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 
125  // Connect the socket writer
126  Simulator::Schedule (Seconds (1), &SocketWriter::Connect, socketWriter);
127 
128  // Write 5 packets to get some bytes in flight and some acks going
129  Simulator::Schedule (Seconds (2), &SocketWriter::Write, socketWriter, 2680);
130  m_inputs.Add (536);
131  m_inputs.Add (536);
132  m_inputs.Add (536);
133  m_inputs.Add (536);
134  m_inputs.Add (536);
135 
136  // Write one byte after 10 ms to ensure that some data is outstanding
137  // and the window is big enough
138  Simulator::Schedule (Seconds (2.010), &SocketWriter::Write, socketWriter, 1);
139 
140  // If Nagle is not enabled, i.e. no delay is on, add an input for a 1-byte
141  // packet to be received
142  if (m_noDelay)
143  {
144  m_inputs.Add (1);
145  }
146 
147  // One ms later, write 535 bytes, i.e. one segment size - 1
148  Simulator::Schedule (Seconds (2.012), &SocketWriter::Write, socketWriter, 535);
149 
150  // If Nagle is not enabled, add an input for a 535 byte packet,
151  // otherwise, we should get a single "full" packet of 536 bytes
152  if (m_noDelay)
153  {
154  m_inputs.Add (535);
155  }
156  else
157  {
158  m_inputs.Add (536);
159  }
160 
161  // Close down the socket
162  Simulator::Schedule (writerStopTimeObj, &SocketWriter::Close, socketWriter);
163 
164  if (m_writeResults)
165  {
166  std::ostringstream oss;
167  if (m_noDelay)
168  {
169  oss << "tcp-no-delay-on-test-case";
170  pointToPoint.EnablePcapAll (oss.str ());
171  }
172  else
173  {
174  oss << "tcp-no-delay-off-test-case";
175  pointToPoint.EnablePcapAll (oss.str ());
176  }
177  }
178 
179  Simulator::Stop (simStopTimeObj);
180  Simulator::Run ();
181  Simulator::Destroy ();
182 
183  // Compare inputs and outputs
184  NS_TEST_ASSERT_MSG_EQ (m_inputs.GetN (), m_responses.GetN (), "Incorrect number of expected receive events");
185  for (uint32_t i = 0; i < m_responses.GetN (); i++)
186  {
187  uint32_t in = m_inputs.Get (i);
188  uint32_t out = m_responses.Get (i);
189  NS_TEST_ASSERT_MSG_EQ (in, out, "Mismatch: expected " << in << " bytes, got " << out << " bytes");
190  }
191 }
192 
194 {
195 public:
197 };
198 
200  : TestSuite ("ns3-tcp-no-delay", SYSTEM)
201 {
202  AddTestCase (new Ns3TcpNoDelayTestCase (true), TestCase::QUICK);
203  AddTestCase (new Ns3TcpNoDelayTestCase (false), TestCase::QUICK);
204 }
205 
Ptr< PacketSink > sink
Definition: wifi-tcp.cc:45
holds a vector of ns3::Application pointers.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:157
tuple pointToPoint
Definition: first.py:28
void SetStopTime(Time stop)
Specify application stop time.
Definition: application.cc:75
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
an Inet address class
AttributeValue implementation for Boolean.
Definition: boolean.h:36
tuple devices
Definition: first.py:32
holds a vector of std::pair of Ptr and interface index.
T Get(uint32_t i) const
Get the i'th test vector.
Definition: test.h:1484
Hold variables of type string.
Definition: string.h:41
A suite of tests to run.
Definition: test.h:1342
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
aggregate IP/TCP/UDP functionality to existing Nodes.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:796
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:1155
uint32_t GetN(void) const
Get the total number of test vectors.
Definition: test.h:1477
a polymophic address class
Definition: address.h:90
void Setup(Ptr< Node > node, Address peer)
void InstallAll(void) const
Aggregate IPv4, IPv6, UDP, and TCP stacks to all nodes in the simulation.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
#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:168
uint32_t Add(T vector)
Definition: test.h:1468
holds a vector of ns3::NetDevice pointers
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
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:843
TestVectors< uint32_t > m_inputs
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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...
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:993
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:782
ApplicationContainer Install(NodeContainer c) const
Install an ns3::PacketSinkApplication on each node of the input container configured with all the att...
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
tuple address
Definition: first.py:37
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
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const