[PATCH] Add more annotations to QMTest runs
Nathaniel Smith
njs at pobox.com
Wed Feb 11 20:45:31 UTC 2004
This patch, attached for review, adds more default annotations to
QMTest. These are required for emulation of the TET[1] output format,
but are useful generally.
Also adds a few more calls to ExecutionEngine._Trace, and
rationalizes the early termination handling;
ExecutionEnginer._RunTests used to sometimes signal early termination
by just exiting, and sometimes by raising an exception; we now always
raise an exception of some form.
New annotations:
qmtest.run.user: user who started the test run
qmtest.run.version: version of QMTest used for this test run
qmtest.run.uname: uname of the machine that started this test run
qmtest.run.aborted: present with value "True" if test run was
aborted early
Questions:
- Currently the simple presence of qmtest.run.aborted signals an
aborted run; should we instead always write this annotation with
value either "True" or "False"?
- Is there any documentation that should be added for these? As far
as I can tell, annotations aren't documentated at all ATM...
[1] http://tetworks.opengroup.org
-- Nathaniel
--
"If you can explain how you do something, then you're very very bad at it."
-- John Hopfield
-------------- next part --------------
? foo
? results.qmr
? qm/external/__init__.pyc
? tests/regress/QMTest/regression_database.pyc
? tests/regress/QMTest/selftest.pyc
? tests/regress/env_context1/output.qmr
? tests/regress/exception_test/output.qmr
? tests/regress/gilles1/output.qmr
? tests/regress/nocycle1/output.qmr
? tests/regress/tuple1/QMTest/tuple_test.pyc
? tests/results_files/QMTest/results_file_database.pyc
? tests/results_files/QMTest/results_file_test.pyc
Index: ChangeLog
===================================================================
RCS file: /home/qm/Repository/qm/ChangeLog,v
retrieving revision 1.595
diff -u -r1.595 ChangeLog
--- ChangeLog 28 Jan 2004 19:50:51 -0000 1.595
+++ ChangeLog 11 Feb 2004 20:06:22 -0000
@@ -1,3 +1,18 @@
+2004-02-11 Nathaniel Smith <njs at codesourcery.com>
+
+ * qm/common.py: Import getpass.
+ (get_username): New function.
+ * qm/test/execution_engine.py
+ (ExecutionEngine._WriteInitialAnnotations): New method.
+ (ExecutionEngine.Run): Call it.
+ (TerminationRequested): New exception.
+ (ExecutionEngine._RunTests): Raise it when terminating.
+ (ExecutionEngine.Run): Check for exceptions in _RunTests.
+
+ (ExecutionEngine.RequestTermination): More tracing.
+ (ExecutionEngine.Run): Likewise.
+ (ExecutionEngine._RunTests): Likewise.
+
2004-01-28 Mark Mitchell <mark at codesourcery.com>
* qm/test/classes/explicit_suite.py (ExplicitSuite.is_implicit):
Index: qm/common.py
===================================================================
RCS file: /home/qm/Repository/qm/qm/common.py,v
retrieving revision 1.79
diff -u -r1.79 common.py
--- qm/common.py 24 Nov 2003 23:00:54 -0000 1.79
+++ qm/common.py 11 Feb 2004 20:06:22 -0000
@@ -39,6 +39,7 @@
import time
import traceback
import types
+import getpass
if sys.platform != "win32":
import fcntl
@@ -872,6 +873,31 @@
assignments[name] = value
return assignments
+
+
+def get_username():
+ """Returns the current username as a string.
+
+ If the username cannot be found, raises a 'QMException'."""
+
+ # First try using the 'getpass' module.
+ try:
+ return getpass.getuser()
+ except:
+ pass
+
+ # 'getpass' doesn't necessarily work on Windows, so if that fails,
+ # try the win32 function.
+ try:
+ import win32api
+ except ImportError:
+ pass
+ else:
+ return win32api.GetUserName()
+
+ # And if none of that worked, give up.
+ raise QMException, "Cannot determine user name."
+
########################################################################
# variables
Index: qm/test/execution_engine.py
===================================================================
RCS file: /home/qm/Repository/qm/qm/test/execution_engine.py,v
retrieving revision 1.25
diff -u -r1.25 execution_engine.py
--- qm/test/execution_engine.py 24 Nov 2003 06:35:01 -0000 1.25
+++ qm/test/execution_engine.py 11 Feb 2004 20:06:22 -0000
@@ -34,6 +34,13 @@
# Classes
########################################################################
+class TerminationRequested(qm.common.QMException):
+ """A target requested termination of the test loop."""
+
+ pass
+
+
+
class ExecutionEngine:
"""A 'ExecutionEngine' executes tests.
@@ -232,6 +239,7 @@
may take some time; tests that are already running will continue
to run, for example."""
+ self._Trace("Test loop termination requested.")
self.__terminated = 1
@@ -253,20 +261,27 @@
returns -- True if any tests had unexpected outcomes."""
- # Write out all the currently known annotations.
- start_time_str = qm.common.format_time_iso(time.time())
- for rs in self.__result_streams:
- rs.WriteAllAnnotations(self.__context)
- rs.WriteAnnotation("qmtest.run.start_time", start_time_str)
+ # Write out run metadata.
+ self._WriteInitialAnnotations()
# Start all of the targets.
for target in self.__targets:
target.Start(self.__response_queue, self)
# Run all of the tests.
+ self._Trace("Starting test loop")
try:
- self._RunTests()
+ try:
+ self._RunTests()
+ except:
+ self._Trace("Test loop exited with exception: %s"
+ % str(sys.exc_info()))
+ for rs in self.__result_streams:
+ rs.WriteAnnotation("qmtest.run.aborted", "True")
+ raise
finally:
+ self._Trace("Test loop finished.")
+
# Stop the targets.
self._Trace("Stopping targets.")
for target in self.__targets:
@@ -346,7 +361,9 @@
while self.__num_tests_started < num_tests:
# If the user interrupted QMTest, stop executing tests.
if self._IsTerminationRequested():
- break
+ self._Trace("Terminating test loop as requested.")
+ raise TerminationRequested, "Termination requested."
+
# Process any responses and update the count of idle targets.
while self.__CheckForResponse(wait=0):
pass
@@ -378,8 +395,9 @@
else:
self.__target_state[target] = self.__TARGET_BUSY
- # Now all tests have been started; we just have wait for them
- # all to finish.
+ # Now every test that we're going to start has started; we just
+ # have wait for them all to finish.
+ self._Trace("Waiting for remaining tests to finish.")
while self.__running:
self.__CheckForResponse(wait=1)
@@ -793,6 +811,31 @@
tracer.Write(message, "exec")
+ def _WriteInitialAnnotations(self):
+
+ # Calculate annotations.
+ start_time_str = qm.common.format_time_iso(time.time())
+
+ try:
+ username = qm.common.get_username()
+ except:
+ username = None
+
+ try:
+ uname = " ".join(os.uname())
+ except:
+ uname = None
+
+ # Write them.
+ for rs in self.__result_streams:
+ rs.WriteAllAnnotations(self.__context)
+ rs.WriteAnnotation("qmtest.run.start_time", start_time_str)
+ if username is not None:
+ rs.WriteAnnotation("qmtest.run.user", username)
+ rs.WriteAnnotation("qmtest.run.version", qm.version)
+ rs.WriteAnnotation("qmtest.run.uname", uname)
+
+
########################################################################
# Local Variables:
# mode: python
More information about the qmtest
mailing list