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) idf_path = dut.app.get_sdk_path() proj_path = os.path.join(idf_path, rel_project_path) elf_path = os.path.join(dut.app.get_binary_path(rel_project_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.OCDProcess(os.path.join(proj_path, 'openocd.log')): 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_args = '-x {} --directory={}'.format( tempfiles[0], os.path.join(proj_path, 'main')) with ttfw_idf.GDBProcess(os.path.join(proj_path, 'gdb.log'), elf_path, dut.app.target, gdb_args) as gdb: gdb.pexpect_proc.expect_exact( 'Thread 1 hit Breakpoint 1, app_main ()') gdb.pexpect_proc.expect_exact('Targets connected.') gdb.pexpect_proc.expect(re.compile(r'\d+')) dut.expect( 'example: Created task' ) # dut has been restarted by gdb since the last dut.expect() dut_expect_task_event() gdb.pexpect_proc.sendcontrol('c') gdb.pexpect_proc.expect_exact('(gdb)') 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.OCDProcess(os.path.join(proj_path, 'openocd.log')): with ttfw_idf.TelnetProcess(os.path.join(proj_path, 'telnet.log')) as telnet_p: 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) telnet_p.pexpect_proc.sendline( 'esp apptrace start file://adc.log 0 9000 5 0 0') telnet_p.pexpect_proc.expect_exact( 'App trace params: from 2 cores, size 9000 bytes, ' 'stop_tmo 5 s, poll period 0 ms, wait_rst 0, skip 0 bytes') telnet_p.pexpect_proc.expect_exact('Targets connected.') telnet_p.pexpect_proc.expect_exact('Targets disconnected.') telnet_p.pexpect_proc.expect_exact( 'Tracing is STOPPED. Size is 9000 of 9000 @') telnet_p.pexpect_proc.expect_exact( 'Data: blocks incomplete 0, lost bytes: 0') 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_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'] example = ttfw_idf.LoadableElfTestApp(rel_project_path, app_files, target="esp32") idf_path = example.get_sdk_path() proj_path = os.path.join(idf_path, rel_project_path) elf_path = os.path.join(example.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_args = '-x {} --directory={}'.format( os.path.join(proj_path, '.gdbinit.ci'), os.path.join(proj_path, 'main')) with ttfw_idf.OCDProcess(openocd_log), ttfw_idf.GDBProcess( gdb_log, elf_path, gdb_args) as gdb: gdb.pexpect_proc.sendline( '' ) # it is for "---Type <return> to continue, or q <return> to quit---" i = gdb.pexpect_proc.expect_exact([ 'Thread 1 hit Temporary breakpoint 2, app_main ()', 'Load failed' ]) if i == 0: Utility.console_log('gdb is at breakpoint') elif i == 1: raise RuntimeError('Load has failed. Please examine the logs.') else: Utility.console_log('i = {}'.format(i)) Utility.console_log(str(gdb.pexpect_proc)) # This really should not happen. TIMEOUT and EOF failures are exceptions. raise RuntimeError( 'An unknown error has occurred. Please examine the logs.') gdb.pexpect_proc.expect_exact('(gdb)') gdb.pexpect_proc.sendline('b esp_restart') gdb.pexpect_proc.sendline('c') gdb.pexpect_proc.expect_exact( 'Thread 1 hit Breakpoint 3, esp_restart ()') 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_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)) openocd_extra_args = '-c \'set ESP_SEMIHOST_BASEDIR {}\''.format( temp_dir) with ttfw_idf.OCDProcess(os.path.join(proj_path, 'openocd.log'), openocd_extra_args): 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_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) with ttfw_idf.OCDProcess(os.path.join(proj_path, 'openocd.log')): with ttfw_idf.TelnetProcess(os.path.join(proj_path, 'telnet.log')) as telnet_p: 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: telnet_p.pexpect_proc.sendline(cmd) telnet_p.pexpect_proc.expect_exact('Targets connected.') telnet_p.pexpect_proc.expect_exact('gcov_example_main.c.gcda') telnet_p.pexpect_proc.expect_exact('gcov_example_func.c.gcda') telnet_p.pexpect_proc.expect_exact('some_funcs.c.gcda') telnet_p.pexpect_proc.expect_exact('Targets disconnected.') except TIMEOUT: # 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 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_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) idf_path = dut.app.get_sdk_path() proj_path = os.path.join(idf_path, rel_project_path) elf_path = os.path.join(dut.app.get_binary_path(rel_project_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.OCDProcess(os.path.join(proj_path, 'openocd.log')): dut.start_app() dut.expect('esp_apptrace: Initialized TRAX on CPU0') gdb_args = '-x {} --directory={}'.format(tempfiles[0], os.path.join(proj_path, 'main')) with ttfw_idf.GDBProcess(os.path.join(proj_path, 'gdb.log'), elf_path, dut.app.target, gdb_args) as gdb: gdb.pexpect_proc.expect_exact('Thread 1 hit Temporary breakpoint 2, heap_trace_stop ()') gdb.pexpect_proc.expect_exact('(gdb)') # 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(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) oocd_log_path = os.path.join(proj_path, 'openocd.log') with ttfw_idf.OCDProcess(oocd_log_path): with ttfw_idf.TelnetProcess(os.path.join(proj_path, 'telnet.log')) as telnet_p: 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) telnet_p.pexpect_proc.sendline( 'esp apptrace start file://adc.log 0 9000 5 0 0') telnet_p.pexpect_proc.expect_exact( 'App trace params: from 2 cores, size 9000 bytes, ' 'stop_tmo 5 s, poll period 0 ms, wait_rst 0, skip 0 bytes') telnet_p.pexpect_proc.expect_exact('Targets connected.') telnet_p.pexpect_proc.expect_exact('Targets disconnected.') telnet_p.pexpect_proc.expect_exact( 'Tracing is STOPPED. Size is 9000 of 9000 @') telnet_p.pexpect_proc.expect_exact( 'Data: blocks incomplete 0, lost bytes: 0') 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.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+'))