A Discrete-Event Network Simulator
API
fq-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 Universita' degli Studi di Napoli Federico II
4 * Copyright (c) 2020 NITK Surathkal (modified for FQ-PIE)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation;
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * Authors: Pasquale Imputato <p.imputato@gmail.com>
20 * Stefano Avallone <stefano.avallone@unina.it>
21 * Modified for FQ-PIE by: Bhaskar Kataria <bhaskar.k7920@gmail.com>
22 * Tom Henderson <tomhend@u.washington.edu>
23 * Mohit P. Tahiliani <tahiliani@nitk.edu.in>
24 * Vivek Jain <jain.vivek.anand@gmail.com>
25 * Ankit Deepak <adadeepak8@gmail.com>
26 *
27 */
28
29#include "ns3/test.h"
30#include "ns3/simulator.h"
31#include "ns3/fq-pie-queue-disc.h"
32#include "ns3/pie-queue-disc.h"
33#include "ns3/ipv4-header.h"
34#include "ns3/ipv4-packet-filter.h"
35#include "ns3/ipv4-queue-disc-item.h"
36#include "ns3/ipv4-address.h"
37#include "ns3/ipv6-header.h"
38#include "ns3/ipv6-packet-filter.h"
39#include "ns3/ipv6-queue-disc-item.h"
40#include "ns3/tcp-header.h"
41#include "ns3/udp-header.h"
42#include "ns3/string.h"
43#include "ns3/pointer.h"
44
45using namespace ns3;
46
49
56{
57public:
62 static TypeId GetTypeId (void);
63
66
67private:
73 virtual int32_t DoClassify (Ptr<QueueDiscItem> item) const;
74
80 virtual bool CheckProtocol (Ptr<QueueDiscItem> item) const;
81};
82
85{
86 static TypeId tid = TypeId ("ns3::Ipv4FqPieTestPacketFilter")
88 .SetGroupName ("Internet")
89 .AddConstructor<Ipv4FqPieTestPacketFilter> ()
90 ;
91 return tid;
92}
93
95{}
96
98{}
99
102{
103 return g_hash;
104}
105
106bool
108{
109 return true;
110}
111
118{
119public:
122
123private:
124 virtual void DoRun (void);
125};
126
128 : TestCase ("Test packets that are not classified by any filter")
129{}
130
132{}
133
134void
136{
137 // Packets that cannot be classified by the available filters should be dropped
138 Ptr<FqPieQueueDisc> queueDisc = CreateObjectWithAttributes<FqPieQueueDisc> ("MaxSize", StringValue ("4p"));
139 Ptr<Ipv4FqPieTestPacketFilter> filter = CreateObject<Ipv4FqPieTestPacketFilter> ();
140 queueDisc->AddPacketFilter (filter);
141
142 g_hash = -1;
143 queueDisc->SetQuantum (1500);
144 queueDisc->Initialize ();
145
146 Ptr<Packet> p;
147 p = Create<Packet> ();
149 Ipv6Header ipv6Header;
150 Address dest;
151 item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
152 queueDisc->Enqueue (item);
153 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetNQueueDiscClasses (), 0, "no flow queue should have been created");
154
155 p = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello, world"), 12);
156 item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
157 queueDisc->Enqueue (item);
158 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetNQueueDiscClasses (), 0, "no flow queue should have been created");
159
160 Simulator::Destroy ();
161}
162
169{
170public:
173
174private:
175 virtual void DoRun (void);
181 void AddPacket (Ptr<FqPieQueueDisc> queue, Ipv4Header hdr);
182};
183
185 : TestCase ("Test IP flows separation and packet limit")
186{}
187
189{}
190
191void
193{
194 Ptr<Packet> p = Create<Packet> (100);
195 Address dest;
196 Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, hdr);
197 queue->Enqueue (item);
198}
199
200void
202{
203 Ptr<FqPieQueueDisc> queueDisc = CreateObjectWithAttributes<FqPieQueueDisc> ("MaxSize", StringValue ("4p"));
204
205 queueDisc->SetQuantum (1500);
206 queueDisc->Initialize ();
207
208 Ipv4Header hdr;
209 hdr.SetPayloadSize (100);
210 hdr.SetSource (Ipv4Address ("10.10.1.1"));
211 hdr.SetDestination (Ipv4Address ("10.10.1.2"));
212 hdr.SetProtocol (7);
213
214 // Add three packets from the first flow
215 AddPacket (queueDisc, hdr);
216 AddPacket (queueDisc, hdr);
217 AddPacket (queueDisc, hdr);
218 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
219 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the flow queue");
220
221 // Add two packets from the second flow
222 hdr.SetDestination (Ipv4Address ("10.10.1.7"));
223 // Add the first packet
224 AddPacket (queueDisc, hdr);
225 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 4, "unexpected number of packets in the queue disc");
226 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the flow queue");
227 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the flow queue");
228 // Add the second packet that causes two packets to be dropped from the fat flow (max backlog = 300, threshold = 150)
229 AddPacket (queueDisc, hdr);
230 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
231 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the flow queue");
232 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the flow queue");
233
234 Simulator::Destroy ();
235}
236
243{
244public:
246 virtual ~FqPieQueueDiscDeficit ();
247
248private:
249 virtual void DoRun (void);
255 void AddPacket (Ptr<FqPieQueueDisc> queue, Ipv4Header hdr);
256};
257
259 : TestCase ("Test credits and flows status")
260{}
261
263{}
264
265void
267{
268 Ptr<Packet> p = Create<Packet> (100);
269 Address dest;
270 Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, hdr);
271 queue->Enqueue (item);
272}
273
274void
276{
277 Ptr<FqPieQueueDisc> queueDisc = CreateObject<FqPieQueueDisc> ();
278
279 queueDisc->SetQuantum (90);
280 queueDisc->Initialize ();
281
282 Ipv4Header hdr;
283 hdr.SetPayloadSize (100);
284 hdr.SetSource (Ipv4Address ("10.10.1.1"));
285 hdr.SetDestination (Ipv4Address ("10.10.1.2"));
286 hdr.SetProtocol (7);
287
288 // Add a packet from the first flow
289 AddPacket (queueDisc, hdr);
290 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 1, "unexpected number of packets in the queue disc");
291 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the first flow queue");
292 Ptr<FqPieFlow> flow1 = StaticCast<FqPieFlow> (queueDisc->GetQueueDiscClass (0));
293 NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), static_cast<int32_t> (queueDisc->GetQuantum ()), "the deficit of the first flow must equal the quantum");
294 NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqPieFlow::NEW_FLOW, "the first flow must be in the list of new queues");
295 // Dequeue a packet
296 queueDisc->Dequeue ();
297 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 0, "unexpected number of packets in the queue disc");
298 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 0, "unexpected number of packets in the first flow queue");
299 // the deficit for the first flow becomes 90 - (100+20) = -30
300 NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), -30, "unexpected deficit for the first flow");
301
302 // Add two packets from the first flow
303 AddPacket (queueDisc, hdr);
304 AddPacket (queueDisc, hdr);
305 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 2, "unexpected number of packets in the queue disc");
306 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the first flow queue");
307 NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqPieFlow::NEW_FLOW, "the first flow must still be in the list of new queues");
308
309 // Add two packets from the second flow
310 hdr.SetDestination (Ipv4Address ("10.10.1.10"));
311 AddPacket (queueDisc, hdr);
312 AddPacket (queueDisc, hdr);
313 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 4, "unexpected number of packets in the queue disc");
314 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the first flow queue");
315 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the second flow queue");
316 Ptr<FqPieFlow> flow2 = StaticCast<FqPieFlow> (queueDisc->GetQueueDiscClass (1));
317 NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), static_cast<int32_t> (queueDisc->GetQuantum ()), "the deficit of the second flow must equal the quantum");
318 NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqPieFlow::NEW_FLOW, "the second flow must be in the list of new queues");
319
320 // Dequeue a packet (from the second flow, as the first flow has a negative deficit)
321 queueDisc->Dequeue ();
322 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
323 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the first flow queue");
324 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
325 // the first flow got a quantum of deficit (-30+90=60) and has been moved to the end of the list of old queues
326 NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), 60, "unexpected deficit for the first flow");
327 NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqPieFlow::OLD_FLOW, "the first flow must be in the list of old queues");
328 // the second flow has a negative deficit (-30) and is still in the list of new queues
329 NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), -30, "unexpected deficit for the second flow");
330 NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqPieFlow::NEW_FLOW, "the second flow must be in the list of new queues");
331
332 // Dequeue a packet (from the first flow, as the second flow has a negative deficit)
333 queueDisc->Dequeue ();
334 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 2, "unexpected number of packets in the queue disc");
335 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the first flow queue");
336 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
337 // the first flow has a negative deficit (60-(100+20)= -60) and stays in the list of old queues
338 NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), -60, "unexpected deficit for the first flow");
339 NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqPieFlow::OLD_FLOW, "the first flow must be in the list of old queues");
340 // the second flow got a quantum of deficit (-30+90=60) and has been moved to the end of the list of old queues
341 NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), 60, "unexpected deficit for the second flow");
342 NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqPieFlow::OLD_FLOW, "the second flow must be in the list of new queues");
343
344 // Dequeue a packet (from the second flow, as the first flow has a negative deficit)
345 queueDisc->Dequeue ();
346 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 1, "unexpected number of packets in the queue disc");
347 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the first flow queue");
348 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 0, "unexpected number of packets in the second flow queue");
349 // the first flow got a quantum of deficit (-60+90=30) and has been moved to the end of the list of old queues
350 NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), 30, "unexpected deficit for the first flow");
351 NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqPieFlow::OLD_FLOW, "the first flow must be in the list of old queues");
352 // the second flow has a negative deficit (60-(100+20)= -60)
353 NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), -60, "unexpected deficit for the second flow");
354 NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqPieFlow::OLD_FLOW, "the second flow must be in the list of new queues");
355
356 // Dequeue a packet (from the first flow, as the second flow has a negative deficit)
357 queueDisc->Dequeue ();
358 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 0, "unexpected number of packets in the queue disc");
359 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 0, "unexpected number of packets in the first flow queue");
360 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 0, "unexpected number of packets in the second flow queue");
361 // the first flow has a negative deficit (30-(100+20)= -90)
362 NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), -90, "unexpected deficit for the first flow");
363 NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqPieFlow::OLD_FLOW, "the first flow must be in the list of old queues");
364 // the second flow got a quantum of deficit (-60+90=30) and has been moved to the end of the list of old queues
365 NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), 30, "unexpected deficit for the second flow");
366 NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqPieFlow::OLD_FLOW, "the second flow must be in the list of new queues");
367
368 // Dequeue a packet
369 queueDisc->Dequeue ();
370 // the first flow is at the head of the list of old queues but has a negative deficit, thus it gets a quantun
371 // of deficit (-90+90=0) and is moved to the end of the list of old queues. Then, the second flow (which has a
372 // positive deficit) is selected, but the second flow is empty and thus it is set to inactive. The first flow is
373 // reconsidered, but it has a null deficit, hence it gets another quantum of deficit (0+90=90). Then, the first
374 // flow is reconsidered again, now it has a positive deficit and hence it is selected. But, it is empty and
375 // therefore is set to inactive, too.
376 NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), 90, "unexpected deficit for the first flow");
377 NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqPieFlow::INACTIVE, "the first flow must be inactive");
378 NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), 30, "unexpected deficit for the second flow");
379 NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqPieFlow::INACTIVE, "the second flow must be inactive");
380
381 Simulator::Destroy ();
382}
383
390{
391public:
394
395private:
396 virtual void DoRun (void);
403 void AddPacket (Ptr<FqPieQueueDisc> queue, Ipv4Header ipHdr, TcpHeader tcpHdr);
404};
405
407 : TestCase ("Test TCP flows separation")
408{}
409
411{}
412
413void
415{
416 Ptr<Packet> p = Create<Packet> (100);
417 p->AddHeader (tcpHdr);
418 Address dest;
419 Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHdr);
420 queue->Enqueue (item);
421}
422
423void
425{
426 Ptr<FqPieQueueDisc> queueDisc = CreateObjectWithAttributes<FqPieQueueDisc> ("MaxSize", StringValue ("10p"));
427
428 queueDisc->SetQuantum (1500);
429 queueDisc->Initialize ();
430
431 Ipv4Header hdr;
432 hdr.SetPayloadSize (100);
433 hdr.SetSource (Ipv4Address ("10.10.1.1"));
434 hdr.SetDestination (Ipv4Address ("10.10.1.2"));
435 hdr.SetProtocol (6);
436
437 TcpHeader tcpHdr;
438 tcpHdr.SetSourcePort (7);
439 tcpHdr.SetDestinationPort (27);
440
441 // Add three packets from the first flow
442 AddPacket (queueDisc, hdr, tcpHdr);
443 AddPacket (queueDisc, hdr, tcpHdr);
444 AddPacket (queueDisc, hdr, tcpHdr);
445 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
446 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
447
448 // Add a packet from the second flow
449 tcpHdr.SetSourcePort (8);
450 AddPacket (queueDisc, hdr, tcpHdr);
451 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 4, "unexpected number of packets in the queue disc");
452 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
453 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
454
455 // Add a packet from the third flow
456 tcpHdr.SetDestinationPort (28);
457 AddPacket (queueDisc, hdr, tcpHdr);
458 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 5, "unexpected number of packets in the queue disc");
459 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
460 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
461 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the third flow queue");
462
463 // Add two packets from the fourth flow
464 tcpHdr.SetSourcePort (7);
465 AddPacket (queueDisc, hdr, tcpHdr);
466 AddPacket (queueDisc, hdr, tcpHdr);
467 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 7, "unexpected number of packets in the queue disc");
468 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
469 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
470 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the third flow queue");
471 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the third flow queue");
472
473 Simulator::Destroy ();
474}
475
482{
483public:
486
487private:
488 virtual void DoRun (void);
495 void AddPacket (Ptr<FqPieQueueDisc> queue, Ipv4Header ipHdr, UdpHeader udpHdr);
496};
497
499 : TestCase ("Test UDP flows separation")
500{}
501
503{}
504
505void
507{
508 Ptr<Packet> p = Create<Packet> (100);
509 p->AddHeader (udpHdr);
510 Address dest;
511 Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHdr);
512 queue->Enqueue (item);
513}
514
515void
517{
518 Ptr<FqPieQueueDisc> queueDisc = CreateObjectWithAttributes<FqPieQueueDisc> ("MaxSize", StringValue ("10p"));
519
520 queueDisc->SetQuantum (1500);
521 queueDisc->Initialize ();
522
523 Ipv4Header hdr;
524 hdr.SetPayloadSize (100);
525 hdr.SetSource (Ipv4Address ("10.10.1.1"));
526 hdr.SetDestination (Ipv4Address ("10.10.1.2"));
527 hdr.SetProtocol (17);
528
529 UdpHeader udpHdr;
530 udpHdr.SetSourcePort (7);
531 udpHdr.SetDestinationPort (27);
532
533 // Add three packets from the first flow
534 AddPacket (queueDisc, hdr, udpHdr);
535 AddPacket (queueDisc, hdr, udpHdr);
536 AddPacket (queueDisc, hdr, udpHdr);
537 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
538 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
539
540 // Add a packet from the second flow
541 udpHdr.SetSourcePort (8);
542 AddPacket (queueDisc, hdr, udpHdr);
543 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 4, "unexpected number of packets in the queue disc");
544 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
545 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
546
547 // Add a packet from the third flow
548 udpHdr.SetDestinationPort (28);
549 AddPacket (queueDisc, hdr, udpHdr);
550 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 5, "unexpected number of packets in the queue disc");
551 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
552 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
553 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the third flow queue");
554
555 // Add two packets from the fourth flow
556 udpHdr.SetSourcePort (7);
557 AddPacket (queueDisc, hdr, udpHdr);
558 AddPacket (queueDisc, hdr, udpHdr);
559 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 7, "unexpected number of packets in the queue disc");
560 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
561 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
562 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the third flow queue");
563 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the third flow queue");
564
565 Simulator::Destroy ();
566}
567
568
596{
597public:
600
601private:
602 virtual void DoRun (void);
608 void AddPacket (Ptr<FqPieQueueDisc> queue, Ipv4Header hdr);
609};
610
612 : TestCase ("Test credits and flows status")
613{}
614
616{}
617
618void
620{
621 Ptr<Packet> p = Create<Packet> (100);
622 Address dest;
623 Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, hdr);
624 queue->Enqueue (item);
625}
626
627void
629{
630 Ptr<FqPieQueueDisc> queueDisc = CreateObjectWithAttributes<FqPieQueueDisc> ("EnableSetAssociativeHash", BooleanValue (true));
631 queueDisc->SetQuantum (90);
632 queueDisc->Initialize ();
633
634 Ptr<Ipv4FqPieTestPacketFilter> filter = CreateObject<Ipv4FqPieTestPacketFilter> ();
635 queueDisc->AddPacketFilter (filter);
636
637 Ipv4Header hdr;
638 hdr.SetPayloadSize (100);
639 hdr.SetSource (Ipv4Address ("10.10.1.1"));
640 hdr.SetDestination (Ipv4Address ("10.10.1.2"));
641 hdr.SetProtocol (7);
642
643 g_hash = 0;
644 AddPacket (queueDisc, hdr);
645 g_hash = 1;
646 AddPacket (queueDisc, hdr);
647 AddPacket (queueDisc, hdr);
648 g_hash = 2;
649 AddPacket (queueDisc, hdr);
650 g_hash = 3;
651 AddPacket (queueDisc, hdr);
652 g_hash = 4;
653 AddPacket (queueDisc, hdr);
654 AddPacket (queueDisc, hdr);
655 g_hash = 5;
656 AddPacket (queueDisc, hdr);
657 g_hash = 6;
658 AddPacket (queueDisc, hdr);
659 g_hash = 7;
660 AddPacket (queueDisc, hdr);
661 g_hash = 1024;
662 AddPacket (queueDisc, hdr);
663
664 NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 11,
665 "unexpected number of packets in the queue disc");
666 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 2,
667 "unexpected number of packets in the first flow queue of set one");
668 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 2,
669 "unexpected number of packets in the second flow queue of set one");
670 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1,
671 "unexpected number of packets in the third flow queue of set one");
672 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetNPackets (), 1,
673 "unexpected number of packets in the fourth flow queue of set one");
674 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (4)->GetQueueDisc ()->GetNPackets (), 2,
675 "unexpected number of packets in the fifth flow queue of set one");
676 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (5)->GetQueueDisc ()->GetNPackets (), 1,
677 "unexpected number of packets in the sixth flow queue of set one");
678 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (6)->GetQueueDisc ()->GetNPackets (), 1,
679 "unexpected number of packets in the seventh flow queue of set one");
680 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (7)->GetQueueDisc ()->GetNPackets (), 1,
681 "unexpected number of packets in the eighth flow queue of set one");
682 g_hash = 1025;
683 AddPacket (queueDisc, hdr);
684 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3,
685 "unexpected number of packets in the first flow of set one");
686 g_hash = 10;
687 AddPacket (queueDisc, hdr);
688 NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (8)->GetQueueDisc ()->GetNPackets (), 1,
689 "unexpected number of packets in the first flow of set two");
690 Simulator::Destroy ();
691}
692
693
710{
711public:
713 virtual ~FqPieQueueDiscL4sMode ();
714
715private:
716 virtual void DoRun (void);
723 void AddPacket (Ptr<FqPieQueueDisc> queue, Ipv4Header hdr, u_int32_t nPkt);
731 void AddPacketWithDelay (Ptr<FqPieQueueDisc> queue,Ipv4Header hdr, double delay, uint32_t nPkt);
737 void Dequeue (Ptr<FqPieQueueDisc> queue, uint32_t nPkt);
744 void DequeueWithDelay (Ptr<FqPieQueueDisc> queue, double delay, uint32_t nPkt);
745};
746
748 : TestCase ("Test L4S mode")
749{}
750
752{}
753
754void
756{
757 Address dest;
758 Ptr<Packet> p = Create<Packet> (100);
759 for (uint32_t i = 0; i < nPkt; i++)
760 {
761 Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, hdr);
762 queue->Enqueue (item);
763 }
764}
765
766void
768{
769 for (uint32_t i = 0; i < nPkt; i++)
770 {
771 Simulator::Schedule (Time (Seconds ((i + 1) * delay)), &FqPieQueueDiscL4sMode::AddPacket, this, queue, hdr, 1);
772 }
773}
774
775void
777{
778 for (uint32_t i = 0; i < nPkt; i++)
779 {
780 Ptr<QueueDiscItem> item = queue->Dequeue ();
781 }
782}
783
784void
786{
787 for (uint32_t i = 0; i < nPkt; i++)
788 {
789 Simulator::Schedule (Time (Seconds ((i + 1) * delay)), &FqPieQueueDiscL4sMode::Dequeue, this, queue, 1);
790 }
791}
792
793void
795{
796 // Test is divided into 2 sub test cases:
797 // 1) Without hash collisions
798 // 2) With hash collisions
799
800 // Test case 1, Without hash collisions
801 Ptr<FqPieQueueDisc> queueDisc = CreateObjectWithAttributes<FqPieQueueDisc> ("MaxSize", StringValue ("10240p"),
802 "UseEcn", BooleanValue (true), "Perturbation", UintegerValue (0),
803 "UseL4s", BooleanValue (true), "CeThreshold", TimeValue (MilliSeconds (2)));
804
805 queueDisc->SetQuantum (1514);
806 queueDisc->Initialize ();
807 Ipv4Header hdr;
808 hdr.SetPayloadSize (100);
809 hdr.SetSource (Ipv4Address ("10.10.1.1"));
810 hdr.SetDestination (Ipv4Address ("10.10.1.2"));
811 hdr.SetProtocol (7);
812 hdr.SetEcn (Ipv4Header::ECN_ECT1);
813
814 // Add 70 ECT1 (ECN capable) packets from the first flow
815 // Set delay = 0.5ms
816 double delay = 0.0005;
817 Simulator::Schedule (Time (Seconds (0)), &FqPieQueueDiscL4sMode::AddPacketWithDelay, this, queueDisc, hdr, delay, 70);
818
819 // Add 70 ECT0 (ECN capable) packets from second flow
820 hdr.SetEcn (Ipv4Header::ECN_ECT0);
821 hdr.SetDestination (Ipv4Address ("10.10.1.10"));
822 Simulator::Schedule (Time (Seconds (0)), &FqPieQueueDiscL4sMode::AddPacketWithDelay, this, queueDisc, hdr, delay, 70);
823
824 //Dequeue 140 packets with delay 1ms
825 delay = 0.001;
826 DequeueWithDelay (queueDisc, delay, 140);
827 Simulator::Stop (Seconds (10.0));
828 Simulator::Run ();
829
830 Ptr<PieQueueDisc> q0 = queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetObject <PieQueueDisc> ();
831 Ptr<PieQueueDisc> q1 = queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetObject <PieQueueDisc> ();
832
833 NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNMarkedPackets (PieQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 66, "There should be 66 marked packets"
834 "4th packet is enqueued at 2ms and dequeued at 4ms hence the delay of 2ms which not greater than CE threshold"
835 "5th packet is enqueued at 2.5ms and dequeued at 5ms hence the delay of 2.5ms and subsequent packet also do have delay"
836 "greater than CE threshold so all the packets after 4th packet are marked");
837 NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP), 0, "Queue delay is less than max burst allowance so"
838 "There should not be any dropped packets");
839 NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNMarkedPackets (PieQueueDisc::UNFORCED_MARK), 0, "There should not be any marked packets");
840 NS_TEST_EXPECT_MSG_EQ (q1->GetStats ().GetNMarkedPackets (PieQueueDisc::UNFORCED_MARK), 0, "There should not be marked packets.");
841 NS_TEST_EXPECT_MSG_EQ (q1->GetStats ().GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP), 0, "There should not be any dropped packets");
842
843 Simulator::Destroy ();
844
845 // Test case 2, With hash collisions
846 queueDisc = CreateObjectWithAttributes<FqPieQueueDisc> ("MaxSize", StringValue ("10240p"),
847 "UseEcn", BooleanValue (true), "Perturbation", UintegerValue (0),
848 "UseL4s", BooleanValue (true), "CeThreshold", TimeValue (MilliSeconds (2)));
849
850 queueDisc->SetQuantum (1514);
851 queueDisc->Initialize ();
852 hdr.SetPayloadSize (100);
853 hdr.SetSource (Ipv4Address ("10.10.1.1"));
854 hdr.SetDestination (Ipv4Address ("10.10.1.2"));
855 hdr.SetProtocol (7);
856 hdr.SetEcn (Ipv4Header::ECN_ECT1);
857
858 // Add 70 ECT1 (ECN capable) packets from the first flow
859 // Set delay = 1ms
860 delay = 0.001;
861 Simulator::Schedule (Time (Seconds (0.0005)), &FqPieQueueDiscL4sMode::AddPacket, this, queueDisc, hdr, 1);
862 Simulator::Schedule (Time (Seconds (0.0005)), &FqPieQueueDiscL4sMode::AddPacketWithDelay, this, queueDisc, hdr, delay, 69);
863
864 // Add 70 ECT0 (ECN capable) packets from first flow
865 hdr.SetEcn (Ipv4Header::ECN_ECT0);
866 Simulator::Schedule (Time (Seconds (0)), &FqPieQueueDiscL4sMode::AddPacketWithDelay, this, queueDisc, hdr, delay, 70);
867
868 //Dequeue 140 packets with delay 1ms
869 DequeueWithDelay (queueDisc, delay, 140);
870 Simulator::Stop (Seconds (1.0));
871 Simulator::Run ();
872 q0 = queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetObject <PieQueueDisc> ();
873 q0 = queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetObject <PieQueueDisc> ();
874
875 NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNMarkedPackets (PieQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 68, "There should be 68 marked packets"
876 "2nd ECT1 packet is enqueued at 1.5ms and dequeued at 3ms hence the delay of 1.5ms which not greater than CE threshold"
877 "3rd packet is enqueued at 2.5ms and dequeued at 5ms hence the delay of 2.5ms and subsequent packet also do have delay"
878 "greater than CE threshold so all the packets after 2nd packet are marked");
879 NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNDroppedPackets (PieQueueDisc::UNFORCED_DROP), 0, "Queue delay is less than max burst allowance so"
880 "There should not be any dropped packets");
881 NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNMarkedPackets (PieQueueDisc::UNFORCED_MARK), 0, "There should not be any marked packets");
882
883 Simulator::Destroy ();
884}
885
886
893{
894public:
896};
897
899 : TestSuite ("fq-pie-queue-disc", UNIT)
900{
901 AddTestCase (new FqPieQueueDiscNoSuitableFilter, TestCase::QUICK);
903 AddTestCase (new FqPieQueueDiscDeficit, TestCase::QUICK);
904 AddTestCase (new FqPieQueueDiscTCPFlowsSeparation, TestCase::QUICK);
905 AddTestCase (new FqPieQueueDiscUDPFlowsSeparation, TestCase::QUICK);
906 AddTestCase (new FqPieQueueDiscSetLinearProbing, TestCase::QUICK);
907 AddTestCase (new FqPieQueueDiscL4sMode, TestCase::QUICK);
908}
909
This class tests the deficit per flow.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void AddPacket(Ptr< FqPieQueueDisc > queue, Ipv4Header hdr)
Enqueue a packet.
This class tests the IP flows separation and the packet limit.
void AddPacket(Ptr< FqPieQueueDisc > queue, Ipv4Header hdr)
Enqueue a packet.
virtual void DoRun(void)
Implementation to actually run this TestCase.
This class tests L4S mode.
void AddPacketWithDelay(Ptr< FqPieQueueDisc > queue, Ipv4Header hdr, double delay, uint32_t nPkt)
Enqueue the given number of packets at different times.
void DequeueWithDelay(Ptr< FqPieQueueDisc > queue, double delay, uint32_t nPkt)
Dequeue the given number of packets at different times.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void AddPacket(Ptr< FqPieQueueDisc > queue, Ipv4Header hdr, u_int32_t nPkt)
Enqueue the given number of packets.
void Dequeue(Ptr< FqPieQueueDisc > queue, uint32_t nPkt)
Dequeue the given number of packets.
This class tests packets for which there is no suitable filter.
virtual void DoRun(void)
Implementation to actually run this TestCase.
This class tests linear probing, collision response, and set creation capability of set associative h...
void AddPacket(Ptr< FqPieQueueDisc > queue, Ipv4Header hdr)
Enqueue a packet.
virtual void DoRun(void)
Implementation to actually run this TestCase.
This class tests the TCP flows separation.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void AddPacket(Ptr< FqPieQueueDisc > queue, Ipv4Header ipHdr, TcpHeader tcpHdr)
Enqueue a packet.
FQ-PIE queue disc test suite.
This class tests the UDP flows separation.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void AddPacket(Ptr< FqPieQueueDisc > queue, Ipv4Header ipHdr, UdpHeader udpHdr)
Enqueue a packet.
Simple test packet filter able to classify IPv4 packets.
virtual int32_t DoClassify(Ptr< QueueDiscItem > item) const
Classify a QueueDiscItem.
virtual bool CheckProtocol(Ptr< QueueDiscItem > item) const
Check the protocol.
static TypeId GetTypeId(void)
Get the type ID.
a polymophic address class
Definition: address.h:91
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
Packet header for IPv4.
Definition: ipv4-header.h:34
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:298
void SetPayloadSize(uint16_t size)
Definition: ipv4-header.cc:56
void SetEcn(EcnType ecn)
Set ECN Field.
Definition: ipv4-header.cc:97
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:278
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:285
Ipv4PacketFilter is the abstract base class for filters defined for IPv4 packets.
Packet header for IPv6.
Definition: ipv6-header.h:36
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
Implements PIE Active Queue Management discipline.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
Hold variables of type string.
Definition: string.h:41
Header for the Transmission Control Protocol.
Definition: tcp-header.h:45
void SetDestinationPort(uint16_t port)
Set the destination port.
Definition: tcp-header.cc:95
void SetSourcePort(uint16_t port)
Set the source port.
Definition: tcp-header.cc:89
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
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
AttributeValue implementation for Time.
Definition: nstime.h:1308
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Packet header for UDP packets.
Definition: udp-header.h:40
void SetSourcePort(uint16_t port)
Definition: udp-header.cc:60
void SetDestinationPort(uint16_t port)
Definition: udp-header.cc:55
Hold an unsigned integer type.
Definition: uinteger.h:44
static FqPieQueueDiscTestSuite g_fqPieQueueDiscTestSuite
Do not forget to allocate an instance of this TestSuite.
static int32_t g_hash
Variable to assign g_hash to a new packet's flow.
@ INACTIVE
Inactive Period or unslotted CSMA-CA.
Definition: lr-wpan-mac.h:93
#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_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:240
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
Every class exported by the ns3 library is enclosed in the ns3 namespace.