def create_resolver(configure=True):
        resolver = MagicMock()
        resolver.nameservers = default_nameservers if configure else []

        def mock_resolver_resolve(target, rdtype=None, lifetime=None):
            resolver_index = tuple(sorted(resolver.nameservers))
            assert resolver_index in nameserver_resolve_sequence, 'No resolver sequence for {0}'.format(
                resolver_index)
            resolve_sequence = nameserver_resolve_sequence[resolver_index]
            assert len(resolve_sequence
                       ) > 0, 'Resolver sequence for {0} is empty'.format(
                           resolver_index)
            resolve_data = resolve_sequence[0]
            del resolve_sequence[0]

            assert target == resolve_data[
                'target'], 'target: {0!r} vs {1!r}'.format(
                    target, resolve_data['target'])
            assert rdtype == resolve_data.get(
                'rdtype'), 'rdtype: {0!r} vs {1!r}'.format(
                    rdtype, resolve_data.get('rdtype'))
            assert lifetime == resolve_data[
                'lifetime'], 'lifetime: {0!r} vs {1!r}'.format(
                    lifetime, resolve_data['lifetime'])

            if 'raise' in resolve_data:
                raise resolve_data['raise']

            return resolve_data['result']

        resolver.resolve = MagicMock(side_effect=mock_resolver_resolve)
        return resolver
Exemple #2
0
def test_extract_error_message():
    api = HetznerAPI(MagicMock(), '123')
    assert api._extract_error_message(None) == ''
    assert api._extract_error_message('foo') == ' with data: foo'
    assert api._extract_error_message(dict()) == ' with data: {}'
    assert api._extract_error_message(
        dict(message='')) == " with data: {'message': ''}"
    assert api._extract_error_message(
        dict(message='foo')) == ' with message "foo"'
    assert api._extract_error_message(dict(message='foo',
                                           error='')) == ' with message "foo"'
    assert api._extract_error_message(dict(
        message='foo', error=dict())) == ' with message "foo"'
    assert api._extract_error_message(
        dict(message='foo',
             error=dict(code=123))) == ' (error code 123) with message "foo"'
    assert api._extract_error_message(
        dict(message='foo', error=dict(
            message='baz'))) == ' with error message "baz" with message "foo"'
    assert api._extract_error_message(
        dict(message='foo', error=dict(message='baz', code=123))) == (
            ' with error message "baz" (error code 123) with message "foo"')
    assert api._extract_error_message(dict(
        error=dict(message='baz',
                   code=123))) == ' with error message "baz" (error code 123)'
def test_extract_error_message():
    api = JSONAPIHelper(MagicMock(), '123', 'https://example.com')
    assert api._extract_error_message(None) == ''
    assert api._extract_error_message('foo') == ' with data: foo'
    assert api._extract_error_message(dict()) == ' with data: {}'
    assert api._extract_error_message(
        dict(message='')) == " with data: {'message': ''}"
    assert api._extract_error_message(
        dict(message='foo')) == " with data: {'message': 'foo'}"
Exemple #4
0
def test_assert_requirements_present():
    class ModuleFailException(Exception):
        pass

    def fail_json(**kwargs):
        raise ModuleFailException(kwargs)

    module = MagicMock()
    module.fail_json = MagicMock(side_effect=fail_json)

    orig_importerror = resolver.DNSPYTHON_IMPORTERROR
    resolver.DNSPYTHON_IMPORTERROR = None
    assert_requirements_present(module)

    resolver.DNSPYTHON_IMPORTERROR = 'asdf'
    with pytest.raises(ModuleFailException) as exc:
        assert_requirements_present(module)

    assert 'dnspython' in exc.value.args[0]['msg']
    assert 'asdf' == exc.value.args[0]['exception']

    resolver.DNSPYTHON_IMPORTERROR = orig_importerror
Exemple #5
0
def test_list_pagination():
    def get_1(url, query=None, must_have_content=True, expected=None):
        assert url == 'https://example.com'
        assert must_have_content is True
        assert expected == [200]
        assert query is not None
        assert len(query) == 2
        assert query['limit'] == 1
        assert query['offset'] in [0, 1, 2]
        if query['offset'] < 2:
            return {'data': [query['offset']]}, {}
        else:
            return {'data': []}, {}

    def get_2(url, query=None, must_have_content=True, expected=None):
        assert url == 'https://example.com'
        assert must_have_content is True
        assert expected == [200]
        assert query is not None
        assert len(query) == 3
        assert query['foo'] == 'bar'
        assert query['limit'] == 2
        assert query['offset'] in [0, 2]
        if query['offset'] < 2:
            return {'data': ['bar', 'baz']}, {}
        else:
            return {'data': ['foo']}, {}

    api = HostTechJSONAPI(MagicMock(), '123')

    api._get = MagicMock(side_effect=get_1)
    result = api._list_pagination('https://example.com', block_size=1)
    assert result == [0, 1]

    api._get = MagicMock(side_effect=get_2)
    result = api._list_pagination('https://example.com',
                                  query=dict(foo='bar'),
                                  block_size=2)
    assert result == ['bar', 'baz', 'foo']
def test_wsdl_missing():
    option_provider = CustomProvideOptions({
        'hosttech_username': '******',
        'hosttech_password': '******',
    })
    old_value = api.HAS_LXML_ETREE
    try:
        api.HAS_LXML_ETREE = False
        with pytest.raises(DNSAPIError) as exc:
            api.create_hosttech_api(option_provider, MagicMock())
        assert exc.value.args[
            0] == 'Needs lxml Python module (pip install lxml)'
    finally:
        api.HAS_LXML_ETREE = old_value
Exemple #7
0
def test_extract_error_message():
    api = HostTechJSONAPI(MagicMock(), '123')
    assert api._extract_error_message(None) == ''
    assert api._extract_error_message('foo') == ' with data: foo'
    assert api._extract_error_message(dict()) == ' with data: {}'
    assert api._extract_error_message(
        dict(message='')) == " with data: {'message': ''}"
    assert api._extract_error_message(
        dict(message='foo')) == ' with message "foo"'
    assert api._extract_error_message(dict(message='foo',
                                           errors='')) == ' with message "foo"'
    assert api._extract_error_message(dict(
        message='foo', errors=dict())) == ' with message "foo"'
    assert api._extract_error_message(
        dict(message='foo', errors=dict(
            bar='baz'))) == ' with message "foo" (field "bar": baz)'
    assert api._extract_error_message(
        dict(errors=dict(bar=['baz', 'bam'], arf='fra'))
    ) == ' (field "arf": fra) (field "bar": baz; bam)'
Exemple #8
0
def test_update_id_delete():
    api = HetznerAPI(MagicMock(), '123')
    with pytest.raises(DNSAPIError) as exc:
        api.delete_record(1, DNSRecord())
    assert exc.value.args[0] == 'Need record ID to delete record!'
def test_internal_error():
    option_provider = CustomProvideOptions({})
    with pytest.raises(DNSAPIError) as exc:
        api.create_hosttech_api(option_provider, MagicMock())
    assert exc.value.args[
        0] == 'One of hosttech_token or both hosttech_username and hosttech_password must be provided!'
 def setUp(self):
     templar = MagicMock()
     templar._loader = None
     self.lookup = lookup_loader.get("community.general.dependent",
                                     templar=templar)
 def setUp(self):
     templar = MagicMock()
     templar._loader = None
     self.lookup = lookup_loader.get("felixfontein.tools.dependent",
                                     templar=templar)
def test_validate():
    module = MagicMock()
    api = JSONAPIHelper(module, '123', 'https://example.com')
    with pytest.raises(DNSAPIError) as exc:
        api._validate()
    assert exc.value.args[0] == 'Internal error: info needs to be provided'
Exemple #13
0
def test_update_id_missing():
    api = HostTechJSONAPI(MagicMock(), '123')
    with pytest.raises(DNSAPIError) as exc:
        api.update_record(1, DNSRecord())
    assert exc.value.args[0] == 'Need record ID to update record!'
def create_mock_response(rcode, authority=None, answer=None):
    response = MagicMock()
    response.rcode = MagicMock(return_value=rcode)
    response.authority = authority or []
    response.answer = answer or []
    return response
def create_mock_answer(rrset=None):
    answer = MagicMock()
    answer.rrset = rrset
    return answer
def test_process_json_result():
    http_helper = MagicMock()
    api = JSONAPIHelper(http_helper, '123', 'https://example.com')
    with pytest.raises(DNSAPIError) as exc:
        api._process_json_result(content=None,
                                 info=dict(status=401,
                                           url='https://example.com'))
    assert exc.value.args[
        0] == 'Unauthorized: the authentication parameters are incorrect (HTTP status 401)'
    with pytest.raises(DNSAPIError) as exc:
        api._process_json_result(content='{"message": ""}'.encode('utf-8'),
                                 info=dict(status=401,
                                           url='https://example.com'))
    assert exc.value.args[
        0] == 'Unauthorized: the authentication parameters are incorrect (HTTP status 401)'
    with pytest.raises(DNSAPIError) as exc:
        api._process_json_result(content='{"message": "foo"}'.encode('utf-8'),
                                 info=dict(status=401,
                                           url='https://example.com'))
    assert exc.value.args[
        0] == 'Unauthorized: the authentication parameters are incorrect (HTTP status 401): foo'
    with pytest.raises(DNSAPIError) as exc:
        api._process_json_result(content=None,
                                 info=dict(status=403,
                                           url='https://example.com'))
    assert exc.value.args[
        0] == 'Forbidden: you do not have access to this resource (HTTP status 403)'
    with pytest.raises(DNSAPIError) as exc:
        api._process_json_result(content='{"message": ""}'.encode('utf-8'),
                                 info=dict(status=403,
                                           url='https://example.com'))
    assert exc.value.args[
        0] == 'Forbidden: you do not have access to this resource (HTTP status 403)'
    with pytest.raises(DNSAPIError) as exc:
        api._process_json_result(content='{"message": "foo"}'.encode('utf-8'),
                                 info=dict(status=403,
                                           url='https://example.com'))
    assert exc.value.args[
        0] == 'Forbidden: you do not have access to this resource (HTTP status 403): foo'

    info = dict(status=200, url='https://example.com')
    info['content-TYPE'] = 'application/json'
    with pytest.raises(DNSAPIError) as exc:
        api._process_json_result(content='not JSON'.encode('utf-8'), info=info)
    assert exc.value.args[
        0] == 'GET https://example.com did not yield JSON data, but HTTP status code 200 with data: not JSON'

    info = dict(status=200, url='https://example.com')
    info['Content-type'] = 'application/json'
    r, i = api._process_json_result(content='not JSON'.encode('utf-8'),
                                    info=info,
                                    must_have_content=False)
    assert r is None
    info = dict(status=200, url='https://example.com')
    info['Content-type'] = 'application/json'
    assert i == info

    info = dict(status=404, url='https://example.com')
    info['content-type'] = 'application/json'
    with pytest.raises(DNSAPIError) as exc:
        api._process_json_result(content='{}'.encode('utf-8'), info=info)
    assert exc.value.args[
        0] == 'Expected successful HTTP status for GET https://example.com, but got HTTP status 404 (Not found) with data: {}'

    info = dict(status=404, url='https://example.com')
    info['content-type'] = 'application/json'
    with pytest.raises(DNSAPIError) as exc:
        api._process_json_result(content='{}'.encode('utf-8'),
                                 info=info,
                                 expected=[200, 201])
    assert exc.value.args[
        0] == 'Expected HTTP status 200, 201 for GET https://example.com, but got HTTP status 404 (Not found) with data: {}'
Exemple #17
0
def test_list_pagination():
    def get_1(url, query=None, must_have_content=True, expected=None):
        assert url == 'https://example.com'
        assert must_have_content == [200]
        assert expected == [200]
        assert query is not None
        assert len(query) == 2
        assert query['per_page'] == 1
        assert query['page'] in [1, 2, 3]
        if query['page'] < 3:
            return {
                'data': [query['page']],
                'meta': {
                    'pagination': {
                        'page': query['page'],
                        'per_page': 1,
                        'last_page': 3,
                        'total_entries': 2,
                    },
                },
            }, {
                'status': 200
            }
        else:
            return {
                'data': [],
                'meta': {
                    'pagination': {
                        'page': query['page'],
                        'per_page': 1,
                        'last_page': 3,
                        'total_entries': 2,
                    },
                },
            }, {
                'status': 200
            }

    def get_2(url, query=None, must_have_content=True, expected=None):
        assert url == 'https://example.com'
        assert must_have_content == [200]
        assert expected == ([200, 404] if query['page'] == 1 else [200])
        assert query is not None
        assert len(query) == 3
        assert query['foo'] == 'bar'
        assert query['per_page'] == 2
        assert query['page'] in [1, 2]
        if query['page'] < 2:
            return {
                'foobar': ['bar', 'baz'],
                'meta': {
                    'pagination': {
                        'page': query['page'],
                        'per_page': 2,
                        'last_page': 2,
                        'total_entries': 3,
                    },
                },
            }, {
                'status': 200
            }
        else:
            return {
                'foobar': ['foo'],
                'meta': {
                    'pagination': {
                        'page': query['page'],
                        'per_page': 2,
                        'last_page': 2,
                        'total_entries': 3,
                    },
                },
            }, {
                'status': 200
            }

    def get_3(url, query=None, must_have_content=True, expected=None):
        assert url == 'https://example.com'
        assert must_have_content == [200]
        assert expected == [200, 404]
        assert query is not None
        assert len(query) == 2
        assert query['per_page'] == 100
        assert query['page'] == 1
        return None, {'status': 404}

    api = HetznerAPI(MagicMock(), '123')

    api._get = MagicMock(side_effect=get_1)
    result = api._list_pagination('https://example.com',
                                  'data',
                                  block_size=1,
                                  accept_404=False)
    assert result == [1, 2]

    api._get = MagicMock(side_effect=get_2)
    result = api._list_pagination('https://example.com',
                                  'foobar',
                                  query=dict(foo='bar'),
                                  block_size=2,
                                  accept_404=True)
    assert result == ['bar', 'baz', 'foo']

    api._get = MagicMock(side_effect=get_3)
    result = api._list_pagination('https://example.com',
                                  'baz',
                                  accept_404=True)
    assert result is None
Exemple #18
0
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

from __future__ import (absolute_import, division, print_function)

__metaclass__ = type

from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import MagicMock
from ansible.utils.path import unfrackpath

mock_unfrackpath_noop = MagicMock(spec_set=unfrackpath,
                                  side_effect=lambda x, *args, **kwargs: x)
Exemple #19
0
def test_no_response():
    fake_query = MagicMock()
    fake_query.question = 'Doctor Who?'
    resolver = mock_resolver(
        ['1.1.1.1'], {
            ('1.1.1.1', ): [
                {
                    'target':
                    'ns.example.com',
                    'lifetime':
                    10,
                    'result':
                    create_mock_answer(
                        dns.rrset.from_rdata(
                            'ns.example.com',
                            300,
                            dns.rdata.from_text(dns.rdataclass.IN,
                                                dns.rdatatype.A, '3.3.3.3'),
                            dns.rdata.from_text(dns.rdataclass.IN,
                                                dns.rdatatype.A, '5.5.5.5'),
                        )),
                },
                {
                    'target':
                    'ns2.example.com',
                    'lifetime':
                    10,
                    'result':
                    create_mock_answer(
                        dns.rrset.from_rdata(
                            'ns.example.com',
                            300,
                            dns.rdata.from_text(dns.rdataclass.IN,
                                                dns.rdatatype.A, '4.4.4.4'),
                        )),
                },
            ],
            ('3.3.3.3', '5.5.5.5'): [
                {
                    'target': dns.name.from_unicode(u'example.com'),
                    'lifetime': 10,
                    'result': create_mock_answer(),
                },
            ],
            ('4.4.4.4', ): [
                {
                    'target': dns.name.from_unicode(u'example.com'),
                    'lifetime': 10,
                    'raise': dns.resolver.NoAnswer(response=fake_query),
                },
            ],
        })
    udp_sequence = [
        {
            'query_target':
            dns.name.from_unicode(u'com'),
            'query_type':
            dns.rdatatype.NS,
            'nameserver':
            '1.1.1.1',
            'kwargs': {
                'timeout': 10,
            },
            'result':
            create_mock_response(dns.rcode.NOERROR,
                                 answer=[
                                     dns.rrset.from_rdata(
                                         'com',
                                         3600,
                                         dns.rdata.from_text(
                                             dns.rdataclass.IN,
                                             dns.rdatatype.NS, 'ns.com'),
                                     )
                                 ]),
        },
        {
            'query_target':
            dns.name.from_unicode(u'example.com'),
            'query_type':
            dns.rdatatype.NS,
            'nameserver':
            '1.1.1.1',
            'kwargs': {
                'timeout': 10,
            },
            'result':
            create_mock_response(
                dns.rcode.NOERROR,
                answer=[
                    dns.rrset.from_rdata(
                        'example.com',
                        3600,
                        dns.rdata.from_text(dns.rdataclass.IN,
                                            dns.rdatatype.NS,
                                            'ns.example.com'),
                        dns.rdata.from_text(dns.rdataclass.IN,
                                            dns.rdatatype.NS,
                                            'ns2.example.com'),
                    )
                ]),
        },
    ]
    with patch('dns.resolver.get_default_resolver', resolver):
        with patch('dns.resolver.Resolver', resolver):
            with patch('dns.query.udp', mock_query_udp(udp_sequence)):
                resolver = ResolveDirectlyFromNameServers()
                rrset_dict = resolver.resolve('example.com')
                assert sorted(rrset_dict.keys()) == [
                    'ns.example.com', 'ns2.example.com'
                ]
                assert rrset_dict['ns.example.com'] is None
                assert rrset_dict['ns2.example.com'] is None
                # Verify nameserver IPs
                assert resolver.resolve_nameservers('example.com') == [
                    'ns.example.com', 'ns2.example.com'
                ]
                assert resolver.resolve_nameservers(
                    'example.com', resolve_addresses=True) == [
                        '3.3.3.3', '4.4.4.4', '5.5.5.5'
                    ]
Exemple #20
0
def test_composer_generation():
    composer = Composer(MagicMock(), api='https://example.com/api')
    composer.add_simple_command('test',
                                int_value=42,
                                str_value='bar',
                                list_value=[1, 2, 3],
                                dict_value={
                                    'hello': 'world',
                                    'list': [2, 3, 5, 7],
                                })
    command = to_native(lxmletree.tostring(composer._root,
                                           pretty_print=True)).splitlines()

    print(command)

    expected_lines = [
        '  <SOAP-ENV:Header/>',
        '  <SOAP-ENV:Body>',
        '    <ns0:test xmlns:ns0="https://example.com/api">',
        '      <int_value xsi:type="xsd:int">42</int_value>',
        '      <str_value xsi:type="xsd:string">bar</str_value>',
        '      <list_value xsi:type="SOAP-ENC:Array">',
        '        <item xsi:type="xsd:int">1</item>',
        '        <item xsi:type="xsd:int">2</item>',
        '        <item xsi:type="xsd:int">3</item>',
        '      </list_value>',
        '      <dict_value xmlns:ns0="http://xml.apache.org/xml-soap" xsi:type="ns0:Map">',
        '        <item>',
        '          <key xsi:type="xsd:string">hello</key>',
        '          <value xsi:type="xsd:string">world</value>',
        '        </item>',
        '        <item>',
        '          <key xsi:type="xsd:string">list</key>',
        '          <value xsi:type="SOAP-ENC:Array">',
        '            <item xsi:type="xsd:int">2</item>',
        '            <item xsi:type="xsd:int">3</item>',
        '            <item xsi:type="xsd:int">5</item>',
        '            <item xsi:type="xsd:int">7</item>',
        '          </value>',
        '        </item>',
        '      </dict_value>',
        '    </ns0:test>',
        '  </SOAP-ENV:Body>',
        '</SOAP-ENV:Envelope>',
    ]

    if sys.version_info < (3, 7):
        assert sorted(command[1:]) == sorted(expected_lines)
    else:
        assert command[1:] == expected_lines

    for part in [
            '<SOAP-ENV:Envelope',
            ' xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"',
            ' xmlns:xsd="http://www.w3.org/2001/XMLSchema"',
            ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"',
            ' xmlns:ns2="auth"',
            ' xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"',
            ' SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"',
    ]:
        assert part in command[0]