diff options
author | Will Chandler <wchandler@gitlab.com> | 2023-11-09 06:44:43 +0300 |
---|---|---|
committer | Will Chandler <wchandler@gitlab.com> | 2023-11-13 21:39:00 +0300 |
commit | 121a604bdd2304bbc7fe470174aea95b4ed41697 (patch) | |
tree | d20c4e839d935e9102d8de70c1553f5336e27029 /internal/cgroups | |
parent | 10e9912a06a3ec542587231441a5abf449d790ac (diff) |
cgroups: Unify TestMetrics
Convert the separate v1 and v2 `TestMetrics` versions to a single test.
Diffstat (limited to 'internal/cgroups')
-rw-r--r-- | internal/cgroups/handler_linux_test.go | 126 | ||||
-rw-r--r-- | internal/cgroups/v1_linux_test.go | 97 | ||||
-rw-r--r-- | internal/cgroups/v2_linux_test.go | 95 |
3 files changed, 126 insertions, 192 deletions
diff --git a/internal/cgroups/handler_linux_test.go b/internal/cgroups/handler_linux_test.go index 4f61ab7f6..a9a12a278 100644 --- a/internal/cgroups/handler_linux_test.go +++ b/internal/cgroups/handler_linux_test.go @@ -7,9 +7,12 @@ import ( "os/exec" "path/filepath" "strconv" + "strings" "testing" cgrps "github.com/containerd/cgroups/v3" + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/config/cgroups" "gitlab.com/gitlab-org/gitaly/v16/internal/testhelper" @@ -352,6 +355,129 @@ func TestCleanup(t *testing.T) { } } +func TestMetrics(t *testing.T) { + tests := []struct { + name string + metricsEnabled bool + pid int + expectV1 string + expectV2 string + }{ + { + name: "metrics enabled: true", + metricsEnabled: true, + pid: 1, + expectV1: `# HELP gitaly_cgroup_cpu_usage_total CPU Usage of Cgroup +# TYPE gitaly_cgroup_cpu_usage_total gauge +gitaly_cgroup_cpu_usage_total{path="%s",type="kernel"} 0 +gitaly_cgroup_cpu_usage_total{path="%s",type="user"} 0 +# HELP gitaly_cgroup_memory_reclaim_attempts_total Number of memory usage hits limits +# TYPE gitaly_cgroup_memory_reclaim_attempts_total gauge +gitaly_cgroup_memory_reclaim_attempts_total{path="%s"} 2 +# HELP gitaly_cgroup_procs_total Total number of procs +# TYPE gitaly_cgroup_procs_total gauge +gitaly_cgroup_procs_total{path="%s",subsystem="cpu"} 1 +gitaly_cgroup_procs_total{path="%s",subsystem="memory"} 1 +# HELP gitaly_cgroup_cpu_cfs_periods_total Number of elapsed enforcement period intervals +# TYPE gitaly_cgroup_cpu_cfs_periods_total counter +gitaly_cgroup_cpu_cfs_periods_total{path="%s"} 10 +# HELP gitaly_cgroup_cpu_cfs_throttled_periods_total Number of throttled period intervals +# TYPE gitaly_cgroup_cpu_cfs_throttled_periods_total counter +gitaly_cgroup_cpu_cfs_throttled_periods_total{path="%s"} 20 +# HELP gitaly_cgroup_cpu_cfs_throttled_seconds_total Total time duration the Cgroup has been throttled +# TYPE gitaly_cgroup_cpu_cfs_throttled_seconds_total counter +gitaly_cgroup_cpu_cfs_throttled_seconds_total{path="%s"} 0.001 +`, + expectV2: `# HELP gitaly_cgroup_cpu_cfs_periods_total Number of elapsed enforcement period intervals +# TYPE gitaly_cgroup_cpu_cfs_periods_total counter +gitaly_cgroup_cpu_cfs_periods_total{path="%s"} 10 +# HELP gitaly_cgroup_cpu_cfs_throttled_periods_total Number of throttled period intervals +# TYPE gitaly_cgroup_cpu_cfs_throttled_periods_total counter +gitaly_cgroup_cpu_cfs_throttled_periods_total{path="%s"} 20 +# HELP gitaly_cgroup_cpu_cfs_throttled_seconds_total Total time duration the Cgroup has been throttled +# TYPE gitaly_cgroup_cpu_cfs_throttled_seconds_total counter +gitaly_cgroup_cpu_cfs_throttled_seconds_total{path="%s"} 0.001 +# HELP gitaly_cgroup_cpu_usage_total CPU Usage of Cgroup +# TYPE gitaly_cgroup_cpu_usage_total gauge +gitaly_cgroup_cpu_usage_total{path="%s",type="kernel"} 0 +gitaly_cgroup_cpu_usage_total{path="%s",type="user"} 0 +# HELP gitaly_cgroup_procs_total Total number of procs +# TYPE gitaly_cgroup_procs_total gauge +gitaly_cgroup_procs_total{path="%s",subsystem="cpu"} 1 +gitaly_cgroup_procs_total{path="%s",subsystem="cpuset"} 1 +gitaly_cgroup_procs_total{path="%s",subsystem="memory"} 1 +`, + }, + { + name: "metrics enabled: false", + metricsEnabled: false, + pid: 2, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + for _, version := range []int{1, 2} { + version := version + t.Run("cgroups-v"+strconv.Itoa(version), func(t *testing.T) { + t.Parallel() + mock := newMock(t, version) + + config := defaultCgroupsConfig() + config.Repositories.Count = 1 + config.Repositories.MemoryBytes = 1048576 + config.Repositories.CPUShares = 16 + config.Mountpoint = mock.rootPath() + config.MetricsEnabled = tt.metricsEnabled + + manager1 := mock.newCgroupManager(config, testhelper.SharedLogger(t), tt.pid) + + var mockFiles []mockCgroupFile + if version == 1 { + mockFiles = append(mockFiles, mockCgroupFile{"memory.failcnt", "2"}) + } + mock.setupMockCgroupFiles(t, manager1, []uint{0}, mockFiles...) + require.NoError(t, manager1.Setup()) + + ctx := testhelper.Context(t) + + cmd := exec.CommandContext(ctx, cmdArgs[0], cmdArgs[1:]...) + require.NoError(t, cmd.Start()) + _, err := manager1.AddCommand(cmd) + require.NoError(t, err) + + gitCmd1 := exec.CommandContext(ctx, cmdArgs[0], cmdArgs[1:]...) + require.NoError(t, gitCmd1.Start()) + _, err = manager1.AddCommand(gitCmd1) + require.NoError(t, err) + + gitCmd2 := exec.CommandContext(ctx, cmdArgs[0], cmdArgs[1:]...) + require.NoError(t, gitCmd2.Start()) + _, err = manager1.AddCommand(gitCmd2) + require.NoError(t, err) + defer func() { + require.NoError(t, gitCmd2.Wait()) + }() + + require.NoError(t, cmd.Wait()) + require.NoError(t, gitCmd1.Wait()) + + repoCgroupPath := filepath.Join(manager1.currentProcessCgroup(), "repos-0") + + var expected *strings.Reader + if version == 1 { + expected = strings.NewReader(strings.ReplaceAll(tt.expectV1, "%s", repoCgroupPath)) + } else { + expected = strings.NewReader(strings.ReplaceAll(tt.expectV2, "%s", repoCgroupPath)) + } + assert.NoError(t, testutil.CollectAndCompare(manager1, expected)) + }) + } + }) + } +} + func requireCgroupComponents(t *testing.T, version int, root string, cgroupPath string, expected expectedCgroup) { t.Helper() diff --git a/internal/cgroups/v1_linux_test.go b/internal/cgroups/v1_linux_test.go index 25c835dcf..35f156354 100644 --- a/internal/cgroups/v1_linux_test.go +++ b/internal/cgroups/v1_linux_test.go @@ -9,11 +9,8 @@ import ( "os/exec" "path/filepath" "strconv" - "strings" "testing" - "github.com/prometheus/client_golang/prometheus/testutil" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/config/cgroups" "gitlab.com/gitlab-org/gitaly/v16/internal/helper/perm" @@ -33,100 +30,6 @@ func defaultCgroupsConfig() cgroups.Config { } } -func TestMetrics(t *testing.T) { - tests := []struct { - name string - metricsEnabled bool - pid int - expect string - }{ - { - name: "metrics enabled: true", - metricsEnabled: true, - pid: 1, - expect: `# HELP gitaly_cgroup_cpu_usage_total CPU Usage of Cgroup -# TYPE gitaly_cgroup_cpu_usage_total gauge -gitaly_cgroup_cpu_usage_total{path="%s",type="kernel"} 0 -gitaly_cgroup_cpu_usage_total{path="%s",type="user"} 0 -# HELP gitaly_cgroup_memory_reclaim_attempts_total Number of memory usage hits limits -# TYPE gitaly_cgroup_memory_reclaim_attempts_total gauge -gitaly_cgroup_memory_reclaim_attempts_total{path="%s"} 2 -# HELP gitaly_cgroup_procs_total Total number of procs -# TYPE gitaly_cgroup_procs_total gauge -gitaly_cgroup_procs_total{path="%s",subsystem="cpu"} 1 -gitaly_cgroup_procs_total{path="%s",subsystem="memory"} 1 -# HELP gitaly_cgroup_cpu_cfs_periods_total Number of elapsed enforcement period intervals -# TYPE gitaly_cgroup_cpu_cfs_periods_total counter -gitaly_cgroup_cpu_cfs_periods_total{path="%s"} 10 -# HELP gitaly_cgroup_cpu_cfs_throttled_periods_total Number of throttled period intervals -# TYPE gitaly_cgroup_cpu_cfs_throttled_periods_total counter -gitaly_cgroup_cpu_cfs_throttled_periods_total{path="%s"} 20 -# HELP gitaly_cgroup_cpu_cfs_throttled_seconds_total Total time duration the Cgroup has been throttled -# TYPE gitaly_cgroup_cpu_cfs_throttled_seconds_total counter -gitaly_cgroup_cpu_cfs_throttled_seconds_total{path="%s"} 0.001 -`, - }, - { - name: "metrics enabled: false", - metricsEnabled: false, - pid: 2, - }, - } - - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(t *testing.T) { - t.Parallel() - mock := newMockV1(t) - - config := defaultCgroupsConfig() - config.Repositories.Count = 1 - config.Repositories.MemoryBytes = 1048576 - config.Repositories.CPUShares = 16 - config.Mountpoint = mock.root - config.MetricsEnabled = tt.metricsEnabled - - v1Manager1 := mock.newCgroupManager(config, testhelper.SharedLogger(t), tt.pid) - - groupID := calcGroupID(cmdArgs, config.Repositories.Count) - - mock.setupMockCgroupFiles(t, v1Manager1, []uint{groupID}, mockCgroupFile{"memory.failcnt", "2"}) - require.NoError(t, v1Manager1.Setup()) - - ctx := testhelper.Context(t) - - cmd := exec.CommandContext(ctx, cmdArgs[0], cmdArgs[1:]...) - require.NoError(t, cmd.Start()) - _, err := v1Manager1.AddCommand(cmd) - require.NoError(t, err) - - gitCmd1 := exec.CommandContext(ctx, cmdArgs[0], cmdArgs[1:]...) - require.NoError(t, gitCmd1.Start()) - _, err = v1Manager1.AddCommand(gitCmd1) - require.NoError(t, err) - - gitCmd2 := exec.CommandContext(ctx, cmdArgs[0], cmdArgs[1:]...) - require.NoError(t, gitCmd2.Start()) - _, err = v1Manager1.AddCommand(gitCmd2) - require.NoError(t, err) - - requireShardsV1(t, mock, v1Manager1, tt.pid, groupID) - - defer func() { - require.NoError(t, gitCmd2.Wait()) - }() - - require.NoError(t, cmd.Wait()) - require.NoError(t, gitCmd1.Wait()) - - repoCgroupPath := filepath.Join(v1Manager1.currentProcessCgroup(), "repos-0") - - expected := strings.NewReader(strings.ReplaceAll(tt.expect, "%s", repoCgroupPath)) - assert.NoError(t, testutil.CollectAndCompare(v1Manager1, expected)) - }) - } -} - func TestPruneOldCgroups(t *testing.T) { t.Parallel() diff --git a/internal/cgroups/v2_linux_test.go b/internal/cgroups/v2_linux_test.go index f1cb82d28..0c89f9aee 100644 --- a/internal/cgroups/v2_linux_test.go +++ b/internal/cgroups/v2_linux_test.go @@ -9,11 +9,8 @@ import ( "os/exec" "path/filepath" "strconv" - "strings" "testing" - "github.com/prometheus/client_golang/prometheus/testutil" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/config/cgroups" "gitlab.com/gitlab-org/gitaly/v16/internal/helper/perm" @@ -33,98 +30,6 @@ func defaultCgroupsV2Config() cgroups.Config { } } -func TestMetricsV2(t *testing.T) { - tests := []struct { - name string - metricsEnabled bool - pid int - expect string - }{ - { - name: "metrics enabled: true", - metricsEnabled: true, - pid: 1, - expect: `# HELP gitaly_cgroup_cpu_cfs_periods_total Number of elapsed enforcement period intervals -# TYPE gitaly_cgroup_cpu_cfs_periods_total counter -gitaly_cgroup_cpu_cfs_periods_total{path="%s"} 10 -# HELP gitaly_cgroup_cpu_cfs_throttled_periods_total Number of throttled period intervals -# TYPE gitaly_cgroup_cpu_cfs_throttled_periods_total counter -gitaly_cgroup_cpu_cfs_throttled_periods_total{path="%s"} 20 -# HELP gitaly_cgroup_cpu_cfs_throttled_seconds_total Total time duration the Cgroup has been throttled -# TYPE gitaly_cgroup_cpu_cfs_throttled_seconds_total counter -gitaly_cgroup_cpu_cfs_throttled_seconds_total{path="%s"} 0.001 -# HELP gitaly_cgroup_cpu_usage_total CPU Usage of Cgroup -# TYPE gitaly_cgroup_cpu_usage_total gauge -gitaly_cgroup_cpu_usage_total{path="%s",type="kernel"} 0 -gitaly_cgroup_cpu_usage_total{path="%s",type="user"} 0 -# HELP gitaly_cgroup_procs_total Total number of procs -# TYPE gitaly_cgroup_procs_total gauge -gitaly_cgroup_procs_total{path="%s",subsystem="cpu"} 1 -gitaly_cgroup_procs_total{path="%s",subsystem="cpuset"} 1 -gitaly_cgroup_procs_total{path="%s",subsystem="memory"} 1 -`, - }, - { - name: "metrics enabled: false", - metricsEnabled: false, - pid: 2, - }, - } - - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(t *testing.T) { - t.Parallel() - mock := newMockV2(t) - - config := defaultCgroupsV2Config() - config.Repositories.Count = 1 - config.Repositories.MemoryBytes = 1048576 - config.Repositories.CPUShares = 16 - config.Mountpoint = mock.root - config.MetricsEnabled = tt.metricsEnabled - - groupID := calcGroupID(cmdArgs, config.Repositories.Count) - v2Manager1 := mock.newCgroupManager(config, testhelper.SharedLogger(t), tt.pid) - - mock.setupMockCgroupFiles(t, v2Manager1, []uint{groupID}) - require.NoError(t, v2Manager1.Setup()) - - ctx := testhelper.Context(t) - - cmd := exec.CommandContext(ctx, cmdArgs[0], cmdArgs[1:]...) - require.NoError(t, cmd.Start()) - _, err := v2Manager1.AddCommand(cmd) - require.NoError(t, err) - - gitCmd1 := exec.CommandContext(ctx, cmdArgs[0], cmdArgs[1:]...) - require.NoError(t, gitCmd1.Start()) - _, err = v2Manager1.AddCommand(gitCmd1) - require.NoError(t, err) - - gitCmd2 := exec.CommandContext(ctx, cmdArgs[0], cmdArgs[1:]...) - require.NoError(t, gitCmd2.Start()) - _, err = v2Manager1.AddCommand(gitCmd2) - require.NoError(t, err) - - requireShardsV2(t, mock, v2Manager1, tt.pid, groupID) - - defer func() { - require.NoError(t, gitCmd2.Wait()) - }() - - require.NoError(t, cmd.Wait()) - require.NoError(t, gitCmd1.Wait()) - - repoCgroupPath := filepath.Join(v2Manager1.currentProcessCgroup(), "repos-0") - - expected := strings.NewReader(strings.ReplaceAll(tt.expect, "%s", repoCgroupPath)) - - assert.NoError(t, testutil.CollectAndCompare(v2Manager1, expected)) - }) - } -} - func TestPruneOldCgroupsV2(t *testing.T) { t.Parallel() |