-
Notifications
You must be signed in to change notification settings - Fork 1.7k
fix: Add perf tests for escrow create and escrow finish #7789
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: ripple/smart-escrow
Are you sure you want to change the base?
Changes from 7 commits
19631a6
e70623d
1825f38
d88f7d8
d430010
3bb6904
b9df9c9
d1d3e3c
fca18f5
26f9488
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,8 @@ | |
| #include <test/jtx/Env.h> | ||
| #include <test/unit_test/SuiteJournal.h> | ||
|
|
||
| #include <xrpl/beast/insight/Event.h> | ||
| #include <xrpl/beast/insight/EventImpl.h> | ||
| #include <xrpl/ledger/AmendmentTable.h> | ||
| #include <xrpl/ledger/detail/ApplyViewBase.h> | ||
| #include <xrpl/ledger/helpers/NFTokenHelpers.h> | ||
|
|
@@ -11,13 +13,72 @@ | |
|
|
||
| #include <boost/algorithm/hex.hpp> | ||
|
|
||
| #include <algorithm> | ||
| #include <cstddef> | ||
| #include <cstdint> | ||
| #include <iterator> | ||
| #include <string> | ||
| #include <string_view> | ||
| #include <vector> | ||
|
|
||
| namespace xrpl::test { | ||
|
|
||
| /** | ||
| * Lets a test assert that the WASM execution-timing path fired and inspect the | ||
| * recorded durations, without needing a StatsD sink or a full Collector. | ||
| */ | ||
| struct RecordingEventImpl : public beast::insight::EventImpl | ||
| { | ||
| std::size_t count = 0; | ||
| value_type last{}; | ||
| value_type total{}; | ||
| value_type min{value_type::max()}; | ||
| value_type max{value_type::min()}; | ||
| std::vector<value_type> samples; | ||
|
|
||
| ~RecordingEventImpl() override | ||
| { | ||
| if (count > 0) | ||
| { | ||
| std::cout << "Mean (ms): " << meanMs() << "\n"; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Claude complained see this printed too many times for unrelated tests.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addressed. As for the resolution of the metrics, the best I can do is fake the values as milliseconds. That is pass in microseconds. StatsD is set at millisecond resolution. |
||
| } | ||
| } | ||
|
|
||
| void | ||
| notify(value_type const& value) override | ||
| { | ||
| ++count; | ||
| last = value; | ||
| total += value; | ||
| min = std::min(min, value); | ||
| max = std::max(max, value); | ||
| samples.push_back(value); | ||
| } | ||
|
|
||
| [[nodiscard]] double | ||
| meanMs() const | ||
| { | ||
| return count != 0 ? static_cast<double>(total.count()) / static_cast<double>(count) : 0.0; | ||
| } | ||
|
|
||
| [[nodiscard]] value_type | ||
| percentile(double p) const | ||
| { | ||
| if (samples.empty()) | ||
| { | ||
| return value_type{}; | ||
| } | ||
| auto sorted = samples; | ||
| std::ranges::sort(sorted); | ||
| auto rank = static_cast<std::size_t>((p / 100.0) * static_cast<double>(sorted.size())); | ||
| if (rank >= sorted.size()) | ||
| { | ||
| rank = sorted.size() - 1; | ||
| } | ||
| return sorted[rank]; | ||
| } | ||
| }; | ||
|
|
||
| struct TestLedgerDataProvider : public HostFunctions | ||
| { | ||
| jtx::Env& env; | ||
|
|
@@ -54,6 +115,7 @@ struct TestHostFunctions : public HostFunctions | |
| Bytes data; | ||
| int clock_drift = 0; | ||
| void* rt = nullptr; | ||
| std::shared_ptr<RecordingEventImpl> execTimeEvent = std::make_shared<RecordingEventImpl>(); | ||
|
|
||
| public: | ||
| TestHostFunctions(test::jtx::Env& env, int cd = 0) | ||
|
|
@@ -76,6 +138,15 @@ struct TestHostFunctions : public HostFunctions | |
| return rt; | ||
| } | ||
|
|
||
| // Return an Event backed by our recording impl so a test can assert that | ||
| // the WASM execution was timed. The name is ignored -- every call records | ||
| // into the same impl. | ||
| [[nodiscard]] beast::insight::Event | ||
| executionTimeEvent(std::string_view name) const override | ||
| { | ||
| return beast::insight::Event(execTimeEvent); | ||
| } | ||
|
|
||
| Expected<std::uint32_t, HostFunctionError> | ||
| getLedgerSqn() const override | ||
| { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a surprise to me too, but the caller in EscrowCreate.cpp is a mock. So it doesn't have the real impl of
executionTimeEvent.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That does seem a bit intentional?