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

(-)ns-3-dev/CHANGES.html (+5 lines)
 Lines 47-52    Link Here 
47
<h1>Changes from ns-3.9 to ns-3.10</h1>
47
<h1>Changes from ns-3.9 to ns-3.10</h1>
48
48
49
<h2>Changes to build system:</h2>
49
<h2>Changes to build system:</h2>
50
<ul>
51
<li><b>Regression tests are no longer run using waf</b>
52
<p>All regression testing is now being done in test.py.  As a result, reference traces are no longer needed in ns-3 to perform regression testing.
53
</p>
54
</ul>
50
55
51
<h2>New API:</h2>
56
<h2>New API:</h2>
52
57
(-)ns-3-dev/doc/manual/tcp.texi (-3 / +3 lines)
 Lines 148-157    Link Here 
148
additional arguments are needed for waf.  Building nsc may take some time
148
additional arguments are needed for waf.  Building nsc may take some time
149
compared to ns-3; it is interleaved in the ns-3 building process.
149
compared to ns-3; it is interleaved in the ns-3 building process.
150
150
151
Try running the regression tests: @code{./waf --regression}.  If NSC has
151
Try running the following ns-3 test suite: @code{./test.py -s ns3-tcp-interoperability}.  If NSC has
152
been successfully built, the following test should show up in the results:
152
been successfully built, the following should show up in the results:
153
@verbatim
153
@verbatim
154
PASS test-tcp-nsc-lfn
154
PASS: TestSuite ns3-tcp-interoperability
155
@end verbatim
155
@end verbatim
156
156
157
This confirms that NSC is ready to use.
157
This confirms that NSC is ready to use.
(-)ns-3-dev/doc/release_steps.txt (-19 / +7 lines)
 Lines 7-13    Link Here 
7
   - confirm that the release builds cleanly.
7
   - confirm that the release builds cleanly.
8
   - cd ns-3-dev
8
   - cd ns-3-dev
9
   - ensure that tests pass (./test.py)
9
   - ensure that tests pass (./test.py)
10
   - ensure no regressions (./waf --regression)
11
2. prepare the source files
10
2. prepare the source files
12
   - revise and check in AUTHORS, if needed
11
   - revise and check in AUTHORS, if needed
13
   - revise and check in RELEASE_NOTES.  Make sure to add the Availability 
12
   - revise and check in RELEASE_NOTES.  Make sure to add the Availability 
 Lines 21-49    Link Here 
21
   - this will create an ns-allinone-dev.tar.bz2 tarball
20
   - this will create an ns-allinone-dev.tar.bz2 tarball
22
4. test dev tarball on release platforms 
21
4. test dev tarball on release platforms 
23
   - ./test.py 
22
   - ./test.py 
24
   - ./waf --regression
25
   - other scripts you can think of
23
   - other scripts you can think of
26
5. once you are happy with the tarball, tag ns-3-dev and ns-3-dev-ref-traces
24
5. once you are happy with the tarball and tag ns-3-dev
27
   - cd into ns-3-dev
25
   - cd into ns-3-dev
28
   - hg tag "ns-3.x"
26
   - hg tag "ns-3.x"
29
   - hg push 
27
   - hg push 
30
   - cd into ns-3-dev-ref-traces
31
   - hg tag "ns-3.x"
32
   - hg push 
33
6. clone the tagged ns-3-dev and place it on the repository
28
6. clone the tagged ns-3-dev and place it on the repository
34
   - ssh code.nsnam.org; sudo bash; su code;
29
   - ssh code.nsnam.org; sudo bash; su code;
35
   - cp -r /home/code/repos/ns-3-dev /home/code/repos/ns-3.x
30
   - cp -r /home/code/repos/ns-3-dev /home/code/repos/ns-3.x
36
   - cd /home/code/repos/ns-3.x/.hg and edit the hgrc appropriately:
31
   - cd /home/code/repos/ns-3.x/.hg and edit the hgrc appropriately:
37
     "description = ns-3.x release
32
     "description = ns-3.x release
38
      name = ns-3.x"
33
      name = ns-3.x"
39
   - clone the ns-3-dev-ref-traces and place it on the repository as above
40
     but use the name ns-3.x-ref-traces and edit the hgrc appropriately
41
7. check out a clean version of the new release (ns-3.x) somewhere
34
7. check out a clean version of the new release (ns-3.x) somewhere
42
   - hg clone http://code.nsnam.org/ns-3.x
35
   - hg clone http://code.nsnam.org/ns-3.x
43
8. Update the VERSION for this new release
36
8. Update the VERSION for this new release
44
   - change the string 3-dev in the VERSION file to the real version 
37
   - change the string 3-dev in the VERSION file to the real version 
45
     (e.g. 3.7 or 3.7-RC1)  This must agree with the version name you chose in the clone
38
     (e.g. 3.7 or 3.7-RC1)  This must agree with the version name you chose in the clone.
46
     for the regression tests to work.
47
   - hg commit -m "update VERSION to ns-3.x"
39
   - hg commit -m "update VERSION to ns-3.x"
48
   - hg push ssh://code@code.nsnam.org//home/code/repos/ns-3.x
40
   - hg push ssh://code@code.nsnam.org//home/code/repos/ns-3.x
49
41
 Lines 51-75    Link Here 
51
   You need to use ns-3-allinone since you will use that to make the distro
43
   You need to use ns-3-allinone since you will use that to make the distro
52
   - hg clone http://code.nsnam.org/ns-3-allinone ns-3-allinone-3.x-test
44
   - hg clone http://code.nsnam.org/ns-3-allinone ns-3-allinone-3.x-test
53
   - cd !$
45
   - cd !$
54
   - ./download.py -n ns-3.x -r ns-3.x-ref-traces
46
   - ./download.py -n ns-3.x
55
   - ./build.py
47
   - ./build.py
56
   - cd ns-3.x
48
   - cd ns-3.x
57
   - ./test.py
49
   - ./test.py
58
   - ./test.py -g
50
   - ./test.py -g
59
   - ./waf --regression
60
   - ./waf --valgrind --regression (for valgrind version)
61
   - ./waf -d optimized configure
51
   - ./waf -d optimized configure
62
   - ./waf
52
   - ./waf
63
   - ./test.py
53
   - ./test.py
64
   - ./test.py -g
54
   - ./test.py -g
65
   - ./waf --regression
55
   - There should be no test errors at this time
66
   - ./waf --valgrind --regression (for valgrind version)
67
   - There should be no regression errors at this time
68
10. Create final tarballs
56
10. Create final tarballs
69
    You need to work with a clean ns-3-allinone-3.x directory
57
    You need to work with a clean ns-3-allinone-3.x directory
70
   - hg clone http://code.nsnam.org/ns-3-allinone ns-3-allinone-3.x
58
   - hg clone http://code.nsnam.org/ns-3-allinone ns-3-allinone-3.x
71
   - cd !$
59
   - cd !$
72
   - ./download.py -n ns-3.x -r ns-3.x-ref-traces
60
   - ./download.py -n ns-3.x
73
   - ./dist.py
61
   - ./dist.py
74
   - notice we did not build here
62
   - notice we did not build here
75
   - this will create an ns-allinone-3.x.tar.bz2 tarball
63
   - this will create an ns-allinone-3.x.tar.bz2 tarball
 Lines 110-118    Link Here 
110
        necessary files
98
        necessary files
111
16. Final checks
99
16. Final checks
112
   - check manual, testing, and tutorial documentation links
100
   - check manual, testing, and tutorial documentation links
113
   - download tarball from web, build and run regression tests for as many
101
   - download tarball from web, build and run tests for as many
114
     targets as you can
102
     targets as you can
115
   - download release from mercurial, build and run regression tests for as
103
   - download release from mercurial, build and run tests for as
116
     many targets as you can
104
     many targets as you can
117
   - test and verify until you're confident the release is solid.
105
   - test and verify until you're confident the release is solid.
118
17. announce to ns-developers, with summary of release notes
106
17. announce to ns-developers, with summary of release notes
(-)ns-3-dev/doc/tutorial/conceptual-overview.texi (-6 / +4 lines)
 Lines 174-183    Link Here 
174
directory structure something like the following:
174
directory structure something like the following:
175
175
176
@verbatim
176
@verbatim
177
  AUTHORS       doc/       README          RELEASE_NOTES  utils/    wscript
177
  AUTHORS       doc/       README         src/     waf.bat*
178
  bindings/     examples/  regression/     samples/       VERSION   wutils.py
178
  bindings/     examples/  RELEASE_NOTES  utils/   wscript
179
  build/        LICENSE    regression.py   scratch/       waf*      wutils.pyc
179
  build/        LICENSE    samples/       VERSION  wutils.py
180
  CHANGES.html  ns3/       regression.pyc  src/           waf.bat*
180
  CHANGES.html  ns3/       scratch/       waf*     wutils.pyc
181
@end verbatim
181
@end verbatim
182
182
183
@cindex first.cc
183
@cindex first.cc
 Lines 811-817    Link Here 
811
drwxr-xr-x                               doc              files
811
drwxr-xr-x                               doc              files
812
drwxr-xr-x                               examples         files
812
drwxr-xr-x                               examples         files
813
drwxr-xr-x                               ns3              files
813
drwxr-xr-x                               ns3              files
814
drwxr-xr-x                               regression       files
815
drwxr-xr-x                               samples          files
814
drwxr-xr-x                               samples          files
816
drwxr-xr-x                               scratch          files
815
drwxr-xr-x                               scratch          files
817
drwxr-xr-x                               src              files
816
drwxr-xr-x                               src              files
 Lines 824-830    Link Here 
824
-rw-r--r-- 2009-07-01 12:47 +0200 3742   README           file | revisions | annotate
823
-rw-r--r-- 2009-07-01 12:47 +0200 3742   README           file | revisions | annotate
825
-rw-r--r-- 2009-07-01 12:47 +0200 16171  RELEASE_NOTES    file | revisions | annotate
824
-rw-r--r-- 2009-07-01 12:47 +0200 16171  RELEASE_NOTES    file | revisions | annotate
826
-rw-r--r-- 2009-07-01 12:47 +0200 6      VERSION          file | revisions | annotate
825
-rw-r--r-- 2009-07-01 12:47 +0200 6      VERSION          file | revisions | annotate
827
-rw-r--r-- 2009-07-01 12:47 +0200 10946  regression.py    file | revisions | annotate
828
-rwxr-xr-x 2009-07-01 12:47 +0200 88110  waf              file | revisions | annotate
826
-rwxr-xr-x 2009-07-01 12:47 +0200 88110  waf              file | revisions | annotate
829
-rwxr-xr-x 2009-07-01 12:47 +0200 28     waf.bat          file | revisions | annotate
827
-rwxr-xr-x 2009-07-01 12:47 +0200 28     waf.bat          file | revisions | annotate
830
-rw-r--r-- 2009-07-01 12:47 +0200 35395  wscript          file | revisions | annotate
828
-rw-r--r-- 2009-07-01 12:47 +0200 35395  wscript          file | revisions | annotate
(-)ns-3-dev/doc/tutorial/getting-started.texi (-115 / +16 lines)
 Lines 126-145    Link Here 
126
still hypothetical release nine of @command{ns-3} would be numbered as
126
still hypothetical release nine of @command{ns-3} would be numbered as
127
@code{ns-3.9.2}.
127
@code{ns-3.9.2}.
128
128
129
We have had a regression testing framework in place since the first release.
130
For each release, a set of output files that define ``good behavior'' are saved.
131
These known good output files are called reference traces and are associated 
132
with a given release by name.  For example, in @uref{http://code.nsnam.org/}
133
you will find a repository named @code{ns-3.1} which is the first stable release
134
of @command{ns-3}.  You will also find a separate repository named 
135
@code{ns-3.1-ref-traces} that holds the reference traces for the @code{ns-3.1}
136
release.  It is crucial to keep these files consistent if you want to do any
137
regression testing of your repository.  This is a good idea to do at least once
138
to verify everything has built correctly.
139
140
The current development snapshot (unreleased) of @command{ns-3} may be found 
129
The current development snapshot (unreleased) of @command{ns-3} may be found 
141
at @uref{http://code.nsnam.org/ns-3-dev/} and the associated reference traces
130
at @uref{http://code.nsnam.org/ns-3-dev/}.  The 
142
may be found at @uref{http://code.nsnam.org/ns-3-dev-ref-traces/}.  The 
143
developers attempt to keep these repository in consistent, working states but
131
developers attempt to keep these repository in consistent, working states but
144
they are in a development area with unreleased code present, so you may want 
132
they are in a development area with unreleased code present, so you may want 
145
to consider staying with an official release if you do not need newly-
133
to consider staying with an official release if you do not need newly-
 Lines 147-154    Link Here 
147
135
148
Since the release numbers are going to be changing, I will stick with 
136
Since the release numbers are going to be changing, I will stick with 
149
the more constant ns-3-dev here in the tutorial, but you can replace the 
137
the more constant ns-3-dev here in the tutorial, but you can replace the 
150
string ``ns-3-dev'' with your choice of release (e.g., ns-3.6 and 
138
string ``ns-3-dev'' with your choice of release (e.g., ns-3.6) in the 
151
ns-3.6-ref-traces) in the text below.  You can find the latest version  of the
139
text below.  You can find the latest version  of the
152
code either by inspection of the repository list or by going to the 
140
code either by inspection of the repository list or by going to the 
153
@uref{http://www.nsnam.org/getting_started.html,,``Getting Started''} 
141
@uref{http://www.nsnam.org/getting_started.html,,``Getting Started''} 
154
web page and looking for the latest release identifier.
142
web page and looking for the latest release identifier.
 Lines 159-173    Link Here 
159
147
160
Go ahead and type the following into your shell (remember you can substitute
148
Go ahead and type the following into your shell (remember you can substitute
161
the name of your chosen release number instead of @code{ns-3-dev} -- like
149
the name of your chosen release number instead of @code{ns-3-dev} -- like
162
@code{"ns-3.6"} and @code{"ns-3.6-ref-traces"} if you want to work with a 
150
@code{"ns-3.6"} if you want to work with a 
163
stable release).
151
stable release).
164
152
165
@verbatim
153
@verbatim
166
  ./download.py -n ns-3-dev -r ns-3-dev-ref-traces
154
  ./download.py -n ns-3-dev
167
@end verbatim
155
@end verbatim
168
156
169
Note that the default for the @code{-n} option is @code{ns-3-dev} and the 
157
Note that the default for the @code{-n} option is @code{ns-3-dev} and so the
170
default for the @code{-r} option is @code{ns-3-dev-ref-traces} and so the
171
above is actually redundant.  We provide this example to illustrate how to
158
above is actually redundant.  We provide this example to illustrate how to
172
specify alternate repositories.  In order to download @code{ns-3-dev} you 
159
specify alternate repositories.  In order to download @code{ns-3-dev} you 
173
can actually use the defaults and simply type,
160
can actually use the defaults and simply type,
 Lines 195-218    Link Here 
195
@end verbatim
182
@end verbatim
196
183
197
This is output by the download script as it fetches the actual @code{ns-3}
184
This is output by the download script as it fetches the actual @code{ns-3}
198
code from the repository.  Next, you should see something like,
185
code from the repository.
199
200
@verbatim
201
      #
202
      # Get the regression traces
203
      #
204
  
205
  Synchronizing reference traces using Mercurial.
206
   =>  hg clone http://code.nsnam.org/ns-3-dev-ref-traces ns-3-dev-ref-traces
207
  requesting all changes
208
  adding changesets
209
  adding manifests
210
  adding file changes
211
  added 86 changesets with 1178 changes to 259 files
212
  208 files updated, 0 files merged, 0 files removed, 0 files unresolved
213
@end verbatim
214
186
215
This is the download script fetching the reference trace files for you.
216
The download script is smart enough to know that on some platforms various
187
The download script is smart enough to know that on some platforms various
217
pieces of ns-3 are not supported.  On your platform you may not see some
188
pieces of ns-3 are not supported.  On your platform you may not see some
218
of these pieces come down.  However, on most platforms, the process should
189
of these pieces come down.  However, on most platforms, the process should
 Lines 254-275    Link Here 
254
Cradle for you. Note that NSC is not supported on OSX or Cygwin and works 
225
Cradle for you. Note that NSC is not supported on OSX or Cygwin and works 
255
best with gcc-3.4 or gcc-4.2 or greater series.
226
best with gcc-3.4 or gcc-4.2 or greater series.
256
227
257
After the clone command completes, you should have several new directories
228
After the download.py script completes, you should have several new directories
258
under @code{~/repos/ns-3-allinone}:
229
under @code{~/repos/ns-3-allinone}:
259
230
260
@verbatim
231
@verbatim
261
  build.py*     constants.pyc  download.py*  ns-3-dev-ref-traces/  pybindgen/  util.py
232
  build.py*     constants.pyc  download.py*  nsc/        README      util.pyc
262
  constants.py  dist.py*       ns-3-dev/     nsc/                  README      util.pyc
233
  constants.py  dist.py*       ns-3-dev/     pybindgen/  util.py
263
@end verbatim
234
@end verbatim
264
235
265
Go ahead and change into @code{ns-3-dev} under your @code{~/repos/ns-3-allinone} 
236
Go ahead and change into @code{ns-3-dev} under your @code{~/repos/ns-3-allinone} 
266
directory.  You should see something like the following there:
237
directory.  You should see something like the following there:
267
238
268
@verbatim
239
@verbatim
269
  AUTHORS       examples/  regression/    scratch/  waf*
240
  AUTHORS       examples/  RELEASE_NOTES  utils/   wscript
270
  bindings/     LICENSE    regression.py  src/      waf.bat*
241
  bindings/     LICENSE    samples/       VERSION  wutils.py
271
  CHANGES.html  ns3/       RELEASE_NOTES  utils/    wscript
242
  CHANGES.html  ns3/       scratch/       waf*
272
  doc/          README     samples/       VERSION   wutils.py
243
  doc/          README     src/           waf.bat*
273
@end verbatim
244
@end verbatim
274
245
275
You are now ready to build the @command{ns-3} distribution.
246
You are now ready to build the @command{ns-3} distribution.
 Lines 299-306    Link Here 
299
number of files:
270
number of files:
300
271
301
@verbatim
272
@verbatim
302
build.py*     ns-3.6/             nsc-0.5.1/             README
273
build.py*     ns-3.6/     pybindgen-0.12.0.700/  util.py
303
constants.py  ns-3.6-ref-traces/  pybindgen-0.12.0.700/  util.py
274
constants.py  nsc-0.5.1/  README
304
@end verbatim 
275
@end verbatim 
305
276
306
You are now ready to build the @command{ns-3} distribution.
277
You are now ready to build the @command{ns-3} distribution.
 Lines 355-361    Link Here 
355
@cindex building debug version with Waf
326
@cindex building debug version with Waf
356
@cindex compiling with Waf
327
@cindex compiling with Waf
357
@cindex unit tests with Waf
328
@cindex unit tests with Waf
358
@cindex regression tests with Waf
359
We use Waf to configure and build the @command{ns-3} project.  It's not 
329
We use Waf to configure and build the @command{ns-3} project.  It's not 
360
strictly required at this point, but it will be valuable to take a slight
330
strictly required at this point, but it will be valuable to take a slight
361
detour and look at how to make changes to the configuration of the project.
331
detour and look at how to make changes to the configuration of the project.
 Lines 380-386    Link Here 
380
  Checking for program ranlib              : ok /usr/bin/ranlib
350
  Checking for program ranlib              : ok /usr/bin/ranlib
381
  Checking for g++                         : ok
351
  Checking for g++                         : ok
382
  Checking for program pkg-config          : ok /usr/bin/pkg-config
352
  Checking for program pkg-config          : ok /usr/bin/pkg-config
383
  Checking for regression reference traces  : ok ../ns-3-dev-ref-traces (guessed)
384
  Checking for -Wno-error=deprecated-declarations support : yes
353
  Checking for -Wno-error=deprecated-declarations support : yes
385
  Checking for -Wl,--soname=foo support                   : yes
354
  Checking for -Wl,--soname=foo support                   : yes
386
  Checking for header stdlib.h                            : ok
355
  Checking for header stdlib.h                            : ok
 Lines 530-603    Link Here 
530
This command is typically run by @code{users} to quickly verify that an 
499
This command is typically run by @code{users} to quickly verify that an 
531
@command{ns-3} distribution has built correctly.  
500
@command{ns-3} distribution has built correctly.  
532
501
533
@cindex regression tests
534
You can also run our regression test suite to ensure that your distribution and
535
toolchain have produced binaries that generate output that is identical to
536
known-good reference output files.  You downloaded these reference traces to 
537
your machine during the @code{./download.py} process above.  (Warning:  The 
538
@code{ns-3.2} and @code{ns-3.3} releases do not use the @code{ns-3-allinone} 
539
environment and require you to be online when you run regression tests because 
540
they dynamically synchronize the reference traces directory with an online
541
repository immediately prior to the run).
542
543
During regression testing Waf will run a number of tests that generate what we
544
call trace files.  The content of these trace files are compared with the 
545
reference traces.  If they are identical, the regression tests report a PASS 
546
status.  If a regression test fails you will see a FAIL indication along with a
547
pointer to the offending trace file and its associated reference trace file
548
along with a suggestion on diff parameters and options in order to see what 
549
has gone awry.  If the error was discovered in a pcap file, it will be useful
550
to convert the pcap files to text using tcpdump prior to comparison.
551
552
Some regression tests may be SKIPped if the required support
553
is not present.
554
555
Note that the regression tests are also run in parallel and so the messages
556
may be interleaved.
557
558
To run the regression tests, you provide Waf with the regression flag.
559
560
@verbatim
561
  ./waf --regression
562
@end verbatim
563
564
You should see messages indicating that many tests are being run and are
565
passing.
566
567
@verbatim
568
  Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
569
  [647/669] regression-test (test-csma-bridge)
570
  [648/669] regression-test (test-csma-broadcast)
571
  [649/669] regression-test (test-csma-multicast)
572
  [650/669] regression-test (test-csma-one-subnet)
573
  PASS test-csma-multicast
574
  [651/669] regression-test (test-csma-packet-socket)
575
  PASS test-csma-bridge
576
  ...
577
  Regression testing summary:
578
  PASS: 22 of 22 tests passed
579
  Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
580
  'build' finished successfully (25.826s)
581
@end verbatim
582
583
If you want to take a look at an example of what might be checked during
584
a regression test, you can do the following:
585
586
@verbatim
587
  cd build/debug/regression/traces/second.ref
588
  tcpdump -nn -tt -r second-2-0.pcap
589
@end verbatim
590
591
The output should be clear to anyone who is familiar with tcpdump or net
592
sniffers.  We'll have much more to say on pcap files later in this tutorial.
593
594
Remember to cd back into the top-level @command{ns-3} directory
595
after you are done:
596
597
@verbatim
598
  cd ../../../../..
599
@end verbatim
600
601
@c ========================================================================
502
@c ========================================================================
602
@c Running a Script
503
@c Running a Script
603
@c ========================================================================
504
@c ========================================================================
(-)ns-3-dev/regression/tests/test-csma-bridge.py (-14 lines)
 Lines 1-14    Link Here 
1
#! /usr/bin/env python
2
3
"""Generic trace-comparison-type regression test."""
4
5
import os.path
6
7
def may_run(env, options):
8
    """Returns 0 when it can run, return non-zero or string (reason) when it cannot run"""
9
    if env['ENABLE_PYTHON_BINDINGS']:
10
        return 0
11
    else:
12
        return "Python bindings not available."
13
14
pyscript = os.path.join('examples/csma', 'csma-bridge.py')
(-)ns-3-dev/regression/tests/test-csma-broadcast.py (-4 lines)
 Lines 1-4    Link Here 
1
#! /usr/bin/env python
2
3
"""Generic trace-comparison-type regression test."""
4
(-)ns-3-dev/regression/tests/test-csma-multicast.py (-3 lines)
 Lines 1-3    Link Here 
1
#! /usr/bin/env python
2
3
"""Generic trace-comparison-type regression test."""
(-)ns-3-dev/regression/tests/test-csma-one-subnet.py (-4 lines)
 Lines 1-4    Link Here 
1
#! /usr/bin/env python
2
3
"""Generic trace-comparison-type regression test."""
4
(-)ns-3-dev/regression/tests/test-csma-packet-socket.py (-4 lines)
 Lines 1-4    Link Here 
1
#! /usr/bin/env python
2
3
"""Generic trace-comparison-type regression test."""
4
(-)ns-3-dev/regression/tests/test-csma-ping.py (-4 lines)
 Lines 1-4    Link Here 
1
#! /usr/bin/env python
2
3
"""Generic trace-comparison-type regression test."""
4
(-)ns-3-dev/regression/tests/test-csma-raw-ip-socket.py (-4 lines)
 Lines 1-4    Link Here 
1
#! /usr/bin/env python
2
3
"""Generic trace-comparison-type regression test."""
4
(-)ns-3-dev/regression/tests/test-csma-star.py (-4 lines)
 Lines 1-4    Link Here 
1
#! /usr/bin/env python
2
3
"""Generic trace-comparison-type regression test."""
4
(-)ns-3-dev/regression/tests/test-dynamic-global-routing.py (-4 lines)
 Lines 1-4    Link Here 
1
#! /usr/bin/env python
2
3
"""Generic trace-comparison-type regression test."""
4
(-)ns-3-dev/regression/tests/test-global-routing-slash32.py (-4 lines)
 Lines 1-4    Link Here 
1
#! /usr/bin/env python
2
3
"""Generic trace-comparison-type regression test."""
4
(-)ns-3-dev/regression/tests/test-object-names.py (-4 lines)
 Lines 1-4    Link Here 
1
#! /usr/bin/env python
2
3
"""Generic trace-comparison-type regression test."""
4
(-)ns-3-dev/regression/tests/test-realtime-udp-echo.py (-7 lines)
 Lines 1-7    Link Here 
1
#! /usr/bin/env python
2
3
"""Generic trace-comparison-type regression test."""
4
5
def may_run(env, options):
6
    if not env["ENABLE_REAL_TIME"]:
7
        return "Real-time support not available"
(-)ns-3-dev/regression/tests/test-second.py (-6 lines)
 Lines 1-6    Link Here 
1
#! /usr/bin/env python
2
3
"""Compare that Second generates correct traces."""
4
5
arguments = ["--verbose=0"]
6
(-)ns-3-dev/regression/tests/test-simple-error-model.py (-4 lines)
 Lines 1-4    Link Here 
1
#! /usr/bin/env python
2
3
"""Generic trace-comparison-type regression test."""
4
(-)ns-3-dev/regression/tests/test-simple-global-routing.py (-4 lines)
 Lines 1-4    Link Here 
1
#! /usr/bin/env python
2
3
"""Generic trace-comparison-type regression test."""
4
(-)ns-3-dev/regression/tests/test-simple-point-to-point-olsr.py (-4 lines)
 Lines 1-4    Link Here 
1
#! /usr/bin/env python
2
3
"""Generic trace-comparison-type regression test."""
4
(-)ns-3-dev/regression/tests/test-static-routing-slash32.py (-4 lines)
 Lines 1-4    Link Here 
1
#! /usr/bin/env python
2
3
"""Generic trace-comparison-type regression test."""
4
(-)ns-3-dev/regression/tests/test-tcp-large-transfer.py (-4 lines)
 Lines 1-4    Link Here 
1
#! /usr/bin/env python
2
3
"""Generic trace-comparison-type regression test."""
4
(-)ns-3-dev/regression/tests/test-tcp-nsc-lfn.py (-30 lines)
 Lines 1-30    Link Here 
1
#! /usr/bin/env python
2
3
"""Trace-comparison-type regression test for the Network Simulation Cradle."""
4
5
import platform
6
import sys
7
8
def may_run(env, options):
9
    if not env['NSC_ENABLED']:
10
        return "NSC not available"
11
    else:
12
        if options.valgrind:
13
            return "NSC does not get along with valgrind"
14
        if sys.platform != 'linux2':
15
            return "NSC is not well supported on non-Linux platforms"
16
        return 0
17
18
19
platform_bits = platform.architecture()[0]
20
if platform_bits == "64bit":
21
    trace_dir_name = "tcp-nsc-lfn_64bit.ref"
22
elif platform_bits == "32bit":
23
    trace_dir_name = "tcp-nsc-lfn_32bit.ref"
24
else:
25
    raise AssertionError("Unknown architecture, not 64 or 32 bit?")
26
del platform_bits
27
28
arguments = ["--ns3::OnOffApplication::DataRate=40000", "--runtime=20"]
29
30
(-)ns-3-dev/regression/tests/test-third.py (-6 lines)
 Lines 1-6    Link Here 
1
#! /usr/bin/env python
2
3
"""Compare that Third generates correct traces."""
4
5
arguments = ["--verbose=0"]
6
(-)ns-3-dev/regression/tests/test-udp-echo.py (-4 lines)
 Lines 1-4    Link Here 
1
#! /usr/bin/env python
2
3
"""Generic trace-comparison-type regression test."""
4
(-)ns-3-dev/regression/tests/test-wifi-wired-bridging.py (-6 lines)
 Lines 1-6    Link Here 
1
#! /usr/bin/env python
2
3
"""Compare that Wifi-Wired Bridging generates correct traces."""
4
5
arguments = ["--SendIp=0"]
6
(-)ns-3-dev/regression/waf (-1 lines)
Line 1    Link Here 
1
exec "`dirname "$0"`"/../waf "$@"
(-)ns-3-dev/regression.py (-308 lines)
 Lines 1-308    Link Here 
1
# python lib modules
2
import os
3
import sys
4
import shutil
5
import pproc as subprocess
6
import errno
7
8
# WAF modules
9
import Options
10
import Utils
11
import Task
12
13
# local modules
14
import wutils
15
16
17
def dev_null():
18
    if sys.platform == 'win32':
19
        return open("NUL:", "w")
20
    else:
21
        return open("/dev/null", "w")
22
23
24
def _find_tests(testdir):
25
    """Return a list of test modules in the test directory
26
27
    Arguments:
28
    testdir -- the directory to look in for tests
29
    """
30
    names = os.listdir(testdir)
31
    tests = []
32
    for name in names:
33
        if name[:5] == "test-" and name[-3:] == ".py":
34
            testname = name[:-3]
35
            tests.append(testname)
36
    tests.sort()
37
    return tests
38
39
def diff(dir1, dir2, verbose):
40
    import filecmp
41
    comp = filecmp.dircmp(dir1, dir2)
42
    differ = (comp.left_only or comp.right_only or comp.diff_files)
43
44
    if differ:
45
        # ok, stupid binary comparison reports differences, but maybe
46
        # only text files differ, in which case we should compare
47
        # again while ignoring newline differences between
48
        # windows/mac/unix.
49
        if not comp.left_only and not comp.right_only:
50
            for diff_fname in comp.diff_files:
51
                if not (diff_fname.endswith(".tr") or diff_fname.endswith(".mob")):
52
                    # doesn't look like a text file; it has to differ
53
                    break
54
                diff_file1 = open(os.path.join(dir1, diff_fname), "rtU").readlines()
55
                diff_file2 = open(os.path.join(dir2, diff_fname), "rtU").readlines()
56
                if diff_file1 != diff_file2:
57
                    break
58
                #else:
59
                #    print ">>>>>>>> %s file does not really differ!" % (diff_fname)
60
            else:
61
                differ = False
62
63
    if differ:
64
        if verbose:
65
            comp.report()
66
            import difflib
67
            for diff_fname in comp.diff_files:
68
                if not (diff_fname.endswith(".tr") or diff_fname.endswith(".mob")):
69
                    print "The different file %r does not sound like a text file, not compared." % (diff_fname,)
70
                diff_file1 = open(os.path.join(dir1, diff_fname), "rt").readlines()
71
                diff_file2 = open(os.path.join(dir2, diff_fname), "rt").readlines()
72
                diff = difflib.unified_diff(diff_file1, diff_file2)
73
                count = 0
74
                print "Differences in file %r" % (diff_fname,)
75
                for line in diff:
76
                    print line
77
                    count += 1
78
                    if count > 100:
79
                        break
80
        return 1
81
    else:
82
        return 0
83
84
class regression_test_task(Task.TaskBase):
85
    after = 'cc cxx cc_link cxx_link'
86
    color = 'BLUE'
87
88
    def __init__(self, bld, env, test_name, test_scripts_dir, build_traces_dir, reference_traces):
89
        self.bld = bld
90
        self.generator = self
91
        self.env = env
92
        super(regression_test_task, self).__init__(generator=self, env=env)
93
        self.test_name = test_name
94
95
        assert self.test_name.startswith('test-')
96
        short_name = self.test_name[len('test-'):]
97
98
        self.test_scripts_dir = test_scripts_dir
99
        self.build_traces_dir = build_traces_dir
100
        self.reference_traces_dir = reference_traces
101
102
        sys.path.insert(0, self.test_scripts_dir)
103
        try:
104
            mod = __import__(self.test_name, globals(), locals(), [])
105
        finally:
106
            sys.path.remove(self.test_scripts_dir)
107
        self.mod = mod
108
        if hasattr(mod, 'may_run'):
109
            reason_cannot_run = mod.may_run(self.env, Options.options)
110
        else:
111
            reason_cannot_run = None
112
        if not reason_cannot_run:
113
            pyscript = getattr(mod, "pyscript", None)
114
            if pyscript:
115
                Options.options.compile_targets += ',ns3module,pybindgen-command'
116
            else:
117
                program = getattr(mod, "program", short_name)
118
                Options.options.compile_targets += ',' + program
119
120
    def __str__(self):
121
        return 'regression-test (%s)\n' % self.test_name
122
123
    def runnable_status(self):
124
        return Task.RUN_ME
125
126
    def run(self):
127
        """Run a single test"""
128
        assert self.test_name.startswith('test-')
129
        short_name = self.test_name[len('test-'):]
130
        mod = self.mod
131
        trace_dir_name = getattr(mod, "trace_dir_name", None)
132
        if trace_dir_name is None:
133
            trace_dir_name = "%s.ref" % short_name
134
        trace_output_path = os.path.join(self.build_traces_dir, trace_dir_name)
135
        reference_traces_path = os.path.join(self.reference_traces_dir, trace_dir_name)
136
137
        if hasattr(mod, 'get_arguments'):
138
            arguments = mod.get_arguments(self.env, '..')
139
        else:
140
            arguments = getattr(mod, "arguments", [])
141
142
        pyscript = getattr(mod, "pyscript", None)
143
        if pyscript:
144
            is_pyscript = True
145
            program = pyscript
146
        else:
147
            is_pyscript = False
148
            program = getattr(mod, "program", short_name)
149
150
        if hasattr(mod, 'may_run'):
151
            reason_cannot_run = mod.may_run(self.env, Options.options)
152
        else:
153
            reason_cannot_run = None
154
        if reason_cannot_run:
155
            print "SKIP %s (%s)" % (self.test_name, reason_cannot_run)
156
            self.result = None
157
            return 0
158
159
        if Options.options.regression_generate:
160
            # clean the target dir
161
            try:
162
                shutil.rmtree(reference_traces_path)
163
            except OSError, ex:
164
                if ex.errno not in [errno.ENOENT]:
165
                    raise
166
            os.makedirs(reference_traces_path)
167
            result = self.run_reference_generate(reference_traces_path, program, arguments, is_pyscript)
168
            if result == 0:
169
                print "GENERATE " + self.test_name
170
            else:
171
                print "GENERATE FAIL " + self.test_name
172
        else:
173
            # clean the target dir
174
            try:
175
                shutil.rmtree(trace_output_path)
176
            except OSError, ex:
177
                if ex.errno not in [errno.ENOENT]:
178
                    raise
179
            os.makedirs(trace_output_path)
180
            # run it
181
            #print "self.run_reference_test:(%r, %r, %r, %r, %r)" \
182
            #    % (reference_traces_path, trace_output_path, program, arguments, is_pyscript)
183
            result = self.run_reference_test(reference_traces_path, trace_output_path, program, arguments, is_pyscript)
184
            if result == 0:
185
                print "PASS " + self.test_name
186
            else:
187
                print "FAIL " + self.test_name
188
        self.result = result
189
        return 0
190
191
    def run_reference_test(self, reference_traces_path, trace_output_path, program, arguments, is_pyscript):
192
        if not os.path.exists(reference_traces_path):
193
            print "Cannot locate reference traces in " + reference_traces_path
194
            return 1
195
196
        if is_pyscript:
197
            script = os.path.abspath(os.path.join('..', *os.path.split(program)))
198
            argv = [self.env['PYTHON'], script] + arguments
199
            try:
200
                wutils.run_argv(argv, self.env, cwd=trace_output_path, force_no_valgrind=True)
201
            except Utils.WafError, ex:
202
                print >> sys.stderr, ex
203
                return 1
204
        else:
205
            try:
206
                wutils.run_program(program, self.env,
207
                                   command_template=wutils.get_command_template(self.env, arguments),
208
                                   cwd=trace_output_path)
209
            except Utils.WafError, ex:
210
                print >> sys.stderr, ex
211
                return 1
212
213
        rc = diff(trace_output_path, reference_traces_path, Options.options.verbose)
214
        if rc:
215
            print "----------"
216
            print "Traces differ in test: ", self.test_name
217
            print "Reference traces in directory: " + reference_traces_path
218
            print "Traces in directory: " + trace_output_path
219
            print "Run the following command for details:"
220
            print "\tdiff -u %s %s" % (reference_traces_path, trace_output_path)
221
            if not Options.options.verbose:
222
                print "Or re-run regression testing with option -v"
223
            print "----------"
224
        return rc
225
226
227
    def run_reference_generate(self, trace_output_path, program, arguments, is_pyscript):
228
        if is_pyscript:
229
            script = os.path.abspath(os.path.join('..', *os.path.split(program)))
230
            argv = [self.env['PYTHON'], script] + arguments
231
            try:
232
                retval = wutils.run_argv(argv, self.env, cwd=trace_output_path, force_no_valgrind=True)
233
            except Utils.WafError, ex:
234
                print >> sys.stderr, ex
235
                return 1
236
        else:
237
            try:
238
                retval = wutils.run_program(program, self.env,
239
                                            command_template=wutils.get_command_template(self.env, arguments),
240
                                            cwd=trace_output_path)
241
            except Utils.WafError, ex:
242
                print >> sys.stderr, ex
243
                return 1
244
        return retval
245
246
247
class regression_test_collector_task(Task.TaskBase):
248
    after = 'regression_test_task'
249
    color = 'BLUE'
250
251
    def __init__(self, bld, test_tasks):
252
        self.bld = bld
253
        super(regression_test_collector_task, self).__init__(generator=self)
254
        self.test_tasks = test_tasks
255
256
    def __str__(self):
257
        return 'regression-test-collector\n'
258
259
    def runnable_status(self):
260
        return Task.RUN_ME
261
262
    def run(self):
263
        failed_tests = [test for test in self.test_tasks if test.result is not None and test.result != 0]
264
        skipped_tests = [test for test in self.test_tasks if test.result is None]
265
        print "Regression testing summary:"
266
        if skipped_tests:
267
            print "SKIP: %i of %i tests have been skipped (%s)" % (
268
                len(skipped_tests), len(self.test_tasks),
269
                ', '.join([test.test_name for test in skipped_tests]))
270
        if failed_tests:
271
            print "FAIL: %i of %i tests have failed (%s)" % (
272
                len(failed_tests), len(self.test_tasks),
273
                ', '.join([test.test_name for test in failed_tests]))
274
            return 1
275
        else:
276
            print "PASS: %i of %i tests passed" % (len(self.test_tasks) - len(skipped_tests),
277
                                                   len(self.test_tasks))
278
            return 0
279
280
def run_regression(bld, reference_traces):
281
    """Execute regression tests.  Called with cwd set to the 'regression' subdir of ns-3.
282
283
    @param reference_traces: reference traces directory.
284
285
    """
286
287
    testdir = os.path.join("regression", "tests")
288
    if not os.path.exists(testdir):
289
        print "Tests directory does not exist"
290
        sys.exit(3)
291
292
    if Options.options.regression_tests:
293
        tests = Options.options.regression_tests.split(',')
294
    else:
295
        tests = _find_tests(testdir)
296
297
    if not os.path.exists(reference_traces):
298
        print "Reference traces directory (%s) does not exist" % reference_traces
299
        return 3
300
    
301
    test_scripts_dir = bld.path.find_dir('regression/tests').abspath()
302
    build_traces_dir = bld.path.find_or_declare('regression/traces').abspath(bld.env)
303
    tasks = []
304
    for test in tests:
305
        task = regression_test_task(bld, bld.env, test, test_scripts_dir, build_traces_dir, reference_traces)
306
        #bld.task_manager.add_task(task)
307
        tasks.append(task)
308
    regression_test_collector_task(bld, tasks)
(-)ns-3-dev/src/test/csma-system-test-suite.cc (+1126 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * This program is free software; you can redistribute it and/or modify
4
 * it under the terms of the GNU General Public License version 2 as
5
 * published by the Free Software Foundation;
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15
 */
16
17
// This is not a test of CsmaNetDevice model behavior per-se, but
18
// instead is a roll up of several end-to-end examples in examples/csma
19
// directory, converted into system tests.  Writing a test suite
20
// to test Csma itself is for further study.
21
22
#include <string>
23
24
#include "ns3/address.h"
25
#include "ns3/application-container.h"
26
#include "ns3/bridge-helper.h"
27
#include "ns3/callback.h"
28
#include "ns3/config.h"
29
#include "ns3/csma-helper.h"
30
#include "ns3/csma-star-helper.h"
31
#include "ns3/inet-socket-address.h"
32
#include "ns3/internet-stack-helper.h"
33
#include "ns3/ipv4-address-helper.h"
34
#include "ns3/ipv4-global-routing-helper.h"
35
#include "ns3/ipv4-static-routing-helper.h"
36
#include "ns3/node.h"
37
#include "ns3/node-container.h"
38
#include "ns3/on-off-helper.h"
39
#include "ns3/packet.h"
40
#include "ns3/packet-sink-helper.h"
41
#include "ns3/packet-socket-helper.h"
42
#include "ns3/packet-socket-address.h"
43
#include "ns3/pointer.h"
44
#include "ns3/random-variable.h"
45
#include "ns3/simple-channel.h"
46
#include "ns3/simulator.h"
47
#include "ns3/string.h"
48
#include "ns3/test.h"
49
#include "ns3/uinteger.h"
50
#include "ns3/v4ping-helper.h"
51
52
using namespace ns3;
53
54
class CsmaBridgeTestCase : public TestCase
55
{
56
public:
57
  CsmaBridgeTestCase ();
58
  virtual ~CsmaBridgeTestCase ();
59
60
private:
61
  virtual bool DoRun (void);
62
  void SinkRx (Ptr<const Packet> p, const Address &ad);
63
  uint32_t m_count;
64
};
65
66
// Add some help text to this case to describe what it is intended to test
67
CsmaBridgeTestCase::CsmaBridgeTestCase ()
68
  : TestCase ("Bridge example for Carrier Sense Multiple Access (CSMA) networks"), m_count (0)
69
{
70
}
71
72
CsmaBridgeTestCase::~CsmaBridgeTestCase ()
73
{
74
}
75
76
void 
77
CsmaBridgeTestCase::SinkRx (Ptr<const Packet> p, const Address &ad)
78
{
79
  m_count++;
80
}
81
82
// Network topology
83
//
84
//        n0     n1  
85
//        |      | 
86
//       ----------
87
//       | Switch |
88
//       ----------
89
//        |      | 
90
//        n2     n3  
91
//
92
// - CBR/UDP test flow from n0 to n1; test that packets received on n1 
93
//
94
bool
95
CsmaBridgeTestCase::DoRun (void)
96
{
97
  NodeContainer terminals;
98
  terminals.Create (4);
99
100
  NodeContainer csmaSwitch;
101
  csmaSwitch.Create (1);
102
103
  CsmaHelper csma;
104
  csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
105
  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
106
107
  NetDeviceContainer terminalDevices;
108
  NetDeviceContainer switchDevices;
109
110
  for (int i = 0; i < 4; i++)
111
    {
112
      NetDeviceContainer link = csma.Install (NodeContainer (terminals.Get (i), csmaSwitch));
113
      terminalDevices.Add (link.Get (0));
114
      switchDevices.Add (link.Get (1));
115
    }
116
117
  // Create the bridge netdevice, which will do the packet switching
118
  Ptr<Node> switchNode = csmaSwitch.Get (0);
119
  BridgeHelper bridge;
120
  bridge.Install (switchNode, switchDevices);
121
122
  InternetStackHelper internet;
123
  internet.Install (terminals);
124
125
  Ipv4AddressHelper ipv4;
126
  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
127
  ipv4.Assign (terminalDevices);
128
129
  uint16_t port = 9;   // Discard port (RFC 863)
130
131
  // Create the OnOff application to send UDP datagrams from n0 to n1.
132
  //
133
  // Make packets be sent about every DefaultPacketSize / DataRate = 
134
  // 4096 bits / (5000 bits/second) = 0.82 second.
135
  OnOffHelper onoff ("ns3::UdpSocketFactory", 
136
                     Address (InetSocketAddress (Ipv4Address ("10.1.1.2"), port)));
137
  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
138
  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
139
  onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000)));
140
141
  ApplicationContainer app = onoff.Install (terminals.Get (0));
142
  app.Start (Seconds (1.0));
143
  app.Stop (Seconds (10.0));
144
145
  PacketSinkHelper sink ("ns3::UdpSocketFactory",
146
                         Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
147
  app = sink.Install (terminals.Get (1));
148
  app.Start (Seconds (0.0));
149
150
  // Trace receptions
151
  Config::ConnectWithoutContext ("/NodeList/1/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback (&CsmaBridgeTestCase::SinkRx, this));
152
153
  Simulator::Run ();
154
  Simulator::Destroy ();
155
156
  // We should have sent and received 10 packets
157
  NS_TEST_ASSERT_MSG_EQ (m_count, 10, "Bridge should have passed 10 packets");
158
159
  return GetErrorStatus ();
160
}
161
162
class CsmaBroadcastTestCase : public TestCase
163
{
164
public:
165
  CsmaBroadcastTestCase ();
166
  virtual ~CsmaBroadcastTestCase ();
167
168
private:
169
  virtual bool DoRun (void);
170
  void SinkRxNode1 (Ptr<const Packet> p, const Address &ad);
171
  void SinkRxNode2 (Ptr<const Packet> p, const Address &ad);
172
  void DropEvent (Ptr<const Packet> p);
173
  uint32_t m_countNode1;
174
  uint32_t m_countNode2;
175
  uint32_t m_drops;
176
};
177
178
// Add some help text to this case to describe what it is intended to test
179
CsmaBroadcastTestCase::CsmaBroadcastTestCase ()
180
  : TestCase ("Broadcast example for Carrier Sense Multiple Access (CSMA) networks"), m_countNode1 (0), m_countNode2 (0), m_drops (0)
181
{
182
}
183
184
CsmaBroadcastTestCase::~CsmaBroadcastTestCase ()
185
{
186
}
187
188
void 
189
CsmaBroadcastTestCase::SinkRxNode1 (Ptr<const Packet> p, const Address &ad)
190
{
191
  m_countNode1++;
192
}
193
194
void 
195
CsmaBroadcastTestCase::SinkRxNode2 (Ptr<const Packet> p, const Address &ad)
196
{
197
  m_countNode2++;
198
}
199
200
void 
201
CsmaBroadcastTestCase::DropEvent (Ptr<const Packet> p)
202
{
203
  m_drops++;
204
}
205
206
//
207
// Example of the sending of a datagram to a broadcast address
208
//
209
// Network topology
210
//     ==============
211
//       |          |
212
//       n0    n1   n2   
213
//       |     |       
214
//     ==========
215
//
216
//   n0 originates UDP broadcast to 255.255.255.255/discard port, which 
217
//   is replicated and received on both n1 and n2
218
//
219
bool
220
CsmaBroadcastTestCase::DoRun (void)
221
{
222
  NodeContainer c;
223
  c.Create (3);
224
  NodeContainer c0 = NodeContainer (c.Get (0), c.Get (1));
225
  NodeContainer c1 = NodeContainer (c.Get (0), c.Get (2));
226
227
  CsmaHelper csma;
228
  csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate(5000000)));
229
  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds(2)));
230
231
  NetDeviceContainer n0 = csma.Install (c0);
232
  NetDeviceContainer n1 = csma.Install (c1);
233
234
  InternetStackHelper internet;
235
  internet.Install (c);
236
237
  Ipv4AddressHelper ipv4;
238
  ipv4.SetBase ("10.1.0.0", "255.255.255.0");
239
  ipv4.Assign (n0);
240
  ipv4.SetBase ("192.168.1.0", "255.255.255.0");
241
  ipv4.Assign (n1);
242
243
244
  // RFC 863 discard port ("9") indicates packet should be thrown away
245
  // by the system.  We allow this silent discard to be overridden
246
  // by the PacketSink application.
247
  uint16_t port = 9;
248
249
  // Create the OnOff application to send UDP datagrams from n0.
250
  //
251
  // Make packets be sent about every DefaultPacketSize / DataRate = 
252
  // 4096 bits / (5000 bits/second) = 0.82 second.
253
  OnOffHelper onoff ("ns3::UdpSocketFactory", 
254
    Address (InetSocketAddress (Ipv4Address ("255.255.255.255"), port)));
255
  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
256
  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
257
  onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000)));
258
259
  ApplicationContainer app = onoff.Install (c0.Get (0));
260
  // Start the application
261
  app.Start (Seconds (1.0));
262
  app.Stop (Seconds (10.0));
263
264
  // Create an optional packet sink to receive these packets
265
  PacketSinkHelper sink ("ns3::UdpSocketFactory",
266
    Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
267
  app = sink.Install (c0.Get (1));
268
  app.Add (sink.Install (c1.Get (1)));
269
  app.Start (Seconds (1.0));
270
  app.Stop (Seconds (10.0));
271
272
  // Trace receptions
273
  Config::ConnectWithoutContext ("/NodeList/1/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback (&CsmaBroadcastTestCase::SinkRxNode1, this));
274
  Config::ConnectWithoutContext ("/NodeList/2/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback (&CsmaBroadcastTestCase::SinkRxNode2, this));
275
276
  Simulator::Run ();    
277
  Simulator::Destroy ();
278
279
  // We should have sent and received 10 packets
280
  NS_TEST_ASSERT_MSG_EQ (m_countNode1, 10, "Node 1 should have received 10 packets");
281
  NS_TEST_ASSERT_MSG_EQ (m_countNode2, 10, "Node 2 should have received 10 packets");
282
283
  return GetErrorStatus ();
284
}
285
286
class CsmaMulticastTestCase : public TestCase
287
{
288
public:
289
  CsmaMulticastTestCase ();
290
  virtual ~CsmaMulticastTestCase ();
291
292
private:
293
  virtual bool DoRun (void);
294
  void SinkRx (Ptr<const Packet> p, const Address &ad);
295
  void DropEvent (Ptr<const Packet> p);
296
  uint32_t m_count;
297
  uint32_t m_drops;
298
};
299
300
// Add some help text to this case to describe what it is intended to test
301
CsmaMulticastTestCase::CsmaMulticastTestCase ()
302
  : TestCase ("Multicast example for Carrier Sense Multiple Access (CSMA) networks"), m_count (0), m_drops (0)
303
{
304
}
305
306
CsmaMulticastTestCase::~CsmaMulticastTestCase ()
307
{
308
}
309
310
void 
311
CsmaMulticastTestCase::SinkRx (Ptr<const Packet> p, const Address& ad)
312
{
313
  m_count++;
314
}
315
316
void 
317
CsmaMulticastTestCase::DropEvent (Ptr<const Packet> p)
318
{
319
  m_drops++;
320
}
321
322
// Network topology
323
//
324
//                     Lan1
325
//                 ===========
326
//                 |    |    | 
327
//       n0   n1   n2   n3   n4
328
//       |    |    |
329
//       ===========
330
//           Lan0
331
//
332
// - Multicast source is at node n0;
333
// - Multicast forwarded by node n2 onto LAN1;
334
// - Nodes n0, n1, n2, n3, and n4 receive the multicast frame.
335
// - Node n4 listens for the data 
336
//
337
bool
338
CsmaMulticastTestCase::DoRun (void)
339
{
340
  //
341
  // Set up default values for the simulation.  
342
  //
343
  // Select DIX/Ethernet II-style encapsulation (no LLC/Snap header)
344
  Config::SetDefault ("ns3::CsmaNetDevice::EncapsulationMode", StringValue ("Dix"));  
345
346
  NodeContainer c;
347
  c.Create (5);
348
  // We will later want two subcontainers of these nodes, for the two LANs
349
  NodeContainer c0 = NodeContainer (c.Get (0), c.Get (1), c.Get (2));
350
  NodeContainer c1 = NodeContainer (c.Get (2), c.Get (3), c.Get (4));
351
  
352
  CsmaHelper csma;
353
  csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000)));
354
  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
355
 
356
  // We will use these NetDevice containers later, for IP addressing
357
  NetDeviceContainer nd0 = csma.Install (c0);  // First LAN
358
  NetDeviceContainer nd1 = csma.Install (c1);  // Second LAN
359
360
  InternetStackHelper internet;
361
  internet.Install (c);
362
363
  Ipv4AddressHelper ipv4Addr;
364
  ipv4Addr.SetBase ("10.1.1.0", "255.255.255.0");
365
  ipv4Addr.Assign (nd0);
366
  ipv4Addr.SetBase ("10.1.2.0", "255.255.255.0");
367
  ipv4Addr.Assign (nd1);
368
369
  //
370
  // Now we can configure multicasting.  As described above, the multicast 
371
  // source is at node zero, which we assigned the IP address of 10.1.1.1 
372
  // earlier.  We need to define a multicast group to send packets to.  This
373
  // can be any multicast address from 224.0.0.0 through 239.255.255.255
374
  // (avoiding the reserved routing protocol addresses).  
375
  //
376
377
  Ipv4Address multicastSource ("10.1.1.1");
378
  Ipv4Address multicastGroup ("225.1.2.4");
379
380
  // Now, we will set up multicast routing.  We need to do three things:
381
  // 1) Configure a (static) multicast route on node n2
382
  // 2) Set up a default multicast route on the sender n0 
383
  // 3) Have node n4 join the multicast group
384
  // We have a helper that can help us with static multicast
385
  Ipv4StaticRoutingHelper multicast;
386
387
  // 1) Configure a (static) multicast route on node n2 (multicastRouter)
388
  Ptr<Node> multicastRouter = c.Get (2);  // The node in question
389
  Ptr<NetDevice> inputIf = nd0.Get (2);  // The input NetDevice
390
  NetDeviceContainer outputDevices;  // A container of output NetDevices
391
  outputDevices.Add (nd1.Get (0));  // (we only need one NetDevice here)
392
393
  multicast.AddMulticastRoute (multicastRouter, multicastSource, 
394
    multicastGroup, inputIf, outputDevices);
395
  
396
  // 2) Set up a default multicast route on the sender n0 
397
  Ptr<Node> sender = c.Get (0);
398
  Ptr<NetDevice> senderIf = nd0.Get(0);
399
  multicast.SetDefaultMulticastRoute (sender, senderIf);
400
401
  //
402
  // Create an OnOff application to send UDP datagrams from node zero to the
403
  // multicast group (node four will be listening).
404
  //
405
406
  uint16_t multicastPort = 9;   // Discard port (RFC 863)
407
408
  // Configure a multicast packet generator.
409
  //
410
  // Make packets be sent about every defaultPacketSize / dataRate = 
411
  // 4096 bits / (5000 bits/second) = 0.82 second.
412
  OnOffHelper onoff ("ns3::UdpSocketFactory", 
413
    Address (InetSocketAddress (multicastGroup, multicastPort)));
414
  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
415
  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
416
  onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000)));
417
418
  ApplicationContainer srcC = onoff.Install (c0.Get (0));
419
420
  //
421
  // Tell the application when to start and stop.
422
  //
423
  srcC.Start(Seconds(1.));
424
  srcC.Stop (Seconds(10.));
425
426
  // Create an optional packet sink to receive these packets
427
  PacketSinkHelper sink ("ns3::UdpSocketFactory",
428
                         InetSocketAddress (Ipv4Address::GetAny(), multicastPort));
429
430
  ApplicationContainer sinkC = sink.Install (c1.Get (2)); // Node n4 
431
  // Start the sink
432
  sinkC.Start (Seconds (1.0));
433
  sinkC.Stop (Seconds (10.0));
434
435
  // Trace receptions
436
  Config::ConnectWithoutContext ("/NodeList/4/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback (&CsmaMulticastTestCase::SinkRx, this));
437
438
  //
439
  // Now, do the actual simulation.
440
  //
441
  Simulator::Run ();
442
  Simulator::Destroy ();
443
444
  // We should have sent and received 10 packets
445
  NS_TEST_ASSERT_MSG_EQ (m_count, 10, "Node 4 should have received 10 packets");
446
447
  return GetErrorStatus ();
448
}
449
450
class CsmaOneSubnetTestCase : public TestCase
451
{
452
public:
453
  CsmaOneSubnetTestCase ();
454
  virtual ~CsmaOneSubnetTestCase ();
455
456
private:
457
  virtual bool DoRun (void);
458
  void SinkRxNode0 (Ptr<const Packet> p, const Address &ad);
459
  void SinkRxNode1 (Ptr<const Packet> p, const Address &ad);
460
  void DropEvent (Ptr<const Packet> p);
461
  uint32_t m_countNode0;
462
  uint32_t m_countNode1;
463
  uint32_t m_drops;
464
};
465
466
// Add some help text to this case to describe what it is intended to test
467
CsmaOneSubnetTestCase::CsmaOneSubnetTestCase ()
468
  : TestCase ("One subnet example for Carrier Sense Multiple Access (CSMA) networks"), m_countNode0 (0), m_countNode1 (0), m_drops (0)
469
{
470
}
471
472
CsmaOneSubnetTestCase::~CsmaOneSubnetTestCase ()
473
{
474
}
475
476
void 
477
CsmaOneSubnetTestCase::SinkRxNode0 (Ptr<const Packet> p, const Address &ad)
478
{
479
  m_countNode0++;
480
}
481
482
void 
483
CsmaOneSubnetTestCase::SinkRxNode1 (Ptr<const Packet> p, const Address &ad)
484
{
485
  m_countNode1++;
486
}
487
488
void 
489
CsmaOneSubnetTestCase::DropEvent (Ptr<const Packet> p)
490
{
491
  m_drops++;
492
}
493
494
// Network topology
495
//
496
//       n0    n1   n2   n3
497
//       |     |    |    |
498
//       =================
499
//              LAN
500
//
501
// - CBR/UDP flows from n0 to n1 and from n3 to n0
502
// - DropTail queues 
503
//
504
bool
505
CsmaOneSubnetTestCase::DoRun (void)
506
{
507
  NodeContainer nodes;
508
  nodes.Create (4);
509
510
  CsmaHelper csma;
511
  csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
512
  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
513
  //
514
  // Now fill out the topology by creating the net devices required to connect
515
  // the nodes to the channels and hooking them up.
516
  //
517
  NetDeviceContainer devices = csma.Install (nodes);
518
519
  InternetStackHelper internet;
520
  internet.Install (nodes);
521
522
  // We've got the "hardware" in place.  Now we need to add IP addresses.
523
  //
524
  Ipv4AddressHelper ipv4;
525
  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
526
  Ipv4InterfaceContainer interfaces = ipv4.Assign (devices);
527
528
  uint16_t port = 9;   // Discard port (RFC 863)
529
530
  //
531
  // Create an OnOff application to send UDP datagrams from node zero
532
  // to node 1.
533
  //
534
  // Make packets be sent about every defaultPacketSize / dataRate = 
535
  // 4096 bits / (5000 bits/second) = 0.82 second.
536
  OnOffHelper onoff ("ns3::UdpSocketFactory", 
537
                     Address (InetSocketAddress (interfaces.GetAddress (1), port)));
538
  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
539
  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
540
  onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000)));
541
542
  ApplicationContainer app = onoff.Install (nodes.Get (0));
543
  // Start the application
544
  app.Start (Seconds (1.0));
545
  app.Stop (Seconds (10.0));
546
547
  // Create an optional packet sink to receive these packets
548
  PacketSinkHelper sink ("ns3::UdpSocketFactory",
549
    Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
550
  app = sink.Install (nodes.Get (1));
551
  app.Start (Seconds (0.0));
552
553
  // 
554
  // Create a similar flow from n3 to n0, starting at time 1.1 seconds
555
  //
556
  onoff.SetAttribute ("Remote", 
557
                      AddressValue (InetSocketAddress (interfaces.GetAddress (0), port)));
558
  app = onoff.Install (nodes.Get (3));
559
  app.Start(Seconds (1.1));
560
  app.Stop (Seconds (10.0));
561
562
  app = sink.Install (nodes.Get (0));
563
  app.Start (Seconds (0.0));
564
565
  // Trace receptions
566
  Config::ConnectWithoutContext ("/NodeList/0/ApplicationList/1/$ns3::PacketSink/Rx", MakeCallback (&CsmaOneSubnetTestCase::SinkRxNode0, this));
567
  Config::ConnectWithoutContext ("/NodeList/1/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback (&CsmaOneSubnetTestCase::SinkRxNode1, this));
568
569
  //
570
  // Now, do the actual simulation.
571
  //
572
  Simulator::Run ();
573
  Simulator::Destroy ();
574
575
  // We should have sent and received 10 packets
576
  NS_TEST_ASSERT_MSG_EQ (m_countNode0, 10, "Node 0 should have received 10 packets");
577
  NS_TEST_ASSERT_MSG_EQ (m_countNode1, 10, "Node 1 should have received 10 packets");
578
579
  return GetErrorStatus ();
580
}
581
582
class CsmaPacketSocketTestCase : public TestCase
583
{
584
public:
585
  CsmaPacketSocketTestCase ();
586
  virtual ~CsmaPacketSocketTestCase ();
587
588
private:
589
  virtual bool DoRun (void);
590
  void SinkRx (std::string path, Ptr<const Packet> p, const Address &address);
591
  void DropEvent (Ptr<const Packet> p);
592
  uint32_t m_count;
593
  uint32_t m_drops;
594
};
595
596
// Add some help text to this case to describe what it is intended to test
597
CsmaPacketSocketTestCase::CsmaPacketSocketTestCase ()
598
  : TestCase ("Packet socket example for Carrier Sense Multiple Access (CSMA) networks"), m_count (0), m_drops (0)
599
{
600
}
601
602
CsmaPacketSocketTestCase::~CsmaPacketSocketTestCase ()
603
{
604
}
605
606
void 
607
CsmaPacketSocketTestCase::SinkRx (std::string path, Ptr<const Packet> p, const Address& address)
608
{
609
  m_count++;
610
}
611
612
void 
613
CsmaPacketSocketTestCase::DropEvent (Ptr<const Packet> p)
614
{
615
  m_drops++;
616
}
617
618
//
619
// Network topology
620
//
621
//       n0    n1   n2   n3
622
//       |     |    |    |
623
//     =====================
624
//
625
// - Packet socket flow from n0 to n1 and from node n3 to n0
626
// -- We will test reception at node n0
627
// - Default 512 byte packets generated by traffic generator
628
//
629
bool
630
CsmaPacketSocketTestCase::DoRun (void)
631
{
632
  // Here, we will explicitly create four nodes.
633
  NodeContainer nodes;
634
  nodes.Create (4);
635
636
  PacketSocketHelper packetSocket;
637
  packetSocket.Install (nodes);
638
639
  // create the shared medium used by all csma devices.
640
  Ptr<CsmaChannel> channel = CreateObjectWithAttributes<CsmaChannel> (
641
    "DataRate", DataRateValue (DataRate(5000000)), 
642
    "Delay", TimeValue (MilliSeconds(2)));
643
644
  // use a helper function to connect our nodes to the shared channel.
645
  CsmaHelper csma;
646
  csma.SetDeviceAttribute ("EncapsulationMode", StringValue ("Llc"));
647
  NetDeviceContainer devs = csma.Install (nodes, channel);
648
649
  // Create the OnOff application to send raw datagrams
650
  //
651
  // Make packets be sent about every DefaultPacketSize / DataRate = 
652
  // 4096 bits / (5000 bits/second) = 0.82 second.
653
  PacketSocketAddress socket;
654
  socket.SetSingleDevice(devs.Get (0)->GetIfIndex ());
655
  socket.SetPhysicalAddress (devs.Get (1)->GetAddress ());
656
  socket.SetProtocol (2);
657
  OnOffHelper onoff ("ns3::PacketSocketFactory", Address (socket));
658
  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1.0)));
659
  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0.0)));
660
  onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000)));
661
  ApplicationContainer apps = onoff.Install (nodes.Get (0));
662
  apps.Start (Seconds (1.0));
663
  apps.Stop (Seconds (10.0));
664
665
  socket.SetSingleDevice (devs.Get (3)->GetIfIndex ());
666
  socket.SetPhysicalAddress (devs.Get (0)->GetAddress ());
667
  socket.SetProtocol (3);
668
  onoff.SetAttribute ("Remote", AddressValue (socket));
669
  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0.0)));
670
  apps = onoff.Install (nodes.Get (3));
671
  apps.Start (Seconds (1.0));
672
  apps.Stop (Seconds (10.0));
673
674
  PacketSinkHelper sink = PacketSinkHelper ("ns3::PacketSocketFactory",
675
                                            socket);
676
  apps = sink.Install (nodes.Get (0));
677
  apps.Start (Seconds (0.0));
678
  apps.Stop (Seconds (20.0));
679
680
  // Trace receptions
681
  Config::Connect ("/NodeList/0/ApplicationList/*/$ns3::PacketSink/Rx",
682
                   MakeCallback (&CsmaPacketSocketTestCase::SinkRx, this));
683
 
684
  Simulator::Run ();
685
  Simulator::Destroy ();
686
687
  // We should have received 10 packets on node 0
688
  NS_TEST_ASSERT_MSG_EQ (m_count, 10, "Node 0 should have received 10 packets");
689
690
  return GetErrorStatus ();
691
}
692
693
class CsmaPingTestCase : public TestCase
694
{
695
public:
696
  CsmaPingTestCase ();
697
  virtual ~CsmaPingTestCase ();
698
699
private:
700
  virtual bool DoRun (void);
701
  void SinkRx (Ptr<const Packet> p, const Address &ad);
702
  void PingRtt (std::string context, Time rtt);
703
  void DropEvent (Ptr<const Packet> p);
704
  uint32_t m_countSinkRx;
705
  uint32_t m_countPingRtt;
706
  uint32_t m_drops;
707
};
708
709
// Add some help text to this case to describe what it is intended to test
710
CsmaPingTestCase::CsmaPingTestCase ()
711
  : TestCase ("Ping example for Carrier Sense Multiple Access (CSMA) networks"), m_countSinkRx (0), m_countPingRtt (0), m_drops (0)
712
{
713
}
714
715
CsmaPingTestCase::~CsmaPingTestCase ()
716
{
717
}
718
719
void 
720
CsmaPingTestCase::SinkRx (Ptr<const Packet> p, const Address &ad)
721
{
722
  m_countSinkRx++;
723
}
724
725
void 
726
CsmaPingTestCase::PingRtt (std::string context, Time rtt)
727
{
728
  m_countPingRtt++;
729
}
730
731
void 
732
CsmaPingTestCase::DropEvent (Ptr<const Packet> p)
733
{
734
  m_drops++;
735
}
736
737
// Network topology
738
//
739
//       n0    n1   n2   n3
740
//       |     |    |    |
741
//     =====================
742
//
743
//  node n0,n1,n3 pings to node n2
744
//  node n0 generates protocol 2 (IGMP) to node n3
745
//
746
bool
747
CsmaPingTestCase::DoRun (void)
748
{
749
  // Here, we will explicitly create four nodes.
750
  NodeContainer c;
751
  c.Create (4);
752
753
  // connect all our nodes to a shared channel.
754
  CsmaHelper csma;
755
  csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000)));
756
  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
757
  csma.SetDeviceAttribute ("EncapsulationMode", StringValue ("Llc"));
758
  NetDeviceContainer devs = csma.Install (c);
759
760
  // add an ip stack to all nodes.
761
  InternetStackHelper ipStack;
762
  ipStack.Install (c);
763
764
  // assign ip addresses
765
  Ipv4AddressHelper ip;
766
  ip.SetBase ("192.168.1.0", "255.255.255.0");
767
  Ipv4InterfaceContainer addresses = ip.Assign (devs);
768
769
  // Create the OnOff application to send UDP datagrams from n0 to n1.
770
  //
771
  // Make packets be sent about every DefaultPacketSize / DataRate = 
772
  // 4096 bits / (5000 bits/second) = 0.82 second.
773
  Config::SetDefault ("ns3::Ipv4RawSocketImpl::Protocol", StringValue ("2"));
774
  InetSocketAddress dst = InetSocketAddress (addresses.GetAddress (3));
775
  OnOffHelper onoff = OnOffHelper ("ns3::Ipv4RawSocketFactory", dst);
776
  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1.0)));
777
  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0.0)));
778
  onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000)));
779
780
  ApplicationContainer apps = onoff.Install (c.Get (0));
781
  apps.Start (Seconds (1.0));
782
  apps.Stop (Seconds (10.0));
783
784
  PacketSinkHelper sink = PacketSinkHelper ("ns3::Ipv4RawSocketFactory", dst);
785
  apps = sink.Install (c.Get (3));
786
  apps.Start (Seconds (0.0));
787
  apps.Stop (Seconds (11.0));
788
789
  V4PingHelper ping = V4PingHelper (addresses.GetAddress (2));
790
  NodeContainer pingers;
791
  pingers.Add (c.Get (0));
792
  pingers.Add (c.Get (1));
793
  pingers.Add (c.Get (3));
794
  apps = ping.Install (pingers);
795
  apps.Start (Seconds (2.0));
796
  apps.Stop (Seconds (5.0));
797
798
  // Trace receptions
799
  Config::ConnectWithoutContext ("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx", 
800
                                 MakeCallback (&CsmaPingTestCase::SinkRx, this));
801
802
  // Trace pings
803
  Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::V4Ping/Rtt",
804
                   MakeCallback (&CsmaPingTestCase::PingRtt, this));
805
806
  Simulator::Run ();
807
  Simulator::Destroy ();
808
809
  // We should have sent and received 10 packets
810
  NS_TEST_ASSERT_MSG_EQ (m_countSinkRx, 10, "Node 3 should have received 10 packets");
811
812
  // We should have 3 pingers that ping every second for 3 seconds.
813
  NS_TEST_ASSERT_MSG_EQ (m_countPingRtt, 9, "Node 2 should have been pinged 9 times");
814
815
  return GetErrorStatus ();
816
}
817
818
class CsmaRawIpSocketTestCase : public TestCase
819
{
820
public:
821
  CsmaRawIpSocketTestCase ();
822
  virtual ~CsmaRawIpSocketTestCase ();
823
824
private:
825
  virtual bool DoRun (void);
826
  void SinkRx (Ptr<const Packet> p, const Address &ad);
827
  void DropEvent (Ptr<const Packet> p);
828
  uint32_t m_count;
829
  uint32_t m_drops;
830
};
831
832
// Add some help text to this case to describe what it is intended to test
833
CsmaRawIpSocketTestCase::CsmaRawIpSocketTestCase ()
834
  : TestCase ("Raw internet protocol socket example for Carrier Sense Multiple Access (CSMA) networks"), m_count (0), m_drops (0)
835
{
836
}
837
838
CsmaRawIpSocketTestCase::~CsmaRawIpSocketTestCase ()
839
{
840
}
841
842
void 
843
CsmaRawIpSocketTestCase::SinkRx (Ptr<const Packet> p, const Address &ad)
844
{
845
  m_count++;
846
}
847
848
void 
849
CsmaRawIpSocketTestCase::DropEvent (Ptr<const Packet> p)
850
{
851
  m_drops++;
852
}
853
854
//
855
// Network topology
856
//    (sender)         (receiver)
857
//       n0    n1   n2   n3
858
//       |     |    |    |
859
//     =====================
860
//
861
// Node n0 sends data to node n3 over a raw IP socket.  The protocol
862
// number used is 2.
863
//
864
bool
865
CsmaRawIpSocketTestCase::DoRun (void)
866
{
867
  // Here, we will explicitly create four nodes.
868
  NodeContainer c;
869
  c.Create (4);
870
871
  // connect all our nodes to a shared channel.
872
  CsmaHelper csma;
873
  csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000)));
874
  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
875
  csma.SetDeviceAttribute ("EncapsulationMode", StringValue ("Llc"));
876
  NetDeviceContainer devs = csma.Install (c);
877
878
  // add an ip stack to all nodes.
879
  InternetStackHelper ipStack;
880
  ipStack.Install (c);
881
882
  // assign ip addresses
883
  Ipv4AddressHelper ip;
884
  ip.SetBase ("192.168.1.0", "255.255.255.0");
885
  Ipv4InterfaceContainer addresses = ip.Assign (devs);
886
887
  // IP protocol configuration
888
  //
889
  // Make packets be sent about every DefaultPacketSize / DataRate = 
890
  // 4096 bits / (5000 bits/second) = 0.82 second.
891
  Config::SetDefault ("ns3::Ipv4RawSocketImpl::Protocol", StringValue ("2"));
892
  InetSocketAddress dst = InetSocketAddress (addresses.GetAddress (3));
893
  OnOffHelper onoff = OnOffHelper ("ns3::Ipv4RawSocketFactory", dst);
894
  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1.0)));
895
  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0.0)));
896
  onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000)));
897
898
  ApplicationContainer apps = onoff.Install (c.Get (0));
899
  apps.Start (Seconds (1.0));
900
  apps.Stop (Seconds (10.0));
901
902
  PacketSinkHelper sink = PacketSinkHelper ("ns3::Ipv4RawSocketFactory", dst);
903
  apps = sink.Install (c.Get (3));
904
  apps.Start (Seconds (0.0));
905
  apps.Stop (Seconds (12.0));
906
907
  // Trace receptions
908
  Config::ConnectWithoutContext ("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx", 
909
                                 MakeCallback (&CsmaRawIpSocketTestCase::SinkRx, this));
910
911
  Simulator::Run ();
912
  Simulator::Destroy ();
913
914
  // We should have sent and received 10 packets
915
  NS_TEST_ASSERT_MSG_EQ (m_count, 10, "Node 3 should have received 10 packets");
916
917
  return GetErrorStatus ();
918
}
919
920
class CsmaStarTestCase : public TestCase
921
{
922
public:
923
  CsmaStarTestCase ();
924
  virtual ~CsmaStarTestCase ();
925
926
private:
927
  virtual bool DoRun (void);
928
  void SinkRx (Ptr<const Packet> p, const Address &ad);
929
  void DropEvent (Ptr<const Packet> p);
930
  uint32_t m_count;
931
  uint32_t m_drops;
932
};
933
934
// Add some help text to this case to describe what it is intended to test
935
CsmaStarTestCase::CsmaStarTestCase ()
936
  : TestCase ("Star example for Carrier Sense Multiple Access (CSMA) networks"), m_count (0), m_drops (0)
937
{
938
}
939
940
CsmaStarTestCase::~CsmaStarTestCase ()
941
{
942
}
943
944
void 
945
CsmaStarTestCase::SinkRx (Ptr<const Packet> p, const Address& ad)
946
{
947
  m_count++;
948
}
949
950
void 
951
CsmaStarTestCase::DropEvent (Ptr<const Packet> p)
952
{
953
  m_drops++;
954
}
955
956
// Network topology (default)
957
//
958
//            n2     +          +     n3          .
959
//             | ... |\        /| ... |           .
960
//             ======= \      / =======           .
961
//              CSMA    \    /   CSMA             .
962
//                       \  /                     .
963
//            n1     +--- n0 ---+     n4          .
964
//             | ... |   /  \   | ... |           .
965
//             =======  /    \  =======           .
966
//              CSMA   /      \  CSMA             .
967
//                    /        \                  .
968
//            n6     +          +     n5          .
969
//             | ... |          | ... |           .
970
//             =======          =======           .
971
//              CSMA             CSMA             .
972
//
973
bool
974
CsmaStarTestCase::DoRun (void)
975
{
976
  //
977
  // Default number of nodes in the star.
978
  //
979
  uint32_t nSpokes = 7;
980
981
  CsmaHelper csma;
982
  csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
983
  csma.SetChannelAttribute ("Delay", StringValue ("1ms"));
984
  CsmaStarHelper star (nSpokes, csma);
985
986
  NodeContainer fillNodes;
987
988
  //
989
  // Just to be nasy, hang some more nodes off of the CSMA channel for each
990
  // spoke, so that there are a total of 16 nodes on each channel.  Stash
991
  // all of these new devices into a container.
992
  //
993
  NetDeviceContainer fillDevices;
994
995
  uint32_t nFill = 14;
996
  for (uint32_t i = 0; i < star.GetSpokeDevices ().GetN (); ++i)
997
    {
998
      Ptr<Channel> channel = star.GetSpokeDevices ().Get (i)->GetChannel ();
999
      Ptr<CsmaChannel> csmaChannel = channel->GetObject<CsmaChannel> ();
1000
      NodeContainer newNodes;
1001
      newNodes.Create (nFill);
1002
      fillNodes.Add (newNodes);
1003
      fillDevices.Add (csma.Install (newNodes, csmaChannel));
1004
    }
1005
1006
  InternetStackHelper internet;
1007
  star.InstallStack (internet);
1008
  internet.Install (fillNodes);
1009
1010
  star.AssignIpv4Addresses (Ipv4AddressHelper ("10.1.0.0", "255.255.255.0"));
1011
1012
  //
1013
  // We assigned addresses to the logical hub and the first "drop" of the 
1014
  // CSMA network that acts as the spoke, but we also have a number of fill
1015
  // devices (nFill) also hanging off the CSMA network.  We have got to 
1016
  // assign addresses to them as well.  We put all of the fill devices into
1017
  // a single device container, so the first nFill devices are associated
1018
  // with the channel connected to spokeDevices.Get (0), the second nFill
1019
  // devices afe associated with the channel connected to spokeDevices.Get (1)
1020
  // etc.
1021
  //
1022
  Ipv4AddressHelper address;
1023
  for(uint32_t i = 0; i < star.SpokeCount (); ++i)
1024
  {
1025
    std::ostringstream subnet;
1026
    subnet << "10.1." << i << ".0";
1027
      address.SetBase (subnet.str ().c_str (), "255.255.255.0", "0.0.0.3");
1028
1029
    for (uint32_t j = 0; j < nFill; ++j)
1030
      {
1031
        address.Assign (fillDevices.Get (i * nFill + j));
1032
      }
1033
  }
1034
1035
  //
1036
  // Create a packet sink on the star "hub" to receive packets.  
1037
  // 
1038
  uint16_t port = 50000;
1039
  Address hubLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
1040
  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", hubLocalAddress);
1041
  ApplicationContainer hubApp = packetSinkHelper.Install (star.GetHub ());
1042
  hubApp.Start (Seconds (1.0));
1043
  hubApp.Stop (Seconds (10.0));
1044
1045
  //
1046
  // Create OnOff applications to send TCP to the hub, one on each spoke node.
1047
  //
1048
  // Make packets be sent about every DefaultPacketSize / DataRate = 
1049
  // 4096 bits / (5000 bits/second) = 0.82 second.
1050
  OnOffHelper onOffHelper ("ns3::TcpSocketFactory", Address ());
1051
  onOffHelper.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
1052
  onOffHelper.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
1053
  onOffHelper.SetAttribute ("DataRate", DataRateValue (DataRate (5000)));
1054
1055
  ApplicationContainer spokeApps;
1056
1057
  for (uint32_t i = 0; i < star.SpokeCount (); ++i)
1058
    {
1059
      AddressValue remoteAddress (InetSocketAddress (star.GetHubIpv4Address (i), port));
1060
      onOffHelper.SetAttribute ("Remote", remoteAddress);
1061
      spokeApps.Add (onOffHelper.Install (star.GetSpokeNode (i)));
1062
    }
1063
1064
  spokeApps.Start (Seconds (1.0));
1065
  spokeApps.Stop (Seconds (10.0));
1066
1067
  //
1068
  // Because we are evil, we also add OnOff applications to send TCP to the hub 
1069
  // from the fill devices on each CSMA link.  The first nFill nodes in the 
1070
  // fillNodes container are on the CSMA network talking to the zeroth device
1071
  // on the hub node.  The next nFill nodes are on the CSMA network talking to
1072
  // the first device on the hub node, etc.  So the ith fillNode is associated
1073
  // with the hub address found on the (i / nFill)th device on the hub node.
1074
  //
1075
  ApplicationContainer fillApps;
1076
1077
  for (uint32_t i = 0; i < fillNodes.GetN (); ++i)
1078
    {
1079
      AddressValue remoteAddress (InetSocketAddress (star.GetHubIpv4Address (i / nFill), port));
1080
      onOffHelper.SetAttribute ("Remote", remoteAddress);
1081
      fillApps.Add (onOffHelper.Install (fillNodes.Get (i)));
1082
    }
1083
1084
  fillApps.Start (Seconds (1.0));
1085
  fillApps.Stop (Seconds (10.0));
1086
1087
  //
1088
  // Turn on global static routing so we can actually be routed across the star.
1089
  //
1090
  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
1091
1092
  // Trace receptions
1093
  Config::ConnectWithoutContext ("/NodeList/0/ApplicationList/*/$ns3::PacketSink/Rx", 
1094
                                 MakeCallback (&CsmaStarTestCase::SinkRx, this));
1095
1096
  Simulator::Run ();
1097
  Simulator::Destroy ();
1098
1099
  // The hub node should have received 10 packets from the nFill + 1
1100
  // nodes on each spoke.
1101
  NS_TEST_ASSERT_MSG_EQ (m_count, 10 * ( nSpokes * (nFill + 1)), "Hub node did not receive the proper number of packets");
1102
1103
  return GetErrorStatus ();
1104
}
1105
1106
class CsmaSystemTestSuite : public TestSuite
1107
{
1108
public:
1109
  CsmaSystemTestSuite ();
1110
};
1111
1112
CsmaSystemTestSuite::CsmaSystemTestSuite ()
1113
  : TestSuite ("csma-system", BVT)
1114
{
1115
  AddTestCase (new CsmaBridgeTestCase);
1116
  AddTestCase (new CsmaBroadcastTestCase);
1117
  AddTestCase (new CsmaMulticastTestCase);
1118
  AddTestCase (new CsmaOneSubnetTestCase);
1119
  AddTestCase (new CsmaPacketSocketTestCase);
1120
  AddTestCase (new CsmaPingTestCase);
1121
  AddTestCase (new CsmaRawIpSocketTestCase);
1122
  AddTestCase (new CsmaStarTestCase);
1123
}
1124
1125
// Do not forget to allocate an instance of this TestSuite
1126
static CsmaSystemTestSuite csmaSystemTestSuite;
(-)ns-3-dev/src/test/global-routing-test-suite.cc (+409 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * This program is free software; you can redistribute it and/or modify
4
 * it under the terms of the GNU General Public License version 2 as
5
 * published by the Free Software Foundation;
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15
 */
16
17
#include "ns3/boolean.h"
18
#include "ns3/config.h"
19
#include "ns3/csma-helper.h"
20
#include "ns3/flow-monitor.h"
21
#include "ns3/flow-monitor-helper.h"
22
#include "ns3/inet-socket-address.h"
23
#include "ns3/internet-stack-helper.h"
24
#include "ns3/ipv4-address-helper.h"
25
#include "ns3/ipv4-global-routing-helper.h"
26
#include "ns3/ipv4-static-routing-helper.h"
27
#include "ns3/node.h"
28
#include "ns3/node-container.h"
29
#include "ns3/on-off-helper.h"
30
#include "ns3/packet.h"
31
#include "ns3/packet-sink-helper.h"
32
#include "ns3/packet-sink.h"
33
#include "ns3/packet-socket-helper.h"
34
#include "ns3/packet-socket-address.h"
35
#include "ns3/csma-net-device.h"
36
#include "ns3/point-to-point-helper.h"
37
#include "ns3/pointer.h"
38
#include "ns3/random-variable.h"
39
#include "ns3/simple-channel.h"
40
#include "ns3/simulator.h"
41
#include "ns3/string.h"
42
#include "ns3/test.h"
43
#include "ns3/uinteger.h"
44
#include "ns3/ipv4-packet-info-tag.h"
45
46
using namespace ns3;
47
48
class DynamicGlobalRoutingTestCase : public TestCase
49
{
50
public:
51
  DynamicGlobalRoutingTestCase ();
52
  virtual ~DynamicGlobalRoutingTestCase ();
53
54
private:
55
  void SinkRx (std::string path, Ptr<const Packet> p, const Address &address);
56
  void HandleRead (Ptr<Socket>);
57
  virtual bool DoRun (void);
58
  int m_count;
59
  uint8_t m_firstInterface[16];
60
  uint8_t m_secondInterface[16];
61
};
62
63
// Add some help text to this case to describe what it is intended to test
64
DynamicGlobalRoutingTestCase::DynamicGlobalRoutingTestCase ()
65
  : TestCase ("Dynamic global routing example"), m_count (0)
66
{
67
}
68
69
DynamicGlobalRoutingTestCase::~DynamicGlobalRoutingTestCase ()
70
{
71
}
72
73
void
74
DynamicGlobalRoutingTestCase::SinkRx (std::string path, Ptr<const Packet> p, const Address& address)
75
{
76
  Ipv4PacketInfoTag tag;
77
  bool found;
78
  found = p->PeekPacketTag (tag);
79
  uint8_t now = static_cast<uint8_t> (Simulator::Now ().GetSeconds ());
80
  if (found)
81
    {
82
      ;
83
    }
84
  m_firstInterface[now]++;
85
  m_count++;
86
}
87
88
void 
89
DynamicGlobalRoutingTestCase::HandleRead (Ptr<Socket> socket)
90
{
91
  Ptr<Packet> packet;
92
  Address from;
93
  while (packet = socket->RecvFrom (from))
94
    {
95
      if (packet->GetSize() == 0)
96
        { //EOF
97
          break;
98
        }
99
      Ipv4PacketInfoTag tag;
100
      bool found;
101
      found = packet->PeekPacketTag (tag);
102
      uint8_t now = static_cast<uint8_t> (Simulator::Now ().GetSeconds ());
103
      if (found)
104
        {
105
          if (tag.GetRecvIf () == 1)
106
            {
107
              m_firstInterface[now]++;
108
            }
109
          if (tag.GetRecvIf () == 2)
110
            {
111
              m_secondInterface[now]++;
112
            }
113
          m_count++;
114
        }
115
    }
116
}
117
118
// Test derived from examples/routing/dynamic-global-routing.cc
119
//
120
// Network topology
121
//
122
//  n0
123
//     \ p-p
124
//      \          (shared csma/cd)
125
//       n2 -------------------------n3
126
//      /            |        | 
127
//     / p-p        n4        n5 ---------- n6
128
//   n1                             p-p
129
//   |                                      |
130
//   ----------------------------------------
131
//                p-p
132
//
133
// Test that for node n6, the interface facing n5 receives packets at
134
// times (1-2), (4-6), (8-10), (11-12), (14-16) and the interface
135
// facing n1 receives packets at times (2-4), (6-8), (12-13)
136
//
137
bool
138
DynamicGlobalRoutingTestCase::DoRun (void)
139
{
140
  // The below value configures the default behavior of global routing.
141
  // By default, it is disabled.  To respond to interface events, set to true
142
  Config::SetDefault ("ns3::Ipv4GlobalRouting::RespondToInterfaceEvents", BooleanValue (true));
143
144
  NodeContainer c;
145
  c.Create (7);
146
  NodeContainer n0n2 = NodeContainer (c.Get (0), c.Get (2));
147
  NodeContainer n1n2 = NodeContainer (c.Get (1), c.Get (2));
148
  NodeContainer n5n6 = NodeContainer (c.Get (5), c.Get (6));
149
  NodeContainer n1n6 = NodeContainer (c.Get (1), c.Get (6));
150
  NodeContainer n2345 = NodeContainer (c.Get (2), c.Get (3), c.Get (4), c.Get (5));
151
152
  InternetStackHelper internet;
153
  internet.Install (c);
154
155
  // We create the channels first without any IP addressing information
156
  PointToPointHelper p2p;
157
  p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
158
  p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
159
  NetDeviceContainer d0d2 = p2p.Install (n0n2);
160
  NetDeviceContainer d1d6 = p2p.Install (n1n6);
161
162
  NetDeviceContainer d1d2 = p2p.Install (n1n2);
163
164
  p2p.SetDeviceAttribute ("DataRate", StringValue ("1500kbps"));
165
  p2p.SetChannelAttribute ("Delay", StringValue ("10ms"));
166
  NetDeviceContainer d5d6 = p2p.Install (n5n6);
167
168
  // We create the channels first without any IP addressing information
169
  CsmaHelper csma;
170
  csma.SetChannelAttribute ("DataRate", StringValue ("5Mbps"));
171
  csma.SetChannelAttribute ("Delay", StringValue ("2ms"));
172
  NetDeviceContainer d2345 = csma.Install (n2345);
173
  
174
  // Later, we add IP addresses.  
175
  Ipv4AddressHelper ipv4;
176
  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
177
  ipv4.Assign (d0d2);
178
179
  ipv4.SetBase ("10.1.2.0", "255.255.255.0");
180
  ipv4.Assign (d1d2);
181
182
  ipv4.SetBase ("10.1.3.0", "255.255.255.0");
183
  Ipv4InterfaceContainer i5i6 = ipv4.Assign (d5d6);
184
185
  ipv4.SetBase ("10.250.1.0", "255.255.255.0");
186
  ipv4.Assign (d2345);
187
188
  ipv4.SetBase ("172.16.1.0", "255.255.255.0");
189
  Ipv4InterfaceContainer i1i6 = ipv4.Assign (d1d6);
190
191
  // Create router nodes, initialize routing database and set up the routing
192
  // tables in the nodes.
193
  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
194
195
  // Create the OnOff application to send UDP datagrams of size
196
  // 210 bytes at a rate of 448 Kb/s
197
  uint16_t port = 9;   // Discard port (RFC 863)
198
  OnOffHelper onoff ("ns3::UdpSocketFactory",
199
                     InetSocketAddress (i5i6.GetAddress (1), port));
200
  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
201
  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
202
  onoff.SetAttribute ("DataRate", StringValue ("2kbps"));
203
  onoff.SetAttribute ("PacketSize", UintegerValue (50));
204
205
  ApplicationContainer apps = onoff.Install (c.Get (1));
206
  apps.Start (Seconds (1.0));
207
  apps.Stop (Seconds (10.0));
208
209
  // Create a second OnOff application to send UDP datagrams of size
210
  // 210 bytes at a rate of 448 Kb/s
211
  OnOffHelper onoff2 ("ns3::UdpSocketFactory",
212
                     InetSocketAddress (i1i6.GetAddress (1), port));
213
  onoff2.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
214
  onoff2.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
215
  onoff2.SetAttribute ("DataRate", StringValue ("2kbps"));
216
  onoff2.SetAttribute ("PacketSize", UintegerValue (50));
217
218
  ApplicationContainer apps2 = onoff2.Install (c.Get (1));
219
  apps2.Start (Seconds (11.0));
220
  apps2.Stop (Seconds (16.0));
221
222
  // Create an optional packet sink to receive these packets
223
  TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
224
  Ptr<Socket> sink2 = Socket::CreateSocket (c.Get (6), tid);
225
  sink2->Bind (Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
226
  sink2->Listen ();
227
  sink2->ShutdownSend ();
228
229
  sink2->SetRecvPktInfo (true);
230
  sink2->SetRecvCallback (MakeCallback(&DynamicGlobalRoutingTestCase::HandleRead, this));
231
232
  Ptr<Node> n1 = c.Get (1);
233
  Ptr<Ipv4> ipv41 = n1->GetObject<Ipv4> ();
234
  // The first ifIndex is 0 for loopback, then the first p2p is numbered 1,
235
  // then the next p2p is numbered 2
236
  uint32_t ipv4ifIndex1 = 2;
237
238
  // Trace receptions
239
  Config::Connect ("/NodeList/6/ApplicationList/*/$ns3::PacketSink/Rx",
240
                   MakeCallback (&DynamicGlobalRoutingTestCase::SinkRx, this));
241
242
  Simulator::Schedule (Seconds (2),&Ipv4::SetDown,ipv41, ipv4ifIndex1);
243
  Simulator::Schedule (Seconds (4),&Ipv4::SetUp,ipv41, ipv4ifIndex1);
244
245
  Ptr<Node> n6 = c.Get (6);
246
  Ptr<Ipv4> ipv46 = n6->GetObject<Ipv4> ();
247
  // The first ifIndex is 0 for loopback, then the first p2p is numbered 1,
248
  // then the next p2p is numbered 2
249
  uint32_t ipv4ifIndex6 = 2;
250
  Simulator::Schedule (Seconds (6),&Ipv4::SetDown,ipv46, ipv4ifIndex6);
251
  Simulator::Schedule (Seconds (8),&Ipv4::SetUp,ipv46, ipv4ifIndex6);
252
253
  Simulator::Schedule (Seconds (12),&Ipv4::SetDown,ipv41, ipv4ifIndex1);
254
  Simulator::Schedule (Seconds (14),&Ipv4::SetUp,ipv41, ipv4ifIndex1);
255
256
  Simulator::Run ();
257
258
  NS_TEST_ASSERT_MSG_EQ (m_count, 68, "Dynamic global routing did not deliver all packets");
259
// Test that for node n6, the interface facing n5 receives packets at
260
// times (1-2), (4-6), (8-10), (11-12), (14-16) and the interface
261
// facing n1 receives packets at times (2-4), (6-8), (12-13)
262
  NS_TEST_ASSERT_MSG_EQ (m_firstInterface[1], 4, "Dynamic global routing did not deliver all packets");
263
  NS_TEST_ASSERT_MSG_EQ (m_secondInterface[2], 5, "Dynamic global routing did not deliver all packets");
264
  NS_TEST_ASSERT_MSG_EQ (m_secondInterface[3], 5, "Dynamic global routing did not deliver all packets");
265
  NS_TEST_ASSERT_MSG_EQ (m_firstInterface[4], 5, "Dynamic global routing did not deliver all packets");
266
  NS_TEST_ASSERT_MSG_EQ (m_firstInterface[5], 5, "Dynamic global routing did not deliver all packets");
267
  NS_TEST_ASSERT_MSG_EQ (m_secondInterface[6], 5, "Dynamic global routing did not deliver all packets");
268
  NS_TEST_ASSERT_MSG_EQ (m_secondInterface[7], 5, "Dynamic global routing did not deliver all packets");
269
  NS_TEST_ASSERT_MSG_EQ (m_firstInterface[8], 5, "Dynamic global routing did not deliver all packets");
270
  NS_TEST_ASSERT_MSG_EQ (m_firstInterface[9], 5, "Dynamic global routing did not deliver all packets");
271
  NS_TEST_ASSERT_MSG_EQ (m_firstInterface[10], 0, "Dynamic global routing did not deliver all packets");
272
  NS_TEST_ASSERT_MSG_EQ (m_firstInterface[11], 4, "Dynamic global routing did not deliver all packets");
273
  NS_TEST_ASSERT_MSG_EQ (m_secondInterface[12], 5, "Dynamic global routing did not deliver all packets");
274
  NS_TEST_ASSERT_MSG_EQ (m_secondInterface[13], 5, "Dynamic global routing did not deliver all packets");
275
  NS_TEST_ASSERT_MSG_EQ (m_firstInterface[14], 5, "Dynamic global routing did not deliver all packets");
276
  NS_TEST_ASSERT_MSG_EQ (m_firstInterface[15], 5, "Dynamic global routing did not deliver all packets");
277
  Simulator::Destroy ();
278
279
  return GetErrorStatus ();
280
}
281
282
class GlobalRoutingSlash32TestCase : public TestCase
283
{
284
public:
285
  GlobalRoutingSlash32TestCase ();
286
  virtual ~GlobalRoutingSlash32TestCase ();
287
288
private:
289
  virtual bool DoRun (void);
290
};
291
292
// Add some help text to this case to describe what it is intended to test
293
GlobalRoutingSlash32TestCase::GlobalRoutingSlash32TestCase ()
294
  : TestCase ("Slash 32 global routing example")
295
{
296
}
297
298
GlobalRoutingSlash32TestCase::~GlobalRoutingSlash32TestCase ()
299
{
300
}
301
302
// Test program for this 3-router scenario, using global routing
303
//
304
// (a.a.a.a/32)A<--x.x.x.0/30-->B<--y.y.y.0/30-->C(c.c.c.c/32)
305
//
306
bool
307
GlobalRoutingSlash32TestCase::DoRun (void)
308
{
309
  Ptr<Node> nA = CreateObject<Node> ();
310
  Ptr<Node> nB = CreateObject<Node> ();
311
  Ptr<Node> nC = CreateObject<Node> ();
312
313
  NodeContainer c = NodeContainer (nA, nB, nC);
314
315
  InternetStackHelper internet;
316
  internet.Install (c);
317
318
  // Point-to-point links
319
  NodeContainer nAnB = NodeContainer (nA, nB);
320
  NodeContainer nBnC = NodeContainer (nB, nC);
321
322
  // We create the channels first without any IP addressing information
323
  PointToPointHelper p2p;
324
  p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
325
  p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
326
  NetDeviceContainer dAdB = p2p.Install (nAnB);
327
328
  NetDeviceContainer dBdC = p2p.Install (nBnC);;
329
330
  Ptr<CsmaNetDevice> deviceA = CreateObject<CsmaNetDevice> ();
331
  deviceA->SetAddress (Mac48Address::Allocate ());
332
  nA->AddDevice (deviceA);
333
334
  Ptr<CsmaNetDevice> deviceC = CreateObject<CsmaNetDevice> ();
335
  deviceC->SetAddress (Mac48Address::Allocate ());
336
  nC->AddDevice (deviceC);
337
338
  // Later, we add IP addresses.  
339
  Ipv4AddressHelper ipv4;
340
  ipv4.SetBase ("10.1.1.0", "255.255.255.252");
341
  Ipv4InterfaceContainer iAiB = ipv4.Assign (dAdB);
342
343
  ipv4.SetBase ("10.1.1.4", "255.255.255.252");
344
  Ipv4InterfaceContainer iBiC = ipv4.Assign (dBdC);
345
346
  Ptr<Ipv4> ipv4A = nA->GetObject<Ipv4> ();
347
  Ptr<Ipv4> ipv4C = nC->GetObject<Ipv4> ();
348
349
  int32_t ifIndexA = ipv4A->AddInterface (deviceA);
350
  int32_t ifIndexC = ipv4C->AddInterface (deviceC);
351
352
  Ipv4InterfaceAddress ifInAddrA = Ipv4InterfaceAddress (Ipv4Address ("172.16.1.1"), Ipv4Mask ("255.255.255.255"));
353
  ipv4A->AddAddress (ifIndexA, ifInAddrA);
354
  ipv4A->SetMetric (ifIndexA, 1);
355
  ipv4A->SetUp (ifIndexA);
356
357
  Ipv4InterfaceAddress ifInAddrC = Ipv4InterfaceAddress (Ipv4Address ("192.168.1.1"), Ipv4Mask ("255.255.255.255"));
358
  ipv4C->AddAddress (ifIndexC, ifInAddrC);
359
  ipv4C->SetMetric (ifIndexC, 1);
360
  ipv4C->SetUp (ifIndexC);
361
362
  // Create router nodes, initialize routing database and set up the routing
363
  // tables in the nodes.
364
  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
365
366
  // Create the OnOff application to send UDP datagrams of size
367
  // 210 bytes at a rate of 448 Kb/s
368
  uint16_t port = 9;   // Discard port (RFC 863)
369
  OnOffHelper onoff ("ns3::UdpSocketFactory",
370
    Address (InetSocketAddress (ifInAddrC.GetLocal(), port)));
371
  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
372
  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
373
  onoff.SetAttribute ("DataRate", DataRateValue (DataRate (6000)));
374
  ApplicationContainer apps = onoff.Install (nA);
375
  apps.Start (Seconds (1.0));
376
  apps.Stop (Seconds (10.0));
377
378
  // Create a packet sink to receive these packets
379
  PacketSinkHelper sink ("ns3::UdpSocketFactory",
380
    Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
381
  apps = sink.Install (nC);
382
  apps.Start (Seconds (1.0));
383
  apps.Stop (Seconds (10.0));
384
385
  Simulator::Run ();
386
  // Check that we received 13 * 512 = 6656 bytes
387
  Ptr<PacketSink> sinkPtr = DynamicCast <PacketSink> (apps.Get (0));
388
  NS_TEST_ASSERT_MSG_EQ (sinkPtr->GetTotalRx (), 6656, "Static routing with /32 did not deliver all packets");
389
  Simulator::Destroy ();
390
391
  return GetErrorStatus ();
392
}
393
394
395
class GlobalRoutingTestSuite : public TestSuite
396
{
397
public:
398
  GlobalRoutingTestSuite ();
399
};
400
401
GlobalRoutingTestSuite::GlobalRoutingTestSuite ()
402
  : TestSuite ("global-routing", BVT)
403
{
404
  AddTestCase (new DynamicGlobalRoutingTestCase);
405
  AddTestCase (new GlobalRoutingSlash32TestCase);
406
}
407
408
// Do not forget to allocate an instance of this TestSuite
409
static GlobalRoutingTestSuite globalRoutingTestSuite;
(-)ns-3-dev/src/test/static-routing-test-suite.cc (+175 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * This program is free software; you can redistribute it and/or modify
4
 * it under the terms of the GNU General Public License version 2 as
5
 * published by the Free Software Foundation;
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15
 */
16
17
// End-to-end tests for Ipv4 static routing
18
19
#include "ns3/boolean.h"
20
#include "ns3/config.h"
21
#include "ns3/csma-helper.h"
22
#include "ns3/csma-net-device.h"
23
#include "ns3/inet-socket-address.h"
24
#include "ns3/internet-stack-helper.h"
25
#include "ns3/ipv4-address-helper.h"
26
#include "ns3/ipv4-static-routing-helper.h"
27
#include "ns3/node.h"
28
#include "ns3/node-container.h"
29
#include "ns3/on-off-helper.h"
30
#include "ns3/packet.h"
31
#include "ns3/packet-sink-helper.h"
32
#include "ns3/packet-sink.h"
33
#include "ns3/packet-socket-helper.h"
34
#include "ns3/packet-socket-address.h"
35
#include "ns3/point-to-point-helper.h"
36
#include "ns3/pointer.h"
37
#include "ns3/random-variable.h"
38
#include "ns3/simulator.h"
39
#include "ns3/string.h"
40
#include "ns3/test.h"
41
#include "ns3/uinteger.h"
42
43
using namespace ns3;
44
45
class StaticRoutingSlash32TestCase : public TestCase
46
{
47
public:
48
  StaticRoutingSlash32TestCase ();
49
  virtual ~StaticRoutingSlash32TestCase ();
50
51
private:
52
  virtual bool DoRun (void);
53
};
54
55
// Add some help text to this case to describe what it is intended to test
56
StaticRoutingSlash32TestCase::StaticRoutingSlash32TestCase ()
57
  : TestCase ("Slash 32 static routing example")
58
{
59
}
60
61
StaticRoutingSlash32TestCase::~StaticRoutingSlash32TestCase ()
62
{
63
}
64
65
// Test program for this 3-router scenario, using static routing
66
//
67
// (a.a.a.a/32)A<--x.x.x.0/30-->B<--y.y.y.0/30-->C(c.c.c.c/32)
68
//
69
bool
70
StaticRoutingSlash32TestCase::DoRun (void)
71
{
72
  Ptr<Node> nA = CreateObject<Node> ();
73
  Ptr<Node> nB = CreateObject<Node> ();
74
  Ptr<Node> nC = CreateObject<Node> ();
75
76
  NodeContainer c = NodeContainer (nA, nB, nC);
77
78
  InternetStackHelper internet;
79
  internet.Install (c);
80
81
  // Point-to-point links
82
  NodeContainer nAnB = NodeContainer (nA, nB);
83
  NodeContainer nBnC = NodeContainer (nB, nC);
84
85
  // We create the channels first without any IP addressing information
86
  PointToPointHelper p2p;
87
  p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
88
  p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
89
  NetDeviceContainer dAdB = p2p.Install (nAnB);
90
91
  NetDeviceContainer dBdC = p2p.Install (nBnC);;
92
  
93
  Ptr<CsmaNetDevice> deviceA = CreateObject<CsmaNetDevice> ();
94
  deviceA->SetAddress (Mac48Address::Allocate ());
95
  nA->AddDevice (deviceA);
96
97
  Ptr<CsmaNetDevice> deviceC = CreateObject<CsmaNetDevice> ();
98
  deviceC->SetAddress (Mac48Address::Allocate ());
99
  nC->AddDevice (deviceC);
100
101
  // Later, we add IP addresses.  
102
  Ipv4AddressHelper ipv4;
103
  ipv4.SetBase ("10.1.1.0", "255.255.255.252");
104
  Ipv4InterfaceContainer iAiB = ipv4.Assign (dAdB);
105
106
  ipv4.SetBase ("10.1.1.4", "255.255.255.252");
107
  Ipv4InterfaceContainer iBiC = ipv4.Assign (dBdC);
108
109
  Ptr<Ipv4> ipv4A = nA->GetObject<Ipv4> ();
110
  Ptr<Ipv4> ipv4B = nB->GetObject<Ipv4> ();
111
  Ptr<Ipv4> ipv4C = nC->GetObject<Ipv4> ();
112
  
113
  int32_t ifIndexA = ipv4A->AddInterface (deviceA);
114
  int32_t ifIndexC = ipv4C->AddInterface (deviceC);
115
    
116
  Ipv4InterfaceAddress ifInAddrA = Ipv4InterfaceAddress (Ipv4Address ("172.16.1.1"), Ipv4Mask ("/32"));
117
  ipv4A->AddAddress (ifIndexA, ifInAddrA);
118
  ipv4A->SetMetric (ifIndexA, 1);
119
  ipv4A->SetUp (ifIndexA);
120
121
  Ipv4InterfaceAddress ifInAddrC = Ipv4InterfaceAddress (Ipv4Address ("192.168.1.1"), Ipv4Mask ("/32"));
122
  ipv4C->AddAddress (ifIndexC, ifInAddrC);
123
  ipv4C->SetMetric (ifIndexC, 1);
124
  ipv4C->SetUp (ifIndexC);
125
 
126
  Ipv4StaticRoutingHelper ipv4RoutingHelper;
127
  // Create static routes from A to C
128
  Ptr<Ipv4StaticRouting> staticRoutingA = ipv4RoutingHelper.GetStaticRouting (ipv4A);
129
  // The ifIndex for this outbound route is 1; the first p2p link added
130
  staticRoutingA->AddHostRouteTo (Ipv4Address ("192.168.1.1"), Ipv4Address ("10.1.1.2"), 1);
131
  Ptr<Ipv4StaticRouting> staticRoutingB = ipv4RoutingHelper.GetStaticRouting (ipv4B);
132
  // The ifIndex we want on node B is 2; 0 corresponds to loopback, and 1 to the first point to point link
133
  staticRoutingB->AddHostRouteTo (Ipv4Address ("192.168.1.1"), Ipv4Address ("10.1.1.6"), 2);
134
  // Create the OnOff application to send UDP datagrams of size
135
  // 210 bytes at a rate of 448 Kb/s
136
  uint16_t port = 9;   // Discard port (RFC 863)
137
  OnOffHelper onoff ("ns3::UdpSocketFactory", 
138
    Address (InetSocketAddress (ifInAddrC.GetLocal (), port)));
139
  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
140
  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
141
  onoff.SetAttribute ("DataRate", DataRateValue (DataRate (6000)));
142
  ApplicationContainer apps = onoff.Install (nA);
143
  apps.Start (Seconds (1.0));
144
  apps.Stop (Seconds (10.0));
145
146
  // Create a packet sink to receive these packets
147
  PacketSinkHelper sink ("ns3::UdpSocketFactory",
148
    Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
149
  apps = sink.Install (nC);
150
  apps.Start (Seconds (1.0));
151
  apps.Stop (Seconds (10.0));
152
153
  Simulator::Run ();
154
  // Check that we received 13 * 512 = 6656 bytes
155
  Ptr<PacketSink> sinkPtr = DynamicCast <PacketSink> (apps.Get (0));
156
  NS_TEST_ASSERT_MSG_EQ (sinkPtr->GetTotalRx (), 6656, "Static routing with /32 did not deliver all packets");
157
  Simulator::Destroy ();
158
159
  return GetErrorStatus ();
160
}
161
162
class StaticRoutingTestSuite : public TestSuite
163
{
164
public:
165
  StaticRoutingTestSuite ();
166
};
167
168
StaticRoutingTestSuite::StaticRoutingTestSuite ()
169
  : TestSuite ("static-routing", BVT)
170
{
171
  AddTestCase (new StaticRoutingSlash32TestCase);
172
}
173
174
// Do not forget to allocate an instance of this TestSuite
175
static StaticRoutingTestSuite staticRoutingTestSuite;
(-)ns-3-dev/src/test/wscript (+3 lines)
 Lines 6-12    Link Here 
6
def build(bld):
6
def build(bld):
7
    test = bld.create_ns3_module('test', ['core'])
7
    test = bld.create_ns3_module('test', ['core'])
8
    test.source = [
8
    test.source = [
9
        'csma-system-test-suite.cc',
10
        'global-routing-test-suite.cc',
9
        'sample-test-suite.cc',
11
        'sample-test-suite.cc',
12
        'static-routing-test-suite.cc',
10
        'error-model-test-suite.cc',
13
        'error-model-test-suite.cc',
11
        'mobility-test-suite.cc',
14
        'mobility-test-suite.cc',
12
        ]
15
        ]
(-)ns-3-dev/wscript (-69 lines)
 Lines 43-49    Link Here 
43
43
44
# local modules
44
# local modules
45
import wutils
45
import wutils
46
import regression
47
46
48
Configure.autoconfig = 1
47
Configure.autoconfig = 1
49
48
 Lines 54-67    Link Here 
54
wutils.VERSION = VERSION
53
wutils.VERSION = VERSION
55
wutils.APPNAME = APPNAME
54
wutils.APPNAME = APPNAME
56
55
57
#
58
# The last part of the path name to use to find the regression traces.  The
59
# path will be APPNAME + '-' + VERSION + REGRESSION_SUFFIX, e.g.,
60
# ns-3-dev-ref-traces
61
#
62
REGRESSION_SUFFIX = "-ref-traces"
63
64
65
# these variables are mandatory ('/' are converted automatically)
56
# these variables are mandatory ('/' are converted automatically)
66
srcdir = '.'
57
srcdir = '.'
67
blddir = 'build'
58
blddir = 'build'
 Lines 97-118    Link Here 
97
    shutil.rmtree("doc/latex", True)
88
    shutil.rmtree("doc/latex", True)
98
    shutil.rmtree("nsc", True)
89
    shutil.rmtree("nsc", True)
99
90
100
    ## build the name of the traces subdirectory.  Will be something like
101
    ## ns-3-dev-ref-traces
102
    traces_name = APPNAME + '-' + VERSION + REGRESSION_SUFFIX
103
    ## Create a tar.bz2 file with the traces
104
    env = load_env()
105
    regression_dir = env['REGRESSION_TRACES']
106
    if not os.path.isdir(regression_dir):
107
        Logs.warn("Not creating traces archive: the %s directory does not exist" % regression_dir)
108
    else:
109
        traceball = traces_name + wutils.TRACEBALL_SUFFIX
110
        tar = tarfile.open(os.path.join("..", traceball), 'w:bz2')
111
        files = get_files(regression_dir)
112
        for fullfilename,relfilename in files:
113
            tar.add(fullfilename,arcname=relfilename)
114
        tar.close()
115
116
def set_options(opt):
91
def set_options(opt):
117
    # options provided by the modules
92
    # options provided by the modules
118
    opt.tool_options('compiler_cc')
93
    opt.tool_options('compiler_cc')
 Lines 177-199    Link Here 
177
    opt.add_option('--disable-examples',
152
    opt.add_option('--disable-examples',
178
                   help=('Do not build the ns-3 examples and samples.'),
153
                   help=('Do not build the ns-3 examples and samples.'),
179
                   dest='enable_examples', action='store_false')
154
                   dest='enable_examples', action='store_false')
180
    opt.add_option('--regression',
181
                   help=("Enable regression testing; only used for the 'check' target"),
182
                   default=False, dest='regression', action="store_true")
183
    opt.add_option('--check',
155
    opt.add_option('--check',
184
                   help=('DEPRECATED (run ./test.py)'),
156
                   help=('DEPRECATED (run ./test.py)'),
185
                   default=False, dest='check', action="store_true")
157
                   default=False, dest='check', action="store_true")
186
    opt.add_option('--regression-generate',
187
                   help=("Generate new regression test traces."),
188
                   default=False, dest='regression_generate', action="store_true")
189
    opt.add_option('--regression-tests',
190
                   help=('For regression testing, only run/generate the indicated regression tests, '
191
                         'specified as a comma separated list of test names'),
192
                   dest='regression_tests', type="string")
193
    opt.add_option('--with-regression-traces',
194
                   help=('Path to the regression reference traces directory'),
195
                   default=None,
196
                   dest='regression_traces', type="string")
197
    opt.add_option('--enable-static',
158
    opt.add_option('--enable-static',
198
                   help=('Compile NS-3 statically: works only on linux, without python'),
159
                   help=('Compile NS-3 statically: works only on linux, without python'),
199
                   dest='enable_static', action='store_true',
160
                   dest='enable_static', action='store_true',
 Lines 258-277    Link Here 
258
        pass
219
        pass
259
    conf.check_tool('command', ['waf-tools'])
220
    conf.check_tool('command', ['waf-tools'])
260
221
261
    # Check for the location of regression reference traces
262
    if Options.options.regression_traces is not None:
263
        if os.path.isdir(Options.options.regression_traces):
264
            conf.check_message("regression traces location", '', True, ("%s (given)" % Options.options.regression_traces))
265
            conf.env['REGRESSION_TRACES'] = os.path.abspath(Options.options.regression_traces)
266
    else:
267
        traces = os.path.join('..', "%s-%s%s" % (APPNAME, VERSION, REGRESSION_SUFFIX))
268
        if os.path.isdir(traces):
269
            conf.check_message("regression reference traces", '', True, ("%s (guessed)" % traces))
270
            conf.env['REGRESSION_TRACES'] = os.path.abspath(traces)
271
        del traces
272
    if not conf.env['REGRESSION_TRACES']:
273
        conf.check_message("regression reference traces", '', False)
274
275
    # create the second environment, set the variant and set its name
222
    # create the second environment, set the variant and set its name
276
    variant_env = conf.env.copy()
223
    variant_env = conf.env.copy()
277
    variant_name = Options.options.build_profile
224
    variant_name = Options.options.build_profile
 Lines 373-381    Link Here 
373
    conf.report_optional_feature("ENABLE_EXAMPLES", "Build examples and samples", env['ENABLE_EXAMPLES'], 
320
    conf.report_optional_feature("ENABLE_EXAMPLES", "Build examples and samples", env['ENABLE_EXAMPLES'], 
374
                                 why_not_examples)
321
                                 why_not_examples)
375
322
376
    # we cannot pull regression traces without mercurial
377
    conf.find_program('hg', var='MERCURIAL')
378
379
    conf.find_program('valgrind', var='VALGRIND')
323
    conf.find_program('valgrind', var='VALGRIND')
380
324
381
    env['ENABLE_STATIC_NS3'] = False
325
    env['ENABLE_STATIC_NS3'] = False
 Lines 645-663    Link Here 
645
            if type(gen).__name__ in ['ns3header_taskgen', 'ns3moduleheader_taskgen']:
589
            if type(gen).__name__ in ['ns3header_taskgen', 'ns3moduleheader_taskgen']:
646
                gen.post()
590
                gen.post()
647
591
648
    if Options.options.regression or Options.options.regression_generate:
649
        regression_traces = env['REGRESSION_TRACES']
650
        if not regression_traces:
651
            raise Utils.WafError("Cannot run regression tests: reference traces directory not given"
652
                                 " (--with-regression-traces configure option)")
653
654
        if env['ENABLE_EXAMPLES'] == True:
655
            regression.run_regression(bld, regression_traces)
656
        else:
657
            raise Utils.WafError("Cannot run regression tests: building the ns-3 examples is not enabled"
658
                                 " (regression tests are based on examples)")
659
660
661
    if Options.options.doxygen_no_build:
592
    if Options.options.doxygen_no_build:
662
        _doxygen(bld)
593
        _doxygen(bld)
663
        raise SystemExit(0)
594
        raise SystemExit(0)
(-)ns-3-dev/wutils.py (-7 lines)
 Lines 19-31    Link Here 
19
VERSION=None
19
VERSION=None
20
bld=None
20
bld=None
21
21
22
#
23
# The last part of the path name to use to find the regression traces tarball.
24
# path will be APPNAME + '-' + VERSION + REGRESSION_SUFFIX + TRACEBALL_SUFFIX,
25
# e.g., ns-3-dev-ref-traces.tar.bz2
26
#
27
TRACEBALL_SUFFIX = ".tar.bz2"
28
29
22
30
23
31
def get_command_template(env, arguments=()):
24
def get_command_template(env, arguments=()):

Return to bug 791