A Discrete-Event Network Simulator
API
tcp-bic-test.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2015 Natale Patriciello, <natale.patriciello@gmail.com>
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 
20 #include "ns3/test.h"
21 #include "ns3/log.h"
22 #include "ns3/tcp-congestion-ops.h"
23 #include "ns3/tcp-socket-base.h"
24 #include "ns3/tcp-bic.h"
25 
26 namespace ns3 {
27 
28 NS_LOG_COMPONENT_DEFINE ("TcpBicTestSuite");
29 
34 {
35 public:
36  TcpBicIncrementTest (uint32_t cWnd,
37  uint32_t segmentSize,
38  uint32_t ssThresh,
39  uint32_t segmentsAcked,
40  uint32_t lastMaxCwnd,
41  const std::string &name);
42 
43 private:
44  virtual void DoRun (void);
45  uint32_t Update (Ptr<TcpSocketState> tcb);
46  void ExecuteTest (void);
47 
48  uint32_t m_cWnd;
49  uint32_t m_segmentSize;
50  uint32_t m_ssThresh;
51  uint32_t m_segmentsAcked;
52  uint32_t m_lastMaxCwnd;
54 };
55 
57  uint32_t segmentSize,
58  uint32_t ssThresh,
59  uint32_t segmentsAcked,
60  uint32_t lastMaxCwnd,
61  const std::string &name)
62  : TestCase (name),
63  m_cWnd (cWnd),
64  m_segmentSize (segmentSize),
65  m_ssThresh (ssThresh),
66  m_segmentsAcked (segmentsAcked),
67  m_lastMaxCwnd (lastMaxCwnd)
68 {
69 }
70 
71 void
73 {
74  m_state = CreateObject<TcpSocketState> ();
75 
76  m_state->m_cWnd = m_cWnd;
77  m_state->m_segmentSize = m_segmentSize;
78  m_state->m_ssThresh = m_ssThresh;
79 
81  Simulator::Run ();
83 }
84 
85 void
87 {
88  uint32_t segCwnd = m_cWnd / m_segmentSize;
89 
90  uint32_t ackCnt = Update (m_state);
91 
92  if (m_segmentsAcked > ackCnt)
93  {
94  NS_TEST_ASSERT_MSG_EQ (m_state->m_cWnd.Get (), segCwnd * m_segmentSize + m_segmentSize,
95  "Bic has not increment cWnd");
96  /* NS_TEST_ASSERT_MSG_EQ (m_state->m_cWnd.Get (), 27000,
97  "Bic has not increment cWnd");*/
98  }
99  else
100  {
101  NS_TEST_ASSERT_MSG_EQ (m_state->m_cWnd.Get (), segCwnd * m_segmentSize,
102  "Bic has modified cWnd");
103  }
104 }
105 
106 uint32_t
108 {
109  uint32_t segCwnd = tcb->m_cWnd / tcb->m_segmentSize;
110  Ptr<TcpBic> cong = CreateObject <TcpBic> ();
111  cong->m_lastMaxCwnd = m_lastMaxCwnd;
112  UintegerValue lowWindow, bsCoeff, wMax;
113  IntegerValue smoothPart;
114  cong->GetAttribute ("LowWnd", lowWindow);
115  cong->GetAttribute ("BinarySearchCoefficient", bsCoeff);
116  cong->GetAttribute ("MaxIncr", wMax);
117  cong->GetAttribute ("SmoothPart", smoothPart);
118 
119  cong->IncreaseWindow (m_state, m_segmentsAcked);
120 
121  uint32_t ackCnt = 0;
122 
123  if (segCwnd < lowWindow.Get ())
124  {
125  ackCnt = segCwnd;
126  return ackCnt;
127  }
128  if (segCwnd < m_lastMaxCwnd)
129  {
130  double midPt = (m_lastMaxCwnd - segCwnd) / bsCoeff.Get ();
131  if (midPt > wMax.Get ())
132  {
133  //Linear increase
134  ackCnt = segCwnd / wMax.Get ();
135  }
136  else if (midPt <= 1)
137  {
138  ackCnt = (segCwnd * smoothPart.Get ()) / bsCoeff.Get ();
139  }
140  else
141  {
142  //Binary search increase
143  ackCnt = segCwnd / midPt;
144  }
145  }
146  else
147  {
148  if (segCwnd < m_lastMaxCwnd + bsCoeff.Get ())
149  {
150  /* slow start AMD linear increase */
151  ackCnt = (segCwnd * smoothPart.Get ()) / bsCoeff.Get ();
152  }
153  else if (segCwnd < m_lastMaxCwnd + wMax.Get () * (bsCoeff.Get () - 1))
154  {
155  /* slow start */
156  ackCnt = (segCwnd * (bsCoeff.Get () - 1)) / (segCwnd - m_lastMaxCwnd);
157  }
158  else
159  {
160  /* linear increase */
161  ackCnt = segCwnd / wMax.Get ();
162 
163  }
164  }
165  return ackCnt;
166 
167 }
168 
173 {
174 public:
175  TcpBicDecrementTest (uint32_t cWnd,
176  uint32_t segmentSize,
177  BooleanValue fastConvergence,
178  uint32_t lastMaxCwnd,
179  const std::string &name);
180 
181 private:
182  virtual void DoRun (void);
183  void ExecuteTest (void);
184 
185  uint32_t m_cWnd;
186  uint32_t m_segmentSize;
188  uint32_t m_lastMaxCwnd;
190 };
191 
193  uint32_t segmentSize,
194  BooleanValue fastConvergence,
195  uint32_t lastMaxCwnd,
196  const std::string &name)
197  : TestCase (name),
198  m_cWnd (cWnd),
199  m_segmentSize (segmentSize),
200  m_fastConvergence (fastConvergence),
201  m_lastMaxCwnd (lastMaxCwnd)
202 {
203 }
204 
205 void
207 {
208  m_state = CreateObject<TcpSocketState> ();
209 
210  m_state->m_cWnd = m_cWnd;
211  m_state->m_segmentSize = m_segmentSize;
212 
214  Simulator::Run ();
216 }
217 
218 void
220 {
221  Ptr<TcpBic> cong = CreateObject <TcpBic> ();
222  cong->m_lastMaxCwnd = m_lastMaxCwnd;
223  cong->SetAttribute ("FastConvergence", m_fastConvergence);
224 
225  uint32_t segCwnd = m_cWnd / m_segmentSize;
226  uint32_t retSsThresh = cong->GetSsThresh (m_state, m_state->m_cWnd);
227  uint32_t retLastMaxCwnd = cong->m_lastMaxCwnd;
228 
229  DoubleValue beta;
230  UintegerValue lowWindow;
231  cong->GetAttribute ("Beta", beta);
232  cong->GetAttribute ("LowWnd", lowWindow);
233 
234  uint32_t lastMaxCwnd, ssThresh;
235 
236  if (segCwnd < m_lastMaxCwnd && m_fastConvergence.Get ())
237  {
238  lastMaxCwnd = beta.Get () * segCwnd;
239  NS_TEST_ASSERT_MSG_EQ (retLastMaxCwnd, lastMaxCwnd,
240  "Bic has not updated lastMaxCwnd during fast convergence");
241  }
242  else
243  {
244  lastMaxCwnd = segCwnd;
245  NS_TEST_ASSERT_MSG_EQ (retLastMaxCwnd, lastMaxCwnd,
246  "Bic has not reset lastMaxCwnd to current cwnd (in segments)");
247  }
248 
249 
250  if (segCwnd < lowWindow.Get ())
251  {
252  ssThresh = std::max (2 * m_segmentSize, m_cWnd / 2);
253  NS_TEST_ASSERT_MSG_EQ (retSsThresh, ssThresh,
254  "Bic has not updated ssThresh when cWnd less than lowWindow");
255  }
256  else
257  {
258  ssThresh = std::max (segCwnd * beta.Get (), 2.0) * m_segmentSize;
259  NS_TEST_ASSERT_MSG_EQ (retSsThresh, ssThresh,
260  "Bic has not updated ssThresh when cWnd greater than lowWindow");
261  }
262 }
263 
264 
265 // -------------------------------------------------------------------
266 
267 static class TcpBicTestSuite : public TestSuite
268 {
269 public:
270  TcpBicTestSuite () : TestSuite ("tcp-bic-test", UNIT)
271  {
272  AddTestCase (new TcpBicIncrementTest (10 * 536, 536, 9 * 536, 11, 0,
273  "Bic increment test: under lowCwnd & enough ACKs received"),
275  AddTestCase (new TcpBicIncrementTest (10 * 536, 536, 9 * 536, 8, 0,
276  "Bic increment test: under lowCwnd but not enough ACKs received"),
278  AddTestCase (new TcpBicIncrementTest (18 * 1446, 1446, 15 * 1446, 5, 90,
279  "Bic increment test: linear increase when distance exceeds S_max"),
281  AddTestCase (new TcpBicIncrementTest (18 * 1446, 1446, 15 * 1446, 24, 20,
282  "Bic increment test: binary search increase with smooth part"),
284  AddTestCase (new TcpBicIncrementTest (19 * 1, 1, 17 * 1, 2, 83,
285  "Bic increment test: binary search increase"),
287  AddTestCase (new TcpBicIncrementTest (15 * 536, 536, 9 * 536, 19, 13,
288  "Bic increment test: slow start AMD linear increase"),
290  AddTestCase (new TcpBicIncrementTest (22 * 1000, 1000, 9 * 1000, 9, 16,
291  "Bic increment test: slow start but not enough ACKs received"),
293  AddTestCase (new TcpBicIncrementTest (65 * 1000, 1000, 9 * 1000, 2, 16,
294  "Bic increment test: linear incrase but not enough ACKs received"),
296 
297  AddTestCase (new TcpBicDecrementTest (5 * 1446, 1446, true, 10,
298  "Bic decrement test: fast convergence & cwnd less than lowWindow"),
300  AddTestCase (new TcpBicDecrementTest (5 * 1446, 1446, false, 10,
301  "Bic decrement test: not in fast convergence & cwnd less than lowWindow"),
303  AddTestCase (new TcpBicDecrementTest (15 * 1446, 1446, false, 10,
304  "Bic decrement test: not in fast convergence & cwnd greater than lowWindow"),
306  }
307 } g_tcpBicTest;
308 
309 } // namespace ns3
bool Get(void) const
Definition: boolean.cc:51
Testing the congestion avoidance increment on TcpBic.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
AttributeValue implementation for Boolean.
Definition: boolean.h:34
Fast test.
Definition: test.h:1152
A suite of tests to run.
Definition: test.h:1333
static void Run(void)
Run the simulation.
Definition: simulator.cc:201
Hold a signed integer type.
Definition: integer.h:44
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
encapsulates test code
Definition: test.h:1147
This test suite implements a Unit Test.
Definition: test.h:1343
virtual void DoRun(void)
Implementation to actually run this TestCase.
Definition: tcp-bic-test.cc:72
Testing the congestion avoidance increment on TcpBic.
Definition: tcp-bic-test.cc:33
uint64_t Get(void) const
Definition: uinteger.cc:35
int64_t Get(void) const
Definition: integer.cc:35
virtual void DoRun(void)
Implementation to actually run this TestCase.
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1238
#define max(a, b)
Definition: 80211b.c:45
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:298
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:161
ns3::TcpBicTestSuite g_tcpBicTest
double Get(void) const
Definition: double.cc:35
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:165
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< TcpSocketState > m_state
Definition: tcp-bic-test.cc:53
uint32_t Update(Ptr< TcpSocketState > tcb)
Ptr< TcpSocketState > m_state
TcpBicIncrementTest(uint32_t cWnd, uint32_t segmentSize, uint32_t ssThresh, uint32_t segmentsAcked, uint32_t lastMaxCwnd, const std::string &name)
Definition: tcp-bic-test.cc:56
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
This class can be used to hold variables of floating point type such as 'double' or 'float'...
Definition: double.h:41
TcpBicDecrementTest(uint32_t cWnd, uint32_t segmentSize, BooleanValue fastConvergence, uint32_t lastMaxCwnd, const std::string &name)
BooleanValue m_fastConvergence