Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some XSpec for testing CI/CD #9

Merged
merged 26 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
f20161f
Mods to markdown XSLT; demo XSpec providing a pattern
wendellpiez Jan 2, 2024
78ec245
Making tests slightly more transparent / refining approaches
wendellpiez Jan 2, 2024
3146214
Pushing the capability boundary by including some iXML (not yet suppo…
wendellpiez Jan 18, 2024
540ae10
Excluding the bad XSpec from Maven 'run-xspec/test' XSpec run, pendin…
wendellpiez Jan 19, 2024
7aaee89
Readme improvements
wendellpiez Jan 19, 2024
cca704b
Corrected glitch in ixml demo
wendellpiez Jan 22, 2024
252a534
Adding XSpec-dev pipeline and scripting support for XSpec
wendellpiez Mar 27, 2024
3a3fc7c
Added scripting and 'make' infrastructure; XProc3 folder w/ Morgana a…
wendellpiez Mar 27, 2024
c870dd6
Adding the submodule directory now
wendellpiez Mar 27, 2024
8c41469
Updated readme.md
wendellpiez Mar 27, 2024
948f57e
Restoring 'target' exclusion to XSpec (we need it)
wendellpiez Mar 27, 2024
1cdeabe
Trying adjusted pom.xml
wendellpiez Mar 27, 2024
e82d800
Placating a jealous (and zealous) robot
wendellpiez Mar 27, 2024
eb11252
More integration/testing and cleanup
wendellpiez Mar 27, 2024
4cedf9b
demo Makefile in random-util showing an XSpec runtime
wendellpiez Mar 27, 2024
0a50d8d
Adjustment to draft CI/CD logic (not yet in place)
wendellpiez Apr 2, 2024
f17abc2
Pegging XSpec submodule to 9cdf371 - v2.3.2
wendellpiez Apr 2, 2024
ca78883
Moving submodule, with updated paths
wendellpiez Apr 2, 2024
d82180d
Some Makefile demonstration
wendellpiez Apr 2, 2024
cb21ea4
Mostly editorial corrections and cleanup
wendellpiez Apr 2, 2024
3120554
Some restoration work on scripts in directory-manifest, with demo run…
wendellpiez Apr 3, 2024
80fd48a
Adding exclusion rule for CI/CD testing
wendellpiez Apr 4, 2024
3b0ee9d
New Makefile logic bypasses bash scripting for resource management (w…
wendellpiez Apr 4, 2024
5175b3b
oops, deleted the wrong stuff there!
wendellpiez Apr 4, 2024
8257a47
Tightening testing and TESTING.md, with better demos
wendellpiez Apr 5, 2024
2ab78c7
Further editorial adjustments
wendellpiez Apr 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "support/xspec"]
path = lib/xspec
url = https://github.com/xspec/xspec.git
54 changes: 54 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
include common/make_common.mk

# We'd like to descend to each subdirectory (recursively) that has a makefile
# Makefile wildcard function does not support that, so we use the shell
# function with the find utility and examine each Makefile in a child dir
# relative to this one, excluding this one to use with the FOREACH macro.
dirs:=$(shell find '.' ! -wholename ./Makefile -name 'Makefile' -printf "%h\n")

# This enables project-level configuration. Each project's own Makefile
# can arrange its own testing accordingly, while making it easy to expose new tests to
# the CI/CD runtime, by using any of the targets provided for here.

# Make logic modeled after an example provided by NW: we are still learning

module_path:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
output_folder:=$(module_path)/test_output

# $folder can be passed in as folder=[folder]
folder?=.


# See Makefile configuration in project files for examples of how to set up calls to 'make'
# including wiring XSpec tests and wiring XSpec tests to these (top-level) targets


.PHONY: test
test: ## Run all tests
$(call FOREACH_MAKE,$@,$(dirs))


.PHONY: pre-checks
pre-checks: ## Run all "pre checks", enforcing validation contracts across input artifacts
$(call FOREACH_MAKE_OPTIONAL,$@,$(dirs))


.PHONY: smoke-test
smoke-test: ## Run all "smoke tests", establishing a baseline of sanity across the project
$(call FOREACH_MAKE_OPTIONAL,$@,$(dirs))


.PHONY: spec-test
spec-test: ## Run all "specification tests", validating an implementation against a spec
$(call FOREACH_MAKE_OPTIONAL,$@,$(dirs))


.PHONY: unit-test
unit-test: ## Run all unit tests (ci/cd)
$(call FOREACH_MAKE_OPTIONAL,$@,$(dirs))


.PHONY: clean
clean: ## Remove any generated test or build artifacts
rm -fr $(output_folder)/*
$(call FOREACH_MAKE_OPTIONAL,$@,$(dirs))
43 changes: 34 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,53 @@ This repository offers a library of XSLT stylesheets and pipelines supporting ge

It is motivated primarily by the need to make available to the community and public logic that we have coded for use in our projects, but that could (more or less easily) be refitted to uses elsewhere.

Most of the code here is not intended to be used standalone, but rather as imports (generally `xsl:import`) from external code. As documented per utility, however, demonstrations may be included to show how to use them, which can be executed independently of any other configuration. Additionally, some functionality has been unit tested (sometimes fairly exhaustively), with unit tests included.
The development model for the repository is to aim for a state of punctuated equilibrium, in which a stable code base remains unchanged functionally even while supporting ongoing development and innovation. Each project in this repository should be maintained and documented independently, with its own readme and testing documents. Thus the place to start with any project is the project itself.

To use these transformations a conformant XSLT 3.0 transformation engine is required such as [Saxon 11](https://saxonica.com/documentation11/documentation.xml) from Saxonica (see SourceForge for the free-to-use HE version), which is available on several platforms and sometimes bundled with commercial software. Outside that practical requirement, this library is free to use and open for contributions.
At the same time, the different projects will, over the long term, be able to borrow logic from one another to support testing, unit testing, and runtime interfaces supporting broader distribution.

Applications here for the most part assume inputs to be OSCAL XML, as distinct from OSCAL in other data formats such as JSON and YAML. Please convert your data first into XML before attempting to work further with these tools. XSLT-based data converters for OSCAL (capable of generating OSCAL XML from valid OSCAL JSON) are available in the [main repository](https://github.com/usnistgov/OSCAL/tree/main/xml/convert).

If there is interest in XSLT to support OSCAL JSON, YAML or other notations, please express this requirement to the developers.
To use these transformations a conformant XSLT 3.0 transformation engine is required such as [Saxon 12](https://saxonica.com/documentation12/documentation.xml) from Saxonica (see [Github](https://github.com/Saxonica/Saxon-HE/) or [Maven](https://central.sonatype.com/artifact/net.sf.saxon/Saxon-HE?smo=true) for the free-to-use HE version), which is available on several platforms and sometimes bundled with commercial software. Outside that practical requirement, this library is free to use and open for contributions.

### Project purpose and maturity

The [OSCAL project](https://pages.nist.gov/OSCAL) has published XSLT since 2018. Over this time it has grown in complexity, warranting a reorganization and refactoring of the development efforts that have supported it.

Current refactoring (2022) encapsulates XSLT functionality supporting OSCAL into two repositories, the [OSCAL XSLT](https://github.com/usnistgov/oscal-xslt) repository, and this one. This repository includes logic of general use (i.e., not specific to OSCAL use cases or implementation), and is kept kept separate in order to facilitate reuse of these offerings outside the OSCAL context, potentially (but not necessarily) as a git submodule.
Some of this code originates with the [OSCAL project](https://pages.nist.gov/OSCAL), which has published XSLT since 2018. Over this time it has grown in complexity and refactored into several supporting repositories, including this one.

Future development of this resource depends largely on uptake and engagement from users who find it valuable. If you have an interest in keeping this code base viable, please make your needs and ideas known to the developers. Demonstrations that take us further into features of XSLT 3 that are demonstrably useful, whether in functionality or architecture (e.g., packaging), are particularly welcome.

See the readme in each project to gauge its scope of application, approach to design, and level of testing. Several of the applications are also accompanied by test suites using the [XSpec XSLT Unit Testing framework](https://github.com/xspec/xspec/).

### Repository contents
## Repository contents

See the subdirectory list for projects and applications currently supported.

Additionally to the project folders are resources at the top level:


- `.github` - for Github CI/CD
- `common` - holds common `bash` scripting - utilities for reuse
- `lib` - contains submodules, dynamic resources and libraries (or scripts for downloading them)

## Running and building on applications

As a 4GL, XSLT is well suited for certain types of applications, as it is hoped this site demonstrates. The resources offered here can be used and adapted for many different platforms and runtimes. While an effort has been made to create no dependendencies on tooling that is costly, encumbering in any way, or hard to acquire, at the same time the applications and interfaces offered and described here should not be considered to be normative or necessary, but as examples for evaluation only.

## `make` support

This repository supports command-line access to its tools via `make`, configured in each folder (when supported) by a `Makefile` configuration.

From any directory, `make --help` from a `bash` command line will show scripted logic for that directory, if any is available.

Make tasks with certain target designations can be run under CI/CD - tbd

## CI/CD

Currently CI/CD is set to use an XProc configuration that runs all available XSpec instances.

It can be run locally on any platform with a configured Maven installation, using the `test` target:

> mvn test

Scripts for more granular or targeted application of XSpec under CI/CD are also available in the [XSpec-dev](xspec-dev/) application, requiring `bash` and `make`.

### Rights and license

See the [LICENSE.md](LICENSE.md) file. As work product of a Bureau of the Department of Commerce (U.S. Government), or of volunteers working in support of our projects, code in this repository is in the public domain unless specifically marked otherwise.
Expand Down
94 changes: 94 additions & 0 deletions TESTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Testing xslt3-functions

This repository is being developed incrementally, in stages. While never ruling out a complete overhaul of organization and resources, we intend most changes to be isolated within projects, when they do not take the form of entirely new work. Accordingly, we need a testing model that is both robust and stable enough to be reliable, while also adaptable enough so that any contributor working on a project can use as much or as little of the generalized infrastructure as seems appropriate.

Testing of utilities offered in this repository includes both informal, interactive testing per project, and in some projects, formal automated testing of XSLT functionalities using [XSpec](https://github.com/xspec/xspec). Over time it is our hope that all testing will improve by virtue of each project's being able to emulate the successful practice that is developed in any other.

To ensure the integrity of our tests we rely on code review as well as other means.

The full testing stack (all XSpec files unless excluded) will be run on all PRs before any git merge; the same tests should first be run off line to help reduce noise in the commit history.

## Dependencies

- [Apache Maven](https://maven.apache.org/) must be [installed and available on your path](https://maven.apache.org/install.html), supported with a JDK.

<small>We give no link for Java Development Kit installation options are available and anything that works with Maven is fine.</small>

*Further options*: Additionally, at developers' discretion, projects in the repo may deploy scripts supporting runtimes in GNU `bash` syntax, Windows batch scripts or others considered appropriate. These tests and runtimes are not currently provided for under CI/CD, but they are nonetheless encouraged in the spirit of *more testing*. See the testing.md or readme.md documentation of any project for more details.

## Guidelines (tl/dr)

- Write unit tests for XSLT using [XSpec](https://github.com/xspec/xspec). The repository already includes some excellent XSpec to study for examples of its use.
- Save your XSpec file as `*.xspec` to be found by the test runner. Place it in a directory named `xspec/pending` (in your project) if you actually wish to hide it.
- In development, you can run the tests in an IDE (make inquiries or search for more details).
- The CI/CD test run is initiated using `mvn tests` from the top. This will execute all XSpec files in the repository that are not excluded by the configuration.
- In the test run, any failure of any XSpec test in an executed XSpec that is not marked as 'pending' is considered a blocking error.
- For more granular testing or testing beyond XSpec, consider using `bash` and `make` as illustrated in project directories such as [`xspec-dev`](xspec-dev/)

## Details

### Verify your JDK installation

If your JDK is installed and configured (JAVA_HOME) you should be able to execute

```
javac --version
```

And a version of the Java Compiler is announced.

If you run into trouble, see Maven documentation for JDK requirements.

### Verify your Maven installation

Once it is installed and on the system path, try

```
> mvn --help
```

A working Maven installation will tell you about itself.


### Repository CI/CD setup

[Under CI/CD we are currently configured](.github/workflows/maven.yml) to run the 'tests target defined in the top-level [Maven configuration pom.xml](pom.xml) file.

With Maven and a JDK installed and the command prompt open at the repository root, run all these tests using

```
> mvn tests
```

The configuration executes *all XSpec test suites in the repository*, unless subject to exclusion rules given in the pom.xml.

An exclusion for files matching `**/xspec/pending/**` permits developers to create an `xspec/pending` directory at any time and place XSpec files there that will *not* be run under CI/CD.

### More about XSpec

[XSpec](https://github.com/xspec/xspec) is a unit testing framework for XSLT supporting [behavior-driven development](https://github.com/xspec/xspec/wiki/What-is-XSpec). It was originated by Jeni Tennison and has been developed as a community-based project since 2016.

### More about more options

Projects in this repository also take advantage of scripts and the GNU **make** build utility to provide testing (or other) runtimes. Because they are run unless specifically designed not to, any XSpec files in place will be executed in CI/CD even while other testing utilities and harnesses can also use (or ignore) them.

In particular, the `xspec-dev` project provides scripts that make its (XSpec-oriented) functionalities available to developers and quality engineers as black box utilities (i.e., no "XML" anywhere, just files) for running tests in more complex configurations.

For simplicity and to reduce the burden on all contributors to this repository, these functions are not being used in the repository CI/CD - while other repositories using this one as a submodule may do so.

At the same time, contributors with `bash` and `make` support on their systems may wish to try

```
> make help
```

from within any directory containing a `Makefile`.

For convenience, the top level file configures a recursive descent into the file system, so all testing configured under `make` (not the same as CI/CD) can be run using

```
> make tests
```

Note to developers: the `make` configuration has its [own pom.xml](common/pom.xml) file in the [common directory](common/).

59 changes: 59 additions & 0 deletions common/make_common.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Common makefile utilities for the metaschema-xslt project
# Note: any makefile including this file will have the following side-effects:
# 1. The SHELL will be set to bash.
# 2. A "help" target will be added. If the include statement is at the top the
# default target will become "help" unless overridden with .DEFAULT_GOAL.
# 3. The environment will be populated with the variables seen below

# Gratefully adapted from an original by NW

SHELL:=/usr/bin/env bash

.PHONY: help
# Run "make" or "make help" to get a list of user targets
# Adapted from https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
# To include a target in the help text, follow the following format:
# <target(s)>: [dependencies] ## Comment
help: ## Show this help message
@grep --no-filename -E '^[a-zA-Z_-]+:.*?##.*$$' $(MAKEFILE_LIST) | awk 'BEGIN { \
FS = ":.*?## "; \
printf "\033[1m%-30s\033[0m %s\n", "TARGET", "DESCRIPTION" \
} \
{ printf "\033[32m%-30s\033[0m %s\n", $$1, $$2 }'

# The path to the Maven POM to use
pom_path:=./pom.xml

define EXEC_MAVEN
mvn --quiet -f "${pom_path}" exec:java \
-Dexec.mainClass="$1" \
-Dexec.args="$2"
endef

# XML Calabash helper macro
define EXEC_CALABASH
$(call EXEC_MAVEN,com.xmlcalabash.drivers.Main,$1)
endef

# Saxon helper macro
define EXEC_SAXON
$(call EXEC_MAVEN,net.sf.saxon.Transform,$1)
endef

define FOREACH
for $1 in $2; do {\
$3 ;\
} done
endef

# Run a Makefile target for each directory, requiring each directory to have a given target
define FOREACH_MAKE
@echo Running makefile target \'$1\' on all subdirectory makefiles
@$(call FOREACH,dir,$2,$(MAKE) -C $$dir $1)
endef

# Run a Makefile target for each directory, skipping directories whose Makefile does not contain a rule
define FOREACH_MAKE_OPTIONAL
@echo Running makefile target \'$1\' on all subdirectory makefiles that contain the rule
@$(call FOREACH,dir,$2,$(MAKE) -C $$dir -n $1 &> /dev/null && $(MAKE) -C $$dir $1 || echo "Makefile target '$1' failed or does not exist in "$$dir". Continuing...")
endef
90 changes: 90 additions & 0 deletions common/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<project>
<modelVersion>4.0.0</modelVersion>

<groupId>gov.nist.secauto.oscal.tools.core</groupId>
<artifactId>java-xml-xslt-support</artifactId>
<version>1.0.0</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<packaging>pom</packaging>

<!--
Required for transitive deps of xmlcalabash. If not specified, expect
the following errors:

The following artifacts could not be resolved: org.restlet.jee:org.restlet:jar:2.2.2 ...

20221230 Workaround: TLS certificates for the restlet.org maven service
expired, see the following GitHub issue for details and status updates
about workaround alternative service and target or maven.restlet.org
redirect. https://github.com/restlet/restlet-framework-java/issues/1390
-->
<repositories>
<repository>
<id>Maven Central</id>
<url>https://repo1.maven.org/maven2</url>
</repository>
<repository>
<id>maven.restlet.org</id>
<name>maven.restlet.org</name>
<url>https://maven.restlet.talend.com</url>
</repository>
</repositories>

<dependencies>
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
<version>11.5</version>
wendellpiez marked this conversation as resolved.
Show resolved Hide resolved
</dependency>
<dependency>
<groupId>com.xmlcalabash</groupId>
<artifactId>xmlcalabash</artifactId>
<version>1.5.3-110</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.nineml/coffeegrinder -->
<dependency>
<groupId>org.nineml</groupId>
<artifactId>coffeegrinder</artifactId>
<version>3.2.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.nineml</groupId>
<artifactId>coffeefilter</artifactId>
<version>3.2.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.nineml</groupId>
<artifactId>coffeesacks</artifactId>
<version>3.2.6</version>
<scope>runtime</scope>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration/>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Loading