-
Notifications
You must be signed in to change notification settings - Fork 435
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add cgroups v2 support to resourcemanager #1744
Changes from all commits
5c1d6c7
0009f06
232ded2
42a4693
7146e9e
bace811
33f6343
89acabd
a007e25
325566f
56a6f11
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,29 +6,28 @@ package resourcemanager | |
import ( | ||
"fmt" | ||
"os" | ||
"regexp" | ||
"testing" | ||
) | ||
|
||
func updateFakeCgroupv1Files(c *cgroupsV1MemoryLimitChecker, limit, usage, inactive int) error { | ||
limitFile, err := os.Create(c.limitFile) | ||
func updateFakeCgroupFiles(c *cgroupsMemoryLimitChecker, limit, usage, inactive int) error { | ||
limitFile, err := os.Create(c.files.limitFile) | ||
if err != nil { | ||
return err | ||
} | ||
_, err = fmt.Fprintf(limitFile, "%d\n", limit) | ||
if err != nil { | ||
if _, err = fmt.Fprintf(limitFile, "%d\n", limit); err != nil { | ||
return err | ||
} | ||
|
||
usageFile, err := os.Create(c.usageFile) | ||
usageFile, err := os.Create(c.files.usageFile) | ||
if err != nil { | ||
return err | ||
} | ||
_, err = fmt.Fprintf(usageFile, "%d\n", usage) | ||
if err != nil { | ||
if _, err = fmt.Fprintf(usageFile, "%d\n", usage); err != nil { | ||
return err | ||
} | ||
|
||
statsFile, err := os.Create(c.statsFile) | ||
statsFile, err := os.Create(c.files.statsFile) | ||
if err != nil { | ||
return err | ||
} | ||
|
@@ -37,42 +36,57 @@ total_rss 1016209408 | |
total_inactive_file %d | ||
total_active_file 321544192 | ||
`, inactive) | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
return err | ||
} | ||
|
||
func TestCgroupsv1MemoryLimit(t *testing.T) { | ||
cgroupDir := t.TempDir() | ||
c := newCgroupsV1MemoryLimitChecker(cgroupDir, 95) | ||
_, err := c.isLimitExceeded() | ||
if err == nil { | ||
t.Error("Should fail open if can't read files") | ||
func makeCgroupsTestDir(cgroupDir string) cgroupsMemoryFiles { | ||
return cgroupsMemoryFiles{ | ||
limitFile: cgroupDir + "/memory.limit_in_bytes", | ||
usageFile: cgroupDir + "/memory.usage_in_bytes", | ||
statsFile: cgroupDir + "/memory.stat", | ||
inactiveRe: regexp.MustCompile(`total_inactive_file (\d+)`), | ||
} | ||
} | ||
|
||
err = updateFakeCgroupv1Files(c, 1000, 1000, 51) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
exceeded, err := c.isLimitExceeded() | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
if exceeded { | ||
t.Error("Expected under limit") | ||
func TestCgroupsFailIfCantOpen(t *testing.T) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
You can either also have TestCgroupsFailIfCantOpen as another case in the test, or leave as is. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can see examples of table-driven tests at: https://github.com/OffchainLabs/nitro/blob/ac0a2de65e86b008ff10ded1f7b003ca01737315/arbnode/dataposter/storage_test.go There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, I'll use this pattern more often. Took your code largely as suggested. |
||
testFiles := makeCgroupsTestDir(t.TempDir()) | ||
c := newCgroupsMemoryLimitChecker(testFiles, 95) | ||
if _, err := c.isLimitExceeded(); err == nil { | ||
t.Fatal("Should fail open if can't read files") | ||
} | ||
} | ||
|
||
err = updateFakeCgroupv1Files(c, 1000, 1000, 50) | ||
if err != nil { | ||
t.Error(err) | ||
func TestCgroupsMemoryLimit(t *testing.T) { | ||
for _, tc := range []struct { | ||
desc string | ||
inactive int | ||
want bool | ||
}{ | ||
{ | ||
desc: "limit should be exceeded", | ||
inactive: 50, | ||
want: true, | ||
}, | ||
{ | ||
desc: "limit should not be exceeded", | ||
inactive: 51, | ||
want: false, | ||
}, | ||
} { | ||
t.Run(tc.desc, func(t *testing.T) { | ||
testFiles := makeCgroupsTestDir(t.TempDir()) | ||
c := newCgroupsMemoryLimitChecker(testFiles, 95) | ||
if err := updateFakeCgroupFiles(c, 1000, 1000, tc.inactive); err != nil { | ||
t.Fatalf("Updating cgroup files: %v", err) | ||
} | ||
exceeded, err := c.isLimitExceeded() | ||
if err != nil { | ||
t.Fatalf("Checking if limit exceeded: %v", err) | ||
} | ||
if exceeded != tc.want { | ||
t.Errorf("isLimitExceeded() = %t, want %t", exceeded, tc.want) | ||
} | ||
}, | ||
) | ||
} | ||
exceeded, err = c.isLimitExceeded() | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
if !exceeded { | ||
t.Error("Expected over limit") | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: go tends to encourage shorter names. You can drop "IfSupported" suffix and just add in the comment above the function that this returns errNotSupported if it's not supported.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what to rename it to since
newCgroupsMemoryLimitChecker
is already the factory method for theCgroupsMemoryLimitChecker
and this version handles auto-detecting cgroups v1 or v2.