1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
"""Test AsusRouter with real devices data."""
from contextlib import contextmanager
from dataclasses import dataclass
from enum import Enum
import importlib
import logging
from pathlib import Path
import re
from typing import Any
import pytest
from asusrouter import AsusData
from asusrouter.modules.endpoint import (
Endpoint,
EndpointControl,
EndpointService,
EndpointTools,
EndpointType,
process,
read,
)
# Create a logger
_LOGGER = logging.getLogger(__name__)
_LOGGER.setLevel(logging.INFO)
class FileExtensions(Enum):
"""File extensions used in the test data."""
CONTENT = ".content"
PYTHON = ".py"
@dataclass
class DataItem:
"""A class used to represent a test item."""
content: str
result: dict[AsusData, Any]
endpoint: EndpointType
label: str
def __repr__(self) -> str:
"""Return a string representation of the data item."""
return self.label
@contextmanager
def log_test_data_loading():
"""Log the start and end of loading test data."""
_LOGGER.info("Starting to load test data")
yield
_LOGGER.info("Finished loading test data")
def load_content_data(device_path: Path, module_name: str) -> str:
"""Load content data from a file."""
content_file = device_path / f"{module_name}{FileExtensions.CONTENT.value}"
with content_file.open("r", encoding="utf-8") as f:
return f.read()
def load_expected_result(device_path: Path, module_name: str) -> Any:
"""Load expected result from a module."""
result_module = importlib.import_module(
f".test_data.{'.'.join([device_path.name, module_name])}",
package="tests",
)
return result_module.expected_result
def load_test_item(device_path: Path, module_name: str) -> DataItem | None:
"""Load a single test item."""
try:
endpoint_name = re.match(r"(.*)_\d+", module_name).group(1)
endpoint = None
for endpoint_enum in [
Endpoint,
EndpointControl,
EndpointService,
EndpointTools,
]:
try:
endpoint = endpoint_enum[endpoint_name.upper()]
break
except KeyError:
continue
if endpoint is None:
raise ValueError("Failed to load test item ", module_name)
content_data = load_content_data(device_path, module_name)
expected_result = load_expected_result(device_path, module_name)
return DataItem(
content=content_data,
result=expected_result,
endpoint=endpoint,
label=f"{device_path.name}_{module_name}",
)
except Exception as ex: # noqa: BLE001
_LOGGER.error("Failed to load test item %s: %s", module_name, ex)
return None
def load_test_data() -> list[DataItem]:
"""Load the test data."""
with log_test_data_loading():
test_data_path = Path(__file__).resolve().parent / "test_data"
data = []
for device_path in test_data_path.iterdir():
if device_path.is_dir():
device_test_count = 0
for content_file in device_path.glob("*.content"):
module_name = content_file.stem
# Check if both .content and .py files exist
if (
not (device_path / f"{module_name}.content").exists()
or not (device_path / f"{module_name}.py").exists()
):
continue
item = load_test_item(device_path, module_name)
data.append(item)
device_test_count += 1
_LOGGER.info(
"Found %s test items for device: %s",
device_test_count,
device_path.name,
)
_LOGGER.info("Total test items found: %s", len(data))
return data
# Load the test data only once
test_data = load_test_data()
# Create a list of ids for the test data
test_ids = [item.label for item in test_data]
@pytest.fixture(params=test_data, ids=test_ids)
def test_item(request) -> DataItem:
"""Yield each item in the test data."""
return request.param
def test_asusrouter(test_item: DataItem) -> None: # pylint: disable=redefined-outer-name
"""
Test the asusrouter module with the given test item.
Args:
test_item (DataItem): The test item to use for the test.
Raises:
AssertionError: If the actual processed data does not match
the expected result.
"""
actual_read = read(test_item.endpoint, test_item.content)
actual_processed = process(test_item.endpoint, actual_read)
assert actual_processed == test_item.result, print(actual_processed) # noqa: T201
|