diff --git a/doc/release_steps.txt b/doc/release_steps.txt index 8743bdf97..a2518c664 100644 --- a/doc/release_steps.txt +++ b/doc/release_steps.txt @@ -19,10 +19,25 @@ Steps in doing an ns-3 release - cd /home/code/repos/ns-3.0.x/.hg and edit the hgrc appropriately: "description = ns-3.0.x release name = ns-3.0.x" -6. upload "ns-3.0.x.tar.bz2" to the /var/www/html/releases/ directory on +6. Run the regression tests on the new release and update the reference traces + - cd regression + - python regression.py + - There should be no regressions at this time + - tag ns-3-dev-ref-traces with "release ns-3.0.X" + hg tag "release ns-3.0.x" + hg push + - clone the ns-3-dev-ref-traces and place it on the repository as in step + 6 but use the name ns-3.0.x-ref-traces +7. Create a reference traces tarball + - cd regression + - tar -cjf ns-3.0.x-ref-traces.tar.bz2 ns-3-dev-ref-traces/ +8. upload "ns-3.0.x.tar.bz2" to the /var/www/html/releases/ directory on the www.nsnam.org server - give it 644 file permissions, and user/group = apache -7. update web pages on www.nsnam.org (source is in the www/ module) +9. upload "ns-3.0.x-ref-traces.tar.bz2" to the /var/www/html/releases/ + directory on the www.nsnam.org server + - give it 644 file permissions, and user/group = apache +10. update web pages on www.nsnam.org (source is in the www/ module) - add link to news.html - update getting_started.html - update documents.html @@ -32,4 +47,4 @@ Steps in doing an ns-3 release -- edit ~/bin/update-doxygen-release file and change RELEASE variable to the right version number -- run ~/bin/update-doxygen-release -8. announce to ns-developers, with summary of release notes +11. announce to ns-developers, with summary of release notes diff --git a/examples/tcp-large-transfer.cc b/examples/tcp-large-transfer.cc index 9c92e3dd9..47b9d57a1 100644 --- a/examples/tcp-large-transfer.cc +++ b/examples/tcp-large-transfer.cc @@ -117,6 +117,11 @@ int main (int argc, char *argv[]) // LogComponentEnable("PacketSink", LOG_LEVEL_ALL); // LogComponentEnable("TcpLargeTransfer", LOG_LEVEL_ALL); + // + // Make the random number generators generate reproducible results. + // + RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8); + // Allow the user to override any of the defaults and the above // Bind()s at run-time, via command-line arguments CommandLine cmd; @@ -182,9 +187,9 @@ int main (int argc, char *argv[]) std::ofstream ascii; ascii.open ("tcp-large-transfer.tr"); - PointToPointHelper::EnablePcap ("tcp-large-transfer"); PointToPointHelper::EnableAscii (ascii); + InternetStackHelper::EnablePcap ("tcp-large-transfer"); Simulator::StopAt (Seconds(1000)); Simulator::Run (); diff --git a/regression/regression.py b/regression/regression.py index 10e5fdb57..042d2b041 100644 --- a/regression/regression.py +++ b/regression/regression.py @@ -36,20 +36,20 @@ refUrl = "http://www.nsnam.org/releases/" # mercurial on the system. It is expected to be created using tar -cjf and # will be extracted using tar -xjf # -refTarName = "ns-3-ref-traces.tar.bz2" +refTarName = "ns-3.0.12-ref-traces.tar.bz2" # # The path to the Mercurial repository used to find the reference traces if # we find "hg" on the system. We expect that the repository will be named # identically to refDirName below # -refRepo = "http://code.nsnam.org/craigdo/" +refRepo = "http://code.nsnam.org/" # # The local directory name into which the reference traces will go in either # case (net or hg). # -refDirName = "ns-3-ref-traces" +refDirName = "ns-3-dev-ref-traces" def main(tests = None, testdir = None): """Execute regression tests. @@ -78,33 +78,6 @@ def main(tests = None, testdir = None): if o == '-v': verbose = 1 if o == '-g': generate = 1 - print "========== Running Unit Tests ==========" - os.system("./waf check") - - print "========== Running Regression Tests ==========" - if os.system("hg version > /dev/null 2>&1") == 0: - print "Synchronizing reference traces using Mercurial." - if not os.path.exists(refDirName): - os.system("hg clone " + refRepo + refDirName + - " > /dev/null 2>&1") - else: - os.chdir(refDirName) - os.system("hg pull " + refRepo + refDirName + - " > /dev/null 2>&1") - os.chdir("..") - else: - print "Synchronizing reference traces from web." - urllib.urlretrieve(refUrl + refTarName, refTarName) - os.system("tar -xjf " + refTarName) - - print "Done." - - bad = [] - - if not os.path.exists(refDirName): - print "Reference traces directory does not exist" - return 3 - if not testdir: testdir = os.path.join(os.curdir, "tests") @@ -123,12 +96,39 @@ def main(tests = None, testdir = None): if not tests: tests = findtests(testdir) + if not generate: + print "========== Running Unit Tests ==========" + os.system("./waf check") + + print "========== Running Regression Tests ==========" + + if os.system("hg version > /dev/null 2>&1") == 0: + print "Synchronizing reference traces using Mercurial." + if not os.path.exists(refDirName): + os.system("hg clone " + refRepo + refDirName + " > /dev/null 2>&1") + else: + os.chdir(refDirName) + os.system("hg pull " + refRepo + refDirName + " > /dev/null 2>&1") + os.chdir("..") + else: + print "Synchronizing reference traces from web." + urllib.urlretrieve(refUrl + refTarName, refTarName) + os.system("tar -xjf " + refTarName) + + print "Done." + + if not os.path.exists(refDirName): + print "Reference traces directory does not exist" + return 3 + + bad = [] + for test in tests: result = run_test(test) if result == 0: if generate: - print "GENERATE" + test + print "GENERATE " + test else: print "PASS " + test else: diff --git a/regression/tracediff.py b/regression/tracediff.py index 1f1c4b3d2..66610e9d8 100644 --- a/regression/tracediff.py +++ b/regression/tracediff.py @@ -9,28 +9,24 @@ import shutil def run_test(verbose, generate, refDirName, testName): """Execute a test.""" - repoName = "ns-3-ref-traces/" - refDirName = testName + ".ref" + refTestDirName = refDirName + "/" + testName + ".ref" - if not os.path.exists(repoName): + if not os.path.exists(refDirName): print"No reference trace repository" return 1 if generate: - if not os.path.exists(repoName + refDirName): - print "creating new " + repoName + refDirName - os.mkdir(repoName + refDirName) + if not os.path.exists(refTestDirName): + print "creating new " + refTestDirName + os.mkdir(refTestDirName) - try: - os.system("./waf --cwd regression/" + repoName + refDirName + - " --run " + testName + " > /dev/null 2>&1") - except: - sys.exit(1) + os.system("./waf --cwd regression/" + refTestDirName + + " --run " + testName + " > /dev/null 2>&1") - print "Remember to commit " + repoName + refDirName + print "Remember to commit " + refTestDirName return 0 else: - if not os.path.exists(repoName + refDirName): + if not os.path.exists(refTestDirName): print "Cannot locate reference traces" return 1 @@ -41,21 +37,20 @@ def run_test(verbose, generate, refDirName, testName): testName + " > /dev/null 2>&1") if verbose: - diffCmd = "diff traces " + repoName + refDirName + " | head" + diffCmd = "diff traces " + refTestDirName + " | head" else: - diffCmd = "diff traces " + repoName + refDirName + \ + diffCmd = "diff traces " + refTestDirName + \ " > /dev/null 2>&1" rc = os.system(diffCmd) if rc: print "----------" print "Traces differ in test: test-" + testName - print "Reference traces in directory: " + repoName + \ - refDirName + print "Reference traces in directory: " + refTestDirName print "Traces in directory: traces" print "Rerun regression test as: " + \ "\"python regression.py test-" + testName + "\"" - print "Then do \"diff -u traces " + repoName + refDirName + \ + print "Then do \"diff -u traces " + refTestDirName + \ "\" for details" print "----------" return rc diff --git a/src/helper/internet-stack-helper.cc b/src/helper/internet-stack-helper.cc index 1003dceba..94615135f 100644 --- a/src/helper/internet-stack-helper.cc +++ b/src/helper/internet-stack-helper.cc @@ -20,9 +20,13 @@ #include "internet-stack-helper.h" #include "ns3/internet-stack.h" #include "ns3/packet-socket-factory.h" +#include "ns3/config.h" namespace ns3 { +std::vector InternetStackHelper::m_traces; +std::string InternetStackHelper::m_pcapBaseFilename; + void InternetStackHelper::Build (NodeContainer c) { @@ -35,5 +39,68 @@ InternetStackHelper::Build (NodeContainer c) } } +void +InternetStackHelper::EnablePcap (std::string filename) +{ + InternetStackHelper::m_pcapBaseFilename = filename; + Config::Connect ("/NodeList/*/$ns3::Ipv4L3Protocol/Tx", + MakeCallback (&InternetStackHelper::LogTxIp)); + Config::Connect ("/NodeList/*/$ns3::Ipv4L3Protocol/Rx", + MakeCallback (&InternetStackHelper::LogRxIp)); +} + +uint32_t +InternetStackHelper::GetNodeIndex (std::string context) +{ + std::string::size_type pos; + pos = context.find ("/NodeList/"); + NS_ASSERT (pos == 0); + std::string::size_type afterNodeIndex = context.find ("/", 11); + NS_ASSERT (afterNodeIndex != std::string::npos); + std::string index = context.substr (10, afterNodeIndex - 10); + std::istringstream iss; + iss.str (index); + uint32_t nodeIndex; + iss >> nodeIndex; + return nodeIndex; +} + +void +InternetStackHelper::LogTxIp (std::string context, Ptr packet, uint32_t interfaceIndex) +{ + Ptr writer = InternetStackHelper::GetStream (GetNodeIndex (context), interfaceIndex); + writer->WritePacket (packet); +} + +void +InternetStackHelper::LogRxIp (std::string context, Ptr packet, uint32_t interfaceIndex) +{ + Ptr writer = InternetStackHelper::GetStream (GetNodeIndex (context), interfaceIndex); + writer->WritePacket (packet); +} + +Ptr +InternetStackHelper::GetStream (uint32_t nodeId, uint32_t interfaceId) +{ + for (std::vector::iterator i = m_traces.begin (); + i != m_traces.end (); i++) + { + if (i->nodeId == nodeId && + i->interfaceId == interfaceId) + { + return i->writer; + } + } + InternetStackHelper::Trace trace; + trace.nodeId = nodeId; + trace.interfaceId = interfaceId; + trace.writer = Create (); + std::ostringstream oss; + oss << m_pcapBaseFilename << "-" << nodeId << "-" << interfaceId << ".pcap"; + trace.writer->Open (oss.str ()); + trace.writer->WriteIpHeader (); + m_traces.push_back (trace); + return trace.writer; +} } // namespace ns3 diff --git a/src/helper/internet-stack-helper.h b/src/helper/internet-stack-helper.h index 828d11879..48bc6b633 100644 --- a/src/helper/internet-stack-helper.h +++ b/src/helper/internet-stack-helper.h @@ -21,6 +21,9 @@ #define INTERNET_STACK_HELPER_H #include "node-container.h" +#include "net-device-container.h" +#include "ns3/pcap-writer.h" +#include "ns3/packet.h" namespace ns3 { @@ -37,6 +40,27 @@ public: * of the ns3::Ipv4, ns3::Udp, and, ns3::Tcp classes. */ void Build (NodeContainer c); + + /** + * \param filename filename prefix to use for pcap files. + * + * Enable pcap output on each protocol instance which is of the + * ns3::Ipv4L3Protocol type. Both Tx and Rx events will be logged. + */ + static void EnablePcap (std::string filename); + +private: + static void LogRxIp (std::string context, Ptr packet, uint32_t deviceId); + static void LogTxIp (std::string context, Ptr packet, uint32_t deviceId); + static Ptr GetStream (uint32_t nodeId, uint32_t interfaceId); + struct Trace { + uint32_t nodeId; + uint32_t interfaceId; + Ptr writer; + }; + static std::string m_pcapBaseFilename; + static uint32_t GetNodeIndex (std::string context); + static std::vector m_traces; }; } // namespace ns3