1 /*
2 * Copyright (C) 2019 Savoir-faire Linux Inc.
3 *
4 * Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "infohashtester.h"
21
22 // std
23 #include <iostream>
24 #include <string>
25
26 // opendht
27 #include "opendht/infohash.h"
28
29 namespace test {
30 CPPUNIT_TEST_SUITE_REGISTRATION(InfoHashTester);
31
32 void
setUp()33 InfoHashTester::setUp() {
34
35 }
36
37 void
testConstructors()38 InfoHashTester::testConstructors() {
39 // Default constructor creates a null infohash
40 auto nullHash = dht::InfoHash();
41 CPPUNIT_ASSERT_EQUAL((size_t)20u, nullHash.size());
42 CPPUNIT_ASSERT(!nullHash);
43 // Build from a uint8_t. if length to short, should get a null infohash
44 uint8_t to_short[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
45 auto infohash = dht::InfoHash(to_short, 8);
46 CPPUNIT_ASSERT_EQUAL((size_t)20u, infohash.size());
47 CPPUNIT_ASSERT_EQUAL(std::string("0000000000000000000000000000000000000000"), infohash.toString());
48 // Build from a uint8_t. if length is enough, data should contains the uint8_t
49 uint8_t enough[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
50 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa};
51 infohash = dht::InfoHash(enough, 20);
52 CPPUNIT_ASSERT(infohash.size() == 20);
53 const auto* data = infohash.data();
54 for (auto i = 0; i < 20; ++i) {
55 CPPUNIT_ASSERT_EQUAL(enough[i], data[i]);
56 }
57 // if too long, should be cutted to 20
58 uint8_t tooLong[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
59 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb0};
60 infohash = dht::InfoHash(tooLong, 21);
61 CPPUNIT_ASSERT(infohash.size() == 20);
62 const auto* data2 = infohash.data();
63 for (auto i = 0; i < 20; ++i) {
64 CPPUNIT_ASSERT_EQUAL(enough[i], data2[i]);
65 }
66 // Build from string
67 auto infohashFromStr = dht::InfoHash("0102030405060708090A0102030405060708090A");
68 CPPUNIT_ASSERT_EQUAL((size_t)20u, infohashFromStr.size());
69 const auto* dataStr = infohashFromStr.data();
70 for (auto i = 0; i < 20; ++i) {
71 CPPUNIT_ASSERT_EQUAL((int)dataStr[i], (int)data[i]);
72 }
73 }
74
75 void
testComperators()76 InfoHashTester::testComperators() {
77 auto nullHash = dht::InfoHash();
78 auto minHash = dht::InfoHash("0000000000000000000000000000000000111110");
79 auto maxHash = dht::InfoHash("0111110000000000000000000000000000000000");
80 // operator ==
81 CPPUNIT_ASSERT_EQUAL(minHash, minHash);
82 CPPUNIT_ASSERT_EQUAL(minHash, dht::InfoHash("0000000000000000000000000000000000111110"));
83 CPPUNIT_ASSERT(!(minHash == maxHash));
84 // operator !=
85 CPPUNIT_ASSERT(!(minHash != minHash));
86 CPPUNIT_ASSERT(!(minHash != dht::InfoHash("0000000000000000000000000000000000111110")));
87 CPPUNIT_ASSERT(minHash != maxHash);
88 // operator<
89 CPPUNIT_ASSERT(nullHash < minHash);
90 CPPUNIT_ASSERT(nullHash < maxHash);
91 CPPUNIT_ASSERT(minHash < maxHash);
92 CPPUNIT_ASSERT(!(minHash < nullHash));
93 CPPUNIT_ASSERT(!(maxHash < nullHash));
94 CPPUNIT_ASSERT(!(maxHash < minHash));
95 CPPUNIT_ASSERT(!(minHash < minHash));
96 // bool()
97 CPPUNIT_ASSERT(maxHash);
98 CPPUNIT_ASSERT(!nullHash);
99
100 }
101
102 void
testLowBit()103 InfoHashTester::testLowBit() {
104 auto nullHash = dht::InfoHash();
105 auto minHash = dht::InfoHash("0000000000000000000000000000000000000010");
106 auto maxHash = dht::InfoHash("0100000000000000000000000000000000000000");
107 CPPUNIT_ASSERT_EQUAL(nullHash.lowbit(), -1);
108 CPPUNIT_ASSERT_EQUAL(minHash.lowbit(), 155);
109 CPPUNIT_ASSERT_EQUAL(maxHash.lowbit(), 7);
110 }
111
112 void
testCommonBits()113 InfoHashTester::testCommonBits() {
114 auto nullHash = dht::InfoHash();
115 auto minHash = dht::InfoHash("0000000000000000000000000000000000000010");
116 auto maxHash = dht::InfoHash("0100000000000000000000000000000000000000");
117 CPPUNIT_ASSERT_EQUAL(dht::InfoHash::commonBits(nullHash, nullHash), (unsigned)160);
118 CPPUNIT_ASSERT_EQUAL(dht::InfoHash::commonBits(nullHash, minHash), (unsigned)155);
119 CPPUNIT_ASSERT_EQUAL(dht::InfoHash::commonBits(nullHash, maxHash), (unsigned)7);
120 CPPUNIT_ASSERT_EQUAL(dht::InfoHash::commonBits(minHash, maxHash), (unsigned)7);
121 }
122
123 void
testXorCmp()124 InfoHashTester::testXorCmp() {
125 auto nullHash = dht::InfoHash();
126 auto minHash = dht::InfoHash("0000000000000000000000000000000000000010");
127 auto maxHash = dht::InfoHash("0100000000000000000000000000000000000000");
128 CPPUNIT_ASSERT_EQUAL(minHash.xorCmp(nullHash, maxHash), -1);
129 CPPUNIT_ASSERT_EQUAL(minHash.xorCmp(maxHash, nullHash), 1);
130 CPPUNIT_ASSERT_EQUAL(minHash.xorCmp(minHash, maxHash), -1);
131 CPPUNIT_ASSERT_EQUAL(minHash.xorCmp(maxHash, minHash), 1);
132 CPPUNIT_ASSERT_EQUAL(nullHash.xorCmp(minHash, maxHash), -1);
133 CPPUNIT_ASSERT_EQUAL(nullHash.xorCmp(maxHash, minHash), 1);
134 // Because hashes are circular in distance.
135 CPPUNIT_ASSERT_EQUAL(maxHash.xorCmp(nullHash, minHash), -1);
136 CPPUNIT_ASSERT_EQUAL(maxHash.xorCmp(minHash, nullHash), 1);
137 }
138
139 void
tearDown()140 InfoHashTester::tearDown() {
141
142 }
143 } // namespace test
144