Clean up some gmxapi sources and tests.
[alexxy/gromacs.git] / python_packaging / src / test / conftest.py
index 6de576d1cabe687ca1e980f7efd2ad3d6d6dd243..e78bcad0d7c1e5ff7f31f3a06d5707781e4fcd1c 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2019, by the GROMACS development team, led by
+# Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
 # Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
 # and including many others, as listed in the AUTHORS file in the
 # top-level source directory and at http://www.gromacs.org.
 import json
 import logging
 import os
-import shutil
-import tempfile
-import warnings
-from contextlib import contextmanager
 
 import pytest
 
 pytest_plugins = ('gmxapi.testsupport',)
 
-def pytest_addoption(parser):
-    """Add a command-line user option for the pytest invocation."""
-    parser.addoption(
-        '--rm',
-        action='store',
-        default='always',
-        choices=['always', 'never', 'success'],
-        help='Remove temporary directories "always", "never", or on "success".'
-    )
-
-
-@pytest.fixture(scope='session')
-def remove_tempdir(request):
-    """pytest fixture to get access to the --rm CLI option."""
-    return request.config.getoption('--rm')
-
-
-@contextmanager
-def scoped_chdir(dir):
-    oldpath = os.getcwd()
-    os.chdir(dir)
-    try:
-        yield dir
-        # If the `with` block using scoped_chdir produces an exception, it will
-        # be raised at this point in this function. We want the exception to
-        # propagate out of the `with` block, but first we want to restore the
-        # original working directory, so we skip `except` but provide a `finally`.
-    finally:
-        os.chdir(oldpath)
-
-
-@contextmanager
-def _cleandir(remove_tempdir):
-    """Context manager for a clean temporary working directory.
-
-    Arguments:
-        remove_tempdir (str): whether to remove temporary directory "always",
-                              "never", or on "success"
-
-    The context manager will issue a warning for each temporary directory that
-    is not removed.
-    """
-
-    newpath = tempfile.mkdtemp()
-
-    def remove():
-        shutil.rmtree(newpath)
-
-    def warn():
-        warnings.warn('Temporary directory not removed: {}'.format(newpath))
-
-    if remove_tempdir == 'always':
-        callback = remove
-    else:
-        callback = warn
-    try:
-        with scoped_chdir(newpath):
-            yield newpath
-        # If we get to this line, the `with` block using _cleandir did not throw.
-        # Clean up the temporary directory unless the user specified `--rm never`.
-        # I.e. If the user specified `--rm success`, then we need to toggle from `warn` to `remove`.
-        if remove_tempdir != 'never':
-            callback = remove
-    finally:
-        callback()
-
-
-@pytest.fixture
-def cleandir(remove_tempdir):
-    """Provide a clean temporary working directory for a test.
-
-    Example usage:
-
-        import os
-        import pytest
-
-        @pytest.mark.usefixtures("cleandir")
-        def test_cwd_starts_empty():
-            assert os.listdir(os.getcwd()) == []
-            with open("myfile", "w") as f:
-                f.write("hello")
-
-        def test_cwd_also_starts_empty(cleandir):
-            assert os.listdir(os.getcwd()) == []
-            assert os.path.abspath(os.getcwd()) == os.path.abspath(cleandir)
-            with open("myfile", "w") as f:
-                f.write("hello")
-
-        @pytest.mark.usefixtures("cleandir")
-        class TestDirectoryInit(object):
-            def test_cwd_starts_empty(self):
-                assert os.listdir(os.getcwd()) == []
-                with open("myfile", "w") as f:
-                    f.write("hello")
-
-            def test_cwd_also_starts_empty(self):
-                assert os.listdir(os.getcwd()) == []
-                with open("myfile", "w") as f:
-                    f.write("hello")
-
-    Ref: https://docs.pytest.org/en/latest/fixture.html#using-fixtures-from-classes-modules-or-projects
-    """
-    with _cleandir(remove_tempdir) as newdir:
-        yield newdir
-
 
 @pytest.fixture(scope='session')
-def gmxcli():
-    # TODO: (#2896) Find a more canonical way to identify the GROMACS commandline wrapper binary.
-    #  We should be able to get the GMXRC contents and related hints from a gmxapi
-    #  package resource or from module attributes of a ``gromacs`` stub package.
-    allowed_command_names = ['gmx', 'gmx_mpi']
-    command = None
-    for command_name in allowed_command_names:
-        if command is not None:
-            break
-        command = shutil.which(command_name)
-        if command is None:
-            gmxbindir = os.getenv('GMXBIN')
-            if gmxbindir is None:
-                gromacsdir = os.getenv('GROMACS_DIR')
-                if gromacsdir is not None and gromacsdir != '':
-                    gmxbindir = os.path.join(gromacsdir, 'bin')
-            if gmxbindir is None:
-                gmxapidir = os.getenv('gmxapi_DIR')
-                if gmxapidir is not None and gmxapidir != '':
-                    gmxbindir = os.path.join(gmxapidir, 'bin')
-            if gmxbindir is not None:
-                gmxbindir = os.path.abspath(gmxbindir)
-                command = shutil.which(command_name, path=gmxbindir)
-    if command is None:
-        message = "Tests need 'gmx' command line tool, but could not find it on the path."
-        raise RuntimeError(message)
-    try:
-        assert os.access(command, os.X_OK)
-    except Exception as E:
-        raise RuntimeError('"{}" is not an executable gmx wrapper program'.format(command)) from E
-    yield command
-
-
-@pytest.fixture(scope='class')
-def spc_water_box(gmxcli, remove_tempdir):
-    """Provide a TPR input file for a simple simulation.
+def spc_water_box_collection(gmxcli, remove_tempdir):
+    """Provide a collection of simulation input items for a simple simulation.
 
     Prepare the MD input in a freshly created working directory.
+    Solvate a 5nm cubic box with spc water. Return a dictionary of the artifacts produced.
     """
     import gmxapi as gmx
+    # TODO: Remove this import when the the spc_water_box fixture is migrated to gmxapi.testsupport
+    from gmxapi.testsupport import _cleandir
 
     # TODO: (#2896) Fetch MD input from package / library data.
     # Example:
@@ -237,11 +97,11 @@ def spc_water_box(gmxcli, remove_tempdir):
         assert os.path.exists(topfile)
 
         if solvate.output.returncode.result() != 0:
-            logging.debug(solvate.output.erroroutput.result())
+            logging.debug(solvate.output.stderr.result())
             raise RuntimeError('solvate failed in spc_water_box testing fixture.')
 
         # Choose an exactly representable dt of 2^-9 ps (approximately 0.002)
-        dt = 2.**-9.
+        dt = 2. ** -9.
         mdp_input = [('integrator', 'md'),
                      ('dt', dt),
                      ('cutoff-scheme', 'Verlet'),
@@ -273,9 +133,23 @@ def spc_water_box(gmxcli, remove_tempdir):
                                            output_files={'-o': tprfile})
         tprfilename = grompp.output.file['-o'].result()
         if grompp.output.returncode.result() != 0:
-            logging.debug(grompp.output.erroroutput.result())
+            logging.debug(grompp.output.stderr.result())
             raise RuntimeError('grompp failed in spc_water_box testing fixture.')
 
         # TODO: more inspection of grompp errors...
         assert os.path.exists(tprfilename)
-        yield tprfilename
+        collection = {
+            'tpr_filename': tprfilename,
+            'mdp_input_filename': mdpfile,
+            'mdp_output_filename': mdout_mdp,
+            'topology_filename': solvate.output.file['-p'].result(),
+            'gro_filename': solvate.output.file['-o'].result(),
+            'mdp_input_list': mdp_input
+        }
+        yield collection
+
+
+@pytest.fixture(scope='session')
+def spc_water_box(spc_water_box_collection):
+    """Provide a TPR input file for a simple simulation."""
+    yield spc_water_box_collection['tpr_filename']