Exemple #1
0
def test_which():
    r"""Test location of executable."""
    assert (tools.which(sys.executable) is not None)
    if platform._is_win:  # pragma: windows
        assert (tools.which('python.exe') is not None)
    else:
        assert (tools.which('python') is not None)
    assert (tools.which('invalid') is None)
    def is_interpreter(cls, cmd):
        r"""Determine if a command line argument is an interpreter.

        Args:
            cmd (str): Command that should be checked.

        Returns:
            bool: True if the command is an interpreter, False otherwise.

        """
        # (cls.language not in cmd)
        out = ((tools.which(cmd) is not None)
               and (not any([cmd.endswith(e) for e in cls.language_ext])))
        return out
Exemple #3
0
class TestModelDriverNoInit(TestModelParam, parent.TestDriverNoInit):
    r"""Test runner for ModelDriver class without creating an instance."""

    def tests_on_not_installed(self):
        r"""Tests for when the driver is not installed."""
        super(TestModelDriverNoInit, self).tests_on_not_installed()
        self.test_comm_installed()
        self.test_write_if_block()
        self.test_write_for_loop()
        self.test_write_while_loop()
        self.test_write_try_except()

    def test_is_installed(self):
        r"""Assert that the tested model driver is installed."""
        assert(self.import_cls.is_installed())

    def test_comm_installed(self):
        r"""Tests for getting installed comm while skipping config."""
        self.assert_equal(self.import_cls.is_comm_installed(),
                          self.import_cls.is_comm_installed(skip_config=True))
        self.assert_equal(self.import_cls.is_comm_installed(commtype='invalid',
                                                            skip_config=True),
                          False)
        
    def test_language_version(self):
        r"""Test language version."""
        assert(self.import_cls.language_version())

    def run_model_instance(self, **kwargs):
        r"""Create a driver for a model and run it."""
        inst_kwargs = copy.deepcopy(self.inst_kwargs)
        inst_kwargs.update(kwargs)
        drv = self.create_instance(kwargs=inst_kwargs)
        drv.start()
        drv.wait(False)
        assert(not drv.errors)

    def test_run_model(self):
        r"""Test running script used without debug."""
        self.run_model_instance()

    @unittest.skipIf(platform._is_win, "No valgrind on windows")
    @unittest.skipIf(tools.which('valgrind') is None,
                     "Valgrind not installed.")
    def test_valgrind(self):
        r"""Test running with valgrind."""
        valgrind_log = os.path.join(
            self.working_dir,
            'valgrind_log_%s.log' % self.uuid.replace('-', '_'))
        try:
            self.run_model_instance(with_valgrind=True, with_strace=False,
                                    valgrind_flags=['--leak-check=full',
                                                    '--log-file=%s' % valgrind_log])
        finally:
            if os.path.isfile(valgrind_log):
                os.remove(valgrind_log)
        
    @unittest.skipIf(platform._is_win or platform._is_mac,
                     "No strace on Windows or MacOS")
    @unittest.skipIf(tools.which('strace') is None,
                     "strace not installed.")
    def test_strace(self):
        r"""Test running with strace."""
        self.run_model_instance(with_valgrind=False, with_strace=True)
        
    # Tests for code generation
    def run_generated_code(self, lines):
        r"""Write and run generated code."""
        if not self.import_cls.is_installed():
            return
        # Write code to a file
        self.import_cls.run_code(lines)

    def get_test_types(self):
        r"""Return the list of tuples mapping json type to expected native type."""
        if self.import_cls.type_map is None:
            return []
        out = list(self.import_cls.type_map.items())
        if 'flag' not in self.import_cls.type_map:
            out.append(('flag', self.import_cls.type_map['boolean']))
        return out

    def test_invalid_function_param(self):
        r"""Test errors raise during class creation when parameters are invalid."""
        kwargs = copy.deepcopy(self.inst_kwargs)
        kwargs['name'] = 'test'
        kwargs['args'] = ['test']
        kwargs['function'] = 'invalid'
        kwargs['source_files'] = []
        if self.import_cls.function_param is None:
            self.assert_raises(ValueError, self.import_cls, **kwargs)
        else:
            kwargs['args'] = ['invalid']
            self.assert_raises(ValueError, self.import_cls, **kwargs)
            kwargs['args'] = [__file__]
            kwargs['is_server'] = True
            self.assert_raises(NotImplementedError, self.import_cls, **kwargs)
                               
    def test_get_native_type(self):
        r"""Test translation to native type."""
        test_vals = self.get_test_types()
        for a, b in test_vals:
            self.assert_equal(
                self.import_cls.get_native_type(type=a), b)
            if not isinstance(a, dict):
                self.assert_equal(
                    self.import_cls.get_native_type(type={'type': a}), b)
                
    def test_write_declaration(self):
        r"""Test write_declaration for all supported native types."""
        if (((self.import_cls.function_param is None)
             or ('declare' not in self.import_cls.function_param))):
            return
        test_vals = self.get_test_types()
        for a, b in test_vals:
            self.import_cls.write_declaration('test', type=a)

    def test_write_model_wrapper(self):
        r"""Test writing a model based on yaml parameters."""
        if self.import_cls.function_param is None:
            self.assert_raises(NotImplementedError,
                               self.import_cls.write_model_wrapper,
                               None, None)
            self.assert_raises(NotImplementedError,
                               self.import_cls.write_model_recv,
                               None, None)
            self.assert_raises(NotImplementedError,
                               self.import_cls.write_model_send,
                               None, None)
        else:
            inputs = [{'name': 'a', 'type': 'bytes', 'outside_loop': True},
                      {'name': 'b', 'type': {'type': 'int', 'precision': 64}},
                      {'name': 'c', 'type': {'type': 'string', 'precision': 10}}]
            outputs = [{'name': 'y', 'type': {'type': 'float', 'precision': 32}},
                       {'name': 'z', 'type': 'bytes', 'outside_loop': True},
                       {'name': 'x', 'type': {'type': 'string', 'precision': 10}}]
            self.import_cls.write_model_wrapper('test', 'test',
                                                inputs=inputs,
                                                outputs=outputs)
            self.assert_raises(NotImplementedError,
                               self.import_cls.format_function_param,
                               'invalid_key')
        
    def test_write_executable(self):
        r"""Test writing an executable."""
        if self.import_cls.function_param is None:
            self.assert_raises(NotImplementedError,
                               self.import_cls.write_executable,
                               None)
        else:
            lines1 = self.import_cls.write_executable('dummy',
                                                      prefix='dummy',
                                                      suffix='dummy')
            lines2 = self.import_cls.write_executable(lines1)
            self.assert_equal(lines1, lines2)
            # Don't run this because it is invalid

    def test_error_code(self):
        r"""Test that error is raised when code generates one."""
        if (((not self.import_cls.is_installed())
             or (self.import_cls.function_param is None))):
            return
        error_msg = 'Test error'
        lines = [self.import_cls.function_param['error'].format(error_msg=error_msg)]
        assert_raises(RuntimeError, self.import_cls.run_code, lines)

    def test_write_if_block(self):
        r"""Test writing an if block."""
        if self.import_cls.function_param is None:
            self.assert_raises(NotImplementedError, self.import_cls.write_if_block,
                               None, None)
        else:
            lines = []
            if 'declare' in self.import_cls.function_param:
                lines.append(self.import_cls.function_param['declare'].format(
                    type_name='int', variable='x'))
            cond = self.import_cls.function_param['true']
            block_contents = self.import_cls.function_param['assign'].format(
                name='x', value='1')
            lines += self.import_cls.write_if_block(cond, block_contents)
            self.run_generated_code(lines)

    def test_write_for_loop(self):
        r"""Test writing a for loop."""
        if self.import_cls.function_param is None:
            self.assert_raises(NotImplementedError, self.import_cls.write_for_loop,
                               None, None, None, None)
        else:
            lines = []
            if 'declare' in self.import_cls.function_param:
                lines.append(self.import_cls.function_param['declare'].format(
                    type_name='int', variable='i'))
                lines.append(self.import_cls.function_param['declare'].format(
                    type_name='int', variable='x'))
            loop_contents = self.import_cls.function_param['assign'].format(
                name='x', value='i')
            lines += self.import_cls.write_for_loop('i', 0, 1, loop_contents)
            self.run_generated_code(lines)

    def test_write_while_loop(self):
        r"""Test writing a while loop."""
        if self.import_cls.function_param is None:
            self.assert_raises(NotImplementedError, self.import_cls.write_while_loop,
                               None, None)
        else:
            lines = []
            cond = self.import_cls.function_param['true']
            loop_contents = self.import_cls.function_param.get('break', 'break')
            lines += self.import_cls.write_while_loop(cond, loop_contents)
            self.run_generated_code(lines)

    def test_write_try_except(self, **kwargs):
        r"""Test writing a try/except block."""
        if self.import_cls.function_param is None:
            self.assert_raises(NotImplementedError, self.import_cls.write_try_except,
                               None, None)
        else:
            lines = []
            try_contents = self.import_cls.function_param['error'].format(
                error_msg='Dummy error')
            except_contents = self.import_cls.function_param['print'].format(
                message='Dummy message')
            lines += self.import_cls.write_try_except(try_contents,
                                                      except_contents, **kwargs)
            self.run_generated_code(lines)
Exemple #4
0
def ygginfo():
    r"""Print information about yggdrasil installation."""
    from yggdrasil import __version__, tools, config, platform
    from yggdrasil.components import import_component
    lang_list = tools.get_installed_lang()
    prefix = '    '
    curr_prefix = ''
    vardict = [
        ('Location', os.path.dirname(__file__)), ('Version', __version__),
        ('Languages', ', '.join(lang_list)),
        ('Communication Mechanisms', ', '.join(tools.get_installed_comm())),
        ('Default Comm Mechanism', tools.get_default_comm()),
        ('Config File', config.usr_config_file)
    ]
    parser = argparse.ArgumentParser(
        description=
        'Display information about the current yggdrasil installation.')
    parser.add_argument(
        '--no-languages',
        action='store_true',
        dest='no_languages',
        help='Don\'t print information about individual languages.')
    parser.add_argument(
        '--verbose',
        action='store_true',
        help='Increase the verbosity of the printed information.')
    args = parser.parse_args()
    try:
        # Add language information
        if not args.no_languages:
            # Install languages
            vardict.append(('Installed Languages:', ''))
            curr_prefix += prefix
            for lang in sorted(lang_list):
                drv = import_component('model', lang)
                vardict.append((curr_prefix + '%s:' % lang.upper(), ''))
                curr_prefix += prefix
                if lang == 'executable':
                    vardict.append((curr_prefix + 'Location', ''))
                else:
                    exec_name = drv.language_executable()
                    if not os.path.isabs(exec_name):
                        exec_name = tools.which(exec_name)
                    vardict.append((curr_prefix + 'Location', exec_name))
                vardict.append(
                    (curr_prefix + 'Version', drv.language_version()))
                curr_prefix = curr_prefix.rsplit(prefix, 1)[0]
            curr_prefix = curr_prefix.rsplit(prefix, 1)[0]
            # Not installed languages
            vardict.append(("Languages Not Installed:", ''))
            curr_prefix += prefix
            for lang in tools.get_supported_lang():
                if lang in lang_list:
                    continue
                drv = import_component('model', lang)
                vardict.append((curr_prefix + '%s:' % lang.upper(), ''))
                curr_prefix += prefix
                vardict.append((curr_prefix + "Language Installed",
                                drv.is_language_installed()))
                vardict.append((curr_prefix + "Base Languages Installed",
                                drv.are_base_languages_installed()))
                if not drv.are_base_languages_installed():
                    vardict.append(
                        (curr_prefix + "Base Languages Not Installed", [
                            b for b in drv.base_languages if
                            (not import_component('model', b).is_installed())
                        ]))
                vardict.append((curr_prefix + "Dependencies Installed",
                                drv.are_dependencies_installed()))
                vardict.append((curr_prefix + "Interface Installed",
                                drv.is_interface_installed()))
                vardict.append(
                    (curr_prefix + "Comm Installed", drv.is_comm_installed()))
                vardict.append(
                    (curr_prefix + "Configured", drv.is_configured()))
                vardict.append((curr_prefix + "Disabled", drv.is_disabled()))
                curr_prefix = curr_prefix.rsplit(prefix, 1)[0]
            curr_prefix = curr_prefix.rsplit(prefix, 1)[0]
        # Add verbose information
        if args.verbose:
            # Conda info
            if os.environ.get('CONDA_PREFIX', ''):
                out = tools.bytes2str(
                    subprocess.check_output(['conda', 'info'])).strip()
                curr_prefix += prefix
                vardict.append((curr_prefix + 'Conda Info:',
                                "\n%s%s" % (curr_prefix + prefix,
                                            ("\n" + curr_prefix + prefix).join(
                                                out.splitlines(False)))))
                curr_prefix = curr_prefix.rsplit(prefix, 1)[0]
            # R and reticulate info
            Rdrv = import_component("model", "R")
            if Rdrv.is_installed():
                env_reticulate = copy.deepcopy(os.environ)
                env_reticulate['RETICULATE_PYTHON'] = sys.executable
                # Stack size
                out = Rdrv.run_executable(["-e", "Cstack_info()"]).strip()
                vardict.append((curr_prefix + "R Cstack_info:",
                                "\n%s%s" % (curr_prefix + prefix,
                                            ("\n" + curr_prefix + prefix).join(
                                                out.splitlines(False)))))
                # Compilation tools
                interp = 'R'.join(Rdrv.get_interpreter().rsplit('Rscript', 1))
                vardict.append((curr_prefix + "R C Compiler:", ""))
                curr_prefix += prefix
                for x in ['CC', 'CFLAGS', 'CXX', 'CXXFLAGS']:
                    out = tools.bytes2str(
                        subprocess.check_output([interp, 'CMD', 'config',
                                                 x])).strip()
                    vardict.append((curr_prefix + x,
                                    "%s" % ("\n" + curr_prefix + prefix).join(
                                        out.splitlines(False))))
                curr_prefix = curr_prefix.rsplit(prefix, 1)[0]
                # Session info
                out = Rdrv.run_executable(["-e", "sessionInfo()"]).strip()
                vardict.append((curr_prefix + "R sessionInfo:",
                                "\n%s%s" % (curr_prefix + prefix,
                                            ("\n" + curr_prefix + prefix).join(
                                                out.splitlines(False)))))
                # Reticulate conda_list
                if os.environ.get('CONDA_PREFIX', ''):
                    out = Rdrv.run_executable([
                        "-e",
                        ("library(reticulate); "
                         "reticulate::conda_list()")
                    ],
                                              env=env_reticulate).strip()
                    vardict.append(
                        (curr_prefix + "R reticulate::conda_list():",
                         "\n%s%s" % (curr_prefix + prefix,
                                     ("\n" + curr_prefix + prefix).join(
                                         out.splitlines(False)))))
                # Windows python versions
                if platform._is_win:  # pragma: windows
                    out = Rdrv.run_executable([
                        "-e",
                        ("library(reticulate); "
                         "reticulate::py_versions_windows()")
                    ],
                                              env=env_reticulate).strip()
                    vardict.append(
                        (curr_prefix + "R reticulate::py_versions_windows():",
                         "\n%s%s" % (curr_prefix + prefix,
                                     ("\n" + curr_prefix + prefix).join(
                                         out.splitlines(False)))))
                # conda_binary
                if platform._is_win:  # pragma: windows
                    out = Rdrv.run_executable([
                        "-e",
                        ("library(reticulate); "
                         "conda <- reticulate:::conda_binary(\"auto\"); "
                         "system(paste(conda, \"info --json\"))")
                    ],
                                              env=env_reticulate).strip()
                    vardict.append(
                        (curr_prefix + "R reticulate::py_versions_windows():",
                         "\n%s%s" % (curr_prefix + prefix,
                                     ("\n" + curr_prefix + prefix).join(
                                         out.splitlines(False)))))
                # Reticulate py_config
                out = Rdrv.run_executable([
                    "-e", ("library(reticulate); "
                           "reticulate::py_config()")
                ],
                                          env=env_reticulate).strip()
                vardict.append((curr_prefix + "R reticulate::py_config():",
                                "\n%s%s" % (curr_prefix + prefix,
                                            ("\n" + curr_prefix + prefix).join(
                                                out.splitlines(False)))))
    finally:
        # Print things
        max_len = max(len(x[0]) for x in vardict)
        lines = []
        line_format = '%-' + str(max_len) + 's' + prefix + '%s'
        for k, v in vardict:
            lines.append(line_format % (k, v))
        logger.info("yggdrasil info:\n%s" % '\n'.join(lines))
def run_tsts(**kwargs):  # pragma: no cover
    r"""Run tests for the package. Relative paths are interpreted to be
    relative to the package root directory.

    Args:
        verbose (bool, optional): If True, set option '-v' which
            increases the verbosity. Defaults to True.
        nocapture (bool, optional): If True, set option '--nocapture'
            ('--capture=no' with pytest) which allows messages to be printed to
            stdout. Defaults to True.
        stop (bool, optional): If True, set option '--stop' ('--exitfirst' for
            pytest) which stops tests at the first failure. Defaults to True.
        nologcapture (bool, optional): If True, set option '--nologcapture'
            which allows logged messages to be printed. Defaults to True.
        withcoverage (bool, optional): If True, set option '--with-coverage'
            which invokes coverage. Defaults to True.
        withexamples (bool, optional): If True, example testing will be
            enabled. Defaults to False.
        language (str, optional): Language to test. Defaults to None
            and all languages will be tested.

    """
    if '-h' not in sys.argv:
        if _test_package is None:
            raise RuntimeError("Could not locate test runner pytest or nose.")
        elif _test_package_name == 'pytest':
            test_cmd = 'pytest'
        elif _test_package_name == 'nose':
            test_cmd = 'nosetests'
        else:
            raise RuntimeError("Unsupported test package: '%s'" %
                               _test_package_name)
    parser = argparse.ArgumentParser(description='Run yggdrasil tests.')
    arguments = [
        (['withcoverage', 'with-coverage'], ['nocover', 'no-cover'], True, {
            'help': 'Record coverage during tests.'
        }),
        (['withexamples',
          'with-examples'], ['noexamples', 'no-examples'], False, {
              'help': 'Run example tests when encountered.'
          }),
        (['longrunning',
          'long-running'], ['nolongrunning', 'no-long-running'], False, {
              'help': 'Run long tests when encounterd.'
          }),
        (['verbose', 'v'], ['quiet'], True, {
            'help': ('Increase verbosity of output from '
                     'the test runner.')
        }),
        (['nocapture', 's'], ['capture'], True, {
            'help': 'Don\'t capture output from tests.'
        }),
        (['stop', 'x'], ['dontstop', 'dont-stop'], True, {
            'help': 'Stop after first test failure.'
        }),
        (['nologcapture'], ['logcapture'], True, {
            'help': ('Don\'t capture output from log '
                     'messages generated during tests.')
        }),
        (['validatecomponents', 'validate-components'],
         ['skipcomponentvalidation', 'skip-component-validation'], False, {
             'help': ('Validate components on creation. This causes '
                      'a decrease in performance so it is turned off '
                      'by default.')
         }),
        (['noflaky', 'no-flaky'], ['flaky'], False, {
            'help': 'Don\'t re-run flaky tests.'
        })
    ]
    for pos_dest, neg_dest, default, kws in arguments:
        dest = pos_dest[0]
        for x in [pos_dest, neg_dest]:
            for i, y in enumerate(x):
                if len(y) == 1:
                    x[i] = '-' + y
                else:
                    x[i] = '--' + y
        if kwargs.get(dest, default):
            if kws['help'].startswith('Don\'t'):
                kws['help'].split('Don\'t', 1)[-1]
                kws['help'] = kws['help'].replace(kws['help'][0],
                                                  kws['help'][0].upper(), 1)
            else:
                kws['help'] = kws['help'].replace(kws['help'][0],
                                                  kws['help'][0].lower(), 1)
                kws['help'] = 'Don\'t ' + kws['help']
            parser.add_argument(*neg_dest,
                                action='store_false',
                                dest=dest,
                                **kws)
        else:
            parser.add_argument(*pos_dest,
                                action='store_true',
                                dest=dest,
                                **kws)
    parser.add_argument('--language',
                        '--languages',
                        default=[],
                        nargs="+",
                        type=str,
                        help='Language(s) that should be tested.')
    parser.add_argument('--ci',
                        action='store_true',
                        help=('Perform addition operations required '
                              'for testing on continuous integration '
                              'services.'))
    suite_args = ('--test-suite', '--test-suites')
    suite_kws = dict(nargs='+',
                     action="extend",
                     type=str,
                     choices=['examples', 'types', 'timing'],
                     help='Test suite(s) that should be run.',
                     dest='test_suites')
    try:
        parser.add_argument(*suite_args, **suite_kws)
    except ValueError:
        # 'extend' introduced in 3.8
        suite_kws['action'] = 'append'
        suite_kws.pop('nargs')
        parser.add_argument(*suite_args, **suite_kws)
    args, extra_argv = parser.parse_known_args()
    initial_dir = os.getcwd()
    package_dir = os.path.dirname(os.path.abspath(__file__))
    error_code = 0
    # Peform ci tests/operations
    # Call bash script?
    if args.ci:
        extra_argv += ['-c', 'setup.cfg', '--cov-config=.coveragerc']
    # Separate out paths from options
    argv = [test_cmd]
    test_paths = []
    opt_val = 0
    for x in extra_argv:
        if opt_val > 0:
            argv.append(x)
            opt_val -= 1
        elif x.endswith('yggtest'):
            pass
        elif x.startswith('-'):
            argv.append(x)
            if (_test_package_name == 'pytest') and (x in ['-c']):
                opt_val = 1
        else:
            test_paths.append(x)
    if args.test_suites:
        for x in args.test_suites:
            if x == 'examples':
                args.withexamples = True
                test_paths.append('examples')
            elif x == 'types':
                args.withexamples = True
                args.longrunning = True
                test_paths.append(
                    os.path.join('examples', 'tests', 'test_types.py'))
            elif x == 'timing':
                args.longrunning = True
                test_paths.append(os.path.join('tests', 'test_timing.py'))
    if _test_package_name == 'nose':
        argv += ['--detailed-errors', '--exe']
    if args.verbose:
        argv.append('-v')
    if args.nocapture:
        argv.append('-s')
    if args.stop:
        argv.append('-x')
    if args.nologcapture and (_test_package_name == 'nose'):
        argv.append('--nologcapture')
    if args.withcoverage:
        if _test_package_name == 'nose':
            argv.append('--with-coverage')
            argv.append('--cover-package=yggdrasil')
        elif _test_package_name == 'pytest':
            argv.append('--cov=%s' % package_dir)
    if args.noflaky:
        if _test_package_name == 'pytest':
            argv += ['-p', 'no:flaky']
    else:
        if _test_package_name == 'nose':
            argv.append('--with-flaky')
    # Get expanded tests to allow for paths that are relative to either the
    # yggdrasil root directory or the current working directory
    expanded_test_paths = []
    if not test_paths:
        expanded_test_paths.append(package_dir)
    else:
        for x in test_paths:
            if not expand_and_add(x, expanded_test_paths,
                                  [package_dir, os.getcwd()]):
                expanded_test_paths.append(x)
    argv += expanded_test_paths
    # Run test command and perform cleanup before logging any errors
    logger.info("Running %s from %s", argv, os.getcwd())
    old_env = {}
    pth_file = 'ygg_coverage.pth'
    assert (not os.path.isfile(pth_file))
    try:
        # Set env
        if args.withexamples:
            old_env['YGG_ENABLE_EXAMPLE_TESTS'] = os.environ.get(
                'YGG_ENABLE_EXAMPLE_TESTS', None)
            os.environ['YGG_ENABLE_EXAMPLE_TESTS'] = 'True'
        if args.language:
            from yggdrasil.components import import_component
            args.language = [
                import_component('model', x).language for x in args.language
            ]
            old_env['YGG_TEST_LANGUAGE'] = os.environ.get(
                'YGG_TEST_LANGUAGE', None)
            os.environ['YGG_TEST_LANGUAGE'] = ','.join(args.language)
        if args.longrunning:
            old_env['YGG_ENABLE_LONG_TESTS'] = os.environ.get(
                'YGG_ENABLE_LONG_TESTS', None)
            os.environ['YGG_ENABLE_LONG_TESTS'] = 'True'
        if args.withcoverage:
            old_env['COVERAGE_PROCESS_START'] = os.environ.get(
                'COVERAGE_PROCESS_START', None)
            os.environ['COVERAGE_PROCESS_START'] = 'True'
            with open(pth_file, 'w') as fd:
                fd.write("import coverage; coverage.process_startup()")
        if args.test_suites and ('timing' in args.test_suites):
            old_env['YGG_TEST_PRODUCTION_RUNS'] = os.environ.get(
                'YGG_TEST_PRODUCTION_RUNS', None)
            os.environ['YGG_TEST_PRODUCTION_RUNS'] = 'True'
        if not args.validatecomponents:
            old_env['YGG_SKIP_COMPONENT_VALIDATION'] = os.environ.get(
                'YGG_SKIP_COMPONENT_VALIDATION', None)
            if old_env['YGG_SKIP_COMPONENT_VALIDATION'] is None:
                os.environ['YGG_SKIP_COMPONENT_VALIDATION'] = 'True'
        # Perform CI specific pretest operations
        if args.ci:
            top_dir = os.path.dirname(os.getcwd())
            src_cmd = ('python -c \"import versioneer; '
                       'print(versioneer.get_version())\"')
            dst_cmd = ('python -c \"import yggdrasil; '
                       'print(yggdrasil.__version__)\"')
            src_ver = subprocess.check_output(src_cmd, shell=True)
            dst_ver = subprocess.check_output(dst_cmd, shell=True, cwd=top_dir)
            if src_ver != dst_ver:  # pragma: debug
                raise RuntimeError(
                    ("Versions do not match:\n"
                     "\tSource version: %s\n"
                     "\tBuild  version: %s\n") % (src_ver, dst_ver))
            if os.environ.get("INSTALLR", None) == "1":
                from yggdrasil import tools
                print(tools.which("R"))
                print(tools.which("Rscript"))
            subprocess.check_call(["flake8", "yggdrasil"])
            if os.environ.get("YGG_CONDA", None):
                subprocess.check_call(["python", "create_coveragerc.py"])
            if not os.path.isfile(".coveragerc"):
                raise RuntimeError(".coveragerc file dosn't exist.")
            with open(".coveragerc", "r") as fd:
                print(fd.read())
            subprocess.check_call(["ygginfo", "--verbose"])
        error_code = subprocess.call(argv)
    except BaseException:
        logger.exception('Error in running test.')
        error_code = -1
    finally:
        os.chdir(initial_dir)
        for k, v in old_env.items():
            if v is None:
                del os.environ[k]
            else:
                os.environ[k] = v
        if os.path.isfile(pth_file):
            os.remove(pth_file)
    return error_code