benchmarking Podman: proof of concept

Add a proof of concept for benchmarking Podman.  The benchmarks are
implemented by means of the end-to-end test suite but hidden behind
a `benchmarks` build tag.  Running `make localbenchmarks` will run
`test/e2e` with the specific build tag and set ginkgo's "focus" to
the specific "Podman Benchmark Suite" to only run this spec and skip
all others.

ginkgo will print a report before terminating listing the CPU and memory
stats for each benchmark.  New benchmarks can easily be added via the
`newBenchmark` function that also supports adding an `init()` function
to each benchmark which allows for performing certain setups for the
specific benchmark.  For instance, benchmarking `podman start` requires
creating a container beforehand.

Podman may be called more than once in the main function of a benchmark
but note that the displayed memory consumption is then a sum of all
Podman invocations.  The memory consumption is collected via
`/usr/bin/time`.

A benchmark's report is split into CPU and memory as displayed below:

```
[CPU] podman images:
  Fastest Time: 0.146s
  Slowest Time: 0.187s
  Average Time: 0.180s ± 0.015s
[MEM] podman images:
  Smallest: 41892.0KB
   Largest: 42792.0KB
   Average: 42380.7KB ± 286.4KB
```

Note that the benchmarks are not wired into the CI yet.  They are meant
as a proof of concept.  More benchmarks and the plumbing into CI will
happen in a later change.

Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>
This commit is contained in:
Valentin Rothberg
2022-04-11 13:32:23 +02:00
parent bc8d8737b7
commit 0162f678c0
3 changed files with 196 additions and 2 deletions

View File

@ -27,6 +27,8 @@ const (
CNI NetworkBackend = iota
// Netavark network backend
Netavark NetworkBackend = iota
// Env variable for creating time files.
EnvTimeDir = "_PODMAN_TIME_DIR"
)
func (n NetworkBackend) ToString() string {
@ -96,6 +98,17 @@ func (p *PodmanTest) PodmanAsUserBase(args []string, uid, gid uint32, cwd string
if p.RemoteTest {
podmanBinary = p.RemotePodmanBinary
}
if timeDir := os.Getenv(EnvTimeDir); timeDir != "" {
timeFile, err := ioutil.TempFile(timeDir, ".time")
if err != nil {
Fail(fmt.Sprintf("Error creating time file: %v", err))
}
timeArgs := []string{"-f", "%M", "-o", timeFile.Name()}
timeCmd := append([]string{"/usr/bin/time"}, timeArgs...)
wrapper = append(timeCmd, wrapper...)
}
runCmd := append(wrapper, podmanBinary)
if p.NetworkBackend == Netavark {
runCmd = append(runCmd, []string{"--network-backend", "netavark"}...)