A Discrete-Event Network Simulator
API
adaptive-red-queue-disc-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) 2015 NITK Surathkal
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  * Author: Mohit P. Tahiliani <tahiliani@nitk.edu.in>
19  *
20  */
21 
22 #include "ns3/test.h"
23 #include "ns3/red-queue-disc.h"
24 #include "ns3/packet.h"
25 #include "ns3/uinteger.h"
26 #include "ns3/string.h"
27 #include "ns3/double.h"
28 #include "ns3/log.h"
29 #include "ns3/simulator.h"
30 
31 using namespace ns3;
32 
46 public:
53  AredQueueDiscTestItem (Ptr<Packet> p, const Address & addr);
54  virtual ~AredQueueDiscTestItem ();
55 
56  // Delete copy constructor and assignment operator to avoid misuse
58  AredQueueDiscTestItem & operator = (const AredQueueDiscTestItem &) = delete;
59 
60  virtual void AddHeader (void);
61  virtual bool Mark(void);
62 
63 private:
65 };
66 
68  : QueueDiscItem (p, addr, 0)
69 {
70 }
71 
73 {
74 }
75 
76 void
78 {
79 }
80 
81 bool
83 {
84  return false;
85 }
86 
94 {
95 public:
97  virtual void DoRun (void);
98 private:
105  void Enqueue (Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt);
112  void EnqueueWithDelay (Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt);
117  void RunAredDiscTest (QueueSizeUnit mode);
118 };
119 
121  : TestCase ("Sanity check on the functionality of Adaptive RED")
122 {
123 }
124 
125 void
127 {
128  uint32_t pktSize = 0;
129  uint32_t modeSize = 1; // 1 for packets; pktSize for bytes
130  double minTh = 70;
131  double maxTh = 150;
132  uint32_t qSize = 300;
133  Address dest;
134 
135  // test 1: Verify automatic setting of QW. [QW = 0.0 with default LinkBandwidth]
136  Ptr<RedQueueDisc> queue = CreateObject<RedQueueDisc> ();
137 
138  if (mode == QueueSizeUnit::BYTES)
139  {
140  pktSize = 500;
141  modeSize = pktSize;
142  minTh = minTh * modeSize;
143  maxTh = maxTh * modeSize;
144  qSize = qSize * modeSize;
145  }
146 
147  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
148  "Verify that we can actually set the attribute MinTh");
149  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
150  "Verify that we can actually set the attribute MaxTh");
151  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
152  true, "Verify that we can actually set the attribute MaxSize");
153  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.0)), true,
154  "Verify that we can actually set the attribute QW");
155  queue->Initialize ();
156  Enqueue (queue, pktSize, 300);
157  QueueDisc::Stats st = queue->GetStats ();
158  NS_TEST_ASSERT_MSG_EQ (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
159  "There should be zero unforced drops");
160 
161 
162  // test 2: Verify automatic setting of QW. [QW = 0.0 with lesser LinkBandwidth]
163  queue = CreateObject<RedQueueDisc> ();
164  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
165  "Verify that we can actually set the attribute MinTh");
166  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
167  "Verify that we can actually set the attribute MaxTh");
168  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
169  true, "Verify that we can actually set the attribute MaxSize");
170  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.0)), true,
171  "Verify that we can actually set the attribute QW");
172  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("LinkBandwidth", DataRateValue (DataRate ("0.015Mbps"))), true,
173  "Verify that we can actually set the attribute LinkBandwidth");
174  queue->Initialize ();
175  Enqueue (queue, pktSize, 300);
176  st = queue->GetStats ();
177  NS_TEST_ASSERT_MSG_NE (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
178  "There should be some unforced drops");
179 
180 
181  // test 3: Verify automatic setting of QW. [QW = -1.0 with default LinkBandwidth]
182  queue = CreateObject<RedQueueDisc> ();
183  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
184  "Verify that we can actually set the attribute MinTh");
185  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
186  "Verify that we can actually set the attribute MaxTh");
187  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
188  true, "Verify that we can actually set the attribute MaxSize");
189  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (-1.0)), true,
190  "Verify that we can actually set the attribute QW");
191  queue->Initialize ();
192  Enqueue (queue, pktSize, 300);
193  st = queue->GetStats ();
194  NS_TEST_ASSERT_MSG_EQ (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
195  "There should be zero unforced drops");
196 
197 
198  // test 4: Verify automatic setting of QW. [QW = -1.0 with lesser LinkBandwidth]
199  queue = CreateObject<RedQueueDisc> ();
200  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
201  "Verify that we can actually set the attribute MinTh");
202  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
203  "Verify that we can actually set the attribute MaxTh");
204  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
205  true, "Verify that we can actually set the attribute MaxSize");
206  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (-1.0)), true,
207  "Verify that we can actually set the attribute QW");
208  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("LinkBandwidth", DataRateValue (DataRate ("0.015Mbps"))), true,
209  "Verify that we can actually set the attribute LinkBandwidth");
210  queue->Initialize ();
211  Enqueue (queue, pktSize, 300);
212  st = queue->GetStats ();
213  NS_TEST_ASSERT_MSG_NE (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
214  "There should be some unforced drops");
215 
216 
217  // test 5: Verify automatic setting of QW. [QW = -2.0 with default LinkBandwidth]
218  queue = CreateObject<RedQueueDisc> ();
219  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
220  "Verify that we can actually set the attribute MinTh");
221  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
222  "Verify that we can actually set the attribute MaxTh");
223  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
224  true, "Verify that we can actually set the attribute MaxSize");
225  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (-2.0)), true,
226  "Verify that we can actually set the attribute QW");
227  queue->Initialize ();
228  Enqueue (queue, pktSize, 300);
229  st = queue->GetStats ();
230  uint32_t test5 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
231  NS_TEST_ASSERT_MSG_NE (test5, 0, "There should be some unforced drops");
232 
233 
234  // test 6: Verify automatic setting of QW. [QW = -2.0 with lesser LinkBandwidth]
235  queue = CreateObject<RedQueueDisc> ();
236  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
237  "Verify that we can actually set the attribute MinTh");
238  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
239  "Verify that we can actually set the attribute MaxTh");
240  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
241  true, "Verify that we can actually set the attribute MaxSize");
242  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (-2.0)), true,
243  "Verify that we can actually set the attribute QW");
244  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("LinkBandwidth", DataRateValue (DataRate ("0.015Mbps"))), true,
245  "Verify that we can actually set the attribute LinkBandwidth");
246  queue->Initialize ();
247  Enqueue (queue, pktSize, 300);
248  st = queue->GetStats ();
249  uint32_t test6 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
250  NS_TEST_ASSERT_MSG_NE (test6, test5, "Test 6 should have more unforced drops than Test 5");
251 
252 
253  // test 7: Verify automatic setting of minTh and maxTh. [minTh = maxTh = 0.0, with default LinkBandwidth]
254  queue = CreateObject<RedQueueDisc> ();
255  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (0.0)), true,
256  "Verify that we can actually set the attribute MinTh");
257  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (0.0)), true,
258  "Verify that we can actually set the attribute MaxTh");
259  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
260  true, "Verify that we can actually set the attribute MaxSize");
261  queue->Initialize ();
262  Enqueue (queue, pktSize, 300);
263  st = queue->GetStats ();
264  NS_TEST_ASSERT_MSG_NE (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
265  "There should be some unforced drops");
266 
267 
268  // test 8: Verify automatic setting of minTh and maxTh. [minTh = maxTh = 0.0, with higher LinkBandwidth]
269  queue = CreateObject<RedQueueDisc> ();
270  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (0.0)), true,
271  "Verify that we can actually set the attribute MinTh");
272  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (0.0)), true,
273  "Verify that we can actually set the attribute MaxTh");
274  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
275  true, "Verify that we can actually set the attribute MaxSize");
276  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("LinkBandwidth", DataRateValue (DataRate ("150Mbps"))), true,
277  "Verify that we can actually set the attribute LinkBandwidth");
278  queue->Initialize ();
279  Enqueue (queue, pktSize, 300);
280  st = queue->GetStats ();
281  NS_TEST_ASSERT_MSG_EQ (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
282  "There should be zero unforced drops");
283 
284 
285  // test 9: Default RED (automatic and adaptive settings disabled)
286  queue = CreateObject<RedQueueDisc> ();
287  minTh = 5 * modeSize;
288  maxTh = 15 * modeSize;
289  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
290  "Verify that we can actually set the attribute MinTh");
291  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
292  "Verify that we can actually set the attribute MaxTh");
293  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
294  true, "Verify that we can actually set the attribute MaxSize");
295  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
296  "Verify that we can actually set the attribute QW");
297  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
298  "Verify that we can actually set the attribute LInterm");
299  queue->Initialize ();
300  EnqueueWithDelay (queue, pktSize, 300);
301  Simulator::Stop (Seconds (5));
302  Simulator::Run ();
303  st = queue->GetStats ();
304  uint32_t test9 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
305  NS_TEST_ASSERT_MSG_NE (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
306  "There should be some unforced drops");
307 
308 
309  // test 10: Adaptive RED (automatic and adaptive settings enabled)
310  queue = CreateObject<RedQueueDisc> ();
311  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
312  true, "Verify that we can actually set the attribute MaxSize");
313  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
314  "Verify that we can actually set the attribute LInterm");
315  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("ARED", BooleanValue (true)), true,
316  "Verify that we can actually set the attribute ARED");
317  queue->Initialize ();
318  EnqueueWithDelay (queue, pktSize, 300);
319  Simulator::Stop (Seconds (5));
320  Simulator::Run ();
321  st = queue->GetStats ();
322  uint32_t test10 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
323  NS_TEST_ASSERT_MSG_LT (test10, test9, "Test 10 should have less unforced drops than test 9");
324 }
325 
326 void
327 AredQueueDiscTestCase::Enqueue (Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt)
328 {
329  Address dest;
330  for (uint32_t i = 0; i < nPkt; i++)
331  {
332  queue->Enqueue (Create<AredQueueDiscTestItem> (Create<Packet> (size), dest));
333  }
334 }
335 
336 void
337 AredQueueDiscTestCase::EnqueueWithDelay (Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt)
338 {
339  Address dest;
340  double delay = 0.01; // enqueue packets with delay to allow m_curMaxP to adapt
341  for (uint32_t i = 0; i < nPkt; i++)
342  {
343  Simulator::Schedule (Time (Seconds ((i + 1) * delay)), &AredQueueDiscTestCase::Enqueue, this, queue, size, 1);
344  }
345 }
346 
347 void
349 {
352  Simulator::Destroy ();
353 }
354 
361 static class AredQueueDiscTestSuite : public TestSuite
362 {
363 public:
365  : TestSuite ("adaptive-red-queue-disc", UNIT)
366  {
367  AddTestCase (new AredQueueDiscTestCase (), TestCase::QUICK);
368  }
virtual void DoRun(void)
Implementation to actually run this TestCase.
void RunAredDiscTest(QueueSizeUnit mode)
Run ARED queue disc test function.
void Enqueue(Ptr< RedQueueDisc > queue, uint32_t size, uint32_t nPkt)
Enqueue function.
void EnqueueWithDelay(Ptr< RedQueueDisc > queue, uint32_t size, uint32_t nPkt)
Enqueue with delay function.
virtual bool Mark(void)
Marks the packet as a substitute for dropping it, such as for Explicit Congestion Notification.
virtual void AddHeader(void)
Add the header to the packet.
AredQueueDiscTestItem(const AredQueueDiscTestItem &)=delete
a polymophic address class
Definition: address.h:91
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Class for representing data rates.
Definition: data-rate.h:89
AttributeValue implementation for DataRate.
Definition: data-rate.h:298
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
QueueDiscItem is the abstract base class for items that are stored in a queue disc.
Definition: queue-item.h:133
Class for representing queue sizes.
Definition: queue-size.h:95
AttributeValue implementation for QueueSize.
Definition: queue-size.h:221
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
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1197
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
QueueSizeUnit
Enumeration of the operating modes of queues.
Definition: queue-size.h:43
@ BYTES
Use number of bytes for queue size.
Definition: queue-size.h:45
@ PACKETS
Use number of packets for queue size.
Definition: queue-size.h:44
#define NS_TEST_ASSERT_MSG_LT(actual, limit, msg)
Test that an actual value is less than a limit and report and abort if not.
Definition: test.h:675
#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
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report and abort if not.
Definition: test.h:542
AredQueueDiscTestSuite g_aredQueueDiscTestSuite
the test suite
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.
Structure that keeps the queue disc statistics.
Definition: queue-disc.h:186
uint32_t GetNDroppedPackets(std::string reason) const
Get the number of packets dropped for the given reason.
Definition: queue-disc.cc:109
uint32_t pktSize
packet size used for the simulation (in bytes)
Definition: wifi-bianchi.cc:89