mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/system_tests_pytest_embedded' into 'master'
CI: migrated system example tests to pytest-embedded framework Closes IDFCI-1134 See merge request espressif/esp-idf!17401
This commit is contained in:
commit
8a9ab63ecb
@ -1,35 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
import ttfw_idf
|
|
||||||
from tiny_test_fw import Utility
|
|
||||||
|
|
||||||
|
|
||||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32c3'])
|
|
||||||
def test_examples_base_mac_address(env, extra_data):
|
|
||||||
|
|
||||||
dut = env.get_dut('base_mac_address', 'examples/system/base_mac_address')
|
|
||||||
dut.start_app()
|
|
||||||
|
|
||||||
dut.expect('BASE_MAC: Base MAC Address read from EFUSE BLK0', timeout=30)
|
|
||||||
hex_r = r', '.join((r'0x([0-9a-f]{1,2})',) * 6)
|
|
||||||
mac_m = dut.expect(re.compile(r'BASE_MAC: Using "' + hex_r + r'" as base MAC address'), timeout=5)
|
|
||||||
Utility.console_log('BASE_MAC detected: {}'.format(':'.join(mac_m)))
|
|
||||||
|
|
||||||
def get_expected_mac_string(increment):
|
|
||||||
'''
|
|
||||||
Return the string representation of the MAC address mac_m with the last octet incremented.
|
|
||||||
mac_m is an array of strings in hexa-decimal format without the '0x' prefix.
|
|
||||||
'''
|
|
||||||
return ', '.join(['0x{}'.format(m) for m in mac_m[:-1]] + [hex(int(mac_m[-1], 16) + increment)])
|
|
||||||
|
|
||||||
dut.expect_all('WIFI_STA MAC: ' + get_expected_mac_string(0),
|
|
||||||
'SoftAP MAC: ' + get_expected_mac_string(1),
|
|
||||||
'BT MAC: ' + get_expected_mac_string(2),
|
|
||||||
'Ethernet MAC: ' + get_expected_mac_string(3),
|
|
||||||
timeout=10)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_examples_base_mac_address()
|
|
@ -94,11 +94,13 @@ void app_main(void)
|
|||||||
derived_mac_addr[0], derived_mac_addr[1], derived_mac_addr[2],
|
derived_mac_addr[0], derived_mac_addr[1], derived_mac_addr[2],
|
||||||
derived_mac_addr[3], derived_mac_addr[4], derived_mac_addr[5]);
|
derived_mac_addr[3], derived_mac_addr[4], derived_mac_addr[5]);
|
||||||
|
|
||||||
|
#if CONFIG_ESP_MAC_ADDR_UNIVERSE_BT
|
||||||
//Get MAC address for Bluetooth
|
//Get MAC address for Bluetooth
|
||||||
ESP_ERROR_CHECK(esp_read_mac(derived_mac_addr, ESP_MAC_BT));
|
ESP_ERROR_CHECK(esp_read_mac(derived_mac_addr, ESP_MAC_BT));
|
||||||
ESP_LOGI("BT MAC", "0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x",
|
ESP_LOGI("BT MAC", "0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x",
|
||||||
derived_mac_addr[0], derived_mac_addr[1], derived_mac_addr[2],
|
derived_mac_addr[0], derived_mac_addr[1], derived_mac_addr[2],
|
||||||
derived_mac_addr[3], derived_mac_addr[4], derived_mac_addr[5]);
|
derived_mac_addr[3], derived_mac_addr[4], derived_mac_addr[5]);
|
||||||
|
#endif //SOC_BT_SUPPORTED
|
||||||
|
|
||||||
//Get MAC address for Ethernet
|
//Get MAC address for Ethernet
|
||||||
ESP_ERROR_CHECK(esp_read_mac(derived_mac_addr, ESP_MAC_ETH));
|
ESP_ERROR_CHECK(esp_read_mac(derived_mac_addr, ESP_MAC_ETH));
|
||||||
|
27
examples/system/base_mac_address/pytest_base_mac_address.py
Normal file
27
examples/system/base_mac_address/pytest_base_mac_address.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.supported_targets
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_base_mac_address(dut: Dut) -> None:
|
||||||
|
dut.expect_exact('BASE_MAC: Base MAC Address read from EFUSE BLK0')
|
||||||
|
hex_r = r', '.join((r'0x([0-9a-f]{1,2})',) * 6)
|
||||||
|
mac_m = dut.expect(r'BASE_MAC: Using "' + hex_r + r'" as base MAC address', timeout=5).groups()
|
||||||
|
|
||||||
|
def get_expected_mac_string(increment: int) -> str:
|
||||||
|
'''
|
||||||
|
Return the string representation of the MAC address mac_m with the last octet incremented.
|
||||||
|
mac_m is an array of strings in hexa-decimal format without the '0x' prefix.
|
||||||
|
'''
|
||||||
|
return ', '.join(['0x{}'.format(m.decode('utf8')) for m in mac_m[:-1]] + [hex(int(mac_m[-1], 16) + increment)])
|
||||||
|
|
||||||
|
dut.expect_exact('WIFI_STA MAC: ' + get_expected_mac_string(0), timeout=2)
|
||||||
|
dut.expect_exact('SoftAP MAC: ' + get_expected_mac_string(1))
|
||||||
|
|
||||||
|
if dut.target != 'esp32s2':
|
||||||
|
dut.expect_exact('BT MAC: ' + get_expected_mac_string(2))
|
||||||
|
dut.expect_exact('Ethernet MAC: ' + get_expected_mac_string(3))
|
@ -1,65 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import re
|
|
||||||
import time
|
|
||||||
|
|
||||||
import ttfw_idf
|
|
||||||
|
|
||||||
touch_wake_up_support = ['esp32', 'esp32s2']
|
|
||||||
|
|
||||||
|
|
||||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3'])
|
|
||||||
def test_examples_deep_sleep(env, extra_data):
|
|
||||||
|
|
||||||
dut = env.get_dut('deep_sleep', 'examples/system/deep_sleep')
|
|
||||||
dut.start_app()
|
|
||||||
|
|
||||||
def expect_enable_deep_sleep_touch():
|
|
||||||
# different targets configure different wake pin(s)
|
|
||||||
wake_pads = {
|
|
||||||
'esp32': [8,9],
|
|
||||||
'esp32s2': [9],
|
|
||||||
}[dut.TARGET]
|
|
||||||
|
|
||||||
print('Expecting to see wakeup configured on pad(s): {}'.format(wake_pads))
|
|
||||||
|
|
||||||
expect_items = ['Enabling timer wakeup, 20s']
|
|
||||||
for pad in wake_pads:
|
|
||||||
expect_items += [re.compile(r'Touch pad #{} average: \d+, wakeup threshold set to \d+.'.format(pad))]
|
|
||||||
expect_items += ['Enabling touch pad wakeup',
|
|
||||||
'Entering deep sleep']
|
|
||||||
|
|
||||||
dut.expect_all(*expect_items, timeout=10)
|
|
||||||
|
|
||||||
def expect_enable_deep_sleep_no_touch():
|
|
||||||
dut.expect_all('Enabling timer wakeup, 20s',
|
|
||||||
'Entering deep sleep',
|
|
||||||
timeout=10)
|
|
||||||
|
|
||||||
if dut.TARGET in touch_wake_up_support:
|
|
||||||
expect_enable_deep_sleep = expect_enable_deep_sleep_touch
|
|
||||||
else:
|
|
||||||
expect_enable_deep_sleep = expect_enable_deep_sleep_no_touch
|
|
||||||
|
|
||||||
dut.expect('Not a deep sleep reset', timeout=30)
|
|
||||||
expect_enable_deep_sleep()
|
|
||||||
|
|
||||||
start_sleep = time.time()
|
|
||||||
print('Waiting for wakeup...')
|
|
||||||
dut.expect('boot: ESP-IDF', timeout=30) # first output that's the same on all chips
|
|
||||||
|
|
||||||
sleep_time = time.time() - start_sleep
|
|
||||||
print('Host measured sleep time at {:.2f}s'.format(sleep_time))
|
|
||||||
assert 19 < sleep_time < 22 # note: high tolerance as measuring time on the host may have some timing skew
|
|
||||||
|
|
||||||
# This line indicates that the CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP option set in sdkconfig.defaults
|
|
||||||
# has correctly allowed skipping verification on wakeup
|
|
||||||
dut.expect('boot: Fast booting app from partition', timeout=2)
|
|
||||||
|
|
||||||
# Check that it measured 2xxxxms in deep sleep, i.e at least 20 seconds:
|
|
||||||
dut.expect(re.compile(r'Wake up from timer. Time spent in deep sleep: 2\d{4}ms'), timeout=2)
|
|
||||||
expect_enable_deep_sleep()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_examples_deep_sleep()
|
|
66
examples/system/deep_sleep/pytest_deep_sleep.py
Normal file
66
examples/system/deep_sleep/pytest_deep_sleep.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import time
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
touch_wake_up_support = ['esp32', 'esp32s2']
|
||||||
|
|
||||||
|
CONFIGS = [
|
||||||
|
pytest.param('esp32_singlecore', marks=[pytest.mark.esp32]),
|
||||||
|
pytest.param('generic', marks=[pytest.mark.supported_targets]),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('config', CONFIGS, indirect=True)
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_deep_sleep(dut: Dut) -> None:
|
||||||
|
|
||||||
|
def expect_enable_deep_sleep_touch() -> None:
|
||||||
|
# different targets configure different wake pin(s)
|
||||||
|
wake_pads = {
|
||||||
|
'esp32': [8,9],
|
||||||
|
'esp32s2': [9],
|
||||||
|
}[dut.target]
|
||||||
|
|
||||||
|
logging.info('Expecting to see wakeup configured on pad(s): {}'.format(wake_pads))
|
||||||
|
|
||||||
|
expect_items = ['Enabling timer wakeup, 20s']
|
||||||
|
for pad in wake_pads:
|
||||||
|
expect_items += [r'Touch pad #{} average: \d+, wakeup threshold set to \d+.'.format(pad)]
|
||||||
|
expect_items += ['Enabling touch pad wakeup',
|
||||||
|
'Entering deep sleep']
|
||||||
|
|
||||||
|
for exp in expect_items:
|
||||||
|
dut.expect(exp, timeout=10)
|
||||||
|
|
||||||
|
def expect_enable_deep_sleep_no_touch() -> None:
|
||||||
|
dut.expect_exact('Enabling timer wakeup, 20s', timeout=10)
|
||||||
|
dut.expect_exact('Entering deep sleep', timeout=10)
|
||||||
|
|
||||||
|
if dut.target in touch_wake_up_support:
|
||||||
|
expect_enable_deep_sleep = expect_enable_deep_sleep_touch
|
||||||
|
else:
|
||||||
|
expect_enable_deep_sleep = expect_enable_deep_sleep_no_touch
|
||||||
|
|
||||||
|
dut.expect_exact('Not a deep sleep reset')
|
||||||
|
expect_enable_deep_sleep()
|
||||||
|
|
||||||
|
start_sleep = time.time()
|
||||||
|
logging.info('Waiting for wakeup...')
|
||||||
|
dut.expect_exact('boot: ESP-IDF') # first output that's the same on all chips
|
||||||
|
|
||||||
|
sleep_time = time.time() - start_sleep
|
||||||
|
logging.info('Host measured sleep time at {:.2f}s'.format(sleep_time))
|
||||||
|
assert 19 < sleep_time < 22 # note: high tolerance as measuring time on the host may have some timing skew
|
||||||
|
|
||||||
|
# This line indicates that the CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP option set in sdkconfig.defaults
|
||||||
|
# has correctly allowed skipping verification on wakeup
|
||||||
|
dut.expect_exact('boot: Fast booting app from partition', timeout=2)
|
||||||
|
|
||||||
|
# Check that it measured 2xxxxms in deep sleep, i.e at least 20 seconds:
|
||||||
|
dut.expect(r'Wake up from timer. Time spent in deep sleep: 2\d{4}ms', timeout=2)
|
||||||
|
expect_enable_deep_sleep()
|
@ -1,40 +0,0 @@
|
|||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import ttfw_idf
|
|
||||||
|
|
||||||
TASK_ITERATION_LIMIT = 10
|
|
||||||
|
|
||||||
TASK_ITERATION_POSTING = 'posting TASK_EVENTS:TASK_ITERATION_EVENT to {}, iteration {} out of ' + str(TASK_ITERATION_LIMIT)
|
|
||||||
TASK_ITERATION_HANDLING = 'handling TASK_EVENTS:TASK_ITERATION_EVENT from {}, iteration {}'
|
|
||||||
|
|
||||||
|
|
||||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32c3'])
|
|
||||||
def test_user_event_loops_example(env, extra_data):
|
|
||||||
dut = env.get_dut('user_event_loops', 'examples/system/esp_event/user_event_loops')
|
|
||||||
|
|
||||||
dut.start_app()
|
|
||||||
|
|
||||||
dut.expect('setting up')
|
|
||||||
dut.expect('starting event source')
|
|
||||||
dut.expect('starting application task')
|
|
||||||
print('Finished setup')
|
|
||||||
|
|
||||||
for iteration in range(1, TASK_ITERATION_LIMIT + 1):
|
|
||||||
loop = None
|
|
||||||
|
|
||||||
if (iteration % 2 == 0):
|
|
||||||
loop = 'loop_with_task'
|
|
||||||
else:
|
|
||||||
loop = 'loop_without_task'
|
|
||||||
|
|
||||||
dut.expect(TASK_ITERATION_POSTING.format(loop, iteration))
|
|
||||||
print('Posted iteration {} to {}'.format(iteration, loop))
|
|
||||||
dut.expect(TASK_ITERATION_HANDLING.format(loop, iteration))
|
|
||||||
print('Handled iteration {} from {}'.format(iteration, loop))
|
|
||||||
|
|
||||||
dut.expect('deleting task event source')
|
|
||||||
print('Deleted task event source')
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_user_event_loops_example()
|
|
@ -94,7 +94,7 @@ void app_main(void)
|
|||||||
.queue_size = 5,
|
.queue_size = 5,
|
||||||
.task_name = "loop_task", // task will be created
|
.task_name = "loop_task", // task will be created
|
||||||
.task_priority = uxTaskPriorityGet(NULL),
|
.task_priority = uxTaskPriorityGet(NULL),
|
||||||
.task_stack_size = 2048,
|
.task_stack_size = 3072,
|
||||||
.task_core_id = tskNO_AFFINITY
|
.task_core_id = tskNO_AFFINITY
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -115,9 +115,9 @@ void app_main(void)
|
|||||||
ESP_LOGI(TAG, "starting event source");
|
ESP_LOGI(TAG, "starting event source");
|
||||||
|
|
||||||
// Create the event source task with the same priority as the current task
|
// Create the event source task with the same priority as the current task
|
||||||
xTaskCreate(task_event_source, "task_event_source", 2048, NULL, uxTaskPriorityGet(NULL), NULL);
|
xTaskCreate(task_event_source, "task_event_source", 3072, NULL, uxTaskPriorityGet(NULL), NULL);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "starting application task");
|
ESP_LOGI(TAG, "starting application task");
|
||||||
// Create the application task with the same priority as the current task
|
// Create the application task with the same priority as the current task
|
||||||
xTaskCreate(application_task, "application_task", 2048, NULL, uxTaskPriorityGet(NULL), NULL);
|
xTaskCreate(application_task, "application_task", 3072, NULL, uxTaskPriorityGet(NULL), NULL);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
TASK_ITERATION_LIMIT = 10
|
||||||
|
|
||||||
|
TASK_ITERATION_POSTING = 'posting TASK_EVENTS:TASK_ITERATION_EVENT to {}, iteration {} out of ' + str(TASK_ITERATION_LIMIT)
|
||||||
|
TASK_ITERATION_HANDLING = 'handling TASK_EVENTS:TASK_ITERATION_EVENT from {}, iteration {}'
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.supported_targets
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_esp_event_user_event_loops(dut: Dut) -> None:
|
||||||
|
|
||||||
|
dut.expect_exact('setting up')
|
||||||
|
dut.expect_exact('starting event source')
|
||||||
|
dut.expect_exact('starting application task')
|
||||||
|
|
||||||
|
for iteration in range(1, TASK_ITERATION_LIMIT + 1):
|
||||||
|
loop = None
|
||||||
|
|
||||||
|
if (iteration % 2 == 0):
|
||||||
|
loop = 'loop_with_task'
|
||||||
|
else:
|
||||||
|
loop = 'loop_without_task'
|
||||||
|
|
||||||
|
dut.expect(TASK_ITERATION_POSTING.format(loop, iteration))
|
||||||
|
logging.info('Posted iteration {} to {}'.format(iteration, loop))
|
||||||
|
dut.expect(TASK_ITERATION_HANDLING.format(loop, iteration))
|
||||||
|
logging.info('Handled iteration {} from {}'.format(iteration, loop))
|
||||||
|
|
||||||
|
dut.expect('deleting task event source')
|
||||||
|
logging.info('Deleted task event source')
|
@ -1,89 +0,0 @@
|
|||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
import ttfw_idf
|
|
||||||
|
|
||||||
STARTING_TIMERS_REGEX = re.compile(r'Started timers, time since boot: (\d+) us')
|
|
||||||
|
|
||||||
# name, period, next_alarm, times_started, times_fired, times_skipped, cb_exec_time
|
|
||||||
TIMER_DUMP_LINE_REGEX = re.compile(r'([\w-]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)')
|
|
||||||
|
|
||||||
PERIODIC_TIMER_REGEX = re.compile(r'Periodic timer called, time since boot: (\d+) us')
|
|
||||||
|
|
||||||
LIGHT_SLEEP_ENTER_REGEX = re.compile(r'Entering light sleep for 0\.5s, time since boot: (\d+) us')
|
|
||||||
LIGHT_SLEEP_EXIT_REGEX = re.compile(r'Woke up from light sleep, time since boot: (\d+) us')
|
|
||||||
|
|
||||||
ONE_SHOT_REGEX = re.compile(r'One\-shot timer called, time since boot: (\d+) us')
|
|
||||||
|
|
||||||
RESTART_REGEX = re.compile(r'Restarted periodic timer with 1s period, time since boot: (\d+) us')
|
|
||||||
|
|
||||||
STOP_REGEX = re.compile(r'Stopped and deleted timers')
|
|
||||||
|
|
||||||
INITIAL_TIMER_PERIOD = 500000
|
|
||||||
FINAL_TIMER_PERIOD = 1000000
|
|
||||||
LIGHT_SLEEP_TIME = 500000
|
|
||||||
ONE_SHOT_TIMER_PERIOD = 5000000
|
|
||||||
|
|
||||||
|
|
||||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32','esp32s2','esp32c3','esp32s3'])
|
|
||||||
def test_examples_system_esp_timer(env, extra_data):
|
|
||||||
dut = env.get_dut('esp_timer_example', 'examples/system/esp_timer')
|
|
||||||
# start test
|
|
||||||
dut.start_app()
|
|
||||||
groups = dut.expect(STARTING_TIMERS_REGEX, timeout=30)
|
|
||||||
start_time = int(groups[0])
|
|
||||||
print('Start time: {} us'.format(start_time))
|
|
||||||
|
|
||||||
groups = dut.expect(TIMER_DUMP_LINE_REGEX, timeout=2)
|
|
||||||
assert(groups[0] == 'periodic' and int(groups[1]) == INITIAL_TIMER_PERIOD)
|
|
||||||
groups = dut.expect(TIMER_DUMP_LINE_REGEX, timeout=2)
|
|
||||||
assert(groups[0] == 'one-shot' and int(groups[1]) == 0)
|
|
||||||
|
|
||||||
for i in range(0, 5):
|
|
||||||
groups = dut.expect(PERIODIC_TIMER_REGEX, timeout=2)
|
|
||||||
cur_time = int(groups[0])
|
|
||||||
diff = start_time + (i + 1) * INITIAL_TIMER_PERIOD - cur_time
|
|
||||||
print('Callback #{}, time: {} us, diff: {} us'.format(i, cur_time, diff))
|
|
||||||
assert(abs(diff) < 100)
|
|
||||||
|
|
||||||
groups = dut.expect(ONE_SHOT_REGEX, timeout=3)
|
|
||||||
one_shot_timer_time = int(groups[0])
|
|
||||||
diff = start_time + ONE_SHOT_TIMER_PERIOD - one_shot_timer_time
|
|
||||||
print('One-shot timer, time: {} us, diff: {}'.format(one_shot_timer_time, diff))
|
|
||||||
assert(abs(diff) < 220)
|
|
||||||
|
|
||||||
groups = dut.expect(RESTART_REGEX, timeout=3)
|
|
||||||
start_time = int(groups[0])
|
|
||||||
print('Timer restarted, time: {} us'.format(start_time))
|
|
||||||
|
|
||||||
for i in range(0, 5):
|
|
||||||
groups = dut.expect(PERIODIC_TIMER_REGEX, timeout=2)
|
|
||||||
cur_time = int(groups[0])
|
|
||||||
diff = start_time + (i + 1) * FINAL_TIMER_PERIOD - cur_time
|
|
||||||
print('Callback #{}, time: {} us, diff: {} us'.format(i, cur_time, diff))
|
|
||||||
assert(abs(diff) < 100)
|
|
||||||
|
|
||||||
groups = dut.expect(LIGHT_SLEEP_ENTER_REGEX, timeout=2)
|
|
||||||
sleep_enter_time = int(groups[0])
|
|
||||||
groups = dut.expect(LIGHT_SLEEP_EXIT_REGEX, timeout=2)
|
|
||||||
sleep_exit_time = int(groups[0])
|
|
||||||
sleep_time = sleep_exit_time - sleep_enter_time
|
|
||||||
|
|
||||||
print('Enter sleep: {}, exit sleep: {}, slept: {}'.format(
|
|
||||||
sleep_enter_time, sleep_exit_time, sleep_time))
|
|
||||||
|
|
||||||
assert(abs(sleep_time - LIGHT_SLEEP_TIME) < 1000)
|
|
||||||
|
|
||||||
for i in range(5, 7):
|
|
||||||
groups = dut.expect(PERIODIC_TIMER_REGEX, timeout=2)
|
|
||||||
cur_time = int(groups[0])
|
|
||||||
diff = abs(start_time + (i + 1) * FINAL_TIMER_PERIOD - cur_time)
|
|
||||||
print('Callback #{}, time: {} us, diff: {} us'.format(i, cur_time, diff))
|
|
||||||
assert(diff < 100)
|
|
||||||
|
|
||||||
dut.expect(STOP_REGEX, timeout=2)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_examples_system_esp_timer()
|
|
86
examples/system/esp_timer/pytest_esp_timer.py
Normal file
86
examples/system/esp_timer/pytest_esp_timer.py
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
STARTING_TIMERS_REGEX = r'Started timers, time since boot: (\d+) us'
|
||||||
|
|
||||||
|
# name, period, next_alarm, times_started, times_fired, times_skipped, cb_exec_time
|
||||||
|
TIMER_DUMP_LINE_REGEX = r'([\w-]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)'
|
||||||
|
|
||||||
|
PERIODIC_TIMER_REGEX = r'Periodic timer called, time since boot: (\d+) us'
|
||||||
|
|
||||||
|
LIGHT_SLEEP_ENTER_REGEX = r'Entering light sleep for 0\.5s, time since boot: (\d+) us'
|
||||||
|
LIGHT_SLEEP_EXIT_REGEX = r'Woke up from light sleep, time since boot: (\d+) us'
|
||||||
|
|
||||||
|
ONE_SHOT_REGEX = r'One\-shot timer called, time since boot: (\d+) us'
|
||||||
|
|
||||||
|
RESTART_REGEX = r'Restarted periodic timer with 1s period, time since boot: (\d+) us'
|
||||||
|
|
||||||
|
STOP_REGEX = r'Stopped and deleted timers'
|
||||||
|
|
||||||
|
INITIAL_TIMER_PERIOD = 500000
|
||||||
|
FINAL_TIMER_PERIOD = 1000000
|
||||||
|
LIGHT_SLEEP_TIME = 500000
|
||||||
|
ONE_SHOT_TIMER_PERIOD = 5000000
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.supported_targets
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_esp_timer(dut: Dut) -> None:
|
||||||
|
|
||||||
|
match = dut.expect(STARTING_TIMERS_REGEX)
|
||||||
|
start_time = int(match.group(1))
|
||||||
|
logging.info('Start time: {} us'.format(start_time))
|
||||||
|
|
||||||
|
match = dut.expect(TIMER_DUMP_LINE_REGEX, timeout=2)
|
||||||
|
assert(match.group(1).decode('utf8') == 'periodic' and int(match.group(2)) == INITIAL_TIMER_PERIOD)
|
||||||
|
match = dut.expect(TIMER_DUMP_LINE_REGEX, timeout=2)
|
||||||
|
assert(match.group(1).decode('utf8') == 'one-shot' and int(match.group(2)) == 0)
|
||||||
|
|
||||||
|
for i in range(0, 5):
|
||||||
|
match = dut.expect(PERIODIC_TIMER_REGEX, timeout=2)
|
||||||
|
cur_time = int(match.group(1))
|
||||||
|
diff = start_time + (i + 1) * INITIAL_TIMER_PERIOD - cur_time
|
||||||
|
logging.info('Callback #{}, time: {} us, diff: {} us'.format(i, cur_time, diff))
|
||||||
|
assert(abs(diff) < 100)
|
||||||
|
|
||||||
|
match = dut.expect(ONE_SHOT_REGEX, timeout=3)
|
||||||
|
one_shot_timer_time = int(match.group(1))
|
||||||
|
diff = start_time + ONE_SHOT_TIMER_PERIOD - one_shot_timer_time
|
||||||
|
logging.info('One-shot timer, time: {} us, diff: {}'.format(one_shot_timer_time, diff))
|
||||||
|
assert(abs(diff) < 220)
|
||||||
|
|
||||||
|
match = dut.expect(RESTART_REGEX, timeout=3)
|
||||||
|
start_time = int(match.group(1))
|
||||||
|
logging.info('Timer restarted, time: {} us'.format(start_time))
|
||||||
|
|
||||||
|
for i in range(0, 5):
|
||||||
|
match = dut.expect(PERIODIC_TIMER_REGEX, timeout=2)
|
||||||
|
cur_time = int(match.group(1))
|
||||||
|
diff = start_time + (i + 1) * FINAL_TIMER_PERIOD - cur_time
|
||||||
|
logging.info('Callback #{}, time: {} us, diff: {} us'.format(i, cur_time, diff))
|
||||||
|
assert(abs(diff) < 100)
|
||||||
|
|
||||||
|
match = dut.expect(LIGHT_SLEEP_ENTER_REGEX, timeout=2)
|
||||||
|
sleep_enter_time = int(match.group(1))
|
||||||
|
match = dut.expect(LIGHT_SLEEP_EXIT_REGEX, timeout=2)
|
||||||
|
sleep_exit_time = int(match.group(1))
|
||||||
|
sleep_time = sleep_exit_time - sleep_enter_time
|
||||||
|
|
||||||
|
logging.info('Enter sleep: {}, exit sleep: {}, slept: {}'.format(
|
||||||
|
sleep_enter_time, sleep_exit_time, sleep_time))
|
||||||
|
|
||||||
|
assert(abs(sleep_time - LIGHT_SLEEP_TIME) < 1000)
|
||||||
|
|
||||||
|
for i in range(5, 7):
|
||||||
|
match = dut.expect(PERIODIC_TIMER_REGEX, timeout=2)
|
||||||
|
cur_time = int(match.group(1))
|
||||||
|
diff = abs(start_time + (i + 1) * FINAL_TIMER_PERIOD - cur_time)
|
||||||
|
logging.info('Callback #{}, time: {} us, diff: {} us'.format(i, cur_time, diff))
|
||||||
|
assert(diff < 100)
|
||||||
|
|
||||||
|
dut.expect(STOP_REGEX, timeout=2)
|
@ -1,38 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
import ttfw_idf
|
|
||||||
from tiny_test_fw import Env, Utility
|
|
||||||
|
|
||||||
|
|
||||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC')
|
|
||||||
def test_examples_eventfd(env, extra_data):
|
|
||||||
# type: (Env, None) -> None
|
|
||||||
|
|
||||||
dut = env.get_dut('eventfd', 'examples/system/eventfd')
|
|
||||||
dut.start_app()
|
|
||||||
|
|
||||||
dut.expect('cpu_start: Starting scheduler', timeout=30)
|
|
||||||
|
|
||||||
exp_list_5seconds = [
|
|
||||||
'eventfd_example: Select timeouted for 1 times',
|
|
||||||
'eventfd_example: Timer triggerred for 2 times',
|
|
||||||
'eventfd_example: Progress triggerred for 1 times',
|
|
||||||
]
|
|
||||||
|
|
||||||
exp_list_10seconds = [
|
|
||||||
'eventfd_example: Select timeouted for 2 times',
|
|
||||||
'eventfd_example: Timer triggerred for 4 times',
|
|
||||||
'eventfd_example: Progress triggerred for 2 times',
|
|
||||||
]
|
|
||||||
|
|
||||||
Utility.console_log('Expecting:{}{}'.format(os.linesep, os.linesep.join(exp_list_5seconds)))
|
|
||||||
dut.expect_all(*exp_list_5seconds, timeout=60)
|
|
||||||
|
|
||||||
Utility.console_log('Expecting:{}{}'.format(os.linesep, os.linesep.join(exp_list_10seconds)))
|
|
||||||
dut.expect_all(*exp_list_10seconds, timeout=60)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_examples_eventfd()
|
|
35
examples/system/eventfd/pytest_eventfd.py
Normal file
35
examples/system/eventfd/pytest_eventfd.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.supported_targets
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_eventfd(dut: Dut) -> None:
|
||||||
|
|
||||||
|
dut.expect_exact('cpu_start: Starting scheduler')
|
||||||
|
|
||||||
|
exp_list_5seconds = [
|
||||||
|
'eventfd_example: Select timeouted for 1 times',
|
||||||
|
'eventfd_example: Timer triggerred for 2 times',
|
||||||
|
'eventfd_example: Progress triggerred for 1 times',
|
||||||
|
]
|
||||||
|
|
||||||
|
exp_list_10seconds = [
|
||||||
|
'eventfd_example: Select timeouted for 2 times',
|
||||||
|
'eventfd_example: Timer triggerred for 4 times',
|
||||||
|
'eventfd_example: Progress triggerred for 2 times',
|
||||||
|
]
|
||||||
|
|
||||||
|
logging.info('Expecting:{}{}'.format(os.linesep, os.linesep.join(exp_list_5seconds)))
|
||||||
|
for exp in exp_list_5seconds:
|
||||||
|
dut.expect_exact(exp)
|
||||||
|
|
||||||
|
logging.info('Expecting:{}{}'.format(os.linesep, os.linesep.join(exp_list_10seconds)))
|
||||||
|
for exp in exp_list_10seconds:
|
||||||
|
dut.expect_exact(exp)
|
@ -1,19 +0,0 @@
|
|||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import ttfw_idf
|
|
||||||
|
|
||||||
STATS_TASK_ITERS = 3
|
|
||||||
STATS_TASK_EXPECT = 'Real time stats obtained'
|
|
||||||
|
|
||||||
|
|
||||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32c3'])
|
|
||||||
def test_real_time_stats_example(env, extra_data):
|
|
||||||
dut = env.get_dut('real_time_stats', 'examples/system/freertos/real_time_stats')
|
|
||||||
dut.start_app()
|
|
||||||
|
|
||||||
for iteration in range(0, STATS_TASK_ITERS):
|
|
||||||
dut.expect(STATS_TASK_EXPECT)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_real_time_stats_example()
|
|
@ -0,0 +1,13 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.supported_targets
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_freertos_real_time_stats(dut: Dut) -> None:
|
||||||
|
|
||||||
|
for _ in range(0, 3):
|
||||||
|
dut.expect_exact('Real time stats obtained')
|
@ -1,24 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
import ttfw_idf
|
|
||||||
|
|
||||||
|
|
||||||
@ttfw_idf.idf_example_test(env_tag='8Mpsram')
|
|
||||||
def test_examples_himem(env, extra_data):
|
|
||||||
|
|
||||||
dut = env.get_dut('himem', 'examples/system/himem')
|
|
||||||
dut.start_app()
|
|
||||||
|
|
||||||
mem = dut.expect(re.compile(r'esp_himem: Initialized. Using last \d+ 32KB address blocks for bank '
|
|
||||||
r'switching on (\d+) KB of physical memory.'), timeout=30)[0]
|
|
||||||
|
|
||||||
dut.expect_all(re.compile(r'Himem has {}KiB of memory, \d+KiB of which is free. '
|
|
||||||
r'Testing the free memory...'.format(mem)),
|
|
||||||
'Done!',
|
|
||||||
timeout=10)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_examples_himem()
|
|
17
examples/system/himem/pytest_himem.py
Normal file
17
examples/system/himem/pytest_himem.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.esp32
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_himem(dut: Dut) -> None:
|
||||||
|
|
||||||
|
mem = dut.expect(r'esp_himem: Initialized. Using last \d+ 32KB address blocks for bank '
|
||||||
|
r'switching on (\d+) KB of physical memory.').group(1).decode('utf8')
|
||||||
|
|
||||||
|
dut.expect(r'Himem has {}KiB of memory, \d+KiB of which is free.'.format(mem), timeout=10)
|
||||||
|
dut.expect_exact('Testing the free memory...')
|
||||||
|
dut.expect_exact('Done!')
|
@ -1,28 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import ttfw_idf
|
|
||||||
|
|
||||||
|
|
||||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32'])
|
|
||||||
def test_examples_ipc_isr(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None
|
|
||||||
|
|
||||||
dut = env.get_dut('ipc_isr', 'examples/system/ipc/ipc_isr')
|
|
||||||
dut.start_app()
|
|
||||||
|
|
||||||
dut.expect_all('example: Start',
|
|
||||||
'example: PS_INTLEVEL = 0x5',
|
|
||||||
'example: PS_EXCM = 0x0',
|
|
||||||
'example: PS_UM = 0x1',
|
|
||||||
'example: in[0] = 0x1',
|
|
||||||
'example: in[1] = 0x2',
|
|
||||||
'example: in[2] = 0x3',
|
|
||||||
'example: out[0] = (in[0] | in[1] | in[2]) = 0x3',
|
|
||||||
'example: out[1] = (in[0] & in[1] & in[2]) = 0x6',
|
|
||||||
'example: out[2] = in[2] = 0x3',
|
|
||||||
'example: out[3] = PS of other cpu = 0x25',
|
|
||||||
'example: End',
|
|
||||||
timeout=10)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_examples_ipc_isr()
|
|
24
examples/system/ipc/ipc_isr/pytest_ipc_isr.py
Normal file
24
examples/system/ipc/ipc_isr/pytest_ipc_isr.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.esp32
|
||||||
|
@pytest.mark.esp32s3
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_ipc_isr(dut: Dut) -> None:
|
||||||
|
|
||||||
|
dut.expect_exact('example: Start')
|
||||||
|
dut.expect_exact('example: PS_INTLEVEL = 0x5')
|
||||||
|
dut.expect_exact('example: PS_EXCM = 0x0')
|
||||||
|
dut.expect_exact('example: PS_UM = 0x1')
|
||||||
|
dut.expect_exact('example: in[0] = 0x1')
|
||||||
|
dut.expect_exact('example: in[1] = 0x2')
|
||||||
|
dut.expect_exact('example: in[2] = 0x3')
|
||||||
|
dut.expect_exact('example: out[0] = (in[0] | in[1] | in[2]) = 0x3')
|
||||||
|
dut.expect_exact('example: out[1] = (in[0] & in[1] & in[2]) = 0x6')
|
||||||
|
dut.expect_exact('example: out[2] = in[2] = 0x3')
|
||||||
|
dut.expect_exact('example: out[3] = PS of other cpu = 0x25')
|
||||||
|
dut.expect_exact('example: End')
|
@ -1,67 +0,0 @@
|
|||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import re
|
|
||||||
import time
|
|
||||||
|
|
||||||
import ttfw_idf
|
|
||||||
|
|
||||||
ENTERING_SLEEP_STR = 'Entering light sleep'
|
|
||||||
EXIT_SLEEP_REGEX = re.compile(r'Returned from light sleep, reason: (\w+), t=(\d+) ms, slept for (\d+) ms')
|
|
||||||
WAITING_FOR_GPIO_STR = re.compile(r'Waiting for GPIO\d to go high...')
|
|
||||||
|
|
||||||
WAKEUP_INTERVAL_MS = 2000
|
|
||||||
|
|
||||||
|
|
||||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3', 'esp32s3'])
|
|
||||||
def test_examples_system_light_sleep(env, extra_data):
|
|
||||||
dut = env.get_dut('light_sleep_example', 'examples/system/light_sleep')
|
|
||||||
dut.start_app()
|
|
||||||
|
|
||||||
# Ensure DTR and RTS are de-asserted for proper control of GPIO0
|
|
||||||
dut.port_inst.setDTR(False)
|
|
||||||
dut.port_inst.setRTS(False)
|
|
||||||
|
|
||||||
# enter sleep first time
|
|
||||||
dut.expect(ENTERING_SLEEP_STR, timeout=30)
|
|
||||||
# don't check timing here, might be cache dependent
|
|
||||||
dut.expect(EXIT_SLEEP_REGEX)
|
|
||||||
print('Got first sleep period')
|
|
||||||
|
|
||||||
# enter sleep second time
|
|
||||||
dut.expect(ENTERING_SLEEP_STR)
|
|
||||||
groups = dut.expect(EXIT_SLEEP_REGEX)
|
|
||||||
print('Got second sleep period, wakeup from {}, slept for {}'.format(groups[0], groups[2]))
|
|
||||||
# sleep time error should be less than 1ms
|
|
||||||
assert(groups[0] == 'timer' and int(groups[2]) >= WAKEUP_INTERVAL_MS - 1 and int(groups[2]) <= WAKEUP_INTERVAL_MS + 1)
|
|
||||||
|
|
||||||
# this time we'll test gpio wakeup
|
|
||||||
dut.expect(ENTERING_SLEEP_STR)
|
|
||||||
print('Pulling GPIO0 low using DTR')
|
|
||||||
dut.port_inst.setDTR(True)
|
|
||||||
time.sleep(1)
|
|
||||||
groups = dut.expect(EXIT_SLEEP_REGEX)
|
|
||||||
print('Got third sleep period, wakeup from {}, slept for {}'.format(groups[0], groups[2]))
|
|
||||||
assert(groups[0] == 'pin' and int(groups[2]) < WAKEUP_INTERVAL_MS)
|
|
||||||
|
|
||||||
dut.expect(WAITING_FOR_GPIO_STR)
|
|
||||||
print('Is waiting for GPIO...')
|
|
||||||
|
|
||||||
dut.port_inst.setDTR(False)
|
|
||||||
dut.expect(ENTERING_SLEEP_STR)
|
|
||||||
print('Went to sleep again')
|
|
||||||
|
|
||||||
# Write 'U' to uart, 'U' in ascii is 0x55 which contains 8 edges in total
|
|
||||||
dut.write('U')
|
|
||||||
time.sleep(1)
|
|
||||||
groups = dut.expect(EXIT_SLEEP_REGEX)
|
|
||||||
print('Got third sleep period, wakeup from {}, slept for {}'.format(groups[0], groups[2]))
|
|
||||||
assert(groups[0] == 'uart' and int(groups[2]) < WAKEUP_INTERVAL_MS)
|
|
||||||
print('Went to sleep again')
|
|
||||||
|
|
||||||
groups = dut.expect(EXIT_SLEEP_REGEX)
|
|
||||||
assert(groups[0] == 'timer' and int(groups[2]) >= WAKEUP_INTERVAL_MS - 1 and int(groups[2]) <= WAKEUP_INTERVAL_MS + 1)
|
|
||||||
print('Woke up from timer again')
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_examples_system_light_sleep()
|
|
64
examples/system/light_sleep/pytest_light_sleep.py
Normal file
64
examples/system/light_sleep/pytest_light_sleep.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import time
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.supported_targets
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_light_sleep(dut: Dut) -> None:
|
||||||
|
|
||||||
|
ENTERING_SLEEP_STR = 'Entering light sleep'
|
||||||
|
EXIT_SLEEP_REGEX = r'Returned from light sleep, reason: (\w+), t=(\d+) ms, slept for (\d+) ms'
|
||||||
|
WAITING_FOR_GPIO_STR = r'Waiting for GPIO\d to go high...'
|
||||||
|
|
||||||
|
WAKEUP_INTERVAL_MS = 2000
|
||||||
|
|
||||||
|
# Ensure DTR and RTS are de-asserted for proper control of GPIO0
|
||||||
|
dut.serial.proc.setDTR(False)
|
||||||
|
dut.serial.proc.setRTS(False)
|
||||||
|
|
||||||
|
# enter sleep first time
|
||||||
|
dut.expect_exact(ENTERING_SLEEP_STR, timeout=30)
|
||||||
|
# don't check timing here, might be cache dependent
|
||||||
|
dut.expect(EXIT_SLEEP_REGEX)
|
||||||
|
logging.info('Got first sleep period')
|
||||||
|
|
||||||
|
# enter sleep second time
|
||||||
|
dut.expect_exact(ENTERING_SLEEP_STR)
|
||||||
|
match = dut.expect(EXIT_SLEEP_REGEX)
|
||||||
|
logging.info('Got second sleep period, wakeup from {}, slept for {}'.format(match.group(1), match.group(3)))
|
||||||
|
# sleep time error should be less than 1ms
|
||||||
|
assert(match.group(1).decode('utf8') == 'timer' and int(match.group(3)) >= WAKEUP_INTERVAL_MS - 1 and int(match.group(3)) <= WAKEUP_INTERVAL_MS + 1)
|
||||||
|
|
||||||
|
# this time we'll test gpio wakeup
|
||||||
|
dut.expect_exact(ENTERING_SLEEP_STR)
|
||||||
|
logging.info('Pulling GPIO0 low using DTR')
|
||||||
|
dut.serial.proc.setDTR(True)
|
||||||
|
time.sleep(1)
|
||||||
|
match = dut.expect(EXIT_SLEEP_REGEX)
|
||||||
|
logging.info('Got third sleep period, wakeup from {}, slept for {}'.format(match.group(1), match.group(3)))
|
||||||
|
assert(match.group(1).decode('utf8') == 'pin' and int(match.group(3)) < WAKEUP_INTERVAL_MS)
|
||||||
|
|
||||||
|
dut.expect(WAITING_FOR_GPIO_STR)
|
||||||
|
logging.info('Is waiting for GPIO...')
|
||||||
|
|
||||||
|
dut.serial.proc.setDTR(False)
|
||||||
|
dut.expect_exact(ENTERING_SLEEP_STR)
|
||||||
|
logging.info('Went to sleep again')
|
||||||
|
|
||||||
|
# Write 'U' to uart, 'U' in ascii is 0x55 which contains 8 edges in total
|
||||||
|
dut.write('U')
|
||||||
|
time.sleep(1)
|
||||||
|
match = dut.expect(EXIT_SLEEP_REGEX)
|
||||||
|
logging.info('Got third sleep period, wakeup from {}, slept for {}'.format(match.group(1), match.group(3)))
|
||||||
|
assert(match.group(1).decode('utf8') == 'uart' and int(match.group(3)) < WAKEUP_INTERVAL_MS)
|
||||||
|
logging.info('Went to sleep again')
|
||||||
|
|
||||||
|
match = dut.expect(EXIT_SLEEP_REGEX)
|
||||||
|
assert(match.group(1).decode('utf8') == 'timer' and int(match.group(3)) >= WAKEUP_INTERVAL_MS - 1 and int(match.group(3)) <= WAKEUP_INTERVAL_MS + 1)
|
||||||
|
logging.info('Woke up from timer again')
|
@ -1,20 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import ttfw_idf
|
|
||||||
|
|
||||||
|
|
||||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32'])
|
|
||||||
def test_examples_perfmon(env, extra_data):
|
|
||||||
|
|
||||||
dut = env.get_dut('perfmon', 'examples/system/perfmon')
|
|
||||||
dut.start_app()
|
|
||||||
|
|
||||||
dut.expect_all('example: Start',
|
|
||||||
'example: Start test with printing all available statistic',
|
|
||||||
'example: Start test with user defined statistic',
|
|
||||||
'example: The End',
|
|
||||||
timeout=60)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_examples_perfmon()
|
|
17
examples/system/perfmon/pytest_perfmon.py
Normal file
17
examples/system/perfmon/pytest_perfmon.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.esp32
|
||||||
|
@pytest.mark.esp32s2
|
||||||
|
@pytest.mark.esp32s3
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_perfmon(dut: Dut) -> None:
|
||||||
|
|
||||||
|
dut.expect('example: Start')
|
||||||
|
dut.expect('example: Start test with printing all available statistic')
|
||||||
|
dut.expect('example: Start test with user defined statistic')
|
||||||
|
dut.expect('example: The End')
|
@ -1,27 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
from __future__ import division, print_function, unicode_literals
|
|
||||||
|
|
||||||
import re
|
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
import ttfw_idf
|
|
||||||
|
|
||||||
|
|
||||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3'])
|
|
||||||
def test_examples_pthread(env, _): # type: (Any, Any) -> None
|
|
||||||
app_name = 'pthread'
|
|
||||||
dut = env.get_dut(app_name, 'examples/system/pthread')
|
|
||||||
dut.start_app()
|
|
||||||
|
|
||||||
# Note: this test doesn't really confirm anything, except that threads are created
|
|
||||||
# and stdout is not being corrupted by multiple threads printing ot it.
|
|
||||||
dut.expect(re.compile(r'Created thread 0x[\da-f]+'))
|
|
||||||
dut.expect(re.compile(r'Created larger stack thread 0x[\da-f]+'))
|
|
||||||
dut.expect(r'Threads have exited')
|
|
||||||
dut.expect(re.compile(r'Created thread 0x[\da-f]+ with new default config'))
|
|
||||||
dut.expect('Thread has exited')
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_examples_pthread()
|
|
18
examples/system/pthread/pytest_pthread.py
Normal file
18
examples/system/pthread/pytest_pthread.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.supported_targets
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_pthread(dut: Dut) -> None:
|
||||||
|
|
||||||
|
# Note: this test doesn't really confirm anything, except that threads are created
|
||||||
|
# and stdout is not being corrupted by multiple threads printing ot it.
|
||||||
|
dut.expect(r'Created thread 0x[\da-f]+')
|
||||||
|
dut.expect(r'Created larger stack thread 0x[\da-f]+')
|
||||||
|
dut.expect(r'Threads have exited')
|
||||||
|
dut.expect(r'Created thread 0x[\da-f]+ with new default config')
|
||||||
|
dut.expect('Thread has exited')
|
@ -1,19 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import ttfw_idf
|
|
||||||
|
|
||||||
|
|
||||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32c3'])
|
|
||||||
def test_examples_task_watchdog(env, extra_data):
|
|
||||||
|
|
||||||
dut = env.get_dut('task_watchdog', 'examples/system/task_watchdog')
|
|
||||||
dut.start_app()
|
|
||||||
|
|
||||||
dut.expect_all('Initialize TWDT',
|
|
||||||
'Delay for 10 seconds', timeout=30)
|
|
||||||
dut.expect_all('Unsubscribing and deleting tasks',
|
|
||||||
'Complete', timeout=20)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_examples_task_watchdog()
|
|
15
examples/system/task_watchdog/pytest_task_watchdog.py
Normal file
15
examples/system/task_watchdog/pytest_task_watchdog.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.supported_targets
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_task_watchdog(dut: Dut) -> None:
|
||||||
|
|
||||||
|
dut.expect_exact('Initialize TWDT')
|
||||||
|
dut.expect_exact('Delay for 10 seconds')
|
||||||
|
dut.expect_exact('Unsubscribing and deleting tasks')
|
||||||
|
dut.expect_exact('Complete')
|
@ -1,45 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import re
|
|
||||||
import time
|
|
||||||
|
|
||||||
import ttfw_idf
|
|
||||||
from tiny_test_fw import Utility
|
|
||||||
|
|
||||||
|
|
||||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32'])
|
|
||||||
def test_examples_ulp(env, extra_data):
|
|
||||||
|
|
||||||
dut = env.get_dut('ulp', 'examples/system/ulp_fsm/ulp')
|
|
||||||
dut.start_app()
|
|
||||||
|
|
||||||
dut.expect_all('Not ULP wakeup, initializing ULP',
|
|
||||||
'Entering deep sleep',
|
|
||||||
timeout=30)
|
|
||||||
|
|
||||||
def generate_gpio0_events():
|
|
||||||
for _ in range(5):
|
|
||||||
dut.port_inst.setDTR(True) # Pulling GPIO0 low using DTR
|
|
||||||
time.sleep(0.25)
|
|
||||||
dut.port_inst.setDTR(False)
|
|
||||||
time.sleep(0.25)
|
|
||||||
|
|
||||||
nvs_value = None
|
|
||||||
for _ in range(5):
|
|
||||||
generate_gpio0_events()
|
|
||||||
dut.expect('ULP wakeup, saving pulse count', timeout=5)
|
|
||||||
Utility.console_log('Woke up...')
|
|
||||||
init_count = int(dut.expect(re.compile(r'Read pulse count from NVS:\s+(\d+)'), timeout=5)[0], 10)
|
|
||||||
assert nvs_value in (init_count, None), ('Read count is {} and previously written value is {}'
|
|
||||||
''.format(init_count, nvs_value))
|
|
||||||
inc = int(dut.expect(re.compile(r'Pulse count from ULP:\s+(\d+)'), timeout=5)[0], 10)
|
|
||||||
assert inc in (5, 6), 'pulse count is {}'.format(inc)
|
|
||||||
new_count = int(dut.expect(re.compile(r'Wrote updated pulse count to NVS:\s+(\d+)'), timeout=5)[0], 10)
|
|
||||||
assert init_count + inc == new_count, '{} + {} != {}'.format(init_count, inc, new_count)
|
|
||||||
nvs_value = new_count
|
|
||||||
Utility.console_log('Pulse count written to NVS: {}. Entering deep sleep...'.format(nvs_value))
|
|
||||||
dut.expect('Entering deep sleep', timeout=5)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_examples_ulp()
|
|
43
examples/system/ulp_fsm/ulp/pytest_ulp_fsm.py
Normal file
43
examples/system/ulp_fsm/ulp/pytest_ulp_fsm.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import time
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.esp32
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_ulp_fsm(dut: Dut) -> None:
|
||||||
|
|
||||||
|
dut.expect_exact('Not ULP wakeup')
|
||||||
|
dut.expect_exact('Entering deep sleep')
|
||||||
|
|
||||||
|
def generate_gpio0_events() -> None:
|
||||||
|
for _ in range(5):
|
||||||
|
dut.serial.proc.setDTR(True) # Pulling GPIO0 low using DTR
|
||||||
|
time.sleep(0.25)
|
||||||
|
dut.serial.proc.setDTR(False)
|
||||||
|
time.sleep(0.25)
|
||||||
|
|
||||||
|
nvs_value = None
|
||||||
|
|
||||||
|
for _ in range(5):
|
||||||
|
generate_gpio0_events()
|
||||||
|
dut.expect_exact('ULP wakeup, saving pulse count', timeout=5)
|
||||||
|
logging.info('Woke up...')
|
||||||
|
init_count = int(dut.expect(r'Read pulse count from NVS:\s+(\d+)', timeout=5).group(1), 10)
|
||||||
|
assert nvs_value in (init_count, None), ('Read count is {} and previously written value is {}'
|
||||||
|
''.format(init_count, nvs_value))
|
||||||
|
|
||||||
|
inc = int(dut.expect(r'Pulse count from ULP:\s+(\d+)', timeout=5).group(1), 10)
|
||||||
|
assert inc in (5, 6), 'pulse count is {}'.format(inc)
|
||||||
|
|
||||||
|
new_count = int(dut.expect(r'Wrote updated pulse count to NVS:\s+(\d+)', timeout=5).group(1), 10)
|
||||||
|
assert init_count + inc == new_count, '{} + {} != {}'.format(init_count, inc, new_count)
|
||||||
|
|
||||||
|
nvs_value = new_count
|
||||||
|
logging.info('Pulse count written to NVS: {}. Entering deep sleep...'.format(nvs_value))
|
||||||
|
dut.expect_exact('Entering deep sleep', timeout=5)
|
@ -1,34 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
import ttfw_idf
|
|
||||||
from tiny_test_fw import Utility
|
|
||||||
|
|
||||||
|
|
||||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32'])
|
|
||||||
def test_examples_ulp_adc(env, extra_data):
|
|
||||||
|
|
||||||
dut = env.get_dut('ulp_adc', 'examples/system/ulp_fsm/ulp_adc')
|
|
||||||
dut.start_app()
|
|
||||||
|
|
||||||
dut.expect_all('Not ULP wakeup',
|
|
||||||
'Entering deep sleep',
|
|
||||||
timeout=30)
|
|
||||||
|
|
||||||
for _ in range(5):
|
|
||||||
dut.expect('Deep sleep wakeup', timeout=60)
|
|
||||||
measurements_str = dut.expect(re.compile(r'ULP did (\d+) measurements'), timeout=5)[0]
|
|
||||||
assert measurements_str is not None
|
|
||||||
measurements = int(measurements_str)
|
|
||||||
Utility.console_log('ULP did {} measurements'.format(measurements))
|
|
||||||
dut.expect('Thresholds: low=1500 high=2000', timeout=5)
|
|
||||||
value_str = dut.expect(re.compile(r'Value=(\d+) was (above|below) threshold'), timeout=5)[0]
|
|
||||||
assert value_str is not None
|
|
||||||
value = int(value_str)
|
|
||||||
Utility.console_log('Value {} was outside the boundaries'.format(value))
|
|
||||||
dut.expect('Entering deep sleep', timeout=60)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_examples_ulp_adc()
|
|
28
examples/system/ulp_fsm/ulp_adc/pytest_ulp_fsm_adc.py
Normal file
28
examples/system/ulp_fsm/ulp_adc/pytest_ulp_fsm_adc.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.esp32
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_ulp_fsm_adc(dut: Dut) -> None:
|
||||||
|
|
||||||
|
dut.expect_exact('Not ULP wakeup')
|
||||||
|
dut.expect_exact('Entering deep sleep')
|
||||||
|
|
||||||
|
for _ in range(5):
|
||||||
|
dut.expect_exact('Deep sleep wakeup', timeout=60)
|
||||||
|
measurements_str = dut.expect(r'ULP did (\d+) measurements', timeout=5).group(1)
|
||||||
|
assert measurements_str is not None
|
||||||
|
measurements = int(measurements_str)
|
||||||
|
logging.info('ULP did {} measurements'.format(measurements))
|
||||||
|
dut.expect_exact('Thresholds: low=1500 high=2000', timeout=5)
|
||||||
|
value_str = dut.expect(r'Value=(\d+) was (above|below) threshold', timeout=5).group(1)
|
||||||
|
assert value_str is not None
|
||||||
|
value = int(value_str)
|
||||||
|
logging.info('Value {} was outside the boundaries'.format(value))
|
||||||
|
dut.expect_exact('Entering deep sleep', timeout=60)
|
@ -1,44 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
import tiny_test_fw
|
|
||||||
import ttfw_idf
|
|
||||||
from tiny_test_fw import DUT
|
|
||||||
|
|
||||||
|
|
||||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32s2'])
|
|
||||||
def test_examples_ulp_riscv(env, extra_data): # type: (tiny_test_fw.Env.Env, None) -> None # pylint: disable=unused-argument
|
|
||||||
dut = env.get_dut('ulp_riscv', 'examples/system/ulp_riscv/gpio')
|
|
||||||
dut.start_app()
|
|
||||||
|
|
||||||
dut.expect_all('Not a ULP-RISC-V wakeup, initializing it!',
|
|
||||||
'Entering in deep sleep',
|
|
||||||
timeout=30)
|
|
||||||
|
|
||||||
# Run two times to make sure device sleep
|
|
||||||
# and wake up properly
|
|
||||||
for i in range(0, 2):
|
|
||||||
# Set GPIO0 using DTR
|
|
||||||
dut.port_inst.setDTR(i % 2 == 0)
|
|
||||||
|
|
||||||
dut.expect('ULP-RISC-V woke up the main CPU!', timeout=5)
|
|
||||||
|
|
||||||
# Check GPIO state
|
|
||||||
state = 'Low' if i % 2 == 0 else 'High'
|
|
||||||
dut.expect(re.compile(r'ULP-RISC-V read changes in GPIO_0 current is: %s' % state), timeout=5)
|
|
||||||
|
|
||||||
# Go back to sleep
|
|
||||||
dut.expect('Entering in deep sleep', timeout=5)
|
|
||||||
|
|
||||||
try:
|
|
||||||
# We expect a timeout here, otherwise it means that
|
|
||||||
# the main CPU woke up unexpectedly!
|
|
||||||
dut.expect('ULP-RISC-V woke up the main CPU!', timeout=20)
|
|
||||||
raise Exception('Main CPU woke up unexpectedly!')
|
|
||||||
except DUT.ExpectTimeout:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_examples_ulp_riscv()
|
|
37
examples/system/ulp_riscv/gpio/pytest_ulp_riscv_gpio.py
Normal file
37
examples/system/ulp_riscv/gpio/pytest_ulp_riscv_gpio.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
import pexpect
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.esp32s2
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_ulp_riscv_gpio(dut: Dut) -> None:
|
||||||
|
|
||||||
|
dut.expect_exact('Not a ULP-RISC-V wakeup, initializing it!')
|
||||||
|
dut.expect_exact('Entering in deep sleep')
|
||||||
|
|
||||||
|
# Run two times to make sure device sleep
|
||||||
|
# and wake up properly
|
||||||
|
for i in range(0, 2):
|
||||||
|
# Set GPIO0 using DTR
|
||||||
|
dut.serial.proc.setDTR(i % 2 == 0)
|
||||||
|
|
||||||
|
dut.expect_exact('ULP-RISC-V woke up the main CPU!', timeout=5)
|
||||||
|
|
||||||
|
# Check GPIO state
|
||||||
|
state = 'Low' if i % 2 == 0 else 'High'
|
||||||
|
dut.expect(r'ULP-RISC-V read changes in GPIO_0 current is: %s' % state, timeout=5)
|
||||||
|
|
||||||
|
# Go back to sleep
|
||||||
|
dut.expect_exact('Entering in deep sleep', timeout=5)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# We expect a timeout here, otherwise it means that
|
||||||
|
# the main CPU woke up unexpectedly!
|
||||||
|
dut.expect('ULP-RISC-V woke up the main CPU!', timeout=20)
|
||||||
|
raise Exception('Main CPU woke up unexpectedly!')
|
||||||
|
except pexpect.exceptions.TIMEOUT:
|
||||||
|
pass
|
@ -1,26 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
import ttfw_idf
|
|
||||||
|
|
||||||
|
|
||||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32c3'])
|
|
||||||
def test_examples_unit_test(env, extra_data):
|
|
||||||
|
|
||||||
dut = env.get_dut('unit_test', 'examples/system/unit_test')
|
|
||||||
dut.start_app()
|
|
||||||
|
|
||||||
def get_reg_nums(number):
|
|
||||||
return re.compile(r'\d{1,2}\s+' * number)
|
|
||||||
|
|
||||||
dut.expect_all('In main application. Collecting 32 random numbers from 1 to 100:',
|
|
||||||
get_reg_nums(10),
|
|
||||||
get_reg_nums(10),
|
|
||||||
get_reg_nums(10),
|
|
||||||
get_reg_nums(2),
|
|
||||||
timeout=30)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_examples_unit_test()
|
|
19
examples/system/unit_test/pytest_unittest.py
Normal file
19
examples/system/unit_test/pytest_unittest.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.supported_targets
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_unit_test(dut: Dut) -> None:
|
||||||
|
|
||||||
|
def get_reg_nums(number: int) -> str:
|
||||||
|
return r'\d{1,2}\s+' * number
|
||||||
|
|
||||||
|
dut.expect_exact('In main application. Collecting 32 random numbers from 1 to 100:')
|
||||||
|
dut.expect(get_reg_nums(10))
|
||||||
|
dut.expect(get_reg_nums(10))
|
||||||
|
dut.expect(get_reg_nums(10))
|
||||||
|
dut.expect(get_reg_nums(2))
|
Loading…
Reference in New Issue
Block a user