A Discrete-Event Network Simulator
API
cobalt-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 (c) 2019 NITK Surathkal
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  * Ported to ns-3 by: Vignesh Kannan <vignesh2496@gmail.com>
19  * Harsh Lara <harshapplefan@gmail.com>
20  * Jendaipou Palmei <jendaipoupalmei@gmail.com>
21  * Shefali Gupta <shefaligups11@gmail.com>
22  * Mohit P. Tahiliani <tahiliani@nitk.edu.in>
23  */
24 
25 #include "ns3/test.h"
26 #include "ns3/cobalt-queue-disc.h"
27 #include "ns3/packet.h"
28 #include "ns3/uinteger.h"
29 #include "ns3/string.h"
30 #include "ns3/double.h"
31 #include "ns3/log.h"
32 #include "ns3/simulator.h"
33 
34 using namespace ns3;
42 {
43 public:
52  CobaltQueueDiscTestItem (Ptr<Packet> p, const Address & addr,uint16_t protocol, bool ecnCapable);
53  virtual ~CobaltQueueDiscTestItem ();
54  virtual void AddHeader (void);
55  virtual bool Mark (void);
56 
57 private:
71 };
72 
73 CobaltQueueDiscTestItem::CobaltQueueDiscTestItem (Ptr<Packet> p, const Address & addr,uint16_t protocol, bool ecnCapable)
74  : QueueDiscItem (p, addr, ecnCapable),
75  m_ecnCapablePacket (ecnCapable)
76 {
77 }
78 
80 {
81 }
82 
83 void
85 {
86 }
87 
88 bool
90 {
92  {
93  return true;
94  }
95  return false;
96 }
97 
105 {
106 public:
113  virtual void DoRun (void);
114 
123 private:
125 };
126 
128  : TestCase ("Basic enqueue and dequeue operations, and attribute setting" + std::to_string (mode))
129 {
130  m_mode = mode;
131 }
132 
133 void
135 {
136  Ptr<CobaltQueueDisc> queue = CreateObject<CobaltQueueDisc> ();
137 
138  uint32_t pktSize = 1000;
139  uint32_t modeSize = 0;
140 
141  Address dest;
142 
143  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinBytes", UintegerValue (pktSize)), true,
144  "Verify that we can actually set the attribute MinBytes");
145  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Interval", StringValue ("50ms")), true,
146  "Verify that we can actually set the attribute Interval");
147  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Target", StringValue ("4ms")), true,
148  "Verify that we can actually set the attribute Target");
149 
151  {
152  modeSize = pktSize;
153  }
154  else if (m_mode == QueueSizeUnit::PACKETS)
155  {
156  modeSize = 1;
157  }
158  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (m_mode, modeSize * 1500))),
159  true, "Verify that we can actually set the attribute MaxSize");
160  queue->Initialize ();
161 
162  Ptr<Packet> p1, p2, p3, p4, p5, p6;
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 
170  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 0 * modeSize, "There should be no packets in queue");
171  queue->Enqueue (Create<CobaltQueueDiscTestItem> (p1, dest,0, false));
172  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 1 * modeSize, "There should be one packet in queue");
173  queue->Enqueue (Create<CobaltQueueDiscTestItem> (p2, dest,0, false));
174  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 2 * modeSize, "There should be two packets in queue");
175  queue->Enqueue (Create<CobaltQueueDiscTestItem> (p3, dest,0, false));
176  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 3 * modeSize, "There should be three packets in queue");
177  queue->Enqueue (Create<CobaltQueueDiscTestItem> (p4, dest,0, false));
178  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 4 * modeSize, "There should be four packets in queue");
179  queue->Enqueue (Create<CobaltQueueDiscTestItem> (p5, dest,0, false));
180  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 5 * modeSize, "There should be five packets in queue");
181  queue->Enqueue (Create<CobaltQueueDiscTestItem> (p6, dest,0, false));
182  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 6 * modeSize, "There should be six packets in queue");
183 
184  NS_TEST_EXPECT_MSG_EQ (queue->GetStats ().GetNDroppedPackets (CobaltQueueDisc::OVERLIMIT_DROP), 0, "There should be no packets being dropped due to full queue");
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->GetCurrentSize ().GetValue (), 5 * modeSize, "There should be five packets in queue");
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->GetCurrentSize ().GetValue (), 4 * modeSize, "There should be four packets in queue");
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->GetCurrentSize ().GetValue (), 3 * modeSize, "There should be three packets in queue");
201  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p3->GetUid (), "Was this the third packet ?");
202 
203  item = queue->Dequeue ();
204  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the forth packet");
205  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 2 * modeSize, "There should be two packets in queue");
206  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p4->GetUid (), "Was this the fourth packet ?");
207 
208  item = queue->Dequeue ();
209  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the fifth packet");
210  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 1 * modeSize, "There should be one packet in queue");
211  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p5->GetUid (), "Was this the fifth packet ?");
212 
213  item = queue->Dequeue ();
214  NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the last packet");
215  NS_TEST_EXPECT_MSG_EQ (queue->GetCurrentSize ().GetValue (), 0 * modeSize, "There should be zero packet in queue");
216  NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p6->GetUid (), "Was this the sixth packet ?");
217 
218  item = queue->Dequeue ();
219  NS_TEST_EXPECT_MSG_EQ ((item == 0), true, "There are really no packets in queue");
220 
221  NS_TEST_EXPECT_MSG_EQ (queue->GetStats ().GetNDroppedPackets (CobaltQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should be no packet drops according to Cobalt algorithm");
222 }
223 
231 {
232 public:
234  virtual void DoRun (void);
241  void Enqueue (Ptr<CobaltQueueDisc> queue, uint32_t size, uint32_t nPkt);
246  void RunDropTest (QueueSizeUnit mode);
247 
248  void EnqueueWithDelay (Ptr<CobaltQueueDisc> queue, uint32_t size, uint32_t nPkt);
249 
250 };
251 
253  : TestCase ("Drop tests verification for both packets and bytes mode")
254 {
255 }
256 
257 void
259 
260 {
261  uint32_t pktSize = 1500;
262  uint32_t modeSize = 0;
263  Ptr<CobaltQueueDisc> queue = CreateObject<CobaltQueueDisc> ();
264 
265  if (mode == QueueSizeUnit::BYTES)
266  {
267  modeSize = pktSize;
268  }
269  else if (mode == QueueSizeUnit::PACKETS)
270  {
271  modeSize = 1;
272  }
273 
274  queue = CreateObject<CobaltQueueDisc> ();
275  NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxSize", QueueSizeValue (QueueSize (mode, modeSize * 100))),
276  true, "Verify that we can actually set the attribute MaxSize");
277 
278  queue->Initialize ();
279 
280  if (mode == QueueSizeUnit::BYTES)
281  {
282  EnqueueWithDelay (queue, pktSize, 200);
283  }
284  else
285  {
286  EnqueueWithDelay (queue, 1, 200);
287  }
288 
289  Simulator::Stop (Seconds (8.0));
290  Simulator::Run ();
291 
292  QueueDisc::Stats st = queue->GetStats ();
293 
294 // The Pdrop value should increase, from it's default value of zero
295  NS_TEST_EXPECT_MSG_NE (queue->GetPdrop (), 0, "Pdrop should be non-zero");
296  NS_TEST_EXPECT_MSG_NE (st.GetNDroppedPackets (CobaltQueueDisc::OVERLIMIT_DROP), 0, "Drops due to queue overflow should be non-zero");
297 }
298 
299 void
301 {
302  Address dest;
303  double delay = 0.01; // enqueue packets with delay
304  for (uint32_t i = 0; i < nPkt; i++)
305  {
306  Simulator::Schedule (Time (Seconds ((i + 1) * delay)), &CobaltQueueDiscDropTest::Enqueue, this, queue, size, 1);
307  }
308 }
309 
310 void
311 CobaltQueueDiscDropTest::Enqueue (Ptr<CobaltQueueDisc> queue, uint32_t size, uint32_t nPkt)
312 {
313  Address dest;
314  for (uint32_t i = 0; i < nPkt; i++)
315  {
316  queue->Enqueue (Create<CobaltQueueDiscTestItem> (Create<Packet> (size), dest, 0, true));
317  }
318 }
319 
320 void
322 {
325  Simulator::Destroy ();
326 }
327 
328 static class CobaltQueueDiscTestSuite : public TestSuite
329 {
330 public:
332  : TestSuite ("cobalt-queue-disc", UNIT)
333  {
334  // Test 1: simple enqueue/dequeue with no drops
335  AddTestCase (new CobaltQueueDiscBasicEnqueueDequeue (PACKETS), TestCase::QUICK);
336  AddTestCase (new CobaltQueueDiscBasicEnqueueDequeue (BYTES), TestCase::QUICK);
337  // Test 2: Drop test
338  AddTestCase (new CobaltQueueDiscDropTest (), TestCase::QUICK);
339  }
Structure that keeps the queue disc statistics.
Definition: queue-disc.h:185
uint64_t GetUid(void) const
Returns the packet&#39;s Uid.
Definition: packet.cc:390
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Class for representing queue sizes.
Definition: queue-size.h:94
bool Enqueue(Ptr< QueueDiscItem > item)
Pass a packet to store to the queue discipline.
Definition: queue-disc.cc:853
Hold variables of type string.
Definition: string.h:41
uint32_t GetValue() const
Get the underlying value.
Definition: queue-size.cc:175
QueueSizeUnit
Enumeration of the operating modes of queues.
Definition: queue-size.h:42
QueueSize GetCurrentSize(void)
Get the current size of the queue disc in bytes, if operating in bytes mode, or packets, otherwise.
Definition: queue-disc.cc:518
A suite of tests to run.
Definition: test.h:1342
void Enqueue(Ptr< CobaltQueueDisc > queue, uint32_t size, uint32_t nPkt)
Enqueue function.
void EnqueueWithDelay(Ptr< CobaltQueueDisc > queue, uint32_t size, uint32_t nPkt)
#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
encapsulates test code
Definition: test.h:1155
STL namespace.
Test 1: simple enqueue/dequeue with no drops.
CobaltQueueDiscBasicEnqueueDequeue(QueueSizeUnit mode)
Constructor.
a polymophic address class
Definition: address.h:90
Cobalt Queue Disc Test Item.
virtual void AddHeader(void)
Add the header to the packet.
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
uint32_t GetNDroppedPackets(std::string reason) const
Get the number of packets dropped for the given reason.
Definition: queue-disc.cc:110
Use number of packets for queue size.
Definition: queue-size.h:44
QueueSizeUnit m_mode
Queue test size function.
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:416
Ptr< QueueDiscItem > Dequeue(void)
Extract from the queue disc the packet that has been dequeued by calling Peek, if any...
Definition: queue-disc.cc:888
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Test 2: Cobalt Queue Disc Drop Test Item.
#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
bool m_ecnCapablePacket
ECN capable packet?
CobaltQueueDiscTestSuite g_cobaltQueueTestSuite
the test suite
virtual void DoRun(void)
Implementation to actually run this TestCase.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1062
double GetPdrop()
Get the drop probability of Blue.
void RunDropTest(QueueSizeUnit mode)
Run Cobalt test function.
This test suite implements a Unit Test.
Definition: test.h:1352
virtual void DoRun(void)
Implementation to actually run this TestCase.
Use number of bytes for queue size.
Definition: queue-size.h:45
void Initialize(void)
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:183