rippled
Version_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012-2017 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/protocol/jss.h>
21 #include <ripple/rpc/impl/RPCHelpers.h>
22 #include <test/jtx.h>
23 
24 namespace ripple {
25 
26 class Version_test : public beast::unit_test::suite
27 {
28  void
30  {
31  testcase("right api_version: explicitly specified or filled by parser");
32 
33  using namespace test::jtx;
34  Env env{*this};
35 
36  auto isCorrectReply = [](Json::Value const& re) -> bool {
37  if (re.isMember(jss::error))
38  return false;
39  return re.isMember(jss::version);
40  };
41 
42  auto jrr = env.rpc(
43  "json",
44  "version",
45  "{\"api_version\": " +
47  "}")[jss::result];
48  BEAST_EXPECT(isCorrectReply(jrr));
49 
50  jrr = env.rpc("version")[jss::result];
51  BEAST_EXPECT(isCorrectReply(jrr));
52  }
53 
54  void
56  {
57  testcase("wrong api_version: too low, too high, or wrong format");
58 
59  using namespace test::jtx;
60  Env env{*this};
61 
62  auto badVersion = [](Json::Value const& re) -> bool {
63  if (re.isMember("error_what"))
64  if (re["error_what"].isString())
65  {
66  return re["error_what"].asString().find(
67  jss::invalid_API_version.c_str()) == 0;
68  }
69  return false;
70  };
71 
72  auto re = env.rpc(
73  "json",
74  "version",
75  "{\"api_version\": " +
77  BEAST_EXPECT(badVersion(re));
78 
79  BEAST_EXPECT(env.app().config().BETA_RPC_API);
80  re = env.rpc(
81  "json",
82  "version",
83  "{\"api_version\": " +
85  std::max(
87  1) +
88  "}");
89  BEAST_EXPECT(badVersion(re));
90 
91  re = env.rpc("json", "version", "{\"api_version\": \"a\"}");
92  BEAST_EXPECT(badVersion(re));
93  }
94 
95  void
97  {
98  testcase("test getAPIVersionNumber function");
99 
100  unsigned int versionIfUnspecified =
104 
107  BEAST_EXPECT(
108  RPC::getAPIVersionNumber(j_array, false) == versionIfUnspecified);
109  BEAST_EXPECT(
110  RPC::getAPIVersionNumber(j_null, false) == versionIfUnspecified);
111 
113  BEAST_EXPECT(
114  RPC::getAPIVersionNumber(j_object, false) == versionIfUnspecified);
115  j_object[jss::api_version] = RPC::apiVersionIfUnspecified;
116  BEAST_EXPECT(
117  RPC::getAPIVersionNumber(j_object, false) == versionIfUnspecified);
118 
119  j_object[jss::api_version] = RPC::apiMinimumSupportedVersion;
120  BEAST_EXPECT(
121  RPC::getAPIVersionNumber(j_object, false) ==
123  j_object[jss::api_version] = RPC::apiMaximumSupportedVersion;
124  BEAST_EXPECT(
125  RPC::getAPIVersionNumber(j_object, false) ==
127 
128  j_object[jss::api_version] = RPC::apiMinimumSupportedVersion - 1;
129  BEAST_EXPECT(
130  RPC::getAPIVersionNumber(j_object, false) ==
132  j_object[jss::api_version] = RPC::apiMaximumSupportedVersion + 1;
133  BEAST_EXPECT(
134  RPC::getAPIVersionNumber(j_object, false) ==
136  j_object[jss::api_version] = RPC::apiBetaVersion;
137  BEAST_EXPECT(
138  RPC::getAPIVersionNumber(j_object, true) == RPC::apiBetaVersion);
139  j_object[jss::api_version] = RPC::apiBetaVersion + 1;
140  BEAST_EXPECT(
142 
143  j_object[jss::api_version] = RPC::apiInvalidVersion;
144  BEAST_EXPECT(
145  RPC::getAPIVersionNumber(j_object, false) ==
147  j_object[jss::api_version] = "a";
148  BEAST_EXPECT(
149  RPC::getAPIVersionNumber(j_object, false) ==
151  }
152 
153  void
155  {
156  testcase("batch, all good request");
157 
158  using namespace test::jtx;
159  Env env{*this};
160 
161  auto const without_api_verion = std::string("{ ") +
162  "\"jsonrpc\": \"2.0\", "
163  "\"ripplerpc\": \"2.0\", "
164  "\"id\": 5, "
165  "\"method\": \"version\", "
166  "\"params\": {}}";
167  auto const with_api_verion = std::string("{ ") +
168  "\"jsonrpc\": \"2.0\", "
169  "\"ripplerpc\": \"2.0\", "
170  "\"id\": 6, "
171  "\"method\": \"version\", "
172  "\"params\": { "
173  "\"api_version\": " +
175  auto re = env.rpc(
176  "json2", '[' + without_api_verion + ", " + with_api_verion + ']');
177 
178  if (!BEAST_EXPECT(re.isArray()))
179  return;
180  if (!BEAST_EXPECT(re.size() == 2))
181  return;
182  BEAST_EXPECT(
183  re[0u].isMember(jss::result) &&
184  re[0u][jss::result].isMember(jss::version));
185  BEAST_EXPECT(
186  re[1u].isMember(jss::result) &&
187  re[1u][jss::result].isMember(jss::version));
188  }
189 
190  void
192  {
193  testcase("batch, with a bad request");
194 
195  using namespace test::jtx;
196  Env env{*this};
197 
198  BEAST_EXPECT(env.app().config().BETA_RPC_API);
199  auto const without_api_verion = std::string("{ ") +
200  "\"jsonrpc\": \"2.0\", "
201  "\"ripplerpc\": \"2.0\", "
202  "\"id\": 5, "
203  "\"method\": \"version\", "
204  "\"params\": {}}";
205  auto const with_wrong_api_verion =
206  std::string("{ ") +
207  "\"jsonrpc\": \"2.0\", "
208  "\"ripplerpc\": \"2.0\", "
209  "\"id\": 6, "
210  "\"method\": \"version\", "
211  "\"params\": { "
212  "\"api_version\": " +
215  1) +
216  "}}";
217  auto re = env.rpc(
218  "json2",
219  '[' + without_api_verion + ", " + with_wrong_api_verion + ']');
220 
221  if (!BEAST_EXPECT(re.isArray()))
222  return;
223  if (!BEAST_EXPECT(re.size() == 2))
224  return;
225  BEAST_EXPECT(
226  re[0u].isMember(jss::result) &&
227  re[0u][jss::result].isMember(jss::version));
228  BEAST_EXPECT(re[1u].isMember(jss::error));
229  }
230 
231  void
233  {
234  testcase("config test");
235  {
236  Config c;
237  BEAST_EXPECT(c.BETA_RPC_API == false);
238  }
239 
240  {
241  Config c;
242  c.loadFromString("\n[beta_rpc_api]\n1\n");
243  BEAST_EXPECT(c.BETA_RPC_API == true);
244  }
245 
246  {
247  Config c;
248  c.loadFromString("\n[beta_rpc_api]\n0\n");
249  BEAST_EXPECT(c.BETA_RPC_API == false);
250  }
251  }
252 
253  void
255  {
256  testcase("test version RPC with api_version >= 2");
257 
258  using namespace test::jtx;
259  Env env{*this, envconfig([](std::unique_ptr<Config> c) {
260  c->loadFromString("\n[beta_rpc_api]\n1\n");
261  return c;
262  })};
263  if (!BEAST_EXPECT(env.app().config().BETA_RPC_API == true))
264  return;
265 
266  auto jrr = env.rpc(
267  "json",
268  "version",
269  "{\"api_version\": " + std::to_string(RPC::apiBetaVersion) +
270  "}")[jss::result];
271 
272  if (!BEAST_EXPECT(jrr.isMember(jss::version)))
273  return;
274  if (!BEAST_EXPECT(jrr[jss::version].isMember(jss::first)) &&
275  jrr[jss::version].isMember(jss::last))
276  return;
277  BEAST_EXPECT(
278  jrr[jss::version][jss::first] == RPC::apiMinimumSupportedVersion);
279  BEAST_EXPECT(jrr[jss::version][jss::last] == RPC::apiBetaVersion);
280  }
281 
282 public:
283  void
284  run() override
285  {
289  testBatch();
290  testBatchFail();
291  testConfig();
293  }
294 };
295 
296 BEAST_DEFINE_TESTSUITE(Version, rpc, ripple);
297 
298 } // namespace ripple
ripple::RPC::apiInvalidVersion
constexpr unsigned int apiInvalidVersion
API version numbers used in later API versions.
Definition: RPCHelpers.h:232
ripple::RPC::apiVersionIfUnspecified
constexpr unsigned int apiVersionIfUnspecified
Definition: RPCHelpers.h:233
ripple::Version_test::testBatch
void testBatch()
Definition: Version_test.cpp:154
std::string
STL class.
ripple::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, ripple)
Json::arrayValue
@ arrayValue
array value (ordered list)
Definition: json_value.h:42
ripple::RPC::getAPIVersionNumber
unsigned int getAPIVersionNumber(Json::Value const &jv, bool betaEnabled)
Retrieve the api version number from the json value.
Definition: RPCHelpers.cpp:992
ripple::Version_test::testBatchFail
void testBatchFail()
Definition: Version_test.cpp:191
ripple::RPC::apiBetaVersion
constexpr unsigned int apiBetaVersion
Definition: RPCHelpers.h:237
ripple::Config::loadFromString
void loadFromString(std::string const &fileContents)
Load the config from the contents of the string.
Definition: Config.cpp:447
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
ripple::Config
Definition: Config.h:92
ripple::Version_test::testConfig
void testConfig()
Definition: Version_test.cpp:232
ripple::Version_test::testCorrectVersionNumber
void testCorrectVersionNumber()
Definition: Version_test.cpp:29
std::to_string
T to_string(T... args)
ripple::Config::BETA_RPC_API
bool BETA_RPC_API
Definition: Config.h:298
ripple::Version_test
Definition: Version_test.cpp:26
ripple::Version_test::run
void run() override
Definition: Version_test.cpp:284
ripple::RPC::apiMinimumSupportedVersion
constexpr unsigned int apiMinimumSupportedVersion
Definition: RPCHelpers.h:234
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::Version_test::testGetAPIVersionNumber
void testGetAPIVersionNumber()
Definition: Version_test.cpp:96
Json::nullValue
@ nullValue
'null' value
Definition: json_value.h:36
ripple::RPC::apiMaximumSupportedVersion
constexpr unsigned int apiMaximumSupportedVersion
Definition: RPCHelpers.h:235
ripple::Version_test::testWrongVersionNumber
void testWrongVersionNumber()
Definition: Version_test.cpp:55
std::max
T max(T... args)
std::unique_ptr
STL class.
ripple::Version_test::testVersionRPCV2
void testVersionRPCV2()
Definition: Version_test.cpp:254
Json::Value
Represents a JSON value.
Definition: json_value.h:145