A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
error-model-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007 University of Washington
3 * Copyright (c) 2013 ResiliNets, ITTC, University of Kansas
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 */
19
20/* BurstErrorModel additions
21 *
22 * Author: Truc Anh N. Nguyen <annguyen@ittc.ku.edu>
23 * ResiliNets Research Group https://resilinets.org/
24 * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
25 */
26
27#include "ns3/address.h"
28#include "ns3/callback.h"
29#include "ns3/double.h"
30#include "ns3/error-model.h"
31#include "ns3/mac48-address.h"
32#include "ns3/node.h"
33#include "ns3/packet.h"
34#include "ns3/pointer.h"
35#include "ns3/queue.h"
36#include "ns3/rng-seed-manager.h"
37#include "ns3/simple-channel.h"
38#include "ns3/simple-net-device.h"
39#include "ns3/simulator.h"
40#include "ns3/string.h"
41#include "ns3/test.h"
42
43using namespace ns3;
44
45static void
46SendPacket(int num, Ptr<NetDevice> device, Address& addr)
47{
48 for (int i = 0; i < num; i++)
49 {
50 Ptr<Packet> pkt = Create<Packet>(1000); // 1000 dummy bytes of data
51 device->Send(pkt, addr, 0);
52 }
53}
54
55// Two nodes, two devices, one channel
56static void
58 Ptr<Node> b,
61 Ptr<SimpleChannel> channel)
62{
63 ObjectFactory queueFactory;
64 queueFactory.SetTypeId("ns3::DropTailQueue<Packet>");
65 queueFactory.Set("MaxSize", StringValue("100000p")); // Much larger than we need
66 Ptr<Queue<Packet>> queueA = queueFactory.Create<Queue<Packet>>();
67 Ptr<Queue<Packet>> queueB = queueFactory.Create<Queue<Packet>>();
68
69 input->SetQueue(queueA);
70 output->SetQueue(queueB);
71 a->AddDevice(input);
72 b->AddDevice(output);
73 input->SetAddress(Mac48Address::Allocate());
74 input->SetChannel(channel);
75 input->SetNode(a);
76 output->SetChannel(channel);
77 output->SetNode(b);
78 output->SetAddress(Mac48Address::Allocate());
79}
80
88{
89 public:
91 ~ErrorModelSimple() override;
92
93 private:
94 void DoRun() override;
103 bool Receive(Ptr<NetDevice> nd, Ptr<const Packet> p, uint16_t protocol, const Address& addr);
109
112};
113
114// Add some help text to this case to describe what it is intended to test
116 : TestCase("ErrorModel and PhyRxDrop trace for SimpleNetDevice"),
117 m_count(0),
118 m_drops(0)
119{
120}
121
123{
124}
125
126bool
129 uint16_t protocol,
130 const Address& addr)
131{
132 m_count++;
133 return true;
134}
135
136void
138{
139 m_drops++;
140}
141
142void
144{
145 // Set some arbitrary deterministic values
148
149 Ptr<Node> a = CreateObject<Node>();
150 Ptr<Node> b = CreateObject<Node>();
151
152 Ptr<SimpleNetDevice> input = CreateObject<SimpleNetDevice>();
153 Ptr<SimpleNetDevice> output = CreateObject<SimpleNetDevice>();
154 Ptr<SimpleChannel> channel = CreateObject<SimpleChannel>();
155 BuildSimpleTopology(a, b, input, output, channel);
156
157 output->SetReceiveCallback(MakeCallback(&ErrorModelSimple::Receive, this));
158 Ptr<UniformRandomVariable> uv = CreateObject<UniformRandomVariable>();
159 // Set this variable to a specific stream
160 uv->SetStream(50);
161
162 Ptr<RateErrorModel> em = CreateObject<RateErrorModel>();
163 em->SetRandomVariable(uv);
164 em->SetAttribute("ErrorRate", DoubleValue(0.001));
165 em->SetAttribute("ErrorUnit", StringValue("ERROR_UNIT_PACKET"));
166
167 // The below hooks will cause drops and receptions to be counted
168 output->SetAttribute("ReceiveErrorModel", PointerValue(em));
169 output->TraceConnectWithoutContext("PhyRxDrop",
171
172 // Send 10000 packets
173 Simulator::Schedule(Seconds(0), &SendPacket, 10000, input, output->GetAddress());
174
177
178 // For this combination of values, we expect about 1 packet in 1000 to be
179 // dropped. For this specific RNG stream, we see 9991 receptions and 9 drops
180 NS_TEST_ASSERT_MSG_EQ(m_count, 9991, "Wrong number of receptions.");
181 NS_TEST_ASSERT_MSG_EQ(m_drops, 9, "Wrong number of drops.");
182}
183
191{
192 public:
194 ~BurstErrorModelSimple() override;
195
196 private:
197 void DoRun() override;
206 bool Receive(Ptr<NetDevice> nd, Ptr<const Packet> p, uint16_t protocol, const Address& addr);
212
215};
216
217// Add some help text to this case to describe what it is intended to test
219 : TestCase("ErrorModel and PhyRxDrop trace for SimpleNetDevice"),
220 m_count(0),
221 m_drops(0)
222{
223}
224
226{
227}
228
229bool
232 uint16_t protocol,
233 const Address& addr)
234{
235 m_count++;
236 return true;
237}
238
239void
241{
242 m_drops++;
243}
244
245void
247{
248 // Set some arbitrary deterministic values
251
252 Ptr<Node> a = CreateObject<Node>();
253 Ptr<Node> b = CreateObject<Node>();
254
255 Ptr<SimpleNetDevice> input = CreateObject<SimpleNetDevice>();
256 Ptr<SimpleNetDevice> output = CreateObject<SimpleNetDevice>();
257 Ptr<SimpleChannel> channel = CreateObject<SimpleChannel>();
258 BuildSimpleTopology(a, b, input, output, channel);
259
260 output->SetReceiveCallback(MakeCallback(&BurstErrorModelSimple::Receive, this));
261 Ptr<UniformRandomVariable> uv = CreateObject<UniformRandomVariable>();
262 // Set this variable to a specific stream
263 uv->SetStream(50);
264
265 Ptr<BurstErrorModel> em = CreateObject<BurstErrorModel>();
266 em->SetRandomVariable(uv);
267 em->SetAttribute("ErrorRate", DoubleValue(0.01));
268
269 // Assign the underlying error model random variables to specific streams
270 em->AssignStreams(51);
271
272 // The below hooks will cause drops and receptions to be counted
273 output->SetAttribute("ReceiveErrorModel", PointerValue(em));
274 output->TraceConnectWithoutContext("PhyRxDrop",
276
277 // Send 10000 packets
278 Simulator::Schedule(Seconds(0), &SendPacket, 10000, input, output->GetAddress());
279
282
283 // With the burst error rate to be 0.01 and the burst size to be from 1 to 4,
284 // we expect about 2.5 packets being dropped every 1000 packets.
285 // That means for 10000 packets, we expect a total of about 250 packet drops.
286 // For this specific RNG seed, we see 9740 receptions and 260 drops.
287 NS_TEST_ASSERT_MSG_EQ(m_count, 9740, "Wrong number of receptions.");
288 NS_TEST_ASSERT_MSG_EQ(m_drops, 260, "Wrong number of drops.");
289}
290
302{
303 public:
305};
306
308 : TestSuite("error-model", Type::UNIT)
309{
310 AddTestCase(new ErrorModelSimple, TestCase::Duration::QUICK);
311 AddTestCase(new BurstErrorModelSimple, TestCase::Duration::QUICK);
312}
313
314// Do not forget to allocate an instance of this TestSuite
BurstErrorModel unit tests.
bool Receive(Ptr< NetDevice > nd, Ptr< const Packet > p, uint16_t protocol, const Address &addr)
Receive form a NetDevice.
void DoRun() override
Implementation to actually run this TestCase.
uint32_t m_count
The received packets counter.
uint32_t m_drops
The dropped packets counter.
void DropEvent(Ptr< const Packet > p)
Register a Drop.
ErrorModel unit tests.
uint32_t m_drops
The dropped packets counter.
bool Receive(Ptr< NetDevice > nd, Ptr< const Packet > p, uint16_t protocol, const Address &addr)
Receive form a NetDevice.
uint32_t m_count
The received packets counter.
void DropEvent(Ptr< const Packet > p)
Register a Drop.
void DoRun() override
Implementation to actually run this TestCase.
ErrorModel TestSuite.
a polymophic address class
Definition: address.h:101
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
static Mac48Address Allocate()
Allocate a new Mac48Address.
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void Set(const std::string &name, const AttributeValue &value, Args &&... args)
Set an attribute to be set during construction.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
AttributeValue implementation for Pointer.
Definition: pointer.h:48
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Template class for packet Queues.
Definition: queue.h:268
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
Hold variables of type string.
Definition: string.h:56
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
static ErrorModelTestSuite errorModelTestSuite
Static variable for test initialization.
static void SendPacket(int num, Ptr< NetDevice > device, Address &addr)
static void BuildSimpleTopology(Ptr< Node > a, Ptr< Node > b, Ptr< SimpleNetDevice > input, Ptr< SimpleNetDevice > output, Ptr< SimpleChannel > channel)
#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:145
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704