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