484 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			484 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # -*- coding:utf-8 -*-
 | |
| # Licensed under the Apache License, Version 2.0 (the "License");
 | |
| # you may not use this file except in compliance with the License.
 | |
| # You may obtain a copy of the License at
 | |
| #
 | |
| #    http://www.apache.org/licenses/LICENSE-2.0
 | |
| #
 | |
| # Unless required by applicable law or agreed to in writing, software
 | |
| # distributed under the License is distributed on an "AS IS" BASIS,
 | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | |
| # implied.
 | |
| # See the License for the specific language governing permissions and
 | |
| # limitations under the License.
 | |
| 
 | |
| import socket
 | |
| 
 | |
| import mock
 | |
| import testtools
 | |
| 
 | |
| from glareclient.common import exceptions as exc
 | |
| from glareclient.common import http
 | |
| from glareclient.tests.unit import fakes
 | |
| 
 | |
| 
 | |
| @mock.patch('glareclient.common.http.requests.request')
 | |
| class HttpClientTest(testtools.TestCase):
 | |
| 
 | |
|     # Patch os.environ to avoid required auth info.
 | |
|     def setUp(self):
 | |
|         super(HttpClientTest, self).setUp()
 | |
| 
 | |
|     def test_http_raw_request(self, mock_request):
 | |
|         headers = {'User-Agent': 'python-glareclient'}
 | |
|         mock_request.return_value = \
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 200, 'OK',
 | |
|                 {},
 | |
|                 '')
 | |
| 
 | |
|         client = http.HTTPClient('http://example.com:9494')
 | |
|         resp = client.request('', 'GET')
 | |
|         self.assertEqual(200, resp.status_code)
 | |
|         self.assertEqual('', ''.join([x for x in resp.content]))
 | |
|         mock_request.assert_called_with('GET', 'http://example.com:9494',
 | |
|                                         allow_redirects=False,
 | |
|                                         headers=headers)
 | |
| 
 | |
|     def test_token_or_credentials(self, mock_request):
 | |
|         # Record a 200
 | |
|         fake200 = fakes.FakeHTTPResponse(
 | |
|             200, 'OK',
 | |
|             {},
 | |
|             '')
 | |
| 
 | |
|         mock_request.side_effect = [fake200, fake200, fake200]
 | |
| 
 | |
|         # Replay, create client, assert
 | |
|         client = http.HTTPClient('http://example.com:9494')
 | |
|         resp = client.request('', 'GET')
 | |
|         self.assertEqual(200, resp.status_code)
 | |
| 
 | |
|         client.username = 'user'
 | |
|         client.password = 'pass'
 | |
|         resp = client.request('', 'GET')
 | |
|         self.assertEqual(200, resp.status_code)
 | |
| 
 | |
|         client.auth_token = 'abcd1234'
 | |
|         resp = client.request('', 'GET')
 | |
|         self.assertEqual(200, resp.status_code)
 | |
| 
 | |
|         # no token or credentials
 | |
|         mock_request.assert_has_calls([
 | |
|             mock.call('GET', 'http://example.com:9494',
 | |
|                       allow_redirects=False,
 | |
|                       headers={'User-Agent': 'python-glareclient'}),
 | |
|             mock.call('GET', 'http://example.com:9494',
 | |
|                       allow_redirects=False,
 | |
|                       headers={'User-Agent': 'python-glareclient',
 | |
|                                'X-Auth-Key': 'pass',
 | |
|                                'X-Auth-User': 'user'}),
 | |
|             mock.call('GET', 'http://example.com:9494',
 | |
|                       allow_redirects=False,
 | |
|                       headers={'User-Agent': 'python-glareclient',
 | |
|                                'X-Auth-Token': 'abcd1234'})
 | |
|         ])
 | |
| 
 | |
|     def test_region_name(self, mock_request):
 | |
|         # Record a 200
 | |
|         fake200 = fakes.FakeHTTPResponse(
 | |
|             200, 'OK',
 | |
|             {},
 | |
|             '')
 | |
| 
 | |
|         mock_request.return_value = fake200
 | |
| 
 | |
|         client = http.HTTPClient('http://example.com:9494')
 | |
|         client.region_name = 'RegionOne'
 | |
|         resp = client.request('', 'GET')
 | |
|         self.assertEqual(200, resp.status_code)
 | |
| 
 | |
|         mock_request.assert_called_once_with(
 | |
|             'GET', 'http://example.com:9494',
 | |
|             allow_redirects=False,
 | |
|             headers={'X-Region-Name': 'RegionOne',
 | |
|                      'User-Agent': 'python-glareclient'})
 | |
| 
 | |
|     def test_http_json_request(self, mock_request):
 | |
|         # Record a 200
 | |
|         mock_request.return_value = \
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 200, 'OK',
 | |
|                 {'content-type': 'application/json'},
 | |
|                 '{}')
 | |
|         client = http.HTTPClient('http://example.com:9494')
 | |
|         resp, body = client.json_request('', 'GET')
 | |
|         self.assertEqual(200, resp.status_code)
 | |
|         self.assertEqual({}, body)
 | |
| 
 | |
|         mock_request.assert_called_once_with(
 | |
|             'GET', 'http://example.com:9494',
 | |
|             allow_redirects=False,
 | |
|             stream=False,
 | |
|             data=None,
 | |
|             headers={'Content-Type': 'application/json',
 | |
|                      'User-Agent': 'python-glareclient'})
 | |
| 
 | |
|     def test_http_json_request_argument_passed_to_requests(self, mock_request):
 | |
|         """Check that we have sent the proper arguments to requests."""
 | |
|         # Record a 200
 | |
|         mock_request.return_value = \
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 200, 'OK',
 | |
|                 {'content-type': 'application/json'},
 | |
|                 '{}')
 | |
| 
 | |
|         client = http.HTTPClient('http://example.com:9494')
 | |
|         client.verify_cert = True
 | |
|         client.cert_file = 'RANDOM_CERT_FILE'
 | |
|         client.key_file = 'RANDOM_KEY_FILE'
 | |
|         client.auth_url = 'http://AUTH_URL'
 | |
|         resp, body = client.json_request('', 'GET', data='text')
 | |
|         self.assertEqual(200, resp.status_code)
 | |
|         self.assertEqual({}, body)
 | |
| 
 | |
|         mock_request.assert_called_once_with(
 | |
|             'GET', 'http://example.com:9494',
 | |
|             allow_redirects=False,
 | |
|             cert=('RANDOM_CERT_FILE', 'RANDOM_KEY_FILE'),
 | |
|             verify=True,
 | |
|             data='text',
 | |
|             stream=False,
 | |
|             headers={'Content-Type': 'application/json',
 | |
|                      'X-Auth-Url': 'http://AUTH_URL',
 | |
|                      'User-Agent': 'python-glareclient'})
 | |
| 
 | |
|     def test_http_json_request_w_req_body(self, mock_request):
 | |
|         # Record a 200
 | |
|         mock_request.return_value = \
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 200, 'OK',
 | |
|                 {'content-type': 'application/json'},
 | |
|                 '{}')
 | |
| 
 | |
|         client = http.HTTPClient('http://example.com:9494')
 | |
|         resp, body = client.json_request('', 'GET', data='test-body')
 | |
|         self.assertEqual(200, resp.status_code)
 | |
|         self.assertEqual({}, body)
 | |
|         mock_request.assert_called_once_with(
 | |
|             'GET', 'http://example.com:9494',
 | |
|             data='test-body',
 | |
|             allow_redirects=False,
 | |
|             stream=False,
 | |
|             headers={'Content-Type': 'application/json',
 | |
|                      'User-Agent': 'python-glareclient'})
 | |
| 
 | |
|     def test_http_json_request_non_json_resp_cont_type(self, mock_request):
 | |
|         # Record a 200
 | |
|         mock_request.return_value = \
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 200, 'OK',
 | |
|                 {'content-type': 'not/json'},
 | |
|                 '{}')
 | |
| 
 | |
|         client = http.HTTPClient('http://example.com:9494')
 | |
|         resp, body = client.json_request('', 'GET', data='test-data')
 | |
|         self.assertEqual(200, resp.status_code)
 | |
|         mock_request.assert_called_once_with(
 | |
|             'GET', 'http://example.com:9494', data='test-data',
 | |
|             allow_redirects=False,
 | |
|             stream=False,
 | |
|             headers={'Content-Type': 'application/json',
 | |
|                      'User-Agent': 'python-glareclient'})
 | |
| 
 | |
|     def test_http_json_request_invalid_json(self, mock_request):
 | |
|         # Record a 200
 | |
|         mock_request.return_value = \
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 200, 'OK',
 | |
|                 {'content-type': 'application/json'},
 | |
|                 'invalid-json')
 | |
| 
 | |
|         client = http.HTTPClient('http://example.com:9494')
 | |
|         resp, body = client.json_request('', 'GET')
 | |
|         self.assertEqual(200, resp.status_code)
 | |
|         self.assertIsNone(body)
 | |
|         mock_request.assert_called_once_with(
 | |
|             'GET', 'http://example.com:9494',
 | |
|             allow_redirects=False,
 | |
|             stream=False,
 | |
|             data=None,
 | |
|             headers={'Content-Type': 'application/json',
 | |
|                      'User-Agent': 'python-glareclient'})
 | |
| 
 | |
|     def test_http_manual_redirect_delete(self, mock_request):
 | |
|         mock_request.side_effect = [
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 302, 'Found',
 | |
|                 {'location': 'http://example.com:9494/foo/bar'},
 | |
|                 ''),
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 200, 'OK',
 | |
|                 {'content-type': 'application/json'},
 | |
|                 '{}')]
 | |
| 
 | |
|         client = http.HTTPClient('http://example.com:9494/foo')
 | |
|         resp, body = client.json_request('', 'DELETE')
 | |
| 
 | |
|         self.assertEqual(200, resp.status_code)
 | |
|         mock_request.assert_has_calls([
 | |
|             mock.call('DELETE', 'http://example.com:9494/foo',
 | |
|                       allow_redirects=False,
 | |
|                       stream=False,
 | |
|                       data=None,
 | |
|                       headers={'Content-Type': 'application/json',
 | |
|                                'User-Agent': 'python-glareclient'}),
 | |
|             mock.call('DELETE', 'http://example.com:9494/foo/bar',
 | |
|                       allow_redirects=False,
 | |
|                       stream=False,
 | |
|                       data=None,
 | |
|                       headers={'Content-Type': 'application/json',
 | |
|                                'User-Agent': 'python-glareclient'})
 | |
|         ])
 | |
| 
 | |
|     def test_http_manual_redirect_post(self, mock_request):
 | |
|         mock_request.side_effect = [
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 302, 'Found',
 | |
|                 {'location': 'http://example.com:9494/foo/bar'},
 | |
|                 ''),
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 200, 'OK',
 | |
|                 {'content-type': 'application/json'},
 | |
|                 '{}')]
 | |
| 
 | |
|         client = http.HTTPClient('http://example.com:9494/foo')
 | |
|         resp, body = client.json_request('', 'POST')
 | |
| 
 | |
|         self.assertEqual(200, resp.status_code)
 | |
|         mock_request.assert_has_calls([
 | |
|             mock.call('POST', 'http://example.com:9494/foo',
 | |
|                       allow_redirects=False,
 | |
|                       stream=False,
 | |
|                       data=None,
 | |
|                       headers={'Content-Type': 'application/json',
 | |
|                                'User-Agent': 'python-glareclient'}),
 | |
|             mock.call('POST', 'http://example.com:9494/foo/bar',
 | |
|                       allow_redirects=False,
 | |
|                       stream=False,
 | |
|                       data=None,
 | |
|                       headers={'Content-Type': 'application/json',
 | |
|                                'User-Agent': 'python-glareclient'})
 | |
|         ])
 | |
| 
 | |
|     def test_http_manual_redirect_put(self, mock_request):
 | |
|         mock_request.side_effect = [
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 302, 'Found',
 | |
|                 {'location': 'http://example.com:9494/foo/bar'},
 | |
|                 ''),
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 200, 'OK',
 | |
|                 {'content-type': 'application/json'},
 | |
|                 '{}')]
 | |
| 
 | |
|         client = http.HTTPClient('http://example.com:9494/foo')
 | |
|         resp, body = client.json_request('', 'PUT')
 | |
| 
 | |
|         self.assertEqual(200, resp.status_code)
 | |
|         mock_request.assert_has_calls([
 | |
|             mock.call('PUT', 'http://example.com:9494/foo',
 | |
|                       allow_redirects=False,
 | |
|                       stream=False,
 | |
|                       data=None,
 | |
|                       headers={'Content-Type': 'application/json',
 | |
|                                'User-Agent': 'python-glareclient'}),
 | |
|             mock.call('PUT', 'http://example.com:9494/foo/bar',
 | |
|                       allow_redirects=False,
 | |
|                       stream=False,
 | |
|                       data=None,
 | |
|                       headers={'Content-Type': 'application/json',
 | |
|                                'User-Agent': 'python-glareclient'})
 | |
|         ])
 | |
| 
 | |
|     def test_http_manual_redirect_prohibited(self, mock_request):
 | |
|         mock_request.return_value = \
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 302, 'Found',
 | |
|                 {'location': 'http://example.com:9494/'},
 | |
|                 '')
 | |
|         client = http.HTTPClient('http://example.com:9494/foo')
 | |
|         self.assertRaises(exc.InvalidEndpoint,
 | |
|                           client.json_request, '', 'DELETE')
 | |
|         mock_request.assert_called_once_with(
 | |
|             'DELETE', 'http://example.com:9494/foo',
 | |
|             allow_redirects=False,
 | |
|             stream=False,
 | |
|             data=None,
 | |
|             headers={'Content-Type': 'application/json',
 | |
|                      'User-Agent': 'python-glareclient'})
 | |
| 
 | |
|     def test_http_manual_redirect_error_without_location(self, mock_request):
 | |
|         mock_request.return_value = \
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 302, 'Found',
 | |
|                 {},
 | |
|                 '')
 | |
|         client = http.HTTPClient('http://example.com:9494/foo')
 | |
|         self.assertRaises(exc.InvalidEndpoint,
 | |
|                           client.json_request, '', 'DELETE')
 | |
|         mock_request.assert_called_once_with(
 | |
|             'DELETE', 'http://example.com:9494/foo',
 | |
|             allow_redirects=False,
 | |
|             stream=False,
 | |
|             data=None,
 | |
|             headers={'Content-Type': 'application/json',
 | |
|                      'User-Agent': 'python-glareclient'})
 | |
| 
 | |
|     def test_http_json_request_redirect(self, mock_request):
 | |
|         # Record the 302
 | |
|         mock_request.side_effect = [
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 302, 'Found',
 | |
|                 {'location': 'http://example.com:9494'},
 | |
|                 ''),
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 200, 'OK',
 | |
|                 {'content-type': 'application/json'},
 | |
|                 '{}')]
 | |
| 
 | |
|         client = http.HTTPClient('http://example.com:9494')
 | |
|         resp, body = client.json_request('', 'GET')
 | |
|         self.assertEqual(200, resp.status_code)
 | |
|         self.assertEqual({}, body)
 | |
| 
 | |
|         mock_request.assert_has_calls([
 | |
|             mock.call('GET', 'http://example.com:9494',
 | |
|                       allow_redirects=False,
 | |
|                       stream=False,
 | |
|                       data=None,
 | |
|                       headers={'Content-Type': 'application/json',
 | |
|                                'User-Agent': 'python-glareclient'}),
 | |
|             mock.call('GET', 'http://example.com:9494',
 | |
|                       allow_redirects=False,
 | |
|                       stream=False,
 | |
|                       data=None,
 | |
|                       headers={'Content-Type': 'application/json',
 | |
|                                'User-Agent': 'python-glareclient'})
 | |
|         ])
 | |
| 
 | |
|     def test_http_404_json_request(self, mock_request):
 | |
|         mock_request.return_value = \
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 404, 'Not Found', {'content-type': 'application/json'},
 | |
|                 '{}')
 | |
| 
 | |
|         client = http.HTTPClient('http://example.com:9494')
 | |
|         e = self.assertRaises(exc.HTTPNotFound, client.json_request, '', 'GET')
 | |
|         # Assert that the raised exception can be converted to string
 | |
|         self.assertIsNotNone(str(e))
 | |
|         # Record a 404
 | |
|         mock_request.assert_called_once_with(
 | |
|             'GET', 'http://example.com:9494',
 | |
|             allow_redirects=False,
 | |
|             stream=False,
 | |
|             data=None,
 | |
|             headers={'Content-Type': 'application/json',
 | |
|                      'User-Agent': 'python-glareclient'})
 | |
| 
 | |
|     def test_http_300_json_request(self, mock_request):
 | |
|         mock_request.return_value = \
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 300, 'OK', {'content-type': 'application/json'},
 | |
|                 '{}')
 | |
|         client = http.HTTPClient('http://example.com:9494')
 | |
|         e = self.assertRaises(
 | |
|             exc.HTTPMultipleChoices, client.json_request, '', 'GET')
 | |
|         # Assert that the raised exception can be converted to string
 | |
|         self.assertIsNotNone(str(e))
 | |
| 
 | |
|         # Record a 300
 | |
|         mock_request.assert_called_once_with(
 | |
|             'GET', 'http://example.com:9494',
 | |
|             allow_redirects=False,
 | |
|             stream=False,
 | |
|             data=None,
 | |
|             headers={'Content-Type': 'application/json',
 | |
|                      'User-Agent': 'python-glareclient'})
 | |
| 
 | |
|     def test_fake_json_request(self, mock_request):
 | |
|         headers = {'User-Agent': 'python-glareclient'}
 | |
|         mock_request.side_effect = [socket.gaierror]
 | |
| 
 | |
|         client = http.HTTPClient('fake://example.com:9494')
 | |
|         self.assertRaises(exc.InvalidEndpoint,
 | |
|                           client.request, "/", "GET")
 | |
|         mock_request.assert_called_once_with('GET', 'fake://example.com:9494/',
 | |
|                                              allow_redirects=False,
 | |
|                                              headers=headers)
 | |
| 
 | |
|     def test_http_request_socket_error(self, mock_request):
 | |
|         headers = {'User-Agent': 'python-glareclient'}
 | |
|         mock_request.side_effect = [socket.gaierror]
 | |
| 
 | |
|         client = http.HTTPClient('http://example.com:9494')
 | |
|         self.assertRaises(exc.InvalidEndpoint,
 | |
|                           client.request, "/", "GET")
 | |
|         mock_request.assert_called_once_with('GET', 'http://example.com:9494/',
 | |
|                                              allow_redirects=False,
 | |
|                                              headers=headers)
 | |
| 
 | |
|     def test_http_request_socket_timeout(self, mock_request):
 | |
|         headers = {'User-Agent': 'python-glareclient'}
 | |
|         mock_request.side_effect = [socket.timeout]
 | |
| 
 | |
|         client = http.HTTPClient('http://example.com:9494')
 | |
|         self.assertRaises(exc.CommunicationError,
 | |
|                           client.request, "/", "GET")
 | |
|         mock_request.assert_called_once_with('GET', 'http://example.com:9494/',
 | |
|                                              allow_redirects=False,
 | |
|                                              headers=headers)
 | |
| 
 | |
|     def test_http_request_specify_timeout(self, mock_request):
 | |
|         mock_request.return_value = \
 | |
|             fakes.FakeHTTPResponse(
 | |
|                 200, 'OK',
 | |
|                 {'content-type': 'application/json'},
 | |
|                 '{}')
 | |
| 
 | |
|         client = http.HTTPClient('http://example.com:9494', timeout='123')
 | |
|         resp, body = client.json_request('', 'GET')
 | |
|         self.assertEqual(200, resp.status_code)
 | |
|         self.assertEqual({}, body)
 | |
|         mock_request.assert_called_once_with(
 | |
|             'GET', 'http://example.com:9494',
 | |
|             allow_redirects=False,
 | |
|             stream=False,
 | |
|             data=None,
 | |
|             headers={'Content-Type': 'application/json',
 | |
|                      'User-Agent': 'python-glareclient'},
 | |
|             timeout=float(123))
 | |
| 
 | |
|     def test_get_system_ca_file(self, mock_request):
 | |
|         chosen = '/etc/ssl/certs/ca-certificates.crt'
 | |
|         with mock.patch('os.path.exists') as mock_os:
 | |
|             mock_os.return_value = chosen
 | |
| 
 | |
|             ca = http.get_system_ca_file()
 | |
|             self.assertEqual(chosen, ca)
 | |
| 
 | |
|             mock_os.assert_called_once_with(chosen)
 | |
| 
 | |
|     def test_insecure_verify_cert_None(self, mock_request):
 | |
|         client = http.HTTPClient('https://foo', insecure=True)
 | |
|         self.assertFalse(client.verify_cert)
 | |
| 
 | |
|     def test_passed_cert_to_verify_cert(self, mock_request):
 | |
|         client = http.HTTPClient('https://foo', cacert="NOWHERE")
 | |
|         self.assertEqual("NOWHERE", client.verify_cert)
 | |
| 
 | |
|         with mock.patch('glareclient.common.http.get_system_ca_file') as gsf:
 | |
|             gsf.return_value = "SOMEWHERE"
 | |
|             client = http.HTTPClient('https://foo')
 | |
|             self.assertEqual("SOMEWHERE", client.verify_cert)
 | 
