node trace added to netns:Node. Bug: netns doesn't properly close subprocesses not...
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Sun, 5 Jun 2011 10:52:26 +0000 (12:52 +0200)
committerAlina Quereilhac <alina.quereilhac@inria.fr>
Sun, 5 Jun 2011 10:52:26 +0000 (12:52 +0200)
src/nepi/testbeds/netns/execute.py
src/nepi/testbeds/netns/metadata_v01.py
src/nepi/testbeds/ns3/execute.py
src/nepi/testbeds/ns3/factories_metadata_v3_9.py
test/testbeds/netns/execute.py

index c6de813..45ccf4e 100644 (file)
@@ -57,8 +57,10 @@ class TestbedController(testbed_impl.TestbedController):
         raise NotImplementedError
 
     def shutdown(self):
-        for trace in self._traces.values():
-            trace.close()
+        for guid, traces in self._traces.iteritems():
+            for trace_id, (trace, filename) in traces.iteritems():
+                if hasattr(trace, "close"):
+                    trace.close()
         for guid, element in self._elements.iteritems():
             if isinstance(element, self.TunChannel):
                 element.Cleanup()
@@ -68,12 +70,15 @@ class TestbedController(testbed_impl.TestbedController):
                     element.destroy()
         self._elements.clear()
 
-    def trace_filename(self, guid, trace_id):
-        # TODO: Need to be defined inside a home!!!! with and experiment id_code
-        return os.path.join(self.home_directory, "%d_%s" % (guid, trace_id))
+    def trace_filename(self, guid, trace_id, filename = None):
+        if not filename:
+            (trace, filename) = self._traces[guid][trace_id]
+        return os.path.join(self.home_directory, filename)
 
-    def follow_trace(self, trace_id, trace):
-        self._traces[trace_id] = trace
+    def follow_trace(self, guid, trace_id, trace, filename):
+        if not guid in self._traces:
+            self._traces[guid] = dict()
+        self._traces[guid][trace_id] = (trace, filename)
 
     def _load_netns_module(self):
         # TODO: Do something with the configuration!!!
index 9c2ee37..3fb9616 100644 (file)
@@ -27,6 +27,12 @@ TUNCHANNEL = "TunChannel"
 NS3_TESTBED_ID = "ns3"
 FDNETDEV = "ns3::FileDescriptorNetDevice"
 
+def _follow_trace(testbed_instance, guid, trace_id, filename):
+    filepath = testbed_instance.trace_filename(guid, trace_id, filename)
+    trace = open(filepath, "wb")
+    testbed_instance.follow_trace(guid, trace_id, trace, filename)
+    return trace
+
 ### Connection functions ####
 
 def connect_switch(testbed_instance, switch_guid, interface_guid):
@@ -75,6 +81,27 @@ def connect_tunchannel_tap(testbed_instance, chan_guid, tap_guid):
         pass
     chan.with_pi = with_pi
 
+### Trace functions ###
+
+def nodepcap_trace(testbed_instance, guid, trace_id):
+    node = testbed_instance._elements[guid]
+    parameters = testbed_instance._get_parameters(guid)
+    filename = "%d-cap.stdout" % guid
+    stdout = _follow_trace(testbed_instance, guid, "pcap_stdout", filename)
+    filename = "%d-pcap.stderr" % guid
+    stderr = _follow_trace(testbed_instance, guid, "pcap_stderr", filename)
+    filename = "%d-node.pcap" % guid
+    filepath = testbed_instance.trace_filename(guid, trace_id, filename)
+    command = "tcpdump -i 'any' -w %s" % filepath
+    user = "root"
+    trace = node.Popen(command, shell = True, stdout = stdout, 
+            stderr = stderr, user = user)
+    testbed_instance.follow_trace(guid, trace_id, trace, filename)
+
+trace_functions = dict({
+    "pcap": nodepcap_trace,
+    })
+
 ### Creation functions ###
 
 def create_node(testbed_instance, guid):
@@ -148,14 +175,11 @@ def start_application(testbed_instance, guid):
         user = parameters["user"]
     stdout = stderr = None
     if "stdout" in traces:
-        filename = testbed_instance.trace_filename(guid, "stdout")
-        stdout = open(filename, "wb")
-        testbed_instance.follow_trace("stdout", stdout)
+        filename = "%d-stdout.trace" % guid
+        stdout = _follow_trace(testbed_instance, guid, "stdout", filename)
     if "stderr" in traces:
-        filename = testbed_instance.trace_filename(guid, "stderr")
-        stderr = open(filename, "wb")
-        testbed_instance.follow_trace("stderr", stderr)
-
+        filename = "%d-stderr.trace" % guid
+        stderr = _follow_trace(testbed_instance, guid, "stderr", filename)
     node_guid = testbed_instance.get_connected(guid, "node", "apps")
     if len(node_guid) == 0:
         raise RuntimeError("Can't instantiate interface %d outside netns \
@@ -177,7 +201,16 @@ def status_application(testbed_instance, guid):
 
 ### Configure functions ###
 
+def configure_traces(testbed_instance, guid):
+    traces = testbed_instance._get_traces(guid)
+    for trace_id in traces:
+        if trace_id not in trace_functions:
+            continue
+        trace_func = trace_functions[trace_id]
+        trace_func(testbed_instance, guid, trace_id)
+
 def configure_device(testbed_instance, guid):
+    configure_traces(testbed_instance, guid)
     element = testbed_instance._elements[guid]
     if not guid in testbed_instance._add_address:
         return
@@ -188,6 +221,7 @@ def configure_device(testbed_instance, guid):
         element.add_v4_address(address, netprefix)
 
 def configure_node(testbed_instance, guid):
+    configure_traces(testbed_instance, guid)
     element = testbed_instance._elements[guid]
     if not guid in testbed_instance._add_route:
         return
@@ -403,6 +437,10 @@ traces = dict({
     "stderr": dict({
                 "name": "stderr",
                 "help": "Application standard error",
+        }),
+    "node_pcap": dict({
+                "name": "pcap",
+                "help": "tcpdump at all node interfaces",
         }) 
     })
 
@@ -422,7 +460,8 @@ factories_info = dict({
             "create_function": create_node,
             "configure_function": configure_node,
             "box_attributes": ["forward_X11"],
-            "connector_types": ["devs", "apps"]
+            "connector_types": ["devs", "apps"],
+            "traces": ["node_pcap"]
        }),
     P2PIFACE: dict({
             "allow_addresses": True,
index bdc0553..57b80c9 100644 (file)
@@ -115,12 +115,11 @@ class TestbedController(testbed_impl.TestbedController):
         raise NotImplementedError
 
     def trace_filename(self, guid, trace_id):
-        # TODO: Need to be defined inside a home!!!! with and experiment id_code
         filename = self._traces[guid][trace_id]
         return os.path.join(self.home_directory, filename)
 
     def follow_trace(self, guid, trace_id, filename):
-        if guid not in self._traces:
+        if not guid in self._traces:
             self._traces[guid] = dict()
         self._traces[guid][trace_id] = filename
 
index 990b6ca..a98240e 100644 (file)
@@ -87,7 +87,7 @@ def p2pascii_trace(testbed_instance, guid, trace_id):
     filepath = testbed_instance.trace_filename(guid, trace_id)
     helper = testbed_instance.ns3.PointToPointHelper()
     asciiHelper = testbed_instance.ns3.AsciiTraceHelper()
-    stream = asciiHelper.CreateFileStream (filepath)
+    stream = asciiHelper.CreateFileStream(filepath)
     helper.EnableAscii(stream, element)
 
 def p2ppcap_trace(testbed_instance, guid, trace_id):
@@ -173,7 +173,6 @@ def rtt_trace(testbed_instance, guid, trace_id):
     prefix = filepath[:filepath.find(prefix)+len(prefix)]
     helper.EnableTrace(element, trace_id, prefix, "T")
 
-
 trace_functions = dict({
     "P2PPcapTrace": p2ppcap_trace,
     "P2PAsciiTrace": p2pascii_trace,
index 39fd54d..8b8892a 100755 (executable)
@@ -165,7 +165,48 @@ class NetnsExecuteTestCase(unittest.TestCase):
         self.assertTrue(ping_result.startswith(comp_result))
         instance.stop()
         instance.shutdown()
-        
+
+    @test_util.skipUnless(os.getuid() == 0, "Test requires root privileges")
+    def test_node_pcap_trace(self):
+        user = getpass.getuser()
+        testbed_version = "01"
+        instance = netns.TestbedController(testbed_version)
+        instance.defer_configure("homeDirectory", self.root_dir)
+        instance.defer_create(2, "Node")
+        instance.defer_add_trace(2, "pcap")
+        instance.defer_create(3, "Node")
+        instance.defer_create(4, "P2PNodeInterface")
+        instance.defer_create_set(4, "up", True)
+        instance.defer_connect(2, "devs", 4, "node")
+        instance.defer_add_address(4, "10.0.0.1", 24, None)
+        instance.defer_create(5, "P2PNodeInterface")
+        instance.defer_create_set(5, "up", True)
+        instance.defer_connect(3, "devs", 5, "node")
+        instance.defer_add_address(5, "10.0.0.2", 24, None)
+        instance.defer_connect(4, "p2p", 5, "p2p")
+        instance.defer_create(6, "Application")
+        instance.defer_add_trace(6, "stdout")
+        instance.defer_create_set(6, "command", "ping -qc5 10.0.0.2")
+        instance.defer_create_set(6, "user", user)
+        instance.defer_connect(6, "node", 2, "apps")
+
+        time.sleep(5)
+        instance.do_setup()
+        instance.do_create()
+        instance.do_connect_init()
+        instance.do_connect_compl()
+        instance.do_preconfigure()
+        instance.do_configure()
+        instance.do_prestart()
+        instance.start()
+        while instance.status(6) != STATUS_FINISHED:
+            time.sleep(0.5)
+        time.sleep(5)
+        pcap_result = instance.trace(2, "pcap")
+        self.assertEquals(len(pcap_result), 1024)
+        instance.stop()
+        instance.shutdown()
+
     def tearDown(self):
         try:
             shutil.rmtree(self.root_dir)