github.com/git-lfs/git-lfs@v2.5.2+incompatible/tools/kv/keyvaluestore_test.go (about) 1 package kv 2 3 import ( 4 "io/ioutil" 5 "os" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 ) 10 11 func TestStoreSimple(t *testing.T) { 12 tmpf, err := ioutil.TempFile("", "lfstest1") 13 assert.Nil(t, err) 14 filename := tmpf.Name() 15 defer os.Remove(filename) 16 tmpf.Close() 17 18 kvs, err := NewStore(filename) 19 assert.Nil(t, err) 20 21 // We'll include storing custom structs 22 type customData struct { 23 Val1 string 24 Val2 int 25 } 26 // Needed to store custom struct 27 RegisterTypeForStorage(&customData{}) 28 29 kvs.Set("stringVal", "This is a string value") 30 kvs.Set("intVal", 3) 31 kvs.Set("floatVal", 3.142) 32 kvs.Set("structVal", &customData{"structTest", 20}) 33 34 s := kvs.Get("stringVal") 35 assert.Equal(t, "This is a string value", s) 36 i := kvs.Get("intVal") 37 assert.Equal(t, 3, i) 38 f := kvs.Get("floatVal") 39 assert.Equal(t, 3.142, f) 40 c := kvs.Get("structVal") 41 assert.Equal(t, c, &customData{"structTest", 20}) 42 n := kvs.Get("noValue") 43 assert.Nil(t, n) 44 45 kvs.Remove("stringVal") 46 s = kvs.Get("stringVal") 47 assert.Nil(t, s) 48 // Set the string value again before saving 49 kvs.Set("stringVal", "This is a string value") 50 51 err = kvs.Save() 52 assert.Nil(t, err) 53 kvs = nil 54 55 // Now confirm that we can read it all back 56 kvs2, err := NewStore(filename) 57 assert.Nil(t, err) 58 s = kvs2.Get("stringVal") 59 assert.Equal(t, "This is a string value", s) 60 i = kvs2.Get("intVal") 61 assert.Equal(t, 3, i) 62 f = kvs2.Get("floatVal") 63 assert.Equal(t, 3.142, f) 64 c = kvs2.Get("structVal") 65 assert.Equal(t, c, &customData{"structTest", 20}) 66 n = kvs2.Get("noValue") 67 assert.Nil(t, n) 68 69 // Test remove all 70 kvs2.RemoveAll() 71 s = kvs2.Get("stringVal") 72 assert.Nil(t, s) 73 i = kvs2.Get("intVal") 74 assert.Nil(t, i) 75 f = kvs2.Get("floatVal") 76 assert.Nil(t, f) 77 c = kvs2.Get("structVal") 78 assert.Nil(t, c) 79 80 err = kvs2.Save() 81 assert.Nil(t, err) 82 kvs2 = nil 83 84 // Now confirm that we can read blank & get nothing 85 kvs, err = NewStore(filename) 86 kvs.Visit(func(k string, v interface{}) bool { 87 // Should not be called 88 assert.Fail(t, "Should be no entries") 89 return true 90 }) 91 92 } 93 94 func TestStoreOptimisticConflict(t *testing.T) { 95 tmpf, err := ioutil.TempFile("", "lfstest2") 96 assert.Nil(t, err) 97 filename := tmpf.Name() 98 defer os.Remove(filename) 99 tmpf.Close() 100 101 kvs1, err := NewStore(filename) 102 assert.Nil(t, err) 103 104 kvs1.Set("key1", "value1") 105 kvs1.Set("key2", "value2") 106 kvs1.Set("key3", "value3") 107 err = kvs1.Save() 108 assert.Nil(t, err) 109 110 // Load second copy & modify 111 kvs2, err := NewStore(filename) 112 assert.Nil(t, err) 113 // New keys 114 kvs2.Set("key4", "value4_fromkvs2") 115 kvs2.Set("key5", "value5_fromkvs2") 116 // Modify a key too 117 kvs2.Set("key1", "value1_fromkvs2") 118 err = kvs2.Save() 119 assert.Nil(t, err) 120 121 // Now modify first copy & save; it should detect optimistic lock issue 122 // New item 123 kvs1.Set("key10", "value10") 124 // Overlapping item; since we save second this will overwrite one from kvs2 125 kvs1.Set("key4", "value4") 126 err = kvs1.Save() 127 assert.Nil(t, err) 128 129 // This should have merged changes from kvs2 in the process 130 v := kvs1.Get("key1") 131 assert.Equal(t, "value1_fromkvs2", v) // this one was modified by kvs2 132 v = kvs1.Get("key2") 133 assert.Equal(t, "value2", v) 134 v = kvs1.Get("key3") 135 assert.Equal(t, "value3", v) 136 v = kvs1.Get("key4") 137 assert.Equal(t, "value4", v) // we overwrote this so would not be merged 138 v = kvs1.Get("key5") 139 assert.Equal(t, "value5_fromkvs2", v) 140 141 } 142 143 func TestStoreReduceSize(t *testing.T) { 144 tmpf, err := ioutil.TempFile("", "lfstest3") 145 assert.Nil(t, err) 146 filename := tmpf.Name() 147 defer os.Remove(filename) 148 tmpf.Close() 149 150 kvs, err := NewStore(filename) 151 assert.Nil(t, err) 152 153 kvs.Set("key1", "I woke up in a Soho doorway") 154 kvs.Set("key2", "A policeman knew my name") 155 kvs.Set("key3", "He said 'You can go sleep at home tonight") 156 kvs.Set("key4", "If you can get up and walk away'") 157 158 assert.NotNil(t, kvs.Get("key1")) 159 assert.NotNil(t, kvs.Get("key2")) 160 assert.NotNil(t, kvs.Get("key3")) 161 assert.NotNil(t, kvs.Get("key4")) 162 163 assert.Nil(t, kvs.Save()) 164 165 stat1, _ := os.Stat(filename) 166 167 // Remove all but 1 key & save smaller version 168 kvs.Remove("key2") 169 kvs.Remove("key3") 170 kvs.Remove("key4") 171 assert.Nil(t, kvs.Save()) 172 173 // Now reload fresh & prove works 174 kvs = nil 175 176 kvs, err = NewStore(filename) 177 assert.Nil(t, err) 178 assert.NotNil(t, kvs.Get("key1")) 179 assert.Nil(t, kvs.Get("key2")) 180 assert.Nil(t, kvs.Get("key3")) 181 assert.Nil(t, kvs.Get("key4")) 182 183 stat2, _ := os.Stat(filename) 184 185 assert.True(t, stat2.Size() < stat1.Size(), "Size should have reduced, was %d now %d", stat1.Size(), stat2.Size()) 186 187 }