A Discrete-Event Network Simulator
API
ns3tcp-no-delay-test-suite.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 as
5  * published by the Free Software Foundation;
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15  */
16 
17 #include "ns3/log.h"
18 #include "ns3/abort.h"
19 #include "ns3/test.h"
20 #include "ns3/pcap-file.h"
21 #include "ns3/config.h"
22 #include "ns3/string.h"
23 #include "ns3/uinteger.h"
24 #include "ns3/boolean.h"
25 #include "ns3/data-rate.h"
26 #include "ns3/inet-socket-address.h"
27 #include "ns3/point-to-point-helper.h"
28 #include "ns3/csma-helper.h"
29 #include "ns3/internet-stack-helper.h"
30 #include "ns3/ipv4-global-routing-helper.h"
31 #include "ns3/ipv4-address-helper.h"
32 #include "ns3/packet-sink-helper.h"
33 #include "ns3/tcp-socket-factory.h"
34 #include "ns3/node-container.h"
35 #include "ns3/simulator.h"
36 #include "ns3tcp-socket-writer.h"
37 
38 using namespace ns3;
39 
40 NS_LOG_COMPONENT_DEFINE ("Ns3TcpNoDelayTest");
41 
42 // ===========================================================================
43 // Tests of Nagle's algorithm and the TCP no delay option
44 // ===========================================================================
45 //
46 //
48 {
49 public:
50  Ns3TcpNoDelayTestCase (bool noDelay);
51  virtual ~Ns3TcpNoDelayTestCase () {}
52 
53 private:
54  virtual void DoRun (void);
55  bool m_noDelay;
57 
58  void SinkRx (std::string path, Ptr<const Packet> p, const Address &address);
59 
62 };
63 
65  : TestCase ("Check that ns-3 TCP Nagle's algorithm works correctly and that we can turn it off."),
66  m_noDelay (noDelay),
67  m_writeResults (false)
68 {
69 }
70 
71 void
73 {
74  m_responses.Add (p->GetSize ());
75 }
76 
77 void
79 {
80  uint16_t sinkPort = 50000;
81  double sinkStopTime = 8; // sec; will trigger Socket::Close
82  double writerStopTime = 5; // sec; will trigger Socket::Close
83  double simStopTime = 10; // sec
84  Time sinkStopTimeObj = Seconds (sinkStopTime);
85  Time writerStopTimeObj = Seconds (writerStopTime);
86  Time simStopTimeObj= Seconds (simStopTime);
87 
88  Ptr<Node> n0 = CreateObject<Node> ();
89  Ptr<Node> n1 = CreateObject<Node> ();
90 
92  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
93  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
94 
96  devices = pointToPoint.Install (n0, n1);
97 
98  InternetStackHelper internet;
99  internet.InstallAll ();
100 
102  address.SetBase ("10.1.1.0", "255.255.255.252");
103  Ipv4InterfaceContainer ifContainer = address.Assign (devices);
104 
105  Ptr<SocketWriter> socketWriter = CreateObject<SocketWriter> ();
106  Address sinkAddress (InetSocketAddress (ifContainer.GetAddress (1), sinkPort));
107  socketWriter->Setup (n0, sinkAddress);
108  n0->AddApplication (socketWriter);
109  socketWriter->SetStartTime (Seconds (0.));
110  socketWriter->SetStopTime (writerStopTimeObj);
111 
112  PacketSinkHelper sink ("ns3::TcpSocketFactory",
113  InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
114  ApplicationContainer apps = sink.Install (n1);
115  // Start the sink application at time zero, and stop it at sinkStopTime
116  apps.Start (Seconds (0.0));
117  apps.Stop (sinkStopTimeObj);
118 
119  Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::PacketSink/Rx",
121 
122  // Enable or disable TCP no delay option
123  Config::SetDefault ("ns3::TcpSocket::TcpNoDelay", BooleanValue (m_noDelay));
124  // This test was written with initial window of 1 segment
125  Config::SetDefault ("ns3::TcpSocket::InitialCwnd", UintegerValue (1));
126 
127  // Connect the socket writer
128  Simulator::Schedule (Seconds (1), &SocketWriter::Connect, socketWriter);
129 
130  // Write 5 packets to get some bytes in flight and some acks going
131  Simulator::Schedule (Seconds (2), &SocketWriter::Write, socketWriter, 2680);
132  m_inputs.Add (536);
133  m_inputs.Add (536);
134  m_inputs.Add (536);
135  m_inputs.Add (536);
136  m_inputs.Add (536);
137 
138  // Write one byte after 10 ms to ensure that some data is outstanding
139  // and the window is big enough
140  Simulator::Schedule (Seconds (2.010), &SocketWriter::Write, socketWriter, 1);
141 
142  // If Nagle is not enabled, i.e. no delay is on, add an input for a 1-byte
143  // packet to be received
144  if (m_noDelay)
145  {
146  m_inputs.Add (1);
147  }
148 
149  // One ms later, write 535 bytes, i.e. one segment size - 1
150  Simulator::Schedule (Seconds (2.012), &SocketWriter::Write, socketWriter, 535);
151 
152  // If Nagle is not enabled, add an input for a 535 byte packet,
153  // otherwise, we should get a single "full" packet of 536 bytes
154  if (m_noDelay)
155  {
156  m_inputs.Add (535);
157  }
158  else
159  {
160  m_inputs.Add (536);
161  }
162 
163  // Close down the socket
164  Simulator::Schedule (writerStopTimeObj, &SocketWriter::Close, socketWriter);
165 
166  if (m_writeResults)
167  {
168  std::ostringstream oss;
169  if (m_noDelay)
170  {
171  oss << "tcp-no-delay-on-test-case";
172  pointToPoint.EnablePcapAll (oss.str ());
173  }
174  else
175  {
176  oss << "tcp-no-delay-off-test-case";
177  pointToPoint.EnablePcapAll (oss.str ());
178  }
179  }
180 
181  Simulator::Stop (simStopTimeObj);
182  Simulator::Run ();
183  Simulator::Destroy ();
184 
185  // Compare inputs and outputs
186  NS_TEST_ASSERT_MSG_EQ (m_inputs.GetN (), m_responses.GetN (), "Incorrect number of expected receive events");
187  for (uint32_t i = 0; i < m_responses.GetN (); i++)
188  {
189  uint32_t in = m_inputs.Get (i);
190  uint32_t out = m_responses.Get (i);
191  NS_TEST_ASSERT_MSG_EQ (in, out, "Mismatch: expected " << in << " bytes, got " << out << " bytes");
192  }
193 }
194 
196 {
197 public:
199 };
200 
202  : TestSuite ("ns3-tcp-no-delay", SYSTEM)
203 {
204  AddTestCase (new Ns3TcpNoDelayTestCase (true), TestCase::QUICK);
205  AddTestCase (new Ns3TcpNoDelayTestCase (false), TestCase::QUICK);
206 }
207 
void InstallAll(void) const
Aggregate IPv4, IPv6, UDP, and TCP stacks to all nodes in the simulation.
Ptr< PacketSink > sink
Definition: wifi-tcp.cc:56
holds a vector of ns3::Application pointers.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:159
void SetStopTime(Time stop)
Specify application stop time.
Definition: application.cc:75
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
an Inet address class
AttributeValue implementation for Boolean.
Definition: boolean.h:36
holds a vector of std::pair of Ptr<Ipv4> and interface index.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
Hold variables of type string.
Definition: string.h:41
A suite of tests to run.
Definition: test.h:1343
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
aggregate IP/TCP/UDP functionality to existing Nodes.
T Get(std::size_t i) const
Get the i&#39;th test vector.
Definition: test.h:1483
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes...
Build a set of PointToPointNetDevice objects.
encapsulates test code
Definition: test.h:1153
a polymophic address class
Definition: address.h:90
std::size_t GetN(void) const
Get the total number of test vectors.
Definition: test.h:1476
void Setup(Ptr< Node > node, Address peer)
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
Hold an unsigned integer type.
Definition: uinteger.h:44
#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.
Definition: test.h:166
pointToPoint
Definition: first.py:35
holds a vector of ns3::NetDevice pointers
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the Time given as a parameter...
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
TestVectors< uint32_t > m_inputs
Every class exported by the ns3 library is enclosed in the ns3 namespace.
address
Definition: first.py:44
virtual void DoRun(void)
Implementation to actually run this TestCase.
static Ns3TcpNoDelayTestSuite ns3TcpNoDelayTestSuite
void Stop(Time stop)
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter...
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
std::size_t Add(T vector)
Definition: test.h:1467
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
devices
Definition: first.py:39
TestVectors< uint32_t > m_responses
void SinkRx(std::string path, Ptr< const Packet > p, const Address &address)
static void SinkRx(std::string path, Ptr< const Packet > p, const Address &address)
void SetStartTime(Time start)
Specify application start time.
Definition: application.cc:69
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642