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

     1  package siafile
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  	"time"
     7  
     8  	"gitlab.com/NebulousLabs/fastrand"
     9  	"gitlab.com/SkynetLabs/skyd/skymodules"
    10  )
    11  
    12  // TestNumChunkPagesRequired tests numChunkPagesRequired.
    13  func TestNumChunkPagesRequired(t *testing.T) {
    14  	for numPieces := 0; numPieces < 1000; numPieces++ {
    15  		chunkSize := marshaledChunkSize(numPieces)
    16  		expectedPages := uint8(chunkSize / pageSize)
    17  		if chunkSize%pageSize != 0 {
    18  			expectedPages++
    19  		}
    20  		if numChunkPagesRequired(numPieces) != expectedPages {
    21  			t.Fatalf("expected %v pages but got %v", expectedPages, numChunkPagesRequired(numPieces))
    22  		}
    23  	}
    24  }
    25  
    26  // TestMarshalUnmarshalChunk tests marshaling and unmarshaling a single chunk.
    27  func TestMarshalUnmarshalChunk(t *testing.T) {
    28  	// Get random chunk.
    29  	chunk := randomChunk()
    30  	numPieces := uint32(len(chunk.Pieces))
    31  
    32  	// Marshal the chunk.
    33  	chunkBytes := marshalChunk(chunk)
    34  	// Check the length of the marshaled chunk.
    35  	if int64(len(chunkBytes)) != marshaledChunkSize(chunk.numPieces()) {
    36  		t.Fatalf("ChunkBytes should have len %v but was %v",
    37  			marshaledChunkSize(chunk.numPieces()), len(chunkBytes))
    38  	}
    39  	// Add some random bytes to the chunkBytes. It should be possible to
    40  	// unmarshal chunks even if we pass in data that is padded at the end.
    41  	chunkBytes = append(chunkBytes, fastrand.Bytes(100)...)
    42  
    43  	// Unmarshal the chunk.
    44  	unmarshaledChunk, err := unmarshalChunk(numPieces, chunkBytes)
    45  	if err != nil {
    46  		t.Fatal(err)
    47  	}
    48  	// Compare unmarshaled chunk to original.
    49  	if !reflect.DeepEqual(chunk, unmarshaledChunk) {
    50  		t.Log("original", chunk)
    51  		t.Log("unmarshaled", unmarshaledChunk)
    52  		t.Fatal("Unmarshaled chunk doesn't equal marshaled chunk")
    53  	}
    54  }
    55  
    56  // TestMarshalUnmarshalErasureCoder tests marshaling and unmarshaling an
    57  // ErasureCoder.
    58  func TestMarshalUnmarshalErasureCoder(t *testing.T) {
    59  	for i := 0; i < 10; i++ {
    60  		for j := 0; j < 20; j++ {
    61  			rc, err := skymodules.NewRSCode(10, 20)
    62  			if err != nil {
    63  				t.Fatal("failed to create reed solomon coder", err)
    64  			}
    65  			// Get the minimum pieces and the total number of pieces.
    66  			numPieces, minPieces := rc.NumPieces(), rc.MinPieces()
    67  			// Marshal the erasure coder.
    68  			ecType, ecParams := marshalErasureCoder(rc)
    69  			// Unmarshal it.
    70  			rc2, err := unmarshalErasureCoder(ecType, ecParams)
    71  			if err != nil {
    72  				t.Fatal("failed to unmarshal reed solomon coder", err)
    73  			}
    74  			// Check if the settings are still the same.
    75  			if numPieces != rc2.NumPieces() {
    76  				t.Errorf("expected %v numPieces but was %v", numPieces, rc2.NumPieces())
    77  			}
    78  			if minPieces != rc2.MinPieces() {
    79  				t.Errorf("expected %v minPieces but was %v", minPieces, rc2.MinPieces())
    80  			}
    81  		}
    82  	}
    83  }
    84  
    85  // TestMarshalUnmarshalMetadata tests marshaling and unmarshaling the metadata
    86  // of a SiaFile.
    87  func TestMarshalUnmarshalMetadata(t *testing.T) {
    88  	if testing.Short() {
    89  		t.SkipNow()
    90  	}
    91  	t.Parallel()
    92  
    93  	sf := newTestFile()
    94  
    95  	// Marshal metadata
    96  	raw, err := marshalMetadata(sf.staticMetadata)
    97  	if err != nil {
    98  		t.Fatal("Failed to marshal metadata", err)
    99  	}
   100  	// Unmarshal metadata
   101  	md, err := unmarshalMetadata(raw)
   102  	if err != nil {
   103  		t.Fatal("Failed to unmarshal metadata", err)
   104  	}
   105  	// Compare the timestamps first since they can't be compared with
   106  	// DeepEqual.
   107  	if sf.staticMetadata.AccessTime.Unix() != md.AccessTime.Unix() {
   108  		t.Fatal("AccessTime's don't match")
   109  	}
   110  	if sf.staticMetadata.ChangeTime.Unix() != md.ChangeTime.Unix() {
   111  		t.Fatal("ChangeTime's don't match")
   112  	}
   113  	if sf.staticMetadata.CreateTime.Unix() != md.CreateTime.Unix() {
   114  		t.Fatal("CreateTime's don't match")
   115  	}
   116  	if sf.staticMetadata.ModTime.Unix() != md.ModTime.Unix() {
   117  		t.Fatal("ModTime's don't match")
   118  	}
   119  	if sf.staticMetadata.LastHealthCheckTime.Unix() != md.LastHealthCheckTime.Unix() {
   120  		t.Fatal("LastHealthCheckTime's don't match")
   121  	}
   122  	if sf.staticMetadata.staticErasureCode.Identifier() != md.staticErasureCode.Identifier() {
   123  		t.Fatal("erasure coder doesn't match")
   124  	}
   125  	// Set the timestamps to zero for DeepEqual.
   126  	sf.staticMetadata.AccessTime = time.Time{}
   127  	sf.staticMetadata.ChangeTime = time.Time{}
   128  	sf.staticMetadata.CreateTime = time.Time{}
   129  	sf.staticMetadata.ModTime = time.Time{}
   130  	sf.staticMetadata.LastHealthCheckTime = time.Time{}
   131  	sf.staticMetadata.staticErasureCode = nil
   132  	md.AccessTime = time.Time{}
   133  	md.ChangeTime = time.Time{}
   134  	md.CreateTime = time.Time{}
   135  	md.ModTime = time.Time{}
   136  	md.LastHealthCheckTime = time.Time{}
   137  	md.staticErasureCode = nil
   138  	// Compare result to original
   139  	if !reflect.DeepEqual(md, sf.staticMetadata) {
   140  		t.Fatal("Unmarshaled metadata not equal to marshaled metadata:", err)
   141  	}
   142  }
   143  
   144  // TestMarshalUnmarshalPubKeyTable tests marshaling and unmarshaling the
   145  // publicKeyTable of a SiaFile.
   146  func TestMarshalUnmarshalPubKeyTable(t *testing.T) {
   147  	if testing.Short() {
   148  		t.SkipNow()
   149  	}
   150  	t.Parallel()
   151  
   152  	sf := newTestFile()
   153  	sf.addRandomHostKeys(10)
   154  
   155  	// Marshal pubKeyTable.
   156  	raw, err := marshalPubKeyTable(sf.pubKeyTable)
   157  	if err != nil {
   158  		t.Fatal("Failed to marshal pubKeyTable", err)
   159  	}
   160  	// Unmarshal pubKeyTable.
   161  	pubKeyTable, err := unmarshalPubKeyTable(raw)
   162  	if err != nil {
   163  		t.Fatal("Failed to unmarshal pubKeyTable", err)
   164  	}
   165  	// Compare them.
   166  	if len(sf.pubKeyTable) != len(pubKeyTable) {
   167  		t.Fatalf("Lengths of tables don't match %v vs %v",
   168  			len(sf.pubKeyTable), len(pubKeyTable))
   169  	}
   170  	for i, spk := range pubKeyTable {
   171  		if spk.Used != sf.pubKeyTable[i].Used {
   172  			t.Fatal("Use fields don't match")
   173  		}
   174  		if !spk.PublicKey.Equals(sf.pubKeyTable[i].PublicKey) {
   175  			t.Fatal("Keys don't match")
   176  		}
   177  	}
   178  }
   179  
   180  // TestMarshalUnmarshalPiece tests marshaling and unmarshaling a single piece
   181  // of a chunk.
   182  func TestMarshalUnmarshalPiece(t *testing.T) {
   183  	// Create random piece.
   184  	piece := randomPiece()
   185  	pieceIndex := uint32(fastrand.Intn(100))
   186  
   187  	// Marshal the piece.
   188  	pieceBytes := make([]byte, marshaledPieceSize)
   189  	putPiece(pieceBytes, pieceIndex, piece)
   190  
   191  	// Unmarshal the piece.
   192  	unmarshaledPieceIndex, unmarshaledPiece, err := unmarshalPiece(pieceBytes)
   193  	if err != nil {
   194  		t.Fatal(err)
   195  	}
   196  	// Compare the pieceIndex.
   197  	if unmarshaledPieceIndex != pieceIndex {
   198  		t.Fatalf("Piece index should be %v but was %v", pieceIndex, unmarshaledPieceIndex)
   199  	}
   200  	// Compare the piece to the original.
   201  	if !reflect.DeepEqual(unmarshaledPiece, piece) {
   202  		t.Fatal("Piece doesn't equal unmarshaled piece")
   203  	}
   204  }