mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-07-04 11:06:21 +00:00
containerd-shim-kata: add unit test cases
Add unit test cases. Signed-off-by: fupan <lifupan@gmail.com>
This commit is contained in:
parent
7951041eb0
commit
8199d10742
40
containerd-shim-v2/container_test.go
Normal file
40
containerd-shim-v2/container_test.go
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2018 HyperHQ Inc.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package containerdshim
|
||||
|
||||
import (
|
||||
taskAPI "github.com/containerd/containerd/runtime/v2/task"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewContainer(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
_, err := newContainer(nil, nil, "", nil)
|
||||
|
||||
assert.Error(err)
|
||||
}
|
||||
|
||||
func TestGetExec(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
r := &taskAPI.CreateTaskRequest{}
|
||||
|
||||
c, err := newContainer(nil, r, "", nil)
|
||||
assert.NoError(err)
|
||||
|
||||
_, err = c.getExec("")
|
||||
assert.Error(err)
|
||||
|
||||
c.execs = make(map[string]*exec)
|
||||
_, err = c.getExec("")
|
||||
assert.Error(err)
|
||||
|
||||
c.execs[TestID] = &exec{}
|
||||
_, err = c.getExec(TestID)
|
||||
assert.NoError(err)
|
||||
}
|
363
containerd-shim-v2/create_test.go
Normal file
363
containerd-shim-v2/create_test.go
Normal file
@ -0,0 +1,363 @@
|
||||
// Copyright (c) 2017 Intel Corporation
|
||||
// Copyright (c) 2018 HyperHQ Inc.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package containerdshim
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
taskAPI "github.com/containerd/containerd/runtime/v2/task"
|
||||
|
||||
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||
"github.com/kata-containers/runtime/virtcontainers/pkg/vcmock"
|
||||
|
||||
"github.com/kata-containers/runtime/pkg/katautils"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCreateSandboxSuccess(t *testing.T) {
|
||||
if os.Geteuid() != 0 {
|
||||
t.Skip(testDisabledNeedRoot)
|
||||
}
|
||||
|
||||
assert := assert.New(t)
|
||||
|
||||
sandbox := &vcmock.Sandbox{
|
||||
MockID: testSandboxID,
|
||||
MockContainers: []*vcmock.Container{
|
||||
{MockID: testContainerID},
|
||||
},
|
||||
}
|
||||
|
||||
testingImpl.CreateSandboxFunc = func(ctx context.Context, sandboxConfig vc.SandboxConfig) (vc.VCSandbox, error) {
|
||||
return sandbox, nil
|
||||
}
|
||||
|
||||
defer func() {
|
||||
testingImpl.CreateSandboxFunc = nil
|
||||
}()
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "")
|
||||
assert.NoError(err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
||||
assert.NoError(err)
|
||||
|
||||
bundlePath := filepath.Join(tmpdir, "bundle")
|
||||
|
||||
err = makeOCIBundle(bundlePath)
|
||||
assert.NoError(err)
|
||||
|
||||
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
||||
assert.True(katautils.FileExists(ociConfigFile))
|
||||
|
||||
spec, err := readOCIConfigFile(ociConfigFile)
|
||||
assert.NoError(err)
|
||||
|
||||
// Force sandbox-type container
|
||||
spec.Annotations = make(map[string]string)
|
||||
spec.Annotations[testContainerTypeAnnotation] = testContainerTypeSandbox
|
||||
|
||||
// Set a limit to ensure processCgroupsPath() considers the
|
||||
// cgroup part of the spec
|
||||
limit := int64(1024 * 1024)
|
||||
spec.Linux.Resources.Memory = &specs.LinuxMemory{
|
||||
Limit: &limit,
|
||||
}
|
||||
|
||||
// Rewrite the file
|
||||
err = writeOCIConfigFile(spec, ociConfigFile)
|
||||
assert.NoError(err)
|
||||
|
||||
s := &service{
|
||||
id: testSandboxID,
|
||||
containers: make(map[string]*container),
|
||||
config: &runtimeConfig,
|
||||
}
|
||||
|
||||
req := &taskAPI.CreateTaskRequest{
|
||||
ID: testSandboxID,
|
||||
Bundle: bundlePath,
|
||||
Terminal: true,
|
||||
}
|
||||
|
||||
ctx := namespaces.WithNamespace(context.Background(), "UnitTest")
|
||||
_, err = s.Create(ctx, req)
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
func TestCreateSandboxFail(t *testing.T) {
|
||||
if os.Geteuid() != 0 {
|
||||
t.Skip(testDisabledNeedRoot)
|
||||
}
|
||||
assert := assert.New(t)
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "")
|
||||
assert.NoError(err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
||||
assert.NoError(err)
|
||||
|
||||
bundlePath := filepath.Join(tmpdir, "bundle")
|
||||
|
||||
err = makeOCIBundle(bundlePath)
|
||||
assert.NoError(err)
|
||||
|
||||
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
||||
assert.True(katautils.FileExists(ociConfigFile))
|
||||
|
||||
spec, err := readOCIConfigFile(ociConfigFile)
|
||||
assert.NoError(err)
|
||||
|
||||
err = writeOCIConfigFile(spec, ociConfigFile)
|
||||
assert.NoError(err)
|
||||
|
||||
s := &service{
|
||||
id: testSandboxID,
|
||||
containers: make(map[string]*container),
|
||||
config: &runtimeConfig,
|
||||
}
|
||||
|
||||
req := &taskAPI.CreateTaskRequest{
|
||||
ID: testSandboxID,
|
||||
Bundle: bundlePath,
|
||||
Terminal: true,
|
||||
}
|
||||
|
||||
ctx := namespaces.WithNamespace(context.Background(), "UnitTest")
|
||||
_, err = s.Create(ctx, req)
|
||||
assert.Error(err)
|
||||
assert.True(vcmock.IsMockError(err))
|
||||
}
|
||||
|
||||
func TestCreateSandboxConfigFail(t *testing.T) {
|
||||
if os.Geteuid() != 0 {
|
||||
t.Skip(testDisabledNeedRoot)
|
||||
}
|
||||
|
||||
assert := assert.New(t)
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "")
|
||||
assert.NoError(err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
||||
assert.NoError(err)
|
||||
|
||||
bundlePath := filepath.Join(tmpdir, "bundle")
|
||||
|
||||
err = makeOCIBundle(bundlePath)
|
||||
assert.NoError(err)
|
||||
|
||||
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
||||
assert.True(katautils.FileExists(ociConfigFile))
|
||||
|
||||
spec, err := readOCIConfigFile(ociConfigFile)
|
||||
assert.NoError(err)
|
||||
|
||||
quota := int64(0)
|
||||
limit := int64(0)
|
||||
|
||||
spec.Linux.Resources.Memory = &specs.LinuxMemory{
|
||||
Limit: &limit,
|
||||
}
|
||||
|
||||
// specify an invalid spec
|
||||
spec.Linux.Resources.CPU = &specs.LinuxCPU{
|
||||
Quota: "a,
|
||||
}
|
||||
|
||||
s := &service{
|
||||
id: testSandboxID,
|
||||
containers: make(map[string]*container),
|
||||
config: &runtimeConfig,
|
||||
}
|
||||
|
||||
req := &taskAPI.CreateTaskRequest{
|
||||
ID: testSandboxID,
|
||||
Bundle: bundlePath,
|
||||
Terminal: true,
|
||||
}
|
||||
|
||||
ctx := namespaces.WithNamespace(context.Background(), "UnitTest")
|
||||
_, err = s.Create(ctx, req)
|
||||
assert.Error(err)
|
||||
assert.True(vcmock.IsMockError(err))
|
||||
}
|
||||
|
||||
func TestCreateContainerSuccess(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
sandbox := &vcmock.Sandbox{
|
||||
MockID: testSandboxID,
|
||||
}
|
||||
|
||||
testingImpl.CreateContainerFunc = func(ctx context.Context, sandboxID string, containerConfig vc.ContainerConfig) (vc.VCSandbox, vc.VCContainer, error) {
|
||||
return sandbox, &vcmock.Container{}, nil
|
||||
}
|
||||
|
||||
defer func() {
|
||||
testingImpl.CreateContainerFunc = nil
|
||||
}()
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "")
|
||||
assert.NoError(err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
||||
assert.NoError(err)
|
||||
|
||||
bundlePath := filepath.Join(tmpdir, "bundle")
|
||||
|
||||
err = makeOCIBundle(bundlePath)
|
||||
assert.NoError(err)
|
||||
|
||||
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
||||
assert.True(katautils.FileExists(ociConfigFile))
|
||||
|
||||
spec, err := readOCIConfigFile(ociConfigFile)
|
||||
assert.NoError(err)
|
||||
|
||||
// set expected container type and sandboxID
|
||||
spec.Annotations = make(map[string]string)
|
||||
spec.Annotations[testContainerTypeAnnotation] = testContainerTypeContainer
|
||||
spec.Annotations[testSandboxIDAnnotation] = testSandboxID
|
||||
|
||||
// rewrite file
|
||||
err = writeOCIConfigFile(spec, ociConfigFile)
|
||||
assert.NoError(err)
|
||||
|
||||
s := &service{
|
||||
id: testContainerID,
|
||||
sandbox: sandbox,
|
||||
containers: make(map[string]*container),
|
||||
config: &runtimeConfig,
|
||||
}
|
||||
|
||||
req := &taskAPI.CreateTaskRequest{
|
||||
ID: testContainerID,
|
||||
Bundle: bundlePath,
|
||||
Terminal: true,
|
||||
}
|
||||
|
||||
ctx := namespaces.WithNamespace(context.Background(), "UnitTest")
|
||||
_, err = s.Create(ctx, req)
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
func TestCreateContainerFail(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "")
|
||||
assert.NoError(err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
||||
assert.NoError(err)
|
||||
|
||||
bundlePath := filepath.Join(tmpdir, "bundle")
|
||||
|
||||
err = makeOCIBundle(bundlePath)
|
||||
assert.NoError(err)
|
||||
|
||||
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
||||
assert.True(katautils.FileExists(ociConfigFile))
|
||||
|
||||
spec, err := readOCIConfigFile(ociConfigFile)
|
||||
assert.NoError(err)
|
||||
|
||||
spec.Annotations = make(map[string]string)
|
||||
spec.Annotations[testContainerTypeAnnotation] = testContainerTypeContainer
|
||||
spec.Annotations[testSandboxIDAnnotation] = testSandboxID
|
||||
|
||||
err = writeOCIConfigFile(spec, ociConfigFile)
|
||||
assert.NoError(err)
|
||||
|
||||
// doesn't create sandbox first
|
||||
s := &service{
|
||||
id: testContainerID,
|
||||
containers: make(map[string]*container),
|
||||
config: &runtimeConfig,
|
||||
}
|
||||
|
||||
req := &taskAPI.CreateTaskRequest{
|
||||
ID: testContainerID,
|
||||
Bundle: bundlePath,
|
||||
Terminal: true,
|
||||
}
|
||||
|
||||
ctx := namespaces.WithNamespace(context.Background(), "UnitTest")
|
||||
_, err = s.Create(ctx, req)
|
||||
assert.Error(err)
|
||||
assert.False(vcmock.IsMockError(err))
|
||||
}
|
||||
|
||||
func TestCreateContainerConfigFail(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
sandbox := &vcmock.Sandbox{
|
||||
MockID: testSandboxID,
|
||||
}
|
||||
|
||||
testingImpl.CreateContainerFunc = func(ctx context.Context, sandboxID string, containerConfig vc.ContainerConfig) (vc.VCSandbox, vc.VCContainer, error) {
|
||||
return sandbox, &vcmock.Container{}, nil
|
||||
}
|
||||
|
||||
defer func() {
|
||||
testingImpl.CreateContainerFunc = nil
|
||||
}()
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "")
|
||||
assert.NoError(err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
||||
assert.NoError(err)
|
||||
|
||||
bundlePath := filepath.Join(tmpdir, "bundle")
|
||||
|
||||
err = makeOCIBundle(bundlePath)
|
||||
assert.NoError(err)
|
||||
|
||||
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
||||
assert.True(katautils.FileExists(ociConfigFile))
|
||||
|
||||
spec, err := readOCIConfigFile(ociConfigFile)
|
||||
assert.NoError(err)
|
||||
|
||||
// set the error containerType
|
||||
spec.Annotations = make(map[string]string)
|
||||
spec.Annotations[testContainerTypeAnnotation] = "errorType"
|
||||
spec.Annotations[testSandboxIDAnnotation] = testSandboxID
|
||||
|
||||
err = writeOCIConfigFile(spec, ociConfigFile)
|
||||
assert.NoError(err)
|
||||
|
||||
s := &service{
|
||||
id: testContainerID,
|
||||
sandbox: sandbox,
|
||||
containers: make(map[string]*container),
|
||||
config: &runtimeConfig,
|
||||
}
|
||||
|
||||
req := &taskAPI.CreateTaskRequest{
|
||||
ID: testContainerID,
|
||||
Bundle: bundlePath,
|
||||
Terminal: true,
|
||||
}
|
||||
|
||||
ctx := namespaces.WithNamespace(context.Background(), "UnitTest")
|
||||
_, err = s.Create(ctx, req)
|
||||
assert.Error(err)
|
||||
}
|
61
containerd-shim-v2/delete_test.go
Normal file
61
containerd-shim-v2/delete_test.go
Normal file
@ -0,0 +1,61 @@
|
||||
// Copyright (c) 2017 Intel Corporation
|
||||
// Copyright (c) 2018 HyperHQ Inc.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package containerdshim
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
taskAPI "github.com/containerd/containerd/runtime/v2/task"
|
||||
"github.com/kata-containers/runtime/virtcontainers/pkg/vcmock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDeleteContainerSuccessAndFail(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
sandbox := &vcmock.Sandbox{
|
||||
MockID: testSandboxID,
|
||||
}
|
||||
|
||||
rootPath, configPath := testConfigSetup(t)
|
||||
defer os.RemoveAll(rootPath)
|
||||
_, err := readOCIConfigJSON(configPath)
|
||||
assert.NoError(err)
|
||||
|
||||
s := &service{
|
||||
id: testSandboxID,
|
||||
sandbox: sandbox,
|
||||
containers: make(map[string]*container),
|
||||
}
|
||||
|
||||
reqCreate := &taskAPI.CreateTaskRequest{
|
||||
ID: testContainerID,
|
||||
}
|
||||
s.containers[testContainerID], err = newContainer(s, reqCreate, "", nil)
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
func testConfigSetup(t *testing.T) (rootPath string, configPath string) {
|
||||
assert := assert.New(t)
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "")
|
||||
assert.NoError(err)
|
||||
|
||||
bundlePath := filepath.Join(tmpdir, "bundle")
|
||||
err = os.MkdirAll(bundlePath, testDirMode)
|
||||
assert.NoError(err)
|
||||
|
||||
err = createOCIConfig(bundlePath)
|
||||
assert.NoError(err)
|
||||
|
||||
// config json path
|
||||
configPath = filepath.Join(bundlePath, "config.json")
|
||||
return tmpdir, configPath
|
||||
}
|
50
containerd-shim-v2/exec_test.go
Normal file
50
containerd-shim-v2/exec_test.go
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2017 Intel Corporation
|
||||
// Copyright (c) 2018 HyperHQ Inc.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package containerdshim
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
|
||||
taskAPI "github.com/containerd/containerd/runtime/v2/task"
|
||||
"github.com/kata-containers/runtime/virtcontainers/pkg/vcmock"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestExecNoSpecFail(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
sandbox := &vcmock.Sandbox{
|
||||
MockID: testSandboxID,
|
||||
}
|
||||
|
||||
s := &service{
|
||||
id: testSandboxID,
|
||||
sandbox: sandbox,
|
||||
containers: make(map[string]*container),
|
||||
}
|
||||
|
||||
reqCreate := &taskAPI.CreateTaskRequest{
|
||||
ID: testContainerID,
|
||||
}
|
||||
|
||||
var err error
|
||||
s.containers[testContainerID], err = newContainer(s, reqCreate, "", nil)
|
||||
assert.NoError(err)
|
||||
|
||||
reqExec := &taskAPI.ExecProcessRequest{
|
||||
ID: testContainerID,
|
||||
ExecID: testContainerID,
|
||||
}
|
||||
ctx := namespaces.WithNamespace(context.Background(), "UnitTest")
|
||||
|
||||
_, err = s.Exec(ctx, reqExec)
|
||||
assert.Error(err)
|
||||
}
|
202
containerd-shim-v2/pause_test.go
Normal file
202
containerd-shim-v2/pause_test.go
Normal file
@ -0,0 +1,202 @@
|
||||
// Copyright (c) 2017 Intel Corporation
|
||||
// Copyright (c) 2018 HyperHQ Inc.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package containerdshim
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
taskAPI "github.com/containerd/containerd/runtime/v2/task"
|
||||
|
||||
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||
"github.com/kata-containers/runtime/virtcontainers/pkg/vcmock"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestPauseContainerSuccess(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
var err error
|
||||
|
||||
sandbox := &vcmock.Sandbox{
|
||||
MockID: testSandboxID,
|
||||
}
|
||||
|
||||
testingImpl.PauseContainerFunc = func(ctx context.Context, sandboxID, containerID string) error {
|
||||
return nil
|
||||
}
|
||||
defer func() {
|
||||
testingImpl.PauseContainerFunc = nil
|
||||
}()
|
||||
|
||||
testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) {
|
||||
return vc.ContainerStatus{
|
||||
ID: testContainerID,
|
||||
Annotations: make(map[string]string),
|
||||
State: vc.State{
|
||||
State: vc.StateRunning,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
defer func() {
|
||||
testingImpl.StatusContainerFunc = nil
|
||||
}()
|
||||
|
||||
s := &service{
|
||||
id: testSandboxID,
|
||||
sandbox: sandbox,
|
||||
containers: make(map[string]*container),
|
||||
}
|
||||
|
||||
reqCreate := &taskAPI.CreateTaskRequest{
|
||||
ID: testContainerID,
|
||||
}
|
||||
s.containers[testContainerID], err = newContainer(s, reqCreate, "", nil)
|
||||
assert.NoError(err)
|
||||
|
||||
reqPause := &taskAPI.PauseRequest{
|
||||
ID: testContainerID,
|
||||
}
|
||||
ctx := namespaces.WithNamespace(context.Background(), "UnitTest")
|
||||
|
||||
_, err = s.Pause(ctx, reqPause)
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
func TestPauseContainerFail(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
sandbox := &vcmock.Sandbox{
|
||||
MockID: testSandboxID,
|
||||
}
|
||||
|
||||
testingImpl.PauseContainerFunc = func(ctx context.Context, sandboxID, containerID string) error {
|
||||
return nil
|
||||
}
|
||||
defer func() {
|
||||
testingImpl.PauseContainerFunc = nil
|
||||
}()
|
||||
|
||||
testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) {
|
||||
return vc.ContainerStatus{
|
||||
ID: testContainerID,
|
||||
Annotations: make(map[string]string),
|
||||
State: vc.State{
|
||||
State: vc.StateRunning,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
defer func() {
|
||||
testingImpl.StatusContainerFunc = nil
|
||||
}()
|
||||
|
||||
s := &service{
|
||||
id: testSandboxID,
|
||||
sandbox: sandbox,
|
||||
containers: make(map[string]*container),
|
||||
}
|
||||
|
||||
reqPause := &taskAPI.PauseRequest{
|
||||
ID: testContainerID,
|
||||
}
|
||||
ctx := namespaces.WithNamespace(context.Background(), "UnitTest")
|
||||
|
||||
_, err := s.Pause(ctx, reqPause)
|
||||
assert.Error(err)
|
||||
}
|
||||
|
||||
func TestResumeContainerSuccess(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
var err error
|
||||
|
||||
sandbox := &vcmock.Sandbox{
|
||||
MockID: testSandboxID,
|
||||
}
|
||||
|
||||
testingImpl.ResumeContainerFunc = func(ctx context.Context, sandboxID, containerID string) error {
|
||||
return nil
|
||||
}
|
||||
defer func() {
|
||||
testingImpl.ResumeContainerFunc = nil
|
||||
}()
|
||||
|
||||
testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) {
|
||||
return vc.ContainerStatus{
|
||||
ID: testContainerID,
|
||||
Annotations: make(map[string]string),
|
||||
State: vc.State{
|
||||
State: vc.StateRunning,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
defer func() {
|
||||
testingImpl.StatusContainerFunc = nil
|
||||
}()
|
||||
|
||||
s := &service{
|
||||
id: testSandboxID,
|
||||
sandbox: sandbox,
|
||||
containers: make(map[string]*container),
|
||||
}
|
||||
|
||||
reqCreate := &taskAPI.CreateTaskRequest{
|
||||
ID: testContainerID,
|
||||
}
|
||||
s.containers[testContainerID], err = newContainer(s, reqCreate, "", nil)
|
||||
assert.NoError(err)
|
||||
|
||||
reqResume := &taskAPI.ResumeRequest{
|
||||
ID: testContainerID,
|
||||
}
|
||||
ctx := namespaces.WithNamespace(context.Background(), "UnitTest")
|
||||
|
||||
_, err = s.Resume(ctx, reqResume)
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
func TestResumeContainerFail(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
sandbox := &vcmock.Sandbox{
|
||||
MockID: testSandboxID,
|
||||
}
|
||||
|
||||
testingImpl.ResumeContainerFunc = func(ctx context.Context, sandboxID, containerID string) error {
|
||||
return nil
|
||||
}
|
||||
defer func() {
|
||||
testingImpl.ResumeContainerFunc = nil
|
||||
}()
|
||||
testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) {
|
||||
return vc.ContainerStatus{
|
||||
ID: testContainerID,
|
||||
Annotations: make(map[string]string),
|
||||
State: vc.State{
|
||||
State: vc.StateRunning,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
defer func() {
|
||||
testingImpl.StatusContainerFunc = nil
|
||||
}()
|
||||
|
||||
s := &service{
|
||||
id: testSandboxID,
|
||||
sandbox: sandbox,
|
||||
containers: make(map[string]*container),
|
||||
}
|
||||
|
||||
reqResume := &taskAPI.ResumeRequest{
|
||||
ID: testContainerID,
|
||||
}
|
||||
ctx := namespaces.WithNamespace(context.Background(), "UnitTest")
|
||||
|
||||
_, err := s.Resume(ctx, reqResume)
|
||||
assert.Error(err)
|
||||
}
|
177
containerd-shim-v2/start_test.go
Normal file
177
containerd-shim-v2/start_test.go
Normal file
@ -0,0 +1,177 @@
|
||||
// Copyright (c) 2017 Intel Corporation
|
||||
// Copyright (c) 2018 HyperHQ Inc.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package containerdshim
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
taskAPI "github.com/containerd/containerd/runtime/v2/task"
|
||||
|
||||
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||
vcAnnotations "github.com/kata-containers/runtime/virtcontainers/pkg/annotations"
|
||||
"github.com/kata-containers/runtime/virtcontainers/pkg/vcmock"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestStartStartSandboxSuccess(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
var err error
|
||||
|
||||
sandbox := &vcmock.Sandbox{
|
||||
MockID: testSandboxID,
|
||||
}
|
||||
|
||||
testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) {
|
||||
return vc.ContainerStatus{
|
||||
ID: sandbox.ID(),
|
||||
Annotations: map[string]string{
|
||||
vcAnnotations.ContainerTypeKey: string(vc.PodSandbox),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
defer func() {
|
||||
testingImpl.StatusContainerFunc = nil
|
||||
}()
|
||||
|
||||
s := &service{
|
||||
id: testSandboxID,
|
||||
sandbox: sandbox,
|
||||
containers: make(map[string]*container),
|
||||
}
|
||||
|
||||
reqCreate := &taskAPI.CreateTaskRequest{
|
||||
ID: testSandboxID,
|
||||
}
|
||||
s.containers[testSandboxID], err = newContainer(s, reqCreate, vc.PodSandbox, nil)
|
||||
assert.NoError(err)
|
||||
|
||||
reqStart := &taskAPI.StartRequest{
|
||||
ID: testSandboxID,
|
||||
}
|
||||
|
||||
testingImpl.StartSandboxFunc = func(ctx context.Context, sandboxID string) (vc.VCSandbox, error) {
|
||||
return sandbox, nil
|
||||
}
|
||||
|
||||
defer func() {
|
||||
testingImpl.StartSandboxFunc = nil
|
||||
}()
|
||||
|
||||
ctx := namespaces.WithNamespace(context.Background(), "UnitTest")
|
||||
_, err = s.Start(ctx, reqStart)
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
func TestStartMissingAnnotation(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
var err error
|
||||
|
||||
sandbox := &vcmock.Sandbox{
|
||||
MockID: testSandboxID,
|
||||
}
|
||||
|
||||
testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) {
|
||||
return vc.ContainerStatus{
|
||||
ID: sandbox.ID(),
|
||||
Annotations: map[string]string{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
defer func() {
|
||||
testingImpl.StatusContainerFunc = nil
|
||||
}()
|
||||
|
||||
s := &service{
|
||||
id: testSandboxID,
|
||||
sandbox: sandbox,
|
||||
containers: make(map[string]*container),
|
||||
}
|
||||
|
||||
reqCreate := &taskAPI.CreateTaskRequest{
|
||||
ID: testSandboxID,
|
||||
}
|
||||
s.containers[testSandboxID], err = newContainer(s, reqCreate, "", nil)
|
||||
assert.NoError(err)
|
||||
|
||||
reqStart := &taskAPI.StartRequest{
|
||||
ID: testSandboxID,
|
||||
}
|
||||
|
||||
testingImpl.StartSandboxFunc = func(ctx context.Context, sandboxID string) (vc.VCSandbox, error) {
|
||||
return sandbox, nil
|
||||
}
|
||||
|
||||
defer func() {
|
||||
testingImpl.StartSandboxFunc = nil
|
||||
}()
|
||||
|
||||
ctx := namespaces.WithNamespace(context.Background(), "UnitTest")
|
||||
_, err = s.Start(ctx, reqStart)
|
||||
assert.Error(err)
|
||||
assert.False(vcmock.IsMockError(err))
|
||||
}
|
||||
|
||||
func TestStartStartContainerSucess(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
var err error
|
||||
|
||||
sandbox := &vcmock.Sandbox{
|
||||
MockID: testSandboxID,
|
||||
}
|
||||
|
||||
sandbox.MockContainers = []*vcmock.Container{
|
||||
{
|
||||
MockID: testContainerID,
|
||||
MockSandbox: sandbox,
|
||||
},
|
||||
}
|
||||
|
||||
testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) {
|
||||
return vc.ContainerStatus{
|
||||
ID: testContainerID,
|
||||
Annotations: map[string]string{
|
||||
vcAnnotations.ContainerTypeKey: string(vc.PodContainer),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
defer func() {
|
||||
testingImpl.StatusContainerFunc = nil
|
||||
}()
|
||||
|
||||
testingImpl.StartContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.VCContainer, error) {
|
||||
return sandbox.MockContainers[0], nil
|
||||
}
|
||||
|
||||
defer func() {
|
||||
testingImpl.StartContainerFunc = nil
|
||||
}()
|
||||
|
||||
s := &service{
|
||||
id: testSandboxID,
|
||||
sandbox: sandbox,
|
||||
containers: make(map[string]*container),
|
||||
}
|
||||
|
||||
reqCreate := &taskAPI.CreateTaskRequest{
|
||||
ID: testContainerID,
|
||||
}
|
||||
s.containers[testContainerID], err = newContainer(s, reqCreate, vc.PodContainer, nil)
|
||||
assert.NoError(err)
|
||||
|
||||
reqStart := &taskAPI.StartRequest{
|
||||
ID: testContainerID,
|
||||
}
|
||||
|
||||
ctx := namespaces.WithNamespace(context.Background(), "UnitTest")
|
||||
_, err = s.Start(ctx, reqStart)
|
||||
assert.NoError(err)
|
||||
}
|
375
containerd-shim-v2/utils_test.go
Normal file
375
containerd-shim-v2/utils_test.go
Normal file
@ -0,0 +1,375 @@
|
||||
// Copyright (c) 2017 Intel Corporation
|
||||
// Copyright (c) 2018 HyperHQ Inc.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package containerdshim
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
sysExec "os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/kata-containers/runtime/pkg/katautils"
|
||||
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
|
||||
"github.com/kata-containers/runtime/virtcontainers/pkg/vcmock"
|
||||
)
|
||||
|
||||
const (
|
||||
// specConf is the name of the file holding the containers configuration
|
||||
specConf = "config.json"
|
||||
|
||||
TestID = "container_test"
|
||||
|
||||
testDirMode = os.FileMode(0750)
|
||||
testFileMode = os.FileMode(0640)
|
||||
// testExeFileMode = os.FileMode(0750)
|
||||
|
||||
// small docker image used to create root filesystems from
|
||||
testDockerImage = "busybox"
|
||||
|
||||
testSandboxID = "777-77-77777777"
|
||||
testContainerID = "42"
|
||||
testBundle = "bundle"
|
||||
testConsole = "/dev/pts/888"
|
||||
|
||||
testDisabledNeedRoot = "Test disabled as requires root user"
|
||||
|
||||
testContainerTypeAnnotation = "io.kubernetes.cri.container-type"
|
||||
testSandboxIDAnnotation = "io.kubernetes.cri.sandbox-id"
|
||||
testContainerTypeSandbox = "sandbox"
|
||||
testContainerTypeContainer = "container"
|
||||
)
|
||||
|
||||
var (
|
||||
// package variables set by calling TestMain()
|
||||
testDir = ""
|
||||
testBundleDir = ""
|
||||
)
|
||||
|
||||
// testingImpl is a concrete mock RVC implementation used for testing
|
||||
var testingImpl = &vcmock.VCMock{}
|
||||
|
||||
func init() {
|
||||
fmt.Printf("INFO: running as actual user %v (effective %v), actual group %v (effective %v)\n",
|
||||
os.Getuid(), os.Geteuid(), os.Getgid(), os.Getegid())
|
||||
|
||||
fmt.Printf("INFO: switching to fake virtcontainers implementation for testing\n")
|
||||
vci = testingImpl
|
||||
|
||||
var err error
|
||||
|
||||
fmt.Printf("INFO: creating test directory\n")
|
||||
testDir, err = ioutil.TempDir("", fmt.Sprintf("shimV2-"))
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("ERROR: failed to create test directory: %v", err))
|
||||
}
|
||||
|
||||
fmt.Printf("INFO: test directory is %v\n", testDir)
|
||||
|
||||
fmt.Printf("INFO: ensuring docker is running\n")
|
||||
output, err := katautils.RunCommandFull([]string{"docker", "version"}, true)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("ERROR: docker daemon is not installed, not running, or not accessible to current user: %v (error %v)",
|
||||
output, err))
|
||||
}
|
||||
|
||||
// Do this now to avoid hitting the test timeout value due to
|
||||
// slow network response.
|
||||
fmt.Printf("INFO: ensuring required docker image (%v) is available\n", testDockerImage)
|
||||
|
||||
// Only hit the network if the image doesn't exist locally
|
||||
_, err = katautils.RunCommand([]string{"docker", "inspect", "--type=image", testDockerImage})
|
||||
if err == nil {
|
||||
fmt.Printf("INFO: docker image %v already exists locally\n", testDockerImage)
|
||||
} else {
|
||||
_, err = katautils.RunCommand([]string{"docker", "pull", testDockerImage})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
testBundleDir = filepath.Join(testDir, testBundle)
|
||||
err = os.MkdirAll(testBundleDir, testDirMode)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("ERROR: failed to create bundle directory %v: %v", testBundleDir, err))
|
||||
}
|
||||
|
||||
fmt.Printf("INFO: creating OCI bundle in %v for tests to use\n", testBundleDir)
|
||||
err = realMakeOCIBundle(testBundleDir)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("ERROR: failed to create OCI bundle: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
// createOCIConfig creates an OCI configuration (spec) file in
|
||||
// the bundle directory specified (which must exist).
|
||||
func createOCIConfig(bundleDir string) error {
|
||||
if bundleDir == "" {
|
||||
return errors.New("BUG: Need bundle directory")
|
||||
}
|
||||
|
||||
if !katautils.FileExists(bundleDir) {
|
||||
return fmt.Errorf("BUG: Bundle directory %s does not exist", bundleDir)
|
||||
}
|
||||
|
||||
var configCmd string
|
||||
|
||||
// Search for a suitable version of runc to use to generate
|
||||
// the OCI config file.
|
||||
for _, cmd := range []string{"docker-runc", "runc"} {
|
||||
fullPath, err := sysExec.LookPath(cmd)
|
||||
if err == nil {
|
||||
configCmd = fullPath
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if configCmd == "" {
|
||||
return errors.New("Cannot find command to generate OCI config file")
|
||||
}
|
||||
|
||||
_, err := katautils.RunCommand([]string{configCmd, "spec", "--bundle", bundleDir})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
specFile := filepath.Join(bundleDir, specConf)
|
||||
if !katautils.FileExists(specFile) {
|
||||
return fmt.Errorf("generated OCI config file does not exist: %v", specFile)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func createEmptyFile(path string) (err error) {
|
||||
return ioutil.WriteFile(path, []byte(""), testFileMode)
|
||||
}
|
||||
|
||||
// newTestHypervisorConfig creaets a new virtcontainers
|
||||
// HypervisorConfig, ensuring that the required resources are also
|
||||
// created.
|
||||
//
|
||||
// Note: no parameter validation in case caller wishes to create an invalid
|
||||
// object.
|
||||
func newTestHypervisorConfig(dir string, create bool) (vc.HypervisorConfig, error) {
|
||||
kernelPath := path.Join(dir, "kernel")
|
||||
imagePath := path.Join(dir, "image")
|
||||
hypervisorPath := path.Join(dir, "hypervisor")
|
||||
|
||||
if create {
|
||||
for _, file := range []string{kernelPath, imagePath, hypervisorPath} {
|
||||
err := createEmptyFile(file)
|
||||
if err != nil {
|
||||
return vc.HypervisorConfig{}, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vc.HypervisorConfig{
|
||||
KernelPath: kernelPath,
|
||||
ImagePath: imagePath,
|
||||
HypervisorPath: hypervisorPath,
|
||||
HypervisorMachineType: "pc-lite",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// newTestRuntimeConfig creates a new RuntimeConfig
|
||||
func newTestRuntimeConfig(dir, consolePath string, create bool) (oci.RuntimeConfig, error) {
|
||||
if dir == "" {
|
||||
return oci.RuntimeConfig{}, errors.New("BUG: need directory")
|
||||
}
|
||||
|
||||
hypervisorConfig, err := newTestHypervisorConfig(dir, create)
|
||||
if err != nil {
|
||||
return oci.RuntimeConfig{}, err
|
||||
}
|
||||
|
||||
return oci.RuntimeConfig{
|
||||
HypervisorType: vc.QemuHypervisor,
|
||||
HypervisorConfig: hypervisorConfig,
|
||||
AgentType: vc.KataContainersAgent,
|
||||
ProxyType: vc.KataBuiltInProxyType,
|
||||
ShimType: vc.KataBuiltInShimType,
|
||||
Console: consolePath,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// readOCIConfig returns an OCI spec.
|
||||
func readOCIConfigFile(configPath string) (oci.CompatOCISpec, error) {
|
||||
if configPath == "" {
|
||||
return oci.CompatOCISpec{}, errors.New("BUG: need config file path")
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(configPath)
|
||||
if err != nil {
|
||||
return oci.CompatOCISpec{}, err
|
||||
}
|
||||
|
||||
var ociSpec oci.CompatOCISpec
|
||||
if err := json.Unmarshal(data, &ociSpec); err != nil {
|
||||
return oci.CompatOCISpec{}, err
|
||||
}
|
||||
caps, err := oci.ContainerCapabilities(ociSpec)
|
||||
if err != nil {
|
||||
return oci.CompatOCISpec{}, err
|
||||
}
|
||||
ociSpec.Process.Capabilities = caps
|
||||
return ociSpec, nil
|
||||
}
|
||||
|
||||
// realMakeOCIBundle will create an OCI bundle (including the "config.json"
|
||||
// config file) in the directory specified (which must already exist).
|
||||
//
|
||||
// XXX: Note that tests should *NOT* call this function - they should
|
||||
// XXX: instead call makeOCIBundle().
|
||||
func realMakeOCIBundle(bundleDir string) error {
|
||||
if bundleDir == "" {
|
||||
return errors.New("BUG: Need bundle directory")
|
||||
}
|
||||
|
||||
if !katautils.FileExists(bundleDir) {
|
||||
return fmt.Errorf("BUG: Bundle directory %v does not exist", bundleDir)
|
||||
}
|
||||
|
||||
err := createOCIConfig(bundleDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Note the unusual parameter (a directory, not the config
|
||||
// file to parse!)
|
||||
spec, err := oci.ParseConfigJSON(bundleDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Determine the rootfs directory name the OCI config refers to
|
||||
ociRootPath := spec.Root.Path
|
||||
|
||||
rootfsDir := filepath.Join(bundleDir, ociRootPath)
|
||||
|
||||
if strings.HasPrefix(ociRootPath, "/") {
|
||||
return fmt.Errorf("Cannot handle absolute rootfs as bundle must be unique to each test")
|
||||
}
|
||||
|
||||
err = createRootfs(rootfsDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create an OCI bundle in the specified directory.
|
||||
//
|
||||
// Note that the directory will be created, but it's parent is expected to exist.
|
||||
//
|
||||
// This function works by copying the already-created test bundle. Ideally,
|
||||
// the bundle would be recreated for each test, but createRootfs() uses
|
||||
// docker which on some systems is too slow, resulting in the tests timing
|
||||
// out.
|
||||
func makeOCIBundle(bundleDir string) error {
|
||||
from := testBundleDir
|
||||
to := bundleDir
|
||||
|
||||
// only the basename of bundleDir needs to exist as bundleDir
|
||||
// will get created by cp(1).
|
||||
base := filepath.Dir(bundleDir)
|
||||
|
||||
for _, dir := range []string{from, base} {
|
||||
if !katautils.FileExists(dir) {
|
||||
return fmt.Errorf("BUG: directory %v should exist", dir)
|
||||
}
|
||||
}
|
||||
|
||||
output, err := katautils.RunCommandFull([]string{"cp", "-a", from, to}, true)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to copy test OCI bundle from %v to %v: %v (output: %v)", from, to, err, output)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// createRootfs creates a minimal root filesystem below the specified
|
||||
// directory.
|
||||
func createRootfs(dir string) error {
|
||||
err := os.MkdirAll(dir, testDirMode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
container, err := katautils.RunCommand([]string{"docker", "create", testDockerImage})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd1 := sysExec.Command("docker", "export", container)
|
||||
cmd2 := sysExec.Command("tar", "-C", dir, "-xvf", "-")
|
||||
|
||||
cmd1Stdout, err := cmd1.StdoutPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd2.Stdin = cmd1Stdout
|
||||
|
||||
err = cmd2.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = cmd1.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = cmd2.Wait()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Clean up
|
||||
_, err = katautils.RunCommand([]string{"docker", "rm", container})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeOCIConfigFile(spec oci.CompatOCISpec, configPath string) error {
|
||||
if configPath == "" {
|
||||
return errors.New("BUG: need config file path")
|
||||
}
|
||||
|
||||
bytes, err := json.MarshalIndent(spec, "", "\t")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(configPath, bytes, testFileMode)
|
||||
}
|
||||
|
||||
// Read fail that should contain a CompatOCISpec and
|
||||
// return its JSON representation on success
|
||||
func readOCIConfigJSON(configFile string) (string, error) {
|
||||
bundlePath := filepath.Dir(configFile)
|
||||
ociSpec, err := oci.ParseConfigJSON(bundlePath)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
ociSpecJSON, err := json.Marshal(ociSpec)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(ociSpecJSON), err
|
||||
}
|
Loading…
Reference in New Issue
Block a user