Sound test (#1820)
* WIP sound test
* it does something
* refactor
* phone only
* update release files
* test sound card init
* add to CI
* check writes
* increase time
* unused
* only build cereal
* small tolerance
Co-authored-by: Comma Device <device@comma.ai>
old-commit-hash: f1afb3e3ae
commatwo_master
parent
06516d0f4c
commit
0d79150606
9 changed files with 147 additions and 70 deletions
@ -1,8 +0,0 @@ |
|||||||
import os |
|
||||||
from nose.tools import nottest |
|
||||||
|
|
||||||
def phone_only(x): |
|
||||||
if os.path.isfile("/init.qcom.rc"): |
|
||||||
return x |
|
||||||
else: |
|
||||||
return nottest(x) |
|
@ -0,0 +1,56 @@ |
|||||||
|
import subprocess |
||||||
|
from functools import wraps |
||||||
|
from nose.tools import nottest |
||||||
|
|
||||||
|
from common.android import ANDROID |
||||||
|
from common.apk import update_apks, start_offroad, pm_apply_packages, android_packages |
||||||
|
from selfdrive.manager import start_managed_process, kill_managed_process, get_running |
||||||
|
|
||||||
|
def phone_only(x): |
||||||
|
if ANDROID: |
||||||
|
return x |
||||||
|
else: |
||||||
|
return nottest(x) |
||||||
|
|
||||||
|
def with_processes(processes): |
||||||
|
def wrapper(func): |
||||||
|
@wraps(func) |
||||||
|
def wrap(): |
||||||
|
# start and assert started |
||||||
|
[start_managed_process(p) for p in processes] |
||||||
|
assert all(get_running()[name].exitcode is None for name in processes) |
||||||
|
|
||||||
|
# call the function |
||||||
|
try: |
||||||
|
func() |
||||||
|
# assert processes are still started |
||||||
|
assert all(get_running()[name].exitcode is None for name in processes) |
||||||
|
finally: |
||||||
|
# kill and assert all stopped |
||||||
|
[kill_managed_process(p) for p in processes] |
||||||
|
assert len(get_running()) == 0 |
||||||
|
return wrap |
||||||
|
return wrapper |
||||||
|
|
||||||
|
def with_apks(): |
||||||
|
def wrapper(func): |
||||||
|
@wraps(func) |
||||||
|
def wrap(): |
||||||
|
update_apks() |
||||||
|
pm_apply_packages('enable') |
||||||
|
start_offroad() |
||||||
|
|
||||||
|
func() |
||||||
|
|
||||||
|
try: |
||||||
|
for package in android_packages: |
||||||
|
apk_is_running = (subprocess.call(["pidof", package]) == 0) |
||||||
|
assert apk_is_running, package |
||||||
|
finally: |
||||||
|
pm_apply_packages('disable') |
||||||
|
for package in android_packages: |
||||||
|
apk_is_not_running = (subprocess.call(["pidof", package]) == 1) |
||||||
|
assert apk_is_not_running, package |
||||||
|
return wrap |
||||||
|
return wrapper |
||||||
|
|
@ -0,0 +1,68 @@ |
|||||||
|
#!/usr/bin/env python3 |
||||||
|
import time |
||||||
|
import subprocess |
||||||
|
|
||||||
|
from cereal import car |
||||||
|
import cereal.messaging as messaging |
||||||
|
from selfdrive.test.helpers import phone_only, with_processes |
||||||
|
from common.android import get_sound_card_online |
||||||
|
from common.realtime import DT_CTRL |
||||||
|
|
||||||
|
AudibleAlert = car.CarControl.HUDControl.AudibleAlert |
||||||
|
|
||||||
|
SOUNDS = { |
||||||
|
# sound: total writes |
||||||
|
AudibleAlert.none: 0, |
||||||
|
AudibleAlert.chimeEngage: 85, |
||||||
|
AudibleAlert.chimeDisengage: 85, |
||||||
|
AudibleAlert.chimeError: 85, |
||||||
|
AudibleAlert.chimePrompt: 85, |
||||||
|
AudibleAlert.chimeWarning1: 80, |
||||||
|
AudibleAlert.chimeWarning2: 107, |
||||||
|
AudibleAlert.chimeWarningRepeat: 134, |
||||||
|
AudibleAlert.chimeWarning2Repeat: 177, |
||||||
|
} |
||||||
|
|
||||||
|
def get_total_writes(): |
||||||
|
audio_flinger = subprocess.check_output('dumpsys media.audio_flinger', shell=True, encoding='utf-8').strip() |
||||||
|
write_lines = [l for l in audio_flinger.split('\n') if l.strip().startswith('Total writes')] |
||||||
|
return sum([int(l.split(':')[1]) for l in write_lines]) |
||||||
|
|
||||||
|
@phone_only |
||||||
|
def test_sound_card_init(): |
||||||
|
assert get_sound_card_online() |
||||||
|
|
||||||
|
|
||||||
|
@phone_only |
||||||
|
@with_processes(['ui', 'camerad']) |
||||||
|
def test_alert_sounds(): |
||||||
|
|
||||||
|
pm = messaging.PubMaster(['thermal', 'controlsState']) |
||||||
|
|
||||||
|
# make sure they're all defined |
||||||
|
alert_sounds = {v: k for k, v in car.CarControl.HUDControl.AudibleAlert.schema.enumerants.items()} |
||||||
|
diff = set(SOUNDS.keys()).symmetric_difference(alert_sounds.keys()) |
||||||
|
assert len(diff) == 0, f"not all sounds defined in test: {diff}" |
||||||
|
|
||||||
|
# wait for procs to init |
||||||
|
time.sleep(5) |
||||||
|
|
||||||
|
msg = messaging.new_message('thermal') |
||||||
|
msg.thermal.started = True |
||||||
|
pm.send('thermal', msg) |
||||||
|
|
||||||
|
for sound, expected_writes in SOUNDS.items(): |
||||||
|
print(f"testing {alert_sounds[sound]}") |
||||||
|
start_writes = get_total_writes() |
||||||
|
|
||||||
|
for _ in range(int(9 / DT_CTRL)): |
||||||
|
msg = messaging.new_message('controlsState') |
||||||
|
msg.controlsState.enabled = True |
||||||
|
msg.controlsState.active = True |
||||||
|
msg.controlsState.alertSound = sound |
||||||
|
msg.controlsState.alertType = str(sound) |
||||||
|
pm.send('controlsState', msg) |
||||||
|
time.sleep(DT_CTRL) |
||||||
|
|
||||||
|
actual_writes = get_total_writes() - start_writes |
||||||
|
assert abs(expected_writes - actual_writes) <= 2, f"{alert_sounds[sound]}: expected {expected_writes} writes, got {actual_writes}" |
Loading…
Reference in new issue