Scripts #
Tools for testing orchard, drawing trees and publishing the documentation. Run them from the repository root. Each script also describes itself in the comment at its top.
| script | what it does | needs |
|---|---|---|
| run-tests.sh | runs the GoogleTest and Ztest suites | CMake, Ninja, GoogleTest; a Zephyr tree for Ztest |
| orchard_tree.py | draws a tree file, checks it like the loader | Python 3, Graphviz for images |
| doxygen_orchard.py | Doxygen input filter for the docs pages | Python 3 |
| sphinx_orchard.py | Sphinx extension with an orchard-tree directive |
Sphinx |
| publish-docs.sh | commits the built docs to the docs branch |
bash, rsync; gophermap for the sitemap |
The containers in docker/ have everything the tests and the documentation need.
run-tests.sh #
scripts/run-tests.sh # both suites
scripts/run-tests.sh gtest # GoogleTest suite and the C++ example
scripts/run-tests.sh ztest # Ztest suite on native_sim
- gtest configures CMake with
-DORCHARD_BUILD_TESTS=ONinbuild/testsand runsctest. The suite in tests/gtest calls the C API from C++: every node type tick by tick (including the scenarios drawn in the docs), every loader error with its line and column, the builder, reporting, the POSIX port andorchard.hpp.ctestalso compiles the trees in tests/compile_fail, which must fail with a given error. The suite runs twice, once per clock width: with the host's default inbuild/tests, then 32-bit inbuild/tests-time32. - sanitize, clang and m32 run the same GoogleTest suite in other builds, only
when named: GCC with AddressSanitizer and UBSan (
build/tests-sanitize), Clang with warnings as errors (build/tests-clang), and 32-bit x86 with both clock widths (build/tests-m32,build/tests-m32-time64; GoogleTest is built from/usr/src/googletest, orGTEST_SOURCE_DIR). CI runs all three. - fuzz builds
tests/fuzzwith Clang, libFuzzer, ASan and UBSan, and runs it on the JSON loader forFUZZ_SECONDS(600). It starts from every tree file in the repository and tests/fuzz/json.dict; inputs that crash land inbuild/fuzz/crashes. Valid trees are also ticked, halted and printed. - boards builds, without running them,
examples/zephyr(both clock widths) andtests/ztestforrpi_pico, and both forstm32_min_dev@blue, an STM32F103C8 with 64 KB of flash and 20 KB of RAM, where theirboards/*.confselect-Oz. Warnings are errors; the builds are inbuild/boards. It needs the Zephyr SDK's ARM toolchain andZEPHYR_MODULESnamingcmsis_6,hal_rpi_picoandhal_stm32: theboardsstage of docker/tests has them.
fuzz and boards take minutes, so CI runs them, with ztest, once a week.
- ztest runs tests/ztest with Zephyr's twister on
native_sim/native/64, results inbuild/twister. It covers the Zephyr port, the runtime on the Zephyr kernel, andorchard.hppwith Zephyr's minimal C++ library, in two scenarios:orchard.ztestwith the default (64-bit) clock andorchard.ztest.time32withCONFIG_ORCHARD_TIME_32BIT. SetZEPHYR_BASEto a Zephyr tree with its Python requirements installed. It builds with the host compiler, so no Zephyr SDK is needed.
The script stops at the first suite that fails, with a non-zero exit status. In the container:
docker build -t orchard-tests docker/tests
docker run --rm -u "$(id -u):$(id -g)" -v "$PWD:/src" orchard-tests
orchard_tree.py #
scripts/orchard_tree.py tree.json -o tree.svg # or .png, .pdf, .dot
scripts/orchard_tree.py tree.json > tree.dot # DOT on stdout
scripts/orchard_tree.py tree.json --no-comments # leave out "comment" keys
Draws composites, actions, conditions and waits in different shapes and colours, with
children in tick order. It runs the loader's checks, so it also works as a lint: an
invalid file prints the error with the path of the node and exits with status 1. Nodes
with a "status" per tick are drawn once per tick, side by side, as in the figures of
Node types. See
Drawing a tree.
In SVG output every node also has a CSS class for its kind or status
(orchard-composite, orchard-success, ...), for HTML themes that replace Graphviz's
colours: the m.css docs style them in docs/mcss-figures.css.
doxygen_orchard.py #
Set as FILTER_PATTERNS in the Doxyfile, so every Markdown page goes through it before
Doxygen reads it. It replaces \orchardtree path "caption" lines with a figure of the
tree, and rewrites links that work in the repository but not in Doxygen's output (to a
section of another page, an example folder or an example file). For m.css, which writes
the HTML, it also turns links in headings into their text and remote images (the build
badge) into raw HTML. Lines in code blocks are left alone, and the line count is kept so
Doxygen's warnings point at the right line.
sphinx_orchard.py #
For projects documented with Sphinx. In conf.py:
sys.path.insert(0, "path/to/orchard/scripts")
extensions = ["sphinx_orchard"]
Then .. orchard-tree:: path/to/tree.json in a page, with :caption:, :align:,
:alt:, :name:, :class: and :no-comments:. The figure is drawn through
sphinx.ext.graphviz, so it works in HTML and LaTeX.
publish-docs.sh #
scripts/publish-docs.sh # commit public/ to the docs branch
scripts/publish-docs.sh --push # and push it
Build the documentation first (docs/99_index.md). The script copies
public/ to latest/ on the docs branch, and also to vX.Y.Z/ when the current
commit is exactly at that tag with no local changes. If gophermap is installed, it
also writes one sitemap.xml for the whole branch; without it, the sitemap is left as
it was.
| variable | default | meaning |
|---|---|---|
ORCHARD_DOCS_DIR |
../orchard-docs |
where the docs branch is checked out |
ORCHARD_DOCS_REMOTE |
bt_home |
remote to push to |
ORCHARD_DOCS_URL |
https://icpmoles.tngl.io/liborchard |
address the branch is served at, for the sitemap |