Source code for libcloud.test.test_connection

# -*- coding: utf-8 -*-
# Licensed to the Apache Software Foundation (ASF) under one or moreĀ§
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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 os
import sys
import ssl

from mock import Mock, call

from libcloud.test import unittest
from libcloud.common.base import Connection
from libcloud.common.base import LoggingConnection
from libcloud.httplib_ssl import LibcloudBaseConnection
from libcloud.httplib_ssl import LibcloudHTTPConnection


[docs]class BaseConnectionClassTestCase(unittest.TestCase):
[docs] def test_parse_proxy_url(self): conn = LibcloudBaseConnection() proxy_url = 'http://127.0.0.1:3128' result = conn._parse_proxy_url(proxy_url=proxy_url) self.assertEqual(result[0], 'http') self.assertEqual(result[1], '127.0.0.1') self.assertEqual(result[2], 3128) self.assertEqual(result[3], None) self.assertEqual(result[4], None) proxy_url = 'http://user1:pass1@127.0.0.1:3128' result = conn._parse_proxy_url(proxy_url=proxy_url) self.assertEqual(result[0], 'http') self.assertEqual(result[1], '127.0.0.1') self.assertEqual(result[2], 3128) self.assertEqual(result[3], 'user1') self.assertEqual(result[4], 'pass1') proxy_url = 'https://127.0.0.1:3128' expected_msg = 'Only http proxies are supported' self.assertRaisesRegexp(ValueError, expected_msg, conn._parse_proxy_url, proxy_url=proxy_url) proxy_url = 'http://127.0.0.1' expected_msg = 'proxy_url must be in the following format' self.assertRaisesRegexp(ValueError, expected_msg, conn._parse_proxy_url, proxy_url=proxy_url) proxy_url = 'http://@127.0.0.1:3128' expected_msg = 'URL is in an invalid format' self.assertRaisesRegexp(ValueError, expected_msg, conn._parse_proxy_url, proxy_url=proxy_url) proxy_url = 'http://user@127.0.0.1:3128' expected_msg = 'URL is in an invalid format' self.assertRaisesRegexp(ValueError, expected_msg, conn._parse_proxy_url, proxy_url=proxy_url)
[docs] def test_constructor(self): conn = LibcloudHTTPConnection(host='localhost', port=80) self.assertEqual(conn.proxy_scheme, None) self.assertEqual(conn.proxy_host, None) self.assertEqual(conn.proxy_port, None) proxy_url = 'http://127.0.0.3:3128' conn.set_http_proxy(proxy_url=proxy_url) self.assertEqual(conn.proxy_scheme, 'http') self.assertEqual(conn.proxy_host, '127.0.0.3') self.assertEqual(conn.proxy_port, 3128) proxy_url = 'http://127.0.0.4:3128' conn = LibcloudHTTPConnection(host='localhost', port=80, proxy_url=proxy_url) self.assertEqual(conn.proxy_scheme, 'http') self.assertEqual(conn.proxy_host, '127.0.0.4') self.assertEqual(conn.proxy_port, 3128) os.environ['http_proxy'] = proxy_url proxy_url = 'http://127.0.0.5:3128' conn = LibcloudHTTPConnection(host='localhost', port=80, proxy_url=proxy_url) self.assertEqual(conn.proxy_scheme, 'http') self.assertEqual(conn.proxy_host, '127.0.0.5') self.assertEqual(conn.proxy_port, 3128)
[docs]class ConnectionClassTestCase(unittest.TestCase):
[docs] def setUp(self): self.originalConnect = Connection.connect self.originalResponseCls = Connection.responseCls Connection.connect = Mock() Connection.responseCls = Mock() Connection.allow_insecure = True
[docs] def tearDown(self): Connection.connect = self.originalConnect Connection.responseCls = Connection.responseCls Connection.allow_insecure = True
[docs] def test_dont_allow_insecure(self): Connection.allow_insecure = True Connection(secure=False) Connection.allow_insecure = False expected_msg = (r'Non https connections are not allowed \(use ' 'secure=True\)') self.assertRaisesRegexp(ValueError, expected_msg, Connection, secure=False)
[docs] def test_content_length(self): con = Connection() con.connection = Mock() # GET method # No data, no content length should be present con.request('/test', method='GET', data=None) call_kwargs = con.connection.request.call_args[1] self.assertTrue('Content-Length' not in call_kwargs['headers']) # '' as data, no content length should be present con.request('/test', method='GET', data='') call_kwargs = con.connection.request.call_args[1] self.assertTrue('Content-Length' not in call_kwargs['headers']) # 'a' as data, content length should be present (data in GET is not # correct, but anyways) con.request('/test', method='GET', data='a') call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs['headers']['Content-Length'], '1') # POST, PUT method # No data, content length should be present for method in ['POST', 'PUT', 'post', 'put']: con.request('/test', method=method, data=None) call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs['headers']['Content-Length'], '0') # '' as data, content length should be present for method in ['POST', 'PUT', 'post', 'put']: con.request('/test', method=method, data='') call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs['headers']['Content-Length'], '0') # No data, raw request, do not touch Content-Length if present for method in ['POST', 'PUT', 'post', 'put']: con.request('/test', method=method, data=None, headers={'Content-Length': '42'}, raw=True) putheader_call_list = con.connection.putheader.call_args_list self.assertIn(call('Content-Length', '42'), putheader_call_list) # '' as data, raw request, do not touch Content-Length if present for method in ['POST', 'PUT', 'post', 'put']: con.request('/test', method=method, data=None, headers={'Content-Length': '42'}, raw=True) putheader_call_list = con.connection.putheader.call_args_list self.assertIn(call('Content-Length', '42'), putheader_call_list) # 'a' as data, content length should be present for method in ['POST', 'PUT', 'post', 'put']: con.request('/test', method=method, data='a') call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs['headers']['Content-Length'], '1')
[docs] def test_cache_busting(self): params1 = {'foo1': 'bar1', 'foo2': 'bar2'} params2 = [('foo1', 'bar1'), ('foo2', 'bar2')] con = Connection() con.connection = Mock() con.pre_connect_hook = Mock() con.pre_connect_hook.return_value = {}, {} con.cache_busting = False con.request(action='/path', params=params1) args, kwargs = con.pre_connect_hook.call_args self.assertFalse('cache-busting' in args[0]) self.assertEqual(args[0], params1) con.request(action='/path', params=params2) args, kwargs = con.pre_connect_hook.call_args self.assertFalse('cache-busting' in args[0]) self.assertEqual(args[0], params2) con.cache_busting = True con.request(action='/path', params=params1) args, kwargs = con.pre_connect_hook.call_args self.assertTrue('cache-busting' in args[0]) con.request(action='/path', params=params2) args, kwargs = con.pre_connect_hook.call_args self.assertTrue('cache-busting' in args[0][len(params2)])
[docs] def test_context_is_reset_after_request_has_finished(self): context = {'foo': 'bar'} def responseCls(connection, response): connection.called = True self.assertEqual(connection.context, context) con = Connection() con.called = False con.connection = Mock() con.responseCls = responseCls con.set_context(context) self.assertEqual(con.context, context) con.request('/') # Context should have been reset self.assertTrue(con.called) self.assertEqual(con.context, {}) # Context should also be reset if a method inside request throws con = Connection() con.connection = Mock() con.set_context(context) self.assertEqual(con.context, context) con.connection.request = Mock(side_effect=ssl.SSLError()) try: con.request('/') except ssl.SSLError: pass self.assertEqual(con.context, {}) con.connection = Mock() con.set_context(context) self.assertEqual(con.context, context) con.responseCls = Mock(side_effect=ValueError()) try: con.request('/') except ValueError: pass self.assertEqual(con.context, {})
[docs] def test_log_curl(self): url = '/test/path' body = None headers = {} con = LoggingConnection() con.protocol = 'http' con.host = 'example.com' con.port = 80 for method in ['GET', 'POST', 'PUT', 'DELETE']: cmd = con._log_curl(method=method, url=url, body=body, headers=headers) self.assertEqual(cmd, 'curl -i -X %s --compress http://example.com:80/test/path' % (method)) # Should use --head for head requests cmd = con._log_curl(method='HEAD', url=url, body=body, headers=headers) self.assertEqual(cmd, 'curl -i --head --compress http://example.com:80/test/path')
if __name__ == '__main__': sys.exit(unittest.main())