diff --git a/validation/linux_cgroups_hugetlb.go b/validation/linux_cgroups_hugetlb.go index e7ba27513..9aeb63d7f 100644 --- a/validation/linux_cgroups_hugetlb.go +++ b/validation/linux_cgroups_hugetlb.go @@ -2,38 +2,103 @@ package main import ( "fmt" + "runtime" + "github.com/mndrix/tap-go" rspec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-tools/cgroups" "github.com/opencontainers/runtime-tools/validation/util" ) -func main() { - page := "1GB" - var limit uint64 = 52985 * 1024 * 1024 * 1024 // multiple of hugepage size - g, err := util.GetDefaultGenerator() - if err != nil { - util.Fatal(err) +func testHugetlbCgroups() error { + // limit =~ 100 * page size + // NOTE: on some systems, pagesize "1GB" doesn't seem to work. + // Ideally we should auto-detect the value. + cases := []struct { + page string + limit uint64 + }{ + {"2MB", 100 * 2 * 1024 * 1024}, + {"1GB", 100 * 1024 * 1024 * 1024}, + {"2MB", 100 * 2 * 1024 * 1024}, + {"1GB", 100 * 1024 * 1024 * 1024}, } - g.SetLinuxCgroupsPath(cgroups.AbsCgroupPath) - g.AddLinuxResourcesHugepageLimit(page, limit) - err = util.RuntimeOutsideValidate(g, func(config *rspec.Spec, state *rspec.State) error { - cg, err := cgroups.FindCgroup() + + for _, c := range cases { + g, err := util.GetDefaultGenerator() if err != nil { return err } - lhd, err := cg.GetHugepageLimitData(state.Pid, config.Linux.CgroupsPath) + g.SetLinuxCgroupsPath(cgroups.AbsCgroupPath) + g.AddLinuxResourcesHugepageLimit(c.page, c.limit) + err = util.RuntimeOutsideValidate(g, func(config *rspec.Spec, state *rspec.State) error { + t := tap.New() + t.Header(0) + defer t.AutoPlan() + + cg, err := cgroups.FindCgroup() + if err != nil { + return err + } + lhd, err := cg.GetHugepageLimitData(state.Pid, config.Linux.CgroupsPath) + if err != nil { + return err + } + for _, lhl := range lhd { + if lhl.Pagesize != c.page { + continue + } + t.Ok(lhl.Limit == c.limit, "hugepage limit is set correctly") + t.Diagnosticf("expect: %d, actual: %d", c.limit, lhl.Limit) + } + return nil + }) if err != nil { return err } - for _, lhl := range lhd { - if lhl.Pagesize == page && lhl.Limit != limit { - return fmt.Errorf("hugepage %s limit is not set correctly, expect: %d, actual: %d", page, limit, lhl.Limit) - } - } + } + + return nil +} + +func testWrongHugetlb() error { + // We deliberately set the page size to a wrong value, "3MB", to see + // if the container really returns an error. + page := "3MB" + var limit uint64 = 100 * 3 * 1024 * 1024 + + g, err := util.GetDefaultGenerator() + if err != nil { + return err + } + + t := tap.New() + t.Header(0) + defer t.AutoPlan() + + g.SetLinuxCgroupsPath(cgroups.AbsCgroupPath) + g.AddLinuxResourcesHugepageLimit(page, limit) + + err = util.RuntimeOutsideValidate(g, func(config *rspec.Spec, state *rspec.State) error { return nil }) - if err != nil { + t.Ok(err != nil, "hugepage invalid pagesize results in an errror") + if err == nil { + t.Diagnosticf("expect: err != nil, actual: err == nil") + } + return err +} + +func main() { + if "linux" != runtime.GOOS { + util.Fatal(fmt.Errorf("linux-specific cgroup test")) + } + + if err := testHugetlbCgroups(); err != nil { + util.Fatal(err) + } + + if err := testWrongHugetlb(); err == nil { util.Fatal(err) } }