Blame cloudinit/tests/test_url_helper.py

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