Skip to content
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

Update the name to test-report and add README for report workflow #3864

Merged
merged 3 commits into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
from manifests.component_manifest import Component, ComponentManifest, Components


class TestRunManifest(ComponentManifest['TestRunManifest', 'TestComponents']):
class TestReportManifest(ComponentManifest['TestReportManifest', 'TestComponents']):
"""
TestRunManifest contains the aggregated test results for the components.
TestReportManifest contains the aggregated test results for the components.

The format for schema version 1.0 is:
schema-version: '1.0'
Expand Down Expand Up @@ -149,7 +149,7 @@ def __to_dict__(self) -> dict:
}


TestRunManifest.VERSIONS = {"1.0": TestRunManifest}
TestReportManifest.VERSIONS = {"1.0": TestReportManifest}

TestComponent.__test__ = False # type: ignore[attr-defined]
TestRunManifest.__test__ = False # type: ignore[attr-defined]
TestReportManifest.__test__ = False # type: ignore[attr-defined]
24 changes: 24 additions & 0 deletions src/report_workflow/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#### Generate test-report manifest for each test.
The input requires a mandatory `test-manifest-path`, `--artifact-paths`, `--base-path`, `--test-type` and `--test-run-id`, optional `--output-path` and `--component` to automatically generate the test-report manifest after testing.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Add <required> and <optional> in the below table so that all information related to params is in one place

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Copy link
Member

@gaiksaya gaiksaya Aug 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove this from here and instead add more description what this workflow actually does.

Suggested change
The input requires a mandatory `test-manifest-path`, `--artifact-paths`, `--base-path`, `--test-type` and `--test-run-id`, optional `--output-path` and `--component` to automatically generate the test-report manifest after testing.
As the name specifies, the test report workflow helps to automatically generate a consolidated report of the tests run at distribution level along with commands to reproduce the error and associated failures.
These tests include integration tests, BWC tests.


*Usage*
```
./report.sh <test-manifest-path> --artifact-paths opensearch=<...> opensearch-dashboards=<...> --test-run-id <...> --test-type integ-test --base-path <...>
```
e.g.
```
./report.sh manifests/2.9.0/opensearch-2.9.0-test.yml -p opensearch=https://ci.opensearch.org/ci/dbc/distribution-build-opensearch/2.9.0/8172/linux/x64/tar --test-run-id 5328 --test-type integ-test --base-path https://ci.opensearch.org/ci/dbc/integ-test/2.9.0/8172/linux/x64/tar
```
The following options are available.

| name | description |
|----------------------|--------------------------------------------------------------------------------|
| test-manifest-path | Specify a test manifest path. |
| -p, --artifact-paths | Artifact paths of distributions used for testing. |
| --base-path | Base paths of testing logs. |
| --test-type | Type of tests report generates on. |
| --output-path | Specify the path location for the test-report manifest. |
| --test-run-id | Specify the unique execution id for the test. |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test-run-id should be equal to the the test runs build number right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this id will be used to retrieve the component yml.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you specify that it should match the test-run-id from already run tests? Seems like you can enter anything which is not right

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Just updated.

| --component | Specify a specific component or components instead of the entire distribution. |
| --verbose | Show more verbose output. |

2 changes: 1 addition & 1 deletion src/report_workflow/report_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def __init__(self) -> None:
parser.add_argument("--base-path", type=str, default="",
help="Specify base paths for the integration test logs.")
parser.add_argument("--test-type", type=str, default="integ-test", help="Specify test type of this.")
parser.add_argument("--output-path", type=str, help="Specify the path location for the test-run manifest.")
parser.add_argument("--output-path", type=str, help="Specify the path location for the test-report manifest.")
parser.add_argument("--test-run-id", type=int, help="The unique execution id for the test")
parser.add_argument("--component", type=str, dest="components", nargs='*', help="Test a specific component or components instead of the entire distribution.")
parser.add_argument(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,22 @@
import yaml

from manifests.test_manifest import TestManifest
from manifests.test_run_manifest import TestRunManifest
from manifests.test_report_manifest import TestReportManifest
from report_workflow.report_args import ReportArgs


class TestRunRunner:
class TestReportRunner:
args: ReportArgs
test_manifest: TestManifest
tests_dir: str
test_run_manifest: TestRunManifest
test_report_manifest: TestReportManifest
test_run_data: dict

def __init__(self, args: ReportArgs, test_manifest: TestManifest) -> None:
self.args = args
self.base_path = args.base_path
self.test_manifest = test_manifest
self.test_run_data = self.test_run_manifest_data_template("manifest")
self.test_run_data = self.test_report_manifest_data_template("manifest")
self.product_name = test_manifest.__to_dict__().get("name")
self.name = self.product_name.replace(" ", "-").lower()
self.components = self.args.components
Expand Down Expand Up @@ -63,13 +63,13 @@
return test_run_data

def generate_report(self, data: dict, output_dir: str) -> Any:
test_run_manifest = TestRunManifest(data)
test_run_manifetest_run_manifest_file = os.path.join(output_dir, "test-run.yml")
logging.info(f"Generating test-run.yml in {output_dir}")
return test_run_manifest.to_file(test_run_manifetest_run_manifest_file)
test_report_manifest = TestReportManifest(data)
test_report_manifest_file = os.path.join(output_dir, "test-report.yml")
logging.info(f"Generating test-report.yml in {output_dir}")
return test_report_manifest.to_file(test_report_manifest_file)

Check warning on line 69 in src/report_workflow/test_report_runner.py

View check run for this annotation

Codecov / codecov/patch

src/report_workflow/test_report_runner.py#L66-L69

Added lines #L66 - L69 were not covered by tests

def component_entry(self, component_name: str) -> Any:
component = self.test_run_manifest_data_template("component")
component = self.test_report_manifest_data_template("component")
component["name"] = component_name
component["command"] = generate_test_command(self.test_type, self.test_manifest_path, self.artifact_paths, component_name)

Expand Down Expand Up @@ -102,7 +102,7 @@
component["configs"].append(config_dict)
return component

def test_run_manifest_data_template(self, template_type: str) -> Any:
def test_report_manifest_data_template(self, template_type: str) -> Any:
templates = {
"manifest": {
"schema-version": "1.0",
Expand Down Expand Up @@ -134,4 +134,4 @@
return command


TestRunRunner.__test__ = False # type:ignore
TestReportRunner.__test__ = False # type:ignore
8 changes: 4 additions & 4 deletions src/run_test_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from manifests.test_manifest import TestManifest
from report_workflow.report_args import ReportArgs
from report_workflow.test_run_runner import TestRunRunner
from report_workflow.test_report_runner import TestReportRunner
from system import console


Expand All @@ -21,11 +21,11 @@ def main() -> Any:

test_manifest = TestManifest.from_path(args.test_manifest_path)

test_run_runner = TestRunRunner(args, test_manifest)
test_report_runner = TestReportRunner(args, test_manifest)

test_run_data = test_run_runner.update_data()
test_report_data = test_report_runner.update_data()

test_run = test_run_runner.generate_report(test_run_data, args.output_path or os.getcwd())
test_run = test_report_runner.generate_report(test_report_data, args.output_path or os.getcwd())

return test_run

Expand Down
2 changes: 1 addition & 1 deletion tests/test_run_test_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def test_usage(self, *mocks: Any) -> None:
self.assertTrue(out.startswith("usage:"))

@patch("argparse._sys.argv", ["run_test_report.py", TEST_MANIFEST_PATH, "-p", "opensearch=foo"])
@patch('run_test_report.TestRunRunner')
@patch('run_test_report.TestReportRunner')
def test_main(self, runner_mock: Mock, *mocks: Any) -> None:

main()
Expand Down
6 changes: 3 additions & 3 deletions tests/tests_manifests/test_test_run_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@

import yaml

from manifests.test_run_manifest import TestRunManifest
from manifests.test_report_manifest import TestReportManifest


class TestTestRunManifest(unittest.TestCase):
class TestTestReportManifest(unittest.TestCase):

def setUp(self) -> None:
self.maxDiff = None
self.data_path = os.path.realpath(os.path.join(os.path.dirname(__file__), "data"))
self.manifest_filename = os.path.join(self.data_path, "test-run.yml")
self.manifest = TestRunManifest.from_path(self.manifest_filename)
self.manifest = TestReportManifest.from_path(self.manifest_filename)

def test_test_run(self) -> None:
self.assertEqual(self.manifest.name, "OpenSearch")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
from unittest.mock import MagicMock, call, mock_open, patch

from manifests.test_manifest import TestManifest
from report_workflow.test_run_runner import TestRunRunner
from report_workflow.test_report_runner import TestReportRunner


class TestTestRunRunner(unittest.TestCase):
class TestTestReportRunner(unittest.TestCase):
TEST_MANIFEST_PATH = os.path.join(
os.path.dirname(__file__), "data", "test_manifest.yml"
)
Expand All @@ -35,7 +35,7 @@ def test_runner_init(self, report_args_mock: MagicMock, test_manifest_mock: Magi
report_args_mock.test_run_id = 123
report_args_mock.test_type = "integ-test"

test_run_runner = TestRunRunner(report_args_mock, self.TEST_MANIFEST)
test_run_runner = TestReportRunner(report_args_mock, self.TEST_MANIFEST)
self.assertEqual(test_run_runner.name, "opensearch")
self.assertEqual(test_run_runner.test_run_id, 123)
self.assertEqual(test_run_runner.test_type, "integ-test")
Expand All @@ -49,7 +49,7 @@ def test_runner_update_test_run_data_local(self, report_args_mock: MagicMock, te
report_args_mock.test_run_id = 123
report_args_mock.test_type = "integ-test"

test_run_dict = TestRunRunner(report_args_mock, self.TEST_MANIFEST).update_test_run_data()
test_run_dict = TestReportRunner(report_args_mock, self.TEST_MANIFEST).update_test_run_data()
self.assertEqual(test_run_dict.get("Command"), " ".join(["./test.sh", "integ-test", self.TEST_MANIFEST_PATH, "--paths", "opensearch=foo/bar"]))
self.assertEqual(test_run_dict.get("TestType"), "integ-test")
self.assertEqual(test_run_dict.get("TestManifest"), self.TEST_MANIFEST_PATH)
Expand All @@ -64,7 +64,7 @@ def test_runner_update_test_run_data_url(self, report_args_mock: MagicMock, test
report_args_mock.test_run_id = 123
report_args_mock.test_type = "integ-test"

test_run_dict = TestRunRunner(report_args_mock, self.TEST_MANIFEST).update_test_run_data()
test_run_dict = TestReportRunner(report_args_mock, self.TEST_MANIFEST).update_test_run_data()
self.assertEqual(test_run_dict.get("Command"), " ".join(["./test.sh", "integ-test", self.TEST_MANIFEST_PATH, "--paths", "opensearch=https://foo/bar"]))
self.assertEqual(test_run_dict.get("TestType"), "integ-test")
self.assertEqual(test_run_dict.get("TestManifest"), self.TEST_MANIFEST_PATH)
Expand All @@ -86,7 +86,7 @@ def test_runner_component_entry_url(self, report_args_mock: MagicMock, validator
yaml_safe_load_mock.return_value = {"test_result": "PASS"}
urlopen_mock.return_value = MagicMock()

test_run_component_dict = TestRunRunner(report_args_mock, self.TEST_MANIFEST).component_entry("geospatial")
test_run_component_dict = TestReportRunner(report_args_mock, self.TEST_MANIFEST).component_entry("geospatial")
urlopen_mock.assert_has_calls([call('https://ci.opensearch.org/ci/dbc/mock/test-results/123/integ-test/geospatial/with-security/geospatial.yml')])
self.assertEqual(test_run_component_dict.get("configs")[0]["status"], "PASS")
self.assertEqual(test_run_component_dict.get("configs")[0]["name"], "with-security")
Expand All @@ -107,7 +107,7 @@ def test_runner_component_entry_local(self, report_args_mock: MagicMock, validat
yaml_safe_load_mock.return_value = {"test_result": "PASS"}
mock_open.return_value = MagicMock()

test_run_component_dict = TestRunRunner(report_args_mock, self.TEST_MANIFEST).component_entry("geospatial")
test_run_component_dict = TestReportRunner(report_args_mock, self.TEST_MANIFEST).component_entry("geospatial")
mock_open.assert_has_calls([call('https://ci.opensearch.org/ci/dbc/mock/test-results/123/integ-test/geospatial/with-security/geospatial.yml', 'r', encoding='utf8')])
self.assertEqual(test_run_component_dict.get("configs")[0]["status"], "PASS")
self.assertEqual(test_run_component_dict.get("configs")[0]["name"], "with-security")
Expand All @@ -125,7 +125,7 @@ def test_runner_component_entry_url_invalid(self, report_args_mock: MagicMock, v

validators_mock.return_value = True

test_run_component_dict = TestRunRunner(report_args_mock, self.TEST_MANIFEST).component_entry("geospatial")
test_run_component_dict = TestReportRunner(report_args_mock, self.TEST_MANIFEST).component_entry("geospatial")
self.assertEqual(test_run_component_dict.get("configs")[0]["status"], "Not Available")
self.assertEqual(test_run_component_dict.get("configs")[0]["name"], "with-security")
self.assertEqual(test_run_component_dict.get("configs")[0]["yml"], "URL not available")
Expand All @@ -145,7 +145,7 @@ def test_runner_component_entry_local_invalid(self, report_args_mock: MagicMock,
yaml_safe_load_mock.return_value = {"test_result": "PASS"}
mock_open.side_effect = FileNotFoundError

test_run_component_dict = TestRunRunner(report_args_mock, self.TEST_MANIFEST).component_entry("geospatial")
test_run_component_dict = TestReportRunner(report_args_mock, self.TEST_MANIFEST).component_entry("geospatial")
mock_open.assert_has_calls([call('https://ci.opensearch.org/ci/dbc/mock/test-results/123/integ-test/geospatial/with-security/geospatial.yml', 'r', encoding='utf8')])
self.assertEqual(test_run_component_dict.get("configs")[0]["status"], "Not Available")
self.assertEqual(test_run_component_dict.get("configs")[0]["name"], "with-security")
Expand Down
Loading