From bd6193a55f4d4a79939c6f4407d19d56a42841a7 Mon Sep 17 00:00:00 2001 From: Brian Scholer <1260690+briantist@users.noreply.github.com> Date: Mon, 8 Aug 2022 15:15:22 -0400 Subject: [PATCH 1/6] wip --- pyproject.toml | 5 +- tests/conftest.py | 16 +++++ .../briantist.one/v0.1.0/README.md | 3 + .../briantist.one/v0.1.0/galaxy.yml | 61 +++++++++++++++++++ .../briantist.one/v0.1.0/meta/runtime.yml | 2 + .../briantist.one/v0.1.0/plugins/README.md | 31 ++++++++++ .../briantist.one/v0.2.0/README.md | 3 + .../briantist.one/v0.2.0/galaxy.yml | 61 +++++++++++++++++++ .../briantist.one/v0.2.0/meta/runtime.yml | 2 + .../briantist.one/v0.2.0/plugins/README.md | 31 ++++++++++ .../briantist.two/v1.1.0/README.md | 3 + .../briantist.two/v1.1.0/galaxy.yml | 61 +++++++++++++++++++ .../briantist.two/v1.1.0/meta/runtime.yml | 2 + .../briantist.two/v1.1.0/plugins/README.md | 31 ++++++++++ .../briantist.two/v2.2.0/README.md | 3 + .../briantist.two/v2.2.0/galaxy.yml | 61 +++++++++++++++++++ .../briantist.two/v2.2.0/meta/runtime.yml | 2 + .../briantist.two/v2.2.0/plugins/README.md | 31 ++++++++++ tests/data/runtime/.gitignore | 2 + tests/integration/conftest.py | 49 +++++++++++++-- tests/integration/test_me.py | 29 ++++++++- tests/requirements.txt | 6 +- 22 files changed, 482 insertions(+), 13 deletions(-) create mode 100644 tests/data/collections/briantist.one/v0.1.0/README.md create mode 100644 tests/data/collections/briantist.one/v0.1.0/galaxy.yml create mode 100644 tests/data/collections/briantist.one/v0.1.0/meta/runtime.yml create mode 100644 tests/data/collections/briantist.one/v0.1.0/plugins/README.md create mode 100644 tests/data/collections/briantist.one/v0.2.0/README.md create mode 100644 tests/data/collections/briantist.one/v0.2.0/galaxy.yml create mode 100644 tests/data/collections/briantist.one/v0.2.0/meta/runtime.yml create mode 100644 tests/data/collections/briantist.one/v0.2.0/plugins/README.md create mode 100644 tests/data/collections/briantist.two/v1.1.0/README.md create mode 100644 tests/data/collections/briantist.two/v1.1.0/galaxy.yml create mode 100644 tests/data/collections/briantist.two/v1.1.0/meta/runtime.yml create mode 100644 tests/data/collections/briantist.two/v1.1.0/plugins/README.md create mode 100644 tests/data/collections/briantist.two/v2.2.0/README.md create mode 100644 tests/data/collections/briantist.two/v2.2.0/galaxy.yml create mode 100644 tests/data/collections/briantist.two/v2.2.0/meta/runtime.yml create mode 100644 tests/data/collections/briantist.two/v2.2.0/plugins/README.md create mode 100644 tests/data/runtime/.gitignore diff --git a/pyproject.toml b/pyproject.toml index b53ea62..38f69ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,10 +11,9 @@ exclude = ["changelogs"] [tool.pytest.ini_options] minversion = "7.1" -addopts = "--cov --cov-report=xml" -# addopts = "--docker-compose=artifactory/docker-compose.yml" +addopts = "--cov --cov-report=xml --docker-compose=artifactory/docker-compose.yml --use-running-containers" # addopts = "-ra -q" testpaths = [ "unit", - # "integration", + "integration", ] diff --git a/tests/conftest.py b/tests/conftest.py index 83e5039..e004364 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -27,6 +27,22 @@ def _finder(*paths): return _finder +@pytest.fixture(scope='session') +def data_finder(): + def _finder(*paths): + here = os.path.dirname(os.path.realpath(__file__)) + data = os.path.join(here, 'data', *paths) + return data + return _finder + + +@pytest.fixture(scope='session') +def collection_finder(data_finder): + def _finder(*paths): + return data_finder('collections', *paths) + return _finder + + @pytest.fixture(scope='session') def fixture_loader(fixture_finder): class FixtureLoader: diff --git a/tests/data/collections/briantist.one/v0.1.0/README.md b/tests/data/collections/briantist.one/v0.1.0/README.md new file mode 100644 index 0000000..4233617 --- /dev/null +++ b/tests/data/collections/briantist.one/v0.1.0/README.md @@ -0,0 +1,3 @@ +# Ansible Collection - briantist.whatever + +Documentation for the collection. diff --git a/tests/data/collections/briantist.one/v0.1.0/galaxy.yml b/tests/data/collections/briantist.one/v0.1.0/galaxy.yml new file mode 100644 index 0000000..7ddd218 --- /dev/null +++ b/tests/data/collections/briantist.one/v0.1.0/galaxy.yml @@ -0,0 +1,61 @@ +### REQUIRED +# The namespace of the collection. This can be a company/brand/organization or product namespace under which all +# content lives. May only contain alphanumeric lowercase characters and underscores. Namespaces cannot start with +# underscores or numbers and cannot contain consecutive underscores +namespace: briantist + +# The name of the collection. Has the same character restrictions as 'namespace' +name: one + +# The version of the collection. Must be compatible with semantic versioning +version: 0.1.0 + +# The path to the Markdown (.md) readme file. This path is relative to the root of the collection +readme: README.md + +# A list of the collection's content authors. Can be just the name or in the format 'Full Name (url) +# @nicks:irc/im.site#channel' +authors: +- your name + + +### OPTIONAL but strongly recommended +# A short summary description of the collection +description: your collection description + +# Either a single license or a list of licenses for content inside of a collection. Ansible Galaxy currently only +# accepts L(SPDX,https://spdx.org/licenses/) licenses. This key is mutually exclusive with 'license_file' +license: +- GPL-2.0-or-later + +# The path to the license file for the collection. This path is relative to the root of the collection. This key is +# mutually exclusive with 'license' +license_file: '' + +# A list of tags you want to associate with the collection for indexing/searching. A tag name has the same character +# requirements as 'namespace' and 'name' +tags: [] + +# Collections that this collection requires to be installed for it to be usable. The key of the dict is the +# collection label 'namespace.name'. The value is a version range +# L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version +# range specifiers can be set and are separated by ',' +dependencies: {} + +# The URL of the originating SCM repository +repository: http://example.com/repository + +# The URL to any online docs +documentation: http://docs.example.com + +# The URL to the homepage of the collection/project +homepage: http://example.com + +# The URL to the collection issue tracker +issues: http://example.com/issue/tracker + +# A list of file glob-like patterns used to filter any files or directories that should not be included in the build +# artifact. A pattern is matched from the relative path of the file or directory of the collection directory. This +# uses 'fnmatch' to match the files or directories. Some directories and files like 'galaxy.yml', '*.pyc', '*.retry', +# and '.git' are always filtered +build_ignore: [] diff --git a/tests/data/collections/briantist.one/v0.1.0/meta/runtime.yml b/tests/data/collections/briantist.one/v0.1.0/meta/runtime.yml new file mode 100644 index 0000000..89a0a2b --- /dev/null +++ b/tests/data/collections/briantist.one/v0.1.0/meta/runtime.yml @@ -0,0 +1,2 @@ +--- +requires_ansible: '>=2.11' diff --git a/tests/data/collections/briantist.one/v0.1.0/plugins/README.md b/tests/data/collections/briantist.one/v0.1.0/plugins/README.md new file mode 100644 index 0000000..29aa319 --- /dev/null +++ b/tests/data/collections/briantist.one/v0.1.0/plugins/README.md @@ -0,0 +1,31 @@ +# Collections Plugins Directory + +This directory can be used to ship various plugins inside an Ansible collection. Each plugin is placed in a folder that +is named after the type of plugin it is in. It can also include the `module_utils` and `modules` directory that +would contain module utils and modules respectively. + +Here is an example directory of the majority of plugins currently supported by Ansible: + +``` +└── plugins + ├── action + ├── become + ├── cache + ├── callback + ├── cliconf + ├── connection + ├── filter + ├── httpapi + ├── inventory + ├── lookup + ├── module_utils + ├── modules + ├── netconf + ├── shell + ├── strategy + ├── terminal + ├── test + └── vars +``` + +A full list of plugin types can be found at [Working With Plugins](https://docs.ansible.com/ansible-core/2.13/plugins/plugins.html). diff --git a/tests/data/collections/briantist.one/v0.2.0/README.md b/tests/data/collections/briantist.one/v0.2.0/README.md new file mode 100644 index 0000000..4233617 --- /dev/null +++ b/tests/data/collections/briantist.one/v0.2.0/README.md @@ -0,0 +1,3 @@ +# Ansible Collection - briantist.whatever + +Documentation for the collection. diff --git a/tests/data/collections/briantist.one/v0.2.0/galaxy.yml b/tests/data/collections/briantist.one/v0.2.0/galaxy.yml new file mode 100644 index 0000000..1cf7f74 --- /dev/null +++ b/tests/data/collections/briantist.one/v0.2.0/galaxy.yml @@ -0,0 +1,61 @@ +### REQUIRED +# The namespace of the collection. This can be a company/brand/organization or product namespace under which all +# content lives. May only contain alphanumeric lowercase characters and underscores. Namespaces cannot start with +# underscores or numbers and cannot contain consecutive underscores +namespace: briantist + +# The name of the collection. Has the same character restrictions as 'namespace' +name: one + +# The version of the collection. Must be compatible with semantic versioning +version: 0.2.0 + +# The path to the Markdown (.md) readme file. This path is relative to the root of the collection +readme: README.md + +# A list of the collection's content authors. Can be just the name or in the format 'Full Name (url) +# @nicks:irc/im.site#channel' +authors: +- your name + + +### OPTIONAL but strongly recommended +# A short summary description of the collection +description: your collection description + +# Either a single license or a list of licenses for content inside of a collection. Ansible Galaxy currently only +# accepts L(SPDX,https://spdx.org/licenses/) licenses. This key is mutually exclusive with 'license_file' +license: +- GPL-2.0-or-later + +# The path to the license file for the collection. This path is relative to the root of the collection. This key is +# mutually exclusive with 'license' +license_file: '' + +# A list of tags you want to associate with the collection for indexing/searching. A tag name has the same character +# requirements as 'namespace' and 'name' +tags: [] + +# Collections that this collection requires to be installed for it to be usable. The key of the dict is the +# collection label 'namespace.name'. The value is a version range +# L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version +# range specifiers can be set and are separated by ',' +dependencies: {} + +# The URL of the originating SCM repository +repository: http://example.com/repository + +# The URL to any online docs +documentation: http://docs.example.com + +# The URL to the homepage of the collection/project +homepage: http://example.com + +# The URL to the collection issue tracker +issues: http://example.com/issue/tracker + +# A list of file glob-like patterns used to filter any files or directories that should not be included in the build +# artifact. A pattern is matched from the relative path of the file or directory of the collection directory. This +# uses 'fnmatch' to match the files or directories. Some directories and files like 'galaxy.yml', '*.pyc', '*.retry', +# and '.git' are always filtered +build_ignore: [] diff --git a/tests/data/collections/briantist.one/v0.2.0/meta/runtime.yml b/tests/data/collections/briantist.one/v0.2.0/meta/runtime.yml new file mode 100644 index 0000000..89a0a2b --- /dev/null +++ b/tests/data/collections/briantist.one/v0.2.0/meta/runtime.yml @@ -0,0 +1,2 @@ +--- +requires_ansible: '>=2.11' diff --git a/tests/data/collections/briantist.one/v0.2.0/plugins/README.md b/tests/data/collections/briantist.one/v0.2.0/plugins/README.md new file mode 100644 index 0000000..29aa319 --- /dev/null +++ b/tests/data/collections/briantist.one/v0.2.0/plugins/README.md @@ -0,0 +1,31 @@ +# Collections Plugins Directory + +This directory can be used to ship various plugins inside an Ansible collection. Each plugin is placed in a folder that +is named after the type of plugin it is in. It can also include the `module_utils` and `modules` directory that +would contain module utils and modules respectively. + +Here is an example directory of the majority of plugins currently supported by Ansible: + +``` +└── plugins + ├── action + ├── become + ├── cache + ├── callback + ├── cliconf + ├── connection + ├── filter + ├── httpapi + ├── inventory + ├── lookup + ├── module_utils + ├── modules + ├── netconf + ├── shell + ├── strategy + ├── terminal + ├── test + └── vars +``` + +A full list of plugin types can be found at [Working With Plugins](https://docs.ansible.com/ansible-core/2.13/plugins/plugins.html). diff --git a/tests/data/collections/briantist.two/v1.1.0/README.md b/tests/data/collections/briantist.two/v1.1.0/README.md new file mode 100644 index 0000000..4233617 --- /dev/null +++ b/tests/data/collections/briantist.two/v1.1.0/README.md @@ -0,0 +1,3 @@ +# Ansible Collection - briantist.whatever + +Documentation for the collection. diff --git a/tests/data/collections/briantist.two/v1.1.0/galaxy.yml b/tests/data/collections/briantist.two/v1.1.0/galaxy.yml new file mode 100644 index 0000000..c7fd297 --- /dev/null +++ b/tests/data/collections/briantist.two/v1.1.0/galaxy.yml @@ -0,0 +1,61 @@ +### REQUIRED +# The namespace of the collection. This can be a company/brand/organization or product namespace under which all +# content lives. May only contain alphanumeric lowercase characters and underscores. Namespaces cannot start with +# underscores or numbers and cannot contain consecutive underscores +namespace: briantist + +# The name of the collection. Has the same character restrictions as 'namespace' +name: two + +# The version of the collection. Must be compatible with semantic versioning +version: 1.1.0 + +# The path to the Markdown (.md) readme file. This path is relative to the root of the collection +readme: README.md + +# A list of the collection's content authors. Can be just the name or in the format 'Full Name (url) +# @nicks:irc/im.site#channel' +authors: +- your name + + +### OPTIONAL but strongly recommended +# A short summary description of the collection +description: your collection description + +# Either a single license or a list of licenses for content inside of a collection. Ansible Galaxy currently only +# accepts L(SPDX,https://spdx.org/licenses/) licenses. This key is mutually exclusive with 'license_file' +license: +- GPL-2.0-or-later + +# The path to the license file for the collection. This path is relative to the root of the collection. This key is +# mutually exclusive with 'license' +license_file: '' + +# A list of tags you want to associate with the collection for indexing/searching. A tag name has the same character +# requirements as 'namespace' and 'name' +tags: [] + +# Collections that this collection requires to be installed for it to be usable. The key of the dict is the +# collection label 'namespace.name'. The value is a version range +# L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version +# range specifiers can be set and are separated by ',' +dependencies: {} + +# The URL of the originating SCM repository +repository: http://example.com/repository + +# The URL to any online docs +documentation: http://docs.example.com + +# The URL to the homepage of the collection/project +homepage: http://example.com + +# The URL to the collection issue tracker +issues: http://example.com/issue/tracker + +# A list of file glob-like patterns used to filter any files or directories that should not be included in the build +# artifact. A pattern is matched from the relative path of the file or directory of the collection directory. This +# uses 'fnmatch' to match the files or directories. Some directories and files like 'galaxy.yml', '*.pyc', '*.retry', +# and '.git' are always filtered +build_ignore: [] diff --git a/tests/data/collections/briantist.two/v1.1.0/meta/runtime.yml b/tests/data/collections/briantist.two/v1.1.0/meta/runtime.yml new file mode 100644 index 0000000..89a0a2b --- /dev/null +++ b/tests/data/collections/briantist.two/v1.1.0/meta/runtime.yml @@ -0,0 +1,2 @@ +--- +requires_ansible: '>=2.11' diff --git a/tests/data/collections/briantist.two/v1.1.0/plugins/README.md b/tests/data/collections/briantist.two/v1.1.0/plugins/README.md new file mode 100644 index 0000000..29aa319 --- /dev/null +++ b/tests/data/collections/briantist.two/v1.1.0/plugins/README.md @@ -0,0 +1,31 @@ +# Collections Plugins Directory + +This directory can be used to ship various plugins inside an Ansible collection. Each plugin is placed in a folder that +is named after the type of plugin it is in. It can also include the `module_utils` and `modules` directory that +would contain module utils and modules respectively. + +Here is an example directory of the majority of plugins currently supported by Ansible: + +``` +└── plugins + ├── action + ├── become + ├── cache + ├── callback + ├── cliconf + ├── connection + ├── filter + ├── httpapi + ├── inventory + ├── lookup + ├── module_utils + ├── modules + ├── netconf + ├── shell + ├── strategy + ├── terminal + ├── test + └── vars +``` + +A full list of plugin types can be found at [Working With Plugins](https://docs.ansible.com/ansible-core/2.13/plugins/plugins.html). diff --git a/tests/data/collections/briantist.two/v2.2.0/README.md b/tests/data/collections/briantist.two/v2.2.0/README.md new file mode 100644 index 0000000..4233617 --- /dev/null +++ b/tests/data/collections/briantist.two/v2.2.0/README.md @@ -0,0 +1,3 @@ +# Ansible Collection - briantist.whatever + +Documentation for the collection. diff --git a/tests/data/collections/briantist.two/v2.2.0/galaxy.yml b/tests/data/collections/briantist.two/v2.2.0/galaxy.yml new file mode 100644 index 0000000..33e3067 --- /dev/null +++ b/tests/data/collections/briantist.two/v2.2.0/galaxy.yml @@ -0,0 +1,61 @@ +### REQUIRED +# The namespace of the collection. This can be a company/brand/organization or product namespace under which all +# content lives. May only contain alphanumeric lowercase characters and underscores. Namespaces cannot start with +# underscores or numbers and cannot contain consecutive underscores +namespace: briantist + +# The name of the collection. Has the same character restrictions as 'namespace' +name: two + +# The version of the collection. Must be compatible with semantic versioning +version: 2.2.0 + +# The path to the Markdown (.md) readme file. This path is relative to the root of the collection +readme: README.md + +# A list of the collection's content authors. Can be just the name or in the format 'Full Name (url) +# @nicks:irc/im.site#channel' +authors: +- your name + + +### OPTIONAL but strongly recommended +# A short summary description of the collection +description: your collection description + +# Either a single license or a list of licenses for content inside of a collection. Ansible Galaxy currently only +# accepts L(SPDX,https://spdx.org/licenses/) licenses. This key is mutually exclusive with 'license_file' +license: +- GPL-2.0-or-later + +# The path to the license file for the collection. This path is relative to the root of the collection. This key is +# mutually exclusive with 'license' +license_file: '' + +# A list of tags you want to associate with the collection for indexing/searching. A tag name has the same character +# requirements as 'namespace' and 'name' +tags: [] + +# Collections that this collection requires to be installed for it to be usable. The key of the dict is the +# collection label 'namespace.name'. The value is a version range +# L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version +# range specifiers can be set and are separated by ',' +dependencies: {} + +# The URL of the originating SCM repository +repository: http://example.com/repository + +# The URL to any online docs +documentation: http://docs.example.com + +# The URL to the homepage of the collection/project +homepage: http://example.com + +# The URL to the collection issue tracker +issues: http://example.com/issue/tracker + +# A list of file glob-like patterns used to filter any files or directories that should not be included in the build +# artifact. A pattern is matched from the relative path of the file or directory of the collection directory. This +# uses 'fnmatch' to match the files or directories. Some directories and files like 'galaxy.yml', '*.pyc', '*.retry', +# and '.git' are always filtered +build_ignore: [] diff --git a/tests/data/collections/briantist.two/v2.2.0/meta/runtime.yml b/tests/data/collections/briantist.two/v2.2.0/meta/runtime.yml new file mode 100644 index 0000000..89a0a2b --- /dev/null +++ b/tests/data/collections/briantist.two/v2.2.0/meta/runtime.yml @@ -0,0 +1,2 @@ +--- +requires_ansible: '>=2.11' diff --git a/tests/data/collections/briantist.two/v2.2.0/plugins/README.md b/tests/data/collections/briantist.two/v2.2.0/plugins/README.md new file mode 100644 index 0000000..29aa319 --- /dev/null +++ b/tests/data/collections/briantist.two/v2.2.0/plugins/README.md @@ -0,0 +1,31 @@ +# Collections Plugins Directory + +This directory can be used to ship various plugins inside an Ansible collection. Each plugin is placed in a folder that +is named after the type of plugin it is in. It can also include the `module_utils` and `modules` directory that +would contain module utils and modules respectively. + +Here is an example directory of the majority of plugins currently supported by Ansible: + +``` +└── plugins + ├── action + ├── become + ├── cache + ├── callback + ├── cliconf + ├── connection + ├── filter + ├── httpapi + ├── inventory + ├── lookup + ├── module_utils + ├── modules + ├── netconf + ├── shell + ├── strategy + ├── terminal + ├── test + └── vars +``` + +A full list of plugin types can be found at [Working With Plugins](https://docs.ansible.com/ansible-core/2.13/plugins/plugins.html). diff --git a/tests/data/runtime/.gitignore b/tests/data/runtime/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/tests/data/runtime/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 58c2b17..b4497a3 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -4,13 +4,52 @@ from urllib3.util.retry import Retry from requests.adapters import HTTPAdapter +from pathlib import Path from artifactory import ArtifactoryPath, RepositoryLocal from dohq_artifactory import User +import ansible_runner -@pytest.fixture(autouse=True, scope='session') -def broken(): - pytest.skip('Integration tests are incomplete and disabled.') +from galactory import create_app + +# @pytest.fixture(autouse=True, scope='session') +# def broken(): +# pytest.skip('Integration tests are incomplete and disabled.') + +@pytest.fixture +def app(repository, artifactory_user): + app = create_app() + app.config.update({ + 'ARTIFACTORY_PATH': repository, + 'ARTIFACTORY_API_KEY': artifactory_user.api_key.get(), + }) + yield app + + +@pytest.fixture +def app_request_context(app): + with app.app_context(), app.test_request_context(): + yield + + +@pytest.fixture +def client(app): + return app.test_client() + + +@pytest.fixture(scope="session") +def test_collections(collection_finder, data_finder): + collections = Path(collection_finder()) + runtime = Path(data_finder('runtime')) + for collection in collections.iterdir(): + for version in collection.iterdir(): + out, err, rc = ansible_runner.run_command( + executable_cmd='ansible-galaxy', + cmdline_args=['collection', 'build', '--force', '--output-path', str(runtime.absolute()), str(version.absolute())] + ) + assert rc == 0 , f"stdout: {out}\nstderr: {err}" + + return [d for d in runtime.rglob('*.tar.gz')] @pytest.fixture(scope='session') @@ -67,5 +106,5 @@ def artifactory_generic_repository(artifactory_authed): @pytest.fixture -def repository(artifactory): - return ArtifactoryPath(f"{artifactory}/repo/subpath") +def repository(artifactory_generic_repository): + return artifactory_generic_repository.path / 'repo' / 'subpath' diff --git a/tests/integration/test_me.py b/tests/integration/test_me.py index 89c1f90..e3c77b7 100644 --- a/tests/integration/test_me.py +++ b/tests/integration/test_me.py @@ -1,9 +1,34 @@ +from threading import Thread + +import pytest from dohq_artifactory import User from artifactory import ArtifactoryPath +import ansible_runner + import inspect -def test(artifactory_generic_repository): + +@pytest.fixture +def running_app(app): + running = Thread(target=lambda: app.run('0.0.0.0', 54321, threaded=True), daemon=True) + running.start() + yield 'http://localhost:54321' + running. + +def test(test_collections, app): + assert len(test_collections) == 4, f"{test_collections}" # a = ArtifactoryPath(artifactory) #, auth=('admin', 'password')) + repository = ArtifactoryPath() + + + + for c in test_collections: + out, err, rc = ansible_runner.run_command( + executable_cmd='ansible-galaxy', + cmdline_args=['collection', '-s', 'publish'] + ) + # response = client.post('/api/v2/collections/', ) + # data = response.json - raise Exception(inspect.getmembers(artifactory_generic_repository)) + # raise Exception(inspect.getmembers(artifactory_generic_repository)) diff --git a/tests/requirements.txt b/tests/requirements.txt index 935616c..d485152 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,7 +1,7 @@ -r ../requirements.txt pytest>=7.1,<8 pytest-cov -# pytest-docker-compose +pytest-docker-compose coverage -# ansible-runner -# ansible-core +ansible-runner +ansible-core From 8aecb93b044235b5c785944a3a56a0c712bdd143 Mon Sep 17 00:00:00 2001 From: Brian Scholer <1260690+briantist@users.noreply.github.com> Date: Sat, 8 Oct 2022 21:53:02 -0400 Subject: [PATCH 2/6] more wip --- tests/integration/conftest.py | 6 +++- tests/integration/test_me.py | 60 ++++++++++++++++++++++++++++------- 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index b4497a3..3d2b4bb 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -22,6 +22,9 @@ def app(repository, artifactory_user): app.config.update({ 'ARTIFACTORY_PATH': repository, 'ARTIFACTORY_API_KEY': artifactory_user.api_key.get(), + 'PUBLISH_SKIP_CONFIGURED_KEY': False, + 'USE_GALAXY_KEY': True, + 'PREFER_CONFIGURED_KEY': True, }) yield app @@ -107,4 +110,5 @@ def artifactory_generic_repository(artifactory_authed): @pytest.fixture def repository(artifactory_generic_repository): - return artifactory_generic_repository.path / 'repo' / 'subpath' + # https://github.com/devopshq/artifactory/issues/386 + return ArtifactoryPath(str(artifactory_generic_repository.path)) / 'repo' / 'subpath' diff --git a/tests/integration/test_me.py b/tests/integration/test_me.py index e3c77b7..19024ec 100644 --- a/tests/integration/test_me.py +++ b/tests/integration/test_me.py @@ -4,19 +4,37 @@ from dohq_artifactory import User from artifactory import ArtifactoryPath +from base64io import Base64IO + +from flask import request +import requests + import ansible_runner import inspect -@pytest.fixture -def running_app(app): - running = Thread(target=lambda: app.run('0.0.0.0', 54321, threaded=True), daemon=True) - running.start() - yield 'http://localhost:54321' - running. +# @pytest.fixture +# def running_app(app): +# @app.route('/_shutdown', methods=['DELETE']) +# def _shutdown(): +# f_shutdown = request.environ.get('werkzeug.server.shutdown') +# f_shutdown() +# return 'Exiting...' + +# listen = '0.0.0.0' +# port = 54321 +# host = 'localhost' +# url = f"http://{host}:{port}" +# shutdown = f"{url}/_shutdown" + +# running = Thread(target=lambda: app.run(listen, port, threaded=True), daemon=True) +# running.start() +# yield url +# requests.delete(shutdown) + -def test(test_collections, app): +def test(test_collections, app, client): assert len(test_collections) == 4, f"{test_collections}" # a = ArtifactoryPath(artifactory) #, auth=('admin', 'password')) repository = ArtifactoryPath() @@ -24,11 +42,29 @@ def test(test_collections, app): for c in test_collections: - out, err, rc = ansible_runner.run_command( - executable_cmd='ansible-galaxy', - cmdline_args=['collection', '-s', 'publish'] - ) - # response = client.post('/api/v2/collections/', ) + # out, err, rc = ansible_runner.run_command( + # executable_cmd='ansible-galaxy', + # cmdline_args=['collection', '-s', running_app, 'publish', c] + # ) + import hashlib + + sha256sum = hashlib.sha256() + chunk_size = sha256sum.block_size + + from io import BytesIO + with c.open('rb') as h, BytesIO() as b: + with Base64IO(b) as b64: + for data in iter(lambda: h.read(chunk_size), b''): + sha256sum.update(data) + b64.write(data) + + b.seek(0) + response = client.post( + '/api/v2/collections/', + data=dict(sha256=sha256sum.hexdigest(), file=(b, c.name)), + ) + + assert response.status_code == 200, response.text # data = response.json # raise Exception(inspect.getmembers(artifactory_generic_repository)) From e2e209b5861031e57c49ebacfdbb0fe9f5e343f2 Mon Sep 17 00:00:00 2001 From: Brian Scholer <1260690+briantist@users.noreply.github.com> Date: Sun, 9 Oct 2022 18:15:14 -0400 Subject: [PATCH 3/6] ci tweaks --- .github/workflows/test.yml | 13 ++++++++++++- pyproject.toml | 2 +- tests/artifactory/docker-compose.yml | 2 +- tests/integration/conftest.py | 1 + 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5beda88..4137a03 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,19 +10,30 @@ on: jobs: test: + name: test [${{ matrix.type }}-py${{ matrix.python }}${{ matrix.type == 'integration' && format('-Ⓐ{0}', matrix.artifactory) || ''] permissions: contents: read runs-on: ubuntu-latest strategy: fail-fast: false matrix: + type: + - unit + - integration + artifactory: + - latest + - 6.23.42 python: - '3.8' - '3.9' # - '3.10' # tests totally broken.. mocks don't seem to work # - '3.11-dev' # test broken: AttributeError: module 'pathlib' has no attribute '_Accessor' + exclude: + - type: unit + artifactory: latest env: PYTEST_ADDOPTS: '--color=yes' + GALACTORY_TEST_ARTIFACTORY_TAG: ${{ matrix.artifactory }} outputs: relver: ${{ steps.setvars.outputs.relver }} branch: ${{ steps.setvars.outputs.branch }} @@ -39,7 +50,7 @@ jobs: run: pip install -r requirements.txt - name: Pytest - run: pytest tests/ + run: pytest tests/${{ matrix.type }} - name: Set vars id: setvars diff --git a/pyproject.toml b/pyproject.toml index 38f69ed..1978b6c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ exclude = ["changelogs"] [tool.pytest.ini_options] minversion = "7.1" -addopts = "--cov --cov-report=xml --docker-compose=artifactory/docker-compose.yml --use-running-containers" +addopts = "--cov --cov-report=xml --docker-compose=tests/artifactory/docker-compose.yml --docker-compose-remove-volumes --use-running-containers" # addopts = "-ra -q" testpaths = [ "unit", diff --git a/tests/artifactory/docker-compose.yml b/tests/artifactory/docker-compose.yml index 611ec4a..1e17f8a 100644 --- a/tests/artifactory/docker-compose.yml +++ b/tests/artifactory/docker-compose.yml @@ -4,7 +4,7 @@ version: '3' services: artifactory: container_name: artifactory - image: docker.bintray.io/jfrog/artifactory-oss:latest + image: docker.bintray.io/jfrog/artifactory-oss:${GALACTORY_TEST_ARTIFACTORY_TAG:-latest} ports: - 8081:8081 - 8082:8082 diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 3d2b4bb..ca9fd13 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -93,6 +93,7 @@ def artifactory_generic_repository(artifactory_authed): name = 'example-repo-local' # repo = artifactory_authed.find_repository_local(name) # ^ can't use this, requires pro license 🙄 + # https://github.com/devopshq/artifactory/issues/356 for repo in artifactory_authed.get_repositories(): if repo.name == name: From 48080ef28e647347a6bb7c7c7f6e53869f68865b Mon Sep 17 00:00:00 2001 From: Brian Scholer <1260690+briantist@users.noreply.github.com> Date: Sun, 9 Oct 2022 18:16:03 -0400 Subject: [PATCH 4/6] closing --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4137a03..7b49d69 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ on: jobs: test: - name: test [${{ matrix.type }}-py${{ matrix.python }}${{ matrix.type == 'integration' && format('-Ⓐ{0}', matrix.artifactory) || ''] + name: test [${{ matrix.type }}-py${{ matrix.python }}${{ matrix.type == 'integration' && format('-Ⓐ{0}', matrix.artifactory) || '' }}] permissions: contents: read runs-on: ubuntu-latest From 8b9a8e02ef607533ba12a51997604f9d3d34e895 Mon Sep 17 00:00:00 2001 From: Brian Scholer <1260690+briantist@users.noreply.github.com> Date: Sun, 9 Oct 2022 18:28:46 -0400 Subject: [PATCH 5/6] pullup --- .github/workflows/test.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7b49d69..c227e2e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -49,6 +49,11 @@ jobs: working-directory: tests run: pip install -r requirements.txt + - name: Pull + if: matrix.type == 'integration' + working-directory: tests/artifactory + run: docker-compose pull + - name: Pytest run: pytest tests/${{ matrix.type }} From cc91727bf5f43d3c1a2efbffc5e8b59f1729dd47 Mon Sep 17 00:00:00 2001 From: Brian Scholer <1260690+briantist@users.noreply.github.com> Date: Sun, 9 Oct 2022 18:32:21 -0400 Subject: [PATCH 6/6] v2? --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c227e2e..61bf8fb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -52,7 +52,7 @@ jobs: - name: Pull if: matrix.type == 'integration' working-directory: tests/artifactory - run: docker-compose pull + run: docker compose pull - name: Pytest run: pytest tests/${{ matrix.type }}