A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
red-queue-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  *
20  */
21 
22 #include "ns3/test.h"
23 #include "ns3/red-queue.h"
24 #include "ns3/uinteger.h"
25 #include "ns3/string.h"
26 #include "ns3/double.h"
27 #include "ns3/log.h"
28 #include "ns3/simulator.h"
29 
30 using namespace ns3;
31 
32 class RedQueueTestCase : public TestCase
33 {
34 public:
36  virtual void DoRun (void);
37 private:
38  void Enqueue (Ptr<RedQueue> queue, uint32_t size, uint32_t nPkt);
39  void RunRedTest (StringValue mode);
40 };
41 
43  : TestCase ("Sanity check on the red queue implementation")
44 {
45 }
46 
47 void
49 {
50  uint32_t pktSize = 0;
51  // 1 for packets; pktSize for bytes
52  uint32_t modeSize = 1;
53  double minTh = 2;
54  double maxTh = 5;
55  uint32_t qSize = 8;
56  Ptr<RedQueue> queue = CreateObject<RedQueue> ();
57 
58  // test 1: simple enqueue/dequeue with no drops
59  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
60  "Verify that we can actually set the attribute Mode");
61  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
62  "Verify that we can actually set the attribute MinTh");
63  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
64  "Verify that we can actually set the attribute MaxTh");
65  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
66  "Verify that we can actually set the attribute QueueLimit");
67  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
68  "Verify that we can actually set the attribute QW");
69 
70  if (queue->GetMode () == RedQueue::QUEUE_MODE_BYTES)
71  {
72  pktSize = 1000;
73  modeSize = pktSize;
74  queue->SetTh (minTh * pktSize, maxTh * pktSize);
75  queue->SetQueueLimit (qSize * pktSize);
76  }
77 
78  Ptr<Packet> p1, p2, p3, p4, p5, p6, p7, p8;
79  p1 = Create<Packet> (pktSize);
80  p2 = Create<Packet> (pktSize);
81  p3 = Create<Packet> (pktSize);
82  p4 = Create<Packet> (pktSize);
83  p5 = Create<Packet> (pktSize);
84  p6 = Create<Packet> (pktSize);
85  p7 = Create<Packet> (pktSize);
86  p8 = Create<Packet> (pktSize);
87 
88  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 0 * modeSize, "There should be no packets in there");
89  queue->Enqueue (p1);
90  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 1 * modeSize, "There should be one packet in there");
91  queue->Enqueue (p2);
92  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 2 * modeSize, "There should be two packets in there");
93  queue->Enqueue (p3);
94  queue->Enqueue (p4);
95  queue->Enqueue (p5);
96  queue->Enqueue (p6);
97  queue->Enqueue (p7);
98  queue->Enqueue (p8);
99  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 8 * modeSize, "There should be eight packets in there");
100 
101  Ptr<Packet> p;
102 
103  p = queue->Dequeue ();
104  NS_TEST_EXPECT_MSG_EQ ((p != 0), true, "I want to remove the first packet");
105  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 7 * modeSize, "There should be seven packets in there");
106  NS_TEST_EXPECT_MSG_EQ (p->GetUid (), p1->GetUid (), "was this the first packet ?");
107 
108  p = queue->Dequeue ();
109  NS_TEST_EXPECT_MSG_EQ ((p != 0), true, "I want to remove the second packet");
110  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 6 * modeSize, "There should be six packet in there");
111  NS_TEST_EXPECT_MSG_EQ (p->GetUid (), p2->GetUid (), "Was this the second packet ?");
112 
113  p = queue->Dequeue ();
114  NS_TEST_EXPECT_MSG_EQ ((p != 0), true, "I want to remove the third packet");
115  NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 5 * modeSize, "There should be five packets in there");
116  NS_TEST_EXPECT_MSG_EQ (p->GetUid (), p3->GetUid (), "Was this the third packet ?");
117 
118  p = queue->Dequeue ();
119  p = queue->Dequeue ();
120  p = queue->Dequeue ();
121  p = queue->Dequeue ();
122  p = queue->Dequeue ();
123 
124  p = queue->Dequeue ();
125  NS_TEST_EXPECT_MSG_EQ ((p == 0), true, "There are really no packets in there");
126 
127 
128  // test 2: more data, but with no drops
129  queue = CreateObject<RedQueue> ();
130  minTh = 70 * modeSize;
131  maxTh = 150 * modeSize;
132  qSize = 300 * modeSize;
133  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
134  "Verify that we can actually set the attribute Mode");
135  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
136  "Verify that we can actually set the attribute MinTh");
137  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
138  "Verify that we can actually set the attribute MaxTh");
139  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
140  "Verify that we can actually set the attribute QueueLimit");
141  Enqueue (queue, pktSize, 300);
142  RedQueue::Stats st = StaticCast<RedQueue> (queue)->GetStats ();
143  NS_TEST_EXPECT_MSG_EQ (st.unforcedDrop, 0, "There should zero dropped packets due probability mark");
144  NS_TEST_EXPECT_MSG_EQ (st.forcedDrop, 0, "There should zero dropped packets due hardmark mark");
145  NS_TEST_EXPECT_MSG_EQ (st.qLimDrop, 0, "There should zero dropped packets due queue full");
146 
147  // save number of drops from tests
148  struct d {
149  uint32_t test3;
150  uint32_t test4;
151  uint32_t test5;
152  uint32_t test6;
153  uint32_t test7;
154  } drop;
155 
156 
157  // test 3: more data, now drops due QW change
158  queue = CreateObject<RedQueue> ();
159  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
160  "Verify that we can actually set the attribute Mode");
161  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
162  "Verify that we can actually set the attribute MinTh");
163  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
164  "Verify that we can actually set the attribute MaxTh");
165  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
166  "Verify that we can actually set the attribute QueueLimit");
167  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
168  "Verify that we can actually set the attribute QW");
169  Enqueue (queue, pktSize, 300);
170  st = StaticCast<RedQueue> (queue)->GetStats ();
171  drop.test3 = st.unforcedDrop + st.forcedDrop + st.qLimDrop;
172  NS_TEST_EXPECT_MSG_NE (drop.test3, 0, "There should be some dropped packets");
173 
174 
175  // test 4: reduced maxTh, this causes more drops
176  maxTh = 100 * modeSize;
177  queue = CreateObject<RedQueue> ();
178  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
179  "Verify that we can actually set the attribute Mode");
180  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
181  "Verify that we can actually set the attribute MinTh");
182  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
183  "Verify that we can actually set the attribute MaxTh");
184  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
185  "Verify that we can actually set the attribute QueueLimit");
186  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
187  "Verify that we can actually set the attribute QW");
188  Enqueue (queue, pktSize, 300);
189  st = StaticCast<RedQueue> (queue)->GetStats ();
190  drop.test4 = st.unforcedDrop + st.forcedDrop + st.qLimDrop;
191  NS_TEST_EXPECT_MSG_GT (drop.test4, drop.test3, "Test 4 should have more drops than test 3");
192 
193 
194  // test 5: change drop probability to a high value (LInterm)
195  maxTh = 150 * modeSize;
196  queue = CreateObject<RedQueue> ();
197  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
198  "Verify that we can actually set the attribute Mode");
199  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
200  "Verify that we can actually set the attribute MinTh");
201  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
202  "Verify that we can actually set the attribute MaxTh");
203  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
204  "Verify that we can actually set the attribute QueueLimit");
205  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
206  "Verify that we can actually set the attribute QW");
207  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (5)), true,
208  "Verify that we can actually set the attribute LInterm");
209  Enqueue (queue, pktSize, 300);
210  st = StaticCast<RedQueue> (queue)->GetStats ();
211  drop.test5 = st.unforcedDrop + st.forcedDrop + st.qLimDrop;
212  NS_TEST_EXPECT_MSG_GT (drop.test5, drop.test3, "Test 5 should have more drops than test 3");
213 
214 
215  // test 6: disable Gentle param
216  queue = CreateObject<RedQueue> ();
217  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
218  "Verify that we can actually set the attribute Mode");
219  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
220  "Verify that we can actually set the attribute MinTh");
221  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
222  "Verify that we can actually set the attribute MaxTh");
223  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
224  "Verify that we can actually set the attribute QueueLimit");
225  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
226  "Verify that we can actually set the attribute QW");
227  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (false)), true,
228  "Verify that we can actually set the attribute Gentle");
229  Enqueue (queue, pktSize, 300);
230  st = StaticCast<RedQueue> (queue)->GetStats ();
231  drop.test6 = st.unforcedDrop + st.forcedDrop + st.qLimDrop;
232  NS_TEST_EXPECT_MSG_GT (drop.test6, drop.test3, "Test 6 should have more drops than test 3");
233 
234 
235  // test 7: disable Wait param
236  queue = CreateObject<RedQueue> ();
237  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
238  "Verify that we can actually set the attribute Mode");
239  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
240  "Verify that we can actually set the attribute MinTh");
241  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
242  "Verify that we can actually set the attribute MaxTh");
243  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
244  "Verify that we can actually set the attribute QueueLimit");
245  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
246  "Verify that we can actually set the attribute QW");
247  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Wait", BooleanValue (false)), true,
248  "Verify that we can actually set the attribute Wait");
249  Enqueue (queue, pktSize, 300);
250  st = StaticCast<RedQueue> (queue)->GetStats ();
251  drop.test7 = st.unforcedDrop + st.forcedDrop + st.qLimDrop;
252  NS_TEST_EXPECT_MSG_GT (drop.test7, drop.test3, "Test 7 should have more drops than test 3");
253 }
254 
255 void
256 RedQueueTestCase::Enqueue (Ptr<RedQueue> queue, uint32_t size, uint32_t nPkt)
257 {
258  for (uint32_t i = 0; i < nPkt; i++)
259  {
260  queue->Enqueue (Create<Packet> (size));
261  }
262 }
263 
264 void
266 {
267  RunRedTest (StringValue ("QUEUE_MODE_PACKETS"));
268  RunRedTest (StringValue ("QUEUE_MODE_BYTES"));
269  Simulator::Destroy ();
270 
271 }
272 
273 static class RedQueueTestSuite : public TestSuite
274 {
275 public:
277  : TestSuite ("red-queue", UNIT)
278  {
279  AddTestCase (new RedQueueTestCase (), TestCase::QUICK);
280  }
uint32_t qLimDrop
Forced drops, qavg > max threshold.
Definition: red-queue.h:108
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
bool Enqueue(Ptr< Packet > p)
Place a packet into the rear of the Queue.
Definition: queue.cc:63
Hold a bool native type.
Definition: boolean.h:38
hold variables of type string
Definition: string.h:19
A suite of tests to run.
Definition: test.h:1025
void SetQueueLimit(uint32_t lim)
Set the limit of the queue.
Definition: red-queue.cc:181
uint64_t GetUid(void) const
A packet is allocated a new uid when it is created empty or with zero-filled payload.
Definition: packet.cc:393
void Enqueue(Ptr< RedQueue > queue, uint32_t size, uint32_t nPkt)
bool SetAttributeFailSafe(std::string name, const AttributeValue &value)
Definition: object-base.cc:181
encapsulates test code
Definition: test.h:849
#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:814
uint32_t GetQueueSize(void)
Get the current value of the queue in bytes or packets.
Definition: red-queue.cc:595
RedQueue::QueueMode GetMode(void)
Get the encapsulation mode of this queue.
Definition: red-queue.cc:174
Hold an unsigned integer type.
Definition: uinteger.h:46
#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:244
Ptr< Packet > Dequeue(void)
Remove a packet from the front of the Queue.
Definition: queue.cc:87
RedQueueTestSuite g_redQueueTestSuite
void SetTh(double minTh, double maxTh)
Set the thresh limits of RED.
Definition: red-queue.cc:188
void AddTestCase(TestCase *testCase) NS_DEPRECATED
Add an individual child TestCase case to this TestCase.
Definition: test.cc:173
uint32_t forcedDrop
Early probability drops.
Definition: red-queue.h:107
uint32_t unforcedDrop
Definition: red-queue.h:106
#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:644
This test suite implements a Unit Test.
Definition: test.h:1035
Hold a floating point type.
Definition: double.h:41
virtual void DoRun(void)
Implementation to actually run this TestCase.
void RunRedTest(StringValue mode)