2 # -*- coding: utf-8 -*-
5 from nepi.core.design import ExperimentDescription, FactoriesProvider
6 from nepi.core.execute import ExperimentController
7 from nepi.util import proxy
8 from nepi.util.constants import DeploymentConfiguration as DC
18 class PlanetLabIntegrationTestCase(unittest.TestCase):
19 testbed_id = "planetlab"
20 slicename = "inria_nepi"
21 plchost = "nepiplc.pl.sophia.inria.fr"
23 host1 = "nepi1.pl.sophia.inria.fr"
24 host2 = "nepi2.pl.sophia.inria.fr"
25 host3 = "nepi3.pl.sophia.inria.fr"
26 host4 = "nepi5.pl.sophia.inria.fr"
28 port_base = 2000 + (os.getpid() % 1000) * 13
31 self.root_dir = tempfile.mkdtemp()
32 self.port_base = self.port_base + 100
36 shutil.rmtree(self.root_dir)
40 shutil.rmtree(self.root_dir)
42 def make_experiment_desc(self):
43 testbed_id = self.testbed_id
44 slicename = self.slicename
45 plchost = self.plchost
46 pl_ssh_key = os.environ.get(
48 "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'],) )
49 pl_user, pl_pwd = test_util.pl_auth()
51 exp_desc = ExperimentDescription()
52 pl_provider = FactoriesProvider(testbed_id)
53 pl_desc = exp_desc.add_testbed_description(pl_provider)
54 pl_desc.set_attribute_value("homeDirectory", self.root_dir)
55 pl_desc.set_attribute_value("slice", slicename)
56 pl_desc.set_attribute_value("sliceSSHKey", pl_ssh_key)
57 pl_desc.set_attribute_value("authUser", pl_user)
58 pl_desc.set_attribute_value("authPass", pl_pwd)
59 pl_desc.set_attribute_value("plcHost", plchost)
61 return pl_desc, exp_desc
63 def _test_simple(self, daemonize_testbed, controller_access_configuration, environ = None):
64 pl, exp = self.make_experiment_desc()
66 node1 = pl.create("Node")
67 node2 = pl.create("Node")
68 node1.set_attribute_value("hostname", self.host1)
69 node2.set_attribute_value("hostname", self.host2)
70 iface1 = pl.create("NodeInterface")
71 iface2 = pl.create("NodeInterface")
72 iface2.set_attribute_value("label", "node2iface")
73 inet = pl.create("Internet")
74 node1.connector("devs").connect(iface1.connector("node"))
75 node2.connector("devs").connect(iface2.connector("node"))
76 iface1.connector("inet").connect(inet.connector("devs"))
77 iface2.connector("inet").connect(inet.connector("devs"))
78 app = pl.create("Application")
79 app.set_attribute_value("command", "ping -qc1 {#[node2iface].addr[0].[Address]#}")
80 app.enable_trace("stdout")
81 app.connector("node").connect(node1.connector("apps"))
84 pl.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
85 inst_root_dir = os.path.join(self.root_dir, "instance")
86 os.mkdir(inst_root_dir)
87 pl.set_attribute_value(DC.ROOT_DIRECTORY, inst_root_dir)
88 pl.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)
91 pl.set_attribute_value(DC.DEPLOYMENT_ENVIRONMENT_SETUP, environ)
95 if controller_access_configuration:
96 controller = proxy.create_experiment_controller(xml,
97 controller_access_configuration)
99 controller = ExperimentController(xml, self.root_dir)
103 while not controller.is_finished(app.guid):
105 ping_result = controller.trace(app.guid, "stdout")
106 comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data.
108 --- .* ping statistics ---
109 1 packets transmitted, 1 received, 0% packet loss, time \d*ms.*
111 self.assertTrue(re.match(comp_result, ping_result, re.MULTILINE),
112 "Unexpected trace:\n" + ping_result)
116 controller.shutdown()
118 @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
119 def test_spanning_deployment(self):
120 pl, exp = self.make_experiment_desc()
122 from nepi.testbeds import planetlab as plpackage
124 nodes = [ pl.create("Node") for i in xrange(4) ]
125 ifaces = [ pl.create("NodeInterface") for node in nodes ]
126 inet = pl.create("Internet")
127 for node, iface in zip(nodes,ifaces):
128 node.connector("devs").connect(iface.connector("node"))
129 iface.connector("inet").connect(inet.connector("devs"))
133 app = pl.create("Application")
134 app.set_attribute_value("command", "./consts")
135 app.set_attribute_value("buildDepends", "gcc")
136 app.set_attribute_value("build", "gcc ${SOURCES}/consts.c -o consts")
137 app.set_attribute_value("install", "cp consts ${SOURCES}/consts")
138 app.set_attribute_value("sources", os.path.join(
139 os.path.dirname(plpackage.__file__),'scripts','consts.c'))
140 app.enable_trace("stdout")
141 app.enable_trace("stderr")
142 app.enable_trace("buildlog")
143 node.connector("apps").connect(app.connector("node"))
147 r""".*ETH_P_ALL = 0x[0-9a-fA-F]{8}
148 ETH_P_IP = 0x[0-9a-fA-F]{8}
149 TUNGETIFF = 0x[0-9a-fA-F]{8}
150 TUNSETIFF = 0x[0-9a-fA-F]{8}
151 IFF_NO_PI = 0x[0-9a-fA-F]{8}
152 IFF_TAP = 0x[0-9a-fA-F]{8}
153 IFF_TUN = 0x[0-9a-fA-F]{8}
154 IFF_VNET_HDR = 0x[0-9a-fA-F]{8}
155 TUN_PKT_STRIP = 0x[0-9a-fA-F]{8}
156 IFHWADDRLEN = 0x[0-9a-fA-F]{8}
157 IFNAMSIZ = 0x[0-9a-fA-F]{8}
158 IFREQ_SZ = 0x[0-9a-fA-F]{8}
159 FIONREAD = 0x[0-9a-fA-F]{8}.*
162 comp_build = r".*(Identity added|gcc).*"
166 controller = ExperimentController(xml, self.root_dir)
169 while not all(controller.is_finished(app.guid) for app in apps):
173 app_result = controller.trace(app.guid, "stdout") or ""
174 self.assertTrue(re.match(comp_result, app_result, re.MULTILINE),
175 "Unexpected trace:\n" + app_result)
177 build_result = controller.trace(app.guid, "buildlog") or ""
178 self.assertTrue(re.match(comp_build, build_result, re.MULTILINE | re.DOTALL),
179 "Unexpected trace:\n" + build_result)
183 controller.shutdown()
185 @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
186 def test_simple(self):
188 daemonize_testbed = False,
189 controller_access_configuration = None)
191 @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
192 def test_simple_daemonized(self):
193 access_config = proxy.AccessConfiguration({
194 DC.DEPLOYMENT_MODE : DC.MODE_DAEMON,
195 DC.ROOT_DIRECTORY : self.root_dir,
199 daemonize_testbed = False,
200 controller_access_configuration = access_config)
202 @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
203 def test_z_simple_ssh(self): # _z_ cause we want it last - it messes up the process :(
204 # Recreate environment
205 environ = ' ; '.join( map("export %s=%r".__mod__, os.environ.iteritems()) )
207 env = test_util.test_environment()
209 access_config = proxy.AccessConfiguration({
210 DC.DEPLOYMENT_MODE : DC.MODE_DAEMON,
211 DC.ROOT_DIRECTORY : self.root_dir,
212 DC.LOG_LEVEL : DC.DEBUG_LEVEL,
213 DC.DEPLOYMENT_COMMUNICATION : DC.ACCESS_SSH,
214 DC.DEPLOYMENT_PORT : env.port,
216 DC.DEPLOYMENT_ENVIRONMENT_SETUP : environ,
220 daemonize_testbed = False,
221 controller_access_configuration = access_config,
225 if __name__ == '__main__':