Example #1
0
def test_entity_values() -> None:
    """Test various entity assigns for value and type correctness."""
    ent = EntityTest()

    # Simple int field.
    with pytest.raises(TypeError):
        # noinspection PyTypeHints
        ent.ival = 'strval'  # type: ignore
    assert static_type_equals(ent.ival, int)
    assert isinstance(ent.ival, int)
    assert ent.ival == 345
    ent.ival = 346
    assert ent.ival == 346

    # Simple float field.
    with pytest.raises(TypeError):
        # noinspection PyTypeHints
        ent.fval = 'foo'  # type: ignore
    assert static_type_equals(ent.fval, float)
    ent.fval = 2
    ent.fval = True
    ent.fval = 1.0

    # Simple value list field.
    assert not ent.slval  # bool operator
    assert len(ent.slval) == 0
    with pytest.raises(TypeError):
        ent.slval.append(1)  # type: ignore
    ent.slval.append('blah')
    assert ent.slval  # bool operator
    assert len(ent.slval) == 1
    assert list(ent.slval) == ['blah']
    with pytest.raises(TypeError):
        # noinspection PyTypeHints
        ent.slval = ['foo', 'bar', 1]  # type: ignore

    # Simple value dict field.
    assert not ent.str_int_dict  # bool operator
    assert 'foo' not in ent.str_int_dict
    # Set with incorrect key type should give TypeError.
    with pytest.raises(TypeError):
        ent.str_int_dict[0] = 123  # type: ignore
    # And set with incorrect value type should do same.
    with pytest.raises(TypeError):
        ent.str_int_dict['foo'] = 'bar'  # type: ignore
    ent.str_int_dict['foo'] = 123
    assert ent.str_int_dict  # bool operator
    assert static_type_equals(ent.str_int_dict['foo'], int)
    assert ent.str_int_dict['foo'] == 123

    # Waaah; this works at runtime, but it seems that we'd need
    # to have BoundDictField inherit from Mapping for mypy to accept this.
    # (which seems to get a bit ugly, but may be worth revisiting)
    # assert dict(ent.str_int_dict) == {'foo': 123}

    # Passing key/value pairs as a list works though..
    assert dict(ent.str_int_dict.items()) == {'foo': 123}
Example #2
0
def test_entity_values_2() -> None:
    """Test various entity assigns for value and type correctness."""

    ent = EntityTest()

    # Compound value
    assert static_type_equals(ent.grp, CompoundTest)
    assert static_type_equals(ent.grp.isubval, int)
    assert isinstance(ent.grp.isubval, int)
    with pytest.raises(TypeError):
        # noinspection PyTypeHints
        ent.grp.isubval = 'blah'  # type: ignore

    # Compound value inheritance.
    assert ent.grp2.isubval2 == 3453
    assert ent.grp2.isubval == 34532

    # Compound list field.
    with pytest.raises(IndexError):
        print(ent.compoundlist[0])
    with pytest.raises(TypeError):
        ent.compoundlist[0] = 123  # type: ignore
    assert len(ent.compoundlist) == 0
    assert not ent.compoundlist  # bool operator
    ent.compoundlist.append()
    assert ent.compoundlist  # bool operator
    assert len(ent.compoundlist) == 1
    assert static_type_equals(ent.compoundlist[0], CompoundTest)

    # Compound dict field.
    assert not ent.compounddict  # bool operator
    cdval = ent.compounddict.add('foo')
    assert ent.compounddict  # bool operator
    assert static_type_equals(cdval, CompoundTest)
    # Set with incorrect key type should give TypeError.
    with pytest.raises(TypeError):
        _cdval2 = ent.compounddict.add(1)  # type: ignore
    # Hmm; should this throw a TypeError and not a KeyError?..
    with pytest.raises(KeyError):
        _cdval3 = ent.compounddict[1]  # type: ignore
    assert static_type_equals(ent.compounddict['foo'], CompoundTest)

    # Enum value
    with pytest.raises(ValueError):
        # noinspection PyTypeHints
        ent.enumval = None  # type: ignore
    assert ent.enumval == EnumTest.FIRST

    # Optional Enum value
    ent.enumval2 = None
    assert ent.enumval2 is None

    # Nested compound values
    assert not ent.grp.compoundlist  # bool operator
    val = ent.grp.compoundlist.append()
    assert ent.grp.compoundlist  # bool operator
    assert static_type_equals(val, SubCompoundTest)
    assert static_type_equals(ent.grp.compoundlist[0], SubCompoundTest)
    assert static_type_equals(ent.grp.compoundlist[0].subval, bool)
Example #3
0
def test_field_access_from_type() -> None:
    """Accessing fields through type objects should return the Field objs."""

    ent = EntityTest()

    # Accessing fields through the type should return field objects
    # instead of values.
    assert static_type_equals(ent.ival, int)
    assert isinstance(ent.ival, int)
    mypytype = 'efro.entity._field.Field[builtins.int*]'
    assert static_type_equals(type(ent).ival, mypytype)
    assert isinstance(type(ent).ival, entity.Field)

    # Accessing subtype on a nested compound field..
    assert static_type_equals(type(ent).compoundlist.d_value, CompoundTest)
    assert isinstance(type(ent).compoundlist.d_value, CompoundTest)
Example #4
0
def test_synchronous_messaging() -> None:
    """Test the full pipeline."""

    # Define a class that can send messages and one that can receive them.
    class TestClassS:
        """Test class incorporating send functionality."""

        msg = _TestMessageSender(TEST_PROTOCOL)

        def __init__(self, target: TestClassR) -> None:
            self._target = target

        @msg.send_raw_handler
        def _send_raw_message(self, data: bytes) -> bytes:
            """Test."""
            return self._target.receiver.handle_raw_message(data)

    class TestClassR:
        """Test class incorporating receive functionality."""

        receiver = _TestMessageReceiver(TEST_PROTOCOL)

        @receiver.handler
        def handle_test_message_1(self, msg: _TMessage1) -> _TResponse1:
            """Test."""
            if msg.ival == 1:
                raise CleanError('Testing Clean Error')
            if msg.ival == 2:
                raise RuntimeError('Testing Runtime Error')
            return _TResponse1(bval=True)

        @receiver.handler
        def handle_test_message_2(
                self, msg: _TMessage2) -> Union[_TResponse1, _TResponse2]:
            """Test."""
            del msg  # Unused
            return _TResponse2(fval=1.2)

        @receiver.handler
        def handle_test_message_3(self, msg: _TMessage3) -> None:
            """Test."""
            del msg  # Unused

        receiver.validate()

    obj_r = TestClassR()
    obj = TestClassS(target=obj_r)

    response = obj.msg.send(_TMessage1(ival=0))
    assert isinstance(response, _TResponse1)

    response2 = obj.msg.send(_TMessage2(sval='rah'))
    assert isinstance(response2, (_TResponse1, _TResponse2))

    response3 = obj.msg.send(_TMessage3(sval='rah'))
    assert response3 is None

    # Make sure static typing lines up too.
    if os.environ.get('EFRO_TEST_MESSAGE_FAST') != '1':
        assert static_type_equals(response, _TResponse1)
        assert static_type_equals(response3, None)

    # Remote CleanErrors should come across locally as the same.
    try:
        _response4 = obj.msg.send(_TMessage1(ival=1))
    except Exception as exc:
        assert isinstance(exc, CleanError)
        assert str(exc) == 'Testing Clean Error'

    # Other remote errors should result in RemoteError.
    with pytest.raises(RemoteError):
        _response4 = obj.msg.send(_TMessage1(ival=2))
Example #5
0
def test_entity_mixin() -> None:
    """Testing our mixin entity variety."""
    ent = EntityTestMixin()
    assert static_type_equals(ent.isubval2, int)
    assert ent.isubval2 == 3453
Example #6
0
def test_field_copies() -> None:
    """Test copying various values between fields."""
    ent1 = EntityTest()
    ent2 = EntityTest()

    # Copying a simple value.
    ent1.ival = 334
    ent2.ival = ent1.ival
    assert ent2.ival == 334

    # Copying a nested compound.
    ent1.grp.isubval = 543
    ent2.grp = ent1.grp
    assert ent2.grp.isubval == 543

    # Type-checker currently allows this because both are Compounds
    # but should fail at runtime since their subfield arrangement differs.
    # reveal_type(ent1.grp.blah)
    with pytest.raises(ValueError):
        ent2.grp = ent1.grp2

    # Copying a value list.
    ent1.slval = ['foo', 'bar']
    assert ent1.slval == ['foo', 'bar']
    ent2.slval = ent1.slval
    assert ent2.slval == ['foo', 'bar']

    # Copying a value dict.
    ent1.str_int_dict['tval'] = 987
    ent2.str_int_dict = ent1.str_int_dict
    assert ent2.str_int_dict['tval'] == 987

    # Copying a CompoundList
    val = ent1.compoundlist.append()
    val.isubval = 356
    assert ent1.compoundlist[0].isubval == 356
    assert len(ent1.compoundlist) == 1
    ent1.compoundlist.append()
    assert len(ent1.compoundlist) == 2
    assert len(ent2.compoundlist) == 0
    # Copying to the same field on different obj should work.
    ent2.compoundlist = ent1.compoundlist
    assert ent2.compoundlist[0].isubval == 356
    assert len(ent2.compoundlist) == 2
    # Cross-field assigns should work too if the field layouts match..
    ent1.compoundlist2 = ent1.compoundlist
    # And not if they don't...
    # (in this case mypy errors too but that may not always be the case)
    with pytest.raises(ValueError):
        ent1.compoundlist3 = ent1.compoundlist  # type: ignore

    # Copying a CompoundDict
    ent1.compounddict.add('foo')
    ent1.compounddict.add('bar')
    assert static_type_equals(ent1.compounddict['foo'].isubval, int)
    ent1.compounddict['foo'].isubval = 23
    # Copying to the same field on different obj should work.
    ent2.compounddict = ent1.compounddict
    assert ent2.compounddict.keys() == ['foo', 'bar']
    assert ent2.compounddict['foo'].isubval == 23
    # Cross field assigns should work too if the field layouts match..
    ent1.compounddict2 = ent1.compounddict
    # ..And should fail otherwise.
    # (mypy catches this too, but that may not always be the case if
    # two CompoundValues have the same type but different layouts based
    # on their __init__ args or whatnot)
    with pytest.raises(ValueError):
        ent1.compounddict3 = ent1.compounddict  # type: ignore
    # Make sure invalid key types get caught when setting a full dict:
    with pytest.raises(TypeError):
        ent1.compounddict2 = {
            'foo': ent1.compounddict['foo'],
            2: ent1.compounddict['bar'],  # type: ignore
        }
Example #7
0
def test_full_pipeline() -> None:
    """Test the full pipeline."""

    # pylint: disable=too-many-locals
    # pylint: disable=too-many-statements

    # Define a class that can send messages and one that can receive them.
    class TestClassS:
        """Test class incorporating send functionality."""

        msg = _TestMessageSenderBBoth()

        test_handling_unregistered = False

        def __init__(self, target: Union[TestClassRSync,
                                         TestClassRAsync]) -> None:
            self.test_sidecar = False
            self._target = target

        @msg.send_method
        def _send_raw_message(self, data: str) -> str:
            """Handle synchronous sending of raw json message data."""
            # Just talk directly to the receiver for this example.
            # (currently only support synchronous receivers)
            assert isinstance(self._target, TestClassRSync)
            try:
                return self._target.receiver.handle_raw_message(
                    data, raise_unregistered=self.test_handling_unregistered)
            except UnregisteredMessageIDError:
                if self.test_handling_unregistered:
                    # Emulate forwarding unregistered messages on to some
                    # other handler...
                    response_dict = self.msg.protocol.response_to_dict(
                        EmptyResponse())
                    return self.msg.protocol.encode_dict(response_dict)
                raise

        @msg.send_async_method
        async def _send_raw_message_async(self, data: str) -> str:
            """Handle asynchronous sending of raw json message data."""
            # Just talk directly to the receiver for this example.
            # (we can do sync or async receivers)
            if isinstance(self._target, TestClassRSync):
                return self._target.receiver.handle_raw_message(data)
            return await self._target.receiver.handle_raw_message(data)

        @msg.encode_filter_method
        def _encode_filter(self, msg: Message, outdict: dict) -> None:
            """Filter our outgoing messages."""
            if self.test_sidecar:
                outdict['_sidecar_data'] = getattr(msg, '_sidecar_data')

        @msg.decode_filter_method
        def _decode_filter(self, indata: dict, response: Response) -> None:
            """Filter our incoming responses."""
            if self.test_sidecar:
                setattr(response, '_sidecar_data', indata['_sidecar_data'])

    class TestClassRSync:
        """Test class incorporating synchronous receive functionality."""

        receiver = _TestSyncMessageReceiver()

        def __init__(self) -> None:
            self.test_sidecar = False

        @receiver.handler
        def handle_test_message_1(self, msg: _TMsg1) -> _TResp1:
            """Test."""
            if msg.ival == 1:
                raise CleanError('Testing Clean Error')
            if msg.ival == 2:
                raise RuntimeError('Testing Runtime Error')
            out = _TResp1(bval=True)
            if self.test_sidecar:
                setattr(out, '_sidecar_data', getattr(msg, '_sidecar_data'))
            return out

        @receiver.handler
        def handle_test_message_2(self,
                                  msg: _TMsg2) -> Union[_TResp1, _TResp2]:
            """Test."""
            del msg  # Unused
            return _TResp2(fval=1.2)

        @receiver.handler
        def handle_test_message_3(self, msg: _TMsg3) -> None:
            """Test."""
            del msg  # Unused

        @receiver.decode_filter_method
        def _decode_filter(self, indata: dict, message: Message) -> None:
            """Filter our incoming messages."""
            if self.test_sidecar:
                setattr(message, '_sidecar_data', indata['_sidecar_data'])

        @receiver.encode_filter_method
        def _encode_filter(self, response: Response, outdict: dict) -> None:
            """Filter our outgoing responses."""
            if self.test_sidecar:
                outdict['_sidecar_data'] = getattr(response, '_sidecar_data')

        receiver.validate()

    class TestClassRAsync:
        """Test class incorporating asynchronous receive functionality."""

        receiver = _TestAsyncMessageReceiver()

        @receiver.handler
        async def handle_test_message_1(self, msg: _TMsg1) -> _TResp1:
            """Test."""
            if msg.ival == 1:
                raise CleanError('Testing Clean Error')
            if msg.ival == 2:
                raise RuntimeError('Testing Runtime Error')
            return _TResp1(bval=True)

        @receiver.handler
        async def handle_test_message_2(
                self, msg: _TMsg2) -> Union[_TResp1, _TResp2]:
            """Test."""
            del msg  # Unused
            return _TResp2(fval=1.2)

        @receiver.handler
        async def handle_test_message_3(self, msg: _TMsg3) -> None:
            """Test."""
            del msg  # Unused

        receiver.validate()

    obj_r_sync = TestClassRSync()
    obj_r_async = TestClassRAsync()
    obj = TestClassS(target=obj_r_sync)
    obj2 = TestClassS(target=obj_r_async)

    # Test sends (of sync and async varieties).
    response1 = obj.msg.send(_TMsg1(ival=0))
    response2 = obj.msg.send(_TMsg2(sval='rah'))
    response3 = obj.msg.send(_TMsg3(sval='rah'))
    response4 = asyncio.run(obj.msg.send_async(_TMsg1(ival=0)))

    # Make sure static typing lines up with what we expect.
    if os.environ.get('EFRO_TEST_MESSAGE_FAST') != '1':
        assert static_type_equals(response1, _TResp1)
        assert static_type_equals(response3, None)

    assert isinstance(response1, _TResp1)
    assert isinstance(response2, (_TResp1, _TResp2))
    assert response3 is None
    assert isinstance(response4, _TResp1)

    # Remote CleanErrors should come across locally as the same.
    try:
        _response5 = obj.msg.send(_TMsg1(ival=1))
    except Exception as exc:
        assert isinstance(exc, CleanError)
        assert str(exc) == 'Testing Clean Error'

    # Other remote errors should result in RemoteError.
    with pytest.raises(RemoteError):
        _response5 = obj.msg.send(_TMsg1(ival=2))

    # Now test sends to async handlers.
    response6 = asyncio.run(obj2.msg.send_async(_TMsg1(ival=0)))
    assert isinstance(response6, _TResp1)

    # Our sender here is using a 'newer' protocol which contains a message
    # type not in the older protocol used by our receivers. Make sure we
    # get the expected error when trying to send that message to them.
    with pytest.raises(RemoteError):
        _response7 = obj.msg.send(_TMsg4(sval2='blargh'))

    # Also make sure the receiver can explicitly handle unregistered
    # messages (by forwarding them along to something that can, etc).
    obj.test_handling_unregistered = True
    response7 = obj.msg.send(_TMsg4(sval2='blargh'))
    assert response7 is None

    # Make sure static typing lines up with what we expect.
    if os.environ.get('EFRO_TEST_MESSAGE_FAST') != '1':
        assert static_type_equals(response6, _TResp1)

    # Now test adding extra data to messages. This should be transferred
    # into the encoded message, copied to the response, and again back
    # through the encoded response using the filter functions we defined.
    obj.test_sidecar = True
    obj_r_sync.test_sidecar = True
    outmsg = _TMsg1(ival=0)
    setattr(outmsg, '_sidecar_data', 198)  # Our test payload.
    response1 = obj.msg.send(outmsg)
    assert getattr(response1, '_sidecar_data') == 198
    obj.test_sidecar = False
    obj_r_sync.test_sidecar = False
Example #8
0
def test_entity_values() -> None:
    """Test various entity assigns for value and type correctness."""
    # pylint: disable=too-many-statements

    ent = EntityTest()

    # Simple int field.
    with pytest.raises(TypeError):
        # noinspection PyTypeHints
        ent.ival = 'strval'  # type: ignore
    assert static_type_equals(ent.ival, int)
    assert isinstance(ent.ival, int)
    assert ent.ival == 345
    ent.ival = 346
    assert ent.ival == 346

    # Simple float field.
    with pytest.raises(TypeError):
        # noinspection PyTypeHints
        ent.fval = 'foo'  # type: ignore
    assert static_type_equals(ent.fval, float)
    ent.fval = 2
    ent.fval = True
    ent.fval = 1.0

    # Simple value list field.
    assert not ent.slval  # bool operator
    assert len(ent.slval) == 0
    with pytest.raises(TypeError):
        ent.slval.append(1)  # type: ignore
    ent.slval.append('blah')
    assert ent.slval  # bool operator
    assert len(ent.slval) == 1
    assert list(ent.slval) == ['blah']
    with pytest.raises(TypeError):
        # noinspection PyTypeHints
        ent.slval = ['foo', 'bar', 1]  # type: ignore

    # Simple value dict field.
    assert not ent.str_int_dict  # bool operator
    assert 'foo' not in ent.str_int_dict
    # Set with incorrect key type should give TypeError.
    with pytest.raises(TypeError):
        ent.str_int_dict[0] = 123  # type: ignore
    # And set with incorrect value type should do same.
    with pytest.raises(TypeError):
        ent.str_int_dict['foo'] = 'bar'  # type: ignore
    ent.str_int_dict['foo'] = 123
    assert ent.str_int_dict  # bool operator
    assert static_type_equals(ent.str_int_dict['foo'], int)
    assert ent.str_int_dict['foo'] == 123

    # Simple dict with enum key.
    assert EnumTest.FIRST not in ent.enum_int_dict
    ent.enum_int_dict[EnumTest.FIRST] = 234
    assert EnumTest.FIRST in ent.enum_int_dict
    assert ent.enum_int_dict[EnumTest.FIRST] == 234
    # Set with incorrect key type should give TypeError.
    with pytest.raises(TypeError):
        ent.enum_int_dict[0] = 123  # type: ignore
    with pytest.raises(TypeError):
        ent.enum_int_dict[EnumTest2.FIRST] = 123  # type: ignore
    # And set with incorrect value type should do same.
    with pytest.raises(TypeError):
        ent.enum_int_dict[EnumTest.FIRST] = 'bar'  # type: ignore
    # Make sure is stored as underlying type.
    assert ent.d_data['ed'] == {0: 234}

    # Make sure invalid raw enum values are caught.
    ent2 = EntityTest()
    ent2.set_data({})
    ent2.set_data({'ed': {0: 111}})
    with pytest.raises(ValueError):
        ent2.set_data({'ed': {5: 111}})

    # Waaah; this works at runtime, but it seems that we'd need
    # to have BoundDictField inherit from Mapping for mypy to accept this.
    # (which seems to get a bit ugly, but may be worth revisiting)
    # assert dict(ent.str_int_dict) == {'foo': 123}

    # Passing key/value pairs as a list works though..
    assert dict(ent.str_int_dict.items()) == {'foo': 123}
Example #9
0
def test_entity_values_2() -> None:
    """Test various entity assigns for value and type correctness."""
    # pylint: disable=too-many-statements

    ent = EntityTest()

    # Compound value
    assert static_type_equals(ent.grp, CompoundTest)
    assert static_type_equals(ent.grp.isubval, int)
    assert isinstance(ent.grp.isubval, int)
    with pytest.raises(TypeError):
        # noinspection PyTypeHints
        ent.grp.isubval = 'blah'  # type: ignore

    # Compound value inheritance.
    assert ent.grp2.isubval2 == 3453
    assert ent.grp2.isubval == 34532

    # Compound list field.
    with pytest.raises(IndexError):
        print(ent.compoundlist[0])
    with pytest.raises(TypeError):
        ent.compoundlist[0] = 123  # type: ignore
    assert len(ent.compoundlist) == 0
    assert not ent.compoundlist  # bool operator
    ent.compoundlist.append()
    assert ent.compoundlist  # bool operator
    assert len(ent.compoundlist) == 1
    assert static_type_equals(ent.compoundlist[0], CompoundTest)

    # Compound dict field.
    assert not ent.compounddict  # bool operator
    cdval = ent.compounddict.add('foo')
    assert ent.compounddict  # bool operator
    assert static_type_equals(cdval, CompoundTest)
    # Set with incorrect key type should give TypeError.
    with pytest.raises(TypeError):
        _cdval2 = ent.compounddict.add(1)  # type: ignore
    # Hmm; should this throw a TypeError and not a KeyError?..
    with pytest.raises(TypeError):
        _cdval3 = ent.compounddict[1]  # type: ignore
    assert static_type_equals(ent.compounddict['foo'], CompoundTest)

    # Enum value
    with pytest.raises(ValueError):
        # noinspection PyTypeHints
        ent.enumval = None  # type: ignore
    assert ent.enumval is EnumTest.FIRST

    # Compound dict with enum key.
    assert not ent.compounddict4  # bool operator
    assert EnumTest.FIRST not in ent.compounddict4
    _cd4val = ent.compounddict4.add(EnumTest.FIRST)
    assert ent.compounddict4  # bool operator
    assert EnumTest.FIRST in ent.compounddict4
    ent.compounddict4[EnumTest.FIRST].isubval = 222
    assert ent.compounddict4[EnumTest.FIRST].isubval == 222
    with pytest.raises(TypeError):
        ent.compounddict4[0].isubval = 222  # type: ignore
    assert static_type_equals(ent.compounddict4[EnumTest.FIRST], CompoundTest)
    # Make sure enum keys are stored as underlying type.
    assert ent.d_data['td4'] == {0: {'i': 222, 'l': []}}

    # Optional Enum value
    ent.enumval2 = None
    assert ent.enumval2 is None

    # Nested compound values
    assert not ent.grp.compoundlist  # bool operator
    val = ent.grp.compoundlist.append()
    assert ent.grp.compoundlist  # bool operator
    assert static_type_equals(val, SubCompoundTest)
    assert static_type_equals(ent.grp.compoundlist[0], SubCompoundTest)
    assert static_type_equals(ent.grp.compoundlist[0].subval, bool)

    # Make sure we can digest the same data we spit out.
    ent.set_data(ent.d_data)
Example #10
0
def test_full_pipeline() -> None:
    """Test the full pipeline."""

    # Define a class that can send messages and one that can receive them.
    class TestClassS:
        """Test class incorporating send functionality."""

        msg = _TestMessageSenderBoth()

        def __init__(self, target: Union[TestClassRSync,
                                         TestClassRAsync]) -> None:
            self._target = target

        @msg.send_method
        def _send_raw_message(self, data: str) -> str:
            """Handle synchronous sending of raw json message data."""
            # Just talk directly to the receiver for this example.
            # (currently only support synchronous receivers)
            assert isinstance(self._target, TestClassRSync)
            return self._target.receiver.handle_raw_message(data)

        @msg.send_async_method
        async def _send_raw_message_async(self, data: str) -> str:
            """Handle asynchronous sending of raw json message data."""
            # Just talk directly to the receiver for this example.
            # (we can do sync or async receivers)
            if isinstance(self._target, TestClassRSync):
                return self._target.receiver.handle_raw_message(data)
            return await self._target.receiver.handle_raw_message(data)

    class TestClassRSync:
        """Test class incorporating synchronous receive functionality."""

        receiver = _TestSyncMessageReceiver()

        @receiver.handler
        def handle_test_message_1(self, msg: _TMsg1) -> _TResp1:
            """Test."""
            if msg.ival == 1:
                raise CleanError('Testing Clean Error')
            if msg.ival == 2:
                raise RuntimeError('Testing Runtime Error')
            return _TResp1(bval=True)

        @receiver.handler
        def handle_test_message_2(self,
                                  msg: _TMsg2) -> Union[_TResp1, _TResp2]:
            """Test."""
            del msg  # Unused
            return _TResp2(fval=1.2)

        @receiver.handler
        def handle_test_message_3(self, msg: _TMsg3) -> None:
            """Test."""
            del msg  # Unused

        receiver.validate()

    class TestClassRAsync:
        """Test class incorporating asynchronous receive functionality."""

        receiver = _TestAsyncMessageReceiver()

        @receiver.handler
        async def handle_test_message_1(self, msg: _TMsg1) -> _TResp1:
            """Test."""
            if msg.ival == 1:
                raise CleanError('Testing Clean Error')
            if msg.ival == 2:
                raise RuntimeError('Testing Runtime Error')
            return _TResp1(bval=True)

        @receiver.handler
        async def handle_test_message_2(
                self, msg: _TMsg2) -> Union[_TResp1, _TResp2]:
            """Test."""
            del msg  # Unused
            return _TResp2(fval=1.2)

        @receiver.handler
        async def handle_test_message_3(self, msg: _TMsg3) -> None:
            """Test."""
            del msg  # Unused

        receiver.validate()

    obj_r_sync = TestClassRSync()
    obj_r_async = TestClassRAsync()
    obj = TestClassS(target=obj_r_sync)
    obj2 = TestClassS(target=obj_r_async)

    # Test sends (of sync and async varieties).
    response1 = obj.msg.send(_TMsg1(ival=0))
    response2 = obj.msg.send(_TMsg2(sval='rah'))
    response3 = obj.msg.send(_TMsg3(sval='rah'))
    response4 = asyncio.run(obj.msg.send_async(_TMsg1(ival=0)))

    # Make sure static typing lines up with what we expect.
    if os.environ.get('EFRO_TEST_MESSAGE_FAST') != '1':
        assert static_type_equals(response1, _TResp1)
        assert static_type_equals(response3, None)

    assert isinstance(response1, _TResp1)
    assert isinstance(response2, (_TResp1, _TResp2))
    assert response3 is None
    assert isinstance(response4, _TResp1)

    # Remote CleanErrors should come across locally as the same.
    try:
        _response5 = obj.msg.send(_TMsg1(ival=1))
    except Exception as exc:
        assert isinstance(exc, CleanError)
        assert str(exc) == 'Testing Clean Error'

    # Other remote errors should result in RemoteError.
    with pytest.raises(RemoteError):
        _response5 = obj.msg.send(_TMsg1(ival=2))

    # Now test sends to async handlers.
    response6 = asyncio.run(obj2.msg.send_async(_TMsg1(ival=0)))
    assert isinstance(response6, _TResp1)

    # Make sure static typing lines up with what we expect.
    if os.environ.get('EFRO_TEST_MESSAGE_FAST') != '1':
        assert static_type_equals(response6, _TResp1)