18d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoifrom boto.compat import http_client
28d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoifrom tests.compat import mock, unittest
38d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
48d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
58d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiclass AWSMockServiceTestCase(unittest.TestCase):
68d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    """Base class for mocking aws services."""
78d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    # This param is used by the unittest module to display a full
88d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    # diff when assert*Equal methods produce an error message.
98d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    maxDiff = None
108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    connection_class = None
118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    def setUp(self):
138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.https_connection = mock.Mock(spec=http_client.HTTPSConnection)
148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.https_connection.debuglevel = 0
158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.https_connection_factory = (
168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            mock.Mock(return_value=self.https_connection), ())
178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.service_connection = self.create_service_connection(
188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            https_connection_factory=self.https_connection_factory,
198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            aws_access_key_id='aws_access_key_id',
208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            aws_secret_access_key='aws_secret_access_key')
218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.initialize_service_connection()
228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    def initialize_service_connection(self):
248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.actual_request = None
258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.original_mexe = self.service_connection._mexe
268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.service_connection._mexe = self._mexe_spy
278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.proxy = None
288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.use_proxy = False
298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    def create_service_connection(self, **kwargs):
318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        if self.connection_class is None:
328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            raise ValueError("The connection_class class attribute must be "
338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                             "set to a non-None value.")
348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return self.connection_class(**kwargs)
358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    def _mexe_spy(self, request, *args, **kwargs):
378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.actual_request = request
388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return self.original_mexe(request, *args, **kwargs)
398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    def create_response(self, status_code, reason='', header=[], body=None):
418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        if body is None:
428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            body = self.default_body()
438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        response = mock.Mock(spec=http_client.HTTPResponse)
448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        response.status = status_code
458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        response.read.return_value = body
468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        response.reason = reason
478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        response.getheaders.return_value = header
498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        response.msg = dict(header)
508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        def overwrite_header(arg, default=None):
528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            header_dict = dict(header)
538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            if arg in header_dict:
548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                return header_dict[arg]
558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            else:
568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                return default
578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        response.getheader.side_effect = overwrite_header
588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return response
608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    def assert_request_parameters(self, params, ignore_params_values=None):
628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        """Verify the actual parameters sent to the service API."""
638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        request_params = self.actual_request.params.copy()
648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        if ignore_params_values is not None:
658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            for param in ignore_params_values:
668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                try:
678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                    del request_params[param]
688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                except KeyError:
698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                    pass
708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.assertDictEqual(request_params, params)
718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    def set_http_response(self, status_code, reason='', header=[], body=None):
738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        http_response = self.create_response(status_code, reason, header, body)
748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.https_connection.getresponse.return_value = http_response
758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    def default_body(self):
778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return ''
788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiclass MockServiceWithConfigTestCase(AWSMockServiceTestCase):
818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    def setUp(self):
828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        super(MockServiceWithConfigTestCase, self).setUp()
838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.environ = {}
848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.config = {}
858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.config_patch = mock.patch('boto.provider.config.get',
868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                                       self.get_config)
878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.has_config_patch = mock.patch('boto.provider.config.has_option',
888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                                           self.has_config)
898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.environ_patch = mock.patch('os.environ', self.environ)
908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.config_patch.start()
918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.has_config_patch.start()
928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.environ_patch.start()
938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    def tearDown(self):
958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.config_patch.stop()
968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.has_config_patch.stop()
978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        self.environ_patch.stop()
988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    def has_config(self, section_name, key):
1008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        try:
1018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            self.config[section_name][key]
1028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            return True
1038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        except KeyError:
1048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            return False
1058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    def get_config(self, section_name, key, default=None):
1078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        try:
1088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            return self.config[section_name][key]
1098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        except KeyError:
1108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            return None
111