gitlab.com/SkynetLabs/skyd@v1.6.9/skymodules/renter/filesystem/siadir/persist_test.go (about) 1 package siadir 2 3 import ( 4 "os" 5 "path/filepath" 6 "reflect" 7 "testing" 8 "time" 9 10 "gitlab.com/NebulousLabs/errors" 11 "gitlab.com/NebulousLabs/fastrand" 12 "go.sia.tech/siad/modules" 13 "go.sia.tech/siad/persist" 14 ) 15 16 // TestPersist probes the persist subsystem 17 func TestPersist(t *testing.T) { 18 t.Run("NewMetadata", testNewMetadata) 19 20 if testing.Short() { 21 t.SkipNow() 22 } 23 t.Parallel() 24 25 t.Run("CallLoadSiaDirMetadata", testCallLoadSiaDirMetadata) 26 t.Run("CreateDirMetadataAll", testCreateDirMetadataAll) 27 } 28 29 // testCallLoadSiaDirMetadata probes the callLoadSiaDirMetadata function 30 func testCallLoadSiaDirMetadata(t *testing.T) { 31 testDir, err := newSiaDirTestDir(t.Name()) 32 if err != nil { 33 t.Fatal(err) 34 } 35 36 // Calling load on an empty path should return IsNotExist 37 _, err = callLoadSiaDirMetadata("doesntexist", modules.ProdDependencies) 38 if !errors.IsOSNotExist(err) { 39 t.Error("unexpected error", err) 40 } 41 42 // An empty file, should return corrupt 43 emptyFile := filepath.Join(testDir, "emptyFile") 44 f, err := os.Create(emptyFile) 45 if err != nil { 46 t.Fatal(err) 47 } 48 if err := f.Close(); err != nil { 49 t.Fatal(err) 50 } 51 _, err = callLoadSiaDirMetadata(emptyFile, modules.ProdDependencies) 52 if !errors.Contains(err, ErrCorruptFile) { 53 t.Error("unexpected error", err) 54 } 55 56 // A file with corrupt data should return invalid checksum 57 corruptFile := filepath.Join(testDir, "corruptFile") 58 f, err = os.Create(corruptFile) 59 if err != nil { 60 t.Fatal(err) 61 } 62 _, err = f.Write(fastrand.Bytes(100)) 63 if err != nil { 64 t.Fatal(err) 65 } 66 if err := f.Close(); err != nil { 67 t.Fatal(err) 68 } 69 _, err = callLoadSiaDirMetadata(corruptFile, modules.ProdDependencies) 70 if !errors.Contains(err, ErrInvalidChecksum) { 71 t.Error("unexpected error", err) 72 } 73 74 // Test happy case 75 happyFile := filepath.Join(testDir, modules.SiaDirExtension) 76 f, err = os.Create(happyFile) 77 if err != nil { 78 t.Fatal(err) 79 } 80 if err := f.Close(); err != nil { 81 t.Fatal(err) 82 } 83 mdNew, err := newMetadata() 84 if err != nil { 85 t.Fatal(err) 86 } 87 err = saveDir(testDir, mdNew, modules.ProdDependencies) 88 if err != nil { 89 t.Fatal(err) 90 } 91 _, err = callLoadSiaDirMetadata(happyFile, modules.ProdDependencies) 92 if err != nil { 93 t.Fatal(err) 94 } 95 } 96 97 // testCreateDirMetadataAll probes the case of a potential infinite loop in 98 // createDirMetadataAll 99 func testCreateDirMetadataAll(t *testing.T) { 100 testDir, err := newSiaDirTestDir(t.Name()) 101 if err != nil { 102 t.Fatal(err) 103 } 104 105 // Create done chan to protect against blocking test 106 done := make(chan struct{}) 107 go func() { 108 select { 109 case <-done: 110 case <-time.After(time.Minute): 111 t.Error("Test didn't return in time") 112 } 113 }() 114 115 // Ignoring errors, only checking that the functions return as a regression 116 // test for a infinite loop bug. 117 createDirMetadataAll(testDir, "", persist.DefaultDiskPermissionsTest, modules.ProdDependencies) 118 createDirMetadataAll(testDir, ".", persist.DefaultDiskPermissionsTest, modules.ProdDependencies) 119 createDirMetadataAll(testDir, "/", persist.DefaultDiskPermissionsTest, modules.ProdDependencies) 120 close(done) 121 122 // Test cleanup. This is needed because the above test cases create a .siadir 123 // in the current directory. 124 err = os.Remove(modules.SiaDirExtension) 125 if err != nil { 126 t.Fatal(err) 127 } 128 } 129 130 // testNewMetadata probes the newMetadata function 131 func testNewMetadata(t *testing.T) { 132 md := Metadata{ 133 AggregateHealth: DefaultDirHealth, 134 AggregateMinRedundancy: DefaultDirRedundancy, 135 AggregateRemoteHealth: DefaultDirHealth, 136 AggregateStuckHealth: DefaultDirHealth, 137 138 Health: DefaultDirHealth, 139 MinRedundancy: DefaultDirRedundancy, 140 Mode: modules.DefaultDirPerm, 141 RemoteHealth: DefaultDirHealth, 142 StuckHealth: DefaultDirHealth, 143 Version: metadataVersion, 144 } 145 mdNew, err := newMetadata() 146 if err != nil { 147 t.Fatal(err) 148 } 149 150 // Sync the time fields 151 md.AggregateModTime = mdNew.AggregateModTime 152 md.ModTime = mdNew.ModTime 153 154 // Metadatas should match 155 if !reflect.DeepEqual(md, mdNew) { 156 t.Log("expected:", md) 157 t.Log("actual:", mdNew) 158 t.Fatal("metadata mismtach") 159 } 160 }