View | Details | Raw Unified | Return to bug 647
Collapse All | Expand All

(-)a/src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc (-9 / +206 lines)
 Lines 27-32    Link Here 
27
#include "ns3/inet-socket-address.h"
27
#include "ns3/inet-socket-address.h"
28
#include "ns3/point-to-point-helper.h"
28
#include "ns3/point-to-point-helper.h"
29
#include "ns3/internet-stack-helper.h"
29
#include "ns3/internet-stack-helper.h"
30
#include "ns3/ipv4-global-routing-helper.h"
30
#include "ns3/ipv4-address-helper.h"
31
#include "ns3/ipv4-address-helper.h"
31
#include "ns3/packet-sink-helper.h"
32
#include "ns3/packet-sink-helper.h"
32
#include "ns3/tcp-socket-factory.h"
33
#include "ns3/tcp-socket-factory.h"
 Lines 172-182   SimpleSource::ScheduleTx (void) Link Here 
172
    }
173
    }
173
}
174
}
174
175
175
class Ns3TcpCwndTestCase : public TestCase
176
class Ns3TcpCwndTestCase1 : public TestCase
176
{
177
{
177
public:
178
public:
178
  Ns3TcpCwndTestCase ();
179
  Ns3TcpCwndTestCase1 ();
179
  virtual ~Ns3TcpCwndTestCase ();
180
  virtual ~Ns3TcpCwndTestCase1 ();
180
181
181
private:
182
private:
182
  virtual bool DoRun (void);
183
  virtual bool DoRun (void);
 Lines 193-210   private: Link Here 
193
  void CwndChange (uint32_t oldCwnd, uint32_t newCwnd);
194
  void CwndChange (uint32_t oldCwnd, uint32_t newCwnd);
194
};
195
};
195
196
196
Ns3TcpCwndTestCase::Ns3TcpCwndTestCase ()
197
Ns3TcpCwndTestCase1::Ns3TcpCwndTestCase1 ()
197
  : TestCase ("Check to see that the ns-3 TCP congestion window works as expected against liblinux2.6.26.so"),
198
  : TestCase ("Check to see that the ns-3 TCP congestion window works as expected against liblinux2.6.26.so"),
198
    m_writeResults (false)
199
    m_writeResults (false)
199
{
200
{
200
}
201
}
201
202
202
Ns3TcpCwndTestCase::~Ns3TcpCwndTestCase ()
203
Ns3TcpCwndTestCase1::~Ns3TcpCwndTestCase1 ()
203
{
204
{
204
}
205
}
205
206
206
void
207
void
207
Ns3TcpCwndTestCase::CwndChange (uint32_t oldCwnd, uint32_t newCwnd)
208
Ns3TcpCwndTestCase1::CwndChange (uint32_t oldCwnd, uint32_t newCwnd)
208
{
209
{
209
  CwndEvent event;
210
  CwndEvent event;
210
211
 Lines 215-221   Ns3TcpCwndTestCase::CwndChange (uint32_t Link Here 
215
}
216
}
216
217
217
bool
218
bool
218
Ns3TcpCwndTestCase::DoRun (void)
219
Ns3TcpCwndTestCase1::DoRun (void)
219
{
220
{
220
  //
221
  //
221
  // Just create two nodes.  One (node zero) will be the node with the TCP
222
  // Just create two nodes.  One (node zero) will be the node with the TCP
 Lines 297-303   Ns3TcpCwndTestCase::DoRun (void) Link Here 
297
  // in the node with the ns-3 TCP.
298
  // in the node with the ns-3 TCP.
298
  //
299
  //
299
  Ptr<Socket> ns3TcpSocket = Socket::CreateSocket (nodes.Get (0), TcpSocketFactory::GetTypeId ());
300
  Ptr<Socket> ns3TcpSocket = Socket::CreateSocket (nodes.Get (0), TcpSocketFactory::GetTypeId ());
300
  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeCallback (&Ns3TcpCwndTestCase::CwndChange, this));
301
  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeCallback (&Ns3TcpCwndTestCase1::CwndChange, this));
301
302
302
  Ptr<SimpleSource> app = CreateObject<SimpleSource> ();
303
  Ptr<SimpleSource> app = CreateObject<SimpleSource> ();
303
  app->Setup (ns3TcpSocket, sinkAddress, 1040, 10, DataRate ("5Mbps"));
304
  app->Setup (ns3TcpSocket, sinkAddress, 1040, 10, DataRate ("5Mbps"));
 Lines 366-371   Ns3TcpCwndTestCase::DoRun (void) Link Here 
366
  return GetErrorStatus ();
367
  return GetErrorStatus ();
367
}
368
}
368
369
370
371
// ===========================================================================
372
// Test case for cwnd changes due to out-of-order packets. A bottleneck 
373
// link is created, and a limited droptail queue is used in order to 
374
// force dropped packets, resulting in out-of-order packet delivery. 
375
// This out-of-order delivery will result in a different congestion 
376
// window behavior than testcase 1.  Specifically, duplicate ACKs
377
// are encountered.
378
//
379
// Network topology
380
//
381
//        1Mb/s, 10ms      100kb/s, 10ms     1Mb/s, 10ms
382
//    n0--------------n1-----------------n2---------------n3
383
//
384
// ===========================================================================
385
class Ns3TcpCwndTestCase2 : public TestCase
386
{
387
public:
388
  Ns3TcpCwndTestCase2 ();
389
  virtual ~Ns3TcpCwndTestCase2 ();
390
391
private:
392
  virtual bool DoRun (void);
393
  bool m_writeResults;
394
395
  class  CwndEvent {
396
  public:
397
    uint32_t m_oldCwnd;
398
    uint32_t m_newCwnd;
399
  };
400
401
  TestVectors<CwndEvent> m_responses;
402
403
  void CwndChange (uint32_t oldCwnd, uint32_t newCwnd);
404
};
405
406
Ns3TcpCwndTestCase2::Ns3TcpCwndTestCase2 ()
407
  : TestCase ("Check to see that the ns-3 TCP congestion window works as expected for out-of-order packet delivery"),
408
    m_writeResults (false)
409
{
410
}
411
412
Ns3TcpCwndTestCase2::~Ns3TcpCwndTestCase2 ()
413
{
414
}
415
416
void
417
Ns3TcpCwndTestCase2::CwndChange (uint32_t oldCwnd, uint32_t newCwnd)
418
{
419
  CwndEvent event;
420
421
  event.m_oldCwnd = oldCwnd;
422
  event.m_newCwnd = newCwnd;
423
424
  m_responses.Add (event);
425
}
426
427
bool
428
Ns3TcpCwndTestCase2::DoRun (void)
429
{
430
  // Set up some default values for the simulation.
431
  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", UintegerValue (4));
432
433
  NodeContainer n0n1;
434
  n0n1.Create (2);
435
436
  NodeContainer n1n2;
437
  n1n2.Add (n0n1.Get (1));
438
  n1n2.Create (1);
439
440
  NodeContainer n2n3;
441
  n2n3.Add (n1n2.Get (1));
442
  n2n3.Create (1);
443
444
  PointToPointHelper p2p1;
445
  p2p1.SetDeviceAttribute ("DataRate", DataRateValue (DataRate(1000000)));
446
  p2p1.SetChannelAttribute ("Delay", TimeValue (MilliSeconds(10)));
447
  PointToPointHelper p2p2;
448
  p2p2.SetDeviceAttribute ("DataRate", DataRateValue (DataRate(100000)));
449
  p2p2.SetChannelAttribute ("Delay", TimeValue (MilliSeconds(10)));
450
451
  // And then install devices and channels connecting our topology.
452
  NetDeviceContainer dev0 = p2p1.Install (n0n1);
453
  NetDeviceContainer dev1 = p2p2.Install (n1n2);
454
  NetDeviceContainer dev2 = p2p1.Install (n2n3);
455
456
  // Now add ip/tcp stack to all nodes.
457
  InternetStackHelper internet;
458
  internet.InstallAll ();
459
460
  // Later, we add IP addresses.
461
  Ipv4AddressHelper ipv4;
462
  ipv4.SetBase ("10.1.3.0", "255.255.255.0");
463
  ipv4.Assign (dev0);
464
  ipv4.SetBase ("10.1.2.0", "255.255.255.0");
465
  ipv4.Assign (dev1);
466
  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
467
  Ipv4InterfaceContainer ipInterfs = ipv4.Assign (dev2);
468
469
  // and setup ip routing tables to get total ip-level connectivity.
470
  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
471
472
  // Set up the apps
473
  uint16_t servPort = 50000;
474
475
  // Create a packet sink to receive these packets on n3
476
  PacketSinkHelper sink ("ns3::TcpSocketFactory",
477
                         InetSocketAddress (Ipv4Address::GetAny (), servPort));
478
479
  ApplicationContainer apps = sink.Install (n2n3.Get (1));
480
  apps.Start (Seconds (0.0));
481
  apps.Stop (Seconds (5.4));
482
483
  // Create the socket for n0
484
  Address sinkAddress (InetSocketAddress(ipInterfs.GetAddress (1), servPort));
485
  Ptr<Socket> ns3TcpSocket = Socket::CreateSocket (n0n1.Get (0), TcpSocketFactory::GetTypeId ());
486
  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeCallback (&Ns3TcpCwndTestCase2::CwndChange, this));
487
488
  // Create and start the app for n0
489
  Ptr<SimpleSource> app = CreateObject<SimpleSource> ();
490
  app->Setup (ns3TcpSocket, sinkAddress, 1040, 1000, DataRate ("1Mbps"));
491
  n0n1.Get (0)->AddApplication (app);
492
  app->Start (Seconds (1.0));
493
  app->Stop (Seconds (5.4));
494
495
  if (m_writeResults)
496
    {
497
      // Write a pcap for tcp cwnd testcase with out-of-order delivery
498
      PointToPointHelper::EnablePcapAll ("tcp-cwnd-ood");
499
    }
500
501
  // Finally, set up the simulator to run.
502
  Simulator::Stop (Seconds(5.4));
503
  Simulator::Run ();
504
  Simulator::Destroy ();
505
506
  //
507
  // As new acks are received by the TCP under test, the congestion window 
508
  // should be opened up by one segment (MSS bytes) each time.  This should
509
  // trigger a congestion window change event which we hooked and saved above.
510
  // We should now be able to look through the saved response vectors and follow
511
  // the congestion window as it opens up when the ns-3 TCP under test 
512
  // transmits its bits
513
  //
514
  // From inspecting the results, we know that we should see 31 congestion
515
  // window change events. On the tenth change event, the window should go back 
516
  // to one segment due to 3 dup acks.  It should then slow start again for 
517
  // 4 events and then enter congestion avoidance.  On change event 30 
518
  // (29 zero-based indexing), it should go back to one segment, because of triple dup ack.
519
  //
520
  const uint32_t MSS = 536;
521
522
  CwndEvent event;
523
524
  NS_TEST_ASSERT_MSG_EQ (m_responses.GetN (), 31, "Unexpected number of cwnd change events");
525
526
  for (uint32_t i = 0, from = 536, to = 1072; i < 9; ++i, from += 536, to += 536)
527
    {
528
      event = m_responses.Get (i);
529
      NS_TEST_ASSERT_MSG_EQ (event.m_oldCwnd, from, "Wrong old cwnd value in cwnd change event " << i);
530
      NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, to, "Wrong new cwnd value in cwnd change event " << i);
531
    }
532
533
  // Cwnd should be back to 536
534
  event = m_responses.Get (9);
535
  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, MSS, "Wrong new cwnd value in cwnd change event " << 9);
536
537
  // Another round of slow start
538
  for (uint32_t i = 10, from = 536, to = 1072; i < 14; ++i, from += 536, to += 536)
539
    {
540
      event = m_responses.Get (i);
541
      NS_TEST_ASSERT_MSG_EQ (event.m_oldCwnd, from, "Wrong old cwnd value in cwnd change event " << i);
542
      NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, to, "Wrong new cwnd value in cwnd change event " << i);
543
    }
544
545
  // Congestion Avoidance
546
  double adder; 
547
  uint32_t from = 2680;
548
  for (uint32_t i = 14;  i < 29; ++i)
549
    {
550
      event = m_responses.Get (i);
551
      NS_TEST_ASSERT_MSG_EQ (event.m_oldCwnd, from, "Wrong old cwnd value in cwnd change event " << i);
552
      adder = ((double) MSS * MSS) / event.m_oldCwnd;
553
      adder += event.m_oldCwnd;
554
      from = adder;
555
      NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, (uint32_t)adder, "Wrong new cwnd value in cwnd change event " << i);
556
    }
557
558
  // Cwnd should be back to 536
559
  event = m_responses.Get (29);
560
  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, MSS, "Wrong new cwnd value in cwnd change event " << 29);
561
562
  return GetErrorStatus ();
563
}
564
369
class Ns3TcpCwndTestSuite : public TestSuite
565
class Ns3TcpCwndTestSuite : public TestSuite
370
{
566
{
371
public:
567
public:
 Lines 375-381   Ns3TcpCwndTestSuite::Ns3TcpCwndTestSuite Link Here 
375
Ns3TcpCwndTestSuite::Ns3TcpCwndTestSuite ()
571
Ns3TcpCwndTestSuite::Ns3TcpCwndTestSuite ()
376
  : TestSuite ("ns3-tcp-cwnd", SYSTEM)
572
  : TestSuite ("ns3-tcp-cwnd", SYSTEM)
377
{
573
{
378
  AddTestCase (new Ns3TcpCwndTestCase);
574
  AddTestCase (new Ns3TcpCwndTestCase1);
575
  AddTestCase (new Ns3TcpCwndTestCase2);
379
}
576
}
380
577
381
Ns3TcpCwndTestSuite ns3TcpCwndTestSuite;
578
Ns3TcpCwndTestSuite ns3TcpCwndTestSuite;

Return to bug 647