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