xrpld
Loading...
Searching...
No Matches
traffic_count_test.cpp
1#include <xrpld/overlay/detail/TrafficCount.h>
2
3#include <xrpl/beast/unit_test/suite.h>
4
5#include <xrpl.pb.h>
6
7#include <algorithm>
8#include <cstddef>
9#include <cstdint>
10
11namespace xrpl::test {
12
14{
15public:
16 traffic_count_test() = default;
17
18 void
20 {
21 testcase("categorize");
22 protocol::TMPing message;
23 message.set_type(protocol::TMPing::ptPING);
24
25 // a known message is categorized to a proper category
26 auto const known = TrafficCount::categorize(message, protocol::mtPING, false);
27 BEAST_EXPECT(known == TrafficCount::Category::Base);
28
29 // cluster messages have a category of their own, in both directions; the same lookup
30 // serves outbound traffic, so a missing entry would hide them from a node's report
31 // whichever way they traveled
32 BEAST_EXPECT(
33 TrafficCount::categorize(message, protocol::mtCLUSTER, true) ==
35 BEAST_EXPECT(
36 TrafficCount::categorize(message, protocol::mtCLUSTER, false) ==
38
39 // an unknown message type is categorized as unknown
40 auto const unknown =
41 TrafficCount::categorize(message, static_cast<protocol::MessageType>(99), false);
42 BEAST_EXPECT(unknown == TrafficCount::Category::Unknown);
43 }
44
45 void
47 {
48 testcase("attribute");
49
50 auto const outsider = TrafficCount::IsFromCluster::No;
51 auto const member = TrafficCount::IsFromCluster::Yes;
52
53 // Cluster is read as traffic between configured cluster members, and any
54 // peer can send that type, so a sender outside the cluster is held to
55 // unknown rather than counted as one.
56 BEAST_EXPECT(
59 BEAST_EXPECT(
62
63 // Every other category is derived from the message alone, so membership
64 // does not enter into it either way. Base is the first category and
65 // Unknown the last, so the walk covers all of them.
66 for (auto i = static_cast<std::size_t>(TrafficCount::Category::Base);
67 i <= static_cast<std::size_t>(TrafficCount::Category::Unknown);
68 ++i)
69 {
70 auto const cat = static_cast<TrafficCount::Category>(i);
72 continue;
73
74 BEAST_EXPECT(TrafficCount::attribute(cat, outsider) == cat);
75 BEAST_EXPECT(TrafficCount::attribute(cat, member) == cat);
76 }
77 }
78
90
91 void
93 {
94 auto run = [&](TestCase const& tc) {
95 testcase(tc.name);
96 TrafficCount traffic;
97
98 auto const counts = traffic.getCounts();
99 std::ranges::for_each(counts, [&](auto const& pair) {
100 for (auto i = 0; i < tc.messageCount; ++i)
101 traffic.addCount(pair.first, tc.inbound, tc.size);
102 });
103
104 auto const countsNew = traffic.getCounts();
105 std::ranges::for_each(countsNew, [&](auto const& pair) {
106 BEAST_EXPECT(pair.second.bytesIn.load() == tc.expectedBytesIn);
107 BEAST_EXPECT(pair.second.bytesOut.load() == tc.expectedBytesOut);
108 BEAST_EXPECT(pair.second.messagesIn.load() == tc.expectedMessagesIn);
109 BEAST_EXPECT(pair.second.messagesOut.load() == tc.expectedMessagesOut);
110 });
111 };
112
113 auto const testcases = {
114 TestCase{
115 .name = "zero-counts",
116 .size = 0,
117 .inbound = false,
118 .messageCount = 0,
119 .expectedBytesIn = 0,
120 .expectedBytesOut = 0,
121 .expectedMessagesIn = 0,
122 .expectedMessagesOut = 0,
123 },
124 TestCase{
125 .name = "inbound-counts",
126 .size = 10,
127 .inbound = true,
128 .messageCount = 10,
129 .expectedBytesIn = 100,
130 .expectedBytesOut = 0,
131 .expectedMessagesIn = 10,
132 .expectedMessagesOut = 0,
133 },
134 TestCase{
135 .name = "outbound-counts",
136 .size = 10,
137 .inbound = false,
138 .messageCount = 10,
139 .expectedBytesIn = 0,
140 .expectedBytesOut = 100,
141 .expectedMessagesIn = 0,
142 .expectedMessagesOut = 10,
143 },
144 };
145
146 for (auto const& tc : testcases)
147 run(tc);
148 }
149
150 void
152 {
153 testcase("category-to-string");
154
155 // known category returns known string value
157
158 // return "unknown" for unknown categories
159 BEAST_EXPECT(
160 TrafficCount::toString(static_cast<TrafficCount::Category>(1000)) == "unknown");
161 }
162
163 void
164 run() override
165 {
168 testAddCount();
169 testToString();
170 }
171};
172
173BEAST_DEFINE_TESTSUITE(traffic_count, overlay, xrpl);
174
175} // namespace xrpl::test
A testsuite class.
Definition suite.h:52
TestcaseT testcase
Memberspace for declaring test cases.
Definition suite.h:155
TrafficCount is used to count ingress and egress wire bytes and number of messages.
static Category attribute(Category cat, IsFromCluster isFromCluster)
Limits a category to what the sender can report.
static Category categorize(::google::protobuf::Message const &message, protocol::MessageType type, bool inbound)
Given a protocol message, determine which traffic category it belongs to.
auto const & getCounts() const
An up-to-date copy of all the counters.
void addCount(Category cat, bool inbound, int bytes)
Account for traffic associated with the given category.
static std::string toString(Category cat)
void run() override
Runs the suite.
T for_each(T... args)
BEAST_DEFINE_TESTSUITE(AMMClawback, app, xrpl)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5