Files
kata-containers/cli/utils_test.go
Harshal Patil b821a5df4c virtcontainers: Add support for ephemeral volumes
Ephemeral volumes should not be passed at 9pfs mounts.
They should be created inside the VM.

This patch disables ephemeral volumes from getting
mounted as 9pfs from the host and instead a corresponding
tmpfs is created inside the VM.

Fixes : #61

Signed-off-by: Harshal Patil <harshal.patil@in.ibm.com>
2018-07-18 07:41:36 +05:30

428 lines
8.9 KiB
Go

// Copyright (c) 2017 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
package main
import (
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"syscall"
"testing"
"github.com/stretchr/testify/assert"
)
func TestFileExists(t *testing.T) {
dir, err := ioutil.TempDir(testDir, "")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(dir)
file := filepath.Join(dir, "foo")
assert.False(t, fileExists(file),
fmt.Sprintf("File %q should not exist", file))
err = createEmptyFile(file)
if err != nil {
t.Fatal(err)
}
assert.True(t, fileExists(file),
fmt.Sprintf("File %q should exist", file))
}
func TestIsEphemeralStorage(t *testing.T) {
sampleEphePath := "/var/lib/kubelet/pods/366c3a75-4869-11e8-b479-507b9ddd5ce4/volumes/kubernetes.io~empty-dir/cache-volume"
isEphe := IsEphemeralStorage(sampleEphePath)
if !isEphe {
t.Fatalf("Unable to correctly determine volume type")
}
sampleEphePath = "/var/lib/kubelet/pods/366c3a75-4869-11e8-b479-507b9ddd5ce4/volumes/cache-volume"
isEphe = IsEphemeralStorage(sampleEphePath)
if isEphe {
t.Fatalf("Unable to correctly determine volume type")
}
}
func TestGetFileContents(t *testing.T) {
type testData struct {
contents string
}
data := []testData{
{""},
{" "},
{"\n"},
{"\n\n"},
{"\n\n\n"},
{"foo"},
{"foo\nbar"},
{"processor : 0\nvendor_id : GenuineIntel\n"},
}
dir, err := ioutil.TempDir(testDir, "")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(dir)
file := filepath.Join(dir, "foo")
// file doesn't exist
_, err = getFileContents(file)
assert.Error(t, err)
for _, d := range data {
// create the file
err = ioutil.WriteFile(file, []byte(d.contents), testFileMode)
if err != nil {
t.Fatal(err)
}
defer os.Remove(file)
contents, err := getFileContents(file)
assert.NoError(t, err)
assert.Equal(t, contents, d.contents)
}
}
func TestGetKernelVersion(t *testing.T) {
type testData struct {
contents string
expectedVersion string
expectError bool
}
const validVersion = "1.2.3-4.5.x86_64"
validContents := fmt.Sprintf("Linux version %s blah blah blah ...", validVersion)
data := []testData{
{"", "", true},
{"invalid contents", "", true},
{"a b c", "c", false},
{validContents, validVersion, false},
}
tmpdir, err := ioutil.TempDir("", "")
if err != nil {
panic(err)
}
defer os.RemoveAll(tmpdir)
subDir := filepath.Join(tmpdir, "subdir")
err = os.MkdirAll(subDir, testDirMode)
assert.NoError(t, err)
_, err = getKernelVersion()
assert.Error(t, err)
file := filepath.Join(tmpdir, "proc-version")
// override
procVersion = file
_, err = getKernelVersion()
// ENOENT
assert.Error(t, err)
assert.True(t, os.IsNotExist(err))
for _, d := range data {
err := createFile(file, d.contents)
assert.NoError(t, err)
version, err := getKernelVersion()
if d.expectError {
assert.Error(t, err, fmt.Sprintf("%+v", d))
continue
} else {
assert.NoError(t, err, fmt.Sprintf("%+v", d))
assert.Equal(t, d.expectedVersion, version)
}
}
}
func TestGetDistroDetails(t *testing.T) {
type testData struct {
clrContents string
nonClrContents string
expectedName string
expectedVersion string
expectError bool
}
tmpdir, err := ioutil.TempDir("", "")
if err != nil {
panic(err)
}
defer os.RemoveAll(tmpdir)
testOSRelease := filepath.Join(tmpdir, "os-release")
testOSReleaseClr := filepath.Join(tmpdir, "os-release-clr")
const clrExpectedName = "clr"
const clrExpectedVersion = "1.2.3-4"
clrContents := fmt.Sprintf(`
HELLO=world
NAME="%s"
FOO=bar
VERSION_ID="%s"
`, clrExpectedName, clrExpectedVersion)
const nonClrExpectedName = "not-clr"
const nonClrExpectedVersion = "999"
nonClrContents := fmt.Sprintf(`
HELLO=world
NAME="%s"
FOO=bar
VERSION_ID="%s"
`, nonClrExpectedName, nonClrExpectedVersion)
subDir := filepath.Join(tmpdir, "subdir")
err = os.MkdirAll(subDir, testDirMode)
assert.NoError(t, err)
// override
osRelease = subDir
_, _, err = getDistroDetails()
assert.Error(t, err)
// override
osRelease = testOSRelease
osReleaseClr = testOSReleaseClr
_, _, err = getDistroDetails()
// ENOENT
assert.Error(t, err)
data := []testData{
{"", "", "", "", true},
{"invalid", "", "", "", true},
{clrContents, "", clrExpectedName, clrExpectedVersion, false},
{"", nonClrContents, nonClrExpectedName, nonClrExpectedVersion, false},
{clrContents, nonClrContents, nonClrExpectedName, nonClrExpectedVersion, false},
}
for _, d := range data {
err := createFile(osRelease, d.nonClrContents)
assert.NoError(t, err)
err = createFile(osReleaseClr, d.clrContents)
assert.NoError(t, err)
name, version, err := getDistroDetails()
if d.expectError {
assert.Error(t, err, fmt.Sprintf("%+v", d))
continue
} else {
assert.NoError(t, err, fmt.Sprintf("%+v", d))
assert.Equal(t, d.expectedName, name)
assert.Equal(t, d.expectedVersion, version)
}
}
}
func TestGetCPUDetails(t *testing.T) {
type testData struct {
contents string
expectedVendor string
expectedModel string
expectError bool
}
const validVendorName = "a vendor"
validVendor := fmt.Sprintf(`%s : %s`, archCPUVendorField, validVendorName)
const validModelName = "some CPU model"
validModel := fmt.Sprintf(`%s : %s`, archCPUModelField, validModelName)
validContents := fmt.Sprintf(`
a : b
%s
foo : bar
%s
`, validVendor, validModel)
data := []testData{
{"", "", "", true},
{"invalid", "", "", true},
{archCPUVendorField, "", "", true},
{validVendor, "", "", true},
{validModel, "", "", true},
{validContents, validVendorName, validModelName, false},
}
tmpdir, err := ioutil.TempDir("", "")
if err != nil {
panic(err)
}
defer os.RemoveAll(tmpdir)
testProcCPUInfo := filepath.Join(tmpdir, "cpuinfo")
// override
procCPUInfo = testProcCPUInfo
_, _, err = getCPUDetails()
// ENOENT
assert.Error(t, err)
assert.True(t, os.IsNotExist(err))
for _, d := range data {
err := createFile(procCPUInfo, d.contents)
assert.NoError(t, err)
vendor, model, err := getCPUDetails()
if d.expectError {
assert.Error(t, err, fmt.Sprintf("%+v", d))
continue
} else {
assert.NoError(t, err, fmt.Sprintf("%+v", d))
assert.Equal(t, d.expectedVendor, vendor)
assert.Equal(t, d.expectedModel, model)
}
}
}
func TestUtilsResolvePathEmptyPath(t *testing.T) {
_, err := resolvePath("")
assert.Error(t, err)
}
func TestUtilsResolvePathValidPath(t *testing.T) {
dir, err := ioutil.TempDir("", "")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(dir)
target := path.Join(dir, "target")
linkDir := path.Join(dir, "a/b/c")
linkFile := path.Join(linkDir, "link")
err = createEmptyFile(target)
assert.NoError(t, err)
absolute, err := filepath.Abs(target)
assert.NoError(t, err)
resolvedTarget, err := filepath.EvalSymlinks(absolute)
assert.NoError(t, err)
err = os.MkdirAll(linkDir, testDirMode)
assert.NoError(t, err)
err = syscall.Symlink(target, linkFile)
assert.NoError(t, err)
resolvedLink, err := resolvePath(linkFile)
assert.NoError(t, err)
assert.Equal(t, resolvedTarget, resolvedLink)
}
func TestUtilsResolvePathENOENT(t *testing.T) {
dir, err := ioutil.TempDir("", "")
if err != nil {
t.Fatal(err)
}
target := path.Join(dir, "target")
linkDir := path.Join(dir, "a/b/c")
linkFile := path.Join(linkDir, "link")
err = createEmptyFile(target)
assert.NoError(t, err)
err = os.MkdirAll(linkDir, testDirMode)
assert.NoError(t, err)
err = syscall.Symlink(target, linkFile)
assert.NoError(t, err)
cwd, err := os.Getwd()
assert.NoError(t, err)
defer os.Chdir(cwd)
err = os.Chdir(dir)
assert.NoError(t, err)
err = os.RemoveAll(dir)
assert.NoError(t, err)
_, err = resolvePath(filepath.Base(linkFile))
assert.Error(t, err)
}
func TestUtilsRunCommand(t *testing.T) {
output, err := runCommand([]string{"true"})
assert.NoError(t, err)
assert.Equal(t, "", output)
}
func TestUtilsRunCommandCaptureStdout(t *testing.T) {
output, err := runCommand([]string{"echo", "hello"})
assert.NoError(t, err)
assert.Equal(t, "hello", output)
}
func TestUtilsRunCommandIgnoreStderr(t *testing.T) {
args := []string{"/bin/sh", "-c", "echo foo >&2;exit 0"}
output, err := runCommand(args)
assert.NoError(t, err)
assert.Equal(t, "", output)
}
func TestUtilsRunCommandInvalidCmds(t *testing.T) {
invalidCommands := [][]string{
{""},
{"", ""},
{" "},
{" ", " "},
{" ", ""},
{"\\"},
{"/"},
{"/.."},
{"../"},
{"/tmp"},
{"\t"},
{"\n"},
{"false"},
}
for _, args := range invalidCommands {
output, err := runCommand(args)
assert.Error(t, err)
assert.Equal(t, "", output)
}
}
func TestWriteFileErrWriteFail(t *testing.T) {
assert := assert.New(t)
err := writeFile("", "", 0000)
assert.Error(err)
}
func TestWriteFileErrNoPath(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir(testDir, "")
assert.NoError(err)
defer os.RemoveAll(dir)
// attempt to write a file over an existing directory
err = writeFile(dir, "", 0000)
assert.Error(err)
}