Skip to content

Commit d3d6772

Browse files
adjust documentation
Signed-off-by: David Korczynski <david@adalogics.com>
1 parent e338a8c commit d3d6772

File tree

1 file changed

+56
-77
lines changed

1 file changed

+56
-77
lines changed

infra/experimental/chronos/README.md

Lines changed: 56 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,29 @@ and analysis of projects' testing infrastructure. This is used by projects,
55
e.g. [OSS-Fuzz-gen](https://github.com/google/oss-fuzz-gen) to help speed up
66
valuation processes during fuzzing harness generation.
77

8-
Chronos is focused on two features, rebuilding projects fast and running the tests of a given project.
8+
At the core, Chronos relies on caching containers after project build, in order
9+
to enable fast rebuilding of a project following minor patches, and also enable
10+
running of the tests in a given project. To support this, Chronos creates a snapshot
11+
of a the docker container given project post build completion. This means that all `.o` files, generated
12+
configuations etc. persist in the docker container. These artifacts are then
13+
leverage for future "replay builds" where only a minor part of the project has changed,
14+
e.g. due to some patching on the project. This patching could be e.g. minor adjustments
15+
to the fuzzing harness source code e.g. by [oss-fuzz-gen](https://github.com/google/oss-fuzz-gen).
916

10-
## Rebuilding projects fast
17+
As such, at the core of Chronos are cached containers that are generated by taking a
18+
snapshot of the container of a project post project build.
19+
20+
Chronos is focused on two features, rebuilding projects fast and running the
21+
tests of a given project.
22+
23+
24+
## Chronos features: fast rebuilding and running the tests of a project
25+
26+
### CLI interface for Chronos
27+
28+
The default route to validating Chronos is using the CLI available in `infra/experimental/chronos/manager.py`
29+
30+
### Chronos feature: Fast rebuilding
1131

1232
Chronos enables rebuilding projects efficiently in contexts where only a small patch
1333
needs to be evalualted in the target. This is achieved by running a replay build script
@@ -17,24 +37,28 @@ of the original `build.sh`.
1737

1838
The replay build scripts are constructed in two ways: manually or automatically.
1939

20-
### Automated rebuilds
40+
#### Option 1: Automated rebuilds
2141

22-
Chronos support automated rebuilding by:
42+
Chronos support automated rebuilding. This is meant as a generic mechanism to enable Chronos support for projects by default. This is achieved by:
2343

2444
1. Calling into a `replay_build.sh` script during the building inside the container [here](https://github.com/google/oss-fuzz/blob/206656447b213fb04901d15122692d8dd4d45312/infra/base-images/base-builder/compile#L292-L296)
2545
2. The `replay_build.sh` calls into `make_build_replayable.py`: [here](https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/replay_build.sh)
2646
3. `make_build_replayable.py` adjusts the build environment to wrap around common commands, to avoid performing a complete run of `build.sh`: [here](https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/make_build_replayable.py).
2747

28-
### Manually provided replay builds
48+
The automated rebuilding works in combination with [Ccache](https://ccache.dev/), in order to facilitate cachine of e.g. `.o` files.
49+
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
50+
rebuild the changed source code.
51+
52+
#### Option 2: Manually provided replay builds
2953

3054
`replay_build.sh` above, is simply just a wrapper script around `build.sh` that aims to enable
3155
fast rebuilding of the project. This `replay_build.sh` can, however, be overwritten in the Dockerfile
32-
of the project's builder image. Examples of this is [php](https://github.com/google/oss-fuzz/blob/206656447b213fb04901d15122692d8dd4d45312/projects/php/replay_build.sh#L1) and [ffmpeg](https://github.com/google/oss-fuzz/blob/master/projects/ffmpeg/replay_build.sh#L1).
56+
of the project's builder image to support a custom approach to fast rebuilding. Two examples of this is [php](https://github.com/google/oss-fuzz/blob/206656447b213fb04901d15122692d8dd4d45312/projects/php/replay_build.sh#L1) and [ffmpeg](https://github.com/google/oss-fuzz/blob/master/projects/ffmpeg/replay_build.sh#L1).
3357

3458
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.
3559

3660

37-
### Testing the validity of a replay build
61+
#### Testing the validity of a replay build
3862

3963
The Chronos manager can use the `manager.py` to validate the validity of a
4064
replay build for a given project:
@@ -46,96 +70,51 @@ python3 infra/experimental/chronos/manager.py check-test tinyobjloader
4670
If the above command fails for the relevant project, then the replay build feature
4771
does not work for the given project.
4872

49-
## Running tests of a project
73+
### Chronos feature: Running tests of a project
5074

5175
The second part of Chronos is a feature to enable running the tests of a given
5276
project. This is done by way of a script `run_tests.sh`. Samples of
5377
this script include [jsonnet](https://github.com/google/oss-fuzz/blob/master/projects/jsonnet/run_tests.sh#L1) and [tinyobjloader](https://github.com/google/oss-fuzz/blob/master/projects/tinyobjloader/run_tests.sh#L1).
5478

5579

56-
### Testing the validity of run_tests.sh
80+
#### Run tests constraints
81+
82+
1. The `run_tests.sh` main task is to run the tests of a project and return `0` upon success and non-null otherwise.
83+
2. The `run_tests.sh` script must leave the main repository in the state as it was prior to the execution of `run_tests.sh` relative to `git diff` (or similar diff features of other version control systems).
84+
85+
#### Testing the validity of run_tests.sh
5786

5887
The Chronos manager can use the `manager.py` to validate the validity of a
5988
`run_tests.sh` script:
6089

6190
```sh
62-
python3 infra/experimental/chronos/manager.py
91+
python3 infra/experimental/chronos/manager.py check-tests json-c
6392
```
6493

6594

66-
**Running tests of a project**
67-
68-
## Pre-built images.
69-
70-
Daily pre-built images are available at:
71-
72-
- `us-central1-docker.pkg.dev/oss-fuzz/oss-fuzz-gen/<PROJECT>-ofg-cached-address`
73-
- `us-central1-docker.pkg.dev/oss-fuzz/oss-fuzz-gen/<PROJECT>-ofg-cached-coverage`
74-
75-
They can be used as drop-in replacements for the usual `gcr.io/oss-fuzz/<PROJECT>` images.
76-
77-
These images are generated in 2 ways:
78-
- (Preferred) [Generate](https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/bash_parser.py)
79-
a replay build script that can be re-run alongside existing build artifacts,
80-
leveraging existing build system mechanisms to avoid rebuilding (e.g. running
81-
`make` twice should not actually rebuild everything). This is error-prone, so
82-
we validate the script works by running it.
83-
- (Fallback, if the replay build script didn't work). We leverage
84-
[ccache](https://ccache.dev/), to provide a compiler cache. This is often not
85-
as fast as the replay build script, because some project builds spend
86-
significant time doing non-compiler tasks (e.g. checking out submodules,
87-
running configure scripts).
88-
89-
Note: this mechanism does not work for every single OSS-Fuzz project today. The
90-
resulting image may either:
91-
- Not provide much performance improvement compared with a normal image, or
92-
- Not exist at all (if neither approach worked).
93-
94-
Stats from a recent run: <https://gist.github.com/oliverchang/abaf3a1106a2b923c0ac3a577410aaaa>
95-
(Feb 3 2025).
96-
97-
## Usage locally
98-
99-
**Example 1: htslib**
95+
### Constraints imposed on replay_build.sh and run_tests.sh
10096

101-
From the OSS-Fuzz root
97+
At the core of chronos are the two scripts `replay_build.sh` and `run_tests.sh`. We have a default
98+
mechanism for `replay_build.sh` so it's not strictly necessary to have a custom one, although it will
99+
likely improve speed and maybe correctness by providing one.
102100

103-
```sh
104-
$ RUN_ALL=1 ./infra/experimental/chronos/build_cache_local.sh htslib c address
105-
...
106-
...
107-
Vanilla compile time:
108-
17
109-
Replay worked
110-
Replay compile time:
111-
2
112-
Ccache compile time:
113-
9
114-
```
101+
There are three stages of the Chronos workflow:
115102

103+
1. The cached containers represent the state of a build container after a successful project build.
104+
2. The `replay_build.sh` is able to rebuild a given project from the state of a cached container.
105+
3. The `run_tests.sh` script is able to run the tests of a given project. This should be able to succeed following the running of a `replay_build.sh`.
116106

117-
## Check tests
107+
The stages (2) and (3) must both support running without network connectivity.
108+
Specifically, this means that the `replay_build.sh` must not do tasks e.g. fetch
109+
dependencies, download corpus, or anything of this nature. Similarly, the `run_tests.sh`
110+
must be able to operate completely in a closed network environment.
118111

119-
Another feature of Chronos is the ability to run tests in a replayed build.
120-
This requires `run_tests.sh` to be available in the cached image at
121-
`$SRC/run_tests.sh`.
122112

123-
Sample running:
113+
## Pre-built images.
124114

125-
```
126-
$ git clone https://github.com/google/oss-fuzz
127-
$ cd oss-fuzz
128-
$ ./infra/experimental/chronos/check_tests.sh jsonnet
129-
...
130-
...
131-
100% tests passed, 0 tests failed out of 10
132-
133-
Total Test time (real) = 119.80 sec
134-
```
115+
Chronos cached images are build daily, and pre-built images are available at:
135116

136-
In order ot make the above work, the general approach is to have a
137-
`run_tests.sh` script in the OSS-Fuzz project's folder, which is copied into
138-
the main image.
117+
- `us-central1-docker.pkg.dev/oss-fuzz/oss-fuzz-gen/<PROJECT>-ofg-cached-address`
118+
- `us-central1-docker.pkg.dev/oss-fuzz/oss-fuzz-gen/<PROJECT>-ofg-cached-coverage`
139119

140-
Notice that the `run_tests.sh` is run from a cached image, meaning the
141-
`run_tests.sh` is run after a run of building fuzzers.
120+
They can be used as drop-in replacements for the usual `gcr.io/oss-fuzz/<PROJECT>` images.

0 commit comments

Comments
 (0)