summaryrefslogtreecommitdiffstats
path: root/test/units/galaxy/test_collection.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/units/galaxy/test_collection.py')
-rw-r--r--test/units/galaxy/test_collection.py229
1 files changed, 216 insertions, 13 deletions
diff --git a/test/units/galaxy/test_collection.py b/test/units/galaxy/test_collection.py
index 8d0aff3c86..6276fb346c 100644
--- a/test/units/galaxy/test_collection.py
+++ b/test/units/galaxy/test_collection.py
@@ -56,6 +56,13 @@ def collection_input(tmp_path_factory):
@pytest.fixture()
+def galaxy_api_version(monkeypatch):
+ mock_avail_ver = MagicMock()
+ mock_avail_ver.return_value = {'v2': '/api/v2'}
+ monkeypatch.setattr(collection, 'get_available_api_versions', mock_avail_ver)
+
+
+@pytest.fixture()
def collection_artifact(monkeypatch, tmp_path_factory):
''' Creates a temp collection artifact and mocked open_url instance for publishing tests '''
mock_open = MagicMock()
@@ -421,6 +428,10 @@ def test_publish_not_a_tarball():
def test_publish_no_wait(galaxy_server, collection_artifact, monkeypatch):
+ mock_avail_ver = MagicMock()
+ mock_avail_ver.return_value = {'v2': '/api/v2'}
+ monkeypatch.setattr(collection, 'get_available_api_versions', mock_avail_ver)
+
mock_display = MagicMock()
monkeypatch.setattr(Display, 'display', mock_display)
@@ -445,12 +456,15 @@ def test_publish_no_wait(galaxy_server, collection_artifact, monkeypatch):
assert mock_display.mock_calls[0][1][0] == "Publishing collection artifact '%s' to %s %s" \
% (artifact_path, galaxy_server.name, galaxy_server.api_server)
assert mock_display.mock_calls[1][1][0] == \
- "Collection has been pushed to the Galaxy server %s %s, not waiting until import has completed due to " \
- "--no-wait being set. Import task results can be found at %s"\
- % (galaxy_server.name, galaxy_server.api_server, fake_import_uri)
+ "Collection has been pushed to the Galaxy server %s %s, not waiting until import has completed due to --no-wait " \
+ "being set. Import task results can be found at %s" % (galaxy_server.name, galaxy_server.api_server, fake_import_uri)
-def test_publish_dont_validate_cert(galaxy_server, collection_artifact):
+def test_publish_dont_validate_cert(galaxy_server, collection_artifact, monkeypatch):
+ mock_avail_ver = MagicMock()
+ mock_avail_ver.return_value = {'v2': '/api/v2'}
+ monkeypatch.setattr(collection, 'get_available_api_versions', mock_avail_ver)
+
galaxy_server.validate_certs = False
artifact_path, mock_open = collection_artifact
@@ -462,29 +476,47 @@ def test_publish_dont_validate_cert(galaxy_server, collection_artifact):
assert mock_open.mock_calls[0][2]['validate_certs'] is False
-def test_publish_failure(galaxy_server, collection_artifact):
+def test_publish_failure(galaxy_server, collection_artifact, monkeypatch):
+ mock_avail_ver = MagicMock()
+ mock_avail_ver.return_value = {'v2': '/api/v2'}
+ monkeypatch.setattr(collection, 'get_available_api_versions', mock_avail_ver)
+
artifact_path, mock_open = collection_artifact
mock_open.side_effect = urllib_error.HTTPError('https://galaxy.server.com', 500, 'msg', {}, StringIO())
- expected = 'Error when publishing collection (HTTP Code: 500, Message: Unknown error returned by Galaxy ' \
+ expected = 'Error when publishing collection to test_server (https://galaxy.ansible.com) ' \
+ '(HTTP Code: 500, Message: Unknown error returned by Galaxy ' \
'server. Code: Unknown)'
with pytest.raises(AnsibleError, match=re.escape(expected)):
collection.publish_collection(artifact_path, galaxy_server, True, 0)
-def test_publish_failure_with_json_info(galaxy_server, collection_artifact):
+def test_publish_failure_with_json_info(galaxy_server, collection_artifact, monkeypatch):
+ mock_avail_ver = MagicMock()
+ mock_avail_ver.return_value = {'v2': '/api/v2'}
+ monkeypatch.setattr(collection, 'get_available_api_versions', mock_avail_ver)
+
artifact_path, mock_open = collection_artifact
return_content = StringIO(u'{"message":"Galaxy error message","code":"GWE002"}')
mock_open.side_effect = urllib_error.HTTPError('https://galaxy.server.com', 503, 'msg', {}, return_content)
- expected = 'Error when publishing collection (HTTP Code: 503, Message: Galaxy error message Code: GWE002)'
+ expected = 'Error when publishing collection to test_server (https://galaxy.ansible.com) ' \
+ '(HTTP Code: 503, Message: Galaxy error message Code: GWE002)'
with pytest.raises(AnsibleError, match=re.escape(expected)):
collection.publish_collection(artifact_path, galaxy_server, True, 0)
-def test_publish_with_wait(galaxy_server, collection_artifact, monkeypatch):
+@pytest.mark.parametrize("api_version,token_type", [
+ ('v2', 'Token'),
+ ('v3', 'Bearer')
+])
+def test_publish_with_wait(api_version, token_type, galaxy_server, collection_artifact, monkeypatch):
+ mock_avail_ver = MagicMock()
+ mock_avail_ver.return_value = {api_version: '/api/%s' % api_version}
+ monkeypatch.setattr(collection, 'get_available_api_versions', mock_avail_ver)
+
mock_display = MagicMock()
monkeypatch.setattr(Display, 'display', mock_display)
@@ -501,7 +533,7 @@ def test_publish_with_wait(galaxy_server, collection_artifact, monkeypatch):
assert mock_open.call_count == 2
assert mock_open.mock_calls[1][1][0] == fake_import_uri
- assert mock_open.mock_calls[1][2]['headers']['Authorization'] == 'Token key'
+ assert mock_open.mock_calls[1][2]['headers']['Authorization'] == '%s key' % token_type
assert mock_open.mock_calls[1][2]['validate_certs'] is True
assert mock_open.mock_calls[1][2]['method'] == 'GET'
@@ -515,7 +547,15 @@ def test_publish_with_wait(galaxy_server, collection_artifact, monkeypatch):
'Galaxy server %s %s' % (galaxy_server.name, galaxy_server.api_server)
-def test_publish_with_wait_timeout(galaxy_server, collection_artifact, monkeypatch):
+@pytest.mark.parametrize("api_version,exp_api_url,token_type", [
+ ('v2', '/api/v2/collections/', 'Token'),
+ ('v3', '/api/v3/artifacts/collections/', 'Bearer')
+])
+def test_publish_with_wait_timeout(api_version, exp_api_url, token_type, galaxy_server, collection_artifact, monkeypatch):
+ mock_avail_ver = MagicMock()
+ mock_avail_ver.return_value = {api_version: '/api/%s' % api_version}
+ monkeypatch.setattr(collection, 'get_available_api_versions', mock_avail_ver)
+
monkeypatch.setattr(time, 'sleep', MagicMock())
mock_vvv = MagicMock()
@@ -535,11 +575,11 @@ def test_publish_with_wait_timeout(galaxy_server, collection_artifact, monkeypat
assert mock_open.call_count == 3
assert mock_open.mock_calls[1][1][0] == fake_import_uri
- assert mock_open.mock_calls[1][2]['headers']['Authorization'] == 'Token key'
+ assert mock_open.mock_calls[1][2]['headers']['Authorization'] == '%s key' % token_type
assert mock_open.mock_calls[1][2]['validate_certs'] is True
assert mock_open.mock_calls[1][2]['method'] == 'GET'
assert mock_open.mock_calls[2][1][0] == fake_import_uri
- assert mock_open.mock_calls[2][2]['headers']['Authorization'] == 'Token key'
+ assert mock_open.mock_calls[2][2]['headers']['Authorization'] == '%s key' % token_type
assert mock_open.mock_calls[2][2]['validate_certs'] is True
assert mock_open.mock_calls[2][2]['method'] == 'GET'
@@ -549,6 +589,10 @@ def test_publish_with_wait_timeout(galaxy_server, collection_artifact, monkeypat
def test_publish_with_wait_timeout_failure(galaxy_server, collection_artifact, monkeypatch):
+ mock_avail_ver = MagicMock()
+ mock_avail_ver.return_value = {'v2': '/api/v2'}
+ monkeypatch.setattr(collection, 'get_available_api_versions', mock_avail_ver)
+
monkeypatch.setattr(time, 'sleep', MagicMock())
mock_vvv = MagicMock()
@@ -588,6 +632,10 @@ def test_publish_with_wait_timeout_failure(galaxy_server, collection_artifact, m
def test_publish_with_wait_and_failure(galaxy_server, collection_artifact, monkeypatch):
+ mock_avail_ver = MagicMock()
+ mock_avail_ver.return_value = {'v2': '/api/v2'}
+ monkeypatch.setattr(collection, 'get_available_api_versions', mock_avail_ver)
+
mock_display = MagicMock()
monkeypatch.setattr(Display, 'display', mock_display)
@@ -661,6 +709,10 @@ def test_publish_with_wait_and_failure(galaxy_server, collection_artifact, monke
def test_publish_with_wait_and_failure_and_no_error(galaxy_server, collection_artifact, monkeypatch):
+ mock_avail_ver = MagicMock()
+ mock_avail_ver.return_value = {'v2': '/api/v2'}
+ monkeypatch.setattr(collection, 'get_available_api_versions', mock_avail_ver)
+
mock_display = MagicMock()
monkeypatch.setattr(Display, 'display', mock_display)
@@ -729,6 +781,69 @@ def test_publish_with_wait_and_failure_and_no_error(galaxy_server, collection_ar
assert mock_err.mock_calls[0][1][0] == 'Galaxy import error message: Some error'
+def test_publish_failure_v3_with_json_info_409_conflict(galaxy_server, collection_artifact, monkeypatch):
+ mock_avail_ver = MagicMock()
+ mock_avail_ver.return_value = {'v3': '/api/v3'}
+ monkeypatch.setattr(collection, 'get_available_api_versions', mock_avail_ver)
+
+ artifact_path, mock_open = collection_artifact
+
+ error_response = {
+ "errors": [
+ {
+ "code": "conflict.collection_exists",
+ "detail": 'Collection "testing-ansible_testing_content-4.0.4" already exists.',
+ "title": "Conflict.",
+ "status": "409",
+ },
+ ]
+ }
+
+ return_content = StringIO(to_text(json.dumps(error_response)))
+ mock_open.side_effect = urllib_error.HTTPError('https://galaxy.server.com', 409, 'msg', {}, return_content)
+
+ expected = 'Error when publishing collection to test_server (https://galaxy.ansible.com) ' \
+ '(HTTP Code: 409, Message: Collection "testing-ansible_testing_content-4.0.4"' \
+ ' already exists. Code: conflict.collection_exists)'
+ with pytest.raises(AnsibleError, match=re.escape(expected)):
+ collection.publish_collection(artifact_path, galaxy_server, True, 0)
+
+
+def test_publish_failure_v3_with_json_info_multiple_errors(galaxy_server, collection_artifact, monkeypatch):
+ mock_avail_ver = MagicMock()
+ mock_avail_ver.return_value = {'v3': '/api/v3'}
+ monkeypatch.setattr(collection, 'get_available_api_versions', mock_avail_ver)
+
+ artifact_path, mock_open = collection_artifact
+
+ error_response = {
+ "errors": [
+ {
+ "code": "conflict.collection_exists",
+ "detail": 'Collection "mynamespace-mycollection-4.1.1" already exists.',
+ "title": "Conflict.",
+ "status": "400",
+ },
+ {
+ "code": "quantum_improbability",
+ "title": "Random(?) quantum improbability.",
+ "source": {"parameter": "the_arrow_of_time"},
+ "meta": {"remediation": "Try again before"}
+ },
+ ]
+ }
+
+ return_content = StringIO(to_text(json.dumps(error_response)))
+ mock_open.side_effect = urllib_error.HTTPError('https://galaxy.server.com', 400, 'msg', {}, return_content)
+
+ expected = 'Error when publishing collection to test_server (https://galaxy.ansible.com) ' \
+ '(HTTP Code: 400, Message: Collection "mynamespace-mycollection-4.1.1"' \
+ ' already exists. Code: conflict.collection_exists),' \
+ ' (HTTP Code: 400, Message: Random(?) quantum improbability. Code: quantum_improbability)'
+ with pytest.raises(AnsibleError, match=re.escape(expected)):
+ collection.publish_collection(artifact_path, galaxy_server, True, 0)
+
+
def test_find_existing_collections(tmp_path_factory, monkeypatch):
test_dir = to_text(tmp_path_factory.mktemp('test-ÅÑŚÌβŁÈ Collections'))
collection1 = os.path.join(test_dir, 'namespace1', 'collection1')
@@ -847,3 +962,91 @@ def test_extract_tar_file_missing_parent_dir(tmp_tarfile):
collection._extract_tar_file(tfile, filename, output_dir, temp_dir, checksum)
os.path.isfile(output_file)
+
+
+def test_get_available_api_versions_v2_auth_not_required_without_auth(galaxy_server, collection_artifact, monkeypatch):
+ # mock_avail_ver = MagicMock()
+ # mock_avail_ver.side_effect = {api_version: '/api/%s' % api_version}
+ # monkeypatch.setattr(collection, 'get_available_api_versions', mock_avail_ver)
+ response_obj = {
+ "description": "GALAXY REST API",
+ "current_version": "v1",
+ "available_versions": {
+ "v1": "/api/v1/",
+ "v2": "/api/v2/"
+ },
+ "server_version": "3.2.4",
+ "version_name": "Doin' it Right",
+ "team_members": [
+ "chouseknecht",
+ "cutwater",
+ "alikins",
+ "newswangerd",
+ "awcrosby",
+ "tima",
+ "gregdek"
+ ]
+ }
+
+ artifact_path, mock_open = collection_artifact
+
+ return_content = StringIO(to_text(json.dumps(response_obj)))
+ mock_open.return_value = return_content
+ res = collection.get_available_api_versions(galaxy_server)
+
+ assert res == {'v1': '/api/v1/', 'v2': '/api/v2/'}
+
+
+def test_get_available_api_versions_v3_auth_required_without_auth(galaxy_server, collection_artifact, monkeypatch):
+ # mock_avail_ver = MagicMock()
+ # mock_avail_ver.side_effect = {api_version: '/api/%s' % api_version}
+ # monkeypatch.setattr(collection, 'get_available_api_versions', mock_avail_ver)
+ error_response = {'code': 'unauthorized', 'detail': 'The request was not authorized'}
+ artifact_path, mock_open = collection_artifact
+
+ return_content = StringIO(to_text(json.dumps(error_response)))
+ mock_open.side_effect = urllib_error.HTTPError('https://galaxy.server.com', 401, 'msg', {'WWW-Authenticate': 'Bearer'}, return_content)
+ with pytest.raises(AnsibleError):
+ collection.get_available_api_versions(galaxy_server)
+
+
+def test_get_available_api_versions_v3_auth_required_with_auth_on_retry(galaxy_server, collection_artifact, monkeypatch):
+ # mock_avail_ver = MagicMock()
+ # mock_avail_ver.side_effect = {api_version: '/api/%s' % api_version}
+ # monkeypatch.setattr(collection, 'get_available_api_versions', mock_avail_ver)
+ error_obj = {'code': 'unauthorized', 'detail': 'The request was not authorized'}
+ success_obj = {
+ "description": "GALAXY REST API",
+ "current_version": "v1",
+ "available_versions": {
+ "v3": "/api/v3/"
+ },
+ "server_version": "3.2.4",
+ "version_name": "Doin' it Right",
+ "team_members": [
+ "chouseknecht",
+ "cutwater",
+ "alikins",
+ "newswangerd",
+ "awcrosby",
+ "tima",
+ "gregdek"
+ ]
+ }
+
+ artifact_path, mock_open = collection_artifact
+
+ error_response = StringIO(to_text(json.dumps(error_obj)))
+ success_response = StringIO(to_text(json.dumps(success_obj)))
+ mock_open.side_effect = [
+ urllib_error.HTTPError('https://galaxy.server.com', 401, 'msg', {'WWW-Authenticate': 'Bearer'}, error_response),
+ success_response,
+ ]
+
+ try:
+ res = collection.get_available_api_versions(galaxy_server)
+ except AnsibleError as err:
+ print(err)
+ raise
+
+ assert res == {'v3': '/api/v3/'}