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