Skip to content
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

[GNOI E2E Testing] Add E2E Tests for GNOI KillProcess API #12478

Merged
merged 4 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions tests/gnmi/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,21 @@ def gnoi_reboot(duthost, localhost, method, delay, message):
return -1, output['stderr']
else:
return 0, output['stdout']


def gnoi_request(duthost, localhost, rpc, request_json_data):
env = GNMIEnvironment(duthost, GNMIEnvironment.GNMI_MODE)
ip = duthost.mgmt_ip
port = env.gnmi_port
cmd = "docker exec %s gnoi_client -target %s:%s " % (env.gnmi_container, ip, port)
cmd += "-cert /etc/sonic/telemetry/gnmiclient.crt "
cmd += "-key /etc/sonic/telemetry/gnmiclient.key "
cmd += "-ca /etc/sonic/telemetry/gnmiCA.pem "
cmd += "-logtostderr -rpc {} ".format(rpc)
cmd += f'-jsonin \'{request_json_data}\''
output = duthost.shell(cmd, module_ignore_errors=True)
if output['stderr']:
logger.error(output['stderr'])
return -1, output['stderr']
else:
return 0, output['stdout']
79 changes: 79 additions & 0 deletions tests/gnmi/test_gnoi_killprocess.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import pytest
from .helper import gnoi_request
from tests.common.helpers.assertions import pytest_assert
from tests.common.helpers.dut_utils import is_container_running


# This test ensures functionality of KillProcess API to kill and restart a process when a valid process name is passed
# When an invalid process name is passed, this test ensures that the expected error is returned
@pytest.mark.parametrize("process,is_valid, expected_msg", [
("gnmi", False, "Dbus does not support gnmi service management"),
("nonexistent", False, "Dbus does not support nonexistent service management"),
("", False, "Dbus stop_service called with no service specified"),
("snmp", True, ""),
("dhcp_relay", True, ""),
("radv", True, ""),
("restapi", True, ""),
("lldp", True, ""),
("sshd", True, ""),
("swss", True, ""),
("pmon", True, ""),
("rsyslog", True, ""),
("telemetry", True, "")
])
def test_gnoi_killprocess_then_restart(duthosts, rand_one_dut_hostname, localhost, process, is_valid, expected_msg):
duthost = duthosts[rand_one_dut_hostname]

if process and process != "nonexistent":
pytest_assert(duthost.is_host_service_running(process),
"{} should be running before KillProcess test attempts to kill this process".format(process))

request_kill_json_data = '{{"name": "{}", "signal": 1}}'.format(process)
ret, msg = gnoi_request(duthost, localhost, "KillProcess", request_kill_json_data)
if is_valid:
pytest_assert(ret == 0, "KillProcess API unexpectedly reported failure")
pytest_assert(not is_container_running(duthost, process),
"{} found running after KillProcess reported success".format(process))

request_restart_json_data = '{{"name": "{}", "restart": true, "signal": 1}}'.format(process)
ret, msg = gnoi_request(duthost, localhost, "KillProcess", request_restart_json_data)
pytest_assert(ret == 0,
"KillProcess API unexpectedly reported failure when attempting to restart {}".format(process))
pytest_assert(duthost.is_host_service_running(process),
"{} not running after KillProcess reported successful restart".format(process))
else:
pytest_assert(ret != 0, "KillProcess API unexpectedly succeeded with invalid request parameters")
pytest_assert(expected_msg in msg, "Unexpected error message in response to invalid gNOI request")

pytest_assert(duthost.critical_services_fully_started, "System unhealthy after gNOI API request")


# This test performs additional verification of the restart request under KillProcess API
# This test focuses on edge conditions of restart value in the request, so we only test against one service: snmp
@pytest.mark.parametrize("request_restart_value, is_valid", [
("invalid", False),
("", False)
])
def test_gnoi_killprocess_restart(duthosts, rand_one_dut_hostname, localhost, request_restart_value, is_valid):
duthost = duthosts[rand_one_dut_hostname]
request_json_data = f'{{"name": "snmp", "restart": {request_restart_value}, "signal": 1}}'
ret, msg = gnoi_request(duthost, localhost, "KillProcess", request_json_data)
if is_valid:
pytest_assert(ret == 0, "KillProcess API unexpectedly reported failure")
pytest_assert(is_container_running(duthost, "snmp"),
"snmp not running after KillProcess API reported successful restart")
else:
pytest_assert(ret != 0, "KillProcess API unexpectedly succeeded with invalid request parameters")
pytest_assert("panic" in msg, "Unexpected error message in response to invalid gNOI request")
pytest_assert(duthost.critical_services_fully_started, "System unhealthy after gNOI API request")


def test_invalid_signal(duthosts, rand_one_dut_hostname, localhost):
duthost = duthosts[rand_one_dut_hostname]
request_json_data = '{"name": "snmp", "restart": true, "signal": 2}'
ret, msg = gnoi_request(duthost, localhost, "KillProcess", request_json_data)

pytest_assert(ret != 0, "KillProcess API unexpectedly succeeded with invalid request parameters")
pytest_assert("KillProcess only supports SIGNAL_TERM (option 1)" in msg,
"Unexpected error message in response to invalid gNOI request")
pytest_assert(duthost.critical_services_fully_started, "System unhealthy after gNOI API request")
Loading