Skip to content

Commit e858592

Browse files
committed
Add mock data scripts and inventory files for role testing
1 parent 07d6aa3 commit e858592

21 files changed

+433
-76
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
"""
5+
Test class for HANA DB HA config validation tasks
6+
7+
This test class uses pytest to run functional tests on the HANA DB HA config validation tasks
8+
defined in roles/ha_db/tasks/ha-config.yml. It sets up a temporary test environment,
9+
mocks necessary Python modules and commands, and verifies the execution of the tasks.
10+
"""
11+
12+
import os
13+
import shutil
14+
from pathlib import Path
15+
import pytest
16+
from tests.roles.ha_db_hana.roles_testing_base_db import RolesTestingBaseDB
17+
18+
19+
class TestDbHaConfigValidation(RolesTestingBaseDB):
20+
"""
21+
Test class for HANA DB HA config validation tasks.
22+
"""
23+
24+
@pytest.fixture
25+
def hana_ha_config_tasks(self):
26+
"""
27+
Load the HANA DB HA config validation tasks from the YAML file.
28+
29+
:return: Parsed YAML content of the tasks file.
30+
:rtype: dict
31+
"""
32+
return self.file_operations(
33+
operation="read",
34+
file_path=Path(__file__).parent.parent.parent
35+
/ "src/roles/ha_db_hana/tasks/ha-config.yml",
36+
)
37+
38+
@pytest.fixture
39+
def test_environment(self, ansible_inventory):
40+
"""
41+
Set up a temporary test environment for the HANA DB HA config validation tasks.
42+
43+
:param ansible_inventory: Path to the Ansible inventory file.
44+
:type ansible_inventory: str
45+
:yield temp_dir: Path to the temporary test environment.
46+
:ytype: str
47+
"""
48+
49+
temp_dir = self.setup_test_environment(
50+
role_type="ha_db_hana",
51+
ansible_inventory=ansible_inventory,
52+
task_name="ha-config",
53+
task_description="The HANA DB HA config validation test validates the DB cluster "
54+
+ "configuration and other system configuration",
55+
module_names=[
56+
"project/library/get_pcmk_properties_db",
57+
"project/library/log_parser",
58+
"project/library/send_telemetry_data",
59+
"project/library/get_package_list",
60+
"bin/crm_resource",
61+
"bin/crm",
62+
],
63+
)
64+
65+
os.makedirs(f"{temp_dir}/project/roles/ha_db_hana/tasks/files", exist_ok=True)
66+
self.file_operations(
67+
operation="write",
68+
file_path=f"{temp_dir}/project/roles/ha_db_hana/tasks/files/constants.yaml",
69+
content=self.file_operations(
70+
operation="read",
71+
file_path=Path(__file__).parent.parent / "mock_data/cluster_config.txt",
72+
),
73+
)
74+
75+
os.makedirs(f"{temp_dir}/project/library", exist_ok=True)
76+
self.file_operations(
77+
operation="write",
78+
file_path=f"{temp_dir}/project/library/uri",
79+
content=self.file_operations(
80+
operation="read",
81+
file_path=Path(__file__).parent.parent / "mock_data/azure_metadata.txt",
82+
),
83+
)
84+
os.chmod(f"{temp_dir}/project/library/uri", 0o755)
85+
86+
yield temp_dir
87+
shutil.rmtree(temp_dir)
88+
89+
def test_ha_config_validation_success(self, test_environment, ansible_inventory):
90+
"""
91+
Test the HANA DB HA config validation tasks using Ansible Runner.
92+
93+
:param test_environment: Path to the temporary test environment.
94+
:type test_environment: str
95+
:param ansible_inventory: Path to the Ansible inventory file.
96+
:type ansible_inventory: str
97+
"""
98+
result = self.run_ansible_playbook(
99+
test_environment=test_environment, inventory_file_name="inventory_db.txt"
100+
)
101+
102+
assert result.rc == 0, (
103+
f"Playbook failed with status: {result.rc}\n"
104+
f"STDOUT: {result.stdout.read() if result.stdout else 'No output'}\n"
105+
f"STDERR: {result.stderr.read() if result.stderr else 'No errors'}\n"
106+
f"Events: {[e.get('event') for e in result.events if 'event' in e]}"
107+
)
108+
109+
ok_events, failed_events = [], []
110+
for event in result.events:
111+
if event.get("event") == "runner_on_ok":
112+
ok_events.append(event)
113+
elif event.get("event") == "runner_on_failed":
114+
failed_events.append(event)
115+
116+
assert len(ok_events) > 0
117+
assert len(failed_events) == 0
118+
119+
for event in ok_events:
120+
task = event.get("event_data", {}).get("task")
121+
task_result = event.get("event_data", {}).get("res")
122+
if "Create package dictionary" in task:
123+
assert task_result.get("changed") is False
124+
assert task_result["details"][1].get("Corosync").get("version") == "2.4.5"
125+
if "Virtual Machine name" in task:
126+
assert task_result.get("changed") is False
127+
if "HA Configuration check" in task:
128+
assert task_result.get("changed") is False
129+
assert (
130+
task_result["details"].get("parameters", {})[1].get("name")
131+
== "migration-threshold"
132+
)
133+
assert task_result["details"].get("parameters", {})[1].get("value") == "3"
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
"""
5+
Base class for testing roles in Ansible playbooks.
6+
This class provides a framework for setting up and tearing down test environments,
7+
mocking necessary modules, and executing Ansible tasks.
8+
"""
9+
10+
from typing import Iterator
11+
from pathlib import Path
12+
import pytest
13+
from tests.roles.roles_testing_base import RolesTestingBase
14+
15+
16+
class RolesTestingBaseDB(RolesTestingBase):
17+
"""
18+
Base class for testing roles in Ansible playbooks.
19+
"""
20+
21+
@pytest.fixture
22+
def ansible_inventory(self) -> Iterator[str]:
23+
"""
24+
Create a temporary Ansible inventory file for testing.
25+
This inventory contains two hosts (db01 and db02) with local connections.
26+
27+
:yield inventory_path: Path to the temporary inventory file.
28+
:ytype: Iterator[str]
29+
"""
30+
inventory_content = self.file_operations(
31+
operation="read",
32+
file_path=Path(__file__).parent.parent / "mock_data/inventory_db.txt",
33+
)
34+
35+
inventory_path = Path(__file__).parent / "test_inventory.ini"
36+
self.file_operations(
37+
operation="write",
38+
file_path=inventory_path,
39+
content=inventory_content,
40+
)
41+
42+
yield str(inventory_path)
43+
44+
inventory_path.unlink(missing_ok=True)

tests/roles/ha_scs/ascs_migration_test.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
import shutil
1313
from pathlib import Path
1414
import pytest
15-
from tests.roles.ha_scs.roles_testing_base import RolesTestingBase
15+
from tests.roles.ha_scs.roles_testing_base_scs import RolesTestingBaseSCS
1616

1717

18-
class TestASCSMigration(RolesTestingBase):
18+
class TestASCSMigration(RolesTestingBaseSCS):
1919
"""
2020
Test class for ASCS migration tasks.
2121
"""
@@ -57,6 +57,7 @@ def test_environment(self, ansible_inventory):
5757
]
5858

5959
temp_dir = self.setup_test_environment(
60+
role_type="ha_scs",
6061
ansible_inventory=ansible_inventory,
6162
task_name="ascs-migration",
6263
task_description="The Resource Migration test validates planned failover scenarios",
@@ -67,7 +68,7 @@ def test_environment(self, ansible_inventory):
6768
"bin/crm_resource",
6869
"bin/crm",
6970
],
70-
extra_vars_override={"commands": commands},
71+
extra_vars_override={"commands": commands, "node_tier": "scs"},
7172
)
7273

7374
yield temp_dir
@@ -83,7 +84,7 @@ def test_functional_ascs_migration_success(self, test_environment, ansible_inven
8384
:type ansible_inventory: str
8485
"""
8586
result = self.run_ansible_playbook(
86-
test_environment=test_environment,
87+
test_environment=test_environment, inventory_file_name="inventory_scs.txt"
8788
)
8889

8990
assert result.rc == 0, (

tests/roles/ha_scs/ascs_node_crash_test.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
import shutil
1313
from pathlib import Path
1414
import pytest
15-
from tests.roles.ha_scs.roles_testing_base import RolesTestingBase
15+
from tests.roles.ha_scs.roles_testing_base_scs import RolesTestingBaseSCS
1616

1717

18-
class TestASCSNodeCrash(RolesTestingBase):
18+
class TestASCSNodeCrash(RolesTestingBaseSCS):
1919
"""
2020
Test class for ASCS node crash tasks.
2121
"""
@@ -45,6 +45,7 @@ def test_environment(self, ansible_inventory):
4545
:ytype: str
4646
"""
4747
temp_dir = self.setup_test_environment(
48+
role_type="ha_scs",
4849
ansible_inventory=ansible_inventory,
4950
task_name="ascs-node-crash",
5051
task_description="Simulate ASCS node crash",
@@ -55,6 +56,9 @@ def test_environment(self, ansible_inventory):
5556
"bin/crm_resource",
5657
"bin/echo",
5758
],
59+
extra_vars_override={
60+
"node_tier": "scs",
61+
},
5862
)
5963

6064
yield temp_dir
@@ -70,7 +74,7 @@ def test_functional_ascs_node_crash_success(self, test_environment, ansible_inve
7074
:type ansible_inventory: str
7175
"""
7276
result = self.run_ansible_playbook(
73-
test_environment=test_environment,
77+
test_environment=test_environment, inventory_file_name="inventory_scs.txt"
7478
)
7579

7680
assert result.rc == 0, (

tests/roles/ha_scs/ha_config_test.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
import shutil
1414
from pathlib import Path
1515
import pytest
16-
from tests.roles.ha_scs.roles_testing_base import RolesTestingBase
16+
from tests.roles.ha_scs.roles_testing_base_scs import RolesTestingBaseSCS
1717

1818

19-
class TestASCSHaConfigValidation(RolesTestingBase):
19+
class TestASCSHaConfigValidation(RolesTestingBaseSCS):
2020
"""
2121
Test class for ASCS HA config validation tasks.
2222
"""
@@ -46,6 +46,7 @@ def test_environment(self, ansible_inventory):
4646
"""
4747

4848
temp_dir = self.setup_test_environment(
49+
role_type="ha_scs",
4950
ansible_inventory=ansible_inventory,
5051
task_name="ha-config",
5152
task_description="The ASCS HA config validation test validates the SCS/ERS cluster "
@@ -57,6 +58,9 @@ def test_environment(self, ansible_inventory):
5758
"bin/crm_resource",
5859
"bin/crm",
5960
],
61+
extra_vars_override={
62+
"node_tier": "scs",
63+
},
6064
)
6165

6266
os.makedirs(f"{temp_dir}/project/roles/ha_scs/tasks/files", exist_ok=True)
@@ -65,7 +69,7 @@ def test_environment(self, ansible_inventory):
6569
file_path=f"{temp_dir}/project/roles/ha_scs/tasks/files/constants.yaml",
6670
content=self.file_operations(
6771
operation="read",
68-
file_path=Path(__file__).parent / "mock_data/cluster_config.txt",
72+
file_path=Path(__file__).parent.parent / "mock_data/cluster_config.txt",
6973
),
7074
)
7175

@@ -75,7 +79,7 @@ def test_environment(self, ansible_inventory):
7579
file_path=f"{temp_dir}/project/library/uri",
7680
content=self.file_operations(
7781
operation="read",
78-
file_path=Path(__file__).parent / "mock_data/azure_metadata.txt",
82+
file_path=Path(__file__).parent.parent / "mock_data/azure_metadata.txt",
7983
),
8084
)
8185
os.chmod(f"{temp_dir}/project/library/uri", 0o755)
@@ -93,7 +97,7 @@ def test_ha_config_validation_success(self, test_environment, ansible_inventory)
9397
:type ansible_inventory: str
9498
"""
9599
result = self.run_ansible_playbook(
96-
test_environment=test_environment,
100+
test_environment=test_environment, inventory_file_name="inventory_scs.txt"
97101
)
98102

99103
assert result.rc == 0, (
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
"""
5+
Base class for testing roles in Ansible playbooks.
6+
This class provides a framework for setting up and tearing down test environments,
7+
mocking necessary modules, and executing Ansible tasks.
8+
"""
9+
10+
from typing import Iterator
11+
from pathlib import Path
12+
import pytest
13+
from tests.roles.roles_testing_base import RolesTestingBase
14+
15+
16+
class RolesTestingBaseSCS(RolesTestingBase):
17+
"""
18+
Base class for testing roles in Ansible playbooks.
19+
"""
20+
21+
@pytest.fixture
22+
def ansible_inventory(self) -> Iterator[str]:
23+
"""
24+
Create a temporary Ansible inventory file for testing.
25+
This inventory contains two hosts (scs01 and scs02) with local connections.
26+
27+
:yield inventory_path: Path to the temporary inventory file.
28+
:ytype: Iterator[str]
29+
"""
30+
inventory_content = self.file_operations(
31+
operation="read",
32+
file_path=Path(__file__).parent.parent / "mock_data/inventory_scs.txt",
33+
)
34+
35+
inventory_path = Path(__file__).parent / "test_inventory.ini"
36+
self.file_operations(
37+
operation="write",
38+
file_path=inventory_path,
39+
content=inventory_content,
40+
)
41+
42+
yield str(inventory_path)
43+
44+
inventory_path.unlink(missing_ok=True)
File renamed without changes.

0 commit comments

Comments
 (0)