A Discrete-Event Network Simulator
API
codel-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) 2014 ResiliNets, ITTC, University of Kansas
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: Truc Anh N Nguyen <trucanh524@gmail.com>
19  * Modified by: Pasquale Imputato <p.imputato@gmail.com>
20  *
21  */
22 
23 #include "ns3/test.h"
24 #include "ns3/codel-queue-disc.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 
33 // The following code borrowed from Linux codel.h, for unit testing
34 #define REC_INV_SQRT_BITS_ns3 (8 * sizeof(uint16_t))
35 /* or sizeof_in_bits(rec_inv_sqrt) */
36 /* needed shift to get a Q0.32 number from rec_inv_sqrt */
37 #define REC_INV_SQRT_SHIFT_ns3 (32 - REC_INV_SQRT_BITS_ns3)
38 
39 static uint16_t _codel_Newton_step (uint32_t count, uint16_t rec_inv_sqrt)
40 {
41  uint32_t invsqrt = ((uint32_t)rec_inv_sqrt) << REC_INV_SQRT_SHIFT_ns3;
42  uint32_t invsqrt2 = ((uint64_t)invsqrt * invsqrt) >> 32;
43  uint64_t val = (3LL << 32) - ((uint64_t)count * invsqrt2);
44 
45  val >>= 2; /* avoid overflow in following multiply */
46  val = (val * invsqrt) >> (32 - 2 + 1);
47  return (val >> REC_INV_SQRT_SHIFT_ns3);
48 }
49 
50 static uint32_t _reciprocal_scale (uint32_t val, uint32_t ep_ro)
51 {
52  return (uint32_t)(((uint64_t)val * ep_ro) >> 32);
53 }
54 // End Linux borrow
55 
56 
58 public:
59  CodelQueueDiscTestItem (Ptr<Packet> p, const Address & addr, uint16_t protocol);
60  virtual ~CodelQueueDiscTestItem ();
61  virtual void AddHeader (void);
62 
63 private:
66  CodelQueueDiscTestItem &operator = (const CodelQueueDiscTestItem &);
67 };
68 
70  : QueueDiscItem (p, addr, protocol)
71 {
72 }
73 
75 {
76 }
77 
78 void
80 {
81 }
82 
83 // Test 1: simple enqueue/dequeue with no drops
85 {
86 public:
87  CoDelQueueDiscBasicEnqueueDequeue (std::string mode);
88  virtual void DoRun (void);
89 
90  void QueueTestSize (Ptr<CoDelQueueDisc> queue, uint32_t size, std::string error)
91  {
92  if (queue->GetMode () == Queue::QUEUE_MODE_BYTES)
93  {
94  NS_TEST_EXPECT_MSG_EQ (queue->GetNBytes (), size, error);
95  }
96  else if (queue->GetMode () == Queue::QUEUE_MODE_PACKETS)
97  {
98  NS_TEST_EXPECT_MSG_EQ (queue->GetNPackets (), size, error);
99  }
100 
101  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), size, error);
102  }
103 
104 private:
106 };
107 
109  : TestCase ("Basic enqueue and dequeue operations, and attribute setting for " + mode)
110 {
111  m_mode = StringValue (mode);
112 }
113 
114 void
116 {
117  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc> ();
118 
119  uint32_t pktSize = 1000;
120  uint32_t modeSize = 0;
121 
122  Address dest;
123 
124  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", m_mode), true,
125  "Verify that we can actually set the attribute Mode");
126  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxPackets", UintegerValue (1500)), true,
127  "Verify that we can actually set the attribute MaxPackets");
128  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxBytes", UintegerValue (pktSize * 1500)), true,
129  "Verify that we can actually set the attribute MaxBytes");
130  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinBytes", UintegerValue (pktSize)), true,
131  "Verify that we can actually set the attribute MinBytes");
132  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Interval", StringValue ("50ms")), true,
133  "Verify that we can actually set the attribute Interval");
134  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Target", StringValue ("4ms")), true,
135  "Verify that we can actually set the attribute Target");
136 
137  if (queue->GetMode () == Queue::QUEUE_MODE_BYTES)
138  {
139  modeSize = pktSize;
140  }
141  else if (queue->GetMode () == Queue::QUEUE_MODE_PACKETS)
142  {
143  modeSize = 1;
144  }
145  queue->Initialize ();
146 
147  Ptr<Packet> p1, p2, p3, p4, p5, p6;
148  p1 = Create<Packet> (pktSize);
149  p2 = Create<Packet> (pktSize);
150  p3 = Create<Packet> (pktSize);
151  p4 = Create<Packet> (pktSize);
152  p5 = Create<Packet> (pktSize);
153  p6 = Create<Packet> (pktSize);
154 
155  QueueTestSize (queue, 0 * modeSize, "There should be no packets in queue");
156  queue->Enqueue (Create<CodelQueueDiscTestItem> (p1, dest, 0));
157  QueueTestSize (queue, 1 * modeSize, "There should be one packet in queue");
158  queue->Enqueue (Create<CodelQueueDiscTestItem> (p2, dest, 0));
159  QueueTestSize (queue, 2 * modeSize, "There should be two packets in queue");
160  queue->Enqueue (Create<CodelQueueDiscTestItem> (p3, dest, 0));
161  QueueTestSize (queue, 3 * modeSize, "There should be three packets in queue");
162  queue->Enqueue (Create<CodelQueueDiscTestItem> (p4, dest, 0));
163  QueueTestSize (queue, 4 * modeSize, "There should be four packets in queue");
164  queue->Enqueue (Create<CodelQueueDiscTestItem> (p5, dest, 0));
165  QueueTestSize (queue, 5 * modeSize, "There should be five packets in queue");
166  queue->Enqueue (Create<CodelQueueDiscTestItem> (p6, dest, 0));
167  QueueTestSize (queue, 6 * modeSize, "There should be six packets in queue");
168 
169  NS_TEST_EXPECT_MSG_EQ (queue->GetDropOverLimit (), 0, "There should be no packets being dropped due to full queue");
170 
171  Ptr<QueueDiscItem> item;
172 
173  item = queue->Dequeue ();
174  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the first packet");
175  QueueTestSize (queue, 5 * modeSize, "There should be five packets in queue");
176  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p1->GetUid (), "was this the first packet ?");
177 
178  item = queue->Dequeue ();
179  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the second packet");
180  QueueTestSize (queue, 4 * modeSize, "There should be four packets in queue");
181  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p2->GetUid (), "Was this the second packet ?");
182 
183  item = queue->Dequeue ();
184  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the third packet");
185  QueueTestSize (queue, 3 * modeSize, "There should be three packets in queue");
186  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p3->GetUid (), "Was this the third packet ?");
187 
188  item = queue->Dequeue ();
189  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the forth packet");
190  QueueTestSize (queue, 2 * modeSize, "There should be two packets in queue");
191  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p4->GetUid (), "Was this the fourth packet ?");
192 
193  item = queue->Dequeue ();
194  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the fifth packet");
195  QueueTestSize (queue, 1 * modeSize, "There should be one packet in queue");
196  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p5->GetUid (), "Was this the fifth packet ?");
197 
198  item = queue->Dequeue ();
199  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the last packet");
200  QueueTestSize (queue, 0 * modeSize, "There should be zero packet in queue");
201  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p6->GetUid (), "Was this the sixth packet ?");
202 
203  item = queue->Dequeue ();
204  NS_TEST_EXPECT_MSG_EQ ((item == 0), true, "There are really no packets in queue");
205 
206  NS_TEST_EXPECT_MSG_EQ (queue->GetDropCount (), 0, "There should be no packet drops according to CoDel algorithm");
207 }
208 
209 // Test 2: enqueue with drops due to queue overflow
211 {
212 public:
213  CoDelQueueDiscBasicOverflow (std::string mode);
214  virtual void DoRun (void);
215 
216  void QueueTestSize (Ptr<CoDelQueueDisc> queue, uint32_t size, std::string error)
217  {
218  if (queue->GetMode () == Queue::QUEUE_MODE_BYTES)
219  {
220  NS_TEST_EXPECT_MSG_EQ (queue->GetNBytes (), size, error);
221  }
222  else if (queue->GetMode () == Queue::QUEUE_MODE_PACKETS)
223  {
224  NS_TEST_EXPECT_MSG_EQ (queue->GetNPackets (), size, error);
225  }
226 
227  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), size, error);
228  }
229 
230 private:
231  void Enqueue (Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt);
233 };
234 
236  : TestCase ("Basic overflow behavior for " + mode)
237 {
238  m_mode = StringValue (mode);
239 }
240 
241 void
243 {
244  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc> ();
245  uint32_t pktSize = 1000;
246  uint32_t modeSize = 0;
247 
248  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", m_mode), true,
249  "Verify that we can actually set the attribute Mode");
250 
251  Address dest;
252 
253  if (queue->GetMode () == Queue::QUEUE_MODE_BYTES)
254  {
255  modeSize = pktSize;
256  }
257  else if (queue->GetMode () == Queue::QUEUE_MODE_PACKETS)
258  {
259  modeSize = 1;
260  }
261 
262  Ptr<Packet> p1, p2, p3;
263  p1 = Create<Packet> (pktSize);
264  p2 = Create<Packet> (pktSize);
265  p3 = Create<Packet> (pktSize);
266 
267  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxPackets", UintegerValue (500)), true,
268  "Verify that we can actually set the attribute MaxPackets");
269  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxBytes", UintegerValue (pktSize * 500)), true,
270  "Verify that we can actually set the attribute MaxBytes");
271  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinBytes", UintegerValue (pktSize)), true,
272  "Verify that we can actually set the attribute MinBytes");
273 
274  queue->Initialize ();
275 
276  Enqueue (queue, pktSize, 500);
277  queue->Enqueue (Create<CodelQueueDiscTestItem> (p1, dest, 0));
278  queue->Enqueue (Create<CodelQueueDiscTestItem> (p2, dest, 0));
279  queue->Enqueue (Create<CodelQueueDiscTestItem> (p3, dest, 0));
280 
281  QueueTestSize (queue, 500 * modeSize, "There should be 500 packets in queue");
282  NS_TEST_EXPECT_MSG_EQ (queue->GetDropOverLimit (), 3, "There should be three packets being dropped due to full queue");
283 }
284 
285 void
286 CoDelQueueDiscBasicOverflow::Enqueue (Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt)
287 {
288  Address dest;
289  for (uint32_t i = 0; i < nPkt; i++)
290  {
291  queue->Enqueue (Create<CodelQueueDiscTestItem> (Create<Packet> (size), dest, 0));
292  }
293 }
294 
295 // Test 3: NewtonStep unit test
296 // test against explicit port of Linux implementation
298 {
299 public:
301  virtual void DoRun (void);
302 };
303 
305  : TestCase ("NewtonStep arithmetic unit test")
306 {
307 }
308 
309 void
311 {
312  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc> ();
313 
314  // Spot check a few points in the expected operational range of
315  // CoDelQueueDisc's m_count and m_recInvSqrt variables
316  uint32_t count = 2;
317  uint16_t recInvSqrt = 65535;
318  queue->m_count = count;
319  queue->m_recInvSqrt = recInvSqrt;
320  queue->NewtonStep ();
321  // Test that ns-3 value is exactly the same as the Linux value
322  NS_TEST_ASSERT_MSG_EQ (_codel_Newton_step (count, recInvSqrt), queue->m_recInvSqrt,
323  "ns-3 NewtonStep() fails to match Linux equivalent");
324 
325  count = 4;
326  recInvSqrt = 36864;
327  queue->m_count = count;
328  queue->m_recInvSqrt = recInvSqrt;
329  queue->NewtonStep ();
330  // Test that ns-3 value is exactly the same as the Linux value
331  NS_TEST_ASSERT_MSG_EQ (_codel_Newton_step (count, recInvSqrt), queue->m_recInvSqrt,
332  "ns-3 NewtonStep() fails to match Linux equivalent");
333 }
334 
335 // Test 4: ControlLaw unit test
336 // test against explicit port of Linux implementation
338 {
339 public:
341  virtual void DoRun (void);
342  uint32_t _codel_control_law (Ptr<CoDelQueueDisc> queue, uint32_t t);
343 };
344 
346  : TestCase ("ControlLaw arithmetic unit test")
347 {
348 }
349 
350 // The following code borrowed from Linux codel.h,
351 // except the addition of queue parameter
352 uint32_t
354 {
355  return t + _reciprocal_scale (queue->Time2CoDel (queue->m_interval), queue->m_recInvSqrt << REC_INV_SQRT_SHIFT_ns3);
356 }
357 // End Linux borrrow
358 
359 void
361 {
362  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc> ();
363 
364  /* Spot check a few points of m_dropNext
365  The integer approximations in Linux should be within
366  2% of the true floating point value obtained in ns-3
367  */
368  uint32_t dropNextTestVals [4] = {292299, 341128, 9804717, 55885007};
369 
370  for (int i = 0; i < 4; ++i)
371  {
372  uint32_t ns3Result = queue->ControlLaw (dropNextTestVals[i]);
373  uint32_t upperBound = ns3Result + 0.02 * ns3Result;
374  uint32_t lowerBound = ns3Result - 0.02 * ns3Result;
375  uint32_t linuxResult = _codel_control_law (queue, dropNextTestVals[i]);
376  NS_TEST_EXPECT_MSG_EQ ((lowerBound < linuxResult || linuxResult < upperBound), true,
377  "Linux result should stay within 2% of ns-3 result");
378  }
379 }
380 
381 // Test 5: enqueue/dequeue with drops according to CoDel algorithm
383 {
384 public:
385  CoDelQueueDiscBasicDrop (std::string mode);
386  virtual void DoRun (void);
387 
388  void QueueTestSize (Ptr<CoDelQueueDisc> queue, uint32_t size, std::string error)
389  {
390  if (queue->GetMode () == Queue::QUEUE_MODE_BYTES)
391  {
392  NS_TEST_EXPECT_MSG_EQ (queue->GetNBytes (), size, error);
393  }
394  else if (queue->GetMode () == Queue::QUEUE_MODE_PACKETS)
395  {
396  NS_TEST_EXPECT_MSG_EQ (queue->GetNPackets (), size, error);
397  }
398 
399  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), size, error);
400  }
401 
402 private:
403  void Enqueue (Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt);
404  void Dequeue (Ptr<CoDelQueueDisc> queue, uint32_t modeSize);
405  void DropNextTracer (uint32_t oldVal, uint32_t newVal);
407  uint32_t m_dropNextCount; //count the number of times m_dropNext is recalculated
408 };
409 
411  : TestCase ("Basic drop operations for " + mode)
412 {
413  m_mode = StringValue (mode);
414  m_dropNextCount = 0;
415 }
416 
417 void
418 CoDelQueueDiscBasicDrop::DropNextTracer (uint32_t oldVal, uint32_t newVal)
419 {
420  m_dropNextCount++;
421 }
422 
423 void
425 {
426  Ptr<CoDelQueueDisc> queue = CreateObject<CoDelQueueDisc> ();
427  uint32_t pktSize = 1000;
428  uint32_t modeSize = 0;
429 
430  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", m_mode), true,
431  "Verify that we can actually set the attribute Mode");
432 
433  if (queue->GetMode () == Queue::QUEUE_MODE_BYTES)
434  {
435  modeSize = pktSize;
436  }
437  else if (queue->GetMode () == Queue::QUEUE_MODE_PACKETS)
438  {
439  modeSize = 1;
440  }
441 
442  queue->Initialize ();
443 
444  Enqueue (queue, pktSize, 20);
445  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 20 * modeSize, "There should be 20 packets in queue.");
446 
447  // Although the first dequeue occurs with a sojourn time above target
448  // the dequeue should be successful in this interval
449  Time waitUntilFirstDequeue = 2 * queue->GetTarget ();
450  Simulator::Schedule (waitUntilFirstDequeue, &CoDelQueueDiscBasicDrop::Dequeue, this, queue, modeSize);
451 
452  // This dequeue should cause a drop
453  Time waitUntilSecondDequeue = waitUntilFirstDequeue + 2 * queue->GetInterval ();
454  Simulator::Schedule (waitUntilSecondDequeue, &CoDelQueueDiscBasicDrop::Dequeue, this, queue, modeSize);
455 
456  // Although we are in dropping state, it's not time for next drop
457  // the dequeue should not cause a drop
458  Simulator::Schedule (waitUntilSecondDequeue, &CoDelQueueDiscBasicDrop::Dequeue, this, queue, modeSize);
459 
460  // In dropping time and it's time for next drop
461  // the dequeue should cause additional packet drops
462  Simulator::Schedule (waitUntilSecondDequeue * 2, &CoDelQueueDiscBasicDrop::Dequeue, this, queue, modeSize);
463 
464  Simulator::Run ();
465  Simulator::Destroy ();
466 }
467 
468 void
469 CoDelQueueDiscBasicDrop::Enqueue (Ptr<CoDelQueueDisc> queue, uint32_t size, uint32_t nPkt)
470 {
471  Address dest;
472  for (uint32_t i = 0; i < nPkt; i++)
473  {
474  queue->Enqueue (Create<CodelQueueDiscTestItem> (Create<Packet> (size), dest, 0));
475  }
476 }
477 
478 void
480 {
481  uint32_t initialDropCount = queue->GetDropCount ();
482  uint32_t initialQSize = queue->GetQueueSize ();
483  uint32_t initialDropNext = queue->GetDropNext ();
484  Time currentTime = Simulator::Now ();
485  uint32_t currentDropCount = 0;
486 
487  if (initialDropCount > 0 && currentTime.GetMicroSeconds () >= initialDropNext)
488  {
490  }
491 
492  if (initialQSize != 0)
493  {
494  Ptr<QueueDiscItem> item = queue->Dequeue ();
495  if (initialDropCount == 0 && currentTime > queue->GetTarget ())
496  {
497  if (currentTime < queue->GetInterval ())
498  {
499  currentDropCount = queue->GetDropCount ();
500  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "We are not in dropping state."
501  "Sojourn time has just gone above target from below."
502  "Hence, there should be no packet drops");
503  QueueTestSize (queue, initialQSize - modeSize, "There should be 1 packet dequeued.");
504 
505  }
506  else if (currentTime >= queue->GetInterval ())
507  {
508  currentDropCount = queue->GetDropCount ();
509  QueueTestSize (queue, initialQSize - 2 * modeSize, "Sojourn time has been above target for at least interval."
510  "We enter the dropping state, perform initial packet drop, and dequeue the next."
511  "So there should be 2 more packets dequeued.");
512  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 1, "There should be 1 packet drop");
513  }
514  }
515  else if (initialDropCount > 0)
516  { // In dropping state
517  if (currentTime.GetMicroSeconds () < initialDropNext)
518  {
519  currentDropCount = queue->GetDropCount ();
520  QueueTestSize (queue, initialQSize - modeSize, "We are in dropping state."
521  "Sojourn is still above target."
522  "However, it's not time for next drop."
523  "So there should be only 1 more packet dequeued");
524 
525  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 1, "There should still be only 1 packet drop from the last dequeue");
526  }
527  else if (currentTime.GetMicroSeconds () >= initialDropNext)
528  {
529  currentDropCount = queue->GetDropCount ();
530  QueueTestSize (queue, initialQSize - (m_dropNextCount + 1) * modeSize, "We are in dropping state."
531  "It's time for next drop."
532  "The number of packets dequeued equals to the number of times m_dropNext is updated plus initial dequeue");
533  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 1 + m_dropNextCount, "The number of drops equals to the number of times m_dropNext is updated plus 1 from last dequeue");
534  }
535  }
536  }
537 }
538 
539 static class CoDelQueueDiscTestSuite : public TestSuite
540 {
541 public:
543  : TestSuite ("codel-queue-disc", UNIT)
544  {
545  // Test 1: simple enqueue/dequeue with no drops
546  AddTestCase (new CoDelQueueDiscBasicEnqueueDequeue ("QUEUE_MODE_PACKETS"), TestCase::QUICK);
547  AddTestCase (new CoDelQueueDiscBasicEnqueueDequeue ("QUEUE_MODE_BYTES"), TestCase::QUICK);
548  // Test 2: enqueue with drops due to queue overflow
549  AddTestCase (new CoDelQueueDiscBasicOverflow ("QUEUE_MODE_PACKETS"), TestCase::QUICK);
550  AddTestCase (new CoDelQueueDiscBasicOverflow ("QUEUE_MODE_BYTES"), TestCase::QUICK);
551  // Test 3: test NewtonStep() against explicit port of Linux implementation
552  AddTestCase (new CoDelQueueDiscNewtonStepTest (), TestCase::QUICK);
553  // Test 4: test ControlLaw() against explicit port of Linux implementation
554  AddTestCase (new CoDelQueueDiscControlLawTest (), TestCase::QUICK);
555  // Test 5: enqueue/dequeue with drops according to CoDel algorithm
556  AddTestCase (new CoDelQueueDiscBasicDrop ("QUEUE_MODE_PACKETS"), TestCase::QUICK);
557  AddTestCase (new CoDelQueueDiscBasicDrop ("QUEUE_MODE_BYTES"), TestCase::QUICK);
558  }
virtual void DoRun(void)
Implementation to actually run this TestCase.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
virtual void DoRun(void)
Implementation to actually run this TestCase.
bool Enqueue(Ptr< QueueDiscItem > item)
Pass a packet to store to the queue discipline.
Definition: queue-disc.cc:451
uint32_t GetDropOverLimit(void)
Get the number of packets dropped when packets arrive at a full queue and cannot be enqueued...
Hold variables of type string.
Definition: string.h:41
uint32_t GetDropNext(void)
Get the time for next packet drop while in the dropping state.
virtual void DoRun(void)
Implementation to actually run this TestCase.
uint32_t GetNBytes(void) const
Get the amount of bytes stored by the queue disc.
Definition: queue-disc.cc:237
TracedValue< uint32_t > m_count
Number of packets dropped since entering drop state.
A suite of tests to run.
Definition: test.h:1333
#define REC_INV_SQRT_SHIFT_ns3
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:368
Time GetInterval(void)
Get the interval.
#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:278
void Dequeue(Ptr< CoDelQueueDisc > queue, uint32_t modeSize)
bool SetAttributeFailSafe(std::string name, const AttributeValue &value)
Set a single attribute without raising errors.
Definition: object-base.cc:211
QueueDiscItem is the abstract base class for items that are stored in a queue disc.
Definition: queue-disc.h:43
encapsulates test code
Definition: test.h:1147
This test suite implements a Unit Test.
Definition: test.h:1343
uint32_t ControlLaw(uint32_t t)
Determine the time for next drop CoDel control law is t + m_interval/sqrt(m_count).
void DropNextTracer(uint32_t oldVal, uint32_t newVal)
void Enqueue(Ptr< CoDelQueueDisc > queue, uint32_t size, uint32_t nPkt)
a polymophic address class
Definition: address.h:90
Queue::QueueMode GetMode(void)
Get the encapsulation mode of this device.
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:349
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:298
static uint16_t _codel_Newton_step(uint32_t count, uint16_t rec_inv_sqrt)
Hold an unsigned integer type.
Definition: uinteger.h:44
#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:161
CoDelQueueDiscTestSuite g_coDelQueueTestSuite
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
virtual void AddHeader(void)
Add the header to the packet.
uint32_t GetQueueSize(void)
Get the current value of the queue in bytes or packets.
uint32_t GetDropCount(void)
Get the number of packets dropped according to CoDel algorithm.
Time m_interval
100 ms sliding minimum time window width
virtual void DoRun(void)
Implementation to actually run this TestCase.
Ptr< QueueDiscItem > Dequeue(void)
Request the queue discipline to extract a packet.
Definition: queue-disc.cc:467
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:299
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint16_t m_recInvSqrt
Reciprocal inverse square root.
uint32_t _codel_control_law(Ptr< CoDelQueueDisc > queue, uint32_t t)
Time GetTarget(void)
Get the target queue delay.
void NewtonStep(void)
Calculate the reciprocal square root of m_count by using Newton's method http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Iterative_methods_for_reciprocal_square_roots m_recInvSqrt (new) = (m_recInvSqrt (old) / 2) * (3 - m_count * m_recInvSqrt^2)
void QueueTestSize(Ptr< CoDelQueueDisc > queue, uint32_t size, std::string error)
void Enqueue(Ptr< CoDelQueueDisc > queue, uint32_t size, uint32_t nPkt)
uint32_t Time2CoDel(Time t)
returned unsigned 32-bit integer representation of the input Time object units are microseconds ...
void QueueTestSize(Ptr< CoDelQueueDisc > queue, uint32_t size, std::string error)
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:340
static uint32_t _reciprocal_scale(uint32_t val, uint32_t ep_ro)
void QueueTestSize(Ptr< CoDelQueueDisc > queue, uint32_t size, std::string error)
virtual void DoRun(void)
Implementation to actually run this TestCase.
void Initialize(void)
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:183
uint32_t GetNPackets(void) const
Get the number of packets stored by the queue disc.
Definition: queue-disc.cc:230