def test_second_checkpoint_is_reached(self): machine = ThreePhaseMachine() player = ProcessPlayer(machine) cp1 = player.add_checkpoint_before(machine.second_phase) cp2 = player.add_checkpoint_before(machine.third_phase) conductor = ProcessConductor([player], [cp1, cp2]) next(conductor) self.assertEqual(machine.steps, [1]) next(conductor) self.assertEqual(machine.steps, [1, 2])
def test_3_checkpoints_are_returned_by_runner(self): machine = ThreePhaseMachine() starter = ProcessPlayer(machine) cp1 = starter.add_checkpoint_before(machine.first_phase, '1-1') cp2 = starter.add_checkpoint_before(machine.second_phase, '1-2') cp3 = starter.add_checkpoint_before(machine.third_phase, '1-3') runner = ProcessConductor([starter], [cp1, cp2, cp3]) self.assertIs(next(runner), cp1) self.assertIs(next(runner), cp2) self.assertIs(next(runner), cp3)
def test_single_checkpoint_is_returned_by_runner(self): machine = ThreePhaseMachine() starter = ProcessPlayer(machine) cp1 = starter.add_checkpoint_before(machine.first_phase) runner = ProcessConductor([starter], [cp1]) self.assertIs(next(runner), cp1)
def test_run_to_first_checkpoint_before_method(self): machine = ThreePhaseMachine() player = ProcessPlayer(machine) cp = player.add_checkpoint_before(machine.third_phase) conductor = ProcessConductor([player], [cp]) next(conductor) self.assertEqual(machine.steps, [1, 2])
def test_continue_until_the_end(self): machine = ThreePhaseMachine() player = ProcessPlayer(machine) cp1 = player.add_checkpoint_before(machine.third_phase) conductor = ProcessConductor([player], [cp1]) next(conductor) next(conductor) self.assertEqual(machine.steps, [1, 2, 3])
def test_thread_state_changes_after_each_checkpoint(self): machine = ThreePhaseMachine() player = ProcessPlayer(machine) cp1 = player.add_checkpoint_before(machine.first_phase) cp2 = player.add_checkpoint_before(machine.second_phase) cp3 = player.add_checkpoint_before(machine.third_phase) cp4 = player.add_checkpoint_after(machine.third_phase) conductor = ProcessConductor([player], [cp1, cp2, cp3, cp4]) self.assertEqual(machine.steps, []) next(conductor) self.assertEqual(machine.steps, []) next(conductor) self.assertEqual(machine.steps, [1]) next(conductor) self.assertEqual(machine.steps, [1, 2]) next(conductor) self.assertEqual(machine.steps, [1, 2, 3])
def test_checkpoint_order_mixed_2_procs_3_checkpoints_each(self): # Time -> ... (checkpoints order) # Process 1: CP1 CP2 CP3 # Process 2: CP1 CP2 CP3 machine1 = ThreePhaseMachine() machine2 = ThreePhaseMachine() starter1 = ProcessPlayer(machine1, 's1') starter2 = ProcessPlayer(machine2, 's2') cp1_1 = starter1.add_checkpoint_before(machine1.first_phase, '1') cp1_2 = starter1.add_checkpoint_before(machine1.second_phase, '2') cp1_3 = starter1.add_checkpoint_before(machine1.third_phase, '3') cp2_1 = starter2.add_checkpoint_before(machine2.first_phase, '1') cp2_2 = starter2.add_checkpoint_before(machine2.second_phase, '2') cp2_3 = starter2.add_checkpoint_before(machine2.third_phase, '3') runner = ProcessConductor( [starter1, starter2], [cp1_1, cp2_1, cp1_2, cp1_3, cp2_2, cp2_3]) self.assertIs(next(runner), cp1_1) self.assertIs(next(runner), cp2_1) self.assertIs(next(runner), cp1_2) self.assertIs(next(runner), cp1_3) self.assertIs(next(runner), cp2_2) self.assertIs(next(runner), cp2_3)
def test_when_switching_threads_all_are_run_until_the_end(self): # Time -> ... # Process 1: CP1 CP2 CP3 # Process 2: CP1 CP2 CP3 machine1 = ThreePhaseMachine() machine2 = ThreePhaseMachine() starter1 = ProcessPlayer(machine1) starter2 = ProcessPlayer(machine2) cp1_1 = starter1.add_checkpoint_before(machine1.third_phase) cp2_1 = starter2.add_checkpoint_before(machine2.third_phase) conductor = ProcessConductor([starter1, starter2], [cp1_1, cp2_1]) next(conductor) next(conductor) self.assertEqual(machine2.steps, [1, 2]) # Easy enough to fix: need special checkpoints that mark that the # thread has exited BUT we also need to make a decision in this # special non-explicit case. Let's just let the currently running # thread to continue self.assertEqual(machine1.steps, [1, 2, 3])
def test_simple_order_for_2_processes(self): # Time -> ... # Process 1: CP1 CP2 CP3 # Process 2: CP1 CP2 CP3 machine1 = ThreePhaseMachine() machine2 = ThreePhaseMachine() starter1 = ProcessPlayer(machine1) starter2 = ProcessPlayer(machine2) cp1_1 = starter1.add_checkpoint_before(machine1.first_phase) cp1_2 = starter1.add_checkpoint_before(machine1.second_phase) cp1_3 = starter1.add_checkpoint_after(machine1.third_phase) cp2_1 = starter2.add_checkpoint_before(machine2.first_phase) cp2_2 = starter2.add_checkpoint_before(machine2.second_phase) cp2_3 = starter2.add_checkpoint_before(machine2.third_phase) conductor = ProcessConductor( [starter1, starter2], [cp1_1, cp1_2, cp1_3, cp2_1, cp2_2, cp2_3] ) next(conductor) self.assertEqual(machine1.steps, []) next(conductor) self.assertEqual(machine1.steps, [1]) next(conductor) self.assertEqual(machine1.steps, [1, 2, 3]) next(conductor) self.assertEqual(machine2.steps, []) self.assertEqual(machine1.steps, [1, 2, 3]) next(conductor) self.assertEqual(machine2.steps, [1]) next(conductor) self.assertEqual(machine2.steps, [1, 2]) next(conductor) self.assertEqual(machine2.steps, [1, 2, 3])
def test_first_thread_finishes_then_second_starts(self): first_machine = ThreePhaseMachine() second_machine = ThreePhaseMachine() first_starter = ProcessPlayer(first_machine) cp1 = first_starter.add_checkpoint_after(first_machine.third_phase) second_starter = ProcessPlayer(second_machine) cp2 = second_starter.add_checkpoint_before(second_machine.first_phase) conductor = ProcessConductor([first_starter, second_starter], [cp1, cp2]) self.assertIs(next(conductor), cp1) self.assertEqual(first_machine.steps, [1, 2, 3]) self.assertEqual(second_machine.steps, []) self.assertIs(next(conductor), cp2) next(conductor) self.assertEqual(second_machine.steps, [1, 2, 3])