Skip to content

Commit

Permalink
Add 1.1 version of test report yml with bundle and rc information (#4887
Browse files Browse the repository at this point in the history
)

Signed-off-by: Peter Zhu <[email protected]>
  • Loading branch information
peterzhuamazon authored Jul 31, 2024
1 parent 6898b1e commit 76a1313
Show file tree
Hide file tree
Showing 9 changed files with 446 additions and 41 deletions.
165 changes: 165 additions & 0 deletions src/manifests/test_report/test_report_manifest_1_0.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# Copyright OpenSearch Contributors
# SPDX-License-Identifier: Apache-2.0
#
# The OpenSearch Contributors require contributions made to
# this file be licensed under the Apache-2.0 license or a
# compatible open source license.

from typing import Optional

from manifests.component_manifest import Component, ComponentManifest, Components


class TestReportManifest_1_0(ComponentManifest['TestReportManifest_1_0', 'TestComponents_1_0']):
"""
TestReportManifest contains the aggregated test results for the components.
The format for schema version 1.0 is:
schema-version: '1.0'
name: name of the product e.g. OpenSearch
test-run:
Command: command to trigger the integ test
TestType: type of test this manifest reports. e.g. integ-test
TestManifest: location of the test manifest used
DistributionManifest: URL or local path of the bundle manifest.
TestID: test id
components:
- name: sql
command: command to trigger the integ test for only sql component
configs:
- name: with-security
status: the status of the test run with this config. e.g. pass/fail
yml: URL or local path to the component yml file
cluster_stdout:
- URL or local path to the OpenSearch cluster logs
cluster_stderr:
- URL or local path to the OpenSearch cluster error logs
"""

SCHEMA = {
"schema-version": {"required": True, "type": "string", "allowed": ["1.0"]},
"name": {"required": True, "type": "string", "allowed": ["OpenSearch", "OpenSearch Dashboards"]},
"test-run": {
"required": False,
"type": "dict",
"schema": {
"Command": {"required": False, "type": "string"},
"TestType": {"required": False, "type": "string"},
"TestManifest": {"required": False, "type": "string"},
"DistributionManifest": {"required": False, "type": "string"},
"TestID": {"required": False, "type": "string"}
},
},
"components": {
"type": "list",
"schema": {
"type": "dict",
"schema": {
"name": {"required": True, "type": "string"},
"command": {"type": "string"},
"configs": {
"type": "list",
"schema": {
"type": "dict",
"schema": {
"name": {"type": "string"},
"status": {"type": "string"},
"yml": {"type": "string"},
"cluster_stdout": {"type": "list"},
"cluster_stderr": {"type": "list"}
}
},
},
},
},
},
}

def __init__(self, data: dict) -> None:
super().__init__(data)
self.name = str(data["name"])
self.test_run = self.TestRun(data.get("test-run", None))
self.components = TestComponents_1_0(data.get("components", [])) # type: ignore[assignment]

def __to_dict__(self) -> dict:
return {
"schema-version": "1.0",
"name": self.name,
"test-run": None if self.test_run is None else self.test_run.__to_dict__(),
"components": self.components.__to_dict__()
}

class TestRun:
def __init__(self, data: dict) -> None:
if data is None:
self.test_run = None
else:
self.command = data["Command"]
self.test_type = data["TestType"]
self.test_manifest = data["TestManifest"]
self.distribution_manifest = data["DistributionManifest"]
self.test_id = data["TestID"]

def __to_dict__(self) -> Optional[dict]:
if (self.command and self.test_type and self.test_manifest and self.distribution_manifest and self.test_id) is None:
return None
else:
return {
"Command": self.command,
"TestType": self.test_type,
"TestManifest": self.test_manifest,
"DistributionManifest": self.distribution_manifest,
"TestID": self.test_id
}


class TestComponents_1_0(Components['TestComponent_1_0']):
@classmethod
def __create__(self, data: dict) -> 'TestComponent_1_0':
return TestComponent_1_0(data)


class TestComponent_1_0(Component):
def __init__(self, data: dict) -> None:
super().__init__(data)
self.command = data["command"]
self.configs = self.TestComponentConfigs_1_0(data.get("configs", None))

def __to_dict__(self) -> dict:
return {
"name": self.name,
"command": self.command,
"configs": self.configs.__to_list__()
}

class TestComponentConfigs_1_0:
def __init__(self, data: list) -> None:
self.configs = []
for config in data:
self.configs.append(self.TestComponentConfig_1_0(config).__to_dict__())

def __to_list__(self) -> list:
return self.configs

class TestComponentConfig_1_0:
def __init__(self, data: dict) -> None:
self.name = data["name"]
self.status = data["status"]
self.yml = data["yml"]
self.cluster_stdout = data["cluster_stdout"]
self.cluster_stderr = data["cluster_stderr"]

def __to_dict__(self) -> dict:
return {
"name": self.name,
"status": self.status,
"yml": self.yml,
"cluster_stdout": self.cluster_stdout,
"cluster_stderr": self.cluster_stderr
}


TestReportManifest_1_0.VERSIONS = {"1.0": TestReportManifest_1_0}

TestComponent_1_0.__test__ = False # type: ignore[attr-defined]
TestReportManifest_1_0.__test__ = False # type: ignore[attr-defined]
40 changes: 35 additions & 5 deletions src/manifests/test_report_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,22 @@
from typing import Optional

from manifests.component_manifest import Component, ComponentManifest, Components
from manifests.test_report.test_report_manifest_1_0 import TestReportManifest_1_0


class TestReportManifest(ComponentManifest['TestReportManifest', 'TestComponents']):
"""
TestReportManifest contains the aggregated test results for the components.
The format for schema version 1.0 is:
schema-version: '1.0'
The format for schema version 1.1 is:
schema-version: '1.1'
name: name of the product e.g. OpenSearch
version: string
platform: linux, darwin or windows
architecture: x64 or arm64
distribution: tar, zip, deb and rpm
id: build id
rc: release candidate information
test-run:
Command: command to trigger the integ test
TestType: type of test this manifest reports. e.g. integ-test
Expand All @@ -36,9 +43,20 @@ class TestReportManifest(ComponentManifest['TestReportManifest', 'TestComponents
- URL or local path to the OpenSearch cluster error logs
"""

VERSIONS = {
"1.0": TestReportManifest_1_0,
# "1.1": current
}

SCHEMA = {
"schema-version": {"required": True, "type": "string", "allowed": ["1.0"]},
"schema-version": {"required": True, "type": "string", "allowed": ["1.1"]},
"name": {"required": True, "type": "string", "allowed": ["OpenSearch", "OpenSearch Dashboards"]},
"version": {"required": True, "type": "string"}, # added in 1.1
"platform": {"required": True, "type": "string"}, # added in 1.1
"architecture": {"required": True, "type": "string"}, # added in 1.1
"distribution": {"required": True, "type": "string"}, # added in 1.1
"id": {"required": True, "type": "string"}, # added in 1.1
"rc": {"required": True, "type": "string"}, # added in 1.1
"test-run": {
"required": False,
"type": "dict",
Expand Down Expand Up @@ -78,13 +96,25 @@ class TestReportManifest(ComponentManifest['TestReportManifest', 'TestComponents
def __init__(self, data: dict) -> None:
super().__init__(data)
self.name = str(data["name"])
self.version = str(data["version"])
self.platform = str(data["platform"])
self.architecture = str(data["architecture"])
self.distribution = str(data["distribution"])
self.build_id = str(data["id"])
self.release_candidate = str(data["rc"])
self.test_run = self.TestRun(data.get("test-run", None))
self.components = TestComponents(data.get("components", [])) # type: ignore[assignment]

def __to_dict__(self) -> dict:
return {
"schema-version": "1.0",
"schema-version": "1.1",
"name": self.name,
"version": self.version,
"platform": self.platform,
"architecture": self.architecture,
"distribution": self.distribution,
"id": self.build_id,
"rc": self.release_candidate,
"test-run": None if self.test_run is None else self.test_run.__to_dict__(),
"components": self.components.__to_dict__()
}
Expand Down Expand Up @@ -159,7 +189,7 @@ def __to_dict__(self) -> dict:
}


TestReportManifest.VERSIONS = {"1.0": TestReportManifest}
TestReportManifest.VERSIONS = {"1.0": TestReportManifest_1_0, "1.1": TestReportManifest}

TestComponent.__test__ = False # type: ignore[attr-defined]
TestReportManifest.__test__ = False # type: ignore[attr-defined]
3 changes: 3 additions & 0 deletions src/report_workflow/report_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class ReportArgs:
test_manifest_path: str
artifact_paths: dict
test_type: str
release_candidate: str
logging_level: int

def __init__(self) -> None:
Expand All @@ -33,6 +34,7 @@ def __init__(self) -> None:
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("--release-candidate", type=str, default="0", help="The release candidate (rc) information of the artifacts, added in schema-version='1.1'.")
parser.add_argument(
"-v", "--verbose", help="Show more verbose output.", action="store_const", default=logging.INFO, const=logging.DEBUG, dest="logging_level"
)
Expand All @@ -45,4 +47,5 @@ def __init__(self) -> None:
self.base_path = args.base_path
self.test_type = args.test_type
self.components = args.components
self.release_candidate = args.release_candidate
self.output_path = args.output_path
19 changes: 18 additions & 1 deletion src/report_workflow/test_report_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import validators
import yaml

from manifests.bundle_manifest import BundleManifest
from manifests.test_manifest import TestManifest
from manifests.test_report_manifest import TestReportManifest
from report_workflow.report_args import ReportArgs
Expand All @@ -26,11 +27,13 @@ class TestReportRunner:
tests_dir: str
test_report_manifest: TestReportManifest
test_run_data: dict
bundle_manifest: BundleManifest

def __init__(self, args: ReportArgs, test_manifest: TestManifest) -> None:
self.args = args
self.base_path = args.base_path
self.test_manifest = test_manifest
self.release_candidate = self.args.release_candidate
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()
Expand All @@ -48,6 +51,13 @@ def __init__(self, args: ReportArgs, test_manifest: TestManifest) -> None:

def update_data(self) -> dict:
self.test_run_data["name"] = self.product_name
self.bundle_manifest = BundleManifest.from_urlpath(self.dist_manifest)
self.test_run_data["version"] = self.bundle_manifest.build.version
self.test_run_data["platform"] = self.bundle_manifest.build.platform
self.test_run_data["architecture"] = self.bundle_manifest.build.architecture
self.test_run_data["distribution"] = self.bundle_manifest.build.distribution
self.test_run_data["id"] = self.bundle_manifest.build.id
self.test_run_data["rc"] = self.release_candidate
self.test_run_data["test-run"] = self.update_test_run_data()
for component in self.test_components.select(focus=self.args.components):
if self.test_manifest.components[component.name].__to_dict__().get(self.test_type) is not None:
Expand Down Expand Up @@ -109,8 +119,14 @@ def component_entry(self, component_name: str) -> Any:
def test_report_manifest_data_template(self, template_type: str) -> Any:
templates = {
"manifest": {
"schema-version": "1.0",
"schema-version": "1.1",
"name": "",
"version": "",
"platform": "",
"architecture": "",
"distribution": "",
"id": "",
"rc": "",
"test-run": {},
"components": []
},
Expand All @@ -120,6 +136,7 @@ def test_report_manifest_data_template(self, template_type: str) -> Any:
"configs": []
}
}

return templates[template_type]


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
schema-version: '1.1'
build:
name: OpenSearch Dashboards
version: 1.3.18
platform: linux
architecture: x64
distribution: tar
location: https://ci.opensearch.org/ci/dbc/distribution-build-opensearch-dashboards/1.3.18/7791/linux/x64/tar/dist/opensearch-dashboards/opensearch-dashboards-1.3.18-linux-x64.tar.gz
id: '7791'
components:
- name: OpenSearch-Dashboards
repository: https://github.com/opensearch-project/OpenSearch-Dashboards.git
ref: '1.3'
commit_id: 26d95c2bb5d43e3d540d4612884ff98f66938046
location: https://ci.opensearch.org/ci/dbc/distribution-build-opensearch-dashboards/1.3.18/7791/linux/x64/tar/builds/opensearch-dashboards/dist/opensearch-dashboards-min-1.3.18-linux-x64.tar.gz
- name: functionalTestDashboards
repository: https://github.com/opensearch-project/opensearch-dashboards-functional-test.git
ref: '1.3'
commit_id: 8b999677608cbe09f3f412ba1b3b57c9731a7ffc
- name: anomalyDetectionDashboards
repository: https://github.com/opensearch-project/anomaly-detection-dashboards-plugin
ref: '1.3'
commit_id: 1da96108484cf891f071ca54634b8df815dccec9
location: https://ci.opensearch.org/ci/dbc/distribution-build-opensearch-dashboards/1.3.18/7791/linux/x64/tar/builds/opensearch-dashboards/plugins/anomalyDetectionDashboards-1.3.18.zip
- name: ganttChartDashboards
repository: https://github.com/opensearch-project/dashboards-visualizations.git
ref: '1.3'
commit_id: 968bcf9f028e7fdd503eaf25e0c877efff0c9ed8
location: https://ci.opensearch.org/ci/dbc/distribution-build-opensearch-dashboards/1.3.18/7791/linux/x64/tar/builds/opensearch-dashboards/plugins/ganttChartDashboards-1.3.18.zip
- name: observabilityDashboards
repository: https://github.com/opensearch-project/dashboards-observability.git
ref: '1.3'
commit_id: a1d4df6bc56b04197f6fc3611c8e7aee6fd51b9f
location: https://ci.opensearch.org/ci/dbc/distribution-build-opensearch-dashboards/1.3.18/7791/linux/x64/tar/builds/opensearch-dashboards/plugins/observabilityDashboards-1.3.18.zip
- name: alertingDashboards
repository: https://github.com/opensearch-project/alerting-dashboards-plugin.git
ref: '1.3'
commit_id: 7c133586fec9cc4d0f3e4d98b2182e2e8563f3dc
location: https://ci.opensearch.org/ci/dbc/distribution-build-opensearch-dashboards/1.3.18/7791/linux/x64/tar/builds/opensearch-dashboards/plugins/alertingDashboards-1.3.18.zip
- name: indexManagementDashboards
repository: https://github.com/opensearch-project/index-management-dashboards-plugin
ref: '1.3'
commit_id: 189fd6b9d81059d4d0485e3a84e2aecebf020b58
location: https://ci.opensearch.org/ci/dbc/distribution-build-opensearch-dashboards/1.3.18/7791/linux/x64/tar/builds/opensearch-dashboards/plugins/indexManagementDashboards-1.3.18.zip
- name: reportsDashboards
repository: https://github.com/opensearch-project/dashboards-reporting.git
ref: '1.3'
commit_id: 45fa281c2f2f727b460d2d8cfdbb61d502046d73
location: https://ci.opensearch.org/ci/dbc/distribution-build-opensearch-dashboards/1.3.18/7791/linux/x64/tar/builds/opensearch-dashboards/plugins/reportsDashboards-1.3.18.zip
- name: securityDashboards
repository: https://github.com/opensearch-project/security-dashboards-plugin.git
ref: '1.3'
commit_id: 7d471b1db91f4452e1fb03ec31cea2862ff69017
location: https://ci.opensearch.org/ci/dbc/distribution-build-opensearch-dashboards/1.3.18/7791/linux/x64/tar/builds/opensearch-dashboards/plugins/securityDashboards-1.3.18.zip
- name: queryWorkbenchDashboards
repository: https://github.com/opensearch-project/dashboards-query-workbench.git
ref: '1.3'
commit_id: 38cebc903e5a3a3247b6493002f235d6389e535d
location: https://ci.opensearch.org/ci/dbc/distribution-build-opensearch-dashboards/1.3.18/7791/linux/x64/tar/builds/opensearch-dashboards/plugins/queryWorkbenchDashboards-1.3.18.zip
Loading

0 comments on commit 76a1313

Please sign in to comment.