85 lines
3.1 KiB
Python
85 lines
3.1 KiB
Python
# Copyright (c) 2023-2024 Arista Networks, Inc.
|
|
# Use of this source code is governed by the Apache License 2.0
|
|
# that can be found in the LICENSE file.
|
|
"""Unit tests the asynceapi.device module."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING, Any
|
|
|
|
import pytest
|
|
from httpx import HTTPStatusError
|
|
|
|
from asynceapi import Device, EapiCommandError
|
|
|
|
from .test_data import ERROR_EAPI_RESPONSE, JSONRPC_REQUEST_TEMPLATE, SUCCESS_EAPI_RESPONSE
|
|
|
|
if TYPE_CHECKING:
|
|
from pytest_httpx import HTTPXMock
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"cmds",
|
|
[
|
|
(["show version", "show clock"]),
|
|
([{"cmd": "show version"}, {"cmd": "show clock"}]),
|
|
([{"cmd": "show version"}, "show clock"]),
|
|
],
|
|
ids=["simple_commands", "complex_commands", "mixed_commands"],
|
|
)
|
|
async def test_jsonrpc_exec_success(
|
|
asynceapi_device: Device,
|
|
httpx_mock: HTTPXMock,
|
|
cmds: list[str | dict[str, Any]],
|
|
) -> None:
|
|
"""Test the Device.jsonrpc_exec method with a successful response. Simple and complex commands are tested."""
|
|
jsonrpc_request: dict[str, Any] = JSONRPC_REQUEST_TEMPLATE.copy()
|
|
jsonrpc_request["params"]["cmds"] = cmds
|
|
|
|
httpx_mock.add_response(json=SUCCESS_EAPI_RESPONSE)
|
|
|
|
result = await asynceapi_device.jsonrpc_exec(jsonrpc=jsonrpc_request)
|
|
|
|
assert result == SUCCESS_EAPI_RESPONSE["result"]
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"cmds",
|
|
[
|
|
(["show version", "bad command", "show clock"]),
|
|
([{"cmd": "show version"}, {"cmd": "bad command"}, {"cmd": "show clock"}]),
|
|
([{"cmd": "show version"}, {"cmd": "bad command"}, "show clock"]),
|
|
],
|
|
ids=["simple_commands", "complex_commands", "mixed_commands"],
|
|
)
|
|
async def test_jsonrpc_exec_eapi_command_error(
|
|
asynceapi_device: Device,
|
|
httpx_mock: HTTPXMock,
|
|
cmds: list[str | dict[str, Any]],
|
|
) -> None:
|
|
"""Test the Device.jsonrpc_exec method with an error response. Simple and complex commands are tested."""
|
|
jsonrpc_request: dict[str, Any] = JSONRPC_REQUEST_TEMPLATE.copy()
|
|
jsonrpc_request["params"]["cmds"] = cmds
|
|
|
|
error_eapi_response: dict[str, Any] = ERROR_EAPI_RESPONSE.copy()
|
|
httpx_mock.add_response(json=error_eapi_response)
|
|
|
|
with pytest.raises(EapiCommandError) as exc_info:
|
|
await asynceapi_device.jsonrpc_exec(jsonrpc=jsonrpc_request)
|
|
|
|
assert exc_info.value.passed == [error_eapi_response["error"]["data"][0]]
|
|
assert exc_info.value.failed == "bad command"
|
|
assert exc_info.value.errors == ["Invalid input (at token 1: 'bad')"]
|
|
assert exc_info.value.errmsg == "CLI command 2 of 3 'bad command' failed: invalid command"
|
|
assert exc_info.value.not_exec == [jsonrpc_request["params"]["cmds"][2]]
|
|
|
|
|
|
async def test_jsonrpc_exec_http_status_error(asynceapi_device: Device, httpx_mock: HTTPXMock) -> None:
|
|
"""Test the Device.jsonrpc_exec method with an HTTPStatusError."""
|
|
jsonrpc_request: dict[str, Any] = JSONRPC_REQUEST_TEMPLATE.copy()
|
|
jsonrpc_request["params"]["cmds"] = ["show version"]
|
|
|
|
httpx_mock.add_response(status_code=500, text="Internal Server Error")
|
|
|
|
with pytest.raises(HTTPStatusError):
|
|
await asynceapi_device.jsonrpc_exec(jsonrpc=jsonrpc_request)
|