@ -2253,6 +2253,12 @@ TEST_P(BlockBasedTableTest, BadChecksumType) {
" Corruption: Corrupt or unsupported checksum type: 123 in test " ) ;
" Corruption: Corrupt or unsupported checksum type: 123 in test " ) ;
}
}
class BuiltinChecksumTest : public testing : : Test ,
public testing : : WithParamInterface < ChecksumType > { } ;
INSTANTIATE_TEST_CASE_P ( SupportedChecksums , BuiltinChecksumTest ,
testing : : ValuesIn ( GetSupportedChecksums ( ) ) ) ;
namespace {
namespace {
std : : string ChecksumAsString ( const std : : string & data ,
std : : string ChecksumAsString ( const std : : string & data ,
ChecksumType checksum_type ) {
ChecksumType checksum_type ) {
@ -2278,7 +2284,11 @@ std::string ChecksumAsString(std::string* data, char new_last_byte,
// Make sure that checksum values don't change in later versions, even if
// Make sure that checksum values don't change in later versions, even if
// consistent within current version.
// consistent within current version.
TEST_P ( BlockBasedTableTest , ChecksumSchemas ) {
TEST_P ( BuiltinChecksumTest , ChecksumSchemas ) {
// Trailing 'x' chars will be replaced by compression type. Specifically,
// the first byte of a block trailer is compression type, which is part of
// the checksum input. This test does not deal with storing or parsing
// checksums from the trailer (next 4 bytes of trailer).
std : : string b0 = " x " ;
std : : string b0 = " x " ;
std : : string b1 = " This is a short block!x " ;
std : : string b1 = " This is a short block!x " ;
std : : string b2 ;
std : : string b2 ;
@ -2286,7 +2296,6 @@ TEST_P(BlockBasedTableTest, ChecksumSchemas) {
b2 . append ( " This is a long block! " ) ;
b2 . append ( " This is a long block! " ) ;
}
}
b2 . append ( " x " ) ;
b2 . append ( " x " ) ;
// Trailing 'x' will be replaced by compression type
std : : string empty ;
std : : string empty ;
@ -2294,9 +2303,7 @@ TEST_P(BlockBasedTableTest, ChecksumSchemas) {
char ct2 = kSnappyCompression ;
char ct2 = kSnappyCompression ;
char ct3 = kZSTD ;
char ct3 = kZSTD ;
// Note: first byte of trailer is compression type, last 4 are checksum
ChecksumType t = GetParam ( ) ;
for ( ChecksumType t : GetSupportedChecksums ( ) ) {
switch ( t ) {
switch ( t ) {
case kNoChecksum :
case kNoChecksum :
EXPECT_EQ ( ChecksumAsString ( empty , t ) , " 00000000 " ) ;
EXPECT_EQ ( ChecksumAsString ( empty , t ) , " 00000000 " ) ;
@ -2364,6 +2371,42 @@ TEST_P(BlockBasedTableTest, ChecksumSchemas) {
break ;
break ;
}
}
}
}
TEST_P ( BuiltinChecksumTest , ChecksumZeroInputs ) {
// Verify that no reasonably sized "all zeros" inputs produce "all zeros"
// output. Otherwise, "wiped" data could appear to be well-formed.
// Assuming essentially random assignment of output values, the likelihood
// of encountering checksum == 0 for an input not specifically crafted is
// 1 in 4 billion.
if ( GetParam ( ) = = kNoChecksum ) {
return ;
}
// "Thorough" case is too slow for continouous testing
bool thorough = getenv ( " ROCKSDB_THOROUGH_CHECKSUM_TEST " ) ! = nullptr ;
// Verified through 10M
size_t kMaxZerosLen = thorough ? 10000000 : 20000 ;
std : : string zeros ( kMaxZerosLen , ' \0 ' ) ;
for ( size_t len = 0 ; len < kMaxZerosLen ; + + len ) {
if ( thorough & & ( len & 0xffffU ) = = 0 ) {
fprintf ( stderr , " t=%u len=%u \n " , ( unsigned ) GetParam ( ) , ( unsigned ) len ) ;
}
uint32_t v = ComputeBuiltinChecksum ( GetParam ( ) , zeros . data ( ) , len ) ;
if ( v = = 0U ) {
// One exception case:
if ( GetParam ( ) = = kXXH3 & & len = = 0 ) {
// This is not a big deal because assuming the block length is known
// from the block handle, which comes from a checksum-verified block,
// there is nothing to corrupt in a zero-length block. And when there
// is a block trailer with compression byte (as in block-based table),
// zero length checksummed data never arises.
continue ;
}
// Only compute this on failure
SCOPED_TRACE ( " len= " + std : : to_string ( len ) ) ;
ASSERT_NE ( v , 0U ) ;
}
}
}
}
void AddInternalKey ( TableConstructor * c , const std : : string & prefix ,
void AddInternalKey ( TableConstructor * c , const std : : string & prefix ,