src/test/ns3tcp/ns3tcp-loss-test-suite.cc
changeset 6329 b08fe828b686
parent 6288 1bc85b014aaf
child 6549 487146fc889e
equal deleted inserted replaced
6328:f03f4d82daaf 6329:b08fe828b686
    39 
    39 
    40 using namespace ns3;
    40 using namespace ns3;
    41 
    41 
    42 NS_LOG_COMPONENT_DEFINE ("Ns3TcpLossTest");
    42 NS_LOG_COMPONENT_DEFINE ("Ns3TcpLossTest");
    43 
    43 
       
    44 const bool WRITE_VECTORS = false;           // set to true to write response vectors
       
    45 const uint32_t PCAP_LINK_TYPE = 1187373553; // Some large random number -- we use to verify data was written by this program
       
    46 const uint32_t PCAP_SNAPLEN   = 64;         // Don't bother to save much data
       
    47 
    44 // ===========================================================================
    48 // ===========================================================================
    45 // Tests of TCP implementation loss behavior
    49 // Tests of TCP implementation loss behavior
    46 // ===========================================================================
    50 // ===========================================================================
    47 //
    51 //
    48 
    52 
    51 public:
    55 public:
    52   Ns3TcpLossTestCase1 ();
    56   Ns3TcpLossTestCase1 ();
    53   virtual ~Ns3TcpLossTestCase1 () {}
    57   virtual ~Ns3TcpLossTestCase1 () {}
    54 
    58 
    55 private:
    59 private:
       
    60   virtual void DoSetup (void);
    56   virtual bool DoRun (void);
    61   virtual bool DoRun (void);
       
    62   virtual void DoTeardown (void);
       
    63 
       
    64   std::string m_pcapFilename;
       
    65   PcapFile m_pcapFile;
       
    66   bool m_writeVectors;
    57   bool m_writeResults;
    67   bool m_writeResults;
    58 
    68 
    59   void SinkRx (std::string path, Ptr<const Packet> p, const Address &address);
    69   void Ipv4L3Tx (std::string context, Ptr<const Packet> packet, Ptr<Ipv4> ipv4, uint32_t interface);
    60 
    70 
    61   TestVectors<uint32_t> m_inputs;
       
    62   TestVectors<uint32_t> m_responses;
       
    63 };
    71 };
    64 
    72 
    65 Ns3TcpLossTestCase1::Ns3TcpLossTestCase1 ()
    73 Ns3TcpLossTestCase1::Ns3TcpLossTestCase1 ()
    66   : TestCase ("Check that ns-3 TCP survives loss of first two SYNs"),
    74   : TestCase ("Check that ns-3 TCP survives loss of first two SYNs"),
       
    75     m_writeVectors (WRITE_VECTORS),
    67     m_writeResults (false)
    76     m_writeResults (false)
    68 {
    77 {
    69 }
    78 }
    70 
    79 
    71 void 
    80 void
    72 Ns3TcpLossTestCase1::SinkRx (std::string path, Ptr<const Packet> p, const Address &address)
    81 Ns3TcpLossTestCase1::DoSetup (void)
    73 {
    82 {
    74   m_responses.Add (p->GetSize ());
    83     //
       
    84     // We expect there to be a file called ns3tcp-loss1-response-vectors.pcap" in
       
    85     // the source directory of this file.
       
    86     //
       
    87     m_pcapFilename = NS_TEST_SOURCEDIR + "ns3tcp-loss1-response-vectors.pcap";
       
    88 
       
    89     if (m_writeVectors)
       
    90       {
       
    91         m_pcapFile.Open (m_pcapFilename, std::ios::out|std::ios::binary);
       
    92         m_pcapFile.Init(PCAP_LINK_TYPE, PCAP_SNAPLEN);
       
    93       }
       
    94     else
       
    95       {
       
    96         m_pcapFile.Open (m_pcapFilename, std::ios::in|std::ios::binary);
       
    97         NS_ABORT_MSG_UNLESS (m_pcapFile.GetDataLinkType () == PCAP_LINK_TYPE, "Wrong response vectors in directory");
       
    98       }
       
    99 }
       
   100 
       
   101 void
       
   102 Ns3TcpLossTestCase1::DoTeardown (void)
       
   103 {
       
   104     m_pcapFile.Close ();
       
   105 }
       
   106 
       
   107 void
       
   108 Ns3TcpLossTestCase1::Ipv4L3Tx (std::string context, Ptr<const Packet> packet, Ptr<Ipv4> ipv4, uint32_t interface)
       
   109 {
       
   110   //
       
   111   // We're not testing IP so remove and toss the header.  In order to do this,
       
   112   // though, we need to copy the packet since we have a const version.
       
   113   //
       
   114   Ptr<Packet> p = packet->Copy ();
       
   115   Ipv4Header ipHeader;
       
   116   p->RemoveHeader (ipHeader);
       
   117 
       
   118   //
       
   119   // What is left is the TCP header and any data that may be sent.  We aren't
       
   120   // sending any TCP data, so we expect what remains is only TCP header, which
       
   121   // is a small thing to save.
       
   122   //
       
   123   if (m_writeVectors)
       
   124     {
       
   125       //
       
   126       // Save the TCP under test response for later testing.
       
   127       //
       
   128       Time tNow = Simulator::Now ();
       
   129       int64_t tMicroSeconds = tNow.GetMicroSeconds ();
       
   130       m_pcapFile.Write (uint32_t (tMicroSeconds / 1000000), 
       
   131                         uint32_t (tMicroSeconds % 1000000), 
       
   132                         p->PeekData(), 
       
   133                         p->GetSize ());
       
   134     }
       
   135   else
       
   136     {
       
   137       //
       
   138       // Read the TCP under test expected response from the expected vector
       
   139       // file and see if it still does the right thing.
       
   140       //
       
   141       uint8_t expected[PCAP_SNAPLEN];
       
   142       uint32_t tsSec, tsUsec, inclLen, origLen, readLen;
       
   143       m_pcapFile.Read (expected, sizeof(expected), tsSec, tsUsec, inclLen, origLen, readLen);
       
   144 
       
   145       uint8_t const *actual = p->PeekData();
       
   146 
       
   147       uint32_t result = memcmp(actual, expected, readLen);
       
   148 
       
   149       //
       
   150       // Avoid streams of errors -- only report the first.
       
   151       //
       
   152       if (GetErrorStatus () == false)
       
   153         {
       
   154           NS_TEST_EXPECT_MSG_EQ (result, 0, "Expected data comparison error");
       
   155         }
       
   156     }
    75 }
   157 }
    76 
   158 
    77 bool
   159 bool
    78 Ns3TcpLossTestCase1::DoRun (void)
   160 Ns3TcpLossTestCase1::DoRun (void)
    79 {
   161 {
   114   ApplicationContainer apps = sink.Install (n1);
   196   ApplicationContainer apps = sink.Install (n1);
   115   // Start the sink application at time zero, and stop it at sinkStopTime
   197   // Start the sink application at time zero, and stop it at sinkStopTime
   116   apps.Start (Seconds (0.0));
   198   apps.Start (Seconds (0.0));
   117   apps.Stop (sinkStopTimeObj);
   199   apps.Stop (sinkStopTimeObj);
   118 
   200 
   119   Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::PacketSink/Rx",
   201   Config::Connect ("/NodeList/0/$ns3::Ipv4L3Protocol/Tx",
   120                    MakeCallback (&Ns3TcpLossTestCase1::SinkRx, this));
   202                    MakeCallback (&Ns3TcpLossTestCase1::Ipv4L3Tx, this));
   121 
   203 
   122   Simulator::Schedule(Seconds (2), &SocketWriter::Connect, socketWriter);
   204   Simulator::Schedule(Seconds (2), &SocketWriter::Connect, socketWriter);
   123   Simulator::Schedule(Seconds (10), &SocketWriter::Write, socketWriter, 500);
   205   Simulator::Schedule(Seconds (10), &SocketWriter::Write, socketWriter, 500);
   124   m_inputs.Add (500);
       
   125   Simulator::Schedule(writerStopTimeObj, &SocketWriter::Close, socketWriter);
   206   Simulator::Schedule(writerStopTimeObj, &SocketWriter::Close, socketWriter);
   126 
   207 
   127   std::list<uint32_t> sampleList;
   208   std::list<uint32_t> sampleList;
   128   // Lose first two SYNs
   209   // Lose first two SYNs
   129   sampleList.push_back (0);
   210   sampleList.push_back (0);
   141 
   222 
   142   Simulator::Stop (simStopTimeObj);
   223   Simulator::Stop (simStopTimeObj);
   143   Simulator::Run ();
   224   Simulator::Run ();
   144   Simulator::Destroy ();
   225   Simulator::Destroy ();
   145 
   226 
   146   // Compare inputs and outputs
       
   147   NS_TEST_ASSERT_MSG_EQ (m_inputs.GetN (), m_responses.GetN (), "Incorrect number of expected receive events");
       
   148   for (uint32_t i = 0; i < m_responses.GetN (); i++)
       
   149     {
       
   150       uint32_t in = m_inputs.Get (i);
       
   151       uint32_t out = m_responses.Get (i);
       
   152       NS_TEST_ASSERT_MSG_EQ (in, out, "Mismatch:  expected " << in << " bytes, got " << out << " bytes");
       
   153     }
       
   154 
       
   155   return GetErrorStatus ();
   227   return GetErrorStatus ();
   156 }
   228 }
   157 
   229 
   158 class Ns3TcpLossTestCase2 : public TestCase
   230 class Ns3TcpLossTestCase2 : public TestCase
   159 {
   231 {
   160 public:
   232 public:
   161   Ns3TcpLossTestCase2 ();
   233   Ns3TcpLossTestCase2 ();
   162   virtual ~Ns3TcpLossTestCase2 () {}
   234   virtual ~Ns3TcpLossTestCase2 () {}
   163 
   235 
   164 private:
   236 private:
       
   237   virtual void DoSetup (void);
   165   virtual bool DoRun (void);
   238   virtual bool DoRun (void);
       
   239   virtual void DoTeardown (void);
       
   240 
       
   241   std::string m_pcapFilename;
       
   242   PcapFile m_pcapFile;
       
   243   bool m_writeVectors;
   166   bool m_writeResults;
   244   bool m_writeResults;
   167 
   245 
   168   void SinkRx (std::string path, Ptr<const Packet> p, const Address &address);
   246   void Ipv4L3Tx (std::string context, Ptr<const Packet> packet, Ptr<Ipv4> ipv4, uint32_t interface);
   169 
       
   170   TestVectors<uint32_t> m_inputs;
       
   171   TestVectors<uint32_t> m_responses;
       
   172 };
   247 };
   173 
   248 
   174 Ns3TcpLossTestCase2::Ns3TcpLossTestCase2 ()
   249 Ns3TcpLossTestCase2::Ns3TcpLossTestCase2 ()
   175   : TestCase ("Check that ns-3 TCP survives loss of first data packet"),
   250   : TestCase ("Check that ns-3 TCP survives loss of first data packet"),
       
   251     m_writeVectors (WRITE_VECTORS),
   176     m_writeResults (false)
   252     m_writeResults (false)
   177 {
   253 {
   178 }
   254 }
   179 
   255 
   180 void 
   256 void
   181 Ns3TcpLossTestCase2::SinkRx (std::string path, Ptr<const Packet> p, const Address &address)
   257 Ns3TcpLossTestCase2::DoSetup (void)
   182 {
   258 {
   183   m_responses.Add (p->GetSize ());
   259     //
       
   260     // We expect there to be a file called ns3tcp-loss1-response-vectors.pcap" in
       
   261     // the source directory of this file.
       
   262     //
       
   263     m_pcapFilename = NS_TEST_SOURCEDIR + "ns3tcp-loss2-response-vectors.pcap";
       
   264 
       
   265     if (m_writeVectors)
       
   266       {
       
   267         m_pcapFile.Open (m_pcapFilename, std::ios::out|std::ios::binary);
       
   268         m_pcapFile.Init(PCAP_LINK_TYPE, PCAP_SNAPLEN);
       
   269       }
       
   270     else
       
   271       {
       
   272         m_pcapFile.Open (m_pcapFilename, std::ios::in|std::ios::binary);
       
   273         NS_ABORT_MSG_UNLESS (m_pcapFile.GetDataLinkType () == PCAP_LINK_TYPE, "Wrong response vectors in directory");
       
   274       }
       
   275 }
       
   276 
       
   277 void
       
   278 Ns3TcpLossTestCase2::DoTeardown (void)
       
   279 {
       
   280     m_pcapFile.Close ();
       
   281 }
       
   282 
       
   283 void
       
   284 Ns3TcpLossTestCase2::Ipv4L3Tx (std::string context, Ptr<const Packet> packet, Ptr<Ipv4> ipv4, uint32_t interface)
       
   285 {
       
   286   //
       
   287   // We're not testing IP so remove and toss the header.  In order to do this,
       
   288   // though, we need to copy the packet since we have a const version.
       
   289   //
       
   290   Ptr<Packet> p = packet->Copy ();
       
   291   Ipv4Header ipHeader;
       
   292   p->RemoveHeader (ipHeader);
       
   293 
       
   294   //
       
   295   // What is left is the TCP header and any data that may be sent.  We aren't
       
   296   // sending any TCP data, so we expect what remains is only TCP header, which
       
   297   // is a small thing to save.
       
   298   //
       
   299   if (m_writeVectors)
       
   300     {
       
   301       //
       
   302       // Save the TCP under test response for later testing.
       
   303       //
       
   304       Time tNow = Simulator::Now ();
       
   305       int64_t tMicroSeconds = tNow.GetMicroSeconds ();
       
   306       m_pcapFile.Write (uint32_t (tMicroSeconds / 1000000), 
       
   307                         uint32_t (tMicroSeconds % 1000000), 
       
   308                         p->PeekData(), 
       
   309                         p->GetSize ());
       
   310     }
       
   311   else
       
   312     {
       
   313       //
       
   314       // Read the TCP under test expected response from the expected vector
       
   315       // file and see if it still does the right thing.
       
   316       //
       
   317       uint8_t expected[PCAP_SNAPLEN];
       
   318       uint32_t tsSec, tsUsec, inclLen, origLen, readLen;
       
   319       m_pcapFile.Read (expected, sizeof(expected), tsSec, tsUsec, inclLen, origLen, readLen);
       
   320 
       
   321       uint8_t const *actual = p->PeekData();
       
   322 
       
   323       uint32_t result = memcmp(actual, expected, readLen);
       
   324 
       
   325       //
       
   326       // Avoid streams of errors -- only report the first.
       
   327       //
       
   328       if (GetErrorStatus () == false)
       
   329         {
       
   330           NS_TEST_EXPECT_MSG_EQ (result, 0, "Expected data comparison error");
       
   331         }
       
   332     }
   184 }
   333 }
   185 
   334 
   186 bool
   335 bool
   187 Ns3TcpLossTestCase2::DoRun (void)
   336 Ns3TcpLossTestCase2::DoRun (void)
   188 {
   337 {
   223   ApplicationContainer apps = sink.Install (n1);
   372   ApplicationContainer apps = sink.Install (n1);
   224   // Start the sink application at time zero, and stop it at sinkStopTime
   373   // Start the sink application at time zero, and stop it at sinkStopTime
   225   apps.Start (Seconds (0.0));
   374   apps.Start (Seconds (0.0));
   226   apps.Stop (sinkStopTimeObj);
   375   apps.Stop (sinkStopTimeObj);
   227 
   376 
   228   Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::PacketSink/Rx",
   377   Config::Connect ("/NodeList/0/$ns3::Ipv4L3Protocol/Tx",
   229                    MakeCallback (&Ns3TcpLossTestCase2::SinkRx, this));
   378                    MakeCallback (&Ns3TcpLossTestCase2::Ipv4L3Tx, this));
   230 
   379 
   231   Simulator::Schedule(Seconds (2), &SocketWriter::Connect, socketWriter);
   380   Simulator::Schedule(Seconds (2), &SocketWriter::Connect, socketWriter);
   232   Simulator::Schedule(Seconds (10), &SocketWriter::Write, socketWriter, 500);
   381   Simulator::Schedule(Seconds (10), &SocketWriter::Write, socketWriter, 500);
   233   m_inputs.Add (500);
       
   234   Simulator::Schedule(writerStopTimeObj, &SocketWriter::Close, socketWriter);
   382   Simulator::Schedule(writerStopTimeObj, &SocketWriter::Close, socketWriter);
   235 
   383 
   236   std::list<uint32_t> sampleList;
   384   std::list<uint32_t> sampleList;
   237   // Lose first data segment
   385   // Lose first data segment
   238   sampleList.push_back (2);
   386   sampleList.push_back (2);
   249 
   397 
   250   Simulator::Stop (simStopTimeObj);
   398   Simulator::Stop (simStopTimeObj);
   251   Simulator::Run ();
   399   Simulator::Run ();
   252   Simulator::Destroy ();
   400   Simulator::Destroy ();
   253 
   401 
   254   // Compare inputs and outputs
       
   255   NS_TEST_ASSERT_MSG_EQ (m_inputs.GetN (), m_responses.GetN (), "Incorrect number of expected receive events");
       
   256   for (uint32_t i = 0; i < m_responses.GetN (); i++)
       
   257     {
       
   258       uint32_t in = m_inputs.Get (i);
       
   259       uint32_t out = m_responses.Get (i);
       
   260       NS_TEST_ASSERT_MSG_EQ (in, out, "Mismatch:  expected " << in << " bytes, got " << out << " bytes");
       
   261     }
       
   262 
       
   263   return GetErrorStatus ();
   402   return GetErrorStatus ();
   264 }
   403 }
   265 
   404 
   266 class Ns3TcpLossTestSuite : public TestSuite
   405 class Ns3TcpLossTestSuite : public TestSuite
   267 {
   406 {