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 
31 using 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 
68 void
70 {
71 }
72 
73 bool
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 
115 void
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 
192  Ptr<QueueDiscItem> item;
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 
599 void
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 
612 void
614 {
617  Simulator::Destroy();
618 }
619 
625 static 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)