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:
54  AredQueueDiscTestItem (Ptr<Packet> p, const Address & addr, uint16_t protocol);
55  virtual ~AredQueueDiscTestItem ();
56  virtual void AddHeader (void);
57  virtual bool Mark(void);
58 
59 private:
71  AredQueueDiscTestItem &operator = (const AredQueueDiscTestItem &);
72 };
73 
75  : QueueDiscItem (p, addr, protocol)
76 {
77 }
78 
80 {
81 }
82 
83 void
85 {
86 }
87 
88 bool
90 {
91  return false;
92 }
93 
101 {
102 public:
104  virtual void DoRun (void);
105 private:
112  void Enqueue (Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt);
119  void EnqueueWithDelay (Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt);
124  void RunAredDiscTest (StringValue mode);
125 };
126 
128  : TestCase ("Sanity check on the functionality of Adaptive RED")
129 {
130 }
131 
132 void
134 {
135  uint32_t pktSize = 0;
136  uint32_t modeSize = 1; // 1 for packets; pktSize for bytes
137  double minTh = 70;
138  double maxTh = 150;
139  uint32_t qSize = 300;
140  Address dest;
141 
142  // test 1: Verify automatic setting of QW. [QW = 0.0 with default LinkBandwidth]
143  Ptr<RedQueueDisc> queue = CreateObject<RedQueueDisc> ();
144  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
145  "Verify that we can actually set the attribute Mode");
146 
147  if (queue->GetMode () == RedQueueDisc::QUEUE_DISC_MODE_BYTES)
148  {
149  pktSize = 500;
150  modeSize = pktSize;
151  minTh = minTh * modeSize;
152  maxTh = maxTh * modeSize;
153  qSize = qSize * modeSize;
154  }
155 
156  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
157  "Verify that we can actually set the attribute MinTh");
158  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
159  "Verify that we can actually set the attribute MaxTh");
160  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
161  "Verify that we can actually set the attribute QueueLimit");
162  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.0)), true,
163  "Verify that we can actually set the attribute QW");
164  queue->Initialize ();
165  Enqueue (queue, pktSize, 300);
166  QueueDisc::Stats st = queue->GetStats ();
167  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
168  "There should be zero unforced drops");
169 
170 
171  // test 2: Verify automatic setting of QW. [QW = 0.0 with lesser LinkBandwidth]
172  queue = CreateObject<RedQueueDisc> ();
173  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
174  "Verify that we can actually set the attribute Mode");
175  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
176  "Verify that we can actually set the attribute MinTh");
177  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
178  "Verify that we can actually set the attribute MaxTh");
179  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
180  "Verify that we can actually set the attribute QueueLimit");
181  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.0)), true,
182  "Verify that we can actually set the attribute QW");
183  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LinkBandwidth", DataRateValue (DataRate ("0.015Mbps"))), true,
184  "Verify that we can actually set the attribute LinkBandwidth");
185  queue->Initialize ();
186  Enqueue (queue, pktSize, 300);
187  st = queue->GetStats ();
188  NS_TEST_EXPECT_MSG_NE (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
189  "There should be some unforced drops");
190 
191 
192  // test 3: Verify automatic setting of QW. [QW = -1.0 with default LinkBandwidth]
193  queue = CreateObject<RedQueueDisc> ();
194  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
195  "Verify that we can actually set the attribute Mode");
196  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
197  "Verify that we can actually set the attribute MinTh");
198  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
199  "Verify that we can actually set the attribute MaxTh");
200  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
201  "Verify that we can actually set the attribute QueueLimit");
202  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (-1.0)), true,
203  "Verify that we can actually set the attribute QW");
204  queue->Initialize ();
205  Enqueue (queue, pktSize, 300);
206  st = queue->GetStats ();
207  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
208  "There should be zero unforced drops");
209 
210 
211  // test 4: Verify automatic setting of QW. [QW = -1.0 with lesser LinkBandwidth]
212  queue = CreateObject<RedQueueDisc> ();
213  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
214  "Verify that we can actually set the attribute Mode");
215  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
216  "Verify that we can actually set the attribute MinTh");
217  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
218  "Verify that we can actually set the attribute MaxTh");
219  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
220  "Verify that we can actually set the attribute QueueLimit");
221  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (-1.0)), true,
222  "Verify that we can actually set the attribute QW");
223  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LinkBandwidth", DataRateValue (DataRate ("0.015Mbps"))), true,
224  "Verify that we can actually set the attribute LinkBandwidth");
225  queue->Initialize ();
226  Enqueue (queue, pktSize, 300);
227  st = queue->GetStats ();
228  NS_TEST_EXPECT_MSG_NE (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
229  "There should be some unforced drops");
230 
231 
232  // test 5: Verify automatic setting of QW. [QW = -2.0 with default LinkBandwidth]
233  queue = CreateObject<RedQueueDisc> ();
234  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
235  "Verify that we can actually set the attribute Mode");
236  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
237  "Verify that we can actually set the attribute MinTh");
238  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
239  "Verify that we can actually set the attribute MaxTh");
240  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
241  "Verify that we can actually set the attribute QueueLimit");
242  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (-2.0)), true,
243  "Verify that we can actually set the attribute QW");
244  queue->Initialize ();
245  Enqueue (queue, pktSize, 300);
246  st = queue->GetStats ();
247  uint32_t test5 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
248  NS_TEST_EXPECT_MSG_NE (test5, 0, "There should be some unforced drops");
249 
250 
251  // test 6: Verify automatic setting of QW. [QW = -2.0 with lesser LinkBandwidth]
252  queue = CreateObject<RedQueueDisc> ();
253  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
254  "Verify that we can actually set the attribute Mode");
255  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
256  "Verify that we can actually set the attribute MinTh");
257  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
258  "Verify that we can actually set the attribute MaxTh");
259  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
260  "Verify that we can actually set the attribute QueueLimit");
261  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (-2.0)), true,
262  "Verify that we can actually set the attribute QW");
263  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LinkBandwidth", DataRateValue (DataRate ("0.015Mbps"))), true,
264  "Verify that we can actually set the attribute LinkBandwidth");
265  queue->Initialize ();
266  Enqueue (queue, pktSize, 300);
267  st = queue->GetStats ();
268  uint32_t test6 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
269  NS_TEST_EXPECT_MSG_NE (test6, test5, "Test 6 should have more unforced drops than Test 5");
270 
271 
272  // test 7: Verify automatic setting of minTh and maxTh. [minTh = maxTh = 0.0, with default LinkBandwidth]
273  queue = CreateObject<RedQueueDisc> ();
274  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
275  "Verify that we can actually set the attribute Mode");
276  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (0.0)), true,
277  "Verify that we can actually set the attribute MinTh");
278  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (0.0)), true,
279  "Verify that we can actually set the attribute MaxTh");
280  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
281  "Verify that we can actually set the attribute QueueLimit");
282  queue->Initialize ();
283  Enqueue (queue, pktSize, 300);
284  st = queue->GetStats ();
285  NS_TEST_EXPECT_MSG_NE (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
286  "There should be some unforced drops");
287 
288 
289  // test 8: Verify automatic setting of minTh and maxTh. [minTh = maxTh = 0.0, with higher LinkBandwidth]
290  queue = CreateObject<RedQueueDisc> ();
291  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
292  "Verify that we can actually set the attribute Mode");
293  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (0.0)), true,
294  "Verify that we can actually set the attribute MinTh");
295  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (0.0)), true,
296  "Verify that we can actually set the attribute MaxTh");
297  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
298  "Verify that we can actually set the attribute QueueLimit");
299  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LinkBandwidth", DataRateValue (DataRate ("150Mbps"))), true,
300  "Verify that we can actually set the attribute LinkBandwidth");
301  queue->Initialize ();
302  Enqueue (queue, pktSize, 300);
303  st = queue->GetStats ();
304  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
305  "There should be zero unforced drops");
306 
307 
308  // test 9: Default RED (automatic and adaptive settings disabled)
309  queue = CreateObject<RedQueueDisc> ();
310  minTh = 5 * modeSize;
311  maxTh = 15 * modeSize;
312  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
313  "Verify that we can actually set the attribute Mode");
314  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
315  "Verify that we can actually set the attribute MinTh");
316  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
317  "Verify that we can actually set the attribute MaxTh");
318  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
319  "Verify that we can actually set the attribute QueueLimit");
320  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
321  "Verify that we can actually set the attribute QW");
322  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
323  "Verify that we can actually set the attribute LInterm");
324  queue->Initialize ();
325  EnqueueWithDelay (queue, pktSize, 300);
326  Simulator::Stop (Seconds (5));
327  Simulator::Run ();
328  st = queue->GetStats ();
329  uint32_t test9 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
330  NS_TEST_EXPECT_MSG_NE (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
331  "There should be some unforced drops");
332 
333 
334  // test 10: Adaptive RED (automatic and adaptive settings enabled)
335  queue = CreateObject<RedQueueDisc> ();
336  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
337  "Verify that we can actually set the attribute Mode");
338  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
339  "Verify that we can actually set the attribute QueueLimit");
340  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
341  "Verify that we can actually set the attribute LInterm");
342  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("ARED", BooleanValue (true)), true,
343  "Verify that we can actually set the attribute ARED");
344  queue->Initialize ();
345  EnqueueWithDelay (queue, pktSize, 300);
346  Simulator::Stop (Seconds (5));
347  Simulator::Run ();
348  st = queue->GetStats ();
349  uint32_t test10 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
350  NS_TEST_EXPECT_MSG_LT (test10, test9, "Test 10 should have less unforced drops than test 9");
351 }
352 
353 void
354 AredQueueDiscTestCase::Enqueue (Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt)
355 {
356  Address dest;
357  for (uint32_t i = 0; i < nPkt; i++)
358  {
359  queue->Enqueue (Create<AredQueueDiscTestItem> (Create<Packet> (size), dest, 0));
360  }
361 }
362 
363 void
364 AredQueueDiscTestCase::EnqueueWithDelay (Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt)
365 {
366  Address dest;
367  double delay = 0.01; // enqueue packets with delay to allow m_curMaxP to adapt
368  for (uint32_t i = 0; i < nPkt; i++)
369  {
370  Simulator::Schedule (Time (Seconds ((i + 1) * delay)), &AredQueueDiscTestCase::Enqueue, this, queue, size, 1);
371  }
372 }
373 
374 void
376 {
377  RunAredDiscTest (StringValue ("QUEUE_DISC_MODE_PACKETS"));
378  RunAredDiscTest (StringValue ("QUEUE_DISC_MODE_BYTES"));
379  Simulator::Destroy ();
380 }
381 
388 static class AredQueueDiscTestSuite : public TestSuite
389 {
390 public:
392  : TestSuite ("adaptive-red-queue-disc", UNIT)
393  {
394  AddTestCase (new AredQueueDiscTestCase (), TestCase::QUICK);
395  }
Structure that keeps the queue disc statistics.
Definition: queue-disc.h:155
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
AttributeValue implementation for Boolean.
Definition: boolean.h:36
bool Enqueue(Ptr< QueueDiscItem > item)
Pass a packet to store to the queue discipline.
Definition: queue-disc.cc:730
Hold variables of type string.
Definition: string.h:41
A suite of tests to run.
Definition: test.h:1342
QueueDiscMode GetMode(void)
Get the operating mode of this queue disc.
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:285
bool SetAttributeFailSafe(std::string name, const AttributeValue &value)
Set a single attribute without raising errors.
Definition: object-base.cc:205
QueueDiscItem is the abstract base class for items that are stored in a queue disc.
Definition: queue-item.h:148
encapsulates test code
Definition: test.h:1155
This test suite implements a Unit Test.
Definition: test.h:1352
a polymophic address class
Definition: address.h:90
Class for representing data rates.
Definition: data-rate.h:88
virtual bool Mark(void)
Marks the packet as a substitute for dropping it, such as for Explicit Congestion Notification...
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
Hold an unsigned integer type.
Definition: uinteger.h:44
virtual void AddHeader(void)
Add the header to the packet.
const Stats & GetStats(void)
Retrieve all the collected statistics.
Definition: queue-disc.cc:411
void RunAredDiscTest(StringValue mode)
Run ARED queue disc test function.
uint32_t GetNDroppedPackets(std::string reason) const
Get the number of packets dropped for the given reason.
Definition: queue-disc.cc:113
Every class exported by the ns3 library is enclosed in the ns3 namespace.
#define NS_TEST_EXPECT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report if not.
Definition: test.h:739
AttributeValue implementation for DataRate.
Definition: data-rate.h:242
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:993
#define NS_TEST_EXPECT_MSG_LT(actual, limit, msg)
Test that an actual value is less than a limit and report if not.
Definition: test.h:903
virtual void DoRun(void)
Implementation to actually run this TestCase.
This class can be used to hold variables of floating point type such as 'double' or 'float'...
Definition: double.h:41
AredQueueDiscTestSuite g_aredQueueDiscTestSuite
the test suite
void Initialize(void)
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:183
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.