From 5b812d876f19395c36373ed4f9967e9e768e6640 Mon Sep 17 00:00:00 2001 From: Mike Ellery Date: Fri, 10 Feb 2017 08:13:58 -0800 Subject: [PATCH 1/4] Add unit test for get_counts RPC method (RIPD-1399) --- Builds/VisualStudio2015/RippleD.vcxproj | 4 + .../VisualStudio2015/RippleD.vcxproj.filters | 3 + src/test/rpc/GetCounts_test.cpp | 92 +++++++++++++++++++ src/test/unity/rpc_test_unity.cpp | 1 + 4 files changed, 100 insertions(+) create mode 100644 src/test/rpc/GetCounts_test.cpp diff --git a/Builds/VisualStudio2015/RippleD.vcxproj b/Builds/VisualStudio2015/RippleD.vcxproj index fdf8c7e9d05..318688e5037 100644 --- a/Builds/VisualStudio2015/RippleD.vcxproj +++ b/Builds/VisualStudio2015/RippleD.vcxproj @@ -4835,6 +4835,10 @@ True True + + True + True + True True diff --git a/Builds/VisualStudio2015/RippleD.vcxproj.filters b/Builds/VisualStudio2015/RippleD.vcxproj.filters index c1ddfe0605a..1a4af1f2ca3 100644 --- a/Builds/VisualStudio2015/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2015/RippleD.vcxproj.filters @@ -5517,6 +5517,9 @@ test\rpc + + test\rpc + test\rpc diff --git a/src/test/rpc/GetCounts_test.cpp b/src/test/rpc/GetCounts_test.cpp new file mode 100644 index 00000000000..33e48053481 --- /dev/null +++ b/src/test/rpc/GetCounts_test.cpp @@ -0,0 +1,92 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012-2017 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include +#include +#include +#include + +namespace ripple { + +class GetCounts_test : public beast::unit_test::suite +{ + void testGetCounts() + { + using namespace test::jtx; + + Env env(*this); + // check counts with no transactions posted + auto jrr = env.rpc("get_counts")[jss::result]; + BEAST_EXPECTS(jrr[jss::status] == "success", "status success"); + BEAST_EXPECTS(! jrr.isMember("Transaction"), "Transaction"); + BEAST_EXPECTS(! jrr.isMember("STObject"), "STObject"); + BEAST_EXPECTS(! jrr.isMember("HashRouterEntry"), + "HashRouterEntry field"); + BEAST_EXPECTS(jrr.isMember(jss::uptime) && + ! jrr[jss::uptime].asString().empty(), + "uptime"); + BEAST_EXPECTS(jrr.isMember(jss::dbKBTotal) && + jrr[jss::dbKBTotal].asInt() > 0, + "dbKBTotal"); + + // create some transactions + env.close(); + Account alice {"alice"}; + Account bob {"bob"}; + env.fund (XRP(10000), alice, bob); + env.trust (alice["USD"](1000), bob); + for(auto i=0; i<10; ++i) + { + env (pay (alice, bob, alice["USD"](5))); + env.close(); + } + + jrr = env.rpc("get_counts")[jss::result]; + BEAST_EXPECTS(jrr[jss::status] == "success", "status success"); + BEAST_EXPECTS(jrr.isMember("Transaction") && + jrr["Transaction"].asInt() > 0, + "Transaction field"); + BEAST_EXPECTS(jrr.isMember("STTx") && jrr["STTx"].asInt() > 0, + "STTx field"); + BEAST_EXPECTS(jrr.isMember("STObject") && jrr["STObject"].asInt() > 0, + "STObject field"); + BEAST_EXPECTS(jrr.isMember("HashRouterEntry") && + jrr["HashRouterEntry"].asInt() > 0, + "HashRouterEntry field"); + BEAST_EXPECTS(! jrr.isMember(jss::local_txs), "local_txs"); + + //local_txs field will exist when there are open TXs + env (pay (alice, bob, alice["USD"](5))); + jrr = env.rpc("get_counts")[jss::result]; + BEAST_EXPECTS(jrr.isMember(jss::local_txs) && + jrr[jss::local_txs].asInt() > 0, + "local_txs field"); + } + +public: + void run () + { + testGetCounts(); + } +}; + +BEAST_DEFINE_TESTSUITE(GetCounts,rpc,ripple); + +} // ripple + diff --git a/src/test/unity/rpc_test_unity.cpp b/src/test/unity/rpc_test_unity.cpp index eecd72d9462..17c9c61d26b 100644 --- a/src/test/unity/rpc_test_unity.cpp +++ b/src/test/unity/rpc_test_unity.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include From 14089b5e3b25a2e60c5aa1aed6f0781f5853efbc Mon Sep 17 00:00:00 2001 From: Mike Ellery Date: Fri, 10 Feb 2017 08:56:48 -0800 Subject: [PATCH 2/4] [FOLD] Use BEAST_EXPECT for static assertion --- src/test/rpc/GetCounts_test.cpp | 49 ++++++++++++++++----------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/src/test/rpc/GetCounts_test.cpp b/src/test/rpc/GetCounts_test.cpp index 33e48053481..20315f3c11c 100644 --- a/src/test/rpc/GetCounts_test.cpp +++ b/src/test/rpc/GetCounts_test.cpp @@ -33,17 +33,16 @@ class GetCounts_test : public beast::unit_test::suite Env env(*this); // check counts with no transactions posted auto jrr = env.rpc("get_counts")[jss::result]; - BEAST_EXPECTS(jrr[jss::status] == "success", "status success"); - BEAST_EXPECTS(! jrr.isMember("Transaction"), "Transaction"); - BEAST_EXPECTS(! jrr.isMember("STObject"), "STObject"); - BEAST_EXPECTS(! jrr.isMember("HashRouterEntry"), - "HashRouterEntry field"); - BEAST_EXPECTS(jrr.isMember(jss::uptime) && - ! jrr[jss::uptime].asString().empty(), - "uptime"); - BEAST_EXPECTS(jrr.isMember(jss::dbKBTotal) && - jrr[jss::dbKBTotal].asInt() > 0, - "dbKBTotal"); + BEAST_EXPECT(jrr[jss::status] == "success"); + BEAST_EXPECT(! jrr.isMember("Transaction")); + BEAST_EXPECT(! jrr.isMember("STObject")); + BEAST_EXPECT(! jrr.isMember("HashRouterEntry")); + BEAST_EXPECT( + jrr.isMember(jss::uptime) && + ! jrr[jss::uptime].asString().empty()); + BEAST_EXPECT( + jrr.isMember(jss::dbKBTotal) && + jrr[jss::dbKBTotal].asInt() > 0); // create some transactions env.close(); @@ -58,25 +57,23 @@ class GetCounts_test : public beast::unit_test::suite } jrr = env.rpc("get_counts")[jss::result]; - BEAST_EXPECTS(jrr[jss::status] == "success", "status success"); - BEAST_EXPECTS(jrr.isMember("Transaction") && - jrr["Transaction"].asInt() > 0, - "Transaction field"); - BEAST_EXPECTS(jrr.isMember("STTx") && jrr["STTx"].asInt() > 0, - "STTx field"); - BEAST_EXPECTS(jrr.isMember("STObject") && jrr["STObject"].asInt() > 0, - "STObject field"); - BEAST_EXPECTS(jrr.isMember("HashRouterEntry") && - jrr["HashRouterEntry"].asInt() > 0, - "HashRouterEntry field"); - BEAST_EXPECTS(! jrr.isMember(jss::local_txs), "local_txs"); + BEAST_EXPECT(jrr[jss::status] == "success"); + BEAST_EXPECT( + jrr.isMember("Transaction") && + jrr["Transaction"].asInt() > 0); + BEAST_EXPECT(jrr.isMember("STTx") && jrr["STTx"].asInt() > 0); + BEAST_EXPECT(jrr.isMember("STObject") && jrr["STObject"].asInt() > 0); + BEAST_EXPECT( + jrr.isMember("HashRouterEntry") && + jrr["HashRouterEntry"].asInt() > 0); + BEAST_EXPECT(! jrr.isMember(jss::local_txs)); //local_txs field will exist when there are open TXs env (pay (alice, bob, alice["USD"](5))); jrr = env.rpc("get_counts")[jss::result]; - BEAST_EXPECTS(jrr.isMember(jss::local_txs) && - jrr[jss::local_txs].asInt() > 0, - "local_txs field"); + BEAST_EXPECT( + jrr.isMember(jss::local_txs) && + jrr[jss::local_txs].asInt() > 0); } public: From b740444b06d45aef72000fee42e397bb2ebfdd52 Mon Sep 17 00:00:00 2001 From: Mike Ellery Date: Fri, 10 Feb 2017 11:10:54 -0800 Subject: [PATCH 3/4] [FOLD] Add check using minimum threshold --- src/test/rpc/GetCounts_test.cpp | 38 +++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/test/rpc/GetCounts_test.cpp b/src/test/rpc/GetCounts_test.cpp index 20315f3c11c..ec161df1ccd 100644 --- a/src/test/rpc/GetCounts_test.cpp +++ b/src/test/rpc/GetCounts_test.cpp @@ -50,7 +50,7 @@ class GetCounts_test : public beast::unit_test::suite Account bob {"bob"}; env.fund (XRP(10000), alice, bob); env.trust (alice["USD"](1000), bob); - for(auto i=0; i<10; ++i) + for(auto i=0; i<20; ++i) { env (pay (alice, bob, alice["USD"](5))); env.close(); @@ -61,16 +61,46 @@ class GetCounts_test : public beast::unit_test::suite BEAST_EXPECT( jrr.isMember("Transaction") && jrr["Transaction"].asInt() > 0); - BEAST_EXPECT(jrr.isMember("STTx") && jrr["STTx"].asInt() > 0); - BEAST_EXPECT(jrr.isMember("STObject") && jrr["STObject"].asInt() > 0); + BEAST_EXPECT(jrr.isMember( + "STTx") && + jrr["STTx"].asInt() > 0); + BEAST_EXPECT( + jrr.isMember("STObject") && + jrr["STObject"].asInt() > 0); + BEAST_EXPECT( + jrr.isMember("NodeObject") && + jrr["NodeObject"].asInt() > 0); + BEAST_EXPECT( + jrr.isMember("STArray") && + jrr["STArray"].asInt() > 0); BEAST_EXPECT( jrr.isMember("HashRouterEntry") && jrr["HashRouterEntry"].asInt() > 0); + BEAST_EXPECT( + jrr.isMember("STLedgerEntry") && + jrr["STLedgerEntry"].asInt() > 0); BEAST_EXPECT(! jrr.isMember(jss::local_txs)); - //local_txs field will exist when there are open TXs + // make request with min threshold 100 and verify + // that only STObject and NodeObject are reported + jrr = env.rpc("get_counts", "100")[jss::result]; + BEAST_EXPECT(jrr[jss::status] == "success"); + BEAST_EXPECT(! jrr.isMember("Transaction")); + BEAST_EXPECT(! jrr.isMember("STTx")); + BEAST_EXPECT( + jrr.isMember("STObject") && + jrr["STObject"].asInt() > 0); + BEAST_EXPECT( + jrr.isMember("NodeObject") && + jrr["NodeObject"].asInt() > 0); + BEAST_EXPECT(! jrr.isMember("STArray")); + BEAST_EXPECT(! jrr.isMember("HashRouterEntry")); + BEAST_EXPECT(! jrr.isMember("STLedgerEntry")); + + // local_txs field will exist when there are open Txs env (pay (alice, bob, alice["USD"](5))); jrr = env.rpc("get_counts")[jss::result]; + // deliberately don't call close so we have open Tx BEAST_EXPECT( jrr.isMember(jss::local_txs) && jrr[jss::local_txs].asInt() > 0); From 914616f985009b6fd18cdd463db3f2baa6f303c1 Mon Sep 17 00:00:00 2001 From: Mike Ellery Date: Thu, 16 Feb 2017 13:22:34 -0800 Subject: [PATCH 4/4] [FOLD] Verify counts against CountedObjects --- src/test/rpc/GetCounts_test.cpp | 117 ++++++++++++++++---------------- 1 file changed, 58 insertions(+), 59 deletions(-) diff --git a/src/test/rpc/GetCounts_test.cpp b/src/test/rpc/GetCounts_test.cpp index ec161df1ccd..c7abadf1d2d 100644 --- a/src/test/rpc/GetCounts_test.cpp +++ b/src/test/rpc/GetCounts_test.cpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace ripple { @@ -29,20 +30,23 @@ class GetCounts_test : public beast::unit_test::suite void testGetCounts() { using namespace test::jtx; - Env env(*this); - // check counts with no transactions posted - auto jrr = env.rpc("get_counts")[jss::result]; - BEAST_EXPECT(jrr[jss::status] == "success"); - BEAST_EXPECT(! jrr.isMember("Transaction")); - BEAST_EXPECT(! jrr.isMember("STObject")); - BEAST_EXPECT(! jrr.isMember("HashRouterEntry")); - BEAST_EXPECT( - jrr.isMember(jss::uptime) && - ! jrr[jss::uptime].asString().empty()); - BEAST_EXPECT( - jrr.isMember(jss::dbKBTotal) && - jrr[jss::dbKBTotal].asInt() > 0); + + Json::Value result; + { + // check counts with no transactions posted + result = env.rpc("get_counts")[jss::result]; + BEAST_EXPECT(result[jss::status] == "success"); + BEAST_EXPECT(! result.isMember("Transaction")); + BEAST_EXPECT(! result.isMember("STObject")); + BEAST_EXPECT(! result.isMember("HashRouterEntry")); + BEAST_EXPECT( + result.isMember(jss::uptime) && + ! result[jss::uptime].asString().empty()); + BEAST_EXPECT( + result.isMember(jss::dbKBTotal) && + result[jss::dbKBTotal].asInt() > 0); + } // create some transactions env.close(); @@ -56,54 +60,49 @@ class GetCounts_test : public beast::unit_test::suite env.close(); } - jrr = env.rpc("get_counts")[jss::result]; - BEAST_EXPECT(jrr[jss::status] == "success"); - BEAST_EXPECT( - jrr.isMember("Transaction") && - jrr["Transaction"].asInt() > 0); - BEAST_EXPECT(jrr.isMember( - "STTx") && - jrr["STTx"].asInt() > 0); - BEAST_EXPECT( - jrr.isMember("STObject") && - jrr["STObject"].asInt() > 0); - BEAST_EXPECT( - jrr.isMember("NodeObject") && - jrr["NodeObject"].asInt() > 0); - BEAST_EXPECT( - jrr.isMember("STArray") && - jrr["STArray"].asInt() > 0); - BEAST_EXPECT( - jrr.isMember("HashRouterEntry") && - jrr["HashRouterEntry"].asInt() > 0); - BEAST_EXPECT( - jrr.isMember("STLedgerEntry") && - jrr["STLedgerEntry"].asInt() > 0); - BEAST_EXPECT(! jrr.isMember(jss::local_txs)); + { + // check counts, default params + result = env.rpc("get_counts")[jss::result]; + BEAST_EXPECT(result[jss::status] == "success"); + // compare with values reported by CountedObjects + auto const& objectCounts = CountedObjects::getInstance ().getCounts (10); + for (auto const& it : objectCounts) + { + BEAST_EXPECTS(result.isMember(it.first), it.first); + BEAST_EXPECTS(result[it.first].asInt() == it.second, it.first); + } + BEAST_EXPECT(! result.isMember(jss::local_txs)); + } + + { + // make request with min threshold 100 and verify + // that only STObject and NodeObject are reported + result = env.rpc("get_counts", "100")[jss::result]; + BEAST_EXPECT(result[jss::status] == "success"); - // make request with min threshold 100 and verify - // that only STObject and NodeObject are reported - jrr = env.rpc("get_counts", "100")[jss::result]; - BEAST_EXPECT(jrr[jss::status] == "success"); - BEAST_EXPECT(! jrr.isMember("Transaction")); - BEAST_EXPECT(! jrr.isMember("STTx")); - BEAST_EXPECT( - jrr.isMember("STObject") && - jrr["STObject"].asInt() > 0); - BEAST_EXPECT( - jrr.isMember("NodeObject") && - jrr["NodeObject"].asInt() > 0); - BEAST_EXPECT(! jrr.isMember("STArray")); - BEAST_EXPECT(! jrr.isMember("HashRouterEntry")); - BEAST_EXPECT(! jrr.isMember("STLedgerEntry")); + // compare with values reported by CountedObjects + auto const& objectCounts = CountedObjects::getInstance ().getCounts (100); + for (auto const& it : objectCounts) + { + BEAST_EXPECTS(result.isMember(it.first), it.first); + BEAST_EXPECTS(result[it.first].asInt() == it.second, it.first); + } + BEAST_EXPECT(! result.isMember("Transaction")); + BEAST_EXPECT(! result.isMember("STTx")); + BEAST_EXPECT(! result.isMember("STArray")); + BEAST_EXPECT(! result.isMember("HashRouterEntry")); + BEAST_EXPECT(! result.isMember("STLedgerEntry")); + } - // local_txs field will exist when there are open Txs - env (pay (alice, bob, alice["USD"](5))); - jrr = env.rpc("get_counts")[jss::result]; - // deliberately don't call close so we have open Tx - BEAST_EXPECT( - jrr.isMember(jss::local_txs) && - jrr[jss::local_txs].asInt() > 0); + { + // local_txs field will exist when there are open Txs + env (pay (alice, bob, alice["USD"](5))); + result = env.rpc("get_counts")[jss::result]; + // deliberately don't call close so we have open Tx + BEAST_EXPECT( + result.isMember(jss::local_txs) && + result[jss::local_txs].asInt() > 0); + } } public: