diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/core_proxy/core_proxy.h | 2 | ||||
-rw-r--r-- | tests/core_tests/chaingen_main.cpp | 1 | ||||
-rw-r--r-- | tests/core_tests/tx_pool.cpp | 52 | ||||
-rw-r--r-- | tests/core_tests/tx_pool.h | 11 | ||||
-rw-r--r-- | tests/functional_tests/make_test_signature.cc | 22 | ||||
-rwxr-xr-x | tests/functional_tests/rpc_payment.py | 40 | ||||
-rwxr-xr-x | tests/functional_tests/transfer.py | 3 | ||||
-rw-r--r-- | tests/unit_tests/CMakeLists.txt | 5 | ||||
-rw-r--r-- | tests/unit_tests/bootstrap_node_selector.cpp | 172 | ||||
-rw-r--r-- | tests/unit_tests/epee_utils.cpp | 46 | ||||
-rw-r--r-- | tests/unit_tests/hmac_keccak.cpp | 2 | ||||
-rw-r--r-- | tests/unit_tests/keccak.cpp | 4 | ||||
-rw-r--r-- | tests/unit_tests/levin.cpp | 20 | ||||
-rw-r--r-- | tests/unit_tests/mul_div.cpp | 2 | ||||
-rw-r--r-- | tests/unit_tests/net.cpp | 4 | ||||
-rw-r--r-- | tests/unit_tests/node_server.cpp | 2 | ||||
-rw-r--r-- | tests/unit_tests/test_tx_utils.cpp | 2 | ||||
-rw-r--r-- | tests/unit_tests/wipeable_string.cpp | 1 | ||||
-rw-r--r-- | tests/unit_tests/zmq_rpc.cpp | 55 |
19 files changed, 417 insertions, 29 deletions
diff --git a/tests/core_proxy/core_proxy.h b/tests/core_proxy/core_proxy.h index aa99699de..aad1bc962 100644 --- a/tests/core_proxy/core_proxy.h +++ b/tests/core_proxy/core_proxy.h @@ -109,5 +109,7 @@ namespace tests bool pad_transactions() const { return false; } uint32_t get_blockchain_pruning_seed() const { return 0; } bool prune_blockchain(uint32_t pruning_seed) const { return true; } + bool get_txpool_complement(const std::vector<crypto::hash> &hashes, std::vector<cryptonote::blobdata> &txes) { return false; } + bool get_pool_transaction_hashes(std::vector<crypto::hash>& txs, bool include_unrelayed_txes = true) const { return false; } }; } diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 23f3170b8..014c7475b 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -161,6 +161,7 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY(txpool_spend_key_all); GENERATE_AND_PLAY(txpool_double_spend_norelay); GENERATE_AND_PLAY(txpool_double_spend_local); + GENERATE_AND_PLAY(txpool_double_spend_keyimage); // Double spend GENERATE_AND_PLAY(gen_double_spend_in_tx<false>); diff --git a/tests/core_tests/tx_pool.cpp b/tests/core_tests/tx_pool.cpp index 537015dca..cc738c4ba 100644 --- a/tests/core_tests/tx_pool.cpp +++ b/tests/core_tests/tx_pool.cpp @@ -125,10 +125,12 @@ txpool_double_spend_base::txpool_double_spend_base() , m_no_relay_hashes() , m_all_hashes() , m_no_new_index(0) + , m_failed_index(0) , m_new_timestamp_index(0) , m_last_tx(crypto::hash{}) { REGISTER_CALLBACK_METHOD(txpool_double_spend_base, mark_no_new); + REGISTER_CALLBACK_METHOD(txpool_double_spend_base, mark_failed); REGISTER_CALLBACK_METHOD(txpool_double_spend_base, mark_timestamp_change); REGISTER_CALLBACK_METHOD(txpool_double_spend_base, timestamp_change_pause); REGISTER_CALLBACK_METHOD(txpool_double_spend_base, check_unchanged); @@ -143,6 +145,12 @@ bool txpool_double_spend_base::mark_no_new(cryptonote::core& /*c*/, size_t ev_in return true; } +bool txpool_double_spend_base::mark_failed(cryptonote::core& /*c*/, size_t ev_index, const std::vector<test_event_entry>& /*events*/) +{ + m_failed_index = ev_index + 1; + return true; +} + bool txpool_double_spend_base::mark_timestamp_change(cryptonote::core& /*c*/, size_t ev_index, const std::vector<test_event_entry>& /*events*/) { m_new_timestamp_index = ev_index + 1; @@ -483,6 +491,8 @@ bool txpool_double_spend_base::check_tx_verification_context(const cryptonote::t m_last_tx = cryptonote::get_transaction_hash(tx); if (m_no_new_index == event_idx) return !tvc.m_verifivation_failed && !tx_added; + else if (m_failed_index == event_idx) + return tvc.m_verifivation_failed;// && !tx_added; else return !tvc.m_verifivation_failed && tx_added; } @@ -559,3 +569,45 @@ bool txpool_double_spend_local::generate(std::vector<test_event_entry>& events) return true; } +bool txpool_double_spend_keyimage::generate(std::vector<test_event_entry>& events) const +{ + INIT_MEMPOOL_TEST(); + + DO_CALLBACK(events, "check_txpool_spent_keys"); + SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_local_relay); + DO_CALLBACK(events, "mark_no_new"); + + const std::size_t tx_index1 = events.size(); + MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0); + + DO_CALLBACK(events, "increase_all_tx_count"); + DO_CALLBACK(events, "check_txpool_spent_keys"); + DO_CALLBACK(events, "mark_timestamp_change"); + DO_CALLBACK(events, "check_new_hidden"); + DO_CALLBACK(events, "timestamp_change_pause"); + DO_CALLBACK(events, "mark_no_new"); + const std::size_t tx_index2 = events.size(); + events.push_back(tx_0); + DO_CALLBACK(events, "check_txpool_spent_keys"); + DO_CALLBACK(events, "mark_timestamp_change"); + DO_CALLBACK(events, "check_unchanged"); + + // use same key image with different id + cryptonote::transaction tx_1; + { + auto events_copy = events; + events_copy.erase(events_copy.begin() + tx_index1); + events_copy.erase(events_copy.begin() + tx_index2 - 1); + MAKE_TX(events_copy, tx_temp, miner_account, bob_account, send_amount, blk_0); + tx_1 = tx_temp; + } + + // same key image + DO_CALLBACK(events, "timestamp_change_pause"); + DO_CALLBACK(events, "mark_failed"); + events.push_back(tx_1); + DO_CALLBACK(events, "check_unchanged"); + + return true; +} + diff --git a/tests/core_tests/tx_pool.h b/tests/core_tests/tx_pool.h index 996c76698..eb71dcf79 100644 --- a/tests/core_tests/tx_pool.h +++ b/tests/core_tests/tx_pool.h @@ -77,6 +77,7 @@ class txpool_double_spend_base : public txpool_base std::unordered_set<crypto::hash> m_no_relay_hashes; std::unordered_map<crypto::hash, uint64_t> m_all_hashes; size_t m_no_new_index; + size_t m_failed_index; size_t m_new_timestamp_index; crypto::hash m_last_tx; @@ -86,6 +87,7 @@ public: txpool_double_spend_base(); bool mark_no_new(cryptonote::core& c, size_t ev_index, const std::vector<test_event_entry>& events); + bool mark_failed(cryptonote::core& c, size_t ev_index, const std::vector<test_event_entry>& events); bool mark_timestamp_change(cryptonote::core& c, size_t ev_index, const std::vector<test_event_entry>& events); //! Pause for 1 second, so that `receive_time` for tx meta changes (tx hidden from public rpc being updated) @@ -116,3 +118,12 @@ struct txpool_double_spend_local : txpool_double_spend_base bool generate(std::vector<test_event_entry>& events) const; }; + +struct txpool_double_spend_keyimage : txpool_double_spend_base +{ + txpool_double_spend_keyimage() + : txpool_double_spend_base() + {} + + bool generate(std::vector<test_event_entry>& events) const; +}; diff --git a/tests/functional_tests/make_test_signature.cc b/tests/functional_tests/make_test_signature.cc index 789523de5..6ac1a6a86 100644 --- a/tests/functional_tests/make_test_signature.cc +++ b/tests/functional_tests/make_test_signature.cc @@ -33,9 +33,9 @@ int main(int argc, const char **argv) { TRY_ENTRY(); - if (argc > 2) + if (argc > 3) { - fprintf(stderr, "usage: %s <secret_key>\n", argv[0]); + fprintf(stderr, "usage: %s [<secret_key> [N]]\n", argv[0]); return 1; } @@ -55,8 +55,22 @@ int main(int argc, const char **argv) fprintf(stderr, "invalid secret key\n"); return 1; } - std::string signature = cryptonote::make_rpc_payment_signature(skey); - printf("%s\n", signature.c_str()); + uint32_t count = 1; + if (argc == 3) + { + int i = atoi(argv[2]); + if (i <= 0) + { + fprintf(stderr, "invalid count\n"); + return 1; + } + count = (uint32_t)i; + } + while (count--) + { + std::string signature = cryptonote::make_rpc_payment_signature(skey); + printf("%s\n", signature.c_str()); + } return 0; CATCH_ENTRY_L0("main()", 1); } diff --git a/tests/functional_tests/rpc_payment.py b/tests/functional_tests/rpc_payment.py index 4c777ccd7..3bf995f0c 100755 --- a/tests/functional_tests/rpc_payment.py +++ b/tests/functional_tests/rpc_payment.py @@ -31,6 +31,7 @@ from __future__ import print_function import subprocess import os +import time """Test daemon RPC payment calls """ @@ -43,6 +44,7 @@ class RPCPaymentTest(): self.make_test_signature = os.environ['MAKE_TEST_SIGNATURE'] assert len(self.make_test_signature) > 0 self.secret_key, self.public_key = self.get_keys() + self.signatures = [] self.reset() self.test_access_tracking() self.test_access_mining() @@ -56,8 +58,17 @@ class RPCPaymentTest(): assert len(fields) == 2 return fields + def refill_signatures(self): + signatures = subprocess.check_output([self.make_test_signature, self.secret_key, '256']).decode('utf-8') + for line in signatures.split(): + self.signatures.append(line.rstrip()) + def get_signature(self): - return subprocess.check_output([self.make_test_signature, self.secret_key]).decode('utf-8').rstrip() + if len(self.signatures) == 0: + self.refill_signatures() + s = self.signatures[0] + self.signatures = self.signatures[1:] + return s def reset(self): print('Resetting blockchain') @@ -143,6 +154,7 @@ class RPCPaymentTest(): found_valid = 0 found_invalid = 0 last_credits = 0 + loop_time = time.time() while found_valid == 0 or found_invalid == 0: nonce += 1 try: @@ -152,10 +164,17 @@ class RPCPaymentTest(): except Exception as e: found_invalid += 1 res = daemon.rpc_access_info(client = self.get_signature()) + cookie = res.cookie + loop_time = time.time() assert res.credits < last_credits or res.credits == 0 assert nonce < 1000 # can't find both valid and invalid -> the RPC probably fails last_credits = res.credits + if time.time() >= loop_time + 10: + res = daemon.rpc_access_info(client = self.get_signature()) + cookie = res.cookie + loop_time = time.time() + # we should now have 1 valid nonce, and a number of bad ones res = daemon.rpc_access_info(client = self.get_signature()) assert len(res.hashing_blob) > 39 @@ -176,6 +195,7 @@ class RPCPaymentTest(): assert e.nonces_dupe == 0 # Try random nonces till we find one that's valid so we get a load of credits + loop_time = time.time() while last_credits == 0: nonce += 1 try: @@ -186,6 +206,10 @@ class RPCPaymentTest(): except: found_invalid += 1 assert nonce < 1000 # can't find a valid none -> the RPC probably fails + if time.time() >= loop_time + 10: + res = daemon.rpc_access_info(client = self.get_signature()) + cookie = res.cookie + loop_time = time.time() # we should now have at least 5000 res = daemon.rpc_access_info(client = self.get_signature()) @@ -208,6 +232,7 @@ class RPCPaymentTest(): res = daemon.rpc_access_info(client = self.get_signature()) cookie = res.cookie old_cookie = cookie # we keep that so can submit a stale later + loop_time = time.time() while True: nonce += 1 try: @@ -218,6 +243,11 @@ class RPCPaymentTest(): found_invalid += 1 assert nonce < 1000 # can't find both valid and invalid -> the RPC probably fails + if time.time() >= loop_time + 10: + res = daemon.rpc_access_info(client = self.get_signature()) + cookie = res.cookie + loop_time = time.time() + res = daemon.rpc_access_data() assert len(res.entries) > 0 e = [x for x in res.entries if x['client'] == self.public_key] @@ -247,14 +277,17 @@ class RPCPaymentTest(): # find stales without updating cookie, one within 5 seconds (accepted), one later (rejected) res = daemon.rpc_access_info(client = self.get_signature()) + cookie = res.cookie # let the daemon update its timestamp, but use old cookie found_close_stale = 0 found_late_stale = 0 + loop_time = time.time() while found_close_stale == 0 or found_late_stale == 0: nonce += 1 try: res = daemon.rpc_access_submit_nonce(nonce = nonce, cookie = cookie, client = self.get_signature()) found_close_stale += 1 found_valid += 1 + time.sleep(15) # now we've got an early stale, wait till they become late stales except Exception as e: #if e[0]['error']['code'] == -18: # stale if "'code': -18" in str(e): # stale (ugly version, but also works with python 3) @@ -263,6 +296,11 @@ class RPCPaymentTest(): found_invalid += 1 assert nonce < 1000 # can't find both valid and invalid -> the RPC probably fails + if time.time() >= loop_time + 10: + res = daemon.rpc_access_info(client = self.get_signature()) + # cookie = res.cookie # let the daemon update its timestamp, but use old cookie + loop_time = time.time() + res = daemon.rpc_access_data() assert len(res.entries) > 0 e = [x for x in res.entries if x['client'] == self.public_key] diff --git a/tests/functional_tests/transfer.py b/tests/functional_tests/transfer.py index 3bed69b98..c3d71aa9c 100755 --- a/tests/functional_tests/transfer.py +++ b/tests/functional_tests/transfer.py @@ -256,7 +256,6 @@ class TransferTest(): assert res.too_big == False assert res.overspend == False assert res.fee_too_low == False - assert res.not_rct == False self.wallet[0].refresh() @@ -598,7 +597,6 @@ class TransferTest(): assert res.too_big == False assert res.overspend == False assert res.fee_too_low == False - assert res.not_rct == False res = daemon.get_transactions([txes[0][0]]) assert len(res.txs) >= 1 @@ -615,7 +613,6 @@ class TransferTest(): assert res.too_big == False assert res.overspend == False assert res.fee_too_low == False - assert res.not_rct == False assert res.too_few_outputs == False res = daemon.get_transactions([txes[0][0]]) diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt index cda25dfc9..9c24a5ec7 100644 --- a/tests/unit_tests/CMakeLists.txt +++ b/tests/unit_tests/CMakeLists.txt @@ -34,6 +34,7 @@ set(unit_tests_sources blockchain_db.cpp block_queue.cpp block_reward.cpp + bootstrap_node_selector.cpp bulletproofs.cpp canonical_amounts.cpp chacha.cpp @@ -93,7 +94,8 @@ set(unit_tests_sources wipeable_string.cpp is_hdd.cpp aligned.cpp - rpc_version_str.cpp) + rpc_version_str.cpp + zmq_rpc.cpp) set(unit_tests_headers unit_tests_utils.h) @@ -106,6 +108,7 @@ target_link_libraries(unit_tests ringct cryptonote_protocol cryptonote_core + daemon_messages blockchain_db lmdb_lib rpc diff --git a/tests/unit_tests/bootstrap_node_selector.cpp b/tests/unit_tests/bootstrap_node_selector.cpp new file mode 100644 index 000000000..c609d1223 --- /dev/null +++ b/tests/unit_tests/bootstrap_node_selector.cpp @@ -0,0 +1,172 @@ +// Copyright (c) 2020, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <gtest/gtest.h> + +#include "rpc/bootstrap_node_selector.h" + +class bootstrap_node_selector : public ::testing::Test +{ +protected: + void SetUp() override + { + nodes.insert(white_nodes.begin(), white_nodes.end()); + nodes.insert(gray_nodes.begin(), gray_nodes.end()); + } + + const std::map<std::string, bool> white_nodes = { + { + "white_node_1:18089", true + }, + { + "white_node_2:18081", true + } + }; + const std::map<std::string, bool> gray_nodes = { + { + "gray_node_1:18081", false + }, + { + "gray_node_2:18089", false + } + }; + + std::map<std::string, bool> nodes; +}; + +TEST_F(bootstrap_node_selector, selector_auto_empty) +{ + cryptonote::bootstrap_node::selector_auto selector([]() { + return std::map<std::string, bool>(); + }); + + EXPECT_FALSE(selector.next_node()); +} + +TEST_F(bootstrap_node_selector, selector_auto_no_credentials) +{ + cryptonote::bootstrap_node::selector_auto selector([this]() { + return nodes; + }); + + for (size_t fails = 0; fails < nodes.size(); ++fails) + { + const auto current = selector.next_node(); + EXPECT_FALSE(current->credentials); + + selector.handle_result(current->address, false); + } +} + +TEST_F(bootstrap_node_selector, selector_auto_success) +{ + cryptonote::bootstrap_node::selector_auto selector([this]() { + return nodes; + }); + + auto current = selector.next_node(); + for (size_t fails = 0; fails < nodes.size(); ++fails) + { + selector.handle_result(current->address, true); + + current = selector.next_node(); + EXPECT_TRUE(white_nodes.count(current->address) > 0); + } +} + +TEST_F(bootstrap_node_selector, selector_auto_failure) +{ + cryptonote::bootstrap_node::selector_auto selector([this]() { + return nodes; + }); + + auto current = selector.next_node(); + for (size_t fails = 0; fails < nodes.size(); ++fails) + { + const auto previous = current; + + selector.handle_result(current->address, false); + + current = selector.next_node(); + EXPECT_NE(current->address, previous->address); + } +} + +TEST_F(bootstrap_node_selector, selector_auto_white_nodes_first) +{ + cryptonote::bootstrap_node::selector_auto selector([this]() { + return nodes; + }); + + for (size_t iterations = 0; iterations < 2; ++iterations) + { + for (size_t fails = 0; fails < white_nodes.size(); ++fails) + { + const auto current = selector.next_node(); + EXPECT_TRUE(white_nodes.count(current->address) > 0); + + selector.handle_result(current->address, false); + } + + for (size_t fails = 0; fails < gray_nodes.size(); ++fails) + { + const auto current = selector.next_node(); + EXPECT_TRUE(gray_nodes.count(current->address) > 0); + + selector.handle_result(current->address, false); + } + } +} + +TEST_F(bootstrap_node_selector, selector_auto_max_nodes) +{ + const size_t max_nodes = nodes.size() / 2; + + bool populated_once = false; + cryptonote::bootstrap_node::selector_auto selector([this, &populated_once]() { + if (!populated_once) + { + populated_once = true; + return nodes; + } + + return std::map<std::string, bool>(); + }, max_nodes); + + std::set<std::string> unique_nodes; + + for (size_t fails = 0; fails < nodes.size(); ++fails) + { + const auto current = selector.next_node(); + unique_nodes.insert(current->address); + + selector.handle_result(current->address, false); + } + + EXPECT_EQ(unique_nodes.size(), max_nodes); +} diff --git a/tests/unit_tests/epee_utils.cpp b/tests/unit_tests/epee_utils.cpp index 513c2227c..42bbb26bb 100644 --- a/tests/unit_tests/epee_utils.cpp +++ b/tests/unit_tests/epee_utils.cpp @@ -824,14 +824,14 @@ TEST(ToHex, String) } -TEST(FromHex, String) +TEST(HexLocale, String) { // the source data to encode and decode std::vector<uint8_t> source{{ 0x00, 0xFF, 0x0F, 0xF0 }}; // encode and decode the data auto hex = epee::to_hex::string({ source.data(), source.size() }); - auto decoded = epee::from_hex::vector(hex); + auto decoded = epee::from_hex_locale::to_vector(hex); // encoded should be twice the size and should decode to the exact same data EXPECT_EQ(source.size() * 2, hex.size()); @@ -840,7 +840,7 @@ TEST(FromHex, String) // we will now create a padded hex string, we want to explicitly allow // decoding it this way also, ignoring spaces and colons between the numbers hex.assign("00:ff 0f:f0"); - EXPECT_EQ(source, epee::from_hex::vector(hex)); + EXPECT_EQ(source, epee::from_hex_locale::to_vector(hex)); } TEST(ToHex, Array) @@ -902,6 +902,46 @@ TEST(ToHex, Formatted) EXPECT_EQ(expected, out.str()); } +TEST(FromHex, ToString) +{ + static constexpr const char hex[] = u8"deadbeeffY"; + static constexpr const char binary[] = { + char(0xde), char(0xad), char(0xbe), char(0xef), 0x00 + }; + + std::string out{}; + EXPECT_FALSE(epee::from_hex::to_string(out, hex)); + + boost::string_ref portion{hex}; + portion.remove_suffix(1); + EXPECT_FALSE(epee::from_hex::to_string(out, portion)); + + portion.remove_suffix(1); + EXPECT_TRUE(epee::from_hex::to_string(out, portion)); + EXPECT_EQ(std::string{binary}, out); +} + +TEST(FromHex, ToBuffer) +{ + static constexpr const char hex[] = u8"deadbeeffY"; + static constexpr const std::uint8_t binary[] = {0xde, 0xad, 0xbe, 0xef}; + + std::vector<std::uint8_t> out{}; + out.resize(sizeof(binary)); + EXPECT_FALSE(epee::from_hex::to_buffer(epee::to_mut_span(out), hex)); + + boost::string_ref portion{hex}; + portion.remove_suffix(1); + EXPECT_FALSE(epee::from_hex::to_buffer(epee::to_mut_span(out), portion)); + + portion.remove_suffix(1); + EXPECT_FALSE(epee::from_hex::to_buffer({out.data(), out.size() - 1}, portion)); + + EXPECT_TRUE(epee::from_hex::to_buffer(epee::to_mut_span(out), portion)); + const std::vector<std::uint8_t> expected{std::begin(binary), std::end(binary)}; + EXPECT_EQ(expected, out); +} + TEST(StringTools, BuffToHex) { const std::vector<unsigned char> all_bytes = get_all_bytes(); diff --git a/tests/unit_tests/hmac_keccak.cpp b/tests/unit_tests/hmac_keccak.cpp index 3898d4a7a..ec7c90dbe 100644 --- a/tests/unit_tests/hmac_keccak.cpp +++ b/tests/unit_tests/hmac_keccak.cpp @@ -123,7 +123,7 @@ static void test_keccak_hmac(const size_t * chunks) } -TEST(keccak_hmac, ) +TEST(keccak_hmac, nullptr) { test_keccak_hmac(nullptr); } diff --git a/tests/unit_tests/keccak.cpp b/tests/unit_tests/keccak.cpp index f4d41a8fa..a869fbaec 100644 --- a/tests/unit_tests/keccak.cpp +++ b/tests/unit_tests/keccak.cpp @@ -54,10 +54,6 @@ extern "C" { keccak_finish(&ctx, md1); \ ASSERT_EQ(memcmp(md0, md1, 32), 0); -TEST(keccak, ) -{ -} - TEST(keccak, 0_and_0) { static const size_t chunks[] = {0}; diff --git a/tests/unit_tests/levin.cpp b/tests/unit_tests/levin.cpp index 38707f075..720103e5a 100644 --- a/tests/unit_tests/levin.cpp +++ b/tests/unit_tests/levin.cpp @@ -462,8 +462,8 @@ TEST_F(levin_notify, fluff_without_padding) } std::vector<cryptonote::blobdata> txs(2); - txs[0].resize(100, 'e'); - txs[1].resize(200, 'f'); + txs[0].resize(100, 'f'); + txs[1].resize(200, 'e'); ASSERT_EQ(10u, contexts_.size()); { @@ -479,6 +479,7 @@ TEST_F(levin_notify, fluff_without_padding) for (++context; context != contexts_.end(); ++context) EXPECT_EQ(1u, context->process_send_queue()); + std::sort(txs.begin(), txs.end()); ASSERT_EQ(9u, receiver_.notified_size()); for (unsigned count = 0; count < 9; ++count) { @@ -510,8 +511,8 @@ TEST_F(levin_notify, fluff_with_padding) } std::vector<cryptonote::blobdata> txs(2); - txs[0].resize(100, 'e'); - txs[1].resize(200, 'f'); + txs[0].resize(100, 'f'); + txs[1].resize(200, 'e'); ASSERT_EQ(10u, contexts_.size()); { @@ -527,6 +528,7 @@ TEST_F(levin_notify, fluff_with_padding) for (++context; context != contexts_.end(); ++context) EXPECT_EQ(1u, context->process_send_queue()); + std::sort(txs.begin(), txs.end()); ASSERT_EQ(9u, receiver_.notified_size()); for (unsigned count = 0; count < 9; ++count) { @@ -558,8 +560,8 @@ TEST_F(levin_notify, private_fluff_without_padding) } std::vector<cryptonote::blobdata> txs(2); - txs[0].resize(100, 'e'); - txs[1].resize(200, 'f'); + txs[0].resize(100, 'f'); + txs[1].resize(200, 'e'); ASSERT_EQ(10u, contexts_.size()); { @@ -572,6 +574,7 @@ TEST_F(levin_notify, private_fluff_without_padding) io_service_.reset(); ASSERT_LT(0u, io_service_.poll()); + std::sort(txs.begin(), txs.end()); EXPECT_EQ(0u, context->process_send_queue()); for (++context; context != contexts_.end(); ++context) { @@ -610,8 +613,8 @@ TEST_F(levin_notify, private_fluff_with_padding) } std::vector<cryptonote::blobdata> txs(2); - txs[0].resize(100, 'e'); - txs[1].resize(200, 'f'); + txs[0].resize(100, 'f'); + txs[1].resize(200, 'e'); ASSERT_EQ(10u, contexts_.size()); { @@ -624,6 +627,7 @@ TEST_F(levin_notify, private_fluff_with_padding) io_service_.reset(); ASSERT_LT(0u, io_service_.poll()); + std::sort(txs.begin(), txs.end()); EXPECT_EQ(0u, context->process_send_queue()); for (++context; context != contexts_.end(); ++context) { diff --git a/tests/unit_tests/mul_div.cpp b/tests/unit_tests/mul_div.cpp index e3f7c34f3..c1a72ce51 100644 --- a/tests/unit_tests/mul_div.cpp +++ b/tests/unit_tests/mul_div.cpp @@ -82,7 +82,7 @@ namespace lo = mul128(0x1111111111111111, 0x1111111111111111, &hi); ASSERT_EQ(lo, 0x0fedcba987654321); - ASSERT_EQ(hi, 0x0123456789abcdf0);; + ASSERT_EQ(hi, 0x0123456789abcdf0); } TEST(mul128_with_carry_1_only, multiplies_correctly) diff --git a/tests/unit_tests/net.cpp b/tests/unit_tests/net.cpp index 250dc35f5..36cb28ae0 100644 --- a/tests/unit_tests/net.cpp +++ b/tests/unit_tests/net.cpp @@ -739,7 +739,7 @@ TEST(i2p_address, epee_serializev_b32) EXPECT_EQ(std::strlen(b32_i2p), host.size()); host.push_back('k'); - EXPECT_TRUE(stg.set_value("host", host, stg.open_section("i2p", nullptr, false))); + EXPECT_TRUE(stg.set_value("host", std::string{host}, stg.open_section("i2p", nullptr, false))); EXPECT_TRUE(command.load(stg)); // poor error reporting from `KV_SERIALIZE` } @@ -790,7 +790,7 @@ TEST(i2p_address, epee_serialize_unknown) EXPECT_EQ(std::strlen(net::i2p_address::unknown_str()), host.size()); host.push_back('k'); - EXPECT_TRUE(stg.set_value("host", host, stg.open_section("i2p", nullptr, false))); + EXPECT_TRUE(stg.set_value("host", std::string{host}, stg.open_section("i2p", nullptr, false))); EXPECT_TRUE(command.load(stg)); // poor error reporting from `KV_SERIALIZE` } diff --git a/tests/unit_tests/node_server.cpp b/tests/unit_tests/node_server.cpp index bda606e1a..b656c4858 100644 --- a/tests/unit_tests/node_server.cpp +++ b/tests/unit_tests/node_server.cpp @@ -90,6 +90,8 @@ public: bool prune_blockchain(uint32_t pruning_seed = 0) { return true; } bool is_within_compiled_block_hash_area(uint64_t height) const { return false; } bool has_block_weights(uint64_t height, uint64_t nblocks) const { return false; } + bool get_txpool_complement(const std::vector<crypto::hash> &hashes, std::vector<cryptonote::blobdata> &txes) { return false; } + bool get_pool_transaction_hashes(std::vector<crypto::hash>& txs, bool include_unrelayed_txes = true) const { return false; } void stop() {} }; diff --git a/tests/unit_tests/test_tx_utils.cpp b/tests/unit_tests/test_tx_utils.cpp index d8d760b07..deb45594d 100644 --- a/tests/unit_tests/test_tx_utils.cpp +++ b/tests/unit_tests/test_tx_utils.cpp @@ -44,7 +44,7 @@ namespace TEST(parse_tx_extra, handles_empty_extra) { - std::vector<uint8_t> extra;; + std::vector<uint8_t> extra; std::vector<cryptonote::tx_extra_field> tx_extra_fields; ASSERT_TRUE(cryptonote::parse_tx_extra(extra, tx_extra_fields)); ASSERT_TRUE(tx_extra_fields.empty()); diff --git a/tests/unit_tests/wipeable_string.cpp b/tests/unit_tests/wipeable_string.cpp index 44e050c5c..9911bd6f4 100644 --- a/tests/unit_tests/wipeable_string.cpp +++ b/tests/unit_tests/wipeable_string.cpp @@ -182,6 +182,7 @@ TEST(wipeable_string, split) ASSERT_TRUE(check_split(" foo bar baz ", {"foo", "bar", "baz"})); ASSERT_TRUE(check_split(" foo bar baz", {"foo", "bar", "baz"})); ASSERT_TRUE(check_split("foo bar baz ", {"foo", "bar", "baz"})); + ASSERT_TRUE(check_split("\tfoo\n bar\r\nbaz", {"foo", "bar", "baz"})); } TEST(wipeable_string, parse_hexstr) diff --git a/tests/unit_tests/zmq_rpc.cpp b/tests/unit_tests/zmq_rpc.cpp new file mode 100644 index 000000000..af1f1608b --- /dev/null +++ b/tests/unit_tests/zmq_rpc.cpp @@ -0,0 +1,55 @@ +// Copyright (c) 2020, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <gtest/gtest.h> + +#include "rpc/message.h" +#include "serialization/json_object.h" + +TEST(ZmqFullMessage, InvalidRequest) +{ + EXPECT_THROW( + (cryptonote::rpc::FullMessage{"{\"jsonrpc\":\"2.0\",\"id\":0,\"params\":[]}", true}), + cryptonote::json::MISSING_KEY + ); + EXPECT_THROW( + (cryptonote::rpc::FullMessage{"{\"jsonrpc\":\"2.0\",\"id\":0,\"method\":3,\"params\":[]}", true}), + cryptonote::json::WRONG_TYPE + ); +} + +TEST(ZmqFullMessage, Request) +{ + static constexpr const char request[] = "{\"jsonrpc\":\"2.0\",\"id\":0,\"method\":\"foo\",\"params\":[]}"; + EXPECT_NO_THROW( + (cryptonote::rpc::FullMessage{request, true}) + ); + + cryptonote::rpc::FullMessage parsed{request, true}; + EXPECT_STREQ("foo", parsed.getRequestType().c_str()); +} |