def test_ns3_in_pl(self): ns3_testbed_id = "ns3" pl, exp = self.make_experiment_desc() node1 = pl.create("Node") node1.set_attribute_value("hostname", self.host1) node1.set_attribute_value("label", "node1") iface1 = pl.create("NodeInterface") iface1.set_attribute_value("label", "node1iface") inet = pl.create("Internet") node1.connector("devs").connect(iface1.connector("node")) iface1.connector("inet").connect(inet.connector("devs")) # Add NS3 support in node1 ns3_desc = self.make_ns_in_pl(pl, exp, node1, iface1, "tb-ns3-1") xml = exp.to_xml() try: controller = ExperimentController(xml, self.root_dir) controller.start() # just test that it starts... finally: try: controller.stop() except: import traceback traceback.print_exc() try: controller.shutdown() except: import traceback traceback.print_exc()
def run(hostnames, vsys_vnet, slicename, plc_host, pl_user, pl_pwd, pl_ssh_key, port_base, root_dir, port): exp_desc, pl_nodes, hostname, pl_app = create_ed(hostnames, vsys_vnet, slicename, plc_host, pl_user, pl_pwd, pl_ssh_key, port_base, root_dir, port) xml = exp_desc.to_xml() controller = ExperimentController(xml, root_dir) controller.start() while not TERMINATE and controller.status(pl_app.guid) == AS.STATUS_NOT_STARTED: time.sleep(0.5) proc = None if not TERMINATE: hostname = hostnames[-1] proc = exec_ccncatchunks(slicename, port, hostname) while not TERMINATE and proc and proc.poll() is None: time.sleep(0.5) if proc: if proc.poll() < 1: err = proc.stderr.read() print "ERROR ", err else: out = proc.stdout.read() print "OUTPUT ", out controller.stop() controller.shutdown()
def run(hostnames, vsys_vnet, slicename, plc_host, pl_user, pl_pwd, pl_ssh_key, port_base, root_dir, port): exp_desc, pl_nodes, hostname, pl_app = create_ed(hostnames, vsys_vnet, slicename, plc_host, pl_user, pl_pwd, pl_ssh_key, port_base, root_dir, port) xml = exp_desc.to_xml() controller = ExperimentController(xml, root_dir) controller.start() while not TERMINATE and controller.status( pl_app.guid) == AS.STATUS_NOT_STARTED: time.sleep(0.5) proc = None if not TERMINATE: hostname = hostnames[-1] proc = exec_ccncatchunks(slicename, port, hostname) while not TERMINATE and proc and proc.poll() is None: time.sleep(0.5) if proc: if proc.poll() < 1: err = proc.stderr.read() print "ERROR ", err else: out = proc.stdout.read() print "OUTPUT ", out controller.stop() controller.shutdown()
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()
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()
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()
ip1.set_attribute_value("NetPrefix", 8) dev2 = create_wifi_device(ns3_desc, node2, channel) ip2 = dev2.add_address() ip2.set_attribute_value("Address", "10.0.0.2") ip2.set_attribute_value("NetPrefix", 8) dev3 = create_wifi_device(ns3_desc, node3, channel) ip3 = dev3.add_address() ip3.set_attribute_value("Address", "10.0.0.3") ip3.set_attribute_value("NetPrefix", 8) app = ns3_desc.create("ns3::V4Ping") app.set_attribute_value("Remote", "10.0.0.2") app.set_attribute_value("Verbose", True) app.set_attribute_value("StartTime", "0s") app.set_attribute_value("StopTime", "20s") app.connector("node").connect(node1.connector("apps")) xml = exp_desc.to_xml() controller = ExperimentController(xml, root_dir) controller.start() while not controller.is_finished(app.guid): time.sleep(0.5) controller.stop() controller.shutdown()
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
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()
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), )
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()
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))
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,) )
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,) )
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) )
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))
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)
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
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()
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()
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()
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()
netns_node = netns_desc.create("Node") netns_node.set_attribute_value("forward_X11", True) netns_tap = netns_desc.create("TunNodeInterface") netns_tap.set_attribute_value("up", True) netns_tap.set_attribute_value("mtu", 1448) netns_node.connector("devs").connect(netns_tap.connector("node")) netns_tunchannel = netns_desc.create("TunChannel") netns_tunchannel.connector("->fd").connect(netns_tap.connector("fd->")) pl_tap.connector("tcp").connect(netns_tunchannel.connector("tcp")) ip2 = netns_tap.add_address() ip2.set_attribute_value("Address", "192.168.3.2") ip2.set_attribute_value("NetPrefix", 30) app = netns_desc.create("Application") app.set_attribute_value("command", "xterm") app.set_attribute_value("user", user) app.connector("node").connect(netns_node.connector("apps")) xml = exp_desc.to_xml() controller = ExperimentController(xml, root_dir) controller.start() while not controller.is_finished(app.guid): time.sleep(0.5) controller.stop() controller.shutdown()
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) )