A Discrete-Event Network Simulator
API
red-queue-disc-test-suite.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright © 2011 Marcos Talau
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Marcos Talau (talau@users.sourceforge.net)
19  * Modified by: Pasquale Imputato <p.imputato@gmail.com>
20  *
21  */
22 
23 #include "ns3/test.h"
24 #include "ns3/red-queue-disc.h"
25 #include "ns3/packet.h"
26 #include "ns3/uinteger.h"
27 #include "ns3/string.h"
28 #include "ns3/double.h"
29 #include "ns3/log.h"
30 #include "ns3/simulator.h"
31 
32 using namespace ns3;
33 
41 public:
49  RedQueueDiscTestItem (Ptr<Packet> p, const Address & addr, bool ecnCapable);
50  virtual ~RedQueueDiscTestItem ();
51 
52  // Delete copy constructor and assignment operator to avoid misuse
54  RedQueueDiscTestItem & operator = (const RedQueueDiscTestItem &) = delete;
55 
56  virtual void AddHeader (void);
57  virtual bool Mark(void);
58 
59 private:
61 
63 };
64 
66  : QueueDiscItem (p, addr, 0),
67  m_ecnCapablePacket (ecnCapable)
68 {
69 }
70 
72 {
73 }
74 
75 void
77 {
78 }
79 
80 bool
82 {
84  {
85  return true;
86  }
87  return false;
88 }
89 
97 {
98 public:
100  virtual void DoRun (void);
101 private:
109  void Enqueue (Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt, bool ecnCapable);
114  void RunRedTest (QueueSizeUnit mode);
115 };
116 
118  : TestCase ("Sanity check on the red queue implementation")
119 {
120 }
121 
122 void
124 {
125  uint32_t pktSize = 0;
126  // 1 for packets; pktSize for bytes
127  uint32_t modeSize = 1;
128  double minTh = 2;
129  double maxTh = 5;
130  uint32_t qSize = 8;
131  Ptr<RedQueueDisc> queue = CreateObject<RedQueueDisc> ();
132 
133  // test 1: simple enqueue/dequeue with no drops
134  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
135  "Verify that we can actually set the attribute MinTh");
136  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
137  "Verify that we can actually set the attribute MaxTh");
138  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
139  true, "Verify that we can actually set the attribute MaxSize");
140  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), 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 mode
148  pktSize = 500;
149  modeSize = pktSize;
150  queue->SetTh (minTh * modeSize, maxTh * modeSize);
151  queue->SetMaxSize (QueueSize (mode, qSize * modeSize));
152  }
153 
154  Ptr<Packet> p1, p2, p3, p4, p5, p6, p7, p8;
155  p1 = Create<Packet> (pktSize);
156  p2 = Create<Packet> (pktSize);
157  p3 = Create<Packet> (pktSize);
158  p4 = Create<Packet> (pktSize);
159  p5 = Create<Packet> (pktSize);
160  p6 = Create<Packet> (pktSize);
161  p7 = Create<Packet> (pktSize);
162  p8 = Create<Packet> (pktSize);
163 
164  queue->Initialize ();
165  NS_TEST_ASSERT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 0 * modeSize, "There should be no packets in there");
166  queue->Enqueue (Create<RedQueueDiscTestItem> (p1, dest, false));
167  NS_TEST_ASSERT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 1 * modeSize, "There should be one packet in there");
168  queue->Enqueue (Create<RedQueueDiscTestItem> (p2, dest, false));
169  NS_TEST_ASSERT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 2 * modeSize, "There should be two packets in there");
170  queue->Enqueue (Create<RedQueueDiscTestItem> (p3, dest, false));
171  queue->Enqueue (Create<RedQueueDiscTestItem> (p4, dest, false));
172  queue->Enqueue (Create<RedQueueDiscTestItem> (p5, dest, false));
173  queue->Enqueue (Create<RedQueueDiscTestItem> (p6, dest, false));
174  queue->Enqueue (Create<RedQueueDiscTestItem> (p7, dest, false));
175  queue->Enqueue (Create<RedQueueDiscTestItem> (p8, dest, false));
176  NS_TEST_ASSERT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 8 * modeSize, "There should be eight packets in there");
177 
178  Ptr<QueueDiscItem> item;
179 
180  item = queue->Dequeue ();
181  NS_TEST_ASSERT_MSG_EQ ((item != 0), true, "I want to remove the first packet");
182  NS_TEST_ASSERT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 7 * modeSize, "There should be seven packets in there");
183  NS_TEST_ASSERT_MSG_EQ (item->GetPacket ()->GetUid (), p1->GetUid (), "was this the first packet ?");
184 
185  item = queue->Dequeue ();
186  NS_TEST_ASSERT_MSG_EQ ((item != 0), true, "I want to remove the second packet");
187  NS_TEST_ASSERT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 6 * modeSize, "There should be six packet in there");
188  NS_TEST_ASSERT_MSG_EQ (item->GetPacket ()->GetUid (), p2->GetUid (), "Was this the second packet ?");
189 
190  item = queue->Dequeue ();
191  NS_TEST_ASSERT_MSG_EQ ((item != 0), true, "I want to remove the third packet");
192  NS_TEST_ASSERT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 5 * modeSize, "There should be five packets in there");
193  NS_TEST_ASSERT_MSG_EQ (item->GetPacket ()->GetUid (), p3->GetUid (), "Was this the third packet ?");
194 
195  item = queue->Dequeue ();
196  item = queue->Dequeue ();
197  item = queue->Dequeue ();
198  item = queue->Dequeue ();
199  item = queue->Dequeue ();
200 
201  item = queue->Dequeue ();
202  NS_TEST_ASSERT_MSG_EQ ((item == 0), true, "There are really no packets in there");
203 
204 
205  // test 2: more data, but with no drops
206  queue = CreateObject<RedQueueDisc> ();
207  minTh = 70 * modeSize;
208  maxTh = 150 * modeSize;
209  qSize = 300 * modeSize;
210  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
211  "Verify that we can actually set the attribute MinTh");
212  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
213  "Verify that we can actually set the attribute MaxTh");
214  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
215  true, "Verify that we can actually set the attribute MaxSize");
216  queue->Initialize ();
217  Enqueue (queue, pktSize, 300, false);
218  QueueDisc::Stats st = queue->GetStats ();
219  NS_TEST_ASSERT_MSG_EQ (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
220  "There should be zero unforced drops");
221  NS_TEST_ASSERT_MSG_EQ (st.GetNDroppedPackets (RedQueueDisc::FORCED_DROP), 0,
222  "There should be zero forced dropps");
223  NS_TEST_ASSERT_MSG_EQ (st.GetNDroppedPackets (QueueDisc::INTERNAL_QUEUE_DROP), 0,
224  "There should be zero drops due to queue limit");
225 
226  // save number of drops from tests
227  struct d {
228  uint32_t test3;
229  uint32_t test4;
230  uint32_t test5;
231  uint32_t test6;
232  uint32_t test7;
233  uint32_t test11;
234  uint32_t test12;
235  uint32_t test13;
236  } drop;
237 
238 
239  // test 3: more data, now drops due QW change
240  queue = CreateObject<RedQueueDisc> ();
241  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
242  "Verify that we can actually set the attribute MinTh");
243  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
244  "Verify that we can actually set the attribute MaxTh");
245  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
246  true, "Verify that we can actually set the attribute MaxSize");
247  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
248  "Verify that we can actually set the attribute QW");
249  queue->Initialize ();
250  Enqueue (queue, pktSize, 300, false);
251  st = queue->GetStats ();
252  drop.test3 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP)
253  + st.GetNDroppedPackets (RedQueueDisc::FORCED_DROP)
254  + st.GetNDroppedPackets (QueueDisc::INTERNAL_QUEUE_DROP);
255  NS_TEST_ASSERT_MSG_NE (drop.test3, 0, "There should be some dropped packets");
256 
257 
258  // test 4: reduced maxTh, this causes more drops
259  maxTh = 100 * modeSize;
260  queue = CreateObject<RedQueueDisc> ();
261  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
262  "Verify that we can actually set the attribute MinTh");
263  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
264  "Verify that we can actually set the attribute MaxTh");
265  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
266  true, "Verify that we can actually set the attribute MaxSize");
267  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
268  "Verify that we can actually set the attribute QW");
269  queue->Initialize ();
270  Enqueue (queue, pktSize, 300, false);
271  st = queue->GetStats ();
272  drop.test4 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP)
273  + st.GetNDroppedPackets (RedQueueDisc::FORCED_DROP)
274  + st.GetNDroppedPackets (QueueDisc::INTERNAL_QUEUE_DROP);
275  NS_TEST_ASSERT_MSG_GT (drop.test4, drop.test3, "Test 4 should have more drops than test 3");
276 
277 
278  // test 5: change drop probability to a high value (LInterm)
279  maxTh = 150 * modeSize;
280  queue = CreateObject<RedQueueDisc> ();
281  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
282  "Verify that we can actually set the attribute MinTh");
283  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
284  "Verify that we can actually set the attribute MaxTh");
285  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
286  true, "Verify that we can actually set the attribute MaxSize");
287  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
288  "Verify that we can actually set the attribute QW");
289  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (5)), true,
290  "Verify that we can actually set the attribute LInterm");
291  queue->Initialize ();
292  Enqueue (queue, pktSize, 300, false);
293  st = queue->GetStats ();
294  drop.test5 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP)
295  + st.GetNDroppedPackets (RedQueueDisc::FORCED_DROP)
296  + st.GetNDroppedPackets (QueueDisc::INTERNAL_QUEUE_DROP);
297  NS_TEST_ASSERT_MSG_GT (drop.test5, drop.test3, "Test 5 should have more drops than test 3");
298 
299 
300  // test 6: disable Gentle param
301  queue = CreateObject<RedQueueDisc> ();
302  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
303  "Verify that we can actually set the attribute MinTh");
304  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
305  "Verify that we can actually set the attribute MaxTh");
306  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
307  true, "Verify that we can actually set the attribute MaxSize");
308  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
309  "Verify that we can actually set the attribute QW");
310  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (false)), true,
311  "Verify that we can actually set the attribute Gentle");
312  queue->Initialize ();
313  Enqueue (queue, pktSize, 300, false);
314  st = queue->GetStats ();
315  drop.test6 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP)
316  + st.GetNDroppedPackets (RedQueueDisc::FORCED_DROP)
317  + st.GetNDroppedPackets (QueueDisc::INTERNAL_QUEUE_DROP);
318  NS_TEST_ASSERT_MSG_GT (drop.test6, drop.test3, "Test 6 should have more drops than test 3");
319 
320 
321  // test 7: disable Wait param
322  queue = CreateObject<RedQueueDisc> ();
323  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
324  "Verify that we can actually set the attribute MinTh");
325  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
326  "Verify that we can actually set the attribute MaxTh");
327  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
328  true, "Verify that we can actually set the attribute MaxSize");
329  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
330  "Verify that we can actually set the attribute QW");
331  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("Wait", BooleanValue (false)), true,
332  "Verify that we can actually set the attribute Wait");
333  queue->Initialize ();
334  Enqueue (queue, pktSize, 300, false);
335  st = queue->GetStats ();
336  drop.test7 = 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.test7, drop.test3, "Test 7 should have more drops than test 3");
340 
341 
342  // test 8: RED queue disc is ECN enabled, but packets are not ECN capable
343  queue = CreateObject<RedQueueDisc> ();
344  minTh = 30 * modeSize;
345  maxTh = 90 * modeSize;
346  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
347  "Verify that we can actually set the attribute MinTh");
348  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
349  "Verify that we can actually set the attribute MaxTh");
350  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
351  true, "Verify that we can actually set the attribute MaxSize");
352  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
353  "Verify that we can actually set the attribute QW");
354  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
355  "Verify that we can actually set the attribute LInterm");
356  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (true)), true,
357  "Verify that we can actually set the attribute Gentle");
358  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (true)), true,
359  "Verify that we can actually set the attribute UseECN");
360  queue->Initialize ();
361  Enqueue (queue, pktSize, 300, false);
362  st = queue->GetStats ();
363  // Packets are not ECN capable, so there should be only unforced drops, no unforced marks
364  NS_TEST_ASSERT_MSG_NE (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
365  "There should be some unforced drops");
366  NS_TEST_ASSERT_MSG_EQ (st.GetNMarkedPackets (RedQueueDisc::UNFORCED_MARK), 0,
367  "There should be no unforced marks");
368 
369 
370  // test 9: Packets are ECN capable, but RED queue disc is not ECN enabled
371  queue = CreateObject<RedQueueDisc> ();
372  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
373  "Verify that we can actually set the attribute MinTh");
374  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
375  "Verify that we can actually set the attribute MaxTh");
376  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
377  true, "Verify that we can actually set the attribute MaxSize");
378  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
379  "Verify that we can actually set the attribute QW");
380  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
381  "Verify that we can actually set the attribute LInterm");
382  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (true)), true,
383  "Verify that we can actually set the attribute Gentle");
384  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (false)), true,
385  "Verify that we can actually set the attribute UseECN");
386  queue->Initialize ();
387  Enqueue (queue, pktSize, 300, true);
388  st = queue->GetStats ();
389  // RED queue disc is not ECN enabled, so there should be only unforced drops, no unforced marks
390  NS_TEST_ASSERT_MSG_NE (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
391  "There should be some unforced drops");
392  NS_TEST_ASSERT_MSG_EQ (st.GetNMarkedPackets (RedQueueDisc::UNFORCED_MARK), 0,
393  "There should be no unforced marks");
394 
395 
396  // test 10: Packets are ECN capable and RED queue disc is ECN enabled
397  queue = CreateObject<RedQueueDisc> ();
398  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
399  "Verify that we can actually set the attribute MinTh");
400  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
401  "Verify that we can actually set the attribute MaxTh");
402  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
403  true, "Verify that we can actually set the attribute MaxSize");
404  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
405  "Verify that we can actually set the attribute QW");
406  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
407  "Verify that we can actually set the attribute LInterm");
408  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (true)), true,
409  "Verify that we can actually set the attribute Gentle");
410  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (true)), true,
411  "Verify that we can actually set the attribute UseECN");
412  queue->Initialize ();
413  Enqueue (queue, pktSize, 300, true);
414  st = queue->GetStats ();
415  // Packets are ECN capable, RED queue disc is ECN enabled; there should be only unforced marks, no unforced drops
416  NS_TEST_ASSERT_MSG_EQ (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
417  "There should be no unforced drops");
418  NS_TEST_ASSERT_MSG_NE (st.GetNMarkedPackets (RedQueueDisc::UNFORCED_MARK), 0,
419  "There should be some unforced marks");
420 
421 
422  // test 11: RED with default parameter settings, linear drop probability and fixed m_curMaxP
423  queue = CreateObject<RedQueueDisc> ();
424  minTh = 30 * modeSize;
425  maxTh = 90 * modeSize;
426  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
427  "Verify that we can actually set the attribute MinTh");
428  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
429  "Verify that we can actually set the attribute MaxTh");
430  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
431  true, "Verify that we can actually set the attribute MaxSize");
432  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
433  "Verify that we can actually set the attribute QW");
434  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
435  "Verify that we can actually set the attribute LInterm");
436  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (true)), true,
437  "Verify that we can actually set the attribute Gentle");
438  queue->Initialize ();
439  Enqueue (queue, pktSize, 300, false);
440  st = queue->GetStats ();
441  drop.test11 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
442  NS_TEST_ASSERT_MSG_NE (drop.test11, 0, "There should some dropped packets due to probability mark");
443 
444 
445  // test 12: Feng's Adaptive RED with default parameter settings and varying m_curMaxP
446  queue = CreateObject<RedQueueDisc> ();
447  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
448  "Verify that we can actually set the attribute MinTh");
449  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
450  "Verify that we can actually set the attribute MaxTh");
451  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
452  true, "Verify that we can actually set the attribute MaxSize");
453  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
454  "Verify that we can actually set the attribute QW");
455  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
456  "Verify that we can actually set the attribute LInterm");
457  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (true)), true,
458  "Verify that we can actually set the attribute Gentle");
459  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("FengAdaptive", BooleanValue (true)), true,
460  "Verify that we can actually set the attribute FengAdaptive");
461  queue->Initialize ();
462  Enqueue (queue, pktSize, 300, false);
463  st = queue->GetStats ();
464  drop.test12 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
465  NS_TEST_ASSERT_MSG_LT (drop.test12, drop.test11, "Test 12 should have less drops due to probability mark than test 11");
466 
467 
468  // test 13: RED with Nonlinear drop probability
469  queue = CreateObject<RedQueueDisc> ();
470  minTh = 30 * modeSize;
471  maxTh = 90 * modeSize;
472  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
473  "Verify that we can actually set the attribute MinTh");
474  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
475  "Verify that we can actually set the attribute MaxTh");
476  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
477  true, "Verify that we can actually set the attribute MaxSize");
478  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
479  "Verify that we can actually set the attribute QW");
480  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
481  "Verify that we can actually set the attribute LInterm");
482  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (true)), true,
483  "Verify that we can actually set the attribute Gentle");
484  NS_TEST_ASSERT_MSG_EQ (queue->SetAttributeFailSafe ("NLRED", BooleanValue (true)), true,
485  "Verify that we can actually set the attribute NLRED");
486  queue->Initialize ();
487  Enqueue (queue, pktSize, 300, false);
488  st = queue->GetStats ();
489  drop.test13 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
490  NS_TEST_ASSERT_MSG_LT (drop.test13, drop.test11, "Test 13 should have less drops due to probability mark than test 11");
491 
492 }
493 
494 void
495 RedQueueDiscTestCase::Enqueue (Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt, bool ecnCapable)
496 {
497  Address dest;
498  for (uint32_t i = 0; i < nPkt; i++)
499  {
500  queue->Enqueue (Create<RedQueueDiscTestItem> (Create<Packet> (size), dest, ecnCapable));
501  }
502 }
503 
504 void
506 {
509  Simulator::Destroy ();
510 
511 }
512 
519 static class RedQueueDiscTestSuite : public TestSuite
520 {
521 public:
523  : TestSuite ("red-queue-disc", UNIT)
524  {
525  AddTestCase (new RedQueueDiscTestCase (), TestCase::QUICK);
526  }
Red Queue Disc Test Case.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void RunRedTest(QueueSizeUnit mode)
Run RED test function.
void Enqueue(Ptr< RedQueueDisc > queue, uint32_t size, uint32_t nPkt, bool ecnCapable)
Enqueue function.
Red Queue Disc Test Item.
virtual void AddHeader(void)
Add the header to the packet.
RedQueueDiscTestItem(const RedQueueDiscTestItem &)=delete
bool m_ecnCapablePacket
ECN capable packet?
virtual bool Mark(void)
Marks the packet as a substitute for dropping it, such as for Explicit Congestion Notification.
Red Queue Disc Test Suite.
a polymophic address class
Definition: address.h:91
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:41
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:390
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:95
AttributeValue implementation for QueueSize.
Definition: queue-size.h:221
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1197
QueueSizeUnit
Enumeration of the operating modes of queues.
Definition: queue-size.h:43
@ BYTES
Use number of bytes for queue size.
Definition: queue-size.h:45
@ PACKETS
Use number of packets for queue size.
Definition: queue-size.h:44
#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:675
#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:141
#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:542
#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:825
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:186
uint32_t GetNDroppedPackets(std::string reason) const
Get the number of packets dropped for the given reason.
Definition: queue-disc.cc:109
uint32_t GetNMarkedPackets(std::string reason) const
Get the number of packets marked for the given reason.
Definition: queue-disc.cc:151
uint32_t pktSize
packet size used for the simulation (in bytes)
Definition: wifi-bianchi.cc:89