package s3api import ( "bytes" "hash/crc32" "testing" "github.com/minio/crc64nvme" ) // Tests that combining per-block CRC-64/NVME values reproduces the CRC of the concatenated data. func TestCombineCRC64NVME(t *testing.T) { params := crcCombineParams[ChecksumAlgorithmCRC64NVMe] blocks := [][]byte{ []byte("abc"), []byte("def"), []byte("hello world, this is a longer block of data to combine"), bytes.Repeat([]byte{0x00}, 5*1024*1024), bytes.Repeat([]byte{0xAB, 0xCD}, 1024), []byte("z"), } var combined uint64 var concatenated []byte for i, block := range blocks { blockCRC := crc64nvme.Checksum(block) if i == 0 { combined = blockCRC } else { combined = combineCRC(combined, blockCRC, uint64(len(block)), params) } concatenated = append(concatenated, block...) want := crc64nvme.Checksum(concatenated) if combined != want { t.Fatalf("after block %d: combined = %016x, want %016x", i, combined, want) } } } // Tests that combining per-block CRC-32 values reproduces the CRC of the concatenated data. func TestCombineCRC32(t *testing.T) { params := crcCombineParams[ChecksumAlgorithmCRC32] blocks := [][]byte{ []byte("abc"), []byte("def"), []byte("hello world, this is a longer block of data to combine"), bytes.Repeat([]byte{0x00}, 5*1024*1024), bytes.Repeat([]byte{0xAB, 0xCD}, 1024), []byte("z"), } var combined uint64 var concatenated []byte for i, block := range blocks { blockCRC := uint64(crc32.Checksum(block, crc32.MakeTable(crc32.IEEE))) if i == 0 { combined = blockCRC } else { combined = combineCRC(combined, blockCRC, uint64(len(block)), params) } concatenated = append(concatenated, block...) want := uint64(crc32.Checksum(concatenated, crc32.MakeTable(crc32.IEEE))) if combined != want { t.Fatalf("after block %d: combined = %016x, want %016x", i, combined, want) } } } // Tests that combining per-block CRC-32C values reproduces the CRC of the concatenated data. func TestCombineCRC32C(t *testing.T) { params := crcCombineParams[ChecksumAlgorithmCRC32C] table := crc32.MakeTable(crc32.Castagnoli) blocks := [][]byte{ []byte("abc"), []byte("def"), []byte("hello world, this is a longer block of data to combine"), bytes.Repeat([]byte{0x00}, 5*1024*1024), bytes.Repeat([]byte{0xAB, 0xCD}, 1024), []byte("z"), } var combined uint64 var concatenated []byte for i, block := range blocks { blockCRC := uint64(crc32.Checksum(block, table)) if i == 0 { combined = blockCRC } else { combined = combineCRC(combined, blockCRC, uint64(len(block)), params) } concatenated = append(concatenated, block...) want := uint64(crc32.Checksum(concatenated, table)) if combined != want { t.Fatalf("after block %d: combined = %016x, want %016x", i, combined, want) } } } func TestCombineCRC64NVMEEmptySecond(t *testing.T) { params := crcCombineParams[ChecksumAlgorithmCRC64NVMe] crc1 := crc64nvme.Checksum([]byte("abc")) if got := combineCRC(crc1, crc64nvme.Checksum(nil), 0, params); got != crc1 { t.Fatalf("combining with empty second block changed crc: got %016x, want %016x", got, crc1) } } func TestCombineCRC32EmptySecond(t *testing.T) { params := crcCombineParams[ChecksumAlgorithmCRC32] crc1 := uint64(crc32.Checksum([]byte("abc"), crc32.MakeTable(crc32.IEEE))) if got := combineCRC(crc1, uint64(crc32.Checksum(nil, crc32.MakeTable(crc32.IEEE))), 0, params); got != crc1 { t.Fatalf("combining with empty second block changed crc: got %016x, want %016x", got, crc1) } }