|
@@ -11,6 +11,9 @@ import (
|
|
|
containertypes "github.com/docker/docker/api/types/container"
|
|
|
"github.com/docker/docker/container"
|
|
|
"github.com/docker/docker/daemon/config"
|
|
|
+ "github.com/docker/docker/pkg/sysinfo"
|
|
|
+ "gotest.tools/assert"
|
|
|
+ is "gotest.tools/assert/cmp"
|
|
|
)
|
|
|
|
|
|
type fakeContainerGetter struct {
|
|
@@ -266,3 +269,110 @@ func TestNetworkOptions(t *testing.T) {
|
|
|
t.Fatal("Expected networkOptions error, got nil")
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+func TestVerifyContainerResources(t *testing.T) {
|
|
|
+ t.Parallel()
|
|
|
+ var (
|
|
|
+ no = false
|
|
|
+ yes = true
|
|
|
+ )
|
|
|
+
|
|
|
+ withMemoryLimit := func(si *sysinfo.SysInfo) {
|
|
|
+ si.MemoryLimit = true
|
|
|
+ }
|
|
|
+ withSwapLimit := func(si *sysinfo.SysInfo) {
|
|
|
+ si.SwapLimit = true
|
|
|
+ }
|
|
|
+ withOomKillDisable := func(si *sysinfo.SysInfo) {
|
|
|
+ si.OomKillDisable = true
|
|
|
+ }
|
|
|
+
|
|
|
+ tests := []struct {
|
|
|
+ name string
|
|
|
+ resources containertypes.Resources
|
|
|
+ sysInfo sysinfo.SysInfo
|
|
|
+ update bool
|
|
|
+ expectedWarnings []string
|
|
|
+ }{
|
|
|
+ {
|
|
|
+ name: "no-oom-kill-disable",
|
|
|
+ resources: containertypes.Resources{},
|
|
|
+ sysInfo: sysInfo(t, withMemoryLimit),
|
|
|
+ expectedWarnings: []string{},
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "oom-kill-disable-disabled",
|
|
|
+ resources: containertypes.Resources{
|
|
|
+ OomKillDisable: &no,
|
|
|
+ },
|
|
|
+ sysInfo: sysInfo(t, withMemoryLimit),
|
|
|
+ expectedWarnings: []string{},
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "oom-kill-disable-not-supported",
|
|
|
+ resources: containertypes.Resources{
|
|
|
+ OomKillDisable: &yes,
|
|
|
+ },
|
|
|
+ sysInfo: sysInfo(t, withMemoryLimit),
|
|
|
+ expectedWarnings: []string{
|
|
|
+ "Your kernel does not support OomKillDisable. OomKillDisable discarded.",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "oom-kill-disable-without-memory-constraints",
|
|
|
+ resources: containertypes.Resources{
|
|
|
+ OomKillDisable: &yes,
|
|
|
+ Memory: 0,
|
|
|
+ },
|
|
|
+ sysInfo: sysInfo(t, withMemoryLimit, withOomKillDisable, withSwapLimit),
|
|
|
+ expectedWarnings: []string{
|
|
|
+ "OOM killer is disabled for the container, but no memory limit is set, this can result in the system running out of resources.",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "oom-kill-disable-with-memory-constraints-but-no-memory-limit-support",
|
|
|
+ resources: containertypes.Resources{
|
|
|
+ OomKillDisable: &yes,
|
|
|
+ Memory: linuxMinMemory,
|
|
|
+ },
|
|
|
+ sysInfo: sysInfo(t, withOomKillDisable),
|
|
|
+ expectedWarnings: []string{
|
|
|
+ "Your kernel does not support memory limit capabilities or the cgroup is not mounted. Limitation discarded.",
|
|
|
+ "OOM killer is disabled for the container, but no memory limit is set, this can result in the system running out of resources.",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "oom-kill-disable-with-memory-constraints",
|
|
|
+ resources: containertypes.Resources{
|
|
|
+ OomKillDisable: &yes,
|
|
|
+ Memory: linuxMinMemory,
|
|
|
+ },
|
|
|
+ sysInfo: sysInfo(t, withMemoryLimit, withOomKillDisable, withSwapLimit),
|
|
|
+ expectedWarnings: []string{},
|
|
|
+ },
|
|
|
+ }
|
|
|
+ for _, tc := range tests {
|
|
|
+ t.Run(tc.name, func(t *testing.T) {
|
|
|
+ t.Parallel()
|
|
|
+ warnings, err := verifyContainerResources(&tc.resources, &tc.sysInfo, tc.update)
|
|
|
+ assert.NilError(t, err)
|
|
|
+ for _, w := range tc.expectedWarnings {
|
|
|
+ assert.Assert(t, is.Contains(warnings, w))
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func sysInfo(t *testing.T, opts ...func(*sysinfo.SysInfo)) sysinfo.SysInfo {
|
|
|
+ t.Helper()
|
|
|
+ si := sysinfo.SysInfo{}
|
|
|
+
|
|
|
+ for _, opt := range opts {
|
|
|
+ opt(&si)
|
|
|
+ }
|
|
|
+
|
|
|
+ if si.OomKillDisable {
|
|
|
+ t.Log(t.Name(), "OOM disable supported")
|
|
|
+ }
|
|
|
+ return si
|
|
|
+}
|