mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Started unit tests for the review controller (#15077)
* Started unit tests for the review controller
* Revert "Started unit tests for the review controller"
This reverts commit 7746eb146f
.
* Started unit tests for the review controller
* FIrst test
* Added test for review endpoint (time filter - after + before)
* Assert expected event
* Added more tests for review endpoint
* Added test for review endpoint with all filters
* Added test for review endpoint with limit
* Comment
* Renamed tests to increase readability
This commit is contained in:
parent
0df091f387
commit
e76f4e9bd9
@ -12,6 +12,7 @@ argmax
|
|||||||
argmin
|
argmin
|
||||||
argpartition
|
argpartition
|
||||||
ascontiguousarray
|
ascontiguousarray
|
||||||
|
astype
|
||||||
authelia
|
authelia
|
||||||
authentik
|
authentik
|
||||||
autodetected
|
autodetected
|
||||||
@ -195,6 +196,7 @@ poweroff
|
|||||||
preexec
|
preexec
|
||||||
probesize
|
probesize
|
||||||
protobuf
|
protobuf
|
||||||
|
pstate
|
||||||
psutil
|
psutil
|
||||||
pubkey
|
pubkey
|
||||||
putenv
|
putenv
|
||||||
@ -278,6 +280,7 @@ uvicorn
|
|||||||
vaapi
|
vaapi
|
||||||
vainfo
|
vainfo
|
||||||
variations
|
variations
|
||||||
|
vbios
|
||||||
vconcat
|
vconcat
|
||||||
vitb
|
vitb
|
||||||
vstream
|
vstream
|
||||||
|
0
frigate/test/http_api/__init__.py
Normal file
0
frigate/test/http_api/__init__.py
Normal file
162
frigate/test/http_api/base_http_test.py
Normal file
162
frigate/test/http_api/base_http_test.py
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
import datetime
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from peewee_migrate import Router
|
||||||
|
from playhouse.sqlite_ext import SqliteExtDatabase
|
||||||
|
from playhouse.sqliteq import SqliteQueueDatabase
|
||||||
|
|
||||||
|
from frigate.api.fastapi_app import create_fastapi_app
|
||||||
|
from frigate.config import FrigateConfig
|
||||||
|
from frigate.models import Event, ReviewSegment
|
||||||
|
from frigate.review.maintainer import SeverityEnum
|
||||||
|
from frigate.test.const import TEST_DB, TEST_DB_CLEANUPS
|
||||||
|
|
||||||
|
|
||||||
|
class BaseTestHttp(unittest.TestCase):
|
||||||
|
def setUp(self, models):
|
||||||
|
# setup clean database for each test run
|
||||||
|
migrate_db = SqliteExtDatabase("test.db")
|
||||||
|
del logging.getLogger("peewee_migrate").handlers[:]
|
||||||
|
router = Router(migrate_db)
|
||||||
|
router.run()
|
||||||
|
migrate_db.close()
|
||||||
|
self.db = SqliteQueueDatabase(TEST_DB)
|
||||||
|
self.db.bind(models)
|
||||||
|
|
||||||
|
self.minimal_config = {
|
||||||
|
"mqtt": {"host": "mqtt"},
|
||||||
|
"cameras": {
|
||||||
|
"front_door": {
|
||||||
|
"ffmpeg": {
|
||||||
|
"inputs": [
|
||||||
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"detect": {
|
||||||
|
"height": 1080,
|
||||||
|
"width": 1920,
|
||||||
|
"fps": 5,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
self.test_stats = {
|
||||||
|
"detection_fps": 13.7,
|
||||||
|
"detectors": {
|
||||||
|
"cpu1": {
|
||||||
|
"detection_start": 0.0,
|
||||||
|
"inference_speed": 91.43,
|
||||||
|
"pid": 42,
|
||||||
|
},
|
||||||
|
"cpu2": {
|
||||||
|
"detection_start": 0.0,
|
||||||
|
"inference_speed": 84.99,
|
||||||
|
"pid": 44,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"front_door": {
|
||||||
|
"camera_fps": 0.0,
|
||||||
|
"capture_pid": 53,
|
||||||
|
"detection_fps": 0.0,
|
||||||
|
"pid": 52,
|
||||||
|
"process_fps": 0.0,
|
||||||
|
"skipped_fps": 0.0,
|
||||||
|
},
|
||||||
|
"service": {
|
||||||
|
"storage": {
|
||||||
|
"/dev/shm": {
|
||||||
|
"free": 50.5,
|
||||||
|
"mount_type": "tmpfs",
|
||||||
|
"total": 67.1,
|
||||||
|
"used": 16.6,
|
||||||
|
},
|
||||||
|
"/media/frigate/clips": {
|
||||||
|
"free": 42429.9,
|
||||||
|
"mount_type": "ext4",
|
||||||
|
"total": 244529.7,
|
||||||
|
"used": 189607.0,
|
||||||
|
},
|
||||||
|
"/media/frigate/recordings": {
|
||||||
|
"free": 0.2,
|
||||||
|
"mount_type": "ext4",
|
||||||
|
"total": 8.0,
|
||||||
|
"used": 7.8,
|
||||||
|
},
|
||||||
|
"/tmp/cache": {
|
||||||
|
"free": 976.8,
|
||||||
|
"mount_type": "tmpfs",
|
||||||
|
"total": 1000.0,
|
||||||
|
"used": 23.2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"uptime": 101113,
|
||||||
|
"version": "0.10.1",
|
||||||
|
"latest_version": "0.11",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
if not self.db.is_closed():
|
||||||
|
self.db.close()
|
||||||
|
|
||||||
|
try:
|
||||||
|
for file in TEST_DB_CLEANUPS:
|
||||||
|
os.remove(file)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def create_app(self, stats=None):
|
||||||
|
return create_fastapi_app(
|
||||||
|
FrigateConfig(**self.minimal_config),
|
||||||
|
self.db,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
stats,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
|
||||||
|
def insert_mock_event(
|
||||||
|
self,
|
||||||
|
id: str,
|
||||||
|
start_time: datetime.datetime = datetime.datetime.now().timestamp(),
|
||||||
|
) -> Event:
|
||||||
|
"""Inserts a basic event model with a given id."""
|
||||||
|
return Event.insert(
|
||||||
|
id=id,
|
||||||
|
label="Mock",
|
||||||
|
camera="front_door",
|
||||||
|
start_time=start_time,
|
||||||
|
end_time=start_time + 20,
|
||||||
|
top_score=100,
|
||||||
|
false_positive=False,
|
||||||
|
zones=list(),
|
||||||
|
thumbnail="",
|
||||||
|
region=[],
|
||||||
|
box=[],
|
||||||
|
area=0,
|
||||||
|
has_clip=True,
|
||||||
|
has_snapshot=True,
|
||||||
|
).execute()
|
||||||
|
|
||||||
|
def insert_mock_review_segment(
|
||||||
|
self,
|
||||||
|
id: str,
|
||||||
|
start_time: datetime.datetime = datetime.datetime.now().timestamp(),
|
||||||
|
end_time: datetime.datetime = datetime.datetime.now().timestamp() + 20,
|
||||||
|
) -> Event:
|
||||||
|
"""Inserts a basic event model with a given id."""
|
||||||
|
return ReviewSegment.insert(
|
||||||
|
id=id,
|
||||||
|
camera="front_door",
|
||||||
|
start_time=start_time,
|
||||||
|
end_time=end_time,
|
||||||
|
has_been_reviewed=False,
|
||||||
|
severity=SeverityEnum.alert,
|
||||||
|
thumb_path=False,
|
||||||
|
data={},
|
||||||
|
).execute()
|
110
frigate/test/http_api/test_http_review.py
Normal file
110
frigate/test/http_api/test_http_review.py
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
import datetime
|
||||||
|
|
||||||
|
from fastapi.testclient import TestClient
|
||||||
|
|
||||||
|
from frigate.models import Event, ReviewSegment
|
||||||
|
from frigate.test.http_api.base_http_test import BaseTestHttp
|
||||||
|
|
||||||
|
|
||||||
|
class TestHttpReview(BaseTestHttp):
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp([Event, ReviewSegment])
|
||||||
|
|
||||||
|
# Does not return any data point since the end time (before parameter) is not passed and the review segment end_time is 2 seconds from now
|
||||||
|
def test_get_review_no_filters_no_matches(self):
|
||||||
|
app = super().create_app()
|
||||||
|
now = datetime.datetime.now().timestamp()
|
||||||
|
|
||||||
|
with TestClient(app) as client:
|
||||||
|
super().insert_mock_review_segment("123456.random", now, now + 2)
|
||||||
|
reviews_response = client.get("/review")
|
||||||
|
assert reviews_response.status_code == 200
|
||||||
|
reviews_in_response = reviews_response.json()
|
||||||
|
assert len(reviews_in_response) == 0
|
||||||
|
|
||||||
|
def test_get_review_no_filters(self):
|
||||||
|
app = super().create_app()
|
||||||
|
now = datetime.datetime.now().timestamp()
|
||||||
|
|
||||||
|
with TestClient(app) as client:
|
||||||
|
super().insert_mock_review_segment("123456.random", now - 2, now - 1)
|
||||||
|
reviews_response = client.get("/review")
|
||||||
|
assert reviews_response.status_code == 200
|
||||||
|
reviews_in_response = reviews_response.json()
|
||||||
|
assert len(reviews_in_response) == 1
|
||||||
|
|
||||||
|
def test_get_review_with_time_filter_no_matches(self):
|
||||||
|
app = super().create_app()
|
||||||
|
now = datetime.datetime.now().timestamp()
|
||||||
|
|
||||||
|
with TestClient(app) as client:
|
||||||
|
id = "123456.random"
|
||||||
|
super().insert_mock_review_segment(id, now, now + 2)
|
||||||
|
params = {
|
||||||
|
"after": now,
|
||||||
|
"before": now + 3,
|
||||||
|
}
|
||||||
|
reviews_response = client.get("/review", params=params)
|
||||||
|
assert reviews_response.status_code == 200
|
||||||
|
reviews_in_response = reviews_response.json()
|
||||||
|
assert len(reviews_in_response) == 0
|
||||||
|
|
||||||
|
def test_get_review_with_time_filter(self):
|
||||||
|
app = super().create_app()
|
||||||
|
now = datetime.datetime.now().timestamp()
|
||||||
|
|
||||||
|
with TestClient(app) as client:
|
||||||
|
id = "123456.random"
|
||||||
|
super().insert_mock_review_segment(id, now, now + 2)
|
||||||
|
params = {
|
||||||
|
"after": now - 1,
|
||||||
|
"before": now + 3,
|
||||||
|
}
|
||||||
|
reviews_response = client.get("/review", params=params)
|
||||||
|
assert reviews_response.status_code == 200
|
||||||
|
reviews_in_response = reviews_response.json()
|
||||||
|
assert len(reviews_in_response) == 1
|
||||||
|
assert reviews_in_response[0]["id"] == id
|
||||||
|
|
||||||
|
def test_get_review_with_limit_filter(self):
|
||||||
|
app = super().create_app()
|
||||||
|
now = datetime.datetime.now().timestamp()
|
||||||
|
|
||||||
|
with TestClient(app) as client:
|
||||||
|
id = "123456.random"
|
||||||
|
id2 = "654321.random"
|
||||||
|
super().insert_mock_review_segment(id, now, now + 2)
|
||||||
|
super().insert_mock_review_segment(id2, now + 1, now + 2)
|
||||||
|
params = {
|
||||||
|
"limit": 1,
|
||||||
|
"after": now,
|
||||||
|
"before": now + 3,
|
||||||
|
}
|
||||||
|
reviews_response = client.get("/review", params=params)
|
||||||
|
assert reviews_response.status_code == 200
|
||||||
|
reviews_in_response = reviews_response.json()
|
||||||
|
assert len(reviews_in_response) == 1
|
||||||
|
assert reviews_in_response[0]["id"] == id2
|
||||||
|
|
||||||
|
def test_get_review_with_all_filters(self):
|
||||||
|
app = super().create_app()
|
||||||
|
now = datetime.datetime.now().timestamp()
|
||||||
|
|
||||||
|
with TestClient(app) as client:
|
||||||
|
id = "123456.random"
|
||||||
|
super().insert_mock_review_segment(id, now, now + 2)
|
||||||
|
params = {
|
||||||
|
"cameras": "front_door",
|
||||||
|
"labels": "all",
|
||||||
|
"zones": "all",
|
||||||
|
"reviewed": 0,
|
||||||
|
"limit": 1,
|
||||||
|
"severity": "alert",
|
||||||
|
"after": now - 1,
|
||||||
|
"before": now + 3,
|
||||||
|
}
|
||||||
|
reviews_response = client.get("/review", params=params)
|
||||||
|
assert reviews_response.status_code == 200
|
||||||
|
reviews_in_response = reviews_response.json()
|
||||||
|
assert len(reviews_in_response) == 1
|
||||||
|
assert reviews_in_response[0]["id"] == id
|
Loading…
Reference in New Issue
Block a user