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 { for k, testCase := range testCases {
tf := cmdtesting.NewTestFactory() t.Run(k, func(t *testing.T) {
tf.Namespace = "test" tf := cmdtesting.NewTestFactory()
tf.ClientConfigVal = defaultClientConfig() defer tf.Cleanup()
buf := bytes.NewBuffer([]byte{}) tf.Namespace = "test"
cmd := NewCmdAnnotate(tf, buf) tf.ClientConfigVal = defaultClientConfig()
cmd.SetOutput(buf)
for k, v := range testCase.flags { buf := bytes.NewBuffer([]byte{})
cmd.Flags().Set(k, v) cmd := NewCmdAnnotate(tf, buf)
} cmd.SetOutput(buf)
options := &AnnotateOptions{}
err := options.Complete(buf, cmd, testCase.args) for k, v := range testCase.flags {
if err == nil { cmd.Flags().Set(k, v)
err = options.Validate() }
} options := &AnnotateOptions{}
if !testCase.errFn(err) { err := options.Complete(buf, cmd, testCase.args)
t.Errorf("%s: unexpected error: %v", k, err) if err == nil {
continue err = options.Validate()
} }
if buf.Len() > 0 { if !testCase.errFn(err) {
t.Errorf("buffer should be empty: %s", string(buf.Bytes())) 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() pods, _, _ := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
@ -499,6 +505,8 @@ func TestAnnotateObjectFromFile(t *testing.T) {
pods, _, _ := testData() pods, _, _ := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
@ -550,6 +558,8 @@ func TestAnnotateObjectFromFile(t *testing.T) {
func TestAnnotateLocal(t *testing.T) { func TestAnnotateLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Group: "testgroup", Version: "v1"}, GroupVersion: schema.GroupVersion{Group: "testgroup", Version: "v1"},
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: unstructuredSerializer,
@ -581,6 +591,8 @@ func TestAnnotateMultipleObjects(t *testing.T) {
pods, _, _ := testData() pods, _, _ := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Group: "testgroup", Version: "v1"}, 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 { for _, test := range tests {
tf := cmdtesting.NewTestFactory() t.Run(test.name, func(t *testing.T) {
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs defer tf.Cleanup()
tf.Client = &fake.RESTClient{ codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion, ns := legacyscheme.Codecs
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()
cmd := &cobra.Command{} tf.Client = &fake.RESTClient{
options := test.p GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
cmdutil.AddPodRunningTimeoutFlag(cmd, test.timeout) 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) cmd := &cobra.Command{}
if test.expectError && err == nil { options := test.p
t.Errorf("%s: unexpected non-error", test.name) cmdutil.AddPodRunningTimeoutFlag(cmd, test.timeout)
}
if !test.expectError && err != nil { err := options.Complete(tf, cmd, test.args)
t.Errorf("%s: unexpected error: %v", test.name, err) if test.expectError && err == nil {
} t.Errorf("%s: unexpected non-error", test.name)
if err != nil { }
continue if !test.expectError && err != nil {
} t.Errorf("%s: unexpected error: %v", test.name, err)
if options.PodName != test.expectedPod { }
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedPod, options.PodName) if err != nil {
} return
if options.ContainerName != test.expectedContainer { }
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedContainer, options.ContainerName) 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 { for _, test := range tests {
tf := cmdtesting.NewTestFactory() t.Run(test.name, func(t *testing.T) {
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs defer tf.Cleanup()
tf.Client = &fake.RESTClient{ codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion, ns := legacyscheme.Codecs
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { tf.Client = &fake.RESTClient{
switch p, m := req.URL.Path, req.Method; { GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
case p == test.podPath && m == "GET": NegotiatedSerializer: ns,
body := objBody(codec, test.pod) Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil switch p, m := req.URL.Path, req.Method; {
case p == test.fetchPodPath && m == "GET": case p == test.podPath && m == "GET":
body := objBody(codec, test.pod) body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default: case p == test.fetchPodPath && m == "GET":
// Ensures no GET is performed when deleting by name body := objBody(codec, test.pod)
t.Errorf("%s: unexpected request: %s %#v\n%#v", p, req.Method, req.URL, req) return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
return nil, fmt.Errorf("unexpected request") 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{}) tf.Namespace = "test"
bufIn := bytes.NewBuffer([]byte{}) tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}}
remoteAttach := &fakeRemoteAttach{} bufOut := bytes.NewBuffer([]byte{})
if test.remoteAttachErr { bufErr := bytes.NewBuffer([]byte{})
remoteAttach.err = fmt.Errorf("attach error") bufIn := bytes.NewBuffer([]byte{})
} remoteAttach := &fakeRemoteAttach{}
params := &AttachOptions{ if test.remoteAttachErr {
StreamOptions: StreamOptions{ remoteAttach.err = fmt.Errorf("attach error")
ContainerName: test.container, }
In: bufIn, params := &AttachOptions{
Out: bufOut, StreamOptions: StreamOptions{
Err: bufErr, ContainerName: test.container,
}, In: bufIn,
Attach: remoteAttach, Out: bufOut,
GetPodTimeout: 1000, Err: bufErr,
} },
cmd := &cobra.Command{} Attach: remoteAttach,
cmdutil.AddPodRunningTimeoutFlag(cmd, 1000) GetPodTimeout: 1000,
if err := params.Complete(tf, cmd, []string{"foo"}); err != nil { }
t.Fatal(err) cmd := &cobra.Command{}
} cmdutil.AddPodRunningTimeoutFlag(cmd, 1000)
err := params.Run() if err := params.Complete(tf, cmd, []string{"foo"}); err != nil {
if test.exepctedErr != "" && err.Error() != test.exepctedErr { t.Fatal(err)
t.Errorf("%s: Unexpected exec error: %v", test.name, err) }
continue err := params.Run()
} if test.exepctedErr != "" && err.Error() != test.exepctedErr {
if test.exepctedErr == "" && err != nil { t.Errorf("%s: Unexpected exec error: %v", test.name, err)
t.Errorf("%s: Unexpected error: %v", test.name, err) return
continue }
} if test.exepctedErr == "" && err != nil {
if test.exepctedErr != "" { t.Errorf("%s: Unexpected error: %v", test.name, err)
continue return
} }
if remoteAttach.url.Path != test.attachPath { if test.exepctedErr != "" {
t.Errorf("%s: Did not get expected path for exec request: %q %q", test.name, test.attachPath, remoteAttach.url.Path) return
continue }
} if remoteAttach.url.Path != test.attachPath {
if remoteAttach.method != "POST" { t.Errorf("%s: Did not get expected path for exec request: %q %q", test.name, test.attachPath, remoteAttach.url.Path)
t.Errorf("%s: Did not get method for attach request: %s", test.name, remoteAttach.method) return
} }
if remoteAttach.url.Query().Get("container") != "bar" { if remoteAttach.method != "POST" {
t.Errorf("%s: Did not have query parameters: %s", test.name, remoteAttach.url.Query()) 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 { for _, test := range tests {
tf := cmdtesting.NewTestFactory() t.Run(test.name, func(t *testing.T) {
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs defer tf.Cleanup()
tf.Client = &fake.RESTClient{ codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion, ns := legacyscheme.Codecs
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 { tf.Client = &fake.RESTClient{
if !test.pod.Spec.Containers[0].TTY { GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
if !strings.Contains(bufErr.String(), test.expectedErr) { NegotiatedSerializer: ns,
t.Errorf("%s: Expected TTY fallback warning for attach request: %s", test.name, bufErr.String()) Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
continue 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 { for _, test := range tests {
test.o.Out = ioutil.Discard t.Run(test.name, func(t *testing.T) {
test.o.Err = ioutil.Discard test.o.Out = ioutil.Discard
test.o.Err = ioutil.Discard
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs defer tf.Cleanup()
tf.Client = &fake.RESTClient{ ns := legacyscheme.Codecs
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)
for _, expectedBody := range test.expectedBodyStrings { tf.Client = &fake.RESTClient{
if !strings.Contains(body, expectedBody) { GroupVersion: schema.GroupVersion{Group: "", Version: "v1"},
t.Errorf("%s expecting %s in %s", test.name, expectedBody, body) 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{ for _, expectedBody := range test.expectedBodyStrings {
StatusCode: http.StatusOK, if !strings.Contains(body, expectedBody) {
Body: ioutil.NopCloser(bytes.NewBufferString( t.Errorf("%s expecting %s in %s", test.name, expectedBody, body)
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"}}}
if err := test.o.Complete(tf, test.args); err != nil { return &http.Response{
t.Errorf("%s: %v", test.name, err) StatusCode: http.StatusOK,
continue 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() if err := test.o.Complete(tf, test.args); err != nil {
switch { t.Errorf("%s: %v", test.name, err)
case test.serverErr == nil && err == nil: return
// pass }
case err != nil && test.serverErr != nil && strings.Contains(err.Error(), test.serverErr.Error()):
// pass actualAllowed, err := test.o.RunAccessCheck()
default: switch {
t.Errorf("%s: expected %v, got %v", test.name, test.serverErr, err) case test.serverErr == nil && err == nil:
continue // pass
} case err != nil && test.serverErr != nil && strings.Contains(err.Error(), test.serverErr.Error()):
if actualAllowed != test.allowed { // pass
t.Errorf("%s: expected %v, got %v", test.name, test.allowed, actualAllowed) default:
continue 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 { for _, test := range tests {
out := &bytes.Buffer{} out := &bytes.Buffer{}
f := cmdtesting.NewTestFactory() f := cmdtesting.NewTestFactory()
defer f.Cleanup()
cmd := NewCmdClusterInfoDump(f, os.Stdout) cmd := NewCmdClusterInfoDump(f, os.Stdout)
cmd.Flag("output-directory").Value.Set(test) cmd.Flag("output-directory").Value.Set(test)
writer := setupOutputWriter(cmd, out, "/some/file/that/should/be/ignored") writer := setupOutputWriter(cmd, out, "/some/file/that/should/be/ignored")
@ -51,6 +53,8 @@ func TestSetupOutputWriterFile(t *testing.T) {
out := &bytes.Buffer{} out := &bytes.Buffer{}
f := cmdtesting.NewTestFactory() f := cmdtesting.NewTestFactory()
defer f.Cleanup()
cmd := NewCmdClusterInfoDump(f, os.Stdout) cmd := NewCmdClusterInfoDump(f, os.Stdout)
cmd.Flag("output-directory").Value.Set(dir) cmd.Flag("output-directory").Value.Set(dir)
writer := setupOutputWriter(cmd, out, file) writer := setupOutputWriter(cmd, out, file)

View File

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

View File

@ -102,6 +102,8 @@ func TestConvertObject(t *testing.T) {
for _, field := range tc.fields { for _, field := range tc.fields {
t.Run(fmt.Sprintf("%s %s", tc.name, field), func(t *testing.T) { t.Run(fmt.Sprintf("%s %s", tc.name, field), func(t *testing.T) {
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) 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" clusterRoleName := "my-cluster-role"
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Namespace = "test" tf.Namespace = "test"
tf.Client = &fake.RESTClient{} tf.Client = &fake.RESTClient{}
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = defaultClientConfig()
@ -148,6 +150,8 @@ func TestCreateClusterRole(t *testing.T) {
func TestClusterRoleValidate(t *testing.T) { func TestClusterRoleValidate(t *testing.T) {
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Namespace = "test" tf.Namespace = "test"
tests := map[string]struct { tests := map[string]struct {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -57,6 +57,8 @@ func TestDeleteObjectByTuple(t *testing.T) {
_, _, rc := testData() _, _, rc := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
@ -121,6 +123,8 @@ func TestOrphanDependentsInDeleteObject(t *testing.T) {
_, _, rc := testData() _, _, rc := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
var expectedOrphanDependents *bool var expectedOrphanDependents *bool
@ -171,6 +175,8 @@ func TestDeleteNamedObject(t *testing.T) {
_, _, rc := testData() _, _, rc := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
@ -222,6 +228,8 @@ func TestDeleteObject(t *testing.T) {
_, _, rc := testData() _, _, rc := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
@ -281,6 +289,8 @@ func TestDeleteObjectGraceZero(t *testing.T) {
objectDeletionWaitInterval = time.Millisecond objectDeletionWaitInterval = time.Millisecond
count := 0 count := 0
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
@ -331,6 +341,8 @@ func TestDeleteObjectGraceZero(t *testing.T) {
func TestDeleteObjectNotFound(t *testing.T) { func TestDeleteObjectNotFound(t *testing.T) {
initTestErrorHandler(t) initTestErrorHandler(t)
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
@ -367,6 +379,8 @@ func TestDeleteObjectNotFound(t *testing.T) {
func TestDeleteObjectIgnoreNotFound(t *testing.T) { func TestDeleteObjectIgnoreNotFound(t *testing.T) {
initTestErrorHandler(t) initTestErrorHandler(t)
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { 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 notFoundError := &errors.NewNotFound(api.Resource("services"), "foo").ErrStatus
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
@ -447,6 +463,8 @@ func TestDeleteAllIgnoreNotFound(t *testing.T) {
_, svc, _ := testData() _, svc, _ := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
// Add an item to the list which will result in a 404 on delete // 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() _, svc, rc := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
@ -524,6 +544,8 @@ func TestDeleteMultipleObjectContinueOnMissing(t *testing.T) {
_, svc, _ := testData() _, svc, _ := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
@ -569,6 +591,8 @@ func TestDeleteMultipleResourcesWithTheSameName(t *testing.T) {
initTestErrorHandler(t) initTestErrorHandler(t)
_, svc, rc := testData() _, svc, rc := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
@ -608,6 +632,8 @@ func TestDeleteDirectory(t *testing.T) {
_, _, rc := testData() _, _, rc := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
@ -641,6 +667,8 @@ func TestDeleteMultipleSelector(t *testing.T) {
pods, svc, _ := testData() pods, svc, _ := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
@ -706,26 +734,30 @@ func TestResourceErrors(t *testing.T) {
} }
for k, testCase := range testCases { for k, testCase := range testCases {
tf := cmdtesting.NewTestFactory() t.Run(k, func(t *testing.T) {
tf.Namespace = "test" tf := cmdtesting.NewTestFactory()
tf.ClientConfigVal = defaultClientConfig() defer tf.Cleanup()
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{}) tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
options := &DeleteOptions{ buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
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
}
if buf.Len() > 0 { options := &DeleteOptions{
t.Errorf("buffer should be empty: %s", string(buf.Bytes())) 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) { func TestDescribeUnknownSchemaObject(t *testing.T) {
d := &testDescriber{Output: "test output"} d := &testDescriber{Output: "test output"}
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
_, _, codec := cmdtesting.NewExternalScheme() _, _, codec := cmdtesting.NewExternalScheme()
tf.DescriberVal = d tf.DescriberVal = d
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
@ -58,6 +59,7 @@ func TestDescribeUnknownSchemaObject(t *testing.T) {
func TestDescribeUnknownNamespacedSchemaObject(t *testing.T) { func TestDescribeUnknownNamespacedSchemaObject(t *testing.T) {
d := &testDescriber{Output: "test output"} d := &testDescriber{Output: "test output"}
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
_, _, codec := cmdtesting.NewExternalScheme() _, _, codec := cmdtesting.NewExternalScheme()
tf.DescriberVal = d tf.DescriberVal = d
@ -83,6 +85,7 @@ func TestDescribeUnknownNamespacedSchemaObject(t *testing.T) {
func TestDescribeObject(t *testing.T) { func TestDescribeObject(t *testing.T) {
_, _, rc := testData() _, _, rc := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
d := &testDescriber{Output: "test output"} d := &testDescriber{Output: "test output"}
@ -118,6 +121,7 @@ func TestDescribeObject(t *testing.T) {
func TestDescribeListObjects(t *testing.T) { func TestDescribeListObjects(t *testing.T) {
pods, _, _ := testData() pods, _, _ := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
d := &testDescriber{Output: "test output"} d := &testDescriber{Output: "test output"}
@ -140,6 +144,7 @@ func TestDescribeListObjects(t *testing.T) {
func TestDescribeObjectShowEvents(t *testing.T) { func TestDescribeObjectShowEvents(t *testing.T) {
pods, _, _ := testData() pods, _, _ := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
d := &testDescriber{Output: "test output"} d := &testDescriber{Output: "test output"}
@ -163,6 +168,7 @@ func TestDescribeObjectShowEvents(t *testing.T) {
func TestDescribeObjectSkipEvents(t *testing.T) { func TestDescribeObjectSkipEvents(t *testing.T) {
pods, _, _ := testData() pods, _, _ := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
d := &testDescriber{Output: "test output"} d := &testDescriber{Output: "test output"}
@ -185,6 +191,7 @@ func TestDescribeObjectSkipEvents(t *testing.T) {
func TestDescribeHelpMessage(t *testing.T) { func TestDescribeHelpMessage(t *testing.T) {
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
buferr := bytes.NewBuffer([]byte{}) buferr := bytes.NewBuffer([]byte{})

View File

@ -150,86 +150,90 @@ func TestCordon(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
tf := cmdtesting.NewTestFactory() t.Run(test.description, func(t *testing.T) {
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs defer tf.Cleanup()
new_node := &corev1.Node{} codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
updated := false 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 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()
buf := bytes.NewBuffer([]byte{}) new_node := &corev1.Node{}
cmd := test.cmd(tf, buf) 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 buf := bytes.NewBuffer([]byte{})
func() { cmd := test.cmd(tf, buf)
defer func() {
// Recover from the panic below. saw_fatal := false
_ = recover() func() {
// Restore cmdutil behavior defer func() {
cmdutil.DefaultBehaviorOnFatal() // 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 test.expectFatal {
if !saw_fatal { if !saw_fatal {
t.Fatalf("%s: unexpected non-error", test.description) 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 { if !test.expectFatal && saw_fatal {
t.Fatalf("%s: unexpected error", test.description) t.Fatalf("%s: unexpected error", test.description)
} }
if !reflect.DeepEqual(test.expected.Spec, test.node.Spec) && !updated { if !reflect.DeepEqual(test.expected.Spec, test.node.Spec) && !updated {
t.Fatalf("%s: node never updated", test.description) t.Fatalf("%s: node never updated", test.description)
} }
})
} }
} }
@ -597,164 +601,168 @@ func TestDrain(t *testing.T) {
currMethod = DeleteMethod currMethod = DeleteMethod
} }
for _, test := range tests { for _, test := range tests {
new_node := &corev1.Node{} t.Run(test.description, func(t *testing.T) {
deleted := false new_node := &corev1.Node{}
evicted := false deleted := false
tf := cmdtesting.NewTestFactory() evicted := false
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs defer tf.Cleanup()
tf.Client = &fake.RESTClient{ codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion, ns := legacyscheme.Codecs
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { tf.Client = &fake.RESTClient{
m := &MyReq{req} GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
switch { NegotiatedSerializer: ns,
case req.Method == "GET" && req.URL.Path == "/api": Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
apiVersions := metav1.APIVersions{ m := &MyReq{req}
Versions: []string{"v1"}, switch {
} case req.Method == "GET" && req.URL.Path == "/api":
return genResponseWithJsonEncodedBody(apiVersions) apiVersions := metav1.APIVersions{
case req.Method == "GET" && req.URL.Path == "/apis": Versions: []string{"v1"},
groupList := metav1.APIGroupList{ }
Groups: []metav1.APIGroup{ return genResponseWithJsonEncodedBody(apiVersions)
{ case req.Method == "GET" && req.URL.Path == "/apis":
Name: "policy", groupList := metav1.APIGroupList{
PreferredVersion: metav1.GroupVersionForDiscovery{ Groups: []metav1.APIGroup{
GroupVersion: "policy/v1beta1", {
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 tf.ClientConfigVal = defaultClientConfig()
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()
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{}) errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdDrain(tf, buf, errBuf) cmd := NewCmdDrain(tf, buf, errBuf)
saw_fatal := false saw_fatal := false
fatal_msg := "" fatal_msg := ""
func() { func() {
defer func() { defer func() {
// Recover from the panic below. // Recover from the panic below.
_ = recover() _ = recover()
// Restore cmdutil behavior // Restore cmdutil behavior
cmdutil.DefaultBehaviorOnFatal() 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) }) if test.expectFatal {
cmd.SetArgs(test.args) if !saw_fatal {
cmd.Execute() t.Fatalf("%s: unexpected non-error when using %s", test.description, currMethod)
}() }
if test.expectFatal { } else {
if !saw_fatal { if saw_fatal {
t.Fatalf("%s: unexpected non-error when using %s", test.description, currMethod) t.Fatalf("%s: unexpected error when using %s: %s", test.description, currMethod, fatal_msg)
}
} 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 { if test.expectDelete {
t.Fatalf("%s: actual warning message did not match expected warning message.\n Expecting: %s\n Got: %s", test.description, test.expectWarning, errBuf.String()) // 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 { for _, test := range tests {
tf := cmdtesting.NewTestFactory() t.Run(test.description, func(t *testing.T) {
o := DrainOptions{Factory: tf} tf := cmdtesting.NewTestFactory()
o.mapper, _ = tf.Object() defer tf.Cleanup()
o.Out = os.Stdout
_, pods := createPods(false)
pendingPods, err := o.waitForDelete(pods, test.interval, test.timeout, false, test.getPodFn)
if test.expectError { o := DrainOptions{Factory: tf}
if err == nil { o.mapper, _ = tf.Object()
t.Fatalf("%s: unexpected non-error", test.description) o.Out = os.Stdout
} else if test.expectedError != nil { _, pods := createPods(false)
if *test.expectedError != err { pendingPods, err := o.waitForDelete(pods, test.interval, test.timeout, false, test.getPodFn)
t.Fatalf("%s: the error does not match expected error", test.description)
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 {
if !test.expectError && err != nil { t.Fatalf("%s: unexpected error", test.description)
t.Fatalf("%s: unexpected error", test.description) }
} if test.expectPendingPods && len(pendingPods) == 0 {
if test.expectPendingPods && len(pendingPods) == 0 { t.Fatalf("%s: unexpected empty pods", test.description)
t.Fatalf("%s: unexpected empty pods", test.description) }
} if !test.expectPendingPods && len(pendingPods) > 0 {
if !test.expectPendingPods && len(pendingPods) > 0 { t.Fatalf("%s: unexpected pending pods", test.description)
t.Fatalf("%s: unexpected pending pods", test.description) }
} })
} }
} }

View File

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

View File

@ -130,38 +130,42 @@ func TestPodAndContainer(t *testing.T) {
}, },
} }
for _, test := range tests { for _, test := range tests {
tf := cmdtesting.NewTestFactory() t.Run(test.name, func(t *testing.T) {
ns := legacyscheme.Codecs tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{ ns := legacyscheme.Codecs
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { return nil, nil }),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
cmd := &cobra.Command{} tf.Client = &fake.RESTClient{
options := test.p NegotiatedSerializer: ns,
options.Err = bytes.NewBuffer([]byte{}) Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { return nil, nil }),
err := options.Complete(tf, cmd, test.args, test.argsLenAtDash) }
if test.expectError && err == nil { tf.Namespace = "test"
t.Errorf("%s: unexpected non-error", test.name) tf.ClientConfigVal = defaultClientConfig()
}
if !test.expectError && err != nil { cmd := &cobra.Command{}
t.Errorf("%s: unexpected error: %v", test.name, err) options := test.p
} options.Err = bytes.NewBuffer([]byte{})
if err != nil { err := options.Complete(tf, cmd, test.args, test.argsLenAtDash)
continue if test.expectError && err == nil {
} t.Errorf("%s: unexpected non-error", test.name)
if options.PodName != test.expectedPod { }
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedPod, options.PodName) if !test.expectError && err != nil {
} t.Errorf("%s: unexpected error: %v", test.name, err)
if options.ContainerName != test.expectedContainer { }
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedContainer, options.ContainerName) if err != nil {
} return
if !reflect.DeepEqual(test.expectedArgs, options.Command) { }
t.Errorf("%s: expected: %v, got %v", test.name, test.expectedArgs, options.Command) 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 { for _, test := range tests {
tf := cmdtesting.NewTestFactory() t.Run(test.name, func(t *testing.T) {
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs defer tf.Cleanup()
tf.Client = &fake.RESTClient{ codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
NegotiatedSerializer: ns, ns := legacyscheme.Codecs
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { tf.Client = &fake.RESTClient{
case p == test.podPath && m == "GET": NegotiatedSerializer: ns,
body := objBody(codec, test.pod) Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil switch p, m := req.URL.Path, req.Method; {
default: case p == test.podPath && m == "GET":
// Ensures no GET is performed when deleting by name body := objBody(codec, test.pod)
t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req) return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
return nil, fmt.Errorf("unexpected request") 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{}) tf.Namespace = "test"
bufIn := bytes.NewBuffer([]byte{}) tf.ClientConfigVal = defaultClientConfig()
ex := &fakeRemoteExecutor{} bufOut := bytes.NewBuffer([]byte{})
if test.execErr { bufErr := bytes.NewBuffer([]byte{})
ex.execErr = fmt.Errorf("exec error") bufIn := bytes.NewBuffer([]byte{})
} ex := &fakeRemoteExecutor{}
params := &ExecOptions{ if test.execErr {
StreamOptions: StreamOptions{ ex.execErr = fmt.Errorf("exec error")
PodName: "foo", }
ContainerName: "bar", params := &ExecOptions{
In: bufIn, StreamOptions: StreamOptions{
Out: bufOut, PodName: "foo",
Err: bufErr, ContainerName: "bar",
}, In: bufIn,
Executor: ex, Out: bufOut,
} Err: bufErr,
cmd := &cobra.Command{} },
args := []string{"test", "command"} Executor: ex,
if err := params.Complete(tf, cmd, args, -1); err != nil { }
t.Fatal(err) cmd := &cobra.Command{}
} args := []string{"test", "command"}
err := params.Run() if err := params.Complete(tf, cmd, args, -1); err != nil {
if test.execErr && err != ex.execErr { t.Fatal(err)
t.Errorf("%s: Unexpected exec error: %v", test.name, err) }
continue err := params.Run()
} if test.execErr && err != ex.execErr {
if !test.execErr && err != nil { t.Errorf("%s: Unexpected exec error: %v", test.name, err)
t.Errorf("%s: Unexpected error: %v", test.name, err) return
continue }
} if !test.execErr && err != nil {
if test.execErr { t.Errorf("%s: Unexpected error: %v", test.name, err)
continue return
} }
if ex.url.Path != test.execPath { if test.execErr {
t.Errorf("%s: Did not get expected path for exec request", test.name) return
continue }
} if ex.url.Path != test.execPath {
if ex.method != "POST" { t.Errorf("%s: Did not get expected path for exec request", test.name)
t.Errorf("%s: Did not get method for exec request: %s", test.name, ex.method) 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 { for _, test := range tests {
tf := cmdtesting.NewTestFactory() t.Run(test.name, func(t *testing.T) {
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs defer tf.Cleanup()
tf.Client = &fake.RESTClient{ codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
GroupVersion: schema.GroupVersion{Version: "v1"}, ns := legacyscheme.Codecs
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{})
cmd := NewCmdExposeService(tf, buf) tf.Client = &fake.RESTClient{
cmd.SetOutput(buf) GroupVersion: schema.GroupVersion{Version: "v1"},
for flag, value := range test.flags { NegotiatedSerializer: ns,
cmd.Flags().Set(flag, value) Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
} switch p, m := req.URL.Path, req.Method; {
cmd.Run(cmd, test.args) 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() cmd := NewCmdExposeService(tf, buf)
if _, ok := test.flags["dry-run"]; ok { cmd.SetOutput(buf)
test.expected = fmt.Sprintf("service %q exposed (dry run)", test.flags["name"]) for flag, value := range test.flags {
} cmd.Flags().Set(flag, value)
}
cmd.Run(cmd, test.args)
if !strings.Contains(out, test.expected) { out := buf.String()
t.Errorf("%s: Unexpected output! Expected\n%s\ngot\n%s", test.name, test.expected, out) 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 { for k, testCase := range testCases {
tf := cmdtesting.NewTestFactory() t.Run(k, func(t *testing.T) {
tf.Namespace = "test" tf := cmdtesting.NewTestFactory()
tf.ClientConfigVal = defaultClientConfig() defer tf.Cleanup()
buf := bytes.NewBuffer([]byte{}) tf.Namespace = "test"
cmd := NewCmdLabel(tf, buf) tf.ClientConfigVal = defaultClientConfig()
cmd.SetOutput(buf)
for k, v := range testCase.flags { buf := bytes.NewBuffer([]byte{})
cmd.Flags().Set(k, v) cmd := NewCmdLabel(tf, buf)
} cmd.SetOutput(buf)
opts := LabelOptions{}
err := opts.Complete(buf, cmd, testCase.args) for k, v := range testCase.flags {
if err == nil { cmd.Flags().Set(k, v)
err = opts.Validate() }
} opts := LabelOptions{}
if err == nil { err := opts.Complete(buf, cmd, testCase.args)
err = opts.RunLabel(tf, cmd) if err == nil {
} err = opts.Validate()
if !testCase.errFn(err) { }
t.Errorf("%s: unexpected error: %v", k, err) if err == nil {
continue err = opts.RunLabel(tf, cmd)
} }
if buf.Len() > 0 { if !testCase.errFn(err) {
t.Errorf("buffer should be empty: %s", string(buf.Bytes())) 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) { func TestLabelForResourceFromFile(t *testing.T) {
pods, _, _ := testData() pods, _, _ := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
@ -405,6 +411,8 @@ func TestLabelForResourceFromFile(t *testing.T) {
func TestLabelLocal(t *testing.T) { func TestLabelLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
@ -438,6 +446,8 @@ func TestLabelLocal(t *testing.T) {
func TestLabelMultipleObjects(t *testing.T) { func TestLabelMultipleObjects(t *testing.T) {
pods, _, _ := testData() pods, _, _ := testData()
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{

View File

@ -48,39 +48,43 @@ func TestLog(t *testing.T) {
}, },
} }
for _, test := range tests { for _, test := range tests {
logContent := "test log content" t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory() logContent := "test log content"
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs defer tf.Cleanup()
tf.Client = &fake.RESTClient{ codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
NegotiatedSerializer: ns, ns := legacyscheme.Codecs
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{})
cmd := NewCmdLogs(tf, buf, buf) tf.Client = &fake.RESTClient{
cmd.Flags().Set("namespace", "test") NegotiatedSerializer: ns,
cmd.Run(cmd, []string{"foo"}) 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 { cmd := NewCmdLogs(tf, buf, buf)
t.Errorf("%s: did not get expected log content. Got: %s", test.name, buf.String()) 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) { func TestValidateLogFlags(t *testing.T) {
f := cmdtesting.NewTestFactory() f := cmdtesting.NewTestFactory()
defer f.Cleanup()
tests := []struct { tests := []struct {
name string name string
@ -152,6 +157,7 @@ func TestValidateLogFlags(t *testing.T) {
func TestLogComplete(t *testing.T) { func TestLogComplete(t *testing.T) {
f := cmdtesting.NewTestFactory() f := cmdtesting.NewTestFactory()
defer f.Cleanup()
tests := []struct { tests := []struct {
name string name string

View File

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

View File

@ -80,34 +80,38 @@ func TestPluginCmd(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
inBuf := bytes.NewBuffer([]byte{}) t.Run(test.name, func(t *testing.T) {
outBuf := bytes.NewBuffer([]byte{}) inBuf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{}) outBuf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmdutil.BehaviorOnFatal(func(str string, code int) { cmdutil.BehaviorOnFatal(func(str string, code int) {
errBuf.Write([]byte(str)) errBuf.Write([]byte(str))
}) })
runner := &mockPluginRunner{ runner := &mockPluginRunner{
success: test.expectedSuccess, 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)
} }
continue
}
cmd.Run(cmd, []string{})
if test.expectedSuccess && outBuf.String() != fmt.Sprintf("ok: %s", test.plugin.Name) { f := cmdtesting.NewTestFactory()
t.Errorf("%s: unexpected output: %q", test.name, outBuf.String()) defer f.Cleanup()
}
if !test.expectedSuccess && errBuf.String() != fmt.Sprintf("error: oops %s", test.plugin.Name) { cmd := NewCmdForPlugin(f, test.plugin, runner, inBuf, outBuf, errBuf)
t.Errorf("%s: unexpected err output: %q", test.name, errBuf.String()) 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 { for _, test := range tests {
var err error t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory() var err error
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs defer tf.Cleanup()
tf.Client = &fake.RESTClient{ codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
VersionedAPIPath: "/api/v1", ns := legacyscheme.Codecs
GroupVersion: schema.GroupVersion{Group: ""},
NegotiatedSerializer: ns, tf.Client = &fake.RESTClient{
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { VersionedAPIPath: "/api/v1",
switch p, m := req.URL.Path, req.Method; { GroupVersion: schema.GroupVersion{Group: ""},
case p == test.podPath && m == "GET": NegotiatedSerializer: ns,
body := objBody(codec, test.pod) Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil switch p, m := req.URL.Path, req.Method; {
default: case p == test.podPath && m == "GET":
// Ensures no GET is performed when deleting by name body := objBody(codec, test.pod)
t.Errorf("%s: unexpected request: %#v\n%#v", test.name, req.URL, req) return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
return nil, 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
} }
}), opts.PortForwarder = ff
} if err = opts.Validate(); err != nil {
tf.Namespace = "test" return
tf.ClientConfigVal = defaultClientConfig() }
ff := &fakePortForwarder{} err = opts.RunPortForward()
if test.pfErr { }
ff.pfErr = fmt.Errorf("pf error")
}
opts := &PortForwardOptions{} for name, value := range flags {
cmd := NewCmdPortForward(tf, os.Stdout, os.Stderr) cmd.Flags().Set(name, value)
cmd.Run = func(cmd *cobra.Command, args []string) { }
if err = opts.Complete(tf, cmd, args); err != nil { 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 return
} }
opts.PortForwarder = ff
if err = opts.Validate(); err != nil { if ff.url == nil || ff.url.Path != test.pfPath {
return t.Errorf("%s: Did not get expected path for portforward request", test.name)
} }
err = opts.RunPortForward() if ff.method != "POST" {
} t.Errorf("%s: Did not get method for attach request: %s", test.name, ff.method)
}
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)
}
} }
} }

View File

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

View File

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

View File

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

View File

@ -168,35 +168,39 @@ func TestRunArgsFollowDashRules(t *testing.T) {
}, },
} }
for _, test := range tests { for _, test := range tests {
tf := cmdtesting.NewTestFactory() t.Run(test.name, func(t *testing.T) {
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs defer tf.Cleanup()
tf.Client = &fake.RESTClient{ codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
GroupVersion: schema.GroupVersion{Version: "v1"}, ns := legacyscheme.Codecs
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { tf.Client = &fake.RESTClient{
if req.URL.Path == "/namespaces/test/replicationcontrollers" { GroupVersion: schema.GroupVersion{Version: "v1"},
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: objBody(codec, rc)}, nil NegotiatedSerializer: ns,
} Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
return &http.Response{ if req.URL.Path == "/namespaces/test/replicationcontrollers" {
StatusCode: http.StatusOK, return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: objBody(codec, rc)}, nil
Body: ioutil.NopCloser(bytes.NewBuffer([]byte("{}"))), }
}, nil return &http.Response{
}), StatusCode: http.StatusOK,
} Body: ioutil.NopCloser(bytes.NewBuffer([]byte("{}"))),
tf.Namespace = "test" }, nil
tf.ClientConfigVal = &restclient.Config{} }),
cmd := NewCmdRun(tf, os.Stdin, os.Stdout, os.Stderr) }
cmd.Flags().Set("image", "nginx") tf.Namespace = "test"
cmd.Flags().Set("generator", "run/v1") tf.ClientConfigVal = &restclient.Config{}
err := RunRun(tf, os.Stdin, os.Stdout, os.Stderr, cmd, test.args, test.argsLenAtDash) cmd := NewCmdRun(tf, os.Stdin, os.Stdout, os.Stderr)
if test.expectError && err == nil { cmd.Flags().Set("image", "nginx")
t.Errorf("unexpected non-error (%s)", test.name) 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 { if test.expectError && err == nil {
t.Errorf("unexpected error: %v (%s)", err, test.name) 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 { for _, test := range tests {
sawPOST := false t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory() sawPOST := false
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs defer tf.Cleanup()
tf.ClientConfigVal = defaultClientConfig() codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.Client = &fake.RESTClient{ ns := legacyscheme.Codecs
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: ns, tf.ClientConfigVal = defaultClientConfig()
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { tf.Client = &fake.RESTClient{
switch p, m := req.URL.Path, req.Method; { GroupVersion: schema.GroupVersion{Version: "v1"},
case test.expectPOST && m == "POST" && p == "/namespaces/namespace/services": NegotiatedSerializer: ns,
sawPOST = true Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
body := objBody(codec, &test.service) switch p, m := req.URL.Path, req.Method; {
data, err := ioutil.ReadAll(req.Body) case test.expectPOST && m == "POST" && p == "/namespaces/namespace/services":
if err != nil { sawPOST = true
t.Fatalf("unexpected error: %v", err) 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 cmd := &cobra.Command{}
} cmd.Flags().Bool(cmdutil.ApplyAnnotationsFlag, false, "")
if err != nil { 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.")
t.Errorf("unexpected error: %v", err) cmdutil.AddPrinterFlags(cmd)
} cmdutil.AddInclude3rdPartyFlags(cmd)
if test.expectPOST != sawPOST { addRunFlags(cmd)
t.Errorf("expectPost: %v, sawPost: %v", test.expectPOST, sawPOST)
} 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) { func TestRunValidations(t *testing.T) {
tests := []struct { tests := []struct {
name string
args []string args []string
flags map[string]string flags map[string]string
expectedErr string expectedErr string
}{ }{
{ {
name: "test missing name error",
expectedErr: "NAME is required", expectedErr: "NAME is required",
}, },
{ {
name: "test missing --image error",
args: []string{"test"}, args: []string{"test"},
expectedErr: "--image is required", expectedErr: "--image is required",
}, },
{ {
name: "test invalid image name error",
args: []string{"test"}, args: []string{"test"},
flags: map[string]string{ flags: map[string]string{
"image": "#", "image": "#",
@ -383,6 +395,7 @@ func TestRunValidations(t *testing.T) {
expectedErr: "Invalid image name", expectedErr: "Invalid image name",
}, },
{ {
name: "test stdin replicas value",
args: []string{"test"}, args: []string{"test"},
flags: map[string]string{ flags: map[string]string{
"image": "busybox", "image": "busybox",
@ -392,6 +405,7 @@ func TestRunValidations(t *testing.T) {
expectedErr: "stdin requires that replicas is 1", expectedErr: "stdin requires that replicas is 1",
}, },
{ {
name: "test rm errors when used on non-attached containers",
args: []string{"test"}, args: []string{"test"},
flags: map[string]string{ flags: map[string]string{
"image": "busybox", "image": "busybox",
@ -400,6 +414,7 @@ func TestRunValidations(t *testing.T) {
expectedErr: "rm should only be used for attached containers", expectedErr: "rm should only be used for attached containers",
}, },
{ {
name: "test error on attached containers options",
args: []string{"test"}, args: []string{"test"},
flags: map[string]string{ flags: map[string]string{
"image": "busybox", "image": "busybox",
@ -409,6 +424,7 @@ func TestRunValidations(t *testing.T) {
expectedErr: "can't be used with attached containers options", expectedErr: "can't be used with attached containers options",
}, },
{ {
name: "test error on attached containers options, with value from stdin",
args: []string{"test"}, args: []string{"test"},
flags: map[string]string{ flags: map[string]string{
"image": "busybox", "image": "busybox",
@ -418,6 +434,7 @@ func TestRunValidations(t *testing.T) {
expectedErr: "can't be used with attached containers options", 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"}, args: []string{"test"},
flags: map[string]string{ flags: map[string]string{
"image": "busybox", "image": "busybox",
@ -428,6 +445,7 @@ func TestRunValidations(t *testing.T) {
expectedErr: "can't be used with attached containers options", expectedErr: "can't be used with attached containers options",
}, },
{ {
name: "test error when tty=true and no stdin provided",
args: []string{"test"}, args: []string{"test"},
flags: map[string]string{ flags: map[string]string{
"image": "busybox", "image": "busybox",
@ -437,28 +455,32 @@ func TestRunValidations(t *testing.T) {
}, },
} }
for _, test := range tests { for _, test := range tests {
tf := cmdtesting.NewTestFactory() t.Run(test.name, func(t *testing.T) {
_, _, codec := cmdtesting.NewExternalScheme() tf := cmdtesting.NewTestFactory()
tf.Client = &fake.RESTClient{ defer tf.Cleanup()
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) _, _, codec := cmdtesting.NewExternalScheme()
for flagName, flagValue := range test.flags { tf.Client = &fake.RESTClient{
cmd.Flags().Set(flagName, flagValue) NegotiatedSerializer: scheme.Codecs,
} Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, cmdtesting.NewInternalType("", "", ""))},
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)
} }
} 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) { func TestSetEnvLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{ tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: ""}, GroupVersion: schema.GroupVersion{Version: ""},
@ -83,6 +85,8 @@ func TestSetEnvLocal(t *testing.T) {
func TestSetMultiResourcesEnvLocal(t *testing.T) { func TestSetMultiResourcesEnvLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{ tf.Client = &fake.RESTClient{
@ -122,12 +126,14 @@ func TestSetMultiResourcesEnvLocal(t *testing.T) {
func TestSetEnvRemote(t *testing.T) { func TestSetEnvRemote(t *testing.T) {
inputs := []struct { inputs := []struct {
name string
object runtime.Object object runtime.Object
apiPrefix, apiGroup, apiVersion string apiPrefix, apiGroup, apiVersion string
testAPIGroup string testAPIGroup string
args []string args []string
}{ }{
{ {
name: "test extensions.v1beta1 replicaset",
object: &extensionsv1beta1.ReplicaSet{ object: &extensionsv1beta1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: extensionsv1beta1.ReplicaSetSpec{ Spec: extensionsv1beta1.ReplicaSetSpec{
@ -148,6 +154,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"replicaset", "nginx", "env=prod"}, args: []string{"replicaset", "nginx", "env=prod"},
}, },
{ {
name: "test apps.v1beta2 replicaset",
object: &appsv1beta2.ReplicaSet{ object: &appsv1beta2.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.ReplicaSetSpec{ Spec: appsv1beta2.ReplicaSetSpec{
@ -168,6 +175,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"replicaset", "nginx", "env=prod"}, args: []string{"replicaset", "nginx", "env=prod"},
}, },
{ {
name: "test appsv1 replicaset",
object: &appsv1.ReplicaSet{ object: &appsv1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.ReplicaSetSpec{ Spec: appsv1.ReplicaSetSpec{
@ -188,6 +196,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"replicaset", "nginx", "env=prod"}, args: []string{"replicaset", "nginx", "env=prod"},
}, },
{ {
name: "test extensions.v1beta1 daemonset",
object: &extensionsv1beta1.DaemonSet{ object: &extensionsv1beta1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: extensionsv1beta1.DaemonSetSpec{ Spec: extensionsv1beta1.DaemonSetSpec{
@ -208,6 +217,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"daemonset", "nginx", "env=prod"}, args: []string{"daemonset", "nginx", "env=prod"},
}, },
{ {
name: "test appsv1beta2 daemonset",
object: &appsv1beta2.DaemonSet{ object: &appsv1beta2.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.DaemonSetSpec{ Spec: appsv1beta2.DaemonSetSpec{
@ -228,6 +238,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"daemonset", "nginx", "env=prod"}, args: []string{"daemonset", "nginx", "env=prod"},
}, },
{ {
name: "test appsv1 daemonset",
object: &appsv1.DaemonSet{ object: &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.DaemonSetSpec{ Spec: appsv1.DaemonSetSpec{
@ -248,6 +259,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"daemonset", "nginx", "env=prod"}, args: []string{"daemonset", "nginx", "env=prod"},
}, },
{ {
name: "test extensions.v1beta1 deployment",
object: &extensionsv1beta1.Deployment{ object: &extensionsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: extensionsv1beta1.DeploymentSpec{ Spec: extensionsv1beta1.DeploymentSpec{
@ -268,6 +280,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"deployment", "nginx", "env=prod"}, args: []string{"deployment", "nginx", "env=prod"},
}, },
{ {
name: "test appsv1bta1 deployment",
object: &appsv1beta1.Deployment{ object: &appsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta1.DeploymentSpec{ Spec: appsv1beta1.DeploymentSpec{
@ -288,6 +301,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"deployment", "nginx", "env=prod"}, args: []string{"deployment", "nginx", "env=prod"},
}, },
{ {
name: "test appsv1beta2n deployment",
object: &appsv1beta2.Deployment{ object: &appsv1beta2.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.DeploymentSpec{ Spec: appsv1beta2.DeploymentSpec{
@ -308,6 +322,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"deployment", "nginx", "env=prod"}, args: []string{"deployment", "nginx", "env=prod"},
}, },
{ {
name: "test appsv1 deployment",
object: &appsv1.Deployment{ object: &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.DeploymentSpec{ Spec: appsv1.DeploymentSpec{
@ -328,6 +343,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"deployment", "nginx", "env=prod"}, args: []string{"deployment", "nginx", "env=prod"},
}, },
{ {
name: "test appsv1beta1 statefulset",
object: &appsv1beta1.StatefulSet{ object: &appsv1beta1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta1.StatefulSetSpec{ Spec: appsv1beta1.StatefulSetSpec{
@ -348,6 +364,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"statefulset", "nginx", "env=prod"}, args: []string{"statefulset", "nginx", "env=prod"},
}, },
{ {
name: "test appsv1beta2 statefulset",
object: &appsv1beta2.StatefulSet{ object: &appsv1beta2.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.StatefulSetSpec{ Spec: appsv1beta2.StatefulSetSpec{
@ -368,6 +385,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"statefulset", "nginx", "env=prod"}, args: []string{"statefulset", "nginx", "env=prod"},
}, },
{ {
name: "test appsv1 statefulset",
object: &appsv1.StatefulSet{ object: &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.StatefulSetSpec{ Spec: appsv1.StatefulSetSpec{
@ -429,48 +447,52 @@ func TestSetEnvRemote(t *testing.T) {
}, },
} }
for _, input := range inputs { for _, input := range inputs {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion} t.Run(input.name, func(t *testing.T) {
testapi.Default = testapi.Groups[input.testAPIGroup] groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
tf := cmdtesting.NewTestFactory() testapi.Default = testapi.Groups[input.testAPIGroup]
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion) tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs defer tf.Cleanup()
tf.Namespace = "test"
tf.Client = &fake.RESTClient{ codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
GroupVersion: groupVersion, ns := legacyscheme.Codecs
NegotiatedSerializer: ns, tf.Namespace = "test"
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { tf.Client = &fake.RESTClient{
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1]) GroupVersion: groupVersion,
switch p, m := req.URL.Path, req.Method; { NegotiatedSerializer: ns,
case p == resourcePath && m == http.MethodGet: Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
case p == resourcePath && m == http.MethodPatch: switch p, m := req.URL.Path, req.Method; {
stream, err := req.GetBody() case p == resourcePath && m == http.MethodGet:
if err != nil { return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
return nil, err 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 { VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()),
return nil, err }
} out := new(bytes.Buffer)
assert.Contains(t, string(bytes), `"value":`+`"`+"prod"+`"`, fmt.Sprintf("env not updated for %#v", input.object)) cmd := NewCmdEnv(tf, out, out, out)
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil cmd.SetOutput(out)
default: cmd.Flags().Set("output", "yaml")
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req) opts := EnvOptions{
return nil, fmt.Errorf("unexpected request") Out: out,
} Local: false}
}), err := opts.Complete(tf, cmd, input.args)
VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()), assert.NoError(t, err)
} err = opts.RunEnv(tf)
out := new(bytes.Buffer) assert.NoError(t, err)
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) { func TestImageLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{ tf.Client = &fake.RESTClient{
@ -149,6 +151,8 @@ func TestSetImageValidation(t *testing.T) {
func TestSetMultiResourcesImageLocal(t *testing.T) { func TestSetMultiResourcesImageLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{ tf.Client = &fake.RESTClient{
@ -190,12 +194,14 @@ func TestSetMultiResourcesImageLocal(t *testing.T) {
func TestSetImageRemote(t *testing.T) { func TestSetImageRemote(t *testing.T) {
inputs := []struct { inputs := []struct {
name string
object runtime.Object object runtime.Object
apiPrefix, apiGroup, apiVersion string apiPrefix, apiGroup, apiVersion string
testAPIGroup string testAPIGroup string
args []string args []string
}{ }{
{ {
name: "set image extensionsv1beta1 ReplicaSet",
object: &extensionsv1beta1.ReplicaSet{ object: &extensionsv1beta1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: extensionsv1beta1.ReplicaSetSpec{ Spec: extensionsv1beta1.ReplicaSetSpec{
@ -216,6 +222,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"replicaset", "nginx", "*=thingy"}, args: []string{"replicaset", "nginx", "*=thingy"},
}, },
{ {
name: "set image appsv1beta2 ReplicaSet",
object: &appsv1beta2.ReplicaSet{ object: &appsv1beta2.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.ReplicaSetSpec{ Spec: appsv1beta2.ReplicaSetSpec{
@ -236,6 +243,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"replicaset", "nginx", "*=thingy"}, args: []string{"replicaset", "nginx", "*=thingy"},
}, },
{ {
name: "set image appsv1 ReplicaSet",
object: &appsv1.ReplicaSet{ object: &appsv1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.ReplicaSetSpec{ Spec: appsv1.ReplicaSetSpec{
@ -256,6 +264,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"replicaset", "nginx", "*=thingy"}, args: []string{"replicaset", "nginx", "*=thingy"},
}, },
{ {
name: "set image extensionsv1beta1 DaemonSet",
object: &extensionsv1beta1.DaemonSet{ object: &extensionsv1beta1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: extensionsv1beta1.DaemonSetSpec{ Spec: extensionsv1beta1.DaemonSetSpec{
@ -276,6 +285,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"daemonset", "nginx", "*=thingy"}, args: []string{"daemonset", "nginx", "*=thingy"},
}, },
{ {
name: "set image appsv1beta2 DaemonSet",
object: &appsv1beta2.DaemonSet{ object: &appsv1beta2.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.DaemonSetSpec{ Spec: appsv1beta2.DaemonSetSpec{
@ -296,6 +306,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"daemonset", "nginx", "*=thingy"}, args: []string{"daemonset", "nginx", "*=thingy"},
}, },
{ {
name: "set image appsv1 DaemonSet",
object: &appsv1.DaemonSet{ object: &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.DaemonSetSpec{ Spec: appsv1.DaemonSetSpec{
@ -316,6 +327,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"daemonset", "nginx", "*=thingy"}, args: []string{"daemonset", "nginx", "*=thingy"},
}, },
{ {
name: "set image extensionsv1beta1 Deployment",
object: &extensionsv1beta1.Deployment{ object: &extensionsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: extensionsv1beta1.DeploymentSpec{ Spec: extensionsv1beta1.DeploymentSpec{
@ -336,6 +348,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"deployment", "nginx", "*=thingy"}, args: []string{"deployment", "nginx", "*=thingy"},
}, },
{ {
name: "set image appsv1beta1 Deployment",
object: &appsv1beta1.Deployment{ object: &appsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta1.DeploymentSpec{ Spec: appsv1beta1.DeploymentSpec{
@ -356,6 +369,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"deployment", "nginx", "*=thingy"}, args: []string{"deployment", "nginx", "*=thingy"},
}, },
{ {
name: "set image appsv1beta2 Deployment",
object: &appsv1beta2.Deployment{ object: &appsv1beta2.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.DeploymentSpec{ Spec: appsv1beta2.DeploymentSpec{
@ -376,6 +390,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"deployment", "nginx", "*=thingy"}, args: []string{"deployment", "nginx", "*=thingy"},
}, },
{ {
name: "set image appsv1 Deployment",
object: &appsv1.Deployment{ object: &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.DeploymentSpec{ Spec: appsv1.DeploymentSpec{
@ -396,6 +411,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"deployment", "nginx", "*=thingy"}, args: []string{"deployment", "nginx", "*=thingy"},
}, },
{ {
name: "set image appsv1beta1 StatefulSet",
object: &appsv1beta1.StatefulSet{ object: &appsv1beta1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta1.StatefulSetSpec{ Spec: appsv1beta1.StatefulSetSpec{
@ -416,6 +432,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"statefulset", "nginx", "*=thingy"}, args: []string{"statefulset", "nginx", "*=thingy"},
}, },
{ {
name: "set image appsv1beta2 StatefulSet",
object: &appsv1beta2.StatefulSet{ object: &appsv1beta2.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.StatefulSetSpec{ Spec: appsv1beta2.StatefulSetSpec{
@ -436,6 +453,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"statefulset", "nginx", "*=thingy"}, args: []string{"statefulset", "nginx", "*=thingy"},
}, },
{ {
name: "set image appsv1 StatefulSet",
object: &appsv1.StatefulSet{ object: &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.StatefulSetSpec{ Spec: appsv1.StatefulSetSpec{
@ -456,6 +474,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"statefulset", "nginx", "*=thingy"}, args: []string{"statefulset", "nginx", "*=thingy"},
}, },
{ {
name: "set image batchv1 Job",
object: &batchv1.Job{ object: &batchv1.Job{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: batchv1.JobSpec{ Spec: batchv1.JobSpec{
@ -476,6 +495,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"job", "nginx", "*=thingy"}, args: []string{"job", "nginx", "*=thingy"},
}, },
{ {
name: "set image v1.ReplicationController",
object: &v1.ReplicationController{ object: &v1.ReplicationController{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"}, ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: v1.ReplicationControllerSpec{ Spec: v1.ReplicationControllerSpec{
@ -497,48 +517,52 @@ func TestSetImageRemote(t *testing.T) {
}, },
} }
for _, input := range inputs { for _, input := range inputs {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion} t.Run(input.name, func(t *testing.T) {
testapi.Default = testapi.Groups[input.testAPIGroup] groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
tf := cmdtesting.NewTestFactory() testapi.Default = testapi.Groups[input.testAPIGroup]
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion) tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs defer tf.Cleanup()
tf.Namespace = "test"
tf.Client = &fake.RESTClient{ codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
GroupVersion: groupVersion, ns := legacyscheme.Codecs
NegotiatedSerializer: ns, tf.Namespace = "test"
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { tf.Client = &fake.RESTClient{
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1]) GroupVersion: groupVersion,
switch p, m := req.URL.Path, req.Method; { NegotiatedSerializer: ns,
case p == resourcePath && m == http.MethodGet: Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
case p == resourcePath && m == http.MethodPatch: switch p, m := req.URL.Path, req.Method; {
stream, err := req.GetBody() case p == resourcePath && m == http.MethodGet:
if err != nil { return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
return nil, err 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 { VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()),
return nil, err }
} out := new(bytes.Buffer)
assert.Contains(t, string(bytes), `"image":`+`"`+"thingy"+`"`, fmt.Sprintf("image not updated for %#v", input.object)) cmd := NewCmdImage(tf, out, out)
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil cmd.SetOutput(out)
default: cmd.Flags().Set("output", "yaml")
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req) opts := ImageOptions{
return nil, fmt.Errorf("unexpected request") Out: out,
} Local: false}
}), err := opts.Complete(tf, cmd, input.args)
VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()), assert.NoError(t, err)
} err = opts.Run()
out := new(bytes.Buffer) assert.NoError(t, err)
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) { func TestResourcesLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{ tf.Client = &fake.RESTClient{
@ -90,6 +91,7 @@ func TestResourcesLocal(t *testing.T) {
func TestSetMultiResourcesLimitsLocal(t *testing.T) { func TestSetMultiResourcesLimitsLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{ tf.Client = &fake.RESTClient{
@ -446,6 +448,7 @@ func TestSetResourcesRemote(t *testing.T) {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion} groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup] testapi.Default = testapi.Groups[input.testAPIGroup]
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion) codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
ns := legacyscheme.Codecs ns := legacyscheme.Codecs
tf.Namespace = "test" tf.Namespace = "test"

View File

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

View File

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

View File

@ -236,102 +236,106 @@ func TestTaint(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
oldNode, expectNewNode := generateNodeAndTaintedNode(test.oldTaints, test.newTaints) t.Run(test.description, func(t *testing.T) {
new_node := &v1.Node{} oldNode, expectNewNode := generateNodeAndTaintedNode(test.oldTaints, test.newTaints)
tainted := false new_node := &v1.Node{}
tf := cmdtesting.NewTestFactory() tainted := false
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs defer tf.Cleanup()
tf.Client = &fake.RESTClient{ codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
NegotiatedSerializer: ns, ns := legacyscheme.Codecs
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()
// apply the patch tf.Client = &fake.RESTClient{
oldJSON, err := runtime.Encode(codec, oldNode) NegotiatedSerializer: ns,
if err != nil { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
t.Fatalf("%s: unexpected error: %v", test.description, err) m := &MyReq{req}
} switch {
appliedPatch, err := strategicpatch.StrategicMergePatch(oldJSON, data, &v1.Node{}) case m.isFor("GET", "/nodes"):
if err != nil { return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, oldNode)}, nil
t.Fatalf("%s: unexpected error: %v", test.description, err) 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 // apply the patch
if err := runtime.DecodeInto(codec, appliedPatch, new_node); err != nil { oldJSON, err := runtime.Encode(codec, oldNode)
t.Fatalf("%s: unexpected error: %v", test.description, err) if 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) appliedPatch, err := strategicpatch.StrategicMergePatch(oldJSON, data, &v1.Node{})
} if err != nil {
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, new_node)}, nil t.Fatalf("%s: unexpected error: %v", test.description, err)
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()
buf := bytes.NewBuffer([]byte{}) // decode the patch
cmd := NewCmdTaint(tf, buf) 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 buf := bytes.NewBuffer([]byte{})
func() { cmd := NewCmdTaint(tf, buf)
defer func() {
// Recover from the panic below. saw_fatal := false
_ = recover() func() {
// Restore cmdutil behavior defer func() {
cmdutil.DefaultBehaviorOnFatal() // 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 test.expectFatal {
if !saw_fatal { if !saw_fatal {
t.Fatalf("%s: unexpected non-error", test.description) t.Fatalf("%s: unexpected non-error", test.description)
}
} }
}
if test.expectTaint { if test.expectTaint {
if !tainted { if !tainted {
t.Fatalf("%s: node not tainted", test.description) t.Fatalf("%s: node not tainted", test.description)
}
} }
} if !test.expectTaint {
if !test.expectTaint { if tainted {
if tainted { t.Fatalf("%s: unexpected taint", test.description)
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/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/rest: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/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 package testing
import ( import (
"bytes"
"errors" "errors"
"fmt" "fmt"
"io/ioutil"
"os"
"path/filepath" "path/filepath"
"time" "time"
@ -34,6 +37,8 @@ import (
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest" restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake" "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" "k8s.io/kubernetes/pkg/api/legacyscheme"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
@ -240,16 +245,55 @@ type TestFactory struct {
ClientConfigVal *restclient.Config ClientConfigVal *restclient.Config
CommandVal string CommandVal string
tempConfigFile *os.File
UnstructuredClientForMappingFunc func(mapping *meta.RESTMapping) (resource.RESTClient, error) UnstructuredClientForMappingFunc func(mapping *meta.RESTMapping) (resource.RESTClient, error)
OpenAPISchemaFunc func() (openapi.Resources, error) OpenAPISchemaFunc func() (openapi.Resources, error)
} }
func NewTestFactory() *TestFactory { func NewTestFactory() *TestFactory {
// specify an optionalClientConfig to explicitly use in testing
// to avoid polluting an existing user config.
config, configFile := defaultFakeClientConfig()
return &TestFactory{ 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 { func (f *TestFactory) CategoryExpander() categories.CategoryExpander {
return categories.LegacyCategoryExpander return categories.LegacyCategoryExpander
} }

View File

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

View File

@ -134,90 +134,94 @@ func TestTopPod(t *testing.T) {
} }
initTestErrorHandler(t) initTestErrorHandler(t)
for _, testCase := range testCases { for _, testCase := range testCases {
t.Logf("Running test case: %s", testCase.name) t.Run(testCase.name, func(t *testing.T) {
metricsList := testPodMetricsData() t.Logf("Running test case: %s", testCase.name)
var expectedMetrics []metricsv1alpha1api.PodMetrics metricsList := testPodMetricsData()
var expectedContainerNames, nonExpectedMetricsNames []string var expectedMetrics []metricsv1alpha1api.PodMetrics
for n, m := range metricsList { var expectedContainerNames, nonExpectedMetricsNames []string
if n < len(testCase.namespaces) { for n, m := range metricsList {
m.Namespace = testCase.namespaces[n] if n < len(testCase.namespaces) {
expectedMetrics = append(expectedMetrics, m) m.Namespace = testCase.namespaces[n]
for _, c := range m.Containers { expectedMetrics = append(expectedMetrics, m)
expectedContainerNames = append(expectedContainerNames, c.Name) 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)
} }
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil } else {
default: nonExpectedMetricsNames = append(nonExpectedMetricsNames, m.Name)
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)
} }
} }
}
for _, m := range expectedMetrics { var response interface{}
if !strings.Contains(result, m.Name) { if len(expectedMetrics) == 1 {
t.Errorf("%s: missing metrics for %s: \n%s", testCase.name, m.Name, result) 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
}
}),
} }
} tf.Namespace = testNS
for _, name := range nonExpectedMetricsNames { tf.ClientConfigVal = defaultClientConfig()
if strings.Contains(result, name) { buf := bytes.NewBuffer([]byte{})
t.Errorf("%s: unexpected metrics for %s: \n%s", testCase.name, name, result)
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() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{ tf.Client = &fake.RESTClient{
@ -471,98 +477,102 @@ func TestTopPodCustomDefaults(t *testing.T) {
} }
initTestErrorHandler(t) initTestErrorHandler(t)
for _, testCase := range testCases { for _, testCase := range testCases {
t.Logf("Running test case: %s", testCase.name) t.Run(testCase.name, func(t *testing.T) {
metricsList := testPodMetricsData() t.Logf("Running test case: %s", testCase.name)
var expectedMetrics []metricsv1alpha1api.PodMetrics metricsList := testPodMetricsData()
var expectedContainerNames, nonExpectedMetricsNames []string var expectedMetrics []metricsv1alpha1api.PodMetrics
for n, m := range metricsList { var expectedContainerNames, nonExpectedMetricsNames []string
if n < len(testCase.namespaces) { for n, m := range metricsList {
m.Namespace = testCase.namespaces[n] if n < len(testCase.namespaces) {
expectedMetrics = append(expectedMetrics, m) m.Namespace = testCase.namespaces[n]
for _, c := range m.Containers { expectedMetrics = append(expectedMetrics, m)
expectedContainerNames = append(expectedContainerNames, c.Name) 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)
} }
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil } else {
default: nonExpectedMetricsNames = append(nonExpectedMetricsNames, m.Name)
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)
} }
} }
}
for _, m := range expectedMetrics { var response interface{}
if !strings.Contains(result, m.Name) { if len(expectedMetrics) == 1 {
t.Errorf("%s: missing metrics for %s: \n%s", testCase.name, m.Name, result) 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
}
}),
} }
} tf.Namespace = testNS
for _, name := range nonExpectedMetricsNames { tf.ClientConfigVal = defaultClientConfig()
if strings.Contains(result, name) { buf := bytes.NewBuffer([]byte{})
t.Errorf("%s: unexpected metrics for %s: \n%s", testCase.name, name, result)
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) initTestErrorHandler(t)
f := cmdtesting.NewTestFactory() f := cmdtesting.NewTestFactory()
defer f.Cleanup()
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
cmd := NewCmdTop(f, buf, buf) cmd := NewCmdTop(f, buf, buf)