def test_handle_provider_exception(self, mock_should_use, exception, default, caplog): """Test handle provider raise exception.""" caplog.set_level(logging.DEBUG, logger="runway.lookups.handlers.cfn") mock_should_use.return_value = True mock_provider = MagicMock(region="us-east-1") mock_provider.get_output.side_effect = exception raw_query = "test-stack.output1" if default: assert (CfnLookup.handle( raw_query + "::default=" + default, context=None, provider=mock_provider, ) == default) mock_should_use.assert_called_once_with({"default": default}, mock_provider) assert ("unable to resolve lookup for CloudFormation Stack output " '"{}"; using default'.format(raw_query)) in caplog.messages else: if isinstance(exception, (ClientError, StackDoesNotExist)): with pytest.raises(exception.__class__): assert not CfnLookup.handle( raw_query, context=None, provider=mock_provider) else: with pytest.raises(OutputDoesNotExist) as excinfo: assert not CfnLookup.handle( raw_query, context=None, provider=mock_provider) assert excinfo.value.stack_name == "test-stack" assert excinfo.value.output == "output1" mock_should_use.assert_called_once_with({}, mock_provider) mock_provider.get_output.assert_called_once_with( "test-stack", "output1")
def test_handle_exception(self, mock_should_use, exception, default, caplog, monkeypatch): """Test handle cls.get_stack_output raise exception.""" caplog.set_level(logging.DEBUG, logger="runway.lookups.handlers.cfn") mock_context = MagicMock(name="context") mock_session = MagicMock(name="session") mock_context.get_session.return_value = mock_session mock_session.client.return_value = mock_session mock_should_use.return_value = False monkeypatch.setattr(CfnLookup, "get_stack_output", MagicMock()) CfnLookup.get_stack_output.side_effect = exception raw_query = "test-stack.output1" query = OutputQuery(*raw_query.split(".")) if default: assert (CfnLookup.handle(raw_query + "::default=" + default, mock_context) == default) mock_should_use.assert_called_once_with({"default": default}, None) assert ("unable to resolve lookup for CloudFormation Stack output " '"{}"; using default'.format(raw_query)) in caplog.messages else: if isinstance(exception, (ClientError, StackDoesNotExist)): with pytest.raises(exception.__class__): assert not CfnLookup.handle(raw_query, mock_context) else: with pytest.raises(OutputDoesNotExist) as excinfo: assert not CfnLookup.handle(raw_query, mock_context) assert excinfo.value.stack_name == "test-stack" assert excinfo.value.output == "output1" mock_should_use.assert_called_once_with({}, None) mock_context.get_session.assert_called_once() mock_session.client.assert_called_once_with("cloudformation") CfnLookup.get_stack_output.assert_called_once_with(mock_session, query)
def test_handle(self, mocker: MockerFixture) -> None: """Test handle.""" mock_format_results = mocker.patch.object(CfnLookup, "format_results", return_value="success") mock_get_stack_output = mocker.patch.object(CfnLookup, "get_stack_output", return_value="cls.success") mock_should_use = mocker.patch.object(CfnLookup, "should_use_provider", side_effect=[True, False]) mock_context = MagicMock(name="context") mock_session = MagicMock(name="session") mock_context.get_session.return_value = mock_session mock_session.client.return_value = mock_session mock_provider = MagicMock(name="provider") mock_provider.get_output.return_value = "provider.success" raw_query = "test-stack.output1" query = OutputQuery(*raw_query.split(".")) region = "us-west-2" args = "::region={region}".format(region=region) value = raw_query + args mock_parse = mocker.patch.object(CfnLookup, "parse", return_value=(raw_query, { "region": region })) # test happy path when used from CFNgin (provider) assert (CfnLookup.handle(value, context=mock_context, provider=mock_provider) == "success") mock_parse.assert_called_once_with(value) mock_provider.get_output.assert_called_once_with(*query) mock_should_use.assert_called_once_with({"region": region}, mock_provider) mock_format_results.assert_called_once_with("provider.success", region=region) mock_context.get_session.assert_not_called() mock_get_stack_output.assert_not_called() # test happy path when use from runway (no provider) assert CfnLookup.handle(value, context=mock_context) == "success" mock_should_use.assert_called_with({"region": region}, None) mock_context.get_session.assert_called_once_with(region=region) mock_session.client.assert_called_once_with("cloudformation") mock_get_stack_output.assert_called_once_with(mock_session, query) mock_format_results.assert_called_with("cls.success", region=region)
def test_handle_valueerror(self, runway_context: MockRunwayContext) -> None: """Test handle raising ValueError.""" with pytest.raises(ValueError) as excinfo: assert CfnLookup.handle("something", runway_context) assert (str(excinfo.value) == 'query must be <stack-name>.<output-name>; got "something"')
def test_should_use_provider_falsy(self, args, provider, caplog): """Test should_use_provider with falsy cases.""" caplog.set_level(logging.DEBUG, logger="runway.lookups.handlers.cfn") assert not CfnLookup.should_use_provider(args, provider) if provider: assert ("not using provider; requested region does not match" in caplog.messages) assert "using provider" not in caplog.messages
def test_should_use_provider_truthy( self, args: Dict[str, Any], caplog: LogCaptureFixture, provider: Optional[Provider], ) -> None: """Test should_use_provider with truthy cases.""" caplog.set_level(logging.DEBUG, logger="runway.lookups.handlers.cfn") assert CfnLookup.should_use_provider(args, provider) assert "using provider" in caplog.messages
def test_should_use_provider_falsy( self, args: Dict[str, Any], caplog: LogCaptureFixture, provider: Optional[Provider], ) -> None: """Test should_use_provider with falsy cases.""" caplog.set_level(logging.DEBUG, logger="runway.lookups.handlers.cfn") assert not CfnLookup.should_use_provider(args, provider) if provider: assert ("not using provider; requested region does not match" in caplog.messages) assert "using provider" not in caplog.messages
def test_get_stack_output_clienterror(self, caplog): """Test get_stack_output raising ClientError.""" caplog.set_level(logging.DEBUG, logger="runway.lookups.handlers.cfn") client, stubber = setup_cfn_client() stack_name = "test-stack" query = OutputQuery(stack_name, "output1") stubber.add_client_error( "describe_stacks", service_error_code="ValidationError", service_message="Stack %s does not exist" % stack_name, expected_params={"StackName": stack_name}, ) with stubber, pytest.raises(ClientError): assert CfnLookup.get_stack_output(client, query) stubber.assert_no_pending_responses() assert "describing stack: %s" % stack_name in caplog.messages
def test_get_stack_output(self, caplog: LogCaptureFixture) -> None: """Test get_stack_output.""" caplog.set_level(logging.DEBUG, logger="runway.lookups.handlers.cfn") client, stubber = setup_cfn_client() stack_name = "test-stack" outputs = {"output1": "val1", "output2": "val2"} query = OutputQuery(stack_name, "output1") stubber.add_response( "describe_stacks", {"Stacks": [generate_describe_stacks_stack(stack_name, outputs)]}, {"StackName": stack_name}, ) with stubber: assert CfnLookup.get_stack_output(client, query) == "val1" stubber.assert_no_pending_responses() assert "describing stack: %s" % stack_name in caplog.messages assert ("{} stack outputs: {}".format(stack_name, json.dumps(outputs)) in caplog.messages)
def test_should_use_provider_truthy(self, args, provider, caplog): """Test should_use_provider with truthy cases.""" caplog.set_level(logging.DEBUG, logger="runway.lookups.handlers.cfn") assert CfnLookup.should_use_provider(args, provider) assert "using provider" in caplog.messages
def test_handle_valueerror(self): """Test handle raising ValueError.""" with pytest.raises(ValueError) as excinfo: assert CfnLookup.handle("something", None) assert (str(excinfo.value) == 'query must be <stack-name>.<output-name>; got "something"')