rippled
Loading...
Searching...
No Matches
ServerInfo_test.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012-2016 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#include <test/jtx.h>
21#include <xrpld/app/misc/NetworkOPs.h>
22#include <xrpld/core/ConfigSections.h>
23#include <xrpl/beast/unit_test.h>
24#include <xrpl/protocol/jss.h>
25
26#include <boost/format.hpp>
27
28namespace ripple {
29
30namespace test {
31
32namespace validator_data {
33static auto const public_key =
34 "nHBt9fsb4849WmZiCds4r5TXyBeQjqnH5kzPtqgMAQMgi39YZRPa";
35
36static auto const token =
37 "eyJ2YWxpZGF0aW9uX3NlY3JldF9rZXkiOiI5ZWQ0NWY4NjYyNDFjYzE4YTI3NDdiNT\n"
38 "QzODdjMDYyNTkwNzk3MmY0ZTcxOTAyMzFmYWE5Mzc0NTdmYTlkYWY2IiwibWFuaWZl\n"
39 "c3QiOiJKQUFBQUFGeEllMUZ0d21pbXZHdEgyaUNjTUpxQzlnVkZLaWxHZncxL3ZDeE\n"
40 "hYWExwbGMyR25NaEFrRTFhZ3FYeEJ3RHdEYklENk9NU1l1TTBGREFscEFnTms4U0tG\n"
41 "bjdNTzJmZGtjd1JRSWhBT25ndTlzQUtxWFlvdUorbDJWMFcrc0FPa1ZCK1pSUzZQU2\n"
42 "hsSkFmVXNYZkFpQnNWSkdlc2FhZE9KYy9hQVpva1MxdnltR21WcmxIUEtXWDNZeXd1\n"
43 "NmluOEhBU1FLUHVnQkQ2N2tNYVJGR3ZtcEFUSGxHS0pkdkRGbFdQWXk1QXFEZWRGdj\n"
44 "VUSmEydzBpMjFlcTNNWXl3TFZKWm5GT3I3QzBrdzJBaVR6U0NqSXpkaXRROD0ifQ==\n";
45} // namespace validator_data
46
48{
49public:
52 {
53 auto p = std::make_unique<Config>();
54 boost::format toLoad(R"rippleConfig(
55[validator_token]
56%1%
57
58[validators]
59%2%
60
61[port_grpc]
62ip = 0.0.0.0
63port = 50051
64
65[port_admin]
66ip = 0.0.0.0
67port = 50052
68protocol = wss2
69admin = 127.0.0.1
70)rippleConfig");
71
72 p->loadFromString(boost::str(
74
76
77 return p;
78 }
79
80 void
82 {
83 testcase("server_info");
84
85 using namespace test::jtx;
86
87 {
88 Env env(*this);
89 auto const result = env.rpc("server_info");
90 BEAST_EXPECT(!result[jss::result].isMember(jss::error));
91 BEAST_EXPECT(result[jss::result][jss::status] == "success");
92 BEAST_EXPECT(result[jss::result].isMember(jss::info));
93 }
94
95 {
96 Env env(*this);
97
98 // Call NetworkOPs directly and set the admin flag to false.
99 // Expect that the admin ports are not included in the result.
100 auto const result =
101 env.app().getOPs().getServerInfo(true, false, 0);
102 auto const& ports = result[jss::ports];
103 BEAST_EXPECT(ports.isArray() && ports.size() == 0);
104 }
105
106 {
107 auto config = makeValidatorConfig();
108 auto const rpc_port =
109 (*config)["port_rpc"].get<unsigned int>("port");
110 auto const grpc_port =
111 (*config)[SECTION_PORT_GRPC].get<unsigned int>("port");
112 auto const ws_port = (*config)["port_ws"].get<unsigned int>("port");
113 BEAST_EXPECT(grpc_port);
114 BEAST_EXPECT(rpc_port);
115 BEAST_EXPECT(ws_port);
116
117 Env env(*this, std::move(config));
118 auto const result = env.rpc("server_info");
119 BEAST_EXPECT(!result[jss::result].isMember(jss::error));
120 BEAST_EXPECT(result[jss::result][jss::status] == "success");
121 BEAST_EXPECT(result[jss::result].isMember(jss::info));
122 BEAST_EXPECT(
123 result[jss::result][jss::info][jss::pubkey_validator] ==
125
126 auto const& ports = result[jss::result][jss::info][jss::ports];
127 BEAST_EXPECT(ports.isArray() && ports.size() == 3);
128 for (auto const& port : ports)
129 {
130 auto const& proto = port[jss::protocol];
131 BEAST_EXPECT(proto.isArray());
132 auto const p = port[jss::port].asUInt();
133 BEAST_EXPECT(p == rpc_port || p == ws_port || p == grpc_port);
134 if (p == grpc_port)
135 {
136 BEAST_EXPECT(proto.size() == 1);
137 BEAST_EXPECT(proto[0u].asString() == "grpc");
138 }
139 if (p == rpc_port)
140 {
141 BEAST_EXPECT(proto.size() == 2);
142 BEAST_EXPECT(proto[0u].asString() == "http");
143 BEAST_EXPECT(proto[1u].asString() == "ws2");
144 }
145 if (p == ws_port)
146 {
147 BEAST_EXPECT(proto.size() == 1);
148 BEAST_EXPECT(proto[0u].asString() == "ws");
149 }
150 }
151 }
152 }
153
154 void
156 {
157 testcase("server_definitions");
158
159 using namespace test::jtx;
160
161 {
162 Env env(*this);
163 auto const result = env.rpc("server_definitions");
164 BEAST_EXPECT(!result[jss::result].isMember(jss::error));
165 BEAST_EXPECT(result[jss::result][jss::status] == "success");
166 BEAST_EXPECT(result[jss::result].isMember(jss::FIELDS));
167 BEAST_EXPECT(result[jss::result].isMember(jss::LEDGER_ENTRY_TYPES));
168 BEAST_EXPECT(
169 result[jss::result].isMember(jss::TRANSACTION_RESULTS));
170 BEAST_EXPECT(result[jss::result].isMember(jss::TRANSACTION_TYPES));
171 BEAST_EXPECT(result[jss::result].isMember(jss::TYPES));
172 BEAST_EXPECT(result[jss::result].isMember(jss::hash));
173
174 // test a random element of each result
175 // (testing the whole output would be difficult to maintain)
176
177 {
178 auto const firstField = result[jss::result][jss::FIELDS][0u];
179 BEAST_EXPECT(firstField[0u].asString() == "Generic");
180 BEAST_EXPECT(
181 firstField[1][jss::isSerialized].asBool() == false);
182 BEAST_EXPECT(
183 firstField[1][jss::isSigningField].asBool() == false);
184 BEAST_EXPECT(firstField[1][jss::isVLEncoded].asBool() == false);
185 BEAST_EXPECT(firstField[1][jss::nth].asUInt() == 0);
186 BEAST_EXPECT(firstField[1][jss::type].asString() == "Unknown");
187 }
188
189 BEAST_EXPECT(
190 result[jss::result][jss::LEDGER_ENTRY_TYPES]["AccountRoot"]
191 .asUInt() == 97);
192 BEAST_EXPECT(
193 result[jss::result][jss::TRANSACTION_RESULTS]["tecDIR_FULL"]
194 .asUInt() == 121);
195 BEAST_EXPECT(
196 result[jss::result][jss::TRANSACTION_TYPES]["Payment"]
197 .asUInt() == 0);
198 BEAST_EXPECT(
199 result[jss::result][jss::TYPES]["AccountID"].asUInt() == 8);
200
201 // check exception SFields
202 {
203 auto const fieldExists = [&](std::string name) {
204 for (auto& field : result[jss::result][jss::FIELDS])
205 {
206 if (field[0u].asString() == name)
207 {
208 return true;
209 }
210 }
211 return false;
212 };
213 BEAST_EXPECT(fieldExists("Generic"));
214 BEAST_EXPECT(fieldExists("Invalid"));
215 BEAST_EXPECT(fieldExists("ObjectEndMarker"));
216 BEAST_EXPECT(fieldExists("ArrayEndMarker"));
217 BEAST_EXPECT(fieldExists("taker_gets_funded"));
218 BEAST_EXPECT(fieldExists("taker_pays_funded"));
219 BEAST_EXPECT(fieldExists("hash"));
220 BEAST_EXPECT(fieldExists("index"));
221 }
222
223 // test that base_uint types are replaced with "Hash" prefix
224 {
225 auto const types = result[jss::result][jss::TYPES];
226 BEAST_EXPECT(types["Hash128"].asUInt() == 4);
227 BEAST_EXPECT(types["Hash160"].asUInt() == 17);
228 BEAST_EXPECT(types["Hash192"].asUInt() == 21);
229 BEAST_EXPECT(types["Hash256"].asUInt() == 5);
230 BEAST_EXPECT(types["Hash384"].asUInt() == 22);
231 BEAST_EXPECT(types["Hash512"].asUInt() == 23);
232 }
233 }
234
235 // test providing the same hash
236 {
237 Env env(*this);
238 auto const firstResult = env.rpc("server_definitions");
239 auto const hash = firstResult[jss::result][jss::hash].asString();
240 auto const hashParam =
241 std::string("{ ") + "\"hash\": \"" + hash + "\"}";
242
243 auto const result =
244 env.rpc("json", "server_definitions", hashParam);
245 BEAST_EXPECT(!result[jss::result].isMember(jss::error));
246 BEAST_EXPECT(result[jss::result][jss::status] == "success");
247 BEAST_EXPECT(!result[jss::result].isMember(jss::FIELDS));
248 BEAST_EXPECT(
249 !result[jss::result].isMember(jss::LEDGER_ENTRY_TYPES));
250 BEAST_EXPECT(
251 !result[jss::result].isMember(jss::TRANSACTION_RESULTS));
252 BEAST_EXPECT(!result[jss::result].isMember(jss::TRANSACTION_TYPES));
253 BEAST_EXPECT(!result[jss::result].isMember(jss::TYPES));
254 BEAST_EXPECT(result[jss::result].isMember(jss::hash));
255 }
256
257 // test providing a different hash
258 {
259 Env env(*this);
260 std::string const hash =
261 "54296160385A27154BFA70A239DD8E8FD4CC2DB7BA32D970BA3A5B132CF749"
262 "D1";
263 auto const hashParam =
264 std::string("{ ") + "\"hash\": \"" + hash + "\"}";
265
266 auto const result =
267 env.rpc("json", "server_definitions", hashParam);
268 BEAST_EXPECT(!result[jss::result].isMember(jss::error));
269 BEAST_EXPECT(result[jss::result][jss::status] == "success");
270 BEAST_EXPECT(result[jss::result].isMember(jss::FIELDS));
271 BEAST_EXPECT(result[jss::result].isMember(jss::LEDGER_ENTRY_TYPES));
272 BEAST_EXPECT(
273 result[jss::result].isMember(jss::TRANSACTION_RESULTS));
274 BEAST_EXPECT(result[jss::result].isMember(jss::TRANSACTION_TYPES));
275 BEAST_EXPECT(result[jss::result].isMember(jss::TYPES));
276 BEAST_EXPECT(result[jss::result].isMember(jss::hash));
277 }
278 }
279
280 void
281 run() override
282 {
285 }
286};
287
288BEAST_DEFINE_TESTSUITE(ServerInfo, app, ripple);
289
290} // namespace test
291} // namespace ripple
std::string asString() const
Returns the unquoted string value.
Definition: json_value.cpp:469
A testsuite class.
Definition: suite.h:53
testcase_t testcase
Memberspace for declaring test cases.
Definition: suite.h:153
virtual NetworkOPs & getOPs()=0
virtual Json::Value getServerInfo(bool human, bool admin, bool counters)=0
void run() override
Runs the suite.
static std::unique_ptr< Config > makeValidatorConfig()
A transaction testing environment.
Definition: Env.h:117
Application & app()
Definition: Env.h:255
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:749
void setupConfigForUnitTests(Config &config)
initializes a config object for use with jtx::Env
Definition: envconfig.cpp:38
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26