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);
69  input->SetChannel (channel);
70  input->SetNode (a);
71  output->SetChannel (channel);
72  output->SetNode (b);
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
uint32_t m_count
The received packets counter.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static void BuildSimpleTopology(Ptr< Node > a, Ptr< Node > b, Ptr< SimpleNetDevice > input, Ptr< SimpleNetDevice > output, Ptr< SimpleChannel > channel)
Hold variables of type string.
Definition: string.h:41
void DropEvent(Ptr< const Packet > p)
Register a Drop.
A suite of tests to run.
Definition: test.h:1343
BurstErrorModel unit tests.
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.
virtual void DoRun(void)
Implementation to actually run this TestCase.
encapsulates test code
Definition: test.h:1153
a polymophic address class
Definition: address.h:90
channel
Definition: third.py:92
virtual void SetNode(Ptr< Node > node)
static Mac48Address Allocate(void)
Allocate a new Mac48Address.
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
ErrorModel TestSuite.
#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:166
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
Definition: error-model.cc:353
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.
ErrorModel unit tests.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Hold objects of type Ptr<T>.
Definition: pointer.h:36
void SetRandomVariable(Ptr< RandomVariableStream > ranVar)
Definition: error-model.cc:339
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)=0
uint32_t m_count
The received packets counter.
void DropEvent(Ptr< const Packet > p)
Register a Drop.
Instantiate subclasses of ns3::Object.
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:130
void SetQueue(Ptr< Queue< Packet > > queue)
Attach a queue to the SimpleNetDevice.
virtual void SetAddress(Address address)
Set the address of this interface.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1278
uint32_t m_drops
The dropped packets counter.
void SetRandomVariable(Ptr< RandomVariableStream >)
Definition: error-model.cc:215
bool Receive(Ptr< NetDevice > nd, Ptr< const Packet > p, uint16_t protocol, const Address &addr)
Receive form a NetDevice.
static ErrorModelTestSuite errorModelTestSuite
Static variable for test initialization.
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
void SetChannel(Ptr< SimpleChannel > channel)
Attach a channel to this net device.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
static void SendPacket(int num, Ptr< NetDevice > device, Address &addr)
virtual void DoRun(void)
Implementation to actually run this TestCase.
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:1642