{"id":34837308,"url":"https://github.com/arenadata/adcm_pytest_plugin","last_synced_at":"2025-12-25T16:10:41.204Z","repository":{"id":37374639,"uuid":"351441353","full_name":"arenadata/adcm_pytest_plugin","owner":"arenadata","description":"The pytest plugin including a set of common tools for ADCM testing","archived":false,"fork":false,"pushed_at":"2023-01-26T06:53:54.000Z","size":162,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":16,"default_branch":"master","last_synced_at":"2023-03-04T04:49:52.326Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arenadata.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null}},"created_at":"2021-03-25T13:11:30.000Z","updated_at":"2023-02-15T19:07:20.000Z","dependencies_parsed_at":"2023-02-14T07:01:00.457Z","dependency_job_id":null,"html_url":"https://github.com/arenadata/adcm_pytest_plugin","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"purl":"pkg:github/arenadata/adcm_pytest_plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arenadata%2Fadcm_pytest_plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arenadata%2Fadcm_pytest_plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arenadata%2Fadcm_pytest_plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arenadata%2Fadcm_pytest_plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arenadata","download_url":"https://codeload.github.com/arenadata/adcm_pytest_plugin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arenadata%2Fadcm_pytest_plugin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28032407,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-25T02:00:05.988Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-25T16:09:01.257Z","updated_at":"2025-12-25T16:10:41.197Z","avatar_url":"https://github.com/arenadata.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ADCM Pytest Plugin\n\n## Overview\n\nThe `pytest` plugin which includes a set of common tools for ADCM tests.\n\n- [Requirements](#requirements)\n- [Installation](#installation)\n- [Fixtures](#fixtures)\n- [Functions and methods](#functions-and-methods)\n- [Basic usage](#basic-usage)\n- [Command line options](#command-line-options)\n- [Writing tests for plugin](#writing-tests-for-plugin)\n- [How to run unit tests for plugin](#how-to-run-unit-tests-for-plugin)\n- [Pre-commit hook](#pre-commit-hook)\n\n\n## Requirements\n\n- `python (3.7+)`\n- `pip`\n\n## Installation\n\n```shell\npip install adcm_pytest_plugin\n```\n\n## Fixtures\n\n### A word about naming convention\n\nThe most of the fixture names introduced by this plugin has a suffix which indicates fixture scope. The following list\nof suffixes are in use:\n\n- `_fs` - function scope\n- `_ms` - module scope\n- `_ss` - session scope\n\nHere in after the name of any fixture used without scope suffix unless stated.\n\nE.g. `adcm` which expands to:\n\n- `adcm_fs`\n- `adcm_ms`\n- `adcm_ss`\n\n### List of fixtures\n\n- `image`\u003csup\u003esession scope only\u003c/sup\u003e - creates initialized ADCM image for further usage in tests\n- `cmd_opts`\u003csup\u003esession scope only\u003c/sup\u003e - fixture aimed to access values of cmd_line options\n- `adcm` - returns instance of ADCM wrapper (ADCM API and Docker container)\n- `sdk_client` - returns ADCMClient instance bounded to ADCM instance\n- `adcm_api_credentials` - returns dict with default ADCM credentials\n\n## Functions and methods\n\n`utils.py` contains a lot of methods useful for testing. See docstrings for more info.\n\n## Basic usage\n\nAssume running from `adcm_test`.\n\n\u003e `conftest.py`\n\n```python\nimport os\n\nimport pytest\n\nfrom adcm_pytest_plugin.utils import random_string\n\nfrom adcm_client.objects import Bundle, Cluster, ADCMClient\n\n\n@pytest.fixture()\ndef dummy_bundle(sdk_client_fs: ADCMClient) -\u003e Bundle:\n    \"\"\"\n    Uploads bundle from dummy_bundle folder \n    \"\"\"\n    bundle = sdk_client_fs.upload_from_fs(\n        os.path.dirname(os.path.abspath(__file__)) + \"/dummy_bundle\"\n    )\n\n    return bundle\n\n\n@pytest.fixture()\ndef dummy_cluster(dummy_bundle: Bundle) -\u003e Cluster:\n    \"\"\"\n    Initialize cluster (based on the cluster prototype)\n    \"\"\"\n\n    cluster = dummy_bundle.cluster_prototype().cluster_create(\n        name=f\"test_cluster_{random_string()}\"\n    )\n\n    return cluster\n\n```\n\n\u003e `dummy_bundle/config.yaml` see [ADCM docs](https://docs.arenadata.io/adcm/sdk/config.html) for details\n\n```yaml\n---\n- name: dummy_cluster\n  type: cluster\n  version: '1.0'\n  config:\n    - name: some_boolean_param\n      type: boolean\n      required: true\n      default: false\n  actions:\n    dummy_job:\n      description: \"Will fail if config param is false\"\n      script: cluster_action.yaml\n      script_type: ansible\n      type: job\n      states:\n        available:\n          - created\n```\n\n\u003e `dummy_bundle/cluster_action.yaml`\n\n```yaml\n---\n- name: fail_if_some_boolean_param_is_false\n  hosts: localhost\n  tasks:\n    - name: Assert bool value\n      assert:\n        that:\n          - cluster.config.some_boolean_param == true\n```\n\n\u003e `test_cluster_action.py`\n\n```python\nfrom adcm_pytest_plugin.steps.actions import (\n    run_cluster_action_and_assert_result,\n)\nfrom adcm_client.objects import Cluster\n\n\ndef test_cluster_action(dummy_cluster: Cluster):\n    \"\"\"Test cluster action run and result\"\"\"\n\n    run_cluster_action_and_assert_result(\n        cluster=dummy_cluster, action=\"dummy_job\", status=\"failed\"\n    )\n\n    dummy_cluster.config_set_diff({\"some_boolean_param\": True})\n\n    run_cluster_action_and_assert_result(\n        cluster=dummy_cluster, action=\"dummy_job\", status=\"success\"\n    )\n\n```\n\n**Then** run `pytest` with command line arguments described [below](#command-line-options).\n\n## Command line options\n\nList of available options:\n\n- ADCM image options\n    - [`--staticimage`](#--staticimage)\n    - [`--dontstop`](#--dontstop)\n    - [`--adcm-image`](#--adcm-image)\n    - [`--adcm-images`](#--adcm-images)\n    - [`--adcm-min-version`](#--adcm-min-version)\n    - [`--nopull`](#--nopull)\n- Misc\n    - [`--remote-executor-host`](#--remote-executor-host)\n    - [`--remote-docker`](#--remote-docker)\n    - [`--verbose-actions`](#--verbose-actions)\n    - [`--actions-report-dir`](#--actions-report-dir)\n\n---\n\n### ADCM image options\n\n#### `--staticimage`\n\n\u003e Use single ADCM docker image instead of initializing new one at the test session start\n\nProperty | Value\n---: | ---\nvalue | `any valid docker image name`\ndefault | `none`\nexample | `--staticimage arenadata/adcm:test or --staticimage some_repo/some_image:some_tag`\n\n#### `--dontstop`\n\n\u003e If passed then ADCM containers will remain running after tests\n\nProperty | Value\n---: | ---\nvalue | `none`\ndefault | `false`\n\n#### `--adcm-image`\n\n\u003e Exact name of ADCM docker image to run tests on\n\u003e\n\u003e Incompatible with [`--adcm-images`](#--adcm-images) and [`--adcm-min-version`](#--adcm-min-version)\n\nProperty | Value\n---: | ---\nvalue | `valid image name:tag`\ndefault | `arenadata/adcm:latest`\n\n#### `--adcm-images`\n\n\u003e Names of ADCM docker images to run tests on.\n\u003e Each image name should be passed as individual arg\n\u003e\n\u003e Incompatible with [`--adcm-image`](#--adcm-image) and [`--adcm-min-version`](#--adcm-min-version)\n\nProperty | Value\n---: | ---\nvalue | `valid image name:tag`\ndefault | `none`\nexample | `--adcm-images arenadata/adcm:2020.01.30.15 arenadata/adcm:2020.10.15.28`\n\n#### `--adcm-min-version`\n\n\u003e If passed then tests will be executed on all ADCM release images\n\u003e newer than version passed\n\u003e\n\u003e Incompatible with [`--adcm-images`](#--adcm-images) and [`--adcm-image`](#--adcm-image)\n\nProperty | Value\n---: | ---\nvalue | `string of ADCM version format`\ndefault | `none`\nexample | `--adcm-min-version 2020.01.30.15`\n\n#### `--nopull`\n\n\u003e If passed then no pull action will be performed on `docker run`\n\nProperty | Value\n---: | ---\nvalue | `none`\ndefault | `false`\n\n### Mics\n\n#### `--remote-executor-host`\n\n\u003e If passed then ADCM API will be initialized with external IP\n\u003e to allow incoming connections from any remote executor (ex. Selenoid)\n\u003e Tests will fail if remote host is unreachable.\n\u003e This option will be ignored if [`--remote-docker`](#--remote-docker) option is passed\n\nProperty | Value\n---: | ---\nvalue | `string with fqdn`\ndefault | `none`\n\n#### `--remote-docker`\n\n\u003e If passed then ADCM instances will be created on a remote host.\n\u003e Docker daemon should be running and be available with provided host:port\n\n\nProperty | Value\n---: | ---\nvalue | `string of host:port format`\ndefault | `none`\nexample | `--remote-docker '10.92.7.14:2375'`\n\n#### `--verbose-actions`\n\n\u003e If passed then ADCM actions will be started with 'verbose' checkbox selected.\n\u003e Applied only to action calls over adcm_client. \n\u003e Does not affect UI action calls in tests.\n\n\nProperty | Value\n---: | ---\nvalue | `none`\ndefault | `false`\n\n\n#### `--actions-report-dir`\n\n\u003e If passed then plugin will collect information about all actions calls made with run_action_*** wrappers\n\u003e and create summary report in the provided directory\n\n\nProperty | Value\n---: | ---\nvalue | `string with absolute or elative path to dir where actions report will be stored`\ndefault | `none`\nexample | `--actions-report-dir relative/path/to/dir` or `--actions-report-dir /absolute/path/to/dir`\n\n## Writing tests for plugin\n\nAt the moment, the project has a set of tests, which is located in the `./tests` directory. Current tests and tests that\nwill be written should be based on usage of the `tesdir` fixture from the `pytester` plugin. This approach allow tests\nto be run inside tests. Nested launch is important for us, since many functions and fixtures of the plugin depends on\nlaunch parameters (`pytest` command-line options)\n\nSource code of nested tests can be stored as:\n\n1. `.py` files in `./tests/_test_files` directory\n2. multiline string inside code of the test that will run nested test\n\n### Example 1.\n\nGiven that the code for a nested test is stored in the `test_some.py` file. To run such a test, you need to run the\nfollowing code:\n\n```python\ndef test_some_fixture(testdir):\n    testdir.copy_example(\"test_some.py\")\n    result = testdir.runpytest()\n    # This number determines the number of successful tests in the nested test\n    result.assert_outcomes(passed=1)\n```\n\n### Example 2.\n\nGiven that the code for a nested test is stored in multiline string. To run such a test, you need to run the following\ncode:\n\n```python\ndef test_some_fixture(testdir):\n    testdir.makepyfile(\n        \"\"\"\n        def test_some():\n          assert True\n        \"\"\"\n    )\n    result = testdir.runpytest()\n    # This number determines the number of successful tests in the nested test\n    result.assert_outcomes(passed=1)\n```\n\nYou can read more about writing tests for pytest plugins here\n- [Testing plugins](https://docs.pytest.org/en/stable/writing_plugins.html?highlight=plugin#testing-plugins)\n\n## How to run unit tests for plugin\n\nTo run plugin tests, you can execute this from your project root:\n\n```\npip install -e .\npip install -r tests/requirements.txt\ncd tests\npytest ./plugin --alluredir allure-result\n```\n\nTo open allure report, you can execute this:\n\n```\nallure serve allure-result\n```\n\n## Pre-commit hook\n\nWe are using black, pylint and pre-commit to care about code formating and linting.\n\nSo you have to install pre-commit hook before you do something with code.\n\n``` sh\npip install pre-commit # Or do it with your preffered way to install pip packages\npre-commit install\n```\n\nAfter this you will see invocation of black and pylint on every commit.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farenadata%2Fadcm_pytest_plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farenadata%2Fadcm_pytest_plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farenadata%2Fadcm_pytest_plugin/lists"}