
This updates the test to: - Use correctly formatted values for RequiredPlugins and DisabledPlugins (values are expected to have a `io.containerd.` prefix). While not needed for the test to pass (no validation is performed), it's good to have these values in the correct format (in case we want to add validation at this stage). - Set a `Version` for both (as version 1 / no version was deprecated) The `Version` field in this test was used to verify the "integer override" behavior; setting "Version: 2" for both would no longer cover that case. As there are only 2 integer fields in the config (Version and OOMScore) and OOMScore was already used in the test, I added separate test-cases for that. Looking at the test, we should consider what we want the behaviour to be if the override file does not specify a version (implicitly: version 1), or if the version is different from the original one; do we want mergeConfig() to produce an error when merging a v2 config with a v1 config (or v3 with v2)? Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
236 lines
6.7 KiB
Go
236 lines
6.7 KiB
Go
/*
|
|
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 config
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"sort"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/containerd/containerd/plugin"
|
|
)
|
|
|
|
func TestMergeConfigs(t *testing.T) {
|
|
a := &Config{
|
|
Version: 2,
|
|
Root: "old_root",
|
|
RequiredPlugins: []string{"io.containerd.old_plugin.v1"},
|
|
DisabledPlugins: []string{"io.containerd.old_plugin.v1"},
|
|
State: "old_state",
|
|
OOMScore: 1,
|
|
Timeouts: map[string]string{"a": "1"},
|
|
StreamProcessors: map[string]StreamProcessor{"1": {Path: "2", Returns: "4"}, "2": {Path: "5"}},
|
|
}
|
|
|
|
b := &Config{
|
|
Version: 2,
|
|
Root: "new_root",
|
|
RequiredPlugins: []string{"io.containerd.new_plugin1.v1", "io.containerd.new_plugin2.v1"},
|
|
OOMScore: 2,
|
|
Timeouts: map[string]string{"b": "2"},
|
|
StreamProcessors: map[string]StreamProcessor{"1": {Path: "3"}},
|
|
}
|
|
|
|
err := mergeConfig(a, b)
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, 2, a.Version)
|
|
assert.Equal(t, "new_root", a.Root)
|
|
assert.Equal(t, "old_state", a.State)
|
|
assert.Equal(t, 2, a.OOMScore)
|
|
assert.Equal(t, []string{"io.containerd.old_plugin.v1", "io.containerd.new_plugin1.v1", "io.containerd.new_plugin2.v1"}, a.RequiredPlugins)
|
|
assert.Equal(t, []string{"io.containerd.old_plugin.v1"}, a.DisabledPlugins)
|
|
assert.Equal(t, map[string]string{"a": "1", "b": "2"}, a.Timeouts)
|
|
assert.Equal(t, map[string]StreamProcessor{"1": {Path: "3"}, "2": {Path: "5"}}, a.StreamProcessors)
|
|
|
|
// Verify overrides for integers
|
|
// https://github.com/containerd/containerd/blob/v1.6.0/services/server/config/config.go#L322-L323
|
|
a = &Config{Version: 2, OOMScore: 1}
|
|
b = &Config{Version: 2, OOMScore: 0} // OOMScore "not set / default"
|
|
err = mergeConfig(a, b)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 1, a.OOMScore)
|
|
|
|
a = &Config{Version: 2, OOMScore: 1}
|
|
b = &Config{Version: 2, OOMScore: 0} // OOMScore "not set / default"
|
|
err = mergeConfig(a, b)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 1, a.OOMScore)
|
|
}
|
|
|
|
func TestResolveImports(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
|
|
for _, filename := range []string{"config_1.toml", "config_2.toml", "test.toml"} {
|
|
err := os.WriteFile(filepath.Join(tempDir, filename), []byte(""), 0600)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
imports, err := resolveImports(filepath.Join(tempDir, "root.toml"), []string{
|
|
filepath.Join(tempDir, "config_*.toml"), // Glob
|
|
filepath.Join(tempDir, "./test.toml"), // Path clean up
|
|
"current.toml", // Resolve current working dir
|
|
})
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, imports, []string{
|
|
filepath.Join(tempDir, "config_1.toml"),
|
|
filepath.Join(tempDir, "config_2.toml"),
|
|
filepath.Join(tempDir, "test.toml"),
|
|
filepath.Join(tempDir, "current.toml"),
|
|
})
|
|
}
|
|
|
|
func TestLoadSingleConfig(t *testing.T) {
|
|
data := `
|
|
version = 2
|
|
root = "/var/lib/containerd"
|
|
|
|
[stream_processors]
|
|
[stream_processors."io.containerd.processor.v1.pigz"]
|
|
accepts = ["application/vnd.docker.image.rootfs.diff.tar.gzip"]
|
|
path = "unpigz"
|
|
`
|
|
tempDir := t.TempDir()
|
|
|
|
path := filepath.Join(tempDir, "config.toml")
|
|
err := os.WriteFile(path, []byte(data), 0600)
|
|
assert.NoError(t, err)
|
|
|
|
var out Config
|
|
err = LoadConfig(path, &out)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 2, out.Version)
|
|
assert.Equal(t, "/var/lib/containerd", out.Root)
|
|
assert.Equal(t, map[string]StreamProcessor{
|
|
"io.containerd.processor.v1.pigz": {
|
|
Accepts: []string{"application/vnd.docker.image.rootfs.diff.tar.gzip"},
|
|
Path: "unpigz",
|
|
},
|
|
}, out.StreamProcessors)
|
|
}
|
|
|
|
func TestLoadConfigWithImports(t *testing.T) {
|
|
data1 := `
|
|
version = 2
|
|
root = "/var/lib/containerd"
|
|
imports = ["data2.toml"]
|
|
`
|
|
|
|
data2 := `
|
|
disabled_plugins = ["io.containerd.v1.xyz"]
|
|
`
|
|
|
|
tempDir := t.TempDir()
|
|
|
|
err := os.WriteFile(filepath.Join(tempDir, "data1.toml"), []byte(data1), 0600)
|
|
assert.NoError(t, err)
|
|
|
|
err = os.WriteFile(filepath.Join(tempDir, "data2.toml"), []byte(data2), 0600)
|
|
assert.NoError(t, err)
|
|
|
|
var out Config
|
|
err = LoadConfig(filepath.Join(tempDir, "data1.toml"), &out)
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, 2, out.Version)
|
|
assert.Equal(t, "/var/lib/containerd", out.Root)
|
|
assert.Equal(t, []string{"io.containerd.v1.xyz"}, out.DisabledPlugins)
|
|
}
|
|
|
|
func TestLoadConfigWithCircularImports(t *testing.T) {
|
|
data1 := `
|
|
version = 2
|
|
root = "/var/lib/containerd"
|
|
imports = ["data2.toml", "data1.toml"]
|
|
`
|
|
|
|
data2 := `
|
|
disabled_plugins = ["io.containerd.v1.xyz"]
|
|
imports = ["data1.toml", "data2.toml"]
|
|
`
|
|
tempDir := t.TempDir()
|
|
|
|
err := os.WriteFile(filepath.Join(tempDir, "data1.toml"), []byte(data1), 0600)
|
|
assert.NoError(t, err)
|
|
|
|
err = os.WriteFile(filepath.Join(tempDir, "data2.toml"), []byte(data2), 0600)
|
|
assert.NoError(t, err)
|
|
|
|
var out Config
|
|
err = LoadConfig(filepath.Join(tempDir, "data1.toml"), &out)
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, 2, out.Version)
|
|
assert.Equal(t, "/var/lib/containerd", out.Root)
|
|
assert.Equal(t, []string{"io.containerd.v1.xyz"}, out.DisabledPlugins)
|
|
|
|
sort.Strings(out.Imports)
|
|
assert.Equal(t, []string{
|
|
filepath.Join(tempDir, "data1.toml"),
|
|
filepath.Join(tempDir, "data2.toml"),
|
|
}, out.Imports)
|
|
}
|
|
|
|
func TestDecodePlugin(t *testing.T) {
|
|
data := `
|
|
version = 2
|
|
[plugins."io.containerd.runtime.v1.linux"]
|
|
shim_debug = true
|
|
`
|
|
|
|
tempDir := t.TempDir()
|
|
|
|
path := filepath.Join(tempDir, "config.toml")
|
|
err := os.WriteFile(path, []byte(data), 0600)
|
|
assert.NoError(t, err)
|
|
|
|
var out Config
|
|
err = LoadConfig(path, &out)
|
|
assert.NoError(t, err)
|
|
|
|
pluginConfig := map[string]interface{}{}
|
|
_, err = out.Decode(&plugin.Registration{Type: "io.containerd.runtime.v1", ID: "linux", Config: &pluginConfig})
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, true, pluginConfig["shim_debug"])
|
|
}
|
|
|
|
// TestDecodePluginInV1Config tests decoding non-versioned
|
|
// config (should be parsed as V1 config).
|
|
func TestDecodePluginInV1Config(t *testing.T) {
|
|
data := `
|
|
[plugins.linux]
|
|
shim_debug = true
|
|
`
|
|
|
|
path := filepath.Join(t.TempDir(), "config.toml")
|
|
err := os.WriteFile(path, []byte(data), 0600)
|
|
assert.NoError(t, err)
|
|
|
|
var out Config
|
|
err = LoadConfig(path, &out)
|
|
assert.NoError(t, err)
|
|
|
|
pluginConfig := map[string]interface{}{}
|
|
_, err = out.Decode(&plugin.Registration{ID: "linux", Config: &pluginConfig})
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, true, pluginConfig["shim_debug"])
|
|
}
|