blob: d7328f973c0c38be88602d7a9641a325253c889d [file]
// Licensed to Apache Software Foundation (ASF) under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Apache Software Foundation (ASF) licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package cgroups
import (
"errors"
"io/fs"
"testing"
"testing/fstest"
)
func TestGetCgroupMemoryLimit(t *testing.T) {
tests := []struct {
fs fs.FS
expectedError error
name string
expectedLimit int64
}{
{
name: "cgroup v1 with explicit memory limit",
fs: fstest.MapFS{
"proc/self/cgroup": &fstest.MapFile{
Data: []byte("0::/user.slice/user-1000.slice/session-1.scope\n1:memory:/user.slice/user-1000.slice/session-1.scope"),
},
"proc/self/mountinfo": &fstest.MapFile{
Data: []byte("36 35 0:33 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime shared:18 - cgroup cgroup rw,memory"),
},
"sys/fs/cgroup/memory/user.slice/user-1000.slice/session-1.scope/memory.limit_in_bytes": &fstest.MapFile{
Data: []byte("1073741824"),
},
"sys/fs/cgroup/memory/user.slice/user-1000.slice/session-1.scope/memory.hierarchical_memory_limit": &fstest.MapFile{
Data: []byte("1073741824"),
},
},
expectedLimit: 1073741824,
expectedError: nil,
},
{
name: "cgroup v1 with inherited memory limit",
fs: fstest.MapFS{
"proc/self/cgroup": &fstest.MapFile{
Data: []byte("0::/user.slice/user-1000.slice/session-1.scope\n1:memory:/user.slice/user-1000.slice/session-1.scope"),
},
"proc/self/mountinfo": &fstest.MapFile{
Data: []byte("36 35 0:33 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime shared:18 - cgroup cgroup rw,memory"),
},
"sys/fs/cgroup/memory/user.slice/user-1000.slice/session-1.scope/memory.limit_in_bytes": &fstest.MapFile{
Data: []byte("9223372036854771712"), // Very high value
},
"sys/fs/cgroup/memory/user.slice/user-1000.slice/session-1.scope/memory.hierarchical_memory_limit": &fstest.MapFile{
Data: []byte("536870912"),
},
},
expectedLimit: 536870912,
expectedError: nil,
},
{
name: "cgroup v2 with explicit memory limit",
fs: fstest.MapFS{
"proc/self/cgroup": &fstest.MapFile{
Data: []byte("0::/user.slice/user-1000.slice/session-1.scope"),
},
"proc/self/mountinfo": &fstest.MapFile{
Data: []byte("36 35 0:33 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime shared:18 - cgroup2 cgroup rw"),
},
"sys/fs/cgroup/user.slice/user-1000.slice/session-1.scope/memory.max": &fstest.MapFile{
Data: []byte("2147483648"),
},
},
expectedLimit: 2147483648,
expectedError: nil,
},
{
name: "cgroup v2 with unlimited memory",
fs: fstest.MapFS{
"proc/self/cgroup": &fstest.MapFile{
Data: []byte("0::/user.slice/user-1000.slice/session-1.scope"),
},
"proc/self/mountinfo": &fstest.MapFile{
Data: []byte("36 35 0:33 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime shared:18 - cgroup2 cgroup rw"),
},
"sys/fs/cgroup/user.slice/user-1000.slice/session-1.scope/memory.max": &fstest.MapFile{
Data: []byte("max"),
},
},
expectedLimit: -1,
expectedError: nil,
},
{
name: "missing cgroup file",
fs: fstest.MapFS{
"proc/self/cgroup": &fstest.MapFile{
Data: []byte("0::/user.slice/user-1000.slice/session-1.scope"),
},
"proc/self/mountinfo": &fstest.MapFile{
Data: []byte("36 35 0:33 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime shared:18 - cgroup2 cgroup rw"),
},
},
expectedLimit: 0,
expectedError: errors.New("failed to read memory limit"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
limit, err := getCgroupMemoryLimit(tt.fs)
if err != nil && tt.expectedError == nil {
t.Fatalf("unexpected error: %v", err)
}
if err == nil && tt.expectedError != nil {
t.Fatalf("expected error: %v, got nil", tt.expectedError)
}
if limit != tt.expectedLimit {
t.Fatalf("expected limit: %d, got: %d", tt.expectedLimit, limit)
}
})
}
}