示例#1
0
    def test_expandvars_dollar(self):
        text = 'Hello, $(echo World)'
        assert 'Hello, World' == os_ext.expandvars(text)

        # Test nested expansion
        text = '$(echo Hello, $(echo World))'
        assert 'Hello, World' == os_ext.expandvars(text)
示例#2
0
    def test_expandvars_backticks(self):
        text = 'Hello, `echo World`'
        assert 'Hello, World' == os_ext.expandvars(text)

        # Test nested expansion
        text = '`echo Hello, `echo World``'
        assert 'Hello, World' == os_ext.expandvars(text)
示例#3
0
    def test_expandvars_backticks(self):
        text = 'Hello, `echo World`'
        self.assertEqual('Hello, World', os_ext.expandvars(text))

        # Test nested expansion
        text = '`echo Hello, `echo World``'
        self.assertEqual('Hello, World', os_ext.expandvars(text))
示例#4
0
    def test_expandvars_dollar(self):
        text = 'Hello, $(echo World)'
        self.assertEqual('Hello, World', os_ext.expandvars(text))

        # Test nested expansion
        text = '$(echo Hello, $(echo World))'
        self.assertEqual('Hello, World', os_ext.expandvars(text))
示例#5
0
def test_expandvars_nocmd(monkeypatch):
    monkeypatch.setenv('FOO', 'World')
    text = 'Hello, $FOO'
    assert 'Hello, World' == os_ext.expandvars(text)

    text = 'Hello, ${FOO}'
    assert 'Hello, World' == os_ext.expandvars(text)
示例#6
0
    def test_expandvars_nocmd(self):
        os.environ['FOO'] = 'World'
        text = 'Hello, $FOO'
        self.assertEqual('Hello, World', os_ext.expandvars(text))

        text = 'Hello, ${FOO}'
        self.assertEqual('Hello, World', os_ext.expandvars(text))
        del os.environ['FOO']
示例#7
0
    def test_expandvars_nocmd(self):
        os.environ['FOO'] = 'World'
        text = 'Hello, $FOO'
        assert 'Hello, World' == os_ext.expandvars(text)

        text = 'Hello, ${FOO}'
        assert 'Hello, World' == os_ext.expandvars(text)
        del os.environ['FOO']
示例#8
0
def is_env_loaded(environ):
    ''':class:`True` if this environment is loaded, :class:`False` otherwise.
    '''
    is_module_loaded = runtime().modules_system.is_module_loaded
    return (all(map(is_module_loaded, environ.modules)) and all(
        os.environ.get(k, None) == os_ext.expandvars(v)
        for k, v in environ.variables.items()))
示例#9
0
def loadenv(*environs):
    '''Load environments in the current Python context.

    :arg environs: A list of environments to load.
    :type environs: List[Environment]

    :returns: A tuple containing snapshot of the current environment upon
        entry to this function and a list of shell commands required to load
        the environments.
    :rtype: Tuple[_EnvironmentSnapshot, List[str]]

    '''
    modules_system = runtime().modules_system
    env_snapshot = snapshot()
    commands = []
    for env in environs:
        for m in env.modules:
            conflicted = modules_system.load_module(m, force=True)
            for c in conflicted:
                commands += modules_system.emit_unload_commands(c)

            commands += modules_system.emit_load_commands(m)

        for k, v in env.variables.items():
            os.environ[k] = os_ext.expandvars(v)
            commands.append('export %s=%s' % (k, v))

    return env_snapshot, commands
示例#10
0
 def is_loaded(self):
     """:class:`True` if this environment is loaded,
     :class:`False` otherwise.
     """
     is_module_loaded = runtime().modules_system.is_module_loaded
     return (all(map(is_module_loaded, self._modules)) and
             all(os.environ.get(k, None) == os_ext.expandvars(v)
                 for k, v in self._variables.items()))
示例#11
0
    def perflogdir(self):
        # Find the first filelog handler
        handlers = self.site_config.get('logging/0/handlers_perflog')
        for i, h in enumerate(handlers):
            if h['type'] == 'filelog':
                break

        return os_ext.expandvars(
            self.site_config.get(f'logging/0/handlers_perflog/{i}/basedir'))
示例#12
0
    def __init__(self, load_path, recurse=False, ignore_conflicts=False):
        # Expand any environment variables and symlinks
        load_path = [os.path.realpath(os_ext.expandvars(p)) for p in load_path]
        self._load_path = os_ext.unique_abs_paths(load_path, recurse)
        self._recurse = recurse
        self._ignore_conflicts = ignore_conflicts

        # Loaded tests by name; maps test names to the file that were defined
        self._loaded = {}
示例#13
0
    def load(self):
        # conflicted module list must be filled at the time of load
        rt = runtime()
        for m in self._modules:
            if rt.modules_system.is_module_loaded(m):
                self._preloaded.add(m)

            conflicted = rt.modules_system.load_module(m, force=True)
            for c in conflicted:
                self._module_ops.append(('u', c))

            self._module_ops.append(('l', m))
            self._conflicted += conflicted

        for k, v in self._variables.items():
            if k in os.environ:
                self._saved_variables[k] = os.environ[k]

            os.environ[k] = os_ext.expandvars(v)

        self._loaded = True
示例#14
0
def loadenv(*environs):
    '''Load environments in the current Python context.

    Returns a tuple containing a snapshot of the environment at entry to this
    function and a list of shell commands required to load ``environs``.
    '''
    modules_system = runtime().modules_system
    env_snapshot = snapshot()
    commands = []
    for env in environs:
        for m in env.modules:
            conflicted = modules_system.load_module(m, force=True)
            for c in conflicted:
                commands += modules_system.emit_unload_commands(c)

            commands += modules_system.emit_load_commands(m)

        for k, v in env.variables.items():
            os.environ[k] = os_ext.expandvars(v)
            commands.append('export %s=%s' % (k, v))

    return env_snapshot, commands
示例#15
0
def load(*environs):
    '''Load environments in the current Python context.

    Returns a tuple containing a snapshot of the environment at entry to this
    function and a list of shell commands required to load ``environs``.
    '''
    env_snapshot = snapshot()
    commands = []
    rt = runtime()
    for env in environs:
        for m in env.modules:
            # This checks the modules on the host system, but we do not want to do that...
            # removing this also speeds up the testing, as we do not test loading all modules
            # conflicted = rt.modules_system.load_module(m, force=True)
            # for c in conflicted:
            #     commands += rt.modules_system.emit_unload_commands(c)

            commands += rt.modules_system.emit_load_commands(m)

        for k, v in env.variables.items():
            os.environ[k] = os_ext.expandvars(v)
            commands.append('export %s=%s' % (k, v))

    return env_snapshot, commands
示例#16
0
    def test_strange_syntax(self):
        text = 'Hello, $(foo`'
        assert 'Hello, $(foo`' == os_ext.expandvars(text)

        text = 'Hello, `foo)'
        assert 'Hello, `foo)' == os_ext.expandvars(text)
示例#17
0
    def test_expandvars_mixed_syntax(self):
        text = '`echo Hello, $(echo World)`'
        self.assertEqual('Hello, World', os_ext.expandvars(text))

        text = '$(echo Hello, `echo World`)'
        self.assertEqual('Hello, World', os_ext.expandvars(text))
示例#18
0
    def test_expandvars_mixed_syntax(self):
        text = '`echo Hello, $(echo World)`'
        assert 'Hello, World' == os_ext.expandvars(text)

        text = '$(echo Hello, `echo World`)'
        assert 'Hello, World' == os_ext.expandvars(text)
示例#19
0
 def test_expandvars_error(self):
     text = 'Hello, $(foo)'
     with pytest.raises(SpawnedProcessError):
         os_ext.expandvars(text)
示例#20
0
    def test_strange_syntax(self):
        text = 'Hello, $(foo`'
        self.assertEqual('Hello, $(foo`', os_ext.expandvars(text))

        text = 'Hello, `foo)'
        self.assertEqual('Hello, `foo)', os_ext.expandvars(text))
示例#21
0
def main():
    # Setup command line options
    argparser = argparse.ArgumentParser()
    output_options = argparser.add_argument_group(
        'Options controlling ReFrame output')
    locate_options = argparser.add_argument_group(
        'Options for discovering checks')
    select_options = argparser.add_argument_group(
        'Options for selecting checks')
    action_options = argparser.add_argument_group(
        'Options controlling actions')
    run_options = argparser.add_argument_group(
        'Options controlling the execution of checks')
    env_options = argparser.add_argument_group(
        'Options controlling the ReFrame environment')
    misc_options = argparser.add_argument_group('Miscellaneous options')

    # Output directory options
    output_options.add_argument('--prefix',
                                action='store',
                                metavar='DIR',
                                help='Set general directory prefix to DIR',
                                envvar='RFM_PREFIX',
                                configvar='systems/prefix')
    output_options.add_argument('-o',
                                '--output',
                                action='store',
                                metavar='DIR',
                                help='Set output directory prefix to DIR',
                                envvar='RFM_OUTPUT_DIR',
                                configvar='systems/outputdir')
    output_options.add_argument('-s',
                                '--stage',
                                action='store',
                                metavar='DIR',
                                help='Set stage directory prefix to DIR',
                                envvar='RFM_STAGE_DIR',
                                configvar='systems/stagedir')
    output_options.add_argument(
        '--timestamp',
        action='store',
        nargs='?',
        const='',
        metavar='TIMEFMT',
        help=('Append a timestamp to the output and stage directory prefixes '
              '(default: "%%FT%%T")'),
        envvar='RFM_TIMESTAMP_DIRS',
        configvar='general/timestamp_dirs')
    output_options.add_argument(
        '--perflogdir',
        action='store',
        metavar='DIR',
        help=('Set performance log data directory prefix '
              '(relevant only to the filelog log handler)'),
        envvar='RFM_PERFLOG_DIR',
        configvar='logging/handlers_perflog/filelog_basedir')
    output_options.add_argument(
        '--keep-stage-files',
        action='store_true',
        help='Keep stage directories even for successful checks',
        envvar='RFM_KEEP_STAGE_FILES',
        configvar='general/keep_stage_files')
    output_options.add_argument('--dont-restage',
                                action='store_false',
                                dest='clean_stagedir',
                                help='Reuse the test stage directory',
                                envvar='RFM_CLEAN_STAGEDIR',
                                configvar='general/clean_stagedir')
    output_options.add_argument(
        '--save-log-files',
        action='store_true',
        default=False,
        help='Save ReFrame log files to the output directory',
        envvar='RFM_SAVE_LOG_FILES',
        configvar='general/save_log_files')
    output_options.add_argument('--report-file',
                                action='store',
                                metavar='FILE',
                                help="Store JSON run report in FILE",
                                envvar='RFM_REPORT_FILE',
                                configvar='general/report_file')

    # Check discovery options
    locate_options.add_argument('-c',
                                '--checkpath',
                                action='append',
                                metavar='PATH',
                                help="Add PATH to the check search path list",
                                envvar='RFM_CHECK_SEARCH_PATH :',
                                configvar='general/check_search_path')
    locate_options.add_argument(
        '-R',
        '--recursive',
        action='store_true',
        help='Search for checks in the search path recursively',
        envvar='RFM_CHECK_SEARCH_RECURSIVE',
        configvar='general/check_search_recursive')
    locate_options.add_argument('--ignore-check-conflicts',
                                action='store_true',
                                help='Skip checks with conflicting names',
                                envvar='RFM_IGNORE_CHECK_CONFLICTS',
                                configvar='general/ignore_check_conflicts')

    # Select options
    select_options.add_argument(
        '-t',
        '--tag',
        action='append',
        dest='tags',
        metavar='PATTERN',
        default=[],
        help='Select checks with at least one tag matching PATTERN')
    select_options.add_argument(
        '-n',
        '--name',
        action='append',
        dest='names',
        default=[],
        metavar='PATTERN',
        help='Select checks whose name matches PATTERN')
    select_options.add_argument(
        '-x',
        '--exclude',
        action='append',
        dest='exclude_names',
        metavar='PATTERN',
        default=[],
        help='Exclude checks whose name matches PATTERN')
    select_options.add_argument(
        '-p',
        '--prgenv',
        action='append',
        default=[r'.*'],
        metavar='PATTERN',
        help=('Select checks with at least one '
              'programming environment matching PATTERN'))
    select_options.add_argument('--gpu-only',
                                action='store_true',
                                help='Select only GPU checks')
    select_options.add_argument('--cpu-only',
                                action='store_true',
                                help='Select only CPU checks')

    # Action options
    action_options.add_argument('-l',
                                '--list',
                                action='store_true',
                                help='List the selected checks')
    action_options.add_argument(
        '-L',
        '--list-detailed',
        action='store_true',
        help='List the selected checks providing details for each test')
    action_options.add_argument('-r',
                                '--run',
                                action='store_true',
                                help='Run the selected checks')

    # Run options
    run_options.add_argument('-J',
                             '--job-option',
                             action='append',
                             metavar='OPT',
                             dest='job_options',
                             default=[],
                             help='Pass option OPT to job scheduler')
    run_options.add_argument('--force-local',
                             action='store_true',
                             help='Force local execution of checks')
    run_options.add_argument('--skip-sanity-check',
                             action='store_true',
                             help='Skip sanity checking')
    run_options.add_argument('--skip-performance-check',
                             action='store_true',
                             help='Skip performance checking')
    run_options.add_argument('--strict',
                             action='store_true',
                             help='Enforce strict performance checking')
    run_options.add_argument('--skip-system-check',
                             action='store_true',
                             help='Skip system check')
    run_options.add_argument('--skip-prgenv-check',
                             action='store_true',
                             help='Skip programming environment check')
    run_options.add_argument(
        '--exec-policy',
        metavar='POLICY',
        action='store',
        choices=['async', 'serial'],
        default='async',
        help='Set the execution policy of ReFrame (default: "async")')
    run_options.add_argument('--mode',
                             action='store',
                             help='Execution mode to use')
    run_options.add_argument(
        '--max-retries',
        metavar='NUM',
        action='store',
        default=0,
        help='Set the maximum number of times a failed regression test '
        'may be retried (default: 0)')
    run_options.add_argument(
        '--flex-alloc-nodes',
        action='store',
        dest='flex_alloc_nodes',
        metavar='{all|STATE|NUM}',
        default=None,
        help='Set strategy for the flexible node allocation (default: "idle").'
    )
    run_options.add_argument('--disable-hook',
                             action='append',
                             metavar='NAME',
                             dest='hooks',
                             default=[],
                             help='Disable a pipeline hook for this run')
    env_options.add_argument('-M',
                             '--map-module',
                             action='append',
                             metavar='MAPPING',
                             dest='module_mappings',
                             default=[],
                             help='Add a module mapping',
                             envvar='RFM_MODULE_MAPPINGS ,',
                             configvar='general/module_mappings')
    env_options.add_argument(
        '-m',
        '--module',
        action='append',
        default=[],
        metavar='MOD',
        dest='user_modules',
        help='Load module MOD before running any regression check',
        envvar='RFM_USER_MODULES ,',
        configvar='general/user_modules')
    env_options.add_argument('--module-mappings',
                             action='store',
                             metavar='FILE',
                             dest='module_map_file',
                             help='Load module mappings from FILE',
                             envvar='RFM_MODULE_MAP_FILE',
                             configvar='general/module_map_file')
    env_options.add_argument(
        '-u',
        '--unload-module',
        action='append',
        metavar='MOD',
        dest='unload_modules',
        default=[],
        help='Unload module MOD before running any regression check',
        envvar='RFM_UNLOAD_MODULES ,',
        configvar='general/unload_modules')
    env_options.add_argument(
        '--purge-env',
        action='store_true',
        dest='purge_env',
        default=False,
        help='Unload all modules before running any regression check',
        envvar='RFM_PURGE_ENVIRONMENT',
        configvar='general/purge_environment')
    env_options.add_argument(
        '--non-default-craype',
        action='store_true',
        help='Test a non-default Cray Programming Environment',
        envvar='RFM_NON_DEFAULT_CRAYPE',
        configvar='general/non_default_craype')

    # Miscellaneous options
    misc_options.add_argument('-C',
                              '--config-file',
                              action='store',
                              dest='config_file',
                              metavar='FILE',
                              help='Set configuration file',
                              envvar='RFM_CONFIG_FILE')
    misc_options.add_argument('--nocolor',
                              action='store_false',
                              dest='colorize',
                              help='Disable coloring of output',
                              envvar='RFM_COLORIZE',
                              configvar='general/colorize')
    misc_options.add_argument('--failure-stats',
                              action='store_true',
                              help='Print failure statistics')
    misc_options.add_argument('--performance-report',
                              action='store_true',
                              help='Print a report for performance tests')
    misc_options.add_argument(
        '--show-config',
        action='store',
        nargs='?',
        const='all',
        metavar='PARAM',
        help='Print the value of configuration parameter PARAM and exit')
    misc_options.add_argument('--system',
                              action='store',
                              help='Load configuration for SYSTEM',
                              envvar='RFM_SYSTEM')
    misc_options.add_argument(
        '--upgrade-config-file',
        action='store',
        metavar='OLD[:NEW]',
        help='Upgrade ReFrame 2.x configuration file to ReFrame 3.x syntax')
    misc_options.add_argument('-V',
                              '--version',
                              action='version',
                              version=os_ext.reframe_version())
    misc_options.add_argument('-v',
                              '--verbose',
                              action='count',
                              help='Increase verbosity level of output',
                              envvar='RFM_VERBOSE',
                              configvar='general/verbose')

    # Options not associated with command-line arguments
    argparser.add_argument(
        dest='graylog_server',
        envvar='RFM_GRAYLOG_ADDRESS',
        configvar='logging/handlers_perflog/graylog_address',
        help='Graylog server address')
    argparser.add_argument(dest='syslog_address',
                           envvar='RFM_SYSLOG_ADDRESS',
                           configvar='logging/handlers_perflog/syslog_address',
                           help='Syslog server address')
    argparser.add_argument(dest='ignore_reqnodenotavail',
                           envvar='RFM_IGNORE_REQNODENOTAVAIL',
                           configvar='schedulers/ignore_reqnodenotavail',
                           action='store_true',
                           help='Graylog server address')
    argparser.add_argument(dest='use_login_shell',
                           envvar='RFM_USE_LOGIN_SHELL',
                           configvar='general/use_login_shell',
                           action='store_true',
                           help='Use a login shell for job scripts')

    if len(sys.argv) == 1:
        argparser.print_help()
        sys.exit(1)

    # Parse command line
    options = argparser.parse_args()

    # First configure logging with our generic configuration so as to be able
    # to print pretty messages; logging will be reconfigured by user's
    # configuration later
    site_config = config.load_config(
        os.path.join(reframe.INSTALL_PREFIX, 'reframe/core/settings.py'))
    site_config.select_subconfig('generic')
    options.update_config(site_config)
    logging.configure_logging(site_config)
    logging.getlogger().colorize = site_config.get('general/0/colorize')
    printer = PrettyPrinter()
    printer.colorize = site_config.get('general/0/colorize')
    printer.inc_verbosity(site_config.get('general/0/verbose'))
    if os.getenv('RFM_GRAYLOG_SERVER'):
        printer.warning(
            'RFM_GRAYLOG_SERVER environment variable is deprecated; '
            'please use RFM_GRAYLOG_ADDRESS instead')
        os.environ['RFM_GRAYLOG_ADDRESS'] = os.getenv('RFM_GRAYLOG_SERVER')

    if options.upgrade_config_file is not None:
        old_config, *new_config = options.upgrade_config_file.split(':',
                                                                    maxsplit=1)
        new_config = new_config[0] if new_config else None

        try:
            new_config = config.convert_old_config(old_config, new_config)
        except Exception as e:
            printer.error(f'could not convert file: {e}')
            sys.exit(1)

        printer.info(f'Conversion successful! '
                     f'The converted file can be found at {new_config!r}.')

        sys.exit(0)

    # Now configure ReFrame according to the user configuration file
    try:
        try:
            site_config = config.load_config(options.config_file)
        except ReframeDeprecationWarning as e:
            printer.warning(e)
            converted = config.convert_old_config(options.config_file)
            printer.warning(f"configuration file has been converted "
                            f"to the new syntax here: '{converted}'")
            site_config = config.load_config(converted)

        site_config.validate()

        # We ignore errors about unresolved sections or configuration
        # parameters here, because they might be defined at the individual
        # partition level and will be caught when we will instantiating
        # internally the system and partitions later on.
        site_config.select_subconfig(options.system,
                                     ignore_resolve_errors=True)
        for err in options.update_config(site_config):
            printer.warning(str(err))

        # Update options from the selected execution mode
        if options.mode:
            mode_args = site_config.get(f'modes/@{options.mode}/options')

            # Parse the mode's options and reparse the command-line
            options = argparser.parse_args(mode_args)
            options = argparser.parse_args(namespace=options.cmd_options)
            options.update_config(site_config)

        logging.configure_logging(site_config)
    except (OSError, ConfigError) as e:
        printer.error(f'failed to load configuration: {e}')
        sys.exit(1)

    logging.getlogger().colorize = site_config.get('general/0/colorize')
    printer.colorize = site_config.get('general/0/colorize')
    printer.inc_verbosity(site_config.get('general/0/verbose'))
    try:
        runtime.init_runtime(site_config)
    except ConfigError as e:
        printer.error(f'failed to initialize runtime: {e}')
        sys.exit(1)

    rt = runtime.runtime()
    try:
        if site_config.get('general/0/module_map_file'):
            rt.modules_system.load_mapping_from_file(
                site_config.get('general/0/module_map_file'))

        if site_config.get('general/0/module_mappings'):
            for m in site_config.get('general/0/module_mappings'):
                rt.modules_system.load_mapping(m)

    except (ConfigError, OSError) as e:
        printer.error('could not load module mappings: %s' % e)
        sys.exit(1)

    if (os_ext.samefile(rt.stage_prefix, rt.output_prefix)
            and not site_config.get('general/0/keep_stage_files')):
        printer.error("stage and output refer to the same directory; "
                      "if this is on purpose, please use the "
                      "'--keep-stage-files' option.")
        sys.exit(1)

    # Show configuration after everything is set up
    if options.show_config:
        config_param = options.show_config
        if config_param == 'all':
            printer.info(str(rt.site_config))
        else:
            value = rt.get_option(config_param)
            if value is None:
                printer.error(
                    f'no such configuration parameter found: {config_param}')
            else:
                printer.info(json.dumps(value, indent=2))

        sys.exit(0)

    printer.debug(format_env(options.env_vars))

    # Setup the check loader
    loader = RegressionCheckLoader(
        load_path=site_config.get('general/0/check_search_path'),
        recurse=site_config.get('general/0/check_search_recursive'),
        ignore_conflicts=site_config.get('general/0/ignore_check_conflicts'))

    def print_infoline(param, value):
        param = param + ':'
        printer.info(f"  {param.ljust(18)} {value}")

    session_info = {
        'cmdline': ' '.join(sys.argv),
        'config_file': rt.site_config.filename,
        'data_version': '1.0',
        'hostname': socket.gethostname(),
        'prefix_output': rt.output_prefix,
        'prefix_stage': rt.stage_prefix,
        'user': os_ext.osuser(),
        'version': os_ext.reframe_version(),
        'workdir': os.getcwd(),
    }

    # Print command line
    printer.info(f"[ReFrame Setup]")
    print_infoline('version', session_info['version'])
    print_infoline('command', repr(session_info['cmdline']))
    print_infoline(
        f"launched by",
        f"{session_info['user'] or '<unknown>'}@{session_info['hostname']}")
    print_infoline('working directory', repr(session_info['workdir']))
    print_infoline('settings file', f"{session_info['config_file']!r}")
    print_infoline(
        'check search path', f"{'(R) ' if loader.recurse else ''}"
        f"{':'.join(loader.load_path)!r}")
    print_infoline('stage directory', repr(session_info['prefix_stage']))
    print_infoline('output directory', repr(session_info['prefix_output']))
    printer.info('')
    try:
        # Locate and load checks
        try:
            checks_found = loader.load_all()
        except OSError as e:
            raise ReframeError from e

        # Filter checks by name
        checks_matched = checks_found
        if options.exclude_names:
            for name in options.exclude_names:
                checks_matched = filter(filters.have_not_name(name),
                                        checks_matched)

        if options.names:
            checks_matched = filter(filters.have_name('|'.join(options.names)),
                                    checks_matched)

        # Filter checks by tags
        for tag in options.tags:
            checks_matched = filter(filters.have_tag(tag), checks_matched)

        # Filter checks by prgenv
        if not options.skip_prgenv_check:
            for prgenv in options.prgenv:
                checks_matched = filter(filters.have_prgenv(prgenv),
                                        checks_matched)

        # Filter checks by system
        if not options.skip_system_check:
            checks_matched = filter(
                filters.have_partition(rt.system.partitions), checks_matched)

        # Filter checks further
        if options.gpu_only and options.cpu_only:
            printer.error("options `--gpu-only' and `--cpu-only' "
                          "are mutually exclusive")
            sys.exit(1)

        if options.gpu_only:
            checks_matched = filter(filters.have_gpu_only(), checks_matched)
        elif options.cpu_only:
            checks_matched = filter(filters.have_cpu_only(), checks_matched)

        # Determine the allowed programming environments
        allowed_environs = {
            e.name
            for env_patt in options.prgenv for p in rt.system.partitions
            for e in p.environs if re.match(env_patt, e.name)
        }

        # Generate the test cases, validate dependencies and sort them
        checks_matched = list(checks_matched)

        # Disable hooks
        for c in checks_matched:
            for h in options.hooks:
                type(c).disable_hook(h)

        testcases = generate_testcases(checks_matched,
                                       options.skip_system_check,
                                       options.skip_prgenv_check,
                                       allowed_environs)
        testgraph = dependency.build_deps(testcases)
        dependency.validate_deps(testgraph)
        testcases = dependency.toposort(testgraph)

        # Manipulate ReFrame's environment
        if site_config.get('general/0/purge_environment'):
            rt.modules_system.unload_all()
        else:
            for m in site_config.get('general/0/unload_modules'):
                rt.modules_system.unload_module(m)

        # Load the environment for the current system
        try:
            runtime.loadenv(rt.system.preload_environ)
        except EnvironError as e:
            printer.error("failed to load current system's environment; "
                          "please check your configuration")
            printer.debug(str(e))
            raise

        for m in site_config.get('general/0/user_modules'):
            try:
                rt.modules_system.load_module(m, force=True)
            except EnvironError as e:
                printer.warning("could not load module '%s' correctly: "
                                "Skipping..." % m)
                printer.debug(str(e))

        options.flex_alloc_nodes = options.flex_alloc_nodes or 'idle'

        # Act on checks
        success = True
        if options.list or options.list_detailed:
            list_checks(list(checks_matched), printer, options.list_detailed)
        elif options.run:
            # Setup the execution policy
            if options.exec_policy == 'serial':
                exec_policy = SerialExecutionPolicy()
            elif options.exec_policy == 'async':
                exec_policy = AsynchronousExecutionPolicy()
            else:
                # This should not happen, since choices are handled by
                # argparser
                printer.error("unknown execution policy `%s': Exiting...")
                sys.exit(1)

            exec_policy.skip_system_check = options.skip_system_check
            exec_policy.force_local = options.force_local
            exec_policy.strict_check = options.strict
            exec_policy.skip_sanity_check = options.skip_sanity_check
            exec_policy.skip_performance_check = options.skip_performance_check
            exec_policy.keep_stage_files = site_config.get(
                'general/0/keep_stage_files')
            try:
                errmsg = "invalid option for --flex-alloc-nodes: '{0}'"
                sched_flex_alloc_nodes = int(options.flex_alloc_nodes)
                if sched_flex_alloc_nodes <= 0:
                    raise ConfigError(errmsg.format(options.flex_alloc_nodes))
            except ValueError:
                sched_flex_alloc_nodes = options.flex_alloc_nodes

            exec_policy.sched_flex_alloc_nodes = sched_flex_alloc_nodes
            parsed_job_options = []
            for opt in options.job_options:
                if opt.startswith('-') or opt.startswith('#'):
                    parsed_job_options.append(opt)
                elif len(opt) == 1:
                    parsed_job_options.append(f'-{opt}')
                else:
                    parsed_job_options.append(f'--{opt}')

            exec_policy.sched_options = parsed_job_options
            try:
                max_retries = int(options.max_retries)
            except ValueError:
                raise ConfigError('--max-retries is not a valid integer: %s' %
                                  max_retries) from None
            runner = Runner(exec_policy, printer, max_retries)
            try:
                time_start = time.time()
                session_info['time_start'] = time.strftime(
                    '%FT%T%z',
                    time.localtime(time_start),
                )
                runner.runall(testcases)
            finally:
                time_end = time.time()
                session_info['time_end'] = time.strftime(
                    '%FT%T%z', time.localtime(time_end))
                session_info['time_elapsed'] = time_end - time_start

                # Print a retry report if we did any retries
                if runner.stats.failures(run=0):
                    printer.info(runner.stats.retry_report())

                # Print a failure report if we had failures in the last run
                if runner.stats.failures():
                    printer.info(runner.stats.failure_report())
                    success = False
                    if options.failure_stats:
                        printer.info(runner.stats.failure_stats())

                if options.performance_report:
                    printer.info(runner.stats.performance_report())

                # Generate the report for this session
                report_file = os.path.normpath(
                    os_ext.expandvars(rt.get_option('general/0/report_file')))
                basedir = os.path.dirname(report_file)
                if basedir:
                    os.makedirs(basedir, exist_ok=True)

                # Build final JSON report
                run_stats = runner.stats.json()
                session_info.update({
                    'num_cases':
                    run_stats[0]['num_cases'],
                    'num_failures':
                    run_stats[-1]['num_failures']
                })
                json_report = {'session_info': session_info, 'runs': run_stats}
                report_file = generate_report_filename(report_file)
                try:
                    with open(report_file, 'w') as fp:
                        jsonext.dump(json_report, fp, indent=2)
                except OSError as e:
                    printer.warning(
                        f'failed to generate report in {report_file!r}: {e}')

        else:
            printer.error("No action specified. Please specify `-l'/`-L' for "
                          "listing or `-r' for running. "
                          "Try `%s -h' for more options." % argparser.prog)
            sys.exit(1)

        if not success:
            sys.exit(1)

        sys.exit(0)

    except KeyboardInterrupt:
        sys.exit(1)
    except ReframeError as e:
        printer.error(str(e))
        sys.exit(1)
    except (Exception, ReframeFatalError):
        printer.error(format_exception(*sys.exc_info()))
        sys.exit(1)
    finally:
        try:
            log_files = logging.log_files()
            if site_config.get('general/0/save_log_files'):
                log_files = logging.save_log_files(rt.output_prefix)

        except OSError as e:
            printer.error('could not save log file: %s' % e)
            sys.exit(1)
        finally:
            if not log_files:
                msg = '<no log file was generated>'
            else:
                msg = f'{", ".join(repr(f) for f in log_files)}'

            printer.info(f'Log file(s) saved in: {msg}')
示例#22
0
 def outputdir(self):
     return os_ext.expandvars(
         self.site_config.get('systems/0/outputdir')
     )
示例#23
0
 def stagedir(self):
     return os_ext.expandvars(
         self.site_config.get('systems/0/stagedir')
     )
示例#24
0
    def load_from_dict(self, site_config):
        if not isinstance(site_config, collections.abc.Mapping):
            raise TypeError('site configuration is not a dict')

        # We do all the necessary imports here and not on the top, because we
        # want to remove import time dependencies
        import reframe.core.environments as m_env
        from reframe.core.systems import System, SystemPartition

        sysconfig = site_config.get('systems', None)
        envconfig = site_config.get('environments', None)
        modes = site_config.get('modes', {})

        if not sysconfig:
            raise ValueError('no entry for systems was found')

        if not envconfig:
            raise ValueError('no entry for environments was found')

        # Convert envconfig to a ScopedDict
        try:
            envconfig = fields.ScopedDict(envconfig)
        except TypeError:
            raise TypeError('environments configuration '
                            'is not a scoped dictionary') from None

        # Convert modes to a `ScopedDict`; note that `modes` will implicitly
        # converted to a scoped dict here, since `self._modes` is a
        # `ScopedDictField`.
        try:
            self._modes = modes
        except TypeError:
            raise TypeError('modes configuration '
                            'is not a scoped dictionary') from None

        def create_env(system, partition, name):
            # Create an environment instance
            try:
                config = envconfig['%s:%s:%s' % (system, partition, name)]
            except KeyError:
                raise ConfigError("could not find a definition for `%s'" %
                                  name) from None

            if not isinstance(config, collections.abc.Mapping):
                raise TypeError("config for `%s' is not a dictionary" % name)

            try:
                envtype = m_env.__dict__[config['type']]
                return envtype(name, **config)
            except KeyError:
                raise ConfigError("no type specified for environment `%s'" %
                                  name) from None

        # Populate the systems directory
        for sys_name, config in sysconfig.items():
            if not isinstance(config, dict):
                raise TypeError('system configuration is not a dictionary')

            if not isinstance(config['partitions'], collections.abc.Mapping):
                raise TypeError('partitions must be a dictionary')

            sys_descr = config.get('descr', sys_name)
            sys_hostnames = config.get('hostnames', [])

            # The System's constructor provides also reasonable defaults, but
            # since we are going to set them anyway from the values provided by
            # the configuration, we should set default values here. The stage,
            # output and log directories default to None, since they are going
            # to be set dynamically by the runtime.
            sys_prefix = config.get('prefix', '.')
            sys_stagedir = config.get('stagedir', None)
            sys_outputdir = config.get('outputdir', None)
            sys_perflogdir = config.get('perflogdir', None)
            sys_resourcesdir = config.get('resourcesdir', '.')
            sys_modules_system = config.get('modules_system', None)

            # Expand variables
            if sys_prefix:
                sys_prefix = os_ext.expandvars(sys_prefix)

            if sys_stagedir:
                sys_stagedir = os_ext.expandvars(sys_stagedir)

            if sys_outputdir:
                sys_outputdir = os_ext.expandvars(sys_outputdir)

            if sys_perflogdir:
                sys_perflogdir = os_ext.expandvars(sys_perflogdir)

            if sys_resourcesdir:
                sys_resourcesdir = os_ext.expandvars(sys_resourcesdir)

            # Create the preload environment for the system
            sys_preload_env = m_env.Environment(
                name='__rfm_env_%s' % sys_name,
                modules=config.get('modules', []),
                variables=config.get('variables', {}))

            system = System(name=sys_name,
                            descr=sys_descr,
                            hostnames=sys_hostnames,
                            preload_env=sys_preload_env,
                            prefix=sys_prefix,
                            stagedir=sys_stagedir,
                            outputdir=sys_outputdir,
                            perflogdir=sys_perflogdir,
                            resourcesdir=sys_resourcesdir,
                            modules_system=sys_modules_system)
            for part_name, partconfig in config.get('partitions', {}).items():
                if not isinstance(partconfig, collections.abc.Mapping):
                    raise TypeError("partition `%s' not configured "
                                    "as a dictionary" % part_name)

                part_descr = partconfig.get('descr', part_name)
                part_scheduler, part_launcher = self.get_schedsystem_config(
                    partconfig.get('scheduler', 'local+local'))
                part_local_env = m_env.Environment(
                    name='__rfm_env_%s' % part_name,
                    modules=partconfig.get('modules', []),
                    variables=partconfig.get('variables', {}).items())
                part_environs = [
                    create_env(sys_name, part_name, e)
                    for e in partconfig.get('environs', [])
                ]
                part_access = partconfig.get('access', [])
                part_resources = partconfig.get('resources', {})
                part_max_jobs = partconfig.get('max_jobs', 1)
                system.add_partition(
                    SystemPartition(name=part_name,
                                    descr=part_descr,
                                    scheduler=part_scheduler,
                                    launcher=part_launcher,
                                    access=part_access,
                                    environs=part_environs,
                                    resources=part_resources,
                                    local_env=part_local_env,
                                    max_jobs=part_max_jobs))

            self._systems[sys_name] = system
示例#25
0
文件: cli.py 项目: ikirker/reframe
def main():
    # Setup command line options
    argparser = argparse.ArgumentParser()
    output_options = argparser.add_argument_group('Options controlling output')
    locate_options = argparser.add_argument_group(
        'Options for locating checks')
    select_options = argparser.add_argument_group(
        'Options for selecting checks')
    action_options = argparser.add_argument_group(
        'Options controlling actions')
    run_options = argparser.add_argument_group(
        'Options controlling execution of checks')
    env_options = argparser.add_argument_group(
        'Options controlling environment')
    misc_options = argparser.add_argument_group('Miscellaneous options')

    # Output directory options
    output_options.add_argument('--prefix',
                                action='store',
                                metavar='DIR',
                                help='Set output directory prefix to DIR')
    output_options.add_argument('-o',
                                '--output',
                                action='store',
                                metavar='DIR',
                                help='Set output directory to DIR')
    output_options.add_argument('-s',
                                '--stage',
                                action='store',
                                metavar='DIR',
                                help='Set stage directory to DIR')
    output_options.add_argument(
        '--perflogdir',
        action='store',
        metavar='DIR',
        help='Set directory prefix for the performance logs '
        '(default: ${prefix}/perflogs, '
        'relevant only if the filelog backend is used)')
    output_options.add_argument(
        '--keep-stage-files',
        action='store_true',
        help='Keep stage directory even if check is successful')
    output_options.add_argument(
        '--save-log-files',
        action='store_true',
        default=False,
        help='Copy the log file from the work dir to the output dir at the '
        'end of the program')

    # Check discovery options
    locate_options.add_argument('-c',
                                '--checkpath',
                                action='append',
                                metavar='DIR|FILE',
                                help='Search for checks in DIR or FILE')
    locate_options.add_argument('-R',
                                '--recursive',
                                action='store_true',
                                help='Load checks recursively')
    locate_options.add_argument('--ignore-check-conflicts',
                                action='store_true',
                                help='Skip checks with conflicting names')

    # Select options
    select_options.add_argument('-t',
                                '--tag',
                                action='append',
                                dest='tags',
                                default=[],
                                help='Select checks matching TAG')
    select_options.add_argument('-n',
                                '--name',
                                action='append',
                                dest='names',
                                default=[],
                                metavar='NAME',
                                help='Select checks with NAME')
    select_options.add_argument('-x',
                                '--exclude',
                                action='append',
                                dest='exclude_names',
                                metavar='NAME',
                                default=[],
                                help='Exclude checks with NAME')
    select_options.add_argument(
        '-p',
        '--prgenv',
        action='append',
        default=[r'.*'],
        help='Select tests for PRGENV programming environment only')
    select_options.add_argument('--gpu-only',
                                action='store_true',
                                help='Select only GPU tests')
    select_options.add_argument('--cpu-only',
                                action='store_true',
                                help='Select only CPU tests')

    # Action options
    action_options.add_argument('-l',
                                '--list',
                                action='store_true',
                                help='List matched regression checks')
    action_options.add_argument(
        '-L',
        '--list-detailed',
        action='store_true',
        help='List matched regression checks with a detailed description')
    action_options.add_argument('-r',
                                '--run',
                                action='store_true',
                                help='Run regression with the selected checks')

    # Run options
    run_options.add_argument('-A',
                             '--account',
                             action='store',
                             help='Use ACCOUNT for submitting jobs')
    run_options.add_argument('-P',
                             '--partition',
                             action='store',
                             metavar='PART',
                             help='Use PART for submitting jobs')
    run_options.add_argument('--reservation',
                             action='store',
                             metavar='RES',
                             help='Use RES for submitting jobs')
    run_options.add_argument('--nodelist',
                             action='store',
                             help='Run checks on the selected list of nodes')
    run_options.add_argument(
        '--exclude-nodes',
        action='store',
        metavar='NODELIST',
        help='Exclude the list of nodes from running checks')
    run_options.add_argument('--job-option',
                             action='append',
                             metavar='OPT',
                             dest='job_options',
                             default=[],
                             help='Pass OPT to job scheduler')
    run_options.add_argument('--force-local',
                             action='store_true',
                             help='Force local execution of checks')
    run_options.add_argument('--skip-sanity-check',
                             action='store_true',
                             help='Skip sanity checking')
    run_options.add_argument('--skip-performance-check',
                             action='store_true',
                             help='Skip performance checking')
    run_options.add_argument('--strict',
                             action='store_true',
                             help='Force strict performance checking')
    run_options.add_argument('--skip-system-check',
                             action='store_true',
                             help='Skip system check')
    run_options.add_argument('--skip-prgenv-check',
                             action='store_true',
                             help='Skip prog. environment check')
    run_options.add_argument(
        '--exec-policy',
        metavar='POLICY',
        action='store',
        choices=['serial', 'async'],
        default='serial',
        help='Specify the execution policy for running the regression tests. '
        'Available policies: "serial" (default), "async"')
    run_options.add_argument('--mode',
                             action='store',
                             help='Execution mode to use')
    run_options.add_argument(
        '--max-retries',
        metavar='NUM',
        action='store',
        default=0,
        help='Specify the maximum number of times a failed regression test '
        'may be retried (default: 0)')
    run_options.add_argument(
        '--flex-alloc-tasks',
        action='store',
        dest='flex_alloc_tasks',
        metavar='{all|idle|NUM}',
        default='idle',
        help="Strategy for flexible task allocation (default: 'idle').")

    env_options.add_argument('-M',
                             '--map-module',
                             action='append',
                             metavar='MAPPING',
                             dest='module_mappings',
                             default=[],
                             help='Apply a single module mapping')
    env_options.add_argument(
        '-m',
        '--module',
        action='append',
        default=[],
        metavar='MOD',
        dest='user_modules',
        help='Load module MOD before running the regression suite')
    env_options.add_argument('--module-mappings',
                             action='store',
                             metavar='FILE',
                             dest='module_map_file',
                             help='Apply module mappings defined in FILE')
    env_options.add_argument(
        '-u',
        '--unload-module',
        action='append',
        metavar='MOD',
        dest='unload_modules',
        default=[],
        help='Unload module MOD before running the regression suite')
    env_options.add_argument(
        '--purge-env',
        action='store_true',
        dest='purge_env',
        default=False,
        help='Purge environment before running the regression suite')

    # Miscellaneous options
    misc_options.add_argument(
        '-C',
        '--config-file',
        action='store',
        dest='config_file',
        metavar='FILE',
        default=os.path.join(reframe.INSTALL_PREFIX, 'reframe/settings.py'),
        help='Specify a custom config-file for the machine. '
        '(default: %s' %
        os.path.join(reframe.INSTALL_PREFIX, 'reframe/settings.py'))
    misc_options.add_argument('--nocolor',
                              action='store_false',
                              dest='colorize',
                              default=True,
                              help='Disable coloring of output')
    misc_options.add_argument('--performance-report',
                              action='store_true',
                              help='Print the performance report')

    # FIXME: This should move to env_options as soon as
    # https://github.com/eth-cscs/reframe/pull/946 is merged
    misc_options.add_argument('--non-default-craype',
                              action='store_true',
                              default=False,
                              help='Test a non-default Cray PE')
    misc_options.add_argument(
        '--show-config',
        action='store_true',
        help='Print configuration of the current system and exit')
    misc_options.add_argument(
        '--show-config-env',
        action='store',
        metavar='ENV',
        help='Print configuration of environment ENV and exit')
    misc_options.add_argument('--system',
                              action='store',
                              help='Load SYSTEM configuration explicitly')
    misc_options.add_argument(
        '--timestamp',
        action='store',
        nargs='?',
        const='%FT%T',
        metavar='TIMEFMT',
        help='Append a timestamp component to the regression directories'
        '(default format "%%FT%%T")')
    misc_options.add_argument('-V',
                              '--version',
                              action='version',
                              version=reframe.VERSION)
    misc_options.add_argument('-v',
                              '--verbose',
                              action='count',
                              default=0,
                              help='Increase verbosity level of output')

    if len(sys.argv) == 1:
        argparser.print_help()
        sys.exit(1)

    # Parse command line
    options = argparser.parse_args()

    # Load configuration
    try:
        settings = config.load_settings_from_file(options.config_file)
    except (OSError, ReframeError) as e:
        sys.stderr.write('%s: could not load settings: %s\n' %
                         (sys.argv[0], e))
        sys.exit(1)

    # Configure logging
    try:
        logging.configure_logging(settings.logging_config),
    except (OSError, ConfigError) as e:
        sys.stderr.write('could not configure logging: %s\n' % e)
        sys.exit(1)

    # Set colors in logger
    logging.getlogger().colorize = options.colorize

    # Setup printer
    printer = PrettyPrinter()
    printer.colorize = options.colorize
    if options.verbose:
        printer.inc_verbosity(options.verbose)

    try:
        runtime.init_runtime(settings.site_configuration,
                             options.system,
                             non_default_craype=options.non_default_craype)
    except SystemAutodetectionError:
        printer.warning(
            'could not find a configuration entry for the current system; '
            'falling back to a generic system configuration; '
            'please check the online documentation on how to configure '
            'ReFrame for your system.')
        settings.site_configuration['systems'] = {
            'generic': {
                'descr': 'Generic fallback system configuration',
                'hostnames': ['localhost'],
                'partitions': {
                    'login': {
                        'scheduler': 'local',
                        'environs': ['builtin-gcc'],
                        'descr': 'Login nodes'
                    }
                }
            }
        }
        settings.site_configuration['environments'] = {
            '*': {
                'builtin-gcc': {
                    'type': 'ProgEnvironment',
                    'cc': 'gcc',
                    'cxx': 'g++',
                    'ftn': 'gfortran',
                }
            }
        }
        runtime.init_runtime(settings.site_configuration,
                             'generic',
                             non_default_craype=options.non_default_craype)
    except Exception as e:
        printer.error('configuration error: %s' % e)
        printer.verbose(''.join(traceback.format_exception(*sys.exc_info())))
        sys.exit(1)

    rt = runtime.runtime()
    try:
        if options.module_map_file:
            rt.modules_system.load_mapping_from_file(options.module_map_file)

        if options.module_mappings:
            for m in options.module_mappings:
                rt.modules_system.load_mapping(m)

    except (ConfigError, OSError) as e:
        printer.error('could not load module mappings: %s' % e)
        sys.exit(1)

    if options.mode:
        try:
            mode_args = rt.mode(options.mode)

            # Parse the mode's options and reparse the command-line
            options = argparser.parse_args(mode_args)
            options = argparser.parse_args(namespace=options)
        except ConfigError as e:
            printer.error('could not obtain execution mode: %s' % e)
            sys.exit(1)

    # Adjust system directories
    if options.prefix:
        # if prefix is set, reset all other directories
        rt.resources.prefix = os_ext.expandvars(options.prefix)
        rt.resources.outputdir = None
        rt.resources.stagedir = None

    if options.output:
        rt.resources.outputdir = os_ext.expandvars(options.output)

    if options.stage:
        rt.resources.stagedir = os_ext.expandvars(options.stage)

    if (os_ext.samefile(rt.resources.stage_prefix, rt.resources.output_prefix)
            and not options.keep_stage_files):
        printer.error('stage and output refer to the same directory; '
                      'if this is on purpose, please use also the '
                      "`--keep-stage-files' option.")
        sys.exit(1)

    if options.timestamp:
        rt.resources.timefmt = options.timestamp

    # Configure performance logging
    # NOTE: we need resources to be configured in order to set the global
    # perf. logging prefix correctly
    if options.perflogdir:
        rt.resources.perflogdir = os_ext.expandvars(options.perflogdir)

    logging.LOG_CONFIG_OPTS['handlers.filelog.prefix'] = (
        rt.resources.perflog_prefix)

    # Show configuration after everything is set up
    if options.show_config:
        printer.info(rt.show_config())
        sys.exit(0)

    if options.show_config_env:
        envname = options.show_config_env
        for p in rt.system.partitions:
            environ = p.environment(envname)
            if environ:
                break

        if environ is None:
            printer.error('no such environment: ' + envname)
            sys.exit(1)

        printer.info(environ.details())
        sys.exit(0)

    if hasattr(settings, 'perf_logging_config'):
        try:
            logging.configure_perflogging(settings.perf_logging_config)
        except (OSError, ConfigError) as e:
            printer.error('could not configure performance logging: %s\n' % e)
            sys.exit(1)
    else:
        printer.warning('no performance logging is configured; '
                        'please check documentation')

    # Setup the check loader
    if options.checkpath:
        load_path = []
        for d in options.checkpath:
            d = os_ext.expandvars(d)
            if not os.path.exists(d):
                printer.warning("%s: path `%s' does not exist. Skipping..." %
                                (argparser.prog, d))
                continue

            load_path.append(d)

        loader = RegressionCheckLoader(
            load_path,
            recurse=options.recursive,
            ignore_conflicts=options.ignore_check_conflicts)
    else:
        loader = RegressionCheckLoader(load_path=settings.checks_path,
                                       prefix=reframe.INSTALL_PREFIX,
                                       recurse=settings.checks_path_recurse)

    printer.debug(argparse.format_options(options))

    # Print command line
    printer.info('Command line: %s' % ' '.join(sys.argv))
    printer.info('Reframe version: ' + reframe.VERSION)
    printer.info('Launched by user: '******'<unknown>'))
    printer.info('Launched on host: ' + socket.gethostname())

    # Print important paths
    printer.info('Reframe paths')
    printer.info('=============')
    printer.info('    Check prefix      : %s' % loader.prefix)
    printer.info(
        '%03s Check search path : %s' %
        ('(R)' if loader.recurse else '', "'%s'" % ':'.join(loader.load_path)))
    printer.info('    Stage dir prefix     : %s' % rt.resources.stage_prefix)
    printer.info('    Output dir prefix    : %s' % rt.resources.output_prefix)
    printer.info(
        '    Perf. logging prefix : %s' %
        os.path.abspath(logging.LOG_CONFIG_OPTS['handlers.filelog.prefix']))
    try:
        # Locate and load checks
        try:
            checks_found = loader.load_all()
        except OSError as e:
            raise ReframeError from e

        # Filter checks by name
        checks_matched = checks_found
        if options.exclude_names:
            for name in options.exclude_names:
                checks_matched = filter(filters.have_not_name(name),
                                        checks_matched)

        if options.names:
            checks_matched = filter(filters.have_name('|'.join(options.names)),
                                    checks_matched)

        # Filter checks by tags
        for tag in options.tags:
            checks_matched = filter(filters.have_tag(tag), checks_matched)

        # Filter checks by prgenv
        if not options.skip_prgenv_check:
            for prgenv in options.prgenv:
                checks_matched = filter(filters.have_prgenv(prgenv),
                                        checks_matched)

        # Filter checks by system
        if not options.skip_system_check:
            checks_matched = filter(
                filters.have_partition(rt.system.partitions), checks_matched)

        # Filter checks further
        if options.gpu_only and options.cpu_only:
            printer.error("options `--gpu-only' and `--cpu-only' "
                          "are mutually exclusive")
            sys.exit(1)

        if options.gpu_only:
            checks_matched = filter(filters.have_gpu_only(), checks_matched)
        elif options.cpu_only:
            checks_matched = filter(filters.have_cpu_only(), checks_matched)

        # Determine the allowed programming environments
        allowed_environs = {
            e.name
            for env_patt in options.prgenv for p in rt.system.partitions
            for e in p.environs if re.match(env_patt, e.name)
        }

        # Generate the test cases, validate dependencies and sort them
        checks_matched = list(checks_matched)
        testcases = generate_testcases(checks_matched,
                                       options.skip_system_check,
                                       options.skip_prgenv_check,
                                       allowed_environs)
        testgraph = dependency.build_deps(testcases)
        dependency.validate_deps(testgraph)
        testcases = dependency.toposort(testgraph)

        # Unload regression's module and load user-specified modules
        if hasattr(settings, 'reframe_module'):
            printer.warning(
                "the 'reframe_module' configuration option will be ignored; "
                "please use the '-u' or '--unload-module' options")

        if options.purge_env:
            rt.modules_system.unload_all()
        else:
            for m in options.unload_modules:
                rt.modules_system.unload_module(m)

        # Load the environment for the current system
        try:
            env.load(rt.system.preload_environ)
        except EnvironError as e:
            printer.error("failed to load current system's environment; "
                          "please check your configuration")
            printer.debug(str(e))
            raise

        for m in options.user_modules:
            try:
                rt.modules_system.load_module(m, force=True)
            except EnvironError as e:
                printer.warning("could not load module '%s' correctly: "
                                "Skipping..." % m)
                printer.debug(str(e))

        # Act on checks

        success = True
        if options.list:
            # List matched checks
            list_checks(list(checks_matched), printer)
        elif options.list_detailed:
            # List matched checks with details
            list_checks(list(checks_matched), printer, detailed=True)

        elif options.run:
            # Setup the execution policy
            if options.exec_policy == 'serial':
                exec_policy = SerialExecutionPolicy()
            elif options.exec_policy == 'async':
                exec_policy = AsynchronousExecutionPolicy()
            else:
                # This should not happen, since choices are handled by
                # argparser
                printer.error("unknown execution policy `%s': Exiting...")
                sys.exit(1)

            exec_policy.skip_system_check = options.skip_system_check
            exec_policy.force_local = options.force_local
            exec_policy.strict_check = options.strict
            exec_policy.skip_sanity_check = options.skip_sanity_check
            exec_policy.skip_performance_check = options.skip_performance_check
            exec_policy.keep_stage_files = options.keep_stage_files
            try:
                errmsg = "invalid option for --flex-alloc-tasks: '{0}'"
                sched_flex_alloc_tasks = int(options.flex_alloc_tasks)
                if sched_flex_alloc_tasks <= 0:
                    raise ConfigError(errmsg.format(options.flex_alloc_tasks))
            except ValueError:
                if not options.flex_alloc_tasks.lower() in {'idle', 'all'}:
                    raise ConfigError(errmsg.format(
                        options.flex_alloc_tasks)) from None

                sched_flex_alloc_tasks = options.flex_alloc_tasks

            exec_policy.sched_flex_alloc_tasks = sched_flex_alloc_tasks
            exec_policy.flex_alloc_tasks = options.flex_alloc_tasks
            exec_policy.sched_account = options.account
            exec_policy.sched_partition = options.partition
            exec_policy.sched_reservation = options.reservation
            exec_policy.sched_nodelist = options.nodelist
            exec_policy.sched_exclude_nodelist = options.exclude_nodes
            exec_policy.sched_options = options.job_options
            try:
                max_retries = int(options.max_retries)
            except ValueError:
                raise ConfigError('--max-retries is not a valid integer: %s' %
                                  max_retries) from None
            runner = Runner(exec_policy, printer, max_retries)
            try:
                runner.runall(testcases)
            finally:
                # Print a retry report if we did any retries
                if runner.stats.failures(run=0):
                    printer.info(runner.stats.retry_report())

                # Print a failure report if we had failures in the last run
                if runner.stats.failures():
                    printer.info(runner.stats.failure_report())
                    success = False

                if options.performance_report:
                    printer.info(runner.stats.performance_report())

        else:
            printer.info('No action specified. Exiting...')
            printer.info("Try `%s -h' for a list of available actions." %
                         argparser.prog)
            sys.exit(1)

        if not success:
            sys.exit(1)

        sys.exit(0)

    except KeyboardInterrupt:
        sys.exit(1)
    except ReframeError as e:
        printer.error(str(e))
        sys.exit(1)
    except (Exception, ReframeFatalError):
        printer.error(format_exception(*sys.exc_info()))
        sys.exit(1)
    finally:
        try:
            if options.save_log_files:
                logging.save_log_files(rt.resources.output_prefix)

        except OSError as e:
            printer.error('could not save log file: %s' % e)
            sys.exit(1)
示例#26
0
 def prefix(self):
     return os_ext.expandvars(
         self.site_config.get('systems/0/prefix')
     )