Skip to content

Commit 4f12997

Browse files
moved helper functions to ha_utils from conftest file
1 parent 0b2f3e5 commit 4f12997

2 files changed

Lines changed: 317 additions & 195 deletions

File tree

tests/ha/conftest.py

Lines changed: 15 additions & 195 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,31 @@
22
import pytest
33
from pathlib import Path
44
from collections import defaultdict
5-
import re
65
import os
76
import json
8-
import ast
97
import time
108

119
from tests.common.config_reload import config_reload
1210
from tests.common.helpers.constants import DEFAULT_NAMESPACE
13-
from tests.common.utilities import wait_until
14-
from common.ha.smartswitch_ha_helper import PtfTcpTestAdapter
15-
from common.ha.smartswitch_ha_io import SmartSwitchHaTrafficTest
16-
from common.ha.smartswitch_ha_helper import (
11+
from tests.common.ha.smartswitch_ha_helper import PtfTcpTestAdapter
12+
from tests.common.ha.smartswitch_ha_io import SmartSwitchHaTrafficTest
13+
from tests.common.ha.smartswitch_ha_helper import (
1714
add_port_to_namespace,
1815
remove_namespace,
1916
add_static_route_to_ptf,
2017
add_static_route_to_dut
2118
)
2219

20+
from ha_utils import (
21+
22+
build_dash_ha_scope_args,
23+
wait_for_pending_operation_id,
24+
build_dash_ha_scope_activate_args,
25+
wait_for_ha_state,
26+
build_dash_ha_set_args,
27+
proto_utils_hset
28+
)
29+
2330
logger = logging.getLogger(__name__)
2431

2532

@@ -417,194 +424,7 @@ def setup_ha_config(duthosts):
417424
return final_cfg
418425

419426

420-
def build_dash_ha_set_args(fields):
421-
"""
422-
Build args for DASH_HA_SET_CONFIG_TABLE
423-
EXACTLY following the working CLI
424-
"""
425-
426-
version = str(fields["version"])
427-
if version.endswith(".0"):
428-
version = version[:-2]
429-
430-
return (
431-
f'version \\"{version}\\" '
432-
f'vip_v4 "{fields["vip_v4"]}" '
433-
f'vip_v6 "{fields["vip_v6"]}" '
434-
f'scope "{fields["scope"]}" '
435-
f'preferred_vdpu_id "{fields["preferred_vdpu_id"]}" '
436-
f'preferred_standalone_vdpu_index 0 '
437-
f'vdpu_ids \'["vdpu0_0","vdpu1_0"]\''
438-
)
439-
440-
441-
def build_dash_ha_scope_args(fields):
442-
"""
443-
Build args for DASH_HA_SCOPE_CONFIG_TABLE
444-
EXACTLY following the working CLI
445-
"""
446-
447-
version = str(fields["version"])
448-
if version.endswith(".0"):
449-
version = version[:-2]
450-
451-
return (
452-
f'version \\"{version}\\" '
453-
f'disabled "{fields["disabled"]}" '
454-
f'desired_ha_state "{fields["desired_ha_state"]}" '
455-
f'ha_set_id "{fields["ha_set_id"]}" '
456-
f'owner "{fields["owner"]}"'
457-
)
458-
459-
460-
def extract_pending_operations(text):
461-
"""
462-
Extract pending_operation_ids and pending_operation_types
463-
and return list of (type, id) tuples.
464-
"""
465-
ids_match = re.search(
466-
r'pending_operation_ids\s*\|\s*([^\|\r\n]+)',
467-
text,
468-
re.DOTALL,
469-
)
470-
types_match = re.search(
471-
r'pending_operation_types\s*\|\s*([^\|\r\n]+)',
472-
text,
473-
re.DOTALL,
474-
)
475-
if not ids_match or not types_match:
476-
return []
477-
478-
try:
479-
ids = ast.literal_eval(f"'{ids_match.group(1)}'")
480-
id_list = ids.split()
481-
ids = id_list[0].split(',')
482-
types = ast.literal_eval(f"'{types_match.group(1)}'")
483-
type_list = types.split()
484-
types = type_list[0].split(',')
485-
except Exception:
486-
return []
487-
488-
return list(zip(types, ids))
489-
490-
491-
def get_pending_operation_id(duthost, scope_key, expected_op_type):
492-
"""
493-
scope_key example: vdpu0_0:haset0_0
494-
expected_op_type example: ACTIVATE_ROLE
495-
"""
496-
cmd = (
497-
"docker exec dash-hadpu0 swbus-cli show hamgrd actor "
498-
f"/hamgrd/0/ha-scope/{scope_key}"
499-
)
500-
res = duthost.shell(cmd)
501-
502-
pending_ops = extract_pending_operations(res["stdout"])
503-
504-
for op_type, op_id in pending_ops:
505-
if op_type == expected_op_type:
506-
return op_id
507-
508-
return None
509-
510-
511-
def build_dash_ha_scope_activate_args(fields, pending_id):
512-
return (
513-
f'version \\"{fields["version"]}\\" '
514-
f'disabled {fields["disabled"]} '
515-
f'desired_ha_state "{fields["desired_ha_state"]}" '
516-
f'ha_set_id "{fields["ha_set_id"]}" '
517-
f'owner "{fields["owner"]}" '
518-
f'approved_pending_operation_ids '
519-
f'[\\\"{pending_id}\\\"]'
520-
)
521-
522-
523-
def proto_utils_hset(duthost, table, key, args):
524-
"""
525-
Wrapper around proto_utils.py hset
526-
527-
Args:
528-
duthost: pytest duthost fixture
529-
table (str): Redis table name
530-
key (str): Redis key
531-
args (str): Already-built proto args string
532-
"""
533-
cmd = (
534-
"docker exec swss python /etc/sonic/proto_utils.py hset "
535-
f'"{table}:{key}" {args}'
536-
)
537-
duthost.shell(cmd)
538-
539-
540-
def wait_for_pending_operation_id(
541-
duthost,
542-
scope_key,
543-
expected_op_type,
544-
timeout=60,
545-
interval=2,
546-
):
547-
"""
548-
Wait until the expected pending_operation_id appears.
549-
"""
550-
pending_id = None
551-
552-
def _condition():
553-
nonlocal pending_id
554-
pending_id = get_pending_operation_id(
555-
duthost,
556-
scope_key,
557-
expected_op_type,
558-
)
559-
return pending_id is not None
560-
561-
success = wait_until(
562-
timeout,
563-
interval,
564-
0, # REQUIRED delay argument
565-
_condition, # condition callable
566-
)
567-
568-
return pending_id if success else None
569-
570-
571-
def extract_ha_state(text):
572-
"""
573-
Extract ha_state from swbus-cli output
574-
"""
575-
match = re.search(r'ha_state\s+\|\s+(\w+)', text)
576-
return match.group(1) if match else None
577-
578-
579-
def wait_for_ha_state(
580-
duthost,
581-
scope_key,
582-
expected_state,
583-
timeout=120,
584-
interval=5,
585-
):
586-
"""
587-
Wait until HA reaches the expected state
588-
"""
589-
def _check_ha_state():
590-
cmd = (
591-
"docker exec dash-hadpu0 swbus-cli show hamgrd actor "
592-
f"/hamgrd/0/ha-scope/{scope_key}"
593-
)
594-
res = duthost.shell(cmd)
595-
return extract_ha_state(res["stdout"]) == expected_state
596-
597-
success = wait_until(
598-
timeout,
599-
interval,
600-
0,
601-
_check_ha_state
602-
)
603-
604-
return success
605-
606-
607-
@pytest.fixture(scope="module")
427+
@pytest.fixture(scope="function")
608428
def setup_dash_ha_from_json(duthosts):
609429
base_dir = "/data/tests/common/ha"
610430
ha_set_file = os.path.join(base_dir, "dash_ha_set_dpu_config_table.json")
@@ -659,7 +479,7 @@ def setup_dash_ha_from_json(duthosts):
659479
)
660480

661481

662-
@pytest.fixture(scope="module")
482+
@pytest.fixture(scope="function")
663483
def activate_dash_ha_from_json(duthosts):
664484
# -------------------------------------------------
665485
# Step 4: Activate Role (using pending_operation_ids)

0 commit comments

Comments
 (0)