mirror of
https://github.com/python-kasa/python-kasa.git
synced 2024-12-22 19:23:34 +00:00
Use freezegun for testing aes http client delays (#954)
This commit is contained in:
parent
8a0edbe2c5
commit
39fc21a124
@ -15,6 +15,7 @@ import aiohttp
|
|||||||
import pytest
|
import pytest
|
||||||
from cryptography.hazmat.primitives import serialization
|
from cryptography.hazmat.primitives import serialization
|
||||||
from cryptography.hazmat.primitives.asymmetric import padding as asymmetric_padding
|
from cryptography.hazmat.primitives.asymmetric import padding as asymmetric_padding
|
||||||
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
from yarl import URL
|
from yarl import URL
|
||||||
|
|
||||||
from ..aestransport import AesEncyptionSession, AesTransport, TransportState
|
from ..aestransport import AesEncyptionSession, AesTransport, TransportState
|
||||||
@ -287,12 +288,20 @@ async def test_port_override():
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"request_delay, should_error, should_succeed",
|
"device_delay_required, should_error, should_succeed",
|
||||||
[(0, False, True), (0.125, True, True), (0.3, True, True), (0.7, True, False)],
|
[
|
||||||
ids=["No error", "Error then succeed", "Two errors then succeed", "No succeed"],
|
pytest.param(0, False, True, id="No error"),
|
||||||
|
pytest.param(0.125, True, True, id="Error then succeed"),
|
||||||
|
pytest.param(0.3, True, True, id="Two errors then succeed"),
|
||||||
|
pytest.param(0.7, True, False, id="No succeed"),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
async def test_device_closes_connection(
|
async def test_device_closes_connection(
|
||||||
mocker, request_delay, should_error, should_succeed
|
mocker,
|
||||||
|
freezer: FrozenDateTimeFactory,
|
||||||
|
device_delay_required,
|
||||||
|
should_error,
|
||||||
|
should_succeed,
|
||||||
):
|
):
|
||||||
"""Test the delay logic in http client to deal with devices that close connections after each request.
|
"""Test the delay logic in http client to deal with devices that close connections after each request.
|
||||||
|
|
||||||
@ -300,16 +309,19 @@ async def test_device_closes_connection(
|
|||||||
"""
|
"""
|
||||||
host = "127.0.0.1"
|
host = "127.0.0.1"
|
||||||
|
|
||||||
# Speed up the test by dividing all times by a factor. Doesn't seem to work on windows
|
default_delay = HttpClient.WAIT_BETWEEN_REQUESTS_ON_OSERROR
|
||||||
# but leaving here as a TODO to manipulate system time for testing.
|
|
||||||
speed_up_factor = 1
|
|
||||||
default_delay = HttpClient.WAIT_BETWEEN_REQUESTS_ON_OSERROR / speed_up_factor
|
|
||||||
request_delay = request_delay / speed_up_factor
|
|
||||||
mock_aes_device = MockAesDevice(
|
mock_aes_device = MockAesDevice(
|
||||||
host, 200, 0, 0, sequential_request_delay=request_delay
|
host, 200, 0, 0, sequential_request_delay=device_delay_required
|
||||||
)
|
)
|
||||||
mocker.patch.object(aiohttp.ClientSession, "post", side_effect=mock_aes_device.post)
|
mocker.patch.object(aiohttp.ClientSession, "post", side_effect=mock_aes_device.post)
|
||||||
|
|
||||||
|
async def _asyncio_sleep_mock(delay, result=None):
|
||||||
|
freezer.tick(delay)
|
||||||
|
return result
|
||||||
|
|
||||||
|
mocker.patch("asyncio.sleep", side_effect=_asyncio_sleep_mock)
|
||||||
|
|
||||||
config = DeviceConfig(host, credentials=Credentials("foo", "bar"))
|
config = DeviceConfig(host, credentials=Credentials("foo", "bar"))
|
||||||
transport = AesTransport(config=config)
|
transport = AesTransport(config=config)
|
||||||
transport._http_client.WAIT_BETWEEN_REQUESTS_ON_OSERROR = default_delay
|
transport._http_client.WAIT_BETWEEN_REQUESTS_ON_OSERROR = default_delay
|
||||||
@ -332,7 +344,7 @@ async def test_device_closes_connection(
|
|||||||
# If the device errors without a delay then it should error immedately ( + 1)
|
# If the device errors without a delay then it should error immedately ( + 1)
|
||||||
# and then the number of times the default delay passes within the request delay window
|
# and then the number of times the default delay passes within the request delay window
|
||||||
expected_error_count = (
|
expected_error_count = (
|
||||||
0 if not should_error else int(request_delay / default_delay) + 1
|
0 if not should_error else int(device_delay_required / default_delay) + 1
|
||||||
)
|
)
|
||||||
for _ in range(3):
|
for _ in range(3):
|
||||||
try:
|
try:
|
||||||
|
56
poetry.lock
generated
56
poetry.lock
generated
@ -636,6 +636,20 @@ docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1
|
|||||||
testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"]
|
testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"]
|
||||||
typing = ["typing-extensions (>=4.8)"]
|
typing = ["typing-extensions (>=4.8)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "freezegun"
|
||||||
|
version = "1.5.1"
|
||||||
|
description = "Let your Python tests travel through time"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "freezegun-1.5.1-py3-none-any.whl", hash = "sha256:bf111d7138a8abe55ab48a71755673dbaa4ab87f4cff5634a4442dfec34c15f1"},
|
||||||
|
{file = "freezegun-1.5.1.tar.gz", hash = "sha256:b29dedfcda6d5e8e083ce71b2b542753ad48cfec44037b3fc79702e2980a89e9"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
python-dateutil = ">=2.7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "frozenlist"
|
name = "frozenlist"
|
||||||
version = "1.4.1"
|
version = "1.4.1"
|
||||||
@ -1505,6 +1519,21 @@ pytest = ">=4.6"
|
|||||||
[package.extras]
|
[package.extras]
|
||||||
testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"]
|
testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pytest-freezer"
|
||||||
|
version = "0.4.8"
|
||||||
|
description = "Pytest plugin providing a fixture interface for spulec/freezegun"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">= 3.6"
|
||||||
|
files = [
|
||||||
|
{file = "pytest_freezer-0.4.8-py3-none-any.whl", hash = "sha256:644ce7ddb8ba52b92a1df0a80a699bad2b93514c55cf92e9f2517b68ebe74814"},
|
||||||
|
{file = "pytest_freezer-0.4.8.tar.gz", hash = "sha256:8ee2f724b3ff3540523fa355958a22e6f4c1c819928b78a7a183ae4248ce6ee6"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
freezegun = ">=1.0"
|
||||||
|
pytest = ">=3.6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pytest-mock"
|
name = "pytest-mock"
|
||||||
version = "3.14.0"
|
version = "3.14.0"
|
||||||
@ -1555,6 +1584,20 @@ files = [
|
|||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
pytest = ">=7.0.0"
|
pytest = ">=7.0.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-dateutil"
|
||||||
|
version = "2.9.0.post0"
|
||||||
|
description = "Extensions to the standard Python datetime module"
|
||||||
|
optional = false
|
||||||
|
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
||||||
|
files = [
|
||||||
|
{file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"},
|
||||||
|
{file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
six = ">=1.5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pytz"
|
name = "pytz"
|
||||||
version = "2024.1"
|
version = "2024.1"
|
||||||
@ -1681,6 +1724,17 @@ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments
|
|||||||
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
|
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
|
||||||
testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
|
testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "six"
|
||||||
|
version = "1.16.0"
|
||||||
|
description = "Python 2 and 3 compatibility utilities"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||||
|
files = [
|
||||||
|
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||||
|
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sniffio"
|
name = "sniffio"
|
||||||
version = "1.3.1"
|
version = "1.3.1"
|
||||||
@ -2156,4 +2210,4 @@ speedups = ["kasa-crypt", "orjson"]
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.8"
|
python-versions = "^3.8"
|
||||||
content-hash = "ba5c0da1e413e466834d0954528c7ace6dd9e01d9fb2e626f4c6b23044803aef"
|
content-hash = "871ef421fe7d48608bcea18b4c41d8bb368e84d74bf7b29db832dc97c5b980ae"
|
||||||
|
@ -58,6 +58,7 @@ codecov = "*"
|
|||||||
xdoctest = "*"
|
xdoctest = "*"
|
||||||
coverage = {version = "*", extras = ["toml"]}
|
coverage = {version = "*", extras = ["toml"]}
|
||||||
pytest-timeout = "^2"
|
pytest-timeout = "^2"
|
||||||
|
pytest-freezer = "^0.4"
|
||||||
|
|
||||||
[tool.poetry.extras]
|
[tool.poetry.extras]
|
||||||
docs = ["sphinx", "sphinx_rtd_theme", "sphinxcontrib-programoutput", "myst-parser", "docutils"]
|
docs = ["sphinx", "sphinx_rtd_theme", "sphinxcontrib-programoutput", "myst-parser", "docutils"]
|
||||||
|
Loading…
Reference in New Issue
Block a user