def test_parse_names_with_hyphens(): proclang = ''' main: 1. PRIMARY: set A-200 to open 2. PRIMARY: set vent-valve to closed 3. BOB-THE-BUILDER: set K-5-B to open 4. CONTROL: set C-AB-2 to closed 5. OPS: set A-200 to semi-closed ''' suite = top.proclang.parse(proclang) expected_suite = top.ProcedureSuite([ top.Procedure('main', [ top.ProcedureStep('1', top.StateChangeAction('A-200', 'open'), [ (top.Immediate(), top.Transition('main', '2')) ], 'PRIMARY'), top.ProcedureStep( '2', top.StateChangeAction('vent-valve', 'closed'), [(top.Immediate(), top.Transition('main', '3'))], 'PRIMARY'), top.ProcedureStep('3', top.StateChangeAction('K-5-B', 'open'), [ (top.Immediate(), top.Transition('main', '4')) ], 'BOB-THE-BUILDER'), top.ProcedureStep('4', top.StateChangeAction('C-AB-2', 'closed'), [ (top.Immediate(), top.Transition('main', '5')) ], 'CONTROL'), top.ProcedureStep('5', top.StateChangeAction( 'A-200', 'semi-closed'), [], 'OPS') ]) ]) assert suite == expected_suite
def test_jump_to_step_normal(): plumb_b = PlumbingBridge() control_b = ControlsBridge(plumb_b) proc_b = ProceduresBridge(plumb_b, control_b) procedure = top.Procedure('main', [ top.ProcedureStep('1', top.StateChangeAction('injector_valve', 'open'), [(top.Immediate(), top.Transition('main', '2'))], 'PRIMARY'), top.ProcedureStep( '2', top.StateChangeAction('injector_valve', 'closed'), [(top.Immediate(), top.Transition('main', '3'))], 'PRIMARY'), top.ProcedureStep( '3', top.StateChangeAction('injector_valve', 'closed'), [(top.Immediate(), top.Transition('main', '4'))], 'PRIMARY'), top.ProcedureStep('4', top.MiscAction('Approach the launch tower'), [], 'SECONDARY') ]) proc_b.load_suite(top.ProcedureSuite([procedure])) plumb_eng = make_plumbing_engine() plumb_b.load_engine(plumb_eng) proc_eng = proc_b._proc_eng assert proc_eng.current_step == procedure.step_list[0] assert proc_eng.step_position == top.StepPosition.Before proc_b.procJump("2") assert proc_eng.current_step == procedure.step_list[1] assert proc_eng.step_position == top.StepPosition.After proc_b.procJump("4") assert proc_eng.current_step == procedure.step_list[3] assert proc_eng.step_position == top.StepPosition.After
def test_parse_two_procedures(): proclang = ''' main: 1. PRIMARY: set injector_valve to open 2. PRIMARY: set vent_valve to closed abort: 1. PRIMARY: set injector_valve to closed 2. PRIMARY: set vent_valve to open ''' suite = top.proclang.parse(proclang) expected_suite = top.ProcedureSuite([ top.Procedure('main', [ top.ProcedureStep( '1', top.StateChangeAction('injector_valve', 'open'), [(top.Immediate(), top.Transition('main', '2'))], 'PRIMARY'), top.ProcedureStep('2', top.StateChangeAction( 'vent_valve', 'closed'), [], 'PRIMARY') ]), top.Procedure('abort', [ top.ProcedureStep( '1', top.StateChangeAction('injector_valve', 'closed'), [(top.Immediate(), top.Transition('abort', '2'))], 'PRIMARY'), top.ProcedureStep('2', top.StateChangeAction('vent_valve', 'open'), [], 'PRIMARY') ]) ]) assert suite == expected_suite
def test_proc_bridge_procedure_step_affects_plumbing(): plumb_b = PlumbingBridge() control_b = ControlsBridge(plumb_b) proc_b = ProceduresBridge(plumb_b, control_b) procedure = top.Procedure('main', [ top.ProcedureStep('1', top.StateChangeAction('injector_valve', 'open'), [(top.Immediate(), top.Transition('main', '2'))], 'PRIMARY'), top.ProcedureStep( '2', top.StateChangeAction('injector_valve', 'closed'), [(top.Immediate(), top.Transition('main', '3'))], 'PRIMARY'), top.ProcedureStep('3', top.MiscAction('Approach the launch tower'), [], 'SECONDARY') ]) proc_b.load_suite(top.ProcedureSuite([procedure])) plumb_eng = make_plumbing_engine() plumb_b.load_engine(plumb_eng) assert plumb_eng.current_state('injector_valve') == 'closed' proc_b.procStepForward() assert plumb_eng.current_state('injector_valve') == 'open' proc_b.procStepForward() assert plumb_eng.current_state('injector_valve') == 'closed'
def test_or_equality(): or_1 = top.Or([top.Immediate(), top.Immediate()]) or_2 = top.Or([top.Immediate(), top.Immediate()]) or_3 = top.Or([NeverSatisfied(), top.Immediate()]) assert or_1 == or_2 assert or_1 != or_3 assert or_1 != 10 assert or_1 is not None
def test_and_equality(): and_1 = top.And([top.Immediate(), top.Immediate()]) and_2 = top.And([top.Immediate(), top.Immediate()]) and_3 = top.And([NeverSatisfied(), top.Immediate()]) assert and_1 == and_2 assert and_1 != and_3 assert and_1 != 10 assert and_1 is not None
def test_nested_and_conditions(): and_sat = top.And( [top.Immediate(), top.And([top.Immediate(), top.Immediate()])]) and_unsat = top.And( [top.Immediate(), top.And([NeverSatisfied(), top.Immediate()])]) assert and_sat.satisfied() is True assert and_unsat.satisfied() is False
def test_parse_misc_actions(): proclang = ''' main: 1. CONTROL: Set injector_valve to open 2. CONTROL: [p1 < 10] Disarm the remote control system 3. PRIMARY: Approach the launch tower, disconnect the cylinder, and replace the cap 4. OPS: [60s] Proceed with teardown ''' suite = top.proclang.parse(proclang) expected_suite = top.ProcedureSuite([ top.Procedure('main', [ top.ProcedureStep( '1', top.StateChangeAction('injector_valve', 'open'), [ (top.Less('p1', 10), top.Transition('main', '2')) ], 'CONTROL'), top.ProcedureStep( '2', top.MiscAction('Disarm the remote control system'), [(top.Immediate(), top.Transition('main', '3'))], 'CONTROL'), top.ProcedureStep( '3', top.MiscAction( 'Approach the launch tower, disconnect the cylinder, and replace the cap' ), [(top.WaitFor(60e6), top.Transition('main', '4'))], 'PRIMARY'), top.ProcedureStep('4', top.MiscAction('Proceed with teardown'), [], 'OPS') ]) ]) assert suite == expected_suite
def test_immediate_condition(): cond = top.Immediate() state = {} assert cond.satisfied() is True cond.update(state) assert cond.satisfied() is True
def branching_procedure_suite_two_options(): close_action = top.StateChangeAction('c1', 'closed') open_action = top.StateChangeAction('c1', 'open') halfway_open_action = top.StateChangeAction('c1', 'halfway_open') s1 = top.ProcedureStep('s1', close_action, [(top.Immediate(), top.Transition('p1', 's2')), (top.Immediate(), top.Transition('p2', 's3'))], 'PRIMARY') s2 = top.ProcedureStep('s2', halfway_open_action, {}, 'PRIMARY') s3 = top.ProcedureStep('s3', open_action, {}, 'PRIMARY') proc_1 = top.Procedure('p1', [s1, s2, s3]) proc_2 = top.Procedure('p2', [s1, s2, s3]) return top.ProcedureSuite([proc_1, proc_2], 'p1')
def test_proc_bridge_procedure_controls_advance_procedure(): plumb_b = MockPlumbingBridge() proc_b = ProceduresBridge(plumb_b) procedure = top.Procedure('main', [ top.ProcedureStep('1', top.StateChangeAction('injector_valve', 'open'), [(top.Immediate(), top.Transition('main', '2'))], 'PRIMARY'), top.ProcedureStep('2', top.StateChangeAction('vent_valve', 'closed'), [ (top.WaitFor(100), top.Transition('main', '3')) ], 'PRIMARY'), top.ProcedureStep('3', top.MiscAction('Approach the launch tower'), [], 'SECONDARY') ]) proc_b.load_suite(top.ProcedureSuite([procedure])) proc_eng = proc_b._proc_eng assert proc_eng.current_step == procedure.step_list[0] assert proc_eng.step_position == top.StepPosition.Before proc_b.procStepForward() assert proc_eng.current_step == procedure.step_list[0] assert proc_eng.step_position == top.StepPosition.After proc_b.procStepForward() assert proc_eng.current_step == procedure.step_list[1] assert proc_eng.step_position == top.StepPosition.After proc_b.procStepForward() # does nothing; condition is not satisfied assert proc_eng.current_step == procedure.step_list[1] assert proc_eng.step_position == top.StepPosition.After proc_b.procStop() assert proc_eng.current_step == procedure.step_list[0] assert proc_eng.step_position == top.StepPosition.Before
def step(self, data): """ Process `step` nodes in the parse tree. We can't build the steps themselves yet, since the condition for advancing to the next step is an annotation on that next step. Instead, we build an intermediate step_info dict and then process all of the steps in sequence at the next stage. data will look like one of these, depending on if the step has an attached entry condition: [id, personnel, step entry condition, action, deviation1, deviation2, ...] [id, personnel, action, deviation1, deviation2, ...] """ step_info = {} step_info['id'] = data[0] step_info['personnel'] = data[1] step_info['conditions_out'] = [] if isinstance(data[2], top.Action): # Step has no attached entry condition step_info['condition_in'] = top.Immediate() step_info['action'] = data[2] deviations = data[3:] else: # Step has an attached entry condition step_info['condition_in'] = data[2] step_info['action'] = data[3] deviations = data[4:] for cond, transition in deviations: step_info['conditions_out'].append((cond, transition)) return step_info
def test_steps_model_change_proc(): model = ProcedureStepsModel() procedure = top.Procedure('main', [ top.ProcedureStep('1', top.StateChangeAction('injector_valve', 'open'), [ (top.Immediate(), top.Transition('main', '2')) ], 'PRIMARY'), top.ProcedureStep('2', top.StateChangeAction('vent_valve', 'closed'), [], 'SECONDARY') ]) wrapper = ProcedureConditionWrapper(top.Immediate(), top.Transition('main', '2')) model.change_procedure(procedure) assert model.procedure == procedure assert model.condition_wrappers == [[wrapper], []] assert model.rowCount() == 2
def test_nested_or_conditions(): or_sat = top.Or( [NeverSatisfied(), top.Or([top.Immediate(), NeverSatisfied()])]) or_unsat = top.Or( [NeverSatisfied(), top.Or([NeverSatisfied(), NeverSatisfied()])]) assert or_sat.satisfied() is True assert or_unsat.satisfied() is False
def test_parse_from_file(): filepath = os.path.join(os.path.dirname(__file__), 'example.proc') suite = top.proclang.parse_from_file(filepath) expected_suite = top.ProcedureSuite([ top.Procedure('main', [ top.ProcedureStep( '1', top.StateChangeAction('series_fill_valve', 'closed'), [(top.WaitFor(5e6), top.Transition('main', '2'))], 'PRIMARY'), top.ProcedureStep( '2', top.StateChangeAction('supply_valve', 'open'), [(top.Less('p1', 600), top.Transition('abort_1', '1')), (top.Greater('p1', 1000), top.Transition('abort_2', '1')), (top.Immediate(), top.Transition('main', '3'))], 'PRIMARY'), top.ProcedureStep( '3', top.StateChangeAction('series_fill_valve', 'open'), [(top.Immediate(), top.Transition('main', '4'))], 'PRIMARY'), top.ProcedureStep( '4', top.StateChangeAction('remote_fill_valve', 'open'), [ (top.WaitFor(180e6), top.Transition('main', '5')) ], 'PRIMARY'), top.ProcedureStep( '5', top.StateChangeAction('remote_fill_valve', 'closed'), [(top.Immediate(), top.Transition('main', '6'))], 'PRIMARY'), top.ProcedureStep( '6', top.StateChangeAction('remote_vent_valve', 'open'), [(top.Immediate(), top.Transition('main', '7'))], 'PRIMARY'), top.ProcedureStep('7', top.MiscAction('Proceed with teardown'), [], 'OPS') ]), top.Procedure('abort_1', [ top.ProcedureStep( '1', top.StateChangeAction('supply_valve', 'closed'), [ (top.WaitFor(10e6), top.Transition('abort_1', '2')) ], 'SECONDARY'), top.ProcedureStep( '2', top.StateChangeAction('remote_vent_valve', 'open'), [ (top.Immediate(), top.Transition('abort_1', '3')) ], 'SECONDARY'), top.ProcedureStep('3', top.MiscAction('Proceed with teardown'), [], 'OPS') ]), top.Procedure('abort_2', [ top.ProcedureStep( '1', top.StateChangeAction('supply_valve', 'closed'), [ (top.Immediate(), top.Transition('abort_2', '2')) ], 'CONTROL'), top.ProcedureStep( '2', top.StateChangeAction('line_vent_valve', 'open'), [ (top.Immediate(), top.Transition('abort_2', '3')) ], 'CONTROL'), top.ProcedureStep('3', top.MiscAction('Proceed with teardown'), [], 'OPS') ]), ]) assert suite == expected_suite
def test_procedure_step_affects_component_state(): plumb_b = PlumbingBridge() control_b = ControlsBridge(plumb_b) proc_b = ProceduresBridge(plumb_b, control_b) procedure = top.Procedure('main', [ top.ProcedureStep('1', top.StateChangeAction('injector_valve', 'open'), [(top.Immediate(), top.Transition('main', '2'))], 'PRIMARY'), top.ProcedureStep( '2', top.StateChangeAction('injector_valve', 'closed'), [(top.Immediate(), top.Transition('main', '3'))], 'PRIMARY'), top.ProcedureStep('3', top.MiscAction('Approach the launch tower'), [], 'SECONDARY') ]) proc_b.load_suite(top.ProcedureSuite([procedure])) plumb_eng = make_plumbing_engine() plumb_b.load_engine(plumb_eng) control_b.refresh() proc_eng = proc_b._proc_eng assert proc_eng.current_step == procedure.step_list[0] assert proc_eng.step_position == top.StepPosition.Before proc_b.procStepForward() assert (control_b.states[0] == "open") assert proc_eng.current_step == procedure.step_list[0] assert proc_eng.step_position == top.StepPosition.After proc_b.procStepForward() assert (control_b.states[0] == "closed") assert proc_eng.current_step == procedure.step_list[1] assert proc_eng.step_position == top.StepPosition.After proc_b.procStepForward() assert (control_b.states[0] == "closed") proc_b.procStop() assert proc_eng.current_step == procedure.step_list[0] assert proc_eng.step_position == top.StepPosition.Before
def single_procedure_suite(): close_action = top.StateChangeAction('c1', 'closed') open_action = top.StateChangeAction('c1', 'open') s1 = top.ProcedureStep('s1', close_action, [(top.Immediate(), top.Transition('p1', 's2'))], 'PRIMARY') s2 = top.ProcedureStep('s2', open_action, [], 'PRIMARY') proc = top.Procedure('p1', [s1, s2]) return top.ProcedureSuite([proc], 'p1')
def test_steps_model_get_data(): procedure = top.Procedure('main', [ top.ProcedureStep('1', top.StateChangeAction('injector_valve', 'open'), [ (top.Immediate(), top.Transition('main', '2')) ], 'PRIMARY'), top.ProcedureStep('2', top.MiscAction('Approach the launch tower'), [], 'SECONDARY') ]) model = ProcedureStepsModel(procedure) wrapper = ProcedureConditionWrapper(top.Immediate(), top.Transition('main', '2')) idx_0 = model.createIndex(0, 0) assert model.data(idx_0, ProcedureStepsModel.ActionRoleIdx) == 'Set injector_valve to open' assert model.data(idx_0, ProcedureStepsModel.OperatorRoleIdx) == 'PRIMARY' assert model.data(idx_0, ProcedureStepsModel.ConditionsRoleIdx) == [wrapper] idx_1 = model.createIndex(1, 0) assert model.data(idx_1, ProcedureStepsModel.ActionRoleIdx) == 'Approach the launch tower' assert model.data(idx_1, ProcedureStepsModel.OperatorRoleIdx) == 'SECONDARY' assert model.data(idx_1, ProcedureStepsModel.ConditionsRoleIdx) == []
def test_control_panel_initialization(): plumb_b = PlumbingBridge() control_b = ControlsBridge(plumb_b) proc_b = ProceduresBridge(plumb_b, control_b) procedure = top.Procedure('main', [ top.ProcedureStep('1', top.StateChangeAction('injector_valve', 'open'), [(top.Immediate(), top.Transition('main', '2'))], 'PRIMARY'), top.ProcedureStep( '2', top.StateChangeAction('injector_valve', 'closed'), [(top.Immediate(), top.Transition('main', '3'))], 'PRIMARY'), top.ProcedureStep('3', top.MiscAction('Approach the launch tower'), [], 'SECONDARY') ]) proc_b.load_suite(top.ProcedureSuite([procedure])) plumb_eng = make_plumbing_engine() plumb_b.load_engine(plumb_eng) control_b.refresh() assert (control_b.toggleable_components == ['injector_valve']) assert (control_b.states[0] == "closed")
def test_different_step_ids(): proclang = ''' main: 1. PRIMARY: Set injector_valve to open 10. PRIMARY: Set injector_valve to open 100. PRIMARY: Set injector_valve to open a. PRIMARY: Set injector_valve to open ab. PRIMARY: Set injector_valve to open a1. PRIMARY: Set injector_valve to open 1a. PRIMARY: Set injector_valve to open a_1. PRIMARY: Set injector_valve to open 1_a. PRIMARY: Set injector_valve to open ''' suite = top.proclang.parse(proclang) expected_suite = top.ProcedureSuite([ top.Procedure('main', [ top.ProcedureStep( '1', top.StateChangeAction('injector_valve', 'open'), [(top.Immediate(), top.Transition('main', '10'))], 'PRIMARY'), top.ProcedureStep( '10', top.StateChangeAction('injector_valve', 'open'), [(top.Immediate(), top.Transition('main', '100'))], 'PRIMARY'), top.ProcedureStep( '100', top.StateChangeAction('injector_valve', 'open'), [(top.Immediate(), top.Transition('main', 'a'))], 'PRIMARY'), top.ProcedureStep( 'a', top.StateChangeAction('injector_valve', 'open'), [(top.Immediate(), top.Transition('main', 'ab'))], 'PRIMARY'), top.ProcedureStep( 'ab', top.StateChangeAction('injector_valve', 'open'), [(top.Immediate(), top.Transition('main', 'a1'))], 'PRIMARY'), top.ProcedureStep( 'a1', top.StateChangeAction('injector_valve', 'open'), [(top.Immediate(), top.Transition('main', '1a'))], 'PRIMARY'), top.ProcedureStep( '1a', top.StateChangeAction('injector_valve', 'open'), [(top.Immediate(), top.Transition('main', 'a_1'))], 'PRIMARY'), top.ProcedureStep( 'a_1', top.StateChangeAction('injector_valve', 'open'), [(top.Immediate(), top.Transition('main', '1_a'))], 'PRIMARY'), top.ProcedureStep('1_a', top.StateChangeAction('injector_valve', 'open'), [], 'PRIMARY') ]) ]) assert suite == expected_suite
def test_proc_bridge_load_suite(): plumb_b = MockPlumbingBridge() proc_b = ProceduresBridge(plumb_b) procedure = top.Procedure('main', [ top.ProcedureStep('1', top.StateChangeAction('injector_valve', 'open'), [(top.Immediate(), top.Transition('main', '2'))], 'PRIMARY'), top.ProcedureStep('2', top.MiscAction('Approach the launch tower'), [], 'SECONDARY') ]) suite = top.ProcedureSuite([procedure]) proc_b.load_suite(suite) assert proc_b._proc_eng._suite == suite assert proc_b.steps.procedure == procedure
def test_string_representations(): immediate_cond = top.Immediate() waitFor_cond = top.WaitFor(1000000) equal_cond = top.Equal('A1', 100) less_cond = top.Less('A2', 100) greater_cond = top.Greater('A3', 100) lessEqual_cond = top.LessEqual('A4', 100) greaterEqual_cond = top.GreaterEqual('A5', 100) and_cond = top.And([less_cond, greater_cond]) or_cond = top.Or([lessEqual_cond, greaterEqual_cond]) assert str(immediate_cond) == 'Immediately' assert str(waitFor_cond) == 'Wait for 1 seconds' assert str(equal_cond) == 'A1 == 100' assert str(less_cond) == 'A2 < 100' assert str(greater_cond) == 'A3 > 100' assert str(lessEqual_cond) == 'A4 <= 100' assert str(greaterEqual_cond) == 'A5 >= 100' assert str(and_cond) == '(A2 < 100 and A3 > 100)' assert str(or_cond) == '(A4 <= 100 or A5 >= 100)'
def test_set_case_insensitive(): proclang = ''' main: 1. PRIMARY: Set injector_valve to open 2. PRIMARY: set injector_valve to open ''' suite = top.proclang.parse(proclang) expected_suite = top.ProcedureSuite([ top.Procedure('main', [ top.ProcedureStep( '1', top.StateChangeAction('injector_valve', 'open'), [(top.Immediate(), top.Transition('main', '2'))], 'PRIMARY'), top.ProcedureStep('2', top.StateChangeAction('injector_valve', 'open'), [], 'PRIMARY') ]) ]) assert suite == expected_suite
def test_parse_step_with_one_deviation(): proclang = ''' main: 1. PRIMARY: set injector_valve to open - [p1 < 500] abort.1 2. PRIMARY: set vent_valve to closed ''' suite = top.proclang.parse(proclang) expected_suite = top.ProcedureSuite([ top.Procedure('main', [ top.ProcedureStep( '1', top.StateChangeAction('injector_valve', 'open'), [(top.Less('p1', 500), top.Transition('abort', '1')), (top.Immediate(), top.Transition('main', '2'))], 'PRIMARY'), top.ProcedureStep('2', top.StateChangeAction( 'vent_valve', 'closed'), [], 'PRIMARY') ]) ]) assert suite == expected_suite
def test_whitespace_is_irrelevant(): proclang = ''' main: 1. CONTROL: set injector_valve to open - [p1 < 500] abort.1 - [300 s] abort.2 2. CONTROL: set vent_valve to closed ''' suite = top.proclang.parse(proclang) expected_suite = top.ProcedureSuite([ top.Procedure('main', [ top.ProcedureStep( '1', top.StateChangeAction('injector_valve', 'open'), [(top.Less('p1', 500), top.Transition('abort', '1')), (top.WaitFor(300e6), top.Transition('abort', '2')), (top.Immediate(), top.Transition('main', '2'))], 'CONTROL'), top.ProcedureStep('2', top.StateChangeAction( 'vent_valve', 'closed'), [], 'CONTROL') ]) ]) assert suite == expected_suite
def test_transitions_respects_procedure_identifier(): plumb_eng = one_component_engine() action = top.MiscAction('Do nothing') s1 = top.ProcedureStep( 's1', action, [(NeverSatisfied(), top.Transition('p1', 'same_name')), (top.Immediate(), top.Transition('p2', 'same_name'))], 'PRIMARY') same_name_1 = top.ProcedureStep('same_name', action, [], 'PRIMARY') same_name_2 = top.ProcedureStep('same_name', action, [], 'PRIMARY') proc_1 = top.Procedure('p1', [s1, same_name_1]) proc_2 = top.Procedure('p2', [same_name_2]) proc_suite = top.ProcedureSuite([proc_1, proc_2], 'p1') proc_eng = top.ProceduresEngine(plumb_eng, proc_suite) proc_eng.execute_current() assert proc_eng.current_procedure_id == 'p1' assert proc_eng.current_step.step_id == 's1' proc_eng.next_step() assert proc_eng.current_procedure_id == 'p2' assert proc_eng.current_step.step_id == 'same_name'
def test_or_one_condition(): or_sat = top.Or([top.Immediate()]) or_unsat = top.Or([NeverSatisfied()]) assert or_sat.satisfied() is True assert or_unsat.satisfied() is False
def test_and_or_not_equal(): and_cond = top.And([NeverSatisfied(), top.Immediate()]) or_cond = top.Or([NeverSatisfied(), top.Immediate()]) assert and_cond != or_cond
def test_immediate_equality(): cond1 = top.Immediate() cond2 = top.Immediate() assert cond1 == cond2 assert cond1 is not None