From b9c6fb52ab1bd41ee56639ed15eaae7919dab79d Mon Sep 17 00:00:00 2001 From: Xing Zhou Date: Fri, 13 Jan 2017 10:15:50 +0800 Subject: [PATCH] Added unit tests for kubectl create role command. Added unit tests for kubectl create role command. --- hack/make-rules/test-cmd-util.sh | 17 ++ pkg/kubectl/cmd/create_role_test.go | 359 ++++++++++++++++++++++++++++ 2 files changed, 376 insertions(+) create mode 100644 pkg/kubectl/cmd/create_role_test.go diff --git a/hack/make-rules/test-cmd-util.sh b/hack/make-rules/test-cmd-util.sh index 0b7495df050..efe9c58e057 100644 --- a/hack/make-rules/test-cmd-util.sh +++ b/hack/make-rules/test-cmd-util.sh @@ -57,6 +57,7 @@ pods="pods" podtemplates="podtemplates" replicasets="replicasets" replicationcontrollers="replicationcontrollers" +roles="roles" secrets="secrets" serviceaccounts="serviceaccounts" services="services" @@ -2817,6 +2818,22 @@ runTests() { kube::test::get_object_assert rolebinding/sarole "{{range.subjects}}{{.namespace}}:{{end}}" 'otherns:' kube::test::get_object_assert rolebinding/sarole "{{range.subjects}}{{.name}}:{{end}}" 'sa-name:' fi + + if kube::test::if_supports_resource "${roles}" ; then + kubectl create "${kube_flags[@]}" role pod-admin --verb=* --resource=pods + kube::test::get_object_assert role/pod-admin "{{range.rules}}{{range.verbs}}{{.}}:{{end}}{{end}}" '\*:' + kube::test::get_object_assert role/pod-admin "{{range.rules}}{{range.resources}}{{.}}:{{end}}{{end}}" 'pods:' + kube::test::get_object_assert role/pod-admin "{{range.rules}}{{range.apiGroups}}{{.}}:{{end}}{{end}}" ':' + kubectl create "${kube_flags[@]}" role resource-reader --verb=get,list --resource=pods,deployments.extensions + kube::test::get_object_assert role/resource-reader "{{range.rules}}{{range.verbs}}{{.}}:{{end}}{{end}}" 'get:list:get:list:' + kube::test::get_object_assert role/resource-reader "{{range.rules}}{{range.resources}}{{.}}:{{end}}{{end}}" 'pods:deployments:' + kube::test::get_object_assert role/resource-reader "{{range.rules}}{{range.apiGroups}}{{.}}:{{end}}{{end}}" ':extensions:' + kubectl create "${kube_flags[@]}" role resourcename-reader --verb=get,list --resource=pods --resource-name=foo + kube::test::get_object_assert role/resourcename-reader "{{range.rules}}{{range.verbs}}{{.}}:{{end}}{{end}}" 'get:list:' + kube::test::get_object_assert role/resourcename-reader "{{range.rules}}{{range.resources}}{{.}}:{{end}}{{end}}" 'pods:' + kube::test::get_object_assert role/resourcename-reader "{{range.rules}}{{range.apiGroups}}{{.}}:{{end}}{{end}}" ':' + kube::test::get_object_assert role/resourcename-reader "{{range.rules}}{{range.resourceNames}}{{.}}:{{end}}{{end}}" 'foo:' + fi ######################### # Assert short name # diff --git a/pkg/kubectl/cmd/create_role_test.go b/pkg/kubectl/cmd/create_role_test.go new file mode 100644 index 00000000000..76a4c5d1e85 --- /dev/null +++ b/pkg/kubectl/cmd/create_role_test.go @@ -0,0 +1,359 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cmd + +import ( + "bytes" + "io" + "reflect" + "testing" + + "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/kubernetes/pkg/apis/rbac" + cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" +) + +type testRolePrinter struct { + CachedRole *rbac.Role +} + +func (t *testRolePrinter) PrintObj(obj runtime.Object, out io.Writer) error { + t.CachedRole = obj.(*rbac.Role) + return nil +} + +func (t *testRolePrinter) AfterPrint(output io.Writer, res string) error { + return nil +} + +func (t *testRolePrinter) HandledResources() []string { + return []string{} +} + +func TestCreateRole(t *testing.T) { + roleName := "my-role" + + f, tf, _, _ := cmdtesting.NewAPIFactory() + printer := &testRolePrinter{} + tf.Printer = printer + tf.Namespace = "test" + + tests := map[string]struct { + verbs string + resources string + resourceNames string + expectedRole *rbac.Role + }{ + "test-duplicate-resources": { + verbs: "get,watch,list", + resources: "pods,pods", + expectedRole: &rbac.Role{ + ObjectMeta: v1.ObjectMeta{ + Name: roleName, + }, + Rules: []rbac.PolicyRule{ + { + Verbs: []string{"get", "watch", "list"}, + Resources: []string{"pods"}, + APIGroups: []string{""}, + ResourceNames: []string{}, + }, + }, + }, + }, + "test-valid-case-with-multiple-apigroups": { + verbs: "get,watch,list", + resources: "pods,deployments.extensions", + expectedRole: &rbac.Role{ + ObjectMeta: v1.ObjectMeta{ + Name: roleName, + }, + Rules: []rbac.PolicyRule{ + { + Verbs: []string{"get", "watch", "list"}, + Resources: []string{"pods"}, + APIGroups: []string{""}, + ResourceNames: []string{}, + }, + { + Verbs: []string{"get", "watch", "list"}, + Resources: []string{"deployments"}, + APIGroups: []string{"extensions"}, + ResourceNames: []string{}, + }, + }, + }, + }, + } + + for name, test := range tests { + buf := bytes.NewBuffer([]byte{}) + cmd := NewCmdCreateRole(f, buf) + cmd.Flags().Set("dry-run", "true") + cmd.Flags().Set("output", "object") + cmd.Flags().Set("verb", test.verbs) + cmd.Flags().Set("resource", test.resources) + if test.resourceNames != "" { + cmd.Flags().Set("resource-name", test.resourceNames) + } + cmd.Run(cmd, []string{roleName}) + if !reflect.DeepEqual(test.expectedRole, printer.CachedRole) { + t.Errorf("%s:\nexpected:\n%#v\nsaw:\n%#v", name, test.expectedRole, printer.CachedRole) + } + } +} + +func TestValidate(t *testing.T) { + f, tf, _, _ := cmdtesting.NewAPIFactory() + tf.Printer = &testPrinter{} + tf.Namespace = "test" + + tests := map[string]struct { + roleOptions *CreateRoleOptions + expectErr bool + }{ + "test-missing-name": { + roleOptions: &CreateRoleOptions{}, + expectErr: true, + }, + "test-missing-verb": { + roleOptions: &CreateRoleOptions{ + Name: "my-role", + }, + expectErr: true, + }, + "test-missing-resource": { + roleOptions: &CreateRoleOptions{ + Name: "my-role", + Verbs: []string{"get"}, + }, + expectErr: true, + }, + "test-invalid-verb": { + roleOptions: &CreateRoleOptions{ + Name: "my-role", + Verbs: []string{"invalid-verb"}, + Resources: []schema.GroupVersionResource{ + { + Resource: "pods", + }, + }, + }, + expectErr: true, + }, + "test-invalid-resource": { + roleOptions: &CreateRoleOptions{ + Name: "my-role", + Verbs: []string{"get"}, + Resources: []schema.GroupVersionResource{ + { + Resource: "invalid-resource", + }, + }, + }, + expectErr: true, + }, + "test-resource-name-with-multiple-resources": { + roleOptions: &CreateRoleOptions{ + Name: "my-role", + Verbs: []string{"get"}, + Resources: []schema.GroupVersionResource{ + { + Resource: "pods", + }, + { + Resource: "deployments", + Group: "extensions", + }, + }, + ResourceNames: []string{"foo"}, + }, + expectErr: true, + }, + "test-valid-case": { + roleOptions: &CreateRoleOptions{ + Name: "my-role", + Verbs: []string{"get", "list"}, + Resources: []schema.GroupVersionResource{ + { + Resource: "pods", + }, + }, + ResourceNames: []string{"foo"}, + }, + expectErr: false, + }, + } + + for name, test := range tests { + err := test.roleOptions.Validate(f) + if test.expectErr && err != nil { + continue + } + if !test.expectErr && err != nil { + t.Errorf("%s: unexpected error: %v", name, err) + } + } +} + +func TestComplete(t *testing.T) { + roleName := "my-role" + + f, tf, _, _ := cmdtesting.NewAPIFactory() + tf.Printer = &testPrinter{} + tf.Namespace = "test" + + buf := bytes.NewBuffer([]byte{}) + cmd := NewCmdCreateRole(f, buf) + cmd.Flags().Set("resource", "pods,deployments.extensions") + + tests := map[string]struct { + params []string + roleOptions *CreateRoleOptions + expected *CreateRoleOptions + expectErr bool + }{ + "test-missing-name": { + params: []string{}, + roleOptions: &CreateRoleOptions{}, + expectErr: true, + }, + "test-duplicate-verbs": { + params: []string{roleName}, + roleOptions: &CreateRoleOptions{ + Name: roleName, + Verbs: []string{ + "get", + "watch", + "list", + "get", + }, + }, + expected: &CreateRoleOptions{ + Name: roleName, + Verbs: []string{ + "get", + "watch", + "list", + }, + Resources: []schema.GroupVersionResource{ + { + Resource: "pods", + Group: "", + }, + { + Resource: "deployments", + Group: "extensions", + }, + }, + ResourceNames: []string{}, + }, + expectErr: false, + }, + "test-verball": { + params: []string{roleName}, + roleOptions: &CreateRoleOptions{ + Name: roleName, + Verbs: []string{ + "get", + "watch", + "list", + "*", + }, + }, + expected: &CreateRoleOptions{ + Name: roleName, + Verbs: []string{"*"}, + Resources: []schema.GroupVersionResource{ + { + Resource: "pods", + Group: "", + }, + { + Resource: "deployments", + Group: "extensions", + }, + }, + ResourceNames: []string{}, + }, + expectErr: false, + }, + "test-duplicate-resourcenames": { + params: []string{roleName}, + roleOptions: &CreateRoleOptions{ + Name: roleName, + Verbs: []string{"*"}, + ResourceNames: []string{"foo", "foo"}, + }, + expected: &CreateRoleOptions{ + Name: roleName, + Verbs: []string{"*"}, + Resources: []schema.GroupVersionResource{ + { + Resource: "pods", + Group: "", + }, + { + Resource: "deployments", + Group: "extensions", + }, + }, + ResourceNames: []string{"foo"}, + }, + expectErr: false, + }, + "test-valid-complete-case": { + params: []string{roleName}, + roleOptions: &CreateRoleOptions{ + Name: roleName, + Verbs: []string{"*"}, + ResourceNames: []string{"foo"}, + }, + expected: &CreateRoleOptions{ + Name: roleName, + Verbs: []string{"*"}, + Resources: []schema.GroupVersionResource{ + { + Resource: "pods", + Group: "", + }, + { + Resource: "deployments", + Group: "extensions", + }, + }, + ResourceNames: []string{"foo"}, + }, + expectErr: false, + }, + } + + for name, test := range tests { + err := test.roleOptions.Complete(cmd, test.params) + if !test.expectErr && err != nil { + t.Errorf("%s: unexpected error: %v", name, err) + } + if test.expectErr && err != nil { + continue + } + if !reflect.DeepEqual(test.roleOptions, test.expected) { + t.Errorf("%s:\nexpected:\n%#v\nsaw:\n%#v", name, test.expected, test.roleOptions) + } + } +}