rippled
Loading...
Searching...
No Matches
Env.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_TEST_JTX_ENV_H_INCLUDED
21#define RIPPLE_TEST_JTX_ENV_H_INCLUDED
22
23#include <test/jtx/AbstractClient.h>
24#include <test/jtx/Account.h>
25#include <test/jtx/JTx.h>
26#include <test/jtx/ManualTimeKeeper.h>
27#include <test/jtx/amount.h>
28#include <test/jtx/envconfig.h>
29#include <test/jtx/require.h>
30#include <test/jtx/tags.h>
31#include <test/unit_test/SuiteJournal.h>
32#include <xrpld/app/ledger/Ledger.h>
33#include <xrpld/app/ledger/OpenLedger.h>
34#include <xrpld/app/main/Application.h>
35#include <xrpld/app/paths/Pathfinder.h>
36#include <xrpld/core/Config.h>
37#include <xrpld/rpc/detail/RPCHelpers.h>
38#include <xrpl/basics/Log.h>
39#include <xrpl/basics/chrono.h>
40#include <xrpl/beast/utility/Journal.h>
41#include <xrpl/json/json_value.h>
42#include <xrpl/json/to_string.h>
43#include <xrpl/protocol/Feature.h>
44#include <xrpl/protocol/Indexes.h>
45#include <xrpl/protocol/Issue.h>
46#include <xrpl/protocol/STAmount.h>
47#include <xrpl/protocol/STObject.h>
48#include <xrpl/protocol/STTx.h>
49#include <functional>
50#include <string>
51#include <tuple>
52#include <type_traits>
53#include <unordered_map>
54#include <utility>
55#include <vector>
56
57namespace ripple {
58namespace test {
59namespace jtx {
60
62template <class... Args>
63std::array<Account, 1 + sizeof...(Args)>
64noripple(Account const& account, Args const&... args)
65{
66 return {{account, args...}};
67}
68
69inline FeatureBitset
71{
72 static const FeatureBitset ids = [] {
73 auto const& sa = ripple::detail::supportedAmendments();
75 feats.reserve(sa.size());
76 for (auto const& [s, vote] : sa)
77 {
78 (void)vote;
79 if (auto const f = getRegisteredFeature(s))
80 feats.push_back(*f);
81 else
82 Throw<std::runtime_error>(
83 "Unknown feature: " + s + " in supportedAmendments.");
84 }
85 return FeatureBitset(feats);
86 }();
87 return ids;
88}
89
90//------------------------------------------------------------------------------
91
92class SuiteLogs : public Logs
93{
95
96public:
98 : Logs(beast::severities::kError), suite_(suite)
99 {
100 }
101
102 ~SuiteLogs() override = default;
103
106 std::string const& partition,
108 {
109 return std::make_unique<SuiteJournalSink>(partition, threshold, suite_);
110 }
111};
112
113//------------------------------------------------------------------------------
114
116class Env
117{
118public:
120
122
125 {
127 // RPC errors tend to return either a "code" and a "message" (sometimes
128 // with an "error" that corresponds to the "code"), or with an "error"
129 // and an "exception". However, this structure allows all possible
130 // combinations.
135 };
136
137private:
139 {
140 Application* app = nullptr;
145
146 AppBundle() = default;
147 AppBundle(
152 ~AppBundle();
153 };
154
156
157public:
159
160 Env() = delete;
161 Env&
162 operator=(Env const&) = delete;
163 Env(Env const&) = delete;
164
179 // VFALCO Could wrap the suite::log in a Journal here
182 FeatureBitset features,
183 std::unique_ptr<Logs> logs = nullptr,
185 : test(suite_)
186 , bundle_(suite_, std::move(config), std::move(logs), thresh)
187 , journal{bundle_.app->journal("Env")}
188 {
192 features, [&appFeats = app().config().features](uint256 const& f) {
193 appFeats.insert(f);
194 });
195 }
196
211 : Env(suite_, envconfig(), features)
212 {
213 }
214
229 std::unique_ptr<Logs> logs = nullptr,
231 : Env(suite_,
232 std::move(config),
234 std::move(logs),
235 thresh)
236 {
237 }
238
249 {
250 }
251
252 virtual ~Env() = default;
253
256 {
257 return *bundle_.app;
258 }
259
260 Application const&
261 app() const
262 {
263 return *bundle_.app;
264 }
265
268 {
269 return *bundle_.timeKeeper;
270 }
271
279 {
280 return timeKeeper().now();
281 }
282
286 {
287 return *bundle_.client;
288 }
289
295 template <class... Args>
297 rpc(unsigned apiVersion,
299 std::string const& cmd,
300 Args&&... args);
301
302 template <class... Args>
304 rpc(unsigned apiVersion, std::string const& cmd, Args&&... args);
305
306 template <class... Args>
309 std::string const& cmd,
310 Args&&... args);
311
312 template <class... Args>
314 rpc(std::string const& cmd, Args&&... args);
315
325 current() const
326 {
327 return app().openLedger().current();
328 }
329
338 closed();
339
359 bool
360 close(
361 NetClock::time_point closeTime,
362 std::optional<std::chrono::milliseconds> consensusDelay = std::nullopt);
363
371 template <class Rep, class Period>
372 bool
374 {
375 // VFALCO Is this the correct time?
376 return close(now() + elapsed);
377 }
378
386 bool
388 {
389 // VFALCO Is this the correct time?
390 return close(std::chrono::seconds(5));
391 }
392
396 void
397 trace(int howMany = -1)
398 {
399 trace_ = howMany;
400 }
401
403 void
405 {
406 trace_ = 0;
407 }
408
409 void
411 {
413 }
414
416 void
418 {
419 app().checkSigs(false);
420 }
421
423 void
424 memoize(Account const& account);
425
428 Account const&
429 lookup(AccountID const& id) const;
430
431 Account const&
432 lookup(std::string const& base58ID) const;
439 balance(Account const& account) const;
440
446 seq(Account const& account) const;
447
451 // VFALCO NOTE This should return a unit-less amount
453 balance(Account const& account, Issue const& issue) const;
454
459 ownerCount(Account const& account) const;
460
465 le(Account const& account) const;
466
471 le(Keylet const& k) const;
472
474 template <class JsonValue, class... FN>
475 JTx
476 jt(JsonValue&& jv, FN const&... fN)
477 {
478 JTx jt(std::forward<JsonValue>(jv));
479 invoke(jt, fN...);
480 autofill(jt);
481 jt.stx = st(jt);
482 return jt;
483 }
484
486 template <class JsonValue, class... FN>
487 JTx
488 jtnofill(JsonValue&& jv, FN const&... fN)
489 {
490 JTx jt(std::forward<JsonValue>(jv));
491 invoke(jt, fN...);
493 jt.stx = st(jt);
494 return jt;
495 }
496
500 template <class JsonValue, class... FN>
502 json(JsonValue&& jv, FN const&... fN)
503 {
504 auto tj = jt(std::forward<JsonValue>(jv), fN...);
505 return std::move(tj.jv);
506 }
507
513 template <class... Args>
514 void
515 require(Args const&... args)
516 {
517 jtx::required(args...)(*this);
518 }
519
522 static ParsedResult
523 parseResult(Json::Value const& jr);
524
528 virtual void
529 submit(JTx const& jt);
530
534 void
536
540 void
542 JTx const& jt,
543 ParsedResult const& parsed,
544 Json::Value const& jr = Json::Value());
545
548 template <class JsonValue, class... FN>
549 Env&
550 apply(JsonValue&& jv, FN const&... fN)
551 {
552 submit(jt(std::forward<JsonValue>(jv), fN...));
553 return *this;
554 }
555
556 template <class JsonValue, class... FN>
557 Env&
558 operator()(JsonValue&& jv, FN const&... fN)
559 {
560 return apply(std::forward<JsonValue>(jv), fN...);
561 }
565 TER
566 ter() const
567 {
568 return ter_;
569 }
570
580 meta();
581
594 tx() const;
595
596 void
597 enableFeature(uint256 const feature);
598
599 void
600 disableFeature(uint256 const feature);
601
602private:
603 void
604 fund(bool setDefaultRipple, STAmount const& amount, Account const& account);
605
606 void
607 fund_arg(STAmount const& amount, Account const& account)
608 {
609 fund(true, amount, account);
610 }
611
612 template <std::size_t N>
613 void
614 fund_arg(STAmount const& amount, std::array<Account, N> const& list)
615 {
616 for (auto const& account : list)
617 fund(false, amount, account);
618 }
619
620public:
647 template <class Arg, class... Args>
648 void
649 fund(STAmount const& amount, Arg const& arg, Args const&... args)
650 {
651 fund_arg(amount, arg);
652 if constexpr (sizeof...(args) > 0)
653 fund(amount, args...);
654 }
655
674 void
675 trust(STAmount const& amount, Account const& account);
676
677 template <class... Accounts>
678 void
680 STAmount const& amount,
681 Account const& to0,
682 Account const& to1,
683 Accounts const&... toN)
684 {
685 trust(amount, to0);
686 trust(amount, to1, toN...);
687 }
695 ust(JTx const& jt);
696
697protected:
698 int trace_ = 0;
703
705 do_rpc(
706 unsigned apiVersion,
707 std::vector<std::string> const& args,
709
710 void
712
713 virtual void
714 autofill(JTx& jt);
715
724 st(JTx const& jt);
725
726 // Invoke funclets on stx
727 // Note: The STTx may not be modified
728 template <class... FN>
729 void
730 invoke(STTx& stx, FN const&... fN)
731 {
732 (fN(*this, stx), ...);
733 }
734
735 // Invoke funclets on jt
736 template <class... FN>
737 void
738 invoke(JTx& jt, FN const&... fN)
739 {
740 (fN(*this, jt), ...);
741 }
742
743 // Map of account IDs to Account
745};
746
747template <class... Args>
750 unsigned apiVersion,
752 std::string const& cmd,
753 Args&&... args)
754{
755 return do_rpc(
756 apiVersion,
757 std::vector<std::string>{cmd, std::forward<Args>(args)...},
758 headers);
759}
760
761template <class... Args>
763Env::rpc(unsigned apiVersion, std::string const& cmd, Args&&... args)
764{
765 return rpc(
766 apiVersion,
768 cmd,
769 std::forward<Args>(args)...);
770}
771
772template <class... Args>
776 std::string const& cmd,
777 Args&&... args)
778{
779 return do_rpc(
781 std::vector<std::string>{cmd, std::forward<Args>(args)...},
782 headers);
783}
784
785template <class... Args>
787Env::rpc(std::string const& cmd, Args&&... args)
788{
789 return rpc(
791 cmd,
792 std::forward<Args>(args)...);
793}
794
795} // namespace jtx
796} // namespace test
797} // namespace ripple
798
799#endif
Represents a JSON value.
Definition: json_value.h:147
A generic endpoint for log messages.
Definition: Journal.h:59
A testsuite class.
Definition: suite.h:53
virtual OpenLedger & openLedger()=0
virtual bool checkSigs() const =0
A currency issued by an account.
Definition: Issue.h:36
Manages partitions for logging.
Definition: Log.h:49
beast::severities::Severity threshold() const
Definition: Log.cpp:150
std::shared_ptr< OpenView const > current() const
Returns a view to the current open ledger.
Definition: OpenLedger.cpp:50
static void initPathTable()
time_point now() const override
Returns the current time.
Immutable cryptographic account descriptor.
Definition: Account.h:38
static Account const master
The master account.
Definition: Account.h:47
A transaction testing environment.
Definition: Env.h:117
void fund_arg(STAmount const &amount, std::array< Account, N > const &list)
Definition: Env.h:614
Json::Value json(JsonValue &&jv, FN const &... fN)
Create JSON from parameters.
Definition: Env.h:502
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
Definition: Env.cpp:115
void trace(int howMany=-1)
Turn on JSON tracing.
Definition: Env.h:397
void disableFeature(uint256 const feature)
Definition: Env.cpp:592
bool parseFailureExpected_
Definition: Env.h:702
static ParsedResult parseResult(Json::Value const &jr)
Gets the TER result and didApply flag from a RPC Json result object.
Definition: Env.cpp:285
Env(beast::unit_test::suite &suite_, std::unique_ptr< Config > config, std::unique_ptr< Logs > logs=nullptr, beast::severities::Severity thresh=beast::severities::kError)
Create Env using suite and Config pointer.
Definition: Env.h:227
std::uint32_t ownerCount(Account const &account) const
Return the number of objects owned by an account.
Definition: Env.cpp:207
std::unordered_map< AccountID, Account > map_
Definition: Env.h:744
void notrace()
Turn off JSON tracing.
Definition: Env.h:404
void require(Args const &... args)
Check a set of requirements.
Definition: Env.h:515
void trust(STAmount const &amount, Account const &to0, Account const &to1, Accounts const &... toN)
Definition: Env.h:679
TER ter() const
Return the TER for the last JTx.
Definition: Env.h:566
beast::unit_test::suite & test
Definition: Env.h:119
virtual ~Env()=default
bool close(std::chrono::duration< Rep, Period > const &elapsed)
Close and advance the ledger.
Definition: Env.h:373
AppBundle bundle_
Definition: Env.h:155
std::shared_ptr< STTx const > tx() const
Return the tx data for the last JTx.
Definition: Env.cpp:467
void invoke(JTx &jt, FN const &... fN)
Definition: Env.h:738
Env & operator=(Env const &)=delete
Env & operator()(JsonValue &&jv, FN const &... fN)
Definition: Env.h:558
Env(Env const &)=delete
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition: Env.h:325
void postconditions(JTx const &jt, ParsedResult const &parsed, Json::Value const &jr=Json::Value())
Check expected postconditions of JTx submission.
Definition: Env.cpp:399
void sign_and_submit(JTx const &jt, Json::Value params=Json::nullValue)
Use the submit RPC command with a provided JTx object.
Definition: Env.cpp:361
AbstractClient & client()
Returns the connected client.
Definition: Env.h:285
void autofill_sig(JTx &jt)
Definition: Env.cpp:473
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
Definition: Env.cpp:268
void fund(STAmount const &amount, Arg const &arg, Args const &... args)
Create a new account with some XRP.
Definition: Env.h:649
Json::Value do_rpc(unsigned apiVersion, std::vector< std::string > const &args, std::unordered_map< std::string, std::string > const &headers={})
Definition: Env.cpp:574
void invoke(STTx &stx, FN const &... fN)
Definition: Env.h:730
std::shared_ptr< STTx const > st(JTx const &jt)
Create a STTx from a JTx The framework requires that JSON is valid.
Definition: Env.cpp:522
void enableFeature(uint256 const feature)
Definition: Env.cpp:584
Env(beast::unit_test::suite &suite_)
Create Env with only the current test suite.
Definition: Env.h:248
Account const & master
Definition: Env.h:121
Account const & lookup(AccountID const &id) const
Returns the Account given the AccountID.
Definition: Env.cpp:162
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition: Env.h:476
NetClock::time_point now()
Returns the current network time.
Definition: Env.h:278
std::shared_ptr< STTx const > ust(JTx const &jt)
Create a STTx from a JTx without sanitizing Use to inject bogus values into test transactions by firs...
Definition: Env.cpp:548
Application & app()
Definition: Env.h:255
beast::Journal const journal
Definition: Env.h:158
Env(beast::unit_test::suite &suite_, FeatureBitset features)
Create Env with default config and specified features.
Definition: Env.h:210
ManualTimeKeeper & timeKeeper()
Definition: Env.h:267
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition: Env.h:749
virtual void submit(JTx const &jt)
Submit an existing JTx.
Definition: Env.cpp:323
Env & apply(JsonValue &&jv, FN const &... fN)
Apply funclets and submit.
Definition: Env.h:550
void disable_sigs()
Turn off signature checks.
Definition: Env.h:417
bool close()
Close and advance the ledger.
Definition: Env.h:387
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:237
TestStopwatch stopwatch_
Definition: Env.h:699
Application const & app() const
Definition: Env.h:261
std::shared_ptr< STObject const > meta()
Return metadata for the last JTx.
Definition: Env.cpp:459
JTx jtnofill(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition: Env.h:488
void set_parse_failure_expected(bool b)
Definition: Env.h:410
void memoize(Account const &account)
Associate AccountID with account.
Definition: Env.cpp:156
Env(beast::unit_test::suite &suite_, std::unique_ptr< Config > config, FeatureBitset features, std::unique_ptr< Logs > logs=nullptr, beast::severities::Severity thresh=beast::severities::kError)
Create Env using suite, Config pointer, and explicit features.
Definition: Env.h:180
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
Definition: Env.cpp:225
void fund_arg(STAmount const &amount, Account const &account)
Definition: Env.h:607
SuiteLogs(beast::unit_test::suite &suite)
Definition: Env.h:97
beast::unit_test::suite & suite_
Definition: Env.h:94
std::unique_ptr< beast::Journal::Sink > makeSink(std::string const &partition, beast::severities::Severity threshold) override
Definition: Env.h:105
~SuiteLogs() override=default
A balance matches.
Definition: balance.h:39
Set the expected result code for a JTx The test will fail if the code doesn't match.
Definition: rpc.h:34
Set the expected result code for a JTx The test will fail if the code doesn't match.
Definition: ter.h:34
@ nullValue
'null' value
Definition: json_value.h:36
Severity
Severity level / threshold of a Journal message.
Definition: Journal.h:31
static constexpr auto apiCommandLineVersion
Definition: ApiVersion.h:60
std::map< std::string, VoteBehavior > const & supportedAmendments()
Amendments that this server supports and the default voting behavior.
Definition: Feature.cpp:354
static autofill_t const autofill
Definition: tags.h:42
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:54
require_t required(Args const &... args)
Compose many condition functors into one.
Definition: require.h:47
FeatureBitset supported_amendments()
Definition: Env.h:70
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
std::optional< uint256 > getRegisteredFeature(std::string const &name)
Definition: Feature.cpp:376
@ tesSUCCESS
Definition: TER.h:242
void foreachFeature(FeatureBitset bs, F &&f)
Definition: Feature.h:312
STL namespace.
T push_back(T... args)
T reserve(T... args)
A pair of SHAMap key and LedgerEntryType.
Definition: Keylet.h:39
std::unique_ptr< Application > owned
Definition: Env.h:141
ManualTimeKeeper * timeKeeper
Definition: Env.h:142
std::unique_ptr< AbstractClient > client
Definition: Env.h:144
Used by parseResult() and postConditions()
Definition: Env.h:125
std::optional< error_code_i > rpcCode
Definition: Env.h:131
Execution context for applying a JSON transaction.
Definition: JTx.h:44
std::shared_ptr< STTx const > stx
Definition: JTx.h:54
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...
Set the sequence number on a JTx.
Definition: seq.h:34