Add binary data string difference reporting to PipeCapture tests (#777973)
Google Test string comparison asserts are only designed of C style strings containing printable text of one or more lines with a terminating NUL character. GParted is crashing when PipeCapture is reading the binary file names being reported by fsck.fat from a very corrupted FAT file system. Therefore need to be able to compare and report differences of binary data stored in C++ std::string and Glib::ustrings. Write a specific assertion to handle this. Now these sample tests: TEST_F( PipeCaptureTest, BinaryStringFailure ) { inputstr = "AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCC"; capturedstr = "AAAAAAAAAAAAAAAABBBBBBBBBBbbbb"; EXPECT_BINARYSTRINGEQ( inputstr, capturedstr.raw() ); } TEST_F( PipeCaptureTest, LeadingBinaryStringFailure ) { inputstr = "The quick brown fox jumps over the lazy dog"; capturedstr = "The quick brown fox\n"; EXPECT_BINARYSTRINGEQ( inputstr.substr( 0, capturedstr.raw().length() ), capturedstr.raw() ); } report failure like this: $ ./test_PipeCapture ... [ RUN ] PipeCaptureTest.BinaryStringFailure test_PipeCapture.cc:270: Failure Expected: inputstr Of length: 48 To be equal to: capturedstr.raw() Of length: 30 With first binary difference: < 0x00000010 "BBBBBBBBBBBBBBBB" 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 -- > 0x00000010 "BBBBBBBBBBbbbb" 42 42 42 42 42 42 42 42 42 42 62 62 62 62 [ FAILED ] PipeCaptureTest.BinaryStringFailure (1 ms) [ RUN ] PipeCaptureTest.LeadingBinaryStringFailure test_PipeCapture.cc:278: Failure Expected: inputstr.substr( 0, capturedstr.raw().length() ) Of length: 20 To be equal to: capturedstr.raw() Of length: 20 With first binary difference: < 0x00000010 "fox " 66 6F 78 20 -- > 0x00000010 "fox." 66 6F 78 0A [ FAILED ] PipeCaptureTest.LeadingBinaryStringFailure (0 ms) ... Bug 777973 - Segmentation fault on bad disk
This commit is contained in:
parent
eb2d571a6c
commit
dc1c49ba62
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <sstream>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -46,6 +47,95 @@ static std::string repeat( const std::string & str, size_t count )
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Number of bytes of binary data to compare and report.
|
||||||
|
const size_t BinaryStringDiffSize = 16;
|
||||||
|
|
||||||
|
// Format up to 16 bytes of binary data ready for printing as:
|
||||||
|
// Hex offset ASCII text Hex bytes
|
||||||
|
// "0x000000000 \"ABCDEFGHabcdefgh\" 41 42 43 44 45 46 47 48 61 62 63 64 65 66 67 68"
|
||||||
|
std::string BinaryStringToPrint( size_t offset, const char * s, size_t len )
|
||||||
|
{
|
||||||
|
std::ostringstream result;
|
||||||
|
|
||||||
|
result << "0x";
|
||||||
|
result.fill( '0' );
|
||||||
|
result << std::setw( 8 ) << std::hex << std::uppercase << offset << " \"";
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
for ( i = 0 ; i < BinaryStringDiffSize && i < len ; i ++ )
|
||||||
|
result.put( ( isprint( s[i] ) ) ? s[i] : '.' );
|
||||||
|
result.put( '\"' );
|
||||||
|
|
||||||
|
if ( len > 0 )
|
||||||
|
{
|
||||||
|
for ( ; i < BinaryStringDiffSize ; i ++ )
|
||||||
|
result.put( ' ' );
|
||||||
|
result.put( ' ' );
|
||||||
|
|
||||||
|
for ( i = 0 ; i < BinaryStringDiffSize && i < len ; i ++ )
|
||||||
|
result << " "
|
||||||
|
<< std::setw( 2 ) << std::hex << std::uppercase
|
||||||
|
<< (unsigned int)(unsigned char)s[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to construct and return message for equality assertion of C++ strings containing
|
||||||
|
// binary data used in:
|
||||||
|
// EXPECT_BINARYSTRINGEQ( str1, str2 )
|
||||||
|
::testing::AssertionResult CompareHelperBinaryStringEQ( const char * lhs_expr, const char * rhs_expr,
|
||||||
|
const std::string & lhs, const std::string & rhs )
|
||||||
|
{
|
||||||
|
// Loop comparing binary data in 16 byte amounts, stopping and reporting the first
|
||||||
|
// difference encountered.
|
||||||
|
bool diff = false;
|
||||||
|
const char * p1 = lhs.data();
|
||||||
|
const char * p2 = rhs.data();
|
||||||
|
size_t len1 = lhs.length();
|
||||||
|
size_t len2 = rhs.length();
|
||||||
|
while ( len1 > 0 || len2 > 0 )
|
||||||
|
{
|
||||||
|
size_t cmp_span = BinaryStringDiffSize;
|
||||||
|
cmp_span = ( len1 < cmp_span ) ? len1 : cmp_span;
|
||||||
|
cmp_span = ( len2 < cmp_span ) ? len2 : cmp_span;
|
||||||
|
if ( cmp_span < BinaryStringDiffSize && len1 != len2 )
|
||||||
|
{
|
||||||
|
diff = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( memcmp( p1, p2, cmp_span ) != 0 )
|
||||||
|
{
|
||||||
|
diff = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p1 += cmp_span;
|
||||||
|
p2 += cmp_span;
|
||||||
|
len1 -= cmp_span;
|
||||||
|
len2 -= cmp_span;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! diff )
|
||||||
|
return ::testing::AssertionSuccess();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t offset = p1 - lhs.data();
|
||||||
|
return ::testing::AssertionFailure()
|
||||||
|
<< " Expected: " << lhs_expr << "\n"
|
||||||
|
<< " Of length: " << lhs.length() << "\n"
|
||||||
|
<< "To be equal to: " << rhs_expr << "\n"
|
||||||
|
<< " Of length: " << rhs.length() << "\n"
|
||||||
|
<< "With first binary difference:\n"
|
||||||
|
<< "< " << BinaryStringToPrint( offset, p1, len1 ) << "\n"
|
||||||
|
<< "--\n"
|
||||||
|
<< "> " << BinaryStringToPrint( offset, p2, len2 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nonfatal assertion that binary data in C++ strings are equal.
|
||||||
|
#define EXPECT_BINARYSTRINGEQ(str1, str2) \
|
||||||
|
EXPECT_PRED_FORMAT2(CompareHelperBinaryStringEQ, str1, str2)
|
||||||
|
|
||||||
// Explicit test fixture class with common variables and methods used in each test.
|
// Explicit test fixture class with common variables and methods used in each test.
|
||||||
// Reference:
|
// Reference:
|
||||||
// Google Test, Primer, Test Fixtures: Using the Same Data Configuration for Multiple Tests
|
// Google Test, Primer, Test Fixtures: Using the Same Data Configuration for Multiple Tests
|
||||||
|
@ -140,7 +230,7 @@ TEST_F( PipeCaptureTest, EmptyPipe )
|
||||||
PipeCapture pc( pipefds[ReaderFD], capturedstr );
|
PipeCapture pc( pipefds[ReaderFD], capturedstr );
|
||||||
pc.connect_signal();
|
pc.connect_signal();
|
||||||
run_writer_thread();
|
run_writer_thread();
|
||||||
EXPECT_STREQ( inputstr.c_str(), capturedstr.c_str() );
|
EXPECT_BINARYSTRINGEQ( inputstr, capturedstr.raw() );
|
||||||
EXPECT_FALSE( eof_signalled );
|
EXPECT_FALSE( eof_signalled );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +242,7 @@ TEST_F( PipeCaptureTest, EmptyPipeWithEOF )
|
||||||
pc.signal_eof.connect( sigc::mem_fun( *this, &PipeCaptureTest::eof_callback ) );
|
pc.signal_eof.connect( sigc::mem_fun( *this, &PipeCaptureTest::eof_callback ) );
|
||||||
pc.connect_signal();
|
pc.connect_signal();
|
||||||
run_writer_thread();
|
run_writer_thread();
|
||||||
EXPECT_STREQ( inputstr.c_str(), capturedstr.c_str() );
|
EXPECT_BINARYSTRINGEQ( inputstr, capturedstr.raw() );
|
||||||
EXPECT_TRUE( eof_signalled );
|
EXPECT_TRUE( eof_signalled );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +254,7 @@ TEST_F( PipeCaptureTest, ShortASCIIText )
|
||||||
pc.signal_eof.connect( sigc::mem_fun( *this, &PipeCaptureTest::eof_callback ) );
|
pc.signal_eof.connect( sigc::mem_fun( *this, &PipeCaptureTest::eof_callback ) );
|
||||||
pc.connect_signal();
|
pc.connect_signal();
|
||||||
run_writer_thread();
|
run_writer_thread();
|
||||||
EXPECT_STREQ( inputstr.c_str(), capturedstr.c_str() );
|
EXPECT_BINARYSTRINGEQ( inputstr, capturedstr.raw() );
|
||||||
EXPECT_TRUE( eof_signalled );
|
EXPECT_TRUE( eof_signalled );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +266,7 @@ TEST_F( PipeCaptureTest, LongASCIIText )
|
||||||
pc.signal_eof.connect( sigc::mem_fun( *this, &PipeCaptureTest::eof_callback ) );
|
pc.signal_eof.connect( sigc::mem_fun( *this, &PipeCaptureTest::eof_callback ) );
|
||||||
pc.connect_signal();
|
pc.connect_signal();
|
||||||
run_writer_thread();
|
run_writer_thread();
|
||||||
EXPECT_STREQ( inputstr.c_str(), capturedstr.c_str() );
|
EXPECT_BINARYSTRINGEQ( inputstr, capturedstr.raw() );
|
||||||
EXPECT_TRUE( eof_signalled );
|
EXPECT_TRUE( eof_signalled );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue