예제 #1
0
def test_decode_with_ref_cache():
    embedded_A = MockObject(channel_id='0x3DE6B821E4fb4599653BF76FF60dC5FaF2e92De8')
    A = MockObject(attr1=10, attr2='123', embedded=embedded_A)

    decoded_A = JSONSerializer.deserialize(
        JSONSerializer.serialize(A),
    )

    assert A == decoded_A

    # Create an exact replica of A
    embedded_B = MockObject(channel_id='0x3DE6B821E4fb4599653BF76FF60dC5FaF2e92De8')
    B = MockObject(attr1=10, attr2='123', embedded=embedded_B)

    decoded_B = JSONSerializer.deserialize(
        JSONSerializer.serialize(B),
    )

    assert B == decoded_B
    assert id(B) != id(decoded_B)
    # Make sure that the original decoded A
    # is returned
    assert id(decoded_A) == id(decoded_B)

    # Make sure no object is cached
    RaidenJSONDecoder.cache_object_references = False
    RaidenJSONDecoder.ref_cache.clear()

    # Decode some object
    decoded_B = JSONSerializer.deserialize(
        JSONSerializer.serialize(B),
    )

    for _, cache_entries in RaidenJSONDecoder.ref_cache._cache.items():
        assert len(cache_entries) == 0
예제 #2
0
    def dispatch(self, state_change: StateChange) -> List[Event]:
        """ Apply the `state_change` in the current machine and return the
        resulting events.

        Args:
            state_change: An object representation of a state
            change.

        Return:
            A list of events produced by the state transition.
            It's the upper layer's responsibility to decided how to handle
            these events.
        """
        assert isinstance(state_change, StateChange)

        # check state change serialization
        try:
            json = JSONSerializer.serialize(state_change)
            restored = JSONSerializer.deserialize(json)

            if state_change != restored:
                log.error('Serialisation failed for:',
                          state_change.__class__.__name__)

        except Exception:
            log.error('Serialisation failed for:',
                      state_change.__class__.__name__)

        # the state objects must be treated as immutable, so make a copy of the
        # current state and pass the copy to the state machine to be modified.
        next_state = deepcopy(self.current_state)

        # update the current state by applying the change
        iteration = self.state_transition(
            next_state,
            state_change,
        )

        assert isinstance(iteration, TransitionResult)

        self.current_state = iteration.new_state
        events = iteration.events

        # check state serialization
        state = self.current_state
        if state is not None:
            json = JSONSerializer.serialize(state)
            restored = JSONSerializer.deserialize(json)

            if state != restored:
                compare_state_trees(state, restored)

        assert isinstance(self.current_state, (State, type(None)))
        assert all(isinstance(e, Event) for e in events)

        return events
예제 #3
0
def test_actioninitchain_restore():
    """ ActionInitChain *must* restore the previous pseudo random generator
    state.

    Message identifiers are used for confirmation messages, e.g. delivered and
    processed messages, therefore it's important for each message identifier to
    not collide with a previous identifier, for this reason the PRNG is used.

    Additionally, during restarts the state changes are reapplied, and it's
    really important for the re-execution of the state changes to be
    deterministic, otherwise undefined behavior may happen. For this reason the
    state of the PRNG must be restored.

    If the above is not respected, the message ids generated during restart
    will not match the previous IDs and the message queues won't be properly
    cleared up.
    """
    pseudo_random_generator = random.Random()
    block_number = 577
    our_address = factories.make_address()
    chain_id = 777

    original_obj = state_change.ActionInitChain(
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
        block_hash=factories.make_block_hash(),
        our_address=our_address,
        chain_id=chain_id,
    )

    decoded_obj = JSONSerializer.deserialize(
        JSONSerializer.serialize(original_obj))

    assert original_obj == decoded_obj
예제 #4
0
def test_actioninitchain_restore():
    """ ActionInitChain *must* restore the previous pseudo random generator
    state.

    Message identifiers are used for confirmation messages, e.g. delivered and
    processed messages, therefore it's important for each message identifier to
    not collide with a previous identifier, for this reason the PRNG is used.

    Additionally, during restarts the state changes are reapplied, and it's
    really important for the re-execution of the state changes to be
    deterministic, otherwise undefined behavior may happen. For this reason the
    state of the PRNG must be restored.

    If the above is not respected, the message ids generated during restart
    will not match the previous IDs and the message queues won't be properly
    cleared up.
    """
    pseudo_random_generator = random.Random()
    block_number = 577
    our_address = factories.make_address()
    chain_id = 777

    original_obj = state_change.ActionInitChain(
        pseudo_random_generator,
        block_number,
        our_address,
        chain_id,
    )

    decoded_obj = JSONSerializer.deserialize(
        JSONSerializer.serialize(original_obj),
    )

    assert original_obj == decoded_obj
예제 #5
0
def test_object_custom_serialization():
    # Simple encode/decode
    original_obj = MockObject(attr1="Hello", attr2="World")
    decoded_obj = JSONSerializer.deserialize(
        JSONSerializer.serialize(original_obj))

    assert original_obj == decoded_obj

    # Encode/Decode with embedded objects
    embedded_obj = MockObject(amount=1, identifier="123")
    original_obj = MockObject(embedded=embedded_obj)
    decoded_obj = JSONSerializer.deserialize(
        JSONSerializer.serialize(original_obj))

    assert original_obj == decoded_obj
    assert decoded_obj.embedded.amount == 1
    assert decoded_obj.embedded.identifier == "123"
예제 #6
0
def test_object_custom_serialization():
    # Simple encode/decode
    original_obj = MockObject(attr1="Hello", attr2="World")
    decoded_obj = JSONSerializer.deserialize(
        JSONSerializer.serialize(original_obj),
    )

    assert original_obj == decoded_obj

    # Encode/Decode with embedded objects
    embedded_obj = MockObject(amount=1, identifier='123')
    original_obj = MockObject(embedded=embedded_obj)
    decoded_obj = JSONSerializer.deserialize(
        JSONSerializer.serialize(original_obj),
    )

    assert original_obj == decoded_obj
    assert decoded_obj.embedded.amount == 1
    assert decoded_obj.embedded.identifier == '123'
예제 #7
0
def test_decode_with_unknown_type():
    test_str = """
{
    "_type": "some.non.existent.package",
    "attr1": "test"
}
"""
    with pytest.raises(TypeError) as m:
        JSONSerializer.deserialize(test_str)
        assert str(m) == 'Module some.non.existent.package does not exist'

    test_str = """
{
    "_type": "raiden.tests.unit.test_serialization.NonExistentClass",
    "attr1": "test"
}
"""
    with pytest.raises(TypeError) as m:
        JSONSerializer.deserialize(test_str)
        assert str(m) == 'raiden.tests.unit.test_serialization.NonExistentClass'
예제 #8
0
def test_decode_with_unknown_type():
    test_str = """
{
    "_type": "some.non.existent.package",
    "attr1": "test"
}
"""
    with pytest.raises(TypeError) as m:
        JSONSerializer.deserialize(test_str)
        assert str(m) == 'Module some.non.existent.package does not exist'

    test_str = """
{
    "_type": "raiden.tests.unit.test_serialization.NonExistentClass",
    "attr1": "test"
}
"""
    with pytest.raises(TypeError) as m:
        JSONSerializer.deserialize(test_str)
        assert str(m) == 'raiden.tests.unit.test_serialization.NonExistentClass'
예제 #9
0
def test_chainstate_restore():
    pseudo_random_generator = random.Random()
    block_number = 577
    our_address = factories.make_address()
    chain_id = 777

    original_obj = state.ChainState(
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
        our_address=our_address,
        chain_id=chain_id,
    )

    decoded_obj = JSONSerializer.deserialize(
        JSONSerializer.serialize(original_obj), )

    assert original_obj == decoded_obj
예제 #10
0
def test_chainstate_restore():
    pseudo_random_generator = random.Random()
    block_number = 577
    our_address = factories.make_address()
    chain_id = 777

    original_obj = state.ChainState(
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
        our_address=our_address,
        chain_id=chain_id,
    )

    decoded_obj = JSONSerializer.deserialize(
        JSONSerializer.serialize(original_obj),
    )

    assert original_obj == decoded_obj