mirror of
https://github.com/aljazceru/kata-containers.git
synced 2025-12-28 03:24:24 +01:00
Since arch-specific func getExpectedHostDetails holds undefined struct field SupportVSocks on arm64, unit test TestEnvGetEnvInfoSetsCPUType, TestEnvGetHostInfo and so on failed. I'm trying to use generic func genericgetExpectedHostDetails on arm64 to avoid similar issues. Fixes: #1287 Signed-off-by: Penny Zheng <penny.zheng@arm.com>
1238 lines
28 KiB
Go
1238 lines
28 KiB
Go
// Copyright (c) 2017 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
goruntime "runtime"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/BurntSushi/toml"
|
|
vc "github.com/kata-containers/runtime/virtcontainers"
|
|
vcUtils "github.com/kata-containers/runtime/virtcontainers/utils"
|
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
|
"github.com/urfave/cli"
|
|
|
|
"strconv"
|
|
|
|
"github.com/kata-containers/runtime/pkg/katautils"
|
|
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
const testProxyVersion = "proxy version 0.1"
|
|
const testShimVersion = "shim version 0.1"
|
|
const testNetmonVersion = "netmon version 0.1"
|
|
const testHypervisorVersion = "QEMU emulator version 2.7.0+git.741f430a96-6.1, Copyright (c) 2003-2016 Fabrice Bellard and the QEMU Project developers"
|
|
|
|
const defaultVCPUCount uint32 = 1
|
|
const defaultMaxVCPUCount uint32 = 0
|
|
const defaultMemSize uint32 = 2048 // MiB
|
|
const defaultMsize9p uint32 = 8192
|
|
const defaultGuestHookPath string = ""
|
|
|
|
var (
|
|
hypervisorDebug = false
|
|
proxyDebug = false
|
|
runtimeDebug = false
|
|
runtimeTrace = false
|
|
shimDebug = false
|
|
netmonDebug = false
|
|
)
|
|
|
|
// makeVersionBinary creates a shell script with the specified file
|
|
// name. When run as "file --version", it will display the specified
|
|
// version to stdout and exit successfully.
|
|
func makeVersionBinary(file, version string) error {
|
|
err := createFile(file,
|
|
fmt.Sprintf(`#!/bin/sh
|
|
[ "$1" = "--version" ] && echo "%s"`, version))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = os.Chmod(file, testExeFileMode)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func createConfig(configPath string, fileData string) error {
|
|
|
|
err := ioutil.WriteFile(configPath, []byte(fileData), testFileMode)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Unable to create config file %s %v\n", configPath, err)
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func makeRuntimeConfigFileData(hypervisor, hypervisorPath, kernelPath, imagePath, kernelParams, machineType, shimPath, proxyPath, netmonPath, logPath string, disableBlock bool, blockDeviceDriver string, enableIOThreads bool, hotplugVFIOOnRootBus, disableNewNetNs bool) string {
|
|
return `
|
|
# Runtime configuration file
|
|
|
|
[hypervisor.` + hypervisor + `]
|
|
path = "` + hypervisorPath + `"
|
|
kernel = "` + kernelPath + `"
|
|
block_device_driver = "` + blockDeviceDriver + `"
|
|
kernel_params = "` + kernelParams + `"
|
|
image = "` + imagePath + `"
|
|
machine_type = "` + machineType + `"
|
|
default_vcpus = ` + strconv.FormatUint(uint64(defaultVCPUCount), 10) + `
|
|
default_maxvcpus = ` + strconv.FormatUint(uint64(defaultMaxVCPUCount), 10) + `
|
|
default_memory = ` + strconv.FormatUint(uint64(defaultMemSize), 10) + `
|
|
disable_block_device_use = ` + strconv.FormatBool(disableBlock) + `
|
|
enable_iothreads = ` + strconv.FormatBool(enableIOThreads) + `
|
|
hotplug_vfio_on_root_bus = ` + strconv.FormatBool(hotplugVFIOOnRootBus) + `
|
|
msize_9p = ` + strconv.FormatUint(uint64(defaultMsize9p), 10) + `
|
|
enable_debug = ` + strconv.FormatBool(hypervisorDebug) + `
|
|
guest_hook_path = "` + defaultGuestHookPath + `"
|
|
|
|
[proxy.kata]
|
|
enable_debug = ` + strconv.FormatBool(proxyDebug) + `
|
|
path = "` + proxyPath + `"
|
|
|
|
[shim.kata]
|
|
path = "` + shimPath + `"
|
|
enable_debug = ` + strconv.FormatBool(shimDebug) + `
|
|
|
|
[agent.kata]
|
|
|
|
[netmon]
|
|
path = "` + netmonPath + `"
|
|
enable_debug = ` + strconv.FormatBool(netmonDebug) + `
|
|
|
|
[runtime]
|
|
enable_debug = ` + strconv.FormatBool(runtimeDebug) + `
|
|
enable_tracing = ` + strconv.FormatBool(runtimeTrace) + `
|
|
disable_new_netns= ` + strconv.FormatBool(disableNewNetNs)
|
|
}
|
|
|
|
func makeRuntimeConfig(prefixDir string) (configFile string, config oci.RuntimeConfig, err error) {
|
|
const logPath = "/log/path"
|
|
hypervisorPath := filepath.Join(prefixDir, "hypervisor")
|
|
kernelPath := filepath.Join(prefixDir, "kernel")
|
|
imagePath := filepath.Join(prefixDir, "image")
|
|
kernelParams := "foo=bar xyz"
|
|
machineType := "machineType"
|
|
shimPath := filepath.Join(prefixDir, "shim")
|
|
proxyPath := filepath.Join(prefixDir, "proxy")
|
|
netmonPath := filepath.Join(prefixDir, "netmon")
|
|
disableBlock := true
|
|
blockStorageDriver := "virtio-scsi"
|
|
enableIOThreads := true
|
|
hotplugVFIOOnRootBus := true
|
|
disableNewNetNs := false
|
|
|
|
filesToCreate := []string{
|
|
hypervisorPath,
|
|
kernelPath,
|
|
imagePath,
|
|
}
|
|
|
|
for _, file := range filesToCreate {
|
|
// files must exist and be >0 bytes.
|
|
err := katautils.WriteFile(file, "foo", testFileMode)
|
|
if err != nil {
|
|
return "", oci.RuntimeConfig{}, err
|
|
}
|
|
}
|
|
|
|
err = makeVersionBinary(shimPath, testShimVersion)
|
|
if err != nil {
|
|
return "", oci.RuntimeConfig{}, err
|
|
}
|
|
|
|
err = makeVersionBinary(proxyPath, testProxyVersion)
|
|
if err != nil {
|
|
return "", oci.RuntimeConfig{}, err
|
|
}
|
|
|
|
err = makeVersionBinary(netmonPath, testNetmonVersion)
|
|
if err != nil {
|
|
return "", oci.RuntimeConfig{}, err
|
|
}
|
|
|
|
err = makeVersionBinary(hypervisorPath, testHypervisorVersion)
|
|
if err != nil {
|
|
return "", oci.RuntimeConfig{}, err
|
|
}
|
|
|
|
runtimeConfig := makeRuntimeConfigFileData(
|
|
"qemu",
|
|
hypervisorPath,
|
|
kernelPath,
|
|
imagePath,
|
|
kernelParams,
|
|
machineType,
|
|
shimPath,
|
|
proxyPath,
|
|
netmonPath,
|
|
logPath,
|
|
disableBlock,
|
|
blockStorageDriver,
|
|
enableIOThreads,
|
|
hotplugVFIOOnRootBus,
|
|
disableNewNetNs,
|
|
)
|
|
|
|
configFile = path.Join(prefixDir, "runtime.toml")
|
|
err = createConfig(configFile, runtimeConfig)
|
|
if err != nil {
|
|
return "", oci.RuntimeConfig{}, err
|
|
}
|
|
|
|
_, config, err = katautils.LoadConfiguration(configFile, true, false)
|
|
if err != nil {
|
|
return "", oci.RuntimeConfig{}, err
|
|
}
|
|
|
|
return configFile, config, nil
|
|
}
|
|
|
|
func getExpectedProxyDetails(config oci.RuntimeConfig) (ProxyInfo, error) {
|
|
return ProxyInfo{
|
|
Type: string(config.ProxyType),
|
|
Version: testProxyVersion,
|
|
Path: config.ProxyConfig.Path,
|
|
Debug: config.ProxyConfig.Debug,
|
|
}, nil
|
|
}
|
|
|
|
func getExpectedNetmonDetails(config oci.RuntimeConfig) (NetmonInfo, error) {
|
|
return NetmonInfo{
|
|
Version: testNetmonVersion,
|
|
Path: config.NetmonConfig.Path,
|
|
Debug: config.NetmonConfig.Debug,
|
|
Enable: config.NetmonConfig.Enable,
|
|
}, nil
|
|
}
|
|
|
|
func getExpectedShimDetails(config oci.RuntimeConfig) (ShimInfo, error) {
|
|
shimConfig, ok := config.ShimConfig.(vc.ShimConfig)
|
|
if !ok {
|
|
return ShimInfo{}, fmt.Errorf("failed to get shim config")
|
|
}
|
|
|
|
shimPath := shimConfig.Path
|
|
|
|
return ShimInfo{
|
|
Type: string(config.ShimType),
|
|
Version: testShimVersion,
|
|
Path: shimPath,
|
|
Debug: shimConfig.Debug,
|
|
}, nil
|
|
}
|
|
|
|
func getExpectedAgentDetails(config oci.RuntimeConfig) (AgentInfo, error) {
|
|
return AgentInfo{
|
|
Type: string(config.AgentType),
|
|
}, nil
|
|
}
|
|
|
|
// nolint: unused
|
|
func genericGetExpectedHostDetails(tmpdir string, expectedVendor string, expectedModel string, expectedVMContainerCapable bool) (HostInfo, error) {
|
|
type filesToCreate struct {
|
|
file string
|
|
contents string
|
|
}
|
|
|
|
const expectedKernelVersion = "99.1"
|
|
const expectedArch = goruntime.GOARCH
|
|
|
|
expectedDistro := DistroInfo{
|
|
Name: "Foo",
|
|
Version: "42",
|
|
}
|
|
|
|
expectedCPU := CPUInfo{
|
|
Vendor: expectedVendor,
|
|
Model: expectedModel,
|
|
}
|
|
|
|
expectedHostDetails := HostInfo{
|
|
Kernel: expectedKernelVersion,
|
|
Architecture: expectedArch,
|
|
Distro: expectedDistro,
|
|
CPU: expectedCPU,
|
|
VMContainerCapable: expectedVMContainerCapable,
|
|
SupportVSocks: vcUtils.SupportsVsocks(),
|
|
}
|
|
|
|
testProcCPUInfo := filepath.Join(tmpdir, "cpuinfo")
|
|
testOSRelease := filepath.Join(tmpdir, "os-release")
|
|
|
|
// XXX: This file is *NOT* created by this function on purpose
|
|
// (to ensure the only file checked by the tests is
|
|
// testOSRelease). osReleaseClr handling is tested in
|
|
// utils_test.go.
|
|
testOSReleaseClr := filepath.Join(tmpdir, "os-release-clr")
|
|
|
|
testProcVersion := filepath.Join(tmpdir, "proc-version")
|
|
|
|
// override
|
|
procVersion = testProcVersion
|
|
osRelease = testOSRelease
|
|
osReleaseClr = testOSReleaseClr
|
|
procCPUInfo = testProcCPUInfo
|
|
|
|
procVersionContents := fmt.Sprintf("Linux version %s a b c",
|
|
expectedKernelVersion)
|
|
|
|
osReleaseContents := fmt.Sprintf(`
|
|
NAME="%s"
|
|
VERSION_ID="%s"
|
|
`, expectedDistro.Name, expectedDistro.Version)
|
|
|
|
procCPUInfoContents := fmt.Sprintf(`
|
|
%s : %s
|
|
%s : %s
|
|
`,
|
|
archCPUVendorField,
|
|
expectedCPU.Vendor,
|
|
archCPUModelField,
|
|
expectedCPU.Model)
|
|
|
|
data := []filesToCreate{
|
|
{procVersion, procVersionContents},
|
|
{osRelease, osReleaseContents},
|
|
{procCPUInfo, procCPUInfoContents},
|
|
}
|
|
|
|
for _, d := range data {
|
|
err := createFile(d.file, d.contents)
|
|
if err != nil {
|
|
return HostInfo{}, err
|
|
}
|
|
}
|
|
|
|
if goruntime.GOARCH == "arm64" {
|
|
expectedHostDetails.CPU.Vendor = "ARM Limited"
|
|
expectedHostDetails.CPU.Model = "v8"
|
|
}
|
|
|
|
return expectedHostDetails, nil
|
|
}
|
|
|
|
func getExpectedHypervisor(config oci.RuntimeConfig) HypervisorInfo {
|
|
return HypervisorInfo{
|
|
Version: testHypervisorVersion,
|
|
Path: config.HypervisorConfig.HypervisorPath,
|
|
MachineType: config.HypervisorConfig.HypervisorMachineType,
|
|
BlockDeviceDriver: config.HypervisorConfig.BlockDeviceDriver,
|
|
Msize9p: config.HypervisorConfig.Msize9p,
|
|
MemorySlots: config.HypervisorConfig.MemSlots,
|
|
Debug: config.HypervisorConfig.Debug,
|
|
EntropySource: config.HypervisorConfig.EntropySource,
|
|
}
|
|
}
|
|
|
|
func getExpectedImage(config oci.RuntimeConfig) ImageInfo {
|
|
return ImageInfo{
|
|
Path: config.HypervisorConfig.ImagePath,
|
|
}
|
|
}
|
|
|
|
func getExpectedKernel(config oci.RuntimeConfig) KernelInfo {
|
|
return KernelInfo{
|
|
Path: config.HypervisorConfig.KernelPath,
|
|
Parameters: strings.Join(vc.SerializeParams(config.HypervisorConfig.KernelParams, "="), " "),
|
|
}
|
|
}
|
|
|
|
func getExpectedRuntimeDetails(config oci.RuntimeConfig, configFile string) RuntimeInfo {
|
|
runtimePath, _ := os.Executable()
|
|
|
|
return RuntimeInfo{
|
|
Version: RuntimeVersionInfo{
|
|
Semver: version,
|
|
Commit: commit,
|
|
OCI: specs.Version,
|
|
},
|
|
Config: RuntimeConfigInfo{
|
|
Path: configFile,
|
|
},
|
|
Path: runtimePath,
|
|
Debug: config.Debug,
|
|
Trace: config.Trace,
|
|
DisableNewNetNs: config.DisableNewNetNs,
|
|
}
|
|
}
|
|
|
|
func getExpectedSettings(config oci.RuntimeConfig, tmpdir, configFile string) (EnvInfo, error) {
|
|
meta := getExpectedMetaInfo()
|
|
|
|
runtime := getExpectedRuntimeDetails(config, configFile)
|
|
|
|
proxy, err := getExpectedProxyDetails(config)
|
|
if err != nil {
|
|
return EnvInfo{}, err
|
|
}
|
|
|
|
shim, err := getExpectedShimDetails(config)
|
|
if err != nil {
|
|
return EnvInfo{}, err
|
|
}
|
|
|
|
agent, err := getExpectedAgentDetails(config)
|
|
if err != nil {
|
|
return EnvInfo{}, err
|
|
}
|
|
|
|
host, err := getExpectedHostDetails(tmpdir)
|
|
if err != nil {
|
|
return EnvInfo{}, err
|
|
}
|
|
|
|
netmon, err := getExpectedNetmonDetails(config)
|
|
if err != nil {
|
|
return EnvInfo{}, err
|
|
}
|
|
|
|
hypervisor := getExpectedHypervisor(config)
|
|
kernel := getExpectedKernel(config)
|
|
image := getExpectedImage(config)
|
|
|
|
env := EnvInfo{
|
|
Meta: meta,
|
|
Runtime: runtime,
|
|
Hypervisor: hypervisor,
|
|
Image: image,
|
|
Kernel: kernel,
|
|
Proxy: proxy,
|
|
Shim: shim,
|
|
Agent: agent,
|
|
Host: host,
|
|
Netmon: netmon,
|
|
}
|
|
|
|
return env, nil
|
|
}
|
|
|
|
func getExpectedMetaInfo() MetaInfo {
|
|
return MetaInfo{
|
|
Version: formatVersion,
|
|
}
|
|
}
|
|
|
|
func TestEnvGetMetaInfo(t *testing.T) {
|
|
expectedMeta := getExpectedMetaInfo()
|
|
|
|
meta := getMetaInfo()
|
|
|
|
assert.Equal(t, expectedMeta, meta)
|
|
}
|
|
|
|
func TestEnvGetHostInfo(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
expectedHostDetails, err := getExpectedHostDetails(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
host, err := getHostInfo()
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, expectedHostDetails, host)
|
|
}
|
|
|
|
func TestEnvGetHostInfoNoProcCPUInfo(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
_, err = getExpectedHostDetails(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
err = os.Remove(procCPUInfo)
|
|
assert.NoError(t, err)
|
|
|
|
_, err = getHostInfo()
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestEnvGetHostInfoNoOSRelease(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
_, err = getExpectedHostDetails(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
err = os.Remove(osRelease)
|
|
assert.NoError(t, err)
|
|
|
|
_, err = getHostInfo()
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestEnvGetHostInfoNoProcVersion(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
_, err = getExpectedHostDetails(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
err = os.Remove(procVersion)
|
|
assert.NoError(t, err)
|
|
|
|
_, err = getHostInfo()
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestEnvGetEnvInfo(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
// Run test twice to ensure the individual component debug+trace
|
|
// options are tested.
|
|
for _, toggle := range []bool{false, true} {
|
|
hypervisorDebug = toggle
|
|
proxyDebug = toggle
|
|
runtimeDebug = toggle
|
|
runtimeTrace = toggle
|
|
shimDebug = toggle
|
|
|
|
configFile, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
expectedEnv, err := getExpectedSettings(config, tmpdir, configFile)
|
|
assert.NoError(t, err)
|
|
|
|
env, err := getEnvInfo(configFile, config)
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, expectedEnv, env)
|
|
}
|
|
}
|
|
|
|
func TestEnvGetEnvInfoNoHypervisorVersion(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
configFile, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(err)
|
|
|
|
expectedEnv, err := getExpectedSettings(config, tmpdir, configFile)
|
|
assert.NoError(err)
|
|
|
|
err = os.Remove(config.HypervisorConfig.HypervisorPath)
|
|
assert.NoError(err)
|
|
|
|
expectedEnv.Hypervisor.Version = unknown
|
|
|
|
env, err := getEnvInfo(configFile, config)
|
|
assert.NoError(err)
|
|
|
|
assert.Equal(expectedEnv, env)
|
|
}
|
|
|
|
func TestEnvGetEnvInfoShimError(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
configFile, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(err)
|
|
|
|
config.ShimConfig = "invalid shim config"
|
|
|
|
_, err = getEnvInfo(configFile, config)
|
|
assert.Error(err)
|
|
}
|
|
|
|
func TestEnvGetEnvInfoAgentError(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
configFile, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(err)
|
|
|
|
config.AgentConfig = "invalid agent config"
|
|
|
|
_, err = getEnvInfo(configFile, config)
|
|
assert.Error(err)
|
|
}
|
|
|
|
func TestEnvGetEnvInfoNoOSRelease(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
configFile, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
_, err = getExpectedSettings(config, tmpdir, configFile)
|
|
assert.NoError(t, err)
|
|
|
|
err = os.Remove(osRelease)
|
|
assert.NoError(t, err)
|
|
|
|
_, err = getEnvInfo(configFile, config)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestEnvGetEnvInfoNoProcCPUInfo(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
configFile, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
_, err = getExpectedSettings(config, tmpdir, configFile)
|
|
assert.NoError(t, err)
|
|
|
|
err = os.Remove(procCPUInfo)
|
|
assert.NoError(t, err)
|
|
|
|
_, err = getEnvInfo(configFile, config)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestEnvGetEnvInfoNoProcVersion(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
configFile, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
_, err = getExpectedSettings(config, tmpdir, configFile)
|
|
assert.NoError(t, err)
|
|
|
|
err = os.Remove(procVersion)
|
|
assert.NoError(t, err)
|
|
|
|
_, err = getEnvInfo(configFile, config)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestEnvGetRuntimeInfo(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
configFile, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
expectedRuntime := getExpectedRuntimeDetails(config, configFile)
|
|
|
|
runtime := getRuntimeInfo(configFile, config)
|
|
|
|
assert.Equal(t, expectedRuntime, runtime)
|
|
}
|
|
|
|
func TestEnvGetProxyInfo(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
_, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
expectedProxy, err := getExpectedProxyDetails(config)
|
|
assert.NoError(t, err)
|
|
|
|
proxy, err := getProxyInfo(config)
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, expectedProxy, proxy)
|
|
}
|
|
|
|
func TestEnvGetProxyInfoNoVersion(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
_, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
expectedProxy, err := getExpectedProxyDetails(config)
|
|
assert.NoError(t, err)
|
|
|
|
// remove the proxy ensuring its version cannot be queried
|
|
err = os.Remove(config.ProxyConfig.Path)
|
|
assert.NoError(t, err)
|
|
|
|
expectedProxy.Version = unknown
|
|
|
|
proxy, err := getProxyInfo(config)
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, expectedProxy, proxy)
|
|
}
|
|
|
|
func TestEnvGetNetmonInfo(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
_, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
expectedNetmon, err := getExpectedNetmonDetails(config)
|
|
assert.NoError(t, err)
|
|
|
|
netmon, err := getNetmonInfo(config)
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, expectedNetmon, netmon)
|
|
}
|
|
|
|
func TestEnvGetNetmonInfoNoVersion(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
_, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
expectedNetmon, err := getExpectedNetmonDetails(config)
|
|
assert.NoError(t, err)
|
|
|
|
// remove the netmon ensuring its version cannot be queried
|
|
err = os.Remove(config.NetmonConfig.Path)
|
|
assert.NoError(t, err)
|
|
|
|
expectedNetmon.Version = unknown
|
|
|
|
netmon, err := getNetmonInfo(config)
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, expectedNetmon, netmon)
|
|
}
|
|
|
|
func TestEnvGetShimInfo(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
_, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
expectedShim, err := getExpectedShimDetails(config)
|
|
assert.NoError(t, err)
|
|
|
|
shim, err := getShimInfo(config)
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, expectedShim, shim)
|
|
}
|
|
|
|
func TestEnvGetShimInfoNoVersion(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
_, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
expectedShim, err := getExpectedShimDetails(config)
|
|
assert.NoError(t, err)
|
|
|
|
shimPath := expectedShim.Path
|
|
|
|
// ensure querying the shim version fails
|
|
err = createFile(shimPath, `#!/bin/sh
|
|
exit 1`)
|
|
assert.NoError(t, err)
|
|
|
|
expectedShim.Version = unknown
|
|
|
|
shim, err := getShimInfo(config)
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, expectedShim, shim)
|
|
}
|
|
|
|
func TestEnvGetShimInfoInvalidType(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
_, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
_, err = getExpectedShimDetails(config)
|
|
assert.NoError(t, err)
|
|
|
|
config.ShimConfig = "foo"
|
|
_, err = getShimInfo(config)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestEnvGetAgentInfo(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
_, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
expectedAgent, err := getExpectedAgentDetails(config)
|
|
assert.NoError(t, err)
|
|
|
|
agent := getAgentInfo(config)
|
|
assert.Equal(t, expectedAgent, agent)
|
|
}
|
|
|
|
func testEnvShowTOMLSettings(t *testing.T, tmpdir string, tmpfile *os.File) error {
|
|
|
|
runtime := RuntimeInfo{}
|
|
|
|
hypervisor := HypervisorInfo{
|
|
Path: "/resolved/hypervisor/path",
|
|
MachineType: "hypervisor-machine-type",
|
|
}
|
|
|
|
image := ImageInfo{
|
|
Path: "/resolved/image/path",
|
|
}
|
|
|
|
kernel := KernelInfo{
|
|
Path: "/kernel/path",
|
|
Parameters: "foo=bar xyz",
|
|
}
|
|
|
|
proxy := ProxyInfo{
|
|
Type: "proxy-type",
|
|
Version: "proxy-version",
|
|
Path: "file:///proxy-url",
|
|
Debug: false,
|
|
}
|
|
|
|
shim := ShimInfo{
|
|
Type: "shim-type",
|
|
Version: "shim-version",
|
|
Path: "/resolved/shim/path",
|
|
}
|
|
|
|
agent := AgentInfo{
|
|
Type: "agent-type",
|
|
}
|
|
|
|
expectedHostDetails, err := getExpectedHostDetails(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
env := EnvInfo{
|
|
Runtime: runtime,
|
|
Hypervisor: hypervisor,
|
|
Image: image,
|
|
Kernel: kernel,
|
|
Proxy: proxy,
|
|
Shim: shim,
|
|
Agent: agent,
|
|
Host: expectedHostDetails,
|
|
}
|
|
|
|
err = writeTOMLSettings(env, tmpfile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
contents, err := katautils.GetFileContents(tmpfile.Name())
|
|
assert.NoError(t, err)
|
|
|
|
buf := new(bytes.Buffer)
|
|
encoder := toml.NewEncoder(buf)
|
|
err = encoder.Encode(env)
|
|
assert.NoError(t, err)
|
|
|
|
expectedContents := buf.String()
|
|
|
|
assert.Equal(t, expectedContents, contents)
|
|
|
|
return nil
|
|
}
|
|
|
|
func testEnvShowJSONSettings(t *testing.T, tmpdir string, tmpfile *os.File) error {
|
|
|
|
runtime := RuntimeInfo{}
|
|
|
|
hypervisor := HypervisorInfo{
|
|
Path: "/resolved/hypervisor/path",
|
|
MachineType: "hypervisor-machine-type",
|
|
}
|
|
|
|
image := ImageInfo{
|
|
Path: "/resolved/image/path",
|
|
}
|
|
|
|
kernel := KernelInfo{
|
|
Path: "/kernel/path",
|
|
Parameters: "foo=bar xyz",
|
|
}
|
|
|
|
proxy := ProxyInfo{
|
|
Type: "proxy-type",
|
|
Version: "proxy-version",
|
|
Path: "file:///proxy-url",
|
|
Debug: false,
|
|
}
|
|
|
|
shim := ShimInfo{
|
|
Type: "shim-type",
|
|
Version: "shim-version",
|
|
Path: "/resolved/shim/path",
|
|
}
|
|
|
|
agent := AgentInfo{
|
|
Type: "agent-type",
|
|
}
|
|
|
|
expectedHostDetails, err := getExpectedHostDetails(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
env := EnvInfo{
|
|
Runtime: runtime,
|
|
Hypervisor: hypervisor,
|
|
Image: image,
|
|
Kernel: kernel,
|
|
Proxy: proxy,
|
|
Shim: shim,
|
|
Agent: agent,
|
|
Host: expectedHostDetails,
|
|
}
|
|
|
|
err = writeJSONSettings(env, tmpfile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
contents, err := katautils.GetFileContents(tmpfile.Name())
|
|
assert.NoError(t, err)
|
|
|
|
buf := new(bytes.Buffer)
|
|
encoder := json.NewEncoder(buf)
|
|
// Ensure we have the same human readable layout
|
|
encoder.SetIndent("", " ")
|
|
err = encoder.Encode(env)
|
|
assert.NoError(t, err)
|
|
|
|
expectedContents := buf.String()
|
|
|
|
assert.Equal(t, expectedContents, contents)
|
|
|
|
return nil
|
|
}
|
|
|
|
func TestEnvShowSettings(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
tmpfile, err := ioutil.TempFile("", "envShowSettings-")
|
|
assert.NoError(t, err)
|
|
defer os.Remove(tmpfile.Name())
|
|
|
|
err = testEnvShowTOMLSettings(t, tmpdir, tmpfile)
|
|
assert.NoError(t, err)
|
|
|
|
// Reset the file to empty for next test
|
|
tmpfile.Truncate(0)
|
|
tmpfile.Seek(0, 0)
|
|
err = testEnvShowJSONSettings(t, tmpdir, tmpfile)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestEnvShowSettingsInvalidFile(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
tmpfile, err := ioutil.TempFile("", "envShowSettings-")
|
|
assert.NoError(t, err)
|
|
defer os.Remove(tmpfile.Name())
|
|
|
|
// close the file
|
|
tmpfile.Close()
|
|
|
|
err = testEnvShowTOMLSettings(t, tmpdir, tmpfile)
|
|
assert.Error(t, err)
|
|
|
|
// Reset the file to empty for next test
|
|
tmpfile.Truncate(0)
|
|
tmpfile.Seek(0, 0)
|
|
err = testEnvShowJSONSettings(t, tmpdir, tmpfile)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestEnvHandleSettings(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
configFile, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
_, err = getExpectedSettings(config, tmpdir, configFile)
|
|
assert.NoError(t, err)
|
|
|
|
set := flag.NewFlagSet("test", flag.ContinueOnError)
|
|
ctx := createCLIContext(set)
|
|
ctx.App.Name = "foo"
|
|
ctx.App.Metadata["configFile"] = configFile
|
|
ctx.App.Metadata["runtimeConfig"] = config
|
|
|
|
tmpfile, err := ioutil.TempFile("", "")
|
|
assert.NoError(t, err)
|
|
defer os.Remove(tmpfile.Name())
|
|
|
|
err = handleSettings(tmpfile, ctx)
|
|
assert.NoError(t, err)
|
|
|
|
var env EnvInfo
|
|
|
|
_, err = toml.DecodeFile(tmpfile.Name(), &env)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestEnvHandleSettingsInvalidShimConfig(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
configFile, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(err)
|
|
|
|
_, err = getExpectedSettings(config, tmpdir, configFile)
|
|
assert.NoError(err)
|
|
|
|
config.ShimConfig = "invalid shim config"
|
|
|
|
ctx := createCLIContext(nil)
|
|
ctx.App.Name = "foo"
|
|
ctx.App.Metadata["configFile"] = configFile
|
|
ctx.App.Metadata["runtimeConfig"] = config
|
|
|
|
tmpfile, err := ioutil.TempFile("", "")
|
|
assert.NoError(err)
|
|
defer os.Remove(tmpfile.Name())
|
|
|
|
err = handleSettings(tmpfile, ctx)
|
|
assert.Error(err)
|
|
}
|
|
|
|
func TestEnvHandleSettingsInvalidParams(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
configFile, _, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(err)
|
|
|
|
ctx := createCLIContext(nil)
|
|
ctx.App.Name = "foo"
|
|
ctx.App.Metadata["configFile"] = configFile
|
|
|
|
err = handleSettings(nil, ctx)
|
|
assert.Error(err)
|
|
}
|
|
|
|
func TestEnvHandleSettingsEmptyMap(t *testing.T) {
|
|
ctx := createCLIContext(nil)
|
|
ctx.App.Name = "foo"
|
|
ctx.App.Metadata = map[string]interface{}{}
|
|
err := handleSettings(os.Stdout, ctx)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestEnvHandleSettingsInvalidFile(t *testing.T) {
|
|
ctx := createCLIContext(nil)
|
|
ctx.App.Name = "foo"
|
|
ctx.App.Metadata["configFile"] = "foo"
|
|
ctx.App.Metadata["runtimeConfig"] = oci.RuntimeConfig{}
|
|
|
|
err := handleSettings(nil, ctx)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestEnvHandleSettingsInvalidConfigFileType(t *testing.T) {
|
|
ctx := createCLIContext(nil)
|
|
ctx.App.Name = "foo"
|
|
ctx.App.Metadata["configFile"] = 123
|
|
ctx.App.Metadata["runtimeConfig"] = oci.RuntimeConfig{}
|
|
|
|
err := handleSettings(os.Stderr, ctx)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestEnvHandleSettingsInvalidRuntimeConfigType(t *testing.T) {
|
|
ctx := createCLIContext(nil)
|
|
ctx.App.Name = "foo"
|
|
ctx.App.Metadata["configFile"] = "/some/where"
|
|
ctx.App.Metadata["runtimeConfig"] = true
|
|
|
|
err := handleSettings(os.Stderr, ctx)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestEnvCLIFunction(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
configFile, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
_, err = getExpectedSettings(config, tmpdir, configFile)
|
|
assert.NoError(t, err)
|
|
|
|
app := cli.NewApp()
|
|
set := flag.NewFlagSet("test", flag.ContinueOnError)
|
|
ctx := createCLIContextWithApp(set, app)
|
|
app.Name = "foo"
|
|
|
|
ctx.App.Metadata["configFile"] = configFile
|
|
ctx.App.Metadata["runtimeConfig"] = config
|
|
|
|
fn, ok := kataEnvCLICommand.Action.(func(context *cli.Context) error)
|
|
assert.True(t, ok)
|
|
|
|
devNull, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0666)
|
|
assert.NoError(t, err)
|
|
|
|
// throw away output
|
|
savedOutputFile := defaultOutputFile
|
|
defaultOutputFile = devNull
|
|
|
|
defer func() {
|
|
defaultOutputFile = savedOutputFile
|
|
}()
|
|
|
|
err = fn(ctx)
|
|
assert.NoError(t, err)
|
|
|
|
set.Bool("json", true, "")
|
|
ctx = createCLIContextWithApp(set, app)
|
|
|
|
err = fn(ctx)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestEnvCLIFunctionFail(t *testing.T) {
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
configFile, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(t, err)
|
|
|
|
_, err = getExpectedSettings(config, tmpdir, configFile)
|
|
assert.NoError(t, err)
|
|
|
|
ctx := createCLIContext(nil)
|
|
ctx.App.Name = "foo"
|
|
|
|
ctx.App.Metadata["configFile"] = configFile
|
|
ctx.App.Metadata["runtimeConfig"] = config
|
|
|
|
fn, ok := kataEnvCLICommand.Action.(func(context *cli.Context) error)
|
|
assert.True(t, ok)
|
|
|
|
savedOutputFile := defaultOutputFile
|
|
// invalidate
|
|
defaultOutputFile = nil
|
|
|
|
defer func() {
|
|
defaultOutputFile = savedOutputFile
|
|
}()
|
|
|
|
err = fn(ctx)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestGetHypervisorInfo(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
_, config, err := makeRuntimeConfig(tmpdir)
|
|
assert.NoError(err)
|
|
|
|
info := getHypervisorInfo(config)
|
|
assert.Equal(info.Version, testHypervisorVersion)
|
|
|
|
err = os.Remove(config.HypervisorConfig.HypervisorPath)
|
|
assert.NoError(err)
|
|
|
|
info = getHypervisorInfo(config)
|
|
assert.Equal(info.Version, unknown)
|
|
}
|