mirror of https://github.com/ansible/ansible.git
* ansible-galaxy - optimise some paths and use fake galaxy int tests (#67685) * ansible-galaxy - optimise some paths and use fake galaxy int tests * Added init, built, and publish tests * Test against both mocked Galaxy and AH server * Finish off writing the install tests * Fix up broken tests * Rename test target and add migrated tests * Use cloud provider for Galaxy implementation * Added blank static config * Use correct alias group * Set release version and fix copy typo * Remove reset step as it is no longer needed * Use sane env var names for test container name (cherry picked from commitpull/67619/head26129fcb80
) * Use --api-key and not --token * Set fallaxy tests as a smoketest (cherry picked from commitb241c021b7
)
parent
b38603c45e
commit
0f7d62f6a5
@ -0,0 +1,5 @@
|
|||||||
|
bugfixes:
|
||||||
|
- ansible-galaxy - Remove uneeded verbose messages when accessing local token file
|
||||||
|
- ansible-galaxy - Display proper error when invalid token is used for Galaxy servers
|
||||||
|
- ansible-galaxy - Send SHA256 hashes when publishing a collection
|
||||||
|
- ansible-galaxy - Fix up pagination searcher for collection versions on Automation Hub
|
@ -0,0 +1,3 @@
|
|||||||
|
shippable/cloud/group1
|
||||||
|
shippable/cloud/smoketest
|
||||||
|
cloud/fallaxy
|
@ -0,0 +1,150 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
# Copyright: (c) 2020, Ansible Project
|
||||||
|
# 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
|
||||||
|
|
||||||
|
ANSIBLE_METADATA = {
|
||||||
|
'metadata_version': '1.1',
|
||||||
|
'status': ['preview'],
|
||||||
|
'supported_by': 'community'
|
||||||
|
}
|
||||||
|
|
||||||
|
DOCUMENTATION = '''
|
||||||
|
---
|
||||||
|
module: setup_collections
|
||||||
|
short_description: Set up test collections based on the input
|
||||||
|
description:
|
||||||
|
- Builds and publishes a whole bunch of collections used for testing in bulk.
|
||||||
|
options:
|
||||||
|
server:
|
||||||
|
description:
|
||||||
|
- The Galaxy server to upload the collections to.
|
||||||
|
required: yes
|
||||||
|
type: str
|
||||||
|
token:
|
||||||
|
description:
|
||||||
|
- The token used to authenticate with the Galaxy server.
|
||||||
|
required: yes
|
||||||
|
type: str
|
||||||
|
collections:
|
||||||
|
description:
|
||||||
|
- A list of collection details to use for the build.
|
||||||
|
required: yes
|
||||||
|
type: list
|
||||||
|
elements: dict
|
||||||
|
options:
|
||||||
|
namespace:
|
||||||
|
description:
|
||||||
|
- The namespace of the collection.
|
||||||
|
required: yes
|
||||||
|
type: str
|
||||||
|
name:
|
||||||
|
description:
|
||||||
|
- The name of the collection.
|
||||||
|
required: yes
|
||||||
|
type: str
|
||||||
|
version:
|
||||||
|
description:
|
||||||
|
- The version of the collection.
|
||||||
|
type: str
|
||||||
|
default: '1.0.0'
|
||||||
|
dependencies:
|
||||||
|
description:
|
||||||
|
- The dependencies of the collection.
|
||||||
|
type: dict
|
||||||
|
default: '{}'
|
||||||
|
author:
|
||||||
|
- Jordan Borean (@jborean93)
|
||||||
|
'''
|
||||||
|
|
||||||
|
EXAMPLES = '''
|
||||||
|
- name: Build test collections
|
||||||
|
setup_collections:
|
||||||
|
path: ~/ansible/collections/ansible_collections
|
||||||
|
collections:
|
||||||
|
- namespace: namespace1
|
||||||
|
name: name1
|
||||||
|
version: 0.0.1
|
||||||
|
- namespace: namespace1
|
||||||
|
name: name1
|
||||||
|
version: 0.0.2
|
||||||
|
'''
|
||||||
|
|
||||||
|
RETURN = '''
|
||||||
|
#
|
||||||
|
'''
|
||||||
|
|
||||||
|
import os
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils._text import to_bytes
|
||||||
|
|
||||||
|
|
||||||
|
def run_module():
|
||||||
|
module_args = dict(
|
||||||
|
server=dict(type='str', required=True),
|
||||||
|
token=dict(type='str', required=True),
|
||||||
|
collections=dict(
|
||||||
|
type='list',
|
||||||
|
elements='dict',
|
||||||
|
required=True,
|
||||||
|
options=dict(
|
||||||
|
namespace=dict(type='str', required=True),
|
||||||
|
name=dict(type='str', required=True),
|
||||||
|
version=dict(type='str', default='1.0.0'),
|
||||||
|
dependencies=dict(type='dict', default={}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
module = AnsibleModule(
|
||||||
|
argument_spec=module_args,
|
||||||
|
supports_check_mode=False
|
||||||
|
)
|
||||||
|
|
||||||
|
result = dict(changed=True)
|
||||||
|
|
||||||
|
for idx, collection in enumerate(module.params['collections']):
|
||||||
|
collection_dir = os.path.join(module.tmpdir, "%s-%s-%s" % (collection['namespace'], collection['name'],
|
||||||
|
collection['version']))
|
||||||
|
b_collection_dir = to_bytes(collection_dir, errors='surrogate_or_strict')
|
||||||
|
os.mkdir(b_collection_dir)
|
||||||
|
|
||||||
|
with open(os.path.join(b_collection_dir, b'README.md'), mode='wb') as fd:
|
||||||
|
fd.write(b"Collection readme")
|
||||||
|
|
||||||
|
galaxy_meta = {
|
||||||
|
'namespace': collection['namespace'],
|
||||||
|
'name': collection['name'],
|
||||||
|
'version': collection['version'],
|
||||||
|
'readme': 'README.md',
|
||||||
|
'authors': ['Collection author <name@email.com'],
|
||||||
|
'dependencies': collection['dependencies'],
|
||||||
|
}
|
||||||
|
with open(os.path.join(b_collection_dir, b'galaxy.yml'), mode='wb') as fd:
|
||||||
|
fd.write(to_bytes(yaml.safe_dump(galaxy_meta), errors='surrogate_or_strict'))
|
||||||
|
|
||||||
|
release_filename = '%s-%s-%s.tar.gz' % (collection['namespace'], collection['name'], collection['version'])
|
||||||
|
collection_path = os.path.join(collection_dir, release_filename)
|
||||||
|
module.run_command(['ansible-galaxy', 'collection', 'build'], cwd=collection_dir)
|
||||||
|
|
||||||
|
# To save on time, skip the import wait until the last collection is being uploaded.
|
||||||
|
publish_args = ['ansible-galaxy', 'collection', 'publish', collection_path, '--server',
|
||||||
|
module.params['server'], '--api-key', module.params['token']]
|
||||||
|
if idx != (len(module.params['collections']) - 1):
|
||||||
|
publish_args.append('--no-wait')
|
||||||
|
module.run_command(publish_args)
|
||||||
|
|
||||||
|
module.exit_json(**result)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
run_module()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
- setup_remote_tmp_dir
|
@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
- name: build basic collection based on current directory
|
||||||
|
command: ansible-galaxy collection build
|
||||||
|
args:
|
||||||
|
chdir: '{{ galaxy_dir }}/scratch/ansible_test/my_collection'
|
||||||
|
register: build_current_dir
|
||||||
|
|
||||||
|
- name: get result of build basic collection on current directory
|
||||||
|
stat:
|
||||||
|
path: '{{ galaxy_dir }}/scratch/ansible_test/my_collection/ansible_test-my_collection-1.0.0.tar.gz'
|
||||||
|
register: build_current_dir_actual
|
||||||
|
|
||||||
|
- name: assert build basic collection based on current directory
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '"Created collection for ansible_test.my_collection" in build_current_dir.stdout'
|
||||||
|
- build_current_dir_actual.stat.exists
|
||||||
|
|
||||||
|
- name: build basic collection based on relative dir
|
||||||
|
command: ansible-galaxy collection build scratch/ansible_test/my_collection
|
||||||
|
args:
|
||||||
|
chdir: '{{ galaxy_dir }}'
|
||||||
|
register: build_relative_dir
|
||||||
|
|
||||||
|
- name: get result of build basic collection based on relative dir
|
||||||
|
stat:
|
||||||
|
path: '{{ galaxy_dir }}/ansible_test-my_collection-1.0.0.tar.gz'
|
||||||
|
register: build_relative_dir_actual
|
||||||
|
|
||||||
|
- name: assert build basic collection based on relative dir
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '"Created collection for ansible_test.my_collection" in build_relative_dir.stdout'
|
||||||
|
- build_relative_dir_actual.stat.exists
|
||||||
|
|
||||||
|
- name: fail to build existing collection without force
|
||||||
|
command: ansible-galaxy collection build scratch/ansible_test/my_collection
|
||||||
|
args:
|
||||||
|
chdir: '{{ galaxy_dir }}'
|
||||||
|
ignore_errors: yes
|
||||||
|
register: build_existing_no_force
|
||||||
|
|
||||||
|
- name: build existing collection with force
|
||||||
|
command: ansible-galaxy collection build scratch/ansible_test/my_collection --force
|
||||||
|
args:
|
||||||
|
chdir: '{{ galaxy_dir }}'
|
||||||
|
register: build_existing_force
|
||||||
|
|
||||||
|
- name: assert build existing collection
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '"use --force to re-create the collection artifact" in build_existing_no_force.stderr'
|
||||||
|
- '"Created collection for ansible_test.my_collection" in build_existing_force.stdout'
|
@ -0,0 +1,44 @@
|
|||||||
|
---
|
||||||
|
- name: create default skeleton
|
||||||
|
command: ansible-galaxy collection init ansible_test.my_collection
|
||||||
|
args:
|
||||||
|
chdir: '{{ galaxy_dir }}/scratch'
|
||||||
|
register: init_relative
|
||||||
|
|
||||||
|
- name: get result of create default skeleton
|
||||||
|
find:
|
||||||
|
path: '{{ galaxy_dir }}/scratch/ansible_test/my_collection'
|
||||||
|
recurse: yes
|
||||||
|
file_type: directory
|
||||||
|
register: init_relative_actual
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
var: init_relative_actual.files | map(attribute='path') | list
|
||||||
|
|
||||||
|
- name: assert create default skeleton
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '"Collection ansible_test.my_collection was created successfully" in init_relative.stdout'
|
||||||
|
- init_relative_actual.files | length == 3
|
||||||
|
- (init_relative_actual.files | map(attribute='path') | list)[0] | basename in ['docs', 'plugins', 'roles']
|
||||||
|
- (init_relative_actual.files | map(attribute='path') | list)[1] | basename in ['docs', 'plugins', 'roles']
|
||||||
|
- (init_relative_actual.files | map(attribute='path') | list)[2] | basename in ['docs', 'plugins', 'roles']
|
||||||
|
|
||||||
|
- name: create collection with custom init path
|
||||||
|
command: ansible-galaxy collection init ansible_test2.my_collection --init-path "{{ galaxy_dir }}/scratch/custom-init-dir"
|
||||||
|
register: init_custom_path
|
||||||
|
|
||||||
|
- name: get result of create default skeleton
|
||||||
|
find:
|
||||||
|
path: '{{ galaxy_dir }}/scratch/custom-init-dir/ansible_test2/my_collection'
|
||||||
|
file_type: directory
|
||||||
|
register: init_custom_path_actual
|
||||||
|
|
||||||
|
- name: assert create collection with custom init path
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '"Collection ansible_test2.my_collection was created successfully" in init_custom_path.stdout'
|
||||||
|
- init_custom_path_actual.files | length == 3
|
||||||
|
- (init_custom_path_actual.files | map(attribute='path') | list)[0] | basename in ['docs', 'plugins', 'roles']
|
||||||
|
- (init_custom_path_actual.files | map(attribute='path') | list)[1] | basename in ['docs', 'plugins', 'roles']
|
||||||
|
- (init_custom_path_actual.files | map(attribute='path') | list)[2] | basename in ['docs', 'plugins', 'roles']
|
@ -0,0 +1,181 @@
|
|||||||
|
---
|
||||||
|
- name: create test collection install directory - {{ test_name }}
|
||||||
|
file:
|
||||||
|
path: '{{ galaxy_dir }}/ansible_collections'
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: install simple collection with implicit path - {{ test_name }}
|
||||||
|
command: ansible-galaxy collection install namespace1.name1 -s '{{ test_server }}'
|
||||||
|
environment:
|
||||||
|
ANSIBLE_COLLECTIONS_PATHS: '{{ galaxy_dir }}/ansible_collections'
|
||||||
|
register: install_normal
|
||||||
|
|
||||||
|
- name: get installed files of install simple collection with implicit path - {{ test_name }}
|
||||||
|
find:
|
||||||
|
path: '{{ galaxy_dir }}/ansible_collections/namespace1/name1'
|
||||||
|
file_type: file
|
||||||
|
register: install_normal_files
|
||||||
|
|
||||||
|
- name: get the manifest of install simple collection with implicit path - {{ test_name }}
|
||||||
|
slurp:
|
||||||
|
path: '{{ galaxy_dir }}/ansible_collections/namespace1/name1/MANIFEST.json'
|
||||||
|
register: install_normal_manifest
|
||||||
|
|
||||||
|
- name: assert install simple collection with implicit path - {{ test_name }}
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '"Installing ''namespace1.name1:1.0.9'' to" in install_normal.stdout'
|
||||||
|
- install_normal_files.files | length == 3
|
||||||
|
- install_normal_files.files[0].path | basename in ['MANIFEST.json', 'FILES.json', 'README.md']
|
||||||
|
- install_normal_files.files[1].path | basename in ['MANIFEST.json', 'FILES.json', 'README.md']
|
||||||
|
- install_normal_files.files[2].path | basename in ['MANIFEST.json', 'FILES.json', 'README.md']
|
||||||
|
- (install_normal_manifest.content | b64decode | from_json).collection_info.version == '1.0.9'
|
||||||
|
|
||||||
|
- name: install existing without --force - {{ test_name }}
|
||||||
|
command: ansible-galaxy collection install namespace1.name1 -s '{{ test_server }}'
|
||||||
|
environment:
|
||||||
|
ANSIBLE_COLLECTIONS_PATHS: '{{ galaxy_dir }}/ansible_collections'
|
||||||
|
register: install_existing_no_force
|
||||||
|
|
||||||
|
- name: assert install existing without --force - {{ test_name }}
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '"Skipping ''namespace1.name1'' as it is already installed" in install_existing_no_force.stdout'
|
||||||
|
|
||||||
|
- name: install existing with --force - {{ test_name }}
|
||||||
|
command: ansible-galaxy collection install namespace1.name1 -s '{{ test_server }}' --force
|
||||||
|
environment:
|
||||||
|
ANSIBLE_COLLECTIONS_PATH: '{{ galaxy_dir }}/ansible_collections'
|
||||||
|
register: install_existing_force
|
||||||
|
|
||||||
|
- name: assert install existing with --force - {{ test_name }}
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '"Installing ''namespace1.name1:1.0.9'' to" in install_existing_force.stdout'
|
||||||
|
|
||||||
|
- name: remove test installed collection - {{ test_name }}
|
||||||
|
file:
|
||||||
|
path: '{{ galaxy_dir }}/ansible_collections/namespace1'
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: install pre-release as explicit version to custom dir - {{ test_name }}
|
||||||
|
command: ansible-galaxy collection install 'namespace1.name1:1.1.0-beta.1' -s '{{ test_server }}' -p '{{ galaxy_dir }}/ansible_collections'
|
||||||
|
register: install_prerelease
|
||||||
|
|
||||||
|
- name: get result of install pre-release as explicit version to custom dir - {{ test_name }}
|
||||||
|
slurp:
|
||||||
|
path: '{{ galaxy_dir }}/ansible_collections/namespace1/name1/MANIFEST.json'
|
||||||
|
register: install_prerelease_actual
|
||||||
|
|
||||||
|
- name: assert install pre-release as explicit version to custom dir - {{ test_name }}
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '"Installing ''namespace1.name1:1.1.0-beta.1'' to" in install_prerelease.stdout'
|
||||||
|
- (install_prerelease_actual.content | b64decode | from_json).collection_info.version == '1.1.0-beta.1'
|
||||||
|
|
||||||
|
- name: install multiple collections with dependencies - {{ test_name }}
|
||||||
|
command: ansible-galaxy collection install parent_dep.parent_collection namespace2.name -s {{ test_name }}
|
||||||
|
args:
|
||||||
|
chdir: '{{ galaxy_dir }}/ansible_collections'
|
||||||
|
environment:
|
||||||
|
ANSIBLE_COLLECTIONS_PATHS: '{{ galaxy_dir }}/ansible_collections'
|
||||||
|
ANSIBLE_CONFIG: '{{ galaxy_dir }}/ansible.cfg'
|
||||||
|
register: install_multiple_with_dep
|
||||||
|
|
||||||
|
- name: get result of install multiple collections with dependencies - {{ test_name }}
|
||||||
|
slurp:
|
||||||
|
path: '{{ galaxy_dir }}/ansible_collections/{{ collection.namespace }}/{{ collection.name }}/MANIFEST.json'
|
||||||
|
register: install_multiple_with_dep_actual
|
||||||
|
loop_control:
|
||||||
|
loop_var: collection
|
||||||
|
loop:
|
||||||
|
- namespace: namespace2
|
||||||
|
name: name
|
||||||
|
- namespace: parent_dep
|
||||||
|
name: parent_collection
|
||||||
|
- namespace: child_dep
|
||||||
|
name: child_collection
|
||||||
|
- namespace: child_dep
|
||||||
|
name: child_dep2
|
||||||
|
|
||||||
|
- name: assert install multiple collections with dependencies - {{ test_name }}
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- (install_multiple_with_dep_actual.results[0].content | b64decode | from_json).collection_info.version == '1.0.0'
|
||||||
|
- (install_multiple_with_dep_actual.results[1].content | b64decode | from_json).collection_info.version == '1.0.0'
|
||||||
|
- (install_multiple_with_dep_actual.results[2].content | b64decode | from_json).collection_info.version == '0.9.9'
|
||||||
|
- (install_multiple_with_dep_actual.results[3].content | b64decode | from_json).collection_info.version == '1.2.2'
|
||||||
|
|
||||||
|
- name: expect failure with dep resolution failure
|
||||||
|
command: ansible-galaxy collection install fail_namespace.fail_collection -s {{ test_server }}
|
||||||
|
register: fail_dep_mismatch
|
||||||
|
failed_when: '"Cannot meet dependency requirement ''fail_dep2.name:<0.0.5'' for collection fail_namespace.fail_collection" not in fail_dep_mismatch.stderr'
|
||||||
|
|
||||||
|
- name: download a collection for an offline install - {{ test_name }}
|
||||||
|
get_url:
|
||||||
|
url: '{{ test_server }}custom/collections/namespace3-name-1.0.0.tar.gz'
|
||||||
|
dest: '{{ galaxy_dir }}/namespace3.tar.gz'
|
||||||
|
|
||||||
|
- name: install a collection from a tarball - {{ test_name }}
|
||||||
|
command: ansible-galaxy collection install '{{ galaxy_dir }}/namespace3.tar.gz'
|
||||||
|
register: install_tarball
|
||||||
|
environment:
|
||||||
|
ANSIBLE_COLLECTIONS_PATHS: '{{ galaxy_dir }}/ansible_collections'
|
||||||
|
|
||||||
|
- name: get result of install collection from a tarball - {{ test_name }}
|
||||||
|
slurp:
|
||||||
|
path: '{{ galaxy_dir }}/ansible_collections/namespace3/name/MANIFEST.json'
|
||||||
|
register: install_tarball_actual
|
||||||
|
|
||||||
|
- name: assert install a collection from a tarball - {{ test_name }}
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '"Installing ''namespace3.name:1.0.0'' to" in install_tarball.stdout'
|
||||||
|
- (install_tarball_actual.content | b64decode | from_json).collection_info.version == '1.0.0'
|
||||||
|
|
||||||
|
- name: install a collection from a URI - {{ test_name }}
|
||||||
|
command: ansible-galaxy collection install '{{ test_server }}custom/collections/namespace4-name-1.0.0.tar.gz'
|
||||||
|
register: install_uri
|
||||||
|
environment:
|
||||||
|
ANSIBLE_COLLECTIONS_PATHS: '{{ galaxy_dir }}/ansible_collections'
|
||||||
|
|
||||||
|
- name: get result of install collection from a URI - {{ test_name }}
|
||||||
|
slurp:
|
||||||
|
path: '{{ galaxy_dir }}/ansible_collections/namespace4/name/MANIFEST.json'
|
||||||
|
register: install_uri_actual
|
||||||
|
|
||||||
|
- name: assert install a collection from a URI - {{ test_name }}
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '"Installing ''namespace4.name:1.0.0'' to" in install_uri.stdout'
|
||||||
|
- (install_uri_actual.content | b64decode | from_json).collection_info.version == '1.0.0'
|
||||||
|
|
||||||
|
- name: fail to install a collection with an undefined URL - {{ test_name }}
|
||||||
|
command: ansible-galaxy collection install namespace5.name
|
||||||
|
register: fail_undefined_server
|
||||||
|
failed_when: '"No setting was provided for required configuration plugin_type: galaxy_server plugin: undefined" not in fail_undefined_server.stderr'
|
||||||
|
environment:
|
||||||
|
ANSIBLE_GALAXY_SERVER_LIST: undefined
|
||||||
|
|
||||||
|
- name: install a collection with an empty server list - {{ test_name }}
|
||||||
|
command: ansible-galaxy collection install namespace5.name -s '{{ test_server }}'
|
||||||
|
register: install_empty_server_list
|
||||||
|
environment:
|
||||||
|
ANSIBLE_COLLECTIONS_PATHS: '{{ galaxy_dir }}/ansible_collections'
|
||||||
|
ANSIBLE_GALAXY_SERVER_LIST: ''
|
||||||
|
|
||||||
|
- name: get result of a collection with an empty server list - {{ test_name }}
|
||||||
|
slurp:
|
||||||
|
path: '{{ galaxy_dir }}/ansible_collections/namespace5/name/MANIFEST.json'
|
||||||
|
register: install_empty_server_list_actual
|
||||||
|
|
||||||
|
- name: assert install a collection with an empty server list - {{ test_name }}
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '"Installing ''namespace5.name:1.0.0'' to" in install_empty_server_list.stdout'
|
||||||
|
- (install_empty_server_list_actual.content | b64decode | from_json).collection_info.version == '1.0.0'
|
||||||
|
|
||||||
|
- name: remove test collection install directory - {{ test_name }}
|
||||||
|
file:
|
||||||
|
path: '{{ galaxy_dir }}/ansible_collections'
|
||||||
|
state: absent
|
@ -0,0 +1,150 @@
|
|||||||
|
---
|
||||||
|
- name: set some facts for tests
|
||||||
|
set_fact:
|
||||||
|
galaxy_dir: "{{ remote_tmp_dir }}/galaxy"
|
||||||
|
|
||||||
|
- name: create scratch dir used for testing
|
||||||
|
file:
|
||||||
|
path: '{{ galaxy_dir }}/scratch'
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: run ansible-galaxy collection init tests
|
||||||
|
import_tasks: init.yml
|
||||||
|
|
||||||
|
- name: run ansible-galaxy collection build tests
|
||||||
|
import_tasks: build.yml
|
||||||
|
|
||||||
|
- name: create test ansible.cfg that contains the Galaxy server list
|
||||||
|
template:
|
||||||
|
src: ansible.cfg.j2
|
||||||
|
dest: '{{ galaxy_dir }}/ansible.cfg'
|
||||||
|
|
||||||
|
- name: run ansible-galaxy collection publish tests for {{ test_name }}
|
||||||
|
include_tasks: publish.yml
|
||||||
|
vars:
|
||||||
|
test_name: '{{ item.name }}'
|
||||||
|
test_server: '{{ item.server }}'
|
||||||
|
with_items:
|
||||||
|
- name: galaxy
|
||||||
|
server: '{{ fallaxy_galaxy_server }}'
|
||||||
|
- name: automation_hub
|
||||||
|
server: '{{ fallaxy_ah_server }}'
|
||||||
|
|
||||||
|
# We use a module for this so we can speed up the test time.
|
||||||
|
- name: setup test collections for install test
|
||||||
|
setup_collections:
|
||||||
|
server: '{{ fallaxy_galaxy_server }}'
|
||||||
|
token: '{{ fallaxy_token }}'
|
||||||
|
collections:
|
||||||
|
# Scenario to test out pre-release being ignored unless explicitly set and version pagination.
|
||||||
|
- namespace: namespace1
|
||||||
|
name: name1
|
||||||
|
version: 0.0.1
|
||||||
|
- namespace: namespace1
|
||||||
|
name: name1
|
||||||
|
version: 0.0.2
|
||||||
|
- namespace: namespace1
|
||||||
|
name: name1
|
||||||
|
version: 0.0.3
|
||||||
|
- namespace: namespace1
|
||||||
|
name: name1
|
||||||
|
version: 0.0.4
|
||||||
|
- namespace: namespace1
|
||||||
|
name: name1
|
||||||
|
version: 0.0.5
|
||||||
|
- namespace: namespace1
|
||||||
|
name: name1
|
||||||
|
version: 0.0.6
|
||||||
|
- namespace: namespace1
|
||||||
|
name: name1
|
||||||
|
version: 0.0.7
|
||||||
|
- namespace: namespace1
|
||||||
|
name: name1
|
||||||
|
version: 0.0.8
|
||||||
|
- namespace: namespace1
|
||||||
|
name: name1
|
||||||
|
version: 0.0.9
|
||||||
|
- namespace: namespace1
|
||||||
|
name: name1
|
||||||
|
version: 0.0.10
|
||||||
|
- namespace: namespace1
|
||||||
|
name: name1
|
||||||
|
version: 0.1.0
|
||||||
|
- namespace: namespace1
|
||||||
|
name: name1
|
||||||
|
version: 1.0.0
|
||||||
|
- namespace: namespace1
|
||||||
|
name: name1
|
||||||
|
version: 1.0.9
|
||||||
|
- namespace: namespace1
|
||||||
|
name: name1
|
||||||
|
version: 1.1.0-beta.1
|
||||||
|
|
||||||
|
# Pad out number of namespaces for pagination testing
|
||||||
|
- namespace: namespace2
|
||||||
|
name: name
|
||||||
|
- namespace: namespace3
|
||||||
|
name: name
|
||||||
|
- namespace: namespace4
|
||||||
|
name: name
|
||||||
|
- namespace: namespace5
|
||||||
|
name: name
|
||||||
|
- namespace: namespace6
|
||||||
|
name: name
|
||||||
|
- namespace: namespace7
|
||||||
|
name: name
|
||||||
|
- namespace: namespace8
|
||||||
|
name: name
|
||||||
|
- namespace: namespace9
|
||||||
|
name: name
|
||||||
|
|
||||||
|
# Complex dependency resolution
|
||||||
|
- namespace: parent_dep
|
||||||
|
name: parent_collection
|
||||||
|
dependencies:
|
||||||
|
child_dep.child_collection: '>=0.5.0,<1.0.0'
|
||||||
|
- namespace: child_dep
|
||||||
|
name: child_collection
|
||||||
|
version: 0.4.0
|
||||||
|
- namespace: child_dep
|
||||||
|
name: child_collection
|
||||||
|
version: 0.5.0
|
||||||
|
- namespace: child_dep
|
||||||
|
name: child_collection
|
||||||
|
version: 0.9.9
|
||||||
|
dependencies:
|
||||||
|
child_dep.child_dep2: '!=1.2.3'
|
||||||
|
- namespace: child_dep
|
||||||
|
name: child_collection
|
||||||
|
- namespace: child_dep
|
||||||
|
name: child_dep2
|
||||||
|
version: 1.2.2
|
||||||
|
- namespace: child_dep
|
||||||
|
name: child_dep2
|
||||||
|
version: 1.2.3
|
||||||
|
|
||||||
|
# Dep resolution failure
|
||||||
|
- namespace: fail_namespace
|
||||||
|
name: fail_collection
|
||||||
|
version: 2.1.2
|
||||||
|
dependencies:
|
||||||
|
fail_dep.name: '0.0.5'
|
||||||
|
fail_dep2.name: '<0.0.5'
|
||||||
|
- namespace: fail_dep
|
||||||
|
name: name
|
||||||
|
version: '0.0.5'
|
||||||
|
dependencies:
|
||||||
|
fail_dep2.name: '>0.0.5'
|
||||||
|
- namespace: fail_dep2
|
||||||
|
name: name
|
||||||
|
|
||||||
|
- name: run ansible-galaxy collection install tests for {{ test_name }}
|
||||||
|
include_tasks: install.yml
|
||||||
|
vars:
|
||||||
|
test_name: '{{ item.name }}'
|
||||||
|
test_server: '{{ item.server }}'
|
||||||
|
with_items:
|
||||||
|
- name: galaxy
|
||||||
|
server: '{{ fallaxy_galaxy_server }}'
|
||||||
|
- name: automation_hub
|
||||||
|
server: '{{ fallaxy_ah_server }}'
|
@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
- name: fail to publish with no token - {{ test_name }}
|
||||||
|
command: ansible-galaxy collection publish ansible_test-my_collection-1.0.0.tar.gz -s {{ test_server }}
|
||||||
|
args:
|
||||||
|
chdir: '{{ galaxy_dir }}'
|
||||||
|
register: fail_no_token
|
||||||
|
failed_when: '"HTTP Code: 401" not in fail_no_token.stderr'
|
||||||
|
|
||||||
|
- name: fail to publish with invalid token - {{ test_name }}
|
||||||
|
command: ansible-galaxy collection publish ansible_test-my_collection-1.0.0.tar.gz -s {{ test_server }} --api-key fail
|
||||||
|
args:
|
||||||
|
chdir: '{{ galaxy_dir }}'
|
||||||
|
register: fail_invalid_token
|
||||||
|
failed_when: '"HTTP Code: 401" not in fail_invalid_token.stderr'
|
||||||
|
|
||||||
|
- name: publish collection - {{ test_name }}
|
||||||
|
command: ansible-galaxy collection publish ansible_test-my_collection-1.0.0.tar.gz -s {{ test_server }} --api-key {{ fallaxy_token }}
|
||||||
|
args:
|
||||||
|
chdir: '{{ galaxy_dir }}'
|
||||||
|
register: publish_collection
|
||||||
|
|
||||||
|
- name: get result of publish collection - {{ test_name }}
|
||||||
|
uri:
|
||||||
|
url: '{{ test_server }}v2/collections/ansible_test/my_collection/versions/1.0.0/'
|
||||||
|
return_content: yes
|
||||||
|
register: publish_collection_actual
|
||||||
|
|
||||||
|
- name: assert publish collection - {{ test_name }}
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '"Collection has been successfully published and imported to the Galaxy server" in publish_collection.stdout'
|
||||||
|
- publish_collection_actual.json.metadata.name == 'my_collection'
|
||||||
|
- publish_collection_actual.json.metadata.namespace == 'ansible_test'
|
||||||
|
- publish_collection_actual.json.metadata.version == '1.0.0'
|
||||||
|
|
||||||
|
- name: fail to publish existing collection version - {{ test_name }}
|
||||||
|
command: ansible-galaxy collection publish ansible_test-my_collection-1.0.0.tar.gz -s {{ test_server }} --api-key {{ fallaxy_token }}
|
||||||
|
args:
|
||||||
|
chdir: '{{ galaxy_dir }}'
|
||||||
|
register: fail_publish_existing
|
||||||
|
failed_when: '"Artifact already exists" not in fail_publish_existing.stderr'
|
||||||
|
|
||||||
|
- name: reset published collections - {{ test_name }}
|
||||||
|
uri:
|
||||||
|
url: '{{ test_server }}custom/reset/'
|
||||||
|
method: POST
|
@ -0,0 +1,10 @@
|
|||||||
|
[galaxy]
|
||||||
|
server_list=galaxy,automation_hub
|
||||||
|
|
||||||
|
[galaxy_server.galaxy]
|
||||||
|
url={{ fallaxy_galaxy_server }}
|
||||||
|
token={{ fallaxy_token }}
|
||||||
|
|
||||||
|
[galaxy_server.automation_hub]
|
||||||
|
url={{ fallaxy_ah_server }}
|
||||||
|
token={{ fallaxy_token }}
|
@ -0,0 +1,177 @@
|
|||||||
|
"""Fallaxy (ansible-galaxy) plugin for integration tests."""
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import os
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
from . import (
|
||||||
|
CloudProvider,
|
||||||
|
CloudEnvironment,
|
||||||
|
CloudEnvironmentConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ..util import (
|
||||||
|
find_executable,
|
||||||
|
display,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ..docker_util import (
|
||||||
|
docker_run,
|
||||||
|
docker_rm,
|
||||||
|
docker_inspect,
|
||||||
|
docker_pull,
|
||||||
|
get_docker_container_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class FallaxyProvider(CloudProvider):
|
||||||
|
"""Fallaxy plugin.
|
||||||
|
|
||||||
|
Sets up Fallaxy (ansible-galaxy) stub server for tests.
|
||||||
|
|
||||||
|
It's source source itself resides at: https://github.com/ansible/fallaxy-test-container
|
||||||
|
"""
|
||||||
|
|
||||||
|
DOCKER_SIMULATOR_NAME = 'fallaxy-stub'
|
||||||
|
|
||||||
|
def __init__(self, args):
|
||||||
|
"""
|
||||||
|
:type args: TestConfig
|
||||||
|
"""
|
||||||
|
super(FallaxyProvider, self).__init__(args)
|
||||||
|
|
||||||
|
if os.environ.get('ANSIBLE_FALLAXY_CONTAINER'):
|
||||||
|
self.image = os.environ.get('ANSIBLE_FALLAXY_CONTAINER')
|
||||||
|
else:
|
||||||
|
self.image = 'quay.io/ansible/fallaxy-test-container:1.0.0'
|
||||||
|
self.container_name = ''
|
||||||
|
|
||||||
|
def filter(self, targets, exclude):
|
||||||
|
"""Filter out the tests with the necessary config and res unavailable.
|
||||||
|
|
||||||
|
:type targets: tuple[TestTarget]
|
||||||
|
:type exclude: list[str]
|
||||||
|
"""
|
||||||
|
docker_cmd = 'docker'
|
||||||
|
docker = find_executable(docker_cmd, required=False)
|
||||||
|
|
||||||
|
if docker:
|
||||||
|
return
|
||||||
|
|
||||||
|
skip = 'cloud/%s/' % self.platform
|
||||||
|
skipped = [target.name for target in targets if skip in target.aliases]
|
||||||
|
|
||||||
|
if skipped:
|
||||||
|
exclude.append(skip)
|
||||||
|
display.warning('Excluding tests marked "%s" which require the "%s" command: %s'
|
||||||
|
% (skip.rstrip('/'), docker_cmd, ', '.join(skipped)))
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
"""Setup cloud resource before delegation and reg cleanup callback."""
|
||||||
|
super(FallaxyProvider, self).setup()
|
||||||
|
|
||||||
|
if self._use_static_config():
|
||||||
|
self._setup_static()
|
||||||
|
else:
|
||||||
|
self._setup_dynamic()
|
||||||
|
|
||||||
|
def get_docker_run_options(self):
|
||||||
|
"""Get additional options needed when delegating tests to a container.
|
||||||
|
|
||||||
|
:rtype: list[str]
|
||||||
|
"""
|
||||||
|
return ['--link', self.DOCKER_SIMULATOR_NAME] if self.managed else []
|
||||||
|
|
||||||
|
def cleanup(self):
|
||||||
|
"""Clean up the resource and temporary configs files after tests."""
|
||||||
|
if self.container_name:
|
||||||
|
docker_rm(self.args, self.container_name)
|
||||||
|
|
||||||
|
super(FallaxyProvider, self).cleanup()
|
||||||
|
|
||||||
|
def _setup_dynamic(self):
|
||||||
|
container_id = get_docker_container_id()
|
||||||
|
|
||||||
|
if container_id:
|
||||||
|
display.info('Running in docker container: %s' % container_id, verbosity=1)
|
||||||
|
|
||||||
|
self.container_name = self.DOCKER_SIMULATOR_NAME
|
||||||
|
|
||||||
|
results = docker_inspect(self.args, self.container_name)
|
||||||
|
|
||||||
|
if results and not results[0].get('State', {}).get('Running'):
|
||||||
|
docker_rm(self.args, self.container_name)
|
||||||
|
results = []
|
||||||
|
|
||||||
|
display.info('%s Fallaxy simulator docker container.'
|
||||||
|
% ('Using the existing' if results else 'Starting a new'),
|
||||||
|
verbosity=1)
|
||||||
|
|
||||||
|
fallaxy_port = 8080
|
||||||
|
fallaxy_token = str(uuid.uuid4()).replace('-', '')
|
||||||
|
|
||||||
|
if not results:
|
||||||
|
if self.args.docker or container_id:
|
||||||
|
publish_ports = []
|
||||||
|
else:
|
||||||
|
# publish the simulator ports when not running inside docker
|
||||||
|
publish_ports = [
|
||||||
|
'-p', ':'.join((str(fallaxy_port),) * 2),
|
||||||
|
]
|
||||||
|
|
||||||
|
if not os.environ.get('ANSIBLE_FALLAXY_CONTAINER'):
|
||||||
|
docker_pull(self.args, self.image)
|
||||||
|
|
||||||
|
docker_run(
|
||||||
|
self.args,
|
||||||
|
self.image,
|
||||||
|
['-d', '--name', self.container_name, '-e', 'FALLAXY_TOKEN=%s' % fallaxy_token] + publish_ports,
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.args.docker:
|
||||||
|
fallaxy_host = self.DOCKER_SIMULATOR_NAME
|
||||||
|
elif container_id:
|
||||||
|
fallaxy_host = self._get_simulator_address()
|
||||||
|
display.info('Found Fallaxy simulator container address: %s' % fallaxy_host, verbosity=1)
|
||||||
|
else:
|
||||||
|
fallaxy_host = 'localhost'
|
||||||
|
|
||||||
|
self._set_cloud_config('FALLAXY_HOST', fallaxy_host)
|
||||||
|
self._set_cloud_config('FALLAXY_PORT', str(fallaxy_port))
|
||||||
|
self._set_cloud_config('FALLAXY_TOKEN', fallaxy_token)
|
||||||
|
|
||||||
|
def _get_simulator_address(self):
|
||||||
|
results = docker_inspect(self.args, self.container_name)
|
||||||
|
ipaddress = results[0]['NetworkSettings']['IPAddress']
|
||||||
|
return ipaddress
|
||||||
|
|
||||||
|
def _setup_static(self):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
|
class FallaxyEnvironment(CloudEnvironment):
|
||||||
|
"""Fallaxy environment plugin.
|
||||||
|
|
||||||
|
Updates integration test environment after delegation.
|
||||||
|
"""
|
||||||
|
def get_environment_config(self):
|
||||||
|
"""
|
||||||
|
:rtype: CloudEnvironmentConfig
|
||||||
|
"""
|
||||||
|
fallaxy_token = self._get_cloud_config('FALLAXY_TOKEN')
|
||||||
|
fallaxy_host = self._get_cloud_config('FALLAXY_HOST')
|
||||||
|
fallaxy_port = self._get_cloud_config('FALLAXY_PORT')
|
||||||
|
|
||||||
|
return CloudEnvironmentConfig(
|
||||||
|
ansible_vars=dict(
|
||||||
|
fallaxy_token=fallaxy_token,
|
||||||
|
fallaxy_galaxy_server='http://%s:%s/api/' % (fallaxy_host, fallaxy_port),
|
||||||
|
fallaxy_ah_server='http://%s:%s/api/automation-hub/' % (fallaxy_host, fallaxy_port),
|
||||||
|
),
|
||||||
|
env_vars=dict(
|
||||||
|
FALLAXY_TOKEN=fallaxy_token,
|
||||||
|
FALLAXY_GALAXY_SERVER='http://%s:%s/api/' % (fallaxy_host, fallaxy_port),
|
||||||
|
FALLAXY_AH_SERVER='http://%s:%s/api/automation-hub/' % (fallaxy_host, fallaxy_port),
|
||||||
|
),
|
||||||
|
)
|
Loading…
Reference in New Issue