Skip to content

Commit 93037ba

Browse files
committed
tests: add benchmark tests
Add a benchmark test suite that wraps hyperfine and is suitable for producing data about test runs of a CLI or A/B testing CLIs.
1 parent e48bb3b commit 93037ba

16 files changed

+880
-0
lines changed

tests/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
These are the unit and integration tests for the libgit2 projects.
44

5+
* `benchmarks`
6+
These are benchmark tests that excercise the CLI.
57
* `clar`
68
This is [clar](https://github.com/clar-test/clar) the common test framework.
79
* `headertest`

tests/benchmarks/README.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# libgit2 benchmarks
2+
3+
This folder contains the individual benchmark tests for libgit2,
4+
meant for understanding the performance characteristics of libgit2,
5+
comparing your development code to the existing libgit2 code, or
6+
comparing libgit2 to the git reference implementation.
7+
8+
## Running benchmark tests
9+
10+
Benchmark tests can be run in several different ways: running all
11+
benchmarks, running one (or more) suite of benchmarks, or running a
12+
single individual benchmark. You can target either an individual
13+
version of a CLI, or you can A/B test a baseline CLI against a test
14+
CLI.
15+
16+
### Specifying the command-line interface to test
17+
18+
By default, the `git` in your path is benchmarked. Use the
19+
`-c` (or `--cli`) option to specify the command-line interface
20+
to test.
21+
22+
Example: `libgit2_bench --cli git2_cli` will run the tests against
23+
`git2_cli`.
24+
25+
### Running tests to compare two different implementations
26+
27+
You can compare a baseline command-line interface against a test
28+
command-line interface using the `-b (or `--baseline-cli`) option.
29+
30+
Example: `libgit2_bench --baseline-cli git --cli git2_cli` will
31+
run the tests against both `git` and `git2_cli`.
32+
33+
### Running individual benchmark tests
34+
35+
Similar to how a test suite or individual test is specified in
36+
[clar](https://github.com/clar-test/clar), the `-s` (or `--suite`)
37+
option may be used to specify the suite or individual test to run.
38+
Like clar, the suite and test name are separated by `::`, and like
39+
clar, this is a prefix match.
40+
41+
Examples:
42+
* `libgit2_bench -shash_object` will run the tests in the
43+
`hash_object` suite.
44+
* `libgit2_bench -shash_object::random_1kb` will run the
45+
`hash_object::random_1kb` test.
46+
* `libgit2_bench -shash_object::random` will run all the tests that
47+
begin with `hash_object::random`.
48+
49+
## Writing benchmark tests
50+
51+
Benchmark tests are meant to be easy to write. Each individual
52+
benchmark is a shell script that allows it to do set up (eg, creating
53+
or cloning a repository, creating temporary files, etc), then running
54+
benchmarks, then teardown.
55+
56+
The `benchmark_helpers.sh` script provides many helpful utility
57+
functions to allow for cross-platform benchmarking, as well as a
58+
wrapper for `hyperfine` that is suited to testing libgit2.
59+
Note that the helper script must be included first, at the beginning
60+
of the benchmark test.
61+
62+
### Benchmark example
63+
64+
This simplistic example compares the speed of running the `git help`
65+
command in the baseline CLI to the test CLI.
66+
67+
```bash
68+
#!/bin/bash -e
69+
70+
# include the benchmark library
71+
. "$(dirname "$0")/benchmark_helpers.sh"
72+
73+
# run the "help" command; this will benchmark `git2_cli help`
74+
gitbench help
75+
```
76+
77+
### Naming
78+
79+
The filename of the benchmark itself is important. A benchmark's
80+
filename should be the name of the benchmark suite, followed by two
81+
underscores, followed by the name of the benchmark. For example,
82+
`hash-object__random_1kb` is the `random_1kb` test in the `hash-object`
83+
suite.
84+
85+
### Options
86+
87+
The `gitbench` function accepts several options.
88+
89+
* `--sandbox <path>`
90+
The name of a test resource (in the `tests/resources` directory).
91+
This will be copied as-is to the sandbox location before test
92+
execution. This is copied _before_ the `prepare` script is run.
93+
This option may be specified multiple times.
94+
* `--repository <path>`
95+
The name of a test resource repository (in the `tests/resources`
96+
directory). This repository will be copied into a sandbox location
97+
before test execution, and your test will run in this directory.
98+
This is copied _before_ the `prepare` script is run.
99+
* `--prepare <script>`
100+
A script to run before each invocation of the test is run. This can
101+
set up data for the test that will _not_ be timed. This script is run
102+
in bash on all platforms.
103+
104+
Several helper functions are available within the context of a prepare
105+
script:
106+
107+
* `flush_disk_cache`
108+
Calling this will flush the disk cache before each test run.
109+
This should probably be run at the end of the `prepare` script.
110+
* `create_random_file <path> [<size>]`
111+
Calling this will populate a file at the given `path` with `size`
112+
bytes of random data.
113+
* `create_text_file <path> [<size>]`
114+
Calling this will populate a file at the given `path` with `size`
115+
bytes of predictable text, with the platform line endings. This
116+
is preferred over random data as it's reproducible.
117+
118+
* `--warmup <n>`
119+
Specifies that the test should run `n` times before actually measuring
120+
the timing; useful for "warming up" a cache.
121+

0 commit comments

Comments
 (0)