update NSC TCP tests to new TCP implementation
authorTom Henderson <tomh@tomh.org>
Sun, 08 Nov 2015 09:37:52 -0800
changeset 11757 2b50450e9c54
parent 11756 00131b06b886
child 11758 44c7b90ce85b
update NSC TCP tests to new TCP implementation
src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc
src/test/ns3tcp/ns3tcp-interop-test-suite.cc
src/test/ns3tcp/response-vectors/ns3tcp-interop-response-vectors.pcap
--- a/src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc	Sun Nov 01 18:48:16 2015 +0100
+++ b/src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc	Sun Nov 08 09:37:52 2015 -0800
@@ -55,7 +55,7 @@
 // The topology is just two nodes communicating over a point-to-point network.
 // The point-to-point network is chosen because it is simple and allows us to
 // easily generate pcap traces we can use to separately verify that the ns-3
-// implementation is responding correctly.  Once the oopration is verified, we
+// implementation is responding correctly.  Once the operation is verified, we
 // enter a list of responses that capture the response succinctly.
 //
 //         node 0                 node 1
@@ -226,6 +226,7 @@
 Ns3TcpCwndTestCase1::CwndChange (uint32_t oldCwnd, uint32_t newCwnd)
 {
   CwndEvent event;
+  NS_LOG_DEBUG ("Cwnd change event at " << Now ().As (Time::S) << " " << oldCwnd << " " << newCwnd);
 
   event.m_oldCwnd = oldCwnd;
   event.m_newCwnd = newCwnd;
@@ -236,8 +237,9 @@
 void
 Ns3TcpCwndTestCase1::DoRun (void)
 {
+  NS_LOG_DEBUG ("Starting test case 1");
   //
-  // Just create two nodes.  One (node zero) will be the node with the TCP
+  // Create two nodes.  One (node zero) will be the node with the TCP
   // under test which is the ns-3 TCP implementation.  The other node (node
   // one) will be the node with the reference implementation we use to drive
   // the tests.
@@ -254,9 +256,6 @@
   pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
   pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
 
-  //
-  // Install the point-to-point devices on both nodes and connec them up.
-  //
   NetDeviceContainer devices;
   devices = pointToPoint.Install (nodes);
 
@@ -296,20 +295,9 @@
   sinkApps.Stop (Seconds (1.1));
 
   //
-  // We want to look at changes in the ns-3 TCP congestion window.  The 
-  // congestion window is flow clontrol imposed by the sender, so we need
-  // to crank up a flow from the ns-3 TCP node to the NSC TCP node and hook the
-  // CongestionWindow attribute on the socket.  Normally one would use an on-off
-  // application to generate a flow, but this has a couple of problems.  First,
-  // the socket of the on-off application is not created until Application Start
-  // time, so we wouldn't be able to hook the socket now at configuration time.
-  // Second, even if we could arrange a call after start time, the socket is not 
-  // public.
-  //
-  // So, we can cook up a simple version of the on-off application that does what
-  // we want.  On the plus side we don't need all of the complexity of the on-off
-  // application.  On the minus side, we don't have a helper, so we have to get
-  // a little more involved in the details, but this is trivial.
+  // This test uses a custom application that provides a direct handle to
+  // the socket (the socket of applications such as the OnOffApplication
+  // is not created until Application Start time, and is not easily accessible).
   //
   // So first, we create a socket and do the trace connect on it; then we pass this
   // socket into the constructor of our simple application which we then install
@@ -319,6 +307,10 @@
   ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeCallback (&Ns3TcpCwndTestCase1::CwndChange, this));
 
   Ptr<SimpleSource> app = CreateObject<SimpleSource> ();
+  // 1040 is size of packet objects used to write data to the socket (note:
+  // the actual TCP segment size will be 536 bytes).  10 is the number
+  // of packets, so we write 10 * 1040 bytes.  This requires 20 segments
+  // of payload size 536, with the last one being a partially full segment
   app->Setup (ns3TcpSocket, sinkAddress, 1040, 10, DataRate ("5Mbps"));
   nodes.Get (0)->AddApplication (app);
   app->SetStartTime (Seconds (1.));
@@ -333,7 +325,7 @@
   // program.  So we provide the ability to generate a pcap trace of the 
   // test execution for your perusal.
   //
-  // Once the validation test is determined to be running exactly as exptected,
+  // Once the validation test is determined to be running exactly as expected,
   // the set of congestion window changes is collected and hard coded into the 
   // test results which will then be checked during the actual execution of the
   // test.
@@ -357,13 +349,11 @@
   // transmits its bits
   //
   // From inspecting the results, we know that we should see N_EVENTS congestion
-  // window change events.  The window should expand N_EVENTS - 1 times (each
-  // time by MSS bytes) until it gets to its largest value.  Then the application
-  // sending stops and the window should be slammed shut, with the last event 
-  // reflecting the change from LARGEST_CWND back to MSS
+  // window change events (each time by MSS bytes) until reaching the largest
+  // value when the client closes.
   //
   const uint32_t MSS = 536;
-  const uint32_t N_EVENTS = 21;
+  const uint32_t N_EVENTS = 20;
 
   CwndEvent event;
 
@@ -430,6 +420,7 @@
 Ns3TcpCwndTestCase2::CwndChange (uint32_t oldCwnd, uint32_t newCwnd)
 {
   CwndEvent event;
+  NS_LOG_DEBUG ("Cwnd change event at " << Now ().As (Time::S) << " " << oldCwnd << " " << newCwnd);
 
   event.m_oldCwnd = oldCwnd;
   event.m_newCwnd = newCwnd;
@@ -440,6 +431,7 @@
 void
 Ns3TcpCwndTestCase2::DoRun (void)
 { 
+  NS_LOG_DEBUG ("Starting test case 2");
   // Set up some default values for the simulation.
   Config::SetDefault ("ns3::DropTailQueue::MaxPackets", UintegerValue (4));
 
@@ -531,10 +523,8 @@
   // cut in half, and then add 3 segments (5360/2 + 3*536 = 4288)
   //
   
-  
-  
   const uint32_t MSS = 536;
-  const uint32_t N_EVENTS = 37;
+  const uint32_t N_EVENTS = 38;
 
   CwndEvent event;
 
@@ -543,39 +533,46 @@
   // Ignore the first event logged (i=0) when m_cWnd goes from 0 to MSS bytes
   VerifyCwndRun (1, 10, 2 * MSS, MSS);
   
-  // Cwnd should be back to (10/2 + 3) = 8*MSS
+  // At the point of loss, sndNxt = 15009; sndUna = 9113, so there are 
+  // 11 segments outstanding.  Cut ssthresh to 11/2 and cwnd to (11/2 + 3)
+  // Cwnd should be back to (11/2 + 3) = 8.5*MSS
   event = m_responses.Get (10);
-  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, 8*MSS, "Wrong new cwnd value in cwnd change event " << 10);
+  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, (MSS * 17)/2, "Wrong new cwnd value in cwnd change event " << 10);
 
-  VerifyCwndRun (11, 13, 9 * MSS, MSS);
+  // Verify that cwnd increments by one for a few segments
+  // from 9.5 at index 11 to 12.5 at index 14
+  VerifyCwndRun (11, 14, (MSS * 19)/2, MSS);
   
-  // partial ack, cwnd reset to 9
-  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (14).m_newCwnd, 9 * MSS, "Wrong new cwnd value in cwnd change event " << 14);
-
-  // partial ack, cwnd reset to 8 
-  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (16).m_newCwnd, 8 * MSS, "Wrong new cwnd value in cwnd change event " << 16);
+  // partial ack at event 15, cwnd reset from 6700 (12.5*MSS) to 5628 (10.5*MSS)
+  // ack of 3 segments, so deflate by 3, and add back one
+  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (15).m_newCwnd, (MSS * 21)/2, "Wrong new cwnd value in cwnd change event " << 15);
 
-  //DUP ACKS in fast recovery
-  VerifyCwndRun (17, 18, 9 * MSS, MSS);
+  // partial ack again of 3 segments after one more acks, cwnd reset to 9.5 
+  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (17).m_newCwnd, (MSS * 19)/2, "Wrong new cwnd value in cwnd change event " << 17);
 
-  VerifyCwndRun (19, 22, 8 * MSS, MSS);
+  //DUP ACKS in remaining fast recovery
+  VerifyCwndRun (18, 19, (MSS * 21)/2, MSS);
+
+  // another partial ack
+  //DUP ACKS in remaining fast recovery
+  VerifyCwndRun (21, 23, (MSS * 21)/2, MSS);
   
-  //Leaving fast recovery
-  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (23).m_newCwnd, 5 * MSS, "Wrong new cwnd value in cwnd change event " << 23);  
+  //Leaving fast recovery at event 24; set cwnd to 11/2 from above
+  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (24).m_newCwnd,  (MSS * 11)/2, "Wrong new cwnd value in cwnd change event " << 24);  
   
-  uint32_t cwnd = 5 * MSS;
+  uint32_t cwnd = 11 * MSS/2;
   //In CongAvoid each event will increase cwnd by (MSS * MSS / cwnd)
-  for (uint32_t i = 24; i < N_EVENTS; ++i)
+  for (uint32_t i = 25; i < N_EVENTS; ++i)
     {
       double adder = static_cast<double> (MSS * MSS) / cwnd;
       adder = std::max (1.0, adder);
       cwnd += static_cast<uint32_t> (adder);    
       NS_TEST_ASSERT_MSG_EQ (m_responses.Get (i).m_newCwnd, cwnd, "Wrong new cwnd value in cwnd change event " << i); 
     }
-    
+  NS_LOG_DEBUG ("Reading out the cwnd event log");  
   for (uint32_t i = 0; i < N_EVENTS; ++i)
   {
-    std::cout << "i: " << i << " newCwnd: " << m_responses.Get(i).m_newCwnd << " newCwnd segments " << static_cast<double> (m_responses.Get(i).m_newCwnd)/MSS << std::endl;
+    NS_LOG_DEBUG ("i: " << i << " newCwnd: " << m_responses.Get(i).m_newCwnd << " newCwnd segments " << static_cast<double> (m_responses.Get(i).m_newCwnd)/MSS);
   }
 }
 
--- a/src/test/ns3tcp/ns3tcp-interop-test-suite.cc	Sun Nov 01 18:48:16 2015 +0100
+++ b/src/test/ns3tcp/ns3tcp-interop-test-suite.cc	Sun Nov 08 09:37:52 2015 -0800
@@ -61,7 +61,7 @@
 // The topology is just two nodes communicating over a point-to-point network.
 // The point-to-point network is chosen because it is simple and allows us to
 // easily generate pcap traces we can use to separately verify that the ns-3
-// implementation is responding correctly.  Once the opration is verified, we
+// implementation is responding correctly.  Once the operation is verified, we
 // capture a set of response vectors that are then checked in the test to
 // ensure that the ns-3 TCP continues to respond correctly over time.
 //
@@ -281,7 +281,7 @@
   // program.  So we provide the ability to generate a pcap trace of the 
   // test execution for your perusal.
   //
-  // Once the validation test is determined to be running exactly as exptected,
+  // Once the validation test is determined to be running exactly as expected,
   // we allow you to generate a file that contains the response vectors that 
   // will be checked during the actual execution of the test.
   //
Binary file src/test/ns3tcp/response-vectors/ns3tcp-interop-response-vectors.pcap has changed