A Discrete-Event Network Simulator
API
cobalt-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) 2019 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  * Ported to ns-3 by: Vignesh Kannan <vignesh2496@gmail.com>
19  * Harsh Lara <harshapplefan@gmail.com>
20  * Jendaipou Palmei <jendaipoupalmei@gmail.com>
21  * Shefali Gupta <shefaligups11@gmail.com>
22  * Mohit P. Tahiliani <tahiliani@nitk.edu.in>
23  */
24 
25 #include "ns3/test.h"
26 #include "ns3/cobalt-queue-disc.h"
27 #include "ns3/packet.h"
28 #include "ns3/uinteger.h"
29 #include "ns3/string.h"
30 #include "ns3/double.h"
31 #include "ns3/log.h"
32 #include "ns3/simulator.h"
33 
34 using namespace ns3;
42 {
43 public:
52  CobaltQueueDiscTestItem (Ptr<Packet> p, const Address & addr,uint16_t protocol, bool ecnCapable);
53  virtual ~CobaltQueueDiscTestItem ();
54  virtual void AddHeader (void);
55  virtual bool Mark (void);
56 
57 private:
71 };
72 
73 CobaltQueueDiscTestItem::CobaltQueueDiscTestItem (Ptr<Packet> p, const Address & addr,uint16_t protocol, bool ecnCapable)
74  : QueueDiscItem (p, addr, ecnCapable),
75  m_ecnCapablePacket (ecnCapable)
76 {
77 }
78 
80 {
81 }
82 
83 void
85 {
86 }
87 
88 bool
90 {
92  {
93  return true;
94  }
95  return false;
96 }
97 
105 {
106 public:
113  virtual void DoRun (void);
114 
123 private:
125 };
126 
128  : TestCase ("Basic enqueue and dequeue operations, and attribute setting" + std::to_string (mode))
129 {
130  m_mode = mode;
131 }
132 
133 void
135 {
136  Ptr<CobaltQueueDisc> queue = CreateObject<CobaltQueueDisc> ();
137 
138  uint32_t pktSize = 1000;
139  uint32_t modeSize = 0;
140 
141  Address dest;
142 
143  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Interval", StringValue ("50ms")), true,
144  "Verify that we can actually set the attribute Interval");
145  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Target", StringValue ("4ms")), true,
146  "Verify that we can actually set the attribute Target");
147 
149  {
150  modeSize = pktSize;
151  }
152  else if (m_mode == QueueSizeUnit::PACKETS)
153  {
154  modeSize = 1;
155  }
156  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (m_mode, modeSize * 1500))),
157  true, "Verify that we can actually set the attribute MaxSize");
158  queue->Initialize ();
159 
160  Ptr<Packet> p1, p2, p3, p4, p5, p6;
161  p1 = Create<Packet> (pktSize);
162  p2 = Create<Packet> (pktSize);
163  p3 = Create<Packet> (pktSize);
164  p4 = Create<Packet> (pktSize);
165  p5 = Create<Packet> (pktSize);
166  p6 = Create<Packet> (pktSize);
167 
168  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 0 * modeSize, "There should be no packets in queue");
169  queue->Enqueue (Create<CobaltQueueDiscTestItem> (p1, dest,0, false));
170  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 1 * modeSize, "There should be one packet in queue");
171  queue->Enqueue (Create<CobaltQueueDiscTestItem> (p2, dest,0, false));
172  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 2 * modeSize, "There should be two packets in queue");
173  queue->Enqueue (Create<CobaltQueueDiscTestItem> (p3, dest,0, false));
174  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 3 * modeSize, "There should be three packets in queue");
175  queue->Enqueue (Create<CobaltQueueDiscTestItem> (p4, dest,0, false));
176  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 4 * modeSize, "There should be four packets in queue");
177  queue->Enqueue (Create<CobaltQueueDiscTestItem> (p5, dest,0, false));
178  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 5 * modeSize, "There should be five packets in queue");
179  queue->Enqueue (Create<CobaltQueueDiscTestItem> (p6, dest,0, false));
180  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 6 * modeSize, "There should be six packets in queue");
181 
182  NS_TEST_EXPECT_MSG_EQ (queue->GetStats ().GetNDroppedPackets (CobaltQueueDisc::OVERLIMIT_DROP), 0, "There should be no packets being dropped due to full queue");
183 
184  Ptr<QueueDiscItem> item;
185 
186  item = queue->Dequeue ();
187  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the first packet");
188  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 5 * modeSize, "There should be five packets in queue");
189  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p1->GetUid (), "was this the first packet ?");
190 
191  item = queue->Dequeue ();
192  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the second packet");
193  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 4 * modeSize, "There should be four packets in queue");
194  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p2->GetUid (), "Was this the second packet ?");
195 
196  item = queue->Dequeue ();
197  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the third packet");
198  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 3 * modeSize, "There should be three packets in queue");
199  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p3->GetUid (), "Was this the third packet ?");
200 
201  item = queue->Dequeue ();
202  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the forth packet");
203  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 2 * modeSize, "There should be two packets in queue");
204  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p4->GetUid (), "Was this the fourth packet ?");
205 
206  item = queue->Dequeue ();
207  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the fifth packet");
208  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 1 * modeSize, "There should be one packet in queue");
209  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p5->GetUid (), "Was this the fifth packet ?");
210 
211  item = queue->Dequeue ();
212  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the last packet");
213  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 0 * modeSize, "There should be zero packet in queue");
214  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p6->GetUid (), "Was this the sixth packet ?");
215 
216  item = queue->Dequeue ();
217  NS_TEST_EXPECT_MSG_EQ ((item == 0), true, "There are really no packets in queue");
218 
219  NS_TEST_EXPECT_MSG_EQ (queue->GetStats ().GetNDroppedPackets (CobaltQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should be no packet drops according to Cobalt algorithm");
220 }
221 
229 {
230 public:
232  virtual void DoRun (void);
239  void Enqueue (Ptr<CobaltQueueDisc> queue, uint32_t size, uint32_t nPkt);
244  void RunDropTest (QueueSizeUnit mode);
245 
246  void EnqueueWithDelay (Ptr<CobaltQueueDisc> queue, uint32_t size, uint32_t nPkt);
247 
248 };
249 
251  : TestCase ("Drop tests verification for both packets and bytes mode")
252 {
253 }
254 
255 void
257 
258 {
259  uint32_t pktSize = 1500;
260  uint32_t modeSize = 0;
261  Ptr<CobaltQueueDisc> queue = CreateObject<CobaltQueueDisc> ();
262 
263  if (mode == QueueSizeUnit::BYTES)
264  {
265  modeSize = pktSize;
266  }
267  else if (mode == QueueSizeUnit::PACKETS)
268  {
269  modeSize = 1;
270  }
271 
272  queue = CreateObject<CobaltQueueDisc> ();
273  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, modeSize * 100))),
274  true, "Verify that we can actually set the attribute MaxSize");
275 
276  queue->Initialize ();
277 
278  if (mode == QueueSizeUnit::BYTES)
279  {
280  EnqueueWithDelay (queue, pktSize, 200);
281  }
282  else
283  {
284  EnqueueWithDelay (queue, 1, 200);
285  }
286 
287  Simulator::Stop (Seconds (8.0));
288  Simulator::Run ();
289 
290  QueueDisc::Stats st = queue->GetStats ();
291 
292 // The Pdrop value should increase, from it's default value of zero
293  NS_TEST_EXPECT_MSG_NE (queue->GetPdrop (), 0, "Pdrop should be non-zero");
294  NS_TEST_EXPECT_MSG_NE (st.GetNDroppedPackets (CobaltQueueDisc::OVERLIMIT_DROP), 0, "Drops due to queue overflow should be non-zero");
295 }
296 
297 void
299 {
300  Address dest;
301  double delay = 0.01; // enqueue packets with delay
302  for (uint32_t i = 0; i < nPkt; i++)
303  {
304  Simulator::Schedule (Time (Seconds ((i + 1) * delay)), &CobaltQueueDiscDropTest::Enqueue, this, queue, size, 1);
305  }
306 }
307 
308 void
309 CobaltQueueDiscDropTest::Enqueue (Ptr<CobaltQueueDisc> queue, uint32_t size, uint32_t nPkt)
310 {
311  Address dest;
312  for (uint32_t i = 0; i < nPkt; i++)
313  {
314  queue->Enqueue (Create<CobaltQueueDiscTestItem> (Create<Packet> (size), dest, 0, true));
315  }
316 }
317 
318 void
320 {
323  Simulator::Destroy ();
324 }
325 
333 {
334 public:
341  virtual void DoRun (void);
342 
343 private:
351  void Enqueue (Ptr<CobaltQueueDisc> queue, uint32_t size, uint32_t nPkt, bool ecnCapable);
358  void Dequeue (Ptr<CobaltQueueDisc> queue, uint32_t modeSize, uint32_t testCase);
364  void DropNextTracer (int64_t oldVal, int64_t newVal);
366  uint32_t m_dropNextCount;
369 };
370 
372  : TestCase ("Basic mark operations")
373 {
374  m_mode = mode;
375  m_dropNextCount = 0;
376 }
377 
378 void
379 CobaltQueueDiscMarkTest::DropNextTracer (int64_t oldVal, int64_t newVal)
380 {
381  NS_UNUSED (oldVal);
382  NS_UNUSED (newVal);
383  m_dropNextCount++;
384 }
385 
386 void
388 {
389  // Test is divided into 3 sub test cases:
390  // 1) Packets are not ECN capable.
391  // 2) Packets are ECN capable.
392  // 3) Some packets are ECN capable.
393 
394  // Test case 1
395  Ptr<CobaltQueueDisc> queue = CreateObject<CobaltQueueDisc> ();
396  uint32_t pktSize = 1000;
397  uint32_t modeSize = 0;
400 
402  {
403  modeSize = pktSize;
404  }
405  else if (m_mode == QueueSizeUnit::PACKETS)
406  {
407  modeSize = 1;
408  }
409 
410  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (m_mode, modeSize * 500))),
411  true, "Verify that we can actually set the attribute MaxSize");
412  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (false)),
413  true, "Verify that we can actually set the attribute UseEcn");
414 
415  queue->Initialize ();
416 
417  // Not-ECT traffic to induce packet drop
418  Enqueue (queue, pktSize, 20, false);
419  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 20 * modeSize, "There should be 20 packets in queue.");
420 
421  // Although the first dequeue occurs with a sojourn time above target
422  // there should not be any dropped packets in this interval
423  Time waitUntilFirstDequeue = 2 * queue->GetTarget ();
424  Simulator::Schedule (waitUntilFirstDequeue, &CobaltQueueDiscMarkTest::Dequeue, this, queue, modeSize, 1);
425 
426  // This dequeue should cause a packet to be dropped
427  Time waitUntilSecondDequeue = waitUntilFirstDequeue + 2 * queue->GetInterval ();
428  Simulator::Schedule (waitUntilSecondDequeue, &CobaltQueueDiscMarkTest::Dequeue, this, queue, modeSize, 1);
429 
430  Simulator::Run ();
431  Simulator::Destroy ();
432 
433  // Test case 2, queue with ECN capable traffic for marking of packets instead of dropping
434  queue = CreateObject<CobaltQueueDisc> ();
435  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (m_mode, modeSize * 500))),
436  true, "Verify that we can actually set the attribute MaxSize");
437  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (true)),
438  true, "Verify that we can actually set the attribute UseEcn");
439 
440  queue->Initialize ();
441 
442  // ECN capable traffic
443  Enqueue (queue, pktSize, 20, true);
444  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 20 * modeSize, "There should be 20 packets in queue.");
445 
446  // Although the first dequeue occurs with a sojourn time above target
447  // there should not be any marked packets in this interval
448  Simulator::Schedule (waitUntilFirstDequeue, &CobaltQueueDiscMarkTest::Dequeue, this, queue, modeSize, 2);
449 
450  // This dequeue should cause a packet to be marked
451  Simulator::Schedule (waitUntilSecondDequeue, &CobaltQueueDiscMarkTest::Dequeue, this, queue, modeSize, 2);
452 
453  // This dequeue should cause a packet to be marked as dropnext is equal to current time
454  Simulator::Schedule (waitUntilSecondDequeue, &CobaltQueueDiscMarkTest::Dequeue, this, queue, modeSize, 2);
455 
456  // In dropping phase and it's time for next packet to be marked
457  // the dequeue should cause additional packet to be marked
458  Simulator::Schedule (waitUntilSecondDequeue * 2, &CobaltQueueDiscMarkTest::Dequeue, this, queue, modeSize, 2);
459 
460  Simulator::Run ();
461  Simulator::Destroy ();
462 
463  // Test case 3, some packets are ECN capable
464  queue = CreateObject<CobaltQueueDisc> ();
465  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (m_mode, modeSize * 500))),
466  true, "Verify that we can actually set the attribute MaxSize");
467  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (true)),
468  true, "Verify that we can actually set the attribute UseEcn");
469 
470  queue->Initialize ();
471 
472  // First 3 packets in the queue are ecnCapable
473  Enqueue (queue, pktSize, 3, true);
474  // Rest of the packet are not ecnCapable
475  Enqueue (queue, pktSize, 17, false);
476  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 20 * modeSize, "There should be 20 packets in queue.");
477 
478  // Although the first dequeue occurs with a sojourn time above target
479  // there should not be any marked packets in this interval
480  Simulator::Schedule (waitUntilFirstDequeue, &CobaltQueueDiscMarkTest::Dequeue, this, queue, modeSize, 3);
481 
482  // This dequeue should cause a packet to be marked
483  Simulator::Schedule (waitUntilSecondDequeue, &CobaltQueueDiscMarkTest::Dequeue, this, queue, modeSize, 3);
484 
485  // This dequeue should cause a packet to be marked as dropnext is equal to current time
486  Simulator::Schedule (waitUntilSecondDequeue, &CobaltQueueDiscMarkTest::Dequeue, this, queue, modeSize, 3);
487 
488  // In dropping phase and it's time for next packet to be dropped as packets are not ECN capable
489  // the dequeue should cause packet to be dropped
490  Simulator::Schedule (waitUntilSecondDequeue * 2, &CobaltQueueDiscMarkTest::Dequeue, this, queue, modeSize, 3);
491 
492  Simulator::Run ();
493  Simulator::Destroy ();
494 }
495 
496 void
497 CobaltQueueDiscMarkTest::Enqueue (Ptr<CobaltQueueDisc> queue, uint32_t size, uint32_t nPkt, bool ecnCapable)
498 {
499  Address dest;
500  for (uint32_t i = 0; i < nPkt; i++)
501  {
502  queue->Enqueue (Create<CobaltQueueDiscTestItem> (Create<Packet> (size), dest, 0, ecnCapable));
503  }
504 }
505 
506 void
507 CobaltQueueDiscMarkTest::Dequeue (Ptr<CobaltQueueDisc> queue, uint32_t modeSize, uint32_t testCase)
508 {
509  uint32_t initialMarkCount = queue->GetStats ().GetNMarkedPackets (CobaltQueueDisc::FORCED_MARK);
510  uint32_t initialQSize = queue->GetCurrentSize ().GetValue ();
511  uint32_t initialDropNext = queue->GetDropNext ();
512  Time currentTime = Simulator::Now ();
513  uint32_t currentDropCount = 0;
514  uint32_t currentMarkCount = 0;
515 
516  if (initialMarkCount > 0 && currentTime.GetNanoSeconds () > initialDropNext && testCase == 3)
517  {
519  }
520 
521  if (initialQSize != 0)
522  {
523  Ptr<QueueDiscItem> item = queue->Dequeue ();
524  if (testCase == 1)
525  {
526  currentDropCount = queue->GetStats ().GetNDroppedPackets (CobaltQueueDisc::TARGET_EXCEEDED_DROP);
527  if (currentDropCount != 0)
528  {
529  nPacketsBeforeFirstDrop = initialQSize;
530  }
531  }
532  if (testCase == 2)
533  {
534  if (initialMarkCount == 0 && currentTime > queue->GetTarget ())
535  {
536  if (currentTime < queue->GetInterval ())
537  {
538  currentDropCount = queue->GetStats ().GetNDroppedPackets (CobaltQueueDisc::TARGET_EXCEEDED_DROP);
539  currentMarkCount = queue->GetStats ().GetNMarkedPackets (CobaltQueueDisc::FORCED_MARK);
540  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize, "There should be 1 packet dequeued.");
541  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "There should not be any packet drops");
542  NS_TEST_ASSERT_MSG_EQ (currentMarkCount, 0, "We are not in dropping state."
543  "Sojourn time has just gone above target from below."
544  "Hence, there should be no marked packets");
545  }
546  else if (currentTime >= queue->GetInterval ())
547  {
548  nPacketsBeforeFirstMark = initialQSize;
549  currentDropCount = queue->GetStats ().GetNDroppedPackets (CobaltQueueDisc::TARGET_EXCEEDED_DROP);
550  currentMarkCount = queue->GetStats ().GetNMarkedPackets (CobaltQueueDisc::FORCED_MARK);
551  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize,
552  "Sojourn time has been above target for at least interval."
553  "We enter the dropping state and perform initial packet marking"
554  "So there should be only 1 more packet dequeued.");
555  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "There should not be any packet drops");
556  NS_TEST_EXPECT_MSG_EQ (currentMarkCount, 1, "There should be 1 marked packet");
557  }
558  }
559  else if (initialMarkCount > 0)
560  {
561  if (currentTime.GetNanoSeconds () <= initialDropNext)
562  {
563  currentDropCount = queue->GetStats ().GetNDroppedPackets (CobaltQueueDisc::TARGET_EXCEEDED_DROP);
564  currentMarkCount = queue->GetStats ().GetNMarkedPackets (CobaltQueueDisc::FORCED_MARK);
565  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize, "We are in dropping state."
566  "Sojourn is still above target."
567  "There should be only 1 more packet dequeued");
568  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "There should not be any packet drops");
569  NS_TEST_EXPECT_MSG_EQ (currentMarkCount, 2, "There should be 2 marked packet as."
570  "current dropnext is equal to current time.");
571  }
572  else if (currentTime.GetNanoSeconds () > initialDropNext)
573  {
574  currentDropCount = queue->GetStats ().GetNDroppedPackets (CobaltQueueDisc::TARGET_EXCEEDED_DROP);
575  currentMarkCount = queue->GetStats ().GetNMarkedPackets (CobaltQueueDisc::FORCED_MARK);
576  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize, "We are in dropping state."
577  "It's time for packet to be marked"
578  "So there should be only 1 more packet dequeued");
579  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "There should not be any packet drops");
580  NS_TEST_EXPECT_MSG_EQ (currentMarkCount, 3, "There should be 3 marked packet");
581  NS_TEST_EXPECT_MSG_EQ (nPacketsBeforeFirstDrop, nPacketsBeforeFirstMark, "Number of packets in the queue before drop should be equal"
582  "to number of packets in the queue before first mark as the behavior until packet N should be the same.");
583  }
584  }
585  }
586  else if (testCase == 3)
587  {
588  if (initialMarkCount == 0 && currentTime > queue->GetTarget ())
589  {
590  if (currentTime < queue->GetInterval ())
591  {
592  currentDropCount = queue->GetStats ().GetNDroppedPackets (CobaltQueueDisc::TARGET_EXCEEDED_DROP);
593  currentMarkCount = queue->GetStats ().GetNMarkedPackets (CobaltQueueDisc::FORCED_MARK);
594  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize, "There should be 1 packet dequeued.");
595  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "There should not be any packet drops");
596  NS_TEST_ASSERT_MSG_EQ (currentMarkCount, 0, "We are not in dropping state."
597  "Sojourn time has just gone above target from below."
598  "Hence, there should be no marked packets");
599  }
600  else if (currentTime >= queue->GetInterval ())
601  {
602  currentDropCount = queue->GetStats ().GetNDroppedPackets (CobaltQueueDisc::TARGET_EXCEEDED_DROP);
603  currentMarkCount = queue->GetStats ().GetNMarkedPackets (CobaltQueueDisc::FORCED_MARK);
604  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize,
605  "Sojourn time has been above target for at least interval."
606  "We enter the dropping state and perform initial packet marking"
607  "So there should be only 1 more packet dequeued.");
608  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "There should not be any packet drops");
609  NS_TEST_EXPECT_MSG_EQ (currentMarkCount, 1, "There should be 1 marked packet");
610  }
611  }
612  else if (initialMarkCount > 0)
613  {
614  if (currentTime.GetNanoSeconds () <= initialDropNext)
615  {
616  currentDropCount = queue->GetStats ().GetNDroppedPackets (CobaltQueueDisc::TARGET_EXCEEDED_DROP);
617  currentMarkCount = queue->GetStats ().GetNMarkedPackets (CobaltQueueDisc::FORCED_MARK);
618  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - modeSize, "We are in dropping state."
619  "Sojourn is still above target."
620  "So there should be only 1 more packet dequeued");
621  NS_TEST_EXPECT_MSG_EQ (currentDropCount, 0, "There should not be any packet drops");
622  NS_TEST_EXPECT_MSG_EQ (currentMarkCount, 2, "There should be 2 marked packet"
623  "as dropnext is equal to current time");
624  }
625  else if (currentTime.GetNanoSeconds () > initialDropNext)
626  {
627  currentDropCount = queue->GetStats ().GetNDroppedPackets (CobaltQueueDisc::TARGET_EXCEEDED_DROP);
628  currentMarkCount = queue->GetStats ().GetNMarkedPackets (CobaltQueueDisc::FORCED_MARK);
629  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), initialQSize - (m_dropNextCount + 1) * modeSize, "We are in dropping state."
630  "It's time for packet to be dropped as packets are not ecnCapable"
631  "The number of packets dequeued equals to the number of times m_dropNext is updated plus initial dequeue");
632  NS_TEST_EXPECT_MSG_EQ (currentDropCount, m_dropNextCount, "The number of drops equals to the number of times m_dropNext is updated");
633  NS_TEST_EXPECT_MSG_EQ (currentMarkCount, 2, "There should still be only 2 marked packet");
634  }
635  }
636  }
637  }
638 }
639 
640 static class CobaltQueueDiscTestSuite : public TestSuite
641 {
642 public:
644  : TestSuite ("cobalt-queue-disc", UNIT)
645  {
646  // Test 1: simple enqueue/dequeue with no drops
647  AddTestCase (new CobaltQueueDiscBasicEnqueueDequeue (PACKETS), TestCase::QUICK);
648  AddTestCase (new CobaltQueueDiscBasicEnqueueDequeue (BYTES), TestCase::QUICK);
649  // Test 2: Drop test
650  AddTestCase (new CobaltQueueDiscDropTest (), TestCase::QUICK);
651  // Test 3: Mark test
652  AddTestCase (new CobaltQueueDiscMarkTest (PACKETS), TestCase::QUICK);
653  AddTestCase (new CobaltQueueDiscMarkTest (BYTES), TestCase::QUICK);
654  }
Structure that keeps the queue disc statistics.
Definition: queue-disc.h:185
uint64_t GetUid(void) const
Returns the packet&#39;s Uid.
Definition: packet.cc:390
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
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
Hold variables of type string.
Definition: string.h:41
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
void Enqueue(Ptr< CobaltQueueDisc > queue, uint32_t size, uint32_t nPkt)
Enqueue function.
void EnqueueWithDelay(Ptr< CobaltQueueDisc > queue, uint32_t size, uint32_t nPkt)
#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
#define NS_UNUSED(x)
Mark a local variable as unused.
Definition: unused.h:36
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:1153
Time GetInterval(void)
Get the interval.
STL namespace.
uint32_t nPacketsBeforeFirstDrop
Number of packets in the queue before first drop.
Test 1: simple enqueue/dequeue with no drops.
virtual void DoRun(void)
Implementation to actually run this TestCase.
CobaltQueueDiscBasicEnqueueDequeue(QueueSizeUnit mode)
Constructor.
a polymophic address class
Definition: address.h:90
Cobalt Queue Disc Test Item.
int64_t GetDropNext(void)
Get the time for next packet drop while in the dropping state.
virtual void AddHeader(void)
Add the header to the packet.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
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
#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:166
QueueSizeUnit m_mode
Queue test size function.
virtual bool Mark(void)
Marks the packet as a substitute for dropping it, such as for Explicit Congestion Notification...
const Stats & GetStats(void)
Retrieve all the collected statistics.
Definition: queue-disc.cc:421
void DropNextTracer(int64_t oldVal, int64_t newVal)
Drop next tracer function.
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
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:293
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint32_t nPacketsBeforeFirstMark
Number of packets in the queue before first mark.
int64_t GetNanoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:391
Test 3: Cobalt Queue Disc ECN marking Test Item.
Test 2: Cobalt Queue Disc Drop Test Item.
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
bool m_ecnCapablePacket
ECN capable packet?
CobaltQueueDiscTestSuite g_cobaltQueueTestSuite
the test suite
virtual void DoRun(void)
Implementation to actually run this TestCase.
uint32_t m_dropNextCount
count the number of times m_dropNext is recalculated
CobaltQueueDiscMarkTest(QueueSizeUnit mode)
Constructor.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1278
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
double GetPdrop()
Get the drop probability of Blue.
void RunDropTest(QueueSizeUnit mode)
Run Cobalt test function.
This test suite implements a Unit Test.
Definition: test.h:1353
virtual void DoRun(void)
Implementation to actually run this TestCase.
uint32_t pktSize
packet size used for the simulation (in bytes)
Definition: wifi-bianchi.cc:83
Time GetTarget(void)
Get the target queue delay.
Use number of bytes for queue size.
Definition: queue-size.h:45
void Enqueue(Ptr< CobaltQueueDisc > queue, uint32_t size, uint32_t nPkt, bool ecnCapable)
Enqueue function.
void Dequeue(Ptr< CobaltQueueDisc > queue, uint32_t modeSize, uint32_t testCase)
Dequeue function.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
void Initialize(void)
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:183