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  re = env.rpc(
80  "json",
81  "version",
82  "{\"api_version\": " +
84  BEAST_EXPECT(badVersion(re));
85 
86  re = env.rpc("json", "version", "{\"api_version\": \"a\"}");
87  BEAST_EXPECT(badVersion(re));
88  }
89 
90  void
92  {
93  testcase("test getAPIVersionNumber function");
94 
95  unsigned int versionIfUnspecified =
99 
102  BEAST_EXPECT(
103  RPC::getAPIVersionNumber(j_array, false) == versionIfUnspecified);
104  BEAST_EXPECT(
105  RPC::getAPIVersionNumber(j_null, false) == versionIfUnspecified);
106 
108  BEAST_EXPECT(
109  RPC::getAPIVersionNumber(j_object, false) == versionIfUnspecified);
110  j_object[jss::api_version] = RPC::apiVersionIfUnspecified;
111  BEAST_EXPECT(
112  RPC::getAPIVersionNumber(j_object, false) == versionIfUnspecified);
113 
114  j_object[jss::api_version] = RPC::apiMinimumSupportedVersion;
115  BEAST_EXPECT(
116  RPC::getAPIVersionNumber(j_object, false) ==
118  j_object[jss::api_version] = RPC::apiMaximumSupportedVersion;
119  BEAST_EXPECT(
120  RPC::getAPIVersionNumber(j_object, false) ==
122 
123  j_object[jss::api_version] = RPC::apiMinimumSupportedVersion - 1;
124  BEAST_EXPECT(
125  RPC::getAPIVersionNumber(j_object, false) ==
127  j_object[jss::api_version] = RPC::apiMaximumSupportedVersion + 1;
128  BEAST_EXPECT(
129  RPC::getAPIVersionNumber(j_object, false) ==
131  j_object[jss::api_version] = RPC::apiBetaVersion;
132  BEAST_EXPECT(
133  RPC::getAPIVersionNumber(j_object, true) == RPC::apiBetaVersion);
134  j_object[jss::api_version] = RPC::apiBetaVersion + 1;
135  BEAST_EXPECT(
137 
138  j_object[jss::api_version] = RPC::apiInvalidVersion;
139  BEAST_EXPECT(
140  RPC::getAPIVersionNumber(j_object, false) ==
142  j_object[jss::api_version] = "a";
143  BEAST_EXPECT(
144  RPC::getAPIVersionNumber(j_object, false) ==
146  }
147 
148  void
150  {
151  testcase("batch, all good request");
152 
153  using namespace test::jtx;
154  Env env{*this};
155 
156  auto const without_api_verion = std::string("{ ") +
157  "\"jsonrpc\": \"2.0\", "
158  "\"ripplerpc\": \"2.0\", "
159  "\"id\": 5, "
160  "\"method\": \"version\", "
161  "\"params\": {}}";
162  auto const with_api_verion = std::string("{ ") +
163  "\"jsonrpc\": \"2.0\", "
164  "\"ripplerpc\": \"2.0\", "
165  "\"id\": 6, "
166  "\"method\": \"version\", "
167  "\"params\": { "
168  "\"api_version\": " +
170  auto re = env.rpc(
171  "json2", '[' + without_api_verion + ", " + with_api_verion + ']');
172 
173  if (!BEAST_EXPECT(re.isArray()))
174  return;
175  if (!BEAST_EXPECT(re.size() == 2))
176  return;
177  BEAST_EXPECT(
178  re[0u].isMember(jss::result) &&
179  re[0u][jss::result].isMember(jss::version));
180  BEAST_EXPECT(
181  re[1u].isMember(jss::result) &&
182  re[1u][jss::result].isMember(jss::version));
183  }
184 
185  void
187  {
188  testcase("batch, with a bad request");
189 
190  using namespace test::jtx;
191  Env env{*this};
192 
193  auto const without_api_verion = std::string("{ ") +
194  "\"jsonrpc\": \"2.0\", "
195  "\"ripplerpc\": \"2.0\", "
196  "\"id\": 5, "
197  "\"method\": \"version\", "
198  "\"params\": {}}";
199  auto const with_wrong_api_verion = std::string("{ ") +
200  "\"jsonrpc\": \"2.0\", "
201  "\"ripplerpc\": \"2.0\", "
202  "\"id\": 6, "
203  "\"method\": \"version\", "
204  "\"params\": { "
205  "\"api_version\": " +
207  auto re = env.rpc(
208  "json2",
209  '[' + without_api_verion + ", " + with_wrong_api_verion + ']');
210 
211  if (!BEAST_EXPECT(re.isArray()))
212  return;
213  if (!BEAST_EXPECT(re.size() == 2))
214  return;
215  BEAST_EXPECT(
216  re[0u].isMember(jss::result) &&
217  re[0u][jss::result].isMember(jss::version));
218  BEAST_EXPECT(re[1u].isMember(jss::error));
219  }
220 
221  void
223  {
224  testcase("config test");
225  {
226  Config c;
227  BEAST_EXPECT(c.BETA_RPC_API == false);
228  }
229 
230  {
231  Config c;
232  c.loadFromString("\n[beta_rpc_api]\n1\n");
233  BEAST_EXPECT(c.BETA_RPC_API == true);
234  }
235 
236  {
237  Config c;
238  c.loadFromString("\n[beta_rpc_api]\n0\n");
239  BEAST_EXPECT(c.BETA_RPC_API == false);
240  }
241  }
242 
243  void
245  {
246  testcase("test version RPC with api_version >= 2");
247 
248  using namespace test::jtx;
249  Env env{*this, envconfig([](std::unique_ptr<Config> c) {
250  c->loadFromString("\n[beta_rpc_api]\n1\n");
251  return c;
252  })};
253  if (!BEAST_EXPECT(env.app().config().BETA_RPC_API == true))
254  return;
255 
256  auto jrr = env.rpc(
257  "json",
258  "version",
259  "{\"api_version\": " + std::to_string(RPC::apiBetaVersion) +
260  "}")[jss::result];
261 
262  if (!BEAST_EXPECT(jrr.isMember(jss::version)))
263  return;
264  if (!BEAST_EXPECT(jrr[jss::version].isMember(jss::first)) &&
265  jrr[jss::version].isMember(jss::last))
266  return;
267  BEAST_EXPECT(
268  jrr[jss::version][jss::first] == RPC::apiMinimumSupportedVersion);
269  BEAST_EXPECT(jrr[jss::version][jss::last] == RPC::apiBetaVersion);
270  }
271 
272 public:
273  void
274  run() override
275  {
279  testBatch();
280  testBatchFail();
281  testConfig();
283  }
284 };
285 
286 BEAST_DEFINE_TESTSUITE(Version, rpc, ripple);
287 
288 } // namespace ripple
ripple::RPC::apiInvalidVersion
constexpr unsigned int apiInvalidVersion
API version numbers used in later API versions.
Definition: RPCHelpers.h:241
ripple::RPC::apiVersionIfUnspecified
constexpr unsigned int apiVersionIfUnspecified
Definition: RPCHelpers.h:242
ripple::Version_test::testBatch
void testBatch()
Definition: Version_test.cpp:149
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:1033
ripple::Version_test::testBatchFail
void testBatchFail()
Definition: Version_test.cpp:186
ripple::RPC::apiBetaVersion
constexpr unsigned int apiBetaVersion
Definition: RPCHelpers.h:245
ripple::Config::loadFromString
void loadFromString(std::string const &fileContents)
Load the config from the contents of the string.
Definition: Config.cpp:457
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
ripple::Config
Definition: Config.h:89
ripple::Version_test::testConfig
void testConfig()
Definition: Version_test.cpp:222
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:293
ripple::Version_test
Definition: Version_test.cpp:26
ripple::Version_test::run
void run() override
Definition: Version_test.cpp:274
ripple::RPC::apiMinimumSupportedVersion
constexpr unsigned int apiMinimumSupportedVersion
Definition: RPCHelpers.h:243
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:91
Json::nullValue
@ nullValue
'null' value
Definition: json_value.h:36
ripple::RPC::apiMaximumSupportedVersion
constexpr unsigned int apiMaximumSupportedVersion
Definition: RPCHelpers.h:244
ripple::Version_test::testWrongVersionNumber
void testWrongVersionNumber()
Definition: Version_test.cpp:55
std::unique_ptr
STL class.
ripple::Version_test::testVersionRPCV2
void testVersionRPCV2()
Definition: Version_test.cpp:244
Json::Value
Represents a JSON value.
Definition: json_value.h:145