diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 82b76dad97..95c977d398 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -7,18 +7,19 @@ toolchain go1.23.6 require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc github.com/docker/cli v26.1.3+incompatible - github.com/docker/docker v26.1.3+incompatible + github.com/docker/docker v28.2.2+incompatible github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/hashicorp/go-multierror v1.1.1 github.com/pkg/errors v0.9.1 + github.com/prometheus/common v0.55.0 github.com/stackrox/rox v0.0.0-20210914215712-9ac265932e28 github.com/stretchr/testify v1.9.0 github.com/thoas/go-funk v0.9.3 go.opentelemetry.io/otel/trace v1.28.0 golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 golang.org/x/sys v0.26.0 - google.golang.org/grpc v1.65.0 + google.golang.org/grpc v1.67.0 gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.32.2 k8s.io/apimachinery v0.32.2 @@ -34,6 +35,8 @@ require ( github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/containerd/errdefs v1.0.0 // indirect + github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/docker-credential-helpers v0.8.1 // indirect github.com/docker/go-connections v0.5.0 // indirect @@ -71,6 +74,7 @@ require ( github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/spdystream v0.5.0 // indirect + github.com/moby/sys/atomicwriter v0.1.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/morikuni/aec v1.0.0 // indirect @@ -78,11 +82,10 @@ require ( github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect - github.com/planetscale/vtprotobuf v0.6.0 // indirect + github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/cobra v1.8.1 // indirect @@ -107,7 +110,7 @@ require ( golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.7.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/protobuf v1.35.1 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 92de6e885f..88592db1e5 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -15,6 +15,10 @@ github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK3 github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= +github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= +github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= +github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -26,8 +30,8 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/docker/cli v26.1.3+incompatible h1:bUpXT/N0kDE3VUHI2r5VMsYQgi38kYuoC0oL9yt3lqc= github.com/docker/cli v26.1.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/docker v26.1.3+incompatible h1:lLCzRbrVZrljpVNobJu1J2FHk8V0s4BawoZippkc+xo= -github.com/docker/docker v26.1.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v28.2.2+incompatible h1:CjwRSksz8Yo4+RmQ339Dp/D2tGO5JxwYeqtMOEe0LDw= +github.com/docker/docker v28.2.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.8.1 h1:j/eKUktUltBtMzKqmfLB0PAgqYyMHOp5vfsD1807oKo= github.com/docker/docker-credential-helpers v0.8.1/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= @@ -126,6 +130,10 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= +github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw= +github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs= +github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= +github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -151,8 +159,8 @@ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYr github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/planetscale/vtprotobuf v0.6.0 h1:nBeETjudeJ5ZgBHUz1fVHvbqUKnYOXNhsIEabROxmNA= -github.com/planetscale/vtprotobuf v0.6.0/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -286,10 +294,10 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 h1:YcyjlL1PRr2Q17/I0dPk2JmYS5CDXfcdb2Z3YRioEbw= google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 h1:2035KHhUv+EpyB+hWgJnaWKJOdX1E95w2S8Rr4uWKTs= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= +google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/integration-tests/pkg/executor/executor.go b/integration-tests/pkg/executor/executor.go index 76b2d823c7..b1ddfb0fe8 100644 --- a/integration-tests/pkg/executor/executor.go +++ b/integration-tests/pkg/executor/executor.go @@ -1,7 +1,9 @@ package executor import ( + "context" "os/exec" + "time" "github.com/stackrox/collector/integration-tests/pkg/config" ) @@ -16,6 +18,14 @@ type ContainerLogs struct { Stderr string } +type ContainerStat struct { + Timestamp time.Time + Id string + Name string + Mem uint64 + Cpu uint64 +} + func (c *ContainerLogs) Empty() bool { return *c == (ContainerLogs{}) } @@ -47,6 +57,7 @@ type Executor interface { StopContainer(name string) (string, error) StartContainer(config config.ContainerStartConfig) (string, error) GetContainerHealthCheck(containerID string) (string, error) + GetContainerStats(ctx context.Context, containerID string) (*ContainerStat, error) GetContainerIP(containerID string) (string, error) GetContainerLogs(containerID string) (ContainerLogs, error) CaptureLogs(testName, containerName string) (string, error) diff --git a/integration-tests/pkg/executor/executor_cri.go b/integration-tests/pkg/executor/executor_cri.go index 733b80c84a..145566b887 100644 --- a/integration-tests/pkg/executor/executor_cri.go +++ b/integration-tests/pkg/executor/executor_cri.go @@ -289,6 +289,23 @@ func (c *criExecutor) GetContainerHealthCheck(containerID string) (string, error return "", fmt.Errorf("Unsupported") } +func (c *criExecutor) GetContainerStats(ctx context.Context, containerID string) ( + *ContainerStat, error) { + + stats, err := c.runtimeService.ContainerStats(ctx, containerID) + if err != nil { + return nil, err + } + + return &ContainerStat{ + Timestamp: time.Unix(stats.Memory.Timestamp, 0), + Id: stats.Attributes.Id, + Name: stats.Attributes.Metadata.Name, + Mem: stats.Memory.UsageBytes.GetValue(), + Cpu: stats.Cpu.UsageCoreNanoSeconds.GetValue(), + }, nil +} + func (c *criExecutor) GetContainerIP(name string) (string, error) { container, err := c.getContainer(name) if err != nil { diff --git a/integration-tests/pkg/executor/executor_docker_api.go b/integration-tests/pkg/executor/executor_docker_api.go index a40f182ea3..fbd552e741 100644 --- a/integration-tests/pkg/executor/executor_docker_api.go +++ b/integration-tests/pkg/executor/executor_docker_api.go @@ -3,6 +3,7 @@ package executor import ( "bytes" "context" + "encoding/json" "fmt" "io" "strings" @@ -91,6 +92,34 @@ func (d *dockerAPIExecutor) GetContainerHealthCheck(containerID string) (string, return strings.Join(inspectResp.Config.Healthcheck.Test, " "), nil } +func (d *dockerAPIExecutor) GetContainerStats(ctx context.Context, containerID string) ( + *ContainerStat, error) { + + // ContainerStatsOneShot add "one-shot" parameter to the API query, which + // instructs the server to get a single stat, rather than waiting for more. + statsResp, err := d.client.ContainerStatsOneShot(ctx, containerID) + if err != nil { + return nil, err + } + + var stats container.StatsResponse + decoder := json.NewDecoder(statsResp.Body) + + if err := decoder.Decode(&stats); err == io.EOF { + return nil, nil + } else if err != nil { + return nil, err + } + + return &ContainerStat{ + Timestamp: stats.Read, + Id: stats.ID, + Name: stats.Name, + Mem: stats.MemoryStats.Usage, + Cpu: stats.CPUStats.CPUUsage.TotalUsage, + }, nil +} + func (d *dockerAPIExecutor) StartContainer(startConfig config.ContainerStartConfig) (string, error) { ctx := context.Background() var binds []string @@ -159,7 +188,7 @@ func (d *dockerAPIExecutor) StartContainer(startConfig config.ContainerStartConf func (d *dockerAPIExecutor) ExecContainer(opts *ExecOptions) (string, error) { ctx := context.Background() - execConfig := types.ExecConfig{ + execConfig := container.ExecOptions{ AttachStdout: true, AttachStderr: true, Cmd: opts.Command, @@ -170,7 +199,7 @@ func (d *dockerAPIExecutor) ExecContainer(opts *ExecOptions) (string, error) { return "", fmt.Errorf("error creating Exec: %w", err) } - execStartCheck := types.ExecStartCheck{Detach: false, Tty: false} + execStartCheck := container.ExecAttachOptions{Detach: false, Tty: false} attachResp, err := d.client.ContainerExecAttach(ctx, resp.ID, execStartCheck) if err != nil { return "", fmt.Errorf("error attaching to Exec: %w", err) diff --git a/integration-tests/suites/async_connections.go b/integration-tests/suites/async_connections.go index 26032b4445..886e2b8fcc 100644 --- a/integration-tests/suites/async_connections.go +++ b/integration-tests/suites/async_connections.go @@ -33,7 +33,6 @@ type AsyncConnectionTestSuite struct { */ func (s *AsyncConnectionTestSuite) SetupSuite() { s.RegisterCleanup("server", "client") - s.StartContainerStats() collectorOptions := collector.StartupOptions{ Env: map[string]string{ diff --git a/integration-tests/suites/base.go b/integration-tests/suites/base.go index 2d8e18b11d..59170329c8 100644 --- a/integration-tests/suites/base.go +++ b/integration-tests/suites/base.go @@ -1,6 +1,7 @@ package suites import ( + "context" "encoding/json" "errors" "fmt" @@ -31,8 +32,6 @@ const ( parentUIDStr = "ParentUid" parentExecFilePathStr = "ParentExecFilePath" - containerStatsName = "container-stats" - defaultWaitTickSeconds = 1 * time.Second ) @@ -42,17 +41,13 @@ type IntegrationTestSuiteBase struct { collector collector.Manager sensor *mock_sensor.MockSensor metrics map[string]float64 - stats []ContainerStat - start time.Time - stop time.Time -} -type ContainerStat struct { - Timestamp string - Id string - Name string - Mem string - Cpu float64 + stats []executor.ContainerStat + statsCtx context.Context + statsCancel context.CancelFunc + + start time.Time + stop time.Time } type PerformanceResult struct { @@ -61,7 +56,7 @@ type PerformanceResult struct { VmConfig string CollectionMethod string Metrics map[string]float64 - ContainerStats []ContainerStat + ContainerStats []executor.ContainerStat LoadStartTs string LoadStopTs string } @@ -110,12 +105,18 @@ func (s *IntegrationTestSuiteBase) StartCollector(disableGRPC bool, options *col s.Require().NoError(err) }) s.Require().True(selfCheckOk) + + // The collector must be running by now, initiate collecting stats + s.StartContainerStats() } // StopCollector will tear down the collector container and stop // the MockSensor if it was started. func (s *IntegrationTestSuiteBase) StopCollector() { + // Stop stats collection first + s.statsCancel() s.Require().NoError(s.collector.TearDown()) + if s.sensor != nil { s.sensor.Stop() } @@ -175,7 +176,6 @@ func (s *IntegrationTestSuiteBase) RegisterCleanup(containers ...string) { // If the test is successful, this clean up function is still run // but everything should be clean already, so this should not fail // if resources are already gone. - containers = append(containers, containerStatsName) s.cleanupContainers(containers...) // StopCollector is safe when collector isn't running, but the container must exist. @@ -187,33 +187,30 @@ func (s *IntegrationTestSuiteBase) RegisterCleanup(containers ...string) { }) } -func (s *IntegrationTestSuiteBase) GetContainerStats() []ContainerStat { +func (s *IntegrationTestSuiteBase) SnapshotContainerStats() { if s.stats == nil { - s.stats = make([]ContainerStat, 0) - - logs, err := s.containerLogs(containerStatsName) - if err != nil { - assert.FailNow(s.T(), "container-stats failure") - return nil - } + s.stats = make([]executor.ContainerStat, 0) + } - logLines := strings.Split(logs.Stderr, "\n") - for i, line := range logLines { - var stat ContainerStat + if s.statsCtx == nil { + s.statsCtx, s.statsCancel = context.WithCancel(context.Background()) + } - _ = json.Unmarshal([]byte(line), &stat) + stat, err := s.Executor().GetContainerStats(s.statsCtx, s.Collector().ContainerID()) - if stat.Name != "" { - s.stats = append(s.stats, stat) - } else { - log.Warn("missing name for stat line %d of %d", i, len(logLines)) - } - } + // The stats context will be canceled at the end of the test. If it happens + // while the request is in flight, ignore the error. + if err != nil && !errors.Is(err, context.Canceled) { + assert.FailNowf(s.T(), "fail to get container stats", "%v", err) + return + } - s.cleanupContainers(containerStatsName) + if stat == nil { + log.Info("No ContainerStats found") + return } - return s.stats + s.stats = append(s.stats, *stat) } // Convert memory string from docker stats into numeric value in MiB @@ -245,13 +242,9 @@ func (s *IntegrationTestSuiteBase) PrintContainerStats() { cpuStats := map[string][]float64{} memStats := map[string][]float64{} - for _, stat := range s.GetContainerStats() { - cpuStats[stat.Name] = append(cpuStats[stat.Name], stat.Cpu) - - memValue, err := Mem2Numeric(stat.Mem) - s.Require().NoError(err) - - memStats[stat.Name] = append(memStats[stat.Name], memValue) + for _, stat := range s.stats { + cpuStats[stat.Name] = append(cpuStats[stat.Name], float64(stat.Cpu)) + memStats[stat.Name] = append(memStats[stat.Name], float64(stat.Mem)) } for name, cpu := range cpuStats { @@ -280,7 +273,7 @@ func (s *IntegrationTestSuiteBase) WritePerfResults() { VmConfig: config.VMInfo().Config, CollectionMethod: config.CollectionMethod(), Metrics: s.metrics, - ContainerStats: s.GetContainerStats(), + ContainerStats: s.stats, LoadStartTs: s.start.Format("2006-01-02 15:04:05"), LoadStopTs: s.stop.Format("2006-01-02 15:04:05"), } @@ -439,15 +432,19 @@ func (s *IntegrationTestSuiteBase) getPort(containerName string) (string, error) } func (s *IntegrationTestSuiteBase) StartContainerStats() { - image := config.Images().QaImageByKey("performance-stats") - err := s.Executor().PullImage(image) - s.Require().NoError(err) - - _, err = s.executor.StartContainer(config.ContainerStartConfig{ - Name: containerStatsName, - Image: image, - Mounts: map[string]string{"/var/run/docker.sock": config.RuntimeInfo().Socket}}) - s.Require().NoError(err) + tick := time.Tick(defaultWaitTickSeconds) + s.statsCtx, s.statsCancel = context.WithCancel(context.Background()) + + go func() { + for { + select { + case <-tick: + s.SnapshotContainerStats() + case <-s.statsCtx.Done(): + return + } + } + }() } func (s *IntegrationTestSuiteBase) execShellCommand(command string) error { diff --git a/integration-tests/suites/benchmark.go b/integration-tests/suites/benchmark.go index 2c06a5713a..4e877cf8a4 100644 --- a/integration-tests/suites/benchmark.go +++ b/integration-tests/suites/benchmark.go @@ -141,7 +141,6 @@ func (b *BenchmarkTestSuiteBase) StopPerfTools() { func (s *BenchmarkCollectorTestSuite) SetupSuite() { s.RegisterCleanup("perf", "bcc", "bpftrace", "init", "benchmark-processes", "benchmark-endpoints") - s.StartContainerStats() s.StartPerfTools() @@ -210,7 +209,6 @@ func (s *BenchmarkCollectorTestSuite) TearDownSuite() { func (s *BenchmarkBaselineTestSuite) SetupSuite() { s.RegisterCleanup("benchmark-processes", "benchmark-endpoints") - s.StartContainerStats() s.StartPerfTools() } diff --git a/integration-tests/suites/connections_and_endpoints.go b/integration-tests/suites/connections_and_endpoints.go index 9137edb9f7..52671f108a 100644 --- a/integration-tests/suites/connections_and_endpoints.go +++ b/integration-tests/suites/connections_and_endpoints.go @@ -30,7 +30,6 @@ type ConnectionsAndEndpointsTestSuite struct { func (s *ConnectionsAndEndpointsTestSuite) SetupSuite() { s.RegisterCleanup(s.Server.Name, s.Client.Name) - s.StartContainerStats() collectorOptions := collector.StartupOptions{ Env: map[string]string{ diff --git a/integration-tests/suites/duplicate_endpoints.go b/integration-tests/suites/duplicate_endpoints.go index 0107bc7ec5..dff3f5ea66 100644 --- a/integration-tests/suites/duplicate_endpoints.go +++ b/integration-tests/suites/duplicate_endpoints.go @@ -32,7 +32,6 @@ func (s *DuplicateEndpointsTestSuite) killSocatProcess(port int) { func (s *DuplicateEndpointsTestSuite) SetupSuite() { s.RegisterCleanup("socat") - s.StartContainerStats() collectorOptions := collector.StartupOptions{ Config: map[string]any{ diff --git a/integration-tests/suites/listening_ports.go b/integration-tests/suites/listening_ports.go index b146cf9812..292fd9e202 100644 --- a/integration-tests/suites/listening_ports.go +++ b/integration-tests/suites/listening_ports.go @@ -23,7 +23,6 @@ type ProcessListeningOnPortTestSuite struct { func (s *ProcessListeningOnPortTestSuite) SetupSuite() { s.RegisterCleanup("process-ports") - s.StartContainerStats() collectorOptions := collector.StartupOptions{ Config: map[string]any{ diff --git a/integration-tests/suites/process_network.go b/integration-tests/suites/process_network.go index 9d41fa7f5d..c03c40e512 100644 --- a/integration-tests/suites/process_network.go +++ b/integration-tests/suites/process_network.go @@ -24,7 +24,6 @@ type ProcessNetworkTestSuite struct { // Execs into nginx and does a sleep func (s *ProcessNetworkTestSuite) SetupSuite() { s.RegisterCleanup("nginx", "nginx-curl") - s.StartContainerStats() s.StartCollector(false, nil) image_store := config.Images() diff --git a/integration-tests/suites/processes_and_endpoints.go b/integration-tests/suites/processes_and_endpoints.go index 2da3032b31..c08d6c7822 100644 --- a/integration-tests/suites/processes_and_endpoints.go +++ b/integration-tests/suites/processes_and_endpoints.go @@ -22,7 +22,6 @@ type ProcessesAndEndpointsTestSuite struct { func (s *ProcessesAndEndpointsTestSuite) SetupSuite() { s.RegisterCleanup(s.ContainerName) - s.StartContainerStats() collectorOptions := collector.StartupOptions{ Env: map[string]string{ diff --git a/integration-tests/suites/procfs_scraper.go b/integration-tests/suites/procfs_scraper.go index d2f13e3856..2487449347 100644 --- a/integration-tests/suites/procfs_scraper.go +++ b/integration-tests/suites/procfs_scraper.go @@ -27,8 +27,6 @@ type ProcfsScraperTestSuite struct { func (s *ProcfsScraperTestSuite) SetupSuite() { s.RegisterCleanup("nginx") - s.StartContainerStats() - collectorOptions := collector.StartupOptions{ Env: map[string]string{ "ROX_PROCESSES_LISTENING_ON_PORT": strconv.FormatBool(s.RoxProcessesListeningOnPort), @@ -48,7 +46,7 @@ func (s *ProcfsScraperTestSuite) SetupSuite() { func (s *ProcfsScraperTestSuite) launchNginx() { image := config.Images().ImageByKey("nginx") - err := s.executor.PullImage(image) + err := s.Executor().PullImage(image) s.Require().NoError(err) // invokes default nginx diff --git a/integration-tests/suites/repeated_network_flow.go b/integration-tests/suites/repeated_network_flow.go index 9a04dc1e04..f200ee6c82 100644 --- a/integration-tests/suites/repeated_network_flow.go +++ b/integration-tests/suites/repeated_network_flow.go @@ -37,7 +37,6 @@ type RepeatedNetworkFlowTestSuite struct { // Launches nginx container func (s *RepeatedNetworkFlowTestSuite) SetupSuite() { s.RegisterCleanup("nginx", "nginx-curl") - s.StartContainerStats() collectorOptions := collector.StartupOptions{ Config: map[string]any{ diff --git a/integration-tests/suites/runtime_config_file.go b/integration-tests/suites/runtime_config_file.go index 1f7267cb34..401a5e8cb2 100644 --- a/integration-tests/suites/runtime_config_file.go +++ b/integration-tests/suites/runtime_config_file.go @@ -78,8 +78,6 @@ func (s *RuntimeConfigFileTestSuite) setExternalIpsEnabled(runtimeConfigFile str func (s *RuntimeConfigFileTestSuite) SetupTest() { s.RegisterCleanup("external-connection") - s.StartContainerStats() - containerID, err := s.Executor().StartContainer( config.ContainerStartConfig{ Name: "external-connection", diff --git a/integration-tests/suites/socat.go b/integration-tests/suites/socat.go index c9b4993996..cf125a995b 100644 --- a/integration-tests/suites/socat.go +++ b/integration-tests/suites/socat.go @@ -31,7 +31,6 @@ type SocatTestSuite struct { func (s *SocatTestSuite) SetupSuite() { s.RegisterCleanup("socat") - s.StartContainerStats() collectorOptions := collector.StartupOptions{ Config: map[string]any{ diff --git a/integration-tests/suites/symlink_process.go b/integration-tests/suites/symlink_process.go index ceb01c6bab..3ef12da43c 100644 --- a/integration-tests/suites/symlink_process.go +++ b/integration-tests/suites/symlink_process.go @@ -18,7 +18,6 @@ type SymbolicLinkProcessTestSuite struct { func (s *SymbolicLinkProcessTestSuite) SetupSuite() { s.RegisterCleanup("process-ports") - s.StartContainerStats() collectorOptions := collector.StartupOptions{ Config: map[string]any{ diff --git a/integration-tests/suites/udp_networkflow.go b/integration-tests/suites/udp_networkflow.go index adfd664d62..052c2aabf4 100644 --- a/integration-tests/suites/udp_networkflow.go +++ b/integration-tests/suites/udp_networkflow.go @@ -45,7 +45,6 @@ func (s *UdpNetworkFlow) SetupSuite() { // The network needs to be removed after the containers, so its // the first cleanup we register. s.RegisterCleanup(UDP_CLIENT, UDP_SERVER) - s.StartContainerStats() collectorOptions := collector.StartupOptions{ Env: map[string]string{ "ROX_COLLECTOR_TRACK_SEND_RECV": "true",