A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
queue-disc-traces-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 Universita' degli Studi di Napoli Federico II
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: Stefano Avallone <stavallo@unina.it>
18 *
19 */
20
21#include "ns3/drop-tail-queue.h"
22#include "ns3/packet.h"
23#include "ns3/queue-disc.h"
24#include "ns3/simulator.h"
25#include "ns3/test.h"
26
27#include <map>
28
29using namespace ns3;
30
37{
38 public:
45 QdTestItem(Ptr<Packet> p, const Address& addr);
46 ~QdTestItem() override;
47 void AddHeader() override;
48 bool Mark() override;
49};
50
52 : QueueDiscItem(p, addr, 0)
53{
54}
55
57{
58}
59
60void
62{
63}
64
65bool
67{
68 return false;
69}
70
77{
78 public:
83 ~TestChildQueueDisc() override;
84 bool DoEnqueue(Ptr<QueueDiscItem> item) override;
86 bool CheckConfig() override;
87 void InitializeParams() override;
88
89 // Reasons for dropping packets
90 static constexpr const char* BEFORE_ENQUEUE = "Before enqueue";
91 static constexpr const char* AFTER_DEQUEUE = "After dequeue";
92};
93
96{
97}
98
100{
101}
102
103bool
105{
106 // Drop the packet if there are already 4 packets queued
107 if (GetNPackets() >= 4)
108 {
110 return false;
111 }
112 return GetInternalQueue(0)->Enqueue(item);
113}
114
117{
118 Ptr<QueueDiscItem> item = GetInternalQueue(0)->Dequeue();
119
120 // Drop the packet if at least 2 packets remain in the queue
121 while (GetNPackets() >= 2)
122 {
124 item = GetInternalQueue(0)->Dequeue();
125 }
126 return item;
127}
128
129bool
131{
133 return true;
134}
135
136void
138{
139}
140
147{
148 public:
153 ~TestParentQueueDisc() override;
154 bool DoEnqueue(Ptr<QueueDiscItem> item) override;
155 Ptr<QueueDiscItem> DoDequeue() override;
156 bool CheckConfig() override;
157 void InitializeParams() override;
158};
159
162{
163}
164
166{
167}
168
169bool
171{
172 return GetQueueDiscClass(0)->GetQueueDisc()->Enqueue(item);
173}
174
177{
178 return GetQueueDiscClass(0)->GetQueueDisc()->Dequeue();
179}
180
181bool
183{
184 Ptr<QueueDiscClass> c = CreateObject<QueueDiscClass>();
185 c->SetQueueDisc(CreateObject<TestChildQueueDisc>());
187 return true;
188}
189
190void
192{
193}
194
201{
202 public:
206 TestCounter();
207 virtual ~TestCounter();
208
214
215 private:
231 void PacketDbe(Ptr<const QueueDiscItem> item, const char* reason);
237 void PacketDad(Ptr<const QueueDiscItem> item, const char* reason);
238
245
247};
248
250 : m_nPackets(0),
251 m_nBytes(0),
252 m_nDbePackets(0),
253 m_nDbeBytes(0),
254 m_nDadPackets(0),
255 m_nDadBytes(0)
256{
257}
258
260{
261}
262
263void
265{
266 m_nPackets++;
267 m_nBytes += item->GetSize();
268}
269
270void
272{
273 m_nPackets--;
274 m_nBytes -= item->GetSize();
275}
276
277void
279{
281 m_nDbeBytes += item->GetSize();
282}
283
284void
286{
288 m_nDadBytes += item->GetSize();
289}
290
291void
293{
294 qd->TraceConnectWithoutContext("Enqueue", MakeCallback(&TestCounter::PacketEnqueued, this));
295 qd->TraceConnectWithoutContext("Dequeue", MakeCallback(&TestCounter::PacketDequeued, this));
296 qd->TraceConnectWithoutContext("DropBeforeEnqueue",
298 qd->TraceConnectWithoutContext("DropAfterDequeue", MakeCallback(&TestCounter::PacketDad, this));
299}
300
317{
318 public:
320 void DoRun() override;
321
328 void CheckQueued(Ptr<QueueDisc> qd, uint32_t nPackets, uint32_t nBytes);
335 void CheckDroppedBeforeEnqueue(Ptr<QueueDisc> qd, uint32_t nDbePackets, uint32_t nDbeBytes);
342 void CheckDroppedAfterDequeue(Ptr<QueueDisc> qd, uint32_t nDadPackets, uint32_t nDadBytes);
343
344 private:
345 std::map<Ptr<QueueDisc>, TestCounter> m_counter;
346};
347
349 : TestCase("Sanity check on the queue disc traces and statistics")
350{
351}
352
353void
355{
356 NS_TEST_ASSERT_MSG_EQ(qd->GetNPackets(),
357 nPackets,
358 "Verify that the number of queued packets is computed correctly");
359 NS_TEST_ASSERT_MSG_EQ(m_counter[qd].m_nPackets,
360 nPackets,
361 "Verify that the number of queued packets is computed correctly");
362
363 NS_TEST_ASSERT_MSG_EQ(qd->GetNBytes(),
364 nBytes,
365 "Verify that the number of queued bytes is computed correctly");
366 NS_TEST_ASSERT_MSG_EQ(m_counter[qd].m_nBytes,
367 nBytes,
368 "Verify that the number of queued bytes is computed correctly");
369}
370
371void
373 uint32_t nDbePackets,
374 uint32_t nDbeBytes)
375{
376 QueueDisc::Stats stats = qd->GetStats();
377
380 nDbePackets,
381 "Verify that the number of packets dropped before enqueue is computed correctly");
383 m_counter[qd].m_nDbePackets,
384 nDbePackets,
385 "Verify that the number of packets dropped before enqueue is computed correctly");
386
389 nDbeBytes,
390 "Verify that the number of bytes dropped before enqueue is computed correctly");
392 m_counter[qd].m_nDbeBytes,
393 nDbeBytes,
394 "Verify that the number of bytes dropped before enqueue is computed correctly");
395}
396
397void
399 uint32_t nDadPackets,
400 uint32_t nDadBytes)
401{
402 QueueDisc::Stats stats = qd->GetStats();
403
406 nDadPackets,
407 "Verify that the number of packets dropped after dequeue is computed correctly");
409 m_counter[qd].m_nDadPackets,
410 nDadPackets,
411 "Verify that the number of packets dropped after dequeue is computed correctly");
412
415 nDadBytes,
416 "Verify that the number of bytes dropped after dequeue is computed correctly");
418 m_counter[qd].m_nDadBytes,
419 nDadBytes,
420 "Verify that the number of bytes dropped after dequeue is computed correctly");
421}
422
423void
425{
426 Address dest;
427 uint32_t pktSizeUnit = 100;
429
430 // Create queue discs
431 Ptr<QueueDisc> root = CreateObject<TestParentQueueDisc>();
432 root->Initialize();
433
434 Ptr<QueueDisc> child = root->GetQueueDiscClass(0)->GetQueueDisc();
435
436 NS_TEST_ASSERT_MSG_NE(child, nullptr, "The child queue disc has not been created");
437
438 // Create counters and connect traces to the counters
439 m_counter.emplace(root, TestCounter());
440 m_counter.emplace(child, TestCounter());
441
442 m_counter[root].ConnectTraces(root);
443 m_counter[child].ConnectTraces(child);
444
445 // Enqueue 4 packets. They must all be enqueued
446 for (uint16_t i = 1; i <= 4; i++)
447 {
448 root->Enqueue(Create<QdTestItem>(Create<Packet>(pktSizeUnit * i), dest));
449
450 CheckQueued(root, i, pktSizeUnit * i * (i + 1) / 2);
451 CheckDroppedBeforeEnqueue(root, 0, 0);
452 CheckDroppedAfterDequeue(root, 0, 0);
453
454 CheckQueued(child, i, pktSizeUnit * i * (i + 1) / 2);
455 CheckDroppedBeforeEnqueue(child, 0, 0);
456 CheckDroppedAfterDequeue(child, 0, 0);
457 }
458
459 // The fifth packet is dropped before enqueue by the child queue disc.
460 // The packet drop is notified to the root queue disc.
461 root->Enqueue(Create<QdTestItem>(Create<Packet>(pktSizeUnit * 5), dest));
462
463 CheckQueued(root, 4, pktSizeUnit * 10);
464 CheckDroppedBeforeEnqueue(root, 1, pktSizeUnit * 5);
465 CheckDroppedAfterDequeue(root, 0, 0);
466
467 CheckQueued(child, 4, pktSizeUnit * 10);
468 CheckDroppedBeforeEnqueue(child, 1, pktSizeUnit * 5);
469 CheckDroppedAfterDequeue(child, 0, 0);
470
471 // Peek one packet. The default DoPeek method asks the root queue disc to dequeue
472 // a packet, even though the statistics are not updated and the dequeue trace is
473 // not fired. The root queue disc asks the child queue disc to dequeue a packet.
474 // In this case, two packets (those having size of 100 and 200 bytes) are dequeued
475 // and dropped by the child queue disc. Therefore, the dequeue trace of the root
476 // queue disc is fired twice and the packet drops are notified to the root queue
477 // disc to reflect the fact that two packets are no longer in the queue disc.
478 // The peeked packet is still part of the root queue disc, but no longer part
479 // of the child queue disc.
480 item = root->Peek();
481
482 NS_TEST_ASSERT_MSG_NE(item, nullptr, "A packet must have been returned");
483 NS_TEST_ASSERT_MSG_EQ(item->GetSize(),
484 pktSizeUnit * 3,
485 "The peeked packet has not the expected size");
486
487 CheckQueued(root, 2, pktSizeUnit * 7);
488 CheckDroppedBeforeEnqueue(root, 1, pktSizeUnit * 5);
489 CheckDroppedAfterDequeue(root, 2, pktSizeUnit * 3);
490
491 CheckQueued(child, 1, pktSizeUnit * 4);
492 CheckDroppedBeforeEnqueue(child, 1, pktSizeUnit * 5);
493 CheckDroppedAfterDequeue(child, 2, pktSizeUnit * 3);
494
495 // Peek again. Nothing changes.
496 item = root->Peek();
497
498 NS_TEST_ASSERT_MSG_NE(item, nullptr, "A packet must have been returned");
499 NS_TEST_ASSERT_MSG_EQ(item->GetSize(),
500 pktSizeUnit * 3,
501 "The peeked packet has not the expected size");
502
503 CheckQueued(root, 2, pktSizeUnit * 7);
504 CheckDroppedBeforeEnqueue(root, 1, pktSizeUnit * 5);
505 CheckDroppedAfterDequeue(root, 2, pktSizeUnit * 3);
506
507 CheckQueued(child, 1, pktSizeUnit * 4);
508 CheckDroppedBeforeEnqueue(child, 1, pktSizeUnit * 5);
509 CheckDroppedAfterDequeue(child, 2, pktSizeUnit * 3);
510
511 // Dequeue one packet. The root queue disc returns the previously peeked packet.
512 item = root->Dequeue();
513
514 NS_TEST_ASSERT_MSG_NE(item, nullptr, "A packet must have been returned");
515 NS_TEST_ASSERT_MSG_EQ(item->GetSize(),
516 pktSizeUnit * 3,
517 "The dequeued packet has not the expected size");
518
519 CheckQueued(root, 1, pktSizeUnit * 4);
520 CheckDroppedBeforeEnqueue(root, 1, pktSizeUnit * 5);
521 CheckDroppedAfterDequeue(root, 2, pktSizeUnit * 3);
522
523 CheckQueued(child, 1, pktSizeUnit * 4);
524 CheckDroppedBeforeEnqueue(child, 1, pktSizeUnit * 5);
525 CheckDroppedAfterDequeue(child, 2, pktSizeUnit * 3);
526
527 // Dequeue the last packet.
528 item = root->Dequeue();
529
530 NS_TEST_ASSERT_MSG_NE(item, nullptr, "A packet must have been returned");
531 NS_TEST_ASSERT_MSG_EQ(item->GetSize(),
532 pktSizeUnit * 4,
533 "The dequeued packet has not the expected size");
534
535 CheckQueued(root, 0, 0);
536 CheckDroppedBeforeEnqueue(root, 1, pktSizeUnit * 5);
537 CheckDroppedAfterDequeue(root, 2, pktSizeUnit * 3);
538
539 CheckQueued(child, 0, 0);
540 CheckDroppedBeforeEnqueue(child, 1, pktSizeUnit * 5);
541 CheckDroppedAfterDequeue(child, 2, pktSizeUnit * 3);
542
543 // Peek a packet. No packet is left.
544 item = root->Peek();
545
546 NS_TEST_ASSERT_MSG_EQ(item, nullptr, "No packet must have been returned");
547
548 CheckQueued(root, 0, 0);
549 CheckDroppedBeforeEnqueue(root, 1, pktSizeUnit * 5);
550 CheckDroppedAfterDequeue(root, 2, pktSizeUnit * 3);
551
552 CheckQueued(child, 0, 0);
553 CheckDroppedBeforeEnqueue(child, 1, pktSizeUnit * 5);
554 CheckDroppedAfterDequeue(child, 2, pktSizeUnit * 3);
555
556 // Enqueue one packet.
557 root->Enqueue(Create<QdTestItem>(Create<Packet>(pktSizeUnit), dest));
558
559 CheckQueued(root, 1, pktSizeUnit);
560 CheckDroppedBeforeEnqueue(root, 1, pktSizeUnit * 5);
561 CheckDroppedAfterDequeue(root, 2, pktSizeUnit * 3);
562
563 CheckQueued(child, 1, pktSizeUnit);
564 CheckDroppedBeforeEnqueue(child, 1, pktSizeUnit * 5);
565 CheckDroppedAfterDequeue(child, 2, pktSizeUnit * 3);
566
567 // Dequeue one packet.
568 item = root->Dequeue();
569
570 NS_TEST_ASSERT_MSG_NE(item, nullptr, "A packet must have been returned");
571 NS_TEST_ASSERT_MSG_EQ(item->GetSize(),
572 pktSizeUnit,
573 "The dequeued packet has not the expected size");
574
575 CheckQueued(root, 0, 0);
576 CheckDroppedBeforeEnqueue(root, 1, pktSizeUnit * 5);
577 CheckDroppedAfterDequeue(root, 2, pktSizeUnit * 3);
578
579 CheckQueued(child, 0, 0);
580 CheckDroppedBeforeEnqueue(child, 1, pktSizeUnit * 5);
581 CheckDroppedAfterDequeue(child, 2, pktSizeUnit * 3);
582
584}
585
592{
593 public:
595 : TestSuite("queue-disc-traces", Type::UNIT)
596 {
597 AddTestCase(new QueueDiscTracesTestCase(), TestCase::Duration::QUICK);
598 }
Queue Disc Test Item.
void AddHeader() override
Add the header to the packet.
bool Mark() override
Marks the packet as a substitute for dropping it, such as for Explicit Congestion Notification.
QdTestItem(Ptr< Packet > p, const Address &addr)
Constructor.
Queue Disc Traces Test Case.
void DoRun() override
Implementation to actually run this TestCase.
std::map< Ptr< QueueDisc >, TestCounter > m_counter
counters for the queue discs
void CheckDroppedAfterDequeue(Ptr< QueueDisc > qd, uint32_t nDadPackets, uint32_t nDadBytes)
Check that packets/bytes dropped after dequeue are consistent with what is expected.
void CheckDroppedBeforeEnqueue(Ptr< QueueDisc > qd, uint32_t nDbePackets, uint32_t nDbeBytes)
Check that packets/bytes dropped before enqueue are consistent with what is expected.
void CheckQueued(Ptr< QueueDisc > qd, uint32_t nPackets, uint32_t nBytes)
Check that queued packets/bytes are consistent with what is expected.
Queue Disc Traces Test Suite.
Test Child Queue Disc that may drop packets before enqueue or after dequeue.
static constexpr const char * AFTER_DEQUEUE
Drop after dequeue.
bool DoEnqueue(Ptr< QueueDiscItem > item) override
This function actually enqueues a packet into the queue disc.
Ptr< QueueDiscItem > DoDequeue() override
This function actually extracts a packet from the queue disc.
void InitializeParams() override
Initialize parameters (if any) before the first packet is enqueued.
static constexpr const char * BEFORE_ENQUEUE
Drop before enqueue.
bool CheckConfig() override
Check whether the current configuration is correct.
Keep statistics based on traces.
void PacketDequeued(Ptr< const QueueDiscItem > item)
Update statistics after a packet has been dequeued.
void PacketDad(Ptr< const QueueDiscItem > item, const char *reason)
Update statistics after a packet has been dropped after dequeue.
void PacketDbe(Ptr< const QueueDiscItem > item, const char *reason)
Update statistics after a packet has been dropped before enqueue.
uint32_t m_nDbeBytes
Number of packets dropped before enqueue.
void PacketEnqueued(Ptr< const QueueDiscItem > item)
Update statistics after a packet has been enqueued.
uint32_t m_nPackets
Number of queued packets.
uint32_t m_nBytes
Number of queued bytes.
uint32_t m_nDbePackets
Number of packets dropped before enqueue.
uint32_t m_nDadBytes
Number of packets dropped after dequeue.
uint32_t m_nDadPackets
Number of packets dropped after dequeue.
void ConnectTraces(Ptr< QueueDisc > qd)
Connect private methods to the queue disc traces.
Test Parent Queue Disc having a child of type TestChildQueueDisc.
Ptr< QueueDiscItem > DoDequeue() override
This function actually extracts a packet from the queue disc.
bool CheckConfig() override
Check whether the current configuration is correct.
void InitializeParams() override
Initialize parameters (if any) before the first packet is enqueued.
bool DoEnqueue(Ptr< QueueDiscItem > item) override
This function actually enqueues a packet into the queue disc.
a polymophic address class
Definition: address.h:101
A FIFO packet queue that drops tail-end packets on overflow.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
QueueDisc is an abstract base class providing the interface and implementing the operations common to...
Definition: queue-disc.h:184
void AddInternalQueue(Ptr< InternalQueue > queue)
Add an internal queue to the tail of the list of queues.
Definition: queue-disc.cc:573
void AddQueueDiscClass(Ptr< QueueDiscClass > qdClass)
Add a queue disc class to the tail of the list of classes.
Definition: queue-disc.cc:624
uint32_t GetNPackets() const
Get the number of packets stored by the queue disc.
Definition: queue-disc.cc:432
Ptr< InternalQueue > GetInternalQueue(std::size_t i) const
Get the i-th internal queue.
Definition: queue-disc.cc:591
void DropAfterDequeue(Ptr< const QueueDiscItem > item, const char *reason)
Perform the actions required when the queue disc is notified of a packet dropped after dequeue.
Definition: queue-disc.cc:759
Ptr< QueueDiscClass > GetQueueDiscClass(std::size_t i) const
Get the i-th queue disc class.
Definition: queue-disc.cc:654
void DropBeforeEnqueue(Ptr< const QueueDiscItem > item, const char *reason)
Perform the actions required when the queue disc is notified of a packet dropped before enqueue.
Definition: queue-disc.cc:720
QueueDiscItem is the abstract base class for items that are stored in a queue disc.
Definition: queue-item.h:133
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
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
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:630
#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
QueueDiscTracesTestSuite g_queueDiscTracesTestSuite
the test suite
QueueDiscSizePolicy
Enumeration of the available policies to handle the queue disc size.
Definition: queue-disc.h:107
@ SINGLE_INTERNAL_QUEUE
Used by queue discs with single internal queue.
Definition: queue-disc.h:108
@ SINGLE_CHILD_QUEUE_DISC
Used by queue discs with single child queue disc.
Definition: queue-disc.h:109
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
Structure that keeps the queue disc statistics.
Definition: queue-disc.h:188
uint64_t nTotalDroppedBytesBeforeEnqueue
Total bytes dropped before enqueue.
Definition: queue-disc.h:218
uint64_t nTotalDroppedBytesAfterDequeue
Total bytes dropped after dequeue.
Definition: queue-disc.h:222
uint32_t nTotalDroppedPacketsBeforeEnqueue
Total packets dropped before enqueue.
Definition: queue-disc.h:208
uint32_t nTotalDroppedPacketsAfterDequeue
Total packets dropped after dequeue.
Definition: queue-disc.h:212