gitlab.com/SkynetLabs/skyd@v1.6.9/skymodules/renter/filesystem/siafile/metadata_test.go (about)

     1  package siafile
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"reflect"
     7  	"testing"
     8  	"time"
     9  
    10  	"gitlab.com/NebulousLabs/errors"
    11  	"gitlab.com/NebulousLabs/fastrand"
    12  	"go.sia.tech/siad/types"
    13  )
    14  
    15  // TestBackupRestoreMetadata tests that restoring a metadata from its backup
    16  // works as expected. Especially using it as a deferred statement like we would
    17  // use it in production code.
    18  func TestBackupRestoreMetadata(t *testing.T) {
    19  	if testing.Short() {
    20  		t.SkipNow()
    21  	}
    22  
    23  	sf := newTestFile()
    24  
    25  	// Test both nil slice and regular slice.
    26  	if fastrand.Intn(2) == 0 {
    27  		sf.staticMetadata.Skylinks = []string{}
    28  	} else {
    29  		sf.staticMetadata.Skylinks = nil
    30  	}
    31  
    32  	// Clone the metadata before modifying it.
    33  	mdBefore := sf.staticMetadata.backup()
    34  
    35  	// Make sure it's not the same address. Otherwise the test would later just
    36  	// compare the pointer to itself.
    37  	if &mdBefore == &sf.staticMetadata {
    38  		t.Fatal("backup only copied pointer")
    39  	}
    40  	// To be 100% sure this works we call it like we would in the remaining
    41  	// codebase. Deferred with a named retval.
    42  	func() (err error) {
    43  		// Adding this should restore the metadata later.
    44  		defer func(backup Metadata) {
    45  			if err != nil {
    46  				sf.staticMetadata.restore(backup)
    47  			}
    48  		}(sf.staticMetadata.backup()) // NOTE: this needs to be passed in like that to work
    49  
    50  		// Change all fields that are not static.
    51  		sf.staticMetadata.UniqueID = SiafileUID(fmt.Sprint(fastrand.Intn(100)))
    52  		sf.staticMetadata.FileSize = int64(fastrand.Intn(100))
    53  		sf.staticMetadata.LocalPath = string(fastrand.Bytes(100))
    54  		sf.staticMetadata.ModTime = time.Now()
    55  		sf.staticMetadata.ChangeTime = time.Now()
    56  		sf.staticMetadata.AccessTime = time.Now()
    57  		sf.staticMetadata.CreateTime = time.Now()
    58  		sf.staticMetadata.CachedRedundancy = float64(fastrand.Intn(10))
    59  		sf.staticMetadata.CachedUserRedundancy = float64(fastrand.Intn(10))
    60  		sf.staticMetadata.CachedHealth = float64(fastrand.Intn(10))
    61  		sf.staticMetadata.CachedRepairBytes = fastrand.Uint64n(100)
    62  		sf.staticMetadata.CachedStuckBytes = fastrand.Uint64n(100)
    63  		sf.staticMetadata.CachedStuckHealth = float64(fastrand.Intn(10))
    64  		sf.staticMetadata.CachedExpiration = types.BlockHeight(fastrand.Intn(10))
    65  		sf.staticMetadata.CachedUploadedBytes = uint64(fastrand.Intn(1000))
    66  		sf.staticMetadata.CachedUploadProgress = float64(fastrand.Intn(100))
    67  		sf.staticMetadata.Finished = fastrand.Intn(2) == 0
    68  		sf.staticMetadata.LastHealthCheckTime = time.Now()
    69  		sf.staticMetadata.NumStuckChunks = fastrand.Uint64n(100)
    70  		sf.staticMetadata.Mode = os.FileMode(fastrand.Intn(100))
    71  		sf.staticMetadata.UserID = int32(fastrand.Intn(100))
    72  		sf.staticMetadata.GroupID = int32(fastrand.Intn(100))
    73  		sf.staticMetadata.ChunkOffset = int64(fastrand.Uint64n(100))
    74  		sf.staticMetadata.PubKeyTableOffset = int64(fastrand.Uint64n(100))
    75  		sf.staticMetadata.Skylinks = nil
    76  		if fastrand.Intn(2) == 0 { // 50% chance to be not nil
    77  			sf.staticMetadata.Skylinks = make([]string, fastrand.Intn(10))
    78  		}
    79  
    80  		// Error occurred after changing the fields.
    81  		return errors.New("")
    82  	}()
    83  	// Fields should be the same as before.
    84  	if !reflect.DeepEqual(mdBefore, sf.staticMetadata) {
    85  		t.Fatalf("metadata wasn't restored successfully %v %v", mdBefore, sf.staticMetadata)
    86  	}
    87  }