From: Alina Quereilhac Date: Sun, 5 Jun 2011 10:52:26 +0000 (+0200) Subject: node trace added to netns:Node. Bug: netns doesn't properly close subprocesses not... X-Git-Tag: nepi_v2_1~45 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=c50784496672190a3ee54102f62b5b3162250254;p=nepi.git node trace added to netns:Node. Bug: netns doesn't properly close subprocesses not forked directly --- diff --git a/src/nepi/testbeds/netns/execute.py b/src/nepi/testbeds/netns/execute.py index c6de813c..45ccf4eb 100644 --- a/src/nepi/testbeds/netns/execute.py +++ b/src/nepi/testbeds/netns/execute.py @@ -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!!! diff --git a/src/nepi/testbeds/netns/metadata_v01.py b/src/nepi/testbeds/netns/metadata_v01.py index 9c2ee377..3fb96162 100644 --- a/src/nepi/testbeds/netns/metadata_v01.py +++ b/src/nepi/testbeds/netns/metadata_v01.py @@ -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, diff --git a/src/nepi/testbeds/ns3/execute.py b/src/nepi/testbeds/ns3/execute.py index bdc05539..57b80c9e 100644 --- a/src/nepi/testbeds/ns3/execute.py +++ b/src/nepi/testbeds/ns3/execute.py @@ -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 diff --git a/src/nepi/testbeds/ns3/factories_metadata_v3_9.py b/src/nepi/testbeds/ns3/factories_metadata_v3_9.py index 990b6cad..a98240e2 100644 --- a/src/nepi/testbeds/ns3/factories_metadata_v3_9.py +++ b/src/nepi/testbeds/ns3/factories_metadata_v3_9.py @@ -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, diff --git a/test/testbeds/netns/execute.py b/test/testbeds/netns/execute.py index 39fd54d6..8b8892a9 100755 --- a/test/testbeds/netns/execute.py +++ b/test/testbeds/netns/execute.py @@ -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)