TestHelper.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  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 TestHelper.h
  15. * @author Marko Simovic <markobarko@gmail.com>
  16. * @date 2014
  17. */
  18. #pragma once
  19. #include <thread>
  20. #include <future>
  21. #include <functional>
  22. #include <boost/test/unit_test.hpp>
  23. #include <boost/filesystem.hpp>
  24. #include <boost/progress.hpp>
  25. #include "JsonSpiritHeaders.h"
  26. #include <libethashseal/Ethash.h>
  27. #include <libethereum/State.h>
  28. #include <libethashseal/GenesisInfo.h>
  29. #include <libevm/ExtVMFace.h>
  30. #include <test/libtestutils/Common.h>
  31. namespace dev
  32. {
  33. namespace eth
  34. {
  35. class Client;
  36. class State;
  37. void mine(Client& c, int numBlocks);
  38. void connectClients(Client& c1, Client& c2);
  39. void mine(Block& _s, BlockChain const& _bc, SealEngineFace* _sealer);
  40. void mine(BlockHeader& _bi, SealEngineFace* _sealer, bool _verify = true);
  41. }
  42. namespace test
  43. {
  44. const int c_testHomesteadBlock = 1150000;
  45. /// Make sure that no Exception is thrown during testing. If one is thrown show its info and fail the test.
  46. /// Our version of BOOST_REQUIRE_NO_THROW()
  47. /// @param _statenent The statement for which to make sure no exceptions are thrown
  48. /// @param _message A message to act as a prefix to the expression's error information
  49. #define ETH_TEST_REQUIRE_NO_THROW(_statement, _message) \
  50. do \
  51. { \
  52. try \
  53. { \
  54. BOOST_TEST_PASSPOINT(); \
  55. _statement; \
  56. } \
  57. catch (boost::exception const& _e) \
  58. { \
  59. auto msg = std::string(_message " due to an exception thrown by " \
  60. BOOST_STRINGIZE(_statement) "\n") + boost::diagnostic_information(_e); \
  61. BOOST_CHECK_IMPL(false, msg, REQUIRE, CHECK_MSG); \
  62. } \
  63. catch (...) \
  64. { \
  65. BOOST_CHECK_IMPL(false, "Unknown exception thrown by " \
  66. BOOST_STRINGIZE(_statement), REQUIRE, CHECK_MSG); \
  67. } \
  68. } \
  69. while (0)
  70. /// Check if an Exception is thrown during testing. If one is thrown show its info and continue the test
  71. /// Our version of BOOST_CHECK_NO_THROW()
  72. /// @param _statement The statement for which to make sure no exceptions are thrown
  73. /// @param _message A message to act as a prefix to the expression's error information
  74. #define ETH_TEST_CHECK_NO_THROW(_statement, _message) \
  75. do \
  76. { \
  77. try \
  78. { \
  79. BOOST_TEST_PASSPOINT(); \
  80. _statement; \
  81. } \
  82. catch (boost::exception const& _e) \
  83. { \
  84. auto msg = std::string(_message " due to an exception thrown by " \
  85. BOOST_STRINGIZE(_statement) "\n") + boost::diagnostic_information(_e); \
  86. BOOST_CHECK_IMPL(false, msg, CHECK, CHECK_MSG); \
  87. } \
  88. catch (...) \
  89. { \
  90. BOOST_CHECK_IMPL(false, "Unknown exception thrown by " \
  91. BOOST_STRINGIZE(_statement), CHECK, CHECK_MSG ); \
  92. } \
  93. } \
  94. while (0)
  95. enum class testType
  96. {
  97. StateTests,
  98. BlockChainTests,
  99. GeneralStateTest,
  100. Other
  101. };
  102. class ImportTest
  103. {
  104. public:
  105. ImportTest(json_spirit::mObject& _o, bool isFiller, testType testTemplate = testType::StateTests);
  106. // imports
  107. void importEnv(json_spirit::mObject& _o);
  108. static void importState(json_spirit::mObject const& _o, eth::State& _state);
  109. static void importState(json_spirit::mObject const& _o, eth::State& _state, eth::AccountMaskMap& o_mask);
  110. static void importTransaction (json_spirit::mObject const& _o, eth::Transaction& o_tr);
  111. void importTransaction(json_spirit::mObject const& _o);
  112. static json_spirit::mObject& makeAllFieldsHex(json_spirit::mObject& _o);
  113. bytes executeTest();
  114. int exportTest(bytes const& _output);
  115. static int compareStates(eth::State const& _stateExpect, eth::State const& _statePost, eth::AccountMaskMap const _expectedStateOptions = eth::AccountMaskMap(), WhenError _throw = WhenError::Throw);
  116. void checkGeneralTestSection(json_spirit::mObject const& _expects, std::vector<size_t>& _errorTransactions, std::string const& _network="") const;
  117. eth::State m_statePre;
  118. eth::State m_statePost;
  119. eth::LogEntries m_logs;
  120. eth::LogEntries m_logsExpected;
  121. private:
  122. typedef std::pair<eth::ExecutionResult, eth::TransactionReceipt> execOutput;
  123. std::pair<eth::State, execOutput> executeTransaction(eth::Network const _sealEngineNetwork, eth::EnvInfo const& _env, eth::State const& _preState, eth::Transaction const& _tr);
  124. eth::EnvInfo m_envInfo;
  125. eth::Transaction m_transaction;
  126. //General State Tests
  127. struct transactionToExecute
  128. {
  129. transactionToExecute(int d, int g, int v, eth::Transaction const& t):
  130. dataInd(d), gasInd(g), valInd(v), transaction(t), postState(0), netId(eth::Network::Test) {}
  131. int dataInd;
  132. int gasInd;
  133. int valInd;
  134. eth::Transaction transaction;
  135. eth::State postState;
  136. eth::Network netId;
  137. };
  138. std::vector<transactionToExecute> m_transactions;
  139. json_spirit::mObject& m_testObject;
  140. testType m_testType;
  141. };
  142. class ZeroGasPricer: public eth::GasPricer
  143. {
  144. protected:
  145. u256 ask(eth::Block const&) const override { return 0; }
  146. u256 bid(eth::TransactionPriority = eth::TransactionPriority::Medium) const override { return 0; }
  147. };
  148. // helping functions
  149. u256 toInt(json_spirit::mValue const& _v);
  150. byte toByte(json_spirit::mValue const& _v);
  151. void replaceLLLinState(json_spirit::mObject& _o);
  152. std::string compileLLL(std::string const& _code);
  153. bytes importCode(json_spirit::mObject& _o);
  154. bytes importData(json_spirit::mObject const& _o);
  155. bytes importByteArray(std::string const& _str);
  156. void copyFile(std::string const& _source, std::string const& _destination);
  157. eth::LogEntries importLog(json_spirit::mArray& _o);
  158. json_spirit::mArray exportLog(eth::LogEntries _logs);
  159. void checkOutput(bytes const& _output, json_spirit::mObject& _o);
  160. void checkStorage(std::map<u256, u256> _expectedStore, std::map<u256, u256> _resultStore, Address _expectedAddr);
  161. void checkLog(eth::LogEntries _resultLogs, eth::LogEntries _expectedLogs);
  162. void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _expectedCallCreates);
  163. dev::eth::BlockHeader constructHeader(
  164. h256 const& _parentHash,
  165. h256 const& _sha3Uncles,
  166. Address const& _author,
  167. h256 const& _stateRoot,
  168. h256 const& _transactionsRoot,
  169. h256 const& _receiptsRoot,
  170. dev::eth::LogBloom const& _logBloom,
  171. u256 const& _difficulty,
  172. u256 const& _number,
  173. u256 const& _gasLimit,
  174. u256 const& _gasUsed,
  175. u256 const& _timestamp,
  176. bytes const& _extraData);
  177. void updateEthashSeal(dev::eth::BlockHeader& _header, h256 const& _mixHash, dev::eth::Nonce const& _nonce);
  178. void executeTests(const std::string& _name, const std::string& _testPathAppendix, const std::string& _fillerPathAppendix, std::function<void(json_spirit::mValue&, bool)> doTests, bool _addFillerSuffix = true);
  179. void userDefinedTest(std::function<void(json_spirit::mValue&, bool)> doTests);
  180. RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject const& _tObj);
  181. eth::LastHashes lastHashes(u256 _currentBlockNumber);
  182. json_spirit::mObject fillJsonWithState(eth::State const& _state);
  183. json_spirit::mObject fillJsonWithTransaction(eth::Transaction const& _txn);
  184. //Fill Test Functions
  185. int createRandomTest(std::vector<char*> const& _parameters);
  186. void doTransactionTests(json_spirit::mValue& _v, bool _fillin);
  187. void doStateTests(json_spirit::mValue& v, bool _fillin);
  188. void doVMTests(json_spirit::mValue& v, bool _fillin);
  189. void doBlockchainTests(json_spirit::mValue& _v, bool _fillin);
  190. void doRlpTests(json_spirit::mValue& v, bool _fillin);
  191. enum class Verbosity
  192. {
  193. Full,
  194. NiceReport,
  195. None
  196. };
  197. class Options
  198. {
  199. public:
  200. bool vmtrace = false; ///< Create EVM execution tracer
  201. bool fillTests = false; ///< Create JSON test files from execution results
  202. bool stats = false; ///< Execution time stats
  203. std::string statsOutFile; ///< Stats output file. "out" for standard output
  204. std::string rCheckTest; ///< Test Input (for random tests)
  205. std::string rCurrentTestSuite; ///< Remember test suite before boost overwrite (for random tests)
  206. bool checkState = false;///< Throw error when checking test states
  207. bool fulloutput = false;///< Replace large output to just it's length
  208. bool createRandomTest = false; ///< Generate random test
  209. Verbosity logVerbosity = Verbosity::NiceReport;
  210. eth::Network sealEngineNetwork = eth::Network::Test; ///< set seal engine (Frontier, Homestead, ...)
  211. /// Test selection
  212. /// @{
  213. bool singleTest = false;
  214. std::string singleTestFile;
  215. std::string singleTestName;
  216. std::string singleTestNet;
  217. bool performance = false;
  218. bool nonetwork = false;///< For libp2p
  219. bool quadratic = false;
  220. bool memory = false;
  221. bool inputLimits = false;
  222. bool bigData = false;
  223. bool wallet = false;
  224. /// @}
  225. /// Get reference to options
  226. /// The first time used, options are parsed with argc, argv
  227. static Options const& get(int argc = 0, char** argv = 0);
  228. private:
  229. Options(int argc = 0, char** argv = 0);
  230. Options(Options const&) = delete;
  231. };
  232. class TestOutputHelper
  233. {
  234. public:
  235. TestOutputHelper() { TestOutputHelper::initTest(); }
  236. static void initTest(int _maxTests = 1);
  237. static void initTest(json_spirit::mValue& _v);
  238. static bool passTest(json_spirit::mObject& _o, std::string& _testName);
  239. static void setMaxTests(int _count) { m_maxTests = _count; }
  240. static void setCurrentTestFileName(std::string _name) { m_currentTestFileName = _name; }
  241. static std::string const& testName() { return m_currentTestName; }
  242. static std::string const& caseName() { return m_currentTestCaseName; }
  243. static std::string const& testFileName() { return m_currentTestFileName; }
  244. private:
  245. static size_t m_currTest;
  246. static size_t m_maxTests;
  247. static std::string m_currentTestName;
  248. static std::string m_currentTestCaseName;
  249. static std::string m_currentTestFileName;
  250. };
  251. /// Allows observing test execution process.
  252. /// This class also provides methods for registering and notifying the listener
  253. class Listener
  254. {
  255. public:
  256. virtual ~Listener() = default;
  257. virtual void suiteStarted(std::string const&) {}
  258. virtual void testStarted(std::string const& _name) = 0;
  259. virtual void testFinished(int64_t _gasUsed) = 0;
  260. static void registerListener(Listener& _listener);
  261. static void notifySuiteStarted(std::string const& _name);
  262. static void notifyTestStarted(std::string const& _name);
  263. static void notifyTestFinished(int64_t _gasUsed);
  264. /// Test started/finished notification RAII helper
  265. class ExecTimeGuard
  266. {
  267. int64_t m_gasUsed = -1;
  268. public:
  269. ExecTimeGuard(std::string const& _testName) { notifyTestStarted(_testName); }
  270. ~ExecTimeGuard() { notifyTestFinished(m_gasUsed); }
  271. ExecTimeGuard(ExecTimeGuard const&) = delete;
  272. ExecTimeGuard& operator=(ExecTimeGuard) = delete;
  273. void setGasUsed(int64_t _gas) { m_gasUsed = _gas; }
  274. };
  275. };
  276. }
  277. }