mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-07-19 01:39:48 +00:00
Merge pull request #5994 from dcantah/virtcontainers_tests_darwin
virtcontainers: tests: Ensure Linux specific tests are just run on Linux
This commit is contained in:
commit
07e77f5be7
@ -3,6 +3,9 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
package virtcontainers
|
package virtcontainers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
302
src/runtime/virtcontainers/container_linux_test.go
Normal file
302
src/runtime/virtcontainers/container_linux_test.go
Normal file
@ -0,0 +1,302 @@
|
|||||||
|
// Copyright (c) 2017 Intel Corporation
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
package virtcontainers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/config"
|
||||||
|
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/manager"
|
||||||
|
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
||||||
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestUnmountHostMountsRemoveBindHostPath(t *testing.T) {
|
||||||
|
if tc.NotValid(ktu.NeedRoot()) {
|
||||||
|
t.Skip(testDisabledAsNonRoot)
|
||||||
|
}
|
||||||
|
|
||||||
|
createFakeMountDir := func(t *testing.T, dir, prefix string) string {
|
||||||
|
name, err := os.MkdirTemp(dir, "test-mnt-"+prefix+"-")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
createFakeMountFile := func(t *testing.T, dir, prefix string) string {
|
||||||
|
f, err := os.CreateTemp(dir, "test-mnt-"+prefix+"-")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
f.Close()
|
||||||
|
return f.Name()
|
||||||
|
}
|
||||||
|
|
||||||
|
doUnmountCheck := func(s *Sandbox, src, dest, hostPath, nonEmptyHostpath, devPath string) {
|
||||||
|
mounts := []Mount{
|
||||||
|
{
|
||||||
|
Source: src,
|
||||||
|
Destination: dest,
|
||||||
|
HostPath: hostPath,
|
||||||
|
Type: "bind",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Source: src,
|
||||||
|
Destination: dest,
|
||||||
|
HostPath: nonEmptyHostpath,
|
||||||
|
Type: "bind",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Source: src,
|
||||||
|
Destination: dest,
|
||||||
|
HostPath: devPath,
|
||||||
|
Type: "dev",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
c := Container{
|
||||||
|
mounts: mounts,
|
||||||
|
ctx: context.Background(),
|
||||||
|
id: "fooabr",
|
||||||
|
sandbox: s,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := bindMount(c.ctx, src, hostPath, false, "private"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer syscall.Unmount(hostPath, 0)
|
||||||
|
if err := bindMount(c.ctx, src, nonEmptyHostpath, false, "private"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer syscall.Unmount(nonEmptyHostpath, 0)
|
||||||
|
if err := bindMount(c.ctx, src, devPath, false, "private"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer syscall.Unmount(devPath, 0)
|
||||||
|
|
||||||
|
err := c.unmountHostMounts(c.ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, path := range [3]string{src, dest, devPath} {
|
||||||
|
if _, err := os.Stat(path); err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
t.Fatalf("path %s should not be removed", path)
|
||||||
|
} else {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(hostPath); err == nil {
|
||||||
|
t.Fatal("empty host-path should be removed")
|
||||||
|
} else if !os.IsNotExist(err) {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(nonEmptyHostpath); err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
t.Fatal("non-empty host-path should not be removed")
|
||||||
|
} else {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
src := createFakeMountDir(t, testDir, "src")
|
||||||
|
dest := createFakeMountDir(t, testDir, "dest")
|
||||||
|
hostPath := createFakeMountDir(t, testDir, "host-path")
|
||||||
|
nonEmptyHostpath := createFakeMountDir(t, testDir, "non-empty-host-path")
|
||||||
|
devPath := createFakeMountDir(t, testDir, "dev-hostpath")
|
||||||
|
// create sandbox for mounting into
|
||||||
|
sandbox := &Sandbox{
|
||||||
|
ctx: context.Background(),
|
||||||
|
id: "foobar",
|
||||||
|
config: &SandboxConfig{},
|
||||||
|
}
|
||||||
|
|
||||||
|
fsShare, err := NewFilesystemShare(sandbox)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
sandbox.fsShare = fsShare
|
||||||
|
|
||||||
|
createFakeMountDir(t, nonEmptyHostpath, "nop")
|
||||||
|
doUnmountCheck(sandbox, src, dest, hostPath, nonEmptyHostpath, devPath)
|
||||||
|
|
||||||
|
src = createFakeMountFile(t, testDir, "src")
|
||||||
|
dest = createFakeMountFile(t, testDir, "dest")
|
||||||
|
hostPath = createFakeMountFile(t, testDir, "host-path")
|
||||||
|
nonEmptyHostpath = createFakeMountFile(t, testDir, "non-empty-host-path")
|
||||||
|
devPath = createFakeMountFile(t, testDir, "dev-host-path")
|
||||||
|
f, err := os.OpenFile(nonEmptyHostpath, os.O_WRONLY, os.FileMode(0640))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
f.WriteString("nop\n")
|
||||||
|
f.Close()
|
||||||
|
doUnmountCheck(sandbox, src, dest, hostPath, nonEmptyHostpath, devPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSetupFakeRootfs(t *testing.T) (testRawFile, loopDev, mntDir string, err error) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
if tc.NotValid(ktu.NeedRoot()) {
|
||||||
|
t.Skip(testDisabledAsNonRoot)
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
|
||||||
|
testRawFile = filepath.Join(tmpDir, "raw.img")
|
||||||
|
_, err = os.Stat(testRawFile)
|
||||||
|
assert.True(os.IsNotExist(err))
|
||||||
|
|
||||||
|
output, err := exec.Command("losetup", "-f").CombinedOutput()
|
||||||
|
assert.NoError(err)
|
||||||
|
loopDev = strings.TrimSpace(string(output[:]))
|
||||||
|
|
||||||
|
_, err = exec.Command("fallocate", "-l", "256K", testRawFile).CombinedOutput()
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
_, err = exec.Command("mkfs.ext4", "-F", testRawFile).CombinedOutput()
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
_, err = exec.Command("losetup", loopDev, testRawFile).CombinedOutput()
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
mntDir = filepath.Join(tmpDir, "rootfs")
|
||||||
|
err = os.Mkdir(mntDir, DirMode)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
err = syscall.Mount(loopDev, mntDir, "ext4", uintptr(0), "")
|
||||||
|
assert.NoError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanupFakeRootfsSetup(testRawFile, loopDev, mntDir string) {
|
||||||
|
// unmount loop device
|
||||||
|
if mntDir != "" {
|
||||||
|
syscall.Unmount(mntDir, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// detach loop device
|
||||||
|
if loopDev != "" {
|
||||||
|
exec.Command("losetup", "-d", loopDev).CombinedOutput()
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(testRawFile); err == nil {
|
||||||
|
tmpDir := filepath.Dir(testRawFile)
|
||||||
|
os.RemoveAll(tmpDir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContainerAddDriveDir(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
if tc.NotValid(ktu.NeedRoot()) {
|
||||||
|
t.Skip(testDisabledAsNonRoot)
|
||||||
|
}
|
||||||
|
|
||||||
|
testRawFile, loopDev, fakeRootfs, err := testSetupFakeRootfs(t)
|
||||||
|
|
||||||
|
defer cleanupFakeRootfsSetup(testRawFile, loopDev, fakeRootfs)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
sandbox := &Sandbox{
|
||||||
|
ctx: context.Background(),
|
||||||
|
id: testSandboxID,
|
||||||
|
devManager: manager.NewDeviceManager(config.VirtioSCSI, false, "", nil),
|
||||||
|
hypervisor: &mockHypervisor{},
|
||||||
|
agent: &mockAgent{},
|
||||||
|
config: &SandboxConfig{
|
||||||
|
HypervisorConfig: HypervisorConfig{
|
||||||
|
DisableBlockDeviceUse: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
sandbox.store, err = persist.GetDriver()
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(sandbox.store)
|
||||||
|
|
||||||
|
defer sandbox.store.Destroy(sandbox.id)
|
||||||
|
|
||||||
|
contID := "100"
|
||||||
|
container := Container{
|
||||||
|
sandbox: sandbox,
|
||||||
|
id: contID,
|
||||||
|
rootFs: RootFs{Target: fakeRootfs, Mounted: true},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the checkStorageDriver func variable point to a fake Check function
|
||||||
|
savedFunc := checkStorageDriver
|
||||||
|
checkStorageDriver = func(major, minor int) (bool, error) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
checkStorageDriver = savedFunc
|
||||||
|
}()
|
||||||
|
|
||||||
|
container.state.Fstype = ""
|
||||||
|
|
||||||
|
err = container.hotplugDrive(sandbox.ctx)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
assert.NotEmpty(container.state.Fstype)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContainerRootfsPath(t *testing.T) {
|
||||||
|
|
||||||
|
testRawFile, loopDev, fakeRootfs, err := testSetupFakeRootfs(t)
|
||||||
|
defer cleanupFakeRootfsSetup(testRawFile, loopDev, fakeRootfs)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
truecheckstoragedriver := checkStorageDriver
|
||||||
|
checkStorageDriver = func(major, minor int) (bool, error) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
checkStorageDriver = truecheckstoragedriver
|
||||||
|
}()
|
||||||
|
|
||||||
|
sandbox := &Sandbox{
|
||||||
|
ctx: context.Background(),
|
||||||
|
id: "rootfstestsandbox",
|
||||||
|
agent: &mockAgent{},
|
||||||
|
hypervisor: &mockHypervisor{},
|
||||||
|
config: &SandboxConfig{
|
||||||
|
HypervisorConfig: HypervisorConfig{
|
||||||
|
DisableBlockDeviceUse: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
container := Container{
|
||||||
|
id: "rootfstestcontainerid",
|
||||||
|
sandbox: sandbox,
|
||||||
|
rootFs: RootFs{Target: fakeRootfs, Mounted: true},
|
||||||
|
rootfsSuffix: "rootfs",
|
||||||
|
}
|
||||||
|
|
||||||
|
container.hotplugDrive(sandbox.ctx)
|
||||||
|
assert.Empty(t, container.rootfsSuffix)
|
||||||
|
|
||||||
|
// Reset the value to test the other case
|
||||||
|
container.rootFs = RootFs{Target: fakeRootfs + "/rootfs", Mounted: true}
|
||||||
|
container.rootfsSuffix = "rootfs"
|
||||||
|
|
||||||
|
container.hotplugDrive(sandbox.ctx)
|
||||||
|
assert.Equal(t, container.rootfsSuffix, "rootfs")
|
||||||
|
}
|
@ -8,9 +8,7 @@ package virtcontainers
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -18,8 +16,6 @@ import (
|
|||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/config"
|
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/config"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/drivers"
|
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/drivers"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/manager"
|
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/manager"
|
||||||
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist"
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
@ -124,286 +120,6 @@ func TestContainerRemoveDrive(t *testing.T) {
|
|||||||
assert.Nil(t, err, "remove drive should succeed")
|
assert.Nil(t, err, "remove drive should succeed")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnmountHostMountsRemoveBindHostPath(t *testing.T) {
|
|
||||||
if tc.NotValid(ktu.NeedRoot()) {
|
|
||||||
t.Skip(testDisabledAsNonRoot)
|
|
||||||
}
|
|
||||||
|
|
||||||
createFakeMountDir := func(t *testing.T, dir, prefix string) string {
|
|
||||||
name, err := os.MkdirTemp(dir, "test-mnt-"+prefix+"-")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
createFakeMountFile := func(t *testing.T, dir, prefix string) string {
|
|
||||||
f, err := os.CreateTemp(dir, "test-mnt-"+prefix+"-")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
f.Close()
|
|
||||||
return f.Name()
|
|
||||||
}
|
|
||||||
|
|
||||||
doUnmountCheck := func(s *Sandbox, src, dest, hostPath, nonEmptyHostpath, devPath string) {
|
|
||||||
mounts := []Mount{
|
|
||||||
{
|
|
||||||
Source: src,
|
|
||||||
Destination: dest,
|
|
||||||
HostPath: hostPath,
|
|
||||||
Type: "bind",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Source: src,
|
|
||||||
Destination: dest,
|
|
||||||
HostPath: nonEmptyHostpath,
|
|
||||||
Type: "bind",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Source: src,
|
|
||||||
Destination: dest,
|
|
||||||
HostPath: devPath,
|
|
||||||
Type: "dev",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
c := Container{
|
|
||||||
mounts: mounts,
|
|
||||||
ctx: context.Background(),
|
|
||||||
id: "fooabr",
|
|
||||||
sandbox: s,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := bindMount(c.ctx, src, hostPath, false, "private"); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer syscall.Unmount(hostPath, 0)
|
|
||||||
if err := bindMount(c.ctx, src, nonEmptyHostpath, false, "private"); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer syscall.Unmount(nonEmptyHostpath, 0)
|
|
||||||
if err := bindMount(c.ctx, src, devPath, false, "private"); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer syscall.Unmount(devPath, 0)
|
|
||||||
|
|
||||||
err := c.unmountHostMounts(c.ctx)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, path := range [3]string{src, dest, devPath} {
|
|
||||||
if _, err := os.Stat(path); err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
t.Fatalf("path %s should not be removed", path)
|
|
||||||
} else {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := os.Stat(hostPath); err == nil {
|
|
||||||
t.Fatal("empty host-path should be removed")
|
|
||||||
} else if !os.IsNotExist(err) {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := os.Stat(nonEmptyHostpath); err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
t.Fatal("non-empty host-path should not be removed")
|
|
||||||
} else {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
src := createFakeMountDir(t, testDir, "src")
|
|
||||||
dest := createFakeMountDir(t, testDir, "dest")
|
|
||||||
hostPath := createFakeMountDir(t, testDir, "host-path")
|
|
||||||
nonEmptyHostpath := createFakeMountDir(t, testDir, "non-empty-host-path")
|
|
||||||
devPath := createFakeMountDir(t, testDir, "dev-hostpath")
|
|
||||||
// create sandbox for mounting into
|
|
||||||
sandbox := &Sandbox{
|
|
||||||
ctx: context.Background(),
|
|
||||||
id: "foobar",
|
|
||||||
config: &SandboxConfig{},
|
|
||||||
}
|
|
||||||
|
|
||||||
fsShare, err := NewFilesystemShare(sandbox)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
sandbox.fsShare = fsShare
|
|
||||||
|
|
||||||
createFakeMountDir(t, nonEmptyHostpath, "nop")
|
|
||||||
doUnmountCheck(sandbox, src, dest, hostPath, nonEmptyHostpath, devPath)
|
|
||||||
|
|
||||||
src = createFakeMountFile(t, testDir, "src")
|
|
||||||
dest = createFakeMountFile(t, testDir, "dest")
|
|
||||||
hostPath = createFakeMountFile(t, testDir, "host-path")
|
|
||||||
nonEmptyHostpath = createFakeMountFile(t, testDir, "non-empty-host-path")
|
|
||||||
devPath = createFakeMountFile(t, testDir, "dev-host-path")
|
|
||||||
f, err := os.OpenFile(nonEmptyHostpath, os.O_WRONLY, os.FileMode(0640))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
f.WriteString("nop\n")
|
|
||||||
f.Close()
|
|
||||||
doUnmountCheck(sandbox, src, dest, hostPath, nonEmptyHostpath, devPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testSetupFakeRootfs(t *testing.T) (testRawFile, loopDev, mntDir string, err error) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
if tc.NotValid(ktu.NeedRoot()) {
|
|
||||||
t.Skip(testDisabledAsNonRoot)
|
|
||||||
}
|
|
||||||
|
|
||||||
tmpDir := t.TempDir()
|
|
||||||
|
|
||||||
testRawFile = filepath.Join(tmpDir, "raw.img")
|
|
||||||
_, err = os.Stat(testRawFile)
|
|
||||||
assert.True(os.IsNotExist(err))
|
|
||||||
|
|
||||||
output, err := exec.Command("losetup", "-f").CombinedOutput()
|
|
||||||
assert.NoError(err)
|
|
||||||
loopDev = strings.TrimSpace(string(output[:]))
|
|
||||||
|
|
||||||
_, err = exec.Command("fallocate", "-l", "256K", testRawFile).CombinedOutput()
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
_, err = exec.Command("mkfs.ext4", "-F", testRawFile).CombinedOutput()
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
_, err = exec.Command("losetup", loopDev, testRawFile).CombinedOutput()
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
mntDir = filepath.Join(tmpDir, "rootfs")
|
|
||||||
err = os.Mkdir(mntDir, DirMode)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
err = syscall.Mount(loopDev, mntDir, "ext4", uintptr(0), "")
|
|
||||||
assert.NoError(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func cleanupFakeRootfsSetup(testRawFile, loopDev, mntDir string) {
|
|
||||||
// unmount loop device
|
|
||||||
if mntDir != "" {
|
|
||||||
syscall.Unmount(mntDir, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// detach loop device
|
|
||||||
if loopDev != "" {
|
|
||||||
exec.Command("losetup", "-d", loopDev).CombinedOutput()
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := os.Stat(testRawFile); err == nil {
|
|
||||||
tmpDir := filepath.Dir(testRawFile)
|
|
||||||
os.RemoveAll(tmpDir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerAddDriveDir(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
if tc.NotValid(ktu.NeedRoot()) {
|
|
||||||
t.Skip(testDisabledAsNonRoot)
|
|
||||||
}
|
|
||||||
|
|
||||||
testRawFile, loopDev, fakeRootfs, err := testSetupFakeRootfs(t)
|
|
||||||
|
|
||||||
defer cleanupFakeRootfsSetup(testRawFile, loopDev, fakeRootfs)
|
|
||||||
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
sandbox := &Sandbox{
|
|
||||||
ctx: context.Background(),
|
|
||||||
id: testSandboxID,
|
|
||||||
devManager: manager.NewDeviceManager(config.VirtioSCSI, false, "", nil),
|
|
||||||
hypervisor: &mockHypervisor{},
|
|
||||||
agent: &mockAgent{},
|
|
||||||
config: &SandboxConfig{
|
|
||||||
HypervisorConfig: HypervisorConfig{
|
|
||||||
DisableBlockDeviceUse: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
sandbox.store, err = persist.GetDriver()
|
|
||||||
assert.NoError(err)
|
|
||||||
assert.NotNil(sandbox.store)
|
|
||||||
|
|
||||||
defer sandbox.store.Destroy(sandbox.id)
|
|
||||||
|
|
||||||
contID := "100"
|
|
||||||
container := Container{
|
|
||||||
sandbox: sandbox,
|
|
||||||
id: contID,
|
|
||||||
rootFs: RootFs{Target: fakeRootfs, Mounted: true},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make the checkStorageDriver func variable point to a fake Check function
|
|
||||||
savedFunc := checkStorageDriver
|
|
||||||
checkStorageDriver = func(major, minor int) (bool, error) {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
checkStorageDriver = savedFunc
|
|
||||||
}()
|
|
||||||
|
|
||||||
container.state.Fstype = ""
|
|
||||||
|
|
||||||
err = container.hotplugDrive(sandbox.ctx)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
assert.NotEmpty(container.state.Fstype)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContainerRootfsPath(t *testing.T) {
|
|
||||||
|
|
||||||
testRawFile, loopDev, fakeRootfs, err := testSetupFakeRootfs(t)
|
|
||||||
defer cleanupFakeRootfsSetup(testRawFile, loopDev, fakeRootfs)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
truecheckstoragedriver := checkStorageDriver
|
|
||||||
checkStorageDriver = func(major, minor int) (bool, error) {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
checkStorageDriver = truecheckstoragedriver
|
|
||||||
}()
|
|
||||||
|
|
||||||
sandbox := &Sandbox{
|
|
||||||
ctx: context.Background(),
|
|
||||||
id: "rootfstestsandbox",
|
|
||||||
agent: &mockAgent{},
|
|
||||||
hypervisor: &mockHypervisor{},
|
|
||||||
config: &SandboxConfig{
|
|
||||||
HypervisorConfig: HypervisorConfig{
|
|
||||||
DisableBlockDeviceUse: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
container := Container{
|
|
||||||
id: "rootfstestcontainerid",
|
|
||||||
sandbox: sandbox,
|
|
||||||
rootFs: RootFs{Target: fakeRootfs, Mounted: true},
|
|
||||||
rootfsSuffix: "rootfs",
|
|
||||||
}
|
|
||||||
|
|
||||||
container.hotplugDrive(sandbox.ctx)
|
|
||||||
assert.Empty(t, container.rootfsSuffix)
|
|
||||||
|
|
||||||
// Reset the value to test the other case
|
|
||||||
container.rootFs = RootFs{Target: fakeRootfs + "/rootfs", Mounted: true}
|
|
||||||
container.rootfsSuffix = "rootfs"
|
|
||||||
|
|
||||||
container.hotplugDrive(sandbox.ctx)
|
|
||||||
assert.Equal(t, container.rootfsSuffix, "rootfs")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCheckSandboxRunningEmptyCmdFailure(t *testing.T) {
|
func TestCheckSandboxRunningEmptyCmdFailure(t *testing.T) {
|
||||||
c := &Container{}
|
c := &Container{}
|
||||||
err := c.checkSandboxRunning("")
|
err := c.checkSandboxRunning("")
|
||||||
|
30
src/runtime/virtcontainers/hypervisor_linux_test.go
Normal file
30
src/runtime/virtcontainers/hypervisor_linux_test.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright (c) 2016 Intel Corporation
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
package virtcontainers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
||||||
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGenerateVMSocket(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
if tc.NotValid(ktu.NeedRoot()) {
|
||||||
|
t.Skip(testDisabledAsNonRoot)
|
||||||
|
}
|
||||||
|
s, err := generateVMSocket("a", "")
|
||||||
|
assert.NoError(err)
|
||||||
|
vsock, ok := s.(types.VSock)
|
||||||
|
assert.True(ok)
|
||||||
|
defer assert.NoError(vsock.VhostFd.Close())
|
||||||
|
assert.NotZero(vsock.VhostFd)
|
||||||
|
assert.NotZero(vsock.ContextID)
|
||||||
|
assert.NotZero(vsock.Port)
|
||||||
|
}
|
@ -10,7 +10,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
@ -299,22 +298,6 @@ func genericTestRunningOnVMM(t *testing.T, data []testNestedVMMData) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenerateVMSocket(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
if tc.NotValid(ktu.NeedRoot()) {
|
|
||||||
t.Skip(testDisabledAsNonRoot)
|
|
||||||
}
|
|
||||||
s, err := generateVMSocket("a", "")
|
|
||||||
assert.NoError(err)
|
|
||||||
vsock, ok := s.(types.VSock)
|
|
||||||
assert.True(ok)
|
|
||||||
defer assert.NoError(vsock.VhostFd.Close())
|
|
||||||
assert.NotZero(vsock.VhostFd)
|
|
||||||
assert.NotZero(vsock.ContextID)
|
|
||||||
assert.NotZero(vsock.Port)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAssetPath(t *testing.T) {
|
func TestAssetPath(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
79
src/runtime/virtcontainers/kata_agent_linux_test.go
Normal file
79
src/runtime/virtcontainers/kata_agent_linux_test.go
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// Copyright (c) 2018 Intel Corporation
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
package virtcontainers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"code.cloudfoundry.org/bytefmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHandleHugepages(t *testing.T) {
|
||||||
|
if os.Getuid() != 0 {
|
||||||
|
t.Skip("Test disabled as requires root user")
|
||||||
|
}
|
||||||
|
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
dir := t.TempDir()
|
||||||
|
|
||||||
|
k := kataAgent{}
|
||||||
|
var formattedSizes []string
|
||||||
|
var mounts []specs.Mount
|
||||||
|
var hugepageLimits []specs.LinuxHugepageLimit
|
||||||
|
|
||||||
|
// On s390x, hugepage sizes must be set at boot and cannot be created ad hoc. Use any that
|
||||||
|
// are present (default is 1M, can only be changed on LPAR). See
|
||||||
|
// https://www.ibm.com/docs/en/linuxonibm/pdf/lku5dd05.pdf, p. 345 for more information.
|
||||||
|
if runtime.GOARCH == "s390x" {
|
||||||
|
dirs, err := os.ReadDir(sysHugepagesDir)
|
||||||
|
assert.Nil(err)
|
||||||
|
for _, dir := range dirs {
|
||||||
|
formattedSizes = append(formattedSizes, strings.TrimPrefix(dir.Name(), "hugepages-"))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
formattedSizes = []string{"1G", "2M"}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, formattedSize := range formattedSizes {
|
||||||
|
bytes, err := bytefmt.ToBytes(formattedSize)
|
||||||
|
assert.Nil(err)
|
||||||
|
hugepageLimits = append(hugepageLimits, specs.LinuxHugepageLimit{
|
||||||
|
Pagesize: formattedSize,
|
||||||
|
Limit: 1_000_000 * bytes,
|
||||||
|
})
|
||||||
|
|
||||||
|
target := path.Join(dir, fmt.Sprintf("hugepages-%s", formattedSize))
|
||||||
|
err = os.MkdirAll(target, 0777)
|
||||||
|
assert.NoError(err, "Unable to create dir %s", target)
|
||||||
|
|
||||||
|
err = syscall.Mount("nodev", target, "hugetlbfs", uintptr(0), fmt.Sprintf("pagesize=%s", formattedSize))
|
||||||
|
assert.NoError(err, "Unable to mount %s", target)
|
||||||
|
|
||||||
|
defer syscall.Unmount(target, 0)
|
||||||
|
defer os.RemoveAll(target)
|
||||||
|
mount := specs.Mount{
|
||||||
|
Type: KataLocalDevType,
|
||||||
|
Source: target,
|
||||||
|
}
|
||||||
|
mounts = append(mounts, mount)
|
||||||
|
}
|
||||||
|
|
||||||
|
hugepages, err := k.handleHugepages(mounts, hugepageLimits)
|
||||||
|
|
||||||
|
assert.NoError(err, "Unable to handle hugepages %v", hugepageLimits)
|
||||||
|
assert.NotNil(hugepages)
|
||||||
|
assert.Equal(len(hugepages), len(formattedSizes))
|
||||||
|
}
|
@ -13,7 +13,6 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
@ -21,11 +20,11 @@ import (
|
|||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"code.cloudfoundry.org/bytefmt"
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/api"
|
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/api"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/config"
|
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/config"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/drivers"
|
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/drivers"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/manager"
|
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/manager"
|
||||||
|
|
||||||
volume "github.com/kata-containers/kata-containers/src/runtime/pkg/direct-volume"
|
volume "github.com/kata-containers/kata-containers/src/runtime/pkg/direct-volume"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist"
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist"
|
||||||
pbTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols"
|
pbTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols"
|
||||||
@ -1148,62 +1147,3 @@ func TestKataAgentDirs(t *testing.T) {
|
|||||||
expected := "/rafs/123/lowerdir"
|
expected := "/rafs/123/lowerdir"
|
||||||
assert.Equal(rafsMountPath(cid), expected)
|
assert.Equal(rafsMountPath(cid), expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHandleHugepages(t *testing.T) {
|
|
||||||
if os.Getuid() != 0 {
|
|
||||||
t.Skip("Test disabled as requires root user")
|
|
||||||
}
|
|
||||||
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
dir := t.TempDir()
|
|
||||||
|
|
||||||
k := kataAgent{}
|
|
||||||
var formattedSizes []string
|
|
||||||
var mounts []specs.Mount
|
|
||||||
var hugepageLimits []specs.LinuxHugepageLimit
|
|
||||||
|
|
||||||
// On s390x, hugepage sizes must be set at boot and cannot be created ad hoc. Use any that
|
|
||||||
// are present (default is 1M, can only be changed on LPAR). See
|
|
||||||
// https://www.ibm.com/docs/en/linuxonibm/pdf/lku5dd05.pdf, p. 345 for more information.
|
|
||||||
if runtime.GOARCH == "s390x" {
|
|
||||||
dirs, err := os.ReadDir(sysHugepagesDir)
|
|
||||||
assert.Nil(err)
|
|
||||||
for _, dir := range dirs {
|
|
||||||
formattedSizes = append(formattedSizes, strings.TrimPrefix(dir.Name(), "hugepages-"))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
formattedSizes = []string{"1G", "2M"}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, formattedSize := range formattedSizes {
|
|
||||||
bytes, err := bytefmt.ToBytes(formattedSize)
|
|
||||||
assert.Nil(err)
|
|
||||||
hugepageLimits = append(hugepageLimits, specs.LinuxHugepageLimit{
|
|
||||||
Pagesize: formattedSize,
|
|
||||||
Limit: 1_000_000 * bytes,
|
|
||||||
})
|
|
||||||
|
|
||||||
target := path.Join(dir, fmt.Sprintf("hugepages-%s", formattedSize))
|
|
||||||
err = os.MkdirAll(target, 0777)
|
|
||||||
assert.NoError(err, "Unable to create dir %s", target)
|
|
||||||
|
|
||||||
err = syscall.Mount("nodev", target, "hugetlbfs", uintptr(0), fmt.Sprintf("pagesize=%s", formattedSize))
|
|
||||||
assert.NoError(err, "Unable to mount %s", target)
|
|
||||||
|
|
||||||
defer syscall.Unmount(target, 0)
|
|
||||||
defer os.RemoveAll(target)
|
|
||||||
mount := specs.Mount{
|
|
||||||
Type: KataLocalDevType,
|
|
||||||
Source: target,
|
|
||||||
}
|
|
||||||
mounts = append(mounts, mount)
|
|
||||||
}
|
|
||||||
|
|
||||||
hugepages, err := k.handleHugepages(mounts, hugepageLimits)
|
|
||||||
|
|
||||||
assert.NoError(err, "Unable to handle hugepages %v", hugepageLimits)
|
|
||||||
assert.NotNil(hugepages)
|
|
||||||
assert.Equal(len(hugepages), len(formattedSizes))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
117
src/runtime/virtcontainers/sandbox_linux_test.go
Normal file
117
src/runtime/virtcontainers/sandbox_linux_test.go
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// Copyright (c) 2016 Intel Corporation
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
package virtcontainers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/config"
|
||||||
|
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/drivers"
|
||||||
|
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/manager"
|
||||||
|
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSandboxAttachDevicesVhostUserBlk(t *testing.T) {
|
||||||
|
rootEnabled := true
|
||||||
|
tc := ktu.NewTestConstraint(false)
|
||||||
|
if tc.NotValid(ktu.NeedRoot()) {
|
||||||
|
rootEnabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
os.RemoveAll(tmpDir)
|
||||||
|
dm := manager.NewDeviceManager(config.VirtioSCSI, true, tmpDir, nil)
|
||||||
|
|
||||||
|
vhostUserDevNodePath := filepath.Join(tmpDir, "/block/devices/")
|
||||||
|
vhostUserSockPath := filepath.Join(tmpDir, "/block/sockets/")
|
||||||
|
deviceNodePath := filepath.Join(vhostUserDevNodePath, "vhostblk0")
|
||||||
|
deviceSockPath := filepath.Join(vhostUserSockPath, "vhostblk0")
|
||||||
|
|
||||||
|
err := os.MkdirAll(vhostUserDevNodePath, dirMode)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
err = os.MkdirAll(vhostUserSockPath, dirMode)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
_, err = os.Create(deviceSockPath)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
// mknod requires root privilege, call mock function for non-root to
|
||||||
|
// get VhostUserBlk device type.
|
||||||
|
if rootEnabled == true {
|
||||||
|
|
||||||
|
err = unix.Mknod(deviceNodePath, unix.S_IFBLK, int(unix.Mkdev(config.VhostUserBlkMajor, 0)))
|
||||||
|
assert.Nil(t, err)
|
||||||
|
} else {
|
||||||
|
savedFunc := config.GetVhostUserNodeStatFunc
|
||||||
|
|
||||||
|
_, err = os.Create(deviceNodePath)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
config.GetVhostUserNodeStatFunc = func(devNodePath string,
|
||||||
|
devNodeStat *unix.Stat_t) error {
|
||||||
|
if deviceNodePath != devNodePath {
|
||||||
|
return fmt.Errorf("mock GetVhostUserNodeStatFunc error")
|
||||||
|
}
|
||||||
|
|
||||||
|
devNodeStat.Rdev = unix.Mkdev(config.VhostUserBlkMajor, 0)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
config.GetVhostUserNodeStatFunc = savedFunc
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
path := "/dev/vda"
|
||||||
|
deviceInfo := config.DeviceInfo{
|
||||||
|
HostPath: deviceNodePath,
|
||||||
|
ContainerPath: path,
|
||||||
|
DevType: "b",
|
||||||
|
Major: config.VhostUserBlkMajor,
|
||||||
|
Minor: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
device, err := dm.NewDevice(deviceInfo)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
_, ok := device.(*drivers.VhostUserBlkDevice)
|
||||||
|
assert.True(t, ok)
|
||||||
|
|
||||||
|
c := &Container{
|
||||||
|
id: "100",
|
||||||
|
devices: []ContainerDevice{
|
||||||
|
{
|
||||||
|
ID: device.DeviceID(),
|
||||||
|
ContainerPath: path,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
containers := map[string]*Container{}
|
||||||
|
containers[c.id] = c
|
||||||
|
|
||||||
|
sandbox := Sandbox{
|
||||||
|
id: "100",
|
||||||
|
containers: containers,
|
||||||
|
hypervisor: &mockHypervisor{},
|
||||||
|
devManager: dm,
|
||||||
|
ctx: context.Background(),
|
||||||
|
config: &SandboxConfig{},
|
||||||
|
}
|
||||||
|
|
||||||
|
containers[c.id].sandbox = &sandbox
|
||||||
|
|
||||||
|
err = containers[c.id].attachDevices(context.Background())
|
||||||
|
assert.Nil(t, err, "Error while attaching vhost-user-blk devices %s", err)
|
||||||
|
|
||||||
|
err = containers[c.id].detachDevices(context.Background())
|
||||||
|
assert.Nil(t, err, "Error while detaching vhost-user-blk devices %s", err)
|
||||||
|
}
|
@ -28,7 +28,6 @@ import (
|
|||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// dirMode is the permission bits used for creating a directory
|
// dirMode is the permission bits used for creating a directory
|
||||||
@ -583,100 +582,6 @@ func TestSandboxAttachDevicesVFIO(t *testing.T) {
|
|||||||
assert.Nil(t, err, "Error while detaching devices %s", err)
|
assert.Nil(t, err, "Error while detaching devices %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSandboxAttachDevicesVhostUserBlk(t *testing.T) {
|
|
||||||
rootEnabled := true
|
|
||||||
tc := ktu.NewTestConstraint(false)
|
|
||||||
if tc.NotValid(ktu.NeedRoot()) {
|
|
||||||
rootEnabled = false
|
|
||||||
}
|
|
||||||
|
|
||||||
tmpDir := t.TempDir()
|
|
||||||
os.RemoveAll(tmpDir)
|
|
||||||
dm := manager.NewDeviceManager(config.VirtioSCSI, true, tmpDir, nil)
|
|
||||||
|
|
||||||
vhostUserDevNodePath := filepath.Join(tmpDir, "/block/devices/")
|
|
||||||
vhostUserSockPath := filepath.Join(tmpDir, "/block/sockets/")
|
|
||||||
deviceNodePath := filepath.Join(vhostUserDevNodePath, "vhostblk0")
|
|
||||||
deviceSockPath := filepath.Join(vhostUserSockPath, "vhostblk0")
|
|
||||||
|
|
||||||
err := os.MkdirAll(vhostUserDevNodePath, dirMode)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
err = os.MkdirAll(vhostUserSockPath, dirMode)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
_, err = os.Create(deviceSockPath)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
// mknod requires root privilege, call mock function for non-root to
|
|
||||||
// get VhostUserBlk device type.
|
|
||||||
if rootEnabled == true {
|
|
||||||
err = unix.Mknod(deviceNodePath, unix.S_IFBLK, int(unix.Mkdev(config.VhostUserBlkMajor, 0)))
|
|
||||||
assert.Nil(t, err)
|
|
||||||
} else {
|
|
||||||
savedFunc := config.GetVhostUserNodeStatFunc
|
|
||||||
|
|
||||||
_, err = os.Create(deviceNodePath)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
config.GetVhostUserNodeStatFunc = func(devNodePath string,
|
|
||||||
devNodeStat *unix.Stat_t) error {
|
|
||||||
if deviceNodePath != devNodePath {
|
|
||||||
return fmt.Errorf("mock GetVhostUserNodeStatFunc error")
|
|
||||||
}
|
|
||||||
|
|
||||||
devNodeStat.Rdev = unix.Mkdev(config.VhostUserBlkMajor, 0)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
config.GetVhostUserNodeStatFunc = savedFunc
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
path := "/dev/vda"
|
|
||||||
deviceInfo := config.DeviceInfo{
|
|
||||||
HostPath: deviceNodePath,
|
|
||||||
ContainerPath: path,
|
|
||||||
DevType: "b",
|
|
||||||
Major: config.VhostUserBlkMajor,
|
|
||||||
Minor: 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
device, err := dm.NewDevice(deviceInfo)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
_, ok := device.(*drivers.VhostUserBlkDevice)
|
|
||||||
assert.True(t, ok)
|
|
||||||
|
|
||||||
c := &Container{
|
|
||||||
id: "100",
|
|
||||||
devices: []ContainerDevice{
|
|
||||||
{
|
|
||||||
ID: device.DeviceID(),
|
|
||||||
ContainerPath: path,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
containers := map[string]*Container{}
|
|
||||||
containers[c.id] = c
|
|
||||||
|
|
||||||
sandbox := Sandbox{
|
|
||||||
id: "100",
|
|
||||||
containers: containers,
|
|
||||||
hypervisor: &mockHypervisor{},
|
|
||||||
devManager: dm,
|
|
||||||
ctx: context.Background(),
|
|
||||||
config: &SandboxConfig{},
|
|
||||||
}
|
|
||||||
|
|
||||||
containers[c.id].sandbox = &sandbox
|
|
||||||
|
|
||||||
err = containers[c.id].attachDevices(context.Background())
|
|
||||||
assert.Nil(t, err, "Error while attaching vhost-user-blk devices %s", err)
|
|
||||||
|
|
||||||
err = containers[c.id].detachDevices(context.Background())
|
|
||||||
assert.Nil(t, err, "Error while detaching vhost-user-blk devices %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var assetContent = []byte("FakeAsset fake asset FAKE ASSET")
|
var assetContent = []byte("FakeAsset fake asset FAKE ASSET")
|
||||||
var assetContentHash = "92549f8d2018a95a294d28a65e795ed7d1a9d150009a28cea108ae10101178676f04ab82a6950d0099e4924f9c5e41dcba8ece56b75fc8b4e0a7492cb2a8c880"
|
var assetContentHash = "92549f8d2018a95a294d28a65e795ed7d1a9d150009a28cea108ae10101178676f04ab82a6950d0099e4924f9c5e41dcba8ece56b75fc8b4e0a7492cb2a8c880"
|
||||||
var assetContentWrongHash = "92549f8d2018a95a294d28a65e795ed7d1a9d150009a28cea108ae10101178676f04ab82a6950d0099e4924f9c5e41dcba8ece56b75fc8b4e0a7492cb2a8c881"
|
var assetContentWrongHash = "92549f8d2018a95a294d28a65e795ed7d1a9d150009a28cea108ae10101178676f04ab82a6950d0099e4924f9c5e41dcba8ece56b75fc8b4e0a7492cb2a8c881"
|
||||||
|
16
src/runtime/virtcontainers/virtcontainers_darwin_test.go
Normal file
16
src/runtime/virtcontainers/virtcontainers_darwin_test.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (c) 2023 Apple Inc.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
package virtcontainers
|
||||||
|
|
||||||
|
import "os"
|
||||||
|
|
||||||
|
// cleanUp removes any stale sandbox/container state that can affect
|
||||||
|
// the next test to run.
|
||||||
|
func cleanUp() {
|
||||||
|
os.RemoveAll(testDir)
|
||||||
|
os.MkdirAll(testDir, DirMode)
|
||||||
|
setup()
|
||||||
|
}
|
21
src/runtime/virtcontainers/virtcontainers_linux_test.go
Normal file
21
src/runtime/virtcontainers/virtcontainers_linux_test.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright (c) 2017 Intel Corporation
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
package virtcontainers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// cleanUp Removes any stale sandbox/container state that can affect
|
||||||
|
// the next test to run.
|
||||||
|
func cleanUp() {
|
||||||
|
syscall.Unmount(GetSharePath(testSandboxID), syscall.MNT_DETACH|UmountNoFollow)
|
||||||
|
os.RemoveAll(testDir)
|
||||||
|
os.MkdirAll(testDir, DirMode)
|
||||||
|
|
||||||
|
setup()
|
||||||
|
}
|
@ -12,7 +12,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"syscall"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist/fs"
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist/fs"
|
||||||
@ -54,16 +53,6 @@ var testVirtiofsdPath = ""
|
|||||||
var testHyperstartCtlSocket = ""
|
var testHyperstartCtlSocket = ""
|
||||||
var testHyperstartTtySocket = ""
|
var testHyperstartTtySocket = ""
|
||||||
|
|
||||||
// cleanUp Removes any stale sandbox/container state that can affect
|
|
||||||
// the next test to run.
|
|
||||||
func cleanUp() {
|
|
||||||
syscall.Unmount(GetSharePath(testSandboxID), syscall.MNT_DETACH|UmountNoFollow)
|
|
||||||
os.RemoveAll(testDir)
|
|
||||||
os.MkdirAll(testDir, DirMode)
|
|
||||||
|
|
||||||
setup()
|
|
||||||
}
|
|
||||||
|
|
||||||
func setup() {
|
func setup() {
|
||||||
os.Mkdir(filepath.Join(testDir, testBundle), DirMode)
|
os.Mkdir(filepath.Join(testDir, testBundle), DirMode)
|
||||||
|
|
||||||
|
36
src/runtime/virtcontainers/vm_linux_test.go
Normal file
36
src/runtime/virtcontainers/vm_linux_test.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright (c) 2018 HyperHQ Inc.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
package virtcontainers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestVMConfigGrpc(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
config := VMConfig{
|
||||||
|
HypervisorType: QemuHypervisor,
|
||||||
|
HypervisorConfig: newQemuConfig(),
|
||||||
|
AgentConfig: KataAgentConfig{
|
||||||
|
LongLiveConn: true,
|
||||||
|
Debug: false,
|
||||||
|
Trace: false,
|
||||||
|
EnableDebugConsole: false,
|
||||||
|
ContainerPipeSize: 0,
|
||||||
|
KernelModules: []string{}},
|
||||||
|
}
|
||||||
|
|
||||||
|
p, err := config.ToGrpc()
|
||||||
|
assert.Nil(err)
|
||||||
|
|
||||||
|
config2, err := GrpcToVMConfig(p)
|
||||||
|
assert.Nil(err)
|
||||||
|
|
||||||
|
assert.True(utils.DeepCompare(config, *config2))
|
||||||
|
}
|
@ -11,7 +11,6 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -85,44 +84,3 @@ func TestNewVM(t *testing.T) {
|
|||||||
_, err = NewVM(ctx, config)
|
_, err = NewVM(ctx, config)
|
||||||
assert.Nil(err)
|
assert.Nil(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVMConfigValid(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
config := VMConfig{}
|
|
||||||
|
|
||||||
err := config.Valid()
|
|
||||||
assert.Error(err)
|
|
||||||
|
|
||||||
testDir := t.TempDir()
|
|
||||||
|
|
||||||
config.HypervisorConfig = HypervisorConfig{
|
|
||||||
KernelPath: testDir,
|
|
||||||
InitrdPath: testDir,
|
|
||||||
}
|
|
||||||
err = config.Valid()
|
|
||||||
assert.Nil(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMConfigGrpc(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
config := VMConfig{
|
|
||||||
HypervisorType: QemuHypervisor,
|
|
||||||
HypervisorConfig: newQemuConfig(),
|
|
||||||
AgentConfig: KataAgentConfig{
|
|
||||||
LongLiveConn: true,
|
|
||||||
Debug: false,
|
|
||||||
Trace: false,
|
|
||||||
EnableDebugConsole: false,
|
|
||||||
ContainerPipeSize: 0,
|
|
||||||
KernelModules: []string{}},
|
|
||||||
}
|
|
||||||
|
|
||||||
p, err := config.ToGrpc()
|
|
||||||
assert.Nil(err)
|
|
||||||
|
|
||||||
config2, err := GrpcToVMConfig(p)
|
|
||||||
assert.Nil(err)
|
|
||||||
|
|
||||||
assert.True(utils.DeepCompare(config, *config2))
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user