Merge branch 'feature/add_sleep_test_for_ot_ci' into 'master'

OpenThread CI: add a test case of sleepy device

See merge request espressif/esp-idf!24715
This commit is contained in:
Xu Si Yu 2023-08-01 20:38:29 +08:00
commit 36511a3005
9 changed files with 186 additions and 32 deletions

View File

@ -1077,6 +1077,15 @@ pytest_examples_openthread_br:
- esp32c6
- openthread_br
pytest_examples_openthread_sleep:
extends:
- .pytest_examples_dir_template
- .rules:test:example_test-esp32h2
needs:
- build_pytest_examples_esp32c6
- build_pytest_examples_esp32h2
tags: [ esp32c6, openthread_sleep ]
pytest_examples_zigbee:
extends:
- .pytest_examples_dir_template

View File

@ -164,6 +164,12 @@ menu "Hardware Settings"
only for code quality inspection. Enabling it will increase the time overhead of entering
and exiting sleep. It is not recommended to enable it in the release version.
config ESP_SLEEP_DEBUG
bool "esp sleep debug"
default n
help
Enable esp sleep debug.
endmenu
menu "ESP_SLEEP_WORKAROUND"

View File

@ -579,6 +579,14 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
bool deep_sleep = (mode == ESP_SLEEP_MODE_DEEP_SLEEP);
bool should_skip_sleep = false;
#if CONFIG_ESP_SLEEP_DEBUG
// The following three logs are used to confirm whether the digital domain and modem are powered off.
// Some CI tests depend on these three logs and it is best not to modify them.
ESP_EARLY_LOGD(TAG, "pd_lags %lu", pd_flags);
ESP_EARLY_LOGD(TAG, "PMU_SLEEP_PD_TOP: %s", (pd_flags & PMU_SLEEP_PD_TOP) ? "True":"False");
ESP_EARLY_LOGD(TAG, "PMU_SLEEP_PD_MODEM: %s", (pd_flags & PMU_SLEEP_PD_MODEM) ? "True":"False");
#endif
int64_t sleep_duration = (int64_t) s_config.sleep_duration - (int64_t) s_config.sleep_time_adjustment;
#if SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256

View File

@ -133,6 +133,7 @@ ENV_MARKERS = {
# multi-dut markers
'ieee802154': 'ieee802154 related tests should run on ieee802154 runners.',
'openthread_br': 'tests should be used for openthread border router.',
'openthread_sleep': 'tests should be used for openthread sleepy device.',
'zigbee_multi_dut': 'zigbee runner which have multiple duts.',
'wifi_two_dut': 'tests should be run on runners which has two wifi duts connected.',
'generic_multi_device': 'generic multiple devices whose corresponding gpio pins are connected to each other.',

View File

@ -3,24 +3,23 @@
# TODO: Modify the configuration after the files matching rules are changed
# Or delete TODO without modifying the configuration if it is sure that current rules are correct.
.openthread_dependencies: &openthread_dependencies
depends_components:
- esp_coex
- esp_netif
- esp_phy
- ieee802154
- lwip
- openthread
depends_filepatterns:
- components/esp_coex/*
- components/esp_coex/**/*
- components/esp_netif/*
- components/esp_netif/**/*
- components/esp_phy/*
- components/esp_phy/**/*
- components/ieee802154/*
- components/ieee802154/**/*
- components/lwip/*
- components/lwip/**/*
- components/openthread/*
- components/openthread/**/*
- examples/common_components/iperf/*
- examples/common_components/iperf/**/*
- examples/openthread/*
- examples/openthread/**/*
.openthread_sleep_dependencies: &openthread_sleep_dependencies
depends_components:
- esp_hw_support
examples/openthread/ot_br:
disable:
- if: IDF_TARGET in ["esp32h2"]
@ -35,10 +34,6 @@ examples/openthread/ot_br:
examples/openthread/ot_cli:
enable:
- if: IDF_TARGET in ["esp32h2", "esp32c6"]
disable_test:
- if: IDF_TARGET == "esp32c6"
temporary: true
reason: only test on esp32h2
<<: *openthread_dependencies
examples/openthread/ot_rcp:
@ -53,8 +48,4 @@ examples/openthread/ot_rcp:
examples/openthread/ot_sleepy_device:
enable:
- if: IDF_TARGET in ["esp32h2", "esp32c6"]
disable_test:
- if: IDF_TARGET in ["esp32h2", "esp32c6"]
temporary: true
reason: No support # TO-DO: TZ-134
<<: *openthread_dependencies
<<: [*openthread_dependencies, *openthread_sleep_dependencies]

View File

@ -23,6 +23,26 @@ class thread_parameter:
self.channel = channel
self.exaddr = exaddr
self.bbr = bbr
self.networkname = ''
self.panid = ''
self.extpanid = ''
self.networkkey = ''
self.pskc = ''
def setnetworkname(self, networkname:str) -> None:
self.networkname = networkname
def setpanid(self, panid:str) -> None:
self.panid = panid
def setextpanid(self, extpanid:str) -> None:
self.extpanid = extpanid
def setnetworkkey(self, networkkey:str) -> None:
self.networkkey = networkkey
def setpskc(self, pskc:str) -> None:
self.pskc = pskc
class wifi_parameter:
@ -34,23 +54,43 @@ class wifi_parameter:
def joinThreadNetwork(dut:IdfDut, thread:thread_parameter) -> None:
if thread.dataset != '':
if thread.dataset:
command = 'dataset set active ' + thread.dataset
execute_command(dut, command)
dut.expect('Done', timeout=5)
else:
execute_command(dut, 'dataset init new')
dut.expect('Done', timeout=5)
execute_command(dut, 'dataset commit active')
dut.expect('Done', timeout=5)
if thread.channel != '':
command = 'channel ' + thread.channel
if thread.channel:
command = 'dataset channel ' + thread.channel
execute_command(dut, command)
dut.expect('Done', timeout=5)
if thread.exaddr != '':
if thread.exaddr:
command = 'extaddr ' + thread.exaddr
execute_command(dut, command)
dut.expect('Done', timeout=5)
if thread.networkname:
command = 'dataset networkname ' + thread.networkname
execute_command(dut, command)
dut.expect('Done', timeout=5)
if thread.panid:
command = 'dataset panid ' + thread.panid
execute_command(dut, command)
dut.expect('Done', timeout=5)
if thread.extpanid:
command = 'dataset extpanid ' + thread.extpanid
execute_command(dut, command)
dut.expect('Done', timeout=5)
if thread.networkkey:
command = 'dataset networkkey ' + thread.networkkey
execute_command(dut, command)
dut.expect('Done', timeout=5)
if thread.pskc:
command = 'dataset pskc ' + thread.pskc
execute_command(dut, command)
dut.expect('Done', timeout=5)
execute_command(dut, 'dataset commit active')
dut.expect('Done', timeout=5)
if thread.bbr:
execute_command(dut, 'bbr enable')
dut.expect('Done', timeout=5)
@ -109,9 +149,13 @@ def getDataset(dut:IdfDut) -> str:
return str(dut_data)
def reset_thread(dut:IdfDut) -> None:
def init_thread(dut:IdfDut) -> None:
dut.expect('>', timeout=10)
wait(dut, 3)
reset_thread(dut)
def reset_thread(dut:IdfDut) -> None:
clean_buffer(dut)
execute_command(dut, 'factoryreset')
dut.expect('OpenThread attached to netif', timeout=20)

View File

@ -0,0 +1,6 @@
CONFIG_IDF_TARGET="esp32c6"
CONFIG_IDF_TARGET_ESP32C6=y
CONFIG_OPENTHREAD_NETWORK_CHANNEL=12
CONFIG_OPENTHREAD_NETWORK_MASTERKEY="aabbccddeeff00112233445566778899"
CONFIG_ESP_SLEEP_DEBUG=y
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y

View File

@ -0,0 +1,6 @@
CONFIG_IDF_TARGET="esp32h2"
CONFIG_IDF_TARGET_ESP32H2=y
CONFIG_OPENTHREAD_NETWORK_CHANNEL=12
CONFIG_OPENTHREAD_NETWORK_MASTERKEY="aabbccddeeff00112233445566778899"
CONFIG_ESP_SLEEP_DEBUG=y
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y

View File

@ -91,9 +91,9 @@ def test_thread_connect(dut:Tuple[IdfDut, IdfDut, IdfDut]) -> None:
cli_list = [cli_h2]
router_extaddr_list = ['7766554433221101']
ocf.reset_thread(br)
ocf.init_thread(br)
for cli in cli_list:
ocf.reset_thread(cli)
ocf.init_thread(cli)
br_ot_para = default_br_ot_para
ocf.joinThreadNetwork(br, br_ot_para)
cli_ot_para = default_cli_ot_para
@ -125,8 +125,8 @@ def test_thread_connect(dut:Tuple[IdfDut, IdfDut, IdfDut]) -> None:
# / \
# Wi-FI_Host Thread_End_Device
def formBasicWiFiThreadNetwork(br:IdfDut, cli:IdfDut) -> None:
ocf.reset_thread(br)
ocf.reset_thread(cli)
ocf.init_thread(br)
ocf.init_thread(cli)
ocf.joinWiFiNetwork(br, default_br_wifi_para)
ocf.joinThreadNetwork(br, default_br_ot_para)
ot_para = default_cli_ot_para
@ -540,3 +540,86 @@ def test_TCP_NAT64(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> N
ocf.execute_command(cli, 'factoryreset')
time.sleep(3)
assert b'hello' in mytcp.tcp_bytes
# Case 10: Sleepy device test
@pytest.mark.esp32h2
@pytest.mark.esp32c6
@pytest.mark.openthread_sleep
@pytest.mark.parametrize(
'config, count, app_path, target', [
('cli_h2|sleepy_c6', 2,
f'{os.path.join(os.path.dirname(__file__), "ot_cli")}'
f'|{os.path.join(os.path.dirname(__file__), "ot_sleepy_device")}',
'esp32h2|esp32c6'),
('cli_c6|sleepy_h2', 2,
f'{os.path.join(os.path.dirname(__file__), "ot_cli")}'
f'|{os.path.join(os.path.dirname(__file__), "ot_sleepy_device")}',
'esp32c6|esp32h2'),
],
indirect=True,
)
def test_ot_sleepy_device(dut: Tuple[IdfDut, IdfDut]) -> None:
leader = dut[0]
sleepy_device = dut[1]
try:
ocf.init_thread(leader)
time.sleep(3)
leader_para = ocf.thread_parameter('leader', '', '12', '7766554433221100', False)
leader_para.setnetworkname('OpenThread-ESP')
leader_para.setpanid('0x1234')
leader_para.setextpanid('dead00beef00cafe')
leader_para.setnetworkkey('aabbccddeeff00112233445566778899')
leader_para.setpskc('104810e2315100afd6bc9215a6bfac53')
ocf.clean_buffer(sleepy_device)
ocf.joinThreadNetwork(leader, leader_para)
ocf.clean_buffer(sleepy_device)
sleepy_device.serial.hard_reset()
sleepy_device.expect('detached -> child', timeout=20)
sleepy_device.expect('PMU_SLEEP_PD_TOP: True', timeout=10)
sleepy_device.expect('PMU_SLEEP_PD_MODEM: True', timeout=20)
ocf.clean_buffer(sleepy_device)
output = sleepy_device.expect(pexpect.TIMEOUT, timeout=5)
assert 'rst:' not in str(output) and 'boot:' not in str(output)
finally:
ocf.execute_command(leader, 'factoryreset')
time.sleep(3)
# Case 11: Basic startup Test of BR
@pytest.mark.supported_targets
@pytest.mark.esp32h2
@pytest.mark.esp32c6
@pytest.mark.openthread_br
@pytest.mark.flaky(reruns=1, reruns_delay=1)
@pytest.mark.parametrize(
'config, count, app_path, target', [
('rcp|br', 2,
f'{os.path.join(os.path.dirname(__file__), "ot_rcp")}'
f'|{os.path.join(os.path.dirname(__file__), "ot_br")}',
'esp32c6|esp32s3'),
],
indirect=True,
)
def test_basic_startup(dut: Tuple[IdfDut, IdfDut]) -> None:
br = dut[1]
dut[0].serial.stop_redirect_thread()
try:
ocf.init_thread(br)
time.sleep(3)
ocf.clean_buffer(br)
ocf.execute_command(br, 'ifconfig up')
br.expect('Done', timeout=5)
ocf.execute_command(br, 'thread start')
br.expect('Done', timeout=5)
assert ocf.wait_for_join(br, 'leader')
ocf.reset_thread(br)
ocf.joinWiFiNetwork(br, default_br_wifi_para)
ocf.execute_command(br, 'ifconfig up')
br.expect('Done', timeout=5)
ocf.execute_command(br, 'thread start')
br.expect('Done', timeout=5)
assert ocf.wait_for_join(br, 'leader')
finally:
ocf.execute_command(br, 'factoryreset')
time.sleep(3)