[qmtest] Problem loading expectation

Nathaniel Smith njs at pobox.com
Sat Aug 9 00:09:45 UTC 2003


On Fri, Aug 08, 2003 at 01:56:40PM -0700, Nathaniel Smith wrote:
> On Tue, Jul 15, 2003 at 08:45:50AM +0400, Vladimir Prus wrote:
> [...]
> >   File 
> > "/home/ghost/build/Tools/qm-up-to-date/qm/test/classes/pickle_result_stream.py", 
> > line 183, in __init__
> >     version = self.__unpickler.load()
> > cPickle.UnpicklingError: <class 'qm.test.context.Context'> is not safe for 
> > unpickling
> 
> Sorry for taking such a long time to get back to this.  I've cleaned
> up the pickle handling a bit so this shouldn't happen again in the
> future, and I believe I've fixed your problem as well.  Patch
> attached.

Updated version attached; only real difference is the addition of a
new set of tests to make sure this doesn't happen again.

-- Nathaniel

-- 
"If you can explain how you do something, then you're very very bad at it."
  -- John Hopfield
-------------- next part --------------
diff -urN --exclude='*~' --exclude='.*' --exclude=CVS --exclude='*.pyo' --exclude='*.pyc' --exclude=build --exclude=GNUmakefile --exclude=config.log --exclude=config.status --exclude=setup_path.py --exclude=qm.sh --exclude=qmtest --exclude=qm.spec --exclude='*.dtd' --exclude=CATALOG --exclude=thread_target --exclude=process_target qm-clean/ChangeLog qm-pickle-compatibility/ChangeLog
--- qm-clean/ChangeLog	2003-08-07 11:10:43.000000000 -0700
+++ qm-pickle-compatibility/ChangeLog	2003-08-08 17:06:41.000000000 -0700
@@ -1,3 +1,40 @@
+2003-08-08  Nathaniel Smith  <njs at codesourcery.com>
+
+	* qm/test/context.py (ContextException.__safe_for_unpickling__):
+	Set to 1.
+	(ContextWrapper): New class.
+	* qm/test/result.py (Result.__setstate__): New method.
+	(Result.__getstate__): New method.
+	* qm/test/share/messages/diagnostics.txt
+	(result pickle too recent): New message.
+
+	* tests/results_files: New directory.
+	* tests/results_files/QMTest: Likewise.
+	* tests/results_files/QMTest/configuration: New file.
+	* tests/results_files/QMTest/classes.qmc: New file.
+	* tests/results_files/QMTest/results_file_database.py: New
+	file.
+	* tests/results_files/QMTest/results_file_test.py: New file.
+	* tests/results_files/README: New file.
+	* tests/results_files/xml_results.qmr: New file.
+	* tests/results_files/result_class_v0-file_format_v0-pickling_format_v0.qmr:
+	New file.
+	* tests/results_files/result_class_v1-file_format_v0-pickling_format_v0.qmr:
+	New file.
+	* tests/results_files/result_class_v1-file_format_v1-pickling_format_v0.qmr:
+	New file.
+	* tests/results_files/result_class_v1-file_format_v1-pickling_format_v1.qmr:
+	New file.
+	* tests/results_file/tdb: New directory.
+	* tests/results_file/tdb/QMTest: New directory.
+	* tests/results_file/tdb/QMTest/configuration: New file.
+	* tests/results_file/tdb/pass.qmt: New file.
+	* tests/results_file/tdb/fail.qmt: New file.
+	* tests/results_file/tdb/error.qmt: New file.
+	* tests/results_file/tdb/untested.qmt: New file.
+	* tests/results_file/tdb/tmpdir_resource.qma: New file.
+	* tests/results_file/tdb/fail_with_tmpdir.qmt: New file.
+	
 2003-08-07  Nathaniel Smith  <njs at codesourcery.com>
 	    Mark Mitchell  <mark at codesourcery.com>
 
diff -urN --exclude='*~' --exclude='.*' --exclude=CVS --exclude='*.pyo' --exclude='*.pyc' --exclude=build --exclude=GNUmakefile --exclude=config.log --exclude=config.status --exclude=setup_path.py --exclude=qm.sh --exclude=qmtest --exclude=qm.spec --exclude='*.dtd' --exclude=CATALOG --exclude=thread_target --exclude=process_target qm-clean/qm/test/context.py qm-pickle-compatibility/qm/test/context.py
--- qm-clean/qm/test/context.py	2003-07-09 17:33:44.000000000 -0700
+++ qm-pickle-compatibility/qm/test/context.py	2003-08-07 19:13:20.000000000 -0700
@@ -39,6 +39,19 @@
 
         
     
+class ContextWrapper:
+    """Do-nothing class to preserve pickle compatability.
+
+    A class called 'ContextWrapper' used to be used in instead of a
+    'Context' class in some cases, and we used to put contexts into
+    'Result's.  Because of how pickles work, this means that the only way
+    to unpickle these old 'Result's is to have a do-nothing placeholder
+    class that can be instantiated and then thrown away."""
+
+    pass
+
+
+
 class Context(types.DictType):
     """Test-time and local configuration for tests.
 
@@ -67,6 +80,9 @@
     the temporary directory is empty, however; it may contain files
     left behind by the execution of other 'Runnable' objects."""
 
+    __safe_for_unpickling__ = 1
+    """Required to unpickle new-style classes under Python 2.2."""
+
     def __init__(self, context = None):
         """Construct a new context.
 
diff -urN --exclude='*~' --exclude='.*' --exclude=CVS --exclude='*.pyo' --exclude='*.pyc' --exclude=build --exclude=GNUmakefile --exclude=config.log --exclude=config.status --exclude=setup_path.py --exclude=qm.sh --exclude=qmtest --exclude=qm.spec --exclude='*.dtd' --exclude=CATALOG --exclude=thread_target --exclude=process_target qm-clean/qm/test/result.py qm-pickle-compatibility/qm/test/result.py
--- qm-clean/qm/test/result.py	2003-05-16 00:31:18.000000000 -0700
+++ qm-pickle-compatibility/qm/test/result.py	2003-08-08 16:19:08.000000000 -0700
@@ -142,6 +142,55 @@
         self.__annotations = annotations.copy()
 
 
+    def __getstate__(self):
+        """Return a representation of this result for pickling.
+
+        By using an explicit tuple representation of 'Result's when
+        storing them in a pickle file, we decouple our storage format
+        from internal implementation details (e.g., the names of private
+        variables)."""
+
+        # First element is a version number; the rest are the data
+        # needed to reconstruct a 'Result'.  No part of this structure
+        # should ever be a user-defined type, because that will
+        # introduce interdependencies that we want to avoid.
+        return (1,
+                self.__kind,
+                self.__id,
+                self.__outcome,
+                self.__annotations)
+
+
+    def __setstate__(self, pickled_state):
+        """Construct a 'Result' from its pickled form."""
+
+        if isinstance(pickled_state, dict):
+            # Old style pickle, from before we defined '__getstate__'.
+            # (Notionally, this is version "0".)  The state is a
+            # dictionary containing the variables we used to have.
+            self.__kind = pickled_state["_Result__kind"]
+            self.__id = pickled_state["_Result__id"]
+            self.__outcome = pickled_state["_Result__outcome"]
+            self.__annotations = pickled_state["_Result__annotations"]
+            # Also has a key "_Result__context" containing a (probably
+            # invalid) context object, but we discard it.
+        else:
+            # New style pickle, from after we defined '__getstate__'.
+            # The state is a tuple whose first element is a version
+            # number, and the rest are values of variables we care
+            # about.
+            if pickled_state[0] == 1:
+                (self.__kind,
+                 self.__id,
+                 self.__outcome,
+                 self.__annotations) = pickled_state[1:]
+            else:
+                raise QMException, \
+                      qm.error("result pickle too recent",
+                               curr_version=1,
+                               bad_version=pickled_state[0])
+
+
     def GetKind(self):
         """Return the kind of result this is.
 
diff -urN --exclude='*~' --exclude='.*' --exclude=CVS --exclude='*.pyo' --exclude='*.pyc' --exclude=build --exclude=GNUmakefile --exclude=config.log --exclude=config.status --exclude=setup_path.py --exclude=qm.sh --exclude=qmtest --exclude=qm.spec --exclude='*.dtd' --exclude=CATALOG --exclude=thread_target --exclude=process_target qm-clean/qm/test/share/messages/diagnostics.txt qm-pickle-compatibility/qm/test/share/messages/diagnostics.txt
--- qm-clean/qm/test/share/messages/diagnostics.txt	2003-08-08 13:35:15.000000000 -0700
+++ qm-pickle-compatibility/qm/test/share/messages/diagnostics.txt	2003-08-08 13:34:59.000000000 -0700
@@ -181,6 +181,11 @@
 @ not test database
 "%(path)s" is not a test database.
 
+@ result pickle too recent
+Attempted to unpickle a 'Result' with version %(bad_version)i, but this
+version of QMTest only supports version %(curr_version)i or lower.  Try
+upgrading your version of QMTest.
+
 @ seed not integer
 The random number generator seed you specified, "%(seed)s", is not an
 integer. 
diff -urN --exclude='*~' --exclude='.*' --exclude=CVS --exclude='*.pyo' --exclude='*.pyc' --exclude=build --exclude=GNUmakefile --exclude=config.log --exclude=config.status --exclude=setup_path.py --exclude=qm.sh --exclude=qmtest --exclude=qm.spec --exclude='*.dtd' --exclude=CATALOG --exclude=thread_target --exclude=process_target qm-clean/tests/results_files/QMTest/classes.qmc qm-pickle-compatibility/tests/results_files/QMTest/classes.qmc
--- qm-clean/tests/results_files/QMTest/classes.qmc	1969-12-31 16:00:00.000000000 -0800
+++ qm-pickle-compatibility/tests/results_files/QMTest/classes.qmc	2003-08-08 15:28:41.000000000 -0700
@@ -0,0 +1,2 @@
+<?xml version="1.0" ?>
+<class-directory><class kind="database">results_file_database.ResultsFileDatabase</class><class kind="test">results_file_test.ResultsFileTest</class></class-directory>
diff -urN --exclude='*~' --exclude='.*' --exclude=CVS --exclude='*.pyo' --exclude='*.pyc' --exclude=build --exclude=GNUmakefile --exclude=config.log --exclude=config.status --exclude=setup_path.py --exclude=qm.sh --exclude=qmtest --exclude=qm.spec --exclude='*.dtd' --exclude=CATALOG --exclude=thread_target --exclude=process_target qm-clean/tests/results_files/QMTest/configuration qm-pickle-compatibility/tests/results_files/QMTest/configuration
--- qm-clean/tests/results_files/QMTest/configuration	1969-12-31 16:00:00.000000000 -0800
+++ qm-pickle-compatibility/tests/results_files/QMTest/configuration	2003-08-08 15:29:09.000000000 -0700
@@ -0,0 +1,2 @@
+<?xml version="1.0" ?>
+<extension class="results_file_database.ResultsFileDatabase" kind="database"/>
\ No newline at end of file
diff -urN --exclude='*~' --exclude='.*' --exclude=CVS --exclude='*.pyo' --exclude='*.pyc' --exclude=build --exclude=GNUmakefile --exclude=config.log --exclude=config.status --exclude=setup_path.py --exclude=qm.sh --exclude=qmtest --exclude=qm.spec --exclude='*.dtd' --exclude=CATALOG --exclude=thread_target --exclude=process_target qm-clean/tests/results_files/QMTest/results_file_database.py qm-pickle-compatibility/tests/results_files/QMTest/results_file_database.py
--- qm-clean/tests/results_files/QMTest/results_file_database.py	1969-12-31 16:00:00.000000000 -0800
+++ qm-pickle-compatibility/tests/results_files/QMTest/results_file_database.py	2003-08-08 16:57:57.000000000 -0700
@@ -0,0 +1,78 @@
+########################################################################
+#
+# File:   results_file_database.py
+# Author: Nathaniel Smith
+# Date:   2003-08-08
+#
+# Contents:
+#   ResultsFileDatabase.
+#
+# Copyright (c) 2003 by CodeSourcery, LLC.  All rights reserved. 
+#
+########################################################################
+
+########################################################################
+# Imports 
+########################################################################
+
+import glob
+import os.path
+from   qm.test.database import *
+
+########################################################################
+# Classes
+########################################################################
+
+class ResultsFileDatabase(Database):
+    """Database storing result file tests for QMTest.
+
+    Each file in the test directory matching the glob "*.qmr" is
+    considered to be a test, and should be a results file resulting from
+    running the database "tdb" in the test directory.  So to generate a
+    new test, one generally should run "qmtest -D tdb run -o my_test".
+    Each test is considered to pass if the latest version of qmtest is
+    able to load it in as an expectations file and run with no
+    unexpected results.
+
+    This database is read-only, i.e. the methods to update it through
+    the GUI are not implemented.  It is expected that users will
+    update it by creating new result files automatically.
+
+    Currently, there are no subdirectories and no resources in this
+    database."""
+
+    def __init__(self, path, arguments):
+
+        arguments["modifiable"] = "false"
+        Database.__init__(self, path, arguments)
+
+        
+    def GetTest(self, test_id):
+
+        results_file = os.path.join(self.GetPath(), test_id + ".qmr")
+        if not os.path.exists(results_file):
+            raise NoSuchTestError
+        tdb = os.path.join(self.GetPath(), "tdb")
+
+        return TestDescriptor(self,
+                              test_id,
+                              "results_file_test.ResultsFileTest",
+                              {"results_file": results_file,
+                               "tdb": tdb})
+
+        
+    def GetIds(self, kind, directory = "", scan_subdirs = 1):
+
+        assert directory == ""
+
+        if kind == Database.TEST:
+            p = self.GetPath()
+            files = glob.glob(os.path.join(p, "*.qmr"))
+            basenames = [os.path.basename(file) for file in files]
+            names = [os.path.splitext(file)[0] for file in basenames]
+            return names
+        else:
+            # There are no suites or resources in this database.
+            return []
+
+        return ids
diff -urN --exclude='*~' --exclude='.*' --exclude=CVS --exclude='*.pyo' --exclude='*.pyc' --exclude=build --exclude=GNUmakefile --exclude=config.log --exclude=config.status --exclude=setup_path.py --exclude=qm.sh --exclude=qmtest --exclude=qm.spec --exclude='*.dtd' --exclude=CATALOG --exclude=thread_target --exclude=process_target qm-clean/tests/results_files/QMTest/results_file_test.py qm-pickle-compatibility/tests/results_files/QMTest/results_file_test.py
--- qm-clean/tests/results_files/QMTest/results_file_test.py	1969-12-31 16:00:00.000000000 -0800
+++ qm-pickle-compatibility/tests/results_files/QMTest/results_file_test.py	2003-08-08 15:40:20.000000000 -0700
@@ -0,0 +1,85 @@
+########################################################################
+#
+# File:   results_file_test.py
+# Author: Nathaniel Smith
+# Date:   2003-08-08
+#
+# Contents:
+#   ResultsFileTest
+#
+# Copyright (c) 2002, 2003 by CodeSourcery, LLC.  All rights reserved.
+#
+# For license terms see the file COPYING.
+#
+########################################################################
+
+########################################################################
+# imports
+########################################################################
+
+import os
+import re
+import qm.executable
+from   qm.test.test import *
+from   qm.test.result import *
+
+########################################################################
+# classes
+########################################################################
+
+class ResultsFileTest(Test):
+    """A 'ResultsFileTest' tests that QMTest can load a results file.
+    """
+
+    arguments = [
+        qm.fields.TextField(
+            name        = "results_file",
+            title       = "Path to results file.",
+            verbatim    = "true",
+            multiline   = "false",
+            description = """The pathname of the results file."""
+            ),
+        qm.fields.TextField(
+            name        = "tdb",
+            title       = "Path to test database.",
+            verbatim    = "true",
+            multiline   = "false",
+            description = """The pathname of the test database file.
+
+            All tests in this database will be run, and the outcomes
+            compared to those stored in the results file."""
+            ),
+        ]
+
+    def Run(self, context, result):
+
+        # Sanity check the arguments.
+        assert os.path.isfile(self.results_file)
+        assert os.path.isdir(self.tdb)
+        
+        # The QMTest binary to test is specified as a context variable.
+        qmtest = context['qmtest_path']
+
+        argv = (qmtest, "-D", self.tdb,
+                "run", "-O", self.results_file, "--no-output")
+
+        e = qm.executable.RedirectedExecutable()
+        status = e.Run(argv)
+
+        result.Annotate({
+            "selftest.RegTest.cmdline"  : ' '.join(argv),
+            "selftest.RegTest.exitcode" : ("%d" % status),
+            "selftest.RegTest.stdout"   : '<pre>' + e.stdout + '</pre>',
+            "selftest.RegTest.stderr"   : '<pre>' + e.stderr + '</pre>',
+            })
+
+        if e.stderr != '':
+            # Printing anything to stderr is a failure.
+            result.Fail("Child process reported errors")
+        elif status:
+            # Unsuccessful termination is a failure.  This is checked
+            # second because output on stderr should come along with
+            # an unsuccessful exit, and we want to pick the more specific
+            # failure cause.
+            result.Fail("Child process exited unsuccessfully")
+        
diff -urN --exclude='*~' --exclude='.*' --exclude=CVS --exclude='*.pyo' --exclude='*.pyc' --exclude=build --exclude=GNUmakefile --exclude=config.log --exclude=config.status --exclude=setup_path.py --exclude=qm.sh --exclude=qmtest --exclude=qm.spec --exclude='*.dtd' --exclude=CATALOG --exclude=thread_target --exclude=process_target qm-clean/tests/results_files/README qm-pickle-compatibility/tests/results_files/README
--- qm-clean/tests/results_files/README	1969-12-31 16:00:00.000000000 -0800
+++ qm-pickle-compatibility/tests/results_files/README	2003-08-08 16:31:28.000000000 -0700
@@ -0,0 +1,25 @@
+We have had several different result file formats, and we need to be able
+to load all of them.  Listed in the order QMTest was changed to output each
+format.
+  -- XML result file format.  The original format.
+     -> xml_results.qmr
+  -- Pickle format v0 (original format).
+       -- 'Result's still contain the context they were run in.
+       -- just a bunch of 'Result' pickles, no metadata.
+       -- 'Result's still use the standard pickling mechanism.
+     -> result_class_v0-file_format_v0-pickling_format_v0.qmr
+  -- Pickle format v0 with new 'Result' object.
+       -- 'Result's no longer contain the context object they were run in.
+       -- just a bunch of 'Result' pickles, no metadata.
+       -- 'Result's still use the standard pickling mechanism.
+     -> result_class_v1-file_format_v0-pickling_format_v0.qmr
+  -- Pickle format v1 with new 'Result' object.
+       -- 'Result's no longer contain the context object they were run in.
+       -- More complicated file layout containing metadata.
+       -- 'Result's still use the standard pickling mechanism.
+     -> result_class_v1-file_format_v1-pickling_format_v0.qmr
+  -- Pickle format v1 with new 'Result' object and new 'Result' pickling.
+       -- 'Result's no longer contain the context object they were run in.
+       -- More complicated file layout containing metadata.
+       -- 'Result's no longer use the standard pickling mechanism.
+     -> result_class_v1-file_format_v1-pickling_format_v1.qmr
Binary files qm-clean/tests/results_files/result_class_v0-file_format_v0-pickling_format_v0.qmr and qm-pickle-compatibility/tests/results_files/result_class_v0-file_format_v0-pickling_format_v0.qmr differ
Binary files qm-clean/tests/results_files/result_class_v1-file_format_v0-pickling_format_v0.qmr and qm-pickle-compatibility/tests/results_files/result_class_v1-file_format_v0-pickling_format_v0.qmr differ
Binary files qm-clean/tests/results_files/result_class_v1-file_format_v1-pickling_format_v0.qmr and qm-pickle-compatibility/tests/results_files/result_class_v1-file_format_v1-pickling_format_v0.qmr differ
Binary files qm-clean/tests/results_files/result_class_v1-file_format_v1-pickling_format_v1.qmr and qm-pickle-compatibility/tests/results_files/result_class_v1-file_format_v1-pickling_format_v1.qmr differ
diff -urN --exclude='*~' --exclude='.*' --exclude=CVS --exclude='*.pyo' --exclude='*.pyc' --exclude=build --exclude=GNUmakefile --exclude=config.log --exclude=config.status --exclude=setup_path.py --exclude=qm.sh --exclude=qmtest --exclude=qm.spec --exclude='*.dtd' --exclude=CATALOG --exclude=thread_target --exclude=process_target qm-clean/tests/results_files/tdb/QMTest/configuration qm-pickle-compatibility/tests/results_files/tdb/QMTest/configuration
--- qm-clean/tests/results_files/tdb/QMTest/configuration	1969-12-31 16:00:00.000000000 -0800
+++ qm-pickle-compatibility/tests/results_files/tdb/QMTest/configuration	2003-08-08 15:31:15.000000000 -0700
@@ -0,0 +1,5 @@
+<?xml version="1.0" ?>
+<!DOCTYPE extension
+  PUBLIC '-//Software Carpentry//QMTest Extension V0.1//EN'
+  'http://www.software-carpentry.com/qm/xml/extension'>
+<extension class="xml_database.XMLDatabase" kind="database"/>
\ No newline at end of file
diff -urN --exclude='*~' --exclude='.*' --exclude=CVS --exclude='*.pyo' --exclude='*.pyc' --exclude=build --exclude=GNUmakefile --exclude=config.log --exclude=config.status --exclude=setup_path.py --exclude=qm.sh --exclude=qmtest --exclude=qm.spec --exclude='*.dtd' --exclude=CATALOG --exclude=thread_target --exclude=process_target qm-clean/tests/results_files/tdb/error.qmt qm-pickle-compatibility/tests/results_files/tdb/error.qmt
--- qm-clean/tests/results_files/tdb/error.qmt	1969-12-31 16:00:00.000000000 -0800
+++ qm-pickle-compatibility/tests/results_files/tdb/error.qmt	2003-08-08 15:32:57.000000000 -0700
@@ -0,0 +1,5 @@
+<?xml version="1.0" ?>
+<!DOCTYPE extension
+  PUBLIC '-//Software Carpentry//QMTest Extension V0.1//EN'
+  'http://www.software-carpentry.com/qm/xml/extension'>
+<extension class="python.ExecTest" kind="test"><argument name="prerequisites"><set/></argument><argument name="source"><text>pass</text></argument><argument name="target_group"><text>.*</text></argument><argument name="expression"><text>raise "An exception"</text></argument><argument name="resources"><set/></argument></extension>
\ No newline at end of file
diff -urN --exclude='*~' --exclude='.*' --exclude=CVS --exclude='*.pyo' --exclude='*.pyc' --exclude=build --exclude=GNUmakefile --exclude=config.log --exclude=config.status --exclude=setup_path.py --exclude=qm.sh --exclude=qmtest --exclude=qm.spec --exclude='*.dtd' --exclude=CATALOG --exclude=thread_target --exclude=process_target qm-clean/tests/results_files/tdb/fail.qmt qm-pickle-compatibility/tests/results_files/tdb/fail.qmt
--- qm-clean/tests/results_files/tdb/fail.qmt	1969-12-31 16:00:00.000000000 -0800
+++ qm-pickle-compatibility/tests/results_files/tdb/fail.qmt	2003-08-08 15:32:32.000000000 -0700
@@ -0,0 +1,5 @@
+<?xml version="1.0" ?>
+<!DOCTYPE extension
+  PUBLIC '-//Software Carpentry//QMTest Extension V0.1//EN'
+  'http://www.software-carpentry.com/qm/xml/extension'>
+<extension class="python.ExecTest" kind="test"><argument name="prerequisites"><set/></argument><argument name="source"><text>pass</text></argument><argument name="target_group"><text>.*</text></argument><argument name="expression"><text>0</text></argument><argument name="resources"><set/></argument></extension>
\ No newline at end of file
diff -urN --exclude='*~' --exclude='.*' --exclude=CVS --exclude='*.pyo' --exclude='*.pyc' --exclude=build --exclude=GNUmakefile --exclude=config.log --exclude=config.status --exclude=setup_path.py --exclude=qm.sh --exclude=qmtest --exclude=qm.spec --exclude='*.dtd' --exclude=CATALOG --exclude=thread_target --exclude=process_target qm-clean/tests/results_files/tdb/fail_with_tmpdir.qmt qm-pickle-compatibility/tests/results_files/tdb/fail_with_tmpdir.qmt
--- qm-clean/tests/results_files/tdb/fail_with_tmpdir.qmt	1969-12-31 16:00:00.000000000 -0800
+++ qm-pickle-compatibility/tests/results_files/tdb/fail_with_tmpdir.qmt	2003-08-08 16:02:23.000000000 -0700
@@ -0,0 +1,5 @@
+<?xml version="1.0" ?>
+<!DOCTYPE extension
+  PUBLIC '-//Software Carpentry//QMTest Extension V0.1//EN'
+  'http://www.software-carpentry.com/qm/xml/extension'>
+<extension class="python.ExecTest" kind="test"><argument name="prerequisites"><set/></argument><argument name="source"><text>pass</text></argument><argument name="target_group"><text>.*</text></argument><argument name="expression"><text>0</text></argument><argument name="resources"><set><text>tmpdir_resource</text></set></argument></extension>
diff -urN --exclude='*~' --exclude='.*' --exclude=CVS --exclude='*.pyo' --exclude='*.pyc' --exclude=build --exclude=GNUmakefile --exclude=config.log --exclude=config.status --exclude=setup_path.py --exclude=qm.sh --exclude=qmtest --exclude=qm.spec --exclude='*.dtd' --exclude=CATALOG --exclude=thread_target --exclude=process_target qm-clean/tests/results_files/tdb/pass.qmt qm-pickle-compatibility/tests/results_files/tdb/pass.qmt
--- qm-clean/tests/results_files/tdb/pass.qmt	1969-12-31 16:00:00.000000000 -0800
+++ qm-pickle-compatibility/tests/results_files/tdb/pass.qmt	2003-08-08 15:32:03.000000000 -0700
@@ -0,0 +1,5 @@
+<?xml version="1.0" ?>
+<!DOCTYPE extension
+  PUBLIC '-//Software Carpentry//QMTest Extension V0.1//EN'
+  'http://www.software-carpentry.com/qm/xml/extension'>
+<extension class="python.ExecTest" kind="test"><argument name="prerequisites"><set/></argument><argument name="source"><text>pass</text></argument><argument name="target_group"><text>.*</text></argument><argument name="expression"><text>1</text></argument><argument name="resources"><set/></argument></extension>
\ No newline at end of file
diff -urN --exclude='*~' --exclude='.*' --exclude=CVS --exclude='*.pyo' --exclude='*.pyc' --exclude=build --exclude=GNUmakefile --exclude=config.log --exclude=config.status --exclude=setup_path.py --exclude=qm.sh --exclude=qmtest --exclude=qm.spec --exclude='*.dtd' --exclude=CATALOG --exclude=thread_target --exclude=process_target qm-clean/tests/results_files/tdb/tmpdir_resource.qma qm-pickle-compatibility/tests/results_files/tdb/tmpdir_resource.qma
--- qm-clean/tests/results_files/tdb/tmpdir_resource.qma	1969-12-31 16:00:00.000000000 -0800
+++ qm-pickle-compatibility/tests/results_files/tdb/tmpdir_resource.qma	2003-08-08 15:58:49.000000000 -0700
@@ -0,0 +1,5 @@
+<?xml version="1.0" ?>
+<!DOCTYPE extension
+  PUBLIC '-//Software Carpentry//QMTest Extension V0.1//EN'
+  'http://www.software-carpentry.com/qm/xml/extension'>
+<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>
\ No newline at end of file
diff -urN --exclude='*~' --exclude='.*' --exclude=CVS --exclude='*.pyo' --exclude='*.pyc' --exclude=build --exclude=GNUmakefile --exclude=config.log --exclude=config.status --exclude=setup_path.py --exclude=qm.sh --exclude=qmtest --exclude=qm.spec --exclude='*.dtd' --exclude=CATALOG --exclude=thread_target --exclude=process_target qm-clean/tests/results_files/tdb/untested.qmt qm-pickle-compatibility/tests/results_files/tdb/untested.qmt
--- qm-clean/tests/results_files/tdb/untested.qmt	1969-12-31 16:00:00.000000000 -0800
+++ qm-pickle-compatibility/tests/results_files/tdb/untested.qmt	2003-08-08 15:36:22.000000000 -0700
@@ -0,0 +1,5 @@
+<?xml version="1.0" ?>
+<!DOCTYPE extension
+  PUBLIC '-//Software Carpentry//QMTest Extension V0.1//EN'
+  'http://www.software-carpentry.com/qm/xml/extension'>
+<extension class="python.ExecTest" kind="test"><argument name="prerequisites"><set><tuple><text>fail</text><enumeral>PASS</enumeral></tuple></set></argument><argument name="source"><text>pass</text></argument><argument name="target_group"><text>.*</text></argument><argument name="expression"><text>1</text></argument><argument name="resources"><set/></argument></extension>
diff -urN --exclude='*~' --exclude='.*' --exclude=CVS --exclude='*.pyo' --exclude='*.pyc' --exclude=build --exclude=GNUmakefile --exclude=config.log --exclude=config.status --exclude=setup_path.py --exclude=qm.sh --exclude=qmtest --exclude=qm.spec --exclude='*.dtd' --exclude=CATALOG --exclude=thread_target --exclude=process_target qm-clean/tests/results_files/xml_results.qmr qm-pickle-compatibility/tests/results_files/xml_results.qmr
--- qm-clean/tests/results_files/xml_results.qmr	1969-12-31 16:00:00.000000000 -0800
+++ qm-pickle-compatibility/tests/results_files/xml_results.qmr	2003-08-08 16:43:05.000000000 -0700
@@ -0,0 +1,16 @@
+<?xml version='1.0' encoding='ISO-8859-1'?>
+<!DOCTYPE results PUBLIC "-//Software Carpentry//QMTest Result V0.3//EN" "http://www.software-carpentry.com/qm/xml/result.dtd">
+<results>
+<annotation key="qmtest.run.start_time">2003-08-08T23:43:05Z</annotation>
+<result id="error" kind="test"><outcome>ERROR</outcome><property name="qmtest.cause">Exception evaluating expression.</property><property name="qmtest.exception">exceptions.SyntaxError: invalid syntax (line 1)</property><property name="qmtest.target">local</property><property name="qmtest.traceback"><pre>  File "/home/njs/src/cvs/qm/qm-pickle-compatibility/qm/test/classes/python.py", line 101, in Run
+    global_namespace, local_namespace)
+</pre></property></result>
+<result id="fail" kind="test"><outcome>FAIL</outcome><property name="ExecTest.expr">0</property><property name="ExecTest.value">0</property><property name="qmtest.cause">Expression evaluates to false.</property><property name="qmtest.target">local</property></result>
+<result id="tmpdir_resource" kind="resource_setup"><outcome>PASS</outcome><property name="qmtest.target">local</property></result>
+<result id="fail_with_tmpdir" kind="test"><outcome>FAIL</outcome><property name="ExecTest.expr">0</property><property name="ExecTest.value">0</property><property name="qmtest.cause">Expression evaluates to false.</property><property name="qmtest.target">local</property></result>
+<result id="pass" kind="test"><outcome>PASS</outcome><property name="qmtest.target">local</property></result>
+<result id="untested" kind="test"><outcome>UNTESTED</outcome><property name="qmtest.cause">A prerequisite produced an incorrect outcome.</property><property name="qmtest.expected_outcome">PASS</property><property name="qmtest.outcome">FAIL</property><property name="qmtest.prequisite">fail</property></result>
+<result id="tmpdir_resource" kind="resource_cleanup"><outcome>PASS</outcome><property name="qmtest.target">local</property></result>
+<annotation key="qmtest.run.end_time">2003-08-08T23:43:05Z</annotation>
+
+</results>


More information about the qmtest mailing list