Ejemplo n.º 1
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
Ejemplo n.º 2
0
    def test_get_start_update_stop_progress_bar(self):
        """
        Test starting/updating/stopping of progress bars.
        """
        # clear progress bar cache first, this test assumes we start with a clean slate
        easybuild.tools.output._progress_bar_cache.clear()

        # restore default configuration to show progress bars (disabled to avoid mangled test output)
        update_build_option('show_progress_bar', True)

        # stopping a progress bar that never was started results in an error
        error_pattern = "Failed to stop extensions progress bar, since it was never started"
        self.assertErrorRegex(EasyBuildError, error_pattern, stop_progress_bar,
                              PROGRESS_BAR_EXTENSIONS)

        # updating a progress bar that never was started is silently ignored on purpose
        update_progress_bar(PROGRESS_BAR_EXTENSIONS)
        update_progress_bar(PROGRESS_BAR_EXTENSIONS, label="foo")
        update_progress_bar(PROGRESS_BAR_EXTENSIONS, progress_size=100)

        # also test normal cycle: start, update, stop
        start_progress_bar(PROGRESS_BAR_EXTENSIONS, 100)
        update_progress_bar(PROGRESS_BAR_EXTENSIONS)  # single step progress
        update_progress_bar(PROGRESS_BAR_EXTENSIONS, total=50)
        update_progress_bar(PROGRESS_BAR_EXTENSIONS,
                            label="test123",
                            progress_size=5)
        stop_progress_bar(PROGRESS_BAR_EXTENSIONS)