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
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
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
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
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"
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'
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'
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