Пример #1
0
    def doPreinit(self, mode):
        if mode != SIMULATION:
            host, port = self.host.split(':')
            self._client = ControlClient(host, port)
            remote_objects = self._client.get_object_collection()

            if self.remoteobj not in remote_objects.keys():
                raise ConfigurationError('No such object on {}: {}'.format(
                    self.host, self.remoteobj))

            self._obj = remote_objects[self.remoteobj]
    def test_json_rpc(self, mock_socket, mock_uuid):
        mock_uuid.return_value = '2'

        connection = ControlClient(host='127.0.0.1', port='10001')
        connection.json_rpc('foo')

        mock_socket.assert_has_calls(
            [call(),
             call().connect('tcp://127.0.0.1:10001'),
             call().send_json({'method': 'foo', 'params': (), 'jsonrpc': '2.0', 'id': '2'}),
             call().recv_json()])
    def test_get_remote_object_works(self, mock_socket):
        client = ControlClient(host='127.0.0.1', port='10001')

        with patch.object(client, 'json_rpc') as json_rpc_mock:
            json_rpc_mock.return_value = ({'id': 2,
                                           'result': {'class': 'Test',
                                                      'methods': ['a:set', 'a:get', 'setTest']}},
                                          2)

            obj = client.get_object()

            self.assertTrue(hasattr(type(obj), 'a'))
            self.assertTrue(hasattr(obj, 'setTest'))

            json_rpc_mock.assert_has_calls([call(':api')])
Пример #4
0
class LewisControlClientDevice(DeviceMixinBase):
    parameters = {
        'host':
        Param('HOST:PORT string for JSON-RPC connection.',
              type=host,
              settable=False,
              mandatory=True),
        'remoteobj':
        Param('Name of remote object to mirror.',
              type=str,
              settable=False,
              mandatory=True,
              userparam=False)
    }

    _client = None
    _obj = None

    def doPreinit(self, mode):
        if mode != SIMULATION:
            host, port = self.host.split(':')
            self._client = ControlClient(host, port)
            remote_objects = self._client.get_object_collection()

            if self.remoteobj not in remote_objects.keys():
                raise ConfigurationError('No such object on {}: {}'.format(
                    self.host, self.remoteobj))

            self._obj = remote_objects[self.remoteobj]
Пример #5
0
    def test_zmq_socket_uses_timeout(self, mock_zmq_context):
        timeout = 100
        ControlClient(host="127.0.0.1", port="10002", timeout=timeout)

        mock_zmq_context.assert_has_calls([
            call().setsockopt(zmq.SNDTIMEO, timeout),
            call().setsockopt(zmq.RCVTIMEO, timeout),
        ])
    def testjson_rpc(self, mock_socket, mock_uuid):
        mock_uuid.return_value = '2'

        connection = ControlClient(host='127.0.0.1', port='10001')
        connection.json_rpc('foo')

        mock_socket.assert_has_calls([
            call(),
            call().connect('tcp://127.0.0.1:10001'),
            call().send_json({
                'method': 'foo',
                'params': (),
                'jsonrpc': '2.0',
                'id': '2'
            }),
            call().recv_json()
        ])
Пример #7
0
    def test_json_rpc(self, mock_socket, mock_uuid):
        mock_uuid.return_value = "2"

        connection = ControlClient(host="127.0.0.1", port="10001")
        connection.json_rpc("foo")

        mock_socket.assert_has_calls([
            call(),
            call().connect("tcp://127.0.0.1:10001"),
            call().send_json({
                "method": "foo",
                "params": (),
                "jsonrpc": "2.0",
                "id": "2"
            }),
            call().recv_json(),
        ])
Пример #8
0
    def test_get_remote_object_raises_exception(self, mock_socket):
        client = ControlClient(host="127.0.0.1", port="10001")

        with patch.object(client, "json_rpc") as json_rpc_mock:
            json_rpc_mock.return_value = ({"id": 2}, 2)

            self.assertRaises(ProtocolException, client.get_object)

            json_rpc_mock.assert_has_calls([call(":api")])
    def test_get_remote_object_raises_exception(self, mock_socket):
        client = ControlClient(host='127.0.0.1', port='10001')

        with patch.object(client, 'json_rpc') as json_rpc_mock:
            json_rpc_mock.return_value = ({'id': 2}, 2)

            self.assertRaises(ProtocolException, client.get_object)

            json_rpc_mock.assert_has_calls([call(':api')])
    def test_get_remote_object_works(self, mock_socket):
        client = ControlClient(host='127.0.0.1', port='10001')

        with patch.object(client, 'json_rpc') as json_rpc_mock:
            json_rpc_mock.return_value = ({
                'id': 2,
                'result': {
                    'class': 'Test',
                    'methods': ['a:set', 'a:get', 'setTest']
                }
            }, 2)

            obj = client.get_object()

            self.assertTrue(hasattr(type(obj), 'a'))
            self.assertTrue(hasattr(obj, 'setTest'))

            json_rpc_mock.assert_has_calls([call(':api')])
    def test_get_remote_object_collection(self, mock_socket):
        client = ControlClient(host='127.0.0.1', port='10001')

        returned_object = Mock()
        returned_object.get_objects = Mock(return_value=['obj1', 'obj2'])

        with patch.object(client, 'get_object') as get_object_mock:
            get_object_mock.side_effect = [returned_object, 'obj1_object', 'obj2_object']

            objects = client.get_object_collection()

            self.assertTrue('obj1' in objects)
            self.assertTrue('obj2' in objects)

            returned_object.get_objects.assert_has_calls([call()])
            get_object_mock.assert_has_calls(
                [call(''),
                 call('obj1'),
                 call('obj2')])
    def test_get_remote_object_collection(self, mock_socket):
        client = ControlClient(host='127.0.0.1', port='10001')

        returned_object = Mock()
        returned_object.get_objects = Mock(return_value=['obj1', 'obj2'])

        with patch.object(client, 'get_object') as get_object_mock:
            get_object_mock.side_effect = [
                returned_object, 'obj1_object', 'obj2_object'
            ]

            objects = client.get_object_collection()

            self.assertTrue('obj1' in objects)
            self.assertTrue('obj2' in objects)

            returned_object.get_objects.assert_has_calls([call()])
            get_object_mock.assert_has_calls(
                [call(''), call('obj1'), call('obj2')])
Пример #13
0
    def test_get_remote_object_collection(self, mock_socket):
        client = ControlClient(host="127.0.0.1", port="10001")

        returned_object = Mock()
        returned_object.get_objects = Mock(return_value=["obj1", "obj2"])

        with patch.object(client, "get_object") as get_object_mock:
            get_object_mock.side_effect = [
                returned_object,
                "obj1_object",
                "obj2_object",
            ]

            objects = client.get_object_collection()

            self.assertTrue("obj1" in objects)
            self.assertTrue("obj2" in objects)

            returned_object.get_objects.assert_has_calls([call()])
            get_object_mock.assert_has_calls(
                [call(""), call("obj1"), call("obj2")])
Пример #14
0
    def test_get_remote_object_works(self, mock_socket):
        client = ControlClient(host="127.0.0.1", port="10001")

        with patch.object(client, "json_rpc") as json_rpc_mock:
            json_rpc_mock.return_value = (
                {
                    "id": 2,
                    "result": {
                        "class": "Test",
                        "methods": ["a:set", "a:get", "setTest"],
                    },
                },
                2,
            )

            obj = client.get_object()

            self.assertTrue(hasattr(type(obj), "a"))
            self.assertTrue(hasattr(obj, "setTest"))

            json_rpc_mock.assert_has_calls([call(":api")])
    def _open(self):
        """
        Start the lewis emulator.

        :param port: the port on which to run lewis
        :return:
        """

        self._control_port = str(get_free_ports(1)[0])
        lewis_command_line = [
            self._python_path, "-m", "lewis", "-r",
            "127.0.0.1:{control_port}".format(control_port=self._control_port)
        ]
        lewis_command_line.extend([
            "-p",
            "{protocol}: {{bind_address: 127.0.0.1, port: {port}}}".format(
                protocol=self._lewis_protocol, port=self._port)
        ])
        if self._lewis_additional_path is not None:
            lewis_command_line.extend(["-a", self._lewis_additional_path])
        if self._lewis_package is not None:
            lewis_command_line.extend(["-k", self._lewis_package])

        # Set lewis speed
        lewis_command_line.extend(["-e", str(self._speed), self._device])

        print("Starting Lewis")
        self._logFile = open(self._log_filename(), "w")
        self._logFile.write("Started Lewis with '{0}'\n".format(
            " ".join(lewis_command_line)))

        self._process = subprocess.Popen(
            lewis_command_line,
            creationflags=subprocess.CREATE_NEW_CONSOLE,
            stdout=self._logFile,
            stderr=subprocess.STDOUT)
        self._connected = True

        self.remote = ControlClient("127.0.0.1", self._control_port)
Пример #16
0
def control_simulation(argument_list=None):
    args = parser.parse_args(argument_list or sys.argv[1:])

    remote = ControlClient(*args.rpc_host.split(':')).get_object_collection()

    if not args.object:
        list_objects(remote)
    else:
        if not args.member:
            show_api(remote, args.object)
        else:
            response = call_method(remote, args.object, args.member,
                                   args.arguments)

            if response is not None or args.print_none:
                print(response)
Пример #17
0
    def test_json_rpc_timeout_raises(self, mock_socket, mock_uuid):
        def zmq_again(self):
            raise zmq.error.Again()

        raising_send = Mock(side_effect=zmq_again)
        mock_uuid.return_value = '2'

        connection = ControlClient(host='127.0.0.1', port='10001')
        connection._socket.send_json = raising_send
        self.assertRaises(ProtocolException, connection.json_rpc, 'foo')

        raising_send.assert_called_once_with({
            'method': 'foo',
            'params': (),
            'jsonrpc': '2.0',
            'id': '2'
        })
Пример #18
0
    def test_json_rpc_timeout_raises(self, mock_socket, mock_uuid):
        def zmq_again(self):
            raise zmq.error.Again()

        raising_send = Mock(side_effect=zmq_again)
        mock_uuid.return_value = "2"

        connection = ControlClient(host="127.0.0.1", port="10001")
        connection._socket.send_json = raising_send
        self.assertRaises(ProtocolException, connection.json_rpc, "foo")

        raising_send.assert_called_once_with({
            "method": "foo",
            "params": (),
            "jsonrpc": "2.0",
            "id": "2"
        })
Пример #19
0
def control_simulation(argument_list=None):
    args = parser.parse_args(argument_list or sys.argv[1:])

    if args.version:
        print(__version__)
        return

    try:
        remote = ControlClient(*args.rpc_host.split(":"),
                               timeout=args.timeout).get_object_collection()

        if not args.object:
            list_objects(remote)
        else:
            if not args.member:
                show_api(remote, args.object)
            else:
                response = call_method(remote, args.object, args.member,
                                       args.arguments)

                if response is not None or args.print_none:
                    print(response)
    except ProtocolException as e:
        print("\n".join(("An error occurred:", str(e))))
class LewisLauncher(EmulatorLauncher):
    """
    Launches Lewis.
    """

    _DEFAULT_PY_PATH = os.path.join("C:\\", "Instrument", "Apps", "Python3")
    _DEFAULT_LEWIS_PATH = os.path.join(_DEFAULT_PY_PATH, "scripts")

    def __init__(self, test_name, device, var_dir, port, options):
        """
        Constructor that also launches Lewis.

        Args:
            test_name: name of test we are creating device emulator for
            device: device to start
            var_dir: location of directory to write log file and macros directories
            port: the port to use
        """
        super(LewisLauncher, self).__init__(test_name, device, var_dir, port,
                                            options)

        self._lewis_path = options.get("lewis_path",
                                       LewisLauncher._DEFAULT_LEWIS_PATH)
        self._python_path = options.get(
            "python_path",
            os.path.join(LewisLauncher._DEFAULT_PY_PATH, "python.exe"))
        self._lewis_protocol = options.get("lewis_protocol", "stream")
        self._lewis_additional_path = options.get("lewis_additional_path",
                                                  DEVICE_EMULATOR_PATH)
        self._lewis_package = options.get("lewis_package", "lewis_emulators")
        self._default_timeout = options.get("default_timeout", 5)
        self._speed = options.get("speed", 100)

        self._process = None
        self._logFile = None
        self._connected = None

    def _close(self):
        """
        Closes the Lewis session by killing the process.
        """
        print("Terminating Lewis")
        if self._process is not None:
            self._process.terminate()
        if self._logFile is not None:
            self._logFile.close()
            print("Lewis log written to {0}".format(self._log_filename()))

    def _open(self):
        """
        Start the lewis emulator.

        :param port: the port on which to run lewis
        :return:
        """

        self._control_port = str(get_free_ports(1)[0])
        lewis_command_line = [
            self._python_path, "-m", "lewis", "-r",
            "127.0.0.1:{control_port}".format(control_port=self._control_port)
        ]
        lewis_command_line.extend([
            "-p",
            "{protocol}: {{bind_address: 127.0.0.1, port: {port}}}".format(
                protocol=self._lewis_protocol, port=self._port)
        ])
        if self._lewis_additional_path is not None:
            lewis_command_line.extend(["-a", self._lewis_additional_path])
        if self._lewis_package is not None:
            lewis_command_line.extend(["-k", self._lewis_package])

        # Set lewis speed
        lewis_command_line.extend(["-e", str(self._speed), self._device])

        print("Starting Lewis")
        self._logFile = open(self._log_filename(), "w")
        self._logFile.write("Started Lewis with '{0}'\n".format(
            " ".join(lewis_command_line)))

        self._process = subprocess.Popen(
            lewis_command_line,
            creationflags=subprocess.CREATE_NEW_CONSOLE,
            stdout=self._logFile,
            stderr=subprocess.STDOUT)
        self._connected = True

        self.remote = ControlClient("127.0.0.1", self._control_port)

    def _log_filename(self):
        return log_filename(self._test_name, "lewis", self._emulator_id, False,
                            self._var_dir)

    def check(self):
        """
        Check that the lewis emulator is running.

        :return: True if it is running; False otherwise
        """
        if self._process.poll() is None:
            return True
        print("Lewis has terminated! It said:")
        stdoutdata, stderrdata = self._process.communicate()
        sys.stderr.write(stderrdata)
        sys.stdout.write(stdoutdata)
        return False

    def _convert_to_string_for_backdoor(self, value):
        """
        Convert the value given to a string for the backdoor. If the type is a string suround with quotes otherwise
        pass it raw, e.g. for a number.
        Args:
            value: value to convert

        Returns: value as a string for the backdoor

        """
        return "'{}'".format(value) if isinstance(value, str) else str(value)

    def backdoor_set_on_device(self, variable_name, value, *_, **__):
        """
        Set a value in the device using the lewis backdoor.

        :param variable_name: name of variable to set
        :param value: new value it should have
        :return:
        """
        self.backdoor_command([
            "device",
            str(variable_name),
            self._convert_to_string_for_backdoor(value)
        ])

    def backdoor_run_function_on_device(self, function_name, arguments=None):
        """
        Run a function in lewis using the back door on a device.

        :param function_name: name of the function to call
        :param arguments: an iterable of the arguments for the function; None means no arguments. Arguments will
            automatically be turned into json
        :return:
        """
        command = ["device", function_name]
        if arguments is not None:
            command.extend([
                self._convert_to_string_for_backdoor(argument)
                for argument in arguments
            ])

        return self.backdoor_command(command)

    def backdoor_command(self, lewis_command):
        """
        Send a command to the backdoor of lewis.

        :param lewis_command: array of command line arguments to send
        :return: lines from the command output
        """
        try:
            return call_method(self.remote.get_object_collection(),
                               lewis_command[0], lewis_command[1],
                               lewis_command[2:])
        except Exception as e:
            sys.stderr.write(f"Error using backdoor: {e}\n")

    def backdoor_emulator_disconnect_device(self):
        """
        Disconnect the emulated device.

        :return:
        """
        if self._connected:
            self.backdoor_command(["simulation", "disconnect_device"])
        self._connected = False

    def backdoor_emulator_connect_device(self):
        """
        Connect the emulated device.

        :return:
        """
        if not self._connected:
            self.backdoor_command(["simulation", "connect_device"])
        self._connected = True

    def backdoor_get_from_device(self, variable_name, *_, **__):
        """
        Return the string of a value on a device from lewis.
        :param variable_name: name of the variable
        :return: the variables value
        """
        # backdoor_command returns a list of bytes and join takes str so convert them here
        return self.backdoor_command(["device", str(variable_name)])
Пример #21
0
    optional_args.add_argument('-h',
                               '--h',
                               action='help',
                               help='Shows this help message and exits.')

    __doc__ = 'To interact with the control server of a running simulation, use this script. ' \
              'Usage:\n\n.. code-block:: none\n\n{}'.format(get_usage_text(parser, indent=4))

    args = parser.parse_args()

    if args.version:
        print(__version__)
        exit()

    try:
        remote = ControlClient(*args.rpc_host.split(':'),
                               timeout=args.timeout).get_object_collection()

        if not args.object:
            list_objects(remote)
        else:
            if not args.member:
                show_api(remote, args.object)
            else:
                response = call_method(remote, args.object, args.member,
                                       args.arguments)

                if response is not None or args.print_none:
                    print(response)
    except ProtocolException as e:
        print('\n'.join(('An error occurred:', str(e))))