diff --git a/.github/workflows/pre-commit-tests.yml b/.github/workflows/pre-commit-tests.yml index 31e5c8c..11f46cd 100644 --- a/.github/workflows/pre-commit-tests.yml +++ b/.github/workflows/pre-commit-tests.yml @@ -18,7 +18,7 @@ jobs: run: | echo "::set-output name=SHA::$(git rev-parse HEAD)" - - name: Install needed dependences for sanity checks + - name: Install needed dependencies for sanity checks id: sched_test run: | sudo apt-get update && sudo apt-get -y install curl jq make git shellcheck python3 python3-pip diff --git a/setup.py b/setup.py index 84c984e..ead1c6a 100644 --- a/setup.py +++ b/setup.py @@ -36,7 +36,7 @@ def get_requirements(): """Parse all packages mentioned in the 'requirements.txt' file.""" - with open(Path(this_directory) / "requirements.txt") as file_stream: + with open("requirements.txt") as file_stream: return file_stream.read().splitlines() diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..543f4c7 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,71 @@ +# MIT License +# +# Copyright (c) 2020 SCL team at Red Hat +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import pytest +import json + +from tests.spellbook import DATA_DIR + + +@pytest.fixture() +def get_repo_name(): + return json.loads((DATA_DIR / "gh_repo_name.json").read_text()) + + +@pytest.fixture() +def get_repo_wrong_name(): + return json.loads((DATA_DIR / "gh_different_repo_name.json").read_text()) + + +@pytest.fixture() +def get_pr_missing_ci(): + return json.loads((DATA_DIR / "pr_missing_ci.json").read_text()) + + +@pytest.fixture() +def get_pr_missing_review(): + return json.loads((DATA_DIR / "pr_missing_review.json").read_text()) + + +@pytest.fixture() +def get_pr_missing_ci_failed(): + return json.loads((DATA_DIR / "pr_missing_review_ci_failed.json").read_text()) + + +@pytest.fixture() +def get_two_pr_missing_labels(): + return json.loads((DATA_DIR / "pr_two_pr_missing_labels.json").read_text()) + + +@pytest.fixture() +def get_no_mr_to_check(): + return json.loads((DATA_DIR / "no_pr_for_merging.json").read_text()) + + +@pytest.fixture() +def get_pr_missing_labels_approved(): + return json.loads((DATA_DIR / "pr_missing_labels_approved.json").read_text()) + + +@pytest.fixture() +def get_pr_missing_labels_one_approval(): + return json.loads((DATA_DIR / "pr_missing_labels_one_approval.json").read_text()) diff --git a/tests/data/gh_different_repo_name.json b/tests/data/gh_different_repo_name.json new file mode 100644 index 0000000..eb6deee --- /dev/null +++ b/tests/data/gh_different_repo_name.json @@ -0,0 +1,3 @@ +{ + "name": "s2i-python-container" +} diff --git a/tests/data/gh_repo_name.json b/tests/data/gh_repo_name.json new file mode 100644 index 0000000..9815cee --- /dev/null +++ b/tests/data/gh_repo_name.json @@ -0,0 +1,3 @@ +{ + "name": "s2i-nodejs-container" +} diff --git a/tests/data/no_pr_for_merging.json b/tests/data/no_pr_for_merging.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/data/no_pr_for_merging.json @@ -0,0 +1 @@ +[] diff --git a/tests/data/pr_missing_ci.json b/tests/data/pr_missing_ci.json new file mode 100644 index 0000000..c1e1547 --- /dev/null +++ b/tests/data/pr_missing_ci.json @@ -0,0 +1,44 @@ +[ + { + "labels": [ + { + "id": "MDU6TGFiZWwxNzM3MjEwMTc=", + "name": "enhancement", + "description": "", + "color": "84b6eb" + }, + { + "id": "MDU6TGFiZWwzNTI2MjY1NDA=", + "name": "P1", + "description": "", + "color": "d93f0b" + }, + { + "id": "LA_kwDOAc6Y3c7cwogD", + "name": "ready for review", + "description": "The pull request is ready to review", + "color": "0052CC" + }, + { + "id": "LA_kwDOAc6Y3c8AAAABpEG3Zg", + "name": "easyfix", + "description": "", + "color": "0E8A16" + }, + { + "id": "LA_kwDOAc6Y3c8AAAABrYkcpw", + "name": "pr/missing-review", + "description": "", + "color": "ededed" + }, + { + "id": "LA_kwDOAc6Y3c8AAAABrdCuRQ", + "name": "pr/failing-ci", + "description": "", + "color": "ededed" + } + ], + "number": 314, + "title": "Support s2i-core building and testing on Fedora 41" + } +] diff --git a/tests/data/pr_missing_labels_approved.json b/tests/data/pr_missing_labels_approved.json new file mode 100644 index 0000000..5b70a21 --- /dev/null +++ b/tests/data/pr_missing_labels_approved.json @@ -0,0 +1,61 @@ +[ + { + "labels": [ + { + "id": "LA_kwDOBAiYYc7jV-mn", + "name": "ready for review", + "description": "", + "color": "0052CC" + } + ], + "number": 380, + "reviews": [ + { + "id": "PRR_kwDOBAiYYc6G8b3f", + "author": { + "login": "github-advanced-security" + }, + "authorAssociation": "NONE", + "body": "", + "submittedAt": "2024-08-27T16:52:10Z", + "includesCreatedEdit": false, + "reactionGroups": [], + "state": "COMMENTED", + "commit": { + "oid": "60c8c81103536c3506226d82e61c83876568b6d1" + } + }, + { + "id": "PRR_kwDOBAiYYc6HFgYG", + "author": { + "login": "SlouchyButton" + }, + "authorAssociation": "MEMBER", + "body": "Tested on Node.js container on all supported targets and versions. All tests seem to be working.\r\n\r\nCode is cleaner and more readable.", + "submittedAt": "2024-08-28T13:57:52Z", + "includesCreatedEdit": false, + "reactionGroups": [], + "state": "APPROVED", + "commit": { + "oid": "fc8bf0e8202ae26f3f012dc81063e629767e20db" + } + }, + { + "id": "PRR_kwDOBAiYYc6HoDdg", + "author": { + "login": "phracek" + }, + "authorAssociation": "MEMBER", + "body": "LGTM. Let's spread it into containers and we will see the updates.", + "submittedAt": "2024-09-02T11:47:52Z", + "includesCreatedEdit": false, + "reactionGroups": [], + "state": "APPROVED", + "commit": { + "oid": "fc8bf0e8202ae26f3f012dc81063e629767e20db" + } + } + ], + "title": "Use timeout utility instead of double-sub-shell hell" + } +] diff --git a/tests/data/pr_missing_labels_one_approval.json b/tests/data/pr_missing_labels_one_approval.json new file mode 100644 index 0000000..8f6648f --- /dev/null +++ b/tests/data/pr_missing_labels_one_approval.json @@ -0,0 +1,46 @@ +[ + { + "labels": [ + { + "id": "LA_kwDOBAiYYc7jV-mn", + "name": "ready for review", + "description": "", + "color": "0052CC" + } + ], + "number": 380, + "reviews": [ + { + "id": "PRR_kwDOBAiYYc6G8b3f", + "author": { + "login": "github-advanced-security" + }, + "authorAssociation": "NONE", + "body": "", + "submittedAt": "2024-08-27T16:52:10Z", + "includesCreatedEdit": false, + "reactionGroups": [], + "state": "COMMENTED", + "commit": { + "oid": "60c8c81103536c3506226d82e61c83876568b6d1" + } + }, + { + "id": "PRR_kwDOBAiYYc6HFgYG", + "author": { + "login": "SlouchyButton" + }, + "authorAssociation": "MEMBER", + "body": "Tested on Node.js container on all supported targets and versions. All tests seem to be working.\r\n\r\nCode is cleaner and more readable.", + "submittedAt": "2024-08-28T13:57:52Z", + "includesCreatedEdit": false, + "reactionGroups": [], + "state": "APPROVED", + "commit": { + "oid": "fc8bf0e8202ae26f3f012dc81063e629767e20db" + } + } + ], + "title": "Use timeout utility instead of double-sub-shell hell" + } +] diff --git a/tests/data/pr_missing_review.json b/tests/data/pr_missing_review.json new file mode 100644 index 0000000..c1e291c --- /dev/null +++ b/tests/data/pr_missing_review.json @@ -0,0 +1,12 @@ +{ + "labels": [ + { + "id": "LA_kwDOA3sMzs8AAAABqTWftQ", + "name": "pr/missing-review", + "description": "", + "color": "ededed" + } + ], + "number": 192, + "title": "[WIP] Make tests work also for rootless containers" +} diff --git a/tests/data/pr_missing_review_ci_failed.json b/tests/data/pr_missing_review_ci_failed.json new file mode 100644 index 0000000..c1e1547 --- /dev/null +++ b/tests/data/pr_missing_review_ci_failed.json @@ -0,0 +1,44 @@ +[ + { + "labels": [ + { + "id": "MDU6TGFiZWwxNzM3MjEwMTc=", + "name": "enhancement", + "description": "", + "color": "84b6eb" + }, + { + "id": "MDU6TGFiZWwzNTI2MjY1NDA=", + "name": "P1", + "description": "", + "color": "d93f0b" + }, + { + "id": "LA_kwDOAc6Y3c7cwogD", + "name": "ready for review", + "description": "The pull request is ready to review", + "color": "0052CC" + }, + { + "id": "LA_kwDOAc6Y3c8AAAABpEG3Zg", + "name": "easyfix", + "description": "", + "color": "0E8A16" + }, + { + "id": "LA_kwDOAc6Y3c8AAAABrYkcpw", + "name": "pr/missing-review", + "description": "", + "color": "ededed" + }, + { + "id": "LA_kwDOAc6Y3c8AAAABrdCuRQ", + "name": "pr/failing-ci", + "description": "", + "color": "ededed" + } + ], + "number": 314, + "title": "Support s2i-core building and testing on Fedora 41" + } +] diff --git a/tests/data/pr_one_approved.json b/tests/data/pr_one_approved.json new file mode 100644 index 0000000..08fd397 --- /dev/null +++ b/tests/data/pr_one_approved.json @@ -0,0 +1 @@ +[{"labels":[{"id":"LA_kwDOA3svrM8AAAABv9iyKQ","name":"pr/failing-ci","description":"","color":"ededed"},{"id":"LA_kwDOA3svrM8AAAABv98gkg","name":"READY-to-MERGE","description":"","color":"23738E"}],"number":230,"reviews":[{"id":"PRR_kwDOA3svrM6Ky3Lu","author":{"login":"hhorak"},"authorAssociation":"MEMBER","body":"lgtm","submittedAt":"2024-09-25T15:08:39Z","includesCreatedEdit":false,"reactionGroups":[],"state":"APPROVED","commit":{"oid":"a45b91f2198bb6d3f64faccac97e7654495e0d41"}}],"title":"Enable building C10S to quay.io"},{"labels":[],"number":140,"reviews":[{"id":"PRR_kwDOA3svrM4-0nfK","author":{"login":"phracek"},"authorAssociation":"MEMBER","body":"The test suite is present and working properly. I did not hit any issues.","submittedAt":"2022-07-28T12:11:00Z","includesCreatedEdit":false,"reactionGroups":[],"state":"APPROVED","commit":{"oid":"be3c4b8a9df331e6d702278329e8dc88489d0c07"}},{"id":"PRR_kwDOA3svrM4_kaSb","author":{"login":"zmiklank"},"authorAssociation":"CONTRIBUTOR","body":"","submittedAt":"2022-08-09T10:48:25Z","includesCreatedEdit":false,"reactionGroups":[],"state":"COMMENTED","commit":{"oid":"be3c4b8a9df331e6d702278329e8dc88489d0c07"}},{"id":"PRR_kwDOA3svrM5qUCNn","author":{"login":"hhorak"},"authorAssociation":"MEMBER","body":"","submittedAt":"2023-12-15T11:20:19Z","includesCreatedEdit":false,"reactionGroups":[],"state":"COMMENTED","commit":{"oid":"be3c4b8a9df331e6d702278329e8dc88489d0c07"}}],"title":"Test certificates age, so we are sure the certificates were just generated during assemble script"}] diff --git a/tests/data/pr_two_pr_missing_labels.json b/tests/data/pr_two_pr_missing_labels.json new file mode 100644 index 0000000..6f5bca6 --- /dev/null +++ b/tests/data/pr_two_pr_missing_labels.json @@ -0,0 +1,12 @@ +[ + { + "labels": [], + "number": 180, + "title": "Use 3.3-ubi9 as default. Add initialConter to rail-postgresql.json" + }, + { + "labels": [], + "number": 178, + "title": "Fix the openshift templates" + } +] diff --git a/tests/spellbook.py b/tests/spellbook.py new file mode 100644 index 0000000..5bf3037 --- /dev/null +++ b/tests/spellbook.py @@ -0,0 +1,26 @@ +# MIT License +# +# Copyright (c) 2020 SCL team at Red Hat +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from pathlib import Path + +TESTS_DIR = Path(__file__).parent +DATA_DIR = TESTS_DIR / "data" diff --git a/tests/test_correct_repo.py b/tests/test_correct_repo.py new file mode 100644 index 0000000..265c3d8 --- /dev/null +++ b/tests/test_correct_repo.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 + +from flexmock import flexmock + +from auto_merger.merger import AutoMerger + + +def test_get_gh_pr_correct_repo(get_repo_name): + flexmock(AutoMerger).should_receive("get_gh_json_output").and_return(get_repo_name) + auto_merger = AutoMerger() + auto_merger.container_name = "s2i-nodejs-container" + assert auto_merger.is_correct_repo() + + +def test_get_gh_pr_wrong_repo(get_repo_wrong_name): + flexmock(AutoMerger).should_receive("get_gh_json_output").and_return( + get_repo_wrong_name + ) + auto_merger = AutoMerger() + auto_merger.container_name = "s2i-nodejs-container" + assert not auto_merger.is_correct_repo() diff --git a/tests/test_pr_status.py b/tests/test_pr_status.py new file mode 100644 index 0000000..d9b3c3c --- /dev/null +++ b/tests/test_pr_status.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 + +from flexmock import flexmock + +from auto_merger.merger import AutoMerger + + +def test_get_gh_pr_list(get_pr_missing_ci): + flexmock(AutoMerger).should_receive("get_gh_json_output").and_return( + get_pr_missing_ci + ) + auto_merger = AutoMerger() + auto_merger.container_name = "s2i-nodejs-container" + auto_merger.get_gh_pr_list() + assert auto_merger.repo_data + flexmock(AutoMerger).should_receive("merge_pull_requests").never() + + +def test_get_gh_two_pr_labels_missing(get_two_pr_missing_labels): + flexmock(AutoMerger).should_receive("get_gh_json_output").and_return( + get_two_pr_missing_labels + ) + auto_merger = AutoMerger() + auto_merger.container_name = "s2i-nodejs-container" + auto_merger.get_gh_pr_list() + assert auto_merger.repo_data + assert not auto_merger.check_pr_to_merge() + flexmock(AutoMerger).should_receive("merge_pull_requests").never() + + +def test_get_gh_pr_missing_ci(get_pr_missing_ci): + flexmock(AutoMerger).should_receive("get_gh_json_output").and_return( + get_pr_missing_ci + ) + auto_merger = AutoMerger() + auto_merger.container_name = "s2i-nodejs-container" + auto_merger.get_gh_pr_list() + assert auto_merger.repo_data + assert not auto_merger.check_pr_to_merge() + flexmock(AutoMerger).should_receive("merge_pull_requests").never() + + +def test_get_no_pr_for_merge(get_no_mr_to_check): + flexmock(AutoMerger).should_receive("get_gh_json_output").and_return( + get_no_mr_to_check + ) + auto_merger = AutoMerger() + auto_merger.container_name = "s2i-nodejs-container" + auto_merger.get_gh_pr_list() + assert not auto_merger.repo_data + assert not auto_merger.check_pr_to_merge() + flexmock(AutoMerger).should_receive("merge_pull_requests").never() diff --git a/tox.ini b/tox.ini index e524bc0..a614e8b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,3 +1,7 @@ +[tox] +skipsdist = True +envlist = py36,py37,py38,py39,py310,py311,py312 + [testenv] commands = python3 -m pytest --color=yes -vv --verbose --showlocals deps =