rippled
Issue_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 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/basics/UnorderedContainers.h>
21 #include <ripple/protocol/Book.h>
22 #include <ripple/protocol/Issue.h>
23 #include <ripple/beast/unit_test.h>
24 #include <map>
25 #include <set>
26 #include <typeinfo>
27 #include <unordered_set>
28 
29 #if BEAST_MSVC
30 # define STL_SET_HAS_EMPLACE 1
31 #else
32 # define STL_SET_HAS_EMPLACE 0
33 #endif
34 
35 #ifndef RIPPLE_ASSETS_ENABLE_STD_HASH
36 # if BEAST_MAC || BEAST_IOS
37 # define RIPPLE_ASSETS_ENABLE_STD_HASH 0
38 # else
39 # define RIPPLE_ASSETS_ENABLE_STD_HASH 1
40 # endif
41 #endif
42 
43 namespace ripple {
44 
45 class Issue_test : public beast::unit_test::suite
46 {
47 public:
48  // Comparison, hash tests for uint60 (via base_uint)
49  template <typename Unsigned>
50  void testUnsigned ()
51  {
52  Unsigned const u1 (1);
53  Unsigned const u2 (2);
54  Unsigned const u3 (3);
55 
56  BEAST_EXPECT(u1 != u2);
57  BEAST_EXPECT(u1 < u2);
58  BEAST_EXPECT(u1 <= u2);
59  BEAST_EXPECT(u2 <= u2);
60  BEAST_EXPECT(u2 == u2);
61  BEAST_EXPECT(u2 >= u2);
62  BEAST_EXPECT(u3 >= u2);
63  BEAST_EXPECT(u3 > u2);
64 
66 
67  BEAST_EXPECT(hash (u1) == hash (u1));
68  BEAST_EXPECT(hash (u2) == hash (u2));
69  BEAST_EXPECT(hash (u3) == hash (u3));
70  BEAST_EXPECT(hash (u1) != hash (u2));
71  BEAST_EXPECT(hash (u1) != hash (u3));
72  BEAST_EXPECT(hash (u2) != hash (u3));
73  }
74 
75  //--------------------------------------------------------------------------
76 
77  // Comparison, hash tests for Issue
78  template <class Issue>
79  void testIssue ()
80  {
81  Currency const c1 (1); AccountID const i1 (1);
82  Currency const c2 (2); AccountID const i2 (2);
83  Currency const c3 (3); AccountID const i3 (3);
84 
85  BEAST_EXPECT(Issue (c1, i1) != Issue (c2, i1));
86  BEAST_EXPECT(Issue (c1, i1) < Issue (c2, i1));
87  BEAST_EXPECT(Issue (c1, i1) <= Issue (c2, i1));
88  BEAST_EXPECT(Issue (c2, i1) <= Issue (c2, i1));
89  BEAST_EXPECT(Issue (c2, i1) == Issue (c2, i1));
90  BEAST_EXPECT(Issue (c2, i1) >= Issue (c2, i1));
91  BEAST_EXPECT(Issue (c3, i1) >= Issue (c2, i1));
92  BEAST_EXPECT(Issue (c3, i1) > Issue (c2, i1));
93  BEAST_EXPECT(Issue (c1, i1) != Issue (c1, i2));
94  BEAST_EXPECT(Issue (c1, i1) < Issue (c1, i2));
95  BEAST_EXPECT(Issue (c1, i1) <= Issue (c1, i2));
96  BEAST_EXPECT(Issue (c1, i2) <= Issue (c1, i2));
97  BEAST_EXPECT(Issue (c1, i2) == Issue (c1, i2));
98  BEAST_EXPECT(Issue (c1, i2) >= Issue (c1, i2));
99  BEAST_EXPECT(Issue (c1, i3) >= Issue (c1, i2));
100  BEAST_EXPECT(Issue (c1, i3) > Issue (c1, i2));
101 
102  std::hash <Issue> hash;
103 
104  BEAST_EXPECT(hash (Issue (c1, i1)) == hash (Issue (c1, i1)));
105  BEAST_EXPECT(hash (Issue (c1, i2)) == hash (Issue (c1, i2)));
106  BEAST_EXPECT(hash (Issue (c1, i3)) == hash (Issue (c1, i3)));
107  BEAST_EXPECT(hash (Issue (c2, i1)) == hash (Issue (c2, i1)));
108  BEAST_EXPECT(hash (Issue (c2, i2)) == hash (Issue (c2, i2)));
109  BEAST_EXPECT(hash (Issue (c2, i3)) == hash (Issue (c2, i3)));
110  BEAST_EXPECT(hash (Issue (c3, i1)) == hash (Issue (c3, i1)));
111  BEAST_EXPECT(hash (Issue (c3, i2)) == hash (Issue (c3, i2)));
112  BEAST_EXPECT(hash (Issue (c3, i3)) == hash (Issue (c3, i3)));
113  BEAST_EXPECT(hash (Issue (c1, i1)) != hash (Issue (c1, i2)));
114  BEAST_EXPECT(hash (Issue (c1, i1)) != hash (Issue (c1, i3)));
115  BEAST_EXPECT(hash (Issue (c1, i1)) != hash (Issue (c2, i1)));
116  BEAST_EXPECT(hash (Issue (c1, i1)) != hash (Issue (c2, i2)));
117  BEAST_EXPECT(hash (Issue (c1, i1)) != hash (Issue (c2, i3)));
118  BEAST_EXPECT(hash (Issue (c1, i1)) != hash (Issue (c3, i1)));
119  BEAST_EXPECT(hash (Issue (c1, i1)) != hash (Issue (c3, i2)));
120  BEAST_EXPECT(hash (Issue (c1, i1)) != hash (Issue (c3, i3)));
121  }
122 
123  template <class Set>
124  void testIssueSet ()
125  {
126  Currency const c1 (1);
127  AccountID const i1 (1);
128  Currency const c2 (2);
129  AccountID const i2 (2);
130  Issue const a1 (c1, i1);
131  Issue const a2 (c2, i2);
132 
133  {
134  Set c;
135 
136  c.insert (a1);
137  if (! BEAST_EXPECT(c.size () == 1)) return;
138  c.insert (a2);
139  if (! BEAST_EXPECT(c.size () == 2)) return;
140 
141  if (! BEAST_EXPECT(c.erase (Issue (c1, i2)) == 0)) return;
142  if (! BEAST_EXPECT(c.erase (Issue (c1, i1)) == 1)) return;
143  if (! BEAST_EXPECT(c.erase (Issue (c2, i2)) == 1)) return;
144  if (! BEAST_EXPECT(c.empty ())) return;
145  }
146 
147  {
148  Set c;
149 
150  c.insert (a1);
151  if (! BEAST_EXPECT(c.size () == 1)) return;
152  c.insert (a2);
153  if (! BEAST_EXPECT(c.size () == 2)) return;
154 
155  if (! BEAST_EXPECT(c.erase (Issue (c1, i2)) == 0)) return;
156  if (! BEAST_EXPECT(c.erase (Issue (c1, i1)) == 1)) return;
157  if (! BEAST_EXPECT(c.erase (Issue (c2, i2)) == 1)) return;
158  if (! BEAST_EXPECT(c.empty ())) return;
159 
160  #if STL_SET_HAS_EMPLACE
161  c.emplace (c1, i1);
162  if (! BEAST_EXPECT(c.size() == 1)) return;
163  c.emplace (c2, i2);
164  if (! BEAST_EXPECT(c.size() == 2)) return;
165  #endif
166  }
167  }
168 
169  template <class Map>
170  void testIssueMap ()
171  {
172  Currency const c1 (1);
173  AccountID const i1 (1);
174  Currency const c2 (2);
175  AccountID const i2 (2);
176  Issue const a1 (c1, i1);
177  Issue const a2 (c2, i2);
178 
179  {
180  Map c;
181 
182  c.insert (std::make_pair (a1, 1));
183  if (! BEAST_EXPECT(c.size () == 1)) return;
184  c.insert (std::make_pair (a2, 2));
185  if (! BEAST_EXPECT(c.size () == 2)) return;
186 
187  if (! BEAST_EXPECT(c.erase (Issue (c1, i2)) == 0)) return;
188  if (! BEAST_EXPECT(c.erase (Issue (c1, i1)) == 1)) return;
189  if (! BEAST_EXPECT(c.erase (Issue (c2, i2)) == 1)) return;
190  if (! BEAST_EXPECT(c.empty ())) return;
191  }
192 
193  {
194  Map c;
195 
196  c.insert (std::make_pair (a1, 1));
197  if (! BEAST_EXPECT(c.size () == 1)) return;
198  c.insert (std::make_pair (a2, 2));
199  if (! BEAST_EXPECT(c.size () == 2)) return;
200 
201  if (! BEAST_EXPECT(c.erase (Issue (c1, i2)) == 0)) return;
202  if (! BEAST_EXPECT(c.erase (Issue (c1, i1)) == 1)) return;
203  if (! BEAST_EXPECT(c.erase (Issue (c2, i2)) == 1)) return;
204  if (! BEAST_EXPECT(c.empty ())) return;
205  }
206  }
207 
209  {
210  testcase ("std::set <Issue>");
211  testIssueSet <std::set <Issue>> ();
212 
213  testcase ("std::set <Issue>");
214  testIssueSet <std::set <Issue>> ();
215 
216 #if RIPPLE_ASSETS_ENABLE_STD_HASH
217  testcase ("std::unordered_set <Issue>");
218  testIssueSet <std::unordered_set <Issue>> ();
219 
220  testcase ("std::unordered_set <Issue>");
221  testIssueSet <std::unordered_set <Issue>> ();
222 #endif
223 
224  testcase ("hash_set <Issue>");
225  testIssueSet <hash_set <Issue>> ();
226 
227  testcase ("hash_set <Issue>");
228  testIssueSet <hash_set <Issue>> ();
229  }
230 
232  {
233  testcase ("std::map <Issue, int>");
234  testIssueMap <std::map <Issue, int>> ();
235 
236  testcase ("std::map <Issue, int>");
237  testIssueMap <std::map <Issue, int>> ();
238 
239 #if RIPPLE_ASSETS_ENABLE_STD_HASH
240  testcase ("std::unordered_map <Issue, int>");
241  testIssueMap <std::unordered_map <Issue, int>> ();
242 
243  testcase ("std::unordered_map <Issue, int>");
244  testIssueMap <std::unordered_map <Issue, int>> ();
245 
246  testcase ("hash_map <Issue, int>");
247  testIssueMap <hash_map <Issue, int>> ();
248 
249  testcase ("hash_map <Issue, int>");
250  testIssueMap <hash_map <Issue, int>> ();
251 
252 #endif
253  }
254 
255  //--------------------------------------------------------------------------
256 
257  // Comparison, hash tests for Book
258  template <class Book>
259  void testBook ()
260  {
261  Currency const c1 (1); AccountID const i1 (1);
262  Currency const c2 (2); AccountID const i2 (2);
263  Currency const c3 (3); AccountID const i3 (3);
264 
265  Issue a1 (c1, i1);
266  Issue a2 (c1, i2);
267  Issue a3 (c2, i2);
268  Issue a4 (c3, i2);
269 
270  BEAST_EXPECT(Book (a1, a2) != Book (a2, a3));
271  BEAST_EXPECT(Book (a1, a2) < Book (a2, a3));
272  BEAST_EXPECT(Book (a1, a2) <= Book (a2, a3));
273  BEAST_EXPECT(Book (a2, a3) <= Book (a2, a3));
274  BEAST_EXPECT(Book (a2, a3) == Book (a2, a3));
275  BEAST_EXPECT(Book (a2, a3) >= Book (a2, a3));
276  BEAST_EXPECT(Book (a3, a4) >= Book (a2, a3));
277  BEAST_EXPECT(Book (a3, a4) > Book (a2, a3));
278 
279  std::hash <Book> hash;
280 
281 // log << std::hex << hash (Book (a1, a2));
282 // log << std::hex << hash (Book (a1, a2));
283 //
284 // log << std::hex << hash (Book (a1, a3));
285 // log << std::hex << hash (Book (a1, a3));
286 //
287 // log << std::hex << hash (Book (a1, a4));
288 // log << std::hex << hash (Book (a1, a4));
289 //
290 // log << std::hex << hash (Book (a2, a3));
291 // log << std::hex << hash (Book (a2, a3));
292 //
293 // log << std::hex << hash (Book (a2, a4));
294 // log << std::hex << hash (Book (a2, a4));
295 //
296 // log << std::hex << hash (Book (a3, a4));
297 // log << std::hex << hash (Book (a3, a4));
298 
299  BEAST_EXPECT(hash (Book (a1, a2)) == hash (Book (a1, a2)));
300  BEAST_EXPECT(hash (Book (a1, a3)) == hash (Book (a1, a3)));
301  BEAST_EXPECT(hash (Book (a1, a4)) == hash (Book (a1, a4)));
302  BEAST_EXPECT(hash (Book (a2, a3)) == hash (Book (a2, a3)));
303  BEAST_EXPECT(hash (Book (a2, a4)) == hash (Book (a2, a4)));
304  BEAST_EXPECT(hash (Book (a3, a4)) == hash (Book (a3, a4)));
305 
306  BEAST_EXPECT(hash (Book (a1, a2)) != hash (Book (a1, a3)));
307  BEAST_EXPECT(hash (Book (a1, a2)) != hash (Book (a1, a4)));
308  BEAST_EXPECT(hash (Book (a1, a2)) != hash (Book (a2, a3)));
309  BEAST_EXPECT(hash (Book (a1, a2)) != hash (Book (a2, a4)));
310  BEAST_EXPECT(hash (Book (a1, a2)) != hash (Book (a3, a4)));
311  }
312 
313  //--------------------------------------------------------------------------
314 
315  template <class Set>
316  void testBookSet ()
317  {
318  Currency const c1 (1);
319  AccountID const i1 (1);
320  Currency const c2 (2);
321  AccountID const i2 (2);
322  Issue const a1 (c1, i1);
323  Issue const a2 (c2, i2);
324  Book const b1 (a1, a2);
325  Book const b2 (a2, a1);
326 
327  {
328  Set c;
329 
330  c.insert (b1);
331  if (! BEAST_EXPECT(c.size () == 1)) return;
332  c.insert (b2);
333  if (! BEAST_EXPECT(c.size () == 2)) return;
334 
335  if (! BEAST_EXPECT(c.erase (Book (a1, a1)) == 0)) return;
336  if (! BEAST_EXPECT(c.erase (Book (a1, a2)) == 1)) return;
337  if (! BEAST_EXPECT(c.erase (Book (a2, a1)) == 1)) return;
338  if (! BEAST_EXPECT(c.empty ())) return;
339  }
340 
341  {
342  Set c;
343 
344  c.insert (b1);
345  if (! BEAST_EXPECT(c.size () == 1)) return;
346  c.insert (b2);
347  if (! BEAST_EXPECT(c.size () == 2)) return;
348 
349  if (! BEAST_EXPECT(c.erase (Book (a1, a1)) == 0)) return;
350  if (! BEAST_EXPECT(c.erase (Book (a1, a2)) == 1)) return;
351  if (! BEAST_EXPECT(c.erase (Book (a2, a1)) == 1)) return;
352  if (! BEAST_EXPECT(c.empty ())) return;
353 
354  #if STL_SET_HAS_EMPLACE
355  c.emplace (a1, a2);
356  if (! BEAST_EXPECT(c.size() == 1)) return;
357  c.emplace (a2, a1);
358  if (! BEAST_EXPECT(c.size() == 2)) return;
359  #endif
360  }
361  }
362 
363  template <class Map>
364  void testBookMap ()
365  {
366  Currency const c1 (1);
367  AccountID const i1 (1);
368  Currency const c2 (2);
369  AccountID const i2 (2);
370  Issue const a1 (c1, i1);
371  Issue const a2 (c2, i2);
372  Book const b1 (a1, a2);
373  Book const b2 (a2, a1);
374 
375  //typename Map::value_type value_type;
376  //std::pair <Book const, int> value_type;
377 
378  {
379  Map c;
380 
381  //c.insert (value_type (b1, 1));
382  c.insert (std::make_pair (b1, 1));
383  if (! BEAST_EXPECT(c.size () == 1)) return;
384  //c.insert (value_type (b2, 2));
385  c.insert (std::make_pair (b2, 1));
386  if (! BEAST_EXPECT(c.size () == 2)) return;
387 
388  if (! BEAST_EXPECT(c.erase (Book (a1, a1)) == 0)) return;
389  if (! BEAST_EXPECT(c.erase (Book (a1, a2)) == 1)) return;
390  if (! BEAST_EXPECT(c.erase (Book (a2, a1)) == 1)) return;
391  if (! BEAST_EXPECT(c.empty ())) return;
392  }
393 
394  {
395  Map c;
396 
397  //c.insert (value_type (b1, 1));
398  c.insert (std::make_pair (b1, 1));
399  if (! BEAST_EXPECT(c.size () == 1)) return;
400  //c.insert (value_type (b2, 2));
401  c.insert (std::make_pair (b2, 1));
402  if (! BEAST_EXPECT(c.size () == 2)) return;
403 
404  if (! BEAST_EXPECT(c.erase (Book (a1, a1)) == 0)) return;
405  if (! BEAST_EXPECT(c.erase (Book (a1, a2)) == 1)) return;
406  if (! BEAST_EXPECT(c.erase (Book (a2, a1)) == 1)) return;
407  if (! BEAST_EXPECT(c.empty ())) return;
408  }
409  }
410 
411  void testBookSets ()
412  {
413  testcase ("std::set <Book>");
414  testBookSet <std::set <Book>> ();
415 
416  testcase ("std::set <Book>");
417  testBookSet <std::set <Book>> ();
418 
419 #if RIPPLE_ASSETS_ENABLE_STD_HASH
420  testcase ("std::unordered_set <Book>");
421  testBookSet <std::unordered_set <Book>> ();
422 
423  testcase ("std::unordered_set <Book>");
424  testBookSet <std::unordered_set <Book>> ();
425 #endif
426 
427  testcase ("hash_set <Book>");
428  testBookSet <hash_set <Book>> ();
429 
430  testcase ("hash_set <Book>");
431  testBookSet <hash_set <Book>> ();
432  }
433 
434  void testBookMaps ()
435  {
436  testcase ("std::map <Book, int>");
437  testBookMap <std::map <Book, int>> ();
438 
439  testcase ("std::map <Book, int>");
440  testBookMap <std::map <Book, int>> ();
441 
442 #if RIPPLE_ASSETS_ENABLE_STD_HASH
443  testcase ("std::unordered_map <Book, int>");
444  testBookMap <std::unordered_map <Book, int>> ();
445 
446  testcase ("std::unordered_map <Book, int>");
447  testBookMap <std::unordered_map <Book, int>> ();
448 
449  testcase ("hash_map <Book, int>");
450  testBookMap <hash_map <Book, int>> ();
451 
452  testcase ("hash_map <Book, int>");
453  testBookMap <hash_map <Book, int>> ();
454 #endif
455  }
456 
457  //--------------------------------------------------------------------------
458 
459  void run() override
460  {
461  testcase ("Currency");
462  testUnsigned <Currency> ();
463 
464  testcase ("AccountID");
465  testUnsigned <AccountID> ();
466 
467  // ---
468 
469  testcase ("Issue");
470  testIssue <Issue> ();
471 
472  testcase ("Issue");
473  testIssue <Issue> ();
474 
475  testIssueSets ();
476  testIssueMaps ();
477 
478  // ---
479 
480  testcase ("Book");
481  testBook <Book> ();
482 
483  testcase ("Book");
484  testBook <Book> ();
485 
486  testBookSets ();
487  testBookMaps ();
488  }
489 };
490 
491 BEAST_DEFINE_TESTSUITE(Issue,protocol,ripple);
492 
493 }
ripple::Issue_test::testIssue
void testIssue()
Definition: Issue_test.cpp:79
ripple::Issue
A currency issued by an account.
Definition: Issue.h:34
ripple::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, ripple)
ripple::Issue_test::testBookMaps
void testBookMaps()
Definition: Issue_test.cpp:434
unordered_set
ripple::Issue_test::run
void run() override
Definition: Issue_test.cpp:459
ripple::Issue_test::testIssueMap
void testIssueMap()
Definition: Issue_test.cpp:170
ripple::Issue_test
Definition: Issue_test.cpp:45
ripple::Issue_test::testIssueSets
void testIssueSets()
Definition: Issue_test.cpp:208
ripple::base_uint< 160, detail::CurrencyTag >
ripple::Issue_test::testIssueMaps
void testIssueMaps()
Definition: Issue_test.cpp:231
map
ripple::Issue_test::testIssueSet
void testIssueSet()
Definition: Issue_test.cpp:124
ripple::Issue_test::testBookMap
void testBookMap()
Definition: Issue_test.cpp:364
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::Issue_test::testBook
void testBook()
Definition: Issue_test.cpp:259
typeinfo
ripple::Book
Specifies an order book.
Definition: Book.h:32
std::make_pair
T make_pair(T... args)
ripple::Issue_test::testUnsigned
void testUnsigned()
Definition: Issue_test.cpp:50
ripple::Issue_test::testBookSet
void testBookSet()
Definition: Issue_test.cpp:316
set
std::hash
ripple::Issue_test::testBookSets
void testBookSets()
Definition: Issue_test.cpp:411