A Discrete-Event Network Simulator
QKDNetSim v2.0 (NS-3 v3.41) @ (+)
API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
type-id-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/double.h"
21 #include "ns3/integer.h"
22 #include "ns3/log.h"
23 #include "ns3/object.h"
24 #include "ns3/test.h"
25 #include "ns3/traced-value.h"
26 #include "ns3/type-id.h"
27 
28 #include <ctime>
29 #include <iomanip>
30 #include <iostream>
31 
32 using namespace ns3;
33 
35 const std::string suite("type-id: ");
36 
54 {
55  public:
57  ~UniqueTypeIdTestCase() override;
58 
59  private:
60  void DoRun() override;
61 
63  static constexpr auto HASH_CHAIN_FLAG{0x80000000};
64 };
65 
67  : TestCase("Check uniqueness of all TypeIds")
68 {
69 }
70 
72 {
73 }
74 
75 void
77 {
78  std::cout << suite << std::endl;
79  std::cout << suite << GetName() << std::endl;
80 
81  // Use same custom hasher as TypeId
82  ns3::Hasher hasher = ns3::Hasher(Create<Hash::Function::Murmur3>());
83 
84  uint16_t nids = TypeId::GetRegisteredN();
85 
86  std::cout << suite << "UniqueTypeIdTestCase: nids: " << nids << std::endl;
87  std::cout << suite << "TypeId list:" << std::endl;
88  std::cout << suite << "TypeId Chain hash Name" << std::endl;
89 
90  for (uint16_t i = 0; i < nids; ++i)
91  {
92  const TypeId tid = TypeId::GetRegistered(i);
93  std::cout << suite << "" << std::setw(6) << tid.GetUid();
94  if (tid.GetHash() & HASH_CHAIN_FLAG)
95  {
96  std::cout << " chain";
97  }
98  else
99  {
100  std::cout << " ";
101  }
102  std::cout << " 0x" << std::setfill('0') << std::hex << std::setw(8) << tid.GetHash()
103  << std::dec << std::setfill(' ') << " " << tid.GetName() << std::endl;
104 
106  TypeId::LookupByName(tid.GetName()).GetUid(),
107  "LookupByName returned different TypeId for " << tid.GetName());
108 
109  // Mask off HASH_CHAIN_FLAG in this test, since tid might have been chained
111  (hasher.clear().GetHash32(tid.GetName()) & (~HASH_CHAIN_FLAG)),
112  "TypeId .hash and Hash32 (.name) unequal for " << tid.GetName());
113 
115  TypeId::LookupByHash(tid.GetHash()).GetUid(),
116  "LookupByHash returned different TypeId for " << tid.GetName());
117  }
118 
119  std::cout << suite << "<-- end TypeId list -->" << std::endl;
120 }
121 
128 {
129  public:
131  ~CollisionTestCase() override;
132 
133  private:
134  void DoRun() override;
135 
137  static constexpr auto HASH_CHAIN_FLAG{0x80000000};
138 };
139 
141  : TestCase("Check behavior when type names collide")
142 {
143 }
144 
146 {
147 }
148 
149 void
151 {
152  std::cout << suite << std::endl;
153  std::cout << suite << GetName() << std::endl;
154 
155  // Register two types whose hashes collide, in alphabetical order
156  // Murmur3 collision from /usr/share/dict/web2
157  std::string t1Name = "daemon";
158  std::string t2Name = "unerring";
159  std::cout << suite << "creating colliding types "
160  << "'" << t1Name << "', '" << t2Name << "'"
161  << " in alphabetical order:" << std::endl;
162  TypeId t1(t1Name);
163  TypeId t2(t2Name);
164 
165  // Check that they are alphabetical: t1 name < t2 name
167  0,
168  "First and lesser TypeId has HASH_CHAIN_FLAG set");
169  std::cout << suite << "collision: first,lesser not chained: OK" << std::endl;
170 
172  0,
173  "Second and greater TypeId does not have HASH_CHAIN_FLAG set");
174  std::cout << suite << "collision: second,greater chained: OK" << std::endl;
175 
176  // Register colliding types in reverse alphabetical order
177  // Murmur3 collision from /usr/share/dict/web2
178  std::string t3Name = "trigonon";
179  std::string t4Name = "seriation";
180  std::cout << suite << "creating colliding types "
181  << "'" << t3Name << "', '" << t4Name << "'"
182  << " in reverse alphabetical order:" << std::endl;
183  TypeId t3(t3Name);
184  TypeId t4(t4Name);
185 
186  // Check that they are alphabetical: t3 name > t4 name
188  0,
189  "First and greater TypeId does not have HASH_CHAIN_FLAG set");
190  std::cout << suite << "collision: first,greater chained: OK" << std::endl;
191 
193  0,
194  "Second and lesser TypeId has HASH_CHAIN_FLAG set");
195  std::cout << suite << "collision: second,lesser not chained: OK" << std::endl;
196 
201 }
202 
209 {
210  private:
211  // float m_obsAttr; // this is obsolete, no trivial forwarding
212  // int m_oldAttr; // this has become m_attr
213  int m_attr;
214 
215  // TracedValue<int> m_obsTrace; // this is obsolete, no trivial forwarding
216  // TracedValue<double> m_oldTrace; // this has become m_trace
218 
219  public:
221  : m_attr(0)
222  {
223  }
224 
226  {
227  }
228 
233  static TypeId GetTypeId()
234  {
235  static TypeId tid =
236  TypeId("DeprecatedAttribute")
237  .SetParent<Object>()
238 
239  // The new attribute
240  .AddAttribute("attribute",
241  "the Attribute",
242  IntegerValue(1),
244  MakeIntegerChecker<int>())
245  // The old deprecated attribute
246  .AddAttribute("oldAttribute",
247  "the old attribute",
248  IntegerValue(1),
250  MakeIntegerChecker<int>(),
251  TypeId::DEPRECATED,
252  "use 'attribute' instead")
253  // Obsolete attribute, as an example
254  .AddAttribute("obsoleteAttribute",
255  "the obsolete attribute",
259  TypeId::OBSOLETE,
260  "refactor to use 'attribute'")
261 
262  // The new trace source
263  .AddTraceSource("trace",
264  "the TraceSource",
266  "ns3::TracedValueCallback::Double")
267  // The old trace source
268  .AddTraceSource("oldTrace",
269  "the old trace source",
271  "ns3::TracedValueCallback::Double",
272  TypeId::DEPRECATED,
273  "use 'trace' instead")
274  // Obsolete trace source, as an example
275  .AddTraceSource("obsoleteTraceSource",
276  "the obsolete trace source",
278  "ns3::TracedValueCallback::Void",
279  TypeId::OBSOLETE,
280  "refactor to use 'trace'");
281 
282  return tid;
283  }
284 };
285 
292 {
293  public:
295  ~DeprecatedAttributeTestCase() override;
296 
297  private:
298  void DoRun() override;
299 };
300 
302  : TestCase("Check deprecated Attributes and TraceSources")
303 {
304 }
305 
307 {
308 }
309 
310 void
312 {
313  std::cerr << suite << std::endl;
314  std::cerr << suite << GetName() << std::endl;
315 
317  std::cerr << suite << "DeprecatedAttribute TypeId: " << tid.GetUid() << std::endl;
318 
319  // Try the lookups
321  NS_TEST_ASSERT_MSG_EQ(tid.LookupAttributeByName("attribute", &ainfo),
322  true,
323  "lookup new attribute");
324  std::cerr << suite << "lookup new attribute:"
325  << (ainfo.supportLevel == TypeId::SUPPORTED ? "supported" : "error") << std::endl;
326 
327  NS_TEST_ASSERT_MSG_EQ(tid.LookupAttributeByName("oldAttribute", &ainfo),
328  true,
329  "lookup old attribute");
330  std::cerr << suite << "lookup old attribute:"
331  << (ainfo.supportLevel == TypeId::DEPRECATED ? "deprecated" : "error") << std::endl;
332 
335  acc = tid.LookupTraceSourceByName("trace", &tinfo);
336  NS_TEST_ASSERT_MSG_NE(acc, nullptr, "lookup new trace source");
337  std::cerr << suite << "lookup new trace source:"
338  << (tinfo.supportLevel == TypeId::SUPPORTED ? "supported" : "error") << std::endl;
339 
340  acc = tid.LookupTraceSourceByName("oldTrace", &tinfo);
341  NS_TEST_ASSERT_MSG_NE(acc, nullptr, "lookup old trace source");
342  std::cerr << suite << "lookup old trace source:"
343  << (tinfo.supportLevel == TypeId::DEPRECATED ? "deprecated" : "error") << std::endl;
344 }
345 
352 {
353  public:
355  ~LookupTimeTestCase() override;
356 
357  private:
358  void DoRun() override;
359  void DoSetup() override;
365  void Report(const std::string how, const uint32_t delta) const;
366 
368  static constexpr uint32_t REPETITIONS{100000};
369 };
370 
372  : TestCase("Measure average lookup time")
373 {
374 }
375 
377 {
378 }
379 
380 void
382 {
383  std::cout << suite << std::endl;
384  std::cout << suite << GetName() << std::endl;
385 
386  uint16_t nids = TypeId::GetRegisteredN();
387 
388  int start = clock();
389  for (uint32_t j = 0; j < REPETITIONS; ++j)
390  {
391  for (uint16_t i = 0; i < nids; ++i)
392  {
393  const TypeId tid = TypeId::GetRegistered(i);
394  const TypeId sid [[maybe_unused]] = TypeId::LookupByName(tid.GetName());
395  }
396  }
397  int stop = clock();
398  Report("name", stop - start);
399 
400  start = clock();
401  for (uint32_t j = 0; j < REPETITIONS; ++j)
402  {
403  for (uint16_t i = 0; i < nids; ++i)
404  {
405  const TypeId tid = TypeId::GetRegistered(i);
406  const TypeId sid [[maybe_unused]] = TypeId::LookupByHash(tid.GetHash());
407  }
408  }
409  stop = clock();
410  Report("hash", stop - start);
411 }
412 
413 void
415 {
416  uint32_t nids = TypeId::GetRegisteredN();
417 
418  std::cout << suite << "Lookup time: reps: " << REPETITIONS << ", num TypeId's: " << nids
419  << std::endl;
420 }
421 
422 void
423 LookupTimeTestCase::Report(const std::string how, const uint32_t delta) const
424 {
425  double nids = TypeId::GetRegisteredN();
426  double reps = nids * REPETITIONS;
427 
428  double per = 1E6 * double(delta) / (reps * double(CLOCKS_PER_SEC));
429 
430  std::cout << suite << "Lookup time: by " << how << ": "
431  << "ticks: " << delta << "\tper: " << per << " microsec/lookup" << std::endl;
432 }
433 
440 {
441  public:
442  TypeIdTestSuite();
443 };
444 
446  : TestSuite("type-id", UNIT)
447 {
448  // Turn on logging, so we see the result of collisions
450 
451  // If the CollisionTestCase is performed before the
452  // UniqueIdTestCase, the artificial collisions added by
453  // CollisionTestCase will show up in the list of TypeIds
454  // as chained.
458 }
459 
462 
469 {
470  public:
472 };
473 
475  : TestSuite("type-id-perf", PERFORMANCE)
476 {
478 }
479 
void DoRun() override
Implementation to actually run this TestCase.
static constexpr auto HASH_CHAIN_FLAG
Hash chaining flag, copied from type-id.cc:IidManager.
Class used to test deprecated Attributes.
int m_attr
An attribute to test deprecation.
static TypeId GetTypeId()
Get the type ID.
TracedValue< double > m_trace
A TracedValue to test deprecation.
Check deprecated Attributes and TraceSources.
void DoRun() override
Implementation to actually run this TestCase.
Performance test: measure average lookup time.
static constexpr uint32_t REPETITIONS
Number of repetitions.
void Report(const std::string how, const uint32_t delta) const
Report the performance test results.
void DoRun() override
Implementation to actually run this TestCase.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
TypeId performance test suites.
TypeId test suites.
Test for uniqueness of all TypeIds.
static constexpr auto HASH_CHAIN_FLAG
Hash chaining flag, copied from type-id.cc:IidManager.
void DoRun() override
Implementation to actually run this TestCase.
A class for an empty attribute value.
Definition: attribute.h:234
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
Hasher & clear()
Restore initial state.
Definition: hash.cc:56
Hold a signed integer type.
Definition: integer.h:45
A base class which provides memory management and object aggregation.
Definition: object.h:89
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
encapsulates test code
Definition: test.h:1060
@ QUICK
Fast test.
Definition: test.h:1065
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
a unique identifier for an interface.
Definition: type-id.h:59
hash_t GetHash() const
Get the hash.
Definition: type-id.cc:999
Ptr< const TraceSourceAccessor > LookupTraceSourceByName(std::string name) const
Find a TraceSource by name.
Definition: type-id.cc:1198
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
uint16_t GetUid() const
Get the internal id of this TypeId.
Definition: type-id.cc:1205
bool LookupAttributeByName(std::string name, AttributeInformation *info) const
Find an Attribute by name, retrieving the associated AttributeInformation.
Definition: type-id.cc:893
std::string GetName() const
Get the name.
Definition: type-id.cc:991
static Ptr< AttributeChecker > MakeEmptyAttributeChecker()
Create an empty AttributeChecker.
Definition: attribute.h:318
static Ptr< const AttributeAccessor > MakeEmptyAttributeAccessor()
Create an empty AttributeAccessor.
Definition: attribute.h:286
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report and abort if not.
Definition: test.h:564
static Ptr< const TraceSourceAccessor > MakeEmptyTraceSourceAccessor()
Create an empty TraceSourceAccessor.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:302
Ptr< const AttributeAccessor > MakeIntegerAccessor(T1 a1)
Definition: integer.h:46
LogLevel
Logging severity classes and levels.
Definition: log.h:94
@ LOG_PREFIX_FUNC
Prefix all trace prints with function.
Definition: log.h:118
@ LOG_ERROR
Serious error messages only.
Definition: log.h:97
Attribute implementation.
Definition: type-id.h:81
TypeId::SupportLevel supportLevel
Support level/deprecation.
Definition: type-id.h:97
TraceSource implementation.
Definition: type-id.h:104
const std::string suite("type-id: ")
static TypeIdTestSuite g_TypeIdTestSuite
Static variable for test initialization.
static TypeIdPerformanceSuite g_TypeIdPerformanceSuite
Static variable for test initialization.