Browse Source

createRandomTest: State test

cl-refactor
Dimitry 10 years ago
parent
commit
b72edc27d0
  1. 14
      test/TestHelper.cpp
  2. 1
      test/TestHelper.h
  3. 2
      test/fuzzTesting/CMakeLists.txt
  4. 119
      test/fuzzTesting/createRandomTest.cpp
  5. 7
      test/fuzzTesting/fuzzHelper.cpp
  6. 6
      test/fuzzTesting/fuzzHelper.h
  7. 14
      test/libethereum/state.cpp

14
test/TestHelper.cpp

@ -178,7 +178,7 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state, stateOptio
{
stateOptions.m_bHasBalance = true;
if (bigint(o["balance"].get_str()) >= c_max256plus1)
BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("State 'balance' is equal or greater than 2**256") );
TBOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("State 'balance' is equal or greater than 2**256") );
balance = toInt(o["balance"]);
}
@ -186,7 +186,7 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state, stateOptio
{
stateOptions.m_bHasNonce = true;
if (bigint(o["nonce"].get_str()) >= c_max256plus1)
BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("State 'nonce' is equal or greater than 2**256") );
TBOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("State 'nonce' is equal or greater than 2**256") );
nonce = toInt(o["nonce"]);
}
@ -230,7 +230,7 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state)
{
//check that every parameter was declared in state object
if (!stateOptionMap.second.isAllSet())
BOOST_THROW_EXCEPTION(MissingFields() << errinfo_comment("Import State: Missing state fields!"));
TBOOST_THROW_EXCEPTION(MissingFields() << errinfo_comment("Import State: Missing state fields!"));
}
}
@ -246,13 +246,13 @@ void ImportTest::importTransaction(json_spirit::mObject& _o)
assert(_o.count("data") > 0);
if (bigint(_o["nonce"].get_str()) >= c_max256plus1)
BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'nonce' is equal or greater than 2**256") );
TBOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'nonce' is equal or greater than 2**256") );
if (bigint(_o["gasPrice"].get_str()) >= c_max256plus1)
BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'gasPrice' is equal or greater than 2**256") );
TBOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'gasPrice' is equal or greater than 2**256") );
if (bigint(_o["gasLimit"].get_str()) >= c_max256plus1)
BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'gasLimit' is equal or greater than 2**256") );
TBOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'gasLimit' is equal or greater than 2**256") );
if (bigint(_o["value"].get_str()) >= c_max256plus1)
BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'value' is equal or greater than 2**256") );
TBOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'value' is equal or greater than 2**256") );
m_transaction = _o["to"].get_str().empty() ?
Transaction(toInt(_o["value"]), toInt(_o["gasPrice"]), toInt(_o["gasLimit"]), importData(_o), toInt(_o["nonce"]), Secret(_o["secretKey"].get_str())) :

1
test/TestHelper.h

@ -178,6 +178,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);
template<typename mapType>
void checkAddresses(mapType& _expectedAddrs, mapType& _resultAddrs)

2
test/fuzzTesting/CMakeLists.txt

@ -8,7 +8,7 @@ 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")
add_executable(createRandomTest "./createRandomTest.cpp" "../TestHelper.cpp" "../Stats.cpp" "fuzzHelper.cpp" "../libethereum/transaction.cpp" "../libethereum/state.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" )

119
test/fuzzTesting/createRandomTest.cpp

@ -25,12 +25,16 @@
#include <test/TestHelper.h>
#include <test/fuzzTesting/fuzzHelper.h>
//String Variables
extern std::string const c_testExampleStateTest;
extern std::string const c_testExampleTransactionTest;
//Main Test functinos
void fillRandomTest(std::function<void(json_spirit::mValue&, bool)> doTests, std::string const& testString);
//Helper Functions
std::vector<std::string> getTypes();
void parseTestWithTypes(std::string& test);
void randomTransactionTest();
void randomBlockChainTest();
int main(int argc, char *argv[])
{
@ -44,7 +48,7 @@ int main(int argc, char *argv[])
if (arg == "-t" && i + 1 < argc)
{
testSuite = argv[i + 1];
if (testSuite != "BlockChainTests" && testSuite != "TransactionTests")
if (testSuite != "BlockChainTests" && testSuite != "TransactionTests" && testSuite != "StateTests")
testSuite = "";
}
}
@ -53,15 +57,18 @@ int main(int argc, char *argv[])
std::cout << "Error! Test suite not supported! (Usage -t TestSuite)";
else
if (testSuite == "BlockChainTests")
randomBlockChainTest();
fillRandomTest(dev::test::doTransactionTests, c_testExampleTransactionTest);
else
if (testSuite == "TransactionTests")
randomTransactionTest();
fillRandomTest(dev::test::doTransactionTests, c_testExampleTransactionTest);
else
if (testSuite == "StateTests")
fillRandomTest(dev::test::doStateTests, c_testExampleStateTest);
return 0;
}
void randomTransactionTest()
void fillRandomTest(std::function<void(json_spirit::mValue&, bool)> doTests, std::string const& testString)
{
//redirect all output to the stream
std::ostringstream strCout;
@ -72,10 +79,10 @@ void randomTransactionTest()
json_spirit::mValue v;
try
{
std::string newTest = c_testExampleTransactionTest;
std::string newTest = testString;
parseTestWithTypes(newTest);
json_spirit::read_string(newTest, v);
dev::test::doTransactionTests(v, true);
doTests(v, true);
}
catch(...)
{
@ -88,55 +95,67 @@ void randomTransactionTest()
std::cout << json_spirit::write_string(v, true);
}
void randomBlockChainTest()
{
}
/// Parse Test string replacing keywords to fuzzed values
void parseTestWithTypes(std::string& test)
void parseTestWithTypes(std::string& _test)
{
dev::test::RandomCodeOptions options;
options.setWeight(dev::eth::Instruction::STOP, 10); //default 50
options.setWeight(dev::eth::Instruction::SSTORE, 70);
options.setWeight(dev::eth::Instruction::CALL, 75);
options.addAddress(dev::Address("0xffffffffffffffffffffffffffffffffffffffff"));
options.addAddress(dev::Address("0x1000000000000000000000000000000000000000"));
options.addAddress(dev::Address("0x095e7baea6a6c7c4c2dfeb977efac326af552d87"));
options.addAddress(dev::Address("0x945304eb96065b2a98b57a48a06ae28d285a71b5"));
options.addAddress(dev::Address("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"));
options.addAddress(dev::Address("0x0000000000000000000000000000000000000001"));
options.addAddress(dev::Address("0x0000000000000000000000000000000000000002"));
options.addAddress(dev::Address("0x0000000000000000000000000000000000000003"));
options.addAddress(dev::Address("0x0000000000000000000000000000000000000004"));
options.smartCodeProbability = 35;
std::vector<std::string> types = getTypes();
for (unsigned i = 0; i < types.size(); i++)
{
std::size_t pos = test.find(types.at(i));
std::size_t pos = _test.find(types.at(i));
while (pos != std::string::npos)
{
if (types.at(i) == "[CODE]")
test.replace(pos, 6, "0x"+dev::test::RandomCode::generate(10));
_test.replace(pos, 6, "0x"+dev::test::RandomCode::generate(10, options));
else
if (types.at(i) == "[HEX]")
test.replace(pos, 5, dev::test::RandomCode::randomUniIntHex());
_test.replace(pos, 5, dev::test::RandomCode::randomUniIntHex());
else
if (types.at(i) == "[HASH20]")
test.replace(pos, 8, dev::test::RandomCode::rndByteSequence(20));
_test.replace(pos, 8, dev::test::RandomCode::rndByteSequence(20));
else
if (types.at(i) == "[0xHASH32]")
test.replace(pos, 10, "0x" + dev::test::RandomCode::rndByteSequence(32));
_test.replace(pos, 10, "0x" + dev::test::RandomCode::rndByteSequence(32));
else
if (types.at(i) == "[HASH32]")
_test.replace(pos, 8, dev::test::RandomCode::rndByteSequence(32));
else
if (types.at(i) == "[V]")
{
int random = dev::test::RandomCode::randomUniInt() % 100;
if (random < 30)
test.replace(pos, 3, "28");
_test.replace(pos, 3, "28");
else
if (random < 60)
test.replace(pos, 3, "29");
_test.replace(pos, 3, "29");
else
test.replace(pos, 3, "0x" + dev::test::RandomCode::rndByteSequence(1));
_test.replace(pos, 3, "0x" + dev::test::RandomCode::rndByteSequence(1));
}
pos = test.find(types.at(i));
pos = _test.find(types.at(i));
}
}
}
std::vector<std::string> getTypes()
{
return {"[CODE]", "[HEX]", "[HASH20]", "[0xHASH32]", "[V]"};
return {"[CODE]", "[HEX]", "[HASH20]", "[HASH32]", "[0xHASH32]", "[V]"};
}
std::string const c_testExampleTransactionTest = R"(
{
"TransactionTest" : {
@ -156,5 +175,49 @@ std::string const c_testExampleTransactionTest = R"(
}
)";
std::string const c_testExampleStateTest = R"(
{
"randomStatetest" : {
"env" : {
"currentCoinbase" : "[HASH20]",
"currentDifficulty" : "[HEX]",
"currentGasLimit" : "[HEX]",
"currentNumber" : "[HEX]",
"currentTimestamp" : "[HEX]",
"previousHash" : "[HASH32]"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "[HEX]",
"code" : "[CODE]",
"nonce" : "[V]",
"storage" : {
}
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "[HEX]",
"code" : "[CODE]",
"nonce" : "[V]",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "[HEX]",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" : {
"data" : "[CODE]",
"gasLimit" : "[HEX]",
"gasPrice" : "[V]",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "[HEX]"
}
}
}
)";

7
test/fuzzTesting/fuzzHelper.cpp

@ -35,10 +35,12 @@ boost::random::mt19937 RandomCode::gen;
boostIntDistrib RandomCode::opCodeDist = boostIntDistrib (0, 255);
boostIntDistrib RandomCode::opLengDist = boostIntDistrib (1, 32);
boostIntDistrib RandomCode::uniIntDist = boostIntDistrib (0, 0x7fffffff);
boostUint64Distrib RandomCode::uInt64Dist = boostUint64Distrib (0, std::numeric_limits<uint64_t>::max());
boostIntGenerator RandomCode::randOpCodeGen = boostIntGenerator(gen, opCodeDist);
boostIntGenerator RandomCode::randOpLengGen = boostIntGenerator(gen, opLengDist);
boostIntGenerator RandomCode::randUniIntGen = boostIntGenerator(gen, uniIntDist);
boostUInt64Generator RandomCode::randUInt64Gen = boostUInt64Generator(gen, uInt64Dist);
std::string RandomCode::rndByteSequence(int _length, SizeStrictness _sizeType)
{
@ -92,7 +94,10 @@ std::string RandomCode::generate(int _maxOpNumber, RandomCodeOptions _options)
std::string RandomCode::randomUniIntHex()
{
refreshSeed();
return "0x" + toCompactHex((int)randUniIntGen());
int rand = randUniIntGen() % 100;
if (rand < 50)
return "0x" + toCompactHex((u256)randUniIntGen());
return "0x" + toCompactHex((u256)randUInt64Gen());
}
int RandomCode::randomUniInt()

6
test/fuzzTesting/fuzzHelper.h

@ -37,9 +37,11 @@ namespace test
typedef boost::random::uniform_int_distribution<> boostIntDistrib;
typedef boost::random::discrete_distribution<> boostDescreteDistrib;
typedef boost::uniform_int<uint64_t> boostUint64Distrib;
typedef boost::random::variate_generator<boost::mt19937&, boostIntDistrib > boostIntGenerator;
typedef boost::random::variate_generator<boost::mt19937&, boostDescreteDistrib > boostWeightGenerator;
typedef boost::random::variate_generator<boost::mt19937&, boostUint64Distrib > boostUInt64Generator;
struct RandomCodeOptions
{
@ -73,7 +75,7 @@ public:
/// Generate random byte string of a given length
static std::string rndByteSequence(int _length = 1, SizeStrictness _sizeType = SizeStrictness::Strict);
/// Generate random uniForm Int with reasonable value 0..0x7fffffff
/// Generate random int64
static std::string randomUniIntHex();
static int randomUniInt();
@ -87,10 +89,12 @@ private:
static boostIntDistrib opCodeDist; ///< 0..255 opcodes
static boostIntDistrib opLengDist; ///< 1..32 byte string
static boostIntDistrib uniIntDist; ///< 0..0x7fffffff
static boostUint64Distrib uInt64Dist; ///< 0..2**64
static boostIntGenerator randUniIntGen; ///< Generate random UniformInt from uniIntDist
static boostIntGenerator randOpCodeGen; ///< Generate random value from opCodeDist
static boostIntGenerator randOpLengGen; ///< Generate random length from opLengDist
static boostUInt64Generator randUInt64Gen; ///< Generate random uInt64
};
}

14
test/libethereum/state.cpp

@ -51,9 +51,9 @@ void doStateTests(json_spirit::mValue& v, bool _fillin)
}
std::cout << " " << i.first << std::endl;
BOOST_REQUIRE(o.count("env") > 0);
BOOST_REQUIRE(o.count("pre") > 0);
BOOST_REQUIRE(o.count("transaction") > 0);
TBOOST_REQUIRE((o.count("env") > 0));
TBOOST_REQUIRE((o.count("pre") > 0));
TBOOST_REQUIRE((o.count("transaction") > 0));
ImportTest importer(o, _fillin);
@ -80,13 +80,13 @@ void doStateTests(json_spirit::mValue& v, bool _fillin)
#if ETH_FATDB
importer.exportTest(output, theState);
#else
BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("You can not fill tests when FATDB is switched off"));
TBOOST_THROW_EXCEPTION(Exception() << errinfo_comment("You can not fill tests when FATDB is switched off"));
#endif
}
else
{
BOOST_REQUIRE(o.count("post") > 0);
BOOST_REQUIRE(o.count("out") > 0);
TBOOST_REQUIRE((o.count("post") > 0));
TBOOST_REQUIRE((o.count("out") > 0));
// check output
checkOutput(output, o);
@ -101,7 +101,7 @@ void doStateTests(json_spirit::mValue& v, bool _fillin)
auto resultAddrs = theState.addresses();
checkAddresses(expectedAddrs, resultAddrs);
#endif
BOOST_CHECK_MESSAGE(theState.rootHash() == h256(o["postStateRoot"].get_str()), "wrong post state root");
TBOOST_CHECK_MESSAGE((theState.rootHash() == h256(o["postStateRoot"].get_str())), "wrong post state root");
}
}
}

Loading…
Cancel
Save