mirror of
https://github.com/espressif/esp-sr.git
synced 2025-09-15 15:28:44 +08:00
feat: Add ci to test all API of multinet, wakenet and afe
This commit is contained in:
parent
85b75fba3a
commit
297596c0f9
8
.gitignore
vendored
8
.gitignore
vendored
@ -24,4 +24,10 @@ _build/*
|
||||
|
||||
# Downloaded font files
|
||||
docs/_static/DejaVuSans.ttf
|
||||
docs/_static/NotoSansSC-Regular.otf
|
||||
docs/_static/NotoSansSC-Regular.otf
|
||||
|
||||
# ci
|
||||
test_apps/dependencies.lock
|
||||
test_apps/managed_components
|
||||
test_apps/*/build_*
|
||||
pytest_log
|
||||
|
||||
215
conftest.py
Normal file
215
conftest.py
Normal file
@ -0,0 +1,215 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
import re
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from typing import Callable, List, Optional, Tuple
|
||||
|
||||
import pytest
|
||||
from pytest import Config, FixtureRequest, Function, Session
|
||||
from pytest_embedded.plugin import multi_dut_argument, multi_dut_fixture
|
||||
|
||||
IDF_VERSION = os.environ.get('IDF_VERSION')
|
||||
PYTEST_ROOT_DIR = str(pathlib.Path(__file__).parent)
|
||||
logging.info(f'Pytest root dir: {PYTEST_ROOT_DIR}')
|
||||
|
||||
|
||||
@pytest.fixture(scope='session', autouse=True)
|
||||
def idf_version() -> str:
|
||||
if os.environ.get('IDF_VERSION'):
|
||||
return os.environ.get('IDF_VERSION')
|
||||
idf_path = os.environ.get('IDF_PATH')
|
||||
if not idf_path:
|
||||
logging.warning('Failed to get IDF_VERSION!')
|
||||
return ''
|
||||
version_path = os.path.join(os.environ['IDF_PATH'], 'tools/cmake/version.cmake')
|
||||
regex = re.compile(r'^\s*set\s*\(\s*IDF_VERSION_([A-Z]{5})\s+(\d+)')
|
||||
ver = {}
|
||||
with open(version_path) as f:
|
||||
for line in f:
|
||||
m = regex.match(line)
|
||||
if m:
|
||||
ver[m.group(1)] = m.group(2)
|
||||
return '{}.{}'.format(int(ver['MAJOR']), int(ver['MINOR']))
|
||||
|
||||
|
||||
@pytest.fixture(scope='session', autouse=True)
|
||||
def session_tempdir() -> str:
|
||||
_tmpdir = os.path.join(
|
||||
os.path.dirname(__file__),
|
||||
'pytest_log',
|
||||
datetime.now().strftime('%Y-%m-%d_%H-%M-%S'),
|
||||
)
|
||||
os.makedirs(_tmpdir, exist_ok=True)
|
||||
return _tmpdir
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@multi_dut_argument
|
||||
def config(request: FixtureRequest) -> str:
|
||||
config_marker = list(request.node.iter_markers(name='config'))
|
||||
return config_marker[0].args[0] if config_marker else 'default'
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@multi_dut_argument
|
||||
def app_path(request: FixtureRequest, test_file_path: str) -> str:
|
||||
config_marker = list(request.node.iter_markers(name='app_path'))
|
||||
if config_marker:
|
||||
return config_marker[0].args[0]
|
||||
else:
|
||||
# compatible with old pytest-embedded parametrize --app_path
|
||||
return request.config.getoption('app_path', None) or os.path.dirname(test_file_path)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_case_name(request: FixtureRequest, target: str, config: str) -> str:
|
||||
if not isinstance(target, str):
|
||||
target = '|'.join(sorted(list(set(target))))
|
||||
if not isinstance(config, str):
|
||||
config = '|'.join(sorted(list(config)))
|
||||
return f'{target}.{config}.{request.node.originalname}'
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@multi_dut_fixture
|
||||
def build_dir(
|
||||
app_path: str,
|
||||
target: Optional[str],
|
||||
config: Optional[str],
|
||||
idf_version: str
|
||||
) -> Optional[str]:
|
||||
"""
|
||||
Check local build dir with the following priority:
|
||||
|
||||
1. <app_path>/${IDF_VERSION}/build_<target>_<config>
|
||||
2. <app_path>/${IDF_VERSION}/build_<target>
|
||||
3. <app_path>/build_<target>_<config>
|
||||
4. <app_path>/build
|
||||
5. <app_path>
|
||||
|
||||
Args:
|
||||
app_path: app path
|
||||
target: target
|
||||
config: config
|
||||
|
||||
Returns:
|
||||
valid build directory
|
||||
"""
|
||||
|
||||
assert target
|
||||
assert config
|
||||
check_dirs = []
|
||||
if idf_version:
|
||||
check_dirs.append(os.path.join(idf_version, f'build_{target}_{config}'))
|
||||
check_dirs.append(os.path.join(idf_version, f'build_{target}'))
|
||||
check_dirs.append(f'build_{target}_{config}')
|
||||
check_dirs.append('build')
|
||||
check_dirs.append('.')
|
||||
for check_dir in check_dirs:
|
||||
binary_path = os.path.join(app_path, check_dir)
|
||||
if os.path.isdir(binary_path):
|
||||
logging.info(f'find valid binary path: {binary_path}')
|
||||
return check_dir
|
||||
|
||||
logging.warning(
|
||||
f'checking binary path: {binary_path} ... missing ... try another place')
|
||||
|
||||
logging.error(
|
||||
f'no build dir. Please build the binary "python tools/build_apps.py {app_path}" and run pytest again')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
@multi_dut_fixture
|
||||
def junit_properties(
|
||||
test_case_name: str, record_xml_attribute: Callable[[str, object], None]
|
||||
) -> None:
|
||||
"""
|
||||
This fixture is autoused and will modify the junit report test case name to <target>.<config>.<case_name>
|
||||
"""
|
||||
record_xml_attribute('name', test_case_name)
|
||||
|
||||
|
||||
##################
|
||||
# Hook functions #
|
||||
##################
|
||||
_idf_pytest_embedded_key = pytest.StashKey['IdfPytestEmbedded']
|
||||
|
||||
|
||||
def pytest_addoption(parser: pytest.Parser) -> None:
|
||||
base_group = parser.getgroup('idf')
|
||||
base_group.addoption(
|
||||
'--env',
|
||||
help='only run tests matching the environment NAME.',
|
||||
)
|
||||
|
||||
|
||||
def pytest_configure(config: Config) -> None:
|
||||
# Require cli option "--target"
|
||||
help_commands = ['--help', '--fixtures', '--markers', '--version']
|
||||
for cmd in help_commands:
|
||||
if cmd in config.invocation_params.args:
|
||||
target = 'unneeded'
|
||||
break
|
||||
else:
|
||||
target = config.getoption('target')
|
||||
if not target:
|
||||
raise ValueError('Please specify one target marker via "--target [TARGET]"')
|
||||
|
||||
config.stash[_idf_pytest_embedded_key] = IdfPytestEmbedded(
|
||||
target=target,
|
||||
env_name=config.getoption('env'),
|
||||
)
|
||||
config.pluginmanager.register(config.stash[_idf_pytest_embedded_key])
|
||||
|
||||
|
||||
def pytest_unconfigure(config: Config) -> None:
|
||||
_pytest_embedded = config.stash.get(_idf_pytest_embedded_key, None)
|
||||
if _pytest_embedded:
|
||||
del config.stash[_idf_pytest_embedded_key]
|
||||
config.pluginmanager.unregister(_pytest_embedded)
|
||||
|
||||
|
||||
class IdfPytestEmbedded:
|
||||
def __init__(
|
||||
self,
|
||||
target: Optional[str] = None,
|
||||
env_name: Optional[str] = None,
|
||||
):
|
||||
# CLI options to filter the test cases
|
||||
self.target = target
|
||||
self.env_name = env_name
|
||||
|
||||
self._failed_cases: List[
|
||||
Tuple[str, bool, bool]
|
||||
] = [] # (test_case_name, is_known_failure_cases, is_xfail)
|
||||
|
||||
@pytest.hookimpl(tryfirst=True)
|
||||
def pytest_sessionstart(self, session: Session) -> None:
|
||||
if self.target:
|
||||
self.target = self.target.lower()
|
||||
session.config.option.target = self.target
|
||||
|
||||
# @pytest.hookimpl(tryfirst=True)
|
||||
def pytest_collection_modifyitems(self, items: List[Function]) -> None:
|
||||
# set default timeout 10 minutes for each case
|
||||
for item in items:
|
||||
# default timeout 5 mins
|
||||
if 'timeout' not in item.keywords:
|
||||
item.add_marker(pytest.mark.timeout(5 * 60))
|
||||
|
||||
# filter all the test cases with "--target"
|
||||
if self.target:
|
||||
def item_targets(item): return [m.args[0] for m in item.iter_markers(name='target')]
|
||||
items[:] = [item for item in items if self.target in item_targets(item)]
|
||||
|
||||
# filter all the test cases with "--env"
|
||||
if self.env_name:
|
||||
def item_envs(item): return [m.args[0] for m in item.iter_markers(name='env')]
|
||||
items[:] = [item for item in items if self.env_name in item_envs(item)]
|
||||
42
pytest.ini
Normal file
42
pytest.ini
Normal file
@ -0,0 +1,42 @@
|
||||
[pytest]
|
||||
# exclude examples/ota/simple_ota_example/pytest_simple_ota.py
|
||||
norecursedirs = examples/ota/*
|
||||
# only the files with prefix `pytest_` would be recognized as pytest test scripts.
|
||||
python_files = pytest_*.py
|
||||
|
||||
# set traceback to "short" to prevent the overwhelming tracebacks
|
||||
addopts =
|
||||
-s
|
||||
--embedded-services esp,idf
|
||||
--tb short
|
||||
--skip-check-coredump y
|
||||
|
||||
# ignore PytestExperimentalApiWarning for record_xml_attribute
|
||||
filterwarnings =
|
||||
ignore::_pytest.warning_types.PytestExperimentalApiWarning
|
||||
|
||||
|
||||
markers =
|
||||
# target markers
|
||||
target: target chip name (--target)
|
||||
# env markers
|
||||
env: target test env name (--env)
|
||||
# config markers
|
||||
config: choose specific bins built by `sdkconfig.ci.<config>`
|
||||
# app_path markers
|
||||
app_path: choose specific app_path, <app_path>[/build_xxx]
|
||||
|
||||
|
||||
# log related
|
||||
log_cli = True
|
||||
log_cli_level = INFO
|
||||
log_cli_format = %(asctime)s %(levelname)s %(message)s
|
||||
log_cli_date_format = %Y-%m-%d %H:%M:%S
|
||||
|
||||
# junit related
|
||||
junit_family = xunit1
|
||||
|
||||
|
||||
## log all to `system-out` when case fail
|
||||
junit_logging = stdout
|
||||
junit_log_passing_tests = False
|
||||
@ -1,19 +0,0 @@
|
||||
set(srcs
|
||||
test_chinese_tts.c
|
||||
)
|
||||
|
||||
if(IDF_TARGET STREQUAL "esp32")
|
||||
list(APPEND srcs test_wakenet.c
|
||||
test_afe.c
|
||||
test_multinet.c)
|
||||
|
||||
elseif(IDF_TARGET STREQUAL "esp32s3")
|
||||
list(APPEND srcs test_wakenet.c
|
||||
test_afe.c
|
||||
test_multinet.c)
|
||||
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES cmock esp-sr)
|
||||
@ -1,96 +0,0 @@
|
||||
/* test_mean.c: Implementation of a testable component.
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "string.h"
|
||||
#include <limits.h>
|
||||
#include "unity.h"
|
||||
#include <sys/time.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_tts.h"
|
||||
#include "esp_tts_voice_xiaole.h"
|
||||
#include "esp_tts_voice_template.h"
|
||||
#include "esp_tts_player.h"
|
||||
#include "esp_partition.h"
|
||||
#include "esp_idf_version.h"
|
||||
|
||||
TEST_CASE("chinese tts create/destroy API & memory leak", "[tts]")
|
||||
{
|
||||
int start_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int start_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
/*** 1. create esp tts handle ***/
|
||||
void* voicedata;
|
||||
const esp_partition_t* partition=esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "voice_data");
|
||||
assert(partition != NULL);
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
esp_partition_mmap_handle_t mmap_handle;
|
||||
ESP_ERROR_CHECK(esp_partition_mmap(partition, 0, partition->size, ESP_PARTITION_MMAP_DATA, &voicedata, &mmap_handle));
|
||||
#else
|
||||
spi_flash_mmap_handle_t mmap_handle;
|
||||
ESP_ERROR_CHECK(esp_partition_mmap(partition, 0, partition->size, SPI_FLASH_MMAP_DATA, &voicedata, &mmap_handle));
|
||||
#endif
|
||||
|
||||
// test model loading time
|
||||
struct timeval tv_start, tv_end;
|
||||
gettimeofday(&tv_start, NULL);
|
||||
esp_tts_voice_t *voice=esp_tts_voice_set_init(&esp_tts_voice_template, (int16_t*)voicedata);
|
||||
esp_tts_handle_t *tts_handle=esp_tts_create(voice);
|
||||
gettimeofday(&tv_end, NULL);
|
||||
int tv_ms = (tv_end.tv_sec - tv_start.tv_sec) * 1000 + (tv_end.tv_usec - tv_start.tv_usec) / 1000;
|
||||
printf("create latency:%d ms\n", tv_ms);
|
||||
|
||||
// test model memory concumption
|
||||
int create_size = start_size - heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int create_internal_size = start_internal_size - heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
printf("Internal RAM: %d, PSRAM:%d\n", create_internal_size, create_size - create_internal_size);
|
||||
|
||||
// test memory leak
|
||||
esp_tts_voice_set_free(voice);
|
||||
esp_tts_destroy(tts_handle);
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
esp_partition_munmap(mmap_handle); // support esp-idf v5
|
||||
#else
|
||||
spi_flash_munmap(mmap_handle); // support esp-idf v4
|
||||
#endif
|
||||
int first_end_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int last_end_size = first_end_size;
|
||||
int mem_leak = start_size - last_end_size;
|
||||
printf("create&destroy times:%d, memory leak:%d\n", 1, mem_leak);
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
printf("init partition ...\n");
|
||||
partition=esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "voice_data");
|
||||
assert(partition != NULL);
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
ESP_ERROR_CHECK(esp_partition_mmap(partition, 0, partition->size, ESP_PARTITION_MMAP_DATA, &voicedata, &mmap_handle));
|
||||
#else
|
||||
ESP_ERROR_CHECK(esp_partition_mmap(partition, 0, partition->size, SPI_FLASH_MMAP_DATA, &voicedata, &mmap_handle));
|
||||
#endif
|
||||
|
||||
printf("create ...\n");
|
||||
voice=esp_tts_voice_set_init(&esp_tts_voice_template, (int16_t*)voicedata);
|
||||
tts_handle=esp_tts_create(voice);
|
||||
|
||||
printf("destroy ...\n");
|
||||
esp_tts_voice_set_free(voice);
|
||||
esp_tts_destroy(tts_handle);
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
esp_partition_munmap(mmap_handle); // support esp-idf v5
|
||||
#else
|
||||
spi_flash_munmap(mmap_handle); // support esp-idf v4
|
||||
#endif
|
||||
last_end_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
mem_leak = start_size - last_end_size;
|
||||
printf("create&destroy times:%d, memory leak:%d\n", i + 2, mem_leak);
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(true, (mem_leak) < 1000 && last_end_size == first_end_size);
|
||||
}
|
||||
@ -1,186 +0,0 @@
|
||||
/* test_mean.c: Implementation of a testable component.
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include "string.h"
|
||||
#include <limits.h>
|
||||
#include "unity.h"
|
||||
|
||||
#include "model_path.h"
|
||||
#include "esp_mn_iface.h"
|
||||
#include "esp_mn_models.h"
|
||||
#include "dakaidiandeng.h"
|
||||
#include "alexa.h"
|
||||
#include "dl_lib_convq_queue.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
TEST_CASE("multinet create/destroy API & memory leak", "[mn]")
|
||||
{
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
int start_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int start_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
// test model loading time
|
||||
struct timeval tv_start, tv_end;
|
||||
gettimeofday(&tv_start, NULL);
|
||||
printf("load multinet!\n");
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
gettimeofday(&tv_end, NULL);
|
||||
int tv_ms = (tv_end.tv_sec - tv_start.tv_sec) * 1000 + (tv_end.tv_usec - tv_start.tv_usec) / 1000;
|
||||
printf("create latency:%d ms\n", tv_ms);
|
||||
|
||||
// test model memory concumption
|
||||
int create_size = start_size - heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int create_internal_size = start_internal_size - heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
printf("Internal RAM: %d, PSRAM:%d\n", create_internal_size, create_size - create_internal_size);
|
||||
multinet->destroy(model_data);
|
||||
esp_srmodel_deinit(models);
|
||||
|
||||
// test memory leak
|
||||
int first_end_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int last_end_size = first_end_size;
|
||||
int mem_leak = start_size - last_end_size;
|
||||
printf("create&destroy times:%d, memory leak:%d\n", 1, mem_leak);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
printf("init partition ...\n");
|
||||
models = esp_srmodel_init("model");
|
||||
model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
int time_out = 3000 + i * 2000;
|
||||
printf("create ..., time out = %d\n", time_out);
|
||||
model_data = multinet->create(model_name, time_out);
|
||||
|
||||
printf("destroy ...\n");
|
||||
multinet->destroy(model_data);
|
||||
esp_srmodel_deinit(models);
|
||||
|
||||
last_end_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
mem_leak = start_size - last_end_size;
|
||||
printf("create&destroy times:%d, memory leak:%d\n", i + 2, mem_leak);
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(true, (mem_leak) < 1000 && last_end_size == first_end_size);
|
||||
}
|
||||
|
||||
TEST_CASE("multinet detect/get_results API & cpu loading", "[mn]")
|
||||
{
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
int frequency = multinet->get_samp_rate(model_data);
|
||||
int audio_chunksize = multinet->get_samp_chunksize(model_data) * sizeof(int16_t);
|
||||
int16_t *buffer = malloc(audio_chunksize);
|
||||
int chunks = 0;
|
||||
struct timeval tv_start, tv_end;
|
||||
gettimeofday(&tv_start, NULL);
|
||||
|
||||
while (1) {
|
||||
if ((chunks + 1)*audio_chunksize <= sizeof(alexa)) {
|
||||
memcpy(buffer, alexa + chunks * audio_chunksize, audio_chunksize);
|
||||
} else {
|
||||
memset(buffer, 0, audio_chunksize);
|
||||
}
|
||||
esp_mn_state_t mn_state = multinet->detect(model_data, buffer);
|
||||
if (mn_state == ESP_MN_STATE_DETECTED) {
|
||||
esp_mn_results_t *mn_result = multinet->get_results(model_data);
|
||||
printf("Command id:%d\n", mn_result->command_id[0]);
|
||||
}
|
||||
|
||||
chunks++;
|
||||
if (chunks == 64) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
gettimeofday(&tv_end, NULL);
|
||||
int tv_ms = (tv_end.tv_sec - tv_start.tv_sec) * 1000 + (tv_end.tv_usec - tv_start.tv_usec) / 1000;
|
||||
chunks -= 7;
|
||||
int run_ms = (chunks) * audio_chunksize / sizeof(int16_t) * 1000 / frequency;
|
||||
float cpu_loading = tv_ms * 100.0 / run_ms;
|
||||
printf("Done! Took %d ms to parse %d ms worth of samples in %d iterations. CPU loading(single core):%.1f%%\n",
|
||||
tv_ms, run_ms, chunks, cpu_loading);
|
||||
|
||||
multinet->destroy(model_data);
|
||||
esp_srmodel_deinit(models);
|
||||
TEST_ASSERT_EQUAL(true, (cpu_loading < 75 && tv_ms > 0));
|
||||
}
|
||||
|
||||
TEST_CASE("multinet switch loader mode", "[mn]")
|
||||
{
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
char *model_name = esp_srmodel_filter(models, "mn6", NULL);
|
||||
if (model_name != NULL) {
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
int start_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int start_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
struct timeval tv_start, tv_end;
|
||||
gettimeofday(&tv_start, NULL);
|
||||
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
int create_size = start_size - heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int create_internal_size = start_internal_size - heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
int first_create_size = create_size;
|
||||
printf("Internal RAM: %d, PSRAM:%d\n\n", create_internal_size, create_size-create_internal_size);
|
||||
|
||||
model_data = multinet->switch_loader_mode(model_data, ESP_MN_LOAD_FROM_PSRAM_FLASH);
|
||||
create_size = start_size - heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
create_internal_size = start_internal_size - heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
printf("Internal RAM: %d, PSRAM:%d\n\n", create_internal_size, create_size-create_internal_size);
|
||||
|
||||
model_data = multinet->switch_loader_mode(model_data, ESP_MN_LOAD_FROM_PSRAM);
|
||||
create_size = start_size - heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
create_internal_size = start_internal_size - heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
printf("Internal RAM: %d, PSRAM:%d\n\n", create_internal_size, create_size-create_internal_size);
|
||||
|
||||
model_data = multinet->switch_loader_mode(model_data, ESP_MN_LOAD_FROM_PSRAM);
|
||||
model_data = multinet->switch_loader_mode(model_data, ESP_MN_LOAD_FROM_PSRAM_FLASH);
|
||||
create_size = start_size - heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
create_internal_size = start_internal_size - heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
printf("Internal RAM: %d, PSRAM:%d\n\n", create_internal_size, create_size-create_internal_size);
|
||||
|
||||
model_data = multinet->switch_loader_mode(model_data, ESP_MN_LOAD_FROM_FLASH);
|
||||
create_size = start_size - heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
create_internal_size = start_internal_size - heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
printf("Internal RAM: %d, PSRAM:%d\n\n", create_internal_size, create_size-create_internal_size);
|
||||
|
||||
model_data = multinet->switch_loader_mode(model_data, ESP_MN_LOAD_FROM_FLASH);
|
||||
model_data = multinet->switch_loader_mode(model_data, ESP_MN_LOAD_FROM_PSRAM);
|
||||
model_data = multinet->switch_loader_mode(model_data, ESP_MN_LOAD_FROM_FLASH);
|
||||
model_data = multinet->switch_loader_mode(model_data, ESP_MN_LOAD_FROM_PSRAM_FLASH);
|
||||
create_size = start_size - heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
create_internal_size = start_internal_size - heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
printf("Internal RAM: %d, PSRAM:%d\n\n", create_internal_size, create_size-create_internal_size);
|
||||
|
||||
|
||||
gettimeofday(&tv_end, NULL);
|
||||
int tv_ms=(tv_end.tv_sec-tv_start.tv_sec)*1000+(tv_end.tv_usec-tv_start.tv_usec)/1000;
|
||||
printf("create latency:%d ms\n", tv_ms);
|
||||
multinet->destroy(model_data);
|
||||
|
||||
int first_end_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int first_end_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
int last_end_size = first_end_size;
|
||||
int last_end_internal_size = first_end_internal_size;
|
||||
int mem_leak = start_size - last_end_size;
|
||||
printf("create&destroy times:%d, memory leak:%d\n", 1, mem_leak);
|
||||
esp_srmodel_deinit(models);
|
||||
TEST_ASSERT_EQUAL(true, (mem_leak) < 1000 && first_create_size == create_size);
|
||||
} else {
|
||||
printf("Just support multinet6 and the later versions\n");
|
||||
TEST_ASSERT_EQUAL(true, 1);
|
||||
}
|
||||
|
||||
}
|
||||
4
test_apps/.build-rules.yml
Normal file
4
test_apps/.build-rules.yml
Normal file
@ -0,0 +1,4 @@
|
||||
test_apps:
|
||||
enable:
|
||||
- if: IDF_TARGET in ["esp32s3"]
|
||||
temporary: false
|
||||
11
test_apps/README.md
Normal file
11
test_apps/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
Steps to run these cases:
|
||||
|
||||
- Build
|
||||
- . ${IDF_PATH}/export.sh
|
||||
- pip install idf_build_apps
|
||||
- python test_apps/build_apps.py test_apps -t esp32s3
|
||||
|
||||
- Test
|
||||
- pip install -r test_apps/requirement.txt
|
||||
- pytest test_apps --target esp32s3
|
||||
151
test_apps/build_apps.py
Normal file
151
test_apps/build_apps.py
Normal file
@ -0,0 +1,151 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
"""
|
||||
This file is used in CI generate binary files for different kinds of apps
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
from idf_build_apps import LOGGER, App, build_apps, find_apps, setup_logging
|
||||
|
||||
PROJECT_ROOT = Path(__file__).parent.parent.absolute()
|
||||
print(PROJECT_ROOT)
|
||||
APPS_BUILD_PER_JOB = 30
|
||||
IGNORE_WARNINGS = [
|
||||
r'1/2 app partitions are too small',
|
||||
r'This clock source will be affected by the DFS of the power management',
|
||||
r'The current IDF version does not support using the gptimer API',
|
||||
]
|
||||
|
||||
def _get_idf_version():
|
||||
if os.environ.get('IDF_VERSION'):
|
||||
return os.environ.get('IDF_VERSION')
|
||||
version_path = os.path.join(os.environ['IDF_PATH'], 'tools/cmake/version.cmake')
|
||||
regex = re.compile(r'^\s*set\s*\(\s*IDF_VERSION_([A-Z]{5})\s+(\d+)')
|
||||
ver = {}
|
||||
with open(version_path) as f:
|
||||
for line in f:
|
||||
m = regex.match(line)
|
||||
if m:
|
||||
ver[m.group(1)] = m.group(2)
|
||||
return '{}.{}'.format(int(ver['MAJOR']), int(ver['MINOR']))
|
||||
|
||||
def get_cmake_apps(
|
||||
paths,
|
||||
target,
|
||||
config_rules_str,
|
||||
default_build_targets,
|
||||
): # type: (List[str], str, List[str]) -> List[App]
|
||||
idf_ver = _get_idf_version()
|
||||
apps = find_apps(
|
||||
paths,
|
||||
recursive=True,
|
||||
target=target,
|
||||
build_dir=f'{idf_ver}/build_@t_@w',
|
||||
config_rules_str=config_rules_str,
|
||||
build_log_path='build_log.txt',
|
||||
size_json_path='size.json',
|
||||
check_warnings=True,
|
||||
preserve=True,
|
||||
default_build_targets=default_build_targets,
|
||||
manifest_files=[
|
||||
# str(Path(PROJECT_ROOT) /'examples'/'.build-rules.yml'),
|
||||
str(Path(PROJECT_ROOT) /'test_apps'/'.build-rules.yml'),
|
||||
],
|
||||
)
|
||||
return apps
|
||||
|
||||
|
||||
def main(args): # type: (argparse.Namespace) -> None
|
||||
default_build_targets = args.default_build_targets.split(',') if args.default_build_targets else None
|
||||
apps = get_cmake_apps(args.paths, args.target, args.config, default_build_targets)
|
||||
print(apps)
|
||||
if args.exclude_apps:
|
||||
apps_to_build = [app for app in apps if app.name not in args.exclude_apps]
|
||||
else:
|
||||
apps_to_build = apps[:]
|
||||
|
||||
LOGGER.info('Found %d apps after filtering', len(apps_to_build))
|
||||
LOGGER.info(
|
||||
'Suggest setting the parallel count to %d for this build job',
|
||||
len(apps_to_build) // APPS_BUILD_PER_JOB + 1,
|
||||
)
|
||||
|
||||
ret_code = build_apps(
|
||||
apps_to_build,
|
||||
parallel_count=args.parallel_count,
|
||||
parallel_index=args.parallel_index,
|
||||
dry_run=False,
|
||||
collect_size_info=args.collect_size_info,
|
||||
keep_going=True,
|
||||
ignore_warning_strs=IGNORE_WARNINGS,
|
||||
copy_sdkconfig=True,
|
||||
)
|
||||
|
||||
sys.exit(ret_code)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Build all the apps for different test types. Will auto remove those non-test apps binaries',
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
)
|
||||
parser.add_argument('paths', nargs='*', help='Paths to the apps to build.')
|
||||
parser.add_argument(
|
||||
'-t', '--target',
|
||||
default='all',
|
||||
help='Build apps for given target. could pass "all" to get apps for all targets',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--config',
|
||||
default=['sdkconfig.ci=default', 'sdkconfig.ci.*=', '=default'],
|
||||
action='append',
|
||||
help='Adds configurations (sdkconfig file names) to build. This can either be '
|
||||
'FILENAME[=NAME] or FILEPATTERN. FILENAME is the name of the sdkconfig file, '
|
||||
'relative to the project directory, to be used. Optional NAME can be specified, '
|
||||
'which can be used as a name of this configuration. FILEPATTERN is the name of '
|
||||
'the sdkconfig file, relative to the project directory, with at most one wildcard. '
|
||||
'The part captured by the wildcard is used as the name of the configuration.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--parallel-count', default=1, type=int, help='Number of parallel build jobs.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--parallel-index',
|
||||
default=1,
|
||||
type=int,
|
||||
help='Index (1-based) of the job, out of the number specified by --parallel-count.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--collect-size-info',
|
||||
type=argparse.FileType('w'),
|
||||
help='If specified, the test case name and size info json will be written to this file',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--exclude-apps',
|
||||
nargs='*',
|
||||
help='Exclude build apps',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--default-build-targets',
|
||||
default=None,
|
||||
help='default build targets used in manifest files',
|
||||
)
|
||||
parser.add_argument(
|
||||
'-v', '--verbose',
|
||||
action='count', default=0,
|
||||
help='Show verbose log message',
|
||||
)
|
||||
|
||||
arguments = parser.parse_args()
|
||||
if not arguments.paths:
|
||||
arguments.paths = [PROJECT_ROOT]
|
||||
setup_logging(verbose=arguments.verbose) # Info
|
||||
main(arguments)
|
||||
10
test_apps/esp-sr/CMakeLists.txt
Normal file
10
test_apps/esp-sr/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# This is the project CMakeLists.txt file for the test subproject
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
# Include the components directory of the main application:
|
||||
#
|
||||
set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/unit-test-app/components"
|
||||
"../../../esp-sr")
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(esp_sr_test)
|
||||
15
test_apps/esp-sr/dependencies.lock
Normal file
15
test_apps/esp-sr/dependencies.lock
Normal file
@ -0,0 +1,15 @@
|
||||
dependencies:
|
||||
espressif/esp-dsp:
|
||||
component_hash: 59a67ce3be799201752ebde99890b0ab947054eff6463d83e944f2d4165d6905
|
||||
source:
|
||||
service_url: https://api.components.espressif.com/
|
||||
type: service
|
||||
version: 1.4.4
|
||||
idf:
|
||||
component_hash: null
|
||||
source:
|
||||
type: idf
|
||||
version: 5.0.2
|
||||
manifest_hash: 1c2a956562f88dbb4682372296ee9497ceb4a13d8ecd1e49e6be10eca321dd51
|
||||
target: esp32s3
|
||||
version: 1.0.0
|
||||
16
test_apps/esp-sr/main/CMakeLists.txt
Normal file
16
test_apps/esp-sr/main/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
||||
if(IDF_TARGET STREQUAL "esp32s3")
|
||||
|
||||
set(srcs
|
||||
"test_app_main.c"
|
||||
"test_wakenet.c"
|
||||
"test_multinet.c"
|
||||
"test_afe.c"
|
||||
)
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
INCLUDE_DIRS "." "samples"
|
||||
REQUIRES unity esp-sr
|
||||
WHOLE_ARCHIVE)
|
||||
|
||||
|
||||
endif()
|
||||
6230
test_apps/esp-sr/main/samples/da_kai_kong_tiao.h
Normal file
6230
test_apps/esp-sr/main/samples/da_kai_kong_tiao.h
Normal file
File diff suppressed because it is too large
Load Diff
5608
test_apps/esp-sr/main/samples/tell_me_a_joke.h
Normal file
5608
test_apps/esp-sr/main/samples/tell_me_a_joke.h
Normal file
File diff suppressed because it is too large
Load Diff
48
test_apps/esp-sr/main/test_app_main.c
Normal file
48
test_apps/esp-sr/main/test_app_main.c
Normal file
@ -0,0 +1,48 @@
|
||||
/* Example test application for testable component.
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "unity.h"
|
||||
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
/* These are the different ways of running registered tests.
|
||||
* In practice, only one of them is usually needed.
|
||||
*
|
||||
* UNITY_BEGIN() and UNITY_END() calls tell Unity to print a summary
|
||||
* (number of tests executed/failed/ignored) of tests executed between these calls.
|
||||
*/
|
||||
// print_banner("Executing one test by its name");
|
||||
// UNITY_BEGIN();
|
||||
// unity_run_test_by_name("Mean of an empty array is zero");
|
||||
// UNITY_END();
|
||||
|
||||
// print_banner("Running tests with [mean] tag");
|
||||
// UNITY_BEGIN();
|
||||
// unity_run_tests_by_tag("[mean]", false);
|
||||
// UNITY_END();
|
||||
|
||||
// print_banner("Running tests without [fails] tag");
|
||||
// UNITY_BEGIN();
|
||||
// unity_run_tests_by_tag("[fails]", true);
|
||||
// UNITY_END();
|
||||
|
||||
// print_banner("Running all the registered tests");
|
||||
// UNITY_BEGIN();
|
||||
// unity_run_all_tests();
|
||||
// UNITY_END();
|
||||
|
||||
// print_banner("Starting interactive test menu");
|
||||
/* This function will not return, and will be busy waiting for UART input.
|
||||
* Make sure that task watchdog is disabled if you use this function.
|
||||
*/
|
||||
unity_run_menu();
|
||||
}
|
||||
395
test_apps/esp-sr/main/test_multinet.c
Normal file
395
test_apps/esp-sr/main/test_multinet.c
Normal file
@ -0,0 +1,395 @@
|
||||
/* test_mean.c: Implementation of a testable component.
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRAMTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include "string.h"
|
||||
#include <limits.h>
|
||||
#include "unity.h"
|
||||
|
||||
#include "model_path.h"
|
||||
#include "esp_mn_iface.h"
|
||||
#include "esp_mn_models.h"
|
||||
#include "da_kai_kong_tiao.h"
|
||||
#include "tell_me_a_joke.h"
|
||||
#include "alexa.h"
|
||||
#include "dl_lib_convq_queue.h"
|
||||
#include <sys/time.h>
|
||||
#include "esp_mn_speech_commands.h"
|
||||
#include "esp_process_sdkconfig.h"
|
||||
|
||||
TEST_CASE("multinet create/destroy API & memory leak", "[mn]")
|
||||
{
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
int start_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int start_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
struct timeval tv_start, tv_end;
|
||||
gettimeofday(&tv_start, NULL);
|
||||
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
int create_size = start_size - heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int create_internal_size = start_internal_size - heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
printf("Internal RAM: %d, PSRAM:%d\n", create_internal_size, create_size-create_internal_size);
|
||||
|
||||
gettimeofday(&tv_end, NULL);
|
||||
int tv_ms=(tv_end.tv_sec-tv_start.tv_sec)*1000+(tv_end.tv_usec-tv_start.tv_usec)/1000;
|
||||
printf("create latency:%d ms\n", tv_ms);
|
||||
multinet->destroy(model_data);
|
||||
|
||||
int first_end_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int last_end_size = first_end_size;
|
||||
int mem_leak = start_size - last_end_size;
|
||||
printf("create&destroy times:%d, memory leak:%d\n", 1, mem_leak);
|
||||
|
||||
|
||||
for (int i=0; i<3; i++) {
|
||||
printf("create ...\n");
|
||||
model_data = multinet->create(model_name, 6000);
|
||||
printf("destroy ...\n");
|
||||
multinet->destroy(model_data);
|
||||
last_end_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
mem_leak = start_size - last_end_size;
|
||||
printf("create&destroy times:%d, memory leak:%d\n", i+2, mem_leak);
|
||||
}
|
||||
|
||||
esp_srmodel_deinit(models);
|
||||
TEST_ASSERT_EQUAL(true, (mem_leak) < 1000 && last_end_size == first_end_size);
|
||||
}
|
||||
|
||||
TEST_CASE("multinet cpu loading", "[mn]")
|
||||
{
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
int frequency = multinet->get_samp_rate(model_data);
|
||||
int audio_chunksize = multinet->get_samp_chunksize(model_data) * sizeof(int16_t);
|
||||
char *lang = multinet->get_language(model_data);
|
||||
esp_mn_commands_update_from_sdkconfig(multinet, model_data);
|
||||
unsigned char* data = NULL;
|
||||
size_t data_size = 0;
|
||||
if (strcmp(lang, ESP_MN_ENGLISH) == 0) {
|
||||
data = (unsigned char*)tell_me_a_joke;
|
||||
data_size = sizeof(tell_me_a_joke);
|
||||
printf("commands: tell me a joke, size:%d\n", data_size);
|
||||
} else if(strcmp(lang, ESP_MN_CHINESE) == 0) {
|
||||
data = (unsigned char*)da_kai_kong_tiao;
|
||||
data_size = sizeof(da_kai_kong_tiao);
|
||||
printf("commands: da kai kong tiao, size:%d\n", data_size);
|
||||
}
|
||||
|
||||
int16_t *buffer = malloc(audio_chunksize);
|
||||
int chunks = 0;
|
||||
struct timeval tv_start, tv_end;
|
||||
gettimeofday(&tv_start, NULL);
|
||||
esp_mn_state_t mn_state;
|
||||
|
||||
while (1) {
|
||||
if ((chunks + 1)*audio_chunksize <= data_size) {
|
||||
memcpy(buffer, data + chunks * audio_chunksize, audio_chunksize);
|
||||
} else {
|
||||
memset(buffer, 0, audio_chunksize);
|
||||
}
|
||||
mn_state = multinet->detect(model_data, buffer);
|
||||
if (mn_state == ESP_MN_STATE_DETECTED) {
|
||||
esp_mn_results_t *mn_result = multinet->get_results(model_data);
|
||||
if (mn_result->num > 0)
|
||||
printf("detected: command id:%d, string:%s\n",mn_result->command_id[0], mn_result->string);
|
||||
else
|
||||
printf("timeout\n");
|
||||
break;
|
||||
}
|
||||
chunks++;
|
||||
if (chunks > 600)
|
||||
break;
|
||||
}
|
||||
gettimeofday(&tv_end, NULL);
|
||||
int tv_ms=(tv_end.tv_sec-tv_start.tv_sec)*1000+(tv_end.tv_usec-tv_start.tv_usec)/1000;
|
||||
chunks -= 7;
|
||||
int run_ms = (chunks)*audio_chunksize/sizeof(int16_t)*1000/frequency;
|
||||
printf("Done! Took %d ms to parse %d ms worth of samples in %d iterations. CPU loading(single core):%.1f%%\n",
|
||||
tv_ms, run_ms, chunks, tv_ms*100.0/run_ms);
|
||||
|
||||
multinet->destroy(model_data);
|
||||
esp_srmodel_deinit(models);
|
||||
TEST_ASSERT_EQUAL(true, mn_state == ESP_MN_STATE_DETECTED);
|
||||
}
|
||||
|
||||
TEST_CASE("multinet set commands", "[mn]")
|
||||
{
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
char *lang = multinet->get_language(model_data);
|
||||
esp_mn_error_t *error_phrases = NULL;
|
||||
printf("MODEL NAME %s\n", model_name);
|
||||
|
||||
// first
|
||||
if (strcmp(lang, ESP_MN_ENGLISH) == 0) {
|
||||
if (strcmp(model_name, "mn5q8_en") == 0) {
|
||||
TEST_ESP_OK(esp_mn_commands_add(1, "TfL Mm c qbK"));
|
||||
TEST_ESP_OK(esp_mn_commands_add(2, "hicST qbK"));
|
||||
} else {
|
||||
TEST_ESP_OK(esp_mn_commands_add(1, "TURN ON THE LIGHT"));
|
||||
TEST_ESP_OK(esp_mn_commands_add(2, "TURN OFF THE KITCHEN LIGHT"));
|
||||
}
|
||||
error_phrases = esp_mn_commands_update();
|
||||
} else if(strcmp(lang, ESP_MN_CHINESE) == 0) {
|
||||
TEST_ESP_OK(esp_mn_commands_add(1, "da kai dian deng"));
|
||||
TEST_ESP_OK(esp_mn_commands_add(2, "guan bi chu fang dian deng"));
|
||||
error_phrases = esp_mn_commands_update();
|
||||
} else {
|
||||
printf("Invalid language\n");
|
||||
}
|
||||
TEST_ASSERT_EQUAL(true, error_phrases == NULL);
|
||||
|
||||
// second
|
||||
if (strcmp(lang, ESP_MN_ENGLISH) == 0) {
|
||||
if (strcmp(model_name, "mn5q8_en") == 0) {
|
||||
TEST_ESP_OK(esp_mn_commands_add(3, "TkN nN eL jc LiTS"));
|
||||
TEST_ESP_OK(esp_mn_commands_add(4, "TkN eF eL jc LiTS"));
|
||||
} else {
|
||||
TEST_ESP_OK(esp_mn_commands_add(3, "TURN OFF THE LIGHT"));
|
||||
TEST_ESP_OK(esp_mn_commands_add(4, "TURN OM THE KITCHEN LIGHT"));
|
||||
}
|
||||
error_phrases = esp_mn_commands_update();
|
||||
} else if(strcmp(lang, ESP_MN_CHINESE) == 0) {
|
||||
esp_mn_commands_add(3, "guan bi dian deng");
|
||||
esp_mn_commands_add(4, "da kai chu fang dian deng");
|
||||
error_phrases = esp_mn_commands_update();
|
||||
} else {
|
||||
printf("Invalid language\n");
|
||||
}
|
||||
|
||||
multinet->destroy(model_data);
|
||||
esp_srmodel_deinit(models);
|
||||
TEST_ASSERT_EQUAL(true, error_phrases == NULL);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("multinet add incorrect commands", "[mn]")
|
||||
{
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
char *lang = multinet->get_language(model_data);
|
||||
esp_mn_error_t *error_phrases = NULL;
|
||||
esp_err_t state = ESP_OK;
|
||||
|
||||
if (strcmp(lang, ESP_MN_ENGLISH) == 0) {
|
||||
state = esp_mn_commands_add(1, "TURN ON THE LIGHT 123");
|
||||
assert(state == ESP_ERR_INVALID_STATE);
|
||||
state = esp_mn_commands_add(2, "TURN. OFF THE LIGHT?");
|
||||
assert(state == ESP_ERR_INVALID_STATE);
|
||||
} else if(strcmp(lang, ESP_MN_CHINESE) == 0) {
|
||||
if (strcmp(model_name, "mn6_cn_ac") == 0 || strcmp(model_name, "mn6_cn") == 0) {
|
||||
state = esp_mn_commands_add(1, "dakai dian deng");
|
||||
assert(state == ESP_ERR_INVALID_STATE);
|
||||
state = esp_mn_commands_add(2, "关闭电灯");
|
||||
assert(state == ESP_ERR_INVALID_STATE);
|
||||
} else {
|
||||
state = esp_mn_commands_add(1, "k");
|
||||
assert(state == ESP_ERR_INVALID_STATE);
|
||||
}
|
||||
} else {
|
||||
printf("Invalid language\n");
|
||||
}
|
||||
|
||||
multinet->destroy(model_data);
|
||||
esp_srmodel_deinit(models);
|
||||
TEST_ASSERT_EQUAL(true, error_phrases == NULL);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("multinet add duplicated commands", "[mn]")
|
||||
{
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
char *lang = multinet->get_language(model_data);
|
||||
esp_mn_error_t *error_phrases = NULL;
|
||||
|
||||
if (strcmp(lang, ESP_MN_ENGLISH) == 0) {
|
||||
if (strcmp(model_name, "mn5q8_en") == 0) {
|
||||
esp_mn_commands_add(1, "TfL Mm c qbK");
|
||||
esp_mn_commands_add(1, "TfL Mm c qbK");
|
||||
} else {
|
||||
esp_mn_commands_add(1, "TURN ON THE LIGHT");
|
||||
esp_mn_commands_add(1, "TURN ON THE LIGHT");
|
||||
}
|
||||
} else if(strcmp(lang, ESP_MN_CHINESE) == 0) {
|
||||
esp_mn_commands_add(1, "da kai dian deng");
|
||||
esp_mn_commands_add(1, "da kai dian deng");
|
||||
} else {
|
||||
printf("Invalid language\n");
|
||||
}
|
||||
|
||||
multinet->destroy(model_data);
|
||||
esp_srmodel_deinit(models);
|
||||
TEST_ASSERT_EQUAL(true, error_phrases == NULL);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("multinet print active commands", "[mn]")
|
||||
{
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
char *lang = multinet->get_language(model_data);
|
||||
esp_mn_commands_update_from_sdkconfig(multinet, model_data);
|
||||
|
||||
if (strcmp(lang, ESP_MN_ENGLISH) == 0) {
|
||||
if (strcmp(model_name, "mn5q8_en") == 0) {
|
||||
esp_mn_commands_add(1, "TfL Mm qbK");
|
||||
} else {
|
||||
esp_mn_commands_add(1, "THIS SHOULD NOT APPEAR IN ACTIVE COMMANDS");
|
||||
}
|
||||
} else if(strcmp(lang, ESP_MN_CHINESE) == 0) {
|
||||
esp_mn_commands_add(1, "bu ying gai chu xian zai biao zhong");
|
||||
} else {
|
||||
printf("Invalid language\n");
|
||||
}
|
||||
|
||||
multinet->print_active_speech_commands(model_data);
|
||||
|
||||
multinet->destroy(model_data);
|
||||
esp_srmodel_deinit(models);
|
||||
TEST_ASSERT_EQUAL(true, 1);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("multinet remove commands", "[mn]")
|
||||
{
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
char *lang = multinet->get_language(model_data);
|
||||
esp_mn_commands_update_from_sdkconfig(multinet, model_data);
|
||||
|
||||
if (strcmp(lang, ESP_MN_ENGLISH) == 0) {
|
||||
if (strcmp(model_name, "mn5q8_en") == 0) {
|
||||
esp_mn_commands_remove("TfL Mm c qbK");
|
||||
} else {
|
||||
esp_mn_commands_remove("TURN ON THE LIGHT");;
|
||||
}
|
||||
} else if(strcmp(lang, ESP_MN_CHINESE) == 0) {
|
||||
esp_mn_commands_remove("da kai dian deng");
|
||||
} else {
|
||||
printf("Invalid language\n");
|
||||
}
|
||||
|
||||
esp_mn_commands_update();
|
||||
multinet->print_active_speech_commands(model_data);
|
||||
|
||||
multinet->destroy(model_data);
|
||||
esp_srmodel_deinit(models);
|
||||
TEST_ASSERT_EQUAL(true, 1);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("multinet clear and add commands", "[mn]")
|
||||
{
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
char *lang = multinet->get_language(model_data);
|
||||
esp_mn_commands_update_from_sdkconfig(multinet, model_data);
|
||||
|
||||
esp_mn_commands_clear();
|
||||
|
||||
if (strcmp(lang, ESP_MN_ENGLISH) == 0) {
|
||||
if (strcmp(model_name, "mn5q8_en") == 0) {
|
||||
esp_mn_commands_add(1, "TfL Mm c qbK");
|
||||
} else {
|
||||
esp_mn_commands_add(1, "TURN ON THE LIGHT");
|
||||
}
|
||||
} else if(strcmp(lang, ESP_MN_CHINESE) == 0) {
|
||||
esp_mn_commands_add(1, "da kai dian deng");
|
||||
} else {
|
||||
printf("Invalid language\n");
|
||||
}
|
||||
|
||||
esp_mn_commands_update();
|
||||
esp_mn_commands_print();
|
||||
multinet->print_active_speech_commands(model_data);
|
||||
|
||||
if (strcmp(lang, ESP_MN_ENGLISH) == 0) {
|
||||
if (strcmp(model_name, "mn5q8_en") == 0) {
|
||||
esp_mn_commands_add(2, "Sgl c Sel");
|
||||
} else {
|
||||
esp_mn_commands_add(2, "SING A SONG");
|
||||
}
|
||||
} else if(strcmp(lang, ESP_MN_CHINESE) == 0) {
|
||||
esp_mn_commands_add(1, "guan bi dian deng");
|
||||
} else {
|
||||
printf("Invalid language\n");
|
||||
}
|
||||
|
||||
esp_mn_commands_update();
|
||||
esp_mn_commands_print();
|
||||
multinet->print_active_speech_commands(model_data);
|
||||
|
||||
multinet->destroy(model_data);
|
||||
esp_srmodel_deinit(models);
|
||||
TEST_ASSERT_EQUAL(true, 1);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("multinet modify commands", "[mn]")
|
||||
{
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
char *lang = multinet->get_language(model_data);
|
||||
esp_mn_commands_update_from_sdkconfig(multinet, model_data);
|
||||
|
||||
if (strcmp(lang, ESP_MN_ENGLISH) == 0) {
|
||||
if (strcmp(model_name, "mn5q8_en") == 0) {
|
||||
esp_mn_commands_modify("TfL Mm c qbK", "TfL TfL Mm c qbK");
|
||||
} else {
|
||||
esp_mn_commands_modify("TURN ON THE LIGHT", "TURN ON THE KITCHEN LIGHT");
|
||||
}
|
||||
} else if(strcmp(lang, ESP_MN_CHINESE) == 0) {
|
||||
esp_mn_commands_modify("da kai dian deng", "da kai chu fang deng");
|
||||
} else {
|
||||
printf("Invalid language\n");
|
||||
}
|
||||
|
||||
esp_mn_commands_update();
|
||||
multinet->print_active_speech_commands(model_data);
|
||||
|
||||
multinet->destroy(model_data);
|
||||
esp_srmodel_deinit(models);
|
||||
TEST_ASSERT_EQUAL(true, 1);
|
||||
}
|
||||
@ -25,7 +25,7 @@ TEST_CASE("wakenet create/destroy API & memory leak", "[wn]")
|
||||
int start_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
char *model_name = esp_srmodel_filter(models, ESP_WN_PREFIX, NULL);
|
||||
esp_wn_iface_t *wakenet = esp_wn_handle_from_name(model_name);
|
||||
esp_wn_iface_t *wakenet = (esp_wn_iface_t*)esp_wn_handle_from_name(model_name);
|
||||
|
||||
// test model loading time
|
||||
struct timeval tv_start, tv_end;
|
||||
@ -52,7 +52,7 @@ TEST_CASE("wakenet create/destroy API & memory leak", "[wn]")
|
||||
printf("init partition ...\n");
|
||||
models = esp_srmodel_init("model");
|
||||
model_name = esp_srmodel_filter(models, ESP_WN_PREFIX, NULL);
|
||||
wakenet = esp_wn_handle_from_name(model_name);
|
||||
wakenet = (esp_wn_iface_t*)esp_wn_handle_from_name(model_name);
|
||||
|
||||
printf("create ...\n");
|
||||
// typedef enum {
|
||||
@ -82,7 +82,7 @@ TEST_CASE("wakenet detect API & cpu loading", "[wn]")
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
char *model_name = esp_srmodel_filter(models, ESP_WN_PREFIX, NULL);
|
||||
esp_wn_iface_t *wakenet = esp_wn_handle_from_name(model_name);
|
||||
esp_wn_iface_t *wakenet = (esp_wn_iface_t*)esp_wn_handle_from_name(model_name);
|
||||
model_iface_data_t *model_data = wakenet->create(model_name, DET_MODE_95);
|
||||
int frequency = wakenet->get_samp_rate(model_data);
|
||||
int audio_chunksize = wakenet->get_samp_chunksize(model_data) * sizeof(int16_t);
|
||||
4
test_apps/esp-sr/partitions.csv
Normal file
4
test_apps/esp-sr/partitions.csv
Normal file
@ -0,0 +1,4 @@
|
||||
# Espressif ESP32 Partition Table
|
||||
# Name, Type, SubType, Offset, Size
|
||||
factory, app, factory, 0x010000, 8000k
|
||||
model, data, , , 7000K,
|
||||
|
36
test_apps/esp-sr/pytest_esp_sr.py
Normal file
36
test_apps/esp-sr/pytest_esp_sr.py
Normal file
@ -0,0 +1,36 @@
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
# @pytest.mark.target('esp32s3')
|
||||
# @pytest.mark.parametrize(
|
||||
# 'config',
|
||||
# [
|
||||
# 'mn5q8_cn',
|
||||
# 'mn6_cn',
|
||||
# ],
|
||||
# )
|
||||
# def test_multinet(dut: Dut)-> None:
|
||||
# dut.run_all_single_board_cases(group="mn")
|
||||
|
||||
|
||||
@pytest.mark.target('esp32s3')
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'mn5q8_cn',
|
||||
'wn9_hilexin',
|
||||
],
|
||||
)
|
||||
def test_wakenet(dut: Dut)-> None:
|
||||
dut.run_all_single_board_cases(group="wn")
|
||||
|
||||
|
||||
@pytest.mark.target('esp32s3')
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'wn9_hilexin',
|
||||
],
|
||||
)
|
||||
def test_afe(dut: Dut)-> None:
|
||||
dut.run_all_single_board_cases(group="afe")
|
||||
5
test_apps/esp-sr/requirements.txt
Normal file
5
test_apps/esp-sr/requirements.txt
Normal file
@ -0,0 +1,5 @@
|
||||
pytest
|
||||
pytest-embedded-idf
|
||||
pytest-embedded-serial-esp
|
||||
pytest-rerunfailures
|
||||
pytest-timeout
|
||||
2087
test_apps/esp-sr/sdkconfig.ci.mn5q8_cn
Normal file
2087
test_apps/esp-sr/sdkconfig.ci.mn5q8_cn
Normal file
File diff suppressed because it is too large
Load Diff
1882
test_apps/esp-sr/sdkconfig.ci.mn6_cn
Normal file
1882
test_apps/esp-sr/sdkconfig.ci.mn6_cn
Normal file
File diff suppressed because it is too large
Load Diff
1873
test_apps/esp-sr/sdkconfig.ci.wn9_hilexin
Normal file
1873
test_apps/esp-sr/sdkconfig.ci.wn9_hilexin
Normal file
File diff suppressed because it is too large
Load Diff
4985
test_apps/main/da_kai_dian_deng.h
Normal file
4985
test_apps/main/da_kai_dian_deng.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -11,7 +11,6 @@
|
||||
#include <string.h>
|
||||
#include "unity.h"
|
||||
|
||||
static void print_banner(const char* text);
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
@ -46,10 +45,4 @@ void app_main(void)
|
||||
* Make sure that task watchdog is disabled if you use this function.
|
||||
*/
|
||||
unity_run_menu();
|
||||
// unity_run_all_tests();
|
||||
}
|
||||
|
||||
static void print_banner(const char* text)
|
||||
{
|
||||
printf("\n#### %s #####\n\n", text);
|
||||
}
|
||||
}
|
||||
@ -27,7 +27,7 @@ TEST_CASE("chinese tts create/destroy API & memory leak", "[tts]")
|
||||
int start_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int start_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
/*** 1. create esp tts handle ***/
|
||||
void* voicedata;
|
||||
const void* voicedata;
|
||||
const esp_partition_t* partition=esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "voice_data");
|
||||
assert(partition != NULL);
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
|
||||
@ -45,7 +45,6 @@ TEST_CASE("multinet create/destroy API & memory leak", "[mn]")
|
||||
multinet->destroy(model_data);
|
||||
|
||||
int first_end_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int first_end_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
int last_end_size = first_end_size;
|
||||
int mem_leak = start_size - last_end_size;
|
||||
printf("create&destroy times:%d, memory leak:%d\n", 1, mem_leak);
|
||||
@ -72,21 +71,19 @@ TEST_CASE("multinet cpu loading", "[mn]")
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
int start_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int start_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
int frequency = multinet->get_samp_rate(model_data);
|
||||
int audio_chunksize = multinet->get_samp_chunksize(model_data) * sizeof(int16_t);
|
||||
char *lang = multinet->get_language(model_data);
|
||||
esp_mn_commands_update_from_sdkconfig(multinet, model_data);
|
||||
unsigned char* data = NULL;
|
||||
int data_size = 0;
|
||||
size_t data_size = 0;
|
||||
if (strcmp(lang, ESP_MN_ENGLISH) == 0) {
|
||||
data = tell_me_a_joke;
|
||||
data = (unsigned char*)tell_me_a_joke;
|
||||
data_size = sizeof(tell_me_a_joke);
|
||||
printf("commands: tell me a joke, size:%d\n", data_size);
|
||||
} else if(strcmp(lang, ESP_MN_CHINESE) == 0) {
|
||||
data = da_kai_kong_tiao;
|
||||
data = (unsigned char*)da_kai_kong_tiao;
|
||||
data_size = sizeof(da_kai_kong_tiao);
|
||||
printf("commands: da kai kong tiao, size:%d\n", data_size);
|
||||
}
|
||||
@ -106,7 +103,7 @@ TEST_CASE("multinet cpu loading", "[mn]")
|
||||
mn_state = multinet->detect(model_data, buffer);
|
||||
if (mn_state == ESP_MN_STATE_DETECTED) {
|
||||
esp_mn_results_t *mn_result = multinet->get_results(model_data);
|
||||
if (mn_result > 0)
|
||||
if (mn_result->num > 0)
|
||||
printf("detected: command id:%d, string:%s\n",mn_result->command_id[0], mn_result->string);
|
||||
else
|
||||
printf("timeout\n");
|
||||
@ -135,13 +132,10 @@ TEST_CASE("multinet set commands", "[mn]")
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
int start_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int start_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
char *lang = multinet->get_language(model_data);
|
||||
esp_mn_error_t *error_phrases = NULL;
|
||||
printf("MODEL NAME %s\n", model_name);
|
||||
esp_err_t state = ESP_OK;
|
||||
|
||||
// first
|
||||
if (strcmp(lang, ESP_MN_ENGLISH) == 0) {
|
||||
@ -193,8 +187,6 @@ TEST_CASE("multinet add incorrect commands", "[mn]")
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
int start_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int start_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
char *lang = multinet->get_language(model_data);
|
||||
esp_mn_error_t *error_phrases = NULL;
|
||||
@ -232,8 +224,6 @@ TEST_CASE("multinet add duplicated commands", "[mn]")
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
int start_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int start_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
char *lang = multinet->get_language(model_data);
|
||||
esp_mn_error_t *error_phrases = NULL;
|
||||
@ -266,8 +256,6 @@ TEST_CASE("multinet print active commands", "[mn]")
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
int start_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int start_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
char *lang = multinet->get_language(model_data);
|
||||
esp_mn_commands_update_from_sdkconfig(multinet, model_data);
|
||||
@ -299,11 +287,8 @@ TEST_CASE("multinet remove commands", "[mn]")
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
int start_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int start_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
char *lang = multinet->get_language(model_data);
|
||||
esp_mn_error_t *error_phrases = NULL;
|
||||
esp_mn_commands_update_from_sdkconfig(multinet, model_data);
|
||||
|
||||
if (strcmp(lang, ESP_MN_ENGLISH) == 0) {
|
||||
@ -334,11 +319,8 @@ TEST_CASE("multinet clear and add commands", "[mn]")
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
int start_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int start_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
char *lang = multinet->get_language(model_data);
|
||||
esp_mn_error_t *error_phrases = NULL;
|
||||
esp_mn_commands_update_from_sdkconfig(multinet, model_data);
|
||||
|
||||
esp_mn_commands_clear();
|
||||
@ -388,11 +370,8 @@ TEST_CASE("multinet modify commands", "[mn]")
|
||||
char *model_name = esp_srmodel_filter(models, ESP_MN_PREFIX, NULL);
|
||||
esp_mn_iface_t *multinet = esp_mn_handle_from_name(model_name);
|
||||
|
||||
int start_size = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
int start_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
model_iface_data_t *model_data = multinet->create(model_name, 6000);
|
||||
char *lang = multinet->get_language(model_data);
|
||||
esp_mn_error_t *error_phrases = NULL;
|
||||
esp_mn_commands_update_from_sdkconfig(multinet, model_data);
|
||||
|
||||
if (strcmp(lang, ESP_MN_ENGLISH) == 0) {
|
||||
|
||||
@ -25,7 +25,7 @@ TEST_CASE("wakenet create/destroy API & memory leak", "[wn]")
|
||||
int start_internal_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
char *model_name = esp_srmodel_filter(models, ESP_WN_PREFIX, NULL);
|
||||
esp_wn_iface_t *wakenet = esp_wn_handle_from_name(model_name);
|
||||
esp_wn_iface_t *wakenet = (esp_wn_iface_t*)esp_wn_handle_from_name(model_name);
|
||||
|
||||
// test model loading time
|
||||
struct timeval tv_start, tv_end;
|
||||
@ -52,7 +52,7 @@ TEST_CASE("wakenet create/destroy API & memory leak", "[wn]")
|
||||
printf("init partition ...\n");
|
||||
models = esp_srmodel_init("model");
|
||||
model_name = esp_srmodel_filter(models, ESP_WN_PREFIX, NULL);
|
||||
wakenet = esp_wn_handle_from_name(model_name);
|
||||
wakenet = (esp_wn_iface_t*)esp_wn_handle_from_name(model_name);
|
||||
|
||||
printf("create ...\n");
|
||||
// typedef enum {
|
||||
@ -82,7 +82,7 @@ TEST_CASE("wakenet detect API & cpu loading", "[wn]")
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
char *model_name = esp_srmodel_filter(models, ESP_WN_PREFIX, NULL);
|
||||
esp_wn_iface_t *wakenet = esp_wn_handle_from_name(model_name);
|
||||
esp_wn_iface_t *wakenet = (esp_wn_iface_t*)esp_wn_handle_from_name(model_name);
|
||||
model_iface_data_t *model_data = wakenet->create(model_name, DET_MODE_95);
|
||||
int frequency = wakenet->get_samp_rate(model_data);
|
||||
int audio_chunksize = wakenet->get_samp_chunksize(model_data) * sizeof(int16_t);
|
||||
|
||||
35
test_apps/pytest_esp_sr.py
Normal file
35
test_apps/pytest_esp_sr.py
Normal file
@ -0,0 +1,35 @@
|
||||
'''
|
||||
Steps to run these cases:
|
||||
- Build
|
||||
- . ${IDF_PATH}/export.sh
|
||||
- pip install idf_build_apps
|
||||
- python test_apps/build_apps.py test_apps -t esp32s3
|
||||
- Test
|
||||
- pip install -r tools/requirements/requirement.pytest.txt
|
||||
- pytest test_apps --target esp32s2
|
||||
'''
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
@pytest.mark.target('esp32s3')
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'mn5q8_cn',
|
||||
'mn6_cn',
|
||||
],
|
||||
)
|
||||
def test_multinet(dut: Dut)-> None:
|
||||
dut.run_all_single_board_cases(group="mn")
|
||||
|
||||
|
||||
@pytest.mark.target('esp32s3')
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'hilexin',
|
||||
'hiesp',
|
||||
],
|
||||
)
|
||||
def test_multinet(dut: Dut)-> None:
|
||||
dut.run_all_single_board_cases(group="mn")
|
||||
2087
test_apps/sdkconfig.ci.mn5q8_cn
Normal file
2087
test_apps/sdkconfig.ci.mn5q8_cn
Normal file
File diff suppressed because it is too large
Load Diff
1882
test_apps/sdkconfig.ci.mn6_cn
Normal file
1882
test_apps/sdkconfig.ci.mn6_cn
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,29 +0,0 @@
|
||||
CONFIG_IDF_TARGET="esp32s3"
|
||||
CONFIG_IDF_TARGET_ESP32S3=y
|
||||
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y
|
||||
CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB=y
|
||||
CONFIG_ESP32S3_DATA_CACHE_64KB=y
|
||||
CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y
|
||||
CONFIG_ESP32S3_SPIRAM_SUPPORT=y
|
||||
CONFIG_SPIRAM_MODE_OCT=y
|
||||
CONFIG_SPIRAM_SPEED_80M=y
|
||||
# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set
|
||||
CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y
|
||||
# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set
|
||||
# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set
|
||||
# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set
|
||||
CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y
|
||||
CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y
|
||||
|
||||
CONFIG_MODEL_IN_SPIFFS=y
|
||||
# CONFIG_MODEL_IN_SDCARD is not set
|
||||
CONFIG_USE_WAKENET=y
|
||||
CONFIG_SR_WN_MODEL_WN7_QUANT8=y
|
||||
CONFIG_SR_WN_WN7_HILEXIN=y
|
||||
# CONFIG_USE_MULTINET is not set
|
||||
Loading…
Reference in New Issue
Block a user