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