A Discrete-Event Network Simulator
API
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
91{
92 public:
94 void DoRun() override;
95
96 private:
103 void Enqueue(Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt);
110 void EnqueueWithDelay(Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt);
116};
117
119 : TestCase("Sanity check on the functionality of Adaptive RED")
120{
121}
122
123void
125{
126 uint32_t pktSize = 0;
127 uint32_t modeSize = 1; // 1 for packets; pktSize for bytes
128 double minTh = 70;
129 double maxTh = 150;
130 uint32_t qSize = 300;
131 Address dest;
132
133 // test 1: Verify automatic setting of QW. [QW = 0.0 with default LinkBandwidth]
134 Ptr<RedQueueDisc> queue = CreateObject<RedQueueDisc>();
135
136 if (mode == QueueSizeUnit::BYTES)
137 {
138 pktSize = 500;
139 modeSize = pktSize;
140 minTh = minTh * modeSize;
141 maxTh = maxTh * modeSize;
142 qSize = qSize * modeSize;
143 }
144
145 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
146 true,
147 "Verify that we can actually set the attribute MinTh");
148 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
149 true,
150 "Verify that we can actually set the attribute MaxTh");
152 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
153 true,
154 "Verify that we can actually set the attribute MaxSize");
155 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(0.0)),
156 true,
157 "Verify that we can actually set the attribute QW");
158 queue->Initialize();
159 Enqueue(queue, pktSize, 300);
160 QueueDisc::Stats st = queue->GetStats();
161 NS_TEST_ASSERT_MSG_EQ(st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP),
162 0,
163 "There should be zero unforced drops");
164
165 // test 2: Verify automatic setting of QW. [QW = 0.0 with lesser LinkBandwidth]
166 queue = CreateObject<RedQueueDisc>();
167 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
168 true,
169 "Verify that we can actually set the attribute MinTh");
170 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
171 true,
172 "Verify that we can actually set the attribute MaxTh");
174 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
175 true,
176 "Verify that we can actually set the attribute MaxSize");
177 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(0.0)),
178 true,
179 "Verify that we can actually set the attribute QW");
181 queue->SetAttributeFailSafe("LinkBandwidth", DataRateValue(DataRate("0.015Mbps"))),
182 true,
183 "Verify that we can actually set the attribute LinkBandwidth");
184 queue->Initialize();
185 Enqueue(queue, pktSize, 300);
186 st = queue->GetStats();
187 NS_TEST_ASSERT_MSG_NE(st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP),
188 0,
189 "There should be some unforced drops");
190
191 // test 3: Verify automatic setting of QW. [QW = -1.0 with default LinkBandwidth]
192 queue = CreateObject<RedQueueDisc>();
193 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
194 true,
195 "Verify that we can actually set the attribute MinTh");
196 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
197 true,
198 "Verify that we can actually set the attribute MaxTh");
200 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
201 true,
202 "Verify that we can actually set the attribute MaxSize");
203 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(-1.0)),
204 true,
205 "Verify that we can actually set the attribute QW");
206 queue->Initialize();
207 Enqueue(queue, pktSize, 300);
208 st = queue->GetStats();
209 NS_TEST_ASSERT_MSG_EQ(st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP),
210 0,
211 "There should be zero unforced drops");
212
213 // test 4: Verify automatic setting of QW. [QW = -1.0 with lesser LinkBandwidth]
214 queue = CreateObject<RedQueueDisc>();
215 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
216 true,
217 "Verify that we can actually set the attribute MinTh");
218 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
219 true,
220 "Verify that we can actually set the attribute MaxTh");
222 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
223 true,
224 "Verify that we can actually set the attribute MaxSize");
225 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(-1.0)),
226 true,
227 "Verify that we can actually set the attribute QW");
229 queue->SetAttributeFailSafe("LinkBandwidth", DataRateValue(DataRate("0.015Mbps"))),
230 true,
231 "Verify that we can actually set the attribute LinkBandwidth");
232 queue->Initialize();
233 Enqueue(queue, pktSize, 300);
234 st = queue->GetStats();
235 NS_TEST_ASSERT_MSG_NE(st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP),
236 0,
237 "There should be some unforced drops");
238
239 // test 5: Verify automatic setting of QW. [QW = -2.0 with default LinkBandwidth]
240 queue = CreateObject<RedQueueDisc>();
241 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
242 true,
243 "Verify that we can actually set the attribute MinTh");
244 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
245 true,
246 "Verify that we can actually set the attribute MaxTh");
248 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
249 true,
250 "Verify that we can actually set the attribute MaxSize");
251 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(-2.0)),
252 true,
253 "Verify that we can actually set the attribute QW");
254 queue->Initialize();
255 Enqueue(queue, pktSize, 300);
256 st = queue->GetStats();
257 uint32_t test5 = st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP);
258 NS_TEST_ASSERT_MSG_NE(test5, 0, "There should be some unforced drops");
259
260 // test 6: Verify automatic setting of QW. [QW = -2.0 with lesser LinkBandwidth]
261 queue = CreateObject<RedQueueDisc>();
262 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
263 true,
264 "Verify that we can actually set the attribute MinTh");
265 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
266 true,
267 "Verify that we can actually set the attribute MaxTh");
269 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
270 true,
271 "Verify that we can actually set the attribute MaxSize");
272 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(-2.0)),
273 true,
274 "Verify that we can actually set the attribute QW");
276 queue->SetAttributeFailSafe("LinkBandwidth", DataRateValue(DataRate("0.015Mbps"))),
277 true,
278 "Verify that we can actually set the attribute LinkBandwidth");
279 queue->Initialize();
280 Enqueue(queue, pktSize, 300);
281 st = queue->GetStats();
282 uint32_t test6 = st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP);
283 NS_TEST_ASSERT_MSG_NE(test6, test5, "Test 6 should have more unforced drops than Test 5");
284
285 // test 7: Verify automatic setting of minTh and maxTh. [minTh = maxTh = 0.0, with default
286 // LinkBandwidth]
287 queue = CreateObject<RedQueueDisc>();
288 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(0.0)),
289 true,
290 "Verify that we can actually set the attribute MinTh");
291 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(0.0)),
292 true,
293 "Verify that we can actually set the attribute MaxTh");
295 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
296 true,
297 "Verify that we can actually set the attribute MaxSize");
298 queue->Initialize();
299 Enqueue(queue, pktSize, 300);
300 st = queue->GetStats();
301 NS_TEST_ASSERT_MSG_NE(st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP),
302 0,
303 "There should be some unforced drops");
304
305 // test 8: Verify automatic setting of minTh and maxTh. [minTh = maxTh = 0.0, with higher
306 // LinkBandwidth]
307 queue = CreateObject<RedQueueDisc>();
308 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(0.0)),
309 true,
310 "Verify that we can actually set the attribute MinTh");
311 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(0.0)),
312 true,
313 "Verify that we can actually set the attribute MaxTh");
315 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
316 true,
317 "Verify that we can actually set the attribute MaxSize");
319 queue->SetAttributeFailSafe("LinkBandwidth", DataRateValue(DataRate("150Mbps"))),
320 true,
321 "Verify that we can actually set the attribute LinkBandwidth");
322 queue->Initialize();
323 Enqueue(queue, pktSize, 300);
324 st = queue->GetStats();
325 NS_TEST_ASSERT_MSG_EQ(st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP),
326 0,
327 "There should be zero unforced drops");
328
329 // test 9: Default RED (automatic and adaptive settings disabled)
330 queue = CreateObject<RedQueueDisc>();
331 minTh = 5 * modeSize;
332 maxTh = 15 * modeSize;
333 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
334 true,
335 "Verify that we can actually set the attribute MinTh");
336 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
337 true,
338 "Verify that we can actually set the attribute MaxTh");
340 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
341 true,
342 "Verify that we can actually set the attribute MaxSize");
343 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(0.002)),
344 true,
345 "Verify that we can actually set the attribute QW");
346 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("LInterm", DoubleValue(2)),
347 true,
348 "Verify that we can actually set the attribute LInterm");
349 queue->Initialize();
350 EnqueueWithDelay(queue, pktSize, 300);
351 Simulator::Stop(Seconds(5));
352 Simulator::Run();
353 st = queue->GetStats();
354 uint32_t test9 = st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP);
355 NS_TEST_ASSERT_MSG_NE(st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP),
356 0,
357 "There should be some unforced drops");
358
359 // test 10: Adaptive RED (automatic and adaptive settings enabled)
360 queue = CreateObject<RedQueueDisc>();
362 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
363 true,
364 "Verify that we can actually set the attribute MaxSize");
365 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("LInterm", DoubleValue(2)),
366 true,
367 "Verify that we can actually set the attribute LInterm");
368 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("ARED", BooleanValue(true)),
369 true,
370 "Verify that we can actually set the attribute ARED");
371 queue->Initialize();
372 EnqueueWithDelay(queue, pktSize, 300);
373 Simulator::Stop(Seconds(5));
374 Simulator::Run();
375 st = queue->GetStats();
376 uint32_t test10 = st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP);
377 NS_TEST_ASSERT_MSG_LT(test10, test9, "Test 10 should have less unforced drops than test 9");
378}
379
380void
382{
383 Address dest;
384 for (uint32_t i = 0; i < nPkt; i++)
385 {
386 queue->Enqueue(Create<AredQueueDiscTestItem>(Create<Packet>(size), dest));
387 }
388}
389
390void
392{
393 Address dest;
394 double delay = 0.01; // enqueue packets with delay to allow m_curMaxP to adapt
395 for (uint32_t i = 0; i < nPkt; i++)
396 {
397 Simulator::Schedule(Time(Seconds((i + 1) * delay)),
399 this,
400 queue,
401 size,
402 1);
403 }
404}
405
406void
408{
411 Simulator::Destroy();
412}
413
421{
422 public:
424 : TestSuite("adaptive-red-queue-disc", UNIT)
425 {
426 AddTestCase(new AredQueueDiscTestCase(), TestCase::QUICK);
427 }
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:92
AttributeValue implementation for Boolean.
Definition: boolean.h:37
AttributeValue implementation for DataRate.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
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.
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:305
A suite of tests to run.
Definition: test.h:1256
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1265
void(* DataRate)(DataRate oldValue, DataRate newValue)
TracedValue callback signature for DataRate.
Definition: data-rate.h:328
QueueSizeUnit
Enumeration of the operating modes of queues.
Definition: queue-size.h:44
@ BYTES
Use number of bytes for queue size.
Definition: queue-size.h:46
@ PACKETS
Use number of packets for queue size.
Definition: queue-size.h:45
#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:709
#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
#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:564
AredQueueDiscTestSuite g_aredQueueDiscTestSuite
the test suite
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:850
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)