forked from SatelliteQE/robottelo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Filter test collection based on files changed in upstream PRs (Satell…
- Loading branch information
Showing
5 changed files
with
123 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Upstream GitHub repos and test collection rules | ||
GITHUB_REPOS: | ||
BASE_MARKER: | ||
FOREMAN: | ||
ORG: theforeman | ||
REPO: foreman | ||
RULES: | ||
- PATH: | ||
MARKER: | ||
MARKER_ARG: | ||
KATELLO: | ||
ORG: Katello | ||
REPO: katello | ||
RULES: | ||
- PATH: | ||
MARKER: | ||
MARKER_ARG: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
from github import Github | ||
|
||
from robottelo.config import settings | ||
from robottelo.logging import collection_logger as logger | ||
|
||
|
||
def rule_match(item, rules): | ||
"""Return True if `item` has a marker matching one of the `rules`. | ||
In order for a rule to match: | ||
1. If `settings.github_repos.base_marker` exists, then `item` has a marker with the given value | ||
as its `name` attribute. | ||
2. `item` has a marker with the name given in `rule.marker`. | ||
3. If `rule.marker_arg` exists, then the item's marker must also have the given value in marker's | ||
`args` attribute. | ||
""" | ||
base_marker = settings.github_repos.get('base_marker') | ||
return ( | ||
not base_marker or any(base_marker == marker.name for marker in item.iter_markers()) | ||
) and any( | ||
rule.marker == marker.name | ||
and (not rule.get('marker_arg') or rule.get('marker_arg') in marker.args) | ||
for marker in item.iter_markers() | ||
for rule in rules | ||
) | ||
|
||
|
||
def pytest_addoption(parser): | ||
"""Add CLI option to specify upstream GitHub PRs. | ||
Add --upstream-pr option for filtering tests based on the files modified by upstream | ||
PRs. | ||
""" | ||
parser.addoption( | ||
"--upstream-pr", | ||
help=( | ||
"Comma separated list of upstream PRs to filter test collection based on files modified in upstream.\n" | ||
"Usage: `pytest tests/foreman --upstream-pr foreman/10146`" | ||
), | ||
) | ||
|
||
|
||
def pytest_collection_modifyitems(session, items, config): | ||
"""Filter tests based on upstream PRs. | ||
1. Get the list of modified files in the upstream PRs. | ||
2. Map each file to at most one marker. | ||
3. Filter the collected tests to include only those with matching markers. | ||
If no rules were matched above, all tests will be deselected. | ||
Filenames that did not match any rules are ignored. | ||
""" | ||
if not ( | ||
upstream_prs := [ | ||
pr_info for pr_info in (config.getoption('upstream_pr') or '').split(',') if pr_info != '' | ||
] | ||
): | ||
return | ||
|
||
matched_rules = [] | ||
|
||
for pr_info in upstream_prs: | ||
repo_key, pr_id = pr_info.split('/') | ||
if not (repo_config := settings.github_repos.get(repo_key)): | ||
raise Exception(f"Key {repo_key} not found in settings file.") | ||
|
||
# Get list of filenames modified by this PR | ||
pr = Github().get_repo(f"{repo_config.org}/{repo_config.repo}").get_pull(int(pr_id)) | ||
pr_filenames = {file.filename for file in pr.get_files()} | ||
|
||
# Get list of matching rules | ||
unprocessed_filenames = pr_filenames.copy() | ||
for rule in repo_config.rules: | ||
if matched_filenames := { | ||
filename for filename in unprocessed_filenames if filename.startswith(rule.path) | ||
}: | ||
matched_rules.append(rule) | ||
unprocessed_filenames.difference_update(matched_filenames) | ||
|
||
# If no rules were matched above, deselect all tests. | ||
# Filenames that didn't match any rules are ignored. | ||
selected = [] | ||
deselected = [] | ||
for item in items: | ||
if matched_rules: | ||
if rule_match(item, matched_rules): | ||
selected.append(item) | ||
else: | ||
logger.debug(f'Deselected test {item.nodeid} due to PR filter {upstream_prs}') | ||
deselected.append(item) | ||
else: | ||
logger.debug(f'Deselected test {item.nodeid} due to PR filter {upstream_prs}') | ||
deselected.append(item) | ||
|
||
config.hook.pytest_deselected(items=deselected) | ||
items[:] = selected |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters