A Discrete-Event Network Simulator
API
tcp-loss-test.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2020 Tom Henderson
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */
18 
19 #include <list>
20 #include "ns3/log.h"
21 #include "ns3/error-model.h"
22 #include "tcp-general-test.h"
23 
24 using namespace ns3;
25 
26 NS_LOG_COMPONENT_DEFINE ("TcpLossTestSuite");
27 
55 {
56 public:
65  TcpLargeTransferLossTest (uint32_t firstLoss, uint32_t secondLoss, uint32_t lastSegment, const std::string& desc);
66 
67 protected:
68  void ConfigureProperties (void);
69  void ConfigureEnvironment (void);
70  void FinalChecks (void);
71  void Tx (const Ptr<const Packet> p, const TcpHeader&h, SocketWho who);
72  void Rx (const Ptr<const Packet> p, const TcpHeader&h, SocketWho who);
73  void CongStateTrace (const TcpSocketState::TcpCongState_t oldValue,
74  const TcpSocketState::TcpCongState_t newValue);
75  Ptr<ErrorModel> CreateReceiverErrorModel ();
76 private:
77  uint32_t m_firstLoss;
78  uint32_t m_secondLoss;
79  uint32_t m_sent {0};
80  uint32_t m_received {0};
81  uint32_t m_lastSegment {0};
82  std::list<int> m_expectedStates;
83 };
84 
85 TcpLargeTransferLossTest::TcpLargeTransferLossTest (uint32_t firstLoss, uint32_t secondLoss, uint32_t lastSegment, const std::string &desc)
86  : TcpGeneralTest (desc),
87  m_firstLoss (firstLoss),
88  m_secondLoss (secondLoss),
89  m_lastSegment (lastSegment)
90 {
91  NS_TEST_ASSERT_MSG_NE (m_lastSegment, 0, "Last segment should be > 0");
92  NS_TEST_ASSERT_MSG_GT (m_secondLoss, m_firstLoss, "Second segment number should be greater than first");
93  m_expectedStates.push_back (TcpSocketState::CA_OPEN);
94  m_expectedStates.push_back (TcpSocketState::CA_DISORDER);
95  m_expectedStates.push_back (TcpSocketState::CA_RECOVERY);
96  m_expectedStates.push_back (TcpSocketState::CA_OPEN);
97  m_expectedStates.push_back (TcpSocketState::CA_DISORDER);
98  m_expectedStates.push_back (TcpSocketState::CA_RECOVERY);
99  m_expectedStates.push_back (TcpSocketState::CA_OPEN);
100 }
101 
102 void
104  const TcpSocketState::TcpCongState_t newValue)
105 {
106  int expectedOldState = m_expectedStates.front ();
107  m_expectedStates.pop_front ();
108  NS_TEST_ASSERT_MSG_EQ (oldValue, expectedOldState, "State transition wrong");
109  NS_TEST_ASSERT_MSG_EQ (newValue, m_expectedStates.front (), "State transition wrong");
110 }
111 
112 void
114 {
115  NS_LOG_FUNCTION (this);
116  TcpGeneralTest::ConfigureEnvironment ();
117  SetPropagationDelay (MicroSeconds (1)); // Keep low to avoid window limit
119  SetAppPktSize (1000);
120  // Note: 4294967295 is the maximum TCP sequence number, so rollover will be
121  // on the 4294967th packet with a packet (segment) size of 1000 bytes
123  SetAppPktInterval (MicroSeconds (8)); // 1 Gb/s
124 }
125 
126 void
128 {
129  NS_LOG_FUNCTION (this);
130  TcpGeneralTest::ConfigureProperties ();
131  SetSegmentSize (SENDER, 1000);
132  SetSegmentSize (RECEIVER, 1000);
133 }
134 
137 {
138  Ptr<ReceiveListErrorModel> rem = CreateObject<ReceiveListErrorModel> ();
139  std::list<uint32_t> errorList;
140  errorList.push_back (m_firstLoss);
141  errorList.push_back (m_secondLoss);
142  rem->SetList (errorList);
143  return rem;
144 }
145 
146 void
148 {
149  m_sent++;
150 }
151 
152 void
154 {
155  m_received++;
156 }
157 
158 void
160 {
161  // The addition of 2 accounts for the two forcibly lost packets
162  NS_TEST_ASSERT_MSG_EQ (m_sent, (m_received + 2), "Did not observe expected number of sent packets");
163 }
164 
172 {
173 public:
174  TcpLossTestSuite () : TestSuite ("tcp-loss-test", UNIT)
175  {
176  // For large transfer tests, the three sequence numbers passed in
177  // are the segment (i.e. not byte) number that should be dropped first,
178  // then the second drop, and then the last segment number to send
179  //
180  // If we force a loss at packet 1000 and then shortly after at 2000,
181  // the TCP logic should correctly pass this case (no sequence wrapping).
182  AddTestCase (new TcpLargeTransferLossTest (1000, 2000, 2500, "large-transfer-loss-without-wrap"), TestCase::EXTENSIVE);
183  // If we force a loss at packet 1000 and then much later at 3294967, the
184  // second sequence number will evaluate to less than 1000 considering
185  // the sequence space wrap, so check this case also.
186  AddTestCase (new TcpLargeTransferLossTest (1000, 3294967, 3295100, "large-transfer-loss-with-wrap"), TestCase::EXTENSIVE);
187  }
188 };
189 
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetSegmentSize(SocketWho who, uint32_t segmentSize)
Forcefully set the segment size.
std::list< int > m_expectedStates
Expected TCP states.
void FinalChecks(void)
Performs the (eventual) final checks through test asserts.
A suite of tests to run.
Definition: test.h:1343
uint32_t m_secondLoss
Second segment loss.
uint32_t m_sent
Number of segments sent.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
void SetAppPktSize(uint32_t pktSize)
Set app packet size.
void SetTransmitStart(Time startTime)
Set the initial time at which the application sends the first data packet.
void ConfigureEnvironment(void)
Change the configuration of the environment.
void Rx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Packet received from IP layer.
static TcpLossTestSuite g_tcpLossTest
static var for test initialization
Test various packet losses.
void ConfigureProperties(void)
Change the configuration of the socket properties.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
uint32_t m_received
Number of segments received.
Check rollover of sequence number and how that affects loss recovery.
#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
TcpCongState_t
Definition of the Congestion state machine.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Header for the Transmission Control Protocol.
Definition: tcp-header.h:44
void SetList(const std::list< uint32_t > &packetlist)
Definition: error-model.cc:520
void SetAppPktCount(uint32_t pktCount)
Set app packet count.
void SetAppPktInterval(Time pktInterval)
Interval between app-generated packet.
void CongStateTrace(const TcpSocketState::TcpCongState_t oldValue, const TcpSocketState::TcpCongState_t newValue)
State on Ack state machine changes.
uint32_t m_firstLoss
First segment loss.
SocketWho
Used as parameter of methods, specifies on what node the caller is interested (e.g.
General infrastructure for TCP testing.
#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...
Definition: test.h:622
Ptr< ErrorModel > CreateReceiverErrorModel()
Create and return the error model to install in the receiver node.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
This test suite implements a Unit Test.
Definition: test.h:1353
#define NS_TEST_ASSERT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report and abort if not.
Definition: test.h:995
TcpLargeTransferLossTest(uint32_t firstLoss, uint32_t secondLoss, uint32_t lastSegment, const std::string &desc)
Constructor.
void Tx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Packet transmitted down to IP layer.
void SetPropagationDelay(Time propDelay)
Propagation delay of the bottleneck link.
uint32_t m_lastSegment
Last received segment.