def test_parse_raw(self, monkeypatch: MonkeyPatch) -> None: """Test parse_raw.""" mock_resolve_raw_data = MagicMock() mock_parse_obj = MagicMock() mock_process_package_sources = MagicMock() monkeypatch.setattr(CfnginConfig, "resolve_raw_data", mock_resolve_raw_data) monkeypatch.setattr(CfnginConfig, "parse_obj", mock_parse_obj) monkeypatch.setattr(CfnginConfig, "process_package_sources", mock_process_package_sources) data = {"namespace": "test"} data_str = yaml.dump(data) mock_resolve_raw_data.return_value = data_str mock_parse_obj.return_value = data mock_process_package_sources.return_value = data_str assert CfnginConfig.parse_raw(data_str, skip_package_sources=True) == data mock_resolve_raw_data.assert_called_once_with(yaml.dump(data), parameters={}) mock_parse_obj.assert_called_once_with(data) mock_process_package_sources.assert_not_called() assert CfnginConfig.parse_raw(data_str, parameters={"key": "val"}) == data mock_resolve_raw_data.assert_called_with(yaml.dump(data), parameters={"key": "val"}) mock_process_package_sources.assert_called_once_with( data_str, parameters={"key": "val"}) assert mock_parse_obj.call_count == 2
def test_parse_file_find_config_file_value_error(self, monkeypatch: MonkeyPatch, tmp_path: Path) -> None: """Test parse_file with path raise ValueError.""" mock_find_config_file = MagicMock( return_value=[tmp_path / "01.yml", tmp_path / "02.yml"]) monkeypatch.setattr(CfnginConfig, "find_config_file", mock_find_config_file) with pytest.raises(ValueError) as excinfo: CfnginConfig.parse_file(path=tmp_path) assert str(excinfo.value).startswith("more than one")
def test_parse_file_file_path(self, tmp_path: Path) -> None: """Test parse_file with file_path.""" config_yml = tmp_path / "config.yml" data = {"namespace": "test"} config_yml.write_text(yaml.dump(data)) config = CfnginConfig.parse_file(file_path=config_yml) assert config.namespace == data["namespace"]
def test_tags_none(self) -> None: """Test tags None.""" obj = CfnginContext(config=CfnginConfig.parse_obj({ "namespace": "test", "tags": None })) assert obj.tags == {"cfngin_namespace": obj.config.namespace}
def _get_context( self, extra_config_args: Optional[Dict[str, Any]] = None, **kwargs: Any ) -> CfnginContext: """Get context.""" config = { "namespace": "namespace", "stacks": [ {"name": "vpc", "template_path": "."}, {"name": "bastion", "requires": ["vpc"], "template_path": "."}, { "name": "instance", "requires": ["vpc", "bastion"], "template_path": ".", }, { "name": "db", "requires": ["instance", "vpc", "bastion"], "template_path": ".", }, {"name": "other", "requires": ["db"], "template_path": "."}, ], } if extra_config_args: config.update(extra_config_args) return CfnginContext(config=CfnginConfig.parse_obj(config), **kwargs)
def test_tags_empty(self) -> None: """Test tags empty.""" obj = CfnginContext(config=CfnginConfig.parse_obj({ "namespace": "test", "tags": {} })) assert obj.tags == {}
def test_resolve_raw_data(self) -> None: """Test resolve_raw_data.""" raw_data = "namespace: ${namespace}" expected = "namespace: test" assert (CfnginConfig.resolve_raw_data(raw_data, parameters={"namespace": "test"}) == expected)
def setUp(self) -> None: """Run before tests.""" self.context = CfnginContext( config=CfnginConfig.parse_obj({ "namespace": "test", "cfngin_bucket": "test" })) self.provider = mock_provider(region="us-east-1")
def test_namespace_delimiter(self) -> None: """Test namespace_delimiter.""" config = CfnginConfig.parse_obj({ "namespace": "test", "namespace_delimiter": "." }) assert (CfnginContext( config=config).namespace_delimiter == config.namespace_delimiter)
def test_bucket_name_config(self, mocker: MockerFixture) -> None: """Test bucket_name from Config.""" mocker.patch.object(CfnginContext, "upload_to_s3", True) assert (CfnginContext( config=CfnginConfig.parse_obj({ "namespace": "test", "cfngin_bucket": "test-bucket" })).bucket_name == "test-bucket")
def test_parse_obj(self, monkeypatch: MonkeyPatch) -> None: """Test parse_obj.""" monkeypatch.setattr( MODULE + ".CfnginConfigDefinitionModel.parse_obj", lambda x: CfnginConfigDefinitionModel(namespace="success" ), # type: ignore ) assert CfnginConfig.parse_obj({}).namespace == "success"
def test_tags(self) -> None: """Test tags.""" obj = CfnginContext(config=CfnginConfig.parse_obj({ "namespace": "test", "tags": { "key": "val" } })) assert obj.tags == obj.config.tags
def cfngin_config(request: SubRequest, runway_config: RunwayConfig, runway_context: RunwayContext) -> CfnginConfig: """Find and return the CFNgin config.""" runway_config.deployments[0].resolve(runway_context, variables=runway_config.variables) return CfnginConfig.parse_file( path=Path(request.fspath).parent / "cfngin.yml", parameters=runway_config.deployments[0].parameters, )
def test_process_package_sources(self, mock_source_processor: MagicMock, monkeypatch: MonkeyPatch, tmp_path: Path) -> None: """Test process_package_sources.""" mock_resolve_raw_data = MagicMock(return_value="rendered") monkeypatch.setattr(CfnginConfig, "resolve_raw_data", mock_resolve_raw_data) mock_source_processor.return_value = mock_source_processor mock_source_processor.configs_to_merge = [] raw_data = "namespace: test" merge_data = "merged: value" other_config = tmp_path / "other_config.yml" other_config.write_text(merge_data) assert (CfnginConfig.process_package_sources( raw_data, parameters={"key": "val"}) == raw_data) mock_source_processor.assert_called_once_with( sources=CfnginPackageSourcesDefinitionModel(), cache_dir=None) mock_source_processor.get_package_sources.assert_called_once_with() mock_resolve_raw_data.assert_not_called() data = { "namespace": "test", "package_sources": { "git": [{ "uri": "something" }] } } raw_data = yaml.dump(data) mock_source_processor.configs_to_merge = [str(other_config.resolve())] assert (CfnginConfig.process_package_sources( raw_data, parameters={"key": "val"}) == "rendered") mock_source_processor.assert_called_with( sources=CfnginPackageSourcesDefinitionModel(git=[{ "uri": "something" }]), cache_dir=None, ) assert mock_source_processor.call_count == 2 expected = data.copy() expected["merged"] = "value" mock_resolve_raw_data.assert_called_once_with( yaml.dump(expected), parameters={"key": "val"})
def setUp(self) -> None: """Run before tests.""" self.context = CfnginContext( config=CfnginConfig.parse_obj({"namespace": "namespace"})) self.provider = MockProvider() self.deploy_action = deploy.Action( self.context, provider_builder=MockProviderBuilder( provider=self.provider), # type: ignore )
def setUp(self) -> None: """Run before tests.""" self.context = CfnginContext( config=CfnginConfig.parse_obj({ "namespace": "test", "cfngin_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()
def mock_context( namespace: str = "default", extra_config_args: Optional[Dict[str, Any]] = None, **kwargs: Any, ) -> CfnginContext: """Mock context.""" config_args = {"namespace": namespace} if extra_config_args: config_args.update(extra_config_args) config = CfnginConfig.parse_obj(config_args) if kwargs.get("environment"): return CfnginContext(config=config, **kwargs) return CfnginContext(config=config, environment={}, **kwargs)
def test_load( self, mock_sys: MagicMock, mock_register_lookup_handler: MagicMock, tmp_path: Path, ) -> None: """Test load.""" config = CfnginConfig(CfnginConfigDefinitionModel(namespace="test")) config.load() mock_sys.path.append.assert_not_called() mock_register_lookup_handler.assert_not_called() config.sys_path = tmp_path config.load() mock_sys.path.append.assert_called_once_with(str(config.sys_path)) mock_register_lookup_handler.assert_not_called() config.lookups = {"custom-lookup": "path"} config.load() mock_register_lookup_handler.assert_called_once_with( "custom-lookup", "path")
def test_persistent_graph_location_add_json(self) -> None: """Test persistent_graph_location adds `.json` extension.""" config = CfnginConfig.parse_obj({ "namespace": "test", "cfngin_bucket": "test-bucket", "persistent_graph_key": "something", }) obj = CfnginContext(config=config) assert obj.persistent_graph_location["Bucket"] == config.cfngin_bucket assert ( obj.persistent_graph_location["Key"] == f"persistent_graphs/{config.namespace}/{config.persistent_graph_key}.json" )
def test_mappings(self) -> None: """Test mappings.""" config = CfnginConfig.parse_obj({ "namespace": "test", "mappings": { "my_map": { "something": { "key": "val" } } } }) assert CfnginContext(config=config).mappings == config.mappings
def test_parse_file_find_config_file(self, monkeypatch: MonkeyPatch, tmp_path: Path) -> None: """Test parse_file with path.""" file_path = tmp_path / "test.yml" file_path.write_text("name: test\n") mock_find_config_file = MagicMock(return_value=[file_path]) mock_parse_raw = MagicMock(return_value=None) monkeypatch.setattr(CfnginConfig, "find_config_file", mock_find_config_file) monkeypatch.setattr(CfnginConfig, "parse_raw", mock_parse_raw) assert not CfnginConfig.parse_file(path=tmp_path) mock_find_config_file.assert_called_once_with(tmp_path) mock_parse_raw.assert_called_once_with(file_path.read_text(), path=file_path, parameters={})
def setUp(self) -> None: """Run before tests.""" self.count = 0 self.config = CfnginConfig.parse_obj({"namespace": "namespace"}) self.context = CfnginContext(config=self.config) class FakeLookup(LookupHandler): """False Lookup.""" # pylint: disable=arguments-differ @classmethod def handle(cls, value: str, *__args: Any, **__kwargs: Any) -> str: # type: ignore """Perform the lookup.""" return "test" register_lookup_handler("noop", FakeLookup)
def test_find_config_file(self, tmp_path: Path) -> None: """Test find_config_file.""" test_01 = tmp_path / "01-config.yaml" test_01.touch() test_02 = tmp_path / "02-config.yml" test_02.touch() test_03 = tmp_path / "03-config.yaml" test_03.touch() (tmp_path / "no-match").touch() (tmp_path / "buildspec.yml").touch() (tmp_path / "docker-compose.yml").touch() (tmp_path / "runway.yml").touch() (tmp_path / "runway.yaml").touch() (tmp_path / "runway.module.yml").touch() (tmp_path / "runway.module.yaml").touch() assert CfnginConfig.find_config_file(tmp_path) == [ test_01, test_02, test_03 ]
def setUp(self) -> None: """Run before tests.""" self.sd = {"name": "test"} # pylint: disable=invalid-name self.config = CfnginConfig.parse_obj({"namespace": "namespace"}) self.context = CfnginContext(config=self.config) self.stack = Stack(definition=generate_definition("vpc", 1), context=self.context) class FakeLookup(LookupHandler): """False Lookup.""" # pylint: disable=arguments-differ,unused-argument @classmethod def handle(cls, value: str, *__args: Any, **__kwargs: Any) -> str: # type: ignore """Perform the lookup.""" return "test" register_lookup_handler("noop", FakeLookup)
def test_path_relative(self) -> None: """Test path relative.""" with self.temp_directory_with_files(["test/test.py"]) as temp_dir: results = self.run_hook( functions={"MyFunction": { "path": "test" }}, context=CfnginContext( config=CfnginConfig.parse_obj({ "namespace": "test", "cfngin_bucket": "test" }), config_path=Path(str(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 _get_context(self, extra_config_args: Optional[Dict[str, Any]] = None, **kwargs: Any) -> CfnginContext: """Get context.""" config: Dict[str, Any] = { "namespace": "namespace", "stacks": [ { "name": "vpc", "template_path": "." }, { "name": "bastion", "template_path": ".", "variables": { "test": "${output vpc::something}" }, }, { "name": "db", "template_path": ".", "variables": { "test": "${output vpc::something}", "else": "${output bastion::something}", }, }, { "name": "other", "template_path": ".", "variables": {} }, ], } if extra_config_args: config.update(extra_config_args) return CfnginContext(config=CfnginConfig.parse_obj(config), **kwargs)
def setUp(self) -> None: """Run before tests.""" self.provider = MagicMock() self.context = CfnginContext( config=CfnginConfig.parse_obj({"namespace": "ns"}))
def test_resolve_raw_data_ignore_lookup(self) -> None: """Test resolve_raw_data ignores lookups.""" lookup_raw_data = "namespace: ${env something}" assert CfnginConfig.resolve_raw_data( lookup_raw_data) == lookup_raw_data
def test_find_config_file_file(self, tmp_path: Path) -> None: """Test find_config_file with file provided as path.""" test = tmp_path / "config.yml" test.touch() assert CfnginConfig.find_config_file(test) == [test]
def test_find_config_file_no_path(self, cd_tmp_path: Path) -> None: """Test find_config_file without providing a path.""" test = cd_tmp_path / "config.yml" test.touch() assert CfnginConfig.find_config_file() == [test]