|
Packit Service |
a04d08 |
# This file is part of cloud-init. See LICENSE file for license information.
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
from cloudinit.url_helper import (
|
|
Packit Service |
751c4a |
NOT_FOUND, UrlError, REDACTED, oauth_headers, read_file_or_url,
|
|
Packit Service |
751c4a |
retry_on_url_exc)
|
|
Packit Service |
a04d08 |
from cloudinit.tests.helpers import CiTestCase, mock, skipIf
|
|
Packit Service |
a04d08 |
from cloudinit import util
|
|
Packit Service |
a04d08 |
from cloudinit import version
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
import httpretty
|
|
Packit Service |
a04d08 |
import requests
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
try:
|
|
Packit Service |
a04d08 |
import oauthlib
|
|
Packit Service |
a04d08 |
assert oauthlib # avoid pyflakes error F401: import unused
|
|
Packit Service |
a04d08 |
_missing_oauthlib_dep = False
|
|
Packit Service |
a04d08 |
except ImportError:
|
|
Packit Service |
a04d08 |
_missing_oauthlib_dep = True
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
M_PATH = 'cloudinit.url_helper.'
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
class TestOAuthHeaders(CiTestCase):
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_oauth_headers_raises_not_implemented_when_oathlib_missing(self):
|
|
Packit Service |
a04d08 |
"""oauth_headers raises a NotImplemented error when oauth absent."""
|
|
Packit Service |
a04d08 |
with mock.patch.dict('sys.modules', {'oauthlib': None}):
|
|
Packit Service |
a04d08 |
with self.assertRaises(NotImplementedError) as context_manager:
|
|
Packit Service |
a04d08 |
oauth_headers(1, 2, 3, 4, 5)
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
'oauth support is not available',
|
|
Packit Service |
a04d08 |
str(context_manager.exception))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
@skipIf(_missing_oauthlib_dep, "No python-oauthlib dependency")
|
|
Packit Service |
a04d08 |
@mock.patch('oauthlib.oauth1.Client')
|
|
Packit Service |
a04d08 |
def test_oauth_headers_calls_oathlibclient_when_available(self, m_client):
|
|
Packit Service |
a04d08 |
"""oauth_headers calls oaut1.hClient.sign with the provided url."""
|
|
Packit Service |
a04d08 |
class fakeclient(object):
|
|
Packit Service |
a04d08 |
def sign(self, url):
|
|
Packit Service |
a04d08 |
# The first and 3rd item of the client.sign tuple are ignored
|
|
Packit Service |
a04d08 |
return ('junk', url, 'junk2')
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
m_client.return_value = fakeclient()
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
return_value = oauth_headers(
|
|
Packit Service |
a04d08 |
'url', 'consumer_key', 'token_key', 'token_secret',
|
|
Packit Service |
a04d08 |
'consumer_secret')
|
|
Packit Service |
a04d08 |
self.assertEqual('url', return_value)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
class TestReadFileOrUrl(CiTestCase):
|
|
Packit Service |
751c4a |
|
|
Packit Service |
751c4a |
with_logs = True
|
|
Packit Service |
751c4a |
|
|
Packit Service |
a04d08 |
def test_read_file_or_url_str_from_file(self):
|
|
Packit Service |
a04d08 |
"""Test that str(result.contents) on file is text version of contents.
|
|
Packit Service |
a04d08 |
It should not be "b'data'", but just "'data'" """
|
|
Packit Service |
a04d08 |
tmpf = self.tmp_path("myfile1")
|
|
Packit Service |
a04d08 |
data = b'This is my file content\n'
|
|
Packit Service |
a04d08 |
util.write_file(tmpf, data, omode="wb")
|
|
Packit Service |
a04d08 |
result = read_file_or_url("file://%s" % tmpf)
|
|
Packit Service |
a04d08 |
self.assertEqual(result.contents, data)
|
|
Packit Service |
a04d08 |
self.assertEqual(str(result), data.decode('utf-8'))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
@httpretty.activate
|
|
Packit Service |
a04d08 |
def test_read_file_or_url_str_from_url(self):
|
|
Packit Service |
a04d08 |
"""Test that str(result.contents) on url is text version of contents.
|
|
Packit Service |
a04d08 |
It should not be "b'data'", but just "'data'" """
|
|
Packit Service |
a04d08 |
url = 'http://hostname/path'
|
|
Packit Service |
a04d08 |
data = b'This is my url content\n'
|
|
Packit Service |
a04d08 |
httpretty.register_uri(httpretty.GET, url, data)
|
|
Packit Service |
a04d08 |
result = read_file_or_url(url)
|
|
Packit Service |
a04d08 |
self.assertEqual(result.contents, data)
|
|
Packit Service |
a04d08 |
self.assertEqual(str(result), data.decode('utf-8'))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
751c4a |
@httpretty.activate
|
|
Packit Service |
751c4a |
def test_read_file_or_url_str_from_url_redacting_headers_from_logs(self):
|
|
Packit Service |
751c4a |
"""Headers are redacted from logs but unredacted in requests."""
|
|
Packit Service |
751c4a |
url = 'http://hostname/path'
|
|
Packit Service |
751c4a |
headers = {'sensitive': 'sekret', 'server': 'blah'}
|
|
Packit Service |
751c4a |
httpretty.register_uri(httpretty.GET, url)
|
|
Packit Service |
751c4a |
|
|
Packit Service |
751c4a |
read_file_or_url(url, headers=headers, headers_redact=['sensitive'])
|
|
Packit Service |
751c4a |
logs = self.logs.getvalue()
|
|
Packit Service |
751c4a |
for k in headers.keys():
|
|
Packit Service |
751c4a |
self.assertEqual(headers[k], httpretty.last_request().headers[k])
|
|
Packit Service |
751c4a |
self.assertIn(REDACTED, logs)
|
|
Packit Service |
751c4a |
self.assertNotIn('sekret', logs)
|
|
Packit Service |
751c4a |
|
|
Packit Service |
751c4a |
@httpretty.activate
|
|
Packit Service |
751c4a |
def test_read_file_or_url_str_from_url_redacts_noheaders(self):
|
|
Packit Service |
751c4a |
"""When no headers_redact, header values are in logs and requests."""
|
|
Packit Service |
751c4a |
url = 'http://hostname/path'
|
|
Packit Service |
751c4a |
headers = {'sensitive': 'sekret', 'server': 'blah'}
|
|
Packit Service |
751c4a |
httpretty.register_uri(httpretty.GET, url)
|
|
Packit Service |
751c4a |
|
|
Packit Service |
751c4a |
read_file_or_url(url, headers=headers)
|
|
Packit Service |
751c4a |
for k in headers.keys():
|
|
Packit Service |
751c4a |
self.assertEqual(headers[k], httpretty.last_request().headers[k])
|
|
Packit Service |
751c4a |
logs = self.logs.getvalue()
|
|
Packit Service |
751c4a |
self.assertNotIn(REDACTED, logs)
|
|
Packit Service |
751c4a |
self.assertIn('sekret', logs)
|
|
Packit Service |
751c4a |
|
|
Packit Service |
a04d08 |
@mock.patch(M_PATH + 'readurl')
|
|
Packit Service |
a04d08 |
def test_read_file_or_url_passes_params_to_readurl(self, m_readurl):
|
|
Packit Service |
a04d08 |
"""read_file_or_url passes all params through to readurl."""
|
|
Packit Service |
a04d08 |
url = 'http://hostname/path'
|
|
Packit Service |
a04d08 |
response = 'This is my url content\n'
|
|
Packit Service |
a04d08 |
m_readurl.return_value = response
|
|
Packit Service |
a04d08 |
params = {'url': url, 'timeout': 1, 'retries': 2,
|
|
Packit Service |
a04d08 |
'headers': {'somehdr': 'val'},
|
|
Packit Service |
a04d08 |
'data': 'data', 'sec_between': 1,
|
|
Packit Service |
a04d08 |
'ssl_details': {'cert_file': '/path/cert.pem'},
|
|
Packit Service |
a04d08 |
'headers_cb': 'headers_cb', 'exception_cb': 'exception_cb'}
|
|
Packit Service |
a04d08 |
self.assertEqual(response, read_file_or_url(**params))
|
|
Packit Service |
a04d08 |
params.pop('url') # url is passed in as a positional arg
|
|
Packit Service |
a04d08 |
self.assertEqual([mock.call(url, **params)], m_readurl.call_args_list)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_wb_read_url_defaults_honored_by_read_file_or_url_callers(self):
|
|
Packit Service |
a04d08 |
"""Readurl param defaults used when unspecified by read_file_or_url
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
Param defaults tested are as follows:
|
|
Packit Service |
a04d08 |
retries: 0, additional headers None beyond default, method: GET,
|
|
Packit Service |
a04d08 |
data: None, check_status: True and allow_redirects: True
|
|
Packit Service |
a04d08 |
"""
|
|
Packit Service |
a04d08 |
url = 'http://hostname/path'
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
m_response = mock.MagicMock()
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
class FakeSession(requests.Session):
|
|
Packit Service |
a04d08 |
@classmethod
|
|
Packit Service |
a04d08 |
def request(cls, **kwargs):
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
{'url': url, 'allow_redirects': True, 'method': 'GET',
|
|
Packit Service |
a04d08 |
'headers': {
|
|
Packit Service |
a04d08 |
'User-Agent': 'Cloud-Init/%s' % (
|
|
Packit Service |
a04d08 |
version.version_string())}},
|
|
Packit Service |
a04d08 |
kwargs)
|
|
Packit Service |
a04d08 |
return m_response
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
with mock.patch(M_PATH + 'requests.Session') as m_session:
|
|
Packit Service |
a04d08 |
error = requests.exceptions.HTTPError('broke')
|
|
Packit Service |
a04d08 |
m_session.side_effect = [error, FakeSession()]
|
|
Packit Service |
a04d08 |
# assert no retries and check_status == True
|
|
Packit Service |
a04d08 |
with self.assertRaises(UrlError) as context_manager:
|
|
Packit Service |
a04d08 |
response = read_file_or_url(url)
|
|
Packit Service |
a04d08 |
self.assertEqual('broke', str(context_manager.exception))
|
|
Packit Service |
a04d08 |
# assert default headers, method, url and allow_redirects True
|
|
Packit Service |
a04d08 |
# Success on 2nd call with FakeSession
|
|
Packit Service |
a04d08 |
response = read_file_or_url(url)
|
|
Packit Service |
a04d08 |
self.assertEqual(m_response, response._response)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
class TestRetryOnUrlExc(CiTestCase):
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_do_not_retry_non_urlerror(self):
|
|
Packit Service |
a04d08 |
"""When exception is not UrlError return False."""
|
|
Packit Service |
a04d08 |
myerror = IOError('something unexcpected')
|
|
Packit Service |
a04d08 |
self.assertFalse(retry_on_url_exc(msg='', exc=myerror))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_perform_retries_on_not_found(self):
|
|
Packit Service |
a04d08 |
"""When exception is UrlError with a 404 status code return True."""
|
|
Packit Service |
a04d08 |
myerror = UrlError(cause=RuntimeError(
|
|
Packit Service |
a04d08 |
'something was not found'), code=NOT_FOUND)
|
|
Packit Service |
a04d08 |
self.assertTrue(retry_on_url_exc(msg='', exc=myerror))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_perform_retries_on_timeout(self):
|
|
Packit Service |
a04d08 |
"""When exception is a requests.Timout return True."""
|
|
Packit Service |
a04d08 |
myerror = UrlError(cause=requests.Timeout('something timed out'))
|
|
Packit Service |
a04d08 |
self.assertTrue(retry_on_url_exc(msg='', exc=myerror))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
# vi: ts=4 expandtab
|