A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
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/type-id.h"
26
#include "ns3/test.h"
27
#include "ns3/log.h"
28
29
using namespace
std;
30
31
namespace
ns3 {
32
33
34
const
std::string
suite
(
"type-id: "
);
35
36
//----------------------------
37
//
38
// Test for uniqueness of all TypeIds
39
40
class
UniqueTypeIdTestCase
:
public
TestCase
41
{
42
public
:
43
UniqueTypeIdTestCase
();
44
virtual
~
UniqueTypeIdTestCase
();
45
private
:
46
virtual
void
DoRun (
void
);
47
enum
{ HashChainFlag = 0x80000000};
48
};
49
50
UniqueTypeIdTestCase::UniqueTypeIdTestCase ()
51
:
TestCase
(
"Check uniqueness of all TypeIds"
)
52
{
53
}
54
55
UniqueTypeIdTestCase::~UniqueTypeIdTestCase
()
56
{
57
}
58
59
void
60
UniqueTypeIdTestCase::DoRun
(
void
)
61
{
62
cout <<
suite
<< endl;
63
cout <<
suite
<<
GetName
() << endl;
64
65
// Use same custom hasher as TypeId
66
ns3::Hasher
hasher =
ns3::Hasher
( Create<Hash::Function::Murmur3> () );
67
68
uint32_t nids =
TypeId::GetRegisteredN
();
69
70
cout <<
suite
<<
"UniqueTypeIdTestCase: nids: "
<< nids << endl;
71
cout <<
suite
<<
"TypeId list:"
<< endl;
72
cout <<
suite
<<
"TypeId Chain hash Name"
<< endl;
73
74
for
(uint32_t i = 0; i < nids; ++i)
75
{
76
const
TypeId
tid =
TypeId::GetRegistered
(i);
77
cout <<
suite
<<
""
<< std::setw(6) << tid.
GetUid
();
78
if
(tid.
GetHash
() &
HashChainFlag
)
79
{
80
cout <<
" chain"
;
81
}
82
else
83
{
84
cout <<
" "
;
85
}
86
cout <<
" 0x"
<< std::setfill (
'0'
) << std::hex << std::setw (8)
87
<< tid.
GetHash
() << std::dec << std::setfill (
' '
)
88
<<
" "
<< tid.
GetName
()
89
<< endl;
90
91
NS_TEST_ASSERT_MSG_EQ
(tid.
GetUid
(),
92
TypeId::LookupByName
(tid.
GetName
()).GetUid (),
93
"LookupByName returned different TypeId for "
94
<< tid.
GetName
());
95
96
// Mask off HashChainFlag in this test, since tid might have been chained
97
NS_TEST_ASSERT_MSG_EQ
((tid.
GetHash
() & (~
HashChainFlag
)),
98
(hasher.
clear
().
GetHash32
(tid.
GetName
()) & (~
HashChainFlag
)),
99
"TypeId .hash and Hash32 (.name) unequal for "
100
<< tid.
GetName
());
101
102
NS_TEST_ASSERT_MSG_EQ
(tid.
GetUid
(),
103
TypeId::LookupByHash
(tid.
GetHash
()).GetUid (),
104
"LookupByHash returned different TypeId for "
105
<< tid.
GetName
());
106
107
}
108
109
cout <<
suite
<<
"<-- end TypeId list -->"
<< endl;
110
}
111
112
113
//----------------------------
114
//
115
// Collision test
116
117
class
CollisionTestCase
:
public
TestCase
118
{
119
public
:
120
CollisionTestCase
();
121
virtual
~CollisionTestCase
();
122
private
:
123
virtual
void
DoRun
(
void
);
124
enum
{
HashChainFlag
= 0x80000000};
125
};
126
127
CollisionTestCase::CollisionTestCase
()
128
:
TestCase
(
"Check behavour when type names collide"
)
129
{
130
}
131
132
CollisionTestCase::~CollisionTestCase
()
133
{
134
}
135
136
void
137
CollisionTestCase::DoRun
(
void
)
138
{
139
cout <<
suite
<< endl;
140
cout <<
suite
<<
GetName
() << endl;
141
142
// Register two types whose hashes collide, in alphabetical order
143
// Murmur3 collision from /usr/share/dict/web2
144
string
t1Name =
"daemon"
;
145
string
t2Name =
"unerring"
;
146
cout <<
suite
<<
"creating colliding types "
147
<<
"'"
<< t1Name <<
"', '"
<< t2Name <<
"'"
148
<<
" in alphabetical order:"
149
<< endl;
150
TypeId
t1 (t1Name.c_str ());
151
TypeId
t2 (t2Name.c_str ());
152
153
// Check that they are alphabetical: t1 name < t2 name
154
NS_TEST_ASSERT_MSG_EQ
( (t1.GetHash () &
HashChainFlag
), 0,
155
"First and lesser TypeId has HashChainFlag set"
);
156
cout <<
suite
<<
"collision: first,lesser not chained: OK"
<< endl;
157
158
NS_TEST_ASSERT_MSG_NE
( (t2.GetHash () &
HashChainFlag
), 0,
159
"Second and greater TypeId does not have HashChainFlag set"
);
160
cout <<
suite
<<
"collision: second,greater chained: OK"
<< endl;
161
162
163
// Register colliding types in reverse alphabetical order
164
// Murmur3 collision from /usr/share/dict/web2
165
string
t3Name =
"trigonon"
;
166
string
t4Name =
"seriation"
;
167
cout <<
suite
<<
"creating colliding types "
168
<<
"'"
<< t3Name <<
"', '"
<< t4Name <<
"'"
169
<<
" in reverse alphabetical order:"
170
<< endl;
171
TypeId
t3 (t3Name.c_str ());
172
TypeId
t4 (t4Name.c_str ());
173
174
// Check that they are alphabetical: t3 name > t4 name
175
NS_TEST_ASSERT_MSG_NE
( (t3.GetHash () &
HashChainFlag
), 0,
176
"First and greater TypeId does not have HashChainFlag set"
);
177
cout <<
suite
<<
"collision: first,greater chained: OK"
<< endl;
178
179
NS_TEST_ASSERT_MSG_EQ
( (t4.GetHash () &
HashChainFlag
), 0,
180
"Second and lesser TypeId has HashChainFlag set"
);
181
cout <<
suite
<<
"collision: second,lesser not chained: OK"
<< endl;
182
188
}
189
190
191
//----------------------------
192
//
193
// Performance test
194
195
class
LookupTimeTestCase
:
public
TestCase
196
{
197
public
:
198
LookupTimeTestCase
();
199
virtual
~LookupTimeTestCase
();
200
private
:
201
void
DoRun
(
void
);
202
void
DoSetup
(
void
);
203
void
Report
(
const
std::string how,
const
uint32_t delta)
const
;
204
205
enum
{
REPETITIONS
= 100000 };
206
};
207
208
LookupTimeTestCase::LookupTimeTestCase
()
209
:
TestCase
(
"Measure average lookup time"
)
210
{
211
}
212
213
LookupTimeTestCase::~LookupTimeTestCase
()
214
{
215
}
216
217
void
218
LookupTimeTestCase::DoRun
(
void
)
219
{
220
cout <<
suite
<< endl;
221
cout <<
suite
<<
GetName
() << endl;
222
223
uint32_t nids =
TypeId::GetRegisteredN
();
224
225
int
start
= clock ();
226
for
(uint32_t j = 0; j <
REPETITIONS
; ++j)
227
{
228
for
(uint32_t i = 0; i < nids; ++i)
229
{
230
const
TypeId
tid =
TypeId::GetRegistered
(i);
231
const
TypeId
sid =
TypeId::LookupByName
(tid.
GetName
());
232
}
233
}
234
int
stop = clock ();
235
Report
(
"name"
, stop - start);
236
237
start = clock ();
238
for
(uint32_t j = 0; j <
REPETITIONS
; ++j)
239
{
240
for
(uint32_t i = 0; i < nids; ++i)
241
{
242
const
TypeId
tid =
TypeId::GetRegistered
(i);
243
const
TypeId
sid =
TypeId::LookupByHash
(tid.
GetHash
());
244
}
245
}
246
stop = clock ();
247
Report
(
"hash"
, stop - start);
248
249
}
250
251
void
252
LookupTimeTestCase::DoSetup
(
void
)
253
{
254
uint32_t nids =
TypeId::GetRegisteredN
();
255
256
cout <<
suite
<<
"Lookup time: reps: "
<<
REPETITIONS
257
<<
", num TypeId's: "
<< nids
258
<< endl;
259
260
}
261
262
void
263
LookupTimeTestCase::Report
(
const
std::string how,
264
const
uint32_t delta)
const
265
{
266
double
nids =
TypeId::GetRegisteredN
();
267
double
reps = nids *
REPETITIONS
;
268
269
double
per = 1E6 * double(delta) / (reps * double(CLOCKS_PER_SEC));
270
271
cout <<
suite
<<
"Lookup time: by "
<< how <<
": "
272
<<
"ticks: "
<< delta
273
<<
"\tper: "
<< per
274
<<
" microsec/lookup"
275
<< endl;
276
}
277
278
279
//----------------------------
280
//
281
// TypeId test suites
282
283
class
TypeIdTestSuite
:
public
TestSuite
284
{
285
public
:
286
TypeIdTestSuite
();
287
};
288
289
TypeIdTestSuite::TypeIdTestSuite
()
290
:
TestSuite
(
"type-id"
, UNIT)
291
{
292
// Turn on logging, so we see the result of collisions
293
LogComponentEnable
(
"TypeId"
,
ns3::LogLevel
(
LOG_ERROR
|
LOG_PREFIX_FUNC
));
294
295
// If the CollisionTestCase is performed before the
296
// UniqueIdTestCase, the artificial collisions added by
297
// CollisionTestCase will show up in the list of TypeIds
298
// as chained.
299
AddTestCase
(
new
UniqueTypeIdTestCase
,
QUICK
);
300
AddTestCase
(
new
CollisionTestCase
,
QUICK
);
301
}
302
303
static
TypeIdTestSuite
g_TypeIdTestSuite
;
304
305
306
class
TypeIdPerformanceSuite
:
public
TestSuite
307
{
308
public
:
309
TypeIdPerformanceSuite
();
310
};
311
312
TypeIdPerformanceSuite::TypeIdPerformanceSuite
()
313
:
TestSuite
(
"type-id-perf"
, PERFORMANCE)
314
{
315
AddTestCase
(
new
LookupTimeTestCase
,
QUICK
);
316
}
317
318
static
TypeIdPerformanceSuite
g_TypeIdPerformanceSuite
;
319
320
321
}
// namespace ns3
src
core
test
type-id-test-suite.cc
Generated on Fri Aug 30 2013 01:42:48 for ns-3 by
1.8.1.2