2#include <test/jtx/envconfig.h> 
    4#include <xrpld/app/main/Application.h> 
    5#include <xrpld/app/main/NodeStoreScheduler.h> 
    6#include <xrpld/app/misc/SHAMapStore.h> 
    7#include <xrpld/app/rdb/backend/SQLiteDatabase.h> 
    8#include <xrpld/core/ConfigSections.h> 
   10#include <xrpl/nodestore/detail/DatabaseRotatingImp.h> 
   11#include <xrpl/protocol/jss.h> 
   44        auto good = 
json.isMember(jss::result) &&
 
   46            json[jss::result][jss::ledger][jss::ledger_index] == ledgerID;
 
   47        if (!good || !checkDB)
 
   50        auto const seq = 
json[jss::result][jss::ledger_index].asUInt();
 
   72        auto const& ledger = 
json[jss::result][jss::ledger];
 
   73        return outHash == ledger[jss::ledger_hash].asString() &&
 
   75            outParentHash == ledger[jss::parent_hash].asString() &&
 
   76            outDrops == ledger[jss::total_coins].asString() &&
 
   77            outCloseTime == ledger[jss::close_time].asUInt() &&
 
   78            outParentCloseTime == ledger[jss::parent_close_time].asUInt() &&
 
   79            outCloseTimeResolution ==
 
   80            ledger[jss::close_time_resolution].asUInt() &&
 
   81            outCloseFlags == ledger[jss::close_flags].asUInt() &&
 
   82            outAccountHash == ledger[jss::account_hash].asString() &&
 
   83            outTxHash == ledger[jss::transaction_hash].asString();
 
 
   89        return json.isMember(jss::result) &&
 
   91            json[jss::result][jss::error_code] == error;
 
 
   98            json.isMember(jss::result) &&
 
   99            json[jss::result].isMember(jss::ledger) &&
 
  100            json[jss::result][jss::ledger].isMember(jss::ledger_hash) &&
 
  101            json[jss::result][jss::ledger][jss::ledger_hash].isString());
 
  102        return json[jss::result][jss::ledger][jss::ledger_hash].asString();
 
 
  108        auto const [actualRows, actualFirst, actualLast] =
 
  110                ->getLedgerCountMinMax();
 
  112        BEAST_EXPECT(actualRows == rows);
 
  113        BEAST_EXPECT(actualFirst == first);
 
  114        BEAST_EXPECT(actualLast == first + rows - 1);
 
 
  136        using namespace std::chrono_literals;
 
  142        BEAST_EXPECT(!store.getLastRotated());
 
  147        auto ledger = env.
rpc(
"ledger", 
"validated");
 
  150        BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
 
 
  158        using namespace std::chrono_literals;
 
  174        auto ledgerTmp = env.
rpc(
"ledger", 
"0");
 
  175        BEAST_EXPECT(
bad(ledgerTmp));
 
  178        BEAST_EXPECT(
goodLedger(env, ledgers[1], 
"1"));
 
  181        BEAST_EXPECT(
goodLedger(env, ledgers[2], 
"2"));
 
  183        ledgerTmp = env.
rpc(
"ledger", 
"current");
 
  184        BEAST_EXPECT(
goodLedger(env, ledgerTmp, 
"3"));
 
  186        ledgerTmp = env.
rpc(
"ledger", 
"4");
 
  187        BEAST_EXPECT(
bad(ledgerTmp));
 
  189        ledgerTmp = env.
rpc(
"ledger", 
"100");
 
  190        BEAST_EXPECT(
bad(ledgerTmp));
 
  193        auto lastRotated = firstSeq - 1;
 
  200            ledgerTmp = env.
rpc(
"ledger", 
"current");
 
  203        BEAST_EXPECT(store.getLastRotated() == lastRotated);
 
  222            auto ledger = env.
rpc(
"ledger", 
"current");
 
  230        lastRotated = store.getLastRotated();
 
  231        BEAST_EXPECT(lastRotated == 11);
 
  239        for (
auto i = lastRotated - 1; i < lastRotated + 
deleteInterval - 1;
 
  244            ledgerTmp = env.
rpc(
"ledger", 
"current");
 
  250                store.getLastRotated() == lastRotated ||
 
  259        BEAST_EXPECT(store.getLastRotated() == 
deleteInterval + lastRotated);
 
 
  269        testcase(
"automatic online_delete");
 
  271        using namespace std::chrono_literals;
 
  277        auto lastRotated = ledgerSeq - 1;
 
  278        BEAST_EXPECT(store.getLastRotated() == lastRotated);
 
  279        BEAST_EXPECT(lastRotated != 2);
 
  283        auto const canDelete = env.
rpc(
"can_delete");
 
  291            auto ledger = env.
rpc(
"ledger", 
"validated");
 
  301        BEAST_EXPECT(lastRotated == store.getLastRotated());
 
  307            auto ledger = env.
rpc(
"ledger", 
"validated");
 
  314        ledgerCheck(env, ledgerSeq - lastRotated, lastRotated);
 
  315        BEAST_EXPECT(lastRotated != store.getLastRotated());
 
  317        lastRotated = store.getLastRotated();
 
  324            auto ledger = env.
rpc(
"ledger", 
"validated");
 
  332        BEAST_EXPECT(lastRotated != store.getLastRotated());
 
 
  338        testcase(
"online_delete with advisory_delete");
 
  340        using namespace std::chrono_literals;
 
  347        auto lastRotated = ledgerSeq - 1;
 
  348        BEAST_EXPECT(store.getLastRotated() == lastRotated);
 
  349        BEAST_EXPECT(lastRotated != 2);
 
  351        auto canDelete = env.
rpc(
"can_delete");
 
  353        BEAST_EXPECT(canDelete[jss::result][jss::can_delete] == 0);
 
  355        canDelete = env.
rpc(
"can_delete", 
"never");
 
  357        BEAST_EXPECT(canDelete[jss::result][jss::can_delete] == 0);
 
  360        for (; ledgerSeq < firstBatch; ++ledgerSeq)
 
  364            auto ledger = env.
rpc(
"ledger", 
"validated");
 
  372        BEAST_EXPECT(lastRotated == store.getLastRotated());
 
  379            canDelete[jss::result][jss::can_delete] ==
 
  385        BEAST_EXPECT(store.getLastRotated() == lastRotated);
 
  391            auto ledger = env.
rpc(
"ledger", 
"validated");
 
  398        ledgerCheck(env, ledgerSeq - lastRotated, lastRotated);
 
  400        BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
 
  401        lastRotated = ledgerSeq - 1;
 
  408            auto ledger = env.
rpc(
"ledger", 
"validated");
 
  415        BEAST_EXPECT(store.getLastRotated() == lastRotated);
 
  421            auto ledger = env.
rpc(
"ledger", 
"validated");
 
  428        ledgerCheck(env, ledgerSeq - firstBatch, firstBatch);
 
  430        BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
 
  431        lastRotated = ledgerSeq - 1;
 
  434        canDelete = env.
rpc(
"can_delete", 
"always");
 
  437            canDelete[jss::result][jss::can_delete] ==
 
  445            auto ledger = env.
rpc(
"ledger", 
"validated");
 
  452        BEAST_EXPECT(store.getLastRotated() == lastRotated);
 
  458            auto ledger = env.
rpc(
"ledger", 
"validated");
 
  465        ledgerCheck(env, ledgerSeq - lastRotated, lastRotated);
 
  467        BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
 
  468        lastRotated = ledgerSeq - 1;
 
  471        canDelete = env.
rpc(
"can_delete", 
"now");
 
  473        BEAST_EXPECT(canDelete[jss::result][jss::can_delete] == ledgerSeq - 1);
 
  480            auto ledger = env.
rpc(
"ledger", 
"validated");
 
  487        BEAST_EXPECT(store.getLastRotated() == lastRotated);
 
  493            auto ledger = env.
rpc(
"ledger", 
"validated");
 
  500        ledgerCheck(env, ledgerSeq - lastRotated, lastRotated);
 
  502        BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
 
  503        lastRotated = ledgerSeq - 1;
 
 
  514        boost::filesystem::path newPath;
 
  516        if (!BEAST_EXPECT(
path.size()))
 
  519        section.set(
"path", newPath.string());
 
 
  536        testcase(
"rotate with lock contention");
 
  547        if (!nscfg.exists(
"cache_size"))
 
  553        if (!nscfg.exists(
"cache_age"))
 
  568        constexpr int readThreads = 4;
 
  572            std::move(writableBackend),
 
  573            std::move(archiveBackend),
 
  579        using namespace std::chrono_literals;
 
  586            auto const cb = [&](
std::string const& writableName,
 
  588                BEAST_EXPECT(writableName == 
"1");
 
  589                BEAST_EXPECT(archiveName == 
"write");
 
  592                BEAST_EXPECT(dbr->getName() == 
"1");
 
  595            dbr->rotate(std::move(newBackend), cb);
 
  597        BEAST_EXPECT(threadNum == 1);
 
  598        BEAST_EXPECT(dbr->getName() == 
"1");
 
  603            auto const cb = [&](
std::string const& writableName,
 
  605                BEAST_EXPECT(writableName == 
"3");
 
  606                BEAST_EXPECT(archiveName == 
"2");
 
  609                BEAST_EXPECT(dbr->getName() == 
"3");
 
  611            auto const cbReentrant = [&](
std::string const& writableName,
 
  613                BEAST_EXPECT(writableName == 
"2");
 
  614                BEAST_EXPECT(archiveName == 
"1");
 
  618                dbr->rotate(std::move(newBackend), cb);
 
  622            dbr->rotate(std::move(newBackend), cbReentrant);
 
  625        BEAST_EXPECT(threadNum == 3);
 
  626        BEAST_EXPECT(dbr->getName() == 
"3");
 
 
 
testcase_t testcase
Memberspace for declaring test cases.
 
virtual Config & config()=0
 
virtual SHAMapStore & getSHAMapStore()=0
 
virtual JobQueue & getJobQueue()=0
 
virtual RelationalDatabase & getRelationalDatabase()=0
 
Section & section(std::string const &name)
Returns the section with the given name.
 
int getValueFor(SizedItem item, std::optional< std::size_t > node=std::nullopt) const
Retrieve the default value for the item at the specified node size.
 
beast::Journal journal(std::string const &name)
 
A NodeStore::Scheduler which uses the JobQueue.
 
virtual std::unique_ptr< Backend > make_Backend(Section const ¶meters, std::size_t burstSize, Scheduler &scheduler, beast::Journal journal)=0
Create a backend.
 
static Manager & instance()
Returns the instance of the manager singleton.
 
virtual std::optional< LedgerInfo > getLedgerInfoByIndex(LedgerIndex ledgerSeq)=0
getLedgerInfoByIndex Returns a ledger by its sequence.
 
class to create database, launch online delete thread, and related SQLite database
 
virtual void rendezvous() const =0
 
virtual std::size_t getAccountTransactionCount()=0
getAccountTransactionCount Returns the number of account transactions.
 
virtual std::size_t getTransactionCount()=0
getTransactionCount Returns the number of transactions.
 
Holds a collection of configuration values.
 
void set(std::string const &key, std::string const &value)
Set a key/value pair.
 
void ledgerCheck(jtx::Env &env, int const rows, int const first)
 
std::string getHash(Json::Value const &json)
 
static auto advisoryDelete(std::unique_ptr< Config > cfg)
 
int waitForReady(jtx::Env &env)
 
bool bad(Json::Value const &json, error_code_i error=rpcLGR_NOT_FOUND)
 
void run() override
Runs the suite.
 
void accountTransactionCheck(jtx::Env &env, int const rows)
 
static auto onlineDelete(std::unique_ptr< Config > cfg)
 
std::unique_ptr< NodeStore::Backend > makeBackendRotating(jtx::Env &env, NodeStoreScheduler &scheduler, std::string path)
 
void transactionCheck(jtx::Env &env, int const rows)
 
static auto const deleteInterval
 
bool goodLedger(jtx::Env &env, Json::Value const &json, std::string ledgerID, bool checkDB=false)
 
A transaction testing environment.
 
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
 
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
 
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
 
bool contains_error(Json::Value const &json)
Returns true if the json contains an rpc error specification.
 
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
 
XRP_t const XRP
Converts to XRP Issue or STAmount.
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
constexpr auto megabytes(T value) noexcept
 
std::string to_string(base_uint< Bits, Tag > const &a)
 
static std::string nodeDatabase()
 
Set the sequence number on a JTx.
 
T time_since_epoch(T... args)