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
422 // set rpc retries
423 void
424 set_retries(unsigned r = 5)
425 {
426 retries_ = r;
427 }
428
429 // get rpc retries
430 unsigned
431 retries() const
432 {
433 return retries_;
434 }
435
437 void
438 memoize(Account const& account);
439
442 Account const&
443 lookup(AccountID const& id) const;
444
445 Account const&
446 lookup(std::string const& base58ID) const;
453 balance(Account const& account) const;
454
460 seq(Account const& account) const;
461
465 // VFALCO NOTE This should return a unit-less amount
467 balance(Account const& account, Issue const& issue) const;
468
473 ownerCount(Account const& account) const;
474
479 le(Account const& account) const;
480
485 le(Keylet const& k) const;
486
488 template <class JsonValue, class... FN>
489 JTx
490 jt(JsonValue&& jv, FN const&... fN)
491 {
492 JTx jt(std::forward<JsonValue>(jv));
493 invoke(jt, fN...);
494 autofill(jt);
495 jt.stx = st(jt);
496 return jt;
497 }
498
500 template <class JsonValue, class... FN>
501 JTx
502 jtnofill(JsonValue&& jv, FN const&... fN)
503 {
504 JTx jt(std::forward<JsonValue>(jv));
505 invoke(jt, fN...);
507 jt.stx = st(jt);
508 return jt;
509 }
510
514 template <class JsonValue, class... FN>
516 json(JsonValue&& jv, FN const&... fN)
517 {
518 auto tj = jt(std::forward<JsonValue>(jv), fN...);
519 return std::move(tj.jv);
520 }
521
527 template <class... Args>
528 void
529 require(Args const&... args)
530 {
531 jtx::required(args...)(*this);
532 }
533
536 static ParsedResult
537 parseResult(Json::Value const& jr);
538
542 virtual void
543 submit(JTx const& jt);
544
548 void
550
554 void
556 JTx const& jt,
557 ParsedResult const& parsed,
558 Json::Value const& jr = Json::Value());
559
562 template <class JsonValue, class... FN>
563 Env&
564 apply(JsonValue&& jv, FN const&... fN)
565 {
566 submit(jt(std::forward<JsonValue>(jv), fN...));
567 return *this;
568 }
569
570 template <class JsonValue, class... FN>
571 Env&
572 operator()(JsonValue&& jv, FN const&... fN)
573 {
574 return apply(std::forward<JsonValue>(jv), fN...);
575 }
579 TER
580 ter() const
581 {
582 return ter_;
583 }
584
594 meta();
595
608 tx() const;
609
610 void
611 enableFeature(uint256 const feature);
612
613 void
614 disableFeature(uint256 const feature);
615
616private:
617 void
618 fund(bool setDefaultRipple, STAmount const& amount, Account const& account);
619
620 void
621 fund_arg(STAmount const& amount, Account const& account)
622 {
623 fund(true, amount, account);
624 }
625
626 template <std::size_t N>
627 void
628 fund_arg(STAmount const& amount, std::array<Account, N> const& list)
629 {
630 for (auto const& account : list)
631 fund(false, amount, account);
632 }
633
634public:
661 template <class Arg, class... Args>
662 void
663 fund(STAmount const& amount, Arg const& arg, Args const&... args)
664 {
665 fund_arg(amount, arg);
666 if constexpr (sizeof...(args) > 0)
667 fund(amount, args...);
668 }
669
688 void
689 trust(STAmount const& amount, Account const& account);
690
691 template <class... Accounts>
692 void
694 STAmount const& amount,
695 Account const& to0,
696 Account const& to1,
697 Accounts const&... toN)
698 {
699 trust(amount, to0);
700 trust(amount, to1, toN...);
701 }
709 ust(JTx const& jt);
710
711protected:
712 int trace_ = 0;
717 unsigned retries_ = 5;
718
720 do_rpc(
721 unsigned apiVersion,
722 std::vector<std::string> const& args,
724
725 void
727
728 virtual void
729 autofill(JTx& jt);
730
739 st(JTx const& jt);
740
741 // Invoke funclets on stx
742 // Note: The STTx may not be modified
743 template <class... FN>
744 void
745 invoke(STTx& stx, FN const&... fN)
746 {
747 (fN(*this, stx), ...);
748 }
749
750 // Invoke funclets on jt
751 template <class... FN>
752 void
753 invoke(JTx& jt, FN const&... fN)
754 {
755 (fN(*this, jt), ...);
756 }
757
758 // Map of account IDs to Account
760};
761
762template <class... Args>
765 unsigned apiVersion,
767 std::string const& cmd,
768 Args&&... args)
769{
770 return do_rpc(
771 apiVersion,
772 std::vector<std::string>{cmd, std::forward<Args>(args)...},
773 headers);
774}
775
776template <class... Args>
778Env::rpc(unsigned apiVersion, std::string const& cmd, Args&&... args)
779{
780 return rpc(
781 apiVersion,
783 cmd,
784 std::forward<Args>(args)...);
785}
786
787template <class... Args>
791 std::string const& cmd,
792 Args&&... args)
793{
794 return do_rpc(
796 std::vector<std::string>{cmd, std::forward<Args>(args)...},
797 headers);
798}
799
800template <class... Args>
802Env::rpc(std::string const& cmd, Args&&... args)
803{
804 return rpc(
806 cmd,
807 std::forward<Args>(args)...);
808}
809
810} // namespace jtx
811} // namespace test
812} // namespace ripple
813
814#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:628
Json::Value json(JsonValue &&jv, FN const &... fN)
Create JSON from parameters.
Definition: Env.h:516
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:600
bool parseFailureExpected_
Definition: Env.h:716
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:759
void notrace()
Turn off JSON tracing.
Definition: Env.h:404
void require(Args const &... args)
Check a set of requirements.
Definition: Env.h:529
void trust(STAmount const &amount, Account const &to0, Account const &to1, Accounts const &... toN)
Definition: Env.h:693
unsigned retries() const
Definition: Env.h:431
TER ter() const
Return the TER for the last JTx.
Definition: Env.h:580
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:459
void invoke(JTx &jt, FN const &... fN)
Definition: Env.h:753
Env & operator=(Env const &)=delete
Env & operator()(JsonValue &&jv, FN const &... fN)
Definition: Env.h:572
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:391
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:353
AbstractClient & client()
Returns the connected client.
Definition: Env.h:285
void autofill_sig(JTx &jt)
Definition: Env.cpp:465
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:663
Json::Value do_rpc(unsigned apiVersion, std::vector< std::string > const &args, std::unordered_map< std::string, std::string > const &headers={})
Definition: Env.cpp:569
void invoke(STTx &stx, FN const &... fN)
Definition: Env.h:745
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:517
void enableFeature(uint256 const feature)
Definition: Env.cpp:592
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
unsigned retries_
Definition: Env.h:717
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition: Env.h:490
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:543
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:764
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:564
void disable_sigs()
Turn off signature checks.
Definition: Env.h:417
void set_retries(unsigned r=5)
Definition: Env.h:424
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:713
Application const & app() const
Definition: Env.h:261
std::shared_ptr< STObject const > meta()
Return metadata for the last JTx.
Definition: Env.cpp:451
JTx jtnofill(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition: Env.h:502
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:621
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:55
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