def test_build_path_o2_m1_i2_tt_m1_i0_two_elements_main_block( self) -> None: sequencer = Sequencer() ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} elem1 = DummySequencingElement(False) elem2 = DummySequencingElement(False) sequencer.push(elem2, ps, cs) sequencer.push(elem1, ps, cs) sequence = sequencer.build() self.assertTrue(sequencer.has_finished()) self.assertIs(elem1, sequence[0].elem) self.assertEqual(ps, elem1.parameters) self.assertEqual(cs, elem1.conditions) self.assertEqual(1, elem1.requires_stop_call_counter) self.assertEqual(1, elem1.build_call_counter) self.assertIs(elem2, sequence[1].elem) self.assertEqual(ps, elem2.parameters) self.assertEqual(cs, elem2.conditions) self.assertEqual(1, elem2.requires_stop_call_counter) self.assertEqual(1, elem2.build_call_counter) self.assertEqual(STOPInstruction(), sequence[2]) self.assertEqual(3, len(sequence))
def test_build_path_o2_m1_i2_tf_m2_i1_f_i1_f_two_elements_main_block_last_requires_stop_add_one_element_requires_stop_new_block( self) -> None: sequencer = Sequencer() ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} new_block = InstructionBlock() new_elem = DummySequencingElement(True) elem1 = DummySequencingElement(False, (new_block, [new_elem])) elem2 = DummySequencingElement(True) sequencer.push(elem2, ps, cs) sequencer.push(elem1, ps, cs) sequence = sequencer.build() self.assertFalse(sequencer.has_finished()) self.assertIs(elem1, sequence[0].elem) self.assertEqual(ps, elem1.parameters) self.assertEqual(cs, elem1.conditions) self.assertEqual(1, elem1.requires_stop_call_counter) self.assertEqual(1, elem1.build_call_counter) self.assertEqual(ps, elem2.parameters) self.assertEqual(cs, elem2.conditions) self.assertEqual(2, elem2.requires_stop_call_counter) self.assertEqual(0, elem2.build_call_counter) self.assertEqual(ps, new_elem.parameters) self.assertEqual(cs, new_elem.conditions) self.assertEqual(1, new_elem.requires_stop_call_counter) self.assertEqual(0, new_elem.build_call_counter) self.assertEqual(STOPInstruction(), sequence[1]) self.assertEqual(2, len(sequence))
def test_build_sequence_loop(self) -> None: sequencer = DummySequencer() block = DummyInstructionBlock() block.add_instruction(DummyInstruction()) delegator = DummySequencingElement() body = DummySequencingElement() trigger = Trigger() condition = HardwareCondition(trigger) condition.build_sequence_loop(delegator, body, sequencer, {}, {}, {}, {}, block) self.assertEqual(1, len(block.embedded_blocks)) body_block = block.embedded_blocks[0] self.assertEqual( [ DummyInstruction(), CJMPInstruction(trigger, InstructionPointer(body_block)) ], block.instructions, "The expected conditional jump was not generated by HardwareConditon." ) self.assertEqual( InstructionPointer(block, 1), body_block.return_ip, "The return address of the loop body block was set wrongly by HardwareCondition." ) self.assertEqual( {body_block: [(body, {}, {}, {}, {})]}, sequencer.sequencing_stacks, "HardwareCondition did not correctly push the body element to the stack" ) self.assertFalse(condition.requires_stop())
def test_build_path_o2_m2_i1_t_i1_t_m2_i0_i0_one_element_custom_block_one_element_main_block( self) -> None: sequencer = Sequencer() ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} elem_main = DummySequencingElement(False) sequencer.push(elem_main, ps, cs) target_block = InstructionBlock() elem_cstm = DummySequencingElement(False) sequencer.push(elem_cstm, ps, cs, target_block) sequence = sequencer.build() self.assertTrue(sequencer.has_finished()) self.assertIs(elem_main, sequence[0].elem) self.assertEqual(ps, elem_main.parameters) self.assertEqual(cs, elem_main.conditions) self.assertEqual(1, elem_main.requires_stop_call_counter) self.assertEqual(1, elem_main.build_call_counter) self.assertIs(target_block, elem_cstm.target_block) self.assertEqual(ps, elem_cstm.parameters) self.assertEqual(cs, elem_cstm.conditions) self.assertEqual(1, elem_cstm.requires_stop_call_counter) self.assertEqual(1, elem_cstm.build_call_counter) self.assertEqual(STOPInstruction(), sequence[1]) self.assertEqual(2, len(sequence))
def test_build_path_o2_m2_i1_f_i2_tf_m2_i1_f_i1_f_two_elements_custom_block_last_requires_stop_one_element_requires_stop_main_block( self) -> None: sequencer = Sequencer() ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} target_block = InstructionBlock() elem2 = DummySequencingElement(True) sequencer.push(elem2, ps, cs, target_block) elem1 = DummySequencingElement(False) sequencer.push(elem1, ps, cs, target_block) elem_main = DummySequencingElement(True) sequencer.push(elem_main, ps, cs) sequencer.build() self.assertFalse(sequencer.has_finished()) self.assertIs(target_block, elem1.target_block) self.assertEqual(ps, elem1.parameters) self.assertEqual(cs, elem1.conditions) self.assertEqual(1, elem1.requires_stop_call_counter) self.assertEqual(1, elem1.build_call_counter) self.assertEqual(ps, elem2.parameters) self.assertEqual(cs, elem2.conditions) self.assertEqual(2, elem2.requires_stop_call_counter) self.assertEqual(0, elem2.build_call_counter) self.assertEqual(ps, elem_main.parameters) self.assertEqual(cs, elem_main.conditions) self.assertEqual(2, elem_main.requires_stop_call_counter) self.assertEqual(0, elem_main.build_call_counter)
def test_build_path_o2_m2_i0_i2_tt_m2_i0_i0_two_elements_custom_block(self) -> None: sequencer = Sequencer() ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} wm = {'foo': 'bar'} target_block = InstructionBlock() elem2 = DummySequencingElement(False) sequencer.push(elem2, ps, cs, window_mapping=wm, target_block=target_block) elem1 = DummySequencingElement(False) sequencer.push(elem1, ps, cs, window_mapping=wm, target_block=target_block) sequencer.build() self.assertTrue(sequencer.has_finished()) self.assertIs(target_block, elem1.target_block) self.assertEqual(ps, elem1.parameters) self.assertEqual(cs, elem1.conditions) self.assertEqual(1, elem1.requires_stop_call_counter) self.assertEqual(1, elem1.build_call_counter) self.assertIs(target_block, elem2.target_block) self.assertEqual(ps, elem2.parameters) self.assertEqual(cs, elem2.conditions) self.assertEqual(1, elem2.requires_stop_call_counter) self.assertEqual(1, elem2.build_call_counter)
def test_build_path_o1_m2_i1_f_i1_f_one_element_custom_and_main_block_requires_stop( self) -> None: sequencer = Sequencer() ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} elem_main = DummySequencingElement(True) sequencer.push(elem_main, ps, cs) elem_cstm = DummySequencingElement(True) target_block = InstructionBlock() sequencer.push(elem_cstm, ps, cs, target_block) sequencer.build() self.assertFalse(sequencer.has_finished()) self.assertEqual(ps, elem_main.parameters) self.assertEqual(cs, elem_main.conditions) self.assertEqual(1, elem_main.requires_stop_call_counter) self.assertEqual(0, elem_main.build_call_counter) self.assertEqual(ps, elem_cstm.parameters) self.assertEqual(cs, elem_cstm.conditions) self.assertEqual(1, elem_cstm.requires_stop_call_counter) self.assertEqual(0, elem_cstm.build_call_counter)
def test_build_path_o2_m2_i2_tt_t_i2_tf_m2_i0_i1_f_two_elements_custom_block_last_requires_stop_two_element_main_block( self) -> None: sequencer = Sequencer() ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} wm = {'foo': 'bar'} target_block = InstructionBlock() elem2 = DummySequencingElement(True) sequencer.push(elem2, ps, cs, window_mapping=wm, target_block=target_block) elem1 = DummySequencingElement(False) sequencer.push(elem1, ps, cs, window_mapping=wm, target_block=target_block) elem_main2 = DummySequencingElement(False) sequencer.push(elem_main2, ps, cs) elem_main1 = DummySequencingElement(False) sequencer.push(elem_main1, ps, cs) sequence = sequencer.build() self.assertFalse(sequencer.has_finished()) self.assertIs(target_block, elem1.target_block) self.assertEqual(ps, elem1.parameters) self.assertEqual(cs, elem1.conditions) self.assertEqual(1, elem1.requires_stop_call_counter) self.assertEqual(1, elem1.build_call_counter) self.assertEqual(ps, elem2.parameters) self.assertEqual(cs, elem2.conditions) self.assertEqual(2, elem2.requires_stop_call_counter) self.assertEqual(0, elem2.build_call_counter) self.assertIs(elem_main1, sequence[0].elem) self.assertEqual(ps, elem_main1.parameters) self.assertEqual(cs, elem_main1.conditions) self.assertEqual(1, elem_main1.requires_stop_call_counter) self.assertEqual(1, elem_main1.build_call_counter) self.assertIs(elem_main2, sequence[1].elem) self.assertEqual(ps, elem_main2.parameters) self.assertEqual(cs, elem_main2.conditions) self.assertEqual(1, elem_main2.requires_stop_call_counter) self.assertEqual(1, elem_main2.build_call_counter) self.assertEqual(STOPInstruction(), sequence[2]) self.assertEqual(3, len(sequence))
def test_build_path_o2_m2_i0_i1_t_m2_i0_i0_one_element_custom_block( self) -> None: sequencer = Sequencer() ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} wm = {'foo': 'bar'} cm = {'A': 'B'} target_block = InstructionBlock() elem = DummySequencingElement(False) sequencer.push(elem, ps, cs, window_mapping=wm, channel_mapping=cm, target_block=target_block) sequencer.build() self.assertTrue(sequencer.has_finished()) self.assertIs(target_block, elem.target_block) self.assertEqual(ps, elem.parameters) self.assertEqual(cs, elem.conditions) self.assertEqual(wm, elem.window_mapping) self.assertEqual(cm, elem.channel_mapping) self.assertEqual(1, elem.requires_stop_call_counter) self.assertEqual(1, elem.build_call_counter)
def test_build_cannot_evaluate(self) -> None: sequencer = DummySequencer() block = DummyInstructionBlock() delegator = DummySequencingElement() body = DummySequencingElement() condition = SoftwareCondition(lambda loop_iteration: None) self.assertTrue(condition.requires_stop()) with self.assertRaises(ConditionEvaluationException): condition.build_sequence_loop(delegator, body, sequencer, {}, {}, {}, {}, block) with self.assertRaises(ConditionEvaluationException): condition.build_sequence_branch(delegator, body, body, sequencer, {}, {}, {}, {}, block) self.assertEqual(str(ConditionEvaluationException()), "The Condition can currently not be evaluated.")
def test_build_sequence_branch(self) -> None: sequencer = DummySequencer() block = DummyInstructionBlock() delegator = DummySequencingElement() if_branch = DummySequencingElement() else_branch = DummySequencingElement() trigger = Trigger() condition = HardwareCondition(trigger) condition.build_sequence_branch(delegator, if_branch, else_branch, sequencer, {}, {}, {}, {}, instruction_block=block) self.assertEqual(2, len(block.embedded_blocks)) if_block = block.embedded_blocks[0] else_block = block.embedded_blocks[1] self.assertEqual( [ CJMPInstruction(trigger, InstructionPointer(if_block)), GOTOInstruction(InstructionPointer(else_block)) ], block.instructions, "The expected jump instruction were not generated by HardwareConditon." ) self.assertEqual( InstructionPointer(block, 2), if_block.return_ip, "The return address of the if branch block was set wrongly by HardwareConditon." ) self.assertEqual( InstructionPointer(block, 2), else_block.return_ip, "The return address of the else branch block was set wrongly by HardwareConditon." ) self.assertEqual( { if_block: [(if_branch, {}, {}, {}, {})], else_block: [(else_branch, {}, {}, {}, {})] }, sequencer.sequencing_stacks, "HardwareCondition did not correctly push the branch elements to the stack" )
def test_build_sequence_loop_false(self): sequencer = DummySequencer() block = DummyInstructionBlock() delegator = DummySequencingElement() body = DummySequencingElement() callback = IterationCallbackDummy(False) condition = SoftwareCondition( lambda loop_iteration: callback.callback(loop_iteration)) condition.build_sequence_loop(delegator, body, sequencer, {}, {}, {}, {}, block) self.assertEqual(0, callback.loop_iteration) self.assertFalse(block.instructions) self.assertFalse(sequencer.sequencing_stacks) condition.build_sequence_loop(delegator, body, sequencer, {}, {}, {}, {}, block) self.assertEqual(0, callback.loop_iteration)
def test_push(self) -> None: sequencer = Sequencer() ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} elem = DummySequencingElement() sequencer.push(elem, ps, cs) self.assertFalse(sequencer.has_finished()) sequencer.build() self.assertEqual(ps, elem.parameters)
def test_push_float_params(self) -> None: sequencer = Sequencer() ps = {'foo': 1, 'bar': 7.3} cs = {'foo': DummyCondition()} elem = DummySequencingElement() sequencer.push(elem, ps, cs) self.assertFalse(sequencer.has_finished()) sequencer.build() self.assertIsInstance(elem.parameters['foo'], ConstantParameter) self.assertIsInstance(elem.parameters['bar'], ConstantParameter) self.assertEqual(cs, elem.conditions)
def test_build_sequence_branch_true(self): sequencer = DummySequencer() block = DummyInstructionBlock() delegator = DummySequencingElement() if_branch = DummySequencingElement() else_branch = DummySequencingElement() callback = IterationCallbackDummy(True) condition = SoftwareCondition( lambda loop_iteration: callback.callback(loop_iteration)) condition.build_sequence_branch(delegator, if_branch, else_branch, sequencer, {}, {}, {}, {}, block) self.assertEqual(0, callback.loop_iteration) self.assertFalse(block.instructions) self.assertEqual({block: [(if_branch, {}, {}, {}, {})]}, sequencer.sequencing_stacks) condition.build_sequence_branch(delegator, if_branch, else_branch, sequencer, {}, {}, {}, {}, block) self.assertEqual(0, callback.loop_iteration)
def test_build_path_o1_m1_i1_f_single_element_requires_stop_main_block(self) -> None: sequencer = Sequencer() elem = DummySequencingElement(True) ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} sequencer.push(elem, ps, cs) sequencer.build() self.assertFalse(sequencer.has_finished()) self.assertEqual(ps, elem.parameters) self.assertEqual(cs, elem.conditions) self.assertEqual(1, elem.requires_stop_call_counter) self.assertEqual(0, elem.build_call_counter)
def test_build_path_o1_m2_i1_f_i0_one_element_custom_block_requires_stop(self) -> None: sequencer = Sequencer() elem = DummySequencingElement(True) ps = {'foo': ConstantParameter(1), 'bar': ConstantParameter(7.3)} cs = {'foo': DummyCondition()} wm = {} target_block = InstructionBlock() sequencer.push(elem, ps, cs, window_mapping=wm, target_block=target_block) sequencer.build() self.assertFalse(sequencer.has_finished()) self.assertEqual(ps, elem.parameters) self.assertEqual(cs, elem.conditions) self.assertEqual(1, elem.requires_stop_call_counter) self.assertEqual(0, elem.build_call_counter)