def select_and_paste_state(gui, state_machine_model, source_state_model, target_state_model, menu_bar_ctrl, operation, main_window_controller, page): """Select a particular state and perform an operation on it (Copy or Cut) and paste it somewhere else. At the end, verify that the operation was completed successfully. :param state_machine_model: The state machine model where the operation will be conducted :param source_state_model: The state model, on which the operation will be performed :param target_state_model: The state model, where the source state will be pasted :param menu_bar_ctrl: The menu_bar controller, through which copy, cut & paste actions are triggered :param operation: String indicating the operation to be performed (Copy or Cut) :param main_window_controller: The MainWindow Controller :param page: The notebook page of the corresponding state machine in the state machines editor :return: The target state model, and the child state count before pasting """ print("\n\n %s \n\n" % source_state_model.state.name) gui(state_machine_model.selection.set, [source_state_model]) gui(getattr(menu_bar_ctrl, 'on_{}_selection_activate'.format(operation)), None, None) print("\n\n %s \n\n" % target_state_model.state.name) gui(state_machine_model.selection.set, [target_state_model]) old_child_state_count = len(target_state_model.state.states) main_window_controller.view['main_window'].grab_focus() focus_graphical_editor_in_page(page) gui(menu_bar_ctrl.on_paste_clipboard_activate, None, None) testing_utils.wait_for_gui() print(list(target_state_model.state.states.keys())) assert len(target_state_model.state.states) == old_child_state_count + 1 return target_state_model, old_child_state_count
def test_simple(caplog): """Do all copy strategies possible in RAFCON and check if all Objects have different memory location to secure reference free assignments from origin to new state. :param caplog: :return: """ testing_utils.dummy_gui(None) print("start test simple") # create testbed testing_utils.initialize_environment( gui_already_started=False, gui_config={ 'HISTORY_ENABLED': False, 'AUTO_BACKUP_ENABLED': False }, ) [state, sm_model, state_dict] = create_models() run_copy_test(sm_model) run_copy_performance_test_and_check_storage_copy(sm_model) # currently destroy doesn't do anything if auto_backup is disabled sm_model.destroy() import rafcon rafcon.core.singleton.state_machine_manager.delete_all_state_machines() [state, sm_model, state_dict] = create_models_concurrency() run_copy_test(sm_model) run_copy_performance_test_and_check_storage_copy(sm_model) # currently destroy doesn't do anything if auto_backup is disabled sm_model.destroy() rafcon.core.singleton.state_machine_manager.delete_all_state_machines() # wait until state machine model is destroyed testing_utils.wait_for_gui() testing_utils.shutdown_environment(caplog=caplog, unpatch_threading=False) print("test simple finished")
def paste(gui, state_machine_model, state_m, main_window_controller, menu_bar_ctrl, page): print("Pasting") gui(state_machine_model.selection.set, [state_m]) main_window_controller.view['main_window'].grab_focus() focus_graphical_editor_in_page(page) gui(menu_bar_ctrl.on_paste_clipboard_activate, None, None) testing_utils.wait_for_gui()
def execute_preemption_of_all_state_machines_at_once(): from rafcon.core.singleton import state_machine_execution_engine, state_machine_manager import rafcon.gui.singleton as gui_singleton menubar_ctrl = gui_singleton.main_window_controller.get_controller( 'menu_bar_controller') call_gui_callback( menubar_ctrl.on_open_activate, None, None, testing_utils.get_test_sm_path( os.path.join("unit_test_state_machines", "all_dialogs_parallel_preempted"))) testing_utils.wait_for_gui() call_gui_callback(menubar_ctrl.on_start_activate, None, None) duration_waited = 0. period = 0.1 while not state_machine_execution_engine.finished_or_stopped(): time.sleep(period) duration_waited += period if duration_waited > 3.: call_gui_callback(menubar_ctrl.on_stop_activate, None, None) raise RuntimeError( "The state machine should finish in less then {0}".format( duration_waited)) print( "Run duration of execute_preemption_of_all_state_machines_at_once was: {0}" .format(duration_waited))
def select_child_states_and_state_sequentially(sm_m, parent_state_m, logger=None): from rafcon.gui.models import ContainerStateModel import rafcon.gui.singleton main_window_controller = rafcon.gui.singleton.main_window_controller sleep_time_max = 5.0 states_editor_controller = main_window_controller.get_controller( 'states_editor_ctrl') if isinstance(parent_state_m, ContainerStateModel): for state_m in list(parent_state_m.states.values()): # get widget of state-model state_identifier = states_editor_controller.get_state_identifier( state_m) sm_m.selection.set([state_m]) [state_editor_ctrl, time_waited] = wait_for_states_editor(main_window_controller, state_identifier, sleep_time_max) testing_utils.wait_for_gui() assert state_editor_ctrl.model is state_m state_identifier = states_editor_controller.get_state_identifier( parent_state_m) parent_state_m.get_state_machine_m() print("try to select", parent_state_m) # create state editor sm_m.selection.set([parent_state_m]) [state_editor_ctrl, time_waited] = wait_for_states_editor(main_window_controller, state_identifier, sleep_time_max) assert state_editor_ctrl.model is parent_state_m
def run_copy_test(sm_m, with_gui=False): """Run general test that """ import rafcon.gui.singleton sm = sm_m.state_machine new_sm_m = copy.copy(sm_m) equal_check_state(sm_m.root_state.state, new_sm_m.root_state.state) equal_check_state_model(sm_m.root_state, new_sm_m.root_state) compare_references_to_sm_model_and_core(sm_m, new_sm_m) # storage copy tests if sm.file_system_path is None: tmp_sm_system_path = join(testing_utils.RAFCON_TEMP_PATH_TEST_BASE, 'copy_test_' + str(sm.state_machine_id)) else: tmp_sm_system_path = join(testing_utils.RAFCON_TEMP_PATH_TEST_BASE, 'copy_test' + sm.file_system_path) new_sm_m.state_machine.root_state.name = "Copied Cont state" testing_utils.wait_for_gui() new_sm_m.destroy() if with_gui: main_window_controller = rafcon.gui.singleton.main_window_controller menubar_ctrl = main_window_controller.get_controller( 'menu_bar_controller') testing_utils.call_gui_callback(sm_m.state_machine.__setattr__, "file_system_path", tmp_sm_system_path) testing_utils.call_gui_callback(menubar_ctrl.on_save_activate, None)
def test_backward_stepping_preemptive_state(gui): gui(initialize_global_variables) from rafcon.core.singleton import state_machine_execution_engine menubar_ctrl = gui.singletons.main_window_controller.menu_bar_controller state_machine = gui( menubar_ctrl.on_open_activate, None, None, testing_utils.get_test_sm_path(os.path.join("unit_test_state_machines", "backward_step_preemtive_test")) ) testing_utils.wait_for_gui() # reset the synchronization counter; although the tests run in different processes they share their memory # as the import statements are at the top of the file and not inside the parallel called functions with state_machine_execution_engine._status.execution_condition_variable: state_machine_execution_engine.synchronization_counter = 0 gui(menubar_ctrl.on_step_mode_activate, None, None) current_state_machine_id = gui.singletons.state_machine_manager.active_state_machine_id state_machines_editor_tab_status_check(current_state_machine_id, active=True) # execution start is synchronous wait_for_execution_engine_sync_counter(1, logger) # forward for i in range(3): gui(menubar_ctrl.on_step_into_activate, None, None) wait_for_execution_engine_sync_counter(2, logger) gui(menubar_ctrl.on_step_into_activate, None, None) wait_for_execution_engine_sync_counter(1, logger) # preemptive concurrency state must be finished before the next step while not state_machine.get_state_by_path("AOURYA/LXEMOO").final_outcome: time.sleep(0.010) gui(menubar_ctrl.on_step_into_activate, None, None) wait_for_execution_engine_sync_counter(1, logger) # "take turn" state reached # backward for i in range(1): gui(menubar_ctrl.on_backward_step_activate, None, None) wait_for_execution_engine_sync_counter(1, logger) for i in range(3): gui(menubar_ctrl.on_backward_step_activate, None, None) wait_for_execution_engine_sync_counter(2, logger) state_machines_editor_tab_status_check(current_state_machine_id, active=True) gui(menubar_ctrl.on_backward_step_activate, None, None) while not state_machine_execution_engine.finished_or_stopped(): time.sleep(0.1) # stop or finished are asynchronous but the call_gui_callback makes the check synchronous gui(state_machines_editor_tab_status_check, current_state_machine_id, False) gui(verify_execute_preemptive_state_forwards_backwards)
def _add_state_machine_to_manager_model(): from rafcon.gui.singleton import state_machine_manager if profiling: profiler.start("add_state_machine") state_machine_manager.add_state_machine(state_machine) testing_utils.wait_for_gui() if profiling: profiler.stop("add_state_machine")
def prepare_state_machine_model(state_machine): import rafcon.gui.singleton rafcon.gui.singleton.state_machine_manager_model.state_machine_manager.add_state_machine(state_machine) testing_utils.wait_for_gui() rafcon.gui.singleton.state_machine_manager_model.selected_state_machine_id = state_machine.state_machine_id sm_m = rafcon.gui.singleton.state_machine_manager_model.state_machines[state_machine.state_machine_id] return sm_m
def test_notification_debugging_example(gui): enable_debugging() # gui(create_bigger_state_machine) gui(create_small_state_machine) # from rafcon.gui.widget.test_storage import create_models # gui(create_models) testing_utils.wait_for_gui() gui(show_debug_graph) disable_debugging() from tests.utils import RAFCON_TEMP_PATH_TEST_BASE_ONLY_USER_SAVE assert exists(join(RAFCON_TEMP_PATH_TEST_BASE_ONLY_USER_SAVE, 'notification_output.gv')) assert exists(join(RAFCON_TEMP_PATH_TEST_BASE_ONLY_USER_SAVE, 'notification_print_out.txt'))
def test_functionality_example(caplog): """Test for now only tests: - if the state machine can be open - if test can be run and stopped - and everything can be closed again """ import rafcon.core.singleton from rafcon.core.storage import storage # The test maybe should also test if functionality are correct depicted. # TODO check if this is done in the common tests already for name in [ 'backward_step_barrier', 'backward_step_hierarchy', 'backward_step_preemption', 'decider_statemachine', 'hierarchy_abortion_handling' ]: sm_path = join(testing_utils.EXAMPLES_PATH, 'functionality_examples', name) print(sm_path) state_machine = storage.load_state_machine_from_path(sm_path) rafcon.core.singleton.state_machine_manager.add_state_machine( state_machine) testing_utils.test_multithreading_lock.acquire() try: # main_window_controller = rafcon.gui.singleton.main_window_controller for state_machine_id in list( rafcon.core.singleton.state_machine_manager.state_machines. keys()): rafcon.core.singleton.state_machine_execution_engine.start( state_machine_id) max_time = 3 current_time = 0.0 sleep_time = 0.2 while not rafcon.core.singleton.state_machine_execution_engine.finished_or_stopped( ): time.sleep(sleep_time) current_time += sleep_time if current_time >= max_time: break rafcon.core.singleton.state_machine_execution_engine.stop() rafcon.core.singleton.state_machine_execution_engine.join() finally: testing_utils.wait_for_gui( ) # to avoid execution and model notification clinches testing_utils.shutdown_environment(gui_config=False, caplog=caplog, expected_warnings=2, expected_errors=4, unpatch_threading=False)
def wait_for_states_editor(main_window_controller, tab_key, max_time=5.0): assert tab_key in main_window_controller.get_controller('states_editor_ctrl').tabs time_waited = 0.0 state_editor_ctrl = None while state_editor_ctrl is None: state_editor_ctrl = main_window_controller.get_controller('states_editor_ctrl').tabs[tab_key]['controller'] if state_editor_ctrl is not None: break last_time = time.time() testing_utils.wait_for_gui() time.sleep(0.02) time_waited += time.time() - last_time assert time_waited < max_time return state_editor_ctrl, time_waited
def execute_all_generic_libraries_with_keyboard_only(gui): menubar_ctrl = gui.singletons.main_window_controller.menu_bar_controller gui( menubar_ctrl.on_open_activate, None, None, testing_utils.get_test_sm_path( os.path.join("unit_test_state_machines", "all_generic_libraries"))) testing_utils.wait_for_gui() gui(menubar_ctrl.on_start_activate, None, None) import time from pykeyboard import PyKeyboard time.sleep(0.5) k = PyKeyboard() k.tap_key('Return', 7, 0.5) k.tap_key('Tab', 2, 0.5) k.tap_key('Return', 5, 0.5) gui(menubar_ctrl.on_stop_activate, None, None)
def trigger_issue_586_reproduction_sequence(): from os.path import join import rafcon.gui.singleton sm_manager_model = rafcon.gui.singleton.state_machine_manager_model main_window_controller = rafcon.gui.singleton.main_window_controller menubar_ctrl = main_window_controller.get_controller('menu_bar_controller') current_sm_length = len(sm_manager_model.state_machines) assert current_sm_length == 0 # backward step barrier test is chosen to work on an existing test state machine including equal child state ids call_gui_callback( menubar_ctrl.on_open_activate, None, None, join(testing_utils.TEST_ASSETS_PATH, "unit_test_state_machines", "backward_step_barrier_test")) sm_m = list(sm_manager_model.state_machines.values())[0] assert sm_m.state_machine_id == sm_manager_model.selected_state_machine_id concurrent_decimate_state_m = sm_m.get_state_model_by_path("GLSUJY/OOECFM") # check start conditions overlapping ids -> all states have four states and those have the same ids import rafcon.core.constants state_ids = list(concurrent_decimate_state_m.states.keys()) state_ids.remove(rafcon.core.constants.UNIQUE_DECIDER_STATE_ID) state_ids_set = set() for state_id in state_ids: for child_state_id in concurrent_decimate_state_m.states[ state_id].states.keys(): state_ids_set.add(child_state_id) assert len(state_ids_set) == 4 call_gui_callback(sm_m.selection.set, concurrent_decimate_state_m) call_gui_callback(menubar_ctrl.on_ungroup_state_activate, None, None) testing_utils.wait_for_gui() # ungroup all three child states which all have the same state ids as there child states plus data flows for state_id in state_ids: print("ungroup state:", state_id) assert state_id in sm_m.root_state.states child_state_m = sm_m.get_state_model_by_path("GLSUJY/" + state_id) call_gui_callback(sm_m.selection.set, child_state_m) call_gui_callback(menubar_ctrl.on_ungroup_state_activate, None, None) # store and refresh selected call_gui_callback(menubar_ctrl.on_save_as_activate, None, None, testing_utils.get_unique_temp_path()) call_gui_callback(menubar_ctrl.on_refresh_selected_activate, None, None)
def create_models(*args, **kargs): import rafcon.core.singleton import rafcon.gui.singleton from rafcon.core.states.hierarchy_state import HierarchyState from rafcon.core.state_machine import StateMachine state1 = HierarchyState('State1', state_id="State1") ctr_state = HierarchyState(name="Root", state_id="Root") ctr_state.add_state(state1) ctr_state.name = "Container" sm = StateMachine(ctr_state) # add new state machine rafcon.core.singleton.state_machine_manager.add_state_machine(sm) testing_utils.wait_for_gui() # select state machine rafcon.gui.singleton.state_machine_manager_model.selected_state_machine_id = sm.state_machine_id
def check_scrollbar_adjustment_to_be_at_bottom(): testing_utils.wait_for_gui() gui(testing_utils.wait_for_gui) # waiting for the gui is not sufficient # calling show(), show_now(), show_all(), realize() or reset_style() on the scrollbar does not work either scrolled_down = False counter = 0 while (not scrolled_down) and counter < 10: adj = logging_console_ctrl.view['scrollable'].get_vadjustment() if not int(adj.get_value()) == int(adj.get_upper() - adj.get_page_size()): testing_utils.wait_for_gui() time.sleep(0.1) else: scrolled_down = False counter += 1 if not int(adj.get_value()) == int(adj.get_upper() - adj.get_page_size()): logger.warning('The scroller seems not to be at the end of the page {0} == {1}' ''.format(int(adj.get_value()), int(adj.get_upper() - adj.get_page_size())))
def test_backward_stepping_library_state(gui): gui(initialize_global_variables) from rafcon.core.singleton import state_machine_execution_engine, state_machine_manager import rafcon.gui.singleton as gui_singleton menubar_ctrl = gui_singleton.main_window_controller.menu_bar_controller sm = gui( menubar_ctrl.on_open_activate, None, None, testing_utils.get_test_sm_path(os.path.join("unit_test_state_machines", "backward_step_library_execution_test")) ) testing_utils.wait_for_gui() # reset the synchronization counter; although the tests run in different processes they share their memory # as the import statements are at the top of the file and not inside the parallel called functions with state_machine_execution_engine._status.execution_condition_variable: state_machine_execution_engine.synchronization_counter = 0 gui(menubar_ctrl.on_step_mode_activate, None, None) current_state_machine_id = gui_singleton.state_machine_manager.active_state_machine_id state_machines_editor_tab_status_check(current_state_machine_id, active=True) # execution start is synchronous wait_for_execution_engine_sync_counter(1, logger) # forward for i in range(5): gui(menubar_ctrl.on_step_into_activate, None, None) wait_for_execution_engine_sync_counter(1, logger) # backward for i in range(4): gui(menubar_ctrl.on_backward_step_activate, None, None) wait_for_execution_engine_sync_counter(1, logger) gui(menubar_ctrl.on_backward_step_activate, None, None) while not state_machine_execution_engine.finished_or_stopped(): time.sleep(0.1) for key, sd in sm.root_state.scoped_data.items(): if sd.name == "beer_count": assert sd.value == 100 # stop or finished are asynchronous but the call_gui_callback makes the check synchronous gui(state_machines_editor_tab_status_check, current_state_machine_id, False)
def execute_all_generic_libraries_with_keyboard_only(): from rafcon.core.singleton import state_machine_execution_engine, state_machine_manager import rafcon.gui.singleton as gui_singleton menubar_ctrl = gui_singleton.main_window_controller.get_controller( 'menu_bar_controller') call_gui_callback( menubar_ctrl.on_open_activate, None, None, testing_utils.get_test_sm_path( os.path.join("unit_test_state_machines", "all_generic_libraries"))) testing_utils.wait_for_gui() call_gui_callback(menubar_ctrl.on_start_activate, None, None) import time from pykeyboard import PyKeyboard time.sleep(0.5) k = PyKeyboard() k.tap_key('Return', 7, 0.5) k.tap_key('Tab', 2, 0.5) k.tap_key('Return', 5, 0.5) call_gui_callback(menubar_ctrl.on_stop_activate, None, None)
def execute_dynamic_state_insertion(state_machine_name="dynamic_library_insertion"): from rafcon.core.singleton import state_machine_execution_engine, state_machine_manager import rafcon.gui.singleton as gui_singleton menubar_ctrl = gui_singleton.main_window_controller.get_controller('menu_bar_controller') sm = call_gui_callback( menubar_ctrl.on_open_activate, None, None, testing_utils.get_test_sm_path(os.path.join("unit_test_state_machines", state_machine_name)) ) testing_utils.wait_for_gui() # TODO check -> without call_gui_callback wait_for_gui should be without effect call_gui_callback(menubar_ctrl.on_start_activate, None, None) current_state_machine_id = gui_singleton.state_machine_manager.active_state_machine_id state_machines_editor_tab_status_check(current_state_machine_id, active=True) # execution start is synchronous testing_utils.wait_for_gui() # TODO check -> without call_gui_callback wait_for_gui should be without effect while not state_machine_execution_engine.finished_or_stopped(): time.sleep(0.1) # stop or finished are asynchronous but the call_gui_callback makes the check synchronous call_gui_callback(state_machines_editor_tab_status_check, current_state_machine_id, False)
def check_state_editor_models(sm_m, parent_state_m, logger=None): from rafcon.gui.models import ContainerStateModel import rafcon.gui.singleton main_window_controller = rafcon.gui.singleton.main_window_controller sleep_time_max = 5.0 states_editor_controller = main_window_controller.get_controller('states_editor_ctrl') if isinstance(parent_state_m, ContainerStateModel): # logger.debug("old tabs are:") # for tab in states_editor_controller.tabs.values(): # logger.debug("%s %s" % (tab['state_m'], tab['state_m'].state.get_path())) # for tab in states_editor_controller.closed_tabs.values(): # logger.debug("%s %s" % (tab['controller'].model, tab['controller'].model.state.get_path())) for state_m in list(parent_state_m.states.values()): # get widget of state-model # if not state_m.state.name == "Decider": state_identifier = states_editor_controller.get_state_identifier(state_m) # time.sleep(1) sm_m.selection.set([state_m]) [state_editor_ctrl, time_waited] = wait_for_states_editor(main_window_controller, state_identifier, sleep_time_max) # logger.debug("wait for state's state editor %s" % time_waited) # # logger.debug("models are: \n ctrl %s path: %s\n model %s path: %s" % # (state_editor_ctrl.model, state_editor_ctrl.model.state.get_path(), # state_m, state_m.state.get_path())) # # check if models of widget and in state_machine-model are the same testing_utils.wait_for_gui() assert state_editor_ctrl.model is state_m state_identifier = states_editor_controller.get_state_identifier(parent_state_m) parent_state_m.get_state_machine_m() print("try to select", parent_state_m) # create state editor sm_m.selection.set([parent_state_m]) [state_editor_ctrl, time_waited] = wait_for_states_editor(main_window_controller, state_identifier, sleep_time_max) assert state_editor_ctrl.model is parent_state_m
def create_models(): import rafcon.core.singleton import rafcon.gui.singleton sm = create_state_machine() rafcon.core.singleton.state_machine_manager.add_state_machine(sm) # give gui time to create the state machine testing_utils.wait_for_gui() for sm_in in list(rafcon.core.singleton.state_machine_manager. state_machines.values()): rafcon.core.singleton.state_machine_manager.remove_state_machine( sm_in.state_machine_id) # give the gui time to remove the state machine testing_utils.wait_for_gui() rafcon.core.singleton.state_machine_manager.add_state_machine(sm) # wait until model is created, otherwise gui will crash testing_utils.wait_for_gui() return sm
def trigger_drag_and_drop_tests(*args): # TODO test should use real SelectionData objects and motion to provide selection # -> currently very limited test scenario class StructHelper: """Used to imitate a SelectionData Class""" def __init__(self, x, y, text): self.x = x self.y = y self.text = text def set_text(self, text, length): self.text = text def get_text(self): return self.text # TODO test needs check on position -> is the state drawn where it was dropped? sm_manager_model = args[0] main_window_controller = args[1] states_machines_editor_controller = main_window_controller.get_controller( 'state_machines_editor_ctrl') library_tree_controller = main_window_controller.get_controller( 'library_controller') state_icon_controller = main_window_controller.get_controller( 'state_icon_controller') graphical_editor_controller = states_machines_editor_controller.get_child_controllers( )[0] # the view is required here; as it is created asynchronously we explicitly wait for its creation while not graphical_editor_controller.view: testing_utils.wait_for_gui() # wait for root state to be focused time.sleep(.5) call_gui_callback(library_tree_controller.view.expand_all) # generic and unit_test_state_machines in library tree index 1 is unit_test_state_machines call_gui_callback(library_tree_controller.view.get_selection().select_path, (1, 0)) selection_data = StructHelper(0, 0, None) state_machine_m = sm_manager_model.get_selected_state_machine_model() # insert state in root_state print("insert state in root_state") call_gui_callback(graphical_editor_controller.on_drag_motion, None, None, 200, 200, None) # Override selection state_m = state_machine_m.root_state call_gui_callback(state_machine_m.selection.set, [state_m]) call_gui_callback(library_tree_controller.on_drag_data_get, library_tree_controller.view, None, selection_data, 0, None) call_gui_callback(graphical_editor_controller.on_drag_data_received, None, None, 200, 200, selection_data, None, None) assert len(sm_manager_model.get_selected_state_machine_model().root_state. state.states) == 2 # insert state from IconView print("insert state from IconView") call_gui_callback(graphical_editor_controller.on_drag_motion, None, None, 300, 300, None) # Override selection state_m = state_machine_m.root_state call_gui_callback(state_machine_m.selection.set, [state_m]) call_gui_callback(state_icon_controller.on_mouse_motion, None, StructHelper(30, 15, None)) call_gui_callback(state_icon_controller.on_drag_data_get, None, None, selection_data, None, None) call_gui_callback(graphical_editor_controller.on_drag_data_received, None, None, 300, 300, selection_data, None, None) assert len(sm_manager_model.get_selected_state_machine_model().root_state. state.states) == 3 # insert state next to root state print("insert state next to root state") # Position (0, 0) in left above the root state call_gui_callback(graphical_editor_controller.on_drag_motion, None, None, 0, 0, None) call_gui_callback(state_icon_controller.on_mouse_motion, None, StructHelper(30, 15, None)) call_gui_callback(state_icon_controller.on_drag_data_get, None, None, selection_data, None, None) # insert state in state1 print("insert state in state1") state_m = state_machine_m.root_state.states['State1'] call_gui_callback(state_machine_m.selection.set, [state_m]) # Selecting a state using the drag_motion event is too unreliable, as the exact position depends on the size of # the editor. Therefore, it is now selected using the selection object directly # if isinstance(graphical_editor_controller, GraphicalEditorGaphasController): # call_gui_callback(graphical_editor_controller.on_drag_motion, None, None, 100, 100, None) # else: # call_gui_callback(graphical_editor_controller.on_drag_motion, None, None, 150, 150, None) call_gui_callback(library_tree_controller.on_drag_data_get, library_tree_controller.view, None, selection_data, 0, None) call_gui_callback(graphical_editor_controller.on_drag_data_received, None, None, 20, 20, selection_data, None, None) assert len(sm_manager_model.get_selected_state_machine_model().root_state. state.states['State1'].states) == 1
def test_drag_and_drop_test(gui): import rafcon.core.singleton gui(create_models) # TODO test should use real SelectionData objects and motion to provide selection # -> currently very limited test scenario # TODO test needs check on position -> is the state drawn where it was dropped? sm_manager_model = gui.singletons.state_machine_manager_model main_window_controller = gui.singletons.main_window_controller states_machines_editor_controller = main_window_controller.state_machines_editor_ctrl library_tree_controller = main_window_controller.library_controller state_icon_controller = main_window_controller.state_icon_controller graphical_editor_controller = states_machines_editor_controller.get_child_controllers( )[0] # the view is required here; as it is created asynchronously we explicitly wait for its creation while not graphical_editor_controller.view: testing_utils.wait_for_gui() # wait for root state to be focused time.sleep(.5) gui(library_tree_controller.view.expand_all) # generic and unit_test_state_machines in library tree index 1 is unit_test_state_machines gui(library_tree_controller.view.get_selection().select_path, (1, 0)) selection_data = StructHelper(0, 0, None) state_machine_m = sm_manager_model.get_selected_state_machine_model() # insert state in root_state print("insert state in root_state") gui(graphical_editor_controller.on_drag_motion, None, None, 200, 200, None) # Override selection state_m = state_machine_m.root_state gui(state_machine_m.selection.set, [state_m]) gui(library_tree_controller.on_drag_data_get, library_tree_controller.view, None, selection_data, 0, None) gui(graphical_editor_controller.on_drag_data_received, None, None, 200, 200, selection_data, None, None) assert len(sm_manager_model.get_selected_state_machine_model().root_state. state.states) == 2 # insert state from IconView print("insert state from IconView") gui(graphical_editor_controller.on_drag_motion, None, None, 300, 300, None) # Override selection state_m = state_machine_m.root_state gui(state_machine_m.selection.set, [state_m]) gui(state_icon_controller.on_mouse_motion, None, StructHelper(30, 15, None)) gui(state_icon_controller.on_drag_data_get, None, None, selection_data, None, None) gui(graphical_editor_controller.on_drag_data_received, None, None, 300, 300, selection_data, None, None) assert len(sm_manager_model.get_selected_state_machine_model().root_state. state.states) == 3 # insert state next to root state print("insert state next to root state") # Position (0, 0) in left above the root state gui(graphical_editor_controller.on_drag_motion, None, None, 0, 0, None) gui(state_icon_controller.on_mouse_motion, None, StructHelper(30, 15, None)) gui(state_icon_controller.on_drag_data_get, None, None, selection_data, None, None) gui.expected_warnings += 1 # insert state in state1 print("insert state in state1") state_m = state_machine_m.root_state.states['State1'] gui(state_machine_m.selection.set, [state_m]) gui(library_tree_controller.on_drag_data_get, library_tree_controller.view, None, selection_data, 0, None) gui(graphical_editor_controller.on_drag_data_received, None, None, 20, 20, selection_data, None, None) assert len(sm_manager_model.get_selected_state_machine_model().root_state. state.states['State1'].states) == 1
def trigger_menu_bar_items(gui, with_refresh=True, with_substitute_library=True): """The function triggers and test basic functions of the menu bar. At the moment those functions are tested: - New State Machine - Open State Machine - Copy State/HierarchyState -> via GraphicalEditor - Cut State/HierarchyState -> via GraphicalEditor - Paste State/HierarchyState -> via GraphicalEditor - Refresh Libraries - Refresh All - Save as - Stop State Machine - Quit GUI """ from rafcon.core.states.library_state import LibraryState import rafcon.core.singleton import rafcon.gui.singleton import rafcon.gui.helpers.state as gui_helper_state import rafcon.gui.helpers.state_machine as gui_helper_state_machine from rafcon.gui.controllers.library_tree import LibraryTreeController from rafcon.core.states.barrier_concurrency_state import UNIQUE_DECIDER_STATE_ID from rafcon.core.states.state import StateType sm_manager_model = rafcon.gui.singleton.state_machine_manager_model main_window_controller = rafcon.gui.singleton.main_window_controller menubar_ctrl = main_window_controller.menu_bar_controller lib_tree_ctrl = main_window_controller.library_controller state_machines_ctrl = main_window_controller.state_machines_editor_ctrl assert isinstance(lib_tree_ctrl, LibraryTreeController) state_machine = create_state_machine() first_sm_id = state_machine.state_machine_id gui(rafcon.core.singleton.state_machine_manager.add_state_machine, state_machine) current_sm_length = len(sm_manager_model.state_machines) gui(menubar_ctrl.on_new_activate, None) # test decider state removal of barrier state sm_m = sm_manager_model.state_machines[first_sm_id + 1] page = state_machines_ctrl.get_page_for_state_machine_id(sm_m.state_machine_id) # Tests for issue #712 # Copy an InputDataPort from a root state to an ExecutionState already having an InputDataPort gui(sm_m.selection.set, [sm_m.root_state]) gui(gui_helper_state_machine.add_new_state, sm_m, StateType.EXECUTION) execution_state_m = list(sm_m.root_state.states.values())[0] gui(sm_m.root_state.state.add_input_data_port, "i1", int, data_port_id=0) gui(execution_state_m.state.add_input_data_port, "i1", int, data_port_id=0) root_input_port_m = sm_m.root_state.get_input_data_port_m(0) copy_port(gui, sm_m, root_input_port_m, menubar_ctrl) paste(gui, sm_m, execution_state_m, main_window_controller, menubar_ctrl, page) gui(sm_m.selection.set, execution_state_m) gui(menubar_ctrl.on_delete_activate, None, None) # TODO check why I have had to move this test above the bug tests below?! # Create BarrierConcurrencyState and try to delete DeciderState (should fail with exception) gui(sm_m.selection.set, [sm_m.root_state]) gui(gui_helper_state_machine.add_new_state, sm_m, StateType.BARRIER_CONCURRENCY) barrier_state_m = list(sm_m.root_state.states.values())[0] decider_state_path = "/".join([barrier_state_m.state.get_path(), UNIQUE_DECIDER_STATE_ID]) gui(sm_m.selection.set, sm_m.get_state_model_by_path(decider_state_path)) gui(menubar_ctrl.on_delete_activate, None, None) gui(sm_m.root_state.state.remove_state, barrier_state_m.state.state_id) # Tests for issue #717 and #726 # create self transition and self data flow and perform state type change and substitute state gui(sm_m.selection.set, [sm_m.root_state]) gui(gui_helper_state_machine.add_new_state, sm_m, StateType.EXECUTION) execution_state_m = list(sm_m.root_state.states.values())[0] new_state_id = execution_state_m.state.state_id idp_id = gui(execution_state_m.state.add_input_data_port, "i1", int, data_port_id=0) odp_id = gui(execution_state_m.state.add_output_data_port, "o1", int, data_port_id=1) # add self transition and self data flow gui(execution_state_m.parent.state.add_transition, new_state_id, 0, new_state_id, None) gui(execution_state_m.parent.state.add_data_flow, new_state_id, odp_id, new_state_id, idp_id) gui(sm_m.selection.set, execution_state_m) # test issue #717 from tests.gui.widget.test_state_type_change import get_state_editor_ctrl_and_store_id_dict from rafcon.core.states.hierarchy_state import HierarchyState [state_editor_ctrl, list_store_id_from_state_type_dict] = gui(get_state_editor_ctrl_and_store_id_dict, sm_m, execution_state_m, main_window_controller, 5., logger) state_type_row_id = list_store_id_from_state_type_dict[HierarchyState.__name__] gui(state_editor_ctrl.get_controller('properties_ctrl').view['type_combobox'].set_active, state_type_row_id) new_state = sm_m.root_state.states[new_state_id] assert len(new_state.parent.transitions) == 1 and len(new_state.parent.data_flows) == 1 # test issue #726 hierarchy_state_m = sm_m.root_state.states[new_state_id] gui(hierarchy_state_m.outcomes[0].__setattr__, "name", "end") # rename to let the transition survive gui(sm_m.selection.set, hierarchy_state_m) library_path, library_name = ('generic', 'wait') gui(lib_tree_ctrl.select_library_tree_element_of_lib_tree_path, join(library_path, library_name)) gui(lib_tree_ctrl.substitute_as_library_clicked, None, True) assert len(sm_m.root_state.states) == 1 wait_state_m = list(sm_m.root_state.states.values())[0] assert len(new_state.parent.transitions) == 1 t_m = list(new_state.parent.transitions)[0] assert t_m.transition.from_state == t_m.transition.to_state and \ t_m.transition.from_state == wait_state_m.state.state_id gui(sm_m.root_state.state.remove_state, wait_state_m.state.state_id) first_sm_id += 1 # count state machine id once up because of library substitution (loads a state machine, too) assert len(sm_manager_model.state_machines) == current_sm_length + 1 gui(menubar_ctrl.on_open_activate, None, None, join(testing_utils.TUTORIAL_PATH, "basic_turtle_demo_sm")) gui(testing_utils.wait_for_gui) assert len(sm_manager_model.state_machines) == current_sm_length + 2 sm_m = sm_manager_model.state_machines[first_sm_id + 2] testing_utils.wait_for_gui() # MAIN_WINDOW NEEDS TO BE FOCUSED (for global input focus) TO OPERATE PASTE IN GRAPHICAL VIEWER main_window_controller.view['main_window'].grab_focus() gui(sm_manager_model.__setattr__, "selected_state_machine_id", first_sm_id + 2) page_id = state_machines_ctrl.get_page_num(first_sm_id + 2) page = state_machines_ctrl.view.notebook.get_nth_page(page_id) gui(focus_graphical_editor_in_page, page) # TODO keep core interface, too # ########################################################## # # group states # # TODO improve test to related data flows # state_m_parent = sm_m.get_state_model_by_path('CDMJPK/RMKGEW/KYENSZ') # state_ids_old = [state_id for state_id in state_m_parent.state.states] # gui(state_m_parent.state.group_states, ['PAYECU', 'UEPNNW', 'KQDJYS']) # # ########################################################## # # ungroup new state # state_new = None # for state_id in state_m_parent.state.states: # if state_id not in state_ids_old: # state_new = state_m_parent.state.states[state_id] # gui(state_m_parent.state.ungroup_state, state_new.state_id) ########################################################## # group states # TODO improve test to related data flows print("#" * 30, "\n", '#### group states \n', "#" * 30, "\n") state_m_parent = sm_m.get_state_model_by_path('CDMJPK/RMKGEW/KYENSZ') state_ids_old = [state_id for state_id in state_m_parent.state.states] state_m_list = [state_m_parent.states[child_state_id] for child_state_id in ['PAYECU', 'UEPNNW', 'KQDJYS']] gui(gui_helper_state.group_states_and_scoped_variables, state_m_list, []) ########################################################## # ungroup new state print("#" * 30, "\n", '#### ungroup state \n', "#" * 30, "\n") new_state = None for state_id in state_m_parent.state.states: if state_id not in state_ids_old: new_state = state_m_parent.state.states[state_id] gui(gui_helper_state.ungroup_state, sm_m.get_state_model_by_path(new_state.get_path())) ######################################################### print("select & copy an execution state -> and paste it somewhere") select_and_paste_state(gui, sm_m, sm_m.get_state_model_by_path('CDMJPK/RMKGEW/KYENSZ'), sm_m.get_state_model_by_path( 'CDMJPK/RMKGEW'), menubar_ctrl, 'copy', main_window_controller, page) ########################################################### print("select & copy a hierarchy state -> and paste it some where") select_and_paste_state(gui, sm_m, sm_m.get_state_model_by_path('CDMJPK/RMKGEW/KYENSZ/VCWTIY'), sm_m.get_state_model_by_path('CDMJPK'), menubar_ctrl, 'copy', main_window_controller, page) ########################################################## print("select a library state -> and paste it some where WITH CUT !!!") state_m, old_child_state_count = select_and_paste_state(gui, sm_m, sm_m.get_state_model_by_path('CDMJPK/RMKGEW/KYENSZ/VCWTIY'), sm_m.get_state_model_by_path('CDMJPK'), menubar_ctrl, 'cut', main_window_controller, page) ########################################################## # create complex state with all elements gui(sm_m.selection.set, [sm_m.get_state_model_by_path('CDMJPK'), ]) lib_state = LibraryState(join("generic", "dialog"), "Dialog [3 options]", "0.1", "Dialog [3 options]") gui(gui_helper_state_machine.insert_state_into_selected_state, lib_state, True) assert len(state_m.state.states) == old_child_state_count + 2 state = None for state in state_m.state.states.values(): if state.name == "Dialog [3 options]": break assert state is not None new_template_state = state gui(new_template_state.add_scoped_variable, 'scoopy', float, 0.3) state_m_to_copy = sm_m.get_state_model_by_path('CDMJPK/' + new_template_state.state_id) ########################################################## print("copy & paste complex state into itself") copy_and_paste_state_into_itself(gui, sm_m, state_m_to_copy, page, menubar_ctrl) print("increase complexity by doing it twice -> increase the hierarchy-level") copy_and_paste_state_into_itself(gui, sm_m, state_m_to_copy, page, menubar_ctrl) ########################################################## # substitute state with template old_keys = list(state_m_parent.state.states.keys()) transitions_before, data_flows_before = state_m_parent.state.get_connections_for_state('RQXPAI') # lib_state = gui(rafcon.gui.singleton.library_manager.get_library_instance, 'generic', 'wait') # CORE LEVEL VERSION OF A SUBSTITUTE STATE EXAMPLE # gui(state_m_parent.state.substitute_state, 'RQXPAI', lib_state.state_copy) # SAME WITH THE GUI AND HELPER METHOD # gui(gui_helper_state.substitute_state_as, state_m_parent.states['RQXPAI'], lib_state, True) # GUI LEVEL SUBSTITUTE STATE EXAMPLE WITH CORRECT META DATA HANDLING TODO why those above produce wrong meta data? gui(sm_m.selection.set, [state_m_parent.states['RQXPAI'], ]) library_path, library_name = ('generic', 'wait') gui(lib_tree_ctrl.select_library_tree_element_of_lib_tree_path, join(library_path, library_name)) gui(lib_tree_ctrl.substitute_as_template_clicked, None, True) new_state_id = None for state_id in state_m_parent.state.states.keys(): if state_id not in old_keys: new_state_id = state_id transitions_after, data_flows_after = state_m_parent.state.get_connections_for_state(new_state_id) # transition is not preserved because of unequal outcome naming assert len(transitions_before['external']['ingoing']) == 1 assert len(transitions_after['external']['ingoing']) == 1 assert len(transitions_before['external']['outgoing']) == 1 assert len(transitions_after['external']['outgoing']) == 0 gui(state_m_parent.state.add_transition, new_state_id, 0, 'MCOLIQ', None) print("XXX1") # modify the template with other data type and respective data flows to parent gui(list(state_m_parent.states[new_state_id].state.input_data_ports.items())[0][1].__setattr__, "data_type", "int") gui(state_m_parent.state.add_input_data_port, 'in_time', "int") gui(state_m_parent.state.add_data_flow, state_m_parent.state.state_id, list(state_m_parent.state.input_data_ports.items())[0][1].data_port_id, new_state_id, list(state_m_parent.states[new_state_id].state.input_data_ports.items())[0][1].data_port_id) ########################################################## # substitute state with library old_keys = list(state_m_parent.state.states.keys()) transitions_before, data_flows_before = state_m_parent.state.get_connections_for_state(new_state_id) # lib_state = gui(rafcon.gui.singleton.library_manager.get_library_instance, 'generic', 'wait') # CORE LEVEL VERSION OF A SUBSTITUTE STATE EXAMPLE # gui(state_m_parent.state.substitute_state, new_state_id, lib_state) # SAME WITH THE GUI AND HELPER METHOD # gui(gui_helper_state.substitute_state_as, state_m_parent.states[new_state_id], lib_state, False) # GUI LEVEL SUBSTITUTE STATE EXAMPLE WITH CORRECT META DATA HANDLING TODO why those above produce wrong meta data? gui(sm_m.selection.set, [state_m_parent.states[new_state_id], ]) library_path, library_name = ('generic', 'wait') gui(lib_tree_ctrl.select_library_tree_element_of_lib_tree_path, join(library_path, library_name)) gui(lib_tree_ctrl.substitute_as_library_clicked, None, True) new_state_id = None for state_id in list(state_m_parent.state.states.keys()): if state_id not in old_keys: new_state_id = state_id transitions_after, data_flows_after = state_m_parent.state.get_connections_for_state(new_state_id) # test if data flow is ignored assert len(transitions_before['external']['ingoing']) == 1 assert len(transitions_after['external']['ingoing']) == 1 assert len(transitions_before['external']['outgoing']) == 1 assert len(transitions_after['external']['outgoing']) == 1 assert len(data_flows_before['external']['ingoing']) == 1 assert len(data_flows_after['external']['ingoing']) == 0 # data flow is preserved if right data type and name is used gui(list(state_m_parent.state.input_data_ports.items())[0][1].__setattr__, "data_type", "float") if isinstance(state_m_parent.state.states[new_state_id], LibraryState): data_port_id = list(state_m_parent.state.states[new_state_id].input_data_ports.items())[0][0] state_m_parent.state.states[new_state_id].use_runtime_value_input_data_ports[data_port_id] = True state_m_parent.state.states[new_state_id].input_data_port_runtime_values[data_port_id] = 2.0 print() else: raise # state_m_parent.state.states[new_state_id].input_data_ports.items()[0][1].default_value = 2.0 gui(state_m_parent.state.add_data_flow, state_m_parent.state.state_id, list(state_m_parent.state.input_data_ports.items())[0][1].data_port_id, new_state_id, list(state_m_parent.states[new_state_id].state.input_data_ports.items())[0][1].data_port_id) old_keys = list(state_m_parent.state.states.keys()) transitions_before, data_flows_before = state_m_parent.state.get_connections_for_state(new_state_id) # CORE LEVEL VERSION OF A SUBSTITUTE STATE EXAMPLE # lib_state = rafcon.gui.singleton.library_manager.get_library_instance('generic', 'wait') # gui(state_m_parent.state.substitute_state, new_state_id, lib_state.state_copy) # GUI LEVEL SUBSTITUTE STATE EXAMPLE WITH CORRECT META DATA HANDLING TODO why those above produce wrong meta data? gui(sm_m.selection.set, [state_m_parent.states[new_state_id], ]) library_path, library_name = ('generic', 'wait') gui(lib_tree_ctrl.select_library_tree_element_of_lib_tree_path, join(library_path, library_name)) gui(lib_tree_ctrl.substitute_as_template_clicked, None, True) new_state_id = None for state_id in list(state_m_parent.state.states.keys()): if state_id not in old_keys: new_state_id = state_id transitions_after, data_flows_after = state_m_parent.state.get_connections_for_state(new_state_id) # test if data flow is ignored assert len(transitions_before['external']['ingoing']) == 1 assert len(transitions_after['external']['ingoing']) == 1 assert len(transitions_before['external']['outgoing']) == 1 assert len(transitions_after['external']['outgoing']) == 1 assert len(data_flows_before['external']['ingoing']) == 1 assert len(data_flows_after['external']['ingoing']) == 1 assert list(state_m_parent.state.states[new_state_id].input_data_ports.items())[0][1].default_value == 2.0 ########################################################## # open separately gui(sm_m.selection.set, [sm_m.get_state_model_by_path('CDMJPK'), ]) lib_state = LibraryState(join("generic", "dialog"), "Dialog [3 options]", "0.1", "Dialog [3 options]") gui(gui_helper_state_machine.insert_state_into_selected_state, lib_state, False) lib_hash = lib_state.state_copy.mutable_hash() # assert lib_state.mutable_hash().hexdigest() == lib_hash.hexdigest() sm_m = sm_manager_model.state_machines[lib_state.get_state_machine().state_machine_id] gui(sm_m.selection.set, [sm_m.get_state_model_by_path(lib_state.get_path())]) gui(gui_helper_state_machine.open_library_state_separately) sm_m = sm_manager_model.get_selected_state_machine_model() assert sm_m.root_state.state.mutable_hash().hexdigest() == lib_hash.hexdigest() ########################################################## if with_substitute_library: ########################################################## # check substitute library state as template -> keep name old_parent = lib_state.parent state_ids = list(old_parent.states.keys()) gui(lib_state.__setattr__, 'name', 'DIALOG_X') gui(sm_manager_model.__setattr__, 'selected_state_machine_id', lib_state.get_state_machine().state_machine_id) gui(gui_helper_state_machine.substitute_selected_library_state_with_template, True) # keep_name=True new_states = [state for state in list(old_parent.states.values()) if state.state_id not in state_ids] assert new_states and len(new_states) == 1 and new_states[0].name == 'DIALOG_X' ########################################################## if with_refresh: gui(menubar_ctrl.on_refresh_libraries_activate) gui(testing_utils.wait_for_gui) gui(menubar_ctrl.on_refresh_all_activate, None, None, True) gui(testing_utils.wait_for_gui) assert len(sm_manager_model.state_machines) == 2 gui.expected_errors = 1
def trigger_gui_signals_first_run(gui, open_state_machines): """The function triggers the creation of different state machines that should be backup-ed. In another run those are restored and checked onto correctness. At the moment TESTED, SHOULD or are THOUGHT about to generate the following state machines: - TESTED new state machine without storage - TESTED new state machine with storage and no changes - TESTED new state machine with storage and changes - TESTED state machine loaded and no changes - TESTED state machine loaded and changes - TESTED library not changed - TESTED library changed - TESTED change tab position - SHOULD not stored state machine that was removed/moved before restart - SHOULD stored state machine and no changes that was removed/moved before restart - SHOULD stored state machine and no changes that was removed/moved before restart """ import rafcon.gui.singleton from rafcon.core.states.hierarchy_state import HierarchyState from rafcon.gui.controllers.main_window import MenuBarController from rafcon.gui.models.state_machine_manager import StateMachineManagerModel from tests.gui.widget.test_state_type_change import get_state_editor_ctrl_and_store_id_dict testing_utils.wait_for_gui() main_window_controller = rafcon.gui.singleton.main_window_controller sm_manager_model = rafcon.gui.singleton.state_machine_manager_model library_manager = rafcon.gui.singleton.library_manager menubar_ctrl = main_window_controller.get_controller('menu_bar_controller') assert isinstance(menubar_ctrl, MenuBarController) assert isinstance(sm_manager_model, StateMachineManagerModel) def add_two_states_to_root_state_of_selected_state_machine(): sm_m = sm_manager_model.get_selected_state_machine_model() current_number_states = len(sm_m.root_state.states) call_gui_callback(sm_m.selection.set, sm_m.root_state) call_gui_callback(menubar_ctrl.on_add_state_activate, None) call_gui_callback(menubar_ctrl.on_add_state_activate, None) assert len(sm_m.root_state.states) == current_number_states + 2 assert sm_manager_model.get_selected_state_machine_model( ).state_machine.marked_dirty #################### # POSITIVE EXAMPLES -> supposed to be added to the open tabs list #################### # new state machine without storage state_machine = create_state_machine() gui(sm_manager_model.state_machine_manager.add_state_machine, state_machine) gui(testing_utils.wait_for_gui) print(sm_manager_model.state_machines.keys()) current_sm_id = list(sm_manager_model.state_machines.keys())[0] current_number_of_sm = len(sm_manager_model.state_machines) # new state machine with storage and no changes current_number_of_sm += 1 current_sm_id += 1 gui(menubar_ctrl.on_new_activate, None) gui(sm_manager_model.__setattr__, 'selected_state_machine_id', current_sm_id) assert len(sm_manager_model.state_machines) == current_number_of_sm gui(menubar_ctrl.on_save_as_activate, None, None, testing_utils.get_unique_temp_path()) # new state machine with storage and with changes current_number_of_sm += 1 current_sm_id += 1 gui(menubar_ctrl.on_new_activate, None) gui(sm_manager_model.__setattr__, 'selected_state_machine_id', current_sm_id) assert len(sm_manager_model.state_machines) == current_number_of_sm gui(menubar_ctrl.on_save_as_activate, None, None, testing_utils.get_unique_temp_path()) add_two_states_to_root_state_of_selected_state_machine() # state machine loaded and no changes current_number_of_sm += 1 current_sm_id += 1 basic_turtle_sm_path = join(testing_utils.TUTORIAL_PATH, "basic_turtle_demo_sm") gui(menubar_ctrl.on_open_activate, None, None, basic_turtle_sm_path) gui(sm_manager_model.__setattr__, 'selected_state_machine_id', current_sm_id) move_this_sm_id = sm_manager_model.selected_state_machine_id assert len(sm_manager_model.state_machines) == current_number_of_sm # state machine loaded and changes current_number_of_sm += 1 current_sm_id += 1 print("BUGS") basic_turtle_sm_path = join(testing_utils.TUTORIAL_PATH, "99_bugs") gui(menubar_ctrl.on_open_activate, None, None, basic_turtle_sm_path) gui(testing_utils.wait_for_gui) assert len(sm_manager_model.state_machines) == current_number_of_sm assert sm_manager_model.get_selected_state_machine_model( ).state_machine.file_system_path == basic_turtle_sm_path add_two_states_to_root_state_of_selected_state_machine() # library not changed (needs state machine that has meta data already -> that should not be changed by opening) print("LIB no changes") library_os_path = library_manager.get_os_path_to_library( "turtle_libraries", "clear_field")[0] gui(menubar_ctrl.on_open_activate, None, None, library_os_path) gui(testing_utils.wait_for_gui) # use artificial marked dirty to check for recovery of the flag assert not sm_manager_model.get_selected_state_machine_model( ).state_machine.marked_dirty sm_manager_model.get_selected_state_machine_model( ).state_machine._marked_dirty = True assert sm_manager_model.get_selected_state_machine_model( ).state_machine.marked_dirty # library with changes print("LIB with changes") library_os_path = library_manager.get_os_path_to_library( "turtle_libraries", "teleport_turtle")[0] gui(menubar_ctrl.on_open_activate, None, None, library_os_path) gui(testing_utils.wait_for_gui) lib_sm_m = sm_manager_model.get_selected_state_machine_model() def do_type_change(): [state_editor_ctrl, list_store_id_from_state_type_dict] = \ get_state_editor_ctrl_and_store_id_dict(lib_sm_m, lib_sm_m.root_state, main_window_controller, 5., logger) # - do state type change state_type_row_id = list_store_id_from_state_type_dict[ HierarchyState.__name__] state_editor_ctrl.get_controller('properties_ctrl').view[ 'type_combobox'].set_active(state_type_row_id) gui(lib_sm_m.selection.set, [lib_sm_m.root_state]) print(lib_sm_m.root_state) gui(do_type_change) print(lib_sm_m.root_state) add_two_states_to_root_state_of_selected_state_machine() print(lib_sm_m.root_state) # change tab position state_machines_editor_ctrl = main_window_controller.get_controller( 'state_machines_editor_ctrl') gui(state_machines_editor_ctrl.rearrange_state_machines, {move_this_sm_id: 0}) # defined selection sm_m = sm_manager_model.state_machines[move_this_sm_id] gui(sm_manager_model.__setattr__, 'selected_state_machine_id', move_this_sm_id) gui(sm_m.selection.set, list(sm_m.root_state.states.values())[0]) print("last state machine:", sm_m.state_machine.file_system_path) #################### # NEGATIVE EXAMPLES -> supposed to not been added to the recently opened state machines list #################### # state machine that was removed/moved before restart -> result in second run #################### # collect open state machine data #################### gui(prepare_tab_data_of_open_state_machines, main_window_controller, sm_manager_model, open_state_machines) #################### # shout down gui #################### gui(menubar_ctrl.on_stop_activate, None) # TODO why this is some how important for correct restore
def test_backward_stepping_barrier_state(gui): gui(initialize_global_variables) from rafcon.core.singleton import state_machine_execution_engine, state_machine_manager import rafcon.gui.singleton as gui_singleton menubar_ctrl = gui_singleton.main_window_controller.get_controller('menu_bar_controller') sm = gui( menubar_ctrl.on_open_activate, None, None, testing_utils.get_test_sm_path(os.path.join("unit_test_state_machines", "backward_step_barrier_test")) ) testing_utils.wait_for_gui() # reset the synchronization counter; although the tests run in different processes they share their memory # as the import statements are at the top of the file and not inside the parallel called functions with state_machine_execution_engine._status.execution_condition_variable: state_machine_execution_engine.synchronization_counter = 0 gui(menubar_ctrl.on_step_mode_activate, sm.state_machine_id, None) wait_for_execution_engine_sync_counter(1, logger) for i in range(2): gui(menubar_ctrl.on_step_into_activate, None, None) wait_for_execution_engine_sync_counter(3, logger) gui(menubar_ctrl.on_step_over_activate, None, None) wait_for_execution_engine_sync_counter(3, logger) gui(menubar_ctrl.on_step_out_activate, None, None) wait_for_execution_engine_sync_counter(1, logger) for i in range(3): gui(menubar_ctrl.on_step_into_activate, None, None) wait_for_execution_engine_sync_counter(1, logger) # backward for i in range(3): gui(menubar_ctrl.on_backward_step_activate, None, None) wait_for_execution_engine_sync_counter(1, logger) print("cp1") for i in range(4): gui(menubar_ctrl.on_backward_step_activate, None, None) wait_for_execution_engine_sync_counter(3, logger) print("cp2") gui(menubar_ctrl.on_backward_step_activate, None, None) print("cp3") while not state_machine_execution_engine.finished_or_stopped(): time.sleep(0.1) print("cp4") testing_utils.wait_for_gui() print("cp5") for key, sd in sm.root_state.scoped_data.items(): if sd.name == "beer_number": assert sd.value == 100 elif sd.name == "wine_number": assert sd.value == 40 elif sd.name == "whiskey_number": assert sd.value == 20 gui.expected_warnings = 3 gui(menubar_ctrl.on_stop_activate, None)
def start_client(interacting_function, queue_dict): from rafcon.gui.config import global_gui_config import os from rafcon.utils.i18n import setup_l10n setup_l10n() from rafcon.gui.controllers.main_window import MainWindowController from rafcon.gui.views.main_window import MainWindowView import rafcon.gui.singleton as gui_singletons from rafcon.gui.runtime_config import global_runtime_config from rafcon.gui.start import signal_handler import rafcon from rafcon.utils import log from rafcon.utils import plugins from rafcon.core.config import global_config from rafcon.core.storage import storage as global_storage from rafcon.core.state_machine import StateMachine from rafcon.core.states.hierarchy_state import HierarchyState import rafcon.core.singleton as core_singletons from rafcon.core.start import setup_environment # load all plugins specified in the RAFCON_PLUGIN_PATH plugins.load_plugins() from tests import utils as testing_utils # check if twisted is imported if "twisted" in sys.modules: from twisted.internet import gtk3reactor # needed for GLib.idle_add, and signals gtk3reactor.install() from twisted.internet import reactor else: print("Twisted not imported! Thus the gkt2reatcor is not installed!") exit() plugins.run_pre_inits() setup_logger() logger = log.get_logger("start") logger.info("RAFCON launcher") setup_environment() signal.signal(signal.SIGINT, signal_handler) global_config.load(path=os.path.dirname(os.path.abspath(__file__))) global_gui_config.load(path=os.path.dirname(os.path.abspath(__file__))) global_runtime_config.load(path=os.path.dirname(os.path.abspath(__file__))) setup_config = dict() setup_config["net_config_path"] = os.path.abspath(path=os.path.join(os.path.dirname(os.path.abspath(__file__)), "client")) # Initialize library core_singletons.library_manager.initialize() # Create the GUI main_window_view = MainWindowView() state_machine = global_storage.load_state_machine_from_path( testing_utils.get_test_sm_path(os.path.join("unit_test_state_machines", "99_bottles_of_beer_monitoring"))) sm_id = rafcon.core.singleton.state_machine_manager.add_state_machine(state_machine) # the active_state_machine_id must be set here, as the state machine can be active (e.g. if the server started the sm already) # although it is not yet started on the client rafcon.core.singleton.state_machine_manager.active_state_machine_id = sm_id sm_manager_model = gui_singletons.state_machine_manager_model main_window_controller = MainWindowController(sm_manager_model, main_window_view) plugins.run_post_inits(setup_config) import threading # this is not recognized by pycharm as the module is loaded in plugins.load_plugins() from monitoring.monitoring_manager import global_monitoring_manager interacting_thread = threading.Thread(target=interacting_function, args=[main_window_controller, global_monitoring_manager, queue_dict, sm_id]) testing_utils.wait_for_gui() interacting_thread.start() # check if twisted is imported if "twisted" in sys.modules: reactor.run() else: logger.error("Client: Twisted is not in sys.modules or twisted is not working! Exiting program ... !") os._exit(0) logger.info("Joined root state") # If there is a running state-machine, wait for it to be finished before exiting sm = core_singletons.state_machine_manager.get_active_state_machine() if sm: sm.root_state.join() logger.info("Exiting ...") # this is a ugly process shutdown method but works if gtk or twisted process are still blocking os._exit(0)
def create_models(): import rafcon.core.singleton from rafcon.core.states.execution_state import ExecutionState from rafcon.core.states.hierarchy_state import HierarchyState from rafcon.core.state_machine import StateMachine state1 = ExecutionState('State1') output_state1 = state1.add_output_data_port("output", "int") input_state1 = state1.add_input_data_port("input", "str", "zero") state2 = ExecutionState('State2') input_par_state2 = state2.add_input_data_port("par", "int", 0) output_res_state2 = state2.add_output_data_port("res", "int") state4 = HierarchyState(name='Nested') state4.add_outcome('GoGo') output_state4 = state4.add_output_data_port("out", "int") state5 = ExecutionState('Nested2') state5.add_outcome('HereWeGo') input_state5 = state5.add_input_data_port("in", "int", 0) state3 = HierarchyState(name='State3') input_state3 = state3.add_input_data_port("input", "int", 0) output_state3 = state3.add_output_data_port("output", "int") state3.add_state(state4) state3.add_state(state5) state3.set_start_state(state4) state3.add_scoped_variable("share", "int", 3) state3.add_transition(state4.state_id, 0, state5.state_id, None) state3.add_transition(state5.state_id, 0, state3.state_id, 0) state3.add_data_flow(state4.state_id, output_state4, state5.state_id, input_state5) state3.add_outcome('Branch1') state3.add_outcome('Branch2') ctr_state = HierarchyState(name="Container") ctr_state.add_state(state1) ctr_state.add_state(state2) ctr_state.add_state(state3) input_ctr_state = ctr_state.add_input_data_port("ctr_in", "str", "zero") output_ctr_state = ctr_state.add_output_data_port("ctr_out", "int") ctr_state.set_start_state(state1) ctr_state.add_transition(state1.state_id, 0, state2.state_id, None) ctr_state.add_transition(state2.state_id, 0, state3.state_id, None) ctr_state.add_transition(state3.state_id, 0, ctr_state.state_id, 0) ctr_state.add_data_flow(state1.state_id, output_state1, state2.state_id, input_par_state2) ctr_state.add_data_flow(state2.state_id, output_res_state2, state3.state_id, input_state3) ctr_state.add_data_flow(ctr_state.state_id, input_ctr_state, state1.state_id, input_state1) ctr_state.add_data_flow(state3.state_id, output_state3, ctr_state.state_id, output_ctr_state) ctr_state.add_input_data_port("input", "str", "default_value1") ctr_state.add_input_data_port("pos_x", "str", "default_value2") ctr_state.add_input_data_port("pos_y", "str", "default_value3") ctr_state.add_output_data_port("output", "str", "default_value1") ctr_state.add_output_data_port("result", "str", "default_value2") scoped_variable1_ctr_state = ctr_state.add_scoped_variable( "scoped", "str", "default_value1") scoped_variable2_ctr_state = ctr_state.add_scoped_variable( "my_var", "str", "default_value1") scoped_variable3_ctr_state = ctr_state.add_scoped_variable( "ctr", "int", 42) ctr_state.add_data_flow(ctr_state.state_id, input_ctr_state, ctr_state.state_id, scoped_variable1_ctr_state) ctr_state.add_data_flow(state1.state_id, output_state1, ctr_state.state_id, scoped_variable3_ctr_state) state_dict = { 'Container': ctr_state, 'State1': state1, 'State2': state2, 'State3': state3, 'Nested': state4, 'Nested2': state5 } sm = StateMachine(ctr_state) rafcon.core.singleton.state_machine_manager.add_state_machine(sm) testing_utils.wait_for_gui() state_machine_model = rafcon.gui.singleton.state_machine_manager_model.state_machines[ sm.state_machine_id] return ctr_state, state_machine_model, state_dict