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