You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by mb...@apache.org on 2020/11/20 22:55:37 UTC

[incubator-daffodil] branch master updated: TDML Runner provides namespace. Disallows dup test names.

This is an automated email from the ASF dual-hosted git repository.

mbeckerle pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-daffodil.git


The following commit(s) were added to refs/heads/master by this push:
     new 7037de4  TDML Runner provides namespace. Disallows dup test names.
7037de4 is described below

commit 7037de42e28cf9cb48d2275f9ce3409a00e57e08
Author: Michael Beckerle <mb...@tresys.com>
AuthorDate: Wed Nov 18 00:57:59 2020 -0500

    TDML Runner provides namespace. Disallows dup test names.
    
    Set out to fix the fact that the TDML Runner needs to pass the
    namespace of the root to the TDML processor, as some processors can't
    (from their current APIs) search and resolve this themselves.
    
    This fixes a problem with vcard and the IBM cross tester rig.
    
    DAFFODIL-1299, DAFFODIL-2440
---
 .../resources/org/apache/daffodil/xsd/tdml.xsd     |  1 +
 .../org/apache/daffodil/tdml/TDMLRunner.scala      | 43 ++++++++++++++++++----
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd b/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd
index 711dc7a..2cd8bfc 100644
--- a/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd
+++ b/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd
@@ -159,6 +159,7 @@
     <attribute name="name" type="xs:NCName" use="required"/>
     <attribute name="ID" type="xs:token" use="optional"/>
     <attribute name="root" type="xs:NCName" use="optional"/> <!-- only needed when there is no infoset. -->
+    <attribute name="rootNS" type="xs:string" use="optional"/> <!-- only needed when there is no infoset. -->
     <attribute name="model" type="xs:string" use="optional"/> <!-- is there a type for a path/uri? -->
     <attribute name="config" type="xs:string" use="optional"/> <!-- is there a type for a path/uri? -->
     <attribute name="roundTrip" type="tns:roundTripType" use="optional"/>
diff --git a/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala b/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala
index 9e2a3c1..0ac8fa6 100644
--- a/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala
+++ b/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala
@@ -304,10 +304,9 @@ class DFDLTestSuite private[tdml] (
     _.tcName
   }.filter { case (name, seq) => seq.length > 1 }
   if (duplicateTestCases.nonEmpty) {
-    duplicateTestCases.foreach {
-      case (name, _) =>
-        System.err.println("TDML Runner: More than one test case for name '%s'.".format(name))
-    }
+    val listOfDups = duplicateTestCases.map{ case(name, _) => name}
+    throw new TDMLExceptionImpl(
+      "More than one test for names: " + listOfDups.mkString(","), None)
   }
   val testCaseMap = testCases.map { tc => (tc.tcName -> tc) }.toMap
   val suiteName = (ts \ "@suiteName").text
@@ -380,7 +379,7 @@ class DFDLTestSuite private[tdml] (
     }
     if (isTDMLFileValid) {
       loadingExceptions.foreach { le =>  log(LogLevel.Warning, le.toString) }
-      val testCase = testCases.find(_.tcName == testName)
+      val testCase = testCaseMap.get(testName)
       testCase match {
         case None => throw TDMLException("test " + testName + " was not found.", None)
         case Some(tc) => {
@@ -511,6 +510,7 @@ abstract class TestCase(testCaseXML: NodeSeq, val parent: DFDLTestSuite)
   lazy val tcID = (testCaseXML \ "@ID").text
   lazy val id = tcName + (if (tcID != "") "(" + tcID + ")" else "")
   lazy val rootAttrib = (testCaseXML \ "@root").text
+  lazy val rootNSAttrib = (testCaseXML \ "@rootNS").text
 
   lazy val (infosetRootName, infosetRootNamespaceString) =
     if (this.optExpectedOrInputInfoset.isDefined) {
@@ -528,13 +528,39 @@ abstract class TestCase(testCaseXML: NodeSeq, val parent: DFDLTestSuite)
     } else rootAttrib
   }
 
-  lazy val rootNamespaceString = {
+  def getRootNamespaceString(schemaArg : Option[Node]) = {
     if (optExpectedOrInputInfoset.isDefined)
       infosetRootNamespaceString
     else if (embeddedSchema.isDefined)
       XMLUtils.EXAMPLE_NAMESPACE.toString
-    else
-      null
+    else if (this.rootNSAttrib != "")
+      rootNSAttrib
+    else {
+      // For some TDML Processors, we have to provide
+      // the root namespace. They don't provide a way to search
+      // for an element when just the name is unambiguous.
+      // So since nothing was provided, we just grab the
+      // target namespace URI (if any) from the primary
+      // schema file. If that turns out to be wrong, then
+      // the test case has to have an explicit rootNS attribute.
+      val schemaNode = schemaArg.getOrElse {
+        val schemaSource = getSuppliedSchema(None)
+        val source = schemaSource.newInputSource()
+        val node = try{
+          scala.xml.XML.load(source)
+        } catch {
+          // any exception while loading then we just use a dummy node.
+          case e:SAXParseException => <dummy/>
+        }
+        node
+      }
+      val tns = (schemaNode \ "@targetNamespace").text
+      val nsURIString = {
+        if (tns != "") tns
+        else null
+      }
+      nsURIString
+    }
   }
 
   lazy val model = (testCaseXML \ "@model").text
@@ -750,6 +776,7 @@ abstract class TestCase(testCaseXML: NodeSeq, val parent: DFDLTestSuite)
         else if (optExpectedWarnings.isDefined) false
         else true
 
+      val rootNamespaceString = getRootNamespaceString(schemaArg)
       val compileResult: TDML.CompileResult = impl.getProcessor(suppliedSchema, useSerializedProcessor, Option(rootName), Option(rootNamespaceString))
       val newCompileResult : TDML.CompileResult = compileResult.right.map {
         case (diags, proc: TDMLDFDLProcessor) =>