From: Alina Quereilhac Date: Fri, 11 Mar 2011 13:57:01 +0000 (+0100) Subject: Daemonized controller woriking ! X-Git-Tag: nepi_v2~188 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=156b6033ed1059ee819996cc4767fa48ca3c25db;p=nepi.git Daemonized controller woriking ! --- diff --git a/src/nepi/util/proxy.py b/src/nepi/util/proxy.py index f9cdcd48..fb730657 100644 --- a/src/nepi/util/proxy.py +++ b/src/nepi/util/proxy.py @@ -1,73 +1,78 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +import base64 from nepi.core.attributes import AttributesMap, Attribute from nepi.util import server from nepi.util import validation import sys -# PROTOCOL MESSAGES -XML = "xml" -ACCESS = "access" -TRACE = "trace" -FINISHED = "finished" -START = "start" -STOP = "stop" -SHUTDOWN = "shutdown" -CONFIGURE = "configure" -CREATE = "create" -CREATE_SET = "create_set" -FACTORY_SET = "factory_set" -CONNECT = "connect" -CROSS_CONNECT = "cross_connect" -ADD_TRACE = "add_trace" -ADD_ADDRESS = "add_address" -ADD_ROUTE = "add_route" -DO_SETUP = "do_setup" -DO_CREATE = "do_create" -DO_CONNECT = "do_connect" -DO_CONFIGURE = "do_configure" -DO_CROSS_CONNECT = "do_cross_connect" -GET = "get" -SET = "set" -ACTION = "action" -STATUS = "status" +# PROTOCOL REPLIES +OK = 0 +ERROR = 1 + +# PROTOCOL INSTRUCTION MESSAGES +XML = 2 +ACCESS = 3 +TRACE = 4 +FINISHED = 5 +START = 6 +STOP = 7 +SHUTDOWN = 8 +CONFIGURE = 9 +CREATE = 10 +CREATE_SET = 11 +FACTORY_SET = 12 +CONNECT = 13 +CROSS_CONNECT = 14 +ADD_TRACE = 15 +ADD_ADDRESS = 16 +ADD_ROUTE = 17 +DO_SETUP = 18 +DO_CREATE = 19 +DO_CONNECT = 20 +DO_CONFIGURE = 21 +DO_CROSS_CONNECT = 22 +GET = 23 +SET = 24 +ACTION = 25 +STATUS = 26 # EXPERIMENT CONTROLER PROTOCOL MESSAGES controller_messages = dict({ - XML: XML, - ACCESS: "%s|%s" % (ACCESS, "%d|%s|%s|%s|%s|%d|%s|%b"), - TRACE: "%s|%s" % (TRACE, "%d|%d|%s"), - FINISHED: "%s|%s" % (FINISHED, "%d"), - START: START, - STOP: STOP, - SHUTDOWN: SHUTDOWN, + XML: "%d" % XML, + ACCESS: "%d|%s" % (ACCESS, "%d|%s|%s|%s|%s|%d|%s|%r"), + TRACE: "%d|%s" % (TRACE, "%d|%d|%s"), + FINISHED: "%d|%s" % (FINISHED, "%d"), + START: "%d" % START, + STOP: "%d" % STOP, + SHUTDOWN: "%d" % SHUTDOWN, }) # TESTBED INSTANCE PROTOCOL MESSAGES testbed_messages = dict({ - TRACE: "%s|%s" % (TRACE, "%d|%s"), - START: "%s|%s" % (START, "%s"), - STOP: "%s|%s" % (STOP, "%s"), - SHUTDOWN: SHUTDOWN, - CONFIGURE: "%s|%s" % (CONFIGURE, "%s|%s"), - CREATE: "%s|%s" % (CREATE, "%d|%s"), - CREATE_SET: "%s|%s" % (CREATE_SET, "%d|%s|%s"), - FACTORY_SET: "%s|%s" % (FACTORY_SET, "%d|%s|%s"), - CONNECT: "%s|%s" % (CONNECT, "%d|%s|%d|%s"), - CROSS_CONNECT: "%s|%s" % (CROSS_CONNECT, "%d|%s|%d|%d|%s|%s"), - ADD_TRACE: "%s|%s" % (ADD_TRACE, "%d|%s"), - ADD_ADDRESS: "%s|%s" % (ADD_ADDRESS, "%d|%d|%s|%d|%s"), - ADD_ROUTE: "%s|%s" % (ADD_ROUTE, "%d|%s|%d|%s"), - DO_SETUP: DO_SETUP, - DO_CREATE: DO_CREATE, - DO_CONNECT: DO_CONNECT, - DO_CONFIGURE: DO_CONFIGURE, - DO_CROSS_CONNECT: DO_CROSS_CONNECT, - GET: "%s|%s" % (GET, "%s|%d|%s"), - SET: "%s|%s" % (SET, "%s|%d|%s|%s"), - ACTION: "%s|%s" % (ACTION, "%s|%d|%s"), - STATUS: "%s|%s" % (STATUS, "%d"), + TRACE: "%d|%s" % (TRACE, "%d|%s"), + START: "%d|%s" % (START, "%s"), + STOP: "%d|%s" % (STOP, "%s"), + SHUTDOWN: "%d" % SHUTDOWN, + CONFIGURE: "%d|%s" % (CONFIGURE, "%s|%s"), + CREATE: "%d|%s" % (CREATE, "%d|%s"), + CREATE_SET: "%d|%s" % (CREATE_SET, "%d|%s|%s"), + FACTORY_SET: "%d|%s" % (FACTORY_SET, "%d|%s|%s"), + CONNECT: "%d|%s" % (CONNECT, "%d|%s|%d|%s"), + CROSS_CONNECT: "%d|%s" % (CROSS_CONNECT, "%d|%s|%d|%d|%s|%s"), + ADD_TRACE: "%d|%s" % (ADD_TRACE, "%d|%s"), + ADD_ADDRESS: "%d|%s" % (ADD_ADDRESS, "%d|%d|%s|%d|%s"), + ADD_ROUTE: "%d|%s" % (ADD_ROUTE, "%d|%s|%d|%s"), + DO_SETUP: "%d" % DO_SETUP, + DO_CREATE: "%d" % DO_CREATE, + DO_CONNECT: "%d" % DO_CONNECT, + DO_CONFIGURE: "%d" % DO_CONFIGURE, + DO_CROSS_CONNECT: "%d" % DO_CROSS_CONNECT, + GET: "%d|%s" % (GET, "%s|%d|%s"), + SET: "%d|%s" % (SET, "%s|%d|%s|%s"), + ACTION: "%d|%s" % (ACTION, "%s|%d|%s"), + STATUS: "%d|%s" % (STATUS, "%d"), }) class AccessConfiguration(AttributesMap): @@ -118,10 +123,10 @@ class AccessConfiguration(AttributesMap): validation_function = validation.is_bool) def create_controller(xml, access_config = None): - from nepi.core.execute import ExperimentController mode = None if not access_config else access_config.get_attribute_value("mode") if not mode or mode == AccessConfiguration.MODE_SINGLE_PROCESS: - return ExperimentController(xml) + from nepi.core.execute import ExperimentController + return ExperimentController(xml) elif mode ==AccessConfiguration.MODE_DAEMON: root_dir = access_config.get_attribute_value("rootDirectory") return ExperimentControllerProxy(xml, root_dir) @@ -143,42 +148,159 @@ def _build_testbed_instance(testbed_id, testbed_version): module = sys.modules[mod_name] return module.TestbedInstance(testbed_version) +class TestbedInstanceServer(server.Server): + def __init__(self, testbed_id, testbed_version, root_dir): + super(TestbedInstanceServer, self).__init__(root_dir) + self._testbed_id = testbed_id + self._testbed_version = testbed_version + self._instance = None + + def post_daemonize(self): + self._instance = _build_testbed_instance(self._testbed_id, + self._testbed_version) + + def reply_action(self, msg): + return "Reply to: %s" % msg + """ + testbed_messages = dict({ + TRACE: "%s|%s" % (TRACE, "%d|%s"), + START: "%s|%s" % (START, "%s"), + STOP: "%s|%s" % (STOP, "%s"), + SHUTDOWN: SHUTDOWN, + CONFIGURE: "%s|%s" % (CONFIGURE, "%s|%s"), + CREATE: "%s|%s" % (CREATE, "%d|%s"), + CREATE_SET: "%s|%s" % (CREATE_SET, "%d|%s|%s"), + FACTORY_SET: "%s|%s" % (FACTORY_SET, "%d|%s|%s"), + CONNECT: "%s|%s" % (CONNECT, "%d|%s|%d|%s"), + CROSS_CONNECT: "%s|%s" % (CROSS_CONNECT, "%d|%s|%d|%d|%s|%s"), + ADD_TRACE: "%s|%s" % (ADD_TRACE, "%d|%s"), + ADD_ADDRESS: "%s|%s" % (ADD_ADDRESS, "%d|%d|%s|%d|%s"), + ADD_ROUTE: "%s|%s" % (ADD_ROUTE, "%d|%s|%d|%s"), + DO_SETUP: DO_SETUP, + DO_CREATE: DO_CREATE, + DO_CONNECT: DO_CONNECT, + DO_CONFIGURE: DO_CONFIGURE, + DO_CROSS_CONNECT: DO_CROSS_CONNECT, + GET: "%s|%s" % (GET, "%s|%d|%s"), + SET: "%s|%s" % (SET, "%s|%d|%s|%s"), + ACTION: "%s|%s" % (ACTION, "%s|%d|%s"), + STATUS: "%s|%s" % (STATUS, "%d"), + }) + """ + +class ExperimentControllerServer(server.Server): + def __init__(self, experiment_xml, root_dir): + super(ExperimentControllerServer, self).__init__(root_dir) + self._experiment_xml = experiment_xml + self._controller = None + + def post_daemonize(self): + from nepi.core.execute import ExperimentController + self._controller = ExperimentController(self._experiment_xml) + + def reply_action(self, msg): + params = msg.split("|") + instruction = int(params[0]) + try: + if instruction == XML: + xml = self._controller.experiment_xml + result = base64.b64encode(xml) + return "%d|%s" % (OK, result) + elif instruction == ACCESS: + testbed_guid = int(params[1]) + mode = params[2] + communication = params[3] + host = params[4] + user = params[5] + port = int(params[6]) + root_dir = params[7] + use_agent = bool(params[8]) + access_config = AccessConfiguration() + access_config.set_attribute_value("mode", mode) + access_config.set_attribute_value("communication", communication) + access_config.set_attribute_value("host", host) + access_config.set_attribute_value("user", user) + access_config.set_attribute_value("port", port) + access_config.set_attribute_value("rootDirectory", root_dir) + access_config.set_attribute_value("useAgent", use_agent) + self._controller.set_access_configuration(testbed_guid, + access_config) + return "%d|%s" % (OK, "") + elif instruction == TRACE: + testbed_guid = int(params[1]) + guid = int(params[2]) + trace_id = params[3] + trace = self._controller.trace(testbed_guid, guid, trace_id) + result = base64.b64encode(trace) + return "%d|%s" % (OK, "%s" % result) + elif instruction == FINISHED: + guid = int(params[1]) + result = self._controller.is_finished(guid) + return "%d|%s" % (OK, "%r" % result) + elif instruction == START: + self._controller.start() + return "%d|%s" % (OK, "") + elif instruction == STOP: + self._controller.stop() + return "%d|%s" % (OK, "") + elif instruction == SHUTDOWN: + self._controller.shutdown() + return "%d|%s" % (OK, "") + else: + error = "Invalid instruction %s" % instruction + self.log_error(error) + result = base64.b64encode(error) + return "%d|%s" % (ERROR, result) + except: + error = self.log_error() + result = base64.b64encode(error) + return "%d|%s" % (ERROR, result) + class TestbedIntanceProxy(object): def __init__(self, testbed_id, testbed_version, root_dir): # launch daemon - server = server.TestbedInstanceServer(testbed_id, testbed_version, + s = TestbedInstanceServer(testbed_id, testbed_version, root_dir) - server.run() + s.run() # create_client self._client = server.Client(root_dir) def configure(self, name, value): - msg = testbed_messages(CONFIGURE) + msg = testbed_messages[CONFIGURE] + # avoid having "|" in this parameters + name = base64.b64encode(name) + value = base64.b64encode(value) msg = msg % (name, value) self._client.send_msg(msg) return self._client.read_reply() def create(self, guid, factory_id): - msg = testbed_messages(CREATE) + msg = testbed_messages[CREATE] msg = msg % (guid, factory_id) self._client.send_msg(msg) return self._client.read_reply() def create_set(self, guid, name, value): - msg = testbed_messages(CREATE_SET) + msg = testbed_messages[CREATE_SET] + # avoid having "|" in this parameters + name = base64.b64encode(name) + value = base64.b64encode(value) msg = msg % (guid, name, value) self._client.send_msg(msg) return self._client.read_reply() def factory_set(self, guid, name, value): - msg = testbed_messages(FACTORY_SET) + msg = testbed_messages[FACTORY_SET] + # avoid having "|" in this parameters + name = base64.b64encode(name) + value = base64.b64encode(value) msg = msg % (guid, name, value) self._client.send_msg(msg) return self._client.read_reply() def connect(self, guid1, connector_type_name1, guid2, connector_type_name2): - msg = testbed_messages(CONNECT) + msg = testbed_messages[CONNECT] msg = msg % (guid1, connector_type_name1, guid2, connector_type_name2) self._client.send_msg(msg) @@ -186,115 +308,126 @@ class TestbedIntanceProxy(object): def cross_connect(self, guid, connector_type_name, cross_guid, cross_testbed_id, cross_factory_id, cross_connector_type_name): - msg = testbed_messages(CROSS_CONNECT) + msg = testbed_messages[CROSS_CONNECT] msg = msg % (guid, connector_type_name, cross_guid, cross_testbed_id, cross_factory_id, cross_connector_type_name) self._client.send_msg(msg) return self._client.read_reply() def add_trace(self, guid, trace_id): - msg = testbed_messages(ADD_TRACE) + msg = testbed_messages[ADD_TRACE] msg = msg % (guid, trace_id) self._client.send_msg(msg) return self._client.read_reply() def add_address(self, guid, family, address, netprefix, broadcast): - msg = testbed_messages(ADD_ADDRESS) + msg = testbed_messages[ADD_ADDRESS] msg = msg % (guid, family, address, netprefix, broadcast) self._client.send_msg(msg) return self._client.read_reply() def add_route(self, guid, destination, netprefix, nexthop): - msg = testbed_messages(ADD_ROUTE) + msg = testbed_messages[ADD_ROUTE] msg = msg % (guid, destination, netprefix, nexthop) self._client.send_msg(msg) return self._client.read_reply() def do_setup(self): - msg = testbed_messages(DO_SETUP) + msg = testbed_messages[DO_SETUP] self._client.send_msg(msg) return self._client.read_reply() def do_create(self): - msg = testbed_messages(DO_CREATE) + msg = testbed_messages[DO_CREATE] self._client.send_msg(msg) return self._client.read_reply() def do_connect(self): - msg = testbed_messages(DO_CONNECT) + msg = testbed_messages[DO_CONNECT] self._client.send_msg(msg) return self._client.read_reply() def do_configure(self): - msg = testbed_messages(DO_CONFIGURE) + msg = testbed_messages[DO_CONFIGURE] self._client.send_msg(msg) return self._client.read_reply() def do_cross_connect(self): - msg = testbed_messages(DO_CROSS_CONNECT) + msg = testbed_messages[DO_CROSS_CONNECT] self._client.send_msg(msg) return self._client.read_reply() def start(self, time): - msg = testbed_messages(START) + msg = testbed_messages[START] msg = msg % (time) self._client.send_msg(msg) return self._client.read_reply() def stop(self, time): - msg = testbed_messages(STOP) + msg = testbed_messages[STOP] msg = msg % (time) self._client.send_msg(msg) return self._client.read_reply() def set(self, time, guid, name, value): - msg = testbed_messages(SET) + msg = testbed_messages[SET] + # avoid having "|" in this parameters + name = base64.b64encode(name) + value = base64.b64encode(value) msg = msg % (time, guid, name, value) self._client.send_msg(msg) return self._client.read_reply() def get(self, time, guid, name): - msg = testbed_messages(GET) + msg = testbed_messages[GET] + # avoid having "|" in this parameters + name = base64.b64encode(name) msg = msg % (time, guid, name) self._client.send_msg(msg) return self._client.read_reply() def action(self, time, guid, action): - msg = testbed_messages(ACTION) + msg = testbed_messages[ACTION] msg = msg % (time, guid, action) self._client.send_msg(msg) return self._client.read_reply() def status(self, guid): - msg = testbed_messages(STATUS) + msg = testbed_messages[STATUS] msg = msg % (guid) self._client.send_msg(msg) return self._client.read_reply() def trace(self, guid, trace_id): - msg = testbed_messages(TRACE) + msg = testbed_messages[TRACE] msg = msg % (guid, trace_id) self._client.send_msg(msg) return self._client.read_reply() def shutdown(self): - msg = testbed_messages(SHUTDOWN) + msg = testbed_messages[SHUTDOWN] self._client.send_msg(msg) return self._client.read_reply() class ExperimentControllerProxy(object): - def __init__(self, root_dir): + def __init__(self, experiment_xml, root_dir): # launch daemon - server = server.ExperimentControllerServer(root_dir) - server.run() + s = ExperimentControllerServer(experiment_xml, root_dir) + s.run() # create_client self._client = server.Client(root_dir) @property def experiment_xml(self): - msg = controller_messages(XML) + msg = controller_messages[XML] self._client.send_msg(msg) - return self._client.read_reply() + reply = self._client.read_reply() + result = reply.split("|") + code = int(result[0]) + text = base64.b64decode(result[1]) + if code == OK: + return text + raise RuntimeError(text) def set_access_configuration(self, testbed_guid, access_config): mode = access_config.get_attribute_value("mode") @@ -304,62 +437,69 @@ class ExperimentControllerProxy(object): port = access_config.get_attribute_value("port") root_dir = access_config.get_attribute_value("rootDirectory") use_agent = access_config.get_attribute_value("useAgent") - msg = controller_messages(ACCESS) + msg = controller_messages[ACCESS] msg = msg % (testbed_guid, mode, communication, host, user, port, root_dir, use_agent) self._client.send_msg(msg) - return self._client.read_reply() + reply = self._client.read_reply() + result = reply.split("|") + code = int(result[0]) + text = base64.b64decode(result[1]) + if code == ERROR: + raise RuntimeError(text) def trace(self, testbed_guid, guid, trace_id): - msg = controller_messages(TRACE) + msg = controller_messages[TRACE] msg = msg % (testbed_guid, guid, trace_id) self._client.send_msg(msg) - return self._client.read_reply() + reply = self._client.read_reply() + result = reply.split("|") + code = int(result[0]) + text = base64.b64decode(result[1]) + if code == OK: + return text + raise RuntimeError(text) def start(self): - msg = controller_messages(START) + msg = controller_messages[START] self._client.send_msg(msg) - return self._client.read_reply() + reply = self._client.read_reply() + result = reply.split("|") + code = int(result[0]) + text = base64.b64decode(result[1]) + if code == ERROR: + raise RuntimeError(text) def stop(self): - msg = controller_messages(STOP) + msg = controller_messages[STOP] self._client.send_msg(msg) - return self._client.read_reply() + reply = self._client.read_reply() + result = reply.split("|") + code = int(result[0]) + text = base64.b64decode(result[1]) + if code == ERROR: + raise RuntimeError(text) def is_finished(self, guid): - msg = controller_messages(FINISED) + msg = controller_messages[FINISHED] msg = msg % guid self._client.send_msg(msg) - return self._client.read_reply() + reply = self._client.read_reply() + result = reply.split("|") + code = int(result[0]) + if code == OK: + return bool(result[1]) + error = base64.b64decode(result[1]) + raise RuntimeError(error) def shutdown(self): - msg = controller_messages(SHUTDOWN) + msg = controller_messages[SHUTDOWN] self._client.send_msg(msg) - return self._client.read_reply() - -class TestbedInstanceServer(server.Server): - def __init__(self, testbed_id, testbed_version, root_dir): - super(TestbedInstanceServer, self).__init__(root_dir) - self._testbed_id = testbed_id - self._testbed_version = testbed_version - self._instance = None - - def post_daemonize(self): - self._instance = _build_testbed_instance(self._testbed_id, - self._testbed_version) - - def reply_action(self, msg): - return "Reply to: %s" % msg - -class ExperimentControllerServer(server.Server): - def __init__(self, xml, root_dir): - super(TestbedInstanceServer, self).__init__(root_dir) - self._xml = xml - self._controller = None - - def post_daemonize(self): - self._controller = ExperimentController(self._xml) - - def reply_action(self, msg): - return "Reply to: %s" % msg + reply = self._client.read_reply() + result = reply.split("|") + code = int(result[0]) + text = base64.b64decode(result[1]) + if code == ERROR: + raise RuntimeError(text) + self._client.send_stop() diff --git a/src/nepi/util/server.py b/src/nepi/util/server.py index 79c7ee6d..1a432ef8 100644 --- a/src/nepi/util/server.py +++ b/src/nepi/util/server.py @@ -24,17 +24,21 @@ class Server(object): self._stderr = None def run(self): - if self.daemonize(): - self.post_daemonize() - self.loop() - self.cleanup() - # ref: "os._exit(0)" - # can not return normally after fork beacuse no exec was done. - # This means that if we don't do a os._exit(0) here the code that - # follows the call to "Server.run()" in the "caller code" will be - # executed... but by now it has already been executed after the - # first process (the one that did the first fork) returned. - os._exit(0) + try: + if self.daemonize(): + self.post_daemonize() + self.loop() + self.cleanup() + # ref: "os._exit(0)" + # can not return normally after fork beacuse no exec was done. + # This means that if we don't do a os._exit(0) here the code that + # follows the call to "Server.run()" in the "caller code" will be + # executed... but by now it has already been executed after the + # first process (the one that did the first fork) returned. + os._exit(0) + except: + self.log_error() + raise def daemonize(self): pid1 = os.fork() @@ -91,15 +95,15 @@ class Server(object): self._stop = True try: reply = self.stop_action() - except e: - sys.stderr.write("ERROR: %s\n" % sys.exc_info()[0]) + except: + self.log_error() self.send_reply(conn, reply) break else: try: reply = self.reply_action(msg) - except e: - sys.stderr.write("ERROR: %s\n" % sys.exc_info()[0]) + except: + self.log_error() self.send_reply(conn, reply) conn.close() @@ -117,7 +121,7 @@ class Server(object): self._ctrl_sock.close() os.remove(CTRL_SOCK) except e: - sys.stderr.write("ERROR: %s\n" % sys.exc_info()[0]) + self.log_error() def stop_action(self): return "Stopping server" @@ -125,6 +129,13 @@ class Server(object): def reply_action(self, msg): return "Reply to: %s" % msg + def log_error(self, error = None): + if error == None: + import traceback + error = "%s\n" % traceback.format_exc() + sys.stderr.write(error) + return error + class Forwarder(object): def __init__(self, root_dir = "."): self._ctrl_sock = None diff --git a/test/core/integration.py b/test/core/integration.py index 1c004721..e7033a68 100755 --- a/test/core/integration.py +++ b/test/core/integration.py @@ -5,17 +5,23 @@ from nepi.core.design import ExperimentDescription, FactoriesProvider from nepi.util.constants import STATUS_FINISHED from nepi.util import proxy import mock -import mock.metadata_v01 +import mock.metadata_v01 +import os +import shutil import sys import time import unittest +import uuid class ExecuteTestCase(unittest.TestCase): def setUp(self): sys.modules["nepi.testbeds.mock.metadata_v01"] = mock.metadata_v01 sys.modules["nepi.testbeds.mock"] = mock + self._root_dir = os.path.join(os.getenv("HOME"), ".nepi", + str(uuid.uuid1())) + os.makedirs(self._root_dir) - def test_integration(self): + def test_single_process_integration(self): exp_desc = ExperimentDescription() testbed_version = "01" testbed_id = "mock" @@ -51,6 +57,48 @@ class ExecuteTestCase(unittest.TestCase): controller.stop() controller.shutdown() + def test_daemonized_controller_integration(self): + exp_desc = ExperimentDescription() + testbed_version = "01" + testbed_id = "mock" + provider = FactoriesProvider(testbed_id, testbed_version) + desc = exp_desc.add_testbed_description(provider) + desc.set_attribute_value("fake", True) + node1 = desc.create("Node") + node2 = desc.create("Node") + iface1 = desc.create("Interface") + iface1.set_attribute_value("fake", True) + node1.connector("devs").connect(iface1.connector("node")) + iface2 = desc.create("Interface") + iface2.set_attribute_value("fake", True) + node2.connector("devs").connect(iface2.connector("node")) + iface1.connector("iface").connect(iface2.connector("iface")) + app = desc.create("Application") + app.connector("node").connect(node1.connector("apps")) + app.enable_trace("fake") + + xml = exp_desc.to_xml() + access_config = proxy.AccessConfiguration() + access_config.set_attribute_value("mode", + proxy.AccessConfiguration.MODE_DAEMON) + access_config.set_attribute_value("rootDirectory", self._root_dir) + controller = proxy.create_controller(xml, access_config) + controller.start() + while not controller.is_finished(app.guid): + time.sleep(0.5) + fake_result = controller.trace(desc.guid, app.guid, "fake") + comp_result = """PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. + +--- 10.0.0.2 ping statistics --- +1 packets transmitted, 1 received, 0% packet loss, time 0ms +""" + self.assertTrue(fake_result.startswith(comp_result)) + controller.stop() + controller.shutdown() + + def tearDown(self): + shutil.rmtree(self._root_dir) + if __name__ == '__main__': unittest.main()