def test_plan_steps_listed_with_fqn(self): plan = Plan(description='Test', sleep_time=0) stack = Stack(definition=generate_definition('vpc', 1), context=self.context) plan.add(stack=stack, run_func=lambda x, y: (x, y)) steps = plan.list_pending() self.assertEqual(steps[0][0], stack.fqn)
def test_plan_steps_listed_with_fqn(self): plan = Plan(description="Test", sleep_time=0) stack = Stack(definition=generate_definition("vpc", 1), context=self.context) plan.add(stack=stack, run_func=lambda x, y: (x, y)) steps = plan.list_pending() self.assertEqual(steps[0][0], stack.fqn)
def test_step_must_return_status(self): plan = Plan(description='Test', sleep_time=0) stack = Stack(definition=generate_definition('vpc', 1), context=mock.MagicMock()) plan.add( stack=stack, run_func=lambda x, **kwargs: (x), ) with self.assertRaises(ValueError): plan.execute()
def test_execute_plan_ensure_parallel_builds(self): # key: stack_name, value: current iteration work_states = {} submitted_state = 0 # It takes 4 iterations for each task to finish finished_state = 3 def _run_func(stack, *args, **kwargs): if stack.name not in work_states: work_states[stack.name] = submitted_state return SUBMITTED if work_states[stack.name] == finished_state: return COMPLETE work_states[stack.name] += 1 return SUBMITTED vpc_stack = Stack(definition=generate_definition("vpc", 1), context=self.context) web_stack = Stack( definition=generate_definition("web", 2, requires=[vpc_stack.fqn]), context=self.context, ) db_stack = Stack( definition=generate_definition("db", 3, requires=[vpc_stack.fqn]), context=self.context, ) plan = Plan(description="Test", sleep_time=0) for stack in [vpc_stack, web_stack, db_stack]: plan.add( stack=stack, run_func=_run_func, requires=stack.requires, ) parallel_success = False while not plan._single_run(): vpc_step = plan[vpc_stack.fqn] web_step = plan[web_stack.fqn] db_step = plan[db_stack.fqn] if not vpc_step.completed: self.assertFalse(web_step.submitted) self.assertFalse(db_step.submitted) else: # If the vpc step is complete, and we see both the web & db # steps submitted during the same run, then parallel running # works if web_step.status == SUBMITTED and \ db_step.status == SUBMITTED: parallel_success = True self.assertTrue(parallel_success)
def test_execute_plan_ensure_parallel_builds(self): # key: stack_name, value: current iteration work_states = {} submitted_state = 0 # It takes 4 iterations for each task to finish finished_state = 3 def _run_func(stack, *args, **kwargs): if stack.name not in work_states: work_states[stack.name] = submitted_state return SUBMITTED if work_states[stack.name] == finished_state: return COMPLETE work_states[stack.name] += 1 return SUBMITTED vpc_stack = Stack(definition=generate_definition('vpc', 1), context=self.context) web_stack = Stack( definition=generate_definition('web', 2, requires=[vpc_stack.fqn]), context=self.context, ) db_stack = Stack( definition=generate_definition('db', 3, requires=[vpc_stack.fqn]), context=self.context, ) plan = Plan(description='Test', sleep_time=0) for stack in [vpc_stack, web_stack, db_stack]: plan.add( stack=stack, run_func=_run_func, requires=stack.requires, ) parallel_success = False while not plan._single_run(): vpc_step = plan[vpc_stack.fqn] web_step = plan[web_stack.fqn] db_step = plan[db_stack.fqn] if not vpc_step.completed: self.assertFalse(web_step.submitted) self.assertFalse(db_step.submitted) else: # If the vpc step is complete, and we see both the web & db # steps submitted during the same run, then parallel running # works if web_step.status == SUBMITTED and \ db_step.status == SUBMITTED: parallel_success = True self.assertTrue(parallel_success)
def test_execute_plan_wait_func_not_called_if_complete(self): wait_func = mock.MagicMock() plan = Plan(description="Test", wait_func=wait_func) def run_func(*args, **kwargs): return COMPLETE for i in range(2): stack = Stack(definition=generate_definition("vpc", i), context=self.context) plan.add(stack=stack, run_func=run_func, requires=stack.requires) plan.execute() self.assertEqual(wait_func.call_count, 0)
def test_reset_after_dump(self, *args): plan = Plan(description="Test", sleep_time=0) previous_stack = None for i in range(5): overrides = { "variables": { "PublicSubnets": "1", "SshKeyName": "1", "PrivateSubnets": "1", "Random": "${noop something}", }, } if previous_stack: overrides["requires"] = [previous_stack.fqn] stack = Stack( definition=generate_definition("vpc", i, **overrides), context=self.context, ) previous_stack = stack plan.add( stack=stack, run_func=self._run_func, requires=stack.requires, ) plan.dump("test", context=self.context) self.assertEqual(len(plan.list_pending()), len(plan))
def test_execute_plan_with_watchers(self, patched_multiprocessing): watch_func = mock.MagicMock() plan = Plan(description="Test", sleep_time=0, watch_func=watch_func) previous_stack = None for i in range(5): overrides = {} if previous_stack: overrides["requires"] = [previous_stack.fqn] stack = Stack( definition=generate_definition("vpc", i, **overrides), context=self.context, ) previous_stack = stack plan.add( stack=stack, run_func=self._run_func, requires=stack.requires, ) plan.execute() self.assertEqual(self.count, 9) self.assertEqual(len(plan.list_skipped()), 1) self.assertEqual(patched_multiprocessing.Process().start.call_count, 5) # verify we terminate the process when the stack is finished and also # redundantly terminate the process after execution self.assertEqual( patched_multiprocessing.Process().terminate.call_count, 10)
def test_dump_no_provider_lookups(self, *args): plan = Plan(description="Test", sleep_time=0) previous_stack = None for i in range(5): overrides = { "variables": { "Var1": "${output fakeStack::FakeOutput}", "Var2": "${xref fakeStack::FakeOutput2}", }, } if previous_stack: overrides["requires"] = [previous_stack.fqn] stack = Stack( definition=generate_definition("vpc", i, **overrides), context=self.context, ) previous_stack = stack plan.add( stack=stack, run_func=self._run_func, requires=stack.requires, ) with self.assertRaises(FailedVariableLookup): plan.dump("test", context=self.context)
def test_execute_plan_with_watchers(self, patched_multiprocessing): watch_func = mock.MagicMock() plan = Plan(description='Test', sleep_time=0, watch_func=watch_func) previous_stack = None for i in range(5): overrides = {} if previous_stack: overrides['requires'] = [previous_stack.fqn] stack = Stack( definition=generate_definition('vpc', i, **overrides), context=self.context, ) previous_stack = stack plan.add( stack=stack, run_func=self._run_func, requires=stack.requires, ) plan.execute() self.assertEqual(self.count, 9) self.assertEqual(len(plan.list_skipped()), 1) self.assertEqual(patched_multiprocessing.Process().start.call_count, 5) # verify we terminate the process when the stack is finished and also # redundantly terminate the process after execution self.assertEqual( patched_multiprocessing.Process().terminate.call_count, 10)
def test_reset_plan(self): plan = Plan(description="Test", sleep_time=0) previous_stack = None for i in range(5): overrides = {} if previous_stack: overrides["requires"] = [previous_stack.fqn] stack = Stack( definition=generate_definition("vpc", i, **overrides), context=self.context, ) previous_stack = stack plan.add( stack=stack, run_func=self._run_func, requires=stack.requires, ) plan.execute() self.assertEqual(self.count, 9) self.assertEqual(len(plan.list_skipped()), 1) plan.reset() self.assertEqual(len(plan.list_pending()), len(plan))
def test_step_must_return_status(self): plan = Plan(description="Test", sleep_time=0) stack = Stack(definition=generate_definition("vpc", 1), context=mock.MagicMock()) plan.add( stack=stack, run_func=lambda x, **kwargs: (x), ) with self.assertRaises(ValueError): plan.execute()
def test_reset_plan(self): plan = Plan(description='Test', sleep_time=0) previous_stack = None for i in range(5): overrides = {} if previous_stack: overrides['requires'] = [previous_stack.fqn] stack = Stack( definition=generate_definition('vpc', i, **overrides), context=self.context, ) previous_stack = stack plan.add( stack=stack, run_func=self._run_func, requires=stack.requires, ) plan.execute() self.assertEqual(self.count, 9) self.assertEqual(len(plan.list_skipped()), 1) plan.reset() self.assertEqual(len(plan.list_pending()), len(plan))
def test_execute_plan(self): plan = Plan(description="Test", sleep_time=0) previous_stack = None for i in range(5): overrides = {} if previous_stack: overrides["requires"] = [previous_stack.fqn] stack = Stack(definition=generate_definition("vpc", i, **overrides), context=self.context) previous_stack = stack plan.add(stack=stack, run_func=self._run_func, requires=stack.requires) plan.execute() self.assertEqual(self.count, 9) self.assertEqual(len(plan.list_skipped()), 1)
def test_execute_plan_wait_func_not_called_if_complete(self): wait_func = mock.MagicMock() plan = Plan(description="Test", wait_func=wait_func) def run_func(*args, **kwargs): return COMPLETE for i in range(2): stack = Stack(definition=generate_definition("vpc", i), context=self.context) plan.add( stack=stack, run_func=run_func, requires=stack.requires, ) plan.execute() self.assertEqual(wait_func.call_count, 0)
def test_dump_create_dirs(self): tmp_dir = tempfile.mkdtemp() try: plan = Plan(description="Test", sleep_time=0) previous_stack = None template_paths = [] for i in range(5): overrides = { "variables": { "PublicSubnets": "1", "SshKeyName": "1", "PrivateSubnets": "1", "Random": "${noop something}", }, } if previous_stack: overrides["requires"] = [previous_stack.fqn] stack = Stack( definition=generate_definition("vpc", i, **overrides), context=self.context, ) previous_stack = stack plan.add( stack=stack, run_func=self._run_func, requires=stack.requires, ) template_path = os.path.join( tmp_dir, stack_template_key_name(stack.blueprint)) template_paths.append(template_path) plan.dump(tmp_dir, context=self.context) for template_path in template_paths: self.assertTrue(os.path.isfile(template_path)) finally: shutil.rmtree(tmp_dir)
class TestPlan(unittest.TestCase): def setUp(self): self.plan = Plan() for i in range(4): self.plan.add(generate_definition('vpc', i)) def test_add(self): first_id = 'vpc.1' self.assertIn(first_id, self.plan) self.assertIsInstance(self.plan[first_id], BlueprintContext) def test_status(self): self.assertEqual(len(self.plan.list_submitted()), 0) self.assertEqual(len(self.plan.list_completed()), 0) self.assertEqual(len(self.plan.list_skipped()), 0) self.assertEqual(len(self.plan.list_pending()), 4) self.plan.submit('vpc.1') self.assertEqual(len(self.plan.list_submitted()), 1) self.assertEqual(len(self.plan.list_completed()), 0) self.assertEqual(len(self.plan.list_skipped()), 0) self.assertEqual(len(self.plan.list_pending()), 4) self.plan.complete('vpc.1') self.assertEqual(len(self.plan.list_submitted()), 0) self.assertEqual(len(self.plan.list_completed()), 1) self.assertEqual(len(self.plan.list_skipped()), 0) self.assertEqual(len(self.plan.list_pending()), 3) self.assertFalse(self.plan.completed) self.plan.skip('vpc.2') self.assertEqual(len(self.plan.list_submitted()), 0) self.assertEqual(len(self.plan.list_completed()), 1) self.assertEqual(len(self.plan.list_skipped()), 1) self.assertEqual(len(self.plan.list_pending()), 2) for i in range(4): self.plan.complete("vpc.%d" % i) self.assertTrue(self.plan.completed)
def test_plan_wait_func_must_be_function(self): with self.assertRaises(ImproperlyConfigured): Plan(description="Test", wait_func="invalid")
def setUp(self): self.plan = Plan() for i in range(4): self.plan.add(generate_definition('vpc', i))
class TestPlan(unittest.TestCase): def setUp(self): self.plan = Plan() for i in range(4): self.plan.add(generate_definition('vpc', i)) def test_add(self): first_id = 'vpc.1' self.assertIn(first_id, self.plan) self.assertIsInstance(self.plan[first_id], BlueprintContext) def test_status(self): self.assertEqual(len(self.plan.list_submitted()), 0) self.assertEqual(len(self.plan.list_completed()), 0) self.assertEqual(len(self.plan.list_pending()), 4) self.plan.submit('vpc.1') self.assertEqual(len(self.plan.list_submitted()), 1) self.assertEqual(len(self.plan.list_completed()), 0) self.assertEqual(len(self.plan.list_pending()), 4) self.plan.complete('vpc.1') self.assertEqual(len(self.plan.list_submitted()), 0) self.assertEqual(len(self.plan.list_completed()), 1) self.assertEqual(len(self.plan.list_pending()), 3) self.assertFalse(self.plan.completed) for i in range(4): self.plan.complete("vpc.%d" % i) self.assertTrue(self.plan.completed)
def test_plan_checkpoint_interval(self): plan = Plan(description="Test", logger_type=BASIC_LOGGER_TYPE) self.assertEqual(plan.check_point_interval, 10) plan = Plan(description="Test", logger_type=LOOP_LOGGER_TYPE) self.assertEqual(plan.check_point_interval, 1)