From 64bc2e1568c3a20b50e2f54bfe199cea0a9d2c8c Mon Sep 17 00:00:00 2001 From: liang chenye Date: Fri, 13 May 2016 17:10:19 +0800 Subject: [PATCH] add start test Signed-off-by: liang chenye --- README.md | 8 ++-- runtimetest.go | 109 ++++++++++++++++++++++++++++++------------------- testunit.go | 38 +++++++---------- 3 files changed, 86 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index 8cc229a26..91538f59c 100644 --- a/README.md +++ b/README.md @@ -31,10 +31,10 @@ FATA[0000] Bundle path shouldn't be empty ```sh # ocitools runtimetest -r runc -INFO[0000] Start to test runtime lifecircle... -INFO[0001] Runtime lifecircle test succeeded. -INFO[0001] Start to test runtime state... -INFO[0006] Runtime state test succeeded. +INFO[0000] Start to test runtime lifecycle... +INFO[0001] Runtime lifecycle test succeeded. +INFO[0001] Start to test runtime operation... +INFO[0006] Runtime operation test succeeded. INFO[0006] Start to test runtime main config... INFO[0006] validating container process validating capabilities diff --git a/runtimetest.go b/runtimetest.go index 31807ce32..ef423d19a 100644 --- a/runtimetest.go +++ b/runtimetest.go @@ -1,7 +1,6 @@ package main import ( - "errors" "fmt" "io" "os" @@ -43,12 +42,12 @@ var runtimeTestCommand = cli.Command{ } logrus.Info("Runtime lifecycle test succeeded.") - logrus.Info("Start to test runtime state...") - if _, err := testState(runtime); err != nil { + logrus.Info("Start to test runtime operation...") + if _, err := testOperation(runtime); err != nil { os.RemoveAll(TestCacheDir) logrus.Fatal(err) } - logrus.Info("Runtime state test succeeded.") + logrus.Info("Runtime operation test succeeded.") logrus.Info("Start to test runtime main config...") if output, err := testMainConfigs(runtime); err != nil { @@ -63,23 +62,29 @@ var runtimeTestCommand = cli.Command{ }, } -func testState(runtime string) (string, error) { - testConfig := getDefaultConfig() - testConfig.Process.Args = []string{"sleep", "60"} - testID := GetFreeUUID(runtime) - unit := TestUnit{ - Name: "state", +func testOperation(runtime string) (string, error) { + testRunningConfig := getDefaultConfig() + testRunningConfig.Process.Args = []string{"sleep", "60"} + runningUnit := TestUnit{ + Name: "running", Runtime: runtime, - Config: testConfig, - ID: testID, + Config: testRunningConfig, + } + if _, err := runningUnit.GetState(); err == nil { + return "", ErrStateWithoutID } + + runningID := GetFreeUUID(runtime) + runningUnit.ID = runningID + // Start a running container (terminated in 60s) go func() { - unit.Start() + runningUnit.Prepare() + runningUnit.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 { + if state, err = runningUnit.GetState(); err == nil { break } } @@ -88,28 +93,37 @@ func testState(runtime string) (string, error) { return "", err } - defer unit.Stop() - if state.ID != testID { - return "", fmt.Errorf("Expected container ID: %s to match: %s", state.ID, testID) - } - if state.BundlePath != unit.GetBundlePath() { - return "", fmt.Errorf("Expected container bundle path: %s to match: %s", state.BundlePath, unit.GetBundlePath()) + defer runningUnit.Stop() + if err := checkState(state, runningUnit); err != nil { + return "", err } - unitDup := TestUnit{ - Name: "state-dup", - Runtime: runtime, - Config: testConfig, - ID: testID, + type testOperationUnit struct { + Unit TestUnit + prepare bool + expectedErr error } - unitDup.Start() - defer unitDup.Stop() - // Expected to get error - if output, err := unitDup.GetOutput(); err != nil { - return output, nil - } else { - return output, errors.New("Expected to get an error when start with a duplicated container ID") + + testConfig := getDefaultConfig() + testConfig.Process.Args = []string{"true"} + startOperUnits := []testOperationUnit{ + {Unit: TestUnit{Name: "start-with-dup-id", Runtime: runtime, Config: testConfig, ID: runningID}, prepare: true, expectedErr: ErrStartWithDupID}, + {Unit: TestUnit{Name: "start-without-id", Runtime: runtime, Config: testConfig}, prepare: true, expectedErr: ErrStartWithoutID}, + {Unit: TestUnit{Name: "start-without-bundle", Runtime: runtime, Config: testConfig, ID: GetFreeUUID(runtime)}, prepare: false, expectedErr: ErrStartWithoutBundle}, + } + for _, operUnit := range startOperUnits { + if operUnit.prepare { + operUnit.Unit.Prepare() + } + err := operUnit.Unit.Start() + defer operUnit.Unit.Stop() + if err != nil && operUnit.expectedErr == nil { + return "", err + } else if err == nil && operUnit.expectedErr != nil { + return "", operUnit.expectedErr + } } + return "", nil } func testLifecycle(runtime string) (string, error) { @@ -126,7 +140,9 @@ func testLifecycle(runtime string) (string, error) { Name: "allOK", Runtime: runtime, Config: allOK, + ID: GetFreeUUID(runtime), } + allOKUnit.Prepare() allOKUnit.Start() defer allOKUnit.Stop() if output, err := allOKUnit.GetOutput(); err != nil { @@ -139,12 +155,13 @@ func testLifecycle(runtime string) (string, error) { poststartFailed.Hooks.Poststart = FailHooks poststopFailed := allOK poststopFailed.Hooks.Poststop = FailHooks - hookFailedUnit := []TestUnit{ - {Name: "prestart", Runtime: runtime, Config: prestartFailed}, - {Name: "poststart", Runtime: runtime, Config: poststartFailed}, - {Name: "poststop", Runtime: runtime, Config: poststopFailed}, + hookFailedUnits := []TestUnit{ + {Name: "prestart", Runtime: runtime, Config: prestartFailed, ID: GetFreeUUID(runtime)}, + {Name: "poststart", Runtime: runtime, Config: poststartFailed, ID: GetFreeUUID(runtime)}, + {Name: "poststop", Runtime: runtime, Config: poststopFailed, ID: GetFreeUUID(runtime)}, } - for _, unit := range hookFailedUnit { + for _, unit := range hookFailedUnits { + unit.Prepare() unit.Start() defer unit.Stop() if output, err := unit.GetOutput(); err == nil { @@ -160,10 +177,10 @@ func testMainConfigs(runtime string) (string, error) { testConfig.Process.Args = []string{"./runtimetest"} defaultUnit := TestUnit{ - Name: "configs", - Runtime: runtime, - Config: testConfig, - ExpectedResult: true, + Name: "configs", + Runtime: runtime, + Config: testConfig, + ID: GetFreeUUID(runtime), } defaultUnit.Prepare() @@ -222,3 +239,13 @@ func getDefaultConfig() *rspec.Spec { return config } + +func checkState(state rspec.State, unit TestUnit) error { + if state.ID != unit.ID { + return fmt.Errorf("Expected container ID: %s to match: %s", state.ID, unit.ID) + } + if state.BundlePath != unit.GetBundlePath() { + return fmt.Errorf("Expected container bundle path: %s to match: %s", state.BundlePath, unit.GetBundlePath()) + } + return nil +} diff --git a/testunit.go b/testunit.go index 3ecb8ad15..7da0cfb68 100644 --- a/testunit.go +++ b/testunit.go @@ -18,29 +18,29 @@ const ( TestCacheDir = "./bundles/" configFile = "config.json" ociTools = "ocitools" - TEST_READY = "test ready" +) + +var ( + ErrStartWithDupID = errors.New("Expected to get an error when start with a duplicated container ID") + ErrStartWithoutID = errors.New("Expected to get an error when start without provide a container ID") + ErrStartWithoutBundle = errors.New("Expected to get an error when start without provide a bundle") + ErrStateWithoutID = errors.New("Expected to get an error when state without provide a container ID") ) // TestUnit for storage testcase type TestUnit struct { - ID string - Name string - Runtime string - Config *rspec.Spec - ExpectedOutput string - ExpectedResult bool + ID string + Name string + Runtime string + Config *rspec.Spec output string err error bundlePath string - ready string } // Prepare a bundle for a test unit func (unit *TestUnit) Prepare() error { - if unit.ready == TEST_READY { - return nil - } if unit.Name == "" || unit.Runtime == "" || unit.Config == nil { return errors.New("Could not prepare a test unit which does not have 'Name', 'Runtime' or 'Config'.") } @@ -49,30 +49,20 @@ func (unit *TestUnit) Prepare() error { return errors.New("Failed to prepare bundle") } - unit.ready = TEST_READY return nil } // Clean the generated bundle of a test unit func (unit *TestUnit) Clean() error { - if unit.ready == TEST_READY { - unit.ready = "" - return os.RemoveAll(unit.bundlePath) - } return nil + return os.RemoveAll(unit.bundlePath) } // Start a test unit // Generate a bundle from unit's args and start it by unit's runtime func (unit *TestUnit) Start() error { - if unit.ready != TEST_READY { - if err := unit.Prepare(); err != nil { - return err - } - } - - if unit.ID == "" { - unit.ID = GetFreeUUID(unit.Runtime) + if unit.Runtime == "" { + return errors.New("'Runtime' must be set before start") } var stderr bytes.Buffer