Skip to content

Commit

Permalink
exec-test clear testing environment
Browse files Browse the repository at this point in the history
This commit adds more control over the environment variables in
exec-tests for users. It brings a way how to clear the test environment
during the test runtime so it won't affect the test script. Only thing
which user needs to do is to set the runner.exectest.clear_env to
`system` or `all` in tests config.

Reference: #5889
Signed-off-by: Jan Richter <[email protected]>
  • Loading branch information
richtja committed Apr 25, 2024
1 parent 9e51688 commit 24f821f
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 18 deletions.
14 changes: 14 additions & 0 deletions avocado/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,20 @@ def register_core_options():
help_msg=help_msg,
)

help_msg = (
"If and how to clear test environment. Two possible options, "
"`system` and `all`. "
"`system` = no variables set, besides avocados default and kwargs. "
"`all` = only kwargs are set."
)
stgs.register_option(
section="runner.exectest",
key="clear_env",
key_type=str,
default=None,
help_msg=help_msg,
)

help_msg = (
"By default Avocado runners will use the {uri} of a test as "
"its identifier. Use a custom f-string identifier in order to "
Expand Down
14 changes: 11 additions & 3 deletions avocado/plugins/runners/exec_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ class ExecTestRunner(BaseRunner):
name = "exec-test"
description = "Runner for standalone executables treated as tests"

CONFIGURATION_USED = ["run.keep_tmp", "runner.exectest.exitcodes.skip"]
CONFIGURATION_USED = [
"run.keep_tmp",
"runner.exectest.exitcodes.skip",
"runner.exectest.clear_env",
]

def _process_final_status(
self, process, runnable, stdout=None, stderr=None
Expand Down Expand Up @@ -119,15 +123,19 @@ def _is_uri_a_file_on_cwd(uri):
return False

def _get_env(self, runnable):
env = dict(os.environ)
clear_env = runnable.config.get("runner.exectest.clear_env", None)
if clear_env in ["all", "system"]:
env = {}
else:
env = dict(os.environ)
if runnable.kwargs:
env.update(runnable.kwargs)
for key, value in runnable.kwargs.items():
if value is None:
del env[key]

# set default Avocado environment variables if running on a valid Task
if runnable.uri is not None:
if runnable.uri is not None and clear_env != "all":
avocado_test_env_variables = self._get_env_variables(runnable)
# save environment variables for further cleanup
runnable.kwargs.update(avocado_test_env_variables)
Expand Down
9 changes: 9 additions & 0 deletions docs/source/guides/writer/chapters/basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,12 @@ disable those variables during the test runtime. To disable a test variable,
you need to set it in test ``kwargs`` to ``None`` like this::

Runnable("exec-test", "examples/tests/sleeptest.sh", SLEEP_LENGTH=None)

If you need to clear the whole environment before your test, then you can set
``runner.exectest.clear_env`` config variable. This variable has two options.
``system`` and ``all``. If you use ``system`` option the testing environment
will have only Avocado default variables and variables from test ``kwargs``.
If you use ``all`` option, the testing environment will have only variables
from test ``kwargs``::

Runnable("exec-test", "examples/tests/sleeptest.sh", config={'runner.exectest.clear_env': system}, SLEEP_LENGTH=1)
2 changes: 1 addition & 1 deletion selftests/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"nrunner-requirement": 24,
"unit": 669,
"jobs": 11,
"functional-parallel": 303,
"functional-parallel": 305,
"functional-serial": 6,
"optional-plugins": 0,
"optional-plugins-golang": 2,
Expand Down
40 changes: 26 additions & 14 deletions selftests/functional/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,12 @@ def test(self):
"""

EXEC_ENV_VARIABLE_TEST = """#!/bin/bash
if [[ -n "${TEST_ENV}" ]]; then
if [[ -n "${TEST_ENV}" ]]; then
exit 1
fi
if [[ -z "${AVOCADO_VERSION}" ]]; then
exit 2
fi
"""


Expand Down Expand Up @@ -1002,6 +1005,20 @@ def setUp(self):
)
self.fail_script.save()

def _test_env(self, configuration, expected_rc):
with script.TemporaryScript("exec_env_var.sh", EXEC_ENV_VARIABLE_TEST) as tst:
res = process.run(
f"env TEST_ENV=test avocado-runner-exec-test runnable-run -k exec-test -u {tst}",
)
result = res.stdout_text.split("\n")[-2]
self.assertIn("'returncode': 1", result, "The test might be corrupted.")

res = process.run(
f"env TEST_ENV=test avocado-runner-exec-test runnable-run -k exec-test -u {tst} {configuration}"
)
result = res.stdout_text.split("\n")[-2]
self.assertIn(f"'returncode': {expected_rc}", result)

def test_exec_test_pass(self):
cmd_line = (
f"{AVOCADO} run --job-results-dir {self.tmpdir.name} "
Expand Down Expand Up @@ -1101,20 +1118,15 @@ def test_non_absolute_path(self):

@skipUnlessPathExists("/bin/bash")
def test_env_var_disable(self):
with script.TemporaryScript("exec_env_var.sh", EXEC_ENV_VARIABLE_TEST) as tst:
res = process.run(
f"env TEST_ENV=test avocado-runner-exec-test runnable-run -k exec-test -u {tst}",
)
result = res.stdout_text.split("\n")[-2]
self.assertIn("'returncode': 1", result, "The test might be corrupted.")
self._test_env("TEST_ENV=json:null", 0)

res = process.run(
f"env TEST_ENV=test avocado-runner-exec-test runnable-run -k exec-test -u {tst} TEST_ENV=json:null",
)
result = res.stdout_text.split("\n")[-2]
self.assertIn(
"'returncode': 0", result, "The env variable was not disabled."
)
@skipUnlessPathExists("/bin/sh")
def test_env_clear_system(self):
self._test_env('-c \'{"runner.exectest.clear_env": "system"}\'', 0)

@skipUnlessPathExists("/bin/sh")
def test_env_clear_all(self):
self._test_env('-c \'{"runner.exectest.clear_env": "all"}\'', 2)

def tearDown(self):
self.pass_script.remove()
Expand Down

0 comments on commit 24f821f

Please sign in to comment.