-
Notifications
You must be signed in to change notification settings - Fork 1k
Upgrade smartswitch via gNOI testcases #22393
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
9380a9a
002f82f
428d3f7
8901ed8
0df33ae
146b31b
7dfd6ad
adf6fd2
42b8242
50f7f13
f330cb2
a032e3d
1e85d11
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,11 +8,12 @@ | |
| import tests.common.fixtures.grpc_fixtures # noqa: F401 | ||
| from tests.common.helpers.assertions import pytest_assert | ||
| from tests.common import reboot | ||
| from tests.common.helpers.multi_thread_utils import SafeThreadPoolExecutor | ||
| from tests.common.reboot import get_reboot_cause, reboot_ctrl_dict | ||
| from tests.common.reboot import REBOOT_TYPE_WARM, REBOOT_TYPE_COLD | ||
| from tests.common.utilities import wait_until, setup_ferret | ||
| from tests.common.platform.device_utils import check_neighbors | ||
| from typing import Dict, Optional | ||
| from typing import Optional, Sequence, Tuple, Union, Dict | ||
|
|
||
| SYSTEM_STABILIZE_MAX_TIME = 300 | ||
| logger = logging.getLogger(__name__) | ||
|
|
@@ -22,7 +23,10 @@ | |
| TMP_PORTS_FILE = '/tmp/ports.json' | ||
| TMP_PEER_INFO_FILE = "/tmp/peer_dev_info.json" | ||
| TMP_PEER_PORT_INFO_FILE = "/tmp/neigh_port_info.json" | ||
| SS_TARGET_TYPE_HDR = "x-sonic-ss-target-type" | ||
| SS_TARGET_INDEX_HDR = "x-sonic-ss-target-index" | ||
|
|
||
| GrpcMetadata = Union[Dict[str, str], Sequence[Tuple[str, str]]] | ||
|
|
||
| @dataclass(frozen=True) | ||
| class GnoiUpgradeConfig: | ||
|
|
@@ -32,6 +36,17 @@ class GnoiUpgradeConfig: | |
| protocol: str = "HTTP" | ||
| allow_fail: bool = False | ||
| to_version: Optional[str] = None # Optional expected version string to validate after upgrade | ||
| ss_target_type: Optional[str] = None # e.g. "dpu" | ||
| ss_target_index: Optional[int] = None # e.g. 3 | ||
| metadata: Optional[GrpcMetadata] = None | ||
| ss_reboot_ready_timeout: int = 1200 | ||
| ss_reboot_message: str = "Rebooting DPU for maintenance" | ||
|
|
||
| def build_smartswitch_metadata(target_type: str, target_index: int): | ||
| return [ | ||
| (SS_TARGET_TYPE_HDR, str(target_type)), | ||
| (SS_TARGET_INDEX_HDR, str(target_index)), | ||
| ] | ||
ryanzhu706 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| def pytest_runtest_setup(item): | ||
|
|
@@ -395,3 +410,81 @@ def perform_gnoi_upgrade( | |
| ) | ||
|
|
||
| return {"transfer_resp": transfer_resp, "setpkg_resp": setpkg_resp} | ||
|
|
||
| def _wait_gnoi_time_ready(ptf_gnoi, metadata, cfg: GnoiUpgradeConfig, timeout=None, interval: int = 10) -> bool: | ||
| timeout = timeout or cfg.ss_reboot_ready_timeout | ||
| return wait_until(timeout, interval, 0, ptf_gnoi.system_time, metadata=metadata) | ||
|
|
||
|
|
||
| def _upgrade_one_dpu_via_gnoi(duthost, tbinfo, ptf_gnoi, cfg: GnoiUpgradeConfig) -> Dict: | ||
| if not cfg.metadata: | ||
| raise ValueError("cfg.metadata must be provided for SmartSwitch DPU upgrade") | ||
|
|
||
| md = cfg.metadata | ||
|
|
||
| ptf_gnoi.system_time(metadata=md) | ||
|
|
||
| transfer_resp = ptf_gnoi.file_transfer_to_remote( | ||
| url=cfg.to_image, | ||
| local_path=cfg.dut_image_path, | ||
| protocol=cfg.protocol, | ||
| metadata=md, | ||
| ) | ||
|
|
||
| setpkg_resp = ptf_gnoi.system_set_package( | ||
| local_path=cfg.dut_image_path, | ||
| version=cfg.to_version, | ||
| activate=True, | ||
| metadata=md, | ||
| ) | ||
|
|
||
| # method = str(cfg.upgrade_type).upper() | ||
| try: | ||
| ## TODO: switch to use the perform reboot helper once it supports gNOI. | ||
| reboot_resp = ptf_gnoi.system_reboot( | ||
| method=cfg.upgrade_type, | ||
| delay=0, | ||
| message=cfg.ss_reboot_message, | ||
| metadata=md, | ||
| ) | ||
| except Exception as e: | ||
| logger.info("Reboot raised (often expected): %s", e) | ||
| reboot_resp = None | ||
|
|
||
| if cfg.allow_fail: | ||
| return {"transfer_resp": transfer_resp, "setpkg_resp": setpkg_resp, "reboot_resp": reboot_resp} | ||
|
|
||
| ok = _wait_gnoi_time_ready(ptf_gnoi, md, cfg) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @v-cshekar , as a next step from here, please include your changes (generic |
||
| pytest_assert(ok, f"gNOI Time not reachable within {cfg.ss_reboot_ready_timeout}s after reboot") | ||
| check_services(duthost, tbinfo) | ||
| check_neighbors(duthost, tbinfo) | ||
| check_copp_config(duthost) | ||
|
|
||
| return {"transfer_resp": transfer_resp, "setpkg_resp": setpkg_resp, "reboot_resp": reboot_resp} | ||
|
|
||
|
|
||
| def perform_gnoi_upgrade_smartswitch_dpu(duthost, tbinfo, ptf_gnoi, cfg: GnoiUpgradeConfig) -> Dict: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optional - Considering the concurrent call has a name |
||
| return _upgrade_one_dpu_via_gnoi(duthost, tbinfo, ptf_gnoi, cfg) | ||
|
|
||
|
|
||
| def perform_gnoi_upgrade_smartswitch_dpus_parallel( | ||
| duthost, tbinfo, | ||
| ptf_gnoi, | ||
| cfgs: Sequence[GnoiUpgradeConfig], | ||
| max_workers: Optional[int] = None, | ||
| ) -> Dict[int, Dict]: | ||
| if not cfgs: | ||
| raise ValueError("cfgs is empty") | ||
|
|
||
| workers = max_workers or len(cfgs) | ||
| results: Dict[int, Dict] = {} | ||
|
|
||
| with SafeThreadPoolExecutor(max_workers=workers) as executor: | ||
| futs = {} | ||
| for i, cfg in enumerate(cfgs): | ||
| futs[i] = executor.submit(_upgrade_one_dpu_via_gnoi, duthost, tbinfo, ptf_gnoi, cfg) | ||
|
|
||
| for i, fut in futs.items(): | ||
| results[i] = fut.result() | ||
|
|
||
| return results | ||
Uh oh!
There was an error while loading. Please reload this page.