createRandomTest.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. /*
  2. This file is part of cpp-ethereum.
  3. cpp-ethereum is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. cpp-ethereum is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /** @file createRandomTest.cpp
  15. * @author Dimitry Khokhlov <winsvega@mail.ru>
  16. * @date 2015
  17. */
  18. #include <string>
  19. #include <iostream>
  20. #include <libdevcore/CommonData.h>
  21. #include <test/TestHelper.h>
  22. #include <test/fuzzTesting/fuzzHelper.h>
  23. #include <libevm/VMFactory.h>
  24. #include <libdevcore/Common.h>
  25. //String Variables
  26. extern std::string const c_testExampleStateTest;
  27. extern std::string const c_testExampleTransactionTest;
  28. extern std::string const c_testExampleVMTest;
  29. extern std::string const c_testExampleBlockchainTest;
  30. extern std::string const c_testExampleRLPTest;
  31. //Main Test functinos
  32. void fillRandomTest(std::function<void(json_spirit::mValue&, bool)> _doTests, std::string const& _testString, bool _debug = false);
  33. int checkRandomTest(std::function<void(json_spirit::mValue&, bool)> _doTests, json_spirit::mValue& _value, bool _debug = false);
  34. namespace dev { namespace test {
  35. int createRandomTest(std::vector<char*> const& _parameters)
  36. {
  37. std::string testSuite;
  38. std::string testFillString;
  39. json_spirit::mValue testmValue;
  40. bool checktest = false;
  41. bool filldebug = false;
  42. bool debug = false;
  43. bool filltest = false;
  44. dev::test::Options& options = const_cast<dev::test::Options&>(dev::test::Options::get());
  45. testSuite = options.rCurrentTestSuite;
  46. if (testSuite != "BlockChainTests" && testSuite != "TransactionTests" && testSuite != "StateTests"
  47. && testSuite != "VMTests")
  48. testSuite = "";
  49. for (size_t i = 0; i < _parameters.size(); ++i)
  50. {
  51. auto arg = std::string{_parameters.at(i)};
  52. if (arg == "--fulloutput")
  53. options.fulloutput = true;
  54. else
  55. if (arg == "--checktest" || arg == "--filltest")
  56. {
  57. std::string s = options.rCheckTest;
  58. BOOST_REQUIRE_MESSAGE(s.length() > 0, "Error! Content of argument is empty! (Usage -checktest textstream)");
  59. if (arg == "--filltest")
  60. {
  61. testFillString = s;
  62. filltest = true;
  63. }
  64. else
  65. {
  66. if (s.find(".json") != std::string::npos)
  67. {
  68. boost::filesystem::path p(__FILE__);
  69. s = asString(dev::contents(s));
  70. }
  71. read_string(s, testmValue);
  72. checktest = true;
  73. }
  74. }
  75. else
  76. if (arg == "--debug")
  77. debug = true;
  78. else
  79. if (arg == "--filldebug")
  80. filldebug = true;
  81. }
  82. if (testSuite == "")
  83. {
  84. std::cerr << "Error! Test suite not supported! (Usage -t TestSuite)" << std::endl;
  85. return 1;
  86. }
  87. else
  88. {
  89. if (checktest)
  90. std::cout << "Testing: " << testSuite.substr(0, testSuite.length() - 1) << "... ";
  91. if (testSuite == "BlockChainTests")
  92. {
  93. if (checktest)
  94. return checkRandomTest(dev::test::doBlockchainTests, testmValue, debug);
  95. else
  96. fillRandomTest(dev::test::doBlockchainTests, (filltest) ? testFillString : c_testExampleBlockchainTest, filldebug);
  97. }
  98. else
  99. if (testSuite == "TransactionTests")
  100. {
  101. if (checktest)
  102. return checkRandomTest(dev::test::doTransactionTests, testmValue, debug);
  103. else
  104. fillRandomTest(dev::test::doTransactionTests, (filltest) ? testFillString : c_testExampleTransactionTest, filldebug);
  105. }
  106. else
  107. if (testSuite == "StateTests")
  108. {
  109. if (checktest)
  110. return checkRandomTest(dev::test::doStateTests, testmValue, debug);
  111. else
  112. fillRandomTest(dev::test::doStateTests, (filltest) ? testFillString : c_testExampleStateTest, filldebug);
  113. }
  114. else
  115. if (testSuite == "VMTests")
  116. {
  117. if (checktest)
  118. {
  119. dev::eth::VMFactory::setKind(dev::eth::VMKind::JIT);
  120. return checkRandomTest(dev::test::doVMTests, testmValue, debug);
  121. }
  122. else
  123. fillRandomTest(dev::test::doVMTests, (filltest) ? testFillString : c_testExampleVMTest, filldebug);
  124. }
  125. }
  126. return 0;
  127. }
  128. }} //namespaces
  129. int checkRandomTest(std::function<void(json_spirit::mValue&, bool)> _doTests, json_spirit::mValue& _value, bool _debug)
  130. {
  131. bool ret = 0;
  132. try
  133. {
  134. //redirect all output to the stream
  135. std::ostringstream strCout;
  136. std::streambuf* oldCoutStreamBuf = std::cout.rdbuf();
  137. if (!_debug)
  138. {
  139. std::cout.rdbuf( strCout.rdbuf() );
  140. std::cerr.rdbuf( strCout.rdbuf() );
  141. }
  142. _doTests(_value, false);
  143. //restroe output
  144. if (!_debug)
  145. {
  146. std::cout.rdbuf(oldCoutStreamBuf);
  147. std::cerr.rdbuf(oldCoutStreamBuf);
  148. }
  149. }
  150. catch (dev::Exception const& _e)
  151. {
  152. std::cout << "Failed test with Exception: " << diagnostic_information(_e) << std::endl;
  153. ret = 1;
  154. }
  155. catch (std::exception const& _e)
  156. {
  157. std::cout << "Failed test with Exception: " << _e.what() << std::endl;
  158. ret = 1;
  159. }
  160. return ret;
  161. }
  162. void fillRandomTest(std::function<void(json_spirit::mValue&, bool)> _doTests, std::string const& _testString, bool _debug)
  163. {
  164. //redirect all output to the stream
  165. std::ostringstream strCout;
  166. std::streambuf* oldCoutStreamBuf = std::cout.rdbuf();
  167. if (!_debug)
  168. {
  169. std::cout.rdbuf( strCout.rdbuf() );
  170. std::cerr.rdbuf( strCout.rdbuf() );
  171. }
  172. json_spirit::mValue v;
  173. try
  174. {
  175. std::string newTest = _testString;
  176. std::map<std::string, std::string> nullReplaceMap;
  177. dev::test::RandomCode::parseTestWithTypes(newTest, nullReplaceMap);
  178. json_spirit::read_string(newTest, v);
  179. _doTests(v, true);
  180. }
  181. catch(...)
  182. {
  183. std::cerr << "Test fill exception!";
  184. }
  185. //restroe output
  186. if (!_debug)
  187. {
  188. std::cout.rdbuf(oldCoutStreamBuf);
  189. std::cerr.rdbuf(oldCoutStreamBuf);
  190. }
  191. std::cout << json_spirit::write_string(v, true);
  192. }
  193. /// Parse Test string replacing keywords to fuzzed values
  194. void dev::test::RandomCode::parseTestWithTypes(std::string& _test, std::map<std::string, std::string> const& _varMap)
  195. {
  196. dev::test::RandomCodeOptions options;
  197. options.setWeight(dev::eth::Instruction::STOP, 10); //default 50
  198. options.setWeight(dev::eth::Instruction::SSTORE, 70);
  199. options.setWeight(dev::eth::Instruction::CALL, 75);
  200. options.setWeight(dev::eth::Instruction::CALLCODE, 55);
  201. options.addAddress(dev::Address("0xffffffffffffffffffffffffffffffffffffffff"));
  202. options.addAddress(dev::Address("0x1000000000000000000000000000000000000000"));
  203. options.addAddress(dev::Address("0x095e7baea6a6c7c4c2dfeb977efac326af552d87"));
  204. options.addAddress(dev::Address("0x945304eb96065b2a98b57a48a06ae28d285a71b5"));
  205. options.addAddress(dev::Address("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"));
  206. options.addAddress(dev::Address("0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6"));
  207. options.addAddress(dev::Address("0x0000000000000000000000000000000000000001"));
  208. options.addAddress(dev::Address("0x0000000000000000000000000000000000000002"));
  209. options.addAddress(dev::Address("0x0000000000000000000000000000000000000003"));
  210. options.addAddress(dev::Address("0x0000000000000000000000000000000000000004"));
  211. options.smartCodeProbability = 60;
  212. std::vector<std::string> types = getTypes();
  213. for (std::map<std::string, std::string>::const_iterator it = _varMap.begin(); it != _varMap.end(); it++)
  214. types.push_back(it->first);
  215. for (unsigned i = 0; i < types.size(); i++)
  216. {
  217. std::size_t pos = _test.find(types.at(i));
  218. while (pos != std::string::npos)
  219. {
  220. if (types.at(i) == "[RLP]")
  221. {
  222. std::string debug;
  223. int randomDepth = 1 + (int)dev::test::RandomCode::randomUniInt() % 10;
  224. _test.replace(pos, 5, dev::test::RandomCode::rndRLPSequence(randomDepth, debug));
  225. cnote << debug;
  226. }
  227. else
  228. if (types.at(i) == "[CODE]")
  229. _test.replace(pos, 6, "0x"+dev::test::RandomCode::generate(10, options));
  230. else
  231. if (types.at(i) == "[HEX]")
  232. _test.replace(pos, 5, dev::test::RandomCode::randomUniIntHex());
  233. else
  234. if (types.at(i) == "[HEX32]")
  235. _test.replace(pos, 7, dev::test::RandomCode::randomUniIntHex(std::numeric_limits<uint32_t>::max()));
  236. else
  237. if (types.at(i) == "[GASLIMIT]")
  238. _test.replace(pos, 10, dev::test::RandomCode::randomUniIntHex(dev::u256("3000000000")));
  239. else
  240. if (types.at(i) == "[HASH20]")
  241. _test.replace(pos, 8, dev::test::RandomCode::rndByteSequence(20));
  242. else
  243. if (types.at(i) == "[0xHASH32]")
  244. _test.replace(pos, 10, "0x" + dev::test::RandomCode::rndByteSequence(32));
  245. else
  246. if (types.at(i) == "[HASH32]")
  247. _test.replace(pos, 8, dev::test::RandomCode::rndByteSequence(32));
  248. else
  249. if (types.at(i) == "[V]")
  250. {
  251. int random = (int)dev::test::RandomCode::randomUniInt() % 100;
  252. if (random < 30)
  253. _test.replace(pos, 3, "0x1c");
  254. else
  255. if (random < 60)
  256. _test.replace(pos, 3, "0x1d");
  257. else
  258. _test.replace(pos, 3, "0x" + dev::test::RandomCode::rndByteSequence(1));
  259. }
  260. else
  261. _test.replace(pos, types.at(i).size(), _varMap.at(types.at(i)));
  262. pos = _test.find(types.at(i));
  263. }
  264. }
  265. }
  266. std::vector<std::string> dev::test::RandomCode::getTypes()
  267. {
  268. return {"[RLP]", "[CODE]", "[HEX]", "[HEX32]", "[HASH20]", "[HASH32]", "[0xHASH32]", "[V]", "[GASLIMIT]"};
  269. }
  270. std::string const c_testExampleTransactionTest = R"(
  271. {
  272. "randomTransactionTest" : {
  273. "transaction" :
  274. {
  275. "data" : "[CODE]",
  276. "gasLimit" : "[HEX]",
  277. "gasPrice" : "[HEX]",
  278. "nonce" : "[HEX]",
  279. "to" : "[HASH20]",
  280. "value" : "[HEX]",
  281. "v" : "[V]",
  282. "r" : "[0xHASH32]",
  283. "s" : "[0xHASH32]"
  284. }
  285. }
  286. }
  287. )";
  288. std::string const c_testExampleStateTest = R"(
  289. {
  290. "randomStatetest" : {
  291. "env" : {
  292. "currentCoinbase" : "[HASH20]",
  293. "currentDifficulty" : "[HEX]",
  294. "currentGasLimit" : "[GASLIMIT]",
  295. "currentNumber" : "[HEX32]",
  296. "currentTimestamp" : "[HEX]",
  297. "previousHash" : "[HASH32]"
  298. },
  299. "pre" : {
  300. "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
  301. "balance" : "[HEX]",
  302. "code" : "[CODE]",
  303. "nonce" : "[V]",
  304. "storage" : {
  305. }
  306. },
  307. "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
  308. "balance" : "[HEX]",
  309. "code" : "[CODE]",
  310. "nonce" : "[V]",
  311. "storage" : {
  312. }
  313. },
  314. "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
  315. "balance" : "[HEX]",
  316. "code" : "0x",
  317. "nonce" : "0",
  318. "storage" : {
  319. }
  320. }
  321. },
  322. "transaction" : {
  323. "data" : "[CODE]",
  324. "gasLimit" : "[HEX]",
  325. "gasPrice" : "[HEX32]",
  326. "nonce" : "0",
  327. "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
  328. "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
  329. "value" : "[HEX]"
  330. }
  331. }
  332. }
  333. )";
  334. std::string const c_testExampleVMTest = R"(
  335. {
  336. "randomVMTest": {
  337. "env" : {
  338. "previousHash" : "[HASH32]",
  339. "currentNumber" : "[HEX]",
  340. "currentGasLimit" : "[GASLIMIT]",
  341. "currentDifficulty" : "[HEX]",
  342. "currentTimestamp" : "[HEX]",
  343. "currentCoinbase" : "[HASH20]"
  344. },
  345. "pre" : {
  346. "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
  347. "balance" : "[HEX]",
  348. "nonce" : "[HEX]",
  349. "code" : "[CODE]",
  350. "storage": {}
  351. }
  352. },
  353. "exec" : {
  354. "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
  355. "origin" : "[HASH20]",
  356. "caller" : "[HASH20]",
  357. "value" : "[HEX]",
  358. "data" : "[CODE]",
  359. "gasPrice" : "[V]",
  360. "gas" : "[HEX]"
  361. }
  362. }
  363. }
  364. )";
  365. std::string const c_testExampleRLPTest = R"(
  366. {
  367. "randomRLPTest" : {
  368. "out" : "[RLP]"
  369. }
  370. }
  371. )";
  372. std::string const c_testExampleBlockchainTest = R"(
  373. {
  374. "randomBlockTest" : {
  375. "genesisBlockHeader" : {
  376. "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  377. "coinbase" : "[HASH20]",
  378. "difficulty" : "131072",
  379. "extraData" : "[CODE]",
  380. "gasLimit" : "4712388",
  381. "gasUsed" : "0",
  382. "mixHash" : "[0xHASH32]",
  383. "nonce" : "0x0102030405060708",
  384. "number" : "0",
  385. "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
  386. "receiptTrie" : "[0xHASH32]",
  387. "stateRoot" : "[0xHASH32]",
  388. "timestamp" : "[HEX]",
  389. "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  390. "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
  391. },
  392. "pre" : {
  393. "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
  394. "balance" : "[HEX]",
  395. "nonce" : "0",
  396. "code" : "",
  397. "storage": {}
  398. },
  399. "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
  400. "balance" : "[HEX]",
  401. "nonce" : "0",
  402. "code" : "[CODE]",
  403. "storage": {}
  404. }
  405. },
  406. "blocks" : [
  407. {
  408. "transactions" : [
  409. {
  410. "data" : "[CODE]",
  411. "gasLimit" : "[HEX]",
  412. "gasPrice" : "[V]",
  413. "nonce" : "0",
  414. "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
  415. "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
  416. "value" : "[V]"
  417. }
  418. ],
  419. "uncleHeaders" : [
  420. ]
  421. }
  422. ]
  423. }
  424. }
  425. )";