mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-11-01 18:14:00 +00:00
Add initial support for opentracing by using the `jaeger` package.
Since opentracing uses the `context` package, add a `context.Context`
as the first parameter to all the functions that we might want to
trace. Trace "spans" (trace points) are then added by extracting the
trace details from the specified context parameter.
Notes:
- Although the tracer is created in `main()`, the "root span"
(aka the first trace point) is not added until `beforeSubcommands()`.
This is by design and is a compromise: by delaying the creation of the
root span, the spans become much more readable since using the web-based
JaegerUI, you will see traces like this:
```
kata-runtime: kata-runtime create
------------ -------------------
^ ^
| |
Trace name First span name
(which clearly shows the CLI command that was run)
```
Creating the span earlier means it is necessary to expand 'n' spans in
the UI before you get to see the name of the CLI command that was run.
In adding support, this became very tedious, hence my design decision to
defer the creation of the root span until after signal handling has been
setup and after CLI options have been parsed, but still very early in
the code path.
- At this stage, the tracing stops at the `virtcontainers` call
boundary.
- Tracing is "always on" as there doesn't appear to be a way to toggle
it. However, its resolves to a "nop" unless the tracer can talk to a
jaeger agent.
Note that this commit required a bit of rework to `beforeSubcommands()`
to reduce the cyclomatic complexity.
Fixes #557.
Signed-off-by: James O. D. Hunt <james.o.hunt@intel.com>
629 lines
18 KiB
Go
629 lines
18 KiB
Go
// Copyright (c) 2017 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
vc "github.com/kata-containers/runtime/virtcontainers"
|
|
vcAnnotations "github.com/kata-containers/runtime/virtcontainers/pkg/annotations"
|
|
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
|
|
"github.com/kata-containers/runtime/virtcontainers/pkg/vcmock"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/urfave/cli"
|
|
)
|
|
|
|
func TestRunCliAction(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
flagSet := flag.NewFlagSet("flag", flag.ContinueOnError)
|
|
flagSet.Parse([]string{"runtime"})
|
|
|
|
// create a new fake context
|
|
ctx := createCLIContext(flagSet)
|
|
|
|
// get Action function
|
|
actionFunc, ok := runCLICommand.Action.(func(ctx *cli.Context) error)
|
|
assert.True(ok)
|
|
|
|
err := actionFunc(ctx)
|
|
assert.Error(err, "missing runtime configuration")
|
|
|
|
// temporal dir to place container files
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
// create a new runtime config
|
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, "/dev/ptmx", true)
|
|
assert.NoError(err)
|
|
|
|
ctx.App.Metadata = map[string]interface{}{
|
|
"runtimeConfig": runtimeConfig,
|
|
}
|
|
|
|
err = actionFunc(ctx)
|
|
assert.Error(err, "run without args")
|
|
}
|
|
|
|
func TestRunInvalidArgs(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
sandbox := &vcmock.Sandbox{
|
|
MockID: testSandboxID,
|
|
MockContainers: []*vcmock.Container{
|
|
{MockID: testContainerID},
|
|
},
|
|
}
|
|
|
|
// fake functions used to run containers
|
|
testingImpl.CreateSandboxFunc = func(sandboxConfig vc.SandboxConfig) (vc.VCSandbox, error) {
|
|
return sandbox, nil
|
|
}
|
|
|
|
testingImpl.StartSandboxFunc = func(sandboxID string) (vc.VCSandbox, error) {
|
|
return sandbox, nil
|
|
}
|
|
|
|
path, err := ioutil.TempDir("", "containers-mapping")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
ctrsMapTreePath = path
|
|
|
|
defer func() {
|
|
testingImpl.CreateSandboxFunc = nil
|
|
testingImpl.StartSandboxFunc = nil
|
|
}()
|
|
|
|
// temporal dir to place container files
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
// create a new bundle
|
|
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
|
|
err = os.MkdirAll(bundlePath, testDirMode)
|
|
assert.NoError(err)
|
|
|
|
err = makeOCIBundle(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
// pid file
|
|
pidFilePath := filepath.Join(tmpdir, "pid")
|
|
|
|
// console file
|
|
consolePath := "/dev/ptmx"
|
|
|
|
// inexistent path
|
|
inexistentPath := "/this/path/does/not/exist"
|
|
|
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, consolePath, true)
|
|
assert.NoError(err)
|
|
|
|
type testArgs struct {
|
|
containerID string
|
|
bundle string
|
|
console string
|
|
consoleSocket string
|
|
pidFile string
|
|
detach bool
|
|
runtimeConfig oci.RuntimeConfig
|
|
}
|
|
|
|
args := []testArgs{
|
|
{"", "", "", "", "", true, oci.RuntimeConfig{}},
|
|
{"", "", "", "", "", false, oci.RuntimeConfig{}},
|
|
{"", "", "", "", "", true, runtimeConfig},
|
|
{"", "", "", "", "", false, runtimeConfig},
|
|
{"", "", "", "", pidFilePath, false, runtimeConfig},
|
|
{"", "", "", "", inexistentPath, false, runtimeConfig},
|
|
{"", "", "", "", pidFilePath, false, runtimeConfig},
|
|
{"", "", "", inexistentPath, pidFilePath, false, runtimeConfig},
|
|
{"", "", inexistentPath, inexistentPath, pidFilePath, false, runtimeConfig},
|
|
{"", "", inexistentPath, "", pidFilePath, false, runtimeConfig},
|
|
{"", "", consolePath, "", pidFilePath, false, runtimeConfig},
|
|
{"", bundlePath, consolePath, "", pidFilePath, false, runtimeConfig},
|
|
{testContainerID, inexistentPath, consolePath, "", pidFilePath, false, oci.RuntimeConfig{}},
|
|
{testContainerID, inexistentPath, consolePath, "", inexistentPath, false, oci.RuntimeConfig{}},
|
|
{testContainerID, bundlePath, consolePath, "", pidFilePath, false, oci.RuntimeConfig{}},
|
|
{testContainerID, inexistentPath, consolePath, "", pidFilePath, false, runtimeConfig},
|
|
{testContainerID, inexistentPath, consolePath, "", inexistentPath, false, runtimeConfig},
|
|
{testContainerID, bundlePath, consolePath, "", pidFilePath, false, runtimeConfig},
|
|
}
|
|
|
|
for i, a := range args {
|
|
err := run(context.Background(), a.containerID, a.bundle, a.console, a.consoleSocket, a.pidFile, a.detach, a.runtimeConfig)
|
|
assert.Errorf(err, "test %d (%+v)", i, a)
|
|
}
|
|
}
|
|
|
|
type runContainerData struct {
|
|
pidFilePath string
|
|
consolePath string
|
|
bundlePath string
|
|
configJSON string
|
|
sandbox *vcmock.Sandbox
|
|
runtimeConfig oci.RuntimeConfig
|
|
process *os.Process
|
|
tmpDir string
|
|
}
|
|
|
|
func testRunContainerSetup(t *testing.T) runContainerData {
|
|
assert := assert.New(t)
|
|
|
|
// create a fake container workload
|
|
workload := []string{"/bin/sleep", "10"}
|
|
cmd := exec.Command(workload[0], workload[1:]...)
|
|
err := cmd.Start()
|
|
assert.NoError(err, "unable to start fake container workload %+v: %s", workload, err)
|
|
|
|
// temporal dir to place container files
|
|
// Note - it is returned to the caller, who does the defer remove to clean up.
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
|
|
// pid file
|
|
pidFilePath := filepath.Join(tmpdir, "pid")
|
|
|
|
// console file
|
|
consolePath := "/dev/ptmx"
|
|
|
|
// create a new bundle
|
|
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
|
|
err = makeOCIBundle(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
// config json path
|
|
configPath := filepath.Join(bundlePath, specConfig)
|
|
|
|
// sandbox id and container id must be the same otherwise delete will not works
|
|
sandbox := &vcmock.Sandbox{
|
|
MockID: testContainerID,
|
|
}
|
|
|
|
sandbox.MockContainers = []*vcmock.Container{
|
|
{
|
|
MockID: testContainerID,
|
|
MockPid: cmd.Process.Pid,
|
|
MockSandbox: sandbox,
|
|
},
|
|
}
|
|
|
|
// create a new runtime config
|
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, consolePath, true)
|
|
assert.NoError(err)
|
|
|
|
configJSON, err := readOCIConfigJSON(configPath)
|
|
assert.NoError(err)
|
|
|
|
return runContainerData{
|
|
pidFilePath: pidFilePath,
|
|
consolePath: consolePath,
|
|
bundlePath: bundlePath,
|
|
configJSON: configJSON,
|
|
sandbox: sandbox,
|
|
runtimeConfig: runtimeConfig,
|
|
process: cmd.Process,
|
|
tmpDir: tmpdir,
|
|
}
|
|
}
|
|
|
|
func TestRunContainerSuccessful(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
d := testRunContainerSetup(t)
|
|
defer os.RemoveAll(d.tmpDir)
|
|
|
|
// this flags is used to detect if createSandboxFunc was called
|
|
flagCreate := false
|
|
|
|
// fake functions used to run containers
|
|
testingImpl.CreateSandboxFunc = func(sandboxConfig vc.SandboxConfig) (vc.VCSandbox, error) {
|
|
flagCreate = true
|
|
return d.sandbox, nil
|
|
}
|
|
|
|
testingImpl.StartSandboxFunc = func(sandboxID string) (vc.VCSandbox, error) {
|
|
return d.sandbox, nil
|
|
}
|
|
|
|
path, err := ioutil.TempDir("", "containers-mapping")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
ctrsMapTreePath = path
|
|
|
|
testingImpl.StatusContainerFunc = func(sandboxID, containerID string) (vc.ContainerStatus, error) {
|
|
// return an empty list on create
|
|
if !flagCreate {
|
|
return vc.ContainerStatus{}, nil
|
|
}
|
|
|
|
// return a sandboxStatus with the container status
|
|
return vc.ContainerStatus{
|
|
ID: d.sandbox.ID(),
|
|
Annotations: map[string]string{
|
|
vcAnnotations.ContainerTypeKey: string(vc.PodContainer),
|
|
vcAnnotations.ConfigJSONKey: d.configJSON,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
testingImpl.StartContainerFunc = func(sandboxID, containerID string) (vc.VCContainer, error) {
|
|
// now we can kill the fake container workload
|
|
err := d.process.Kill()
|
|
assert.NoError(err)
|
|
|
|
return d.sandbox.MockContainers[0], nil
|
|
}
|
|
|
|
testingImpl.DeleteSandboxFunc = func(sandboxID string) (vc.VCSandbox, error) {
|
|
return d.sandbox, nil
|
|
}
|
|
|
|
testingImpl.DeleteContainerFunc = func(sandboxID, containerID string) (vc.VCContainer, error) {
|
|
return d.sandbox.MockContainers[0], nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.CreateSandboxFunc = nil
|
|
testingImpl.StartSandboxFunc = nil
|
|
testingImpl.StatusContainerFunc = nil
|
|
testingImpl.StartContainerFunc = nil
|
|
testingImpl.DeleteSandboxFunc = nil
|
|
testingImpl.DeleteContainerFunc = nil
|
|
}()
|
|
|
|
err = run(context.Background(), d.sandbox.ID(), d.bundlePath, d.consolePath, "", d.pidFilePath, false, d.runtimeConfig)
|
|
|
|
// should return ExitError with the message and exit code
|
|
e, ok := err.(*cli.ExitError)
|
|
assert.True(ok, "error should be a cli.ExitError: %s", err)
|
|
assert.Empty(e.Error())
|
|
assert.NotZero(e.ExitCode())
|
|
}
|
|
|
|
func TestRunContainerDetachSuccessful(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
d := testRunContainerSetup(t)
|
|
defer os.RemoveAll(d.tmpDir)
|
|
|
|
// this flags is used to detect if createSandboxFunc was called
|
|
flagCreate := false
|
|
|
|
// fake functions used to run containers
|
|
testingImpl.CreateSandboxFunc = func(sandboxConfig vc.SandboxConfig) (vc.VCSandbox, error) {
|
|
flagCreate = true
|
|
return d.sandbox, nil
|
|
}
|
|
|
|
testingImpl.StartSandboxFunc = func(sandboxID string) (vc.VCSandbox, error) {
|
|
return d.sandbox, nil
|
|
}
|
|
|
|
path, err := ioutil.TempDir("", "containers-mapping")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
ctrsMapTreePath = path
|
|
|
|
testingImpl.StatusContainerFunc = func(sandboxID, containerID string) (vc.ContainerStatus, error) {
|
|
// return an empty list on create
|
|
if !flagCreate {
|
|
return vc.ContainerStatus{}, nil
|
|
}
|
|
|
|
// return a sandboxStatus with the container status
|
|
return vc.ContainerStatus{
|
|
ID: d.sandbox.ID(),
|
|
Annotations: map[string]string{
|
|
vcAnnotations.ContainerTypeKey: string(vc.PodContainer),
|
|
vcAnnotations.ConfigJSONKey: d.configJSON,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
testingImpl.StartContainerFunc = func(sandboxID, containerID string) (vc.VCContainer, error) {
|
|
// now we can kill the fake container workload
|
|
err := d.process.Kill()
|
|
assert.NoError(err)
|
|
|
|
return d.sandbox.MockContainers[0], nil
|
|
}
|
|
|
|
testingImpl.DeleteSandboxFunc = func(sandboxID string) (vc.VCSandbox, error) {
|
|
return d.sandbox, nil
|
|
}
|
|
|
|
testingImpl.DeleteContainerFunc = func(sandboxID, containerID string) (vc.VCContainer, error) {
|
|
return d.sandbox.MockContainers[0], nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.CreateSandboxFunc = nil
|
|
testingImpl.StartSandboxFunc = nil
|
|
testingImpl.StatusContainerFunc = nil
|
|
testingImpl.StartContainerFunc = nil
|
|
testingImpl.DeleteSandboxFunc = nil
|
|
testingImpl.DeleteContainerFunc = nil
|
|
}()
|
|
|
|
err = run(context.Background(), d.sandbox.ID(), d.bundlePath, d.consolePath, "", d.pidFilePath, true, d.runtimeConfig)
|
|
|
|
// should not return ExitError
|
|
assert.NoError(err)
|
|
}
|
|
|
|
func TestRunContainerDeleteFail(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
d := testRunContainerSetup(t)
|
|
defer os.RemoveAll(d.tmpDir)
|
|
|
|
// this flags is used to detect if createSandboxFunc was called
|
|
flagCreate := false
|
|
|
|
// fake functions used to run containers
|
|
testingImpl.CreateSandboxFunc = func(sandboxConfig vc.SandboxConfig) (vc.VCSandbox, error) {
|
|
flagCreate = true
|
|
return d.sandbox, nil
|
|
}
|
|
|
|
testingImpl.StartSandboxFunc = func(sandboxID string) (vc.VCSandbox, error) {
|
|
return d.sandbox, nil
|
|
}
|
|
|
|
path, err := ioutil.TempDir("", "containers-mapping")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
ctrsMapTreePath = path
|
|
|
|
testingImpl.StatusContainerFunc = func(sandboxID, containerID string) (vc.ContainerStatus, error) {
|
|
// return an empty list on create
|
|
if !flagCreate {
|
|
return vc.ContainerStatus{}, nil
|
|
}
|
|
|
|
// return a sandboxStatus with the container status
|
|
return vc.ContainerStatus{
|
|
ID: d.sandbox.ID(),
|
|
Annotations: map[string]string{
|
|
vcAnnotations.ContainerTypeKey: string(vc.PodContainer),
|
|
vcAnnotations.ConfigJSONKey: d.configJSON,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
testingImpl.StartContainerFunc = func(sandboxID, containerID string) (vc.VCContainer, error) {
|
|
// now we can kill the fake container workload
|
|
err := d.process.Kill()
|
|
assert.NoError(err)
|
|
|
|
return d.sandbox.MockContainers[0], nil
|
|
}
|
|
|
|
testingImpl.DeleteSandboxFunc = func(sandboxID string) (vc.VCSandbox, error) {
|
|
// return an error to provoke a failure in delete
|
|
return nil, fmt.Errorf("DeleteSandboxFunc")
|
|
}
|
|
|
|
testingImpl.DeleteContainerFunc = func(sandboxID, containerID string) (vc.VCContainer, error) {
|
|
// return an error to provoke a failure in delete
|
|
return d.sandbox.MockContainers[0], fmt.Errorf("DeleteContainerFunc")
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.CreateSandboxFunc = nil
|
|
testingImpl.StartSandboxFunc = nil
|
|
testingImpl.StatusContainerFunc = nil
|
|
testingImpl.StartContainerFunc = nil
|
|
testingImpl.DeleteSandboxFunc = nil
|
|
testingImpl.DeleteContainerFunc = nil
|
|
}()
|
|
|
|
err = run(context.Background(), d.sandbox.ID(), d.bundlePath, d.consolePath, "", d.pidFilePath, false, d.runtimeConfig)
|
|
|
|
// should not return ExitError
|
|
err, ok := err.(*cli.ExitError)
|
|
assert.False(ok, "error should not be a cli.ExitError: %s", err)
|
|
}
|
|
|
|
func TestRunContainerWaitFail(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
d := testRunContainerSetup(t)
|
|
defer os.RemoveAll(d.tmpDir)
|
|
|
|
// this flags is used to detect if createSandboxFunc was called
|
|
flagCreate := false
|
|
|
|
// fake functions used to run containers
|
|
testingImpl.CreateSandboxFunc = func(sandboxConfig vc.SandboxConfig) (vc.VCSandbox, error) {
|
|
flagCreate = true
|
|
return d.sandbox, nil
|
|
}
|
|
|
|
testingImpl.StartSandboxFunc = func(sandboxID string) (vc.VCSandbox, error) {
|
|
return d.sandbox, nil
|
|
}
|
|
|
|
path, err := ioutil.TempDir("", "containers-mapping")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
ctrsMapTreePath = path
|
|
|
|
testingImpl.StatusContainerFunc = func(sandboxID, containerID string) (vc.ContainerStatus, error) {
|
|
// return an empty list on create
|
|
if !flagCreate {
|
|
return vc.ContainerStatus{}, nil
|
|
}
|
|
|
|
// return a sandboxStatus with the container status
|
|
return vc.ContainerStatus{
|
|
ID: d.sandbox.ID(),
|
|
Annotations: map[string]string{
|
|
vcAnnotations.ContainerTypeKey: string(vc.PodContainer),
|
|
vcAnnotations.ConfigJSONKey: d.configJSON,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
testingImpl.StartContainerFunc = func(sandboxID, containerID string) (vc.VCContainer, error) {
|
|
// now we can kill the fake container workload
|
|
err := d.process.Kill()
|
|
assert.NoError(err)
|
|
|
|
// change PID to provoke a failure in Wait
|
|
d.sandbox.MockContainers[0].MockPid = -1
|
|
|
|
return d.sandbox.MockContainers[0], nil
|
|
}
|
|
|
|
testingImpl.DeleteSandboxFunc = func(sandboxID string) (vc.VCSandbox, error) {
|
|
// return an error to provoke a failure in delete
|
|
return nil, fmt.Errorf("DeleteSandboxFunc")
|
|
}
|
|
|
|
testingImpl.DeleteContainerFunc = func(sandboxID, containerID string) (vc.VCContainer, error) {
|
|
// return an error to provoke a failure in delete
|
|
return d.sandbox.MockContainers[0], fmt.Errorf("DeleteContainerFunc")
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.CreateSandboxFunc = nil
|
|
testingImpl.StartSandboxFunc = nil
|
|
testingImpl.StatusContainerFunc = nil
|
|
testingImpl.StartContainerFunc = nil
|
|
testingImpl.DeleteSandboxFunc = nil
|
|
testingImpl.DeleteContainerFunc = nil
|
|
}()
|
|
|
|
err = run(context.Background(), d.sandbox.ID(), d.bundlePath, d.consolePath, "", d.pidFilePath, false, d.runtimeConfig)
|
|
|
|
// should not return ExitError
|
|
err, ok := err.(*cli.ExitError)
|
|
assert.False(ok, "error should not be a cli.ExitError: %s", err)
|
|
}
|
|
|
|
func TestRunContainerStartFail(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
d := testRunContainerSetup(t)
|
|
defer os.RemoveAll(d.tmpDir)
|
|
|
|
// now we can kill the fake container workload
|
|
err := d.process.Kill()
|
|
assert.NoError(err)
|
|
|
|
// this flags is used to detect if createSandboxFunc was called
|
|
flagCreate := false
|
|
|
|
// fake functions used to run containers
|
|
testingImpl.CreateSandboxFunc = func(sandboxConfig vc.SandboxConfig) (vc.VCSandbox, error) {
|
|
flagCreate = true
|
|
return d.sandbox, nil
|
|
}
|
|
|
|
testingImpl.StartSandboxFunc = func(sandboxID string) (vc.VCSandbox, error) {
|
|
// start fails
|
|
return nil, fmt.Errorf("StartSandbox")
|
|
}
|
|
|
|
path, err := ioutil.TempDir("", "containers-mapping")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
ctrsMapTreePath = path
|
|
|
|
testingImpl.StatusContainerFunc = func(sandboxID, containerID string) (vc.ContainerStatus, error) {
|
|
// return an empty list on create
|
|
if !flagCreate {
|
|
return vc.ContainerStatus{}, nil
|
|
}
|
|
|
|
// return a sandboxStatus with the container status
|
|
return vc.ContainerStatus{
|
|
ID: d.sandbox.ID(),
|
|
Annotations: map[string]string{
|
|
vcAnnotations.ContainerTypeKey: string(vc.PodContainer),
|
|
vcAnnotations.ConfigJSONKey: d.configJSON,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.CreateSandboxFunc = nil
|
|
testingImpl.StartSandboxFunc = nil
|
|
testingImpl.StatusContainerFunc = nil
|
|
}()
|
|
|
|
err = run(context.Background(), d.sandbox.ID(), d.bundlePath, d.consolePath, "", d.pidFilePath, false, d.runtimeConfig)
|
|
|
|
// should not return ExitError
|
|
err, ok := err.(*cli.ExitError)
|
|
assert.False(ok, "error should not be a cli.ExitError: %s", err)
|
|
}
|
|
|
|
func TestRunContainerStartFailExistingContainer(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
d := testRunContainerSetup(t)
|
|
defer os.RemoveAll(d.tmpDir)
|
|
|
|
sandbox := &vcmock.Sandbox{
|
|
MockID: testSandboxID,
|
|
}
|
|
|
|
sandbox.MockContainers = []*vcmock.Container{
|
|
{
|
|
MockID: testContainerID,
|
|
MockSandbox: sandbox,
|
|
},
|
|
}
|
|
|
|
path, err := createTempContainerIDMapping(testContainerID, sandbox.ID())
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
|
|
testingImpl.StatusContainerFunc = func(sandboxID, containerID string) (vc.ContainerStatus, error) {
|
|
// return the container status
|
|
return vc.ContainerStatus{
|
|
ID: testContainerID,
|
|
Annotations: map[string]string{
|
|
vcAnnotations.ContainerTypeKey: string(vc.PodContainer),
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
testingImpl.CreateSandboxFunc = func(sandboxConfig vc.SandboxConfig) (vc.VCSandbox, error) {
|
|
return sandbox, nil
|
|
}
|
|
|
|
testingImpl.StartSandboxFunc = func(sandboxID string) (vc.VCSandbox, error) {
|
|
// force no containers
|
|
sandbox.MockContainers = nil
|
|
|
|
return sandbox, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.StatusContainerFunc = nil
|
|
testingImpl.CreateSandboxFunc = nil
|
|
testingImpl.StartSandboxFunc = nil
|
|
}()
|
|
|
|
err = run(context.Background(), d.sandbox.ID(), d.bundlePath, d.consolePath, "", d.pidFilePath, false, d.runtimeConfig)
|
|
assert.Error(err)
|
|
assert.False(vcmock.IsMockError(err))
|
|
}
|