A Discrete-Event Network Simulator
API
fq-codel-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  *
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: Pasquale Imputato <p.imputato@gmail.com>
19  * Stefano Avallone <stefano.avallone@unina.it>
20 */
21 
22 #include "ns3/test.h"
23 #include "ns3/simulator.h"
24 #include "ns3/fq-codel-queue-disc.h"
25 #include "ns3/ipv4-header.h"
26 #include "ns3/ipv4-packet-filter.h"
27 #include "ns3/ipv4-queue-disc-item.h"
28 #include "ns3/ipv4-address.h"
29 #include "ns3/ipv6-header.h"
30 #include "ns3/ipv6-packet-filter.h"
31 #include "ns3/ipv6-queue-disc-item.h"
32 #include "ns3/tcp-header.h"
33 #include "ns3/udp-header.h"
34 #include "ns3/uinteger.h"
35 #include "ns3/pointer.h"
36 
37 using namespace ns3;
38 
43 {
44 public:
47 
48 private:
49  virtual void DoRun (void);
50 };
51 
53  : TestCase ("Test packets that are not classified by any filter")
54 {
55 }
56 
58 {
59 }
60 
61 void
63 {
64  // Packets that cannot be classified by the available filters should be dropped
65  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("PacketLimit", UintegerValue (4));
66  Ptr<FqCoDelIpv4PacketFilter> filter = CreateObject<FqCoDelIpv4PacketFilter> ();
67  queueDisc->AddPacketFilter (filter);
68 
69  queueDisc->SetQuantum (1500);
70  queueDisc->Initialize ();
71 
72  Ptr<Packet> p;
73  p = Create<Packet> ();
75  Ipv6Header ipv6Header;
76  Address dest;
77  item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
78  queueDisc->Enqueue (item);
79  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetNQueueDiscClasses (), 0, "no flow queue should have been created");
80 
81  p = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello, world"), 12);
82  item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
83  queueDisc->Enqueue (item);
84  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetNQueueDiscClasses (), 0, "no flow queue should have been created");
85 
86  Simulator::Destroy ();
87 }
88 
93 {
94 public:
97 
98 private:
99  virtual void DoRun (void);
100  void AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr);
101 };
102 
104  : TestCase ("Test IP flows separation and packet limit")
105 {
106 }
107 
109 {
110 }
111 
112 void
114 {
115  Ptr<Packet> p = Create<Packet> (100);
116  Address dest;
117  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, hdr);
118  queue->Enqueue (item);
119 }
120 
121 void
123 {
124  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("PacketLimit", UintegerValue (4));
125  Ptr<FqCoDelIpv6PacketFilter> ipv6Filter = CreateObject<FqCoDelIpv6PacketFilter> ();
126  Ptr<FqCoDelIpv4PacketFilter> ipv4Filter = CreateObject<FqCoDelIpv4PacketFilter> ();
127  queueDisc->AddPacketFilter (ipv6Filter);
128  queueDisc->AddPacketFilter (ipv4Filter);
129 
130  queueDisc->SetQuantum (1500);
131  queueDisc->Initialize ();
132 
133  Ipv4Header hdr;
134  hdr.SetPayloadSize (100);
135  hdr.SetSource (Ipv4Address ("10.10.1.1"));
136  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
137  hdr.SetProtocol (7);
138 
139  // Add three packets from the first flow
140  AddPacket (queueDisc, hdr);
141  AddPacket (queueDisc, hdr);
142  AddPacket (queueDisc, hdr);
143  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
144  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the flow queue");
145 
146  // Add two packets from the second flow
147  hdr.SetDestination (Ipv4Address ("10.10.1.7"));
148  // Add the first packet
149  AddPacket (queueDisc, hdr);
150  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 4, "unexpected number of packets in the queue disc");
151  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the flow queue");
152  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the flow queue");
153  // Add the second packet that causes two packets to be dropped from the fat flow (max backlog = 300, threshold = 150)
154  AddPacket (queueDisc, hdr);
155  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
156  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the flow queue");
157  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the flow queue");
158 
159  Simulator::Destroy ();
160 }
161 
166 {
167 public:
169  virtual ~FqCoDelQueueDiscDeficit ();
170 
171 private:
172  virtual void DoRun (void);
173  void AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr);
174 };
175 
177  : TestCase ("Test credits and flows status")
178 {
179 }
180 
182 {
183 }
184 
185 void
187 {
188  Ptr<Packet> p = Create<Packet> (100);
189  Address dest;
190  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, hdr);
191  queue->Enqueue (item);
192 }
193 
194 void
196 {
197  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ();
198  Ptr<FqCoDelIpv6PacketFilter> ipv6Filter = CreateObject<FqCoDelIpv6PacketFilter> ();
199  Ptr<FqCoDelIpv4PacketFilter> ipv4Filter = CreateObject<FqCoDelIpv4PacketFilter> ();
200  queueDisc->AddPacketFilter (ipv6Filter);
201  queueDisc->AddPacketFilter (ipv4Filter);
202 
203  queueDisc->SetQuantum (90);
204  queueDisc->Initialize ();
205 
206  Ipv4Header hdr;
207  hdr.SetPayloadSize (100);
208  hdr.SetSource (Ipv4Address ("10.10.1.1"));
209  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
210  hdr.SetProtocol (7);
211 
212  // Add a packet from the first flow
213  AddPacket (queueDisc, hdr);
214  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 1, "unexpected number of packets in the queue disc");
215  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the first flow queue");
216  Ptr<FqCoDelFlow> flow1 = StaticCast<FqCoDelFlow> (queueDisc->GetQueueDiscClass (0));
217  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), static_cast<int32_t> (queueDisc->GetQuantum ()), "the deficit of the first flow must equal the quantum");
218  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::NEW_FLOW, "the first flow must be in the list of new queues");
219  // Dequeue a packet
220  queueDisc->Dequeue ();
221  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 0, "unexpected number of packets in the queue disc");
222  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 0, "unexpected number of packets in the first flow queue");
223  // the deficit for the first flow becomes 90 - (100+20) = -30
224  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), -30, "unexpected deficit for the first flow");
225 
226  // Add two packets from the first flow
227  AddPacket (queueDisc, hdr);
228  AddPacket (queueDisc, hdr);
229  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 2, "unexpected number of packets in the queue disc");
230  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the first flow queue");
231  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::NEW_FLOW, "the first flow must still be in the list of new queues");
232 
233  // Add two packets from the second flow
234  hdr.SetDestination (Ipv4Address ("10.10.1.10"));
235  AddPacket (queueDisc, hdr);
236  AddPacket (queueDisc, hdr);
237  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 4, "unexpected number of packets in the queue disc");
238  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the first flow queue");
239  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the second flow queue");
240  Ptr<FqCoDelFlow> flow2 = StaticCast<FqCoDelFlow> (queueDisc->GetQueueDiscClass (1));
241  NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), static_cast<int32_t> (queueDisc->GetQuantum ()), "the deficit of the second flow must equal the quantum");
242  NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqCoDelFlow::NEW_FLOW, "the second flow must be in the list of new queues");
243 
244  // Dequeue a packet (from the second flow, as the first flow has a negative deficit)
245  queueDisc->Dequeue ();
246  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
247  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the first flow queue");
248  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
249  // the first flow got a quantum of deficit (-30+90=60) and has been moved to the end of the list of old queues
250  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), 60, "unexpected deficit for the first flow");
251  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::OLD_FLOW, "the first flow must be in the list of old queues");
252  // the second flow has a negative deficit (-30) and is still in the list of new queues
253  NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), -30, "unexpected deficit for the second flow");
254  NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqCoDelFlow::NEW_FLOW, "the second flow must be in the list of new queues");
255 
256  // Dequeue a packet (from the first flow, as the second flow has a negative deficit)
257  queueDisc->Dequeue ();
258  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 2, "unexpected number of packets in the queue disc");
259  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the first flow queue");
260  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
261  // the first flow has a negative deficit (60-(100+20)= -60) and stays in the list of old queues
262  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), -60, "unexpected deficit for the first flow");
263  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::OLD_FLOW, "the first flow must be in the list of old queues");
264  // the second flow got a quantum of deficit (-30+90=60) and has been moved to the end of the list of old queues
265  NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), 60, "unexpected deficit for the second flow");
266  NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqCoDelFlow::OLD_FLOW, "the second flow must be in the list of new queues");
267 
268  // Dequeue a packet (from the second flow, as the first flow has a negative deficit)
269  queueDisc->Dequeue ();
270  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 1, "unexpected number of packets in the queue disc");
271  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the first flow queue");
272  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 0, "unexpected number of packets in the second flow queue");
273  // the first flow got a quantum of deficit (-60+90=30) and has been moved to the end of the list of old queues
274  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), 30, "unexpected deficit for the first flow");
275  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::OLD_FLOW, "the first flow must be in the list of old queues");
276  // the second flow has a negative deficit (60-(100+20)= -60)
277  NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), -60, "unexpected deficit for the second flow");
278  NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqCoDelFlow::OLD_FLOW, "the second flow must be in the list of new queues");
279 
280  // Dequeue a packet (from the first flow, as the second flow has a negative deficit)
281  queueDisc->Dequeue ();
282  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 0, "unexpected number of packets in the queue disc");
283  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 0, "unexpected number of packets in the first flow queue");
284  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 0, "unexpected number of packets in the second flow queue");
285  // the first flow has a negative deficit (30-(100+20)= -90)
286  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), -90, "unexpected deficit for the first flow");
287  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::OLD_FLOW, "the first flow must be in the list of old queues");
288  // the second flow got a quantum of deficit (-60+90=30) and has been moved to the end of the list of old queues
289  NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), 30, "unexpected deficit for the second flow");
290  NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqCoDelFlow::OLD_FLOW, "the second flow must be in the list of new queues");
291 
292  // Dequeue a packet
293  queueDisc->Dequeue ();
294  // the first flow is at the head of the list of old queues but has a negative deficit, thus it gets a quantun
295  // of deficit (-90+90=0) and is moved to the end of the list of old queues. Then, the second flow (which has a
296  // positive deficit) is selected, but the second flow is empty and thus it is set to inactive. The first flow is
297  // reconsidered, but it has a null deficit, hence it gets another quantum of deficit (0+90=90). Then, the first
298  // flow is reconsidered again, now it has a positive deficit and hence it is selected. But, it is empty and
299  // therefore is set to inactive, too.
300  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), 90, "unexpected deficit for the first flow");
301  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::INACTIVE, "the first flow must be inactive");
302  NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), 30, "unexpected deficit for the second flow");
303  NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqCoDelFlow::INACTIVE, "the second flow must be inactive");
304 
305  Simulator::Destroy ();
306 }
307 
312 {
313 public:
316 
317 private:
318  virtual void DoRun (void);
319  void AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header ipHdr, TcpHeader tcpHdr);
320 };
321 
323  : TestCase ("Test TCP flows separation")
324 {
325 }
326 
328 {
329 }
330 
331 void
333 {
334  Ptr<Packet> p = Create<Packet> (100);
335  p->AddHeader (tcpHdr);
336  Address dest;
337  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHdr);
338  queue->Enqueue (item);
339 }
340 
341 void
343 {
344  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("PacketLimit", UintegerValue (10));
345  Ptr<FqCoDelIpv6PacketFilter> ipv6Filter = CreateObject<FqCoDelIpv6PacketFilter> ();
346  Ptr<FqCoDelIpv4PacketFilter> ipv4Filter = CreateObject<FqCoDelIpv4PacketFilter> ();
347  queueDisc->AddPacketFilter (ipv6Filter);
348  queueDisc->AddPacketFilter (ipv4Filter);
349 
350  queueDisc->SetQuantum (1500);
351  queueDisc->Initialize ();
352 
353  Ipv4Header hdr;
354  hdr.SetPayloadSize (100);
355  hdr.SetSource (Ipv4Address ("10.10.1.1"));
356  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
357  hdr.SetProtocol (6);
358 
359  TcpHeader tcpHdr;
360  tcpHdr.SetSourcePort (7);
361  tcpHdr.SetDestinationPort (27);
362 
363  // Add three packets from the first flow
364  AddPacket (queueDisc, hdr, tcpHdr);
365  AddPacket (queueDisc, hdr, tcpHdr);
366  AddPacket (queueDisc, hdr, tcpHdr);
367  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
368  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
369 
370  // Add a packet from the second flow
371  tcpHdr.SetSourcePort (8);
372  AddPacket (queueDisc, hdr, tcpHdr);
373  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 4, "unexpected number of packets in the queue disc");
374  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
375  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
376 
377  // Add a packet from the third flow
378  tcpHdr.SetDestinationPort (28);
379  AddPacket (queueDisc, hdr, tcpHdr);
380  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 5, "unexpected number of packets in the queue disc");
381  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
382  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
383  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the third flow queue");
384 
385  // Add two packets from the fourth flow
386  tcpHdr.SetSourcePort (7);
387  AddPacket (queueDisc, hdr, tcpHdr);
388  AddPacket (queueDisc, hdr, tcpHdr);
389  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 7, "unexpected number of packets in the queue disc");
390  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
391  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
392  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the third flow queue");
393  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the third flow queue");
394 
395  Simulator::Destroy ();
396 }
397 
402 {
403 public:
406 
407 private:
408  virtual void DoRun (void);
409  void AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header ipHdr, UdpHeader udpHdr);
410 };
411 
413  : TestCase ("Test UDP flows separation")
414 {
415 }
416 
418 {
419 }
420 
421 void
423 {
424  Ptr<Packet> p = Create<Packet> (100);
425  p->AddHeader (udpHdr);
426  Address dest;
427  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHdr);
428  queue->Enqueue (item);
429 }
430 
431 void
433 {
434  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("PacketLimit", UintegerValue (10));
435  Ptr<FqCoDelIpv6PacketFilter> ipv6Filter = CreateObject<FqCoDelIpv6PacketFilter> ();
436  Ptr<FqCoDelIpv4PacketFilter> ipv4Filter = CreateObject<FqCoDelIpv4PacketFilter> ();
437  queueDisc->AddPacketFilter (ipv6Filter);
438  queueDisc->AddPacketFilter (ipv4Filter);
439 
440  queueDisc->SetQuantum (1500);
441  queueDisc->Initialize ();
442 
443  Ipv4Header hdr;
444  hdr.SetPayloadSize (100);
445  hdr.SetSource (Ipv4Address ("10.10.1.1"));
446  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
447  hdr.SetProtocol (17);
448 
449  UdpHeader udpHdr;
450  udpHdr.SetSourcePort (7);
451  udpHdr.SetDestinationPort (27);
452 
453  // Add three packets from the first flow
454  AddPacket (queueDisc, hdr, udpHdr);
455  AddPacket (queueDisc, hdr, udpHdr);
456  AddPacket (queueDisc, hdr, udpHdr);
457  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
458  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
459 
460  // Add a packet from the second flow
461  udpHdr.SetSourcePort (8);
462  AddPacket (queueDisc, hdr, udpHdr);
463  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 4, "unexpected number of packets in the queue disc");
464  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
465  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
466 
467  // Add a packet from the third flow
468  udpHdr.SetDestinationPort (28);
469  AddPacket (queueDisc, hdr, udpHdr);
470  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 5, "unexpected number of packets in the queue disc");
471  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
472  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
473  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the third flow queue");
474 
475  // Add two packets from the fourth flow
476  udpHdr.SetSourcePort (7);
477  AddPacket (queueDisc, hdr, udpHdr);
478  AddPacket (queueDisc, hdr, udpHdr);
479  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 7, "unexpected number of packets in the queue disc");
480  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
481  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
482  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the third flow queue");
483  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the third flow queue");
484 
485  Simulator::Destroy ();
486 }
487 
489 {
490 public:
492 };
493 
495  : TestSuite ("fq-codel-queue-disc", UNIT)
496 {
497  AddTestCase (new FqCoDelQueueDiscNoSuitableFilter, TestCase::QUICK);
499  AddTestCase (new FqCoDelQueueDiscDeficit, TestCase::QUICK);
500  AddTestCase (new FqCoDelQueueDiscTCPFlowsSeparation, TestCase::QUICK);
501  AddTestCase (new FqCoDelQueueDiscUDPFlowsSeparation, TestCase::QUICK);
502 }
503 
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:285
void SetPayloadSize(uint16_t size)
Definition: ipv4-header.cc:56
virtual void DoRun(void)
Implementation to actually run this TestCase.
Packet header for IPv6.
Definition: ipv6-header.h:34
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:298
uint32_t GetNQueueDiscClasses(void) const
Get the number of queue disc classes.
Definition: queue-disc.cc:379
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
bool Enqueue(Ptr< QueueDiscItem > item)
Pass a packet to store to the queue discipline.
Definition: queue-disc.cc:451
virtual void DoRun(void)
Implementation to actually run this TestCase.
A suite of tests to run.
Definition: test.h:1333
void SetDestinationPort(uint16_t port)
Definition: udp-header.cc:55
void SetSourcePort(uint16_t port)
Definition: udp-header.cc:60
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:278
encapsulates test code
Definition: test.h:1147
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr)
a polymophic address class
Definition: address.h:90
This class tests the TCP flows separation.
Packet header for IPv4.
Definition: ipv4-header.h:33
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:298
Hold an unsigned integer type.
Definition: uinteger.h:44
#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:161
This class tests packets for which there is no suitable filter.
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header ipHdr, TcpHeader tcpHdr)
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header ipHdr, UdpHeader udpHdr)
virtual void DoRun(void)
Implementation to actually run this TestCase.
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr)
virtual void DoRun(void)
Implementation to actually run this TestCase.
void SetDestinationPort(uint16_t port)
Set the destination port.
Definition: tcp-header.cc:95
Ptr< QueueDiscItem > Dequeue(void)
Request the queue discipline to extract a packet.
Definition: queue-disc.cc:467
uint32_t GetQuantum(void) const
Get the quantum value.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetQuantum(uint32_t quantum)
Set the quantum value.
Header for the Transmission Control Protocol.
Definition: tcp-header.h:44
This class tests the UDP flows separation.
void SetSourcePort(uint16_t port)
Set the source port.
Definition: tcp-header.cc:89
Packet header for UDP packets.
Definition: udp-header.h:39
static FqCoDelQueueDiscTestSuite fqCoDelQueueDiscTestSuite
This class tests the IP flows separation and the packet limit.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
This class tests the deficit per flow.
void AddPacketFilter(Ptr< PacketFilter > filter)
Add a packet filter to the tail of the list of filters used to classify packets.
Definition: queue-disc.cc:337
void Initialize(void)
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:183
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:257
Ptr< QueueDiscClass > GetQueueDiscClass(uint32_t i) const
Get the i-th queue disc class.
Definition: queue-disc.cc:372