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 std;
34
35using namespace ns3;
36
38const std::string suite ("type-id: ");
39
57{
58public:
60 virtual ~UniqueTypeIdTestCase ();
61
62private:
63 virtual void DoRun (void);
64 enum
65 {
66 HashChainFlag = 0x80000000
67 };
68};
69
71 : TestCase ("Check uniqueness of all TypeIds")
72{}
73
75{}
76
77void
79{
80 cout << suite << endl;
81 cout << suite << GetName () << endl;
82
83 // Use same custom hasher as TypeId
84 ns3::Hasher hasher = ns3::Hasher ( Create<Hash::Function::Murmur3> () );
85
86 uint32_t nids = TypeId::GetRegisteredN ();
87
88 cout << suite << "UniqueTypeIdTestCase: nids: " << nids << endl;
89 cout << suite << "TypeId list:" << endl;
90 cout << suite << "TypeId Chain hash Name" << endl;
91
92 for (uint16_t i = 0; i < nids; ++i)
93 {
94 const TypeId tid = TypeId::GetRegistered (i);
95 cout << suite << "" << std::setw (6) << tid.GetUid ();
96 if (tid.GetHash () & HashChainFlag)
97 {
98 cout << " chain";
99 }
100 else
101 {
102 cout << " ";
103 }
104 cout << " 0x" << std::setfill ('0') << std::hex << std::setw (8)
105 << tid.GetHash () << std::dec << std::setfill (' ')
106 << " " << tid.GetName ()
107 << endl;
108
110 TypeId::LookupByName (tid.GetName ()).GetUid (),
111 "LookupByName returned different TypeId for "
112 << tid.GetName ());
113
114 // Mask off HashChainFlag in this test, since tid might have been chained
116 (hasher.clear ().GetHash32 (tid.GetName ()) & (~HashChainFlag)),
117 "TypeId .hash and Hash32 (.name) unequal for "
118 << tid.GetName ());
119
121 TypeId::LookupByHash (tid.GetHash ()).GetUid (),
122 "LookupByHash returned different TypeId for "
123 << tid.GetName ());
124
125 }
126
127 cout << suite << "<-- end TypeId list -->" << endl;
128}
129
130
137{
138public:
140 virtual ~CollisionTestCase ();
141
142private:
143 virtual void DoRun (void);
144 enum
145 {
146 HashChainFlag = 0x80000000
147 };
148};
149
151 : TestCase ("Check behavior when type names collide")
152{}
153
155{}
156
157void
159{
160 cout << suite << endl;
161 cout << suite << GetName () << endl;
162
163 // Register two types whose hashes collide, in alphabetical order
164 // Murmur3 collision from /usr/share/dict/web2
165 string t1Name = "daemon";
166 string t2Name = "unerring";
167 cout << suite << "creating colliding types "
168 << "'" << t1Name << "', '" << t2Name << "'"
169 << " in alphabetical order:"
170 << endl;
171 TypeId t1 (t1Name);
172 TypeId t2 (t2Name);
173
174 // Check that they are alphabetical: t1 name < t2 name
176 "First and lesser TypeId has HashChainFlag set");
177 cout << suite << "collision: first,lesser not chained: OK" << endl;
178
180 "Second and greater TypeId does not have HashChainFlag set");
181 cout << suite << "collision: second,greater chained: OK" << endl;
182
183
184 // Register colliding types in reverse alphabetical order
185 // Murmur3 collision from /usr/share/dict/web2
186 string t3Name = "trigonon";
187 string t4Name = "seriation";
188 cout << suite << "creating colliding types "
189 << "'" << t3Name << "', '" << t4Name << "'"
190 << " in reverse alphabetical order:"
191 << endl;
192 TypeId t3 (t3Name.c_str ());
193 TypeId t4 (t4Name.c_str ());
194
195 // Check that they are alphabetical: t3 name > t4 name
197 "First and greater TypeId does not have HashChainFlag set");
198 cout << suite << "collision: first,greater chained: OK" << endl;
199
201 "Second and lesser TypeId has HashChainFlag set");
202 cout << suite << "collision: second,lesser not chained: OK" << endl;
203
209}
210
211
218{
219private:
220 // float m_obsAttr; // this is obsolete, no trivial forwarding
221 // int m_oldAttr; // this has become m_attr
222 int m_attr;
223
224 // TracedValue<int> m_obsTrace; // this is obsolete, no trivial forwarding
225 // TracedValue<double> m_oldTrace; // this has become m_trace
227
228public:
230 : m_attr (0)
231 {
232 }
234 {}
235
240 static TypeId GetTypeId (void)
241 {
242 static TypeId tid = TypeId ("DeprecatedAttribute")
243 .SetParent<Object> ()
244
245 // The new attribute
246 .AddAttribute ("attribute",
247 "the Attribute",
248 IntegerValue (1),
250 MakeIntegerChecker<int> ())
251 // The old deprecated attribute
252 .AddAttribute ("oldAttribute",
253 "the old attribute",
254 IntegerValue (1),
256 MakeIntegerChecker<int> (),
257 TypeId::DEPRECATED,
258 "use 'attribute' instead")
259 // Obsolete attribute, as an example
260 .AddAttribute ("obsoleteAttribute",
261 "the obsolete attribute",
265 TypeId::OBSOLETE,
266 "refactor to use 'attribute'")
267
268 // The new trace source
269 .AddTraceSource ("trace",
270 "the TraceSource",
272 "ns3::TracedValueCallback::Double")
273 // The old trace source
274 .AddTraceSource ("oldTrace",
275 "the old trace source",
277 "ns3::TracedValueCallback::Double",
278 TypeId::DEPRECATED,
279 "use 'trace' instead")
280 // Obsolete trace source, as an example
281 .AddTraceSource ("obsoleteTraceSource",
282 "the obsolete trace source",
284 "ns3::TracedValueCallback::Void",
285 TypeId::OBSOLETE,
286 "refactor to use 'trace'");
287
288 return tid;
289 }
290
291};
292
293
300{
301public:
304
305private:
306 virtual void DoRun (void);
307
308};
309
311 : TestCase ("Check deprecated Attributes and TraceSources")
312{}
313
315{}
316
317void
319{
320 cerr << suite << endl;
321 cerr << suite << GetName () << endl;
322
324 cerr << suite << "DeprecatedAttribute TypeId: " << tid.GetUid () << endl;
325
326 // Try the lookups
327 struct TypeId::AttributeInformation ainfo;
328 NS_TEST_ASSERT_MSG_EQ (tid.LookupAttributeByName ("attribute", &ainfo), true,
329 "lookup new attribute");
330 cerr << suite << "lookup new attribute:"
331 << (ainfo.supportLevel == TypeId::SUPPORTED ? "supported" : "error")
332 << endl;
333
334 NS_TEST_ASSERT_MSG_EQ (tid.LookupAttributeByName ("oldAttribute", &ainfo), true,
335 "lookup old attribute");
336 cerr << suite << "lookup old attribute:"
337 << (ainfo.supportLevel == TypeId::DEPRECATED ? "deprecated" : "error")
338 << endl;
339
340
343 acc = tid.LookupTraceSourceByName ("trace", &tinfo);
344 NS_TEST_ASSERT_MSG_NE (acc, 0, "lookup new trace source");
345 cerr << suite << "lookup new trace source:"
346 << (tinfo.supportLevel == TypeId::SUPPORTED ? "supported" : "error")
347 << endl;
348
349 acc = tid.LookupTraceSourceByName ("oldTrace", &tinfo);
350 NS_TEST_ASSERT_MSG_NE (acc, 0, "lookup old trace source");
351 cerr << suite << "lookup old trace source:"
352 << (tinfo.supportLevel == TypeId::DEPRECATED ? "deprecated" : "error")
353 << endl;
354}
355
356
363{
364public:
366 virtual ~LookupTimeTestCase ();
367
368private:
369 void DoRun (void);
370 void DoSetup (void);
376 void Report (const std::string how, const uint32_t delta) const;
377
378 enum
379 {
380 REPETITIONS = 100000
381 };
382};
383
385 : TestCase ("Measure average lookup time")
386{}
387
389{}
390
391void
393{
394 cout << suite << endl;
395 cout << suite << GetName () << endl;
396
397 uint32_t nids = TypeId::GetRegisteredN ();
398
399 int start = clock ();
400 for (uint32_t j = 0; j < REPETITIONS; ++j)
401 {
402 for (uint16_t i = 0; i < nids; ++i)
403 {
404 const TypeId tid = TypeId::GetRegistered (i);
405 const TypeId sid = TypeId::LookupByName (tid.GetName ());
406 }
407 }
408 int stop = clock ();
409 Report ("name", stop - start);
410
411 start = clock ();
412 for (uint32_t j = 0; j < REPETITIONS; ++j)
413 {
414 for (uint16_t i = 0; i < nids; ++i)
415 {
416 const TypeId tid = TypeId::GetRegistered (i);
417 const TypeId sid = TypeId::LookupByHash (tid.GetHash ());
418 }
419 }
420 stop = clock ();
421 Report ("hash", stop - start);
422
423}
424
425void
427{
428 uint32_t nids = TypeId::GetRegisteredN ();
429
430 cout << suite << "Lookup time: reps: " << REPETITIONS
431 << ", num TypeId's: " << nids
432 << endl;
433
434}
435
436void
437LookupTimeTestCase::Report (const std::string how,
438 const uint32_t delta) const
439{
440 double nids = TypeId::GetRegisteredN ();
441 double reps = nids * REPETITIONS;
442
443 double per = 1E6 * double(delta) / (reps * double(CLOCKS_PER_SEC));
444
445 cout << suite << "Lookup time: by " << how << ": "
446 << "ticks: " << delta
447 << "\tper: " << per
448 << " microsec/lookup"
449 << endl;
450}
451
452
459{
460public:
462};
463
465 : TestSuite ("type-id", UNIT)
466{
467 // Turn on logging, so we see the result of collisions
469
470 // If the CollisionTestCase is performed before the
471 // UniqueIdTestCase, the artificial collisions added by
472 // CollisionTestCase will show up in the list of TypeIds
473 // as chained.
477}
478
481
482
489{
490public:
492};
493
495 : TestSuite ("type-id-perf", PERFORMANCE)
496{
498}
499
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:74
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:94
@ LOG_PREFIX_FUNC
Prefix all trace prints with function.
Definition: log.h:118
@ LOG_ERROR
Serious error messages only.
Definition: log.h:97
void LogComponentEnable(char const *name, enum LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:361
STL namespace.
def start()
Definition: core.py:1853
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: ")
Const string used to build the test name.
static TypeIdTestSuite g_TypeIdTestSuite
Static variable for test initialization.
static TypeIdPerformanceSuite g_TypeIdPerformanceSuite
Static variable for test initialization.