24 #include "ns3/cobalt-queue-disc.h" 
   25 #include "ns3/double.h" 
   27 #include "ns3/packet.h" 
   28 #include "ns3/simulator.h" 
   29 #include "ns3/string.h" 
   31 #include "ns3/uinteger.h" 
   58     void AddHeader() 
override;
 
   69       m_ecnCapablePacket(ecnCapable)
 
  106     void DoRun() 
override;
 
  121     : 
TestCase(
"Basic enqueue and dequeue operations, and attribute setting" + std::to_string(mode))
 
  132     uint32_t modeSize = 0;
 
  138                           "Verify that we can actually set the attribute Interval");
 
  141                           "Verify that we can actually set the attribute Target");
 
  144                           "Disable Blue enhancement");
 
  157         "Verify that we can actually set the attribute MaxSize");
 
  175                           "There should be no packets in queue");
 
  176     queue->Enqueue(Create<CobaltQueueDiscTestItem>(p1, dest, 
false));
 
  179                           "There should be one packet in queue");
 
  180     queue->Enqueue(Create<CobaltQueueDiscTestItem>(p2, dest, 
false));
 
  183                           "There should be two packets in queue");
 
  184     queue->Enqueue(Create<CobaltQueueDiscTestItem>(p3, dest, 
false));
 
  187                           "There should be three packets in queue");
 
  188     queue->Enqueue(Create<CobaltQueueDiscTestItem>(p4, dest, 
false));
 
  191                           "There should be four packets in queue");
 
  192     queue->Enqueue(Create<CobaltQueueDiscTestItem>(p5, dest, 
false));
 
  195                           "There should be five packets in queue");
 
  196     queue->Enqueue(Create<CobaltQueueDiscTestItem>(p6, dest, 
false));
 
  199                           "There should be six packets in queue");
 
  203                           "There should be no packets being dropped due to full queue");
 
  207     item = queue->Dequeue();
 
  211                           "There should be five packets in queue");
 
  214     item = queue->Dequeue();
 
  218                           "There should be four packets in queue");
 
  221                           "Was this the second packet ?");
 
  223     item = queue->Dequeue();
 
  227                           "There should be three packets in queue");
 
  230     item = queue->Dequeue();
 
  234                           "There should be two packets in queue");
 
  237                           "Was this the fourth packet ?");
 
  239     item = queue->Dequeue();
 
  243                           "There should be one packet in queue");
 
  246     item = queue->Dequeue();
 
  250                           "There should be zero packet in queue");
 
  253     item = queue->Dequeue();
 
  257         queue->GetStats().GetNDroppedPackets(CobaltQueueDisc::TARGET_EXCEEDED_DROP),
 
  259         "There should be no packet drops according to Cobalt algorithm");
 
  271     void DoRun() 
override;
 
  296     : 
TestCase(
"Drop tests verification for both packets and bytes mode")
 
  305     uint32_t modeSize = 0;
 
  317     queue = CreateObject<CobaltQueueDisc>();
 
  321         "Verify that we can actually set the attribute MaxSize");
 
  324                           "Disable Blue enhancement");
 
  345                           "Drops due to queue overflow should be non-zero");
 
  353     for (uint32_t i = 0; i < nPkt; i++)
 
  355         Simulator::Schedule(
Time(
Seconds((i + 1) * delay)),
 
  368     for (uint32_t i = 0; i < nPkt; i++)
 
  370         queue->Enqueue(Create<CobaltQueueDiscTestItem>(Create<Packet>(size), dest, 
true));
 
  379     Simulator::Destroy();
 
  396     void DoRun() 
override;
 
  450     uint32_t modeSize = 0;
 
  466         "Verify that we can actually set the attribute MaxSize");
 
  469                           "Verify that we can actually set the attribute UseEcn");
 
  472                           "Disable Blue enhancement");
 
  479                           "There should be 20 packets in queue.");
 
  483     Time waitUntilFirstDequeue = 2 * queue->GetTarget();
 
  484     Simulator::Schedule(waitUntilFirstDequeue,
 
  492     Time waitUntilSecondDequeue = waitUntilFirstDequeue + 2 * queue->GetInterval();
 
  493     Simulator::Schedule(waitUntilSecondDequeue,
 
  501     Simulator::Destroy();
 
  504     queue = CreateObject<CobaltQueueDisc>();
 
  508         "Verify that we can actually set the attribute MaxSize");
 
  511                           "Verify that we can actually set the attribute UseEcn");
 
  514                           "Disable Blue enhancement");
 
  521                           "There should be 20 packets in queue.");
 
  525     Simulator::Schedule(waitUntilFirstDequeue,
 
  533     Simulator::Schedule(waitUntilSecondDequeue,
 
  541     Simulator::Schedule(waitUntilSecondDequeue,
 
  550     Simulator::Schedule(waitUntilSecondDequeue * 2,
 
  558     Simulator::Destroy();
 
  561     queue = CreateObject<CobaltQueueDisc>();
 
  565         "Verify that we can actually set the attribute MaxSize");
 
  568                           "Verify that we can actually set the attribute UseEcn");
 
  571                           "Disable Blue enhancement");
 
  580                           "There should be 20 packets in queue.");
 
  584     Simulator::Schedule(waitUntilFirstDequeue,
 
  592     Simulator::Schedule(waitUntilSecondDequeue,
 
  600     Simulator::Schedule(waitUntilSecondDequeue,
 
  609     Simulator::Schedule(waitUntilSecondDequeue * 2,
 
  617     Simulator::Destroy();
 
  627     for (uint32_t i = 0; i < nPkt; i++)
 
  629         queue->Enqueue(Create<CobaltQueueDiscTestItem>(Create<Packet>(size), dest, ecnCapable));
 
  636     uint32_t initialMarkCount = queue->GetStats().GetNMarkedPackets(CobaltQueueDisc::FORCED_MARK);
 
  637     uint32_t initialQSize = queue->GetCurrentSize().GetValue();
 
  638     uint32_t initialDropNext = queue->GetDropNext();
 
  640     uint32_t currentDropCount = 0;
 
  641     uint32_t currentMarkCount = 0;
 
  643     if (initialMarkCount > 0 && currentTime.
GetNanoSeconds() > initialDropNext && testCase == 3)
 
  645         queue->TraceConnectWithoutContext(
 
  650     if (initialQSize != 0)
 
  656                 queue->GetStats().GetNDroppedPackets(CobaltQueueDisc::TARGET_EXCEEDED_DROP);
 
  657             if (currentDropCount != 0)
 
  664             if (initialMarkCount == 0 && currentTime > queue->GetTarget())
 
  666                 if (currentTime < queue->GetInterval())
 
  669                         queue->GetStats().GetNDroppedPackets(CobaltQueueDisc::TARGET_EXCEEDED_DROP);
 
  671                         queue->GetStats().GetNMarkedPackets(CobaltQueueDisc::FORCED_MARK);
 
  673                                           initialQSize - modeSize,
 
  674                                           "There should be 1 packet dequeued.");
 
  677                                           "There should not be any packet drops");
 
  680                                           "We are not in dropping state." 
  681                                           "Sojourn time has just gone above target from below." 
  682                                           "Hence, there should be no marked packets");
 
  684                 else if (currentTime >= queue->GetInterval())
 
  688                         queue->GetStats().GetNDroppedPackets(CobaltQueueDisc::TARGET_EXCEEDED_DROP);
 
  690                         queue->GetStats().GetNMarkedPackets(CobaltQueueDisc::FORCED_MARK);
 
  692                         queue->GetCurrentSize().GetValue(),
 
  693                         initialQSize - modeSize,
 
  694                         "Sojourn time has been above target for at least interval." 
  695                         "We enter the dropping state and perform initial packet marking" 
  696                         "So there should be only 1 more packet dequeued.");
 
  699                                           "There should not be any packet drops");
 
  703             else if (initialMarkCount > 0)
 
  708                         queue->GetStats().GetNDroppedPackets(CobaltQueueDisc::TARGET_EXCEEDED_DROP);
 
  710                         queue->GetStats().GetNMarkedPackets(CobaltQueueDisc::FORCED_MARK);
 
  712                                           initialQSize - modeSize,
 
  713                                           "We are in dropping state." 
  714                                           "Sojourn is still above target." 
  715                                           "There should be only 1 more packet dequeued");
 
  718                                           "There should not be any packet drops");
 
  721                                           "There should be 2 marked packet as." 
  722                                           "current dropnext is equal to current time.");
 
  727                         queue->GetStats().GetNDroppedPackets(CobaltQueueDisc::TARGET_EXCEEDED_DROP);
 
  729                         queue->GetStats().GetNMarkedPackets(CobaltQueueDisc::FORCED_MARK);
 
  731                                           initialQSize - modeSize,
 
  732                                           "We are in dropping state." 
  733                                           "It's time for packet to be marked" 
  734                                           "So there should be only 1 more packet dequeued");
 
  737                                           "There should not be any packet drops");
 
  742                         "Number of packets in the queue before drop should be equal" 
  743                         "to number of packets in the queue before first mark as the behavior until " 
  744                         "packet N should be the same.");
 
  748         else if (testCase == 3)
 
  750             if (initialMarkCount == 0 && currentTime > queue->GetTarget())
 
  752                 if (currentTime < queue->GetInterval())
 
  755                         queue->GetStats().GetNDroppedPackets(CobaltQueueDisc::TARGET_EXCEEDED_DROP);
 
  757                         queue->GetStats().GetNMarkedPackets(CobaltQueueDisc::FORCED_MARK);
 
  759                                           initialQSize - modeSize,
 
  760                                           "There should be 1 packet dequeued.");
 
  763                                           "There should not be any packet drops");
 
  766                                           "We are not in dropping state." 
  767                                           "Sojourn time has just gone above target from below." 
  768                                           "Hence, there should be no marked packets");
 
  770                 else if (currentTime >= queue->GetInterval())
 
  773                         queue->GetStats().GetNDroppedPackets(CobaltQueueDisc::TARGET_EXCEEDED_DROP);
 
  775                         queue->GetStats().GetNMarkedPackets(CobaltQueueDisc::FORCED_MARK);
 
  777                         queue->GetCurrentSize().GetValue(),
 
  778                         initialQSize - modeSize,
 
  779                         "Sojourn time has been above target for at least interval." 
  780                         "We enter the dropping state and perform initial packet marking" 
  781                         "So there should be only 1 more packet dequeued.");
 
  784                                           "There should not be any packet drops");
 
  788             else if (initialMarkCount > 0)
 
  793                         queue->GetStats().GetNDroppedPackets(CobaltQueueDisc::TARGET_EXCEEDED_DROP);
 
  795                         queue->GetStats().GetNMarkedPackets(CobaltQueueDisc::FORCED_MARK);
 
  797                                           initialQSize - modeSize,
 
  798                                           "We are in dropping state." 
  799                                           "Sojourn is still above target." 
  800                                           "So there should be only 1 more packet dequeued");
 
  803                                           "There should not be any packet drops");
 
  806                                           "There should be 2 marked packet" 
  807                                           "as dropnext is equal to current time");
 
  812                         queue->GetStats().GetNDroppedPackets(CobaltQueueDisc::TARGET_EXCEEDED_DROP);
 
  814                         queue->GetStats().GetNMarkedPackets(CobaltQueueDisc::FORCED_MARK);
 
  816                         queue->GetCurrentSize().GetValue(),
 
  818                         "We are in dropping state." 
  819                         "It's time for packet to be dropped as packets are not ecnCapable" 
  820                         "The number of packets dequeued equals to the number of times m_dropNext " 
  821                         "is updated plus initial dequeue");
 
  825                         "The number of drops equals to the number of times m_dropNext is updated");
 
  828                                           "There should still be only 2 marked packet");
 
  852     void DoRun() 
override;
 
  886     : 
TestCase(
"Test CE Threshold marking")
 
  899     for (uint32_t i = 0; i < nPkt; i++)
 
  901         queue->Enqueue(Create<CobaltQueueDiscTestItem>(Create<Packet>(size), dest, 
true));
 
  911     for (uint32_t i = 0; i < nPkt; i++)
 
  930             queue->GetStats().GetNMarkedPackets(CobaltQueueDisc::CE_THRESHOLD_EXCEEDED_MARK),
 
  932             "There should be only 1 packet" 
  933             "mark, the delay between the enqueueing of the packets decreased after the" 
  934             "1st mark (packet enqueued at 11ms) and increased for the packet enqueued after 20.6ms." 
  935             "Queue delay remains below or equal to 1ms for the packet enqueued before 28ms");
 
  940             queue->GetStats().GetNMarkedPackets(CobaltQueueDisc::CE_THRESHOLD_EXCEEDED_MARK),
 
  942             "There should be 3 packet" 
  943             "marks, the delay between the enqueueing of the packets decreased after 1st mark" 
  944             "(packet enqueued at 11ms) and increased for the packet enqueued after 20.6ms." 
  945             "Queue delay remains below 1ms for the packets enqueued before 28ms and increases" 
  946             "for the packets enqueued after 28ms.");
 
  956     for (uint32_t i = 0; i < nPkt; i++)
 
  971     uint32_t modeSize = 0;
 
  984                           "Verify that we can actually set the attribute UseEcn");
 
  987                           "Verify that we can actually set the attribute UseEcn");
 
  990                           "Disable Blue enhancement");
 
 1005     Simulator::Schedule(waitUntilFirstMark,
 
 1014     Simulator::Schedule(waitUntilFirstMark,
 
 1024     Time waitUntilDecreasingEnqueueDelay = waitUntilFirstMark + 
MilliSeconds(9);
 
 1025     Simulator::Schedule(waitUntilDecreasingEnqueueDelay,
 
 1034     Simulator::Schedule(waitUntilFirstMark,
 
 1043     Simulator::Destroy();
 
 1070     void DoRun() 
override;
 
 1094     : 
TestCase(
"Enhanced Blue tests verification for both packets and bytes mode")
 
 1108     uint32_t modeSize = 0;
 
 1119     queue->Initialize();
 
 1120     queue->AssignStreams(1);
 
 1121     Enqueue(queue, modeSize, 200);
 
 1124     Simulator::Stop(
Seconds(8.0));
 
 1133         "Pdrop should be increased by 1/256 for every packet whose sojourn time is above 400ms." 
 1134         " From the 41st dequeue until the last one, sojourn time is above 400ms, so 60 packets " 
 1135         "have sojourn time above 400ms" 
 1136         "hence Pdrop should be increased 60*(1/256) which is 0.234375");
 
 1139                           "There should a fixed number of drops (49 here)");
 
 1140     Simulator::Destroy();
 
 1142     queue = CreateObject<CobaltQueueDisc>();
 
 1145                           "Verify that we can actually set the attribute UseEcn");
 
 1148                           "Disable Blue enhancement");
 
 1149     queue->Initialize();
 
 1150     Enqueue(queue, modeSize, 200);
 
 1153     Simulator::Stop(
Seconds(8.0));
 
 1156     st = queue->GetStats();
 
 1161                           "There should not any dropped packets");
 
 1162     Simulator::Destroy();
 
 1169     for (uint32_t i = 0; i < nPkt; i++)
 
 1171         queue->Enqueue(Create<CobaltQueueDiscTestItem>(Create<Packet>(size), dest, 
true));
 
 1186     for (uint32_t i = 0; i < nPkt; i++)
 
Test 1: simple enqueue/dequeue with no drops.
QueueSizeUnit m_mode
Queue test size function.
void DoRun() override
Implementation to actually run this TestCase.
CobaltQueueDiscBasicEnqueueDequeue(QueueSizeUnit mode)
Constructor.
Test 4: Cobalt Queue Disc CE Threshold marking Test Item.
~CobaltQueueDiscCeThresholdTest() override
CobaltQueueDiscCeThresholdTest(QueueSizeUnit mode)
Constructor.
void DoRun() override
Implementation to actually run this TestCase.
void DequeueWithDelay(Ptr< CobaltQueueDisc > queue, uint32_t modeSize, uint32_t nPkt, Time delay)
Dequeue with delay function.
void Enqueue(Ptr< CobaltQueueDisc > queue, uint32_t size, uint32_t nPkt)
Enqueue function.
void EnqueueWithDelay(Ptr< CobaltQueueDisc > queue, uint32_t size, uint32_t nPkt, Time delay)
Enqueue with delay function.
void Dequeue(Ptr< CobaltQueueDisc > queue, uint32_t modeSize)
Dequeue function.
Test 2: Cobalt Queue Disc Drop Test Item.
void DoRun() override
Implementation to actually run this TestCase.
void RunDropTest(QueueSizeUnit mode)
Run Cobalt test function.
void Enqueue(Ptr< CobaltQueueDisc > queue, uint32_t size, uint32_t nPkt)
Enqueue function.
void EnqueueWithDelay(Ptr< CobaltQueueDisc > queue, uint32_t size, uint32_t nPkt)
Enqueue the given number of packets, each of the given size, at different times.
CobaltQueueDiscDropTest()
Test 5: Cobalt Queue Disc Enhanced Blue Test Item This test checks that the Blue Enhancement is worki...
CobaltQueueDiscEnhancedBlueTest(QueueSizeUnit mode)
Constructor.
void Dequeue(Ptr< CobaltQueueDisc > queue)
Dequeue function.
void DoRun() override
Implementation to actually run this TestCase.
void Enqueue(Ptr< CobaltQueueDisc > queue, uint32_t size, uint32_t nPkt)
Enqueue function.
void DequeueWithDelay(Ptr< CobaltQueueDisc > queue, uint32_t nPkt, Time delay)
Dequeue with delay function.
~CobaltQueueDiscEnhancedBlueTest() override
Test 3: Cobalt Queue Disc ECN marking Test Item.
CobaltQueueDiscMarkTest(QueueSizeUnit mode)
Constructor.
uint32_t nPacketsBeforeFirstMark
Number of packets in the queue before first mark.
void Enqueue(Ptr< CobaltQueueDisc > queue, uint32_t size, uint32_t nPkt, bool ecnCapable)
Enqueue function.
void DropNextTracer(int64_t oldVal, int64_t newVal)
Drop next tracer function.
uint32_t nPacketsBeforeFirstDrop
Number of packets in the queue before first drop.
void DoRun() override
Implementation to actually run this TestCase.
void Dequeue(Ptr< CobaltQueueDisc > queue, uint32_t modeSize, uint32_t testCase)
Dequeue function.
uint32_t m_dropNextCount
count the number of times m_dropNext is recalculated
Cobalt Queue Disc Test Item.
bool m_ecnCapablePacket
ECN capable packet?
CobaltQueueDiscTestItem()=delete
~CobaltQueueDiscTestItem() override
void AddHeader() override
Add the header to the packet.
CobaltQueueDiscTestItem & operator=(const CobaltQueueDiscTestItem &)=delete
CobaltQueueDiscTestItem(const CobaltQueueDiscTestItem &)=delete
bool Mark() override
Marks the packet as a substitute for dropping it, such as for Explicit Congestion Notification.
The COBALT queue disc test suite.
CobaltQueueDiscTestSuite()
a polymophic address class
AttributeValue implementation for Boolean.
uint64_t GetUid() const
Returns the packet's Uid.
QueueDiscItem is the abstract base class for items that are stored in a queue disc.
Class for representing queue sizes.
AttributeValue implementation for QueueSize.
Hold variables of type string.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
@ UNIT
This test suite implements a Unit Test.
Simulation virtual time values and global simulation resolution.
int64_t GetNanoSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
AttributeValue implementation for Time.
QueueSizeUnit
Enumeration of the operating modes of queues.
@ BYTES
Use number of bytes for queue size.
@ PACKETS
Use number of packets for queue size.
Time Now()
create an ns3::Time instance which contains the current simulation time.
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report and abort if not.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time Seconds(double value)
Construct a Time in the indicated unit.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
CobaltQueueDiscTestSuite g_cobaltQueueTestSuite
the test suite
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Structure that keeps the queue disc statistics.
uint32_t GetNDroppedPackets(std::string reason) const
Get the number of packets dropped for the given reason.
uint32_t pktSize
packet size used for the simulation (in bytes)