gvisor/runsc/cmd/exec_test.go

155 lines
4.8 KiB
Go
Raw Normal View History

// Copyright 2018 Google LLC
//
// 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 cmd
import (
"os"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
specs "github.com/opencontainers/runtime-spec/specs-go"
"gvisor.googlesource.com/gvisor/pkg/abi/linux"
"gvisor.googlesource.com/gvisor/pkg/sentry/control"
"gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth"
"gvisor.googlesource.com/gvisor/pkg/urpc"
)
func TestUser(t *testing.T) {
testCases := []struct {
input string
want user
wantErr bool
}{
{input: "0", want: user{kuid: 0, kgid: 0}},
{input: "7", want: user{kuid: 7, kgid: 0}},
{input: "49:343", want: user{kuid: 49, kgid: 343}},
{input: "0:2401", want: user{kuid: 0, kgid: 2401}},
{input: "", wantErr: true},
{input: "foo", wantErr: true},
{input: ":123", wantErr: true},
{input: "1:2:3", wantErr: true},
}
for _, tc := range testCases {
var u user
if err := u.Set(tc.input); err != nil && tc.wantErr {
// We got an error and wanted one.
continue
} else if err == nil && tc.wantErr {
t.Errorf("user.Set(%s): got no error, but wanted one", tc.input)
} else if err != nil && !tc.wantErr {
t.Errorf("user.Set(%s): got error %v, but wanted none", tc.input, err)
} else if u != tc.want {
t.Errorf("user.Set(%s): got %+v, but wanted %+v", tc.input, u, tc.want)
}
}
}
func TestCLIArgs(t *testing.T) {
testCases := []struct {
ex Exec
argv []string
expected control.ExecArgs
}{
{
ex: Exec{
cwd: "/foo/bar",
user: user{kuid: 0, kgid: 0},
extraKGIDs: []string{"1", "2", "3"},
caps: []string{"CAP_DAC_OVERRIDE"},
processPath: "",
},
argv: []string{"ls", "/"},
expected: control.ExecArgs{
Argv: []string{"ls", "/"},
WorkingDirectory: "/foo/bar",
FilePayload: urpc.FilePayload{Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}},
KUID: 0,
KGID: 0,
ExtraKGIDs: []auth.KGID{1, 2, 3},
Capabilities: &auth.TaskCapabilities{
BoundingCaps: auth.CapabilitySetOf(linux.CAP_DAC_OVERRIDE),
EffectiveCaps: auth.CapabilitySetOf(linux.CAP_DAC_OVERRIDE),
InheritableCaps: auth.CapabilitySetOf(linux.CAP_DAC_OVERRIDE),
PermittedCaps: auth.CapabilitySetOf(linux.CAP_DAC_OVERRIDE),
},
},
},
}
for _, tc := range testCases {
e, err := tc.ex.argsFromCLI(tc.argv)
if err != nil {
t.Errorf("argsFromCLI(%+v): got error: %+v", tc.ex, err)
} else if !cmp.Equal(*e, tc.expected, cmpopts.IgnoreUnexported(os.File{})) {
t.Errorf("argsFromCLI(%+v): got %+v, but expected %+v", tc.ex, *e, tc.expected)
}
}
}
func TestJSONArgs(t *testing.T) {
testCases := []struct {
// ex is provided to make sure it is overridden by p.
ex Exec
p specs.Process
expected control.ExecArgs
}{
{
ex: Exec{
cwd: "/baz/quux",
user: user{kuid: 1, kgid: 1},
extraKGIDs: []string{"4", "5", "6"},
caps: []string{"CAP_SETGID"},
processPath: "/bin/foo",
},
p: specs.Process{
User: specs.User{UID: 0, GID: 0, AdditionalGids: []uint32{1, 2, 3}},
Args: []string{"ls", "/"},
Cwd: "/foo/bar",
Capabilities: &specs.LinuxCapabilities{
Bounding: []string{"CAP_DAC_OVERRIDE"},
Effective: []string{"CAP_DAC_OVERRIDE"},
Inheritable: []string{"CAP_DAC_OVERRIDE"},
Permitted: []string{"CAP_DAC_OVERRIDE"},
},
},
expected: control.ExecArgs{
Argv: []string{"ls", "/"},
WorkingDirectory: "/foo/bar",
FilePayload: urpc.FilePayload{Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}},
KUID: 0,
KGID: 0,
ExtraKGIDs: []auth.KGID{1, 2, 3},
Capabilities: &auth.TaskCapabilities{
BoundingCaps: auth.CapabilitySetOf(linux.CAP_DAC_OVERRIDE),
EffectiveCaps: auth.CapabilitySetOf(linux.CAP_DAC_OVERRIDE),
InheritableCaps: auth.CapabilitySetOf(linux.CAP_DAC_OVERRIDE),
PermittedCaps: auth.CapabilitySetOf(linux.CAP_DAC_OVERRIDE),
},
},
},
}
for _, tc := range testCases {
e, err := argsFromProcess(&tc.p)
if err != nil {
t.Errorf("argsFromProcess(%+v): got error: %+v", tc.p, err)
} else if !cmp.Equal(*e, tc.expected, cmpopts.IgnoreUnexported(os.File{})) {
t.Errorf("argsFromProcess(%+v): got %+v, but expected %+v", tc.p, *e, tc.expected)
}
}
}