Merge pull request #405 from procrypt/unit_tests

Unit tests for error out if controller object is specified with restart: on-failure
This commit is contained in:
Tomas Kral 2017-02-14 15:36:31 +01:00 committed by GitHub
commit d20a42e447
2 changed files with 102 additions and 0 deletions

View File

@ -29,6 +29,8 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/extensions"
"os"
"os/exec"
) )
func newServiceConfig() kobject.ServiceConfig { func newServiceConfig() kobject.ServiceConfig {
@ -451,3 +453,52 @@ func TestUnsupportedKeys(t *testing.T) {
} }
} }
// Here we are testing a function which results in `logus.Fatalf()` when a condition is met, which further call `os.Exit()` and exits the process.
// If we write a test in the usual way that will call the function,
// it will exit the process and the running process is actually the test process and our test would fail.
// So to test the function resulting in `os.Exit()` we need invoke go test again in a separate process through `exec.Command`,
// limiting execution to the TestRestartOnFailure test using `-test.run=TestRestartOnFailure` flag set.
// The `TestRestartOnFailure` doing is two things simultaneously,
// it is going to the be the test itself and second it will a be `subprocess` that the test runs.
func TestRestartOnFailure(t *testing.T) {
kobjectWithRestartOnFailure := newKomposeObject()
serviceConfig := kobjectWithRestartOnFailure.ServiceConfigs["app"]
serviceConfig.Restart = "on-failure"
kobjectWithRestartOnFailure.ServiceConfigs = map[string]kobject.ServiceConfig{"app": serviceConfig}
// define all test cases for RestartOnFailure function
replicas := 2
testCase := map[string]struct {
komposeObject kobject.KomposeObject
opt kobject.ConvertOptions
}{
// objects generated are deployment, service and replication controller
"Do not Create Deployment (D) with restart:'on-failure'": {kobjectWithRestartOnFailure, kobject.ConvertOptions{IsDeploymentFlag: true, Replicas: replicas}},
"Do not Create DaemonSet (DS) with restart:'on-failure'": {kobjectWithRestartOnFailure, kobject.ConvertOptions{IsDaemonSetFlag: true, Replicas: replicas}},
"Do not Create ReplicationController (RC) with restart:'on-failure'": {kobjectWithRestartOnFailure, kobject.ConvertOptions{IsReplicationControllerFlag: true, Replicas: replicas}},
}
for name, test := range testCase {
t.Log("Test case:", name)
k := Kubernetes{}
if os.Getenv("BE_CRASHER") == "1" {
k.Transform(test.komposeObject, test.opt)
}
}
// cmd := exec.Command(os.Args[0], "-test.run=TestRestartOnFailure") will execute the test binary
// with the flag -test.run=TestRestartOnFailure and set the environment variable BE_CRASHER=1.
cmd := exec.Command(os.Args[0], "-test.run=TestRestartOnFailure")
cmd.Env = append(os.Environ(), "BE_CRASHER=1")
// err := cmd.Run() will re-execute the test binary and this time os.Getenv("BE_CRASHER") == "1"
// will return true and we can call o.Transform(test.komposeObject, test.opt).
// so that the test binary that calls itself and execute the code on behalf of the parent process.
err := cmd.Run()
if e, ok := err.(*exec.ExitError); ok && !e.Success() {
return
}
t.Fatalf("Process ran with err %v, want exit status 1", err)
}

View File

@ -29,6 +29,7 @@ import (
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/kubernetes-incubator/kompose/pkg/testutils" "github.com/kubernetes-incubator/kompose/pkg/testutils"
"github.com/kubernetes-incubator/kompose/pkg/transformer/kubernetes" "github.com/kubernetes-incubator/kompose/pkg/transformer/kubernetes"
"os/exec"
) )
func newServiceConfig() kobject.ServiceConfig { func newServiceConfig() kobject.ServiceConfig {
@ -329,3 +330,53 @@ func TestServiceWithoutPort(t *testing.T) {
} }
} }
// Here we are testing a function which results in `logus.Fatalf()` when a condition is met, which further call `os.Exit()` and exits the process.
// If we write a test in the usual way that will call the function,
// it will exit the process and the running process is actually the test process and our test would fail.
// So to test the function resulting in `os.Exit()` we need invoke go test again in a separate process through `exec.Command`,
// limiting execution to the TestRestartOnFailure test using `-test.run=TestRestartOnFailure` flag set.
// The `TestRestartOnFailure` doing is two things simultaneously,
// it is going to the be the test itself and second it will a be `subprocess` that the test runs.
func TestRestartOnFailure(t *testing.T) {
service := kobject.ServiceConfig{
Restart: "on-failure",
}
komposeObject := kobject.KomposeObject{
ServiceConfigs: map[string]kobject.ServiceConfig{"app": service},
}
// define all test cases for RestartOnFailure function
replicas := 2
testCase := map[string]struct {
komposeObject kobject.KomposeObject
opt kobject.ConvertOptions
}{
// objects generated are deployment, service and replication controller
"Do not Create DeploymentConfig (DC) with restart:'on-failure'": {komposeObject, kobject.ConvertOptions{IsDeploymentConfigFlag: true, Replicas: replicas}},
}
for name, test := range testCase {
t.Log("Test case:", name)
o := OpenShift{}
if os.Getenv("BE_CRASHER") == "1" {
o.Transform(test.komposeObject, test.opt)
}
}
// cmd := exec.Command(os.Args[0], "-test.run=TestRestartOnFailure") will execute the test binary
// with the flag -test.run=TestRestartOnFailure and set the environment variable BE_CRASHER=1
cmd := exec.Command(os.Args[0], "-test.run=TestRestartOnFailure")
cmd.Env = append(os.Environ(), "BE_CRASHER=1")
// err := cmd.Run() will re-execute the test binary and this time os.Getenv("BE_CRASHER") == "1".
// will return true and we can call o.Transform(test.komposeObject, test.opt).
// so that the test binary that calls itself and execute the code on behalf of the parent process.
err := cmd.Run()
if e, ok := err.(*exec.ExitError); ok && !e.Success() {
return
}
t.Fatalf("Process ran with err %v, want exit status 1", err)
}