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  virtual void AddHeader (void);
56  virtual bool Mark(void);
57 
58 private:
70  AredQueueDiscTestItem &operator = (const AredQueueDiscTestItem &);
71 };
72 
74  : QueueDiscItem (p, addr, 0)
75 {
76 }
77 
79 {
80 }
81 
82 void
84 {
85 }
86 
87 bool
89 {
90  return false;
91 }
92 
100 {
101 public:
103  virtual void DoRun (void);
104 private:
111  void Enqueue (Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt);
118  void EnqueueWithDelay (Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt);
123  void RunAredDiscTest (QueueSizeUnit mode);
124 };
125 
127  : TestCase ("Sanity check on the functionality of Adaptive RED")
128 {
129 }
130 
131 void
133 {
134  uint32_t pktSize = 0;
135  uint32_t modeSize = 1; // 1 for packets; pktSize for bytes
136  double minTh = 70;
137  double maxTh = 150;
138  uint32_t qSize = 300;
139  Address dest;
140 
141  // test 1: Verify automatic setting of QW. [QW = 0.0 with default LinkBandwidth]
142  Ptr<RedQueueDisc> queue = CreateObject<RedQueueDisc> ();
143 
144  if (mode == QueueSizeUnit::BYTES)
145  {
146  pktSize = 500;
147  modeSize = pktSize;
148  minTh = minTh * modeSize;
149  maxTh = maxTh * modeSize;
150  qSize = qSize * modeSize;
151  }
152 
153  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
154  "Verify that we can actually set the attribute MinTh");
155  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
156  "Verify that we can actually set the attribute MaxTh");
157  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
158  true, "Verify that we can actually set the attribute MaxSize");
159  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.0)), true,
160  "Verify that we can actually set the attribute QW");
161  queue->Initialize ();
162  Enqueue (queue, pktSize, 300);
163  QueueDisc::Stats st = queue->GetStats ();
164  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
165  "There should be zero unforced drops");
166 
167 
168  // test 2: Verify automatic setting of QW. [QW = 0.0 with lesser LinkBandwidth]
169  queue = CreateObject<RedQueueDisc> ();
170  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
171  "Verify that we can actually set the attribute MinTh");
172  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
173  "Verify that we can actually set the attribute MaxTh");
174  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
175  true, "Verify that we can actually set the attribute MaxSize");
176  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.0)), true,
177  "Verify that we can actually set the attribute QW");
178  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LinkBandwidth", DataRateValue (DataRate ("0.015Mbps"))), true,
179  "Verify that we can actually set the attribute LinkBandwidth");
180  queue->Initialize ();
181  Enqueue (queue, pktSize, 300);
182  st = queue->GetStats ();
183  NS_TEST_EXPECT_MSG_NE (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
184  "There should be some unforced drops");
185 
186 
187  // test 3: Verify automatic setting of QW. [QW = -1.0 with default LinkBandwidth]
188  queue = CreateObject<RedQueueDisc> ();
189  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
190  "Verify that we can actually set the attribute MinTh");
191  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
192  "Verify that we can actually set the attribute MaxTh");
193  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
194  true, "Verify that we can actually set the attribute MaxSize");
195  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (-1.0)), true,
196  "Verify that we can actually set the attribute QW");
197  queue->Initialize ();
198  Enqueue (queue, pktSize, 300);
199  st = queue->GetStats ();
200  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
201  "There should be zero unforced drops");
202 
203 
204  // test 4: Verify automatic setting of QW. [QW = -1.0 with lesser LinkBandwidth]
205  queue = CreateObject<RedQueueDisc> ();
206  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
207  "Verify that we can actually set the attribute MinTh");
208  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
209  "Verify that we can actually set the attribute MaxTh");
210  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
211  true, "Verify that we can actually set the attribute MaxSize");
212  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (-1.0)), true,
213  "Verify that we can actually set the attribute QW");
214  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LinkBandwidth", DataRateValue (DataRate ("0.015Mbps"))), true,
215  "Verify that we can actually set the attribute LinkBandwidth");
216  queue->Initialize ();
217  Enqueue (queue, pktSize, 300);
218  st = queue->GetStats ();
219  NS_TEST_EXPECT_MSG_NE (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
220  "There should be some unforced drops");
221 
222 
223  // test 5: Verify automatic setting of QW. [QW = -2.0 with default LinkBandwidth]
224  queue = CreateObject<RedQueueDisc> ();
225  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
226  "Verify that we can actually set the attribute MinTh");
227  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
228  "Verify that we can actually set the attribute MaxTh");
229  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
230  true, "Verify that we can actually set the attribute MaxSize");
231  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (-2.0)), true,
232  "Verify that we can actually set the attribute QW");
233  queue->Initialize ();
234  Enqueue (queue, pktSize, 300);
235  st = queue->GetStats ();
236  uint32_t test5 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
237  NS_TEST_EXPECT_MSG_NE (test5, 0, "There should be some unforced drops");
238 
239 
240  // test 6: Verify automatic setting of QW. [QW = -2.0 with lesser LinkBandwidth]
241  queue = CreateObject<RedQueueDisc> ();
242  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
243  "Verify that we can actually set the attribute MinTh");
244  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
245  "Verify that we can actually set the attribute MaxTh");
246  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
247  true, "Verify that we can actually set the attribute MaxSize");
248  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (-2.0)), true,
249  "Verify that we can actually set the attribute QW");
250  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LinkBandwidth", DataRateValue (DataRate ("0.015Mbps"))), true,
251  "Verify that we can actually set the attribute LinkBandwidth");
252  queue->Initialize ();
253  Enqueue (queue, pktSize, 300);
254  st = queue->GetStats ();
255  uint32_t test6 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
256  NS_TEST_EXPECT_MSG_NE (test6, test5, "Test 6 should have more unforced drops than Test 5");
257 
258 
259  // test 7: Verify automatic setting of minTh and maxTh. [minTh = maxTh = 0.0, with default LinkBandwidth]
260  queue = CreateObject<RedQueueDisc> ();
261  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (0.0)), true,
262  "Verify that we can actually set the attribute MinTh");
263  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (0.0)), true,
264  "Verify that we can actually set the attribute MaxTh");
265  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
266  true, "Verify that we can actually set the attribute MaxSize");
267  queue->Initialize ();
268  Enqueue (queue, pktSize, 300);
269  st = queue->GetStats ();
270  NS_TEST_EXPECT_MSG_NE (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
271  "There should be some unforced drops");
272 
273 
274  // test 8: Verify automatic setting of minTh and maxTh. [minTh = maxTh = 0.0, with higher LinkBandwidth]
275  queue = CreateObject<RedQueueDisc> ();
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 ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
281  true, "Verify that we can actually set the attribute MaxSize");
282  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LinkBandwidth", DataRateValue (DataRate ("150Mbps"))), true,
283  "Verify that we can actually set the attribute LinkBandwidth");
284  queue->Initialize ();
285  Enqueue (queue, pktSize, 300);
286  st = queue->GetStats ();
287  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
288  "There should be zero unforced drops");
289 
290 
291  // test 9: Default RED (automatic and adaptive settings disabled)
292  queue = CreateObject<RedQueueDisc> ();
293  minTh = 5 * modeSize;
294  maxTh = 15 * modeSize;
295  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
296  "Verify that we can actually set the attribute MinTh");
297  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
298  "Verify that we can actually set the attribute MaxTh");
299  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
300  true, "Verify that we can actually set the attribute MaxSize");
301  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
302  "Verify that we can actually set the attribute QW");
303  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
304  "Verify that we can actually set the attribute LInterm");
305  queue->Initialize ();
306  EnqueueWithDelay (queue, pktSize, 300);
307  Simulator::Stop (Seconds (5));
308  Simulator::Run ();
309  st = queue->GetStats ();
310  uint32_t test9 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
311  NS_TEST_EXPECT_MSG_NE (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
312  "There should be some unforced drops");
313 
314 
315  // test 10: Adaptive RED (automatic and adaptive settings enabled)
316  queue = CreateObject<RedQueueDisc> ();
317  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
318  true, "Verify that we can actually set the attribute MaxSize");
319  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
320  "Verify that we can actually set the attribute LInterm");
321  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("ARED", BooleanValue (true)), true,
322  "Verify that we can actually set the attribute ARED");
323  queue->Initialize ();
324  EnqueueWithDelay (queue, pktSize, 300);
325  Simulator::Stop (Seconds (5));
326  Simulator::Run ();
327  st = queue->GetStats ();
328  uint32_t test10 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
329  NS_TEST_EXPECT_MSG_LT (test10, test9, "Test 10 should have less unforced drops than test 9");
330 }
331 
332 void
333 AredQueueDiscTestCase::Enqueue (Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt)
334 {
335  Address dest;
336  for (uint32_t i = 0; i < nPkt; i++)
337  {
338  queue->Enqueue (Create<AredQueueDiscTestItem> (Create<Packet> (size), dest));
339  }
340 }
341 
342 void
343 AredQueueDiscTestCase::EnqueueWithDelay (Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt)
344 {
345  Address dest;
346  double delay = 0.01; // enqueue packets with delay to allow m_curMaxP to adapt
347  for (uint32_t i = 0; i < nPkt; i++)
348  {
349  Simulator::Schedule (Time (Seconds ((i + 1) * delay)), &AredQueueDiscTestCase::Enqueue, this, queue, size, 1);
350  }
351 }
352 
353 void
355 {
358  Simulator::Destroy ();
359 }
360 
367 static class AredQueueDiscTestSuite : public TestSuite
368 {
369 public:
371  : TestSuite ("adaptive-red-queue-disc", UNIT)
372  {
373  AddTestCase (new AredQueueDiscTestCase (), TestCase::QUICK);
374  }
Structure that keeps the queue disc statistics.
Definition: queue-disc.h:185
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
AttributeValue implementation for Boolean.
Definition: boolean.h:36
Class for representing queue sizes.
Definition: queue-size.h:94
bool Enqueue(Ptr< QueueDiscItem > item)
Pass a packet to store to the queue discipline.
Definition: queue-disc.cc:861
QueueSizeUnit
Enumeration of the operating modes of queues.
Definition: queue-size.h:42
A suite of tests to run.
Definition: test.h:1341
#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:283
bool SetAttributeFailSafe(std::string name, const AttributeValue &value)
Set a single attribute without raising errors.
Definition: object-base.cc:207
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:1153
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
void RunAredDiscTest(QueueSizeUnit 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:110
Use number of packets for queue size.
Definition: queue-size.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:421
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:737
AttributeValue implementation for DataRate.
Definition: data-rate.h:242
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1064
#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:901
virtual void DoRun(void)
Implementation to actually run this TestCase.
This test suite implements a Unit Test.
Definition: test.h:1351
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
AredQueueDiscTestSuite g_aredQueueDiscTestSuite
the test suite
Use number of bytes for queue size.
Definition: queue-size.h:45
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.