- 1 Mercurial repository layout for developers
- 2 The WAF build system
- 3 Generating new python bindings
- 4 Submitting patches for consideration
- 5 Checking in code
- 6 Using gcov and lcov code coverage tools
- 7 The preferred way to create a private repository
- 8 Testing code on nsnam.org hosts
Mercurial repository layout for developers
- In your home dir on code.nsnam.org, you will find a new directory named "
/home/tomh/repositories/tomh. If you create a repository in this directory, it will appear automatically on http://code.nsnam.org
- Note: To enable this for new users, edit /var/www/cgi-hg/hgweb.config
- You can obviously ssh to your personal account and manage these repositories
- You can push to these repositories with the command:
hg push ssh://firstname.lastname@example.org/repositories/tomh/ns-3-com
- You can pull with the usual commands:
hg clone http://code.nsnam.org/tomh/ns-3-com
- If you want to allow another user to push into your repository, all you have to do is change the unix permissions of your repository to allow this user write permissions. This means that if you want to give everyone write permissions, you can "
chmod -R g +rw /home/tomh/repositories/tomh/ns-3-com/". If you want to allow only a smaller subset of users to push, we will need to create unix group which matches this subset
- The push command for the main tree is still:
hg push ssh://email@example.com/repos/ns-3-dev
- New developers, please read this: When creating a new repository, do not "hg clone" it into your directory on code.nsnam.org (which will generate a big ns-commits mail message); instead, just copy (cp -r) or rsync it to your local "/home/username/repositories/username" directory.
- How to undo a commit: Let's suppose you are working on a private repository and you check something in, but some other files were inadvertently checked in, and you want to revert and start over. There are two ways to do this:
hg revert: This can be used to revert the repository to a previous revision number. For example, to revert to changeset number #1000, type
hg revert -r 1000 --all. This does not remove your checkin from the repository history. For example, if your mistaken checkin was number 1001, and you revert back to 1000 and then commit, you will be at changeset number 1002 now even though the code matches what was in there at changeset 1000.
hg rollback: This can be used to completely wipe clean the last transaction only (commit, import, push, pull). Use with care-- cannot be undone.
- How to rename a file:
hg rename old-file-name new-file-nameThis is preferable to adding the new file name and removing the old file name, because it preserves revision history. Don't forget to commit once you are done.
- How to merge a branch: If you have forked a branch repository, have worked on it, and are ready to merge it back to ns-3-dev, here are the steps to take (Also, read this chapter to better understand how the mercurial source tree is structured when merging is occurring):
- How to create patches for circulation:
hg export tipSuppose you don't have write access to the main repositories, but have some patches you'd like to circulate. This command outputs out all the diffs for the latest changeset you committed into your local repository. Simply redirect this output to a file, and you can circulate your patch for consideration. This is for when you have committed changesets. If you would like to export uncommitted changes as a patch, use:
hg diffThis gets the diffs of all the uncommitted changes versus what is checked into the repository. Redirect to a file for circulation among developers, or for inclusion with a bug report, etc.
The WAF build system
See also the Waf User FAQ.
A snapshot of WAF is distributed with ns-3 releases and mercurial branches. This snapshopt has been tested to work correctly with ns-3, although the trunk version from the main WAF repository usually works equally well.
There is some incomplete documentation near the bottom of the WAF home page. Some useful tips can be found in the WAF Wiki. Finally, there is a plethora of examples distributed in WAF itself, in the 'demos' directory.
How to add new ns-3 modules
Ns-3 is organized as a set of modules. Each module is built as a set of object files, has a name, may depend on other modules, and installs a specific set of public header files.
To add a new ns-3 module to the WAF build system, begin by creating a directory under the
src/ subtree, with the source files inside. We will use p2p module as example here. Each module needs to define a
wscript file. For instance let us see what
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- def build(bld): module = bld.create_ns3_module('point-to-point', ['node']) module.source = [ 'point-to-point-net-device.cc', 'point-to-point-channel.cc', 'point-to-point-topology.cc', ] headers = bld.create_obj('ns3header') headers.module = 'point-to-point' headers.source = [ 'point-to-point-net-device.h', 'point-to-point-channel.h', 'point-to-point-topology.h', ]
A wscript file is basically a special python module. The main entry point to this module is the
build(bld) python function.
In the code above, the module variable represents a ns-3 module; internally it is a WAF 'objects' build object that will be linked to be come part of the ns3 library. It is created by calling a special method bld.create_ns3_module, whose first parameter is the name of the module, and the second parameter is a list of other modules that this module depends on. Additionally, module.sources has to be set to the list of source files (excluding header files) that constitute the module. Warning: beware that the name of the module must match the name of the directory where it is built. In this case, the module is in 'src/devices/point-to-point', so the module name must be 'point-to-point'.
There is usually also a headers object. It is used to declare public header files. These files are copied to the build directory, and can be included from any module or program with
A final step, after the wscript file is created, is to register it. Open the file
src/wscript and add the new module to the
all_modules list variable:
all_modules = ( 'core', 'common', 'simulator', 'node', 'internet-node', 'devices/point-to-point', # <---- example here 'applications', )
Use the special method bld.create_ns3_program(name, [...dependencies...]). Example:
obj = bld.create_ns3_program('main-simple', ['node', 'internet-node', 'applications']) obj.source = 'main-simple.cc'
Generating new python bindings
See the ns-3 python wiki page.
Submitting patches for consideration
When you send a tree without a detailed summary of your changes, it would help if you could send a list of the changesets you want to merge. To generate it, first merge with ns-3-dev and then, from your modified directory, run "hg outgoing -p http://code.nsnam.org/ns-3-dev"
Also, avoid spurious coding style and whitespace changes when preparing such a patch, as it distracts from the readability of your proposed technical changes.
If you use VIM you should add the following lines to your ~/.vimrc:
set ts=2 set sw=2 set sta set et set ai set si set cin
And the following lines to realize white space errors (trailing white spaces):
let c_no_bracket_error=1 let c_no_curly_error=1 let c_comment_strings=1 let c_gnu=
Checking in code
just before you do a checkin you should run the regression tests. Change into the top level directory and type
If you do this, you will see a bunch of passing tests and then, if something goes wrong:
Traces differ in test: test-tcp-large-transfer Reference traces in directory: regression/ns-3-dev-ref-traces/tcp-large-transfer.ref Traces in directory: traces Rerun regression test as: "./waf --regression --regression-tests=test-tcp-large-transfer" Then do "diff -u regression/ns-3-dev-ref-traces/tcp-large-transfer.ref regression/traces" for details ---------- FAIL test-tcp-large-transfer
Now, this "failure" is most likely due to another developer checking in a change that altered the behavior of an underlying model. You can follow the directions in the failure message to see what has changed for ASCII trace files. If the problem is with pcap traces, it is usually convenient to "tcpdump -nn -tt -r trace-file-name" in order to translate the output to human-readable form before doing the diff.
If you yourself have made a change and broken the regression output, and you expect the changes, you'll need to update the reference traces for the new behavior. All you have to do is to run the individual regression test:
./waf --regression-generate --regression-tests=test-tcp-large-transfer
This will write the new trace bits into a directory in a subdirectory of regression/ns-3-dev-ref-traces (assuming you are in a repository with VERSION set to 3-dev) corresponding to the test name. You will need to verify that the new traces are what you expect to see given your change. If you don't expect to see any changes, you may have caused a real regression and you'll need to debug it before checking in.
Assuming that the new traces represent new expected behavior, you just need to push the new bits into the ns-3-dev-ref-traces repository.
cd ns-3-dev-ref-traces hg push ssh://firstname.lastname@example.org//home/code/repos/ns-3-dev-ref-traces
Using gcov and lcov code coverage tools
You must have lcov installed on your machine to do this. e.g.
sudo apt-get install lcov
or install from source.
Then, for instance, to see the coverage of the ns-3 unit tests, type:
./waf configure --enable-gcov ./waf --lcov-report ./waf check ./waf --lcov-report
You will find a file "index.html" in the directory build/debug-gcov/lcov-report/ that you can look at with your browser.
Note that the first time you type ./waf --lcov-report, it may complain that no .gcda files were found. Just ignore this and run the program you want to test coverage of.
The preferred way to create a private repository
Let's say that developer "alice" wants to create a new repository "ns-3-dev-new-feature" that will exist on the code server as alice/ns-3-dev-new-feature. Suppose she wants to fork from the tip of ns-3-dev.
cd /home/alice/repositories/alice cp -r /home/code/repos/ns-3-dev ns-3-dev-new-feature cd ns-3-dev-new-feature/.hg
At this point, edit the "hgrc" file to provide contact/description information:
[paths] default = http://code.nsnam.org/alice/ns-3-dev-new-feature [web] description = alice's new feature contact = <email@example.com>
Note: A common minor problem is if you do an "hg clone" into the new directory instead of a "cp -r", there will be a huge ns-commits mail message generated. This is why "cp -r" is preferred way to do this.
Testing code on nsnam.org hosts
Some times a compilation error can only reproduced in certain architectures. nsnam.org has some machines that can be accessed remotely for testing purposes, if you have an appropriate account. Contact Tom Henderson if you need an account.
Note that this takes several hours to run. It puts a specified branch through its paces on several machines/architectures. You can specify a branch to test, where to find its regression traces, and a notification email address where you will receive a report about how the branch performed in the tests (SUCCESS or FAILURE).
$ ssh ns-regression.ee.washington.edu $ sudo -u nsnam bash $ cd /usr/local/bin/ $ ./ns-3-run-tests.sh -h usage: ./ns-3-run-tests.sh options This script runs the ns-3 branch through the ns-regression testbed. OPTIONS: -h Help: show this message -n ns-3 branch Default: ns-3-dev -r regression branch Default: ns-3-dev-ref-traces -m mailto address. Where to send the mail. If unspecified, program output will just scroll onto stdout. $ ./ns-3-run-tests.sh -n mathieu/ns-3-simu -m firstname.lastname@example.org
Mac OS X PowerPC
ssh ns-regression.ee.washington.edu sudo -u nsnam bash <enter your password> ssh darwin-ppc