mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-05 09:46:53 +00:00
Merge branch 'pratik/otel-phase8-log-correlation' into pratik/otel-phase9-metric-gap-fill
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -32,20 +32,9 @@ xrpl_add_test(json)
|
||||
target_link_libraries(xrpl.test.json PRIVATE xrpl.imports.test)
|
||||
add_dependencies(xrpl.tests xrpl.test.json)
|
||||
|
||||
# protocol_autogen tests use explicit source list (not GLOB) because sources are generated
|
||||
# Mark generated sources so CMake knows they'll be created at build time
|
||||
set_source_files_properties(
|
||||
${PROTOCOL_AUTOGEN_TEST_SOURCES}
|
||||
PROPERTIES GENERATED TRUE
|
||||
)
|
||||
add_executable(xrpl.test.protocol_autogen ${PROTOCOL_AUTOGEN_TEST_SOURCES})
|
||||
xrpl_add_test(protocol_autogen)
|
||||
target_link_libraries(xrpl.test.protocol_autogen PRIVATE xrpl.imports.test)
|
||||
add_dependencies(xrpl.tests xrpl.test.protocol_autogen)
|
||||
add_test(NAME xrpl.test.protocol_autogen COMMAND xrpl.test.protocol_autogen)
|
||||
# Ensure code generation runs before compiling tests
|
||||
if(TARGET protocol_autogen_generate)
|
||||
add_dependencies(xrpl.test.protocol_autogen protocol_autogen_generate)
|
||||
endif()
|
||||
|
||||
# Network unit tests are currently not supported on Windows
|
||||
if(NOT WIN32)
|
||||
|
||||
213
src/tests/libxrpl/basics/MallocTrim.cpp
Normal file
213
src/tests/libxrpl/basics/MallocTrim.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
#include <xrpl/basics/MallocTrim.h>
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
|
||||
#include <boost/predef.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace xrpl;
|
||||
|
||||
// cSpell:ignore statm
|
||||
|
||||
#if defined(__GLIBC__) && BOOST_OS_LINUX
|
||||
namespace xrpl::detail {
|
||||
long
|
||||
parseStatmRSSkB(std::string const& statm);
|
||||
} // namespace xrpl::detail
|
||||
#endif
|
||||
|
||||
TEST(MallocTrimReport, structure)
|
||||
{
|
||||
// Test default construction
|
||||
MallocTrimReport report;
|
||||
EXPECT_EQ(report.supported, false);
|
||||
EXPECT_EQ(report.trimResult, -1);
|
||||
EXPECT_EQ(report.rssBeforeKB, -1);
|
||||
EXPECT_EQ(report.rssAfterKB, -1);
|
||||
EXPECT_EQ(report.durationUs, std::chrono::microseconds{-1});
|
||||
EXPECT_EQ(report.minfltDelta, -1);
|
||||
EXPECT_EQ(report.majfltDelta, -1);
|
||||
EXPECT_EQ(report.deltaKB(), 0);
|
||||
|
||||
// Test deltaKB calculation - memory freed
|
||||
report.rssBeforeKB = 1000;
|
||||
report.rssAfterKB = 800;
|
||||
EXPECT_EQ(report.deltaKB(), -200);
|
||||
|
||||
// Test deltaKB calculation - memory increased
|
||||
report.rssBeforeKB = 500;
|
||||
report.rssAfterKB = 600;
|
||||
EXPECT_EQ(report.deltaKB(), 100);
|
||||
|
||||
// Test deltaKB calculation - no change
|
||||
report.rssBeforeKB = 1234;
|
||||
report.rssAfterKB = 1234;
|
||||
EXPECT_EQ(report.deltaKB(), 0);
|
||||
}
|
||||
|
||||
#if defined(__GLIBC__) && BOOST_OS_LINUX
|
||||
TEST(parseStatmRSSkB, standard_format)
|
||||
{
|
||||
using xrpl::detail::parseStatmRSSkB;
|
||||
|
||||
// Test standard format: size resident shared text lib data dt
|
||||
// Assuming 4KB page size: resident=1000 pages = 4000 KB
|
||||
{
|
||||
std::string const statm = "25365 1000 2377 0 0 5623 0";
|
||||
long const result = parseStatmRSSkB(statm);
|
||||
// Note: actual result depends on system page size
|
||||
// On most systems it's 4KB, so 1000 pages = 4000 KB
|
||||
EXPECT_GT(result, 0);
|
||||
}
|
||||
|
||||
// Test with newline
|
||||
{
|
||||
std::string const statm = "12345 2000 1234 0 0 3456 0\n";
|
||||
long const result = parseStatmRSSkB(statm);
|
||||
EXPECT_GT(result, 0);
|
||||
}
|
||||
|
||||
// Test with tabs
|
||||
{
|
||||
std::string const statm = "12345\t2000\t1234\t0\t0\t3456\t0";
|
||||
long const result = parseStatmRSSkB(statm);
|
||||
EXPECT_GT(result, 0);
|
||||
}
|
||||
|
||||
// Test zero resident pages
|
||||
{
|
||||
std::string const statm = "25365 0 2377 0 0 5623 0";
|
||||
long const result = parseStatmRSSkB(statm);
|
||||
EXPECT_EQ(result, 0);
|
||||
}
|
||||
|
||||
// Test with extra whitespace
|
||||
{
|
||||
std::string const statm = " 25365 1000 2377 ";
|
||||
long const result = parseStatmRSSkB(statm);
|
||||
EXPECT_GT(result, 0);
|
||||
}
|
||||
|
||||
// Test empty string
|
||||
{
|
||||
std::string const statm;
|
||||
long const result = parseStatmRSSkB(statm);
|
||||
EXPECT_EQ(result, -1);
|
||||
}
|
||||
|
||||
// Test malformed data (only one field)
|
||||
{
|
||||
std::string const statm = "25365";
|
||||
long const result = parseStatmRSSkB(statm);
|
||||
EXPECT_EQ(result, -1);
|
||||
}
|
||||
|
||||
// Test malformed data (non-numeric)
|
||||
{
|
||||
std::string const statm = "abc def ghi";
|
||||
long const result = parseStatmRSSkB(statm);
|
||||
EXPECT_EQ(result, -1);
|
||||
}
|
||||
|
||||
// Test malformed data (second field non-numeric)
|
||||
{
|
||||
std::string const statm = "25365 abc 2377";
|
||||
long const result = parseStatmRSSkB(statm);
|
||||
EXPECT_EQ(result, -1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(mallocTrim, without_debug_logging)
|
||||
{
|
||||
beast::Journal const journal{beast::Journal::getNullSink()};
|
||||
|
||||
MallocTrimReport const report = mallocTrim("without_debug", journal);
|
||||
|
||||
#if defined(__GLIBC__) && BOOST_OS_LINUX
|
||||
EXPECT_EQ(report.supported, true);
|
||||
EXPECT_GE(report.trimResult, 0);
|
||||
EXPECT_EQ(report.durationUs, std::chrono::microseconds{-1});
|
||||
EXPECT_EQ(report.minfltDelta, -1);
|
||||
EXPECT_EQ(report.majfltDelta, -1);
|
||||
#else
|
||||
EXPECT_EQ(report.supported, false);
|
||||
EXPECT_EQ(report.trimResult, -1);
|
||||
EXPECT_EQ(report.rssBeforeKB, -1);
|
||||
EXPECT_EQ(report.rssAfterKB, -1);
|
||||
EXPECT_EQ(report.durationUs, std::chrono::microseconds{-1});
|
||||
EXPECT_EQ(report.minfltDelta, -1);
|
||||
EXPECT_EQ(report.majfltDelta, -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(mallocTrim, empty_tag)
|
||||
{
|
||||
beast::Journal const journal{beast::Journal::getNullSink()};
|
||||
MallocTrimReport const report = mallocTrim("", journal);
|
||||
|
||||
#if defined(__GLIBC__) && BOOST_OS_LINUX
|
||||
EXPECT_EQ(report.supported, true);
|
||||
EXPECT_GE(report.trimResult, 0);
|
||||
#else
|
||||
EXPECT_EQ(report.supported, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(mallocTrim, with_debug_logging)
|
||||
{
|
||||
struct DebugSink : public beast::Journal::Sink
|
||||
{
|
||||
DebugSink() : Sink(beast::severities::kDebug, false)
|
||||
{
|
||||
}
|
||||
void
|
||||
write(beast::severities::Severity, std::string const&) override
|
||||
{
|
||||
}
|
||||
void
|
||||
writeAlways(beast::severities::Severity, std::string const&) override
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
DebugSink sink;
|
||||
beast::Journal const journal{sink};
|
||||
|
||||
MallocTrimReport const report = mallocTrim("debug_test", journal);
|
||||
|
||||
#if defined(__GLIBC__) && BOOST_OS_LINUX
|
||||
EXPECT_EQ(report.supported, true);
|
||||
EXPECT_GE(report.trimResult, 0);
|
||||
EXPECT_GE(report.durationUs.count(), 0);
|
||||
EXPECT_GE(report.minfltDelta, 0);
|
||||
EXPECT_GE(report.majfltDelta, 0);
|
||||
#else
|
||||
EXPECT_EQ(report.supported, false);
|
||||
EXPECT_EQ(report.trimResult, -1);
|
||||
EXPECT_EQ(report.durationUs, std::chrono::microseconds{-1});
|
||||
EXPECT_EQ(report.minfltDelta, -1);
|
||||
EXPECT_EQ(report.majfltDelta, -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(mallocTrim, repeated_calls)
|
||||
{
|
||||
beast::Journal const journal{beast::Journal::getNullSink()};
|
||||
|
||||
// Call malloc_trim multiple times to ensure it's safe
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
MallocTrimReport const report = mallocTrim("iteration_" + std::to_string(i), journal);
|
||||
|
||||
#if defined(__GLIBC__) && BOOST_OS_LINUX
|
||||
EXPECT_EQ(report.supported, true);
|
||||
EXPECT_GE(report.trimResult, 0);
|
||||
#else
|
||||
EXPECT_EQ(report.supported, false);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace xrpl;
|
||||
@@ -183,7 +185,7 @@ TEST_F(MutexConstCorrectnessTest, non_const_allows_modification)
|
||||
|
||||
TEST_F(MutexConstCorrectnessTest, const_reference_provides_const_access)
|
||||
{
|
||||
Mutex<std::vector<int>> m({1, 2, 3, 4, 5, 6});
|
||||
Mutex<std::vector<int>> const m({1, 2, 3, 4, 5, 6});
|
||||
Mutex<std::vector<int>> const& const_ref = m;
|
||||
auto lock = const_ref.lock();
|
||||
static_assert(std::is_const_v<std::remove_reference_t<decltype(*lock)>>);
|
||||
@@ -225,7 +227,7 @@ struct MutexSharedMutexTest : ::testing::Test
|
||||
|
||||
TEST_F(MutexSharedMutexTest, shared_lock_for_const_access)
|
||||
{
|
||||
Mutex<int, std::shared_mutex> m(100);
|
||||
Mutex<int, std::shared_mutex> const m(100);
|
||||
Mutex<int, std::shared_mutex> const& const_ref = m;
|
||||
auto lock = const_ref.lock<std::shared_lock>();
|
||||
EXPECT_EQ(*lock, 100);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include <xrpl/basics/RangeSet.h>
|
||||
|
||||
#include <boost/icl/concept/interval_associator.hpp>
|
||||
#include <boost/icl/concept/interval_set.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
using namespace xrpl;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
using namespace xrpl;
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
using namespace xrpl;
|
||||
|
||||
TEST(scope, scope_exit)
|
||||
@@ -10,7 +12,7 @@ TEST(scope, scope_exit)
|
||||
// unless release() is called
|
||||
int i = 0;
|
||||
{
|
||||
scope_exit x{[&i]() { i = 1; }};
|
||||
scope_exit const x{[&i]() { i = 1; }};
|
||||
}
|
||||
EXPECT_EQ(i, 1);
|
||||
{
|
||||
@@ -32,7 +34,7 @@ TEST(scope, scope_exit)
|
||||
{
|
||||
try
|
||||
{
|
||||
scope_exit x{[&i]() { i = 5; }};
|
||||
scope_exit const x{[&i]() { i = 5; }};
|
||||
throw 1;
|
||||
}
|
||||
catch (...) // NOLINT(bugprone-empty-catch)
|
||||
@@ -60,7 +62,7 @@ TEST(scope, scope_fail)
|
||||
// if an exception is unwinding, unless release() is called
|
||||
int i = 0;
|
||||
{
|
||||
scope_fail x{[&i]() { i = 1; }};
|
||||
scope_fail const x{[&i]() { i = 1; }};
|
||||
}
|
||||
EXPECT_EQ(i, 0);
|
||||
{
|
||||
@@ -82,7 +84,7 @@ TEST(scope, scope_fail)
|
||||
{
|
||||
try
|
||||
{
|
||||
scope_fail x{[&i]() { i = 5; }};
|
||||
scope_fail const x{[&i]() { i = 5; }};
|
||||
throw 1;
|
||||
}
|
||||
catch (...) // NOLINT(bugprone-empty-catch)
|
||||
@@ -110,7 +112,7 @@ TEST(scope, scope_success)
|
||||
// if an exception is not unwinding, unless release() is called
|
||||
int i = 0;
|
||||
{
|
||||
scope_success x{[&i]() { i = 1; }};
|
||||
scope_success const x{[&i]() { i = 1; }};
|
||||
}
|
||||
EXPECT_EQ(i, 1);
|
||||
{
|
||||
@@ -132,7 +134,7 @@ TEST(scope, scope_success)
|
||||
{
|
||||
try
|
||||
{
|
||||
scope_success x{[&i]() { i = 5; }};
|
||||
scope_success const x{[&i]() { i = 5; }};
|
||||
throw 1;
|
||||
}
|
||||
catch (...) // NOLINT(bugprone-empty-catch)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
using namespace xrpl;
|
||||
@@ -21,85 +22,85 @@ using TagUInt3 = tagged_integer<std::uint64_t, Tag1>;
|
||||
|
||||
// Check construction of tagged_integers
|
||||
static_assert(
|
||||
std::is_constructible<TagUInt1, std::uint32_t>::value,
|
||||
std::is_constructible_v<TagUInt1, std::uint32_t>,
|
||||
"TagUInt1 should be constructible using a std::uint32_t");
|
||||
|
||||
static_assert(
|
||||
!std::is_constructible<TagUInt1, std::uint64_t>::value,
|
||||
!std::is_constructible_v<TagUInt1, std::uint64_t>,
|
||||
"TagUInt1 should not be constructible using a std::uint64_t");
|
||||
|
||||
static_assert(
|
||||
std::is_constructible<TagUInt3, std::uint32_t>::value,
|
||||
std::is_constructible_v<TagUInt3, std::uint32_t>,
|
||||
"TagUInt3 should be constructible using a std::uint32_t");
|
||||
|
||||
static_assert(
|
||||
std::is_constructible<TagUInt3, std::uint64_t>::value,
|
||||
std::is_constructible_v<TagUInt3, std::uint64_t>,
|
||||
"TagUInt3 should be constructible using a std::uint64_t");
|
||||
|
||||
// Check assignment of tagged_integers
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt1, std::uint32_t>::value,
|
||||
!std::is_assignable_v<TagUInt1, std::uint32_t>,
|
||||
"TagUInt1 should not be assignable with a std::uint32_t");
|
||||
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt1, std::uint64_t>::value,
|
||||
!std::is_assignable_v<TagUInt1, std::uint64_t>,
|
||||
"TagUInt1 should not be assignable with a std::uint64_t");
|
||||
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt3, std::uint32_t>::value,
|
||||
!std::is_assignable_v<TagUInt3, std::uint32_t>,
|
||||
"TagUInt3 should not be assignable with a std::uint32_t");
|
||||
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt3, std::uint64_t>::value,
|
||||
!std::is_assignable_v<TagUInt3, std::uint64_t>,
|
||||
"TagUInt3 should not be assignable with a std::uint64_t");
|
||||
|
||||
static_assert(
|
||||
std::is_assignable<TagUInt1, TagUInt1>::value,
|
||||
std::is_assignable_v<TagUInt1, TagUInt1>,
|
||||
"TagUInt1 should be assignable with a TagUInt1");
|
||||
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt1, TagUInt2>::value,
|
||||
!std::is_assignable_v<TagUInt1, TagUInt2>,
|
||||
"TagUInt1 should not be assignable with a TagUInt2");
|
||||
|
||||
static_assert(
|
||||
std::is_assignable<TagUInt3, TagUInt3>::value,
|
||||
std::is_assignable_v<TagUInt3, TagUInt3>,
|
||||
"TagUInt3 should be assignable with a TagUInt1");
|
||||
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt1, TagUInt3>::value,
|
||||
!std::is_assignable_v<TagUInt1, TagUInt3>,
|
||||
"TagUInt1 should not be assignable with a TagUInt3");
|
||||
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt3, TagUInt1>::value,
|
||||
!std::is_assignable_v<TagUInt3, TagUInt1>,
|
||||
"TagUInt3 should not be assignable with a TagUInt1");
|
||||
|
||||
// Check convertibility of tagged_integers
|
||||
static_assert(
|
||||
!std::is_convertible<std::uint32_t, TagUInt1>::value,
|
||||
!std::is_convertible_v<std::uint32_t, TagUInt1>,
|
||||
"std::uint32_t should not be convertible to a TagUInt1");
|
||||
|
||||
static_assert(
|
||||
!std::is_convertible<std::uint32_t, TagUInt3>::value,
|
||||
!std::is_convertible_v<std::uint32_t, TagUInt3>,
|
||||
"std::uint32_t should not be convertible to a TagUInt3");
|
||||
|
||||
static_assert(
|
||||
!std::is_convertible<std::uint64_t, TagUInt3>::value,
|
||||
!std::is_convertible_v<std::uint64_t, TagUInt3>,
|
||||
"std::uint64_t should not be convertible to a TagUInt3");
|
||||
|
||||
static_assert(
|
||||
!std::is_convertible<std::uint64_t, TagUInt2>::value,
|
||||
!std::is_convertible_v<std::uint64_t, TagUInt2>,
|
||||
"std::uint64_t should not be convertible to a TagUInt2");
|
||||
|
||||
static_assert(
|
||||
!std::is_convertible<TagUInt1, TagUInt2>::value,
|
||||
!std::is_convertible_v<TagUInt1, TagUInt2>,
|
||||
"TagUInt1 should not be convertible to TagUInt2");
|
||||
|
||||
static_assert(
|
||||
!std::is_convertible<TagUInt1, TagUInt3>::value,
|
||||
!std::is_convertible_v<TagUInt1, TagUInt3>,
|
||||
"TagUInt1 should not be convertible to TagUInt3");
|
||||
|
||||
static_assert(
|
||||
!std::is_convertible<TagUInt2, TagUInt3>::value,
|
||||
!std::is_convertible_v<TagUInt2, TagUInt3>,
|
||||
"TagUInt2 should not be convertible to a TagUInt3");
|
||||
|
||||
using TagInt = tagged_integer<std::int32_t, Tag1>;
|
||||
@@ -147,7 +148,7 @@ TEST(tagged_integer, increment_decrement_operators)
|
||||
|
||||
TEST(tagged_integer, arithmetic_operators)
|
||||
{
|
||||
TagInt a{-2};
|
||||
TagInt const a{-2};
|
||||
EXPECT_EQ(+a, TagInt{-2});
|
||||
EXPECT_EQ(-a, TagInt{2});
|
||||
EXPECT_EQ(TagInt{-3} + TagInt{4}, TagInt{1});
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
using namespace xrpl;
|
||||
|
||||
TEST(csprng, get_values)
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
#include <boost/predef.h>
|
||||
|
||||
#include <helpers/TestSink.h>
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
|
||||
#include <boost/predef.h>
|
||||
|
||||
#include <cstdlib> // for getenv
|
||||
#include <string>
|
||||
|
||||
#if BOOST_OS_WINDOWS
|
||||
#include <io.h> // for _isatty, _fileno
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <xrpl/json/Output.h>
|
||||
|
||||
#include <xrpl/json/json_reader.h>
|
||||
#include <xrpl/json/json_writer.h>
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <xrpl/beast/core/LexicalCast.h>
|
||||
#include <xrpl/json/json_errors.h>
|
||||
#include <xrpl/json/json_forwards.h>
|
||||
#include <xrpl/json/json_reader.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/json/json_writer.h>
|
||||
@@ -7,10 +8,15 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <limits>
|
||||
#include <numbers>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -38,7 +44,7 @@ TEST(json_value, construct_and_compare_Json_StaticString)
|
||||
EXPECT_EQ(test1, test2);
|
||||
EXPECT_NE(test1, test3);
|
||||
|
||||
std::string str{sample};
|
||||
std::string const str{sample};
|
||||
EXPECT_EQ(str, test2);
|
||||
EXPECT_NE(str, test3);
|
||||
EXPECT_EQ(test2, str);
|
||||
@@ -52,7 +58,7 @@ TEST(json_value, different_types)
|
||||
|
||||
auto testCopy = [](Json::ValueType typ) {
|
||||
Json::Value val{typ};
|
||||
Json::Value cpy{val};
|
||||
Json::Value const cpy{val};
|
||||
EXPECT_EQ(val.type(), typ);
|
||||
EXPECT_EQ(cpy.type(), typ);
|
||||
return val;
|
||||
@@ -135,7 +141,7 @@ TEST(json_value, different_types)
|
||||
{
|
||||
Json::Value const staticStrV{staticStr};
|
||||
{
|
||||
Json::Value cpy{staticStrV};
|
||||
Json::Value const cpy{staticStrV};
|
||||
EXPECT_EQ(staticStrV.type(), Json::stringValue);
|
||||
EXPECT_EQ(cpy.type(), Json::stringValue);
|
||||
}
|
||||
@@ -588,13 +594,13 @@ TEST(json_value, bad_json)
|
||||
|
||||
TEST(json_value, edge_cases)
|
||||
{
|
||||
std::uint32_t max_uint = std::numeric_limits<std::uint32_t>::max();
|
||||
std::int32_t max_int = std::numeric_limits<std::int32_t>::max();
|
||||
std::int32_t min_int = std::numeric_limits<std::int32_t>::min();
|
||||
std::uint32_t const max_uint = std::numeric_limits<std::uint32_t>::max();
|
||||
std::int32_t const max_int = std::numeric_limits<std::int32_t>::max();
|
||||
std::int32_t const min_int = std::numeric_limits<std::int32_t>::min();
|
||||
|
||||
std::uint32_t a_uint = max_uint - 1978;
|
||||
std::int32_t a_large_int = max_int - 1978;
|
||||
std::int32_t a_small_int = min_int + 1978;
|
||||
std::uint32_t const a_uint = max_uint - 1978;
|
||||
std::int32_t const a_large_int = max_int - 1978;
|
||||
std::int32_t const a_small_int = min_int + 1978;
|
||||
|
||||
{
|
||||
std::string json = "{\"max_uint\":" + std::to_string(max_uint);
|
||||
@@ -628,7 +634,7 @@ TEST(json_value, edge_cases)
|
||||
EXPECT_LT(j1["a_small_int"], a_uint);
|
||||
}
|
||||
|
||||
std::uint64_t overflow = std::uint64_t(max_uint) + 1;
|
||||
std::uint64_t const overflow = std::uint64_t(max_uint) + 1;
|
||||
{
|
||||
std::string json = "{\"overflow\":";
|
||||
json += std::to_string(overflow);
|
||||
@@ -640,7 +646,7 @@ TEST(json_value, edge_cases)
|
||||
EXPECT_FALSE(r2.parse(json, j2));
|
||||
}
|
||||
|
||||
std::int64_t underflow = std::int64_t(min_int) - 1;
|
||||
std::int64_t const underflow = std::int64_t(min_int) - 1;
|
||||
{
|
||||
std::string json = "{\"underflow\":";
|
||||
json += std::to_string(underflow);
|
||||
@@ -654,8 +660,8 @@ TEST(json_value, edge_cases)
|
||||
|
||||
{
|
||||
Json::Value intString{std::to_string(overflow)};
|
||||
EXPECT_THROW(intString.asUInt(), beast::BadLexicalCast);
|
||||
EXPECT_THROW(intString.asAbsUInt(), Json::error);
|
||||
EXPECT_THROW([&] { return intString.asUInt(); }(), beast::BadLexicalCast);
|
||||
EXPECT_THROW([&] { return intString.asAbsUInt(); }(), Json::error);
|
||||
|
||||
intString = "4294967295";
|
||||
EXPECT_EQ(intString.asUInt(), 4294967295u);
|
||||
@@ -666,17 +672,17 @@ TEST(json_value, edge_cases)
|
||||
EXPECT_EQ(intString.asAbsUInt(), 0);
|
||||
|
||||
intString = "-1";
|
||||
EXPECT_THROW(intString.asUInt(), beast::BadLexicalCast);
|
||||
EXPECT_THROW([&] { return intString.asUInt(); }(), beast::BadLexicalCast);
|
||||
EXPECT_EQ(intString.asAbsUInt(), 1);
|
||||
|
||||
intString = "-4294967295";
|
||||
EXPECT_EQ(intString.asAbsUInt(), 4294967295);
|
||||
|
||||
intString = "-4294967296";
|
||||
EXPECT_THROW(intString.asAbsUInt(), Json::error);
|
||||
EXPECT_THROW([&] { return intString.asAbsUInt(); }(), Json::error);
|
||||
|
||||
intString = "2147483648";
|
||||
EXPECT_THROW(intString.asInt(), beast::BadLexicalCast);
|
||||
EXPECT_THROW([&] { return intString.asInt(); }(), beast::BadLexicalCast);
|
||||
EXPECT_EQ(intString.asAbsUInt(), 2147483648);
|
||||
|
||||
intString = "2147483647";
|
||||
@@ -688,14 +694,14 @@ TEST(json_value, edge_cases)
|
||||
EXPECT_EQ(intString.asAbsUInt(), 2147483648LL);
|
||||
|
||||
intString = "-2147483649";
|
||||
EXPECT_THROW(intString.asInt(), beast::BadLexicalCast);
|
||||
EXPECT_THROW([&] { return intString.asInt(); }(), beast::BadLexicalCast);
|
||||
EXPECT_EQ(intString.asAbsUInt(), 2147483649);
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value intReal{4294967297.0};
|
||||
EXPECT_THROW(intReal.asUInt(), Json::error);
|
||||
EXPECT_THROW(intReal.asAbsUInt(), Json::error);
|
||||
EXPECT_THROW([&] { return intReal.asUInt(); }(), Json::error);
|
||||
EXPECT_THROW([&] { return intReal.asAbsUInt(); }(), Json::error);
|
||||
|
||||
intReal = 4294967295.0;
|
||||
EXPECT_EQ(intReal.asUInt(), 4294967295u);
|
||||
@@ -706,17 +712,17 @@ TEST(json_value, edge_cases)
|
||||
EXPECT_EQ(intReal.asAbsUInt(), 0);
|
||||
|
||||
intReal = -1.0;
|
||||
EXPECT_THROW(intReal.asUInt(), Json::error);
|
||||
EXPECT_THROW([&] { return intReal.asUInt(); }(), Json::error);
|
||||
EXPECT_EQ(intReal.asAbsUInt(), 1);
|
||||
|
||||
intReal = -4294967295.0;
|
||||
EXPECT_EQ(intReal.asAbsUInt(), 4294967295);
|
||||
|
||||
intReal = -4294967296.0;
|
||||
EXPECT_THROW(intReal.asAbsUInt(), Json::error);
|
||||
EXPECT_THROW([&] { return intReal.asAbsUInt(); }(), Json::error);
|
||||
|
||||
intReal = 2147483648.0;
|
||||
EXPECT_THROW(intReal.asInt(), Json::error);
|
||||
EXPECT_THROW([&] { return intReal.asInt(); }(), Json::error);
|
||||
EXPECT_EQ(intReal.asAbsUInt(), 2147483648);
|
||||
|
||||
intReal = 2147483647.0;
|
||||
@@ -728,7 +734,7 @@ TEST(json_value, edge_cases)
|
||||
EXPECT_EQ(intReal.asAbsUInt(), 2147483648LL);
|
||||
|
||||
intReal = -2147483649.0;
|
||||
EXPECT_THROW(intReal.asInt(), Json::error);
|
||||
EXPECT_THROW([&] { return intReal.asInt(); }(), Json::error);
|
||||
EXPECT_EQ(intReal.asAbsUInt(), 2147483649);
|
||||
}
|
||||
}
|
||||
@@ -739,7 +745,7 @@ TEST(json_value, copy)
|
||||
EXPECT_TRUE(v1.isDouble());
|
||||
EXPECT_EQ(v1.asDouble(), 2.5);
|
||||
|
||||
Json::Value v2 = v1;
|
||||
Json::Value const v2 = v1;
|
||||
EXPECT_TRUE(v1.isDouble());
|
||||
EXPECT_EQ(v1.asDouble(), 2.5);
|
||||
EXPECT_TRUE(v2.isDouble());
|
||||
@@ -819,7 +825,7 @@ TEST(json_value, comparisons)
|
||||
b["a"] = Json::Int(-1);
|
||||
testGreaterThan("negative");
|
||||
|
||||
Json::Int big = std::numeric_limits<int>::max();
|
||||
Json::Int const big = std::numeric_limits<int>::max();
|
||||
Json::UInt bigger = big;
|
||||
bigger++;
|
||||
|
||||
@@ -859,7 +865,7 @@ TEST(json_value, conversions)
|
||||
// TODO: What's the thinking here?
|
||||
{
|
||||
// null
|
||||
Json::Value val;
|
||||
Json::Value const val;
|
||||
EXPECT_TRUE(val.isNull());
|
||||
// val.asCString() should trigger an assertion failure
|
||||
EXPECT_EQ(val.asString(), "");
|
||||
@@ -880,12 +886,12 @@ TEST(json_value, conversions)
|
||||
}
|
||||
{
|
||||
// int
|
||||
Json::Value val = -1234;
|
||||
Json::Value const val = -1234;
|
||||
EXPECT_TRUE(val.isInt());
|
||||
// val.asCString() should trigger an assertion failure
|
||||
EXPECT_EQ(val.asString(), "-1234");
|
||||
EXPECT_EQ(val.asInt(), -1234);
|
||||
EXPECT_THROW(val.asUInt(), Json::error);
|
||||
EXPECT_THROW([&] { return val.asUInt(); }(), Json::error);
|
||||
EXPECT_EQ(val.asAbsUInt(), 1234u);
|
||||
EXPECT_EQ(val.asDouble(), -1234.0);
|
||||
EXPECT_TRUE(val.asBool());
|
||||
@@ -901,7 +907,7 @@ TEST(json_value, conversions)
|
||||
}
|
||||
{
|
||||
// uint
|
||||
Json::Value val = 1234U;
|
||||
Json::Value const val = 1234U;
|
||||
EXPECT_TRUE(val.isUInt());
|
||||
// val.asCString() should trigger an assertion failure
|
||||
EXPECT_EQ(val.asString(), "1234");
|
||||
@@ -922,7 +928,7 @@ TEST(json_value, conversions)
|
||||
}
|
||||
{
|
||||
// real
|
||||
Json::Value val = 2.0;
|
||||
Json::Value const val = 2.0;
|
||||
EXPECT_TRUE(val.isDouble());
|
||||
// val.asCString() should trigger an assertion failure
|
||||
EXPECT_TRUE(std::regex_match(val.asString(), std::regex("^2\\.0*$")));
|
||||
@@ -943,14 +949,14 @@ TEST(json_value, conversions)
|
||||
}
|
||||
{
|
||||
// numeric string
|
||||
Json::Value val = "54321";
|
||||
Json::Value const val = "54321";
|
||||
EXPECT_TRUE(val.isString());
|
||||
EXPECT_EQ(strcmp(val.asCString(), "54321"), 0);
|
||||
EXPECT_EQ(val.asString(), "54321");
|
||||
EXPECT_EQ(val.asInt(), 54321);
|
||||
EXPECT_EQ(val.asUInt(), 54321u);
|
||||
EXPECT_EQ(val.asAbsUInt(), 54321);
|
||||
EXPECT_THROW(val.asDouble(), Json::error);
|
||||
EXPECT_THROW([&] { return val.asDouble(); }(), Json::error);
|
||||
EXPECT_TRUE(val.asBool());
|
||||
|
||||
EXPECT_FALSE(val.isConvertibleTo(Json::nullValue));
|
||||
@@ -964,14 +970,14 @@ TEST(json_value, conversions)
|
||||
}
|
||||
{
|
||||
// non-numeric string
|
||||
Json::Value val(Json::stringValue);
|
||||
Json::Value const val(Json::stringValue);
|
||||
EXPECT_TRUE(val.isString());
|
||||
EXPECT_EQ(val.asCString(), nullptr);
|
||||
EXPECT_EQ(val.asString(), "");
|
||||
EXPECT_THROW(val.asInt(), std::exception);
|
||||
EXPECT_THROW(val.asUInt(), std::exception);
|
||||
EXPECT_THROW(val.asAbsUInt(), std::exception);
|
||||
EXPECT_THROW(val.asDouble(), std::exception);
|
||||
EXPECT_THROW([&] { return val.asInt(); }(), std::exception);
|
||||
EXPECT_THROW([&] { return val.asUInt(); }(), std::exception);
|
||||
EXPECT_THROW([&] { return val.asAbsUInt(); }(), std::exception);
|
||||
EXPECT_THROW([&] { return val.asDouble(); }(), std::exception);
|
||||
EXPECT_TRUE(val.asBool() == false);
|
||||
|
||||
EXPECT_TRUE(val.isConvertibleTo(Json::nullValue));
|
||||
@@ -985,7 +991,7 @@ TEST(json_value, conversions)
|
||||
}
|
||||
{
|
||||
// bool false
|
||||
Json::Value val = false;
|
||||
Json::Value const val = false;
|
||||
EXPECT_TRUE(val.isBool());
|
||||
// val.asCString() should trigger an assertion failure
|
||||
EXPECT_EQ(val.asString(), "false");
|
||||
@@ -1006,7 +1012,7 @@ TEST(json_value, conversions)
|
||||
}
|
||||
{
|
||||
// bool true
|
||||
Json::Value val = true;
|
||||
Json::Value const val = true;
|
||||
EXPECT_TRUE(val.isBool());
|
||||
// val.asCString() should trigger an assertion failure
|
||||
EXPECT_EQ(val.asString(), "true");
|
||||
@@ -1027,14 +1033,14 @@ TEST(json_value, conversions)
|
||||
}
|
||||
{
|
||||
// array type
|
||||
Json::Value val(Json::arrayValue);
|
||||
Json::Value const val(Json::arrayValue);
|
||||
EXPECT_TRUE(val.isArray());
|
||||
// val.asCString should trigger an assertion failure
|
||||
EXPECT_THROW(val.asString(), Json::error);
|
||||
EXPECT_THROW(val.asInt(), Json::error);
|
||||
EXPECT_THROW(val.asUInt(), Json::error);
|
||||
EXPECT_THROW(val.asAbsUInt(), Json::error);
|
||||
EXPECT_THROW(val.asDouble(), Json::error);
|
||||
EXPECT_THROW([&] { return val.asString(); }(), Json::error);
|
||||
EXPECT_THROW([&] { return val.asInt(); }(), Json::error);
|
||||
EXPECT_THROW([&] { return val.asUInt(); }(), Json::error);
|
||||
EXPECT_THROW([&] { return val.asAbsUInt(); }(), Json::error);
|
||||
EXPECT_THROW([&] { return val.asDouble(); }(), Json::error);
|
||||
EXPECT_FALSE(val.asBool()); // empty or not
|
||||
|
||||
EXPECT_TRUE(val.isConvertibleTo(Json::nullValue));
|
||||
@@ -1048,14 +1054,14 @@ TEST(json_value, conversions)
|
||||
}
|
||||
{
|
||||
// object type
|
||||
Json::Value val(Json::objectValue);
|
||||
Json::Value const val(Json::objectValue);
|
||||
EXPECT_TRUE(val.isObject());
|
||||
// val.asCString should trigger an assertion failure
|
||||
EXPECT_THROW(val.asString(), Json::error);
|
||||
EXPECT_THROW(val.asInt(), Json::error);
|
||||
EXPECT_THROW(val.asUInt(), Json::error);
|
||||
EXPECT_THROW(val.asAbsUInt(), Json::error);
|
||||
EXPECT_THROW(val.asDouble(), Json::error);
|
||||
EXPECT_THROW([&] { return val.asString(); }(), Json::error);
|
||||
EXPECT_THROW([&] { return val.asInt(); }(), Json::error);
|
||||
EXPECT_THROW([&] { return val.asUInt(); }(), Json::error);
|
||||
EXPECT_THROW([&] { return val.asAbsUInt(); }(), Json::error);
|
||||
EXPECT_THROW([&] { return val.asDouble(); }(), Json::error);
|
||||
EXPECT_FALSE(val.asBool()); // empty or not
|
||||
|
||||
EXPECT_TRUE(val.isConvertibleTo(Json::nullValue));
|
||||
@@ -1099,7 +1105,7 @@ TEST(json_value, access_members)
|
||||
EXPECT_FALSE(val.isValidIndex(0));
|
||||
EXPECT_FALSE(val.isMember("key"));
|
||||
|
||||
val = 3.14159;
|
||||
val = std::numbers::pi;
|
||||
EXPECT_EQ(val.type(), Json::realValue);
|
||||
EXPECT_EQ(val.size(), 0);
|
||||
EXPECT_FALSE(val.isValidIndex(0));
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include <xrpl/json/Writer.h>
|
||||
|
||||
#include <google/protobuf/stubs/port.h>
|
||||
#include <xrpl/json/Output.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/net/HTTPClient.h>
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/asio/co_spawn.hpp>
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
|
||||
#include <boost/asio/awaitable.hpp>
|
||||
#include <boost/asio/co_spawn.hpp> // IWYU pragma: keep
|
||||
#include <boost/asio/detached.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/socket_base.hpp>
|
||||
#include <boost/asio/use_awaitable.hpp>
|
||||
#include <boost/asio/use_future.hpp>
|
||||
#include <boost/beast/core.hpp>
|
||||
#include <boost/beast/http.hpp>
|
||||
#include <boost/beast/version.hpp>
|
||||
#include <boost/asio/use_future.hpp> // IWYU pragma: keep
|
||||
#include <boost/beast/core.hpp> // IWYU pragma: keep
|
||||
#include <boost/beast/http.hpp> // IWYU pragma: keep
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <helpers/TestSink.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <exception>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <semaphore>
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace xrpl;
|
||||
|
||||
@@ -74,7 +79,7 @@ public:
|
||||
return ioc_;
|
||||
}
|
||||
|
||||
unsigned short
|
||||
[[nodiscard]] unsigned short
|
||||
port() const
|
||||
{
|
||||
return port_;
|
||||
@@ -105,7 +110,7 @@ public:
|
||||
acceptor_.close();
|
||||
}
|
||||
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
finished() const
|
||||
{
|
||||
return finished_;
|
||||
@@ -267,7 +272,7 @@ protected:
|
||||
TEST_F(HTTPClientTest, case_insensitive_content_length)
|
||||
{
|
||||
// Test different cases of Content-Length header
|
||||
std::vector<std::string> headerCases = {
|
||||
std::vector<std::string> const headerCases = {
|
||||
"Content-Length", // Standard case
|
||||
"content-length", // Lowercase - this tests the regex icase fix
|
||||
"CONTENT-LENGTH", // Uppercase
|
||||
@@ -278,7 +283,7 @@ TEST_F(HTTPClientTest, case_insensitive_content_length)
|
||||
for (auto const& headerName : headerCases)
|
||||
{
|
||||
TestHTTPServer server;
|
||||
std::string testBody = "Hello World!";
|
||||
std::string const testBody = "Hello World!";
|
||||
server.setResponseBody(testBody);
|
||||
server.setHeader(headerName, std::to_string(testBody.size()));
|
||||
|
||||
@@ -287,7 +292,7 @@ TEST_F(HTTPClientTest, case_insensitive_content_length)
|
||||
std::string resultData;
|
||||
boost::system::error_code resultError;
|
||||
|
||||
bool testCompleted =
|
||||
bool const testCompleted =
|
||||
runHTTPTest(server, "/test", completed, resultStatus, resultData, resultError);
|
||||
// Verify results
|
||||
EXPECT_TRUE(testCompleted);
|
||||
@@ -300,7 +305,7 @@ TEST_F(HTTPClientTest, case_insensitive_content_length)
|
||||
TEST_F(HTTPClientTest, basic_http_request)
|
||||
{
|
||||
TestHTTPServer server;
|
||||
std::string testBody = "Test response body";
|
||||
std::string const testBody = "Test response body";
|
||||
server.setResponseBody(testBody);
|
||||
server.setHeader("Content-Type", "text/plain");
|
||||
|
||||
@@ -309,7 +314,7 @@ TEST_F(HTTPClientTest, basic_http_request)
|
||||
std::string resultData;
|
||||
boost::system::error_code resultError;
|
||||
|
||||
bool testCompleted =
|
||||
bool const testCompleted =
|
||||
runHTTPTest(server, "/basic", completed, resultStatus, resultData, resultError);
|
||||
|
||||
EXPECT_TRUE(testCompleted);
|
||||
@@ -329,7 +334,7 @@ TEST_F(HTTPClientTest, empty_response)
|
||||
std::string resultData;
|
||||
boost::system::error_code resultError;
|
||||
|
||||
bool testCompleted =
|
||||
bool const testCompleted =
|
||||
runHTTPTest(server, "/empty", completed, resultStatus, resultData, resultError);
|
||||
|
||||
EXPECT_TRUE(testCompleted);
|
||||
@@ -340,7 +345,7 @@ TEST_F(HTTPClientTest, empty_response)
|
||||
|
||||
TEST_F(HTTPClientTest, different_status_codes)
|
||||
{
|
||||
std::vector<unsigned int> statusCodes = {200, 404, 500};
|
||||
std::vector<unsigned int> const statusCodes = {200, 404, 500};
|
||||
|
||||
for (auto status : statusCodes)
|
||||
{
|
||||
@@ -353,7 +358,7 @@ TEST_F(HTTPClientTest, different_status_codes)
|
||||
std::string resultData;
|
||||
boost::system::error_code resultError;
|
||||
|
||||
bool testCompleted =
|
||||
bool const testCompleted =
|
||||
runHTTPTest(server, "/status", completed, resultStatus, resultData, resultError);
|
||||
|
||||
EXPECT_TRUE(testCompleted);
|
||||
|
||||
3
src/tests/libxrpl/protocol_autogen/.clang-tidy
Normal file
3
src/tests/libxrpl/protocol_autogen/.clang-tidy
Normal file
@@ -0,0 +1,3 @@
|
||||
# This disables all checks for this directory and its subdirectories
|
||||
Checks: "-*"
|
||||
InheritParentConfig: false
|
||||
@@ -1,70 +0,0 @@
|
||||
#include <xrpl/protocol/MPTAmount.h>
|
||||
#include <xrpl/protocol/MPTIssue.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol_autogen/STObjectValidation.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace xrpl {
|
||||
TEST(STObjectValidation, validate_required_field)
|
||||
{
|
||||
SOTemplate format{{sfFlags, soeREQUIRED}};
|
||||
STObject obj(sfGeneric);
|
||||
obj.setFieldU32(sfFlags, 0);
|
||||
EXPECT_TRUE(protocol_autogen::validateSTObject(obj, format));
|
||||
}
|
||||
|
||||
TEST(STObjectValidation, validate_missing_required_field)
|
||||
{
|
||||
SOTemplate format{{sfFlags, soeREQUIRED}};
|
||||
STObject obj(sfGeneric);
|
||||
EXPECT_FALSE(protocol_autogen::validateSTObject(obj, format));
|
||||
}
|
||||
|
||||
TEST(STObjectValidation, validate_optional_field)
|
||||
{
|
||||
SOTemplate format{{sfFlags, soeOPTIONAL}};
|
||||
STObject obj(sfGeneric);
|
||||
obj.setFieldU32(sfFlags, 0);
|
||||
EXPECT_TRUE(protocol_autogen::validateSTObject(obj, format));
|
||||
}
|
||||
|
||||
TEST(STObjectValidation, validate_missing_optional_field)
|
||||
{
|
||||
SOTemplate format{{sfFlags, soeOPTIONAL}};
|
||||
STObject obj(sfGeneric);
|
||||
EXPECT_TRUE(protocol_autogen::validateSTObject(obj, format));
|
||||
}
|
||||
|
||||
TEST(STObjectValidation, validate_mpt_amount_supported)
|
||||
{
|
||||
SOTemplate format{{sfAmount, soeREQUIRED, soeMPTSupported}};
|
||||
STObject obj(sfGeneric);
|
||||
obj.setFieldAmount(sfAmount, STAmount{MPTAmount{Number{1}}, MPTIssue{}});
|
||||
EXPECT_TRUE(protocol_autogen::validateSTObject(obj, format));
|
||||
}
|
||||
|
||||
TEST(STObjectValidation, validate_mpt_amount_not_supported)
|
||||
{
|
||||
SOTemplate format{{sfAmount, soeREQUIRED, soeMPTNotSupported}};
|
||||
STObject obj(sfGeneric);
|
||||
obj.setFieldAmount(sfAmount, STAmount{MPTAmount{Number{1}}, MPTIssue{}});
|
||||
EXPECT_FALSE(protocol_autogen::validateSTObject(obj, format));
|
||||
}
|
||||
|
||||
TEST(STObjectValidation, validate_mpt_issue_supported)
|
||||
{
|
||||
SOTemplate format{{sfAsset, soeREQUIRED, soeMPTSupported}};
|
||||
STObject obj(sfGeneric);
|
||||
obj.setFieldIssue(sfAsset, STIssue{sfAsset, MPTIssue{}});
|
||||
EXPECT_TRUE(protocol_autogen::validateSTObject(obj, format));
|
||||
}
|
||||
|
||||
TEST(STObjectValidation, validate_mpt_issue_not_supported)
|
||||
{
|
||||
SOTemplate format{{sfAsset, soeREQUIRED, soeMPTNotSupported}};
|
||||
STObject obj(sfGeneric);
|
||||
obj.setFieldIssue(sfAsset, STIssue{sfAsset, MPTIssue{}});
|
||||
EXPECT_FALSE(protocol_autogen::validateSTObject(obj, format));
|
||||
}
|
||||
} // namespace xrpl
|
||||
@@ -23,8 +23,10 @@ TEST(DirectoryNodeTests, BuilderSettersRoundTrip)
|
||||
auto const ownerValue = canonical_ACCOUNT();
|
||||
auto const takerPaysCurrencyValue = canonical_UINT160();
|
||||
auto const takerPaysIssuerValue = canonical_UINT160();
|
||||
auto const takerPaysMPTValue = canonical_UINT192();
|
||||
auto const takerGetsCurrencyValue = canonical_UINT160();
|
||||
auto const takerGetsIssuerValue = canonical_UINT160();
|
||||
auto const takerGetsMPTValue = canonical_UINT192();
|
||||
auto const exchangeRateValue = canonical_UINT64();
|
||||
auto const indexesValue = canonical_VECTOR256();
|
||||
auto const rootIndexValue = canonical_UINT256();
|
||||
@@ -43,8 +45,10 @@ TEST(DirectoryNodeTests, BuilderSettersRoundTrip)
|
||||
builder.setOwner(ownerValue);
|
||||
builder.setTakerPaysCurrency(takerPaysCurrencyValue);
|
||||
builder.setTakerPaysIssuer(takerPaysIssuerValue);
|
||||
builder.setTakerPaysMPT(takerPaysMPTValue);
|
||||
builder.setTakerGetsCurrency(takerGetsCurrencyValue);
|
||||
builder.setTakerGetsIssuer(takerGetsIssuerValue);
|
||||
builder.setTakerGetsMPT(takerGetsMPTValue);
|
||||
builder.setExchangeRate(exchangeRateValue);
|
||||
builder.setIndexNext(indexNextValue);
|
||||
builder.setIndexPrevious(indexPreviousValue);
|
||||
@@ -98,6 +102,14 @@ TEST(DirectoryNodeTests, BuilderSettersRoundTrip)
|
||||
EXPECT_TRUE(entry.hasTakerPaysIssuer());
|
||||
}
|
||||
|
||||
{
|
||||
auto const& expected = takerPaysMPTValue;
|
||||
auto const actualOpt = entry.getTakerPaysMPT();
|
||||
ASSERT_TRUE(actualOpt.has_value());
|
||||
expectEqualField(expected, *actualOpt, "sfTakerPaysMPT");
|
||||
EXPECT_TRUE(entry.hasTakerPaysMPT());
|
||||
}
|
||||
|
||||
{
|
||||
auto const& expected = takerGetsCurrencyValue;
|
||||
auto const actualOpt = entry.getTakerGetsCurrency();
|
||||
@@ -114,6 +126,14 @@ TEST(DirectoryNodeTests, BuilderSettersRoundTrip)
|
||||
EXPECT_TRUE(entry.hasTakerGetsIssuer());
|
||||
}
|
||||
|
||||
{
|
||||
auto const& expected = takerGetsMPTValue;
|
||||
auto const actualOpt = entry.getTakerGetsMPT();
|
||||
ASSERT_TRUE(actualOpt.has_value());
|
||||
expectEqualField(expected, *actualOpt, "sfTakerGetsMPT");
|
||||
EXPECT_TRUE(entry.hasTakerGetsMPT());
|
||||
}
|
||||
|
||||
{
|
||||
auto const& expected = exchangeRateValue;
|
||||
auto const actualOpt = entry.getExchangeRate();
|
||||
@@ -186,8 +206,10 @@ TEST(DirectoryNodeTests, BuilderFromSleRoundTrip)
|
||||
auto const ownerValue = canonical_ACCOUNT();
|
||||
auto const takerPaysCurrencyValue = canonical_UINT160();
|
||||
auto const takerPaysIssuerValue = canonical_UINT160();
|
||||
auto const takerPaysMPTValue = canonical_UINT192();
|
||||
auto const takerGetsCurrencyValue = canonical_UINT160();
|
||||
auto const takerGetsIssuerValue = canonical_UINT160();
|
||||
auto const takerGetsMPTValue = canonical_UINT192();
|
||||
auto const exchangeRateValue = canonical_UINT64();
|
||||
auto const indexesValue = canonical_VECTOR256();
|
||||
auto const rootIndexValue = canonical_UINT256();
|
||||
@@ -203,8 +225,10 @@ TEST(DirectoryNodeTests, BuilderFromSleRoundTrip)
|
||||
sle->at(sfOwner) = ownerValue;
|
||||
sle->at(sfTakerPaysCurrency) = takerPaysCurrencyValue;
|
||||
sle->at(sfTakerPaysIssuer) = takerPaysIssuerValue;
|
||||
sle->at(sfTakerPaysMPT) = takerPaysMPTValue;
|
||||
sle->at(sfTakerGetsCurrency) = takerGetsCurrencyValue;
|
||||
sle->at(sfTakerGetsIssuer) = takerGetsIssuerValue;
|
||||
sle->at(sfTakerGetsMPT) = takerGetsMPTValue;
|
||||
sle->at(sfExchangeRate) = exchangeRateValue;
|
||||
sle->at(sfIndexes) = indexesValue;
|
||||
sle->at(sfRootIndex) = rootIndexValue;
|
||||
@@ -283,6 +307,19 @@ TEST(DirectoryNodeTests, BuilderFromSleRoundTrip)
|
||||
expectEqualField(expected, *fromBuilderOpt, "sfTakerPaysIssuer");
|
||||
}
|
||||
|
||||
{
|
||||
auto const& expected = takerPaysMPTValue;
|
||||
|
||||
auto const fromSleOpt = entryFromSle.getTakerPaysMPT();
|
||||
auto const fromBuilderOpt = entryFromBuilder.getTakerPaysMPT();
|
||||
|
||||
ASSERT_TRUE(fromSleOpt.has_value());
|
||||
ASSERT_TRUE(fromBuilderOpt.has_value());
|
||||
|
||||
expectEqualField(expected, *fromSleOpt, "sfTakerPaysMPT");
|
||||
expectEqualField(expected, *fromBuilderOpt, "sfTakerPaysMPT");
|
||||
}
|
||||
|
||||
{
|
||||
auto const& expected = takerGetsCurrencyValue;
|
||||
|
||||
@@ -309,6 +346,19 @@ TEST(DirectoryNodeTests, BuilderFromSleRoundTrip)
|
||||
expectEqualField(expected, *fromBuilderOpt, "sfTakerGetsIssuer");
|
||||
}
|
||||
|
||||
{
|
||||
auto const& expected = takerGetsMPTValue;
|
||||
|
||||
auto const fromSleOpt = entryFromSle.getTakerGetsMPT();
|
||||
auto const fromBuilderOpt = entryFromBuilder.getTakerGetsMPT();
|
||||
|
||||
ASSERT_TRUE(fromSleOpt.has_value());
|
||||
ASSERT_TRUE(fromBuilderOpt.has_value());
|
||||
|
||||
expectEqualField(expected, *fromSleOpt, "sfTakerGetsMPT");
|
||||
expectEqualField(expected, *fromBuilderOpt, "sfTakerGetsMPT");
|
||||
}
|
||||
|
||||
{
|
||||
auto const& expected = exchangeRateValue;
|
||||
|
||||
@@ -462,10 +512,14 @@ TEST(DirectoryNodeTests, OptionalFieldsReturnNullopt)
|
||||
EXPECT_FALSE(entry.getTakerPaysCurrency().has_value());
|
||||
EXPECT_FALSE(entry.hasTakerPaysIssuer());
|
||||
EXPECT_FALSE(entry.getTakerPaysIssuer().has_value());
|
||||
EXPECT_FALSE(entry.hasTakerPaysMPT());
|
||||
EXPECT_FALSE(entry.getTakerPaysMPT().has_value());
|
||||
EXPECT_FALSE(entry.hasTakerGetsCurrency());
|
||||
EXPECT_FALSE(entry.getTakerGetsCurrency().has_value());
|
||||
EXPECT_FALSE(entry.hasTakerGetsIssuer());
|
||||
EXPECT_FALSE(entry.getTakerGetsIssuer().has_value());
|
||||
EXPECT_FALSE(entry.hasTakerGetsMPT());
|
||||
EXPECT_FALSE(entry.getTakerGetsMPT().has_value());
|
||||
EXPECT_FALSE(entry.hasExchangeRate());
|
||||
EXPECT_FALSE(entry.getExchangeRate().has_value());
|
||||
EXPECT_FALSE(entry.hasIndexNext());
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
106
src/tests/libxrpl/telemetry/SpanGuardFactory.cpp
Normal file
106
src/tests/libxrpl/telemetry/SpanGuardFactory.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
#include <xrpl/telemetry/SpanGuard.h>
|
||||
#include <xrpl/telemetry/SpanNames.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
using namespace xrpl;
|
||||
using namespace xrpl::telemetry;
|
||||
|
||||
TEST(SpanGuardFactory, null_guard_methods_are_safe)
|
||||
{
|
||||
auto span = SpanGuard::span(TraceCategory::Rpc, "rpc", "nonexistent");
|
||||
EXPECT_FALSE(span);
|
||||
|
||||
span.setAttribute("key", "value");
|
||||
span.setAttribute("int_key", static_cast<int64_t>(42));
|
||||
span.setAttribute("bool_key", true);
|
||||
span.setOk();
|
||||
span.setError("test");
|
||||
span.addEvent("event");
|
||||
}
|
||||
|
||||
TEST(SpanGuardFactory, category_span_returns_null_when_disabled)
|
||||
{
|
||||
auto span = SpanGuard::span(TraceCategory::Rpc, "rpc", "test");
|
||||
EXPECT_FALSE(span);
|
||||
|
||||
span.setAttribute("xrpl.rpc.command", "test");
|
||||
span.setAttribute("xrpl.rpc.status", "success");
|
||||
}
|
||||
|
||||
TEST(SpanGuardFactory, child_span_null_when_no_parent)
|
||||
{
|
||||
auto span = SpanGuard::span(TraceCategory::Rpc, "rpc", "parent");
|
||||
auto child = span.childSpan("child.test");
|
||||
EXPECT_FALSE(child);
|
||||
}
|
||||
|
||||
TEST(SpanGuardFactory, linked_span_null_when_no_context)
|
||||
{
|
||||
auto span = SpanGuard::span(TraceCategory::Rpc, "rpc", "source");
|
||||
auto linked = span.linkedSpan("linked.test");
|
||||
EXPECT_FALSE(linked);
|
||||
}
|
||||
|
||||
TEST(SpanGuardFactory, capture_context_returns_invalid_on_null)
|
||||
{
|
||||
auto span = SpanGuard::span(TraceCategory::Rpc, "rpc", "ctx");
|
||||
auto ctx = span.captureContext();
|
||||
EXPECT_FALSE(ctx.isValid());
|
||||
}
|
||||
|
||||
TEST(SpanGuardFactory, move_construction_transfers_ownership)
|
||||
{
|
||||
auto span = SpanGuard::span(TraceCategory::Rpc, "rpc", "move");
|
||||
auto moved = std::move(span);
|
||||
EXPECT_FALSE(span); // NOLINT(bugprone-use-after-move,hicpp-invalid-access-moved)
|
||||
moved.setAttribute("key", "value");
|
||||
}
|
||||
|
||||
TEST(SpanGuardFactory, record_exception_safe_on_null)
|
||||
{
|
||||
auto span = SpanGuard::span(TraceCategory::Rpc, "rpc.command", "test");
|
||||
try
|
||||
{
|
||||
throw std::runtime_error("test error");
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
span.recordException(e);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SpanGuardFactory, discard_safe_on_null)
|
||||
{
|
||||
auto span = SpanGuard::span(TraceCategory::Transactions, "tx", "process");
|
||||
span.discard();
|
||||
EXPECT_FALSE(span);
|
||||
}
|
||||
|
||||
TEST(SpanGuardFactory, consensus_close_time_attributes)
|
||||
{
|
||||
// Verify the consensus attribute pattern compiles and
|
||||
// doesn't crash with null SpanGuard.
|
||||
{
|
||||
auto span = telemetry::SpanGuard::span(
|
||||
telemetry::TraceCategory::Consensus, telemetry::seg::consensus, "accept.apply");
|
||||
span.setAttribute("xrpl.consensus.ledger.seq", static_cast<int64_t>(42));
|
||||
span.setAttribute("xrpl.consensus.close_time", static_cast<int64_t>(780000000));
|
||||
span.setAttribute("xrpl.consensus.close_time_correct", true);
|
||||
span.setAttribute("xrpl.consensus.close_resolution_ms", static_cast<int64_t>(30000));
|
||||
span.setAttribute("xrpl.consensus.state", std::string("finished"));
|
||||
span.setAttribute("xrpl.consensus.proposing", true);
|
||||
span.setAttribute("xrpl.consensus.round_time_ms", static_cast<int64_t>(3500));
|
||||
}
|
||||
{
|
||||
auto span = telemetry::SpanGuard::span(
|
||||
telemetry::TraceCategory::Consensus, telemetry::seg::consensus, "accept.apply");
|
||||
span.setAttribute("xrpl.consensus.close_time_correct", false);
|
||||
span.setAttribute("xrpl.consensus.state", std::string("moved_on"));
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <xrpl/basics/BasicConfig.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/telemetry/Telemetry.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
@@ -9,12 +10,11 @@ using namespace xrpl;
|
||||
|
||||
TEST(TelemetryConfig, setup_defaults)
|
||||
{
|
||||
telemetry::Telemetry::Setup s;
|
||||
telemetry::Telemetry::Setup const s;
|
||||
EXPECT_FALSE(s.enabled);
|
||||
EXPECT_EQ(s.serviceName, "rippled");
|
||||
EXPECT_EQ(s.serviceName, "xrpld");
|
||||
EXPECT_TRUE(s.serviceVersion.empty());
|
||||
EXPECT_TRUE(s.serviceInstanceId.empty());
|
||||
EXPECT_EQ(s.exporterType, "otlp_http");
|
||||
EXPECT_EQ(s.exporterEndpoint, "http://localhost:4318/v1/traces");
|
||||
EXPECT_FALSE(s.useTls);
|
||||
EXPECT_TRUE(s.tlsCertPath.empty());
|
||||
@@ -33,14 +33,13 @@ TEST(TelemetryConfig, setup_defaults)
|
||||
|
||||
TEST(TelemetryConfig, parse_empty_section)
|
||||
{
|
||||
Section section;
|
||||
auto setup = telemetry::setup_Telemetry(section, "nHUtest123", "2.0.0");
|
||||
Section const section;
|
||||
auto setup = telemetry::setup_Telemetry(section, "nHUtest123", "2.0.0", 0);
|
||||
|
||||
EXPECT_FALSE(setup.enabled);
|
||||
EXPECT_EQ(setup.serviceName, "rippled");
|
||||
EXPECT_EQ(setup.serviceName, "xrpld");
|
||||
EXPECT_EQ(setup.serviceVersion, "2.0.0");
|
||||
EXPECT_EQ(setup.serviceInstanceId, "nHUtest123");
|
||||
EXPECT_EQ(setup.exporterType, "otlp_http");
|
||||
EXPECT_DOUBLE_EQ(setup.samplingRatio, 1.0);
|
||||
EXPECT_TRUE(setup.traceRpc);
|
||||
EXPECT_TRUE(setup.traceTransactions);
|
||||
@@ -69,12 +68,11 @@ TEST(TelemetryConfig, parse_full_section)
|
||||
section.set("trace_peer", "1");
|
||||
section.set("trace_ledger", "0");
|
||||
|
||||
auto setup = telemetry::setup_Telemetry(section, "nHUtest123", "2.0.0");
|
||||
auto setup = telemetry::setup_Telemetry(section, "nHUtest123", "2.0.0", 1);
|
||||
|
||||
EXPECT_TRUE(setup.enabled);
|
||||
EXPECT_EQ(setup.serviceName, "my-rippled");
|
||||
EXPECT_EQ(setup.serviceInstanceId, "custom-id");
|
||||
EXPECT_EQ(setup.exporterType, "otlp_http");
|
||||
EXPECT_EQ(setup.exporterEndpoint, "http://collector:4318/v1/traces");
|
||||
EXPECT_TRUE(setup.useTls);
|
||||
EXPECT_EQ(setup.tlsCertPath, "/etc/ssl/ca.pem");
|
||||
@@ -95,7 +93,7 @@ TEST(TelemetryConfig, null_telemetry_factory)
|
||||
setup.enabled = false;
|
||||
|
||||
beast::Journal::Sink& sink = beast::Journal::getNullSink();
|
||||
beast::Journal j(sink);
|
||||
beast::Journal const j(sink);
|
||||
auto tel = telemetry::make_Telemetry(setup, j);
|
||||
EXPECT_TRUE(tel != nullptr);
|
||||
EXPECT_FALSE(tel->isEnabled());
|
||||
@@ -109,3 +107,16 @@ TEST(TelemetryConfig, null_telemetry_factory)
|
||||
tel->start();
|
||||
tel->stop();
|
||||
}
|
||||
|
||||
TEST(TelemetryConfig, sampling_ratio_clamped)
|
||||
{
|
||||
Section section;
|
||||
section.set("sampling_ratio", "2.5");
|
||||
auto setup = telemetry::setup_Telemetry(section, "nHUtest123", "2.0.0", 0);
|
||||
EXPECT_DOUBLE_EQ(setup.samplingRatio, 1.0);
|
||||
|
||||
Section section2;
|
||||
section2.set("sampling_ratio", "-0.5");
|
||||
auto setup2 = telemetry::setup_Telemetry(section2, "nHUtest123", "2.0.0", 0);
|
||||
EXPECT_DOUBLE_EQ(setup2.samplingRatio, 0.0);
|
||||
}
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
#include <xrpld/telemetry/TracingInstrumentation.h>
|
||||
|
||||
#include <xrpl/telemetry/Telemetry.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace xrpl;
|
||||
|
||||
TEST(TracingMacros, macros_with_null_telemetry)
|
||||
{
|
||||
telemetry::Telemetry::Setup setup;
|
||||
setup.enabled = false;
|
||||
beast::Journal::Sink& sink = beast::Journal::getNullSink();
|
||||
beast::Journal j(sink);
|
||||
auto tel = telemetry::make_Telemetry(setup, j);
|
||||
tel->start();
|
||||
|
||||
// Each macro should compile and execute without crashing.
|
||||
{
|
||||
XRPL_TRACE_RPC(*tel, "rpc.test.command");
|
||||
XRPL_TRACE_SET_ATTR("xrpl.rpc.command", "test");
|
||||
XRPL_TRACE_SET_ATTR("xrpl.rpc.status", "success");
|
||||
}
|
||||
{
|
||||
XRPL_TRACE_TX(*tel, "tx.test.process");
|
||||
XRPL_TRACE_SET_ATTR("xrpl.tx.hash", "abc123");
|
||||
}
|
||||
{
|
||||
XRPL_TRACE_CONSENSUS(*tel, "consensus.test");
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.mode", "Proposing");
|
||||
}
|
||||
{
|
||||
XRPL_TRACE_PEER(*tel, "peer.test");
|
||||
}
|
||||
{
|
||||
XRPL_TRACE_LEDGER(*tel, "ledger.test");
|
||||
}
|
||||
|
||||
tel->stop();
|
||||
}
|
||||
|
||||
TEST(TracingMacros, separate_scopes)
|
||||
{
|
||||
// Multiple macros in separate scopes should not collide on
|
||||
// the _xrpl_guard_ variable name.
|
||||
telemetry::Telemetry::Setup setup;
|
||||
setup.enabled = false;
|
||||
beast::Journal::Sink& sink = beast::Journal::getNullSink();
|
||||
beast::Journal j(sink);
|
||||
auto tel = telemetry::make_Telemetry(setup, j);
|
||||
|
||||
{
|
||||
XRPL_TRACE_RPC(*tel, "rpc.outer");
|
||||
}
|
||||
{
|
||||
XRPL_TRACE_TX(*tel, "tx.inner");
|
||||
}
|
||||
{
|
||||
XRPL_TRACE_CONSENSUS(*tel, "consensus.other");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TracingMacros, conditional_guards)
|
||||
{
|
||||
// NullTelemetry returns false for all shouldTrace* methods.
|
||||
// XRPL_TRACE_SET_ATTR on an empty guard must be safe.
|
||||
telemetry::Telemetry::Setup setup;
|
||||
setup.enabled = false;
|
||||
beast::Journal::Sink& sink = beast::Journal::getNullSink();
|
||||
beast::Journal j(sink);
|
||||
auto tel = telemetry::make_Telemetry(setup, j);
|
||||
|
||||
EXPECT_FALSE(tel->shouldTraceRpc());
|
||||
EXPECT_FALSE(tel->shouldTraceTransactions());
|
||||
EXPECT_FALSE(tel->shouldTraceConsensus());
|
||||
EXPECT_FALSE(tel->shouldTracePeer());
|
||||
EXPECT_FALSE(tel->shouldTraceLedger());
|
||||
|
||||
{
|
||||
XRPL_TRACE_RPC(*tel, "should.not.create");
|
||||
XRPL_TRACE_SET_ATTR("key", "value");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TracingMacros, consensus_close_time_attributes)
|
||||
{
|
||||
// Verify the consensus.accept.apply attribute pattern compiles and
|
||||
// doesn't crash with NullTelemetry. Mirrors the real instrumentation
|
||||
// in RCLConsensus::Adaptor::doAccept().
|
||||
telemetry::Telemetry::Setup setup;
|
||||
setup.enabled = false;
|
||||
beast::Journal::Sink& sink = beast::Journal::getNullSink();
|
||||
beast::Journal j(sink);
|
||||
auto tel = telemetry::make_Telemetry(setup, j);
|
||||
|
||||
{
|
||||
XRPL_TRACE_CONSENSUS(*tel, "consensus.accept.apply");
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.ledger.seq", static_cast<int64_t>(42));
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.close_time", static_cast<int64_t>(780000000));
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.close_time_correct", true);
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.close_resolution_ms", static_cast<int64_t>(30000));
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.state", std::string("finished"));
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.proposing", true);
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.round_time_ms", static_cast<int64_t>(3500));
|
||||
}
|
||||
// close_time_correct=false path (agreed to disagree)
|
||||
{
|
||||
XRPL_TRACE_CONSENSUS(*tel, "consensus.accept.apply");
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.close_time_correct", false);
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.state", std::string("moved_on"));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef XRPL_ENABLE_TELEMETRY
|
||||
|
||||
TEST(TracingMacros, span_guard_raii)
|
||||
{
|
||||
telemetry::Telemetry::Setup setup;
|
||||
setup.enabled = false;
|
||||
beast::Journal::Sink& sink = beast::Journal::getNullSink();
|
||||
beast::Journal j(sink);
|
||||
auto tel = telemetry::make_Telemetry(setup, j);
|
||||
|
||||
auto span = tel->startSpan("test.guard");
|
||||
{
|
||||
telemetry::SpanGuard guard(span);
|
||||
guard.setAttribute("key", "value");
|
||||
guard.addEvent("test_event");
|
||||
guard.setOk();
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TracingMacros, span_guard_move)
|
||||
{
|
||||
telemetry::Telemetry::Setup setup;
|
||||
setup.enabled = false;
|
||||
beast::Journal::Sink& sink = beast::Journal::getNullSink();
|
||||
beast::Journal j(sink);
|
||||
auto tel = telemetry::make_Telemetry(setup, j);
|
||||
|
||||
auto span = tel->startSpan("test.move");
|
||||
std::optional<telemetry::SpanGuard> opt;
|
||||
opt.emplace(span);
|
||||
EXPECT_TRUE(opt.has_value());
|
||||
opt.reset();
|
||||
}
|
||||
|
||||
TEST(TracingMacros, span_guard_exception)
|
||||
{
|
||||
telemetry::Telemetry::Setup setup;
|
||||
setup.enabled = false;
|
||||
beast::Journal::Sink& sink = beast::Journal::getNullSink();
|
||||
beast::Journal j(sink);
|
||||
auto tel = telemetry::make_Telemetry(setup, j);
|
||||
|
||||
auto span = tel->startSpan("test.exception");
|
||||
{
|
||||
telemetry::SpanGuard guard(span);
|
||||
try
|
||||
{
|
||||
throw std::runtime_error("test error");
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
guard.recordException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // XRPL_ENABLE_TELEMETRY
|
||||
Reference in New Issue
Block a user