mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Move multi-container test to a single file
PiperOrigin-RevId: 211685288 Change-Id: I7872f2a83fcaaa54f385e6e567af6e72320c5aa0
This commit is contained in:
committed by
Shentubot
parent
f96b33c73c
commit
1d22d87fdc
@@ -38,6 +38,7 @@ go_test(
|
||||
srcs = [
|
||||
"container_test.go",
|
||||
"fs_test.go",
|
||||
"multi_container_test.go",
|
||||
],
|
||||
data = [
|
||||
":uds_test_app",
|
||||
|
||||
@@ -38,7 +38,6 @@ import (
|
||||
"gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth"
|
||||
"gvisor.googlesource.com/gvisor/pkg/unet"
|
||||
"gvisor.googlesource.com/gvisor/runsc/boot"
|
||||
"gvisor.googlesource.com/gvisor/runsc/specutils"
|
||||
"gvisor.googlesource.com/gvisor/runsc/test/testutil"
|
||||
)
|
||||
|
||||
@@ -1366,200 +1365,6 @@ func TestAbbreviatedIDs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestMultiContainerSanity checks that it is possible to run 2 dead-simple
|
||||
// containers in the same sandbox.
|
||||
func TestMultiContainerSanity(t *testing.T) {
|
||||
for _, conf := range configs(all...) {
|
||||
t.Logf("Running test with conf: %+v", conf)
|
||||
|
||||
containerIDs := []string{
|
||||
testutil.UniqueContainerID(),
|
||||
testutil.UniqueContainerID(),
|
||||
}
|
||||
containerAnnotations := []map[string]string{
|
||||
// The first container creates a sandbox.
|
||||
map[string]string{
|
||||
specutils.ContainerdContainerTypeAnnotation: specutils.ContainerdContainerTypeSandbox,
|
||||
},
|
||||
// The second container creates a container within the first
|
||||
// container's sandbox.
|
||||
map[string]string{
|
||||
specutils.ContainerdContainerTypeAnnotation: specutils.ContainerdContainerTypeContainer,
|
||||
specutils.ContainerdSandboxIDAnnotation: containerIDs[0],
|
||||
},
|
||||
}
|
||||
|
||||
rootDir, err := testutil.SetupRootDir()
|
||||
if err != nil {
|
||||
t.Fatalf("error creating root dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(rootDir)
|
||||
|
||||
// Setup the containers.
|
||||
containers := make([]*Container, 0, len(containerIDs))
|
||||
for i, annotations := range containerAnnotations {
|
||||
spec := testutil.NewSpecWithArgs("sleep", "100")
|
||||
spec.Annotations = annotations
|
||||
bundleDir, err := testutil.SetupContainerInRoot(rootDir, spec, conf)
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up container: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(bundleDir)
|
||||
cont, err := Create(containerIDs[i], spec, conf, bundleDir, "", "")
|
||||
if err != nil {
|
||||
t.Fatalf("error creating container: %v", err)
|
||||
}
|
||||
defer cont.Destroy()
|
||||
if err := cont.Start(conf); err != nil {
|
||||
t.Fatalf("error starting container: %v", err)
|
||||
}
|
||||
containers = append(containers, cont)
|
||||
}
|
||||
|
||||
expectedPL := []*control.Process{
|
||||
{
|
||||
UID: 0,
|
||||
PID: 1,
|
||||
PPID: 0,
|
||||
C: 0,
|
||||
Cmd: "sleep",
|
||||
},
|
||||
{
|
||||
UID: 0,
|
||||
PID: 2,
|
||||
PPID: 0,
|
||||
C: 0,
|
||||
Cmd: "sleep",
|
||||
},
|
||||
}
|
||||
|
||||
// Check via ps that multiple processes are running.
|
||||
if err := waitForProcessList(containers[0], expectedPL); err != nil {
|
||||
t.Errorf("failed to wait for sleep to start: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiContainerWait(t *testing.T) {
|
||||
t.Skip("Test is flakey.") // TODO: Remove.
|
||||
containerIDs := []string{
|
||||
testutil.UniqueContainerID(),
|
||||
testutil.UniqueContainerID(),
|
||||
}
|
||||
containerAnnotations := []map[string]string{
|
||||
// The first container creates a sandbox.
|
||||
map[string]string{
|
||||
specutils.ContainerdContainerTypeAnnotation: specutils.ContainerdContainerTypeSandbox,
|
||||
},
|
||||
// The second container creates a container within the first
|
||||
// container's sandbox.
|
||||
map[string]string{
|
||||
specutils.ContainerdContainerTypeAnnotation: specutils.ContainerdContainerTypeContainer,
|
||||
specutils.ContainerdSandboxIDAnnotation: containerIDs[0],
|
||||
},
|
||||
}
|
||||
args := [][]string{
|
||||
// The first container should run the entire duration of the
|
||||
// test.
|
||||
{"sleep", "100"},
|
||||
// We'll wait on the second container, which is much shorter
|
||||
// lived.
|
||||
{"sleep", "1"},
|
||||
}
|
||||
|
||||
rootDir, err := testutil.SetupRootDir()
|
||||
if err != nil {
|
||||
t.Fatalf("error creating root dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(rootDir)
|
||||
|
||||
// Setup the containers.
|
||||
containers := make([]*Container, 0, len(containerIDs))
|
||||
for i, annotations := range containerAnnotations {
|
||||
spec := testutil.NewSpecWithArgs(args[i][0], args[i][1])
|
||||
spec.Annotations = annotations
|
||||
conf := testutil.TestConfig()
|
||||
bundleDir, err := testutil.SetupContainerInRoot(rootDir, spec, conf)
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up container: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(bundleDir)
|
||||
cont, err := Create(containerIDs[i], spec, conf, bundleDir, "", "")
|
||||
if err != nil {
|
||||
t.Fatalf("error creating container: %v", err)
|
||||
}
|
||||
defer cont.Destroy()
|
||||
if err := cont.Start(conf); err != nil {
|
||||
t.Fatalf("error starting container: %v", err)
|
||||
}
|
||||
containers = append(containers, cont)
|
||||
}
|
||||
|
||||
expectedPL := []*control.Process{
|
||||
{
|
||||
UID: 0,
|
||||
PID: 1,
|
||||
PPID: 0,
|
||||
C: 0,
|
||||
Cmd: "sleep",
|
||||
},
|
||||
{
|
||||
UID: 0,
|
||||
PID: 2,
|
||||
PPID: 0,
|
||||
C: 0,
|
||||
Cmd: "sleep",
|
||||
},
|
||||
}
|
||||
|
||||
// Check via ps that multiple processes are running.
|
||||
if err := waitForProcessList(containers[0], expectedPL); err != nil {
|
||||
t.Errorf("failed to wait for sleep to start: %v", err)
|
||||
}
|
||||
|
||||
// Wait on the short lived container from multiple goroutines.
|
||||
wg := sync.WaitGroup{}
|
||||
for i := 0; i < 3; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if ws, err := containers[1].Wait(); err != nil {
|
||||
t.Errorf("failed to wait for process %q: %v", strings.Join(containers[1].Spec.Process.Args, " "), err)
|
||||
} else if es := ws.ExitStatus(); es != 0 {
|
||||
t.Errorf("process %q exited with non-zero status %d", strings.Join(containers[1].Spec.Process.Args, " "), es)
|
||||
}
|
||||
if _, err := containers[1].Wait(); err == nil {
|
||||
t.Errorf("wait for stopped process %q should fail", strings.Join(containers[1].Spec.Process.Args, " "))
|
||||
}
|
||||
|
||||
// After Wait returns, ensure that the root container is running and
|
||||
// the child has finished.
|
||||
if err := waitForProcessList(containers[0], expectedPL[:1]); err != nil {
|
||||
t.Errorf("failed to wait for %q to start: %v", strings.Join(containers[0].Spec.Process.Args, " "), err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Also wait via PID.
|
||||
for i := 0; i < 3; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
const pid = 2
|
||||
if ws, err := containers[0].WaitPID(pid); err != nil {
|
||||
t.Errorf("failed to wait for PID %d: %v", pid, err)
|
||||
} else if es := ws.ExitStatus(); es != 0 {
|
||||
t.Errorf("PID %d exited with non-zero status %d", pid, es)
|
||||
}
|
||||
if _, err := containers[0].WaitPID(pid); err == nil {
|
||||
t.Errorf("wait for stopped PID %d should fail", pid)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// Check that modifications to a volume mount are propigated into and out of
|
||||
// the sandbox.
|
||||
func TestContainerVolumeContentsShared(t *testing.T) {
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
// Copyright 2018 Google Inc.
|
||||
//
|
||||
// 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 container
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"gvisor.googlesource.com/gvisor/pkg/sentry/control"
|
||||
"gvisor.googlesource.com/gvisor/runsc/specutils"
|
||||
"gvisor.googlesource.com/gvisor/runsc/test/testutil"
|
||||
)
|
||||
|
||||
// TestMultiContainerSanity checks that it is possible to run 2 dead-simple
|
||||
// containers in the same sandbox.
|
||||
func TestMultiContainerSanity(t *testing.T) {
|
||||
for _, conf := range configs(all...) {
|
||||
t.Logf("Running test with conf: %+v", conf)
|
||||
|
||||
containerIDs := []string{
|
||||
testutil.UniqueContainerID(),
|
||||
testutil.UniqueContainerID(),
|
||||
}
|
||||
containerAnnotations := []map[string]string{
|
||||
// The first container creates a sandbox.
|
||||
map[string]string{
|
||||
specutils.ContainerdContainerTypeAnnotation: specutils.ContainerdContainerTypeSandbox,
|
||||
},
|
||||
// The second container creates a container within the first
|
||||
// container's sandbox.
|
||||
map[string]string{
|
||||
specutils.ContainerdContainerTypeAnnotation: specutils.ContainerdContainerTypeContainer,
|
||||
specutils.ContainerdSandboxIDAnnotation: containerIDs[0],
|
||||
},
|
||||
}
|
||||
|
||||
rootDir, err := testutil.SetupRootDir()
|
||||
if err != nil {
|
||||
t.Fatalf("error creating root dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(rootDir)
|
||||
|
||||
// Setup the containers.
|
||||
containers := make([]*Container, 0, len(containerIDs))
|
||||
for i, annotations := range containerAnnotations {
|
||||
spec := testutil.NewSpecWithArgs("sleep", "100")
|
||||
spec.Annotations = annotations
|
||||
bundleDir, err := testutil.SetupContainerInRoot(rootDir, spec, conf)
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up container: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(bundleDir)
|
||||
cont, err := Create(containerIDs[i], spec, conf, bundleDir, "", "")
|
||||
if err != nil {
|
||||
t.Fatalf("error creating container: %v", err)
|
||||
}
|
||||
defer cont.Destroy()
|
||||
if err := cont.Start(conf); err != nil {
|
||||
t.Fatalf("error starting container: %v", err)
|
||||
}
|
||||
containers = append(containers, cont)
|
||||
}
|
||||
|
||||
expectedPL := []*control.Process{
|
||||
{
|
||||
UID: 0,
|
||||
PID: 1,
|
||||
PPID: 0,
|
||||
C: 0,
|
||||
Cmd: "sleep",
|
||||
},
|
||||
{
|
||||
UID: 0,
|
||||
PID: 2,
|
||||
PPID: 0,
|
||||
C: 0,
|
||||
Cmd: "sleep",
|
||||
},
|
||||
}
|
||||
|
||||
// Check via ps that multiple processes are running.
|
||||
if err := waitForProcessList(containers[0], expectedPL); err != nil {
|
||||
t.Errorf("failed to wait for sleep to start: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiContainerWait(t *testing.T) {
|
||||
t.Skip("Test is flakey.") // TODO: Remove.
|
||||
containerIDs := []string{
|
||||
testutil.UniqueContainerID(),
|
||||
testutil.UniqueContainerID(),
|
||||
}
|
||||
containerAnnotations := []map[string]string{
|
||||
// The first container creates a sandbox.
|
||||
map[string]string{
|
||||
specutils.ContainerdContainerTypeAnnotation: specutils.ContainerdContainerTypeSandbox,
|
||||
},
|
||||
// The second container creates a container within the first
|
||||
// container's sandbox.
|
||||
map[string]string{
|
||||
specutils.ContainerdContainerTypeAnnotation: specutils.ContainerdContainerTypeContainer,
|
||||
specutils.ContainerdSandboxIDAnnotation: containerIDs[0],
|
||||
},
|
||||
}
|
||||
args := [][]string{
|
||||
// The first container should run the entire duration of the
|
||||
// test.
|
||||
{"sleep", "100"},
|
||||
// We'll wait on the second container, which is much shorter
|
||||
// lived.
|
||||
{"sleep", "1"},
|
||||
}
|
||||
|
||||
rootDir, err := testutil.SetupRootDir()
|
||||
if err != nil {
|
||||
t.Fatalf("error creating root dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(rootDir)
|
||||
|
||||
// Setup the containers.
|
||||
containers := make([]*Container, 0, len(containerIDs))
|
||||
for i, annotations := range containerAnnotations {
|
||||
spec := testutil.NewSpecWithArgs(args[i][0], args[i][1])
|
||||
spec.Annotations = annotations
|
||||
conf := testutil.TestConfig()
|
||||
bundleDir, err := testutil.SetupContainerInRoot(rootDir, spec, conf)
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up container: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(bundleDir)
|
||||
cont, err := Create(containerIDs[i], spec, conf, bundleDir, "", "")
|
||||
if err != nil {
|
||||
t.Fatalf("error creating container: %v", err)
|
||||
}
|
||||
defer cont.Destroy()
|
||||
if err := cont.Start(conf); err != nil {
|
||||
t.Fatalf("error starting container: %v", err)
|
||||
}
|
||||
containers = append(containers, cont)
|
||||
}
|
||||
|
||||
expectedPL := []*control.Process{
|
||||
{
|
||||
UID: 0,
|
||||
PID: 1,
|
||||
PPID: 0,
|
||||
C: 0,
|
||||
Cmd: "sleep",
|
||||
},
|
||||
{
|
||||
UID: 0,
|
||||
PID: 2,
|
||||
PPID: 0,
|
||||
C: 0,
|
||||
Cmd: "sleep",
|
||||
},
|
||||
}
|
||||
|
||||
// Check via ps that multiple processes are running.
|
||||
if err := waitForProcessList(containers[0], expectedPL); err != nil {
|
||||
t.Errorf("failed to wait for sleep to start: %v", err)
|
||||
}
|
||||
|
||||
// Wait on the short lived container from multiple goroutines.
|
||||
wg := sync.WaitGroup{}
|
||||
for i := 0; i < 3; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if ws, err := containers[1].Wait(); err != nil {
|
||||
t.Errorf("failed to wait for process %q: %v", strings.Join(containers[1].Spec.Process.Args, " "), err)
|
||||
} else if es := ws.ExitStatus(); es != 0 {
|
||||
t.Errorf("process %q exited with non-zero status %d", strings.Join(containers[1].Spec.Process.Args, " "), es)
|
||||
}
|
||||
if _, err := containers[1].Wait(); err == nil {
|
||||
t.Errorf("wait for stopped process %q should fail", strings.Join(containers[1].Spec.Process.Args, " "))
|
||||
}
|
||||
|
||||
// After Wait returns, ensure that the root container is running and
|
||||
// the child has finished.
|
||||
if err := waitForProcessList(containers[0], expectedPL[:1]); err != nil {
|
||||
t.Errorf("failed to wait for %q to start: %v", strings.Join(containers[0].Spec.Process.Args, " "), err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Also wait via PID.
|
||||
for i := 0; i < 3; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
const pid = 2
|
||||
if ws, err := containers[0].WaitPID(pid); err != nil {
|
||||
t.Errorf("failed to wait for PID %d: %v", pid, err)
|
||||
} else if es := ws.ExitStatus(); es != 0 {
|
||||
t.Errorf("PID %d exited with non-zero status %d", pid, es)
|
||||
}
|
||||
if _, err := containers[0].WaitPID(pid); err == nil {
|
||||
t.Errorf("wait for stopped PID %d should fail", pid)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
Reference in New Issue
Block a user