LEFT | RIGHT |
(no file at all) | |
| 1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
| 2 /* |
| 3 * Copyright (c) 2017 Universita' degli Studi di Napoli Federico II |
| 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: Stefano Avallone <stavallo@unina.it> |
| 19 * |
| 20 */ |
| 21 |
| 22 #include "ns3/test.h" |
| 23 #include "ns3/uinteger.h" |
| 24 #include "ns3/pointer.h" |
| 25 #include "ns3/string.h" |
| 26 #include "ns3/double.h" |
| 27 #include "ns3/log.h" |
| 28 #include "ns3/simulator.h" |
| 29 #include "ns3/node-container.h" |
| 30 #include "ns3/traffic-control-layer.h" |
| 31 #include "ns3/traffic-control-helper.h" |
| 32 #include "ns3/simple-net-device.h" |
| 33 #include "ns3/simple-channel.h" |
| 34 #include "ns3/drop-tail-queue.h" |
| 35 #include "ns3/net-device-queue-interface.h" |
| 36 #include "ns3/config.h" |
| 37 |
| 38 using namespace ns3; |
| 39 |
| 40 class QueueDiscTestItem : public QueueDiscItem { |
| 41 public: |
| 42 QueueDiscTestItem (Ptr<Packet> p); |
| 43 virtual ~QueueDiscTestItem (); |
| 44 virtual void AddHeader (void); |
| 45 virtual bool Mark(void); |
| 46 |
| 47 private: |
| 48 QueueDiscTestItem (); |
| 49 QueueDiscTestItem (const QueueDiscTestItem &); |
| 50 QueueDiscTestItem &operator = (const QueueDiscTestItem &); |
| 51 }; |
| 52 |
| 53 QueueDiscTestItem::QueueDiscTestItem (Ptr<Packet> p) |
| 54 : QueueDiscItem (p, Mac48Address (), 0) |
| 55 { |
| 56 } |
| 57 |
| 58 QueueDiscTestItem::~QueueDiscTestItem () |
| 59 { |
| 60 } |
| 61 |
| 62 void |
| 63 QueueDiscTestItem::AddHeader (void) |
| 64 { |
| 65 } |
| 66 |
| 67 bool |
| 68 QueueDiscTestItem::Mark (void) |
| 69 { |
| 70 return false; |
| 71 } |
| 72 |
| 73 // Tests to verify the working of ARED |
| 74 class TcFlowControlTestCase : public TestCase |
| 75 { |
| 76 public: |
| 77 |
| 78 enum TestType |
| 79 { |
| 80 PACKET_MODE, |
| 81 BYTE_MODE |
| 82 }; |
| 83 |
| 84 TcFlowControlTestCase (TestType tt); |
| 85 virtual ~TcFlowControlTestCase (); |
| 86 private: |
| 87 virtual void DoRun (void); |
| 88 void SendPackets (Ptr<Node> n, uint16_t nPackets); |
| 89 void CheckPacketsInDeviceQueue (Ptr<NetDevice> dev, uint16_t nPackets, const c
har* msg); |
| 90 void CheckDeviceQueueStopped (Ptr<NetDevice> dev, bool value, const char* msg)
; |
| 91 void CheckPacketsInQueueDisc (Ptr<NetDevice> dev, uint16_t nPackets, const cha
r* msg); |
| 92 TestType m_type; |
| 93 }; |
| 94 |
| 95 TcFlowControlTestCase::TcFlowControlTestCase (TestType tt) |
| 96 : TestCase ("Test the operation of the flow control mechanism"), |
| 97 m_type (tt) |
| 98 { |
| 99 } |
| 100 |
| 101 TcFlowControlTestCase::~TcFlowControlTestCase () |
| 102 { |
| 103 } |
| 104 |
| 105 void |
| 106 TcFlowControlTestCase::SendPackets (Ptr<Node> n, uint16_t nPackets) |
| 107 { |
| 108 Ptr<TrafficControlLayer> tc = n->GetObject<TrafficControlLayer> (); |
| 109 for (uint16_t i = 0; i < nPackets; i++) |
| 110 { |
| 111 tc->Send (n->GetDevice (0), Create<QueueDiscTestItem> (Create<Packet> (100
0))); |
| 112 } |
| 113 } |
| 114 |
| 115 void |
| 116 TcFlowControlTestCase::CheckPacketsInDeviceQueue (Ptr<NetDevice> dev, uint16_t n
Packets, const char* msg) |
| 117 { |
| 118 PointerValue ptr; |
| 119 dev->GetAttributeFailSafe ("TxQueue", ptr); |
| 120 Ptr<Queue<Packet> > queue = ptr.Get<Queue<Packet> > (); |
| 121 NS_TEST_EXPECT_MSG_EQ (queue->GetNPackets (), nPackets, msg); |
| 122 } |
| 123 |
| 124 void |
| 125 TcFlowControlTestCase::CheckDeviceQueueStopped (Ptr<NetDevice> dev, bool value,
const char* msg) |
| 126 { |
| 127 Ptr<NetDeviceQueueInterface> ndqi = dev->GetObject<NetDeviceQueueInterface> ()
; |
| 128 NS_TEST_EXPECT_MSG_EQ (ndqi->GetTxQueue (0)->IsStopped (), value, msg); |
| 129 } |
| 130 |
| 131 void |
| 132 TcFlowControlTestCase::CheckPacketsInQueueDisc (Ptr<NetDevice> dev, uint16_t nPa
ckets, const char* msg) |
| 133 { |
| 134 Ptr<TrafficControlLayer> tc = dev->GetNode ()->GetObject<TrafficControlLayer>
(); |
| 135 Ptr<QueueDisc> qdisc = tc->GetRootQueueDiscOnDevice (dev); |
| 136 NS_TEST_EXPECT_MSG_EQ (qdisc->GetNPackets (), nPackets, msg); |
| 137 } |
| 138 |
| 139 |
| 140 void |
| 141 TcFlowControlTestCase::DoRun (void) |
| 142 { |
| 143 NodeContainer n; |
| 144 n.Create (2); |
| 145 |
| 146 n.Get (0)->AggregateObject (CreateObject<TrafficControlLayer> ()); |
| 147 n.Get (1)->AggregateObject (CreateObject<TrafficControlLayer> ()); |
| 148 |
| 149 Ptr<Queue<Packet> > queue; |
| 150 |
| 151 if (m_type == PACKET_MODE) |
| 152 { |
| 153 queue = CreateObjectWithAttributes<DropTailQueue<Packet> > ("Mode", EnumVa
lue (QueueBase::QUEUE_MODE_PACKETS), |
| 154 "MaxPackets",
UintegerValue (5)); |
| 155 } |
| 156 else |
| 157 { |
| 158 queue = CreateObjectWithAttributes<DropTailQueue<Packet> > ("Mode", EnumVa
lue (QueueBase::QUEUE_MODE_BYTES), |
| 159 "MaxBytes", Ui
ntegerValue (5000)); |
| 160 } |
| 161 |
| 162 // link the two nodes |
| 163 Ptr<SimpleNetDevice> txDev, rxDev; |
| 164 txDev = CreateObjectWithAttributes<SimpleNetDevice> ("TxQueue", PointerValue (
queue), |
| 165 "DataRate", DataRateValue
(DataRate ("1Mb/s"))); |
| 166 rxDev = CreateObject<SimpleNetDevice> (); |
| 167 n.Get (0)->AddDevice (txDev); |
| 168 n.Get (1)->AddDevice (rxDev); |
| 169 Ptr<SimpleChannel> channel1 = CreateObject<SimpleChannel> (); |
| 170 txDev->SetChannel (channel1); |
| 171 rxDev->SetChannel (channel1); |
| 172 |
| 173 txDev->SetMtu (2500); |
| 174 |
| 175 TrafficControlHelper tch = TrafficControlHelper::Default (); |
| 176 tch.Install (txDev); |
| 177 |
| 178 // transmit 10 packets at time 0 |
| 179 Simulator::Schedule (Time (Seconds (0)), &TcFlowControlTestCase::SendPackets, |
| 180 this, n.Get (0), 10); |
| 181 |
| 182 if (m_type == PACKET_MODE) |
| 183 { |
| 184 /* |
| 185 * When the device queue is in packet mode, all the packets enqueued in th
e |
| 186 * queue disc are correctly transmitted, even if the device queue is stopp
ed |
| 187 * when the last packet is received from the upper layers |
| 188 */ |
| 189 |
| 190 // The transmission of each packet takes 1000B/1Mbps = 8ms |
| 191 // After 1ms, we have 5 packets in the device queue (stopped) and 4 in the
queue disc |
| 192 Simulator::Schedule (Time (MilliSeconds (1)), &TcFlowControlTestCase::Chec
kPacketsInDeviceQueue, |
| 193 this, txDev, 5, "There must be 5 packets in the device
queue after 1ms"); |
| 194 Simulator::Schedule (Time (MilliSeconds (1)), &TcFlowControlTestCase::Chec
kDeviceQueueStopped, |
| 195 this, txDev, true, "The device queue must be stopped a
fter 1ms"); |
| 196 Simulator::Schedule (Time (MilliSeconds (1)), &TcFlowControlTestCase::Chec
kPacketsInQueueDisc, |
| 197 this, txDev, 4, "There must be 4 packets in the queue
disc after 1ms"); |
| 198 |
| 199 // After 9ms, we have 5 packets in the device queue (stopped) and 3 in the
queue disc |
| 200 Simulator::Schedule (Time (MilliSeconds (9)), &TcFlowControlTestCase::Chec
kPacketsInDeviceQueue, |
| 201 this, txDev, 5, "There must be 5 packets in the device
queue after 9ms"); |
| 202 Simulator::Schedule (Time (MilliSeconds (9)), &TcFlowControlTestCase::Chec
kDeviceQueueStopped, |
| 203 this, txDev, true, "The device queue must be stopped a
fter 9ms"); |
| 204 Simulator::Schedule (Time (MilliSeconds (9)), &TcFlowControlTestCase::Chec
kPacketsInQueueDisc, |
| 205 this, txDev, 3, "There must be 3 packets in the queue
disc after 9ms"); |
| 206 |
| 207 // After 17ms, we have 5 packets in the device queue (stopped) and 2 in th
e queue disc |
| 208 Simulator::Schedule (Time (MilliSeconds (17)), &TcFlowControlTestCase::Che
ckPacketsInDeviceQueue, |
| 209 this, txDev, 5, "There must be 5 packets in the device
queue after 17ms"); |
| 210 Simulator::Schedule (Time (MilliSeconds (17)), &TcFlowControlTestCase::Che
ckDeviceQueueStopped, |
| 211 this, txDev, true, "The device queue must be stopped a
fter 17ms"); |
| 212 Simulator::Schedule (Time (MilliSeconds (17)), &TcFlowControlTestCase::Che
ckPacketsInQueueDisc, |
| 213 this, txDev, 2, "There must be 2 packets in the queue
disc after 17ms"); |
| 214 |
| 215 // After 25ms, we have 5 packets in the device queue (stopped) and 1 in th
e queue disc |
| 216 Simulator::Schedule (Time (MilliSeconds (25)), &TcFlowControlTestCase::Che
ckPacketsInDeviceQueue, |
| 217 this, txDev, 5, "There must be 5 packets in the device
queue after 25ms"); |
| 218 Simulator::Schedule (Time (MilliSeconds (25)), &TcFlowControlTestCase::Che
ckDeviceQueueStopped, |
| 219 this, txDev, true, "The device queue must be stopped a
fter 25ms"); |
| 220 Simulator::Schedule (Time (MilliSeconds (25)), &TcFlowControlTestCase::Che
ckPacketsInQueueDisc, |
| 221 this, txDev, 1, "There must be 1 packet in the queue d
isc after 25ms"); |
| 222 |
| 223 // After 33ms, we have 5 packets in the device queue (stopped) and the que
ue disc is empty |
| 224 Simulator::Schedule (Time (MilliSeconds (33)), &TcFlowControlTestCase::Che
ckPacketsInDeviceQueue, |
| 225 this, txDev, 5, "There must be 5 packets in the device
queue after 33ms"); |
| 226 Simulator::Schedule (Time (MilliSeconds (33)), &TcFlowControlTestCase::Che
ckDeviceQueueStopped, |
| 227 this, txDev, true, "The device queue must be stopped a
fter 33ms"); |
| 228 Simulator::Schedule (Time (MilliSeconds (33)), &TcFlowControlTestCase::Che
ckPacketsInQueueDisc, |
| 229 this, txDev, 0, "The queue disc must be empty after 33
ms"); |
| 230 |
| 231 // After 41ms, we have 4 packets in the device queue (not stopped) and the
queue disc is empty |
| 232 Simulator::Schedule (Time (MilliSeconds (41)), &TcFlowControlTestCase::Che
ckPacketsInDeviceQueue, |
| 233 this, txDev, 4, "There must be 4 packets in the device
queue after 41ms"); |
| 234 Simulator::Schedule (Time (MilliSeconds (41)), &TcFlowControlTestCase::Che
ckDeviceQueueStopped, |
| 235 this, txDev, false, "The device queue must not be stop
ped after 41ms"); |
| 236 Simulator::Schedule (Time (MilliSeconds (41)), &TcFlowControlTestCase::Che
ckPacketsInQueueDisc, |
| 237 this, txDev, 0, "The queue disc must be empty after 41
ms"); |
| 238 |
| 239 // After 81ms, all packets must have been transmitted (the device queue an
d the queue disc are empty) |
| 240 Simulator::Schedule (Time (MilliSeconds (81)), &TcFlowControlTestCase::Che
ckPacketsInDeviceQueue, |
| 241 this, txDev, 0, "The device queue must be empty after
81ms"); |
| 242 Simulator::Schedule (Time (MilliSeconds (81)), &TcFlowControlTestCase::Che
ckDeviceQueueStopped, |
| 243 this, txDev, false, "The device queue must not be stop
ped after 81ms"); |
| 244 Simulator::Schedule (Time (MilliSeconds (81)), &TcFlowControlTestCase::Che
ckPacketsInQueueDisc, |
| 245 this, txDev, 0, "The queue disc must be empty after 81
ms"); |
| 246 } |
| 247 else |
| 248 { |
| 249 /* |
| 250 * When the device queue is in byte mode, all the packets enqueued in the |
| 251 * queue disc are correctly transmitted, even if the device queue is stopp
ed |
| 252 * when the last packet is received from the upper layers |
| 253 */ |
| 254 |
| 255 // The transmission of each packet takes 1000B/1Mbps = 8ms |
| 256 // After 1ms, we have 3 packets in the device queue (stopped) and 6 in the
queue disc |
| 257 Simulator::Schedule (Time (MilliSeconds (1)), &TcFlowControlTestCase::Chec
kPacketsInDeviceQueue, |
| 258 this, txDev, 3, "There must be 3 packets in the device
queue after 1ms"); |
| 259 Simulator::Schedule (Time (MilliSeconds (1)), &TcFlowControlTestCase::Chec
kDeviceQueueStopped, |
| 260 this, txDev, true, "The device queue must be stopped a
fter 1ms"); |
| 261 Simulator::Schedule (Time (MilliSeconds (1)), &TcFlowControlTestCase::Chec
kPacketsInQueueDisc, |
| 262 this, txDev, 6, "There must be 6 packets in the queue
disc after 1ms"); |
| 263 |
| 264 // After 9ms, we have 3 packets in the device queue (stopped) and 5 in the
queue disc |
| 265 Simulator::Schedule (Time (MilliSeconds (9)), &TcFlowControlTestCase::Chec
kPacketsInDeviceQueue, |
| 266 this, txDev, 3, "There must be 3 packets in the device
queue after 9ms"); |
| 267 Simulator::Schedule (Time (MilliSeconds (9)), &TcFlowControlTestCase::Chec
kDeviceQueueStopped, |
| 268 this, txDev, true, "The device queue must be stopped a
fter 9ms"); |
| 269 Simulator::Schedule (Time (MilliSeconds (9)), &TcFlowControlTestCase::Chec
kPacketsInQueueDisc, |
| 270 this, txDev, 5, "There must be 5 packets in the queue
disc after 9ms"); |
| 271 |
| 272 // After 17ms, we have 3 packets in the device queue (stopped) and 4 in th
e queue disc |
| 273 Simulator::Schedule (Time (MilliSeconds (17)), &TcFlowControlTestCase::Che
ckPacketsInDeviceQueue, |
| 274 this, txDev, 3, "There must be 3 packets in the device
queue after 17ms"); |
| 275 Simulator::Schedule (Time (MilliSeconds (17)), &TcFlowControlTestCase::Che
ckDeviceQueueStopped, |
| 276 this, txDev, true, "The device queue must be stopped a
fter 17ms"); |
| 277 Simulator::Schedule (Time (MilliSeconds (17)), &TcFlowControlTestCase::Che
ckPacketsInQueueDisc, |
| 278 this, txDev, 4, "There must be 4 packets in the queue
disc after 17ms"); |
| 279 |
| 280 // After 25ms, we have 3 packets in the device queue (stopped) and 3 in th
e queue disc |
| 281 Simulator::Schedule (Time (MilliSeconds (25)), &TcFlowControlTestCase::Che
ckPacketsInDeviceQueue, |
| 282 this, txDev, 3, "There must be 3 packets in the device
queue after 25ms"); |
| 283 Simulator::Schedule (Time (MilliSeconds (25)), &TcFlowControlTestCase::Che
ckDeviceQueueStopped, |
| 284 this, txDev, true, "The device queue must be stopped a
fter 25ms"); |
| 285 Simulator::Schedule (Time (MilliSeconds (25)), &TcFlowControlTestCase::Che
ckPacketsInQueueDisc, |
| 286 this, txDev, 3, "There must be 3 packets in the queue
disc after 25ms"); |
| 287 |
| 288 // After 33ms, we have 3 packets in the device queue (stopped) and 2 in th
e queue disc |
| 289 Simulator::Schedule (Time (MilliSeconds (33)), &TcFlowControlTestCase::Che
ckPacketsInDeviceQueue, |
| 290 this, txDev, 3, "There must be 3 packets in the device
queue after 33ms"); |
| 291 Simulator::Schedule (Time (MilliSeconds (33)), &TcFlowControlTestCase::Che
ckDeviceQueueStopped, |
| 292 this, txDev, true, "The device queue must be stopped a
fter 33ms"); |
| 293 Simulator::Schedule (Time (MilliSeconds (33)), &TcFlowControlTestCase::Che
ckPacketsInQueueDisc, |
| 294 this, txDev, 2, "There must be 2 packets in the queue
disc after 33ms"); |
| 295 |
| 296 // After 41ms, we have 3 packets in the device queue (stopped) and 1 in th
e queue disc |
| 297 Simulator::Schedule (Time (MilliSeconds (41)), &TcFlowControlTestCase::Che
ckPacketsInDeviceQueue, |
| 298 this, txDev, 3, "There must be 3 packets in the device
queue after 41ms"); |
| 299 Simulator::Schedule (Time (MilliSeconds (41)), &TcFlowControlTestCase::Che
ckDeviceQueueStopped, |
| 300 this, txDev, true, "The device queue must be stopped a
fter 41ms"); |
| 301 Simulator::Schedule (Time (MilliSeconds (41)), &TcFlowControlTestCase::Che
ckPacketsInQueueDisc, |
| 302 this, txDev, 1, "There must be 1 packet in the queue d
isc after 41ms"); |
| 303 |
| 304 // After 49ms, we have 3 packets in the device queue (stopped) and the que
ue disc is empty |
| 305 Simulator::Schedule (Time (MilliSeconds (49)), &TcFlowControlTestCase::Che
ckPacketsInDeviceQueue, |
| 306 this, txDev, 3, "There must be 3 packets in the device
queue after 49ms"); |
| 307 Simulator::Schedule (Time (MilliSeconds (49)), &TcFlowControlTestCase::Che
ckDeviceQueueStopped, |
| 308 this, txDev, true, "The device queue must be stopped a
fter 49ms"); |
| 309 Simulator::Schedule (Time (MilliSeconds (49)), &TcFlowControlTestCase::Che
ckPacketsInQueueDisc, |
| 310 this, txDev, 0, "The queue disc must be empty after 49
ms"); |
| 311 |
| 312 // After 57ms, we have 2 packets in the device queue (not stopped) and the
queue disc is empty |
| 313 Simulator::Schedule (Time (MilliSeconds (57)), &TcFlowControlTestCase::Che
ckPacketsInDeviceQueue, |
| 314 this, txDev, 2, "There must be 2 packets in the device
queue after 57ms"); |
| 315 Simulator::Schedule (Time (MilliSeconds (57)), &TcFlowControlTestCase::Che
ckDeviceQueueStopped, |
| 316 this, txDev, false, "The device queue must not be stop
ped after 57ms"); |
| 317 Simulator::Schedule (Time (MilliSeconds (57)), &TcFlowControlTestCase::Che
ckPacketsInQueueDisc, |
| 318 this, txDev, 0, "The queue disc must be empty after 57
ms"); |
| 319 |
| 320 // After 81ms, all packets must have been transmitted (the device queue an
d the queue disc are empty) |
| 321 Simulator::Schedule (Time (MilliSeconds (81)), &TcFlowControlTestCase::Che
ckPacketsInDeviceQueue, |
| 322 this, txDev, 0, "The device queue must be empty after
81ms"); |
| 323 Simulator::Schedule (Time (MilliSeconds (81)), &TcFlowControlTestCase::Che
ckDeviceQueueStopped, |
| 324 this, txDev, false, "The device queue must not be stop
ped after 81ms"); |
| 325 Simulator::Schedule (Time (MilliSeconds (81)), &TcFlowControlTestCase::Che
ckPacketsInQueueDisc, |
| 326 this, txDev, 0, "The queue disc must be empty after 81
ms"); |
| 327 } |
| 328 |
| 329 Simulator::Run (); |
| 330 Simulator::Destroy (); |
| 331 } |
| 332 |
| 333 static class TcFlowControlTestSuite : public TestSuite |
| 334 { |
| 335 public: |
| 336 TcFlowControlTestSuite () |
| 337 : TestSuite ("tc-flow-control", UNIT) |
| 338 { |
| 339 AddTestCase (new TcFlowControlTestCase (TcFlowControlTestCase::PACKET_MODE),
TestCase::QUICK); |
| 340 AddTestCase (new TcFlowControlTestCase (TcFlowControlTestCase::BYTE_MODE), T
estCase::QUICK); |
| 341 } |
| 342 } g_tcFlowControlTestSuite; |
LEFT | RIGHT |