A Discrete-Event Network Simulator
API
pfifo-fast-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) 2014 University of Washington
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  */
19 
20 #include "ns3/test.h"
21 #include "ns3/pfifo-fast-queue-disc.h"
22 #include "ns3/drop-tail-queue.h"
23 #include "ns3/ipv4-queue-disc-item.h"
24 #include "ns3/ipv6-queue-disc-item.h"
25 #include "ns3/ipv4-packet-filter.h"
26 #include "ns3/enum.h"
27 #include "ns3/uinteger.h"
28 #include "ns3/pointer.h"
29 #include "ns3/object-factory.h"
30 
31 using namespace ns3;
32 
37 {
38 public:
41 
42 private:
43  virtual void DoRun (void);
44  Ptr<Packet> CreatePacketWithTos (uint8_t tos);
45  void TestTosValue (Ptr<PfifoFastQueueDisc> queue, uint8_t tos, uint32_t band);
46 };
47 
49  : TestCase ("Test TOS-based prioritization")
50 {
51 }
52 
54 {
55 }
56 
59 {
60  Ptr<Packet> p = Create<Packet> (100);
61  Ipv4Header ipHeader;
62  ipHeader.SetPayloadSize (100);
63  ipHeader.SetTos (tos);
64  ipHeader.SetProtocol (6);
65  p->AddHeader (ipHeader);
66  return p;
67 }
68 
69 void
71 {
73  Ipv4Header ipHeader;
74  p->RemoveHeader (ipHeader);
75  Address dest;
76  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHeader);
77  queue->Enqueue (item);
78  NS_TEST_ASSERT_MSG_EQ (queue->GetInternalQueue (band)->GetNPackets (), 1, "enqueued to unexpected band");
79  queue->Dequeue ();
80  NS_TEST_ASSERT_MSG_EQ (queue->GetInternalQueue (band)->GetNPackets (), 0, "unable to dequeue");
81 }
82 
83 void
85 {
86  Ptr<PfifoFastQueueDisc> queueDisc = CreateObject<PfifoFastQueueDisc> ();
87  Ptr<PfifoFastIpv4PacketFilter> filter = CreateObject<PfifoFastIpv4PacketFilter> ();
88  bool ok = filter->SetAttributeFailSafe ("Mode", EnumValue (PfifoFastIpv4PacketFilter::PF_MODE_TOS));
89  NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute");
90  queueDisc->AddPacketFilter (filter);
91  for (uint16_t i = 0; i < 3; i++)
92  {
93  Ptr<DropTailQueue> queue = CreateObject<DropTailQueue> ();
94  bool ok = queue->SetAttributeFailSafe ("MaxPackets", UintegerValue (1000));
95  NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute");
96  queueDisc->AddInternalQueue (queue);
97  }
98  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (0)->GetNPackets (), 0, "initialized non-zero");
99  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 0, "initialized non-zero");
100  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (2)->GetNPackets (), 0, "initialized non-zero");
101 
102  TestTosValue (queueDisc, 0x0, 1);
103  TestTosValue (queueDisc, 0x2, 2);
104  TestTosValue (queueDisc, 0x4, 1);
105  TestTosValue (queueDisc, 0x6, 1);
106  TestTosValue (queueDisc, 0x8, 2);
107  TestTosValue (queueDisc, 0xa, 2);
108  TestTosValue (queueDisc, 0xc, 2);
109  TestTosValue (queueDisc, 0xe, 2);
110  TestTosValue (queueDisc, 0x10, 0);
111  TestTosValue (queueDisc, 0x12, 0);
112  TestTosValue (queueDisc, 0x14, 0);
113  TestTosValue (queueDisc, 0x16, 0);
114  TestTosValue (queueDisc, 0x18, 1);
115  TestTosValue (queueDisc, 0x1a, 1);
116  TestTosValue (queueDisc, 0x1c, 1);
117  TestTosValue (queueDisc, 0x1e, 1);
118 }
119 
124 {
125 public:
128 
129 private:
130  virtual void DoRun (void);
132  void TestDscpValue (Ptr<PfifoFastQueueDisc> queue, Ipv4Header::DscpType dscp, uint32_t band);
133 };
134 
136  : TestCase ("Test DSCP-based prioritization")
137 {
138 }
139 
141 {
142 }
143 
146 {
147  Ptr<Packet> p = Create<Packet> (100);
148  Ipv4Header ipHeader;
149  ipHeader.SetPayloadSize (100);
150  ipHeader.SetProtocol (6);
151  ipHeader.SetDscp (dscp);
152  p->AddHeader (ipHeader);
153  return p;
154 }
155 
156 void
158 {
160  Ipv4Header ipHeader;
161  p->RemoveHeader (ipHeader);
162  Address dest;
163  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHeader);
164  queue->Enqueue (item);
165  NS_TEST_ASSERT_MSG_EQ (queue->GetInternalQueue (band)->GetNPackets (), 1, "enqueued to unexpected band");
166  queue->Dequeue ();
167  NS_TEST_ASSERT_MSG_EQ (queue->GetInternalQueue (band)->GetNPackets (), 0, "unable to dequeue");
168 }
169 
170 void
172 {
173  Ptr<PfifoFastQueueDisc> queueDisc = CreateObject<PfifoFastQueueDisc> ();
174  Ptr<PfifoFastIpv4PacketFilter> filter = CreateObject<PfifoFastIpv4PacketFilter> ();
175  bool ok = filter->SetAttributeFailSafe ("Mode", EnumValue (PfifoFastIpv4PacketFilter::PF_MODE_DSCP));
176  NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute");
177  queueDisc->AddPacketFilter (filter);
178  for (uint16_t i = 0; i < 3; i++)
179  {
180  Ptr<DropTailQueue> queue = CreateObject<DropTailQueue> ();
181  bool ok = queue->SetAttributeFailSafe ("MaxPackets", UintegerValue (1000));
182  NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute");
183  queueDisc->AddInternalQueue (queue);
184  }
185  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (0)->GetNPackets (), 0, "initialized non-zero");
186  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 0, "initialized non-zero");
187  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (2)->GetNPackets (), 0, "initialized non-zero");
188 
189  TestDscpValue (queueDisc, Ipv4Header::DscpDefault, 1);
190  TestDscpValue (queueDisc, Ipv4Header::DSCP_EF, 1);
191  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF11, 2);
192  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF21, 2);
193  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF31, 2);
194  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF41, 2);
195  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF12, 0);
196  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF22, 0);
197  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF32, 0);
198  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF42, 0);
199  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF13, 1);
200  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF23, 1);
201  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF33, 1);
202  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF43, 1);
203  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS1, 2);
204  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS2, 1);
205  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS3, 1);
206  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS4, 0);
207  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS5, 0);
208  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS6, 0);
209  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS7, 0);
210 }
211 
216 {
217 public:
219  virtual ~PfifoFastQueueDiscOverflow ();
220 
221 private:
222  virtual void DoRun (void);
224 };
225 
227  : TestCase ("Test queue overflow")
228 {
229 }
230 
232 {
233 }
234 
235 void
237 {
238  Ptr<Packet> p = Create<Packet> (100);
239  Ipv4Header ipHeader;
240  ipHeader.SetPayloadSize (100);
241  ipHeader.SetProtocol (6);
242  ipHeader.SetDscp (dscp);
243  Address dest;
244  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHeader);
245  queue->Enqueue (item);
246 }
247 
248 void
250 {
251  Ptr<PfifoFastQueueDisc> queueDisc = CreateObjectWithAttributes<PfifoFastQueueDisc> ("Limit", UintegerValue (6));
252  Ptr<DropTailQueue> band0 = CreateObjectWithAttributes<DropTailQueue> ("MaxPackets", UintegerValue (6));
253  Ptr<DropTailQueue> band1 = CreateObjectWithAttributes<DropTailQueue> ("MaxPackets", UintegerValue (6));
254  Ptr<DropTailQueue> band2 = CreateObjectWithAttributes<DropTailQueue> ("MaxPackets", UintegerValue (6));
255  queueDisc->AddInternalQueue (band0);
256  queueDisc->AddInternalQueue (band1);
257  queueDisc->AddInternalQueue (band2);
258  Ptr<PfifoFastIpv4PacketFilter> filter = CreateObject<PfifoFastIpv4PacketFilter> ();
259  bool ok = filter->SetAttributeFailSafe ("Mode", EnumValue (PfifoFastIpv4PacketFilter::PF_MODE_DSCP));
260  NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute");
261  queueDisc->AddPacketFilter (filter);
262 
263  // Add two packets per each band
264  AddPacket (queueDisc, Ipv4Header::DSCP_AF42); // 0
265  AddPacket (queueDisc, Ipv4Header::DSCP_AF42); // 0
266  AddPacket (queueDisc, Ipv4Header::DSCP_AF13); // 1
267  AddPacket (queueDisc, Ipv4Header::DSCP_AF13); // 1
268  AddPacket (queueDisc, Ipv4Header::DSCP_AF11); // 2
269  AddPacket (queueDisc, Ipv4Header::DSCP_AF11); // 2
270  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (0)->GetNPackets (), 2, "unexpected queue depth");
271  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 2, "unexpected queue depth");
272  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (2)->GetNPackets (), 2, "unexpected queue depth");
273  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 6, "unexpected queue depth");
274  // Add a third packet to each band
275  AddPacket (queueDisc, Ipv4Header::DSCP_AF42); // 0
276  AddPacket (queueDisc, Ipv4Header::DSCP_AF13); // 1
277  AddPacket (queueDisc, Ipv4Header::DSCP_AF11); // 2
278  // Bands should still have two packets each
279  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (0)->GetNPackets (), 2, "unexpected queue depth");
280  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 2, "unexpected queue depth");
281  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (2)->GetNPackets (), 2, "unexpected queue depth");
282  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 6, "unexpected queue depth");
283 }
284 
290 {
291 public:
294 
295 private:
296  virtual void DoRun (void);
297 };
298 
300  : TestCase ("Test queue with non IP header")
301 {
302 }
303 
305 {
306 }
307 
308 void
310 {
311  // all packets with non-IP headers should enqueue in band 1
312  Ptr<PfifoFastQueueDisc> queueDisc = CreateObject<PfifoFastQueueDisc> ();
313  Ptr<PfifoFastIpv4PacketFilter> filter = CreateObject<PfifoFastIpv4PacketFilter> ();
314  queueDisc->AddPacketFilter (filter);
315  for (uint16_t i = 0; i < 3; i++)
316  {
317  Ptr<DropTailQueue> queue = CreateObject<DropTailQueue> ();
318  bool ok = queue->SetAttributeFailSafe ("MaxPackets", UintegerValue (1000));
319  NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute");
320  queueDisc->AddInternalQueue (queue);
321  }
322  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 0, "unexpected queue depth");
323  Ptr<Packet> p;
324  p = Create<Packet> ();
326  Ipv6Header ipv6Header;
327  Address dest;
328  item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
329  queueDisc->Enqueue (item);
330  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 1, "unexpected queue depth");
331  p = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello, world"), 12);
332  item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
333  queueDisc->Enqueue (item);
334  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 2, "unexpected queue depth");
335  p = Create<Packet> (100);
336  uint8_t *buf = new uint8_t[100];
337  uint8_t counter = 0;
338  for (uint32_t i = 0; i < 100; i++)
339  {
340  buf[i] = counter++;
341  }
342  p->CopyData (buf, 100);
343  item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
344  queueDisc->Enqueue (item);
345  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 3, "unexpected queue depth");
346  delete[] buf;
347 }
348 
350 {
351 public:
353 };
354 
356  : TestSuite ("pfifo-fast-queue-disc", UNIT)
357 {
358  AddTestCase (new PfifoFastQueueDiscTosPrioritization, TestCase::QUICK);
359  AddTestCase (new PfifoFastQueueDiscDscpPrioritization, TestCase::QUICK);
360  AddTestCase (new PfifoFastQueueDiscOverflow, TestCase::QUICK);
361  AddTestCase (new PfifoFastQueueDiscNonIpHeader, TestCase::QUICK);
362 }
363 
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
void SetPayloadSize(uint16_t size)
Definition: ipv4-header.cc:56
Introspection did not find any typical Config paths.
Definition: ipv6-header.h:33
bool Enqueue(Ptr< QueueDiscItem > item)
Pass a packet to store to the queue discipline.
Definition: queue-disc.cc:411
This class tests that non-IP packets are handled by placing them into band 1.
Ptr< Queue > GetInternalQueue(uint32_t i) const
Get the i-th internal queue.
Definition: queue-disc.cc:319
DscpType
DiffServ Code Points Code Points defined in Assured Forwarding (AF) RFC 2597 Expedited Forwarding (EF...
Definition: ipv4-header.h:65
This class tests that each possible TOS is enqueued in the right band.
void TestTosValue(Ptr< PfifoFastQueueDisc > queue, uint8_t tos, uint32_t band)
virtual void DoRun(void)
Implementation to actually run this TestCase.
A suite of tests to run.
Definition: test.h:1333
bool SetAttributeFailSafe(std::string name, const AttributeValue &value)
Set a single attribute without raising errors.
Definition: object-base.cc:211
encapsulates test code
Definition: test.h:1147
a polymophic address class
Definition: address.h:90
This class tests that each band is txqueuelen deep.
Packet header for IPv4.
Definition: ipv4-header.h:31
Hold variables of type enum.
Definition: enum.h:54
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:297
void TestDscpValue(Ptr< PfifoFastQueueDisc > queue, Ipv4Header::DscpType dscp, uint32_t band)
Hold an unsigned integer type.
Definition: uinteger.h:44
void AddPacket(Ptr< PfifoFastQueueDisc > queue, Ipv4Header::DscpType dscp)
#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
void AddInternalQueue(Ptr< Queue > queue)
Add an internal queue to the tail of the list of queues.
Definition: queue-disc.cc:312
virtual void DoRun(void)
Implementation to actually run this TestCase.
Ptr< Packet > CreatePacketWithDscp(Ipv4Header::DscpType dscp)
Ptr< QueueDiscItem > Dequeue(void)
Request the queue discipline to extract a packet.
Definition: queue-disc.cc:427
Every class exported by the ns3 library is enclosed in the ns3 namespace.
virtual void DoRun(void)
Implementation to actually run this TestCase.
static PfifoFastQueueDiscTestSuite pfifoFastQueueTestSuite
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:332
This class tests that each possible DSCP is enqueued in the right band.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:257
virtual void DoRun(void)
Implementation to actually run this TestCase.