summaryrefslogtreecommitdiffstats
path: root/test/units/galaxy/test_collection_install.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/units/galaxy/test_collection_install.py')
-rw-r--r--test/units/galaxy/test_collection_install.py558
1 files changed, 331 insertions, 227 deletions
diff --git a/test/units/galaxy/test_collection_install.py b/test/units/galaxy/test_collection_install.py
index 9acf55fd52..a4f5c35a3b 100644
--- a/test/units/galaxy/test_collection_install.py
+++ b/test/units/galaxy/test_collection_install.py
@@ -24,12 +24,24 @@ import ansible.module_utils.six.moves.urllib.error as urllib_error
from ansible import context
from ansible.cli.galaxy import GalaxyCLI
from ansible.errors import AnsibleError
-from ansible.galaxy import collection, api
+from ansible.galaxy import collection, api, dependency_resolution
+from ansible.galaxy.dependency_resolution.dataclasses import Candidate, Requirement
from ansible.module_utils._text import to_bytes, to_native, to_text
from ansible.utils import context_objects as co
from ansible.utils.display import Display
+class RequirementCandidates():
+ def __init__(self):
+ self.candidates = []
+
+ def func_wrapper(self, func):
+ def run(*args, **kwargs):
+ self.candidates = func(*args, **kwargs)
+ return self.candidates
+ return run
+
+
def call_galaxy_cli(args):
orig = co.GlobalCLIArgs._Singleton__instance
co.GlobalCLIArgs._Singleton__instance = None
@@ -160,16 +172,14 @@ def galaxy_server():
def test_build_requirement_from_path(collection_artifact):
- actual = collection.CollectionRequirement.from_path(collection_artifact[0], True)
+ tmp_path = os.path.join(os.path.split(collection_artifact[1])[0], b'temp')
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(tmp_path, validate_certs=False)
+ actual = Requirement.from_dir_path_as_unknown(collection_artifact[0], concrete_artifact_cm)
assert actual.namespace == u'ansible_namespace'
assert actual.name == u'collection'
- assert actual.b_path == collection_artifact[0]
- assert actual.api is None
- assert actual.skip is True
- assert actual.versions == set([u'*'])
- assert actual.latest_version == u'*'
- assert actual.dependencies == {}
+ assert actual.src == collection_artifact[0]
+ assert actual.ver == u'0.1.0'
@pytest.mark.parametrize('version', ['1.1.1', '1.1.0', '1.0.0'])
@@ -188,17 +198,15 @@ def test_build_requirement_from_path_with_manifest(version, collection_artifact)
with open(manifest_path, 'wb') as manifest_obj:
manifest_obj.write(to_bytes(manifest_value))
- actual = collection.CollectionRequirement.from_path(collection_artifact[0], True)
+ tmp_path = os.path.join(os.path.split(collection_artifact[1])[0], b'temp')
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(tmp_path, validate_certs=False)
+ actual = Requirement.from_dir_path_as_unknown(collection_artifact[0], concrete_artifact_cm)
# While the folder name suggests a different collection, we treat MANIFEST.json as the source of truth.
assert actual.namespace == u'namespace'
assert actual.name == u'name'
- assert actual.b_path == collection_artifact[0]
- assert actual.api is None
- assert actual.skip is True
- assert actual.versions == set([to_text(version)])
- assert actual.latest_version == to_text(version)
- assert actual.dependencies == {'ansible_namespace.collection': '*'}
+ assert actual.src == collection_artifact[0]
+ assert actual.ver == to_text(version)
def test_build_requirement_from_path_invalid_manifest(collection_artifact):
@@ -206,12 +214,19 @@ def test_build_requirement_from_path_invalid_manifest(collection_artifact):
with open(manifest_path, 'wb') as manifest_obj:
manifest_obj.write(b"not json")
- expected = "Collection file at '%s' does not contain a valid json string." % to_native(manifest_path)
+ tmp_path = os.path.join(os.path.split(collection_artifact[1])[0], b'temp')
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(tmp_path, validate_certs=False)
+
+ expected = "Collection tar file member MANIFEST.json does not contain a valid json string."
with pytest.raises(AnsibleError, match=expected):
- collection.CollectionRequirement.from_path(collection_artifact[0], True)
+ Requirement.from_dir_path_as_unknown(collection_artifact[0], concrete_artifact_cm)
-def test_build_requirement_from_path_no_version(collection_artifact, monkeypatch):
+def test_build_artifact_from_path_no_version(collection_artifact, monkeypatch):
+ mock_display = MagicMock()
+ monkeypatch.setattr(Display, 'display', mock_display)
+
+ # a collection artifact should always contain a valid version
manifest_path = os.path.join(collection_artifact[0], b'MANIFEST.json')
manifest_value = json.dumps({
'collection_info': {
@@ -224,40 +239,56 @@ def test_build_requirement_from_path_no_version(collection_artifact, monkeypatch
with open(manifest_path, 'wb') as manifest_obj:
manifest_obj.write(to_bytes(manifest_value))
+ tmp_path = os.path.join(os.path.split(collection_artifact[1])[0], b'temp')
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(tmp_path, validate_certs=False)
+
+ expected = (
+ '^Collection metadata file at `.*` is expected to have a valid SemVer '
+ 'version value but got {empty_unicode_string!r}$'.
+ format(empty_unicode_string=u'')
+ )
+ with pytest.raises(AnsibleError, match=expected):
+ Requirement.from_dir_path_as_unknown(collection_artifact[0], concrete_artifact_cm)
+
+
+def test_build_requirement_from_path_no_version(collection_artifact, monkeypatch):
mock_display = MagicMock()
monkeypatch.setattr(Display, 'display', mock_display)
- actual = collection.CollectionRequirement.from_path(collection_artifact[0], True)
+ # version may be falsey/arbitrary strings for collections in development
+ manifest_path = os.path.join(collection_artifact[0], b'galaxy.yml')
+ metadata = {
+ 'authors': ['Ansible'],
+ 'readme': 'README.md',
+ 'namespace': 'namespace',
+ 'name': 'name',
+ 'version': '',
+ 'dependencies': {},
+ }
+ with open(manifest_path, 'wb') as manifest_obj:
+ manifest_obj.write(to_bytes(yaml.safe_dump(metadata)))
+
+ tmp_path = os.path.join(os.path.split(collection_artifact[1])[0], b'temp')
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(tmp_path, validate_certs=False)
+ actual = Requirement.from_dir_path_as_unknown(collection_artifact[0], concrete_artifact_cm)
# While the folder name suggests a different collection, we treat MANIFEST.json as the source of truth.
assert actual.namespace == u'namespace'
assert actual.name == u'name'
- assert actual.b_path == collection_artifact[0]
- assert actual.api is None
- assert actual.skip is True
- assert actual.versions == set(['*'])
- assert actual.latest_version == u'*'
- assert actual.dependencies == {}
-
- assert mock_display.call_count == 1
-
- actual_warn = ' '.join(mock_display.mock_calls[0][1][0].split('\n'))
- expected_warn = "Collection at '%s' does not have a valid version set, falling back to '*'. Found version: ''" \
- % to_text(collection_artifact[0])
- assert expected_warn in actual_warn
+ assert actual.src == collection_artifact[0]
+ assert actual.ver == u'*'
def test_build_requirement_from_tar(collection_artifact):
- actual = collection.CollectionRequirement.from_tar(collection_artifact[1], True, True)
+ tmp_path = os.path.join(os.path.split(collection_artifact[1])[0], b'temp')
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(tmp_path, validate_certs=False)
+
+ actual = Requirement.from_requirement_dict({'name': to_text(collection_artifact[1])}, concrete_artifact_cm)
assert actual.namespace == u'ansible_namespace'
assert actual.name == u'collection'
- assert actual.b_path == collection_artifact[1]
- assert actual.api is None
- assert actual.skip is False
- assert actual.versions == set([u'0.1.0'])
- assert actual.latest_version == u'0.1.0'
- assert actual.dependencies == {}
+ assert actual.src == to_text(collection_artifact[1])
+ assert actual.ver == u'0.1.0'
def test_build_requirement_from_tar_fail_not_tar(tmp_path_factory):
@@ -266,9 +297,11 @@ def test_build_requirement_from_tar_fail_not_tar(tmp_path_factory):
with open(test_file, 'wb') as test_obj:
test_obj.write(b"\x00\x01\x02\x03")
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(test_dir, validate_certs=False)
+
expected = "Collection artifact at '%s' is not a valid tar file." % to_native(test_file)
with pytest.raises(AnsibleError, match=expected):
- collection.CollectionRequirement.from_tar(test_file, True, True)
+ Requirement.from_requirement_dict({'name': to_text(test_file)}, concrete_artifact_cm)
def test_build_requirement_from_tar_no_manifest(tmp_path_factory):
@@ -289,9 +322,11 @@ def test_build_requirement_from_tar_no_manifest(tmp_path_factory):
tar_info.mode = 0o0644
tfile.addfile(tarinfo=tar_info, fileobj=b_io)
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(test_dir, validate_certs=False)
+
expected = "Collection at '%s' does not contain the required file MANIFEST.json." % to_native(tar_path)
with pytest.raises(AnsibleError, match=expected):
- collection.CollectionRequirement.from_tar(tar_path, True, True)
+ Requirement.from_requirement_dict({'name': to_text(tar_path)}, concrete_artifact_cm)
def test_build_requirement_from_tar_no_files(tmp_path_factory):
@@ -311,9 +346,9 @@ def test_build_requirement_from_tar_no_files(tmp_path_factory):
tar_info.mode = 0o0644
tfile.addfile(tarinfo=tar_info, fileobj=b_io)
- expected = "Collection at '%s' does not contain the required file FILES.json." % to_native(tar_path)
- with pytest.raises(AnsibleError, match=expected):
- collection.CollectionRequirement.from_tar(tar_path, True, True)
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(test_dir, validate_certs=False)
+ with pytest.raises(KeyError, match='namespace'):
+ Requirement.from_requirement_dict({'name': to_text(tar_path)}, concrete_artifact_cm)
def test_build_requirement_from_tar_invalid_manifest(tmp_path_factory):
@@ -329,95 +364,128 @@ def test_build_requirement_from_tar_invalid_manifest(tmp_path_factory):
tar_info.mode = 0o0644
tfile.addfile(tarinfo=tar_info, fileobj=b_io)
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(test_dir, validate_certs=False)
+
expected = "Collection tar file member MANIFEST.json does not contain a valid json string."
with pytest.raises(AnsibleError, match=expected):
- collection.CollectionRequirement.from_tar(tar_path, True, True)
+ Requirement.from_requirement_dict({'name': to_text(tar_path)}, concrete_artifact_cm)
-def test_build_requirement_from_name(galaxy_server, monkeypatch):
+def test_build_requirement_from_name(galaxy_server, monkeypatch, tmp_path_factory):
mock_get_versions = MagicMock()
mock_get_versions.return_value = ['2.1.9', '2.1.10']
monkeypatch.setattr(galaxy_server, 'get_collection_versions', mock_get_versions)
- actual = collection.CollectionRequirement.from_name('namespace.collection', [galaxy_server], '*', True, True)
+ mock_version_metadata = MagicMock(
+ namespace='namespace', name='collection',
+ version='2.1.10', artifact_sha256='', dependencies={}
+ )
+ monkeypatch.setattr(api.GalaxyAPI, 'get_collection_version_metadata', mock_version_metadata)
+
+ test_dir = to_bytes(tmp_path_factory.mktemp('test-ÅÑŚÌβŁÈ Collections Input'))
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(test_dir, validate_certs=False)
+
+ collections = ['namespace.collection']
+ requirements_file = None
+
+ cli = GalaxyCLI(args=['ansible-galaxy', 'collection', 'install', collections[0]])
+ requirements = cli._require_one_of_collections_requirements(
+ collections, requirements_file, artifacts_manager=concrete_artifact_cm
+ )['collections']
+ actual = collection._resolve_depenency_map(requirements, [galaxy_server], concrete_artifact_cm, None, True, False)['namespace.collection']
assert actual.namespace == u'namespace'
assert actual.name == u'collection'
- assert actual.b_path is None
- assert actual.api == galaxy_server
- assert actual.skip is False
- assert actual.versions == set([u'2.1.9', u'2.1.10'])
- assert actual.latest_version == u'2.1.10'
- assert actual.dependencies == {}
+ assert actual.ver == u'2.1.10'
+ assert actual.src == galaxy_server
assert mock_get_versions.call_count == 1
assert mock_get_versions.mock_calls[0][1] == ('namespace', 'collection')
-def test_build_requirement_from_name_with_prerelease(galaxy_server, monkeypatch):
+def test_build_requirement_from_name_with_prerelease(galaxy_server, monkeypatch, tmp_path_factory):
mock_get_versions = MagicMock()
mock_get_versions.return_value = ['1.0.1', '2.0.1-beta.1', '2.0.1']
monkeypatch.setattr(galaxy_server, 'get_collection_versions', mock_get_versions)
- actual = collection.CollectionRequirement.from_name('namespace.collection', [galaxy_server], '*', True, True)
+ mock_get_info = MagicMock()
+ mock_get_info.return_value = api.CollectionVersionMetadata('namespace', 'collection', '2.0.1', None, None, {})
+ monkeypatch.setattr(galaxy_server, 'get_collection_version_metadata', mock_get_info)
+
+ test_dir = to_bytes(tmp_path_factory.mktemp('test-ÅÑŚÌβŁÈ Collections Input'))
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(test_dir, validate_certs=False)
+
+ cli = GalaxyCLI(args=['ansible-galaxy', 'collection', 'install', 'namespace.collection'])
+ requirements = cli._require_one_of_collections_requirements(
+ ['namespace.collection'], None, artifacts_manager=concrete_artifact_cm
+ )['collections']
+ actual = collection._resolve_depenency_map(requirements, [galaxy_server], concrete_artifact_cm, None, True, False)['namespace.collection']
assert actual.namespace == u'namespace'
assert actual.name == u'collection'
- assert actual.b_path is None
- assert actual.api == galaxy_server
- assert actual.skip is False
- assert actual.versions == set([u'1.0.1', u'2.0.1'])
- assert actual.latest_version == u'2.0.1'
- assert actual.dependencies == {}
+ assert actual.src == galaxy_server
+ assert actual.ver == u'2.0.1'
assert mock_get_versions.call_count == 1
assert mock_get_versions.mock_calls[0][1] == ('namespace', 'collection')
-def test_build_requirment_from_name_with_prerelease_explicit(galaxy_server, monkeypatch):
+def test_build_requirment_from_name_with_prerelease_explicit(galaxy_server, monkeypatch, tmp_path_factory):
+ mock_get_versions = MagicMock()
+ mock_get_versions.return_value = ['1.0.1', '2.0.1-beta.1', '2.0.1']
+ monkeypatch.setattr(galaxy_server, 'get_collection_versions', mock_get_versions)
+
mock_get_info = MagicMock()
mock_get_info.return_value = api.CollectionVersionMetadata('namespace', 'collection', '2.0.1-beta.1', None, None,
{})
monkeypatch.setattr(galaxy_server, 'get_collection_version_metadata', mock_get_info)
- actual = collection.CollectionRequirement.from_name('namespace.collection', [galaxy_server], '2.0.1-beta.1', True,
- True)
+ test_dir = to_bytes(tmp_path_factory.mktemp('test-ÅÑŚÌβŁÈ Collections Input'))
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(test_dir, validate_certs=False)
+
+ cli = GalaxyCLI(args=['ansible-galaxy', 'collection', 'install', 'namespace.collection:2.0.1-beta.1'])
+ requirements = cli._require_one_of_collections_requirements(
+ ['namespace.collection:2.0.1-beta.1'], None, artifacts_manager=concrete_artifact_cm
+ )['collections']
+ actual = collection._resolve_depenency_map(requirements, [galaxy_server], concrete_artifact_cm, None, True, False)['namespace.collection']
assert actual.namespace == u'namespace'
assert actual.name == u'collection'
- assert actual.b_path is None
- assert actual.api == galaxy_server
- assert actual.skip is False
- assert actual.versions == set([u'2.0.1-beta.1'])
- assert actual.latest_version == u'2.0.1-beta.1'
- assert actual.dependencies == {}
+ assert actual.src == galaxy_server
+ assert actual.ver == u'2.0.1-beta.1'
assert mock_get_info.call_count == 1
assert mock_get_info.mock_calls[0][1] == ('namespace', 'collection', '2.0.1-beta.1')
-def test_build_requirement_from_name_second_server(galaxy_server, monkeypatch):
+def test_build_requirement_from_name_second_server(galaxy_server, monkeypatch, tmp_path_factory):
mock_get_versions = MagicMock()
mock_get_versions.return_value = ['1.0.1', '1.0.2', '1.0.3']
monkeypatch.setattr(galaxy_server, 'get_collection_versions', mock_get_versions)
+ mock_get_info = MagicMock()
+ mock_get_info.return_value = api.CollectionVersionMetadata('namespace', 'collection', '1.0.3', None, None, {})
+ monkeypatch.setattr(galaxy_server, 'get_collection_version_metadata', mock_get_info)
+
broken_server = copy.copy(galaxy_server)
broken_server.api_server = 'https://broken.com/'
mock_version_list = MagicMock()
mock_version_list.return_value = []
monkeypatch.setattr(broken_server, 'get_collection_versions', mock_version_list)
- actual = collection.CollectionRequirement.from_name('namespace.collection', [broken_server, galaxy_server],
- '>1.0.1', False, True)
+ test_dir = to_bytes(tmp_path_factory.mktemp('test-ÅÑŚÌβŁÈ Collections Input'))
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(test_dir, validate_certs=False)
+
+ cli = GalaxyCLI(args=['ansible-galaxy', 'collection', 'install', 'namespace.collection:>1.0.1'])
+ requirements = cli._require_one_of_collections_requirements(
+ ['namespace.collection:>1.0.1'], None, artifacts_manager=concrete_artifact_cm
+ )['collections']
+ actual = collection._resolve_depenency_map(requirements, [broken_server, galaxy_server], concrete_artifact_cm, None, True, False)['namespace.collection']
assert actual.namespace == u'namespace'
assert actual.name == u'collection'
- assert actual.b_path is None
- # assert actual.api == galaxy_server
- assert actual.skip is False
- assert actual.versions == set([u'1.0.2', u'1.0.3'])
- assert actual.latest_version == u'1.0.3'
- assert actual.dependencies == {}
+ assert actual.src == galaxy_server
+ assert actual.ver == u'1.0.3'
assert mock_version_list.call_count == 1
assert mock_version_list.mock_calls[0][1] == ('namespace', 'collection')
@@ -426,53 +494,91 @@ def test_build_requirement_from_name_second_server(galaxy_server, monkeypatch):
assert mock_get_versions.mock_calls[0][1] == ('namespace', 'collection')
-def test_build_requirement_from_name_missing(galaxy_server, monkeypatch):
+def test_build_requirement_from_name_missing(galaxy_server, monkeypatch, tmp_path_factory):
mock_open = MagicMock()
mock_open.return_value = []
monkeypatch.setattr(galaxy_server, 'get_collection_versions', mock_open)
- expected = "Failed to find collection namespace.collection:*"
- with pytest.raises(AnsibleError, match=expected):
- collection.CollectionRequirement.from_name('namespace.collection', [galaxy_server, galaxy_server], '*', False,
- True)
+ test_dir = to_bytes(tmp_path_factory.mktemp('test-ÅÑŚÌβŁÈ Collections Input'))
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(test_dir, validate_certs=False)
+ cli = GalaxyCLI(args=['ansible-galaxy', 'collection', 'install', 'namespace.collection:>1.0.1'])
+ requirements = cli._require_one_of_collections_requirements(
+ ['namespace.collection'], None, artifacts_manager=concrete_artifact_cm
+ )['collections']
-def test_build_requirement_from_name_401_unauthorized(galaxy_server, monkeypatch):
+ expected = "Failed to resolve the requested dependencies map. Could not satisfy the following requirements:\n* namespace.collection:* (direct request)"
+ with pytest.raises(AnsibleError, match=re.escape(expected)):
+ collection._resolve_depenency_map(requirements, [galaxy_server, galaxy_server], concrete_artifact_cm, None, False, True)
+
+
+def test_build_requirement_from_name_401_unauthorized(galaxy_server, monkeypatch, tmp_path_factory):
mock_open = MagicMock()
mock_open.side_effect = api.GalaxyError(urllib_error.HTTPError('https://galaxy.server.com', 401, 'msg', {},
StringIO()), "error")
monkeypatch.setattr(galaxy_server, 'get_collection_versions', mock_open)
+ test_dir = to_bytes(tmp_path_factory.mktemp('test-ÅÑŚÌβŁÈ Collections Input'))
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(test_dir, validate_certs=False)
+
+ cli = GalaxyCLI(args=['ansible-galaxy', 'collection', 'install', 'namespace.collection:>1.0.1'])
+ requirements = cli._require_one_of_collections_requirements(
+ ['namespace.collection'], None, artifacts_manager=concrete_artifact_cm
+ )['collections']
+
expected = "error (HTTP Code: 401, Message: msg)"
with pytest.raises(api.GalaxyError, match=re.escape(expected)):
- collection.CollectionRequirement.from_name('namespace.collection', [galaxy_server, galaxy_server], '*', False)
+ collection._resolve_depenency_map(requirements, [galaxy_server, galaxy_server], concrete_artifact_cm, None, False, False)
-def test_build_requirement_from_name_single_version(galaxy_server, monkeypatch):
+def test_build_requirement_from_name_single_version(galaxy_server, monkeypatch, tmp_path_factory):
+ test_dir = to_bytes(tmp_path_factory.mktemp('test-ÅÑŚÌβŁÈ Collections Input'))
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(test_dir, validate_certs=False)
+ multi_api_proxy = collection.galaxy_api_proxy.MultiGalaxyAPIProxy([galaxy_server], concrete_artifact_cm)
+ dep_provider = dependency_resolution.providers.CollectionDependencyProvider(apis=multi_api_proxy, concrete_artifacts_manager=concrete_artifact_cm)
+
+ matches = RequirementCandidates()
+ mock_find_matches = MagicMock(side_effect=matches.func_wrapper(dep_provider.find_matches), autospec=True)
+ monkeypatch.setattr(dependency_resolution.providers.CollectionDependencyProvider, 'find_matches', mock_find_matches)
+
+ mock_get_versions = MagicMock()
+ mock_get_versions.return_value = ['2.0.0']
+ monkeypatch.setattr(galaxy_server, 'get_collection_versions', mock_get_versions)
+
mock_get_info = MagicMock()
mock_get_info.return_value = api.CollectionVersionMetadata('namespace', 'collection', '2.0.0', None, None,
{})
monkeypatch.setattr(galaxy_server, 'get_collection_version_metadata', mock_get_info)
- actual = collection.CollectionRequirement.from_name('namespace.collection', [galaxy_server], '2.0.0', True,
- True)
+ cli = GalaxyCLI(args=['ansible-galaxy', 'collection', 'install', 'namespace.collection:==2.0.0'])
+ requirements = cli._require_one_of_collections_requirements(
+ ['namespace.collection:==2.0.0'], None, artifacts_manager=concrete_artifact_cm
+ )['collections']
+
+ actual = collection._resolve_depenency_map(requirements, [galaxy_server], concrete_artifact_cm, None, False, True)['namespace.collection']
assert actual.namespace == u'namespace'
assert actual.name == u'collection'
- assert actual.b_path is None
- assert actual.api == galaxy_server
- assert actual.skip is False
- assert actual.versions == set([u'2.0.0'])
- assert actual.latest_version == u'2.0.0'
- assert actual.dependencies == {}
+ assert actual.src == galaxy_server
+ assert actual.ver == u'2.0.0'
+ assert [c.ver for c in matches.candidates] == [u'2.0.0']
assert mock_get_info.call_count == 1
assert mock_get_info.mock_calls[0][1] == ('namespace', 'collection', '2.0.0')
-def test_build_requirement_from_name_multiple_versions_one_match(galaxy_server, monkeypatch):
+def test_build_requirement_from_name_multiple_versions_one_match(galaxy_server, monkeypatch, tmp_path_factory):
+ test_dir = to_bytes(tmp_path_factory.mktemp('test-ÅÑŚÌβŁÈ Collections Input'))
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(test_dir, validate_certs=False)
+ multi_api_proxy = collection.galaxy_api_proxy.MultiGalaxyAPIProxy([galaxy_server], concrete_artifact_cm)
+ dep_provider = dependency_resolution.providers.CollectionDependencyProvider(apis=multi_api_proxy, concrete_artifacts_manager=concrete_artifact_cm)
+
+ matches = RequirementCandidates()
+ mock_find_matches = MagicMock(side_effect=matches.func_wrapper(dep_provider.find_matches), autospec=True)
+ monkeypatch.setattr(dependency_resolution.providers.CollectionDependencyProvider, 'find_matches', mock_find_matches)
+
mock_get_versions = MagicMock()
mock_get_versions.return_value = ['2.0.0', '2.0.1', '2.0.2']
monkeypatch.setattr(galaxy_server, 'get_collection_versions', mock_get_versions)
@@ -482,17 +588,18 @@ def test_build_requirement_from_name_multiple_versions_one_match(galaxy_server,
{})
monkeypatch.setattr(galaxy_server, 'get_collection_version_metadata', mock_get_info)
- actual = collection.CollectionRequirement.from_name('namespace.collection', [galaxy_server], '>=2.0.1,<2.0.2',
- True, True)
+ cli = GalaxyCLI(args=['ansible-galaxy', 'collection', 'install', 'namespace.collection:>=2.0.1,<2.0.2'])
+ requirements = cli._require_one_of_collections_requirements(
+ ['namespace.collection:>=2.0.1,<2.0.2'], None, artifacts_manager=concrete_artifact_cm
+ )['collections']
+
+ actual = collection._resolve_depenency_map(requirements, [galaxy_server], concrete_artifact_cm, None, False, True)['namespace.collection']
assert actual.namespace == u'namespace'
assert actual.name == u'collection'
- assert actual.b_path is None
- assert actual.api == galaxy_server
- assert actual.skip is False
- assert actual.versions == set([u'2.0.1'])
- assert actual.latest_version == u'2.0.1'
- assert actual.dependencies == {}
+ assert actual.src == galaxy_server
+ assert actual.ver == u'2.0.1'
+ assert [c.ver for c in matches.candidates] == [u'2.0.1']
assert mock_get_versions.call_count == 1
assert mock_get_versions.mock_calls[0][1] == ('namespace', 'collection')
@@ -501,122 +608,118 @@ def test_build_requirement_from_name_multiple_versions_one_match(galaxy_server,
assert mock_get_info.mock_calls[0][1] == ('namespace', 'collection', '2.0.1')
-def test_build_requirement_from_name_multiple_version_results(galaxy_server, monkeypatch):
+def test_build_requirement_from_name_multiple_version_results(galaxy_server, monkeypatch, tmp_path_factory):
+ test_dir = to_bytes(tmp_path_factory.mktemp('test-ÅÑŚÌβŁÈ Collections Input'))
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(test_dir, validate_certs=False)
+ multi_api_proxy = collection.galaxy_api_proxy.MultiGalaxyAPIProxy([galaxy_server], concrete_artifact_cm)
+ dep_provider = dependency_resolution.providers.CollectionDependencyProvider(apis=multi_api_proxy, concrete_artifacts_manager=concrete_artifact_cm)
+
+ matches = RequirementCandidates()
+ mock_find_matches = MagicMock(side_effect=matches.func_wrapper(dep_provider.find_matches), autospec=True)
+ monkeypatch.setattr(dependency_resolution.providers.CollectionDependencyProvider, 'find_matches', mock_find_matches)
+
+ mock_get_info = MagicMock()
+ mock_get_info.return_value = api.CollectionVersionMetadata('namespace', 'collection', '2.0.5', None, None, {})
+ monkeypatch.setattr(galaxy_server, 'get_collection_version_metadata', mock_get_info)
+
mock_get_versions = MagicMock()
+ mock_get_versions.return_value = ['1.0.1', '1.0.2', '1.0.3']
+ monkeypatch.setattr(galaxy_server, 'get_collection_versions', mock_get_versions)
+
mock_get_versions.return_value = ['2.0.0', '2.0.1', '2.0.2', '2.0.3', '2.0.4', '2.0.5']
monkeypatch.setattr(galaxy_server, 'get_collection_versions', mock_get_versions)
- actual = collection.CollectionRequirement.from_name('namespace.collection', [galaxy_server], '!=2.0.2',
- True, True)
+ cli = GalaxyCLI(args=['ansible-galaxy', 'collection', 'install', 'namespace.collection:!=2.0.2'])
+ requirements = cli._require_one_of_collections_requirements(
+ ['namespace.collection:!=2.0.2'], None, artifacts_manager=concrete_artifact_cm
+ )['collections']
+
+ actual = collection._resolve_depenency_map(requirements, [galaxy_server], concrete_artifact_cm, None, False, True)['namespace.collection']
assert actual.namespace == u'namespace'
assert actual.name == u'collection'
- assert actual.b_path is None
- assert actual.api == galaxy_server
- assert actual.skip is False
- assert actual.versions == set([u'2.0.0', u'2.0.1', u'2.0.3', u'2.0.4', u'2.0.5'])
- assert actual.latest_version == u'2.0.5'
- assert actual.dependencies == {}
+ assert actual.src == galaxy_server
+ assert actual.ver == u'2.0.5'
+ # should be ordered latest to earliest
+ assert [c.ver for c in matches.candidates] == [u'2.0.5', u'2.0.4', u'2.0.3', u'2.0.1', u'2.0.0']
assert mock_get_versions.call_count == 1
assert mock_get_versions.mock_calls[0][1] == ('namespace', 'collection')
-@pytest.mark.parametrize('versions, requirement, expected_filter, expected_latest', [
- [['1.0.0', '1.0.1'], '*', ['1.0.0', '1.0.1'], '1.0.1'],
- [['1.0.0', '1.0.5', '1.1.0'], '>1.0.0,<1.1.0', ['1.0.5'], '1.0.5'],
- [['1.0.0', '1.0.5', '1.1.0'], '>1.0.0,<=1.0.5', ['1.0.5'], '1.0.5'],
- [['1.0.0', '1.0.5', '1.1.0'], '>=1.1.0', ['1.1.0'], '1.1.0'],
- [['1.0.0', '1.0.5', '1.1.0'], '!=1.1.0', ['1.0.0', '1.0.5'], '1.0.5'],
- [['1.0.0', '1.0.5', '1.1.0'], '==1.0.5', ['1.0.5'], '1.0.5'],
- [['1.0.0', '1.0.5', '1.1.0'], '1.0.5', ['1.0.5'], '1.0.5'],
- [['1.0.0', '2.0.0', '3.0.0'], '>=2', ['2.0.0', '3.0.0'], '3.0.0'],
-])
-def test_add_collection_requirements(versions, requirement, expected_filter, expected_latest):
- req = collection.CollectionRequirement('namespace', 'name', None, 'https://galaxy.com', versions, requirement,
- False)
- assert req.versions == set(expected_filter)
- assert req.latest_version == expected_latest
-
-
-def test_add_collection_requirement_to_unknown_installed_version(monkeypatch):
- mock_display = MagicMock()
- monkeypatch.setattr(Display, 'display', mock_display)
-
- req = collection.CollectionRequirement('namespace', 'name', None, 'https://galaxy.com', ['*'], '*', False,
- skip=True)
+def test_candidate_with_conflict(monkeypatch, tmp_path_factory, galaxy_server):
- req.add_requirement('parent.collection', '1.0.0')
- assert req.latest_version == '*'
+ test_dir = to_bytes(tmp_path_factory.mktemp('test-ÅÑŚÌβŁÈ Collections Input'))
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(test_dir, validate_certs=False)
- assert mock_display.call_count == 1
+ mock_get_info = MagicMock()
+ mock_get_info.return_value = api.CollectionVersionMetadata('namespace', 'collection', '2.0.5', None, None, {})
+ monkeypatch.setattr(galaxy_server, 'get_collection_version_metadata', mock_get_info)
- actual_warn = ' '.join(mock_display.mock_calls[0][1][0].split('\n'))
- assert "Failed to validate the collection requirement 'namespace.name:1.0.0' for parent.collection" in actual_warn
+ mock_get_versions = MagicMock()
+ mock_get_versions.return_value = ['2.0.5']
+ monkeypatch.setattr(galaxy_server, 'get_collection_versions', mock_get_versions)
+ cli = GalaxyCLI(args=['ansible-galaxy', 'collection', 'install', 'namespace.collection:!=2.0.5'])
+ requirements = cli._require_one_of_collections_requirements(
+ ['namespace.collection:!=2.0.5'], None, artifacts_manager=concrete_artifact_cm
+ )['collections']
-def test_add_collection_wildcard_requirement_to_unknown_installed_version():
- req = collection.CollectionRequirement('namespace', 'name', None, 'https://galaxy.com', ['*'], '*', False,
- skip=True)
- req.add_requirement(str(req), '*')
+ expected = "Failed to resolve the requested dependencies map. Could not satisfy the following requirements:\n"
+ expected += "* namespace.collection:!=2.0.5 (direct request)"
+ with pytest.raises(AnsibleError, match=re.escape(expected)):
+ collection._resolve_depenency_map(requirements, [galaxy_server], concrete_artifact_cm, None, False, True)
- assert req.versions == set('*')
- assert req.latest_version == '*'
+def test_dep_candidate_with_conflict(monkeypatch, tmp_path_factory, galaxy_server):
+ test_dir = to_bytes(tmp_path_factory.mktemp('test-ÅÑŚÌβŁÈ Collections Input'))
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(test_dir, validate_certs=False)
-def test_add_collection_requirement_with_conflict(galaxy_server):
- expected = "Cannot meet requirement ==1.0.2 for dependency namespace.name from source '%s'. Available versions " \
- "before last requirement added: 1.0.0, 1.0.1\n" \
- "Requirements from:\n" \
- "\tbase - 'namespace.name:==1.0.2'" % galaxy_server.api_server
- with pytest.raises(AnsibleError, match=expected):
- collection.CollectionRequirement('namespace', 'name', None, galaxy_server, ['1.0.0', '1.0.1'], '==1.0.2',
- False)
+ mock_get_info_return = [
+ api.CollectionVersionMetadata('parent', 'collection', '2.0.5', None, None, {'namespace.collection': '!=1.0.0'}),
+ api.CollectionVersionMetadata('namespace', 'collection', '1.0.0', None, None, {}),
+ ]
+ mock_get_info = MagicMock(side_effect=mock_get_info_return)
+ monkeypatch.setattr(galaxy_server, 'get_collection_version_metadata', mock_get_info)
+ mock_get_versions = MagicMock(side_effect=[['2.0.5'], ['1.0.0']])
+ monkeypatch.setattr(galaxy_server, 'get_collection_versions', mock_get_versions)
-def test_add_requirement_to_existing_collection_with_conflict(galaxy_server):
- req = collection.CollectionRequirement('namespace', 'name', None, galaxy_server, ['1.0.0', '1.0.1'], '*', False)
+ cli = GalaxyCLI(args=['ansible-galaxy', 'collection', 'install', 'parent.collection:2.0.5'])
+ requirements = cli._require_one_of_collections_requirements(
+ ['parent.collection:2.0.5'], None, artifacts_manager=concrete_artifact_cm
+ )['collections']
- expected = "Cannot meet dependency requirement 'namespace.name:1.0.2' for collection namespace.collection2 from " \
- "source '%s'. Available versions before last requirement added: 1.0.0, 1.0.1\n" \
- "Requirements from:\n" \
- "\tbase - 'namespace.name:*'\n" \
- "\tnamespace.collection2 - 'namespace.name:1.0.2'" % galaxy_server.api_server
+ expected = "Failed to resolve the requested dependencies map. Could not satisfy the following requirements:\n"
+ expected += "* namespace.collection:!=1.0.0 (dependency of parent.collection:2.0.5)"
with pytest.raises(AnsibleError, match=re.escape(expected)):
- req.add_requirement('namespace.collection2', '1.0.2')
+ collection._resolve_depenency_map(requirements, [galaxy_server], concrete_artifact_cm, None, False, True)
-def test_add_requirement_to_installed_collection_with_conflict():
- source = 'https://galaxy.ansible.com'
- req = collection.CollectionRequirement('namespace', 'name', None, source, ['1.0.0', '1.0.1'], '*', False,
- skip=True)
+def test_install_installed_collection(monkeypatch, tmp_path_factory, galaxy_server):
- expected = "Cannot meet requirement namespace.name:1.0.2 as it is already installed at version '1.0.1'. " \
- "Use --force to overwrite"
- with pytest.raises(AnsibleError, match=re.escape(expected)):
- req.add_requirement(None, '1.0.2')
+ mock_installed_collections = MagicMock(return_value=[Candidate('namespace.collection', '1.2.3', None, 'dir')])
+ monkeypatch.setattr(collection, 'find_existing_collections', mock_installed_collections)
-def test_add_requirement_to_installed_collection_with_conflict_as_dep():
- source = 'https://galaxy.ansible.com'
- req = collection.CollectionRequirement('namespace', 'name', None, source, ['1.0.0', '1.0.1'], '*', False,
- skip=True)
+ test_dir = to_text(tmp_path_factory.mktemp('test-ÅÑŚÌβŁÈ Collections'))
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(test_dir, validate_certs=False)
- expected = "Cannot meet requirement namespace.name:1.0.2 as it is already installed at version '1.0.1'. " \
- "Use --force-with-deps to overwrite"
- with pytest.raises(AnsibleError, match=re.escape(expected)):
- req.add_requirement('namespace.collection2', '1.0.2')
-
-
-def test_install_skipped_collection(monkeypatch):
mock_display = MagicMock()
monkeypatch.setattr(Display, 'display', mock_display)
- req = collection.CollectionRequirement('namespace', 'name', None, 'source', ['1.0.0'], '*', False, skip=True)
- req.install(None, None)
+ mock_get_info = MagicMock()
+ mock_get_info.return_value = api.CollectionVersionMetadata('namespace', 'collection', '1.2.3', None, None, {})
+ monkeypatch.setattr(galaxy_server, 'get_collection_version_metadata', mock_get_info)
+
+ mock_get_versions = MagicMock(return_value=['1.2.3', '1.3.0'])
+ monkeypatch.setattr(galaxy_server, 'get_collection_versions', mock_get_versions)
+
+ cli = GalaxyCLI(args=['ansible-galaxy', 'collection', 'install', 'namespace.collection'])
+ cli.run()
- assert mock_display.call_count == 1
- assert mock_display.mock_calls[0][1][0] == "Skipping 'namespace.name' as it is already installed"
+ expected = "Nothing to do. All requested collections are already installed. If you want to reinstall them, consider using `--force`."
+ assert mock_display.mock_calls[1][1][0] == expected
def test_install_collection(collection_artifact, monkeypatch):
@@ -624,15 +727,17 @@ def test_install_collection(collection_artifact, monkeypatch):
monkeypatch.setattr(Display, 'display', mock_display)
collection_tar = collection_artifact[1]
- output_path = os.path.join(os.path.split(collection_tar)[0], b'output')
- collection_path = os.path.join(output_path, b'ansible_namespace', b'collection')
- os.makedirs(os.path.join(collection_path, b'delete_me')) # Create a folder to verify the install cleans out the dir
temp_path = os.path.join(os.path.split(collection_tar)[0], b'temp')
os.makedirs(temp_path)
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(temp_path, validate_certs=False)
- req = collection.CollectionRequirement.from_tar(collection_tar, True, True)
- req.install(to_text(output_path), temp_path)
+ output_path = os.path.join(os.path.split(collection_tar)[0])
+ collection_path = os.path.join(output_path, b'ansible_namespace', b'collection')
+ os.makedirs(os.path.join(collection_path, b'delete_me')) # Create a folder to verify the install cleans out the dir
+
+ candidate = Candidate('ansible_namespace.collection', '0.1.0', to_text(collection_tar), 'file')
+ collection.install(candidate, to_text(output_path), concrete_artifact_cm)
# Ensure the temp directory is empty, nothing is left behind
assert os.listdir(temp_path) == []
@@ -649,33 +754,29 @@ def test_install_collection(collection_artifact, monkeypatch):
assert mock_display.call_count == 2
assert mock_display.mock_calls[0][1][0] == "Installing 'ansible_namespace.collection:0.1.0' to '%s'" \
% to_text(collection_path)
- assert mock_display.mock_calls[1][1][0] == "ansible_namespace.collection (0.1.0) was installed successfully"
+ assert mock_display.mock_calls[1][1][0] == "ansible_namespace.collection:0.1.0 was installed successfully"
def test_install_collection_with_download(galaxy_server, collection_artifact, monkeypatch):
- collection_tar = collection_artifact[1]
- output_path = os.path.join(os.path.split(collection_tar)[0], b'output')
- collection_path = os.path.join(output_path, b'ansible_namespace', b'collection')
+ collection_path, collection_tar = collection_artifact
+ shutil.rmtree(collection_path)
+
+ collections_dir = ('%s' % os.path.sep).join(to_text(collection_path).split('%s' % os.path.sep)[:-2])
+
+ temp_path = os.path.join(os.path.split(collection_tar)[0], b'temp')
+ os.makedirs(temp_path)
mock_display = MagicMock()
monkeypatch.setattr(Display, 'display', mock_display)
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(temp_path, validate_certs=False)
+
mock_download = MagicMock()
mock_download.return_value = collection_tar
- monkeypatch.setattr(collection, '_download_file', mock_download)
-
- monkeypatch.setattr(galaxy_server, '_available_api_versions', {'v2': 'v2/'})
- temp_path = os.path.join(os.path.split(collection_tar)[0], b'temp')
- os.makedirs(temp_path)
+ monkeypatch.setattr(concrete_artifact_cm, 'get_galaxy_artifact_path', mock_download)
- meta = api.CollectionVersionMetadata('ansible_namespace', 'collection', '0.1.0', 'https://downloadme.com',
- 'myhash', {})
- req = collection.CollectionRequirement('ansible_namespace', 'collection', None, galaxy_server,
- ['0.1.0'], '*', False, metadata=meta)
- req.install(to_text(output_path), temp_path)
-
- # Ensure the temp directory is empty, nothing is left behind
- assert os.listdir(temp_path) == []
+ req = Requirement('ansible_namespace.collection', '0.1.0', 'https://downloadme.com', 'galaxy')
+ collection.install(req, to_text(collections_dir), concrete_artifact_cm)
actual_files = os.listdir(collection_path)
actual_files.sort()
@@ -685,13 +786,11 @@ def test_install_collection_with_download(galaxy_server, collection_artifact, mo
assert mock_display.call_count == 2
assert mock_display.mock_calls[0][1][0] == "Installing 'ansible_namespace.collection:0.1.0' to '%s'" \
% to_text(collection_path)
- assert mock_display.mock_calls[1][1][0] == "ansible_namespace.collection (0.1.0) was installed successfully"
+ assert mock_display.mock_calls[1][1][0] == "ansible_namespace.collection:0.1.0 was installed successfully"
assert mock_download.call_count == 1
- assert mock_download.mock_calls[0][1][0] == 'https://downloadme.com'
- assert mock_download.mock_calls[0][1][1] == temp_path
- assert mock_download.mock_calls[0][1][2] == 'myhash'
- assert mock_download.mock_calls[0][1][3] is True
+ assert mock_download.mock_calls[0][1][0].src == 'https://downloadme.com'
+ assert mock_download.mock_calls[0][1][0].type == 'galaxy'
def test_install_collections_from_tar(collection_artifact, monkeypatch):
@@ -702,8 +801,10 @@ def test_install_collections_from_tar(collection_artifact, monkeypatch):
mock_display = MagicMock()
monkeypatch.setattr(Display, 'display', mock_display)
- collection.install_collections([(to_text(collection_tar), '*', None, None)], to_text(temp_path),
- [u'https://galaxy.ansible.com'], True, False, False, False, False)
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(temp_path, validate_certs=False)
+
+ requirements = [Requirement('ansible_namespace.collection', '0.1.0', to_text(collection_tar), 'file')]
+ collection.install_collections(requirements, to_text(temp_path), [], False, False, False, False, False, concrete_artifact_cm)
assert os.path.isdir(collection_path)
@@ -734,9 +835,12 @@ def test_install_collections_existing_without_force(collection_artifact, monkeyp
mock_display = MagicMock()
monkeypatch.setattr(Display, 'display', mock_display)
- # If we don't delete collection_path it will think the original build skeleton is installed so we expect a skip
- collection.install_collections([(to_text(collection_tar), '*', None, None)], to_text(temp_path),
- [u'https://galaxy.ansible.com'], True, False, False, False, False)
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(temp_path, validate_certs=False)
+
+ assert os.path.isdir(collection_path)
+
+ requirements = [Requirement('ansible_namespace.collection', '0.1.0', to_text(collection_tar), 'file')]
+ collection.install_collections(requirements, to_text(temp_path), [], False, False, False, False, False, concrete_artifact_cm)
assert os.path.isdir(collection_path)
@@ -746,11 +850,9 @@ def test_install_collections_existing_without_force(collection_artifact, monkeyp
# Filter out the progress cursor display calls.
display_msgs = [m[1][0] for m in mock_display.mock_calls if 'newline' not in m[2] and len(m[1]) == 1]
- assert len(display_msgs) == 3
+ assert len(display_msgs) == 1
- assert display_msgs[0] == "Process install dependency map"
- assert display_msgs[1] == "Starting collection install process"
- assert display_msgs[2] == "Skipping 'ansible_namespace.collection' as it is already installed"
+ assert display_msgs[0] == 'Nothing to do. All requested collections are already installed. If you want to reinstall them, consider using `--force`.'
for msg in display_msgs:
assert 'WARNING' not in msg
@@ -768,8 +870,9 @@ def test_install_missing_metadata_warning(collection_artifact, monkeypatch):
if os.path.isfile(b_path):
os.unlink(b_path)
- collection.install_collections([(to_text(collection_tar), '*', None, None)], to_text(temp_path),
- [u'https://galaxy.ansible.com'], True, False, False, False, False)
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(temp_path, validate_certs=False)
+ requirements = [Requirement('ansible_namespace.collection', '0.1.0', to_text(collection_tar), 'file')]
+ collection.install_collections(requirements, to_text(temp_path), [], False, False, False, False, False, concrete_artifact_cm)
display_msgs = [m[1][0] for m in mock_display.mock_calls if 'newline' not in m[2] and len(m[1]) == 1]
@@ -788,8 +891,9 @@ def test_install_collection_with_circular_dependency(collection_artifact, monkey
mock_display = MagicMock()
monkeypatch.setattr(Display, 'display', mock_display)
- collection.install_collections([(to_text(collection_tar), '*', None, None)], to_text(temp_path),
- [u'https://galaxy.ansible.com'], True, False, False, False, False)
+ concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(temp_path, validate_certs=False)
+ requirements = [Requirement('ansible_namespace.collection', '0.1.0', to_text(collection_tar), 'file')]
+ collection.install_collections(requirements, to_text(temp_path), [], False, False, False, False, False, concrete_artifact_cm)
assert os.path.isdir(collection_path)
@@ -811,4 +915,4 @@ def test_install_collection_with_circular_dependency(collection_artifact, monkey
assert display_msgs[0] == "Process install dependency map"
assert display_msgs[1] == "Starting collection install process"
assert display_msgs[2] == "Installing 'ansible_namespace.collection:0.1.0' to '%s'" % to_text(collection_path)
- assert display_msgs[3] == "ansible_namespace.collection (0.1.0) was installed successfully"
+ assert display_msgs[3] == "ansible_namespace.collection:0.1.0 was installed successfully"