A Discrete-Event Network Simulator
API
error-model-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) 2007 University of Washington
4  * Copyright (c) 2013 ResiliNets, ITTC, University of Kansas
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  */
20 
21 /* BurstErrorModel additions
22  *
23  * Author: Truc Anh N. Nguyen <annguyen@ittc.ku.edu>
24  * ResiliNets Research Group http://wiki.ittc.ku.edu/resilinets
25  * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
26  */
27 
28 #include "ns3/test.h"
29 #include "ns3/simple-net-device.h"
30 #include "ns3/simple-channel.h"
31 #include "ns3/address.h"
32 #include "ns3/mac48-address.h"
33 #include "ns3/packet.h"
34 #include "ns3/callback.h"
35 #include "ns3/node.h"
36 #include "ns3/simulator.h"
37 #include "ns3/error-model.h"
38 #include "ns3/pointer.h"
39 #include "ns3/double.h"
40 #include "ns3/string.h"
41 #include "ns3/rng-seed-manager.h"
42 #include "ns3/queue.h"
43 
44 using namespace ns3;
45 
46 static void 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
57 {
58  ObjectFactory queueFactory;
59  queueFactory.SetTypeId("ns3::DropTailQueue<Packet>");
60  queueFactory.Set("MaxSize", StringValue("100000p")); // Much larger than we need
61  Ptr<Queue<Packet> > queueA = queueFactory.Create<Queue<Packet> > ();
62  Ptr<Queue<Packet> > queueB = queueFactory.Create<Queue<Packet> > ();
63 
64  input->SetQueue(queueA);
65  output->SetQueue(queueB);
66  a->AddDevice (input);
67  b->AddDevice (output);
68  input->SetAddress (Mac48Address::Allocate ());
69  input->SetChannel (channel);
70  input->SetNode (a);
71  output->SetChannel (channel);
72  output->SetNode (b);
73  output->SetAddress (Mac48Address::Allocate ());
74 }
75 
82 class ErrorModelSimple : public TestCase
83 {
84 public:
86  virtual ~ErrorModelSimple ();
87 
88 private:
89  virtual void DoRun (void);
98  bool Receive (Ptr<NetDevice> nd, Ptr<const Packet> p, uint16_t protocol, const Address& addr);
103  void DropEvent (Ptr<const Packet> p);
104 
105  uint32_t m_count;
106  uint32_t m_drops;
107 };
108 
109 // Add some help text to this case to describe what it is intended to test
111  : TestCase ("ErrorModel and PhyRxDrop trace for SimpleNetDevice"), m_count (0), m_drops (0)
112 {
113 }
114 
116 {
117 }
118 
119 bool
120 ErrorModelSimple::Receive (Ptr<NetDevice> nd, Ptr<const Packet> p, uint16_t protocol, const Address& addr)
121 {
122  m_count++;
123  return true;
124 }
125 
126 void
128 {
129  m_drops++;
130 }
131 
132 void
134 {
135  // Set some arbitrary deterministic values
136  RngSeedManager::SetSeed (7);
137  RngSeedManager::SetRun (2);
138 
139  Ptr<Node> a = CreateObject<Node> ();
140  Ptr<Node> b = CreateObject<Node> ();
141 
142  Ptr<SimpleNetDevice> input = CreateObject<SimpleNetDevice> ();
143  Ptr<SimpleNetDevice> output = CreateObject<SimpleNetDevice> ();
144  Ptr<SimpleChannel> channel = CreateObject<SimpleChannel> ();
145  BuildSimpleTopology (a, b, input, output, channel);
146 
147  output->SetReceiveCallback (MakeCallback (&ErrorModelSimple::Receive, this));
148  Ptr<UniformRandomVariable> uv = CreateObject<UniformRandomVariable> ();
149  // Set this variable to a specific stream
150  uv->SetStream (50);
151 
152  Ptr<RateErrorModel> em = CreateObject<RateErrorModel> ();
153  em->SetRandomVariable (uv);
154  em->SetAttribute ("ErrorRate", DoubleValue (0.001));
155  em->SetAttribute ("ErrorUnit", StringValue ("ERROR_UNIT_PACKET"));
156 
157  // The below hooks will cause drops and receptions to be counted
158  output->SetAttribute ("ReceiveErrorModel", PointerValue (em));
159  output->TraceConnectWithoutContext ("PhyRxDrop", MakeCallback (&ErrorModelSimple::DropEvent, this));
160 
161  // Send 10000 packets
162  Simulator::Schedule (Seconds (0), &SendPacket, 10000, input, output->GetAddress ());
163 
164  Simulator::Run ();
165  Simulator::Destroy ();
166 
167  // For this combination of values, we expect about 1 packet in 1000 to be
168  // dropped. For this specific RNG stream, we see 9991 receptions and 9 drops
169  NS_TEST_ASSERT_MSG_EQ (m_count, 9991, "Wrong number of receptions.");
170  NS_TEST_ASSERT_MSG_EQ (m_drops, 9, "Wrong number of drops.");
171 }
172 
180 {
181 public:
183  virtual ~BurstErrorModelSimple ();
184 
185 private:
186  virtual void DoRun (void);
195  bool Receive (Ptr<NetDevice> nd, Ptr<const Packet> p, uint16_t protocol, const Address& addr);
200  void DropEvent (Ptr<const Packet> p);
201 
202  uint32_t m_count;
203  uint32_t m_drops;
204 };
205 
206 // Add some help text to this case to describe what it is intended to test
208  : TestCase ("ErrorModel and PhyRxDrop trace for SimpleNetDevice"), m_count (0), m_drops (0)
209 {
210 }
211 
213 {
214 }
215 
216 bool
218 {
219  m_count++;
220  return true;
221 }
222 
223 void
225 {
226  m_drops++;
227 }
228 
229 void
231 {
232  // Set some arbitrary deterministic values
233  RngSeedManager::SetSeed (5);
234  RngSeedManager::SetRun (8);
235 
236  Ptr<Node> a = CreateObject<Node> ();
237  Ptr<Node> b = CreateObject<Node> ();
238 
239  Ptr<SimpleNetDevice> input = CreateObject<SimpleNetDevice> ();
240  Ptr<SimpleNetDevice> output = CreateObject<SimpleNetDevice> ();
241  Ptr<SimpleChannel> channel = CreateObject<SimpleChannel> ();
242  BuildSimpleTopology (a, b, input, output, channel);
243 
244  output->SetReceiveCallback (MakeCallback (&BurstErrorModelSimple::Receive, this));
245  Ptr<UniformRandomVariable> uv = CreateObject<UniformRandomVariable> ();
246  // Set this variable to a specific stream
247  uv->SetStream (50);
248 
249  Ptr<BurstErrorModel> em = CreateObject<BurstErrorModel> ();
250  em->SetRandomVariable (uv);
251  em->SetAttribute ("ErrorRate", DoubleValue (0.01));
252 
253  // Assign the underlying error model random variables to specific streams
254  em->AssignStreams (51);
255 
256  // The below hooks will cause drops and receptions to be counted
257  output->SetAttribute ("ReceiveErrorModel", PointerValue (em));
258  output->TraceConnectWithoutContext ("PhyRxDrop", MakeCallback (&BurstErrorModelSimple::DropEvent, this));
259 
260  // Send 10000 packets
261  Simulator::Schedule (Seconds (0), &SendPacket, 10000, input, output->GetAddress ());
262 
263  Simulator::Run ();
264  Simulator::Destroy ();
265 
266  // With the burst error rate to be 0.01 and the burst size to be from 1 to 4,
267  // we expect about 2.5 packets being dropped every 1000 packets.
268  // That means for 10000 packets, we expect a total of about 250 packet drops.
269  // For this specific RNG seed, we see 9740 receptions and 260 drops.
270  NS_TEST_ASSERT_MSG_EQ (m_count, 9740, "Wrong number of receptions.");
271  NS_TEST_ASSERT_MSG_EQ (m_drops, 260 , "Wrong number of drops.");
272 }
273 
285 {
286 public:
288 };
289 
291  : TestSuite ("error-model", UNIT)
292 {
293  AddTestCase (new ErrorModelSimple, TestCase::QUICK);
294  AddTestCase (new BurstErrorModelSimple, TestCase::QUICK);
295 }
296 
297 // 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.
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.
virtual void DoRun(void)
Implementation to actually run this TestCase.
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.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void DropEvent(Ptr< const Packet > p)
Register a Drop.
ErrorModel TestSuite.
a polymophic address class
Definition: address.h:91
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
static Mac48Address Allocate(void)
Allocate a new Mac48Address.
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)=0
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:130
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:256
Instantiate subclasses of ns3::Object.
void Set(const std::string &name, const AttributeValue &value, Args &&... args)
Set an attribute to be set during construction.
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
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
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
void SetRandomVariable(Ptr< RandomVariableStream >)
Definition: error-model.cc:215
Hold variables of type string.
Definition: string.h:41
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
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:141
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
channel
Definition: third.py:92