Skip to content

Commit 07d6aa3

Browse files
committed
Add mock data and scripts for HA SCS role testing
1 parent a968230 commit 07d6aa3

16 files changed

+234
-10
lines changed
File renamed without changes.

tests/roles/ascs_migration_test.py renamed to tests/roles/ha_scs/ascs_migration_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import shutil
1313
from pathlib import Path
1414
import pytest
15-
from tests.roles.roles_testing_base import RolesTestingBase
15+
from tests.roles.ha_scs.roles_testing_base import RolesTestingBase
1616

1717

1818
class TestASCSMigration(RolesTestingBase):

tests/roles/ascs_node_crash_test.py renamed to tests/roles/ha_scs/ascs_node_crash_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import shutil
1313
from pathlib import Path
1414
import pytest
15-
from tests.roles.roles_testing_base import RolesTestingBase
15+
from tests.roles.ha_scs.roles_testing_base import RolesTestingBase
1616

1717

1818
class TestASCSNodeCrash(RolesTestingBase):
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
"""
5+
Test class for ASCS HA config validation tasks
6+
7+
This test class uses pytest to run functional tests on the ASCS HA config validation tasks
8+
defined in roles/ha_scs/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_scs.roles_testing_base import RolesTestingBase
17+
18+
19+
class TestASCSHaConfigValidation(RolesTestingBase):
20+
"""
21+
Test class for ASCS HA config validation tasks.
22+
"""
23+
24+
@pytest.fixture
25+
def ascs_migration_tasks(self):
26+
"""
27+
Load the ASCS 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 / "src/roles/ha_scs/tasks/ha-config.yml",
35+
)
36+
37+
@pytest.fixture
38+
def test_environment(self, ansible_inventory):
39+
"""
40+
Set up a temporary test environment for the ASCS HA config validation tasks.
41+
42+
:param ansible_inventory: Path to the Ansible inventory file.
43+
:type ansible_inventory: str
44+
:yield temp_dir: Path to the temporary test environment.
45+
:ytype: str
46+
"""
47+
48+
temp_dir = self.setup_test_environment(
49+
ansible_inventory=ansible_inventory,
50+
task_name="ha-config",
51+
task_description="The ASCS HA config validation test validates the SCS/ERS cluster "
52+
+ "configuration and other system configuration",
53+
module_names=[
54+
"project/library/get_pcmk_properties_scs",
55+
"project/library/log_parser",
56+
"project/library/send_telemetry_data",
57+
"bin/crm_resource",
58+
"bin/crm",
59+
],
60+
)
61+
62+
os.makedirs(f"{temp_dir}/project/roles/ha_scs/tasks/files", exist_ok=True)
63+
self.file_operations(
64+
operation="write",
65+
file_path=f"{temp_dir}/project/roles/ha_scs/tasks/files/constants.yaml",
66+
content=self.file_operations(
67+
operation="read",
68+
file_path=Path(__file__).parent / "mock_data/cluster_config.txt",
69+
),
70+
)
71+
72+
os.makedirs(f"{temp_dir}/project/library", exist_ok=True)
73+
self.file_operations(
74+
operation="write",
75+
file_path=f"{temp_dir}/project/library/uri",
76+
content=self.file_operations(
77+
operation="read",
78+
file_path=Path(__file__).parent / "mock_data/azure_metadata.txt",
79+
),
80+
)
81+
os.chmod(f"{temp_dir}/project/library/uri", 0o755)
82+
83+
yield temp_dir
84+
shutil.rmtree(temp_dir)
85+
86+
def test_ha_config_validation_success(self, test_environment, ansible_inventory):
87+
"""
88+
Test the ASCS migration tasks using Ansible Runner.
89+
90+
:param test_environment: Path to the temporary test environment.
91+
:type test_environment: str
92+
:param ansible_inventory: Path to the Ansible inventory file.
93+
:type ansible_inventory: str
94+
"""
95+
result = self.run_ansible_playbook(
96+
test_environment=test_environment,
97+
)
98+
99+
assert result.rc == 0, (
100+
f"Playbook failed with status: {result.rc}\n"
101+
f"STDOUT: {result.stdout.read() if result.stdout else 'No output'}\n"
102+
f"STDERR: {result.stderr.read() if result.stderr else 'No errors'}\n"
103+
f"Events: {[e.get('event') for e in result.events if 'event' in e]}"
104+
)
105+
106+
ok_events, failed_events = [], []
107+
for event in result.events:
108+
if event.get("event") == "runner_on_ok":
109+
ok_events.append(event)
110+
elif event.get("event") == "runner_on_failed":
111+
failed_events.append(event)
112+
113+
assert len(ok_events) > 0
114+
assert len(failed_events) == 0
115+
116+
for event in ok_events:
117+
task = event.get("event_data", {}).get("task")
118+
task_result = event.get("event_data", {}).get("res")
119+
if "Virtual Machine name" in task:
120+
assert task_result.get("changed") is False
121+
if "HA Configuration check" in task:
122+
assert task_result.get("changed") is False
123+
assert (
124+
task_result["details"].get("parameters", {})[1].get("name")
125+
== "migration-threshold"
126+
)
127+
assert task_result["details"].get("parameters", {})[1].get("value") == "3"
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/usr/bin/python3
2+
from ansible.module_utils.basic import AnsibleModule
3+
import json
4+
5+
def main():
6+
module = AnsibleModule(
7+
argument_spec=dict(
8+
url=dict(type='str', required=True),
9+
use_proxy=dict(type='bool', required=False),
10+
headers=dict(type='dict', required=False)
11+
)
12+
)
13+
14+
# Check if this is the Azure metadata request
15+
if "169.254.169.254/metadata/instance" in module.params['url']:
16+
result = {
17+
"changed": False,
18+
"json": {
19+
"compute": {
20+
"name": "scs01",
21+
"vmId": "12345678-1234-1234-1234-123456789012",
22+
"location": "eastus"
23+
}
24+
},
25+
"status": 200
26+
}
27+
else:
28+
result = {
29+
"changed": False,
30+
"status": 404,
31+
"msg": "URL not mocked"
32+
}
33+
34+
module.exit_json(**result)
35+
36+
if __name__ == '__main__':
37+
main()
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
CRM_CONFIG_DEFAULTS:
2+
cluster-infrastructure: corosync
3+
priority-fencing-delay: '30'
4+
stonith-action: reboot
5+
stonith-enabled: 'false'
6+
concurrent-fencing: 'true'
7+
maintenance-mode: 'false'
8+
node-health-strategy: 'custom'
9+
azure-events-az_globalPullState: 'IDLE'
10+
11+
RSC_DEFAULTS:
12+
migration-threshold: '3'
13+
priority: '1'
14+
resource-stickiness: '1'
15+
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)