A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
adaptive-red-queue-disc-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015 NITK Surathkal
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 * Author: Mohit P. Tahiliani <tahiliani@nitk.edu.in>
18 *
19 */
20
21#include "ns3/double.h"
22#include "ns3/log.h"
23#include "ns3/packet.h"
24#include "ns3/red-queue-disc.h"
25#include "ns3/simulator.h"
26#include "ns3/string.h"
27#include "ns3/test.h"
28#include "ns3/uinteger.h"
29
30using namespace ns3;
31
44{
45 public:
53 ~AredQueueDiscTestItem() override;
54
55 // Delete default constructor, copy constructor and assignment operator to avoid misuse
59
60 void AddHeader() override;
61 bool Mark() override;
62};
63
65 : QueueDiscItem(p, addr, 0)
66{
67}
68
70{
71}
72
73void
75{
76}
77
78bool
80{
81 return false;
82}
83
90{
91 public:
93 void DoRun() override;
94
95 private:
102 void Enqueue(Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt);
109 void EnqueueWithDelay(Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt);
115};
116
118 : TestCase("Sanity check on the functionality of Adaptive RED")
119{
120}
121
122void
124{
125 uint32_t pktSize = 0;
126 uint32_t modeSize = 1; // 1 for packets; pktSize for bytes
127 double minTh = 70;
128 double maxTh = 150;
129 uint32_t qSize = 300;
130 Address dest;
131
132 // test 1: Verify automatic setting of QW. [QW = 0.0 with default LinkBandwidth]
133 Ptr<RedQueueDisc> queue = CreateObject<RedQueueDisc>();
134
135 if (mode == QueueSizeUnit::BYTES)
136 {
137 pktSize = 500;
138 modeSize = pktSize;
139 minTh = minTh * modeSize;
140 maxTh = maxTh * modeSize;
141 qSize = qSize * modeSize;
142 }
143
144 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
145 true,
146 "Verify that we can actually set the attribute MinTh");
147 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
148 true,
149 "Verify that we can actually set the attribute MaxTh");
151 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
152 true,
153 "Verify that we can actually set the attribute MaxSize");
154 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(0.0)),
155 true,
156 "Verify that we can actually set the attribute QW");
157 queue->Initialize();
158 Enqueue(queue, pktSize, 300);
159 QueueDisc::Stats st = queue->GetStats();
161 0,
162 "There should be zero unforced drops");
163
164 // test 2: Verify automatic setting of QW. [QW = 0.0 with lesser LinkBandwidth]
165 queue = CreateObject<RedQueueDisc>();
166 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
167 true,
168 "Verify that we can actually set the attribute MinTh");
169 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
170 true,
171 "Verify that we can actually set the attribute MaxTh");
173 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
174 true,
175 "Verify that we can actually set the attribute MaxSize");
176 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(0.0)),
177 true,
178 "Verify that we can actually set the attribute QW");
180 queue->SetAttributeFailSafe("LinkBandwidth", DataRateValue(DataRate("0.015Mbps"))),
181 true,
182 "Verify that we can actually set the attribute LinkBandwidth");
183 queue->Initialize();
184 Enqueue(queue, pktSize, 300);
185 st = queue->GetStats();
187 0,
188 "There should be some unforced drops");
189
190 // test 3: Verify automatic setting of QW. [QW = -1.0 with default LinkBandwidth]
191 queue = CreateObject<RedQueueDisc>();
192 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
193 true,
194 "Verify that we can actually set the attribute MinTh");
195 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
196 true,
197 "Verify that we can actually set the attribute MaxTh");
199 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
200 true,
201 "Verify that we can actually set the attribute MaxSize");
202 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(-1.0)),
203 true,
204 "Verify that we can actually set the attribute QW");
205 queue->Initialize();
206 Enqueue(queue, pktSize, 300);
207 st = queue->GetStats();
209 0,
210 "There should be zero unforced drops");
211
212 // test 4: Verify automatic setting of QW. [QW = -1.0 with lesser LinkBandwidth]
213 queue = CreateObject<RedQueueDisc>();
214 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
215 true,
216 "Verify that we can actually set the attribute MinTh");
217 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
218 true,
219 "Verify that we can actually set the attribute MaxTh");
221 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
222 true,
223 "Verify that we can actually set the attribute MaxSize");
224 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(-1.0)),
225 true,
226 "Verify that we can actually set the attribute QW");
228 queue->SetAttributeFailSafe("LinkBandwidth", DataRateValue(DataRate("0.015Mbps"))),
229 true,
230 "Verify that we can actually set the attribute LinkBandwidth");
231 queue->Initialize();
232 Enqueue(queue, pktSize, 300);
233 st = queue->GetStats();
235 0,
236 "There should be some unforced drops");
237
238 // test 5: Verify automatic setting of QW. [QW = -2.0 with default LinkBandwidth]
239 queue = CreateObject<RedQueueDisc>();
240 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
241 true,
242 "Verify that we can actually set the attribute MinTh");
243 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
244 true,
245 "Verify that we can actually set the attribute MaxTh");
247 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
248 true,
249 "Verify that we can actually set the attribute MaxSize");
250 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(-2.0)),
251 true,
252 "Verify that we can actually set the attribute QW");
253 queue->Initialize();
254 Enqueue(queue, pktSize, 300);
255 st = queue->GetStats();
257 NS_TEST_ASSERT_MSG_NE(test5, 0, "There should be some unforced drops");
258
259 // test 6: Verify automatic setting of QW. [QW = -2.0 with lesser LinkBandwidth]
260 queue = CreateObject<RedQueueDisc>();
261 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
262 true,
263 "Verify that we can actually set the attribute MinTh");
264 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
265 true,
266 "Verify that we can actually set the attribute MaxTh");
268 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
269 true,
270 "Verify that we can actually set the attribute MaxSize");
271 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(-2.0)),
272 true,
273 "Verify that we can actually set the attribute QW");
275 queue->SetAttributeFailSafe("LinkBandwidth", DataRateValue(DataRate("0.015Mbps"))),
276 true,
277 "Verify that we can actually set the attribute LinkBandwidth");
278 queue->Initialize();
279 Enqueue(queue, pktSize, 300);
280 st = queue->GetStats();
282 NS_TEST_ASSERT_MSG_NE(test6, test5, "Test 6 should have more unforced drops than Test 5");
283
284 // test 7: Verify automatic setting of minTh and maxTh. [minTh = maxTh = 0.0, with default
285 // LinkBandwidth]
286 queue = CreateObject<RedQueueDisc>();
287 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(0.0)),
288 true,
289 "Verify that we can actually set the attribute MinTh");
290 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(0.0)),
291 true,
292 "Verify that we can actually set the attribute MaxTh");
294 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
295 true,
296 "Verify that we can actually set the attribute MaxSize");
297 queue->Initialize();
298 Enqueue(queue, pktSize, 300);
299 st = queue->GetStats();
301 0,
302 "There should be some unforced drops");
303
304 // test 8: Verify automatic setting of minTh and maxTh. [minTh = maxTh = 0.0, with higher
305 // LinkBandwidth]
306 queue = CreateObject<RedQueueDisc>();
307 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(0.0)),
308 true,
309 "Verify that we can actually set the attribute MinTh");
310 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(0.0)),
311 true,
312 "Verify that we can actually set the attribute MaxTh");
314 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
315 true,
316 "Verify that we can actually set the attribute MaxSize");
318 queue->SetAttributeFailSafe("LinkBandwidth", DataRateValue(DataRate("150Mbps"))),
319 true,
320 "Verify that we can actually set the attribute LinkBandwidth");
321 queue->Initialize();
322 Enqueue(queue, pktSize, 300);
323 st = queue->GetStats();
325 0,
326 "There should be zero unforced drops");
327
328 // test 9: Default RED (automatic and adaptive settings disabled)
329 queue = CreateObject<RedQueueDisc>();
330 minTh = 5 * modeSize;
331 maxTh = 15 * modeSize;
332 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
333 true,
334 "Verify that we can actually set the attribute MinTh");
335 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
336 true,
337 "Verify that we can actually set the attribute MaxTh");
339 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
340 true,
341 "Verify that we can actually set the attribute MaxSize");
342 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(0.002)),
343 true,
344 "Verify that we can actually set the attribute QW");
345 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("LInterm", DoubleValue(2)),
346 true,
347 "Verify that we can actually set the attribute LInterm");
348 queue->Initialize();
349 EnqueueWithDelay(queue, pktSize, 300);
352 st = queue->GetStats();
355 0,
356 "There should be some unforced drops");
357
358 // test 10: Adaptive RED (automatic and adaptive settings enabled)
359 queue = CreateObject<RedQueueDisc>();
361 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
362 true,
363 "Verify that we can actually set the attribute MaxSize");
364 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("LInterm", DoubleValue(2)),
365 true,
366 "Verify that we can actually set the attribute LInterm");
367 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("ARED", BooleanValue(true)),
368 true,
369 "Verify that we can actually set the attribute ARED");
370 queue->Initialize();
371 EnqueueWithDelay(queue, pktSize, 300);
374 st = queue->GetStats();
376 NS_TEST_ASSERT_MSG_LT(test10, test9, "Test 10 should have less unforced drops than test 9");
377}
378
379void
381{
382 Address dest;
383 for (uint32_t i = 0; i < nPkt; i++)
384 {
385 queue->Enqueue(Create<AredQueueDiscTestItem>(Create<Packet>(size), dest));
386 }
387}
388
389void
391{
392 Address dest;
393 double delay = 0.01; // enqueue packets with delay to allow m_curMaxP to adapt
394 for (uint32_t i = 0; i < nPkt; i++)
395 {
396 Simulator::Schedule(Time(Seconds((i + 1) * delay)),
398 this,
399 queue,
400 size,
401 1);
402 }
403}
404
405void
407{
408 RunAredDiscTest(QueueSizeUnit::PACKETS);
409 RunAredDiscTest(QueueSizeUnit::BYTES);
411}
412
419{
420 public:
422 : TestSuite("adaptive-red-queue-disc", Type::UNIT)
423 {
424 AddTestCase(new AredQueueDiscTestCase(), TestCase::Duration::QUICK);
425 }
void RunAredDiscTest(QueueSizeUnit mode)
Run ARED queue disc test function.
void Enqueue(Ptr< RedQueueDisc > queue, uint32_t size, uint32_t nPkt)
Enqueue function.
void EnqueueWithDelay(Ptr< RedQueueDisc > queue, uint32_t size, uint32_t nPkt)
Enqueue with delay function.
void DoRun() override
Implementation to actually run this TestCase.
AredQueueDiscTestItem()=delete
void AddHeader() override
Add the header to the packet.
AredQueueDiscTestItem(const AredQueueDiscTestItem &)=delete
AredQueueDiscTestItem & operator=(const AredQueueDiscTestItem &)=delete
bool Mark() override
Marks the packet as a substitute for dropping it, such as for Explicit Congestion Notification.
a polymophic address class
Definition: address.h:101
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Class for representing data rates.
Definition: data-rate.h:89
AttributeValue implementation for DataRate.
Definition: data-rate.h:296
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
QueueDiscItem is the abstract base class for items that are stored in a queue disc.
Definition: queue-item.h:133
Class for representing queue sizes.
Definition: queue-size.h:96
AttributeValue implementation for QueueSize.
Definition: queue-size.h:221
static constexpr const char * UNFORCED_DROP
Early probability drops.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
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
static constexpr auto UNIT
Definition: test.h:1286
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
QueueSizeUnit
Enumeration of the operating modes of queues.
Definition: queue-size.h:44
#define NS_TEST_ASSERT_MSG_LT(actual, limit, msg)
Test that an actual value is less than a limit and report and abort if not.
Definition: test.h:710
#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
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report and abort if not.
Definition: test.h:565
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
AredQueueDiscTestSuite g_aredQueueDiscTestSuite
the test suite
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Structure that keeps the queue disc statistics.
Definition: queue-disc.h:188
uint32_t GetNDroppedPackets(std::string reason) const
Get the number of packets dropped for the given reason.
Definition: queue-disc.cc:111
uint32_t pktSize
packet size used for the simulation (in bytes)