Merge pull request #60950 from juanvallejo/jvallejo/use-temp-kubeconfig-file-tests

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

use temp kubeconfig for fake factory

**Release note**:
```release-note
NONE
```

Fixes https://github.com/kubernetes/kubernetes/issues/60907

cc @deads2k @ixdy
This commit is contained in:
Kubernetes Submit Queue 2018-03-09 15:00:21 -08:00 committed by GitHub
commit df36379670
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 2156 additions and 1723 deletions

View File

@ -417,29 +417,33 @@ func TestAnnotateErrors(t *testing.T) {
}
for k, testCase := range testCases {
tf := cmdtesting.NewTestFactory()
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
t.Run(k, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdAnnotate(tf, buf)
cmd.SetOutput(buf)
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
for k, v := range testCase.flags {
cmd.Flags().Set(k, v)
}
options := &AnnotateOptions{}
err := options.Complete(buf, cmd, testCase.args)
if err == nil {
err = options.Validate()
}
if !testCase.errFn(err) {
t.Errorf("%s: unexpected error: %v", k, err)
continue
}
if buf.Len() > 0 {
t.Errorf("buffer should be empty: %s", string(buf.Bytes()))
}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdAnnotate(tf, buf)
cmd.SetOutput(buf)
for k, v := range testCase.flags {
cmd.Flags().Set(k, v)
}
options := &AnnotateOptions{}
err := options.Complete(buf, cmd, testCase.args)
if err == nil {
err = options.Validate()
}
if !testCase.errFn(err) {
t.Errorf("%s: unexpected error: %v", k, err)
return
}
if buf.Len() > 0 {
t.Errorf("buffer should be empty: %s", string(buf.Bytes()))
}
})
}
}
@ -447,6 +451,8 @@ func TestAnnotateObject(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -499,6 +505,8 @@ func TestAnnotateObjectFromFile(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -550,6 +558,8 @@ func TestAnnotateObjectFromFile(t *testing.T) {
func TestAnnotateLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Group: "testgroup", Version: "v1"},
NegotiatedSerializer: unstructuredSerializer,
@ -581,6 +591,8 @@ func TestAnnotateMultipleObjects(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Group: "testgroup", Version: "v1"},

File diff suppressed because it is too large Load Diff

View File

@ -139,43 +139,47 @@ func TestPodAndContainerAttach(t *testing.T) {
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
if test.obj != nil {
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, test.obj)}, nil
}
return nil, nil
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
cmd := &cobra.Command{}
options := test.p
cmdutil.AddPodRunningTimeoutFlag(cmd, test.timeout)
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
if test.obj != nil {
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, test.obj)}, nil
}
return nil, nil
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
err := options.Complete(tf, cmd, test.args)
if test.expectError && err == nil {
t.Errorf("%s: unexpected non-error", test.name)
}
if !test.expectError && err != nil {
t.Errorf("%s: unexpected error: %v", test.name, err)
}
if err != nil {
continue
}
if options.PodName != test.expectedPod {
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedPod, options.PodName)
}
if options.ContainerName != test.expectedContainer {
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedContainer, options.ContainerName)
}
cmd := &cobra.Command{}
options := test.p
cmdutil.AddPodRunningTimeoutFlag(cmd, test.timeout)
err := options.Complete(tf, cmd, test.args)
if test.expectError && err == nil {
t.Errorf("%s: unexpected non-error", test.name)
}
if !test.expectError && err != nil {
t.Errorf("%s: unexpected error: %v", test.name, err)
}
if err != nil {
return
}
if options.PodName != test.expectedPod {
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedPod, options.PodName)
}
if options.ContainerName != test.expectedContainer {
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedContainer, options.ContainerName)
}
})
}
}
@ -219,74 +223,78 @@ func TestAttach(t *testing.T) {
},
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
case p == test.fetchPodPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %s %#v\n%#v", p, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}}
bufOut := bytes.NewBuffer([]byte{})
bufErr := bytes.NewBuffer([]byte{})
bufIn := bytes.NewBuffer([]byte{})
remoteAttach := &fakeRemoteAttach{}
if test.remoteAttachErr {
remoteAttach.err = fmt.Errorf("attach error")
}
params := &AttachOptions{
StreamOptions: StreamOptions{
ContainerName: test.container,
In: bufIn,
Out: bufOut,
Err: bufErr,
},
Attach: remoteAttach,
GetPodTimeout: 1000,
}
cmd := &cobra.Command{}
cmdutil.AddPodRunningTimeoutFlag(cmd, 1000)
if err := params.Complete(tf, cmd, []string{"foo"}); err != nil {
t.Fatal(err)
}
err := params.Run()
if test.exepctedErr != "" && err.Error() != test.exepctedErr {
t.Errorf("%s: Unexpected exec error: %v", test.name, err)
continue
}
if test.exepctedErr == "" && err != nil {
t.Errorf("%s: Unexpected error: %v", test.name, err)
continue
}
if test.exepctedErr != "" {
continue
}
if remoteAttach.url.Path != test.attachPath {
t.Errorf("%s: Did not get expected path for exec request: %q %q", test.name, test.attachPath, remoteAttach.url.Path)
continue
}
if remoteAttach.method != "POST" {
t.Errorf("%s: Did not get method for attach request: %s", test.name, remoteAttach.method)
}
if remoteAttach.url.Query().Get("container") != "bar" {
t.Errorf("%s: Did not have query parameters: %s", test.name, remoteAttach.url.Query())
}
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
case p == test.fetchPodPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %s %#v\n%#v", p, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}}
bufOut := bytes.NewBuffer([]byte{})
bufErr := bytes.NewBuffer([]byte{})
bufIn := bytes.NewBuffer([]byte{})
remoteAttach := &fakeRemoteAttach{}
if test.remoteAttachErr {
remoteAttach.err = fmt.Errorf("attach error")
}
params := &AttachOptions{
StreamOptions: StreamOptions{
ContainerName: test.container,
In: bufIn,
Out: bufOut,
Err: bufErr,
},
Attach: remoteAttach,
GetPodTimeout: 1000,
}
cmd := &cobra.Command{}
cmdutil.AddPodRunningTimeoutFlag(cmd, 1000)
if err := params.Complete(tf, cmd, []string{"foo"}); err != nil {
t.Fatal(err)
}
err := params.Run()
if test.exepctedErr != "" && err.Error() != test.exepctedErr {
t.Errorf("%s: Unexpected exec error: %v", test.name, err)
return
}
if test.exepctedErr == "" && err != nil {
t.Errorf("%s: Unexpected error: %v", test.name, err)
return
}
if test.exepctedErr != "" {
return
}
if remoteAttach.url.Path != test.attachPath {
t.Errorf("%s: Did not get expected path for exec request: %q %q", test.name, test.attachPath, remoteAttach.url.Path)
return
}
if remoteAttach.method != "POST" {
t.Errorf("%s: Did not get method for attach request: %s", test.name, remoteAttach.method)
}
if remoteAttach.url.Query().Get("container") != "bar" {
t.Errorf("%s: Did not have query parameters: %s", test.name, remoteAttach.url.Query())
}
})
}
}
@ -309,62 +317,66 @@ func TestAttachWarnings(t *testing.T) {
},
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
case p == test.fetchPodPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}}
bufOut := bytes.NewBuffer([]byte{})
bufErr := bytes.NewBuffer([]byte{})
bufIn := bytes.NewBuffer([]byte{})
ex := &fakeRemoteAttach{}
params := &AttachOptions{
StreamOptions: StreamOptions{
ContainerName: test.container,
In: bufIn,
Out: bufOut,
Err: bufErr,
Stdin: test.stdin,
TTY: test.tty,
},
Attach: ex,
GetPodTimeout: 1000,
}
cmd := &cobra.Command{}
cmdutil.AddPodRunningTimeoutFlag(cmd, 1000)
if err := params.Complete(tf, cmd, []string{"foo"}); err != nil {
t.Fatal(err)
}
if err := params.Run(); err != nil {
t.Fatal(err)
}
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
if test.stdin && test.tty {
if !test.pod.Spec.Containers[0].TTY {
if !strings.Contains(bufErr.String(), test.expectedErr) {
t.Errorf("%s: Expected TTY fallback warning for attach request: %s", test.name, bufErr.String())
continue
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
case p == test.fetchPodPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}}
bufOut := bytes.NewBuffer([]byte{})
bufErr := bytes.NewBuffer([]byte{})
bufIn := bytes.NewBuffer([]byte{})
ex := &fakeRemoteAttach{}
params := &AttachOptions{
StreamOptions: StreamOptions{
ContainerName: test.container,
In: bufIn,
Out: bufOut,
Err: bufErr,
Stdin: test.stdin,
TTY: test.tty,
},
Attach: ex,
GetPodTimeout: 1000,
}
cmd := &cobra.Command{}
cmdutil.AddPodRunningTimeoutFlag(cmd, 1000)
if err := params.Complete(tf, cmd, []string{"foo"}); err != nil {
t.Fatal(err)
}
if err := params.Run(); err != nil {
t.Fatal(err)
}
if test.stdin && test.tty {
if !test.pod.Spec.Containers[0].TTY {
if !strings.Contains(bufErr.String(), test.expectedErr) {
t.Errorf("%s: Expected TTY fallback warning for attach request: %s", test.name, bufErr.String())
return
}
}
}
}
})
}
}

View File

@ -117,64 +117,68 @@ func TestRunAccessCheck(t *testing.T) {
}
for _, test := range tests {
test.o.Out = ioutil.Discard
test.o.Err = ioutil.Discard
t.Run(test.name, func(t *testing.T) {
test.o.Out = ioutil.Discard
test.o.Err = ioutil.Discard
tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Group: "", Version: "v1"},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
expectPath := "/apis/authorization.k8s.io/v1/selfsubjectaccessreviews"
if req.URL.Path != expectPath {
t.Errorf("%s: expected %v, got %v", test.name, expectPath, req.URL.Path)
return nil, nil
}
bodyBits, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Errorf("%s: %v", test.name, err)
return nil, nil
}
body := string(bodyBits)
ns := legacyscheme.Codecs
for _, expectedBody := range test.expectedBodyStrings {
if !strings.Contains(body, expectedBody) {
t.Errorf("%s expecting %s in %s", test.name, expectedBody, body)
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Group: "", Version: "v1"},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
expectPath := "/apis/authorization.k8s.io/v1/selfsubjectaccessreviews"
if req.URL.Path != expectPath {
t.Errorf("%s: expected %v, got %v", test.name, expectPath, req.URL.Path)
return nil, nil
}
}
bodyBits, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Errorf("%s: %v", test.name, err)
return nil, nil
}
body := string(bodyBits)
return &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewBufferString(
fmt.Sprintf(`{"kind":"SelfSubjectAccessReview","apiVersion":"authorization.k8s.io/v1","status":{"allowed":%v}}`, test.allowed),
)),
},
test.serverErr
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}}}
for _, expectedBody := range test.expectedBodyStrings {
if !strings.Contains(body, expectedBody) {
t.Errorf("%s expecting %s in %s", test.name, expectedBody, body)
}
}
if err := test.o.Complete(tf, test.args); err != nil {
t.Errorf("%s: %v", test.name, err)
continue
}
return &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewBufferString(
fmt.Sprintf(`{"kind":"SelfSubjectAccessReview","apiVersion":"authorization.k8s.io/v1","status":{"allowed":%v}}`, test.allowed),
)),
},
test.serverErr
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}}}
actualAllowed, err := test.o.RunAccessCheck()
switch {
case test.serverErr == nil && err == nil:
// pass
case err != nil && test.serverErr != nil && strings.Contains(err.Error(), test.serverErr.Error()):
// pass
default:
t.Errorf("%s: expected %v, got %v", test.name, test.serverErr, err)
continue
}
if actualAllowed != test.allowed {
t.Errorf("%s: expected %v, got %v", test.name, test.allowed, actualAllowed)
continue
}
if err := test.o.Complete(tf, test.args); err != nil {
t.Errorf("%s: %v", test.name, err)
return
}
actualAllowed, err := test.o.RunAccessCheck()
switch {
case test.serverErr == nil && err == nil:
// pass
case err != nil && test.serverErr != nil && strings.Contains(err.Error(), test.serverErr.Error()):
// pass
default:
t.Errorf("%s: expected %v, got %v", test.name, test.serverErr, err)
return
}
if actualAllowed != test.allowed {
t.Errorf("%s: expected %v, got %v", test.name, test.allowed, actualAllowed)
return
}
})
}
}

View File

@ -31,6 +31,8 @@ func TestSetupOutputWriterNoOp(t *testing.T) {
for _, test := range tests {
out := &bytes.Buffer{}
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
cmd := NewCmdClusterInfoDump(f, os.Stdout)
cmd.Flag("output-directory").Value.Set(test)
writer := setupOutputWriter(cmd, out, "/some/file/that/should/be/ignored")
@ -51,6 +53,8 @@ func TestSetupOutputWriterFile(t *testing.T) {
out := &bytes.Buffer{}
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
cmd := NewCmdClusterInfoDump(f, os.Stdout)
cmd.Flag("output-directory").Value.Set(dir)
writer := setupOutputWriter(cmd, out, file)

View File

@ -178,6 +178,8 @@ func stringBody(body string) io.ReadCloser {
func Example_printMultiContainersReplicationControllerWithWide() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
@ -228,6 +230,8 @@ func Example_printMultiContainersReplicationControllerWithWide() {
func Example_printReplicationController() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
@ -277,6 +281,8 @@ func Example_printReplicationController() {
func Example_printPodWithWideFormat() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
@ -315,6 +321,8 @@ func Example_printPodWithWideFormat() {
func Example_printPodWithShowLabels() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
@ -448,6 +456,8 @@ func newAllPhasePodList() *api.PodList {
func Example_printPodShowTerminated() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
@ -484,6 +494,8 @@ func Example_printPodShowTerminated() {
func Example_printPodShowAll() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
@ -507,6 +519,8 @@ func Example_printPodShowAll() {
func Example_printServiceWithLabels() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{

View File

@ -102,6 +102,8 @@ func TestConvertObject(t *testing.T) {
for _, field := range tc.fields {
t.Run(fmt.Sprintf("%s %s", tc.name, field), func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)

View File

@ -33,6 +33,8 @@ func TestCreateClusterRole(t *testing.T) {
clusterRoleName := "my-cluster-role"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Namespace = "test"
tf.Client = &fake.RESTClient{}
tf.ClientConfigVal = defaultClientConfig()
@ -148,6 +150,8 @@ func TestCreateClusterRole(t *testing.T) {
func TestClusterRoleValidate(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Namespace = "test"
tests := map[string]struct {

View File

@ -68,6 +68,8 @@ func TestCreateClusterRoleBinding(t *testing.T) {
}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
info, _ := runtime.SerializerInfoForMediaType(ns.SupportedMediaTypes(), runtime.ContentTypeJSON)

View File

@ -33,6 +33,8 @@ func TestCreateConfigMap(t *testing.T) {
configMap := &v1.ConfigMap{}
configMap.Name = "my-configmap"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs

View File

@ -75,6 +75,8 @@ func Test_generatorFromName(t *testing.T) {
func TestCreateDeployment(t *testing.T) {
depName := "jonny-dep"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
@ -104,6 +106,8 @@ func TestCreateDeployment(t *testing.T) {
func TestCreateDeploymentNoImage(t *testing.T) {
depName := "jonny-dep"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{

View File

@ -82,6 +82,8 @@ func TestCreateJobFromCronJob(t *testing.T) {
return true, expectJob, nil
})
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
buf := bytes.NewBuffer([]byte{})
cmdOptions := &CreateJobOptions{
Name: testJobName,

View File

@ -33,6 +33,8 @@ func TestCreateNamespace(t *testing.T) {
namespaceObject := &v1.Namespace{}
namespaceObject.Name = "my-namespace"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs

View File

@ -32,6 +32,8 @@ import (
func TestCreatePdb(t *testing.T) {
pdbName := "my-pdb"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{

View File

@ -32,6 +32,8 @@ import (
func TestCreatePriorityClass(t *testing.T) {
pcName := "my-pc"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{

View File

@ -33,6 +33,8 @@ func TestCreateQuota(t *testing.T) {
resourceQuotaObject := &v1.ResourceQuota{}
resourceQuotaObject.Name = "my-quota"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs

View File

@ -35,6 +35,8 @@ func TestCreateRole(t *testing.T) {
roleName := "my-role"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Namespace = "test"
tf.Client = &fake.RESTClient{}
tf.ClientConfigVal = defaultClientConfig()
@ -147,6 +149,8 @@ func TestCreateRole(t *testing.T) {
func TestValidate(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Namespace = "test"
tests := map[string]struct {
@ -346,6 +350,8 @@ func TestComplete(t *testing.T) {
roleName := "my-role"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Namespace = "test"
tf.Client = &fake.RESTClient{}
tf.ClientConfigVal = defaultClientConfig()

View File

@ -70,6 +70,8 @@ func TestCreateRoleBinding(t *testing.T) {
}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
info, _ := runtime.SerializerInfoForMediaType(ns.SupportedMediaTypes(), runtime.ContentTypeJSON)

View File

@ -38,6 +38,8 @@ func TestCreateSecretGeneric(t *testing.T) {
}
secretObject.Name = "my-secret"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs

View File

@ -33,6 +33,8 @@ func TestCreateService(t *testing.T) {
service := &v1.Service{}
service.Name = "my-service"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
negSer := legacyscheme.Codecs
@ -65,6 +67,8 @@ func TestCreateServiceNodePort(t *testing.T) {
service := &v1.Service{}
service.Name = "my-node-port-service"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
negSer := legacyscheme.Codecs
@ -97,6 +101,8 @@ func TestCreateServiceExternalName(t *testing.T) {
service := &v1.Service{}
service.Name = "my-external-name-service"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
negSer := legacyscheme.Codecs

View File

@ -33,6 +33,8 @@ func TestCreateServiceAccount(t *testing.T) {
serviceAccountObject := &v1.ServiceAccount{}
serviceAccountObject.Name = "my-service-account"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs

View File

@ -34,6 +34,8 @@ func TestExtraArgsFail(t *testing.T) {
errBuf := bytes.NewBuffer([]byte{})
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
c := NewCmdCreate(f, buf, errBuf)
options := CreateOptions{}
if options.ValidateArgs(c, []string{"rc"}) == nil {
@ -47,6 +49,8 @@ func TestCreateObject(t *testing.T) {
rc.Items[0].Name = "redis-master-controller"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -82,6 +86,8 @@ func TestCreateMultipleObject(t *testing.T) {
_, svc, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -121,6 +127,8 @@ func TestCreateDirectory(t *testing.T) {
rc.Items[0].Name = "name"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{

View File

@ -57,6 +57,8 @@ func TestDeleteObjectByTuple(t *testing.T) {
_, _, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -121,6 +123,8 @@ func TestOrphanDependentsInDeleteObject(t *testing.T) {
_, _, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
var expectedOrphanDependents *bool
@ -171,6 +175,8 @@ func TestDeleteNamedObject(t *testing.T) {
_, _, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -222,6 +228,8 @@ func TestDeleteObject(t *testing.T) {
_, _, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -281,6 +289,8 @@ func TestDeleteObjectGraceZero(t *testing.T) {
objectDeletionWaitInterval = time.Millisecond
count := 0
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -331,6 +341,8 @@ func TestDeleteObjectGraceZero(t *testing.T) {
func TestDeleteObjectNotFound(t *testing.T) {
initTestErrorHandler(t)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
@ -367,6 +379,8 @@ func TestDeleteObjectNotFound(t *testing.T) {
func TestDeleteObjectIgnoreNotFound(t *testing.T) {
initTestErrorHandler(t)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
@ -402,6 +416,8 @@ func TestDeleteAllNotFound(t *testing.T) {
notFoundError := &errors.NewNotFound(api.Resource("services"), "foo").ErrStatus
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -447,6 +463,8 @@ func TestDeleteAllIgnoreNotFound(t *testing.T) {
_, svc, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
// Add an item to the list which will result in a 404 on delete
@ -488,6 +506,8 @@ func TestDeleteMultipleObject(t *testing.T) {
_, svc, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -524,6 +544,8 @@ func TestDeleteMultipleObjectContinueOnMissing(t *testing.T) {
_, svc, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -569,6 +591,8 @@ func TestDeleteMultipleResourcesWithTheSameName(t *testing.T) {
initTestErrorHandler(t)
_, svc, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -608,6 +632,8 @@ func TestDeleteDirectory(t *testing.T) {
_, _, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -641,6 +667,8 @@ func TestDeleteMultipleSelector(t *testing.T) {
pods, svc, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -706,26 +734,30 @@ func TestResourceErrors(t *testing.T) {
}
for k, testCase := range testCases {
tf := cmdtesting.NewTestFactory()
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
t.Run(k, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
options := &DeleteOptions{
FilenameOptions: resource.FilenameOptions{},
GracePeriod: -1,
Cascade: false,
Output: "name",
}
err := options.Complete(tf, buf, errBuf, testCase.args, fakecmd)
if !testCase.errFn(err) {
t.Errorf("%s: unexpected error: %v", k, err)
continue
}
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
if buf.Len() > 0 {
t.Errorf("buffer should be empty: %s", string(buf.Bytes()))
}
options := &DeleteOptions{
FilenameOptions: resource.FilenameOptions{},
GracePeriod: -1,
Cascade: false,
Output: "name",
}
err := options.Complete(tf, buf, errBuf, testCase.args, fakecmd)
if !testCase.errFn(err) {
t.Errorf("%s: unexpected error: %v", k, err)
return
}
if buf.Len() > 0 {
t.Errorf("buffer should be empty: %s", string(buf.Bytes()))
}
})
}
}

View File

@ -33,6 +33,7 @@ import (
func TestDescribeUnknownSchemaObject(t *testing.T) {
d := &testDescriber{Output: "test output"}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
_, _, codec := cmdtesting.NewExternalScheme()
tf.DescriberVal = d
tf.UnstructuredClient = &fake.RESTClient{
@ -58,6 +59,7 @@ func TestDescribeUnknownSchemaObject(t *testing.T) {
func TestDescribeUnknownNamespacedSchemaObject(t *testing.T) {
d := &testDescriber{Output: "test output"}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
_, _, codec := cmdtesting.NewExternalScheme()
tf.DescriberVal = d
@ -83,6 +85,7 @@ func TestDescribeUnknownNamespacedSchemaObject(t *testing.T) {
func TestDescribeObject(t *testing.T) {
_, _, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
d := &testDescriber{Output: "test output"}
@ -118,6 +121,7 @@ func TestDescribeObject(t *testing.T) {
func TestDescribeListObjects(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
d := &testDescriber{Output: "test output"}
@ -140,6 +144,7 @@ func TestDescribeListObjects(t *testing.T) {
func TestDescribeObjectShowEvents(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
d := &testDescriber{Output: "test output"}
@ -163,6 +168,7 @@ func TestDescribeObjectShowEvents(t *testing.T) {
func TestDescribeObjectSkipEvents(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
d := &testDescriber{Output: "test output"}
@ -185,6 +191,7 @@ func TestDescribeObjectSkipEvents(t *testing.T) {
func TestDescribeHelpMessage(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
buf := bytes.NewBuffer([]byte{})
buferr := bytes.NewBuffer([]byte{})

View File

@ -150,86 +150,90 @@ func TestCordon(t *testing.T) {
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.description, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
new_node := &corev1.Node{}
updated := false
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
m := &MyReq{req}
switch {
case m.isFor("GET", "/nodes/node"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, test.node)}, nil
case m.isFor("GET", "/nodes/bar"):
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: stringBody("nope")}, nil
case m.isFor("PATCH", "/nodes/node"):
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
defer req.Body.Close()
oldJSON, err := runtime.Encode(codec, node)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
appliedPatch, err := strategicpatch.StrategicMergePatch(oldJSON, data, &corev1.Node{})
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if err := runtime.DecodeInto(codec, appliedPatch, new_node); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if !reflect.DeepEqual(test.expected.Spec, new_node.Spec) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, test.expected.Spec.Unschedulable, new_node.Spec.Unschedulable)
}
updated = true
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, new_node)}, nil
default:
t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req)
return nil, nil
}
}),
}
tf.ClientConfigVal = defaultClientConfig()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
buf := bytes.NewBuffer([]byte{})
cmd := test.cmd(tf, buf)
new_node := &corev1.Node{}
updated := false
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
m := &MyReq{req}
switch {
case m.isFor("GET", "/nodes/node"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, test.node)}, nil
case m.isFor("GET", "/nodes/bar"):
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: stringBody("nope")}, nil
case m.isFor("PATCH", "/nodes/node"):
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
defer req.Body.Close()
oldJSON, err := runtime.Encode(codec, node)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
appliedPatch, err := strategicpatch.StrategicMergePatch(oldJSON, data, &corev1.Node{})
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if err := runtime.DecodeInto(codec, appliedPatch, new_node); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if !reflect.DeepEqual(test.expected.Spec, new_node.Spec) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, test.expected.Spec.Unschedulable, new_node.Spec.Unschedulable)
}
updated = true
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, new_node)}, nil
default:
t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req)
return nil, nil
}
}),
}
tf.ClientConfigVal = defaultClientConfig()
saw_fatal := false
func() {
defer func() {
// Recover from the panic below.
_ = recover()
// Restore cmdutil behavior
cmdutil.DefaultBehaviorOnFatal()
buf := bytes.NewBuffer([]byte{})
cmd := test.cmd(tf, buf)
saw_fatal := false
func() {
defer func() {
// Recover from the panic below.
_ = recover()
// Restore cmdutil behavior
cmdutil.DefaultBehaviorOnFatal()
}()
cmdutil.BehaviorOnFatal(func(e string, code int) {
saw_fatal = true
panic(e)
})
cmd.SetArgs([]string{test.arg})
cmd.Execute()
}()
cmdutil.BehaviorOnFatal(func(e string, code int) {
saw_fatal = true
panic(e)
})
cmd.SetArgs([]string{test.arg})
cmd.Execute()
}()
if test.expectFatal {
if !saw_fatal {
t.Fatalf("%s: unexpected non-error", test.description)
if test.expectFatal {
if !saw_fatal {
t.Fatalf("%s: unexpected non-error", test.description)
}
if updated {
t.Fatalf("%s: unexpected update", test.description)
}
}
if updated {
t.Fatalf("%s: unexpected update", test.description)
}
}
if !test.expectFatal && saw_fatal {
t.Fatalf("%s: unexpected error", test.description)
}
if !reflect.DeepEqual(test.expected.Spec, test.node.Spec) && !updated {
t.Fatalf("%s: node never updated", test.description)
}
if !test.expectFatal && saw_fatal {
t.Fatalf("%s: unexpected error", test.description)
}
if !reflect.DeepEqual(test.expected.Spec, test.node.Spec) && !updated {
t.Fatalf("%s: node never updated", test.description)
}
})
}
}
@ -597,164 +601,168 @@ func TestDrain(t *testing.T) {
currMethod = DeleteMethod
}
for _, test := range tests {
new_node := &corev1.Node{}
deleted := false
evicted := false
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.description, func(t *testing.T) {
new_node := &corev1.Node{}
deleted := false
evicted := false
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
m := &MyReq{req}
switch {
case req.Method == "GET" && req.URL.Path == "/api":
apiVersions := metav1.APIVersions{
Versions: []string{"v1"},
}
return genResponseWithJsonEncodedBody(apiVersions)
case req.Method == "GET" && req.URL.Path == "/apis":
groupList := metav1.APIGroupList{
Groups: []metav1.APIGroup{
{
Name: "policy",
PreferredVersion: metav1.GroupVersionForDiscovery{
GroupVersion: "policy/v1beta1",
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
m := &MyReq{req}
switch {
case req.Method == "GET" && req.URL.Path == "/api":
apiVersions := metav1.APIVersions{
Versions: []string{"v1"},
}
return genResponseWithJsonEncodedBody(apiVersions)
case req.Method == "GET" && req.URL.Path == "/apis":
groupList := metav1.APIGroupList{
Groups: []metav1.APIGroup{
{
Name: "policy",
PreferredVersion: metav1.GroupVersionForDiscovery{
GroupVersion: "policy/v1beta1",
},
},
},
},
}
return genResponseWithJsonEncodedBody(groupList)
case req.Method == "GET" && req.URL.Path == "/api/v1":
resourceList := metav1.APIResourceList{
GroupVersion: "v1",
}
if testEviction {
resourceList.APIResources = []metav1.APIResource{
{
Name: EvictionSubresource,
Kind: EvictionKind,
},
}
return genResponseWithJsonEncodedBody(groupList)
case req.Method == "GET" && req.URL.Path == "/api/v1":
resourceList := metav1.APIResourceList{
GroupVersion: "v1",
}
if testEviction {
resourceList.APIResources = []metav1.APIResource{
{
Name: EvictionSubresource,
Kind: EvictionKind,
},
}
}
return genResponseWithJsonEncodedBody(resourceList)
case m.isFor("GET", "/nodes/node"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, test.node)}, nil
case m.isFor("GET", "/namespaces/default/replicationcontrollers/rc"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &test.rcs[0])}, nil
case m.isFor("GET", "/namespaces/default/daemonsets/ds"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(testapi.Extensions.Codec(), &ds)}, nil
case m.isFor("GET", "/namespaces/default/daemonsets/missing-ds"):
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: objBody(testapi.Extensions.Codec(), &extensions.DaemonSet{})}, nil
case m.isFor("GET", "/namespaces/default/jobs/job"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(testapi.Batch.Codec(), &job)}, nil
case m.isFor("GET", "/namespaces/default/replicasets/rs"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(testapi.Extensions.Codec(), &test.replicaSets[0])}, nil
case m.isFor("GET", "/namespaces/default/pods/bar"):
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: objBody(codec, &corev1.Pod{})}, nil
case m.isFor("GET", "/pods"):
values, err := url.ParseQuery(req.URL.RawQuery)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
get_params := make(url.Values)
get_params["fieldSelector"] = []string{"spec.nodeName=node"}
if !reflect.DeepEqual(get_params, values) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, get_params, values)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &corev1.PodList{Items: test.pods})}, nil
case m.isFor("GET", "/replicationcontrollers"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &api.ReplicationControllerList{Items: test.rcs})}, nil
case m.isFor("PATCH", "/nodes/node"):
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
defer req.Body.Close()
oldJSON, err := runtime.Encode(codec, node)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
appliedPatch, err := strategicpatch.StrategicMergePatch(oldJSON, data, &corev1.Node{})
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if err := runtime.DecodeInto(codec, appliedPatch, new_node); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if !reflect.DeepEqual(test.expected.Spec, new_node.Spec) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, test.expected.Spec, new_node.Spec)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, new_node)}, nil
case m.isFor("DELETE", "/namespaces/default/pods/bar"):
deleted = true
return &http.Response{StatusCode: 204, Header: defaultHeader(), Body: objBody(codec, &test.pods[0])}, nil
case m.isFor("POST", "/namespaces/default/pods/bar/eviction"):
evicted = true
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: policyObjBody(&policyv1beta1.Eviction{})}, nil
default:
t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req)
return nil, nil
}
return genResponseWithJsonEncodedBody(resourceList)
case m.isFor("GET", "/nodes/node"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, test.node)}, nil
case m.isFor("GET", "/namespaces/default/replicationcontrollers/rc"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &test.rcs[0])}, nil
case m.isFor("GET", "/namespaces/default/daemonsets/ds"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(testapi.Extensions.Codec(), &ds)}, nil
case m.isFor("GET", "/namespaces/default/daemonsets/missing-ds"):
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: objBody(testapi.Extensions.Codec(), &extensions.DaemonSet{})}, nil
case m.isFor("GET", "/namespaces/default/jobs/job"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(testapi.Batch.Codec(), &job)}, nil
case m.isFor("GET", "/namespaces/default/replicasets/rs"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(testapi.Extensions.Codec(), &test.replicaSets[0])}, nil
case m.isFor("GET", "/namespaces/default/pods/bar"):
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: objBody(codec, &corev1.Pod{})}, nil
case m.isFor("GET", "/pods"):
values, err := url.ParseQuery(req.URL.RawQuery)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
get_params := make(url.Values)
get_params["fieldSelector"] = []string{"spec.nodeName=node"}
if !reflect.DeepEqual(get_params, values) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, get_params, values)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &corev1.PodList{Items: test.pods})}, nil
case m.isFor("GET", "/replicationcontrollers"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &api.ReplicationControllerList{Items: test.rcs})}, nil
case m.isFor("PATCH", "/nodes/node"):
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
defer req.Body.Close()
oldJSON, err := runtime.Encode(codec, node)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
appliedPatch, err := strategicpatch.StrategicMergePatch(oldJSON, data, &corev1.Node{})
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if err := runtime.DecodeInto(codec, appliedPatch, new_node); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if !reflect.DeepEqual(test.expected.Spec, new_node.Spec) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, test.expected.Spec, new_node.Spec)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, new_node)}, nil
case m.isFor("DELETE", "/namespaces/default/pods/bar"):
deleted = true
return &http.Response{StatusCode: 204, Header: defaultHeader(), Body: objBody(codec, &test.pods[0])}, nil
case m.isFor("POST", "/namespaces/default/pods/bar/eviction"):
evicted = true
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: policyObjBody(&policyv1beta1.Eviction{})}, nil
default:
t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req)
return nil, nil
}
}),
}
tf.ClientConfigVal = defaultClientConfig()
}),
}
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdDrain(tf, buf, errBuf)
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdDrain(tf, buf, errBuf)
saw_fatal := false
fatal_msg := ""
func() {
defer func() {
// Recover from the panic below.
_ = recover()
// Restore cmdutil behavior
cmdutil.DefaultBehaviorOnFatal()
saw_fatal := false
fatal_msg := ""
func() {
defer func() {
// Recover from the panic below.
_ = recover()
// Restore cmdutil behavior
cmdutil.DefaultBehaviorOnFatal()
}()
cmdutil.BehaviorOnFatal(func(e string, code int) { saw_fatal = true; fatal_msg = e; panic(e) })
cmd.SetArgs(test.args)
cmd.Execute()
}()
cmdutil.BehaviorOnFatal(func(e string, code int) { saw_fatal = true; fatal_msg = e; panic(e) })
cmd.SetArgs(test.args)
cmd.Execute()
}()
if test.expectFatal {
if !saw_fatal {
t.Fatalf("%s: unexpected non-error when using %s", test.description, currMethod)
}
} else {
if saw_fatal {
t.Fatalf("%s: unexpected error when using %s: %s", test.description, currMethod, fatal_msg)
if test.expectFatal {
if !saw_fatal {
t.Fatalf("%s: unexpected non-error when using %s", test.description, currMethod)
}
} else {
if saw_fatal {
t.Fatalf("%s: unexpected error when using %s: %s", test.description, currMethod, fatal_msg)
}
}
if test.expectDelete {
// Test Delete
if !testEviction && !deleted {
t.Fatalf("%s: pod never deleted", test.description)
}
// Test Eviction
if testEviction && !evicted {
t.Fatalf("%s: pod never evicted", test.description)
}
}
if !test.expectDelete {
if deleted {
t.Fatalf("%s: unexpected delete when using %s", test.description, currMethod)
}
}
if len(test.expectWarning) > 0 {
if len(errBuf.String()) == 0 {
t.Fatalf("%s: expected warning, but found no stderr output", test.description)
}
}
if errBuf.String() != test.expectWarning {
t.Fatalf("%s: actual warning message did not match expected warning message.\n Expecting: %s\n Got: %s", test.description, test.expectWarning, errBuf.String())
if test.expectDelete {
// Test Delete
if !testEviction && !deleted {
t.Fatalf("%s: pod never deleted", test.description)
}
// Test Eviction
if testEviction && !evicted {
t.Fatalf("%s: pod never evicted", test.description)
}
}
}
if !test.expectDelete {
if deleted {
t.Fatalf("%s: unexpected delete when using %s", test.description, currMethod)
}
}
if len(test.expectWarning) > 0 {
if len(errBuf.String()) == 0 {
t.Fatalf("%s: expected warning, but found no stderr output", test.description)
}
if errBuf.String() != test.expectWarning {
t.Fatalf("%s: actual warning message did not match expected warning message.\n Expecting: %s\n Got: %s", test.description, test.expectWarning, errBuf.String())
}
}
})
}
}
}
@ -824,31 +832,35 @@ func TestDeletePods(t *testing.T) {
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
o := DrainOptions{Factory: tf}
o.mapper, _ = tf.Object()
o.Out = os.Stdout
_, pods := createPods(false)
pendingPods, err := o.waitForDelete(pods, test.interval, test.timeout, false, test.getPodFn)
t.Run(test.description, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
if test.expectError {
if err == nil {
t.Fatalf("%s: unexpected non-error", test.description)
} else if test.expectedError != nil {
if *test.expectedError != err {
t.Fatalf("%s: the error does not match expected error", test.description)
o := DrainOptions{Factory: tf}
o.mapper, _ = tf.Object()
o.Out = os.Stdout
_, pods := createPods(false)
pendingPods, err := o.waitForDelete(pods, test.interval, test.timeout, false, test.getPodFn)
if test.expectError {
if err == nil {
t.Fatalf("%s: unexpected non-error", test.description)
} else if test.expectedError != nil {
if *test.expectedError != err {
t.Fatalf("%s: the error does not match expected error", test.description)
}
}
}
}
if !test.expectError && err != nil {
t.Fatalf("%s: unexpected error", test.description)
}
if test.expectPendingPods && len(pendingPods) == 0 {
t.Fatalf("%s: unexpected empty pods", test.description)
}
if !test.expectPendingPods && len(pendingPods) > 0 {
t.Fatalf("%s: unexpected pending pods", test.description)
}
if !test.expectError && err != nil {
t.Fatalf("%s: unexpected error", test.description)
}
if test.expectPendingPods && len(pendingPods) == 0 {
t.Fatalf("%s: unexpected empty pods", test.description)
}
if !test.expectPendingPods && len(pendingPods) > 0 {
t.Fatalf("%s: unexpected pending pods", test.description)
}
})
}
}

View File

@ -207,6 +207,8 @@ func TestEdit(t *testing.T) {
}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClientForMappingFunc = func(mapping *meta.RESTMapping) (resource.RESTClient, error) {
versionedAPIPath := ""
if mapping.GroupVersionKind.Group == "" {

View File

@ -130,38 +130,42 @@ func TestPodAndContainer(t *testing.T) {
},
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { return nil, nil }),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
ns := legacyscheme.Codecs
cmd := &cobra.Command{}
options := test.p
options.Err = bytes.NewBuffer([]byte{})
err := options.Complete(tf, cmd, test.args, test.argsLenAtDash)
if test.expectError && err == nil {
t.Errorf("%s: unexpected non-error", test.name)
}
if !test.expectError && err != nil {
t.Errorf("%s: unexpected error: %v", test.name, err)
}
if err != nil {
continue
}
if options.PodName != test.expectedPod {
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedPod, options.PodName)
}
if options.ContainerName != test.expectedContainer {
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedContainer, options.ContainerName)
}
if !reflect.DeepEqual(test.expectedArgs, options.Command) {
t.Errorf("%s: expected: %v, got %v", test.name, test.expectedArgs, options.Command)
}
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { return nil, nil }),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
cmd := &cobra.Command{}
options := test.p
options.Err = bytes.NewBuffer([]byte{})
err := options.Complete(tf, cmd, test.args, test.argsLenAtDash)
if test.expectError && err == nil {
t.Errorf("%s: unexpected non-error", test.name)
}
if !test.expectError && err != nil {
t.Errorf("%s: unexpected error: %v", test.name, err)
}
if err != nil {
return
}
if options.PodName != test.expectedPod {
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedPod, options.PodName)
}
if options.ContainerName != test.expectedContainer {
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedContainer, options.ContainerName)
}
if !reflect.DeepEqual(test.expectedArgs, options.Command) {
t.Errorf("%s: expected: %v, got %v", test.name, test.expectedArgs, options.Command)
}
})
}
}
@ -187,67 +191,71 @@ func TestExec(t *testing.T) {
},
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
bufOut := bytes.NewBuffer([]byte{})
bufErr := bytes.NewBuffer([]byte{})
bufIn := bytes.NewBuffer([]byte{})
ex := &fakeRemoteExecutor{}
if test.execErr {
ex.execErr = fmt.Errorf("exec error")
}
params := &ExecOptions{
StreamOptions: StreamOptions{
PodName: "foo",
ContainerName: "bar",
In: bufIn,
Out: bufOut,
Err: bufErr,
},
Executor: ex,
}
cmd := &cobra.Command{}
args := []string{"test", "command"}
if err := params.Complete(tf, cmd, args, -1); err != nil {
t.Fatal(err)
}
err := params.Run()
if test.execErr && err != ex.execErr {
t.Errorf("%s: Unexpected exec error: %v", test.name, err)
continue
}
if !test.execErr && err != nil {
t.Errorf("%s: Unexpected error: %v", test.name, err)
continue
}
if test.execErr {
continue
}
if ex.url.Path != test.execPath {
t.Errorf("%s: Did not get expected path for exec request", test.name)
continue
}
if ex.method != "POST" {
t.Errorf("%s: Did not get method for exec request: %s", test.name, ex.method)
}
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
bufOut := bytes.NewBuffer([]byte{})
bufErr := bytes.NewBuffer([]byte{})
bufIn := bytes.NewBuffer([]byte{})
ex := &fakeRemoteExecutor{}
if test.execErr {
ex.execErr = fmt.Errorf("exec error")
}
params := &ExecOptions{
StreamOptions: StreamOptions{
PodName: "foo",
ContainerName: "bar",
In: bufIn,
Out: bufOut,
Err: bufErr,
},
Executor: ex,
}
cmd := &cobra.Command{}
args := []string{"test", "command"}
if err := params.Complete(tf, cmd, args, -1); err != nil {
t.Fatal(err)
}
err := params.Run()
if test.execErr && err != ex.execErr {
t.Errorf("%s: Unexpected exec error: %v", test.name, err)
return
}
if !test.execErr && err != nil {
t.Errorf("%s: Unexpected error: %v", test.name, err)
return
}
if test.execErr {
return
}
if ex.url.Path != test.execPath {
t.Errorf("%s: Did not get expected path for exec request", test.name)
return
}
if ex.method != "POST" {
t.Errorf("%s: Did not get method for exec request: %s", test.name, ex.method)
}
})
}
}

View File

@ -466,42 +466,46 @@ func TestRunExposeService(t *testing.T) {
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.calls[m] && m == "GET":
return &http.Response{StatusCode: test.status, Header: defaultHeader(), Body: objBody(codec, test.input)}, nil
case p == test.calls[m] && m == "POST":
return &http.Response{StatusCode: test.status, Header: defaultHeader(), Body: objBody(codec, test.output)}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.Namespace = test.ns
buf := bytes.NewBuffer([]byte{})
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
cmd := NewCmdExposeService(tf, buf)
cmd.SetOutput(buf)
for flag, value := range test.flags {
cmd.Flags().Set(flag, value)
}
cmd.Run(cmd, test.args)
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.calls[m] && m == "GET":
return &http.Response{StatusCode: test.status, Header: defaultHeader(), Body: objBody(codec, test.input)}, nil
case p == test.calls[m] && m == "POST":
return &http.Response{StatusCode: test.status, Header: defaultHeader(), Body: objBody(codec, test.output)}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.Namespace = test.ns
buf := bytes.NewBuffer([]byte{})
out := buf.String()
if _, ok := test.flags["dry-run"]; ok {
test.expected = fmt.Sprintf("service %q exposed (dry run)", test.flags["name"])
}
cmd := NewCmdExposeService(tf, buf)
cmd.SetOutput(buf)
for flag, value := range test.flags {
cmd.Flags().Set(flag, value)
}
cmd.Run(cmd, test.args)
if !strings.Contains(out, test.expected) {
t.Errorf("%s: Unexpected output! Expected\n%s\ngot\n%s", test.name, test.expected, out)
}
out := buf.String()
if _, ok := test.flags["dry-run"]; ok {
test.expected = fmt.Sprintf("service %q exposed (dry run)", test.flags["name"])
}
if !strings.Contains(out, test.expected) {
t.Errorf("%s: Unexpected output! Expected\n%s\ngot\n%s", test.name, test.expected, out)
}
})
}
}

View File

@ -321,38 +321,44 @@ func TestLabelErrors(t *testing.T) {
}
for k, testCase := range testCases {
tf := cmdtesting.NewTestFactory()
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
t.Run(k, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdLabel(tf, buf)
cmd.SetOutput(buf)
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
for k, v := range testCase.flags {
cmd.Flags().Set(k, v)
}
opts := LabelOptions{}
err := opts.Complete(buf, cmd, testCase.args)
if err == nil {
err = opts.Validate()
}
if err == nil {
err = opts.RunLabel(tf, cmd)
}
if !testCase.errFn(err) {
t.Errorf("%s: unexpected error: %v", k, err)
continue
}
if buf.Len() > 0 {
t.Errorf("buffer should be empty: %s", string(buf.Bytes()))
}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdLabel(tf, buf)
cmd.SetOutput(buf)
for k, v := range testCase.flags {
cmd.Flags().Set(k, v)
}
opts := LabelOptions{}
err := opts.Complete(buf, cmd, testCase.args)
if err == nil {
err = opts.Validate()
}
if err == nil {
err = opts.RunLabel(tf, cmd)
}
if !testCase.errFn(err) {
t.Errorf("%s: unexpected error: %v", k, err)
return
}
if buf.Len() > 0 {
t.Errorf("buffer should be empty: %s", string(buf.Bytes()))
}
})
}
}
func TestLabelForResourceFromFile(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -405,6 +411,8 @@ func TestLabelForResourceFromFile(t *testing.T) {
func TestLabelLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
@ -438,6 +446,8 @@ func TestLabelLocal(t *testing.T) {
func TestLabelMultipleObjects(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{

View File

@ -48,39 +48,43 @@ func TestLog(t *testing.T) {
},
}
for _, test := range tests {
logContent := "test log content"
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.name, func(t *testing.T) {
logContent := "test log content"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
case p == test.logPath && m == "GET":
body := ioutil.NopCloser(bytes.NewBufferString(logContent))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %#v\n%#v", test.name, req.URL, req)
return nil, nil
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
cmd := NewCmdLogs(tf, buf, buf)
cmd.Flags().Set("namespace", "test")
cmd.Run(cmd, []string{"foo"})
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
case p == test.logPath && m == "GET":
body := ioutil.NopCloser(bytes.NewBufferString(logContent))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %#v\n%#v", test.name, req.URL, req)
return nil, nil
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
if buf.String() != logContent {
t.Errorf("%s: did not get expected log content. Got: %s", test.name, buf.String())
}
cmd := NewCmdLogs(tf, buf, buf)
cmd.Flags().Set("namespace", "test")
cmd.Run(cmd, []string{"foo"})
if buf.String() != logContent {
t.Errorf("%s: did not get expected log content. Got: %s", test.name, buf.String())
}
})
}
}
@ -101,6 +105,7 @@ func testPod() *api.Pod {
func TestValidateLogFlags(t *testing.T) {
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
tests := []struct {
name string
@ -152,6 +157,7 @@ func TestValidateLogFlags(t *testing.T) {
func TestLogComplete(t *testing.T) {
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
tests := []struct {
name string

View File

@ -32,6 +32,8 @@ func TestPatchObject(t *testing.T) {
_, svc, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -72,6 +74,8 @@ func TestPatchObjectFromFile(t *testing.T) {
_, svc, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -108,6 +112,8 @@ func TestPatchNoop(t *testing.T) {
patchObject := &svc.Items[0]
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -154,6 +160,8 @@ func TestPatchObjectFromFileOutput(t *testing.T) {
svcCopy.Labels["post-patch"] = "post-patch-value"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{

View File

@ -80,34 +80,38 @@ func TestPluginCmd(t *testing.T) {
}
for _, test := range tests {
inBuf := bytes.NewBuffer([]byte{})
outBuf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
t.Run(test.name, func(t *testing.T) {
inBuf := bytes.NewBuffer([]byte{})
outBuf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmdutil.BehaviorOnFatal(func(str string, code int) {
errBuf.Write([]byte(str))
})
cmdutil.BehaviorOnFatal(func(str string, code int) {
errBuf.Write([]byte(str))
})
runner := &mockPluginRunner{
success: test.expectedSuccess,
}
f := cmdtesting.NewTestFactory()
cmd := NewCmdForPlugin(f, test.plugin, runner, inBuf, outBuf, errBuf)
if cmd == nil {
if !test.expectedNilCmd {
t.Fatalf("%s: command was unexpectedly not registered", test.name)
runner := &mockPluginRunner{
success: test.expectedSuccess,
}
continue
}
cmd.Run(cmd, []string{})
if test.expectedSuccess && outBuf.String() != fmt.Sprintf("ok: %s", test.plugin.Name) {
t.Errorf("%s: unexpected output: %q", test.name, outBuf.String())
}
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
if !test.expectedSuccess && errBuf.String() != fmt.Sprintf("error: oops %s", test.plugin.Name) {
t.Errorf("%s: unexpected err output: %q", test.name, errBuf.String())
}
cmd := NewCmdForPlugin(f, test.plugin, runner, inBuf, outBuf, errBuf)
if cmd == nil {
if !test.expectedNilCmd {
t.Fatalf("%s: command was unexpectedly not registered", test.name)
}
return
}
cmd.Run(cmd, []string{})
if test.expectedSuccess && outBuf.String() != fmt.Sprintf("ok: %s", test.plugin.Name) {
t.Errorf("%s: unexpected output: %q", test.name, outBuf.String())
}
if !test.expectedSuccess && errBuf.String() != fmt.Sprintf("error: oops %s", test.plugin.Name) {
t.Errorf("%s: unexpected err output: %q", test.name, errBuf.String())
}
})
}
}

View File

@ -71,68 +71,72 @@ func testPortForward(t *testing.T, flags map[string]string, args []string) {
},
}
for _, test := range tests {
var err error
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.name, func(t *testing.T) {
var err error
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
VersionedAPIPath: "/api/v1",
GroupVersion: schema.GroupVersion{Group: ""},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %#v\n%#v", test.name, req.URL, req)
return nil, nil
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
VersionedAPIPath: "/api/v1",
GroupVersion: schema.GroupVersion{Group: ""},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %#v\n%#v", test.name, req.URL, req)
return nil, nil
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
ff := &fakePortForwarder{}
if test.pfErr {
ff.pfErr = fmt.Errorf("pf error")
}
opts := &PortForwardOptions{}
cmd := NewCmdPortForward(tf, os.Stdout, os.Stderr)
cmd.Run = func(cmd *cobra.Command, args []string) {
if err = opts.Complete(tf, cmd, args); err != nil {
return
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
ff := &fakePortForwarder{}
if test.pfErr {
ff.pfErr = fmt.Errorf("pf error")
}
opts.PortForwarder = ff
if err = opts.Validate(); err != nil {
return
}
err = opts.RunPortForward()
}
opts := &PortForwardOptions{}
cmd := NewCmdPortForward(tf, os.Stdout, os.Stderr)
cmd.Run = func(cmd *cobra.Command, args []string) {
if err = opts.Complete(tf, cmd, args); err != nil {
for name, value := range flags {
cmd.Flags().Set(name, value)
}
cmd.Run(cmd, args)
if test.pfErr && err != ff.pfErr {
t.Errorf("%s: Unexpected port-forward error: %v", test.name, err)
}
if !test.pfErr && err != nil {
t.Errorf("%s: Unexpected error: %v", test.name, err)
}
if test.pfErr {
return
}
opts.PortForwarder = ff
if err = opts.Validate(); err != nil {
return
if ff.url == nil || ff.url.Path != test.pfPath {
t.Errorf("%s: Did not get expected path for portforward request", test.name)
}
err = opts.RunPortForward()
}
for name, value := range flags {
cmd.Flags().Set(name, value)
}
cmd.Run(cmd, args)
if test.pfErr && err != ff.pfErr {
t.Errorf("%s: Unexpected port-forward error: %v", test.name, err)
}
if !test.pfErr && err != nil {
t.Errorf("%s: Unexpected error: %v", test.name, err)
}
if test.pfErr {
continue
}
if ff.url.Path != test.pfPath {
t.Errorf("%s: Did not get expected path for portforward request", test.name)
}
if ff.method != "POST" {
t.Errorf("%s: Did not get method for attach request: %s", test.name, ff.method)
}
if ff.method != "POST" {
t.Errorf("%s: Did not get method for attach request: %s", test.name, ff.method)
}
})
}
}

View File

@ -33,6 +33,7 @@ func TestReplaceObject(t *testing.T) {
_, _, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
deleted := false
@ -89,6 +90,7 @@ func TestReplaceMultipleObject(t *testing.T) {
_, svc, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
redisMasterDeleted := false
@ -159,6 +161,7 @@ func TestReplaceDirectory(t *testing.T) {
_, _, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
created := map[string]bool{}
@ -216,6 +219,7 @@ func TestForceReplaceObjectNotFound(t *testing.T) {
_, _, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{

View File

@ -198,6 +198,7 @@ func testComponentStatusData() *api.ComponentStatusList {
func TestGetUnknownSchemaObject(t *testing.T) {
t.Skip("This test is completely broken. The first thing it does is add the object to the scheme!")
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
_, _, codec := cmdtesting.NewExternalScheme()
tf.OpenAPISchemaFunc = openapitesting.CreateOpenAPISchemaFunc(openapiSchemaPath)
@ -272,6 +273,7 @@ func TestGetUnknownSchemaObject(t *testing.T) {
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
func TestGetSchemaObject(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := testapi.Default.Codec()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
@ -294,6 +296,7 @@ func TestGetObjectsWithOpenAPIOutputFormatPresent(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
// overide the openAPISchema function to return custom output
@ -351,6 +354,7 @@ func TestGetObjects(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -417,6 +421,8 @@ func TestGetObjectsFiltered(t *testing.T) {
for i, test := range testCases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -458,6 +464,7 @@ func TestGetObjectIgnoreNotFound(t *testing.T) {
}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -511,6 +518,7 @@ func TestGetSortedObjects(t *testing.T) {
}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -544,6 +552,7 @@ func TestGetObjectsIdentifiedByFile(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -571,6 +580,7 @@ func TestGetListObjects(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -598,6 +608,7 @@ func TestGetAllListObjects(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -626,6 +637,7 @@ func TestGetListComponentStatus(t *testing.T) {
statuses := testComponentStatusData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -667,6 +679,7 @@ func TestGetMixedGenericObjects(t *testing.T) {
}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -717,6 +730,7 @@ func TestGetMultipleTypeObjects(t *testing.T) {
pods, svc, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -756,6 +770,7 @@ func TestGetMultipleTypeObjectsAsList(t *testing.T) {
pods, svc, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -858,6 +873,7 @@ func TestGetMultipleTypeObjectsWithLabelSelector(t *testing.T) {
pods, svc, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -902,6 +918,7 @@ func TestGetMultipleTypeObjectsWithFieldSelector(t *testing.T) {
pods, svc, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -954,6 +971,7 @@ func TestGetMultipleTypeObjectsWithDirectReference(t *testing.T) {
}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -993,6 +1011,7 @@ func TestGetByFormatForcesFlag(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -1089,6 +1108,7 @@ func TestWatchLabelSelector(t *testing.T) {
pods, events := watchTestData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
podList := &api.PodList{
@ -1141,6 +1161,7 @@ func TestWatchFieldSelector(t *testing.T) {
pods, events := watchTestData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
podList := &api.PodList{
@ -1193,6 +1214,7 @@ func TestWatchResource(t *testing.T) {
pods, events := watchTestData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -1237,6 +1259,7 @@ func TestWatchResourceIdentifiedByFile(t *testing.T) {
pods, events := watchTestData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -1282,6 +1305,7 @@ func TestWatchOnlyResource(t *testing.T) {
pods, events := watchTestData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
@ -1325,6 +1349,7 @@ func TestWatchOnlyList(t *testing.T) {
pods, events := watchTestData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
podList := &api.PodList{

View File

@ -25,6 +25,7 @@ import (
func TestValidateArgs(t *testing.T) {
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
tests := []struct {
testName string

View File

@ -168,35 +168,39 @@ func TestRunArgsFollowDashRules(t *testing.T) {
},
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
if req.URL.Path == "/namespaces/test/replicationcontrollers" {
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: objBody(codec, rc)}, nil
}
return &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewBuffer([]byte("{}"))),
}, nil
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = &restclient.Config{}
cmd := NewCmdRun(tf, os.Stdin, os.Stdout, os.Stderr)
cmd.Flags().Set("image", "nginx")
cmd.Flags().Set("generator", "run/v1")
err := RunRun(tf, os.Stdin, os.Stdout, os.Stderr, cmd, test.args, test.argsLenAtDash)
if test.expectError && err == nil {
t.Errorf("unexpected non-error (%s)", test.name)
}
if !test.expectError && err != nil {
t.Errorf("unexpected error: %v (%s)", err, test.name)
}
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
if req.URL.Path == "/namespaces/test/replicationcontrollers" {
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: objBody(codec, rc)}, nil
}
return &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewBuffer([]byte("{}"))),
}, nil
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = &restclient.Config{}
cmd := NewCmdRun(tf, os.Stdin, os.Stdout, os.Stderr)
cmd.Flags().Set("image", "nginx")
cmd.Flags().Set("generator", "run/v1")
err := RunRun(tf, os.Stdin, os.Stdout, os.Stderr, cmd, test.args, test.argsLenAtDash)
if test.expectError && err == nil {
t.Errorf("unexpected non-error (%s)", test.name)
}
if !test.expectError && err != nil {
t.Errorf("unexpected error: %v (%s)", err, test.name)
}
})
}
}
@ -292,90 +296,98 @@ func TestGenerateService(t *testing.T) {
},
}
for _, test := range tests {
sawPOST := false
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.name, func(t *testing.T) {
sawPOST := false
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.ClientConfigVal = defaultClientConfig()
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case test.expectPOST && m == "POST" && p == "/namespaces/namespace/services":
sawPOST = true
body := objBody(codec, &test.service)
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("unexpected error: %v", err)
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
tf.ClientConfigVal = defaultClientConfig()
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case test.expectPOST && m == "POST" && p == "/namespaces/namespace/services":
sawPOST = true
body := objBody(codec, &test.service)
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
defer req.Body.Close()
svc := &api.Service{}
if err := runtime.DecodeInto(codec, data, svc); err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Copy things that are defaulted by the system
test.service.Annotations = svc.Annotations
if !reflect.DeepEqual(&test.service, svc) {
t.Errorf("expected:\n%v\nsaw:\n%v\n", &test.service, svc)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
defer req.Body.Close()
svc := &api.Service{}
if err := runtime.DecodeInto(codec, data, svc); err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Copy things that are defaulted by the system
test.service.Annotations = svc.Annotations
if !reflect.DeepEqual(&test.service, svc) {
t.Errorf("expected:\n%v\nsaw:\n%v\n", &test.service, svc)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
}
cmd := &cobra.Command{}
cmd.Flags().Bool(cmdutil.ApplyAnnotationsFlag, false, "")
cmd.Flags().Bool("record", false, "Record current kubectl command in the resource annotation. If set to false, do not record the command. If set to true, record the command. If not set, default to updating the existing annotation value only if one already exists.")
cmdutil.AddPrinterFlags(cmd)
cmdutil.AddInclude3rdPartyFlags(cmd)
addRunFlags(cmd)
if !test.expectPOST {
cmd.Flags().Set("dry-run", "true")
}
if len(test.port) > 0 {
cmd.Flags().Set("port", test.port)
test.params["port"] = test.port
}
buff := &bytes.Buffer{}
_, err := generateService(tf, cmd, test.args, test.serviceGenerator, test.params, "namespace", buff)
if test.expectErr {
if err == nil {
t.Error("unexpected non-error")
}),
}
continue
}
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if test.expectPOST != sawPOST {
t.Errorf("expectPost: %v, sawPost: %v", test.expectPOST, sawPOST)
}
cmd := &cobra.Command{}
cmd.Flags().Bool(cmdutil.ApplyAnnotationsFlag, false, "")
cmd.Flags().Bool("record", false, "Record current kubectl command in the resource annotation. If set to false, do not record the command. If set to true, record the command. If not set, default to updating the existing annotation value only if one already exists.")
cmdutil.AddPrinterFlags(cmd)
cmdutil.AddInclude3rdPartyFlags(cmd)
addRunFlags(cmd)
if !test.expectPOST {
cmd.Flags().Set("dry-run", "true")
}
if len(test.port) > 0 {
cmd.Flags().Set("port", test.port)
test.params["port"] = test.port
}
buff := &bytes.Buffer{}
_, err := generateService(tf, cmd, test.args, test.serviceGenerator, test.params, "namespace", buff)
if test.expectErr {
if err == nil {
t.Error("unexpected non-error")
}
return
}
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if test.expectPOST != sawPOST {
t.Errorf("expectPost: %v, sawPost: %v", test.expectPOST, sawPOST)
}
})
}
}
func TestRunValidations(t *testing.T) {
tests := []struct {
name string
args []string
flags map[string]string
expectedErr string
}{
{
name: "test missing name error",
expectedErr: "NAME is required",
},
{
name: "test missing --image error",
args: []string{"test"},
expectedErr: "--image is required",
},
{
name: "test invalid image name error",
args: []string{"test"},
flags: map[string]string{
"image": "#",
@ -383,6 +395,7 @@ func TestRunValidations(t *testing.T) {
expectedErr: "Invalid image name",
},
{
name: "test stdin replicas value",
args: []string{"test"},
flags: map[string]string{
"image": "busybox",
@ -392,6 +405,7 @@ func TestRunValidations(t *testing.T) {
expectedErr: "stdin requires that replicas is 1",
},
{
name: "test rm errors when used on non-attached containers",
args: []string{"test"},
flags: map[string]string{
"image": "busybox",
@ -400,6 +414,7 @@ func TestRunValidations(t *testing.T) {
expectedErr: "rm should only be used for attached containers",
},
{
name: "test error on attached containers options",
args: []string{"test"},
flags: map[string]string{
"image": "busybox",
@ -409,6 +424,7 @@ func TestRunValidations(t *testing.T) {
expectedErr: "can't be used with attached containers options",
},
{
name: "test error on attached containers options, with value from stdin",
args: []string{"test"},
flags: map[string]string{
"image": "busybox",
@ -418,6 +434,7 @@ func TestRunValidations(t *testing.T) {
expectedErr: "can't be used with attached containers options",
},
{
name: "test error on attached containers options, with value from stdin and tty",
args: []string{"test"},
flags: map[string]string{
"image": "busybox",
@ -428,6 +445,7 @@ func TestRunValidations(t *testing.T) {
expectedErr: "can't be used with attached containers options",
},
{
name: "test error when tty=true and no stdin provided",
args: []string{"test"},
flags: map[string]string{
"image": "busybox",
@ -437,28 +455,32 @@ func TestRunValidations(t *testing.T) {
},
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
_, _, codec := cmdtesting.NewExternalScheme()
tf.Client = &fake.RESTClient{
NegotiatedSerializer: scheme.Codecs,
Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, cmdtesting.NewInternalType("", "", ""))},
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
inBuf := bytes.NewReader([]byte{})
outBuf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
cmd := NewCmdRun(tf, inBuf, outBuf, errBuf)
for flagName, flagValue := range test.flags {
cmd.Flags().Set(flagName, flagValue)
}
err := RunRun(tf, inBuf, outBuf, errBuf, cmd, test.args, cmd.ArgsLenAtDash())
if err != nil && len(test.expectedErr) > 0 {
if !strings.Contains(err.Error(), test.expectedErr) {
t.Errorf("unexpected error: %v", err)
_, _, codec := cmdtesting.NewExternalScheme()
tf.Client = &fake.RESTClient{
NegotiatedSerializer: scheme.Codecs,
Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, cmdtesting.NewInternalType("", "", ""))},
}
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
inBuf := bytes.NewReader([]byte{})
outBuf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdRun(tf, inBuf, outBuf, errBuf)
for flagName, flagValue := range test.flags {
cmd.Flags().Set(flagName, flagValue)
}
err := RunRun(tf, inBuf, outBuf, errBuf, cmd, test.args, cmd.ArgsLenAtDash())
if err != nil && len(test.expectedErr) > 0 {
if !strings.Contains(err.Error(), test.expectedErr) {
t.Errorf("unexpected error: %v", err)
}
}
})
}
}

View File

@ -47,6 +47,8 @@ import (
func TestSetEnvLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: ""},
@ -83,6 +85,8 @@ func TestSetEnvLocal(t *testing.T) {
func TestSetMultiResourcesEnvLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
@ -122,12 +126,14 @@ func TestSetMultiResourcesEnvLocal(t *testing.T) {
func TestSetEnvRemote(t *testing.T) {
inputs := []struct {
name string
object runtime.Object
apiPrefix, apiGroup, apiVersion string
testAPIGroup string
args []string
}{
{
name: "test extensions.v1beta1 replicaset",
object: &extensionsv1beta1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: extensionsv1beta1.ReplicaSetSpec{
@ -148,6 +154,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"replicaset", "nginx", "env=prod"},
},
{
name: "test apps.v1beta2 replicaset",
object: &appsv1beta2.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.ReplicaSetSpec{
@ -168,6 +175,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"replicaset", "nginx", "env=prod"},
},
{
name: "test appsv1 replicaset",
object: &appsv1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.ReplicaSetSpec{
@ -188,6 +196,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"replicaset", "nginx", "env=prod"},
},
{
name: "test extensions.v1beta1 daemonset",
object: &extensionsv1beta1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: extensionsv1beta1.DaemonSetSpec{
@ -208,6 +217,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"daemonset", "nginx", "env=prod"},
},
{
name: "test appsv1beta2 daemonset",
object: &appsv1beta2.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.DaemonSetSpec{
@ -228,6 +238,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"daemonset", "nginx", "env=prod"},
},
{
name: "test appsv1 daemonset",
object: &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.DaemonSetSpec{
@ -248,6 +259,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"daemonset", "nginx", "env=prod"},
},
{
name: "test extensions.v1beta1 deployment",
object: &extensionsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: extensionsv1beta1.DeploymentSpec{
@ -268,6 +280,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"deployment", "nginx", "env=prod"},
},
{
name: "test appsv1bta1 deployment",
object: &appsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta1.DeploymentSpec{
@ -288,6 +301,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"deployment", "nginx", "env=prod"},
},
{
name: "test appsv1beta2n deployment",
object: &appsv1beta2.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.DeploymentSpec{
@ -308,6 +322,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"deployment", "nginx", "env=prod"},
},
{
name: "test appsv1 deployment",
object: &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.DeploymentSpec{
@ -328,6 +343,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"deployment", "nginx", "env=prod"},
},
{
name: "test appsv1beta1 statefulset",
object: &appsv1beta1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta1.StatefulSetSpec{
@ -348,6 +364,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"statefulset", "nginx", "env=prod"},
},
{
name: "test appsv1beta2 statefulset",
object: &appsv1beta2.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.StatefulSetSpec{
@ -368,6 +385,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"statefulset", "nginx", "env=prod"},
},
{
name: "test appsv1 statefulset",
object: &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.StatefulSetSpec{
@ -429,48 +447,52 @@ func TestSetEnvRemote(t *testing.T) {
},
}
for _, input := range inputs {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup]
tf := cmdtesting.NewTestFactory()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
ns := legacyscheme.Codecs
tf.Namespace = "test"
tf.Client = &fake.RESTClient{
GroupVersion: groupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
switch p, m := req.URL.Path, req.Method; {
case p == resourcePath && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
case p == resourcePath && m == http.MethodPatch:
stream, err := req.GetBody()
if err != nil {
return nil, err
t.Run(input.name, func(t *testing.T) {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup]
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
ns := legacyscheme.Codecs
tf.Namespace = "test"
tf.Client = &fake.RESTClient{
GroupVersion: groupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
switch p, m := req.URL.Path, req.Method; {
case p == resourcePath && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
case p == resourcePath && m == http.MethodPatch:
stream, err := req.GetBody()
if err != nil {
return nil, err
}
bytes, err := ioutil.ReadAll(stream)
if err != nil {
return nil, err
}
assert.Contains(t, string(bytes), `"value":`+`"`+"prod"+`"`, fmt.Sprintf("env not updated for %#v", input.object))
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
bytes, err := ioutil.ReadAll(stream)
if err != nil {
return nil, err
}
assert.Contains(t, string(bytes), `"value":`+`"`+"prod"+`"`, fmt.Sprintf("env not updated for %#v", input.object))
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()),
}
out := new(bytes.Buffer)
cmd := NewCmdEnv(tf, out, out, out)
cmd.SetOutput(out)
cmd.Flags().Set("output", "yaml")
opts := EnvOptions{
Out: out,
Local: false}
err := opts.Complete(tf, cmd, input.args)
assert.NoError(t, err)
err = opts.RunEnv(tf)
assert.NoError(t, err)
}),
VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()),
}
out := new(bytes.Buffer)
cmd := NewCmdEnv(tf, out, out, out)
cmd.SetOutput(out)
cmd.Flags().Set("output", "yaml")
opts := EnvOptions{
Out: out,
Local: false}
err := opts.Complete(tf, cmd, input.args)
assert.NoError(t, err)
err = opts.RunEnv(tf)
assert.NoError(t, err)
})
}
}

View File

@ -46,6 +46,8 @@ import (
func TestImageLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
@ -149,6 +151,8 @@ func TestSetImageValidation(t *testing.T) {
func TestSetMultiResourcesImageLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
@ -190,12 +194,14 @@ func TestSetMultiResourcesImageLocal(t *testing.T) {
func TestSetImageRemote(t *testing.T) {
inputs := []struct {
name string
object runtime.Object
apiPrefix, apiGroup, apiVersion string
testAPIGroup string
args []string
}{
{
name: "set image extensionsv1beta1 ReplicaSet",
object: &extensionsv1beta1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: extensionsv1beta1.ReplicaSetSpec{
@ -216,6 +222,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"replicaset", "nginx", "*=thingy"},
},
{
name: "set image appsv1beta2 ReplicaSet",
object: &appsv1beta2.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.ReplicaSetSpec{
@ -236,6 +243,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"replicaset", "nginx", "*=thingy"},
},
{
name: "set image appsv1 ReplicaSet",
object: &appsv1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.ReplicaSetSpec{
@ -256,6 +264,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"replicaset", "nginx", "*=thingy"},
},
{
name: "set image extensionsv1beta1 DaemonSet",
object: &extensionsv1beta1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: extensionsv1beta1.DaemonSetSpec{
@ -276,6 +285,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"daemonset", "nginx", "*=thingy"},
},
{
name: "set image appsv1beta2 DaemonSet",
object: &appsv1beta2.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.DaemonSetSpec{
@ -296,6 +306,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"daemonset", "nginx", "*=thingy"},
},
{
name: "set image appsv1 DaemonSet",
object: &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.DaemonSetSpec{
@ -316,6 +327,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"daemonset", "nginx", "*=thingy"},
},
{
name: "set image extensionsv1beta1 Deployment",
object: &extensionsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: extensionsv1beta1.DeploymentSpec{
@ -336,6 +348,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"deployment", "nginx", "*=thingy"},
},
{
name: "set image appsv1beta1 Deployment",
object: &appsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta1.DeploymentSpec{
@ -356,6 +369,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"deployment", "nginx", "*=thingy"},
},
{
name: "set image appsv1beta2 Deployment",
object: &appsv1beta2.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.DeploymentSpec{
@ -376,6 +390,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"deployment", "nginx", "*=thingy"},
},
{
name: "set image appsv1 Deployment",
object: &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.DeploymentSpec{
@ -396,6 +411,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"deployment", "nginx", "*=thingy"},
},
{
name: "set image appsv1beta1 StatefulSet",
object: &appsv1beta1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta1.StatefulSetSpec{
@ -416,6 +432,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"statefulset", "nginx", "*=thingy"},
},
{
name: "set image appsv1beta2 StatefulSet",
object: &appsv1beta2.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.StatefulSetSpec{
@ -436,6 +453,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"statefulset", "nginx", "*=thingy"},
},
{
name: "set image appsv1 StatefulSet",
object: &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.StatefulSetSpec{
@ -456,6 +474,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"statefulset", "nginx", "*=thingy"},
},
{
name: "set image batchv1 Job",
object: &batchv1.Job{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: batchv1.JobSpec{
@ -476,6 +495,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"job", "nginx", "*=thingy"},
},
{
name: "set image v1.ReplicationController",
object: &v1.ReplicationController{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: v1.ReplicationControllerSpec{
@ -497,48 +517,52 @@ func TestSetImageRemote(t *testing.T) {
},
}
for _, input := range inputs {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup]
tf := cmdtesting.NewTestFactory()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
ns := legacyscheme.Codecs
tf.Namespace = "test"
tf.Client = &fake.RESTClient{
GroupVersion: groupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
switch p, m := req.URL.Path, req.Method; {
case p == resourcePath && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
case p == resourcePath && m == http.MethodPatch:
stream, err := req.GetBody()
if err != nil {
return nil, err
t.Run(input.name, func(t *testing.T) {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup]
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
ns := legacyscheme.Codecs
tf.Namespace = "test"
tf.Client = &fake.RESTClient{
GroupVersion: groupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
switch p, m := req.URL.Path, req.Method; {
case p == resourcePath && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
case p == resourcePath && m == http.MethodPatch:
stream, err := req.GetBody()
if err != nil {
return nil, err
}
bytes, err := ioutil.ReadAll(stream)
if err != nil {
return nil, err
}
assert.Contains(t, string(bytes), `"image":`+`"`+"thingy"+`"`, fmt.Sprintf("image not updated for %#v", input.object))
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
bytes, err := ioutil.ReadAll(stream)
if err != nil {
return nil, err
}
assert.Contains(t, string(bytes), `"image":`+`"`+"thingy"+`"`, fmt.Sprintf("image not updated for %#v", input.object))
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()),
}
out := new(bytes.Buffer)
cmd := NewCmdImage(tf, out, out)
cmd.SetOutput(out)
cmd.Flags().Set("output", "yaml")
opts := ImageOptions{
Out: out,
Local: false}
err := opts.Complete(tf, cmd, input.args)
assert.NoError(t, err)
err = opts.Run()
assert.NoError(t, err)
}),
VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()),
}
out := new(bytes.Buffer)
cmd := NewCmdImage(tf, out, out)
cmd.SetOutput(out)
cmd.Flags().Set("output", "yaml")
opts := ImageOptions{
Out: out,
Local: false}
err := opts.Complete(tf, cmd, input.args)
assert.NoError(t, err)
err = opts.Run()
assert.NoError(t, err)
})
}
}

View File

@ -46,6 +46,7 @@ import (
func TestResourcesLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
@ -90,6 +91,7 @@ func TestResourcesLocal(t *testing.T) {
func TestSetMultiResourcesLimitsLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
@ -446,6 +448,7 @@ func TestSetResourcesRemote(t *testing.T) {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup]
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
ns := legacyscheme.Codecs
tf.Namespace = "test"

View File

@ -317,6 +317,8 @@ func TestGetResourcesAndSelector(t *testing.T) {
func TestSelectorTest(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: ""},

View File

@ -68,6 +68,8 @@ func TestSetServiceAccountLocal(t *testing.T) {
for i, input := range inputs {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
@ -98,6 +100,8 @@ func TestSetServiceAccountLocal(t *testing.T) {
func TestSetServiceAccountMultiLocal(t *testing.T) {
testapi.Default = testapi.Groups[""]
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: ""},
@ -310,77 +314,86 @@ func TestSetServiceAccountRemote(t *testing.T) {
},
}
for _, input := range inputs {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup]
tf := cmdtesting.NewTestFactory()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
ns := legacyscheme.Codecs
tf.Namespace = "test"
tf.Client = &fake.RESTClient{
GroupVersion: groupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
switch p, m := req.URL.Path, req.Method; {
case p == resourcePath && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
case p == resourcePath && m == http.MethodPatch:
stream, err := req.GetBody()
if err != nil {
return nil, err
t.Run(input.apiPrefix, func(t *testing.T) {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup]
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
ns := legacyscheme.Codecs
tf.Namespace = "test"
tf.Client = &fake.RESTClient{
GroupVersion: groupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
switch p, m := req.URL.Path, req.Method; {
case p == resourcePath && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
case p == resourcePath && m == http.MethodPatch:
stream, err := req.GetBody()
if err != nil {
return nil, err
}
bytes, err := ioutil.ReadAll(stream)
if err != nil {
return nil, err
}
assert.Contains(t, string(bytes), `"serviceAccountName":`+`"`+serviceAccount+`"`, fmt.Sprintf("serviceaccount not updated for %#v", input.object))
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "serviceaccount", req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
bytes, err := ioutil.ReadAll(stream)
if err != nil {
return nil, err
}
assert.Contains(t, string(bytes), `"serviceAccountName":`+`"`+serviceAccount+`"`, fmt.Sprintf("serviceaccount not updated for %#v", input.object))
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "serviceaccount", req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()),
}
out := new(bytes.Buffer)
cmd := NewCmdServiceAccount(tf, out, out)
cmd.SetOutput(out)
cmd.Flags().Set("output", "yaml")
saConfig := serviceAccountConfig{
out: out,
local: false}
err := saConfig.Complete(tf, cmd, input.args)
assert.NoError(t, err)
err = saConfig.Run()
assert.NoError(t, err)
}),
VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()),
}
out := new(bytes.Buffer)
cmd := NewCmdServiceAccount(tf, out, out)
cmd.SetOutput(out)
cmd.Flags().Set("output", "yaml")
saConfig := serviceAccountConfig{
out: out,
local: false}
err := saConfig.Complete(tf, cmd, input.args)
assert.NoError(t, err)
err = saConfig.Run()
assert.NoError(t, err)
})
}
}
func TestServiceAccountValidation(t *testing.T) {
inputs := []struct {
name string
args []string
errorString string
}{
{args: []string{}, errorString: serviceAccountMissingErrString},
{args: []string{serviceAccount}, errorString: resourceMissingErrString},
{name: "test service account missing", args: []string{}, errorString: serviceAccountMissingErrString},
{name: "test service account resource missing", args: []string{serviceAccount}, errorString: resourceMissingErrString},
}
for _, input := range inputs {
tf := cmdtesting.NewTestFactory()
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
return nil, nil
}),
}
tf.Namespace = "test"
out := bytes.NewBuffer([]byte{})
cmd := NewCmdServiceAccount(tf, out, out)
cmd.SetOutput(out)
t.Run(input.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
saConfig := &serviceAccountConfig{}
err := saConfig.Complete(tf, cmd, input.args)
assert.EqualError(t, err, input.errorString)
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
return nil, nil
}),
}
tf.Namespace = "test"
out := bytes.NewBuffer([]byte{})
cmd := NewCmdServiceAccount(tf, out, out)
cmd.SetOutput(out)
saConfig := &serviceAccountConfig{}
err := saConfig.Complete(tf, cmd, input.args)
assert.EqualError(t, err, input.errorString)
})
}
}

View File

@ -29,6 +29,8 @@ import (
func TestValidate(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Namespace = "test"
tests := map[string]struct {

View File

@ -236,102 +236,106 @@ func TestTaint(t *testing.T) {
}
for _, test := range tests {
oldNode, expectNewNode := generateNodeAndTaintedNode(test.oldTaints, test.newTaints)
new_node := &v1.Node{}
tainted := false
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.description, func(t *testing.T) {
oldNode, expectNewNode := generateNodeAndTaintedNode(test.oldTaints, test.newTaints)
new_node := &v1.Node{}
tainted := false
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
m := &MyReq{req}
switch {
case m.isFor("GET", "/nodes"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, oldNode)}, nil
case m.isFor("GET", "/nodes/node-name"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, oldNode)}, nil
case m.isFor("PATCH", "/nodes/node-name"):
tainted = true
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
defer req.Body.Close()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
// apply the patch
oldJSON, err := runtime.Encode(codec, oldNode)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
appliedPatch, err := strategicpatch.StrategicMergePatch(oldJSON, data, &v1.Node{})
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
m := &MyReq{req}
switch {
case m.isFor("GET", "/nodes"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, oldNode)}, nil
case m.isFor("GET", "/nodes/node-name"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, oldNode)}, nil
case m.isFor("PATCH", "/nodes/node-name"):
tainted = true
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
defer req.Body.Close()
// decode the patch
if err := runtime.DecodeInto(codec, appliedPatch, new_node); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if !equalTaints(expectNewNode.Spec.Taints, new_node.Spec.Taints) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, expectNewNode.Spec.Taints, new_node.Spec.Taints)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, new_node)}, nil
case m.isFor("PUT", "/nodes/node-name"):
tainted = true
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
defer req.Body.Close()
if err := runtime.DecodeInto(codec, data, new_node); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if !equalTaints(expectNewNode.Spec.Taints, new_node.Spec.Taints) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, expectNewNode.Spec.Taints, new_node.Spec.Taints)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, new_node)}, nil
default:
t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req)
return nil, nil
}
}),
}
tf.ClientConfigVal = defaultClientConfig()
// apply the patch
oldJSON, err := runtime.Encode(codec, oldNode)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
appliedPatch, err := strategicpatch.StrategicMergePatch(oldJSON, data, &v1.Node{})
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdTaint(tf, buf)
// decode the patch
if err := runtime.DecodeInto(codec, appliedPatch, new_node); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if !equalTaints(expectNewNode.Spec.Taints, new_node.Spec.Taints) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, expectNewNode.Spec.Taints, new_node.Spec.Taints)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, new_node)}, nil
case m.isFor("PUT", "/nodes/node-name"):
tainted = true
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
defer req.Body.Close()
if err := runtime.DecodeInto(codec, data, new_node); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if !equalTaints(expectNewNode.Spec.Taints, new_node.Spec.Taints) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, expectNewNode.Spec.Taints, new_node.Spec.Taints)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, new_node)}, nil
default:
t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req)
return nil, nil
}
}),
}
tf.ClientConfigVal = defaultClientConfig()
saw_fatal := false
func() {
defer func() {
// Recover from the panic below.
_ = recover()
// Restore cmdutil behavior
cmdutil.DefaultBehaviorOnFatal()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdTaint(tf, buf)
saw_fatal := false
func() {
defer func() {
// Recover from the panic below.
_ = recover()
// Restore cmdutil behavior
cmdutil.DefaultBehaviorOnFatal()
}()
cmdutil.BehaviorOnFatal(func(e string, code int) { saw_fatal = true; panic(e) })
cmd.SetArgs(test.args)
cmd.Execute()
}()
cmdutil.BehaviorOnFatal(func(e string, code int) { saw_fatal = true; panic(e) })
cmd.SetArgs(test.args)
cmd.Execute()
}()
if test.expectFatal {
if !saw_fatal {
t.Fatalf("%s: unexpected non-error", test.description)
if test.expectFatal {
if !saw_fatal {
t.Fatalf("%s: unexpected non-error", test.description)
}
}
}
if test.expectTaint {
if !tainted {
t.Fatalf("%s: node not tainted", test.description)
if test.expectTaint {
if !tainted {
t.Fatalf("%s: node not tainted", test.description)
}
}
}
if !test.expectTaint {
if tainted {
t.Fatalf("%s: unexpected taint", test.description)
if !test.expectTaint {
if tainted {
t.Fatalf("%s: unexpected taint", test.description)
}
}
}
})
}
}

View File

@ -37,6 +37,8 @@ go_library(
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/rest/fake:go_default_library",
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
],
)

View File

@ -17,8 +17,11 @@ limitations under the License.
package testing
import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"time"
@ -34,6 +37,8 @@ import (
"k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"k8s.io/kubernetes/pkg/api/legacyscheme"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
@ -240,16 +245,55 @@ type TestFactory struct {
ClientConfigVal *restclient.Config
CommandVal string
tempConfigFile *os.File
UnstructuredClientForMappingFunc func(mapping *meta.RESTMapping) (resource.RESTClient, error)
OpenAPISchemaFunc func() (openapi.Resources, error)
}
func NewTestFactory() *TestFactory {
// specify an optionalClientConfig to explicitly use in testing
// to avoid polluting an existing user config.
config, configFile := defaultFakeClientConfig()
return &TestFactory{
Factory: cmdutil.NewFactory(nil),
Factory: cmdutil.NewFactory(config),
tempConfigFile: configFile,
}
}
func (f *TestFactory) Cleanup() {
if f.tempConfigFile == nil {
return
}
os.Remove(f.tempConfigFile.Name())
}
func defaultFakeClientConfig() (clientcmd.ClientConfig, *os.File) {
loadingRules, tmpFile, err := newDefaultFakeClientConfigLoadingRules()
if err != nil {
panic(fmt.Sprintf("unable to create a fake client config: %v", err))
}
overrides := &clientcmd.ConfigOverrides{ClusterDefaults: clientcmdapi.Cluster{Server: "http://localhost:8080"}}
fallbackReader := bytes.NewBuffer([]byte{})
clientConfig := clientcmd.NewInteractiveDeferredLoadingClientConfig(loadingRules, overrides, fallbackReader)
return clientConfig, tmpFile
}
func newDefaultFakeClientConfigLoadingRules() (*clientcmd.ClientConfigLoadingRules, *os.File, error) {
tmpFile, err := ioutil.TempFile("", "cmdtests_temp")
if err != nil {
return nil, nil, err
}
return &clientcmd.ClientConfigLoadingRules{
Precedence: []string{tmpFile.Name()},
MigrationRules: map[string]string{},
}, tmpFile, nil
}
func (f *TestFactory) CategoryExpander() categories.CategoryExpander {
return categories.LegacyCategoryExpander
}

View File

@ -50,6 +50,8 @@ func TestTopNodeAllMetrics(t *testing.T) {
expectedNodePath := fmt.Sprintf("/%s/%s/nodes", apiPrefix, apiVersion)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
@ -101,6 +103,8 @@ func TestTopNodeAllMetricsCustomDefaults(t *testing.T) {
expectedNodePath := fmt.Sprintf("/%s/%s/nodes", apiPrefix, apiVersion)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
@ -162,6 +166,8 @@ func TestTopNodeWithNameMetrics(t *testing.T) {
expectedNodePath := fmt.Sprintf("/%s/%s/nodes/%s", apiPrefix, apiVersion, expectedMetrics.Name)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
@ -227,6 +233,8 @@ func TestTopNodeWithLabelSelectorMetrics(t *testing.T) {
expectedNodePath := fmt.Sprintf("/%s/%s/nodes", apiPrefix, apiVersion)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
@ -280,6 +288,8 @@ func TestTopNodeAllMetricsFromMetricsServer(t *testing.T) {
expectedNodePath := fmt.Sprintf("/%s/%s/nodes", apiPrefix, apiVersion)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
@ -344,6 +354,8 @@ func TestTopNodeWithNameMetricsFromMetricsServer(t *testing.T) {
expectedNodePath := fmt.Sprintf("/%s/%s/nodes/%s", apiPrefix, apiVersion, expectedMetrics.Name)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
@ -418,6 +430,8 @@ func TestTopNodeWithLabelSelectorMetricsFromMetricsServer(t *testing.T) {
expectedNodePath := fmt.Sprintf("/%s/%s/nodes", apiPrefix, apiVersion)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs

View File

@ -134,90 +134,94 @@ func TestTopPod(t *testing.T) {
}
initTestErrorHandler(t)
for _, testCase := range testCases {
t.Logf("Running test case: %s", testCase.name)
metricsList := testPodMetricsData()
var expectedMetrics []metricsv1alpha1api.PodMetrics
var expectedContainerNames, nonExpectedMetricsNames []string
for n, m := range metricsList {
if n < len(testCase.namespaces) {
m.Namespace = testCase.namespaces[n]
expectedMetrics = append(expectedMetrics, m)
for _, c := range m.Containers {
expectedContainerNames = append(expectedContainerNames, c.Name)
}
} else {
nonExpectedMetricsNames = append(nonExpectedMetricsNames, m.Name)
}
}
var response interface{}
if len(expectedMetrics) == 1 {
response = expectedMetrics[0]
} else {
response = metricsv1alpha1api.PodMetricsList{
ListMeta: metav1.ListMeta{
ResourceVersion: "2",
},
Items: expectedMetrics,
}
}
tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m, q := req.URL.Path, req.Method, req.URL.RawQuery; {
case p == "/api":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apibody)))}, nil
case p == "/apis":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apisbody)))}, nil
case p == testCase.expectedPath && m == "GET" && (testCase.expectedQuery == "" || q == testCase.expectedQuery):
body, err := marshallBody(response)
if err != nil {
t.Errorf("%s: unexpected error: %v", testCase.name, err)
t.Run(testCase.name, func(t *testing.T) {
t.Logf("Running test case: %s", testCase.name)
metricsList := testPodMetricsData()
var expectedMetrics []metricsv1alpha1api.PodMetrics
var expectedContainerNames, nonExpectedMetricsNames []string
for n, m := range metricsList {
if n < len(testCase.namespaces) {
m.Namespace = testCase.namespaces[n]
expectedMetrics = append(expectedMetrics, m)
for _, c := range m.Containers {
expectedContainerNames = append(expectedContainerNames, c.Name)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
t.Fatalf("%s: unexpected request: %#v\nGot URL: %#v\nExpected path: %#v\nExpected query: %#v",
testCase.name, req, req.URL, testCase.expectedPath, testCase.expectedQuery)
return nil, nil
}
}),
}
tf.Namespace = testNS
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdTopPod(tf, nil, buf)
for name, value := range testCase.flags {
cmd.Flags().Set(name, value)
}
cmd.Run(cmd, testCase.args)
// Check the presence of pod names&namespaces/container names in the output.
result := buf.String()
if testCase.containers {
for _, containerName := range expectedContainerNames {
if !strings.Contains(result, containerName) {
t.Errorf("%s: missing metrics for container %s: \n%s", testCase.name, containerName, result)
} else {
nonExpectedMetricsNames = append(nonExpectedMetricsNames, m.Name)
}
}
}
for _, m := range expectedMetrics {
if !strings.Contains(result, m.Name) {
t.Errorf("%s: missing metrics for %s: \n%s", testCase.name, m.Name, result)
var response interface{}
if len(expectedMetrics) == 1 {
response = expectedMetrics[0]
} else {
response = metricsv1alpha1api.PodMetricsList{
ListMeta: metav1.ListMeta{
ResourceVersion: "2",
},
Items: expectedMetrics,
}
}
if testCase.listsNamespaces && !strings.Contains(result, m.Namespace) {
t.Errorf("%s: missing metrics for %s/%s: \n%s", testCase.name, m.Namespace, m.Name, result)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m, q := req.URL.Path, req.Method, req.URL.RawQuery; {
case p == "/api":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apibody)))}, nil
case p == "/apis":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apisbody)))}, nil
case p == testCase.expectedPath && m == "GET" && (testCase.expectedQuery == "" || q == testCase.expectedQuery):
body, err := marshallBody(response)
if err != nil {
t.Errorf("%s: unexpected error: %v", testCase.name, err)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
t.Fatalf("%s: unexpected request: %#v\nGot URL: %#v\nExpected path: %#v\nExpected query: %#v",
testCase.name, req, req.URL, testCase.expectedPath, testCase.expectedQuery)
return nil, nil
}
}),
}
}
for _, name := range nonExpectedMetricsNames {
if strings.Contains(result, name) {
t.Errorf("%s: unexpected metrics for %s: \n%s", testCase.name, name, result)
tf.Namespace = testNS
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdTopPod(tf, nil, buf)
for name, value := range testCase.flags {
cmd.Flags().Set(name, value)
}
}
cmd.Run(cmd, testCase.args)
// Check the presence of pod names&namespaces/container names in the output.
result := buf.String()
if testCase.containers {
for _, containerName := range expectedContainerNames {
if !strings.Contains(result, containerName) {
t.Errorf("%s: missing metrics for container %s: \n%s", testCase.name, containerName, result)
}
}
}
for _, m := range expectedMetrics {
if !strings.Contains(result, m.Name) {
t.Errorf("%s: missing metrics for %s: \n%s", testCase.name, m.Name, result)
}
if testCase.listsNamespaces && !strings.Contains(result, m.Namespace) {
t.Errorf("%s: missing metrics for %s/%s: \n%s", testCase.name, m.Namespace, m.Name, result)
}
}
for _, name := range nonExpectedMetricsNames {
if strings.Contains(result, name) {
t.Errorf("%s: unexpected metrics for %s: \n%s", testCase.name, name, result)
}
}
})
}
}
@ -305,6 +309,8 @@ func TestTopPodWithMetricsServer(t *testing.T) {
}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
@ -471,98 +477,102 @@ func TestTopPodCustomDefaults(t *testing.T) {
}
initTestErrorHandler(t)
for _, testCase := range testCases {
t.Logf("Running test case: %s", testCase.name)
metricsList := testPodMetricsData()
var expectedMetrics []metricsv1alpha1api.PodMetrics
var expectedContainerNames, nonExpectedMetricsNames []string
for n, m := range metricsList {
if n < len(testCase.namespaces) {
m.Namespace = testCase.namespaces[n]
expectedMetrics = append(expectedMetrics, m)
for _, c := range m.Containers {
expectedContainerNames = append(expectedContainerNames, c.Name)
}
} else {
nonExpectedMetricsNames = append(nonExpectedMetricsNames, m.Name)
}
}
var response interface{}
if len(expectedMetrics) == 1 {
response = expectedMetrics[0]
} else {
response = metricsv1alpha1api.PodMetricsList{
ListMeta: metav1.ListMeta{
ResourceVersion: "2",
},
Items: expectedMetrics,
}
}
tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m, q := req.URL.Path, req.Method, req.URL.RawQuery; {
case p == "/api":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apibody)))}, nil
case p == "/apis":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apisbody)))}, nil
case p == testCase.expectedPath && m == "GET" && (testCase.expectedQuery == "" || q == testCase.expectedQuery):
body, err := marshallBody(response)
if err != nil {
t.Errorf("%s: unexpected error: %v", testCase.name, err)
t.Run(testCase.name, func(t *testing.T) {
t.Logf("Running test case: %s", testCase.name)
metricsList := testPodMetricsData()
var expectedMetrics []metricsv1alpha1api.PodMetrics
var expectedContainerNames, nonExpectedMetricsNames []string
for n, m := range metricsList {
if n < len(testCase.namespaces) {
m.Namespace = testCase.namespaces[n]
expectedMetrics = append(expectedMetrics, m)
for _, c := range m.Containers {
expectedContainerNames = append(expectedContainerNames, c.Name)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
t.Fatalf("%s: unexpected request: %#v\nGot URL: %#v\nExpected path: %#v\nExpected query: %#v",
testCase.name, req, req.URL, testCase.expectedPath, testCase.expectedQuery)
return nil, nil
}
}),
}
tf.Namespace = testNS
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
opts := &TopPodOptions{
HeapsterOptions: HeapsterTopOptions{
Namespace: "custom-namespace",
Scheme: "https",
Service: "custom-heapster-service",
},
DiscoveryClient: &fakeDiscovery{},
}
cmd := NewCmdTopPod(tf, opts, buf)
for name, value := range testCase.flags {
cmd.Flags().Set(name, value)
}
cmd.Run(cmd, testCase.args)
// Check the presence of pod names&namespaces/container names in the output.
result := buf.String()
if testCase.containers {
for _, containerName := range expectedContainerNames {
if !strings.Contains(result, containerName) {
t.Errorf("%s: missing metrics for container %s: \n%s", testCase.name, containerName, result)
} else {
nonExpectedMetricsNames = append(nonExpectedMetricsNames, m.Name)
}
}
}
for _, m := range expectedMetrics {
if !strings.Contains(result, m.Name) {
t.Errorf("%s: missing metrics for %s: \n%s", testCase.name, m.Name, result)
var response interface{}
if len(expectedMetrics) == 1 {
response = expectedMetrics[0]
} else {
response = metricsv1alpha1api.PodMetricsList{
ListMeta: metav1.ListMeta{
ResourceVersion: "2",
},
Items: expectedMetrics,
}
}
if testCase.listsNamespaces && !strings.Contains(result, m.Namespace) {
t.Errorf("%s: missing metrics for %s/%s: \n%s", testCase.name, m.Namespace, m.Name, result)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m, q := req.URL.Path, req.Method, req.URL.RawQuery; {
case p == "/api":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apibody)))}, nil
case p == "/apis":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apisbody)))}, nil
case p == testCase.expectedPath && m == "GET" && (testCase.expectedQuery == "" || q == testCase.expectedQuery):
body, err := marshallBody(response)
if err != nil {
t.Errorf("%s: unexpected error: %v", testCase.name, err)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
t.Fatalf("%s: unexpected request: %#v\nGot URL: %#v\nExpected path: %#v\nExpected query: %#v",
testCase.name, req, req.URL, testCase.expectedPath, testCase.expectedQuery)
return nil, nil
}
}),
}
}
for _, name := range nonExpectedMetricsNames {
if strings.Contains(result, name) {
t.Errorf("%s: unexpected metrics for %s: \n%s", testCase.name, name, result)
tf.Namespace = testNS
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
opts := &TopPodOptions{
HeapsterOptions: HeapsterTopOptions{
Namespace: "custom-namespace",
Scheme: "https",
Service: "custom-heapster-service",
},
DiscoveryClient: &fakeDiscovery{},
}
}
cmd := NewCmdTopPod(tf, opts, buf)
for name, value := range testCase.flags {
cmd.Flags().Set(name, value)
}
cmd.Run(cmd, testCase.args)
// Check the presence of pod names&namespaces/container names in the output.
result := buf.String()
if testCase.containers {
for _, containerName := range expectedContainerNames {
if !strings.Contains(result, containerName) {
t.Errorf("%s: missing metrics for container %s: \n%s", testCase.name, containerName, result)
}
}
}
for _, m := range expectedMetrics {
if !strings.Contains(result, m.Name) {
t.Errorf("%s: missing metrics for %s: \n%s", testCase.name, m.Name, result)
}
if testCase.listsNamespaces && !strings.Contains(result, m.Namespace) {
t.Errorf("%s: missing metrics for %s/%s: \n%s", testCase.name, m.Namespace, m.Name, result)
}
}
for _, name := range nonExpectedMetricsNames {
if strings.Contains(result, name) {
t.Errorf("%s: unexpected metrics for %s: \n%s", testCase.name, name, result)
}
}
})
}
}

View File

@ -44,6 +44,8 @@ func TestTopSubcommandsExist(t *testing.T) {
initTestErrorHandler(t)
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdTop(f, buf, buf)