Skip to main content

Build and test

Openflexo is built with Gradle, through a custom plugin that adds global tasks to the standard ones. Stray pom.xml files in some repositories are not the build. Prefer the global tasks to raw Gradle lifecycle tasks.

Tasks

Run them from the root of a repository, or of openflexo-dev to act on all the repositories you have included.

TaskWhat it does
./gradlew compilecompiles every module
./gradlew testruns the non-UI tests, headless (java.awt.headless=true), on 4 parallel forks
./gradlew uiTestruns only the UI tests, on a single fork; needs a display
./gradlew testAllruns test and uiTest
./gradlew cleancleans every module
./gradlew depreports the dependencies across modules
./gradlew tasksAlllists the tasks of every module
./gradlew sableccParsergenerates the parsers from the SableCC grammars

To run a single test, name its module and filter by class:

./gradlew :default-expression-language:test --tests '*TestExpression'

A green build does not mean the tests passed

test and uiTest are configured with ignoreFailures = true: BUILD SUCCESSFUL is printed even when tests fail. Read the summary box the build prints after each test task:

--------------------------------------------------------------------
| Results: SUCCESS (6 tests, 6 successes, 0 failures, 0 skipped) |
--------------------------------------------------------------------

A non-zero number of failures is a real failure, whatever the last line says. A continuous integration job must therefore inspect the test reports, not the exit status alone.

UI tests and headless tests

Tests are split by a JUnit category. A test that needs a display must be annotated @Category(org.openflexo.test.UITest.class): it is then excluded from test, which runs headless, and run by uiTest. A test that does not need one must not carry the category, or it never runs in test.

Generated parsers

Several projects generate a parser from a SableCC grammar in src/main/sablecc/*.sablecc: connie, openflexo-core (fml-parser and fml-cli) and a few technology adapters. The generated sources land in build/generated-sources/ and are neither committed nor edited: change the grammar, then regenerate. Run ./gradlew sableccParser before the first build of such a project, or before importing it in an IDE, and again after changing a grammar: it is the reliable way to have the parsers in place, and without them the classes the rest of the code needs are missing.

Not everything under a parser/ directory is generated: the factories and analyzers committed there are hand-written code over the generated syntax tree, and they are yours to edit.

Java version

Openflexo 2.99 is built and run with Java 8: the core still uses java.xml.bind, removed from the JDK in version 11, so compilation fails on 11 and 17. This limit disappears with 3.0, which requires Java 17 or later (see Component versions).

Versions and dependencies

Dependencies between Openflexo components are declared with helpers of the build plugin (connie(), pamela(), flexoUtils(), one xxxConnector() per technology adapter…), never with a literal group:name:version. The version of every component is defined in one place, the buildconfig of openflexo-buildplugin: bumping a version means editing that map, not the build.gradle files that use it. A hard-coded -SNAPSHOT in a build.gradle would make a release depend silently on a snapshot.

Adding a technology adapter means adding its helper to the build plugin, which must then be published before a repository that uses the helper can be built on the continuous integration server; the local composite build hides that ordering.