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
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
# 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"',
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_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")
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)
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")
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)