class TestCFNginContext: # pylint: disable=too-many-public-methods """Test runway.context._cfngin.CFNginContext.""" config = CfnginConfig.parse_obj({ "namespace": "test", "stacks": [ { "name": "stack1", "template_path": "." }, { "name": "stack2", "template_path": "." }, ], }) env = DeployEnvironment(explicit_name="test") persist_graph_raw_config = { "namespace": "test", "cfngin_bucket": "cfngin-test", "cfngin_bucket_region": "us-east-1", "persistent_graph_key": "test.json", "stacks": [ { "name": "stack1", "template_path": "." }, { "name": "stack2", "template_path": ".", "requires": ["stack1"] }, ], } persist_graph_raw: Dict[str, Set[str]] = { "stack1": set(), "stack2": {"stack1"} } persist_graph_config = CfnginConfig.parse_obj(persist_graph_raw_config) @pytest.mark.parametrize( "namespace, expected", [ ("test", "test"), ("test-01", "test-01"), ("test.01", "test-01"), ("Test.01", "test-01"), ], ) def test_base_fqn(self, expected: str, namespace: str) -> None: """Test base_fqn.""" obj = CfnginContext( config=CfnginConfig.parse_obj({"namespace": namespace})) assert obj.base_fqn == expected 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_bucket_name_generated(self, mocker: MockerFixture) -> None: """Test bucket_name generated.""" mocker.patch.object(CfnginContext, "upload_to_s3", True) assert CfnginContext( config=self.config).bucket_name == "cfngin-test-us-east-1" def test_bucket_name_none(self, mocker: MockerFixture) -> None: """Test bucket_name is None.""" mocker.patch.object(CfnginContext, "upload_to_s3", False) assert CfnginContext().bucket_name is None def test_copy(self) -> None: """Test copy.""" obj = CfnginContext(deploy_environment=self.env) obj_copy = obj.copy() assert obj_copy != obj assert obj_copy.config == obj.config assert obj_copy.env != obj.env def test_get_fqn(self, mocker: MockerFixture) -> None: """Test get_fqn.""" mock_get_fqn = mocker.patch(f"{MODULE}.get_fqn", return_value="success") obj = CfnginContext(config=self.config) assert obj.get_fqn("name") == "success" mock_get_fqn.assert_called_once_with(obj.base_fqn, self.config.namespace_delimiter, "name") def test_get_stack(self) -> None: """Test get_stack.""" obj = CfnginContext(config=self.config) assert obj.get_stack("test-stack1") == obj.stacks[0] # namespace is added if not provided assert obj.get_stack("stack1") == obj.stacks[0] assert not obj.get_stack("dev-stack1") assert not obj.get_stack("stack12") def test_init(self, tmp_path: Path) -> None: """Test init.""" obj = CfnginContext( config=self.config, config_path=tmp_path, deploy_environment=self.env, force_stacks=["stack-01"], parameters={"key": "val"}, stack_names=["stack-02"], ) assert obj.bucket_region == self.env.aws_region assert obj.config == self.config assert obj.config_path == tmp_path assert obj.env == self.env assert obj.force_stacks == ["stack-01"] assert obj.hook_data == {} assert obj.logger assert obj.parameters == {"key": "val"} assert obj.stack_names == ["stack-02"] def test_init_defaults(self) -> None: """Test init defaults.""" obj = CfnginContext() assert obj.bucket_region == self.env.aws_region assert isinstance(obj.config, CfnginConfig) assert obj.config.namespace == "example" assert obj.config_path == Path.cwd() assert isinstance(obj.env, DeployEnvironment) assert obj.force_stacks == [] assert obj.hook_data == {} assert obj.logger assert obj.parameters == {} assert obj.stack_names == [] def test_lock_persistent_graph_locked(self, mocker: MockerFixture) -> None: """Test lock_persistent_graph no graph.""" mocker.patch.object(CfnginContext, "persistent_graph_locked", True) mocker.patch.object(CfnginContext, "persistent_graph", True) with pytest.raises(PersistentGraphLocked): CfnginContext().lock_persistent_graph("123") def test_lock_persistent_graph_no_graph(self, mocker: MockerFixture) -> None: """Test lock_persistent_graph no graph.""" mocker.patch.object(CfnginContext, "persistent_graph", None) assert CfnginContext().lock_persistent_graph("123") is None def test_lock_persistent_graph_no_such_key(self, mocker: MockerFixture) -> None: """Test lock_persistent_graph NoSuchKey.""" mocker.patch.object( CfnginContext, "persistent_graph_location", { "Bucket": "test-bucket", "Key": "something.json" }, ) mocker.patch.object(CfnginContext, "persistent_graph_locked", False) mocker.patch.object(CfnginContext, "persistent_graph", True) obj = CfnginContext() stubber = Stubber(obj.s3_client) stubber.add_client_error("put_object_tagging", "NoSuchKey") with stubber, pytest.raises(PersistentGraphCannotLock): obj.lock_persistent_graph("123") def test_lock_persistent_graph(self, mocker: MockerFixture) -> None: """Test lock_persistent_graph.""" mocker.patch.object( CfnginContext, "persistent_graph_location", { "Bucket": "test-bucket", "Key": "something.json" }, ) mocker.patch.object(CfnginContext, "persistent_graph_locked", False) mocker.patch.object(CfnginContext, "persistent_graph", True) obj = CfnginContext() stubber = Stubber(obj.s3_client) stubber.add_response( "put_object_tagging", {}, { "Tagging": { # pylint: disable=protected-access "TagSet": [{ "Key": obj._persistent_graph_lock_tag, "Value": "123" }] }, **obj.persistent_graph_location, }, ) with stubber: assert not obj.lock_persistent_graph("123") 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_namespace(self) -> None: """Test namespace.""" config = CfnginConfig.parse_obj({"namespace": "test"}) assert CfnginContext(config=config).namespace == config.namespace 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_persistent_graph_no_location(self, mocker: MockerFixture) -> None: """Test persistent_graph no persistent_graph_location.""" mocker.patch.object(CfnginContext, "persistent_graph_location", {}) assert CfnginContext().persistent_graph is None def test_persistent_graph_s3_not_verified(self, mocker: MockerFixture) -> None: """Test persistent_graph s3 not verified.""" mock_graph = mocker.patch( f"{MODULE}.Graph", MagicMock(from_dict=MagicMock(return_value="success"))) mocker.patch.object( CfnginContext, "persistent_graph_location", { "Bucket": "test-bucket", "key": "something.json" }, ) mocker.patch.object(CfnginContext, "s3_bucket_verified", False) obj = CfnginContext() assert obj.persistent_graph == "success" mock_graph.from_dict.assert_called_once_with({}, obj) def test_persistent_graph_no_such_key(self, mocker: MockerFixture) -> None: """Test persistent_graph NoSuchKey.""" mocker.patch.object( CfnginContext, "persistent_graph_location", { "Bucket": "test-bucket", "Key": "something.json" }, ) mocker.patch.object(CfnginContext, "s3_bucket_verified", True) obj = CfnginContext() stubber = Stubber(obj.s3_client) stubber.add_client_error("get_object", "NoSuchKey") stubber.add_response( "put_object", {}, { "Body": "{}".encode(), "ServerSideEncryption": "AES256", "ACL": "bucket-owner-full-control", "ContentType": "application/json", **obj.persistent_graph_location, }, ) with stubber: assert isinstance(obj.persistent_graph, Graph) assert obj.persistent_graph.to_dict() == {} def test_persistent_graph(self, mocker: MockerFixture) -> None: """Test persistent_graph.""" mocker.patch.object( CfnginContext, "persistent_graph_location", { "Bucket": "test-bucket", "Key": "something.json" }, ) mocker.patch.object(CfnginContext, "s3_bucket_verified", True) obj = CfnginContext() stubber = Stubber(obj.s3_client) stubber.add_response( "get_object", {"Body": gen_s3_object_content(self.persist_graph_raw)}, { "ResponseContentType": "application/json", **obj.persistent_graph_location, }, ) with stubber: assert isinstance(obj.persistent_graph, Graph) assert obj.persistent_graph.to_dict() == self.persist_graph_raw 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" ) @pytest.mark.parametrize( "config_ext", [ { "cfngin_bucket": "something" }, { "cfngin_bucket": "", "persistent_graph_key": "something" }, ], ) def test_persistent_graph_location_empty( self, config_ext: Dict[str, str]) -> None: """Test persistent_graph_location.""" config = CfnginConfig.parse_obj({"namespace": "test", **config_ext}) assert CfnginContext(config=config).persistent_graph_location == {} def test_persistent_graph_location(self) -> None: """Test persistent_graph_location.""" config = CfnginConfig.parse_obj({ "namespace": "test", "cfngin_bucket": "test-bucket", "persistent_graph_key": "something.json", }) 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}" ) def test_persistent_graph_lock_code_none(self, mocker: MockerFixture) -> None: """Test persistent_graph_lock_code None.""" mocker.patch.object(CfnginContext, "persistent_graph_location", False) assert not CfnginContext().persistent_graph_lock_code mocker.patch.object(CfnginContext, "persistent_graph_location", True) mocker.patch.object(CfnginContext, "persistent_graph_tags", {"key": "val"}) assert not CfnginContext().persistent_graph_lock_code def test_persistent_graph_lock_code(self, mocker: MockerFixture) -> None: """Test persistent_graph_lock_code.""" mocker.patch.object(CfnginContext, "persistent_graph_location", True) mocker.patch.object(CfnginContext, "persistent_graph_tags", {"cfngin_lock_code": "lock code"}) assert CfnginContext().persistent_graph_lock_code == "lock code" def test_persistent_graph_locked_no_code(self, mocker: MockerFixture) -> None: """Test persistent_graph_locked no persistent_graph_lock_code.""" mocker.patch.object(CfnginContext, "persistent_graph", True) mocker.patch.object(CfnginContext, "persistent_graph_lock_code", None) assert CfnginContext().persistent_graph_locked is False def test_persistent_graph_locked_no_graph(self, mocker: MockerFixture) -> None: """Test persistent_graph_locked no persistent_graph.""" mocker.patch.object(CfnginContext, "persistent_graph", {}) assert CfnginContext().persistent_graph_locked is False def test_persistent_graph_locked(self, mocker: MockerFixture) -> None: """Test persistent_graph_locked.""" mocker.patch.object(CfnginContext, "persistent_graph", True) mocker.patch.object(CfnginContext, "persistent_graph_lock_code", "something") assert CfnginContext().persistent_graph_locked is True def test_persistent_graph_tags_no_such_key(self, mocker: MockerFixture) -> None: """Test persistent_graph_tags NoSuchKey.""" mocker.patch.object( CfnginContext, "persistent_graph_location", { "Bucket": "test-bucket", "Key": "persistent_graphs/test/something.json" }, ) obj = CfnginContext() stubber = Stubber(obj.s3_client) stubber.add_client_error("get_object_tagging", "NoSuchKey") with stubber: assert obj.persistent_graph_tags == {} def test_persistent_graph_tags(self, mocker: MockerFixture) -> None: """Test persistent_graph_tags.""" bucket = "test-bucket" key = "persistent_graphs/test/something.json" mocker.patch.object(CfnginContext, "persistent_graph_location", { "Bucket": bucket, "Key": key }) obj = CfnginContext() stubber = Stubber(obj.s3_client) stubber.add_response("get_object_tagging", {"TagSet": []}, obj.persistent_graph_location) stubber.add_response( "get_object_tagging", {"TagSet": [{ "Key": "key", "Value": "val" }]}, obj.persistent_graph_location, ) with stubber: assert obj.persistent_graph_tags == {} assert obj.persistent_graph_tags == {"key": "val"} def test_put_persistent_graph_empty(self, mocker: MockerFixture) -> None: """Test put_persistent_graph empty.""" mocker.patch.object( CfnginContext, "persistent_graph_location", { "Bucket": "test-bucket", "Key": "something.json" }, ) obj = CfnginContext() obj.persistent_graph = Graph.from_dict({}, context=obj) stubber = Stubber(obj.s3_client) stubber.add_response("delete_object", {}, obj.persistent_graph_location) with stubber: assert not obj.put_persistent_graph("123") def test_put_persistent_graph_lock_code_mismatch( self, mocker: MockerFixture) -> None: """Test put_persistent_graph lock code mismatch.""" mocker.patch.object( CfnginContext, "persistent_graph_location", { "Bucket": "test-bucket", "Key": "something.json" }, ) mocker.patch.object(CfnginContext, "persistent_graph_locked", True) mocker.patch.object(CfnginContext, "persistent_graph_lock_code", "0") obj = CfnginContext() obj.persistent_graph = Graph.from_dict(self.persist_graph_raw, context=obj) with pytest.raises(PersistentGraphLockCodeMissmatch): obj.put_persistent_graph("123") def test_put_persistent_graph_not_locked(self, mocker: MockerFixture) -> None: """Test put_persistent_graph not locked.""" mocker.patch.object( CfnginContext, "persistent_graph_location", { "Bucket": "test-bucket", "Key": "something.json" }, ) mocker.patch.object(CfnginContext, "persistent_graph_locked", False) obj = CfnginContext() obj.persistent_graph = Graph.from_dict(self.persist_graph_raw, context=obj) with pytest.raises(PersistentGraphUnlocked): obj.put_persistent_graph("123") def test_put_persistent_graph_no_graph(self, mocker: MockerFixture) -> None: """Test put_persistent_graph n persistent_graph.""" mocker.patch.object(CfnginContext, "persistent_graph", False) assert not CfnginContext().put_persistent_graph("123") def test_put_persistent_graph(self, mocker: MockerFixture) -> None: """Test put_persistent_graph.""" mocker.patch.object( CfnginContext, "persistent_graph_location", { "Bucket": "test-bucket", "Key": "something.json" }, ) mocker.patch.object(CfnginContext, "persistent_graph_locked", True) mocker.patch.object(CfnginContext, "persistent_graph_lock_code", "123") obj = CfnginContext() obj.persistent_graph = Graph.from_dict(self.persist_graph_raw, context=obj) stubber = Stubber(obj.s3_client) stubber.add_response( "put_object", {}, { "Body": json.dumps(self.persist_graph_raw, default=json_serial, indent=4).encode(), "ServerSideEncryption": "AES256", "ACL": "bucket-owner-full-control", "ContentType": "application/json", "Tagging": "cfngin_lock_code=123", **obj.persistent_graph_location, }, ) with stubber: assert not obj.put_persistent_graph("123") def test_s3_bucket_verified_no_bucket(self, mocker: MockerFixture) -> None: """Test s3_bucket_verified no bucket.""" mocker.patch.object(CfnginContext, "bucket_name", None) assert CfnginContext().s3_bucket_verified is False def test_s3_bucket_verified(self, mocker: MockerFixture) -> None: """Test s3_bucket_verified.""" mock_ensure_s3_bucket = mocker.patch(f"{MODULE}.ensure_s3_bucket") mocker.patch.object(CfnginContext, "bucket_name", "test-bucket") mocker.patch.object(CfnginContext, "persistent_graph_location", {}) obj = CfnginContext() assert obj.s3_bucket_verified is True assert obj.s3_bucket_verified is True # value should be cached mock_ensure_s3_bucket.assert_called_once_with(obj.s3_client, obj.bucket_name, obj.bucket_region, persist_graph=False) def test_s3_client(self, mocker: MockerFixture) -> None: """Test s3_client.""" mock_client = MagicMock() mock_session = MagicMock(client=MagicMock(return_value=mock_client)) mock_get_session = mocker.patch.object(CfnginContext, "get_session", return_value=mock_session) assert CfnginContext( deploy_environment=self.env).s3_client == mock_client mock_get_session.assert_called_once_with(region=self.env.aws_region) mock_session.client.assert_called_once_with("s3") def test_set_hook_data_key_error(self) -> None: """Test set_hook_data KeyError.""" obj = CfnginContext() obj.set_hook_data("test", {}) with pytest.raises(KeyError): obj.set_hook_data("test", {"key": "val"}) @pytest.mark.parametrize("data", ["string", 1, 1.0, ["1"], {"1", "2"}, ("1", "2")]) def test_set_hook_data_type_error(self, data: Any) -> None: """Test set_hook_data TypeError.""" with pytest.raises(TypeError): CfnginContext().set_hook_data("test", data) # type: ignore def test_set_hook_data(self) -> None: """Test set_hook_data.""" obj = CfnginContext() obj.set_hook_data("test", {"key": "val"}) assert obj.hook_data == {"test": {"key": "val"}} def test_stacks_dict(self) -> None: """Test stacks_dict.""" obj = CfnginContext(config=self.config) assert obj.stacks_dict == { "test-stack1": obj.stacks[0], "test-stack2": obj.stacks[1], } def test_stacks(self) -> None: """Test stacks.""" obj = CfnginContext(config=self.config) assert len(obj.stacks) == len(self.config.stacks) assert isinstance(obj.stacks[0], Stack) assert obj.stacks[0].name == self.config.stacks[0].name assert isinstance(obj.stacks[1], Stack) assert obj.stacks[1].name == self.config.stacks[1].name def test_tags_empty(self) -> None: """Test tags empty.""" obj = CfnginContext(config=CfnginConfig.parse_obj({ "namespace": "test", "tags": {} })) assert obj.tags == {} 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 test_tags(self) -> None: """Test tags.""" obj = CfnginContext(config=CfnginConfig.parse_obj({ "namespace": "test", "tags": { "key": "val" } })) assert obj.tags == obj.config.tags def test_template_indent(self) -> None: """Test template_indent.""" assert (CfnginContext( config=self.config).template_indent == self.config.template_indent) @pytest.mark.parametrize( "config, expected", [ ({ "namespace": "test" }, True), ({ "namespace": "" }, False), ({ "namespace": "test", "cfngin_bucket": "" }, False), ({ "namespace": "", "cfngin_bucket": "something" }, True), ({ "namespace": "test", "cfngin_bucket": "something" }, True), ], ) def test_upload_to_s3(self, config: Dict[str, Any], expected: bool) -> None: """Test upload_to_s3.""" assert (CfnginContext( config=CfnginConfig.parse_obj(config)).upload_to_s3 is expected) def test_unlock_persistent_graph_empty_no_such_key( self, mocker: MockerFixture) -> None: """Test unlock_persistent_graph empty graph NoSuchKey.""" mocker.patch.object( CfnginContext, "persistent_graph_location", { "Bucket": "test-bucket", "Key": "something.json" }, ) obj = CfnginContext() obj.persistent_graph = Graph.from_dict({}, context=obj) stubber = Stubber(obj.s3_client) stubber.add_client_error("get_object", "NoSuchKey") with stubber: assert obj.unlock_persistent_graph("123") def test_unlock_persistent_graph_lock_code_mismatch( self, mocker: MockerFixture) -> None: """Test unlock_persistent_graph lock code mismatch.""" mocker.patch.object( CfnginContext, "persistent_graph_location", { "Bucket": "test-bucket", "Key": "something.json" }, ) mocker.patch.object(CfnginContext, "persistent_graph_locked", True) mocker.patch.object(CfnginContext, "persistent_graph_lock_code", "0") obj = CfnginContext() obj.persistent_graph = Graph.from_dict(self.persist_graph_raw, context=obj) with pytest.raises(PersistentGraphCannotUnlock): assert obj.unlock_persistent_graph("123") def test_unlock_persistent_graph_not_locked(self, mocker: MockerFixture) -> None: """Test unlock_persistent_graph.""" mocker.patch.object( CfnginContext, "persistent_graph_location", { "Bucket": "test-bucket", "Key": "something.json" }, ) mocker.patch.object(CfnginContext, "persistent_graph_locked", False) mocker.patch.object(CfnginContext, "persistent_graph_lock_code", "123") obj = CfnginContext() obj.persistent_graph = Graph.from_dict(self.persist_graph_raw, context=obj) with pytest.raises(PersistentGraphCannotUnlock): obj.unlock_persistent_graph("123") def test_unlock_persistent_graph_no_graph(self, mocker: MockerFixture) -> None: """Test unlock_persistent_graph no graph.""" mocker.patch.object(CfnginContext, "persistent_graph", False) assert CfnginContext().unlock_persistent_graph("123") def test_unlock_persistent_graph_no_such_key( self, mocker: MockerFixture) -> None: """Test unlock_persistent_graph empty graph NoSuchKey.""" mocker.patch.object( CfnginContext, "persistent_graph_location", { "Bucket": "test-bucket", "Key": "something.json" }, ) mocker.patch.object(CfnginContext, "persistent_graph_locked", True) mocker.patch.object(CfnginContext, "persistent_graph_lock_code", "123") obj = CfnginContext() obj.persistent_graph = Graph.from_dict({}, context=obj) stubber = Stubber(obj.s3_client) stubber.add_response( "get_object", {"Body": "{}".encode()}, { "ResponseContentType": "application/json", **obj.persistent_graph_location, }, ) stubber.add_client_error("delete_object_tagging", "NoSuchKey") with stubber: assert obj.unlock_persistent_graph("123") @pytest.mark.parametrize("graph_dict", cast(List[Dict[str, List[str]]], [{ "stack0": [] }, {}])) def test_unlock_persistent_graph(self, graph_dict: Dict[str, List[str]], mocker: MockerFixture) -> None: """Test unlock_persistent_graph.""" mocker.patch.object( CfnginContext, "persistent_graph_location", { "Bucket": "test-bucket", "Key": "something.json" }, ) mocker.patch.object(CfnginContext, "persistent_graph_locked", True) mocker.patch.object(CfnginContext, "persistent_graph_lock_code", "123") obj = CfnginContext() obj.persistent_graph = Graph.from_dict(graph_dict, context=obj) stubber = Stubber(obj.s3_client) if not graph_dict: stubber.add_response( "get_object", {"Body": "{}".encode()}, { "ResponseContentType": "application/json", **obj.persistent_graph_location, }, ) stubber.add_response("delete_object_tagging", {}, obj.persistent_graph_location) with stubber: assert obj.unlock_persistent_graph("123")
def runway_context(cd_test_dir: Path) -> RunwayContext: """Create Runway context.""" return RunwayContext(deploy_environment=DeployEnvironment( explicit_name="test", root_dir=cd_test_dir))
def deploy_environment(tmp_path: Path) -> DeployEnvironment: """Create a deploy environment that can be used for testing.""" return DeployEnvironment(explicit_name="test", root_dir=tmp_path)
class TestBaseContext: """Test runway.context._base.BaseContext.""" env = DeployEnvironment(explicit_name="test") def test_boto3_credentials(self, mocker: MockerFixture) -> None: """Test boto3_credentials.""" mocker.patch.object(self.env, "vars", TEST_ENV_CREDS) assert (BaseContext( deploy_environment=self.env).boto3_credentials == TEST_BOTO3_CREDS) def test_boto3_credentials_empty(self, mocker: MockerFixture) -> None: """Test boto3_credentials empty.""" mocker.patch.object(self.env, "vars", TEST_BOTO3_CREDS) assert BaseContext(deploy_environment=self.env).boto3_credentials == {} def test_current_aws_creds(self, mocker: MockerFixture) -> None: """Test current_aws_creds.""" mocker.patch.object(self.env, "vars", TEST_ENV_CREDS) assert (BaseContext( deploy_environment=self.env).current_aws_creds == TEST_ENV_CREDS) def test_current_aws_creds_empty(self, mocker: MockerFixture) -> None: """Test current_aws_creds empty.""" mocker.patch.object(self.env, "vars", TEST_BOTO3_CREDS) assert BaseContext(deploy_environment=self.env).current_aws_creds == {} def test_is_interactive(self, mocker: MockerFixture) -> None: """Test is_interactive.""" mocker.patch.object(self.env, "ci", False) ctx = BaseContext(deploy_environment=self.env) assert ctx.is_interactive mocker.patch.object(self.env, "ci", True) assert not ctx.is_interactive def test_is_noninteractive(self, mocker: MockerFixture) -> None: """Test is_noninteractive.""" mocker.patch.object(self.env, "ci", False) ctx = BaseContext(deploy_environment=self.env) assert not ctx.is_noninteractive mocker.patch.object(self.env, "ci", True) assert ctx.is_noninteractive def test_get_session(self, mock_boto3_session: MagicMock, mock_sso_botocore_session: MagicMock) -> None: """Test get_session.""" ctx = BaseContext(deploy_environment=self.env) assert ctx.get_session() == mock_boto3_session.return_value mock_boto3_session.assert_called_once_with( aws_access_key_id=None, aws_secret_access_key=None, aws_session_token=None, botocore_session=mock_sso_botocore_session.return_value, region_name=None, profile_name=None, ) mock_boto3_session.return_value._session.get_component.assert_called_once_with( "credential_provider") cred_provider = cast( MagicMock, mock_boto3_session.return_value._session.get_component. return_value, ) cred_provider.get_provider.assert_called_once_with("assume-role") provider = cast(MagicMock, cred_provider.get_provider.return_value) assert provider.cache == {} def test_get_session_with_creds( self, mock_boto3_session: MagicMock, mock_sso_botocore_session: MagicMock) -> None: """Test get_session with credentials.""" ctx = BaseContext(deploy_environment=self.env) assert ctx.get_session( **TEST_BOTO3_CREDS) == mock_boto3_session.return_value mock_boto3_session.assert_called_once_with( aws_access_key_id=TEST_BOTO3_CREDS["aws_access_key_id"], aws_secret_access_key=TEST_BOTO3_CREDS["aws_secret_access_key"], aws_session_token=TEST_BOTO3_CREDS["aws_session_token"], botocore_session=mock_sso_botocore_session.return_value, region_name=None, profile_name=None, ) def test_get_session_with_profile( self, mock_boto3_session: MagicMock, mock_sso_botocore_session: MagicMock) -> None: """Test get_session with profile.""" ctx = BaseContext(deploy_environment=self.env) assert ctx.get_session( profile="something") == mock_boto3_session.return_value mock_boto3_session.assert_called_once_with( aws_access_key_id=None, aws_secret_access_key=None, aws_session_token=None, botocore_session=mock_sso_botocore_session.return_value, region_name=None, profile_name="something", ) def test_get_session_with_region( self, mock_boto3_session: MagicMock, mock_sso_botocore_session: MagicMock) -> None: """Test get_session with region.""" ctx = BaseContext(deploy_environment=self.env) assert ctx.get_session( region="us-east-2") == mock_boto3_session.return_value mock_boto3_session.assert_called_once_with( aws_access_key_id=None, aws_secret_access_key=None, aws_session_token=None, botocore_session=mock_sso_botocore_session.return_value, region_name="us-east-2", profile_name=None, ) def test_sys_info(self) -> None: """Test sys_info.""" assert isinstance( BaseContext(deploy_environment=self.env).sys_info, SystemInfo)