use temp kubeconfig for fake factory

parent 40143fd6
......@@ -417,29 +417,33 @@ func TestAnnotateErrors(t *testing.T) {
}
for k, testCase := range testCases {
tf := cmdtesting.NewTestFactory()
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
t.Run(k, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdAnnotate(tf, buf)
cmd.SetOutput(buf)
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
for k, v := range testCase.flags {
cmd.Flags().Set(k, v)
}
options := &AnnotateOptions{}
err := options.Complete(buf, cmd, testCase.args)
if err == nil {
err = options.Validate()
}
if !testCase.errFn(err) {
t.Errorf("%s: unexpected error: %v", k, err)
continue
}
if buf.Len() > 0 {
t.Errorf("buffer should be empty: %s", string(buf.Bytes()))
}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdAnnotate(tf, buf)
cmd.SetOutput(buf)
for k, v := range testCase.flags {
cmd.Flags().Set(k, v)
}
options := &AnnotateOptions{}
err := options.Complete(buf, cmd, testCase.args)
if err == nil {
err = options.Validate()
}
if !testCase.errFn(err) {
t.Errorf("%s: unexpected error: %v", k, err)
return
}
if buf.Len() > 0 {
t.Errorf("buffer should be empty: %s", string(buf.Bytes()))
}
})
}
}
......@@ -447,6 +451,8 @@ func TestAnnotateObject(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -499,6 +505,8 @@ func TestAnnotateObjectFromFile(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -550,6 +558,8 @@ func TestAnnotateObjectFromFile(t *testing.T) {
func TestAnnotateLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Group: "testgroup", Version: "v1"},
NegotiatedSerializer: unstructuredSerializer,
......@@ -581,6 +591,8 @@ func TestAnnotateMultipleObjects(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Group: "testgroup", Version: "v1"},
......
......@@ -69,6 +69,8 @@ func TestApplyExtraArgsFail(t *testing.T) {
errBuf := bytes.NewBuffer([]byte{})
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
c := NewCmdApply("kubectl", f, buf, errBuf)
if validateApplyArgs(c, []string{"rc"}) == nil {
t.Fatalf("unexpected non-error")
......@@ -332,55 +334,59 @@ func TestRunApplyViewLastApplied(t *testing.T) {
},
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == pathRC && m == "GET":
bodyRC := ioutil.NopCloser(bytes.NewReader(test.respBytes))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case p == "/namespaces/test/replicationcontrollers" && m == "GET":
bodyRC := ioutil.NopCloser(bytes.NewReader(test.respBytes))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case p == "/namespaces/test/replicationcontrollers/no-match" && m == "GET":
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: objBody(codec, &api.Pod{})}, nil
case p == "/api/v1/namespaces/test" && m == "GET":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &api.Namespace{})}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
cmdutil.BehaviorOnFatal(func(str string, code int) {
if str != test.expectedErr {
t.Errorf("%s: unexpected error: %s\nexpected: %s", test.name, str, test.expectedErr)
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == pathRC && m == "GET":
bodyRC := ioutil.NopCloser(bytes.NewReader(test.respBytes))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case p == "/namespaces/test/replicationcontrollers" && m == "GET":
bodyRC := ioutil.NopCloser(bytes.NewReader(test.respBytes))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case p == "/namespaces/test/replicationcontrollers/no-match" && m == "GET":
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: objBody(codec, &api.Pod{})}, nil
case p == "/api/v1/namespaces/test" && m == "GET":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &api.Namespace{})}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
})
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
cmd := NewCmdApplyViewLastApplied(tf, buf, errBuf)
if test.filePath != "" {
cmd.Flags().Set("filename", test.filePath)
}
if test.outputFormat != "" {
cmd.Flags().Set("output", test.outputFormat)
}
if test.selector != "" {
cmd.Flags().Set("selector", test.selector)
}
cmdutil.BehaviorOnFatal(func(str string, code int) {
if str != test.expectedErr {
t.Errorf("%s: unexpected error: %s\nexpected: %s", test.name, str, test.expectedErr)
}
})
cmd.Run(cmd, test.args)
if buf.String() != test.expectedOut {
t.Fatalf("%s: unexpected output: %s\nexpected: %s", test.name, buf.String(), test.expectedOut)
}
cmd := NewCmdApplyViewLastApplied(tf, buf, errBuf)
if test.filePath != "" {
cmd.Flags().Set("filename", test.filePath)
}
if test.outputFormat != "" {
cmd.Flags().Set("output", test.outputFormat)
}
if test.selector != "" {
cmd.Flags().Set("selector", test.selector)
}
cmd.Run(cmd, test.args)
if buf.String() != test.expectedOut {
t.Fatalf("%s: unexpected output: %s\nexpected: %s", test.name, buf.String(), test.expectedOut)
}
})
}
}
......@@ -390,6 +396,8 @@ func TestApplyObjectWithoutAnnotation(t *testing.T) {
pathRC := "/namespaces/test/replicationcontrollers/" + nameRC
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
......@@ -433,42 +441,46 @@ func TestApplyObject(t *testing.T) {
pathRC := "/namespaces/test/replicationcontrollers/" + nameRC
for _, fn := range testingOpenAPISchemaFns {
tf := cmdtesting.NewTestFactory()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == pathRC && m == "GET":
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case p == pathRC && m == "PATCH":
validatePatchApplication(t, req)
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.OpenAPISchemaFunc = fn
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf)
cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
// uses the name from the file, not the response
expectRC := "replicationcontroller/" + nameRC + "\n"
if buf.String() != expectRC {
t.Fatalf("unexpected output: %s\nexpected: %s", buf.String(), expectRC)
}
if errBuf.String() != "" {
t.Fatalf("unexpected error output: %s", errBuf.String())
}
t.Run("test apply when a local object is specified", func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == pathRC && m == "GET":
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case p == pathRC && m == "PATCH":
validatePatchApplication(t, req)
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.OpenAPISchemaFunc = fn
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf)
cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
// uses the name from the file, not the response
expectRC := "replicationcontroller/" + nameRC + "\n"
if buf.String() != expectRC {
t.Fatalf("unexpected output: %s\nexpected: %s", buf.String(), expectRC)
}
if errBuf.String() != "" {
t.Fatalf("unexpected error output: %s", errBuf.String())
}
})
}
}
......@@ -494,43 +506,47 @@ func TestApplyObjectOutput(t *testing.T) {
}
for _, fn := range testingOpenAPISchemaFns {
tf := cmdtesting.NewTestFactory()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == pathRC && m == "GET":
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case p == pathRC && m == "PATCH":
validatePatchApplication(t, req)
bodyRC := ioutil.NopCloser(bytes.NewReader(postPatchData))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.OpenAPISchemaFunc = fn
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf)
cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("output", "yaml")
cmd.Run(cmd, []string{})
if !strings.Contains(buf.String(), "test-rc") {
t.Fatalf("unexpected output: %s\nexpected to contain: %s", buf.String(), "test-rc")
}
if !strings.Contains(buf.String(), "post-patch: value") {
t.Fatalf("unexpected output: %s\nexpected to contain: %s", buf.String(), "post-patch: value")
}
if errBuf.String() != "" {
t.Fatalf("unexpected error output: %s", errBuf.String())
}
t.Run("test apply returns correct output", func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == pathRC && m == "GET":
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case p == pathRC && m == "PATCH":
validatePatchApplication(t, req)
bodyRC := ioutil.NopCloser(bytes.NewReader(postPatchData))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.OpenAPISchemaFunc = fn
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf)
cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("output", "yaml")
cmd.Run(cmd, []string{})
if !strings.Contains(buf.String(), "test-rc") {
t.Fatalf("unexpected output: %s\nexpected to contain: %s", buf.String(), "test-rc")
}
if !strings.Contains(buf.String(), "post-patch: value") {
t.Fatalf("unexpected output: %s\nexpected to contain: %s", buf.String(), "post-patch: value")
}
if errBuf.String() != "" {
t.Fatalf("unexpected error output: %s", errBuf.String())
}
})
}
}
......@@ -540,58 +556,62 @@ func TestApplyRetry(t *testing.T) {
pathRC := "/namespaces/test/replicationcontrollers/" + nameRC
for _, fn := range testingOpenAPISchemaFns {
firstPatch := true
retry := false
getCount := 0
tf := cmdtesting.NewTestFactory()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == pathRC && m == "GET":
getCount++
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case p == pathRC && m == "PATCH":
if firstPatch {
firstPatch = false
statusErr := kubeerr.NewConflict(schema.GroupResource{Group: "", Resource: "rc"}, "test-rc", fmt.Errorf("the object has been modified. Please apply at first."))
bodyBytes, _ := json.Marshal(statusErr)
bodyErr := ioutil.NopCloser(bytes.NewReader(bodyBytes))
return &http.Response{StatusCode: http.StatusConflict, Header: defaultHeader(), Body: bodyErr}, nil
t.Run("test apply retries on conflict error", func(t *testing.T) {
firstPatch := true
retry := false
getCount := 0
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == pathRC && m == "GET":
getCount++
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case p == pathRC && m == "PATCH":
if firstPatch {
firstPatch = false
statusErr := kubeerr.NewConflict(schema.GroupResource{Group: "", Resource: "rc"}, "test-rc", fmt.Errorf("the object has been modified. Please apply at first."))
bodyBytes, _ := json.Marshal(statusErr)
bodyErr := ioutil.NopCloser(bytes.NewReader(bodyBytes))
return &http.Response{StatusCode: http.StatusConflict, Header: defaultHeader(), Body: bodyErr}, nil
}
retry = true
validatePatchApplication(t, req)
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
retry = true
validatePatchApplication(t, req)
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.OpenAPISchemaFunc = fn
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf)
cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
if !retry || getCount != 2 {
t.Fatalf("apply didn't retry when get conflict error")
}
}),
}
tf.OpenAPISchemaFunc = fn
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
// uses the name from the file, not the response
expectRC := "replicationcontroller/" + nameRC + "\n"
if buf.String() != expectRC {
t.Fatalf("unexpected output: %s\nexpected: %s", buf.String(), expectRC)
}
if errBuf.String() != "" {
t.Fatalf("unexpected error output: %s", errBuf.String())
}
cmd := NewCmdApply("kubectl", tf, buf, errBuf)
cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
if !retry || getCount != 2 {
t.Fatalf("apply didn't retry when get conflict error")
}
// uses the name from the file, not the response
expectRC := "replicationcontroller/" + nameRC + "\n"
if buf.String() != expectRC {
t.Fatalf("unexpected output: %s\nexpected: %s", buf.String(), expectRC)
}
if errBuf.String() != "" {
t.Fatalf("unexpected error output: %s", errBuf.String())
}
})
}
}
......@@ -601,6 +621,8 @@ func TestApplyNonExistObject(t *testing.T) {
pathNameRC := pathRC + "/" + nameRC
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
......@@ -645,6 +667,8 @@ func TestApplyEmptyPatch(t *testing.T) {
var body []byte
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: unstructuredSerializer,
......@@ -718,59 +742,63 @@ func testApplyMultipleObjects(t *testing.T, asList bool) {
pathSVC := "/namespaces/test/services/" + nameSVC
for _, fn := range testingOpenAPISchemaFns {
tf := cmdtesting.NewTestFactory()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == pathRC && m == "GET":
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case p == pathRC && m == "PATCH":
validatePatchApplication(t, req)
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case p == pathSVC && m == "GET":
bodySVC := ioutil.NopCloser(bytes.NewReader(currentSVC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodySVC}, nil
case p == pathSVC && m == "PATCH":
validatePatchApplication(t, req)
bodySVC := ioutil.NopCloser(bytes.NewReader(currentSVC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodySVC}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.OpenAPISchemaFunc = fn
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf)
if asList {
cmd.Flags().Set("filename", filenameRCSVC)
} else {
cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("filename", filenameSVC)
}
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
// Names should come from the REST response, NOT the files
expectRC := "replicationcontroller/" + nameRC + "\n"
expectSVC := "service/" + nameSVC + "\n"
// Test both possible orders since output is non-deterministic.
expectOne := expectRC + expectSVC
expectTwo := expectSVC + expectRC
if buf.String() != expectOne && buf.String() != expectTwo {
t.Fatalf("unexpected output: %s\nexpected: %s OR %s", buf.String(), expectOne, expectTwo)
}
if errBuf.String() != "" {
t.Fatalf("unexpected error output: %s", errBuf.String())
}
t.Run("test apply on multiple objects", func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == pathRC && m == "GET":
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case p == pathRC && m == "PATCH":
validatePatchApplication(t, req)
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case p == pathSVC && m == "GET":
bodySVC := ioutil.NopCloser(bytes.NewReader(currentSVC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodySVC}, nil
case p == pathSVC && m == "PATCH":
validatePatchApplication(t, req)
bodySVC := ioutil.NopCloser(bytes.NewReader(currentSVC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodySVC}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.OpenAPISchemaFunc = fn
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf)
if asList {
cmd.Flags().Set("filename", filenameRCSVC)
} else {
cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("filename", filenameSVC)
}
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
// Names should come from the REST response, NOT the files
expectRC := "replicationcontroller/" + nameRC + "\n"
expectSVC := "service/" + nameSVC + "\n"
// Test both possible orders since output is non-deterministic.
expectOne := expectRC + expectSVC
expectTwo := expectSVC + expectRC
if buf.String() != expectOne && buf.String() != expectTwo {
t.Fatalf("unexpected output: %s\nexpected: %s OR %s", buf.String(), expectOne, expectTwo)
}
if errBuf.String() != "" {
t.Fatalf("unexpected error output: %s", errBuf.String())
}
})
}
}
......@@ -801,66 +829,70 @@ func TestApplyNULLPreservation(t *testing.T) {
deploymentBytes := readDeploymentFromFile(t, filenameDeployObjServerside)
for _, fn := range testingOpenAPISchemaFns {
tf := cmdtesting.NewTestFactory()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == deploymentPath && m == "GET":
body := ioutil.NopCloser(bytes.NewReader(deploymentBytes))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
case p == deploymentPath && m == "PATCH":
patch, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatal(err)
}
t.Run("test apply preserves NULL fields", func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
patchMap := map[string]interface{}{}
if err := json.Unmarshal(patch, &patchMap); err != nil {
t.Fatal(err)
}
annotationMap := walkMapPath(t, patchMap, []string{"metadata", "annotations"})
if _, ok := annotationMap[api.LastAppliedConfigAnnotation]; !ok {
t.Fatalf("patch does not contain annotation:\n%s\n", patch)
}
strategy := walkMapPath(t, patchMap, []string{"spec", "strategy"})
if value, ok := strategy["rollingUpdate"]; !ok || value != nil {
t.Fatalf("patch did not retain null value in key: rollingUpdate:\n%s\n", patch)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == deploymentPath && m == "GET":
body := ioutil.NopCloser(bytes.NewReader(deploymentBytes))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
case p == deploymentPath && m == "PATCH":
patch, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatal(err)
}
patchMap := map[string]interface{}{}
if err := json.Unmarshal(patch, &patchMap); err != nil {
t.Fatal(err)
}
annotationMap := walkMapPath(t, patchMap, []string{"metadata", "annotations"})
if _, ok := annotationMap[api.LastAppliedConfigAnnotation]; !ok {
t.Fatalf("patch does not contain annotation:\n%s\n", patch)
}
strategy := walkMapPath(t, patchMap, []string{"spec", "strategy"})
if value, ok := strategy["rollingUpdate"]; !ok || value != nil {
t.Fatalf("patch did not retain null value in key: rollingUpdate:\n%s\n", patch)
}
verifiedPatch = true
// The real API server would had returned the patched object but Kubectl
// is ignoring the actual return object.
// TODO: Make this match actual server behavior by returning the patched object.
body := ioutil.NopCloser(bytes.NewReader(deploymentBytes))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
verifiedPatch = true
// The real API server would had returned the patched object but Kubectl
// is ignoring the actual return object.
// TODO: Make this match actual server behavior by returning the patched object.
body := ioutil.NopCloser(bytes.NewReader(deploymentBytes))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.OpenAPISchemaFunc = fn
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
}),
}
tf.OpenAPISchemaFunc = fn
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf)
cmd.Flags().Set("filename", filenameDeployObjClientside)
cmd.Flags().Set("output", "name")
cmd := NewCmdApply("kubectl", tf, buf, errBuf)
cmd.Flags().Set("filename", filenameDeployObjClientside)
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
cmd.Run(cmd, []string{})
expected := "deployment.extensions/" + deploymentName + "\n"
if buf.String() != expected {
t.Fatalf("unexpected output: %s\nexpected: %s", buf.String(), expected)
}
if errBuf.String() != "" {
t.Fatalf("unexpected error output: %s", errBuf.String())
}
if !verifiedPatch {
t.Fatal("No server-side patch call detected")
}
expected := "deployment.extensions/" + deploymentName + "\n"
if buf.String() != expected {
t.Fatalf("unexpected output: %s\nexpected: %s", buf.String(), expected)
}
if errBuf.String() != "" {
t.Fatalf("unexpected error output: %s", errBuf.String())
}
if !verifiedPatch {
t.Fatal("No server-side patch call detected")
}
})
}
}
......@@ -873,56 +905,60 @@ func TestUnstructuredApply(t *testing.T) {
verifiedPatch := false
for _, fn := range testingOpenAPISchemaFns {
tf := cmdtesting.NewTestFactory()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == path && m == "GET":
body := ioutil.NopCloser(bytes.NewReader(curr))
return &http.Response{
StatusCode: 200,
Header: defaultHeader(),
Body: body}, nil
case p == path && m == "PATCH":
contentType := req.Header.Get("Content-Type")
if contentType != "application/merge-patch+json" {
t.Fatalf("Unexpected Content-Type: %s", contentType)
t.Run("test apply works correctly with unstructured objects", func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == path && m == "GET":
body := ioutil.NopCloser(bytes.NewReader(curr))
return &http.Response{
StatusCode: 200,
Header: defaultHeader(),
Body: body}, nil
case p == path && m == "PATCH":
contentType := req.Header.Get("Content-Type")
if contentType != "application/merge-patch+json" {
t.Fatalf("Unexpected Content-Type: %s", contentType)
}
validatePatchApplication(t, req)
verifiedPatch = true
body := ioutil.NopCloser(bytes.NewReader(curr))
return &http.Response{
StatusCode: 200,
Header: defaultHeader(),
Body: body}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
validatePatchApplication(t, req)
verifiedPatch = true
body := ioutil.NopCloser(bytes.NewReader(curr))
return &http.Response{
StatusCode: 200,
Header: defaultHeader(),
Body: body}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.OpenAPISchemaFunc = fn
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf)
cmd.Flags().Set("filename", filenameWidgetClientside)
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
expected := "widget.unit-test.test.com/" + name + "\n"
if buf.String() != expected {
t.Fatalf("unexpected output: %s\nexpected: %s", buf.String(), expected)
}
if errBuf.String() != "" {
t.Fatalf("unexpected error output: %s", errBuf.String())
}
if !verifiedPatch {
t.Fatal("No server-side patch call detected")
}
}),
}
tf.OpenAPISchemaFunc = fn
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf)
cmd.Flags().Set("filename", filenameWidgetClientside)
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
expected := "widget.unit-test.test.com/" + name + "\n"
if buf.String() != expected {
t.Fatalf("unexpected output: %s\nexpected: %s", buf.String(), expected)
}
if errBuf.String() != "" {
t.Fatalf("unexpected error output: %s", errBuf.String())
}
if !verifiedPatch {
t.Fatal("No server-side patch call detected")
}
})
}
}
......@@ -940,79 +976,83 @@ func TestUnstructuredIdempotentApply(t *testing.T) {
verifiedPatch := false
for _, fn := range testingOpenAPISchemaFns {
tf := cmdtesting.NewTestFactory()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == path && m == "GET":
body := ioutil.NopCloser(bytes.NewReader(serversideData))
return &http.Response{
StatusCode: 200,
Header: defaultHeader(),
Body: body}, nil
case p == path && m == "PATCH":
// In idempotent updates, kubectl sends a logically empty
// request body with the PATCH request.
// Should look like this:
// Request Body: {"metadata":{"annotations":{}}}
patch, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatal(err)
}
t.Run("test repeated apply operations on an unstructured object", func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
contentType := req.Header.Get("Content-Type")
if contentType != "application/merge-patch+json" {
t.Fatalf("Unexpected Content-Type: %s", contentType)
}
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == path && m == "GET":
body := ioutil.NopCloser(bytes.NewReader(serversideData))
return &http.Response{
StatusCode: 200,
Header: defaultHeader(),
Body: body}, nil
case p == path && m == "PATCH":
// In idempotent updates, kubectl sends a logically empty
// request body with the PATCH request.
// Should look like this:
// Request Body: {"metadata":{"annotations":{}}}
patch, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatal(err)
}
patchMap := map[string]interface{}{}
if err := json.Unmarshal(patch, &patchMap); err != nil {
t.Fatal(err)
}
if len(patchMap) != 1 {
t.Fatalf("Unexpected Patch. Has more than 1 entry. path: %s", patch)
}
contentType := req.Header.Get("Content-Type")
if contentType != "application/merge-patch+json" {
t.Fatalf("Unexpected Content-Type: %s", contentType)
}
patchMap := map[string]interface{}{}
if err := json.Unmarshal(patch, &patchMap); err != nil {
t.Fatal(err)
}
if len(patchMap) != 1 {
t.Fatalf("Unexpected Patch. Has more than 1 entry. path: %s", patch)
}
annotationsMap := walkMapPath(t, patchMap, []string{"metadata", "annotations"})
if len(annotationsMap) != 0 {
t.Fatalf("Unexpected Patch. Found unexpected annotation: %s", patch)
annotationsMap := walkMapPath(t, patchMap, []string{"metadata", "annotations"})
if len(annotationsMap) != 0 {
t.Fatalf("Unexpected Patch. Found unexpected annotation: %s", patch)
}
verifiedPatch = true
body := ioutil.NopCloser(bytes.NewReader(serversideData))
return &http.Response{
StatusCode: 200,
Header: defaultHeader(),
Body: body}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.OpenAPISchemaFunc = fn
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
verifiedPatch = true
cmd := NewCmdApply("kubectl", tf, buf, errBuf)
cmd.Flags().Set("filename", filenameWidgetClientside)
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
body := ioutil.NopCloser(bytes.NewReader(serversideData))
return &http.Response{
StatusCode: 200,
Header: defaultHeader(),
Body: body}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.OpenAPISchemaFunc = fn
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf)
cmd.Flags().Set("filename", filenameWidgetClientside)
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
expected := "widget.unit-test.test.com/widget\n"
if buf.String() != expected {
t.Fatalf("unexpected output: %s\nexpected: %s", buf.String(), expected)
}
if errBuf.String() != "" {
t.Fatalf("unexpected error output: %s", errBuf.String())
}
if !verifiedPatch {
t.Fatal("No server-side patch call detected")
}
expected := "widget.unit-test.test.com/widget\n"
if buf.String() != expected {
t.Fatalf("unexpected output: %s\nexpected: %s", buf.String(), expected)
}
if errBuf.String() != "" {
t.Fatalf("unexpected error output: %s", errBuf.String())
}
if !verifiedPatch {
t.Fatal("No server-side patch call detected")
}
})
}
}
......@@ -1069,6 +1109,8 @@ func TestRunApplySetLastApplied(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -1158,104 +1200,108 @@ func TestForceApply(t *testing.T) {
}
for _, fn := range testingOpenAPISchemaFns {
deleted := false
isScaledDownToZero := false
counts := map[string]int{}
tf := cmdtesting.NewTestFactory()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case strings.HasSuffix(p, pathRC) && m == "GET":
if deleted {
counts["getNotFound"]++
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte{}))}, nil
}
counts["getOk"]++
var bodyRC io.ReadCloser
if isScaledDownToZero {
rcObj := readReplicationControllerFromFile(t, filenameRC)
rcObj.Spec.Replicas = 0
rcBytes, err := runtime.Encode(testapi.Default.Codec(), rcObj)
t.Run("test apply with --force", func(t *testing.T) {
deleted := false
isScaledDownToZero := false
counts := map[string]int{}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case strings.HasSuffix(p, pathRC) && m == "GET":
if deleted {
counts["getNotFound"]++
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte{}))}, nil
}
counts["getOk"]++
var bodyRC io.ReadCloser
if isScaledDownToZero {
rcObj := readReplicationControllerFromFile(t, filenameRC)
rcObj.Spec.Replicas = 0
rcBytes, err := runtime.Encode(testapi.Default.Codec(), rcObj)
if err != nil {
t.Fatal(err)
}
bodyRC = ioutil.NopCloser(bytes.NewReader(rcBytes))
} else {
bodyRC = ioutil.NopCloser(bytes.NewReader(currentRC))
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case strings.HasSuffix(p, pathRCList) && m == "GET":
counts["getList"]++
rcObj := readUnstructuredFromFile(t, filenameRC)
list := &unstructured.UnstructuredList{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "ReplicationControllerList",
},
Items: []unstructured.Unstructured{*rcObj},
}
listBytes, err := runtime.Encode(testapi.Default.Codec(), list)
if err != nil {
t.Fatal(err)
}
bodyRC = ioutil.NopCloser(bytes.NewReader(rcBytes))
} else {
bodyRC = ioutil.NopCloser(bytes.NewReader(currentRC))
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case strings.HasSuffix(p, pathRCList) && m == "GET":
counts["getList"]++
rcObj := readUnstructuredFromFile(t, filenameRC)
list := &unstructured.UnstructuredList{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "ReplicationControllerList",
},
Items: []unstructured.Unstructured{*rcObj},
}
listBytes, err := runtime.Encode(testapi.Default.Codec(), list)
if err != nil {
t.Fatal(err)
}
bodyRCList := ioutil.NopCloser(bytes.NewReader(listBytes))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRCList}, nil
case strings.HasSuffix(p, pathRC) && m == "PATCH":
counts["patch"]++
if counts["patch"] <= 6 {
statusErr := kubeerr.NewConflict(schema.GroupResource{Group: "", Resource: "rc"}, "test-rc", fmt.Errorf("the object has been modified. Please apply at first."))
bodyBytes, _ := json.Marshal(statusErr)
bodyErr := ioutil.NopCloser(bytes.NewReader(bodyBytes))
return &http.Response{StatusCode: http.StatusConflict, Header: defaultHeader(), Body: bodyErr}, nil
bodyRCList := ioutil.NopCloser(bytes.NewReader(listBytes))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRCList}, nil
case strings.HasSuffix(p, pathRC) && m == "PATCH":
counts["patch"]++
if counts["patch"] <= 6 {
statusErr := kubeerr.NewConflict(schema.GroupResource{Group: "", Resource: "rc"}, "test-rc", fmt.Errorf("the object has been modified. Please apply at first."))
bodyBytes, _ := json.Marshal(statusErr)
bodyErr := ioutil.NopCloser(bytes.NewReader(bodyBytes))
return &http.Response{StatusCode: http.StatusConflict, Header: defaultHeader(), Body: bodyErr}, nil
}
t.Fatalf("unexpected request: %#v after %v tries\n%#v", req.URL, counts["patch"], req)
return nil, nil
case strings.HasSuffix(p, pathRC) && m == "DELETE":
counts["delete"]++
deleted = true
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte{}))}, nil
case strings.HasSuffix(p, pathRC) && m == "PUT":
counts["put"]++
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
isScaledDownToZero = true
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case strings.HasSuffix(p, pathRCList) && m == "POST":
counts["post"]++
deleted = false
isScaledDownToZero = false
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
t.Fatalf("unexpected request: %#v after %v tries\n%#v", req.URL, counts["patch"], req)
return nil, nil
case strings.HasSuffix(p, pathRC) && m == "DELETE":
counts["delete"]++
deleted = true
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte{}))}, nil
case strings.HasSuffix(p, pathRC) && m == "PUT":
counts["put"]++
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
isScaledDownToZero = true
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case strings.HasSuffix(p, pathRCList) && m == "POST":
counts["post"]++
deleted = false
isScaledDownToZero = false
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}),
}
tf.OpenAPISchemaFunc = fn
tf.Client = tf.UnstructuredClient
tf.ClientConfigVal = &restclient.Config{}
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf)
cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("output", "name")
cmd.Flags().Set("force", "true")
cmd.Run(cmd, []string{})
for method, exp := range expected {
if exp != counts[method] {
t.Errorf("Unexpected amount of %q API calls, wanted %v got %v", method, exp, counts[method])
}
}),
}
tf.OpenAPISchemaFunc = fn
tf.Client = tf.UnstructuredClient
tf.ClientConfigVal = &restclient.Config{}
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf)
cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("output", "name")
cmd.Flags().Set("force", "true")
cmd.Run(cmd, []string{})
for method, exp := range expected {
if exp != counts[method] {
t.Errorf("Unexpected amount of %q API calls, wanted %v got %v", method, exp, counts[method])
}
}
if expected := "replicationcontroller/" + nameRC + "\n"; buf.String() != expected {
t.Fatalf("unexpected output: %s\nexpected: %s", buf.String(), expected)
}
if errBuf.String() != "" {
t.Fatalf("unexpected error output: %s", errBuf.String())
}
if expected := "replicationcontroller/" + nameRC + "\n"; buf.String() != expected {
t.Fatalf("unexpected output: %s\nexpected: %s", buf.String(), expected)
}
if errBuf.String() != "" {
t.Fatalf("unexpected error output: %s", errBuf.String())
}
})
}
}
......@@ -139,43 +139,47 @@ func TestPodAndContainerAttach(t *testing.T) {
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
if test.obj != nil {
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, test.obj)}, nil
}
return nil, nil
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
if test.obj != nil {
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, test.obj)}, nil
}
return nil, nil
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
cmd := &cobra.Command{}
options := test.p
cmdutil.AddPodRunningTimeoutFlag(cmd, test.timeout)
cmd := &cobra.Command{}
options := test.p
cmdutil.AddPodRunningTimeoutFlag(cmd, test.timeout)
err := options.Complete(tf, cmd, test.args)
if test.expectError && err == nil {
t.Errorf("%s: unexpected non-error", test.name)
}
if !test.expectError && err != nil {
t.Errorf("%s: unexpected error: %v", test.name, err)
}
if err != nil {
continue
}
if options.PodName != test.expectedPod {
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedPod, options.PodName)
}
if options.ContainerName != test.expectedContainer {
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedContainer, options.ContainerName)
}
err := options.Complete(tf, cmd, test.args)
if test.expectError && err == nil {
t.Errorf("%s: unexpected non-error", test.name)
}
if !test.expectError && err != nil {
t.Errorf("%s: unexpected error: %v", test.name, err)
}
if err != nil {
return
}
if options.PodName != test.expectedPod {
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedPod, options.PodName)
}
if options.ContainerName != test.expectedContainer {
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedContainer, options.ContainerName)
}
})
}
}
......@@ -219,74 +223,78 @@ func TestAttach(t *testing.T) {
},
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
case p == test.fetchPodPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %s %#v\n%#v", p, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}}
bufOut := bytes.NewBuffer([]byte{})
bufErr := bytes.NewBuffer([]byte{})
bufIn := bytes.NewBuffer([]byte{})
remoteAttach := &fakeRemoteAttach{}
if test.remoteAttachErr {
remoteAttach.err = fmt.Errorf("attach error")
}
params := &AttachOptions{
StreamOptions: StreamOptions{
ContainerName: test.container,
In: bufIn,
Out: bufOut,
Err: bufErr,
},
Attach: remoteAttach,
GetPodTimeout: 1000,
}
cmd := &cobra.Command{}
cmdutil.AddPodRunningTimeoutFlag(cmd, 1000)
if err := params.Complete(tf, cmd, []string{"foo"}); err != nil {
t.Fatal(err)
}
err := params.Run()
if test.exepctedErr != "" && err.Error() != test.exepctedErr {
t.Errorf("%s: Unexpected exec error: %v", test.name, err)
continue
}
if test.exepctedErr == "" && err != nil {
t.Errorf("%s: Unexpected error: %v", test.name, err)
continue
}
if test.exepctedErr != "" {
continue
}
if remoteAttach.url.Path != test.attachPath {
t.Errorf("%s: Did not get expected path for exec request: %q %q", test.name, test.attachPath, remoteAttach.url.Path)
continue
}
if remoteAttach.method != "POST" {
t.Errorf("%s: Did not get method for attach request: %s", test.name, remoteAttach.method)
}
if remoteAttach.url.Query().Get("container") != "bar" {
t.Errorf("%s: Did not have query parameters: %s", test.name, remoteAttach.url.Query())
}
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
case p == test.fetchPodPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %s %#v\n%#v", p, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}}
bufOut := bytes.NewBuffer([]byte{})
bufErr := bytes.NewBuffer([]byte{})
bufIn := bytes.NewBuffer([]byte{})
remoteAttach := &fakeRemoteAttach{}
if test.remoteAttachErr {
remoteAttach.err = fmt.Errorf("attach error")
}
params := &AttachOptions{
StreamOptions: StreamOptions{
ContainerName: test.container,
In: bufIn,
Out: bufOut,
Err: bufErr,
},
Attach: remoteAttach,
GetPodTimeout: 1000,
}
cmd := &cobra.Command{}
cmdutil.AddPodRunningTimeoutFlag(cmd, 1000)
if err := params.Complete(tf, cmd, []string{"foo"}); err != nil {
t.Fatal(err)
}
err := params.Run()
if test.exepctedErr != "" && err.Error() != test.exepctedErr {
t.Errorf("%s: Unexpected exec error: %v", test.name, err)
return
}
if test.exepctedErr == "" && err != nil {
t.Errorf("%s: Unexpected error: %v", test.name, err)
return
}
if test.exepctedErr != "" {
return
}
if remoteAttach.url.Path != test.attachPath {
t.Errorf("%s: Did not get expected path for exec request: %q %q", test.name, test.attachPath, remoteAttach.url.Path)
return
}
if remoteAttach.method != "POST" {
t.Errorf("%s: Did not get method for attach request: %s", test.name, remoteAttach.method)
}
if remoteAttach.url.Query().Get("container") != "bar" {
t.Errorf("%s: Did not have query parameters: %s", test.name, remoteAttach.url.Query())
}
})
}
}
......@@ -309,62 +317,66 @@ func TestAttachWarnings(t *testing.T) {
},
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
case p == test.fetchPodPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}}
bufOut := bytes.NewBuffer([]byte{})
bufErr := bytes.NewBuffer([]byte{})
bufIn := bytes.NewBuffer([]byte{})
ex := &fakeRemoteAttach{}
params := &AttachOptions{
StreamOptions: StreamOptions{
ContainerName: test.container,
In: bufIn,
Out: bufOut,
Err: bufErr,
Stdin: test.stdin,
TTY: test.tty,
},
Attach: ex,
GetPodTimeout: 1000,
}
cmd := &cobra.Command{}
cmdutil.AddPodRunningTimeoutFlag(cmd, 1000)
if err := params.Complete(tf, cmd, []string{"foo"}); err != nil {
t.Fatal(err)
}
if err := params.Run(); err != nil {
t.Fatal(err)
}
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
case p == test.fetchPodPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}}
bufOut := bytes.NewBuffer([]byte{})
bufErr := bytes.NewBuffer([]byte{})
bufIn := bytes.NewBuffer([]byte{})
ex := &fakeRemoteAttach{}
params := &AttachOptions{
StreamOptions: StreamOptions{
ContainerName: test.container,
In: bufIn,
Out: bufOut,
Err: bufErr,
Stdin: test.stdin,
TTY: test.tty,
},
Attach: ex,
GetPodTimeout: 1000,
}
cmd := &cobra.Command{}
cmdutil.AddPodRunningTimeoutFlag(cmd, 1000)
if err := params.Complete(tf, cmd, []string{"foo"}); err != nil {
t.Fatal(err)
}
if err := params.Run(); err != nil {
t.Fatal(err)
}
if test.stdin && test.tty {
if !test.pod.Spec.Containers[0].TTY {
if !strings.Contains(bufErr.String(), test.expectedErr) {
t.Errorf("%s: Expected TTY fallback warning for attach request: %s", test.name, bufErr.String())
continue
if test.stdin && test.tty {
if !test.pod.Spec.Containers[0].TTY {
if !strings.Contains(bufErr.String(), test.expectedErr) {
t.Errorf("%s: Expected TTY fallback warning for attach request: %s", test.name, bufErr.String())
return
}
}
}
}
})
}
}
......
......@@ -117,64 +117,68 @@ func TestRunAccessCheck(t *testing.T) {
}
for _, test := range tests {
test.o.Out = ioutil.Discard
test.o.Err = ioutil.Discard
tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Group: "", Version: "v1"},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
expectPath := "/apis/authorization.k8s.io/v1/selfsubjectaccessreviews"
if req.URL.Path != expectPath {
t.Errorf("%s: expected %v, got %v", test.name, expectPath, req.URL.Path)
return nil, nil
}
bodyBits, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Errorf("%s: %v", test.name, err)
return nil, nil
}
body := string(bodyBits)
for _, expectedBody := range test.expectedBodyStrings {
if !strings.Contains(body, expectedBody) {
t.Errorf("%s expecting %s in %s", test.name, expectedBody, body)
t.Run(test.name, func(t *testing.T) {
test.o.Out = ioutil.Discard
test.o.Err = ioutil.Discard
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Group: "", Version: "v1"},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
expectPath := "/apis/authorization.k8s.io/v1/selfsubjectaccessreviews"
if req.URL.Path != expectPath {
t.Errorf("%s: expected %v, got %v", test.name, expectPath, req.URL.Path)
return nil, nil
}
}
return &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewBufferString(
fmt.Sprintf(`{"kind":"SelfSubjectAccessReview","apiVersion":"authorization.k8s.io/v1","status":{"allowed":%v}}`, test.allowed),
)),
},
test.serverErr
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}}}
if err := test.o.Complete(tf, test.args); err != nil {
t.Errorf("%s: %v", test.name, err)
continue
}
actualAllowed, err := test.o.RunAccessCheck()
switch {
case test.serverErr == nil && err == nil:
// pass
case err != nil && test.serverErr != nil && strings.Contains(err.Error(), test.serverErr.Error()):
// pass
default:
t.Errorf("%s: expected %v, got %v", test.name, test.serverErr, err)
continue
}
if actualAllowed != test.allowed {
t.Errorf("%s: expected %v, got %v", test.name, test.allowed, actualAllowed)
continue
}
bodyBits, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Errorf("%s: %v", test.name, err)
return nil, nil
}
body := string(bodyBits)
for _, expectedBody := range test.expectedBodyStrings {
if !strings.Contains(body, expectedBody) {
t.Errorf("%s expecting %s in %s", test.name, expectedBody, body)
}
}
return &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewBufferString(
fmt.Sprintf(`{"kind":"SelfSubjectAccessReview","apiVersion":"authorization.k8s.io/v1","status":{"allowed":%v}}`, test.allowed),
)),
},
test.serverErr
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}}}
if err := test.o.Complete(tf, test.args); err != nil {
t.Errorf("%s: %v", test.name, err)
return
}
actualAllowed, err := test.o.RunAccessCheck()
switch {
case test.serverErr == nil && err == nil:
// pass
case err != nil && test.serverErr != nil && strings.Contains(err.Error(), test.serverErr.Error()):
// pass
default:
t.Errorf("%s: expected %v, got %v", test.name, test.serverErr, err)
return
}
if actualAllowed != test.allowed {
t.Errorf("%s: expected %v, got %v", test.name, test.allowed, actualAllowed)
return
}
})
}
}
......@@ -31,6 +31,8 @@ func TestSetupOutputWriterNoOp(t *testing.T) {
for _, test := range tests {
out := &bytes.Buffer{}
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
cmd := NewCmdClusterInfoDump(f, os.Stdout)
cmd.Flag("output-directory").Value.Set(test)
writer := setupOutputWriter(cmd, out, "/some/file/that/should/be/ignored")
......@@ -51,6 +53,8 @@ func TestSetupOutputWriterFile(t *testing.T) {
out := &bytes.Buffer{}
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
cmd := NewCmdClusterInfoDump(f, os.Stdout)
cmd.Flag("output-directory").Value.Set(dir)
writer := setupOutputWriter(cmd, out, file)
......
......@@ -178,6 +178,8 @@ func stringBody(body string) io.ReadCloser {
func Example_printMultiContainersReplicationControllerWithWide() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
......@@ -228,6 +230,8 @@ func Example_printMultiContainersReplicationControllerWithWide() {
func Example_printReplicationController() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
......@@ -277,6 +281,8 @@ func Example_printReplicationController() {
func Example_printPodWithWideFormat() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
......@@ -315,6 +321,8 @@ func Example_printPodWithWideFormat() {
func Example_printPodWithShowLabels() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
......@@ -448,6 +456,8 @@ func newAllPhasePodList() *api.PodList {
func Example_printPodShowTerminated() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
......@@ -484,6 +494,8 @@ func Example_printPodShowTerminated() {
func Example_printPodShowAll() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
......@@ -507,6 +519,8 @@ func Example_printPodShowAll() {
func Example_printServiceWithLabels() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
......
......@@ -102,6 +102,8 @@ func TestConvertObject(t *testing.T) {
for _, field := range tc.fields {
t.Run(fmt.Sprintf("%s %s", tc.name, field), func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
......
......@@ -33,6 +33,8 @@ func TestCreateClusterRole(t *testing.T) {
clusterRoleName := "my-cluster-role"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Namespace = "test"
tf.Client = &fake.RESTClient{}
tf.ClientConfigVal = defaultClientConfig()
......@@ -148,6 +150,8 @@ func TestCreateClusterRole(t *testing.T) {
func TestClusterRoleValidate(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Namespace = "test"
tests := map[string]struct {
......
......@@ -68,6 +68,8 @@ func TestCreateClusterRoleBinding(t *testing.T) {
}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
info, _ := runtime.SerializerInfoForMediaType(ns.SupportedMediaTypes(), runtime.ContentTypeJSON)
......
......@@ -33,6 +33,8 @@ func TestCreateConfigMap(t *testing.T) {
configMap := &v1.ConfigMap{}
configMap.Name = "my-configmap"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
......
......@@ -75,6 +75,8 @@ func Test_generatorFromName(t *testing.T) {
func TestCreateDeployment(t *testing.T) {
depName := "jonny-dep"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
......@@ -104,6 +106,8 @@ func TestCreateDeployment(t *testing.T) {
func TestCreateDeploymentNoImage(t *testing.T) {
depName := "jonny-dep"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
......
......@@ -82,6 +82,8 @@ func TestCreateJobFromCronJob(t *testing.T) {
return true, expectJob, nil
})
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
buf := bytes.NewBuffer([]byte{})
cmdOptions := &CreateJobOptions{
Name: testJobName,
......
......@@ -33,6 +33,8 @@ func TestCreateNamespace(t *testing.T) {
namespaceObject := &v1.Namespace{}
namespaceObject.Name = "my-namespace"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
......
......@@ -32,6 +32,8 @@ import (
func TestCreatePdb(t *testing.T) {
pdbName := "my-pdb"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
......
......@@ -32,6 +32,8 @@ import (
func TestCreatePriorityClass(t *testing.T) {
pcName := "my-pc"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
......
......@@ -33,6 +33,8 @@ func TestCreateQuota(t *testing.T) {
resourceQuotaObject := &v1.ResourceQuota{}
resourceQuotaObject.Name = "my-quota"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
......
......@@ -35,6 +35,8 @@ func TestCreateRole(t *testing.T) {
roleName := "my-role"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Namespace = "test"
tf.Client = &fake.RESTClient{}
tf.ClientConfigVal = defaultClientConfig()
......@@ -147,6 +149,8 @@ func TestCreateRole(t *testing.T) {
func TestValidate(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Namespace = "test"
tests := map[string]struct {
......@@ -346,6 +350,8 @@ func TestComplete(t *testing.T) {
roleName := "my-role"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Namespace = "test"
tf.Client = &fake.RESTClient{}
tf.ClientConfigVal = defaultClientConfig()
......
......@@ -70,6 +70,8 @@ func TestCreateRoleBinding(t *testing.T) {
}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
info, _ := runtime.SerializerInfoForMediaType(ns.SupportedMediaTypes(), runtime.ContentTypeJSON)
......
......@@ -38,6 +38,8 @@ func TestCreateSecretGeneric(t *testing.T) {
}
secretObject.Name = "my-secret"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
......
......@@ -33,6 +33,8 @@ func TestCreateService(t *testing.T) {
service := &v1.Service{}
service.Name = "my-service"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
negSer := legacyscheme.Codecs
......@@ -65,6 +67,8 @@ func TestCreateServiceNodePort(t *testing.T) {
service := &v1.Service{}
service.Name = "my-node-port-service"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
negSer := legacyscheme.Codecs
......@@ -97,6 +101,8 @@ func TestCreateServiceExternalName(t *testing.T) {
service := &v1.Service{}
service.Name = "my-external-name-service"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
negSer := legacyscheme.Codecs
......
......@@ -33,6 +33,8 @@ func TestCreateServiceAccount(t *testing.T) {
serviceAccountObject := &v1.ServiceAccount{}
serviceAccountObject.Name = "my-service-account"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
......
......@@ -34,6 +34,8 @@ func TestExtraArgsFail(t *testing.T) {
errBuf := bytes.NewBuffer([]byte{})
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
c := NewCmdCreate(f, buf, errBuf)
options := CreateOptions{}
if options.ValidateArgs(c, []string{"rc"}) == nil {
......@@ -47,6 +49,8 @@ func TestCreateObject(t *testing.T) {
rc.Items[0].Name = "redis-master-controller"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -82,6 +86,8 @@ func TestCreateMultipleObject(t *testing.T) {
_, svc, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -121,6 +127,8 @@ func TestCreateDirectory(t *testing.T) {
rc.Items[0].Name = "name"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......
......@@ -57,6 +57,8 @@ func TestDeleteObjectByTuple(t *testing.T) {
_, _, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -121,6 +123,8 @@ func TestOrphanDependentsInDeleteObject(t *testing.T) {
_, _, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
var expectedOrphanDependents *bool
......@@ -171,6 +175,8 @@ func TestDeleteNamedObject(t *testing.T) {
_, _, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -222,6 +228,8 @@ func TestDeleteObject(t *testing.T) {
_, _, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -281,6 +289,8 @@ func TestDeleteObjectGraceZero(t *testing.T) {
objectDeletionWaitInterval = time.Millisecond
count := 0
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -331,6 +341,8 @@ func TestDeleteObjectGraceZero(t *testing.T) {
func TestDeleteObjectNotFound(t *testing.T) {
initTestErrorHandler(t)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
......@@ -367,6 +379,8 @@ func TestDeleteObjectNotFound(t *testing.T) {
func TestDeleteObjectIgnoreNotFound(t *testing.T) {
initTestErrorHandler(t)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
......@@ -402,6 +416,8 @@ func TestDeleteAllNotFound(t *testing.T) {
notFoundError := &errors.NewNotFound(api.Resource("services"), "foo").ErrStatus
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -447,6 +463,8 @@ func TestDeleteAllIgnoreNotFound(t *testing.T) {
_, svc, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
// Add an item to the list which will result in a 404 on delete
......@@ -488,6 +506,8 @@ func TestDeleteMultipleObject(t *testing.T) {
_, svc, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -524,6 +544,8 @@ func TestDeleteMultipleObjectContinueOnMissing(t *testing.T) {
_, svc, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -569,6 +591,8 @@ func TestDeleteMultipleResourcesWithTheSameName(t *testing.T) {
initTestErrorHandler(t)
_, svc, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -608,6 +632,8 @@ func TestDeleteDirectory(t *testing.T) {
_, _, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -641,6 +667,8 @@ func TestDeleteMultipleSelector(t *testing.T) {
pods, svc, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -706,26 +734,30 @@ func TestResourceErrors(t *testing.T) {
}
for k, testCase := range testCases {
tf := cmdtesting.NewTestFactory()
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
options := &DeleteOptions{
FilenameOptions: resource.FilenameOptions{},
GracePeriod: -1,
Cascade: false,
Output: "name",
}
err := options.Complete(tf, buf, errBuf, testCase.args, fakecmd)
if !testCase.errFn(err) {
t.Errorf("%s: unexpected error: %v", k, err)
continue
}
if buf.Len() > 0 {
t.Errorf("buffer should be empty: %s", string(buf.Bytes()))
}
t.Run(k, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
options := &DeleteOptions{
FilenameOptions: resource.FilenameOptions{},
GracePeriod: -1,
Cascade: false,
Output: "name",
}
err := options.Complete(tf, buf, errBuf, testCase.args, fakecmd)
if !testCase.errFn(err) {
t.Errorf("%s: unexpected error: %v", k, err)
return
}
if buf.Len() > 0 {
t.Errorf("buffer should be empty: %s", string(buf.Bytes()))
}
})
}
}
......@@ -33,6 +33,7 @@ import (
func TestDescribeUnknownSchemaObject(t *testing.T) {
d := &testDescriber{Output: "test output"}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
_, _, codec := cmdtesting.NewExternalScheme()
tf.DescriberVal = d
tf.UnstructuredClient = &fake.RESTClient{
......@@ -58,6 +59,7 @@ func TestDescribeUnknownSchemaObject(t *testing.T) {
func TestDescribeUnknownNamespacedSchemaObject(t *testing.T) {
d := &testDescriber{Output: "test output"}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
_, _, codec := cmdtesting.NewExternalScheme()
tf.DescriberVal = d
......@@ -83,6 +85,7 @@ func TestDescribeUnknownNamespacedSchemaObject(t *testing.T) {
func TestDescribeObject(t *testing.T) {
_, _, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
d := &testDescriber{Output: "test output"}
......@@ -118,6 +121,7 @@ func TestDescribeObject(t *testing.T) {
func TestDescribeListObjects(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
d := &testDescriber{Output: "test output"}
......@@ -140,6 +144,7 @@ func TestDescribeListObjects(t *testing.T) {
func TestDescribeObjectShowEvents(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
d := &testDescriber{Output: "test output"}
......@@ -163,6 +168,7 @@ func TestDescribeObjectShowEvents(t *testing.T) {
func TestDescribeObjectSkipEvents(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
d := &testDescriber{Output: "test output"}
......@@ -185,6 +191,7 @@ func TestDescribeObjectSkipEvents(t *testing.T) {
func TestDescribeHelpMessage(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
buf := bytes.NewBuffer([]byte{})
buferr := bytes.NewBuffer([]byte{})
......
......@@ -150,86 +150,90 @@ func TestCordon(t *testing.T) {
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
new_node := &corev1.Node{}
updated := false
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
m := &MyReq{req}
switch {
case m.isFor("GET", "/nodes/node"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, test.node)}, nil
case m.isFor("GET", "/nodes/bar"):
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: stringBody("nope")}, nil
case m.isFor("PATCH", "/nodes/node"):
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
defer req.Body.Close()
oldJSON, err := runtime.Encode(codec, node)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
appliedPatch, err := strategicpatch.StrategicMergePatch(oldJSON, data, &corev1.Node{})
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if err := runtime.DecodeInto(codec, appliedPatch, new_node); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if !reflect.DeepEqual(test.expected.Spec, new_node.Spec) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, test.expected.Spec.Unschedulable, new_node.Spec.Unschedulable)
t.Run(test.description, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
new_node := &corev1.Node{}
updated := false
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
m := &MyReq{req}
switch {
case m.isFor("GET", "/nodes/node"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, test.node)}, nil
case m.isFor("GET", "/nodes/bar"):
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: stringBody("nope")}, nil
case m.isFor("PATCH", "/nodes/node"):
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
defer req.Body.Close()
oldJSON, err := runtime.Encode(codec, node)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
appliedPatch, err := strategicpatch.StrategicMergePatch(oldJSON, data, &corev1.Node{})
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if err := runtime.DecodeInto(codec, appliedPatch, new_node); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if !reflect.DeepEqual(test.expected.Spec, new_node.Spec) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, test.expected.Spec.Unschedulable, new_node.Spec.Unschedulable)
}
updated = true
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, new_node)}, nil
default:
t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req)
return nil, nil
}
updated = true
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, new_node)}, nil
default:
t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req)
return nil, nil
}
}),
}
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
cmd := test.cmd(tf, buf)
saw_fatal := false
func() {
defer func() {
// Recover from the panic below.
_ = recover()
// Restore cmdutil behavior
cmdutil.DefaultBehaviorOnFatal()
}),
}
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
cmd := test.cmd(tf, buf)
saw_fatal := false
func() {
defer func() {
// Recover from the panic below.
_ = recover()
// Restore cmdutil behavior
cmdutil.DefaultBehaviorOnFatal()
}()
cmdutil.BehaviorOnFatal(func(e string, code int) {
saw_fatal = true
panic(e)
})
cmd.SetArgs([]string{test.arg})
cmd.Execute()
}()
cmdutil.BehaviorOnFatal(func(e string, code int) {
saw_fatal = true
panic(e)
})
cmd.SetArgs([]string{test.arg})
cmd.Execute()
}()
if test.expectFatal {
if !saw_fatal {
t.Fatalf("%s: unexpected non-error", test.description)
}
if updated {
t.Fatalf("%s: unexpected update", test.description)
if test.expectFatal {
if !saw_fatal {
t.Fatalf("%s: unexpected non-error", test.description)
}
if updated {
t.Fatalf("%s: unexpected update", test.description)
}
}
}
if !test.expectFatal && saw_fatal {
t.Fatalf("%s: unexpected error", test.description)
}
if !reflect.DeepEqual(test.expected.Spec, test.node.Spec) && !updated {
t.Fatalf("%s: node never updated", test.description)
}
if !test.expectFatal && saw_fatal {
t.Fatalf("%s: unexpected error", test.description)
}
if !reflect.DeepEqual(test.expected.Spec, test.node.Spec) && !updated {
t.Fatalf("%s: node never updated", test.description)
}
})
}
}
......@@ -597,164 +601,168 @@ func TestDrain(t *testing.T) {
currMethod = DeleteMethod
}
for _, test := range tests {
new_node := &corev1.Node{}
deleted := false
evicted := false
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
m := &MyReq{req}
switch {
case req.Method == "GET" && req.URL.Path == "/api":
apiVersions := metav1.APIVersions{
Versions: []string{"v1"},
}
return genResponseWithJsonEncodedBody(apiVersions)
case req.Method == "GET" && req.URL.Path == "/apis":
groupList := metav1.APIGroupList{
Groups: []metav1.APIGroup{
{
Name: "policy",
PreferredVersion: metav1.GroupVersionForDiscovery{
GroupVersion: "policy/v1beta1",
t.Run(test.description, func(t *testing.T) {
new_node := &corev1.Node{}
deleted := false
evicted := false
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
m := &MyReq{req}
switch {
case req.Method == "GET" && req.URL.Path == "/api":
apiVersions := metav1.APIVersions{
Versions: []string{"v1"},
}
return genResponseWithJsonEncodedBody(apiVersions)
case req.Method == "GET" && req.URL.Path == "/apis":
groupList := metav1.APIGroupList{
Groups: []metav1.APIGroup{
{
Name: "policy",
PreferredVersion: metav1.GroupVersionForDiscovery{
GroupVersion: "policy/v1beta1",
},
},
},
},
}
return genResponseWithJsonEncodedBody(groupList)
case req.Method == "GET" && req.URL.Path == "/api/v1":
resourceList := metav1.APIResourceList{
GroupVersion: "v1",
}
if testEviction {
resourceList.APIResources = []metav1.APIResource{
{
Name: EvictionSubresource,
Kind: EvictionKind,
},
}
return genResponseWithJsonEncodedBody(groupList)
case req.Method == "GET" && req.URL.Path == "/api/v1":
resourceList := metav1.APIResourceList{
GroupVersion: "v1",
}
if testEviction {
resourceList.APIResources = []metav1.APIResource{
{
Name: EvictionSubresource,
Kind: EvictionKind,
},
}
}
return genResponseWithJsonEncodedBody(resourceList)
case m.isFor("GET", "/nodes/node"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, test.node)}, nil
case m.isFor("GET", "/namespaces/default/replicationcontrollers/rc"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &test.rcs[0])}, nil
case m.isFor("GET", "/namespaces/default/daemonsets/ds"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(testapi.Extensions.Codec(), &ds)}, nil
case m.isFor("GET", "/namespaces/default/daemonsets/missing-ds"):
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: objBody(testapi.Extensions.Codec(), &extensions.DaemonSet{})}, nil
case m.isFor("GET", "/namespaces/default/jobs/job"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(testapi.Batch.Codec(), &job)}, nil
case m.isFor("GET", "/namespaces/default/replicasets/rs"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(testapi.Extensions.Codec(), &test.replicaSets[0])}, nil
case m.isFor("GET", "/namespaces/default/pods/bar"):
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: objBody(codec, &corev1.Pod{})}, nil
case m.isFor("GET", "/pods"):
values, err := url.ParseQuery(req.URL.RawQuery)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
get_params := make(url.Values)
get_params["fieldSelector"] = []string{"spec.nodeName=node"}
if !reflect.DeepEqual(get_params, values) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, get_params, values)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &corev1.PodList{Items: test.pods})}, nil
case m.isFor("GET", "/replicationcontrollers"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &api.ReplicationControllerList{Items: test.rcs})}, nil
case m.isFor("PATCH", "/nodes/node"):
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
defer req.Body.Close()
oldJSON, err := runtime.Encode(codec, node)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
appliedPatch, err := strategicpatch.StrategicMergePatch(oldJSON, data, &corev1.Node{})
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if err := runtime.DecodeInto(codec, appliedPatch, new_node); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if !reflect.DeepEqual(test.expected.Spec, new_node.Spec) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, test.expected.Spec, new_node.Spec)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, new_node)}, nil
case m.isFor("DELETE", "/namespaces/default/pods/bar"):
deleted = true
return &http.Response{StatusCode: 204, Header: defaultHeader(), Body: objBody(codec, &test.pods[0])}, nil
case m.isFor("POST", "/namespaces/default/pods/bar/eviction"):
evicted = true
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: policyObjBody(&policyv1beta1.Eviction{})}, nil
default:
t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req)
return nil, nil
}
return genResponseWithJsonEncodedBody(resourceList)
case m.isFor("GET", "/nodes/node"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, test.node)}, nil
case m.isFor("GET", "/namespaces/default/replicationcontrollers/rc"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &test.rcs[0])}, nil
case m.isFor("GET", "/namespaces/default/daemonsets/ds"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(testapi.Extensions.Codec(), &ds)}, nil
case m.isFor("GET", "/namespaces/default/daemonsets/missing-ds"):
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: objBody(testapi.Extensions.Codec(), &extensions.DaemonSet{})}, nil
case m.isFor("GET", "/namespaces/default/jobs/job"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(testapi.Batch.Codec(), &job)}, nil
case m.isFor("GET", "/namespaces/default/replicasets/rs"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(testapi.Extensions.Codec(), &test.replicaSets[0])}, nil
case m.isFor("GET", "/namespaces/default/pods/bar"):
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: objBody(codec, &corev1.Pod{})}, nil
case m.isFor("GET", "/pods"):
values, err := url.ParseQuery(req.URL.RawQuery)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
get_params := make(url.Values)
get_params["fieldSelector"] = []string{"spec.nodeName=node"}
if !reflect.DeepEqual(get_params, values) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, get_params, values)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &corev1.PodList{Items: test.pods})}, nil
case m.isFor("GET", "/replicationcontrollers"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &api.ReplicationControllerList{Items: test.rcs})}, nil
case m.isFor("PATCH", "/nodes/node"):
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
defer req.Body.Close()
oldJSON, err := runtime.Encode(codec, node)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
appliedPatch, err := strategicpatch.StrategicMergePatch(oldJSON, data, &corev1.Node{})
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if err := runtime.DecodeInto(codec, appliedPatch, new_node); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if !reflect.DeepEqual(test.expected.Spec, new_node.Spec) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, test.expected.Spec, new_node.Spec)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, new_node)}, nil
case m.isFor("DELETE", "/namespaces/default/pods/bar"):
deleted = true
return &http.Response{StatusCode: 204, Header: defaultHeader(), Body: objBody(codec, &test.pods[0])}, nil
case m.isFor("POST", "/namespaces/default/pods/bar/eviction"):
evicted = true
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: policyObjBody(&policyv1beta1.Eviction{})}, nil
default:
t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req)
return nil, nil
}
}),
}
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdDrain(tf, buf, errBuf)
saw_fatal := false
fatal_msg := ""
func() {
defer func() {
// Recover from the panic below.
_ = recover()
// Restore cmdutil behavior
cmdutil.DefaultBehaviorOnFatal()
}()
cmdutil.BehaviorOnFatal(func(e string, code int) { saw_fatal = true; fatal_msg = e; panic(e) })
cmd.SetArgs(test.args)
cmd.Execute()
}()
if test.expectFatal {
if !saw_fatal {
t.Fatalf("%s: unexpected non-error when using %s", test.description, currMethod)
}),
}
} else {
if saw_fatal {
t.Fatalf("%s: unexpected error when using %s: %s", test.description, currMethod, fatal_msg)
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdDrain(tf, buf, errBuf)
saw_fatal := false
fatal_msg := ""
func() {
defer func() {
// Recover from the panic below.
_ = recover()
// Restore cmdutil behavior
cmdutil.DefaultBehaviorOnFatal()
}()
cmdutil.BehaviorOnFatal(func(e string, code int) { saw_fatal = true; fatal_msg = e; panic(e) })
cmd.SetArgs(test.args)
cmd.Execute()
}()
if test.expectFatal {
if !saw_fatal {
t.Fatalf("%s: unexpected non-error when using %s", test.description, currMethod)
}
} else {
if saw_fatal {
t.Fatalf("%s: unexpected error when using %s: %s", test.description, currMethod, fatal_msg)
}
}
}
if test.expectDelete {
// Test Delete
if !testEviction && !deleted {
t.Fatalf("%s: pod never deleted", test.description)
}
// Test Eviction
if testEviction && !evicted {
t.Fatalf("%s: pod never evicted", test.description)
if test.expectDelete {
// Test Delete
if !testEviction && !deleted {
t.Fatalf("%s: pod never deleted", test.description)
}
// Test Eviction
if testEviction && !evicted {
t.Fatalf("%s: pod never evicted", test.description)
}
}
}
if !test.expectDelete {
if deleted {
t.Fatalf("%s: unexpected delete when using %s", test.description, currMethod)
if !test.expectDelete {
if deleted {
t.Fatalf("%s: unexpected delete when using %s", test.description, currMethod)
}
}
}
if len(test.expectWarning) > 0 {
if len(errBuf.String()) == 0 {
t.Fatalf("%s: expected warning, but found no stderr output", test.description)
}
if len(test.expectWarning) > 0 {
if len(errBuf.String()) == 0 {
t.Fatalf("%s: expected warning, but found no stderr output", test.description)
}
if errBuf.String() != test.expectWarning {
t.Fatalf("%s: actual warning message did not match expected warning message.\n Expecting: %s\n Got: %s", test.description, test.expectWarning, errBuf.String())
if errBuf.String() != test.expectWarning {
t.Fatalf("%s: actual warning message did not match expected warning message.\n Expecting: %s\n Got: %s", test.description, test.expectWarning, errBuf.String())
}
}
}
})
}
}
}
......@@ -824,31 +832,35 @@ func TestDeletePods(t *testing.T) {
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
o := DrainOptions{Factory: tf}
o.mapper, _ = tf.Object()
o.Out = os.Stdout
_, pods := createPods(false)
pendingPods, err := o.waitForDelete(pods, test.interval, test.timeout, false, test.getPodFn)
if test.expectError {
if err == nil {
t.Fatalf("%s: unexpected non-error", test.description)
} else if test.expectedError != nil {
if *test.expectedError != err {
t.Fatalf("%s: the error does not match expected error", test.description)
t.Run(test.description, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
o := DrainOptions{Factory: tf}
o.mapper, _ = tf.Object()
o.Out = os.Stdout
_, pods := createPods(false)
pendingPods, err := o.waitForDelete(pods, test.interval, test.timeout, false, test.getPodFn)
if test.expectError {
if err == nil {
t.Fatalf("%s: unexpected non-error", test.description)
} else if test.expectedError != nil {
if *test.expectedError != err {
t.Fatalf("%s: the error does not match expected error", test.description)
}
}
}
}
if !test.expectError && err != nil {
t.Fatalf("%s: unexpected error", test.description)
}
if test.expectPendingPods && len(pendingPods) == 0 {
t.Fatalf("%s: unexpected empty pods", test.description)
}
if !test.expectPendingPods && len(pendingPods) > 0 {
t.Fatalf("%s: unexpected pending pods", test.description)
}
if !test.expectError && err != nil {
t.Fatalf("%s: unexpected error", test.description)
}
if test.expectPendingPods && len(pendingPods) == 0 {
t.Fatalf("%s: unexpected empty pods", test.description)
}
if !test.expectPendingPods && len(pendingPods) > 0 {
t.Fatalf("%s: unexpected pending pods", test.description)
}
})
}
}
......
......@@ -207,6 +207,8 @@ func TestEdit(t *testing.T) {
}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClientForMappingFunc = func(mapping *meta.RESTMapping) (resource.RESTClient, error) {
versionedAPIPath := ""
if mapping.GroupVersionKind.Group == "" {
......
......@@ -130,38 +130,42 @@ func TestPodAndContainer(t *testing.T) {
},
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { return nil, nil }),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
cmd := &cobra.Command{}
options := test.p
options.Err = bytes.NewBuffer([]byte{})
err := options.Complete(tf, cmd, test.args, test.argsLenAtDash)
if test.expectError && err == nil {
t.Errorf("%s: unexpected non-error", test.name)
}
if !test.expectError && err != nil {
t.Errorf("%s: unexpected error: %v", test.name, err)
}
if err != nil {
continue
}
if options.PodName != test.expectedPod {
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedPod, options.PodName)
}
if options.ContainerName != test.expectedContainer {
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedContainer, options.ContainerName)
}
if !reflect.DeepEqual(test.expectedArgs, options.Command) {
t.Errorf("%s: expected: %v, got %v", test.name, test.expectedArgs, options.Command)
}
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { return nil, nil }),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
cmd := &cobra.Command{}
options := test.p
options.Err = bytes.NewBuffer([]byte{})
err := options.Complete(tf, cmd, test.args, test.argsLenAtDash)
if test.expectError && err == nil {
t.Errorf("%s: unexpected non-error", test.name)
}
if !test.expectError && err != nil {
t.Errorf("%s: unexpected error: %v", test.name, err)
}
if err != nil {
return
}
if options.PodName != test.expectedPod {
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedPod, options.PodName)
}
if options.ContainerName != test.expectedContainer {
t.Errorf("%s: expected: %s, got: %s", test.name, test.expectedContainer, options.ContainerName)
}
if !reflect.DeepEqual(test.expectedArgs, options.Command) {
t.Errorf("%s: expected: %v, got %v", test.name, test.expectedArgs, options.Command)
}
})
}
}
......@@ -187,67 +191,71 @@ func TestExec(t *testing.T) {
},
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
bufOut := bytes.NewBuffer([]byte{})
bufErr := bytes.NewBuffer([]byte{})
bufIn := bytes.NewBuffer([]byte{})
ex := &fakeRemoteExecutor{}
if test.execErr {
ex.execErr = fmt.Errorf("exec error")
}
params := &ExecOptions{
StreamOptions: StreamOptions{
PodName: "foo",
ContainerName: "bar",
In: bufIn,
Out: bufOut,
Err: bufErr,
},
Executor: ex,
}
cmd := &cobra.Command{}
args := []string{"test", "command"}
if err := params.Complete(tf, cmd, args, -1); err != nil {
t.Fatal(err)
}
err := params.Run()
if test.execErr && err != ex.execErr {
t.Errorf("%s: Unexpected exec error: %v", test.name, err)
continue
}
if !test.execErr && err != nil {
t.Errorf("%s: Unexpected error: %v", test.name, err)
continue
}
if test.execErr {
continue
}
if ex.url.Path != test.execPath {
t.Errorf("%s: Did not get expected path for exec request", test.name)
continue
}
if ex.method != "POST" {
t.Errorf("%s: Did not get method for exec request: %s", test.name, ex.method)
}
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
bufOut := bytes.NewBuffer([]byte{})
bufErr := bytes.NewBuffer([]byte{})
bufIn := bytes.NewBuffer([]byte{})
ex := &fakeRemoteExecutor{}
if test.execErr {
ex.execErr = fmt.Errorf("exec error")
}
params := &ExecOptions{
StreamOptions: StreamOptions{
PodName: "foo",
ContainerName: "bar",
In: bufIn,
Out: bufOut,
Err: bufErr,
},
Executor: ex,
}
cmd := &cobra.Command{}
args := []string{"test", "command"}
if err := params.Complete(tf, cmd, args, -1); err != nil {
t.Fatal(err)
}
err := params.Run()
if test.execErr && err != ex.execErr {
t.Errorf("%s: Unexpected exec error: %v", test.name, err)
return
}
if !test.execErr && err != nil {
t.Errorf("%s: Unexpected error: %v", test.name, err)
return
}
if test.execErr {
return
}
if ex.url.Path != test.execPath {
t.Errorf("%s: Did not get expected path for exec request", test.name)
return
}
if ex.method != "POST" {
t.Errorf("%s: Did not get method for exec request: %s", test.name, ex.method)
}
})
}
}
......
......@@ -466,42 +466,46 @@ func TestRunExposeService(t *testing.T) {
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.calls[m] && m == "GET":
return &http.Response{StatusCode: test.status, Header: defaultHeader(), Body: objBody(codec, test.input)}, nil
case p == test.calls[m] && m == "POST":
return &http.Response{StatusCode: test.status, Header: defaultHeader(), Body: objBody(codec, test.output)}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.Namespace = test.ns
buf := bytes.NewBuffer([]byte{})
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
cmd := NewCmdExposeService(tf, buf)
cmd.SetOutput(buf)
for flag, value := range test.flags {
cmd.Flags().Set(flag, value)
}
cmd.Run(cmd, test.args)
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.calls[m] && m == "GET":
return &http.Response{StatusCode: test.status, Header: defaultHeader(), Body: objBody(codec, test.input)}, nil
case p == test.calls[m] && m == "POST":
return &http.Response{StatusCode: test.status, Header: defaultHeader(), Body: objBody(codec, test.output)}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.Namespace = test.ns
buf := bytes.NewBuffer([]byte{})
out := buf.String()
if _, ok := test.flags["dry-run"]; ok {
test.expected = fmt.Sprintf("service %q exposed (dry run)", test.flags["name"])
}
cmd := NewCmdExposeService(tf, buf)
cmd.SetOutput(buf)
for flag, value := range test.flags {
cmd.Flags().Set(flag, value)
}
cmd.Run(cmd, test.args)
if !strings.Contains(out, test.expected) {
t.Errorf("%s: Unexpected output! Expected\n%s\ngot\n%s", test.name, test.expected, out)
}
out := buf.String()
if _, ok := test.flags["dry-run"]; ok {
test.expected = fmt.Sprintf("service %q exposed (dry run)", test.flags["name"])
}
if !strings.Contains(out, test.expected) {
t.Errorf("%s: Unexpected output! Expected\n%s\ngot\n%s", test.name, test.expected, out)
}
})
}
}
......@@ -321,38 +321,44 @@ func TestLabelErrors(t *testing.T) {
}
for k, testCase := range testCases {
tf := cmdtesting.NewTestFactory()
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
t.Run(k, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdLabel(tf, buf)
cmd.SetOutput(buf)
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
for k, v := range testCase.flags {
cmd.Flags().Set(k, v)
}
opts := LabelOptions{}
err := opts.Complete(buf, cmd, testCase.args)
if err == nil {
err = opts.Validate()
}
if err == nil {
err = opts.RunLabel(tf, cmd)
}
if !testCase.errFn(err) {
t.Errorf("%s: unexpected error: %v", k, err)
continue
}
if buf.Len() > 0 {
t.Errorf("buffer should be empty: %s", string(buf.Bytes()))
}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdLabel(tf, buf)
cmd.SetOutput(buf)
for k, v := range testCase.flags {
cmd.Flags().Set(k, v)
}
opts := LabelOptions{}
err := opts.Complete(buf, cmd, testCase.args)
if err == nil {
err = opts.Validate()
}
if err == nil {
err = opts.RunLabel(tf, cmd)
}
if !testCase.errFn(err) {
t.Errorf("%s: unexpected error: %v", k, err)
return
}
if buf.Len() > 0 {
t.Errorf("buffer should be empty: %s", string(buf.Bytes()))
}
})
}
}
func TestLabelForResourceFromFile(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -405,6 +411,8 @@ func TestLabelForResourceFromFile(t *testing.T) {
func TestLabelLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
......@@ -438,6 +446,8 @@ func TestLabelLocal(t *testing.T) {
func TestLabelMultipleObjects(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......
......@@ -48,39 +48,43 @@ func TestLog(t *testing.T) {
},
}
for _, test := range tests {
logContent := "test log content"
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
case p == test.logPath && m == "GET":
body := ioutil.NopCloser(bytes.NewBufferString(logContent))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %#v\n%#v", test.name, req.URL, req)
return nil, nil
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdLogs(tf, buf, buf)
cmd.Flags().Set("namespace", "test")
cmd.Run(cmd, []string{"foo"})
if buf.String() != logContent {
t.Errorf("%s: did not get expected log content. Got: %s", test.name, buf.String())
}
t.Run(test.name, func(t *testing.T) {
logContent := "test log content"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
case p == test.logPath && m == "GET":
body := ioutil.NopCloser(bytes.NewBufferString(logContent))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %#v\n%#v", test.name, req.URL, req)
return nil, nil
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdLogs(tf, buf, buf)
cmd.Flags().Set("namespace", "test")
cmd.Run(cmd, []string{"foo"})
if buf.String() != logContent {
t.Errorf("%s: did not get expected log content. Got: %s", test.name, buf.String())
}
})
}
}
......@@ -101,6 +105,7 @@ func testPod() *api.Pod {
func TestValidateLogFlags(t *testing.T) {
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
tests := []struct {
name string
......@@ -152,6 +157,7 @@ func TestValidateLogFlags(t *testing.T) {
func TestLogComplete(t *testing.T) {
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
tests := []struct {
name string
......
......@@ -32,6 +32,8 @@ func TestPatchObject(t *testing.T) {
_, svc, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -72,6 +74,8 @@ func TestPatchObjectFromFile(t *testing.T) {
_, svc, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -108,6 +112,8 @@ func TestPatchNoop(t *testing.T) {
patchObject := &svc.Items[0]
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -154,6 +160,8 @@ func TestPatchObjectFromFileOutput(t *testing.T) {
svcCopy.Labels["post-patch"] = "post-patch-value"
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......
......@@ -80,34 +80,38 @@ func TestPluginCmd(t *testing.T) {
}
for _, test := range tests {
inBuf := bytes.NewBuffer([]byte{})
outBuf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
t.Run(test.name, func(t *testing.T) {
inBuf := bytes.NewBuffer([]byte{})
outBuf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmdutil.BehaviorOnFatal(func(str string, code int) {
errBuf.Write([]byte(str))
})
cmdutil.BehaviorOnFatal(func(str string, code int) {
errBuf.Write([]byte(str))
})
runner := &mockPluginRunner{
success: test.expectedSuccess,
}
runner := &mockPluginRunner{
success: test.expectedSuccess,
}
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
f := cmdtesting.NewTestFactory()
cmd := NewCmdForPlugin(f, test.plugin, runner, inBuf, outBuf, errBuf)
if cmd == nil {
if !test.expectedNilCmd {
t.Fatalf("%s: command was unexpectedly not registered", test.name)
cmd := NewCmdForPlugin(f, test.plugin, runner, inBuf, outBuf, errBuf)
if cmd == nil {
if !test.expectedNilCmd {
t.Fatalf("%s: command was unexpectedly not registered", test.name)
}
return
}
continue
}
cmd.Run(cmd, []string{})
cmd.Run(cmd, []string{})
if test.expectedSuccess && outBuf.String() != fmt.Sprintf("ok: %s", test.plugin.Name) {
t.Errorf("%s: unexpected output: %q", test.name, outBuf.String())
}
if test.expectedSuccess && outBuf.String() != fmt.Sprintf("ok: %s", test.plugin.Name) {
t.Errorf("%s: unexpected output: %q", test.name, outBuf.String())
}
if !test.expectedSuccess && errBuf.String() != fmt.Sprintf("error: oops %s", test.plugin.Name) {
t.Errorf("%s: unexpected err output: %q", test.name, errBuf.String())
}
if !test.expectedSuccess && errBuf.String() != fmt.Sprintf("error: oops %s", test.plugin.Name) {
t.Errorf("%s: unexpected err output: %q", test.name, errBuf.String())
}
})
}
}
......@@ -71,68 +71,72 @@ func testPortForward(t *testing.T, flags map[string]string, args []string) {
},
}
for _, test := range tests {
var err error
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.name, func(t *testing.T) {
var err error
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
VersionedAPIPath: "/api/v1",
GroupVersion: schema.GroupVersion{Group: ""},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %#v\n%#v", test.name, req.URL, req)
return nil, nil
}
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
ff := &fakePortForwarder{}
if test.pfErr {
ff.pfErr = fmt.Errorf("pf error")
}
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
opts := &PortForwardOptions{}
cmd := NewCmdPortForward(tf, os.Stdout, os.Stderr)
cmd.Run = func(cmd *cobra.Command, args []string) {
if err = opts.Complete(tf, cmd, args); err != nil {
return
tf.Client = &fake.RESTClient{
VersionedAPIPath: "/api/v1",
GroupVersion: schema.GroupVersion{Group: ""},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == test.podPath && m == "GET":
body := objBody(codec, test.pod)
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %#v\n%#v", test.name, req.URL, req)
return nil, nil
}
}),
}
opts.PortForwarder = ff
if err = opts.Validate(); err != nil {
return
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
ff := &fakePortForwarder{}
if test.pfErr {
ff.pfErr = fmt.Errorf("pf error")
}
err = opts.RunPortForward()
}
for name, value := range flags {
cmd.Flags().Set(name, value)
}
cmd.Run(cmd, args)
opts := &PortForwardOptions{}
cmd := NewCmdPortForward(tf, os.Stdout, os.Stderr)
cmd.Run = func(cmd *cobra.Command, args []string) {
if err = opts.Complete(tf, cmd, args); err != nil {
return
}
opts.PortForwarder = ff
if err = opts.Validate(); err != nil {
return
}
err = opts.RunPortForward()
}
if test.pfErr && err != ff.pfErr {
t.Errorf("%s: Unexpected port-forward error: %v", test.name, err)
}
if !test.pfErr && err != nil {
t.Errorf("%s: Unexpected error: %v", test.name, err)
}
if test.pfErr {
continue
}
for name, value := range flags {
cmd.Flags().Set(name, value)
}
cmd.Run(cmd, args)
if ff.url.Path != test.pfPath {
t.Errorf("%s: Did not get expected path for portforward request", test.name)
}
if ff.method != "POST" {
t.Errorf("%s: Did not get method for attach request: %s", test.name, ff.method)
}
if test.pfErr && err != ff.pfErr {
t.Errorf("%s: Unexpected port-forward error: %v", test.name, err)
}
if !test.pfErr && err != nil {
t.Errorf("%s: Unexpected error: %v", test.name, err)
}
if test.pfErr {
return
}
if ff.url == nil || ff.url.Path != test.pfPath {
t.Errorf("%s: Did not get expected path for portforward request", test.name)
}
if ff.method != "POST" {
t.Errorf("%s: Did not get method for attach request: %s", test.name, ff.method)
}
})
}
}
......
......@@ -33,6 +33,7 @@ func TestReplaceObject(t *testing.T) {
_, _, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
deleted := false
......@@ -89,6 +90,7 @@ func TestReplaceMultipleObject(t *testing.T) {
_, svc, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
redisMasterDeleted := false
......@@ -159,6 +161,7 @@ func TestReplaceDirectory(t *testing.T) {
_, _, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
created := map[string]bool{}
......@@ -216,6 +219,7 @@ func TestForceReplaceObjectNotFound(t *testing.T) {
_, _, rc := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......
......@@ -198,6 +198,7 @@ func testComponentStatusData() *api.ComponentStatusList {
func TestGetUnknownSchemaObject(t *testing.T) {
t.Skip("This test is completely broken. The first thing it does is add the object to the scheme!")
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
_, _, codec := cmdtesting.NewExternalScheme()
tf.OpenAPISchemaFunc = openapitesting.CreateOpenAPISchemaFunc(openapiSchemaPath)
......@@ -272,6 +273,7 @@ func TestGetUnknownSchemaObject(t *testing.T) {
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
func TestGetSchemaObject(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := testapi.Default.Codec()
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
......@@ -294,6 +296,7 @@ func TestGetObjectsWithOpenAPIOutputFormatPresent(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
// overide the openAPISchema function to return custom output
......@@ -351,6 +354,7 @@ func TestGetObjects(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -417,6 +421,8 @@ func TestGetObjectsFiltered(t *testing.T) {
for i, test := range testCases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -458,6 +464,7 @@ func TestGetObjectIgnoreNotFound(t *testing.T) {
}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -511,6 +518,7 @@ func TestGetSortedObjects(t *testing.T) {
}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -544,6 +552,7 @@ func TestGetObjectsIdentifiedByFile(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -571,6 +580,7 @@ func TestGetListObjects(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -598,6 +608,7 @@ func TestGetAllListObjects(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -626,6 +637,7 @@ func TestGetListComponentStatus(t *testing.T) {
statuses := testComponentStatusData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -667,6 +679,7 @@ func TestGetMixedGenericObjects(t *testing.T) {
}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -717,6 +730,7 @@ func TestGetMultipleTypeObjects(t *testing.T) {
pods, svc, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -756,6 +770,7 @@ func TestGetMultipleTypeObjectsAsList(t *testing.T) {
pods, svc, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -858,6 +873,7 @@ func TestGetMultipleTypeObjectsWithLabelSelector(t *testing.T) {
pods, svc, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -902,6 +918,7 @@ func TestGetMultipleTypeObjectsWithFieldSelector(t *testing.T) {
pods, svc, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -954,6 +971,7 @@ func TestGetMultipleTypeObjectsWithDirectReference(t *testing.T) {
}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -993,6 +1011,7 @@ func TestGetByFormatForcesFlag(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -1089,6 +1108,7 @@ func TestWatchLabelSelector(t *testing.T) {
pods, events := watchTestData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
podList := &api.PodList{
......@@ -1141,6 +1161,7 @@ func TestWatchFieldSelector(t *testing.T) {
pods, events := watchTestData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
podList := &api.PodList{
......@@ -1193,6 +1214,7 @@ func TestWatchResource(t *testing.T) {
pods, events := watchTestData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -1237,6 +1259,7 @@ func TestWatchResourceIdentifiedByFile(t *testing.T) {
pods, events := watchTestData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -1282,6 +1305,7 @@ func TestWatchOnlyResource(t *testing.T) {
pods, events := watchTestData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
......@@ -1325,6 +1349,7 @@ func TestWatchOnlyList(t *testing.T) {
pods, events := watchTestData()
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
podList := &api.PodList{
......
......@@ -25,6 +25,7 @@ import (
func TestValidateArgs(t *testing.T) {
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
tests := []struct {
testName string
......
......@@ -168,35 +168,39 @@ func TestRunArgsFollowDashRules(t *testing.T) {
},
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
if req.URL.Path == "/namespaces/test/replicationcontrollers" {
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: objBody(codec, rc)}, nil
}
return &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewBuffer([]byte("{}"))),
}, nil
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = &restclient.Config{}
cmd := NewCmdRun(tf, os.Stdin, os.Stdout, os.Stderr)
cmd.Flags().Set("image", "nginx")
cmd.Flags().Set("generator", "run/v1")
err := RunRun(tf, os.Stdin, os.Stdout, os.Stderr, cmd, test.args, test.argsLenAtDash)
if test.expectError && err == nil {
t.Errorf("unexpected non-error (%s)", test.name)
}
if !test.expectError && err != nil {
t.Errorf("unexpected error: %v (%s)", err, test.name)
}
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
if req.URL.Path == "/namespaces/test/replicationcontrollers" {
return &http.Response{StatusCode: 201, Header: defaultHeader(), Body: objBody(codec, rc)}, nil
}
return &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewBuffer([]byte("{}"))),
}, nil
}),
}
tf.Namespace = "test"
tf.ClientConfigVal = &restclient.Config{}
cmd := NewCmdRun(tf, os.Stdin, os.Stdout, os.Stderr)
cmd.Flags().Set("image", "nginx")
cmd.Flags().Set("generator", "run/v1")
err := RunRun(tf, os.Stdin, os.Stdout, os.Stderr, cmd, test.args, test.argsLenAtDash)
if test.expectError && err == nil {
t.Errorf("unexpected non-error (%s)", test.name)
}
if !test.expectError && err != nil {
t.Errorf("unexpected error: %v (%s)", err, test.name)
}
})
}
}
......@@ -292,90 +296,98 @@ func TestGenerateService(t *testing.T) {
},
}
for _, test := range tests {
sawPOST := false
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.name, func(t *testing.T) {
sawPOST := false
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.ClientConfigVal = defaultClientConfig()
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case test.expectPOST && m == "POST" && p == "/namespaces/namespace/services":
sawPOST = true
body := objBody(codec, &test.service)
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
defer req.Body.Close()
svc := &api.Service{}
if err := runtime.DecodeInto(codec, data, svc); err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Copy things that are defaulted by the system
test.service.Annotations = svc.Annotations
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
tf.ClientConfigVal = defaultClientConfig()
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case test.expectPOST && m == "POST" && p == "/namespaces/namespace/services":
sawPOST = true
body := objBody(codec, &test.service)
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
defer req.Body.Close()
svc := &api.Service{}
if err := runtime.DecodeInto(codec, data, svc); err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Copy things that are defaulted by the system
test.service.Annotations = svc.Annotations
if !reflect.DeepEqual(&test.service, svc) {
t.Errorf("expected:\n%v\nsaw:\n%v\n", &test.service, svc)
if !reflect.DeepEqual(&test.service, svc) {
t.Errorf("expected:\n%v\nsaw:\n%v\n", &test.service, svc)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
// Ensures no GET is performed when deleting by name
t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
}
cmd := &cobra.Command{}
cmd.Flags().Bool(cmdutil.ApplyAnnotationsFlag, false, "")
cmd.Flags().Bool("record", false, "Record current kubectl command in the resource annotation. If set to false, do not record the command. If set to true, record the command. If not set, default to updating the existing annotation value only if one already exists.")
cmdutil.AddPrinterFlags(cmd)
cmdutil.AddInclude3rdPartyFlags(cmd)
addRunFlags(cmd)
}),
}
cmd := &cobra.Command{}
cmd.Flags().Bool(cmdutil.ApplyAnnotationsFlag, false, "")
cmd.Flags().Bool("record", false, "Record current kubectl command in the resource annotation. If set to false, do not record the command. If set to true, record the command. If not set, default to updating the existing annotation value only if one already exists.")
cmdutil.AddPrinterFlags(cmd)
cmdutil.AddInclude3rdPartyFlags(cmd)
addRunFlags(cmd)
if !test.expectPOST {
cmd.Flags().Set("dry-run", "true")
}
if !test.expectPOST {
cmd.Flags().Set("dry-run", "true")
}
if len(test.port) > 0 {
cmd.Flags().Set("port", test.port)
test.params["port"] = test.port
}
if len(test.port) > 0 {
cmd.Flags().Set("port", test.port)
test.params["port"] = test.port
}
buff := &bytes.Buffer{}
_, err := generateService(tf, cmd, test.args, test.serviceGenerator, test.params, "namespace", buff)
if test.expectErr {
if err == nil {
t.Error("unexpected non-error")
buff := &bytes.Buffer{}
_, err := generateService(tf, cmd, test.args, test.serviceGenerator, test.params, "namespace", buff)
if test.expectErr {
if err == nil {
t.Error("unexpected non-error")
}
return
}
continue
}
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if test.expectPOST != sawPOST {
t.Errorf("expectPost: %v, sawPost: %v", test.expectPOST, sawPOST)
}
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if test.expectPOST != sawPOST {
t.Errorf("expectPost: %v, sawPost: %v", test.expectPOST, sawPOST)
}
})
}
}
func TestRunValidations(t *testing.T) {
tests := []struct {
name string
args []string
flags map[string]string
expectedErr string
}{
{
name: "test missing name error",
expectedErr: "NAME is required",
},
{
name: "test missing --image error",
args: []string{"test"},
expectedErr: "--image is required",
},
{
name: "test invalid image name error",
args: []string{"test"},
flags: map[string]string{
"image": "#",
......@@ -383,6 +395,7 @@ func TestRunValidations(t *testing.T) {
expectedErr: "Invalid image name",
},
{
name: "test stdin replicas value",
args: []string{"test"},
flags: map[string]string{
"image": "busybox",
......@@ -392,6 +405,7 @@ func TestRunValidations(t *testing.T) {
expectedErr: "stdin requires that replicas is 1",
},
{
name: "test rm errors when used on non-attached containers",
args: []string{"test"},
flags: map[string]string{
"image": "busybox",
......@@ -400,6 +414,7 @@ func TestRunValidations(t *testing.T) {
expectedErr: "rm should only be used for attached containers",
},
{
name: "test error on attached containers options",
args: []string{"test"},
flags: map[string]string{
"image": "busybox",
......@@ -409,6 +424,7 @@ func TestRunValidations(t *testing.T) {
expectedErr: "can't be used with attached containers options",
},
{
name: "test error on attached containers options, with value from stdin",
args: []string{"test"},
flags: map[string]string{
"image": "busybox",
......@@ -418,6 +434,7 @@ func TestRunValidations(t *testing.T) {
expectedErr: "can't be used with attached containers options",
},
{
name: "test error on attached containers options, with value from stdin and tty",
args: []string{"test"},
flags: map[string]string{
"image": "busybox",
......@@ -428,6 +445,7 @@ func TestRunValidations(t *testing.T) {
expectedErr: "can't be used with attached containers options",
},
{
name: "test error when tty=true and no stdin provided",
args: []string{"test"},
flags: map[string]string{
"image": "busybox",
......@@ -437,28 +455,32 @@ func TestRunValidations(t *testing.T) {
},
}
for _, test := range tests {
tf := cmdtesting.NewTestFactory()
_, _, codec := cmdtesting.NewExternalScheme()
tf.Client = &fake.RESTClient{
NegotiatedSerializer: scheme.Codecs,
Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, cmdtesting.NewInternalType("", "", ""))},
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
inBuf := bytes.NewReader([]byte{})
outBuf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
t.Run(test.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
cmd := NewCmdRun(tf, inBuf, outBuf, errBuf)
for flagName, flagValue := range test.flags {
cmd.Flags().Set(flagName, flagValue)
}
err := RunRun(tf, inBuf, outBuf, errBuf, cmd, test.args, cmd.ArgsLenAtDash())
if err != nil && len(test.expectedErr) > 0 {
if !strings.Contains(err.Error(), test.expectedErr) {
t.Errorf("unexpected error: %v", err)
_, _, codec := cmdtesting.NewExternalScheme()
tf.Client = &fake.RESTClient{
NegotiatedSerializer: scheme.Codecs,
Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, cmdtesting.NewInternalType("", "", ""))},
}
}
tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig()
inBuf := bytes.NewReader([]byte{})
outBuf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdRun(tf, inBuf, outBuf, errBuf)
for flagName, flagValue := range test.flags {
cmd.Flags().Set(flagName, flagValue)
}
err := RunRun(tf, inBuf, outBuf, errBuf, cmd, test.args, cmd.ArgsLenAtDash())
if err != nil && len(test.expectedErr) > 0 {
if !strings.Contains(err.Error(), test.expectedErr) {
t.Errorf("unexpected error: %v", err)
}
}
})
}
}
......@@ -47,6 +47,8 @@ import (
func TestSetEnvLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: ""},
......@@ -83,6 +85,8 @@ func TestSetEnvLocal(t *testing.T) {
func TestSetMultiResourcesEnvLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
......@@ -122,12 +126,14 @@ func TestSetMultiResourcesEnvLocal(t *testing.T) {
func TestSetEnvRemote(t *testing.T) {
inputs := []struct {
name string
object runtime.Object
apiPrefix, apiGroup, apiVersion string
testAPIGroup string
args []string
}{
{
name: "test extensions.v1beta1 replicaset",
object: &extensionsv1beta1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: extensionsv1beta1.ReplicaSetSpec{
......@@ -148,6 +154,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"replicaset", "nginx", "env=prod"},
},
{
name: "test apps.v1beta2 replicaset",
object: &appsv1beta2.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.ReplicaSetSpec{
......@@ -168,6 +175,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"replicaset", "nginx", "env=prod"},
},
{
name: "test appsv1 replicaset",
object: &appsv1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.ReplicaSetSpec{
......@@ -188,6 +196,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"replicaset", "nginx", "env=prod"},
},
{
name: "test extensions.v1beta1 daemonset",
object: &extensionsv1beta1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: extensionsv1beta1.DaemonSetSpec{
......@@ -208,6 +217,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"daemonset", "nginx", "env=prod"},
},
{
name: "test appsv1beta2 daemonset",
object: &appsv1beta2.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.DaemonSetSpec{
......@@ -228,6 +238,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"daemonset", "nginx", "env=prod"},
},
{
name: "test appsv1 daemonset",
object: &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.DaemonSetSpec{
......@@ -248,6 +259,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"daemonset", "nginx", "env=prod"},
},
{
name: "test extensions.v1beta1 deployment",
object: &extensionsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: extensionsv1beta1.DeploymentSpec{
......@@ -268,6 +280,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"deployment", "nginx", "env=prod"},
},
{
name: "test appsv1bta1 deployment",
object: &appsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta1.DeploymentSpec{
......@@ -288,6 +301,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"deployment", "nginx", "env=prod"},
},
{
name: "test appsv1beta2n deployment",
object: &appsv1beta2.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.DeploymentSpec{
......@@ -308,6 +322,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"deployment", "nginx", "env=prod"},
},
{
name: "test appsv1 deployment",
object: &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.DeploymentSpec{
......@@ -328,6 +343,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"deployment", "nginx", "env=prod"},
},
{
name: "test appsv1beta1 statefulset",
object: &appsv1beta1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta1.StatefulSetSpec{
......@@ -348,6 +364,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"statefulset", "nginx", "env=prod"},
},
{
name: "test appsv1beta2 statefulset",
object: &appsv1beta2.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.StatefulSetSpec{
......@@ -368,6 +385,7 @@ func TestSetEnvRemote(t *testing.T) {
args: []string{"statefulset", "nginx", "env=prod"},
},
{
name: "test appsv1 statefulset",
object: &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.StatefulSetSpec{
......@@ -429,48 +447,52 @@ func TestSetEnvRemote(t *testing.T) {
},
}
for _, input := range inputs {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup]
tf := cmdtesting.NewTestFactory()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
ns := legacyscheme.Codecs
tf.Namespace = "test"
tf.Client = &fake.RESTClient{
GroupVersion: groupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
switch p, m := req.URL.Path, req.Method; {
case p == resourcePath && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
case p == resourcePath && m == http.MethodPatch:
stream, err := req.GetBody()
if err != nil {
return nil, err
}
bytes, err := ioutil.ReadAll(stream)
if err != nil {
return nil, err
t.Run(input.name, func(t *testing.T) {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup]
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
ns := legacyscheme.Codecs
tf.Namespace = "test"
tf.Client = &fake.RESTClient{
GroupVersion: groupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
switch p, m := req.URL.Path, req.Method; {
case p == resourcePath && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
case p == resourcePath && m == http.MethodPatch:
stream, err := req.GetBody()
if err != nil {
return nil, err
}
bytes, err := ioutil.ReadAll(stream)
if err != nil {
return nil, err
}
assert.Contains(t, string(bytes), `"value":`+`"`+"prod"+`"`, fmt.Sprintf("env not updated for %#v", input.object))
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
assert.Contains(t, string(bytes), `"value":`+`"`+"prod"+`"`, fmt.Sprintf("env not updated for %#v", input.object))
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()),
}
out := new(bytes.Buffer)
cmd := NewCmdEnv(tf, out, out, out)
cmd.SetOutput(out)
cmd.Flags().Set("output", "yaml")
opts := EnvOptions{
Out: out,
Local: false}
err := opts.Complete(tf, cmd, input.args)
assert.NoError(t, err)
err = opts.RunEnv(tf)
assert.NoError(t, err)
}),
VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()),
}
out := new(bytes.Buffer)
cmd := NewCmdEnv(tf, out, out, out)
cmd.SetOutput(out)
cmd.Flags().Set("output", "yaml")
opts := EnvOptions{
Out: out,
Local: false}
err := opts.Complete(tf, cmd, input.args)
assert.NoError(t, err)
err = opts.RunEnv(tf)
assert.NoError(t, err)
})
}
}
......@@ -46,6 +46,8 @@ import (
func TestImageLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
......@@ -149,6 +151,8 @@ func TestSetImageValidation(t *testing.T) {
func TestSetMultiResourcesImageLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
......@@ -190,12 +194,14 @@ func TestSetMultiResourcesImageLocal(t *testing.T) {
func TestSetImageRemote(t *testing.T) {
inputs := []struct {
name string
object runtime.Object
apiPrefix, apiGroup, apiVersion string
testAPIGroup string
args []string
}{
{
name: "set image extensionsv1beta1 ReplicaSet",
object: &extensionsv1beta1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: extensionsv1beta1.ReplicaSetSpec{
......@@ -216,6 +222,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"replicaset", "nginx", "*=thingy"},
},
{
name: "set image appsv1beta2 ReplicaSet",
object: &appsv1beta2.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.ReplicaSetSpec{
......@@ -236,6 +243,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"replicaset", "nginx", "*=thingy"},
},
{
name: "set image appsv1 ReplicaSet",
object: &appsv1.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.ReplicaSetSpec{
......@@ -256,6 +264,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"replicaset", "nginx", "*=thingy"},
},
{
name: "set image extensionsv1beta1 DaemonSet",
object: &extensionsv1beta1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: extensionsv1beta1.DaemonSetSpec{
......@@ -276,6 +285,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"daemonset", "nginx", "*=thingy"},
},
{
name: "set image appsv1beta2 DaemonSet",
object: &appsv1beta2.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.DaemonSetSpec{
......@@ -296,6 +306,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"daemonset", "nginx", "*=thingy"},
},
{
name: "set image appsv1 DaemonSet",
object: &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.DaemonSetSpec{
......@@ -316,6 +327,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"daemonset", "nginx", "*=thingy"},
},
{
name: "set image extensionsv1beta1 Deployment",
object: &extensionsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: extensionsv1beta1.DeploymentSpec{
......@@ -336,6 +348,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"deployment", "nginx", "*=thingy"},
},
{
name: "set image appsv1beta1 Deployment",
object: &appsv1beta1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta1.DeploymentSpec{
......@@ -356,6 +369,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"deployment", "nginx", "*=thingy"},
},
{
name: "set image appsv1beta2 Deployment",
object: &appsv1beta2.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.DeploymentSpec{
......@@ -376,6 +390,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"deployment", "nginx", "*=thingy"},
},
{
name: "set image appsv1 Deployment",
object: &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.DeploymentSpec{
......@@ -396,6 +411,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"deployment", "nginx", "*=thingy"},
},
{
name: "set image appsv1beta1 StatefulSet",
object: &appsv1beta1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta1.StatefulSetSpec{
......@@ -416,6 +432,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"statefulset", "nginx", "*=thingy"},
},
{
name: "set image appsv1beta2 StatefulSet",
object: &appsv1beta2.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1beta2.StatefulSetSpec{
......@@ -436,6 +453,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"statefulset", "nginx", "*=thingy"},
},
{
name: "set image appsv1 StatefulSet",
object: &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: appsv1.StatefulSetSpec{
......@@ -456,6 +474,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"statefulset", "nginx", "*=thingy"},
},
{
name: "set image batchv1 Job",
object: &batchv1.Job{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: batchv1.JobSpec{
......@@ -476,6 +495,7 @@ func TestSetImageRemote(t *testing.T) {
args: []string{"job", "nginx", "*=thingy"},
},
{
name: "set image v1.ReplicationController",
object: &v1.ReplicationController{
ObjectMeta: metav1.ObjectMeta{Name: "nginx"},
Spec: v1.ReplicationControllerSpec{
......@@ -497,48 +517,52 @@ func TestSetImageRemote(t *testing.T) {
},
}
for _, input := range inputs {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup]
tf := cmdtesting.NewTestFactory()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
ns := legacyscheme.Codecs
tf.Namespace = "test"
tf.Client = &fake.RESTClient{
GroupVersion: groupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
switch p, m := req.URL.Path, req.Method; {
case p == resourcePath && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
case p == resourcePath && m == http.MethodPatch:
stream, err := req.GetBody()
if err != nil {
return nil, err
}
bytes, err := ioutil.ReadAll(stream)
if err != nil {
return nil, err
t.Run(input.name, func(t *testing.T) {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup]
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
ns := legacyscheme.Codecs
tf.Namespace = "test"
tf.Client = &fake.RESTClient{
GroupVersion: groupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
switch p, m := req.URL.Path, req.Method; {
case p == resourcePath && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
case p == resourcePath && m == http.MethodPatch:
stream, err := req.GetBody()
if err != nil {
return nil, err
}
bytes, err := ioutil.ReadAll(stream)
if err != nil {
return nil, err
}
assert.Contains(t, string(bytes), `"image":`+`"`+"thingy"+`"`, fmt.Sprintf("image not updated for %#v", input.object))
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
assert.Contains(t, string(bytes), `"image":`+`"`+"thingy"+`"`, fmt.Sprintf("image not updated for %#v", input.object))
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()),
}
out := new(bytes.Buffer)
cmd := NewCmdImage(tf, out, out)
cmd.SetOutput(out)
cmd.Flags().Set("output", "yaml")
opts := ImageOptions{
Out: out,
Local: false}
err := opts.Complete(tf, cmd, input.args)
assert.NoError(t, err)
err = opts.Run()
assert.NoError(t, err)
}),
VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()),
}
out := new(bytes.Buffer)
cmd := NewCmdImage(tf, out, out)
cmd.SetOutput(out)
cmd.Flags().Set("output", "yaml")
opts := ImageOptions{
Out: out,
Local: false}
err := opts.Complete(tf, cmd, input.args)
assert.NoError(t, err)
err = opts.Run()
assert.NoError(t, err)
})
}
}
......@@ -46,6 +46,7 @@ import (
func TestResourcesLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
......@@ -90,6 +91,7 @@ func TestResourcesLocal(t *testing.T) {
func TestSetMultiResourcesLimitsLocal(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
......@@ -446,6 +448,7 @@ func TestSetResourcesRemote(t *testing.T) {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup]
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
ns := legacyscheme.Codecs
tf.Namespace = "test"
......
......@@ -317,6 +317,8 @@ func TestGetResourcesAndSelector(t *testing.T) {
func TestSelectorTest(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: ""},
......
......@@ -68,6 +68,8 @@ func TestSetServiceAccountLocal(t *testing.T) {
for i, input := range inputs {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
......@@ -98,6 +100,8 @@ func TestSetServiceAccountLocal(t *testing.T) {
func TestSetServiceAccountMultiLocal(t *testing.T) {
testapi.Default = testapi.Groups[""]
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: ""},
......@@ -310,77 +314,86 @@ func TestSetServiceAccountRemote(t *testing.T) {
},
}
for _, input := range inputs {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup]
tf := cmdtesting.NewTestFactory()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
ns := legacyscheme.Codecs
tf.Namespace = "test"
tf.Client = &fake.RESTClient{
GroupVersion: groupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
switch p, m := req.URL.Path, req.Method; {
case p == resourcePath && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
case p == resourcePath && m == http.MethodPatch:
stream, err := req.GetBody()
if err != nil {
return nil, err
}
bytes, err := ioutil.ReadAll(stream)
if err != nil {
return nil, err
t.Run(input.apiPrefix, func(t *testing.T) {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup]
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
ns := legacyscheme.Codecs
tf.Namespace = "test"
tf.Client = &fake.RESTClient{
GroupVersion: groupVersion,
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
switch p, m := req.URL.Path, req.Method; {
case p == resourcePath && m == http.MethodGet:
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
case p == resourcePath && m == http.MethodPatch:
stream, err := req.GetBody()
if err != nil {
return nil, err
}
bytes, err := ioutil.ReadAll(stream)
if err != nil {
return nil, err
}
assert.Contains(t, string(bytes), `"serviceAccountName":`+`"`+serviceAccount+`"`, fmt.Sprintf("serviceaccount not updated for %#v", input.object))
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "serviceaccount", req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
assert.Contains(t, string(bytes), `"serviceAccountName":`+`"`+serviceAccount+`"`, fmt.Sprintf("serviceaccount not updated for %#v", input.object))
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
default:
t.Errorf("%s: unexpected request: %s %#v\n%#v", "serviceaccount", req.Method, req.URL, req)
return nil, fmt.Errorf("unexpected request")
}
}),
VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()),
}
out := new(bytes.Buffer)
cmd := NewCmdServiceAccount(tf, out, out)
cmd.SetOutput(out)
cmd.Flags().Set("output", "yaml")
saConfig := serviceAccountConfig{
out: out,
local: false}
err := saConfig.Complete(tf, cmd, input.args)
assert.NoError(t, err)
err = saConfig.Run()
assert.NoError(t, err)
}),
VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()),
}
out := new(bytes.Buffer)
cmd := NewCmdServiceAccount(tf, out, out)
cmd.SetOutput(out)
cmd.Flags().Set("output", "yaml")
saConfig := serviceAccountConfig{
out: out,
local: false}
err := saConfig.Complete(tf, cmd, input.args)
assert.NoError(t, err)
err = saConfig.Run()
assert.NoError(t, err)
})
}
}
func TestServiceAccountValidation(t *testing.T) {
inputs := []struct {
name string
args []string
errorString string
}{
{args: []string{}, errorString: serviceAccountMissingErrString},
{args: []string{serviceAccount}, errorString: resourceMissingErrString},
{name: "test service account missing", args: []string{}, errorString: serviceAccountMissingErrString},
{name: "test service account resource missing", args: []string{serviceAccount}, errorString: resourceMissingErrString},
}
for _, input := range inputs {
tf := cmdtesting.NewTestFactory()
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
return nil, nil
}),
}
tf.Namespace = "test"
out := bytes.NewBuffer([]byte{})
cmd := NewCmdServiceAccount(tf, out, out)
cmd.SetOutput(out)
t.Run(input.name, func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
return nil, nil
}),
}
tf.Namespace = "test"
out := bytes.NewBuffer([]byte{})
cmd := NewCmdServiceAccount(tf, out, out)
cmd.SetOutput(out)
saConfig := &serviceAccountConfig{}
err := saConfig.Complete(tf, cmd, input.args)
assert.EqualError(t, err, input.errorString)
saConfig := &serviceAccountConfig{}
err := saConfig.Complete(tf, cmd, input.args)
assert.EqualError(t, err, input.errorString)
})
}
}
......
......@@ -29,6 +29,8 @@ import (
func TestValidate(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Namespace = "test"
tests := map[string]struct {
......
......@@ -236,102 +236,106 @@ func TestTaint(t *testing.T) {
}
for _, test := range tests {
oldNode, expectNewNode := generateNodeAndTaintedNode(test.oldTaints, test.newTaints)
new_node := &v1.Node{}
tainted := false
tf := cmdtesting.NewTestFactory()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
t.Run(test.description, func(t *testing.T) {
oldNode, expectNewNode := generateNodeAndTaintedNode(test.oldTaints, test.newTaints)
new_node := &v1.Node{}
tainted := false
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
m := &MyReq{req}
switch {
case m.isFor("GET", "/nodes"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, oldNode)}, nil
case m.isFor("GET", "/nodes/node-name"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, oldNode)}, nil
case m.isFor("PATCH", "/nodes/node-name"):
tainted = true
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
defer req.Body.Close()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
// apply the patch
oldJSON, err := runtime.Encode(codec, oldNode)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
appliedPatch, err := strategicpatch.StrategicMergePatch(oldJSON, data, &v1.Node{})
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
m := &MyReq{req}
switch {
case m.isFor("GET", "/nodes"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, oldNode)}, nil
case m.isFor("GET", "/nodes/node-name"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, oldNode)}, nil
case m.isFor("PATCH", "/nodes/node-name"):
tainted = true
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
defer req.Body.Close()
// decode the patch
if err := runtime.DecodeInto(codec, appliedPatch, new_node); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if !equalTaints(expectNewNode.Spec.Taints, new_node.Spec.Taints) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, expectNewNode.Spec.Taints, new_node.Spec.Taints)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, new_node)}, nil
case m.isFor("PUT", "/nodes/node-name"):
tainted = true
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
defer req.Body.Close()
if err := runtime.DecodeInto(codec, data, new_node); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if !equalTaints(expectNewNode.Spec.Taints, new_node.Spec.Taints) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, expectNewNode.Spec.Taints, new_node.Spec.Taints)
// apply the patch
oldJSON, err := runtime.Encode(codec, oldNode)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
appliedPatch, err := strategicpatch.StrategicMergePatch(oldJSON, data, &v1.Node{})
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
// decode the patch
if err := runtime.DecodeInto(codec, appliedPatch, new_node); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if !equalTaints(expectNewNode.Spec.Taints, new_node.Spec.Taints) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, expectNewNode.Spec.Taints, new_node.Spec.Taints)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, new_node)}, nil
case m.isFor("PUT", "/nodes/node-name"):
tainted = true
data, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
defer req.Body.Close()
if err := runtime.DecodeInto(codec, data, new_node); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err)
}
if !equalTaints(expectNewNode.Spec.Taints, new_node.Spec.Taints) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, expectNewNode.Spec.Taints, new_node.Spec.Taints)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, new_node)}, nil
default:
t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req)
return nil, nil
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, new_node)}, nil
default:
t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req)
return nil, nil
}
}),
}
tf.ClientConfigVal = defaultClientConfig()
}),
}
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdTaint(tf, buf)
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdTaint(tf, buf)
saw_fatal := false
func() {
defer func() {
// Recover from the panic below.
_ = recover()
// Restore cmdutil behavior
cmdutil.DefaultBehaviorOnFatal()
saw_fatal := false
func() {
defer func() {
// Recover from the panic below.
_ = recover()
// Restore cmdutil behavior
cmdutil.DefaultBehaviorOnFatal()
}()
cmdutil.BehaviorOnFatal(func(e string, code int) { saw_fatal = true; panic(e) })
cmd.SetArgs(test.args)
cmd.Execute()
}()
cmdutil.BehaviorOnFatal(func(e string, code int) { saw_fatal = true; panic(e) })
cmd.SetArgs(test.args)
cmd.Execute()
}()
if test.expectFatal {
if !saw_fatal {
t.Fatalf("%s: unexpected non-error", test.description)
if test.expectFatal {
if !saw_fatal {
t.Fatalf("%s: unexpected non-error", test.description)
}
}
}
if test.expectTaint {
if !tainted {
t.Fatalf("%s: node not tainted", test.description)
if test.expectTaint {
if !tainted {
t.Fatalf("%s: node not tainted", test.description)
}
}
}
if !test.expectTaint {
if tainted {
t.Fatalf("%s: unexpected taint", test.description)
if !test.expectTaint {
if tainted {
t.Fatalf("%s: unexpected taint", test.description)
}
}
}
})
}
}
......
......@@ -37,6 +37,8 @@ go_library(
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/rest/fake:go_default_library",
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
],
)
......
......@@ -17,8 +17,11 @@ limitations under the License.
package testing
import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"time"
......@@ -34,6 +37,8 @@ import (
"k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"k8s.io/kubernetes/pkg/api/legacyscheme"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
......@@ -240,14 +245,53 @@ type TestFactory struct {
ClientConfigVal *restclient.Config
CommandVal string
tempConfigFile *os.File
UnstructuredClientForMappingFunc func(mapping *meta.RESTMapping) (resource.RESTClient, error)
OpenAPISchemaFunc func() (openapi.Resources, error)
}
func NewTestFactory() *TestFactory {
// specify an optionalClientConfig to explicitly use in testing
// to avoid polluting an existing user config.
config, configFile := defaultFakeClientConfig()
return &TestFactory{
Factory: cmdutil.NewFactory(nil),
Factory: cmdutil.NewFactory(config),
tempConfigFile: configFile,
}
}
func (f *TestFactory) Cleanup() {
if f.tempConfigFile == nil {
return
}
os.Remove(f.tempConfigFile.Name())
}
func defaultFakeClientConfig() (clientcmd.ClientConfig, *os.File) {
loadingRules, tmpFile, err := newDefaultFakeClientConfigLoadingRules()
if err != nil {
panic(fmt.Sprintf("unable to create a fake client config: %v", err))
}
overrides := &clientcmd.ConfigOverrides{ClusterDefaults: clientcmdapi.Cluster{Server: "http://localhost:8080"}}
fallbackReader := bytes.NewBuffer([]byte{})
clientConfig := clientcmd.NewInteractiveDeferredLoadingClientConfig(loadingRules, overrides, fallbackReader)
return clientConfig, tmpFile
}
func newDefaultFakeClientConfigLoadingRules() (*clientcmd.ClientConfigLoadingRules, *os.File, error) {
tmpFile, err := ioutil.TempFile("", "cmdtests_temp")
if err != nil {
return nil, nil, err
}
return &clientcmd.ClientConfigLoadingRules{
Precedence: []string{tmpFile.Name()},
MigrationRules: map[string]string{},
}, tmpFile, nil
}
func (f *TestFactory) CategoryExpander() categories.CategoryExpander {
......
......@@ -50,6 +50,8 @@ func TestTopNodeAllMetrics(t *testing.T) {
expectedNodePath := fmt.Sprintf("/%s/%s/nodes", apiPrefix, apiVersion)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
......@@ -101,6 +103,8 @@ func TestTopNodeAllMetricsCustomDefaults(t *testing.T) {
expectedNodePath := fmt.Sprintf("/%s/%s/nodes", apiPrefix, apiVersion)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
......@@ -162,6 +166,8 @@ func TestTopNodeWithNameMetrics(t *testing.T) {
expectedNodePath := fmt.Sprintf("/%s/%s/nodes/%s", apiPrefix, apiVersion, expectedMetrics.Name)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
......@@ -227,6 +233,8 @@ func TestTopNodeWithLabelSelectorMetrics(t *testing.T) {
expectedNodePath := fmt.Sprintf("/%s/%s/nodes", apiPrefix, apiVersion)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
......@@ -280,6 +288,8 @@ func TestTopNodeAllMetricsFromMetricsServer(t *testing.T) {
expectedNodePath := fmt.Sprintf("/%s/%s/nodes", apiPrefix, apiVersion)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
......@@ -344,6 +354,8 @@ func TestTopNodeWithNameMetricsFromMetricsServer(t *testing.T) {
expectedNodePath := fmt.Sprintf("/%s/%s/nodes/%s", apiPrefix, apiVersion, expectedMetrics.Name)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
......@@ -418,6 +430,8 @@ func TestTopNodeWithLabelSelectorMetricsFromMetricsServer(t *testing.T) {
expectedNodePath := fmt.Sprintf("/%s/%s/nodes", apiPrefix, apiVersion)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
ns := legacyscheme.Codecs
......
......@@ -134,90 +134,94 @@ func TestTopPod(t *testing.T) {
}
initTestErrorHandler(t)
for _, testCase := range testCases {
t.Logf("Running test case: %s", testCase.name)
metricsList := testPodMetricsData()
var expectedMetrics []metricsv1alpha1api.PodMetrics
var expectedContainerNames, nonExpectedMetricsNames []string
for n, m := range metricsList {
if n < len(testCase.namespaces) {
m.Namespace = testCase.namespaces[n]
expectedMetrics = append(expectedMetrics, m)
for _, c := range m.Containers {
expectedContainerNames = append(expectedContainerNames, c.Name)
t.Run(testCase.name, func(t *testing.T) {
t.Logf("Running test case: %s", testCase.name)
metricsList := testPodMetricsData()
var expectedMetrics []metricsv1alpha1api.PodMetrics
var expectedContainerNames, nonExpectedMetricsNames []string
for n, m := range metricsList {
if n < len(testCase.namespaces) {
m.Namespace = testCase.namespaces[n]
expectedMetrics = append(expectedMetrics, m)
for _, c := range m.Containers {
expectedContainerNames = append(expectedContainerNames, c.Name)
}
} else {
nonExpectedMetricsNames = append(nonExpectedMetricsNames, m.Name)
}
} else {
nonExpectedMetricsNames = append(nonExpectedMetricsNames, m.Name)
}
}
var response interface{}
if len(expectedMetrics) == 1 {
response = expectedMetrics[0]
} else {
response = metricsv1alpha1api.PodMetricsList{
ListMeta: metav1.ListMeta{
ResourceVersion: "2",
},
Items: expectedMetrics,
var response interface{}
if len(expectedMetrics) == 1 {
response = expectedMetrics[0]
} else {
response = metricsv1alpha1api.PodMetricsList{
ListMeta: metav1.ListMeta{
ResourceVersion: "2",
},
Items: expectedMetrics,
}
}
}
tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m, q := req.URL.Path, req.Method, req.URL.RawQuery; {
case p == "/api":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apibody)))}, nil
case p == "/apis":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apisbody)))}, nil
case p == testCase.expectedPath && m == "GET" && (testCase.expectedQuery == "" || q == testCase.expectedQuery):
body, err := marshallBody(response)
if err != nil {
t.Errorf("%s: unexpected error: %v", testCase.name, err)
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m, q := req.URL.Path, req.Method, req.URL.RawQuery; {
case p == "/api":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apibody)))}, nil
case p == "/apis":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apisbody)))}, nil
case p == testCase.expectedPath && m == "GET" && (testCase.expectedQuery == "" || q == testCase.expectedQuery):
body, err := marshallBody(response)
if err != nil {
t.Errorf("%s: unexpected error: %v", testCase.name, err)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
t.Fatalf("%s: unexpected request: %#v\nGot URL: %#v\nExpected path: %#v\nExpected query: %#v",
testCase.name, req, req.URL, testCase.expectedPath, testCase.expectedQuery)
return nil, nil
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
t.Fatalf("%s: unexpected request: %#v\nGot URL: %#v\nExpected path: %#v\nExpected query: %#v",
testCase.name, req, req.URL, testCase.expectedPath, testCase.expectedQuery)
return nil, nil
}
}),
}
tf.Namespace = testNS
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
}),
}
tf.Namespace = testNS
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdTopPod(tf, nil, buf)
for name, value := range testCase.flags {
cmd.Flags().Set(name, value)
}
cmd.Run(cmd, testCase.args)
// Check the presence of pod names&namespaces/container names in the output.
result := buf.String()
if testCase.containers {
for _, containerName := range expectedContainerNames {
if !strings.Contains(result, containerName) {
t.Errorf("%s: missing metrics for container %s: \n%s", testCase.name, containerName, result)
}
cmd := NewCmdTopPod(tf, nil, buf)
for name, value := range testCase.flags {
cmd.Flags().Set(name, value)
}
}
for _, m := range expectedMetrics {
if !strings.Contains(result, m.Name) {
t.Errorf("%s: missing metrics for %s: \n%s", testCase.name, m.Name, result)
cmd.Run(cmd, testCase.args)
// Check the presence of pod names&namespaces/container names in the output.
result := buf.String()
if testCase.containers {
for _, containerName := range expectedContainerNames {
if !strings.Contains(result, containerName) {
t.Errorf("%s: missing metrics for container %s: \n%s", testCase.name, containerName, result)
}
}
}
if testCase.listsNamespaces && !strings.Contains(result, m.Namespace) {
t.Errorf("%s: missing metrics for %s/%s: \n%s", testCase.name, m.Namespace, m.Name, result)
for _, m := range expectedMetrics {
if !strings.Contains(result, m.Name) {
t.Errorf("%s: missing metrics for %s: \n%s", testCase.name, m.Name, result)
}
if testCase.listsNamespaces && !strings.Contains(result, m.Namespace) {
t.Errorf("%s: missing metrics for %s/%s: \n%s", testCase.name, m.Namespace, m.Name, result)
}
}
}
for _, name := range nonExpectedMetricsNames {
if strings.Contains(result, name) {
t.Errorf("%s: unexpected metrics for %s: \n%s", testCase.name, name, result)
for _, name := range nonExpectedMetricsNames {
if strings.Contains(result, name) {
t.Errorf("%s: unexpected metrics for %s: \n%s", testCase.name, name, result)
}
}
}
})
}
}
......@@ -305,6 +309,8 @@ func TestTopPodWithMetricsServer(t *testing.T) {
}
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
......@@ -471,98 +477,102 @@ func TestTopPodCustomDefaults(t *testing.T) {
}
initTestErrorHandler(t)
for _, testCase := range testCases {
t.Logf("Running test case: %s", testCase.name)
metricsList := testPodMetricsData()
var expectedMetrics []metricsv1alpha1api.PodMetrics
var expectedContainerNames, nonExpectedMetricsNames []string
for n, m := range metricsList {
if n < len(testCase.namespaces) {
m.Namespace = testCase.namespaces[n]
expectedMetrics = append(expectedMetrics, m)
for _, c := range m.Containers {
expectedContainerNames = append(expectedContainerNames, c.Name)
t.Run(testCase.name, func(t *testing.T) {
t.Logf("Running test case: %s", testCase.name)
metricsList := testPodMetricsData()
var expectedMetrics []metricsv1alpha1api.PodMetrics
var expectedContainerNames, nonExpectedMetricsNames []string
for n, m := range metricsList {
if n < len(testCase.namespaces) {
m.Namespace = testCase.namespaces[n]
expectedMetrics = append(expectedMetrics, m)
for _, c := range m.Containers {
expectedContainerNames = append(expectedContainerNames, c.Name)
}
} else {
nonExpectedMetricsNames = append(nonExpectedMetricsNames, m.Name)
}
}
var response interface{}
if len(expectedMetrics) == 1 {
response = expectedMetrics[0]
} else {
nonExpectedMetricsNames = append(nonExpectedMetricsNames, m.Name)
response = metricsv1alpha1api.PodMetricsList{
ListMeta: metav1.ListMeta{
ResourceVersion: "2",
},
Items: expectedMetrics,
}
}
}
var response interface{}
if len(expectedMetrics) == 1 {
response = expectedMetrics[0]
} else {
response = metricsv1alpha1api.PodMetricsList{
ListMeta: metav1.ListMeta{
ResourceVersion: "2",
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m, q := req.URL.Path, req.Method, req.URL.RawQuery; {
case p == "/api":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apibody)))}, nil
case p == "/apis":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apisbody)))}, nil
case p == testCase.expectedPath && m == "GET" && (testCase.expectedQuery == "" || q == testCase.expectedQuery):
body, err := marshallBody(response)
if err != nil {
t.Errorf("%s: unexpected error: %v", testCase.name, err)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
t.Fatalf("%s: unexpected request: %#v\nGot URL: %#v\nExpected path: %#v\nExpected query: %#v",
testCase.name, req, req.URL, testCase.expectedPath, testCase.expectedQuery)
return nil, nil
}
}),
}
tf.Namespace = testNS
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
opts := &TopPodOptions{
HeapsterOptions: HeapsterTopOptions{
Namespace: "custom-namespace",
Scheme: "https",
Service: "custom-heapster-service",
},
Items: expectedMetrics,
DiscoveryClient: &fakeDiscovery{},
}
}
cmd := NewCmdTopPod(tf, opts, buf)
for name, value := range testCase.flags {
cmd.Flags().Set(name, value)
}
cmd.Run(cmd, testCase.args)
tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m, q := req.URL.Path, req.Method, req.URL.RawQuery; {
case p == "/api":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apibody)))}, nil
case p == "/apis":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader([]byte(apisbody)))}, nil
case p == testCase.expectedPath && m == "GET" && (testCase.expectedQuery == "" || q == testCase.expectedQuery):
body, err := marshallBody(response)
if err != nil {
t.Errorf("%s: unexpected error: %v", testCase.name, err)
// Check the presence of pod names&namespaces/container names in the output.
result := buf.String()
if testCase.containers {
for _, containerName := range expectedContainerNames {
if !strings.Contains(result, containerName) {
t.Errorf("%s: missing metrics for container %s: \n%s", testCase.name, containerName, result)
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: body}, nil
default:
t.Fatalf("%s: unexpected request: %#v\nGot URL: %#v\nExpected path: %#v\nExpected query: %#v",
testCase.name, req, req.URL, testCase.expectedPath, testCase.expectedQuery)
return nil, nil
}
}),
}
tf.Namespace = testNS
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
opts := &TopPodOptions{
HeapsterOptions: HeapsterTopOptions{
Namespace: "custom-namespace",
Scheme: "https",
Service: "custom-heapster-service",
},
DiscoveryClient: &fakeDiscovery{},
}
cmd := NewCmdTopPod(tf, opts, buf)
for name, value := range testCase.flags {
cmd.Flags().Set(name, value)
}
cmd.Run(cmd, testCase.args)
// Check the presence of pod names&namespaces/container names in the output.
result := buf.String()
if testCase.containers {
for _, containerName := range expectedContainerNames {
if !strings.Contains(result, containerName) {
t.Errorf("%s: missing metrics for container %s: \n%s", testCase.name, containerName, result)
}
}
}
for _, m := range expectedMetrics {
if !strings.Contains(result, m.Name) {
t.Errorf("%s: missing metrics for %s: \n%s", testCase.name, m.Name, result)
}
if testCase.listsNamespaces && !strings.Contains(result, m.Namespace) {
t.Errorf("%s: missing metrics for %s/%s: \n%s", testCase.name, m.Namespace, m.Name, result)
for _, m := range expectedMetrics {
if !strings.Contains(result, m.Name) {
t.Errorf("%s: missing metrics for %s: \n%s", testCase.name, m.Name, result)
}
if testCase.listsNamespaces && !strings.Contains(result, m.Namespace) {
t.Errorf("%s: missing metrics for %s/%s: \n%s", testCase.name, m.Namespace, m.Name, result)
}
}
}
for _, name := range nonExpectedMetricsNames {
if strings.Contains(result, name) {
t.Errorf("%s: unexpected metrics for %s: \n%s", testCase.name, name, result)
for _, name := range nonExpectedMetricsNames {
if strings.Contains(result, name) {
t.Errorf("%s: unexpected metrics for %s: \n%s", testCase.name, name, result)
}
}
}
})
}
}
......
......@@ -44,6 +44,8 @@ func TestTopSubcommandsExist(t *testing.T) {
initTestErrorHandler(t)
f := cmdtesting.NewTestFactory()
defer f.Cleanup()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdTop(f, buf, buf)
......
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