← Back to team overview

sikuli-driver team mailing list archive

[Question #254612]: sikulix remote server with jython start error:[error] ImagePath: addImagePath: not valid: /

 

New question #254612 on Sikuli:
https://answers.launchpad.net/sikuli/+question/254612

i download the latest sikuli 1.1.0 beta4 and setup;
Environment Variables is like this:
JAVA_HOME         C:\Program Files (x86)\Java\jdk1.7.0_05
CLASSPATH           F:\SikuliX\1.1.0\sikulixapi.jar;.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar
JYTHONPATH       C:\jython2.5.3\Lib;C:\jython2.5.3\sikulixapi.jar\Lib

while i Integration sikulix with robotframework (Remote Library), when start Remote Server,I got this error message:

[error] ImagePath: addImagePath: not valid:   /
[error] ImagePath: addImagePath: not valid:   /
Robot Framework remote server at 127.0.0.1:8270 starting.

but,the robotframework can still connect the server and call  this keyword(click_object) remotely sucessfully;
i don't know,why i got this error message?

i start remote server by this command: jython sikuliServer.py

sikuliServer.py source is like this:

import sys
from robotremoteserver import RobotRemoteServer
from org.sikuli.script import *
class SikuliRemoteLibrary:
	def __init__(self):
		self.SS = Screen()
		self.PT = Pattern()
		
	def _wait(self,imgFile,timeOut,similarity):
		self.PT = Pattern(imgFile)
		self.PT = self.PT.similar(float(similarity))
		self.SS.wait(self.PT,float(timeOut))
		
	def click_object(self, imgFile, timeOut, similarity):
		try:
			self._wait(imgFile, timeOut, similarity)
			self.SS.click(imgFile)
		except FindFailed, err:
			raise AssertionError("Cannot click [" + imgFile + "]")
			
if __name__ == '__main__':
	SRL = SikuliRemoteLibrary()
	RobotRemoteServer(SRL, *sys.argv[1:])



and robotremoteserver.py called by above script is like this:


#  Copyright 2008-2014 Nokia Solutions and Networks
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

__version__ = 'devel'

import errno
import re
import select
import sys
import inspect
import traceback
from StringIO import StringIO
from SimpleXMLRPCServer import SimpleXMLRPCServer
from xmlrpclib import Binary
try:
    import signal
except ImportError:
    signal = None
try:
    from collections import Mapping
except ImportError:
    Mapping = dict


BINARY = re.compile('[\x00-\x08\x0B\x0C\x0E-\x1F]')
NON_ASCII = re.compile('[\x80-\xff]')


class RobotRemoteServer(SimpleXMLRPCServer):
    allow_reuse_address = True
    _generic_exceptions = (AssertionError, RuntimeError, Exception)
    _fatal_exceptions = (SystemExit, KeyboardInterrupt)

    def __init__(self, library, host='127.0.0.1', port=8270, port_file=None,
                 allow_stop=True):
        """Configure and start-up remote server.

        :param library:     Test library instance or module to host.
        :param host:        Address to listen. Use ``'0.0.0.0'`` to listen
                            to all available interfaces.
        :param port:        Port to listen. Use ``0`` to select a free port
                            automatically. Can be given as an integer or as
                            a string.
        :param port_file:   File to write port that is used. ``None`` means
                            no such file is written.
        :param allow_stop:  Allow/disallow stopping the server using
                            ``Stop Remote Server`` keyword.
        """
        SimpleXMLRPCServer.__init__(self, (host, int(port)), logRequests=False)
        self._library = library
        self._allow_stop = allow_stop
        self._shutdown = False
        self._register_functions()
        self._register_signal_handlers()
        self._announce_start(port_file)
        self.serve_forever()

    def _register_functions(self):
        self.register_function(self.get_keyword_names)
        self.register_function(self.run_keyword)
        self.register_function(self.get_keyword_arguments)
        self.register_function(self.get_keyword_documentation)
        self.register_function(self.stop_remote_server)

    def _register_signal_handlers(self):
        def stop_with_signal(signum, frame):
            self._allow_stop = True
            self.stop_remote_server()
        for name in 'SIGINT', 'SIGTERM', 'SIGHUP':
            if hasattr(signal, name):
                signal.signal(getattr(signal, name), stop_with_signal)

    def _announce_start(self, port_file=None):
        host, port = self.server_address
        self._log('Robot Framework remote server at %s:%s starting.'
                  % (host, port))
        if port_file:
            pf = open(port_file, 'w')
            try:
                pf.write(str(port))
            finally:
                pf.close()

    def serve_forever(self):
        if hasattr(self, 'timeout'):
            self.timeout = 0.5
        elif sys.platform.startswith('java'):
            self.socket.settimeout(0.5)
        while not self._shutdown:
            try:
                self.handle_request()
            except (OSError, select.error), err:
                if err.args[0] != errno.EINTR:
                    raise

    def stop_remote_server(self):
        prefix = 'Robot Framework remote server at %s:%s ' % self.server_address
        if self._allow_stop:
            self._log(prefix + 'stopping.')
            self._shutdown = True
        else:
            self._log(prefix + 'does not allow stopping.', 'WARN')
        return self._shutdown

    def get_keyword_names(self):
        get_kw_names = getattr(self._library, 'get_keyword_names', None) or \
                       getattr(self._library, 'getKeywordNames', None)
        if self._is_function_or_method(get_kw_names):
            names = get_kw_names()
        else:
            names = [attr for attr in dir(self._library) if attr[0] != '_' and
                     self._is_function_or_method(getattr(self._library, attr))]
        return names + ['stop_remote_server']

    def _is_function_or_method(self, item):
        # Cannot use inspect.isroutine because it returns True for
        # object().__init__ with Jython and IronPython
        return inspect.isfunction(item) or inspect.ismethod(item)

    def run_keyword(self, name, args, kwargs=None):
        args, kwargs = self._handle_binary_args(args, kwargs or {})
        result = {'status': 'FAIL'}
        self._intercept_std_streams()
        try:
            return_value = self._get_keyword(name)(*args, **kwargs)
        except:
            exc_type, exc_value, exc_tb = sys.exc_info()
            self._add_to_result(result, 'error',
                                self._get_error_message(exc_type, exc_value))
            self._add_to_result(result, 'traceback',
                                self._get_error_traceback(exc_tb))
            self._add_to_result(result, 'continuable',
                                self._get_error_attribute(exc_value, 'CONTINUE'),
                                default=False)
            self._add_to_result(result, 'fatal',
                                self._get_error_attribute(exc_value, 'EXIT'),
                                default=False)
        else:
            try:
                self._add_to_result(result, 'return',
                                    self._handle_return_value(return_value))
            except:
                exc_type, exc_value, _ = sys.exc_info()
                self._add_to_result(result, 'error',
                                    self._get_error_message(exc_type, exc_value))
            else:
                result['status'] = 'PASS'
        self._add_to_result(result, 'output', self._restore_std_streams())
        return result

    def _handle_binary_args(self, args, kwargs):
        args = [self._handle_binary_arg(a) for a in args]
        kwargs = dict([(k, self._handle_binary_arg(v)) for k, v in kwargs.items()])
        return args, kwargs

    def _handle_binary_arg(self, arg):
        if isinstance(arg, Binary):
            return arg.data
        return arg

    def _add_to_result(self, result, key, value, default=''):
        if value != default:
            result[key] = value

    def get_keyword_arguments(self, name):
        kw = self._get_keyword(name)
        if not kw:
            return []
        return self._arguments_from_kw(kw)

    def _arguments_from_kw(self, kw):
        args, varargs, kwargs, defaults = inspect.getargspec(kw)
        if inspect.ismethod(kw):
            args = args[1:]  # drop 'self'
        if defaults:
            args, names = args[:-len(defaults)], args[-len(defaults):]
            args += ['%s=%s' % (n, d) for n, d in zip(names, defaults)]
        if varargs:
            args.append('*%s' % varargs)
        if kwargs:
            args.append('**%s' % kwargs)
        return args

    def get_keyword_documentation(self, name):
        if name == '__intro__':
            return inspect.getdoc(self._library) or ''
        if name == '__init__' and inspect.ismodule(self._library):
            return ''
        return inspect.getdoc(self._get_keyword(name)) or ''

    def _get_keyword(self, name):
        if name == 'stop_remote_server':
            return self.stop_remote_server
        kw = getattr(self._library, name, None)
        if not self._is_function_or_method(kw):
            return None
        return kw

    def _get_error_message(self, exc_type, exc_value):
        if exc_type in self._fatal_exceptions:
            self._restore_std_streams()
            raise
        name = exc_type.__name__
        message = self._get_message_from_exception(exc_value)
        if not message:
            return name
        if exc_type in self._generic_exceptions \
                or getattr(exc_value, 'ROBOT_SUPPRESS_NAME', False):
            return message
        return '%s: %s' % (name, message)

    def _get_message_from_exception(self, value):
        # UnicodeError occurs below 2.6 and if message contains non-ASCII bytes
        try:
            msg = unicode(value)
        except UnicodeError:
            msg = ' '.join([self._str(a, handle_binary=False) for a in value.args])
        return self._handle_binary_result(msg)

    def _get_error_traceback(self, exc_tb):
        # Latest entry originates from this class so it can be removed
        entries = traceback.extract_tb(exc_tb)[1:]
        trace = ''.join(traceback.format_list(entries))
        return 'Traceback (most recent call last):\n' + trace

    def _get_error_attribute(self, exc_value, name):
        return bool(getattr(exc_value, 'ROBOT_%s_ON_FAILURE' % name, False))

    def _handle_return_value(self, ret):
        if isinstance(ret, basestring):
            return self._handle_binary_result(ret)
        if isinstance(ret, (int, long, float)):
            return ret
        if isinstance(ret, Mapping):
            return dict([(self._str(key), self._handle_return_value(value))
                         for key, value in ret.items()])
        try:
            return [self._handle_return_value(item) for item in ret]
        except TypeError:
            return self._str(ret)

    def _handle_binary_result(self, result):
        if not self._contains_binary(result):
            return result
        try:
            result = str(result)
        except UnicodeError:
            raise ValueError("Cannot represent %r as binary." % result)
        return Binary(result)

    def _contains_binary(self, result):
        return (BINARY.search(result) or isinstance(result, str) and
                sys.platform != 'cli' and NON_ASCII.search(result))

    def _str(self, item, handle_binary=True):
        if item is None:
            return ''
        if not isinstance(item, basestring):
            item = unicode(item)
        if handle_binary:
            return self._handle_binary_result(item)
        return item

    def _intercept_std_streams(self):
        sys.stdout = StringIO()
        sys.stderr = StringIO()

    def _restore_std_streams(self):
        stdout = sys.stdout.getvalue()
        stderr = sys.stderr.getvalue()
        close = [sys.stdout, sys.stderr]
        sys.stdout = sys.__stdout__
        sys.stderr = sys.__stderr__
        for stream in close:
            stream.close()
        if stdout and stderr:
            if not stderr.startswith(('*TRACE*', '*DEBUG*', '*INFO*', '*HTML*',
                                      '*WARN*')):
                stderr = '*INFO* %s' % stderr
            if not stdout.endswith('\n'):
                stdout += '\n'
        return self._handle_binary_result(stdout + stderr)

    def _log(self, msg, level=None):
        if level:
            msg = '*%s* %s' % (level.upper(), msg)
        self._write_to_stream(msg, sys.stdout)
        if sys.__stdout__ is not sys.stdout:
            self._write_to_stream(msg, sys.__stdout__)

    def _write_to_stream(self, msg, stream):
        stream.write(msg + '\n')
        stream.flush()


if __name__ == '__main__':
    import xmlrpclib

    def stop(uri):
        server = test(uri, log_success=False)
        if server is not None:
            print 'Stopping remote server at %s.' % uri
            server.stop_remote_server()

    def test(uri, log_success=True):
        server = xmlrpclib.ServerProxy(uri)
        try:
            server.get_keyword_names()
        except:
            print 'No remote server running at %s.' % uri
            return None
        if log_success:
            print 'Remote server running at %s.' % uri
        return server

    def parse_args(args):
        actions = {'stop': stop, 'test': test}
        if not args or len(args) > 2 or args[0] not in actions:
            sys.exit('Usage:  python -m robotremoteserver test|stop [uri]')
        uri = len(args) == 2 and args[1] or 'http://127.0.0.1:8270'
        if '://' not in uri:
            uri = 'http://' + uri
        return actions[args[0]], uri

    action, uri = parse_args(sys.argv[1:])
    action(uri)



how to resolve this error message ? thank you so much

-- 
You received this question notification because you are a member of
Sikuli Drivers, which is an answer contact for Sikuli.