def test_app_loadable_elf(env, extra_data): rel_project_path = os.path.join('tools', 'test_apps', 'system', 'gdb_loadable_elf') app_files = ['gdb_loadable_elf.elf'] target = 'esp32' app = ttfw_idf.LoadableElfTestApp(rel_project_path, app_files, target=target) idf_path = app.get_sdk_path() proj_path = os.path.join(idf_path, rel_project_path) elf_path = os.path.join(app.binary_path, 'gdb_loadable_elf.elf') esp_log_path = os.path.join(proj_path, 'esp.log') with SerialThread(esp_log_path): openocd_log = os.path.join(proj_path, 'openocd.log') gdb_log = os.path.join(proj_path, 'gdb.log') gdb_init = os.path.join(proj_path, 'gdbinit_' + target) gdb_dir = os.path.join(proj_path, 'main') with ttfw_idf.OCDBackend(openocd_log, app.target): with ttfw_idf.GDBBackend(gdb_log, elf_path, app.target, gdb_init, gdb_dir) as p: def wait_for_breakpoint(): p.gdb.wait_target_state(debug_backend.TARGET_STATE_RUNNING) stop_reason = p.gdb.wait_target_state(debug_backend.TARGET_STATE_STOPPED) assert stop_reason == debug_backend.TARGET_STOP_REASON_BP, 'STOP reason: {}'.format(stop_reason) wait_for_breakpoint() p.gdb.add_bp('esp_restart') p.gdb.exec_continue() wait_for_breakpoint() if pexpect.run('grep "Restarting now." {}'.format(esp_log_path), withexitstatus=True)[1]: raise RuntimeError('Expected output from ESP was not received')
def test_examples_app_trace_to_host(env, extra_data): rel_project_path = os.path.join('examples', 'system', 'app_trace_to_host') dut = env.get_dut('app_trace_to_host', rel_project_path) idf_path = dut.app.get_sdk_path() proj_path = os.path.join(idf_path, rel_project_path) with ttfw_idf.OCDBackend(os.path.join(proj_path, 'openocd.log'), dut.app.target) as ocd: dut.start_app() dut.expect_all('example: Enabling ADC1 on channel 6 / GPIO34.', 'example: Enabling CW generator on DAC channel 1', 'example: Sampling ADC and sending data to the host...', re.compile(r'example: Collected \d+ samples in 20 ms.'), 'example: Sampling ADC and sending data to the UART...', re.compile(r'example: Sample:\d, Value:\d+'), re.compile(r'example: Collected \d+ samples in 20 ms.'), timeout=20) ocd.apptrace_start("file://adc.log 0 9000 5 0 0") ocd.apptrace_wait_stop(tmo=30) with ttfw_idf.CustomProcess(' '.join([os.path.join(idf_path, 'tools/esp_app_trace/logtrace_proc.py'), 'adc.log', os.path.join(dut.app.get_binary_path(rel_project_path), 'app_trace_to_host.elf')]), logfile='logtrace_proc.log') as logtrace: logtrace.pexpect_proc.expect_exact('Parse trace file') logtrace.pexpect_proc.expect_exact('Parsing completed.') logtrace.pexpect_proc.expect_exact('====================================================================') logtrace.pexpect_proc.expect(re.compile(r'example: Sample:\d+, Value:\d+')) logtrace.pexpect_proc.expect_exact('====================================================================') logtrace.pexpect_proc.expect(re.compile(r'Log records count: \d+'))
def test_examples_gcov(env, extra_data): rel_project_path = os.path.join('examples', 'system', 'gcov') dut = env.get_dut('gcov', rel_project_path) idf_path = dut.app.get_sdk_path() proj_path = os.path.join(idf_path, rel_project_path) openocd_cmd_log = os.path.join(proj_path, 'openocd_cmd.log') with ttfw_idf.OCDBackend(os.path.join(proj_path, 'openocd.log'), dut.app.target) as oocd: dut.start_app() def expect_counter_output(loop, timeout=10): dut.expect_all('blink_dummy_func: Counter = {}'.format(loop), 'some_dummy_func: Counter = {}'.format(loop * 2), timeout=timeout) expect_counter_output(0, timeout=20) dut.expect('Ready to dump GCOV data...', timeout=5) def dump_coverage(cmd): try: response = oocd.cmd_exec(cmd) with open(openocd_cmd_log, 'a') as f: f.write(response) assert all(x in response for x in [ 'Targets connected.', 'gcov_example_main.c.gcda', 'gcov_example_func.c.gcda', 'some_funcs.c.gcda', 'Targets disconnected.', ]) except AssertionError: # Print what is happening with DUT. Limit the size if it is in loop and generating output. Utility.console_log(dut.read(size=1000)) raise # Test two hard-coded dumps dump_coverage('esp gcov dump') dut.expect('GCOV data have been dumped.', timeout=5) expect_counter_output(1) dut.expect('Ready to dump GCOV data...', timeout=5) dump_coverage('esp gcov dump') dut.expect('GCOV data have been dumped.', timeout=5) for i in range(2, 6): expect_counter_output(i) for _ in range(3): time.sleep(1) # Test instant run-time dump dump_coverage('esp gcov')
def test_examples_app_trace_to_host(env, extra_data): rel_project_path = os.path.join('examples', 'system', 'app_trace_to_host') dut = env.get_dut('app_trace_to_host', rel_project_path) idf_path = dut.app.get_sdk_path() proj_path = os.path.join(idf_path, rel_project_path) oocd_log_path = os.path.join(proj_path, 'openocd.log') with ttfw_idf.OCDBackend(oocd_log_path, dut.app.target) as ocd: dut.start_app() dut.expect_all('example: Enabling ADC1 on channel 6 / GPIO34.', 'example: Enabling CW generator on DAC channel 1', 'example: Sampling ADC and sending data to the host...', re.compile(r'example: Collected \d+ samples in 20 ms.'), 'example: Sampling ADC and sending data to the UART...', re.compile(r'example: Sample:\d, Value:\d+'), re.compile(r'example: Collected \d+ samples in 20 ms.'), timeout=20) ocd.apptrace_start('file://adc.log 0 9000 5 0 0') ocd.apptrace_wait_stop(tmo=30) with open(oocd_log_path) as oocd_log: cores = 1 if dut.app.get_sdkconfig().get( 'CONFIG_FREERTOS_UNICORE', '').replace('"', '') == 'y' else 2 params_str = 'App trace params: from {} cores'.format(cores) for line in oocd_log: if params_str in line: break else: raise RuntimeError('"{}" could not be found in {}'.format( params_str, oocd_log_path)) with ttfw_idf.CustomProcess(' '.join([ os.path.join(idf_path, 'tools/esp_app_trace/logtrace_proc.py'), 'adc.log', os.path.join(dut.app.binary_path, 'app_trace_to_host.elf') ]), logfile='logtrace_proc.log') as logtrace: logtrace.pexpect_proc.expect_exact('Parse trace file') logtrace.pexpect_proc.expect_exact('Parsing completed.') logtrace.pexpect_proc.expect_exact( '====================================================================' ) logtrace.pexpect_proc.expect( re.compile(r'example: Sample:\d+, Value:\d+')) logtrace.pexpect_proc.expect_exact( '====================================================================' ) logtrace.pexpect_proc.expect(re.compile(r'Log records count: \d+'))
def test_examples_semihost_vfs(env, extra_data): rel_project_path = os.path.join('examples', 'storage', 'semihost_vfs') dut = env.get_dut('semihost_vfs', rel_project_path) idf_path = dut.app.get_sdk_path() proj_path = os.path.join(idf_path, rel_project_path) host_file_name = 'host_file.txt' try: temp_dir = tempfile.mkdtemp() host_file_path = os.path.join(proj_path, 'data', host_file_name) shutil.copyfile(host_file_path, os.path.join(temp_dir, host_file_name)) cfg_cmds = ['set ESP_SEMIHOST_BASEDIR "{}"'.format(temp_dir)] with ttfw_idf.OCDBackend(os.path.join(proj_path, 'openocd.log'), dut.app.target, cfg_cmds=cfg_cmds): dut.start_app() dut.expect_all( 'example: Switch to semihosted stdout', 'example: Switched back to UART stdout', 'example: Wrote 2798 bytes', '====================== HOST DATA START =========================', timeout=20) with open(host_file_path) as f: file_content = [line.strip() for line in f] dut.expect_all(*file_content, timeout=20) dut.expect_all( '====================== HOST DATA END =========================', 'example: Read 6121 bytes', timeout=5) with open(os.path.join(temp_dir, 'esp32_stdout.txt')) as f: def expected_content(): yield 'example: Switched to semihosted stdout' for i in range(100): yield 'Semihosted stdout write {}'.format(i) yield 'example: Switch to UART stdout' for actual, expected in zip_longest(f, expected_content(), fillvalue='-'): if expected not in actual: # "in" used because of the printed ASCII color codes raise RuntimeError('"{}" != "{}"'.format( expected, actual.strip())) finally: shutil.rmtree(temp_dir, ignore_errors=True)
def test_examples_sysview_tracing_heap_log(env, extra_data): rel_project_path = os.path.join('examples', 'system', 'sysview_tracing_heap_log') dut = env.get_dut('sysview_tracing_heap_log', rel_project_path) proj_path = os.path.join(dut.app.idf_path, rel_project_path) elf_path = os.path.join(dut.app.binary_path, 'sysview_tracing_heap_log.elf') def get_temp_file(): with tempfile.NamedTemporaryFile(delete=False) as f: return f.name try: tempfiles = [get_temp_file(), get_temp_file()] with open(os.path.join(proj_path, 'gdbinit')) as f_in, open(tempfiles[0], 'w') as f_out: new_content = f_in.read() # localhost connection issue occurs in docker unless: new_content = new_content.replace(':3333', '127.0.0.1:3333', 1) new_content = new_content.replace('file:///tmp/heap_log.svdat', 'file://{}'.format(tempfiles[1]), 1) f_out.write(new_content) with ttfw_idf.OCDBackend(os.path.join(proj_path, 'openocd.log'), dut.app.target): dut.start_app() dut.expect('esp_apptrace: Initialized TRAX on CPU0') gdb_log = os.path.join(proj_path, 'gdb.log') gdb_workdir = os.path.join(proj_path, 'main') with ttfw_idf.GDBBackend(gdb_log, elf_path, dut.app.target, tempfiles[0], gdb_workdir) as p: for _ in range(2): # There are two breakpoints p.gdb.wait_target_state(debug_backend.TARGET_STATE_RUNNING) stop_reason = p.gdb.wait_target_state(debug_backend.TARGET_STATE_STOPPED) assert stop_reason == debug_backend.TARGET_STOP_REASON_BP, 'STOP reason: {}'.format(stop_reason) # dut has been restarted by gdb since the last dut.expect() dut.expect('esp_apptrace: Initialized TRAX on CPU0') with ttfw_idf.CustomProcess(' '.join([os.path.join(dut.app.idf_path, 'tools/esp_app_trace/sysviewtrace_proc.py'), '-p', '-b', elf_path, tempfiles[1]]), logfile='sysviewtrace_proc.log') as sysviewtrace: sysviewtrace.pexpect_proc.expect(re.compile(r'Found \d+ leaked bytes in \d+ blocks.'), timeout=120) finally: for x in tempfiles: try: os.unlink(x) except Exception: pass
def test_examples_app_trace_to_host(env, extra_data): rel_project_path = os.path.join('examples', 'system', 'app_trace_to_host') dut = env.get_dut('app_trace_to_host', rel_project_path) idf_path = dut.app.get_sdk_path() proj_path = os.path.join(idf_path, rel_project_path) with ttfw_idf.OCDBackend(os.path.join(proj_path, 'openocd.log'), dut.app.target) as ocd: dut.start_app() dut.expect_all( 'example: Enabling ADC1 on channel 6 / GPIO34.', 'example: Enabling CW generator on DAC channel 1', 'example: Custom divider of RTC 8 MHz clock has been set.', 'example: Sampling ADC and sending data to the host...', re.compile(r'example: Collected \d+ samples in 20 ms.'), 'example: Sampling ADC and sending data to the UART...', re.compile(r'example: Sample:\d, Value:\d+'), re.compile(r'example: Collected \d+ samples in 20 ms.'), timeout=20) response = ocd.cmd_exec( 'esp apptrace start file://adc.log 0 9000 5 0 0') with open(os.path.join(proj_path, 'telnet.log'), 'w') as f: f.write(response) assert ('Data: blocks incomplete 0, lost bytes: 0' in response) with ttfw_idf.CustomProcess(' '.join([ os.path.join(idf_path, 'tools/esp_app_trace/logtrace_proc.py'), 'adc.log', os.path.join(dut.app.get_binary_path(rel_project_path), 'app_trace_to_host.elf') ]), logfile='logtrace_proc.log') as logtrace: logtrace.pexpect_proc.expect_exact('Parse trace file') logtrace.pexpect_proc.expect_exact('Parsing completed.') logtrace.pexpect_proc.expect_exact( '====================================================================' ) logtrace.pexpect_proc.expect( re.compile(r'example: Sample:\d+, Value:\d+')) logtrace.pexpect_proc.expect_exact( '====================================================================' ) logtrace.pexpect_proc.expect(re.compile(r'Log records count: \d+'))
def test_examples_sysview_tracing(env, extra_data): rel_project_path = os.path.join('examples', 'system', 'sysview_tracing') dut = env.get_dut('sysview_tracing', rel_project_path) proj_path = os.path.join(dut.app.idf_path, rel_project_path) elf_path = os.path.join(dut.app.binary_path, 'sysview_tracing.elf') def get_temp_file(): with tempfile.NamedTemporaryFile(delete=False) as f: return f.name try: tempfiles = [get_temp_file(), get_temp_file()] with open(os.path.join(proj_path, 'gdbinit')) as f_in, open(tempfiles[0], 'w') as f_out: new_content = f_in.read() # localhost connection issue occurs in docker unless: new_content = new_content.replace(':3333', '127.0.0.1:3333', 1) new_content = new_content.replace( 'file:///tmp/sysview_example.svdat', 'file://{}'.format(tempfiles[1]), 1) f_out.write(new_content) with ttfw_idf.OCDBackend(os.path.join(proj_path, 'openocd.log'), dut.app.target) as oocd: dut.start_app() def dut_expect_task_event(): dut.expect(re.compile( r'example: Task\[0x3[0-9A-Fa-f]+\]: received event \d+'), timeout=30) dut_expect_task_event() gdb_log = os.path.join(proj_path, 'gdb.log') gdb_workdir = os.path.join(proj_path, 'main') with ttfw_idf.GDBBackend(gdb_log, elf_path, dut.app.target, tempfiles[0], gdb_workdir) as p: p.gdb.wait_target_state(debug_backend.TARGET_STATE_RUNNING) stop_reason = p.gdb.wait_target_state( debug_backend.TARGET_STATE_STOPPED) assert stop_reason == debug_backend.TARGET_STOP_REASON_BP, 'STOP reason: {}'.format( stop_reason) dut.expect( 'example: Created task' ) # dut has been restarted by gdb since the last dut.expect() dut_expect_task_event() # Do a sleep while sysview samples are captured. time.sleep(3) # GDBMI isn't responding now to any commands, therefore, the following command is issued to openocd oocd.cmd_exec('esp sysview stop') finally: for x in tempfiles: try: os.unlink(x) except Exception: pass