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/uinteger.h"
28 #include "ns3/pointer.h"
29 #include "ns3/object-factory.h"
30 #include "ns3/socket.h"
31 
32 using namespace ns3;
33 
38 {
39 public:
42 
43 private:
44  virtual void DoRun (void);
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 
57 void
59 {
60  Ptr<Packet> p = Create<Packet> (100);
61  Ipv4Header ipHeader;
62  ipHeader.SetPayloadSize (100);
63  ipHeader.SetTos (tos);
64  ipHeader.SetProtocol (6);
65  SocketPriorityTag priorityTag;
66  priorityTag.SetPriority (Socket::IpTos2Priority (tos));
67  p->AddPacketTag (priorityTag);
68  Address dest;
69  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHeader);
70  queue->Enqueue (item);
71  NS_TEST_ASSERT_MSG_EQ (queue->GetInternalQueue (band)->GetNPackets (), 1, "enqueued to unexpected band");
72  queue->Dequeue ();
73  NS_TEST_ASSERT_MSG_EQ (queue->GetInternalQueue (band)->GetNPackets (), 0, "unable to dequeue");
74 }
75 
76 void
78 {
79  Ptr<PfifoFastQueueDisc> queueDisc = CreateObject<PfifoFastQueueDisc> ();
80  for (uint16_t i = 0; i < 3; i++)
81  {
82  Ptr<DropTailQueue<QueueDiscItem> > queue = CreateObject<DropTailQueue<QueueDiscItem> > ();
83  bool ok = queue->SetAttributeFailSafe ("MaxPackets", UintegerValue (1000));
84  NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute");
85  queueDisc->AddInternalQueue (queue);
86  }
87  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (0)->GetNPackets (), 0, "initialized non-zero");
88  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 0, "initialized non-zero");
89  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (2)->GetNPackets (), 0, "initialized non-zero");
90 
91  // Service name priority band
92  TestTosValue (queueDisc, 0x00, 1); // Normal service -> Best Effort (0) -> 1
93  TestTosValue (queueDisc, 0x02, 1); // MMC -> Best Effort (0) -> 1
94  TestTosValue (queueDisc, 0x04, 1); // MR -> Best Effort (0) -> 1
95  TestTosValue (queueDisc, 0x06, 1); // MMC+MR -> Best Effort (0) -> 1
96  TestTosValue (queueDisc, 0x08, 2); // Max. Throughput -> Bulk (2) -> 2
97  TestTosValue (queueDisc, 0x0a, 2); // MMC+MT -> Bulk (2) -> 2
98  TestTosValue (queueDisc, 0x0c, 2); // MR+MT -> Bulk (2) -> 2
99  TestTosValue (queueDisc, 0x0e, 2); // MMC+MR+MT -> Bulk (2) -> 2
100  TestTosValue (queueDisc, 0x10, 0); // Minimize Delay -> Interactive (6) -> 0
101  TestTosValue (queueDisc, 0x12, 0); // MMC+MD -> Interactive (6) -> 0
102  TestTosValue (queueDisc, 0x14, 0); // MR+MD -> Interactive (6) -> 0
103  TestTosValue (queueDisc, 0x16, 0); // MMC+MR+MD -> Interactive (6) -> 0
104  TestTosValue (queueDisc, 0x18, 1); // MT+MD -> Int. Bulk (4) -> 1
105  TestTosValue (queueDisc, 0x1a, 1); // MMC+MT+MD -> Int. Bulk (4) -> 1
106  TestTosValue (queueDisc, 0x1c, 1); // MR+MT+MD -> Int. Bulk (4) -> 1
107  TestTosValue (queueDisc, 0x1e, 1); // MMC+MR+MT+MD -> Int. Bulk (4) -> 1
108  Simulator::Destroy ();
109 }
110 
115 {
116 public:
119 
120 private:
121  virtual void DoRun (void);
122  void TestDscpValue (Ptr<PfifoFastQueueDisc> queue, Ipv4Header::DscpType dscp, uint32_t band);
123 };
124 
126  : TestCase ("Test DSCP-based prioritization")
127 {
128 }
129 
131 {
132 }
133 
134 void
136 {
137  Ptr<Packet> p = Create<Packet> (100);
138  Ipv4Header ipHeader;
139  ipHeader.SetPayloadSize (100);
140  ipHeader.SetProtocol (6);
141  ipHeader.SetDscp (dscp);
142  SocketPriorityTag priorityTag;
143  priorityTag.SetPriority (Socket::IpTos2Priority (ipHeader.GetTos ()));
144  p->AddPacketTag (priorityTag);
145  Address dest;
146  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHeader);
147  queue->Enqueue (item);
148  NS_TEST_ASSERT_MSG_EQ (queue->GetInternalQueue (band)->GetNPackets (), 1, "enqueued to unexpected band");
149  queue->Dequeue ();
150  NS_TEST_ASSERT_MSG_EQ (queue->GetInternalQueue (band)->GetNPackets (), 0, "unable to dequeue");
151 }
152 
153 void
155 {
156  Ptr<PfifoFastQueueDisc> queueDisc = CreateObject<PfifoFastQueueDisc> ();
157  for (uint16_t i = 0; i < 3; i++)
158  {
159  Ptr<DropTailQueue<QueueDiscItem> > queue = CreateObject<DropTailQueue<QueueDiscItem> > ();
160  bool ok = queue->SetAttributeFailSafe ("MaxPackets", UintegerValue (1000));
161  NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute");
162  queueDisc->AddInternalQueue (queue);
163  }
164  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (0)->GetNPackets (), 0, "initialized non-zero");
165  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 0, "initialized non-zero");
166  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (2)->GetNPackets (), 0, "initialized non-zero");
167 
168  // priority band
169  TestDscpValue (queueDisc, Ipv4Header::DscpDefault, 1); // Best Effort (0) -> 1
170  TestDscpValue (queueDisc, Ipv4Header::DSCP_EF, 1); // Int. Bulk (4) -> 1
171  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF11, 2); // Bulk (2) -> 2
172  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF21, 2); // Bulk (2) -> 2
173  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF31, 2); // Bulk (2) -> 2
174  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF41, 2); // Bulk (2) -> 2
175  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF12, 0); // Interactive (6) -> 0
176  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF22, 0); // Interactive (6) -> 0
177  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF32, 0); // Interactive (6) -> 0
178  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF42, 0); // Interactive (6) -> 0
179  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF13, 1); // Int. Bulk (4) -> 1
180  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF23, 1); // Int. Bulk (4) -> 1
181  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF33, 1); // Int. Bulk (4) -> 1
182  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF43, 1); // Int. Bulk (4) -> 1
183  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS1, 1); // Best Effort (0) -> 1
184  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS2, 1); // Best Effort (0) -> 1
185  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS3, 1); // Best Effort (0) -> 1
186  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS4, 1); // Best Effort (0) -> 1
187  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS5, 1); // Best Effort (0) -> 1
188  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS6, 1); // Best Effort (0) -> 1
189  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS7, 1); // Best Effort (0) -> 1
190  Simulator::Destroy ();
191 }
192 
197 {
198 public:
200  virtual ~PfifoFastQueueDiscOverflow ();
201 
202 private:
203  virtual void DoRun (void);
205 };
206 
208  : TestCase ("Test queue overflow")
209 {
210 }
211 
213 {
214 }
215 
216 void
218 {
219  Ptr<Packet> p = Create<Packet> (100);
220  Ipv4Header ipHeader;
221  ipHeader.SetPayloadSize (100);
222  ipHeader.SetProtocol (6);
223  ipHeader.SetDscp (dscp);
224  SocketPriorityTag priorityTag;
225  priorityTag.SetPriority (Socket::IpTos2Priority (ipHeader.GetTos ()));
226  p->AddPacketTag (priorityTag);
227  Address dest;
228  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHeader);
229  queue->Enqueue (item);
230 }
231 
232 void
234 {
235  Ptr<PfifoFastQueueDisc> queueDisc = CreateObjectWithAttributes<PfifoFastQueueDisc> ("Limit", UintegerValue (6));
236  Ptr<DropTailQueue<QueueDiscItem> > band0 = CreateObjectWithAttributes<DropTailQueue<QueueDiscItem> > ("MaxPackets", UintegerValue (6));
237  Ptr<DropTailQueue<QueueDiscItem> > band1 = CreateObjectWithAttributes<DropTailQueue<QueueDiscItem> > ("MaxPackets", UintegerValue (6));
238  Ptr<DropTailQueue<QueueDiscItem> > band2 = CreateObjectWithAttributes<DropTailQueue<QueueDiscItem> > ("MaxPackets", UintegerValue (6));
239  queueDisc->AddInternalQueue (band0);
240  queueDisc->AddInternalQueue (band1);
241  queueDisc->AddInternalQueue (band2);
242 
243  // Add two packets per each band
244  AddPacket (queueDisc, Ipv4Header::DSCP_AF42); // 0
245  AddPacket (queueDisc, Ipv4Header::DSCP_AF42); // 0
246  AddPacket (queueDisc, Ipv4Header::DSCP_AF13); // 1
247  AddPacket (queueDisc, Ipv4Header::DSCP_AF13); // 1
248  AddPacket (queueDisc, Ipv4Header::DSCP_AF11); // 2
249  AddPacket (queueDisc, Ipv4Header::DSCP_AF11); // 2
250  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (0)->GetNPackets (), 2, "unexpected queue depth");
251  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 2, "unexpected queue depth");
252  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (2)->GetNPackets (), 2, "unexpected queue depth");
253  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 6, "unexpected queue depth");
254  // Add a third packet to each band
255  AddPacket (queueDisc, Ipv4Header::DSCP_AF42); // 0
256  AddPacket (queueDisc, Ipv4Header::DSCP_AF13); // 1
257  AddPacket (queueDisc, Ipv4Header::DSCP_AF11); // 2
258  // Bands should still have two packets each
259  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (0)->GetNPackets (), 2, "unexpected queue depth");
260  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 2, "unexpected queue depth");
261  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (2)->GetNPackets (), 2, "unexpected queue depth");
262  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 6, "unexpected queue depth");
263  Simulator::Destroy ();
264 }
265 
271 {
272 public:
275 
276 private:
277  virtual void DoRun (void);
278 };
279 
281  : TestCase ("Test queue with no priority tag")
282 {
283 }
284 
286 {
287 }
288 
289 void
291 {
292  // all packets with non-IP headers should enqueue in band 1
293  Ptr<PfifoFastQueueDisc> queueDisc = CreateObject<PfifoFastQueueDisc> ();
294  for (uint16_t i = 0; i < 3; i++)
295  {
296  Ptr<DropTailQueue<QueueDiscItem> > queue = CreateObject<DropTailQueue<QueueDiscItem> > ();
297  bool ok = queue->SetAttributeFailSafe ("MaxPackets", UintegerValue (1000));
298  NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute");
299  queueDisc->AddInternalQueue (queue);
300  }
301  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 0, "unexpected queue depth");
302  Ptr<Packet> p;
303  p = Create<Packet> ();
305  Ipv6Header ipv6Header;
306  Address dest;
307  item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
308  queueDisc->Enqueue (item);
309  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 1, "unexpected queue depth");
310  p = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello, world"), 12);
311  item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
312  queueDisc->Enqueue (item);
313  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 2, "unexpected queue depth");
314  p = Create<Packet> (100);
315  uint8_t *buf = new uint8_t[100];
316  uint8_t counter = 0;
317  for (uint32_t i = 0; i < 100; i++)
318  {
319  buf[i] = counter++;
320  }
321  p->CopyData (buf, 100);
322  item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
323  queueDisc->Enqueue (item);
324  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 3, "unexpected queue depth");
325  delete[] buf;
326  Simulator::Destroy ();
327 }
328 
330 {
331 public:
333 };
334 
336  : TestSuite ("pfifo-fast-queue-disc", UNIT)
337 {
338  AddTestCase (new PfifoFastQueueDiscTosPrioritization, TestCase::QUICK);
339  AddTestCase (new PfifoFastQueueDiscDscpPrioritization, TestCase::QUICK);
340  AddTestCase (new PfifoFastQueueDiscOverflow, TestCase::QUICK);
341  AddTestCase (new PfifoFastQueueDiscNoPriority, TestCase::QUICK);
342 }
343 
void SetPayloadSize(uint16_t size)
Definition: ipv4-header.cc:56
Packet header for IPv6.
Definition: ipv6-header.h:34
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:730
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:1342
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:814
virtual void DoRun(void)
Implementation to actually run this TestCase.
encapsulates test code
Definition: test.h:1155
a polymophic address class
Definition: address.h:90
Ptr< InternalQueue > GetInternalQueue(uint32_t i) const
Get the i-th internal queue.
Definition: queue-disc.cc:492
This class tests that each band is txqueuelen deep.
Packet header for IPv4.
Definition: ipv4-header.h:33
void AddInternalQueue(Ptr< InternalQueue > queue)
Add an internal queue to the tail of the list of queues.
Definition: queue-disc.cc:472
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
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:168
virtual void DoRun(void)
Implementation to actually run this TestCase.
indicates whether the socket has a priority set.
Definition: socket.h:1303
Ptr< QueueDiscItem > Dequeue(void)
Request the queue discipline to extract a packet.
Definition: queue-disc.cc:765
Every class exported by the ns3 library is enclosed in the ns3 namespace.
This class tests that packets without a priority tag are handled by placing them into band 1...
DscpType
DiffServ Code Points Code Points defined in Assured Forwarding (AF) RFC 2597 Expedited Forwarding (EF...
Definition: ipv4-header.h:67
static PfifoFastQueueDiscTestSuite pfifoFastQueueTestSuite
This class tests that each possible DSCP is enqueued in the right band.
void SetPriority(uint8_t priority)
Set the tag's priority.
Definition: socket.cc:848
virtual void DoRun(void)
Implementation to actually run this TestCase.