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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8#include "ns3/drop-tail-queue.h"
9#include "ns3/enum.h"
10#include "ns3/ipv4-queue-disc-item.h"
11#include "ns3/ipv6-queue-disc-item.h"
12#include "ns3/object-factory.h"
13#include "ns3/pfifo-fast-queue-disc.h"
14#include "ns3/pointer.h"
15#include "ns3/simulator.h"
16#include "ns3/socket.h"
17#include "ns3/string.h"
18#include "ns3/test.h"
19
20using namespace ns3;
21
22/**
23 * \ingroup system-tests-tc
24 *
25 * This class tests that each possible TOS is enqueued in the right band
26 */
28{
29 public:
32
33 private:
34 void DoRun() override;
35 /**
36 * Enqueue a packet and checks that it's added to the proper band.
37 *
38 * \param queue The queue disc.
39 * \param tos The TOS of the packet.
40 * \param band Expected band.
41 */
42 void TestTosValue(Ptr<PfifoFastQueueDisc> queue, uint8_t tos, uint32_t band);
43};
44
49
53
54void
56 uint8_t tos,
57 uint32_t band)
58{
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(),
71 1,
72 "enqueued to unexpected band");
73 queue->Dequeue();
74 NS_TEST_ASSERT_MSG_EQ(queue->GetInternalQueue(band)->GetNPackets(), 0, "unable to dequeue");
75}
76
77void
79{
81 for (uint16_t i = 0; i < 3; i++)
82 {
84 bool ok = queue->SetAttributeFailSafe("MaxSize", StringValue("1000p"));
85 NS_TEST_ASSERT_MSG_EQ(ok, true, "unable to set attribute");
86 queueDisc->AddInternalQueue(queue);
87 }
88 NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(0)->GetNPackets(), 0, "initialized non-zero");
89 NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(1)->GetNPackets(), 0, "initialized non-zero");
90 NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(2)->GetNPackets(), 0, "initialized non-zero");
91
92 // Service name priority band
93 TestTosValue(queueDisc, 0x00, 1); // Normal service -> Best Effort (0) -> 1
94 TestTosValue(queueDisc, 0x02, 1); // MMC -> Best Effort (0) -> 1
95 TestTosValue(queueDisc, 0x04, 1); // MR -> Best Effort (0) -> 1
96 TestTosValue(queueDisc, 0x06, 1); // MMC+MR -> Best Effort (0) -> 1
97 TestTosValue(queueDisc, 0x08, 2); // Max. Throughput -> Bulk (2) -> 2
98 TestTosValue(queueDisc, 0x0a, 2); // MMC+MT -> Bulk (2) -> 2
99 TestTosValue(queueDisc, 0x0c, 2); // MR+MT -> Bulk (2) -> 2
100 TestTosValue(queueDisc, 0x0e, 2); // MMC+MR+MT -> Bulk (2) -> 2
101 TestTosValue(queueDisc, 0x10, 0); // Minimize Delay -> Interactive (6) -> 0
102 TestTosValue(queueDisc, 0x12, 0); // MMC+MD -> Interactive (6) -> 0
103 TestTosValue(queueDisc, 0x14, 0); // MR+MD -> Interactive (6) -> 0
104 TestTosValue(queueDisc, 0x16, 0); // MMC+MR+MD -> Interactive (6) -> 0
105 TestTosValue(queueDisc, 0x18, 1); // MT+MD -> Int. Bulk (4) -> 1
106 TestTosValue(queueDisc, 0x1a, 1); // MMC+MT+MD -> Int. Bulk (4) -> 1
107 TestTosValue(queueDisc, 0x1c, 1); // MR+MT+MD -> Int. Bulk (4) -> 1
108 TestTosValue(queueDisc, 0x1e, 1); // MMC+MR+MT+MD -> Int. Bulk (4) -> 1
110}
111
112/**
113 * \ingroup system-tests-tc
114 *
115 * This class tests that each possible DSCP is enqueued in the right band.
116 */
118{
119 public:
122
123 private:
124 void DoRun() override;
125 /**
126 * Enqueue a packet and checks that it's added to the proper band.
127 *
128 * \param queue The queue disc.
129 * \param dscp The DSCP of the packet.
130 * \param band Expected band.
131 */
133};
134
139
143
144void
147 uint32_t band)
148{
150 Ipv4Header ipHeader;
151 ipHeader.SetPayloadSize(100);
152 ipHeader.SetProtocol(6);
153 ipHeader.SetDscp(dscp);
154 SocketPriorityTag priorityTag;
155 priorityTag.SetPriority(Socket::IpTos2Priority(ipHeader.GetTos()));
156 p->AddPacketTag(priorityTag);
157 Address dest;
158 Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem>(p, dest, 0, ipHeader);
159 queue->Enqueue(item);
160 NS_TEST_ASSERT_MSG_EQ(queue->GetInternalQueue(band)->GetNPackets(),
161 1,
162 "enqueued to unexpected band");
163 queue->Dequeue();
164 NS_TEST_ASSERT_MSG_EQ(queue->GetInternalQueue(band)->GetNPackets(), 0, "unable to dequeue");
165}
166
167void
169{
171 for (uint16_t i = 0; i < 3; i++)
172 {
174 bool ok = queue->SetAttributeFailSafe("MaxSize", StringValue("1000p"));
175 NS_TEST_ASSERT_MSG_EQ(ok, true, "unable to set attribute");
176 queueDisc->AddInternalQueue(queue);
177 }
178 NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(0)->GetNPackets(), 0, "initialized non-zero");
179 NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(1)->GetNPackets(), 0, "initialized non-zero");
180 NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(2)->GetNPackets(), 0, "initialized non-zero");
181
182 // priority band
183 TestDscpValue(queueDisc, Ipv4Header::DscpDefault, 1); // Best Effort (0) -> 1
184 TestDscpValue(queueDisc, Ipv4Header::DSCP_EF, 1); // Int. Bulk (4) -> 1
185 TestDscpValue(queueDisc, Ipv4Header::DSCP_AF11, 2); // Bulk (2) -> 2
186 TestDscpValue(queueDisc, Ipv4Header::DSCP_AF21, 2); // Bulk (2) -> 2
187 TestDscpValue(queueDisc, Ipv4Header::DSCP_AF31, 2); // Bulk (2) -> 2
188 TestDscpValue(queueDisc, Ipv4Header::DSCP_AF41, 2); // Bulk (2) -> 2
189 TestDscpValue(queueDisc, Ipv4Header::DSCP_AF12, 0); // Interactive (6) -> 0
190 TestDscpValue(queueDisc, Ipv4Header::DSCP_AF22, 0); // Interactive (6) -> 0
191 TestDscpValue(queueDisc, Ipv4Header::DSCP_AF32, 0); // Interactive (6) -> 0
192 TestDscpValue(queueDisc, Ipv4Header::DSCP_AF42, 0); // Interactive (6) -> 0
193 TestDscpValue(queueDisc, Ipv4Header::DSCP_AF13, 1); // Int. Bulk (4) -> 1
194 TestDscpValue(queueDisc, Ipv4Header::DSCP_AF23, 1); // Int. Bulk (4) -> 1
195 TestDscpValue(queueDisc, Ipv4Header::DSCP_AF33, 1); // Int. Bulk (4) -> 1
196 TestDscpValue(queueDisc, Ipv4Header::DSCP_AF43, 1); // Int. Bulk (4) -> 1
197 TestDscpValue(queueDisc, Ipv4Header::DSCP_CS1, 1); // Best Effort (0) -> 1
198 TestDscpValue(queueDisc, Ipv4Header::DSCP_CS2, 1); // Best Effort (0) -> 1
199 TestDscpValue(queueDisc, Ipv4Header::DSCP_CS3, 1); // Best Effort (0) -> 1
200 TestDscpValue(queueDisc, Ipv4Header::DSCP_CS4, 1); // Best Effort (0) -> 1
201 TestDscpValue(queueDisc, Ipv4Header::DSCP_CS5, 1); // Best Effort (0) -> 1
202 TestDscpValue(queueDisc, Ipv4Header::DSCP_CS6, 1); // Best Effort (0) -> 1
203 TestDscpValue(queueDisc, Ipv4Header::DSCP_CS7, 1); // Best Effort (0) -> 1
205}
206
207/**
208 * \ingroup system-tests-tc
209 *
210 * This class tests that each band is txqueuelen deep.
211 */
213{
214 public:
217
218 private:
219 void DoRun() override;
220 /**
221 * Enqueue a packet.
222 *
223 * \param queue The queue disc.
224 * \param dscp The DSCP of the packet.
225 */
227};
228
233
237
238void
240{
242 Ipv4Header ipHeader;
243 ipHeader.SetPayloadSize(100);
244 ipHeader.SetProtocol(6);
245 ipHeader.SetDscp(dscp);
246 SocketPriorityTag priorityTag;
247 priorityTag.SetPriority(Socket::IpTos2Priority(ipHeader.GetTos()));
248 p->AddPacketTag(priorityTag);
249 Address dest;
250 Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem>(p, dest, 0, ipHeader);
251 queue->Enqueue(item);
252}
253
254void
256{
257 Ptr<PfifoFastQueueDisc> queueDisc =
265 queueDisc->AddInternalQueue(band0);
266 queueDisc->AddInternalQueue(band1);
267 queueDisc->AddInternalQueue(band2);
268
269 // Add two packets per each band
270 AddPacket(queueDisc, Ipv4Header::DSCP_AF42); // 0
271 AddPacket(queueDisc, Ipv4Header::DSCP_AF42); // 0
272 AddPacket(queueDisc, Ipv4Header::DSCP_AF13); // 1
273 AddPacket(queueDisc, Ipv4Header::DSCP_AF13); // 1
274 AddPacket(queueDisc, Ipv4Header::DSCP_AF11); // 2
275 AddPacket(queueDisc, Ipv4Header::DSCP_AF11); // 2
276 NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(0)->GetNPackets(),
277 2,
278 "unexpected queue depth");
279 NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(1)->GetNPackets(),
280 2,
281 "unexpected queue depth");
282 NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(2)->GetNPackets(),
283 2,
284 "unexpected queue depth");
285 NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(), 6, "unexpected queue depth");
286 // Add a third packet to each band
287 AddPacket(queueDisc, Ipv4Header::DSCP_AF42); // 0
288 AddPacket(queueDisc, Ipv4Header::DSCP_AF13); // 1
289 AddPacket(queueDisc, Ipv4Header::DSCP_AF11); // 2
290 // Bands should still have two packets each
291 NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(0)->GetNPackets(),
292 2,
293 "unexpected queue depth");
294 NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(1)->GetNPackets(),
295 2,
296 "unexpected queue depth");
297 NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(2)->GetNPackets(),
298 2,
299 "unexpected queue depth");
300 NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(), 6, "unexpected queue depth");
302}
303
304/**
305 * \ingroup system-tests-tc
306 *
307 * This class tests that packets without a priority tag are handled by placing
308 * them into band 1.
309 */
311{
312 public:
315
316 private:
317 void DoRun() override;
318};
319
321 : TestCase("Test queue with no priority tag")
322{
323}
324
328
329void
331{
332 // all packets with non-IP headers should enqueue in band 1
334 for (uint16_t i = 0; i < 3; i++)
335 {
337 bool ok = queue->SetAttributeFailSafe("MaxSize", StringValue("1000p"));
338 NS_TEST_ASSERT_MSG_EQ(ok, true, "unable to set attribute");
339 queueDisc->AddInternalQueue(queue);
340 }
341 NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(1)->GetNPackets(),
342 0,
343 "unexpected queue depth");
344 Ptr<Packet> p;
345 p = Create<Packet>();
347 Ipv6Header ipv6Header;
348 Address dest;
349 item = Create<Ipv6QueueDiscItem>(p, dest, 0, ipv6Header);
350 queueDisc->Enqueue(item);
351 NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(1)->GetNPackets(),
352 1,
353 "unexpected queue depth");
354 p = Create<Packet>(reinterpret_cast<const uint8_t*>("hello, world"), 12);
355 item = Create<Ipv6QueueDiscItem>(p, dest, 0, ipv6Header);
356 queueDisc->Enqueue(item);
357 NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(1)->GetNPackets(),
358 2,
359 "unexpected queue depth");
360 p = Create<Packet>(100);
361 auto buf = new uint8_t[100];
362 uint8_t counter = 0;
363 for (uint32_t i = 0; i < 100; i++)
364 {
365 buf[i] = counter++;
366 }
367 p->CopyData(buf, 100);
368 item = Create<Ipv6QueueDiscItem>(p, dest, 0, ipv6Header);
369 queueDisc->Enqueue(item);
370 NS_TEST_ASSERT_MSG_EQ(queueDisc->GetInternalQueue(1)->GetNPackets(),
371 3,
372 "unexpected queue depth");
373 delete[] buf;
375}
376
377/**
378 * \ingroup system-tests-tc
379 *
380 * PfifoFast queue disc test suite.
381 */
383{
384 public:
386};
387
389 : TestSuite("pfifo-fast-queue-disc", Type::UNIT)
390{
391 AddTestCase(new PfifoFastQueueDiscTosPrioritization, TestCase::Duration::QUICK);
392 AddTestCase(new PfifoFastQueueDiscDscpPrioritization, TestCase::Duration::QUICK);
393 AddTestCase(new PfifoFastQueueDiscOverflow, TestCase::Duration::QUICK);
394 AddTestCase(new PfifoFastQueueDiscNoPriority, TestCase::Duration::QUICK);
395}
396
397/// 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.
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:90
Packet header for IPv4.
Definition ipv4-header.h:23
uint8_t GetTos() const
void SetPayloadSize(uint16_t size)
void SetDscp(DscpType dscp)
Set DSCP Field.
DscpType
DiffServ codepoints.
Definition ipv4-header.h:61
void SetProtocol(uint8_t num)
void SetTos(uint8_t tos)
Packet header for IPv6.
Definition ipv6-header.h:24
Smart pointer class similar to boost::intrusive_ptr.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static uint8_t IpTos2Priority(uint8_t ipTos)
Return the priority corresponding to a given TOS value.
Definition socket.cc:388
indicates whether the socket has a priority set.
Definition socket.h:1307
void SetPriority(uint8_t priority)
Set the tag's priority.
Definition socket.cc:843
Hold variables of type string.
Definition string.h:45
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > CreateObjectWithAttributes(Args... args)
Allocate an Object on the heap and initialize with a set of attributes.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
#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:134
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.