From 3ea577b38455f21d1a5cca3d57723bd42e66c757 Mon Sep 17 00:00:00 2001 From: Yftach Herzog Date: Wed, 6 Dec 2023 15:49:06 +0200 Subject: [PATCH] test(RHTAPWATCH-643): Adding python tests to CI Signed-off-by: Yftach Herzog --- .github/workflows/test.yaml | 23 ++ Pipfile | 18 ++ Pipfile.lock | 198 ++++++++++++++++++ compose_generator/compose_generator.py | 1 + compose_generator/odcs_compose_generator.py | 4 +- .../odcs_configurations_generator.py | 1 + compose_generator/odcs_fetcher.py | 2 + compose_generator/odcs_requester.py | 2 + compose_generator/protocols.py | 2 + format.sh | 11 + tests/test_static_check.py | 25 +++ 11 files changed, 285 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/test.yaml create mode 100644 Pipfile create mode 100644 Pipfile.lock create mode 100755 format.sh create mode 100644 tests/test_static_check.py diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..af4b00c --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,23 @@ +name: tests + +on: + pull_request: + branches: [ main ] +jobs: + test: + permissions: + checks: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v1 + with: + python-version: 3.11 + - name: Install pipenv + run: pip install pipenv==2023.7.23 + - name: Create virtualenv + run: pipenv sync + - name: Run tests + run: | + pipenv run pytest tests diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..af8f602 --- /dev/null +++ b/Pipfile @@ -0,0 +1,18 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +pytest = "*" +black = "*" +mypy = "*" +pylint = "*" +isort = "*" + +[dev-packages] + +[requires] +python_version = "3.11" + +[scripts] diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..b5a4018 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,198 @@ +{ + "_meta": { + "hash": { + "sha256": "f20cbe721a5c209098a9ee44fc8aa3abefcf267249b49b400f193cd5dba62796" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.11" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "astroid": { + "hashes": [ + "sha256:7d5895c9825e18079c5aeac0572bc2e4c83205c95d416e0b4fee8bc361d2d9ca", + "sha256:86b0bb7d7da0be1a7c4aedb7974e391b32d4ed89e33de6ed6902b4b15c97577e" + ], + "markers": "python_full_version >= '3.8.0'", + "version": "==3.0.1" + }, + "black": { + "hashes": [ + "sha256:250d7e60f323fcfc8ea6c800d5eba12f7967400eb6c2d21ae85ad31c204fb1f4", + "sha256:2a9acad1451632021ee0d146c8765782a0c3846e0e0ea46659d7c4f89d9b212b", + "sha256:412f56bab20ac85927f3a959230331de5614aecda1ede14b373083f62ec24e6f", + "sha256:421f3e44aa67138ab1b9bfbc22ee3780b22fa5b291e4db8ab7eee95200726b07", + "sha256:45aa1d4675964946e53ab81aeec7a37613c1cb71647b5394779e6efb79d6d187", + "sha256:4c44b7211a3a0570cc097e81135faa5f261264f4dfaa22bd5ee2875a4e773bd6", + "sha256:4c68855825ff432d197229846f971bc4d6666ce90492e5b02013bcaca4d9ab05", + "sha256:5133f5507007ba08d8b7b263c7aa0f931af5ba88a29beacc4b2dc23fcefe9c06", + "sha256:54caaa703227c6e0c87b76326d0862184729a69b73d3b7305b6288e1d830067e", + "sha256:58e5f4d08a205b11800332920e285bd25e1a75c54953e05502052738fe16b3b5", + "sha256:698c1e0d5c43354ec5d6f4d914d0d553a9ada56c85415700b81dc90125aac244", + "sha256:6c1cac07e64433f646a9a838cdc00c9768b3c362805afc3fce341af0e6a9ae9f", + "sha256:760415ccc20f9e8747084169110ef75d545f3b0932ee21368f63ac0fee86b221", + "sha256:7f622b6822f02bfaf2a5cd31fdb7cd86fcf33dab6ced5185c35f5db98260b055", + "sha256:cf57719e581cfd48c4efe28543fea3d139c6b6f1238b3f0102a9c73992cbb479", + "sha256:d136ef5b418c81660ad847efe0e55c58c8208b77a57a28a503a5f345ccf01394", + "sha256:dbea0bb8575c6b6303cc65017b46351dc5953eea5c0a59d7b7e3a2d2f433a911", + "sha256:fc7f6a44d52747e65a02558e1d807c82df1d66ffa80a601862040a43ec2e3142" + ], + "index": "pypi", + "version": "==23.11.0" + }, + "click": { + "hashes": [ + "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" + ], + "markers": "python_version >= '3.7'", + "version": "==8.1.7" + }, + "dill": { + "hashes": [ + "sha256:76b122c08ef4ce2eedcd4d1abd8e641114bfc6c2867f49f3c41facf65bf19f5e", + "sha256:cc1c8b182eb3013e24bd475ff2e9295af86c1a38eb1aff128dac8962a9ce3c03" + ], + "markers": "python_version >= '3.11'", + "version": "==0.3.7" + }, + "iniconfig": { + "hashes": [ + "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", + "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" + ], + "markers": "python_version >= '3.7'", + "version": "==2.0.0" + }, + "isort": { + "hashes": [ + "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504", + "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6" + ], + "index": "pypi", + "version": "==5.12.0" + }, + "mccabe": { + "hashes": [ + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" + ], + "markers": "python_version >= '3.6'", + "version": "==0.7.0" + }, + "mypy": { + "hashes": [ + "sha256:12cce78e329838d70a204293e7b29af9faa3ab14899aec397798a4b41be7f340", + "sha256:1484b8fa2c10adf4474f016e09d7a159602f3239075c7bf9f1627f5acf40ad49", + "sha256:204e0d6de5fd2317394a4eff62065614c4892d5a4d1a7ee55b765d7a3d9e3f82", + "sha256:2643d145af5292ee956aa0a83c2ce1038a3bdb26e033dadeb2f7066fb0c9abce", + "sha256:2c6e4464ed5f01dc44dc9821caf67b60a4e5c3b04278286a85c067010653a0eb", + "sha256:2f7f6985d05a4e3ce8255396df363046c28bea790e40617654e91ed580ca7c51", + "sha256:31902408f4bf54108bbfb2e35369877c01c95adc6192958684473658c322c8a5", + "sha256:40716d1f821b89838589e5b3106ebbc23636ffdef5abc31f7cd0266db936067e", + "sha256:4b901927f16224d0d143b925ce9a4e6b3a758010673eeded9b748f250cf4e8f7", + "sha256:4fc3d14ee80cd22367caaaf6e014494415bf440980a3045bf5045b525680ac33", + "sha256:5cf3f0c5ac72139797953bd50bc6c95ac13075e62dbfcc923571180bebb662e9", + "sha256:6dbdec441c60699288adf051f51a5d512b0d818526d1dcfff5a41f8cd8b4aaf1", + "sha256:72cf32ce7dd3562373f78bd751f73c96cfb441de147cc2448a92c1a308bd0ca6", + "sha256:75aa828610b67462ffe3057d4d8a4112105ed211596b750b53cbfe182f44777a", + "sha256:75c4d2a6effd015786c87774e04331b6da863fc3fc4e8adfc3b40aa55ab516fe", + "sha256:78e25b2fd6cbb55ddfb8058417df193f0129cad5f4ee75d1502248e588d9e0d7", + "sha256:84860e06ba363d9c0eeabd45ac0fde4b903ad7aa4f93cd8b648385a888e23200", + "sha256:8c5091ebd294f7628eb25ea554852a52058ac81472c921150e3a61cdd68f75a7", + "sha256:944bdc21ebd620eafefc090cdf83158393ec2b1391578359776c00de00e8907a", + "sha256:9c7ac372232c928fff0645d85f273a726970c014749b924ce5710d7d89763a28", + "sha256:d9b338c19fa2412f76e17525c1b4f2c687a55b156320acb588df79f2e6fa9fea", + "sha256:ee5d62d28b854eb61889cde4e1dbc10fbaa5560cb39780c3995f6737f7e82120", + "sha256:f2c2521a8e4d6d769e3234350ba7b65ff5d527137cdcde13ff4d99114b0c8e7d", + "sha256:f6efc9bd72258f89a3816e3a98c09d36f079c223aa345c659622f056b760ab42", + "sha256:f7c5d642db47376a0cc130f0de6d055056e010debdaf0707cd2b0fc7e7ef30ea", + "sha256:fcb6d9afb1b6208b4c712af0dafdc650f518836065df0d4fb1d800f5d6773db2", + "sha256:fcd2572dd4519e8a6642b733cd3a8cfc1ef94bafd0c1ceed9c94fe736cb65b6a" + ], + "index": "pypi", + "version": "==1.7.1" + }, + "mypy-extensions": { + "hashes": [ + "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", + "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" + ], + "markers": "python_version >= '3.5'", + "version": "==1.0.0" + }, + "packaging": { + "hashes": [ + "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", + "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + ], + "markers": "python_version >= '3.7'", + "version": "==23.2" + }, + "pathspec": { + "hashes": [ + "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20", + "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3" + ], + "markers": "python_version >= '3.7'", + "version": "==0.11.2" + }, + "platformdirs": { + "hashes": [ + "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380", + "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420" + ], + "markers": "python_version >= '3.8'", + "version": "==4.1.0" + }, + "pluggy": { + "hashes": [ + "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12", + "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7" + ], + "markers": "python_version >= '3.8'", + "version": "==1.3.0" + }, + "pylint": { + "hashes": [ + "sha256:0d4c286ef6d2f66c8bfb527a7f8a629009e42c99707dec821a03e1b51a4c1496", + "sha256:60ed5f3a9ff8b61839ff0348b3624ceeb9e6c2a92c514d81c9cc273da3b6bcda" + ], + "index": "pypi", + "version": "==3.0.2" + }, + "pytest": { + "hashes": [ + "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac", + "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5" + ], + "index": "pypi", + "version": "==7.4.3" + }, + "tomlkit": { + "hashes": [ + "sha256:75baf5012d06501f07bee5bf8e801b9f343e7aac5a92581f20f80ce632e6b5a4", + "sha256:b0a645a9156dc7cb5d3a1f0d4bab66db287fcb8e0430bdd4664a095ea16414ba" + ], + "markers": "python_version >= '3.7'", + "version": "==0.12.3" + }, + "typing-extensions": { + "hashes": [ + "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0", + "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" + ], + "markers": "python_version >= '3.8'", + "version": "==4.8.0" + } + }, + "develop": {} +} diff --git a/compose_generator/compose_generator.py b/compose_generator/compose_generator.py index cbec5dd..f6146a2 100644 --- a/compose_generator/compose_generator.py +++ b/compose_generator/compose_generator.py @@ -20,6 +20,7 @@ class ComposeGenerator: :param requestor: an object to request a new composed :param fetcher: an object to fetch a compose once it's ready """ + configurations_generator: ComposeConfigurationsGenerator requestor: ComposeRequester fetcher: ComposeFetcher diff --git a/compose_generator/odcs_compose_generator.py b/compose_generator/odcs_compose_generator.py index 3af29db..922809c 100644 --- a/compose_generator/odcs_compose_generator.py +++ b/compose_generator/odcs_compose_generator.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 +from .compose_generator import ComposeGenerator +from .odcs_configurations_generator import ODCSConfigurationsGenerator from .odcs_fetcher import ODCSFetcher from .odcs_requester import ODCSRequester -from .odcs_configurations_generator import ODCSConfigurationsGenerator -from .compose_generator import ComposeGenerator def main(): diff --git a/compose_generator/odcs_configurations_generator.py b/compose_generator/odcs_configurations_generator.py index 17a1d43..13c7d98 100644 --- a/compose_generator/odcs_configurations_generator.py +++ b/compose_generator/odcs_configurations_generator.py @@ -18,6 +18,7 @@ class ODCSConfigurationsGenerator(ComposeConfigurationsGenerator): :param container_data: data loaded from container.yaml :param content_sets_data: data loaded from content_sets.yaml """ + container_data: dict content_sets_data: dict diff --git a/compose_generator/odcs_fetcher.py b/compose_generator/odcs_fetcher.py index 4a83172..2992897 100644 --- a/compose_generator/odcs_fetcher.py +++ b/compose_generator/odcs_fetcher.py @@ -9,6 +9,7 @@ class ODCSResultReference(ComposeReference): """ Reference to a locally-stored compose result """ + compose_path: Path @@ -17,5 +18,6 @@ class ODCSFetcher(ComposeFetcher): """ Fetch ODCS compose based on a remote compose-reference and store it locally """ + def __call__(self, request_reference: ComposeReference) -> ODCSResultReference: raise NotImplementedError() diff --git a/compose_generator/odcs_requester.py b/compose_generator/odcs_requester.py index 3175cb8..4fcd6b0 100644 --- a/compose_generator/odcs_requester.py +++ b/compose_generator/odcs_requester.py @@ -8,6 +8,7 @@ class ODCSRequestReference(ComposeReference): """ Reference to a remotely-stored compose data """ + compose_url: str @@ -17,5 +18,6 @@ class ODCSRequester(ComposeRequester): Request a new ODCS compose based on compose configurations and return a reference to the remote compose location. """ + def __call__(self, configs: ComposeConfigurations) -> ODCSRequestReference: raise NotImplementedError() diff --git a/compose_generator/protocols.py b/compose_generator/protocols.py index f7687cd..4773cf9 100644 --- a/compose_generator/protocols.py +++ b/compose_generator/protocols.py @@ -11,6 +11,7 @@ class ComposeConfigurationsGenerator(Protocol): """ Generate compose configurations """ + def __call__(self) -> ComposeConfigurations: pass @@ -25,6 +26,7 @@ class ComposeRequester(Protocol): """ Given compose configurations, return a remote compose reference """ + def __call__(self, configs: ComposeConfigurations) -> ComposeReference: pass diff --git a/format.sh b/format.sh new file mode 100755 index 0000000..45c5dfb --- /dev/null +++ b/format.sh @@ -0,0 +1,11 @@ +#!/bin/bash -ex + +main() { + local pkgs=("tests" "compose_generator") + pipenv run isort --profile black "${pkgs[@]}" + pipenv run black "${pkgs[@]}" +} + +if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then + main "$@" +fi diff --git a/tests/test_static_check.py b/tests/test_static_check.py new file mode 100644 index 0000000..9798fe4 --- /dev/null +++ b/tests/test_static_check.py @@ -0,0 +1,25 @@ +"""Static checks""" +from subprocess import run +from typing import Final + +PKGS: Final[list[str]] = ["tests"] + + +def test_mypy() -> None: + """Static Type check""" + run(["mypy"] + PKGS, check=True) + + +def test_isort() -> None: + """Imports formatting check""" + run(["isort", "--check", "--profile", "black"] + PKGS, check=True) + + +def test_black() -> None: + """Formatting check""" + run(["black", "--check"] + PKGS, check=True) + + +def test_pylint() -> None: + """Lint check""" + run(["pylint"] + PKGS, check=True)