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:
50  RedQueueDiscTestItem (Ptr<Packet> p, const Address & addr, uint16_t protocol, bool ecnCapable);
51  virtual ~RedQueueDiscTestItem ();
52  virtual void AddHeader (void);
53  virtual bool Mark(void);
54 
55 private:
67  RedQueueDiscTestItem &operator = (const RedQueueDiscTestItem &);
69 };
70 
71 RedQueueDiscTestItem::RedQueueDiscTestItem (Ptr<Packet> p, const Address & addr, uint16_t protocol, bool ecnCapable)
72  : QueueDiscItem (p, addr, protocol),
73  m_ecnCapablePacket (ecnCapable)
74 {
75 }
76 
78 {
79 }
80 
81 void
83 {
84 }
85 
86 bool
88 {
90  {
91  return true;
92  }
93  return false;
94 }
95 
103 {
104 public:
106  virtual void DoRun (void);
107 private:
115  void Enqueue (Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt, bool ecnCapable);
120  void RunRedTest (StringValue mode);
121 };
122 
124  : TestCase ("Sanity check on the red queue implementation")
125 {
126 }
127 
128 void
130 {
131  uint32_t pktSize = 0;
132  // 1 for packets; pktSize for bytes
133  uint32_t modeSize = 1;
134  double minTh = 2;
135  double maxTh = 5;
136  uint32_t qSize = 8;
137  Ptr<RedQueueDisc> queue = CreateObject<RedQueueDisc> ();
138 
139  // test 1: simple enqueue/dequeue with no drops
140  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
141  "Verify that we can actually set the attribute Mode");
142  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
143  "Verify that we can actually set the attribute MinTh");
144  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
145  "Verify that we can actually set the attribute MaxTh");
146  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
147  "Verify that we can actually set the attribute QueueLimit");
148  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
149  "Verify that we can actually set the attribute QW");
150 
151  Address dest;
152 
153  if (queue->GetMode () == RedQueueDisc::QUEUE_DISC_MODE_BYTES)
154  {
155  // pktSize should be same as MeanPktSize to avoid performance gap between byte and packet mode
156  pktSize = 500;
157  modeSize = pktSize;
158  queue->SetTh (minTh * modeSize, maxTh * modeSize);
159  queue->SetQueueLimit (qSize * modeSize);
160  }
161 
162  Ptr<Packet> p1, p2, p3, p4, p5, p6, p7, p8;
163  p1 = Create<Packet> (pktSize);
164  p2 = Create<Packet> (pktSize);
165  p3 = Create<Packet> (pktSize);
166  p4 = Create<Packet> (pktSize);
167  p5 = Create<Packet> (pktSize);
168  p6 = Create<Packet> (pktSize);
169  p7 = Create<Packet> (pktSize);
170  p8 = Create<Packet> (pktSize);
171 
172  queue->Initialize ();
173  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 0 * modeSize, "There should be no packets in there");
174  queue->Enqueue (Create<RedQueueDiscTestItem> (p1, dest, 0, false));
175  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 1 * modeSize, "There should be one packet in there");
176  queue->Enqueue (Create<RedQueueDiscTestItem> (p2, dest, 0, false));
177  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 2 * modeSize, "There should be two packets in there");
178  queue->Enqueue (Create<RedQueueDiscTestItem> (p3, dest, 0, false));
179  queue->Enqueue (Create<RedQueueDiscTestItem> (p4, dest, 0, false));
180  queue->Enqueue (Create<RedQueueDiscTestItem> (p5, dest, 0, false));
181  queue->Enqueue (Create<RedQueueDiscTestItem> (p6, dest, 0, false));
182  queue->Enqueue (Create<RedQueueDiscTestItem> (p7, dest, 0, false));
183  queue->Enqueue (Create<RedQueueDiscTestItem> (p8, dest, 0, false));
184  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 8 * modeSize, "There should be eight packets in there");
185 
186  Ptr<QueueDiscItem> item;
187 
188  item = queue->Dequeue ();
189  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the first packet");
190  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 7 * modeSize, "There should be seven packets in there");
191  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p1->GetUid (), "was this the first packet ?");
192 
193  item = queue->Dequeue ();
194  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the second packet");
195  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 6 * modeSize, "There should be six packet in there");
196  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p2->GetUid (), "Was this the second packet ?");
197 
198  item = queue->Dequeue ();
199  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the third packet");
200  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 5 * modeSize, "There should be five packets in there");
201  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p3->GetUid (), "Was this the third packet ?");
202 
203  item = queue->Dequeue ();
204  item = queue->Dequeue ();
205  item = queue->Dequeue ();
206  item = queue->Dequeue ();
207  item = queue->Dequeue ();
208 
209  item = queue->Dequeue ();
210  NS_TEST_EXPECT_MSG_EQ ((item == 0), true, "There are really no packets in there");
211 
212 
213  // test 2: more data, but with no drops
214  queue = CreateObject<RedQueueDisc> ();
215  minTh = 70 * modeSize;
216  maxTh = 150 * modeSize;
217  qSize = 300 * modeSize;
218  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
219  "Verify that we can actually set the attribute Mode");
220  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
221  "Verify that we can actually set the attribute MinTh");
222  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
223  "Verify that we can actually set the attribute MaxTh");
224  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
225  "Verify that we can actually set the attribute QueueLimit");
226  queue->Initialize ();
227  Enqueue (queue, pktSize, 300, false);
228  QueueDisc::Stats st = queue->GetStats ();
229  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
230  "There should be zero unforced drops");
231  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (RedQueueDisc::FORCED_DROP), 0,
232  "There should be zero forced dropps");
233  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (QueueDisc::INTERNAL_QUEUE_DROP), 0,
234  "There should be zero drops due to queue limit");
235 
236  // save number of drops from tests
237  struct d {
238  uint32_t test3;
239  uint32_t test4;
240  uint32_t test5;
241  uint32_t test6;
242  uint32_t test7;
243  uint32_t test11;
244  uint32_t test12;
245  uint32_t test13;
246  } drop;
247 
248 
249  // test 3: more data, now drops due QW change
250  queue = CreateObject<RedQueueDisc> ();
251  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
252  "Verify that we can actually set the attribute Mode");
253  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
254  "Verify that we can actually set the attribute MinTh");
255  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
256  "Verify that we can actually set the attribute MaxTh");
257  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
258  "Verify that we can actually set the attribute QueueLimit");
259  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
260  "Verify that we can actually set the attribute QW");
261  queue->Initialize ();
262  Enqueue (queue, pktSize, 300, false);
263  st = queue->GetStats ();
264  drop.test3 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP)
265  + st.GetNDroppedPackets (RedQueueDisc::FORCED_DROP)
266  + st.GetNDroppedPackets (QueueDisc::INTERNAL_QUEUE_DROP);
267  NS_TEST_EXPECT_MSG_NE (drop.test3, 0, "There should be some dropped packets");
268 
269 
270  // test 4: reduced maxTh, this causes more drops
271  maxTh = 100 * modeSize;
272  queue = CreateObject<RedQueueDisc> ();
273  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
274  "Verify that we can actually set the attribute Mode");
275  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
276  "Verify that we can actually set the attribute MinTh");
277  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
278  "Verify that we can actually set the attribute MaxTh");
279  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
280  "Verify that we can actually set the attribute QueueLimit");
281  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
282  "Verify that we can actually set the attribute QW");
283  queue->Initialize ();
284  Enqueue (queue, pktSize, 300, false);
285  st = queue->GetStats ();
286  drop.test4 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP)
287  + st.GetNDroppedPackets (RedQueueDisc::FORCED_DROP)
288  + st.GetNDroppedPackets (QueueDisc::INTERNAL_QUEUE_DROP);
289  NS_TEST_EXPECT_MSG_GT (drop.test4, drop.test3, "Test 4 should have more drops than test 3");
290 
291 
292  // test 5: change drop probability to a high value (LInterm)
293  maxTh = 150 * modeSize;
294  queue = CreateObject<RedQueueDisc> ();
295  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
296  "Verify that we can actually set the attribute Mode");
297  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
298  "Verify that we can actually set the attribute MinTh");
299  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
300  "Verify that we can actually set the attribute MaxTh");
301  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
302  "Verify that we can actually set the attribute QueueLimit");
303  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
304  "Verify that we can actually set the attribute QW");
305  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (5)), true,
306  "Verify that we can actually set the attribute LInterm");
307  queue->Initialize ();
308  Enqueue (queue, pktSize, 300, false);
309  st = queue->GetStats ();
310  drop.test5 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP)
311  + st.GetNDroppedPackets (RedQueueDisc::FORCED_DROP)
312  + st.GetNDroppedPackets (QueueDisc::INTERNAL_QUEUE_DROP);
313  NS_TEST_EXPECT_MSG_GT (drop.test5, drop.test3, "Test 5 should have more drops than test 3");
314 
315 
316  // test 6: disable Gentle param
317  queue = CreateObject<RedQueueDisc> ();
318  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
319  "Verify that we can actually set the attribute Mode");
320  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
321  "Verify that we can actually set the attribute MinTh");
322  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
323  "Verify that we can actually set the attribute MaxTh");
324  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
325  "Verify that we can actually set the attribute QueueLimit");
326  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
327  "Verify that we can actually set the attribute QW");
328  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (false)), true,
329  "Verify that we can actually set the attribute Gentle");
330  queue->Initialize ();
331  Enqueue (queue, pktSize, 300, false);
332  st = queue->GetStats ();
333  drop.test6 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP)
334  + st.GetNDroppedPackets (RedQueueDisc::FORCED_DROP)
335  + st.GetNDroppedPackets (QueueDisc::INTERNAL_QUEUE_DROP);
336  NS_TEST_EXPECT_MSG_GT (drop.test6, drop.test3, "Test 6 should have more drops than test 3");
337 
338 
339  // test 7: disable Wait param
340  queue = CreateObject<RedQueueDisc> ();
341  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
342  "Verify that we can actually set the attribute Mode");
343  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
344  "Verify that we can actually set the attribute MinTh");
345  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
346  "Verify that we can actually set the attribute MaxTh");
347  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
348  "Verify that we can actually set the attribute QueueLimit");
349  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
350  "Verify that we can actually set the attribute QW");
351  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Wait", BooleanValue (false)), true,
352  "Verify that we can actually set the attribute Wait");
353  queue->Initialize ();
354  Enqueue (queue, pktSize, 300, false);
355  st = queue->GetStats ();
356  drop.test7 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP)
357  + st.GetNDroppedPackets (RedQueueDisc::FORCED_DROP)
358  + st.GetNDroppedPackets (QueueDisc::INTERNAL_QUEUE_DROP);
359  NS_TEST_EXPECT_MSG_GT (drop.test7, drop.test3, "Test 7 should have more drops than test 3");
360 
361 
362  // test 8: RED queue disc is ECN enabled, but packets are not ECN capable
363  queue = CreateObject<RedQueueDisc> ();
364  minTh = 30 * modeSize;
365  maxTh = 90 * modeSize;
366  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
367  "Verify that we can actually set the attribute Mode");
368  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
369  "Verify that we can actually set the attribute MinTh");
370  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
371  "Verify that we can actually set the attribute MaxTh");
372  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
373  "Verify that we can actually set the attribute QueueLimit");
374  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
375  "Verify that we can actually set the attribute QW");
376  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
377  "Verify that we can actually set the attribute LInterm");
378  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (true)), true,
379  "Verify that we can actually set the attribute Gentle");
380  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (true)), true,
381  "Verify that we can actually set the attribute UseECN");
382  queue->Initialize ();
383  Enqueue (queue, pktSize, 300, false);
384  st = queue->GetStats ();
385  // Packets are not ECN capable, so there should be only unforced drops, no unforced marks
386  NS_TEST_EXPECT_MSG_NE (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
387  "There should be some unforced drops");
388  NS_TEST_EXPECT_MSG_EQ (st.GetNMarkedPackets (RedQueueDisc::UNFORCED_MARK), 0,
389  "There should be no unforced marks");
390 
391 
392  // test 9: Packets are ECN capable, but RED queue disc is not ECN enabled
393  queue = CreateObject<RedQueueDisc> ();
394  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
395  "Verify that we can actually set the attribute Mode");
396  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
397  "Verify that we can actually set the attribute MinTh");
398  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
399  "Verify that we can actually set the attribute MaxTh");
400  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
401  "Verify that we can actually set the attribute QueueLimit");
402  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
403  "Verify that we can actually set the attribute QW");
404  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
405  "Verify that we can actually set the attribute LInterm");
406  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (true)), true,
407  "Verify that we can actually set the attribute Gentle");
408  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (false)), true,
409  "Verify that we can actually set the attribute UseECN");
410  queue->Initialize ();
411  Enqueue (queue, pktSize, 300, true);
412  st = queue->GetStats ();
413  // RED queue disc is not ECN enabled, so there should be only unforced drops, no unforced marks
414  NS_TEST_EXPECT_MSG_NE (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
415  "There should be some unforced drops");
416  NS_TEST_EXPECT_MSG_EQ (st.GetNMarkedPackets (RedQueueDisc::UNFORCED_MARK), 0,
417  "There should be no unforced marks");
418 
419 
420  // test 10: Packets are ECN capable and RED queue disc is ECN enabled
421  queue = CreateObject<RedQueueDisc> ();
422  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
423  "Verify that we can actually set the attribute Mode");
424  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
425  "Verify that we can actually set the attribute MinTh");
426  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
427  "Verify that we can actually set the attribute MaxTh");
428  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
429  "Verify that we can actually set the attribute QueueLimit");
430  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
431  "Verify that we can actually set the attribute QW");
432  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
433  "Verify that we can actually set the attribute LInterm");
434  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (true)), true,
435  "Verify that we can actually set the attribute Gentle");
436  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (true)), true,
437  "Verify that we can actually set the attribute UseECN");
438  queue->Initialize ();
439  Enqueue (queue, pktSize, 300, true);
440  st = queue->GetStats ();
441  // Packets are ECN capable, RED queue disc is ECN enabled; there should be only unforced marks, no unforced drops
442  NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
443  "There should be no unforced drops");
444  NS_TEST_EXPECT_MSG_NE (st.GetNMarkedPackets (RedQueueDisc::UNFORCED_MARK), 0,
445  "There should be some unforced marks");
446 
447 
448  // test 11: RED with default parameter settings, linear drop probability and fixed m_curMaxP
449  queue = CreateObject<RedQueueDisc> ();
450  minTh = 30 * modeSize;
451  maxTh = 90 * modeSize;
452  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
453  "Verify that we can actually set the attribute Mode");
454  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
455  "Verify that we can actually set the attribute MinTh");
456  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
457  "Verify that we can actually set the attribute MaxTh");
458  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
459  "Verify that we can actually set the attribute QueueLimit");
460  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
461  "Verify that we can actually set the attribute QW");
462  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
463  "Verify that we can actually set the attribute LInterm");
464  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (true)), true,
465  "Verify that we can actually set the attribute Gentle");
466  queue->Initialize ();
467  Enqueue (queue, pktSize, 300, false);
468  st = queue->GetStats ();
469  drop.test11 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
470  NS_TEST_EXPECT_MSG_NE (drop.test11, 0, "There should some dropped packets due to probability mark");
471 
472 
473  // test 12: Feng's Adaptive RED with default parameter settings and varying m_curMaxP
474  queue = CreateObject<RedQueueDisc> ();
475  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
476  "Verify that we can actually set the attribute Mode");
477  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
478  "Verify that we can actually set the attribute MinTh");
479  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
480  "Verify that we can actually set the attribute MaxTh");
481  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
482  "Verify that we can actually set the attribute QueueLimit");
483  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
484  "Verify that we can actually set the attribute QW");
485  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
486  "Verify that we can actually set the attribute LInterm");
487  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (true)), true,
488  "Verify that we can actually set the attribute Gentle");
489  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("FengAdaptive", BooleanValue (true)), true,
490  "Verify that we can actually set the attribute FengAdaptive");
491  queue->Initialize ();
492  Enqueue (queue, pktSize, 300, false);
493  st = queue->GetStats ();
494  drop.test12 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
495  NS_TEST_EXPECT_MSG_LT (drop.test12, drop.test11, "Test 12 should have less drops due to probability mark than test 11");
496 
497 
498  // test 13: RED with Nonlinear drop probability
499  queue = CreateObject<RedQueueDisc> ();
500  minTh = 30 * modeSize;
501  maxTh = 90 * modeSize;
502  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
503  "Verify that we can actually set the attribute Mode");
504  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
505  "Verify that we can actually set the attribute MinTh");
506  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
507  "Verify that we can actually set the attribute MaxTh");
508  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
509  "Verify that we can actually set the attribute QueueLimit");
510  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
511  "Verify that we can actually set the attribute QW");
512  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
513  "Verify that we can actually set the attribute LInterm");
514  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (true)), true,
515  "Verify that we can actually set the attribute Gentle");
516  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("NLRED", BooleanValue (true)), true,
517  "Verify that we can actually set the attribute NLRED");
518  queue->Initialize ();
519  Enqueue (queue, pktSize, 300, false);
520  st = queue->GetStats ();
521  drop.test13 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
522  NS_TEST_EXPECT_MSG_LT (drop.test13, drop.test11, "Test 13 should have less drops due to probability mark than test 11");
523 
524 }
525 
526 void
527 RedQueueDiscTestCase::Enqueue (Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt, bool ecnCapable)
528 {
529  Address dest;
530  for (uint32_t i = 0; i < nPkt; i++)
531  {
532  queue->Enqueue (Create<RedQueueDiscTestItem> (Create<Packet> (size), dest, 0, ecnCapable));
533  }
534 }
535 
536 void
538 {
539  RunRedTest (StringValue ("QUEUE_DISC_MODE_PACKETS"));
540  RunRedTest (StringValue ("QUEUE_DISC_MODE_BYTES"));
541  Simulator::Destroy ();
542 
543 }
544 
551 static class RedQueueDiscTestSuite : public TestSuite
552 {
553 public:
555  : TestSuite ("red-queue-disc", UNIT)
556  {
557  AddTestCase (new RedQueueDiscTestCase (), TestCase::QUICK);
558  }
Structure that keeps the queue disc statistics.
Definition: queue-disc.h:155
uint32_t GetQueueSize(void)
Get the current value of the queue in bytes or packets.
AttributeValue implementation for Boolean.
Definition: boolean.h:36
bool Enqueue(Ptr< QueueDiscItem > item)
Pass a packet to store to the queue discipline.
Definition: queue-disc.cc:730
Hold variables of type string.
Definition: string.h:41
void SetTh(double minTh, double maxTh)
Set the thresh limits of RED.
virtual void AddHeader(void)
Add the header to the packet.
A suite of tests to run.
Definition: test.h:1342
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:367
QueueDiscMode GetMode(void)
Get the operating mode of this queue disc.
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:285
bool SetAttributeFailSafe(std::string name, const AttributeValue &value)
Set a single attribute without raising errors.
Definition: object-base.cc:205
QueueDiscItem is the abstract base class for items that are stored in a queue disc.
Definition: queue-item.h:148
bool m_ecnCapablePacket
ECN capable packet?
encapsulates test code
Definition: test.h:1155
This test suite implements a Unit Test.
Definition: test.h:1352
a polymophic address class
Definition: address.h:90
Red Queue Disc Test Suite.
void SetQueueLimit(uint32_t lim)
Set the limit of the queue.
Red Queue Disc Test Item.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
Hold an unsigned integer type.
Definition: uinteger.h:44
virtual bool Mark(void)
Marks the packet as a substitute for dropping it, such as for Explicit Congestion Notification...
const Stats & GetStats(void)
Retrieve all the collected statistics.
Definition: queue-disc.cc:411
uint32_t GetNDroppedPackets(std::string reason) const
Get the number of packets dropped for the given reason.
Definition: queue-disc.cc:113
Ptr< QueueDiscItem > Dequeue(void)
Request the queue discipline to extract a packet.
Definition: queue-disc.cc:765
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Red Queue Disc Test Case.
#define NS_TEST_EXPECT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report if not.
Definition: test.h:739
#define NS_TEST_EXPECT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report if not.
Definition: test.h:1090
RedQueueDiscTestSuite g_redQueueTestSuite
the test suite
void RunRedTest(StringValue mode)
Run RED test function.
#define NS_TEST_EXPECT_MSG_LT(actual, limit, msg)
Test that an actual value is less than a limit and report if not.
Definition: test.h:903
uint32_t GetNMarkedPackets(std::string reason) const
Get the number of packets marked for the given reason.
Definition: queue-disc.cc:155
This class can be used to hold variables of floating point type such as 'double' or 'float'...
Definition: double.h:41
void Initialize(void)
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:183
virtual void DoRun(void)
Implementation to actually run this TestCase.
void Enqueue(Ptr< RedQueueDisc > queue, uint32_t size, uint32_t nPkt, bool ecnCapable)
Enqueue function.