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