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

olabusayo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil.git


The following commit(s) were added to refs/heads/main by this push:
     new 78f2e4bda Output diagnosticFile for embedded schemas diagnostics
78f2e4bda is described below

commit 78f2e4bda3cdc8f1365da2e8f74df971536846dc
Author: olabusayoT <[email protected]>
AuthorDate: Sat Mar 30 21:18:39 2024 -0400

    Output diagnosticFile for embedded schemas diagnostics
    
    - UnitTestSchemaSource embedded schemas called from Runner(testSuite) don't 
have the dafint prefix bound so we check if they have it and bind it when the 
dafint:file info is added. The issue they still use the temp file and don't 
have an associated TDML file we can set for diagnosticFile/URI
    - TDML embedded schemas are given a diagnostic file that is gotten from 
dafint:file attr. This is set using diagnosticFile provided when the 
URISchemaSource was created for the embedded schema in the DFDL test suite
    - pass around URISchemaSource instead of URI in DFDL Test Suite
    - get the DefinedSchema filename from the tsURISchemaSource.diagnosticFile 
or use the dafint:file attribute
    - add tdml test with no path separators for windows
    - add unittests to hit usageError when a node, file or URISChemaSource 
isn't passsed in and to hit when the node passed in is not valid
    
    DAFFODIL-2159
---
 .../daffodil/lib/api/DaffodilSchemaSource.scala    |  5 +++
 .../org/apache/daffodil/lib/util/SchemaUtils.scala |  5 ++-
 .../org/apache/daffodil/lib/xml/XMLUtils.scala     |  9 ++++
 .../org/apache/daffodil/tdml/RunnerFactory.scala   |  8 ++--
 .../org/apache/daffodil/tdml/TDMLRunner.scala      | 48 ++++++++++++++--------
 .../daffodil/processor/tdml/TestTDMLRunner.scala   | 26 ++++++++++++
 .../section00/general/testElementFormDefault.tdml  | 26 +++++++++++-
 .../general/TestElementFormDefaultGeneral.scala    |  3 ++
 8 files changed, 107 insertions(+), 23 deletions(-)

diff --git 
a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/api/DaffodilSchemaSource.scala
 
b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/api/DaffodilSchemaSource.scala
index 1179115b7..1ef6157fb 100644
--- 
a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/api/DaffodilSchemaSource.scala
+++ 
b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/api/DaffodilSchemaSource.scala
@@ -213,4 +213,9 @@ case class EmbeddedSchemaSource(node: Node, nameHint: 
String, optTmpDir: Option[
     XMLUtils.convertNodeToTempFile(node, optTmpDir.orNull, nameHint),
   ) {
   override val blameName = nameHint
+
+  override val diagnosticFile =
+    XMLUtils
+      .getOptTDMLFileFromNode(node)
+      .getOrElse(super.diagnosticFile)
 }
diff --git 
a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/SchemaUtils.scala 
b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/SchemaUtils.scala
index 7445f2649..839da5dd8 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/SchemaUtils.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/SchemaUtils.scala
@@ -100,7 +100,7 @@ object SchemaUtils {
   ): Elem = {
     val fileAttrib =
       if (fileName == "") Null
-      else Attribute(XMLUtils.INT_PREFIX, "file", Text(fileName), Null)
+      else Attribute(XMLUtils.INT_PREFIX, XMLUtils.FILE_ATTRIBUTE_NAME, 
Text(fileName), Null)
     val targetNamespaceAttrib =
       if (targetNamespace == NoNamespace) Null
       else Attribute(None, "targetNamespace", 
Text(targetNamespace.uri.toString), Null)
@@ -110,7 +110,7 @@ object SchemaUtils {
         import XMLUtils._
         <ignore xmlns:xsd={xsdURI} xmlns:dfdl={dfdlURI} xmlns:xsi={xsiURI} 
xmlns:fn={
           fnURI
-        } xmlns:math={mathURI} xmlns:dafint={dafintURI}/>.scope
+        } xmlns:math={mathURI}/>.scope
       }
     scope = XMLUtils.combineScopes("xs", XMLUtils.xsdURI, scope) // always 
need this one
     if (useDefaultNamespace) {
@@ -120,6 +120,7 @@ object SchemaUtils {
       scope = XMLUtils.combineScopes("tns", targetNamespace, scope)
     scope = XMLUtils.combineScopes("ex", targetNamespace, scope)
     scope = XMLUtils.combineScopes("dfdlx", XMLUtils.DFDLX_NAMESPACE, scope)
+    scope = XMLUtils.combineScopes(XMLUtils.INT_PREFIX, XMLUtils.INT_NS, scope)
 
     val schemaNode =
       <xs:schema elementFormDefault={elementFormDefault}>
diff --git 
a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/xml/XMLUtils.scala 
b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/xml/XMLUtils.scala
index 5d6996c55..860f0086b 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/xml/XMLUtils.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/xml/XMLUtils.scala
@@ -1215,6 +1215,15 @@ Differences were (path, expected, actual):
     }
   }
 
+  /**
+   * Look for the dafint:file attribute that should be set for every embedded 
schema
+   */
+  def getOptTDMLFileFromNode(node: Node): Option[File] = {
+    node
+      .attribute(XMLUtils.INT_NS, XMLUtils.FILE_ATTRIBUTE_NAME)
+      .map(uriStringNode => new File(uriStringNode.text))
+  }
+
   /**
    * for quick tests, we use literal scala nodes. However, the underlying
    * infrastructure wants to be all file centric for diagnostic-message
diff --git 
a/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/RunnerFactory.scala 
b/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/RunnerFactory.scala
index c2d3b7dcb..936ad6c17 100644
--- 
a/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/RunnerFactory.scala
+++ 
b/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/RunnerFactory.scala
@@ -20,6 +20,7 @@ package org.apache.daffodil.tdml
 import java.nio.file.Paths
 
 import org.apache.daffodil.lib.api.TDMLImplementation
+import org.apache.daffodil.lib.api.URISchemaSource
 import org.apache.daffodil.lib.util.Misc
 
 /**
@@ -203,13 +204,14 @@ class Runner private (
   // synchronized to ensure we only ever create one per Runner.
   def getTS = this.synchronized {
     if (ts == null) {
-      val elemOrURI: Any = source match {
+      val elemOrURISchemaSource: Any = source match {
         case Left(l) => l
         case Right(r) =>
-          if (r.startsWith("/")) Misc.getRequiredResource(r) else new 
java.net.URI(r)
+          val uri = if (r.startsWith("/")) Misc.getRequiredResource(r) else 
new java.net.URI(r)
+          URISchemaSource(new java.io.File(r), uri)
       }
       ts = new DFDLTestSuite(
-        elemOrURI,
+        elemOrURISchemaSource,
         optTDMLImplementation,
         validateTDMLFile,
         validateDFDLSchemas,
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 0499c5c29..5a6c2a1a0 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
@@ -171,7 +171,7 @@ private[tdml] object DFDLTestSuite {
  */
 
 class DFDLTestSuite private[tdml] (
-  aNodeFileOrURL: Any,
+  aNodeFileOrURISchemaSource: Any,
   val optTDMLImplementation: Option[TDMLImplementation],
   validateTDMLFile: Boolean,
   val validateDFDLSchemas: Boolean,
@@ -185,11 +185,12 @@ class DFDLTestSuite private[tdml] (
 
   val TMP_DIR = System.getProperty("java.io.tmpdir", ".")
 
-  aNodeFileOrURL match {
-    case _: URI => // ok
+  aNodeFileOrURISchemaSource match {
+    case _: URISchemaSource => // ok
     case _: File => // ok
     case _: scala.xml.Node => // ok
-    case x => Assert.usageError("argument was not a scala.xmlNode, File, or 
URI: " + x)
+    case x =>
+      Assert.usageError("argument was not a scala.xmlNode, File, or 
URISchemaSource: " + x)
   }
 
   /*
@@ -298,7 +299,7 @@ class DFDLTestSuite private[tdml] (
       None
     }
 
-  lazy val (tsRaw, tsURI) = aNodeFileOrURL match {
+  lazy val (tsRaw, tsURISchemaSource) = aNodeFileOrURISchemaSource match {
     case tsNode: Node => {
       //
       // We were passed a literal schema node. This is for unit testing
@@ -307,7 +308,11 @@ class DFDLTestSuite private[tdml] (
       val tmpDir = new File(TMP_DIR, "daffodil")
       tmpDir.mkdirs()
 
-      val src = UnitTestSchemaSource(tsNode, "", Some(tmpDir))
+      val nameHint = Seq((tsNode \@ "suiteName"), (tsNode \ "defineSchema" \@ 
"name"))
+        .filterNot(Misc.isNullOrBlank)
+        .mkString("_")
+
+      val src = UnitTestSchemaSource(tsNode, nameHint, Some(tmpDir))
 
       loader.load(
         src,
@@ -315,29 +320,30 @@ class DFDLTestSuite private[tdml] (
         addPositionAttributes = true,
       ) // want line numbers for TDML
       //
-      (tsNode, src.uriForLoading)
+      (tsNode, src)
     }
     case tdmlFile: File => {
       Logger.log.info(s"loading TDML file: ${tdmlFile}")
       val uri = tdmlFile.toURI()
+      val schemaSource = URISchemaSource(tdmlFile, uri)
       val newNode =
         loader.load(
-          URISchemaSource(tdmlFile, uri),
+          schemaSource,
           optTDMLSchema,
           addPositionAttributes = true,
         )
-      val res = (newNode, uri)
+      val res = (newNode, schemaSource)
       Logger.log.debug(s"done loading TDML file: ${tdmlFile}")
       res
     }
-    case uri: URI => {
+    case uriSchemaSource: URISchemaSource => {
       val newNode =
         loader.load(
-          URISchemaSource(Misc.uriToDiagnosticFile(uri), uri),
+          uriSchemaSource,
           optTDMLSchema,
           addPositionAttributes = true,
         )
-      val res = (newNode, uri)
+      val res = (newNode, uriSchemaSource)
       res
     }
     case _ => Assert.usageError("not a Node, File, or URL")
@@ -423,7 +429,10 @@ class DFDLTestSuite private[tdml] (
     if (isTDMLFileValid)
       testCases.map { _.run() }
     else {
-      throw TDMLException(s"TDML file ${tsURI} is not valid.", None)
+      throw TDMLException(
+        s"TDML file ${tsURISchemaSource.diagnosticFile.getPath} is not valid.",
+        None,
+      )
     }
   }
 
@@ -475,7 +484,7 @@ class DFDLTestSuite private[tdml] (
    * directory as the tdml file, and some other variations.
    */
   def findTDMLResource(resName: String): Option[URI] = {
-    Misc.searchResourceOption(resName, Some(tsURI))
+    Misc.searchResourceOption(resName, Some(tsURISchemaSource.uri))
   }
 
   def findEmbeddedSchema(modelName: String): Option[DefinedSchema] = {
@@ -2080,9 +2089,14 @@ case class DefinedSchema(xml: Node, parent: 
DFDLTestSuite) {
   val dfdlTopLevels = defineFormats ++ defaultFormats ++ defineVariables ++ 
defineEscapeSchemes
   val xsdTopLevels = globalElementDecls ++ globalSimpleTypeDefs ++
     globalComplexTypeDefs ++ globalGroupDefs
-  val fileName = parent.ts.attribute(XMLUtils.INT_NS, 
XMLUtils.FILE_ATTRIBUTE_NAME) match {
-    case Some(seqNodes) => seqNodes.toString
-    case None => ""
+  private val parentDiagnosticFileName = 
parent.tsURISchemaSource.diagnosticFile.getPath
+  val fileName = if (parentDiagnosticFileName.nonEmpty) {
+    parentDiagnosticFileName
+  } else {
+    parent.ts.attribute(XMLUtils.INT_NS, XMLUtils.FILE_ATTRIBUTE_NAME) match {
+      case Some(seqNodes) => seqNodes.toString
+      case None => ""
+    }
   }
   lazy val xsdSchema =
     SchemaUtils.dfdlTestSchema(
diff --git 
a/daffodil-tdml-processor/src/test/scala/org/apache/daffodil/processor/tdml/TestTDMLRunner.scala
 
b/daffodil-tdml-processor/src/test/scala/org/apache/daffodil/processor/tdml/TestTDMLRunner.scala
index 5014fc748..293bf80d3 100644
--- 
a/daffodil-tdml-processor/src/test/scala/org/apache/daffodil/processor/tdml/TestTDMLRunner.scala
+++ 
b/daffodil-tdml-processor/src/test/scala/org/apache/daffodil/processor/tdml/TestTDMLRunner.scala
@@ -21,6 +21,7 @@ import java.io.File
 
 import org.apache.daffodil.lib.Implicits._
 import org.apache.daffodil.lib.Implicits.using
+import org.apache.daffodil.lib.exceptions.UsageException
 import org.apache.daffodil.lib.util._
 import org.apache.daffodil.lib.xml.XMLUtils
 import org.apache.daffodil.tdml.Runner
@@ -953,6 +954,31 @@ f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff
     )
   }
 
+  @Test def testNullTestSuite(): Unit = {
+    val testSuite: scala.xml.Elem = null
+    val runner = new Runner(testSuite)
+    val exc = intercept[UsageException] {
+      runner.runAllTests()
+    }
+    assertTrue(
+      exc.getMessage.contains(
+        "argument was not a scala.xmlNode, File, or URISchemaSource: null",
+      ),
+    )
+  }
+
+  @Test def testEmptyNodeTestSuite(): Unit = {
+    val testSuite: scala.xml.Elem = <node/>
+    val runner = new Runner(testSuite)
+    val exc = intercept[TDMLException] {
+      runner.runAllTests()
+    }
+    assertTrue(
+      exc.getMessage().contains("TDML file") &&
+        exc.getMessage().contains("is not valid"),
+    )
+  }
+
   @Test def testDuplicateDefineConfig(): Unit = {
     val testSuite =
       <tdml:testSuite suiteName="theSuiteName" xmlns:tns={tns} 
xmlns:tdml={tdml} xmlns:dfdl={
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/testElementFormDefault.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/testElementFormDefault.tdml
index 5f5ccc02d..b8ebee0ce 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/testElementFormDefault.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/testElementFormDefault.tdml
@@ -136,7 +136,31 @@
     <tdml:document><![CDATA[1]]></tdml:document>
 
   </tdml:unparserTestCase>
-  
+
+  <tdml:unparserTestCase name="delimOptPresentQualified02_additionalByte" 
root="r1"
+                         model="qualified" roundTrip="true">
+
+    <tdml:infoset >
+      <tdml:dfdlInfoset>
+        <ex:r1>
+          <ex:opt>12</ex:opt>
+        </ex:r1>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:document><![CDATA[12]]></tdml:document>
+
+    <tdml:errors>
+      <tdml:error>Unparse Error</tdml:error>
+      <tdml:error>Schema context: ex:opt</tdml:error>
+      <tdml:error>org</tdml:error>
+      <tdml:error>apache</tdml:error>
+      <tdml:error>daffodil</tdml:error>
+      <tdml:error>section00</tdml:error>
+      <tdml:error>general</tdml:error>
+      <tdml:error>testElementFormDefault.tdml</tdml:error>
+    </tdml:errors>
+
+  </tdml:unparserTestCase>
 <!--
   Test Name: delimOptPresentQualified03
      Schema: elementFormDefaultQualified.dfdl.xsd
diff --git 
a/daffodil-test/src/test/scala/org/apache/daffodil/section00/general/TestElementFormDefaultGeneral.scala
 
b/daffodil-test/src/test/scala/org/apache/daffodil/section00/general/TestElementFormDefaultGeneral.scala
index e5b5ffbcd..0c1de856e 100644
--- 
a/daffodil-test/src/test/scala/org/apache/daffodil/section00/general/TestElementFormDefaultGeneral.scala
+++ 
b/daffodil-test/src/test/scala/org/apache/daffodil/section00/general/TestElementFormDefaultGeneral.scala
@@ -43,6 +43,9 @@ class TestElementFormDefaultGeneral {
   @Test def test_delimOptPresentQualified02(): Unit = {
     runner.runOneTest("delimOptPresentQualified02")
   }
+  @Test def test_delimOptPresentQualified02_additionalByte(): Unit = {
+    runner.runOneTest("delimOptPresentQualified02_additionalByte")
+  }
   @Test def test_delimOptPresentQualified03(): Unit = {
     runner.runOneTest("delimOptPresentQualified03")
   }

Reply via email to