test: enable running tests under root user

Add tests that run under root user to test special cases.

Fixes: #2446

Signed-off-by: bin <bin@hyper.sh>
This commit is contained in:
bin 2021-08-16 12:59:03 +08:00
parent 9bbaa66f39
commit 2abc450a4d
12 changed files with 74 additions and 20 deletions

View File

@ -84,3 +84,7 @@ jobs:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }} if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }}
run: | run: |
cd ${GOPATH}/src/github.com/${{ github.repository }} && make test cd ${GOPATH}/src/github.com/${{ github.repository }} && make test
- name: Run Unit Tests As Root User
if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }}
run: |
cd ${GOPATH}/src/github.com/${{ github.repository }} && sudo -E PATH="$PATH" make test

View File

@ -127,7 +127,7 @@ vendor:
#TARGET test: run cargo tests #TARGET test: run cargo tests
test: test:
@cargo test --all --target $(TRIPLE) @cargo test --all --target $(TRIPLE) -- --nocapture
##TARGET check: run test ##TARGET check: run test
check: clippy format check: clippy format

View File

@ -193,14 +193,6 @@ impl Storage {
size += metadata.len(); size += metadata.len();
ensure!(
self.watched_files.len() <= MAX_ENTRIES_PER_STORAGE,
WatcherError::MountTooManyFiles {
count: self.watched_files.len(),
mnt: self.source_mount_point.display().to_string()
}
);
// Insert will return old entry if any // Insert will return old entry if any
if let Some(old_st) = self.watched_files.insert(path.to_path_buf(), modified) { if let Some(old_st) = self.watched_files.insert(path.to_path_buf(), modified) {
if modified > old_st { if modified > old_st {
@ -211,6 +203,14 @@ impl Storage {
debug!(logger, "New entry: {}", path.display()); debug!(logger, "New entry: {}", path.display());
update_list.push(PathBuf::from(&path)) update_list.push(PathBuf::from(&path))
} }
ensure!(
self.watched_files.len() <= MAX_ENTRIES_PER_STORAGE,
WatcherError::MountTooManyFiles {
count: self.watched_files.len(),
mnt: self.source_mount_point.display().to_string()
}
);
} else { } else {
// Scan dir recursively // Scan dir recursively
let mut entries = fs::read_dir(path) let mut entries = fs::read_dir(path)

View File

@ -611,6 +611,7 @@ endif
go-test: $(GENERATED_FILES) go-test: $(GENERATED_FILES)
$(QUIET_BUILD)(cd $(SHIMV2_DIR)/ && ln -fs $(GENERATED_CONFIG)) $(QUIET_BUILD)(cd $(SHIMV2_DIR)/ && ln -fs $(GENERATED_CONFIG))
go clean -testcache
go test -v -mod=vendor ./... go test -v -mod=vendor ./...
check-go-static: check-go-static:

View File

@ -229,7 +229,7 @@ func checkKernelModules(modules map[string]kernelModule, handler kernelParamHand
} }
if !haveKernelModule(module) { if !haveKernelModule(module) {
kataLog.WithFields(fields).Error("kernel property not found") kataLog.WithFields(fields).Errorf("kernel property %s not found", module)
if details.required { if details.required {
count++ count++
} }
@ -292,11 +292,9 @@ func genericHostIsVMContainerCapable(details vmContainerCapableDetails) error {
errorCount := uint32(0) errorCount := uint32(0)
count := checkCPUAttribs(cpuinfo, details.requiredCPUAttribs) count := checkCPUAttribs(cpuinfo, details.requiredCPUAttribs)
errorCount += count errorCount += count
count = checkCPUFlags(cpuFlags, details.requiredCPUFlags) count = checkCPUFlags(cpuFlags, details.requiredCPUFlags)
errorCount += count errorCount += count
count, err = checkKernelModules(details.requiredKernelModules, archKernelParamHandler) count, err = checkKernelModules(details.requiredKernelModules, archKernelParamHandler)

View File

@ -161,6 +161,16 @@ func setCPUtype(hypervisorType vc.HypervisorType) error {
required: false, required: false,
}, },
} }
case "mock":
archRequiredCPUFlags = map[string]string{
cpuFlagVMX: "Virtualization support",
cpuFlagLM: "64Bit CPU",
cpuFlagSSE4_1: "SSE4.1",
}
archRequiredCPUAttribs = map[string]string{
archGenuineIntel: "Intel Architecture CPU",
}
default: default:
return fmt.Errorf("setCPUtype: Unknown hypervisor type %s", hypervisorType) return fmt.Errorf("setCPUtype: Unknown hypervisor type %s", hypervisorType)
} }
@ -292,6 +302,8 @@ func archHostCanCreateVMContainer(hypervisorType vc.HypervisorType) error {
return kvmIsUsable() return kvmIsUsable()
case "acrn": case "acrn":
return acrnIsUsable() return acrnIsUsable()
case "mock":
return nil
default: default:
return fmt.Errorf("archHostCanCreateVMContainer: Unknown hypervisor type %s", hypervisorType) return fmt.Errorf("archHostCanCreateVMContainer: Unknown hypervisor type %s", hypervisorType)
} }

View File

@ -317,11 +317,12 @@ func TestCheckHostIsVMContainerCapable(t *testing.T) {
} }
} }
setupCheckHostIsVMContainerCapable(assert, cpuInfoFile, cpuData, moduleData) // to check if host is capable for Kata Containers, must setup CPU info first.
_, config, err := makeRuntimeConfig(dir)
// remove the modules to force a failure
err = os.RemoveAll(sysModuleDir)
assert.NoError(err) assert.NoError(err)
setCPUtype(config.HypervisorType)
setupCheckHostIsVMContainerCapable(assert, cpuInfoFile, cpuData, moduleData)
details := vmContainerCapableDetails{ details := vmContainerCapableDetails{
cpuInfoFile: cpuInfoFile, cpuInfoFile: cpuInfoFile,
@ -332,6 +333,12 @@ func TestCheckHostIsVMContainerCapable(t *testing.T) {
err = hostIsVMContainerCapable(details) err = hostIsVMContainerCapable(details)
assert.Nil(err) assert.Nil(err)
// remove the modules to force a failure
err = os.RemoveAll(sysModuleDir)
assert.NoError(err)
err = hostIsVMContainerCapable(details)
assert.Error(err)
} }
func TestArchKernelParamHandler(t *testing.T) { func TestArchKernelParamHandler(t *testing.T) {

View File

@ -17,8 +17,10 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils" ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
"github.com/kata-containers/kata-containers/src/runtime/pkg/katautils" "github.com/kata-containers/kata-containers/src/runtime/pkg/katautils"
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -247,6 +249,13 @@ func genericCheckCLIFunction(t *testing.T, cpuData []testCPUData, moduleData []t
flagSet := &flag.FlagSet{} flagSet := &flag.FlagSet{}
ctx := createCLIContext(flagSet) ctx := createCLIContext(flagSet)
ctx.App.Name = "foo" ctx.App.Name = "foo"
if katatestutils.IsInGitHubActions() {
// only set to mock if on GitHub
t.Logf("running tests under GitHub actions")
config.HypervisorType = vc.MockHypervisor
}
ctx.App.Metadata["runtimeConfig"] = config ctx.App.Metadata["runtimeConfig"] = config
// create buffer to save logger output // create buffer to save logger output

View File

@ -6,7 +6,10 @@
package katatestutils package katatestutils
import "strconv" import (
"os"
"strconv"
)
type RuntimeConfigOptions struct { type RuntimeConfigOptions struct {
Hypervisor string Hypervisor string
@ -150,3 +153,8 @@ func MakeRuntimeConfigFileData(config RuntimeConfigOptions) string {
jaeger_user= "` + config.JaegerUser + `" jaeger_user= "` + config.JaegerUser + `"
jaeger_password= "` + config.JaegerPassword + `"` jaeger_password= "` + config.JaegerPassword + `"`
} }
func IsInGitHubActions() bool {
// https://docs.github.com/en/actions/reference/environment-variables#default-environment-variables
return os.Getenv("GITHUB_ACTIONS") == "true"
}

View File

@ -129,6 +129,5 @@ func TestTemplateFactory(t *testing.T) {
// expect tt.statePath not exist, if exist, it means this case failed. // expect tt.statePath not exist, if exist, it means this case failed.
_, err = os.Stat(tt.statePath) _, err = os.Stat(tt.statePath)
assert.Error(err) assert.Nil(err)
assert.True(os.IsNotExist(err))
} }

View File

@ -19,6 +19,8 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
var urandomDev = "/dev/urandom"
// VM is abstraction of a virtual machine. // VM is abstraction of a virtual machine.
type VM struct { type VM struct {
hypervisor hypervisor hypervisor hypervisor
@ -298,7 +300,6 @@ func (v *VM) OnlineCPUMemory(ctx context.Context) error {
// and reseeds it. // and reseeds it.
func (v *VM) ReseedRNG(ctx context.Context) error { func (v *VM) ReseedRNG(ctx context.Context) error {
v.logger().Infof("reseed guest random number generator") v.logger().Infof("reseed guest random number generator")
urandomDev := "/dev/urandom"
data := make([]byte, 512) data := make([]byte, 512)
f, err := os.OpenFile(urandomDev, os.O_RDONLY, 0) f, err := os.OpenFile(urandomDev, os.O_RDONLY, 0)
if err != nil { if err != nil {

View File

@ -9,6 +9,7 @@ import (
"context" "context"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath"
"testing" "testing"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
@ -59,6 +60,20 @@ func TestNewVM(t *testing.T) {
assert.Nil(err) assert.Nil(err)
err = vm.OnlineCPUMemory(context.Background()) err = vm.OnlineCPUMemory(context.Background())
assert.Nil(err) assert.Nil(err)
// mock urandom device
savedUrandomDev := urandomDev
defer func() {
urandomDev = savedUrandomDev
}()
tmpdir, err := ioutil.TempDir("", "")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
urandomDev = filepath.Join(tmpdir, "urandom")
data := make([]byte, 512)
err = ioutil.WriteFile(urandomDev, data, os.FileMode(0640))
assert.NoError(err)
err = vm.ReseedRNG(context.Background()) err = vm.ReseedRNG(context.Background())
assert.Nil(err) assert.Nil(err)