rippled
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 <ripple/app/misc/NetworkOPs.h>
21 #include <ripple/beast/unit_test.h>
22 #include <ripple/core/ConfigSections.h>
23 #include <ripple/protocol/jss.h>
24 #include <test/jtx.h>
25 
26 #include <boost/format.hpp>
27 
28 namespace ripple {
29 
30 namespace test {
31 
32 namespace validator_data {
33 static auto const public_key =
34  "nHBt9fsb4849WmZiCds4r5TXyBeQjqnH5kzPtqgMAQMgi39YZRPa";
35 
36 static 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 
47 class ServerInfo_test : public beast::unit_test::suite
48 {
49 public:
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]
62 ip = 0.0.0.0
63 port = 50051
64 
65 [port_admin]
66 ip = 0.0.0.0
67 port = 50052
68 protocol = wss2
69 admin = 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 
202  // test providing the same hash
203  {
204  Env env(*this);
205  auto const firstResult = env.rpc("server_definitions");
206  auto const hash = firstResult[jss::result][jss::hash].asString();
207  auto const hashParam =
208  std::string("{ ") + "\"hash\": \"" + hash + "\"}";
209 
210  auto const result =
211  env.rpc("json", "server_definitions", hashParam);
212  BEAST_EXPECT(!result[jss::result].isMember(jss::error));
213  BEAST_EXPECT(result[jss::result][jss::status] == "success");
214  BEAST_EXPECT(!result[jss::result].isMember(jss::FIELDS));
215  BEAST_EXPECT(
216  !result[jss::result].isMember(jss::LEDGER_ENTRY_TYPES));
217  BEAST_EXPECT(
218  !result[jss::result].isMember(jss::TRANSACTION_RESULTS));
219  BEAST_EXPECT(!result[jss::result].isMember(jss::TRANSACTION_TYPES));
220  BEAST_EXPECT(!result[jss::result].isMember(jss::TYPES));
221  BEAST_EXPECT(result[jss::result].isMember(jss::hash));
222  }
223 
224  // test providing a different hash
225  {
226  Env env(*this);
227  std::string const hash =
228  "54296160385A27154BFA70A239DD8E8FD4CC2DB7BA32D970BA3A5B132CF749"
229  "D1";
230  auto const hashParam =
231  std::string("{ ") + "\"hash\": \"" + hash + "\"}";
232 
233  auto const result =
234  env.rpc("json", "server_definitions", hashParam);
235  BEAST_EXPECT(!result[jss::result].isMember(jss::error));
236  BEAST_EXPECT(result[jss::result][jss::status] == "success");
237  BEAST_EXPECT(result[jss::result].isMember(jss::FIELDS));
238  BEAST_EXPECT(result[jss::result].isMember(jss::LEDGER_ENTRY_TYPES));
239  BEAST_EXPECT(
240  result[jss::result].isMember(jss::TRANSACTION_RESULTS));
241  BEAST_EXPECT(result[jss::result].isMember(jss::TRANSACTION_TYPES));
242  BEAST_EXPECT(result[jss::result].isMember(jss::TYPES));
243  BEAST_EXPECT(result[jss::result].isMember(jss::hash));
244  }
245  }
246 
247  void
248  run() override
249  {
250  testServerInfo();
252  }
253 };
254 
255 BEAST_DEFINE_TESTSUITE(ServerInfo, app, ripple);
256 
257 } // namespace test
258 } // namespace ripple
ripple::test::ServerInfo_test::testServerDefinitions
void testServerDefinitions()
Definition: ServerInfo_test.cpp:155
ripple::NetworkOPs::getServerInfo
virtual Json::Value getServerInfo(bool human, bool admin, bool counters)=0
std::string
STL class.
ripple::test::jtx::Env::rpc
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:711
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:241
ripple::test::validator_data::public_key
static const auto public_key
Definition: ServerInfo_test.cpp:33
ripple::test::validator_data::token
static const auto token
Definition: ServerInfo_test.cpp:36
ripple::test::ServerInfo_test::makeValidatorConfig
static std::unique_ptr< Config > makeValidatorConfig()
Definition: ServerInfo_test.cpp:51
ripple::Application::getOPs
virtual NetworkOPs & getOPs()=0
ripple::test::ServerInfo_test::run
void run() override
Definition: ServerInfo_test.cpp:248
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::ServerInfo_test
Definition: ServerInfo_test.cpp:47
std::unique_ptr
STL class.
ripple::test::setupConfigForUnitTests
void setupConfigForUnitTests(Config &config)
initializes a config object for use with jtx::Env
Definition: envconfig.cpp:38
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:116
ripple::test::ServerInfo_test::testServerInfo
void testServerInfo()
Definition: ServerInfo_test.cpp:81
Json::Value::asString
std::string asString() const
Returns the unquoted string value.
Definition: json_value.cpp:469
ripple::test::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(DeliverMin, app, ripple)