A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
31using namespace ns3;
32
33/**
34 * \ingroup system-tests-tc
35 *
36 * This class tests that each possible TOS is enqueued in the right band
37 */
39{
40 public:
43
44 private:
45 void DoRun() override;
46 /**
47 * Enqueue a packet and checks that it's added to the proper band.
48 *
49 * \param queue The queue disc.
50 * \param tos The TOS of the packet.
51 * \param band Expected band.
52 */
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
65void
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
88void
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
121}
122
123/**
124 * \ingroup system-tests-tc
125 *
126 * This class tests that each possible DSCP is enqueued in the right band.
127 */
129{
130 public:
133
134 private:
135 void DoRun() override;
136 /**
137 * Enqueue a packet and checks that it's added to the proper band.
138 *
139 * \param queue The queue disc.
140 * \param dscp The DSCP of the packet.
141 * \param band Expected band.
142 */
144};
145
147 : TestCase("Test DSCP-based prioritization")
148{
149}
150
152{
153}
154
155void
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
178void
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
216}
217
218/**
219 * \ingroup system-tests-tc
220 *
221 * This class tests that each band is txqueuelen deep.
222 */
224{
225 public:
228
229 private:
230 void DoRun() override;
231 /**
232 * Enqueue a packet.
233 *
234 * \param queue The queue disc.
235 * \param dscp The DSCP of the packet.
236 */
238};
239
241 : TestCase("Test queue overflow")
242{
243}
244
246{
247}
248
249void
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
265void
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");
313}
314
315/**
316 * \ingroup system-tests-tc
317 *
318 * This class tests that packets without a priority tag are handled by placing
319 * them into band 1.
320 */
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
340void
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;
386}
387
388/**
389 * \ingroup system-tests-tc
390 *
391 * PfifoFast queue disc test suite.
392 */
394{
395 public:
397};
398
400 : TestSuite("pfifo-fast-queue-disc", Type::UNIT)
401{
402 AddTestCase(new PfifoFastQueueDiscTosPrioritization, TestCase::Duration::QUICK);
403 AddTestCase(new PfifoFastQueueDiscDscpPrioritization, TestCase::Duration::QUICK);
404 AddTestCase(new PfifoFastQueueDiscOverflow, TestCase::Duration::QUICK);
405 AddTestCase(new PfifoFastQueueDiscNoPriority, TestCase::Duration::QUICK);
406}
407
408/// Do not forget to allocate an instance of this TestSuite.
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
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static uint8_t IpTos2Priority(uint8_t ipTos)
Return the priority corresponding to a given TOS value.
Definition: socket.cc:399
indicates whether the socket has a priority set.
Definition: socket.h:1318
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:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
#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:145
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.