A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
pie-queue-disc-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016 NITK Surathkal
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Authors: Shravya Ks <shravya.ks0@gmail.com>
18 * Smriti Murali <m.smriti.95@gmail.com>
19 * Mohit P. Tahiliani <tahiliani@nitk.edu.in>
20 *
21 */
22
23#include "ns3/double.h"
24#include "ns3/log.h"
25#include "ns3/packet.h"
26#include "ns3/pie-queue-disc.h"
27#include "ns3/simulator.h"
28#include "ns3/string.h"
29#include "ns3/test.h"
30#include "ns3/uinteger.h"
31
32using namespace ns3;
33
40{
41 public:
49 PieQueueDiscTestItem(Ptr<Packet> p, const Address& addr, bool ecnCapable);
50
51 // Delete default constructor, copy constructor and assignment operator to avoid misuse
55
56 void AddHeader() override;
57 bool Mark() override;
58
59 // ** Variables for testing m_isCapDropAdjustment
61 0.0;
62 double m_prevDropProb = 0.0;
63 bool m_checkProb = false;
64
65 // ** Variable for testing ECN
66 double m_maxDropProb = 0.0;
67 bool m_ecnCapable = false;
68
69 // ** Variables for testing Derandomization
70 bool m_checkAccuProb = false;
71 bool m_constAccuProb = false;
72 bool m_checkMaxAccuProb = false;
73 double m_accuProbError = 0.0;
74 double m_prevAccuProb = 0.0;
75 double m_setAccuProb = 0.0;
77
78 private:
80};
81
83 : QueueDiscItem(p, addr, 0),
84 m_ecnCapablePacket(ecnCapable)
85{
86}
87
88void
90{
91}
92
93bool
95{
97 {
98 return true;
99 }
100 return false;
101}
102
109{
110 public:
112 void DoRun() override;
113
114 private:
122 void Enqueue(Ptr<PieQueueDisc> queue,
123 uint32_t size,
124 uint32_t nPkt,
125 Ptr<PieQueueDiscTestItem> testAttributes);
134 uint32_t size,
135 uint32_t nPkt,
136 Ptr<PieQueueDiscTestItem> testAttributes);
142 void Dequeue(Ptr<PieQueueDisc> queue, uint32_t nPkt);
149 void DequeueWithDelay(Ptr<PieQueueDisc> queue, double delay, uint32_t nPkt);
154 void RunPieTest(QueueSizeUnit mode);
173};
174
176 : TestCase("Sanity check on the pie queue disc implementation")
177{
178}
179
180void
182{
183 uint32_t pktSize = 0;
184
185 // 1 for packets; pktSize for bytes
186 uint32_t modeSize = 1;
187
188 uint32_t qSize = 300;
189 Ptr<PieQueueDisc> queue = CreateObject<PieQueueDisc>();
190
191 // test 1: simple enqueue/dequeue with defaults, no drops
192 Address dest;
193 // PieQueueDiscItem pointer for attributes
194 Ptr<PieQueueDiscTestItem> testAttributes =
195 Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
196
197 if (mode == QueueSizeUnit::BYTES)
198 {
199 // pktSize should be same as MeanPktSize to avoid performance gap between byte and packet
200 // mode
201 pktSize = 1000;
202 modeSize = pktSize;
203 qSize = qSize * modeSize;
204 }
205
207 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
208 true,
209 "Verify that we can actually set the attribute MaxSize");
210
211 Ptr<Packet> p1;
212 Ptr<Packet> p2;
213 Ptr<Packet> p3;
214 Ptr<Packet> p4;
215 Ptr<Packet> p5;
216 Ptr<Packet> p6;
217 Ptr<Packet> p7;
218 Ptr<Packet> p8;
219 p1 = Create<Packet>(pktSize);
220 p2 = Create<Packet>(pktSize);
221 p3 = Create<Packet>(pktSize);
222 p4 = Create<Packet>(pktSize);
223 p5 = Create<Packet>(pktSize);
224 p6 = Create<Packet>(pktSize);
225 p7 = Create<Packet>(pktSize);
226 p8 = Create<Packet>(pktSize);
227
228 queue->Initialize();
229 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
230 0 * modeSize,
231 "There should be no packets in there");
232 queue->Enqueue(Create<PieQueueDiscTestItem>(p1, dest, false));
233 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
234 1 * modeSize,
235 "There should be one packet in there");
236 queue->Enqueue(Create<PieQueueDiscTestItem>(p2, dest, false));
237 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
238 2 * modeSize,
239 "There should be two packets in there");
240 queue->Enqueue(Create<PieQueueDiscTestItem>(p3, dest, false));
241 queue->Enqueue(Create<PieQueueDiscTestItem>(p4, dest, false));
242 queue->Enqueue(Create<PieQueueDiscTestItem>(p5, dest, false));
243 queue->Enqueue(Create<PieQueueDiscTestItem>(p6, dest, false));
244 queue->Enqueue(Create<PieQueueDiscTestItem>(p7, dest, false));
245 queue->Enqueue(Create<PieQueueDiscTestItem>(p8, dest, false));
246 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
247 8 * modeSize,
248 "There should be eight packets in there");
249
251
252 item = queue->Dequeue();
253 NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the first packet");
254 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
255 7 * modeSize,
256 "There should be seven packets in there");
257 NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(), p1->GetUid(), "was this the first packet ?");
258
259 item = queue->Dequeue();
260 NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the second packet");
261 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
262 6 * modeSize,
263 "There should be six packet in there");
264 NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(),
265 p2->GetUid(),
266 "Was this the second packet ?");
267
268 item = queue->Dequeue();
269 NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the third packet");
270 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
271 5 * modeSize,
272 "There should be five packets in there");
273 NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(), p3->GetUid(), "Was this the third packet ?");
274
275 item = queue->Dequeue();
276 item = queue->Dequeue();
277 item = queue->Dequeue();
278 item = queue->Dequeue();
279 item = queue->Dequeue();
280
281 item = queue->Dequeue();
282 NS_TEST_ASSERT_MSG_EQ(item, nullptr, "There are really no packets in there");
283
284 // test 2: more data with defaults, unforced drops but no forced drops
285 queue = CreateObject<PieQueueDisc>();
286 // PieQueueDiscItem pointer for attributes
287 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
288 pktSize = 1000; // pktSize != 0 because DequeueThreshold always works in bytes
290 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
291 true,
292 "Verify that we can actually set the attribute MaxSize");
293 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Tupdate", TimeValue(Seconds(0.03))),
294 true,
295 "Verify that we can actually set the attribute Tupdate");
296 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("DequeueThreshold", UintegerValue(10000)),
297 true,
298 "Verify that we can actually set the attribute DequeueThreshold");
300 queue->SetAttributeFailSafe("QueueDelayReference", TimeValue(Seconds(0.02))),
301 true,
302 "Verify that we can actually set the attribute QueueDelayReference");
303 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxBurstAllowance", TimeValue(Seconds(0.1))),
304 true,
305 "Verify that we can actually set the attribute MaxBurstAllowance");
306 queue->Initialize();
307 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
308 DequeueWithDelay(queue, 0.012, 400);
311 QueueDisc::Stats st = queue->GetStats();
313 NS_TEST_ASSERT_MSG_NE(test2, 0, "There should be some unforced drops");
315 0,
316 "There should be zero forced drops");
317
318 // test 3: same as test 2, but with higher QueueDelayReference
319 queue = CreateObject<PieQueueDisc>();
320 // PieQueueDiscItem pointer for attributes
321 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
323 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
324 true,
325 "Verify that we can actually set the attribute MaxSize");
326 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Tupdate", TimeValue(Seconds(0.03))),
327 true,
328 "Verify that we can actually set the attribute Tupdate");
329 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("DequeueThreshold", UintegerValue(10000)),
330 true,
331 "Verify that we can actually set the attribute DequeueThreshold");
333 queue->SetAttributeFailSafe("QueueDelayReference", TimeValue(Seconds(0.08))),
334 true,
335 "Verify that we can actually set the attribute QueueDelayReference");
336 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxBurstAllowance", TimeValue(Seconds(0.1))),
337 true,
338 "Verify that we can actually set the attribute MaxBurstAllowance");
339 queue->Initialize();
340 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
341 DequeueWithDelay(queue, 0.012, 400);
344 st = queue->GetStats();
346 NS_TEST_ASSERT_MSG_LT(test3, test2, "Test 3 should have less unforced drops than test 2");
348 0,
349 "There should be zero forced drops");
350
351 // test 4: same as test 2, but with reduced dequeue rate
352 queue = CreateObject<PieQueueDisc>();
353 // PieQueueDiscItem pointer for attributes
354 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
356 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
357 true,
358 "Verify that we can actually set the attribute MaxSize");
359 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Tupdate", TimeValue(Seconds(0.03))),
360 true,
361 "Verify that we can actually set the attribute Tupdate");
362 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("DequeueThreshold", UintegerValue(10000)),
363 true,
364 "Verify that we can actually set the attribute DequeueThreshold");
366 queue->SetAttributeFailSafe("QueueDelayReference", TimeValue(Seconds(0.02))),
367 true,
368 "Verify that we can actually set the attribute QueueDelayReference");
369 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxBurstAllowance", TimeValue(Seconds(0.1))),
370 true,
371 "Verify that we can actually set the attribute MaxBurstAllowance");
372 queue->Initialize();
373 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
374 DequeueWithDelay(queue, 0.015, 400); // delay between two successive dequeue events is increased
377 st = queue->GetStats();
379 NS_TEST_ASSERT_MSG_GT(test4, test2, "Test 4 should have more unforced drops than test 2");
381 0,
382 "There should be zero forced drops");
383
384 // test 5: same dequeue rate as test 4, but with higher Tupdate
385 queue = CreateObject<PieQueueDisc>();
386 // PieQueueDiscItem pointer for attributes
387 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
389 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
390 true,
391 "Verify that we can actually set the attribute MaxSize");
392 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Tupdate", TimeValue(Seconds(0.09))),
393 true,
394 "Verify that we can actually set the attribute Tupdate");
395 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("DequeueThreshold", UintegerValue(10000)),
396 true,
397 "Verify that we can actually set the attribute DequeueThreshold");
399 queue->SetAttributeFailSafe("QueueDelayReference", TimeValue(Seconds(0.02))),
400 true,
401 "Verify that we can actually set the attribute QueueDelayReference");
402 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxBurstAllowance", TimeValue(Seconds(0.1))),
403 true,
404 "Verify that we can actually set the attribute MaxBurstAllowance");
405 queue->Initialize();
406 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
407 DequeueWithDelay(queue, 0.015, 400);
410 st = queue->GetStats();
412 NS_TEST_ASSERT_MSG_LT(test5, test4, "Test 5 should have less unforced drops than test 4");
414 0,
415 "There should be zero forced drops");
416
417 // test 6: same as test 2, but with UseDequeueRateEstimator enabled
418 queue = CreateObject<PieQueueDisc>();
419 // PieQueueDiscItem pointer for attributes
420 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
422 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
423 true,
424 "Verify that we can actually set the attribute MaxSize");
426 queue->SetAttributeFailSafe("UseDequeueRateEstimator", BooleanValue(true)),
427 true,
428 "Verify that we can actually set the attribute UseTimestamp");
429 queue->Initialize();
430 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
431 DequeueWithDelay(queue, 0.014, 400);
434 st = queue->GetStats();
436 NS_TEST_ASSERT_MSG_NE(test6, 0, "There should be some unforced drops");
438 0,
439 "There should be zero forced drops");
440
441 // test 7: test with CapDropAdjustment disabled
442 queue = CreateObject<PieQueueDisc>();
443 // PieQueueDiscItem pointer for attributes
444 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
446 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
447 true,
448 "Verify that we can actually set the attribute MaxSize");
449 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseCapDropAdjustment", BooleanValue(false)),
450 true,
451 "Verify that we can actually set the attribute UseCapDropAdjustment");
452 queue->Initialize();
453 testAttributes->m_checkProb = true;
454 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
455 DequeueWithDelay(queue, 0.014, 400);
458 st = queue->GetStats();
460 NS_TEST_ASSERT_MSG_NE(test7, 0, "There should be some unforced drops");
462 0,
463 "There should be zero forced drops");
464 NS_TEST_ASSERT_MSG_GT(testAttributes->m_maxDropProbDiff,
465 0.02,
466 "Maximum increase in drop probability should be greater than 0.02");
467
468 // test 8: test with CapDropAdjustment enabled
469 queue = CreateObject<PieQueueDisc>();
470 // PieQueueDiscItem pointer for attributes
471 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
473 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
474 true,
475 "Verify that we can actually set the attribute MaxSize");
476 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseCapDropAdjustment", BooleanValue(true)),
477 true,
478 "Verify that we can actually set the attribute UseCapDropAdjustment");
479 queue->Initialize();
480 testAttributes->m_checkProb = true;
481 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
482 DequeueWithDelay(queue, 0.014, 400);
485 st = queue->GetStats();
487 NS_TEST_ASSERT_MSG_NE(test8, 0, "There should be some unforced drops");
489 0,
490 "There should be zero forced drops");
492 testAttributes->m_maxDropProbDiff,
493 0.0200000000000001,
494 "Maximum increase in drop probability should be less than or equal to 0.02");
495
496 // test 9: PIE queue disc is ECN enabled, but packets are not ECN capable
497 queue = CreateObject<PieQueueDisc>();
498 // PieQueueDiscItem pointer for attributes
499 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
501 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
502 true,
503 "Verify that we can actually set the attribute MaxSize");
504 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(true)),
505 true,
506 "Verify that we can actually set the attribute UseEcn");
507 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MarkEcnThreshold", DoubleValue(0.3)),
508 true,
509 "Verify that we can actually set the attribute MarkEcnThreshold");
510 queue->Initialize();
511 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
512 DequeueWithDelay(queue, 0.014, 400);
515 st = queue->GetStats();
517 NS_TEST_ASSERT_MSG_EQ(test9, 0, "There should be zero unforced marks");
519 0,
520 "There should be some unforced drops");
522 0,
523 "There should be zero forced drops");
524
525 // test 10: Packets are ECN capable, but PIE queue disc is not ECN enabled
526 queue = CreateObject<PieQueueDisc>();
527 // PieQueueDiscItem pointer for attributes
528 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
530 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
531 true,
532 "Verify that we can actually set the attribute MaxSize");
533 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(false)),
534 true,
535 "Verify that we can actually set the attribute UseEcn");
536 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MarkEcnThreshold", DoubleValue(0.3)),
537 true,
538 "Verify that we can actually set the attribute MarkEcnThreshold");
539 queue->Initialize();
540 testAttributes->m_ecnCapable = true;
541 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
542 DequeueWithDelay(queue, 0.014, 400);
545 st = queue->GetStats();
547 NS_TEST_ASSERT_MSG_EQ(test10, 0, "There should be zero unforced marks");
549 0,
550 "There should be some unforced drops");
552 0,
553 "There should be zero forced drops");
554
555 // test 11: Packets and PIE queue disc both are ECN capable
556 queue = CreateObject<PieQueueDisc>();
557 // PieQueueDiscItem pointer for attributes
558 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
560 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
561 true,
562 "Verify that we can actually set the attribute MaxSize");
563 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(true)),
564 true,
565 "Verify that we can actually set the attribute UseEcn");
566 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MarkEcnThreshold", DoubleValue(0.3)),
567 true,
568 "Verify that we can actually set the attribute MarkEcnThreshold");
569 queue->Initialize();
570 testAttributes->m_ecnCapable = true;
571 testAttributes->m_checkProb = true;
572 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
573 DequeueWithDelay(queue, 0.014, 400);
576 st = queue->GetStats();
578 NS_TEST_ASSERT_MSG_NE(test11, 0, "There should be some unforced marks");
579 // There are unforced drops because the value of m_maxDropProb goes beyond 0.3 in this test.
580 // PIE drops the packets even when they are ECN capable if drop probability is more than 30%.
582 0,
583 "There should be some unforced drops");
584 // Confirm that m_maxDropProb goes above 0.3 in this test
585 NS_TEST_ASSERT_MSG_GT(testAttributes->m_maxDropProb,
586 0.3,
587 "Maximum Drop probability should be greater than 0.3");
589 0,
590 "There should be zero forced drops");
591
592 // test 12: test with derandomization enabled
593 queue = CreateObject<PieQueueDisc>();
594 // PieQueueDiscItem pointer for attributes
595 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
597 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
598 true,
599 "Verify that we can actually set the attribute MaxSize");
600 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseDerandomization", BooleanValue(true)),
601 true,
602 "Verify that we can actually set the attribute UseDerandomization");
603 queue->Initialize();
604 testAttributes->m_checkAccuProb = true;
605 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
606 DequeueWithDelay(queue, 0.014, 400);
609 st = queue->GetStats();
611 NS_TEST_ASSERT_MSG_NE(test12, 0, "There should be some unforced drops");
613 0,
614 "There should be zero forced drops");
615 NS_TEST_ASSERT_MSG_EQ(testAttributes->m_accuProbError,
616 0.0,
617 "There should not be any error in setting accuProb");
618
619 // test 13: same as test 11 but with accumulated drop probability set below the low threshold
620 queue = CreateObject<PieQueueDisc>();
621 // PieQueueDiscItem pointer for attributes
622 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
624 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
625 true,
626 "Verify that we can actually set the attribute MaxSize");
627 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseDerandomization", BooleanValue(true)),
628 true,
629 "Verify that we can actually set the attribute UseDerandomization");
630 queue->Initialize();
631 testAttributes->m_constAccuProb = true;
632 // Final value of accumulated drop probability to drop packet will be maximum 0.84 while
633 // threshold to drop packet is 0.85
634 testAttributes->m_setAccuProb = -0.16;
635 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
636 DequeueWithDelay(queue, 0.014, 400);
639 st = queue->GetStats();
641 NS_TEST_ASSERT_MSG_EQ(test13, 0, "There should be zero unforced drops");
643 0,
644 "There should be zero forced drops");
645
646 // test 14: same as test 12 but with accumulated drop probability set above the high threshold
647 queue = CreateObject<PieQueueDisc>();
648 // PieQueueDiscItem pointer for attributes
649 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
651 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
652 true,
653 "Verify that we can actually set the attribute MaxSize");
654 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxBurstAllowance", TimeValue(Seconds(0.0))),
655 true,
656 "Verify that we can actually set the attribute MaxBurstAllowance");
657 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseDerandomization", BooleanValue(true)),
658 true,
659 "Verify that we can actually set the attribute UseDerandomization");
660 queue->Initialize();
661 testAttributes->m_constAccuProb = true;
662 testAttributes->m_checkMaxAccuProb = true;
663 // Final value of accumulated drop probability to drop packet will be minimum 8.6 while
664 // threshold to drop packet is 8.5
665 testAttributes->m_setAccuProb = 8.6;
666 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
667 DequeueWithDelay(queue, 0.014, 400);
670 st = queue->GetStats();
673 test14,
674 testAttributes->m_expectedDrops,
675 "The number of unforced drops should be equal to number of expected unforced drops");
677 0,
678 "There should be zero forced drops");
679
680 // test 15: tests Active/Inactive feature, ActiveThreshold set to a high value so PIE never
681 // starts and there should not be any drops
682 queue = CreateObject<PieQueueDisc>();
683 // PieQueueDiscItem pointer for attributes
684 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
685 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize)));
686 queue->SetAttributeFailSafe("ActiveThreshold", TimeValue(Seconds(1)));
687 queue->Initialize();
688
689 EnqueueWithDelay(queue, pktSize, 100, testAttributes);
690 DequeueWithDelay(queue, 0.02, 100);
693 st = queue->GetStats();
695 NS_TEST_ASSERT_MSG_EQ(test15, 0, "There should not be any drops.");
697 0,
698 "There should be zero marks");
699
700 // test 16: tests Active/Inactive feature, ActiveThreshold set to a low value so PIE starts
701 // early and some packets should be dropped.
702 queue = CreateObject<PieQueueDisc>();
703 // PieQueueDiscItem pointer for attributes
704 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
705 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize)));
706 queue->SetAttributeFailSafe("ActiveThreshold", TimeValue(Seconds(0.001)));
707 queue->Initialize();
708
709 EnqueueWithDelay(queue, pktSize, 100, testAttributes);
710 DequeueWithDelay(queue, 0.02, 100);
713 st = queue->GetStats();
715 NS_TEST_ASSERT_MSG_NE(test16, 0, "There should be some drops.");
717 0,
718 "There should be zero marks");
719}
720
721void
723 uint32_t size,
724 uint32_t nPkt,
725 Ptr<PieQueueDiscTestItem> testAttributes)
726{
727 Address dest;
728 for (uint32_t i = 0; i < nPkt; i++)
729 {
730 if (testAttributes->m_constAccuProb)
731 {
732 queue->m_accuProb = testAttributes->m_setAccuProb;
733 if (testAttributes->m_checkMaxAccuProb)
734 {
735 CheckMaxAccuProb(queue, testAttributes);
736 }
737 }
738 queue->Enqueue(
739 Create<PieQueueDiscTestItem>(Create<Packet>(size), dest, testAttributes->m_ecnCapable));
740 if (testAttributes->m_checkProb)
741 {
742 CheckDropProb(queue, testAttributes);
743 }
744 if (testAttributes->m_checkAccuProb)
745 {
746 CheckAccuProb(queue, testAttributes);
747 }
748 }
749}
750
751void
753 Ptr<PieQueueDiscTestItem> testAttributes)
754{
755 double dropProb = queue->m_dropProb;
756 if (testAttributes->m_maxDropProb < dropProb)
757 {
758 testAttributes->m_maxDropProb = dropProb;
759 }
760 if (testAttributes->m_prevDropProb > 0.1)
761 {
762 double currentDiff = dropProb - testAttributes->m_prevDropProb;
763 if (testAttributes->m_maxDropProbDiff < currentDiff)
764 {
765 testAttributes->m_maxDropProbDiff = currentDiff;
766 }
767 }
768 testAttributes->m_prevDropProb = dropProb;
769}
770
771void
773 Ptr<PieQueueDiscTestItem> testAttributes)
774{
775 double dropProb = queue->m_dropProb;
776 double accuProb = queue->m_accuProb;
777 if (accuProb != 0)
778 {
779 double expectedAccuProb = testAttributes->m_prevAccuProb + dropProb;
780 testAttributes->m_accuProbError = accuProb - expectedAccuProb;
781 }
782 testAttributes->m_prevAccuProb = accuProb;
783}
784
785void
787 Ptr<PieQueueDiscTestItem> testAttributes)
788{
789 queue->m_dropProb = 0.001;
790 QueueSize queueSize = queue->GetCurrentSize();
791 if ((queueSize.GetUnit() == QueueSizeUnit::PACKETS && queueSize.GetValue() > 2) ||
792 (queueSize.GetUnit() == QueueSizeUnit::BYTES && queueSize.GetValue() > 2000))
793 {
794 testAttributes->m_expectedDrops = testAttributes->m_expectedDrops + 1;
795 }
796}
797
798void
800 uint32_t size,
801 uint32_t nPkt,
802 Ptr<PieQueueDiscTestItem> testAttributes)
803{
804 Address dest;
805 double delay = 0.01; // enqueue packets with delay
806 for (uint32_t i = 0; i < nPkt; i++)
807 {
808 Simulator::Schedule(Time(Seconds((i + 1) * delay)),
810 this,
811 queue,
812 size,
813 1,
814 testAttributes);
815 }
816}
817
818void
820{
821 for (uint32_t i = 0; i < nPkt; i++)
822 {
823 Ptr<QueueDiscItem> item = queue->Dequeue();
824 }
825}
826
827void
829{
830 for (uint32_t i = 0; i < nPkt; i++)
831 {
832 Simulator::Schedule(Time(Seconds((i + 1) * delay)),
834 this,
835 queue,
836 1);
837 }
838}
839
840void
842{
843 RunPieTest(QueueSizeUnit::PACKETS);
844 RunPieTest(QueueSizeUnit::BYTES);
846}
847
853static class PieQueueDiscTestSuite : public TestSuite
854{
855 public:
857 : TestSuite("pie-queue-disc", UNIT)
858 {
860 }
Pie Queue Disc Test Case.
void Dequeue(Ptr< PieQueueDisc > queue, uint32_t nPkt)
Dequeue function.
void RunPieTest(QueueSizeUnit mode)
Run test function.
void CheckMaxAccuProb(Ptr< PieQueueDisc > queue, Ptr< PieQueueDiscTestItem > testAttributes)
Check Maximum Accumulated Drop Probability.
void EnqueueWithDelay(Ptr< PieQueueDisc > queue, uint32_t size, uint32_t nPkt, Ptr< PieQueueDiscTestItem > testAttributes)
Enqueue with delay function.
void CheckAccuProb(Ptr< PieQueueDisc > queue, Ptr< PieQueueDiscTestItem > testAttributes)
Check Accumulated Drop Probability.
void CheckDropProb(Ptr< PieQueueDisc > queue, Ptr< PieQueueDiscTestItem > testAttributes)
Check Drop Probability.
void DequeueWithDelay(Ptr< PieQueueDisc > queue, double delay, uint32_t nPkt)
Dequeue with delay function.
void Enqueue(Ptr< PieQueueDisc > queue, uint32_t size, uint32_t nPkt, Ptr< PieQueueDiscTestItem > testAttributes)
Enqueue function.
void DoRun() override
Implementation to actually run this TestCase.
Pie Queue Disc Test Item.
double m_prevDropProb
Previous drop probability.
bool m_checkAccuProb
Enable/Disable accumulated drop probability checks.
bool m_ecnCapable
Enable/Disable ECN capability.
double m_maxDropProbDiff
Maximum difference between two consecutive drop probability values.
bool m_constAccuProb
Enable/Disable fixed accumulated drop probability.
bool m_ecnCapablePacket
ECN capable packet?
PieQueueDiscTestItem & operator=(const PieQueueDiscTestItem &)=delete
PieQueueDiscTestItem(const PieQueueDiscTestItem &)=delete
bool m_checkProb
Enable/Disable drop probability checks.
bool m_checkMaxAccuProb
Enable/Disable Maximum accumulated drop probability checks.
double m_maxDropProb
Maximum value of drop probability.
double m_prevAccuProb
Previous accumulated drop probability.
PieQueueDiscTestItem()=delete
void AddHeader() override
Add the header to the packet.
uint32_t m_expectedDrops
Number of expected unforced drops.
double m_setAccuProb
Value to be set for accumulated drop probability.
bool Mark() override
Marks the packet as a substitute for dropping it, such as for Explicit Congestion Notification.
double m_accuProbError
Error in accumulated drop probability.
Pie Queue Disc Test Suite.
a polymophic address class
Definition: address.h:100
AttributeValue implementation for Boolean.
Definition: boolean.h:37
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
static constexpr const char * UNFORCED_DROP
Early probability drops: proactive.
static constexpr const char * FORCED_DROP
Drops due to queue limit: reactive.
static constexpr const char * UNFORCED_MARK
Early probability marks: proactive.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
QueueDiscItem is the abstract base class for items that are stored in a queue disc.
Definition: queue-item.h:133
Class for representing queue sizes.
Definition: queue-size.h:96
QueueSizeUnit GetUnit() const
Get the underlying unit.
Definition: queue-size.cc:176
uint32_t GetValue() const
Get the underlying value.
Definition: queue-size.cc:183
AttributeValue implementation for QueueSize.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:140
static void Run()
Run the simulation.
Definition: simulator.cc:176
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:184
encapsulates test code
Definition: test.h:1060
@ QUICK
Fast test.
Definition: test.h:1065
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:305
A suite of tests to run.
Definition: test.h:1256
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1265
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
AttributeValue implementation for Time.
Definition: nstime.h:1423
Hold an unsigned integer type.
Definition: uinteger.h:45
QueueSizeUnit
Enumeration of the operating modes of queues.
Definition: queue-size.h:44
#define NS_TEST_ASSERT_MSG_LT(actual, limit, msg)
Test that an actual value is less than a limit and report and abort if not.
Definition: test.h:709
#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:144
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report and abort if not.
Definition: test.h:564
#define NS_TEST_ASSERT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report and abort if not.
Definition: test.h:874
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
PieQueueDiscTestSuite g_pieQueueTestSuite
the test suite
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Structure that keeps the queue disc statistics.
Definition: queue-disc.h:188
uint32_t GetNDroppedPackets(std::string reason) const
Get the number of packets dropped for the given reason.
Definition: queue-disc.cc:111
uint32_t GetNMarkedPackets(std::string reason) const
Get the number of packets marked for the given reason.
Definition: queue-disc.cc:153
uint32_t pktSize
packet size used for the simulation (in bytes)