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/enum.h"
26 #include "ns3/uinteger.h"
27 #include "ns3/pointer.h"
28 #include "ns3/object-factory.h"
29 #include "ns3/socket.h"
30 
31 using namespace ns3;
32 
37 {
38 public:
41 
42 private:
43  virtual void DoRun (void);
44  void TestTosValue (Ptr<PfifoFastQueueDisc> queue, uint8_t tos, uint32_t band);
45 };
46 
48  : TestCase ("Test TOS-based prioritization")
49 {
50 }
51 
53 {
54 }
55 
56 void
58 {
59  Ptr<Packet> p = Create<Packet> (100);
60  Ipv4Header ipHeader;
61  ipHeader.SetPayloadSize (100);
62  ipHeader.SetTos (tos);
63  ipHeader.SetProtocol (6);
64  SocketPriorityTag priorityTag;
65  priorityTag.SetPriority (Socket::IpTos2Priority (tos));
66  p->AddPacketTag (priorityTag);
67  Address dest;
68  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHeader);
69  queue->Enqueue (item);
70  NS_TEST_ASSERT_MSG_EQ (queue->GetInternalQueue (band)->GetNPackets (), 1, "enqueued to unexpected band");
71  queue->Dequeue ();
72  NS_TEST_ASSERT_MSG_EQ (queue->GetInternalQueue (band)->GetNPackets (), 0, "unable to dequeue");
73 }
74 
75 void
77 {
78  Ptr<PfifoFastQueueDisc> queueDisc = CreateObject<PfifoFastQueueDisc> ();
79  for (uint16_t i = 0; i < 3; i++)
80  {
81  Ptr<DropTailQueue> queue = CreateObject<DropTailQueue> ();
82  bool ok = queue->SetAttributeFailSafe ("MaxPackets", UintegerValue (1000));
83  NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute");
84  queueDisc->AddInternalQueue (queue);
85  }
86  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (0)->GetNPackets (), 0, "initialized non-zero");
87  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 0, "initialized non-zero");
88  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (2)->GetNPackets (), 0, "initialized non-zero");
89 
90  // Service name priority band
91  TestTosValue (queueDisc, 0x00, 1); // Normal service -> Best Effort (0) -> 1
92  TestTosValue (queueDisc, 0x02, 1); // MMC -> Best Effort (0) -> 1
93  TestTosValue (queueDisc, 0x04, 1); // MR -> Best Effort (0) -> 1
94  TestTosValue (queueDisc, 0x06, 1); // MMC+MR -> Best Effort (0) -> 1
95  TestTosValue (queueDisc, 0x08, 2); // Max. Throughput -> Bulk (2) -> 2
96  TestTosValue (queueDisc, 0x0a, 2); // MMC+MT -> Bulk (2) -> 2
97  TestTosValue (queueDisc, 0x0c, 2); // MR+MT -> Bulk (2) -> 2
98  TestTosValue (queueDisc, 0x0e, 2); // MMC+MR+MT -> Bulk (2) -> 2
99  TestTosValue (queueDisc, 0x10, 0); // Minimize Delay -> Interactive (6) -> 0
100  TestTosValue (queueDisc, 0x12, 0); // MMC+MD -> Interactive (6) -> 0
101  TestTosValue (queueDisc, 0x14, 0); // MR+MD -> Interactive (6) -> 0
102  TestTosValue (queueDisc, 0x16, 0); // MMC+MR+MD -> Interactive (6) -> 0
103  TestTosValue (queueDisc, 0x18, 1); // MT+MD -> Int. Bulk (4) -> 1
104  TestTosValue (queueDisc, 0x1a, 1); // MMC+MT+MD -> Int. Bulk (4) -> 1
105  TestTosValue (queueDisc, 0x1c, 1); // MR+MT+MD -> Int. Bulk (4) -> 1
106  TestTosValue (queueDisc, 0x1e, 1); // MMC+MR+MT+MD -> Int. Bulk (4) -> 1
107 }
108 
113 {
114 public:
117 
118 private:
119  virtual void DoRun (void);
120  void TestDscpValue (Ptr<PfifoFastQueueDisc> queue, Ipv4Header::DscpType dscp, uint32_t band);
121 };
122 
124  : TestCase ("Test DSCP-based prioritization")
125 {
126 }
127 
129 {
130 }
131 
132 void
134 {
135  Ptr<Packet> p = Create<Packet> (100);
136  Ipv4Header ipHeader;
137  ipHeader.SetPayloadSize (100);
138  ipHeader.SetProtocol (6);
139  ipHeader.SetDscp (dscp);
140  SocketPriorityTag priorityTag;
141  priorityTag.SetPriority (Socket::IpTos2Priority (ipHeader.GetTos ()));
142  p->AddPacketTag (priorityTag);
143  Address dest;
144  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHeader);
145  queue->Enqueue (item);
146  NS_TEST_ASSERT_MSG_EQ (queue->GetInternalQueue (band)->GetNPackets (), 1, "enqueued to unexpected band");
147  queue->Dequeue ();
148  NS_TEST_ASSERT_MSG_EQ (queue->GetInternalQueue (band)->GetNPackets (), 0, "unable to dequeue");
149 }
150 
151 void
153 {
154  Ptr<PfifoFastQueueDisc> queueDisc = CreateObject<PfifoFastQueueDisc> ();
155  for (uint16_t i = 0; i < 3; i++)
156  {
157  Ptr<DropTailQueue> queue = CreateObject<DropTailQueue> ();
158  bool ok = queue->SetAttributeFailSafe ("MaxPackets", UintegerValue (1000));
159  NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute");
160  queueDisc->AddInternalQueue (queue);
161  }
162  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (0)->GetNPackets (), 0, "initialized non-zero");
163  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 0, "initialized non-zero");
164  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (2)->GetNPackets (), 0, "initialized non-zero");
165 
166  // priority band
167  TestDscpValue (queueDisc, Ipv4Header::DscpDefault, 1); // Best Effort (0) -> 1
168  TestDscpValue (queueDisc, Ipv4Header::DSCP_EF, 1); // Int. Bulk (4) -> 1
169  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF11, 2); // Bulk (2) -> 2
170  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF21, 2); // Bulk (2) -> 2
171  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF31, 2); // Bulk (2) -> 2
172  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF41, 2); // Bulk (2) -> 2
173  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF12, 0); // Interactive (6) -> 0
174  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF22, 0); // Interactive (6) -> 0
175  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF32, 0); // Interactive (6) -> 0
176  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF42, 0); // Interactive (6) -> 0
177  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF13, 1); // Int. Bulk (4) -> 1
178  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF23, 1); // Int. Bulk (4) -> 1
179  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF33, 1); // Int. Bulk (4) -> 1
180  TestDscpValue (queueDisc, Ipv4Header::DSCP_AF43, 1); // Int. Bulk (4) -> 1
181  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS1, 1); // Best Effort (0) -> 1
182  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS2, 1); // Best Effort (0) -> 1
183  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS3, 1); // Best Effort (0) -> 1
184  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS4, 1); // Best Effort (0) -> 1
185  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS5, 1); // Best Effort (0) -> 1
186  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS6, 1); // Best Effort (0) -> 1
187  TestDscpValue (queueDisc, Ipv4Header::DSCP_CS7, 1); // Best Effort (0) -> 1
188 }
189 
194 {
195 public:
197  virtual ~PfifoFastQueueDiscOverflow ();
198 
199 private:
200  virtual void DoRun (void);
202 };
203 
205  : TestCase ("Test queue overflow")
206 {
207 }
208 
210 {
211 }
212 
213 void
215 {
216  Ptr<Packet> p = Create<Packet> (100);
217  Ipv4Header ipHeader;
218  ipHeader.SetPayloadSize (100);
219  ipHeader.SetProtocol (6);
220  ipHeader.SetDscp (dscp);
221  SocketPriorityTag priorityTag;
222  priorityTag.SetPriority (Socket::IpTos2Priority (ipHeader.GetTos ()));
223  p->AddPacketTag (priorityTag);
224  Address dest;
225  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHeader);
226  queue->Enqueue (item);
227 }
228 
229 void
231 {
232  Ptr<PfifoFastQueueDisc> queueDisc = CreateObjectWithAttributes<PfifoFastQueueDisc> ("Limit", UintegerValue (6));
233  Ptr<DropTailQueue> band0 = CreateObjectWithAttributes<DropTailQueue> ("MaxPackets", UintegerValue (6));
234  Ptr<DropTailQueue> band1 = CreateObjectWithAttributes<DropTailQueue> ("MaxPackets", UintegerValue (6));
235  Ptr<DropTailQueue> band2 = CreateObjectWithAttributes<DropTailQueue> ("MaxPackets", UintegerValue (6));
236  queueDisc->AddInternalQueue (band0);
237  queueDisc->AddInternalQueue (band1);
238  queueDisc->AddInternalQueue (band2);
239 
240  // Add two packets per each band
241  AddPacket (queueDisc, Ipv4Header::DSCP_AF42); // 0
242  AddPacket (queueDisc, Ipv4Header::DSCP_AF42); // 0
243  AddPacket (queueDisc, Ipv4Header::DSCP_AF13); // 1
244  AddPacket (queueDisc, Ipv4Header::DSCP_AF13); // 1
245  AddPacket (queueDisc, Ipv4Header::DSCP_AF11); // 2
246  AddPacket (queueDisc, Ipv4Header::DSCP_AF11); // 2
247  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (0)->GetNPackets (), 2, "unexpected queue depth");
248  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 2, "unexpected queue depth");
249  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (2)->GetNPackets (), 2, "unexpected queue depth");
250  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 6, "unexpected queue depth");
251  // Add a third packet to each band
252  AddPacket (queueDisc, Ipv4Header::DSCP_AF42); // 0
253  AddPacket (queueDisc, Ipv4Header::DSCP_AF13); // 1
254  AddPacket (queueDisc, Ipv4Header::DSCP_AF11); // 2
255  // Bands should still have two packets each
256  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (0)->GetNPackets (), 2, "unexpected queue depth");
257  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 2, "unexpected queue depth");
258  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (2)->GetNPackets (), 2, "unexpected queue depth");
259  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 6, "unexpected queue depth");
260 }
261 
267 {
268 public:
271 
272 private:
273  virtual void DoRun (void);
274 };
275 
277  : TestCase ("Test queue with no priority tag")
278 {
279 }
280 
282 {
283 }
284 
285 void
287 {
288  // all packets with non-IP headers should enqueue in band 1
289  Ptr<PfifoFastQueueDisc> queueDisc = CreateObject<PfifoFastQueueDisc> ();
290  for (uint16_t i = 0; i < 3; i++)
291  {
292  Ptr<DropTailQueue> queue = CreateObject<DropTailQueue> ();
293  bool ok = queue->SetAttributeFailSafe ("MaxPackets", UintegerValue (1000));
294  NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute");
295  queueDisc->AddInternalQueue (queue);
296  }
297  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 0, "unexpected queue depth");
298  Ptr<Packet> p;
299  p = Create<Packet> ();
301  Ipv6Header ipv6Header;
302  Address dest;
303  item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
304  queueDisc->Enqueue (item);
305  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 1, "unexpected queue depth");
306  p = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello, world"), 12);
307  item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
308  queueDisc->Enqueue (item);
309  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 2, "unexpected queue depth");
310  p = Create<Packet> (100);
311  uint8_t *buf = new uint8_t[100];
312  uint8_t counter = 0;
313  for (uint32_t i = 0; i < 100; i++)
314  {
315  buf[i] = counter++;
316  }
317  p->CopyData (buf, 100);
318  item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
319  queueDisc->Enqueue (item);
320  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 3, "unexpected queue depth");
321  delete[] buf;
322 }
323 
325 {
326 public:
328 };
329 
331  : TestSuite ("pfifo-fast-queue-disc", UNIT)
332 {
333  AddTestCase (new PfifoFastQueueDiscTosPrioritization, TestCase::QUICK);
334  AddTestCase (new PfifoFastQueueDiscDscpPrioritization, TestCase::QUICK);
335  AddTestCase (new PfifoFastQueueDiscOverflow, TestCase::QUICK);
336  AddTestCase (new PfifoFastQueueDiscNoPriority, TestCase::QUICK);
337 }
338 
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:451
Ptr< Queue > GetInternalQueue(uint32_t i) const
Get the i-th internal queue.
Definition: queue-disc.cc:324
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
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:824
virtual void DoRun(void)
Implementation to actually run this TestCase.
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:33
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:298
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:314
virtual void DoRun(void)
Implementation to actually run this TestCase.
indicates whether the socket has a priority set.
Definition: socket.h:1304
Ptr< QueueDiscItem > Dequeue(void)
Request the queue discipline to extract a packet.
Definition: queue-disc.cc:467
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.