2019-09-07 03:07:18 +08:00
|
|
|
package parse
|
|
|
|
|
|
|
|
import (
|
2021-02-23 20:27:24 +08:00
|
|
|
"fmt"
|
2019-09-07 03:07:18 +08:00
|
|
|
"runtime"
|
|
|
|
"testing"
|
|
|
|
|
2022-01-12 04:29:28 +08:00
|
|
|
"github.com/containers/buildah/define"
|
2022-01-15 04:39:29 +08:00
|
|
|
"github.com/containers/image/v5/types"
|
2022-01-12 04:29:28 +08:00
|
|
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
2022-01-08 06:09:21 +08:00
|
|
|
"github.com/spf13/pflag"
|
2019-09-07 03:07:18 +08:00
|
|
|
"github.com/stretchr/testify/assert"
|
2024-06-22 03:31:59 +08:00
|
|
|
"github.com/stretchr/testify/require"
|
2019-09-07 03:07:18 +08:00
|
|
|
)
|
|
|
|
|
2022-01-08 06:09:21 +08:00
|
|
|
func TestCommonBuildOptionsFromFlagSet(t *testing.T) {
|
2025-02-04 13:36:03 +08:00
|
|
|
t.Parallel()
|
2022-01-08 06:09:21 +08:00
|
|
|
fs := pflag.NewFlagSet("testme", pflag.PanicOnError)
|
|
|
|
fs.String("memory", "1GB", "")
|
|
|
|
fs.String("shm-size", "5TB", "")
|
|
|
|
fs.String("cpuset-cpus", "1", "")
|
|
|
|
fs.String("cpuset-mems", "2", "")
|
|
|
|
fs.String("cgroup-parent", "none", "")
|
|
|
|
err := fs.Parse([]string{"--memory", "2GB"})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
cbo, err := CommonBuildOptionsFromFlagSet(fs, fs.Lookup)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, cbo.Memory, int64(2147483648))
|
|
|
|
}
|
|
|
|
|
2019-09-07 03:07:18 +08:00
|
|
|
// TestDeviceParser verifies the given device strings is parsed correctly
|
|
|
|
func TestDeviceParser(t *testing.T) {
|
2025-02-04 13:36:03 +08:00
|
|
|
t.Parallel()
|
2019-09-07 03:07:18 +08:00
|
|
|
if runtime.GOOS != "linux" {
|
|
|
|
t.Skip("Devices is only supported on Linux")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test defaults
|
|
|
|
src, dest, permissions, err := Device("/dev/foo")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, src, "/dev/foo")
|
|
|
|
assert.Equal(t, dest, "/dev/foo")
|
|
|
|
assert.Equal(t, permissions, "rwm")
|
|
|
|
|
|
|
|
// Test defaults, different dest
|
|
|
|
src, dest, permissions, err = Device("/dev/foo:/dev/bar")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, src, "/dev/foo")
|
|
|
|
assert.Equal(t, dest, "/dev/bar")
|
|
|
|
assert.Equal(t, permissions, "rwm")
|
|
|
|
|
|
|
|
// Test fully specified
|
|
|
|
src, dest, permissions, err = Device("/dev/foo:/dev/bar:rm")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, src, "/dev/foo")
|
|
|
|
assert.Equal(t, dest, "/dev/bar")
|
|
|
|
assert.Equal(t, permissions, "rm")
|
|
|
|
|
|
|
|
// Test device, permissions
|
|
|
|
src, dest, permissions, err = Device("/dev/foo:rm")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, src, "/dev/foo")
|
|
|
|
assert.Equal(t, dest, "/dev/foo")
|
|
|
|
assert.Equal(t, permissions, "rm")
|
|
|
|
|
2024-08-16 00:50:07 +08:00
|
|
|
// test bogus permissions
|
2019-09-07 03:07:18 +08:00
|
|
|
_, _, _, err = Device("/dev/fuse1:BOGUS")
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
|
|
|
_, _, _, err = Device("")
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
|
|
|
_, _, _, err = Device("/dev/foo:/dev/bar:rm:")
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
|
|
|
_, _, _, err = Device("/dev/foo::rm")
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestIsValidDeviceMode(t *testing.T) {
|
2025-02-04 13:36:03 +08:00
|
|
|
t.Parallel()
|
2019-09-07 03:07:18 +08:00
|
|
|
if runtime.GOOS != "linux" {
|
|
|
|
t.Skip("Devices is only supported on Linux")
|
|
|
|
}
|
|
|
|
assert.False(t, isValidDeviceMode("BOGUS"))
|
|
|
|
assert.False(t, isValidDeviceMode("rwx"))
|
|
|
|
assert.True(t, isValidDeviceMode("r"))
|
|
|
|
assert.True(t, isValidDeviceMode("rw"))
|
|
|
|
assert.True(t, isValidDeviceMode("rm"))
|
|
|
|
assert.True(t, isValidDeviceMode("rwm"))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDeviceFromPath(t *testing.T) {
|
2025-02-04 13:36:03 +08:00
|
|
|
t.Parallel()
|
2019-09-07 03:07:18 +08:00
|
|
|
if runtime.GOOS != "linux" {
|
|
|
|
t.Skip("Devices is only supported on Linux")
|
|
|
|
}
|
|
|
|
// Path is valid
|
|
|
|
dev, err := DeviceFromPath("/dev/null")
|
|
|
|
assert.NoError(t, err)
|
2019-10-22 09:59:15 +08:00
|
|
|
assert.Equal(t, len(dev), 1)
|
|
|
|
assert.Equal(t, dev[0].Major, int64(1))
|
|
|
|
assert.Equal(t, dev[0].Minor, int64(3))
|
2020-07-21 10:59:50 +08:00
|
|
|
assert.Equal(t, string(dev[0].Permissions), "rwm")
|
2019-10-22 09:59:15 +08:00
|
|
|
assert.Equal(t, dev[0].Uid, uint32(0))
|
|
|
|
assert.Equal(t, dev[0].Gid, uint32(0))
|
2019-09-07 03:07:18 +08:00
|
|
|
|
|
|
|
// Path does not exists
|
|
|
|
_, err = DeviceFromPath("/dev/BOGUS")
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
2019-10-22 09:59:15 +08:00
|
|
|
// Path is a directory of devices
|
2019-09-07 03:07:18 +08:00
|
|
|
_, err = DeviceFromPath("/dev/pts")
|
2019-10-22 09:59:15 +08:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
// path of directory has no device
|
|
|
|
_, err = DeviceFromPath("/etc/passwd")
|
2019-09-07 03:07:18 +08:00
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
2021-02-23 20:27:24 +08:00
|
|
|
|
2022-01-13 03:14:46 +08:00
|
|
|
func TestIDMappingOptions(t *testing.T) {
|
2025-02-04 13:36:03 +08:00
|
|
|
t.Parallel()
|
2022-01-13 03:14:46 +08:00
|
|
|
fs := pflag.NewFlagSet("testme", pflag.PanicOnError)
|
|
|
|
pfs := pflag.NewFlagSet("persist", pflag.PanicOnError)
|
|
|
|
fs.String("userns-uid-map-user", "", "")
|
|
|
|
fs.String("userns-gid-map-group", "", "")
|
|
|
|
fs.String("userns-uid-map", "", "")
|
|
|
|
fs.String("userns-gid-map", "", "")
|
|
|
|
fs.String("userns", "", "")
|
|
|
|
err := fs.Parse([]string{})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
uos, _, err := IDMappingOptionsFromFlagSet(fs, pfs, fs.Lookup)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
nso := uos.Find(string(specs.UserNamespace))
|
|
|
|
assert.Equal(t, *nso, define.NamespaceOption{
|
|
|
|
Host: true,
|
|
|
|
Name: string(specs.UserNamespace),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-02-23 20:27:24 +08:00
|
|
|
func TestIsolation(t *testing.T) {
|
2025-02-04 13:36:03 +08:00
|
|
|
t.Parallel()
|
2021-02-23 20:27:24 +08:00
|
|
|
def, err := defaultIsolation()
|
|
|
|
if err != nil {
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
isolations := []string{"", "default", "oci", "chroot", "rootless"}
|
|
|
|
for _, i := range isolations {
|
|
|
|
isolation, err := IsolationOption(i)
|
|
|
|
if err != nil {
|
|
|
|
assert.Error(t, fmt.Errorf("isolation %q not supported", i))
|
|
|
|
}
|
|
|
|
var expected string
|
|
|
|
switch i {
|
|
|
|
case "":
|
|
|
|
expected = def.String()
|
|
|
|
case "default":
|
|
|
|
expected = "oci"
|
|
|
|
default:
|
|
|
|
expected = i
|
|
|
|
}
|
|
|
|
|
|
|
|
if isolation.String() != expected {
|
|
|
|
assert.Error(t, fmt.Errorf("isolation %q not equal to user input %q", isolation.String(), expected))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-03-31 03:26:24 +08:00
|
|
|
|
2022-01-12 04:29:28 +08:00
|
|
|
func TestNamespaceOptions(t *testing.T) {
|
2025-02-04 13:36:03 +08:00
|
|
|
t.Parallel()
|
2022-01-12 04:29:28 +08:00
|
|
|
fs := pflag.NewFlagSet("testme", pflag.PanicOnError)
|
|
|
|
fs.String("cgroupns", "", "")
|
|
|
|
err := fs.Parse([]string{"--cgroupns", "private"})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
nsos, np, err := NamespaceOptionsFromFlagSet(fs, fs.Lookup)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, np, define.NetworkEnabled)
|
|
|
|
nso := nsos.Find(string(specs.CgroupNamespace))
|
|
|
|
assert.Equal(t, *nso, define.NamespaceOption{
|
|
|
|
Name: string(specs.CgroupNamespace),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-03-31 03:26:24 +08:00
|
|
|
func TestParsePlatform(t *testing.T) {
|
2025-02-04 13:36:03 +08:00
|
|
|
t.Parallel()
|
2021-03-31 03:26:24 +08:00
|
|
|
os, arch, variant, err := Platform("a/b/c")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, os, "a")
|
|
|
|
assert.Equal(t, arch, "b")
|
|
|
|
assert.Equal(t, variant, "c")
|
|
|
|
|
|
|
|
os, arch, variant, err = Platform("a/b")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, os, "a")
|
|
|
|
assert.Equal(t, arch, "b")
|
|
|
|
assert.Equal(t, variant, "")
|
|
|
|
|
|
|
|
_, _, _, err = Platform("a")
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
2021-10-11 11:26:35 +08:00
|
|
|
|
2024-06-22 03:31:59 +08:00
|
|
|
func TestParsePullPolicy(t *testing.T) {
|
2025-02-04 13:36:03 +08:00
|
|
|
t.Parallel()
|
2024-06-22 03:31:59 +08:00
|
|
|
testCases := map[string]bool{
|
|
|
|
"missing": true,
|
|
|
|
"ifmissing": true,
|
|
|
|
"notpresent": true,
|
|
|
|
"always": true,
|
|
|
|
"true": true,
|
|
|
|
"ifnewer": true,
|
|
|
|
"newer": true,
|
|
|
|
"false": true,
|
|
|
|
"never": true,
|
2024-11-09 09:10:56 +08:00
|
|
|
"try": false,
|
2024-06-22 03:31:59 +08:00
|
|
|
"truth": false,
|
|
|
|
}
|
|
|
|
for value, result := range testCases {
|
|
|
|
t.Run(value, func(t *testing.T) {
|
|
|
|
policy, err := pullPolicyWithFlags(value, false, false)
|
|
|
|
if result {
|
|
|
|
require.NoErrorf(t, err, "expected value %q to be recognized", value)
|
|
|
|
} else {
|
|
|
|
require.Errorf(t, err, "did not expect value %q to be recognized as %q", value, policy.String())
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-11 11:26:35 +08:00
|
|
|
func TestSplitStringWithColonEscape(t *testing.T) {
|
2025-02-04 13:36:03 +08:00
|
|
|
t.Parallel()
|
2021-10-11 11:26:35 +08:00
|
|
|
tests := []struct {
|
|
|
|
volume string
|
|
|
|
expectedResult []string
|
|
|
|
}{
|
|
|
|
{"/root/a:/root/test:O", []string{"/root/a", "/root/test", "O"}},
|
|
|
|
{"/root/a\\:b/c:/root/test:O", []string{"/root/a:b/c", "/root/test", "O"}},
|
|
|
|
{"/root/a:/root/test\\:test1/a:O", []string{"/root/a", "/root/test:test1/a", "O"}},
|
|
|
|
{"/root/a\\:b/c:/root/test\\:test1/a:O", []string{"/root/a:b/c", "/root/test:test1/a", "O"}},
|
|
|
|
}
|
|
|
|
for _, args := range tests {
|
|
|
|
val := SplitStringWithColonEscape(args.volume)
|
|
|
|
assert.Equal(t, val, args.expectedResult)
|
|
|
|
}
|
|
|
|
}
|
2022-01-15 04:39:29 +08:00
|
|
|
|
|
|
|
func TestSystemContextFromFlagSet(t *testing.T) {
|
2025-02-04 13:36:03 +08:00
|
|
|
t.Parallel()
|
2022-01-15 04:39:29 +08:00
|
|
|
fs := pflag.NewFlagSet("testme", pflag.PanicOnError)
|
|
|
|
fs.Bool("tls-verify", false, "")
|
|
|
|
err := fs.Parse([]string{"--tls-verify", "false"})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
sc, err := SystemContextFromFlagSet(fs, fs.Lookup)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, sc, &types.SystemContext{
|
|
|
|
BigFilesTemporaryDir: GetTempDir(),
|
|
|
|
DockerInsecureSkipTLSVerify: types.OptionalBoolFalse,
|
|
|
|
DockerRegistryUserAgent: fmt.Sprintf("Buildah/%s", define.Version),
|
|
|
|
})
|
|
|
|
}
|