package cmd import ( "io/ioutil" "strconv" "strings" "testing" kapi "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/apimachinery/registered" buildapi "github.com/openshift/origin/pkg/build/api" "github.com/openshift/origin/pkg/client/testclient" ) // TestCancelBuildDefaultFlags ensures that flags default values are set. func TestCancelBuildDefaultFlags(t *testing.T) { o := CancelBuildOptions{} tests := map[string]struct { flagName string defaultVal string }{ "state": { flagName: "state", defaultVal: "[" + strings.Join(o.States, ",") + "]", }, "dump-logs": { flagName: "dump-logs", defaultVal: strconv.FormatBool(o.DumpLogs), }, "restart": { flagName: "restart", defaultVal: strconv.FormatBool(o.Restart), }, } cmd := NewCmdCancelBuild("oc", CancelBuildRecommendedCommandName, nil, nil, nil, nil) for _, v := range tests { f := cmd.Flag(v.flagName) if f == nil { t.Fatalf("expected flag %s to be registered but found none", v.flagName) } if f.DefValue != v.defaultVal { t.Errorf("expected default value of %s for %s but found %s", v.defaultVal, v.flagName, f.DefValue) } } } // TestCancelBuildRun ensures that RunCancelBuild command calls the right actions. func TestCancelBuildRun(t *testing.T) { tests := map[string]struct { opts *CancelBuildOptions phase buildapi.BuildPhase expectedActions []testAction expectedErr error }{ "cancelled": { opts: &CancelBuildOptions{ Out: ioutil.Discard, Namespace: "test", States: []string{"new", "pending", "running"}, }, phase: buildapi.BuildPhaseCancelled, expectedActions: []testAction{ {verb: "get", resource: "builds"}, }, expectedErr: nil, }, "complete": { opts: &CancelBuildOptions{ Out: ioutil.Discard, Namespace: "test", }, phase: buildapi.BuildPhaseComplete, expectedActions: []testAction{ {verb: "get", resource: "builds"}, }, expectedErr: nil, }, "new": { opts: &CancelBuildOptions{ Out: ioutil.Discard, Namespace: "test", }, phase: buildapi.BuildPhaseNew, expectedActions: []testAction{ {verb: "get", resource: "builds"}, {verb: "update", resource: "builds"}, {verb: "get", resource: "builds"}, }, expectedErr: nil, }, "pending": { opts: &CancelBuildOptions{ Out: ioutil.Discard, Namespace: "test", }, phase: buildapi.BuildPhaseNew, expectedActions: []testAction{ {verb: "get", resource: "builds"}, {verb: "update", resource: "builds"}, {verb: "get", resource: "builds"}, }, expectedErr: nil, }, "running and restart": { opts: &CancelBuildOptions{ Out: ioutil.Discard, Namespace: "test", Restart: true, }, phase: buildapi.BuildPhaseNew, expectedActions: []testAction{ {verb: "get", resource: "builds"}, {verb: "update", resource: "builds"}, {verb: "get", resource: "builds"}, {verb: "create", resource: "builds"}, }, expectedErr: nil, }, } for _, test := range tests { client := testclient.NewSimpleFake(genBuild(test.phase)) buildClient := NewFakeTestBuilds(client, test.opts.Namespace) test.opts.Client = client test.opts.BuildClient = buildClient test.opts.ReportError = func(err error) { test.opts.HasError = true } test.opts.Mapper = registered.RESTMapper() test.opts.BuildNames = []string{"ruby-ex"} test.opts.States = []string{"new", "pending", "running"} if err := test.opts.RunCancelBuild(); err != test.expectedErr { t.Fatalf("error mismatch: expected %v, got %v", test.expectedErr, err) } got := test.opts.Client.(*testclient.Fake).Actions() if len(test.expectedActions) != len(got) { t.Fatalf("action length mismatch: expected %d, got %d", len(test.expectedActions), len(got)) } for i, action := range test.expectedActions { if !got[i].Matches(action.verb, action.resource) { t.Errorf("action mismatch: expected %s %s, got %s %s", action.verb, action.resource, got[i].GetVerb(), got[i].GetResource()) } } } } type FakeTestBuilds struct { *testclient.FakeBuilds Obj *buildapi.Build } func NewFakeTestBuilds(c *testclient.Fake, ns string) *FakeTestBuilds { f := FakeTestBuilds{} f.FakeBuilds = &testclient.FakeBuilds{} f.Fake = c f.Namespace = ns return &f } func (c *FakeTestBuilds) Get(name string) (*buildapi.Build, error) { obj, err := c.FakeBuilds.Get(name) if c.Obj == nil { c.Obj = obj } return c.Obj, err } func (c *FakeTestBuilds) Update(inObj *buildapi.Build) (*buildapi.Build, error) { _, err := c.FakeBuilds.Update(inObj) if inObj.Status.Cancelled == true { inObj.Status.Phase = buildapi.BuildPhaseCancelled } c.Obj = inObj return c.Obj, err } func genBuild(phase buildapi.BuildPhase) *buildapi.Build { build := buildapi.Build{ ObjectMeta: kapi.ObjectMeta{ Name: "ruby-ex", Namespace: "test", }, Status: buildapi.BuildStatus{ Phase: phase, }, } return &build }