示例#1
0
def run(args, command_path=None):
    import sys
    tests = []
    stdtty = console.save()
    opts = None
    default_exefilter = '*.exe'
    try:
        optargs = {
            '--rtems-tools':
            'The path to the RTEMS tools',
            '--rtems-bsp':
            'The RTEMS BSP to run the test on',
            '--user-config':
            'Path to your local user configuration INI file',
            '--report-path':
            'Report output base path (file extension will be added)',
            '--report-format':
            'Formats in which to report test results in addition to txt: json',
            '--log-mode':
            'Reporting modes, failures (default),all,none',
            '--list-bsps':
            'List the supported BSPs',
            '--debug-trace':
            'Debug trace based on specific flags (console,gdb,output,cov)',
            '--filter':
            'Glob that executables must match to run (default: ' +
            default_exefilter + ')',
            '--stacktrace':
            'Dump a stack trace on a user termination (^C)',
            '--coverage':
            'Perform coverage analysis of test executables.'
        }
        mailer.append_options(optargs)
        opts = options.load(args, optargs=optargs, command_path=command_path)
        mail = None
        output = None
        if opts.find_arg('--mail'):
            mail = mailer.mail(opts)
            # Request these now to generate any errors.
            from_addr = mail.from_address()
            smtp_host = mail.smtp_host()
            to_addr = opts.find_arg('--mail-to')
            if to_addr:
                to_addr = to_addr[1]
            else:
                to_addr = '*****@*****.**'
            output = log_capture()
        report_location = opts.find_arg('--report-path')
        if report_location is not None:
            report_location = report_location[1]

        report_formats = opts.find_arg('--report-format')
        if report_formats is not None:
            if len(report_formats) != 2:
                raise error.general('invalid RTEMS report formats option')
            report_formats = report_formats[1].split(',')
            check_report_formats(report_formats, report_location)
        else:
            report_formats = []
        log.notice('RTEMS Testing - Tester, %s' % (version.string()))
        if opts.find_arg('--list-bsps'):
            bsps.list(opts)
        exe_filter = opts.find_arg('--filter')
        if exe_filter:
            exe_filter = exe_filter[1]
        else:
            exe_filter = default_exefilter
        opts.log_info()
        log.output('Host: ' + host.label(mode='all'))
        executables = find_executables(opts.params(), exe_filter)
        debug_trace = opts.find_arg('--debug-trace')
        if debug_trace:
            if len(debug_trace) != 1:
                debug_trace = debug_trace[1]
            else:
                raise error.general(
                    'no debug flags, can be: console,gdb,output,cov')
        else:
            debug_trace = ''
        opts.defaults['exe_trace'] = debug_trace
        job_trace = 'jobs' in debug_trace.split(',')
        rtems_tools = opts.find_arg('--rtems-tools')
        if rtems_tools is not None:
            if len(rtems_tools) != 2:
                raise error.general('invalid RTEMS tools option')
            rtems_tools = rtems_tools[1]
        bsp = opts.find_arg('--rtems-bsp')
        if bsp is None or len(bsp) != 2:
            raise error.general('RTEMS BSP not provided or an invalid option')
        bsp = config.load(bsp[1], opts)
        bsp_config = opts.defaults.expand(opts.defaults['tester'])
        coverage_enabled = opts.find_arg('--coverage')
        if coverage_enabled:
            cov_trace = 'cov' in debug_trace.split(',')
            if len(coverage_enabled) == 2:
                coverage_runner = coverage.coverage_run(
                    opts.defaults,
                    executables,
                    rtems_tools,
                    symbol_set=coverage_enabled[1],
                    trace=cov_trace)
            else:
                coverage_runner = coverage.coverage_run(opts.defaults,
                                                        executables,
                                                        rtems_tools,
                                                        trace=cov_trace)
        log_mode = opts.find_arg('--log-mode')
        if log_mode:
            if log_mode[1] != 'failures' and \
                    log_mode[1] != 'all' and \
                    log_mode[1] != 'none':
                raise error.general('invalid report mode')
            log_mode = log_mode[1]
        else:
            log_mode = 'failures'
        if len(executables) == 0:
            raise error.general('no executables supplied')
        start_time = datetime.datetime.now()
        total = len(executables)
        reports = report.report(total)
        reporting = 1
        jobs = int(opts.jobs(opts.defaults['_ncpus']))
        exe = 0
        finished = []
        if jobs > len(executables):
            jobs = len(executables)
        while exe < total or len(tests) > 0:
            if exe < total and len(tests) < jobs:
                tst = test_run(exe + 1, total, reports, executables[exe],
                               rtems_tools, bsp, bsp_config, opts)
                exe += 1
                tests += [tst]
                if job_trace:
                    _job_trace(tst, 'create', total, exe, tests, reporting)
                tst.run()
            else:
                dead = [t for t in tests if not t.is_alive()]
                tests[:] = [t for t in tests if t not in dead]
                for tst in dead:
                    if job_trace:
                        _job_trace(tst, 'dead', total, exe, tests, reporting)
                    finished += [tst]
                    tst.reraise()
                del dead
                if len(tests) >= jobs or exe >= total:
                    time.sleep(0.250)
                if len(finished):
                    reporting = report_finished(reports, log_mode, reporting,
                                                finished, job_trace)
        finished_time = datetime.datetime.now()
        reporting = report_finished(reports, log_mode, reporting, finished,
                                    job_trace)
        if reporting < total:
            log.warning('finished jobs does match: %d' % (reporting))
            report_finished(reports, log_mode, -1, finished, job_trace)
        reports.summary()
        end_time = datetime.datetime.now()
        average_time = 'Average test time: %s' % (str(
            (end_time - start_time) / total))
        total_time = 'Testing time     : %s' % (str(end_time - start_time))
        log.notice(average_time)
        log.notice(total_time)
        for report_format in report_formats:
            report_formatters[report_format](
                args, reports, start_time, end_time, total,
                '.'.join([report_location, report_format]))

        if mail is not None and output is not None:
            m_arch = opts.defaults.expand('%{arch}')
            m_bsp = opts.defaults.expand('%{bsp}')
            build = ' %s:' % (reports.get_config('build', not_found=''))
            subject = '[rtems-test] %s/%s:%s %s' % (
                m_arch, m_bsp, build, reports.score_card('short'))
            np = 'Not present in test'
            ver = reports.get_config('version', not_found=np)
            build = reports.get_config('build', not_found=np)
            tools = reports.get_config('tools', not_found=np)
            body = [
                total_time, average_time, '', 'Host', '====',
                host.label(mode='all'), '', 'Configuration', '=============',
                'Version: %s' % (ver),
                'Build  : %s' % (build),
                'Tools  : %s' % (tools), '', 'Summary', '=======', '',
                reports.score_card(), '',
                reports.failures(), 'Log', '===', ''
            ] + output.get()
            mail.send(to_addr, subject, os.linesep.join(body))
        if coverage_enabled:
            coverage_runner.run()

    except error.general as gerr:
        print(gerr)
        sys.exit(1)
    except error.internal as ierr:
        print(ierr)
        sys.exit(1)
    except error.exit:
        sys.exit(2)
    except KeyboardInterrupt:
        if opts is not None and opts.find_arg('--stacktrace'):
            print('}} dumping:', threading.active_count())
            for t in threading.enumerate():
                print('}} ', t.name)
            print(stacktraces.trace())
        log.notice('abort: user terminated')
        killall(tests)
        sys.exit(1)
    finally:
        console.restore(stdtty)
    sys.exit(0)
示例#2
0
def run(args):
    b = None
    ec = 0
    try:
        rtems.clean_windows_path()

        start = _now()
        prefix = '/opt/rtems/%s' % (rtems_version())
        tools = prefix
        build_dir = 'bsp-builds'
        logf = 'bsp-build-%s.txt' % (_now().strftime('%Y%m%d-%H%M%S'))
        config_file = rtems.bsp_configuration_file(prog=args[0])

        description = 'RTEMS BSP Builder is a BSP build tester. It builds BSPs '
        description += 'in various ways to test build regressions in the kernel. You '
        description += 'can build based on tier, architecture, or BSP. You can control '
        description += 'the profile of build with various build configuration settings.'

        argsp = argparse.ArgumentParser(prog='rtems-bsp-builder',
                                        description=description)
        argsp.add_argument('--prefix',
                           help='Prefix to build the BSP.',
                           type=str)
        argsp.add_argument('--rtems-tools',
                           help='The RTEMS tools directory.',
                           type=str)
        argsp.add_argument('--rtems', help='The RTEMS source tree.', type=str)
        argsp.add_argument('--build-path', help='Path to build in.', type=str)
        argsp.add_argument('--log', help='Log file.', type=str)
        argsp.add_argument('--config-report',
                           help='Report the configuration.',
                           type=str,
                           default=None,
                           choices=['all', 'profiles', 'builds', 'archs'])
        argsp.add_argument('--warnings-report',
                           help='Report the warnings to a file.',
                           type=str,
                           default=None)
        argsp.add_argument('--failures-report',
                           help='Report the failures to a file.',
                           type=str,
                           default=None)
        argsp.add_argument('--stop-on-error',
                           help='Stop on an error.',
                           action='store_true')
        argsp.add_argument('--no-clean',
                           help='Do not clean the build output.',
                           action='store_true')
        argsp.add_argument(
            '--profiles',
            help='Build the listed profiles (profile,profile,..).',
            type=str,
            default='tier-1')
        argsp.add_argument('--arch',
                           help='Build the architectures (arch,arch,..).',
                           type=str)
        argsp.add_argument('--bsp',
                           help='Build the BSPs (arch/bsp,arch/bsp,..).',
                           type=str)
        argsp.add_argument('--build',
                           help='Build name to build (see --config-report).',
                           type=str,
                           default='all')
        argsp.add_argument('--jobs',
                           help='Number of jobs to run.',
                           type=str,
                           default='1/%d' % (host.cpus()))
        argsp.add_argument('--dry-run',
                           help='Do not run the actual builds.',
                           action='store_true')
        mailer.add_arguments(argsp)

        opts = argsp.parse_args(args[1:])
        mail = None
        if opts.mail:
            mail = mailer.mail(opts)
            # Request these now to generate any errors.
            from_addr = mail.from_address()
            smtp_host = mail.smtp_host()
            if 'mail_to' in opts and opts.mail_to is not None:
                to_addr = opts.mail_to
            else:
                to_addr = '*****@*****.**'
        if opts.log is not None:
            logf = opts.log
        log.default = log.log([logf])
        log.notice(title())
        log.output(command_line())
        if mail:
            log.notice('Mail: from:%s to:%s smtp:%s' %
                       (from_addr, to_addr, smtp_host))

        config = rtems.configuration()
        config.load(config_file, opts.build)

        if opts.config_report:
            log.notice('Configuration Report: %s' % (opts.config_report))
            c_profiles = False
            c_builds = False
            c_archs = False
            if opts.config_report == 'all':
                c_profiles = True
                c_builds = True
                c_archs = True
            elif opts.config_report == 'profiles':
                c_profiles = True
            elif opts.config_report == 'builds':
                c_builds = True
            elif opts.config_report == 'archs':
                c_archs = True
            log.notice(config.report(c_profiles, c_builds, c_archs))
            sys.exit(0)

        if opts.rtems is None:
            raise error.general('No RTEMS source provided on the command line')
        if opts.prefix is not None:
            prefix = path.shell(opts.prefix)
        if opts.rtems_tools is not None:
            tools = path.shell(opts.rtems_tools)
        if opts.build_path is not None:
            build_dir = path.shell(opts.build_path)

        options = {
            'stop-on-error': opts.stop_on_error,
            'no-clean': opts.no_clean,
            'dry-run': opts.dry_run,
            'jobs': opts.jobs,
            'warnings-report': opts.warnings_report,
            'failures-report': opts.failures_report
        }

        b = builder(config, rtems_version(), prefix, tools,
                    path.shell(opts.rtems), build_dir, options)

        profiles = comma_split(opts.profiles)
        archs = comma_split(opts.arch)
        bsps = comma_split(opts.bsp)

        #
        # The default is build a profile.
        #
        if bsps is not None:
            if archs is not None:
                raise error.general('--arch supplied with --bsp;' \
                                    ' use --bsp=arch/bsp,arch/bsp,..')
            what = 'BSPs: %s' % (' '.join(bsps))
            b.build_bsps(bsps)
        elif archs is not None:
            what = 'Archs: %s' % (' '.join(archs))
            b.build_archs(archs)
        else:
            what = 'Profile(s): %s' % (' '.join(profiles))
            b.build_profiles(profiles)
        end = _now()

        #
        # Email the results of the build.
        #
        if mail is not None:
            subject = '[rtems-bsp-builder] %s: %s' % (str(start).split('.')[0],
                                                      what)
            t = title()
            body = t + os.linesep
            body += '=' * len(t) + os.linesep
            body += os.linesep
            body += 'Host: %s' % (os.uname()[3]) + os.linesep
            body += os.linesep
            body += command_line()
            body += os.linesep
            body += 'Total Time            : %s for %d completed job(s)' % \
                    (str(b.duration), b.jobs_completed)
            body += os.linesep
            body += 'Average BSP Build Time: %s' % (str(b.average))
            body += os.linesep + os.linesep
            body += 'Builds' + os.linesep
            body += '======' + os.linesep
            body += os.linesep.join([' ' + cb for cb in config.builds()])
            body += os.linesep + os.linesep
            body += 'Failures Report' + os.linesep
            body += '===============' + os.linesep
            body += b.results.failures_report()
            body += os.linesep
            body += 'Warnings Report' + os.linesep
            body += '===============' + os.linesep
            body += b.results.warnings_report(summary=True)
            mail.send(to_addr, subject, body)

    except error.general as gerr:
        print(gerr)
        print('BSP Build FAILED', file=sys.stderr)
        ec = 1
    except error.internal as ierr:
        print(ierr)
        print('BSP Build FAILED', file=sys.stderr)
        ec = 1
    except error.exit as eerr:
        pass
    except KeyboardInterrupt:
        log.notice('abort: user terminated')
        ec = 1
    if b is not None:
        b.results.report()
    sys.exit(ec)