From 719b5cc2e72640b2fde8600d1ab2946f934bdea3 Mon Sep 17 00:00:00 2001 From: Jennifer Power Date: Thu, 26 Oct 2023 16:39:19 -0400 Subject: [PATCH] test: add e2e scenarios for create-cd Signed-off-by: Jennifer Power --- tests/e2e/README.md | 6 +- tests/e2e/test_e2e.py | 199 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 175 insertions(+), 30 deletions(-) diff --git a/tests/e2e/README.md b/tests/e2e/README.md index 14ff575f..4890e635 100644 --- a/tests/e2e/README.md +++ b/tests/e2e/README.md @@ -44,4 +44,8 @@ To run the end-to-end tests, follow these steps: ## Additional Notes - The WireMock tool is used to mock Git server endpoints for testing. - Podman is used for container and pod management and to build the container image for the mock API server. -- In the future, we plan to provide an option to use pre-built trestle-bot container images from a registry instead of building them locally. \ No newline at end of file + +## Future Improvements +- Provide an option to use pre-built trestle-bot container images from a registry instead of building them locally. +- Create endpoints that mock GitHub and GitLab API calls for pull request creation. +- Add more end-to-end tests to cover more use cases. \ No newline at end of file diff --git a/tests/e2e/test_e2e.py b/tests/e2e/test_e2e.py index d99fb4a0..373c0c04 100644 --- a/tests/e2e/test_e2e.py +++ b/tests/e2e/test_e2e.py @@ -17,6 +17,7 @@ """E2E tests for the rules transform command.""" import argparse +import logging import pathlib import subprocess from typing import Dict, List, Tuple @@ -24,44 +25,33 @@ import pytest from git.repo import Repo from trestle.core.commands.init import InitCmd +from trestle.oscal.profile import Profile from tests.conftest import YieldFixture -from tests.testutils import args_dict_to_list, setup_rules_view +from tests.testutils import ( + args_dict_to_list, + load_from_json, + setup_for_profile, + setup_rules_view, +) from trestlebot.const import RULES_VIEW_DIR +logger = logging.getLogger(__name__) +logger.setLevel(logging.INFO) + image_name = "localhost/trestlebot:latest" mock_server_image_name = "localhost/mock-server:latest" pod_name = "trestlebot-e2e-pod" e2e_context = "tests/e2e" container_file = "Dockerfile" +test_prof = "simplified_nist_profile" +test_filter_prof = "simplified_filter_profile" + -# Define test cases and expected outcomes -test_cases: List[Tuple[Dict[str, str], int]] = [ - ( - { - "branch": "test", - "rules-view-path": RULES_VIEW_DIR, - "committer-name": "test", - "committer-email": "test@email.com", - "file-patterns": ".", - }, - 0, - ), - ( - { - "branch": "test", - "rules-view-path": RULES_VIEW_DIR, - "file-patterns": ".", - }, - 2, - ), -] - - -def build_image_command(data_path: str, command_args: Dict[str, str]) -> List[str]: - """Build a command to be run in the shell.""" +def build_transform_command(data_path: str, command_args: Dict[str, str]) -> List[str]: + """Build a command to be run in the shell for rules transform.""" return [ "podman", "run", @@ -79,6 +69,25 @@ def build_image_command(data_path: str, command_args: Dict[str, str]) -> List[st ] +def build_create_cd_command(data_path: str, command_args: Dict[str, str]) -> List[str]: + """Build a command to be run in the shell for create cd.""" + return [ + "podman", + "run", + "--pod", + pod_name, + "--entrypoint", + "trestlebot-create-cd", + "--rm", + "-v", + f"{data_path}:/trestle", + "-w", + "/trestle", + image_name, + *args_dict_to_list(command_args), + ] + + @pytest.fixture(scope="module") def podman_setup() -> YieldFixture[int]: """Build the trestlebot container image and run the mock server in a pod.""" @@ -127,12 +136,34 @@ def podman_setup() -> YieldFixture[int]: raise RuntimeError(f"Failed to clean up podman resources: {e}") -# Run each test case @pytest.mark.slow -@pytest.mark.parametrize("command_args, response", test_cases) +@pytest.mark.parametrize( + "test_name, command_args, response", + [ + ( + "success/happy path", + { + "branch": "test", + "rules-view-path": RULES_VIEW_DIR, + "committer-name": "test", + "committer-email": "test@email.com", + }, + 0, + ), + ( + "failure/missing args", + { + "branch": "test", + "rules-view-path": RULES_VIEW_DIR, + }, + 2, + ), + ], +) def test_rules_transform_e2e( tmp_repo: Tuple[str, Repo], podman_setup: int, + test_name: str, command_args: Dict[str, str], response: int, ) -> None: @@ -141,6 +172,8 @@ def test_rules_transform_e2e( # and the mock server is running assert podman_setup == 0 + logger.info(f"Running test: {test_name}") + tmp_repo_str, repo = tmp_repo tmp_repo_path = pathlib.Path(tmp_repo_str) @@ -163,7 +196,115 @@ def test_rules_transform_e2e( repo.create_remote("origin", url=remote_url) # Build the command to be run in the shell - command = build_image_command(tmp_repo_str, command_args) + command = build_transform_command(tmp_repo_str, command_args) + + # Run the command + run_response = subprocess.run(command, cwd=tmp_repo_path) + + # Get subprocess response + assert run_response.returncode == response + + +@pytest.mark.slow +@pytest.mark.parametrize( + "test_name, command_args, response", + [ + ( + "success/happy path", + { + "profile-name": test_prof, + "component-title": "test-comp", + "compdef-name": "test-compdef", + "component-description": "test", + "markdown-path": "markdown", + "branch": "test", + "committer-name": "test", + "committer-email": "test@email.com", + }, + 0, + ), + ( + "success/happy path with filtering", + { + "profile-name": test_prof, + "component-title": "test-comp", + "compdef-name": "test-compdef", + "component-description": "test", + "markdown-path": "markdown", + "branch": "test", + "committer-name": "test", + "committer-email": "test@email.com", + "filter-by-profile": test_filter_prof, + }, + 0, + ), + ( + "failure/missing args", + { + "component-title": "test-comp", + "compdef-name": "test-compdef", + "component-description": "test", + "markdown-path": "markdown", + "branch": "test", + "committer-name": "test", + "committer-email": "test@email.com", + }, + 2, + ), + ( + "failure/missing profile", + { + "profile-name": "fake", + "component-title": "test-comp", + "compdef-name": "test-compdef", + "component-description": "test", + "markdown-path": "markdown", + "branch": "test", + "committer-name": "test", + "committer-email": "test@email.com", + }, + 1, + ), + ], +) +def test_create_cd_e2e( + tmp_repo: Tuple[str, Repo], + podman_setup: int, + test_name: str, + command_args: Dict[str, str], + response: int, +) -> None: + """Test the trestlebot rules transform command.""" + # Check that the container image was built successfully + # and the mock server is running + assert podman_setup == 0 + + logger.info(f"Running test: {test_name}") + + tmp_repo_str, repo = tmp_repo + + tmp_repo_path = pathlib.Path(tmp_repo_str) + + # Create a trestle workspace in the temporary git repository + args = argparse.Namespace( + verbose=0, + trestle_root=tmp_repo_path, + full=True, + local=False, + govdocs=False, + ) + init = InitCmd() + init._run(args) + + # Load profiles into the environment + _ = setup_for_profile(tmp_repo_path, test_prof, "") + load_from_json(tmp_repo_path, test_filter_prof, test_filter_prof, Profile) + + remote_url = "http://localhost:8080/test.git" + repo.create_remote("origin", url=remote_url) + + # Build the command to be run in the shell + command = build_create_cd_command(tmp_repo_str, command_args) # Run the command run_response = subprocess.run(command, cwd=tmp_repo_path)