Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature #2253 conftest fixture to set pytest tmpdir #2261

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/Contributors_Guide/github_workflow.rst
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ Create a feature branch

.. code-block:: ini

git fetch upstream develop
git checkout develop

* Verify the current development branch is active by running:
Expand Down
6 changes: 0 additions & 6 deletions docs/Contributors_Guide/testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,6 @@ permissions, navigate to the METplus directory, then call pytest::
cd METplus
pytest internal/tests/pytests

Some of the tests use your default location for writing temporary files,
typically `/tmp`. If you do not have write permissions this may cause an
error. To override this behaviour you can specify the default directory::

pytest --basetemp=${METPLUS_TEST_OUTPUT_BASE}/tmp internal/tests/pytests

A report will be output showing which pytest categories failed.
To view verbose test output, add the **-vv** argument::

Expand Down
44 changes: 34 additions & 10 deletions internal/tests/pytests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,48 @@

from metplus.util import config_metplus

output_base = os.environ.get('METPLUS_TEST_OUTPUT_BASE')
output_base = os.environ.get("METPLUS_TEST_OUTPUT_BASE")
if not output_base:
print('ERROR: METPLUS_TEST_OUTPUT_BASE must be set to a path to write')
print("ERROR: METPLUS_TEST_OUTPUT_BASE must be set to a path to write")
sys.exit(1)

try:
test_output_dir = os.path.join(output_base, 'test_output')
test_output_dir = os.path.join(output_base, "test_output")
if os.path.exists(test_output_dir):
print(f'Removing test output dir: {test_output_dir}')
print(f"Removing test output dir: {test_output_dir}")
shutil.rmtree(test_output_dir)

if not os.path.exists(test_output_dir):
print(f'Creating test output dir: {test_output_dir}')
print(f"Creating test output dir: {test_output_dir}")
os.makedirs(test_output_dir)
except PermissionError:
print(f'ERROR: Cannot write to $METPLUS_TEST_OUTPUT_BASE: {output_base}')
print(f"ERROR: Cannot write to $METPLUS_TEST_OUTPUT_BASE: {output_base}")
sys.exit(2)


@pytest.fixture(scope="session", autouse=True)
def custom_tmpdir():
"""! Set the default output location for temp files produced by pytest
to METPLUS_TEST_OUTPUT_BASE env var. Causes default pytest fixtures,
such as tmpdir_factory, to write temp files to this dir.

A sub directory named 'pytest_tmp' is created to ensure there will never
be name conflicts between files created by default pytest fixture and
other methods for writing temp files.
"""
original_var = os.environ.get("PYTEST_DEBUG_TEMPROOT", None)
output_base = os.environ.get("METPLUS_TEST_OUTPUT_BASE")
temp_base = os.path.join(output_base, "pytest_tmp")

os.environ["PYTEST_DEBUG_TEMPROOT"] = temp_base
if not os.path.exists(temp_base):
os.mkdir(temp_base)
yield
# Restore original value, if existed
if original_var:
os.environ["PYTEST_DEBUG_TEMPROOT"] = original_var


@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
"""! This is used to capture the status of a test so the metplus_config
Expand All @@ -58,19 +81,19 @@ def metplus_config(request):
config = metplus_config.
"""
script_dir = os.path.dirname(__file__)
args = [os.path.join(script_dir, 'minimum_pytest.conf')]
args = [os.path.join(script_dir, "minimum_pytest.conf")]
config = config_metplus.setup(args)
yield config

# don't remove output base if test fails
if request.node.rep_call.failed:
return
config_output_base = config.getdir('OUTPUT_BASE')
config_output_base = config.getdir("OUTPUT_BASE")
if config_output_base and os.path.exists(config_output_base):
shutil.rmtree(config_output_base)


@pytest.fixture(scope='function')
@pytest.fixture(scope="function")
def metplus_config_files():
"""! Create a METplus configuration object using minimum_pytest.conf
settings and any list of config files.The metplus_config fixture is
Expand All @@ -79,10 +102,11 @@ def metplus_config_files():
metplus_config_files as an argument to the test function and pass in a list
of config files to it. Example: config = metplus_config_files([my_file])
"""

def read_configs(extra_configs):
# Read in minimum pytest config file and any other extra configs
script_dir = os.path.dirname(__file__)
minimum_conf = os.path.join(script_dir, 'minimum_pytest.conf')
minimum_conf = os.path.join(script_dir, "minimum_pytest.conf")
args = extra_configs.copy()
args.append(minimum_conf)
config = config_metplus.setup(args)
Expand Down