A Discrete-Event Network Simulator
API
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 
43 using namespace ns3;
44 
45 static void
46 SendPacket(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
56 static void
58  Ptr<Node> b,
60  Ptr<SimpleNetDevice> output,
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 
87 class ErrorModelSimple : public TestCase
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);
108  void DropEvent(Ptr<const Packet> p);
109 
110  uint32_t m_count;
111  uint32_t m_drops;
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 
126 bool
129  uint16_t protocol,
130  const Address& addr)
131 {
132  m_count++;
133  return true;
134 }
135 
136 void
138 {
139  m_drops++;
140 }
141 
142 void
144 {
145  // Set some arbitrary deterministic values
146  RngSeedManager::SetSeed(7);
147  RngSeedManager::SetRun(2);
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 
175  Simulator::Run();
176  Simulator::Destroy();
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 
213  uint32_t m_count;
214  uint32_t m_drops;
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 
229 bool
232  uint16_t protocol,
233  const Address& addr)
234 {
235  m_count++;
236  return true;
237 }
238 
239 void
241 {
242  m_drops++;
243 }
244 
245 void
247 {
248  // Set some arbitrary deterministic values
249  RngSeedManager::SetSeed(5);
250  RngSeedManager::SetRun(8);
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 
280  Simulator::Run();
281  Simulator::Destroy();
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", UNIT)
309 {
310  AddTestCase(new ErrorModelSimple, TestCase::QUICK);
311  AddTestCase(new BurstErrorModelSimple, TestCase::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.
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:138
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:204
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.
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Template class for packet Queues.
Definition: queue.h:268
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
void SetRandomVariable(Ptr< RandomVariableStream >)
Definition: error-model.cc:222
Hold variables of type string.
Definition: string.h:56
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
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:144
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
channel
Definition: third.py:88