Synchronize and cache Generic Camera still image fetching (#105821)
This commit is contained in:
parent
5545883400
commit
8778763a3e
2 changed files with 121 additions and 15 deletions
|
@ -1,9 +1,11 @@
|
|||
"""The tests for generic camera component."""
|
||||
import asyncio
|
||||
from datetime import timedelta
|
||||
from http import HTTPStatus
|
||||
from unittest.mock import patch
|
||||
|
||||
import aiohttp
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
import httpx
|
||||
import pytest
|
||||
import respx
|
||||
|
@ -49,6 +51,7 @@ async def test_fetching_url(
|
|||
"username": "user",
|
||||
"password": "pass",
|
||||
"authentication": "basic",
|
||||
"framerate": 20,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -63,10 +66,87 @@ async def test_fetching_url(
|
|||
body = await resp.read()
|
||||
assert body == fakeimgbytes_png
|
||||
|
||||
# sleep .1 seconds to make cached image expire
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
resp = await client.get("/api/camera_proxy/camera.config_test")
|
||||
assert respx.calls.call_count == 2
|
||||
|
||||
|
||||
@respx.mock
|
||||
async def test_image_caching(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
fakeimgbytes_png,
|
||||
) -> None:
|
||||
"""Test that the image is cached and not fetched more often than the framerate indicates."""
|
||||
respx.get("http://example.com").respond(stream=fakeimgbytes_png)
|
||||
|
||||
framerate = 5
|
||||
await async_setup_component(
|
||||
hass,
|
||||
"camera",
|
||||
{
|
||||
"camera": {
|
||||
"name": "config_test",
|
||||
"platform": "generic",
|
||||
"still_image_url": "http://example.com",
|
||||
"username": "user",
|
||||
"password": "pass",
|
||||
"authentication": "basic",
|
||||
"framerate": framerate,
|
||||
}
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
client = await hass_client()
|
||||
|
||||
resp = await client.get("/api/camera_proxy/camera.config_test")
|
||||
assert resp.status == HTTPStatus.OK
|
||||
body = await resp.read()
|
||||
assert body == fakeimgbytes_png
|
||||
|
||||
resp = await client.get("/api/camera_proxy/camera.config_test")
|
||||
assert resp.status == HTTPStatus.OK
|
||||
body = await resp.read()
|
||||
assert body == fakeimgbytes_png
|
||||
|
||||
# time is frozen, image should have come from cache
|
||||
assert respx.calls.call_count == 1
|
||||
|
||||
# advance time by 150ms
|
||||
freezer.tick(timedelta(seconds=0.150))
|
||||
|
||||
resp = await client.get("/api/camera_proxy/camera.config_test")
|
||||
assert resp.status == HTTPStatus.OK
|
||||
body = await resp.read()
|
||||
assert body == fakeimgbytes_png
|
||||
|
||||
# Only 150ms have passed, image should still have come from cache
|
||||
assert respx.calls.call_count == 1
|
||||
|
||||
# advance time by another 150ms
|
||||
freezer.tick(timedelta(seconds=0.150))
|
||||
|
||||
resp = await client.get("/api/camera_proxy/camera.config_test")
|
||||
assert resp.status == HTTPStatus.OK
|
||||
body = await resp.read()
|
||||
assert body == fakeimgbytes_png
|
||||
|
||||
# 300ms have passed, now we should have fetched a new image
|
||||
assert respx.calls.call_count == 2
|
||||
|
||||
resp = await client.get("/api/camera_proxy/camera.config_test")
|
||||
assert resp.status == HTTPStatus.OK
|
||||
body = await resp.read()
|
||||
assert body == fakeimgbytes_png
|
||||
|
||||
# Still only 300ms have passed, should have returned the cached image
|
||||
assert respx.calls.call_count == 2
|
||||
|
||||
|
||||
@respx.mock
|
||||
async def test_fetching_without_verify_ssl(
|
||||
hass: HomeAssistant, hass_client: ClientSessionGenerator, fakeimgbytes_png
|
||||
|
@ -468,6 +548,7 @@ async def test_timeout_cancelled(
|
|||
"still_image_url": "http://example.com",
|
||||
"username": "user",
|
||||
"password": "pass",
|
||||
"framerate": 20,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -497,6 +578,8 @@ async def test_timeout_cancelled(
|
|||
]
|
||||
|
||||
for total_calls in range(2, 4):
|
||||
# sleep .1 seconds to make cached image expire
|
||||
await asyncio.sleep(0.1)
|
||||
resp = await client.get("/api/camera_proxy/camera.config_test")
|
||||
assert respx.calls.call_count == total_calls
|
||||
assert resp.status == HTTPStatus.OK
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue