diff --git a/manifests/2.15.0/opensearch-dashboards-2.15.0-test.yml b/manifests/2.15.0/opensearch-dashboards-2.15.0-test.yml index 039159de92..d1a4216bd2 100644 --- a/manifests/2.15.0/opensearch-dashboards-2.15.0-test.yml +++ b/manifests/2.15.0/opensearch-dashboards-2.15.0-test.yml @@ -18,6 +18,7 @@ components: logging.json: false data.search.aggs.shardDelay.enabled: true csp.warnLegacyBrowsers: false + ci-groups: 9 - name: alertingDashboards integ-test: test-configs: diff --git a/src/manifests/test_manifest.py b/src/manifests/test_manifest.py index c345b96bae..428743454f 100644 --- a/src/manifests/test_manifest.py +++ b/src/manifests/test_manifest.py @@ -77,6 +77,7 @@ class TestManifest(ComponentManifest['TestManifest', 'TestComponents']): }, "test-configs": {"type": "list", "allowed": ["with-security", "without-security"]}, "additional-cluster-configs": {"type": "dict"}, + "ci-groups": {"type": "integer"} }, }, "bwc-test": { diff --git a/src/test_workflow/integ_test/integ_test_runner.py b/src/test_workflow/integ_test/integ_test_runner.py index e2959a5c31..a9f410057b 100644 --- a/src/test_workflow/integ_test/integ_test_runner.py +++ b/src/test_workflow/integ_test/integ_test_runner.py @@ -43,10 +43,19 @@ def run(self) -> TestSuiteResults: if component.name in self.test_manifest.components: test_config = self.test_manifest.components[component.name] if test_config.integ_test: - test_suite = self.__create_test_suite__(component, test_config, work_dir.path) - test_results = test_suite.execute_tests() - [self.test_recorder.test_results_logs.generate_component_yml(result_data) for result_data in test_suite.result_data] - all_results.append(component.name, test_results) + if 'ci-groups' in test_config.integ_test.keys(): + orig_component_name = component.name + for i in range(1, test_config.integ_test['ci-groups'] + 1): + component.name = f"{orig_component_name}-ci-group-{i}" + test_suite = self.__create_test_suite__(component, test_config, work_dir.path) + test_results = test_suite.execute_tests() + [self.test_recorder.test_results_logs.generate_component_yml(result_data) for result_data in test_suite.result_data] + all_results.append(component.name, test_results) + else: + test_suite = self.__create_test_suite__(component, test_config, work_dir.path) + test_results = test_suite.execute_tests() + [self.test_recorder.test_results_logs.generate_component_yml(result_data) for result_data in test_suite.result_data] + all_results.append(component.name, test_results) else: logging.info(f"Skipping integ-tests for {component.name}, as it is currently not supported") else: diff --git a/src/test_workflow/integ_test/integ_test_suite_opensearch_dashboards.py b/src/test_workflow/integ_test/integ_test_suite_opensearch_dashboards.py index 6edc8500e2..68eb8146f1 100644 --- a/src/test_workflow/integ_test/integ_test_suite_opensearch_dashboards.py +++ b/src/test_workflow/integ_test/integ_test_suite_opensearch_dashboards.py @@ -59,8 +59,8 @@ def __init__( # Integ-tests for OSD now clones FunctionalTestDashboards Repository by default and points to integtest.sh from FunctionalTestDashboards for all OSD plugins self.repo = GitRepository( - build_manifest_opensearch_dashboards.components['functionalTestDashboards'].repository, - build_manifest_opensearch_dashboards.components['functionalTestDashboards'].ref, + 'https://github.com/SuZhou-Joe/opensearch-dashboards-functional-test.git', + 'reuse-ci-group', os.path.join(self.work_dir, self.component.name), test_config.working_directory ) diff --git a/tests/tests_test_workflow/test_integ_workflow/integ_test/test_integ_test_runner_opensearch_dashboards.py b/tests/tests_test_workflow/test_integ_workflow/integ_test/test_integ_test_runner_opensearch_dashboards.py index 7540a9e29f..de8a4346a2 100644 --- a/tests/tests_test_workflow/test_integ_workflow/integ_test/test_integ_test_runner_opensearch_dashboards.py +++ b/tests/tests_test_workflow/test_integ_workflow/integ_test/test_integ_test_runner_opensearch_dashboards.py @@ -6,7 +6,7 @@ # compatible open source license. import unittest -from unittest.mock import MagicMock, Mock, patch +from unittest.mock import MagicMock, Mock, call, patch from test_workflow.integ_test.integ_test_runner_opensearch_dashboards import IntegTestRunnerOpenSearchDashboards @@ -90,3 +90,81 @@ def test_with_integ_test(self, mock_temp: Mock, mock_test_recorder: Mock, mock_s mock_path, mock_test_recorder_object ) + + @patch("test_workflow.integ_test.integ_test_runner_opensearch_dashboards.IntegTestStartPropertiesOpenSearch") + @patch("test_workflow.integ_test.integ_test_runner_opensearch_dashboards.IntegTestStartPropertiesOpenSearchDashboards") + @patch("test_workflow.integ_test.integ_test_runner_opensearch_dashboards.IntegTestSuiteOpenSearchDashboards") + @patch("test_workflow.integ_test.integ_test_runner.TestRecorder") + @patch("test_workflow.integ_test.integ_test_runner.TemporaryDirectory") + def test_with_integ_test_ci_groups(self, mock_temp: Mock, mock_test_recorder: Mock, mock_suite: Mock, mock_properties: Mock, mock_properties_dependency: Mock) -> None: + self.args.paths = {"opensearch-dashboards": "test-path"} + self.args.component = "sql" + self.args.test_run_id = "12345" + + mock_test_config = MagicMock() + mock_test_config.integ_test = {'test-configs': ['with-security'], 'ci-groups': 3} + self.test_manifest.components = {"sql": mock_test_config} + + mock_build_manifest = MagicMock() + mock_components = MagicMock() + mock_component = MagicMock() + mock_component.name = "sql" + mock_components.select.return_value = [mock_component] + mock_build_manifest.components = mock_components + + mock_bundle_manifest = MagicMock() + mock_dependency_installer = MagicMock() + + mock_properties_object = MagicMock() + mock_properties_object.bundle_manifest = mock_bundle_manifest + mock_properties_object.build_manifest = mock_build_manifest + mock_properties_object.dependency_installer = mock_dependency_installer + + mock_properties.return_value = mock_properties_object + + mock_properties_dependency_object = MagicMock() + mock_properties_dependency_object.bundle_manifest = MagicMock() + mock_properties_dependency_object.build_manifest = MagicMock() + mock_properties_dependency_object.dependency_installer = MagicMock() + mock_properties_dependency.return_value = mock_properties_dependency_object + + mock_suite_object = MagicMock() + mock_test_results = MagicMock() + + mock_suite_object.execute_tests.return_value = mock_test_results + + mock_suite.return_value = mock_suite_object + + mock_path = MagicMock() + mock_temp.return_value.__enter__.return_value.path = mock_path + + mock_test_recorder_object = MagicMock() + mock_test_recorder.return_value = mock_test_recorder_object + + mock_suite_object.result_data.__iter__.return_value = [MagicMock(), MagicMock()] + + runner = IntegTestRunnerOpenSearchDashboards(self.args, self.test_manifest) + + # call the test target + results = runner.run() + + self.assertEqual(results["sql-ci-group-1"], mock_test_results) + self.assertEqual(results["sql-ci-group-2"], mock_test_results) + self.assertEqual(results["sql-ci-group-3"], mock_test_results) + + mock_suite_object.result_data.__iter__.assert_called() + mock_test_recorder_object.test_results_logs.generate_component_yml.assert_called() + + expected_call = call( + mock_properties_dependency_object.dependency_installer, + mock_properties_object.dependency_installer, + mock_component, + mock_test_config, + mock_properties_dependency_object.bundle_manifest, + mock_properties_object.bundle_manifest, + mock_properties_dependency_object.build_manifest, + mock_properties_object.build_manifest, + mock_path, + mock_test_recorder_object + ) + mock_suite.assert_has_calls([expected_call, expected_call, expected_call], any_order=True)