A Discrete-Event Network Simulator
API
pie-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) 2016 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  * Authors: Shravya Ks <shravya.ks0@gmail.com>
19  * Smriti Murali <m.smriti.95@gmail.com>
20  * Mohit P. Tahiliani <tahiliani@nitk.edu.in>
21  *
22  */
23 
24 #include "ns3/test.h"
25 #include "ns3/pie-queue-disc.h"
26 #include "ns3/packet.h"
27 #include "ns3/uinteger.h"
28 #include "ns3/string.h"
29 #include "ns3/double.h"
30 #include "ns3/log.h"
31 #include "ns3/simulator.h"
32 
33 using namespace ns3;
34 
42 {
43 public:
51  PieQueueDiscTestItem (Ptr<Packet> p, const Address & addr, bool ecnCapable);
52  virtual ~PieQueueDiscTestItem ();
53  virtual void AddHeader (void);
54  virtual bool Mark (void);
55 
56  // ** Variables for testing m_isCapDropAdjustment
57  double m_maxDropProbDiff = 0.0;
58  double m_prevDropProb = 0.0;
59  bool m_checkProb = false;
60 
61  // ** Variable for testing ECN
62  double m_maxDropProb = 0.0;
63  bool m_ecnCapable = false;
64 
65  // ** Variables for testing Derandomization
66  bool m_checkAccuProb = false;
67  bool m_constAccuProb = false;
68  bool m_checkMaxAccuProb = false;
69  double m_accuProbError = 0.0;
70  double m_prevAccuProb = 0.0;
71  double m_setAccuProb = 0.0;
72  uint32_t m_expectedDrops = 0;
73 
74 private:
86  PieQueueDiscTestItem &operator = (const PieQueueDiscTestItem &);
88 };
89 
91  : QueueDiscItem (p, addr, 0), m_ecnCapablePacket (ecnCapable)
92 {
93 }
94 
96 {
97 }
98 
99 void
101 {
102 }
103 
104 bool
106 {
107  if (m_ecnCapablePacket)
108  {
109  return true;
110  }
111  return false;
112 }
113 
121 {
122 public:
124  virtual void DoRun (void);
125 private:
133  void Enqueue (Ptr<PieQueueDisc> queue, uint32_t size, uint32_t nPkt, Ptr<PieQueueDiscTestItem> testAttributes);
141  void EnqueueWithDelay (Ptr<PieQueueDisc> queue, uint32_t size, uint32_t nPkt, Ptr<PieQueueDiscTestItem> testAttributes);
147  void Dequeue (Ptr<PieQueueDisc> queue, uint32_t nPkt);
154  void DequeueWithDelay (Ptr<PieQueueDisc> queue, double delay, uint32_t nPkt);
159  void RunPieTest (QueueSizeUnit mode);
165  void CheckDropProb (Ptr<PieQueueDisc> queue, Ptr<PieQueueDiscTestItem> testAttributes);
171  void CheckAccuProb (Ptr<PieQueueDisc> queue, Ptr<PieQueueDiscTestItem> testAttributes);
177  void CheckMaxAccuProb (Ptr<PieQueueDisc> queue, Ptr<PieQueueDiscTestItem> testAttributes);
178 };
179 
181  : TestCase ("Sanity check on the pie queue disc implementation")
182 {
183 }
184 
185 void
187 {
188  uint32_t pktSize = 0;
189 
190  // 1 for packets; pktSize for bytes
191  uint32_t modeSize = 1;
192 
193  uint32_t qSize = 300;
194  Ptr<PieQueueDisc> queue = CreateObject<PieQueueDisc> ();
195 
196 
197  // test 1: simple enqueue/dequeue with defaults, no drops
198  Address dest;
199  // PieQueueDiscItem pointer for attributes
200  Ptr<PieQueueDiscTestItem> testAttributes = Create<PieQueueDiscTestItem> (Create<Packet> (pktSize), dest, false);
201 
202  if (mode == QueueSizeUnit::BYTES)
203  {
204  // pktSize should be same as MeanPktSize to avoid performance gap between byte and packet mode
205  pktSize = 1000;
206  modeSize = pktSize;
207  qSize = qSize * modeSize;
208  }
209 
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 
213  Ptr<Packet> p1, p2, p3, p4, p5, p6, p7, p8;
214  p1 = Create<Packet> (pktSize);
215  p2 = Create<Packet> (pktSize);
216  p3 = Create<Packet> (pktSize);
217  p4 = Create<Packet> (pktSize);
218  p5 = Create<Packet> (pktSize);
219  p6 = Create<Packet> (pktSize);
220  p7 = Create<Packet> (pktSize);
221  p8 = Create<Packet> (pktSize);
222 
223  queue->Initialize ();
224  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 0 * modeSize, "There should be no packets in there");
225  queue->Enqueue (Create<PieQueueDiscTestItem> (p1, dest, false));
226  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 1 * modeSize, "There should be one packet in there");
227  queue->Enqueue (Create<PieQueueDiscTestItem> (p2, dest, false));
228  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 2 * modeSize, "There should be two packets in there");
229  queue->Enqueue (Create<PieQueueDiscTestItem> (p3, dest, false));
230  queue->Enqueue (Create<PieQueueDiscTestItem> (p4, dest, false));
231  queue->Enqueue (Create<PieQueueDiscTestItem> (p5, dest, false));
232  queue->Enqueue (Create<PieQueueDiscTestItem> (p6, dest, false));
233  queue->Enqueue (Create<PieQueueDiscTestItem> (p7, dest, false));
234  queue->Enqueue (Create<PieQueueDiscTestItem> (p8, dest, false));
235  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 8 * modeSize, "There should be eight packets in there");
236 
237  Ptr<QueueDiscItem> item;
238 
239  item = queue->Dequeue ();
240  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the first packet");
241  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 7 * modeSize, "There should be seven packets in there");
242  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p1->GetUid (), "was this the first packet ?");
243 
244  item = queue->Dequeue ();
245  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the second packet");
246  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 6 * modeSize, "There should be six packet in there");
247  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p2->GetUid (), "Was this the second packet ?");
248 
249  item = queue->Dequeue ();
250  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the third packet");
251  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 5 * modeSize, "There should be five packets in there");
252  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p3->GetUid (), "Was this the third packet ?");
253 
254  item = queue->Dequeue ();
255  item = queue->Dequeue ();
256  item = queue->Dequeue ();
257  item = queue->Dequeue ();
258  item = queue->Dequeue ();
259 
260  item = queue->Dequeue ();
261  NS_TEST_EXPECT_MSG_EQ ((item == 0), true, "There are really no packets in there");
262 
263 
264  // test 2: more data with defaults, unforced drops but no forced drops
265  queue = CreateObject<PieQueueDisc> ();
266  // PieQueueDiscItem pointer for attributes
267  testAttributes = Create<PieQueueDiscTestItem> (Create<Packet> (pktSize), dest, false);
268  pktSize = 1000; // pktSize != 0 because DequeueThreshold always works in bytes
269  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
270  true, "Verify that we can actually set the attribute MaxSize");
271  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Tupdate", TimeValue (Seconds (0.03))), true,
272  "Verify that we can actually set the attribute Tupdate");
273  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("DequeueThreshold", UintegerValue (10000)), true,
274  "Verify that we can actually set the attribute DequeueThreshold");
275  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueDelayReference", TimeValue (Seconds (0.02))), true,
276  "Verify that we can actually set the attribute QueueDelayReference");
277  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxBurstAllowance", TimeValue (Seconds (0.1))), true,
278  "Verify that we can actually set the attribute MaxBurstAllowance");
279  queue->Initialize ();
280  EnqueueWithDelay (queue, pktSize, 400, testAttributes);
281  DequeueWithDelay (queue, 0.012, 400);
282  Simulator::Stop (Seconds (8.0));
283  Simulator::Run ();
284  QueueDisc::Stats st = queue->GetStats ();
285  uint32_t test2 = st.GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP);
286  NS_TEST_EXPECT_MSG_NE (test2, 0, "There should be some unforced drops");
287  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (PieQueueDisc::FORCED_DROP), 0, "There should be zero forced drops");
288 
289 
290  // test 3: same as test 2, but with higher QueueDelayReference
291  queue = CreateObject<PieQueueDisc> ();
292  // PieQueueDiscItem pointer for attributes
293  testAttributes = Create<PieQueueDiscTestItem> (Create<Packet> (pktSize), dest, false);
294  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
295  true, "Verify that we can actually set the attribute MaxSize");
296  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Tupdate", TimeValue (Seconds (0.03))), true,
297  "Verify that we can actually set the attribute Tupdate");
298  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("DequeueThreshold", UintegerValue (10000)), true,
299  "Verify that we can actually set the attribute DequeueThreshold");
300  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueDelayReference", TimeValue (Seconds (0.08))), true,
301  "Verify that we can actually set the attribute QueueDelayReference");
302  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxBurstAllowance", TimeValue (Seconds (0.1))), true,
303  "Verify that we can actually set the attribute MaxBurstAllowance");
304  queue->Initialize ();
305  EnqueueWithDelay (queue, pktSize, 400, testAttributes);
306  DequeueWithDelay (queue, 0.012, 400);
307  Simulator::Stop (Seconds (8.0));
308  Simulator::Run ();
309  st = queue->GetStats ();
310  uint32_t test3 = st.GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP);
311  NS_TEST_EXPECT_MSG_LT (test3, test2, "Test 3 should have less unforced drops than test 2");
312  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (PieQueueDisc::FORCED_DROP), 0, "There should be zero forced drops");
313 
314 
315  // test 4: same as test 2, but with reduced dequeue rate
316  queue = CreateObject<PieQueueDisc> ();
317  // PieQueueDiscItem pointer for attributes
318  testAttributes = Create<PieQueueDiscTestItem> (Create<Packet> (pktSize), dest, false);
319  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
320  true, "Verify that we can actually set the attribute MaxSize");
321  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Tupdate", TimeValue (Seconds (0.03))), true,
322  "Verify that we can actually set the attribute Tupdate");
323  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("DequeueThreshold", UintegerValue (10000)), true,
324  "Verify that we can actually set the attribute DequeueThreshold");
325  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueDelayReference", TimeValue (Seconds (0.02))), true,
326  "Verify that we can actually set the attribute QueueDelayReference");
327  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxBurstAllowance", TimeValue (Seconds (0.1))), true,
328  "Verify that we can actually set the attribute MaxBurstAllowance");
329  queue->Initialize ();
330  EnqueueWithDelay (queue, pktSize, 400, testAttributes);
331  DequeueWithDelay (queue, 0.015, 400); // delay between two successive dequeue events is increased
332  Simulator::Stop (Seconds (8.0));
333  Simulator::Run ();
334  st = queue->GetStats ();
335  uint32_t test4 = st.GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP);
336  NS_TEST_EXPECT_MSG_GT (test4, test2, "Test 4 should have more unforced drops than test 2");
337  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (PieQueueDisc::FORCED_DROP), 0, "There should be zero forced drops");
338 
339 
340  // test 5: same dequeue rate as test 4, but with higher Tupdate
341  queue = CreateObject<PieQueueDisc> ();
342  // PieQueueDiscItem pointer for attributes
343  testAttributes = Create<PieQueueDiscTestItem> (Create<Packet> (pktSize), dest, false);
344  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
345  true, "Verify that we can actually set the attribute MaxSize");
346  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Tupdate", TimeValue (Seconds (0.09))), true,
347  "Verify that we can actually set the attribute Tupdate");
348  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("DequeueThreshold", UintegerValue (10000)), true,
349  "Verify that we can actually set the attribute DequeueThreshold");
350  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueDelayReference", TimeValue (Seconds (0.02))), true,
351  "Verify that we can actually set the attribute QueueDelayReference");
352  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxBurstAllowance", TimeValue (Seconds (0.1))), true,
353  "Verify that we can actually set the attribute MaxBurstAllowance");
354  queue->Initialize ();
355  EnqueueWithDelay (queue, pktSize, 400, testAttributes);
356  DequeueWithDelay (queue, 0.015, 400);
357  Simulator::Stop (Seconds (8.0));
358  Simulator::Run ();
359  st = queue->GetStats ();
360  uint32_t test5 = st.GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP);
361  NS_TEST_EXPECT_MSG_LT (test5, test4, "Test 5 should have less unforced drops than test 4");
362  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (PieQueueDisc::FORCED_DROP), 0, "There should be zero forced drops");
363 
364 
365  // test 6: same as test 2, but with UseDequeueRateEstimator enabled
366  queue = CreateObject<PieQueueDisc> ();
367  // PieQueueDiscItem pointer for attributes
368  testAttributes = Create<PieQueueDiscTestItem> (Create<Packet> (pktSize), dest, false);
369  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
370  true, "Verify that we can actually set the attribute MaxSize");
371  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseDequeueRateEstimator", BooleanValue (true)), true,
372  "Verify that we can actually set the attribute UseTimestamp");
373  queue->Initialize ();
374  EnqueueWithDelay (queue, pktSize, 400, testAttributes);
375  DequeueWithDelay (queue, 0.014, 400);
376  Simulator::Stop (Seconds (8.0));
377  Simulator::Run ();
378  st = queue->GetStats ();
379  uint32_t test6 = st.GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP);
380  NS_TEST_EXPECT_MSG_NE (test6, 0, "There should be some unforced drops");
381  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (PieQueueDisc::FORCED_DROP), 0, "There should be zero forced drops");
382 
383 
384  // test 7: test with CapDropAdjustment disabled
385  queue = CreateObject<PieQueueDisc> ();
386  // PieQueueDiscItem pointer for attributes
387  testAttributes = Create<PieQueueDiscTestItem> (Create<Packet> (pktSize), dest, false);
388  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
389  true, "Verify that we can actually set the attribute MaxSize");
390  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseCapDropAdjustment", BooleanValue (false)), true,
391  "Verify that we can actually set the attribute UseCapDropAdjustment");
392  queue->Initialize ();
393  testAttributes->m_checkProb = true;
394  EnqueueWithDelay (queue, pktSize, 400, testAttributes);
395  DequeueWithDelay (queue, 0.014, 400);
396  Simulator::Stop (Seconds (8.0));
397  Simulator::Run ();
398  st = queue->GetStats ();
399  uint32_t test7 = st.GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP);
400  NS_TEST_EXPECT_MSG_NE (test7, 0, "There should be some unforced drops");
401  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (PieQueueDisc::FORCED_DROP), 0, "There should be zero forced drops");
402  NS_TEST_EXPECT_MSG_GT (testAttributes->m_maxDropProbDiff, 0.02,
403  "Maximum increase in drop probability should be greater than 0.02");
404 
405 
406  // test 8: test with CapDropAdjustment enabled
407  queue = CreateObject<PieQueueDisc> ();
408  // PieQueueDiscItem pointer for attributes
409  testAttributes = Create<PieQueueDiscTestItem> (Create<Packet> (pktSize), dest, false);
410  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
411  true, "Verify that we can actually set the attribute MaxSize");
412  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseCapDropAdjustment", BooleanValue (true)), true,
413  "Verify that we can actually set the attribute UseCapDropAdjustment");
414  queue->Initialize ();
415  testAttributes->m_checkProb = true;
416  EnqueueWithDelay (queue, pktSize, 400, testAttributes);
417  DequeueWithDelay (queue, 0.014, 400);
418  Simulator::Stop (Seconds (8.0));
419  Simulator::Run ();
420  st = queue->GetStats ();
421  uint32_t test8 = st.GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP);
422  NS_TEST_EXPECT_MSG_NE (test8, 0, "There should be some unforced drops");
423  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (PieQueueDisc::FORCED_DROP), 0, "There should be zero forced drops");
424  NS_TEST_EXPECT_MSG_LT (testAttributes->m_maxDropProbDiff, 0.0200000000000001,
425  "Maximum increase in drop probability should be less than or equal to 0.02");
426 
427 
428  // test 9: PIE queue disc is ECN enabled, but packets are not ECN capable
429  queue = CreateObject<PieQueueDisc> ();
430  // PieQueueDiscItem pointer for attributes
431  testAttributes = Create<PieQueueDiscTestItem> (Create<Packet> (pktSize), dest, false);
432  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
433  true, "Verify that we can actually set the attribute MaxSize");
434  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (true)), true,
435  "Verify that we can actually set the attribute UseEcn");
436  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MarkEcnThreshold", DoubleValue (0.3)), true,
437  "Verify that we can actually set the attribute MarkEcnThreshold");
438  queue->Initialize ();
439  EnqueueWithDelay (queue, pktSize, 400, testAttributes);
440  DequeueWithDelay (queue, 0.014, 400);
441  Simulator::Stop (Seconds (8.0));
442  Simulator::Run ();
443  st = queue->GetStats ();
444  uint32_t test9 = st.GetNMarkedPackets (PieQueueDisc::UNFORCED_MARK);
445  NS_TEST_EXPECT_MSG_EQ (test9, 0, "There should be zero unforced marks");
446  NS_TEST_EXPECT_MSG_NE (st.GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP), 0, "There should be some unforced drops");
447  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (PieQueueDisc::FORCED_DROP), 0, "There should be zero forced drops");
448 
449 
450  // test 10: Packets are ECN capable, but PIE queue disc is not ECN enabled
451  queue = CreateObject<PieQueueDisc> ();
452  // PieQueueDiscItem pointer for attributes
453  testAttributes = Create<PieQueueDiscTestItem> (Create<Packet> (pktSize), dest, false);
454  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
455  true, "Verify that we can actually set the attribute MaxSize");
456  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (false)), true,
457  "Verify that we can actually set the attribute UseEcn");
458  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MarkEcnThreshold", DoubleValue (0.3)), true,
459  "Verify that we can actually set the attribute MarkEcnThreshold");
460  queue->Initialize ();
461  testAttributes->m_ecnCapable = true;
462  EnqueueWithDelay (queue, pktSize, 400, testAttributes);
463  DequeueWithDelay (queue, 0.014, 400);
464  Simulator::Stop (Seconds (8.0));
465  Simulator::Run ();
466  st = queue->GetStats ();
467  uint32_t test10 = st.GetNMarkedPackets (PieQueueDisc::UNFORCED_MARK);
468  NS_TEST_EXPECT_MSG_EQ (test10, 0, "There should be zero unforced marks");
469  NS_TEST_EXPECT_MSG_NE (st.GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP), 0, "There should be some unforced drops");
470  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (PieQueueDisc::FORCED_DROP), 0, "There should be zero forced drops");
471 
472 
473  // test 11: Packets and PIE queue disc both are ECN capable
474  queue = CreateObject<PieQueueDisc> ();
475  // PieQueueDiscItem pointer for attributes
476  testAttributes = Create<PieQueueDiscTestItem> (Create<Packet> (pktSize), dest, false);
477  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
478  true, "Verify that we can actually set the attribute MaxSize");
479  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (true)), true,
480  "Verify that we can actually set the attribute UseEcn");
481  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MarkEcnThreshold", DoubleValue (0.3)), true,
482  "Verify that we can actually set the attribute MarkEcnThreshold");
483  queue->Initialize ();
484  testAttributes->m_ecnCapable = true;
485  testAttributes->m_checkProb = true;
486  EnqueueWithDelay (queue, pktSize, 400, testAttributes);
487  DequeueWithDelay (queue, 0.014, 400);
488  Simulator::Stop (Seconds (8.0));
489  Simulator::Run ();
490  st = queue->GetStats ();
491  uint32_t test11 = st.GetNMarkedPackets (PieQueueDisc::UNFORCED_MARK);
492  NS_TEST_EXPECT_MSG_NE (test11, 0, "There should be some unforced marks");
493  // There are unforced drops because the value of m_maxDropProb goes beyond 0.3 in this test.
494  // PIE drops the packets even when they are ECN capable if drop probability is more than 30%.
495  NS_TEST_EXPECT_MSG_NE (st.GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP), 0, "There should be some unforced drops");
496  // Confirm that m_maxDropProb goes above 0.3 in this test
497  NS_TEST_EXPECT_MSG_GT (testAttributes->m_maxDropProb, 0.3, "Maximum Drop probability should be greater than 0.3");
498  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (PieQueueDisc::FORCED_DROP), 0, "There should be zero forced drops");
499 
500 
501  // test 12: test with derandomization enabled
502  queue = CreateObject<PieQueueDisc> ();
503  // PieQueueDiscItem pointer for attributes
504  testAttributes = Create<PieQueueDiscTestItem> (Create<Packet> (pktSize), dest, false);
505  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
506  true, "Verify that we can actually set the attribute MaxSize");
507  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseDerandomization", BooleanValue (true)), true,
508  "Verify that we can actually set the attribute UseDerandomization");
509  queue->Initialize ();
510  testAttributes->m_checkAccuProb = true;
511  EnqueueWithDelay (queue, pktSize, 400, testAttributes);
512  DequeueWithDelay (queue, 0.014, 400);
513  Simulator::Stop (Seconds (8.0));
514  Simulator::Run ();
515  st = queue->GetStats ();
516  uint32_t test12 = st.GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP);
517  NS_TEST_EXPECT_MSG_NE (test12, 0, "There should be some unforced drops");
518  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (PieQueueDisc::FORCED_DROP), 0, "There should be zero forced drops");
519  NS_TEST_EXPECT_MSG_EQ (testAttributes->m_accuProbError, 0.0, "There should not be any error in setting accuProb");
520 
521 
522  // test 13: same as test 11 but with accumulated drop probability set below the low threshold
523  queue = CreateObject<PieQueueDisc> ();
524  // PieQueueDiscItem pointer for attributes
525  testAttributes = Create<PieQueueDiscTestItem> (Create<Packet> (pktSize), dest, false);
526  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
527  true, "Verify that we can actually set the attribute MaxSize");
528  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseDerandomization", BooleanValue (true)), true,
529  "Verify that we can actually set the attribute UseDerandomization");
530  queue->Initialize ();
531  testAttributes->m_constAccuProb = true;
532  // Final value of accumulated drop probability to drop packet will be maximum 0.84 while threshold to drop packet is 0.85
533  testAttributes->m_setAccuProb = -0.16;
534  EnqueueWithDelay (queue, pktSize, 400, testAttributes);
535  DequeueWithDelay (queue, 0.014, 400);
536  Simulator::Stop (Seconds (8.0));
537  Simulator::Run ();
538  st = queue->GetStats ();
539  uint32_t test13 = st.GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP);
540  NS_TEST_EXPECT_MSG_EQ (test13, 0, "There should be zero unforced drops");
541  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (PieQueueDisc::FORCED_DROP), 0, "There should be zero forced drops");
542 
543 
544  // test 14: same as test 12 but with accumulated drop probability set above the high threshold
545  queue = CreateObject<PieQueueDisc> ();
546  // PieQueueDiscItem pointer for attributes
547  testAttributes = Create<PieQueueDiscTestItem> (Create<Packet> (pktSize), dest, false);
548  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
549  true, "Verify that we can actually set the attribute MaxSize");
550  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxBurstAllowance", TimeValue (Seconds (0.0))), true,
551  "Verify that we can actually set the attribute MaxBurstAllowance");
552  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseDerandomization", BooleanValue (true)), true,
553  "Verify that we can actually set the attribute UseDerandomization");
554  queue->Initialize ();
555  testAttributes->m_constAccuProb = true;
556  testAttributes->m_checkMaxAccuProb = true;
557  // Final value of accumulated drop probability to drop packet will be minimum 8.6 while threshold to drop packet is 8.5
558  testAttributes->m_setAccuProb = 8.6;
559  EnqueueWithDelay (queue, pktSize, 400, testAttributes);
560  DequeueWithDelay (queue, 0.014, 400);
561  Simulator::Stop (Seconds (8.0));
562  Simulator::Run ();
563  st = queue->GetStats ();
564  uint32_t test14 = st.GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP);
565  NS_TEST_EXPECT_MSG_EQ (test14, testAttributes->m_expectedDrops,
566  "The number of unforced drops should be equal to number of expected unforced drops");
567  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (PieQueueDisc::FORCED_DROP), 0, "There should be zero forced drops");
568 
569 
570  // test 15: tests Active/Inactive feature, ActiveThreshold set to a high value so PIE never starts and there should
571  // not be any drops
572  queue = CreateObject<PieQueueDisc> ();
573  // PieQueueDiscItem pointer for attributes
574  testAttributes = Create<PieQueueDiscTestItem> (Create<Packet> (pktSize), dest, false);
575  queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize)));
576  queue->SetAttributeFailSafe ("ActiveThreshold", TimeValue (Seconds (1)));
577  queue->Initialize ();
578 
579  EnqueueWithDelay (queue, pktSize, 100, testAttributes);
580  DequeueWithDelay (queue, 0.02, 100);
581  Simulator::Stop (Seconds (8.0));
582  Simulator::Run ();
583  st = queue->GetStats ();
584  uint32_t test15 = st.GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP);
585  NS_TEST_EXPECT_MSG_EQ (test15, 0, "There should not be any drops.");
586  NS_TEST_EXPECT_MSG_EQ (st.GetNMarkedPackets (PieQueueDisc::UNFORCED_MARK), 0, "There should be zero marks");
587 
588 
589  // test 16: tests Active/Inactive feature, ActiveThreshold set to a low value so PIE starts early
590  // and some packets should be dropped.
591  queue = CreateObject<PieQueueDisc> ();
592  // PieQueueDiscItem pointer for attributes
593  testAttributes = Create<PieQueueDiscTestItem> (Create<Packet> (pktSize), dest, false);
594  queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize)));
595  queue->SetAttributeFailSafe ("ActiveThreshold", TimeValue (Seconds (0.001)));
596  queue->Initialize ();
597 
598  EnqueueWithDelay (queue, pktSize, 100, testAttributes);
599  DequeueWithDelay (queue, 0.02, 100);
600  Simulator::Stop (Seconds (8.0));
601  Simulator::Run ();
602  st = queue->GetStats ();
603  uint32_t test16 = st.GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP);
604  NS_TEST_EXPECT_MSG_NE (test16, 0, "There should be some drops.");
605  NS_TEST_EXPECT_MSG_EQ (st.GetNMarkedPackets (PieQueueDisc::UNFORCED_MARK), 0, "There should be zero marks");
606 }
607 
608 void
609 PieQueueDiscTestCase::Enqueue (Ptr<PieQueueDisc> queue, uint32_t size, uint32_t nPkt, Ptr<PieQueueDiscTestItem> testAttributes)
610 {
611  Address dest;
612  for (uint32_t i = 0; i < nPkt; i++)
613  {
614  if (testAttributes->m_constAccuProb)
615  {
616  queue->m_accuProb = testAttributes->m_setAccuProb;
617  if (testAttributes->m_checkMaxAccuProb)
618  {
619  CheckMaxAccuProb (queue, testAttributes);
620  }
621  }
622  queue->Enqueue (Create<PieQueueDiscTestItem> (Create<Packet> (size), dest, testAttributes->m_ecnCapable));
623  if (testAttributes->m_checkProb)
624  {
625  CheckDropProb (queue, testAttributes);
626  }
627  if (testAttributes->m_checkAccuProb)
628  {
629  CheckAccuProb (queue, testAttributes);
630  }
631  }
632 }
633 
634 void
636 {
637  double dropProb = queue->m_dropProb;
638  if (testAttributes->m_maxDropProb < dropProb)
639  {
640  testAttributes->m_maxDropProb = dropProb;
641  }
642  if (testAttributes->m_prevDropProb > 0.1)
643  {
644  double currentDiff = dropProb - testAttributes->m_prevDropProb;
645  if (testAttributes->m_maxDropProbDiff < currentDiff)
646  {
647  testAttributes->m_maxDropProbDiff = currentDiff;
648  }
649  }
650  testAttributes->m_prevDropProb = dropProb;
651 }
652 
653 void
655 {
656  double dropProb = queue->m_dropProb;
657  double accuProb = queue->m_accuProb;
658  if (accuProb != 0)
659  {
660  double expectedAccuProb = testAttributes->m_prevAccuProb + dropProb;
661  testAttributes->m_accuProbError = accuProb - expectedAccuProb;
662  }
663  testAttributes->m_prevAccuProb = accuProb;
664 }
665 
666 void
668 {
669  queue->m_dropProb = 0.001;
670  QueueSize queueSize = queue->GetCurrentSize ();
671  if ((queueSize.GetUnit () == QueueSizeUnit::PACKETS && queueSize.GetValue () > 2) || (queueSize.GetUnit () == QueueSizeUnit::BYTES && queueSize.GetValue () > 2000))
672  {
673  testAttributes->m_expectedDrops = testAttributes->m_expectedDrops + 1;
674  }
675 }
676 
677 void
678 PieQueueDiscTestCase::EnqueueWithDelay (Ptr<PieQueueDisc> queue, uint32_t size, uint32_t nPkt, Ptr<PieQueueDiscTestItem> testAttributes)
679 {
680  Address dest;
681  double delay = 0.01; // enqueue packets with delay
682  for (uint32_t i = 0; i < nPkt; i++)
683  {
684  Simulator::Schedule (Time (Seconds ((i + 1) * delay)), &PieQueueDiscTestCase::Enqueue, this, queue, size, 1, testAttributes);
685  }
686 }
687 
688 void
690 {
691  for (uint32_t i = 0; i < nPkt; i++)
692  {
693  Ptr<QueueDiscItem> item = queue->Dequeue ();
694  }
695 }
696 
697 void
698 PieQueueDiscTestCase::DequeueWithDelay (Ptr<PieQueueDisc> queue, double delay, uint32_t nPkt)
699 {
700  for (uint32_t i = 0; i < nPkt; i++)
701  {
702  Simulator::Schedule (Time (Seconds ((i + 1) * delay)), &PieQueueDiscTestCase::Dequeue, this, queue, 1);
703  }
704 }
705 
706 void
708 {
711  Simulator::Destroy ();
712 }
713 
720 static class PieQueueDiscTestSuite : public TestSuite
721 {
722 public:
724  : TestSuite ("pie-queue-disc", UNIT)
725  {
726  AddTestCase (new PieQueueDiscTestCase (), TestCase::QUICK);
727  }
Structure that keeps the queue disc statistics.
Definition: queue-disc.h:185
Pie Queue Disc Test Case.
virtual bool Mark(void)
Marks the packet as a substitute for dropping it, such as for Explicit Congestion Notification...
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
bool m_checkAccuProb
Enable/Disable accumulated drop probability checks.
AttributeValue implementation for Boolean.
Definition: boolean.h:36
void CheckMaxAccuProb(Ptr< PieQueueDisc > queue, Ptr< PieQueueDiscTestItem > testAttributes)
Check Maximum Accumulated Drop Probability.
Class for representing queue sizes.
Definition: queue-size.h:94
void RunPieTest(QueueSizeUnit mode)
Run test function.
bool Enqueue(Ptr< QueueDiscItem > item)
Pass a packet to store to the queue discipline.
Definition: queue-disc.cc:861
bool m_ecnCapablePacket
ECN capable packet?
uint32_t GetValue() const
Get the underlying value.
Definition: queue-size.cc:175
QueueSizeUnit
Enumeration of the operating modes of queues.
Definition: queue-size.h:42
QueueSize GetCurrentSize(void)
Get the current size of the queue disc in bytes, if operating in bytes mode, or packets, otherwise.
Definition: queue-disc.cc:523
A suite of tests to run.
Definition: test.h:1343
bool m_checkMaxAccuProb
Enable/Disable Maximum accumulated drop probability checks.
void Dequeue(Ptr< PieQueueDisc > queue, uint32_t nPkt)
Dequeue function.
#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:205
QueueDiscItem is the abstract base class for items that are stored in a queue disc.
Definition: queue-item.h:148
uint32_t m_expectedDrops
Number of expected unforced drops.
double m_accuProb
Accumulated drop probability.
encapsulates test code
Definition: test.h:1153
void Enqueue(Ptr< PieQueueDisc > queue, uint32_t size, uint32_t nPkt, Ptr< PieQueueDiscTestItem > testAttributes)
Enqueue function.
double m_dropProb
Variable used in calculation of drop probability.
a polymophic address class
Definition: address.h:90
double m_maxDropProbDiff
Maximum difference between two consecutive drop probability values.
virtual void DoRun(void)
Implementation to actually run this TestCase.
double m_setAccuProb
Value to be set for accumulated drop probability.
AttributeValue implementation for Time.
Definition: nstime.h:1353
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
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
double m_maxDropProb
Maximum value of drop probability.
virtual void AddHeader(void)
Add the header to the packet.
const Stats & GetStats(void)
Retrieve all the collected statistics.
Definition: queue-disc.cc:421
double m_prevDropProb
Previous drop probability.
Ptr< QueueDiscItem > Dequeue(void)
Extract from the queue disc the packet that has been dequeued by calling Peek, if any...
Definition: queue-disc.cc:896
void CheckAccuProb(Ptr< PieQueueDisc > queue, Ptr< PieQueueDiscTestItem > testAttributes)
Check Accumulated Drop Probability.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool m_checkProb
Enable/Disable drop probability checks.
uint32_t GetNMarkedPackets(std::string reason) const
Get the number of packets marked for the given reason.
Definition: queue-disc.cc:152
#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
#define NS_TEST_EXPECT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report if not.
Definition: test.h:1088
QueueSizeUnit GetUnit() const
Get the underlying unit.
Definition: queue-size.cc:169
double m_accuProbError
Error in accumulated drop probability.
Pie Queue Disc Test Item.
PieQueueDiscTestSuite g_pieQueueTestSuite
the test suite
bool m_constAccuProb
Enable/Disable fixed accumulated drop probability.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
#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
void EnqueueWithDelay(Ptr< PieQueueDisc > queue, uint32_t size, uint32_t nPkt, Ptr< PieQueueDiscTestItem > testAttributes)
Enqueue with delay function.
Pie Queue Disc Test Suite.
bool m_ecnCapable
Enable/Disable ECN capability.
void DequeueWithDelay(Ptr< PieQueueDisc > queue, double delay, uint32_t nPkt)
Dequeue with delay function.
This test suite implements a Unit Test.
Definition: test.h:1353
uint32_t pktSize
packet size used for the simulation (in bytes)
Definition: wifi-bianchi.cc:86
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
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
double m_prevAccuProb
Previous accumulated drop probability.
void CheckDropProb(Ptr< PieQueueDisc > queue, Ptr< PieQueueDiscTestItem > testAttributes)
Check Drop Probability.