def make_experiment_desc(self, use_sfa=False): testbed_id = self.testbed_id slicename = self.slicename plchost = self.plchost pl_ssh_key = os.environ.get( "PL_SSH_KEY", "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'], )) pl_user, pl_pwd = test_util.pl_auth() exp_desc = ExperimentDescription() pl_provider = FactoriesProvider(testbed_id) pl_desc = exp_desc.add_testbed_description(pl_provider) pl_desc.set_attribute_value("homeDirectory", self.root_dir) pl_desc.set_attribute_value("slice", slicename) pl_desc.set_attribute_value("sliceSSHKey", pl_ssh_key) pl_desc.set_attribute_value("authUser", pl_user) pl_desc.set_attribute_value("authPass", pl_pwd) pl_desc.set_attribute_value("plcHost", plchost) pl_desc.set_attribute_value("tapPortBase", self.port_base) pl_desc.set_attribute_value( "p2pDeployment", False) # it's interactive, we don't want it in tests pl_desc.set_attribute_value("cleanProc", True) pl_desc.set_attribute_value("plLogLevel", "DEBUG") if use_sfa: pl_desc.set_attribute_value("sfa", True) pl_desc.set_attribute_value("sliceHrn", self.slicehrn) return pl_desc, exp_desc
def make_experiment_desc(self, use_sfa=False): testbed_id = self.testbed_id slicename = self.slicename plchost = self.plchost pl_ssh_key = os.environ.get("PL_SSH_KEY", "%s/.ssh/id_rsa_planetlab" % (os.environ["HOME"],)) pl_user, pl_pwd = test_util.pl_auth() exp_desc = ExperimentDescription() pl_provider = FactoriesProvider(testbed_id) pl_desc = exp_desc.add_testbed_description(pl_provider) pl_desc.set_attribute_value("homeDirectory", self.root_dir) pl_desc.set_attribute_value("slice", slicename) pl_desc.set_attribute_value("sliceSSHKey", pl_ssh_key) pl_desc.set_attribute_value("authUser", pl_user) pl_desc.set_attribute_value("authPass", pl_pwd) pl_desc.set_attribute_value("plcHost", plchost) pl_desc.set_attribute_value("tapPortBase", self.port_base) pl_desc.set_attribute_value("p2pDeployment", False) # it's interactive, we don't want it in tests pl_desc.set_attribute_value("cleanProc", True) pl_desc.set_attribute_value("plLogLevel", "DEBUG") if use_sfa: pl_desc.set_attribute_value("sfa", True) pl_desc.set_attribute_value("sliceHrn", self.slicehrn) return pl_desc, exp_desc
def make_instance(self): testbed_id = self.testbed_id slicename = self.slicename plchost = self.plchost instance = planetlab.TestbedController() pl_ssh_key = os.environ.get( "PL_SSH_KEY", "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'], )) slicename = os.environ.get("PL_SLICE", slicename) pl_user, pl_pwd = test_util.pl_auth() instance.defer_configure("homeDirectory", self.root_dir) instance.defer_configure("slice", slicename) instance.defer_configure("sliceSSHKey", pl_ssh_key) instance.defer_configure("authUser", pl_user) instance.defer_configure("authPass", pl_pwd) instance.defer_configure("plcHost", plchost) instance.defer_configure("tapPortBase", self.port_base) instance.defer_configure( "p2pDeployment", False) # it's interactive, we don't want it in tests instance.defer_configure("cleanProc", True) # Hack, but we need vsys_vnet instance.do_setup() vnet = instance.vsys_vnet self.net_prefix = vnet.rsplit('.', 1)[0] return instance
def make_instance(self): testbed_id = self.testbed_id slicename = self.slicename plchost = self.plchost instance = planetlab.TestbedController() pl_ssh_key = os.environ.get( "PL_SSH_KEY", "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'],) ) slicename = os.environ.get( "PL_SLICE", slicename) pl_user, pl_pwd = test_util.pl_auth() instance.defer_configure("homeDirectory", self.root_dir) instance.defer_configure("slice", slicename) instance.defer_configure("sliceSSHKey", pl_ssh_key) instance.defer_configure("authUser", pl_user) instance.defer_configure("authPass", pl_pwd) instance.defer_configure("plcHost", plchost) instance.defer_configure("tapPortBase", self.port_base) instance.defer_configure("p2pDeployment", False) # it's interactive, we don't want it in tests instance.defer_configure("cleanProc", True) # Hack, but we need vsys_vnet instance.do_setup() vnet = instance.vsys_vnet self.net_prefix = vnet.rsplit('.',1)[0] return instance
def make_experiment_desc(self): testbed_id = self.testbed_id slicename1 = self.slicename1 plchost1 = self.plchost1 slicename2 = self.slicename2 plchost2 = self.plchost2 pl_ssh_key = os.environ.get( "PL_SSH_KEY", "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'], )) pl_user, pl_pwd = test_util.pl_auth() exp_desc = ExperimentDescription() pl_provider = FactoriesProvider(testbed_id) pl_desc = exp_desc.add_testbed_description(pl_provider) pl_desc.set_attribute_value("homeDirectory", self.root_dir) pl_desc.set_attribute_value("slice", slicename1) pl_desc.set_attribute_value("sliceSSHKey", pl_ssh_key) pl_desc.set_attribute_value("authUser", pl_user) pl_desc.set_attribute_value("authPass", pl_pwd) pl_desc.set_attribute_value("plcHost", plchost1) pl_desc.set_attribute_value("tapPortBase", self.port_base) pl_desc.set_attribute_value( "p2pDeployment", False) # it's interactive, we don't want it in tests pl_desc.set_attribute_value("cleanProc", True) pl_desc2 = exp_desc.add_testbed_description(pl_provider) pl_desc2.set_attribute_value("homeDirectory", self.root_dir + "v2") pl_desc2.set_attribute_value("slice", slicename2) pl_desc2.set_attribute_value("sliceSSHKey", pl_ssh_key) pl_desc2.set_attribute_value("authUser", pl_user) pl_desc2.set_attribute_value("authPass", pl_pwd) pl_desc2.set_attribute_value("plcHost", plchost2) pl_desc2.set_attribute_value("tapPortBase", self.port_base + 500) pl_desc2.set_attribute_value( "p2pDeployment", False) # it's interactive, we don't want it in tests pl_desc2.set_attribute_value("cleanProc", True) return pl_desc, pl_desc2, exp_desc
def make_experiment_desc(self): testbed_id = self.testbed_id slicename1 = self.slicename1 plchost1 = self.plchost1 slicename2 = self.slicename2 plchost2 = self.plchost2 pl_ssh_key = os.environ.get( "PL_SSH_KEY", "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'],) ) pl_user, pl_pwd = test_util.pl_auth() exp_desc = ExperimentDescription() pl_provider = FactoriesProvider(testbed_id) pl_desc = exp_desc.add_testbed_description(pl_provider) pl_desc.set_attribute_value("homeDirectory", self.root_dir) pl_desc.set_attribute_value("slice", slicename1) pl_desc.set_attribute_value("sliceSSHKey", pl_ssh_key) pl_desc.set_attribute_value("authUser", pl_user) pl_desc.set_attribute_value("authPass", pl_pwd) pl_desc.set_attribute_value("plcHost", plchost1) pl_desc.set_attribute_value("tapPortBase", self.port_base) pl_desc.set_attribute_value("p2pDeployment", False) # it's interactive, we don't want it in tests pl_desc.set_attribute_value("cleanProc", True) pl_desc2 = exp_desc.add_testbed_description(pl_provider) pl_desc2.set_attribute_value("homeDirectory", self.root_dir+"v2") pl_desc2.set_attribute_value("slice", slicename2) pl_desc2.set_attribute_value("sliceSSHKey", pl_ssh_key) pl_desc2.set_attribute_value("authUser", pl_user) pl_desc2.set_attribute_value("authPass", pl_pwd) pl_desc2.set_attribute_value("plcHost", plchost2) pl_desc2.set_attribute_value("tapPortBase", self.port_base+500) pl_desc2.set_attribute_value("p2pDeployment", False) # it's interactive, we don't want it in tests pl_desc2.set_attribute_value("cleanProc", True) return pl_desc, pl_desc2, exp_desc
class PlanetLabMultiIntegrationTestCase(unittest.TestCase): testbed_id = "planetlab" slicename1 = "inria_nepi" plchost1 = "nepiplc.pl.sophia.inria.fr" slicename2 = "inria_nepi12" plchost2 = "www.planet-lab.eu" host1pl1 = "nepi1.pl.sophia.inria.fr" host2pl1 = "nepi2.pl.sophia.inria.fr" host1pl2 = "planetlab1.utt.fr" host2pl2 = "planetlab2.utt.fr" port_base = 2000 + (os.getpid() % 1000) * 13 def setUp(self): self.root_dir = tempfile.mkdtemp() self.__class__.port_base = self.port_base + 100 def tearDown(self): try: shutil.rmtree(self.root_dir) except: # retry time.sleep(0.1) shutil.rmtree(self.root_dir) def make_experiment_desc(self): testbed_id = self.testbed_id slicename1 = self.slicename1 plchost1 = self.plchost1 slicename2 = self.slicename2 plchost2 = self.plchost2 pl_ssh_key = os.environ.get( "PL_SSH_KEY", "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'], )) pl_user, pl_pwd = test_util.pl_auth() exp_desc = ExperimentDescription() pl_provider = FactoriesProvider(testbed_id) pl_desc = exp_desc.add_testbed_description(pl_provider) pl_desc.set_attribute_value("homeDirectory", self.root_dir) pl_desc.set_attribute_value("slice", slicename1) pl_desc.set_attribute_value("sliceSSHKey", pl_ssh_key) pl_desc.set_attribute_value("authUser", pl_user) pl_desc.set_attribute_value("authPass", pl_pwd) pl_desc.set_attribute_value("plcHost", plchost1) pl_desc.set_attribute_value("tapPortBase", self.port_base) pl_desc.set_attribute_value( "p2pDeployment", False) # it's interactive, we don't want it in tests pl_desc.set_attribute_value("cleanProc", True) pl_desc2 = exp_desc.add_testbed_description(pl_provider) pl_desc2.set_attribute_value("homeDirectory", self.root_dir + "v2") pl_desc2.set_attribute_value("slice", slicename2) pl_desc2.set_attribute_value("sliceSSHKey", pl_ssh_key) pl_desc2.set_attribute_value("authUser", pl_user) pl_desc2.set_attribute_value("authPass", pl_pwd) pl_desc2.set_attribute_value("plcHost", plchost2) pl_desc2.set_attribute_value("tapPortBase", self.port_base + 500) pl_desc2.set_attribute_value( "p2pDeployment", False) # it's interactive, we don't want it in tests pl_desc2.set_attribute_value("cleanProc", True) return pl_desc, pl_desc2, exp_desc def make_pl_tapnode(self, pl, tapip, hostname, label_prefix): node1 = pl.create("Node") node1.set_attribute_value("hostname", hostname) node1.set_attribute_value("label", label_prefix) iface1 = pl.create("NodeInterface") iface1.set_attribute_value("label", label_prefix + "iface") if tapip: tap1 = pl.create("TapInterface") tap1.enable_trace("packets") # for error output tap1.set_attribute_value("label", label_prefix + "tap") node1.connector("devs").connect(tap1.connector("node")) tap1ip = tap1.add_address() tap1ip.set_attribute_value("Address", tapip) tap1ip.set_attribute_value("NetPrefix", 24) tap1ip.set_attribute_value("Broadcast", False) else: tap1 = None tap1ip = None inet = pl.create("Internet") node1.connector("devs").connect(iface1.connector("node")) iface1.connector("inet").connect(inet.connector("devs")) return node1, iface1, tap1, tap1ip, inet def make_ns_in_pl(self, pl, exp, node1, iface1, root): ns3_testbed_id = "ns3" # Add NS3 support in node1 plnepi = pl.create("NepiDependency") plns3 = pl.create("NS3Dependency") plnepi.connector("node").connect(node1.connector("deps")) plns3.connector("node").connect(node1.connector("deps")) # Create NS3 testbed running in node1 ns3_provider = FactoriesProvider(ns3_testbed_id) ns3_desc = exp.add_testbed_description(ns3_provider) ns3_desc.set_attribute_value("rootDirectory", root) ns3_desc.set_attribute_value("SimulatorImplementationType", "ns3::RealtimeSimulatorImpl") ns3_desc.set_attribute_value("ChecksumEnabled", True) ns3_desc.set_attribute_value( DC.DEPLOYMENT_HOST, "{#[%s].addr[0].[Address]#}" % (iface1.get_attribute_value("label"), )) ns3_desc.set_attribute_value(DC.DEPLOYMENT_USER, pl.get_attribute_value("slice")) ns3_desc.set_attribute_value(DC.DEPLOYMENT_KEY, pl.get_attribute_value("sliceSSHKey")) ns3_desc.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON) ns3_desc.set_attribute_value(DC.DEPLOYMENT_COMMUNICATION, DC.ACCESS_SSH) ns3_desc.set_attribute_value( DC.DEPLOYMENT_ENVIRONMENT_SETUP, "{#[%s].[%s]#}" % ( node1.get_attribute_value("label"), ATTR_NEPI_TESTBED_ENVIRONMENT_SETUP, )) ns3_desc.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL) return ns3_desc 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)) @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) @test_util.skipUnless( os.environ.get('NEPI_FULL_TESTS', '').lower() in ('1', 'yes', 'true', 'on'), "Test is expensive, requires NEPI_FULL_TESTS=yes") def test_plns3_crossconnect_udp(self): self._test_plns3_crossconnect("udp") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) @test_util.skipUnless( os.environ.get('NEPI_FULL_TESTS', '').lower() in ('1', 'yes', 'true', 'on'), "Test is expensive, requires NEPI_FULL_TESTS=yes") def test_plns3_crossconnect_tcp(self): self._test_plns3_crossconnect("tcp")
class PlanetLabIntegrationTestCase(unittest.TestCase): testbed_id = "planetlab" slicename = "inria_nepi" slicehrn = "nepi.inria.nepi" plchost = "nepiplc.pl.sophia.inria.fr" host1 = "nepi1.pl.sophia.inria.fr" host2 = "nepi2.pl.sophia.inria.fr" host3 = "nepi3.pl.sophia.inria.fr" host4 = "nepi5.pl.sophia.inria.fr" port_base = 2000 + (os.getpid() % 1000) * 13 def setUp(self): self.root_dir = tempfile.mkdtemp() self.__class__.port_base = self.port_base + 100 def tearDown(self): try: shutil.rmtree(self.root_dir) except: # retry time.sleep(0.1) shutil.rmtree(self.root_dir) def make_experiment_desc(self, use_sfa=False): testbed_id = self.testbed_id slicename = self.slicename plchost = self.plchost pl_ssh_key = os.environ.get( "PL_SSH_KEY", "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'], )) pl_user, pl_pwd = test_util.pl_auth() exp_desc = ExperimentDescription() pl_provider = FactoriesProvider(testbed_id) pl_desc = exp_desc.add_testbed_description(pl_provider) pl_desc.set_attribute_value("homeDirectory", self.root_dir) pl_desc.set_attribute_value("slice", slicename) pl_desc.set_attribute_value("sliceSSHKey", pl_ssh_key) pl_desc.set_attribute_value("authUser", pl_user) pl_desc.set_attribute_value("authPass", pl_pwd) pl_desc.set_attribute_value("plcHost", plchost) pl_desc.set_attribute_value("tapPortBase", self.port_base) pl_desc.set_attribute_value( "p2pDeployment", False) # it's interactive, we don't want it in tests pl_desc.set_attribute_value("cleanProc", True) pl_desc.set_attribute_value("plLogLevel", "DEBUG") if use_sfa: pl_desc.set_attribute_value("sfa", True) pl_desc.set_attribute_value("sliceHrn", self.slicehrn) return pl_desc, exp_desc 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_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() @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_simple(self): self._test_simple(daemonize_testbed=False, controller_access_configuration=None) @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_simple_sfa(self): self._test_simple(daemonize_testbed=False, controller_access_configuration=None, use_sfa=True) @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) @test_util.skipUnless( os.environ.get('NEPI_FULL_TESTS', '').lower() in ('1', 'yes', 'true', 'on'), "Test is interactive, requires NEPI_FULL_TESTS=yes") def test_spanning_deployment(self): self._test_spanning_deployment() @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) @test_util.skipUnless( os.environ.get('NEPI_FULL_TESTS', '').lower() in ('1', 'yes', 'true', 'on'), "Test is interactive, requires NEPI_FULL_TESTS=yes") def test_spanning_deployment_sfa(self): self._test_spanning_deployment(use_sfa=True) @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_simple_daemonized(self): access_config = proxy.AccessConfiguration({ DC.DEPLOYMENT_MODE: DC.MODE_DAEMON, DC.ROOT_DIRECTORY: self.root_dir, DC.LOG_LEVEL: DC.DEBUG_LEVEL, }) self._test_simple(daemonize_testbed=False, controller_access_configuration=access_config) @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_simple_daemonized_sfa(self): access_config = proxy.AccessConfiguration({ DC.DEPLOYMENT_MODE: DC.MODE_DAEMON, DC.ROOT_DIRECTORY: self.root_dir, DC.LOG_LEVEL: DC.DEBUG_LEVEL, }) self._test_simple(daemonize_testbed=False, controller_access_configuration=access_config, use_sfa=True) @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_z_simple_ssh( self): # _z_ cause we want it last - it messes up the process :( # Recreate environment environ = ' ; '.join( map("export %s=%r".__mod__, os.environ.iteritems())) env = test_util.test_environment() access_config = proxy.AccessConfiguration({ DC.DEPLOYMENT_MODE: DC.MODE_DAEMON, DC.ROOT_DIRECTORY: self.root_dir, DC.LOG_LEVEL: DC.DEBUG_LEVEL, DC.DEPLOYMENT_COMMUNICATION: DC.ACCESS_SSH, DC.DEPLOYMENT_PORT: env.port, DC.USE_AGENT: True, DC.DEPLOYMENT_ENVIRONMENT_SETUP: environ, }) self._test_simple(daemonize_testbed=False, controller_access_configuration=access_config, environ=environ) @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_recover(self): self._test_recover(daemonize_testbed=False, controller_access_configuration=None) @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_recover_sfa(self): self._test_recover(daemonize_testbed=False, controller_access_configuration=None, use_sfa=True) @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_recover_daemonized(self): access_config = proxy.AccessConfiguration({ DC.DEPLOYMENT_MODE: DC.MODE_DAEMON, DC.ROOT_DIRECTORY: self.root_dir, DC.LOG_LEVEL: DC.DEBUG_LEVEL, }) self._test_recover(daemonize_testbed=False, controller_access_configuration=access_config) @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_recover_daemonized_sfa(self): access_config = proxy.AccessConfiguration({ DC.DEPLOYMENT_MODE: DC.MODE_DAEMON, DC.ROOT_DIRECTORY: self.root_dir, DC.LOG_LEVEL: DC.DEBUG_LEVEL, }) self._test_recover(daemonize_testbed=False, controller_access_configuration=access_config, use_sfa=True)
class PlanetLabMultiIntegrationTestCase(unittest.TestCase): testbed_id = "planetlab" slicename1 = "inria_nepi" plchost1 = "nepiplc.pl.sophia.inria.fr" plcvnet1 = "192.168.2" slicename2 = "inria_nepi2" plchost2 = "nepiplc.pl.sophia.inria.fr" plcvnet2 = "192.168.3" host1pl1 = "nepi1.pl.sophia.inria.fr" host2pl1 = "nepi2.pl.sophia.inria.fr" host1pl2 = "nepi3.pl.sophia.inria.fr" host2pl2 = "nepi5.pl.sophia.inria.fr" port_base = 2000 + (os.getpid() % 1000) * 13 def setUp(self): self.root_dir = tempfile.mkdtemp() self.__class__.port_base = self.port_base + 100 def tearDown(self): try: shutil.rmtree(self.root_dir) except: # retry time.sleep(0.1) shutil.rmtree(self.root_dir) def make_experiment_desc(self): testbed_id = self.testbed_id slicename1 = self.slicename1 plchost1 = self.plchost1 slicename2 = self.slicename2 plchost2 = self.plchost2 pl_ssh_key = os.environ.get( "PL_SSH_KEY", "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'], )) pl_user, pl_pwd = test_util.pl_auth() exp_desc = ExperimentDescription() pl_provider = FactoriesProvider(testbed_id) pl_desc = exp_desc.add_testbed_description(pl_provider) pl_desc.set_attribute_value("homeDirectory", self.root_dir) pl_desc.set_attribute_value("slice", slicename1) pl_desc.set_attribute_value("sliceSSHKey", pl_ssh_key) pl_desc.set_attribute_value("authUser", pl_user) pl_desc.set_attribute_value("authPass", pl_pwd) pl_desc.set_attribute_value("plcHost", plchost1) pl_desc.set_attribute_value("tapPortBase", self.port_base) pl_desc.set_attribute_value( "p2pDeployment", False) # it's interactive, we don't want it in tests pl_desc.set_attribute_value("cleanProc", True) pl_desc.set_attribute_value("plLogLevel", "DEBUG") pl_desc2 = exp_desc.add_testbed_description(pl_provider) pl_desc2.set_attribute_value("homeDirectory", self.root_dir + "v2") pl_desc2.set_attribute_value("slice", slicename2) pl_desc2.set_attribute_value("sliceSSHKey", pl_ssh_key) pl_desc2.set_attribute_value("authUser", pl_user) pl_desc2.set_attribute_value("authPass", pl_pwd) pl_desc2.set_attribute_value("plcHost", plchost2) pl_desc2.set_attribute_value("tapPortBase", self.port_base + 500) pl_desc2.set_attribute_value( "p2pDeployment", False) # it's interactive, we don't want it in tests pl_desc2.set_attribute_value("cleanProc", True) pl_desc2.set_attribute_value("plLogLevel", "DEBUG") return pl_desc, pl_desc2, exp_desc def make_pl_tapnode(self, pl, tapip, hostname, label_prefix): node1 = pl.create("Node") node1.set_attribute_value("hostname", hostname) node1.set_attribute_value("label", label_prefix) iface1 = pl.create("NodeInterface") iface1.set_attribute_value("label", label_prefix + "iface") tap1 = pl.create("TapInterface") tap1.enable_trace("packets") # for error output tap1.set_attribute_value("label", label_prefix + "tap") inet = pl.create("Internet") node1.connector("devs").connect(iface1.connector("node")) node1.connector("devs").connect(tap1.connector("node")) iface1.connector("inet").connect(inet.connector("devs")) tap1ip = tap1.add_address() tap1ip.set_attribute_value("Address", tapip) tap1ip.set_attribute_value("NetPrefix", 24) tap1ip.set_attribute_value("Broadcast", False) return node1, iface1, tap1, tap1ip, inet 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)) @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_plpl_crossconnect_udp(self): self._test_plpl_crossconnect("udp") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_plpl_crossconnect_tcp(self): self._test_plpl_crossconnect("tcp") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_plpl_crossconnect_gre(self): self._test_plpl_crossconnect("gre") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_plpl_crossconnect_udp_recover(self): self._test_plpl_crossconnect("udp", recover=True)
class PlanetLabExecuteTestCase(unittest.TestCase): testbed_id = "planetlab" slicename = "inria_nepi" plchost = "nepiplc.pl.sophia.inria.fr" host1 = "nepi1.pl.sophia.inria.fr" host2 = "nepi2.pl.sophia.inria.fr" port_base = 2000 + (os.getpid() % 1000) * 13 PLR50_PY = os.path.join(os.path.dirname(planetlab.__file__), 'scripts', 'plr50.py') PLR50_C = os.path.join(os.path.dirname(planetlab.__file__), 'scripts', 'plr50.c') TOS_PY = os.path.join(os.path.dirname(planetlab.__file__), 'scripts', 'tosqueue.py') CLS_PY = os.path.join(os.path.dirname(planetlab.__file__), 'scripts', 'classqueue.py') def setUp(self): self.root_dir = tempfile.mkdtemp() self.__class__.port_base = self.port_base + 100 def tearDown(self): try: shutil.rmtree(self.root_dir) except: # retry time.sleep(0.1) shutil.rmtree(self.root_dir) def make_instance(self): testbed_id = self.testbed_id slicename = self.slicename plchost = self.plchost instance = planetlab.TestbedController() pl_ssh_key = os.environ.get( "PL_SSH_KEY", "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'], )) slicename = os.environ.get("PL_SLICE", slicename) pl_user, pl_pwd = test_util.pl_auth() instance.defer_configure("homeDirectory", self.root_dir) instance.defer_configure("slice", slicename) instance.defer_configure("sliceSSHKey", pl_ssh_key) instance.defer_configure("authUser", pl_user) instance.defer_configure("authPass", pl_pwd) instance.defer_configure("plcHost", plchost) instance.defer_configure("tapPortBase", self.port_base) instance.defer_configure( "p2pDeployment", False) # it's interactive, we don't want it in tests instance.defer_configure("cleanProc", True) # Hack, but we need vsys_vnet instance.do_setup() vnet = instance.vsys_vnet self.net_prefix = vnet.rsplit('.', 1)[0] return instance @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_simple(self): instance = self.make_instance() instance.defer_create(2, "Node") instance.defer_create_set(2, "hostname", self.host1) instance.defer_create(3, "Node") instance.defer_create_set(3, "hostname", self.host2) instance.defer_create(4, "NodeInterface") instance.defer_connect(2, "devs", 4, "node") instance.defer_create(5, "NodeInterface") instance.defer_connect(3, "devs", 5, "node") instance.defer_create(6, "Internet") instance.defer_connect(4, "inet", 6, "devs") instance.defer_connect(5, "inet", 6, "devs") instance.defer_create(7, "Application") instance.defer_create_set(7, "command", "ping -qc1 {#[GUID-5].addr[0].[Address]#}") instance.defer_add_trace(7, "stdout") instance.defer_add_trace(7, "stderr") instance.defer_connect(7, "node", 2, "apps") comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data. --- .* ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time \d*ms.* """ try: instance.do_setup() instance.do_create() instance.do_connect_init() instance.do_connect_compl() instance.do_preconfigure() # Manually replace netref instance.set( 7, "command", instance.get(7, "command").replace( "{#[GUID-5].addr[0].[Address]#}", instance.get_address(5, 0, "Address"))) instance.do_configure() instance.do_prestart() instance.start() while instance.status(7) != AS.STATUS_FINISHED: time.sleep(0.5) ping_result = instance.trace(7, "stdout") or "" instance.stop() finally: try: instance.shutdown() except: pass # asserts at the end, to make sure there's proper cleanup self.assertTrue(re.match(comp_result, ping_result, re.MULTILINE), "Unexpected trace:\n" + ping_result) @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_depends(self): instance = self.make_instance() instance.defer_create(2, "Node") instance.defer_create_set(2, "hostname", self.host1) instance.defer_create(3, "NodeInterface") instance.defer_connect(2, "devs", 3, "node") instance.defer_create(4, "Internet") instance.defer_connect(3, "inet", 4, "devs") instance.defer_create(5, "Application") instance.defer_create_set(5, "command", "gfortran --version") instance.defer_create_set(5, "depends", "gcc-gfortran") instance.defer_add_trace(5, "stdout") instance.defer_add_trace(5, "stderr") instance.defer_connect(5, "node", 2, "apps") try: instance.do_setup() instance.do_create() instance.do_connect_init() instance.do_connect_compl() instance.do_preconfigure() instance.do_configure() instance.do_prestart() instance.start() while instance.status(5) != AS.STATUS_FINISHED: time.sleep(0.5) ping_result = instance.trace(5, "stdout") or "" comp_result = r".*GNU Fortran \(GCC\).*" instance.stop() finally: try: instance.shutdown() except: pass # asserts at the end, to make sure there's proper cleanup self.assertTrue(re.match(comp_result, ping_result, re.MULTILINE), "Unexpected trace:\n" + ping_result) @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_build(self): instance = self.make_instance() instance.defer_create(2, "Node") instance.defer_create_set(2, "hostname", self.host1) instance.defer_create(3, "NodeInterface") instance.defer_connect(2, "devs", 3, "node") instance.defer_create(4, "Internet") instance.defer_connect(3, "inet", 4, "devs") instance.defer_create(10, "Application") instance.defer_create_set(10, "command", "./consts") instance.defer_create_set(10, "buildDepends", "gcc") instance.defer_create_set(10, "build", "gcc ${SOURCES}/consts.c -o consts") instance.defer_create_set(10, "install", "cp consts ${SOURCES}/consts") instance.defer_create_set( 10, "sources", os.path.join(os.path.dirname(planetlab.__file__), 'scripts', 'consts.c')) instance.defer_add_trace(10, "stdout") instance.defer_add_trace(10, "stderr") instance.defer_connect(10, "node", 2, "apps") 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}.* """ try: instance.do_setup() instance.do_create() instance.do_connect_init() instance.do_connect_compl() instance.do_preconfigure() instance.do_configure() instance.do_prestart() instance.start() while instance.status(10) != AS.STATUS_FINISHED: time.sleep(0.5) ping_result = instance.trace(10, "stdout") or "" instance.stop() finally: try: instance.shutdown() except: pass # asserts at the end, to make sure there's proper cleanup self.assertTrue(re.match(comp_result, ping_result, re.MULTILINE), "Unexpected trace:\n" + ping_result) @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_simple_vsys(self): instance = self.make_instance() instance.defer_create(2, "Node") instance.defer_create_set(2, "hostname", self.host1) instance.defer_create(3, "NodeInterface") instance.defer_connect(2, "devs", 3, "node") instance.defer_create(4, "Internet") instance.defer_connect(3, "inet", 4, "devs") instance.defer_create(5, "TunInterface") instance.defer_add_address(5, self.net_prefix + ".2", 24, False) instance.defer_connect(2, "devs", 5, "node") instance.defer_create(6, "Application") instance.defer_create_set( 6, "command", """ set -e netconfig help > /dev/null test -e /vsys/vif_up.in > /dev/null test -e /vsys/vif_up.out > /dev/null test -e /vsys/fd_tuntap.control > /dev/null echo 'OKIDOKI' """) instance.defer_create_set(6, "sudo", True) # only sudo has access to /vsys instance.defer_add_trace(6, "stdout") instance.defer_add_trace(6, "stderr") instance.defer_connect(6, "node", 2, "apps") try: instance.do_setup() instance.do_create() instance.do_connect_init() instance.do_connect_compl() instance.do_preconfigure() instance.do_configure() instance.do_prestart() instance.start() while instance.status(6) != AS.STATUS_FINISHED: time.sleep(0.5) test_result = (instance.trace(6, "stdout") or "").strip() comp_result = "OKIDOKI" instance.stop() finally: try: instance.shutdown() except: pass # asserts at the end, to make sure there's proper cleanup self.assertEqual(comp_result, test_result) @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_emulation(self): instance = self.make_instance() instance.defer_create(2, "Node") instance.defer_create_set(2, "hostname", self.host1) instance.defer_create(3, "NodeInterface") instance.defer_connect(2, "devs", 3, "node") instance.defer_create(4, "Internet") instance.defer_connect(3, "inet", 4, "devs") instance.defer_create(7, "NetPipe") instance.defer_create_set(7, "mode", "CLIENT") instance.defer_create_set(7, "portList", "80") instance.defer_create_set(7, "bwOut", 12.0 / 1024.0) # 12kbps instance.defer_create_set(7, "bwIn", 64.0 / 1024.0) # 64kbps instance.defer_create_set(7, "plrOut", 0.01) # 1% plr outbound - high loss instance.defer_create_set(7, "plrIn", 0.001) # 0.1% plr inbound - regular loss instance.defer_create_set(7, "delayOut", int(1500 * 8 / (12.0 / 1024.0) / 1000)) # tx delay at 12kbps in ms instance.defer_create_set(7, "delayIn", int(1500 * 8 / (64.0 / 1024.0) / 1000)) # rx delay at 64kbps in ms instance.defer_add_trace(7, "netpipeStats") instance.defer_connect(2, "pipes", 7, "node") instance.defer_create(8, "Application") instance.defer_create_set( 8, "command", "time wget -q -O /dev/null http://www.google.com/") # Fetch ~10kb instance.defer_add_trace(8, "stdout") instance.defer_add_trace(8, "stderr") instance.defer_connect(8, "node", 2, "apps") try: instance.do_setup() instance.do_create() instance.do_connect_init() instance.do_connect_compl() instance.do_preconfigure() instance.do_configure() instance.do_prestart() instance.start() while instance.status(8) != AS.STATUS_FINISHED: time.sleep(0.5) test_result = (instance.trace(8, "stderr") or "").strip() comp_result = r".*real\s*(?P<min>[0-9]+)m(?P<sec>[0-9]+[.][0-9]+)s.*" netpipe_stats = instance.trace(7, "netpipeStats") instance.stop() finally: try: instance.shutdown() except: pass # asserts at the end, to make sure there's proper cleanup match = re.match(comp_result, test_result, re.MULTILINE) self.assertTrue(match, "Unexpected output: %s" % (test_result, )) minutes = int(match.group("min")) seconds = float(match.group("sec")) self.assertTrue((minutes * 60 + seconds) > 1.0, "Emulation not effective: %s" % (test_result, )) self.assertTrue(netpipe_stats, "Unavailable netpipe stats") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def _pingtest(self, TunClass, ConnectionProto, Cipher, Filter1=None, Filter2=None, Filter1args=None, Filter2args=None, PLREX=None, flood=False): instance = self.make_instance() instance.defer_create(2, "Node") instance.defer_create_set(2, "hostname", self.host1) instance.defer_create(3, "Node") instance.defer_create_set(3, "hostname", self.host2) instance.defer_create(4, "NodeInterface") instance.defer_connect(2, "devs", 4, "node") instance.defer_create(5, "Internet") instance.defer_connect(4, "inet", 5, "devs") instance.defer_create(6, "NodeInterface") instance.defer_connect(3, "devs", 6, "node") instance.defer_connect(6, "inet", 5, "devs") instance.defer_create(7, TunClass) instance.defer_create_set(7, "tun_cipher", Cipher) instance.defer_add_trace(7, "packets") instance.defer_add_address(7, self.net_prefix + ".2", 24, False) if flood: instance.defer_create_set(7, "bwlimit", 128) instance.defer_connect(2, "devs", 7, "node") instance.defer_create(8, TunClass) instance.defer_create_set(8, "tun_cipher", Cipher) instance.defer_add_trace(8, "packets") instance.defer_add_address(8, self.net_prefix + ".3", 24, False) instance.defer_connect(3, "devs", 8, "node") instance.defer_create(9, "Application") if flood: instance.defer_create_set( 9, "command", "sudo -S ping -s 1000 -l 1000 -qfc1000 {#[GUID-8].addr[0].[Address]#} ; sleep 20 ; ping -qc10 {#[GUID-8].addr[0].[Address]#}" ) else: instance.defer_create_set( 9, "command", "ping -qc10 {#[GUID-8].addr[0].[Address]#}") instance.defer_add_trace(9, "stdout") instance.defer_add_trace(9, "stderr") instance.defer_connect(9, "node", 2, "apps") if Filter1: instance.defer_create(10, "TunFilter") instance.defer_create_set(10, "module", Filter1) if Filter1args: instance.defer_create_set(10, "args", Filter1args) instance.defer_connect(7, "fd->", 10, "->fd") if Filter2: instance.defer_create(11, "TunFilter") instance.defer_create_set(11, "module", Filter2) if Filter2args: instance.defer_create_set(11, "args", Filter2args) instance.defer_connect(8, "fd->", 11, "->fd") if PLREX is None: if Filter1 and Filter2: plr = "[5-9][0-9]" elif Filter1 or Filter2: plr = "[3-9][0-9]" else: plr = "0" else: plr = PLREX instance.defer_connect((10 if Filter1 else 7), ConnectionProto, (11 if Filter2 else 8), ConnectionProto) comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data. --- .* ping statistics --- 10 packets transmitted, [0-9]+ received,.* %s%% packet loss, time \d*ms.* """ % (plr, ) if flood: comp_result = ".*" + comp_result try: instance.do_setup() instance.do_create() instance.do_connect_init() instance.do_connect_compl() instance.do_preconfigure() # Manually replace netref instance.set( 9, "command", instance.get(9, "command").replace( "{#[GUID-8].addr[0].[Address]#}", instance.get_address(8, 0, "Address"))) instance.do_configure() instance.do_prestart() instance.start() while instance.status(9) != AS.STATUS_FINISHED: time.sleep(0.5) ping_result = instance.trace(9, "stdout") or "" packets1 = instance.trace(7, "packets") or "" packets2 = instance.trace(8, "packets") or "" instance.stop() finally: try: instance.shutdown() except: pass # asserts at the end, to make sure there's proper cleanup self.assertTrue( re.match(comp_result, ping_result, re.MULTILINE | re.DOTALL), "Unexpected trace:\n%s\nPackets @ source:\n%s\nPackets @ target:\n%s" % (ping_result, packets1, packets2)) @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_tun_ping(self): self._pingtest("TunInterface", "tcp", "AES") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_tun_ping_udp(self): self._pingtest("TunInterface", "udp", "AES") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_tun_ping_gre(self): self._pingtest("TunInterface", "gre", "PLAIN") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_tun_ping_flood(self): self._pingtest("TunInterface", "tcp", "PLAIN", flood=True) @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_tun_ping_flood_udp(self): self._pingtest("TunInterface", "udp", "PLAIN", flood=True) @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_tap_ping(self): self._pingtest("TapInterface", "tcp", "AES") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_tap_ping_udp(self): self._pingtest("TapInterface", "udp", "AES") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_tap_ping_gre(self): self._pingtest("TapInterface", "gre", "PLAIN") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_tap_ping_udp_loss1_py(self): self._pingtest("TapInterface", "udp", "AES", self.PLR50_PY, None, "plr=50") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_tap_ping_udp_loss2_py(self): self._pingtest("TapInterface", "udp", "AES", self.PLR50_PY, self.PLR50_PY, "plr=40", "plr=40") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_tap_ping_udp_loss1_c(self): self._pingtest("TapInterface", "udp", "AES", self.PLR50_C, None, "plr=50") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_tap_ping_udp_loss2_c(self): self._pingtest("TapInterface", "udp", "AES", self.PLR50_C, self.PLR50_C, "plr=40", "plr=40") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_tun_ping_udp_tos(self): self._pingtest("TunInterface", "udp", "AES", self.TOS_PY, self.TOS_PY, "size=1000", "size=1000", "0") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_tun_ping_udp_class(self): self._pingtest("TunInterface", "udp", "AES", self.CLS_PY, self.CLS_PY, "size=10", "size=10", "0") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_nepi_depends(self): instance = self.make_instance() instance.defer_create(2, "Node") instance.defer_create_set(2, "hostname", self.host1) instance.defer_create(3, "NodeInterface") instance.defer_connect(2, "devs", 3, "node") instance.defer_create(4, "Internet") instance.defer_connect(3, "inet", 4, "devs") instance.defer_create(5, "NepiDependency") instance.defer_connect(5, "node", 2, "deps") instance.defer_create(12, "Application") instance.defer_connect(12, "node", 2, "apps") instance.defer_create_set(12, "command", "python -c 'import nepi'") instance.defer_add_trace(12, "stderr") try: instance.do_setup() instance.do_create() instance.do_connect_init() instance.do_connect_compl() instance.do_preconfigure() instance.do_configure() instance.do_prestart() instance.start() while instance.status(12) != AS.STATUS_FINISHED: time.sleep(0.5) ping_result = (instance.trace(12, "stderr") or "").strip() instance.stop() finally: try: instance.shutdown() except: pass # asserts at the end, to make sure there's proper cleanup self.assertEqual(ping_result, "") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) @test_util.skipUnless( os.environ.get('NEPI_FULL_TESTS', '').lower() in ('1', 'yes', 'true', 'on'), "Test is expensive, requires NEPI_FULL_TESTS=yes") def test_ns3_depends(self): instance = self.make_instance() instance.defer_create(2, "Node") instance.defer_create_set(2, "hostname", self.host1) instance.defer_create(3, "NodeInterface") instance.defer_connect(2, "devs", 3, "node") instance.defer_create(4, "Internet") instance.defer_connect(3, "inet", 4, "devs") instance.defer_create(5, "NepiDependency") instance.defer_connect(5, "node", 2, "deps") instance.defer_create(6, "NS3Dependency") instance.defer_connect(6, "node", 2, "deps") instance.defer_create(12, "Application") instance.defer_connect(12, "node", 2, "apps") instance.defer_create_set( 12, "command", "python -c 'import nepi.testbeds.ns3.execute ; tb = nepi.testbeds.ns3.execute.TestbedController() ; mod = tb._configure_ns3_module()'" ) instance.defer_add_trace(12, "stderr") try: instance.do_setup() instance.do_create() instance.do_connect_init() instance.do_connect_compl() instance.do_preconfigure() instance.do_configure() instance.do_prestart() instance.start() while instance.status(12) != AS.STATUS_FINISHED: time.sleep(0.5) ping_result = (instance.trace(12, "stderr") or "").strip() instance.stop() finally: try: instance.shutdown() except: pass # asserts at the end, to make sure there's proper cleanup self.assertEqual(ping_result, "") @test_util.skipUnless( test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)" ) def test_discovery(self): instance = self.make_instance() instance.defer_create(2, "Node") instance.defer_create_set(2, "operatingSystem", "f12") instance.defer_create(3, "Node") instance.defer_create_set(3, "operatingSystem", "f12") instance.defer_create(4, "NodeInterface") instance.defer_connect(2, "devs", 4, "node") instance.defer_create(5, "NodeInterface") instance.defer_connect(3, "devs", 5, "node") instance.defer_create(6, "Internet") instance.defer_connect(4, "inet", 6, "devs") instance.defer_connect(5, "inet", 6, "devs") instance.defer_create(7, "Application") instance.defer_create_set(7, "command", "ping -qc1 {#[GUID-5].addr[0].[Address]#}") instance.defer_add_trace(7, "stdout") instance.defer_add_trace(7, "stderr") instance.defer_connect(7, "node", 2, "apps") comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data. --- .* ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time \d*ms.* """ try: instance.do_setup() instance.do_create() instance.do_connect_init() instance.do_connect_compl() instance.do_preconfigure() # Manually replace netref instance.set( 7, "command", instance.get(7, "command").replace( "{#[GUID-5].addr[0].[Address]#}", instance.get_address(5, 0, "Address"))) instance.do_configure() instance.do_prestart() instance.start() while instance.status(7) != AS.STATUS_FINISHED: time.sleep(0.5) ping_result = instance.trace(7, "stdout") or "" instance.stop() finally: try: instance.shutdown() except: pass # asserts at the end, to make sure there's proper cleanup self.assertTrue(re.match(comp_result, ping_result, re.MULTILINE), "Unexpected trace:\n" + ping_result)