@ -40,8 +40,125 @@ namespace js = json_spirit;
namespace dev
{
namespace test
{
static void buildRLP ( js : : mValue & _v , RLPStream & _rlp )
{
void buildRLP ( js : : mValue & _v , RLPStream & _rlp ) ;
void checkRLPAgainstJson ( js : : mValue & v , RLP & u ) ;
enum class RlpType
{
Valid ,
Invalid ,
Test
} ;
void doRlpTests ( json_spirit : : mValue & v , bool _fillin )
{
for ( auto & i : v . get_obj ( ) )
{
js : : mObject & o = i . second . get_obj ( ) ;
if ( test : : Options : : get ( ) . singleTest & & test : : Options : : get ( ) . singleTestName ! = i . first )
{
o . clear ( ) ;
continue ;
}
cout < < " " < < i . first < < endl ;
TBOOST_REQUIRE ( ( o . count ( " out " ) > 0 ) ) ;
TBOOST_REQUIRE ( ( ! o [ " out " ] . is_null ( ) ) ) ;
if ( _fillin )
{
try
{
bytes payloadToDecode = fromHex ( o [ " out " ] . get_str ( ) ) ;
RLP payload ( payloadToDecode ) ;
if ( payload . isEmpty ( ) )
BOOST_THROW_EXCEPTION ( RLPException ( ) < < errinfo_comment ( " Decoded Empty RLP! " ) ) ;
o [ " in " ] = " VALID " ;
}
catch ( Exception const & _e )
{
cnote < < " Exception: " < < diagnostic_information ( _e ) ;
o [ " in " ] = " INVALID " ;
}
catch ( std : : exception const & _e )
{
cnote < < " rlp exception: " < < _e . what ( ) ;
o [ " in " ] = " INVALID " ;
}
}
else
{
//Check Encode
TBOOST_REQUIRE ( ( o . count ( " in " ) > 0 ) ) ;
RlpType rlpType = RlpType : : Test ;
if ( o [ " in " ] . type ( ) = = js : : str_type )
{
if ( o [ " in " ] . get_str ( ) = = " INVALID " )
rlpType = RlpType : : Invalid ;
else if ( o [ " in " ] . get_str ( ) = = " VALID " )
rlpType = RlpType : : Valid ;
}
if ( rlpType = = RlpType : : Test )
{
RLPStream s ;
dev : : test : : buildRLP ( o [ " in " ] , s ) ;
string computedText = toHex ( s . out ( ) ) ;
string expectedText ( o [ " out " ] . get_str ( ) ) ;
transform ( expectedText . begin ( ) , expectedText . end ( ) , expectedText . begin ( ) , : : tolower ) ;
stringstream msg ;
msg < < " Encoding Failed: expected: " < < expectedText < < std : : endl ;
msg < < " But Computed: " < < computedText ;
TBOOST_CHECK_MESSAGE (
( expectedText = = computedText ) ,
msg . str ( )
) ;
}
//Check Decode
// Uses the same test cases as encoding but in reverse.
// We read into the string of hex values, convert to bytes,
// and then compare the output structure to the json of the
// input object.
bool was_exception = false ;
js : : mValue & inputData = o [ " in " ] ;
try
{
bytes payloadToDecode = fromHex ( o [ " out " ] . get_str ( ) ) ;
RLP payload ( payloadToDecode ) ;
if ( rlpType = = RlpType : : Test )
dev : : test : : checkRLPAgainstJson ( inputData , payload ) ;
}
catch ( Exception const & _e )
{
cnote < < " Exception: " < < diagnostic_information ( _e ) ;
was_exception = true ;
}
catch ( exception const & _e )
{
cnote < < " rlp exception: " < < _e . what ( ) ;
was_exception = true ;
}
//Expect exception as input is INVALID
if ( rlpType = = RlpType : : Invalid & & was_exception )
continue ;
//Check that there was an exception as input is INVALID
if ( rlpType = = RlpType : : Invalid & & ! was_exception )
TBOOST_ERROR ( " Expected RLP Exception as rlp should be invalid! " ) ;
//input is VALID check that there was no exceptions
if ( was_exception )
TBOOST_ERROR ( " Unexpected RLP Exception! " ) ;
}
}
}
void buildRLP ( js : : mValue & _v , RLPStream & _rlp )
{
if ( _v . type ( ) = = js : : array_type )
{
@ -62,67 +179,46 @@ namespace dev
}
}
static void getRLPTestCases ( js : : mValue & v )
{
string testPath = getTestPath ( ) ;
testPath + = " /BasicTests " ;
string s = contentsString ( testPath + " /rlptest.json " ) ;
BOOST_REQUIRE_MESSAGE ( s . length ( ) > 0 ,
" Contents of 'rlptest.json' is empty. Have you cloned the 'tests' repo branch develop? " ) ;
js : : read_string ( s , v ) ;
}
static void checkRLPTestCase ( js : : mObject & o )
{
BOOST_REQUIRE ( o . count ( " in " ) > 0 ) ;
BOOST_REQUIRE ( o . count ( " out " ) > 0 ) ;
BOOST_REQUIRE ( ! o [ " out " ] . is_null ( ) ) ;
}
static void checkRLPAgainstJson ( js : : mValue & v , RLP & u )
void checkRLPAgainstJson ( js : : mValue & v , RLP & u )
{
if ( v . type ( ) = = js : : str_type )
{
const std : : st ring & expectedText = v . get_str ( ) ;
const string & expectedText = v . get_str ( ) ;
if ( ! expectedText . empty ( ) & & expectedText . front ( ) = = ' # ' )
{
// Deal with bigint instead of a raw string
std : : st ring bigIntStr = expectedText . substr ( 1 , expectedText . length ( ) - 1 ) ;
std : : st ringstream bintStream ( bigIntStr ) ;
string bigIntStr = expectedText . substr ( 1 , expectedText . length ( ) - 1 ) ;
stringstream bintStream ( bigIntStr ) ;
bigint val ;
bintStream > > val ;
BOOST_CHECK ( ! u . isList ( ) ) ;
BOOST_CHECK ( ! u . isNull ( ) ) ;
BOOST_CHECK ( u ) ; // operator bool()
BOOST_CHECK ( u = = val ) ;
TBOOST_CHECK ( ( ! u . isList ( ) ) ) ;
TBOOST_CHECK ( ( ! u . isNull ( ) ) ) ;
TBOOST_CHECK ( ( u = = val ) ) ;
}
else
{
BOOST_CHECK ( ! u . isList ( ) ) ;
BOOST_CHECK ( ! u . isNull ( ) ) ;
BOOST_CHECK ( u . isData ( ) ) ;
BOOST_CHECK ( u ) ;
BOOST_CHECK ( u . size ( ) = = expectedText . length ( ) ) ;
BOOST_CHECK ( u = = expectedText ) ;
TBOOST_CHECK ( ( ! u . isList ( ) ) ) ;
TBOOST_CHECK ( ( ! u . isNull ( ) ) ) ;
TBOOST_CHECK ( ( u . isData ( ) ) ) ;
TBOOST_CHECK ( ( u . size ( ) = = expectedText . length ( ) ) ) ;
TBOOST_CHECK ( ( u = = expectedText ) ) ;
}
}
else if ( v . type ( ) = = js : : int_type )
{
const int expectedValue = v . get_int ( ) ;
BOOST_CHECK ( u . isInt ( ) ) ;
BOOST_CHECK ( ! u . isList ( ) ) ;
BOOST_CHECK ( ! u . isNull ( ) ) ;
BOOST_CHECK ( u ) ; // operator bool()
BOOST_CHECK ( u = = expectedValue ) ;
TBOOST_CHECK ( ( u . isInt ( ) ) ) ;
TBOOST_CHECK ( ( ! u . isList ( ) ) ) ;
TBOOST_CHECK ( ( ! u . isNull ( ) ) ) ;
TBOOST_CHECK ( ( u = = expectedValue ) ) ;
}
else if ( v . type ( ) = = js : : array_type )
{
BOOST_CHECK ( u . isList ( ) ) ;
BOOST_CHECK ( ! u . isInt ( ) ) ;
BOOST_CHECK ( ! u . isData ( ) ) ;
T BOOST_CHECK( ( u . isList ( ) ) ) ;
T BOOST_CHECK( ( ! u . isInt ( ) ) ) ;
T BOOST_CHECK( ( ! u . isData ( ) ) ) ;
js : : mArray & arr = v . get_array ( ) ;
BOOST_CHECK ( u . itemCount ( ) = = arr . size ( ) ) ;
T BOOST_CHECK( ( u . itemCount ( ) = = arr . size ( ) ) ) ;
unsigned i ;
for ( i = 0 ; i < arr . size ( ) ; i + + )
{
@ -132,71 +228,59 @@ namespace dev
}
else
{
BOOST_ERROR ( " Invalid Javascript object! " ) ;
T BOOST_ERROR( " Invalid Javascript object! " ) ;
}
}
}
}
BOOST_AUTO_TEST_SUITE ( Basic Tests)
BOOST_AUTO_TEST_SUITE ( Rlp Tests)
BOOST_AUTO_TEST_CASE ( rlp_encoding_ test)
BOOST_AUTO_TEST_CASE ( invalidRLP test)
{
cnote < < " Testing RLP Encoding... " ;
js : : mValue v ;
dev : : test : : getRLPTestCases ( v ) ;
for ( auto & i : v . get_obj ( ) )
{
js : : mObject & o = i . second . get_obj ( ) ;
cnote < < i . first ;
dev : : test : : checkRLPTestCase ( o ) ;
RLPStream s ;
dev : : test : : buildRLP ( o [ " in " ] , s ) ;
std : : string expectedText ( o [ " out " ] . get_str ( ) ) ;
std : : transform ( expectedText . begin ( ) , expectedText . end ( ) , expectedText . begin ( ) , : : tolower ) ;
const std : : string & computedText = toHex ( s . out ( ) ) ;
std : : stringstream msg ;
msg < < " Encoding Failed: expected: " < < expectedText < < std : : endl ;
msg < < " But Computed: " < < computedText ;
BOOST_CHECK_MESSAGE (
expectedText = = computedText ,
msg . str ( )
) ;
}
dev : : test : : executeTests ( " invalidRLPTest " , " /RLPTests " , dev : : test : : getFolder ( __FILE__ ) + " /RLPTestsFiller " , dev : : test : : doRlpTests ) ;
}
BOOST_AUTO_TEST_CASE ( rlptest )
{
dev : : test : : executeTests ( " rlptest " , " /RLPTests " , dev : : test : : getFolder ( __FILE__ ) + " /RLPTestsFiller " , dev : : test : : doRlpTests ) ;
}
BOOST_AUTO_TEST_CASE ( rlp_decoding_test )
BOOST_AUTO_TEST_CASE ( rlpRandom )
{
cnote < < " Testing RLP decoding... " ;
// Uses the same test cases as encoding but in reverse.
// We read into the string of hex values, convert to bytes,
// and then compare the output structure to the json of the
// input object.
js : : mValue v ;
dev : : test : : getRLPTestCases ( v ) ;
for ( auto & i : v . get_obj ( ) )
{
js : : mObject & o = i . second . get_obj ( ) ;
cnote < < i . first ;
dev : : test : : checkRLPTestCase ( o ) ;
test : : Options : : get ( ) ;
js : : mValue & inputData = o [ " in " ] ;
bytes payloadToDecode = fromHex ( o [ " out " ] . get_str ( ) ) ;
string testPath = dev : : test : : getTestPath ( ) ;
testPath + = " /RLPTests/RandomRLPTests " ;
RLP payload ( payloadToDecode ) ;
vector < boost : : filesystem : : path > testFiles ;
boost : : filesystem : : directory_iterator iterator ( testPath ) ;
for ( ; iterator ! = boost : : filesystem : : directory_iterator ( ) ; + + iterator )
if ( boost : : filesystem : : is_regular_file ( iterator - > path ( ) ) & & iterator - > path ( ) . extension ( ) = = " .json " )
testFiles . push_back ( iterator - > path ( ) ) ;
dev : : test : : checkRLPAgainstJson ( inputData , payload ) ;
for ( auto & path : testFiles )
{
try
{
cnote < < " Testing ... " < < path . filename ( ) ;
json_spirit : : mValue v ;
string s = asString ( dev : : contents ( path . string ( ) ) ) ;
TBOOST_REQUIRE_MESSAGE ( ( s . length ( ) > 0 ) , " Content of " + path . string ( ) + " is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path? " ) ;
json_spirit : : read_string ( s , v ) ;
test : : Listener : : notifySuiteStarted ( path . filename ( ) . string ( ) ) ;
dev : : test : : doRlpTests ( v , false ) ;
}
catch ( Exception const & _e )
{
TBOOST_ERROR ( " Failed test with Exception: " < < diagnostic_information ( _e ) ) ;
}
catch ( std : : exception const & _e )
{
TBOOST_ERROR ( " Failed test with Exception: " < < _e . what ( ) ) ;
}
}
}
BOOST_AUTO_TEST_SUITE_END ( )