diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 0e43d278b..743b16273 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -285,9 +285,9 @@ void ImportTest::checkExpectedState(State const& _stateExpect, State const& _sta #define CHECK(a,b) \ { \ if (_throw == WhenError::Throw) \ - BOOST_CHECK_MESSAGE(a,b); \ + {TBOOST_CHECK_MESSAGE(a,b);}\ else \ - BOOST_WARN_MESSAGE(a,b); \ + {TBOOST_WARN_MESSAGE(a,b);} \ } for (auto const& a: _stateExpect.addresses()) @@ -304,35 +304,35 @@ void ImportTest::checkExpectedState(State const& _stateExpect, State const& _sta } catch(std::out_of_range const&) { - BOOST_ERROR("expectedStateOptions map does not match expectedState in checkExpectedState!"); + TBOOST_ERROR("expectedStateOptions map does not match expectedState in checkExpectedState!"); break; } } if (addressOptions.m_bHasBalance) - CHECK(_stateExpect.balance(a.first) == _statePost.balance(a.first), + CHECK((_stateExpect.balance(a.first) == _statePost.balance(a.first)), "Check State: " << a.first << ": incorrect balance " << _statePost.balance(a.first) << ", expected " << _stateExpect.balance(a.first)); if (addressOptions.m_bHasNonce) - CHECK(_stateExpect.transactionsFrom(a.first) == _statePost.transactionsFrom(a.first), + CHECK((_stateExpect.transactionsFrom(a.first) == _statePost.transactionsFrom(a.first)), "Check State: " << a.first << ": incorrect nonce " << _statePost.transactionsFrom(a.first) << ", expected " << _stateExpect.transactionsFrom(a.first)); if (addressOptions.m_bHasStorage) { unordered_map stateStorage = _statePost.storage(a.first); for (auto const& s: _stateExpect.storage(a.first)) - CHECK(stateStorage[s.first] == s.second, + CHECK((stateStorage[s.first] == s.second), "Check State: " << a.first << ": incorrect storage [" << s.first << "] = " << toHex(stateStorage[s.first]) << ", expected [" << s.first << "] = " << toHex(s.second)); //Check for unexpected storage values stateStorage = _stateExpect.storage(a.first); for (auto const& s: _statePost.storage(a.first)) - CHECK(stateStorage[s.first] == s.second, + CHECK((stateStorage[s.first] == s.second), "Check State: " << a.first << ": incorrect storage [" << s.first << "] = " << toHex(s.second) << ", expected [" << s.first << "] = " << toHex(stateStorage[s.first])); } if (addressOptions.m_bHasCode) - CHECK(_stateExpect.code(a.first) == _statePost.code(a.first), + CHECK((_stateExpect.code(a.first) == _statePost.code(a.first)), "Check State: " << a.first << ": incorrect code '" << toHex(_statePost.code(a.first)) << "', expected '" << toHex(_stateExpect.code(a.first)) << "'"); } } @@ -518,18 +518,17 @@ void checkOutput(bytes const& _output, json_spirit::mObject& _o) int j = 0; if (_o["out"].get_str().find("#") == 0) - BOOST_CHECK((u256)_output.size() == toInt(_o["out"].get_str().substr(1))); - + {TBOOST_CHECK(((u256)_output.size() == toInt(_o["out"].get_str().substr(1))));} else if (_o["out"].type() == json_spirit::array_type) for (auto const& d: _o["out"].get_array()) { - BOOST_CHECK_MESSAGE(_output[j] == toInt(d), "Output byte [" << j << "] different!"); + TBOOST_CHECK_MESSAGE((_output[j] == toInt(d)), "Output byte [" << j << "] different!"); ++j; } else if (_o["out"].get_str().find("0x") == 0) - BOOST_CHECK(_output == fromHex(_o["out"].get_str().substr(2))); + {TBOOST_CHECK((_output == fromHex(_o["out"].get_str().substr(2))));} else - BOOST_CHECK(_output == fromHex(_o["out"].get_str())); + TBOOST_CHECK((_output == fromHex(_o["out"].get_str()))); } void checkStorage(map _expectedStore, map _resultStore, Address _expectedAddr) @@ -557,13 +556,13 @@ void checkStorage(map _expectedStore, map _resultStore, void checkLog(LogEntries _resultLogs, LogEntries _expectedLogs) { - BOOST_REQUIRE_EQUAL(_resultLogs.size(), _expectedLogs.size()); + TBOOST_REQUIRE_EQUAL(_resultLogs.size(), _expectedLogs.size()); for (size_t i = 0; i < _resultLogs.size(); ++i) { - BOOST_CHECK_EQUAL(_resultLogs[i].address, _expectedLogs[i].address); - BOOST_CHECK_EQUAL(_resultLogs[i].topics, _expectedLogs[i].topics); - BOOST_CHECK(_resultLogs[i].data == _expectedLogs[i].data); + TBOOST_CHECK_EQUAL(_resultLogs[i].address, _expectedLogs[i].address); + TBOOST_CHECK_EQUAL(_resultLogs[i].topics, _expectedLogs[i].topics); + TBOOST_CHECK((_resultLogs[i].data == _expectedLogs[i].data)); } } diff --git a/test/TestHelper.h b/test/TestHelper.h index df74c2dc3..b1ad923a7 100644 --- a/test/TestHelper.h +++ b/test/TestHelper.h @@ -35,13 +35,21 @@ #ifdef DONTUSE_BOOST_MACROS #define TBOOST_THROW_EXCEPTION(arg) throw dev::Exception(); #define TBOOST_REQUIRE(arg) if(arg == false) throw dev::Exception(); + #define TBOOST_REQUIRE_EQUAL(arg1, arg2) if(arg1 != arg2) throw dev::Exception(); + #define TBOOST_CHECK_EQUAL(arg1, arg2) if(arg1 != arg2) throw dev::Exception(); + #define TBOOST_CHECK(arg) if(arg == false) throw dev::Exception(); #define TBOOST_CHECK_MESSAGE(arg1, arg2) if(arg1 == false) throw dev::Exception(); #define TBOOST_WARN_MESSAGE(arg1, arg2) throw dev::Exception(); + #define TBOOST_ERROR(arg) throw dev::Exception(); #else #define TBOOST_THROW_EXCEPTION(arg) BOOST_THROW_EXCEPTION(arg) #define TBOOST_REQUIRE(arg) BOOST_REQUIRE(arg) + #define TBOOST_REQUIRE_EQUAL(arg1, arg2) BOOST_REQUIRE_EQUAL(arg1, arg2) + #define TBOOST_CHECK(arg) BOOOST_CHECK(arg) + #define TBOOST_CHECK_EQUAL(arg1, arg2) BOOST_CHECK_EQUAL(arg1, arg2) #define TBOOST_CHECK_MESSAGE(arg1, arg2) BOOST_CHECK_MESSAGE(arg1, arg2) #define TBOOST_WARN_MESSAGE(arg1, arg2) BOOST_WARN_MESSAGE(arg1, arg2) + #define TBOOST_ERROR(arg) BOOST_ERROR(arg) #endif namespace dev @@ -179,6 +187,7 @@ json_spirit::mObject fillJsonWithTransaction(eth::Transaction _txn); //Fill Test Functions void doTransactionTests(json_spirit::mValue& _v, bool _fillin); void doStateTests(json_spirit::mValue& v, bool _fillin); +void doVMTests(json_spirit::mValue& v, bool _fillin); template void checkAddresses(mapType& _expectedAddrs, mapType& _resultAddrs) @@ -188,9 +197,9 @@ void checkAddresses(mapType& _expectedAddrs, mapType& _resultAddrs) auto& resultAddr = resultPair.first; auto expectedAddrIt = _expectedAddrs.find(resultAddr); if (expectedAddrIt == _expectedAddrs.end()) - BOOST_ERROR("Missing result address " << resultAddr); + TBOOST_ERROR("Missing result address " << resultAddr); } - BOOST_CHECK(_expectedAddrs == _resultAddrs); + TBOOST_CHECK((_expectedAddrs == _resultAddrs)); } class Options diff --git a/test/fuzzTesting/CMakeLists.txt b/test/fuzzTesting/CMakeLists.txt index f25a2b31e..9cdc7eb60 100644 --- a/test/fuzzTesting/CMakeLists.txt +++ b/test/fuzzTesting/CMakeLists.txt @@ -8,7 +8,8 @@ include_directories(${Boost_INCLUDE_DIRS}) include_directories(${CRYPTOPP_INCLUDE_DIRS}) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) -add_executable(createRandomTest "./createRandomTest.cpp" "../TestHelper.cpp" "../Stats.cpp" "fuzzHelper.cpp" "../libethereum/transaction.cpp" "../libethereum/state.cpp") +add_executable(createRandomTest "./createRandomTest.cpp" "../TestHelper.cpp" "../Stats.cpp" "fuzzHelper.cpp" "../libethereum/transaction.cpp" "../libethereum/state.cpp" "../libevm/vm.cpp") + add_executable(createRandomVMTest "./createRandomVMTest.cpp" "../libevm/vm.cpp" "../TestHelper.cpp" "../Stats.cpp") add_executable(createRandomStateTest "./createRandomStateTest.cpp" "../TestHelper.cpp" "../Stats.cpp" "fuzzHelper.cpp") add_executable(checkRandomVMTest "./checkRandomVMTest.cpp" "../libevm/vm.cpp" "../TestHelper.cpp" "../Stats.cpp" ) diff --git a/test/fuzzTesting/createRandomTest.cpp b/test/fuzzTesting/createRandomTest.cpp index 373207f44..a42ead3ef 100644 --- a/test/fuzzTesting/createRandomTest.cpp +++ b/test/fuzzTesting/createRandomTest.cpp @@ -19,18 +19,23 @@ * @date 2015 */ +///This file require #define DONTUSE_BOOST_MACROS compile flag to run! + #include #include #include #include +#include //String Variables extern std::string const c_testExampleStateTest; extern std::string const c_testExampleTransactionTest; +extern std::string const c_testExampleVMTest; //Main Test functinos void fillRandomTest(std::function doTests, std::string const& testString); +int checkRandomTest(std::function doTests, json_spirit::mValue& value); //Helper Functions std::vector getTypes(); @@ -39,35 +44,111 @@ void parseTestWithTypes(std::string& test); int main(int argc, char *argv[]) { std::string testSuite; + json_spirit::mValue testValue; + bool checktest = false; for (auto i = 0; i < argc; ++i) { auto arg = std::string{argv[i]}; dev::test::Options& options = const_cast(dev::test::Options::get()); if (arg == "--fulloutput") options.fulloutput = true; + else if (arg == "-t" && i + 1 < argc) { testSuite = argv[i + 1]; - if (testSuite != "BlockChainTests" && testSuite != "TransactionTests" && testSuite != "StateTests") + if (testSuite != "BlockChainTests" && testSuite != "TransactionTests" && testSuite != "StateTests" && testSuite != "VMTests") testSuite = ""; } + else + if (arg == "-checktest" && i + 1 < argc) + { + std::string s; + for (int j = i+1; j < argc; ++j) + s += argv[j]; + if (asserts(s.length() > 0)) + { + std::cout << "Error! Content of argument is empty! (Usage -checktest textstream) \n"; + return 1; + } + read_string(s, testValue); + checktest = true; + } } if (testSuite == "") + { std::cout << "Error! Test suite not supported! (Usage -t TestSuite)"; + return 1; + } else if (testSuite == "BlockChainTests") - fillRandomTest(dev::test::doTransactionTests, c_testExampleTransactionTest); + { + if (checktest) + return checkRandomTest(dev::test::doTransactionTests, testValue); + else + fillRandomTest(dev::test::doTransactionTests, c_testExampleTransactionTest); + } else if (testSuite == "TransactionTests") - fillRandomTest(dev::test::doTransactionTests, c_testExampleTransactionTest); + { + if (checktest) + return checkRandomTest(dev::test::doTransactionTests, testValue); + else + fillRandomTest(dev::test::doTransactionTests, c_testExampleTransactionTest); + } else if (testSuite == "StateTests") - fillRandomTest(dev::test::doStateTests, c_testExampleStateTest); + { + if (checktest) + return checkRandomTest(dev::test::doStateTests, testValue); + else + fillRandomTest(dev::test::doStateTests, c_testExampleStateTest); + } + else + if (testSuite == "VMTests") + { + if (checktest) + { + dev::eth::VMFactory::setKind(dev::eth::VMKind::JIT); + return checkRandomTest(dev::test::doVMTests, testValue); + } + else + fillRandomTest(dev::test::doVMTests, c_testExampleVMTest); + } return 0; } +int checkRandomTest(std::function doTests, json_spirit::mValue& value) +{ + bool ret = 0; + try + { + //redirect all output to the stream + std::ostringstream strCout; + std::streambuf* oldCoutStreamBuf = std::cout.rdbuf(); + std::cout.rdbuf( strCout.rdbuf() ); + std::cerr.rdbuf( strCout.rdbuf() ); + + doTests(value, false); + + //restroe output + std::cout.rdbuf(oldCoutStreamBuf); + std::cerr.rdbuf(oldCoutStreamBuf); + } + catch (dev::Exception const& _e) + { + std::cout << "Failed test with Exception: " << diagnostic_information(_e) << std::endl; + ret = 1; + } + catch (std::exception const& _e) + { + std::cout << "Failed test with Exception: " << _e.what() << std::endl; + ret = 1; + } + return ret; +} + void fillRandomTest(std::function doTests, std::string const& testString) { //redirect all output to the stream @@ -107,6 +188,7 @@ void parseTestWithTypes(std::string& _test) options.addAddress(dev::Address("0x095e7baea6a6c7c4c2dfeb977efac326af552d87")); options.addAddress(dev::Address("0x945304eb96065b2a98b57a48a06ae28d285a71b5")); options.addAddress(dev::Address("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")); + options.addAddress(dev::Address("0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6")); options.addAddress(dev::Address("0x0000000000000000000000000000000000000001")); options.addAddress(dev::Address("0x0000000000000000000000000000000000000002")); options.addAddress(dev::Address("0x0000000000000000000000000000000000000003")); @@ -138,10 +220,10 @@ void parseTestWithTypes(std::string& _test) { int random = dev::test::RandomCode::randomUniInt() % 100; if (random < 30) - _test.replace(pos, 3, "28"); + _test.replace(pos, 3, "0x1c"); else if (random < 60) - _test.replace(pos, 3, "29"); + _test.replace(pos, 3, "0x1d"); else _test.replace(pos, 3, "0x" + dev::test::RandomCode::rndByteSequence(1)); } @@ -221,3 +303,35 @@ std::string const c_testExampleStateTest = R"( } } )"; + +std::string const c_testExampleVMTest = R"( +{ + "randomVMTest": { + "env" : { + "previousHash" : "[HASH32]", + "currentNumber" : "[HEX]", + "currentGasLimit" : "[HEX]", + "currentDifficulty" : "[HEX]", + "currentTimestamp" : "[HEX]", + "currentCoinbase" : "[HASH20]" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "[HEX]", + "nonce" : "[HEX]", + "code" : "[CODE]", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "[HASH20]", + "caller" : "[HASH20]", + "value" : "[HEX]", + "data" : "[CODE]", + "gasPrice" : "[V]", + "gas" : "[HEX]" + } + } +} +)"; diff --git a/test/libevm/vm.cpp b/test/libevm/vm.cpp index ea9339f05..25ed8113b 100644 --- a/test/libevm/vm.cpp +++ b/test/libevm/vm.cpp @@ -306,9 +306,9 @@ void doVMTests(json_spirit::mValue& v, bool _fillin) } std::cout << " " << i.first << "\n"; - BOOST_REQUIRE(o.count("env") > 0); - BOOST_REQUIRE(o.count("pre") > 0); - BOOST_REQUIRE(o.count("exec") > 0); + TBOOST_REQUIRE((o.count("env") > 0)); + TBOOST_REQUIRE((o.count("pre") > 0)); + TBOOST_REQUIRE((o.count("exec") > 0)); FakeExtVM fev; fev.importEnv(o["env"].get_obj()); @@ -344,12 +344,12 @@ void doVMTests(json_spirit::mValue& v, bool _fillin) catch (Exception const& _e) { cnote << "VM did throw an exception: " << diagnostic_information(_e); - BOOST_ERROR("Failed VM Test with Exception: " << _e.what()); + TBOOST_ERROR("Failed VM Test with Exception: " << _e.what()); } catch (std::exception const& _e) { cnote << "VM did throw an exception: " << _e.what(); - BOOST_ERROR("Failed VM Test with Exception: " << _e.what()); + TBOOST_ERROR("Failed VM Test with Exception: " << _e.what()); } // delete null entries in storage for the sake of comparison @@ -410,13 +410,13 @@ void doVMTests(json_spirit::mValue& v, bool _fillin) { if (o.count("post") > 0) // No exceptions expected { - BOOST_CHECK(!vmExceptionOccured); + TBOOST_CHECK(!vmExceptionOccured); - BOOST_REQUIRE(o.count("post") > 0); - BOOST_REQUIRE(o.count("callcreates") > 0); - BOOST_REQUIRE(o.count("out") > 0); - BOOST_REQUIRE(o.count("gas") > 0); - BOOST_REQUIRE(o.count("logs") > 0); + TBOOST_REQUIRE((o.count("post") > 0)); + TBOOST_REQUIRE((o.count("callcreates") > 0)); + TBOOST_REQUIRE((o.count("out") > 0)); + TBOOST_REQUIRE((o.count("gas") > 0)); + TBOOST_REQUIRE((o.count("logs") > 0)); dev::test::FakeExtVM test; test.importState(o["post"].get_obj()); @@ -425,7 +425,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin) checkOutput(output, o); - BOOST_CHECK_EQUAL(toInt(o["gas"]), fev.gas); + TBOOST_CHECK_EQUAL(toInt(o["gas"]), fev.gas); State postState, expectState; mObject mPostState = fev.exportState(); @@ -435,7 +435,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin) checkAddresses, bytes> > >(test.addresses, fev.addresses); - checkCallCreates(test.callcreates, fev.callcreates); + checkCallCreates(fev.callcreates, test.callcreates); checkLog(fev.sub.logs, test.sub.logs); }