Exemplo n.º 1
0
def main(connection_handle,
         connection_type,
         guard_time_seconds,
         inactivity_time_seconds,
         terminator,
         instance,
         printer,
         reporter,
         test_report_handle,
         send_string=None,
         keep_going_flag=None):
    '''Main as a function'''
    # Dictionary in which results are stored
    results = {
        "finished": False,
        "reboots": 0,
        "items_run": 0,
        "items_failed": 0,
        "items_ignored": 0,
        "overall_start_time": 0,
        "last_start_time": 0,
        "outcomes": []
    }
    results["last_start_time"] = time()
    return_value = -1

    if instance:
        prompt = PROMPT + "_" + u_utils.get_instance_text(instance) + ": "
    else:
        prompt = PROMPT + ": "

    # If we have a serial interface we have can chose which tests to run
    # (at least, on the ESP32 platform) else the lot will just run
    if (send_string is None or esp32_send_first(
            send_string, connection_handle, connection_type, printer, prompt)):
        results["overall_start_time"] = time()
        return_value = watch_items(connection_handle, connection_type, results,
                                   guard_time_seconds, inactivity_time_seconds,
                                   terminator, printer, reporter, prompt,
                                   keep_going_flag)

    # Write the report
    if test_report_handle and instance:
        printer.string("{}writing report file...".format(prompt))
        test_report_handle.write("<testsuite name=\"{}\" tests=\"{}\" failures=\"{}\">\n". \
                                 format("instance " + u_utils.get_instance_text(instance),
                                        results["items_run"],
                                        results["items_failed"]))
        for outcome in results["outcomes"]:
            test_report_handle.write("    <testcase classname=\"{}\" name=\"{}\" " \
                                     "time=\"{}\" status=\"{}\"></testcase>\n".    \
                                     format("ubxlib_tests", outcome[0], outcome[1],
                                            outcome[2]))
        test_report_handle.write("</testsuite>\n")

    printer.string("{}end with return value {}.".format(prompt, return_value))

    return return_value
Exemplo n.º 2
0
def lock(connection, connection_lock, guard_time_seconds, printer, prompt):
    '''Lock the given connection'''
    timeout_seconds = guard_time_seconds
    success = False

    if connection:
        instance_text = u_utils.get_instance_text(get_instance(connection))
        if connection_lock:
            # Wait on the lock
            printer.string("{}instance {} waiting up to {} second(s)"   \
                           " to lock connection...".                    \
                           format(prompt, instance_text, guard_time_seconds))
            count = 0
            while not connection_lock.acquire(False) and                \
                ((guard_time_seconds == 0) or (timeout_seconds > 0)):
                sleep(1)
                timeout_seconds -= 1
                count += 1
                if count == 30:
                    printer.string("{}instance {} still waiting {} second(s)"     \
                                   " for a connection lock (locker is"            \
                                   " currently {}).".                             \
                                   format(prompt, instance_text, timeout_seconds,
                                          connection_lock))
                    count = 0
            if (guard_time_seconds == 0) or (timeout_seconds > 0):
                success = True
                printer.string("{}instance {} has locked a connection ({}).". \
                               format(prompt, instance_text, connection_lock))
        else:
            success = True
            printer.string("{}note: instance {} lock is empty.".           \
                           format(prompt, instance_text))

    return success
Exemplo n.º 3
0
def unlock(connection, connection_lock, printer, prompt):
    '''Unlock the given connection'''

    if connection:
        instance_text = u_utils.get_instance_text(get_instance(connection))
        if connection_lock:
            connection_lock.release()
            printer.string("{}instance {} has unlocked a connection.".   \
                           format(prompt, instance_text))
Exemplo n.º 4
0
def lock(connection,
         connection_lock,
         guard_time_seconds,
         printer,
         prompt,
         keep_going_flag=None,
         hw_reset=True):
    '''Lock the given connection'''
    timeout_seconds = guard_time_seconds
    success = False

    if connection:
        instance_text = u_utils.get_instance_text(get_instance(connection))
        if connection_lock:
            # Wait on the lock
            printer.string("{}instance {} waiting up to {} second(s)"   \
                           " to lock connection...".                    \
                           format(prompt, instance_text, guard_time_seconds))
            count = 0
            while not connection_lock.acquire(False) and                 \
                ((guard_time_seconds == 0) or (timeout_seconds > 0)) and \
                u_utils.keep_going(keep_going_flag, printer, prompt):
                sleep(1)
                timeout_seconds -= 1
                count += 1
                if count == 30:
                    printer.string("{}instance {} still waiting {} second(s)"     \
                                   " for a connection lock (locker is"            \
                                   " currently {}).".                             \
                                   format(prompt, instance_text, timeout_seconds,
                                          connection_lock))
                    count = 0
            if (guard_time_seconds == 0) or (timeout_seconds > 0):
                printer.string("{}instance {} has locked a connection ({}).". \
                               format(prompt, instance_text, connection_lock))
                if hw_reset:
                    kmtronic = get_kmtronic(connection)
                    usb_cutter_id_str = get_usb_cutter_id_str(connection)
                    if kmtronic:
                        printer.string("{}using KMTronic to reset {}...". \
                                       format(prompt, instance_text))
                        u_utils.kmtronic_reset(kmtronic["ip_address"],
                                               kmtronic["hex_bitmap"], printer,
                                               prompt)
                    if usb_cutter_id_str:
                        printer.string("{}using USB cutter to reset {}...". \
                                       format(prompt, instance_text))
                        u_utils.usb_cutter_reset([usb_cutter_id_str], printer,
                                                 prompt)
                success = True
        else:
            success = True
            printer.string("{}note: instance {} lock is empty.".           \
                           format(prompt, instance_text))

    return success
Exemplo n.º 5
0
 def __init__(self, queue, instance, file_handle, printer):
     self._queue = queue
     self._instance = instance
     self._file_handle = file_handle
     self._printer = printer
     self._prompt = PROMPT
     if instance:
         self._prompt += "_" + u_utils.get_instance_text(instance) + ": "
     else:
         self._prompt += ": "
Exemplo n.º 6
0
 def _write_events(self, instance):
     '''Write the events for an instance to file'''
     remove_list = []
     for event in self._events:
         if event["instance"] == instance:
             remove_list.append(event)
             if self._file_handle:
                 string = strftime(u_utils.TIME_FORMAT, event["timestamp"]) +  \
                          " instance " + u_utils.get_instance_text(instance) + \
                          " " + event_as_string(event) + ".\n"
                 self._file_handle.write(string)
     if self._file_handle:
         self._file_handle.flush()
     # Remove the list items we've written
     for item in remove_list:
         self._events.remove(item)
Exemplo n.º 7
0
def run(instance, mcu, toolchain, connection, connection_lock, platform_lock,
        misc_locks, clean, defines, ubxlib_dir, working_dir, printer, reporter,
        test_report_handle):
    '''Build/run on nRF5'''
    return_value = -1
    hex_file_path = None
    instance_text = u_utils.get_instance_text(instance)
    swo_port = u_utils.JLINK_SWO_PORT
    downloaded = False

    # Don't need the platform lock
    del platform_lock

    prompt = PROMPT + instance_text + ": "

    # Print out what we've been told to do
    text = "running nRF5 for " + mcu + " under " + toolchain
    if connection and "debugger" in connection and connection["debugger"]:
        text += ", on JLink debugger serial number " + connection["debugger"]
    if clean:
        text += ", clean build"
    if defines:
        text += ", with #define(s)"
        for idx, define in enumerate(defines):
            if idx == 0:
                text += " \"" + define + "\""
            else:
                text += ", \"" + define + "\""
    if ubxlib_dir:
        text += ", ubxlib directory \"" + ubxlib_dir + "\""
    if working_dir:
        text += ", working directory \"" + working_dir + "\""
    printer.string("{}{}.".format(prompt, text))

    reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_START,
                   "nRF5SDK/" + toolchain)
    # Switch to the working directory
    with u_utils.ChangeDir(working_dir):
        # Check that everything we need is installed
        if check_installation(toolchain, TOOLS_LIST, printer, prompt):
            # Fetch Unity
            if u_utils.fetch_repo(u_utils.UNITY_URL, u_utils.UNITY_SUBDIR,
                                  None, printer, prompt):
                # Do the build
                build_start_time = time()
                if toolchain.lower() == "gcc":
                    build_subdir_gcc = BUILD_SUBDIR_PREFIX_GCC + instance_text.replace(
                        ".", "_")
                    hex_file_path = build_gcc(clean, build_subdir_gcc,
                                              ubxlib_dir, defines, printer,
                                              prompt, reporter)
                elif toolchain.lower() == "ses":
                    hex_file_path = build_ses(clean, ubxlib_dir, defines,
                                              printer, prompt, reporter)
                if hex_file_path:
                    # Build succeeded, need to lock a connection to do the download
                    reporter.event(
                        u_report.EVENT_TYPE_BUILD, u_report.EVENT_PASSED,
                        "build took {:.0f} second(s)".format(time() -
                                                             build_start_time))
                    # Do the download
                    # On nRF5 doing a download or starting RTT logging
                    # on more than one platform at a time seems to cause
                    # problems, even though it should be tied to the
                    # serial number of the given debugger on that board,
                    # so lock JLink for this.
                    jlink_lock = None
                    if "jlink_lock" in misc_locks:
                        jlink_lock = misc_locks["jlink_lock"]
                    with u_utils.Lock(jlink_lock, INSTALL_LOCK_WAIT_SECONDS,
                                      "JLink", printer,
                                      prompt) as locked_jlink:
                        if locked_jlink:
                            with u_connection.Lock(
                                    connection, connection_lock,
                                    CONNECTION_LOCK_GUARD_TIME_SECONDS,
                                    printer, prompt) as locked_connection:
                                if locked_connection:
                                    reporter.event(
                                        u_report.EVENT_TYPE_DOWNLOAD,
                                        u_report.EVENT_START)
                                    # I have seen the download fail on occasion
                                    # so give this two bites of the cherry
                                    retries = 2
                                    while not downloaded and (retries > 0):
                                        downloaded = download(
                                            connection,
                                            DOWNLOAD_GUARD_TIME_SECONDS,
                                            hex_file_path, printer, prompt)
                                        retries -= 1
                                        if not downloaded and (retries > 0):
                                            reporter.event(
                                                u_report.EVENT_TYPE_DOWNLOAD,
                                                u_report.EVENT_WARNING,
                                                "unable to download, will retry..."
                                            )
                                            sleep(5)
                                    if downloaded:
                                        reporter.event(
                                            u_report.EVENT_TYPE_DOWNLOAD,
                                            u_report.EVENT_COMPLETE)

                                        # Now the target can be reset
                                        u_utils.reset_nrf_target(
                                            connection, printer, prompt)
                                        reporter.event(
                                            u_report.EVENT_TYPE_TEST,
                                            u_report.EVENT_START)
                                        if connection and "swo_port" in connection:
                                            swo_port = connection["swo_port"]

                                        # With JLink started
                                        RUN_JLINK.append("-RTTTelnetPort")
                                        RUN_JLINK.append(str(swo_port))
                                        if connection and "debugger" in connection and \
                                           connection["debugger"]:
                                            RUN_JLINK.append("-USB")
                                            RUN_JLINK.append(
                                                connection["debugger"])
                                        with u_utils.ExeRun(RUN_JLINK,
                                                            printer,
                                                            prompt,
                                                            with_stdin=True
                                                            ) as process_jlink:
                                            # Open the Telnet port to JLink
                                            # to get the debug output
                                            telnet_handle = u_utils.open_telnet(
                                                swo_port, printer, prompt)
                                            if telnet_handle is not None:
                                                # Monitor progress
                                                return_value = u_monitor.    \
                                                               main(telnet_handle,
                                                                    u_monitor.CONNECTION_TELNET,
                                                                    RUN_GUARD_TIME_SECONDS,
                                                                    RUN_INACTIVITY_TIME_SECONDS,
                                                                    instance, printer, reporter,
                                                                    test_report_handle)
                                                telnet_handle.close()
                                            else:
                                                reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                                                               u_report.EVENT_FAILED,
                                                               "unable to open RTT port " +  \
                                                               str(swo_port))
                                            # JLink is VERY touchy as to how it exits,
                                            # need to send it "exit\n" over stdin
                                            # for it to exit cleanly
                                            process_jlink.stdin.write(
                                                "exit\n".encode())
                                            sleep(5)
                                        if return_value == 0:
                                            reporter.event(
                                                u_report.EVENT_TYPE_TEST,
                                                u_report.EVENT_COMPLETE)
                                        else:
                                            reporter.event(
                                                u_report.EVENT_TYPE_TEST,
                                                u_report.EVENT_FAILED)
                                    else:
                                        reporter.event(
                                            u_report.EVENT_TYPE_DOWNLOAD,
                                            u_report.EVENT_FAILED,
                                            "check debug log for details")
                                    # Wait for a short while before giving
                                    # the connection lock away to make sure
                                    # that everything really has shut down
                                    # in the debugger
                                    sleep(5)
                                else:
                                    reporter.event(
                                        u_report.EVENT_TYPE_INFRASTRUCTURE,
                                        u_report.EVENT_FAILED,
                                        "unable to lock a connection")
                        else:
                            reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                                           u_report.EVENT_FAILED,
                                           "unable to lock JLink")
                else:
                    return_value = 1
                    reporter.event(u_report.EVENT_TYPE_BUILD,
                                   u_report.EVENT_FAILED,
                                   "check debug log for details")
            else:
                reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                               u_report.EVENT_FAILED, "unable to fetch Unity")
        else:
            reporter.event(
                u_report.EVENT_TYPE_INFRASTRUCTURE, u_report.EVENT_FAILED,
                "there is a problem with the tools installation for nRF5 SDK")

    return return_value
Exemplo n.º 8
0
def run(instance,
        mcu,
        board,
        toolchain,
        connection,
        connection_lock,
        platform_lock,
        misc_locks,
        clean,
        defines,
        ubxlib_dir,
        working_dir,
        printer,
        reporter,
        test_report_handle,
        keep_going_flag=None,
        unity_dir=None):
    '''Build/run on Arduino'''
    return_value = -1
    monitor_dtr_rts_on = None
    installed = False
    sketch_paths = []
    build_paths = []
    return_values = []
    instance_text = u_utils.get_instance_text(instance)

    # None of the misc locks are required
    del misc_locks

    # Since we only currently support ESP-IDF we don't need
    # unity as ESP-IDF already has a copy built in
    del unity_dir

    prompt = PROMPT + instance_text + ": "

    toolchain = toolchain.lower()

    # Print out what we've been told to do and at the
    # same time check for the DTR/RTS off marker
    text = "running Arduino for " + mcu + " with SDK " + toolchain + \
           " on board with FQBN \"" + board + "\""
    if connection and connection["serial_port"]:
        text += ", serial port " + connection["serial_port"]
    if clean:
        text += ", clean build"
    if defines:
        text += ", with #define(s)"
        for idx, define in enumerate(defines):
            if define == MONITOR_DTR_RTS_OFF_MARKER:
                monitor_dtr_rts_on = False
            if idx == 0:
                text += " \"" + define + "\""
            else:
                text += ", \"" + define + "\""
    if ubxlib_dir:
        text += ", ubxlib directory \"" + ubxlib_dir + "\""
    if working_dir:
        text += ", working directory \"" + working_dir + "\""
    printer.string("{}{}.".format(prompt, text))

    reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_START, "Arduino")
    printer.string("{}CD to {}...".format(prompt, working_dir))

    with u_utils.ChangeDir(working_dir):
        # Lock the Arduino platform while we install the tools
        with u_utils.Lock(platform_lock, PLATFORM_LOCK_GUARD_TIME_SECONDS,
                          "platform", printer, prompt,
                          keep_going_flag) as locked_platform:
            if locked_platform:
                installed = install(board, ARDUINO_BOARDS_URLS, printer,
                                    prompt, keep_going_flag)

        if installed:
            arduino_dir = os.path.join(ubxlib_dir, ARDUINO_SUB_DIR)
            library_path = os.path.join(working_dir, LIBRARIES_SUB_DIR)
            # Clear out any pre-built ubxlib library or rebuilds
            # won't pick up changes
            clear_prebuilt_library(os.path.join(library_path, LIBRARY_NAME),
                                   mcu, printer, prompt)
            # Create the ubxlib Arduino library
            if create_library(ubxlib_dir, arduino_dir, toolchain,
                              os.path.join(library_path, LIBRARY_NAME),
                              LIBRARY_NAME_LIB_POSTFIX, clean, printer, prompt,
                              keep_going_flag):
                # Create the ubxlib Arduino test library
                if create_library(ubxlib_dir, arduino_dir, toolchain,
                                  os.path.join(library_path, LIBRARY_NAME),
                                  LIBRARY_NAME_TEST_POSTFIX, clean, printer,
                                  prompt, keep_going_flag):
                    # We now build both libraries with the test sketch and we also
                    # build the examples with the just the ubxlib Arduino library.
                    # Make a list of the sketches to build
                    sketch_paths.append(
                        os.path.join(arduino_dir, TEST_SKETCH_SUB_PATH))
                    for root, _directories, files in os.walk(library_path):
                        for file in files:
                            if os.sep + "examples" + os.sep in root and file.endswith(
                                    ".ino"):
                                sketch_paths.append(os.path.join(root, file))
                    printer.string("{}{} thing(s) to build.".format(
                        prompt, len(sketch_paths)))
                    # Build the sketches: note that the first build of the ubxlib
                    # Arduino library to a .a file will be copied back into the library
                    # directory for use in the following builds
                    build_dir = os.path.join(working_dir, BUILD_SUBDIR)
                    for sketch_path in sketch_paths:
                        build_start_time = time()
                        build_path = build(build_dir, sketch_path,
                                           library_path, mcu, board, defines,
                                           clean, printer, prompt, reporter,
                                           keep_going_flag)
                        if not u_utils.keep_going(keep_going_flag, printer,
                                                  prompt) or not build_path:
                            break
                        build_paths.append(build_path)
                        reporter.event(u_report.EVENT_TYPE_BUILD,
                                       u_report.EVENT_PASSED,
                                       "build {} of {} took {:.0f} second(s)". \
                                       format(len(build_paths), len(sketch_paths),
                                              time() - build_start_time))
                    if len(build_paths) == len(sketch_paths):
                        # Download and run the builds
                        with u_connection.Lock(
                                connection, connection_lock,
                                CONNECTION_LOCK_GUARD_TIME_SECONDS, printer,
                                prompt, keep_going_flag) as locked:
                            if locked:
                                for build_path in build_paths:
                                    # I have seen download failures occur if two
                                    # are initiated at the same time so lock the
                                    # platform for this
                                    downloaded = False
                                    with u_utils.Lock(
                                            platform_lock,
                                            PLATFORM_LOCK_GUARD_TIME_SECONDS,
                                            "platform", printer, prompt,
                                            keep_going_flag
                                    ) as locked_platform:
                                        if locked_platform:
                                            # Have seen this fail, so give it a few goes
                                            reporter.event(
                                                u_report.EVENT_TYPE_DOWNLOAD,
                                                u_report.EVENT_START)
                                            retries = 0
                                            while u_utils.keep_going(keep_going_flag, printer,
                                                                     prompt) and               \
                                                  not downloaded and (retries < 3):
                                                downloaded = download(
                                                    build_path, board,
                                                    connection["serial_port"],
                                                    printer, prompt,
                                                    keep_going_flag)
                                                if not downloaded:
                                                    reporter.event(u_report.EVENT_TYPE_DOWNLOAD,
                                                                   u_report.EVENT_WARNING,
                                                                   "unable to download, will" \
                                                                   " retry...")
                                                    retries += 1
                                                    sleep(5)
                                    if downloaded:
                                        reporter.event(
                                            u_report.EVENT_TYPE_DOWNLOAD,
                                            u_report.EVENT_COMPLETE)
                                        reporter.event(
                                            u_report.EVENT_TYPE_TEST,
                                            u_report.EVENT_START)
                                        # Open the COM port to get debug output
                                        serial_handle = u_utils.open_serial(
                                            connection["serial_port"],
                                            115200,
                                            printer,
                                            prompt,
                                            dtr_set_on=monitor_dtr_rts_on,
                                            rts_set_on=monitor_dtr_rts_on)
                                        if serial_handle is not None:
                                            # Monitor progress
                                            return_values.append(
                                                u_monitor.main(
                                                    serial_handle,
                                                    u_monitor.
                                                    CONNECTION_SERIAL,
                                                    RUN_GUARD_TIME_SECONDS,
                                                    RUN_INACTIVITY_TIME_SECONDS,
                                                    "\r",
                                                    instance,
                                                    printer,
                                                    reporter,
                                                    test_report_handle,
                                                    keep_going_flag=
                                                    keep_going_flag))
                                            # Delays and flushes here to make sure
                                            # that the serial port actually closes
                                            # since we might need to re-open it for
                                            # another download going around the loop
                                            serial_handle.cancel_read()
                                            sleep(1)
                                            serial_handle.reset_input_buffer()
                                            serial_handle.reset_output_buffer()
                                            sleep(1)
                                            serial_handle.close()
                                            reporter.event(
                                                u_report.
                                                EVENT_TYPE_INFRASTRUCTURE,
                                                u_report.EVENT_COMPLETE,
                                                "serial port closed")
                                            sleep(5)
                                        else:
                                            reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                                                           u_report.EVENT_FAILED,
                                                           "unable to open serial port " +      \
                                                           connection["serial_port"])
                                        if return_values and return_values[
                                                -1] == 0:
                                            reporter.event(
                                                u_report.EVENT_TYPE_TEST,
                                                u_report.EVENT_COMPLETE)
                                        else:
                                            reporter.event(
                                                u_report.EVENT_TYPE_TEST,
                                                u_report.EVENT_FAILED)
                                    else:
                                        reporter.event(
                                            u_report.EVENT_TYPE_DOWNLOAD,
                                            u_report.EVENT_FAILED,
                                            "unable to download to the target")
                                if return_values:
                                    return_value = 0
                                    for item in return_values:
                                        # If a return value goes negative then
                                        # only count the negative values, i.e. the
                                        # number of infrastructure failures
                                        if (item < 0) and (return_value >= 0):
                                            return_value = item
                                        else:
                                            if (((item > 0) and (return_value >= 0)) or  \
                                                ((item < 0) and (return_value < 0))):
                                                return_value += item
                            else:
                                reporter.event(
                                    u_report.EVENT_TYPE_INFRASTRUCTURE,
                                    u_report.EVENT_FAILED,
                                    "unable to lock a connection")
                    else:
                        reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                                       u_report.EVENT_FAILED, "failed a build")
                else:
                    reporter.event(
                        u_report.EVENT_TYPE_BUILD, u_report.EVENT_FAILED,
                        "unable to build library, check debug log for details")
            else:
                reporter.event(
                    u_report.EVENT_TYPE_INFRASTRUCTURE, u_report.EVENT_FAILED,
                    "unable to create library, check debug log for details")
        else:
            reporter.event(
                u_report.EVENT_TYPE_INFRASTRUCTURE, u_report.EVENT_FAILED,
                "unable to install tools, check debug log for details")

    return return_value
Exemplo n.º 9
0
def run(instance, mcu, toolchain, connection, connection_lock, platform_lock,
        misc_locks, clean, defines, ubxlib_dir, working_dir, printer, reporter,
        test_report_handle):
    '''Build/run on Zephyr'''
    return_value = -1
    build_dir = None
    instance_text = u_utils.get_instance_text(instance)

    # Don't need the platform lock
    del platform_lock

    # Only one toolchain for Zephyr
    del toolchain

    prompt = PROMPT + instance_text + ": "

    # Print out what we've been told to do
    text = "running Zephyr for " + mcu
    if connection and "debugger" in connection and connection["debugger"]:
        text += ", on JLink debugger serial number " + connection["debugger"]
    if clean:
        text += ", clean build"
    if defines:
        text += ", with #define(s)"
        for idx, define in enumerate(defines):
            if idx == 0:
                text += " \"" + define + "\""
            else:
                text += ", \"" + define + "\""
    if ubxlib_dir:
        text += ", ubxlib directory \"" + ubxlib_dir + "\""
    if working_dir:
        text += ", working directory \"" + working_dir + "\""
    printer.string("{}{}.".format(prompt, text))

    reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_START, "Zephyr")
    # Switch to the working directory
    with u_utils.ChangeDir(working_dir):
        # Check that everything we need is installed
        # and configured
        if check_installation(TOOLS_LIST, printer, prompt):
            # Set up the environment variables for Zephyr
            returned_env = set_env(printer, prompt)
            if returned_env:
                # The west tools need to use the environment
                # configured above.
                print_env(returned_env, printer, prompt)
                # Note that Zephyr brings in its own
                # copy of Unity so there is no need to
                # fetch it here.
                # For Zephyr we need to obtain the full board name
                board = find_board(ubxlib_dir, mcu)
                if board:
                    # Do the build
                    build_start_time = time()
                    build_dir = build(board, clean, ubxlib_dir, defines,
                                      returned_env, printer, prompt, reporter)
                    if build_dir:
                        # Build succeeded, need to lock some things to do the download
                        reporter.event(
                            u_report.EVENT_TYPE_BUILD, u_report.EVENT_PASSED,
                            "build took {:.0f} second(s)".format(
                                time() - build_start_time))
                        # On NRF52 (NRF5)/Zephyr (NRF53/NRF52) doing a download
                        # on more than one platform at a time or doing a download
                        # while RTT logging is in progress seems to cause problems,
                        # even though it should be tied to the serial number of the
                        # given debugger on that board, so lock JLink for this.
                        jlink_lock = None
                        if "jlink_lock" in misc_locks:
                            jlink_lock = misc_locks["jlink_lock"]
                        with u_utils.Lock(jlink_lock,
                                          INSTALL_LOCK_WAIT_SECONDS, "JLink",
                                          printer, prompt) as locked_jlink:
                            if locked_jlink:
                                with u_connection.Lock(
                                        connection, connection_lock,
                                        CONNECTION_LOCK_GUARD_TIME_SECONDS,
                                        printer, prompt) as locked_connection:
                                    if locked_connection:
                                        # Get the device name for JLink
                                        jlink_device_name = jlink_device(mcu)
                                        if not jlink_device_name:
                                            reporter.event(
                                                u_report.
                                                EVENT_TYPE_INFRASTRUCTURE,
                                                u_report.EVENT_WARNING,
                                                "MCU not found in JLink devices"
                                            )
                                        # Do the download
                                        reporter.event(
                                            u_report.EVENT_TYPE_DOWNLOAD,
                                            u_report.EVENT_START)
                                        if download(
                                                connection, jlink_device_name,
                                                DOWNLOAD_GUARD_TIME_SECONDS,
                                                build_dir, returned_env,
                                                printer, prompt):
                                            reporter.event(
                                                u_report.EVENT_TYPE_DOWNLOAD,
                                                u_report.EVENT_COMPLETE)
                                            # Now the target can be reset
                                            u_utils.reset_nrf_target(
                                                connection, printer, prompt)
                                            reporter.event(
                                                u_report.EVENT_TYPE_TEST,
                                                u_report.EVENT_START)
                                            if connection and "swo_port" in connection:
                                                swo_port = connection[
                                                    "swo_port"]

                                            # With JLink started
                                            if jlink_device_name:
                                                RUN_JLINK.append("-Device")
                                                RUN_JLINK.append(
                                                    jlink_device(mcu))
                                            RUN_JLINK.append("-RTTTelnetPort")
                                            RUN_JLINK.append(str(swo_port))
                                            if connection and "debugger" in connection and \
                                               connection["debugger"]:
                                                RUN_JLINK.append("-USB")
                                                RUN_JLINK.append(
                                                    connection["debugger"])
                                            with u_utils.ExeRun(
                                                    RUN_JLINK,
                                                    printer,
                                                    prompt,
                                                    with_stdin=True
                                            ) as process_jlink:
                                                # Open the Telnet port to JLink
                                                # to get the debug output
                                                telnet_handle = u_utils.open_telnet(
                                                    swo_port, printer, prompt)
                                                if telnet_handle is not None:
                                                    # Monitor progress
                                                    return_value = u_monitor.    \
                                                                   main(telnet_handle,
                                                                        u_monitor.CONNECTION_TELNET,
                                                                        RUN_GUARD_TIME_SECONDS,
                                                                        RUN_INACTIVITY_TIME_SECONDS,
                                                                        instance, printer,
                                                                        reporter,
                                                                        test_report_handle)
                                                    telnet_handle.close()
                                                else:
                                                    reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                                                                   u_report.EVENT_FAILED,
                                                                   "unable to open RTT port " +  \
                                                                   str(swo_port))
                                                # JLink is VERY touchy as to how it exits,
                                                # need to send it "exit\n" over stdin
                                                # for it to exit cleanly
                                                process_jlink.stdin.write(
                                                    "exit\n".encode())
                                                sleep(5)
                                            if return_value == 0:
                                                reporter.event(
                                                    u_report.EVENT_TYPE_TEST,
                                                    u_report.EVENT_COMPLETE)
                                            else:
                                                reporter.event(
                                                    u_report.EVENT_TYPE_TEST,
                                                    u_report.EVENT_FAILED)
                                        else:
                                            reporter.event(
                                                u_report.EVENT_TYPE_DOWNLOAD,
                                                u_report.EVENT_FAILED,
                                                "check debug log for details")
                                    else:
                                        reporter.event(
                                            u_report.EVENT_TYPE_INFRASTRUCTURE,
                                            u_report.EVENT_FAILED,
                                            "unable to lock a connection")
                            else:
                                reporter.event(
                                    u_report.EVENT_TYPE_INFRASTRUCTURE,
                                    u_report.EVENT_FAILED,
                                    "unable to lock JLink")
                    else:
                        return_value = 1
                        reporter.event(u_report.EVENT_TYPE_BUILD,
                                       u_report.EVENT_FAILED,
                                       "check debug log for details")
                else:
                    return_value = 1
                    reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                                   u_report.EVENT_FAILED,
                                   "unable to find overlay file")
            else:
                reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                               u_report.EVENT_FAILED,
                               "environment setup failed")
        else:
            reporter.event(
                u_report.EVENT_TYPE_INFRASTRUCTURE, u_report.EVENT_FAILED,
                "there is a problem with the tools installation for Zephyr")

    return return_value
Exemplo n.º 10
0
def run(instance, defines, ubxlib_dir, working_dir, printer, reporter):
    '''Run Lint'''
    return_value = 1
    call_list = []
    instance_text = u_utils.get_instance_text(instance)

    prompt = PROMPT + instance_text + ": "

    # Print out what we've been told to do
    text = "running Lint from ubxlib directory \"" + ubxlib_dir + "\""
    if working_dir:
        text += ", working directory \"" + working_dir + "\""
    printer.string("{}{}.".format(prompt, text))

    reporter.event(u_report.EVENT_TYPE_CHECK,
                   u_report.EVENT_START,
                   "Lint")
    # Switch to the working directory
    with u_utils.ChangeDir(working_dir):
        # Check that everything we need is installed
        if check_installation(TOOLS_LIST, COMPILER_INCLUDE_DIRS,
                              printer, prompt):
            # Fetch Unity
            if u_utils.fetch_repo(u_utils.UNITY_URL,
                                  u_utils.UNITY_SUBDIR,
                                  None, printer, prompt):
                # Create the local Lint configuration files
                if create_lint_config(ubxlib_dir + os.sep +
                                      LINT_PLATFORM_PATH,
                                      defines, printer, prompt):
                    # Get the file list
                    file_list = get_file_list(ubxlib_dir, LINT_DIRS)

                    # Assemble the call list
                    call_list.append("flexelint")
                    if defines:
                        for item in defines:
                            call_list.append("-d" + item)
                    for item in COMPILER_INCLUDE_DIRS:
                        call_list.append("-i\"" + item + "\"")
                    call_list.append("-i\"" + u_utils.UNITY_SUBDIR + os.sep + "src\"")
                    for item in UBXLIB_INCLUDE_DIRS:
                        call_list.append("-i\"" + ubxlib_dir + os.sep + item + "\"")
                    for item in LINT_PLATFORM_CONFIG_FILES:
                        call_list.append(ubxlib_dir + os.sep + LINT_PLATFORM_PATH +
                                         os.sep + item)
                    call_list.extend(file_list)

                    # Print what we're gonna do
                    tmp = ""
                    for item in call_list:
                        tmp += " " + item
                    printer.string("{}in directory {} calling{}".         \
                                   format(prompt, os.getcwd(), tmp))
                    try:
                        text = subprocess.check_output(call_list,
                                                       stderr=subprocess.STDOUT,
                                                       shell=True) # Jenkins hangs without this
                        reporter.event(u_report.EVENT_TYPE_CHECK,
                                       u_report.EVENT_PASSED)
                        for line in text.splitlines():
                            printer.string("{}{}".format(prompt, line.decode()))
                        return_value = 0
                    except subprocess.CalledProcessError as error:
                        reporter.event(u_report.EVENT_TYPE_CHECK,
                                       u_report.EVENT_FAILED)
                        printer.string("{}Lint returned error {}:".
                                       format(prompt, error.returncode))
                        for line in error.output.splitlines():
                            line = line.strip().decode()
                            if line:
                                reporter.event_extra_information(line)
                                printer.string("{}{}".format(prompt, line))
                else:
                    reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                                   u_report.EVENT_FAILED,
                                   "could not create Lint config")
            else:
                reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                               u_report.EVENT_FAILED,
                               "unable to fetch Unity")
        else:
            reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                           u_report.EVENT_FAILED,
                           "there is a problem with the Lint installation")

    return return_value
Exemplo n.º 11
0
def run(instance, ubxlib_dir, working_dir, printer, reporter):
    '''Run Doxygen'''
    return_value = 1
    got_doxygen = False
    instance_text = u_utils.get_instance_text(instance)

    prompt = PROMPT + instance_text + ": "

    # Print out what we've been told to do
    text = "running Doxygen from ubxlib directory \"" + ubxlib_dir + "\""
    if working_dir:
        text += ", working directory \"" + working_dir + "\""
    printer.string("{}{}.".format(prompt, text))

    reporter.event(u_report.EVENT_TYPE_CHECK,
                   u_report.EVENT_START,
                   "Doxygen")

    got_doxygen = u_utils.exe_where("doxygen", \
                                    "ERROR: can't find Doxygen, please make"     \
                                    " sure that it is installed and on the path.", \
                                    printer, prompt)

    if got_doxygen:
        # Sort out any subst
        printer.string("{}Doxygen finds no files if run from a" \
                       " subst drive so convert {} to a real"      \
                       " path".format(prompt, ubxlib_dir))
        actual_ubxlib_dir = u_utils.get_actual_path(ubxlib_dir)
        printer.string("{}Actual ubxlib directory is {}".      \
                       format(prompt, actual_ubxlib_dir))
        # Run Doxygen
        config_path = actual_ubxlib_dir + os.sep + DOXYFILE
        printer.string("{}CD to {}...".format(prompt, actual_ubxlib_dir))
        with u_utils.ChangeDir(actual_ubxlib_dir):
            printer.string("{}in directory {} calling doxygen {}.".    \
                           format(prompt, os.getcwd(), config_path))
            try:
                my_env = os.environ.copy()
                my_env['UBX_WORKDIR'] = working_dir
                text = subprocess.check_output(["doxygen", config_path],
                                               stderr=subprocess.STDOUT,
                                               env=my_env,
                                               shell=True) # Jenkins hangs without this
                reporter.event(u_report.EVENT_TYPE_CHECK,
                               u_report.EVENT_PASSED)
                for line in text.splitlines():
                    printer.string("{}{}".format(prompt, line.decode()))
                return_value = 0
            except subprocess.CalledProcessError as error:
                reporter.event(u_report.EVENT_TYPE_CHECK,
                               u_report.EVENT_FAILED)
                printer.string("{}Doxygen returned error {}:".
                               format(prompt, error.returncode))
                for line in error.output.splitlines():
                    line = line.strip().decode()
                    if line:
                        reporter.event_extra_information(line)
                        printer.string("{}{}".format(prompt, line))
    else:
        reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                       u_report.EVENT_FAILED,
                       "there is a problem with the Doxygen installation")

    return return_value
Exemplo n.º 12
0
def run(instance, mcu, toolchain, connection, connection_lock, platform_lock,
        misc_locks, clean, defines, ubxlib_dir, working_dir, printer, reporter,
        test_report_handle):
    '''Build/run on STM32Cube'''
    return_value = -1
    mcu_dir = ubxlib_dir + os.sep + SDK_DIR + os.sep + "mcu" + os.sep + mcu
    instance_text = u_utils.get_instance_text(instance)
    # Create a unique project name prefix in case more than
    # one process is running this
    updated_project_name_prefix = UPDATED_PROJECT_NAME_PREFIX + str(
        os.getpid()) + "_"
    workspace_subdir = STM32CUBE_IDE_WORKSPACE_SUBDIR + "_" + str(os.getpid())
    elf_path = None
    downloaded = False
    running = False
    download_list = None

    # Only one toolchain for STM32Cube
    del toolchain

    prompt = PROMPT + instance_text + ": "

    # Print out what we've been told to do
    text = "running STM32Cube for " + mcu
    if connection and "debugger" in connection and connection["debugger"]:
        text += ", on STLink debugger serial number " + connection["debugger"]
    if clean:
        text += ", clean build"
    if defines:
        text += ", with #define(s)"
        for idx, define in enumerate(defines):
            if idx == 0:
                text += " \"" + define + "\""
            else:
                text += ", \"" + define + "\""
    if ubxlib_dir:
        text += ", ubxlib directory \"" + ubxlib_dir + "\""
    if working_dir:
        text += ", working directory \"" + working_dir + "\""
    printer.string("{}{}.".format(prompt, text))

    # On STM32F4 we can get USB errors if we try to do a download
    # on one platform while another is performing SWO logging.
    # Since each board only runs a single instance of stuff we
    # can work around this be ensuring that all downloads are
    # completed before SWO logging begins.
    # Add us to the list of pending downloads
    if misc_locks and ("stm32f4_downloads_list" in misc_locks):
        download_list = misc_locks["stm32f4_downloads_list"]
        download_list.append(instance_text)

    reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_START,
                   "STM32Cube")
    # Switch to the working directory
    with u_utils.ChangeDir(working_dir):
        # Check that everything we need is installed
        if check_installation(PATHS_LIST, printer, prompt):
            # Fetch Unity
            if u_utils.fetch_repo(u_utils.UNITY_URL, u_utils.UNITY_SUBDIR,
                                  None, printer, prompt):
                # I've no idea why but on every other
                # build STM32Cube loses track of where
                # most of the files are: you'll see it
                # say that it can't find u_cfg_sw.h and
                # fail.  Until we find out why just
                # give it two goes, deleting the project
                # we created before trying again.
                retries = 2
                while (elf_path is None) and (retries > 0):
                    # The STM32Cube IDE, based on Eclipse
                    # has no mechanism for overriding the locations
                    # of things so here we read the .project
                    # file and replace the locations of the
                    # STM32Cube SDK and Unity files as
                    # appropriate
                    if create_project(
                            mcu_dir, PROJECT_NAME,
                            updated_project_name_prefix + PROJECT_NAME,
                            STM32CUBE_FW_PATH,
                            working_dir + os.sep + u_utils.UNITY_SUBDIR,
                            printer, prompt):
                        # Do the build
                        build_start_time = time()
                        elf_path = build_binary(
                            mcu_dir, workspace_subdir,
                            updated_project_name_prefix + PROJECT_NAME, clean,
                            defines, printer, prompt)
                        if elf_path is None:
                            reporter.event(u_report.EVENT_TYPE_BUILD,
                                           u_report.EVENT_INFORMATION,
                                           "unable to build, will retry")
                            printer.string("{}if the compilation."       \
                                           " failure was because"        \
                                           " the build couldn't"         \
                                           " even find u_cfg_sw.h"       \
                                           " then ignore it, Eclipse"    \
                                           " lost its head, happens"     \
                                           " a lot, we will try again.". \
                                           format(prompt))
                    else:
                        reporter.event(
                            u_report.EVENT_TYPE_BUILD, u_report.EVENT_WARNING,
                            "unable to create STM32Cube project, will retry")
                    retries -= 1
                if elf_path:
                    reporter.event(
                        u_report.EVENT_TYPE_BUILD, u_report.EVENT_PASSED,
                        "build took {:.0f} second(s)".format(time() -
                                                             build_start_time))
                    # Lock the connection.
                    with u_connection.Lock(connection, connection_lock,
                                           CONNECTION_LOCK_GUARD_TIME_SECONDS,
                                           printer,
                                           prompt) as locked_connection:
                        if locked_connection:
                            # I have seen download failures occur if two
                            # ST-Link connections are initiated at the same time.
                            with u_utils.Lock(
                                    platform_lock,
                                    PLATFORM_LOCK_GUARD_TIME_SECONDS,
                                    "platform", printer,
                                    prompt) as locked_platform:
                                if locked_platform:
                                    reporter.event(
                                        u_report.EVENT_TYPE_DOWNLOAD,
                                        u_report.EVENT_START)
                                    # Do the download.  I have seen the STM32F4 debugger
                                    # barf on occasions so give this two bites of
                                    # the cherry
                                    retries = 2
                                    while not downloaded and (retries > 0):
                                        downloaded = download(
                                            connection,
                                            DOWNLOAD_GUARD_TIME_SECONDS,
                                            elf_path, printer, prompt)
                                        retries -= 1
                                        if not downloaded:
                                            if connection and "serial_port" in connection \
                                               and connection["serial_port"]:
                                                # Before retrying, reset the USB port
                                                u_utils.usb_reset("STMicroelectronics STLink" \
                                                                  "Virtual COM Port (" +
                                                                  connection["serial_port"] +
                                                                  ")", printer, prompt)
                                            sleep(5)
                                    if platform_lock:
                                        # Once the download has been done (or not) the platform lock
                                        # can be released, after a little safety sleep
                                        sleep(1)
                                        platform_lock.release()
                                    if downloaded:
                                        # Remove us from the list of pending downloads
                                        if download_list:
                                            download_list.remove(instance_text)
                                        reporter.event(
                                            u_report.EVENT_TYPE_DOWNLOAD,
                                            u_report.EVENT_COMPLETE)
                                        # Wait for all the other downloads to complete before
                                        # starting SWO logging
                                        u_utils.wait_for_completion(
                                            download_list, "download",
                                            DOWNLOADS_COMPLETE_GUARD_TIME_SECONDS,
                                            printer, prompt)
                                        # So that all STM32Cube instances don't start up at
                                        # once, which can also cause problems, wait the
                                        # instance-number number of seconds.
                                        hold_off = instance[0]
                                        if hold_off > 30:
                                            hold_off = 30
                                        sleep(hold_off)
                                        # Create and empty the SWO data file and decoded text file
                                        file_handle = open(SWO_DATA_FILE,
                                                           "w").close()
                                        file_handle = open(
                                            SWO_DECODED_TEXT_FILE,
                                            "w").close()
                                        reporter.event(
                                            u_report.EVENT_TYPE_TEST,
                                            u_report.EVENT_START)
                                        try:
                                            # Start a process which reads the
                                            # SWO output from a file, decodes it and
                                            # writes it back to a file
                                            process = Process(
                                                target=swo_decode_process,
                                                args=(SWO_DATA_FILE,
                                                      SWO_DECODED_TEXT_FILE))
                                            process.start()
                                            # Two bites at the cherry again
                                            retries = 2
                                            while not running and (retries >
                                                                   0):
                                                # Now start Open OCD to reset the target
                                                # and capture SWO output
                                                sleep(1)
                                                with u_utils.ExeRun(
                                                        open_ocd(
                                                            OPENOCD_COMMANDS,
                                                            connection),
                                                        printer, prompt):
                                                    running = True
                                                    # Open the SWO decoded text file for
                                                    # reading, binary to prevent the line
                                                    # endings being munged.
                                                    file_handle = open(
                                                        SWO_DECODED_TEXT_FILE,
                                                        "rb")
                                                    # Monitor progress based on the decoded
                                                    # SWO text
                                                    return_value = u_monitor.          \
                                                                   main(file_handle,
                                                                        u_monitor.CONNECTION_PIPE,
                                                                        RUN_GUARD_TIME_SECONDS,
                                                                        RUN_INACTIVITY_TIME_SECONDS,
                                                                        instance, printer,
                                                                        reporter,
                                                                        test_report_handle)
                                                    file_handle.close()
                                                retries -= 1
                                                if not running:
                                                    sleep(5)
                                            process.terminate()
                                        except KeyboardInterrupt:
                                            # Tidy up process on SIGINT
                                            printer.string(
                                                "{}caught CTRL-C, terminating..."
                                                .format(prompt))
                                            process.terminate()
                                            return_value = -1
                                        if return_value == 0:
                                            reporter.event(
                                                u_report.EVENT_TYPE_TEST,
                                                u_report.EVENT_COMPLETE)
                                        else:
                                            reporter.event(
                                                u_report.EVENT_TYPE_TEST,
                                                u_report.EVENT_FAILED)
                                    else:
                                        reporter.event(
                                            u_report.EVENT_TYPE_DOWNLOAD,
                                            u_report.EVENT_FAILED)
                        else:
                            reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                                           u_report.EVENT_FAILED,
                                           "unable to lock a connection")
                else:
                    reporter.event(u_report.EVENT_TYPE_BUILD,
                                   u_report.EVENT_FAILED,
                                   "check debug log for details")

                # To avoid a build up of stuff, delete the temporary build and
                # workspace on exit
                tmp = mcu_dir + os.sep + updated_project_name_prefix + PROJECT_NAME
                if os.path.exists(tmp):
                    printer.string("{}deleting temporary build directory {}...".   \
                                   format(prompt, tmp))
                    u_utils.deltree(tmp, printer, prompt)
                if os.path.exists(workspace_subdir):
                    printer.string("{}deleting temporary workspace directory {}...". \
                                   format(prompt, workspace_subdir))
                    u_utils.deltree(workspace_subdir, printer, prompt)

            else:
                reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                               u_report.EVENT_FAILED, "unable to fetch Unity")
        else:
            reporter.event(
                u_report.EVENT_TYPE_INFRASTRUCTURE, u_report.EVENT_FAILED,
                "there is a problem with the tools installation for STM32F4")

    # Remove us from the list of pending downloads for safety
    try:
        misc_locks["stm32f4_downloads_list"].remove(instance_text)
    except (AttributeError, ValueError, TypeError):
        pass

    return return_value
Exemplo n.º 13
0
def run(instance,
        mcu,
        toolchain,
        connection,
        connection_lock,
        platform_lock,
        misc_locks,
        clean,
        defines,
        ubxlib_dir,
        working_dir,
        printer,
        reporter,
        test_report_handle,
        keep_going_flag=None,
        unity_dir=None):
    '''Build/run on nRF5'''
    return_value = -1
    hex_file_path = None
    instance_text = u_utils.get_instance_text(instance)
    downloaded = False
    _ = (misc_locks)  # Suppress unused variable

    # Don't need the platform lock
    del platform_lock

    prompt = PROMPT + instance_text + ": "

    # Print out what we've been told to do
    text = "running nRF5 for " + mcu + " under " + toolchain
    if connection and "debugger" in connection and connection["debugger"]:
        text += ", on JLink debugger serial number " + connection["debugger"]
    if clean:
        text += ", clean build"
    if defines:
        text += ", with #define(s)"
        for idx, define in enumerate(defines):
            if idx == 0:
                text += " \"" + define + "\""
            else:
                text += ", \"" + define + "\""
    if ubxlib_dir:
        text += ", ubxlib directory \"" + ubxlib_dir + "\""
    if working_dir:
        text += ", working directory \"" + working_dir + "\""
    if unity_dir:
        text += ", using Unity from \"" + unity_dir + "\""
    printer.string("{}{}.".format(prompt, text))

    reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_START,
                   "nRF5SDK/" + toolchain)
    # Switch to the working directory
    with u_utils.ChangeDir(working_dir):
        # Check that everything we need is installed
        if u_utils.keep_going(keep_going_flag, printer, prompt) and \
           check_installation(toolchain, TOOLS_LIST, printer, prompt):
            # Fetch Unity, if necessary
            if u_utils.keep_going(keep_going_flag, printer, prompt) and \
                not unity_dir:
                if u_utils.fetch_repo(u_utils.UNITY_URL,
                                      u_utils.UNITY_SUBDIR,
                                      None,
                                      printer,
                                      prompt,
                                      submodule_init=False):
                    unity_dir = os.getcwd() + os.sep + u_utils.UNITY_SUBDIR
            if unity_dir:
                # Do the build
                build_start_time = time()
                if u_utils.keep_going(keep_going_flag, printer, prompt):
                    if toolchain.lower() == "gcc":
                        build_subdir_gcc = BUILD_SUBDIR_PREFIX_GCC + instance_text.replace(
                            ".", "_")
                        hex_file_path = build_gcc(clean, build_subdir_gcc,
                                                  ubxlib_dir, unity_dir,
                                                  defines, printer, prompt,
                                                  reporter, keep_going_flag)
                    elif toolchain.lower() == "ses":
                        hex_file_path = build_ses(clean, ubxlib_dir, unity_dir,
                                                  defines, printer, prompt,
                                                  reporter, keep_going_flag)
                if hex_file_path:
                    # Build succeeded, need to lock a connection to do the download
                    reporter.event(
                        u_report.EVENT_TYPE_BUILD, u_report.EVENT_PASSED,
                        "build took {:.0f} second(s)".format(time() -
                                                             build_start_time))
                    # Do the download
                    with u_connection.Lock(
                            connection, connection_lock,
                            CONNECTION_LOCK_GUARD_TIME_SECONDS, printer,
                            prompt, keep_going_flag) as locked_connection:
                        if locked_connection:
                            reporter.event(u_report.EVENT_TYPE_DOWNLOAD,
                                           u_report.EVENT_START)
                            # I have seen the download fail on occasion
                            # so give this two bites of the cherry
                            retries = 2
                            while not downloaded and (retries > 0):
                                downloaded = download(
                                    connection, DOWNLOAD_GUARD_TIME_SECONDS,
                                    hex_file_path, printer, prompt)
                                retries -= 1
                                if not downloaded and (retries > 0):
                                    reporter.event(
                                        u_report.EVENT_TYPE_DOWNLOAD,
                                        u_report.EVENT_WARNING,
                                        "unable to download, will retry...")
                                    sleep(5)
                            if downloaded:
                                reporter.event(u_report.EVENT_TYPE_DOWNLOAD,
                                               u_report.EVENT_COMPLETE)

                                # Now the target can be reset
                                u_utils.reset_nrf_target(
                                    connection, printer, prompt)
                                reporter.event(u_report.EVENT_TYPE_TEST,
                                               u_report.EVENT_START)

                                with URttReader(
                                        "NRF52840_XXAA",
                                        jlink_serial=connection["debugger"],
                                        printer=printer,
                                        prompt=prompt) as rtt_reader:
                                    return_value = u_monitor.main(
                                        rtt_reader, u_monitor.CONNECTION_RTT,
                                        RUN_GUARD_TIME_SECONDS,
                                        RUN_INACTIVITY_TIME_SECONDS, "\n",
                                        instance, printer, reporter,
                                        test_report_handle)

                                if return_value == 0:
                                    reporter.event(u_report.EVENT_TYPE_TEST,
                                                   u_report.EVENT_COMPLETE)
                                else:
                                    reporter.event(u_report.EVENT_TYPE_TEST,
                                                   u_report.EVENT_FAILED)
                            else:
                                reporter.event(u_report.EVENT_TYPE_DOWNLOAD,
                                               u_report.EVENT_FAILED,
                                               "check debug log for details")
                            # Wait for a short while before giving
                            # the connection lock away to make sure
                            # that everything really has shut down
                            # in the debugger
                            sleep(5)
                        else:
                            reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                                           u_report.EVENT_FAILED,
                                           "unable to lock a connection")
                else:
                    return_value = 1
                    reporter.event(u_report.EVENT_TYPE_BUILD,
                                   u_report.EVENT_FAILED,
                                   "check debug log for details")
            else:
                reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                               u_report.EVENT_FAILED, "unable to fetch Unity")
        else:
            reporter.event(
                u_report.EVENT_TYPE_INFRASTRUCTURE, u_report.EVENT_FAILED,
                "there is a problem with the tools installation for nRF5 SDK")

    return return_value
Exemplo n.º 14
0
def run_instances(database, instances, filter_string, ubxlib_dir, working_dir,
                  clean, summary_report_file, test_report_file, debug_file):
    '''Run the given instances'''
    return_value = 0
    processes = []
    platform_locks = []
    misc_locks = {}
    alive_count = 0
    report_thread = None
    report_queue = None
    reporter = None
    summary_report_file_path = None
    test_report_file_path = None
    debug_file_path = None
    summary_report_handle = None

    manager = Manager()

    # Create a lock to cover things that cross
    # platforms or that any process of u_run.main()
    # may need to perform outside of its working
    # directory
    misc_locks["system_lock"] = manager.RLock()

    # Create a lock which can be used on Nordic
    # platforms (nRF5 and Zephyer): performing a
    # JLink download to a board while JLink RTT logging
    # is active on any other board will often stop
    # the RTT logging even though the sessions are
    # aimed at debuggers with entirely different
    # serial numbers.
    misc_locks["jlink_lock"] = manager.RLock()

    # Create a "lock" that can be used on STM32F4
    # platforms to ensure that all downloads are
    # completed before logging commences.  We
    # can do this, rather than locking a tool for the
    # whole time as we have to do with Nordic, because
    # each STM32F4 board only runs a single instance
    misc_locks["stm32f4_downloads_list"] = manager.list()

    # It is possible for some platforms to be a bit
    # pants at running in multiple instances
    # hence here we create a lock per platform and pass it
    # into the instance for it to be able to manage
    # multiplicity if required
    create_platform_locks(database, instances, manager, platform_locks)

    # Launch a thread that prints stuff out
    # nicely from multiple sources
    print_queue = manager.Queue()
    print_thread = u_utils.PrintThread(print_queue)
    print_thread.start()

    # Set up a printer for this thread to print to the queue
    printer = u_utils.PrintToQueue(print_queue, None, True)

    if summary_report_file:
        # Launch a thread that manages reporting
        # from multiple sources
        summary_report_file_path = working_dir + os.sep + summary_report_file
        summary_report_handle = open(summary_report_file_path, "w")
        if summary_report_handle:
            printer.string("{}writing overall summary report to \"{}\".".  \
                           format(PROMPT, summary_report_file_path))
        else:
            printer.string("{}unable to open file \"{}\" for overall summary report.".   \
                           format(PROMPT, summary_report_file_path))
        report_queue = manager.Queue()
        report_thread = u_report.ReportThread(report_queue,
                                              summary_report_handle)
        report_thread.start()
        reporter = u_report.ReportToQueue(report_queue, None, None, printer)
        reporter.open()

    # From this post:
    # https://stackoverflow.com/questions/11312525/catch-ctrlc-sigint-and-exit-multiprocesses-gracefully-in-python
    # ...create a pool of worker processes to run our
    # instances, then they will handle sigint correctly
    # and tidy up after themselves.

    # SIGINT is ignored while the pool is created
    original_sigint_handler = signal(SIGINT, SIG_IGN)
    pool = NoDaemonPool(len(instances))
    signal(SIGINT, original_sigint_handler)

    # Create locks for connections
    u_connection.init_locks(manager)

    try:
        # Set up all the instances
        for instance in instances:
            # Provide a working directory that is unique
            # for each instance and make sure it exists
            if working_dir:
                this_working_dir = working_dir + os.sep +       \
                                   INSTANCE_DIR_PREFIX + \
                                   u_utils.get_instance_text(instance).replace(".", "_")
            else:
                this_working_dir = os.getcwd() + os.sep +       \
                                   INSTANCE_DIR_PREFIX + \
                                   u_utils.get_instance_text(instance).replace(".", "_")
            if not os.path.isdir(this_working_dir):
                os.makedirs(this_working_dir)
            # Only clean the working directory if requested
            if clean:
                u_utils.deltree(this_working_dir, printer, PROMPT)
                os.makedirs(this_working_dir)

            # Create the file paths for this instance
            if summary_report_file:
                summary_report_file_path = this_working_dir + os.sep + summary_report_file
            if test_report_file:
                test_report_file_path = this_working_dir + os.sep + test_report_file
            if debug_file:
                debug_file_path = this_working_dir + os.sep + debug_file

            # Start u_run.main in each worker thread
            process = {}
            process["platform"] = u_data.get_platform_for_instance(
                database, instance)
            process["instance"] = instance
            process["platform_lock"] = None
            process["connection_lock"] = u_connection.get_lock(instance)
            for platform_lock in platform_locks:
                if process["platform"] == platform_lock["platform"]:
                    process["platform_lock"] = platform_lock["lock"]
                    break
            process["handle"] = pool.apply_async(
                u_run.main,
                (database, instance, filter_string, True, ubxlib_dir,
                 this_working_dir, process["connection_lock"],
                 process["platform_lock"], misc_locks, print_queue,
                 report_queue, summary_report_file_path, test_report_file_path,
                 debug_file_path))
            alive_count += 1
            processes.append(process.copy())

        # Wait for all the launched processes to complete
        printer.string("{}all instances now launched.".format(PROMPT))
        loop_count = 0
        while alive_count > 0:
            for process in processes:
                instance_text = u_utils.get_instance_text(process["instance"])
                if not "dealt_with" in process and process["handle"].ready():
                    try:
                        # If the return value has gone negative, i.e.
                        # an infrastructure failure, leave it there,
                        # else add the number of test failures to it
                        if (return_value >= 0 and process["handle"].get() > 0) or \
                            (return_value <= 0 and process["handle"].get() < 0):
                            return_value += process["handle"].get()
                    except KeyboardInterrupt as ex:
                        raise KeyboardInterrupt from ex
                    except Exception as ex:
                        # If an instance threw an exception then flag an
                        # infrastructure error
                        return_value = -1
                        printer.string("{}instance {} threw exception \"{}:"    \
                                       " {}\" but I can't tell you where"       \
                                       " I'm afraid.".                          \
                                       format(PROMPT, instance_text,
                                              type(ex).__name__, str(ex)))
                        if reporter:
                            reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                                           u_report.EVENT_FAILED,
                                           "instance {} threw exception \"{}: {}\"". \
                                           format(instance_text, type(ex).__name__,
                                                  str(ex)))
                    alive_count -= 1
                    process["dealt_with"] = True
                if not process["handle"].ready() and                         \
                   (loop_count == STILL_RUNNING_REPORT_SECONDS):
                    printer.string("{}instance {} still running.".           \
                                        format(PROMPT, instance_text))
            loop_count += 1
            if loop_count > STILL_RUNNING_REPORT_SECONDS:
                loop_count = 0
            sleep(1)

    except KeyboardInterrupt:
        # Pools can tidy themselves up on SIGINT
        printer.string(
            "{}caught CTRL-C, terminating instances...".format(PROMPT))
        if reporter:
            reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                           u_report.EVENT_FAILED,
                           "CTRL-C received, terminating")
        pool.terminate()
        return_value = -1

    # Tidy up
    pool.close()
    pool.join()
    if reporter:
        reporter.event_extra_information("return value overall {} (0 = success, negative ="   \
                                         " probable infrastructure failure, positive ="       \
                                         " failure(s) (may still be due to infrastructure))". \
                                         format(return_value))
        reporter.close()

    # Wait for the print and report queues to empty
    # and stop the print process
    printer.string("{}all runs complete, return value {}.".format(
        PROMPT, return_value))
    sleep(1)
    print_thread.stop_thread()
    print_thread.join()

    # Stop the reporting process
    if report_thread:
        report_thread.stop_thread()
        report_thread.join()

    if summary_report_handle:
        summary_report_handle.close()

    return return_value
Exemplo n.º 15
0
def run(instance, ubxlib_dir, working_dir, printer, reporter):
    '''Run AStyle'''
    return_value = 1
    got_astyle = False
    call_list = []
    instance_text = u_utils.get_instance_text(instance)

    prompt = PROMPT + instance_text + ": "

    # Print out what we've been told to do
    text = "running AStyle from ubxlib directory \"" + ubxlib_dir +  \
           "\" using configuration file \"" + ubxlib_dir + os.sep +  \
           CONFIG_FILE + "\""
    if working_dir:
        text += ", working directory \"" + working_dir + "\""
    printer.string("{}{}.".format(prompt, text))

    reporter.event(u_report.EVENT_TYPE_CHECK, u_report.EVENT_START, "AStyle")
    got_astyle = u_utils.exe_where("astyle", \
                        "ERROR: can't find AStyle, please make"      \
                        " sure that it is installed and on the path.", \
                        printer, prompt)
    if got_astyle:
        # Run AStyle
        printer.string("{}CD to {}...".format(prompt, ubxlib_dir))
        with u_utils.ChangeDir(ubxlib_dir):
            # Assemble the call list
            call_list.append("astyle")
            call_list.append("--options=" + CONFIG_FILE)  # Options file
            call_list.append("--dry-run")  # Don't make changes
            call_list.append("--formatted")  # Only list changed files
            call_list.append(
                "--suffix=none")  # Don't leave .orig files everywhere
            call_list.append("--verbose")  # Print out stats
            for exclude_dir in EXCLUDE_DIRS:  # Exclude these directories
                call_list.append("--exclude=" + exclude_dir)
            call_list.append(
                "--ignore-exclude-errors-x")  # Ignore unfound excludes
            call_list.append("--recursive")  # Recurse through...
            for include_dir in ASTYLE_DIRS:  # ...these files
                call_list.append(include_dir + os.sep + ASTYLE_FILE_EXTENSIONS)

            # Print what we're gonna do
            tmp = ""
            for item in call_list:
                tmp += " " + item
            printer.string("{}in directory {} calling{}".         \
                           format(prompt, os.getcwd(), tmp))
            try:
                text = subprocess.check_output(
                    call_list, stderr=subprocess.STDOUT,
                    shell=True)  # Jenkins hangs without this
                formatted = []
                for line in text.splitlines():
                    line = line.decode(encoding="utf-8", errors="ignore")
                    printer.string("{}{}".format(prompt, line))
                    # AStyle doesn't return anything other than 0,
                    # need to look for the word "Formatted" to find
                    # a file it has fiddled with
                    if line.startswith("Formatted"):
                        formatted.append(line)
                if not formatted:
                    reporter.event(u_report.EVENT_TYPE_CHECK,
                                   u_report.EVENT_PASSED)
                else:
                    reporter.event(u_report.EVENT_TYPE_CHECK,
                                   u_report.EVENT_WARNING)
                    for line in formatted:
                        reporter.event_extra_information(line)
                # We don't return any errors about formatting
                return_value = 0
            except subprocess.CalledProcessError as error:
                reporter.event(u_report.EVENT_TYPE_CHECK,
                               u_report.EVENT_FAILED)
                printer.string("{}AStyle returned error {}:".format(
                    prompt, error.returncode))
                for line in error.output.splitlines():
                    line = line.strip()
                    if line:
                        reporter.event_extra_information(line)
                        printer.string("{}{}".format(prompt, line))
    else:
        reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                       u_report.EVENT_FAILED,
                       "there is a problem with the AStyle installation")

    return return_value
Exemplo n.º 16
0
def run(instance,
        defines,
        ubxlib_dir,
        working_dir,
        printer,
        reporter,
        keep_going_flag=None):
    '''Build to check static sizes'''
    return_value = -1
    instance_text = u_utils.get_instance_text(instance)
    map_file_path = BUILD_SUBDIR + os.sep + MAP_FILE_NAME
    cflags = C_FLAGS

    prompt = PROMPT + instance_text + ": "

    # Print out what we've been told to do
    text = "running static size check from ubxlib directory \"" + ubxlib_dir + "\""
    if working_dir:
        text += ", working directory \"" + working_dir + "\""
    printer.string("{}{}.".format(prompt, text))

    reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_START, "NoFloat")

    # Switch to the working directory
    with u_utils.ChangeDir(working_dir):
        # Add the #defines to C_FLAGS
        if defines:
            for define in defines:
                cflags += " -D" + define

        # Assemble the call list
        call_list = ["python"]
        call_list.append(ubxlib_dir + os.sep + SUB_DIR + os.sep +
                         "static_size.py")
        call_list.append("-p")
        call_list.append(GNU_INSTALL_ROOT)
        call_list.append("-u")
        call_list.append(ubxlib_dir)
        call_list.append("-c")
        call_list.append(cflags)
        call_list.append("-l")
        call_list.append(LD_FLAGS)
        call_list.append(ubxlib_dir + os.sep + SUB_DIR + os.sep + "source.txt")
        call_list.append(ubxlib_dir + os.sep + SUB_DIR + os.sep +
                         "include.txt")

        # Print what we're gonna do
        tmp = ""
        for item in call_list:
            tmp += " " + item
        printer.string("{}in directory {} calling{}".         \
                       format(prompt, os.getcwd(), tmp))

        # Set shell to keep Jenkins happy
        if u_utils.exe_run(call_list,
                           0,
                           printer,
                           prompt,
                           shell_cmd=True,
                           keep_going_flag=keep_going_flag):
            reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_COMPLETE)
            reporter.event(u_report.EVENT_TYPE_TEST, u_report.EVENT_START)
            # Having performed the build, open the .map file
            printer.string("{} opening map file {}...".format(
                prompt, MAP_FILE_NAME))
            if os.path.exists(map_file_path):
                map_file = open(map_file_path, "r")
                if map_file:
                    # Parse the cross-reference section to seek
                    # if any of the functions that indicate the
                    # floating point has been introduced turn up
                    got_xref = False
                    got_fp = False
                    for line in map_file.read().splitlines():
                        if got_xref:
                            for function in FLOAT_FUNCTIONS:
                                if line.startswith(function):
                                    printer.string("{} found {} in map file which" \
                                                   " indicates floating point is"  \
                                                   " in use: {}".format(prompt,      \
                                                                        function, line))
                                    got_fp = True
                        else:
                            if line.startswith("Cross Reference Table"):
                                got_xref = True
                    if not got_xref:
                        reporter.event(
                            u_report.EVENT_TYPE_TEST, u_report.EVENT_FAILED,
                            "map file has no cross-reference section")
                    else:
                        if got_fp:
                            reporter.event(
                                u_report.EVENT_TYPE_TEST,
                                u_report.EVENT_FAILED,
                                "floating point seems to be in use")
                        else:
                            return_value = 0
                            reporter.event(u_report.EVENT_TYPE_TEST,
                                           u_report.EVENT_COMPLETE)
                    map_file.close()
            else:
                reporter.event(u_report.EVENT_TYPE_TEST, u_report.EVENT_FAILED,
                               "unable to open map file")
        else:
            reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_FAILED,
                           "check debug log for details")

    return return_value
Exemplo n.º 17
0
def run(instance,
        mcu,
        toolchain,
        connection,
        connection_lock,
        platform_lock,
        misc_locks,
        clean,
        defines,
        ubxlib_dir,
        working_dir,
        printer,
        reporter,
        test_report_handle,
        keep_going_flag=None):
    '''Build/run on ESP-IDF'''
    return_value = -1
    monitor_dtr_rts_on = None
    instance_text = u_utils.get_instance_text(instance)

    # No issues with running in parallel on ESP-IDF
    del platform_lock

    # Only one toolchain for ESP-IDF
    del toolchain

    prompt = PROMPT + instance_text + ": "

    # Print out what we've been told to do and at the
    # same time check for the DTR/RTS off marker
    text = "running ESP-IDF for " + mcu
    if connection and connection["serial_port"]:
        text += ", on serial port " + connection["serial_port"]
    if clean:
        text += ", clean build"
    if defines:
        text += ", with #define(s)"
        for idx, define in enumerate(defines):
            if define == MONITOR_DTR_RTS_OFF_MARKER:
                monitor_dtr_rts_on = False
            if idx == 0:
                text += " \"" + define + "\""
            else:
                text += ", \"" + define + "\""
    if ubxlib_dir:
        text += ", ubxlib directory \"" + ubxlib_dir + "\""
    if working_dir:
        text += ", working directory \"" + working_dir + "\""
    printer.string("{}{}.".format(prompt, text))

    reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_START, "ESP-IDF")
    printer.string("{}CD to {}...".format(prompt, working_dir))
    with u_utils.ChangeDir(working_dir):
        # Fetch ESP-IDF into the right sub directory
        # and install the tools
        esp_idf_dir = ESP_IDF_ROOT + os.sep + ESP_IDF_LOCATION["subdir"]
        system_lock = None
        if u_utils.keep_going(keep_going_flag, printer, prompt) and \
           misc_locks and ("system_lock" in misc_locks):
            system_lock = misc_locks["system_lock"]
        returned_env = install(ESP_IDF_LOCATION["url"], esp_idf_dir,
                               ESP_IDF_LOCATION["branch"], system_lock,
                               keep_going_flag, printer, prompt, reporter)
        if u_utils.keep_going(keep_going_flag, printer, prompt) and \
           returned_env:
            # From here on the ESP-IDF tools need to set up
            # and use the set of environment variables
            # returned above.
            print_env(returned_env, printer, prompt)
            # Now do the build
            build_dir = working_dir + os.sep + BUILD_SUBDIR
            build_start_time = time()
            if u_utils.keep_going(keep_going_flag, printer, prompt) and \
               build(esp_idf_dir, ubxlib_dir, build_dir,
                     defines, returned_env, clean,
                     printer, prompt, reporter, keep_going_flag):
                reporter.event(u_report.EVENT_TYPE_BUILD,
                               u_report.EVENT_PASSED,
                               "build took {:.0f} second(s)". \
                               format(time() - build_start_time))
                with u_connection.Lock(connection, connection_lock,
                                       CONNECTION_LOCK_GUARD_TIME_SECONDS,
                                       printer, prompt,
                                       keep_going_flag) as locked:
                    if locked:
                        # Have seen this fail, only with Python 3 for
                        # some reason, so give it a few goes
                        reporter.event(u_report.EVENT_TYPE_DOWNLOAD,
                                       u_report.EVENT_START)
                        retries = 0
                        downloaded = False
                        while u_utils.keep_going(keep_going_flag, printer, prompt) and \
                              not downloaded and (retries < 3):
                            downloaded = download(esp_idf_dir, ubxlib_dir,
                                                  build_dir,
                                                  connection["serial_port"],
                                                  returned_env, printer,
                                                  prompt)
                            if not downloaded:
                                reporter.event(
                                    u_report.EVENT_TYPE_DOWNLOAD,
                                    u_report.EVENT_WARNING,
                                    "unable to download, will retry...")
                                retries += 1
                                sleep(5)
                        if downloaded:
                            reporter.event(u_report.EVENT_TYPE_DOWNLOAD,
                                           u_report.EVENT_COMPLETE)
                            reporter.event(u_report.EVENT_TYPE_TEST,
                                           u_report.EVENT_START)
                            # Open the COM port to get debug output
                            serial_handle = u_utils.open_serial(
                                connection["serial_port"],
                                115200,
                                printer,
                                prompt,
                                dtr_set_on=monitor_dtr_rts_on,
                                rts_set_on=monitor_dtr_rts_on)
                            if serial_handle is not None:
                                # Monitor progress
                                return_value = u_monitor.main(
                                    serial_handle,
                                    u_monitor.CONNECTION_SERIAL,
                                    RUN_GUARD_TIME_SECONDS,
                                    RUN_INACTIVITY_TIME_SECONDS,
                                    "\r",
                                    instance,
                                    printer,
                                    reporter,
                                    test_report_handle,
                                    keep_going_flag=keep_going_flag)
                                serial_handle.close()
                            else:
                                reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                                               u_report.EVENT_FAILED,
                                               "unable to open serial port " +      \
                                               connection["serial_port"])
                            if return_value == 0:
                                reporter.event(u_report.EVENT_TYPE_TEST,
                                               u_report.EVENT_COMPLETE)
                            else:
                                reporter.event(u_report.EVENT_TYPE_TEST,
                                               u_report.EVENT_FAILED)
                        else:
                            reporter.event(u_report.EVENT_TYPE_DOWNLOAD,
                                           u_report.EVENT_FAILED,
                                           "unable to download to the target")
                    else:
                        reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                                       u_report.EVENT_FAILED,
                                       "unable to lock a connection")
            else:
                reporter.event(u_report.EVENT_TYPE_BUILD,
                               u_report.EVENT_FAILED,
                               "unable to build, check debug log for details")
        else:
            reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                           u_report.EVENT_FAILED, "tools installation failed")

    return return_value
Exemplo n.º 18
0
def run(instance,
        mcu,
        board,
        toolchain,
        connection,
        connection_lock,
        platform_lock,
        misc_locks,
        clean,
        defines,
        ubxlib_dir,
        working_dir,
        printer,
        reporter,
        test_report_handle,
        keep_going_flag=None):
    '''Build/run on Zephyr'''
    return_value = -1
    build_dir = None
    instance_text = u_utils.get_instance_text(instance)

    # Don't need the platform or misc locks
    del platform_lock
    del misc_locks

    # Only one toolchain for Zephyr
    del toolchain

    prompt = PROMPT + instance_text + ": "

    # Print out what we've been told to do
    text = "running Zephyr for " + mcu + " (on a \"" + board + "\" board)"
    if connection and "debugger" in connection and connection["debugger"]:
        text += ", on JLink debugger serial number " + connection["debugger"]
    if clean:
        text += ", clean build"
    if defines:
        text += ", with #define(s)"
        for idx, define in enumerate(defines):
            if idx == 0:
                text += " \"" + define + "\""
            else:
                text += ", \"" + define + "\""
    if ubxlib_dir:
        text += ", ubxlib directory \"" + ubxlib_dir + "\""
    if working_dir:
        text += ", working directory \"" + working_dir + "\""
    printer.string("{}{}.".format(prompt, text))

    reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_START, "Zephyr")
    # Switch to the working directory
    with u_utils.ChangeDir(working_dir):
        # Check that everything we need is installed
        # and configured
        if u_utils.keep_going(keep_going_flag, printer, prompt) and \
           check_installation(TOOLS_LIST, printer, prompt):
            # Set up the environment variables for Zephyr
            returned_env = set_env(printer, prompt)
            if u_utils.keep_going(keep_going_flag, printer, prompt) and \
               returned_env:
                # The west tools need to use the environment
                # configured above.
                print_env(returned_env, printer, prompt)
                # Note that Zephyr brings in its own
                # copy of Unity so there is no need to
                # fetch it here.
                if board:
                    # Do the build
                    build_start_time = time()
                    build_dir = build(board, clean, ubxlib_dir, defines,
                                      returned_env, printer, prompt, reporter,
                                      keep_going_flag)
                    if u_utils.keep_going(keep_going_flag, printer, prompt) and \
                       build_dir:
                        # Build succeeded, need to lock some things to do the download
                        reporter.event(
                            u_report.EVENT_TYPE_BUILD, u_report.EVENT_PASSED,
                            "build took {:.0f} second(s)".format(
                                time() - build_start_time))
                        # Do the download
                        with u_connection.Lock(
                                connection, connection_lock,
                                CONNECTION_LOCK_GUARD_TIME_SECONDS, printer,
                                prompt, keep_going_flag) as locked_connection:
                            if locked_connection:
                                # Get the device name for JLink
                                jlink_device_name = jlink_device(mcu)
                                if not jlink_device_name:
                                    reporter.event(
                                        u_report.EVENT_TYPE_INFRASTRUCTURE,
                                        u_report.EVENT_WARNING,
                                        "MCU not found in JLink devices")
                                # Do the download
                                reporter.event(u_report.EVENT_TYPE_DOWNLOAD,
                                               u_report.EVENT_START)
                                retries = 0
                                downloaded = False
                                while u_utils.keep_going(keep_going_flag, printer, prompt) and \
                                      not downloaded and (retries < 3):
                                    downloaded = download(
                                        connection, jlink_device_name,
                                        DOWNLOAD_GUARD_TIME_SECONDS, build_dir,
                                        returned_env, printer, prompt)
                                    if not downloaded:
                                        reporter.event(
                                            u_report.EVENT_TYPE_DOWNLOAD,
                                            u_report.EVENT_WARNING,
                                            "unable to download, will retry..."
                                        )
                                        retries += 1
                                        sleep(5)
                                if downloaded:
                                    reporter.event(
                                        u_report.EVENT_TYPE_DOWNLOAD,
                                        u_report.EVENT_COMPLETE)
                                    # Now the target can be reset
                                    u_utils.reset_nrf_target(
                                        connection, printer, prompt)
                                    reporter.event(u_report.EVENT_TYPE_TEST,
                                                   u_report.EVENT_START)

                                    with URttReader(
                                            jlink_device(mcu),
                                            jlink_serial=connection[
                                                "debugger"],
                                            printer=printer,
                                            prompt=prompt) as rtt_reader:
                                        return_value = u_monitor.main(
                                            rtt_reader,
                                            u_monitor.CONNECTION_RTT,
                                            RUN_GUARD_TIME_SECONDS,
                                            RUN_INACTIVITY_TIME_SECONDS,
                                            "\n",
                                            instance,
                                            printer,
                                            reporter,
                                            test_report_handle,
                                            keep_going_flag=keep_going_flag)
                                    if return_value == 0:
                                        reporter.event(
                                            u_report.EVENT_TYPE_TEST,
                                            u_report.EVENT_COMPLETE)
                                    else:
                                        reporter.event(
                                            u_report.EVENT_TYPE_TEST,
                                            u_report.EVENT_FAILED)
                                else:
                                    reporter.event(
                                        u_report.EVENT_TYPE_DOWNLOAD,
                                        u_report.EVENT_FAILED,
                                        "check debug log for details")
                            else:
                                reporter.event(
                                    u_report.EVENT_TYPE_INFRASTRUCTURE,
                                    u_report.EVENT_FAILED,
                                    "unable to lock a connection")
                    else:
                        return_value = 1
                        reporter.event(u_report.EVENT_TYPE_BUILD,
                                       u_report.EVENT_FAILED,
                                       "check debug log for details")
                else:
                    return_value = 1
                    reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                                   u_report.EVENT_FAILED,
                                   "unable to find overlay file")
            else:
                reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                               u_report.EVENT_FAILED,
                               "environment setup failed")
        else:
            reporter.event(
                u_report.EVENT_TYPE_INFRASTRUCTURE, u_report.EVENT_FAILED,
                "there is a problem with the tools installation for Zephyr")

    return return_value
Exemplo n.º 19
0
def run(instance,
        defines,
        ubxlib_dir,
        working_dir,
        printer,
        reporter,
        keep_going_flag=None):
    '''Build to check static sizes'''
    return_value = -1
    instance_text = u_utils.get_instance_text(instance)
    cflags = C_FLAGS

    prompt = PROMPT + instance_text + ": "

    # Print out what we've been told to do
    text = "running static size check from ubxlib directory \"" + ubxlib_dir + "\""
    if working_dir:
        text += ", working directory \"" + working_dir + "\""
    printer.string("{}{}.".format(prompt, text))

    reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_START,
                   "StaticSize")

    # Switch to the working directory
    with u_utils.ChangeDir(working_dir):
        # Add the #defines to C_FLAGS
        if defines:
            for define in defines:
                cflags += " -D" + define

        # Assemble the call list
        call_list = ["python"]
        call_list.append(ubxlib_dir + os.sep + SUB_DIR + os.sep +
                         "static_size.py")
        call_list.append("-p")
        call_list.append(GNU_INSTALL_ROOT)
        call_list.append("-u")
        call_list.append(ubxlib_dir)
        call_list.append("-c")
        call_list.append(cflags)
        call_list.append("-l")
        call_list.append(LD_FLAGS)
        call_list.append(ubxlib_dir + os.sep + SUB_DIR + os.sep + "source.txt")
        call_list.append(ubxlib_dir + os.sep + SUB_DIR + os.sep +
                         "include.txt")

        # Print what we're gonna do
        tmp = ""
        for item in call_list:
            tmp += " " + item
        printer.string("{}in directory {} calling{}".         \
                       format(prompt, os.getcwd(), tmp))

        # Set shell to keep Jenkins happy
        if u_utils.exe_run(call_list,
                           0,
                           printer,
                           prompt,
                           shell_cmd=True,
                           keep_going_flag=keep_going_flag):
            return_value = 0
            reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_COMPLETE)
        else:
            reporter.event(u_report.EVENT_TYPE_BUILD, u_report.EVENT_FAILED,
                           "check debug log for details")

    return return_value
Exemplo n.º 20
0
def run(instance, ubxlib_dir, working_dir, printer, reporter):
    '''Run Pylint'''
    return_value = 1
    got_pylint = False
    min_rating = 10
    instance_text = u_utils.get_instance_text(instance)

    prompt = PROMPT + instance_text + ": "

    # Print out what we've been told to do
    text = "running Pylint from ubxlib directory \"" + ubxlib_dir + "\""
    if working_dir:
        text += ", working directory \"" + working_dir + "\""
    text += ", checking for minimum rating " + str(MIN_RATING)
    printer.string("{}{}.".format(prompt, text))

    reporter.event(u_report.EVENT_TYPE_CHECK,
                   u_report.EVENT_START,
                   "Pylint")
    got_pylint = u_utils.exe_where("pylint", \
                        "ERROR: can't find pylint, please make"     \
                        " sure that it is installed and on the path.", \
                        printer, prompt)


    if got_pylint:
        # Run Pylint on all the .py files in PYTHON_PATHS
        return_value = 0
        for py_path in PYTHON_PATHS:
            abs_py_path = ubxlib_dir + os.sep + py_path
            if os.path.exists(abs_py_path):
                printer.string("{}CD to {}...".format(prompt, abs_py_path))
                with u_utils.ChangeDir(abs_py_path):
                    for py_file in os.listdir(abs_py_path):
                        if py_file.endswith(".py"):
                            printer.string("{}running Pylint on {}...".format(prompt, py_file))
                            got_rating = False
                            try:
                                # ignore u_settings module as it sets members programatically and
                                # will thus generate a bunch of lint warnings
                                text = subprocess.check_output(["pylint", "--exit-zero",
                                                                "--ignored-modules=u_settings",
                                                                py_file],
                                                               stderr=subprocess.STDOUT,
                                                               shell=True) # Stop Jenkins hanging
                                rating = 0
                                for line in text.splitlines():
                                    line = line.decode()
                                    printer.string("{}{}".format(prompt, line))
                                    # See if there is a rating in this line
                                    outcome = line.rpartition("Your code has been rated at ")
                                    if len(outcome) == 3:
                                        outcome = outcome[2].split("/")
                                        # Get the bit before the "/" in the "x/y" rating
                                        try:
                                            rating = float(outcome[0])
                                            got_rating = True
                                            if rating < min_rating:
                                                min_rating = rating
                                            if rating < MIN_RATING:
                                                return_value += 1
                                        except ValueError:
                                            # Can't have been a rating line
                                            pass
                                if got_rating:
                                    if rating < MIN_RATING:
                                        reporter.event(u_report.EVENT_TYPE_CHECK,
                                                       u_report.EVENT_ERROR,
                                                       "rating {} < minimum ({})".  \
                                                       format(rating, MIN_RATING))
                                        for line in text.splitlines():
                                            line = line.strip().decode()
                                            if line:
                                                reporter.event_extra_information(line)
                                else:
                                    reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                                                   u_report.EVENT_FAILED,
                                                   "Pylint returned no rating for file \"{}\"". \
                                                   format(py_file))
                                    printer.string("{}Pylint returned no rating.". \
                                                   format(prompt))
                                    # No rating returned, flag an error
                                    return_value += 1
                            except subprocess.CalledProcessError as error:
                                reporter.event(u_report.EVENT_TYPE_CHECK,
                                               u_report.EVENT_FAILED)
                                printer.string("{}Pylint returned error {}:".
                                               format(prompt, error.returncode))
                                for line in error.output.splitlines():
                                    line = line.strip().decode()
                                    if line:
                                        reporter.event_extra_information(line)
                                        printer.string("{}{}".format(prompt, line))
            else:
                # Flag an error if a path doesn't exist
                reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                               u_report.EVENT_FAILED,
                               "path {} does not exit".format(abs_py_path))
                printer.string("{}path \"{}\" does not exist.".   \
                               format(prompt, abs_py_path))
                return_value += 1

        printer.string("{}Pylint check complete, minimum rating {}.".
                       format(prompt, min_rating))
        if min_rating < MIN_RATING:
            reporter.event(u_report.EVENT_TYPE_CHECK,
                           u_report.EVENT_FAILED)
        else:
            reporter.event(u_report.EVENT_TYPE_CHECK,
                           u_report.EVENT_PASSED)

    else:
        reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                       u_report.EVENT_FAILED,
                       "there is a problem with the Pylint installation")

    return return_value
Exemplo n.º 21
0
def session_run(database, instances, filter_string,
                ubxlib_dir, working_dir, clean,
                summary_report_file, test_report_file, debug_file,
                process_pool, session_name=None,
                print_queue=None, print_queue_prompt=None,
                abort_on_first_failure=False, unity_dir=None):
    '''Start a session running the given instances'''
    session = {}
    summary_report_file_path = None
    test_report_file_path = None
    debug_file_path = None
    return_value = 0
    local_agent = False
    agent_context = None

    with CONTEXT_LOCK:

        # Start the agent if not already running
        agent_context = get()
        if agent_context:
            if print_queue:
                agent_context["print_thread"].add_forward_queue(print_queue, print_queue_prompt)
        else:
            return_value = -1
            # HW reset is false when the agent is started implicitly:
            # it is up to the caller to call agent.start() explicitly
            # if it wants a HW reset
            if start(print_queue, hw_reset=False):
                return_value = 0
                agent_context = get()
                local_agent = True

        if agent_context:
            printer = agent_context["printer"]

            # Name the session and add it to the session list
            session["id"] = agent_context["next_session_id"]
            agent_context["next_session_id"] += 1
            session["name"] = "session " + str(session["id"])
            if session_name:
                session["name"] = session_name

            # Set a flag to indicate that the session is
            # running: processes can watch this and, if it is
            # cleared, they must exit at the next opportunity
            session["running_flag"] = CONTEXT_MANAGER.Event()
            session["running_flag"].set()
            session["process_running_count"] = 0
            session["processes"] = []
            agent_context["sessions"].append(session)
            agent_context["session_running_count"] += 1

            # Launch a thread that manages reporting
            # from multiple sources
            session["report_queue"] = None
            session["reporter"] = None
            session["report_thread"] = None
            session["summary_report_handle"] = None
            if summary_report_file:
                summary_report_file_path = working_dir + os.sep + summary_report_file
                session["summary_report_handle"] = open(summary_report_file_path, "w")
                if session["summary_report_handle"]:
                    printer.string("{}writing summary report to \"{}\".".  \
                                  format(PROMPT, summary_report_file_path))
                else:
                    printer.string("{}unable to open file \"{}\" for summary report.".   \
                                   format(PROMPT, summary_report_file_path))
                session["report_queue"] = agent_context["manager"].Queue()
                session["report_thread"] = u_report.ReportThread(session["report_queue"],
                                                                 session["summary_report_handle"])
                session["report_thread"].start()
                session["reporter"] = u_report.ReportToQueue(session["report_queue"], None, None,
                                                             agent_context["printer"])
                session["reporter"].open()

            # Add any new platform locks required for these instances
            create_platform_locks(database, instances,
                                  agent_context["manager"],
                                  agent_context["platform_locks"])

            # Set up all the instances
            for instance in instances:
                # Provide a working directory that is unique
                # for each instance and make sure it exists
                if working_dir:
                    this_working_dir = working_dir + os.sep +       \
                                       INSTANCE_DIR_PREFIX + \
                                       u_utils.get_instance_text(instance)
                else:
                    this_working_dir = os.getcwd() + os.sep +       \
                                       INSTANCE_DIR_PREFIX + \
                                       u_utils.get_instance_text(instance)

                if not os.path.isdir(this_working_dir):
                    os.makedirs(this_working_dir)
                # Only clean the working directory if requested
                if clean:
                    u_utils.deltree(this_working_dir, printer, PROMPT)
                    os.makedirs(this_working_dir)

                # Create the file paths for this instance
                if summary_report_file:
                    summary_report_file_path = this_working_dir + os.sep + summary_report_file
                if test_report_file:
                    test_report_file_path = this_working_dir + os.sep + test_report_file
                if debug_file:
                    debug_file_path = this_working_dir + os.sep + debug_file

                # Start u_run.main in each worker thread
                process = {}
                process["platform"] = u_data.get_platform_for_instance(database, instance)
                process["instance"] = instance
                # Create a flag to be set by u_run. while the process is running
                process["running_flag"] = CONTEXT_MANAGER.Event()
                process["platform_lock"] = None
                process["connection_lock"] = u_connection.get_lock(instance)
                for platform_lock in agent_context["platform_locks"]:
                    if process["platform"] == platform_lock["platform"]:
                        process["platform_lock"] = platform_lock["lock"]
                        break

                process["handle"] = process_pool.apply_async(u_run.main,
                                                             (database, instance,
                                                              filter_string, True,
                                                              ubxlib_dir,
                                                              this_working_dir,
                                                              process["connection_lock"],
                                                              process["platform_lock"],
                                                              agent_context["misc_locks"],
                                                              agent_context["print_queue"],
                                                              session["report_queue"],
                                                              summary_report_file_path,
                                                              test_report_file_path,
                                                              debug_file_path,
                                                              session["running_flag"],
                                                              process["running_flag"],
                                                              unity_dir))
                session["process_running_count"] += 1
                session["processes"].append(process)

    # The lock is released while we're running so that others can get in
    if agent_context:
        try:
            # IMPORTANT: need to be careful here with the bits of context
            # referenced while the context lock is released. Stick to things
            # within a session (or a process of a session) and don't remove
            # sessions.  That way it won't conflict with other calls into this
            # agent.

            # Wait for all the launched processes to complete
            printer.string("{}all instances now launched.".format(PROMPT))
            loop_count = 0
            while agent_context.is_alive() and (session["process_running_count"] > 0):
                for process in session["processes"]:
                    instance_text = u_utils.get_instance_text(process["instance"])
                    if not "stopped" in process and process["handle"].ready():
                        try:
                            # If the return value has gone negative, i.e.
                            # an infrastructure failure, leave it there,
                            # else add the number of test failures to it
                            if (return_value >= 0 and process["handle"].get() > 0) or \
                                (return_value <= 0 and process["handle"].get() < 0):
                                return_value += process["handle"].get()
                            if (return_value != 0) and abort_on_first_failure:
                                session["running_flag"].clear()
                                printer.string("{}an instance has failed, aborting"    \
                                               " (gracefully, might take a while)"     \
                                               " as requested...".                     \
                                               format(PROMPT))
                                abort_on_first_failure = False
                        except Exception as ex:
                            # If an instance threw an exception then flag an
                            # infrastructure error
                            return_value = -1
                            printer.string("{}instance {} threw exception \"{}:"    \
                                           " {}\" but I can't tell you where"       \
                                           " I'm afraid.".                          \
                                           format(PROMPT, instance_text,
                                                  type(ex).__name__, str(ex)))
                            if session["reporter"]:
                                session["reporter"].event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                                                          u_report.EVENT_FAILED,
                                                          "instance {} threw exception \"{}: {}\"". \
                                                          format(instance_text, type(ex).__name__,
                                                          str(ex)))
                        process["stopped"] = True
                        session["process_running_count"] -= 1
                        if session["process_running_count"] <= 0:
                            session["stopped"] = True
                    if not process["handle"].ready() and                         \
                       (loop_count == STILL_RUNNING_REPORT_SECONDS):
                        printer.string("{}instance {} still running.".           \
                                       format(PROMPT, instance_text))
                loop_count += 1
                if loop_count > STILL_RUNNING_REPORT_SECONDS:
                    loop_count = 0
                sleep(1)
        except KeyboardInterrupt:
            # Start things cleaning up
            session["running_flag"].clear()
            raise KeyboardInterrupt from ex

    #  Now need to lock again while we're manipulating stuff
    with CONTEXT_LOCK:

        if agent_context:
            # Remove the session from the list
            idx_to_remove = None
            for idx, item in enumerate(agent_context["sessions"]):
                if item["id"] == session["id"]:
                    idx_to_remove = idx
                    break
            if idx_to_remove is not None:
                agent_context["session_running_count"] -= 1
                agent_context["sessions"].pop(idx_to_remove)

            # Tidy up
            if session["reporter"]:
                session["reporter"].event_extra_information("return value overall {} (0 = success," \
                                                            " negative = probable infrastructure"   \
                                                            " failure, positive = failure(s) (may"  \
                                                            " still be due to infrastructure))".    \
                                                            format(return_value))
                session["reporter"].close()
            if session["report_thread"]:
                session["report_thread"].stop_thread()
                session["report_thread"].join()
                session["report_thread"] = None
            if session["summary_report_handle"]:
                session["summary_report_handle"].close()
                session["summary_report_handle"] = None

            printer.string("{}run(s) complete, return value {}.".
                           format(PROMPT, return_value))
            if local_agent:
                stop()
            else:
                if print_queue:
                    agent_context["print_thread"].remove_forward_queue(print_queue)

    return return_value
Exemplo n.º 22
0
def run(instance, mcu, toolchain, connection, connection_lock,
        platform_lock, misc_locks, clean, defines, ubxlib_dir,
        working_dir, printer, reporter, test_report_handle):
    '''Build/run on ESP-IDF'''
    return_value = -1
    instance_text = u_utils.get_instance_text(instance)
    filter_string = "*\r\n"

    # No issues with running in parallel on ESP-IDF
    del platform_lock

    # Only one toolchain for ESP-IDF
    del toolchain

    prompt = PROMPT + instance_text + ": "

    # Print out what we've been told to do
    text = "running ESP-IDF for " + mcu
    if connection and connection["serial_port"]:
        text += ", on serial port " + connection["serial_port"]
    if clean:
        text += ", clean build"
    if defines:
        text += ", with #define(s)"
        for idx, define in enumerate(defines):
            if idx == 0:
                text += " \"" + define + "\""
            else:
                text += ", \"" + define + "\""
    if ubxlib_dir:
        text += ", ubxlib directory \"" + ubxlib_dir + "\""
    if working_dir:
        text += ", working directory \"" + working_dir + "\""
    printer.string("{}{}.".format(prompt, text))

    reporter.event(u_report.EVENT_TYPE_BUILD,
                   u_report.EVENT_START,
                   "ESP-IDF")
    printer.string("{}CD to {}...".format(prompt, working_dir))
    with u_utils.ChangeDir(working_dir):
        # Fetch ESP-IDF into the right sub directory
        # and install the tools
        esp_idf_location = get_esp_idf_location(instance)
        esp_idf_dir = ESP_IDF_ROOT + os.sep + esp_idf_location["subdir"]
        if esp_idf_location:
            system_lock = None
            if misc_locks and ("system_lock" in misc_locks):
                system_lock = misc_locks["system_lock"]
            returned_env = install(esp_idf_location["url"], esp_idf_dir,
                                   esp_idf_location["branch"], system_lock,
                                   printer, prompt, reporter)
            if returned_env:
                # From here on the ESP-IDF tools need to set up
                # and use the set of environment variables
                # returned above.
                print_env(returned_env, printer, prompt)
                # Now do the build
                build_dir = working_dir + os.sep + BUILD_SUBDIR
                build_start_time = time()
                if build(esp_idf_dir, ubxlib_dir, build_dir,
                         defines, returned_env, clean,
                         printer, prompt, reporter):
                    reporter.event(u_report.EVENT_TYPE_BUILD,
                                   u_report.EVENT_PASSED,
                                   "build took {:.0f} second(s)". \
                                   format(time() - build_start_time))
                    with u_connection.Lock(connection, connection_lock,
                                           CONNECTION_LOCK_GUARD_TIME_SECONDS,
                                           printer, prompt) as locked:
                        if locked:
                            # Have seen this fail, only with Python 3 for
                            # some reason, so give it a few goes
                            reporter.event(u_report.EVENT_TYPE_DOWNLOAD,
                                           u_report.EVENT_START)
                            retries = 0
                            while not download(esp_idf_dir, ubxlib_dir, build_dir,
                                               connection["serial_port"], returned_env,
                                               printer, prompt) and (retries < 3):
                                reporter.event(u_report.EVENT_TYPE_DOWNLOAD,
                                               u_report.EVENT_WARNING,
                                               "unable to download, will retry...")
                                retries += 1
                                sleep(5)
                            if retries < 3:
                                reporter.event(u_report.EVENT_TYPE_DOWNLOAD,
                                               u_report.EVENT_COMPLETE)
                                reporter.event(u_report.EVENT_TYPE_TEST,
                                               u_report.EVENT_START)
                                # Search the defines list to see if it includes a
                                # "U_CFG_APP_FILTER=blah" item.  On ESP32 the tests
                                # that are run are not selected at compile time,
                                # they are selected by sending the "blah" string
                                # over the COM port where it must match a "module name",
                                # a thing in [square brackets] which our naming convention
                                # dictates will be an API name (e.g. "port") or "example".
                                for define in defines:
                                    tmp = u_utils.FILTER_MACRO_NAME + "="
                                    if define.startswith(tmp):
                                        filter_string = define[len(tmp):]
                                        reporter.event(u_report.EVENT_TYPE_TEST,
                                                       u_report.EVENT_INFORMATION,
                                                       "only running module \"" +
                                                       filter_string + "\"")
                                        printer.string("{} will use filter [{}].".   \
                                                       format(prompt, filter_string))
                                        # Add the top and tail it needs for sending
                                        filter_string = "[" + filter_string + "]\r\n"
                                        break
                                # Open the COM port to get debug output
                                serial_handle = u_utils.open_serial(connection["serial_port"],
                                                                    115200, printer, prompt)
                                if serial_handle is not None:
                                    # Monitor progress
                                    return_value = u_monitor.main(serial_handle,
                                                                  u_monitor.CONNECTION_SERIAL,
                                                                  RUN_GUARD_TIME_SECONDS,
                                                                  RUN_INACTIVITY_TIME_SECONDS,
                                                                  instance, printer, reporter,
                                                                  test_report_handle,
                                                                  send_string=filter_string)
                                    serial_handle.close()
                                else:
                                    reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                                                   u_report.EVENT_FAILED,
                                                   "unable to open serial port " +      \
                                                   connection["serial_port"])
                                if return_value == 0:
                                    reporter.event(u_report.EVENT_TYPE_TEST,
                                                   u_report.EVENT_COMPLETE)
                                else:
                                    reporter.event(u_report.EVENT_TYPE_TEST,
                                                   u_report.EVENT_FAILED)
                            else:
                                reporter.event(u_report.EVENT_TYPE_DOWNLOAD,
                                               u_report.EVENT_FAILED,
                                               "unable to download to the target")
                        else:
                            reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                                           u_report.EVENT_FAILED,
                                           "unable to lock a connection")
                else:
                    reporter.event(u_report.EVENT_TYPE_BUILD,
                                   u_report.EVENT_FAILED,
                                   "unable to build, check debug log for details")
            else:
                reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                               u_report.EVENT_FAILED,
                               "tools installation failed")
        else:
            reporter.event(u_report.EVENT_TYPE_INFRASTRUCTURE,
                           u_report.EVENT_FAILED,
                           "don't have ESP-IDF URL for this instance")
            printer.string("{}error: don't have ESP-IDF URL instance {}.".
                           format(prompt, instance_text))

    return return_value
Exemplo n.º 23
0
def main(database, instance, filter_string, clean, ubxlib_dir, working_dir,
         connection_lock, platform_lock, misc_locks, print_queue, report_queue,
         summary_report_file_path, test_report_file_path, debug_file_path,
         keep_going_flag, running_flag, unity_dir):
    '''Main as a function'''
    return_value = 1
    connection = None
    platform = None
    summary_report_handle = None
    test_report_handle = None
    debug_handle = None
    instance_text = u_utils.get_instance_text(instance)
    printer_text = []

    if running_flag:
        # We're off
        running_flag.set()

    # Create the files
    if summary_report_file_path:
        summary_report_handle = open(summary_report_file_path, "w")
        if summary_report_handle:
            printer_text.append("{}writing summary report to \"{}\".".  \
                                format(PROMPT, summary_report_file_path))
        else:
            printer_text.append("{}unable to open file \"{}\" for summary report.".   \
                                format(PROMPT, summary_report_file_path))
    if test_report_file_path:
        test_report_handle = open(test_report_file_path, "w")
        if test_report_handle:
            printer_text.append("{}writing test report to \"{}\".".  \
                                format(PROMPT, test_report_file_path))
        else:
            printer_text.append("{}unable to open file \"{}\" for test report.".   \
                                format(PROMPT, test_report_file_path))
    if debug_file_path:
        debug_handle = open(debug_file_path, "w")
        if debug_handle:
            printer_text.append("{}writing log output to \"{}\".".  \
                                format(PROMPT, debug_file_path))
        else:
            printer_text.append("{}unable to open file \"{}\" for log"       \
                                " output.".format(PROMPT, debug_file_path))

    # Create a printer and send the initial printer text there
    printer = u_utils.PrintToQueue(print_queue, debug_handle, True)
    for line in printer_text:
        printer.string(line)

    # Print out what we've been told to do
    text = "running instance " + instance_text
    if filter_string:
        text += " with filter_string \"" + filter_string + "\""
    if clean:
        text += ", clean build"
    if ubxlib_dir:
        text += ", ubxlib directory \"" + ubxlib_dir + "\""
    if working_dir:
        text += ", working directory \"" + working_dir + "\""
    printer.string("{}{}.".format(PROMPT, text))

    # Get the connection for this instance
    connection = u_connection.get_connection(instance)

    # Get the #defines for this instance
    defines = u_data.get_defines_for_instance(database, instance)
    if not defines:
        defines = []

    # If there is a cellular module on this instance, add its
    # name to the defines list
    cellular_module_name = u_data.get_cellular_module_for_instance(
        database, instance)
    if cellular_module_name:
        defines.append("U_CFG_TEST_CELL_MODULE_TYPE=" + cellular_module_name)

    # If there is a short-range module on this instance, add its
    # name to the defines list
    short_range_module_name = u_data.get_short_range_module_for_instance(
        database, instance)
    if short_range_module_name:
        defines.append("U_CFG_TEST_SHORT_RANGE_MODULE_TYPE=" +
                       short_range_module_name)

    # If there is a GNSS module on this instance, add its
    # name to the defines list
    gnss_module_name = u_data.get_gnss_module_for_instance(database, instance)
    if gnss_module_name:
        defines.append("U_CFG_TEST_GNSS_MODULE_TYPE=" + gnss_module_name)

    # Also, when running testing it is best to run the
    # the "port" tests first as, if there's a problem with the
    # port, you want to notice it first.
    # This also acts as a flag to indicate that we're running
    # under u_runner automation
    defines.append("U_RUNNER_TOP_STR=port")

    # When running tests on cellular LTE modules, so
    # SARA-R4 or SARA-R5, we need to set the RF band we
    # are running in to NOT include the public network,
    # since otherwise the modules can sometimes wander off
    # onto it.
    defines.append("U_CELL_TEST_CFG_BANDMASK1=0x000010ULL")

    # Defines may be provided via an environment
    # variable, in a list separated with semicolons, e.g.:
    # set U_UBXLIB_DEFINES=THING_1;ANOTHER_THING=123;ONE_MORE=boo
    # Add these in.
    if UBXLIB_DEFINES_VAR in environ and environ[UBXLIB_DEFINES_VAR].strip():
        defines.extend(environ[UBXLIB_DEFINES_VAR].strip().split(";"))

    # Merge in any filter string we might have
    defines = merge_filter(defines, filter_string)

    # It is sometimes useful for the platform tools to be able
    # to detect that they are running under automation (e.g. this
    # is used to switch ESP-IDF to using u_runner rather than the
    # usual ESP-IDF unit test menu system).
    # For this purpose we add ENV_UBXLIB_AUTO to the environment
    environ[ENV_UBXLIB_AUTO] = "1"

    # With a reporter
    with u_report.ReportToQueue(report_queue, instance, summary_report_handle,
                                printer) as reporter:
        if connection:
            # Run the type of build/test specified
            platform = u_data.get_platform_for_instance(database, instance)
            if platform:
                # Since there will be many different platforms, add
                # the description from the database to the report
                description = u_data.get_description_for_instance(
                    database, instance)
                mcu = u_data.get_mcu_for_instance(database, instance)
                # Zephyr requires a board name also
                board = u_data.get_board_for_instance(database, instance)
                toolchain = u_data.get_toolchain_for_instance(
                    database, instance)
                if description:
                    reporter.event(u_report.EVENT_TYPE_BUILD,
                                   u_report.EVENT_NAME, description)
                # A NOTE ABOUT keep_going_flag: the keep_going_flag is passed
                # into any instance that will take more than a few seconds
                # to run.  Each instance receiving it should ensure that
                # anything that can be safely stopped and is likely to run
                # for more than about 10ish seconds should be stopped
                # if the flag is cleared, in case the user decides to abort
                # a test run.
                if platform.lower() == "esp-idf":
                    return_value = u_run_esp_idf.run(
                        instance, mcu, toolchain, connection, connection_lock,
                        platform_lock, misc_locks, clean, defines, ubxlib_dir,
                        working_dir, printer, reporter, test_report_handle,
                        keep_going_flag)
                elif platform.lower() == "nrf5sdk":
                    return_value = u_run_nrf5sdk.run(
                        instance, mcu, toolchain, connection, connection_lock,
                        platform_lock, misc_locks, clean, defines, ubxlib_dir,
                        working_dir, printer, reporter, test_report_handle,
                        keep_going_flag, unity_dir)
                elif platform.lower() == "zephyr":
                    return_value = u_run_zephyr.run(
                        instance, mcu, board, toolchain, connection,
                        connection_lock, platform_lock, misc_locks, clean,
                        defines, ubxlib_dir, working_dir, printer, reporter,
                        test_report_handle, keep_going_flag)
                elif platform.lower() == "stm32cube":
                    return_value = u_run_stm32cube.run(
                        instance, mcu, toolchain, connection, connection_lock,
                        platform_lock, misc_locks, clean, defines, ubxlib_dir,
                        working_dir, printer, reporter, test_report_handle,
                        keep_going_flag, unity_dir)
                elif platform.lower() == "arduino":
                    return_value = u_run_arduino.run(
                        instance, mcu, board, toolchain, connection,
                        connection_lock, platform_lock, misc_locks, clean,
                        defines, ubxlib_dir, working_dir, printer, reporter,
                        test_report_handle, keep_going_flag, unity_dir)
                else:
                    printer.string("{}don't know how to handle platform \"{}\".".    \
                                   format(PROMPT, platform))
            else:
                printer.string(
                    "{}this instance has no platform.".format(PROMPT))
        else:
            # No connection, must be a local thing
            if instance[0] == 0:
                return_value = u_run_lint.run(instance, defines, ubxlib_dir,
                                              working_dir, printer, reporter,
                                              keep_going_flag, unity_dir)
            elif instance[0] == 1:
                return_value = u_run_doxygen.run(instance, ubxlib_dir,
                                                 working_dir, printer,
                                                 reporter)
            elif instance[0] == 2:
                return_value = u_run_astyle.run(instance, ubxlib_dir,
                                                working_dir, printer, reporter)
            elif instance[0] == 3:
                return_value = u_run_pylint.run(instance, ubxlib_dir,
                                                working_dir, printer, reporter,
                                                keep_going_flag)
            elif instance[0] == 4:
                return_value = u_run_static_size.run(instance, defines,
                                                     ubxlib_dir, working_dir,
                                                     printer, reporter,
                                                     keep_going_flag)
            elif instance[0] == 5:
                return_value = u_run_no_floating_point.run(
                    instance, defines, ubxlib_dir, working_dir, printer,
                    reporter, keep_going_flag)
            elif instance[0] == 6:
                printer.string("{}reserved, nothing to do.".format(PROMPT))
                return_value = 0
            elif instance[0] == 7:
                printer.string("{}reserved, nothing to do.".format(PROMPT))
                return_value = 0
            elif instance[0] == 8:
                printer.string("{}reserved, nothing to do.".format(PROMPT))
                return_value = 0
            elif instance[0] == 9:
                printer.string("{}reserved, nothing to do.".format(PROMPT))
                return_value = 0
            else:
                printer.string("{}instance {} has no connection and isn't a"     \
                               " local thing.".format(PROMPT, instance_text))

    if platform:
        printer.string("{}instance {}, platform {} EXITING with"    \
                       " return value {}.".format(PROMPT, instance_text, platform,
                                                  return_value))
    elif connection:
        printer.string("{}instance {}, EXITING with return value {}.". \
                       format(PROMPT, instance_text, return_value))
    else:
        printer.string("{}instance {} EXITING with return value {}.".        \
                       format(PROMPT, instance_text, return_value))

    if summary_report_handle:
        summary_report_handle.close()
    if test_report_handle:
        test_report_handle.close()
    if debug_handle:
        debug_handle.close()

    if running_flag:
        # We're done
        running_flag.clear()

    return return_value
Exemplo n.º 24
0
def main(database, instance, filter_string, clean, ubxlib_dir, working_dir,
         connection_lock, platform_lock, misc_locks, print_queue, report_queue,
         summary_report_file_path, test_report_file_path, debug_file_path):
    '''Main as a function'''
    return_value = 1
    connection = None
    platform = None
    summary_report_handle = None
    test_report_handle = None
    debug_handle = None
    instance_text = u_utils.get_instance_text(instance)
    printer_text = []

    signal(SIGINT, signal_handler)

    # Create the files
    if summary_report_file_path:
        summary_report_handle = open(summary_report_file_path, "w")
        if summary_report_handle:
            printer_text.append("{}writing summary report to \"{}\".".  \
                                format(PROMPT, summary_report_file_path))
        else:
            printer_text.append("{}unable to open file \"{}\" for summary report.".   \
                                format(PROMPT, summary_report_file_path))
    if test_report_file_path:
        test_report_handle = open(test_report_file_path, "w")
        if test_report_handle:
            printer_text.append("{}writing test report to \"{}\".".  \
                                format(PROMPT, test_report_file_path))
        else:
            printer_text.append("{}unable to open file \"{}\" for test report.".   \
                                format(PROMPT, test_report_file_path))
    if debug_file_path:
        debug_handle = open(debug_file_path, "w")
        if debug_handle:
            printer_text.append("{}writing log output to \"{}\".".  \
                                format(PROMPT, debug_file_path))
        else:
            printer_text.append("{}unable to open file \"{}\" for log"       \
                                " output.".format(PROMPT, debug_file_path))

    # Create a printer and send the initial printer text there
    printer = u_utils.PrintToQueue(print_queue, debug_handle, True)
    for line in printer_text:
        printer.string(line)

    # Print out what we've been told to do
    text = "running instance " + instance_text
    if filter_string:
        text += " with filter_string \"" + filter_string + "\""
    if clean:
        text += ", clean build"
    if ubxlib_dir:
        text += ", ubxlib directory \"" + ubxlib_dir + "\""
    if working_dir:
        text += ", working directory \"" + working_dir + "\""
    printer.string("{}{}.".format(PROMPT, text))

    # Get the connection for this instance
    connection = u_connection.get_connection(instance)

    # Get the #defines for this instance
    defines = u_data.get_defines_for_instance(database, instance)
    if not defines:
        defines = []
    if filter_string:
        # The filter_string is just another #define so
        # add it to the list
        defines.append(u_utils.FILTER_MACRO_NAME + "=" + \
                       filter_string)
    # If there is a cellular module on this instance, add its
    # name to the defines list
    cellular_module_name = u_data.get_cellular_module_for_instance(
        database, instance)
    if cellular_module_name:
        defines.append("U_CFG_TEST_CELL_MODULE_TYPE=" + cellular_module_name)

    # If there is a short-range module on this instance, add its
    # name to the defines list
    short_range_module_name = u_data.get_short_range_module_for_instance(
        database, instance)
    if short_range_module_name:
        defines.append("U_CFG_TEST_SHORT_RANGE_MODULE_TYPE=" +
                       short_range_module_name)

    # Also, when running testing it is best to run the
    # the "port" tests first as, if there's a problem with the
    # port, you want to notice it first.
    defines.append("U_RUNNER_TOP_STR=port")

    # With a reporter
    with u_report.ReportToQueue(report_queue, instance, summary_report_handle,
                                printer) as reporter:
        if connection:
            # Run the type of build/test specified
            platform = u_data.get_platform_for_instance(database, instance)
            if platform:
                # Since there will be many different platforms, add
                # the description from the database to the report
                description = u_data.get_description_for_instance(
                    database, instance)
                mcu = u_data.get_mcu_for_instance(database, instance)
                toolchain = u_data.get_toolchain_for_instance(
                    database, instance)
                if description:
                    reporter.event(u_report.EVENT_TYPE_BUILD,
                                   u_report.EVENT_NAME, description)
                if platform.lower() == "esp-idf":
                    return_value = u_run_esp_idf.run(
                        instance, mcu, toolchain, connection, connection_lock,
                        platform_lock, misc_locks, clean, defines, ubxlib_dir,
                        working_dir, printer, reporter, test_report_handle)
                elif platform.lower() == "nrf5sdk":
                    return_value = u_run_nrf5sdk.run(
                        instance, mcu, toolchain, connection, connection_lock,
                        platform_lock, misc_locks, clean, defines, ubxlib_dir,
                        working_dir, printer, reporter, test_report_handle)
                elif platform.lower() == "zephyr":
                    return_value = u_run_zephyr.run(
                        instance, mcu, toolchain, connection, connection_lock,
                        platform_lock, misc_locks, clean, defines, ubxlib_dir,
                        working_dir, printer, reporter, test_report_handle)
                elif platform.lower() == "stm32cube":
                    return_value = u_run_stm32cube.run(
                        instance, mcu, toolchain, connection, connection_lock,
                        platform_lock, misc_locks, clean, defines, ubxlib_dir,
                        working_dir, printer, reporter, test_report_handle)
                else:
                    printer.string("{}don't know how to handle platform \"{}\".".    \
                                   format(PROMPT, platform))
            else:
                printer.string(
                    "{}this instance has no platform.".format(PROMPT))
        else:
            # No connection, must be a local thing
            if instance[0] == 0:
                return_value = u_run_lint.run(instance, defines, ubxlib_dir,
                                              working_dir, printer, reporter)
            elif instance[0] == 1:
                return_value = u_run_doxygen.run(instance, ubxlib_dir,
                                                 working_dir, printer,
                                                 reporter)
            elif instance[0] == 2:
                return_value = u_run_astyle.run(instance, ubxlib_dir,
                                                working_dir, printer, reporter)
            elif instance[0] == 3:
                return_value = u_run_pylint.run(instance, ubxlib_dir,
                                                working_dir, printer, reporter)
            elif instance[0] == 4:
                return_value = u_run_lint.run(instance, defines, ubxlib_dir,
                                              working_dir, printer, reporter)
            elif instance[0] == 5:
                printer.string("{}reserved, nothing to do.".format(PROMPT))
                return_value = 0
            elif instance[0] == 6:
                printer.string("{}reserved, nothing to do.".format(PROMPT))
                return_value = 0
            elif instance[0] == 7:
                printer.string("{}reserved, nothing to do.".format(PROMPT))
                return_value = 0
            elif instance[0] == 8:
                printer.string("{}reserved, nothing to do.".format(PROMPT))
                return_value = 0
            elif instance[0] == 9:
                printer.string("{}reserved, nothing to do.".format(PROMPT))
                return_value = 0
            else:
                printer.string("{}instance {} has no connection and isn't a"     \
                               " local thing.".format(PROMPT, instance_text))

    if platform:
        printer.string("{}instance {}, platform {} EXITING with"    \
                       " return value {}.".format(PROMPT, instance_text, platform,
                                                  return_value))
    elif connection:
        printer.string("{}instance {}, EXITING with return value {}.". \
                       format(PROMPT, instance_text, return_value))
    else:
        printer.string("{}instance {} EXITING with return value {}.".        \
                       format(PROMPT, instance_text, return_value))

    if summary_report_handle:
        summary_report_handle.close()
    if test_report_handle:
        test_report_handle.close()
    if debug_handle:
        debug_handle.close()

    return return_value