mirror of
https://github.com/aljazceru/kata-containers.git
synced 2025-12-25 10:04:20 +01:00
Fixes: #2023 CompatOCISpec is used to gurantee backward compatbility for old runtime specs, after we convert CompatOCISpec to standard specs.Spec, we should use specs.Spec instead of CompatOCISpec, and CompatOCISpec should be useless from then. Spread usage of CompatOCISpec can make code structure confusing and making the runtime spec usage non-standard. Besides, this can be the very first step of removing CompatOCISpec from config's Annotations field. Signed-off-by: Wei Zhang <weizhang555.zw@gmail.com>
624 lines
16 KiB
Go
624 lines
16 KiB
Go
// Copyright (c) 2017 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
ktu "github.com/kata-containers/runtime/pkg/katatestutils"
|
|
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/kata-containers/runtime/virtcontainers/types"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/urfave/cli"
|
|
)
|
|
|
|
func testRemoveCgroupsPathSuccessful(t *testing.T, cgroupsPathList []string) {
|
|
if err := removeCgroupsPath(context.Background(), "foo", cgroupsPathList); err != nil {
|
|
t.Fatalf("This test should succeed (cgroupsPathList = %v): %s", cgroupsPathList, err)
|
|
}
|
|
}
|
|
|
|
func TestRemoveCgroupsPathEmptyPathSuccessful(t *testing.T) {
|
|
testRemoveCgroupsPathSuccessful(t, []string{})
|
|
}
|
|
|
|
func TestRemoveCgroupsPathNonEmptyPathSuccessful(t *testing.T) {
|
|
cgroupsPath, err := ioutil.TempDir(testDir, "cgroups-path-")
|
|
if err != nil {
|
|
t.Fatalf("Could not create temporary cgroups directory: %s", err)
|
|
}
|
|
|
|
if err := os.MkdirAll(cgroupsPath, testDirMode); err != nil {
|
|
t.Fatalf("CgroupsPath directory %q could not be created: %s", cgroupsPath, err)
|
|
}
|
|
|
|
testRemoveCgroupsPathSuccessful(t, []string{cgroupsPath})
|
|
|
|
if _, err := os.Stat(cgroupsPath); err == nil {
|
|
t.Fatalf("CgroupsPath directory %q should have been removed: %s", cgroupsPath, err)
|
|
}
|
|
}
|
|
|
|
func TestDeleteInvalidContainer(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
// Missing container id
|
|
err := delete(context.Background(), "", false)
|
|
assert.Error(err)
|
|
assert.False(vcmock.IsMockError(err))
|
|
|
|
path, err := ioutil.TempDir("", "containers-mapping")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
ctrsMapTreePath = path
|
|
|
|
// Container missing in ListSandbox
|
|
err = delete(context.Background(), testContainerID, false)
|
|
assert.Error(err)
|
|
assert.False(vcmock.IsMockError(err))
|
|
|
|
// Force to delete missing container
|
|
err = delete(context.Background(), "non-existing-test", true)
|
|
assert.NoError(err)
|
|
}
|
|
|
|
func TestDeleteMissingContainerTypeAnnotation(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
sandbox := &vcmock.Sandbox{
|
|
MockID: testSandboxID,
|
|
}
|
|
|
|
path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID())
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
|
|
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
|
|
}()
|
|
|
|
err = delete(context.Background(), sandbox.ID(), false)
|
|
assert.Error(err)
|
|
assert.False(vcmock.IsMockError(err))
|
|
}
|
|
|
|
func TestDeleteInvalidConfig(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
sandbox := &vcmock.Sandbox{
|
|
MockID: testSandboxID,
|
|
}
|
|
|
|
path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID())
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
|
|
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
|
|
}()
|
|
|
|
err = delete(context.Background(), sandbox.ID(), false)
|
|
assert.Error(err)
|
|
assert.False(vcmock.IsMockError(err))
|
|
}
|
|
|
|
func testConfigSetup(t *testing.T) (rootPath string, bundlePath 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)
|
|
|
|
return tmpdir, bundlePath
|
|
}
|
|
|
|
func TestDeleteSandbox(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
sandbox := &vcmock.Sandbox{
|
|
MockID: testSandboxID,
|
|
}
|
|
|
|
rootPath, bundlePath := testConfigSetup(t)
|
|
defer os.RemoveAll(rootPath)
|
|
configJSON, err := readOCIConfigJSON(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID())
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
|
|
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),
|
|
vcAnnotations.ConfigJSONKey: configJSON,
|
|
},
|
|
State: types.ContainerState{
|
|
State: "ready",
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.StatusContainerFunc = nil
|
|
}()
|
|
|
|
err = delete(context.Background(), sandbox.ID(), false)
|
|
assert.Error(err)
|
|
assert.True(vcmock.IsMockError(err))
|
|
|
|
testingImpl.StatusSandboxFunc = func(ctx context.Context, sandboxID string) (vc.SandboxStatus, error) {
|
|
return vc.SandboxStatus{
|
|
ID: sandbox.ID(),
|
|
State: types.SandboxState{
|
|
State: types.StateReady,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.StatusSandboxFunc = nil
|
|
}()
|
|
|
|
err = delete(context.Background(), sandbox.ID(), false)
|
|
assert.Error(err)
|
|
assert.True(vcmock.IsMockError(err))
|
|
|
|
testingImpl.StopSandboxFunc = func(ctx context.Context, sandboxID string, force bool) (vc.VCSandbox, error) {
|
|
return sandbox, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.StopSandboxFunc = nil
|
|
}()
|
|
|
|
err = delete(context.Background(), sandbox.ID(), false)
|
|
assert.Error(err)
|
|
assert.True(vcmock.IsMockError(err))
|
|
|
|
testingImpl.DeleteSandboxFunc = func(ctx context.Context, sandboxID string) (vc.VCSandbox, error) {
|
|
return sandbox, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.DeleteSandboxFunc = nil
|
|
}()
|
|
|
|
err = delete(context.Background(), sandbox.ID(), false)
|
|
assert.Nil(err)
|
|
}
|
|
|
|
func TestDeleteInvalidContainerType(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
sandbox := &vcmock.Sandbox{
|
|
MockID: testSandboxID,
|
|
}
|
|
|
|
rootPath, bundlePath := testConfigSetup(t)
|
|
defer os.RemoveAll(rootPath)
|
|
configJSON, err := readOCIConfigJSON(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID())
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
|
|
testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) {
|
|
return vc.ContainerStatus{
|
|
ID: sandbox.ID(),
|
|
Annotations: map[string]string{
|
|
vcAnnotations.ContainerTypeKey: "InvalidType",
|
|
vcAnnotations.ConfigJSONKey: configJSON,
|
|
},
|
|
State: types.ContainerState{
|
|
State: "created",
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.StatusContainerFunc = nil
|
|
}()
|
|
|
|
// Delete an invalid container type
|
|
err = delete(context.Background(), sandbox.ID(), false)
|
|
assert.Error(err)
|
|
assert.False(vcmock.IsMockError(err))
|
|
}
|
|
|
|
func TestDeleteSandboxRunning(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
sandbox := &vcmock.Sandbox{
|
|
MockID: testSandboxID,
|
|
}
|
|
|
|
rootPath, bundlePath := testConfigSetup(t)
|
|
defer os.RemoveAll(rootPath)
|
|
configJSON, err := readOCIConfigJSON(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID())
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
|
|
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),
|
|
vcAnnotations.ConfigJSONKey: configJSON,
|
|
},
|
|
State: types.ContainerState{
|
|
State: "running",
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.StatusContainerFunc = nil
|
|
}()
|
|
|
|
// Delete on a running sandbox should fail
|
|
err = delete(context.Background(), sandbox.ID(), false)
|
|
assert.Error(err)
|
|
assert.False(vcmock.IsMockError(err))
|
|
|
|
testingImpl.StatusSandboxFunc = func(ctx context.Context, sandboxID string) (vc.SandboxStatus, error) {
|
|
return vc.SandboxStatus{
|
|
ID: sandbox.ID(),
|
|
State: types.SandboxState{
|
|
State: types.StateRunning,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
testingImpl.StopSandboxFunc = func(ctx context.Context, sandboxID string, force bool) (vc.VCSandbox, error) {
|
|
return sandbox, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.StatusSandboxFunc = nil
|
|
testingImpl.StopSandboxFunc = nil
|
|
}()
|
|
|
|
// Force delete a running sandbox
|
|
err = delete(context.Background(), sandbox.ID(), true)
|
|
assert.Error(err)
|
|
assert.True(vcmock.IsMockError(err))
|
|
|
|
testingImpl.DeleteSandboxFunc = func(ctx context.Context, sandboxID string) (vc.VCSandbox, error) {
|
|
return sandbox, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.DeleteSandboxFunc = nil
|
|
}()
|
|
|
|
err = delete(context.Background(), sandbox.ID(), true)
|
|
assert.Nil(err)
|
|
}
|
|
|
|
func TestDeleteRunningContainer(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
sandbox := &vcmock.Sandbox{
|
|
MockID: testSandboxID,
|
|
}
|
|
|
|
sandbox.MockContainers = []*vcmock.Container{
|
|
{
|
|
MockID: testContainerID,
|
|
MockSandbox: sandbox,
|
|
},
|
|
}
|
|
|
|
rootPath, bundlePath := testConfigSetup(t)
|
|
defer os.RemoveAll(rootPath)
|
|
configJSON, err := readOCIConfigJSON(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
path, err := createTempContainerIDMapping(sandbox.MockContainers[0].ID(), sandbox.MockContainers[0].ID())
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
|
|
testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) {
|
|
return vc.ContainerStatus{
|
|
ID: sandbox.MockContainers[0].ID(),
|
|
Annotations: map[string]string{
|
|
vcAnnotations.ContainerTypeKey: string(vc.PodContainer),
|
|
vcAnnotations.ConfigJSONKey: configJSON,
|
|
},
|
|
State: types.ContainerState{
|
|
State: "running",
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.StatusContainerFunc = nil
|
|
}()
|
|
|
|
// Delete on a running container should fail.
|
|
err = delete(context.Background(), sandbox.MockContainers[0].ID(), false)
|
|
assert.Error(err)
|
|
assert.False(vcmock.IsMockError(err))
|
|
|
|
path, err = createTempContainerIDMapping(sandbox.MockContainers[0].ID(), sandbox.MockContainers[0].ID())
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
|
|
// force delete
|
|
err = delete(context.Background(), sandbox.MockContainers[0].ID(), true)
|
|
assert.Error(err)
|
|
assert.True(vcmock.IsMockError(err))
|
|
|
|
testingImpl.StopContainerFunc = testStopContainerFuncReturnNil
|
|
defer func() {
|
|
testingImpl.StopContainerFunc = nil
|
|
}()
|
|
|
|
path, err = createTempContainerIDMapping(sandbox.MockContainers[0].ID(), sandbox.MockContainers[0].ID())
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
|
|
err = delete(context.Background(), sandbox.MockContainers[0].ID(), true)
|
|
assert.Error(err)
|
|
assert.True(vcmock.IsMockError(err))
|
|
|
|
testingImpl.DeleteContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.VCContainer, error) {
|
|
return &vcmock.Container{}, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.DeleteContainerFunc = nil
|
|
}()
|
|
|
|
path, err = createTempContainerIDMapping(sandbox.MockContainers[0].ID(), sandbox.MockContainers[0].ID())
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
|
|
err = delete(context.Background(), sandbox.MockContainers[0].ID(), true)
|
|
assert.Nil(err)
|
|
}
|
|
|
|
func TestDeleteContainer(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
sandbox := &vcmock.Sandbox{
|
|
MockID: testSandboxID,
|
|
}
|
|
|
|
sandbox.MockContainers = []*vcmock.Container{
|
|
{
|
|
MockID: testContainerID,
|
|
MockSandbox: sandbox,
|
|
},
|
|
}
|
|
|
|
rootPath, bundlePath := testConfigSetup(t)
|
|
defer os.RemoveAll(rootPath)
|
|
configJSON, err := readOCIConfigJSON(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
path, err := createTempContainerIDMapping(sandbox.MockContainers[0].ID(), sandbox.MockContainers[0].ID())
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
|
|
testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) {
|
|
return vc.ContainerStatus{
|
|
ID: sandbox.MockContainers[0].ID(),
|
|
Annotations: map[string]string{
|
|
vcAnnotations.ContainerTypeKey: string(vc.PodContainer),
|
|
vcAnnotations.ConfigJSONKey: configJSON,
|
|
},
|
|
State: types.ContainerState{
|
|
State: "ready",
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.StatusContainerFunc = nil
|
|
}()
|
|
|
|
err = delete(context.Background(), sandbox.MockContainers[0].ID(), false)
|
|
assert.Error(err)
|
|
assert.True(vcmock.IsMockError(err))
|
|
|
|
path, err = createTempContainerIDMapping(sandbox.MockContainers[0].ID(), sandbox.MockContainers[0].ID())
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
|
|
testingImpl.StopContainerFunc = testStopContainerFuncReturnNil
|
|
defer func() {
|
|
testingImpl.StopContainerFunc = nil
|
|
}()
|
|
|
|
err = delete(context.Background(), sandbox.MockContainers[0].ID(), false)
|
|
assert.Error(err)
|
|
assert.True(vcmock.IsMockError(err))
|
|
|
|
testingImpl.DeleteContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.VCContainer, error) {
|
|
return &vcmock.Container{}, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.DeleteContainerFunc = nil
|
|
}()
|
|
|
|
path, err = createTempContainerIDMapping(sandbox.MockContainers[0].ID(), sandbox.MockContainers[0].ID())
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
|
|
err = delete(context.Background(), sandbox.MockContainers[0].ID(), false)
|
|
assert.Nil(err)
|
|
}
|
|
|
|
func TestDeleteCLIFunction(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
flagSet := &flag.FlagSet{}
|
|
ctx := createCLIContext(flagSet)
|
|
|
|
fn, ok := deleteCLICommand.Action.(func(context *cli.Context) error)
|
|
assert.True(ok)
|
|
|
|
// no container id in the Metadata
|
|
err := fn(ctx)
|
|
assert.Error(err)
|
|
assert.False(vcmock.IsMockError(err))
|
|
|
|
path, err := createTempContainerIDMapping("xyz", "xyz")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
|
|
flagSet = flag.NewFlagSet("container-id", flag.ContinueOnError)
|
|
flagSet.Parse([]string{"xyz"})
|
|
ctx = createCLIContext(flagSet)
|
|
|
|
err = fn(ctx)
|
|
assert.Error(err)
|
|
assert.True(vcmock.IsMockError(err))
|
|
}
|
|
|
|
func TestDeleteCLIFunctionSuccess(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
sandbox := &vcmock.Sandbox{
|
|
MockID: testSandboxID,
|
|
}
|
|
|
|
sandbox.MockContainers = []*vcmock.Container{
|
|
{
|
|
MockID: testContainerID,
|
|
MockSandbox: sandbox,
|
|
},
|
|
}
|
|
|
|
rootPath, bundlePath := testConfigSetup(t)
|
|
defer os.RemoveAll(rootPath)
|
|
configJSON, err := readOCIConfigJSON(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID())
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
|
|
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),
|
|
vcAnnotations.ConfigJSONKey: configJSON,
|
|
},
|
|
State: types.ContainerState{
|
|
State: "ready",
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
testingImpl.StatusSandboxFunc = func(ctx context.Context, sandboxID string) (vc.SandboxStatus, error) {
|
|
return vc.SandboxStatus{
|
|
ID: sandbox.ID(),
|
|
State: types.SandboxState{
|
|
State: types.StateReady,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
testingImpl.StopSandboxFunc = func(ctx context.Context, sandboxID string, force bool) (vc.VCSandbox, error) {
|
|
return sandbox, nil
|
|
}
|
|
|
|
testingImpl.DeleteSandboxFunc = func(ctx context.Context, sandboxID string) (vc.VCSandbox, error) {
|
|
return sandbox, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.StatusContainerFunc = nil
|
|
testingImpl.StopSandboxFunc = nil
|
|
testingImpl.DeleteSandboxFunc = nil
|
|
}()
|
|
|
|
flagSet := &flag.FlagSet{}
|
|
ctx := createCLIContext(flagSet)
|
|
|
|
fn, ok := deleteCLICommand.Action.(func(context *cli.Context) error)
|
|
assert.True(ok)
|
|
|
|
err = fn(ctx)
|
|
assert.Error(err)
|
|
assert.False(vcmock.IsMockError(err))
|
|
|
|
flagSet = flag.NewFlagSet("container-id", flag.ContinueOnError)
|
|
flagSet.Parse([]string{sandbox.ID()})
|
|
ctx = createCLIContext(flagSet)
|
|
assert.NotNil(ctx)
|
|
|
|
err = fn(ctx)
|
|
assert.NoError(err)
|
|
}
|
|
|
|
func TestRemoveCGroupsPath(t *testing.T) {
|
|
if tc.NotValid(ktu.NeedNonRoot()) {
|
|
t.Skip(ktu.TestDisabledNeedNonRoot)
|
|
}
|
|
|
|
assert := assert.New(t)
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
dir := filepath.Join(tmpdir, "dir")
|
|
|
|
err = os.Mkdir(dir, testDirMode)
|
|
assert.NoError(err)
|
|
|
|
// make directory unreadable by non-root user
|
|
err = os.Chmod(tmpdir, 0000)
|
|
assert.NoError(err)
|
|
defer func() {
|
|
_ = os.Chmod(tmpdir, 0755)
|
|
}()
|
|
|
|
err = removeCgroupsPath(context.Background(), "foo", []string{dir})
|
|
assert.Error(err)
|
|
}
|