From 101b8cda92782e32dd0d25578cccd4fee4f83439 Mon Sep 17 00:00:00 2001 From: Dimitry Date: Wed, 5 Aug 2015 12:43:42 +0300 Subject: [PATCH] Coverage: tests --- test/TestHelper.cpp | 59 ++++++----- test/TestHelper.h | 8 +- test/libethereum/AccountDiff.cpp | 144 ++++++++++++++++++++++++++ test/libethereum/transactionTests.cpp | 7 +- 4 files changed, 186 insertions(+), 32 deletions(-) create mode 100644 test/libethereum/AccountDiff.cpp diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 399779756..fa889be16 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -191,7 +191,7 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state) BOOST_THROW_EXCEPTION(MissingFields() << errinfo_comment("Import State: Missing state fields!")); } -void ImportTest::importTransaction(json_spirit::mObject& _o) +void ImportTest::importTransaction (json_spirit::mObject const& _o, eth::Transaction& o_tr) { if (_o.count("secretKey") > 0) { @@ -202,18 +202,18 @@ void ImportTest::importTransaction(json_spirit::mObject& _o) assert(_o.count("value") > 0); assert(_o.count("data") > 0); - if (bigint(_o["nonce"].get_str()) >= c_max256plus1) + if (bigint(_o.at("nonce").get_str()) >= c_max256plus1) BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'nonce' is equal or greater than 2**256") ); - if (bigint(_o["gasPrice"].get_str()) >= c_max256plus1) + if (bigint(_o.at("gasPrice").get_str()) >= c_max256plus1) BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'gasPrice' is equal or greater than 2**256") ); - if (bigint(_o["gasLimit"].get_str()) >= c_max256plus1) + if (bigint(_o.at("gasLimit").get_str()) >= c_max256plus1) BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'gasLimit' is equal or greater than 2**256") ); - if (bigint(_o["value"].get_str()) >= c_max256plus1) + if (bigint(_o.at("value").get_str()) >= c_max256plus1) BOOST_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())) : - Transaction(toInt(_o["value"]), toInt(_o["gasPrice"]), toInt(_o["gasLimit"]), Address(_o["to"].get_str()), importData(_o), toInt(_o["nonce"]), Secret(_o["secretKey"].get_str())); + o_tr = _o.at("to").get_str().empty() ? + Transaction(toInt(_o.at("value")), toInt(_o.at("gasPrice")), toInt(_o.at("gasLimit")), importData(_o), toInt(_o.at("nonce")), Secret(_o.at("secretKey").get_str())) : + Transaction(toInt(_o.at("value")), toInt(_o.at("gasPrice")), toInt(_o.at("gasLimit")), Address(_o.at("to").get_str()), importData(_o), toInt(_o.at("nonce")), Secret(_o.at("secretKey").get_str())); } else { @@ -221,14 +221,14 @@ void ImportTest::importTransaction(json_spirit::mObject& _o) RLP transactionRLP(transactionRLPStream.out()); try { - m_transaction = Transaction(transactionRLP.data(), CheckTransaction::Everything); + o_tr = Transaction(transactionRLP.data(), CheckTransaction::Everything); } catch (InvalidSignature) { // create unsigned transaction - m_transaction = _o["to"].get_str().empty() ? - Transaction(toInt(_o["value"]), toInt(_o["gasPrice"]), toInt(_o["gasLimit"]), importData(_o), toInt(_o["nonce"])) : - Transaction(toInt(_o["value"]), toInt(_o["gasPrice"]), toInt(_o["gasLimit"]), Address(_o["to"].get_str()), importData(_o), toInt(_o["nonce"])); + o_tr = _o.at("to").get_str().empty() ? + Transaction(toInt(_o.at("value")), toInt(_o.at("gasPrice")), toInt(_o.at("gasLimit")), importData(_o), toInt(_o.at("nonce"))) : + Transaction(toInt(_o.at("value")), toInt(_o.at("gasPrice")), toInt(_o.at("gasLimit")), Address(_o.at("to").get_str()), importData(_o), toInt(_o.at("nonce"))); } catch (Exception& _e) { @@ -237,6 +237,11 @@ void ImportTest::importTransaction(json_spirit::mObject& _o) } } +void ImportTest::importTransaction(json_spirit::mObject const& o_tr) +{ + importTransaction(o_tr, m_transaction); +} + void ImportTest::compareStates(State const& _stateExpect, State const& _statePost, AccountMaskMap const _expectedStateOptions, WhenError _throw) { #define CHECK(a,b) \ @@ -421,13 +426,13 @@ bytes importByteArray(std::string const& _str) return fromHex(_str.substr(0, 2) == "0x" ? _str.substr(2) : _str, WhenError::Throw); } -bytes importData(json_spirit::mObject& _o) +bytes importData(json_spirit::mObject const& _o) { bytes data; - if (_o["data"].type() == json_spirit::str_type) - data = importByteArray(_o["data"].get_str()); + if (_o.at("data").type() == json_spirit::str_type) + data = importByteArray(_o.at("data").get_str()); else - for (auto const& j: _o["data"].get_array()) + for (auto const& j: _o.at("data").get_array()) data.push_back(toByte(j)); return data; } @@ -633,46 +638,46 @@ void executeTests(const string& _name, const string& _testPathAppendix, const bo } } -RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject& _tObj) +RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject const& _tObj) { //Construct Rlp of the given transaction RLPStream rlpStream; rlpStream.appendList(_tObj.size()); if (_tObj.count("nonce")) - rlpStream << bigint(_tObj["nonce"].get_str()); + rlpStream << bigint(_tObj.at("nonce").get_str()); if (_tObj.count("gasPrice")) - rlpStream << bigint(_tObj["gasPrice"].get_str()); + rlpStream << bigint(_tObj.at("gasPrice").get_str()); if (_tObj.count("gasLimit")) - rlpStream << bigint(_tObj["gasLimit"].get_str()); + rlpStream << bigint(_tObj.at("gasLimit").get_str()); if (_tObj.count("to")) { - if (_tObj["to"].get_str().empty()) + if (_tObj.at("to").get_str().empty()) rlpStream << ""; else - rlpStream << importByteArray(_tObj["to"].get_str()); + rlpStream << importByteArray(_tObj.at("to").get_str()); } if (_tObj.count("value")) - rlpStream << bigint(_tObj["value"].get_str()); + rlpStream << bigint(_tObj.at("value").get_str()); if (_tObj.count("data")) rlpStream << importData(_tObj); if (_tObj.count("v")) - rlpStream << bigint(_tObj["v"].get_str()); + rlpStream << bigint(_tObj.at("v").get_str()); if (_tObj.count("r")) - rlpStream << bigint(_tObj["r"].get_str()); + rlpStream << bigint(_tObj.at("r").get_str()); if (_tObj.count("s")) - rlpStream << bigint(_tObj["s"].get_str()); + rlpStream << bigint(_tObj.at("s").get_str()); if (_tObj.count("extrafield")) - rlpStream << bigint(_tObj["extrafield"].get_str()); + rlpStream << bigint(_tObj.at("extrafield").get_str()); return rlpStream; } diff --git a/test/TestHelper.h b/test/TestHelper.h index 9d2625e19..5f2f8d6d5 100644 --- a/test/TestHelper.h +++ b/test/TestHelper.h @@ -32,7 +32,6 @@ #include #include - #ifdef NOBOOST #define TBOOST_REQUIRE(arg) if(arg == false) throw dev::Exception(); #define TBOOST_REQUIRE_EQUAL(arg1, arg2) if(arg1 != arg2) throw dev::Exception(); @@ -139,7 +138,8 @@ public: void importEnv(json_spirit::mObject& _o); static void importState(json_spirit::mObject& _o, eth::State& _state); static void importState(json_spirit::mObject& _o, eth::State& _state, eth::AccountMaskMap& o_mask); - void importTransaction(json_spirit::mObject& _o); + static void importTransaction (json_spirit::mObject const& _o, eth::Transaction& o_tr); + void importTransaction(json_spirit::mObject const& _o); static json_spirit::mObject& makeAllFieldsHex(json_spirit::mObject& _o); bytes executeTest(); @@ -168,7 +168,7 @@ protected: u256 toInt(json_spirit::mValue const& _v); byte toByte(json_spirit::mValue const& _v); bytes importCode(json_spirit::mObject& _o); -bytes importData(json_spirit::mObject& _o); +bytes importData(json_spirit::mObject const& _o); bytes importByteArray(std::string const& _str); eth::LogEntries importLog(json_spirit::mArray& _o); json_spirit::mArray exportLog(eth::LogEntries _logs); @@ -193,7 +193,7 @@ dev::eth::Ethash::BlockHeader constructHeader( void updateEthashSeal(dev::eth::Ethash::BlockHeader& _header, h256 const& _mixHash, dev::eth::Nonce const& _nonce); void executeTests(const std::string& _name, const std::string& _testPathAppendix, const boost::filesystem::path _pathToFiller, std::function doTests); void userDefinedTest(std::function doTests); -RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject& _tObj); +RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject const& _tObj); eth::LastHashes lastHashes(u256 _currentBlockNumber); json_spirit::mObject fillJsonWithState(eth::State _state); json_spirit::mObject fillJsonWithTransaction(eth::Transaction _txn); diff --git a/test/libethereum/AccountDiff.cpp b/test/libethereum/AccountDiff.cpp new file mode 100644 index 000000000..3b009df6c --- /dev/null +++ b/test/libethereum/AccountDiff.cpp @@ -0,0 +1,144 @@ +/* + 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 . +*/ +/** @file AccountDiff.cpp + * @author Dimitry Khokhlov + * @date 2015 + * libethereum unit test functions coverage. + */ + +#include +#include +#include +#include "../JsonSpiritHeaders.h" + +#include + +#include +#include +#include +#include + +using namespace dev; +using namespace eth; + +BOOST_AUTO_TEST_SUITE(libethereum) + +BOOST_AUTO_TEST_CASE(AccountDiff) +{ + dev::eth::AccountDiff accDiff; + + // Testing changeType + // exist = true exist_from = true AccountChange::Deletion + accDiff.exist = dev::Diff(true, false); + BOOST_CHECK_MESSAGE(accDiff.changeType() == dev::eth::AccountChange::Deletion, "Account change type expected to be Deletion!"); + BOOST_CHECK_MESSAGE(strcmp(dev::eth::lead(accDiff.changeType()), "XXX") == 0, "Deletion lead expected to be 'XXX'!"); + + // exist = true exist_from = false AccountChange::Creation + accDiff.exist = dev::Diff(false, true); + BOOST_CHECK_MESSAGE(accDiff.changeType() == dev::eth::AccountChange::Creation, "Account change type expected to be Creation!"); + BOOST_CHECK_MESSAGE(strcmp(dev::eth::lead(accDiff.changeType()), "+++") == 0, "Creation lead expected to be '+++'!"); + + // exist = false bn = true sc = true AccountChange::All + accDiff.exist = dev::Diff(false, false); + accDiff.nonce = dev::Diff(1, 2); + accDiff.code = dev::Diff(dev::fromHex("00"), dev::fromHex("01")); + BOOST_CHECK_MESSAGE(accDiff.changeType() == dev::eth::AccountChange::All, "Account change type expected to be All!"); + BOOST_CHECK_MESSAGE(strcmp(dev::eth::lead(accDiff.changeType()), "***") == 0, "All lead expected to be '***'!"); + + // exist = false bn = true sc = false AccountChange::Intrinsic + accDiff.exist = dev::Diff(false, false); + accDiff.nonce = dev::Diff(1, 2); + accDiff.code = dev::Diff(dev::fromHex("00"), dev::fromHex("00")); + BOOST_CHECK_MESSAGE(accDiff.changeType() == dev::eth::AccountChange::Intrinsic, "Account change type expected to be Intrinsic!"); + BOOST_CHECK_MESSAGE(strcmp(dev::eth::lead(accDiff.changeType()), " * ") == 0, "Intrinsic lead expected to be ' * '!"); + + // exist = false bn = false sc = true AccountChange::CodeStorage + accDiff.exist = dev::Diff(false, false); + accDiff.nonce = dev::Diff(1, 1); + accDiff.balance = dev::Diff(1, 1); + accDiff.code = dev::Diff(dev::fromHex("00"), dev::fromHex("01")); + BOOST_CHECK_MESSAGE(accDiff.changeType() == dev::eth::AccountChange::CodeStorage, "Account change type expected to be CodeStorage!"); + BOOST_CHECK_MESSAGE(strcmp(dev::eth::lead(accDiff.changeType()), "* *") == 0, "CodeStorage lead expected to be '* *'!"); + + // exist = false bn = false sc = false AccountChange::None + accDiff.exist = dev::Diff(false, false); + accDiff.nonce = dev::Diff(1, 1); + accDiff.balance = dev::Diff(1, 1); + accDiff.code = dev::Diff(dev::fromHex("00"), dev::fromHex("00")); + BOOST_CHECK_MESSAGE(accDiff.changeType() == dev::eth::AccountChange::None, "Account change type expected to be None!"); + BOOST_CHECK_MESSAGE(strcmp(dev::eth::lead(accDiff.changeType()), " ") == 0, "None lead expected to be ' '!"); + + //ofstream + accDiff.exist = dev::Diff(false, false); + accDiff.nonce = dev::Diff(1, 2); + accDiff.balance = dev::Diff(1, 2); + accDiff.code = dev::Diff(dev::fromHex("00"), dev::fromHex("01")); + std::map> storage; + storage[1] = accDiff.nonce; + accDiff.storage = storage; + std::stringstream buffer; + + //if (!_s.exist.to()) + buffer << accDiff; + BOOST_CHECK_MESSAGE(buffer.str() == "", "Not expected output: '" + buffer.str() + "'"); + buffer.str(std::string()); + + accDiff.exist = dev::Diff(false, true); + buffer << accDiff; + BOOST_CHECK_MESSAGE(buffer.str() == "#2 (+1) 2 (+1) $[1] ([0]) \n * 0000000000000000000000000000000000000000000000000000000000000001: 2 (1)", "Not expected output: '" + buffer.str() + "'"); + buffer.str(std::string()); + + storage[1] = dev::Diff(0, 0); + accDiff.storage = storage; + buffer << accDiff; + BOOST_CHECK_MESSAGE(buffer.str() == "#2 (+1) 2 (+1) $[1] ([0]) \n + 0000000000000000000000000000000000000000000000000000000000000001: 0", "Not expected output: '" + buffer.str() + "'"); + buffer.str(std::string()); + + storage[1] = dev::Diff(1, 0); + accDiff.storage = storage; + buffer << accDiff; + BOOST_CHECK_MESSAGE(buffer.str() == "#2 (+1) 2 (+1) $[1] ([0]) \nXXX 0000000000000000000000000000000000000000000000000000000000000001 (1)", "Not expected output: '" + buffer.str() + "'"); + buffer.str(std::string()); + + BOOST_CHECK_MESSAGE(accDiff.changed() == true, "dev::eth::AccountDiff::changed(): incorrect return value"); + + //unexpected value + //BOOST_CHECK_MESSAGE(strcmp(dev::eth::lead((dev::eth::AccountChange)123), "") != 0, "Not expected output when dev::eth::lead on unexpected value"); +} + +BOOST_AUTO_TEST_CASE(StateDiff) +{ + dev::eth::StateDiff stateDiff; + dev::eth::AccountDiff accDiff; + + accDiff.exist = dev::Diff(false, false); + accDiff.nonce = dev::Diff(1, 2); + accDiff.balance = dev::Diff(1, 2); + accDiff.code = dev::Diff(dev::fromHex("00"), dev::fromHex("01")); + std::map> storage; + storage[1] = accDiff.nonce; + accDiff.storage = storage; + std::stringstream buffer; + + dev::Address address("001122334455667788991011121314151617181920"); + stateDiff.accounts[address] = accDiff; + buffer << stateDiff; + + BOOST_CHECK_MESSAGE(buffer.str() == "1 accounts changed:\n*** 0000000000000000000000000000000000000000: \n", "Not expected output: '" + buffer.str() + "'"); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libethereum/transactionTests.cpp b/test/libethereum/transactionTests.cpp index fe620eac6..f6bde061a 100644 --- a/test/libethereum/transactionTests.cpp +++ b/test/libethereum/transactionTests.cpp @@ -34,9 +34,14 @@ void doTransactionTests(json_spirit::mValue& _v, bool _fillin) { for (auto& i: _v.get_obj()) { - cerr << i.first << endl; mObject& o = i.second.get_obj(); + if (test::Options::get().singleTest && test::Options::get().singleTestName != i.first) + { + o.clear(); + continue; + } + cerr << i.first << endl; if (_fillin) { TBOOST_REQUIRE((o.count("transaction") > 0));