rippled
Loading...
Searching...
No Matches
cluster_test.cpp
1#include <test/jtx/TestSuite.h>
2#include <test/unit_test/SuiteJournal.h>
3
4#include <xrpld/overlay/Cluster.h>
5
6#include <xrpl/basics/BasicConfig.h>
7#include <xrpl/protocol/SecretKey.h>
8
9namespace xrpl {
10namespace tests {
11
13{
15
16public:
17 cluster_test() : journal_("cluster_test", *this)
18 {
19 }
20
23 {
24 auto cluster = std::make_unique<Cluster>(journal_);
25
26 for (auto const& n : nodes)
27 cluster->update(n, "Test");
28
29 return cluster;
30 }
31
32 static PublicKey
37
38 void
40 {
41 // The servers on the network
43
44 while (network.size() != 128)
45 network.push_back(randomNode());
46
47 {
48 testcase("Membership: Empty cluster");
49
50 auto c = create({});
51
52 for (auto const& n : network)
53 BEAST_EXPECT(!c->member(n));
54 }
55
56 {
57 testcase("Membership: Non-empty cluster and none present");
58
60 while (cluster.size() != 32)
61 cluster.push_back(randomNode());
62
63 auto c = create(cluster);
64
65 for (auto const& n : network)
66 BEAST_EXPECT(!c->member(n));
67 }
68
69 {
70 testcase("Membership: Non-empty cluster and some present");
71
72 std::vector<PublicKey> cluster(network.begin(), network.begin() + 16);
73
74 while (cluster.size() != 32)
75 cluster.push_back(randomNode());
76
77 auto c = create(cluster);
78
79 for (auto const& n : cluster)
80 BEAST_EXPECT(c->member(n));
81
82 for (auto const& n : network)
83 {
84 auto found = std::find(cluster.begin(), cluster.end(), n);
85 BEAST_EXPECT(static_cast<bool>(c->member(n)) == (found != cluster.end()));
86 }
87 }
88
89 {
90 testcase("Membership: Non-empty cluster and all present");
91
92 std::vector<PublicKey> cluster(network.begin(), network.begin() + 32);
93
94 auto c = create(cluster);
95
96 for (auto const& n : cluster)
97 BEAST_EXPECT(c->member(n));
98
99 for (auto const& n : network)
100 {
101 auto found = std::find(cluster.begin(), cluster.end(), n);
102 BEAST_EXPECT(static_cast<bool>(c->member(n)) == (found != cluster.end()));
103 }
104 }
105 }
106
107 void
109 {
110 testcase("Updating");
111
112 auto c = create({});
113
114 auto const node = randomNode();
115 auto const name = toBase58(TokenType::NodePublic, node);
116 std::uint32_t const load = 0;
117 NetClock::time_point tick = {};
118
119 // Initial update
120 BEAST_EXPECT(c->update(node, "", load, tick));
121 {
122 auto member = c->member(node);
123 BEAST_EXPECT(static_cast<bool>(member));
124 BEAST_EXPECT(member->empty()); // NOLINT(bugprone-unchecked-optional-access)
125 }
126
127 // Updating too quickly: should fail
128 BEAST_EXPECT(!c->update(node, name, load, tick));
129 {
130 auto member = c->member(node);
131 BEAST_EXPECT(static_cast<bool>(member));
132 BEAST_EXPECT(member->empty()); // NOLINT(bugprone-unchecked-optional-access)
133 }
134
135 using namespace std::chrono_literals;
136
137 // Updating the name (empty updates to non-empty)
138 tick += 1s;
139 BEAST_EXPECT(c->update(node, name, load, tick));
140 {
141 auto member = c->member(node);
142 BEAST_EXPECT(static_cast<bool>(member));
143 BEAST_EXPECT(member->compare(name) == 0); // NOLINT(bugprone-unchecked-optional-access)
144 }
145
146 // Updating the name (non-empty doesn't go to empty)
147 tick += 1s;
148 BEAST_EXPECT(c->update(node, "", load, tick));
149 {
150 auto member = c->member(node);
151 BEAST_EXPECT(static_cast<bool>(member));
152 BEAST_EXPECT(member->compare(name) == 0); // NOLINT(bugprone-unchecked-optional-access)
153 }
154
155 // Updating the name (non-empty updates to new non-empty)
156 tick += 1s;
157 BEAST_EXPECT(c->update(node, "test", load, tick));
158 {
159 auto member = c->member(node);
160 BEAST_EXPECT(static_cast<bool>(member));
161 BEAST_EXPECT(
162 member->compare("test") == 0); // NOLINT(bugprone-unchecked-optional-access)
163 }
164 }
165
166 void
168 {
169 testcase("Config Load");
170
172
173 // The servers on the network
175
176 while (network.size() != 8)
177 network.push_back(randomNode());
178
179 auto format = [](PublicKey const& publicKey, char const* comment = nullptr) {
180 auto ret = toBase58(TokenType::NodePublic, publicKey);
181
182 if (comment)
183 ret += comment;
184
185 return ret;
186 };
187
188 Section s1;
189
190 // Correct (empty) configuration
191 BEAST_EXPECT(c->load(s1));
192 BEAST_EXPECT(c->size() == 0);
193
194 // Correct configuration
195 s1.append(format(network[0]));
196 s1.append(format(network[1], " "));
197 s1.append(format(network[2], " Comment"));
198 s1.append(format(network[3], " Multi Word Comment"));
199 s1.append(format(network[4], " Leading Whitespace"));
200 s1.append(format(network[5], " Trailing Whitespace "));
201 s1.append(format(network[6], " Leading & Trailing Whitespace "));
202 s1.append(format(network[7], " Leading, Trailing & Internal Whitespace "));
203
204 BEAST_EXPECT(c->load(s1));
205
206 for (auto const& n : network)
207 BEAST_EXPECT(c->member(n));
208
209 // Incorrect configurations
210 Section s2;
211 s2.append("NotAPublicKey");
212 BEAST_EXPECT(!c->load(s2));
213
214 Section s3;
215 s3.append(format(network[0], "!"));
216 BEAST_EXPECT(!c->load(s3));
217
218 Section s4;
219 s4.append(format(network[0], "! Comment"));
220 BEAST_EXPECT(!c->load(s4));
221
222 // Check if we properly terminate when we encounter
223 // a malformed or unparsable entry:
224 auto const node1 = randomNode();
225 auto const node2 = randomNode();
226
227 Section s5;
228 s5.append(format(node1, "XXX"));
229 s5.append(format(node2));
230 BEAST_EXPECT(!c->load(s5));
231 BEAST_EXPECT(!c->member(node1));
232 BEAST_EXPECT(!c->member(node2));
233 }
234
235 void
236 run() override
237 {
239 testUpdating();
241 }
242};
243
244BEAST_DEFINE_TESTSUITE(cluster, overlay, xrpl);
245
246} // namespace tests
247} // namespace xrpl
T begin(T... args)
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:150
A public key.
Definition PublicKey.h:42
Holds a collection of configuration values.
Definition BasicConfig.h:24
void append(std::vector< std::string > const &lines)
Append a set of lines to this section.
static PublicKey randomNode()
test::SuiteJournal journal_
void run() override
Runs the suite.
std::unique_ptr< Cluster > create(std::vector< PublicKey > const &nodes)
T end(T... args)
T find(T... args)
T is_same_v
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
PublicKey derivePublicKey(KeyType type, SecretKey const &sk)
Derive the public key from a secret key.
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition AccountID.cpp:92
SecretKey randomSecretKey()
Create a secret key using secure random numbers.
T push_back(T... args)
T size(T... args)