Beispiel #1
0
    def _test_spanning_deployment(self, use_sfa=False):
        pl, exp = self.make_experiment_desc(use_sfa)

        pl.set_attribute_value(
            "p2pDeployment", True)  # we do want it here - even if interactive

        from nepi.testbeds import planetlab as plpackage

        nodes = [pl.create("Node") for i in xrange(4)]
        ifaces = [pl.create("NodeInterface") for node in nodes]
        inet = pl.create("Internet")
        for node, iface in zip(nodes, ifaces):
            node.connector("devs").connect(iface.connector("node"))
            iface.connector("inet").connect(inet.connector("devs"))

        apps = []
        for node in nodes:
            app = pl.create("Application")
            app.set_attribute_value("command", "./consts")
            app.set_attribute_value("buildDepends", "gcc")
            app.set_attribute_value("build",
                                    "gcc ${SOURCES}/consts.c -o consts")
            app.set_attribute_value("install", "cp consts ${SOURCES}/consts")
            app.set_attribute_value(
                "sources",
                os.path.join(os.path.dirname(plpackage.__file__), 'scripts',
                             'consts.c'))
            app.enable_trace("stdout")
            app.enable_trace("stderr")
            app.enable_trace("buildlog")
            node.connector("apps").connect(app.connector("node"))
            apps.append(app)

        comp_result = \
r""".*ETH_P_ALL = 0x[0-9a-fA-F]{8}
ETH_P_IP = 0x[0-9a-fA-F]{8}
TUNGETIFF = 0x[0-9a-fA-F]{8}
TUNSETIFF = 0x[0-9a-fA-F]{8}
IFF_NO_PI = 0x[0-9a-fA-F]{8}
IFF_TAP = 0x[0-9a-fA-F]{8}
IFF_TUN = 0x[0-9a-fA-F]{8}
IFF_VNET_HDR = 0x[0-9a-fA-F]{8}
TUN_PKT_STRIP = 0x[0-9a-fA-F]{8}
IFHWADDRLEN = 0x[0-9a-fA-F]{8}
IFNAMSIZ = 0x[0-9a-fA-F]{8}
IFREQ_SZ = 0x[0-9a-fA-F]{8}
FIONREAD = 0x[0-9a-fA-F]{8}.*
"""

        comp_build = r".*(Identity added|gcc).*"

        xml = exp.to_xml()

        controller = ExperimentController(xml, self.root_dir)
        try:
            controller.start()
            while not all(controller.is_finished(app.guid) for app in apps):
                time.sleep(0.5)

            for app in apps:
                app_result = controller.trace(app.guid, "stdout") or ""
                self.assertTrue(
                    re.match(comp_result, app_result, re.MULTILINE),
                    "Unexpected trace:\n" + app_result)

                build_result = controller.trace(app.guid, "buildlog") or ""
                self.assertTrue(
                    re.match(comp_build, build_result,
                             re.MULTILINE | re.DOTALL),
                    "Unexpected trace:\n" + build_result)

        finally:
            try:
                controller.stop()
            except:
                import traceback
                traceback.print_exc()
            try:
                controller.shutdown()
            except:
                import traceback
                traceback.print_exc()
Beispiel #2
0
    def _test_recover(self,
                      daemonize_testbed,
                      controller_access_configuration,
                      environ=None,
                      use_sfa=False):
        pl, exp = self.make_experiment_desc(use_sfa)

        pl.set_attribute_value(DC.RECOVERY_POLICY, DC.POLICY_RECOVER)

        node1 = pl.create("Node")
        node2 = pl.create("Node")
        node1.set_attribute_value("hostname", self.host1)
        node2.set_attribute_value("hostname", self.host2)

        iface1 = pl.create("NodeInterface")
        iface2 = pl.create("NodeInterface")
        inet = pl.create("Internet")
        node1.connector("devs").connect(iface1.connector("node"))
        node2.connector("devs").connect(iface2.connector("node"))
        iface1.connector("inet").connect(inet.connector("devs"))
        iface2.connector("inet").connect(inet.connector("devs"))

        tap1 = pl.create("TapInterface")
        tap2 = pl.create("TapInterface")
        node1.connector("devs").connect(tap1.connector("node"))
        node2.connector("devs").connect(tap2.connector("node"))
        tap1.connector("udp").connect(tap2.connector("udp"))

        tap1ip = tap1.add_address()
        tap1ip.set_attribute_value("Address", "192.168.2.2")
        tap1ip.set_attribute_value("NetPrefix", 24)
        tap1ip.set_attribute_value("Broadcast", False)

        tap2ip = tap2.add_address()
        tap2ip.set_attribute_value("Address", "192.168.2.3")
        tap2ip.set_attribute_value("NetPrefix", 24)
        tap2ip.set_attribute_value("Broadcast", False)

        app = pl.create("Application")
        app.set_attribute_value("command", "ping -qc10 192.168.2.3")
        app.enable_trace("stdout")
        app.connector("node").connect(node1.connector("apps"))

        if daemonize_testbed:
            pl.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
            inst_root_dir = os.path.join(self.root_dir, "instance")
            os.mkdir(inst_root_dir)
            pl.set_attribute_value(DC.ROOT_DIRECTORY, inst_root_dir)
            pl.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)

            if environ:
                pl.set_attribute_value(DC.DEPLOYMENT_ENVIRONMENT_SETUP,
                                       environ)

        xml = exp.to_xml()

        if controller_access_configuration:
            controller = proxy.create_experiment_controller(
                xml, controller_access_configuration)
        else:
            controller = ExperimentController(xml, self.root_dir)

        try:
            controller.start()

            # purposedly break connection
            controller = None

            # recover
            if controller_access_configuration:
                controller_access_configuration.set_attribute_value(
                    DC.RECOVER, True)
                controller = proxy.create_experiment_controller(
                    None, controller_access_configuration)
            else:
                controller = ExperimentController(None, self.root_dir)
                controller.recover()

            while not controller.is_finished(app.guid):
                time.sleep(0.5)
            ping_result = controller.trace(app.guid, "stdout")
            comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data.

--- .* ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time \d*ms.*
"""
            self.assertTrue(re.match(comp_result, ping_result, re.MULTILINE),
                            "Unexpected trace:\n" + ping_result)

        finally:
            if controller is not None:
                try:
                    controller.stop()
                except:
                    import traceback
                    traceback.print_exc()
                try:
                    controller.shutdown()
                except:
                    import traceback
                    traceback.print_exc()
Beispiel #3
0
    def test_ns3_in_pl_crossconnect(self):
        pl, exp = self.make_experiment_desc()
        
        # Create PL node, ifaces, assign addresses
        node1, iface1, tap1, tap1ip, inet = self.make_pl_tapnode(pl)
        
        # Add NS3 support in node1
        ns3_desc = self.make_ns_in_pl(pl, exp, node1, iface1, "tb-ns3-2")
        
        # Create NS3 node that is responsive to pings, connected
        # to node1 through the Tap interface
        ns1 = ns3_desc.create("ns3::Node")
        ipv41 = ns3_desc.create("ns3::Ipv4L3Protocol")
        arp1  = ns3_desc.create("ns3::ArpL3Protocol")
        icmp1 = ns3_desc.create("ns3::Icmpv4L4Protocol")
        ns1.connector("protos").connect(ipv41.connector("node"))
        ns1.connector("protos").connect(arp1.connector("node"))
        ns1.connector("protos").connect(icmp1.connector("node"))
        ns1if = ns3_desc.create("ns3::FdNetDevice")
        ns1if.enable_trace("FdPcapTrace")
        ns1if.set_attribute_value("label", "ns1if")
        ns1.connector("devs").connect(ns1if.connector("node"))
        tap1.connector("fd->").connect(ns1if.connector("->fd"))
        tap1.set_attribute_value("tun_cipher", "PLAIN")
        ip1 = ns1if.add_address()
        ip1.set_attribute_value("Address", "192.168.2.3")
        ip1.set_attribute_value("NetPrefix", 24)
        ip1.set_attribute_value("Broadcast", False)

        # Create PlanetLab ping application, pinging the NS3 node
        ping = pl.create("Application")
        ping.set_attribute_value("command", "ping -qc10 {#[ns1if].addr[0].[Address]#}")
        ping.enable_trace("stdout")
        ping.enable_trace("stderr")
        ping.connector("node").connect(node1.connector("apps"))

        comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data.

--- .* ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time \d*ms.*
"""

        xml = exp.to_xml()

        try:
            controller = ExperimentController(xml, self.root_dir)
            controller.start()

            while not controller.is_finished(ping.guid):
                time.sleep(0.5)
              
            ping_result = controller.trace(ping.guid, "stdout")
            tap_trace = controller.trace(tap1.guid, "packets")

        finally:
            try:
                controller.stop()
            except:
                import traceback
                traceback.print_exc()
            try:
                controller.shutdown()
            except:
                import traceback
                traceback.print_exc()

        # asserts at the end, to make sure there's proper cleanup
        self.assertTrue(re.match(comp_result, ping_result, re.MULTILINE),
            "Unexpected trace:\n%s\nTap trace:\n%s\n" % (
                ping_result,
                tap_trace) )
Beispiel #4
0
    def _test_simple(self, daemonize_testbed, controller_access_configuration, environ=None, use_sfa=False):
        pl, exp = self.make_experiment_desc(use_sfa)

        node1 = pl.create("Node")
        node2 = pl.create("Node")
        node1.set_attribute_value("hostname", self.host1)
        node2.set_attribute_value("hostname", self.host2)
        iface1 = pl.create("NodeInterface")
        iface2 = pl.create("NodeInterface")
        iface2.set_attribute_value("label", "node2iface")
        inet = pl.create("Internet")
        node1.connector("devs").connect(iface1.connector("node"))
        node2.connector("devs").connect(iface2.connector("node"))
        iface1.connector("inet").connect(inet.connector("devs"))
        iface2.connector("inet").connect(inet.connector("devs"))
        app = pl.create("Application")
        app.set_attribute_value("command", "ping -qc1 {#[node2iface].addr[0].[Address]#}")
        app.enable_trace("stdout")
        app.connector("node").connect(node1.connector("apps"))

        if daemonize_testbed:
            pl.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
            inst_root_dir = os.path.join(self.root_dir, "instance")
            os.mkdir(inst_root_dir)
            pl.set_attribute_value(DC.ROOT_DIRECTORY, inst_root_dir)
            pl.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)

            if environ:
                pl.set_attribute_value(DC.DEPLOYMENT_ENVIRONMENT_SETUP, environ)

        xml = exp.to_xml()

        if controller_access_configuration:
            controller = proxy.create_experiment_controller(xml, controller_access_configuration)
        else:
            controller = ExperimentController(xml, self.root_dir)

        try:
            controller.start()
            while not controller.is_finished(app.guid):
                time.sleep(0.5)
            ping_result = controller.trace(app.guid, "stdout")
            comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data.

--- .* ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time \d*ms.*
"""
            self.assertTrue(re.match(comp_result, ping_result, re.MULTILINE), "Unexpected trace:\n" + ping_result)

        finally:
            try:
                controller.stop()
            except:
                import traceback

                traceback.print_exc()
            try:
                controller.shutdown()
            except:
                import traceback

                traceback.print_exc()
Beispiel #5
0
    def _test_fd_net_device(self, daemonize_testbed,
            controller_access_configuration):
        testbed_id = "ns3"
        exp_desc = ExperimentDescription()
        ns3_provider = FactoriesProvider(testbed_id)
        ns3_desc1 = exp_desc.add_testbed_description(ns3_provider)
        root_dir1 = os.path.join(self.root_dir, "1")
        ns3_desc1.set_attribute_value("homeDirectory", root_dir1)
        ns3_desc1.set_attribute_value("SimulatorImplementationType",
                "ns3::RealtimeSimulatorImpl")
        ns3_desc1.set_attribute_value("ChecksumEnabled", True)
        ns3_desc2 = exp_desc.add_testbed_description(ns3_provider)
        root_dir2 = os.path.join(self.root_dir, "2")
        ns3_desc2.set_attribute_value("homeDirectory", root_dir2)
        ns3_desc2.set_attribute_value("SimulatorImplementationType",
                "ns3::RealtimeSimulatorImpl")
        ns3_desc2.set_attribute_value("ChecksumEnabled", True)

        node1 = ns3_desc1.create("ns3::Node")
        ipv41 = ns3_desc1.create("ns3::Ipv4L3Protocol")
        arp1  = ns3_desc1.create("ns3::ArpL3Protocol")
        icmp1 = ns3_desc1.create("ns3::Icmpv4L4Protocol")
        node1.connector("protos").connect(ipv41.connector("node"))
        node1.connector("protos").connect(arp1.connector("node"))
        node1.connector("protos").connect(icmp1.connector("node"))
        iface1 = ns3_desc1.create("ns3::FdNetDevice")
        node1.connector("devs").connect(iface1.connector("node"))
        ip1 = iface1.add_address()
        ip1.set_attribute_value("Address", "10.0.0.1")
        tc1 = ns3_desc1.create("ns3::Nepi::TunChannel")
        tc1.connector("fd->").connect(iface1.connector("->fd"))

        node2 = ns3_desc2.create("ns3::Node")
        ipv42 = ns3_desc2.create("ns3::Ipv4L3Protocol")
        arp2  = ns3_desc2.create("ns3::ArpL3Protocol")
        icmp2 = ns3_desc2.create("ns3::Icmpv4L4Protocol")
        node2.connector("protos").connect(ipv42.connector("node"))
        node2.connector("protos").connect(arp2.connector("node"))
        node2.connector("protos").connect(icmp2.connector("node"))
        iface2 = ns3_desc2.create("ns3::FdNetDevice")
        iface2.enable_trace("FdAsciiTrace")
        node2.connector("devs").connect(iface2.connector("node"))
        ip2 = iface2.add_address()
        ip2.set_attribute_value("Address", "10.0.0.2")
        tc2 = ns3_desc2.create("ns3::Nepi::TunChannel")
        tc2.connector("fd->").connect(iface2.connector("->fd"))

        tc2.connector("udp").connect(tc1.connector("udp"))

        app = ns3_desc1.create("ns3::V4Ping")
        app.set_attribute_value("Remote", "10.0.0.2")
        app.set_attribute_value("StartTime", "0s")
        app.set_attribute_value("StopTime", "2s")
        app.connector("node").connect(node1.connector("apps"))

        if daemonize_testbed:
            ns3_desc1.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
            inst_root_dir = os.path.join(root_dir1, "instance")
            os.makedirs(inst_root_dir)
            ns3_desc1.set_attribute_value(DC.ROOT_DIRECTORY, inst_root_dir)
            #ns3_desc1.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)

            ns3_desc2.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
            inst_root_dir = os.path.join(root_dir2, "instance")
            os.makedirs(inst_root_dir)
            ns3_desc2.set_attribute_value(DC.ROOT_DIRECTORY, inst_root_dir)
            #ns3_desc2.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)

        xml = exp_desc.to_xml()
        
        if controller_access_configuration:
            controller = ExperimentController(xml, self.root_dir)
        else:
            controller = proxy.create_experiment_controller(xml, 
                controller_access_configuration)
        
        try:
            controller.start()
            while not controller.is_finished(app.guid):
                time.sleep(0.5)
            ping_result = controller.trace(iface2.guid, "FdAsciiTrace")
            ping_exp_result = r"""r [-+0-9.e]+ /NodeList/0/DeviceList/0/\$ns3::FdNetDevice/Rx Payload \(size=42\)
r [-+0-9.e]+ /NodeList/0/DeviceList/0/\$ns3::FdNetDevice/Rx Payload \(size=98\)
r [-+0-9.e]+ /NodeList/0/DeviceList/0/\$ns3::FdNetDevice/Rx Payload \(size=42\)
r [-+0-9.e]+ /NodeList/0/DeviceList/0/\$ns3::FdNetDevice/Rx Payload \(size=98\)
"""
            if not re.match(ping_exp_result, ping_result):
                self.fail("Unexpected trace: %s" % (ping_result,))

        finally:
            controller.stop()
            controller.shutdown()
Beispiel #6
0
app1 = netns_desc.create("Application")
app1.set_attribute_value("command", "ping -qc 3 192.168.1.2")
app1.set_attribute_value("user", user)
app1.connector("node").connect(node1.connector("apps"))

app1.enable_trace("stdout")

app2 = netns_desc.create("Application")
app2.set_attribute_value("command", "ping -qc 3 192.168.0.1")
app2.set_attribute_value("user", user)
app2.connector("node").connect(node3.connector("apps"))

app2.enable_trace("stdout")

xml = exp_desc.to_xml()

controller = ExperimentController(xml, root_dir)
controller.start()
while not (controller.is_finished(app1.guid) and \
        controller.is_finished(app2.guid)):
    time.sleep(0.5)

result1 = controller.trace(app1.guid, "stdout")
result2 = controller.trace(app2.guid, "stdout")

controller.stop()
controller.shutdown()

print result1
print result2
app1 = netns_desc.create("Application")
app1.set_attribute_value("command", "ping -qc 3 192.168.1.2")
app1.set_attribute_value("user", user)
app1.connector("node").connect(node1.connector("apps"))

app1.enable_trace("stdout")

app2 = netns_desc.create("Application")
app2.set_attribute_value("command", "ping -qc 3 192.168.0.1")
app2.set_attribute_value("user", user)
app2.connector("node").connect(node3.connector("apps"))

app2.enable_trace("stdout")

xml = exp_desc.to_xml()

controller = ExperimentController(xml, root_dir)
controller.start()
while not (controller.is_finished(app1.guid) and \
        controller.is_finished(app2.guid)):
    time.sleep(0.5)

result1 = controller.trace(app1.guid, "stdout")
result2 = controller.trace(app2.guid, "stdout")

controller.stop()
controller.shutdown()

print result1
print result2
Beispiel #8
0
class ExperimentControllerServer(BaseServer):
    def __init__(self, root_dir, log_level, experiment_xml, environment_setup,
            clean_root):
        super(ExperimentControllerServer, self).__init__(root_dir, log_level, 
            environment_setup = environment_setup, clean_root = clean_root)
        self._experiment_xml = experiment_xml
        self._experiment = None

    def post_daemonize(self):
        from nepi.core.execute import ExperimentController
        self._experiment = ExperimentController(self._experiment_xml, 
            root_dir = self._root_dir)

    @Marshalling.handles(GUIDS)
    @Marshalling.args()
    @Marshalling.retval( Marshalling.pickled_data )
    def guids(self):
        return self._experiment.guids

    @Marshalling.handles(STARTED_TIME)
    @Marshalling.args()
    @Marshalling.retval( Marshalling.pickled_data )
    def started_time(self):
        return self._experiment.started_time

    @Marshalling.handles(STOPPED_TIME)
    @Marshalling.args()
    @Marshalling.retval( Marshalling.pickled_data )
    def stopped_time(self):
        return self._experiment.stopped_time

    @Marshalling.handles(XML)
    @Marshalling.args()
    @Marshalling.retval()
    def experiment_design_xml(self):
        return self._experiment.experiment_design_xml
        
    @Marshalling.handles(EXEC_XML)
    @Marshalling.args()
    @Marshalling.retval()
    def experiment_execute_xml(self):
        return self._experiment.experiment_execute_xml
        
    @Marshalling.handles(TRACE)
    @Marshalling.args(int, str, Marshalling.base64_data)
    @Marshalling.retval()
    def trace(self, guid, trace_id, attribute):
        return str(self._experiment.trace(guid, trace_id, attribute))

    @Marshalling.handles(TRACES_INFO)
    @Marshalling.args()
    @Marshalling.retval( Marshalling.pickled_data )
    def traces_info(self):
        return self._experiment.traces_info()

    @Marshalling.handles(FINISHED)
    @Marshalling.args(int)
    @Marshalling.retval(Marshalling.bool)
    def is_finished(self, guid):
        return self._experiment.is_finished(guid)

    @Marshalling.handles(STATUS)
    @Marshalling.args(int)
    @Marshalling.retval(int)
    def status(self, guid):
        return self._experiment.status(guid)

    @Marshalling.handles(GET)
    @Marshalling.args(int, Marshalling.base64_data, str)
    @Marshalling.retval( Marshalling.pickled_data )
    def get(self, guid, name, time):
        return self._experiment.get(guid, name, time)

    @Marshalling.handles(SET)
    @Marshalling.args(int, Marshalling.base64_data, Marshalling.pickled_data, str)
    @Marshalling.retvoid
    def set(self, guid, name, value, time):
        self._experiment.set(guid, name, value, time)

    @Marshalling.handles(START)
    @Marshalling.args()
    @Marshalling.retvoid
    def start(self):
        self._experiment.start()

    @Marshalling.handles(STOP)
    @Marshalling.args()
    @Marshalling.retvoid
    def stop(self):
        self._experiment.stop()

    @Marshalling.handles(RECOVER)
    @Marshalling.args()
    @Marshalling.retvoid
    def recover(self):
        self._experiment.recover()

    @Marshalling.handles(SHUTDOWN)
    @Marshalling.args()
    @Marshalling.retvoid
    def shutdown(self):
        self._experiment.shutdown()

    @Marshalling.handles(GET_TESTBED_ID)
    @Marshalling.args(int)
    @Marshalling.retval()
    def get_testbed_id(self, guid):
        return self._experiment.get_testbed_id(guid)

    @Marshalling.handles(GET_FACTORY_ID)
    @Marshalling.args(int)
    @Marshalling.retval()
    def get_factory_id(self, guid):
        return self._experiment.get_factory_id(guid)

    @Marshalling.handles(GET_TESTBED_VERSION)
    @Marshalling.args(int)
    @Marshalling.retval()
    def get_testbed_version(self, guid):
        return self._experiment.get_testbed_version(guid)
Beispiel #9
0
    def make_pl_overlay(self, numnodes):
        ns3_testbed_id = "ns3"
        
        pl, exp = self.make_experiment_desc()
        
        # We'll make a distribution spanning tree using prefix matching as a distance
        api = plutil.getAPI(self.pluser, self.plpass, hostname=self.plchost)
        nodes = plutil.getNodes(api, numnodes, operatingSystem = 'f12')
        root = min(nodes, key=operator.attrgetter('hostname'))
        links = list(plutil.getSpanningTree(nodes, root=root))
        
        for node in nodes:
            node.vif_ips = set()
            node.children = []
            node.childips = set()
        
        # Build an explicit tree
        for slave, master in links:
            master.children.append(slave)
        
        # We have to assign IPs and routes.
        # The IP will be assigned sequentially, depth-first.
        # This will result in rather compact routing rules
        nextip = [128-numnodes]
        def traverse(traverse, node, parent=None, base=struct.unpack('!L',socket.inet_aton(self.vnet))[0]):
            if nextip[0] >= 254:
                raise RuntimeError, "Too many IPs to assign!"
            
            node.vif_addr = base | (nextip[0])
            nips = 1+len(node.children) # one vif per child, plus one for the parent
            nextip[0] += nips
            
            for i in xrange(nips):
                node.vif_ips.add(node.vif_addr+i)

            if parent:
                parent.childips.update(node.vif_ips)

            for i,child in enumerate(node.children):
                traverse(traverse, child, node, base)
                
            if parent:
                parent.childips.update(node.childips)
                
        traverse(traverse, root)
        
        def printtree(printtree, node, indent=''):
            print indent, '-', socket.inet_ntoa(struct.pack('!L',node.vif_addr)), '\t', node.country, node.city, node.site, '\t', node.hostname
            for child in node.children:
                childips = map(ipaddr.IPAddress, child.childips)
                childnets = ipaddr.collapse_address_list(childips)
                cip = ipaddr.IPAddress(child.vif_addr)
                for cnet in childnets:
                    print indent, '|- R', cnet, '->', cip
                printtree(printtree, child, indent+' | ')
        printtree(printtree, root)

        inet = pl.create("Internet")

        ns_chosen = []
        leaves = []

        def maketree(maketree, node, parent=None, parentIp=None):
            routes = []
            ctaps = []
            for i,child in enumerate(node.children):
                childips = map(ipaddr.IPAddress, child.childips)
                childnets = ipaddr.collapse_address_list(childips)
                cip = ipaddr.IPAddress(child.vif_addr)
                pip = ipaddr.IPAddress(node.vif_addr+1+i)
                for cnet in childnets:
                    routes.append((cnet.ip.exploded, cnet.prefixlen, cip.exploded))
                ctaps.append( maketree(maketree, child, node, pip) )
            if parentIp:
                routes.append((self.vnet,24,parentIp))
            
            if not parent:
                label = "root"
            else:
                label = None
                
            # NS node, first leaf
            if not ns_chosen and not node.children:
                ns_chosen.append(True)
                label = "ns_root"
                
            ips = [ ipaddr.IPAddress(node.vif_addr+i) for i in xrange(1+len(node.children)) ]
            node1, iface1, tap1, tap1ip, _ = self.make_pl_tapnode(pl, ips, inet, 
                hostname = node.hostname,
                routes = routes,
                mcastrouter = bool(node.children),
                mcast = True,
                label = label,
                types = ( [ "TapInterface" ] * len(ips) if parent else [ "TunInterface" ] + [ "TapInterface" ] * (len(ips)-1) ) 
                )
            
            for tap, ctap in zip(tap1[1:], ctaps):
                tap.connector("udp").connect(ctap.connector("udp"))
            
            # Store leaves
            if not node.children:
                leaves.append((node, node1))
            
            self.add_net_monitor(pl, node1)
            self.add_vlc_dumper(pl, node1)
            self.add_vlc_restreamer(pl, node1)
            #if not parent:
            #    taplabels = [
            #        t.get_attribute_value("label")
            #        for t in tap1[1:]
            #    ]
            #    self.add_vlc_source(pl, node1, taplabels)
            
            return tap1[0]
        roottap = maketree(maketree, root)

        vnet_i = int(ipaddr.IPAddress(self.vnet))

        ## NS3 ##
        pl_ns_root = exp.get_element_by_label("ns_root")
        pl_ns_root_iface = exp.get_element_by_label("ns_rootiface")
        ns = self.make_ns_in_pl(pl, exp, pl_ns_root, pl_ns_root_iface, "ns3")
        wifi_chan = self.add_ns_wifi_channel(ns)

        # AP node
        ap_node = self.add_ns_node(ns)
        self.add_ns_constant_mobility(ns, ap_node, 0, 0, 0)
        ap_wifi, ap_phy = self.add_ns_wifi_dev(ns, ap_node, access_point = True)
        ap_phy.connector("chan").connect(wifi_chan.connector("phys"))

        # Net range free for WiFi
        wifi_net_prefix = 32-int(math.floor(math.log(256-nextip[0]&0xff) / math.log(2)))
        wifi_net = vnet_i | (256 - (1<<(32-wifi_net_prefix)))

        # connect AP to PL
        pl_addr = str(ipaddr.IPAddress(wifi_net | 1))
        ns_addr = str(ipaddr.IPAddress(wifi_net | 2))
        self.add_pl_ns_connection(
            pl, pl_ns_root, pl_addr, 
            ns, ap_node, ns_addr, 
            fd = True, ptp = True, prefix=30)

        
        # AP ip
        ap_addr = str(ipaddr.IPAddress(vnet_i | 254))
        ap_addr_prefix = 32-int(math.ceil(math.log(self.nsta+3) / math.log(2)))
        self.add_ip_address(ap_wifi, ap_addr, ap_addr_prefix)
        
        # route for PL->wifi
        self.add_route(pl_ns_root, 
            str(ipaddr.IPAddress(wifi_net)), wifi_net_prefix,
            ns_addr)
        
        print "NS-3 AP\t%s/%s <--> PL AP %s" % (ns_addr, 30, pl_addr)
        print " | (|) %s/%s" % (ap_addr, ap_addr_prefix)
        print " |"
        print " |                  R %s/%d --> %s" % (str(ipaddr.IPAddress(wifi_net)), wifi_net_prefix, ns_addr)
       
        nextpip = (vnet_i | 255) >> (32-ap_addr_prefix) << (32-ap_addr_prefix)
        nextdip = vnet_i | 253
        ap_net = nextpip - (1<<(32-ap_addr_prefix))
        r = 50
        # STA nodes
        for i in xrange(self.nsta):
            stai = self.add_ns_node(ns)
            angi = (360/self.nsta)*i
            xi = r*math.cos(angi)
            yi = r*math.sin(angi)
            self.add_ns_constant_mobility(ns, stai, xi, yi, 0)
            wifi, phy = self.add_ns_wifi_dev(ns, stai, access_point = False)
            phy.connector("chan").connect(wifi_chan.connector("phys"))
            
            wifi_addr = str(ipaddr.IPAddress(vnet_i | nextdip))
            nextdip -= 1

            nextpip -= 4
            while nextpip & 3:
                nextpip -= 1
            plns_net_i = nextpip
            plns_net = str(ipaddr.IPAddress(plns_net_i))
            pl_addr2 = str(ipaddr.IPAddress(plns_net_i | 1))
            ns_addr2 = str(ipaddr.IPAddress(plns_net_i | 2))

            # route from AP (after others)
            print " | R %s/%s -> %s" % ( plns_net,30,ns_addr2 )
            self.add_route(ap_node, plns_net, 30, wifi_addr)

            print " +---\t(|) %16s/%s" % (wifi_addr,ap_addr_prefix)
            print " |         %16s (ns3) <---> (pl) %16s/30" % (ns_addr2, pl_addr2)
            print " |\t       \t\t                 <--  R %s/24" % (self.vnet, )
            print " |\t       \t R %s/30 -> %s" % (plns_net, pl_addr2)
            print " |\t       \t R %s <-- %s/24" % (ap_addr, plns_net)

            self.add_ip_address(wifi, wifi_addr, ap_addr_prefix)
            self.add_route(stai, plns_net, 30, pl_addr2)
            self.add_route(stai, self.vnet, 24, ap_addr)
            
            pl_nodei, _, pl_ifacei, _, _ = self.make_pl_tapnode(pl, [], inet, 
                routes = [(self.vnet, 24, ns_addr2)],
                mcast = False,
                label = "ns_plnode_%d" % (i+1,)
                )
 
            self.add_pl_ns_connection(
                pl, pl_nodei, pl_addr2,
                ns, stai, ns_addr2,
                prefix = 30)
            
            self.add_vlc_dumper(pl, pl_nodei,
                hostname = pl_addr,
                labelprefix = "vlc_dumper_ns",
                precmd = "sleep 15 ; ")

            # Validate (post-fact to let the user see the diagram above)
            if nextpip < wifi_net:
                raise RuntimeError, "Not enough IPs for wifi section"
        
        # route back to PL (after others)
        print " | R %s/%s -> %s" % ( self.vnet,24,pl_addr )
        self.add_route(ap_node, self.vnet, 24, pl_addr)


        ## NETNS ##
        netns_addr = str(ipaddr.IPAddress(vnet_i | 1))

        root1 = exp.get_element_by_label("root")
        netns = self.make_netns_testbed(exp)
        netns_node = self.add_netns_node(netns)
        netns_term = self.add_netns_app(netns, "xterm", netns_node)
        if self.movie_source:
            cmd = (
                "vlc -I dummy "
                +os.path.abspath(self.movie_source)
                +" --sout '#std{access=udp{ttl=64,miface-addr="+netns_addr+"},dst=239.255.12.42,mux=ts}'"
            )
        else:
            cmd = self.movie_command % {
                "dst" : "std{access=udp{ttl=64,miface-addr="+netns_addr+"},dst=239.255.12.42,mux=ts}"
            }
        netns_vlc  = self.add_netns_app(netns, cmd, netns_node)
        
        # connection PL1/NETNS
        self.add_pl_netns_connection(
            roottap,
            netns, netns_node, netns_addr,
            24,
            taplabel="netns_source")
        self.add_route(netns_node, 
            "0.0.0.0", 0, 
            str(ipaddr.IPAddress(root.vif_addr)) )
        
        # pick random hostname to stream from
        interactive_source_host = random.sample(leaves,1)[0][0].hostname

        xml = exp.to_xml()
        test_dir = "./results"
        #sys.exit(1)

        try:
            controller = ExperimentController(xml, self.root_dir)
            controller.start()
            
            # launch vlc client to monitor activity
            time.sleep(5)
            proc = subprocess.Popen([
                "vlc", "-I", "dummy", "http://%s:8080" % (interactive_source_host,)])
            
            print >>sys.stderr, "Close xterm to shut down or Ctrl+C"
            try:
                while not controller.is_finished(netns_term.guid):
                    time.sleep(5)
            except KeyboardInterrupt:
                # ping netns
                try:
                    controller.traces_info()
                except:
                    pass
                try:
                    controller.traces_info()
                except:
                    pass
            
            # kill streamer
            os.kill(proc.pid, signal.SIGTERM)
            
            # download results
            traces_info = controller.traces_info()
            for progress, (testbed_guid, guids) in enumerate(traces_info.iteritems()):
                for subprogress, (guid, traces) in enumerate(guids.iteritems()):
                    for name, data in traces.iteritems():
                        path = data["filepath"]
                        elem = exp.get_element(guid)
                        if elem is not None:
                            label = elem.get_attribute_value("label")
                            if label is not None:
                                path = "%s-%s" % (label,path)
                        
                        if not path:
                            continue
                        
                        print >>sys.stderr, ("%.2f%% Downloading trace" % (progress + (subprogress * 1.0 / len(guids)) * 100.0 / len(traces_info))), path
                        
                        filepath = os.path.join(test_dir, path)
                        
                        try:
                            trace = controller.trace(guid, name)
                        except:
                            traceback.print_exc(file=sys.stderr)
                            continue
                        try:
                            if not os.path.exists(os.path.dirname(filepath)):
                                os.makedirs(os.path.dirname(filepath))
                        except:
                            traceback.print_exc(file=sys.stderr)
                        
                        try:
                            if len(trace) >= 2**20:
                                # Bigger than 1M, compress
                                tracefile = gzip.GzipFile(filepath+".gz", "wb")
                            else:
                                tracefile = open(filepath,"wb")
                            try:
                                tracefile.write(trace)
                            finally:
                                tracefile.close()
                        except:
                            traceback.print_exc(file=sys.stderr)
        finally:
            try:
                controller.stop()
            except:
                traceback.print_exc()
            try:
                controller.shutdown()
            except:
                traceback.print_exc()
Beispiel #10
0
    def _test_plpl_crossconnect(self, proto, recover=False):
        pl, pl2, exp = self.make_experiment_desc()

        if recover:
            pl.set_attribute_value(DC.RECOVERY_POLICY, DC.POLICY_RECOVER)
            pl2.set_attribute_value(DC.RECOVERY_POLICY, DC.POLICY_RECOVER)

        # Create PL node, ifaces, assign addresses
        node1, iface1, tap1, tap1ip, inet1 = self.make_pl_tapnode(pl, self.plcvnet1 + ".2", self.host1pl1, "node1")
        node2, iface2, tap2, tap2ip, inet2 = self.make_pl_tapnode(pl2, self.plcvnet2 + ".3", self.host1pl2, "node2")

        # Connect the two
        tap1.connector(proto).connect(tap2.connector(proto))
        tap1.set_attribute_value("pointopoint", "{#[node2tap].addr[0].[Address]#}")
        tap2.set_attribute_value("pointopoint", "{#[node1tap].addr[0].[Address]#}")

        # Disable encryption for GRE
        if proto == "gre":
            tap1.set_attribute_value("tun_cipher", "PLAIN")
            tap2.set_attribute_value("tun_cipher", "PLAIN")

        # Create PlanetLab ping application, pinging the from one PL to another
        ping = pl.create("Application")
        ping.set_attribute_value("command", "ping -qc10 {#[node2tap].addr[0].[Address]#}")
        ping.enable_trace("stdout")
        ping.enable_trace("stderr")
        ping.connector("node").connect(node1.connector("apps"))

        comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data.

--- .* ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time \d*ms.*
"""

        xml = exp.to_xml()

        try:
            controller = ExperimentController(xml, self.root_dir)
            controller.start()

            if recover:
                controller = None
                controller = ExperimentController(None, self.root_dir)
                controller.recover()

            while not controller.is_finished(ping.guid):
                time.sleep(0.5)

            ping_result = controller.trace(ping.guid, "stdout")
            tap_trace = controller.trace(tap1.guid, "packets")
            tap2_trace = controller.trace(tap2.guid, "packets")

        finally:
            if controller is not None:
                try:
                    controller.stop()
                except:
                    import traceback

                    traceback.print_exc()
                try:
                    controller.shutdown()
                except:
                    import traceback

                    traceback.print_exc()

        # asserts at the end, to make sure there's proper cleanup
        self.assertTrue(
            re.match(comp_result, ping_result, re.MULTILINE),
            "Unexpected trace:\n%s\nTap trace at origin:\n%s\nTap trace at destination:\n%s\n"
            % (ping_result, tap_trace, tap2_trace),
        )
Beispiel #11
0
    def _test_plpl_crossconnect(self, proto, recover=False):
        pl, pl2, exp = self.make_experiment_desc()

        if recover:
            pl.set_attribute_value(DC.RECOVERY_POLICY, DC.POLICY_RECOVER)
            pl2.set_attribute_value(DC.RECOVERY_POLICY, DC.POLICY_RECOVER)

        # Create PL node, ifaces, assign addresses
        node1, iface1, tap1, tap1ip, inet1 = self.make_pl_tapnode(
            pl, self.plcvnet1 + ".2", self.host1pl1, "node1")
        node2, iface2, tap2, tap2ip, inet2 = self.make_pl_tapnode(
            pl2, self.plcvnet2 + ".3", self.host1pl2, "node2")

        # Connect the two
        tap1.connector(proto).connect(tap2.connector(proto))
        tap1.set_attribute_value("pointopoint",
                                 "{#[node2tap].addr[0].[Address]#}")
        tap2.set_attribute_value("pointopoint",
                                 "{#[node1tap].addr[0].[Address]#}")

        # Disable encryption for GRE
        if proto == "gre":
            tap1.set_attribute_value("tun_cipher", "PLAIN")
            tap2.set_attribute_value("tun_cipher", "PLAIN")

        # Create PlanetLab ping application, pinging the from one PL to another
        ping = pl.create("Application")
        ping.set_attribute_value(
            "command", "ping -qc10 {#[node2tap].addr[0].[Address]#}")
        ping.enable_trace("stdout")
        ping.enable_trace("stderr")
        ping.connector("node").connect(node1.connector("apps"))

        comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data.

--- .* ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time \d*ms.*
"""

        xml = exp.to_xml()

        try:
            controller = ExperimentController(xml, self.root_dir)
            controller.start()

            if recover:
                controller = None
                controller = ExperimentController(None, self.root_dir)
                controller.recover()

            while not controller.is_finished(ping.guid):
                time.sleep(0.5)

            ping_result = controller.trace(ping.guid, "stdout")
            tap_trace = controller.trace(tap1.guid, "packets")
            tap2_trace = controller.trace(tap2.guid, "packets")

        finally:
            if controller is not None:
                try:
                    controller.stop()
                except:
                    import traceback
                    traceback.print_exc()
                try:
                    controller.shutdown()
                except:
                    import traceback
                    traceback.print_exc()

        # asserts at the end, to make sure there's proper cleanup
        self.assertTrue(
            re.match(comp_result, ping_result, re.MULTILINE),
            "Unexpected trace:\n%s\nTap trace at origin:\n%s\nTap trace at destination:\n%s\n"
            % (ping_result, tap_trace, tap2_trace))
Beispiel #12
0
    def _test_ns3_in_pl_p2p(self, proto):
        pl, exp = self.make_experiment_desc()
        
        # Create PL node, ifaces, assign addresses
        node1, iface1, (tap0,tap1), (tap0ip,tap1ip), inet = self.make_pl_tapnode(pl, 
            label="node1", hostname = self.host1,
            ip=["192.168.2.2","192.168.2.5"])
        node2, iface2, (tap2,tap3), (tap2ip,tap3ip), inet = self.make_pl_tapnode(pl, inet=inet, 
            label="node2", hostname = self.host2,
            ip=["192.168.2.6","192.168.2.9"])
        node3, iface3, tap4, tap4ip, inet = self.make_pl_tapnode(pl, inet=inet, 
            label="node3", hostname = self.host3,
            ip="192.168.2.10")
        
        # Add NS3 support in node1
        ns3_desc = self.make_ns_in_pl(pl, exp, node1, iface1, "tb-ns3-4-%s" % (proto,))
        
        # Configure P2P links
        tap0.set_attribute_value("pointopoint", "192.168.2.1") # cross-p2p is not automatic
        tap1.connector(proto).connect(tap2.connector(proto))
        tap3.connector(proto).connect(tap4.connector(proto))
        
        # Configure routes
        r = node1.add_route()
        r.set_attribute_value("Destination", "192.168.2.8")
        r.set_attribute_value("NetPrefix", 29)
        r.set_attribute_value("NextHop", "192.168.2.6")

        r = node2.add_route()
        r.set_attribute_value("Destination", "192.168.2.0")
        r.set_attribute_value("NetPrefix", 29)
        r.set_attribute_value("NextHop", "192.168.2.5")

        r = node3.add_route()
        r.set_attribute_value("Destination", "192.168.2.0")
        r.set_attribute_value("NetPrefix", 29)
        r.set_attribute_value("NextHop", "192.168.2.9")
        
        # Create NS3 node that is responsive to pings, connected
        # to node1 through the Tap interface
        ns1 = ns3_desc.create("ns3::Node")
        ipv41 = ns3_desc.create("ns3::Ipv4L3Protocol")
        arp1  = ns3_desc.create("ns3::ArpL3Protocol")
        icmp1 = ns3_desc.create("ns3::Icmpv4L4Protocol")
        ns1.connector("protos").connect(ipv41.connector("node"))
        ns1.connector("protos").connect(arp1.connector("node"))
        ns1.connector("protos").connect(icmp1.connector("node"))
        ns1if = ns3_desc.create("ns3::FdNetDevice")
        ns1if.enable_trace("FdPcapTrace")
        ns1if.set_attribute_value("label", "ns1if")
        ns1.connector("devs").connect(ns1if.connector("node"))
        tap0.connector("fd->").connect(ns1if.connector("->fd"))
        tap0.set_attribute_value("tun_cipher", "PLAIN")
        ip1 = ns1if.add_address()
        ip1.set_attribute_value("Address", "192.168.2.1")
        ip1.set_attribute_value("NetPrefix", 30)
        ip1.set_attribute_value("Broadcast", False)
        
        # Add default route to the PL node
        r1 = ns1.add_route()
        r1.set_attribute_value("Destination", "0.0.0.0")
        r1.set_attribute_value("NetPrefix", 0)
        r1.set_attribute_value("NextHop", "192.168.2.2")

        # Create NS3 ping application, pinging the PL node
        ping = ns3_desc.create("ns3::V4Ping")
        ping.set_attribute_value("Remote", "{#[node3tap].addr[0].[Address]#}")
        ping.set_attribute_value("StartTime", "0s")
        ping.set_attribute_value("StopTime", "10s")
        ping.connector("node").connect(ns1.connector("apps"))

        xml = exp.to_xml()

        try:
            controller = ExperimentController(xml, self.root_dir)
            controller.start()

            while not controller.is_finished(ping.guid):
                time.sleep(0.5)

            tap_trace = []
            for i,tap in enumerate([ tap0, tap1, tap2, tap3, tap4 ]):
                tap_trace.append("\nTrace for tap%d:\n" % i)
                tap_trace.append(controller.trace(tap.guid, "packets"))
            tap_trace = "".join(tap_trace)
            tap0_trace = controller.trace(tap0.guid, "packets")

        finally:
            try:
                controller.stop()
            except:
                import traceback
                traceback.print_exc()
            try:
                controller.shutdown()
            except:
                import traceback
                traceback.print_exc()
        
        # asserts at the end, to make sure there's proper cleanup
        sent = 0
        replied = 0
        for seq in xrange(10):
            re_send = r""".*
[0-9.:]* IP 192.168.2.1 > (\d*\.){3}\d*: ICMP echo request, id 0, seq %(seq)d, length \d*
.*""" % dict(seq=seq)

            re_reply = r""".*
[0-9.:]* IP 192.168.2.1 > (\d*\.){3}\d*: ICMP echo request, id 0, seq %(seq)d, length \d*.*
[0-9.:]* IP (\d*\.){3}\d* > 192.168.2.1: ICMP echo reply, id 0, seq %(seq)d, length \d*
.*""" % dict(seq=seq)

            sent += bool(re.match(re_send, tap0_trace, re.MULTILINE|re.DOTALL))
            replied += bool(re.match(re_reply, tap0_trace, re.MULTILINE|re.DOTALL))

        self.assertTrue(replied >= sent/2 and sent > 5,
            "Unexpected trace:\n%s\n" % (
                tap_trace,) )
Beispiel #13
0
    def test_ns3_in_pl_snat(self):
        pl, exp = self.make_experiment_desc()
        
        # Create PL node, ifaces, assign addresses
        node1, iface1, tap1, tap1ip, inet = self.make_pl_tapnode(pl)
        
        # Add NS3 support in node1
        ns3_desc = self.make_ns_in_pl(pl, exp, node1, iface1, "tb-ns3-3")
        
        # Enable SNAT
        tap1.set_attribute_value("snat", True)
        
        # Add second PL node (ping target)
        node2 = pl.create("Node")
        node2.set_attribute_value("hostname", self.host2)
        node2.set_attribute_value("label", "node2")
        iface2 = pl.create("NodeInterface")
        iface2.set_attribute_value("label", "node2iface")
        node2.connector("devs").connect(iface2.connector("node"))
        iface2.connector("inet").connect(inet.connector("devs"))
        
        # Create NS3 node that is responsive to pings, connected
        # to node1 through the Tap interface
        ns1 = ns3_desc.create("ns3::Node")
        ipv41 = ns3_desc.create("ns3::Ipv4L3Protocol")
        arp1  = ns3_desc.create("ns3::ArpL3Protocol")
        icmp1 = ns3_desc.create("ns3::Icmpv4L4Protocol")
        ns1.connector("protos").connect(ipv41.connector("node"))
        ns1.connector("protos").connect(arp1.connector("node"))
        ns1.connector("protos").connect(icmp1.connector("node"))
        ns1if = ns3_desc.create("ns3::FdNetDevice")
        ns1if.enable_trace("FdPcapTrace")
        ns1if.set_attribute_value("label", "ns1if")
        ns1.connector("devs").connect(ns1if.connector("node"))
        tap1.connector("fd->").connect(ns1if.connector("->fd"))
        tap1.set_attribute_value("tun_cipher", "PLAIN")
        ip1 = ns1if.add_address()
        ip1.set_attribute_value("Address", "192.168.2.3")
        ip1.set_attribute_value("NetPrefix", 24)
        ip1.set_attribute_value("Broadcast", False)
        
        # Add default route to the PL node
        r1 = ns1.add_route()
        r1.set_attribute_value("Destination", "0.0.0.0")
        r1.set_attribute_value("NetPrefix", 0)
        r1.set_attribute_value("NextHop", "192.168.2.2")

        # Create NS3 ping application, pinging the PL node
        ping = ns3_desc.create("ns3::V4Ping")
        ping.set_attribute_value("Remote", "{#[node2iface].addr[0].[Address]#}")
        ping.set_attribute_value("StartTime", "0s")
        ping.set_attribute_value("StopTime", "10s")
        ping.connector("node").connect(ns1.connector("apps"))

        xml = exp.to_xml()

        try:
            controller = ExperimentController(xml, self.root_dir)
            controller.start()

            while not controller.is_finished(ping.guid):
                time.sleep(0.5)
              
            tap_trace = controller.trace(tap1.guid, "packets")

        finally:
            try:
                controller.stop()
            except:
                import traceback
                traceback.print_exc()
            try:
                controller.shutdown()
            except:
                import traceback
                traceback.print_exc()
        
        # asserts at the end, to make sure there's proper cleanup
        sent = 0
        replied = 0
        for seq in xrange(10):
            re_send = r""".*
[0-9.:]* IP 192.168.2.3 > (\d*\.){3}\d*: ICMP echo request, id 0, seq %(seq)d, length \d*
.*""" % dict(seq=seq)

            re_reply = r""".*
[0-9.:]* IP 192.168.2.3 > (\d*\.){3}\d*: ICMP echo request, id 0, seq %(seq)d, length \d*.*
[0-9.:]* IP (\d*\.){3}\d* > 192.168.2.3: ICMP echo reply, id 0, seq %(seq)d, length \d*
.*""" % dict(seq=seq)

            sent += bool(re.match(re_send, tap_trace, re.MULTILINE|re.DOTALL))
            replied += bool(re.match(re_reply, tap_trace, re.MULTILINE|re.DOTALL))

        self.assertTrue(sent == replied and sent > 5,
            "Unexpected trace:\n%s\n" % (
                tap_trace,) )
Beispiel #14
0
    def _test_simple(self,
                     daemonize_testbed,
                     controller_access_configuration,
                     environ=None,
                     use_sfa=False):
        pl, exp = self.make_experiment_desc(use_sfa)

        node1 = pl.create("Node")
        node2 = pl.create("Node")
        node1.set_attribute_value("hostname", self.host1)
        node2.set_attribute_value("hostname", self.host2)
        iface1 = pl.create("NodeInterface")
        iface2 = pl.create("NodeInterface")
        iface2.set_attribute_value("label", "node2iface")
        inet = pl.create("Internet")
        node1.connector("devs").connect(iface1.connector("node"))
        node2.connector("devs").connect(iface2.connector("node"))
        iface1.connector("inet").connect(inet.connector("devs"))
        iface2.connector("inet").connect(inet.connector("devs"))
        app = pl.create("Application")
        app.set_attribute_value(
            "command", "ping -qc1 {#[node2iface].addr[0].[Address]#}")
        app.enable_trace("stdout")
        app.connector("node").connect(node1.connector("apps"))

        if daemonize_testbed:
            pl.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
            inst_root_dir = os.path.join(self.root_dir, "instance")
            os.mkdir(inst_root_dir)
            pl.set_attribute_value(DC.ROOT_DIRECTORY, inst_root_dir)
            pl.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)

            if environ:
                pl.set_attribute_value(DC.DEPLOYMENT_ENVIRONMENT_SETUP,
                                       environ)

        xml = exp.to_xml()

        if controller_access_configuration:
            controller = proxy.create_experiment_controller(
                xml, controller_access_configuration)
        else:
            controller = ExperimentController(xml, self.root_dir)

        try:
            controller.start()
            while not controller.is_finished(app.guid):
                time.sleep(0.5)
            ping_result = controller.trace(app.guid, "stdout")
            comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data.

--- .* ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time \d*ms.*
"""
            self.assertTrue(re.match(comp_result, ping_result, re.MULTILINE),
                            "Unexpected trace:\n" + ping_result)

        finally:
            try:
                controller.stop()
            except:
                import traceback
                traceback.print_exc()
            try:
                controller.shutdown()
            except:
                import traceback
                traceback.print_exc()
Beispiel #15
0
    def run(self, duration, xml_filepath, testset, results_dir, iteration):
        app_guid = 8

        testset_dir = os.path.join(results_dir, testset)

        # create test results file
        test_dir = os.path.join(testset_dir, str(iteration))

        # replace results values in xml
        replacements = cPickle.loads(
            os.environ['POPI_REPLACEMENTS'].strip().decode("base64"))
        file = open(xml_filepath)
        xml2 = xml = file.read()
        file.close()

        for key, value in replacements.iteritems():
            xml2 = xml2.replace("##%s##" % (key, ), value)

        # launch experiment
        controller = ExperimentController(xml2, results_dir)

        try:
            controller.start()

            t0 = time.time()
            t1 = t0
            while (t1 -
                   t0) < duration and not controller.is_finished(app_guid):
                time.sleep(10)

            # download results
            for testbed_guid, guids in controller.traces_info().iteritems():
                for guid, traces in guids.iteritems():
                    for name, data in traces.iteritems():
                        path = data["filepath"]
                        print >> sys.stderr, "Downloading trace", path

                        filepath = os.path.join(test_dir, path)

                        try:
                            trace = controller.trace(guid, name)
                        except:
                            traceback.print_exc(file=sys.stderr)
                            continue
                        try:
                            if not os.path.exists(os.path.dirname(filepath)):
                                os.makedirs(os.path.dirname(filepath))
                        except:
                            traceback.print_exc(file=sys.stderr)

                        try:
                            if len(trace) >= 2**20:
                                # Bigger than 1M, compress
                                tracefile = gzip.GzipFile(
                                    filepath + ".gz", "wb")
                            else:
                                tracefile = open(filepath, "wb")
                            try:
                                tracefile.write(trace)
                            finally:
                                tracefile.close()
                        except:
                            traceback.print_exc(file=sys.stderr)

        finally:
            # clean up
            try:
                controller.stop()
            except:
                pass
            try:
                controller.shutdown()
            except:
                pass
Beispiel #16
0
    def _test_plns3_crossconnect(self, proto):
        pl, pl2, exp = self.make_experiment_desc()

        # Create PL node, ifaces, assign addresses
        node1, iface1, _, _, inet1 = self.make_pl_tapnode(
            pl, None, self.host1pl1, "node1")
        node2, iface2, tap2, tap2ip, inet2 = self.make_pl_tapnode(
            pl2, "192.168.2.3", self.host1pl2, "node2")

        # Create NS3 instance in node1
        # With a node and all required protocols to be pinged
        ns3 = self.make_ns_in_pl(pl, exp, node1, iface1, "tb-ns-rcross-1")

        ns1 = ns3.create("ns3::Node")
        ipv41 = ns3.create("ns3::Ipv4L3Protocol")
        arp1 = ns3.create("ns3::ArpL3Protocol")
        icmp1 = ns3.create("ns3::Icmpv4L4Protocol")
        ns1.connector("protos").connect(ipv41.connector("node"))
        ns1.connector("protos").connect(arp1.connector("node"))
        ns1.connector("protos").connect(icmp1.connector("node"))
        ns1if = ns3.create("ns3::FdNetDevice")
        ns1if.enable_trace("FdPcapTrace")
        ns1if.set_attribute_value("label", "ns1if")
        ns1tc = ns3.create("ns3::Nepi::TunChannel")
        ns1.connector("devs").connect(ns1if.connector("node"))
        ns1tc.connector("fd->").connect(ns1if.connector("->fd"))
        ip1 = ns1if.add_address()
        ip1.set_attribute_value("Address", "192.168.2.2")
        ip1.set_attribute_value("NetPrefix", 24)
        ip1.set_attribute_value("Broadcast", False)

        # Connect the two
        tap2.connector(proto).connect(ns1tc.connector(proto))

        # Create PlanetLab ping application, pinging the from one PL to another
        ping = pl2.create("Application")
        ping.set_attribute_value("command",
                                 "ping -qc10 {#[ns1if].addr[0].[Address]#}")
        ping.enable_trace("stdout")
        ping.enable_trace("stderr")
        ping.connector("node").connect(node2.connector("apps"))

        comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data.

--- .* ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time \d*ms.*
"""

        xml = exp.to_xml()

        controller = ExperimentController(xml, self.root_dir)

        try:
            controller.start()

            while not controller.is_finished(ping.guid):
                time.sleep(0.5)

            ping_result = controller.trace(ping.guid, "stdout")
            tap2_trace = controller.trace(tap2.guid, "packets")
        finally:
            try:
                controller.stop()
            except:
                import traceback
                traceback.print_exc()
            try:
                controller.shutdown()
            except:
                import traceback
                traceback.print_exc()

        # asserts at the end, to make sure there's proper cleanup
        self.assertTrue(
            re.match(comp_result, ping_result,
                     re.MULTILINE), "Unexpected trace:\n%s\nTap trace:\n%s\n" %
            (ping_result, tap2_trace))
route = node3.add_route()
route.set_attribute_value("Destination", "10.0.0.0")
route.set_attribute_value("NextHop", "10.0.1.1")

route = node4.add_route()
route.set_attribute_value("Destination", "10.0.0.0")
route.set_attribute_value("NextHop", "10.0.2.1")

app = netns_desc.create("Application")
app.set_attribute_value("command", "ping -qc 3 10.0.0.1")
app.set_attribute_value("user", user)
app.connector("node").connect(node4.connector("apps"))
app.enable_trace("stdout")
      
xml = exp_desc.to_xml()

controller = ExperimentController(xml, root_dir)

controller.start()
while not controller.is_finished(app.guid):
    time.sleep(0.5)

result = controller.trace(app.guid, "stdout")

controller.stop()
controller.shutdown()

print result

Beispiel #18
0
    def _test_if(self, daemonize_testbed, controller_access_configuration):
        exp_desc = ExperimentDescription()
        testbed_id = "ns3"
        ns3_provider = FactoriesProvider(testbed_id)
        ns3_desc = exp_desc.add_testbed_description(ns3_provider)
        ns3_desc.set_attribute_value("homeDirectory", self.root_dir)

        node1 = ns3_desc.create("ns3::Node")
        ipv41 = ns3_desc.create("ns3::Ipv4L3Protocol")
        arp1  = ns3_desc.create("ns3::ArpL3Protocol")
        icmp1 = ns3_desc.create("ns3::Icmpv4L4Protocol")
        node1.connector("protos").connect(ipv41.connector("node"))
        node1.connector("protos").connect(arp1.connector("node"))
        node1.connector("protos").connect(icmp1.connector("node"))
        iface1 = ns3_desc.create("ns3::PointToPointNetDevice")
        queue1 = ns3_desc.create("ns3::DropTailQueue")
        node1.connector("devs").connect(iface1.connector("node"))
        iface1.connector("queue").connect(queue1.connector("dev"))
        trace1 = iface1.enable_trace("P2PAsciiTrace")
        ip1 = iface1.add_address()
        ip1.set_attribute_value("Address", "10.0.0.1")

        node2 = ns3_desc.create("ns3::Node")
        ipv42 = ns3_desc.create("ns3::Ipv4L3Protocol")
        arp2  = ns3_desc.create("ns3::ArpL3Protocol")
        icmp2 = ns3_desc.create("ns3::Icmpv4L4Protocol")
        node2.connector("protos").connect(ipv42.connector("node"))
        node2.connector("protos").connect(arp2.connector("node"))
        node2.connector("protos").connect(icmp2.connector("node"))
        iface2 = ns3_desc.create("ns3::PointToPointNetDevice")
        queue2 = ns3_desc.create("ns3::DropTailQueue")
        node2.connector("devs").connect(iface2.connector("node"))
        iface2.connector("queue").connect(queue2.connector("dev"))
        trace2 = iface2.enable_trace("P2PAsciiTrace")
        ip2 = iface2.add_address()
        ip2.set_attribute_value("Address", "10.0.0.2")

        chan = ns3_desc.create("ns3::PointToPointChannel")
        iface1.connector("chan").connect(chan.connector("dev2"))
        iface2.connector("chan").connect(chan.connector("dev2"))

        app = ns3_desc.create("ns3::V4Ping")
        app.set_attribute_value("Remote", "10.0.0.2")
        app.set_attribute_value("StartTime", "0s")
        app.set_attribute_value("StopTime", "20s")
        app.connector("node").connect(node1.connector("apps"))

        if daemonize_testbed:
            ns3_desc.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
            inst_root_dir = os.path.join(self.root_dir, "instance")
            os.mkdir(inst_root_dir)
            ns3_desc.set_attribute_value(DC.ROOT_DIRECTORY, inst_root_dir)
            #ns3_desc.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)

        xml = exp_desc.to_xml()
        
        if controller_access_configuration:
            controller = ExperimentController(xml, self.root_dir)
        else:
            controller = proxy.create_experiment_controller(xml, 
                controller_access_configuration)
        
        try:
            controller.start()
            while not controller.is_finished(app.guid):
                time.sleep(0.5)
            ping_result = controller.trace(iface2.guid, "P2PAsciiTrace")

            comp_result = "- 19.021 /NodeList/1/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Dequeue ns3::PppHeader (Point-to-Point Protocol: IP (0x0021)) ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 64 id 19 protocol 1 offset (bytes) 0 flags [none] length: 84 10.0.0.2 > 10.0.0.1) ns3::Icmpv4Header (type=0, code=0) ns3::Icmpv4Echo (identifier=0, sequence=19)"
            
            if ping_result.find(comp_result) == -1:
                self.fail("Unexpected trace: %s" % (ping_result,))
        finally:
            controller.stop()
            controller.shutdown()
Beispiel #19
0
    def _test_spanning_deployment(self, use_sfa=False):
        pl, exp = self.make_experiment_desc(use_sfa)

        pl.set_attribute_value("p2pDeployment", True)  # we do want it here - even if interactive

        from nepi.testbeds import planetlab as plpackage

        nodes = [pl.create("Node") for i in xrange(4)]
        ifaces = [pl.create("NodeInterface") for node in nodes]
        inet = pl.create("Internet")
        for node, iface in zip(nodes, ifaces):
            node.connector("devs").connect(iface.connector("node"))
            iface.connector("inet").connect(inet.connector("devs"))

        apps = []
        for node in nodes:
            app = pl.create("Application")
            app.set_attribute_value("command", "./consts")
            app.set_attribute_value("buildDepends", "gcc")
            app.set_attribute_value("build", "gcc ${SOURCES}/consts.c -o consts")
            app.set_attribute_value("install", "cp consts ${SOURCES}/consts")
            app.set_attribute_value("sources", os.path.join(os.path.dirname(plpackage.__file__), "scripts", "consts.c"))
            app.enable_trace("stdout")
            app.enable_trace("stderr")
            app.enable_trace("buildlog")
            node.connector("apps").connect(app.connector("node"))
            apps.append(app)

        comp_result = r""".*ETH_P_ALL = 0x[0-9a-fA-F]{8}
ETH_P_IP = 0x[0-9a-fA-F]{8}
TUNGETIFF = 0x[0-9a-fA-F]{8}
TUNSETIFF = 0x[0-9a-fA-F]{8}
IFF_NO_PI = 0x[0-9a-fA-F]{8}
IFF_TAP = 0x[0-9a-fA-F]{8}
IFF_TUN = 0x[0-9a-fA-F]{8}
IFF_VNET_HDR = 0x[0-9a-fA-F]{8}
TUN_PKT_STRIP = 0x[0-9a-fA-F]{8}
IFHWADDRLEN = 0x[0-9a-fA-F]{8}
IFNAMSIZ = 0x[0-9a-fA-F]{8}
IFREQ_SZ = 0x[0-9a-fA-F]{8}
FIONREAD = 0x[0-9a-fA-F]{8}.*
"""

        comp_build = r".*(Identity added|gcc).*"

        xml = exp.to_xml()

        controller = ExperimentController(xml, self.root_dir)
        try:
            controller.start()
            while not all(controller.is_finished(app.guid) for app in apps):
                time.sleep(0.5)

            for app in apps:
                app_result = controller.trace(app.guid, "stdout") or ""
                self.assertTrue(re.match(comp_result, app_result, re.MULTILINE), "Unexpected trace:\n" + app_result)

                build_result = controller.trace(app.guid, "buildlog") or ""
                self.assertTrue(
                    re.match(comp_build, build_result, re.MULTILINE | re.DOTALL), "Unexpected trace:\n" + build_result
                )

        finally:
            try:
                controller.stop()
            except:
                import traceback

                traceback.print_exc()
            try:
                controller.shutdown()
            except:
                import traceback

                traceback.print_exc()
Beispiel #20
0
    def run(self, duration, xml_filepath, testset, results_dir, iteration):
        app_guid = 8

        testset_dir = os.path.join(results_dir, testset)
        
        # create test results file
        test_dir = os.path.join(testset_dir, str(iteration))

        # replace results values in xml
        replacements = cPickle.loads(os.environ['POPI_REPLACEMENTS'].strip().decode("base64"))
        file = open(xml_filepath)
        xml2 = xml = file.read()
        file.close()

        for key,value in replacements.iteritems():
            xml2 = xml2.replace("##%s##" % (key,), value)

        # launch experiment
        controller = ExperimentController(xml2, results_dir)
        
        try:
            controller.start()

            t0 = time.time()
            t1 = t0
            while (t1-t0) < duration and not controller.is_finished(app_guid):
                time.sleep(10)
            
            # download results
            for testbed_guid, guids in controller.traces_info().iteritems():
                for guid, traces in guids.iteritems():
                    for name, data in traces.iteritems():
                        path = data["filepath"]
                        print >>sys.stderr, "Downloading trace", path
                        
                        filepath = os.path.join(test_dir, path)
                        
                        try:
                            trace = controller.trace(guid, name)
                        except:
                            traceback.print_exc(file=sys.stderr)
                            continue
                        try:
                            if not os.path.exists(os.path.dirname(filepath)):
                                os.makedirs(os.path.dirname(filepath))
                        except:
                            traceback.print_exc(file=sys.stderr)
                        
                        try:
                            if len(trace) >= 2**20:
                                # Bigger than 1M, compress
                                tracefile = gzip.GzipFile(filepath+".gz", "wb")
                            else:
                                tracefile = open(filepath,"wb")
                            try:
                                tracefile.write(trace)
                            finally:
                                tracefile.close()
                        except:
                            traceback.print_exc(file=sys.stderr)

        finally:
            # clean up
            try:
                controller.stop()
            except:
                pass
            try:
                controller.shutdown()
            except:
                pass
Beispiel #21
0
    def _test_recover(self, daemonize_testbed, controller_access_configuration, environ=None, use_sfa=False):
        pl, exp = self.make_experiment_desc(use_sfa)

        pl.set_attribute_value(DC.RECOVERY_POLICY, DC.POLICY_RECOVER)

        node1 = pl.create("Node")
        node2 = pl.create("Node")
        node1.set_attribute_value("hostname", self.host1)
        node2.set_attribute_value("hostname", self.host2)

        iface1 = pl.create("NodeInterface")
        iface2 = pl.create("NodeInterface")
        inet = pl.create("Internet")
        node1.connector("devs").connect(iface1.connector("node"))
        node2.connector("devs").connect(iface2.connector("node"))
        iface1.connector("inet").connect(inet.connector("devs"))
        iface2.connector("inet").connect(inet.connector("devs"))

        tap1 = pl.create("TapInterface")
        tap2 = pl.create("TapInterface")
        node1.connector("devs").connect(tap1.connector("node"))
        node2.connector("devs").connect(tap2.connector("node"))
        tap1.connector("udp").connect(tap2.connector("udp"))

        tap1ip = tap1.add_address()
        tap1ip.set_attribute_value("Address", "192.168.2.2")
        tap1ip.set_attribute_value("NetPrefix", 24)
        tap1ip.set_attribute_value("Broadcast", False)

        tap2ip = tap2.add_address()
        tap2ip.set_attribute_value("Address", "192.168.2.3")
        tap2ip.set_attribute_value("NetPrefix", 24)
        tap2ip.set_attribute_value("Broadcast", False)

        app = pl.create("Application")
        app.set_attribute_value("command", "ping -qc10 192.168.2.3")
        app.enable_trace("stdout")
        app.connector("node").connect(node1.connector("apps"))

        if daemonize_testbed:
            pl.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
            inst_root_dir = os.path.join(self.root_dir, "instance")
            os.mkdir(inst_root_dir)
            pl.set_attribute_value(DC.ROOT_DIRECTORY, inst_root_dir)
            pl.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)

            if environ:
                pl.set_attribute_value(DC.DEPLOYMENT_ENVIRONMENT_SETUP, environ)

        xml = exp.to_xml()

        if controller_access_configuration:
            controller = proxy.create_experiment_controller(xml, controller_access_configuration)
        else:
            controller = ExperimentController(xml, self.root_dir)

        try:
            controller.start()

            # purposedly break connection
            controller = None

            # recover
            if controller_access_configuration:
                controller_access_configuration.set_attribute_value(DC.RECOVER, True)
                controller = proxy.create_experiment_controller(None, controller_access_configuration)
            else:
                controller = ExperimentController(None, self.root_dir)
                controller.recover()

            while not controller.is_finished(app.guid):
                time.sleep(0.5)
            ping_result = controller.trace(app.guid, "stdout")
            comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data.

--- .* ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time \d*ms.*
"""
            self.assertTrue(re.match(comp_result, ping_result, re.MULTILINE), "Unexpected trace:\n" + ping_result)

        finally:
            if controller is not None:
                try:
                    controller.stop()
                except:
                    import traceback

                    traceback.print_exc()
                try:
                    controller.shutdown()
                except:
                    import traceback

                    traceback.print_exc()
pl_iface2.connector("inet").connect(pl_inet.connector("devs"))
pl_node2.connector("devs").connect(pl_iface2.connector("node"))

pl_app1 = pl_desc.create("Application")
pl_app1.set_attribute_value("command",
                            "ping -qc3 {#[iface2].addr[0].[Address]#}")
pl_app1.enable_trace("stdout")
pl_app1.connector("node").connect(pl_node1.connector("apps"))

pl_app2 = pl_desc.create("Application")
pl_app2.set_attribute_value("command",
                            "ping -qc3 {#[iface1].addr[0].[Address]#}")
pl_app2.enable_trace("stdout")
pl_app2.connector("node").connect(pl_node2.connector("apps"))

xml = exp_desc.to_xml()

controller = ExperimentController(xml, root_dir)
controller.start()
while (not controller.is_finished(pl_app1.guid)
       or not controller.is_finished(pl_app1.guid)):
    time.sleep(0.5)

ping_result1 = controller.trace(pl_app1.guid, "stdout")
print ping_result1
ping_result2 = controller.trace(pl_app2.guid, "stdout")
print ping_result2

controller.stop()
controller.shutdown()
Beispiel #23
0
    def _test_plns3_crossconnect(self, proto):
        pl, pl2, exp = self.make_experiment_desc()
        
        # Create PL node, ifaces, assign addresses
        node1, iface1, _, _, inet1 = self.make_pl_tapnode(pl, 
            None, self.host1pl1, "node1")
        node2, iface2, tap2, tap2ip, inet2 = self.make_pl_tapnode(pl2, 
            "192.168.2.3", self.host1pl2, "node2")

        # Create NS3 instance in node1
        # With a node and all required protocols to be pinged
        ns3 = self.make_ns_in_pl(pl, exp, node1, iface1, "tb-ns-rcross-1")

        ns1 = ns3.create("ns3::Node")
        ipv41 = ns3.create("ns3::Ipv4L3Protocol")
        arp1  = ns3.create("ns3::ArpL3Protocol")
        icmp1 = ns3.create("ns3::Icmpv4L4Protocol")
        ns1.connector("protos").connect(ipv41.connector("node"))
        ns1.connector("protos").connect(arp1.connector("node"))
        ns1.connector("protos").connect(icmp1.connector("node"))
        ns1if = ns3.create("ns3::FdNetDevice")
        ns1if.enable_trace("FdPcapTrace")
        ns1if.set_attribute_value("label", "ns1if")
        ns1tc = ns3.create("ns3::Nepi::TunChannel")
        ns1.connector("devs").connect(ns1if.connector("node"))
        ns1tc.connector("fd->").connect(ns1if.connector("->fd"))
        ip1 = ns1if.add_address()
        ip1.set_attribute_value("Address", "192.168.2.2")
        ip1.set_attribute_value("NetPrefix", 24)
        ip1.set_attribute_value("Broadcast", False)
            
        # Connect the two
        tap2.connector(proto).connect(ns1tc.connector(proto))
        
        # Create PlanetLab ping application, pinging the from one PL to another
        ping = pl2.create("Application")
        ping.set_attribute_value("command", "ping -qc10 {#[ns1if].addr[0].[Address]#}")
        ping.enable_trace("stdout")
        ping.enable_trace("stderr")
        ping.connector("node").connect(node2.connector("apps"))

        comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data.

--- .* ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time \d*ms.*
"""

        xml = exp.to_xml()

        controller = ExperimentController(xml, self.root_dir)
        
        try:
            controller.start()

            while not controller.is_finished(ping.guid):
                time.sleep(0.5)
              
            ping_result = controller.trace(ping.guid, "stdout")
            tap2_trace = controller.trace(tap2.guid, "packets")
        finally:
            try:
                controller.stop()
            except:
                import traceback
                traceback.print_exc()
            try:
                controller.shutdown()
            except:
                import traceback
                traceback.print_exc()

        # asserts at the end, to make sure there's proper cleanup
        self.assertTrue(re.match(comp_result, ping_result, re.MULTILINE),
            "Unexpected trace:\n%s\nTap trace:\n%s\n" % (
                ping_result,
                tap2_trace) )