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_wait_for_equality(): cond1 = top.WaitFor(100) cond2 = top.WaitFor(100) cond3 = top.WaitFor(200) assert cond1 == cond2 assert cond1 != cond3 assert cond1 != 100 assert cond1 is not None
def test_nested_logic_works(): eq_cond_1 = top.Equal('A1', 100) eq_cond_2 = top.Equal('A2', 100) wait_cond = top.WaitFor(100) or_cond = top.Or([eq_cond_1, eq_cond_2]) and_cond = top.And([or_cond, wait_cond]) state_0 = {'pressures': {'A1': 0, 'A2': 0, 'A3': 0}, 'time': 0} state_1 = {'pressures': {'A1': 100, 'A2': 200, 'A3': 300}, 'time': 100} assert eq_cond_1.satisfied() is False assert eq_cond_2.satisfied() is False assert wait_cond.satisfied() is False assert or_cond.satisfied() is False assert and_cond.satisfied() is False and_cond.reinitialize(state_0) assert eq_cond_1.satisfied() is False assert eq_cond_2.satisfied() is False assert wait_cond.satisfied() is False assert or_cond.satisfied() is False assert and_cond.satisfied() is False and_cond.update(state_1) assert eq_cond_1.satisfied() is True assert eq_cond_2.satisfied() is False assert wait_cond.satisfied() is True assert or_cond.satisfied() is True assert and_cond.satisfied() is True
def test_parse_combined_conditions(): proclang = ''' main: 1. PRIMARY: set s to v 2. PRIMARY: [p1 < 100 or 500s and p2 < 200] set s to v ''' suite = top.proclang.parse(proclang) comp_or = top.Or([ top.Less('p1', 100), top.And([top.WaitFor(1e6 * 500), top.Less('p2', 200)]) ]) expected_suite = top.ProcedureSuite([ top.Procedure('main', [ top.ProcedureStep('1', top.StateChangeAction('s', 'v'), [ (comp_or, top.Transition('main', '2')) ], 'PRIMARY'), top.ProcedureStep('2', top.StateChangeAction('s', 'v'), [], 'PRIMARY') ]) ]) assert suite == expected_suite
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 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_wait_for_condition_after(): cond = top.WaitFor(100) cond.reinitialize({'time': 0}) assert cond.satisfied() is False cond.update({'time': 101}) assert cond.satisfied() is True
def test_waitfor_latex_export(): suite = top.ProcedureSuite([ top.Procedure('main', [ top.ProcedureStep( '1', top.StateChangeAction('injector_valve', 'open'), [(top.And([ top.WaitFor(10e6), top.Or( [top.Less('p1', 400.0), top.GreaterEqual('p2', 17.0)]) ]), top.Transition('main', '2'))], 'PRIMARY'), top.ProcedureStep('2', top.StateChangeAction( 'vent_valve', 'closed'), [], 'PRIMARY') ]) ]) export = suite.export(top.ExportFormat.Latex) expected_export = textwrap.dedent(r''' \subsection{main} \begin{checklist} \item \PRIMARY{} Open injector\_valve \item Wait 10 seconds and p1 is less than 400psi or p2 is greater than or equal to 17psi \item \PRIMARY{} Close vent\_valve \end{checklist}''') assert export == expected_export
def test_time_step_forward(): plumb_b = PlumbingBridge() plumb_b.step_size = 0.1e6 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.WaitFor(0.2e6), top.Transition('main', '2'))], 'PRIMARY'), top.ProcedureStep( '2', top.StateChangeAction('injector_valve', 'closed'), [(top.WaitFor(0.2e6), 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) proc_eng = proc_b._proc_eng proc_b.procStepForward() # execute step 1 assert not proc_eng.ready_to_proceed() # Time hasn't advanced yet, so pressures should be the same assert plumb_eng.current_pressures('A') == 100 assert plumb_eng.current_pressures('B') == 0 plumb_b.timeStepForward() # time == 0.1s assert not proc_eng.ready_to_proceed() # Valve is open, so pressures should start dropping assert plumb_eng.current_pressures('A') < 100 assert plumb_eng.current_pressures('B') > 0 plumb_b.timeStepForward() # time == 0.2s assert proc_eng.ready_to_proceed() pressures_at_02 = plumb_eng.current_pressures() proc_b.procStepForward() # execute step 2 assert not proc_eng.ready_to_proceed() assert plumb_eng.current_pressures() == pressures_at_02 plumb_b.timeStepForward() # time == 0.3s assert not proc_eng.ready_to_proceed() # Valve is now closed, so pressures shouldn't change further assert plumb_eng.current_pressures() == pressures_at_02
def waitfor(self, data): """ Process `waitfor` nodes in the parse tree. `data` is a list of the form [reference_time]. reference_time is in seconds, so we need to convert it to microseconds. """ return top.WaitFor(data[0] * 1e6)
def test_condition_wrapper_wraps_condition(): cond = top.WaitFor(1) cond.reinitialize({'time': 0}) wrapper = ProcedureConditionWrapper(cond, None) assert not wrapper.satisfied cond.update({'time': 101}) assert wrapper.satisfied
def test_update_conditions_updates_time(): plumb_eng = one_component_engine() plumb_eng.set_component_state('c1', 'open') s1 = top.ProcedureStep('s1', None, [(top.WaitFor(10), 's2')], 'PRIMARY') proc = top.Procedure('p1', [s1]) proc_suite = top.ProcedureSuite([proc], 'p1') proc_eng = top.ProceduresEngine(plumb_eng, proc_suite) proc_eng.execute_current() assert proc_eng.ready_to_proceed() is False plumb_eng.step(10) proc_eng.update_conditions() assert proc_eng.ready_to_proceed() is True
def test_parse_step_with_waitfor(): proclang = ''' main: 1. PRIMARY: set injector_valve to open 2. PRIMARY: [10s] 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.WaitFor(10e6), top.Transition('main', '2'))], 'PRIMARY'), top.ProcedureStep('2', top.StateChangeAction( 'vent_valve', 'closed'), [], 'PRIMARY') ]) ]) assert suite == expected_suite
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_waitfor_latex_export(): suite = top.ProcedureSuite([ top.Procedure('main', [ top.ProcedureStep( '1', top.StateChangeAction('injector_valve', 'open'), [(top.WaitFor(10e6), top.Transition('main', '2'))], 'PRIMARY'), top.ProcedureStep('2', top.StateChangeAction( 'vent_valve', 'closed'), [], 'PRIMARY') ]) ]) export = suite.export(top.ExportFormat.Latex) expected_export = textwrap.dedent(r''' \subsection{main} \begin{checklist} \item \PRIMARY{} Open injector\_valve \item Wait 10 seconds \item \PRIMARY{} Close vent\_valve \end{checklist}''') assert export == expected_export
def test_parse_step_with_two_deviations(): proclang = ''' main: 1. PRIMARY: set injector_valve to open - [p1 < 500] abort.1 - [300s] abort.2 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.WaitFor(300e6), top.Transition('abort', '2')), (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