Convert remaining image processing tests to async (#64506)

This commit is contained in:
Paulus Schoutsen 2022-01-20 09:00:58 -08:00 committed by GitHub
parent ddf548cd27
commit 6803219133
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 264 additions and 283 deletions

View File

@ -2,200 +2,188 @@
import asyncio import asyncio
from unittest.mock import PropertyMock, patch from unittest.mock import PropertyMock, patch
import pytest
from homeassistant.components import camera, image_processing as ip from homeassistant.components import camera, image_processing as ip
from homeassistant.components.openalpr_cloud.image_processing import OPENALPR_API_URL from homeassistant.components.openalpr_cloud.image_processing import OPENALPR_API_URL
from homeassistant.core import callback from homeassistant.setup import async_setup_component
from homeassistant.setup import setup_component
from tests.common import assert_setup_component, get_test_home_assistant, load_fixture from tests.common import assert_setup_component, async_capture_events, load_fixture
from tests.components.image_processing import common from tests.components.image_processing import common
class TestOpenAlprCloudSetup: @pytest.fixture
"""Test class for image processing.""" async def setup_openalpr_cloud(hass):
"""Set up openalpr cloud."""
config = {
ip.DOMAIN: {
"platform": "openalpr_cloud",
"source": {"entity_id": "camera.demo_camera", "name": "test local"},
"region": "eu",
"api_key": "sk_abcxyz123456",
},
"camera": {"platform": "demo"},
}
def setup_method(self): with patch(
"""Set up things to be run when tests are started.""" "homeassistant.components.openalpr_cloud.image_processing."
self.hass = get_test_home_assistant() "OpenAlprCloudEntity.should_poll",
new_callable=PropertyMock(return_value=False),
def teardown_method(self): ):
"""Stop everything that was started.""" await async_setup_component(hass, ip.DOMAIN, config)
self.hass.stop() await hass.async_block_till_done()
def test_setup_platform(self):
"""Set up platform with one entity."""
config = {
ip.DOMAIN: {
"platform": "openalpr_cloud",
"source": {"entity_id": "camera.demo_camera"},
"region": "eu",
"api_key": "sk_abcxyz123456",
},
"camera": {"platform": "demo"},
}
with assert_setup_component(1, ip.DOMAIN):
setup_component(self.hass, ip.DOMAIN, config)
self.hass.block_till_done()
assert self.hass.states.get("image_processing.openalpr_demo_camera")
def test_setup_platform_name(self):
"""Set up platform with one entity and set name."""
config = {
ip.DOMAIN: {
"platform": "openalpr_cloud",
"source": {"entity_id": "camera.demo_camera", "name": "test local"},
"region": "eu",
"api_key": "sk_abcxyz123456",
},
"camera": {"platform": "demo"},
}
with assert_setup_component(1, ip.DOMAIN):
setup_component(self.hass, ip.DOMAIN, config)
self.hass.block_till_done()
assert self.hass.states.get("image_processing.test_local")
def test_setup_platform_without_api_key(self):
"""Set up platform with one entity without api_key."""
config = {
ip.DOMAIN: {
"platform": "openalpr_cloud",
"source": {"entity_id": "camera.demo_camera"},
"region": "eu",
},
"camera": {"platform": "demo"},
}
with assert_setup_component(0, ip.DOMAIN):
setup_component(self.hass, ip.DOMAIN, config)
def test_setup_platform_without_region(self):
"""Set up platform with one entity without region."""
config = {
ip.DOMAIN: {
"platform": "openalpr_cloud",
"source": {"entity_id": "camera.demo_camera"},
"api_key": "sk_abcxyz123456",
},
"camera": {"platform": "demo"},
}
with assert_setup_component(0, ip.DOMAIN):
setup_component(self.hass, ip.DOMAIN, config)
class TestOpenAlprCloud: @pytest.fixture
"""Test class for image processing.""" async def alpr_events(hass):
"""Listen for events."""
return async_capture_events(hass, "image_processing.found_plate")
def setup_method(self):
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
config = { PARAMS = {
ip.DOMAIN: { "secret_key": "sk_abcxyz123456",
"platform": "openalpr_cloud", "tasks": "plate",
"source": {"entity_id": "camera.demo_camera", "name": "test local"}, "return_image": 0,
"region": "eu", "country": "eu",
"api_key": "sk_abcxyz123456", }
},
"camera": {"platform": "demo"},
}
with patch(
"homeassistant.components.openalpr_cloud.image_processing."
"OpenAlprCloudEntity.should_poll",
new_callable=PropertyMock(return_value=False),
):
setup_component(self.hass, ip.DOMAIN, config)
self.hass.block_till_done()
self.alpr_events = [] async def test_setup_platform(hass):
"""Set up platform with one entity."""
config = {
ip.DOMAIN: {
"platform": "openalpr_cloud",
"source": {"entity_id": "camera.demo_camera"},
"region": "eu",
"api_key": "sk_abcxyz123456",
},
"camera": {"platform": "demo"},
}
@callback with assert_setup_component(1, ip.DOMAIN):
def mock_alpr_event(event): await async_setup_component(hass, ip.DOMAIN, config)
"""Mock event.""" await hass.async_block_till_done()
self.alpr_events.append(event)
self.hass.bus.listen("image_processing.found_plate", mock_alpr_event) assert hass.states.get("image_processing.openalpr_demo_camera")
self.params = {
"secret_key": "sk_abcxyz123456",
"tasks": "plate",
"return_image": 0,
"country": "eu",
}
def teardown_method(self): async def test_setup_platform_name(hass):
"""Stop everything that was started.""" """Set up platform with one entity and set name."""
self.hass.stop() config = {
ip.DOMAIN: {
"platform": "openalpr_cloud",
"source": {"entity_id": "camera.demo_camera", "name": "test local"},
"region": "eu",
"api_key": "sk_abcxyz123456",
},
"camera": {"platform": "demo"},
}
def test_openalpr_process_image(self, aioclient_mock): with assert_setup_component(1, ip.DOMAIN):
"""Set up and scan a picture and test plates from event.""" await async_setup_component(hass, ip.DOMAIN, config)
aioclient_mock.post( await hass.async_block_till_done()
OPENALPR_API_URL,
params=self.params,
text=load_fixture("alpr_cloud.json"),
status=200,
)
with patch( assert hass.states.get("image_processing.test_local")
"homeassistant.components.camera.async_get_image",
return_value=camera.Image("image/jpeg", b"image"),
):
common.scan(self.hass, entity_id="image_processing.test_local")
self.hass.block_till_done()
state = self.hass.states.get("image_processing.test_local")
assert len(aioclient_mock.mock_calls) == 1 async def test_setup_platform_without_api_key(hass):
assert len(self.alpr_events) == 5 """Set up platform with one entity without api_key."""
assert state.attributes.get("vehicles") == 1 config = {
assert state.state == "H786P0J" ip.DOMAIN: {
"platform": "openalpr_cloud",
"source": {"entity_id": "camera.demo_camera"},
"region": "eu",
},
"camera": {"platform": "demo"},
}
event_data = [ with assert_setup_component(0, ip.DOMAIN):
event.data await async_setup_component(hass, ip.DOMAIN, config)
for event in self.alpr_events
if event.data.get("plate") == "H786P0J"
]
assert len(event_data) == 1
assert event_data[0]["plate"] == "H786P0J"
assert event_data[0]["confidence"] == float(90.436699)
assert event_data[0]["entity_id"] == "image_processing.test_local"
def test_openalpr_process_image_api_error(self, aioclient_mock):
"""Set up and scan a picture and test api error."""
aioclient_mock.post(
OPENALPR_API_URL,
params=self.params,
text="{'error': 'error message'}",
status=400,
)
with patch( async def test_setup_platform_without_region(hass):
"homeassistant.components.camera.async_get_image", """Set up platform with one entity without region."""
return_value=camera.Image("image/jpeg", b"image"), config = {
): ip.DOMAIN: {
common.scan(self.hass, entity_id="image_processing.test_local") "platform": "openalpr_cloud",
self.hass.block_till_done() "source": {"entity_id": "camera.demo_camera"},
"api_key": "sk_abcxyz123456",
},
"camera": {"platform": "demo"},
}
assert len(aioclient_mock.mock_calls) == 1 with assert_setup_component(0, ip.DOMAIN):
assert len(self.alpr_events) == 0 await async_setup_component(hass, ip.DOMAIN, config)
def test_openalpr_process_image_api_timeout(self, aioclient_mock):
"""Set up and scan a picture and test api error."""
aioclient_mock.post(
OPENALPR_API_URL, params=self.params, exc=asyncio.TimeoutError()
)
with patch( async def test_openalpr_process_image(
"homeassistant.components.camera.async_get_image", alpr_events, setup_openalpr_cloud, hass, aioclient_mock
return_value=camera.Image("image/jpeg", b"image"), ):
): """Set up and scan a picture and test plates from event."""
common.scan(self.hass, entity_id="image_processing.test_local") aioclient_mock.post(
self.hass.block_till_done() OPENALPR_API_URL,
params=PARAMS,
text=load_fixture("alpr_cloud.json"),
status=200,
)
assert len(aioclient_mock.mock_calls) == 1 with patch(
assert len(self.alpr_events) == 0 "homeassistant.components.camera.async_get_image",
return_value=camera.Image("image/jpeg", b"image"),
):
common.async_scan(hass, entity_id="image_processing.test_local")
await hass.async_block_till_done()
state = hass.states.get("image_processing.test_local")
assert len(aioclient_mock.mock_calls) == 1
assert len(alpr_events) == 5
assert state.attributes.get("vehicles") == 1
assert state.state == "H786P0J"
event_data = [
event.data for event in alpr_events if event.data.get("plate") == "H786P0J"
]
assert len(event_data) == 1
assert event_data[0]["plate"] == "H786P0J"
assert event_data[0]["confidence"] == float(90.436699)
assert event_data[0]["entity_id"] == "image_processing.test_local"
async def test_openalpr_process_image_api_error(
alpr_events, setup_openalpr_cloud, hass, aioclient_mock
):
"""Set up and scan a picture and test api error."""
aioclient_mock.post(
OPENALPR_API_URL,
params=PARAMS,
text="{'error': 'error message'}",
status=400,
)
with patch(
"homeassistant.components.camera.async_get_image",
return_value=camera.Image("image/jpeg", b"image"),
):
common.async_scan(hass, entity_id="image_processing.test_local")
await hass.async_block_till_done()
assert len(aioclient_mock.mock_calls) == 1
assert len(alpr_events) == 0
async def test_openalpr_process_image_api_timeout(
alpr_events, setup_openalpr_cloud, hass, aioclient_mock
):
"""Set up and scan a picture and test api error."""
aioclient_mock.post(OPENALPR_API_URL, params=PARAMS, exc=asyncio.TimeoutError())
with patch(
"homeassistant.components.camera.async_get_image",
return_value=camera.Image("image/jpeg", b"image"),
):
common.async_scan(hass, entity_id="image_processing.test_local")
await hass.async_block_till_done()
assert len(aioclient_mock.mock_calls) == 1
assert len(alpr_events) == 0

View File

@ -1,16 +1,52 @@
"""The tests for the openalpr local platform.""" """The tests for the openalpr local platform."""
from unittest.mock import MagicMock, PropertyMock, patch from unittest.mock import MagicMock, PropertyMock, patch
import pytest
import homeassistant.components.image_processing as ip import homeassistant.components.image_processing as ip
from homeassistant.const import ATTR_ENTITY_PICTURE from homeassistant.const import ATTR_ENTITY_PICTURE
from homeassistant.core import callback from homeassistant.setup import async_setup_component
from homeassistant.setup import setup_component
from tests.common import assert_setup_component, get_test_home_assistant, load_fixture from tests.common import assert_setup_component, async_capture_events, load_fixture
from tests.components.image_processing import common from tests.components.image_processing import common
def mock_async_subprocess(): @pytest.fixture
async def setup_openalpr_local(hass):
"""Set up openalpr local."""
config = {
ip.DOMAIN: {
"platform": "openalpr_local",
"source": {"entity_id": "camera.demo_camera", "name": "test local"},
"region": "eu",
},
"camera": {"platform": "demo"},
}
with patch(
"homeassistant.components.openalpr_local.image_processing."
"OpenAlprLocalEntity.should_poll",
new_callable=PropertyMock(return_value=False),
):
await async_setup_component(hass, ip.DOMAIN, config)
await hass.async_block_till_done()
@pytest.fixture
def url(hass, setup_openalpr_local):
"""Return the camera URL."""
state = hass.states.get("camera.demo_camera")
return f"{hass.config.internal_url}{state.attributes.get(ATTR_ENTITY_PICTURE)}"
@pytest.fixture
async def alpr_events(hass):
"""Listen for events."""
return async_capture_events(hass, "image_processing.found_plate")
@pytest.fixture
def popen_mock():
"""Get a Popen mock back.""" """Get a Popen mock back."""
async_popen = MagicMock() async_popen = MagicMock()
@ -20,130 +56,87 @@ def mock_async_subprocess():
return (fixture, None) return (fixture, None)
async_popen.communicate = communicate async_popen.communicate = communicate
return async_popen
with patch("asyncio.create_subprocess_exec", return_value=async_popen) as mock:
yield mock
class TestOpenAlprLocalSetup: async def test_setup_platform(hass):
"""Test class for image processing.""" """Set up platform with one entity."""
config = {
ip.DOMAIN: {
"platform": "openalpr_local",
"source": {"entity_id": "camera.demo_camera"},
"region": "eu",
},
"camera": {"platform": "demo"},
}
def setup_method(self): with assert_setup_component(1, ip.DOMAIN):
"""Set up things to be run when tests are started.""" await async_setup_component(hass, ip.DOMAIN, config)
self.hass = get_test_home_assistant() await hass.async_block_till_done()
def teardown_method(self): assert hass.states.get("image_processing.openalpr_demo_camera")
"""Stop everything that was started."""
self.hass.stop()
def test_setup_platform(self):
"""Set up platform with one entity."""
config = {
ip.DOMAIN: {
"platform": "openalpr_local",
"source": {"entity_id": "camera.demo_camera"},
"region": "eu",
},
"camera": {"platform": "demo"},
}
with assert_setup_component(1, ip.DOMAIN):
setup_component(self.hass, ip.DOMAIN, config)
self.hass.block_till_done()
assert self.hass.states.get("image_processing.openalpr_demo_camera")
def test_setup_platform_name(self):
"""Set up platform with one entity and set name."""
config = {
ip.DOMAIN: {
"platform": "openalpr_local",
"source": {"entity_id": "camera.demo_camera", "name": "test local"},
"region": "eu",
},
"camera": {"platform": "demo"},
}
with assert_setup_component(1, ip.DOMAIN):
setup_component(self.hass, ip.DOMAIN, config)
self.hass.block_till_done()
assert self.hass.states.get("image_processing.test_local")
def test_setup_platform_without_region(self):
"""Set up platform with one entity without region."""
config = {
ip.DOMAIN: {
"platform": "openalpr_local",
"source": {"entity_id": "camera.demo_camera"},
},
"camera": {"platform": "demo"},
}
with assert_setup_component(0, ip.DOMAIN):
setup_component(self.hass, ip.DOMAIN, config)
self.hass.block_till_done()
class TestOpenAlprLocal: async def test_setup_platform_name(hass):
"""Test class for image processing.""" """Set up platform with one entity and set name."""
config = {
ip.DOMAIN: {
"platform": "openalpr_local",
"source": {"entity_id": "camera.demo_camera", "name": "test local"},
"region": "eu",
},
"camera": {"platform": "demo"},
}
def setup_method(self): with assert_setup_component(1, ip.DOMAIN):
"""Set up things to be run when tests are started.""" await async_setup_component(hass, ip.DOMAIN, config)
self.hass = get_test_home_assistant() await hass.async_block_till_done()
config = { assert hass.states.get("image_processing.test_local")
ip.DOMAIN: {
"platform": "openalpr_local",
"source": {"entity_id": "camera.demo_camera", "name": "test local"},
"region": "eu",
},
"camera": {"platform": "demo"},
}
with patch(
"homeassistant.components.openalpr_local.image_processing."
"OpenAlprLocalEntity.should_poll",
new_callable=PropertyMock(return_value=False),
):
setup_component(self.hass, ip.DOMAIN, config)
self.hass.block_till_done()
state = self.hass.states.get("camera.demo_camera") async def test_setup_platform_without_region(hass):
self.url = f"{self.hass.config.internal_url}{state.attributes.get(ATTR_ENTITY_PICTURE)}" """Set up platform with one entity without region."""
config = {
ip.DOMAIN: {
"platform": "openalpr_local",
"source": {"entity_id": "camera.demo_camera"},
},
"camera": {"platform": "demo"},
}
self.alpr_events = [] with assert_setup_component(0, ip.DOMAIN):
await async_setup_component(hass, ip.DOMAIN, config)
await hass.async_block_till_done()
@callback
def mock_alpr_event(event):
"""Mock event."""
self.alpr_events.append(event)
self.hass.bus.listen("image_processing.found_plate", mock_alpr_event) async def test_openalpr_process_image(
setup_openalpr_local,
url,
hass,
alpr_events,
popen_mock,
aioclient_mock,
):
"""Set up and scan a picture and test plates from event."""
aioclient_mock.get(url, content=b"image")
def teardown_method(self): common.async_scan(hass, entity_id="image_processing.test_local")
"""Stop everything that was started.""" await hass.async_block_till_done()
self.hass.stop()
@patch("asyncio.create_subprocess_exec", return_value=mock_async_subprocess()) state = hass.states.get("image_processing.test_local")
def test_openalpr_process_image(self, popen_mock, aioclient_mock):
"""Set up and scan a picture and test plates from event."""
aioclient_mock.get(self.url, content=b"image")
common.scan(self.hass, entity_id="image_processing.test_local") assert popen_mock.called
self.hass.block_till_done() assert len(alpr_events) == 5
assert state.attributes.get("vehicles") == 1
assert state.state == "PE3R2X"
state = self.hass.states.get("image_processing.test_local") event_data = [
event.data for event in alpr_events if event.data.get("plate") == "PE3R2X"
assert popen_mock.called ]
assert len(self.alpr_events) == 5 assert len(event_data) == 1
assert state.attributes.get("vehicles") == 1 assert event_data[0]["plate"] == "PE3R2X"
assert state.state == "PE3R2X" assert event_data[0]["confidence"] == float(98.9371)
assert event_data[0]["entity_id"] == "image_processing.test_local"
event_data = [
event.data
for event in self.alpr_events
if event.data.get("plate") == "PE3R2X"
]
assert len(event_data) == 1
assert event_data[0]["plate"] == "PE3R2X"
assert event_data[0]["confidence"] == float(98.9371)
assert event_data[0]["entity_id"] == "image_processing.test_local"