Example #1
0
    def test_create_test_report(self):
        """Test create_test_report function."""
        logfile = os.path.join(self.test_prefix, 'log.txt')
        write_file(logfile, "Bazel failed with: error")
        ecs_with_res = [
            ({'spec': 'test.eb'}, {'success': True}),
            ({'spec': 'fail.eb'}, {
                'success': False,
                'err': EasyBuildError("error: bazel"),
                'traceback': "in bazel",
                'log_file': logfile,
            }),
        ]
        init_session_state = {
            'easybuild_configuration': ['EASYBUILD_DEBUG=1'],
            'environment': {'USER': '******'},
            'module_list': [{'mod_name': 'test'}],
            'system_info': {'name': 'test'},
            'time': gmtime(0),
        }
        res = create_test_report("just a test", ecs_with_res, init_session_state)
        patterns = [
            "**SUCCESS** _test.eb_",
            "**FAIL (build issue)** _fail.eb_",
            "01 Jan 1970 00:00:00",
            "EASYBUILD_DEBUG=1",
        ]
        for pattern in patterns:
            self.assertTrue(pattern in res['full'], "Pattern '%s' found in: %s" % (pattern, res['full']))

        for pattern in patterns[:2]:
            self.assertTrue(pattern in res['full'], "Pattern '%s' found in: %s" % (pattern, res['overview']))

        # mock create_gist function, we don't want to actually create a gist every time we run this test...
        def fake_create_gist(*args, **kwargs):
            return 'https://gist.github.com/test'

        easybuild.tools.testing.create_gist = fake_create_gist

        res = create_test_report("just a test", ecs_with_res, init_session_state, pr_nrs=[123], gist_log=True)

        patterns.insert(2, "https://gist.github.com/test")
        patterns.extend([
            "https://github.com/easybuilders/easybuild-easyconfigs/pull/123",
        ])
        for pattern in patterns:
            self.assertTrue(pattern in res['full'], "Pattern '%s' found in: %s" % (pattern, res['full']))

        for pattern in patterns[:3]:
            self.assertTrue(pattern in res['full'], "Pattern '%s' found in: %s" % (pattern, res['overview']))

        self.assertTrue("**SUCCESS** _test.eb_" in res['overview'])
def build_and_install_software(ecs, init_session_state, exit_on_failure=True):
    """Build and install software for all provided parsed easyconfig files."""
    # obtain a copy of the starting environment so each build can start afresh
    # we shouldn't use the environment from init_session_state, since relevant env vars might have been set since
    # e.g. via easyconfig.handle_allowed_system_deps
    init_env = copy.deepcopy(os.environ)

    res = []
    for ec in ecs:
        ec_res = {}
        try:
            (ec_res['success'], app_log,
             err) = build_and_install_one(ec, init_env)
            ec_res['log_file'] = app_log
            if not ec_res['success']:
                ec_res['err'] = EasyBuildError(err)
        except Exception, err:
            # purposely catch all exceptions
            ec_res['success'] = False
            ec_res['err'] = err
            ec_res['traceback'] = traceback.format_exc()

        # keep track of success/total count
        if ec_res['success']:
            test_msg = "Successfully built %s" % ec['spec']
        else:
            test_msg = "Build of %s failed" % ec['spec']
            if 'err' in ec_res:
                test_msg += " (err: %s)" % ec_res['err']

        # dump test report next to log file
        test_report_txt = create_test_report(test_msg, [(ec, ec_res)],
                                             init_session_state)
        if 'log_file' in ec_res and ec_res['log_file']:
            test_report_fp = "%s_test_report.md" % '.'.join(
                ec_res['log_file'].split('.')[:-1])
            parent_dir = os.path.dirname(test_report_fp)
            # parent dir for test report may not be writable at this time, e.g. when --read-only-installdir is used
            if os.stat(parent_dir).st_mode & 0200:
                write_file(test_report_fp, test_report_txt)
            else:
                adjust_permissions(parent_dir,
                                   stat.S_IWUSR,
                                   add=True,
                                   recursive=False)
                write_file(test_report_fp, test_report_txt)
                adjust_permissions(parent_dir,
                                   stat.S_IWUSR,
                                   add=False,
                                   recursive=False)

        if not ec_res['success'] and exit_on_failure:
            if 'traceback' in ec_res:
                raise EasyBuildError(ec_res['traceback'])
            else:
                raise EasyBuildError(test_msg)

        res.append((ec, ec_res))
Example #3
0
def build_and_install_software(ecs, init_session_state, exit_on_failure=True, hooks=None):
    """
    Build and install software for all provided parsed easyconfig files.

    :param ecs: easyconfig files to install software with
    :param init_session_state: initial session state, to use in test reports
    :param exit_on_failure: whether or not to exit on installation failure
    :param hooks: list of defined pre- and post-step hooks
    """
    # obtain a copy of the starting environment so each build can start afresh
    # we shouldn't use the environment from init_session_state, since relevant env vars might have been set since
    # e.g. via easyconfig.handle_allowed_system_deps
    init_env = copy.deepcopy(os.environ)

    run_hook(START, hooks)

    res = []
    for ec in ecs:
        ec_res = {}
        try:
            (ec_res['success'], app_log, err) = build_and_install_one(ec, init_env, hooks=hooks)
            ec_res['log_file'] = app_log
            if not ec_res['success']:
                ec_res['err'] = EasyBuildError(err)
        except Exception, err:
            # purposely catch all exceptions
            ec_res['success'] = False
            ec_res['err'] = err
            ec_res['traceback'] = traceback.format_exc()

        # keep track of success/total count
        if ec_res['success']:
            test_msg = "Successfully built %s" % ec['spec']
        else:
            test_msg = "Build of %s failed" % ec['spec']
            if 'err' in ec_res:
                test_msg += " (err: %s)" % ec_res['err']

        # dump test report next to log file
        test_report_txt = create_test_report(test_msg, [(ec, ec_res)], init_session_state)
        if 'log_file' in ec_res and ec_res['log_file']:
            test_report_fp = "%s_test_report.md" % '.'.join(ec_res['log_file'].split('.')[:-1])
            parent_dir = os.path.dirname(test_report_fp)
            # parent dir for test report may not be writable at this time, e.g. when --read-only-installdir is used
            if os.stat(parent_dir).st_mode & 0200:
                write_file(test_report_fp, test_report_txt)
            else:
                adjust_permissions(parent_dir, stat.S_IWUSR, add=True, recursive=False)
                write_file(test_report_fp, test_report_txt)
                adjust_permissions(parent_dir, stat.S_IWUSR, add=False, recursive=False)

        if not ec_res['success'] and exit_on_failure:
            if 'traceback' in ec_res:
                raise EasyBuildError(ec_res['traceback'])
            else:
                raise EasyBuildError(test_msg)

        res.append((ec, ec_res))
Example #4
0
def build_and_install_software(ecs, init_session_state, exit_on_failure=True):
    """Build and install software for all provided parsed easyconfig files."""
    # obtain a copy of the starting environment so each build can start afresh
    # we shouldn't use the environment from init_session_state, since relevant env vars might have been set since
    # e.g. via easyconfig.handle_allowed_system_deps
    init_env = copy.deepcopy(os.environ)

    res = []
    for ec in ecs:
        ec_res = {}
        try:
            (ec_res["success"], app_log, err) = build_and_install_one(ec, init_env)
            ec_res["log_file"] = app_log
            if not ec_res["success"]:
                ec_res["err"] = EasyBuildError(err)
        except Exception, err:
            # purposely catch all exceptions
            ec_res["success"] = False
            ec_res["err"] = err
            ec_res["traceback"] = traceback.format_exc()

        # keep track of success/total count
        if ec_res["success"]:
            test_msg = "Successfully built %s" % ec["spec"]
        else:
            test_msg = "Build of %s failed" % ec["spec"]
            if "err" in ec_res:
                test_msg += " (err: %s)" % ec_res["err"]

        # dump test report next to log file
        test_report_txt = create_test_report(test_msg, [(ec, ec_res)], init_session_state)
        if "log_file" in ec_res and ec_res["log_file"]:
            test_report_fp = "%s_test_report.md" % ".".join(ec_res["log_file"].split(".")[:-1])
            parent_dir = os.path.dirname(test_report_fp)
            # parent dir for test report may not be writable at this time, e.g. when --read-only-installdir is used
            if os.stat(parent_dir).st_mode & 0200:
                write_file(test_report_fp, test_report_txt)
            else:
                adjust_permissions(parent_dir, stat.S_IWUSR, add=True, recursive=False)
                write_file(test_report_fp, test_report_txt)
                adjust_permissions(parent_dir, stat.S_IWUSR, add=False, recursive=False)

        if not ec_res["success"] and exit_on_failure:
            if "traceback" in ec_res:
                raise EasyBuildError(ec_res["traceback"])
            else:
                raise EasyBuildError(test_msg)

        res.append((ec, ec_res))
Example #5
0
def build_and_install_software(ecs, init_session_state, exit_on_failure=True):
    """Build and install software for all provided parsed easyconfig files."""
    # obtain a copy of the starting environment so each build can start afresh
    # we shouldn't use the environment from init_session_state, since relevant env vars might have been set since
    # e.g. via easyconfig.handle_allowed_system_deps
    orig_environ = copy.deepcopy(os.environ)

    res = []
    for ec in ecs:
        ec_res = {}
        try:
            (ec_res['success'], app_log,
             err) = build_and_install_one(ec, orig_environ)
            ec_res['log_file'] = app_log
            if not ec_res['success']:
                ec_res['err'] = EasyBuildError(err)
        except Exception, err:
            # purposely catch all exceptions
            ec_res['success'] = False
            ec_res['err'] = err
            ec_res['traceback'] = traceback.format_exc()

        # keep track of success/total count
        if ec_res['success']:
            test_msg = "Successfully built %s" % ec['spec']
        else:
            test_msg = "Build of %s failed" % ec['spec']
            if 'err' in ec_res:
                test_msg += " (err: %s)" % ec_res['err']

        # dump test report next to log file
        test_report_txt = create_test_report(test_msg, [(ec, ec_res)],
                                             init_session_state)
        if 'log_file' in ec_res:
            test_report_fp = "%s_test_report.md" % '.'.join(
                ec_res['log_file'].split('.')[:-1])
            write_file(test_report_fp, test_report_txt)

        if not ec_res['success'] and exit_on_failure:
            if 'traceback' in ec_res:
                _log.error(ec_res['traceback'])
            else:
                _log.error(test_msg)

        res.append((ec, ec_res))
Example #6
0
def build_and_install_software(ecs, init_session_state, exit_on_failure=True):
    """Build and install software for all provided parsed easyconfig files."""
    # obtain a copy of the starting environment so each build can start afresh
    # we shouldn't use the environment from init_session_state, since relevant env vars might have been set since
    # e.g. via easyconfig.handle_allowed_system_deps
    orig_environ = copy.deepcopy(os.environ)

    res = []
    for ec in ecs:
        ec_res = {}
        try:
            (ec_res['success'], app_log, err) = build_and_install_one(ec, orig_environ)
            ec_res['log_file'] = app_log
            if not ec_res['success']:
                ec_res['err'] = EasyBuildError(err)
        except Exception, err:
            # purposely catch all exceptions
            ec_res['success'] = False
            ec_res['err'] = err
            ec_res['traceback'] = traceback.format_exc()

        # keep track of success/total count
        if ec_res['success']:
            test_msg = "Successfully built %s" % ec['spec']
        else:
            test_msg = "Build of %s failed" % ec['spec']
            if 'err' in ec_res:
                test_msg += " (err: %s)" % ec_res['err']

        # dump test report next to log file
        test_report_txt = create_test_report(test_msg, [(ec, ec_res)], init_session_state)
        if 'log_file' in ec_res:
            test_report_fp = "%s_test_report.md" % '.'.join(ec_res['log_file'].split('.')[:-1])
            write_file(test_report_fp, test_report_txt)

        if not ec_res['success'] and exit_on_failure:
            if 'traceback' in ec_res:
                _log.error(ec_res['traceback'])
            else:
                _log.error(test_msg)

        res.append((ec, ec_res))
Example #7
0
    correct_builds_cnt = len([
        ec_res for (_, ec_res) in ecs_with_res if ec_res.get('success', False)
    ])
    overall_success = correct_builds_cnt == len(ordered_ecs)
    success_msg = "Build succeeded for %s out of %s" % (correct_builds_cnt,
                                                        len(ordered_ecs))

    repo = init_repository(get_repository(), get_repositorypath())
    repo.cleanup()

    # report back in PR in case of testing
    if options.upload_test_report:
        msg = success_msg + " (%d easyconfigs in this PR)" % len(paths)
        test_report = create_test_report(msg,
                                         ecs_with_res,
                                         init_session_state,
                                         pr_nr=options.from_pr,
                                         gist_log=True)
        if options.from_pr:
            # upload test report to gist and issue a comment in the PR to notify
            msg = post_easyconfigs_pr_test_report(options.from_pr, test_report,
                                                  success_msg,
                                                  init_session_state,
                                                  overall_success)
            print_msg(msg)
        else:
            # only upload test report as a gist
            gist_url = upload_test_report_as_gist(test_report)
            print_msg("Test report uploaded to %s" % gist_url)
    else:
        test_report = create_test_report(success_msg, ecs_with_res,
Example #8
0
def build_and_install_software(ecs, init_session_state, exit_on_failure=True):
    """
    Build and install software for all provided parsed easyconfig files.

    :param ecs: easyconfig files to install software with
    :param init_session_state: initial session state, to use in test reports
    :param exit_on_failure: whether or not to exit on installation failure
    """
    # obtain a copy of the starting environment so each build can start afresh
    # we shouldn't use the environment from init_session_state, since relevant env vars might have been set since
    # e.g. via easyconfig.handle_allowed_system_deps
    init_env = copy.deepcopy(os.environ)

    start_progress_bar(STATUS_BAR, size=len(ecs))

    res = []
    ec_results = []
    failed_cnt = 0

    for ec in ecs:

        ec_res = {}
        try:
            (ec_res['success'], app_log,
             err) = build_and_install_one(ec, init_env)
            ec_res['log_file'] = app_log
            if not ec_res['success']:
                ec_res['err'] = EasyBuildError(err)
        except Exception as err:
            # purposely catch all exceptions
            ec_res['success'] = False
            ec_res['err'] = err
            ec_res['traceback'] = traceback.format_exc()

        if ec_res['success']:
            ec_results.append(ec['full_mod_name'] + ' (' +
                              colorize('OK', COLOR_GREEN) + ')')
        else:
            ec_results.append(ec['full_mod_name'] + ' (' +
                              colorize('FAILED', COLOR_RED) + ')')
            failed_cnt += 1

        # keep track of success/total count
        if ec_res['success']:
            test_msg = "Successfully built %s" % ec['spec']
        else:
            test_msg = "Build of %s failed" % ec['spec']
            if 'err' in ec_res:
                test_msg += " (err: %s)" % ec_res['err']

        # dump test report next to log file
        test_report_txt = create_test_report(test_msg, [(ec, ec_res)],
                                             init_session_state)
        if 'log_file' in ec_res and ec_res['log_file']:
            test_report_fp = "%s_test_report.md" % '.'.join(
                ec_res['log_file'].split('.')[:-1])
            parent_dir = os.path.dirname(test_report_fp)
            # parent dir for test report may not be writable at this time, e.g. when --read-only-installdir is used
            if os.stat(parent_dir).st_mode & 0o200:
                write_file(test_report_fp, test_report_txt['full'])
            else:
                adjust_permissions(parent_dir,
                                   stat.S_IWUSR,
                                   add=True,
                                   recursive=False)
                write_file(test_report_fp, test_report_txt['full'])
                adjust_permissions(parent_dir,
                                   stat.S_IWUSR,
                                   add=False,
                                   recursive=False)

        if not ec_res['success'] and exit_on_failure:
            if 'traceback' in ec_res:
                raise EasyBuildError(ec_res['traceback'])
            else:
                raise EasyBuildError(test_msg)

        res.append((ec, ec_res))

        if failed_cnt:
            # if installations failed: indicate th
            status_label = ' (%s): ' % colorize('%s failed!' % failed_cnt,
                                                COLOR_RED)
            failed_ecs = [x for x in ec_results[::-1] if 'FAILED' in x]
            ok_ecs = [x for x in ec_results[::-1] if x not in failed_ecs]
            status_label += ', '.join(failed_ecs + ok_ecs)
        else:
            status_label = ': ' + ', '.join(ec_results[::-1])

        update_progress_bar(STATUS_BAR, label=status_label)

    stop_progress_bar(STATUS_BAR)

    return res
Example #9
0
    if not testing or (testing and do_build):
        ecs_with_res = build_and_install_software(ordered_ecs, init_session_state, exit_on_failure=exit_on_failure)
    else:
        ecs_with_res = [(ec, {}) for ec in ordered_ecs]

    correct_builds_cnt = len([ec_res for (_, ec_res) in ecs_with_res if ec_res.get('success', False)])
    overall_success = correct_builds_cnt == len(ordered_ecs)
    success_msg = "Build succeeded for %s out of %s" % (correct_builds_cnt, len(ordered_ecs))

    repo = init_repository(get_repository(), get_repositorypath())
    repo.cleanup()

    # report back in PR in case of testing
    if options.upload_test_report:
        msg = success_msg + " (%d easyconfigs in this PR)" % len(paths)
        test_report = create_test_report(msg, ecs_with_res, init_session_state, pr_nr=options.from_pr, gist_log=True)
        if options.from_pr:
            # upload test report to gist and issue a comment in the PR to notify
            msg = post_easyconfigs_pr_test_report(options.from_pr, test_report, success_msg, init_session_state, overall_success)
            print_msg(msg)
        else:
            # only upload test report as a gist
            gist_url = upload_test_report_as_gist(test_report)
            print_msg("Test report uploaded to %s" % gist_url)
    else:
        test_report = create_test_report(success_msg, ecs_with_res, init_session_state)
    _log.debug("Test report: %s" % test_report)
    if options.dump_test_report is not None:
        write_file(options.dump_test_report, test_report)
        _log.info("Test report dumped to %s" % options.dump_test_report)