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
34 /**
35 * \ingroup traffic-control-test
36 * \ingroup tests
37 *
38 * \brief Red Queue Disc Test Item
39 */
40 class RedQueueDiscTestItem : public QueueDiscItem {
41 public:
42 /**
43 * Constructor
44 *
45 * \param p packet
46 * \param addr address
47 * \param ecnCapable ECN capable flag
48 */
49 RedQueueDiscTestItem (Ptr<Packet> p, const Address & addr, bool ecnCapable);
50 virtual ~RedQueueDiscTestItem ();
51 virtual void AddHeader (void);
52 virtual bool Mark(void);
53
54 private:
55 RedQueueDiscTestItem ();
56 /**
57 * \brief Copy constructor
58 * Disable default implementation to avoid misuse
59 */
60 RedQueueDiscTestItem (const RedQueueDiscTestItem &);
61 /**
62 * \brief Assignment operator
63 * \return this object
64 * Disable default implementation to avoid misuse
65 */
66 RedQueueDiscTestItem &operator = (const RedQueueDiscTestItem &);
67 bool m_ecnCapablePacket; ///< ECN capable packet?
68 };
69
RedQueueDiscTestItem(Ptr<Packet> p,const Address & addr,bool ecnCapable)70 RedQueueDiscTestItem::RedQueueDiscTestItem (Ptr<Packet> p, const Address & addr, bool ecnCapable)
71 : QueueDiscItem (p, addr, 0),
72 m_ecnCapablePacket (ecnCapable)
73 {
74 }
75
~RedQueueDiscTestItem()76 RedQueueDiscTestItem::~RedQueueDiscTestItem ()
77 {
78 }
79
80 void
AddHeader(void)81 RedQueueDiscTestItem::AddHeader (void)
82 {
83 }
84
85 bool
Mark(void)86 RedQueueDiscTestItem::Mark (void)
87 {
88 if (m_ecnCapablePacket)
89 {
90 return true;
91 }
92 return false;
93 }
94
95 /**
96 * \ingroup traffic-control-test
97 * \ingroup tests
98 *
99 * \brief Red Queue Disc Test Case
100 */
101 class RedQueueDiscTestCase : public TestCase
102 {
103 public:
104 RedQueueDiscTestCase ();
105 virtual void DoRun (void);
106 private:
107 /**
108 * Enqueue function
109 * \param queue the queue disc
110 * \param size the size
111 * \param nPkt the number of packets
112 * \param ecnCapable ECN capable flag
113 */
114 void Enqueue (Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt, bool ecnCapable);
115 /**
116 * Run RED test function
117 * \param mode the mode
118 */
119 void RunRedTest (QueueSizeUnit mode);
120 };
121
RedQueueDiscTestCase()122 RedQueueDiscTestCase::RedQueueDiscTestCase ()
123 : TestCase ("Sanity check on the red queue implementation")
124 {
125 }
126
127 void
RunRedTest(QueueSizeUnit mode)128 RedQueueDiscTestCase::RunRedTest (QueueSizeUnit mode)
129 {
130 uint32_t pktSize = 0;
131 // 1 for packets; pktSize for bytes
132 uint32_t modeSize = 1;
133 double minTh = 2;
134 double maxTh = 5;
135 uint32_t qSize = 8;
136 Ptr<RedQueueDisc> queue = CreateObject<RedQueueDisc> ();
137
138 // test 1: simple enqueue/dequeue with no drops
139 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
140 "Verify that we can actually set the attribute MinTh");
141 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
142 "Verify that we can actually set the attribute MaxTh");
143 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
144 true, "Verify that we can actually set the attribute MaxSize");
145 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
146 "Verify that we can actually set the attribute QW");
147
148 Address dest;
149
150 if (mode == QueueSizeUnit::BYTES)
151 {
152 // pktSize should be same as MeanPktSize to avoid performance gap between byte and packet mode
153 pktSize = 500;
154 modeSize = pktSize;
155 queue->SetTh (minTh * modeSize, maxTh * modeSize);
156 queue->SetMaxSize (QueueSize (mode, qSize * modeSize));
157 }
158
159 Ptr<Packet> p1, p2, p3, p4, p5, p6, p7, p8;
160 p1 = Create<Packet> (pktSize);
161 p2 = Create<Packet> (pktSize);
162 p3 = Create<Packet> (pktSize);
163 p4 = Create<Packet> (pktSize);
164 p5 = Create<Packet> (pktSize);
165 p6 = Create<Packet> (pktSize);
166 p7 = Create<Packet> (pktSize);
167 p8 = Create<Packet> (pktSize);
168
169 queue->Initialize ();
170 NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 0 * modeSize, "There should be no packets in there");
171 queue->Enqueue (Create<RedQueueDiscTestItem> (p1, dest, false));
172 NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 1 * modeSize, "There should be one packet in there");
173 queue->Enqueue (Create<RedQueueDiscTestItem> (p2, dest, false));
174 NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 2 * modeSize, "There should be two packets in there");
175 queue->Enqueue (Create<RedQueueDiscTestItem> (p3, dest, false));
176 queue->Enqueue (Create<RedQueueDiscTestItem> (p4, dest, false));
177 queue->Enqueue (Create<RedQueueDiscTestItem> (p5, dest, false));
178 queue->Enqueue (Create<RedQueueDiscTestItem> (p6, dest, false));
179 queue->Enqueue (Create<RedQueueDiscTestItem> (p7, dest, false));
180 queue->Enqueue (Create<RedQueueDiscTestItem> (p8, dest, false));
181 NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 8 * modeSize, "There should be eight packets in there");
182
183 Ptr<QueueDiscItem> item;
184
185 item = queue->Dequeue ();
186 NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the first packet");
187 NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 7 * modeSize, "There should be seven packets in there");
188 NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p1->GetUid (), "was this the first packet ?");
189
190 item = queue->Dequeue ();
191 NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the second packet");
192 NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 6 * modeSize, "There should be six packet in there");
193 NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p2->GetUid (), "Was this the second packet ?");
194
195 item = queue->Dequeue ();
196 NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the third packet");
197 NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 5 * modeSize, "There should be five packets in there");
198 NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p3->GetUid (), "Was this the third packet ?");
199
200 item = queue->Dequeue ();
201 item = queue->Dequeue ();
202 item = queue->Dequeue ();
203 item = queue->Dequeue ();
204 item = queue->Dequeue ();
205
206 item = queue->Dequeue ();
207 NS_TEST_EXPECT_MSG_EQ ((item == 0), true, "There are really no packets in there");
208
209
210 // test 2: more data, but with no drops
211 queue = CreateObject<RedQueueDisc> ();
212 minTh = 70 * modeSize;
213 maxTh = 150 * modeSize;
214 qSize = 300 * modeSize;
215 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
216 "Verify that we can actually set the attribute MinTh");
217 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
218 "Verify that we can actually set the attribute MaxTh");
219 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
220 true, "Verify that we can actually set the attribute MaxSize");
221 queue->Initialize ();
222 Enqueue (queue, pktSize, 300, false);
223 QueueDisc::Stats st = queue->GetStats ();
224 NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
225 "There should be zero unforced drops");
226 NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (RedQueueDisc::FORCED_DROP), 0,
227 "There should be zero forced dropps");
228 NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (QueueDisc::INTERNAL_QUEUE_DROP), 0,
229 "There should be zero drops due to queue limit");
230
231 // save number of drops from tests
232 struct d {
233 uint32_t test3;
234 uint32_t test4;
235 uint32_t test5;
236 uint32_t test6;
237 uint32_t test7;
238 uint32_t test11;
239 uint32_t test12;
240 uint32_t test13;
241 } drop;
242
243
244 // test 3: more data, now drops due QW change
245 queue = CreateObject<RedQueueDisc> ();
246 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
247 "Verify that we can actually set the attribute MinTh");
248 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
249 "Verify that we can actually set the attribute MaxTh");
250 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
251 true, "Verify that we can actually set the attribute MaxSize");
252 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
253 "Verify that we can actually set the attribute QW");
254 queue->Initialize ();
255 Enqueue (queue, pktSize, 300, false);
256 st = queue->GetStats ();
257 drop.test3 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP)
258 + st.GetNDroppedPackets (RedQueueDisc::FORCED_DROP)
259 + st.GetNDroppedPackets (QueueDisc::INTERNAL_QUEUE_DROP);
260 NS_TEST_EXPECT_MSG_NE (drop.test3, 0, "There should be some dropped packets");
261
262
263 // test 4: reduced maxTh, this causes more drops
264 maxTh = 100 * modeSize;
265 queue = CreateObject<RedQueueDisc> ();
266 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
267 "Verify that we can actually set the attribute MinTh");
268 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
269 "Verify that we can actually set the attribute MaxTh");
270 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
271 true, "Verify that we can actually set the attribute MaxSize");
272 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
273 "Verify that we can actually set the attribute QW");
274 queue->Initialize ();
275 Enqueue (queue, pktSize, 300, false);
276 st = queue->GetStats ();
277 drop.test4 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP)
278 + st.GetNDroppedPackets (RedQueueDisc::FORCED_DROP)
279 + st.GetNDroppedPackets (QueueDisc::INTERNAL_QUEUE_DROP);
280 NS_TEST_EXPECT_MSG_GT (drop.test4, drop.test3, "Test 4 should have more drops than test 3");
281
282
283 // test 5: change drop probability to a high value (LInterm)
284 maxTh = 150 * modeSize;
285 queue = CreateObject<RedQueueDisc> ();
286 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
287 "Verify that we can actually set the attribute MinTh");
288 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
289 "Verify that we can actually set the attribute MaxTh");
290 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
291 true, "Verify that we can actually set the attribute MaxSize");
292 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
293 "Verify that we can actually set the attribute QW");
294 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (5)), true,
295 "Verify that we can actually set the attribute LInterm");
296 queue->Initialize ();
297 Enqueue (queue, pktSize, 300, false);
298 st = queue->GetStats ();
299 drop.test5 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP)
300 + st.GetNDroppedPackets (RedQueueDisc::FORCED_DROP)
301 + st.GetNDroppedPackets (QueueDisc::INTERNAL_QUEUE_DROP);
302 NS_TEST_EXPECT_MSG_GT (drop.test5, drop.test3, "Test 5 should have more drops than test 3");
303
304
305 // test 6: disable Gentle param
306 queue = CreateObject<RedQueueDisc> ();
307 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
308 "Verify that we can actually set the attribute MinTh");
309 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
310 "Verify that we can actually set the attribute MaxTh");
311 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
312 true, "Verify that we can actually set the attribute MaxSize");
313 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
314 "Verify that we can actually set the attribute QW");
315 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (false)), true,
316 "Verify that we can actually set the attribute Gentle");
317 queue->Initialize ();
318 Enqueue (queue, pktSize, 300, false);
319 st = queue->GetStats ();
320 drop.test6 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP)
321 + st.GetNDroppedPackets (RedQueueDisc::FORCED_DROP)
322 + st.GetNDroppedPackets (QueueDisc::INTERNAL_QUEUE_DROP);
323 NS_TEST_EXPECT_MSG_GT (drop.test6, drop.test3, "Test 6 should have more drops than test 3");
324
325
326 // test 7: disable Wait param
327 queue = CreateObject<RedQueueDisc> ();
328 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
329 "Verify that we can actually set the attribute MinTh");
330 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
331 "Verify that we can actually set the attribute MaxTh");
332 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
333 true, "Verify that we can actually set the attribute MaxSize");
334 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
335 "Verify that we can actually set the attribute QW");
336 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Wait", BooleanValue (false)), true,
337 "Verify that we can actually set the attribute Wait");
338 queue->Initialize ();
339 Enqueue (queue, pktSize, 300, false);
340 st = queue->GetStats ();
341 drop.test7 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP)
342 + st.GetNDroppedPackets (RedQueueDisc::FORCED_DROP)
343 + st.GetNDroppedPackets (QueueDisc::INTERNAL_QUEUE_DROP);
344 NS_TEST_EXPECT_MSG_GT (drop.test7, drop.test3, "Test 7 should have more drops than test 3");
345
346
347 // test 8: RED queue disc is ECN enabled, but packets are not ECN capable
348 queue = CreateObject<RedQueueDisc> ();
349 minTh = 30 * modeSize;
350 maxTh = 90 * modeSize;
351 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
352 "Verify that we can actually set the attribute MinTh");
353 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
354 "Verify that we can actually set the attribute MaxTh");
355 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
356 true, "Verify that we can actually set the attribute MaxSize");
357 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
358 "Verify that we can actually set the attribute QW");
359 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
360 "Verify that we can actually set the attribute LInterm");
361 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (true)), true,
362 "Verify that we can actually set the attribute Gentle");
363 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (true)), true,
364 "Verify that we can actually set the attribute UseECN");
365 queue->Initialize ();
366 Enqueue (queue, pktSize, 300, false);
367 st = queue->GetStats ();
368 // Packets are not ECN capable, so there should be only unforced drops, no unforced marks
369 NS_TEST_EXPECT_MSG_NE (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
370 "There should be some unforced drops");
371 NS_TEST_EXPECT_MSG_EQ (st.GetNMarkedPackets (RedQueueDisc::UNFORCED_MARK), 0,
372 "There should be no unforced marks");
373
374
375 // test 9: Packets are ECN capable, but RED queue disc is not ECN enabled
376 queue = CreateObject<RedQueueDisc> ();
377 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
378 "Verify that we can actually set the attribute MinTh");
379 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
380 "Verify that we can actually set the attribute MaxTh");
381 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
382 true, "Verify that we can actually set the attribute MaxSize");
383 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
384 "Verify that we can actually set the attribute QW");
385 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
386 "Verify that we can actually set the attribute LInterm");
387 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (true)), true,
388 "Verify that we can actually set the attribute Gentle");
389 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (false)), true,
390 "Verify that we can actually set the attribute UseECN");
391 queue->Initialize ();
392 Enqueue (queue, pktSize, 300, true);
393 st = queue->GetStats ();
394 // RED queue disc is not ECN enabled, so there should be only unforced drops, no unforced marks
395 NS_TEST_EXPECT_MSG_NE (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
396 "There should be some unforced drops");
397 NS_TEST_EXPECT_MSG_EQ (st.GetNMarkedPackets (RedQueueDisc::UNFORCED_MARK), 0,
398 "There should be no unforced marks");
399
400
401 // test 10: Packets are ECN capable and RED queue disc is ECN enabled
402 queue = CreateObject<RedQueueDisc> ();
403 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
404 "Verify that we can actually set the attribute MinTh");
405 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
406 "Verify that we can actually set the attribute MaxTh");
407 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
408 true, "Verify that we can actually set the attribute MaxSize");
409 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
410 "Verify that we can actually set the attribute QW");
411 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
412 "Verify that we can actually set the attribute LInterm");
413 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (true)), true,
414 "Verify that we can actually set the attribute Gentle");
415 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("UseEcn", BooleanValue (true)), true,
416 "Verify that we can actually set the attribute UseECN");
417 queue->Initialize ();
418 Enqueue (queue, pktSize, 300, true);
419 st = queue->GetStats ();
420 // Packets are ECN capable, RED queue disc is ECN enabled; there should be only unforced marks, no unforced drops
421 NS_TEST_EXPECT_MSG_EQ (st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP), 0,
422 "There should be no unforced drops");
423 NS_TEST_EXPECT_MSG_NE (st.GetNMarkedPackets (RedQueueDisc::UNFORCED_MARK), 0,
424 "There should be some unforced marks");
425
426
427 // test 11: RED with default parameter settings, linear drop probability and fixed m_curMaxP
428 queue = CreateObject<RedQueueDisc> ();
429 minTh = 30 * modeSize;
430 maxTh = 90 * modeSize;
431 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
432 "Verify that we can actually set the attribute MinTh");
433 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
434 "Verify that we can actually set the attribute MaxTh");
435 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
436 true, "Verify that we can actually set the attribute MaxSize");
437 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
438 "Verify that we can actually set the attribute QW");
439 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
440 "Verify that we can actually set the attribute LInterm");
441 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (true)), true,
442 "Verify that we can actually set the attribute Gentle");
443 queue->Initialize ();
444 Enqueue (queue, pktSize, 300, false);
445 st = queue->GetStats ();
446 drop.test11 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
447 NS_TEST_EXPECT_MSG_NE (drop.test11, 0, "There should some dropped packets due to probability mark");
448
449
450 // test 12: Feng's Adaptive RED with default parameter settings and varying m_curMaxP
451 queue = CreateObject<RedQueueDisc> ();
452 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
453 "Verify that we can actually set the attribute MinTh");
454 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
455 "Verify that we can actually set the attribute MaxTh");
456 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
457 true, "Verify that we can actually set the attribute MaxSize");
458 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
459 "Verify that we can actually set the attribute QW");
460 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (2)), true,
461 "Verify that we can actually set the attribute LInterm");
462 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (true)), true,
463 "Verify that we can actually set the attribute Gentle");
464 NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("FengAdaptive", BooleanValue (true)), true,
465 "Verify that we can actually set the attribute FengAdaptive");
466 queue->Initialize ();
467 Enqueue (queue, pktSize, 300, false);
468 st = queue->GetStats ();
469 drop.test12 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
470 NS_TEST_EXPECT_MSG_LT (drop.test12, drop.test11, "Test 12 should have less drops due to probability mark than test 11");
471
472
473 // test 13: RED with Nonlinear drop probability
474 queue = CreateObject<RedQueueDisc> ();
475 minTh = 30 * modeSize;
476 maxTh = 90 * modeSize;
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 ("MaxSize", QueueSizeValue (QueueSize (mode, qSize))),
482 true, "Verify that we can actually set the attribute MaxSize");
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 ("NLRED", BooleanValue (true)), true,
490 "Verify that we can actually set the attribute NLRED");
491 queue->Initialize ();
492 Enqueue (queue, pktSize, 300, false);
493 st = queue->GetStats ();
494 drop.test13 = st.GetNDroppedPackets (RedQueueDisc::UNFORCED_DROP);
495 NS_TEST_EXPECT_MSG_LT (drop.test13, drop.test11, "Test 13 should have less drops due to probability mark than test 11");
496
497 }
498
499 void
Enqueue(Ptr<RedQueueDisc> queue,uint32_t size,uint32_t nPkt,bool ecnCapable)500 RedQueueDiscTestCase::Enqueue (Ptr<RedQueueDisc> queue, uint32_t size, uint32_t nPkt, bool ecnCapable)
501 {
502 Address dest;
503 for (uint32_t i = 0; i < nPkt; i++)
504 {
505 queue->Enqueue (Create<RedQueueDiscTestItem> (Create<Packet> (size), dest, ecnCapable));
506 }
507 }
508
509 void
DoRun(void)510 RedQueueDiscTestCase::DoRun (void)
511 {
512 RunRedTest (QueueSizeUnit::PACKETS);
513 RunRedTest (QueueSizeUnit::BYTES);
514 Simulator::Destroy ();
515
516 }
517
518 /**
519 * \ingroup traffic-control-test
520 * \ingroup tests
521 *
522 * \brief Red Queue Disc Test Suite
523 */
524 static class RedQueueDiscTestSuite : public TestSuite
525 {
526 public:
RedQueueDiscTestSuite()527 RedQueueDiscTestSuite ()
528 : TestSuite ("red-queue-disc", UNIT)
529 {
530 AddTestCase (new RedQueueDiscTestCase (), TestCase::QUICK);
531 }
532 } g_redQueueTestSuite; ///< the test suite
533