def test_avail_core_count_linux(self):
     """Test getting core count (mocked for Linux)."""
     st.get_os_type = lambda: st.LINUX
     orig_sched_getaffinity = st.sched_getaffinity
     class MockedSchedGetaffinity(object):
         cpus = [1L, 1L, 0L, 0L, 1L, 1L, 0L, 0L, 1L, 1L, 0L, 0L]
     st.sched_getaffinity = lambda: MockedSchedGetaffinity()
     self.assertEqual(get_avail_core_count(), 6)
     st.sched_getaffinity = orig_sched_getaffinity
Exemplo n.º 2
0
def get_build_stats(app, start_time, command_line):
    """
    Return build statistics for this build
    """

    time_now = time.time()
    build_time = round(time_now - start_time, 2)

    buildstats = OrderedDict([
        ('easybuild-framework_version', str(FRAMEWORK_VERSION)),
        ('easybuild-easyblocks_version', str(EASYBLOCKS_VERSION)),
        ('host', os.uname()[1]),
        ('platform', platform.platform()),
        ('cpu_model', get_cpu_model()),
        ('core_count', get_avail_core_count()),
        ('timestamp', int(time_now)),
        ('build_time', build_time),
        ('install_size', app.det_installsize()),
        ('command_line', command_line),
        ('modules_tool', app.modules_tool.buildstats()),
    ])

    return buildstats
Exemplo n.º 3
0
            # patch do_regtest so that reference output is used
            if regtest_refdir:
                self.log.info("Using reference output available in %s" % regtest_refdir)
                try:
                    for line in fileinput.input(regtest_script, inplace=1, backup='.orig.refout'):
                        line = re.sub(r"^(dir_last\s*=\${dir_base})/.*$", r"\1/%s" % regtest_refdir, line)
                        sys.stdout.write(line)
                except IOError, err:
                    raise EasyBuildError("Failed to modify '%s': %s", regtest_script, err)

            else:
                self.log.info("No reference output found for regression test, just continuing without it...")

            test_core_cnt = min(self.cfg.get('parallel', sys.maxint), 2)
            if get_avail_core_count() < test_core_cnt:
                raise EasyBuildError("Cannot run MPI tests as not enough cores (< %s) are available", test_core_cnt)
            else:
                self.log.info("Using %s cores for the MPI tests" % test_core_cnt)

            # configure regression test
            cfg_txt = '\n'.join([
                'FORT_C_NAME="%(f90)s"',
                'dir_base=%(base)s',
                'cp2k_version=%(cp2k_version)s',
                'dir_triplet=%(triplet)s',
                'export ARCH=${dir_triplet}',
                'cp2k_dir=%(cp2k_dir)s',
                'leakcheck="YES"',
                'maxtasks=%(maxtasks)s',
                'cp2k_run_prefix="%(mpicmd_prefix)s"',
Exemplo n.º 4
0
 def test_avail_core_count_darwin(self):
     """Test getting core count (mocked for Darwin)."""
     st.get_os_type = lambda: st.DARWIN
     st.run_cmd = mocked_run_cmd
     self.assertEqual(get_avail_core_count(), 10)
Exemplo n.º 5
0
    def test_step(self):
        """Run regression test."""

        if self.cfg['runtest']:

            # we need to specify location of 'data' directory in *build* dir,
            # since we've configured CP2K to look into the installation directory
            # (where 'data' will be copied to in install step)
            setvar('CP2K_DATA_DIR', os.path.join(self.cfg['start_dir'],
                                                 'data'))

            if not build_option('mpi_tests'):
                self.log.info(
                    "Skipping testing of CP2K since MPI testing is disabled")
                return

            if self.cfg['omp_num_threads']:
                setvar('OMP_NUM_THREADS', self.cfg['omp_num_threads'])

            # change to root of build dir
            change_dir(self.builddir)

            # use regression test reference output if available
            # try and find an unpacked directory that starts with 'LAST-'
            regtest_refdir = None
            for d in os.listdir(self.builddir):
                if d.startswith("LAST-"):
                    regtest_refdir = d
                    break

            # location of do_regtest script
            cfg_fn = 'cp2k_regtest.cfg'

            regtest_script = os.path.join(self.cfg['start_dir'], 'tools',
                                          'regtesting', 'do_regtest')
            regtest_cmd = [regtest_script, '-nobuild', '-config', cfg_fn]
            if LooseVersion(self.version) < LooseVersion('7.1'):
                # -nosvn option was removed in CP2K 7.1
                regtest_cmd.insert(1, '-nosvn')

            # older version of CP2K
            if not os.path.exists(regtest_script):
                regtest_script = os.path.join(self.cfg['start_dir'], 'tools',
                                              'do_regtest')
                regtest_cmd = [
                    regtest_script, '-nocvs', '-quick', '-nocompile',
                    '-config', cfg_fn
                ]

            regtest_cmd = ' '.join(regtest_cmd)

            # patch do_regtest so that reference output is used
            if regtest_refdir:
                self.log.info("Using reference output available in %s" %
                              regtest_refdir)
                try:
                    for line in fileinput.input(regtest_script,
                                                inplace=1,
                                                backup='.orig.refout'):
                        line = re.sub(r"^(dir_last\s*=\${dir_base})/.*$",
                                      r"\1/%s" % regtest_refdir, line)
                        sys.stdout.write(line)
                except IOError as err:
                    raise EasyBuildError("Failed to modify '%s': %s",
                                         regtest_script, err)

            else:
                self.log.info(
                    "No reference output found for regression test, just continuing without it..."
                )

            # prefer using 4 cores, since some tests require/prefer square (n^2) numbers or powers of 2 (2^n)
            test_core_cnt = min(self.cfg['parallel'], 4)
            if get_avail_core_count() < test_core_cnt:
                raise EasyBuildError(
                    "Cannot run MPI tests as not enough cores (< %s) are available",
                    test_core_cnt)
            else:
                self.log.info("Using %s cores for the MPI tests" %
                              test_core_cnt)

            # configure regression test
            cfg_txt = '\n'.join([
                'FORT_C_NAME="%(f90)s"',
                'dir_base=%(base)s',
                'cp2k_version=%(cp2k_version)s',
                'dir_triplet=%(triplet)s',
                'export ARCH=${dir_triplet}',
                'cp2k_dir=%(cp2k_dir)s',
                'leakcheck="YES"',
                'maxtasks=%(maxtasks)s',
                'cp2k_run_prefix="%(mpicmd_prefix)s"',
            ]) % {
                'f90':
                os.getenv('F90'),
                'base':
                os.path.dirname(os.path.normpath(self.cfg['start_dir'])),
                'cp2k_version':
                self.cfg['type'],
                'triplet':
                self.typearch,
                'cp2k_dir':
                os.path.basename(os.path.normpath(self.cfg['start_dir'])),
                'maxtasks':
                self.cfg['maxtasks'],
                'mpicmd_prefix':
                self.toolchain.mpi_cmd_for('', test_core_cnt),
            }

            write_file(cfg_fn, cfg_txt)
            self.log.debug("Contents of %s: %s" % (cfg_fn, cfg_txt))

            # run regression test
            (regtest_output, ec) = run_cmd(regtest_cmd,
                                           log_all=True,
                                           simple=False,
                                           log_output=True)

            if ec == 0:
                self.log.info("Regression test output:\n%s" % regtest_output)
            else:
                raise EasyBuildError(
                    "Regression test failed (non-zero exit code): %s",
                    regtest_output)

            # pattern to search for regression test summary
            re_pattern = r"number\s+of\s+%s\s+tests\s+(?P<cnt>[0-9]+)"

            # find total number of tests
            regexp = re.compile(re_pattern % "", re.M | re.I)
            res = regexp.search(regtest_output)
            tot_cnt = None
            if res:
                tot_cnt = int(res.group('cnt'))
            else:
                raise EasyBuildError(
                    "Finding total number of tests in regression test summary failed"
                )

            # function to report on regtest results
            def test_report(test_result):
                """Report on tests with given result."""

                postmsg = ''

                test_result = test_result.upper()
                regexp = re.compile(re_pattern % test_result, re.M | re.I)

                cnt = None
                res = regexp.search(regtest_output)
                if not res:
                    raise EasyBuildError(
                        "Finding number of %s tests in regression test summary failed",
                        test_result.lower())
                else:
                    cnt = int(res.group('cnt'))

                logmsg = "Regression test reported %s / %s %s tests"
                logmsg_values = (cnt, tot_cnt, test_result.lower())

                # failed tests indicate problem with installation
                # wrong tests are only an issue when there are excessively many
                if (test_result == "FAILED"
                        and cnt > 0) or (test_result == "WRONG" and
                                         (cnt / tot_cnt) > 0.1):
                    if self.cfg['ignore_regtest_fails']:
                        self.log.warning(logmsg, *logmsg_values)
                        self.log.info(
                            "Ignoring failures in regression test, as requested."
                        )
                    else:
                        raise EasyBuildError(logmsg, *logmsg_values)
                elif test_result == "CORRECT" or cnt == 0:
                    self.log.info(logmsg, *logmsg_values)
                else:
                    self.log.warning(logmsg, *logmsg_values)

                return postmsg

            # number of failed/wrong tests, will report error if count is positive
            self.postmsg += test_report("FAILED")
            self.postmsg += test_report("WRONG")

            # there are no more 'new' tests from CP2K 8.1 onwards
            if LooseVersion(self.version) < LooseVersion('8.0'):
                # number of new tests, will be high if a non-suitable regtest reference was used
                # will report error if count is positive (is that what we want?)
                self.postmsg += test_report("NEW")

            # number of correct tests: just report
            test_report("CORRECT")
Exemplo n.º 6
0
 def test_avail_core_count_darwin(self):
     """Test getting core count (mocked for Darwin)."""
     st.get_os_type = lambda: st.DARWIN
     st.run_cmd = mocked_run_cmd
     self.assertEqual(get_avail_core_count(), 10)
 def test_avail_core_count_native(self):
     """Test getting core count."""
     core_count = get_avail_core_count()
     self.assertTrue(isinstance(core_count, int), "core_count has type int: %s, %s" % (core_count, type(core_count)))
     self.assertTrue(core_count > 0, "core_count %d > 0" % core_count)
Exemplo n.º 8
0
            # patch do_regtest so that reference output is used
            if regtest_refdir:
                self.log.info("Using reference output available in %s" % regtest_refdir)
                try:
                    for line in fileinput.input(regtest_script, inplace=1, backup='.orig.refout'):
                        line = re.sub(r"^(dir_last\s*=\${dir_base})/.*$", r"\1/%s" % regtest_refdir, line)
                        sys.stdout.write(line)
                except IOError, err:
                    raise EasyBuildError("Failed to modify '%s': %s", regtest_script, err)

            else:
                self.log.info("No reference output found for regression test, just continuing without it...")

            test_core_cnt = min(self.cfg.get('parallel', sys.maxint), 2)
            if get_avail_core_count() < test_core_cnt:
                raise EasyBuildError("Cannot run MPI tests as not enough cores (< %s) are available", test_core_cnt)
            else:
                self.log.info("Using %s cores for the MPI tests" % test_core_cnt)

            # configure regression test
            cfg_txt = '\n'.join([
                'FORT_C_NAME="%(f90)s"',
                'dir_base=%(base)s',
                'cp2k_version=%(cp2k_version)s',
                'dir_triplet=%(triplet)s',
                'export ARCH=${dir_triplet}',
                'cp2k_dir=%(cp2k_dir)s',
                'leakcheck="YES"',
                'maxtasks=%(maxtasks)s',
                'cp2k_run_prefix="%(mpicmd_prefix)s"',
Exemplo n.º 9
0
    def test_step(self):
        """Run regression test."""

        if self.cfg['runtest']:

            # we need to specify location of 'data' directory in *build* dir,
            # since we've configured CP2K to look into the installation directory
            # (where 'data' will be copied to in install step)
            setvar('CP2K_DATA_DIR', os.path.join(self.cfg['start_dir'], 'data'))

            if not build_option('mpi_tests'):
                self.log.info("Skipping testing of CP2K since MPI testing is disabled")
                return

            if self.cfg['omp_num_threads']:
                setvar('OMP_NUM_THREADS', self.cfg['omp_num_threads'])

            # change to root of build dir
            change_dir(self.builddir)

            # use regression test reference output if available
            # try and find an unpacked directory that starts with 'LAST-'
            regtest_refdir = None
            for d in os.listdir(self.builddir):
                if d.startswith("LAST-"):
                    regtest_refdir = d
                    break

            # location of do_regtest script
            cfg_fn = "cp2k_regtest.cfg"
            regtest_script = os.path.join(self.cfg['start_dir'], 'tools', 'regtesting', 'do_regtest')
            regtest_cmd = "%s -nosvn -nobuild -config %s" % (regtest_script, cfg_fn)
            # older version of CP2K
            if not os.path.exists(regtest_script):
                regtest_script = os.path.join(self.cfg['start_dir'], 'tools', 'do_regtest')
                regtest_cmd = "%s -nocvs -quick -nocompile -config %s" % (regtest_script, cfg_fn)

            # patch do_regtest so that reference output is used
            if regtest_refdir:
                self.log.info("Using reference output available in %s" % regtest_refdir)
                try:
                    for line in fileinput.input(regtest_script, inplace=1, backup='.orig.refout'):
                        line = re.sub(r"^(dir_last\s*=\${dir_base})/.*$", r"\1/%s" % regtest_refdir, line)
                        sys.stdout.write(line)
                except IOError as err:
                    raise EasyBuildError("Failed to modify '%s': %s", regtest_script, err)

            else:
                self.log.info("No reference output found for regression test, just continuing without it...")

            # prefer using 4 cores, since some tests require/prefer square (n^2) numbers or powers of 2 (2^n)
            test_core_cnt = min(self.cfg.get('parallel', sys.maxint), 4)
            if get_avail_core_count() < test_core_cnt:
                raise EasyBuildError("Cannot run MPI tests as not enough cores (< %s) are available", test_core_cnt)
            else:
                self.log.info("Using %s cores for the MPI tests" % test_core_cnt)

            # configure regression test
            cfg_txt = '\n'.join([
                'FORT_C_NAME="%(f90)s"',
                'dir_base=%(base)s',
                'cp2k_version=%(cp2k_version)s',
                'dir_triplet=%(triplet)s',
                'export ARCH=${dir_triplet}',
                'cp2k_dir=%(cp2k_dir)s',
                'leakcheck="YES"',
                'maxtasks=%(maxtasks)s',
                'cp2k_run_prefix="%(mpicmd_prefix)s"',
            ]) % {
                'f90': os.getenv('F90'),
                'base': os.path.dirname(os.path.normpath(self.cfg['start_dir'])),
                'cp2k_version': self.cfg['type'],
                'triplet': self.typearch,
                'cp2k_dir': os.path.basename(os.path.normpath(self.cfg['start_dir'])),
                'maxtasks': self.cfg['maxtasks'],
                'mpicmd_prefix': self.toolchain.mpi_cmd_for('', test_core_cnt),
            }

            write_file(cfg_fn, cfg_txt)
            self.log.debug("Contents of %s: %s" % (cfg_fn, cfg_txt))

            # run regression test
            (regtest_output, ec) = run_cmd(regtest_cmd, log_all=True, simple=False, log_output=True)

            if ec == 0:
                self.log.info("Regression test output:\n%s" % regtest_output)
            else:
                raise EasyBuildError("Regression test failed (non-zero exit code): %s", regtest_output)

            # pattern to search for regression test summary
            re_pattern = "number\s+of\s+%s\s+tests\s+(?P<cnt>[0-9]+)"

            # find total number of tests
            regexp = re.compile(re_pattern % "", re.M | re.I)
            res = regexp.search(regtest_output)
            tot_cnt = None
            if res:
                tot_cnt = int(res.group('cnt'))
            else:
                raise EasyBuildError("Finding total number of tests in regression test summary failed")

            # function to report on regtest results
            def test_report(test_result):
                """Report on tests with given result."""

                postmsg = ''

                test_result = test_result.upper()
                regexp = re.compile(re_pattern % test_result, re.M | re.I)

                cnt = None
                res = regexp.search(regtest_output)
                if not res:
                    raise EasyBuildError("Finding number of %s tests in regression test summary failed",
                                         test_result.lower())
                else:
                    cnt = int(res.group('cnt'))

                logmsg = "Regression test reported %s / %s %s tests"
                logmsg_values = (cnt, tot_cnt, test_result.lower())

                # failed tests indicate problem with installation
                # wrong tests are only an issue when there are excessively many
                if (test_result == "FAILED" and cnt > 0) or (test_result == "WRONG" and (cnt / tot_cnt) > 0.1):
                    if self.cfg['ignore_regtest_fails']:
                        self.log.warning(logmsg, *logmsg_values)
                        self.log.info("Ignoring failures in regression test, as requested.")
                    else:
                        raise EasyBuildError(logmsg, *logmsg_values)
                elif test_result == "CORRECT" or cnt == 0:
                    self.log.info(logmsg, *logmsg_values)
                else:
                    self.log.warning(logmsg, *logmsg_values)

                return postmsg

            # number of failed/wrong tests, will report error if count is positive
            self.postmsg += test_report("FAILED")
            self.postmsg += test_report("WRONG")

            # number of new tests, will be high if a non-suitable regtest reference was used
            # will report error if count is positive (is that what we want?)
            self.postmsg += test_report("NEW")

            # number of correct tests: just report
            test_report("CORRECT")
Exemplo n.º 10
0
 def test_core_count(self):
     """Test getting core count."""
     for core_count in [get_avail_core_count(), get_core_count()]:
         self.assertTrue(isinstance(core_count, int), "core_count has type int: %s, %s" % (core_count, type(core_count)))
         self.assertTrue(core_count > 0, "core_count %d > 0" % core_count)