-
Notifications
You must be signed in to change notification settings - Fork 23
Run a reproducer in a simple way #369
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
majamassarini
wants to merge
1
commit into
packit:main
Choose a base branch
from
majamassarini:simple-reproducer
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or 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 hidden or 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
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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,84 @@ | ||
| import asyncio | ||
| import logging | ||
| import re | ||
| import shlex | ||
| from typing import Annotated, Tuple | ||
|
|
||
| from fastmcp.exceptions import ToolError | ||
| from pydantic import Field | ||
|
|
||
| from common.utils import init_kerberos_ticket, KerberosError | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
| async def get_copr_repo(issue: Annotated[str, Field(description="Jira issue to get the Copr repo for")]) -> str: | ||
| """Gets the Copr repo for the package""" | ||
| try: | ||
| principal = await init_kerberos_ticket() | ||
| except KerberosError as e: | ||
| raise ToolError(f"Failed to initialize Kerberos ticket: {e}") from e | ||
| copr_user = principal.split("@", maxsplit=1)[0] | ||
| return f"copr.devel.redhat.com/{copr_user}/{issue}" | ||
|
|
||
| async def get_compose_from_branch(dist_git_branch: Annotated[str, Field(description="Branch to get the compose from")]) -> str: | ||
| """Gets the compose from the branch""" | ||
| if dist_git_branch == "rhel-8.10": | ||
| # There is one more .0 needed only for the RHEL 8.10 compose (not for 10.X branches) | ||
| return "RHEL-8.10.0-Nightly" | ||
| elif dist_git_branch.startswith("rhel-"): | ||
| return dist_git_branch.upper() + "-Nightly" | ||
| else: | ||
| match = re.match(r'^c(\d+)s$', dist_git_branch) | ||
| if match: | ||
| number = match.group(1) | ||
| return f"CentOS-Stream-{number}" | ||
| else: | ||
| raise ToolError(f"Invalid branch format, can't get compose from branch: {dist_git_branch}") | ||
|
|
||
| async def run_testing_farm_test( | ||
| git_url: Annotated[str, Field(description="Git URL to the test repository")], | ||
| git_ref: Annotated[str, Field(description="Git reference to the test repository")], | ||
| path_to_test: Annotated[str, Field(description="Path to the test to run")], | ||
| package: Annotated[str, Field(description="Package URL to be installed in the test environment")], | ||
| dist_git_branch: Annotated[str, Field(description="Dist Git branch to use to get the compose")], | ||
| ) -> Tuple[bool, str]: | ||
| """Runs the specified testing-farm test and returns True if the test passed, False otherwise.""" | ||
|
|
||
| tmt_prepare = f'--insert --how install --package {shlex.quote(package)}' | ||
| compose = await get_compose_from_branch(dist_git_branch) | ||
|
|
||
| # Build the command arguments | ||
| cmd = [ | ||
| "testing-farm", | ||
| "request", | ||
| "--tmt-prepare", tmt_prepare, | ||
| "--compose", compose, | ||
| "--git-ref", git_ref, | ||
| "--git-url", git_url, | ||
| "--test", path_to_test, | ||
| ] | ||
|
|
||
| logger.info(f"Running testing-farm command: {' '.join(shlex.quote(arg) for arg in cmd)}") | ||
|
|
||
| try: | ||
| process = await asyncio.create_subprocess_exec( | ||
| *cmd, | ||
| stdout=asyncio.subprocess.PIPE, | ||
| stderr=asyncio.subprocess.PIPE, | ||
| ) | ||
|
|
||
| stdout, stderr = await process.communicate() | ||
|
|
||
| if process.returncode == 0: | ||
| msg = f"Testing Farm test passed: \n stdout {'='*60}\n {stdout.decode()}\n {'='*60}\n stderr {'='*60}\n {stderr.decode()}\n {'='*60}" | ||
| logger.info(msg) | ||
| return True, msg | ||
| else: | ||
| msg = f"Testing Farm test failed (exit code {process.returncode}): \n stdout {'='*60}\n {stdout.decode()}\n {'='*60}\n stderr {'='*60}\n {stderr.decode()}\n {'='*60}" | ||
| msg += f"\n Ran command: {' '.join(shlex.quote(arg) for arg in cmd)}" | ||
| logger.error(msg) | ||
| return False, msg | ||
|
|
||
| except Exception as e: | ||
| logger.error(f"Failed to run testing-farm command: {e}") | ||
| raise ToolError(f"Failed to run testing-farm test: {e}") from e | ||
This file contains hidden or 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,105 @@ | ||
| """Tests for testing_farm_tools module.""" | ||
|
|
||
| import asyncio | ||
| import shlex | ||
| import pytest | ||
| from unittest.mock import AsyncMock, patch | ||
| from mcp_server.testing_farm_tools import run_testing_farm_test, get_compose_from_branch | ||
|
|
||
|
|
||
| def test_tmt_prepare_quoting(): | ||
| """Test that package URLs with special characters are properly quoted.""" | ||
| # Test with a package URL that has special characters | ||
| package = 'http://example.com/package-1.0-1.el9.x86_64.rpm' | ||
| tmt_prepare = f'--insert --how install --package {shlex.quote(package)}' | ||
|
|
||
| # Should be properly quoted | ||
| assert '--insert' in tmt_prepare | ||
| assert '--how' in tmt_prepare | ||
| assert 'install' in tmt_prepare | ||
| assert '--package' in tmt_prepare | ||
| assert package in tmt_prepare | ||
|
|
||
|
|
||
| @pytest.mark.asyncio | ||
| async def test_get_compose_from_branch(): | ||
| """Test get_compose_from_branch function with various branch formats.""" | ||
| test_cases = [ | ||
| ("rhel-9.7.0", "RHEL-9.7.0-Nightly"), | ||
| ("rhel-10.2", "RHEL-10.2-Nightly"), | ||
| ("rhel-8.10", "RHEL-8.10.0-Nightly"), | ||
| ("c8s", "CentOS-Stream-8"), | ||
| ] | ||
|
|
||
| for branch, expected_compose in test_cases: | ||
| result = await get_compose_from_branch(branch) | ||
| assert result == expected_compose, ( | ||
| f"Branch '{branch}' should return '{expected_compose}', " | ||
| f"but got '{result}'" | ||
| ) | ||
|
|
||
|
|
||
| @pytest.mark.asyncio | ||
| async def test_run_testing_farm_test_success(): | ||
| """Test run_testing_farm_test with successful test execution.""" | ||
| git_url = "https://gitlab.com/redhat/rhel/tests/expat.git" | ||
| git_ref = "master" | ||
| path_to_test = "Security/RHEL-114639-CVE-2025-59375-expat-libexpat-in-Expat-allows" | ||
| package = "http://coprbe.devel.redhat.com/results/mmassari/RHEL-114644/rhel-9-x86_64/00127295-expat/expat-2.5.0-5.el9.x86_64.rpm" | ||
| dist_git_branch = "rhel-9.7.0" | ||
|
|
||
| # Mock the subprocess to return success | ||
| mock_process = AsyncMock() | ||
| mock_process.returncode = 0 | ||
| mock_process.communicate = AsyncMock(return_value=(b"Test passed", b"")) | ||
|
|
||
| with patch('mcp_server.testing_farm_tools.asyncio.create_subprocess_exec', return_value=mock_process): | ||
| success, result = await run_testing_farm_test( | ||
| git_url=git_url, | ||
| git_ref=git_ref, | ||
| path_to_test=path_to_test, | ||
| package=package, | ||
| dist_git_branch=dist_git_branch, | ||
| ) | ||
|
|
||
| assert success is True | ||
| assert "Test passed" in result | ||
| assert "Testing Farm test passed" in result | ||
|
|
||
|
|
||
| @pytest.mark.asyncio | ||
| async def test_run_testing_farm_test_failure(): | ||
| """Test run_testing_farm_test with failed test execution.""" | ||
| git_url = "https://gitlab.com/redhat/rhel/tests/expat.git" | ||
| git_ref = "master" | ||
| path_to_test = "Security/RHEL-114639-CVE-2025-59375-expat-libexpat-in-Expat-allows" | ||
| package = "http://coprbe.devel.redhat.com/results/mmassari/RHEL-114644/rhel-9-x86_64/00127295-expat/expat-2.5.0-5.el9.x86_64.rpm" | ||
| dist_git_branch = "rhel-9.7.0" | ||
|
|
||
| # Mock the subprocess to return failure | ||
| mock_process = AsyncMock() | ||
| mock_process.returncode = 1 | ||
| mock_process.communicate = AsyncMock(return_value=(b"", b"Test failed with error")) | ||
|
|
||
| with patch('mcp_server.testing_farm_tools.asyncio.create_subprocess_exec', return_value=mock_process): | ||
| success, result = await run_testing_farm_test( | ||
| git_url=git_url, | ||
| git_ref=git_ref, | ||
| path_to_test=path_to_test, | ||
| package=package, | ||
| dist_git_branch=dist_git_branch, | ||
| ) | ||
|
|
||
| assert success is False | ||
| assert "Test failed" in result or "exit code 1" in result | ||
| assert "Testing Farm test failed" in result | ||
|
|
||
|
|
||
| if __name__ == '__main__': | ||
| # Run tests if executed directly | ||
| test_tmt_prepare_quoting() | ||
| # Run async tests | ||
| asyncio.run(test_get_compose_from_branch()) | ||
| asyncio.run(test_run_testing_farm_test_success()) | ||
| asyncio.run(test_run_testing_farm_test_failure()) | ||
| print("All tests passed!") |
This file contains hidden or 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
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rather send a request using
aiohttp.