Example #1
0
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+'))
Example #2
0
def test_monitor_ide_integration(env, extra_data):
    config_files = glob.glob(os.path.join(os.path.dirname(__file__), 'sdkconfig.ci.*'))
    config_names = [os.path.basename(s).replace('sdkconfig.ci.', '') for s in config_files]
    rel_proj_path = 'tools/test_apps/system/monitor_ide_integration'
    for name in config_names:
        Utility.console_log('Checking config "{}"... '.format(name), 'green', end='')
        dut = env.get_dut('panic', rel_proj_path, app_config_name=name)
        monitor_path = os.path.join(dut.app.idf_path, 'tools/idf_monitor.py')
        elf_path = os.path.join(dut.app.binary_path, 'panic.elf')
        dut.start_app()
        # Closing the DUT because we will reconnect with IDF Monitor
        env.close_dut(dut.name)

        with WebSocketServer(), ttfw_idf.CustomProcess(' '.join([monitor_path,
                                                                 elf_path,
                                                                 '--ws', 'ws://{}:{}'.format(WebSocketServer.HOST,
                                                                                             WebSocketServer.PORT)]),
                                                       logfile='monitor_{}.log'.format(name)) as p:
            p.pexpect_proc.expect(re.compile(r'Guru Meditation Error'), timeout=10)
            p.pexpect_proc.expect_exact('Communicating through WebSocket', timeout=5)
            # "u?" is for Python 2 only in the following regular expressions.
            # The elements of dictionary can be printed in different order depending on the Python version.
            p.pexpect_proc.expect(re.compile(r"WebSocket sent: \{u?.*'event': u?'" + name + "'"), timeout=5)
            p.pexpect_proc.expect_exact('Waiting for debug finished event', timeout=5)
            p.pexpect_proc.expect(re.compile(r"WebSocket received: \{u?'event': u?'debug_finished'\}"), timeout=5)
            p.pexpect_proc.expect_exact('Communications through WebSocket is finished', timeout=5)
Example #3
0
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+'))
Example #4
0
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_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
Example #6
0
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
Example #7
0
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_pppos_client(env, extra_data):

    rel_project_path = 'examples/protocols/pppos_client'
    dut = env.get_dut('pppos_client', rel_project_path)
    project_path = os.path.join(dut.app.get_sdk_path(), rel_project_path)

    modem_port = '/dev/ttyUSB{}'.format(0 if dut.port.endswith('1') else 1)

    with SerialThread(modem_port, os.path.join(project_path, 'serial.log')):
        dut.start_app()

        dut.expect_all('pppos_example: Module: 0G Dummy Model',
                       'pppos_example: Operator: "ESP Network"',
                       'pppos_example: IMEI: 0123456789',
                       'pppos_example: IMSI: ESP',
                       'pppos_example: rssi: 4, ber: 0',
                       'pppos_example: Battery voltage: 0 mV',
                       'pppos_example: Modem PPP Started',
                       timeout=60)

    cmd = (
        'pppd {} 115200 10.0.0.1:10.0.0.2 logfile {} local noauth debug nocrtscts nodetach +ipv6'
        ''.format(modem_port, os.path.join(project_path, 'ppp.log')))
    with ttfw_idf.CustomProcess(cmd, '/dev/null'):  # Nothing is printed here
        dut.expect_all(
            'pppos_example: Modem Connect to PPP Server',
            'pppos_example: IP          : 10.0.0.2',
            'pppos_example: Netmask     : 255.255.255.255',
            'pppos_example: Gateway     : 10.0.0.1',
            'pppos_example: Name Server1: 0.0.0.0',
            'pppos_example: Name Server2: 0.0.0.0',
            'pppos_example: GOT ip event!!!',
            'pppos_example: MQTT other event id: 7',
            # There are no fake DNS server and MQTT server set up so the example fails at this point
            'TRANS_TCP: DNS lookup failed err=202 res=0x0',
            'MQTT_CLIENT: Error transport connect',
            'pppos_example: MQTT_EVENT_ERROR',
            'pppos_example: MQTT_EVENT_DISCONNECTED')
def test_examples_esp_local_ctrl(env, extra_data):

    rel_project_path = os.path.join('examples', 'protocols', 'esp_local_ctrl')
    dut = env.get_dut('esp_local_ctrl', rel_project_path)
    idf_path = dut.app.get_sdk_path()
    dut.start_app()

    dut_ip = dut.expect(
        re.compile(
            r'esp_netif_handlers: sta ip: (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'
        ))[0]
    dut.expect('esp_https_server: Starting server')
    dut.expect('esp_https_server: Server listening on port 443')
    dut.expect(
        'control: esp_local_ctrl service started with name : my_esp_ctrl_device'
    )

    def dut_expect_read():
        dut.expect('control: Reading property : timestamp (us)')
        dut.expect('control: Reading property : property1')
        dut.expect('control: Reading property : property2')
        dut.expect('control: Reading property : property3')

    # Running mDNS services in docker is not a trivial task. Therefore, the script won't connect to the host name but
    # to IP address. However, the certificates were generated for the host name and will be rejected.
    cmd = ' '.join([
        sys.executable,
        os.path.join(idf_path, rel_project_path, 'scripts/esp_local_ctrl.py'),
        '--name', dut_ip, '--dont-check-hostname'
    ])  # don't reject the certificate because of the hostname
    esp_local_ctrl_log = os.path.join(idf_path, rel_project_path,
                                      'esp_local_ctrl.log')
    with ttfw_idf.CustomProcess(cmd, esp_local_ctrl_log) as ctrl_py:

        def expect_properties(prop1, prop3):
            dut_expect_read()
            ctrl_py.pexpect_proc.expect_exact('==== Available Properties ====')
            ctrl_py.pexpect_proc.expect(
                re.compile(r'S.N. Name\s+Type\s+Flags\s+Value'))
            ctrl_py.pexpect_proc.expect(
                re.compile(
                    r'\[ 1\] timestamp \(us\)\s+TIME\(us\)\s+Read-Only\s+\d+'))
            ctrl_py.pexpect_proc.expect(
                re.compile(r'\[ 2\] property1\s+INT32\s+{}'.format(prop1)))
            ctrl_py.pexpect_proc.expect(
                re.compile(
                    r'\[ 3\] property2\s+BOOLEAN\s+Read-Only\s+(True)|(False)')
            )
            ctrl_py.pexpect_proc.expect(
                re.compile(r'\[ 4\] property3\s+STRING\s+{}'.format(prop3)))
            ctrl_py.pexpect_proc.expect_exact(
                'Select properties to set (0 to re-read, \'q\' to quit) :')

        property1 = 123456789
        property3 = ''

        ctrl_py.pexpect_proc.expect_exact('Connecting to {}'.format(dut_ip))
        dut.expect('esp_https_server: performing session handshake',
                   timeout=60)
        expect_properties(property1, property3)

        ctrl_py.pexpect_proc.sendline('1')
        ctrl_py.pexpect_proc.expect_exact(
            'Enter value to set for property (timestamp (us)) :')
        ctrl_py.pexpect_proc.sendline('2')
        ctrl_py.pexpect_proc.expect_exact('Failed to set values!')
        dut.expect('control: timestamp (us) is read-only')
        expect_properties(property1, property3)

        property1 = 638
        ctrl_py.pexpect_proc.sendline('2')
        ctrl_py.pexpect_proc.expect_exact(
            'Enter value to set for property (property1) :')
        ctrl_py.pexpect_proc.sendline(str(property1))
        dut.expect('control: Setting property1 value to {}'.format(property1))
        expect_properties(property1, property3)

        property3 = 'test'
        ctrl_py.pexpect_proc.sendline('4')
        ctrl_py.pexpect_proc.expect_exact(
            'Enter value to set for property (property3) :')
        ctrl_py.pexpect_proc.sendline(property3)
        dut.expect('control: Setting property3 value to {}'.format(property3))
        expect_properties(property1, property3)

        ctrl_py.pexpect_proc.sendline('q')
        ctrl_py.pexpect_proc.expect_exact('Quitting...')
Example #10
0
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+'))