-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathoom_suite.go
More file actions
92 lines (73 loc) · 2.81 KB
/
Copy pathoom_suite.go
File metadata and controls
92 lines (73 loc) · 2.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*
Copyright The containerd 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 shimtest
import (
"syscall"
"testing"
taskAPI "github.com/containerd/containerd/api/runtime/task/v3"
"github.com/containerd/containerd/v2/pkg/namespaces"
"github.com/containerd/ttrpc"
)
// OOMSuite contains the OOM-killer test, gated on the "oom" feature
// (some shim configurations don't expose memory cgroup controls or
// can't reliably trigger the kernel OOM killer).
type OOMSuite struct {
cfg Config
}
// NewOOMSuite constructs an OOMSuite from the given options.
func NewOOMSuite(cfg Config) *OOMSuite {
return &OOMSuite{cfg: cfg}
}
// Run runs every test in the suite as a subtest of t.
func (s *OOMSuite) Run(t *testing.T) {
t.Helper()
registerShimLeakCheck(t, s.cfg.ShimBinary)
t.Run("OOM", s.testOOM)
}
// TestOOM runs a memory-hungry process inside a container with a
// 128MiB memory limit and verifies the kernel OOM-kills it (exit 137).
func (s *OOMSuite) testOOM(t *testing.T) {
shimBin, bundleDir, rootfsMounts := shimSetup(t, s.cfg)
containerID := containerID(t)
createOCISpec(t, bundleDir, []string{"/bin/memhog"}, s.cfg,
withMemoryLimit(128*1024*1024),
)
stdoutPath, stderrPath := createIOFifos(t, bundleDir)
ns := uniqueTestNamespace(t, "oom")
ctx := namespaces.WithNamespace(t.Context(), ns)
params := startShim(t, shimBin, bundleDir, containerID, ns, s.cfg)
conn := connectShim(t, params.Address)
client := ttrpc.NewClient(conn)
defer client.Close()
tc := newTaskClient(client, params.Version)
drainFifo(t, ctx, stdoutPath)
drainFifo(t, ctx, stderrPath)
if _, err := tc.Create(ctx, newCreateTaskRequest(t, containerID, bundleDir, stdoutPath, stderrPath, rootfsMounts)); err != nil {
t.Fatal("create failed:", err)
}
if _, err := tc.Start(ctx, &taskAPI.StartRequest{ID: containerID}); err != nil {
t.Fatal("start failed:", err)
}
waitResp, err := tc.Wait(ctx, &taskAPI.WaitRequest{ID: containerID})
if err != nil {
t.Fatal("wait failed:", err)
}
t.Log("task exit status:", waitResp.ExitStatus)
const sigkillExit = 128 + uint32(syscall.SIGKILL)
if waitResp.ExitStatus != sigkillExit {
t.Fatalf("expected exit status %d (SIGKILL from OOM killer), got %d",
sigkillExit, waitResp.ExitStatus)
}
tc.Delete(ctx, &taskAPI.DeleteRequest{ID: containerID})
shutdownTask(ctx, tc, containerID)
}