virtcontainers: tests: Ensure Linux specific tests are just run on Linux

Fixes: #5993

Several tests utilize linux'isms like Mounts, bindmounts, vsock etc.

Let's ensure that these are still tested on Linux, but that we also skip
these tests when on other operating systems (Darwin). This commit just
moves tests; there shouldn't be any functional test changes. While the
tests still won't be runnable on Darwin/other hosts yet, this is a necessary
step forward.

Signed-off-by: Eric Ernst <eric_ernst@apple.com>
Signed-off-by: Danny Canter <danny@dcantah.dev>
This commit is contained in:
Eric Ernst 2022-06-11 10:47:20 +02:00 committed by Danny Canter
parent 31abe170fc
commit fafc7a8b1a
14 changed files with 605 additions and 510 deletions

View File

@ -3,6 +3,9 @@
// SPDX-License-Identifier: Apache-2.0
//
//go:build linux
// +build linux
package virtcontainers
import (

View 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")
}

View File

@ -8,9 +8,7 @@ package virtcontainers
import (
"context"
"os"
"os/exec"
"path/filepath"
"strings"
"syscall"
"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/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/kata-containers/kata-containers/src/runtime/virtcontainers/persist"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
"github.com/stretchr/testify/assert"
)
@ -124,286 +120,6 @@ func TestContainerRemoveDrive(t *testing.T) {
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) {
c := &Container{}
err := c.checkSandboxRunning("")

View 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)
}

View File

@ -10,7 +10,6 @@ import (
"os"
"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"
)
@ -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) {
assert := assert.New(t)

View 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))
}

View File

@ -13,7 +13,6 @@ import (
"path"
"path/filepath"
"reflect"
"runtime"
"strings"
"syscall"
"testing"
@ -21,11 +20,11 @@ import (
specs "github.com/opencontainers/runtime-spec/specs-go"
"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/config"
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/drivers"
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/manager"
volume "github.com/kata-containers/kata-containers/src/runtime/pkg/direct-volume"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist"
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"
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))
}

View 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)
}

View File

@ -28,7 +28,6 @@ import (
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/assert"
"golang.org/x/sys/unix"
)
// 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)
}
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 assetContentHash = "92549f8d2018a95a294d28a65e795ed7d1a9d150009a28cea108ae10101178676f04ab82a6950d0099e4924f9c5e41dcba8ece56b75fc8b4e0a7492cb2a8c880"
var assetContentWrongHash = "92549f8d2018a95a294d28a65e795ed7d1a9d150009a28cea108ae10101178676f04ab82a6950d0099e4924f9c5e41dcba8ece56b75fc8b4e0a7492cb2a8c881"

View 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()
}

View 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()
}

View File

@ -12,7 +12,6 @@ import (
"os"
"os/exec"
"path/filepath"
"syscall"
"testing"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist/fs"
@ -54,16 +53,6 @@ var testVirtiofsdPath = ""
var testHyperstartCtlSocket = ""
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() {
os.Mkdir(filepath.Join(testDir, testBundle), DirMode)

View 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))
}

View File

@ -11,7 +11,6 @@ import (
"path/filepath"
"testing"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
"github.com/stretchr/testify/assert"
)
@ -85,44 +84,3 @@ func TestNewVM(t *testing.T) {
_, err = NewVM(ctx, config)
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))
}