A Discrete-Event Network Simulator
API
type-id-test-suite.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2012 Lawrence Livermore National Laboratory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Peter D. Barnes, Jr. <pdbarnes@llnl.gov>
19 */
20
21#include <iostream>
22#include <iomanip>
23#include <ctime>
24
25#include "ns3/integer.h"
26#include "ns3/double.h"
27#include "ns3/object.h"
28#include "ns3/traced-value.h"
29#include "ns3/type-id.h"
30#include "ns3/test.h"
31#include "ns3/log.h"
32
33using namespace ns3;
34
36const std::string suite ("type-id: ");
37
55{
56public:
58 virtual ~UniqueTypeIdTestCase ();
59
60private:
61 virtual void DoRun (void);
62 enum
63 {
64 HashChainFlag = 0x80000000
65 };
66};
67
69 : TestCase ("Check uniqueness of all TypeIds")
70{}
71
73{}
74
75void
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 uint32_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 () & HashChainFlag)
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)
103 << tid.GetHash () << std::dec << std::setfill (' ')
104 << " " << tid.GetName ()
105 << std::endl;
106
108 TypeId::LookupByName (tid.GetName ()).GetUid (),
109 "LookupByName returned different TypeId for "
110 << tid.GetName ());
111
112 // Mask off HashChainFlag in this test, since tid might have been chained
114 (hasher.clear ().GetHash32 (tid.GetName ()) & (~HashChainFlag)),
115 "TypeId .hash and Hash32 (.name) unequal for "
116 << tid.GetName ());
117
119 TypeId::LookupByHash (tid.GetHash ()).GetUid (),
120 "LookupByHash returned different TypeId for "
121 << tid.GetName ());
122
123 }
124
125 std::cout << suite << "<-- end TypeId list -->" << std::endl;
126}
127
128
135{
136public:
138 virtual ~CollisionTestCase ();
139
140private:
141 virtual void DoRun (void);
142 enum
143 {
144 HashChainFlag = 0x80000000
145 };
146};
147
149 : TestCase ("Check behavior when type names collide")
150{}
151
153{}
154
155void
157{
158 std::cout << suite << std::endl;
159 std::cout << suite << GetName () << std::endl;
160
161 // Register two types whose hashes collide, in alphabetical order
162 // Murmur3 collision from /usr/share/dict/web2
163 std::string t1Name = "daemon";
164 std::string t2Name = "unerring";
165 std::cout << suite << "creating colliding types "
166 << "'" << t1Name << "', '" << t2Name << "'"
167 << " in alphabetical order:"
168 << std::endl;
169 TypeId t1 (t1Name);
170 TypeId t2 (t2Name);
171
172 // Check that they are alphabetical: t1 name < t2 name
174 "First and lesser TypeId has HashChainFlag set");
175 std::cout << suite << "collision: first,lesser not chained: OK" << std::endl;
176
178 "Second and greater TypeId does not have HashChainFlag set");
179 std::cout << suite << "collision: second,greater chained: OK" << std::endl;
180
181
182 // Register colliding types in reverse alphabetical order
183 // Murmur3 collision from /usr/share/dict/web2
184 std::string t3Name = "trigonon";
185 std::string t4Name = "seriation";
186 std::cout << suite << "creating colliding types "
187 << "'" << t3Name << "', '" << t4Name << "'"
188 << " in reverse alphabetical order:"
189 << std::endl;
190 TypeId t3 (t3Name.c_str ());
191 TypeId t4 (t4Name.c_str ());
192
193 // Check that they are alphabetical: t3 name > t4 name
195 "First and greater TypeId does not have HashChainFlag set");
196 std::cout << suite << "collision: first,greater chained: OK" << std::endl;
197
199 "Second and lesser TypeId has HashChainFlag set");
200 std::cout << suite << "collision: second,lesser not chained: OK" << std::endl;
201
207}
208
209
216{
217private:
218 // float m_obsAttr; // this is obsolete, no trivial forwarding
219 // int m_oldAttr; // this has become m_attr
220 int m_attr;
221
222 // TracedValue<int> m_obsTrace; // this is obsolete, no trivial forwarding
223 // TracedValue<double> m_oldTrace; // this has become m_trace
225
226public:
228 : m_attr (0)
229 {
230 }
232 {}
233
238 static TypeId GetTypeId (void)
239 {
240 static TypeId tid = TypeId ("DeprecatedAttribute")
241 .SetParent<Object> ()
242
243 // The new attribute
244 .AddAttribute ("attribute",
245 "the Attribute",
246 IntegerValue (1),
248 MakeIntegerChecker<int> ())
249 // The old deprecated attribute
250 .AddAttribute ("oldAttribute",
251 "the old attribute",
252 IntegerValue (1),
254 MakeIntegerChecker<int> (),
255 TypeId::DEPRECATED,
256 "use 'attribute' instead")
257 // Obsolete attribute, as an example
258 .AddAttribute ("obsoleteAttribute",
259 "the obsolete attribute",
263 TypeId::OBSOLETE,
264 "refactor to use 'attribute'")
265
266 // The new trace source
267 .AddTraceSource ("trace",
268 "the TraceSource",
270 "ns3::TracedValueCallback::Double")
271 // The old trace source
272 .AddTraceSource ("oldTrace",
273 "the old trace source",
275 "ns3::TracedValueCallback::Double",
276 TypeId::DEPRECATED,
277 "use 'trace' instead")
278 // Obsolete trace source, as an example
279 .AddTraceSource ("obsoleteTraceSource",
280 "the obsolete trace source",
282 "ns3::TracedValueCallback::Void",
283 TypeId::OBSOLETE,
284 "refactor to use 'trace'");
285
286 return tid;
287 }
288
289};
290
291
298{
299public:
302
303private:
304 virtual void DoRun (void);
305
306};
307
309 : TestCase ("Check deprecated Attributes and TraceSources")
310{}
311
313{}
314
315void
317{
318 std::cerr << suite << std::endl;
319 std::cerr << suite << GetName () << std::endl;
320
322 std::cerr << suite << "DeprecatedAttribute TypeId: " << tid.GetUid () << std::endl;
323
324 // Try the lookups
325 struct TypeId::AttributeInformation ainfo;
326 NS_TEST_ASSERT_MSG_EQ (tid.LookupAttributeByName ("attribute", &ainfo), true,
327 "lookup new attribute");
328 std::cerr << suite << "lookup new attribute:"
329 << (ainfo.supportLevel == TypeId::SUPPORTED ? "supported" : "error")
330 << std::endl;
331
332 NS_TEST_ASSERT_MSG_EQ (tid.LookupAttributeByName ("oldAttribute", &ainfo), true,
333 "lookup old attribute");
334 std::cerr << suite << "lookup old attribute:"
335 << (ainfo.supportLevel == TypeId::DEPRECATED ? "deprecated" : "error")
336 << std::endl;
337
338
341 acc = tid.LookupTraceSourceByName ("trace", &tinfo);
342 NS_TEST_ASSERT_MSG_NE (acc, nullptr, "lookup new trace source");
343 std::cerr << suite << "lookup new trace source:"
344 << (tinfo.supportLevel == TypeId::SUPPORTED ? "supported" : "error")
345 << std::endl;
346
347 acc = tid.LookupTraceSourceByName ("oldTrace", &tinfo);
348 NS_TEST_ASSERT_MSG_NE (acc, nullptr, "lookup old trace source");
349 std::cerr << suite << "lookup old trace source:"
350 << (tinfo.supportLevel == TypeId::DEPRECATED ? "deprecated" : "error")
351 << std::endl;
352}
353
354
361{
362public:
364 virtual ~LookupTimeTestCase ();
365
366private:
367 void DoRun (void);
368 void DoSetup (void);
374 void Report (const std::string how, const uint32_t delta) const;
375
376 enum
377 {
378 REPETITIONS = 100000
379 };
380};
381
383 : TestCase ("Measure average lookup time")
384{}
385
387{}
388
389void
391{
392 std::cout << suite << std::endl;
393 std::cout << suite << GetName () << std::endl;
394
395 uint32_t nids = TypeId::GetRegisteredN ();
396
397 int start = clock ();
398 for (uint32_t j = 0; j < REPETITIONS; ++j)
399 {
400 for (uint16_t i = 0; i < nids; ++i)
401 {
402 const TypeId tid = TypeId::GetRegistered (i);
403 const TypeId sid = TypeId::LookupByName (tid.GetName ());
404 }
405 }
406 int stop = clock ();
407 Report ("name", stop - start);
408
409 start = clock ();
410 for (uint32_t j = 0; j < REPETITIONS; ++j)
411 {
412 for (uint16_t i = 0; i < nids; ++i)
413 {
414 const TypeId tid = TypeId::GetRegistered (i);
415 const TypeId sid = TypeId::LookupByHash (tid.GetHash ());
416 }
417 }
418 stop = clock ();
419 Report ("hash", stop - start);
420
421}
422
423void
425{
426 uint32_t nids = TypeId::GetRegisteredN ();
427
428 std::cout << suite << "Lookup time: reps: " << REPETITIONS
429 << ", num TypeId's: " << nids
430 << std::endl;
431
432}
433
434void
435LookupTimeTestCase::Report (const std::string how,
436 const uint32_t delta) const
437{
438 double nids = TypeId::GetRegisteredN ();
439 double reps = nids * REPETITIONS;
440
441 double per = 1E6 * double(delta) / (reps * double(CLOCKS_PER_SEC));
442
443 std::cout << suite << "Lookup time: by " << how << ": "
444 << "ticks: " << delta
445 << "\tper: " << per
446 << " microsec/lookup"
447 << std::endl;
448}
449
450
457{
458public:
460};
461
463 : TestSuite ("type-id", UNIT)
464{
465 // Turn on logging, so we see the result of collisions
467
468 // If the CollisionTestCase is performed before the
469 // UniqueIdTestCase, the artificial collisions added by
470 // CollisionTestCase will show up in the list of TypeIds
471 // as chained.
475}
476
479
480
487{
488public:
490};
491
493 : TestSuite ("type-id-perf", PERFORMANCE)
494{
496}
497
virtual void DoRun(void)
Implementation to actually run this TestCase.
Class used to test deprecated Attributes.
static TypeId GetTypeId(void)
Get the type ID.
int m_attr
An attribute to test deprecation.
TracedValue< double > m_trace
A TracedValue to test deprecation.
Check deprecated Attributes and TraceSources.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Performance test: measure average lookup time.
void DoSetup(void)
Implementation to do any local setup required for this TestCase.
void Report(const std::string how, const uint32_t delta) const
Report the performance test results.
void DoRun(void)
Implementation to actually run this TestCase.
TypeId performance test suites.
TypeId test suites.
Test for uniqueness of all TypeIds.
virtual void DoRun(void)
Implementation to actually run this TestCase.
A class for an empty attribute value.
Definition: attribute.h:233
Generic Hash function interface.
Definition: hash.h:88
uint32_t GetHash32(const char *buffer, const std::size_t size)
Compute 32-bit hash of a byte buffer.
Definition: hash.h:239
Hasher & clear(void)
Restore initial state.
Definition: hash.cc:55
Hold a signed integer type.
Definition: integer.h:44
A base class which provides memory management and object aggregation.
Definition: object.h:88
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
encapsulates test code
Definition: test.h:994
@ QUICK
Fast test.
Definition: test.h:999
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
std::string GetName(void) const
Definition: test.cc:370
A suite of tests to run.
Definition: test.h:1188
a unique identifier for an interface.
Definition: type-id.h:59
uint16_t GetUid(void) const
Get the internal id of this TypeId.
Definition: type-id.cc:1184
hash_t GetHash(void) const
Get the hash.
Definition: type-id.cc:984
Ptr< const TraceSourceAccessor > LookupTraceSourceByName(std::string name) const
Find a TraceSource by name.
Definition: type-id.cc:1177
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
std::string GetName(void) const
Get the name.
Definition: type-id.cc:976
bool LookupAttributeByName(std::string name, struct AttributeInformation *info) const
Find an Attribute by name, retrieving the associated AttributeInformation.
Definition: type-id.cc:882
Ptr< const AttributeAccessor > MakeIntegerAccessor(T1 a1)
Definition: integer.h:45
static Ptr< AttributeChecker > MakeEmptyAttributeChecker()
Create an empty AttributeChecker.
Definition: attribute.h:317
static Ptr< const AttributeAccessor > MakeEmptyAttributeAccessor()
Create an empty AttributeAccessor.
Definition: attribute.h:285
#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:141
#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:542
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.
LogLevel
Logging severity classes and levels.
Definition: log.h:95
@ LOG_PREFIX_FUNC
Prefix all trace prints with function.
Definition: log.h:119
@ LOG_ERROR
Serious error messages only.
Definition: log.h:98
void LogComponentEnable(char const *name, enum LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:361
def start()
Definition: core.py:1852
Attribute implementation.
Definition: type-id.h:78
TypeId::SupportLevel supportLevel
Support level/deprecation.
Definition: type-id.h:94
TraceSource implementation.
Definition: type-id.h:100
TypeId::SupportLevel supportLevel
Support level/deprecation.
Definition: type-id.h:110
const std::string suite("type-id: ")
static TypeIdTestSuite g_TypeIdTestSuite
Static variable for test initialization.
static TypeIdPerformanceSuite g_TypeIdPerformanceSuite
Static variable for test initialization.