未验证 提交 1642dbdf 编写于 作者: L Lukáš Doktor

Merging pull request 2097

Signed-off-by: NLukáš Doktor <ldoktor@redhat.com>

* https://github.com/avocado-framework/avocado:
  Docs: document the test process environment
  Docs: AVOCADO_* environment variables are available to all tests
......@@ -313,7 +313,13 @@ class TestRunner(object):
signal.signal(signal.SIGTERM, sigterm_handler)
# Replace STDIN (0) with the /dev/null's fd
# At this point, the original `sys.stdin` has already been
# closed and replaced with `os.devnull` by
# `multiprocessing.Process()` (not directly from Avocado
# code). Still, tests trying to use file descriptor 0 would
# be able to read from the tty, and would hang. Let's replace
# STDIN fd (0), with the same fd previously set by
# `multiprocessing.Process()`
os.dup2(sys.stdin.fileno(), 0)
instance = loader.load_test(test_factory)
......
......@@ -361,6 +361,72 @@ The instances should have:
.. [#f1] Avocado plugins can introduce additional test types.
Test execution environment
--------------------------
Each test is executed in a separate process. Due to how the
underlying operating system works, a lot of the attributes of the
parent process (the Avocado test **runner**) are passed down to the
test process.
On GNU/Linux systems, a child process should be *"an exact duplicate
of the parent process, except"* some items that are documented in
the ``fork(2)`` man page.
Besides those operating system exceptions, the Avocado test runner
changes the test process in the following ways:
1) The standard input (``STDIN``) is set to a :data:`null device
<os.devnull>`. This is truth both for :data:`sys.stdin` and for
file descriptor ``0``. Both will point to the same open null
device file.
2) The standard output (``STDOUT``), as in :data:`sys.stdout`, is
redirected so that it doesn't interfere with the test runner's own
output. All content written to the test's :data:`sys.stdout` will
be available in the logs under the ``output`` prefix.
.. warning:: The file descriptor ``1`` (AKA ``/dev/stdout``, AKA
``/proc/self/fd/1``, etc) is **not** currently
redirected for INSTRUMENTED tests. Any attempt to
write directly to the file descriptor will interfere
with the runner's own output stream. This behavior
will be addressed in a future version.
3) The standard error (``STDERR``), as in :data:`sys.stderr`, is
redirected so that it doesn't interfere with the test runner's own
errors. All content written to the test's :data:`sys.stderr` will
be available in the logs under the ``output`` prefix.
.. warning:: The file descriptor ``2`` (AKA ``/dev/stderr``, AKA
``/proc/self/fd/2``, etc) is **not** currently
redirected for INSTRUMENTED tests. Any attempt to
write directly to the file descriptor will interfere
with the runner's own error stream. This behavior
will be addressed in a future version.
4) A custom handler for signal ``SIGTERM`` which will simply raise an
exception (with the appropriate message) to be handled by the
Avocado test runner, stating the fact that the test was interrupted
by such a signal.
.. tip:: By following the backtrace that is given alongside the in
the test log (look for ``RuntimeError: Test interrupted
by SIGTERM``) a user can quickly grasp at which point the
test was interrupted.
.. note:: If the test handles ``SIGTERM`` differently and doesn't
finish the test process quickly enough, it will receive
then a ``SIGKILL`` which is supposed to definitely end
the test process.
5) A number of :ref:`environment variables
<environment-variables-for-tests>` that are set by Avocado, all
prefixed with ``AVOCADO_``.
If you want to see for yourself what is described here, you may want
to run the example test ``test_env.py`` and examine its log messages.
Pre and post plugins
====================
......
......@@ -1586,15 +1586,21 @@ from an outside source (say a "pickle" file). Finding and using a
reliable and safe location for saving such data is currently not in
the Avocado supported use cases.
Environment Variables for Simple Tests
======================================
.. _environment-variables-for-tests:
Avocado exports Avocado variables and test parameters as BASH environment
to the running test. Those variables are interesting to simple tests, because
they can not make use of Avocado API directly with Python, like the native
tests can do and also they can modify the test parameters.
Environment Variables for Tests
===============================
Avocado exports some information, including test parameters, as environment
variables to the running test.
While these variables are available to all tests, they are usually
more interesting to SIMPLE tests. The reason is that SIMPLE tests can
not make direct use of Avocado API. INSTRUMENTED tests will usually
have more powerful ways, to access the same information.
Here are the current variables that Avocado exports to the tests:
Here is a list of the variables that Avocado currently exports to
tests:
+-----------------------------+---------------------------------------+-----------------------------------------------------------------------------------------------------+
| Environemnt Variable | Meaning | Example |
......
import os
import sys
from avocado import Test
class Env(Test):
def test(self):
"""
Logs information about the environment under which the test is executed
"""
pid = os.getpid()
p_dir = '/proc/%d' % pid
def get_proc_content(rel_path):
try:
return open(os.path.join(p_dir, rel_path)).read().strip()
except:
return "<NOT AVAILABLE>"
self.log.debug('Process ID: %s', pid)
self.log.debug('Current workding directory: %s', os.getcwd())
self.log.debug('Process "name" (comm): %s', get_proc_content('comm'))
raw_cmdline = get_proc_content('cmdline')
massaged_cmdline = raw_cmdline.replace('\0', ' ')
self.log.debug('Process "cmdline": %s', massaged_cmdline)
def log_std_io(name, std_io):
self.log.debug('%s:', name.upper())
self.log.debug(' sys.%s: %s', name, std_io)
self.log.debug(' sys.%s is a tty: %s', name, std_io.isatty())
if hasattr(std_io, 'fileno'):
self.log.debug(' fd: %s', std_io.fileno())
self.log.debug(' fd is tty: %s', os.isatty(std_io.fileno()))
else:
self.log.debug(' fd: not available')
self.log.debug(' fd is a tty: can not determine, most possibly *not* a tty')
log_std_io('stdin', sys.stdin)
log_std_io('stdout', sys.stdout)
log_std_io('stderr', sys.stdout)
fd_dir = '/proc/%s/fd' % pid
if os.path.isdir('/proc/%s/fd' % pid):
fds = os.listdir(fd_dir)
self.log.debug('Open file descriptors:')
for fd in fds:
fd_path = os.path.join(fd_dir, fd)
if os.path.islink(fd_path):
self.log.debug(" %s: %s", fd, os.readlink(fd_path))
self.log.debug('Environment variables (probably) set by Avocado:')
for k, v in os.environ.items():
if k.startswith('AVOCADO_'):
self.log.debug(' %s: %s', k, v)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册