Chronos is a utility tooling to enable fast re-building of OSS-Fuzz projects and analysis of projects' testing infrastructure. This is used by projects, e.g. OSS-Fuzz-gen to help speed up valuation processes during fuzzing harness generation.
At the core, Chronos relies on caching containers after project build, in order
to enable fast rebuilding of a project following minor patches, and also enable
running of the tests in a given project. To support this, Chronos creates a snapshot
of a the docker container given project post build completion. This means that all .o files, generated
configuations etc. persist in the docker container. These artifacts are then
leverage for future "replay builds" where only a minor part of the project has changed,
e.g. due to some patching on the project. This patching could be e.g. minor adjustments
to the fuzzing harness source code e.g. by oss-fuzz-gen.
As such, at the core of Chronos are cached containers that are generated by taking a snapshot of the container of a project post project build.
Chronos is focused on two features, rebuilding projects fast and running the tests of a given project.
The default route to validating Chronos is using the CLI available in infra/experimental/chronos/manager.py
Chronos enables rebuilding projects efficiently in contexts where only a small patch
needs to be evalualted in the target. This is achieved by running a replay build script
in the build container, similarly to how a regular build_fuzzers command would run, but
with the caveat that the replay build script only performs a subset of the operations
of the original build.sh.
The replay build scripts are constructed in two ways: manually or automatically.
Chronos support automated rebuilding. This is meant as a generic mechanism to enable Chronos support for projects by default. This is achieved by:
- Calling into a
replay_build.shscript during the building inside the container here - The
replay_build.shcalls intomake_build_replayable.py: here make_build_replayable.pyadjusts the build environment to wrap around common commands, to avoid performing a complete run ofbuild.sh: here.
The automated rebuilding works in combination with Ccache, in order to facilitate cachine of e.g. .o files.
This means that during rebuild mode as long as we have a cacche, we don't need to e.g. run configure again and will only have to
rebuild the changed source code.
replay_build.sh above, is simply just a wrapper script around build.sh that aims to enable
fast rebuilding of the project. This replay_build.sh can, however, be overwritten in the Dockerfile
of the project's builder image to support a custom approach to fast rebuilding. Two examples of this is php and ffmpeg.
Providing a manual replay_build.sh is likely more efficient at build time and can help speed up the process. Automated replay build scripts can also be erroneous.
The Chronos manager can use the manager.py to validate the validity of a
replay build for a given project:
python3 infra/experimental/chronos/manager.py check-test tinyobjloaderIf the above command fails for the relevant project, then the replay build feature does not work for the given project.
The second part of Chronos is a feature to enable running the tests of a given
project. This is done by way of a script run_tests.sh. Samples of
this script include jsonnet and tinyobjloader.
- The
run_tests.shmain task is to run the tests of a project and return0upon success and non-null otherwise. - The
run_tests.shscript must leave the main repository in the state as it was prior to the execution ofrun_tests.shrelative togit diff(or similar diff features of other version control systems).
The Chronos manager can use the manager.py to validate the validity of a
run_tests.sh script:
python3 infra/experimental/chronos/manager.py check-tests json-cAt the core of chronos are the two scripts replay_build.sh and run_tests.sh. We have a default
mechanism for replay_build.sh so it's not strictly necessary to have a custom one, although it will
likely improve speed and maybe correctness by providing one.
There are three stages of the Chronos workflow:
- The cached containers represent the state of a build container after a successful project build.
- The
replay_build.shis able to rebuild a given project from the state of a cached container. - The
run_tests.shscript is able to run the tests of a given project. This should be able to succeed following the running of areplay_build.sh.
The stages (2) and (3) must both support running without network connectivity.
Specifically, this means that the replay_build.sh must not do tasks e.g. fetch
dependencies, download corpus, or anything of this nature. Similarly, the run_tests.sh
must be able to operate completely in a closed network environment.
Chronos cached images are build daily, and pre-built images are available at:
us-central1-docker.pkg.dev/oss-fuzz/oss-fuzz-gen/<PROJECT>-ofg-cached-addressus-central1-docker.pkg.dev/oss-fuzz/oss-fuzz-gen/<PROJECT>-ofg-cached-coverage
They can be used as drop-in replacements for the usual gcr.io/oss-fuzz/<PROJECT> images.