summaryrefslogtreecommitdiff
path: root/test/units/module_utils/xenserver/conftest.py
blob: 647758a3b1cfa5aa672714d419156cf45f247fce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# -*- coding: utf-8 -*-
#
# Copyright: (c) 2019, Bojan Vitnik <bvitnik@mainstream.rs>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

from __future__ import absolute_import, division, print_function
__metaclass__ = type


import sys
import importlib
import os
import json
import pytest

from .FakeAnsibleModule import FakeAnsibleModule
from ansible.module_utils import six
from mock import MagicMock


@pytest.fixture
def fake_ansible_module(request):
    """Returns fake AnsibleModule with fake module params."""
    if hasattr(request, 'param'):
        return FakeAnsibleModule(request.param)
    else:
        params = {
            "hostname": "somehost",
            "username": "someuser",
            "password": "somepwd",
            "validate_certs": True,
        }

        return FakeAnsibleModule(params)


@pytest.fixture(autouse=True)
def XenAPI():
    """Imports and returns fake XenAPI module."""

    # Import of fake XenAPI module is wrapped by fixture so that it does not
    # affect other unit tests which could potentialy also use XenAPI module.

    # First we use importlib.import_module() to import the module and assign
    # it to a local symbol.
    fake_xenapi = importlib.import_module('units.module_utils.xenserver.FakeXenAPI')

    # Now we populate Python module cache with imported fake module using the
    # original module name (XenAPI). That way, any 'import XenAPI' statement
    # will just load already imported fake module from the cache.
    sys.modules['XenAPI'] = fake_xenapi

    return fake_xenapi


@pytest.fixture(autouse=True)
def xenserver(XenAPI):
    """Imports and returns xenserver module util."""

    # Since we are wrapping fake XenAPI module inside a fixture, all modules
    # that depend on it have to be imported inside a test function. To make
    # this easier to handle and remove some code repetition, we wrap the import
    # of xenserver module util with a fixture.
    from ansible.module_utils import xenserver

    return xenserver


@pytest.fixture
def mock_xenapi_failure(XenAPI, mocker):
    """
    Returns mock object that raises XenAPI.Failure on any XenAPI
    method call.
    """
    fake_error_msg = "Fake XAPI method call error!"

    # We need to use our MagicMock based class that passes side_effect to its
    # children because calls to xenapi methods can generate an arbitrary
    # hierarchy of mock objects. Any such object when called should use the
    # same side_effect as its parent mock object.
    class MagicMockSideEffect(MagicMock):
        def _get_child_mock(self, **kw):
            child_mock = super(MagicMockSideEffect, self)._get_child_mock(**kw)
            child_mock.side_effect = self.side_effect
            return child_mock

    mocked_xenapi = mocker.patch.object(XenAPI.Session, 'xenapi', new=MagicMockSideEffect(), create=True)
    mocked_xenapi.side_effect = XenAPI.Failure(fake_error_msg)

    return mocked_xenapi, fake_error_msg


@pytest.fixture
def fixture_data_from_file(request):
    """Loads fixture data from files."""
    if not hasattr(request, 'param'):
        return {}

    fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures')
    fixture_data = {}

    if isinstance(request.param, six.string_types):
        request.param = [request.param]

    for fixture_name in request.param:
        path = os.path.join(fixture_path, fixture_name)

        with open(path) as f:
            data = f.read()

        try:
            data = json.loads(data)
        except Exception:
            pass

        fixture_data[fixture_name] = data

    return fixture_data