diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_restart.go b/staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_restart.go index a7cc5bc762b..8a803a19b2d 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_restart.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_restart.go @@ -18,7 +18,6 @@ package rollout import ( "fmt" - "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/types" utilerrors "k8s.io/apimachinery/pkg/util/errors" @@ -183,7 +182,8 @@ func (o RestartOptions) RunRestart() error { } if string(patch.Patch) == "{}" || len(patch.Patch) == 0 { - allErrs = append(allErrs, fmt.Errorf("failed to create patch for %v: empty patch", info.Name)) + allErrs = append(allErrs, fmt.Errorf("failed to create patch for %v: if restart has already been triggered within the past second, please wait before attempting to trigger another", info.Name)) + continue } obj, err := resource.NewHelper(info.Client, info.Mapping). diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_restart_test.go b/staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_restart_test.go index 5dc47d21a8f..504f0fc97f1 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_restart_test.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_restart_test.go @@ -23,6 +23,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" + appsv1 "k8s.io/api/apps/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -70,6 +72,56 @@ func TestRolloutRestartOne(t *testing.T) { } } +func TestRolloutRestartError(t *testing.T) { + deploymentName := "deployment/nginx-deployment" + ns := scheme.Codecs.WithoutConversion() + tf := cmdtesting.NewTestFactory().WithNamespace("test") + + info, _ := runtime.SerializerInfoForMediaType(ns.SupportedMediaTypes(), runtime.ContentTypeJSON) + encoder := ns.EncoderForVersion(info.Serializer, rolloutRestartGroupVersionEncoder) + tf.Client = &RolloutRestartRESTClient{ + RESTClient: &fake.RESTClient{ + GroupVersion: rolloutRestartGroupVersionEncoder, + NegotiatedSerializer: ns, + Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { + switch p, m := req.URL.Path, req.Method; { + case p == "/namespaces/test/deployments/nginx-deployment" && (m == "GET" || m == "PATCH"): + responseDeployment := &appsv1.Deployment{} + responseDeployment.Name = deploymentName + body := io.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(encoder, responseDeployment)))) + return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: body}, nil + default: + t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) + return nil, nil + } + }), + }, + } + + streams, _, bufOut, _ := genericclioptions.NewTestIOStreams() + opt := NewRolloutRestartOptions(streams) + err := opt.Complete(tf, nil, []string{deploymentName}) + assert.NoError(t, err) + err = opt.Validate() + assert.NoError(t, err) + opt.Restarter = func(obj runtime.Object) ([]byte, error) { + return runtime.Encode(scheme.Codecs.LegacyCodec(appsv1.SchemeGroupVersion), obj) + } + + expectedErr := "failed to create patch for nginx-deployment: if restart has already been triggered within the past second, please wait before attempting to trigger another" + err = opt.RunRestart() + if err == nil { + t.Errorf("error expected but not fired") + } + if err.Error() != expectedErr { + t.Errorf("unexpected error fired %v", err) + } + + if bufOut.String() != "" { + t.Errorf("unexpected message") + } +} + // Tests that giving selectors with no matching objects shows an error func TestRolloutRestartSelectorNone(t *testing.T) { labelSelector := "app=test"