gitlab.com/SiaPrime/SiaPrime@v1.4.1/modules/renter/siadir/siadir_test.go (about)

     1  package siadir
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"testing"
     8  	"time"
     9  
    10  	"gitlab.com/NebulousLabs/errors"
    11  
    12  	"gitlab.com/SiaPrime/SiaPrime/modules"
    13  )
    14  
    15  // checkMetadataInit is a helper that verifies that the metadata was initialized
    16  // properly
    17  func checkMetadataInit(md Metadata) error {
    18  	// Check Aggregate Fields
    19  	if md.AggregateHealth != DefaultDirHealth {
    20  		return fmt.Errorf("SiaDir AggregateHealth not set properly: got %v expected %v", md.AggregateHealth, DefaultDirHealth)
    21  	}
    22  	if !md.AggregateLastHealthCheckTime.IsZero() {
    23  		return fmt.Errorf("AggregateLastHealthCheckTime should be zero but was %v", md.AggregateLastHealthCheckTime)
    24  	}
    25  	if md.AggregateMinRedundancy != 0 {
    26  		return fmt.Errorf("SiaDir AggregateMinRedundancy not set properly: got %v expected 0", md.AggregateMinRedundancy)
    27  	}
    28  	if md.AggregateModTime.IsZero() {
    29  		return errors.New("AggregateModTime not initialized")
    30  	}
    31  	if md.AggregateNumFiles != 0 {
    32  		return fmt.Errorf("SiaDir AggregateNumFiles not set properly: got %v expected 0", md.AggregateNumFiles)
    33  	}
    34  	if md.AggregateNumStuckChunks != 0 {
    35  		return fmt.Errorf("SiaDir AggregateNumStuckChunks not initialized properly, expected 0, got %v", md.AggregateNumStuckChunks)
    36  	}
    37  	if md.AggregateNumSubDirs != 0 {
    38  		return fmt.Errorf("SiaDir AggregateNumSubDirs not initialized properly, expected 0, got %v", md.AggregateNumSubDirs)
    39  	}
    40  	if md.AggregateStuckHealth != DefaultDirHealth {
    41  		return fmt.Errorf("SiaDir AggregateStuckHealth not set properly: got %v expected %v", md.AggregateStuckHealth, DefaultDirHealth)
    42  	}
    43  	if md.AggregateSize != 0 {
    44  		return fmt.Errorf("SiaDir AggregateSize not set properly: got %v expected 0", md.AggregateSize)
    45  	}
    46  
    47  	// Check SiaDir Fields
    48  	if md.Health != DefaultDirHealth {
    49  		return fmt.Errorf("SiaDir Health not set properly: got %v expected %v", md.Health, DefaultDirHealth)
    50  	}
    51  	if !md.LastHealthCheckTime.IsZero() {
    52  		return fmt.Errorf("LastHealthCheckTime should be zero but was %v", md.LastHealthCheckTime)
    53  	}
    54  	if md.MinRedundancy != 0 {
    55  		return fmt.Errorf("SiaDir MinRedundancy not set properly: got %v expected 0", md.MinRedundancy)
    56  	}
    57  	if md.ModTime.IsZero() {
    58  		return errors.New("ModTime not initialized")
    59  	}
    60  	if md.NumFiles != 0 {
    61  		return fmt.Errorf("SiaDir NumFiles not initialized properly, expected 0, got %v", md.NumFiles)
    62  	}
    63  	if md.NumStuckChunks != 0 {
    64  		return fmt.Errorf("SiaDir NumStuckChunks not initialized properly, expected 0, got %v", md.NumStuckChunks)
    65  	}
    66  	if md.NumSubDirs != 0 {
    67  		return fmt.Errorf("SiaDir NumSubDirs not initialized properly, expected 0, got %v", md.NumSubDirs)
    68  	}
    69  	if md.StuckHealth != DefaultDirHealth {
    70  		return fmt.Errorf("SiaDir stuck health not set properly: got %v expected %v", md.StuckHealth, DefaultDirHealth)
    71  	}
    72  	if md.Size != 0 {
    73  		return fmt.Errorf("SiaDir Size not set properly: got %v expected 0", md.Size)
    74  	}
    75  	return nil
    76  }
    77  
    78  // newRootDir creates a root directory for the test and removes old test files
    79  func newRootDir(t *testing.T) (string, error) {
    80  	dir := filepath.Join(os.TempDir(), "siadirs", t.Name())
    81  	err := os.RemoveAll(dir)
    82  	if err != nil {
    83  		return "", err
    84  	}
    85  	return dir, nil
    86  }
    87  
    88  // TestNewSiaDir tests that siadirs are created on disk properly. It uses
    89  // LoadSiaDir to read the metadata from disk
    90  func TestNewSiaDir(t *testing.T) {
    91  	if testing.Short() {
    92  		t.SkipNow()
    93  	}
    94  	t.Parallel()
    95  
    96  	// Create New SiaDir that is two levels deep
    97  	rootDir, err := newRootDir(t)
    98  	if err != nil {
    99  		t.Fatal(err)
   100  	}
   101  	siaPathDir, err := modules.NewSiaPath("TestDir")
   102  	if err != nil {
   103  		t.Fatal(err)
   104  	}
   105  	siaPathSubDir, err := modules.NewSiaPath("SubDir")
   106  	if err != nil {
   107  		t.Fatal(err)
   108  	}
   109  	siaPath, err := siaPathDir.Join(siaPathSubDir.String())
   110  	if err != nil {
   111  		t.Fatal(err)
   112  	}
   113  	wal, _ := newTestWAL()
   114  	siaDir, err := New(siaPath, rootDir, wal)
   115  	if err != nil {
   116  		t.Fatal(err)
   117  	}
   118  
   119  	// Check Sub Dir
   120  	//
   121  	// Check that the metadta was initialized properly
   122  	md := siaDir.metadata
   123  	if err = checkMetadataInit(md); err != nil {
   124  		t.Fatal(err)
   125  	}
   126  	// Check that the SiaPath was initialized properly
   127  	if siaDir.SiaPath() != siaPath {
   128  		t.Fatalf("SiaDir SiaPath not set properly: got %v expected %v", siaDir.SiaPath(), siaPath)
   129  	}
   130  	// Check that the directory and .siadir file were created on disk
   131  	_, err = os.Stat(siaPath.SiaDirSysPath(rootDir))
   132  	if err != nil {
   133  		t.Fatal(err)
   134  	}
   135  	_, err = os.Stat(siaPath.SiaDirMetadataSysPath(rootDir))
   136  	if err != nil {
   137  		t.Fatal(err)
   138  	}
   139  
   140  	// Check Top Directory
   141  	//
   142  	// Check that the directory and .siadir file were created on disk
   143  	_, err = os.Stat(siaPath.SiaDirSysPath(rootDir))
   144  	if err != nil {
   145  		t.Fatal(err)
   146  	}
   147  	_, err = os.Stat(siaPath.SiaDirMetadataSysPath(rootDir))
   148  	if err != nil {
   149  		t.Fatal(err)
   150  	}
   151  	// Get SiaDir
   152  	subDir, err := LoadSiaDir(rootDir, siaPathDir, modules.ProdDependencies, wal)
   153  	// Check that the metadata was initialized properly
   154  	md = subDir.metadata
   155  	if err = checkMetadataInit(md); err != nil {
   156  		t.Fatal(err)
   157  	}
   158  	// Check that the SiaPath was initialized properly
   159  	if subDir.SiaPath() != siaPathDir {
   160  		t.Fatalf("SiaDir SiaPath not set properly: got %v expected %v", subDir.SiaPath(), siaPathDir)
   161  	}
   162  
   163  	// Check Root Directory
   164  	//
   165  	// Get SiaDir
   166  	rootSiaDir, err := LoadSiaDir(rootDir, modules.RootSiaPath(), modules.ProdDependencies, wal)
   167  	// Check that the metadata was initialized properly
   168  	md = rootSiaDir.metadata
   169  	if err = checkMetadataInit(md); err != nil {
   170  		t.Fatal(err)
   171  	}
   172  	// Check that the SiaPath was initialized properly
   173  	if !rootSiaDir.SiaPath().IsRoot() {
   174  		t.Fatalf("SiaDir SiaPath not set properly: got %v expected %v", rootSiaDir.SiaPath().String(), "")
   175  	}
   176  	// Check that the directory and .siadir file were created on disk
   177  	_, err = os.Stat(rootDir)
   178  	if err != nil {
   179  		t.Fatal(err)
   180  	}
   181  	_, err = os.Stat(modules.RootSiaPath().SiaDirMetadataSysPath(rootDir))
   182  	if err != nil {
   183  		t.Fatal(err)
   184  	}
   185  }
   186  
   187  // Test UpdatedMetadata probes the UpdateMetadata method
   188  func TestUpdateMetadata(t *testing.T) {
   189  	if testing.Short() {
   190  		t.SkipNow()
   191  	}
   192  	t.Parallel()
   193  
   194  	// Create new siaDir
   195  	rootDir, err := newRootDir(t)
   196  	if err != nil {
   197  		t.Fatal(err)
   198  	}
   199  	siaPath, err := modules.NewSiaPath("TestDir")
   200  	if err != nil {
   201  		t.Fatal(err)
   202  	}
   203  	wal, _ := newTestWAL()
   204  	siaDir, err := New(siaPath, rootDir, wal)
   205  	if err != nil {
   206  		t.Fatal(err)
   207  	}
   208  
   209  	// Check metadata was initialized properly in memory and on disk
   210  	md := siaDir.metadata
   211  	if err = checkMetadataInit(md); err != nil {
   212  		t.Fatal(err)
   213  	}
   214  	siaDir, err = LoadSiaDir(rootDir, siaPath, modules.ProdDependencies, wal)
   215  	if err != nil {
   216  		t.Fatal(err)
   217  	}
   218  	md = siaDir.metadata
   219  	if err = checkMetadataInit(md); err != nil {
   220  		t.Fatal(err)
   221  	}
   222  
   223  	// Set the metadata
   224  	checkTime := time.Now()
   225  	metadataUpdate := md
   226  	// Aggregate fields
   227  	metadataUpdate.AggregateHealth = 7
   228  	metadataUpdate.AggregateLastHealthCheckTime = checkTime
   229  	metadataUpdate.AggregateMinRedundancy = 2.2
   230  	metadataUpdate.AggregateModTime = checkTime
   231  	metadataUpdate.AggregateNumFiles = 11
   232  	metadataUpdate.AggregateNumStuckChunks = 15
   233  	metadataUpdate.AggregateNumSubDirs = 5
   234  	metadataUpdate.AggregateSize = 2432
   235  	metadataUpdate.AggregateStuckHealth = 5
   236  	// SiaDir fields
   237  	metadataUpdate.Health = 4
   238  	metadataUpdate.LastHealthCheckTime = checkTime
   239  	metadataUpdate.MinRedundancy = 2
   240  	metadataUpdate.ModTime = checkTime
   241  	metadataUpdate.NumFiles = 5
   242  	metadataUpdate.NumStuckChunks = 6
   243  	metadataUpdate.NumSubDirs = 4
   244  	metadataUpdate.Size = 223
   245  	metadataUpdate.StuckHealth = 2
   246  
   247  	err = siaDir.UpdateMetadata(metadataUpdate)
   248  	if err != nil {
   249  		t.Fatal(err)
   250  	}
   251  
   252  	// Check that the metadata was updated properly in memory and on disk
   253  	md = siaDir.metadata
   254  	err = equalMetadatas(md, metadataUpdate)
   255  	if err != nil {
   256  		t.Fatal(err)
   257  	}
   258  	siaDir, err = LoadSiaDir(rootDir, siaPath, modules.ProdDependencies, wal)
   259  	if err != nil {
   260  		t.Fatal(err)
   261  	}
   262  	md = siaDir.metadata
   263  	// Check Time separately due to how the time is persisted
   264  	if !md.AggregateLastHealthCheckTime.Equal(metadataUpdate.AggregateLastHealthCheckTime) {
   265  		t.Fatalf("AggregateLastHealthCheckTimes not equal, got %v expected %v", md.AggregateLastHealthCheckTime, metadataUpdate.AggregateLastHealthCheckTime)
   266  	}
   267  	metadataUpdate.AggregateLastHealthCheckTime = md.AggregateLastHealthCheckTime
   268  	if !md.LastHealthCheckTime.Equal(metadataUpdate.LastHealthCheckTime) {
   269  		t.Fatalf("LastHealthCheckTimes not equal, got %v expected %v", md.LastHealthCheckTime, metadataUpdate.LastHealthCheckTime)
   270  	}
   271  	metadataUpdate.LastHealthCheckTime = md.LastHealthCheckTime
   272  	if !md.AggregateModTime.Equal(metadataUpdate.AggregateModTime) {
   273  		t.Fatalf("AggregateModTimes not equal, got %v expected %v", md.AggregateModTime, metadataUpdate.AggregateModTime)
   274  	}
   275  	metadataUpdate.AggregateModTime = md.AggregateModTime
   276  	if !md.ModTime.Equal(metadataUpdate.ModTime) {
   277  		t.Fatalf("ModTimes not equal, got %v expected %v", md.ModTime, metadataUpdate.ModTime)
   278  	}
   279  	metadataUpdate.ModTime = md.ModTime
   280  	// Check the rest of the metadata
   281  	err = equalMetadatas(md, metadataUpdate)
   282  	if err != nil {
   283  		t.Fatal(err)
   284  	}
   285  }
   286  
   287  // TestDelete tests if deleting a siadir removes the siadir from disk and sets
   288  // the deleted flag correctly.
   289  func TestDelete(t *testing.T) {
   290  	if testing.Short() {
   291  		t.SkipNow()
   292  	}
   293  	t.Parallel()
   294  
   295  	// Create SiaFileSet with SiaDir
   296  	entry, _, err := newTestSiaDirSetWithDir()
   297  	if err != nil {
   298  		t.Fatal(err)
   299  	}
   300  	// Delete siadir.
   301  	if err := entry.Delete(); err != nil {
   302  		t.Fatal("Failed to delete siadir", err)
   303  	}
   304  	// Check if siadir was deleted and if deleted flag was set.
   305  	if !entry.Deleted() {
   306  		t.Fatal("Deleted flag was not set correctly")
   307  	}
   308  	siaDirPath := entry.siaPath.SiaDirSysPath(entry.rootDir)
   309  	if _, err := os.Open(siaDirPath); !os.IsNotExist(err) {
   310  		t.Fatal("Expected a siadir doesn't exist error but got", err)
   311  	}
   312  }