diff -Naur --exclude=.hg ns-3-dev/CHANGES.html ns-3-dev-test/CHANGES.html --- ns-3-dev/CHANGES.html 2010-10-08 15:42:05.718942751 -0700 +++ ns-3-dev-test/CHANGES.html 2010-10-08 15:12:13.218943297 -0700 @@ -47,6 +47,11 @@

Changes from ns-3.9 to ns-3.10

Changes to build system:

+

New API:

diff -Naur --exclude=.hg ns-3-dev/doc/manual/tcp.texi ns-3-dev-test/doc/manual/tcp.texi --- ns-3-dev/doc/manual/tcp.texi 2010-10-08 15:42:05.839943111 -0700 +++ ns-3-dev-test/doc/manual/tcp.texi 2010-10-08 15:13:07.060880555 -0700 @@ -148,10 +148,10 @@ 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. diff -Naur --exclude=.hg ns-3-dev/doc/release_steps.txt ns-3-dev-test/doc/release_steps.txt --- ns-3-dev/doc/release_steps.txt 2010-10-08 15:42:05.845943218 -0700 +++ ns-3-dev-test/doc/release_steps.txt 2010-10-08 15:12:13.344943231 -0700 @@ -7,7 +7,6 @@ - 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 @@ - 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 @@ 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 @@ 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 diff -Naur --exclude=.hg ns-3-dev/doc/tutorial/conceptual-overview.texi ns-3-dev-test/doc/tutorial/conceptual-overview.texi --- ns-3-dev/doc/tutorial/conceptual-overview.texi 2010-10-08 15:42:05.853943099 -0700 +++ ns-3-dev-test/doc/tutorial/conceptual-overview.texi 2010-10-08 15:12:13.352943315 -0700 @@ -174,10 +174,10 @@ 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 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 @@ -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 diff -Naur --exclude=.hg ns-3-dev/doc/tutorial/getting-started.texi ns-3-dev-test/doc/tutorial/getting-started.texi --- ns-3-dev/doc/tutorial/getting-started.texi 2010-10-08 15:42:05.857943142 -0700 +++ ns-3-dev-test/doc/tutorial/getting-started.texi 2010-10-08 15:12:13.356943454 -0700 @@ -126,20 +126,8 @@ 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 @@ 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 @@ 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 @@ @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, - -@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 +code from the repository. -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 @@ 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 @@ 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 @@ @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 @@ 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 @@ 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 ======================================================================== diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-csma-bridge.py ns-3-dev-test/regression/tests/test-csma-bridge.py --- ns-3-dev/regression/tests/test-csma-bridge.py 2010-10-08 15:42:05.929943052 -0700 +++ ns-3-dev-test/regression/tests/test-csma-bridge.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,14 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" - -import os.path - -def may_run(env, options): - """Returns 0 when it can run, return non-zero or string (reason) when it cannot run""" - if env['ENABLE_PYTHON_BINDINGS']: - return 0 - else: - return "Python bindings not available." - -pyscript = os.path.join('examples/csma', 'csma-bridge.py') diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-csma-broadcast.py ns-3-dev-test/regression/tests/test-csma-broadcast.py --- ns-3-dev/regression/tests/test-csma-broadcast.py 2010-10-08 15:42:05.929943052 -0700 +++ ns-3-dev-test/regression/tests/test-csma-broadcast.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,4 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" - diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-csma-multicast.py ns-3-dev-test/regression/tests/test-csma-multicast.py --- ns-3-dev/regression/tests/test-csma-multicast.py 2010-10-08 15:42:05.929943052 -0700 +++ ns-3-dev-test/regression/tests/test-csma-multicast.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,3 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-csma-one-subnet.py ns-3-dev-test/regression/tests/test-csma-one-subnet.py --- ns-3-dev/regression/tests/test-csma-one-subnet.py 2010-10-08 15:42:05.930943155 -0700 +++ ns-3-dev-test/regression/tests/test-csma-one-subnet.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,4 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" - diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-csma-packet-socket.py ns-3-dev-test/regression/tests/test-csma-packet-socket.py --- ns-3-dev/regression/tests/test-csma-packet-socket.py 2010-10-08 15:42:05.930943155 -0700 +++ ns-3-dev-test/regression/tests/test-csma-packet-socket.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,4 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" - diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-csma-ping.py ns-3-dev-test/regression/tests/test-csma-ping.py --- ns-3-dev/regression/tests/test-csma-ping.py 2010-10-08 15:42:05.930943155 -0700 +++ ns-3-dev-test/regression/tests/test-csma-ping.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,4 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" - diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-csma-raw-ip-socket.py ns-3-dev-test/regression/tests/test-csma-raw-ip-socket.py --- ns-3-dev/regression/tests/test-csma-raw-ip-socket.py 2010-10-08 15:42:05.931943119 -0700 +++ ns-3-dev-test/regression/tests/test-csma-raw-ip-socket.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,4 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" - diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-csma-star.py ns-3-dev-test/regression/tests/test-csma-star.py --- ns-3-dev/regression/tests/test-csma-star.py 2010-10-08 15:42:05.931943119 -0700 +++ ns-3-dev-test/regression/tests/test-csma-star.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,4 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" - diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-dynamic-global-routing.py ns-3-dev-test/regression/tests/test-dynamic-global-routing.py --- ns-3-dev/regression/tests/test-dynamic-global-routing.py 2010-10-08 15:42:05.931943119 -0700 +++ ns-3-dev-test/regression/tests/test-dynamic-global-routing.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,4 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" - diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-global-routing-slash32.py ns-3-dev-test/regression/tests/test-global-routing-slash32.py --- ns-3-dev/regression/tests/test-global-routing-slash32.py 2010-10-08 15:42:05.931943119 -0700 +++ ns-3-dev-test/regression/tests/test-global-routing-slash32.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,4 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" - diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-object-names.py ns-3-dev-test/regression/tests/test-object-names.py --- ns-3-dev/regression/tests/test-object-names.py 2010-10-08 15:42:05.932943166 -0700 +++ ns-3-dev-test/regression/tests/test-object-names.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,4 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" - diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-realtime-udp-echo.py ns-3-dev-test/regression/tests/test-realtime-udp-echo.py --- ns-3-dev/regression/tests/test-realtime-udp-echo.py 2010-10-08 15:42:05.932943166 -0700 +++ ns-3-dev-test/regression/tests/test-realtime-udp-echo.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,7 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" - -def may_run(env, options): - if not env["ENABLE_REAL_TIME"]: - return "Real-time support not available" diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-second.py ns-3-dev-test/regression/tests/test-second.py --- ns-3-dev/regression/tests/test-second.py 2010-10-08 15:42:05.932943166 -0700 +++ ns-3-dev-test/regression/tests/test-second.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,6 +0,0 @@ -#! /usr/bin/env python - -"""Compare that Second generates correct traces.""" - -arguments = ["--verbose=0"] - diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-simple-error-model.py ns-3-dev-test/regression/tests/test-simple-error-model.py --- ns-3-dev/regression/tests/test-simple-error-model.py 2010-10-08 15:42:05.932943166 -0700 +++ ns-3-dev-test/regression/tests/test-simple-error-model.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,4 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" - diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-simple-global-routing.py ns-3-dev-test/regression/tests/test-simple-global-routing.py --- ns-3-dev/regression/tests/test-simple-global-routing.py 2010-10-08 15:42:05.933943220 -0700 +++ ns-3-dev-test/regression/tests/test-simple-global-routing.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,4 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" - diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-simple-point-to-point-olsr.py ns-3-dev-test/regression/tests/test-simple-point-to-point-olsr.py --- ns-3-dev/regression/tests/test-simple-point-to-point-olsr.py 2010-10-08 15:42:05.933943220 -0700 +++ ns-3-dev-test/regression/tests/test-simple-point-to-point-olsr.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,4 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" - diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-static-routing-slash32.py ns-3-dev-test/regression/tests/test-static-routing-slash32.py --- ns-3-dev/regression/tests/test-static-routing-slash32.py 2010-10-08 15:42:05.933943220 -0700 +++ ns-3-dev-test/regression/tests/test-static-routing-slash32.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,4 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" - diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-tcp-large-transfer.py ns-3-dev-test/regression/tests/test-tcp-large-transfer.py --- ns-3-dev/regression/tests/test-tcp-large-transfer.py 2010-10-08 15:42:05.934943150 -0700 +++ ns-3-dev-test/regression/tests/test-tcp-large-transfer.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,4 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" - diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-tcp-nsc-lfn.py ns-3-dev-test/regression/tests/test-tcp-nsc-lfn.py --- ns-3-dev/regression/tests/test-tcp-nsc-lfn.py 2010-10-08 15:42:05.934943150 -0700 +++ ns-3-dev-test/regression/tests/test-tcp-nsc-lfn.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,30 +0,0 @@ -#! /usr/bin/env python - -"""Trace-comparison-type regression test for the Network Simulation Cradle.""" - -import platform -import sys - -def may_run(env, options): - if not env['NSC_ENABLED']: - return "NSC not available" - else: - if options.valgrind: - return "NSC does not get along with valgrind" - if sys.platform != 'linux2': - return "NSC is not well supported on non-Linux platforms" - return 0 - - -platform_bits = platform.architecture()[0] -if platform_bits == "64bit": - trace_dir_name = "tcp-nsc-lfn_64bit.ref" -elif platform_bits == "32bit": - trace_dir_name = "tcp-nsc-lfn_32bit.ref" -else: - raise AssertionError("Unknown architecture, not 64 or 32 bit?") -del platform_bits - -arguments = ["--ns3::OnOffApplication::DataRate=40000", "--runtime=20"] - - diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-third.py ns-3-dev-test/regression/tests/test-third.py --- ns-3-dev/regression/tests/test-third.py 2010-10-08 15:42:05.934943150 -0700 +++ ns-3-dev-test/regression/tests/test-third.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,6 +0,0 @@ -#! /usr/bin/env python - -"""Compare that Third generates correct traces.""" - -arguments = ["--verbose=0"] - diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-udp-echo.py ns-3-dev-test/regression/tests/test-udp-echo.py --- ns-3-dev/regression/tests/test-udp-echo.py 2010-10-08 15:42:05.934943150 -0700 +++ ns-3-dev-test/regression/tests/test-udp-echo.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,4 +0,0 @@ -#! /usr/bin/env python - -"""Generic trace-comparison-type regression test.""" - diff -Naur --exclude=.hg ns-3-dev/regression/tests/test-wifi-wired-bridging.py ns-3-dev-test/regression/tests/test-wifi-wired-bridging.py --- ns-3-dev/regression/tests/test-wifi-wired-bridging.py 2010-10-08 15:42:05.935943208 -0700 +++ ns-3-dev-test/regression/tests/test-wifi-wired-bridging.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,6 +0,0 @@ -#! /usr/bin/env python - -"""Compare that Wifi-Wired Bridging generates correct traces.""" - -arguments = ["--SendIp=0"] - diff -Naur --exclude=.hg ns-3-dev/regression/waf ns-3-dev-test/regression/waf --- ns-3-dev/regression/waf 2010-10-08 15:42:05.935943208 -0700 +++ ns-3-dev-test/regression/waf 1969-12-31 16:00:00.000000000 -0800 @@ -1 +0,0 @@ -exec "`dirname "$0"`"/../waf "$@" \ No newline at end of file diff -Naur --exclude=.hg ns-3-dev/regression.py ns-3-dev-test/regression.py --- ns-3-dev/regression.py 2010-10-08 15:42:05.928943130 -0700 +++ ns-3-dev-test/regression.py 1969-12-31 16:00:00.000000000 -0800 @@ -1,308 +0,0 @@ -# python lib modules -import os -import sys -import shutil -import pproc as subprocess -import errno - -# WAF modules -import Options -import Utils -import Task - -# local modules -import wutils - - -def dev_null(): - if sys.platform == 'win32': - return open("NUL:", "w") - else: - return open("/dev/null", "w") - - -def _find_tests(testdir): - """Return a list of test modules in the test directory - - Arguments: - testdir -- the directory to look in for tests - """ - names = os.listdir(testdir) - tests = [] - for name in names: - if name[:5] == "test-" and name[-3:] == ".py": - testname = name[:-3] - tests.append(testname) - tests.sort() - return tests - -def diff(dir1, dir2, verbose): - import filecmp - comp = filecmp.dircmp(dir1, dir2) - differ = (comp.left_only or comp.right_only or comp.diff_files) - - if differ: - # ok, stupid binary comparison reports differences, but maybe - # only text files differ, in which case we should compare - # again while ignoring newline differences between - # windows/mac/unix. - if not comp.left_only and not comp.right_only: - for diff_fname in comp.diff_files: - if not (diff_fname.endswith(".tr") or diff_fname.endswith(".mob")): - # doesn't look like a text file; it has to differ - break - diff_file1 = open(os.path.join(dir1, diff_fname), "rtU").readlines() - diff_file2 = open(os.path.join(dir2, diff_fname), "rtU").readlines() - if diff_file1 != diff_file2: - break - #else: - # print ">>>>>>>> %s file does not really differ!" % (diff_fname) - else: - differ = False - - if differ: - if verbose: - comp.report() - import difflib - for diff_fname in comp.diff_files: - if not (diff_fname.endswith(".tr") or diff_fname.endswith(".mob")): - print "The different file %r does not sound like a text file, not compared." % (diff_fname,) - diff_file1 = open(os.path.join(dir1, diff_fname), "rt").readlines() - diff_file2 = open(os.path.join(dir2, diff_fname), "rt").readlines() - diff = difflib.unified_diff(diff_file1, diff_file2) - count = 0 - print "Differences in file %r" % (diff_fname,) - for line in diff: - print line - count += 1 - if count > 100: - break - return 1 - else: - return 0 - -class regression_test_task(Task.TaskBase): - after = 'cc cxx cc_link cxx_link' - color = 'BLUE' - - def __init__(self, bld, env, test_name, test_scripts_dir, build_traces_dir, reference_traces): - self.bld = bld - self.generator = self - self.env = env - super(regression_test_task, self).__init__(generator=self, env=env) - self.test_name = test_name - - assert self.test_name.startswith('test-') - short_name = self.test_name[len('test-'):] - - self.test_scripts_dir = test_scripts_dir - self.build_traces_dir = build_traces_dir - self.reference_traces_dir = reference_traces - - sys.path.insert(0, self.test_scripts_dir) - try: - mod = __import__(self.test_name, globals(), locals(), []) - finally: - sys.path.remove(self.test_scripts_dir) - self.mod = mod - if hasattr(mod, 'may_run'): - reason_cannot_run = mod.may_run(self.env, Options.options) - else: - reason_cannot_run = None - if not reason_cannot_run: - pyscript = getattr(mod, "pyscript", None) - if pyscript: - Options.options.compile_targets += ',ns3module,pybindgen-command' - else: - program = getattr(mod, "program", short_name) - Options.options.compile_targets += ',' + program - - def __str__(self): - return 'regression-test (%s)\n' % self.test_name - - def runnable_status(self): - return Task.RUN_ME - - def run(self): - """Run a single test""" - assert self.test_name.startswith('test-') - short_name = self.test_name[len('test-'):] - mod = self.mod - trace_dir_name = getattr(mod, "trace_dir_name", None) - if trace_dir_name is None: - trace_dir_name = "%s.ref" % short_name - trace_output_path = os.path.join(self.build_traces_dir, trace_dir_name) - reference_traces_path = os.path.join(self.reference_traces_dir, trace_dir_name) - - if hasattr(mod, 'get_arguments'): - arguments = mod.get_arguments(self.env, '..') - else: - arguments = getattr(mod, "arguments", []) - - pyscript = getattr(mod, "pyscript", None) - if pyscript: - is_pyscript = True - program = pyscript - else: - is_pyscript = False - program = getattr(mod, "program", short_name) - - if hasattr(mod, 'may_run'): - reason_cannot_run = mod.may_run(self.env, Options.options) - else: - reason_cannot_run = None - if reason_cannot_run: - print "SKIP %s (%s)" % (self.test_name, reason_cannot_run) - self.result = None - return 0 - - if Options.options.regression_generate: - # clean the target dir - try: - shutil.rmtree(reference_traces_path) - except OSError, ex: - if ex.errno not in [errno.ENOENT]: - raise - os.makedirs(reference_traces_path) - result = self.run_reference_generate(reference_traces_path, program, arguments, is_pyscript) - if result == 0: - print "GENERATE " + self.test_name - else: - print "GENERATE FAIL " + self.test_name - else: - # clean the target dir - try: - shutil.rmtree(trace_output_path) - except OSError, ex: - if ex.errno not in [errno.ENOENT]: - raise - os.makedirs(trace_output_path) - # run it - #print "self.run_reference_test:(%r, %r, %r, %r, %r)" \ - # % (reference_traces_path, trace_output_path, program, arguments, is_pyscript) - result = self.run_reference_test(reference_traces_path, trace_output_path, program, arguments, is_pyscript) - if result == 0: - print "PASS " + self.test_name - else: - print "FAIL " + self.test_name - self.result = result - return 0 - - def run_reference_test(self, reference_traces_path, trace_output_path, program, arguments, is_pyscript): - if not os.path.exists(reference_traces_path): - print "Cannot locate reference traces in " + reference_traces_path - return 1 - - if is_pyscript: - script = os.path.abspath(os.path.join('..', *os.path.split(program))) - argv = [self.env['PYTHON'], script] + arguments - try: - wutils.run_argv(argv, self.env, cwd=trace_output_path, force_no_valgrind=True) - except Utils.WafError, ex: - print >> sys.stderr, ex - return 1 - else: - try: - wutils.run_program(program, self.env, - command_template=wutils.get_command_template(self.env, arguments), - cwd=trace_output_path) - except Utils.WafError, ex: - print >> sys.stderr, ex - return 1 - - rc = diff(trace_output_path, reference_traces_path, Options.options.verbose) - if rc: - print "----------" - print "Traces differ in test: ", self.test_name - print "Reference traces in directory: " + reference_traces_path - print "Traces in directory: " + trace_output_path - print "Run the following command for details:" - print "\tdiff -u %s %s" % (reference_traces_path, trace_output_path) - if not Options.options.verbose: - print "Or re-run regression testing with option -v" - print "----------" - return rc - - - def run_reference_generate(self, trace_output_path, program, arguments, is_pyscript): - if is_pyscript: - script = os.path.abspath(os.path.join('..', *os.path.split(program))) - argv = [self.env['PYTHON'], script] + arguments - try: - retval = wutils.run_argv(argv, self.env, cwd=trace_output_path, force_no_valgrind=True) - except Utils.WafError, ex: - print >> sys.stderr, ex - return 1 - else: - try: - retval = wutils.run_program(program, self.env, - command_template=wutils.get_command_template(self.env, arguments), - cwd=trace_output_path) - except Utils.WafError, ex: - print >> sys.stderr, ex - return 1 - return retval - - -class regression_test_collector_task(Task.TaskBase): - after = 'regression_test_task' - color = 'BLUE' - - def __init__(self, bld, test_tasks): - self.bld = bld - super(regression_test_collector_task, self).__init__(generator=self) - self.test_tasks = test_tasks - - def __str__(self): - return 'regression-test-collector\n' - - def runnable_status(self): - return Task.RUN_ME - - def run(self): - failed_tests = [test for test in self.test_tasks if test.result is not None and test.result != 0] - skipped_tests = [test for test in self.test_tasks if test.result is None] - print "Regression testing summary:" - if skipped_tests: - print "SKIP: %i of %i tests have been skipped (%s)" % ( - len(skipped_tests), len(self.test_tasks), - ', '.join([test.test_name for test in skipped_tests])) - if failed_tests: - print "FAIL: %i of %i tests have failed (%s)" % ( - len(failed_tests), len(self.test_tasks), - ', '.join([test.test_name for test in failed_tests])) - return 1 - else: - print "PASS: %i of %i tests passed" % (len(self.test_tasks) - len(skipped_tests), - len(self.test_tasks)) - return 0 - -def run_regression(bld, reference_traces): - """Execute regression tests. Called with cwd set to the 'regression' subdir of ns-3. - - @param reference_traces: reference traces directory. - - """ - - testdir = os.path.join("regression", "tests") - if not os.path.exists(testdir): - print "Tests directory does not exist" - sys.exit(3) - - if Options.options.regression_tests: - tests = Options.options.regression_tests.split(',') - else: - tests = _find_tests(testdir) - - if not os.path.exists(reference_traces): - print "Reference traces directory (%s) does not exist" % reference_traces - return 3 - - test_scripts_dir = bld.path.find_dir('regression/tests').abspath() - build_traces_dir = bld.path.find_or_declare('regression/traces').abspath(bld.env) - tasks = [] - for test in tests: - task = regression_test_task(bld, bld.env, test, test_scripts_dir, build_traces_dir, reference_traces) - #bld.task_manager.add_task(task) - tasks.append(task) - regression_test_collector_task(bld, tasks) diff -Naur --exclude=.hg ns-3-dev/src/test/csma-system-test-suite.cc ns-3-dev-test/src/test/csma-system-test-suite.cc --- ns-3-dev/src/test/csma-system-test-suite.cc 1969-12-31 16:00:00.000000000 -0800 +++ ns-3-dev-test/src/test/csma-system-test-suite.cc 2010-10-08 15:40:27.287822104 -0700 @@ -0,0 +1,1126 @@ +/* -*- 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 + */ + +// This is not a test of CsmaNetDevice model behavior per-se, but +// instead is a roll up of several end-to-end examples in examples/csma +// directory, converted into system tests. Writing a test suite +// to test Csma itself is for further study. + +#include + +#include "ns3/address.h" +#include "ns3/application-container.h" +#include "ns3/bridge-helper.h" +#include "ns3/callback.h" +#include "ns3/config.h" +#include "ns3/csma-helper.h" +#include "ns3/csma-star-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-socket-helper.h" +#include "ns3/packet-socket-address.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/v4ping-helper.h" + +using namespace ns3; + +class CsmaBridgeTestCase : public TestCase +{ +public: + CsmaBridgeTestCase (); + virtual ~CsmaBridgeTestCase (); + +private: + virtual bool DoRun (void); + void SinkRx (Ptr p, const Address &ad); + uint32_t m_count; +}; + +// Add some help text to this case to describe what it is intended to test +CsmaBridgeTestCase::CsmaBridgeTestCase () + : TestCase ("Bridge example for Carrier Sense Multiple Access (CSMA) networks"), m_count (0) +{ +} + +CsmaBridgeTestCase::~CsmaBridgeTestCase () +{ +} + +void +CsmaBridgeTestCase::SinkRx (Ptr p, const Address &ad) +{ + m_count++; +} + +// Network topology +// +// n0 n1 +// | | +// ---------- +// | Switch | +// ---------- +// | | +// n2 n3 +// +// - CBR/UDP test flow from n0 to n1; test that packets received on n1 +// +bool +CsmaBridgeTestCase::DoRun (void) +{ + NodeContainer terminals; + terminals.Create (4); + + NodeContainer csmaSwitch; + csmaSwitch.Create (1); + + CsmaHelper csma; + csma.SetChannelAttribute ("DataRate", DataRateValue (5000000)); + csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2))); + + NetDeviceContainer terminalDevices; + NetDeviceContainer switchDevices; + + for (int i = 0; i < 4; i++) + { + NetDeviceContainer link = csma.Install (NodeContainer (terminals.Get (i), csmaSwitch)); + terminalDevices.Add (link.Get (0)); + switchDevices.Add (link.Get (1)); + } + + // Create the bridge netdevice, which will do the packet switching + Ptr switchNode = csmaSwitch.Get (0); + BridgeHelper bridge; + bridge.Install (switchNode, switchDevices); + + InternetStackHelper internet; + internet.Install (terminals); + + Ipv4AddressHelper ipv4; + ipv4.SetBase ("10.1.1.0", "255.255.255.0"); + ipv4.Assign (terminalDevices); + + uint16_t port = 9; // Discard port (RFC 863) + + // Create the OnOff application to send UDP datagrams from n0 to n1. + // + // Make packets be sent about every DefaultPacketSize / DataRate = + // 4096 bits / (5000 bits/second) = 0.82 second. + OnOffHelper onoff ("ns3::UdpSocketFactory", + Address (InetSocketAddress (Ipv4Address ("10.1.1.2"), port))); + onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1))); + onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); + onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000))); + + ApplicationContainer app = onoff.Install (terminals.Get (0)); + app.Start (Seconds (1.0)); + app.Stop (Seconds (10.0)); + + PacketSinkHelper sink ("ns3::UdpSocketFactory", + Address (InetSocketAddress (Ipv4Address::GetAny (), port))); + app = sink.Install (terminals.Get (1)); + app.Start (Seconds (0.0)); + + // Trace receptions + Config::ConnectWithoutContext ("/NodeList/1/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback (&CsmaBridgeTestCase::SinkRx, this)); + + Simulator::Run (); + Simulator::Destroy (); + + // We should have sent and received 10 packets + NS_TEST_ASSERT_MSG_EQ (m_count, 10, "Bridge should have passed 10 packets"); + + return GetErrorStatus (); +} + +class CsmaBroadcastTestCase : public TestCase +{ +public: + CsmaBroadcastTestCase (); + virtual ~CsmaBroadcastTestCase (); + +private: + virtual bool DoRun (void); + void SinkRxNode1 (Ptr p, const Address &ad); + void SinkRxNode2 (Ptr p, const Address &ad); + void DropEvent (Ptr p); + uint32_t m_countNode1; + uint32_t m_countNode2; + uint32_t m_drops; +}; + +// Add some help text to this case to describe what it is intended to test +CsmaBroadcastTestCase::CsmaBroadcastTestCase () + : TestCase ("Broadcast example for Carrier Sense Multiple Access (CSMA) networks"), m_countNode1 (0), m_countNode2 (0), m_drops (0) +{ +} + +CsmaBroadcastTestCase::~CsmaBroadcastTestCase () +{ +} + +void +CsmaBroadcastTestCase::SinkRxNode1 (Ptr p, const Address &ad) +{ + m_countNode1++; +} + +void +CsmaBroadcastTestCase::SinkRxNode2 (Ptr p, const Address &ad) +{ + m_countNode2++; +} + +void +CsmaBroadcastTestCase::DropEvent (Ptr p) +{ + m_drops++; +} + +// +// Example of the sending of a datagram to a broadcast address +// +// Network topology +// ============== +// | | +// n0 n1 n2 +// | | +// ========== +// +// n0 originates UDP broadcast to 255.255.255.255/discard port, which +// is replicated and received on both n1 and n2 +// +bool +CsmaBroadcastTestCase::DoRun (void) +{ + NodeContainer c; + c.Create (3); + NodeContainer c0 = NodeContainer (c.Get (0), c.Get (1)); + NodeContainer c1 = NodeContainer (c.Get (0), c.Get (2)); + + CsmaHelper csma; + csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate(5000000))); + csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds(2))); + + NetDeviceContainer n0 = csma.Install (c0); + NetDeviceContainer n1 = csma.Install (c1); + + InternetStackHelper internet; + internet.Install (c); + + Ipv4AddressHelper ipv4; + ipv4.SetBase ("10.1.0.0", "255.255.255.0"); + ipv4.Assign (n0); + ipv4.SetBase ("192.168.1.0", "255.255.255.0"); + ipv4.Assign (n1); + + + // RFC 863 discard port ("9") indicates packet should be thrown away + // by the system. We allow this silent discard to be overridden + // by the PacketSink application. + uint16_t port = 9; + + // Create the OnOff application to send UDP datagrams from n0. + // + // Make packets be sent about every DefaultPacketSize / DataRate = + // 4096 bits / (5000 bits/second) = 0.82 second. + OnOffHelper onoff ("ns3::UdpSocketFactory", + Address (InetSocketAddress (Ipv4Address ("255.255.255.255"), port))); + onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1))); + onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); + onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000))); + + ApplicationContainer app = onoff.Install (c0.Get (0)); + // Start the application + app.Start (Seconds (1.0)); + app.Stop (Seconds (10.0)); + + // Create an optional packet sink to receive these packets + PacketSinkHelper sink ("ns3::UdpSocketFactory", + Address (InetSocketAddress (Ipv4Address::GetAny (), port))); + app = sink.Install (c0.Get (1)); + app.Add (sink.Install (c1.Get (1))); + app.Start (Seconds (1.0)); + app.Stop (Seconds (10.0)); + + // Trace receptions + Config::ConnectWithoutContext ("/NodeList/1/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback (&CsmaBroadcastTestCase::SinkRxNode1, this)); + Config::ConnectWithoutContext ("/NodeList/2/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback (&CsmaBroadcastTestCase::SinkRxNode2, this)); + + Simulator::Run (); + Simulator::Destroy (); + + // We should have sent and received 10 packets + NS_TEST_ASSERT_MSG_EQ (m_countNode1, 10, "Node 1 should have received 10 packets"); + NS_TEST_ASSERT_MSG_EQ (m_countNode2, 10, "Node 2 should have received 10 packets"); + + return GetErrorStatus (); +} + +class CsmaMulticastTestCase : public TestCase +{ +public: + CsmaMulticastTestCase (); + virtual ~CsmaMulticastTestCase (); + +private: + virtual bool DoRun (void); + void SinkRx (Ptr p, const Address &ad); + void DropEvent (Ptr p); + uint32_t m_count; + uint32_t m_drops; +}; + +// Add some help text to this case to describe what it is intended to test +CsmaMulticastTestCase::CsmaMulticastTestCase () + : TestCase ("Multicast example for Carrier Sense Multiple Access (CSMA) networks"), m_count (0), m_drops (0) +{ +} + +CsmaMulticastTestCase::~CsmaMulticastTestCase () +{ +} + +void +CsmaMulticastTestCase::SinkRx (Ptr p, const Address& ad) +{ + m_count++; +} + +void +CsmaMulticastTestCase::DropEvent (Ptr p) +{ + m_drops++; +} + +// Network topology +// +// Lan1 +// =========== +// | | | +// n0 n1 n2 n3 n4 +// | | | +// =========== +// Lan0 +// +// - Multicast source is at node n0; +// - Multicast forwarded by node n2 onto LAN1; +// - Nodes n0, n1, n2, n3, and n4 receive the multicast frame. +// - Node n4 listens for the data +// +bool +CsmaMulticastTestCase::DoRun (void) +{ + // + // Set up default values for the simulation. + // + // Select DIX/Ethernet II-style encapsulation (no LLC/Snap header) + Config::SetDefault ("ns3::CsmaNetDevice::EncapsulationMode", StringValue ("Dix")); + + NodeContainer c; + c.Create (5); + // We will later want two subcontainers of these nodes, for the two LANs + NodeContainer c0 = NodeContainer (c.Get (0), c.Get (1), c.Get (2)); + NodeContainer c1 = NodeContainer (c.Get (2), c.Get (3), c.Get (4)); + + CsmaHelper csma; + csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000))); + csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2))); + + // We will use these NetDevice containers later, for IP addressing + NetDeviceContainer nd0 = csma.Install (c0); // First LAN + NetDeviceContainer nd1 = csma.Install (c1); // Second LAN + + InternetStackHelper internet; + internet.Install (c); + + Ipv4AddressHelper ipv4Addr; + ipv4Addr.SetBase ("10.1.1.0", "255.255.255.0"); + ipv4Addr.Assign (nd0); + ipv4Addr.SetBase ("10.1.2.0", "255.255.255.0"); + ipv4Addr.Assign (nd1); + + // + // Now we can configure multicasting. As described above, the multicast + // source is at node zero, which we assigned the IP address of 10.1.1.1 + // earlier. We need to define a multicast group to send packets to. This + // can be any multicast address from 224.0.0.0 through 239.255.255.255 + // (avoiding the reserved routing protocol addresses). + // + + Ipv4Address multicastSource ("10.1.1.1"); + Ipv4Address multicastGroup ("225.1.2.4"); + + // Now, we will set up multicast routing. We need to do three things: + // 1) Configure a (static) multicast route on node n2 + // 2) Set up a default multicast route on the sender n0 + // 3) Have node n4 join the multicast group + // We have a helper that can help us with static multicast + Ipv4StaticRoutingHelper multicast; + + // 1) Configure a (static) multicast route on node n2 (multicastRouter) + Ptr multicastRouter = c.Get (2); // The node in question + Ptr inputIf = nd0.Get (2); // The input NetDevice + NetDeviceContainer outputDevices; // A container of output NetDevices + outputDevices.Add (nd1.Get (0)); // (we only need one NetDevice here) + + multicast.AddMulticastRoute (multicastRouter, multicastSource, + multicastGroup, inputIf, outputDevices); + + // 2) Set up a default multicast route on the sender n0 + Ptr sender = c.Get (0); + Ptr senderIf = nd0.Get(0); + multicast.SetDefaultMulticastRoute (sender, senderIf); + + // + // Create an OnOff application to send UDP datagrams from node zero to the + // multicast group (node four will be listening). + // + + uint16_t multicastPort = 9; // Discard port (RFC 863) + + // Configure a multicast packet generator. + // + // Make packets be sent about every defaultPacketSize / dataRate = + // 4096 bits / (5000 bits/second) = 0.82 second. + OnOffHelper onoff ("ns3::UdpSocketFactory", + Address (InetSocketAddress (multicastGroup, multicastPort))); + onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1))); + onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); + onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000))); + + ApplicationContainer srcC = onoff.Install (c0.Get (0)); + + // + // Tell the application when to start and stop. + // + srcC.Start(Seconds(1.)); + srcC.Stop (Seconds(10.)); + + // Create an optional packet sink to receive these packets + PacketSinkHelper sink ("ns3::UdpSocketFactory", + InetSocketAddress (Ipv4Address::GetAny(), multicastPort)); + + ApplicationContainer sinkC = sink.Install (c1.Get (2)); // Node n4 + // Start the sink + sinkC.Start (Seconds (1.0)); + sinkC.Stop (Seconds (10.0)); + + // Trace receptions + Config::ConnectWithoutContext ("/NodeList/4/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback (&CsmaMulticastTestCase::SinkRx, this)); + + // + // Now, do the actual simulation. + // + Simulator::Run (); + Simulator::Destroy (); + + // We should have sent and received 10 packets + NS_TEST_ASSERT_MSG_EQ (m_count, 10, "Node 4 should have received 10 packets"); + + return GetErrorStatus (); +} + +class CsmaOneSubnetTestCase : public TestCase +{ +public: + CsmaOneSubnetTestCase (); + virtual ~CsmaOneSubnetTestCase (); + +private: + virtual bool DoRun (void); + void SinkRxNode0 (Ptr p, const Address &ad); + void SinkRxNode1 (Ptr p, const Address &ad); + void DropEvent (Ptr p); + uint32_t m_countNode0; + uint32_t m_countNode1; + uint32_t m_drops; +}; + +// Add some help text to this case to describe what it is intended to test +CsmaOneSubnetTestCase::CsmaOneSubnetTestCase () + : TestCase ("One subnet example for Carrier Sense Multiple Access (CSMA) networks"), m_countNode0 (0), m_countNode1 (0), m_drops (0) +{ +} + +CsmaOneSubnetTestCase::~CsmaOneSubnetTestCase () +{ +} + +void +CsmaOneSubnetTestCase::SinkRxNode0 (Ptr p, const Address &ad) +{ + m_countNode0++; +} + +void +CsmaOneSubnetTestCase::SinkRxNode1 (Ptr p, const Address &ad) +{ + m_countNode1++; +} + +void +CsmaOneSubnetTestCase::DropEvent (Ptr p) +{ + m_drops++; +} + +// Network topology +// +// n0 n1 n2 n3 +// | | | | +// ================= +// LAN +// +// - CBR/UDP flows from n0 to n1 and from n3 to n0 +// - DropTail queues +// +bool +CsmaOneSubnetTestCase::DoRun (void) +{ + NodeContainer nodes; + nodes.Create (4); + + CsmaHelper csma; + csma.SetChannelAttribute ("DataRate", DataRateValue (5000000)); + csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2))); + // + // Now fill out the topology by creating the net devices required to connect + // the nodes to the channels and hooking them up. + // + NetDeviceContainer devices = csma.Install (nodes); + + InternetStackHelper internet; + internet.Install (nodes); + + // We've got the "hardware" in place. Now we need to add IP addresses. + // + Ipv4AddressHelper ipv4; + ipv4.SetBase ("10.1.1.0", "255.255.255.0"); + Ipv4InterfaceContainer interfaces = ipv4.Assign (devices); + + uint16_t port = 9; // Discard port (RFC 863) + + // + // Create an OnOff application to send UDP datagrams from node zero + // to node 1. + // + // Make packets be sent about every defaultPacketSize / dataRate = + // 4096 bits / (5000 bits/second) = 0.82 second. + OnOffHelper onoff ("ns3::UdpSocketFactory", + Address (InetSocketAddress (interfaces.GetAddress (1), port))); + onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1))); + onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); + onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000))); + + ApplicationContainer app = onoff.Install (nodes.Get (0)); + // Start the application + app.Start (Seconds (1.0)); + app.Stop (Seconds (10.0)); + + // Create an optional packet sink to receive these packets + PacketSinkHelper sink ("ns3::UdpSocketFactory", + Address (InetSocketAddress (Ipv4Address::GetAny (), port))); + app = sink.Install (nodes.Get (1)); + app.Start (Seconds (0.0)); + + // + // Create a similar flow from n3 to n0, starting at time 1.1 seconds + // + onoff.SetAttribute ("Remote", + AddressValue (InetSocketAddress (interfaces.GetAddress (0), port))); + app = onoff.Install (nodes.Get (3)); + app.Start(Seconds (1.1)); + app.Stop (Seconds (10.0)); + + app = sink.Install (nodes.Get (0)); + app.Start (Seconds (0.0)); + + // Trace receptions + Config::ConnectWithoutContext ("/NodeList/0/ApplicationList/1/$ns3::PacketSink/Rx", MakeCallback (&CsmaOneSubnetTestCase::SinkRxNode0, this)); + Config::ConnectWithoutContext ("/NodeList/1/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback (&CsmaOneSubnetTestCase::SinkRxNode1, this)); + + // + // Now, do the actual simulation. + // + Simulator::Run (); + Simulator::Destroy (); + + // We should have sent and received 10 packets + NS_TEST_ASSERT_MSG_EQ (m_countNode0, 10, "Node 0 should have received 10 packets"); + NS_TEST_ASSERT_MSG_EQ (m_countNode1, 10, "Node 1 should have received 10 packets"); + + return GetErrorStatus (); +} + +class CsmaPacketSocketTestCase : public TestCase +{ +public: + CsmaPacketSocketTestCase (); + virtual ~CsmaPacketSocketTestCase (); + +private: + virtual bool DoRun (void); + void SinkRx (std::string path, Ptr p, const Address &address); + void DropEvent (Ptr p); + uint32_t m_count; + uint32_t m_drops; +}; + +// Add some help text to this case to describe what it is intended to test +CsmaPacketSocketTestCase::CsmaPacketSocketTestCase () + : TestCase ("Packet socket example for Carrier Sense Multiple Access (CSMA) networks"), m_count (0), m_drops (0) +{ +} + +CsmaPacketSocketTestCase::~CsmaPacketSocketTestCase () +{ +} + +void +CsmaPacketSocketTestCase::SinkRx (std::string path, Ptr p, const Address& address) +{ + m_count++; +} + +void +CsmaPacketSocketTestCase::DropEvent (Ptr p) +{ + m_drops++; +} + +// +// Network topology +// +// n0 n1 n2 n3 +// | | | | +// ===================== +// +// - Packet socket flow from n0 to n1 and from node n3 to n0 +// -- We will test reception at node n0 +// - Default 512 byte packets generated by traffic generator +// +bool +CsmaPacketSocketTestCase::DoRun (void) +{ + // Here, we will explicitly create four nodes. + NodeContainer nodes; + nodes.Create (4); + + PacketSocketHelper packetSocket; + packetSocket.Install (nodes); + + // create the shared medium used by all csma devices. + Ptr channel = CreateObjectWithAttributes ( + "DataRate", DataRateValue (DataRate(5000000)), + "Delay", TimeValue (MilliSeconds(2))); + + // use a helper function to connect our nodes to the shared channel. + CsmaHelper csma; + csma.SetDeviceAttribute ("EncapsulationMode", StringValue ("Llc")); + NetDeviceContainer devs = csma.Install (nodes, channel); + + // Create the OnOff application to send raw datagrams + // + // Make packets be sent about every DefaultPacketSize / DataRate = + // 4096 bits / (5000 bits/second) = 0.82 second. + PacketSocketAddress socket; + socket.SetSingleDevice(devs.Get (0)->GetIfIndex ()); + socket.SetPhysicalAddress (devs.Get (1)->GetAddress ()); + socket.SetProtocol (2); + OnOffHelper onoff ("ns3::PacketSocketFactory", Address (socket)); + onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1.0))); + onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0.0))); + onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000))); + ApplicationContainer apps = onoff.Install (nodes.Get (0)); + apps.Start (Seconds (1.0)); + apps.Stop (Seconds (10.0)); + + socket.SetSingleDevice (devs.Get (3)->GetIfIndex ()); + socket.SetPhysicalAddress (devs.Get (0)->GetAddress ()); + socket.SetProtocol (3); + onoff.SetAttribute ("Remote", AddressValue (socket)); + onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0.0))); + apps = onoff.Install (nodes.Get (3)); + apps.Start (Seconds (1.0)); + apps.Stop (Seconds (10.0)); + + PacketSinkHelper sink = PacketSinkHelper ("ns3::PacketSocketFactory", + socket); + apps = sink.Install (nodes.Get (0)); + apps.Start (Seconds (0.0)); + apps.Stop (Seconds (20.0)); + + // Trace receptions + Config::Connect ("/NodeList/0/ApplicationList/*/$ns3::PacketSink/Rx", + MakeCallback (&CsmaPacketSocketTestCase::SinkRx, this)); + + Simulator::Run (); + Simulator::Destroy (); + + // We should have received 10 packets on node 0 + NS_TEST_ASSERT_MSG_EQ (m_count, 10, "Node 0 should have received 10 packets"); + + return GetErrorStatus (); +} + +class CsmaPingTestCase : public TestCase +{ +public: + CsmaPingTestCase (); + virtual ~CsmaPingTestCase (); + +private: + virtual bool DoRun (void); + void SinkRx (Ptr p, const Address &ad); + void PingRtt (std::string context, Time rtt); + void DropEvent (Ptr p); + uint32_t m_countSinkRx; + uint32_t m_countPingRtt; + uint32_t m_drops; +}; + +// Add some help text to this case to describe what it is intended to test +CsmaPingTestCase::CsmaPingTestCase () + : TestCase ("Ping example for Carrier Sense Multiple Access (CSMA) networks"), m_countSinkRx (0), m_countPingRtt (0), m_drops (0) +{ +} + +CsmaPingTestCase::~CsmaPingTestCase () +{ +} + +void +CsmaPingTestCase::SinkRx (Ptr p, const Address &ad) +{ + m_countSinkRx++; +} + +void +CsmaPingTestCase::PingRtt (std::string context, Time rtt) +{ + m_countPingRtt++; +} + +void +CsmaPingTestCase::DropEvent (Ptr p) +{ + m_drops++; +} + +// Network topology +// +// n0 n1 n2 n3 +// | | | | +// ===================== +// +// node n0,n1,n3 pings to node n2 +// node n0 generates protocol 2 (IGMP) to node n3 +// +bool +CsmaPingTestCase::DoRun (void) +{ + // Here, we will explicitly create four nodes. + NodeContainer c; + c.Create (4); + + // connect all our nodes to a shared channel. + CsmaHelper csma; + csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000))); + csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2))); + csma.SetDeviceAttribute ("EncapsulationMode", StringValue ("Llc")); + NetDeviceContainer devs = csma.Install (c); + + // add an ip stack to all nodes. + InternetStackHelper ipStack; + ipStack.Install (c); + + // assign ip addresses + Ipv4AddressHelper ip; + ip.SetBase ("192.168.1.0", "255.255.255.0"); + Ipv4InterfaceContainer addresses = ip.Assign (devs); + + // Create the OnOff application to send UDP datagrams from n0 to n1. + // + // Make packets be sent about every DefaultPacketSize / DataRate = + // 4096 bits / (5000 bits/second) = 0.82 second. + Config::SetDefault ("ns3::Ipv4RawSocketImpl::Protocol", StringValue ("2")); + InetSocketAddress dst = InetSocketAddress (addresses.GetAddress (3)); + OnOffHelper onoff = OnOffHelper ("ns3::Ipv4RawSocketFactory", dst); + onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1.0))); + onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0.0))); + onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000))); + + ApplicationContainer apps = onoff.Install (c.Get (0)); + apps.Start (Seconds (1.0)); + apps.Stop (Seconds (10.0)); + + PacketSinkHelper sink = PacketSinkHelper ("ns3::Ipv4RawSocketFactory", dst); + apps = sink.Install (c.Get (3)); + apps.Start (Seconds (0.0)); + apps.Stop (Seconds (11.0)); + + V4PingHelper ping = V4PingHelper (addresses.GetAddress (2)); + NodeContainer pingers; + pingers.Add (c.Get (0)); + pingers.Add (c.Get (1)); + pingers.Add (c.Get (3)); + apps = ping.Install (pingers); + apps.Start (Seconds (2.0)); + apps.Stop (Seconds (5.0)); + + // Trace receptions + Config::ConnectWithoutContext ("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx", + MakeCallback (&CsmaPingTestCase::SinkRx, this)); + + // Trace pings + Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::V4Ping/Rtt", + MakeCallback (&CsmaPingTestCase::PingRtt, this)); + + Simulator::Run (); + Simulator::Destroy (); + + // We should have sent and received 10 packets + NS_TEST_ASSERT_MSG_EQ (m_countSinkRx, 10, "Node 3 should have received 10 packets"); + + // We should have 3 pingers that ping every second for 3 seconds. + NS_TEST_ASSERT_MSG_EQ (m_countPingRtt, 9, "Node 2 should have been pinged 9 times"); + + return GetErrorStatus (); +} + +class CsmaRawIpSocketTestCase : public TestCase +{ +public: + CsmaRawIpSocketTestCase (); + virtual ~CsmaRawIpSocketTestCase (); + +private: + virtual bool DoRun (void); + void SinkRx (Ptr p, const Address &ad); + void DropEvent (Ptr p); + uint32_t m_count; + uint32_t m_drops; +}; + +// Add some help text to this case to describe what it is intended to test +CsmaRawIpSocketTestCase::CsmaRawIpSocketTestCase () + : TestCase ("Raw internet protocol socket example for Carrier Sense Multiple Access (CSMA) networks"), m_count (0), m_drops (0) +{ +} + +CsmaRawIpSocketTestCase::~CsmaRawIpSocketTestCase () +{ +} + +void +CsmaRawIpSocketTestCase::SinkRx (Ptr p, const Address &ad) +{ + m_count++; +} + +void +CsmaRawIpSocketTestCase::DropEvent (Ptr p) +{ + m_drops++; +} + +// +// Network topology +// (sender) (receiver) +// n0 n1 n2 n3 +// | | | | +// ===================== +// +// Node n0 sends data to node n3 over a raw IP socket. The protocol +// number used is 2. +// +bool +CsmaRawIpSocketTestCase::DoRun (void) +{ + // Here, we will explicitly create four nodes. + NodeContainer c; + c.Create (4); + + // connect all our nodes to a shared channel. + CsmaHelper csma; + csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000))); + csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2))); + csma.SetDeviceAttribute ("EncapsulationMode", StringValue ("Llc")); + NetDeviceContainer devs = csma.Install (c); + + // add an ip stack to all nodes. + InternetStackHelper ipStack; + ipStack.Install (c); + + // assign ip addresses + Ipv4AddressHelper ip; + ip.SetBase ("192.168.1.0", "255.255.255.0"); + Ipv4InterfaceContainer addresses = ip.Assign (devs); + + // IP protocol configuration + // + // Make packets be sent about every DefaultPacketSize / DataRate = + // 4096 bits / (5000 bits/second) = 0.82 second. + Config::SetDefault ("ns3::Ipv4RawSocketImpl::Protocol", StringValue ("2")); + InetSocketAddress dst = InetSocketAddress (addresses.GetAddress (3)); + OnOffHelper onoff = OnOffHelper ("ns3::Ipv4RawSocketFactory", dst); + onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1.0))); + onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0.0))); + onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000))); + + ApplicationContainer apps = onoff.Install (c.Get (0)); + apps.Start (Seconds (1.0)); + apps.Stop (Seconds (10.0)); + + PacketSinkHelper sink = PacketSinkHelper ("ns3::Ipv4RawSocketFactory", dst); + apps = sink.Install (c.Get (3)); + apps.Start (Seconds (0.0)); + apps.Stop (Seconds (12.0)); + + // Trace receptions + Config::ConnectWithoutContext ("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx", + MakeCallback (&CsmaRawIpSocketTestCase::SinkRx, this)); + + Simulator::Run (); + Simulator::Destroy (); + + // We should have sent and received 10 packets + NS_TEST_ASSERT_MSG_EQ (m_count, 10, "Node 3 should have received 10 packets"); + + return GetErrorStatus (); +} + +class CsmaStarTestCase : public TestCase +{ +public: + CsmaStarTestCase (); + virtual ~CsmaStarTestCase (); + +private: + virtual bool DoRun (void); + void SinkRx (Ptr p, const Address &ad); + void DropEvent (Ptr p); + uint32_t m_count; + uint32_t m_drops; +}; + +// Add some help text to this case to describe what it is intended to test +CsmaStarTestCase::CsmaStarTestCase () + : TestCase ("Star example for Carrier Sense Multiple Access (CSMA) networks"), m_count (0), m_drops (0) +{ +} + +CsmaStarTestCase::~CsmaStarTestCase () +{ +} + +void +CsmaStarTestCase::SinkRx (Ptr p, const Address& ad) +{ + m_count++; +} + +void +CsmaStarTestCase::DropEvent (Ptr p) +{ + m_drops++; +} + +// Network topology (default) +// +// n2 + + n3 . +// | ... |\ /| ... | . +// ======= \ / ======= . +// CSMA \ / CSMA . +// \ / . +// n1 +--- n0 ---+ n4 . +// | ... | / \ | ... | . +// ======= / \ ======= . +// CSMA / \ CSMA . +// / \ . +// n6 + + n5 . +// | ... | | ... | . +// ======= ======= . +// CSMA CSMA . +// +bool +CsmaStarTestCase::DoRun (void) +{ + // + // Default number of nodes in the star. + // + uint32_t nSpokes = 7; + + CsmaHelper csma; + csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps")); + csma.SetChannelAttribute ("Delay", StringValue ("1ms")); + CsmaStarHelper star (nSpokes, csma); + + NodeContainer fillNodes; + + // + // Just to be nasy, hang some more nodes off of the CSMA channel for each + // spoke, so that there are a total of 16 nodes on each channel. Stash + // all of these new devices into a container. + // + NetDeviceContainer fillDevices; + + uint32_t nFill = 14; + for (uint32_t i = 0; i < star.GetSpokeDevices ().GetN (); ++i) + { + Ptr channel = star.GetSpokeDevices ().Get (i)->GetChannel (); + Ptr csmaChannel = channel->GetObject (); + NodeContainer newNodes; + newNodes.Create (nFill); + fillNodes.Add (newNodes); + fillDevices.Add (csma.Install (newNodes, csmaChannel)); + } + + InternetStackHelper internet; + star.InstallStack (internet); + internet.Install (fillNodes); + + star.AssignIpv4Addresses (Ipv4AddressHelper ("10.1.0.0", "255.255.255.0")); + + // + // We assigned addresses to the logical hub and the first "drop" of the + // CSMA network that acts as the spoke, but we also have a number of fill + // devices (nFill) also hanging off the CSMA network. We have got to + // assign addresses to them as well. We put all of the fill devices into + // a single device container, so the first nFill devices are associated + // with the channel connected to spokeDevices.Get (0), the second nFill + // devices afe associated with the channel connected to spokeDevices.Get (1) + // etc. + // + Ipv4AddressHelper address; + for(uint32_t i = 0; i < star.SpokeCount (); ++i) + { + std::ostringstream subnet; + subnet << "10.1." << i << ".0"; + address.SetBase (subnet.str ().c_str (), "255.255.255.0", "0.0.0.3"); + + for (uint32_t j = 0; j < nFill; ++j) + { + address.Assign (fillDevices.Get (i * nFill + j)); + } + } + + // + // Create a packet sink on the star "hub" to receive packets. + // + uint16_t port = 50000; + Address hubLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port)); + PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", hubLocalAddress); + ApplicationContainer hubApp = packetSinkHelper.Install (star.GetHub ()); + hubApp.Start (Seconds (1.0)); + hubApp.Stop (Seconds (10.0)); + + // + // Create OnOff applications to send TCP to the hub, one on each spoke node. + // + // Make packets be sent about every DefaultPacketSize / DataRate = + // 4096 bits / (5000 bits/second) = 0.82 second. + OnOffHelper onOffHelper ("ns3::TcpSocketFactory", Address ()); + onOffHelper.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1))); + onOffHelper.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); + onOffHelper.SetAttribute ("DataRate", DataRateValue (DataRate (5000))); + + ApplicationContainer spokeApps; + + for (uint32_t i = 0; i < star.SpokeCount (); ++i) + { + AddressValue remoteAddress (InetSocketAddress (star.GetHubIpv4Address (i), port)); + onOffHelper.SetAttribute ("Remote", remoteAddress); + spokeApps.Add (onOffHelper.Install (star.GetSpokeNode (i))); + } + + spokeApps.Start (Seconds (1.0)); + spokeApps.Stop (Seconds (10.0)); + + // + // Because we are evil, we also add OnOff applications to send TCP to the hub + // from the fill devices on each CSMA link. The first nFill nodes in the + // fillNodes container are on the CSMA network talking to the zeroth device + // on the hub node. The next nFill nodes are on the CSMA network talking to + // the first device on the hub node, etc. So the ith fillNode is associated + // with the hub address found on the (i / nFill)th device on the hub node. + // + ApplicationContainer fillApps; + + for (uint32_t i = 0; i < fillNodes.GetN (); ++i) + { + AddressValue remoteAddress (InetSocketAddress (star.GetHubIpv4Address (i / nFill), port)); + onOffHelper.SetAttribute ("Remote", remoteAddress); + fillApps.Add (onOffHelper.Install (fillNodes.Get (i))); + } + + fillApps.Start (Seconds (1.0)); + fillApps.Stop (Seconds (10.0)); + + // + // Turn on global static routing so we can actually be routed across the star. + // + Ipv4GlobalRoutingHelper::PopulateRoutingTables (); + + // Trace receptions + Config::ConnectWithoutContext ("/NodeList/0/ApplicationList/*/$ns3::PacketSink/Rx", + MakeCallback (&CsmaStarTestCase::SinkRx, this)); + + Simulator::Run (); + Simulator::Destroy (); + + // The hub node should have received 10 packets from the nFill + 1 + // nodes on each spoke. + NS_TEST_ASSERT_MSG_EQ (m_count, 10 * ( nSpokes * (nFill + 1)), "Hub node did not receive the proper number of packets"); + + return GetErrorStatus (); +} + +class CsmaSystemTestSuite : public TestSuite +{ +public: + CsmaSystemTestSuite (); +}; + +CsmaSystemTestSuite::CsmaSystemTestSuite () + : TestSuite ("csma-system", BVT) +{ + AddTestCase (new CsmaBridgeTestCase); + AddTestCase (new CsmaBroadcastTestCase); + AddTestCase (new CsmaMulticastTestCase); + AddTestCase (new CsmaOneSubnetTestCase); + AddTestCase (new CsmaPacketSocketTestCase); + AddTestCase (new CsmaPingTestCase); + AddTestCase (new CsmaRawIpSocketTestCase); + AddTestCase (new CsmaStarTestCase); +} + +// Do not forget to allocate an instance of this TestSuite +static CsmaSystemTestSuite csmaSystemTestSuite; diff -Naur --exclude=.hg ns-3-dev/src/test/global-routing-test-suite.cc ns-3-dev-test/src/test/global-routing-test-suite.cc --- ns-3-dev/src/test/global-routing-test-suite.cc 1969-12-31 16:00:00.000000000 -0800 +++ ns-3-dev-test/src/test/global-routing-test-suite.cc 2010-10-08 15:27:56.263818811 -0700 @@ -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 p, const Address &address); + void HandleRead (Ptr); + 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 p, const Address& address) +{ + Ipv4PacketInfoTag tag; + bool found; + found = p->PeekPacketTag (tag); + uint8_t now = static_cast (Simulator::Now ().GetSeconds ()); + if (found) + { + ; + } + m_firstInterface[now]++; + m_count++; +} + +void +DynamicGlobalRoutingTestCase::HandleRead (Ptr socket) +{ + Ptr 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 (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 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 n1 = c.Get (1); + Ptr ipv41 = n1->GetObject (); + // 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 n6 = c.Get (6); + Ptr ipv46 = n6->GetObject (); + // 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 nA = CreateObject (); + Ptr nB = CreateObject (); + Ptr nC = CreateObject (); + + 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 deviceA = CreateObject (); + deviceA->SetAddress (Mac48Address::Allocate ()); + nA->AddDevice (deviceA); + + Ptr deviceC = CreateObject (); + 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 ipv4A = nA->GetObject (); + Ptr ipv4C = nC->GetObject (); + + 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 sinkPtr = DynamicCast (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; diff -Naur --exclude=.hg ns-3-dev/src/test/static-routing-test-suite.cc ns-3-dev-test/src/test/static-routing-test-suite.cc --- ns-3-dev/src/test/static-routing-test-suite.cc 1969-12-31 16:00:00.000000000 -0800 +++ ns-3-dev-test/src/test/static-routing-test-suite.cc 2010-10-08 15:27:50.207943883 -0700 @@ -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 nA = CreateObject (); + Ptr nB = CreateObject (); + Ptr nC = CreateObject (); + + 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 deviceA = CreateObject (); + deviceA->SetAddress (Mac48Address::Allocate ()); + nA->AddDevice (deviceA); + + Ptr deviceC = CreateObject (); + 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 ipv4A = nA->GetObject (); + Ptr ipv4B = nB->GetObject (); + Ptr ipv4C = nC->GetObject (); + + 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 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 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 sinkPtr = DynamicCast (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; diff -Naur --exclude=.hg ns-3-dev/src/test/wscript ns-3-dev-test/src/test/wscript --- ns-3-dev/src/test/wscript 2010-10-08 15:42:06.580943183 -0700 +++ ns-3-dev-test/src/test/wscript 2010-10-08 15:41:26.176943467 -0700 @@ -6,7 +6,10 @@ 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', ] diff -Naur --exclude=.hg ns-3-dev/wscript ns-3-dev-test/wscript --- ns-3-dev/wscript 2010-10-08 15:42:06.600942702 -0700 +++ ns-3-dev-test/wscript 2010-10-08 15:12:14.094942851 -0700 @@ -43,7 +43,6 @@ # local modules import wutils -import regression Configure.autoconfig = 1 @@ -54,14 +53,6 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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) diff -Naur --exclude=.hg ns-3-dev/wutils.py ns-3-dev-test/wutils.py --- ns-3-dev/wutils.py 2010-10-08 15:42:06.601943292 -0700 +++ ns-3-dev-test/wutils.py 2010-10-08 15:12:14.094942851 -0700 @@ -19,13 +19,6 @@ 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=()):