X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=test%2Ftestbeds%2Fplanetlab%2Fexecute.py;h=557425f2ca45bfed9872d2bcfd52a984a0ee2df4;hb=f2029beb7726af4f8d00ba7625be27b49b4db66f;hp=627e256aca0bdc1d6236447688a53ab0578641d9;hpb=552a2b6824a9e07fa6a5189bc7404fed12378d55;p=nepi.git diff --git a/test/testbeds/planetlab/execute.py b/test/testbeds/planetlab/execute.py index 627e256a..557425f2 100755 --- a/test/testbeds/planetlab/execute.py +++ b/test/testbeds/planetlab/execute.py @@ -2,19 +2,47 @@ # -*- coding: utf-8 -*- import getpass -from nepi.util.constants import STATUS_FINISHED +from nepi.util.constants import ApplicationStatus as AS from nepi.testbeds import planetlab import os +import re import shutil +import sys import tempfile +import test_util import time import unittest -import re -import test_util 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: @@ -25,12 +53,17 @@ class PlanetLabExecuteTestCase(unittest.TestCase): shutil.rmtree(self.root_dir) def make_instance(self): - testbed_version = "01" - instance = planetlab.TestbedController(testbed_version) - slicename = "inria_nepi12" + 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) @@ -38,6 +71,15 @@ class PlanetLabExecuteTestCase(unittest.TestCase): 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 @@ -46,9 +88,9 @@ class PlanetLabExecuteTestCase(unittest.TestCase): instance = self.make_instance() instance.defer_create(2, "Node") - instance.defer_create_set(2, "hostname", "onelab11.pl.sophia.inria.fr") + instance.defer_create_set(2, "hostname", self.host1) instance.defer_create(3, "Node") - instance.defer_create_set(3, "hostname", "onelab10.pl.sophia.inria.fr") + 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") @@ -84,13 +126,17 @@ class PlanetLabExecuteTestCase(unittest.TestCase): instance.do_configure() + instance.do_prestart() instance.start() - while instance.status(7) != STATUS_FINISHED: + while instance.status(7) != AS.STATUS_FINISHED: time.sleep(0.5) ping_result = instance.trace(7, "stdout") or "" instance.stop() finally: - instance.shutdown() + 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), @@ -101,7 +147,7 @@ class PlanetLabExecuteTestCase(unittest.TestCase): instance = self.make_instance() instance.defer_create(2, "Node") - instance.defer_create_set(2, "hostname", "onelab11.pl.sophia.inria.fr") + 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") @@ -121,14 +167,18 @@ class PlanetLabExecuteTestCase(unittest.TestCase): instance.do_preconfigure() instance.do_configure() + instance.do_prestart() instance.start() - while instance.status(5) != STATUS_FINISHED: + 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: - instance.shutdown() + 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), @@ -139,7 +189,7 @@ class PlanetLabExecuteTestCase(unittest.TestCase): instance = self.make_instance() instance.defer_create(2, "Node") - instance.defer_create_set(2, "hostname", "onelab11.pl.sophia.inria.fr") + 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") @@ -157,6 +207,7 @@ class PlanetLabExecuteTestCase(unittest.TestCase): 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} @@ -177,13 +228,17 @@ FIONREAD = 0x[0-9a-fA-F]{8}.* instance.do_preconfigure() instance.do_configure() + instance.do_prestart() instance.start() - while instance.status(10) != STATUS_FINISHED: + while instance.status(10) != AS.STATUS_FINISHED: time.sleep(0.5) ping_result = instance.trace(10, "stdout") or "" instance.stop() finally: - instance.shutdown() + 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), @@ -194,14 +249,13 @@ FIONREAD = 0x[0-9a-fA-F]{8}.* instance = self.make_instance() instance.defer_create(2, "Node") - instance.defer_create_set(2, "hostname", "onelab11.pl.sophia.inria.fr") - instance.defer_create_set(2, "emulation", True) # require emulation + 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, "192.168.2.2", 24, False) + 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", """ @@ -225,14 +279,18 @@ echo 'OKIDOKI' instance.do_preconfigure() instance.do_configure() + instance.do_prestart() instance.start() - while instance.status(6) != STATUS_FINISHED: + 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: - instance.shutdown() + try: + instance.shutdown() + except: + pass # asserts at the end, to make sure there's proper cleanup self.assertEqual(comp_result, test_result) @@ -242,8 +300,7 @@ echo 'OKIDOKI' instance = self.make_instance() instance.defer_create(2, "Node") - instance.defer_create_set(2, "hostname", "onelab11.pl.sophia.inria.fr") - instance.defer_create_set(2, "emulation", True) # require emulation + 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") @@ -273,8 +330,9 @@ echo 'OKIDOKI' instance.do_preconfigure() instance.do_configure() + instance.do_prestart() instance.start() - while instance.status(8) != STATUS_FINISHED: + 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[0-9]+)m(?P[0-9]+[.][0-9]+)s.*" @@ -282,7 +340,10 @@ echo 'OKIDOKI' instance.stop() finally: - instance.shutdown() + 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) @@ -295,45 +356,13 @@ echo 'OKIDOKI' 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 test_tun_emulation_requirement(self): - instance = self.make_instance() - - instance.defer_create(2, "Node") - instance.defer_create_set(2, "hostname", "onelab11.pl.sophia.inria.fr") - 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, "192.168.2.2", 24, False) - instance.defer_connect(2, "devs", 5, "node") - instance.defer_create(6, "Application") - instance.defer_create_set(6, "command", "false") - 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() - self.fail("Usage of TUN without emulation should fail") - except Exception,e: - pass - - @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): + 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", "onelab11.pl.sophia.inria.fr") - instance.defer_create_set(2, "emulation", True) # require emulation + instance.defer_create_set(2, "hostname", self.host1) instance.defer_create(3, "Node") - instance.defer_create_set(3, "hostname", "onelab10.pl.sophia.inria.fr") - instance.defer_create_set(3, "emulation", True) # require emulation + 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") @@ -341,24 +370,62 @@ echo 'OKIDOKI' instance.defer_create(6, "NodeInterface") instance.defer_connect(3, "devs", 6, "node") instance.defer_connect(6, "inet", 5, "devs") - instance.defer_create(7, "TunInterface") - instance.defer_add_address(7, "192.168.2.2", 24, False) + 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, "TunInterface") - instance.defer_add_address(8, "192.168.2.3", 24, False) + 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_connect(7, "tcp", 8, "tcp") instance.defer_create(9, "Application") - instance.defer_create_set(9, "command", "ping -qc1 {#[GUID-8].addr[0].[Address]#}") + 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 --- -1 packets transmitted, 1 received, 0% packet loss, time \d*ms.* -""" +10 packets transmitted, [0-9]+ received,.* %s%% packet loss, time \d*ms.* +""" % (plr,) + if flood: + comp_result = ".*" + comp_result try: instance.do_setup() @@ -376,24 +443,89 @@ echo 'OKIDOKI' instance.do_configure() + instance.do_prestart() instance.start() - while instance.status(9) != STATUS_FINISHED: + 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: - instance.shutdown() + 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) + 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", "onelab11.pl.sophia.inria.fr") + 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") @@ -413,13 +545,17 @@ echo 'OKIDOKI' instance.do_preconfigure() instance.do_configure() + instance.do_prestart() instance.start() - while instance.status(12) != STATUS_FINISHED: + while instance.status(12) != AS.STATUS_FINISHED: time.sleep(0.5) ping_result = (instance.trace(12, "stderr") or "").strip() instance.stop() finally: - instance.shutdown() + try: + instance.shutdown() + except: + pass # asserts at the end, to make sure there's proper cleanup self.assertEqual(ping_result, "") @@ -432,7 +568,7 @@ echo 'OKIDOKI' instance = self.make_instance() instance.defer_create(2, "Node") - instance.defer_create_set(2, "hostname", "onelab11.pl.sophia.inria.fr") + 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") @@ -443,7 +579,7 @@ echo 'OKIDOKI' 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(\"3_9_RC3\") ; mod = tb._load_ns3_module()'") + 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: @@ -454,16 +590,80 @@ echo 'OKIDOKI' instance.do_preconfigure() instance.do_configure() + instance.do_prestart() instance.start() - while instance.status(12) != STATUS_FINISHED: + while instance.status(12) != AS.STATUS_FINISHED: time.sleep(0.5) ping_result = (instance.trace(12, "stderr") or "").strip() instance.stop() finally: - instance.shutdown() + 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) + if __name__ == '__main__':