def setUp(self): """Run before tests.""" self.config = Config({ "namespace": "namespace", "stacks": [{ "name": "stack1" }, { "name": "stack2" }] }) self.persist_graph_raw_config = { 'namespace': 'test', 'cfngin_bucket': 'cfngin-test', 'cfngin_bucket_region': 'us-east-1', 'persistent_graph_key': 'test.json', 'stacks': [{ 'name': 'stack1' }, { 'name': 'stack2', 'requires': ['stack1'] }] } self.persist_graph_config = Config(self.persist_graph_raw_config)
def setUp(self): """Run before tests.""" self.config = Config({ "namespace": "namespace", "stacks": [{ "name": "stack1" }, { "name": "stack2" }], }) self.persist_graph_raw_config = { "namespace": "test", "cfngin_bucket": "cfngin-test", "cfngin_bucket_region": "us-east-1", "persistent_graph_key": "test.json", "stacks": [{ "name": "stack1" }, { "name": "stack2", "requires": ["stack1"] }], } self.persist_graph_config = Config(self.persist_graph_raw_config)
def test_config_build(self): """Test config build.""" vpc = Stack({"name": "vpc", "class_path": "blueprints.VPC"}) config = Config({"namespace": "prod", "stacks": [vpc]}) assert config.namespace == 'prod' assert config.stacks[0].name == 'vpc' assert config["namespace"] == 'prod' config.validate()
def test_context_bucket_name_is_overridden_but_is_none(self): """Test context bucket name is overridden but is none.""" config = Config({"namespace": "test", "cfngin_bucket": ""}) context = Context(config=config) self.assertEqual(context.bucket_name, None) config = Config({"namespace": "test", "cfngin_bucket": None}) context = Context(config=config) self.assertEqual(context.bucket_name, "stacker-test")
def test_config_validate_missing_stack_source_when_locked(self): """Test config validate missing stack source when locked.""" config = Config({ "namespace": "prod", "stacks": [ { "name": "bastion", "locked": True}]}) config.validate()
def test_config_validate_missing_name(self): """Test config validate missing name.""" config = Config( {"namespace": "prod", "stacks": [{"class_path": "blueprints.Bastion"}]} ) with self.assertRaises(exceptions.InvalidConfig) as ex: config.validate() error = ex.exception.errors["stacks"][0]["name"].errors[0] assert error.__str__() == "This field is required."
def test_config_validate_missing_stack_source(self): """Test config validate missing stack source.""" config = Config({"namespace": "prod", "stacks": [{"name": "bastion"}]}) with self.assertRaises(exceptions.InvalidConfig) as ex: config.validate() stack_errors = ex.exception.errors['stacks'][0] assert stack_errors['template_path'][0].__str__() == \ "class_path or template_path is required." assert stack_errors['class_path'][0].__str__() == \ "class_path or template_path is required."
def test_context_default_bucket_no_namespace(self): """Test context default bucket no namespace.""" context = Context(config=Config({"namespace": ""})) self.assertEqual(context.bucket_name, None) context = Context(config=Config({"namespace": None})) self.assertEqual(context.bucket_name, None) context = Context(config=Config({ "namespace": None, "cfngin_bucket": "" })) self.assertEqual(context.bucket_name, None)
def test_dump_unicode(self): """Test dump unicode.""" config = Config() config.namespace = "test" assert dump(config) == b"""namespace: test stacks: [] """ config = Config({"namespace": "test"}) # Ensure that we're producing standard yaml, that doesn't include # python specific objects. assert dump(config) != b"namespace: !!python/unicode 'test'\n" assert dump(config) == b"""namespace: test
def test_load_register_custom_lookups(self): """Test load register custom lookups.""" config = Config({ "lookups": { "custom": "importlib.import_module"}}) load(config) self.assertTrue(callable(CFNGIN_LOOKUP_HANDLERS["custom"]))
def test_config_validate_duplicate_stack_names(self): """Test config validate duplicate stack names.""" config = Config({ "namespace": "prod", "stacks": [ { "name": "bastion", "class_path": "blueprints.Bastion"}, { "name": "bastion", "class_path": "blueprints.BastionV2"}]}) with self.assertRaises(exceptions.InvalidConfig) as ex: config.validate() error = ex.exception.errors['stacks'][0] assert error.__str__() == "Duplicate stack bastion found at index 0."
def test_dump_complex(self): """Test dump complex.""" config = Config({ "namespace": "prod", "stacks": [ Stack({ "name": "vpc", "class_path": "blueprints.VPC"}), Stack({ "name": "bastion", "class_path": "blueprints.Bastion", "requires": ["vpc"]})]}) self.assertEqual(dump(config), b"""namespace: prod stacks: - class_path: blueprints.VPC enabled: true locked: false name: vpc protected: false termination_protection: false - class_path: blueprints.Bastion enabled: true locked: false name: bastion protected: false requires: - vpc termination_protection: false """)
def setUp(self): """Run before tests.""" self.context = Context(config=Config({ "namespace": "test", "stacker_bucket": "test" })) self.provider = mock_provider(region="us-east-1")
def setUp(self): """Run before tests.""" self.context = Context(config=Config({ 'namespace': 'test', 'stacker_bucket': 'test' })) self.provider = mock_provider(region="us-east-1")
def test_persistent_graph_location_no_bucket(self): """Return an empty dict if key is set but no bucket name.""" cp_config = self.persist_graph_raw_config.copy() cp_config["cfngin_bucket"] = "" context = Context(config=Config(cp_config)) self.assertEqual({}, context.persistent_graph_location)
def test_config_validate_stack_class_and_template_paths(self): """Test config validate stack class and template paths.""" config = Config({ "namespace": "prod", "stacks": [ { "name": "bastion", "class_path": "foo", "template_path": "bar"}]}) with self.assertRaises(exceptions.InvalidConfig) as ex: config.validate() stack_errors = ex.exception.errors['stacks'][0] assert stack_errors['template_path'][0].__str__() == \ "class_path cannot be present when template_path is provided." assert stack_errors['class_path'][0].__str__() == \ "template_path cannot be present when class_path is provided."
def test_context_optional_keys_set(self): """Test context optional keys set.""" context = Context( config=Config({}), stack_names=["stack"], ) self.assertEqual(context.mappings, {}) self.assertEqual(context.stack_names, ["stack"])
def test_lookup_with_sys_path(self): """Test lookup with sys path.""" config = Config({ "sys_path": "./tests/cfngin", "lookups": { "custom": "fixtures.mock_lookups.handler"}}) load(config) self.assertTrue(callable(CFNGIN_LOOKUP_HANDLERS["custom"]))
def mock_context(namespace="default", extra_config_args=None, **kwargs): """Mock context.""" config_args = {"namespace": namespace} if extra_config_args: config_args.update(extra_config_args) config = Config(config_args) if kwargs.get("environment"): return Context(config=config, **kwargs) return Context(config=config, environment={}, **kwargs)
def setUp(self): """Run before tests.""" self.sd = {"name": "test"} # pylint: disable=invalid-name self.config = Config({"namespace": "namespace"}) self.context = Context(config=self.config) self.stack = Stack( definition=generate_definition("vpc", 1), context=self.context, ) register_lookup_handler("noop", lambda **kwargs: "test")
def setUp(self): """Run before tests.""" self.config = Config({ "namespace": "namespace", "stacks": [{ "name": "stack1" }, { "name": "stack2" }] })
def test_persistent_graph_location_no_json(self): """'.json' appended to the key if it does not exist.""" cp_config = self.persist_graph_raw_config.copy() cp_config['persistent_graph_key'] = 'test' context = Context(config=Config(cp_config)) expected = { 'Bucket': 'cfngin-test', 'Key': 'persistent_graphs/test/test.json' } self.assertEqual(expected, context.persistent_graph_location)
def test_persistent_graph_location_no_json(self): """'.json' appended to the key if it does not exist.""" cp_config = self.persist_graph_raw_config.copy() cp_config["persistent_graph_key"] = "test" context = Context(config=Config(cp_config)) expected = { "Bucket": "cfngin-test", "Key": "persistent_graphs/test/test.json" } self.assertEqual(expected, context.persistent_graph_location)
def test_attributes(self): """Test class attributes.""" context = Context(config=Config({}), region="us-east-1") assert isinstance(context.config, Config) assert context.config_path == "./" assert context.bucket_region == "us-east-1" assert not context.environment # TODO check value assert isinstance(context.force_stacks, list) assert isinstance(context.hook_data, dict) assert context.s3_conn # TODO check value assert isinstance(context.stack_names, list)
def test_path_relative(self): """Test path relative.""" with self.temp_directory_with_files(["test/test.py"]) as temp_dir: results = self.run_hook( functions={"MyFunction": {"path": "test"}}, context=Context( config=Config({"namespace": "test", "stacker_bucket": "test"}), config_path=temp_dir.path, ), ) self.assertIsNotNone(results) code = results.get("MyFunction") self.assertIsInstance(code, Code) self.assert_s3_zip_file_list(code.S3Bucket, code.S3Key, ["test.py"])
def setUp(self): """Run before tests.""" self.context = Context(config=Config({ 'namespace': 'test', 'stacker_bucket': 'test' })) self.provider = mock_provider(region="us-east-1") self.mock_process = MockProcess() self.popen_mock = \ mock.patch('runway.cfngin.hooks.command.Popen', return_value=self.mock_process).start() self.devnull = mock.Mock() self.devnull_mock = \ mock.patch('runway.cfngin.hooks.command._devnull', return_value=self.devnull).start()
def test_path_relative(self): """Test path relative.""" with self.temp_directory_with_files(['test/test.py']) as temp_dir: results = self.run_hook(functions={'MyFunction': { 'path': 'test' }}, context=Context(config=Config({ 'namespace': 'test', 'stacker_bucket': 'test' }), config_path=temp_dir.path)) self.assertIsNotNone(results) code = results.get('MyFunction') self.assertIsInstance(code, Code) self.assert_s3_zip_file_list(code.S3Bucket, code.S3Key, ['test.py'])
def test_hook_with_sys_path(self): """Test hook with sys path.""" config = Config({ "namespace": "test", "sys_path": "./tests/unit/cfngin", "pre_build": [{ "data_key": "myHook", "path": "fixtures.mock_hooks.mock_hook", "required": True, "args": { "value": "mockResult" }, }], }) load(config) context = Context(config=config) stage = "pre_build" handle_hooks(stage, context.config[stage], "mock-region-1", context) self.assertEqual("mockResult", context.hook_data["myHook"]["result"])
def setUp(self): """Run before tests.""" self.provider = MagicMock() self.context = Context(config=Config({"namespace": "ns"}))
def test_load_adds_sys_path(self): """Test load adds sys path.""" config = Config({"sys_path": "/foo/bar"}) load(config) self.assertIn("/foo/bar", sys.path)