diff options
Diffstat (limited to 'test/root')
-rw-r--r-- | test/root/cgroup_test.go | 54 | ||||
-rw-r--r-- | test/root/crictl_test.go | 53 | ||||
-rw-r--r-- | test/root/oom_score_adj_test.go | 28 | ||||
-rw-r--r-- | test/root/testdata/BUILD | 1 | ||||
-rw-r--r-- | test/root/testdata/simple.go | 41 |
5 files changed, 168 insertions, 9 deletions
diff --git a/test/root/cgroup_test.go b/test/root/cgroup_test.go index 76f1e4f2a..4038661cb 100644 --- a/test/root/cgroup_test.go +++ b/test/root/cgroup_test.go @@ -24,6 +24,7 @@ import ( "strconv" "strings" "testing" + "time" "gvisor.dev/gvisor/runsc/cgroup" "gvisor.dev/gvisor/runsc/dockerutil" @@ -56,6 +57,59 @@ func verifyPid(pid int, path string) error { } // TestCgroup sets cgroup options and checks that cgroup was properly configured. +func TestMemCGroup(t *testing.T) { + allocMemSize := 128 << 20 + if err := dockerutil.Pull("python"); err != nil { + t.Fatal("docker pull failed:", err) + } + d := dockerutil.MakeDocker("memusage-test") + + // Start a new container and allocate the specified about of memory. + args := []string{ + "--memory=256MB", + "python", + "python", + "-c", + fmt.Sprintf("import time; s = 'a' * %d; time.sleep(100)", allocMemSize), + } + if err := d.Run(args...); err != nil { + t.Fatal("docker create failed:", err) + } + defer d.CleanUp() + + gid, err := d.ID() + if err != nil { + t.Fatalf("Docker.ID() failed: %v", err) + } + t.Logf("cgroup ID: %s", gid) + + path := filepath.Join("/sys/fs/cgroup/memory/docker", gid, "memory.usage_in_bytes") + memUsage := 0 + + // Wait when the container will allocate memory. + start := time.Now() + for time.Now().Sub(start) < 30*time.Second { + outRaw, err := ioutil.ReadFile(path) + if err != nil { + t.Fatalf("failed to read %q: %v", path, err) + } + out := strings.TrimSpace(string(outRaw)) + memUsage, err = strconv.Atoi(out) + if err != nil { + t.Fatalf("Atoi(%v): %v", out, err) + } + + if memUsage > allocMemSize { + return + } + + time.Sleep(100 * time.Millisecond) + } + + t.Fatalf("%vMB is less than %vMB: %v", memUsage>>20, allocMemSize>>20) +} + +// TestCgroup sets cgroup options and checks that cgroup was properly configured. func TestCgroup(t *testing.T) { if err := dockerutil.Pull("alpine"); err != nil { t.Fatal("docker pull failed:", err) diff --git a/test/root/crictl_test.go b/test/root/crictl_test.go index d597664f5..3f90c4c6a 100644 --- a/test/root/crictl_test.go +++ b/test/root/crictl_test.go @@ -126,6 +126,59 @@ func TestMountOverSymlinks(t *testing.T) { } } +// TestHomeDir tests that the HOME environment variable is set for +// multi-containers. +func TestHomeDir(t *testing.T) { + // Setup containerd and crictl. + crictl, cleanup, err := setup(t) + if err != nil { + t.Fatalf("failed to setup crictl: %v", err) + } + defer cleanup() + contSpec := testdata.SimpleSpec("root", "k8s.gcr.io/busybox", []string{"sleep", "1000"}) + podID, contID, err := crictl.StartPodAndContainer("k8s.gcr.io/busybox", testdata.Sandbox, contSpec) + if err != nil { + t.Fatal(err) + } + + t.Run("root container", func(t *testing.T) { + out, err := crictl.Exec(contID, "sh", "-c", "echo $HOME") + if err != nil { + t.Fatal(err) + } + if got, want := strings.TrimSpace(string(out)), "/root"; got != want { + t.Fatalf("Home directory invalid. Got %q, Want : %q", got, want) + } + }) + + t.Run("sub-container", func(t *testing.T) { + // Create a sub container in the same pod. + subContSpec := testdata.SimpleSpec("subcontainer", "k8s.gcr.io/busybox", []string{"sleep", "1000"}) + subContID, err := crictl.StartContainer(podID, "k8s.gcr.io/busybox", testdata.Sandbox, subContSpec) + if err != nil { + t.Fatal(err) + } + + out, err := crictl.Exec(subContID, "sh", "-c", "echo $HOME") + if err != nil { + t.Fatal(err) + } + if got, want := strings.TrimSpace(string(out)), "/root"; got != want { + t.Fatalf("Home directory invalid. Got %q, Want: %q", got, want) + } + + if err := crictl.StopContainer(subContID); err != nil { + t.Fatal(err) + } + }) + + // Stop everything. + if err := crictl.StopPodAndContainer(podID, contID); err != nil { + t.Fatal(err) + } + +} + // setup sets up before a test. Specifically it: // * Creates directories and a socket for containerd to utilize. // * Runs containerd and waits for it to reach a "ready" state for testing. diff --git a/test/root/oom_score_adj_test.go b/test/root/oom_score_adj_test.go index 6cd378a1b..126f0975a 100644 --- a/test/root/oom_score_adj_test.go +++ b/test/root/oom_score_adj_test.go @@ -40,6 +40,15 @@ var ( // TestOOMScoreAdjSingle tests that oom_score_adj is set properly in a // single container sandbox. func TestOOMScoreAdjSingle(t *testing.T) { + rootDir, err := testutil.SetupRootDir() + if err != nil { + t.Fatalf("error creating root dir: %v", err) + } + defer os.RemoveAll(rootDir) + + conf := testutil.TestConfig() + conf.RootDir = rootDir + ppid, err := specutils.GetParentPid(os.Getpid()) if err != nil { t.Fatalf("getting parent pid: %v", err) @@ -84,7 +93,6 @@ func TestOOMScoreAdjSingle(t *testing.T) { s := testutil.NewSpecWithArgs("sleep", "1000") s.Process.OOMScoreAdj = testCase.OOMScoreAdj - conf := testutil.TestConfig() containers, cleanup, err := startContainers(conf, []*specs.Spec{s}, []string{id}) if err != nil { t.Fatalf("error starting containers: %v", err) @@ -123,6 +131,15 @@ func TestOOMScoreAdjSingle(t *testing.T) { // TestOOMScoreAdjMulti tests that oom_score_adj is set properly in a // multi-container sandbox. func TestOOMScoreAdjMulti(t *testing.T) { + rootDir, err := testutil.SetupRootDir() + if err != nil { + t.Fatalf("error creating root dir: %v", err) + } + defer os.RemoveAll(rootDir) + + conf := testutil.TestConfig() + conf.RootDir = rootDir + ppid, err := specutils.GetParentPid(os.Getpid()) if err != nil { t.Fatalf("getting parent pid: %v", err) @@ -240,7 +257,6 @@ func TestOOMScoreAdjMulti(t *testing.T) { } } - conf := testutil.TestConfig() containers, cleanup, err := startContainers(conf, specs, ids) if err != nil { t.Fatalf("error starting containers: %v", err) @@ -327,13 +343,8 @@ func createSpecs(cmds ...[]string) ([]*specs.Spec, []string) { } func startContainers(conf *boot.Config, specs []*specs.Spec, ids []string) ([]*container.Container, func(), error) { - // Setup root dir if one hasn't been provided. if len(conf.RootDir) == 0 { - rootDir, err := testutil.SetupRootDir() - if err != nil { - return nil, nil, fmt.Errorf("error creating root dir: %v", err) - } - conf.RootDir = rootDir + panic("conf.RootDir not set. Call testutil.SetupRootDir() to set.") } var containers []*container.Container @@ -345,7 +356,6 @@ func startContainers(conf *boot.Config, specs []*specs.Spec, ids []string) ([]*c for _, b := range bundles { os.RemoveAll(b) } - os.RemoveAll(conf.RootDir) } for i, spec := range specs { bundleDir, err := testutil.SetupBundleDir(spec) diff --git a/test/root/testdata/BUILD b/test/root/testdata/BUILD index 14c19ef1e..125633680 100644 --- a/test/root/testdata/BUILD +++ b/test/root/testdata/BUILD @@ -10,6 +10,7 @@ go_library( "httpd.go", "httpd_mount_paths.go", "sandbox.go", + "simple.go", ], importpath = "gvisor.dev/gvisor/test/root/testdata", visibility = [ diff --git a/test/root/testdata/simple.go b/test/root/testdata/simple.go new file mode 100644 index 000000000..1cca53f0c --- /dev/null +++ b/test/root/testdata/simple.go @@ -0,0 +1,41 @@ +// Copyright 2018 The gVisor Authors. +// +// Licensed 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 testdata + +import ( + "encoding/json" + "fmt" +) + +// SimpleSpec returns a JSON config for a simple container that runs the +// specified command in the specified image. +func SimpleSpec(name, image string, cmd []string) string { + cmds, err := json.Marshal(cmd) + if err != nil { + // This shouldn't happen. + panic(err) + } + return fmt.Sprintf(` +{ + "metadata": { + "name": %q + }, + "image": { + "image": %q + }, + "command": %s + } +`, name, image, cmds) +} |