Skip to content

Commit

Permalink
Updated integ-tests implementation to run all the OSD plugins. (#3316)
Browse files Browse the repository at this point in the history
Signed-off-by: Divya Madala <[email protected]>
  • Loading branch information
Divyaasm authored May 4, 2023
1 parent 401f71a commit 904abbc
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 92 deletions.
56 changes: 2 additions & 54 deletions src/test_workflow/integ_test/integ_test_suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,15 @@
# compatible open source license.

import abc
import json
import logging
import os
from pathlib import Path
from typing import Any, Dict

from git.git_repository import GitRepository
from manifests.build_manifest import BuildManifest
from manifests.bundle_manifest import BundleManifest
from paths.script_finder import ScriptFinder
from system.execute import execute
from test_workflow.dependency_installer import DependencyInstaller
from test_workflow.integ_test.topology import ClusterEndpoint, NodeEndpoint
from test_workflow.test_recorder.log_recorder import LogRecorder
from test_workflow.test_recorder.test_recorder import TestRecorder
from test_workflow.test_recorder.test_result_data import TestResultData
from test_workflow.test_result.test_component_results import TestComponentResults


Expand All @@ -33,7 +26,6 @@ class IntegTestSuite(abc.ABC):
dependency_installer: DependencyInstaller
bundle_manifest: BundleManifest
build_manifest: BuildManifest
repo: GitRepository
save_logs: LogRecorder
additional_cluster_config: dict

Expand Down Expand Up @@ -61,60 +53,16 @@ def __init__(
self.bundle_manifest = bundle_manifest
self.build_manifest = build_manifest

self.repo = GitRepository(
self.component.repository,
self.component.commit_id,
os.path.join(self.work_dir, self.component.name),
test_config.working_directory
)

self.save_logs = test_recorder.test_results_logs
self.additional_cluster_config = None

@abc.abstractmethod
def execute_tests(self) -> TestComponentResults:
pass

@abc.abstractmethod
def multi_execute_integtest_sh(self, cluster_endpoints: list, security: bool, test_config: str) -> int:
script = ScriptFinder.find_integ_test_script(self.component.name, self.repo.working_directory)

def custom_node_endpoint_encoder(node_endpoint: NodeEndpoint) -> dict:
return {"endpoint": node_endpoint.endpoint, "port": node_endpoint.port, "transport": node_endpoint.transport}
if os.path.exists(script):
if len(cluster_endpoints) == 1:
single_data_node = cluster_endpoints[0].data_nodes[0]
cmd = f"bash {script} -b {single_data_node.endpoint} -p {single_data_node.port} -s {str(security).lower()} -v {self.bundle_manifest.build.version}"
else:
endpoints_list = []
for cluster_details in cluster_endpoints:
endpoints_list.append(cluster_details.__dict__)
endpoints_string = json.dumps(endpoints_list, indent=0, default=custom_node_endpoint_encoder)
cmd = f"bash {script} -e '"
cmd = cmd + endpoints_string + "'"
cmd = cmd + f" -s {str(security).lower()} -v {self.bundle_manifest.build.version}"
self.repo_work_dir = os.path.join(
self.repo.dir, self.test_config.working_directory) if self.test_config.working_directory is not None else self.repo.dir
(status, stdout, stderr) = execute(cmd, self.repo_work_dir, True, False)
test_result_data = TestResultData(
self.component.name,
test_config,
status,
stdout,
stderr,
self.test_artifact_files
)
self.save_logs.save_test_result_data(test_result_data)
if stderr:
logging.info("Stderr reported for component: " + self.component.name)
logging.info(stderr)
return status
else:
logging.info(f"{script} does not exist. Skipping integ tests for {self.component.name}")
return 0

def execute_integtest_sh(self, endpoint: str, port: int, security: bool, test_config: str) -> int:
cluster_endpoint_port = [ClusterEndpoint("cluster1", [NodeEndpoint(endpoint, port, 9300)], [])]
return self.multi_execute_integtest_sh(cluster_endpoint_port, security, test_config)
pass

def is_security_enabled(self, config: str) -> bool:
if config in ["with-security", "without-security"]:
Expand Down
51 changes: 50 additions & 1 deletion src/test_workflow/integ_test/integ_test_suite_opensearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,29 @@
# compatible open source license.

import glob
import json
import logging
import os
from pathlib import Path
from typing import Any

from git.git_repository import GitRepository
from manifests.build_manifest import BuildManifest
from manifests.bundle_manifest import BundleManifest
from paths.script_finder import ScriptFinder
from system.execute import execute
from test_workflow.dependency_installer_opensearch import DependencyInstallerOpenSearch
from test_workflow.integ_test.integ_test_suite import IntegTestSuite, InvalidTestConfigError
from test_workflow.integ_test.topology import Topology
from test_workflow.integ_test.topology import NodeEndpoint, Topology
from test_workflow.test_recorder.test_recorder import TestRecorder
from test_workflow.test_recorder.test_result_data import TestResultData
from test_workflow.test_result.test_component_results import TestComponentResults
from test_workflow.test_result.test_result import TestResult


class IntegTestSuiteOpenSearch(IntegTestSuite):
dependency_installer: DependencyInstallerOpenSearch
repo: GitRepository

def __init__(
self,
Expand All @@ -43,6 +49,12 @@ def __init__(
bundle_manifest_opensearch,
build_manifest_opensearch
)
self.repo = GitRepository(
self.component.repository,
self.component.commit_id,
os.path.join(self.work_dir, self.component.name),
test_config.working_directory
)

def execute_tests(self) -> TestComponentResults:
test_results = TestComponentResults()
Expand Down Expand Up @@ -89,6 +101,43 @@ def __setup_cluster_and_execute_test_config(self, config: str) -> int:
self.pretty_print_message("Running integration tests for " + self.component.name + " " + config)
return self.multi_execute_integtest_sh(endpoints, security, config)

def multi_execute_integtest_sh(self, cluster_endpoints: list, security: bool, test_config: str) -> int:
script = ScriptFinder.find_integ_test_script(self.component.name, self.repo.working_directory)

def custom_node_endpoint_encoder(node_endpoint: NodeEndpoint) -> dict:
return {"endpoint": node_endpoint.endpoint, "port": node_endpoint.port, "transport": node_endpoint.transport}
if os.path.exists(script):
if len(cluster_endpoints) == 1:
single_data_node = cluster_endpoints[0].data_nodes[0]
cmd = f"bash {script} -b {single_data_node.endpoint} -p {single_data_node.port} -s {str(security).lower()} -v {self.bundle_manifest.build.version}"
else:
endpoints_list = []
for cluster_details in cluster_endpoints:
endpoints_list.append(cluster_details.__dict__)
endpoints_string = json.dumps(endpoints_list, indent=0, default=custom_node_endpoint_encoder)
cmd = f"bash {script} -e '"
cmd = cmd + endpoints_string + "'"
cmd = cmd + f" -s {str(security).lower()} -v {self.bundle_manifest.build.version}"
self.repo_work_dir = os.path.join(
self.repo.dir, self.test_config.working_directory) if self.test_config.working_directory is not None else self.repo.dir
(status, stdout, stderr) = execute(cmd, self.repo_work_dir, True, False)
test_result_data = TestResultData(
self.component.name,
test_config,
status,
stdout,
stderr,
self.test_artifact_files
)
self.save_logs.save_test_result_data(test_result_data)
if stderr:
logging.info("Stderr reported for component: " + self.component.name)
logging.info(stderr)
return status
else:
logging.info(f"{script} does not exist. Skipping integ tests for {self.component.name}")
return 0

@property
def test_artifact_files(self) -> dict:
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@
# this file be licensed under the Apache-2.0 license or a
# compatible open source license.

import logging
import os
from pathlib import Path

from git.git_repository import GitRepository
from manifests.build_manifest import BuildManifest
from manifests.bundle_manifest import BundleManifest
from manifests.test_manifest import TestComponent
from paths.script_finder import ScriptFinder
from system.execute import execute
from test_workflow.dependency_installer_opensearch import DependencyInstallerOpenSearch
from test_workflow.dependency_installer_opensearch_dashboards import DependencyInstallerOpenSearchDashboards
from test_workflow.integ_test.integ_test_suite import IntegTestSuite
from test_workflow.integ_test.local_test_cluster_opensearch_dashboards import LocalTestClusterOpenSearchDashboards
from test_workflow.integ_test.topology import ClusterEndpoint, NodeEndpoint
from test_workflow.test_recorder.test_recorder import TestRecorder
from test_workflow.test_recorder.test_result_data import TestResultData
from test_workflow.test_result.test_component_results import TestComponentResults
from test_workflow.test_result.test_result import TestResult

Expand All @@ -24,6 +30,7 @@ class IntegTestSuiteOpenSearchDashboards(IntegTestSuite):
dependency_installer_opensearch_dashboards: DependencyInstallerOpenSearchDashboards
bundle_manifest_opensearch_dashboards: BundleManifest
build_manifest_opensearch_dashboards: BuildManifest
repo: GitRepository

def __init__(
self,
Expand All @@ -49,6 +56,15 @@ def __init__(
build_manifest_opensearch
)

# 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'].commit_id,
os.path.join(self.work_dir, self.component.name),
test_config.working_directory
)

self.dependency_installer_opensearch_dashboards = dependency_installer_opensearch_dashboards
self.bundle_manifest_opensearch_dashboards = bundle_manifest_opensearch_dashboards
self.build_manifest_opensearch_dashboards = build_manifest_opensearch_dashboards
Expand Down Expand Up @@ -81,6 +97,38 @@ def __setup_cluster_and_execute_test_config(self, config: str) -> int:
os.chdir(self.work_dir)
return self.execute_integtest_sh(endpoint, port, security, config)

def multi_execute_integtest_sh(self, cluster_endpoints: list, security: bool, test_config: str) -> int:
script = ScriptFinder.find_integ_test_script(self.component.name, self.repo.working_directory)

def custom_node_endpoint_encoder(node_endpoint: NodeEndpoint) -> dict:
return {"endpoint": node_endpoint.endpoint, "port": node_endpoint.port, "transport": node_endpoint.transport}
if os.path.exists(script):
single_node = cluster_endpoints[0].data_nodes[0]
cmd = f"bash {script} -b {single_node.endpoint} -p {single_node.port} -s {str(security).lower()} -t {self.component.name} -v {self.bundle_manifest.build.version} -o default"
self.repo_work_dir = os.path.join(
self.repo.dir, self.test_config.working_directory) if self.test_config.working_directory is not None else self.repo.dir
(status, stdout, stderr) = execute(cmd, self.repo_work_dir, True, False)
test_result_data = TestResultData(
self.component.name,
test_config,
status,
stdout,
stderr,
self.test_artifact_files
)
self.save_logs.save_test_result_data(test_result_data)
if stderr:
logging.info("Stderr reported for component: " + self.component.name)
logging.info(stderr)
return status
else:
logging.info(f"{script} does not exist. Skipping integ tests for {self.component.name}")
return 0

def execute_integtest_sh(self, endpoint: str, port: int, security: bool, test_config: str) -> int:
cluster_endpoint_port = [ClusterEndpoint("cluster1", [NodeEndpoint(endpoint, port, 9300)], [])]
return self.multi_execute_integtest_sh(cluster_endpoint_port, security, test_config)

@property
def test_artifact_files(self) -> dict:
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
from manifests.build_manifest import BuildManifest
from manifests.bundle_manifest import BundleComponent, BundleManifest
from manifests.test_manifest import TestComponent, TestManifest
from test_workflow.integ_test.integ_test_suite import InvalidTestConfigError, ScriptFinder
from test_workflow.integ_test.integ_test_suite_opensearch import IntegTestSuiteOpenSearch, Topology
from test_workflow.integ_test.integ_test_suite_opensearch import IntegTestSuiteOpenSearch, InvalidTestConfigError, ScriptFinder, Topology


@patch("os.makedirs")
Expand Down Expand Up @@ -51,15 +50,15 @@ def test_execute_with_multiple_test_configs(self, mock_test_recorder: Mock, mock
mock_test_recorder
)
mock_topology.create().__enter__.return_value = [{"cluster_name": "cluster1", "data_nodes": [{"endpoint": "localhost", "port": 9200, "transport": 9300}], "cluster_manager_nodes": []}]
mock_execute_integtest_sh = MagicMock()
IntegTestSuiteOpenSearch.multi_execute_integtest_sh = mock_execute_integtest_sh # type: ignore
mock_execute_integtest_sh.return_value = "success"
mock_multi_execute_integtest_sh = MagicMock()
IntegTestSuiteOpenSearch.multi_execute_integtest_sh = mock_multi_execute_integtest_sh # type: ignore
mock_multi_execute_integtest_sh.return_value = "success"

test_results = integ_test_suite.execute_tests()
self.assertEqual(len(test_results), 2)
self.assertTrue(test_results.failed)

mock_execute_integtest_sh.assert_has_calls([
mock_multi_execute_integtest_sh.assert_has_calls([
call([{"cluster_name": "cluster1", "data_nodes": [{"endpoint": "localhost", "port": 9200, "transport": 9300}], "cluster_manager_nodes": []}], True, "with-security"),
call([{"cluster_name": "cluster1", "data_nodes": [{"endpoint": "localhost", "port": 9200, "transport": 9300}], "cluster_manager_nodes": []}], False, "without-security")
])
Expand All @@ -81,22 +80,21 @@ def test_execute_with_build_dependencies(self, mock_test_recorder: Mock, mock_to

mock_topology.create().__enter__.return_value = [{"cluster_name": "cluster1", "data_nodes": [{"endpoint": "localhost", "port": 9200, "transport": 9300}], "cluster_manager_nodes": []}]

mock_execute_integtest_sh = MagicMock()
IntegTestSuiteOpenSearch.multi_execute_integtest_sh = mock_execute_integtest_sh # type: ignore
mock_execute_integtest_sh.return_value = "success"
mock_multi_execute_integtest_sh = MagicMock()
IntegTestSuiteOpenSearch.multi_execute_integtest_sh = mock_multi_execute_integtest_sh # type: ignore
mock_multi_execute_integtest_sh.return_value = "success"

integ_test_suite.execute_tests()
dependency_installer.install_build_dependencies.assert_called_with(
{"opensearch-job-scheduler": "1.1.0.0"}, os.path.join(self.work_dir, "index-management", "src", "test", "resources", "job-scheduler")
)

mock_execute_integtest_sh.assert_has_calls([
call([{"cluster_name": "cluster1", "data_nodes": [{"endpoint": "localhost", "port": 9200, "transport": 9300}], "cluster_manager_nodes": []}], True, "with-security"),
call([{"cluster_name": "cluster1", "data_nodes": [{"endpoint": "localhost", "port": 9200, "transport": 9300}], "cluster_manager_nodes": []}], False, "without-security")
])
mock_multi_execute_integtest_sh.assert_has_calls([call(
[{"cluster_name": "cluster1", "data_nodes": [{"endpoint": "localhost", "port": 9200, "transport": 9300}], "cluster_manager_nodes": []}], False, "without-security")]
)

@patch("test_workflow.test_recorder.test_recorder.TestRecorder")
@patch("test_workflow.integ_test.integ_test_suite.execute")
@patch("test_workflow.integ_test.integ_test_suite_opensearch.execute")
def test_execute_without_build_dependencies(self, mock_execute: Mock, *mock: Any) -> None:
dependency_installer = MagicMock()
test_config, component = self.__get_test_config_and_bundle_component("job-scheduler")
Expand Down Expand Up @@ -180,13 +178,13 @@ def test_execute_with_working_directory(self, mock_test_recorder: Mock, mock_top
mock_topology.create().__enter__.return_value = [{"cluster_name": "cluster1", "data_nodes": [{"endpoint": "localhost", "port": 9200, "transport": 9300}], "cluster_manager_nodes": []}]
mock_script_finder.return_value = "integtest.sh"

mock_execute_integtest_sh = MagicMock()
IntegTestSuiteOpenSearch.multi_execute_integtest_sh = mock_execute_integtest_sh # type: ignore
mock_execute_integtest_sh.return_value = "success"
mock_multi_execute_integtest_sh = MagicMock()
IntegTestSuiteOpenSearch.multi_execute_integtest_sh = mock_multi_execute_integtest_sh # type: ignore
mock_multi_execute_integtest_sh.return_value = "success"

integ_test_suite.execute_tests() # type: ignore

mock_execute_integtest_sh.assert_called_with(
mock_multi_execute_integtest_sh.assert_called_with(
[{"cluster_name": "cluster1", "data_nodes": [{"endpoint": "localhost", "port": 9200, "transport": 9300}], "cluster_manager_nodes": []}],
True,
"with-security"
Expand Down
Loading

0 comments on commit 904abbc

Please sign in to comment.