Skip to content

Commit

Permalink
rename cmd/runtimetest to main config test; add state test
Browse files Browse the repository at this point in the history
Signed-off-by: liang chenye <liangchenye@huawei.com>
  • Loading branch information
liangchenye committed May 10, 2016
1 parent 9d1c354 commit 1f8cb69
Show file tree
Hide file tree
Showing 5 changed files with 322 additions and 412 deletions.
57 changes: 0 additions & 57 deletions config/config.go

This file was deleted.

8 changes: 5 additions & 3 deletions generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ var generateCommand = cli.Command{
Usage: "generate a OCI spec file",
Flags: generateFlags,
Action: func(context *cli.Context) {
spec := getDefaultTemplate()
spec := GetDefaultTemplate()
template := context.String("template")
if template != "" {
var err error
Expand Down Expand Up @@ -143,10 +143,11 @@ func modify(spec *rspec.Spec, context *cli.Context) error {
spec.Process.Terminal = context.Bool("tty")
}

fmt.Println(context.StringSlice("args"))
for i, a := range context.StringSlice("args") {
if a != "" {
if i == 0 {
// Replace "sh" from getDefaultTemplate()
// Replace "sh" from GetDefaultTemplate()
spec.Process.Args[0] = a
} else {
spec.Process.Args = append(spec.Process.Args, a)
Expand Down Expand Up @@ -675,7 +676,8 @@ func setupNamespaces(spec *rspec.Spec, context *cli.Context) {

func sPtr(s string) *string { return &s }

func getDefaultTemplate() *rspec.Spec {
//GetDefaultTemplate provides a default oci spec.
func GetDefaultTemplate() *rspec.Spec {
spec := rspec.Spec{
Version: rspec.Version,
Platform: rspec.Platform{
Expand Down
174 changes: 140 additions & 34 deletions runtimetest.go
Original file line number Diff line number Diff line change
@@ -1,62 +1,59 @@
package main

import (
"errors"
"fmt"
"io"
"os"
"path"
"runtime"
"time"

"github.com/Sirupsen/logrus"
"github.com/codegangsta/cli"
"github.com/opencontainers/ocitools/units"
rspec "github.com/opencontainers/runtime-spec/specs-go"
)

const bundleCacheDir = "./bundles"

var runtimetestFlags = []cli.Flag{
cli.StringFlag{Name: "runtime, r", Usage: "runtime to be tested"},
cli.StringFlag{Name: "output, o", Usage: "output format, \n" +
"-o=all: ouput sucessful details and statics, -o=err-only: ouput failure details and statics"},
cli.BoolFlag{Name: "debug, d", Usage: "switch of debug mode, defaults to false, with '--debug' to enable debug mode"},
cli.BoolFlag{Name: "debug, d", Usage: "switch of debug mode, default to 'false', with '--debug' to enable debug mode"},
}

var runtimeTestCommand = cli.Command{
Name: "runtimetest",
Usage: "test if a runtime is comlpliant to oci specs",
Usage: "test if a runtime is compliant to OCI Runtime Specification",
Flags: runtimetestFlags,
Action: func(context *cli.Context) {

if os.Geteuid() != 0 {
logrus.Fatalln("runtimetest should be run as root")
logrus.Fatalln("Should be run as 'root'")
}
var runtime string
if runtime = context.String("runtime"); runtime != "runc" {
logrus.Fatalf("runtimetest have not support %v\n", runtime)
logrus.Fatalf("'%s' is currently not supported", runtime)
}
output := context.String("output")
setDebugMode(context.Bool("debug"))

units.LoadTestUnits("./cases.conf")

if err := os.MkdirAll(bundleCacheDir, os.ModePerm); err != nil {
logrus.Printf("create cache dir for bundle cases err: %v\ns", bundleCacheDir)
return
logrus.Fatalf("Failed to create cache dir: %s", bundleCacheDir)
}

for _, tu := range *units.Units {
testTask(tu, runtime)
}

units.OutputResult(output)

if err := os.RemoveAll(bundleCacheDir); err != nil {
logrus.Fatalf("remove cache dir of bundles %v err: %v\n", bundleCacheDir, err)
_, err := testState(runtime)
if err != nil {
os.RemoveAll(bundleCacheDir)
logrus.Fatalf("\n%v", err)
}
logrus.Info("Runtime state test succeeded.")

if err := os.Remove("./runtime.json"); err != nil {
logrus.Fatalf("remove ./runtime.json err: %v\n", err)
output, err := testMainConfigs(runtime)
if err != nil {
os.RemoveAll(bundleCacheDir)
logrus.Infof("\n%s", output)
logrus.Fatalf("\n%v", err)
}

if err := os.Remove("./config.json"); err != nil {
logrus.Fatalf("remove ./config.json err: %v\n", err)
if output != "" {
logrus.Infof("\n%s", output)
}
logrus.Info("Runtime main config test succeeded.")

},
}
Expand All @@ -69,12 +66,121 @@ func setDebugMode(debug bool) {
}
}

func testTask(unit *units.TestUnit, runtime string) {
logrus.Debugf("test bundle name: %v, Test args: %v\n", unit.Name, unit.Args)
if err := unit.SetRuntime(runtime); err != nil {
logrus.Fatalf("failed to setup runtime %s , error: %v\n", runtime, err)
func testState(runtime string) (string, error) {
testConfig := getDefaultConfig()
testConfig.Process.Args = []string{"sleep", "60"}
//TODO: use UUID
testID := "12345678"
unit := TestUnit{
Name: "state",
Runtime: runtime,
Config: testConfig,
ID: testID,
}
go func() {
unit.Start()
}()
var state rspec.State
var err error
for t := time.Now(); time.Since(t) < time.Minute; time.Sleep(time.Second * 5) {
if state, err = unit.GetState(); err == nil {
break
}
}

if err != nil {
return "", err
}

defer unit.Stop()
if state.ID != testID {
return "", fmt.Errorf("Expect container ID: %s to match: %s", state.ID, testID)
}
if state.BundlePath != unit.GetBundlePath() {
return "", fmt.Errorf("Expect container bundle path: %s to match: %s", state.BundlePath, unit.GetBundlePath())
}

unitDup := TestUnit{
Name: "state-dup",
Runtime: runtime,
Config: testConfig,
ID: testID,
}
unitDup.Start()
defer unitDup.Stop()
// Expected to get error
if output, err := unitDup.GetOutput(); err != nil {
return output, nil
} else {
return output, errors.New("Failed to popup error with duplicated container ID")
}
}

func testMainConfigs(runtime string) (string, error) {
testConfig := getDefaultConfig()
testConfig.Process.Args = []string{"./runtimetest"}
testConfig.Hostname = "zenlin"

hostnameUnit := TestUnit{
Name: "configs",
Runtime: runtime,
Config: testConfig,
ExpectedResult: true,
}

hostnameUnit.Prepare()
defer hostnameUnit.Clean()

// Copy runtimtest from plugins to rootfs
src := "./runtimetest"
dest := path.Join(hostnameUnit.GetBundlePath(), "rootfs", "runtimetest")
if err := copyFile(dest, src); err != nil {
return "", fmt.Errorf("Failed to copy '%s' to '%s': %v\n", src, dest, err)
}
if err := os.Chmod(dest, os.ModePerm); err != nil {
return "", fmt.Errorf("Failed to chmod runtimetest: %v\n", err)
}

src = path.Join(hostnameUnit.GetBundlePath(), configFile)
dest = path.Join(hostnameUnit.GetBundlePath(), "rootfs", configFile)
if err := copyFile(dest, src); err != nil {
return "", fmt.Errorf("Failed to copy '%s' to '%s': %v\n", src, dest, err)
}

hostnameUnit.Start()
defer hostnameUnit.Stop()
if output, err := hostnameUnit.GetOutput(); err != nil {
return output, fmt.Errorf("Failed to test main config '%s' case: %v", hostnameUnit.Name, err)
} else {
unit.Run()
return output, nil
}
}

func copyFile(dst string, src string) error {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
return
defer out.Close()
_, err = io.Copy(out, in)
cerr := out.Close()
if err != nil {
return err
}
return cerr
}

func getDefaultConfig() *rspec.Spec {
config := GetDefaultTemplate()
config.Root.Path = "rootfs"
config.Platform.OS = runtime.GOOS
config.Platform.Arch = runtime.GOARCH
config.Process.Cwd = "/"

return config
}
Loading

0 comments on commit 1f8cb69

Please sign in to comment.