advancing the testbed instance daemon.
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Fri, 11 Mar 2011 17:41:09 +0000 (18:41 +0100)
committerAlina Quereilhac <alina.quereilhac@inria.fr>
Fri, 11 Mar 2011 17:41:09 +0000 (18:41 +0100)
src/nepi/util/proxy.py
test/core/integration.py

index fb73065..afcee74 100644 (file)
@@ -38,6 +38,12 @@ SET = 24
 ACTION  = 25
 STATUS  = 26
 
+# PARAMETER TYPE
+STRING  =  100
+INTEGER = 101
+BOOL    = 102
+FLOAT   = 103
+
 # EXPERIMENT CONTROLER PROTOCOL MESSAGES
 controller_messages = dict({
     XML:    "%d" % XML,
@@ -55,10 +61,10 @@ testbed_messages = dict({
     START:  "%d|%s" % (START, "%s"),
     STOP:    "%d|%s" % (STOP, "%s"),
     SHUTDOWN:   "%d" % SHUTDOWN,
-    CONFIGURE: "%d|%s" % (CONFIGURE, "%s|%s"),
+    CONFIGURE: "%d|%s" % (CONFIGURE, "%s|%s|%d"),
     CREATE: "%d|%s" % (CREATE, "%d|%s"),
-    CREATE_SET: "%d|%s" % (CREATE_SET, "%d|%s|%s"),
-    FACTORY_SET: "%d|%s" % (FACTORY_SET, "%d|%s|%s"),
+    CREATE_SET: "%d|%s" % (CREATE_SET, "%d|%s|%s|%d"),
+    FACTORY_SET: "%d|%s" % (FACTORY_SET, "%d|%s|%s|%d"),
     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"),
@@ -70,11 +76,32 @@ testbed_messages = dict({
     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"),
+    SET:    "%d|%s" % (SET, "%s|%d|%s|%s|%d"),
     ACTION: "%d|%s" % (ACTION, "%s|%d|%s"),
     STATUS: "%d|%s" % (STATUS, "%d"),
     })
 
+def get_type(value):
+    if isinstance(value, bool):
+        return BOOL
+    elif isinstance(value, int):
+        return INTEGER
+    elif isinstance(value, float):
+        return FLOAT
+    else:
+        return STRING
+
+def set_type(type, value):
+    if type == INTEGER:
+        value = int(value)
+    elif type == FLOAT:
+        value = float(value)
+    elif type == BOOL:
+        value = bool(value)
+    else:
+        value = str(value)
+    return value
+
 class AccessConfiguration(AttributesMap):
     MODE_SINGLE_PROCESS = "SINGLE"
     MODE_DAEMON = "DAEMON"
@@ -160,34 +187,216 @@ class TestbedInstanceServer(server.Server):
                 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"),
-            })
-        """
+        params = msg.split("|")
+        instruction = int(params[0])
+        try:
+            if instruction == TRACE:
+                return self.trace(params)
+            elif instruction == START:
+                return self.start(params)
+            elif instruction == STOP:
+                return self.stop(params)
+            elif instruction == SHUTDOWN:
+                return self.shutdown(params)
+            elif instruction == CONFIGURE:
+                return self.configure(params)
+            elif instruction == CREATE:
+                return self.create(params)
+            elif instruction == CREATE_SET:
+                return self.create_set(params)
+            elif instruction == FACTORY_SET:
+                return self.factory_set(params)
+            elif instruction == CONNECT:
+                return self.connect(params)
+            elif instruction == CROSS_CONNECT:
+                return self.cross_connect(params)
+            elif instruction == ADD_TRACE:
+                return self.add_trace(params)
+            elif instruction == ADD_ADDRESS:
+                return self.add_address(params)
+            elif instruction == ADD_ROUTE:
+                return self.add_route(params)
+            elif instruction == DO_SETUP:
+                return self.do_setup(params)
+            elif instruction == DO_CREATE:
+                return self.do_create(params)
+            elif instruction == DO_CONNECT:
+                return self.do_connect(params)
+            elif instruction == DO_CONFIGURE:
+                return self.do_configure(params)
+            elif instruction == DO_CROSS_CONNECT:
+                return self.do_cross_connect(params)
+            elif instruction == GET:
+                return self.get(params)
+            elif instruction == SET:
+                return self.set(params)
+            elif instruction == ACTION:
+                return self.action(params)
+            elif instruction == STATUS:
+                return self.status(params)
+            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)
 
+    def create(self, params):
+        guid = int(params[1])
+        factory_id = params[2]
+        self._instance.create(guid, factory_id)
+        return "%d|%s" % (OK, "")
+
+    def trace(self, params):
+        guid = int(params[1])
+        trace_id = params[2]
+        trace = self._instance.trace(guid, trace_id)
+        result = base64.b64encode(trace)
+        return "%d|%s" % (OK, result)
+
+    def start(self, params):
+        time = params[1]
+        self._instance.start(time)
+        return "%d|%s" % (OK, "")
+
+    def stop(self, params):
+        time = params[1]
+        self._instance.stop(time)
+        return "%d|%s" % (OK, "")
+
+    def shutdown(self, params):
+        self._instance.shutdown()
+        return "%d|%s" % (OK, "")
+
+    def configure(self, params):
+        name = base64.b64decode(params[1])
+        value = base64.b64decode(params[2])
+        type = int(params[3])
+        value = set_type(type, value)
+        self._instance.configure(name, value)
+        return "%d|%s" % (OK, "")
+
+    def trace(self, params):
+        guid = int(params[1])
+        factory_id = params[2]
+        self._instance.trace(guid, factory_id)
+        return "%d|%s" % (OK, "")
+
+    def create_set(self, params):
+        name = base64.b64decode(params[1])
+        value = base64.b64decode(params[2])
+        type = int(params[3])
+        value = set_type(type, value)
+        self._instance.create_set(name, value)
+        return "%d|%s" % (OK, "")
+
+    def factory_set(self, params):
+        name = base64.b64decode(params[1])
+        value = base64.b64decode(params[2])
+        type = int(params[3])
+        value = set_type(type, value)
+        self._instance.factory_set(name, value)
+        return "%d|%s" % (OK, "")
+
+    def connect(self, params):
+        guid1 = int(params[1])
+        connector_type_name1 = params[2]
+        guid2 = int(params[3])
+        connector_type_name2 = params[4]
+        self._instance.connect(guid1, connector_type_name1, guid2, 
+            connector_type_name2)
+        return "%d|%s" % (OK, "")
+
+    def cross_connect(self, params):
+        guid = int(params[1])
+        connector_type_name = params[2]
+        cross_guid = int(params[3])
+        connector_type_name = params[4]
+        cross_guid = int(params[5])
+        cross_testbed_id = params[6]
+        cross_factory_id = params[7]
+        cross_connector_type_name = params[8]
+        self._instance.cross_connect(guid, connector_type_name, cross_guid, 
+            cross_testbed_id, cross_factory_id, cross_connector_type_name)
+        return "%d|%s" % (OK, "")
+
+    def add_trace(self, params):
+        guid = int(params[1])
+        trace_id = params[2]
+        self._instance.add_trace(guid, trace_id)
+        return "%d|%s" % (OK, "")
+
+    def add_address(self, params):
+        guid = int(params[1])
+        family = int(params[2])
+        address = params[3]
+        netprefix = int(params[4])
+        broadcast = params[5]
+        self._instance.add_address(guid, family, address, netprefix,
+                broadcast)
+        return "%d|%s" % (OK, "")
+
+    def add_route(self, params):
+        guid = int(params[1])
+        destination = params[2]
+        netprefix = int(params[3])
+        nexthop = params[4]
+        self._instance.add_route(guid, destination, netprefix, nexthop)
+        return "%d|%s" % (OK, "")
+
+    def do_setup(self, params):
+        self._instance.do_setup()
+        return "%d|%s" % (OK, "")
+
+    def do_create(self, params):
+        self._instance.do_create()
+        return "%d|%s" % (OK, "")
+
+    def do_connect(self, params):
+        self._instance.do_connect()
+        return "%d|%s" % (OK, "")
+
+    def do_configure(self, params):
+        self._instance.do_configure()
+        return "%d|%s" % (OK, "")
+
+    def do_cross_connect(self, params):
+        self._instance.do_cross_connect()
+        return "%d|%s" % (OK, "")
+
+    def get(self, params):
+        time = params[1]
+        guid = int(param[2] )
+        name = base64.b64decode(params[3])
+        value = self._instance.get(time, guid, name)
+        result = base64.b64encode(str(value))
+        return "%d|%s" % (OK, result)
+
+    def set(self, params):
+        time = params[1]
+        guid = int(params[2])
+        name = base64.b64decode(params[3])
+        value = base64.b64decode(params[4])
+        type = int(params[3])
+        value = set_type(type, value)
+        self._instance.set(time, guid, name, value)
+        return "%d|%s" % (OK, "")
+
+    def action(self, params):
+        time = params[1]
+        guid = int(params[2])
+        command = base64.b64decode(params[3])
+        self._instance.action(time, guid, command)
+        return "%d|%s" % (OK, "")
+
+    def status(self, params):
+        guid = int(params[1])
+        status = self._instance.status(guid)
+        return "%d|%s" % (OK, "%d" % status)
 class ExperimentControllerServer(server.Server):
     def __init__(self, experiment_xml, root_dir):
         super(ExperimentControllerServer, self).__init__(root_dir)
@@ -203,49 +412,19 @@ class ExperimentControllerServer(server.Server):
         instruction = int(params[0])
         try:
             if instruction == XML:
-                xml = self._controller.experiment_xml
-                result = base64.b64encode(xml)
-                return "%d|%s" % (OK, result)
+                return self.experiment_xml(params)
             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, "")
+                return self.set_access_configuration(params)
             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)
+                return self.trace(params)
             elif instruction == FINISHED:
-                guid = int(params[1])
-                result = self._controller.is_finished(guid)
-                return "%d|%s" % (OK, "%r" % result)
+                return self.is_finished(params)
             elif instruction == START:
-                self._controller.start()
-                return "%d|%s" % (OK, "")
+                return self.start(params)
             elif instruction == STOP:
-                self._controller.stop()
-                return "%d|%s" % (OK, "")
+                return self.stop(params)
             elif instruction == SHUTDOWN:
-                self._controller.shutdown()
-                return "%d|%s" % (OK, "")
+                return self.shutdown(params)
             else:
                 error = "Invalid instruction %s" % instruction
                 self.log_error(error)
@@ -256,6 +435,57 @@ class ExperimentControllerServer(server.Server):
             result = base64.b64encode(error)
             return "%d|%s" % (ERROR, result)
 
+    def experiment_xml(self, parameters):
+        xml = self._controller.experiment_xml
+        result = base64.b64encode(xml)
+        return "%d|%s" % (OK, result)
+
+    def set_access_configuration(self, parameters):
+        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, "")
+
+    def trace(self, parameters):
+        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)
+
+    def is_finished(self, parameters):
+        guid = int(params[1])
+        result = self._controller.is_finished(guid)
+        return "%d|%s" % (OK, "%r" % result)
+
+    def start(self, parameters):
+        self._controller.start()
+        return "%d|%s" % (OK, "")
+
+    def stop(self, parameters):
+        self._controller.stop()
+        return "%d|%s" % (OK, "")
+
+    def shutdown(self, parameters):
+        self._controller.shutdown()
+        return "%d|%s" % (OK, "")
+
 class TestbedIntanceProxy(object):
     def __init__(self, testbed_id, testbed_version, root_dir):
         # launch daemon
@@ -267,36 +497,59 @@ class TestbedIntanceProxy(object):
 
     def configure(self, name, value):
         msg = testbed_messages[CONFIGURE]
+        type = get_type(value)
         # avoid having "|" in this parameters
         name = base64.b64encode(name)
-        value = base64.b64encode(value)
-        msg = msg % (name, value)
+        value = base64.b64encode(str(value))
+        msg = msg % (name, value, type)
         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 create(self, guid, factory_id):
         msg = testbed_messages[CREATE]
         msg = msg % (guid, factory_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 == ERROR:
+            raise RuntimeError(text)
 
     def create_set(self, guid, name, value):
         msg = testbed_messages[CREATE_SET]
+        type = get_type(value)
         # avoid having "|" in this parameters
         name = base64.b64encode(name)
-        value = base64.b64encode(value)
-        msg = msg % (guid, name, value)
+        value = base64.b64encode(str(value))
+        msg = msg % (guid, name, value, type)
         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 factory_set(self, guid, name, value):
         msg = testbed_messages[FACTORY_SET]
+        type = get_type(value)
         # avoid having "|" in this parameters
         name = base64.b64encode(name)
-        value = base64.b64encode(value)
-        msg = msg % (guid, name, value)
+        value = base64.b64encode(str(value))
+        msg = msg % (guid, name, value, type)
         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 connect(self, guid1, connector_type_name1, guid2, 
             connector_type_name2): 
@@ -304,7 +557,12 @@ class TestbedIntanceProxy(object):
         msg = msg % (guid1, connector_type_name1, guid2, 
             connector_type_name2)
         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 cross_connect(self, guid, connector_type_name, cross_guid, 
             cross_testbed_id, cross_factory_id, cross_connector_type_name):
@@ -312,71 +570,131 @@ class TestbedIntanceProxy(object):
         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()
+        reply = self._client.read_reply()
+        result = reply.split("|")
+        code = int(result[0])
+        text = base64.b64decode(result[1])
+        if code == ERROR:
+            raise RuntimeError(text)
 
     def add_trace(self, guid, trace_id):
         msg = testbed_messages[ADD_TRACE]
         msg = msg % (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 == ERROR:
+            raise RuntimeError(text)
 
     def add_address(self, guid, family, address, netprefix, broadcast): 
         msg = testbed_messages[ADD_ADDRESS]
         msg = msg % (guid, family, address, netprefix, broadcast)
         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 add_route(self, guid, destination, netprefix, nexthop):
         msg = testbed_messages[ADD_ROUTE]
         msg = msg % (guid, destination, netprefix, nexthop)
         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 do_setup(self):
         msg = testbed_messages[DO_SETUP]
         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 do_create(self):
         msg = testbed_messages[DO_CREATE]
         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 do_connect(self):
         msg = testbed_messages[DO_CONNECT]
         self._client.send_msg(msg)
-        return self._client.read_reply()
+        result = reply.split("|")
+        code = int(result[0])
+        text = base64.b64decode(result[1])
+        if code == ERROR:
+            raise RuntimeError(text)
 
     def do_configure(self):
         msg = testbed_messages[DO_CONFIGURE]
         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 do_cross_connect(self):
         msg = testbed_messages[DO_CROSS_CONNECT]
         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 start(self, time):
         msg = testbed_messages[START]
         msg = msg % (time)
         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, time):
         msg = testbed_messages[STOP]
         msg = msg % (time)
         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 set(self, time, guid, name, value):
         msg = testbed_messages[SET]
+        type = get_type(value)
         # avoid having "|" in this parameters
         name = base64.b64encode(name)
-        value = base64.b64encode(value)
-        msg = msg % (time, guid, name, value)
+        value = base64.b64encode(str(value))
+        msg = msg % (time, guid, name, value, type)
         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 get(self, time, guid, name):
         msg = testbed_messages[GET]
@@ -384,30 +702,58 @@ class TestbedIntanceProxy(object):
         name = base64.b64encode(name)
         msg = msg % (time, guid, name)
         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)
+        return text
 
     def action(self, time, guid, action):
         msg = testbed_messages[ACTION]
         msg = msg % (time, guid, action)
         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 status(self, guid):
         msg = testbed_messages[STATUS]
         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])
+        text = base64.b64decode(result[1])
+        if code == ERROR:
+            raise RuntimeError(text)
+        return bool(text)
 
     def trace(self, guid, trace_id):
         msg = testbed_messages[TRACE]
         msg = msg % (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 == ERROR:
+            raise RuntimeError(text)
+        return text
 
     def shutdown(self):
         msg = testbed_messages[SHUTDOWN]
         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)
 
 class ExperimentControllerProxy(object):
     def __init__(self, experiment_xml, root_dir):
index e7033a6..8c52af3 100755 (executable)
@@ -89,6 +89,46 @@ class ExecuteTestCase(unittest.TestCase):
         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 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()
+        controller = proxy.create_controller(xml, access_config = None)
+        access_config = proxy.AccessConfiguration()
+        access_config.set_attribute_value("mode", 
+                proxy.AccessConfiguration.MODE_DAEMON)
+        access_config.set_attribute_value("rootDirectory", self._root_dir)
+        controller.set_access_configuration(desc.guid, 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
 """