github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/libkb/erasable_kv_store_test.go (about) 1 package libkb 2 3 import ( 4 "crypto/sha256" 5 "fmt" 6 "os" 7 8 "path/filepath" 9 "testing" 10 11 "github.com/stretchr/testify/require" 12 ) 13 14 func TestErasableKVStore(t *testing.T) { 15 tc := SetupTest(t, "libkb store encryption", 1) 16 defer tc.Cleanup() 17 mctx := NewMetaContextForTest(tc) 18 19 subDir := "" 20 s := NewFileErasableKVStore(mctx, subDir, func(_ MetaContext, noise NoiseBytes) ([32]byte, error) { 21 return sha256.Sum256(noise[:]), nil 22 }) 23 24 key := "test-key.key" 25 expected := "value" 26 err := s.Put(mctx, key, expected) 27 require.NoError(t, err) 28 var val string 29 err = s.Get(mctx, key, &val) 30 require.NoError(t, err) 31 require.Equal(t, expected, val) 32 33 // create a tmp file in the storage dir, ensure we clean it up when calling 34 // `AllKeys` 35 tmp, err := os.CreateTemp(s.storageDir, key) 36 require.NoError(t, err) 37 for i := 0; i < 5; i++ { 38 keys, err := s.AllKeys(mctx, ".key") 39 require.NoError(t, err) 40 require.Equal(t, []string{key}, keys) 41 exists, err := FileExists(tmp.Name()) 42 require.NoError(t, err) 43 if !exists { 44 break 45 } 46 } 47 48 // Test noise file corruption 49 noiseName := fmt.Sprintf("%s%s", key, noiseSuffix) 50 storageDir := getStorageDir(mctx, subDir) 51 noiseFilePath := filepath.Join(storageDir, noiseName) 52 noise, err := os.ReadFile(noiseFilePath) 53 require.NoError(t, err) 54 55 // flip one bit 56 corruptedNoise := make([]byte, len(noise)) 57 copy(corruptedNoise, noise) 58 corruptedNoise[0] ^= 0x01 59 60 err = os.WriteFile(noiseFilePath, corruptedNoise, PermFile) 61 require.NoError(t, err) 62 63 var corrupt string 64 err = s.Get(mctx, key, &corrupt) 65 require.Error(t, err) 66 uerr, ok := err.(UnboxError) 67 require.True(t, ok) 68 require.Equal(t, fmt.Sprintf("ErasableKVStore UnboxError (info=noise hashes do not match): secretbox.Open failure. Stored noise hash: %x, current noise hash: %x, equal: %v", s.noiseHash(noise), s.noiseHash(corruptedNoise), false), uerr.Error()) 69 require.NotEqual(t, expected, corrupt) 70 71 err = s.Erase(mctx, key) 72 require.NoError(t, err) 73 74 keys, err := s.AllKeys(mctx, ".key") 75 require.NoError(t, err) 76 require.Equal(t, []string(nil), keys) 77 78 s2 := NewFileErasableKVStore(mctx, "nah", func(_ MetaContext, noise NoiseBytes) ([32]byte, error) { 79 return sha256.Sum256(noise[:]), nil 80 }) 81 key2 := "mynewkey" 82 expected2 := []byte("yellow_submarine") 83 err = s2.Put(mctx, key2, expected2) 84 require.NoError(t, err) 85 86 s3 := NewFileErasableKVStore(mctx, "nah", func(_ MetaContext, noise NoiseBytes) ([32]byte, error) { 87 return sha256.Sum256(noise[:]), nil 88 }) 89 var val2 []byte 90 err = s3.Get(mctx, key2, &val2) 91 require.NoError(t, err) 92 require.Equal(t, expected2, val2) 93 }