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 
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 ("MaxSize", StringValue ("1000p"));
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 ("MaxSize", StringValue ("1000p"));
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> ("MaxSize", StringValue ("6p"));
236  Ptr<DropTailQueue<QueueDiscItem> > band0 = CreateObjectWithAttributes<DropTailQueue<QueueDiscItem> > ("MaxSize", StringValue ("6p"));
237  Ptr<DropTailQueue<QueueDiscItem> > band1 = CreateObjectWithAttributes<DropTailQueue<QueueDiscItem> > ("MaxSize", StringValue ("6p"));
238  Ptr<DropTailQueue<QueueDiscItem> > band2 = CreateObjectWithAttributes<DropTailQueue<QueueDiscItem> > ("MaxSize", StringValue ("6p"));
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 ("MaxSize", StringValue ("1000p"));
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 
This class tests that each possible DSCP is enqueued in the right band.
void TestDscpValue(Ptr< PfifoFastQueueDisc > queue, Ipv4Header::DscpType dscp, uint32_t 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)
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)
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:35
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:1154
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:1344
#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:166
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static PfifoFastQueueDiscTestSuite pfifoFastQueueTestSuite