def __init__(self, name=None, state_id=None, input_keys=None, output_keys=None, income=None, outcomes=None, states=None, transitions=None, data_flows=None, start_state_id=None, scoped_variables=None, safe_init=True): ContainerState.__init__(self, name, state_id, input_keys, output_keys, income, outcomes, states, transitions, data_flows, start_state_id, scoped_variables, safe_init=safe_init) self.concurrency_history_item = None
def __init__(self, name=None, state_id=None, input_data_ports=None, output_data_ports=None, income=None, outcomes=None, states=None, transitions=None, data_flows=None, start_state_id=None, scoped_variables=None, safe_init=True): ContainerState.__init__(self, name, state_id, input_data_ports, output_data_ports, income, outcomes, states, transitions, data_flows, start_state_id, scoped_variables, safe_init=safe_init) self.handling_execution_mode = False self.child_state = None self.last_error = None self.last_child = None self.last_transition = None
def __init__(self, name=None, state_id=None, input_keys=None, output_keys=None, outcomes=None, states=None, transitions=None, data_flows=None, start_state_id=None, scoped_variables=None): ContainerState.__init__(self, name, state_id, input_keys, output_keys, outcomes, states, transitions, data_flows, start_state_id, scoped_variables)
def remove_state(self, state_id, recursive=True, force=False, destroy=True): """ Overwrite the parent class remove state method by checking if the user tries to delete the decider state :param state_id: the id of the state to remove :param recursive: a flag to indicate a recursive disassembling of all substates :param force: a flag to indicate forcefully deletion of all states (important of the decider state in the barrier concurrency state) :param destroy: a flag which indicates if the state should not only be disconnected from the state but also destroyed, including all its state elements :raises exceptions.AttributeError: if the state_id parameter is the decider state """ if state_id == UNIQUE_DECIDER_STATE_ID and force is False: raise AttributeError("You are not allowed to delete the decider state.") else: return ContainerState.remove_state(self, state_id, recursive=recursive, force=force, destroy=destroy)
def test_create_container_state(caplog): container = ContainerState("Container") assert len(container.states) == 0 input_port_container_state = container.add_input_data_port( "input", "float") output_port_container_state = container.add_output_data_port( "output", "float") scoped_var_1_container_state = container.add_scoped_variable( "scope_1", "float") scoped_var_2_container_state = container.add_scoped_variable( "scope_2", "float") state1 = ExecutionState("MyFirstState") container.add_state(state1) assert len(container.states) == 1 # As the ID of two states is identical, the add method should adapt the state_id and return the new state_id new_state_id = container.add_state( ExecutionState("test_execution_state", state_id=state1.state_id)) assert len(container.states) == 2 assert not new_state_id == state1.state_id container.remove_state(new_state_id) state2 = ExecutionState("2nd State", state_id=container.state_id) logger.debug("Old state id: {0}".format(str(state2.state_id))) new_state_id = container.add_state(state2) logger.debug("New state id: {0}".format(str(new_state_id))) assert len(container.states) == 2 input_state1 = state1.add_input_data_port("input", "float") output_state1 = state1.add_output_data_port("output", "float") input_state2 = state2.add_input_data_port("input", "float") input2_state2 = state2.add_input_data_port("input2", "float") output_state2 = state2.add_output_data_port("output", "float") assert len(container.data_flows) == 0 container.add_data_flow(state1.state_id, output_state1, state2.state_id, input_state2) assert len(container.data_flows) == 1 with raises(ValueError): # Data flow to connected input port container.add_data_flow(state1.state_id, input_state1, state2.state_id, input_state2) with raises(ValueError): # Data flow to non-existing port wrong_data_port_id = 218347 container.add_data_flow(state1.state_id, output_state1, state2.state_id, wrong_data_port_id) with raises(ValueError): # Data flow from non-existing port wrong_data_port_id = 239847 container.add_data_flow(state1.state_id, wrong_data_port_id, state2.state_id, input_state2) with raises(ValueError): # Data flow from non-existing state container.add_data_flow(-1, output_state1, state2.state_id, input_state2) with raises(ValueError): # Data flow to non-existing state container.add_data_flow(state1.state_id, output_state1, -1, input_state2) with raises(ValueError): # Connect port to itself container.add_data_flow(state1.state_id, output_state1, state1.state_id, output_state1) with raises(ValueError): # Connect two scoped variable container.add_data_flow(container.state_id, scoped_var_1_container_state, container.state_id, scoped_var_2_container_state) container.add_data_flow(container.state_id, input_port_container_state, state1.state_id, input_state1) # with raises(ValueError): # cannot connect data flow to same child state container.add_data_flow(state2.state_id, output_state2, state2.state_id, input2_state2) assert len(container.data_flows) == 3 assert len(container.transitions) == 0 container.add_transition(state1.state_id, -1, state2.state_id, None) assert len(container.transitions) == 1 container.add_transition(state1.state_id, -2, container.state_id, -2) assert len(container.transitions) == 2 t3 = container.add_transition(state2.state_id, -1, container.state_id, -1) assert len(container.transitions) == 3 with raises(ValueError): # Transition from connected outcome container.add_transition(state1.state_id, -1, state2.state_id, None) with raises(ValueError): # Non-existing from state id container.add_transition(-1, -1, state2.state_id, None) with raises(ValueError): # Non-existing from outcome container.add_transition(state1.state_id, -3, state2.state_id, None) with raises(ValueError): # Non-existing to state id container.add_transition(state1.state_id, -1, -1, None) with raises(ValueError): # Non-existing to outcome container.add_transition(state1.state_id, -1, container.state_id, -3) with raises(ValueError): # Transition pointing to the state itself container.add_transition(state1.state_id, -2, state1.state_id, None) with raises(ValueError): # to_state_id and to_outcome not None container.add_transition(state1.state_id, -2, state1.state_id, -1) with raises(ValueError): # Transition from connected outcome container.add_transition(state2.state_id, -1, state2.state_id, -2) with raises(ValueError): # Transition going from one outcome to another outcome of the same state container.add_transition(state2.state_id, -1, state2.state_id, -2) # Get connections for state related_transitions, related_data_flows = container.get_connections_for_state( state1.state_id) assert len(related_transitions['external']['outgoing']) == 2 assert len(related_data_flows['external']['ingoing']) == 1 container2 = ContainerState("Container 2") container2.add_state(container) related_transitions, related_data_flows = container2.get_connections_for_state( container.state_id) related_transitions_scoped, related_data_flows_scoped = container.get_connections_for_state_and_scoped_variables( [state2.state_id, state1.state_id], container.scoped_variables) # Test scoped connections assert (related_transitions['internal']['enclosed'] == related_transitions_scoped['enclosed']) assert (related_transitions['internal']['ingoing'] == related_transitions_scoped['ingoing']) assert (related_transitions['internal']['outgoing'] == related_transitions_scoped['outgoing']) assert (related_data_flows['internal']['enclosed'] == related_data_flows_scoped['enclosed']) assert (related_data_flows['internal']['ingoing'] == related_data_flows_scoped['ingoing']) assert (related_data_flows['internal']['outgoing'] == related_data_flows_scoped['outgoing']) with raises(AttributeError): # The removal of an undefined transition should throw an AttributeError container.remove_transition(-1) container.remove_transition(t3) assert len(container.transitions) == 2 with raises(AttributeError): # The removal of an undefined transition should throw an AttributeError container.remove_transition(t3) container.add_transition(state2.state_id, -1, container.state_id, -1) assert len(container.transitions) == 3 container.remove_state(state1.state_id) assert len(container.states) == 1 assert len(container.transitions) == 1 assert len(container.data_flows) == 1 # barrier state remove test and bug test elements for issue #346 barrier_state_id = container.add_state(BarrierConcurrencyState()) container.remove(container.states[barrier_state_id]) barrier_state_id = container.add_state(BarrierConcurrencyState()) with raises(AttributeError): container.states[barrier_state_id].remove( list(container.states[barrier_state_id].states.values())[0]) container.remove_state(barrier_state_id) ########################################### assert_logger_warnings_and_errors(caplog)
def test_port_and_outcome_removal(caplog): container = ContainerState("Container") input_container_state = container.add_input_data_port("input", "float") output_container_state = container.add_output_data_port("output", "float") scoped_variable_container_state = container.add_scoped_variable( "scope", "float") assert len(container.transitions) == 0 assert len(container.data_flows) == 0 assert len(container.outcomes) == 3 assert len(container.input_data_ports) == 1 assert len(container.output_data_ports) == 1 assert len(container.scoped_variables) == 1 state1 = ExecutionState("test_execution_state") input_state1 = state1.add_input_data_port("input", "float") output_state1 = state1.add_output_data_port("output", "float") container.add_state(state1) container.add_transition(state1.state_id, 0, container.state_id, -2) container.add_data_flow(container.state_id, input_container_state, state1.state_id, input_state1) container.add_data_flow(state1.state_id, output_state1, container.state_id, output_container_state) container.add_data_flow(container.state_id, input_container_state, container.state_id, scoped_variable_container_state) assert len(container.transitions) == 1 assert len(container.data_flows) == 3 state1.remove_outcome(0) assert len(container.transitions) == 0 state1.remove_output_data_port(output_state1) assert len(container.data_flows) == 2 state1.remove_input_data_port(input_state1) assert len(container.data_flows) == 1 container.remove_scoped_variable(scoped_variable_container_state) assert len(container.data_flows) == 0 assert_logger_warnings_and_errors(caplog)
def test_group_states(caplog): container = ContainerState("Container") input_port_container_state = container.add_input_data_port( "input", "float") container.add_output_data_port("output", "float") container.add_scoped_variable("scope_1", "float") container.add_scoped_variable("scope_2", "float") state1 = ExecutionState("MyFirstState") container.add_state(state1) new_state_id = container.add_state( ExecutionState("test_execution_state", state_id=state1.state_id)) container.remove_state(new_state_id) state2 = ExecutionState("2nd State", state_id=container.state_id) logger.debug("Old state id: {0}".format(str(state2.state_id))) new_state_id = container.add_state(state2) logger.debug("New state id: {0}".format(str(new_state_id))) input_state1 = state1.add_input_data_port("input", "float") output_state1 = state1.add_output_data_port("output", "float") input_state2 = state2.add_input_data_port("input", "float") input2_state2 = state2.add_input_data_port("input2", "float") output_state2 = state2.add_output_data_port("output", "float") container.add_data_flow(state1.state_id, output_state1, state2.state_id, input_state2) container.add_data_flow(container.state_id, input_port_container_state, state1.state_id, input_state1) container.add_data_flow(state2.state_id, output_state2, state2.state_id, input2_state2) container.add_transition(state1.state_id, -1, state2.state_id, None) container.add_transition(state1.state_id, -2, container.state_id, -2) container.add_transition(state2.state_id, -1, container.state_id, -1) group_state = container.group_states([state1.state_id, state2.state_id]) container.ungroup_state(group_state.state_id) assert_logger_warnings_and_errors(caplog)
def test_container_state(caplog): container = ContainerState("Container") input_container_state = container.add_input_data_port("input", "float") output_container_state = container.add_output_data_port("output", "float") scoped_variable_container_state = container.add_scoped_variable( "scope", "float") state1 = ExecutionState("test_execution_state") input_state1 = state1.add_input_data_port("input", "float") output_state1 = state1.add_output_data_port("output", "float") container.add_state(state1) transition_id = container.add_transition(state1.state_id, 0, container.state_id, -2) container.add_data_flow(container.state_id, input_container_state, state1.state_id, input_state1) container.add_data_flow(state1.state_id, output_state1, container.state_id, output_container_state) container.add_data_flow(container.state_id, input_container_state, container.state_id, scoped_variable_container_state) transition = container.get_transition_for_outcome(state1, state1.outcomes[0]) # Test transition from outcome assert (transition == container.transitions[transition_id]) # Test contains assert (transition in container) # Test dictionary dict_state = ContainerState.state_to_dict(container) # print(dict_state) container2, transitions, data_flows = ContainerState.from_dict(dict_state) print(container) print(container2) assert (container == copy.copy(container)) assert (container == copy.deepcopy(container)) new_state1 = ExecutionState("new_test_execution_state") old_state1_id = state1.state_id new_state = container.substitute_state(state1.state_id, new_state1) assert (old_state1_id == state1.state_id) assert (not new_state.state_id == old_state1_id) assert_logger_warnings_and_errors(caplog)
def test_conatiner_state_hash(): state1 = ContainerState('ES', state_id="12345") state2 = ContainerState('ES', state_id="12345") state1.add_output_data_port("out1", "int", data_port_id=1) state1.add_output_data_port("out2", "int", data_port_id=2) state1.add_input_data_port("in1", "int", data_port_id=3) state1.add_input_data_port("in2", "int", data_port_id=4) state1.add_outcome("o1", outcome_id=1) state1.add_outcome("o2", outcome_id=2) state2.add_outcome("o2", outcome_id=2) state2.add_outcome("o1", outcome_id=1) state2.add_input_data_port("in2", "int", data_port_id=4) state2.add_input_data_port("in1", "int", data_port_id=3) state2.add_output_data_port("out2", "int", data_port_id=2) state2.add_output_data_port("out1", "int", data_port_id=1) hash1 = hashlib.sha256() hash2 = hashlib.sha256() assert hash1.hexdigest() == hash2.hexdigest() Hashable.update_hash_from_dict(hash1, state1) Hashable.update_hash_from_dict(hash2, state2) assert hash1.hexdigest() == hash2.hexdigest()