mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-10-10 00:23:54 +00:00
Kata support several hypervisor and not all hypervisor support the same type of sockets, for example QEMU support vsock and unix sockets, while firecracker only support hybrid vsocks, hence sockets generations should be hypervisor specific fixes #2027 Signed-off-by: Julio Montes <julio.montes@intel.com>
1762 lines
40 KiB
Go
1762 lines
40 KiB
Go
// Copyright (c) 2016 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package virtcontainers
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"syscall"
|
|
"testing"
|
|
|
|
ktu "github.com/kata-containers/runtime/pkg/katatestutils"
|
|
"github.com/kata-containers/runtime/virtcontainers/pkg/mock"
|
|
vcTypes "github.com/kata-containers/runtime/virtcontainers/pkg/types"
|
|
"github.com/kata-containers/runtime/virtcontainers/store"
|
|
"github.com/kata-containers/runtime/virtcontainers/types"
|
|
"github.com/kata-containers/runtime/virtcontainers/utils"
|
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
const (
|
|
containerID = "1"
|
|
)
|
|
|
|
var sandboxAnnotations = map[string]string{
|
|
"sandbox.foo": "sandbox.bar",
|
|
"sandbox.hello": "sandbox.world",
|
|
}
|
|
|
|
var containerAnnotations = map[string]string{
|
|
"container.foo": "container.bar",
|
|
"container.hello": "container.world",
|
|
}
|
|
|
|
func newEmptySpec() *specs.Spec {
|
|
return &specs.Spec{
|
|
Linux: &specs.Linux{
|
|
Resources: &specs.LinuxResources{},
|
|
},
|
|
Process: &specs.Process{
|
|
Capabilities: &specs.LinuxCapabilities{},
|
|
},
|
|
}
|
|
}
|
|
|
|
func newBasicTestCmd() types.Cmd {
|
|
envs := []types.EnvVar{
|
|
{
|
|
Var: "PATH",
|
|
Value: "/bin:/usr/bin:/sbin:/usr/sbin",
|
|
},
|
|
}
|
|
|
|
cmd := types.Cmd{
|
|
Args: strings.Split("/bin/sh", " "),
|
|
Envs: envs,
|
|
WorkDir: "/",
|
|
}
|
|
|
|
return cmd
|
|
}
|
|
|
|
func newTestSandboxConfigNoop() SandboxConfig {
|
|
bundlePath := filepath.Join(testDir, testBundle)
|
|
containerAnnotations["com.github.containers.virtcontainers.pkg.oci.bundle_path"] = bundlePath
|
|
// containerAnnotations["com.github.containers.virtcontainers.pkg.oci.container_type"] = "pod_sandbox"
|
|
|
|
emptySpec := newEmptySpec()
|
|
|
|
// Define the container command and bundle.
|
|
container := ContainerConfig{
|
|
ID: containerID,
|
|
RootFs: RootFs{Target: bundlePath, Mounted: true},
|
|
Cmd: newBasicTestCmd(),
|
|
Annotations: containerAnnotations,
|
|
Spec: emptySpec,
|
|
}
|
|
|
|
// Sets the hypervisor configuration.
|
|
hypervisorConfig := HypervisorConfig{
|
|
KernelPath: filepath.Join(testDir, testKernel),
|
|
ImagePath: filepath.Join(testDir, testImage),
|
|
HypervisorPath: filepath.Join(testDir, testHypervisor),
|
|
}
|
|
|
|
sandboxConfig := SandboxConfig{
|
|
ID: testSandboxID,
|
|
HypervisorType: MockHypervisor,
|
|
HypervisorConfig: hypervisorConfig,
|
|
|
|
AgentType: NoopAgentType,
|
|
|
|
Containers: []ContainerConfig{container},
|
|
|
|
Annotations: sandboxAnnotations,
|
|
|
|
ProxyType: NoopProxyType,
|
|
}
|
|
|
|
configFile := filepath.Join(bundlePath, "config.json")
|
|
f, err := os.OpenFile(configFile, os.O_RDWR|os.O_CREATE, 0644)
|
|
if err != nil {
|
|
return SandboxConfig{}
|
|
}
|
|
defer f.Close()
|
|
|
|
if err := json.NewEncoder(f).Encode(emptySpec); err != nil {
|
|
return SandboxConfig{}
|
|
}
|
|
|
|
return sandboxConfig
|
|
}
|
|
|
|
func newTestSandboxConfigKataAgent() SandboxConfig {
|
|
sandboxConfig := newTestSandboxConfigNoop()
|
|
sandboxConfig.AgentType = KataContainersAgent
|
|
sandboxConfig.AgentConfig = KataAgentConfig{}
|
|
sandboxConfig.Containers = nil
|
|
|
|
return sandboxConfig
|
|
}
|
|
|
|
func TestCreateSandboxNoopAgentSuccessful(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
p, err := CreateSandbox(context.Background(), config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(p.ID())
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.NoError(err)
|
|
}
|
|
|
|
func TestCreateSandboxKataAgentSuccessful(t *testing.T) {
|
|
assert := assert.New(t)
|
|
if tc.NotValid(ktu.NeedRoot()) {
|
|
t.Skip(testDisabledAsNonRoot)
|
|
}
|
|
|
|
defer cleanUp()
|
|
|
|
config := newTestSandboxConfigKataAgent()
|
|
|
|
sockDir, err := testGenerateKataProxySockDir()
|
|
assert.NoError(err)
|
|
|
|
defer os.RemoveAll(sockDir)
|
|
|
|
testKataProxyURL := fmt.Sprintf(testKataProxyURLTempl, sockDir)
|
|
noopProxyURL = testKataProxyURL
|
|
|
|
impl := &gRPCProxy{}
|
|
|
|
kataProxyMock := mock.ProxyGRPCMock{
|
|
GRPCImplementer: impl,
|
|
GRPCRegister: gRPCRegister,
|
|
}
|
|
err = kataProxyMock.Start(testKataProxyURL)
|
|
assert.NoError(err)
|
|
defer kataProxyMock.Stop()
|
|
|
|
p, err := CreateSandbox(context.Background(), config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(p.ID())
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.NoError(err)
|
|
}
|
|
|
|
func TestCreateSandboxFailing(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
config := SandboxConfig{}
|
|
|
|
p, err := CreateSandbox(context.Background(), config, nil)
|
|
assert.Error(err)
|
|
assert.Nil(p.(*Sandbox))
|
|
}
|
|
|
|
func TestDeleteSandboxNoopAgentSuccessful(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
ctx := context.Background()
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(p.ID())
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.NoError(err)
|
|
|
|
p, err = DeleteSandbox(ctx, p.ID())
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.Error(err)
|
|
}
|
|
|
|
func TestDeleteSandboxKataAgentSuccessful(t *testing.T) {
|
|
assert := assert.New(t)
|
|
if tc.NotValid(ktu.NeedRoot()) {
|
|
t.Skip(testDisabledAsNonRoot)
|
|
}
|
|
|
|
defer cleanUp()
|
|
|
|
config := newTestSandboxConfigKataAgent()
|
|
|
|
sockDir, err := testGenerateKataProxySockDir()
|
|
assert.NoError(err)
|
|
|
|
defer os.RemoveAll(sockDir)
|
|
|
|
testKataProxyURL := fmt.Sprintf(testKataProxyURLTempl, sockDir)
|
|
noopProxyURL = testKataProxyURL
|
|
|
|
impl := &gRPCProxy{}
|
|
|
|
kataProxyMock := mock.ProxyGRPCMock{
|
|
GRPCImplementer: impl,
|
|
GRPCRegister: gRPCRegister,
|
|
}
|
|
err = kataProxyMock.Start(testKataProxyURL)
|
|
assert.NoError(err)
|
|
defer kataProxyMock.Stop()
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(p.ID())
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.NoError(err)
|
|
|
|
p, err = DeleteSandbox(ctx, p.ID())
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.Error(err)
|
|
}
|
|
|
|
func TestDeleteSandboxFailing(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(testSandboxID)
|
|
os.Remove(sandboxDir)
|
|
|
|
p, err := DeleteSandbox(context.Background(), testSandboxID)
|
|
assert.Error(err)
|
|
assert.Nil(p)
|
|
}
|
|
|
|
func TestStartSandboxNoopAgentSuccessful(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
p, _, err := createAndStartSandbox(context.Background(), config)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
}
|
|
|
|
func TestStartSandboxKataAgentSuccessful(t *testing.T) {
|
|
assert := assert.New(t)
|
|
if tc.NotValid(ktu.NeedRoot()) {
|
|
t.Skip(testDisabledAsNonRoot)
|
|
}
|
|
|
|
defer cleanUp()
|
|
|
|
config := newTestSandboxConfigKataAgent()
|
|
|
|
sockDir, err := testGenerateKataProxySockDir()
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(sockDir)
|
|
|
|
testKataProxyURL := fmt.Sprintf(testKataProxyURLTempl, sockDir)
|
|
noopProxyURL = testKataProxyURL
|
|
|
|
impl := &gRPCProxy{}
|
|
|
|
kataProxyMock := mock.ProxyGRPCMock{
|
|
GRPCImplementer: impl,
|
|
GRPCRegister: gRPCRegister,
|
|
}
|
|
err = kataProxyMock.Start(testKataProxyURL)
|
|
assert.NoError(err)
|
|
defer kataProxyMock.Stop()
|
|
|
|
ctx := context.Background()
|
|
p, _, err := createAndStartSandbox(ctx, config)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
pImpl, ok := p.(*Sandbox)
|
|
assert.True(ok)
|
|
|
|
// TODO: defaultSharedDir is a hyper var = /run/hyper/shared/sandboxes
|
|
// do we need to unmount sandboxes and containers?
|
|
err = bindUnmountAllRootfs(ctx, testDir, pImpl)
|
|
assert.NoError(err)
|
|
}
|
|
|
|
func TestStartSandboxFailing(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(testSandboxID)
|
|
os.Remove(sandboxDir)
|
|
|
|
p, err := StartSandbox(context.Background(), testSandboxID)
|
|
assert.Error(err)
|
|
assert.Nil(p)
|
|
}
|
|
|
|
func TestStopSandboxNoopAgentSuccessful(t *testing.T) {
|
|
if tc.NotValid(ktu.NeedRoot()) {
|
|
t.Skip(testDisabledAsNonRoot)
|
|
}
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
p, _, err := createAndStartSandbox(ctx, config)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
vp, err := StopSandbox(ctx, p.ID(), false)
|
|
assert.NoError(err)
|
|
assert.NotNil(vp)
|
|
}
|
|
|
|
func TestPauseThenResumeSandboxNoopAgentSuccessful(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
|
|
p, _, err := createAndStartSandbox(ctx, config)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
contID := "100"
|
|
contConfig := newTestContainerConfigNoop(contID)
|
|
|
|
_, c, err := CreateContainer(ctx, p.ID(), contConfig)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
p, err = PauseSandbox(ctx, p.ID())
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
pImpl, ok := p.(*Sandbox)
|
|
assert.True(ok)
|
|
|
|
expectedState := types.StatePaused
|
|
|
|
assert.Equal(pImpl.state.State, expectedState, "unexpected paused sandbox state")
|
|
|
|
for i, c := range p.GetAllContainers() {
|
|
cImpl, ok := c.(*Container)
|
|
assert.True(ok)
|
|
|
|
assert.Equal(expectedState, cImpl.state.State,
|
|
fmt.Sprintf("paused container %d has unexpected state", i))
|
|
}
|
|
|
|
p, err = ResumeSandbox(ctx, p.ID())
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
pImpl, ok = p.(*Sandbox)
|
|
assert.True(ok)
|
|
|
|
expectedState = types.StateRunning
|
|
|
|
assert.Equal(pImpl.state.State, expectedState, "unexpected resumed sandbox state")
|
|
|
|
for i, c := range p.GetAllContainers() {
|
|
cImpl, ok := c.(*Container)
|
|
assert.True(ok)
|
|
|
|
assert.Equal(cImpl.state.State, expectedState,
|
|
fmt.Sprintf("resumed container %d has unexpected state", i))
|
|
}
|
|
}
|
|
|
|
func TestStopSandboxKataAgentSuccessful(t *testing.T) {
|
|
assert := assert.New(t)
|
|
if tc.NotValid(ktu.NeedRoot()) {
|
|
t.Skip(testDisabledAsNonRoot)
|
|
}
|
|
|
|
defer cleanUp()
|
|
|
|
config := newTestSandboxConfigKataAgent()
|
|
|
|
sockDir, err := testGenerateKataProxySockDir()
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(sockDir)
|
|
|
|
testKataProxyURL := fmt.Sprintf(testKataProxyURLTempl, sockDir)
|
|
noopProxyURL = testKataProxyURL
|
|
|
|
impl := &gRPCProxy{}
|
|
|
|
kataProxyMock := mock.ProxyGRPCMock{
|
|
GRPCImplementer: impl,
|
|
GRPCRegister: gRPCRegister,
|
|
}
|
|
err = kataProxyMock.Start(testKataProxyURL)
|
|
assert.NoError(err)
|
|
defer kataProxyMock.Stop()
|
|
|
|
ctx := context.Background()
|
|
p, _, err := createAndStartSandbox(ctx, config)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
p, err = StopSandbox(ctx, p.ID(), false)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
}
|
|
|
|
func TestStopSandboxFailing(t *testing.T) {
|
|
defer cleanUp()
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(testSandboxID)
|
|
os.Remove(sandboxDir)
|
|
|
|
p, err := StopSandbox(context.Background(), testSandboxID, false)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, p)
|
|
}
|
|
|
|
func TestRunSandboxNoopAgentSuccessful(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
p, err := RunSandbox(context.Background(), config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(p.ID())
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.NoError(err)
|
|
}
|
|
|
|
func TestRunSandboxKataAgentSuccessful(t *testing.T) {
|
|
assert := assert.New(t)
|
|
if tc.NotValid(ktu.NeedRoot()) {
|
|
t.Skip(testDisabledAsNonRoot)
|
|
}
|
|
|
|
defer cleanUp()
|
|
|
|
config := newTestSandboxConfigKataAgent()
|
|
|
|
sockDir, err := testGenerateKataProxySockDir()
|
|
assert.NoError(err)
|
|
|
|
defer os.RemoveAll(sockDir)
|
|
|
|
testKataProxyURL := fmt.Sprintf(testKataProxyURLTempl, sockDir)
|
|
noopProxyURL = testKataProxyURL
|
|
|
|
impl := &gRPCProxy{}
|
|
|
|
kataProxyMock := mock.ProxyGRPCMock{
|
|
GRPCImplementer: impl,
|
|
GRPCRegister: gRPCRegister,
|
|
}
|
|
err = kataProxyMock.Start(testKataProxyURL)
|
|
assert.NoError(err)
|
|
defer kataProxyMock.Stop()
|
|
|
|
ctx := context.Background()
|
|
p, err := RunSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(p.ID())
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.NoError(err)
|
|
|
|
pImpl, ok := p.(*Sandbox)
|
|
assert.True(ok)
|
|
|
|
err = bindUnmountAllRootfs(ctx, testDir, pImpl)
|
|
assert.NoError(err)
|
|
}
|
|
|
|
func TestRunSandboxFailing(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
config := SandboxConfig{}
|
|
|
|
p, err := RunSandbox(context.Background(), config, nil)
|
|
assert.Error(err)
|
|
assert.Nil(p)
|
|
}
|
|
|
|
func TestListSandboxSuccessful(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
_, err = ListSandbox(ctx)
|
|
assert.NoError(err)
|
|
}
|
|
|
|
func TestListSandboxNoSandboxDirectory(t *testing.T) {
|
|
defer cleanUp()
|
|
|
|
_, err := ListSandbox(context.Background())
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestStatusSandboxSuccessfulStateReady(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
config := newTestSandboxConfigNoop()
|
|
cgroupPath, err := renameCgroupPath(utils.DefaultCgroupPath)
|
|
assert.NoError(err)
|
|
|
|
hypervisorConfig := HypervisorConfig{
|
|
KernelPath: filepath.Join(testDir, testKernel),
|
|
ImagePath: filepath.Join(testDir, testImage),
|
|
HypervisorPath: filepath.Join(testDir, testHypervisor),
|
|
NumVCPUs: defaultVCPUs,
|
|
MemorySize: defaultMemSzMiB,
|
|
DefaultBridges: defaultBridges,
|
|
BlockDeviceDriver: defaultBlockDriver,
|
|
DefaultMaxVCPUs: defaultMaxQemuVCPUs,
|
|
Msize9p: defaultMsize9p,
|
|
}
|
|
|
|
expectedStatus := SandboxStatus{
|
|
ID: testSandboxID,
|
|
State: types.SandboxState{
|
|
State: types.StateReady,
|
|
},
|
|
Hypervisor: MockHypervisor,
|
|
HypervisorConfig: hypervisorConfig,
|
|
Agent: NoopAgentType,
|
|
Annotations: sandboxAnnotations,
|
|
ContainersStatus: []ContainerStatus{
|
|
{
|
|
ID: containerID,
|
|
State: types.ContainerState{
|
|
State: types.StateReady,
|
|
CgroupPath: cgroupPath,
|
|
},
|
|
PID: 0,
|
|
RootFs: filepath.Join(testDir, testBundle),
|
|
Annotations: containerAnnotations,
|
|
Spec: newEmptySpec(),
|
|
},
|
|
},
|
|
}
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
status, err := StatusSandbox(ctx, p.ID())
|
|
assert.NoError(err)
|
|
|
|
// Copy the start time as we can't pretend we know what that
|
|
// value will be.
|
|
expectedStatus.ContainersStatus[0].StartTime = status.ContainersStatus[0].StartTime
|
|
|
|
assert.Equal(status, expectedStatus)
|
|
}
|
|
|
|
func TestStatusSandboxSuccessfulStateRunning(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
config := newTestSandboxConfigNoop()
|
|
cgroupPath, err := renameCgroupPath(utils.DefaultCgroupPath)
|
|
assert.NoError(err)
|
|
|
|
hypervisorConfig := HypervisorConfig{
|
|
KernelPath: filepath.Join(testDir, testKernel),
|
|
ImagePath: filepath.Join(testDir, testImage),
|
|
HypervisorPath: filepath.Join(testDir, testHypervisor),
|
|
NumVCPUs: defaultVCPUs,
|
|
MemorySize: defaultMemSzMiB,
|
|
DefaultBridges: defaultBridges,
|
|
BlockDeviceDriver: defaultBlockDriver,
|
|
DefaultMaxVCPUs: defaultMaxQemuVCPUs,
|
|
Msize9p: defaultMsize9p,
|
|
}
|
|
|
|
expectedStatus := SandboxStatus{
|
|
ID: testSandboxID,
|
|
State: types.SandboxState{
|
|
State: types.StateRunning,
|
|
},
|
|
Hypervisor: MockHypervisor,
|
|
HypervisorConfig: hypervisorConfig,
|
|
Agent: NoopAgentType,
|
|
Annotations: sandboxAnnotations,
|
|
ContainersStatus: []ContainerStatus{
|
|
{
|
|
ID: containerID,
|
|
State: types.ContainerState{
|
|
State: types.StateRunning,
|
|
CgroupPath: cgroupPath,
|
|
},
|
|
PID: 0,
|
|
RootFs: filepath.Join(testDir, testBundle),
|
|
Annotations: containerAnnotations,
|
|
Spec: newEmptySpec(),
|
|
},
|
|
},
|
|
}
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
p, err = StartSandbox(ctx, p.ID())
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
status, err := StatusSandbox(ctx, p.ID())
|
|
assert.NoError(err)
|
|
|
|
// Copy the start time as we can't pretend we know what that
|
|
// value will be.
|
|
expectedStatus.ContainersStatus[0].StartTime = status.ContainersStatus[0].StartTime
|
|
|
|
assert.Exactly(status, expectedStatus)
|
|
}
|
|
|
|
func TestStatusSandboxFailingFetchSandboxConfig(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
store.DeleteAll()
|
|
globalSandboxList.removeSandbox(p.ID())
|
|
|
|
_, err = StatusSandbox(ctx, p.ID())
|
|
assert.Error(err)
|
|
}
|
|
|
|
func TestStatusPodSandboxFailingFetchSandboxState(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
store.DeleteAll()
|
|
globalSandboxList.removeSandbox(p.ID())
|
|
|
|
_, err = StatusSandbox(ctx, p.ID())
|
|
assert.Error(err)
|
|
}
|
|
|
|
func newTestContainerConfigNoop(contID string) ContainerConfig {
|
|
// Define the container command and bundle.
|
|
container := ContainerConfig{
|
|
ID: contID,
|
|
RootFs: RootFs{Target: filepath.Join(testDir, testBundle), Mounted: true},
|
|
Cmd: newBasicTestCmd(),
|
|
Annotations: containerAnnotations,
|
|
Spec: newEmptySpec(),
|
|
}
|
|
|
|
return container
|
|
}
|
|
|
|
func TestCreateContainerSuccessful(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
contID := "100"
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(p.ID())
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.NoError(err)
|
|
|
|
contConfig := newTestContainerConfigNoop(contID)
|
|
|
|
_, c, err := CreateContainer(ctx, p.ID(), contConfig)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
contDir := filepath.Join(sandboxDir, contID)
|
|
_, err = os.Stat(contDir)
|
|
assert.NoError(err)
|
|
}
|
|
|
|
func TestCreateContainerFailingNoSandbox(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
contID := "100"
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
p, err = DeleteSandbox(ctx, p.ID())
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(p.ID())
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.Error(err)
|
|
|
|
contConfig := newTestContainerConfigNoop(contID)
|
|
|
|
_, c, err := CreateContainer(ctx, p.ID(), contConfig)
|
|
assert.Error(err)
|
|
assert.Nil(c)
|
|
}
|
|
|
|
func TestDeleteContainerSuccessful(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
contID := "100"
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(p.ID())
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.NoError(err)
|
|
|
|
contConfig := newTestContainerConfigNoop(contID)
|
|
|
|
_, c, err := CreateContainer(ctx, p.ID(), contConfig)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
contDir := filepath.Join(sandboxDir, contID)
|
|
_, err = os.Stat(contDir)
|
|
assert.NoError(err)
|
|
|
|
c, err = DeleteContainer(ctx, p.ID(), contID)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
_, err = os.Stat(contDir)
|
|
assert.Error(err)
|
|
}
|
|
|
|
func TestDeleteContainerFailingNoSandbox(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
contID := "100"
|
|
c, err := DeleteContainer(context.Background(), testSandboxID, contID)
|
|
assert.Error(err)
|
|
assert.Nil(c)
|
|
}
|
|
|
|
func TestDeleteContainerFailingNoContainer(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
contID := "100"
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(p.ID())
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.NoError(err)
|
|
|
|
c, err := DeleteContainer(ctx, p.ID(), contID)
|
|
assert.Error(err)
|
|
assert.Nil(c)
|
|
}
|
|
|
|
func TestStartContainerNoopAgentSuccessful(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
contID := "100"
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
|
|
p, sandboxDir, err := createAndStartSandbox(ctx, config)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
contConfig := newTestContainerConfigNoop(contID)
|
|
|
|
_, c, err := CreateContainer(ctx, p.ID(), contConfig)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
contDir := filepath.Join(sandboxDir, contID)
|
|
_, err = os.Stat(contDir)
|
|
assert.NoError(err)
|
|
|
|
c, err = StartContainer(ctx, p.ID(), contID)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
}
|
|
|
|
func TestStartContainerFailingNoSandbox(t *testing.T) {
|
|
defer cleanUp()
|
|
|
|
contID := "100"
|
|
c, err := StartContainer(context.Background(), testSandboxID, contID)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, c)
|
|
}
|
|
|
|
func TestStartContainerFailingNoContainer(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
contID := "100"
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(p.ID())
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.NoError(err)
|
|
|
|
c, err := StartContainer(ctx, p.ID(), contID)
|
|
assert.Error(err)
|
|
assert.Nil(c)
|
|
}
|
|
|
|
func TestStartContainerFailingSandboxNotStarted(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
contID := "100"
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(p.ID())
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.NoError(err)
|
|
|
|
contConfig := newTestContainerConfigNoop(contID)
|
|
|
|
_, c, err := CreateContainer(ctx, p.ID(), contConfig)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
contDir := filepath.Join(sandboxDir, contID)
|
|
_, err = os.Stat(contDir)
|
|
assert.NoError(err)
|
|
|
|
_, err = StartContainer(ctx, p.ID(), contID)
|
|
assert.Error(err)
|
|
}
|
|
|
|
func TestStopContainerNoopAgentSuccessful(t *testing.T) {
|
|
if tc.NotValid(ktu.NeedRoot()) {
|
|
t.Skip(testDisabledAsNonRoot)
|
|
}
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
contID := "100"
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
|
|
p, sandboxDir, err := createAndStartSandbox(ctx, config)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
contConfig := newTestContainerConfigNoop(contID)
|
|
|
|
_, c, err := CreateContainer(ctx, p.ID(), contConfig)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
contDir := filepath.Join(sandboxDir, contID)
|
|
_, err = os.Stat(contDir)
|
|
assert.NoError(err)
|
|
|
|
c, err = StartContainer(ctx, p.ID(), contID)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
c, err = StopContainer(ctx, p.ID(), contID)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
}
|
|
|
|
func TestStopContainerFailingNoSandbox(t *testing.T) {
|
|
if tc.NotValid(ktu.NeedRoot()) {
|
|
t.Skip(testDisabledAsNonRoot)
|
|
}
|
|
defer cleanUp()
|
|
|
|
contID := "100"
|
|
c, err := StopContainer(context.Background(), testSandboxID, contID)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, c)
|
|
}
|
|
|
|
func TestStopContainerFailingNoContainer(t *testing.T) {
|
|
if tc.NotValid(ktu.NeedRoot()) {
|
|
t.Skip(testDisabledAsNonRoot)
|
|
}
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
contID := "100"
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(p.ID())
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.NoError(err)
|
|
|
|
c, err := StopContainer(ctx, p.ID(), contID)
|
|
assert.Error(err)
|
|
assert.Nil(c)
|
|
}
|
|
|
|
func testKillContainerFromContReadySuccessful(t *testing.T, signal syscall.Signal) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
contID := "100"
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
|
|
p, sandboxDir, err := createAndStartSandbox(ctx, config)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
contConfig := newTestContainerConfigNoop(contID)
|
|
|
|
_, c, err := CreateContainer(ctx, p.ID(), contConfig)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
contDir := filepath.Join(sandboxDir, contID)
|
|
_, err = os.Stat(contDir)
|
|
assert.NoError(err)
|
|
|
|
err = KillContainer(ctx, p.ID(), contID, signal, false)
|
|
assert.NoError(err)
|
|
}
|
|
|
|
func TestKillContainerFromContReadySuccessful(t *testing.T) {
|
|
// SIGUSR1
|
|
testKillContainerFromContReadySuccessful(t, syscall.SIGUSR1)
|
|
// SIGUSR2
|
|
testKillContainerFromContReadySuccessful(t, syscall.SIGUSR2)
|
|
// SIGKILL
|
|
testKillContainerFromContReadySuccessful(t, syscall.SIGKILL)
|
|
// SIGTERM
|
|
testKillContainerFromContReadySuccessful(t, syscall.SIGTERM)
|
|
}
|
|
|
|
func TestEnterContainerNoopAgentSuccessful(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
contID := "100"
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
|
|
p, sandboxDir, err := createAndStartSandbox(ctx, config)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
contConfig := newTestContainerConfigNoop(contID)
|
|
|
|
_, c, err := CreateContainer(ctx, p.ID(), contConfig)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
contDir := filepath.Join(sandboxDir, contID)
|
|
_, err = os.Stat(contDir)
|
|
assert.NoError(err)
|
|
|
|
c, err = StartContainer(ctx, p.ID(), contID)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
cmd := newBasicTestCmd()
|
|
|
|
_, c, _, err = EnterContainer(ctx, p.ID(), contID, cmd)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
}
|
|
|
|
func TestEnterContainerFailingNoSandbox(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
contID := "100"
|
|
cmd := newBasicTestCmd()
|
|
|
|
_, c, _, err := EnterContainer(context.Background(), testSandboxID, contID, cmd)
|
|
assert.Error(err)
|
|
assert.Nil(c)
|
|
}
|
|
|
|
func TestEnterContainerFailingNoContainer(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
contID := "100"
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(p.ID())
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.NoError(err)
|
|
|
|
cmd := newBasicTestCmd()
|
|
|
|
_, c, _, err := EnterContainer(ctx, p.ID(), contID, cmd)
|
|
assert.Error(err)
|
|
assert.Nil(c)
|
|
}
|
|
|
|
func TestEnterContainerFailingContNotStarted(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
contID := "100"
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
|
|
p, sandboxDir, err := createAndStartSandbox(ctx, config)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
contConfig := newTestContainerConfigNoop(contID)
|
|
|
|
_, c, err := CreateContainer(ctx, p.ID(), contConfig)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
contDir := filepath.Join(sandboxDir, contID)
|
|
_, err = os.Stat(contDir)
|
|
assert.NoError(err)
|
|
|
|
cmd := newBasicTestCmd()
|
|
|
|
_, c, _, err = EnterContainer(ctx, p.ID(), contID, cmd)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
}
|
|
|
|
func TestStatusContainerSuccessful(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
contID := "100"
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(p.ID())
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.NoError(err)
|
|
|
|
contConfig := newTestContainerConfigNoop(contID)
|
|
|
|
_, c, err := CreateContainer(ctx, p.ID(), contConfig)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
contDir := filepath.Join(sandboxDir, contID)
|
|
_, err = os.Stat(contDir)
|
|
assert.NoError(err)
|
|
|
|
status, err := StatusContainer(ctx, p.ID(), contID)
|
|
assert.NoError(err)
|
|
|
|
pImpl, ok := p.(*Sandbox)
|
|
assert.True(ok)
|
|
|
|
cImpl, ok := c.(*Container)
|
|
assert.True(ok)
|
|
|
|
assert.True(status.StartTime.Equal(cImpl.process.StartTime))
|
|
assert.Exactly(pImpl.config.Containers[0].Annotations, status.Annotations)
|
|
}
|
|
|
|
func TestStatusContainerStateReady(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
// (homage to a great album! ;)
|
|
contID := "101"
|
|
|
|
config := newTestSandboxConfigNoop()
|
|
cgroupPath, err := renameCgroupPath(utils.DefaultCgroupPath)
|
|
assert.NoError(err)
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(p.ID())
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.NoError(err)
|
|
|
|
contConfig := newTestContainerConfigNoop(contID)
|
|
|
|
_, c, err := CreateContainer(ctx, p.ID(), contConfig)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
contDir := filepath.Join(sandboxDir, contID)
|
|
_, err = os.Stat(contDir)
|
|
assert.NoError(err)
|
|
|
|
// fresh lookup
|
|
p2, err := fetchSandbox(ctx, p.ID())
|
|
assert.NoError(err)
|
|
defer p2.releaseStatelessSandbox()
|
|
|
|
expectedStatus := ContainerStatus{
|
|
ID: contID,
|
|
State: types.ContainerState{
|
|
State: types.StateReady,
|
|
CgroupPath: cgroupPath,
|
|
},
|
|
PID: 0,
|
|
RootFs: filepath.Join(testDir, testBundle),
|
|
Annotations: containerAnnotations,
|
|
Spec: newEmptySpec(),
|
|
}
|
|
|
|
defer p2.wg.Wait()
|
|
|
|
status, err := statusContainer(p2, contID)
|
|
assert.NoError(err)
|
|
|
|
// Copy the start time as we can't pretend we know what that
|
|
// value will be.
|
|
expectedStatus.StartTime = status.StartTime
|
|
|
|
assert.Exactly(status, expectedStatus)
|
|
}
|
|
|
|
func TestStatusContainerStateRunning(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
// (homage to a great album! ;)
|
|
contID := "101"
|
|
|
|
config := newTestSandboxConfigNoop()
|
|
cgroupPath, err := renameCgroupPath(utils.DefaultCgroupPath)
|
|
assert.NoError(err)
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
p, err = StartSandbox(ctx, p.ID())
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(p.ID())
|
|
_, err = os.Stat(sandboxDir)
|
|
assert.NoError(err)
|
|
|
|
contConfig := newTestContainerConfigNoop(contID)
|
|
|
|
_, c, err := CreateContainer(ctx, p.ID(), contConfig)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
c, err = StartContainer(ctx, p.ID(), c.ID())
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
contDir := filepath.Join(sandboxDir, contID)
|
|
_, err = os.Stat(contDir)
|
|
assert.NoError(err)
|
|
|
|
// fresh lookup
|
|
p2, err := fetchSandbox(ctx, p.ID())
|
|
assert.NoError(err)
|
|
defer p2.releaseStatelessSandbox()
|
|
|
|
expectedStatus := ContainerStatus{
|
|
ID: contID,
|
|
State: types.ContainerState{
|
|
State: types.StateRunning,
|
|
CgroupPath: cgroupPath,
|
|
},
|
|
PID: 0,
|
|
RootFs: filepath.Join(testDir, testBundle),
|
|
Annotations: containerAnnotations,
|
|
Spec: newEmptySpec(),
|
|
}
|
|
|
|
defer p2.wg.Wait()
|
|
|
|
status, err := statusContainer(p2, contID)
|
|
assert.NoError(err)
|
|
|
|
// Copy the start time as we can't pretend we know what that
|
|
// value will be.
|
|
expectedStatus.StartTime = status.StartTime
|
|
|
|
assert.Exactly(status, expectedStatus)
|
|
}
|
|
|
|
func TestStatusContainerFailing(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
contID := "100"
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
store.DeleteAll()
|
|
globalSandboxList.removeSandbox(p.ID())
|
|
|
|
_, err = StatusContainer(ctx, p.ID(), contID)
|
|
assert.Error(err)
|
|
}
|
|
|
|
func TestStatsContainerFailing(t *testing.T) {
|
|
defer cleanUp()
|
|
assert := assert.New(t)
|
|
|
|
contID := "100"
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
store.DeleteAll()
|
|
globalSandboxList.removeSandbox(p.ID())
|
|
|
|
_, err = StatsContainer(ctx, p.ID(), contID)
|
|
assert.Error(err)
|
|
}
|
|
|
|
func TestStatsContainer(t *testing.T) {
|
|
defer cleanUp()
|
|
|
|
assert := assert.New(t)
|
|
contID := "100"
|
|
|
|
ctx := context.Background()
|
|
_, err := StatsContainer(ctx, "", "")
|
|
assert.Error(err)
|
|
|
|
_, err = StatsContainer(ctx, "abc", "")
|
|
assert.Error(err)
|
|
|
|
_, err = StatsContainer(ctx, "abc", "abc")
|
|
assert.Error(err)
|
|
|
|
config := newTestSandboxConfigNoop()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
p, err = StartSandbox(ctx, p.ID())
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
pImpl, ok := p.(*Sandbox)
|
|
assert.True(ok)
|
|
defer store.DeleteAll()
|
|
|
|
contConfig := newTestContainerConfigNoop(contID)
|
|
_, c, err := CreateContainer(ctx, p.ID(), contConfig)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
_, err = StatsContainer(ctx, pImpl.id, "xyz")
|
|
assert.Error(err)
|
|
|
|
_, err = StatsContainer(ctx, "xyz", contID)
|
|
assert.Error(err)
|
|
|
|
stats, err := StatsContainer(ctx, pImpl.id, contID)
|
|
assert.NoError(err)
|
|
assert.Equal(stats, ContainerStats{})
|
|
}
|
|
|
|
func TestProcessListContainer(t *testing.T) {
|
|
defer cleanUp()
|
|
|
|
assert := assert.New(t)
|
|
|
|
contID := "abc"
|
|
options := ProcessListOptions{
|
|
Format: "json",
|
|
Args: []string{"-ef"},
|
|
}
|
|
|
|
ctx := context.Background()
|
|
_, err := ProcessListContainer(ctx, "", "", options)
|
|
assert.Error(err)
|
|
|
|
_, err = ProcessListContainer(ctx, "xyz", "", options)
|
|
assert.Error(err)
|
|
|
|
_, err = ProcessListContainer(ctx, "xyz", "xyz", options)
|
|
assert.Error(err)
|
|
|
|
config := newTestSandboxConfigNoop()
|
|
p, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(err)
|
|
assert.NotNil(p)
|
|
|
|
pImpl, ok := p.(*Sandbox)
|
|
assert.True(ok)
|
|
defer store.DeleteAll()
|
|
|
|
contConfig := newTestContainerConfigNoop(contID)
|
|
_, c, err := CreateContainer(ctx, p.ID(), contConfig)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
_, err = ProcessListContainer(ctx, pImpl.id, "xyz", options)
|
|
assert.Error(err)
|
|
|
|
_, err = ProcessListContainer(ctx, "xyz", contID, options)
|
|
assert.Error(err)
|
|
|
|
_, err = ProcessListContainer(ctx, pImpl.id, contID, options)
|
|
// Sandbox not running, impossible to ps the container
|
|
assert.Error(err)
|
|
}
|
|
|
|
/*
|
|
* Benchmarks
|
|
*/
|
|
|
|
func createNewSandboxConfig(hType HypervisorType, aType AgentType, aConfig interface{}) SandboxConfig {
|
|
hypervisorConfig := HypervisorConfig{
|
|
KernelPath: "/usr/share/kata-containers/vmlinux.container",
|
|
ImagePath: "/usr/share/kata-containers/kata-containers.img",
|
|
HypervisorPath: "/usr/bin/qemu-system-x86_64",
|
|
}
|
|
|
|
netConfig := NetworkConfig{}
|
|
|
|
return SandboxConfig{
|
|
ID: testSandboxID,
|
|
HypervisorType: hType,
|
|
HypervisorConfig: hypervisorConfig,
|
|
|
|
AgentType: aType,
|
|
AgentConfig: aConfig,
|
|
|
|
NetworkConfig: netConfig,
|
|
|
|
ProxyType: NoopProxyType,
|
|
}
|
|
}
|
|
|
|
// createAndStartSandbox handles the common test operation of creating and
|
|
// starting a sandbox.
|
|
func createAndStartSandbox(ctx context.Context, config SandboxConfig) (sandbox VCSandbox, sandboxDir string,
|
|
err error) {
|
|
|
|
// Create sandbox
|
|
sandbox, err = CreateSandbox(ctx, config, nil)
|
|
if sandbox == nil || err != nil {
|
|
return nil, "", err
|
|
}
|
|
|
|
sandboxDir = store.SandboxConfigurationRootPath(sandbox.ID())
|
|
_, err = os.Stat(sandboxDir)
|
|
if err != nil {
|
|
return nil, "", err
|
|
}
|
|
|
|
// Start sandbox
|
|
sandbox, err = StartSandbox(ctx, sandbox.ID())
|
|
if sandbox == nil || err != nil {
|
|
return nil, "", err
|
|
}
|
|
|
|
return sandbox, sandboxDir, nil
|
|
}
|
|
|
|
func createStartStopDeleteSandbox(b *testing.B, sandboxConfig SandboxConfig) {
|
|
ctx := context.Background()
|
|
|
|
p, _, err := createAndStartSandbox(ctx, sandboxConfig)
|
|
if p == nil || err != nil {
|
|
b.Fatalf("Could not create and start sandbox: %s", err)
|
|
}
|
|
|
|
// Stop sandbox
|
|
_, err = StopSandbox(ctx, p.ID(), false)
|
|
if err != nil {
|
|
b.Fatalf("Could not stop sandbox: %s", err)
|
|
}
|
|
|
|
// Delete sandbox
|
|
_, err = DeleteSandbox(ctx, p.ID())
|
|
if err != nil {
|
|
b.Fatalf("Could not delete sandbox: %s", err)
|
|
}
|
|
}
|
|
|
|
func BenchmarkCreateStartStopDeleteSandboxQemuHypervisorNoopAgentNetworkNoop(b *testing.B) {
|
|
for i := 0; i < b.N; i++ {
|
|
sandboxConfig := createNewSandboxConfig(QemuHypervisor, NoopAgentType, nil)
|
|
createStartStopDeleteSandbox(b, sandboxConfig)
|
|
}
|
|
}
|
|
|
|
func BenchmarkCreateStartStopDeleteSandboxMockHypervisorNoopAgentNetworkNoop(b *testing.B) {
|
|
for i := 0; i < b.N; i++ {
|
|
sandboxConfig := createNewSandboxConfig(MockHypervisor, NoopAgentType, nil)
|
|
createStartStopDeleteSandbox(b, sandboxConfig)
|
|
}
|
|
}
|
|
|
|
func TestFetchSandbox(t *testing.T) {
|
|
defer cleanUp()
|
|
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
|
|
s, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, s)
|
|
|
|
fetched, err := FetchSandbox(ctx, s.ID())
|
|
assert.Nil(t, err, "%v", err)
|
|
assert.True(t, fetched != s, "fetched stateless sandboxes should not match")
|
|
}
|
|
|
|
func TestFetchStatefulSandbox(t *testing.T) {
|
|
defer cleanUp()
|
|
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
config.Stateful = true
|
|
|
|
ctx := context.Background()
|
|
|
|
s, err := CreateSandbox(ctx, config, nil)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, s)
|
|
|
|
fetched, err := FetchSandbox(ctx, s.ID())
|
|
assert.Nil(t, err, "%v", err)
|
|
assert.Equal(t, fetched, s, "fetched stateful sandboxed should match")
|
|
}
|
|
|
|
func TestFetchNonExistingSandbox(t *testing.T) {
|
|
defer cleanUp()
|
|
|
|
_, err := FetchSandbox(context.Background(), "some-non-existing-sandbox-name")
|
|
assert.NotNil(t, err, "fetch non-existing sandbox should fail")
|
|
}
|
|
|
|
func TestReleaseSandbox(t *testing.T) {
|
|
defer cleanUp()
|
|
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
s, err := CreateSandbox(context.Background(), config, nil)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, s)
|
|
|
|
err = s.Release()
|
|
assert.Nil(t, err, "sandbox release failed: %v", err)
|
|
}
|
|
|
|
func TestUpdateContainer(t *testing.T) {
|
|
if tc.NotValid(ktu.NeedRoot()) {
|
|
t.Skip(testDisabledAsNonRoot)
|
|
}
|
|
|
|
defer cleanUp()
|
|
|
|
ctx := context.Background()
|
|
|
|
period := uint64(1000)
|
|
quota := int64(2000)
|
|
memoryLimit := int64(1073741824)
|
|
memorySwap := int64(1073741824)
|
|
assert := assert.New(t)
|
|
resources := specs.LinuxResources{
|
|
CPU: &specs.LinuxCPU{
|
|
Period: &period,
|
|
Quota: "a,
|
|
},
|
|
Memory: &specs.LinuxMemory{
|
|
Limit: &memoryLimit,
|
|
Swap: &memorySwap,
|
|
},
|
|
}
|
|
err := UpdateContainer(ctx, "", "", resources)
|
|
assert.Error(err)
|
|
|
|
err = UpdateContainer(ctx, "abc", "", resources)
|
|
assert.Error(err)
|
|
|
|
contID := "100"
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
s, sandboxDir, err := createAndStartSandbox(ctx, config)
|
|
assert.NoError(err)
|
|
assert.NotNil(s)
|
|
|
|
contConfig := newTestContainerConfigNoop(contID)
|
|
_, c, err := CreateContainer(ctx, s.ID(), contConfig)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
contDir := filepath.Join(sandboxDir, contID)
|
|
_, err = os.Stat(contDir)
|
|
assert.NoError(err)
|
|
|
|
_, err = StartContainer(ctx, s.ID(), contID)
|
|
assert.NoError(err)
|
|
|
|
err = UpdateContainer(ctx, s.ID(), contID, resources)
|
|
assert.NoError(err)
|
|
}
|
|
|
|
func TestPauseResumeContainer(t *testing.T) {
|
|
if tc.NotValid(ktu.NeedRoot()) {
|
|
t.Skip(testDisabledAsNonRoot)
|
|
}
|
|
|
|
defer cleanUp()
|
|
|
|
ctx := context.Background()
|
|
|
|
assert := assert.New(t)
|
|
err := PauseContainer(ctx, "", "")
|
|
assert.Error(err)
|
|
|
|
err = PauseContainer(ctx, "abc", "")
|
|
assert.Error(err)
|
|
|
|
contID := "100"
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
s, sandboxDir, err := createAndStartSandbox(ctx, config)
|
|
assert.NoError(err)
|
|
assert.NotNil(s)
|
|
|
|
contConfig := newTestContainerConfigNoop(contID)
|
|
_, c, err := CreateContainer(ctx, s.ID(), contConfig)
|
|
assert.NoError(err)
|
|
assert.NotNil(c)
|
|
|
|
contDir := filepath.Join(sandboxDir, contID)
|
|
_, err = os.Stat(contDir)
|
|
assert.NoError(err)
|
|
|
|
_, err = StartContainer(ctx, s.ID(), contID)
|
|
assert.NoError(err)
|
|
|
|
err = PauseContainer(ctx, s.ID(), contID)
|
|
assert.NoError(err)
|
|
|
|
err = ResumeContainer(ctx, s.ID(), contID)
|
|
assert.NoError(err)
|
|
}
|
|
|
|
func TestNetworkOperation(t *testing.T) {
|
|
if tc.NotValid(ktu.NeedRoot()) {
|
|
t.Skip(testDisabledAsNonRoot)
|
|
}
|
|
|
|
defer cleanUp()
|
|
|
|
assert := assert.New(t)
|
|
inf := &vcTypes.Interface{
|
|
Name: "eno1",
|
|
Mtu: 1500,
|
|
HwAddr: "02:00:ca:fe:00:48",
|
|
}
|
|
ip := vcTypes.IPAddress{
|
|
Family: 0,
|
|
Address: "192.168.0.101",
|
|
Mask: "24",
|
|
}
|
|
inf.IPAddresses = append(inf.IPAddresses, &ip)
|
|
|
|
ctx := context.Background()
|
|
|
|
_, err := AddInterface(ctx, "", inf)
|
|
assert.Error(err)
|
|
|
|
_, err = AddInterface(ctx, "abc", inf)
|
|
assert.Error(err)
|
|
|
|
netNSPath, err := createNetNS()
|
|
assert.NoError(err)
|
|
defer deleteNetNS(netNSPath)
|
|
|
|
config := newTestSandboxConfigNoop()
|
|
config.NetworkConfig = NetworkConfig{
|
|
NetNSPath: netNSPath,
|
|
}
|
|
|
|
s, _, err := createAndStartSandbox(ctx, config)
|
|
assert.NoError(err)
|
|
assert.NotNil(s)
|
|
|
|
_, err = AddInterface(ctx, s.ID(), inf)
|
|
assert.Error(err)
|
|
|
|
_, err = RemoveInterface(ctx, s.ID(), inf)
|
|
assert.NoError(err)
|
|
|
|
_, err = ListInterfaces(ctx, s.ID())
|
|
assert.NoError(err)
|
|
|
|
_, err = UpdateRoutes(ctx, s.ID(), nil)
|
|
assert.NoError(err)
|
|
|
|
_, err = ListRoutes(ctx, s.ID())
|
|
assert.NoError(err)
|
|
}
|
|
|
|
func TestCleanupContainer(t *testing.T) {
|
|
config := newTestSandboxConfigNoop()
|
|
|
|
ctx := context.Background()
|
|
|
|
p, _, err := createAndStartSandbox(ctx, config)
|
|
if p == nil || err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
contIDs := []string{"100", "101", "102", "103", "104"}
|
|
for _, contID := range contIDs {
|
|
contConfig := newTestContainerConfigNoop(contID)
|
|
|
|
c, err := p.CreateContainer(contConfig)
|
|
if c == nil || err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
c, err = p.StartContainer(c.ID())
|
|
if c == nil || err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
for _, c := range p.GetAllContainers() {
|
|
CleanupContainer(ctx, p.ID(), c.ID(), true)
|
|
}
|
|
|
|
sandboxDir := store.SandboxConfigurationRootPath(p.ID())
|
|
|
|
_, err = os.Stat(sandboxDir)
|
|
if err == nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|