PATCH: XML improvements

Mark Mitchell mark at codesourcery.com
Mon Sep 22 06:22:04 UTC 2003


This patch allows us to turn on pretty-printed XML in a couple of
places, which makes the XML output much more readable.  I intend to
make similar changes for the "Extension" class storage while
travelling this week.

This is part of the overall audit that we're performing to stabilize
the interfaces and APIs in preparation for QMTest 2.1.

--
Mark Mitchell
CodeSourcery, LLC
mark at codesourcery.com

2003-09-21  Mark Mitchell  <mark at codesourcery.com>

	* qm/xmlutil.py (get_children): Remove.
	(get_child_texts): Don't use it.
	* qm/test/base.py (get_extension_class_names_in_directory):
	Support new class directory format.
	* qm/test/cmdline.py (QMTest.__ExecuteRegister): Generate the
	class directory using the new directory format.
	* qm/test/database.py (load_database): Do not use get_children.
	* qm/test/result.py (Result.MakeDomNode): Revise result format.
	(__all__): New variable.
	* qm/test/classes.qmc: Regenerated.
	* qm/test/classes/xml_result_stream.py
	(XMLResultStream.WriteAnnotation): Use indentation when writing
	out results.
	(XMLResultStream.WriteResult): Likewise.
	(XMLResultReader._get_result_from_dom): Rename to ...
	(XMLResultReader._GetResultFromDomNode): ... this.  Support old
	and new formats.
	* qm/test/share/dtds/result.dtd: Update.
	* qm/test/share/dtds/class-directory.dtd: Likewise.

Index: qm/xmlutil.py
===================================================================
RCS file: /home/sc/Repository/qm/qm/xmlutil.py,v
retrieving revision 1.22
diff -c -5 -p -r1.22 xmlutil.py
*** qm/xmlutil.py	15 Sep 2003 20:26:40 -0000	1.22
--- qm/xmlutil.py	22 Sep 2003 04:41:58 -0000
*************** def get_child(node, child_tag):
*** 126,141 ****
      if len(matching_children) != 1:
          raise KeyError, child_tag
      return matching_children[0]
  
  
- def get_children(node, child_tag):
-     """Return a sequence of children of 'node' whose tags are 'child_tag'."""
-     
-     return filter(child_tag_predicate(child_tag), node.childNodes)
- 
- 
  def get_child_text(node, child_tag, default=None):
      """Return the text contained in a child of DOM 'node'.
  
      'child_tag' -- The tag of the child node whose text is to be
      retrieved.
--- 126,135 ----
*************** def get_child_texts(node, child_tag):
*** 162,178 ****
  
      returns -- The list containing all child nodes of 'node' which have
      tag 'child_tag'.  Each child must have exactly one child of its own,
      which must be a text node."""
  
!     return map(get_dom_text, get_children(node, child_tag))
  
  
  def create_dom_text_element(document, tag, text):
      """Return a DOM element containing a single text node.
  
!     'document' -- The containing DOM document node.
  
      'tag' -- The element tag.
  
      'text' -- The text contents of the text node."""
  
--- 156,172 ----
  
      returns -- The list containing all child nodes of 'node' which have
      tag 'child_tag'.  Each child must have exactly one child of its own,
      which must be a text node."""
  
!     return map(get_dom_text, node.getElementsByTagName(child_tag))
  
  
  def create_dom_text_element(document, tag, text):
      """Return a DOM element containing a single text node.
  
!     'document' -- The containing DOM document.
  
      'tag' -- The element tag.
  
      'text' -- The text contents of the text node."""
  
Index: qm/test/base.py
===================================================================
RCS file: /home/sc/Repository/qm/qm/test/base.py,v
retrieving revision 1.91
diff -c -5 -p -r1.91 base.py
*** qm/test/base.py	15 Sep 2003 20:26:41 -0000	1.91
--- qm/test/base.py	22 Sep 2003 04:41:58 -0000
*************** def get_extension_class_names_in_directo
*** 149,169 ****
          document = qm.xmlutil.load_xml_file(file)
          # Get the root node in the document.
          root = document.documentElement
          # Get the sequence of elements corresponding to each of the
          # classes listed in the directory.
!         classes = qm.xmlutil.get_children(root, 'class')
          # Go through each of the classes to see what kind it is.
          for c in classes:
              kind = c.getAttribute('kind')
              # Skip extensions we do not understand.  Perhaps they
              # are for some other QM tool.
              if kind not in extension_kinds:
                  continue
!             extensions[kind].append(qm.xmlutil.get_dom_text(c))
      except:
!         pass
  
      return extensions
  
  
  def get_extension_class_names(kind, database, database_path = None):
--- 149,177 ----
          document = qm.xmlutil.load_xml_file(file)
          # Get the root node in the document.
          root = document.documentElement
          # Get the sequence of elements corresponding to each of the
          # classes listed in the directory.
!         classes = root.getElementsByTagName("class")
          # Go through each of the classes to see what kind it is.
          for c in classes:
              kind = c.getAttribute('kind')
              # Skip extensions we do not understand.  Perhaps they
              # are for some other QM tool.
              if kind not in extension_kinds:
                  continue
!             if c.hasAttribute("name"):
!                 name = c.getAttribute("name")
!             else:
!                 # Before QMTest 2.1, the class name was contained in
!                 # the class element, rather than being an attribute.
!                 name = qm.xmlutil.get_dom_text(c)
!             # Strip whitespace.
!             name = name.strip()
!             extensions[kind].append(name)
      except:
!         raise
  
      return extensions
  
  
  def get_extension_class_names(kind, database, database_path = None):
Index: qm/test/cmdline.py
===================================================================
RCS file: /home/sc/Repository/qm/qm/test/cmdline.py,v
retrieving revision 1.98
diff -c -5 -p -r1.98 cmdline.py
*** qm/test/cmdline.py	15 Sep 2003 20:26:41 -0000	1.98
--- qm/test/cmdline.py	22 Sep 2003 04:42:01 -0000
*************** Valid formats are "full", "brief" (the d
*** 1112,1149 ****
          extension_class = get_extension_class_from_directory(class_name,
                                                               kind,
                                                               directory,
                                                               directories)
  
!         # Update the classes.qmc file.  If it already exists, we must
!         # read it in first.
          classes_file_name = os.path.join(directory, "classes.qmc")
!         try:
!             document = qm.xmlutil.load_xml_file(classes_file_name)
!         except:
!             document = (qm.xmlutil.create_dom_document
!                         (public_id = "Class-Directory",
!                          document_element_tag="class-directory"))
  
!         # Remove any previous entries for this class.
!         duplicates = []
!         for element in qm.xmlutil.get_children(document.documentElement,
!                                                "class"):
!             if (str(qm.xmlutil.get_dom_text(element)) == class_name):
!                 duplicates.append(element)
!         for element in duplicates:
!             document.documentElement.removeChild(element)
!             element.unlink()
!                 
!         # Construct the new node.
!         class_element = (qm.xmlutil.create_dom_text_element
!                          (document, "class", class_name))
!         class_element.setAttribute("kind", kind)
!         document.documentElement.appendChild(class_element)
  
          # Write out the file.
!         document.writexml(open(classes_file_name, "w"))
  
          return 0
  
          
      def __ExecuteSummarize(self):
--- 1112,1151 ----
          extension_class = get_extension_class_from_directory(class_name,
                                                               kind,
                                                               directory,
                                                               directories)
  
!         # Create or update the classes.qmc file.
          classes_file_name = os.path.join(directory, "classes.qmc")
!         
!         # Create a new DOM document for the class directory.
!         document = (qm.xmlutil.create_dom_document
!                     (public_id = "Class-Directory",
!                      document_element_tag="class-directory"))
!         
!         # Copy entries from the old file to the new one.
!         extensions \
!             = qm.test.base.get_extension_class_names_in_directory(directory)
!         for k, ns in extensions.iteritems():
!             for n in ns:
!                 # Remove previous entries for the class being added.
!                 if k == kind and n == class_name:
!                     continue
!                 element = document.createElement("class")
!                 element.setAttribute("kind", k)
!                 element.setAttribute("name", n)
!                 document.documentElement.appendChild(element)
  
!         # Add an entry for the new element.
!         element = document.createElement("class")
!         element.setAttribute("kind", kind)
!         element.setAttribute("name", class_name)
!         document.documentElement.appendChild(element)        
  
          # Write out the file.
!         document.writexml(open(classes_file_name, "w"),
!                           addindent = " ", newl = "\n")
  
          return 0
  
          
      def __ExecuteSummarize(self):
Index: qm/test/database.py
===================================================================
RCS file: /home/sc/Repository/qm/qm/test/database.py,v
retrieving revision 1.38
diff -c -5 -p -r1.38 database.py
*** qm/test/database.py	23 Jun 2003 06:46:47 -0000	1.38
--- qm/test/database.py	22 Sep 2003 04:42:03 -0000
*************** def load_database(db_path):
*** 1114,1125 ****
             (document.documentElement,
              lambda n: qm.test.base.get_extension_class(n, "database",
                                                         None, db_path)))
      # For backwards compatibility with QM 1.1.x, we look for "attribute"
      # elements.
!     for node in qm.xmlutil.get_children(document.documentElement,
!                                         "attribute"):
          name = node.getAttribute("name")
          # These elements were only allowed to contain strings as
          # values.
          value = qm.xmlutil.get_dom_text(node)
          # Python does not allow keyword arguments to have Unicode
--- 1114,1124 ----
             (document.documentElement,
              lambda n: qm.test.base.get_extension_class(n, "database",
                                                         None, db_path)))
      # For backwards compatibility with QM 1.1.x, we look for "attribute"
      # elements.
!     for node in document.documentElement.getElementsByTagName("attribute"):
          name = node.getAttribute("name")
          # These elements were only allowed to contain strings as
          # values.
          value = qm.xmlutil.get_dom_text(node)
          # Python does not allow keyword arguments to have Unicode
Index: qm/test/qmtest.py
===================================================================
RCS file: /home/sc/Repository/qm/qm/test/qmtest.py,v
retrieving revision 1.25
diff -c -5 -p -r1.25 qmtest.py
*** qm/test/qmtest.py	17 Sep 2003 19:15:52 -0000	1.25
--- qm/test/qmtest.py	22 Sep 2003 04:42:03 -0000
*************** import sys
*** 38,49 ****
  import gc
  
  # This executable is supposed to live in ${QM_HOME}/bin (posix)
  # or ${QM_HOME}\Scripts (nt) so we deduce the QM_HOME variable
  # by stripping off the last two components of the path.
! #
! _qm_home = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))
  os.environ['QM_HOME']=_qm_home
  
  import qm
  
  class config:
--- 38,50 ----
  import gc
  
  # This executable is supposed to live in ${QM_HOME}/bin (posix)
  # or ${QM_HOME}\Scripts (nt) so we deduce the QM_HOME variable
  # by stripping off the last two components of the path.
! _qm_home = os.environ.get("QM_HOME",
!                           os.path.dirname(os.path.dirname(os.path.abspath
!                                                           (sys.argv[0]))))
  os.environ['QM_HOME']=_qm_home
  
  import qm
  
  class config:
Index: qm/test/result.py
===================================================================
RCS file: /home/sc/Repository/qm/qm/test/result.py,v
retrieving revision 1.19
diff -c -5 -p -r1.19 result.py
*** qm/test/result.py	9 Aug 2003 05:15:02 -0000	1.19
--- qm/test/result.py	22 Sep 2003 04:42:05 -0000
*************** class Result:
*** 323,345 ****
          # Add a property element for each property.
          keys = self.keys()
          keys.sort()
          for key in keys:
              value = self[key]
!             property_element = document.createElement("property")
!             # The property name is an attribute.
!             property_element.setAttribute("name", str(key))
!             if type(value) in qm.common.string_types:
!                 # The property value is contained in a text mode.
!                 node = document.createTextNode(str(value))
!                 property_element.appendChild(node)
!             else:
!                 for text in value:
!                     node = document.createTextNode(str(text))
!                     property_element.appendChild(node)
!             # Add the property element to the result node.
!             element.appendChild(property_element)
  
          return element
  
      # These methods allow 'Result' to act like a dictionary of
      # annotations.
--- 323,342 ----
          # Add a property element for each property.
          keys = self.keys()
          keys.sort()
          for key in keys:
              value = self[key]
!             annotation_element = document.createElement("annotation")
!             # The annotation name is an attribute.
!             annotation_element.setAttribute("name", str(key))
!             # The annotation value is contained in a text node.  The
!             # data is enclosed in quotes for robustness if the
!             # document is pretty-printed.
!             node = document.createTextNode('"' + str(value) + '"')
!             annotation_element.appendChild(node)
!             # Add the annotation element to the result node.
!             element.appendChild(annotation_element)
  
          return element
  
      # These methods allow 'Result' to act like a dictionary of
      # annotations.
*************** class Result:
*** 375,379 ****
--- 372,382 ----
  
  
      def items(self):
          return self.__annotations.items()
  
+ 
+ ########################################################################
+ # Variables
+ ########################################################################
+ 
+ __all__ = ["Result"]
Index: qm/test/classes/classes.qmc
===================================================================
RCS file: /home/sc/Repository/qm/qm/test/classes/classes.qmc,v
retrieving revision 1.13
diff -c -5 -p -r1.13 classes.qmc
*** qm/test/classes/classes.qmc	3 Jul 2003 19:32:04 -0000	1.13
--- qm/test/classes/classes.qmc	22 Sep 2003 04:42:05 -0000
***************
*** 1,27 ****
  <?xml version="1.0" ?>
  <class-directory>
! <class kind="database">mount_database.MountDatabase</class>
! <class kind="database">xml_database.XMLDatabase</class>
! <class kind="test">command.ExecTest</class>
! <class kind="test">command.ShellCommandTest</class>
! <class kind="test">command.ShellScriptTest</class>
! <class kind="test">file.FileContentsTest</class>
! <class kind="test">python.ExecTest</class>
! <class kind="test">python.ExceptionTest</class>
! <class kind="test">python.StringExceptionTest</class>
! <class kind="resource">temporary.TempDirectoryResource</class>
! <class kind="target">serial_target.SerialTarget</class>
! <class kind="target">thread_target.ThreadTarget</class>
! <class kind="target">process_target.ProcessTarget</class>
! <class kind="target">rsh_target.RSHTarget</class>
! <class kind="label">file_label.FileLabel</class>
! <class kind="label">python_label.PythonLabel</class>
! <class kind="result_stream">text_result_stream.TextResultStream</class>
! <class kind="result_stream">xml_result_stream.XMLResultStream</class>
! <class kind="result_reader">xml_result_stream.XMLResultReader</class>
! <class kind="result_stream">pickle_result_stream.PickleResultStream</class>
! <class kind="result_reader">pickle_result_stream.PickleResultReader</class>
! <class kind="result_stream">sql_result_stream.SQLResultStream</class>
! <class kind="result_reader">sql_result_stream.SQLResultReader</class>
! <class kind="result_stream">dejagnu_stream.DejaGNUStream</class>
  </class-directory>
--- 1,27 ----
  <?xml version="1.0" ?>
  <class-directory>
!  <class kind="result_reader" name="pickle_result_stream.PickleResultReader"/>
!  <class kind="result_reader" name="sql_result_stream.SQLResultReader"/>
!  <class kind="result_reader" name="xml_result_stream.XMLResultReader"/>
!  <class kind="result_stream" name="dejagnu_stream.DejaGNUStream"/>
!  <class kind="result_stream" name="pickle_result_stream.PickleResultStream"/>
!  <class kind="result_stream" name="sql_result_stream.SQLResultStream"/>
!  <class kind="result_stream" name="text_result_stream.TextResultStream"/>
!  <class kind="result_stream" name="xml_result_stream.XMLResultStream"/>
!  <class kind="resource" name="temporary.TempDirectoryResource"/>
!  <class kind="target" name="process_target.ProcessTarget"/>
!  <class kind="target" name="rsh_target.RSHTarget"/>
!  <class kind="target" name="serial_target.SerialTarget"/>
!  <class kind="target" name="thread_target.ThreadTarget"/>
!  <class kind="database" name="mount_database.MountDatabase"/>
!  <class kind="test" name="command.ExecTest"/>
!  <class kind="test" name="command.ShellCommandTest"/>
!  <class kind="test" name="command.ShellScriptTest"/>
!  <class kind="test" name="file.FileContentsTest"/>
!  <class kind="test" name="python.ExceptionTest"/>
!  <class kind="test" name="python.ExecTest"/>
!  <class kind="test" name="python.StringExceptionTest"/>
!  <class kind="label" name="file_label.FileLabel"/>
!  <class kind="label" name="python_label.PythonLabel"/>
!  <class kind="database" name="xml_database.XMLDatabase"/>
  </class-directory>
Index: qm/test/classes/xml_result_stream.py
===================================================================
RCS file: /home/sc/Repository/qm/qm/test/classes/xml_result_stream.py,v
retrieving revision 1.4
diff -c -5 -p -r1.4 xml_result_stream.py
*** qm/test/classes/xml_result_stream.py	15 Sep 2003 20:26:41 -0000	1.4
--- qm/test/classes/xml_result_stream.py	22 Sep 2003 04:42:05 -0000
*************** class XMLResultStream(FileResultStream):
*** 54,89 ****
          self.file.write("<results>\n")
  
  
      def WriteAnnotation(self, key, value):
  
!             element = self.__document.createElement("annotation")
!             element.setAttribute("key", key)
!             text = self.__document.createTextNode(value)
!             element.appendChild(text)
!             element.writexml(self.file)
!             # Following increases readability of output:
!             self.file.write("\n")
  
  
      def WriteResult(self, result):
-         """Output a test or resource result.
- 
-         'result' -- A 'Result'."""
  
          element = result.MakeDomNode(self.__document)
!         element.writexml(self.file)
!         self.file.write("\n")
          
  
      def Summarize(self):
-         """Output summary information about the results.
- 
-         When this method is called, the test run is complete.  Summary
-         information should be displayed for the user, if appropriate.
-         Any finalization, such as the closing of open files, should
-         also be performed at this point."""
  
          # Finish the list of results.
          self.file.write("\n</results>\n")
  
          FileResultStream.Summarize(self)
--- 54,78 ----
          self.file.write("<results>\n")
  
  
      def WriteAnnotation(self, key, value):
  
!         element = self.__document.createElement("annotation")
!         element.setAttribute("key", key)
!         text = self.__document.createTextNode(value)
!         element.appendChild(text)
!         element.writexml(self.file, addindent = " ", newl = "\n")
  
  
      def WriteResult(self, result):
  
          element = result.MakeDomNode(self.__document)
!         element.writexml(self.file, indent = " ", addindent = " ",
!                          newl = "\n")
          
  
      def Summarize(self):
  
          # Finish the list of results.
          self.file.write("\n</results>\n")
  
          FileResultStream.Summarize(self)
*************** class XMLResultReader(FileResultReader):
*** 99,158 ****
  
          super(XMLResultReader, self).__init__(arguments)
  
          document = qm.xmlutil.load_xml(self.file)
          node = document.documentElement
!         results = qm.xmlutil.get_children(node, "result")
          self.__node_iterator = iter(results)
  
          # Read out annotations
          self._annotations = {}
!         annotation_nodes = qm.xmlutil.get_children(node, "annotation")
          for node in annotation_nodes:
              key = node.getAttribute("key")
!             value = qm.xmlutil.get_dom_text(node)
              self._annotations[key] = value
  
  
      def GetAnnotations(self):
  
          return self._annotations
  
  
!     def _result_from_dom(self, node):
          """Extract a result from a DOM node.
  
          'node' -- A DOM node corresponding to a "result" element.
  
          returns -- A 'Result' object."""
  
          assert node.tagName == "result"
          # Extract the outcome.
!         outcome = qm.xmlutil.get_child_text(node, "outcome")
          # Extract the test ID.
          test_id = node.getAttribute("id")
          kind = node.getAttribute("kind")
          # Build a Result.
          result = Result(kind, test_id, outcome)
!         # Extract properties, one for each property element.
!         for property_node in node.getElementsByTagName("property"):
!             # The name is stored in an attribute.
!             name = property_node.getAttribute("name")
!             # The value is stored in the child text node.
!             value = qm.xmlutil.get_dom_text(property_node)
!             # Store it.
              result[name] = value
  
          return result
  
  
-     def GetResult(self):
- 
-         try:
-             return self._result_from_dom(self.__node_iterator.next())
-         except StopIteration:
-             return None
  
  ########################################################################
  # Local Variables:
  # mode: python
  # indent-tabs-mode: nil
--- 88,162 ----
  
          super(XMLResultReader, self).__init__(arguments)
  
          document = qm.xmlutil.load_xml(self.file)
          node = document.documentElement
!         results = node.getElementsByTagName("result")
          self.__node_iterator = iter(results)
  
          # Read out annotations
          self._annotations = {}
!         annotation_nodes = node.getElementsByTagName("annotation")
          for node in annotation_nodes:
              key = node.getAttribute("key")
!             value = qm.xmlutil.get_dom_text(node).strip()
              self._annotations[key] = value
  
  
      def GetAnnotations(self):
  
          return self._annotations
  
  
!     def GetResult(self):
! 
!         try:
!             return self._GetResultFromDomNode(self.__node_iterator.next())
!         except StopIteration:
!             return None
! 
! 
!     def _GetResultFromDomNode(self, node):
          """Extract a result from a DOM node.
  
          'node' -- A DOM node corresponding to a "result" element.
  
          returns -- A 'Result' object."""
  
          assert node.tagName == "result"
          # Extract the outcome.
!         outcome = qm.xmlutil.get_child_text(node, "outcome").strip()
          # Extract the test ID.
          test_id = node.getAttribute("id")
          kind = node.getAttribute("kind")
          # Build a Result.
          result = Result(kind, test_id, outcome)
!         # Extract annotations.
!         for n in node.childNodes:
!             if n.nodeType != node.ELEMENT_NODE:
!                 continue
!             if n.tagName == "annotation":
!                 quoted = 1
!             elif n.tagName == "property":
!                 # Versions of QMTest before 2.1 used the "property" tag,
!                 # and did not quote the contained text.
!                 quoted = 0
!             else:
!                 continue
!             # Get the name of the annotation.
!             name = n.getAttribute("name")
!             # Get the value of the annotation.
!             value = qm.xmlutil.get_dom_text(n)
!             if quoted:
!                 # Remove whitespace and then remove the enclosing quotes.
!                 value = value.strip()[1:-1]
!             # Remember the annotation.
              result[name] = value
  
          return result
  
  
  
  ########################################################################
  # Local Variables:
  # mode: python
  # indent-tabs-mode: nil
Index: qm/test/share/dtds/class-directory.dtd
===================================================================
RCS file: /home/sc/Repository/qm/qm/test/share/dtds/class-directory.dtd,v
retrieving revision 1.4
diff -c -5 -p -r1.4 class-directory.dtd
*** qm/test/share/dtds/class-directory.dtd	15 Sep 2003 20:26:41 -0000	1.4
--- qm/test/share/dtds/class-directory.dtd	22 Sep 2003 04:42:05 -0000
***************
*** 19,28 ****
--- 19,29 ----
  <!ELEMENT class-directory (class*)>
  
  <!-- A class. -->
  <!ELEMENT class (#PCDATA)>
  <!ATTLIST class kind CDATA #REQUIRED>
+ <!ATTLIST class name CDATA #REQUIRED>
  
  <!-- 
    Local Variables:
    mode: xml
    indent-tabs-mode: nil
Index: qm/test/share/dtds/result.dtd
===================================================================
RCS file: /home/sc/Repository/qm/qm/test/share/dtds/result.dtd,v
retrieving revision 1.4
diff -c -5 -p -r1.4 result.dtd
*** qm/test/share/dtds/result.dtd	15 Sep 2003 20:26:42 -0000	1.4
--- qm/test/share/dtds/result.dtd	22 Sep 2003 04:42:05 -0000
***************
*** 29,40 ****
  
  <!-- The outcome of a test or resource.  -->
  <!ELEMENT outcome (#PCDATA)>
  
  <!-- An additional annotation to the result.  -->
! <!ELEMENT property (#PCDATA)>
! <!ATTLIST property name CDATA #REQUIRED>
  
  <!-- 
    Local Variables:
    mode: xml
    indent-tabs-mode: nil
--- 29,40 ----
  
  <!-- The outcome of a test or resource.  -->
  <!ELEMENT outcome (#PCDATA)>
  
  <!-- An additional annotation to the result.  -->
! <!ELEMENT annotation (#PCDATA)>
! <!ATTLIST annotation name CDATA #REQUIRED>
  
  <!-- 
    Local Variables:
    mode: xml
    indent-tabs-mode: nil
Index: tests/results_files/xml_results_v2.qmr
===================================================================
RCS file: tests/results_files/xml_results_v2.qmr
diff -N tests/results_files/xml_results_v2.qmr
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- tests/results_files/xml_results_v2.qmr	22 Sep 2003 04:42:05 -0000
***************
*** 0 ****
--- 1,105 ----
+ <?xml version='1.0' encoding='ISO-8859-1'?>
+ <!DOCTYPE results PUBLIC "-//QM/2.1/QMTest/Result//EN" "http://www.codesourcery.com/qm/dtds/2.1/qmtest/result.dtd">
+ <results>
+ <annotation key="qmtest.run.start_time">
+  2003-09-22T01:43:05Z
+ </annotation>
+  <result id="error" kind="test">
+   <outcome>
+    ERROR
+   </outcome>
+   <annotation name="qmtest.cause">
+    "Exception evaluating expression."
+   </annotation>
+   <annotation name="qmtest.exception">
+    "exceptions.SyntaxError: invalid syntax (line 1)"
+   </annotation>
+   <annotation name="qmtest.target">
+    "local"
+   </annotation>
+   <annotation name="qmtest.traceback">
+    "<pre>  File "/home/mitchell/dev/qm-mainline/qm/test/classes/python.py", line 101, in Run
+     global_namespace, local_namespace)
+ </pre>"
+   </annotation>
+  </result>
+  <result id="fail" kind="test">
+   <outcome>
+    FAIL
+   </outcome>
+   <annotation name="ExecTest.expr">
+    "0"
+   </annotation>
+   <annotation name="ExecTest.value">
+    "0"
+   </annotation>
+   <annotation name="qmtest.cause">
+    "Expression evaluates to false."
+   </annotation>
+   <annotation name="qmtest.target">
+    "local"
+   </annotation>
+  </result>
+  <result id="tmpdir_resource" kind="resource_setup">
+   <outcome>
+    PASS
+   </outcome>
+   <annotation name="qmtest.target">
+    "local"
+   </annotation>
+  </result>
+  <result id="fail_with_tmpdir" kind="test">
+   <outcome>
+    FAIL
+   </outcome>
+   <annotation name="ExecTest.expr">
+    "0"
+   </annotation>
+   <annotation name="ExecTest.value">
+    "0"
+   </annotation>
+   <annotation name="qmtest.cause">
+    "Expression evaluates to false."
+   </annotation>
+   <annotation name="qmtest.target">
+    "local"
+   </annotation>
+  </result>
+  <result id="pass" kind="test">
+   <outcome>
+    PASS
+   </outcome>
+   <annotation name="qmtest.target">
+    "local"
+   </annotation>
+  </result>
+  <result id="untested" kind="test">
+   <outcome>
+    UNTESTED
+   </outcome>
+   <annotation name="qmtest.cause">
+    "A prerequisite produced an incorrect outcome."
+   </annotation>
+   <annotation name="qmtest.expected_outcome">
+    "PASS"
+   </annotation>
+   <annotation name="qmtest.outcome">
+    "FAIL"
+   </annotation>
+   <annotation name="qmtest.prequisite">
+    "fail"
+   </annotation>
+  </result>
+  <result id="tmpdir_resource" kind="resource_cleanup">
+   <outcome>
+    PASS
+   </outcome>
+   <annotation name="qmtest.target">
+    "local"
+   </annotation>
+  </result>
+ <annotation key="qmtest.run.end_time">
+  2003-09-22T01:43:05Z
+ </annotation>
+ 
+ </results>



More information about the qmtest mailing list