arkpar
10 years ago
27 changed files with 856 additions and 290 deletions
@ -0,0 +1,397 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/** @file createRandomTest.cpp
|
||||
|
* @author Dimitry Khokhlov <winsvega@mail.ru> |
||||
|
* @date 2015 |
||||
|
*/ |
||||
|
|
||||
|
///This file require #define DONTUSE_BOOST_MACROS compile flag to run!
|
||||
|
|
||||
|
#include <string> |
||||
|
#include <iostream> |
||||
|
|
||||
|
#include <test/TestHelper.h> |
||||
|
#include <test/fuzzTesting/fuzzHelper.h> |
||||
|
#include <libevm/VMFactory.h> |
||||
|
#include <libdevcore/Common.h> |
||||
|
|
||||
|
//String Variables
|
||||
|
extern std::string const c_testExampleStateTest; |
||||
|
extern std::string const c_testExampleTransactionTest; |
||||
|
extern std::string const c_testExampleVMTest; |
||||
|
extern std::string const c_testExampleBlockchainTest; |
||||
|
|
||||
|
//Main Test functinos
|
||||
|
void fillRandomTest(std::function<void(json_spirit::mValue&, bool)> doTests, std::string const& testString); |
||||
|
int checkRandomTest(std::function<void(json_spirit::mValue&, bool)> doTests, json_spirit::mValue& value); |
||||
|
|
||||
|
//Helper Functions
|
||||
|
std::vector<std::string> getTypes(); |
||||
|
void parseTestWithTypes(std::string& test); |
||||
|
|
||||
|
int main(int argc, char *argv[]) |
||||
|
{ |
||||
|
std::string testSuite; |
||||
|
json_spirit::mValue testmValue; |
||||
|
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&>(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" && 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, testmValue); |
||||
|
checktest = true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (testSuite == "") |
||||
|
{ |
||||
|
std::cout << "Error! Test suite not supported! (Usage -t TestSuite)"; |
||||
|
return 1; |
||||
|
} |
||||
|
else |
||||
|
if (testSuite == "BlockChainTests") |
||||
|
{ |
||||
|
if (checktest) |
||||
|
return checkRandomTest(dev::test::doBlockchainTests, testmValue); |
||||
|
else |
||||
|
fillRandomTest(dev::test::doBlockchainTests, c_testExampleBlockchainTest); |
||||
|
} |
||||
|
else |
||||
|
if (testSuite == "TransactionTests") |
||||
|
{ |
||||
|
if (checktest) |
||||
|
return checkRandomTest(dev::test::doTransactionTests, testmValue); |
||||
|
else |
||||
|
fillRandomTest(dev::test::doTransactionTests, c_testExampleTransactionTest); |
||||
|
} |
||||
|
else |
||||
|
if (testSuite == "StateTests") |
||||
|
{ |
||||
|
if (checktest) |
||||
|
return checkRandomTest(dev::test::doStateTests, testmValue); |
||||
|
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, testmValue); |
||||
|
} |
||||
|
else |
||||
|
fillRandomTest(dev::test::doVMTests, c_testExampleVMTest); |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
int checkRandomTest(std::function<void(json_spirit::mValue&, bool)> 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<void(json_spirit::mValue&, bool)> doTests, std::string const& testString) |
||||
|
{ |
||||
|
//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() ); |
||||
|
|
||||
|
json_spirit::mValue v; |
||||
|
try |
||||
|
{ |
||||
|
std::string newTest = testString; |
||||
|
parseTestWithTypes(newTest); |
||||
|
json_spirit::read_string(newTest, v); |
||||
|
doTests(v, true); |
||||
|
} |
||||
|
catch(...) |
||||
|
{ |
||||
|
std::cerr << "Test fill exception!"; |
||||
|
} |
||||
|
|
||||
|
//restroe output
|
||||
|
std::cout.rdbuf(oldCoutStreamBuf); |
||||
|
std::cerr.rdbuf(oldCoutStreamBuf); |
||||
|
std::cout << json_spirit::write_string(v, true); |
||||
|
} |
||||
|
|
||||
|
/// Parse Test string replacing keywords to fuzzed values
|
||||
|
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("0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6")); |
||||
|
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)); |
||||
|
while (pos != std::string::npos) |
||||
|
{ |
||||
|
if (types.at(i) == "[CODE]") |
||||
|
_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()); |
||||
|
else |
||||
|
if (types.at(i) == "[GASLIMIT]") |
||||
|
_test.replace(pos, 10, dev::test::RandomCode::randomUniIntHex(dev::u256("3000000000"))); |
||||
|
else |
||||
|
if (types.at(i) == "[HASH20]") |
||||
|
_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)); |
||||
|
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, "0x1c"); |
||||
|
else |
||||
|
if (random < 60) |
||||
|
_test.replace(pos, 3, "0x1d"); |
||||
|
else |
||||
|
_test.replace(pos, 3, "0x" + dev::test::RandomCode::rndByteSequence(1)); |
||||
|
} |
||||
|
|
||||
|
pos = _test.find(types.at(i)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
std::vector<std::string> getTypes() |
||||
|
{ |
||||
|
return {"[CODE]", "[HEX]", "[HASH20]", "[HASH32]", "[0xHASH32]", "[V]", "[GASLIMIT]"}; |
||||
|
} |
||||
|
|
||||
|
std::string const c_testExampleTransactionTest = R"( |
||||
|
{ |
||||
|
"randomTransactionTest" : { |
||||
|
"transaction" : |
||||
|
{ |
||||
|
"data" : "[CODE]", |
||||
|
"gasLimit" : "[HEX]", |
||||
|
"gasPrice" : "[HEX]", |
||||
|
"nonce" : "[HEX]", |
||||
|
"to" : "[HASH20]", |
||||
|
"value" : "[HEX]", |
||||
|
"v" : "[V]", |
||||
|
"r" : "[0xHASH32]", |
||||
|
"s" : "[0xHASH32]" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
)"; |
||||
|
|
||||
|
std::string const c_testExampleStateTest = R"( |
||||
|
{ |
||||
|
"randomStatetest" : { |
||||
|
"env" : { |
||||
|
"currentCoinbase" : "[HASH20]", |
||||
|
"currentDifficulty" : "[HEX]", |
||||
|
"currentGasLimit" : "[GASLIMIT]", |
||||
|
"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]" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
)"; |
||||
|
|
||||
|
std::string const c_testExampleVMTest = R"( |
||||
|
{ |
||||
|
"randomVMTest": { |
||||
|
"env" : { |
||||
|
"previousHash" : "[HASH32]", |
||||
|
"currentNumber" : "[HEX]", |
||||
|
"currentGasLimit" : "[GASLIMIT]", |
||||
|
"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]" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
)"; |
||||
|
|
||||
|
std::string const c_testExampleBlockchainTest = R"( |
||||
|
{ |
||||
|
"randomBlockTest" : { |
||||
|
"genesisBlockHeader" : { |
||||
|
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
||||
|
"coinbase" : "[HASH20]", |
||||
|
"difficulty" : "131072", |
||||
|
"extraData" : "[CODE]", |
||||
|
"gasLimit" : "3141592", |
||||
|
"gasUsed" : "0", |
||||
|
"mixHash" : "[0xHASH32]", |
||||
|
"nonce" : "0x0102030405060708", |
||||
|
"number" : "0", |
||||
|
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", |
||||
|
"receiptTrie" : "[0xHASH32]", |
||||
|
"stateRoot" : "[0xHASH32]", |
||||
|
"timestamp" : "[HEX]", |
||||
|
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
||||
|
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" |
||||
|
}, |
||||
|
"pre" : { |
||||
|
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
||||
|
"balance" : "[HEX]", |
||||
|
"nonce" : "0", |
||||
|
"code" : "", |
||||
|
"storage": {} |
||||
|
}, |
||||
|
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
||||
|
"balance" : "[HEX]", |
||||
|
"nonce" : "0", |
||||
|
"code" : "[CODE]", |
||||
|
"storage": {} |
||||
|
} |
||||
|
}, |
||||
|
"blocks" : [ |
||||
|
{ |
||||
|
"transactions" : [ |
||||
|
{ |
||||
|
"data" : "[CODE]", |
||||
|
"gasLimit" : "[HEX]", |
||||
|
"gasPrice" : "[V]", |
||||
|
"nonce" : "0", |
||||
|
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
||||
|
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
||||
|
"value" : "[V]" |
||||
|
} |
||||
|
], |
||||
|
"uncleHeaders" : [ |
||||
|
] |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
)"; |
Loading…
Reference in new issue