github.com/Synthesix/Sia@v1.3.3-0.20180413141344-f863baeed3ca/persist/json_test.go (about) 1 package persist 2 3 import ( 4 "bytes" 5 "os" 6 "path/filepath" 7 "sync" 8 "testing" 9 10 "github.com/Synthesix/Sia/build" 11 ) 12 13 // TestSaveLoadJSON creates a simple object and then tries saving and loading 14 // it. 15 func TestSaveLoadJSON(t *testing.T) { 16 if testing.Short() { 17 t.SkipNow() 18 } 19 // Create the directory used for testing. 20 dir := filepath.Join(build.TempDir(persistDir), t.Name()) 21 err := os.MkdirAll(dir, 0700) 22 if err != nil { 23 t.Fatal(err) 24 } 25 26 // Create and save the test object. 27 testMeta := Metadata{"Test Struct", "v1.2.1"} 28 type testStruct struct { 29 One string 30 Two uint64 31 Three []byte 32 } 33 34 obj1 := testStruct{"dog", 25, []byte("more dog")} 35 obj1Filename := filepath.Join(dir, "obj1.json") 36 err = SaveJSON(testMeta, obj1, obj1Filename) 37 if err != nil { 38 t.Fatal(err) 39 } 40 var obj2 testStruct 41 42 // Try loading the object 43 err = LoadJSON(testMeta, &obj2, obj1Filename) 44 if err != nil { 45 t.Fatal(err) 46 } 47 // Verify equivalence. 48 if obj2.One != obj1.One { 49 t.Error("persist mismatch") 50 } 51 if obj2.Two != obj1.Two { 52 t.Error("persist mismatch") 53 } 54 if !bytes.Equal(obj2.Three, obj1.Three) { 55 t.Error("persist mismatch") 56 } 57 if obj2.One != "dog" { 58 t.Error("persist mismatch") 59 } 60 if obj2.Two != 25 { 61 t.Error("persist mismatch") 62 } 63 if !bytes.Equal(obj2.Three, []byte("more dog")) { 64 t.Error("persist mismatch") 65 } 66 67 // Try loading the object using the temp file. 68 err = LoadJSON(testMeta, &obj2, obj1Filename+tempSuffix) 69 if err != ErrBadFilenameSuffix { 70 t.Error("did not get bad filename suffix") 71 } 72 73 // Try saving the object multiple times concurrently. 74 var wg sync.WaitGroup 75 for i := 0; i < 250; i++ { 76 wg.Add(1) 77 go func(i int) { 78 defer wg.Done() 79 defer func() { 80 recover() // Error is irrelevant. 81 }() 82 SaveJSON(testMeta, obj1, obj1Filename) 83 }(i) 84 } 85 wg.Wait() 86 87 // Despite possible errors from saving the object many times concurrently, 88 // the object should still be readable. 89 err = LoadJSON(testMeta, &obj2, obj1Filename) 90 if err != nil { 91 t.Fatal(err) 92 } 93 // Verify equivalence. 94 if obj2.One != obj1.One { 95 t.Error("persist mismatch") 96 } 97 if obj2.Two != obj1.Two { 98 t.Error("persist mismatch") 99 } 100 if !bytes.Equal(obj2.Three, obj1.Three) { 101 t.Error("persist mismatch") 102 } 103 if obj2.One != "dog" { 104 t.Error("persist mismatch") 105 } 106 if obj2.Two != 25 { 107 t.Error("persist mismatch") 108 } 109 if !bytes.Equal(obj2.Three, []byte("more dog")) { 110 t.Error("persist mismatch") 111 } 112 } 113 114 // TestLoadJSONCorruptedFiles checks that LoadJSON correctly handles various 115 // types of corruption that can occur during the saving process. 116 func TestLoadJSONCorruptedFiles(t *testing.T) { 117 if testing.Short() { 118 t.SkipNow() 119 } 120 // Define the test object that will be getting loaded. 121 testMeta := Metadata{"Test Struct", "v1.2.1"} 122 type testStruct struct { 123 One string 124 Two uint64 125 Three []byte 126 } 127 obj1 := testStruct{"dog", 25, []byte("more dog")} 128 var obj2 testStruct 129 130 // Try loading a file with a bad checksum. 131 err := LoadJSON(testMeta, &obj2, filepath.Join("testdata", "badchecksum.json")) 132 if err == nil { 133 t.Error("bad checksum should have failed") 134 } 135 // Try loading a file where only the main has a bad checksum. 136 err = LoadJSON(testMeta, &obj2, filepath.Join("testdata", "badchecksummain.json")) 137 if err != nil { 138 t.Error("bad checksum main failed:", err) 139 } 140 // Verify equivalence. 141 if obj2.One != obj1.One { 142 t.Error("persist mismatch") 143 } 144 if obj2.Two != obj1.Two { 145 t.Error("persist mismatch") 146 } 147 if !bytes.Equal(obj2.Three, obj1.Three) { 148 t.Error("persist mismatch") 149 } 150 if obj2.One != "dog" { 151 t.Error("persist mismatch") 152 } 153 if obj2.Two != 25 { 154 t.Error("persist mismatch") 155 } 156 if !bytes.Equal(obj2.Three, []byte("more dog")) { 157 t.Error("persist mismatch") 158 } 159 160 // Try loading a file with a manual checksum. 161 err = LoadJSON(testMeta, &obj2, filepath.Join("testdata", "manual.json")) 162 if err != nil { 163 t.Error("bad checksum should have failed") 164 } 165 // Verify equivalence. 166 if obj2.One != obj1.One { 167 t.Error("persist mismatch") 168 } 169 if obj2.Two != obj1.Two { 170 t.Error("persist mismatch") 171 } 172 if !bytes.Equal(obj2.Three, obj1.Three) { 173 t.Error("persist mismatch") 174 } 175 if obj2.One != "dog" { 176 t.Error("persist mismatch") 177 } 178 if obj2.Two != 25 { 179 t.Error("persist mismatch") 180 } 181 if !bytes.Equal(obj2.Three, []byte("more dog")) { 182 t.Error("persist mismatch") 183 } 184 185 // Try loading a corrupted main file. 186 err = LoadJSON(testMeta, &obj2, filepath.Join("testdata", "corruptmain.json")) 187 if err != nil { 188 t.Error("couldn't load corrupted main:", err) 189 } 190 // Verify equivalence. 191 if obj2.One != obj1.One { 192 t.Error("persist mismatch") 193 } 194 if obj2.Two != obj1.Two { 195 t.Error("persist mismatch") 196 } 197 if !bytes.Equal(obj2.Three, obj1.Three) { 198 t.Error("persist mismatch") 199 } 200 if obj2.One != "dog" { 201 t.Error("persist mismatch") 202 } 203 if obj2.Two != 25 { 204 t.Error("persist mismatch") 205 } 206 if !bytes.Equal(obj2.Three, []byte("more dog")) { 207 t.Error("persist mismatch") 208 } 209 210 // Try loading a corrupted temp file. 211 err = LoadJSON(testMeta, &obj2, filepath.Join("testdata", "corrupttemp.json")) 212 if err != nil { 213 t.Error("couldn't load corrupted main:", err) 214 } 215 // Verify equivalence. 216 if obj2.One != obj1.One { 217 t.Error("persist mismatch") 218 } 219 if obj2.Two != obj1.Two { 220 t.Error("persist mismatch") 221 } 222 if !bytes.Equal(obj2.Three, obj1.Three) { 223 t.Error("persist mismatch") 224 } 225 if obj2.One != "dog" { 226 t.Error("persist mismatch") 227 } 228 if obj2.Two != 25 { 229 t.Error("persist mismatch") 230 } 231 if !bytes.Equal(obj2.Three, []byte("more dog")) { 232 t.Error("persist mismatch") 233 } 234 235 // Try loading a file with no temp, and no checksum. 236 err = LoadJSON(testMeta, &obj2, filepath.Join("testdata", "nochecksum.json")) 237 if err != nil { 238 t.Error("couldn't load no checksum:", err) 239 } 240 // Verify equivalence. 241 if obj2.One != obj1.One { 242 t.Error("persist mismatch") 243 } 244 if obj2.Two != obj1.Two { 245 t.Error("persist mismatch") 246 } 247 if !bytes.Equal(obj2.Three, obj1.Three) { 248 t.Error("persist mismatch") 249 } 250 if obj2.One != "dog" { 251 t.Error("persist mismatch") 252 } 253 if obj2.Two != 25 { 254 t.Error("persist mismatch") 255 } 256 if !bytes.Equal(obj2.Three, []byte("more dog")) { 257 t.Error("persist mismatch") 258 } 259 }