A Discrete-Event Network Simulator
API
red-queue-disc-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright © 2011 Marcos Talau
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: Marcos Talau (talau@users.sourceforge.net)
18 * Modified by: Pasquale Imputato <p.imputato@gmail.com>
19 *
20 */
21
22#include "ns3/double.h"
23#include "ns3/log.h"
24#include "ns3/packet.h"
25#include "ns3/red-queue-disc.h"
26#include "ns3/simulator.h"
27#include "ns3/string.h"
28#include "ns3/test.h"
29#include "ns3/uinteger.h"
30
31using namespace ns3;
32
40{
41 public:
49 RedQueueDiscTestItem(Ptr<Packet> p, const Address& addr, bool ecnCapable);
50
51 // Delete default constructor, copy constructor and assignment operator to avoid misuse
55
56 void AddHeader() override;
57 bool Mark() override;
58
59 private:
61};
62
64 : QueueDiscItem(p, addr, 0),
65 m_ecnCapablePacket(ecnCapable)
66{
67}
68
69void
71{
72}
73
74bool
76{
78 {
79 return true;
80 }
81 return false;
82}
83
91{
92 public:
94 void DoRun() override;
95
96 private:
104 void Enqueue(Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt, bool ecnCapable);
109 void RunRedTest(QueueSizeUnit mode);
110};
111
113 : TestCase("Sanity check on the red queue implementation")
114{
115}
116
117void
119{
120 uint32_t pktSize = 0;
121 // 1 for packets; pktSize for bytes
122 uint32_t modeSize = 1;
123 double minTh = 2;
124 double maxTh = 5;
125 uint32_t qSize = 8;
126 Ptr<RedQueueDisc> queue = CreateObject<RedQueueDisc>();
127
128 // test 1: simple enqueue/dequeue with no drops
129 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
130 true,
131 "Verify that we can actually set the attribute MinTh");
132 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
133 true,
134 "Verify that we can actually set the attribute MaxTh");
136 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
137 true,
138 "Verify that we can actually set the attribute MaxSize");
139 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(0.002)),
140 true,
141 "Verify that we can actually set the attribute QW");
142
143 Address dest;
144
145 if (mode == QueueSizeUnit::BYTES)
146 {
147 // pktSize should be same as MeanPktSize to avoid performance gap between byte and packet
148 // mode
149 pktSize = 500;
150 modeSize = pktSize;
151 queue->SetTh(minTh * modeSize, maxTh * modeSize);
152 queue->SetMaxSize(QueueSize(mode, qSize * modeSize));
153 }
154
155 Ptr<Packet> p1;
156 Ptr<Packet> p2;
157 Ptr<Packet> p3;
158 Ptr<Packet> p4;
159 Ptr<Packet> p5;
160 Ptr<Packet> p6;
161 Ptr<Packet> p7;
162 Ptr<Packet> p8;
163 p1 = Create<Packet>(pktSize);
164 p2 = Create<Packet>(pktSize);
165 p3 = Create<Packet>(pktSize);
166 p4 = Create<Packet>(pktSize);
167 p5 = Create<Packet>(pktSize);
168 p6 = Create<Packet>(pktSize);
169 p7 = Create<Packet>(pktSize);
170 p8 = Create<Packet>(pktSize);
171
172 queue->Initialize();
173 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
174 0 * modeSize,
175 "There should be no packets in there");
176 queue->Enqueue(Create<RedQueueDiscTestItem>(p1, dest, false));
177 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
178 1 * modeSize,
179 "There should be one packet in there");
180 queue->Enqueue(Create<RedQueueDiscTestItem>(p2, dest, false));
181 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
182 2 * modeSize,
183 "There should be two packets in there");
184 queue->Enqueue(Create<RedQueueDiscTestItem>(p3, dest, false));
185 queue->Enqueue(Create<RedQueueDiscTestItem>(p4, dest, false));
186 queue->Enqueue(Create<RedQueueDiscTestItem>(p5, dest, false));
187 queue->Enqueue(Create<RedQueueDiscTestItem>(p6, dest, false));
188 queue->Enqueue(Create<RedQueueDiscTestItem>(p7, dest, false));
189 queue->Enqueue(Create<RedQueueDiscTestItem>(p8, dest, false));
190 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
191 8 * modeSize,
192 "There should be eight packets in there");
193
195
196 item = queue->Dequeue();
197 NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the first packet");
198 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
199 7 * modeSize,
200 "There should be seven packets in there");
201 NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(), p1->GetUid(), "was this the first packet ?");
202
203 item = queue->Dequeue();
204 NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the second packet");
205 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
206 6 * modeSize,
207 "There should be six packet in there");
208 NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(),
209 p2->GetUid(),
210 "Was this the second packet ?");
211
212 item = queue->Dequeue();
213 NS_TEST_ASSERT_MSG_NE(item, nullptr, "I want to remove the third packet");
214 NS_TEST_ASSERT_MSG_EQ(queue->GetCurrentSize().GetValue(),
215 5 * modeSize,
216 "There should be five packets in there");
217 NS_TEST_ASSERT_MSG_EQ(item->GetPacket()->GetUid(), p3->GetUid(), "Was this the third packet ?");
218
219 item = queue->Dequeue();
220 item = queue->Dequeue();
221 item = queue->Dequeue();
222 item = queue->Dequeue();
223 item = queue->Dequeue();
224
225 item = queue->Dequeue();
226 NS_TEST_ASSERT_MSG_EQ(item, nullptr, "There are really no packets in there");
227
228 // test 2: more data, but with no drops
229 queue = CreateObject<RedQueueDisc>();
230 minTh = 70 * modeSize;
231 maxTh = 150 * modeSize;
232 qSize = 300 * modeSize;
233 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
234 true,
235 "Verify that we can actually set the attribute MinTh");
236 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
237 true,
238 "Verify that we can actually set the attribute MaxTh");
240 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
241 true,
242 "Verify that we can actually set the attribute MaxSize");
243 queue->Initialize();
244 Enqueue(queue, pktSize, 300, false);
245 QueueDisc::Stats st = queue->GetStats();
246 NS_TEST_ASSERT_MSG_EQ(st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP),
247 0,
248 "There should be zero unforced drops");
249 NS_TEST_ASSERT_MSG_EQ(st.GetNDroppedPackets(RedQueueDisc::FORCED_DROP),
250 0,
251 "There should be zero forced dropps");
252 NS_TEST_ASSERT_MSG_EQ(st.GetNDroppedPackets(QueueDisc::INTERNAL_QUEUE_DROP),
253 0,
254 "There should be zero drops due to queue limit");
255
256 // save number of drops from tests
257 struct d
258 {
259 uint32_t test3;
260 uint32_t test4;
261 uint32_t test5;
262 uint32_t test6;
263 uint32_t test7;
264 uint32_t test11;
265 uint32_t test12;
266 uint32_t test13;
267 } drop;
268
269 // test 3: more data, now drops due QW change
270 queue = CreateObject<RedQueueDisc>();
271 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
272 true,
273 "Verify that we can actually set the attribute MinTh");
274 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
275 true,
276 "Verify that we can actually set the attribute MaxTh");
278 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
279 true,
280 "Verify that we can actually set the attribute MaxSize");
281 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(0.020)),
282 true,
283 "Verify that we can actually set the attribute QW");
284 queue->Initialize();
285 Enqueue(queue, pktSize, 300, false);
286 st = queue->GetStats();
287 drop.test3 = st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP) +
288 st.GetNDroppedPackets(RedQueueDisc::FORCED_DROP) +
289 st.GetNDroppedPackets(QueueDisc::INTERNAL_QUEUE_DROP);
290 NS_TEST_ASSERT_MSG_NE(drop.test3, 0, "There should be some dropped packets");
291
292 // test 4: reduced maxTh, this causes more drops
293 maxTh = 100 * modeSize;
294 queue = CreateObject<RedQueueDisc>();
295 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
296 true,
297 "Verify that we can actually set the attribute MinTh");
298 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
299 true,
300 "Verify that we can actually set the attribute MaxTh");
302 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
303 true,
304 "Verify that we can actually set the attribute MaxSize");
305 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(0.020)),
306 true,
307 "Verify that we can actually set the attribute QW");
308 queue->Initialize();
309 Enqueue(queue, pktSize, 300, false);
310 st = queue->GetStats();
311 drop.test4 = st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP) +
312 st.GetNDroppedPackets(RedQueueDisc::FORCED_DROP) +
313 st.GetNDroppedPackets(QueueDisc::INTERNAL_QUEUE_DROP);
314 NS_TEST_ASSERT_MSG_GT(drop.test4, drop.test3, "Test 4 should have more drops than test 3");
315
316 // test 5: change drop probability to a high value (LInterm)
317 maxTh = 150 * modeSize;
318 queue = CreateObject<RedQueueDisc>();
319 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
320 true,
321 "Verify that we can actually set the attribute MinTh");
322 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
323 true,
324 "Verify that we can actually set the attribute MaxTh");
326 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
327 true,
328 "Verify that we can actually set the attribute MaxSize");
329 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(0.020)),
330 true,
331 "Verify that we can actually set the attribute QW");
332 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("LInterm", DoubleValue(5)),
333 true,
334 "Verify that we can actually set the attribute LInterm");
335 queue->Initialize();
336 Enqueue(queue, pktSize, 300, false);
337 st = queue->GetStats();
338 drop.test5 = st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP) +
339 st.GetNDroppedPackets(RedQueueDisc::FORCED_DROP) +
340 st.GetNDroppedPackets(QueueDisc::INTERNAL_QUEUE_DROP);
341 NS_TEST_ASSERT_MSG_GT(drop.test5, drop.test3, "Test 5 should have more drops than test 3");
342
343 // test 6: disable Gentle param
344 queue = CreateObject<RedQueueDisc>();
345 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
346 true,
347 "Verify that we can actually set the attribute MinTh");
348 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
349 true,
350 "Verify that we can actually set the attribute MaxTh");
352 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
353 true,
354 "Verify that we can actually set the attribute MaxSize");
355 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(0.020)),
356 true,
357 "Verify that we can actually set the attribute QW");
358 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Gentle", BooleanValue(false)),
359 true,
360 "Verify that we can actually set the attribute Gentle");
361 queue->Initialize();
362 Enqueue(queue, pktSize, 300, false);
363 st = queue->GetStats();
364 drop.test6 = st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP) +
365 st.GetNDroppedPackets(RedQueueDisc::FORCED_DROP) +
366 st.GetNDroppedPackets(QueueDisc::INTERNAL_QUEUE_DROP);
367 NS_TEST_ASSERT_MSG_GT(drop.test6, drop.test3, "Test 6 should have more drops than test 3");
368
369 // test 7: disable Wait param
370 queue = CreateObject<RedQueueDisc>();
371 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
372 true,
373 "Verify that we can actually set the attribute MinTh");
374 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
375 true,
376 "Verify that we can actually set the attribute MaxTh");
378 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
379 true,
380 "Verify that we can actually set the attribute MaxSize");
381 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(0.020)),
382 true,
383 "Verify that we can actually set the attribute QW");
384 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Wait", BooleanValue(false)),
385 true,
386 "Verify that we can actually set the attribute Wait");
387 queue->Initialize();
388 Enqueue(queue, pktSize, 300, false);
389 st = queue->GetStats();
390 drop.test7 = st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP) +
391 st.GetNDroppedPackets(RedQueueDisc::FORCED_DROP) +
392 st.GetNDroppedPackets(QueueDisc::INTERNAL_QUEUE_DROP);
393 NS_TEST_ASSERT_MSG_GT(drop.test7, drop.test3, "Test 7 should have more drops than test 3");
394
395 // test 8: RED queue disc is ECN enabled, but packets are not ECN capable
396 queue = CreateObject<RedQueueDisc>();
397 minTh = 30 * modeSize;
398 maxTh = 90 * modeSize;
399 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
400 true,
401 "Verify that we can actually set the attribute MinTh");
402 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
403 true,
404 "Verify that we can actually set the attribute MaxTh");
406 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
407 true,
408 "Verify that we can actually set the attribute MaxSize");
409 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(0.002)),
410 true,
411 "Verify that we can actually set the attribute QW");
412 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("LInterm", DoubleValue(2)),
413 true,
414 "Verify that we can actually set the attribute LInterm");
415 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Gentle", BooleanValue(true)),
416 true,
417 "Verify that we can actually set the attribute Gentle");
418 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(true)),
419 true,
420 "Verify that we can actually set the attribute UseECN");
421 queue->Initialize();
422 Enqueue(queue, pktSize, 300, false);
423 st = queue->GetStats();
424 // Packets are not ECN capable, so there should be only unforced drops, no unforced marks
425 NS_TEST_ASSERT_MSG_NE(st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP),
426 0,
427 "There should be some unforced drops");
428 NS_TEST_ASSERT_MSG_EQ(st.GetNMarkedPackets(RedQueueDisc::UNFORCED_MARK),
429 0,
430 "There should be no unforced marks");
431
432 // test 9: Packets are ECN capable, but RED queue disc is not ECN enabled
433 queue = CreateObject<RedQueueDisc>();
434 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
435 true,
436 "Verify that we can actually set the attribute MinTh");
437 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
438 true,
439 "Verify that we can actually set the attribute MaxTh");
441 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
442 true,
443 "Verify that we can actually set the attribute MaxSize");
444 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(0.002)),
445 true,
446 "Verify that we can actually set the attribute QW");
447 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("LInterm", DoubleValue(2)),
448 true,
449 "Verify that we can actually set the attribute LInterm");
450 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Gentle", BooleanValue(true)),
451 true,
452 "Verify that we can actually set the attribute Gentle");
453 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(false)),
454 true,
455 "Verify that we can actually set the attribute UseECN");
456 queue->Initialize();
457 Enqueue(queue, pktSize, 300, true);
458 st = queue->GetStats();
459 // RED queue disc is not ECN enabled, so there should be only unforced drops, no unforced marks
460 NS_TEST_ASSERT_MSG_NE(st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP),
461 0,
462 "There should be some unforced drops");
463 NS_TEST_ASSERT_MSG_EQ(st.GetNMarkedPackets(RedQueueDisc::UNFORCED_MARK),
464 0,
465 "There should be no unforced marks");
466
467 // test 10: Packets are ECN capable and RED queue disc is ECN enabled
468 queue = CreateObject<RedQueueDisc>();
469 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
470 true,
471 "Verify that we can actually set the attribute MinTh");
472 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
473 true,
474 "Verify that we can actually set the attribute MaxTh");
476 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
477 true,
478 "Verify that we can actually set the attribute MaxSize");
479 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(0.002)),
480 true,
481 "Verify that we can actually set the attribute QW");
482 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("LInterm", DoubleValue(2)),
483 true,
484 "Verify that we can actually set the attribute LInterm");
485 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Gentle", BooleanValue(true)),
486 true,
487 "Verify that we can actually set the attribute Gentle");
488 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("UseEcn", BooleanValue(true)),
489 true,
490 "Verify that we can actually set the attribute UseECN");
491 queue->Initialize();
492 Enqueue(queue, pktSize, 300, true);
493 st = queue->GetStats();
494 // Packets are ECN capable, RED queue disc is ECN enabled; there should be only unforced marks,
495 // no unforced drops
496 NS_TEST_ASSERT_MSG_EQ(st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP),
497 0,
498 "There should be no unforced drops");
499 NS_TEST_ASSERT_MSG_NE(st.GetNMarkedPackets(RedQueueDisc::UNFORCED_MARK),
500 0,
501 "There should be some unforced marks");
502
503 // test 11: RED with default parameter settings, linear drop probability and fixed m_curMaxP
504 queue = CreateObject<RedQueueDisc>();
505 minTh = 30 * modeSize;
506 maxTh = 90 * modeSize;
507 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
508 true,
509 "Verify that we can actually set the attribute MinTh");
510 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
511 true,
512 "Verify that we can actually set the attribute MaxTh");
514 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
515 true,
516 "Verify that we can actually set the attribute MaxSize");
517 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(0.002)),
518 true,
519 "Verify that we can actually set the attribute QW");
520 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("LInterm", DoubleValue(2)),
521 true,
522 "Verify that we can actually set the attribute LInterm");
523 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Gentle", BooleanValue(true)),
524 true,
525 "Verify that we can actually set the attribute Gentle");
526 queue->Initialize();
527 Enqueue(queue, pktSize, 300, false);
528 st = queue->GetStats();
529 drop.test11 = st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP);
530 NS_TEST_ASSERT_MSG_NE(drop.test11,
531 0,
532 "There should some dropped packets due to probability mark");
533
534 // test 12: Feng's Adaptive RED with default parameter settings and varying m_curMaxP
535 queue = CreateObject<RedQueueDisc>();
536 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
537 true,
538 "Verify that we can actually set the attribute MinTh");
539 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
540 true,
541 "Verify that we can actually set the attribute MaxTh");
543 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
544 true,
545 "Verify that we can actually set the attribute MaxSize");
546 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(0.002)),
547 true,
548 "Verify that we can actually set the attribute QW");
549 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("LInterm", DoubleValue(2)),
550 true,
551 "Verify that we can actually set the attribute LInterm");
552 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Gentle", BooleanValue(true)),
553 true,
554 "Verify that we can actually set the attribute Gentle");
555 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("FengAdaptive", BooleanValue(true)),
556 true,
557 "Verify that we can actually set the attribute FengAdaptive");
558 queue->Initialize();
559 Enqueue(queue, pktSize, 300, false);
560 st = queue->GetStats();
561 drop.test12 = st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP);
562 NS_TEST_ASSERT_MSG_LT(drop.test12,
563 drop.test11,
564 "Test 12 should have less drops due to probability mark than test 11");
565
566 // test 13: RED with Nonlinear drop probability
567 queue = CreateObject<RedQueueDisc>();
568 minTh = 30 * modeSize;
569 maxTh = 90 * modeSize;
570 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MinTh", DoubleValue(minTh)),
571 true,
572 "Verify that we can actually set the attribute MinTh");
573 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("MaxTh", DoubleValue(maxTh)),
574 true,
575 "Verify that we can actually set the attribute MaxTh");
577 queue->SetAttributeFailSafe("MaxSize", QueueSizeValue(QueueSize(mode, qSize))),
578 true,
579 "Verify that we can actually set the attribute MaxSize");
580 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("QW", DoubleValue(0.002)),
581 true,
582 "Verify that we can actually set the attribute QW");
583 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("LInterm", DoubleValue(2)),
584 true,
585 "Verify that we can actually set the attribute LInterm");
586 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("Gentle", BooleanValue(true)),
587 true,
588 "Verify that we can actually set the attribute Gentle");
589 NS_TEST_ASSERT_MSG_EQ(queue->SetAttributeFailSafe("NLRED", BooleanValue(true)),
590 true,
591 "Verify that we can actually set the attribute NLRED");
592 queue->Initialize();
593 Enqueue(queue, pktSize, 300, false);
594 st = queue->GetStats();
595 drop.test13 = st.GetNDroppedPackets(RedQueueDisc::UNFORCED_DROP);
596 NS_TEST_ASSERT_MSG_LT(drop.test13,
597 drop.test11,
598 "Test 13 should have less drops due to probability mark than test 11");
599}
600
601void
603 uint32_t size,
604 uint32_t nPkt,
605 bool ecnCapable)
606{
607 Address dest;
608 for (uint32_t i = 0; i < nPkt; i++)
609 {
610 queue->Enqueue(Create<RedQueueDiscTestItem>(Create<Packet>(size), dest, ecnCapable));
611 }
612}
613
614void
616{
619 Simulator::Destroy();
620}
621
628static class RedQueueDiscTestSuite : public TestSuite
629{
630 public:
632 : TestSuite("red-queue-disc", UNIT)
633 {
634 AddTestCase(new RedQueueDiscTestCase(), TestCase::QUICK);
635 }
Red Queue Disc Test Case.
void RunRedTest(QueueSizeUnit mode)
Run RED test function.
void Enqueue(Ptr< RedQueueDisc > queue, uint32_t size, uint32_t nPkt, bool ecnCapable)
Enqueue function.
void DoRun() override
Implementation to actually run this TestCase.
Red Queue Disc Test Item.
void AddHeader() override
Add the header to the packet.
RedQueueDiscTestItem & operator=(const RedQueueDiscTestItem &)=delete
RedQueueDiscTestItem()=delete
bool Mark() override
Marks the packet as a substitute for dropping it, such as for Explicit Congestion Notification.
RedQueueDiscTestItem(const RedQueueDiscTestItem &)=delete
bool m_ecnCapablePacket
ECN capable packet?
Red Queue Disc Test Suite.
a polymophic address class
Definition: address.h:92
AttributeValue implementation for Boolean.
Definition: boolean.h:37
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
uint64_t GetUid() const
Returns the packet's Uid.
Definition: packet.cc:412
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
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
#define NS_TEST_ASSERT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report and abort if not.
Definition: test.h:874
RedQueueDiscTestSuite g_redQueueTestSuite
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 GetNMarkedPackets(std::string reason) const
Get the number of packets marked for the given reason.
Definition: queue-disc.cc:153
uint32_t pktSize
packet size used for the simulation (in bytes)