mirror of https://github.com/containers/podman.git
272 lines
7.6 KiB
Go
272 lines
7.6 KiB
Go
//go:build benchmarks
|
|
// +build benchmarks
|
|
|
|
package integration
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path"
|
|
"strconv"
|
|
"strings"
|
|
|
|
podmanRegistry "github.com/containers/podman/v4/hack/podman-registry-go"
|
|
. "github.com/containers/podman/v4/test/utils"
|
|
. "github.com/onsi/ginkgo"
|
|
. "github.com/onsi/gomega"
|
|
. "github.com/onsi/gomega/gexec"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
var (
|
|
// Number of times to execute each benchmark.
|
|
numBenchmarkSamples = 3
|
|
// All benchmarks are ququed here.
|
|
allBenchmarks []benchmark
|
|
)
|
|
|
|
// An internal struct for queuing benchmarks.
|
|
type benchmark struct {
|
|
// The name of the benchmark.
|
|
name string
|
|
// The function to execute.
|
|
main func()
|
|
// Allows for extending a benchmark.
|
|
options newBenchmarkOptions
|
|
}
|
|
|
|
var benchmarkRegistry *podmanRegistry.Registry
|
|
|
|
// Allows for customizing the benchnmark in an easy to extend way.
|
|
type newBenchmarkOptions struct {
|
|
// Sets the benchmark's init function.
|
|
init func()
|
|
// Run a local registry for this benchmark. Use `getPortUserPass()` in
|
|
// the benchmark to get the port, user and password.
|
|
needsRegistry bool
|
|
}
|
|
|
|
// Queue a new benchmark.
|
|
func newBenchmark(name string, main func(), options *newBenchmarkOptions) {
|
|
bm := benchmark{name: name, main: main}
|
|
if options != nil {
|
|
bm.options = *options
|
|
}
|
|
allBenchmarks = append(allBenchmarks, bm)
|
|
}
|
|
|
|
// getPortUserPass returns the port, user and password of the currently running
|
|
// registry.
|
|
func getPortUserPass() (string, string, string) {
|
|
if benchmarkRegistry == nil {
|
|
return "", "", ""
|
|
}
|
|
return benchmarkRegistry.Port, benchmarkRegistry.User, benchmarkRegistry.Password
|
|
}
|
|
|
|
var _ = Describe("Podman Benchmark Suite", func() {
|
|
var (
|
|
timedir string
|
|
podmanTest *PodmanTestIntegration
|
|
)
|
|
|
|
setup := func() {
|
|
tempdir, err := CreateTempDirInTempDir()
|
|
if err != nil {
|
|
os.Exit(1)
|
|
}
|
|
podmanTest = PodmanTestCreate(tempdir)
|
|
podmanTest.Setup()
|
|
timedir, err = CreateTempDirInTempDir()
|
|
if err != nil {
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
cleanup := func() {
|
|
podmanTest.Cleanup()
|
|
os.RemoveAll(timedir)
|
|
|
|
// Stop the local registry.
|
|
if benchmarkRegistry != nil {
|
|
if err := benchmarkRegistry.Stop(); err != nil {
|
|
logrus.Errorf("Error stopping registry: %v", err)
|
|
os.Exit(1)
|
|
}
|
|
benchmarkRegistry = nil
|
|
}
|
|
}
|
|
|
|
totalMemoryInKb := func() (total uint64) {
|
|
files, err := os.ReadDir(timedir)
|
|
if err != nil {
|
|
Fail(fmt.Sprintf("Error reading timing dir: %v", err))
|
|
}
|
|
|
|
for _, f := range files {
|
|
if f.IsDir() {
|
|
continue
|
|
}
|
|
raw, err := os.ReadFile(path.Join(timedir, f.Name()))
|
|
if err != nil {
|
|
Fail(fmt.Sprintf("Error reading timing file: %v", err))
|
|
}
|
|
rawS := strings.TrimSuffix(string(raw), "\n")
|
|
number, err := strconv.ParseUint(rawS, 10, 64)
|
|
if err != nil {
|
|
Fail(fmt.Sprintf("Error converting timing file to numeric value: %v", err))
|
|
}
|
|
total += number
|
|
}
|
|
|
|
return total
|
|
}
|
|
|
|
// Make sure to clean up after the benchmarks.
|
|
AfterEach(func() {
|
|
cleanup()
|
|
})
|
|
|
|
// All benchmarks are executed here to have *one* table listing all data.
|
|
Measure("Podman Benchmark Suite", func(b Benchmarker) {
|
|
|
|
registryOptions := &podmanRegistry.Options{
|
|
Image: "docker-archive:" + imageTarPath(REGISTRY_IMAGE),
|
|
}
|
|
|
|
for i := range allBenchmarks {
|
|
setup()
|
|
bm := allBenchmarks[i]
|
|
|
|
// Start a local registry if requested.
|
|
if bm.options.needsRegistry {
|
|
reg, err := podmanRegistry.StartWithOptions(registryOptions)
|
|
if err != nil {
|
|
logrus.Errorf("Error starting registry: %v", err)
|
|
os.Exit(1)
|
|
}
|
|
benchmarkRegistry = reg
|
|
}
|
|
|
|
if bm.options.init != nil {
|
|
bm.options.init()
|
|
}
|
|
|
|
// Set the time dir only for the main() function.
|
|
os.Setenv(EnvTimeDir, timedir)
|
|
b.Time("[CPU] "+bm.name, bm.main)
|
|
os.Unsetenv(EnvTimeDir)
|
|
|
|
mem := totalMemoryInKb()
|
|
b.RecordValueWithPrecision("[MEM] "+bm.name, float64(mem), "KB", 1)
|
|
|
|
cleanup()
|
|
}
|
|
}, numBenchmarkSamples)
|
|
|
|
BeforeEach(func() {
|
|
|
|
// --------------------------------------------------------------------------
|
|
// IMAGE BENCHMARKS
|
|
// --------------------------------------------------------------------------
|
|
|
|
newBenchmark("podman images", func() {
|
|
session := podmanTest.Podman([]string{"images"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(Exit(0))
|
|
}, nil)
|
|
|
|
newBenchmark("podman push", func() {
|
|
port, user, pass := getPortUserPass()
|
|
session := podmanTest.Podman([]string{"push", "--tls-verify=false", "--creds", user + ":" + pass, SYSTEMD_IMAGE, "localhost:" + port + "/repo/image:tag"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(Exit(0))
|
|
}, &newBenchmarkOptions{needsRegistry: true})
|
|
|
|
newBenchmark("podman pull", func() {
|
|
port, user, pass := getPortUserPass()
|
|
session := podmanTest.Podman([]string{"pull", "--tls-verify=false", "--creds", user + ":" + pass, "localhost:" + port + "/repo/image:tag"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(Exit(0))
|
|
}, &newBenchmarkOptions{
|
|
needsRegistry: true,
|
|
init: func() {
|
|
port, user, pass := getPortUserPass()
|
|
session := podmanTest.Podman([]string{"push", "--tls-verify=false", "--creds", user + ":" + pass, SYSTEMD_IMAGE, "localhost:" + port + "/repo/image:tag"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(Exit(0))
|
|
},
|
|
})
|
|
|
|
newBenchmark("podman load [docker]", func() {
|
|
session := podmanTest.Podman([]string{"load", "-i", "./testdata/docker-two-images.tar.xz"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(Exit(0))
|
|
}, nil)
|
|
|
|
newBenchmark("podman load [oci]", func() {
|
|
session := podmanTest.Podman([]string{"load", "-i", "./testdata/oci-registry-name.tar.gz"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(Exit(0))
|
|
}, nil)
|
|
|
|
newBenchmark("podman save", func() {
|
|
session := podmanTest.Podman([]string{"save", ALPINE, "-o", path.Join(podmanTest.TempDir, "alpine.tar")})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(Exit(0))
|
|
}, nil)
|
|
|
|
newBenchmark("podman image inspect", func() {
|
|
session := podmanTest.Podman([]string{"inspect", ALPINE})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(Exit(0))
|
|
}, nil)
|
|
|
|
newBenchmark("podman login + logout", func() {
|
|
port, user, pass := getPortUserPass()
|
|
|
|
session := podmanTest.Podman([]string{"login", "-u", user, "-p", pass, "--tls-verify=false", "localhost:" + port})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(Exit(0))
|
|
|
|
session = podmanTest.Podman([]string{"logout", "localhost:" + port})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(Exit(0))
|
|
}, &newBenchmarkOptions{needsRegistry: true})
|
|
|
|
// --------------------------------------------------------------------------
|
|
// CONTAINER BENCHMARKS
|
|
// --------------------------------------------------------------------------
|
|
|
|
newBenchmark("podman create", func() {
|
|
session := podmanTest.Podman([]string{"create", ALPINE, "true"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(Exit(0))
|
|
}, nil)
|
|
|
|
newBenchmark("podman start", func() {
|
|
session := podmanTest.Podman([]string{"start", "foo"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(Exit(0))
|
|
}, &newBenchmarkOptions{
|
|
init: func() {
|
|
session := podmanTest.Podman([]string{"create", "--name=foo", ALPINE, "true"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(Exit(0))
|
|
},
|
|
})
|
|
|
|
newBenchmark("podman run", func() {
|
|
session := podmanTest.Podman([]string{"run", ALPINE, "true"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(Exit(0))
|
|
}, nil)
|
|
|
|
newBenchmark("podman run --detach", func() {
|
|
session := podmanTest.Podman([]string{"run", "--detach", ALPINE, "true"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(Exit(0))
|
|
}, nil)
|
|
})
|
|
})
|