From 634f7299be6303a892f8ee7aba7e619d11164a1f Mon Sep 17 00:00:00 2001 From: Keshav Nangare Date: Tue, 10 Sep 2019 14:52:54 +0530 Subject: [PATCH] Invoke test suite using REST API interface. #33 --- pom.xml | 50 ++++--- src/assembly/aio.xml | 20 +++ src/assembly/deps.xml | 25 ++++ .../java/org/opengis/cite/csw20/CSW20.java | 17 +++ .../org/opengis/cite/csw20/CtlController.java | 127 ++++++++++++++++++ .../opengis/cite/csw20/TestRunArguments.java | 85 ++++++++++++ src/main/javadoc/index.html | 10 ++ src/main/javadoc/overview.html | 92 +++++++++++++ ....occamlab.te.spi.jaxrs.TestSuiteController | 1 + .../org/opengis/cite/csw20/ets.properties | 4 + .../org/opengis/cite/csw20/test-run-props.xml | 6 + src/main/scripts/ctl/main-auto.xml | 107 +++++++++++++++ 12 files changed, 529 insertions(+), 15 deletions(-) create mode 100644 src/assembly/aio.xml create mode 100644 src/assembly/deps.xml create mode 100644 src/main/java/org/opengis/cite/csw20/CSW20.java create mode 100644 src/main/java/org/opengis/cite/csw20/CtlController.java create mode 100644 src/main/java/org/opengis/cite/csw20/TestRunArguments.java create mode 100644 src/main/javadoc/index.html create mode 100644 src/main/javadoc/overview.html create mode 100644 src/main/resources/META-INF/services/com.occamlab.te.spi.jaxrs.TestSuiteController create mode 100644 src/main/resources/org/opengis/cite/csw20/ets.properties create mode 100644 src/main/resources/org/opengis/cite/csw20/test-run-props.xml create mode 100644 src/main/scripts/ctl/main-auto.xml diff --git a/pom.xml b/pom.xml index bfc6ea0..43629a0 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,6 @@ ets-csw20 org.opengis.cite 1.19-SNAPSHOT - jar Conformance Test Suite - CSW 2.0.2 @@ -54,7 +53,7 @@ csw 2.0.2 UTF-8 - 4.10 + 5.4 @@ -94,13 +93,18 @@ org.apache.maven.plugins maven-jar-plugin - 2.5 - - - default-jar - disable - - + 3.0.2 + + + + true + + + ${maven.build.timestamp} + ${buildNumber} + + + org.apache.maven.plugins @@ -155,7 +159,9 @@ - src/assembly/ctl.xml + ${basedir}/src/assembly/ctl.xml + ${basedir}/src/assembly/aio.xml + ${basedir}/src/assembly/deps.xml @@ -188,10 +194,10 @@ org.apache.maven.plugins maven-compiler-plugin - 3.2 + 3.6.0 - 1.7 - 1.7 + 1.8 + 1.8 @@ -250,6 +256,21 @@ + + + ${basedir}/src/main/resources + true + + + ${basedir}/src/main/scripts + ${ets-code}/${spec-version} + + + src/main/javadoc + true + doc/${ets-code}/${project.version} + + ${basedir}/src/test/resources @@ -280,9 +301,8 @@ org.opengis.cite.teamengine - teamengine-core + teamengine-spi-ctl ${teamengine.version} - test junit diff --git a/src/assembly/aio.xml b/src/assembly/aio.xml new file mode 100644 index 0000000..c5e5c72 --- /dev/null +++ b/src/assembly/aio.xml @@ -0,0 +1,20 @@ + + + + aio + + jar + + false + + + / + true + true + runtime + + com.sun.jersey:jersey-server + + + + diff --git a/src/assembly/deps.xml b/src/assembly/deps.xml new file mode 100644 index 0000000..b1ab6b2 --- /dev/null +++ b/src/assembly/deps.xml @@ -0,0 +1,25 @@ + + + deps + + zip + tar.gz + + false + + + true + + org.opengis.cite.teamengine:teamengine-spi-ctl + + / + false + runtime + true + true + + + diff --git a/src/main/java/org/opengis/cite/csw20/CSW20.java b/src/main/java/org/opengis/cite/csw20/CSW20.java new file mode 100644 index 0000000..27cbd01 --- /dev/null +++ b/src/main/java/org/opengis/cite/csw20/CSW20.java @@ -0,0 +1,17 @@ +package org.opengis.cite.csw20; + +/** + * Contains various constants defined in the CSW 2.0.2 specification, such as test + * run parameters. + * + * @see "OGC 07-006r1: OGC Catalog Service for the Web Implementation Specification, Version 2.0.2" + */ +public class CSW20 { + + private CSW20() { + } + + /** Supplies reference to CSW capabilities document (URI). */ + public static final String CAPABILITIES_URL = "capabilities.url"; + +} diff --git a/src/main/java/org/opengis/cite/csw20/CtlController.java b/src/main/java/org/opengis/cite/csw20/CtlController.java new file mode 100644 index 0000000..753e4ac --- /dev/null +++ b/src/main/java/org/opengis/cite/csw20/CtlController.java @@ -0,0 +1,127 @@ +package org.opengis.cite.csw20; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Source; + +import org.w3c.dom.Document; + +import com.occamlab.te.SetupOptions; +import com.occamlab.te.spi.ctl.CtlExecutor; +import com.occamlab.te.spi.executors.TestRunExecutor; +import com.occamlab.te.spi.jaxrs.TestSuiteController; + +public class CtlController implements TestSuiteController { + + private TestRunExecutor executor; + private Properties etsProperties = new Properties(); + + /** + * Constructs a controller object for this test suite. The location of the + * main CTL script is read from the "main-script" property in the + * ets.properties file (a classpath resource). + */ + public CtlController() { + SetupOptions setupOpts = new SetupOptions(); + try (InputStream is = getClass().getResourceAsStream("ets.properties")) { + this.etsProperties.load(is); + String mainScriptPath = etsProperties.getProperty("main-script"); + File ctlFile = findScriptFile(URI.create(mainScriptPath)); + setupOpts.addSource(ctlFile); + this.executor = new CtlExecutor(setupOpts); + } catch (IOException ex) { + Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Failed to initialize CtlController. {0}", + ex.getMessage()); + } + } + + /** + * A convenience method for running the test suite using a command-line + * interface. + * + * @param args + * Test run arguments (optional). The first argument must refer + * to a local XML properties file containing the expected set of + * test run arguments. If no argument is supplied, the file + * located at ${user.home}/test-run-props.xml will be used. + * @throws Exception + * If an error errors during the test run. + */ + public static void main(String[] args) throws Exception { + File propsFile; + if (args.length == 0) { + propsFile = new File(System.getProperty("user.home"), "test-run-props.xml"); + } else { + String xmlProps = args[0]; + propsFile = (xmlProps.startsWith("file:")) ? new File(URI.create(xmlProps)) : new File(xmlProps); + } + if (!propsFile.isFile()) { + throw new IllegalArgumentException("Test run arguments not found at " + propsFile); + } + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document testRunArgs = db.parse(propsFile); + TestSuiteController controller = new CtlController(); + Source results = controller.doTestRun(testRunArgs); + Logger.getLogger(CtlController.class.getName()).log(Level.INFO, "Test results: {0}", results.getSystemId()); + } + + public String getCode() { + return etsProperties.getProperty("ets-code"); + } + + public String getVersion() { + return etsProperties.getProperty("ets-version"); + } + + public String getTitle() { + return etsProperties.getProperty("ets-title"); + } + + public Source doTestRun(Document testRunArgs) throws Exception { + Properties validArgs = TestRunArguments.validateArguments(testRunArgs); + + return executor.execute(TestRunArguments.propertiesAsDocument(validArgs)); + } + + /** + * Creates a File from the given URI reference. If the URI is not absolute, + * is is resolved against the location of the TE_BASE/scripts directory; if + * a file does not exist at this location the URI is assumed to be a + * classpath reference. + * + * @param uri + * An absolute or relative URI. + * @return A File object, or null if one could not be created. + */ + final File findScriptFile(URI uri) { + File ctlFile = null; + File baseDir = SetupOptions.getBaseConfigDirectory(); + if (!uri.isAbsolute()) { + File scriptsDir = new File(baseDir, "scripts"); + ctlFile = new File(scriptsDir, uri.getPath()); + } + if (null == ctlFile || !ctlFile.isFile()) { + URL resource = getClass().getResource(uri.getPath()); + try { + ctlFile = new File(resource.toURI()); + } catch (URISyntaxException ex) { + Logger.getLogger(getClass().getName()).log(Level.INFO, "Invalid URI: {0}", ex); + } + } + Logger.getLogger(getClass().getName()).log(Level.CONFIG, "Created File object: {0}", ctlFile); + return ctlFile; + } + +} + \ No newline at end of file diff --git a/src/main/java/org/opengis/cite/csw20/TestRunArguments.java b/src/main/java/org/opengis/cite/csw20/TestRunArguments.java new file mode 100644 index 0000000..4a9f878 --- /dev/null +++ b/src/main/java/org/opengis/cite/csw20/TestRunArguments.java @@ -0,0 +1,85 @@ +package org.opengis.cite.csw20; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/** + * Provides utility methods that assist with the handling of test run arguments. + */ +public class TestRunArguments { + + /** + * Validates the given test run arguments. An + * IllegalArgumentException is thrown if a required argument is + * missing or invalid. The recognized arguments are listed below. + *
    + *
  • {@value org.opengis.cite.csw20.CSW20#CAPABILITIES_URL} + * (required)
  • + *
+ * + * @param testRunArgs + * A Document containing a set of XML properties; each entry + * (key-value pair) is a test run argument. + * @return A valid set of test run arguments. + */ + public static Properties validateArguments(Document testRunArgs) { + NodeList entries = testRunArgs.getDocumentElement().getElementsByTagName("entry"); + if (entries.getLength() == 0) { + throw new IllegalArgumentException("No test run arguments."); + } + // load defaults? + Properties args = new Properties(); + for (int i = 0; i < entries.getLength(); i++) { + Element entry = (Element) entries.item(i); + args.setProperty(entry.getAttribute("key"), entry.getTextContent().trim()); + } + String capabilitiesUrl = args.getProperty(CSW20.CAPABILITIES_URL); + try { + URI uriRef = new URI(capabilitiesUrl); + if (!uriRef.isAbsolute()) { + throw new IllegalArgumentException(String.format("Not an absolute URI: %s", uriRef)); + } + } catch (URISyntaxException e1) { + throw new IllegalArgumentException(String.format("Invalid URI reference: %s", capabilitiesUrl)); + } catch (NullPointerException e2) { + throw new IllegalArgumentException(String.format("Missing required argument: %s", CSW20.CAPABILITIES_URL)); + } + return args; + } + + /** + * Creates a document that contains a simple XML representation of the given + * set of properties. + * + * @param props + * A set of properties (key-value pairs). + * @return A Document node, wherein each property is represented by an + * entry[@key] element. + */ + public static Document propertiesAsDocument(Properties props) { + Document doc = null; + try { + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + props.storeToXML(outStream, "Test run arguments"); + DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + doc = builder.parse(new ByteArrayInputStream(outStream.toByteArray())); + } catch (Exception e) { // very unlikely + Logger.getLogger(TestRunArguments.class.getName()).log(Level.WARNING, "Failed to create Document node. {0}", + e.getMessage()); + } + return doc; + } + +} diff --git a/src/main/javadoc/index.html b/src/main/javadoc/index.html new file mode 100644 index 0000000..0204851 --- /dev/null +++ b/src/main/javadoc/index.html @@ -0,0 +1,10 @@ + + + + + + + </head> + <body> + </body> +</html> diff --git a/src/main/javadoc/overview.html b/src/main/javadoc/overview.html new file mode 100644 index 0000000..1b362eb --- /dev/null +++ b/src/main/javadoc/overview.html @@ -0,0 +1,92 @@ +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> + <head> + <title>CSW 2.0.2 Conformance Test Suite + + + + +

CSW 2.0.2 Conformance Test Suite

+

Verifies that OGC Catalog Service for the Web (CSW) 2.0.2 Test-Suite implementation is based on the following OGC specifications:

+
    +
  • OGC Catalogue Services Specification - 2.0.2 [ OGC 07-006r1]
  • +
+ +

The test run arguments are summarized in the following table. The Obligation + descriptor can have the following values: M (mandatory), O (optional), or C + (conditional).

+ + + + + + + + + + + + + + + + + + + +
Test run arguments
NameValue domainObligationDescription
capabilities.urlURIMAn absolute URI that refers to an XML representation of the service capabilities document. + This document does not need to be obtained from the service under test (SUT), but it must + describe the implementation under test (IUT). Ampersand ('&') characters appearing within + a query parameter value must be percent-encoded as %26.
+ + + diff --git a/src/main/resources/META-INF/services/com.occamlab.te.spi.jaxrs.TestSuiteController b/src/main/resources/META-INF/services/com.occamlab.te.spi.jaxrs.TestSuiteController new file mode 100644 index 0000000..c386443 --- /dev/null +++ b/src/main/resources/META-INF/services/com.occamlab.te.spi.jaxrs.TestSuiteController @@ -0,0 +1 @@ +org.opengis.cite.csw20.CtlController \ No newline at end of file diff --git a/src/main/resources/org/opengis/cite/csw20/ets.properties b/src/main/resources/org/opengis/cite/csw20/ets.properties new file mode 100644 index 0000000..f7fd30d --- /dev/null +++ b/src/main/resources/org/opengis/cite/csw20/ets.properties @@ -0,0 +1,4 @@ +ets-title = ${project.name} +ets-version = ${project.version} +ets-code = ${ets-code} +main-script = /${ets-code}/${spec-version}/ctl/main-auto.xml diff --git a/src/main/resources/org/opengis/cite/csw20/test-run-props.xml b/src/main/resources/org/opengis/cite/csw20/test-run-props.xml new file mode 100644 index 0000000..b37c7ba --- /dev/null +++ b/src/main/resources/org/opengis/cite/csw20/test-run-props.xml @@ -0,0 +1,6 @@ + + + + Test run arguments for ets-csw20 + + diff --git a/src/main/scripts/ctl/main-auto.xml b/src/main/scripts/ctl/main-auto.xml new file mode 100644 index 0000000..197a306 --- /dev/null +++ b/src/main/scripts/ctl/main-auto.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + CSW 2.0.2 Compliance Test Suite + + Verifies a CSW 2.0.2 catalogue implementation against all applicable + abstract test suites. No specific CSW application profile is presumed. + These tests are intended to be incorporated into profile-specific test + suites. + + data/csw-2.0.2-data.zip + docs/csw/2.0.2/ + csw:Main-auto + + + + + The implementation under test minimally conforms to the CSW + part (Clause 10) of Catalogue 2.0.2 (OGC 07-006r1). + + + + + + + GET + + + + + + [FAILURE] Did not obtain a csw:Capabilities document! Skipping remaining tests. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Confirm that the IUT is ready to undergo testing. + + + Check all of the following conditions: + (1) the service is available; + (2) the capabilities document is valid; + (3) test data have been loaded. + If any of these checks fail, the test run is aborted. + + + + Check that the capabilities document is valid against + the schema. + + + /sch/csw/2.0.2/Capabilities.sch + RequiredElementsPhase + + + + + + + + +