A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
43 using namespace ns3;
44 
45 static void SendPacket (int num, Ptr<NetDevice> device, Address& addr)
46 {
47  for (int i = 0; i < num; i++)
48  {
49  Ptr<Packet> pkt = Create<Packet> (1000); // 1000 dummy bytes of data
50  device->Send (pkt, addr, 0);
51  }
52 }
53 
54 // Two nodes, two devices, one channel
56 {
57  a->AddDevice (input);
58  b->AddDevice (output);
60  input->SetChannel (channel);
61  input->SetNode (a);
62  output->SetChannel (channel);
63  output->SetNode (b);
65 }
66 
67 class ErrorModelSimple : public TestCase
68 {
69 public:
71  virtual ~ErrorModelSimple ();
72 
73 private:
74  virtual void DoRun (void);
75  bool Receive (Ptr<NetDevice> nd, Ptr<const Packet> p, uint16_t protocol, const Address& addr);
76  void DropEvent (Ptr<const Packet> p);
77  uint32_t m_count;
78  uint32_t m_drops;
79 };
80 
81 // Add some help text to this case to describe what it is intended to test
83  : TestCase ("ErrorModel and PhyRxDrop trace for SimpleNetDevice"), m_count (0), m_drops (0)
84 {
85 }
86 
88 {
89 }
90 
91 bool
92 ErrorModelSimple::Receive (Ptr<NetDevice> nd, Ptr<const Packet> p, uint16_t protocol, const Address& addr)
93 {
94  m_count++;
95  return true;
96 }
97 
98 void
100 {
101  m_drops++;
102 }
103 
104 void
106 {
107  // Set some arbitrary deterministic values
108  RngSeedManager::SetSeed (7);
109  RngSeedManager::SetRun (2);
110 
111  Ptr<Node> a = CreateObject<Node> ();
112  Ptr<Node> b = CreateObject<Node> ();
113 
114  Ptr<SimpleNetDevice> input = CreateObject<SimpleNetDevice> ();
115  Ptr<SimpleNetDevice> output = CreateObject<SimpleNetDevice> ();
116  Ptr<SimpleChannel> channel = CreateObject<SimpleChannel> ();
117  BuildSimpleTopology (a, b, input, output, channel);
118 
119  output->SetReceiveCallback (MakeCallback (&ErrorModelSimple::Receive, this));
120  Ptr<UniformRandomVariable> uv = CreateObject<UniformRandomVariable> ();
121  // Set this variable to a specific stream
122  uv->SetStream (50);
123 
124  Ptr<RateErrorModel> em = CreateObject<RateErrorModel> ();
125  em->SetRandomVariable (uv);
126  em->SetAttribute ("ErrorRate", DoubleValue (0.001));
127  em->SetAttribute ("ErrorUnit", StringValue ("ERROR_UNIT_PACKET"));
128 
129  // The below hooks will cause drops and receptions to be counted
130  output->SetAttribute ("ReceiveErrorModel", PointerValue (em));
131  output->TraceConnectWithoutContext ("PhyRxDrop", MakeCallback (&ErrorModelSimple::DropEvent, this));
132 
133  // Send 10000 packets
134  Simulator::Schedule (Seconds (0), &SendPacket, 10000, input, output->GetAddress ());
135 
136  Simulator::Run ();
137  Simulator::Destroy ();
138 
139  // For this combination of values, we expect about 1 packet in 1000 to be
140  // dropped. For this specific RNG stream, we see 9991 receptions and 9 drops
141  NS_TEST_ASSERT_MSG_EQ (m_count, 9991, "Wrong number of receptions.");
142  NS_TEST_ASSERT_MSG_EQ (m_drops, 9, "Wrong number of drops.");
143 }
144 
146 {
147 public:
149  virtual ~BurstErrorModelSimple ();
150 
151 private:
152  virtual void DoRun (void);
153  bool Receive (Ptr<NetDevice> nd, Ptr<const Packet> p, uint16_t protocol, const Address& addr);
154  void DropEvent (Ptr<const Packet> p);
155  uint32_t m_count;
156  uint32_t m_drops;
157 };
158 
159 // Add some help text to this case to describe what it is intended to test
161  : TestCase ("ErrorModel and PhyRxDrop trace for SimpleNetDevice"), m_count (0), m_drops (0)
162 {
163 }
164 
166 {
167 }
168 
169 bool
171 {
172  m_count++;
173  return true;
174 }
175 
176 void
178 {
179  m_drops++;
180 }
181 
182 void
184 {
185  // Set some arbitrary deterministic values
186  RngSeedManager::SetSeed (5);
187  RngSeedManager::SetRun (8);
188 
189  Ptr<Node> a = CreateObject<Node> ();
190  Ptr<Node> b = CreateObject<Node> ();
191 
192  Ptr<SimpleNetDevice> input = CreateObject<SimpleNetDevice> ();
193  Ptr<SimpleNetDevice> output = CreateObject<SimpleNetDevice> ();
194  Ptr<SimpleChannel> channel = CreateObject<SimpleChannel> ();
195  BuildSimpleTopology (a, b, input, output, channel);
196 
197  output->SetReceiveCallback (MakeCallback (&BurstErrorModelSimple::Receive, this));
198  Ptr<UniformRandomVariable> uv = CreateObject<UniformRandomVariable> ();
199  // Set this variable to a specific stream
200  uv->SetStream (50);
201 
202  Ptr<BurstErrorModel> em = CreateObject<BurstErrorModel> ();
203  em->SetRandomVariable (uv);
204  em->SetAttribute ("ErrorRate", DoubleValue (0.01));
205 
206  // Assign the underlying error model random variables to specific streams
207  em->AssignStreams (51);
208 
209  // The below hooks will cause drops and receptions to be counted
210  output->SetAttribute ("ReceiveErrorModel", PointerValue (em));
211  output->TraceConnectWithoutContext ("PhyRxDrop", MakeCallback (&BurstErrorModelSimple::DropEvent, this));
212 
213  // Send 10000 packets
214  Simulator::Schedule (Seconds (0), &SendPacket, 10000, input, output->GetAddress ());
215 
216  Simulator::Run ();
217  Simulator::Destroy ();
218 
219  // With the burst error rate to be 0.01 and the burst size to be from 1 to 4,
220  // we expect about 2.5 packets being dropped every 1000 packets.
221  // That means for 10000 packets, we expect a total of about 250 packet drops.
222  // For this specific RNG seed, we see 9740 receptions and 260 drops.
223  NS_TEST_ASSERT_MSG_EQ (m_count, 9740, "Wrong number of receptions.");
224  NS_TEST_ASSERT_MSG_EQ (m_drops, 260 , "Wrong number of drops.");
225 }
226 
227 // This is the start of an error model test suite. For starters, this is
228 // just testing that the SimpleNetDevice is working but this can be
229 // extended to many more test cases in the future
231 {
232 public:
234 };
235 
237  : TestSuite ("error-model", UNIT)
238 {
239  AddTestCase (new ErrorModelSimple, TestCase::QUICK);
240  AddTestCase (new BurstErrorModelSimple, TestCase::QUICK);
241 }
242 
243 // Do not forget to allocate an instance of this TestSuite
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
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:19
void DropEvent(Ptr< const Packet > p)
A suite of tests to run.
Definition: test.h:1025
virtual void DoRun(void)
Implementation to actually run this TestCase.
encapsulates test code
Definition: test.h:849
a polymophic address class
Definition: address.h:86
virtual void SetNode(Ptr< Node > node)
static Mac48Address Allocate(void)
Allocate a new Mac48Address.
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
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
bool Receive(Ptr< NetDevice > nd, Ptr< const Packet > p, uint16_t protocol, const Address &addr)
hold objects of type Ptr
Definition: pointer.h:33
void SetRandomVariable(Ptr< RandomVariableStream > ranVar)
Definition: error-model.cc:339
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)=0
void AddTestCase(TestCase *testCase) NS_DEPRECATED
Add an individual child TestCase case to this TestCase.
Definition: test.cc:173
void DropEvent(Ptr< const Packet > p)
uint32_t AddDevice(Ptr< NetDevice > device)
Definition: node.cc:118
virtual void SetAddress(Address address)
Set the address of this interface.
void SetRandomVariable(Ptr< RandomVariableStream >)
Definition: error-model.cc:215
bool Receive(Ptr< NetDevice > nd, Ptr< const Packet > p, uint16_t protocol, const Address &addr)
EventId output
static ErrorModelTestSuite errorModelTestSuite
Hold a floating point type.
Definition: double.h:41
void SetChannel(Ptr< SimpleChannel > channel)
Attach a channel to this net device.
void SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:161
static void SendPacket(int num, Ptr< NetDevice > device, Address &addr)
virtual void DoRun(void)
Implementation to actually run this TestCase.
#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:137