diff options
-rw-r--r-- | Makefile | 12 | ||||
-rw-r--r-- | pkg/machine/wsl/machine.go | 10 | ||||
-rw-r--r-- | pkg/specgen/generate/container.go | 19 | ||||
-rw-r--r-- | test/e2e/benchmarks_test.go | 173 | ||||
-rw-r--r-- | test/e2e/healthcheck_run_test.go | 2 | ||||
-rw-r--r-- | test/utils/utils.go | 13 |
6 files changed, 221 insertions, 8 deletions
@@ -553,8 +553,8 @@ test: localunit localintegration remoteintegration localsystem remotesystem ## .PHONY: ginkgo-run ginkgo-run: - $(GOBIN)/ginkgo version - $(GOBIN)/ginkgo -v $(TESTFLAGS) -tags "$(TAGS)" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor -nodes 3 -debug test/e2e/. $(HACK) + ACK_GINKGO_RC=true $(GOBIN)/ginkgo version + ACK_GINKGO_RC=true $(GOBIN)/ginkgo -v $(TESTFLAGS) -tags "$(TAGS)" $(GINKGOTIMEOUT) -cover -flakeAttempts 3 -progress -trace -noColor -nodes 3 -debug test/e2e/. $(HACK) .PHONY: ginkgo ginkgo: @@ -570,6 +570,14 @@ localintegration: test-binaries ginkgo .PHONY: remoteintegration remoteintegration: test-binaries ginkgo-remote +.PHONY: localbenchmarks +localbenchmarks: test-binaries + ACK_GINKGO_RC=true $(GOBIN)/ginkgo \ + -focus "Podman Benchmark Suite" \ + -tags "$(BUILDTAGS) benchmarks" -noColor \ + -noisySkippings=false -noisyPendings=false \ + test/e2e/. + .PHONY: localsystem localsystem: # Wipe existing config, database, and cache: start with clean slate. diff --git a/pkg/machine/wsl/machine.go b/pkg/machine/wsl/machine.go index 1da042f6a..dff7bfef9 100644 --- a/pkg/machine/wsl/machine.go +++ b/pkg/machine/wsl/machine.go @@ -830,7 +830,15 @@ func launchWinProxy(v *MachineVM) (bool, string, error) { return globalName, "", err } - dest := fmt.Sprintf("ssh://root@localhost:%d/run/podman/podman.sock", v.Port) + destSock := "/run/user/1000/podman/podman.sock" + forwardUser := v.RemoteUsername + + if v.Rootful { + destSock = "/run/podman/podman.sock" + forwardUser = "root" + } + + dest := fmt.Sprintf("ssh://%s@localhost:%d%s", forwardUser, v.Port, destSock) args := []string{v.Name, stateDir, pipePrefix + machinePipe, dest, v.IdentityPath} waitPipe := machinePipe if globalName { diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go index f7ea2edfa..5f4218899 100644 --- a/pkg/specgen/generate/container.go +++ b/pkg/specgen/generate/container.go @@ -67,12 +67,21 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat // NOTE: the health check is only set for Docker images // but inspect will take care of it. s.HealthConfig = inspectData.HealthCheck - if s.HealthConfig != nil && s.HealthConfig.Timeout == 0 { - hct, err := time.ParseDuration(define.DefaultHealthCheckTimeout) - if err != nil { - return nil, err + if s.HealthConfig != nil { + if s.HealthConfig.Timeout == 0 { + hct, err := time.ParseDuration(define.DefaultHealthCheckTimeout) + if err != nil { + return nil, err + } + s.HealthConfig.Timeout = hct + } + if s.HealthConfig.Interval == 0 { + hct, err := time.ParseDuration(define.DefaultHealthCheckInterval) + if err != nil { + return nil, err + } + s.HealthConfig.Interval = hct } - s.HealthConfig.Timeout = hct } } diff --git a/test/e2e/benchmarks_test.go b/test/e2e/benchmarks_test.go new file mode 100644 index 000000000..c631b06ee --- /dev/null +++ b/test/e2e/benchmarks_test.go @@ -0,0 +1,173 @@ +//go:build benchmarks +// +build benchmarks + +package integration + +import ( + "fmt" + "io/ioutil" + "os" + "path" + "strconv" + "strings" + + . "github.com/containers/podman/v4/test/utils" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" +) + +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() + // Function is run before `main`. + init func() +} + +// Allows for customizing the benchnmark in an easy to extend way. +type newBenchmarkOptions struct { + // Sets the benchmark's init function. + init func() +} + +// Queue a new benchmark. +func newBenchmark(name string, main func(), options *newBenchmarkOptions) { + bm := benchmark{name: name, main: main} + if options != nil { + bm.init = options.init + } + allBenchmarks = append(allBenchmarks, bm) +} + +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) + } + + totalMemoryInKb := func() (total uint64) { + files, err := ioutil.ReadDir(timedir) + if err != nil { + Fail(fmt.Sprintf("Error reading timing dir: %v", err)) + } + + for _, f := range files { + if f.IsDir() { + continue + } + raw, err := ioutil.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) { + for i := range allBenchmarks { + setup() + bm := allBenchmarks[i] + if bm.init != nil { + bm.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 pull", func() { + session := podmanTest.Podman([]string{"pull", "quay.io/libpod/cirros"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + }, nil) + + // -------------------------------------------------------------------------- + // CONTAINER BENCHMARKS + // -------------------------------------------------------------------------- + + newBenchmark("podman create", func() { + session := podmanTest.Podman([]string{"run", 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) + }) +}) diff --git a/test/e2e/healthcheck_run_test.go b/test/e2e/healthcheck_run_test.go index 757eaed20..23f1a1dbf 100644 --- a/test/e2e/healthcheck_run_test.go +++ b/test/e2e/healthcheck_run_test.go @@ -325,6 +325,8 @@ HEALTHCHECK CMD ls -l / 2>&1`, ALPINE) inspect := podmanTest.InspectContainer("hctest") // Check to make sure a default time value was added Expect(inspect[0].Config.Healthcheck.Timeout).To(BeNumerically("==", 30000000000)) + // Check to make sure a default time interval value was added + Expect(inspect[0].Config.Healthcheck.Interval).To(BeNumerically("==", 30000000000)) // Check to make sure characters were not coerced to utf8 Expect(inspect[0].Config.Healthcheck.Test).To(Equal([]string{"CMD-SHELL", "ls -l / 2>&1"})) }) diff --git a/test/utils/utils.go b/test/utils/utils.go index 57f002130..da56a3a2e 100644 --- a/test/utils/utils.go +++ b/test/utils/utils.go @@ -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"}...) |