Skip to content

Commit 5957e10

Browse files
authored
chore: remove dependency on pytest-jira plugin and use xfail with condition for that (#1268)
Signed-off-by: Debarati Basu-Nag <dbasunag@redhat.com>
1 parent ec8d50a commit 5957e10

File tree

6 files changed

+1098
-1072
lines changed

6 files changed

+1098
-1072
lines changed

docs/GETTING_STARTED.md

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,30 @@ To skip RHOAI/ODH-related tests (for example when running in upstream), pass `--
135135

136136
To run tests with admin client only, pass `--tc=use_unprivileged_client:False` to pytest.
137137

138-
### jira integration
139138

140-
To skip running tests which have open bugs, [pytest_jira](https://github.com/rhevm-qe-automation/pytest_jira) plugin is used.
141-
To run tests with jira integration, you need to set `PYTEST_JIRA_URL`, `PYTEST_JIRA_USERNAME` and `PYTEST_JIRA_TOKEN` environment variables.
142-
To make a test with jira marker, add: `@pytest.mark.jira(jira_id="RHOAIENG-0000", run=False)` to the test.
139+
### Skipping tests for known Jira issues
140+
141+
To skip a test that is affected by a known Jira bug, use `pytest.mark.xfail` with `is_jira_issue_open` as the condition:
142+
143+
```python
144+
from utilities.jira import is_jira_issue_open
145+
146+
@pytest.mark.xfail(condition=is_jira_issue_open(jira_id="RHOAIENG-12345"), reason="RHOAIENG-12345", run=False)
147+
def test_example(self):
148+
...
149+
```
150+
151+
- `condition=is_jira_issue_open(...)` checks the Jira issue status at collection time. If the issue is open, the test is marked as xfail.
152+
- `run=False` skips execution entirely while the issue is open. Once the issue is closed/resolved, the test runs normally.
153+
- If Jira is unreachable, the issue is assumed open and the test is skipped.
154+
155+
The following environment variables must be set for Jira connectivity:
156+
157+
```bash
158+
export PYTEST_JIRA_URL=<your_jira_url>
159+
export PYTEST_JIRA_USERNAME=<username>
160+
export PYTEST_JIRA_TOKEN=<token>
161+
```
143162

144163
### Running containerized tests
145164

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ dependencies = [
6161
"grpcio-reflection",
6262
"portforward>=0.7.1",
6363
"pytest-testconfig>=0.2.0",
64-
"pytest-jira>=0.3.21",
64+
6565
"pygithub>=2.5.0",
6666
"timeout-sampler>=1.0.6",
6767
"shortuuid>=1.0.13",

pytest.ini

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ testpaths = tests
55
markers =
66
# General
77
polarion: Store polarion test ID
8-
jira: Store jira bug ID
8+
99
skip_on_disconnected: Mark tests that can only be run in deployments with Internet access i.e. not on disconnected clusters.
1010
parallel: marks tests that can run in parallel along with pytest-xdist
1111

@@ -63,6 +63,3 @@ addopts =
6363
--show-progress
6464
--tc-file=tests/global_config.py
6565
--tc-format=python
66-
--jira
67-
--jira-connection-error-strategy=skip
68-
--jira-disable-docs-search

tests/model_serving/model_server/kserve/authentication/test_kserve_token_authentication_raw.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from utilities.constants import Annotations, Protocols
66
from utilities.inference_utils import Inference
77
from utilities.infra import check_pod_status_in_time, get_pods_by_isvc_label
8+
from utilities.jira import is_jira_issue_open
89
from utilities.manifests.onnx import ONNX_INFERENCE_CONFIG
910

1011
pytestmark = pytest.mark.usefixtures("valid_aws_config")
@@ -49,7 +50,7 @@ def test_disabled_raw_model_authentication(self, patched_remove_raw_authenticati
4950
)
5051

5152
@pytest.mark.smoke
52-
@pytest.mark.jira("RHOAIENG-52129", run=False)
53+
@pytest.mark.xfail(condition=is_jira_issue_open(jira_id="RHOAIENG-52129"), reason="RHOAIENG-52129", run=False)
5354
def test_raw_disable_enable_authentication_no_pod_rollout(self, http_s3_ovms_raw_inference_service):
5455
"""Verify no pod rollout when disabling and enabling authentication"""
5556
pod = get_pods_by_isvc_label(

utilities/jira.py

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
import os
22
import re
33
from functools import cache
4+
from typing import Any
45

5-
from jira import JIRA
6+
from jira import JIRA, JIRAError
67
from kubernetes.dynamic import DynamicClient
78
from ocp_resources.cluster_service_version import ClusterServiceVersion
89
from ocp_resources.exceptions import MissingResourceError
910
from packaging.version import Version
1011
from pytest_testconfig import config as py_config
12+
from requests.exceptions import ConnectionError as RequestsConnectionError
1113
from simple_logger.logger import get_logger
14+
from urllib3.exceptions import NewConnectionError
1215

1316
LOGGER = get_logger(name=__name__)
1417

18+
JIRA_CLOSED_STATUSES = ("closed", "resolved", "testing")
19+
1520

1621
@cache
1722
def get_jira_connection() -> JIRA:
@@ -28,6 +33,20 @@ def get_jira_connection() -> JIRA:
2833
)
2934

3035

36+
@cache
37+
def get_jira_issue_fields(jira_id: str) -> Any:
38+
"""
39+
Get Jira issue fields (status and fixVersions).
40+
41+
Args:
42+
jira_id: Jira issue id (e.g. "RHOAIENG-52129").
43+
44+
Returns:
45+
Jira issue fields object with status and fixVersions.
46+
"""
47+
return get_jira_connection().issue(id=jira_id, fields="status, fixVersions").fields
48+
49+
3150
def is_jira_open(jira_id: str, admin_client: DynamicClient) -> bool:
3251
"""
3352
Check if Jira issue is open.
@@ -40,15 +59,11 @@ def is_jira_open(jira_id: str, admin_client: DynamicClient) -> bool:
4059
bool: True if Jira issue is open.
4160
4261
"""
43-
jira_fields = get_jira_connection().issue(id=jira_id, fields="status, fixVersions").fields
44-
45-
jira_status = jira_fields.status.name.lower()
46-
47-
if jira_status not in ("testing", "resolved", "closed"):
48-
LOGGER.info(f"Jira {jira_id}: status is {jira_status}")
62+
if is_jira_issue_open(jira_id=jira_id):
4963
return True
5064

5165
else:
66+
jira_fields = get_jira_issue_fields(jira_id=jira_id)
5267
# Check if the operator version in ClusterServiceVersion is greater than the jira fix version
5368
jira_fix_versions: list[Version] = [
5469
Version(_fix_version.group())
@@ -57,7 +72,7 @@ def is_jira_open(jira_id: str, admin_client: DynamicClient) -> bool:
5772
]
5873

5974
if not jira_fix_versions:
60-
raise ValueError(f"Jira {jira_id}: status is {jira_status} but does not have fix version(s)")
75+
raise ValueError(f"Jira {jira_id}: closed/resolved but does not have fix version(s)")
6176

6277
operator_version: str = ""
6378
for csv in ClusterServiceVersion.get(client=admin_client, namespace=py_config["applications_namespace"]):
@@ -71,9 +86,31 @@ def is_jira_open(jira_id: str, admin_client: DynamicClient) -> bool:
7186
csv_version = Version(version=operator_version)
7287
if all(csv_version < fix_version for fix_version in jira_fix_versions):
7388
LOGGER.info(
74-
f"Bug is open: Jira {jira_id}: status is {jira_status}, "
75-
f"fix versions {jira_fix_versions}, operator version is {operator_version}"
89+
f"Bug is open: Jira {jira_id}: fix versions {jira_fix_versions}, operator version is {operator_version}"
7690
)
7791
return True
7892

7993
return False
94+
95+
96+
@cache
97+
def is_jira_issue_open(jira_id: str) -> bool: # skip-unused-code
98+
"""
99+
Check if a Jira issue is open based on its status.
100+
101+
Args:
102+
jira_id: Jira issue id (e.g. "RHOAIENG-52129").
103+
104+
Returns:
105+
True if the issue status is not in closed/resolved/testing.
106+
True if Jira is unreachable (assumes issue is open).
107+
"""
108+
try:
109+
jira_status = get_jira_issue_fields(jira_id=jira_id).status.name.lower()
110+
except NewConnectionError, JIRAError, RequestsConnectionError:
111+
LOGGER.warning(f"Failed to get Jira issue {jira_id}, assuming it is open")
112+
return True
113+
114+
is_open = jira_status not in JIRA_CLOSED_STATUSES
115+
LOGGER.info(f"Jira {jira_id}: status={jira_status}, open={is_open}")
116+
return is_open

0 commit comments

Comments
 (0)