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
34/**
35 * \ingroup traffic-control-test
36 *
37 * \brief Pie Queue Disc Test Item
38 */
40{
41 public:
42 /**
43 * Constructor
44 *
45 * \param p the packet
46 * \param addr the address
47 * \param ecnCapable ECN capable flag
48 */
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; //!< Maximum difference between two consecutive drop probability values
62 double m_prevDropProb = 0.0; //!< Previous drop probability
63 bool m_checkProb = false; //!< Enable/Disable drop probability checks
64
65 // ** Variable for testing ECN
66 double m_maxDropProb = 0.0; //!< Maximum value of drop probability
67 bool m_ecnCapable = false; //!< Enable/Disable ECN capability
68
69 // ** Variables for testing Derandomization
70 bool m_checkAccuProb = false; //!< Enable/Disable accumulated drop probability checks
71 bool m_constAccuProb = false; //!< Enable/Disable fixed accumulated drop probability
72 bool m_checkMaxAccuProb = false; //!< Enable/Disable Maximum accumulated drop probability checks
73 double m_accuProbError = 0.0; //!< Error in accumulated drop probability
74 double m_prevAccuProb = 0.0; //!< Previous accumulated drop probability
75 double m_setAccuProb = 0.0; //!< Value to be set for accumulated drop probability
76 uint32_t m_expectedDrops = 0; //!< Number of expected unforced drops
77
78 private:
79 bool m_ecnCapablePacket; //!< ECN capable packet?
80};
81
83 : QueueDiscItem(p, addr, 0),
84 m_ecnCapablePacket(ecnCapable)
85{
86}
87
88void
90{
91}
92
93bool
95{
96 return m_ecnCapablePacket;
97}
98
99/**
100 * \ingroup traffic-control-test
101 *
102 * \brief Pie Queue Disc Test Case
103 */
105{
106 public:
108 void DoRun() override;
109
110 private:
111 /**
112 * Enqueue function
113 * \param queue the queue disc
114 * \param size the size
115 * \param nPkt the number of packets
116 * \param testAttributes attributes for testing
117 */
118 void Enqueue(Ptr<PieQueueDisc> queue,
119 uint32_t size,
120 uint32_t nPkt,
121 Ptr<PieQueueDiscTestItem> testAttributes);
122 /**
123 * Enqueue with delay function
124 * \param queue the queue disc
125 * \param size the size
126 * \param nPkt the number of packets
127 * \param testAttributes attributes for testing
128 */
130 uint32_t size,
131 uint32_t nPkt,
132 Ptr<PieQueueDiscTestItem> testAttributes);
133 /**
134 * Dequeue function
135 * \param queue the queue disc
136 * \param nPkt the number of packets
137 */
138 void Dequeue(Ptr<PieQueueDisc> queue, uint32_t nPkt);
139 /**
140 * Dequeue with delay function
141 * \param queue the queue disc
142 * \param delay the delay
143 * \param nPkt the number of packets
144 */
145 void DequeueWithDelay(Ptr<PieQueueDisc> queue, double delay, uint32_t nPkt);
146 /**
147 * Run test function
148 * \param mode the test mode
149 */
150 void RunPieTest(QueueSizeUnit mode);
151 /**
152 * \brief Check Drop Probability
153 * \param queue the queue disc
154 * \param testAttributes attributes for testing
155 */
157 /**
158 * \brief Check Accumulated Drop Probability
159 * \param queue the queue disc
160 * \param testAttributes attributes for testing
161 */
163 /**
164 * \brief Check Maximum Accumulated Drop Probability
165 * \param queue the queue disc
166 * \param testAttributes attributes for testing
167 */
169};
170
172 : TestCase("Sanity check on the pie queue disc implementation")
173{
174}
175
176void
178{
179 uint32_t pktSize = 0;
180
181 // 1 for packets; pktSize for bytes
182 uint32_t modeSize = 1;
183
184 uint32_t qSize = 300;
185 Ptr<PieQueueDisc> queue = CreateObject<PieQueueDisc>();
186
187 // test 1: simple enqueue/dequeue with defaults, no drops
188 Address dest;
189 // PieQueueDiscItem pointer for attributes
190 Ptr<PieQueueDiscTestItem> testAttributes =
191 Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
192
193 if (mode == QueueSizeUnit::BYTES)
194 {
195 // pktSize should be same as MeanPktSize to avoid performance gap between byte and packet
196 // mode
197 pktSize = 1000;
198 modeSize = pktSize;
199 qSize = qSize * modeSize;
200 }
201
203 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
204 true,
205 "Verify that we can actually set the attribute MaxSize");
206
207 Ptr<Packet> p1;
208 Ptr<Packet> p2;
209 Ptr<Packet> p3;
210 Ptr<Packet> p4;
211 Ptr<Packet> p5;
212 Ptr<Packet> p6;
213 Ptr<Packet> p7;
214 Ptr<Packet> p8;
215 p1 = Create<Packet>(pktSize);
216 p2 = Create<Packet>(pktSize);
217 p3 = Create<Packet>(pktSize);
218 p4 = Create<Packet>(pktSize);
219 p5 = Create<Packet>(pktSize);
220 p6 = Create<Packet>(pktSize);
221 p7 = Create<Packet>(pktSize);
222 p8 = Create<Packet>(pktSize);
223
224 queue->Initialize();
225 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
226 0 * modeSize,
227 "There should be no packets in there");
228 queue->Enqueue(Create<PieQueueDiscTestItem>(p1, dest, false));
229 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
230 1 * modeSize,
231 "There should be one packet in there");
232 queue->Enqueue(Create<PieQueueDiscTestItem>(p2, dest, false));
233 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
234 2 * modeSize,
235 "There should be two packets in there");
236 queue->Enqueue(Create<PieQueueDiscTestItem>(p3, dest, false));
237 queue->Enqueue(Create<PieQueueDiscTestItem>(p4, dest, false));
238 queue->Enqueue(Create<PieQueueDiscTestItem>(p5, dest, false));
239 queue->Enqueue(Create<PieQueueDiscTestItem>(p6, dest, false));
240 queue->Enqueue(Create<PieQueueDiscTestItem>(p7, dest, false));
241 queue->Enqueue(Create<PieQueueDiscTestItem>(p8, dest, false));
242 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
243 8 * modeSize,
244 "There should be eight packets in there");
245
247
248 item = queue->Dequeue();
249 NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the first packet");
250 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
251 7 * modeSize,
252 "There should be seven packets in there");
253 NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(), p1->GetUid(), "was this the first packet ?");
254
255 item = queue->Dequeue();
256 NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the second packet");
257 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
258 6 * modeSize,
259 "There should be six packet in there");
260 NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(),
261 p2->GetUid(),
262 "Was this the second packet ?");
263
264 item = queue->Dequeue();
265 NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the third packet");
266 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
267 5 * modeSize,
268 "There should be five packets in there");
269 NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(), p3->GetUid(), "Was this the third packet ?");
270
271 item = queue->Dequeue();
272 item = queue->Dequeue();
273 item = queue->Dequeue();
274 item = queue->Dequeue();
275 item = queue->Dequeue();
276
277 item = queue->Dequeue();
278 NS_TEST_ASSERT_MSG_EQ(item, nullptr, "There are really no packets in there");
279
280 // test 2: more data with defaults, unforced drops but no forced drops
281 queue = CreateObject<PieQueueDisc>();
282 // PieQueueDiscItem pointer for attributes
283 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
284 pktSize = 1000; // pktSize != 0 because DequeueThreshold always works in bytes
286 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
287 true,
288 "Verify that we can actually set the attribute MaxSize");
289 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Tupdate", TimeValue(Seconds(0.03))),
290 true,
291 "Verify that we can actually set the attribute Tupdate");
292 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("DequeueThreshold", UintegerValue(10000)),
293 true,
294 "Verify that we can actually set the attribute DequeueThreshold");
296 queue->SetAttributeFailSafe("QueueDelayReference", TimeValue(Seconds(0.02))),
297 true,
298 "Verify that we can actually set the attribute QueueDelayReference");
299 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxBurstAllowance", TimeValue(Seconds(0.1))),
300 true,
301 "Verify that we can actually set the attribute MaxBurstAllowance");
302 queue->Initialize();
303 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
304 DequeueWithDelay(queue, 0.012, 400);
307 QueueDisc::Stats st = queue->GetStats();
309 NS_TEST_ASSERT_MSG_NE(test2, 0, "There should be some unforced drops");
311 0,
312 "There should be zero forced drops");
313
314 // test 3: same as test 2, but with higher QueueDelayReference
315 queue = CreateObject<PieQueueDisc>();
316 // PieQueueDiscItem pointer for attributes
317 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
319 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
320 true,
321 "Verify that we can actually set the attribute MaxSize");
322 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Tupdate", TimeValue(Seconds(0.03))),
323 true,
324 "Verify that we can actually set the attribute Tupdate");
325 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("DequeueThreshold", UintegerValue(10000)),
326 true,
327 "Verify that we can actually set the attribute DequeueThreshold");
329 queue->SetAttributeFailSafe("QueueDelayReference", TimeValue(Seconds(0.08))),
330 true,
331 "Verify that we can actually set the attribute QueueDelayReference");
332 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxBurstAllowance", TimeValue(Seconds(0.1))),
333 true,
334 "Verify that we can actually set the attribute MaxBurstAllowance");
335 queue->Initialize();
336 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
337 DequeueWithDelay(queue, 0.012, 400);
340 st = queue->GetStats();
342 NS_TEST_ASSERT_MSG_LT(test3, test2, "Test 3 should have less unforced drops than test 2");
344 0,
345 "There should be zero forced drops");
346
347 // test 4: same as test 2, but with reduced dequeue rate
348 queue = CreateObject<PieQueueDisc>();
349 // PieQueueDiscItem pointer for attributes
350 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
352 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
353 true,
354 "Verify that we can actually set the attribute MaxSize");
355 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Tupdate", TimeValue(Seconds(0.03))),
356 true,
357 "Verify that we can actually set the attribute Tupdate");
358 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("DequeueThreshold", UintegerValue(10000)),
359 true,
360 "Verify that we can actually set the attribute DequeueThreshold");
362 queue->SetAttributeFailSafe("QueueDelayReference", TimeValue(Seconds(0.02))),
363 true,
364 "Verify that we can actually set the attribute QueueDelayReference");
365 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxBurstAllowance", TimeValue(Seconds(0.1))),
366 true,
367 "Verify that we can actually set the attribute MaxBurstAllowance");
368 queue->Initialize();
369 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
370 DequeueWithDelay(queue, 0.015, 400); // delay between two successive dequeue events is increased
373 st = queue->GetStats();
375 NS_TEST_ASSERT_MSG_GT(test4, test2, "Test 4 should have more unforced drops than test 2");
377 0,
378 "There should be zero forced drops");
379
380 // test 5: same dequeue rate as test 4, but with higher Tupdate
381 queue = CreateObject<PieQueueDisc>();
382 // PieQueueDiscItem pointer for attributes
383 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
385 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
386 true,
387 "Verify that we can actually set the attribute MaxSize");
388 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Tupdate", TimeValue(Seconds(0.09))),
389 true,
390 "Verify that we can actually set the attribute Tupdate");
391 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("DequeueThreshold", UintegerValue(10000)),
392 true,
393 "Verify that we can actually set the attribute DequeueThreshold");
395 queue->SetAttributeFailSafe("QueueDelayReference", TimeValue(Seconds(0.02))),
396 true,
397 "Verify that we can actually set the attribute QueueDelayReference");
398 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxBurstAllowance", TimeValue(Seconds(0.1))),
399 true,
400 "Verify that we can actually set the attribute MaxBurstAllowance");
401 queue->Initialize();
402 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
403 DequeueWithDelay(queue, 0.015, 400);
406 st = queue->GetStats();
408 NS_TEST_ASSERT_MSG_LT(test5, test4, "Test 5 should have less unforced drops than test 4");
410 0,
411 "There should be zero forced drops");
412
413 // test 6: same as test 2, but with UseDequeueRateEstimator enabled
414 queue = CreateObject<PieQueueDisc>();
415 // PieQueueDiscItem pointer for attributes
416 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
418 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
419 true,
420 "Verify that we can actually set the attribute MaxSize");
422 queue->SetAttributeFailSafe("UseDequeueRateEstimator", BooleanValue(true)),
423 true,
424 "Verify that we can actually set the attribute UseTimestamp");
425 queue->Initialize();
426 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
427 DequeueWithDelay(queue, 0.014, 400);
430 st = queue->GetStats();
432 NS_TEST_ASSERT_MSG_NE(test6, 0, "There should be some unforced drops");
434 0,
435 "There should be zero forced drops");
436
437 // test 7: test with CapDropAdjustment disabled
438 queue = CreateObject<PieQueueDisc>();
439 // PieQueueDiscItem pointer for attributes
440 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
442 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
443 true,
444 "Verify that we can actually set the attribute MaxSize");
445 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseCapDropAdjustment", BooleanValue(false)),
446 true,
447 "Verify that we can actually set the attribute UseCapDropAdjustment");
448 queue->Initialize();
449 testAttributes->m_checkProb = true;
450 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
451 DequeueWithDelay(queue, 0.014, 400);
454 st = queue->GetStats();
456 NS_TEST_ASSERT_MSG_NE(test7, 0, "There should be some unforced drops");
458 0,
459 "There should be zero forced drops");
460 NS_TEST_ASSERT_MSG_GT(testAttributes->m_maxDropProbDiff,
461 0.02,
462 "Maximum increase in drop probability should be greater than 0.02");
463
464 // test 8: test with CapDropAdjustment enabled
465 queue = CreateObject<PieQueueDisc>();
466 // PieQueueDiscItem pointer for attributes
467 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
469 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
470 true,
471 "Verify that we can actually set the attribute MaxSize");
472 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseCapDropAdjustment", BooleanValue(true)),
473 true,
474 "Verify that we can actually set the attribute UseCapDropAdjustment");
475 queue->Initialize();
476 testAttributes->m_checkProb = true;
477 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
478 DequeueWithDelay(queue, 0.014, 400);
481 st = queue->GetStats();
483 NS_TEST_ASSERT_MSG_NE(test8, 0, "There should be some unforced drops");
485 0,
486 "There should be zero forced drops");
488 testAttributes->m_maxDropProbDiff,
489 0.0200000000000001,
490 "Maximum increase in drop probability should be less than or equal to 0.02");
491
492 // test 9: PIE queue disc is ECN enabled, but packets are not ECN capable
493 queue = CreateObject<PieQueueDisc>();
494 // PieQueueDiscItem pointer for attributes
495 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
497 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
498 true,
499 "Verify that we can actually set the attribute MaxSize");
500 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(true)),
501 true,
502 "Verify that we can actually set the attribute UseEcn");
503 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MarkEcnThreshold", DoubleValue(0.3)),
504 true,
505 "Verify that we can actually set the attribute MarkEcnThreshold");
506 queue->Initialize();
507 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
508 DequeueWithDelay(queue, 0.014, 400);
511 st = queue->GetStats();
513 NS_TEST_ASSERT_MSG_EQ(test9, 0, "There should be zero unforced marks");
515 0,
516 "There should be some unforced drops");
518 0,
519 "There should be zero forced drops");
520
521 // test 10: Packets are ECN capable, but PIE queue disc is not ECN enabled
522 queue = CreateObject<PieQueueDisc>();
523 // PieQueueDiscItem pointer for attributes
524 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
526 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
527 true,
528 "Verify that we can actually set the attribute MaxSize");
529 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(false)),
530 true,
531 "Verify that we can actually set the attribute UseEcn");
532 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MarkEcnThreshold", DoubleValue(0.3)),
533 true,
534 "Verify that we can actually set the attribute MarkEcnThreshold");
535 queue->Initialize();
536 testAttributes->m_ecnCapable = true;
537 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
538 DequeueWithDelay(queue, 0.014, 400);
541 st = queue->GetStats();
543 NS_TEST_ASSERT_MSG_EQ(test10, 0, "There should be zero unforced marks");
545 0,
546 "There should be some unforced drops");
548 0,
549 "There should be zero forced drops");
550
551 // test 11: Packets and PIE queue disc both are ECN capable
552 queue = CreateObject<PieQueueDisc>();
553 // PieQueueDiscItem pointer for attributes
554 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
556 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
557 true,
558 "Verify that we can actually set the attribute MaxSize");
559 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(true)),
560 true,
561 "Verify that we can actually set the attribute UseEcn");
562 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MarkEcnThreshold", DoubleValue(0.3)),
563 true,
564 "Verify that we can actually set the attribute MarkEcnThreshold");
565 queue->Initialize();
566 testAttributes->m_ecnCapable = true;
567 testAttributes->m_checkProb = true;
568 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
569 DequeueWithDelay(queue, 0.014, 400);
572 st = queue->GetStats();
574 NS_TEST_ASSERT_MSG_NE(test11, 0, "There should be some unforced marks");
575 // There are unforced drops because the value of m_maxDropProb goes beyond 0.3 in this test.
576 // PIE drops the packets even when they are ECN capable if drop probability is more than 30%.
578 0,
579 "There should be some unforced drops");
580 // Confirm that m_maxDropProb goes above 0.3 in this test
581 NS_TEST_ASSERT_MSG_GT(testAttributes->m_maxDropProb,
582 0.3,
583 "Maximum Drop probability should be greater than 0.3");
585 0,
586 "There should be zero forced drops");
587
588 // test 12: test with derandomization enabled
589 queue = CreateObject<PieQueueDisc>();
590 // PieQueueDiscItem pointer for attributes
591 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
593 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
594 true,
595 "Verify that we can actually set the attribute MaxSize");
596 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseDerandomization", BooleanValue(true)),
597 true,
598 "Verify that we can actually set the attribute UseDerandomization");
599 queue->Initialize();
600 testAttributes->m_checkAccuProb = true;
601 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
602 DequeueWithDelay(queue, 0.014, 400);
605 st = queue->GetStats();
607 NS_TEST_ASSERT_MSG_NE(test12, 0, "There should be some unforced drops");
609 0,
610 "There should be zero forced drops");
611 NS_TEST_ASSERT_MSG_EQ(testAttributes->m_accuProbError,
612 0.0,
613 "There should not be any error in setting accuProb");
614
615 // test 13: same as test 11 but with accumulated drop probability set below the low threshold
616 queue = CreateObject<PieQueueDisc>();
617 // PieQueueDiscItem pointer for attributes
618 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
620 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
621 true,
622 "Verify that we can actually set the attribute MaxSize");
623 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseDerandomization", BooleanValue(true)),
624 true,
625 "Verify that we can actually set the attribute UseDerandomization");
626 queue->Initialize();
627 testAttributes->m_constAccuProb = true;
628 // Final value of accumulated drop probability to drop packet will be maximum 0.84 while
629 // threshold to drop packet is 0.85
630 testAttributes->m_setAccuProb = -0.16;
631 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
632 DequeueWithDelay(queue, 0.014, 400);
635 st = queue->GetStats();
637 NS_TEST_ASSERT_MSG_EQ(test13, 0, "There should be zero unforced drops");
639 0,
640 "There should be zero forced drops");
641
642 // test 14: same as test 12 but with accumulated drop probability set above the high threshold
643 queue = CreateObject<PieQueueDisc>();
644 // PieQueueDiscItem pointer for attributes
645 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
647 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
648 true,
649 "Verify that we can actually set the attribute MaxSize");
650 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxBurstAllowance", TimeValue(Seconds(0.0))),
651 true,
652 "Verify that we can actually set the attribute MaxBurstAllowance");
653 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseDerandomization", BooleanValue(true)),
654 true,
655 "Verify that we can actually set the attribute UseDerandomization");
656 queue->Initialize();
657 testAttributes->m_constAccuProb = true;
658 testAttributes->m_checkMaxAccuProb = true;
659 // Final value of accumulated drop probability to drop packet will be minimum 8.6 while
660 // threshold to drop packet is 8.5
661 testAttributes->m_setAccuProb = 8.6;
662 EnqueueWithDelay(queue, pktSize, 400, testAttributes);
663 DequeueWithDelay(queue, 0.014, 400);
666 st = queue->GetStats();
669 test14,
670 testAttributes->m_expectedDrops,
671 "The number of unforced drops should be equal to number of expected unforced drops");
673 0,
674 "There should be zero forced drops");
675
676 // test 15: tests Active/Inactive feature, ActiveThreshold set to a high value so PIE never
677 // starts and there should not be any drops
678 queue = CreateObject<PieQueueDisc>();
679 // PieQueueDiscItem pointer for attributes
680 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
681 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize)));
682 queue->SetAttributeFailSafe("ActiveThreshold", TimeValue(Seconds(1)));
683 queue->Initialize();
684
685 EnqueueWithDelay(queue, pktSize, 100, testAttributes);
686 DequeueWithDelay(queue, 0.02, 100);
689 st = queue->GetStats();
691 NS_TEST_ASSERT_MSG_EQ(test15, 0, "There should not be any drops.");
693 0,
694 "There should be zero marks");
695
696 // test 16: tests Active/Inactive feature, ActiveThreshold set to a low value so PIE starts
697 // early and some packets should be dropped.
698 queue = CreateObject<PieQueueDisc>();
699 // PieQueueDiscItem pointer for attributes
700 testAttributes = Create<PieQueueDiscTestItem>(Create<Packet>(pktSize), dest, false);
701 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize)));
702 queue->SetAttributeFailSafe("ActiveThreshold", TimeValue(Seconds(0.001)));
703 queue->Initialize();
704
705 EnqueueWithDelay(queue, pktSize, 100, testAttributes);
706 DequeueWithDelay(queue, 0.02, 100);
709 st = queue->GetStats();
711 NS_TEST_ASSERT_MSG_NE(test16, 0, "There should be some drops.");
713 0,
714 "There should be zero marks");
715}
716
717void
719 uint32_t size,
720 uint32_t nPkt,
721 Ptr<PieQueueDiscTestItem> testAttributes)
722{
723 Address dest;
724 for (uint32_t i = 0; i < nPkt; i++)
725 {
726 if (testAttributes->m_constAccuProb)
727 {
728 queue->m_accuProb = testAttributes->m_setAccuProb;
729 if (testAttributes->m_checkMaxAccuProb)
730 {
731 CheckMaxAccuProb(queue, testAttributes);
732 }
733 }
734 queue->Enqueue(
735 Create<PieQueueDiscTestItem>(Create<Packet>(size), dest, testAttributes->m_ecnCapable));
736 if (testAttributes->m_checkProb)
737 {
738 CheckDropProb(queue, testAttributes);
739 }
740 if (testAttributes->m_checkAccuProb)
741 {
742 CheckAccuProb(queue, testAttributes);
743 }
744 }
745}
746
747void
749 Ptr<PieQueueDiscTestItem> testAttributes)
750{
751 double dropProb = queue->m_dropProb;
752 if (testAttributes->m_maxDropProb < dropProb)
753 {
754 testAttributes->m_maxDropProb = dropProb;
755 }
756 if (testAttributes->m_prevDropProb > 0.1)
757 {
758 double currentDiff = dropProb - testAttributes->m_prevDropProb;
759 if (testAttributes->m_maxDropProbDiff < currentDiff)
760 {
761 testAttributes->m_maxDropProbDiff = currentDiff;
762 }
763 }
764 testAttributes->m_prevDropProb = dropProb;
765}
766
767void
769 Ptr<PieQueueDiscTestItem> testAttributes)
770{
771 double dropProb = queue->m_dropProb;
772 double accuProb = queue->m_accuProb;
773 if (accuProb != 0)
774 {
775 double expectedAccuProb = testAttributes->m_prevAccuProb + dropProb;
776 testAttributes->m_accuProbError = accuProb - expectedAccuProb;
777 }
778 testAttributes->m_prevAccuProb = accuProb;
779}
780
781void
783 Ptr<PieQueueDiscTestItem> testAttributes)
784{
785 queue->m_dropProb = 0.001;
786 QueueSize queueSize = queue->GetCurrentSize();
787 if ((queueSize.GetUnit() == QueueSizeUnit::PACKETS && queueSize.GetValue() > 2) ||
788 (queueSize.GetUnit() == QueueSizeUnit::BYTES && queueSize.GetValue() > 2000))
789 {
790 testAttributes->m_expectedDrops = testAttributes->m_expectedDrops + 1;
791 }
792}
793
794void
796 uint32_t size,
797 uint32_t nPkt,
798 Ptr<PieQueueDiscTestItem> testAttributes)
799{
800 Address dest;
801 double delay = 0.01; // enqueue packets with delay
802 for (uint32_t i = 0; i < nPkt; i++)
803 {
804 Simulator::Schedule(Time(Seconds((i + 1) * delay)),
806 this,
807 queue,
808 size,
809 1,
810 testAttributes);
811 }
812}
813
814void
816{
817 for (uint32_t i = 0; i < nPkt; i++)
818 {
819 Ptr<QueueDiscItem> item = queue->Dequeue();
820 }
821}
822
823void
825{
826 for (uint32_t i = 0; i < nPkt; i++)
827 {
828 Simulator::Schedule(Time(Seconds((i + 1) * delay)),
830 this,
831 queue,
832 1);
833 }
834}
835
836void
838{
839 RunPieTest(QueueSizeUnit::PACKETS);
840 RunPieTest(QueueSizeUnit::BYTES);
842}
843
844/**
845 * \ingroup traffic-control-test
846 *
847 * \brief Pie Queue Disc Test Suite
848 */
849static class PieQueueDiscTestSuite : public TestSuite
850{
851 public:
853 : TestSuite("pie-queue-disc", Type::UNIT)
854 {
855 AddTestCase(new PieQueueDiscTestCase(), TestCase::Duration::QUICK);
856 }
857} g_pieQueueTestSuite; ///< the test suite
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:101
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:77
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
AttributeValue implementation for QueueSize.
Definition: queue-size.h:221
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
static constexpr auto UNIT
Definition: test.h:1286
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
AttributeValue implementation for Time.
Definition: nstime.h:1413
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:710
#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:145
#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:565
#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:875
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
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
std::ofstream queueSize
uint32_t pktSize
packet size used for the simulation (in bytes)