[PATCH] Save/restore signal masks.
Nathaniel Smith
njs at pobox.com
Wed May 5 04:40:00 UTC 2004
Attached for review.
This patch also overhauls a bit of the build system, so that testing
and such run out of the build directory, not the source directory;
this is necessitated by the addition of an impure module, that will
_only_ work from the build directory...
The goals of this patch, then, are:
-- Signals aren't screwed up by threads.
-- QMTest still builds fine on all systems.
-- 'make check' still works on all systems.
-- running out of the build directory still works on all systems.
-- Building packages still works on all systems, except
-- Packages are now architecture specific, and can only be
built on the relevant architecture.
-- Nathaniel
--
"But in Middle-earth, the distinct accusative case disappeared from
the speech of the Noldor (such things happen when you are busy
fighting Orcs, Balrogs, and Dragons)."
-------------- next part --------------
? results.qmr
? qm/sigmask.c
? qm/external/__init__.pyc
? qm/external/__init__.pyo
? qmdist/command/bdist_wininst.py
? tests/regress/QMTest/regression_database.pyc
? tests/regress/QMTest/selftest.pyc
? tests/regress/tuple1/QMTest/tuple_test.pyc
? tests/results_files/QMTest/results_file_database.pyc
? tests/results_files/QMTest/results_file_test.pyc
? tests/xmldb/signals_unblocked.qmt
? tests/xmldb/signals_unblocked_tmpdir.qma
Index: ChangeLog
===================================================================
RCS file: /home/qm/Repository/qm/ChangeLog,v
retrieving revision 1.616
diff -u -r1.616 ChangeLog
--- ChangeLog 31 Mar 2004 10:32:44 -0000 1.616
+++ ChangeLog 5 May 2004 04:33:08 -0000
@@ -1,3 +1,22 @@
+2004-05-04 Nathaniel Smith <njs at codesourcery.com>
+
+ * setup.py: Import 'Extension'.
+ Use it to build qm.sigmask.
+ * qm/sigmask.c: New file.
+ * qm/test/qmtest (main): Import 'qm.sigmask'; call
+ 'qm.sigmask.save_mask'.
+ * qm/executable.py: Import 'qm.sigmask'.
+ (Executable._InitializeChild): Call 'qm.sigmask.restore_mask'.
+
+ * tests/xmldb/signals_unblocked.qmt: New test.
+ * tests/xmldb/signals_unblocked_tmpdir.qma: New resource.
+
+ * qmdist/command/check.py (check): Overhaul to respect
+ QMTESTFLAGS and use the correct path to the QMTest executable.
+ * GNUmakefile.in: Use "setup.py check" to run tests.
+ * qm/test/qmtest (rel_libdir): When running out of source tree,
+ use built library.
+
2004-03-30 Nathaniel Smith <njs at codesourcery.com>
* qm/common.py (htmllib): Import it.
Index: GNUmakefile.in
===================================================================
RCS file: /home/qm/Repository/qm/GNUmakefile.in,v
retrieving revision 1.34
diff -u -r1.34 GNUmakefile.in
--- GNUmakefile.in 24 Nov 2003 21:09:48 -0000 1.34
+++ GNUmakefile.in 5 May 2004 04:33:08 -0000
@@ -109,38 +109,13 @@
check: check-serial check-threads check-processes
check-serial: build
- qm/test/qmtest -D tests run $(QMTESTFLAGS) \
- -c qmtest_path=qm/test/qmtest
+ $(PYTHON) setup.py check --serial
check-threads: build
- rm -f tests/QMTest/thread_target
- qm/test/qmtest -D tests create-target -a threads=4 \
- -T tests/QMTest/thread_target \
- thread thread_target.ThreadTarget
- qm/test/qmtest -D tests run -T tests/QMTest/thread_target \
- $(QMTESTFLAGS) \
- -c qmtest_path=qm/test/qmtest \
- -c qmtest_target=tests/QMTest/thread_target
+ $(PYTHON) setup.py check --threads
check-processes: build
- rm -f tests/QMTest/process_target
- qm/test/qmtest -D tests create-target -a processes=4 \
- -T tests/QMTest/process_target \
- process process_target.ProcessTarget
- qm/test/qmtest -D tests run -T tests/QMTest/process_target \
- $(QMTESTFLAGS) \
- -c qmtest_path=qm/test/qmtest \
- -c qmtest_target=tests/QMTest/process_target
+ $(PYTHON) setup.py check --processes
check-rsh: build
- rm -f tests/QMTest/rsh_target
- qm/test/qmtest -D tests create-target \
- -a host=localhost -a remote_shell=ssh \
- -T tests/QMTest/rsh_target \
- rsh rsh_target.RSHTarget
- qm/test/qmtest -D tests run -T tests/QMTest/rsh_target \
- $(QMTESTFLAGS) \
- -c qmtest_path=`pwd`/qm/test/qmtest \
- -c qmtest_target=`pwd`/tests/QMTest/rsh_target
-
-
+ $(PYTHON) setup.py check --rsh
Index: setup.py
===================================================================
RCS file: /home/qm/Repository/qm/setup.py,v
retrieving revision 1.10
diff -u -r1.10 setup.py
--- setup.py 27 Feb 2004 22:04:33 -0000 1.10
+++ setup.py 5 May 2004 04:33:08 -0000
@@ -17,7 +17,7 @@
# Imports
########################################################################
-from distutils.core import setup
+from distutils.core import setup, Extension
import sys
import os
import os.path
@@ -94,6 +94,13 @@
qmtest_py_script = qmtest_script + ".py"
shutil.copyfile(qmtest_script, qmtest_py_script)
+# We need the sigmask extension on POSIX systems, but don't want it on
+# Win32.
+if sys.platform != "win32":
+ ext_modules = [Extension("qm.sigmask", ["qm/sigmask.c"])]
+else:
+ ext_modules = []
+
setup(name="qm",
version=version,
author="CodeSourcery, LLC",
@@ -116,6 +123,7 @@
'qm/test',
'qm/test/classes',
'qm/test/web'),
+ ext_modules=ext_modules,
scripts=[qmtest_script, qmtest_py_script],
data_files=[('qm/messages/test',
prefix(messages, 'qm/test/share/messages')),
Index: qm/executable.py
===================================================================
RCS file: /home/qm/Repository/qm/qm/executable.py,v
retrieving revision 1.24
diff -u -r1.24 executable.py
--- qm/executable.py 2 Mar 2004 03:24:41 -0000 1.24
+++ qm/executable.py 5 May 2004 04:33:08 -0000
@@ -38,6 +38,7 @@
import cPickle
import fcntl
import select
+ import qm.sigmask
########################################################################
# Classes
@@ -328,6 +329,8 @@
This method is not used under Windows."""
assert sys.platform != "win32"
+
+ qm.sigmask.restore_mask()
if self.__dir:
os.chdir(self.__dir)
Index: qm/test/qmtest
===================================================================
RCS file: /home/qm/Repository/qm/qm/test/qmtest,v
retrieving revision 1.3
diff -u -r1.3 qmtest
--- qm/test/qmtest 24 Nov 2003 06:35:01 -0000 1.3
+++ qm/test/qmtest 5 May 2004 04:33:08 -0000
@@ -54,7 +54,11 @@
# Update sys.path so that we can find the rest of QMTest.
if sys.platform != "win32":
- rel_libdir = ""
+ # Following logic stolen from distutils.command.build:
+ import distutils.util
+ plat_spec = "lib.%s-%s" % (distutils.util.get_platform(),
+ sys.version[0:3])
+ rel_libdir = os.path.join("build", plat_spec)
"""The relative path from the prefix to the library directory.
This path gives the relative path from the prefix to the library
@@ -124,6 +128,11 @@
# Make sure our Python is recent enough.
check_python_version()
+
+ # Save the initial signal mask, as early as possible.
+ if sys.platform != "win32":
+ import qm.sigmask
+ qm.sigmask.save_mask()
# Parse the command line.
command = qm.test.cmdline.QMTest(sys.argv[1:], qm_path)
Index: qmdist/command/check.py
===================================================================
RCS file: /home/qm/Repository/qm/qmdist/command/check.py,v
retrieving revision 1.2
diff -u -r1.2 check.py
--- qmdist/command/check.py 14 Oct 2003 21:56:07 -0000 1.2
+++ qmdist/command/check.py 5 May 2004 04:33:08 -0000
@@ -52,6 +52,8 @@
self.rsh = 0
self.all = None
+ self.build_scripts = None
+
def finalize_options (self):
"""Compute what tests to execute.
@@ -64,76 +66,88 @@
self.threads = 1
self.processes = 1
self.rsh = 1
+ # Pick up the build scripts directory from the 'build' command.
+ self.set_undefined_options("build",
+ ("build_scripts", "build_scripts"))
- qmtest = 'qm/test/qmtest'
-
- def check_serial(self):
+ def check_serial(self, qmtest, options):
"""Perform serial tests."""
- cmd = [check.qmtest,
- '-D', 'tests', 'run', '-c',
- norm('qmtest_path=qm/test/qmtest')]
+ cmd = [qmtest] + options + \
+ ['-D', 'tests', 'run', '-c',
+ norm('qmtest_path=' + qmtest)]
spawn(cmd)
- def check_threads(self):
+ def check_threads(self, qmtest, options):
"""Perform threaded tests."""
remove_if_exists(norm('tests/QMTest/thread_target'))
- cmd = [check.qmtest,
+ cmd = [qmtest,
'-D', 'tests', 'create-target', '-a', 'threads=4',
'-T', norm('tests/QMTest/thread_target'),
'thread', 'thread_target.ThreadTarget']
spawn(cmd)
- cmd = [check.qmtest,
- '-D', 'tests', 'run',
+ cmd = [qmtest] + options + \
+ ['-D', 'tests', 'run',
'-T', norm('tests/QMTest/thread_target'),
- '-c', 'qmtest_path=%s'%norm('qm/test/qmtest'),
+ '-c', 'qmtest_path=%s' % norm(qmtest),
'-c', 'qmtest_target=%s'%norm('tests/QMTest/thread_target')]
spawn(cmd)
- def check_processes(self):
+ def check_processes(self, qmtest, options):
"""Perform sub-processed tests."""
remove_if_exists(norm('tests/QMTest/process_target'))
- cmd = [check.qmtest,
+ cmd = [qmtest,
'-D', 'tests', 'create-target', '-a', 'processes=4',
'-T', norm('tests/QMTest/process_target'),
'process', 'process_target.ProcessTarget']
spawn(cmd)
- cmd = [check.qmtest,
- '-D', 'tests', 'run',
+ cmd = [qmtest] + options + \
+ ['-D', 'tests', 'run',
'-T', norm('tests/QMTest/process_target'),
- '-c', 'qmtest_path=%s'%norm('qm/test/qmtest'),
+ '-c', 'qmtest_path=%s' % norm(qmtest),
'-c', 'qmtest_target=%s'%norm('tests/QMTest/process_target')]
spawn(cmd)
- def check_rsh(self):
+ def check_rsh(self, qmtest, options):
"""Perform tests over a remote shell."""
remove_if_exists(norm('tests/QMTest/rsh_target'))
- cmd = [check.qmtest,
- '-D', 'tests', 'create-target',
+ cmd = [qmtest,
+ '-D', 'tests', 'create-target',
'-a', 'host=localhost', '-a', 'remote_shell=ssh',
'-T', norm('tests/QMTest/rsh_target'),
'rsh', 'rsh_target.RSHTarget']
spawn(cmd)
- cmd = [check.qmtest,
- '-D', 'tests', 'run',
+ abs_target = os.path.abspath("tests/QMTest/rsh_target")
+ cmd = [qmtest] + options + \
+ ['-D', 'tests', 'run',
'-T', norm('tests/QMTest/rsh_target'),
- '-c', 'qmtest_path=%s'%norm('%s/qm/test/qmtest'%os.getcwd()),
- '-c', 'qmtest_target=%s'%norm('%s/tests/QMTest/rsh_target'%os.getcwd())]
+ '-c', 'qmtest_path=%s' % norm(qmtest),
+ '-c', 'qmtest_target=%s' % norm(abs_target)]
spawn(cmd)
def run(self):
"""Execute the various tests."""
+ # Ensure that QMTest is already built.
+ self.run_command("build")
+
+ qmtest = os.path.abspath(os.path.join(self.build_scripts,
+ "qmtest"))
+ if os.environ.has_key("QMTESTFLAGS"):
+ options = os.environ["QMTESTFLAGS"].split()
+ else:
+ options = []
+
if self.serial:
- self.check_serial()
+ self.check_serial(qmtest, options)
if self.threads:
- self.check_threads()
+ self.check_threads(qmtest, options)
if self.processes:
- self.check_processes()
+ self.check_processes(qmtest, options)
if self.rsh:
- self.check_rsh()
+ self.check_rsh(qmtest, options)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: sigmask.c
Type: text/x-csrc
Size: 2176 bytes
Desc: not available
URL: <http://sourcerytools.com/pipermail/qmtest/attachments/20040504/0739d10f/attachment.c>
-------------- next part --------------
<?xml version="1.0" ?>
<!DOCTYPE extension
PUBLIC '-//QM/2.2/Extension//EN'
'http://www.codesourcery.com/qm/dtds/2.2/-//qm/2.2/extension//en.dtd'>
<extension class="command.ShellScriptTest" kind="test"><argument name="stdin"><text/></argument><argument name="stderr"><text/></argument><argument name="stdout"><text/></argument><argument name="prerequisites"><set/></argument><argument name="target_group"><text>.*</text></argument><argument name="exit_code"><integer>0</integer></argument><argument name="environment"><set/></argument><argument name="script"><text>if ! which cc >/dev/null; then
echo "No cc, skipping test"
exit 1
fi
cd $QMV_temp_dir_path
cat >check_sigmask.c <<EOF
#include <signal.h>
int main(int argc, char** argv)
{
sigset_t s;
sigprocmask(SIG_BLOCK, 0, &s);
return (sigismember(&s, SIGTERM) || sigismember(&s, SIGXCPU));
}
EOF
cc check_sigmask.c -o check_sigmask
if ! ./check_sigmask; then
echo "Test failed; some signals are blocked that shouldn't be."
OUTCOME=1
else
OUTCOME=0
fi
rm -f ./check_sigmask check_sigmask.c
exit $OUTCOME</text></argument><argument name="arguments"><set/></argument><argument name="timeout"><integer>-1</integer></argument><argument name="resources"><set><text>signals_unblocked_tmpdir</text></set></argument></extension>
-------------- next part --------------
<?xml version="1.0" ?>
<!DOCTYPE extension
PUBLIC '-//QM/2.2/Extension//EN'
'http://www.codesourcery.com/qm/dtds/2.2/-//qm/2.2/extension//en.dtd'>
<extension class="temporary.TempDirectoryResource" kind="resource"><argument name="dir_path_property"><text>temp_dir_path</text></argument><argument name="resources"><set/></argument><argument name="delete_recursively"><integer>1</integer></argument></extension>
More information about the qmtest
mailing list