A Discrete-Event Network Simulator
API
hash-test-suite.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Lawrence Livermore National Laboratory
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Peter D. Barnes, Jr. <pdbarnes@llnl.gov>
18  */
19 
20 #include "ns3/hash.h"
21 #include "ns3/test.h"
22 
23 #include <iomanip>
24 #include <string>
25 
40 namespace ns3
41 {
42 
43 namespace tests
44 {
45 
50 class HashTestCase : public TestCase
51 {
52  public:
58  HashTestCase(const std::string name);
60  ~HashTestCase() override;
61 
62  protected:
68  void Check(const std::string hashName, const uint32_t hash);
74  void Check(const std::string hashName, const uint64_t hash);
75 
76  std::string key;
77  uint32_t hash32Reference;
78  uint64_t hash64Reference;
79 
80  private:
87  void Check(const std::string hashName, const int bits, const uint64_t hash);
88  void DoRun() override;
89 
90 }; // class HashTestCase
91 
92 HashTestCase::HashTestCase(const std::string name)
93  : TestCase(name),
94  key("The quick brown fox jumped over the lazy dogs.")
95 {
96 }
97 
99 {
100 }
101 
102 void
103 HashTestCase::Check(const std::string hashName, const uint32_t hash)
104 {
105  Check(hashName, 32, hash);
106 }
107 
108 void
109 HashTestCase::Check(const std::string hashName, const uint64_t hash)
110 {
111  Check(hashName, 64, hash);
112 }
113 
114 void
115 HashTestCase::Check(std::string hashName, int bits, uint64_t hash)
116 {
117  int w;
118  std::string type;
119  uint64_t hashRef;
120 
121  if (bits == 32)
122  {
123  w = 8;
124  type = "Hash32";
125  hashRef = hash32Reference;
126  }
127  else
128  {
129  w = 16;
130  type = "Hash64";
131  hashRef = hash64Reference;
132  }
133 
134  std::cout << GetName() << "checking " << hashName << " " << bits << "-bit result...";
136  hashRef,
137  hashName << " " << type << " produced " << std::hex << std::setw(w)
138  << hash << ", expected " << std::hex << std::setw(w) << hashRef
139  << std::dec);
140  std::cout << std::hex << std::setw(w) << hash << ", ok" << std::dec << std::endl;
141 }
142 
143 void
145 {
146 }
147 
153 {
154  public:
158  ~DefaultHashTestCase() override;
159 
160  private:
161  void DoRun() override;
162 };
163 
165  : HashTestCase("DefaultHash: ")
166 {
167 }
168 
170 {
171 }
172 
173 void
175 {
176  std::cout << GetName() << "checking with key: \"" << key << "\"" << std::endl;
177 
178  hash32Reference = 0x463d70e2; // murmur3(key)
179  Check("default", Hash32(key));
180 
181  hash64Reference = 0xa750412079d53e04ULL;
182  Check("default", Hash64(key));
183 }
184 
190 {
191  public:
193  Fnv1aTestCase();
195  ~Fnv1aTestCase() override;
196 
197  private:
198  void DoRun() override;
199 };
200 
202  : HashTestCase("Fnv1a: ")
203 {
204 }
205 
207 {
208 }
209 
210 void
212 {
213  Hasher hasher = Hasher(Create<Hash::Function::Fnv1a>());
214  hash32Reference = 0xa3fc0d6d; // Fnv1a(key)
215  Check("FNV1a", hasher.clear().GetHash32(key));
216 
217  hash64Reference = 0x88f6cdbe0a31098dULL;
218  Check("FNV1a", hasher.clear().GetHash64(key));
219 }
220 
226 {
227  public:
229  Murmur3TestCase();
231  ~Murmur3TestCase() override;
232 
233  private:
234  void DoRun() override;
235 };
236 
238  : HashTestCase("Murmur3: ")
239 {
240 }
241 
243 {
244 }
245 
246 void
248 {
249  Hasher hasher = Hasher(Create<Hash::Function::Murmur3>());
250  hash32Reference = 0x463d70e2; // Murmur3(key)
251  Check("murmur3", hasher.clear().GetHash32(key));
252 
253  hash64Reference = 0xa750412079d53e04ULL;
254  Check("murmur3", hasher.clear().GetHash64(key));
255 }
256 
270 uint16_t
271 gnu_sum(const char* buffer, const std::size_t size)
272 {
273  const char* p = buffer;
274  const char* const pend = p + size;
275 
276  uint16_t checksum = 0; /* The checksum mod 2^16. */
277 
278  while (p != pend)
279  {
280  checksum = (checksum >> 1) + ((checksum & 1) << 15); // barrel shift
281  checksum += *p++;
282  }
283  return checksum;
284 }
285 
291 uint32_t
292 gnu_sum32(const char* buffer, const std::size_t size)
293 {
294  uint32_t h = gnu_sum(buffer, size);
295  return (uint32_t)((h << 16) + h);
296 }
297 
303 uint64_t
304 gnu_sum64(const char* buffer, const std::size_t size)
305 {
306  uint64_t h = gnu_sum32(buffer, size);
307  return (uint64_t)((h << 32) + h);
308 }
309 
315 {
316  public:
320  ~Hash32FunctionPtrTestCase() override;
321 
322  private:
323  void DoRun() override;
324 };
325 
327  : HashTestCase("Hash32FunctionPtr: ")
328 {
329 }
330 
332 {
333 }
334 
335 void
337 {
338  Hasher hasher = Hasher(Create<Hash::Function::Hash32>(&gnu_sum32));
339  hash32Reference = 0x41264126; // Hash32FunctionPtr(key)
340  Check("gnu_sum32", hasher.clear().GetHash32(key));
341 }
342 
348 {
349  public:
353  ~Hash64FunctionPtrTestCase() override;
354 
355  private:
356  void DoRun() override;
357 };
358 
360  : HashTestCase("Hash64FunctionPtr: ")
361 {
362 }
363 
365 {
366 }
367 
368 void
370 {
371  Hasher hasher = Hasher(Create<Hash::Function::Hash64>(&gnu_sum64));
372  hash64Reference = 0x4126412641264126ULL; // Hash64FunctionPtr(key)
373  Check("gnu_sum64", hasher.clear().GetHash64(key));
374 }
375 
381 {
382  public:
386  ~IncrementalTestCase() override;
387 
388  private:
389  void DoRun() override;
395  void DoHash(const std::string name, Hasher hasher);
396  std::string key1;
397  std::string key2;
398  std::string key12;
399 };
400 
402  : HashTestCase("Incremental: ")
403 {
404 }
405 
407 {
408 }
409 
410 void
411 IncrementalTestCase::DoHash(const std::string name, Hasher hasher)
412 {
413  hash32Reference = hasher.clear().GetHash32(key12);
414  hasher.clear().GetHash32(key1);
415  Check(name, hasher.GetHash32(key2));
416 
417  hash64Reference = hasher.clear().GetHash64(key12);
418  hasher.clear().GetHash64(key1);
419  Check(name, hasher.GetHash64(key2));
420 }
421 
422 void
424 {
425  key1 = "The quick brown ";
426  key2 = "Incremental.";
427  key12 = key1 + key2;
428 
429  std::cout << GetName() << "checking with key: "
430  << "\"" << key1 << "\"[" << key1.size() << "] + "
431  << "\"" << key2 << "\"[" << key2.size() << "]" << std::endl;
432  std::cout << GetName() << "equivalent to: "
433  << "\"" << key12 << "\"[" << key12.size() << "]" << std::endl;
434 
435  DoHash("default", Hasher());
436  DoHash("murmur3", Hasher(Create<Hash::Function::Murmur3>()));
437  DoHash("FNV1a", Hasher(Create<Hash::Function::Fnv1a>()));
438 }
439 
444 class HashTestSuite : public TestSuite
445 {
446  public:
448  HashTestSuite();
449 };
450 
452  : TestSuite("hash")
453 {
460 }
461 
467 
468 } // namespace tests
469 
470 } // namespace ns3
Generic Hash function interface.
Definition: hash.h:87
uint32_t GetHash32(const char *buffer, const std::size_t size)
Compute 32-bit hash of a byte buffer.
Definition: hash.h:236
uint64_t GetHash64(const char *buffer, const std::size_t size)
Compute 64-bit hash of a byte buffer.
Definition: hash.h:243
Hasher & clear()
Restore initial state.
Definition: hash.cc:56
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
std::string GetName() const
Definition: test.cc:373
A suite of tests to run.
Definition: test.h:1256
Test default hash on fixed string.
void DoRun() override
Implementation to actually run this TestCase.
~DefaultHashTestCase() override
Destructor.
FNV hash on fixed string.
void DoRun() override
Implementation to actually run this TestCase.
~Fnv1aTestCase() override
Destructor.
Test 32-bit function pointer.
void DoRun() override
Implementation to actually run this TestCase.
~Hash32FunctionPtrTestCase() override
Destructor.
Test 64-bit function pointer.
~Hash64FunctionPtrTestCase() override
Destructor.
void DoRun() override
Implementation to actually run this TestCase.
Base class for hash tests.
void DoRun() override
Implementation to actually run this TestCase.
uint64_t hash64Reference
The 64-bit hash of the reference.
uint32_t hash32Reference
The 32-bit hash of the reference.
~HashTestCase() override
Destructor.
HashTestCase(const std::string name)
Constructor.
std::string key
The reference value to hash.
void Check(const std::string hashName, const uint32_t hash)
Check function.
Hash functions test suite.
Test incremental hashing.
void DoRun() override
Implementation to actually run this TestCase.
~IncrementalTestCase() override
Destructor.
void DoHash(const std::string name, Hasher hasher)
Complute the hash test function.
std::string key12
test string
Test Murmur3 hash on fixed string.
void DoRun() override
Implementation to actually run this TestCase.
~Murmur3TestCase() override
Destructor.
uint32_t gnu_sum32(const char *buffer, const std::size_t size)
A 32-bit hash function, based on gnu_sum().
uint64_t gnu_sum64(const char *buffer, const std::size_t size)
A 64-bit hash function, base on gnu_sum().
static HashTestSuite g_hashTestSuite
HashTestSuite instance variable.
uint16_t gnu_sum(const char *buffer, const std::size_t size)
Simple hash function based on the GNU sum program.
uint64_t Hash64(const char *buffer, const std::size_t size)
Compute 64-bit hash of a byte buffer, using the default hash function.
Definition: hash.h:280
uint32_t Hash32(const char *buffer, const std::size_t size)
Compute 32-bit hash of a byte buffer, using the default hash function.
Definition: hash.h:274
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:251
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.h:4680
Every class exported by the ns3 library is enclosed in the ns3 namespace.