Exemplo n.º 1
0
 def post_load(self):
     """
     Restore client connection and remote state after loading local state.
     """
     self._client = Client(self._host, self._port)
     self._client.start(self._typname, self._objname)
     self._restore(self)
     super(ComponentProxy, self).post_load()
Exemplo n.º 2
0
    def __init__(self, typname, host, port):
        self._typname = typname
        self._objname = 'the_obj'
        self._host = host
        self._port = port

        self._client = Client(host, port)
        self._client.start(typname, self._objname)
        super(ComponentProxy, self).__init__()

        # Add properties (variables).
        self._populate(self, self._objname)

        # Add methods.
        self._methods = self._client.list_methods(self._objname)
        self._add_methods()
Exemplo n.º 3
0
    def __init__(self, typname, host, port):
        self._typname = typname
        self._objname = 'the_obj'
        self._host = host
        self._port = port

        trace = bool(os.environ.get('AS_TRACE_PROXY'))
        self._client = Client(host, port, trace)
        self._client.start(typname, self._objname)
        super(ComponentProxy, self).__init__()

        # Add properties (variables).
        self._populate(self, self._objname)

        # Add methods.
        self._methods = self._client.list_methods(self._objname)
        self._add_methods()
Exemplo n.º 4
0
    def __init__(self, typname, host, port):
        self._typname = typname
        self._objname = 'the_obj'
        self._host = host
        self._port = port

        self._client = Client(host, port)
        self._client.start(typname, self._objname)
        super(ComponentProxy, self).__init__()
        self._populate(self, self._objname)
Exemplo n.º 5
0
    def __init__(self, typname, host, port):
        self._typname = typname
        self._objname = 'the_obj'
        self._host = host
        self._port = port

        self._client = Client(host, port)
        self._client.start(typname, self._objname)
        super(ComponentProxy, self).__init__()

        # Add properties (variables).
        self._populate(self, self._objname)

        # Add methods.
        self._methods = self._client.list_methods(self._objname)
        self._add_methods()
Exemplo n.º 6
0
    def setUp(self):
        logging.info("---------------- Starting test %s" % self.id())

        self.testdir = os.path.dirname(os.path.abspath(__file__))
        self.tempdir = tempfile.mkdtemp(prefix=self.id().split('.')[-1]+'_')

        os.makedirs(os.path.join(self.tempdir, 'd1'))
        os.makedirs(os.path.join(self.tempdir, 'd2/d3'))

        shutil.copy(os.path.join(self.testdir, 'ASTestComp.py'),
                    os.path.join(self.tempdir, 'd2', 'd3'))
        shutil.copy(os.path.join(self.testdir, 'TestCompProblem.cfg'),
                    os.path.join(self.tempdir, 'd2', 'd3'))

        os.chdir(self.tempdir)

        try:
            self.server, self.port = start_server(args=['-c', self.tempdir])
            self.client = Client(port=self.port)
        except:
            os.chdir(STARTDIR)
            raise
Exemplo n.º 7
0
    def test_execute(self):
        try:
            self.server, self.port = start_server(args=['-c', 'TestParDOEProblem.cfg'])
            self.client = Client(port=self.port)
        except:
            os.chdir(STARTDIR)
            raise

        reply = self.client.start('TestParDOEProblem', 'p')

        # set some input cases [indep_var.a, indep_var.b, indep_var.c]
        ncases = 20
        cases = numpy.arange(3.0*ncases).reshape(ncases, 3)
        self.client.set('p.driver.desvar_array', array2str(cases))
        self.client.execute('p')
        results = str2array(self.client.get('p.driver.response_array'))

        for i in range(results.shape[0]):
            for j in range(i, results.shape[0]):
                if i!=j and results[i][0] == results[j][0]:
                    logging.info("*** indices %d and %d match" % (i,j))

        # test to make sure that the set/get array -> str -> array conversion
        # works.
        numpy.testing.assert_array_almost_equal(cases,
                           str2array(self.client.get('p.driver.desvar_array')),
                           decimal=9)

        # we registered our case inputs as responses (first 3 cols of results)
        # so make sure their values haven't changed, and are in the same
        # order as we sent them.
        numpy.testing.assert_array_almost_equal(cases, results[:,:3],
                                                decimal=9)

        mult = numpy.array([2.0, 3.0, 1.5])
        for i in range(cases.shape[0]):
            numpy.testing.assert_array_almost_equal(results[i,3:],
                                                    cases[i]*mult, decimal=9)
Exemplo n.º 8
0
class ComponentProxy(Component):
    """
    Proxy for a component running under an AnalysisServer.
    The proxy will populate itself with proxies for all variables exposed
    by the remote component, in an identical hierarchy.

    typname: string
        Component type.

    host: string
        Hostname of server.

    port: int
        Port on `host` used by server.

    Communications between the proxy and AnalysisServer can be traced
    by setting environment variable ``AS_TRACE_PROXY`` to ``1``.

    .. note::
        While variable attributes like 'units' are read from the remote
        component, attempts to set attributes other than 'value' from the local
        side will have no effect on the remote side.
    """

    def __init__(self, typname, host, port):
        self._typname = typname
        self._objname = 'the_obj'
        self._host = host
        self._port = port

        trace = bool(os.environ.get('AS_TRACE_PROXY'))
        self._client = Client(host, port, trace)
        self._client.start(typname, self._objname)
        super(ComponentProxy, self).__init__()

        # Add properties (variables).
        self._populate(self, self._objname)

        # Add methods.
        self._methods = self._client.list_methods(self._objname)
        self._add_methods()

    def _populate(self, container, path):
        """
        Populate a container from a remote object.

        container: Container
            The local container object to be populated.

        path: string
            Path on server corresponding to `container`.
        """
        info = self._client.list_properties(path)
        for prop, typ, iotype in info:
            if hasattr(container, prop):
                container.raise_exception('Name %r already bound to %r'
                                          % (prop, getattr(container, prop)),
                                          AttributeError)

            rpath = '.'.join([path, prop])
            if typ == 'PHXDouble' or typ == 'PHXLong' or typ == 'PHXString':
                enum_valstrs = self._client.get(rpath+'.enumValues')
                if enum_valstrs:
                    container.add(prop,
                                  EnumProxy(iotype, self._client, rpath,
                                            typ, enum_valstrs))
                    continue

            if typ == 'PHXBoolean':
                container.add(prop, BoolProxy(iotype, self._client, rpath))
            elif typ == 'PHXDouble':
                container.add(prop, FloatProxy(iotype, self._client, rpath))
            elif typ == 'PHXLong':
                container.add(prop, IntProxy(iotype, self._client, rpath))
            elif typ == 'PHXRawFile':
                container.add(prop, FileProxy(iotype, self._client, rpath,
                                              self))
            elif typ == 'PHXString':
                container.add(prop, StrProxy(iotype, self._client, rpath))
            elif typ == 'PHXGroup':
                group = container.add(prop, Container())
                self._populate(group, rpath)  # Recurse.

            elif typ.startswith('double['):
                container.add(prop, ArrayProxy(iotype, self._client, rpath,
                                               float))
            elif typ.startswith('long['):
                container.add(prop, ArrayProxy(iotype, self._client, rpath,
                                               int))
            elif typ.startswith('java.lang.String['):
                container.add(prop, ListProxy(iotype, self._client, rpath,
                                              str))
            elif typ == 'PHXScriptObject':
                container.add(prop, VarTree(ObjProxy(iotype, self._client, rpath)))
            else:
                self._logger.warning('Unsupported property: %r type %r',
                                     prop, typ)

    def _add_methods(self):
        """ Add methods to invoke remote methods. """
        for name in self._methods:
            if hasattr(self, name):
                self.raise_exception('Name %r already bound to %r'
                                     % (name, getattr(self, name)),
                                     AttributeError)
            dct = {}
            exec """
def %s(self):
    return self._invoke_method(%r)
""" % (name, name) in dct
            setattr(self, name,
                    types.MethodType(dct[name], self, self.__class__))

    def __getstate__(self):
        """ Return dict representing this component's local state. """
        state = super(ComponentProxy, self).__getstate__()
        del state['_client']
        for name in self._methods:
            del state[name]
        return state

    def __setstate__(self, state):
        """ Restore this component's local state. """
        state['_client'] = None
        super(ComponentProxy, self).__setstate__(state)
        self._add_methods()

    def post_load(self):
        """
        Restore client connection and remote state after loading local state.
        """
        self._client = Client(self._host, self._port)
        self._client.start(self._typname, self._objname)
        self._restore(self)
        super(ComponentProxy, self).post_load()

    def _restore(self, container):
        """ Restore remote state (variables don't have a post_load()). """
        # Using _alltraits() here because at this point items()
        # considers the ProxyMixin traits as 'Missing'.
        for name, trait in container._alltraits().items():
            typ = trait.trait_type
            if isinstance(typ, ProxyMixin):
                typ.restore(self._client)

        for name, obj in container.items():
            if is_instance(obj, Container):
                if isinstance(obj, ObjProxy):
                    obj.restore(self._client)
                else:
                    self._restore(obj)  # Recurse.

    def pre_delete(self):
        """ Unload remote instance before we get deleted. """
        super(ComponentProxy, self).pre_delete()
        if self._client is not None:
            self._client.end(self._objname)
            self._client.quit()
            self._client = None

    def execute(self):
        """ Execute remote component. """
        self._flush_proxies()
        self._client.execute(self._objname)
        self._update_proxies()

    def _invoke_method(self, name):
        """ Invoke remote method. """
        self._flush_proxies()
        result = self._client.invoke('%s.%s' % (self._objname, name))
        self._update_proxies()
        return result

    def _flush_proxies(self):
        """ Flush all 'in' object proxies. """
        for name, obj in self.items():
            if isinstance(obj, VariableTree):
                if obj.iotype == 'in':
                    obj.flush()

    def _update_proxies(self):
        """ Update all 'out' object proxies. """
        for name, obj in self.items():
            if isinstance(obj, VariableTree):
                if obj.iotype == 'out':
                    obj.update()
Exemplo n.º 9
0
class ComponentProxy(Component):
    """
    Proxy for a component running under an AnalysisServer.
    The proxy will populate itself with proxies for all variables exposed
    by the remote component, in an identical hierarchy.

    .. note::
        While variable attributes like 'units' are read from the remote
        component, attempts to set attributes other than 'value' from the local
        side will have no effect on the remote side.

    typname: string
        Component type.

    host: string
        Hostname of server.

    port: int
        Port on `host` used by server.
    """

    def __init__(self, typname, host, port):
        self._typname = typname
        self._objname = 'the_obj'
        self._host = host
        self._port = port

        self._client = Client(host, port)
        self._client.start(typname, self._objname)
        super(ComponentProxy, self).__init__()
        self._populate(self, self._objname)

    def _populate(self, container, path):
        """
        Populate a container from a remote object.

        container: Container
            The local container object to be populated.

        path: string
            Path on server corresponding to `container`.
        """
# TODO: local/remote name collision detection/resolution?
        info = self._client.list_properties(path)
        for prop, typ, iotype in info:
            rpath = '.'.join([path, prop])
            if typ == 'PHXDouble' or typ == 'PHXLong' or typ == 'PHXString':
                enum_valstrs = self._client.get(rpath+'.enumValues')
                if enum_valstrs:
                    container.add_trait(prop,
                                        EnumProxy(iotype, self._client, rpath,
                                                  typ, enum_valstrs))
                    continue

            if typ == 'PHXBoolean':
                container.add_trait(prop,
                                    BoolProxy(iotype, self._client, rpath))
            elif typ == 'PHXDouble':
                container.add_trait(prop,
                                    FloatProxy(iotype, self._client, rpath))
            elif typ == 'PHXLong':
                container.add_trait(prop,
                                    IntProxy(iotype, self._client, rpath))
            elif typ == 'PHXRawFile':
                container.add_trait(prop,
                                    FileProxy(iotype, self._client, rpath,
                                              self))
            elif typ == 'PHXString':
                container.add_trait(prop,
                                    StrProxy(iotype, self._client, rpath))
            elif typ == 'PHXGroup':
                group = container.add(prop, Container())
                self._populate(group, rpath)  # Recurse.

            elif typ.startswith('double['):
                container.add_trait(prop,
                                    ArrayProxy(iotype, self._client, rpath,
                                               float))
            elif typ.startswith('long['):
                container.add_trait(prop,
                                    ArrayProxy(iotype, self._client, rpath,
                                               int))
            elif typ.startswith('java.lang.String['):
                container.add_trait(prop,
                                    ListProxy(iotype, self._client, rpath,
                                              str))
            else:
                raise NotImplementedError('%r type %r' % (prop, typ))

    def __getstate__(self):
        """ Return dict representing this component's local state. """
        state = super(ComponentProxy, self).__getstate__()
        del state['_client']
        return state

    def __setstate__(self, state):
        """ Restore this component's local state. """
        state['_client'] = None
        super(ComponentProxy, self).__setstate__(state)

    def post_load(self):
        """
        Restore client connection and remote state after loading local state.
        """
        super(ComponentProxy, self).post_load()
        self._client = Client(self._host, self._port)
        self._client.start(self._typname, self._objname)
        self._restore(self)

    def _restore(self, container):
        """ Restore remote state (variables don't have a post_load()). """
        # Using _alltraits() here because at this point items()
        # considers the ProxyMixin traits as 'Missing'.
        for name, trait in container._alltraits().items():
            typ = trait.trait_type
            if isinstance(typ, ProxyMixin):
                typ.restore(self._client)

        for name, obj in container.items():
            if is_instance(obj, Container):
                self._restore(obj)  # Recurse.

    def pre_delete(self):
        """ Unload remote instance before we get deleted. """
        super(ComponentProxy, self).pre_delete()
        if self._client is not None:
            self._client.end(self._objname)
            self._client = None

    def __del__(self):
        """ Cleanup client if it hasn't been already. """
        if self._client is not None:
            try:
                self._client.end(self._objname)
            except (EOFError, socket.error):  # pragma no cover
                pass
            self._client = None

    def execute(self):
        """ Execute remote component. """
        self._client.execute(self._objname)
Exemplo n.º 10
0
class DOETestCase(unittest.TestCase):
    """ Test AnalysisServer emulation for a model that uses MPI to run
    a DOE in parallel.
    """

    def setUp(self):
        logging.info("---------------- Starting test %s" % self.id())

        self.testdir = os.path.dirname(os.path.abspath(__file__))
        self.tempdir = tempfile.mkdtemp(prefix='aserver-')
        if not os.path.isdir(self.tempdir):
            os.mkdir(self.tempdir)

        shutil.copy(os.path.join(self.testdir, 'ASTestProb.py'),
                    os.path.join(self.tempdir))
        shutil.copy(os.path.join(self.testdir, 'TestParDOEProblem.cfg'),
                    os.path.join(self.tempdir))

        os.chdir(self.tempdir)

    def tearDown(self):
        try:
            self.client.quit()
            stop_server(self.server)
        finally:
            os.chdir(STARTDIR)
            if not os.environ.get('OPENMDAO_KEEPDIRS'):
                try:
                    shutil.rmtree(self.tempdir)
                except OSError:
                    pass

    def test_execute(self):
        try:
            self.server, self.port = start_server(args=['-c', 'TestParDOEProblem.cfg'])
            self.client = Client(port=self.port)
        except:
            os.chdir(STARTDIR)
            raise

        reply = self.client.start('TestParDOEProblem', 'p')

        # set some input cases [indep_var.a, indep_var.b, indep_var.c]
        ncases = 20
        cases = numpy.arange(3.0*ncases).reshape(ncases, 3)
        self.client.set('p.driver.desvar_array', array2str(cases))
        self.client.execute('p')
        results = str2array(self.client.get('p.driver.response_array'))

        for i in range(results.shape[0]):
            for j in range(i, results.shape[0]):
                if i!=j and results[i][0] == results[j][0]:
                    logging.info("*** indices %d and %d match" % (i,j))

        # test to make sure that the set/get array -> str -> array conversion
        # works.
        numpy.testing.assert_array_almost_equal(cases,
                           str2array(self.client.get('p.driver.desvar_array')),
                           decimal=9)

        # we registered our case inputs as responses (first 3 cols of results)
        # so make sure their values haven't changed, and are in the same
        # order as we sent them.
        numpy.testing.assert_array_almost_equal(cases, results[:,:3],
                                                decimal=9)

        mult = numpy.array([2.0, 3.0, 1.5])
        for i in range(cases.shape[0]):
            numpy.testing.assert_array_almost_equal(results[i,3:],
                                                    cases[i]*mult, decimal=9)
Exemplo n.º 11
0
class TestCase(unittest.TestCase):
    """ Test AnalysisServer emulation. """

    def setUp(self):
        logging.info("---------------- Starting test %s" % self.id())

        self.testdir = os.path.dirname(os.path.abspath(__file__))
        self.tempdir = tempfile.mkdtemp(prefix=self.id().split('.')[-1]+'_')

        os.makedirs(os.path.join(self.tempdir, 'd1'))
        os.makedirs(os.path.join(self.tempdir, 'd2/d3'))

        shutil.copy(os.path.join(self.testdir, 'ASTestComp.py'),
                    os.path.join(self.tempdir, 'd2', 'd3'))
        shutil.copy(os.path.join(self.testdir, 'TestCompProblem.cfg'),
                    os.path.join(self.tempdir, 'd2', 'd3'))

        os.chdir(self.tempdir)

        try:
            self.server, self.port = start_server(args=['-c', self.tempdir])
            self.client = Client(port=self.port)
        except:
            os.chdir(STARTDIR)
            raise

    def tearDown(self):
        try:
            self.client.quit()
            stop_server(self.server)
        finally:
            os.chdir(STARTDIR)
            if not KEEPDIRS:
                try:
                    shutil.rmtree(self.tempdir)
                except OSError:
                    pass

    def compare(self, reply, expected):
        reply_lines = reply.split('\n')
        expected_lines = expected.split('\n')
        for i, reply_line in enumerate(reply_lines):
            if i >= len(expected_lines):
                self.fail('%d reply lines, %d expected lines'
                      % (len(reply_lines), len(expected_lines)))
            expected_line = expected_lines[i]
            if reply_line.startswith('classURL'): # installation-specific
                if not expected_line.startswith('classURL'):
                    self.fail('Line %d: %r vs. %r'
                               % (i+1, reply_line, expected_line))
            else:
                if reply_line != expected_line:
                    self.fail('Line %d: %r vs. %r'
                               % (i+1, reply_line, expected_line))
        if len(reply_lines) != len(expected_lines):
            self.fail('%d reply lines, %d expected lines'
                      % (len(reply_lines), len(expected_lines)))

    def test_describe(self):
        expected = {
            'Version': '0.2',
            'Author': 'anonymous  ( & < > )',
            'hasIcon': 'false',
            'Description': 'Component for testing AnalysisServer functionality.\nAn additional description line.  ( & < > )',
            'Help URL': '',
            'Keywords': '',
            'Driver': 'false',
            'Time Stamp': '',
            'Requirements': '',
            'HasVersionInfo': 'false',
            'Checksum': '0',
        }
        files = glob.glob('d2/d3/TestCompProblem.cfg')
        if len(files) < 1:
            self.fail("Couldn't find TestCompProblem.cfg file.")

        expected['Time Stamp'] = \
            time.ctime(os.path.getmtime(files[0]))

        result = self.client.describe('d2/d3/TestCompProblem')

        for key, val in expected.items():
            try:
                self.assertEqual("%s: %s" % (key,val), "%s: %s" % (key,result[key]))
            except KeyError:
                self.fail("Key '%s' not found in results." % key)

    def test_end(self):
        self.client.start('d2/d3/TestCompProblem', 'comp')
        reply = self.client.end('comp')
        self.assertEqual(reply, 'comp completed.\nObject comp ended.')

        try:
            self.client.end('froboz')
        except Exception as err:
            self.assertEqual(str(err),
                         'no such object: <froboz>')
        else:
            self.fail("Exception expected")

        try:
            self.client._send_recv('end')
        except Exception as err:
            self.assertEqual(str(err),
                             'invalid syntax. Proper syntax:\n'
                             'end <object>')
        else:
            self.fail("Exception expected")

    def test_execute(self):
        self.client.start('d2/d3/TestCompProblem', 'comp')
        self.client.set('comp.in_file', 'Hello world!')
        self.client.execute('comp')
        self.client.execute('comp', background=True)

    def test_get(self):
        self.client.start('d2/d3/TestCompProblem', 'comp')
        result = self.client.get('comp.x')
        self.assertEqual(result, '2')

    def test_get_branches(self):
        result = self.client.get_branches_and_tags()
        self.assertEqual(result, '')

    def test_get_direct(self):
        result = self.client.get_direct_transfer()
        self.assertFalse(result)

    def test_get_hierarchy(self):
        self.client.start('d2/d3/TestCompProblem', 'comp')
        result = self.client.get_hierarchy('comp')
        # TODO: do some check of the xml vs expected...
        #print(result)

    def test_get_icon(self):
        try:
            self.client.get_icon('d2/d3/TestCompProblem')
        except Exception as err:
            self.assertTrue('NotImplementedError' in str(err))
            self.assertTrue('getIcon' in str(err))
        else:
            self.fail("Exception expected")

    def test_get_license(self):
        result = self.client.get_license()
        self.assertEqual(result, 'Use at your own risk!')

    def test_get_status(self):
        expected = {'comp': 'ready'}
        self.client.start('d2/d3/TestCompProblem', 'comp')
        result = self.client.get_status()
        self.assertEqual(result, expected)

    def test_get_sys_info(self):
        expected = {
            'version': '7.0',
            'build': '42968',
            'num clients': '1',
            'num components': '1',
            'os name': platform.system(),
            'os arch': platform.processor(),
            'os version': platform.release(),
            'python version': platform.python_version(),
            'user name': getpass.getuser(),
        }
        result = self.client.get_sys_info()
        self.assertEqual(result, expected)

    def test_get_version(self):
        expected = """\
OpenMDAO Analysis Server 0.1
Use at your own risk!
Attempting to support Phoenix Integration, Inc.
version: 7.0, build: 42968"""
        result = self.client.get_version()
        self.assertEqual(result, expected)

    def test_heartbeat(self):
        self.client.heartbeat(True)
        self.client.heartbeat(False)

    def test_help(self):
        expected = [
            'Available Commands:',
            'listComponents,lc [category]',
            'listCategories,la [category]',
            'describe,d <category/component> [-xml]',
            'setServerAuthInfo <serverURL> <username> <password> (NOT IMPLEMENTED)',
            'start <category/component> <instanceName> [connector] [queue]',
            'end <object>',
            'execute,x <objectName>',
            'listProperties,list,ls,l [object]',
            'listGlobals,lg',
            'listValues,lv <object>',
            'listArrayValues,lav <object> (NOT IMPLEMENTED)',
            'get <object.property>',
            'set <object.property> = <value>',
            'move,rename,mv,rn <from> <to> (NOT IMPLEMENTED)',
            'getIcon <analysisComponent> (NOT IMPLEMENTED)',
            'getIcon2 <analysisComponent> (NOT IMPLEMENTED)',
            'getVersion',
            'getLicense',
            'getStatus',
            'help,h',
            'quit',
            'getSysInfo',
            'invoke <object.method()> [full]',
            'listMethods,lm <object> [full]',
            'addProxyClients <clientHost1>,<clientHost2>',
            'monitor start <object.property>, monitor stop <id>',
            'versions,v category/component',
            'ps <object>',
            'listMonitors,lo <objectName>',
            'heartbeat,hb [start|stop]',
            'listValuesURL,lvu <object>',
            'getDirectTransfer',
            'getByUrl <object.property> <url> (NOT IMPLEMENTED)',
            'setByUrl <object.property> = <url> (NOT IMPLEMENTED)',
            'setDictionary <xml dictionary string> (xml accepted, but not used)',
            'getHierarchy <object.property>',
            #'setHierarchy <object.property> <xml>',
            'deleteRunShare <key> (NOT IMPLEMENTED)',
            'getBranchesAndTags (NOT IMPLEMENTED)',
            'getQueues <category/component> [full] (NOT IMPLEMENTED)',
            'setRunQueue <object> <connector> <queue> (NOT IMPLEMENTED)',
        ]
        result = self.client.help()
        self.assertEqual(result, expected)

    def test_invoke(self):
        self.client.start('d2/d3/TestCompProblem', 'prob')
        result = self.client.invoke('prob.comp.reinitialize')
        self.assertEqual(result, '')
        result = self.client.invoke('prob.comp.float_method')
        self.assertEqual(result, '5')
        result = self.client.invoke('prob.comp.null_method')
        self.assertEqual(result, '')
        result = self.client.invoke('prob.comp.str_method')
        self.assertEqual(result,
                         'current state: x 2.0, y 3.0, z 0.0, exe_count 0')

    def test_list_array_values(self):
        self.client.start('d2/d3/TestCompProblem', 'comp')
        try:
            self.client.list_array_values('comp')
        except Exception as err:
            self.assertTrue('NotImplementedError' in str(err))
            self.assertTrue('listArrayValues' in str(err))

    def test_list_categories(self):
        result = self.client.list_categories('/')
        self.assertEqual(result, ['d2'])
        result = self.client.list_categories('/d2')
        self.assertEqual(result, ['d3'])

    def test_list_components(self):
        result = self.client.list_components()

        self.assertEqual(sorted(result),
                         ['d2/d3/TestCompProblem'])

    def test_list_globals(self):
        result = self.client.list_globals()
        self.assertEqual(result, [])

    def test_list_methods(self):
        self.client.start('d2/d3/TestCompProblem', 'comp')
        result = self.client.list_methods('comp')
        #logging.info("RESULT: %s" % result)
        self.assertTrue("comp.float_method" in result, "can't find float_method in 'comp'")
        self.assertTrue("comp.str_method" in result, "can't find str_method in 'comp'")
        self.assertTrue("comp.int_method" in result, "can't find int_method in 'comp'")

        result = self.client.list_methods('comp', full=True)
        #logging.info("RESULT: %s" % result)
        self.assertTrue(("comp.float_method", "TestCompProblem/comp.float_method") in result, "can't find float_method in 'comp'")
        self.assertTrue(("comp.str_method", "TestCompProblem/comp.str_method") in result, "can't find str_method in 'comp'")
        self.assertTrue(("comp.int_method", "TestCompProblem/comp.int_method") in result, "can't find int_method in 'comp'")

    def test_list_monitors(self):
        self.client.start('d2/d3/TestCompProblem', 'comp')
        result = sorted(self.client.list_monitors('comp'))
        self.assertEqual('hosts.allow', result[1])
        self.assertTrue(fnmatch.fnmatch(result[0], 'as-*.out'))

    def test_list_properties(self):
        self.client.start('d2/d3/TestCompProblem', 'comp')
        result = self.client.list_properties()
        self.assertEqual(result, ['comp'])

        expected = [
             ('exe_count', 'PHXLong', 'out'),
             ('exe_dir', 'PHXString', 'out'),
             ('in_file', 'PHXRawFile', 'in'),
             ('obj_input.sobobj.sob', 'PHXBoolean', 'in'),
             ('obj_input.sobobj.sof', 'PHXDouble', 'in'),
             ('obj_input.sobobj.soi', 'PHXLong', 'in'),
             ('obj_input.sobobj.sos', 'PHXString', 'in'),
             ('obj_input.tob', 'PHXBoolean', 'in'),
             ('obj_input.tof', 'PHXDouble', 'in'),
             ('obj_input.tof1d', 'double[9]', 'in'),
             ('obj_input.tof2d', 'double[2][4]', 'in'),
             ('obj_input.tof3d', 'double[2][3][3]', 'in'),
             ('obj_input.tofe', 'PHXDouble', 'in'),
             ('obj_input.toflst', 'double[0]', 'in'),
             ('obj_input.toi', 'PHXLong', 'in'),
             ('obj_input.toi1d', 'long[9]', 'in'),
             ('obj_input.toie', 'PHXLong', 'in'),
             ('obj_input.toilst', 'long[0]', 'in'),
             ('obj_input.tos', 'PHXString', 'in'),
             ('obj_input.tos1d', 'java.lang.String[3]', 'in'),
             ('obj_input.tose', 'PHXString', 'in'),
             ('obj_output.sobobj.sob', 'PHXBoolean', 'out'),
             ('obj_output.sobobj.sof', 'PHXDouble', 'out'),
             ('obj_output.sobobj.soi', 'PHXLong', 'out'),
             ('obj_output.sobobj.sos', 'PHXString', 'out'),
             ('obj_output.tob', 'PHXBoolean', 'out'),
             ('obj_output.tof', 'PHXDouble', 'out'),
             ('obj_output.tof1d', 'double[9]', 'out'),
             ('obj_output.tof2d', 'double[2][4]', 'out'),
             ('obj_output.tof3d', 'double[2][3][3]', 'out'),
             ('obj_output.tofe', 'PHXDouble', 'out'),
             ('obj_output.toflst', 'double[0]', 'out'),
             ('obj_output.toi', 'PHXLong', 'out'),
             ('obj_output.toi1d', 'long[9]', 'out'),
             ('obj_output.toie', 'PHXLong', 'out'),
             ('obj_output.toilst', 'long[0]', 'out'),
             ('obj_output.tos', 'PHXString', 'out'),
             ('obj_output.tos1d', 'java.lang.String[3]', 'out'),
             ('obj_output.tose', 'PHXString', 'out'),
             ('out_file', 'PHXRawFile', 'out'),
             ('sub_group.b', 'PHXBoolean', 'in'),
             ('sub_group.f', 'PHXDouble', 'in'),
             ('sub_group.f1d', 'double[9]', 'in'),
             ('sub_group.f2d', 'double[2][4]', 'in'),
             ('sub_group.f3d', 'double[2][3][3]', 'in'),
             ('sub_group.fe', 'PHXDouble', 'in'),
             ('sub_group.flst', 'double[0]', 'in'),
             ('sub_group.i', 'PHXLong', 'in'),
             ('sub_group.i1d', 'long[9]', 'in'),
             ('sub_group.ie', 'PHXLong', 'in'),
             ('sub_group.ilst', 'long[0]', 'in'),
             ('sub_group.s', 'PHXString', 'in'),
             ('sub_group.s1d', 'java.lang.String[3]', 'in'),
             ('sub_group.se', 'PHXString', 'in'),
             ('x', 'PHXDouble', 'in'),
             ('y', 'PHXDouble', 'in'),
             ('z', 'PHXDouble', 'out')
        ]
        result = self.client.list_properties('comp')
        self.assertEqual(result, expected)

    def test_monitor(self):
        self.client.start('d2/d3/TestCompProblem', 'comp')
        result, monitor_id = self.client.start_monitor('comp.d2/d3/TestCompProblem.cfg')
        expected = """\
[AnalysisServer]
version: 0.2
filename: ASTestComp.py
comment: Initial version.
author: anonymous  ( & < > )
description: Component for testing AnalysisServer functionality.
    An additional description line.  ( & < > )
in_vars: in_* x y obj_input:* sub_group:*
out_vars: out_* z exe_* obj_output:*
methods: comp.reinitialize
   comp.float_method
   comp.null_method
   comp.str_method
   comp.int_method
"""
        self.assertEqual(result[:len(expected)], expected)

        self.client.stop_monitor(monitor_id)

    def test_set_hierarchy(self):
        # Grab value of obj_input (big XML string).
        reply = self.client.start('d2/d3/TestCompProblem', 'comp')
        # reply = self.client.get('comp.obj_input')
        # obj_input = reply[:-3]
#<Variable name="obj_input">%s</Variable>

        xml = """\
<?xml version="1.0" encoding="utf-8" standalone="no"?><html>
<root xml:space="preserve" autoDFT="true">
<Variable name="in_file">test setHierarchy</Variable>
<Variable name="sub_group.b">false</Variable>
<Variable name="sub_group.f">-0.5</Variable>
<Variable name="sub_group.f1d">5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 5.9</Variable>
<Variable name="sub_group.f2d">bounds[2, 4] {.1, .2, .3, .4, .5, .6, .7, .8}</Variable>
<Variable name="sub_group.f3d">bounds[2, 3, 3] {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9</Variable>
<Variable name="sub_group.fe">3.14159</Variable>
<Variable name="sub_group.i">-7</Variable>
<Variable name="sub_group.i1d">-1, -2, -3, -4, -5, -6, -7, -8, -9</Variable>
<Variable name="sub_group.ie">9</Variable>
<Variable name="sub_group.s">Cruel world :-(</Variable>
<Variable name="sub_group.se">hot</Variable>
<Variable name="x">6</Variable>
<Variable name="y">7</Variable></root>""" # % escape(obj_input)

        self.client.set_mode_raw()
        reply = self.client.set_hierarchy('comp', xml)
        expected = 'values set'
        self.assertEqual(reply, '2\r\nformat: string\r\n%d\r\n%s'
                                      % (len(expected), expected))

    def test_move(self):
        try:
            self.client.move('from', 'to')
        except Exception as err:
            self.assertTrue('NotImplementedError' in str(err))
            self.assertTrue('move' in str(err))

        else:
            self.fail("Exception expected")

    def test_ps(self):
        expected = [{
            'PID': 0,
            'ParentPID': 0,
            'PercentCPU': 0.,
            'Memory': 0,
            'Time': 0.,
            'WallTime': 0.,
            'Command': os.path.basename(sys.executable),
        }]
        self.client.start('d2/d3/TestCompProblem', 'comp')
        process_info = self.client.ps('comp')
        self.assertEqual(process_info, expected)

    def test_set(self):
        self.client.start('d2/d3/TestCompProblem', 'comp')
        self.client.set('comp.x', '42')
        self.assertEqual(self.client.get('comp.x'), '42')

    def test_set_mode(self):
        self.client.set_mode_raw()
        result = self.client.list_components()
        self.assertEqual(result, ['d2/d3/TestCompProblem'])

        self.assertTrue(self.client._stream.raw)

        try:
            self.client._stream.raw = False
        except Exception as err:
            self.assertEqual("Can only transition from 'cooked' to 'raw'",
                             str(err))
        else:
            self.fail("Exception expected")

    def test_start(self):
        reply = self.client.start('d2/d3/TestCompProblem', 'comp')
        self.assertEqual("Object comp started.", reply)

    def test_versions(self):

        reply = self.client.versions('d2/d3/TestCompProblem')
        self.assertEqual(reply, ['0.2'])

        try:
            reply = self.client._send_recv('versions')
        except Exception as err:
            self.assertEqual(str(err),
                            'invalid syntax. Proper syntax:\n'
                            'versions,v category/component')
        else:
            self.fail("Exception expected")

        try:
            reply = self.client._send_recv('versions NoSuchComp')
        except Exception as err:
            self.assertEqual(str(err),
                  "component </NoSuchComp> does not match a known component")
        else:
            self.fail("Exception expected")