summaryrefslogtreecommitdiffstats
path: root/test/units/galaxy/test_role_install.py
blob: 8e77352a30f2f95d006db3f1415be4c95b81c01c (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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# -*- coding: utf-8 -*-
# Copyright: (c) 2019, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

from __future__ import annotations


import json
import os
import functools
import pytest
import tempfile

from io import StringIO
from ansible import context
from ansible.cli.galaxy import GalaxyCLI
from ansible.galaxy import api, role, Galaxy
from ansible.module_utils.common.text.converters import to_text
from ansible.utils import context_objects as co


def call_galaxy_cli(args):
    orig = co.GlobalCLIArgs._Singleton__instance
    co.GlobalCLIArgs._Singleton__instance = None
    try:
        return GalaxyCLI(args=['ansible-galaxy', 'role'] + args).run()
    finally:
        co.GlobalCLIArgs._Singleton__instance = orig


@pytest.fixture(autouse=True)
def reset_cli_args():
    co.GlobalCLIArgs._Singleton__instance = None
    yield
    co.GlobalCLIArgs._Singleton__instance = None


@pytest.fixture(autouse=True)
def galaxy_server():
    context.CLIARGS._store = {'ignore_certs': False}
    galaxy_api = api.GalaxyAPI(None, 'test_server', 'https://galaxy.ansible.com')
    return galaxy_api


@pytest.fixture(autouse=True)
def init_role_dir(tmp_path_factory):
    test_dir = to_text(tmp_path_factory.mktemp('test-ÅÑŚÌβŁÈ Roles Input'))
    namespace = 'ansible_namespace'
    role = 'role'
    skeleton_path = os.path.join(os.path.dirname(os.path.split(__file__)[0]), 'cli', 'test_data', 'role_skeleton')
    call_galaxy_cli(['init', '%s.%s' % (namespace, role), '-c', '--init-path', test_dir, '--role-skeleton', skeleton_path])


def mock_NamedTemporaryFile(mocker, **args):
    mock_ntf = mocker.MagicMock()
    mock_ntf.write = mocker.MagicMock()
    mock_ntf.close = mocker.MagicMock()
    mock_ntf.name = None
    return mock_ntf


@pytest.fixture
def init_mock_temp_file(mocker, monkeypatch):
    monkeypatch.setattr(tempfile, 'NamedTemporaryFile', functools.partial(mock_NamedTemporaryFile, mocker))


@pytest.fixture(autouse=True)
def mock_role_download_api(mocker, monkeypatch):
    mock_role_api = mocker.MagicMock()
    mock_role_api.side_effect = [
        StringIO(u''),
    ]
    monkeypatch.setattr(role, 'open_url', mock_role_api)
    return mock_role_api


def test_role_download_github(init_mock_temp_file, mocker, galaxy_server, mock_role_download_api, monkeypatch):
    mock_api = mocker.MagicMock()
    mock_api.side_effect = [
        StringIO(u'{"available_versions":{"v1":"v1/"}}'),
        StringIO(u'{"results":[{"id":"123","github_user":"test_owner","github_repo": "test_role"}]}'),
        StringIO(u'{"results":[{"name": "0.0.1"},{"name": "0.0.2"}]}'),
    ]
    monkeypatch.setattr(api, 'open_url', mock_api)

    role.GalaxyRole(Galaxy(), galaxy_server, 'test_owner.test_role', version="0.0.1").install()

    assert mock_role_download_api.call_count == 1
    assert mock_role_download_api.mock_calls[0][1][0] == 'https://github.com/test_owner/test_role/archive/0.0.1.tar.gz'


def test_role_download_github_default_version(init_mock_temp_file, mocker, galaxy_server, mock_role_download_api, monkeypatch):
    mock_api = mocker.MagicMock()
    mock_api.side_effect = [
        StringIO(u'{"available_versions":{"v1":"v1/"}}'),
        StringIO(u'{"results":[{"id":"123","github_user":"test_owner","github_repo": "test_role"}]}'),
        StringIO(u'{"results":[{"name": "0.0.1"},{"name": "0.0.2"}]}'),
    ]
    monkeypatch.setattr(api, 'open_url', mock_api)

    role.GalaxyRole(Galaxy(), galaxy_server, 'test_owner.test_role').install()

    assert mock_role_download_api.call_count == 1
    assert mock_role_download_api.mock_calls[0][1][0] == 'https://github.com/test_owner/test_role/archive/0.0.2.tar.gz'


def test_role_download_github_no_download_url_for_version(init_mock_temp_file, mocker, galaxy_server, mock_role_download_api, monkeypatch):
    mock_api = mocker.MagicMock()
    mock_api.side_effect = [
        StringIO(u'{"available_versions":{"v1":"v1/"}}'),
        StringIO(u'{"results":[{"id":"123","github_user":"test_owner","github_repo": "test_role"}]}'),
        StringIO(u'{"results":[{"name": "0.0.1"},{"name": "0.0.2","download_url":"http://localhost:8080/test_owner/test_role/0.0.2.tar.gz"}]}'),
    ]
    monkeypatch.setattr(api, 'open_url', mock_api)

    role.GalaxyRole(Galaxy(), galaxy_server, 'test_owner.test_role', version="0.0.1").install()

    assert mock_role_download_api.call_count == 1
    assert mock_role_download_api.mock_calls[0][1][0] == 'https://github.com/test_owner/test_role/archive/0.0.1.tar.gz'


@pytest.mark.parametrize(
    'state,rc',
    [('SUCCESS', 0), ('FAILED', 1),]
)
def test_role_import(state, rc, mocker, galaxy_server, monkeypatch):
    responses = [
        {"available_versions": {"v1": "v1/"}},
        {"results": [{'id': 12345, 'github_user': 'user', 'github_repo': 'role', 'github_reference': None, 'summary_fields': {'role': {'name': 'role'}}}]},
        {"results": [{'state': 'WAITING', 'id': 12345, 'summary_fields': {'task_messages': []}}]},
        {"results": [{'state': state, 'id': 12345, 'summary_fields': {'task_messages': []}}]},
    ]
    mock_api = mocker.MagicMock(side_effect=[StringIO(json.dumps(rsp)) for rsp in responses])
    monkeypatch.setattr(api, 'open_url', mock_api)
    assert call_galaxy_cli(['import', 'user', 'role']) == rc


def test_role_download_url(init_mock_temp_file, mocker, galaxy_server, mock_role_download_api, monkeypatch):
    mock_api = mocker.MagicMock()
    mock_api.side_effect = [
        StringIO(u'{"available_versions":{"v1":"v1/"}}'),
        StringIO(u'{"results":[{"id":"123","github_user":"test_owner","github_repo": "test_role"}]}'),
        StringIO(u'{"results":[{"name": "0.0.1","download_url":"http://localhost:8080/test_owner/test_role/0.0.1.tar.gz"},'
                 u'{"name": "0.0.2","download_url":"http://localhost:8080/test_owner/test_role/0.0.2.tar.gz"}]}'),
    ]
    monkeypatch.setattr(api, 'open_url', mock_api)

    role.GalaxyRole(Galaxy(), galaxy_server, 'test_owner.test_role', version="0.0.1").install()

    assert mock_role_download_api.call_count == 1
    assert mock_role_download_api.mock_calls[0][1][0] == 'http://localhost:8080/test_owner/test_role/0.0.1.tar.gz'


def test_role_download_url_default_version(init_mock_temp_file, mocker, galaxy_server, mock_role_download_api, monkeypatch):
    mock_api = mocker.MagicMock()
    mock_api.side_effect = [
        StringIO(u'{"available_versions":{"v1":"v1/"}}'),
        StringIO(u'{"results":[{"id":"123","github_user":"test_owner","github_repo": "test_role"}]}'),
        StringIO(u'{"results":[{"name": "0.0.1","download_url":"http://localhost:8080/test_owner/test_role/0.0.1.tar.gz"},'
                 u'{"name": "0.0.2","download_url":"http://localhost:8080/test_owner/test_role/0.0.2.tar.gz"}]}'),
    ]
    monkeypatch.setattr(api, 'open_url', mock_api)

    role.GalaxyRole(Galaxy(), galaxy_server, 'test_owner.test_role').install()

    assert mock_role_download_api.call_count == 1
    assert mock_role_download_api.mock_calls[0][1][0] == 'http://localhost:8080/test_owner/test_role/0.0.2.tar.gz'