Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"rpc" decorator for virtual devices fails to pack response if resp_format is not specified. #942

Open
dvksirin opened this issue Jan 28, 2020 · 1 comment
Labels
iotile-core Related to iotile-core package type:bug

Comments

@dvksirin
Copy link
Contributor

Here is truncated example from tutorial:

from iotile.core.hw.virtual import SimpleVirtualDevice, rpc

class DemoVirtualDevice(SimpleVirtualDevice):
    def __init__(self, args):
        super(DemoVirtualDevice, self).__init__(1, 'Demo01')
        self.temp = 273

    @rpc(8, 0x8002, "L")
    def set_temperature(self, new_temp):
        """Set the current temperature of the device in degrees kelvin"""

        self.temp = new_temp
        return []

When "resp_format" keyword argument for "rpc" is not specified it returns not changed value returned by decorated method or "[]" if returned value is None. But should return bytes according to its docstring description

....
Similarly, the function being decorated should return an iterable of results that
will be encoded into a 20 byte response buffer by struct.pack using resp_format as
the format string.

It causes an error.
Here is traceback I got when executed the example code from the tutorial

(coretools) dvk@sirin-dvk:~/test/test_component$ iotile hw --port=virtual:./demo_device.py connect 1 controller set_temperature 10
Traceback (most recent call last):
  File "/home/dvk/projects/coretools/iotilecore/iotile/core/scripts/iotile_script.py", line 206, in main
    finished = shell.invoke(line)
  File "/home/dvk/.virtualenvs/coretools/lib/python3.6/site-packages/typedargs/shell.py", line 489, in invoke
    val, line, finished = self.invoke_one(line)
  File "/home/dvk/.virtualenvs/coretools/lib/python3.6/site-packages/typedargs/shell.py", line 452, in invoke_one
    val = func(*posargs, **kwargs)
  File "</home/dvk/.virtualenvs/coretools/lib/python3.6/site-packages/decorator.py:decorator-gen-41>", line 2, in set_temperature
  File "/home/dvk/.virtualenvs/coretools/lib/python3.6/site-packages/typedargs/utils.py", line 32, in _check_and_execute
    retval = func(*convargs, **convkw)
  File "/home/dvk/test/test_component/python/demo_proxy.py", line 31, in set_temperature
    self.rpc_v2(0x8002, "L", "", new_temp)
  File "/home/dvk/projects/coretools/iotilecore/iotile/core/hw/proxy/proxy.py", line 99, in rpc_v2
    return unpack_rpc_payload(result_format, payload)
  File "/home/dvk/projects/coretools/iotilecore/iotile/core/hw/virtual/common_types.py", line 140, in unpack_rpc_payload
    return struct.unpack(code, payload)
TypeError: a bytes-like object is required, not 'list'
@dvksirin dvksirin added the iotile-core Related to iotile-core package label Jan 28, 2020
@timburke
Copy link
Member

timburke commented Jan 28, 2020

Yes, this is a clear bug. The oversight seems to be here:

If the user doesn't indicate an rpc response then we should:

  • verify they returned None or an empty list (otherwise raise ReturnValue error)
  • return an empty byte string out of the rpc decorator.

The right exception to raise is here:

class RPCInvalidReturnValueError(RPCError):

It's possible to write a quick test here by directly invoking the wrapped rpc on a virtual device class using simple_rpc (which didn't exist at the time of the original tutorial):

def simple_rpc(self, address, rpc_id, *args, **kwargs):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
iotile-core Related to iotile-core package type:bug
Projects
None yet
Development

No branches or pull requests

2 participants