A Discrete-Event Network Simulator
API
pfifo-fast-queue-disc-test-suite.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 University of Washington
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  */
18 
19 #include "ns3/drop-tail-queue.h"
20 #include "ns3/enum.h"
21 #include "ns3/ipv4-queue-disc-item.h"
22 #include "ns3/ipv6-queue-disc-item.h"
23 #include "ns3/object-factory.h"
24 #include "ns3/pfifo-fast-queue-disc.h"
25 #include "ns3/pointer.h"
26 #include "ns3/simulator.h"
27 #include "ns3/socket.h"
28 #include "ns3/string.h"
29 #include "ns3/test.h"
30 
31 using namespace ns3;
32 
39 {
40  public:
43 
44  private:
45  void DoRun() override;
53  void TestTosValue(Ptr<PfifoFastQueueDisc> queue, uint8_t tos, uint32_t band);
54 };
55 
57  : TestCase("Test TOS-based prioritization")
58 {
59 }
60 
62 {
63 }
64 
65 void
67  uint8_t tos,
68  uint32_t band)
69 {
70  Ptr<Packet> p = Create<Packet>(100);
71  Ipv4Header ipHeader;
72  ipHeader.SetPayloadSize(100);
73  ipHeader.SetTos(tos);
74  ipHeader.SetProtocol(6);
75  SocketPriorityTag priorityTag;
76  priorityTag.SetPriority(Socket::IpTos2Priority(tos));
77  p->AddPacketTag(priorityTag);
78  Address dest;
79  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem>(p, dest, 0, ipHeader);
80  queue->Enqueue(item);
81  NS_TEST_ASSERT_MSG_EQ(queue->GetInternalQueue(band)->GetNPackets(),
82  1,
83  "enqueued to unexpected band");
84  queue->Dequeue();
85  NS_TEST_ASSERT_MSG_EQ(queue->GetInternalQueue(band)->GetNPackets(), 0, "unable to dequeue");
86 }
87 
88 void
90 {
91  Ptr<PfifoFastQueueDisc> queueDisc = CreateObject<PfifoFastQueueDisc>();
92  for (uint16_t i = 0; i < 3; i++)
93  {
94  Ptr<DropTailQueue<QueueDiscItem>> queue = CreateObject<DropTailQueue<QueueDiscItem>>();
95  bool ok = queue->SetAttributeFailSafe("MaxSize", StringValue("1000p"));
96  NS_TEST_ASSERT_MSG_EQ(ok, true, "unable to set attribute");
97  queueDisc->AddInternalQueue(queue);
98  }
99  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(0)->GetNPackets(), 0, "initialized non-zero");
100  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(1)->GetNPackets(), 0, "initialized non-zero");
101  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(2)->GetNPackets(), 0, "initialized non-zero");
102 
103  // Service name priority band
104  TestTosValue(queueDisc, 0x00, 1); // Normal service -> Best Effort (0) -> 1
105  TestTosValue(queueDisc, 0x02, 1); // MMC -> Best Effort (0) -> 1
106  TestTosValue(queueDisc, 0x04, 1); // MR -> Best Effort (0) -> 1
107  TestTosValue(queueDisc, 0x06, 1); // MMC+MR -> Best Effort (0) -> 1
108  TestTosValue(queueDisc, 0x08, 2); // Max. Throughput -> Bulk (2) -> 2
109  TestTosValue(queueDisc, 0x0a, 2); // MMC+MT -> Bulk (2) -> 2
110  TestTosValue(queueDisc, 0x0c, 2); // MR+MT -> Bulk (2) -> 2
111  TestTosValue(queueDisc, 0x0e, 2); // MMC+MR+MT -> Bulk (2) -> 2
112  TestTosValue(queueDisc, 0x10, 0); // Minimize Delay -> Interactive (6) -> 0
113  TestTosValue(queueDisc, 0x12, 0); // MMC+MD -> Interactive (6) -> 0
114  TestTosValue(queueDisc, 0x14, 0); // MR+MD -> Interactive (6) -> 0
115  TestTosValue(queueDisc, 0x16, 0); // MMC+MR+MD -> Interactive (6) -> 0
116  TestTosValue(queueDisc, 0x18, 1); // MT+MD -> Int. Bulk (4) -> 1
117  TestTosValue(queueDisc, 0x1a, 1); // MMC+MT+MD -> Int. Bulk (4) -> 1
118  TestTosValue(queueDisc, 0x1c, 1); // MR+MT+MD -> Int. Bulk (4) -> 1
119  TestTosValue(queueDisc, 0x1e, 1); // MMC+MR+MT+MD -> Int. Bulk (4) -> 1
120  Simulator::Destroy();
121 }
122 
129 {
130  public:
133 
134  private:
135  void DoRun() override;
143  void TestDscpValue(Ptr<PfifoFastQueueDisc> queue, Ipv4Header::DscpType dscp, uint32_t band);
144 };
145 
147  : TestCase("Test DSCP-based prioritization")
148 {
149 }
150 
152 {
153 }
154 
155 void
158  uint32_t band)
159 {
160  Ptr<Packet> p = Create<Packet>(100);
161  Ipv4Header ipHeader;
162  ipHeader.SetPayloadSize(100);
163  ipHeader.SetProtocol(6);
164  ipHeader.SetDscp(dscp);
165  SocketPriorityTag priorityTag;
166  priorityTag.SetPriority(Socket::IpTos2Priority(ipHeader.GetTos()));
167  p->AddPacketTag(priorityTag);
168  Address dest;
169  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem>(p, dest, 0, ipHeader);
170  queue->Enqueue(item);
171  NS_TEST_ASSERT_MSG_EQ(queue->GetInternalQueue(band)->GetNPackets(),
172  1,
173  "enqueued to unexpected band");
174  queue->Dequeue();
175  NS_TEST_ASSERT_MSG_EQ(queue->GetInternalQueue(band)->GetNPackets(), 0, "unable to dequeue");
176 }
177 
178 void
180 {
181  Ptr<PfifoFastQueueDisc> queueDisc = CreateObject<PfifoFastQueueDisc>();
182  for (uint16_t i = 0; i < 3; i++)
183  {
184  Ptr<DropTailQueue<QueueDiscItem>> queue = CreateObject<DropTailQueue<QueueDiscItem>>();
185  bool ok = queue->SetAttributeFailSafe("MaxSize", StringValue("1000p"));
186  NS_TEST_ASSERT_MSG_EQ(ok, true, "unable to set attribute");
187  queueDisc->AddInternalQueue(queue);
188  }
189  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(0)->GetNPackets(), 0, "initialized non-zero");
190  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(1)->GetNPackets(), 0, "initialized non-zero");
191  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(2)->GetNPackets(), 0, "initialized non-zero");
192 
193  // priority band
194  TestDscpValue(queueDisc, Ipv4Header::DscpDefault, 1); // Best Effort (0) -> 1
195  TestDscpValue(queueDisc, Ipv4Header::DSCP_EF, 1); // Int. Bulk (4) -> 1
196  TestDscpValue(queueDisc, Ipv4Header::DSCP_AF11, 2); // Bulk (2) -> 2
197  TestDscpValue(queueDisc, Ipv4Header::DSCP_AF21, 2); // Bulk (2) -> 2
198  TestDscpValue(queueDisc, Ipv4Header::DSCP_AF31, 2); // Bulk (2) -> 2
199  TestDscpValue(queueDisc, Ipv4Header::DSCP_AF41, 2); // Bulk (2) -> 2
200  TestDscpValue(queueDisc, Ipv4Header::DSCP_AF12, 0); // Interactive (6) -> 0
201  TestDscpValue(queueDisc, Ipv4Header::DSCP_AF22, 0); // Interactive (6) -> 0
202  TestDscpValue(queueDisc, Ipv4Header::DSCP_AF32, 0); // Interactive (6) -> 0
203  TestDscpValue(queueDisc, Ipv4Header::DSCP_AF42, 0); // Interactive (6) -> 0
204  TestDscpValue(queueDisc, Ipv4Header::DSCP_AF13, 1); // Int. Bulk (4) -> 1
205  TestDscpValue(queueDisc, Ipv4Header::DSCP_AF23, 1); // Int. Bulk (4) -> 1
206  TestDscpValue(queueDisc, Ipv4Header::DSCP_AF33, 1); // Int. Bulk (4) -> 1
207  TestDscpValue(queueDisc, Ipv4Header::DSCP_AF43, 1); // Int. Bulk (4) -> 1
208  TestDscpValue(queueDisc, Ipv4Header::DSCP_CS1, 1); // Best Effort (0) -> 1
209  TestDscpValue(queueDisc, Ipv4Header::DSCP_CS2, 1); // Best Effort (0) -> 1
210  TestDscpValue(queueDisc, Ipv4Header::DSCP_CS3, 1); // Best Effort (0) -> 1
211  TestDscpValue(queueDisc, Ipv4Header::DSCP_CS4, 1); // Best Effort (0) -> 1
212  TestDscpValue(queueDisc, Ipv4Header::DSCP_CS5, 1); // Best Effort (0) -> 1
213  TestDscpValue(queueDisc, Ipv4Header::DSCP_CS6, 1); // Best Effort (0) -> 1
214  TestDscpValue(queueDisc, Ipv4Header::DSCP_CS7, 1); // Best Effort (0) -> 1
215  Simulator::Destroy();
216 }
217 
224 {
225  public:
227  ~PfifoFastQueueDiscOverflow() override;
228 
229  private:
230  void DoRun() override;
238 };
239 
241  : TestCase("Test queue overflow")
242 {
243 }
244 
246 {
247 }
248 
249 void
251 {
252  Ptr<Packet> p = Create<Packet>(100);
253  Ipv4Header ipHeader;
254  ipHeader.SetPayloadSize(100);
255  ipHeader.SetProtocol(6);
256  ipHeader.SetDscp(dscp);
257  SocketPriorityTag priorityTag;
258  priorityTag.SetPriority(Socket::IpTos2Priority(ipHeader.GetTos()));
259  p->AddPacketTag(priorityTag);
260  Address dest;
261  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem>(p, dest, 0, ipHeader);
262  queue->Enqueue(item);
263 }
264 
265 void
267 {
268  Ptr<PfifoFastQueueDisc> queueDisc =
269  CreateObjectWithAttributes<PfifoFastQueueDisc>("MaxSize", StringValue("6p"));
271  CreateObjectWithAttributes<DropTailQueue<QueueDiscItem>>("MaxSize", StringValue("6p"));
273  CreateObjectWithAttributes<DropTailQueue<QueueDiscItem>>("MaxSize", StringValue("6p"));
275  CreateObjectWithAttributes<DropTailQueue<QueueDiscItem>>("MaxSize", StringValue("6p"));
276  queueDisc->AddInternalQueue(band0);
277  queueDisc->AddInternalQueue(band1);
278  queueDisc->AddInternalQueue(band2);
279 
280  // Add two packets per each band
281  AddPacket(queueDisc, Ipv4Header::DSCP_AF42); // 0
282  AddPacket(queueDisc, Ipv4Header::DSCP_AF42); // 0
283  AddPacket(queueDisc, Ipv4Header::DSCP_AF13); // 1
284  AddPacket(queueDisc, Ipv4Header::DSCP_AF13); // 1
285  AddPacket(queueDisc, Ipv4Header::DSCP_AF11); // 2
286  AddPacket(queueDisc, Ipv4Header::DSCP_AF11); // 2
287  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(0)->GetNPackets(),
288  2,
289  "unexpected queue depth");
290  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(1)->GetNPackets(),
291  2,
292  "unexpected queue depth");
293  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(2)->GetNPackets(),
294  2,
295  "unexpected queue depth");
296  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(), 6, "unexpected queue depth");
297  // Add a third packet to each band
298  AddPacket(queueDisc, Ipv4Header::DSCP_AF42); // 0
299  AddPacket(queueDisc, Ipv4Header::DSCP_AF13); // 1
300  AddPacket(queueDisc, Ipv4Header::DSCP_AF11); // 2
301  // Bands should still have two packets each
302  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(0)->GetNPackets(),
303  2,
304  "unexpected queue depth");
305  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(1)->GetNPackets(),
306  2,
307  "unexpected queue depth");
308  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(2)->GetNPackets(),
309  2,
310  "unexpected queue depth");
311  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(), 6, "unexpected queue depth");
312  Simulator::Destroy();
313 }
314 
322 {
323  public:
326 
327  private:
328  void DoRun() override;
329 };
330 
332  : TestCase("Test queue with no priority tag")
333 {
334 }
335 
337 {
338 }
339 
340 void
342 {
343  // all packets with non-IP headers should enqueue in band 1
344  Ptr<PfifoFastQueueDisc> queueDisc = CreateObject<PfifoFastQueueDisc>();
345  for (uint16_t i = 0; i < 3; i++)
346  {
347  Ptr<DropTailQueue<QueueDiscItem>> queue = CreateObject<DropTailQueue<QueueDiscItem>>();
348  bool ok = queue->SetAttributeFailSafe("MaxSize", StringValue("1000p"));
349  NS_TEST_ASSERT_MSG_EQ(ok, true, "unable to set attribute");
350  queueDisc->AddInternalQueue(queue);
351  }
352  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(1)->GetNPackets(),
353  0,
354  "unexpected queue depth");
355  Ptr<Packet> p;
356  p = Create<Packet>();
358  Ipv6Header ipv6Header;
359  Address dest;
360  item = Create<Ipv6QueueDiscItem>(p, dest, 0, ipv6Header);
361  queueDisc->Enqueue(item);
362  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(1)->GetNPackets(),
363  1,
364  "unexpected queue depth");
365  p = Create<Packet>(reinterpret_cast<const uint8_t*>("hello, world"), 12);
366  item = Create<Ipv6QueueDiscItem>(p, dest, 0, ipv6Header);
367  queueDisc->Enqueue(item);
368  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(1)->GetNPackets(),
369  2,
370  "unexpected queue depth");
371  p = Create<Packet>(100);
372  auto buf = new uint8_t[100];
373  uint8_t counter = 0;
374  for (uint32_t i = 0; i < 100; i++)
375  {
376  buf[i] = counter++;
377  }
378  p->CopyData(buf, 100);
379  item = Create<Ipv6QueueDiscItem>(p, dest, 0, ipv6Header);
380  queueDisc->Enqueue(item);
381  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(1)->GetNPackets(),
382  3,
383  "unexpected queue depth");
384  delete[] buf;
385  Simulator::Destroy();
386 }
387 
394 {
395  public:
397 };
398 
400  : TestSuite("pfifo-fast-queue-disc", UNIT)
401 {
402  AddTestCase(new PfifoFastQueueDiscTosPrioritization, TestCase::QUICK);
404  AddTestCase(new PfifoFastQueueDiscOverflow, TestCase::QUICK);
405  AddTestCase(new PfifoFastQueueDiscNoPriority, TestCase::QUICK);
406 }
407 
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.
void DoRun() override
Implementation to actually run this TestCase.
This class tests that packets without a priority tag are handled by placing them into band 1.
void DoRun() override
Implementation to actually run this TestCase.
This class tests that each band is txqueuelen deep.
void DoRun() override
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.
void DoRun() override
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:101
Packet header for IPv4.
Definition: ipv4-header.h:34
uint8_t GetTos() const
Definition: ipv4-header.cc:196
void SetPayloadSize(uint16_t size)
Definition: ipv4-header.cc:57
void SetDscp(DscpType dscp)
Set DSCP Field.
Definition: ipv4-header.cc:92
DscpType
DiffServ codepoints.
Definition: ipv4-header.h:72
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:288
void SetTos(uint8_t tos)
Definition: ipv4-header.cc:85
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:400
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:960
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
indicates whether the socket has a priority set.
Definition: socket.h:1316
void SetPriority(uint8_t priority)
Set the tag's priority.
Definition: socket.cc:854
Hold variables of type string.
Definition: string.h:56
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
#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:144
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.