github.com/0chain/gosdk@v1.17.11/zboxcore/sdk/chunked_upload_chunk_reader_test.go (about)

     1  package sdk
     2  
     3  import (
     4  	"bytes"
     5  	"math"
     6  	"testing"
     7  
     8  	"github.com/0chain/gosdk/zboxcore/encryption"
     9  	"github.com/0chain/gosdk/zboxcore/zboxutil"
    10  	"github.com/klauspost/reedsolomon"
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func TestReadChunks(t *testing.T) {
    15  	tests := []struct {
    16  		Name      string
    17  		Size      int64
    18  		ChunkSize int64
    19  
    20  		EncryptOnUpload bool
    21  		DataShards      int
    22  		ParityShards    int
    23  	}{
    24  
    25  		// size < chunk_size
    26  		{Name: "Size_Less_ChunkSize", Size: KB*64 - KB*1, ChunkSize: KB * 64, DataShards: 2, ParityShards: 1, EncryptOnUpload: false},
    27  		// size == chunk_size
    28  		{Name: "size_Equals_ChunkSize", Size: KB * 64 * 1, ChunkSize: KB * 64, DataShards: 2, ParityShards: 1, EncryptOnUpload: false},
    29  		// size > chunk_size
    30  		{Name: "Size_Greater_ChunkSize", Size: KB*64 + KB*1, ChunkSize: KB * 64, DataShards: 2, ParityShards: 1, EncryptOnUpload: false},
    31  
    32  		// size < datashards * chunk_size
    33  		{Name: "Size_Less_DataShards_x_ChunkSize", Size: KB*64*2 - KB*1, ChunkSize: KB * 64, DataShards: 2, ParityShards: 1, EncryptOnUpload: false},
    34  		// size == datashards * chunk_size
    35  		{Name: "size_Equals_DataShards_x_ChunkSize", Size: KB * 64 * 2, ChunkSize: KB * 64, DataShards: 2, ParityShards: 1, EncryptOnUpload: false},
    36  		// size > datashards * chunk_size
    37  		{Name: "Size_Greater_DataShards_x_ChunkSize", Size: KB*64*2 + KB*1, ChunkSize: KB * 64, DataShards: 2, ParityShards: 1, EncryptOnUpload: false},
    38  
    39  		// size = 3 * datashards * chunk_size
    40  		{Name: "Size_Less_3_x_DataShards_x_ChunkSize", Size: KB*64*2*3 - KB*1, ChunkSize: KB * 64, DataShards: 2, ParityShards: 1, EncryptOnUpload: false},
    41  		// size = 3 * datashards * chunk_size
    42  		{Name: "Size_Equals_3_x_DataShards_x_ChunkSize", Size: KB * 64 * 2 * 3, ChunkSize: KB * 64, DataShards: 2, ParityShards: 1, EncryptOnUpload: false},
    43  		// size > 3 * datashards * chunk_size
    44  		{Name: "Size_Greater_3_x_DataShards_x_ChunkSize", Size: KB*64*2*3 + KB*1, ChunkSize: KB * 64, DataShards: 2, ParityShards: 1, EncryptOnUpload: false},
    45  
    46  		// size < chunk_size
    47  		{Name: "Size_Less_ChunkSize_Encrypt", Size: KB*64 - KB*1, ChunkSize: KB * 64, DataShards: 2, ParityShards: 1, EncryptOnUpload: false},
    48  		// size == chunk_size
    49  		{Name: "size_Equals_ChunkSize_Encrypt", Size: KB * 64 * 1, ChunkSize: KB * 64, DataShards: 2, ParityShards: 1, EncryptOnUpload: false},
    50  		// size > chunk_size
    51  		{Name: "Size_Greater_ChunkSize_Encrypt", Size: KB*64 + KB*1, ChunkSize: KB * 64, DataShards: 2, ParityShards: 1, EncryptOnUpload: false},
    52  
    53  		// size < datashards * chunk_size
    54  		{Name: "Size_Less_DataShards_x_ChunkSize_Encrypt", Size: KB*64*2 - KB*1, ChunkSize: KB * 64, DataShards: 2, ParityShards: 1, EncryptOnUpload: false},
    55  		// size == datashards * chunk_size
    56  		{Name: "size_Equals_DataShards_x_ChunkSize_Encrypt", Size: KB * 64 * 2, ChunkSize: KB * 64, DataShards: 2, ParityShards: 1, EncryptOnUpload: false},
    57  		// size > datashards * chunk_size
    58  		{Name: "Size_Greater_DataShards_x_ChunkSize_Encrypt", Size: KB*64*2 + KB*1, ChunkSize: KB * 64, DataShards: 2, ParityShards: 1, EncryptOnUpload: false},
    59  
    60  		// size = 3 * datashards * chunk_size
    61  		{Name: "Size_Less_3_x_DataShards_x_ChunkSize_Encrypt", Size: KB*64*2*3 - KB*1, ChunkSize: KB * 64, DataShards: 2, ParityShards: 1, EncryptOnUpload: false},
    62  		// size = 3 * datashards * chunk_size
    63  		{Name: "Size_Equals_3_x_DataShards_x_ChunkSize_Encrypt", Size: KB * 64 * 2 * 3, ChunkSize: KB * 64, DataShards: 2, ParityShards: 1, EncryptOnUpload: false},
    64  		// size > 3 * datashards * chunk_size
    65  		{Name: "Size_Greater_3_x_DataShards_x_ChunkSize_Encrypt", Size: KB*64*2*3 + KB*1, ChunkSize: KB * 64, DataShards: 2, ParityShards: 1, EncryptOnUpload: false},
    66  	}
    67  
    68  	for _, test := range tests {
    69  		t.Run(test.Name, func(t *testing.T) {
    70  			uploadMask := zboxutil.NewUint128(1).Lsh(uint64(test.DataShards + test.ParityShards)).Sub64(1)
    71  			erasureEncoder, _ := reedsolomon.New(test.DataShards, test.ParityShards, reedsolomon.WithAutoGoroutines(int(test.ChunkSize)))
    72  			encscheme := encryption.NewEncryptionScheme()
    73  			require := require.New(t)
    74  			_, err := encscheme.Initialize(test.Name)
    75  			require.Nil(err)
    76  
    77  			encscheme.InitForEncryption("filetype:audio")
    78  
    79  			buf := generateRandomBytes(test.Size)
    80  
    81  			reader, err := createChunkReader(
    82  				bytes.NewReader(buf), int64(test.Size),
    83  				int64(test.ChunkSize), test.DataShards, test.ParityShards,
    84  				test.EncryptOnUpload, uploadMask,
    85  				erasureEncoder, encscheme,
    86  				CreateHasher(getShardSize(test.Size, test.DataShards, test.EncryptOnUpload)), 100,
    87  			)
    88  			require.Nil(err)
    89  
    90  			lastChunkIndex := 0
    91  			var totalReadSize int64
    92  			var totalFragmentSize int64
    93  			for {
    94  				chunk, err := reader.Next()
    95  				if err != nil {
    96  					t.Fatal(err)
    97  				}
    98  
    99  				lastChunkIndex = chunk.Index
   100  
   101  				totalReadSize += chunk.ReadSize
   102  				totalFragmentSize += chunk.FragmentSize * int64(test.DataShards)
   103  
   104  				if chunk.IsFinal {
   105  					break
   106  				}
   107  			}
   108  
   109  			var chunkDataSize int64
   110  			if test.EncryptOnUpload {
   111  				chunkDataSize = test.ChunkSize - EncryptedDataPaddingSize - EncryptionHeaderSize
   112  			} else {
   113  				chunkDataSize = test.ChunkSize
   114  			}
   115  
   116  			chunkDataSizePerRead := chunkDataSize * int64(test.DataShards)
   117  			chunkNumber := int(math.Ceil(float64(test.Size) / float64(chunkDataSizePerRead)))
   118  
   119  			totalSize := test.Size
   120  
   121  			if test.EncryptOnUpload {
   122  				totalSize += (EncryptedDataPaddingSize + EncryptionHeaderSize) * int64(test.DataShards)
   123  			}
   124  
   125  			require.Equal(chunkNumber, lastChunkIndex+1)
   126  			require.Equal(totalSize, totalFragmentSize)
   127  			require.Equal(totalSize, totalReadSize)
   128  		})
   129  	}
   130  }