MolSSI / QCEngine

Quantum chemistry program executor and IO standardizer (QCSchema).
https://molssi.github.io/QCEngine/
BSD 3-Clause "New" or "Revised" License
168 stars 80 forks source link

Tests failing on master after py-cpuinfo update #252

Closed mattwthompson closed 4 years ago

mattwthompson commented 4 years ago

Describe the bug I'm hunting down some CI failures and have ended up here. It looks like py-cpuiunfo updated one of their dict keys ("brand" -> "brand_raw") which I will file a PR for in a moment. RDKit also made a release last week, but that does not seem to be the issue.

To Reproduce after conda env create --name qcengine --file devtools/conda-envs/rdkit.yaml and activating it,

Click to expand pytest && pytest -v --lf openmm_cmiles ============================================= test session starts ============================================== platform darwin -- Python 3.8.3, pytest-5.4.3, py-1.8.2, pluggy-0.13.1 rootdir: /Users/mwt/software/QCEngine, inifile: setup.cfg plugins: cov-2.10.0 collected 475 items / 4 skipped / 471 selected qcengine/programs/tests/test_dftd3_mp2d.py sssss......................ssssssssssssssssssssssssssssssssss [ 12%] ssssssssssssssssssssssssssssssssssssss [ 20%] qcengine/programs/tests/test_nwchem.py sssss [ 21%] qcengine/programs/tests/test_programs.py F.ssssssFFFFssFFFsss [ 26%] qcengine/programs/tests/test_standard_suite.py sssssssssssssssssssssssssssssssssssssssssssssssssssssssss [ 38%] ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss [ 60%] sssssssssssssssssssssssssssssssssssssssssssssssssssssss [ 71%] qcengine/programs/tests/test_standard_suite_ccsd(t).py sssssssssss [ 73%] qcengine/programs/tests/test_standard_suite_hf.py ssssssssssssssssssssssssssss [ 79%] qcengine/programs/tests/test_turbomole.py sssssssss [ 81%] qcengine/tests/test_cli.py .Fss [ 82%] qcengine/tests/test_config.py .............F.. [ 85%] qcengine/tests/test_harness_canonical.py sssssssssFsssssssssssFssssssssss.ss [ 93%] qcengine/tests/test_mdi.py s [ 93%] qcengine/tests/test_procedures.py sssssssssssssss [ 96%] qcengine/tests/test_program_utils.py .ss...ss. [ 98%] qcengine/tests/test_utils.py ....... [100%] =================================================== FAILURES =================================================== _______________________________________________ test_missing_key _______________________________________________ def test_missing_key(): > ret = qcng.compute({"hello": "hi"}, "bleh") qcengine/programs/tests/test_programs.py:15: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/compute.py:102: in compute return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict) qcengine/util.py:181: in handle_output_metadata provenance_augments = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() > _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] E KeyError: 'brand' qcengine/config.py:52: KeyError _____________________________________________ test_rdkit_task[UFF] _____________________________________________ method = 'UFF' @using("rdkit") @pytest.mark.parametrize("method", ["UFF", "MMFF94", "MMFF94s"]) def test_rdkit_task(method): input_data = { "molecule": qcng.get_molecule("water"), "driver": "gradient", "model": {"method": method}, "keywords": {}, } > ret = qcng.compute(input_data, "rdkit", raise_error=True) qcengine/programs/tests/test_programs.py:143: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/compute.py:102: in compute return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict) qcengine/util.py:181: in handle_output_metadata provenance_augments = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] if key is None: return _global_values.copy() else: > return _global_values[key] E KeyError: 'cpu_brand' qcengine/config.py:57: KeyError ___________________________________________ test_rdkit_task[MMFF94] ____________________________________________ method = 'MMFF94' @using("rdkit") @pytest.mark.parametrize("method", ["UFF", "MMFF94", "MMFF94s"]) def test_rdkit_task(method): input_data = { "molecule": qcng.get_molecule("water"), "driver": "gradient", "model": {"method": method}, "keywords": {}, } > ret = qcng.compute(input_data, "rdkit", raise_error=True) qcengine/programs/tests/test_programs.py:143: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/compute.py:102: in compute return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict) qcengine/util.py:181: in handle_output_metadata provenance_augments = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] if key is None: return _global_values.copy() else: > return _global_values[key] E KeyError: 'cpu_brand' qcengine/config.py:57: KeyError ___________________________________________ test_rdkit_task[MMFF94s] ___________________________________________ method = 'MMFF94s' @using("rdkit") @pytest.mark.parametrize("method", ["UFF", "MMFF94", "MMFF94s"]) def test_rdkit_task(method): input_data = { "molecule": qcng.get_molecule("water"), "driver": "gradient", "model": {"method": method}, "keywords": {}, } > ret = qcng.compute(input_data, "rdkit", raise_error=True) qcengine/programs/tests/test_programs.py:143: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/compute.py:102: in compute return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict) qcengine/util.py:181: in handle_output_metadata provenance_augments = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] if key is None: return _global_values.copy() else: > return _global_values[key] E KeyError: 'cpu_brand' qcengine/config.py:57: KeyError ________________________________________ test_rdkit_connectivity_error _________________________________________ @using("rdkit") def test_rdkit_connectivity_error(): input_data = { "molecule": qcng.get_molecule("water").dict(), "driver": "energy", "model": {"method": "UFF", "basis": ""}, "keywords": {}, } del input_data["molecule"]["connectivity"] > ret = qcng.compute(input_data, "rdkit") qcengine/programs/tests/test_programs.py:158: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/compute.py:102: in compute return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict) qcengine/util.py:181: in handle_output_metadata provenance_augments = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] if key is None: return _global_values.copy() else: > return _global_values[key] E KeyError: 'cpu_brand' qcengine/config.py:57: KeyError ________________________________________ test_random_failure_no_retries ________________________________________ failure_engine = FailEngine(name='testing_random_name', scratch=False, thread_safe=True, thread_parallel=False, node_parallel=False, managed_memory=False, extras=None, iter_modes=[], ncalls=1, start_distance=5, equilibrium_distance=4) def test_random_failure_no_retries(failure_engine): failure_engine.iter_modes = ["input_error"] > ret = qcng.compute(failure_engine.get_job(), failure_engine.name, raise_error=False) qcengine/programs/tests/test_programs.py:210: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/compute.py:102: in compute return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict) qcengine/util.py:181: in handle_output_metadata provenance_augments = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] if key is None: return _global_values.copy() else: > return _global_values[key] E KeyError: 'cpu_brand' qcengine/config.py:57: KeyError _______________________________________ test_random_failure_with_retries _______________________________________ failure_engine = FailEngine(name='testing_random_name', scratch=False, thread_safe=True, thread_parallel=False, node_parallel=False, managed_memory=False, extras=None, iter_modes=[], ncalls=3, start_distance=5, equilibrium_distance=4) def test_random_failure_with_retries(failure_engine): failure_engine.iter_modes = ["random_error", "random_error", "random_error"] > ret = qcng.compute(failure_engine.get_job(), failure_engine.name, raise_error=False, local_options={"retries": 2}) qcengine/programs/tests/test_programs.py:223: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/compute.py:102: in compute return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict) qcengine/util.py:181: in handle_output_metadata provenance_augments = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] if key is None: return _global_values.copy() else: > return _global_values[key] E KeyError: 'cpu_brand' qcengine/config.py:57: KeyError _______________________________________ test_random_failure_with_success _______________________________________ failure_engine = FailEngine(name='testing_random_name', scratch=False, thread_safe=True, thread_parallel=False, node_parallel=False, managed_memory=False, extras=None, iter_modes=[], ncalls=2, start_distance=5, equilibrium_distance=4) def test_random_failure_with_success(failure_engine): failure_engine.iter_modes = ["random_error", "pass"] failure_engine.ncalls = 0 > ret = qcng.compute(failure_engine.get_job(), failure_engine.name, raise_error=False, local_options={"retries": 1}) qcengine/programs/tests/test_programs.py:237: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/compute.py:102: in compute return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict) qcengine/util.py:181: in handle_output_metadata provenance_augments = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] if key is None: return _global_values.copy() else: > return _global_values[key] E KeyError: 'cpu_brand' qcengine/config.py:57: KeyError __________________________________________________ test_info ___________________________________________________ def test_info(): """Test for qcengine info""" outputs = [] for arg in cli.info_choices: > output = run_qcengine_cli(["info", arg]) qcengine/tests/test_cli.py:50: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/tests/test_cli.py:35: in run_qcengine_cli return subprocess.check_output([sys.executable, "-m", "qcengine"] + args, input=stdin) ../miniconda3/envs/qcengine/lib/python3.8/subprocess.py:411: in check_output return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = b'', capture_output = False, timeout = None, check = True popenargs = (['/Users/mwt/software/miniconda3/envs/qcengine/bin/python', '-m', 'qcengine', 'info', 'config'],) kwargs = {'stdin': -1, 'stdout': -1}, process = stdout = b'>>> Configuration information\n\n', stderr = None, retcode = 1 def run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs): """Run command with arguments and return a CompletedProcess instance. The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured. If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised. There is an optional argument "input", allowing you to pass bytes or a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it will be used internally. By default, all communication is in bytes, and therefore any "input" should be bytes, and the stdout and stderr will be bytes. If in text mode, any "input" should be a string, and stdout and stderr will be strings decoded according to locale encoding, or by "encoding" if set. Text mode is triggered by setting any of text, encoding, errors or universal_newlines. The other arguments are the same as for the Popen constructor. """ if input is not None: if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE kwargs['stderr'] = PIPE with Popen(*popenargs, **kwargs) as process: try: stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired as exc: process.kill() if _mswindows: # Windows accumulates the output in a single blocking # read() call run on child threads, with the timeout # being done in a join() on those threads. communicate() # _after_ kill() is required to collect that and add it # to the exception. exc.stdout, exc.stderr = process.communicate() else: # POSIX _communicate already populated the output so # far into the TimeoutExpired exception. process.wait() raise except: # Including KeyboardInterrupt, communicate handled that. process.kill() # We don't call process.wait() as .__exit__ does that for us. raise retcode = process.poll() if check and retcode: > raise CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) E subprocess.CalledProcessError: Command '['/Users/mwt/software/miniconda3/envs/qcengine/bin/python', '-m', 'qcengine', 'info', 'config']' returned non-zero exit status 1. ../miniconda3/envs/qcengine/lib/python3.8/subprocess.py:512: CalledProcessError --------------------------------------------- Captured stderr call --------------------------------------------- Traceback (most recent call last): File "/Users/mwt/software/miniconda3/envs/qcengine/lib/python3.8/runpy.py", line 194, in _run_module_as_main return _run_code(code, main_globals, None, File "/Users/mwt/software/miniconda3/envs/qcengine/lib/python3.8/runpy.py", line 87, in _run_code exec(code, run_globals) File "/Users/mwt/software/QCEngine/qcengine/__main__.py", line 3, in qcengine.cli.main() File "/Users/mwt/software/QCEngine/qcengine/cli.py", line 163, in main info_cli(args) File "/Users/mwt/software/QCEngine/qcengine/cli.py", line 132, in info_cli print(global_repr()) File "/Users/mwt/software/QCEngine/qcengine/config.py", line 199, in global_repr prov = get_provenance_augments() File "/Users/mwt/software/QCEngine/qcengine/config.py", line 321, in get_provenance_augments "cpu": get_global("cpu_brand"), File "/Users/mwt/software/QCEngine/qcengine/config.py", line 52, in get_global _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] KeyError: 'brand' _______________________________________________ test_global_repr _______________________________________________ def test_global_repr(): > assert isinstance(qcng.config.global_repr(), str) qcengine/tests/test_config.py:215: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/config.py:199: in global_repr prov = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] if key is None: return _global_values.copy() else: > return _global_values[key] E KeyError: 'cpu_brand' qcengine/config.py:57: KeyError ______________________________________ test_compute_energy[rdkit-model9] _______________________________________ program = 'rdkit', model = {'method': 'UFF'} @pytest.mark.parametrize("program, model", _canonical_methods) def test_compute_energy(program, model): if not has_program(program): pytest.skip("Program '{}' not found.".format(program)) molecule = _get_molecule(program) inp = AtomicInput(molecule=molecule, driver="energy", model=model) > ret = qcng.compute(inp, program, raise_error=True) qcengine/tests/test_harness_canonical.py:44: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/compute.py:102: in compute return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict) qcengine/util.py:181: in handle_output_metadata provenance_augments = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] if key is None: return _global_values.copy() else: > return _global_values[key] E KeyError: 'cpu_brand' qcengine/config.py:57: KeyError _____________________________________ test_compute_gradient[rdkit-model9] ______________________________________ program = 'rdkit', model = {'method': 'UFF'} @pytest.mark.parametrize("program, model", _canonical_methods) def test_compute_gradient(program, model): if not has_program(program): pytest.skip("Program '{}' not found.".format(program)) molecule = _get_molecule(program) inp = AtomicInput(molecule=molecule, driver="gradient", model=model, extras={"mytag": "something"}) > ret = qcng.compute(inp, program, raise_error=True) qcengine/tests/test_harness_canonical.py:58: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/compute.py:102: in compute return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict) qcengine/util.py:181: in handle_output_metadata provenance_augments = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] if key is None: return _global_values.copy() else: > return _global_values[key] E KeyError: 'cpu_brand' qcengine/config.py:57: KeyError =============================================== warnings summary =============================================== qcengine/programs/tests/test_programs.py::test_rdkit_task[UFF] :219: RuntimeWarning: numpy.ufunc size changed, may indicate binary incompatibility. Expected 192 from C header, got 216 from PyObject -- Docs: https://docs.pytest.org/en/latest/warnings.html =========================================== short test summary info ============================================ FAILED qcengine/programs/tests/test_programs.py::test_missing_key - KeyError: 'brand' FAILED qcengine/programs/tests/test_programs.py::test_rdkit_task[UFF] - KeyError: 'cpu_brand' FAILED qcengine/programs/tests/test_programs.py::test_rdkit_task[MMFF94] - KeyError: 'cpu_brand' FAILED qcengine/programs/tests/test_programs.py::test_rdkit_task[MMFF94s] - KeyError: 'cpu_brand' FAILED qcengine/programs/tests/test_programs.py::test_rdkit_connectivity_error - KeyError: 'cpu_brand' FAILED qcengine/programs/tests/test_programs.py::test_random_failure_no_retries - KeyError: 'cpu_brand' FAILED qcengine/programs/tests/test_programs.py::test_random_failure_with_retries - KeyError: 'cpu_brand' FAILED qcengine/programs/tests/test_programs.py::test_random_failure_with_success - KeyError: 'cpu_brand' FAILED qcengine/tests/test_cli.py::test_info - subprocess.CalledProcessError: Command '['/Users/mwt/software/... FAILED qcengine/tests/test_config.py::test_global_repr - KeyError: 'cpu_brand' FAILED qcengine/tests/test_harness_canonical.py::test_compute_energy[rdkit-model9] - KeyError: 'cpu_brand' FAILED qcengine/tests/test_harness_canonical.py::test_compute_gradient[rdkit-model9] - KeyError: 'cpu_brand' ============================ 12 failed, 52 passed, 415 skipped, 1 warning in 9.20s =============================

Additional context