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/simulator.h"
22 #include "ns3/pfifo-fast-queue-disc.h"
23 #include "ns3/drop-tail-queue.h"
24 #include "ns3/ipv4-queue-disc-item.h"
25 #include "ns3/ipv6-queue-disc-item.h"
26 #include "ns3/enum.h"
27 #include "ns3/string.h"
28 #include "ns3/pointer.h"
29 #include "ns3/object-factory.h"
30 #include "ns3/socket.h"
31 
32 using namespace ns3;
33 
40 {
41 public:
44 
45 private:
46  virtual void DoRun (void);
54  void TestTosValue (Ptr<PfifoFastQueueDisc> queue, uint8_t tos, uint32_t band);
55 };
56 
58  : TestCase ("Test TOS-based prioritization")
59 {
60 }
61 
63 {
64 }
65 
66 void
68 {
69  Ptr<Packet> p = Create<Packet> (100);
70  Ipv4Header ipHeader;
71  ipHeader.SetPayloadSize (100);
72  ipHeader.SetTos (tos);
73  ipHeader.SetProtocol (6);
74  SocketPriorityTag priorityTag;
75  priorityTag.SetPriority (Socket::IpTos2Priority (tos));
76  p->AddPacketTag (priorityTag);
77  Address dest;
78  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHeader);
79  queue->Enqueue (item);
80  NS_TEST_ASSERT_MSG_EQ (queue->GetInternalQueue (band)->GetNPackets (), 1, "enqueued to unexpected band");
81  queue->Dequeue ();
82  NS_TEST_ASSERT_MSG_EQ (queue->GetInternalQueue (band)->GetNPackets (), 0, "unable to dequeue");
83 }
84 
85 void
87 {
88  Ptr<PfifoFastQueueDisc> queueDisc = CreateObject<PfifoFastQueueDisc> ();
89  for (uint16_t i = 0; i < 3; i++)
90  {
91  Ptr<DropTailQueue<QueueDiscItem> > queue = CreateObject<DropTailQueue<QueueDiscItem> > ();
92  bool ok = queue->SetAttributeFailSafe ("MaxSize", StringValue ("1000p"));
93  NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute");
94  queueDisc->AddInternalQueue (queue);
95  }
96  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (0)->GetNPackets (), 0, "initialized non-zero");
97  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 0, "initialized non-zero");
98  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (2)->GetNPackets (), 0, "initialized non-zero");
99 
100  // Service name priority band
101  TestTosValue (queueDisc, 0x00, 1); // Normal service -> Best Effort (0) -> 1
102  TestTosValue (queueDisc, 0x02, 1); // MMC -> Best Effort (0) -> 1
103  TestTosValue (queueDisc, 0x04, 1); // MR -> Best Effort (0) -> 1
104  TestTosValue (queueDisc, 0x06, 1); // MMC+MR -> Best Effort (0) -> 1
105  TestTosValue (queueDisc, 0x08, 2); // Max. Throughput -> Bulk (2) -> 2
106  TestTosValue (queueDisc, 0x0a, 2); // MMC+MT -> Bulk (2) -> 2
107  TestTosValue (queueDisc, 0x0c, 2); // MR+MT -> Bulk (2) -> 2
108  TestTosValue (queueDisc, 0x0e, 2); // MMC+MR+MT -> Bulk (2) -> 2
109  TestTosValue (queueDisc, 0x10, 0); // Minimize Delay -> Interactive (6) -> 0
110  TestTosValue (queueDisc, 0x12, 0); // MMC+MD -> Interactive (6) -> 0
111  TestTosValue (queueDisc, 0x14, 0); // MR+MD -> Interactive (6) -> 0
112  TestTosValue (queueDisc, 0x16, 0); // MMC+MR+MD -> Interactive (6) -> 0
113  TestTosValue (queueDisc, 0x18, 1); // MT+MD -> Int. Bulk (4) -> 1
114  TestTosValue (queueDisc, 0x1a, 1); // MMC+MT+MD -> Int. Bulk (4) -> 1
115  TestTosValue (queueDisc, 0x1c, 1); // MR+MT+MD -> Int. Bulk (4) -> 1
116  TestTosValue (queueDisc, 0x1e, 1); // MMC+MR+MT+MD -> Int. Bulk (4) -> 1
117  Simulator::Destroy ();
118 }
119 
126 {
127 public:
130 
131 private:
132  virtual void DoRun (void);
140  void TestDscpValue (Ptr<PfifoFastQueueDisc> queue, Ipv4Header::DscpType dscp, uint32_t band);
141 };
142 
144  : TestCase ("Test DSCP-based prioritization")
145 {
146 }
147 
149 {
150 }
151 
152 void
154 {
155  Ptr<Packet> p = Create<Packet> (100);
156  Ipv4Header ipHeader;
157  ipHeader.SetPayloadSize (100);
158  ipHeader.SetProtocol (6);
159  ipHeader.SetDscp (dscp);
160  SocketPriorityTag priorityTag;
161  priorityTag.SetPriority (Socket::IpTos2Priority (ipHeader.GetTos ()));
162  p->AddPacketTag (priorityTag);
163  Address dest;
164  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHeader);
165  queue->Enqueue (item);
166  NS_TEST_ASSERT_MSG_EQ (queue->GetInternalQueue (band)->GetNPackets (), 1, "enqueued to unexpected band");
167  queue->Dequeue ();
168  NS_TEST_ASSERT_MSG_EQ (queue->GetInternalQueue (band)->GetNPackets (), 0, "unable to dequeue");
169 }
170 
171 void
173 {
174  Ptr<PfifoFastQueueDisc> queueDisc = CreateObject<PfifoFastQueueDisc> ();
175  for (uint16_t i = 0; i < 3; i++)
176  {
177  Ptr<DropTailQueue<QueueDiscItem> > queue = CreateObject<DropTailQueue<QueueDiscItem> > ();
178  bool ok = queue->SetAttributeFailSafe ("MaxSize", StringValue ("1000p"));
179  NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute");
180  queueDisc->AddInternalQueue (queue);
181  }
182  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (0)->GetNPackets (), 0, "initialized non-zero");
183  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 0, "initialized non-zero");
184  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (2)->GetNPackets (), 0, "initialized non-zero");
185 
186  // priority band
187  TestDscpValue (queueDisc, Ipv4Header::DscpDefault, 1); // Best Effort (0) -> 1
188  TestDscpValue (queueDisc, Ipv4Header::DSCP_EF, 1); // Int. Bulk (4) -> 1
189  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF11, 2); // Bulk (2) -> 2
190  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF21, 2); // Bulk (2) -> 2
191  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF31, 2); // Bulk (2) -> 2
192  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF41, 2); // Bulk (2) -> 2
193  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF12, 0); // Interactive (6) -> 0
194  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF22, 0); // Interactive (6) -> 0
195  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF32, 0); // Interactive (6) -> 0
196  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF42, 0); // Interactive (6) -> 0
197  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF13, 1); // Int. Bulk (4) -> 1
198  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF23, 1); // Int. Bulk (4) -> 1
199  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF33, 1); // Int. Bulk (4) -> 1
200  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF43, 1); // Int. Bulk (4) -> 1
201  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS1, 1); // Best Effort (0) -> 1
202  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS2, 1); // Best Effort (0) -> 1
203  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS3, 1); // Best Effort (0) -> 1
204  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS4, 1); // Best Effort (0) -> 1
205  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS5, 1); // Best Effort (0) -> 1
206  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS6, 1); // Best Effort (0) -> 1
207  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS7, 1); // Best Effort (0) -> 1
208  Simulator::Destroy ();
209 }
210 
217 {
218 public:
220  virtual ~PfifoFastQueueDiscOverflow ();
221 
222 private:
223  virtual void DoRun (void);
231 };
232 
234  : TestCase ("Test queue overflow")
235 {
236 }
237 
239 {
240 }
241 
242 void
244 {
245  Ptr<Packet> p = Create<Packet> (100);
246  Ipv4Header ipHeader;
247  ipHeader.SetPayloadSize (100);
248  ipHeader.SetProtocol (6);
249  ipHeader.SetDscp (dscp);
250  SocketPriorityTag priorityTag;
251  priorityTag.SetPriority (Socket::IpTos2Priority (ipHeader.GetTos ()));
252  p->AddPacketTag (priorityTag);
253  Address dest;
254  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHeader);
255  queue->Enqueue (item);
256 }
257 
258 void
260 {
261  Ptr<PfifoFastQueueDisc> queueDisc = CreateObjectWithAttributes<PfifoFastQueueDisc> ("MaxSize", StringValue ("6p"));
262  Ptr<DropTailQueue<QueueDiscItem> > band0 = CreateObjectWithAttributes<DropTailQueue<QueueDiscItem> > ("MaxSize", StringValue ("6p"));
263  Ptr<DropTailQueue<QueueDiscItem> > band1 = CreateObjectWithAttributes<DropTailQueue<QueueDiscItem> > ("MaxSize", StringValue ("6p"));
264  Ptr<DropTailQueue<QueueDiscItem> > band2 = CreateObjectWithAttributes<DropTailQueue<QueueDiscItem> > ("MaxSize", StringValue ("6p"));
265  queueDisc->AddInternalQueue (band0);
266  queueDisc->AddInternalQueue (band1);
267  queueDisc->AddInternalQueue (band2);
268 
269  // Add two packets per each band
270  AddPacket (queueDisc, Ipv4Header::DSCP_AF42); // 0
271  AddPacket (queueDisc, Ipv4Header::DSCP_AF42); // 0
272  AddPacket (queueDisc, Ipv4Header::DSCP_AF13); // 1
273  AddPacket (queueDisc, Ipv4Header::DSCP_AF13); // 1
274  AddPacket (queueDisc, Ipv4Header::DSCP_AF11); // 2
275  AddPacket (queueDisc, Ipv4Header::DSCP_AF11); // 2
276  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (0)->GetNPackets (), 2, "unexpected queue depth");
277  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 2, "unexpected queue depth");
278  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (2)->GetNPackets (), 2, "unexpected queue depth");
279  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 6, "unexpected queue depth");
280  // Add a third packet to each band
281  AddPacket (queueDisc, Ipv4Header::DSCP_AF42); // 0
282  AddPacket (queueDisc, Ipv4Header::DSCP_AF13); // 1
283  AddPacket (queueDisc, Ipv4Header::DSCP_AF11); // 2
284  // Bands should still have two packets each
285  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (0)->GetNPackets (), 2, "unexpected queue depth");
286  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 2, "unexpected queue depth");
287  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (2)->GetNPackets (), 2, "unexpected queue depth");
288  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 6, "unexpected queue depth");
289  Simulator::Destroy ();
290 }
291 
299 {
300 public:
303 
304 private:
305  virtual void DoRun (void);
306 };
307 
309  : TestCase ("Test queue with no priority tag")
310 {
311 }
312 
314 {
315 }
316 
317 void
319 {
320  // all packets with non-IP headers should enqueue in band 1
321  Ptr<PfifoFastQueueDisc> queueDisc = CreateObject<PfifoFastQueueDisc> ();
322  for (uint16_t i = 0; i < 3; i++)
323  {
324  Ptr<DropTailQueue<QueueDiscItem> > queue = CreateObject<DropTailQueue<QueueDiscItem> > ();
325  bool ok = queue->SetAttributeFailSafe ("MaxSize", StringValue ("1000p"));
326  NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute");
327  queueDisc->AddInternalQueue (queue);
328  }
329  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 0, "unexpected queue depth");
330  Ptr<Packet> p;
331  p = Create<Packet> ();
333  Ipv6Header ipv6Header;
334  Address dest;
335  item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
336  queueDisc->Enqueue (item);
337  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 1, "unexpected queue depth");
338  p = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello, world"), 12);
339  item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
340  queueDisc->Enqueue (item);
341  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 2, "unexpected queue depth");
342  p = Create<Packet> (100);
343  uint8_t *buf = new uint8_t[100];
344  uint8_t counter = 0;
345  for (uint32_t i = 0; i < 100; i++)
346  {
347  buf[i] = counter++;
348  }
349  p->CopyData (buf, 100);
350  item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
351  queueDisc->Enqueue (item);
352  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 3, "unexpected queue depth");
353  delete[] buf;
354  Simulator::Destroy ();
355 }
356 
363 {
364 public:
366 };
367 
369  : TestSuite ("pfifo-fast-queue-disc", UNIT)
370 {
371  AddTestCase (new PfifoFastQueueDiscTosPrioritization, TestCase::QUICK);
372  AddTestCase (new PfifoFastQueueDiscDscpPrioritization, TestCase::QUICK);
373  AddTestCase (new PfifoFastQueueDiscOverflow, TestCase::QUICK);
374  AddTestCase (new PfifoFastQueueDiscNoPriority, TestCase::QUICK);
375 }
376 
This class tests that each possible DSCP is enqueued in the right band.
void TestDscpValue(Ptr< PfifoFastQueueDisc > queue, Ipv4Header::DscpType dscp, uint32_t band)
Enqueue a packet and checks that it's added to the proper band.
virtual void DoRun(void)
Implementation to actually run this TestCase.
This class tests that packets without a priority tag are handled by placing them into band 1.
virtual void DoRun(void)
Implementation to actually run this TestCase.
This class tests that each band is txqueuelen deep.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void AddPacket(Ptr< PfifoFastQueueDisc > queue, Ipv4Header::DscpType dscp)
Enqueue a packet.
PfifoFast queue disc test suite.
This class tests that each possible TOS is enqueued in the right band.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void TestTosValue(Ptr< PfifoFastQueueDisc > queue, uint8_t tos, uint32_t band)
Enqueue a packet and checks that it's added to the proper band.
a polymophic address class
Definition: address.h:91
Packet header for IPv4.
Definition: ipv4-header.h:34
void SetPayloadSize(uint16_t size)
Definition: ipv4-header.cc:56
uint8_t GetTos(void) const
Definition: ipv4-header.cc:194
void SetDscp(DscpType dscp)
Set DSCP Field.
Definition: ipv4-header.cc:89
DscpType
DiffServ codepoints.
Definition: ipv4-header.h:71
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:278
void SetTos(uint8_t tos)
Definition: ipv4-header.cc:82
Packet header for IPv6.
Definition: ipv6-header.h:36
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:378
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:956
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
indicates whether the socket has a priority set.
Definition: socket.h:1309
void SetPriority(uint8_t priority)
Set the tag's priority.
Definition: socket.cc:842
Hold variables of type string.
Definition: string.h:41
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
#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
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static PfifoFastQueueDiscTestSuite g_pfifoFastQueueTestSuite
Do not forget to allocate an instance of this TestSuite.