예제 #1
0
class TestConnectionManager(object):
    def setup_method(self, test_method):
        self.iam_role = None
        self.region = "eu-west-1"

        self.connection_manager = ConnectionManager(region=self.region,
                                                    iam_role=self.iam_role)

    def test_connection_manager_initialised_with_all_parameters(self):
        connection_manager = ConnectionManager(region=self.region,
                                               iam_role=self.iam_role)
        assert connection_manager.iam_role == self.iam_role
        assert connection_manager.region == self.region
        assert connection_manager._boto_session is None
        assert connection_manager.clients == {}

    def test_connection_manager_initialised_with_no_optional_parameters(self):
        connection_manager = ConnectionManager(region=sentinel.region)

        assert connection_manager.iam_role is None
        assert connection_manager.region == sentinel.region
        assert connection_manager._boto_session is None
        assert connection_manager.clients == {}

    def test_repr(self):
        self.connection_manager.iam_role = "role"
        self.connection_manager.region = "region"
        response = self.connection_manager.__repr__()
        assert response == "sceptre.connection_manager.ConnectionManager(" \
            "region='region', iam_role='role')"

    def test_boto_session_with_cache(self):
        self.connection_manager._boto_session = sentinel.boto_session
        assert self.connection_manager.boto_session == sentinel.boto_session

    @patch("sceptre.connection_manager.boto3.session.Session")
    def test_boto_session_with_no_iam_role_and_no_cache(self, mock_Session):
        mock_Session = MagicMock(name='Session', return_value=sentinel.session)
        mock_Session.get_credentials.access_key.return_value = \
            sentinel.access_key
        mock_Session.get_credentials.secret_key.return_value = \
            sentinel.secret_key
        mock_Session.get_credentials.method.return_value = \
            sentinel.method

        self.connection_manager._boto_session = None
        self.connection_manager.iam_role = None

        boto_session = self.connection_manager.boto_session
        assert boto_session.isinstance(mock_Session(region_name="eu-west-1"))
        mock_Session.assert_called_once_with(region_name="eu-west-1")

    @patch("sceptre.connection_manager.boto3.session.Session")
    @patch("sceptre.connection_manager.boto3.client")
    def test_boto_session_with_iam_role_and_no_cache(self, mock_client,
                                                     mock_Session):
        mock_Session.return_value = sentinel.session
        self.connection_manager.iam_role = "non-default"
        mock_credentials = {
            "Credentials": {
                "AccessKeyId": "id",
                "SecretAccessKey": "key",
                "SessionToken": "token"
            }
        }
        mock_sts_client = Mock()
        mock_sts_client.assume_role.return_value = mock_credentials
        mock_client.return_value = mock_sts_client

        boto_session = self.connection_manager.boto_session

        assert boto_session == sentinel.session
        mock_Session.assert_called_once_with(aws_access_key_id="id",
                                             aws_secret_access_key="key",
                                             aws_session_token="token",
                                             region_name=self.region)

    @patch("sceptre.connection_manager.boto3.session.Session")
    def test_two_boto_sessions(self, mock_Session):
        self.connection_manager._boto_session = None
        boto_session_1 = self.connection_manager.boto_session
        boto_session_2 = self.connection_manager.boto_session
        assert boto_session_1 == boto_session_2

    @patch("sceptre.connection_manager.boto3.session.Session.get_credentials")
    def test_get_client_with_no_pre_existing_clients(self,
                                                     mock_get_credentials):
        service = "s3"

        client = self.connection_manager._get_client(service)
        expected_client = Session().client(service)
        assert str(type(client)) == str(type(expected_client))

    @patch("sceptre.connection_manager.boto3.session.Session.get_credentials")
    def test_get_client_with_invalid_client_type(self, mock_get_credentials):
        service = "invalid_type"
        with pytest.raises(botocore.exceptions.UnknownServiceError):
            self.connection_manager._get_client(service)

    @patch("sceptre.connection_manager.boto3.session.Session.get_credentials")
    def test_get_client_with_exisiting_client(self, mock_get_credentials):
        service = "cloudformation"
        client_1 = self.connection_manager._get_client(service)
        client_2 = self.connection_manager._get_client(service)
        assert client_1 == client_2

    @mock_s3
    def test_call_with_valid_service_and_call(self):
        service = 's3'
        command = 'list_buckets'

        return_value = self.connection_manager.call(service, command, {})
        assert return_value['ResponseMetadata']['HTTPStatusCode'] == 200
예제 #2
0
class TestConnectionManager(object):
    def setup_method(self, test_method):
        self.iam_role = None
        self.profile = None
        self.region = "eu-west-1"

        self.connection_manager = ConnectionManager(region=self.region,
                                                    iam_role=self.iam_role,
                                                    profile=self.profile)

    def test_connection_manager_initialised_with_all_parameters(self):
        connection_manager = ConnectionManager(region=self.region,
                                               iam_role="role",
                                               profile="profile")
        assert connection_manager.iam_role == "role"
        assert connection_manager.profile == "profile"
        assert connection_manager.region == self.region
        assert connection_manager._boto_session is None
        assert connection_manager.clients == {}

    def test_connection_manager_initialised_with_no_optional_parameters(self):
        connection_manager = ConnectionManager(region=sentinel.region)

        assert connection_manager.iam_role is None
        assert connection_manager.profile is None
        assert connection_manager.region == sentinel.region
        assert connection_manager._boto_session is None
        assert connection_manager.clients == {}

    def test_repr(self):
        self.connection_manager.iam_role = "role"
        self.connection_manager.profile = "profile"
        self.connection_manager.region = "region"
        response = self.connection_manager.__repr__()
        assert response == "sceptre.connection_manager.ConnectionManager(" \
            "region='region', iam_role='role', profile='profile')"

    def test_boto_session_with_cache(self):
        self.connection_manager._boto_session = sentinel.boto_session
        assert self.connection_manager.boto_session == sentinel.boto_session

    @patch("sceptre.connection_manager.boto3.session.Session")
    def test_boto_session_with_no_iam_role_and_no_profile(self, mock_Session):
        self.connection_manager._boto_session = None
        self.connection_manager.iam_role = None
        self.connection_manager.profile = None

        boto_session = self.connection_manager.boto_session
        assert boto_session.isinstance(mock_Session)
        mock_Session.assert_called_once_with(region_name="eu-west-1",
                                             profile_name=None)

    @patch("sceptre.connection_manager.boto3.session.Session")
    def test_boto_session_with_no_iam_role_and_profile(self, mock_Session):
        self.connection_manager._boto_session = None
        self.connection_manager.iam_role = None
        self.connection_manager.profile = "profile"

        boto_session = self.connection_manager.boto_session
        assert boto_session.isinstance(mock_Session)
        mock_Session.assert_called_once_with(region_name="eu-west-1",
                                             profile_name="profile")

    @patch("sceptre.connection_manager.boto3.session.Session")
    def test_boto_session_with_iam_role_and_no_profile(self, mock_Session):
        self.connection_manager._boto_session = None
        self.connection_manager.iam_role = "non-default"
        self.connection_manager.profile = None

        mock_credentials = {
            "Credentials": {
                "AccessKeyId": "id",
                "SecretAccessKey": "key",
                "SessionToken": "token",
                "Expiration": datetime(2020, 1, 1)
            }
        }

        mock_Session.return_value.client.return_value.\
            assume_role.return_value = mock_credentials

        boto_session = self.connection_manager.boto_session
        assert boto_session.isinstance(mock_Session)

        mock_Session.assert_any_call(profile_name=None,
                                     region_name=self.region)
        mock_Session.assert_any_call(aws_access_key_id="id",
                                     aws_secret_access_key="key",
                                     aws_session_token="token",
                                     region_name=self.region)

    @patch("sceptre.connection_manager.boto3.session.Session")
    def test_boto_session_with_iam_role_and_profile(self, mock_Session):
        self.connection_manager._boto_session = None
        self.connection_manager.iam_role = "non-default"
        self.connection_manager.profile = "profile"

        mock_credentials = {
            "Credentials": {
                "AccessKeyId": "id",
                "SecretAccessKey": "key",
                "SessionToken": "token",
                "Expiration": datetime(2020, 1, 1)
            }
        }

        mock_Session.return_value.client.return_value. \
            assume_role.return_value = mock_credentials

        boto_session = self.connection_manager.boto_session
        assert boto_session.isinstance(mock_Session)

        mock_Session.assert_any_call(profile_name="profile",
                                     region_name=self.region)
        mock_Session.assert_any_call(aws_access_key_id="id",
                                     aws_secret_access_key="key",
                                     aws_session_token="token",
                                     region_name=self.region)

    @patch("sceptre.connection_manager.boto3.session.Session")
    def test_two_boto_sessions(self, mock_Session):
        self.connection_manager._boto_session = None
        boto_session_1 = self.connection_manager.boto_session
        boto_session_2 = self.connection_manager.boto_session
        assert boto_session_1 == boto_session_2

    @patch("sceptre.connection_manager.boto3.session.Session.get_credentials")
    def test_get_client_with_no_pre_existing_clients(self,
                                                     mock_get_credentials):
        service = "s3"

        client = self.connection_manager._get_client(service)
        expected_client = Session().client(service)
        assert str(type(client)) == str(type(expected_client))

    @patch("sceptre.connection_manager.boto3.session.Session.get_credentials")
    def test_get_client_with_invalid_client_type(self, mock_get_credentials):
        service = "invalid_type"
        with pytest.raises(UnknownServiceError):
            self.connection_manager._get_client(service)

    @patch("sceptre.connection_manager.boto3.session.Session.get_credentials")
    def test_get_client_with_exisiting_client(self, mock_get_credentials):
        service = "cloudformation"
        client_1 = self.connection_manager._get_client(service)
        client_2 = self.connection_manager._get_client(service)
        assert client_1 == client_2

    @patch("sceptre.connection_manager.boto3.session.Session.get_credentials")
    def test_get_client_with_exisiting_client_and_iam_role_none(
            self, mock_get_credentials):
        service = "cloudformation"
        self.connection_manager._iam_role = None
        client_1 = self.connection_manager._get_client(service)
        client_2 = self.connection_manager._get_client(service)
        assert client_1 == client_2

    def test_clear_session_cache_if_expired_with_no_iam_role(self):
        self.connection_manager.iam_role = None
        self.connection_manager._boto_session_expiration = sentinel.expiration
        self.connection_manager.clients = sentinel.clients
        self.connection_manager._boto_session = sentinel.boto_session
        self.connection_manager._clear_session_cache_if_expired()
        assert self.connection_manager.clients == sentinel.clients
        assert self.connection_manager._boto_session == sentinel.boto_session

    @freeze_time("2000-01-30")
    def test_clear_session_cache_if_expired_with_future_date(self):
        self.connection_manager.iam_role = "iam_role"
        future_date = datetime(2015, 1, 30, tzinfo=tz.tzutc())
        self.connection_manager._boto_session_expiration = future_date
        self.connection_manager.clients = sentinel.clients
        self.connection_manager._boto_session = sentinel.boto_session
        self.connection_manager._clear_session_cache_if_expired()
        assert self.connection_manager.clients == sentinel.clients
        assert self.connection_manager._boto_session == sentinel.boto_session

    @freeze_time("2015-01-30")
    def test_clear_session_cache_if_expired_with_expired_date(self):
        self.connection_manager.iam_role = "iam_role"
        past_date = datetime(2000, 1, 30, tzinfo=tz.tzutc())
        self.connection_manager._boto_session_expiration = past_date

        self.connection_manager.clients = sentinel.clients
        self.connection_manager._boto_session = sentinel.boto_session

        self.connection_manager._clear_session_cache_if_expired()
        assert self.connection_manager.clients == {}
        assert self.connection_manager._boto_session is None

    @mock_s3
    def test_call_with_valid_service_and_call(self):
        service = 's3'
        command = 'list_buckets'

        return_value = self.connection_manager.call(service, command, {})
        assert return_value['ResponseMetadata']['HTTPStatusCode'] == 200
예제 #3
0
class TestConnectionManager(object):
    def setup_method(self, test_method):
        self.stack_name = None
        self.profile = None
        self.region = "eu-west-1"

        ConnectionManager._boto_sessions = {}
        ConnectionManager._clients = {}
        ConnectionManager._stack_keys = {}

        # Temporary workaround for https://github.com/spulec/moto/issues/1924
        os.environ.setdefault("AWS_ACCESS_KEY_ID", "sceptre_test_key_id")
        os.environ.setdefault("AWS_SECRET_ACCESS_KEY",
                              "sceptre_test_access_key")

        self.connection_manager = ConnectionManager(region=self.region,
                                                    stack_name=self.stack_name,
                                                    profile=self.profile)

    def test_connection_manager_initialised_with_no_optional_parameters(self):
        connection_manager = ConnectionManager(region=sentinel.region)

        assert connection_manager.stack_name is None
        assert connection_manager.profile is None
        assert connection_manager.region == sentinel.region
        assert connection_manager._boto_sessions == {}
        assert connection_manager._clients == {}
        assert connection_manager._stack_keys == {}

    def test_connection_manager_initialised_with_all_parameters(self):
        connection_manager = ConnectionManager(region=self.region,
                                               stack_name="stack",
                                               profile="profile")

        assert connection_manager.stack_name == "stack"
        assert connection_manager.profile == "profile"
        assert connection_manager.region == self.region
        assert connection_manager._boto_sessions == {}
        assert connection_manager._clients == {}
        assert connection_manager._stack_keys == {
            "stack": (self.region, "profile")
        }

    def test_repr(self):
        self.connection_manager.stack_name = "stack"
        self.connection_manager.profile = "profile"
        self.connection_manager.region = "region"
        response = self.connection_manager.__repr__()
        assert response == "sceptre.connection_manager.ConnectionManager(" \
            "region='region', profile='profile', stack_name='stack')"

    def test_boto_session_with_cache(self):
        self.connection_manager._boto_sessions["test"] = sentinel.boto_session

        boto_session = self.connection_manager._boto_sessions["test"]
        assert boto_session == sentinel.boto_session

    @patch("sceptre.connection_manager.boto3.session.Session")
    def test_boto_session_with_no_profile(self, mock_Session):
        self.connection_manager._boto_sessions = {}
        self.connection_manager.profile = None

        boto_session = self.connection_manager._get_session(
            self.connection_manager.profile, self.region)

        assert boto_session.isinstance(mock_Session)
        mock_Session.assert_called_once_with(profile_name=None,
                                             region_name="eu-west-1",
                                             aws_access_key_id=ANY,
                                             aws_secret_access_key=ANY,
                                             aws_session_token=ANY)

    @patch("sceptre.connection_manager.boto3.session.Session")
    def test_boto_session_with_profile(self, mock_Session):
        self.connection_manager._boto_sessions = {}
        self.connection_manager.profile = "profile"

        boto_session = self.connection_manager._get_session(
            self.connection_manager.profile, self.region)

        assert boto_session.isinstance(mock_Session)
        mock_Session.assert_called_once_with(profile_name="profile",
                                             region_name="eu-west-1",
                                             aws_access_key_id=ANY,
                                             aws_secret_access_key=ANY,
                                             aws_session_token=ANY)

    @patch("sceptre.connection_manager.boto3.session.Session")
    def test_two_boto_sessions(self, mock_Session):
        self.connection_manager._boto_sessions = {
            "one": mock_Session,
            "two": mock_Session
        }

        boto_session_1 = self.connection_manager._boto_sessions["one"]
        boto_session_2 = self.connection_manager._boto_sessions["two"]
        assert boto_session_1 == boto_session_2

    @patch("sceptre.connection_manager.boto3.session.Session.get_credentials")
    def test_get_client_with_no_pre_existing_clients(self,
                                                     mock_get_credentials):
        service = "s3"
        region = "eu-west-1"
        profile = None
        stack = self.stack_name

        client = self.connection_manager._get_client(service, region, profile,
                                                     stack)
        expected_client = Session().client(service)
        assert str(type(client)) == str(type(expected_client))

    @patch("sceptre.connection_manager.boto3.session.Session.get_credentials")
    def test_get_client_with_invalid_client_type(self, mock_get_credentials):
        service = "invalid_type"
        region = "eu-west-1"
        profile = None
        stack = self.stack_name

        with pytest.raises(UnknownServiceError):
            self.connection_manager._get_client(service, region, profile,
                                                stack)

    @patch("sceptre.connection_manager.boto3.session.Session.get_credentials")
    def test_get_client_with_exisiting_client(self, mock_get_credentials):
        service = "cloudformation"
        region = "eu-west-1"
        profile = None
        stack = self.stack_name

        client_1 = self.connection_manager._get_client(service, region,
                                                       profile, stack)
        client_2 = self.connection_manager._get_client(service, region,
                                                       profile, stack)
        assert client_1 == client_2

    @patch("sceptre.connection_manager.boto3.session.Session.get_credentials")
    def test_get_client_with_exisiting_client_and_profile_none(
            self, mock_get_credentials):
        service = "cloudformation"
        region = "eu-west-1"
        profile = None
        stack = self.stack_name

        self.connection_manager.profile = None
        client_1 = self.connection_manager._get_client(service, region,
                                                       profile, stack)
        client_2 = self.connection_manager._get_client(service, region,
                                                       profile, stack)
        assert client_1 == client_2

    @mock_s3
    def test_call_with_valid_service_and_call(self):
        service = 's3'
        command = 'list_buckets'

        return_value = self.connection_manager.call(service, command, {})
        assert return_value['ResponseMetadata']['HTTPStatusCode'] == 200

    @mock_s3
    def test_call_with_valid_service_and_stack_name_call(self):
        service = 's3'
        command = 'list_buckets'

        connection_manager = ConnectionManager(region=self.region,
                                               stack_name='stack')

        return_value = connection_manager.call(service,
                                               command, {},
                                               stack_name='stack')
        assert return_value['ResponseMetadata']['HTTPStatusCode'] == 200
예제 #4
0
class TestConnectionManager(object):

    def setup_method(self, test_method):
        self.stack_name = None
        self.profile = None
        self.iam_role = None
        self.iam_role_session_duration = 3600
        self.region = "eu-west-1"

        ConnectionManager._boto_sessions = {}
        ConnectionManager._clients = {}
        ConnectionManager._stack_keys = {}

        # Temporary workaround for https://github.com/spulec/moto/issues/1924
        os.environ.setdefault("AWS_ACCESS_KEY_ID", "sceptre_test_key_id")
        os.environ.setdefault("AWS_SECRET_ACCESS_KEY", "sceptre_test_access_key")

        self.connection_manager = ConnectionManager(
            region=self.region,
            stack_name=self.stack_name,
            profile=self.profile,
            iam_role=self.iam_role
        )

    def test_connection_manager_initialised_with_no_optional_parameters(self):
        connection_manager = ConnectionManager(region=sentinel.region)

        assert connection_manager.stack_name is None
        assert connection_manager.profile is None
        assert connection_manager.region == sentinel.region
        assert connection_manager._boto_sessions == {}
        assert connection_manager._clients == {}
        assert connection_manager._stack_keys == {}

    def test_connection_manager_initialised_with_all_parameters(self):
        connection_manager = ConnectionManager(
            region=self.region,
            stack_name="stack",
            profile="profile",
            iam_role="iam_role",
            iam_role_session_duration=21600
        )

        assert connection_manager.stack_name == "stack"
        assert connection_manager.profile == "profile"
        assert connection_manager.iam_role == "iam_role"
        assert connection_manager.iam_role_session_duration == 21600
        assert connection_manager.region == self.region
        assert connection_manager._boto_sessions == {}
        assert connection_manager._clients == {}
        assert connection_manager._stack_keys == {
            "stack": (self.region, "profile", "iam_role")
        }

    def test_repr(self):
        self.connection_manager.stack_name = "stack"
        self.connection_manager.profile = "profile"
        self.connection_manager.region = "region"
        self.connection_manager.iam_role = "iam_role"
        response = self.connection_manager.__repr__()
        assert response == "sceptre.connection_manager.ConnectionManager(" \
            "region='region', profile='profile', stack_name='stack', "\
            "iam_role='iam_role', iam_role_session_duration='None')"

    def test_repr_with_iam_role_session_duration(self):
        self.connection_manager.stack_name = "stack"
        self.connection_manager.profile = "profile"
        self.connection_manager.region = "region"
        self.connection_manager.iam_role = "iam_role"
        self.connection_manager.iam_role_session_duration = 21600
        response = self.connection_manager.__repr__()
        assert response == "sceptre.connection_manager.ConnectionManager(" \
            "region='region', profile='profile', stack_name='stack', "\
            "iam_role='iam_role', iam_role_session_duration='21600')"

    def test_boto_session_with_cache(self):
        self.connection_manager._boto_sessions["test"] = sentinel.boto_session

        boto_session = self.connection_manager._boto_sessions["test"]
        assert boto_session == sentinel.boto_session

    @patch("sceptre.connection_manager.boto3.session.Session")
    def test_boto_session_with_no_profile(
            self, mock_Session
    ):
        self.connection_manager._boto_sessions = {}
        self.connection_manager.profile = None

        boto_session = self.connection_manager._get_session(
            self.connection_manager.profile, self.region, self.iam_role
        )

        assert boto_session.isinstance(mock_Session)
        mock_Session.assert_called_once_with(
            profile_name=None,
            region_name="eu-west-1",
            aws_access_key_id=ANY,
            aws_secret_access_key=ANY,
            aws_session_token=ANY
        )

    @patch("sceptre.connection_manager.boto3.session.Session")
    def test_boto_session_with_profile(self, mock_Session):
        self.connection_manager._boto_sessions = {}
        self.connection_manager.profile = "profile"

        boto_session = self.connection_manager._get_session(
            self.connection_manager.profile, self.region, self.iam_role
        )

        assert boto_session.isinstance(mock_Session)
        mock_Session.assert_called_once_with(
            profile_name="profile",
            region_name="eu-west-1",
            aws_access_key_id=ANY,
            aws_secret_access_key=ANY,
            aws_session_token=ANY
        )

    @patch("sceptre.connection_manager.boto3.session.Session")
    def test_boto_session_with_no_iam_role(
            self, mock_Session
    ):
        self.connection_manager._boto_sessions = {}
        self.connection_manager.iam_role = None

        boto_session = self.connection_manager._get_session(
            self.profile, self.region, self.connection_manager.iam_role
        )

        assert boto_session.isinstance(mock_Session)
        mock_Session.assert_called_once_with(
            profile_name=None,
            region_name="eu-west-1",
            aws_access_key_id=ANY,
            aws_secret_access_key=ANY,
            aws_session_token=ANY
        )

        boto_session.client().assume_role.assert_not_called()

    @patch("sceptre.connection_manager.boto3.session.Session")
    def test_boto_session_with_iam_role(self, mock_Session):
        self.connection_manager._boto_sessions = {}
        self.connection_manager.iam_role = "iam_role"

        boto_session = self.connection_manager._get_session(
            self.profile, self.region, self.connection_manager.iam_role
        )

        assert boto_session.isinstance(mock_Session)
        mock_Session.assert_any_call(
            profile_name=None,
            region_name="eu-west-1",
            aws_access_key_id=ANY,
            aws_secret_access_key=ANY,
            aws_session_token=ANY
        )

        boto_session.client().assume_role.assert_called_once_with(
            RoleArn=self.connection_manager.iam_role,
            RoleSessionName="{0}-session".format(
                self.connection_manager.iam_role.split("/")[-1]
            )
        )

        credentials = boto_session.client().assume_role()["Credentials"]

        mock_Session.assert_any_call(
            region_name="eu-west-1",
            aws_access_key_id=credentials["AccessKeyId"],
            aws_secret_access_key=credentials["SecretAccessKey"],
            aws_session_token=credentials["SessionToken"]
        )

    @patch("sceptre.connection_manager.boto3.session.Session")
    def test_boto_session_with_iam_role_session_duration(self, mock_Session):
        self.connection_manager._boto_sessions = {}
        self.connection_manager.iam_role = "iam_role"
        self.connection_manager.iam_role_session_duration = 21600

        boto_session = self.connection_manager._get_session(
            self.profile, self.region, self.connection_manager.iam_role
        )

        boto_session.client().assume_role.assert_called_once_with(
            RoleArn=self.connection_manager.iam_role,
            RoleSessionName="{0}-session".format(
                self.connection_manager.iam_role.split("/")[-1]
            ),
            DurationSeconds=21600
        )

    @patch("sceptre.connection_manager.boto3.session.Session")
    def test_boto_session_with_iam_role_returning_empty_credentials(self, mock_Session):
        self.connection_manager._boto_sessions = {}
        self.connection_manager.iam_role = "iam_role"

        mock_Session.return_value.get_credentials.side_effect = [
            MagicMock(), None, MagicMock(), MagicMock(), MagicMock()
        ]

        with pytest.raises(InvalidAWSCredentialsError):
            self.connection_manager._get_session(
                self.profile, self.region, self.connection_manager.iam_role
            )

    @patch("sceptre.connection_manager.boto3.session.Session")
    def test_two_boto_sessions(self, mock_Session):
        self.connection_manager._boto_sessions = {
            "one": mock_Session,
            "two": mock_Session
        }

        boto_session_1 = self.connection_manager._boto_sessions["one"]
        boto_session_2 = self.connection_manager._boto_sessions["two"]
        assert boto_session_1 == boto_session_2

    @patch("sceptre.connection_manager.boto3.session.Session.get_credentials")
    def test_get_client_with_no_pre_existing_clients(
        self, mock_get_credentials
    ):
        service = "s3"
        region = "eu-west-1"
        profile = None
        iam_role = None
        stack = self.stack_name

        client = self.connection_manager._get_client(
            service, region, profile, stack, iam_role
        )
        expected_client = Session().client(service)
        assert str(type(client)) == str(type(expected_client))

    @patch("sceptre.connection_manager.boto3.session.Session.get_credentials")
    def test_get_client_with_invalid_client_type(self, mock_get_credentials):
        service = "invalid_type"
        region = "eu-west-1"
        iam_role = None
        profile = None
        stack = self.stack_name

        with pytest.raises(UnknownServiceError):
            self.connection_manager._get_client(
                service, region, profile, stack, iam_role
            )

    @patch("sceptre.connection_manager.boto3.session.Session.get_credentials")
    def test_get_client_with_exisiting_client(self, mock_get_credentials):
        service = "cloudformation"
        region = "eu-west-1"
        iam_role = None
        profile = None
        stack = self.stack_name

        client_1 = self.connection_manager._get_client(
            service, region, profile, stack, iam_role
        )
        client_2 = self.connection_manager._get_client(
            service, region, profile, stack, iam_role
        )
        assert client_1 == client_2

    @patch("sceptre.connection_manager.boto3.session.Session.get_credentials")
    def test_get_client_with_exisiting_client_and_profile_none(
            self, mock_get_credentials
    ):
        service = "cloudformation"
        region = "eu-west-1"
        iam_role = None
        profile = None
        stack = self.stack_name

        self.connection_manager.profile = None
        client_1 = self.connection_manager._get_client(
            service, region, profile, stack, iam_role
        )
        client_2 = self.connection_manager._get_client(
            service, region, profile, stack, iam_role
        )
        assert client_1 == client_2

    @mock_s3
    def test_call_with_valid_service_and_call(self):
        service = 's3'
        command = 'list_buckets'

        return_value = self.connection_manager.call(service, command, {})
        assert return_value['ResponseMetadata']['HTTPStatusCode'] == 200

    @mock_s3
    def test_call_with_valid_service_and_stack_name_call(self):
        service = 's3'
        command = 'list_buckets'

        connection_manager = ConnectionManager(
            region=self.region,
            stack_name='stack'
        )

        return_value = connection_manager.call(
            service, command, {}, stack_name='stack'
        )
        assert return_value['ResponseMetadata']['HTTPStatusCode'] == 200