Remove regression tests from waf

This commit is contained in:
Mitch Watrous
2010-10-15 16:31:32 -07:00
parent b892b53ca7
commit 23adf1034b
11 changed files with 1748 additions and 219 deletions

View File

@@ -47,6 +47,11 @@ us a note on ns-developers mailing list. </p>
<h1>Changes from ns-3.9 to ns-3.10</h1>
<h2>Changes to build system:</h2>
<ul>
<li><b>Regression tests are no longer run using waf</b>
<p>All regression testing is now being done in test.py. As a result, reference traces are no longer needed in ns-3 to perform regression testing.
</p>
</ul>
<h2>New API:</h2>

View File

@@ -148,10 +148,10 @@ Building ns-3 with nsc support is the same as building it without; no
additional arguments are needed for waf. Building nsc may take some time
compared to ns-3; it is interleaved in the ns-3 building process.
Try running the regression tests: @code{./waf --regression}. If NSC has
been successfully built, the following test should show up in the results:
Try running the following ns-3 test suite: @code{./test.py -s ns3-tcp-interoperability}. If NSC has
been successfully built, the following should show up in the results:
@verbatim
PASS test-tcp-nsc-lfn
PASS: TestSuite ns3-tcp-interoperability
@end verbatim
This confirms that NSC is ready to use.

View File

@@ -7,7 +7,6 @@ Steps in doing an ns-3 release
- confirm that the release builds cleanly.
- cd ns-3-dev
- ensure that tests pass (./test.py)
- ensure no regressions (./waf --regression)
2. prepare the source files
- revise and check in AUTHORS, if needed
- revise and check in RELEASE_NOTES. Make sure to add the Availability
@@ -21,29 +20,22 @@ Steps in doing an ns-3 release
- this will create an ns-allinone-dev.tar.bz2 tarball
4. test dev tarball on release platforms
- ./test.py
- ./waf --regression
- other scripts you can think of
5. once you are happy with the tarball, tag ns-3-dev and ns-3-dev-ref-traces
5. once you are happy with the tarball and tag ns-3-dev
- cd into ns-3-dev
- hg tag "ns-3.x"
- hg push
- cd into ns-3-dev-ref-traces
- hg tag "ns-3.x"
- hg push
6. clone the tagged ns-3-dev and place it on the repository
- ssh code.nsnam.org; sudo bash; su code;
- cp -r /home/code/repos/ns-3-dev /home/code/repos/ns-3.x
- cd /home/code/repos/ns-3.x/.hg and edit the hgrc appropriately:
"description = ns-3.x release
name = ns-3.x"
- clone the ns-3-dev-ref-traces and place it on the repository as above
but use the name ns-3.x-ref-traces and edit the hgrc appropriately
7. check out a clean version of the new release (ns-3.x) somewhere
- hg clone http://code.nsnam.org/ns-3.x
8. Update the VERSION for this new release
- change the string 3-dev in the VERSION file to the real version
(e.g. 3.7 or 3.7-RC1) This must agree with the version name you chose in the clone
for the regression tests to work.
(e.g. 3.7 or 3.7-RC1) This must agree with the version name you chose in the clone.
- hg commit -m "update VERSION to ns-3.x"
- hg push ssh://code@code.nsnam.org//home/code/repos/ns-3.x
@@ -51,25 +43,21 @@ Steps in doing an ns-3 release
You need to use ns-3-allinone since you will use that to make the distro
- hg clone http://code.nsnam.org/ns-3-allinone ns-3-allinone-3.x-test
- cd !$
- ./download.py -n ns-3.x -r ns-3.x-ref-traces
- ./download.py -n ns-3.x
- ./build.py
- cd ns-3.x
- ./test.py
- ./test.py -g
- ./waf --regression
- ./waf --valgrind --regression (for valgrind version)
- ./waf -d optimized configure
- ./waf
- ./test.py
- ./test.py -g
- ./waf --regression
- ./waf --valgrind --regression (for valgrind version)
- There should be no regression errors at this time
- There should be no test errors at this time
10. Create final tarballs
You need to work with a clean ns-3-allinone-3.x directory
- hg clone http://code.nsnam.org/ns-3-allinone ns-3-allinone-3.x
- cd !$
- ./download.py -n ns-3.x -r ns-3.x-ref-traces
- ./download.py -n ns-3.x
- ./dist.py
- notice we did not build here
- this will create an ns-allinone-3.x.tar.bz2 tarball
@@ -110,9 +98,9 @@ Steps in doing an ns-3 release
necessary files
16. Final checks
- check manual, testing, and tutorial documentation links
- download tarball from web, build and run regression tests for as many
- download tarball from web, build and run tests for as many
targets as you can
- download release from mercurial, build and run regression tests for as
- download release from mercurial, build and run tests for as
many targets as you can
- test and verify until you're confident the release is solid.
17. announce to ns-developers, with summary of release notes

View File

@@ -174,10 +174,10 @@ directory. Change into that release directory, and you should find a
directory structure something like the following:
@verbatim
AUTHORS doc/ README RELEASE_NOTES utils/ wscript
bindings/ examples/ regression/ samples/ VERSION wutils.py
build/ LICENSE regression.py scratch/ waf* wutils.pyc
CHANGES.html ns3/ regression.pyc src/ waf.bat*
AUTHORS doc/ README src/ waf.bat*
bindings/ examples/ RELEASE_NOTES utils/ wscript
build/ LICENSE samples/ VERSION wutils.py
CHANGES.html ns3/ scratch/ waf* wutils.pyc
@end verbatim
@cindex first.cc
@@ -811,7 +811,6 @@ drwxr-xr-x bindings python files
drwxr-xr-x doc files
drwxr-xr-x examples files
drwxr-xr-x ns3 files
drwxr-xr-x regression files
drwxr-xr-x samples files
drwxr-xr-x scratch files
drwxr-xr-x src files
@@ -824,7 +823,6 @@ drwxr-xr-x utils files
-rw-r--r-- 2009-07-01 12:47 +0200 3742 README file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 16171 RELEASE_NOTES file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 6 VERSION file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 10946 regression.py file | revisions | annotate
-rwxr-xr-x 2009-07-01 12:47 +0200 88110 waf file | revisions | annotate
-rwxr-xr-x 2009-07-01 12:47 +0200 28 waf.bat file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 35395 wscript file | revisions | annotate

View File

@@ -126,20 +126,8 @@ numbered as @code{ns-3.<release>.<hotfix>}. For example, a second hotfix to a
still hypothetical release nine of @command{ns-3} would be numbered as
@code{ns-3.9.2}.
We have had a regression testing framework in place since the first release.
For each release, a set of output files that define ``good behavior'' are saved.
These known good output files are called reference traces and are associated
with a given release by name. For example, in @uref{http://code.nsnam.org/}
you will find a repository named @code{ns-3.1} which is the first stable release
of @command{ns-3}. You will also find a separate repository named
@code{ns-3.1-ref-traces} that holds the reference traces for the @code{ns-3.1}
release. It is crucial to keep these files consistent if you want to do any
regression testing of your repository. This is a good idea to do at least once
to verify everything has built correctly.
The current development snapshot (unreleased) of @command{ns-3} may be found
at @uref{http://code.nsnam.org/ns-3-dev/} and the associated reference traces
may be found at @uref{http://code.nsnam.org/ns-3-dev-ref-traces/}. The
at @uref{http://code.nsnam.org/ns-3-dev/}. The
developers attempt to keep these repository in consistent, working states but
they are in a development area with unreleased code present, so you may want
to consider staying with an official release if you do not need newly-
@@ -147,8 +135,8 @@ introduced features.
Since the release numbers are going to be changing, I will stick with
the more constant ns-3-dev here in the tutorial, but you can replace the
string ``ns-3-dev'' with your choice of release (e.g., ns-3.6 and
ns-3.6-ref-traces) in the text below. You can find the latest version of the
string ``ns-3-dev'' with your choice of release (e.g., ns-3.6) in the
text below. You can find the latest version of the
code either by inspection of the repository list or by going to the
@uref{http://www.nsnam.org/getting_started.html,,``Getting Started''}
web page and looking for the latest release identifier.
@@ -159,15 +147,14 @@ script to pull down the various pieces of @command{ns-3} you will be using.
Go ahead and type the following into your shell (remember you can substitute
the name of your chosen release number instead of @code{ns-3-dev} -- like
@code{"ns-3.6"} and @code{"ns-3.6-ref-traces"} if you want to work with a
@code{"ns-3.6"} if you want to work with a
stable release).
@verbatim
./download.py -n ns-3-dev -r ns-3-dev-ref-traces
./download.py -n ns-3-dev
@end verbatim
Note that the default for the @code{-n} option is @code{ns-3-dev} and the
default for the @code{-r} option is @code{ns-3-dev-ref-traces} and so the
Note that the default for the @code{-n} option is @code{ns-3-dev} and so the
above is actually redundant. We provide this example to illustrate how to
specify alternate repositories. In order to download @code{ns-3-dev} you
can actually use the defaults and simply type,
@@ -195,24 +182,8 @@ following,
@end verbatim
This is output by the download script as it fetches the actual @code{ns-3}
code from the repository. Next, you should see something like,
code from the repository.
@verbatim
#
# Get the regression traces
#
Synchronizing reference traces using Mercurial.
=> hg clone http://code.nsnam.org/ns-3-dev-ref-traces ns-3-dev-ref-traces
requesting all changes
adding changesets
adding manifests
adding file changes
added 86 changesets with 1178 changes to 259 files
208 files updated, 0 files merged, 0 files removed, 0 files unresolved
@end verbatim
This is the download script fetching the reference trace files for you.
The download script is smart enough to know that on some platforms various
pieces of ns-3 are not supported. On your platform you may not see some
of these pieces come down. However, on most platforms, the process should
@@ -254,22 +225,22 @@ This part of the process is the script downloading the Network Simulation
Cradle for you. Note that NSC is not supported on OSX or Cygwin and works
best with gcc-3.4 or gcc-4.2 or greater series.
After the clone command completes, you should have several new directories
After the download.py script completes, you should have several new directories
under @code{~/repos/ns-3-allinone}:
@verbatim
build.py* constants.pyc download.py* ns-3-dev-ref-traces/ pybindgen/ util.py
constants.py dist.py* ns-3-dev/ nsc/ README util.pyc
build.py* constants.pyc download.py* nsc/ README util.pyc
constants.py dist.py* ns-3-dev/ pybindgen/ util.py
@end verbatim
Go ahead and change into @code{ns-3-dev} under your @code{~/repos/ns-3-allinone}
directory. You should see something like the following there:
@verbatim
AUTHORS examples/ regression/ scratch/ waf*
bindings/ LICENSE regression.py src/ waf.bat*
CHANGES.html ns3/ RELEASE_NOTES utils/ wscript
doc/ README samples/ VERSION wutils.py
AUTHORS examples/ RELEASE_NOTES utils/ wscript
bindings/ LICENSE samples/ VERSION wutils.py
CHANGES.html ns3/ scratch/ waf*
doc/ README src/ waf.bat*
@end verbatim
You are now ready to build the @command{ns-3} distribution.
@@ -299,8 +270,8 @@ If you change into the directory @code{ns-allinone-3.6} you should see a
number of files:
@verbatim
build.py* ns-3.6/ nsc-0.5.1/ README
constants.py ns-3.6-ref-traces/ pybindgen-0.12.0.700/ util.py
build.py* ns-3.6/ pybindgen-0.12.0.700/ util.py
constants.py nsc-0.5.1/ README
@end verbatim
You are now ready to build the @command{ns-3} distribution.
@@ -355,7 +326,6 @@ downloaded.
@cindex building debug version with Waf
@cindex compiling with Waf
@cindex unit tests with Waf
@cindex regression tests with Waf
We use Waf to configure and build the @command{ns-3} project. It's not
strictly required at this point, but it will be valuable to take a slight
detour and look at how to make changes to the configuration of the project.
@@ -380,7 +350,6 @@ output that looks similar to the following,
Checking for program ranlib : ok /usr/bin/ranlib
Checking for g++ : ok
Checking for program pkg-config : ok /usr/bin/pkg-config
Checking for regression reference traces : ok ../ns-3-dev-ref-traces (guessed)
Checking for -Wno-error=deprecated-declarations support : yes
Checking for -Wl,--soname=foo support : yes
Checking for header stdlib.h : ok
@@ -530,74 +499,6 @@ You will also see output from the test runner and the output will actually look
This command is typically run by @code{users} to quickly verify that an
@command{ns-3} distribution has built correctly.
@cindex regression tests
You can also run our regression test suite to ensure that your distribution and
toolchain have produced binaries that generate output that is identical to
known-good reference output files. You downloaded these reference traces to
your machine during the @code{./download.py} process above. (Warning: The
@code{ns-3.2} and @code{ns-3.3} releases do not use the @code{ns-3-allinone}
environment and require you to be online when you run regression tests because
they dynamically synchronize the reference traces directory with an online
repository immediately prior to the run).
During regression testing Waf will run a number of tests that generate what we
call trace files. The content of these trace files are compared with the
reference traces. If they are identical, the regression tests report a PASS
status. If a regression test fails you will see a FAIL indication along with a
pointer to the offending trace file and its associated reference trace file
along with a suggestion on diff parameters and options in order to see what
has gone awry. If the error was discovered in a pcap file, it will be useful
to convert the pcap files to text using tcpdump prior to comparison.
Some regression tests may be SKIPped if the required support
is not present.
Note that the regression tests are also run in parallel and so the messages
may be interleaved.
To run the regression tests, you provide Waf with the regression flag.
@verbatim
./waf --regression
@end verbatim
You should see messages indicating that many tests are being run and are
passing.
@verbatim
Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
[647/669] regression-test (test-csma-bridge)
[648/669] regression-test (test-csma-broadcast)
[649/669] regression-test (test-csma-multicast)
[650/669] regression-test (test-csma-one-subnet)
PASS test-csma-multicast
[651/669] regression-test (test-csma-packet-socket)
PASS test-csma-bridge
...
Regression testing summary:
PASS: 22 of 22 tests passed
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (25.826s)
@end verbatim
If you want to take a look at an example of what might be checked during
a regression test, you can do the following:
@verbatim
cd build/debug/regression/traces/second.ref
tcpdump -nn -tt -r second-2-0.pcap
@end verbatim
The output should be clear to anyone who is familiar with tcpdump or net
sniffers. We'll have much more to say on pcap files later in this tutorial.
Remember to cd back into the top-level @command{ns-3} directory
after you are done:
@verbatim
cd ../../../../..
@end verbatim
@c ========================================================================
@c Running a Script
@c ========================================================================

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,409 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ns3/boolean.h"
#include "ns3/config.h"
#include "ns3/csma-helper.h"
#include "ns3/flow-monitor.h"
#include "ns3/flow-monitor-helper.h"
#include "ns3/inet-socket-address.h"
#include "ns3/internet-stack-helper.h"
#include "ns3/ipv4-address-helper.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/ipv4-static-routing-helper.h"
#include "ns3/node.h"
#include "ns3/node-container.h"
#include "ns3/on-off-helper.h"
#include "ns3/packet.h"
#include "ns3/packet-sink-helper.h"
#include "ns3/packet-sink.h"
#include "ns3/packet-socket-helper.h"
#include "ns3/packet-socket-address.h"
#include "ns3/csma-net-device.h"
#include "ns3/point-to-point-helper.h"
#include "ns3/pointer.h"
#include "ns3/random-variable.h"
#include "ns3/simple-channel.h"
#include "ns3/simulator.h"
#include "ns3/string.h"
#include "ns3/test.h"
#include "ns3/uinteger.h"
#include "ns3/ipv4-packet-info-tag.h"
using namespace ns3;
class DynamicGlobalRoutingTestCase : public TestCase
{
public:
DynamicGlobalRoutingTestCase ();
virtual ~DynamicGlobalRoutingTestCase ();
private:
void SinkRx (std::string path, Ptr<const Packet> p, const Address &address);
void HandleRead (Ptr<Socket>);
virtual bool DoRun (void);
int m_count;
uint8_t m_firstInterface[16];
uint8_t m_secondInterface[16];
};
// Add some help text to this case to describe what it is intended to test
DynamicGlobalRoutingTestCase::DynamicGlobalRoutingTestCase ()
: TestCase ("Dynamic global routing example"), m_count (0)
{
}
DynamicGlobalRoutingTestCase::~DynamicGlobalRoutingTestCase ()
{
}
void
DynamicGlobalRoutingTestCase::SinkRx (std::string path, Ptr<const Packet> p, const Address& address)
{
Ipv4PacketInfoTag tag;
bool found;
found = p->PeekPacketTag (tag);
uint8_t now = static_cast<uint8_t> (Simulator::Now ().GetSeconds ());
if (found)
{
;
}
m_firstInterface[now]++;
m_count++;
}
void
DynamicGlobalRoutingTestCase::HandleRead (Ptr<Socket> socket)
{
Ptr<Packet> packet;
Address from;
while (packet = socket->RecvFrom (from))
{
if (packet->GetSize() == 0)
{ //EOF
break;
}
Ipv4PacketInfoTag tag;
bool found;
found = packet->PeekPacketTag (tag);
uint8_t now = static_cast<uint8_t> (Simulator::Now ().GetSeconds ());
if (found)
{
if (tag.GetRecvIf () == 1)
{
m_firstInterface[now]++;
}
if (tag.GetRecvIf () == 2)
{
m_secondInterface[now]++;
}
m_count++;
}
}
}
// Test derived from examples/routing/dynamic-global-routing.cc
//
// Network topology
//
// n0
// \ p-p
// \ (shared csma/cd)
// n2 -------------------------n3
// / | |
// / p-p n4 n5 ---------- n6
// n1 p-p
// | |
// ----------------------------------------
// p-p
//
// Test that for node n6, the interface facing n5 receives packets at
// times (1-2), (4-6), (8-10), (11-12), (14-16) and the interface
// facing n1 receives packets at times (2-4), (6-8), (12-13)
//
bool
DynamicGlobalRoutingTestCase::DoRun (void)
{
// The below value configures the default behavior of global routing.
// By default, it is disabled. To respond to interface events, set to true
Config::SetDefault ("ns3::Ipv4GlobalRouting::RespondToInterfaceEvents", BooleanValue (true));
NodeContainer c;
c.Create (7);
NodeContainer n0n2 = NodeContainer (c.Get (0), c.Get (2));
NodeContainer n1n2 = NodeContainer (c.Get (1), c.Get (2));
NodeContainer n5n6 = NodeContainer (c.Get (5), c.Get (6));
NodeContainer n1n6 = NodeContainer (c.Get (1), c.Get (6));
NodeContainer n2345 = NodeContainer (c.Get (2), c.Get (3), c.Get (4), c.Get (5));
InternetStackHelper internet;
internet.Install (c);
// We create the channels first without any IP addressing information
PointToPointHelper p2p;
p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
NetDeviceContainer d0d2 = p2p.Install (n0n2);
NetDeviceContainer d1d6 = p2p.Install (n1n6);
NetDeviceContainer d1d2 = p2p.Install (n1n2);
p2p.SetDeviceAttribute ("DataRate", StringValue ("1500kbps"));
p2p.SetChannelAttribute ("Delay", StringValue ("10ms"));
NetDeviceContainer d5d6 = p2p.Install (n5n6);
// We create the channels first without any IP addressing information
CsmaHelper csma;
csma.SetChannelAttribute ("DataRate", StringValue ("5Mbps"));
csma.SetChannelAttribute ("Delay", StringValue ("2ms"));
NetDeviceContainer d2345 = csma.Install (n2345);
// Later, we add IP addresses.
Ipv4AddressHelper ipv4;
ipv4.SetBase ("10.1.1.0", "255.255.255.0");
ipv4.Assign (d0d2);
ipv4.SetBase ("10.1.2.0", "255.255.255.0");
ipv4.Assign (d1d2);
ipv4.SetBase ("10.1.3.0", "255.255.255.0");
Ipv4InterfaceContainer i5i6 = ipv4.Assign (d5d6);
ipv4.SetBase ("10.250.1.0", "255.255.255.0");
ipv4.Assign (d2345);
ipv4.SetBase ("172.16.1.0", "255.255.255.0");
Ipv4InterfaceContainer i1i6 = ipv4.Assign (d1d6);
// Create router nodes, initialize routing database and set up the routing
// tables in the nodes.
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
// Create the OnOff application to send UDP datagrams of size
// 210 bytes at a rate of 448 Kb/s
uint16_t port = 9; // Discard port (RFC 863)
OnOffHelper onoff ("ns3::UdpSocketFactory",
InetSocketAddress (i5i6.GetAddress (1), port));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
onoff.SetAttribute ("DataRate", StringValue ("2kbps"));
onoff.SetAttribute ("PacketSize", UintegerValue (50));
ApplicationContainer apps = onoff.Install (c.Get (1));
apps.Start (Seconds (1.0));
apps.Stop (Seconds (10.0));
// Create a second OnOff application to send UDP datagrams of size
// 210 bytes at a rate of 448 Kb/s
OnOffHelper onoff2 ("ns3::UdpSocketFactory",
InetSocketAddress (i1i6.GetAddress (1), port));
onoff2.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
onoff2.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
onoff2.SetAttribute ("DataRate", StringValue ("2kbps"));
onoff2.SetAttribute ("PacketSize", UintegerValue (50));
ApplicationContainer apps2 = onoff2.Install (c.Get (1));
apps2.Start (Seconds (11.0));
apps2.Stop (Seconds (16.0));
// Create an optional packet sink to receive these packets
TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
Ptr<Socket> sink2 = Socket::CreateSocket (c.Get (6), tid);
sink2->Bind (Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
sink2->Listen ();
sink2->ShutdownSend ();
sink2->SetRecvPktInfo (true);
sink2->SetRecvCallback (MakeCallback(&DynamicGlobalRoutingTestCase::HandleRead, this));
Ptr<Node> n1 = c.Get (1);
Ptr<Ipv4> ipv41 = n1->GetObject<Ipv4> ();
// The first ifIndex is 0 for loopback, then the first p2p is numbered 1,
// then the next p2p is numbered 2
uint32_t ipv4ifIndex1 = 2;
// Trace receptions
Config::Connect ("/NodeList/6/ApplicationList/*/$ns3::PacketSink/Rx",
MakeCallback (&DynamicGlobalRoutingTestCase::SinkRx, this));
Simulator::Schedule (Seconds (2),&Ipv4::SetDown,ipv41, ipv4ifIndex1);
Simulator::Schedule (Seconds (4),&Ipv4::SetUp,ipv41, ipv4ifIndex1);
Ptr<Node> n6 = c.Get (6);
Ptr<Ipv4> ipv46 = n6->GetObject<Ipv4> ();
// The first ifIndex is 0 for loopback, then the first p2p is numbered 1,
// then the next p2p is numbered 2
uint32_t ipv4ifIndex6 = 2;
Simulator::Schedule (Seconds (6),&Ipv4::SetDown,ipv46, ipv4ifIndex6);
Simulator::Schedule (Seconds (8),&Ipv4::SetUp,ipv46, ipv4ifIndex6);
Simulator::Schedule (Seconds (12),&Ipv4::SetDown,ipv41, ipv4ifIndex1);
Simulator::Schedule (Seconds (14),&Ipv4::SetUp,ipv41, ipv4ifIndex1);
Simulator::Run ();
NS_TEST_ASSERT_MSG_EQ (m_count, 68, "Dynamic global routing did not deliver all packets");
// Test that for node n6, the interface facing n5 receives packets at
// times (1-2), (4-6), (8-10), (11-12), (14-16) and the interface
// facing n1 receives packets at times (2-4), (6-8), (12-13)
NS_TEST_ASSERT_MSG_EQ (m_firstInterface[1], 4, "Dynamic global routing did not deliver all packets");
NS_TEST_ASSERT_MSG_EQ (m_secondInterface[2], 5, "Dynamic global routing did not deliver all packets");
NS_TEST_ASSERT_MSG_EQ (m_secondInterface[3], 5, "Dynamic global routing did not deliver all packets");
NS_TEST_ASSERT_MSG_EQ (m_firstInterface[4], 5, "Dynamic global routing did not deliver all packets");
NS_TEST_ASSERT_MSG_EQ (m_firstInterface[5], 5, "Dynamic global routing did not deliver all packets");
NS_TEST_ASSERT_MSG_EQ (m_secondInterface[6], 5, "Dynamic global routing did not deliver all packets");
NS_TEST_ASSERT_MSG_EQ (m_secondInterface[7], 5, "Dynamic global routing did not deliver all packets");
NS_TEST_ASSERT_MSG_EQ (m_firstInterface[8], 5, "Dynamic global routing did not deliver all packets");
NS_TEST_ASSERT_MSG_EQ (m_firstInterface[9], 5, "Dynamic global routing did not deliver all packets");
NS_TEST_ASSERT_MSG_EQ (m_firstInterface[10], 0, "Dynamic global routing did not deliver all packets");
NS_TEST_ASSERT_MSG_EQ (m_firstInterface[11], 4, "Dynamic global routing did not deliver all packets");
NS_TEST_ASSERT_MSG_EQ (m_secondInterface[12], 5, "Dynamic global routing did not deliver all packets");
NS_TEST_ASSERT_MSG_EQ (m_secondInterface[13], 5, "Dynamic global routing did not deliver all packets");
NS_TEST_ASSERT_MSG_EQ (m_firstInterface[14], 5, "Dynamic global routing did not deliver all packets");
NS_TEST_ASSERT_MSG_EQ (m_firstInterface[15], 5, "Dynamic global routing did not deliver all packets");
Simulator::Destroy ();
return GetErrorStatus ();
}
class GlobalRoutingSlash32TestCase : public TestCase
{
public:
GlobalRoutingSlash32TestCase ();
virtual ~GlobalRoutingSlash32TestCase ();
private:
virtual bool DoRun (void);
};
// Add some help text to this case to describe what it is intended to test
GlobalRoutingSlash32TestCase::GlobalRoutingSlash32TestCase ()
: TestCase ("Slash 32 global routing example")
{
}
GlobalRoutingSlash32TestCase::~GlobalRoutingSlash32TestCase ()
{
}
// Test program for this 3-router scenario, using global routing
//
// (a.a.a.a/32)A<--x.x.x.0/30-->B<--y.y.y.0/30-->C(c.c.c.c/32)
//
bool
GlobalRoutingSlash32TestCase::DoRun (void)
{
Ptr<Node> nA = CreateObject<Node> ();
Ptr<Node> nB = CreateObject<Node> ();
Ptr<Node> nC = CreateObject<Node> ();
NodeContainer c = NodeContainer (nA, nB, nC);
InternetStackHelper internet;
internet.Install (c);
// Point-to-point links
NodeContainer nAnB = NodeContainer (nA, nB);
NodeContainer nBnC = NodeContainer (nB, nC);
// We create the channels first without any IP addressing information
PointToPointHelper p2p;
p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
NetDeviceContainer dAdB = p2p.Install (nAnB);
NetDeviceContainer dBdC = p2p.Install (nBnC);;
Ptr<CsmaNetDevice> deviceA = CreateObject<CsmaNetDevice> ();
deviceA->SetAddress (Mac48Address::Allocate ());
nA->AddDevice (deviceA);
Ptr<CsmaNetDevice> deviceC = CreateObject<CsmaNetDevice> ();
deviceC->SetAddress (Mac48Address::Allocate ());
nC->AddDevice (deviceC);
// Later, we add IP addresses.
Ipv4AddressHelper ipv4;
ipv4.SetBase ("10.1.1.0", "255.255.255.252");
Ipv4InterfaceContainer iAiB = ipv4.Assign (dAdB);
ipv4.SetBase ("10.1.1.4", "255.255.255.252");
Ipv4InterfaceContainer iBiC = ipv4.Assign (dBdC);
Ptr<Ipv4> ipv4A = nA->GetObject<Ipv4> ();
Ptr<Ipv4> ipv4C = nC->GetObject<Ipv4> ();
int32_t ifIndexA = ipv4A->AddInterface (deviceA);
int32_t ifIndexC = ipv4C->AddInterface (deviceC);
Ipv4InterfaceAddress ifInAddrA = Ipv4InterfaceAddress (Ipv4Address ("172.16.1.1"), Ipv4Mask ("255.255.255.255"));
ipv4A->AddAddress (ifIndexA, ifInAddrA);
ipv4A->SetMetric (ifIndexA, 1);
ipv4A->SetUp (ifIndexA);
Ipv4InterfaceAddress ifInAddrC = Ipv4InterfaceAddress (Ipv4Address ("192.168.1.1"), Ipv4Mask ("255.255.255.255"));
ipv4C->AddAddress (ifIndexC, ifInAddrC);
ipv4C->SetMetric (ifIndexC, 1);
ipv4C->SetUp (ifIndexC);
// Create router nodes, initialize routing database and set up the routing
// tables in the nodes.
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
// Create the OnOff application to send UDP datagrams of size
// 210 bytes at a rate of 448 Kb/s
uint16_t port = 9; // Discard port (RFC 863)
OnOffHelper onoff ("ns3::UdpSocketFactory",
Address (InetSocketAddress (ifInAddrC.GetLocal(), port)));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
onoff.SetAttribute ("DataRate", DataRateValue (DataRate (6000)));
ApplicationContainer apps = onoff.Install (nA);
apps.Start (Seconds (1.0));
apps.Stop (Seconds (10.0));
// Create a packet sink to receive these packets
PacketSinkHelper sink ("ns3::UdpSocketFactory",
Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
apps = sink.Install (nC);
apps.Start (Seconds (1.0));
apps.Stop (Seconds (10.0));
Simulator::Run ();
// Check that we received 13 * 512 = 6656 bytes
Ptr<PacketSink> sinkPtr = DynamicCast <PacketSink> (apps.Get (0));
NS_TEST_ASSERT_MSG_EQ (sinkPtr->GetTotalRx (), 6656, "Static routing with /32 did not deliver all packets");
Simulator::Destroy ();
return GetErrorStatus ();
}
class GlobalRoutingTestSuite : public TestSuite
{
public:
GlobalRoutingTestSuite ();
};
GlobalRoutingTestSuite::GlobalRoutingTestSuite ()
: TestSuite ("global-routing", BVT)
{
AddTestCase (new DynamicGlobalRoutingTestCase);
AddTestCase (new GlobalRoutingSlash32TestCase);
}
// Do not forget to allocate an instance of this TestSuite
static GlobalRoutingTestSuite globalRoutingTestSuite;

View File

@@ -0,0 +1,175 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// End-to-end tests for Ipv4 static routing
#include "ns3/boolean.h"
#include "ns3/config.h"
#include "ns3/csma-helper.h"
#include "ns3/csma-net-device.h"
#include "ns3/inet-socket-address.h"
#include "ns3/internet-stack-helper.h"
#include "ns3/ipv4-address-helper.h"
#include "ns3/ipv4-static-routing-helper.h"
#include "ns3/node.h"
#include "ns3/node-container.h"
#include "ns3/on-off-helper.h"
#include "ns3/packet.h"
#include "ns3/packet-sink-helper.h"
#include "ns3/packet-sink.h"
#include "ns3/packet-socket-helper.h"
#include "ns3/packet-socket-address.h"
#include "ns3/point-to-point-helper.h"
#include "ns3/pointer.h"
#include "ns3/random-variable.h"
#include "ns3/simulator.h"
#include "ns3/string.h"
#include "ns3/test.h"
#include "ns3/uinteger.h"
using namespace ns3;
class StaticRoutingSlash32TestCase : public TestCase
{
public:
StaticRoutingSlash32TestCase ();
virtual ~StaticRoutingSlash32TestCase ();
private:
virtual bool DoRun (void);
};
// Add some help text to this case to describe what it is intended to test
StaticRoutingSlash32TestCase::StaticRoutingSlash32TestCase ()
: TestCase ("Slash 32 static routing example")
{
}
StaticRoutingSlash32TestCase::~StaticRoutingSlash32TestCase ()
{
}
// Test program for this 3-router scenario, using static routing
//
// (a.a.a.a/32)A<--x.x.x.0/30-->B<--y.y.y.0/30-->C(c.c.c.c/32)
//
bool
StaticRoutingSlash32TestCase::DoRun (void)
{
Ptr<Node> nA = CreateObject<Node> ();
Ptr<Node> nB = CreateObject<Node> ();
Ptr<Node> nC = CreateObject<Node> ();
NodeContainer c = NodeContainer (nA, nB, nC);
InternetStackHelper internet;
internet.Install (c);
// Point-to-point links
NodeContainer nAnB = NodeContainer (nA, nB);
NodeContainer nBnC = NodeContainer (nB, nC);
// We create the channels first without any IP addressing information
PointToPointHelper p2p;
p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
NetDeviceContainer dAdB = p2p.Install (nAnB);
NetDeviceContainer dBdC = p2p.Install (nBnC);;
Ptr<CsmaNetDevice> deviceA = CreateObject<CsmaNetDevice> ();
deviceA->SetAddress (Mac48Address::Allocate ());
nA->AddDevice (deviceA);
Ptr<CsmaNetDevice> deviceC = CreateObject<CsmaNetDevice> ();
deviceC->SetAddress (Mac48Address::Allocate ());
nC->AddDevice (deviceC);
// Later, we add IP addresses.
Ipv4AddressHelper ipv4;
ipv4.SetBase ("10.1.1.0", "255.255.255.252");
Ipv4InterfaceContainer iAiB = ipv4.Assign (dAdB);
ipv4.SetBase ("10.1.1.4", "255.255.255.252");
Ipv4InterfaceContainer iBiC = ipv4.Assign (dBdC);
Ptr<Ipv4> ipv4A = nA->GetObject<Ipv4> ();
Ptr<Ipv4> ipv4B = nB->GetObject<Ipv4> ();
Ptr<Ipv4> ipv4C = nC->GetObject<Ipv4> ();
int32_t ifIndexA = ipv4A->AddInterface (deviceA);
int32_t ifIndexC = ipv4C->AddInterface (deviceC);
Ipv4InterfaceAddress ifInAddrA = Ipv4InterfaceAddress (Ipv4Address ("172.16.1.1"), Ipv4Mask ("/32"));
ipv4A->AddAddress (ifIndexA, ifInAddrA);
ipv4A->SetMetric (ifIndexA, 1);
ipv4A->SetUp (ifIndexA);
Ipv4InterfaceAddress ifInAddrC = Ipv4InterfaceAddress (Ipv4Address ("192.168.1.1"), Ipv4Mask ("/32"));
ipv4C->AddAddress (ifIndexC, ifInAddrC);
ipv4C->SetMetric (ifIndexC, 1);
ipv4C->SetUp (ifIndexC);
Ipv4StaticRoutingHelper ipv4RoutingHelper;
// Create static routes from A to C
Ptr<Ipv4StaticRouting> staticRoutingA = ipv4RoutingHelper.GetStaticRouting (ipv4A);
// The ifIndex for this outbound route is 1; the first p2p link added
staticRoutingA->AddHostRouteTo (Ipv4Address ("192.168.1.1"), Ipv4Address ("10.1.1.2"), 1);
Ptr<Ipv4StaticRouting> staticRoutingB = ipv4RoutingHelper.GetStaticRouting (ipv4B);
// The ifIndex we want on node B is 2; 0 corresponds to loopback, and 1 to the first point to point link
staticRoutingB->AddHostRouteTo (Ipv4Address ("192.168.1.1"), Ipv4Address ("10.1.1.6"), 2);
// Create the OnOff application to send UDP datagrams of size
// 210 bytes at a rate of 448 Kb/s
uint16_t port = 9; // Discard port (RFC 863)
OnOffHelper onoff ("ns3::UdpSocketFactory",
Address (InetSocketAddress (ifInAddrC.GetLocal (), port)));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
onoff.SetAttribute ("DataRate", DataRateValue (DataRate (6000)));
ApplicationContainer apps = onoff.Install (nA);
apps.Start (Seconds (1.0));
apps.Stop (Seconds (10.0));
// Create a packet sink to receive these packets
PacketSinkHelper sink ("ns3::UdpSocketFactory",
Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
apps = sink.Install (nC);
apps.Start (Seconds (1.0));
apps.Stop (Seconds (10.0));
Simulator::Run ();
// Check that we received 13 * 512 = 6656 bytes
Ptr<PacketSink> sinkPtr = DynamicCast <PacketSink> (apps.Get (0));
NS_TEST_ASSERT_MSG_EQ (sinkPtr->GetTotalRx (), 6656, "Static routing with /32 did not deliver all packets");
Simulator::Destroy ();
return GetErrorStatus ();
}
class StaticRoutingTestSuite : public TestSuite
{
public:
StaticRoutingTestSuite ();
};
StaticRoutingTestSuite::StaticRoutingTestSuite ()
: TestSuite ("static-routing", BVT)
{
AddTestCase (new StaticRoutingSlash32TestCase);
}
// Do not forget to allocate an instance of this TestSuite
static StaticRoutingTestSuite staticRoutingTestSuite;

View File

@@ -6,7 +6,10 @@ def configure(conf):
def build(bld):
test = bld.create_ns3_module('test', ['core'])
test.source = [
'csma-system-test-suite.cc',
'global-routing-test-suite.cc',
'sample-test-suite.cc',
'static-routing-test-suite.cc',
'error-model-test-suite.cc',
'mobility-test-suite.cc',
]

69
wscript
View File

@@ -43,7 +43,6 @@ cflags.default_profile = 'debug'
# local modules
import wutils
import regression
Configure.autoconfig = 1
@@ -54,14 +53,6 @@ APPNAME = 'ns'
wutils.VERSION = VERSION
wutils.APPNAME = APPNAME
#
# The last part of the path name to use to find the regression traces. The
# path will be APPNAME + '-' + VERSION + REGRESSION_SUFFIX, e.g.,
# ns-3-dev-ref-traces
#
REGRESSION_SUFFIX = "-ref-traces"
# these variables are mandatory ('/' are converted automatically)
srcdir = '.'
blddir = 'build'
@@ -97,22 +88,6 @@ def dist_hook():
shutil.rmtree("doc/latex", True)
shutil.rmtree("nsc", True)
## build the name of the traces subdirectory. Will be something like
## ns-3-dev-ref-traces
traces_name = APPNAME + '-' + VERSION + REGRESSION_SUFFIX
## Create a tar.bz2 file with the traces
env = load_env()
regression_dir = env['REGRESSION_TRACES']
if not os.path.isdir(regression_dir):
Logs.warn("Not creating traces archive: the %s directory does not exist" % regression_dir)
else:
traceball = traces_name + wutils.TRACEBALL_SUFFIX
tar = tarfile.open(os.path.join("..", traceball), 'w:bz2')
files = get_files(regression_dir)
for fullfilename,relfilename in files:
tar.add(fullfilename,arcname=relfilename)
tar.close()
def set_options(opt):
# options provided by the modules
opt.tool_options('compiler_cc')
@@ -177,23 +152,9 @@ def set_options(opt):
opt.add_option('--disable-examples',
help=('Do not build the ns-3 examples and samples.'),
dest='enable_examples', action='store_false')
opt.add_option('--regression',
help=("Enable regression testing; only used for the 'check' target"),
default=False, dest='regression', action="store_true")
opt.add_option('--check',
help=('DEPRECATED (run ./test.py)'),
default=False, dest='check', action="store_true")
opt.add_option('--regression-generate',
help=("Generate new regression test traces."),
default=False, dest='regression_generate', action="store_true")
opt.add_option('--regression-tests',
help=('For regression testing, only run/generate the indicated regression tests, '
'specified as a comma separated list of test names'),
dest='regression_tests', type="string")
opt.add_option('--with-regression-traces',
help=('Path to the regression reference traces directory'),
default=None,
dest='regression_traces', type="string")
opt.add_option('--enable-static',
help=('Compile NS-3 statically: works only on linux, without python'),
dest='enable_static', action='store_true',
@@ -258,20 +219,6 @@ def configure(conf):
pass
conf.check_tool('command', ['waf-tools'])
# Check for the location of regression reference traces
if Options.options.regression_traces is not None:
if os.path.isdir(Options.options.regression_traces):
conf.check_message("regression traces location", '', True, ("%s (given)" % Options.options.regression_traces))
conf.env['REGRESSION_TRACES'] = os.path.abspath(Options.options.regression_traces)
else:
traces = os.path.join('..', "%s-%s%s" % (APPNAME, VERSION, REGRESSION_SUFFIX))
if os.path.isdir(traces):
conf.check_message("regression reference traces", '', True, ("%s (guessed)" % traces))
conf.env['REGRESSION_TRACES'] = os.path.abspath(traces)
del traces
if not conf.env['REGRESSION_TRACES']:
conf.check_message("regression reference traces", '', False)
# create the second environment, set the variant and set its name
variant_env = conf.env.copy()
variant_name = Options.options.build_profile
@@ -373,9 +320,6 @@ def configure(conf):
conf.report_optional_feature("ENABLE_EXAMPLES", "Build examples and samples", env['ENABLE_EXAMPLES'],
why_not_examples)
# we cannot pull regression traces without mercurial
conf.find_program('hg', var='MERCURIAL')
conf.find_program('valgrind', var='VALGRIND')
env['ENABLE_STATIC_NS3'] = False
@@ -645,19 +589,6 @@ def build(bld):
if type(gen).__name__ in ['ns3header_taskgen', 'ns3moduleheader_taskgen']:
gen.post()
if Options.options.regression or Options.options.regression_generate:
regression_traces = env['REGRESSION_TRACES']
if not regression_traces:
raise Utils.WafError("Cannot run regression tests: reference traces directory not given"
" (--with-regression-traces configure option)")
if env['ENABLE_EXAMPLES'] == True:
regression.run_regression(bld, regression_traces)
else:
raise Utils.WafError("Cannot run regression tests: building the ns-3 examples is not enabled"
" (regression tests are based on examples)")
if Options.options.doxygen_no_build:
_doxygen(bld)
raise SystemExit(0)

View File

@@ -19,13 +19,6 @@ APPNAME=None
VERSION=None
bld=None
#
# The last part of the path name to use to find the regression traces tarball.
# path will be APPNAME + '-' + VERSION + REGRESSION_SUFFIX + TRACEBALL_SUFFIX,
# e.g., ns-3-dev-ref-traces.tar.bz2
#
TRACEBALL_SUFFIX = ".tar.bz2"
def get_command_template(env, arguments=()):