React to moves

parent 33adf367
...@@ -27,6 +27,7 @@ import ( ...@@ -27,6 +27,7 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/genericclioptions/resource"
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/kubectl/scheme"
...@@ -420,7 +421,7 @@ func TestAnnotateErrors(t *testing.T) { ...@@ -420,7 +421,7 @@ func TestAnnotateErrors(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup() defer tf.Cleanup()
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
iostreams, _, bufOut, bufErr := genericclioptions.NewTestIOStreams() iostreams, _, bufOut, bufErr := genericclioptions.NewTestIOStreams()
cmd := NewCmdAnnotate("kubectl", tf, iostreams) cmd := NewCmdAnnotate("kubectl", tf, iostreams)
...@@ -449,7 +450,7 @@ func TestAnnotateErrors(t *testing.T) { ...@@ -449,7 +450,7 @@ func TestAnnotateErrors(t *testing.T) {
} }
func TestAnnotateObject(t *testing.T) { func TestAnnotateObject(t *testing.T) {
pods, _, _ := testData() pods, _, _ := cmdtesting.TestData()
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup() defer tf.Cleanup()
...@@ -458,13 +459,13 @@ func TestAnnotateObject(t *testing.T) { ...@@ -458,13 +459,13 @@ func TestAnnotateObject(t *testing.T) {
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: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch req.Method { switch req.Method {
case "GET": case "GET":
switch req.URL.Path { switch req.URL.Path {
case "/namespaces/test/pods/foo": case "/namespaces/test/pods/foo":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &pods.Items[0])}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &pods.Items[0])}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -472,7 +473,7 @@ func TestAnnotateObject(t *testing.T) { ...@@ -472,7 +473,7 @@ func TestAnnotateObject(t *testing.T) {
case "PATCH": case "PATCH":
switch req.URL.Path { switch req.URL.Path {
case "/namespaces/test/pods/foo": case "/namespaces/test/pods/foo":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &pods.Items[0])}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &pods.Items[0])}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -483,7 +484,7 @@ func TestAnnotateObject(t *testing.T) { ...@@ -483,7 +484,7 @@ func TestAnnotateObject(t *testing.T) {
} }
}), }),
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
iostreams, _, bufOut, _ := genericclioptions.NewTestIOStreams() iostreams, _, bufOut, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdAnnotate("kubectl", tf, iostreams) cmd := NewCmdAnnotate("kubectl", tf, iostreams)
...@@ -502,7 +503,7 @@ func TestAnnotateObject(t *testing.T) { ...@@ -502,7 +503,7 @@ func TestAnnotateObject(t *testing.T) {
} }
func TestAnnotateObjectFromFile(t *testing.T) { func TestAnnotateObjectFromFile(t *testing.T) {
pods, _, _ := testData() pods, _, _ := cmdtesting.TestData()
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup() defer tf.Cleanup()
...@@ -511,13 +512,13 @@ func TestAnnotateObjectFromFile(t *testing.T) { ...@@ -511,13 +512,13 @@ func TestAnnotateObjectFromFile(t *testing.T) {
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: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch req.Method { switch req.Method {
case "GET": case "GET":
switch req.URL.Path { switch req.URL.Path {
case "/namespaces/test/replicationcontrollers/cassandra": case "/namespaces/test/replicationcontrollers/cassandra":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &pods.Items[0])}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &pods.Items[0])}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -525,7 +526,7 @@ func TestAnnotateObjectFromFile(t *testing.T) { ...@@ -525,7 +526,7 @@ func TestAnnotateObjectFromFile(t *testing.T) {
case "PATCH": case "PATCH":
switch req.URL.Path { switch req.URL.Path {
case "/namespaces/test/replicationcontrollers/cassandra": case "/namespaces/test/replicationcontrollers/cassandra":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &pods.Items[0])}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &pods.Items[0])}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -536,13 +537,13 @@ func TestAnnotateObjectFromFile(t *testing.T) { ...@@ -536,13 +537,13 @@ func TestAnnotateObjectFromFile(t *testing.T) {
} }
}), }),
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
iostreams, _, bufOut, _ := genericclioptions.NewTestIOStreams() iostreams, _, bufOut, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdAnnotate("kubectl", tf, iostreams) cmd := NewCmdAnnotate("kubectl", tf, iostreams)
cmd.SetOutput(bufOut) cmd.SetOutput(bufOut)
options := NewAnnotateOptions(iostreams) options := NewAnnotateOptions(iostreams)
options.Filenames = []string{"../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"} options.Filenames = []string{"../../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}
args := []string{"a=b", "c-"} args := []string{"a=b", "c-"}
if err := options.Complete(tf, cmd, args); err != nil { if err := options.Complete(tf, cmd, args); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
...@@ -561,19 +562,19 @@ func TestAnnotateLocal(t *testing.T) { ...@@ -561,19 +562,19 @@ func TestAnnotateLocal(t *testing.T) {
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: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req) t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
return nil, nil return nil, nil
}), }),
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
iostreams, _, _, _ := genericclioptions.NewTestIOStreams() iostreams, _, _, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdAnnotate("kubectl", tf, iostreams) cmd := NewCmdAnnotate("kubectl", tf, iostreams)
options := NewAnnotateOptions(iostreams) options := NewAnnotateOptions(iostreams)
options.local = true options.local = true
options.Filenames = []string{"../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"} options.Filenames = []string{"../../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}
args := []string{"a=b"} args := []string{"a=b"}
if err := options.Complete(tf, cmd, args); err != nil { if err := options.Complete(tf, cmd, args); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
...@@ -587,7 +588,7 @@ func TestAnnotateLocal(t *testing.T) { ...@@ -587,7 +588,7 @@ func TestAnnotateLocal(t *testing.T) {
} }
func TestAnnotateMultipleObjects(t *testing.T) { func TestAnnotateMultipleObjects(t *testing.T) {
pods, _, _ := testData() pods, _, _ := cmdtesting.TestData()
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup() defer tf.Cleanup()
...@@ -595,13 +596,13 @@ func TestAnnotateMultipleObjects(t *testing.T) { ...@@ -595,13 +596,13 @@ func TestAnnotateMultipleObjects(t *testing.T) {
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...) codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
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: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch req.Method { switch req.Method {
case "GET": case "GET":
switch req.URL.Path { switch req.URL.Path {
case "/namespaces/test/pods": case "/namespaces/test/pods":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, pods)}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, pods)}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -609,9 +610,9 @@ func TestAnnotateMultipleObjects(t *testing.T) { ...@@ -609,9 +610,9 @@ func TestAnnotateMultipleObjects(t *testing.T) {
case "PATCH": case "PATCH":
switch req.URL.Path { switch req.URL.Path {
case "/namespaces/test/pods/foo": case "/namespaces/test/pods/foo":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &pods.Items[0])}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &pods.Items[0])}, nil
case "/namespaces/test/pods/bar": case "/namespaces/test/pods/bar":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &pods.Items[1])}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &pods.Items[1])}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -622,7 +623,7 @@ func TestAnnotateMultipleObjects(t *testing.T) { ...@@ -622,7 +623,7 @@ func TestAnnotateMultipleObjects(t *testing.T) {
} }
}), }),
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
iostreams, _, _, _ := genericclioptions.NewTestIOStreams() iostreams, _, _, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdAnnotate("kubectl", tf, iostreams) cmd := NewCmdAnnotate("kubectl", tf, iostreams)
......
...@@ -31,6 +31,7 @@ import ( ...@@ -31,6 +31,7 @@ import (
"k8s.io/cli-runtime/pkg/genericclioptions/resource" "k8s.io/cli-runtime/pkg/genericclioptions/resource"
restclient "k8s.io/client-go/rest" restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/remotecommand" "k8s.io/client-go/tools/remotecommand"
"k8s.io/kubernetes/pkg/kubectl/cmd/exec"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers" "k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"
...@@ -62,7 +63,7 @@ const ( ...@@ -62,7 +63,7 @@ const (
// AttachOptions declare the arguments accepted by the Exec command // AttachOptions declare the arguments accepted by the Exec command
type AttachOptions struct { type AttachOptions struct {
StreamOptions exec.StreamOptions
// whether to disable use of standard error when streaming output from tty // whether to disable use of standard error when streaming output from tty
DisableStderr bool DisableStderr bool
...@@ -85,11 +86,11 @@ type AttachOptions struct { ...@@ -85,11 +86,11 @@ type AttachOptions struct {
func NewAttachOptions(streams genericclioptions.IOStreams) *AttachOptions { func NewAttachOptions(streams genericclioptions.IOStreams) *AttachOptions {
return &AttachOptions{ return &AttachOptions{
StreamOptions: StreamOptions{ StreamOptions: exec.StreamOptions{
IOStreams: streams, IOStreams: streams,
}, },
Attach: &DefaultRemoteAttach{}, Attach: &DefaultRemoteAttach{},
AttachFunc: defaultAttachFunc, AttachFunc: DefaultAttachFunc,
} }
} }
...@@ -119,7 +120,7 @@ type RemoteAttach interface { ...@@ -119,7 +120,7 @@ type RemoteAttach interface {
Attach(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue remotecommand.TerminalSizeQueue) error Attach(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool, terminalSizeQueue remotecommand.TerminalSizeQueue) error
} }
func defaultAttachFunc(o *AttachOptions, containerToAttach *corev1.Container, raw bool, sizeQueue remotecommand.TerminalSizeQueue) func() error { func DefaultAttachFunc(o *AttachOptions, containerToAttach *corev1.Container, raw bool, sizeQueue remotecommand.TerminalSizeQueue) func() error {
return func() error { return func() error {
restClient, err := restclient.RESTClientFor(o.Config) restClient, err := restclient.RESTClientFor(o.Config)
if err != nil { if err != nil {
...@@ -262,7 +263,7 @@ func (o *AttachOptions) Run() error { ...@@ -262,7 +263,7 @@ func (o *AttachOptions) Run() error {
} }
// ensure we can recover the terminal while attached // ensure we can recover the terminal while attached
t := o.setupTTY() t := o.SetupTTY()
var sizeQueue remotecommand.TerminalSizeQueue var sizeQueue remotecommand.TerminalSizeQueue
if t.Raw { if t.Raw {
......
...@@ -33,6 +33,7 @@ import ( ...@@ -33,6 +33,7 @@ import (
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/remotecommand" "k8s.io/client-go/tools/remotecommand"
"k8s.io/kubernetes/pkg/kubectl/cmd/exec"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers" "k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"
"k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/kubectl/scheme"
...@@ -87,7 +88,7 @@ func TestPodAndContainerAttach(t *testing.T) { ...@@ -87,7 +88,7 @@ func TestPodAndContainerAttach(t *testing.T) {
}, },
{ {
name: "container in flag", name: "container in flag",
options: &AttachOptions{StreamOptions: StreamOptions{ContainerName: "bar"}, GetPodTimeout: 10000000}, options: &AttachOptions{StreamOptions: exec.StreamOptions{ContainerName: "bar"}, GetPodTimeout: 10000000},
args: []string{"foo"}, args: []string{"foo"},
expectedPodName: "foo", expectedPodName: "foo",
expectedContainerName: "bar", expectedContainerName: "bar",
...@@ -95,7 +96,7 @@ func TestPodAndContainerAttach(t *testing.T) { ...@@ -95,7 +96,7 @@ func TestPodAndContainerAttach(t *testing.T) {
}, },
{ {
name: "init container in flag", name: "init container in flag",
options: &AttachOptions{StreamOptions: StreamOptions{ContainerName: "initfoo"}, GetPodTimeout: 30}, options: &AttachOptions{StreamOptions: exec.StreamOptions{ContainerName: "initfoo"}, GetPodTimeout: 30},
args: []string{"foo"}, args: []string{"foo"},
expectedPodName: "foo", expectedPodName: "foo",
expectedContainerName: "initfoo", expectedContainerName: "initfoo",
...@@ -103,7 +104,7 @@ func TestPodAndContainerAttach(t *testing.T) { ...@@ -103,7 +104,7 @@ func TestPodAndContainerAttach(t *testing.T) {
}, },
{ {
name: "non-existing container", name: "non-existing container",
options: &AttachOptions{StreamOptions: StreamOptions{ContainerName: "wrong"}, GetPodTimeout: 10}, options: &AttachOptions{StreamOptions: exec.StreamOptions{ContainerName: "wrong"}, GetPodTimeout: 10},
args: []string{"foo"}, args: []string{"foo"},
expectedPodName: "foo", expectedPodName: "foo",
expectError: "container not found", expectError: "container not found",
...@@ -238,11 +239,11 @@ func TestAttach(t *testing.T) { ...@@ -238,11 +239,11 @@ func TestAttach(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET": case p == test.podPath && m == "GET":
body := objBody(codec, test.pod) body := cmdtesting.ObjBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: body}, nil
case p == test.fetchPodPath && m == "GET": case p == test.fetchPodPath && m == "GET":
body := objBody(codec, test.pod) body := cmdtesting.ObjBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: body}, nil
default: default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", p, req.Method, req.URL, req) t.Errorf("%s: unexpected request: %s %#v\n%#v", p, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request") return nil, fmt.Errorf("unexpected request")
...@@ -256,7 +257,7 @@ func TestAttach(t *testing.T) { ...@@ -256,7 +257,7 @@ func TestAttach(t *testing.T) {
remoteAttach.err = fmt.Errorf("attach error") remoteAttach.err = fmt.Errorf("attach error")
} }
options := &AttachOptions{ options := &AttachOptions{
StreamOptions: StreamOptions{ StreamOptions: exec.StreamOptions{
ContainerName: test.container, ContainerName: test.container,
IOStreams: genericclioptions.NewTestIOStreamsDiscard(), IOStreams: genericclioptions.NewTestIOStreamsDiscard(),
}, },
...@@ -340,11 +341,11 @@ func TestAttachWarnings(t *testing.T) { ...@@ -340,11 +341,11 @@ func TestAttachWarnings(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET": case p == test.podPath && m == "GET":
body := objBody(codec, test.pod) body := cmdtesting.ObjBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: body}, nil
case p == test.fetchPodPath && m == "GET": case p == test.fetchPodPath && m == "GET":
body := objBody(codec, test.pod) body := cmdtesting.ObjBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: body}, nil
default: default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", p, req.Method, req.URL, req) t.Errorf("%s: unexpected request: %s %#v\n%#v", p, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request") return nil, fmt.Errorf("unexpected request")
...@@ -354,7 +355,7 @@ func TestAttachWarnings(t *testing.T) { ...@@ -354,7 +355,7 @@ func TestAttachWarnings(t *testing.T) {
tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: scheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}} tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: scheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}}
options := &AttachOptions{ options := &AttachOptions{
StreamOptions: StreamOptions{ StreamOptions: exec.StreamOptions{
Stdin: test.stdin, Stdin: test.stdin,
TTY: test.tty, TTY: test.tty,
ContainerName: test.container, ContainerName: test.container,
......
...@@ -38,6 +38,11 @@ import ( ...@@ -38,6 +38,11 @@ import (
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
const (
defaultPodLogsTimeout = 20 * time.Second
timeout = 5 * time.Minute
)
type ClusterInfoDumpOptions struct { type ClusterInfoDumpOptions struct {
PrintFlags *genericclioptions.PrintFlags PrintFlags *genericclioptions.PrintFlags
PrintObj printers.ResourcePrinterFunc PrintObj printers.ResourcePrinterFunc
......
...@@ -28,17 +28,48 @@ import ( ...@@ -28,17 +28,48 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/meta"
utilflag "k8s.io/apiserver/pkg/util/flag" utilflag "k8s.io/apiserver/pkg/util/flag"
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
"k8s.io/kubernetes/pkg/kubectl/cmd/annotate"
"k8s.io/kubernetes/pkg/kubectl/cmd/apiresources"
"k8s.io/kubernetes/pkg/kubectl/cmd/apply"
"k8s.io/kubernetes/pkg/kubectl/cmd/attach"
"k8s.io/kubernetes/pkg/kubectl/cmd/auth" "k8s.io/kubernetes/pkg/kubectl/cmd/auth"
"k8s.io/kubernetes/pkg/kubectl/cmd/autoscale"
"k8s.io/kubernetes/pkg/kubectl/cmd/certificates"
"k8s.io/kubernetes/pkg/kubectl/cmd/clusterinfo"
"k8s.io/kubernetes/pkg/kubectl/cmd/completion"
cmdconfig "k8s.io/kubernetes/pkg/kubectl/cmd/config" cmdconfig "k8s.io/kubernetes/pkg/kubectl/cmd/config"
"k8s.io/kubernetes/pkg/kubectl/cmd/convert"
"k8s.io/kubernetes/pkg/kubectl/cmd/cp"
"k8s.io/kubernetes/pkg/kubectl/cmd/create" "k8s.io/kubernetes/pkg/kubectl/cmd/create"
"k8s.io/kubernetes/pkg/kubectl/cmd/delete"
"k8s.io/kubernetes/pkg/kubectl/cmd/describe"
"k8s.io/kubernetes/pkg/kubectl/cmd/diff"
"k8s.io/kubernetes/pkg/kubectl/cmd/drain"
"k8s.io/kubernetes/pkg/kubectl/cmd/edit"
cmdexec "k8s.io/kubernetes/pkg/kubectl/cmd/exec"
"k8s.io/kubernetes/pkg/kubectl/cmd/explain"
"k8s.io/kubernetes/pkg/kubectl/cmd/expose"
"k8s.io/kubernetes/pkg/kubectl/cmd/get" "k8s.io/kubernetes/pkg/kubectl/cmd/get"
"k8s.io/kubernetes/pkg/kubectl/cmd/label"
"k8s.io/kubernetes/pkg/kubectl/cmd/logs"
"k8s.io/kubernetes/pkg/kubectl/cmd/options"
"k8s.io/kubernetes/pkg/kubectl/cmd/patch"
"k8s.io/kubernetes/pkg/kubectl/cmd/plugin"
"k8s.io/kubernetes/pkg/kubectl/cmd/portforward"
"k8s.io/kubernetes/pkg/kubectl/cmd/proxy"
"k8s.io/kubernetes/pkg/kubectl/cmd/replace"
"k8s.io/kubernetes/pkg/kubectl/cmd/rollingupdate"
"k8s.io/kubernetes/pkg/kubectl/cmd/rollout" "k8s.io/kubernetes/pkg/kubectl/cmd/rollout"
"k8s.io/kubernetes/pkg/kubectl/cmd/run"
"k8s.io/kubernetes/pkg/kubectl/cmd/scale"
"k8s.io/kubernetes/pkg/kubectl/cmd/set" "k8s.io/kubernetes/pkg/kubectl/cmd/set"
"k8s.io/kubernetes/pkg/kubectl/cmd/taint"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
"k8s.io/kubernetes/pkg/kubectl/cmd/top"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/cmd/version"
"k8s.io/kubernetes/pkg/kubectl/cmd/wait" "k8s.io/kubernetes/pkg/kubectl/cmd/wait"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
...@@ -416,72 +447,72 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command { ...@@ -416,72 +447,72 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
Message: "Basic Commands (Beginner):", Message: "Basic Commands (Beginner):",
Commands: []*cobra.Command{ Commands: []*cobra.Command{
create.NewCmdCreate(f, ioStreams), create.NewCmdCreate(f, ioStreams),
NewCmdExposeService(f, ioStreams), expose.NewCmdExposeService(f, ioStreams),
NewCmdRun(f, ioStreams), run.NewCmdRun(f, ioStreams),
set.NewCmdSet(f, ioStreams), set.NewCmdSet(f, ioStreams),
deprecatedAlias("run-container", NewCmdRun(f, ioStreams)), deprecatedAlias("run-container", run.NewCmdRun(f, ioStreams)),
}, },
}, },
{ {
Message: "Basic Commands (Intermediate):", Message: "Basic Commands (Intermediate):",
Commands: []*cobra.Command{ Commands: []*cobra.Command{
NewCmdExplain("kubectl", f, ioStreams), explain.NewCmdExplain("kubectl", f, ioStreams),
get.NewCmdGet("kubectl", f, ioStreams), get.NewCmdGet("kubectl", f, ioStreams),
NewCmdEdit(f, ioStreams), edit.NewCmdEdit(f, ioStreams),
NewCmdDelete(f, ioStreams), delete.NewCmdDelete(f, ioStreams),
}, },
}, },
{ {
Message: "Deploy Commands:", Message: "Deploy Commands:",
Commands: []*cobra.Command{ Commands: []*cobra.Command{
rollout.NewCmdRollout(f, ioStreams), rollout.NewCmdRollout(f, ioStreams),
NewCmdRollingUpdate(f, ioStreams), rollingupdate.NewCmdRollingUpdate(f, ioStreams),
NewCmdScale(f, ioStreams), scale.NewCmdScale(f, ioStreams),
NewCmdAutoscale(f, ioStreams), autoscale.NewCmdAutoscale(f, ioStreams),
}, },
}, },
{ {
Message: "Cluster Management Commands:", Message: "Cluster Management Commands:",
Commands: []*cobra.Command{ Commands: []*cobra.Command{
NewCmdCertificate(f, ioStreams), certificates.NewCmdCertificate(f, ioStreams),
NewCmdClusterInfo(f, ioStreams), clusterinfo.NewCmdClusterInfo(f, ioStreams),
NewCmdTop(f, ioStreams), top.NewCmdTop(f, ioStreams),
NewCmdCordon(f, ioStreams), drain.NewCmdCordon(f, ioStreams),
NewCmdUncordon(f, ioStreams), drain.NewCmdUncordon(f, ioStreams),
NewCmdDrain(f, ioStreams), drain.NewCmdDrain(f, ioStreams),
NewCmdTaint(f, ioStreams), taint.NewCmdTaint(f, ioStreams),
}, },
}, },
{ {
Message: "Troubleshooting and Debugging Commands:", Message: "Troubleshooting and Debugging Commands:",
Commands: []*cobra.Command{ Commands: []*cobra.Command{
NewCmdDescribe("kubectl", f, ioStreams), describe.NewCmdDescribe("kubectl", f, ioStreams),
NewCmdLogs(f, ioStreams), logs.NewCmdLogs(f, ioStreams),
NewCmdAttach(f, ioStreams), attach.NewCmdAttach(f, ioStreams),
NewCmdExec(f, ioStreams), cmdexec.NewCmdExec(f, ioStreams),
NewCmdPortForward(f, ioStreams), portforward.NewCmdPortForward(f, ioStreams),
NewCmdProxy(f, ioStreams), proxy.NewCmdProxy(f, ioStreams),
NewCmdCp(f, ioStreams), cp.NewCmdCp(f, ioStreams),
auth.NewCmdAuth(f, ioStreams), auth.NewCmdAuth(f, ioStreams),
}, },
}, },
{ {
Message: "Advanced Commands:", Message: "Advanced Commands:",
Commands: []*cobra.Command{ Commands: []*cobra.Command{
NewCmdDiff(f, ioStreams), diff.NewCmdDiff(f, ioStreams),
NewCmdApply("kubectl", f, ioStreams), apply.NewCmdApply("kubectl", f, ioStreams),
NewCmdPatch(f, ioStreams), patch.NewCmdPatch(f, ioStreams),
NewCmdReplace(f, ioStreams), replace.NewCmdReplace(f, ioStreams),
wait.NewCmdWait(f, ioStreams), wait.NewCmdWait(f, ioStreams),
NewCmdConvert(f, ioStreams), convert.NewCmdConvert(f, ioStreams),
}, },
}, },
{ {
Message: "Settings Commands:", Message: "Settings Commands:",
Commands: []*cobra.Command{ Commands: []*cobra.Command{
NewCmdLabel(f, ioStreams), label.NewCmdLabel(f, ioStreams),
NewCmdAnnotate("kubectl", f, ioStreams), annotate.NewCmdAnnotate("kubectl", f, ioStreams),
NewCmdCompletion(ioStreams.Out, ""), completion.NewCmdCompletion(ioStreams.Out, ""),
}, },
}, },
} }
...@@ -511,11 +542,11 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command { ...@@ -511,11 +542,11 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
cmds.AddCommand(alpha) cmds.AddCommand(alpha)
cmds.AddCommand(cmdconfig.NewCmdConfig(f, clientcmd.NewDefaultPathOptions(), ioStreams)) cmds.AddCommand(cmdconfig.NewCmdConfig(f, clientcmd.NewDefaultPathOptions(), ioStreams))
cmds.AddCommand(NewCmdPlugin(f, ioStreams)) cmds.AddCommand(plugin.NewCmdPlugin(f, ioStreams))
cmds.AddCommand(NewCmdVersion(f, ioStreams)) cmds.AddCommand(version.NewCmdVersion(f, ioStreams))
cmds.AddCommand(NewCmdApiVersions(f, ioStreams)) cmds.AddCommand(apiresources.NewCmdApiVersions(f, ioStreams))
cmds.AddCommand(NewCmdApiResources(f, ioStreams)) cmds.AddCommand(apiresources.NewCmdApiResources(f, ioStreams))
cmds.AddCommand(NewCmdOptions(ioStreams.Out)) cmds.AddCommand(options.NewCmdOptions(ioStreams.Out))
return cmds return cmds
} }
...@@ -524,10 +555,6 @@ func runHelp(cmd *cobra.Command, args []string) { ...@@ -524,10 +555,6 @@ func runHelp(cmd *cobra.Command, args []string) {
cmd.Help() cmd.Help()
} }
func printDeprecationWarning(errOut io.Writer, command, alias string) {
fmt.Fprintf(errOut, "%s is DEPRECATED and will be removed in a future version. Use %s instead.\n", alias, command)
}
// deprecatedAlias is intended to be used to create a "wrapper" command around // deprecatedAlias is intended to be used to create a "wrapper" command around
// an existing command. The wrapper works the same but prints a deprecation // an existing command. The wrapper works the same but prints a deprecation
// message before running. This command is identical functionality. // message before running. This command is identical functionality.
...@@ -542,5 +569,3 @@ func deprecatedAlias(deprecatedVersion string, cmd *cobra.Command) *cobra.Comman ...@@ -542,5 +569,3 @@ func deprecatedAlias(deprecatedVersion string, cmd *cobra.Command) *cobra.Comman
cmd.Hidden = true cmd.Hidden = true
return cmd return cmd
} }
var metadataAccessor = meta.NewAccessor()
...@@ -18,127 +18,19 @@ package cmd ...@@ -18,127 +18,19 @@ package cmd
import ( import (
"bytes" "bytes"
"encoding/json"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"net/http"
"os" "os"
"reflect" "reflect"
stdstrings "strings" "strings"
"testing" "testing"
"github.com/spf13/cobra" "github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
restclient "k8s.io/client-go/rest"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/scheme"
) )
func initTestErrorHandler(t *testing.T) {
cmdutil.BehaviorOnFatal(func(str string, code int) {
t.Errorf("Error running command (exit code %d): %s", code, str)
})
}
func defaultHeader() http.Header {
header := http.Header{}
header.Set("Content-Type", runtime.ContentTypeJSON)
return header
}
func defaultClientConfig() *restclient.Config {
return &restclient.Config{
APIPath: "/api",
ContentConfig: restclient.ContentConfig{
NegotiatedSerializer: scheme.Codecs,
ContentType: runtime.ContentTypeJSON,
GroupVersion: &corev1.SchemeGroupVersion,
},
}
}
func testData() (*corev1.PodList, *corev1.ServiceList, *corev1.ReplicationControllerList) {
grace := int64(30)
enableServiceLinks := corev1.DefaultEnableServiceLinks
pods := &corev1.PodList{
ListMeta: metav1.ListMeta{
ResourceVersion: "15",
},
Items: []corev1.Pod{
{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "10"},
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyAlways,
DNSPolicy: corev1.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
SecurityContext: &corev1.PodSecurityContext{},
EnableServiceLinks: &enableServiceLinks,
},
},
{
ObjectMeta: metav1.ObjectMeta{Name: "bar", Namespace: "test", ResourceVersion: "11"},
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyAlways,
DNSPolicy: corev1.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
SecurityContext: &corev1.PodSecurityContext{},
EnableServiceLinks: &enableServiceLinks,
},
},
},
}
svc := &corev1.ServiceList{
ListMeta: metav1.ListMeta{
ResourceVersion: "16",
},
Items: []corev1.Service{
{
ObjectMeta: metav1.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "12"},
Spec: corev1.ServiceSpec{
SessionAffinity: "None",
Type: corev1.ServiceTypeClusterIP,
},
},
},
}
rc := &corev1.ReplicationControllerList{
ListMeta: metav1.ListMeta{
ResourceVersion: "17",
},
Items: []corev1.ReplicationController{
{
ObjectMeta: metav1.ObjectMeta{Name: "rc1", Namespace: "test", ResourceVersion: "18"},
Spec: corev1.ReplicationControllerSpec{
Replicas: int32ptr(1),
},
},
},
}
return pods, svc, rc
}
func int32ptr(val int) *int32 {
t := int32(val)
return &t
}
func objBody(codec runtime.Codec, obj runtime.Object) io.ReadCloser {
return ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, obj))))
}
func bytesBody(bodyBytes []byte) io.ReadCloser {
return ioutil.NopCloser(bytes.NewReader(bodyBytes))
}
func stringBody(body string) io.ReadCloser {
return ioutil.NopCloser(bytes.NewReader([]byte(body)))
}
func TestNormalizationFuncGlobalExistence(t *testing.T) { func TestNormalizationFuncGlobalExistence(t *testing.T) {
// This test can be safely deleted when we will not support multiple flag formats // This test can be safely deleted when we will not support multiple flag formats
root := NewKubectlCommand(os.Stdin, os.Stdout, os.Stderr) root := NewKubectlCommand(os.Stdin, os.Stdout, os.Stderr)
...@@ -165,14 +57,6 @@ func TestNormalizationFuncGlobalExistence(t *testing.T) { ...@@ -165,14 +57,6 @@ func TestNormalizationFuncGlobalExistence(t *testing.T) {
} }
} }
func genResponseWithJsonEncodedBody(bodyStruct interface{}) (*http.Response, error) {
jsonBytes, err := json.Marshal(bodyStruct)
if err != nil {
return nil, err
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bytesBody(jsonBytes)}, nil
}
func Test_deprecatedAlias(t *testing.T) { func Test_deprecatedAlias(t *testing.T) {
var correctCommandCalled bool var correctCommandCalled bool
makeCobraCommand := func() *cobra.Command { makeCobraCommand := func() *cobra.Command {
...@@ -190,7 +74,7 @@ func Test_deprecatedAlias(t *testing.T) { ...@@ -190,7 +74,7 @@ func Test_deprecatedAlias(t *testing.T) {
if len(alias.Deprecated) == 0 { if len(alias.Deprecated) == 0 {
t.Error("deprecatedAlias should always have a non-empty .Deprecated") t.Error("deprecatedAlias should always have a non-empty .Deprecated")
} }
if !stdstrings.Contains(alias.Deprecated, "print") { if !strings.Contains(alias.Deprecated, "print") {
t.Error("deprecatedAlias should give the name of the new function in its .Deprecated field") t.Error("deprecatedAlias should give the name of the new function in its .Deprecated field")
} }
if !alias.Hidden { if !alias.Hidden {
...@@ -210,7 +94,7 @@ func Test_deprecatedAlias(t *testing.T) { ...@@ -210,7 +94,7 @@ func Test_deprecatedAlias(t *testing.T) {
alias.SetOutput(buffer) alias.SetOutput(buffer)
alias.Execute() alias.Execute()
str := buffer.String() str := buffer.String()
if !stdstrings.Contains(str, "deprecated") || !stdstrings.Contains(str, "print") { if !strings.Contains(str, "deprecated") || !strings.Contains(str, "print") {
t.Errorf("deprecation warning %q does not include enough information", str) t.Errorf("deprecation warning %q does not include enough information", str)
} }
...@@ -240,7 +124,7 @@ func TestKubectlCommandHandlesPlugins(t *testing.T) { ...@@ -240,7 +124,7 @@ func TestKubectlCommandHandlesPlugins(t *testing.T) {
{ {
name: "test that a plugin executable is found based on command args", name: "test that a plugin executable is found based on command args",
args: []string{"kubectl", "foo", "--bar"}, args: []string{"kubectl", "foo", "--bar"},
expectPlugin: "testdata/plugin/kubectl-foo", expectPlugin: "plugin/testdata/kubectl-foo",
expectPluginArgs: []string{"foo", "--bar"}, expectPluginArgs: []string{"foo", "--bar"},
}, },
{ {
...@@ -252,7 +136,7 @@ func TestKubectlCommandHandlesPlugins(t *testing.T) { ...@@ -252,7 +136,7 @@ func TestKubectlCommandHandlesPlugins(t *testing.T) {
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
pluginsHandler := &testPluginHandler{ pluginsHandler := &testPluginHandler{
pluginsDirectory: "testdata/plugin", pluginsDirectory: "plugin/testdata",
} }
_, in, out, errOut := genericclioptions.NewTestIOStreams() _, in, out, errOut := genericclioptions.NewTestIOStreams()
......
...@@ -43,7 +43,7 @@ func TestConvertObject(t *testing.T) { ...@@ -43,7 +43,7 @@ func TestConvertObject(t *testing.T) {
testcases := []testcase{ testcases := []testcase{
{ {
name: "apps deployment to extensions deployment", name: "apps deployment to extensions deployment",
file: "../../../test/fixtures/pkg/kubectl/cmd/convert/appsdeployment.yaml", file: "../../../../test/fixtures/pkg/kubectl/cmd/convert/appsdeployment.yaml",
outputVersion: "extensions/v1beta1", outputVersion: "extensions/v1beta1",
fields: []checkField{ fields: []checkField{
{ {
...@@ -53,7 +53,7 @@ func TestConvertObject(t *testing.T) { ...@@ -53,7 +53,7 @@ func TestConvertObject(t *testing.T) {
}, },
{ {
name: "extensions deployment to apps deployment", name: "extensions deployment to apps deployment",
file: "../../../test/fixtures/pkg/kubectl/cmd/convert/extensionsdeployment.yaml", file: "../../../../test/fixtures/pkg/kubectl/cmd/convert/extensionsdeployment.yaml",
outputVersion: "apps/v1beta2", outputVersion: "apps/v1beta2",
fields: []checkField{ fields: []checkField{
{ {
...@@ -63,7 +63,7 @@ func TestConvertObject(t *testing.T) { ...@@ -63,7 +63,7 @@ func TestConvertObject(t *testing.T) {
}, },
{ {
name: "v1 HPA to v2beta1 HPA", name: "v1 HPA to v2beta1 HPA",
file: "../../../test/fixtures/pkg/kubectl/cmd/convert/v1HPA.yaml", file: "../../../../test/fixtures/pkg/kubectl/cmd/convert/v1HPA.yaml",
outputVersion: "autoscaling/v2beta1", outputVersion: "autoscaling/v2beta1",
fields: []checkField{ fields: []checkField{
{ {
...@@ -79,7 +79,7 @@ func TestConvertObject(t *testing.T) { ...@@ -79,7 +79,7 @@ func TestConvertObject(t *testing.T) {
}, },
{ {
name: "v2beta1 HPA to v1 HPA", name: "v2beta1 HPA to v1 HPA",
file: "../../../test/fixtures/pkg/kubectl/cmd/convert/v2beta1HPA.yaml", file: "../../../../test/fixtures/pkg/kubectl/cmd/convert/v2beta1HPA.yaml",
outputVersion: "autoscaling/v1", outputVersion: "autoscaling/v1",
fields: []checkField{ fields: []checkField{
{ {
......
...@@ -30,6 +30,7 @@ import ( ...@@ -30,6 +30,7 @@ import (
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest" restclient "k8s.io/client-go/rest"
"k8s.io/kubernetes/pkg/kubectl/cmd/exec"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
...@@ -197,8 +198,8 @@ func (o *CopyOptions) Run(args []string) error { ...@@ -197,8 +198,8 @@ func (o *CopyOptions) Run(args []string) error {
// pod. If the destination path does not exist or is _not_ a // pod. If the destination path does not exist or is _not_ a
// directory, an error is returned with the exit code received. // directory, an error is returned with the exit code received.
func (o *CopyOptions) checkDestinationIsDir(dest fileSpec) error { func (o *CopyOptions) checkDestinationIsDir(dest fileSpec) error {
options := &ExecOptions{ options := &exec.ExecOptions{
StreamOptions: StreamOptions{ StreamOptions: exec.StreamOptions{
IOStreams: genericclioptions.IOStreams{ IOStreams: genericclioptions.IOStreams{
Out: bytes.NewBuffer([]byte{}), Out: bytes.NewBuffer([]byte{}),
ErrOut: bytes.NewBuffer([]byte{}), ErrOut: bytes.NewBuffer([]byte{}),
...@@ -209,7 +210,7 @@ func (o *CopyOptions) checkDestinationIsDir(dest fileSpec) error { ...@@ -209,7 +210,7 @@ func (o *CopyOptions) checkDestinationIsDir(dest fileSpec) error {
}, },
Command: []string{"test", "-d", dest.File}, Command: []string{"test", "-d", dest.File},
Executor: &DefaultRemoteExecutor{}, Executor: &exec.DefaultRemoteExecutor{},
} }
return o.execute(options) return o.execute(options)
...@@ -245,8 +246,8 @@ func (o *CopyOptions) copyToPod(src, dest fileSpec) error { ...@@ -245,8 +246,8 @@ func (o *CopyOptions) copyToPod(src, dest fileSpec) error {
cmdArr = append(cmdArr, "-C", destDir) cmdArr = append(cmdArr, "-C", destDir)
} }
options := &ExecOptions{ options := &exec.ExecOptions{
StreamOptions: StreamOptions{ StreamOptions: exec.StreamOptions{
IOStreams: genericclioptions.IOStreams{ IOStreams: genericclioptions.IOStreams{
In: reader, In: reader,
Out: o.Out, Out: o.Out,
...@@ -259,7 +260,7 @@ func (o *CopyOptions) copyToPod(src, dest fileSpec) error { ...@@ -259,7 +260,7 @@ func (o *CopyOptions) copyToPod(src, dest fileSpec) error {
}, },
Command: cmdArr, Command: cmdArr,
Executor: &DefaultRemoteExecutor{}, Executor: &exec.DefaultRemoteExecutor{},
} }
return o.execute(options) return o.execute(options)
} }
...@@ -270,8 +271,8 @@ func (o *CopyOptions) copyFromPod(src, dest fileSpec) error { ...@@ -270,8 +271,8 @@ func (o *CopyOptions) copyFromPod(src, dest fileSpec) error {
} }
reader, outStream := io.Pipe() reader, outStream := io.Pipe()
options := &ExecOptions{ options := &exec.ExecOptions{
StreamOptions: StreamOptions{ StreamOptions: exec.StreamOptions{
IOStreams: genericclioptions.IOStreams{ IOStreams: genericclioptions.IOStreams{
In: nil, In: nil,
Out: outStream, Out: outStream,
...@@ -284,7 +285,7 @@ func (o *CopyOptions) copyFromPod(src, dest fileSpec) error { ...@@ -284,7 +285,7 @@ func (o *CopyOptions) copyFromPod(src, dest fileSpec) error {
// TODO: Improve error messages by first testing if 'tar' is present in the container? // TODO: Improve error messages by first testing if 'tar' is present in the container?
Command: []string{"tar", "cf", "-", src.File}, Command: []string{"tar", "cf", "-", src.File},
Executor: &DefaultRemoteExecutor{}, Executor: &exec.DefaultRemoteExecutor{},
} }
go func() { go func() {
...@@ -460,7 +461,7 @@ func getPrefix(file string) string { ...@@ -460,7 +461,7 @@ func getPrefix(file string) string {
return strings.TrimLeft(file, "/") return strings.TrimLeft(file, "/")
} }
func (o *CopyOptions) execute(options *ExecOptions) error { func (o *CopyOptions) execute(options *exec.ExecOptions) error {
if len(options.Namespace) == 0 { if len(options.Namespace) == 0 {
options.Namespace = o.Namespace options.Namespace = o.Namespace
} }
......
...@@ -527,11 +527,11 @@ func TestCopyToPod(t *testing.T) { ...@@ -527,11 +527,11 @@ func TestCopyToPod(t *testing.T) {
NegotiatedSerializer: ns, NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
responsePod := &v1.Pod{} responsePod := &v1.Pod{}
return &http.Response{StatusCode: http.StatusNotFound, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, responsePod))))}, nil return &http.Response{StatusCode: http.StatusNotFound, Header: cmdtesting.DefaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, responsePod))))}, nil
}), }),
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
ioStreams, _, _, _ := genericclioptions.NewTestIOStreams() ioStreams, _, _, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCp(tf, ioStreams) cmd := NewCmdCp(tf, ioStreams)
......
...@@ -24,9 +24,7 @@ import ( ...@@ -24,9 +24,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/kubectl/scheme"
...@@ -39,7 +37,7 @@ func TestCreateClusterRole(t *testing.T) { ...@@ -39,7 +37,7 @@ func TestCreateClusterRole(t *testing.T) {
defer tf.Cleanup() defer tf.Cleanup()
tf.Client = &fake.RESTClient{} tf.Client = &fake.RESTClient{}
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
tests := map[string]struct { tests := map[string]struct {
verbs string verbs string
...@@ -514,14 +512,3 @@ func TestClusterRoleValidate(t *testing.T) { ...@@ -514,14 +512,3 @@ func TestClusterRoleValidate(t *testing.T) {
}) })
} }
} }
func defaultClientConfig() *restclient.Config {
return &restclient.Config{
APIPath: "/api",
ContentConfig: restclient.ContentConfig{
NegotiatedSerializer: scheme.Codecs,
ContentType: runtime.ContentTypeJSON,
GroupVersion: &schema.GroupVersion{Version: "v1"},
},
}
}
...@@ -101,7 +101,7 @@ func TestCreateClusterRoleBinding(t *testing.T) { ...@@ -101,7 +101,7 @@ func TestCreateClusterRoleBinding(t *testing.T) {
responseBinding := &rbac.ClusterRoleBinding{} responseBinding := &rbac.ClusterRoleBinding{}
responseBinding.Name = "fake-binding" responseBinding.Name = "fake-binding"
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(encoder, responseBinding))))}, nil return &http.Response{StatusCode: 201, Header: cmdtesting.DefaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(encoder, responseBinding))))}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -145,9 +145,3 @@ func (c *ClusterRoleBindingRESTClient) Post() *restclient.Request { ...@@ -145,9 +145,3 @@ func (c *ClusterRoleBindingRESTClient) Post() *restclient.Request {
} }
return restclient.NewRequest(c, "POST", &url.URL{Host: "localhost"}, c.VersionedAPIPath, config, serializers, nil, nil, 0) return restclient.NewRequest(c, "POST", &url.URL{Host: "localhost"}, c.VersionedAPIPath, config, serializers, nil, nil, 0)
} }
func defaultHeader() http.Header {
header := http.Header{}
header.Set("Content-Type", runtime.ContentTypeJSON)
return header
}
...@@ -17,14 +17,10 @@ limitations under the License. ...@@ -17,14 +17,10 @@ limitations under the License.
package create package create
import ( import (
"bytes"
"io"
"io/ioutil"
"net/http" "net/http"
"testing" "testing"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
...@@ -47,7 +43,7 @@ func TestCreateConfigMap(t *testing.T) { ...@@ -47,7 +43,7 @@ func TestCreateConfigMap(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/configmaps" && m == "POST": case p == "/namespaces/test/configmaps" && m == "POST":
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: objBody(codec, configMap)}, nil return &http.Response{StatusCode: 201, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, configMap)}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -63,7 +59,3 @@ func TestCreateConfigMap(t *testing.T) { ...@@ -63,7 +59,3 @@ func TestCreateConfigMap(t *testing.T) {
t.Errorf("expected output: %s, but got: %s", expectedOutput, buf.String()) t.Errorf("expected output: %s, but got: %s", expectedOutput, buf.String())
} }
} }
func objBody(codec runtime.Codec, obj runtime.Object) io.ReadCloser {
return ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, obj))))
}
...@@ -43,7 +43,7 @@ func TestCreateNamespace(t *testing.T) { ...@@ -43,7 +43,7 @@ func TestCreateNamespace(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces" && m == "POST": case p == "/namespaces" && m == "POST":
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: objBody(codec, namespaceObject)}, nil return &http.Response{StatusCode: 201, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, namespaceObject)}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
......
...@@ -38,7 +38,7 @@ func TestCreateRole(t *testing.T) { ...@@ -38,7 +38,7 @@ func TestCreateRole(t *testing.T) {
defer tf.Cleanup() defer tf.Cleanup()
tf.Client = &fake.RESTClient{} tf.Client = &fake.RESTClient{}
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
tests := map[string]struct { tests := map[string]struct {
verbs string verbs string
...@@ -358,7 +358,7 @@ func TestComplete(t *testing.T) { ...@@ -358,7 +358,7 @@ func TestComplete(t *testing.T) {
defer tf.Cleanup() defer tf.Cleanup()
tf.Client = &fake.RESTClient{} tf.Client = &fake.RESTClient{}
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
defaultTestResources := "pods,deployments.extensions" defaultTestResources := "pods,deployments.extensions"
......
...@@ -103,7 +103,7 @@ func TestCreateRoleBinding(t *testing.T) { ...@@ -103,7 +103,7 @@ func TestCreateRoleBinding(t *testing.T) {
responseBinding := &rbac.RoleBinding{} responseBinding := &rbac.RoleBinding{}
responseBinding.Name = "fake-binding" responseBinding.Name = "fake-binding"
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(encoder, responseBinding))))}, nil return &http.Response{StatusCode: 201, Header: cmdtesting.DefaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(encoder, responseBinding))))}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
......
...@@ -48,7 +48,7 @@ func TestCreateSecretGeneric(t *testing.T) { ...@@ -48,7 +48,7 @@ func TestCreateSecretGeneric(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/secrets" && m == "POST": case p == "/namespaces/test/secrets" && m == "POST":
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: objBody(codec, secretObject)}, nil return &http.Response{StatusCode: 201, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, secretObject)}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -80,7 +80,7 @@ func TestCreateSecretDockerRegistry(t *testing.T) { ...@@ -80,7 +80,7 @@ func TestCreateSecretDockerRegistry(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/secrets" && m == "POST": case p == "/namespaces/test/secrets" && m == "POST":
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: objBody(codec, secretObject)}, nil return &http.Response{StatusCode: 201, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, secretObject)}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
......
...@@ -43,7 +43,7 @@ func TestCreateService(t *testing.T) { ...@@ -43,7 +43,7 @@ func TestCreateService(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/services" && m == "POST": case p == "/namespaces/test/services" && m == "POST":
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: objBody(codec, service)}, nil return &http.Response{StatusCode: 201, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, service)}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -76,7 +76,7 @@ func TestCreateServiceNodePort(t *testing.T) { ...@@ -76,7 +76,7 @@ func TestCreateServiceNodePort(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/services" && m == http.MethodPost: case p == "/namespaces/test/services" && m == http.MethodPost:
return &http.Response{StatusCode: http.StatusCreated, Header: defaultHeader(), Body: objBody(codec, service)}, nil return &http.Response{StatusCode: http.StatusCreated, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, service)}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -109,7 +109,7 @@ func TestCreateServiceExternalName(t *testing.T) { ...@@ -109,7 +109,7 @@ func TestCreateServiceExternalName(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/services" && m == http.MethodPost: case p == "/namespaces/test/services" && m == http.MethodPost:
return &http.Response{StatusCode: http.StatusCreated, Header: defaultHeader(), Body: objBody(codec, service)}, nil return &http.Response{StatusCode: http.StatusCreated, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, service)}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
......
...@@ -43,7 +43,7 @@ func TestCreateServiceAccount(t *testing.T) { ...@@ -43,7 +43,7 @@ func TestCreateServiceAccount(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/serviceaccounts" && m == "POST": case p == "/namespaces/test/serviceaccounts" && m == "POST":
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: objBody(codec, serviceAccountObject)}, nil return &http.Response{StatusCode: 201, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, serviceAccountObject)}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
......
...@@ -20,19 +20,16 @@ import ( ...@@ -20,19 +20,16 @@ import (
"net/http" "net/http"
"testing" "testing"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/genericclioptions/resource" "k8s.io/cli-runtime/pkg/genericclioptions/resource"
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/kubectl/scheme"
) )
func TestExtraArgsFail(t *testing.T) { func TestExtraArgsFail(t *testing.T) {
initTestErrorHandler(t) cmdtesting.InitTestErrorHandler(t)
f := cmdtesting.NewTestFactory() f := cmdtesting.NewTestFactory()
defer f.Cleanup() defer f.Cleanup()
...@@ -45,8 +42,8 @@ func TestExtraArgsFail(t *testing.T) { ...@@ -45,8 +42,8 @@ func TestExtraArgsFail(t *testing.T) {
} }
func TestCreateObject(t *testing.T) { func TestCreateObject(t *testing.T) {
initTestErrorHandler(t) cmdtesting.InitTestErrorHandler(t)
_, _, rc := testData() _, _, rc := cmdtesting.TestData()
rc.Items[0].Name = "redis-master-controller" rc.Items[0].Name = "redis-master-controller"
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
...@@ -56,11 +53,11 @@ func TestCreateObject(t *testing.T) { ...@@ -56,11 +53,11 @@ func TestCreateObject(t *testing.T) {
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"}, GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/replicationcontrollers" && m == http.MethodPost: case p == "/namespaces/test/replicationcontrollers" && m == http.MethodPost:
return &http.Response{StatusCode: http.StatusCreated, Header: defaultHeader(), Body: objBody(codec, &rc.Items[0])}, nil return &http.Response{StatusCode: http.StatusCreated, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &rc.Items[0])}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -81,8 +78,8 @@ func TestCreateObject(t *testing.T) { ...@@ -81,8 +78,8 @@ func TestCreateObject(t *testing.T) {
} }
func TestCreateMultipleObject(t *testing.T) { func TestCreateMultipleObject(t *testing.T) {
initTestErrorHandler(t) cmdtesting.InitTestErrorHandler(t)
_, svc, rc := testData() _, svc, rc := cmdtesting.TestData()
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup() defer tf.Cleanup()
...@@ -91,13 +88,13 @@ func TestCreateMultipleObject(t *testing.T) { ...@@ -91,13 +88,13 @@ func TestCreateMultipleObject(t *testing.T) {
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"}, GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/services" && m == http.MethodPost: case p == "/namespaces/test/services" && m == http.MethodPost:
return &http.Response{StatusCode: http.StatusCreated, Header: defaultHeader(), Body: objBody(codec, &svc.Items[0])}, nil return &http.Response{StatusCode: http.StatusCreated, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &svc.Items[0])}, nil
case p == "/namespaces/test/replicationcontrollers" && m == http.MethodPost: case p == "/namespaces/test/replicationcontrollers" && m == http.MethodPost:
return &http.Response{StatusCode: http.StatusCreated, Header: defaultHeader(), Body: objBody(codec, &rc.Items[0])}, nil return &http.Response{StatusCode: http.StatusCreated, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &rc.Items[0])}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -119,8 +116,8 @@ func TestCreateMultipleObject(t *testing.T) { ...@@ -119,8 +116,8 @@ func TestCreateMultipleObject(t *testing.T) {
} }
func TestCreateDirectory(t *testing.T) { func TestCreateDirectory(t *testing.T) {
initTestErrorHandler(t) cmdtesting.InitTestErrorHandler(t)
_, _, rc := testData() _, _, rc := cmdtesting.TestData()
rc.Items[0].Name = "name" rc.Items[0].Name = "name"
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
...@@ -130,11 +127,11 @@ func TestCreateDirectory(t *testing.T) { ...@@ -130,11 +127,11 @@ func TestCreateDirectory(t *testing.T) {
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"}, GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/replicationcontrollers" && m == http.MethodPost: case p == "/namespaces/test/replicationcontrollers" && m == http.MethodPost:
return &http.Response{StatusCode: http.StatusCreated, Header: defaultHeader(), Body: objBody(codec, &rc.Items[0])}, nil return &http.Response{StatusCode: http.StatusCreated, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &rc.Items[0])}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -152,69 +149,3 @@ func TestCreateDirectory(t *testing.T) { ...@@ -152,69 +149,3 @@ func TestCreateDirectory(t *testing.T) {
t.Errorf("unexpected output: %s", buf.String()) t.Errorf("unexpected output: %s", buf.String())
} }
} }
var unstructuredSerializer = resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer
func initTestErrorHandler(t *testing.T) {
cmdutil.BehaviorOnFatal(func(str string, code int) {
t.Errorf("Error running command (exit code %d): %s", code, str)
})
}
func testData() (*corev1.PodList, *corev1.ServiceList, *corev1.ReplicationControllerList) {
grace := int64(30)
pods := &corev1.PodList{
ListMeta: metav1.ListMeta{
ResourceVersion: "15",
},
Items: []corev1.Pod{
{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "10"},
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyAlways,
DNSPolicy: corev1.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
SecurityContext: &corev1.PodSecurityContext{},
},
},
{
ObjectMeta: metav1.ObjectMeta{Name: "bar", Namespace: "test", ResourceVersion: "11"},
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyAlways,
DNSPolicy: corev1.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
SecurityContext: &corev1.PodSecurityContext{},
},
},
},
}
svc := &corev1.ServiceList{
ListMeta: metav1.ListMeta{
ResourceVersion: "16",
},
Items: []corev1.Service{
{
ObjectMeta: metav1.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "12"},
Spec: corev1.ServiceSpec{
SessionAffinity: "None",
Type: corev1.ServiceTypeClusterIP,
},
},
},
}
one := int32(1)
rc := &corev1.ReplicationControllerList{
ListMeta: metav1.ListMeta{
ResourceVersion: "17",
},
Items: []corev1.ReplicationController{
{
ObjectMeta: metav1.ObjectMeta{Name: "rc1", Namespace: "test", ResourceVersion: "18"},
Spec: corev1.ReplicationControllerSpec{
Replicas: &one,
},
},
},
}
return pods, svc, rc
}
...@@ -24,6 +24,7 @@ import ( ...@@ -24,6 +24,7 @@ import (
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/genericclioptions/resource"
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
...@@ -45,8 +46,8 @@ func TestDescribeUnknownSchemaObject(t *testing.T) { ...@@ -45,8 +46,8 @@ func TestDescribeUnknownSchemaObject(t *testing.T) {
_, _, codec := cmdtesting.NewExternalScheme() _, _, codec := cmdtesting.NewExternalScheme()
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, cmdtesting.NewInternalType("", "", "foo"))}, Resp: &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, cmdtesting.NewInternalType("", "", "foo"))},
} }
streams, _, buf, _ := genericclioptions.NewTestIOStreams() streams, _, buf, _ := genericclioptions.NewTestIOStreams()
...@@ -77,8 +78,8 @@ func TestDescribeUnknownNamespacedSchemaObject(t *testing.T) { ...@@ -77,8 +78,8 @@ func TestDescribeUnknownNamespacedSchemaObject(t *testing.T) {
_, _, codec := cmdtesting.NewExternalScheme() _, _, codec := cmdtesting.NewExternalScheme()
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, cmdtesting.NewInternalNamespacedType("", "", "foo", "non-default"))}, Resp: &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, cmdtesting.NewInternalNamespacedType("", "", "foo", "non-default"))},
} }
tf.WithNamespace("non-default") tf.WithNamespace("non-default")
...@@ -104,17 +105,17 @@ func TestDescribeObject(t *testing.T) { ...@@ -104,17 +105,17 @@ func TestDescribeObject(t *testing.T) {
}() }()
cmdutil.DescriberFn = d.describerFor cmdutil.DescriberFn = d.describerFor
_, _, rc := testData() _, _, rc := cmdtesting.TestData()
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup() defer tf.Cleanup()
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...) codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/replicationcontrollers/redis-master" && m == "GET": case p == "/namespaces/test/replicationcontrollers/redis-master" && m == "GET":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &rc.Items[0])}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &rc.Items[0])}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -125,7 +126,7 @@ func TestDescribeObject(t *testing.T) { ...@@ -125,7 +126,7 @@ func TestDescribeObject(t *testing.T) {
streams, _, buf, _ := genericclioptions.NewTestIOStreams() streams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdDescribe("kubectl", tf, streams) cmd := NewCmdDescribe("kubectl", tf, streams)
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml") cmd.Flags().Set("filename", "../../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
cmd.Run(cmd, []string{}) cmd.Run(cmd, []string{})
if d.Name != "redis-master" || d.Namespace != "test" { if d.Name != "redis-master" || d.Namespace != "test" {
...@@ -145,14 +146,14 @@ func TestDescribeListObjects(t *testing.T) { ...@@ -145,14 +146,14 @@ func TestDescribeListObjects(t *testing.T) {
}() }()
cmdutil.DescriberFn = d.describerFor cmdutil.DescriberFn = d.describerFor
pods, _, _ := testData() pods, _, _ := cmdtesting.TestData()
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup() defer tf.Cleanup()
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...) codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, pods)}, Resp: &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, pods)},
} }
streams, _, buf, _ := genericclioptions.NewTestIOStreams() streams, _, buf, _ := genericclioptions.NewTestIOStreams()
...@@ -172,14 +173,14 @@ func TestDescribeObjectShowEvents(t *testing.T) { ...@@ -172,14 +173,14 @@ func TestDescribeObjectShowEvents(t *testing.T) {
}() }()
cmdutil.DescriberFn = d.describerFor cmdutil.DescriberFn = d.describerFor
pods, _, _ := testData() pods, _, _ := cmdtesting.TestData()
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup() defer tf.Cleanup()
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...) codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, pods)}, Resp: &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, pods)},
} }
cmd := NewCmdDescribe("kubectl", tf, genericclioptions.NewTestIOStreamsDiscard()) cmd := NewCmdDescribe("kubectl", tf, genericclioptions.NewTestIOStreamsDiscard())
...@@ -198,14 +199,14 @@ func TestDescribeObjectSkipEvents(t *testing.T) { ...@@ -198,14 +199,14 @@ func TestDescribeObjectSkipEvents(t *testing.T) {
}() }()
cmdutil.DescriberFn = d.describerFor cmdutil.DescriberFn = d.describerFor
pods, _, _ := testData() pods, _, _ := cmdtesting.TestData()
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup() defer tf.Cleanup()
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...) codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, pods)}, Resp: &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, pods)},
} }
cmd := NewCmdDescribe("kubectl", tf, genericclioptions.NewTestIOStreamsDiscard()) cmd := NewCmdDescribe("kubectl", tf, genericclioptions.NewTestIOStreamsDiscard())
......
...@@ -34,6 +34,7 @@ import ( ...@@ -34,6 +34,7 @@ import (
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/genericclioptions/resource" "k8s.io/cli-runtime/pkg/genericclioptions/resource"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/apply"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi" "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
...@@ -259,16 +260,16 @@ func (obj InfoObject) Merged() (runtime.Object, error) { ...@@ -259,16 +260,16 @@ func (obj InfoObject) Merged() (runtime.Object, error) {
// This is using the patcher from apply, to keep the same behavior. // This is using the patcher from apply, to keep the same behavior.
// We plan on replacing this with server-side apply when it becomes available. // We plan on replacing this with server-side apply when it becomes available.
patcher := &patcher{ patcher := &apply.Patcher{
mapping: obj.Info.Mapping, Mapping: obj.Info.Mapping,
helper: resource.NewHelper(obj.Info.Client, obj.Info.Mapping), Helper: resource.NewHelper(obj.Info.Client, obj.Info.Mapping),
overwrite: true, Overwrite: true,
backOff: clockwork.NewRealClock(), BackOff: clockwork.NewRealClock(),
serverDryRun: true, ServerDryRun: true,
openapiSchema: obj.OpenAPI, OpenapiSchema: obj.OpenAPI,
} }
_, result, err := patcher.patch(obj.Info.Object, modified, obj.Info.Source, obj.Info.Namespace, obj.Info.Name, nil) _, result, err := patcher.Patch(obj.Info.Object, modified, obj.Info.Source, obj.Info.Namespace, obj.Info.Name, nil)
return result, err return result, err
} }
......
...@@ -161,9 +161,9 @@ func TestCordon(t *testing.T) { ...@@ -161,9 +161,9 @@ func TestCordon(t *testing.T) {
m := &MyReq{req} m := &MyReq{req}
switch { switch {
case m.isFor("GET", "/nodes/node"): case m.isFor("GET", "/nodes/node"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, test.node)}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, test.node)}, nil
case m.isFor("GET", "/nodes/bar"): case m.isFor("GET", "/nodes/bar"):
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: stringBody("nope")}, nil return &http.Response{StatusCode: 404, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.StringBody("nope")}, nil
case m.isFor("PATCH", "/nodes/node"): case m.isFor("PATCH", "/nodes/node"):
data, err := ioutil.ReadAll(req.Body) data, err := ioutil.ReadAll(req.Body)
if err != nil { if err != nil {
...@@ -185,14 +185,14 @@ func TestCordon(t *testing.T) { ...@@ -185,14 +185,14 @@ func TestCordon(t *testing.T) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, test.expected.Spec.Unschedulable, new_node.Spec.Unschedulable) t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, test.expected.Spec.Unschedulable, new_node.Spec.Unschedulable)
} }
updated = true updated = true
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, new_node)}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, new_node)}, nil
default: default:
t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req) t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req)
return nil, nil return nil, nil
} }
}), }),
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
ioStreams, _, _, _ := genericclioptions.NewTestIOStreams() ioStreams, _, _, _ := genericclioptions.NewTestIOStreams()
cmd := test.cmd(tf, ioStreams) cmd := test.cmd(tf, ioStreams)
...@@ -719,7 +719,7 @@ func TestDrain(t *testing.T) { ...@@ -719,7 +719,7 @@ func TestDrain(t *testing.T) {
apiVersions := metav1.APIVersions{ apiVersions := metav1.APIVersions{
Versions: []string{"v1"}, Versions: []string{"v1"},
} }
return genResponseWithJsonEncodedBody(apiVersions) return cmdtesting.GenResponseWithJsonEncodedBody(apiVersions)
case req.Method == "GET" && req.URL.Path == "/apis": case req.Method == "GET" && req.URL.Path == "/apis":
groupList := metav1.APIGroupList{ groupList := metav1.APIGroupList{
Groups: []metav1.APIGroup{ Groups: []metav1.APIGroup{
...@@ -731,7 +731,7 @@ func TestDrain(t *testing.T) { ...@@ -731,7 +731,7 @@ func TestDrain(t *testing.T) {
}, },
}, },
} }
return genResponseWithJsonEncodedBody(groupList) return cmdtesting.GenResponseWithJsonEncodedBody(groupList)
case req.Method == "GET" && req.URL.Path == "/api/v1": case req.Method == "GET" && req.URL.Path == "/api/v1":
resourceList := metav1.APIResourceList{ resourceList := metav1.APIResourceList{
GroupVersion: "v1", GroupVersion: "v1",
...@@ -744,21 +744,21 @@ func TestDrain(t *testing.T) { ...@@ -744,21 +744,21 @@ func TestDrain(t *testing.T) {
}, },
} }
} }
return genResponseWithJsonEncodedBody(resourceList) return cmdtesting.GenResponseWithJsonEncodedBody(resourceList)
case m.isFor("GET", "/nodes/node"): case m.isFor("GET", "/nodes/node"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, test.node)}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, test.node)}, nil
case m.isFor("GET", "/namespaces/default/replicationcontrollers/rc"): case m.isFor("GET", "/namespaces/default/replicationcontrollers/rc"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &test.rcs[0])}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &test.rcs[0])}, nil
case m.isFor("GET", "/namespaces/default/daemonsets/ds"): case m.isFor("GET", "/namespaces/default/daemonsets/ds"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &ds)}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &ds)}, nil
case m.isFor("GET", "/namespaces/default/daemonsets/missing-ds"): case m.isFor("GET", "/namespaces/default/daemonsets/missing-ds"):
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: objBody(codec, &extensionsv1beta1.DaemonSet{})}, nil return &http.Response{StatusCode: 404, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &extensionsv1beta1.DaemonSet{})}, nil
case m.isFor("GET", "/namespaces/default/jobs/job"): case m.isFor("GET", "/namespaces/default/jobs/job"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &job)}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &job)}, nil
case m.isFor("GET", "/namespaces/default/replicasets/rs"): case m.isFor("GET", "/namespaces/default/replicasets/rs"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &test.replicaSets[0])}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &test.replicaSets[0])}, nil
case m.isFor("GET", "/namespaces/default/pods/bar"): case m.isFor("GET", "/namespaces/default/pods/bar"):
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: objBody(codec, &corev1.Pod{})}, nil return &http.Response{StatusCode: 404, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &corev1.Pod{})}, nil
case m.isFor("GET", "/pods"): case m.isFor("GET", "/pods"):
values, err := url.ParseQuery(req.URL.RawQuery) values, err := url.ParseQuery(req.URL.RawQuery)
if err != nil { if err != nil {
...@@ -769,9 +769,9 @@ func TestDrain(t *testing.T) { ...@@ -769,9 +769,9 @@ func TestDrain(t *testing.T) {
if !reflect.DeepEqual(get_params, values) { if !reflect.DeepEqual(get_params, values) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, 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 return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &corev1.PodList{Items: test.pods})}, nil
case m.isFor("GET", "/replicationcontrollers"): case m.isFor("GET", "/replicationcontrollers"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &corev1.ReplicationControllerList{Items: test.rcs})}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &corev1.ReplicationControllerList{Items: test.rcs})}, nil
case m.isFor("PATCH", "/nodes/node"): case m.isFor("PATCH", "/nodes/node"):
data, err := ioutil.ReadAll(req.Body) data, err := ioutil.ReadAll(req.Body)
if err != nil { if err != nil {
...@@ -792,20 +792,20 @@ func TestDrain(t *testing.T) { ...@@ -792,20 +792,20 @@ func TestDrain(t *testing.T) {
if !reflect.DeepEqual(test.expected.Spec, new_node.Spec) { 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) 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 return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, new_node)}, nil
case m.isFor("DELETE", "/namespaces/default/pods/bar"): case m.isFor("DELETE", "/namespaces/default/pods/bar"):
deleted = true deleted = true
return &http.Response{StatusCode: 204, Header: defaultHeader(), Body: objBody(codec, &test.pods[0])}, nil return &http.Response{StatusCode: 204, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &test.pods[0])}, nil
case m.isFor("POST", "/namespaces/default/pods/bar/eviction"): case m.isFor("POST", "/namespaces/default/pods/bar/eviction"):
evicted = true evicted = true
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: objBody(codec, &policyv1beta1.Eviction{})}, nil return &http.Response{StatusCode: 201, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &policyv1beta1.Eviction{})}, nil
default: default:
t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req) t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req)
return nil, nil return nil, nil
} }
}), }),
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
ioStreams, _, _, errBuf := genericclioptions.NewTestIOStreams() ioStreams, _, _, errBuf := genericclioptions.NewTestIOStreams()
cmd := NewCmdDrain(tf, ioStreams) cmd := NewCmdDrain(tf, ioStreams)
......
...@@ -38,6 +38,7 @@ import ( ...@@ -38,6 +38,7 @@ import (
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/genericclioptions/resource" "k8s.io/cli-runtime/pkg/genericclioptions/resource"
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/kubectl/cmd/apply"
"k8s.io/kubernetes/pkg/kubectl/cmd/create" "k8s.io/kubernetes/pkg/kubectl/cmd/create"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
...@@ -102,13 +103,13 @@ func TestEdit(t *testing.T) { ...@@ -102,13 +103,13 @@ func TestEdit(t *testing.T) {
} }
} }
inputFile := filepath.Join("testdata/edit", "testcase-"+name, step.Input) inputFile := filepath.Join("testdata", "testcase-"+name, step.Input)
expectedInput, err := ioutil.ReadFile(inputFile) expectedInput, err := ioutil.ReadFile(inputFile)
if err != nil { if err != nil {
t.Fatalf("%s, step %d: %v", name, i, err) t.Fatalf("%s, step %d: %v", name, i, err)
} }
outputFile := filepath.Join("testdata/edit", "testcase-"+name, step.Output) outputFile := filepath.Join("testdata", "testcase-"+name, step.Output)
resultingOutput, err := ioutil.ReadFile(outputFile) resultingOutput, err := ioutil.ReadFile(outputFile)
if err != nil { if err != nil {
t.Fatalf("%s, step %d: %v", name, i, err) t.Fatalf("%s, step %d: %v", name, i, err)
...@@ -150,7 +151,7 @@ func TestEdit(t *testing.T) { ...@@ -150,7 +151,7 @@ func TestEdit(t *testing.T) {
t.Logf("If the change in input is expected, rerun tests with %s=true to update input fixtures", updateEnvVar) t.Logf("If the change in input is expected, rerun tests with %s=true to update input fixtures", updateEnvVar)
} }
} }
return &http.Response{StatusCode: step.ResponseStatusCode, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader(resultingOutput))}, nil return &http.Response{StatusCode: step.ResponseStatusCode, Header: cmdtesting.DefaultHeader(), Body: ioutil.NopCloser(bytes.NewReader(resultingOutput))}, nil
} }
} }
...@@ -169,15 +170,15 @@ func TestEdit(t *testing.T) { ...@@ -169,15 +170,15 @@ func TestEdit(t *testing.T) {
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
os.Setenv("KUBE_EDITOR", "testdata/edit/test_editor.sh") os.Setenv("KUBE_EDITOR", "testdata/test_editor.sh")
os.Setenv("KUBE_EDITOR_CALLBACK", server.URL+"/callback") os.Setenv("KUBE_EDITOR_CALLBACK", server.URL+"/callback")
testcases := sets.NewString() testcases := sets.NewString()
filepath.Walk("testdata/edit", func(path string, info os.FileInfo, err error) error { filepath.Walk("testdata", func(path string, info os.FileInfo, err error) error {
if err != nil { if err != nil {
return err return err
} }
if path == "testdata/edit" { if path == "testdata" {
return nil return nil
} }
name := filepath.Base(path) name := filepath.Base(path)
...@@ -199,7 +200,7 @@ func TestEdit(t *testing.T) { ...@@ -199,7 +200,7 @@ func TestEdit(t *testing.T) {
i = 0 i = 0
name = testcaseName name = testcaseName
testcase = EditTestCase{} testcase = EditTestCase{}
testcaseDir := filepath.Join("testdata", "edit", "testcase-"+name) testcaseDir := filepath.Join("testdata", "testcase-"+name)
testcaseData, err := ioutil.ReadFile(filepath.Join(testcaseDir, "test.yaml")) testcaseData, err := ioutil.ReadFile(filepath.Join(testcaseDir, "test.yaml"))
if err != nil { if err != nil {
t.Fatalf("%s: %v", name, err) t.Fatalf("%s: %v", name, err)
...@@ -220,12 +221,12 @@ func TestEdit(t *testing.T) { ...@@ -220,12 +221,12 @@ func TestEdit(t *testing.T) {
} }
return &fake.RESTClient{ return &fake.RESTClient{
VersionedAPIPath: versionedAPIPath, VersionedAPIPath: versionedAPIPath,
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Client: fake.CreateHTTPClient(reqResp), Client: fake.CreateHTTPClient(reqResp),
}, nil }, nil
} }
tf.WithNamespace(testcase.Namespace) tf.WithNamespace(testcase.Namespace)
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams() ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
var cmd *cobra.Command var cmd *cobra.Command
...@@ -236,7 +237,7 @@ func TestEdit(t *testing.T) { ...@@ -236,7 +237,7 @@ func TestEdit(t *testing.T) {
cmd = create.NewCmdCreate(tf, ioStreams) cmd = create.NewCmdCreate(tf, ioStreams)
cmd.Flags().Set("edit", "true") cmd.Flags().Set("edit", "true")
case "edit-last-applied": case "edit-last-applied":
cmd = NewCmdApplyEditLastApplied(tf, ioStreams) cmd = apply.NewCmdApplyEditLastApplied(tf, ioStreams)
default: default:
t.Fatalf("%s: unexpected mode %s", name, testcase.Mode) t.Fatalf("%s: unexpected mode %s", name, testcase.Mode)
} }
......
...@@ -212,7 +212,7 @@ func (p *ExecOptions) Validate() error { ...@@ -212,7 +212,7 @@ func (p *ExecOptions) Validate() error {
return nil return nil
} }
func (o *StreamOptions) setupTTY() term.TTY { func (o *StreamOptions) SetupTTY() term.TTY {
t := term.TTY{ t := term.TTY{
Parent: o.InterruptParent, Parent: o.InterruptParent,
Out: o.Out, Out: o.Out,
...@@ -288,7 +288,7 @@ func (p *ExecOptions) Run() error { ...@@ -288,7 +288,7 @@ func (p *ExecOptions) Run() error {
} }
// ensure we can recover the terminal while attached // ensure we can recover the terminal while attached
t := p.setupTTY() t := p.SetupTTY()
var sizeQueue remotecommand.TerminalSizeQueue var sizeQueue remotecommand.TerminalSizeQueue
if t.Raw { if t.Raw {
......
...@@ -140,7 +140,7 @@ func TestPodAndContainer(t *testing.T) { ...@@ -140,7 +140,7 @@ func TestPodAndContainer(t *testing.T) {
NegotiatedSerializer: ns, NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { return nil, nil }), Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { return nil, nil }),
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
cmd := &cobra.Command{} cmd := &cobra.Command{}
options := test.p options := test.p
...@@ -202,15 +202,15 @@ func TestExec(t *testing.T) { ...@@ -202,15 +202,15 @@ func TestExec(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET": case p == test.podPath && m == "GET":
body := objBody(codec, test.pod) body := cmdtesting.ObjBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: body}, nil
default: default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req) t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request") return nil, fmt.Errorf("unexpected request")
} }
}), }),
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
ex := &fakeRemoteExecutor{} ex := &fakeRemoteExecutor{}
if test.execErr { if test.execErr {
ex.execErr = fmt.Errorf("exec error") ex.execErr = fmt.Errorf("exec error")
...@@ -280,7 +280,7 @@ func TestSetupTTY(t *testing.T) { ...@@ -280,7 +280,7 @@ func TestSetupTTY(t *testing.T) {
TTY: true, TTY: true,
} }
tty := o.setupTTY() tty := o.SetupTTY()
if o.In != nil { if o.In != nil {
t.Errorf("don't attach stdin: o.In should be nil") t.Errorf("don't attach stdin: o.In should be nil")
...@@ -304,7 +304,7 @@ func TestSetupTTY(t *testing.T) { ...@@ -304,7 +304,7 @@ func TestSetupTTY(t *testing.T) {
o.In = &bytes.Buffer{} o.In = &bytes.Buffer{}
o.TTY = false o.TTY = false
tty = o.setupTTY() tty = o.SetupTTY()
if o.In == nil { if o.In == nil {
t.Errorf("attach stdin, no TTY: o.In should not be nil") t.Errorf("attach stdin, no TTY: o.In should not be nil")
...@@ -328,7 +328,7 @@ func TestSetupTTY(t *testing.T) { ...@@ -328,7 +328,7 @@ func TestSetupTTY(t *testing.T) {
o.ErrOut = stderr o.ErrOut = stderr
o.TTY = true o.TTY = true
tty = o.setupTTY() tty = o.SetupTTY()
if o.In == nil { if o.In == nil {
t.Errorf("attach stdin, TTY, not a terminal: o.In should not be nil") t.Errorf("attach stdin, TTY, not a terminal: o.In should not be nil")
...@@ -363,7 +363,7 @@ func TestSetupTTY(t *testing.T) { ...@@ -363,7 +363,7 @@ func TestSetupTTY(t *testing.T) {
return true return true
} }
tty = o.setupTTY() tty = o.SetupTTY()
if o.In != overrideStdin { if o.In != overrideStdin {
t.Errorf("attach stdin, TTY, is a terminal: o.In should equal overrideStdin") t.Errorf("attach stdin, TTY, is a terminal: o.In should equal overrideStdin")
......
...@@ -306,7 +306,7 @@ func TestRunExposeService(t *testing.T) { ...@@ -306,7 +306,7 @@ func TestRunExposeService(t *testing.T) {
Selector: map[string]string{"app": "go"}, Selector: map[string]string{"app": "go"},
}, },
}, },
flags: map[string]string{"filename": "../../../test/e2e/testing-manifests/guestbook/redis-master-service.yaml", "selector": "func=stream", "protocol": "UDP", "port": "14", "name": "foo", "labels": "svc=test", "dry-run": "true"}, flags: map[string]string{"filename": "../../../../test/e2e/testing-manifests/guestbook/redis-master-service.yaml", "selector": "func=stream", "protocol": "UDP", "port": "14", "name": "foo", "labels": "svc=test", "dry-run": "true"},
output: &corev1.Service{ output: &corev1.Service{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Labels: map[string]string{"svc": "test"}}, ObjectMeta: metav1.ObjectMeta{Name: "foo", Labels: map[string]string{"svc": "test"}},
Spec: corev1.ServiceSpec{ Spec: corev1.ServiceSpec{
...@@ -610,7 +610,7 @@ func TestRunExposeService(t *testing.T) { ...@@ -610,7 +610,7 @@ func TestRunExposeService(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == test.calls[m] && m == "GET": case p == test.calls[m] && m == "GET":
return &http.Response{StatusCode: test.status, Header: defaultHeader(), Body: objBody(codec, test.input)}, nil return &http.Response{StatusCode: test.status, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, test.input)}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
......
...@@ -27,6 +27,7 @@ import ( ...@@ -27,6 +27,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/genericclioptions/resource"
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/kubectl/scheme"
...@@ -324,7 +325,7 @@ func TestLabelErrors(t *testing.T) { ...@@ -324,7 +325,7 @@ func TestLabelErrors(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup() defer tf.Cleanup()
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
ioStreams, _, _, _ := genericclioptions.NewTestIOStreams() ioStreams, _, _, _ := genericclioptions.NewTestIOStreams()
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
...@@ -354,20 +355,20 @@ func TestLabelErrors(t *testing.T) { ...@@ -354,20 +355,20 @@ func TestLabelErrors(t *testing.T) {
} }
func TestLabelForResourceFromFile(t *testing.T) { func TestLabelForResourceFromFile(t *testing.T) {
pods, _, _ := testData() pods, _, _ := cmdtesting.TestData()
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup() defer tf.Cleanup()
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...) codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch req.Method { switch req.Method {
case "GET": case "GET":
switch req.URL.Path { switch req.URL.Path {
case "/namespaces/test/replicationcontrollers/cassandra": case "/namespaces/test/replicationcontrollers/cassandra":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &pods.Items[0])}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &pods.Items[0])}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -375,7 +376,7 @@ func TestLabelForResourceFromFile(t *testing.T) { ...@@ -375,7 +376,7 @@ func TestLabelForResourceFromFile(t *testing.T) {
case "PATCH": case "PATCH":
switch req.URL.Path { switch req.URL.Path {
case "/namespaces/test/replicationcontrollers/cassandra": case "/namespaces/test/replicationcontrollers/cassandra":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &pods.Items[0])}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &pods.Items[0])}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -386,12 +387,12 @@ func TestLabelForResourceFromFile(t *testing.T) { ...@@ -386,12 +387,12 @@ func TestLabelForResourceFromFile(t *testing.T) {
} }
}), }),
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams() ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdLabel(tf, ioStreams) cmd := NewCmdLabel(tf, ioStreams)
opts := NewLabelOptions(ioStreams) opts := NewLabelOptions(ioStreams)
opts.Filenames = []string{"../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"} opts.Filenames = []string{"../../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}
err := opts.Complete(tf, cmd, []string{"a=b"}) err := opts.Complete(tf, cmd, []string{"a=b"})
if err == nil { if err == nil {
err = opts.Validate() err = opts.Validate()
...@@ -412,18 +413,18 @@ func TestLabelLocal(t *testing.T) { ...@@ -412,18 +413,18 @@ func TestLabelLocal(t *testing.T) {
defer tf.Cleanup() defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req) t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
return nil, nil return nil, nil
}), }),
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams() ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdLabel(tf, ioStreams) cmd := NewCmdLabel(tf, ioStreams)
opts := NewLabelOptions(ioStreams) opts := NewLabelOptions(ioStreams)
opts.Filenames = []string{"../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"} opts.Filenames = []string{"../../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}
opts.local = true opts.local = true
err := opts.Complete(tf, cmd, []string{"a=b"}) err := opts.Complete(tf, cmd, []string{"a=b"})
if err == nil { if err == nil {
...@@ -441,20 +442,20 @@ func TestLabelLocal(t *testing.T) { ...@@ -441,20 +442,20 @@ func TestLabelLocal(t *testing.T) {
} }
func TestLabelMultipleObjects(t *testing.T) { func TestLabelMultipleObjects(t *testing.T) {
pods, _, _ := testData() pods, _, _ := cmdtesting.TestData()
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup() defer tf.Cleanup()
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...) codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch req.Method { switch req.Method {
case "GET": case "GET":
switch req.URL.Path { switch req.URL.Path {
case "/namespaces/test/pods": case "/namespaces/test/pods":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, pods)}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, pods)}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -462,9 +463,9 @@ func TestLabelMultipleObjects(t *testing.T) { ...@@ -462,9 +463,9 @@ func TestLabelMultipleObjects(t *testing.T) {
case "PATCH": case "PATCH":
switch req.URL.Path { switch req.URL.Path {
case "/namespaces/test/pods/foo": case "/namespaces/test/pods/foo":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &pods.Items[0])}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &pods.Items[0])}, nil
case "/namespaces/test/pods/bar": case "/namespaces/test/pods/bar":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &pods.Items[1])}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &pods.Items[1])}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -475,7 +476,7 @@ func TestLabelMultipleObjects(t *testing.T) { ...@@ -475,7 +476,7 @@ func TestLabelMultipleObjects(t *testing.T) {
} }
}), }),
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams() ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
opts := NewLabelOptions(ioStreams) opts := NewLabelOptions(ioStreams)
......
...@@ -75,6 +75,10 @@ var ( ...@@ -75,6 +75,10 @@ var (
logsUsageErrStr = fmt.Sprintf("expected '%s'.\nPOD or TYPE/NAME is a required argument for the logs command", logsUsageStr) logsUsageErrStr = fmt.Sprintf("expected '%s'.\nPOD or TYPE/NAME is a required argument for the logs command", logsUsageStr)
) )
const (
defaultPodLogsTimeout = 20 * time.Second
)
type LogsOptions struct { type LogsOptions struct {
Namespace string Namespace string
ResourceArg string ResourceArg string
...@@ -126,7 +130,7 @@ func NewCmdLogs(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.C ...@@ -126,7 +130,7 @@ func NewCmdLogs(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.C
Example: logsExample, Example: logsExample,
PreRun: func(cmd *cobra.Command, args []string) { PreRun: func(cmd *cobra.Command, args []string) {
if len(os.Args) > 1 && os.Args[1] == "log" { if len(os.Args) > 1 && os.Args[1] == "log" {
printDeprecationWarning(o.ErrOut, "logs", "log") fmt.Fprintf(o.ErrOut, "%s is DEPRECATED and will be removed in a future version. Use %s instead.\n", "log", "logs")
} }
}, },
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
......
...@@ -22,13 +22,14 @@ import ( ...@@ -22,13 +22,14 @@ import (
"testing" "testing"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/genericclioptions/resource"
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/kubectl/scheme"
) )
func TestPatchObject(t *testing.T) { func TestPatchObject(t *testing.T) {
_, svc, _ := testData() _, svc, _ := cmdtesting.TestData()
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup() defer tf.Cleanup()
...@@ -36,7 +37,7 @@ func TestPatchObject(t *testing.T) { ...@@ -36,7 +37,7 @@ func TestPatchObject(t *testing.T) {
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...) codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/services/frontend" && (m == "PATCH" || m == "GET"): case p == "/namespaces/test/services/frontend" && (m == "PATCH" || m == "GET"):
...@@ -47,7 +48,7 @@ func TestPatchObject(t *testing.T) { ...@@ -47,7 +48,7 @@ func TestPatchObject(t *testing.T) {
if m == "PATCH" { if m == "PATCH" {
obj.Spec.Type = "NodePort" obj.Spec.Type = "NodePort"
} }
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &obj)}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &obj)}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -69,7 +70,7 @@ func TestPatchObject(t *testing.T) { ...@@ -69,7 +70,7 @@ func TestPatchObject(t *testing.T) {
} }
func TestPatchObjectFromFile(t *testing.T) { func TestPatchObjectFromFile(t *testing.T) {
_, svc, _ := testData() _, svc, _ := cmdtesting.TestData()
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup() defer tf.Cleanup()
...@@ -77,11 +78,11 @@ func TestPatchObjectFromFile(t *testing.T) { ...@@ -77,11 +78,11 @@ func TestPatchObjectFromFile(t *testing.T) {
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...) codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/services/frontend" && (m == "PATCH" || m == "GET"): case p == "/namespaces/test/services/frontend" && (m == "PATCH" || m == "GET"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &svc.Items[0])}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &svc.Items[0])}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -94,7 +95,7 @@ func TestPatchObjectFromFile(t *testing.T) { ...@@ -94,7 +95,7 @@ func TestPatchObjectFromFile(t *testing.T) {
cmd.Flags().Set("namespace", "test") cmd.Flags().Set("namespace", "test")
cmd.Flags().Set("patch", `{"spec":{"type":"NodePort"}}`) cmd.Flags().Set("patch", `{"spec":{"type":"NodePort"}}`)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/frontend-service.yaml") cmd.Flags().Set("filename", "../../../../test/e2e/testing-manifests/guestbook/frontend-service.yaml")
cmd.Run(cmd, []string{}) cmd.Run(cmd, []string{})
// uses the name from the response // uses the name from the response
...@@ -104,7 +105,7 @@ func TestPatchObjectFromFile(t *testing.T) { ...@@ -104,7 +105,7 @@ func TestPatchObjectFromFile(t *testing.T) {
} }
func TestPatchNoop(t *testing.T) { func TestPatchNoop(t *testing.T) {
_, svc, _ := testData() _, svc, _ := cmdtesting.TestData()
getObject := &svc.Items[0] getObject := &svc.Items[0]
patchObject := &svc.Items[0] patchObject := &svc.Items[0]
...@@ -114,13 +115,13 @@ func TestPatchNoop(t *testing.T) { ...@@ -114,13 +115,13 @@ func TestPatchNoop(t *testing.T) {
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...) codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/services/frontend" && m == "PATCH": case p == "/namespaces/test/services/frontend" && m == "PATCH":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, patchObject)}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, patchObject)}, nil
case p == "/namespaces/test/services/frontend" && m == "GET": case p == "/namespaces/test/services/frontend" && m == "GET":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, getObject)}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, getObject)}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -147,7 +148,7 @@ func TestPatchNoop(t *testing.T) { ...@@ -147,7 +148,7 @@ func TestPatchNoop(t *testing.T) {
} }
func TestPatchObjectFromFileOutput(t *testing.T) { func TestPatchObjectFromFileOutput(t *testing.T) {
_, svc, _ := testData() _, svc, _ := cmdtesting.TestData()
svcCopy := svc.Items[0].DeepCopy() svcCopy := svc.Items[0].DeepCopy()
if svcCopy.Labels == nil { if svcCopy.Labels == nil {
...@@ -161,13 +162,13 @@ func TestPatchObjectFromFileOutput(t *testing.T) { ...@@ -161,13 +162,13 @@ func TestPatchObjectFromFileOutput(t *testing.T) {
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...) codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{ tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer, NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/services/frontend" && m == "GET": case p == "/namespaces/test/services/frontend" && m == "GET":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &svc.Items[0])}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &svc.Items[0])}, nil
case p == "/namespaces/test/services/frontend" && m == "PATCH": case p == "/namespaces/test/services/frontend" && m == "PATCH":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, svcCopy)}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, svcCopy)}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -180,7 +181,7 @@ func TestPatchObjectFromFileOutput(t *testing.T) { ...@@ -180,7 +181,7 @@ func TestPatchObjectFromFileOutput(t *testing.T) {
cmd.Flags().Set("namespace", "test") cmd.Flags().Set("namespace", "test")
cmd.Flags().Set("patch", `{"spec":{"type":"NodePort"}}`) cmd.Flags().Set("patch", `{"spec":{"type":"NodePort"}}`)
cmd.Flags().Set("output", "yaml") cmd.Flags().Set("output", "yaml")
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/frontend-service.yaml") cmd.Flags().Set("filename", "../../../../test/e2e/testing-manifests/guestbook/frontend-service.yaml")
cmd.Run(cmd, []string{}) cmd.Run(cmd, []string{})
t.Log(buf.String()) t.Log(buf.String())
......
...@@ -26,6 +26,7 @@ import ( ...@@ -26,6 +26,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
...@@ -85,15 +86,15 @@ func testPortForward(t *testing.T, flags map[string]string, args []string) { ...@@ -85,15 +86,15 @@ func testPortForward(t *testing.T, flags map[string]string, args []string) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET": case p == test.podPath && m == "GET":
body := objBody(codec, test.pod) body := cmdtesting.ObjBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: body}, nil
default: default:
t.Errorf("%s: unexpected request: %#v\n%#v", test.name, req.URL, req) t.Errorf("%s: unexpected request: %#v\n%#v", test.name, req.URL, req)
return nil, nil return nil, nil
} }
}), }),
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
ff := &fakePortForwarder{} ff := &fakePortForwarder{}
if test.pfErr { if test.pfErr {
ff.pfErr = fmt.Errorf("pf error") ff.pfErr = fmt.Errorf("pf error")
...@@ -354,3 +355,21 @@ func TestTranslateServicePortToTargetPort(t *testing.T) { ...@@ -354,3 +355,21 @@ func TestTranslateServicePortToTargetPort(t *testing.T) {
} }
} }
} }
func execPod() *corev1.Pod {
return &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "10"},
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyAlways,
DNSPolicy: corev1.DNSClusterFirst,
Containers: []corev1.Container{
{
Name: "bar",
},
},
},
Status: corev1.PodStatus{
Phase: corev1.PodRunning,
},
}
}
...@@ -33,6 +33,7 @@ import ( ...@@ -33,6 +33,7 @@ import (
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/genericclioptions/resource" "k8s.io/cli-runtime/pkg/genericclioptions/resource"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/delete"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/kubectl/scheme"
...@@ -67,10 +68,10 @@ var ( ...@@ -67,10 +68,10 @@ var (
type ReplaceOptions struct { type ReplaceOptions struct {
PrintFlags *genericclioptions.PrintFlags PrintFlags *genericclioptions.PrintFlags
DeleteFlags *DeleteFlags
RecordFlags *genericclioptions.RecordFlags RecordFlags *genericclioptions.RecordFlags
DeleteOptions *DeleteOptions DeleteFlags *delete.DeleteFlags
DeleteOptions *delete.DeleteOptions
PrintObj func(obj runtime.Object) error PrintObj func(obj runtime.Object) error
...@@ -92,7 +93,7 @@ type ReplaceOptions struct { ...@@ -92,7 +93,7 @@ type ReplaceOptions struct {
func NewReplaceOptions(streams genericclioptions.IOStreams) *ReplaceOptions { func NewReplaceOptions(streams genericclioptions.IOStreams) *ReplaceOptions {
return &ReplaceOptions{ return &ReplaceOptions{
PrintFlags: genericclioptions.NewPrintFlags("replaced"), PrintFlags: genericclioptions.NewPrintFlags("replaced"),
DeleteFlags: NewDeleteFlags("to use to replace the resource."), DeleteFlags: delete.NewDeleteFlags("to use to replace the resource."),
IOStreams: streams, IOStreams: streams,
} }
......
...@@ -72,10 +72,10 @@ var ( ...@@ -72,10 +72,10 @@ var (
kubectl rolling-update frontend-v1 frontend-v2 --rollback`)) kubectl rolling-update frontend-v1 frontend-v2 --rollback`))
) )
var ( const (
updatePeriod, _ = time.ParseDuration("1m0s") updatePeriod = 1 * time.Minute
timeout, _ = time.ParseDuration("5m0s") timeout = 5 * time.Minute
pollInterval, _ = time.ParseDuration("3s") pollInterval = 3 * time.Second
) )
type RollingUpdateOptions struct { type RollingUpdateOptions struct {
......
...@@ -53,7 +53,7 @@ func TestRolloutPause(t *testing.T) { ...@@ -53,7 +53,7 @@ func TestRolloutPause(t *testing.T) {
responseDeployment := &extensionsv1beta1.Deployment{} responseDeployment := &extensionsv1beta1.Deployment{}
responseDeployment.Name = deploymentName responseDeployment.Name = deploymentName
body := ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(encoder, responseDeployment)))) body := ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(encoder, responseDeployment))))
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: body}, nil return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: body}, nil
default: default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
...@@ -113,9 +113,3 @@ func (c *RolloutPauseRESTClient) Patch(pt types.PatchType) *restclient.Request { ...@@ -113,9 +113,3 @@ func (c *RolloutPauseRESTClient) Patch(pt types.PatchType) *restclient.Request {
} }
return restclient.NewRequest(c, "PATCH", &url.URL{Host: "localhost"}, c.VersionedAPIPath, config, serializers, nil, nil, 0) return restclient.NewRequest(c, "PATCH", &url.URL{Host: "localhost"}, c.VersionedAPIPath, config, serializers, nil, nil, 0)
} }
func defaultHeader() http.Header {
header := http.Header{}
header.Set("Content-Type", runtime.ContentTypeJSON)
return header
}
...@@ -39,6 +39,10 @@ import ( ...@@ -39,6 +39,10 @@ import (
corev1client "k8s.io/client-go/kubernetes/typed/core/v1" corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
watchtools "k8s.io/client-go/tools/watch" watchtools "k8s.io/client-go/tools/watch"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/attach"
"k8s.io/kubernetes/pkg/kubectl/cmd/delete"
"k8s.io/kubernetes/pkg/kubectl/cmd/exec"
"k8s.io/kubernetes/pkg/kubectl/cmd/logs"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers" "k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"
...@@ -92,16 +96,23 @@ var ( ...@@ -92,16 +96,23 @@ var (
kubectl run pi --schedule="0/5 * * * ?" --image=perl --restart=OnFailure -- perl -Mbignum=bpi -wle 'print bpi(2000)'`)) kubectl run pi --schedule="0/5 * * * ?" --image=perl --restart=OnFailure -- perl -Mbignum=bpi -wle 'print bpi(2000)'`))
) )
const (
defaultPodAttachTimeout = 60 * time.Second
)
var metadataAccessor = meta.NewAccessor()
type RunObject struct { type RunObject struct {
Object runtime.Object Object runtime.Object
Mapping *meta.RESTMapping Mapping *meta.RESTMapping
} }
type RunOptions struct { type RunOptions struct {
PrintFlags *genericclioptions.PrintFlags PrintFlags *genericclioptions.PrintFlags
DeleteFlags *DeleteFlags RecordFlags *genericclioptions.RecordFlags
DeleteOptions *DeleteOptions
RecordFlags *genericclioptions.RecordFlags DeleteFlags *delete.DeleteFlags
DeleteOptions *delete.DeleteOptions
DryRun bool DryRun bool
...@@ -128,7 +139,7 @@ type RunOptions struct { ...@@ -128,7 +139,7 @@ type RunOptions struct {
func NewRunOptions(streams genericclioptions.IOStreams) *RunOptions { func NewRunOptions(streams genericclioptions.IOStreams) *RunOptions {
return &RunOptions{ return &RunOptions{
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme), PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
DeleteFlags: NewDeleteFlags("to use to replace the resource."), DeleteFlags: delete.NewDeleteFlags("to use to replace the resource."),
RecordFlags: genericclioptions.NewRecordFlags(), RecordFlags: genericclioptions.NewRecordFlags(),
Recorder: genericclioptions.NoopRecorder{}, Recorder: genericclioptions.NoopRecorder{},
...@@ -369,8 +380,8 @@ func (o *RunOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e ...@@ -369,8 +380,8 @@ func (o *RunOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
defer o.removeCreatedObjects(f, createdObjects) defer o.removeCreatedObjects(f, createdObjects)
} }
opts := &AttachOptions{ opts := &attach.AttachOptions{
StreamOptions: StreamOptions{ StreamOptions: exec.StreamOptions{
IOStreams: o.IOStreams, IOStreams: o.IOStreams,
Stdin: o.Interactive, Stdin: o.Interactive,
TTY: o.TTY, TTY: o.TTY,
...@@ -379,14 +390,14 @@ func (o *RunOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e ...@@ -379,14 +390,14 @@ func (o *RunOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
GetPodTimeout: timeout, GetPodTimeout: timeout,
CommandName: cmd.Parent().CommandPath() + " attach", CommandName: cmd.Parent().CommandPath() + " attach",
Attach: &DefaultRemoteAttach{}, Attach: &attach.DefaultRemoteAttach{},
} }
config, err := f.ToRESTConfig() config, err := f.ToRESTConfig()
if err != nil { if err != nil {
return err return err
} }
opts.Config = config opts.Config = config
opts.AttachFunc = defaultAttachFunc opts.AttachFunc = attach.DefaultAttachFunc
clientset, err := kubernetes.NewForConfig(config) clientset, err := kubernetes.NewForConfig(config)
if err != nil { if err != nil {
...@@ -504,7 +515,7 @@ func waitForPod(podClient corev1client.PodsGetter, ns, name string, exitConditio ...@@ -504,7 +515,7 @@ func waitForPod(podClient corev1client.PodsGetter, ns, name string, exitConditio
return result, err return result, err
} }
func handleAttachPod(f cmdutil.Factory, podClient corev1client.PodsGetter, ns, name string, opts *AttachOptions) error { func handleAttachPod(f cmdutil.Factory, podClient corev1client.PodsGetter, ns, name string, opts *attach.AttachOptions) error {
pod, err := waitForPod(podClient, ns, name, kubectl.PodRunningAndReady) pod, err := waitForPod(podClient, ns, name, kubectl.PodRunningAndReady)
if err != nil && err != kubectl.ErrPodCompleted { if err != nil && err != kubectl.ErrPodCompleted {
return err return err
...@@ -519,7 +530,7 @@ func handleAttachPod(f cmdutil.Factory, podClient corev1client.PodsGetter, ns, n ...@@ -519,7 +530,7 @@ func handleAttachPod(f cmdutil.Factory, podClient corev1client.PodsGetter, ns, n
opts.Namespace = ns opts.Namespace = ns
if opts.AttachFunc == nil { if opts.AttachFunc == nil {
opts.AttachFunc = defaultAttachFunc opts.AttachFunc = attach.DefaultAttachFunc
} }
if err := opts.Run(); err != nil { if err := opts.Run(); err != nil {
...@@ -530,7 +541,7 @@ func handleAttachPod(f cmdutil.Factory, podClient corev1client.PodsGetter, ns, n ...@@ -530,7 +541,7 @@ func handleAttachPod(f cmdutil.Factory, podClient corev1client.PodsGetter, ns, n
} }
// logOpts logs output from opts to the pods log. // logOpts logs output from opts to the pods log.
func logOpts(restClientGetter genericclioptions.RESTClientGetter, pod *corev1.Pod, opts *AttachOptions) error { func logOpts(restClientGetter genericclioptions.RESTClientGetter, pod *corev1.Pod, opts *attach.AttachOptions) error {
ctrName, err := opts.GetContainerName(pod) ctrName, err := opts.GetContainerName(pod)
if err != nil { if err != nil {
return err return err
...@@ -541,7 +552,7 @@ func logOpts(restClientGetter genericclioptions.RESTClientGetter, pod *corev1.Po ...@@ -541,7 +552,7 @@ func logOpts(restClientGetter genericclioptions.RESTClientGetter, pod *corev1.Po
return err return err
} }
for _, request := range requests { for _, request := range requests {
if err := DefaultConsumeRequest(request, opts.Out); err != nil { if err := logs.DefaultConsumeRequest(request, opts.Out); err != nil {
return err return err
} }
} }
......
...@@ -36,6 +36,7 @@ import ( ...@@ -36,6 +36,7 @@ import (
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
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/kubernetes/pkg/kubectl/cmd/delete"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/kubectl/scheme"
...@@ -174,7 +175,7 @@ func TestRunArgsFollowDashRules(t *testing.T) { ...@@ -174,7 +175,7 @@ func TestRunArgsFollowDashRules(t *testing.T) {
NegotiatedSerializer: ns, NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
if req.URL.Path == "/namespaces/test/replicationcontrollers" { if req.URL.Path == "/namespaces/test/replicationcontrollers" {
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: objBody(codec, rc)}, nil return &http.Response{StatusCode: 201, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, rc)}, nil
} }
return &http.Response{ return &http.Response{
StatusCode: http.StatusOK, StatusCode: http.StatusOK,
...@@ -196,7 +197,7 @@ func TestRunArgsFollowDashRules(t *testing.T) { ...@@ -196,7 +197,7 @@ func TestRunArgsFollowDashRules(t *testing.T) {
return return
} }
deleteFlags := NewDeleteFlags("to use to replace the resource.") deleteFlags := delete.NewDeleteFlags("to use to replace the resource.")
opts := &RunOptions{ opts := &RunOptions{
PrintFlags: printFlags, PrintFlags: printFlags,
DeleteOptions: deleteFlags.ToOptions(nil, genericclioptions.NewTestIOStreamsDiscard()), DeleteOptions: deleteFlags.ToOptions(nil, genericclioptions.NewTestIOStreamsDiscard()),
...@@ -328,7 +329,7 @@ func TestGenerateService(t *testing.T) { ...@@ -328,7 +329,7 @@ func TestGenerateService(t *testing.T) {
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...) codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
ns := scheme.Codecs ns := scheme.Codecs
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
tf.Client = &fake.RESTClient{ tf.Client = &fake.RESTClient{
GroupVersion: corev1.SchemeGroupVersion, GroupVersion: corev1.SchemeGroupVersion,
NegotiatedSerializer: ns, NegotiatedSerializer: ns,
...@@ -336,7 +337,7 @@ func TestGenerateService(t *testing.T) { ...@@ -336,7 +337,7 @@ func TestGenerateService(t *testing.T) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case test.expectPOST && m == "POST" && p == "/namespaces/test/services": case test.expectPOST && m == "POST" && p == "/namespaces/test/services":
sawPOST = true sawPOST = true
body := objBody(codec, &test.service) body := cmdtesting.ObjBody(codec, &test.service)
data, err := ioutil.ReadAll(req.Body) data, err := ioutil.ReadAll(req.Body)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
...@@ -352,7 +353,7 @@ func TestGenerateService(t *testing.T) { ...@@ -352,7 +353,7 @@ func TestGenerateService(t *testing.T) {
if !apiequality.Semantic.DeepEqual(&test.service, svc) { if !apiequality.Semantic.DeepEqual(&test.service, svc) {
t.Errorf("expected:\n%v\nsaw:\n%v\n", &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 return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: body}, nil
default: default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req) t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request") return nil, fmt.Errorf("unexpected request")
...@@ -368,7 +369,7 @@ func TestGenerateService(t *testing.T) { ...@@ -368,7 +369,7 @@ func TestGenerateService(t *testing.T) {
} }
ioStreams, _, buff, _ := genericclioptions.NewTestIOStreams() ioStreams, _, buff, _ := genericclioptions.NewTestIOStreams()
deleteFlags := NewDeleteFlags("to use to replace the resource.") deleteFlags := delete.NewDeleteFlags("to use to replace the resource.")
opts := &RunOptions{ opts := &RunOptions{
PrintFlags: printFlags, PrintFlags: printFlags,
DeleteOptions: deleteFlags.ToOptions(nil, genericclioptions.NewTestIOStreamsDiscard()), DeleteOptions: deleteFlags.ToOptions(nil, genericclioptions.NewTestIOStreamsDiscard()),
...@@ -506,9 +507,9 @@ func TestRunValidations(t *testing.T) { ...@@ -506,9 +507,9 @@ func TestRunValidations(t *testing.T) {
_, _, codec := cmdtesting.NewExternalScheme() _, _, codec := cmdtesting.NewExternalScheme()
tf.Client = &fake.RESTClient{ tf.Client = &fake.RESTClient{
NegotiatedSerializer: scheme.Codecs, NegotiatedSerializer: scheme.Codecs,
Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, cmdtesting.NewInternalType("", "", ""))}, Resp: &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, cmdtesting.NewInternalType("", "", ""))},
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
streams, _, _, bufErr := genericclioptions.NewTestIOStreams() streams, _, _, bufErr := genericclioptions.NewTestIOStreams()
cmdutil.BehaviorOnFatal(func(str string, code int) { cmdutil.BehaviorOnFatal(func(str string, code int) {
......
...@@ -64,6 +64,10 @@ var ( ...@@ -64,6 +64,10 @@ var (
kubectl scale --replicas=3 statefulset/web`)) kubectl scale --replicas=3 statefulset/web`))
) )
const (
timeout = 5 * time.Minute
)
type ScaleOptions struct { type ScaleOptions struct {
FilenameOptions resource.FilenameOptions FilenameOptions resource.FilenameOptions
RecordFlags *genericclioptions.RecordFlags RecordFlags *genericclioptions.RecordFlags
......
...@@ -452,7 +452,7 @@ func TestSetEnvRemote(t *testing.T) { ...@@ -452,7 +452,7 @@ func TestSetEnvRemote(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == input.path && m == http.MethodGet: case p == input.path && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(input.object)}, nil return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: objBody(input.object)}, nil
case p == input.path && m == http.MethodPatch: case p == input.path && m == http.MethodPatch:
stream, err := req.GetBody() stream, err := req.GetBody()
if err != nil { if err != nil {
...@@ -463,7 +463,7 @@ func TestSetEnvRemote(t *testing.T) { ...@@ -463,7 +463,7 @@ func TestSetEnvRemote(t *testing.T) {
return nil, err return nil, err
} }
assert.Contains(t, string(bytes), `"value":`+`"`+"prod"+`"`, fmt.Sprintf("env not updated for %#v", input.object)) 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(input.object)}, nil return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: objBody(input.object)}, nil
default: default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req) t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request") return nil, fmt.Errorf("unexpected request")
...@@ -587,11 +587,11 @@ func TestSetEnvFromResource(t *testing.T) { ...@@ -587,11 +587,11 @@ func TestSetEnvFromResource(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/configmaps/testconfigmap" && m == http.MethodGet: case p == "/namespaces/test/configmaps/testconfigmap" && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(mockConfigMap)}, nil return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: objBody(mockConfigMap)}, nil
case p == "/namespaces/test/secrets/testsecret" && m == http.MethodGet: case p == "/namespaces/test/secrets/testsecret" && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(mockSecret)}, nil return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: objBody(mockSecret)}, nil
case p == "/namespaces/test/deployments/nginx" && m == http.MethodGet: case p == "/namespaces/test/deployments/nginx" && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(mockDeployment)}, nil return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: objBody(mockDeployment)}, nil
case p == "/namespaces/test/deployments/nginx" && m == http.MethodPatch: case p == "/namespaces/test/deployments/nginx" && m == http.MethodPatch:
stream, err := req.GetBody() stream, err := req.GetBody()
if err != nil { if err != nil {
...@@ -607,7 +607,7 @@ func TestSetEnvFromResource(t *testing.T) { ...@@ -607,7 +607,7 @@ func TestSetEnvFromResource(t *testing.T) {
for _, exclude := range input.assertExcludes { for _, exclude := range input.assertExcludes {
assert.NotContains(t, string(bytes), exclude) assert.NotContains(t, string(bytes), exclude)
} }
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(mockDeployment)}, nil return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: objBody(mockDeployment)}, nil
default: default:
t.Errorf("%s: unexpected request: %#v\n%#v", input.name, req.URL, req) t.Errorf("%s: unexpected request: %#v\n%#v", input.name, req.URL, req)
return nil, nil return nil, nil
......
...@@ -535,7 +535,7 @@ func TestSetImageRemote(t *testing.T) { ...@@ -535,7 +535,7 @@ func TestSetImageRemote(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == input.path && m == http.MethodGet: case p == input.path && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(input.object)}, nil return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: objBody(input.object)}, nil
case p == input.path && m == http.MethodPatch: case p == input.path && m == http.MethodPatch:
stream, err := req.GetBody() stream, err := req.GetBody()
if err != nil { if err != nil {
...@@ -546,7 +546,7 @@ func TestSetImageRemote(t *testing.T) { ...@@ -546,7 +546,7 @@ func TestSetImageRemote(t *testing.T) {
return nil, err return nil, err
} }
assert.Contains(t, string(bytes), `"image":`+`"`+"thingy"+`"`, fmt.Sprintf("image not updated for %#v", input.object)) 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(input.object)}, nil return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: objBody(input.object)}, nil
default: default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req) t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request") return nil, fmt.Errorf("unexpected request")
......
...@@ -475,7 +475,7 @@ func TestSetResourcesRemote(t *testing.T) { ...@@ -475,7 +475,7 @@ func TestSetResourcesRemote(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == input.path && m == http.MethodGet: case p == input.path && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(input.object)}, nil return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: objBody(input.object)}, nil
case p == input.path && m == http.MethodPatch: case p == input.path && m == http.MethodPatch:
stream, err := req.GetBody() stream, err := req.GetBody()
if err != nil { if err != nil {
...@@ -486,7 +486,7 @@ func TestSetResourcesRemote(t *testing.T) { ...@@ -486,7 +486,7 @@ func TestSetResourcesRemote(t *testing.T) {
return nil, err return nil, err
} }
assert.Contains(t, string(bytes), "200m", fmt.Sprintf("resources not updated for %#v", input.object)) assert.Contains(t, string(bytes), "200m", fmt.Sprintf("resources not updated for %#v", input.object))
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(input.object)}, nil return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: objBody(input.object)}, nil
default: default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "resources", req.Method, req.URL, req) t.Errorf("%s: unexpected request: %s %#v\n%#v", "resources", req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request") return nil, fmt.Errorf("unexpected request")
......
...@@ -17,7 +17,6 @@ limitations under the License. ...@@ -17,7 +17,6 @@ limitations under the License.
package set package set
import ( import (
"bytes"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
...@@ -327,7 +326,7 @@ func TestSetServiceAccountRemote(t *testing.T) { ...@@ -327,7 +326,7 @@ func TestSetServiceAccountRemote(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == input.path && m == http.MethodGet: case p == input.path && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(input.object)}, nil return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: objBody(input.object)}, nil
case p == input.path && m == http.MethodPatch: case p == input.path && m == http.MethodPatch:
stream, err := req.GetBody() stream, err := req.GetBody()
if err != nil { if err != nil {
...@@ -338,7 +337,7 @@ func TestSetServiceAccountRemote(t *testing.T) { ...@@ -338,7 +337,7 @@ func TestSetServiceAccountRemote(t *testing.T) {
return nil, err return nil, err
} }
assert.Contains(t, string(bytes), `"serviceAccountName":`+`"`+serviceAccount+`"`, fmt.Sprintf("serviceaccount not updated for %#v", input.object)) 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(input.object)}, nil return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: objBody(input.object)}, nil
default: default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "serviceaccount", req.Method, req.URL, req) t.Errorf("%s: unexpected request: %s %#v\n%#v", "serviceaccount", req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request") return nil, fmt.Errorf("unexpected request")
...@@ -403,15 +402,5 @@ func TestServiceAccountValidation(t *testing.T) { ...@@ -403,15 +402,5 @@ func TestServiceAccountValidation(t *testing.T) {
} }
func objBody(obj runtime.Object) io.ReadCloser { func objBody(obj runtime.Object) io.ReadCloser {
return bytesBody([]byte(runtime.EncodeOrDie(scheme.DefaultJSONEncoder(), obj))) return cmdtesting.BytesBody([]byte(runtime.EncodeOrDie(scheme.DefaultJSONEncoder(), obj)))
}
func defaultHeader() http.Header {
header := http.Header{}
header.Set("Content-Type", runtime.ContentTypeJSON)
return header
}
func bytesBody(bodyBytes []byte) io.ReadCloser {
return ioutil.NopCloser(bytes.NewReader(bodyBytes))
} }
...@@ -20,6 +20,7 @@ import ( ...@@ -20,6 +20,7 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"reflect" "reflect"
"strings"
"testing" "testing"
"time" "time"
...@@ -251,9 +252,9 @@ func TestTaint(t *testing.T) { ...@@ -251,9 +252,9 @@ func TestTaint(t *testing.T) {
m := &MyReq{req} m := &MyReq{req}
switch { switch {
case m.isFor("GET", "/nodes"): case m.isFor("GET", "/nodes"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, oldNode)}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, oldNode)}, nil
case m.isFor("GET", "/nodes/node-name"): case m.isFor("GET", "/nodes/node-name"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, oldNode)}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, oldNode)}, nil
case m.isFor("PATCH", "/nodes/node-name"): case m.isFor("PATCH", "/nodes/node-name"):
tainted = true tainted = true
data, err := ioutil.ReadAll(req.Body) data, err := ioutil.ReadAll(req.Body)
...@@ -279,7 +280,7 @@ func TestTaint(t *testing.T) { ...@@ -279,7 +280,7 @@ func TestTaint(t *testing.T) {
if !equalTaints(expectNewNode.Spec.Taints, new_node.Spec.Taints) { 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) 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 return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, new_node)}, nil
case m.isFor("PUT", "/nodes/node-name"): case m.isFor("PUT", "/nodes/node-name"):
tainted = true tainted = true
data, err := ioutil.ReadAll(req.Body) data, err := ioutil.ReadAll(req.Body)
...@@ -293,14 +294,14 @@ func TestTaint(t *testing.T) { ...@@ -293,14 +294,14 @@ func TestTaint(t *testing.T) {
if !equalTaints(expectNewNode.Spec.Taints, new_node.Spec.Taints) { 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) 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 return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, new_node)}, nil
default: default:
t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req) t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req)
return nil, nil return nil, nil
} }
}), }),
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
cmd := NewCmdTaint(tf, genericclioptions.NewTestIOStreamsDiscard()) cmd := NewCmdTaint(tf, genericclioptions.NewTestIOStreamsDiscard())
...@@ -386,3 +387,16 @@ func TestValidateFlags(t *testing.T) { ...@@ -386,3 +387,16 @@ func TestValidateFlags(t *testing.T) {
} }
} }
} }
type MyReq struct {
Request *http.Request
}
func (m *MyReq) isFor(method string, path string) bool {
req := m.Request
return method == req.Method && (req.URL.Path == path ||
req.URL.Path == strings.Join([]string{"/api/v1", path}, "") ||
req.URL.Path == strings.Join([]string{"/apis/extensions/v1beta1", path}, "") ||
req.URL.Path == strings.Join([]string{"/apis/batch/v1", path}, ""))
}
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package testing
import (
"bytes"
"encoding/json"
"io"
"io/ioutil"
"net/http"
"testing"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
restclient "k8s.io/client-go/rest"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/scheme"
)
var (
grace = int64(30)
enableServiceLinks = corev1.DefaultEnableServiceLinks
)
func DefaultHeader() http.Header {
header := http.Header{}
header.Set("Content-Type", runtime.ContentTypeJSON)
return header
}
func DefaultClientConfig() *restclient.Config {
return &restclient.Config{
APIPath: "/api",
ContentConfig: restclient.ContentConfig{
NegotiatedSerializer: scheme.Codecs,
ContentType: runtime.ContentTypeJSON,
GroupVersion: &corev1.SchemeGroupVersion,
},
}
}
func ObjBody(codec runtime.Codec, obj runtime.Object) io.ReadCloser {
return ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, obj))))
}
func BytesBody(bodyBytes []byte) io.ReadCloser {
return ioutil.NopCloser(bytes.NewReader(bodyBytes))
}
func StringBody(body string) io.ReadCloser {
return ioutil.NopCloser(bytes.NewReader([]byte(body)))
}
func TestData() (*corev1.PodList, *corev1.ServiceList, *corev1.ReplicationControllerList) {
pods := &corev1.PodList{
ListMeta: metav1.ListMeta{
ResourceVersion: "15",
},
Items: []corev1.Pod{
{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "10"},
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyAlways,
DNSPolicy: corev1.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
SecurityContext: &corev1.PodSecurityContext{},
EnableServiceLinks: &enableServiceLinks,
},
},
{
ObjectMeta: metav1.ObjectMeta{Name: "bar", Namespace: "test", ResourceVersion: "11"},
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyAlways,
DNSPolicy: corev1.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
SecurityContext: &corev1.PodSecurityContext{},
EnableServiceLinks: &enableServiceLinks,
},
},
},
}
svc := &corev1.ServiceList{
ListMeta: metav1.ListMeta{
ResourceVersion: "16",
},
Items: []corev1.Service{
{
ObjectMeta: metav1.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "12"},
Spec: corev1.ServiceSpec{
SessionAffinity: "None",
Type: corev1.ServiceTypeClusterIP,
},
},
},
}
one := int32(1)
rc := &corev1.ReplicationControllerList{
ListMeta: metav1.ListMeta{
ResourceVersion: "17",
},
Items: []corev1.ReplicationController{
{
ObjectMeta: metav1.ObjectMeta{Name: "rc1", Namespace: "test", ResourceVersion: "18"},
Spec: corev1.ReplicationControllerSpec{
Replicas: &one,
},
},
},
}
return pods, svc, rc
}
func GenResponseWithJsonEncodedBody(bodyStruct interface{}) (*http.Response, error) {
jsonBytes, err := json.Marshal(bodyStruct)
if err != nil {
return nil, err
}
return &http.Response{StatusCode: 200, Header: DefaultHeader(), Body: BytesBody(jsonBytes)}, nil
}
func InitTestErrorHandler(t *testing.T) {
cmdutil.BehaviorOnFatal(func(str string, code int) {
t.Errorf("Error running command (exit code %d): %s", code, str)
})
}
func Int32ptr(val int) *int32 {
t := int32(val)
return &t
}
...@@ -142,7 +142,7 @@ func TestTopPod(t *testing.T) { ...@@ -142,7 +142,7 @@ func TestTopPod(t *testing.T) {
containers: true, containers: true,
}, },
} }
initTestErrorHandler(t) cmdtesting.InitTestErrorHandler(t)
for _, testCase := range testCases { for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) { t.Run(testCase.name, func(t *testing.T) {
t.Logf("Running test case: %s", testCase.name) t.Logf("Running test case: %s", testCase.name)
...@@ -183,15 +183,15 @@ func TestTopPod(t *testing.T) { ...@@ -183,15 +183,15 @@ func TestTopPod(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m, q := req.URL.Path, req.Method, req.URL.RawQuery; { switch p, m, q := req.URL.Path, req.Method, req.URL.RawQuery; {
case p == "/api": case p == "/api":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apibody)))}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apibody)))}, nil
case p == "/apis": case p == "/apis":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apisbody)))}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apisbody)))}, nil
case p == testCase.expectedPath && m == "GET" && (testCase.expectedQuery == "" || q == testCase.expectedQuery): case p == testCase.expectedPath && m == "GET" && (testCase.expectedQuery == "" || q == testCase.expectedQuery):
body, err := marshallBody(response) body, err := marshallBody(response)
if err != nil { if err != nil {
t.Errorf("%s: unexpected error: %v", testCase.name, err) t.Errorf("%s: unexpected error: %v", testCase.name, err)
} }
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: body}, nil
default: default:
t.Fatalf("%s: unexpected request: %#v\nGot URL: %#v\nExpected path: %#v\nExpected query: %#v", t.Fatalf("%s: unexpected request: %#v\nGot URL: %#v\nExpected path: %#v\nExpected query: %#v",
testCase.name, req, req.URL, testCase.expectedPath, testCase.expectedQuery) testCase.name, req, req.URL, testCase.expectedPath, testCase.expectedQuery)
...@@ -199,7 +199,7 @@ func TestTopPod(t *testing.T) { ...@@ -199,7 +199,7 @@ func TestTopPod(t *testing.T) {
} }
}), }),
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
streams, _, buf, _ := genericclioptions.NewTestIOStreams() streams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdTopPod(tf, nil, streams) cmd := NewCmdTopPod(tf, nil, streams)
...@@ -284,7 +284,7 @@ func TestTopPodWithMetricsServer(t *testing.T) { ...@@ -284,7 +284,7 @@ func TestTopPodWithMetricsServer(t *testing.T) {
containers: true, containers: true,
}, },
} }
initTestErrorHandler(t) cmdtesting.InitTestErrorHandler(t)
for _, testCase := range testCases { for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) { t.Run(testCase.name, func(t *testing.T) {
metricsList := testV1beta1PodMetricsData() metricsList := testV1beta1PodMetricsData()
...@@ -330,9 +330,9 @@ func TestTopPodWithMetricsServer(t *testing.T) { ...@@ -330,9 +330,9 @@ func TestTopPodWithMetricsServer(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p := req.URL.Path; { switch p := req.URL.Path; {
case p == "/api": case p == "/api":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apibody)))}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apibody)))}, nil
case p == "/apis": case p == "/apis":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apisbodyWithMetrics)))}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apisbodyWithMetrics)))}, nil
default: default:
t.Fatalf("%s: unexpected request: %#v\nGot URL: %#v", t.Fatalf("%s: unexpected request: %#v\nGot URL: %#v",
testCase.name, req, req.URL) testCase.name, req, req.URL)
...@@ -340,7 +340,7 @@ func TestTopPodWithMetricsServer(t *testing.T) { ...@@ -340,7 +340,7 @@ func TestTopPodWithMetricsServer(t *testing.T) {
} }
}), }),
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
streams, _, buf, _ := genericclioptions.NewTestIOStreams() streams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdTopPod(tf, nil, streams) cmd := NewCmdTopPod(tf, nil, streams)
...@@ -487,7 +487,7 @@ func TestTopPodCustomDefaults(t *testing.T) { ...@@ -487,7 +487,7 @@ func TestTopPodCustomDefaults(t *testing.T) {
containers: true, containers: true,
}, },
} }
initTestErrorHandler(t) cmdtesting.InitTestErrorHandler(t)
for _, testCase := range testCases { for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) { t.Run(testCase.name, func(t *testing.T) {
t.Logf("Running test case: %s", testCase.name) t.Logf("Running test case: %s", testCase.name)
...@@ -528,15 +528,15 @@ func TestTopPodCustomDefaults(t *testing.T) { ...@@ -528,15 +528,15 @@ func TestTopPodCustomDefaults(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m, q := req.URL.Path, req.Method, req.URL.RawQuery; { switch p, m, q := req.URL.Path, req.Method, req.URL.RawQuery; {
case p == "/api": case p == "/api":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apibody)))}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apibody)))}, nil
case p == "/apis": case p == "/apis":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apisbody)))}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apisbody)))}, nil
case p == testCase.expectedPath && m == "GET" && (testCase.expectedQuery == "" || q == testCase.expectedQuery): case p == testCase.expectedPath && m == "GET" && (testCase.expectedQuery == "" || q == testCase.expectedQuery):
body, err := marshallBody(response) body, err := marshallBody(response)
if err != nil { if err != nil {
t.Errorf("%s: unexpected error: %v", testCase.name, err) t.Errorf("%s: unexpected error: %v", testCase.name, err)
} }
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: body}, nil
default: default:
t.Fatalf("%s: unexpected request: %#v\nGot URL: %#v\nExpected path: %#v\nExpected query: %#v", t.Fatalf("%s: unexpected request: %#v\nGot URL: %#v\nExpected path: %#v\nExpected query: %#v",
testCase.name, req, req.URL, testCase.expectedPath, testCase.expectedQuery) testCase.name, req, req.URL, testCase.expectedPath, testCase.expectedQuery)
...@@ -544,7 +544,7 @@ func TestTopPodCustomDefaults(t *testing.T) { ...@@ -544,7 +544,7 @@ func TestTopPodCustomDefaults(t *testing.T) {
} }
}), }),
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
streams, _, buf, _ := genericclioptions.NewTestIOStreams() streams, _, buf, _ := genericclioptions.NewTestIOStreams()
opts := &TopPodOptions{ opts := &TopPodOptions{
......
...@@ -42,7 +42,7 @@ const ( ...@@ -42,7 +42,7 @@ const (
) )
func TestTopSubcommandsExist(t *testing.T) { func TestTopSubcommandsExist(t *testing.T) {
initTestErrorHandler(t) cmdtesting.InitTestErrorHandler(t)
f := cmdtesting.NewTestFactory() f := cmdtesting.NewTestFactory()
defer f.Cleanup() defer f.Cleanup()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment