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")
}