From 9bb7fd2c1374c66484d4e3804b932d214067188e Mon Sep 17 00:00:00 2001 From: Will Tomlin <76996781+witomlin@users.noreply.github.com> Date: Wed, 31 Jan 2024 13:25:04 +0000 Subject: [PATCH] Remove use of github.com/pkg/errors (#4) Remove use of github.com/pkg/errors --- CHANGELOG.md | 16 +++++++ README.md | 3 +- .../container-startup-autoscaler/CHANGELOG.md | 9 ++++ .../container-startup-autoscaler/Chart.yaml | 4 +- cmd/container-startup-autoscaler/main.go | 14 +++--- go.mod | 2 +- .../stacktracer.go => common/error.go} | 12 +++-- internal/common/error_test.go | 48 +++++++++++++++++++ internal/context/helper.go | 2 +- internal/controller/controller.go | 8 ++-- internal/controller/controller_test.go | 2 +- internal/controller/reconciler.go | 13 ++--- internal/controller/reconciler_test.go | 2 +- internal/logging/keys.go | 1 - internal/logging/log.go | 20 ++------ internal/logging/log_test.go | 32 ++----------- internal/pod/containerkubehelper.go | 29 ++++++----- internal/pod/error.go | 15 ++---- internal/pod/error_test.go | 33 +++++-------- internal/pod/kubehelper.go | 24 +++++----- internal/pod/kubehelper_test.go | 7 +-- internal/pod/podcommon/stateconst.go | 5 +- internal/pod/podcommon/statusannotation.go | 3 +- internal/pod/podcommon/statusconst.go | 5 +- internal/pod/podtest/container.go | 3 +- internal/pod/podtest/pod.go | 3 +- internal/pod/podtest/podinterceptor.go | 2 +- internal/pod/retry.go | 2 +- internal/pod/scaleconfig.go | 40 ++++++++-------- internal/pod/scaleconfig_test.go | 2 +- internal/pod/status.go | 8 ++-- internal/pod/targetcontaineraction.go | 26 +++++----- internal/pod/targetcontaineraction_test.go | 2 +- internal/pod/targetcontainerstate.go | 39 +++++++-------- internal/pod/targetcontainerstate_test.go | 3 +- internal/pod/validation_test.go | 4 +- internal/retry/retry_test.go | 2 +- test/integration/command.go | 4 +- test/integration/csa.go | 6 +-- test/integration/integration_test.go | 2 +- test/integration/kind.go | 8 ++-- test/integration/kube.go | 3 +- 42 files changed, 251 insertions(+), 217 deletions(-) rename internal/{logging/stacktracer.go => common/error.go} (64%) create mode 100644 internal/common/error_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 82286bf..f2d0a31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,3 +17,19 @@ | 1.29 | ✔️ | Alpha | | 1.28 | ✔️ | Alpha | | 1.27 | ❌ | Alpha | + +## 0.2.0 +2024-02-01 + +### Removed +- https://github.com/pkg/errors in favor of the `errors` package from the Go standard library. + +### Helm Chart +[1.1.0](charts/container-startup-autoscaler/CHANGELOG.md#110) + +### Kubernetes Compatibility +| Kube Version | Compatible? | `In-place Update of Pod Resources` Maturity | +|:------------:|:-----------:|:-------------------------------------------:| +| 1.29 | ✔️ | Alpha | +| 1.28 | ✔️ | Alpha | +| 1.27 | ❌ | Alpha | diff --git a/README.md b/README.md index 38ff267..c91bfc0 100644 --- a/README.md +++ b/README.md @@ -331,8 +331,7 @@ Each message includes a number of keys that originate from controller-runtime an - `targetname`: the name of the container to target. - `targetstates`: the states of the target container, per [status](#status). -Regardless of configured logging verbosity, `error`-level messages are always displayed and additionally include a -stack trace key (`stacktrace`), if available. +Regardless of configured logging verbosity, `error`-level messages are always displayed. ## Metrics Additional CSA-specific metrics are registered to the Prometheus registry exposed by controller-runtime and exposed diff --git a/charts/container-startup-autoscaler/CHANGELOG.md b/charts/container-startup-autoscaler/CHANGELOG.md index 211e968..1e95f4a 100644 --- a/charts/container-startup-autoscaler/CHANGELOG.md +++ b/charts/container-startup-autoscaler/CHANGELOG.md @@ -10,3 +10,12 @@ ### CSA Version [0.1.0](../../CHANGELOG.md#010) + +## 1.1.0 +2024-02-01 + +### Changed +- CSA version only. + +### CSA Version +[0.2.0](../../CHANGELOG.md#020) \ No newline at end of file diff --git a/charts/container-startup-autoscaler/Chart.yaml b/charts/container-startup-autoscaler/Chart.yaml index fd6e12e..50da045 100644 --- a/charts/container-startup-autoscaler/Chart.yaml +++ b/charts/container-startup-autoscaler/Chart.yaml @@ -3,8 +3,8 @@ name: container-startup-autoscaler description: > container-startup-autoscaler is a Kubernetes controller that modifies the CPU and/or memory resources of containers depending on whether they're starting up. -version: 1.0.0 -appVersion: "0.1.0" +version: 1.1.0 +appVersion: "0.2.0" home: https://github.com/ExpediaGroup/container-startup-autoscaler/README.md sources: - https://github.com/ExpediaGroup/container-startup-autoscaler diff --git a/cmd/container-startup-autoscaler/main.go b/cmd/container-startup-autoscaler/main.go index 8418d8e..16d0dfa 100644 --- a/cmd/container-startup-autoscaler/main.go +++ b/cmd/container-startup-autoscaler/main.go @@ -19,11 +19,11 @@ package main import ( "os" + "github.com/ExpediaGroup/container-startup-autoscaler/internal/common" "github.com/ExpediaGroup/container-startup-autoscaler/internal/controller" "github.com/ExpediaGroup/container-startup-autoscaler/internal/controller/controllercommon" "github.com/ExpediaGroup/container-startup-autoscaler/internal/logging" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" - "github.com/pkg/errors" "github.com/spf13/cobra" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/labels" @@ -94,29 +94,29 @@ func run(_ *cobra.Command, _ []string) { // Uses KUBECONFIG env var if set, otherwise tries in-cluster config. restConfig, err := config.GetConfig() if err != nil { - logging.Fatale(nil, errors.Wrap(err, "unable to get rest config")) + logging.Fatale(nil, common.WrapErrorf(err, "unable to get rest config")) } runtimeManager, err := manager.New(restConfig, options) if err != nil { - logging.Fatale(nil, errors.Wrap(err, "unable to create controller-runtime manager")) + logging.Fatale(nil, common.WrapErrorf(err, "unable to create controller-runtime manager")) } if err = runtimeManager.AddHealthzCheck("liveness", healthz.Ping); err != nil { - logging.Fatale(nil, errors.Wrap(err, "unable to add healthz check")) + logging.Fatale(nil, common.WrapErrorf(err, "unable to add healthz check")) } csaController, err := controller.NewController(controllerConfig, runtimeManager) if err != nil { - logging.Fatale(nil, errors.Wrap(err, "unable to create controller")) + logging.Fatale(nil, common.WrapErrorf(err, "unable to create controller")) } if err = csaController.Initialize(); err != nil { - logging.Fatale(nil, errors.Wrap(err, "unable to initialize controller")) + logging.Fatale(nil, common.WrapErrorf(err, "unable to initialize controller")) } // Blocks. if err = runtimeManager.Start(signals.SetupSignalHandler()); err != nil { - logging.Fatale(nil, errors.Wrap(err, "unable to start controller-runtime manager")) + logging.Fatale(nil, common.WrapErrorf(err, "unable to start controller-runtime manager")) } } diff --git a/go.mod b/go.mod index 88d1698..16c4701 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,6 @@ require ( github.com/go-logr/zerologr v1.2.3 github.com/google/uuid v1.4.0 github.com/orcaman/concurrent-map/v2 v2.0.1 - github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.17.0 github.com/rs/zerolog v1.31.0 github.com/spf13/cobra v1.7.0 @@ -50,6 +49,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.45.0 // indirect diff --git a/internal/logging/stacktracer.go b/internal/common/error.go similarity index 64% rename from internal/logging/stacktracer.go rename to internal/common/error.go index 6b5142b..70ec237 100644 --- a/internal/logging/stacktracer.go +++ b/internal/common/error.go @@ -14,11 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -package logging +package common -import "github.com/pkg/errors" +import "fmt" -// stackTracer is implemented within errors that include a stack trace. -type stackTracer interface { - StackTrace() errors.StackTrace +// WrapErrorf returns an error with the supplied format that wraps err. The supplied format is appended with ': %w', +// with %w as err. +func WrapErrorf(err error, format string, a ...any) error { + wrapFormat := fmt.Sprintf("%s: %%w", format) + return fmt.Errorf(wrapFormat, append(a, err)...) } diff --git a/internal/common/error_test.go b/internal/common/error_test.go new file mode 100644 index 0000000..7eb9f14 --- /dev/null +++ b/internal/common/error_test.go @@ -0,0 +1,48 @@ +/* +Copyright 2024 Expedia Group, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestWrapErrorf(t *testing.T) { + t.Run("WithFormatString", func(t *testing.T) { + err := WrapErrorf(errors.New("non-wrapped err message"), "format (%s)", "test") + assert.Equal(t, "format (test): non-wrapped err message", err.Error()) + }) + + t.Run("WithoutFormatString", func(t *testing.T) { + err := WrapErrorf(errors.New("non-wrapped err message"), "format") + assert.Equal(t, "format: non-wrapped err message", err.Error()) + }) + + t.Run("ChainWithFormatString", func(t *testing.T) { + errInner := WrapErrorf(errors.New("non-wrapped err message"), "errInner format (%s)", "errInner test") + errOuter := WrapErrorf(errInner, "errOuter format (%s)", "errOuter test") + assert.Equal(t, "errOuter format (errOuter test): errInner format (errInner test): non-wrapped err message", errOuter.Error()) + }) + + t.Run("ChainWithoutFormatString", func(t *testing.T) { + errInner := WrapErrorf(errors.New("non-wrapped err message"), "errInner format") + errOuter := WrapErrorf(errInner, "errOuter format") + assert.Equal(t, "errOuter format: errInner format: non-wrapped err message", errOuter.Error()) + }) +} diff --git a/internal/context/helper.go b/internal/context/helper.go index f82d2bc..b63ba38 100644 --- a/internal/context/helper.go +++ b/internal/context/helper.go @@ -18,10 +18,10 @@ package context import ( "context" + "errors" "github.com/ExpediaGroup/container-startup-autoscaler/internal/context/contextcommon" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" - "github.com/pkg/errors" ) // WithStandardRetryAttempts adds or replaces contextcommon.KeyStandardRetryAttempts to/in ctx. diff --git a/internal/controller/controller.go b/internal/controller/controller.go index c5a3c68..8125cac 100644 --- a/internal/controller/controller.go +++ b/internal/controller/controller.go @@ -17,12 +17,14 @@ limitations under the License. package controller import ( + "errors" + + "github.com/ExpediaGroup/container-startup-autoscaler/internal/common" "github.com/ExpediaGroup/container-startup-autoscaler/internal/controller/controllercommon" "github.com/ExpediaGroup/container-startup-autoscaler/internal/logging" csametrics "github.com/ExpediaGroup/container-startup-autoscaler/internal/metrics" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod" "github.com/go-logr/logr" - "github.com/pkg/errors" "k8s.io/api/core/v1" runtimecontroller "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/handler" @@ -97,7 +99,7 @@ func (c *controller) Initialize(runtimeController ...runtimecontroller.Controlle }, ) if err != nil { - return errors.Wrap(err, "unable to create controller-runtime controller") + return common.WrapErrorf(err, "unable to create controller-runtime controller") } } else { actualRuntimeController = runtimeController[0] @@ -114,7 +116,7 @@ func (c *controller) Initialize(runtimeController ...runtimecontroller.Controlle GenericFunc: PredicateGenericFunc, }, ); err != nil { - return errors.Wrap(err, "unable to watch pods") + return common.WrapErrorf(err, "unable to watch pods") } csametrics.RegisterAllMetrics(metrics.Registry, Name) diff --git a/internal/controller/controller_test.go b/internal/controller/controller_test.go index 31b1ecc..e0ec49d 100644 --- a/internal/controller/controller_test.go +++ b/internal/controller/controller_test.go @@ -18,12 +18,12 @@ package controller import ( "context" + "errors" "net/http" "testing" "github.com/ExpediaGroup/container-startup-autoscaler/internal/controller/controllercommon" "github.com/go-logr/logr" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "k8s.io/apimachinery/pkg/api/meta" diff --git a/internal/controller/reconciler.go b/internal/controller/reconciler.go index 04f4691..6061a04 100644 --- a/internal/controller/reconciler.go +++ b/internal/controller/reconciler.go @@ -19,8 +19,10 @@ package controller import ( "context" "encoding/json" + "errors" "sync" + "github.com/ExpediaGroup/container-startup-autoscaler/internal/common" ccontext "github.com/ExpediaGroup/container-startup-autoscaler/internal/context" "github.com/ExpediaGroup/container-startup-autoscaler/internal/controller/controllercommon" "github.com/ExpediaGroup/container-startup-autoscaler/internal/logging" @@ -28,7 +30,6 @@ import ( "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" cmap "github.com/orcaman/concurrent-map/v2" - "github.com/pkg/errors" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) @@ -88,7 +89,7 @@ func (r *containerStartupAutoscalerReconciler) Reconcile( // Reconcilation will still operate correctly in this case as current conditions are always examined. podExists, kubePod, err := r.pod.KubeHelper.Get(ctx, request.NamespacedName) if err != nil { - wrappedErr := errors.Wrap(err, "unable to get pod (will requeue)") + wrappedErr := common.WrapErrorf(err, "unable to get pod (will requeue)") logging.Errore(ctx, wrappedErr) reconciler.FailureUnableToGetPod().Inc() return reconcile.Result{RequeueAfter: r.controllerConfig.RequeueDurationSecsDuration()}, nil @@ -106,7 +107,7 @@ func (r *containerStartupAutoscalerReconciler) Reconcile( var podJson []byte podJson, err = json.Marshal(kubePod) if err != nil { - logging.Errore(ctx, errors.Wrap(err, "unable to marshal pod to json for trace logging")) + logging.Errore(ctx, common.WrapErrorf(err, "unable to marshal pod to json for trace logging")) } else { logging.Infof(ctx, logging.VTrace, "reconciling pod: %s", string(podJson)) } @@ -121,7 +122,7 @@ func (r *containerStartupAutoscalerReconciler) Reconcile( } err = r.pod.Validation.Validate(ctx, kubePod, config, afterScaleConfigPopulatedFunc) if err != nil { - wrappedErr := errors.Wrap(err, "unable to validate pod (won't requeue)") + wrappedErr := common.WrapErrorf(err, "unable to validate pod (won't requeue)") logging.Errore(ctx, wrappedErr) reconciler.FailureValidation().Inc() return reconcile.Result{}, reconcile.TerminalError(wrappedErr) @@ -130,7 +131,7 @@ func (r *containerStartupAutoscalerReconciler) Reconcile( // Determine target container states. states, err := r.pod.TargetContainerState.States(ctx, kubePod, config) if err != nil { - wrappedErr := errors.Wrap(err, "unable to determine target container states (won't requeue)") + wrappedErr := common.WrapErrorf(err, "unable to determine target container states (won't requeue)") logging.Errore(ctx, wrappedErr) reconciler.FailureStatesDetermination().Inc() return reconcile.Result{}, reconcile.TerminalError(wrappedErr) @@ -140,7 +141,7 @@ func (r *containerStartupAutoscalerReconciler) Reconcile( // Execute action for determined target container states. err = r.pod.TargetContainerAction.Execute(ctx, states, kubePod, config) if err != nil { - wrappedErr := errors.Wrap(err, "unable to action target container states (won't requeue)") + wrappedErr := common.WrapErrorf(err, "unable to action target container states (won't requeue)") logging.Errore(ctx, wrappedErr) reconciler.FailureStatesAction().Inc() return reconcile.Result{}, reconcile.TerminalError(wrappedErr) diff --git a/internal/controller/reconciler_test.go b/internal/controller/reconciler_test.go index 41c0b15..b454fdc 100644 --- a/internal/controller/reconciler_test.go +++ b/internal/controller/reconciler_test.go @@ -18,6 +18,7 @@ package controller import ( "bytes" + "errors" "testing" "time" @@ -28,7 +29,6 @@ import ( "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podtest" cmap "github.com/orcaman/concurrent-map/v2" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" v1 "k8s.io/api/core/v1" diff --git a/internal/logging/keys.go b/internal/logging/keys.go index 3eb0312..77dac23 100644 --- a/internal/logging/keys.go +++ b/internal/logging/keys.go @@ -19,5 +19,4 @@ package logging const ( KeyTargetContainerName = "targetname" KeyTargetContainerStates = "targetstates" - KeyStackTrace = "stacktrace" ) diff --git a/internal/logging/log.go b/internal/logging/log.go index 71073bd..f226b12 100644 --- a/internal/logging/log.go +++ b/internal/logging/log.go @@ -18,6 +18,7 @@ package logging import ( "context" + "errors" "fmt" "io" "os" @@ -27,9 +28,7 @@ import ( "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" "github.com/go-logr/logr" "github.com/go-logr/zerologr" - "github.com/pkg/errors" "github.com/rs/zerolog" - "github.com/rs/zerolog/pkgerrors" "sigs.k8s.io/controller-runtime/pkg/log" ) @@ -70,7 +69,6 @@ func Init(w io.Writer, v V, addCaller bool) { // configureLogger actually configures the logger with the supplied settings. func configureLogger(w io.Writer, v V, addCaller bool) { zerolog.TimeFieldFormat = zerolog.TimeFormatUnixMs - zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack zerologr.SetMaxV(int(v)) // See https://github.com/go-logr/zerologr#implementation-details. zerologr.VerbosityFieldName = "" @@ -92,7 +90,7 @@ func Errore(ctx context.Context, err error) { // Errorf logs err with a formatted message. func Errorf(ctx context.Context, err error, format string, args ...any) { validateFormat(format) - configuredLogger(ctx, err).Error(err, buildMessage(format, args, false)) + configuredLogger(ctx).Error(err, buildMessage(format, args, false)) } // Fatale logs err and exits with a non-0 return code. The resulting message is the err's message. @@ -103,7 +101,7 @@ func Fatale(ctx context.Context, err error) { // Fatalf logs err with a formatted message and exits with a non-0 return code. func Fatalf(ctx context.Context, err error, format string, args ...any) { validateFormat(format) - configuredLogger(ctx, err).Error(err, buildMessage(format, args, true)) + configuredLogger(ctx).Error(err, buildMessage(format, args, true)) if exitOnFatal { os.Exit(1) } @@ -138,11 +136,7 @@ func buildMessage(format string, args []any, isFatal bool) string { } // buildMessage returns a logger that's been configured with additional values. -func configuredLogger(ctx context.Context, err ...error) logr.Logger { - if len(err) > 1 { - panic(errors.New("more than one err supplied")) - } - +func configuredLogger(ctx context.Context) logr.Logger { logger := Logger if ctx != nil { @@ -162,11 +156,5 @@ func configuredLogger(ctx context.Context, err ...error) logr.Logger { logger = logger.WithCallDepth(1) - if len(err) == 1 { - if stackErr, stackOK := err[0].(stackTracer); stackOK { - logger = logger.WithValues(KeyStackTrace, stackErr.StackTrace()) - } - } - return logger } diff --git a/internal/logging/log_test.go b/internal/logging/log_test.go index 5bd2fd4..5bd8939 100644 --- a/internal/logging/log_test.go +++ b/internal/logging/log_test.go @@ -19,13 +19,13 @@ package logging import ( "bytes" "context" + "errors" "fmt" "testing" ccontext "github.com/ExpediaGroup/container-startup-autoscaler/internal/context" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" "github.com/go-logr/logr" - "github.com/pkg/errors" "github.com/rs/zerolog" "github.com/stretchr/testify/assert" ) @@ -50,7 +50,6 @@ type wantLogRxConfig struct { wantMsgRx string wantTargetNameRx string wantTargetStates bool - wantStackTrace bool } const ( @@ -116,7 +115,6 @@ func TestErrore(t *testing.T) { wantMsgRx: testErrorMsg, wantTargetNameRx: testTargetContainerName, wantTargetStates: true, - wantStackTrace: true, }, }, } @@ -146,9 +144,8 @@ func TestErrorf(t *testing.T) { args: []any{testArg}, }, wantLogRxConfig: wantLogRxConfig{ - wantLevelRx: wantErrorLevelRx, - wantMsgRx: wantFormatArgsMsgRx, - wantStackTrace: true, + wantLevelRx: wantErrorLevelRx, + wantMsgRx: wantFormatArgsMsgRx, }, }, { @@ -164,7 +161,6 @@ func TestErrorf(t *testing.T) { wantMsgRx: wantFormatArgsMsgRx, wantTargetNameRx: testTargetContainerName, wantTargetStates: true, - wantStackTrace: true, }, }, } @@ -188,7 +184,6 @@ func TestFatale(t *testing.T) { wantMsgRx: testErrorMsg + fatalSuffixRx, wantTargetNameRx: testTargetContainerName, wantTargetStates: true, - wantStackTrace: true, }, }, } @@ -218,9 +213,8 @@ func TestFatalf(t *testing.T) { args: []any{testArg}, }, wantLogRxConfig: wantLogRxConfig{ - wantLevelRx: wantErrorLevelRx, - wantMsgRx: wantFormatArgsMsgRx + fatalSuffixRx, - wantStackTrace: true, + wantLevelRx: wantErrorLevelRx, + wantMsgRx: wantFormatArgsMsgRx + fatalSuffixRx, }, }, { @@ -236,7 +230,6 @@ func TestFatalf(t *testing.T) { wantMsgRx: wantFormatArgsMsgRx + fatalSuffixRx, wantTargetNameRx: testTargetContainerName, wantTargetStates: true, - wantStackTrace: true, }, }, } @@ -326,17 +319,6 @@ func TestInfofNotLoggedForLevel(t *testing.T) { assert.Empty(t, buffer.String()) } -func TestConfiguredLogger(t *testing.T) { - // Note: private functions should only be included in unit tests where strictly necessary. - t.Run("MoreThanOneErrPanic", func(t *testing.T) { - assert.PanicsWithError( - t, - "more than one err supplied", - func() { configuredLogger(testContextNoPodInfo(), errors.New("test1"), errors.New("test2")) }, - ) - }) -} - func testContextPodInfo() context.Context { buffer := &bytes.Buffer{} Init(buffer, testV, testAddCaller) @@ -396,8 +378,4 @@ func assertLog(t *testing.T, ctx context.Context, config wantLogRxConfig) { if config.wantTargetStates { assert.Regexp(t, fmt.Sprintf("\"%s\":\\{.+?\\}", KeyTargetContainerStates), log) } - - if config.wantStackTrace { - assert.Regexp(t, fmt.Sprintf("\"%s\":\\[.+?\\]", KeyStackTrace), log) - } } diff --git a/internal/pod/containerkubehelper.go b/internal/pod/containerkubehelper.go index d749feb..282934d 100644 --- a/internal/pod/containerkubehelper.go +++ b/internal/pod/containerkubehelper.go @@ -17,7 +17,10 @@ limitations under the License. package pod import ( - "github.com/pkg/errors" + "errors" + "fmt" + + "github.com/ExpediaGroup/container-startup-autoscaler/internal/common" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" ) @@ -70,7 +73,7 @@ func (h containerKubeHelper) HasReadinessProbe(container *v1.Container) bool { func (h containerKubeHelper) State(pod *v1.Pod, containerName string) (v1.ContainerState, error) { stat, err := h.status(pod, containerName) if err != nil { - return v1.ContainerState{}, errors.Wrap(err, "unable to get container status") + return v1.ContainerState{}, common.WrapErrorf(err, "unable to get container status") } return stat.State, nil @@ -80,7 +83,7 @@ func (h containerKubeHelper) State(pod *v1.Pod, containerName string) (v1.Contai func (h containerKubeHelper) IsStarted(pod *v1.Pod, containerName string) (bool, error) { stat, err := h.status(pod, containerName) if err != nil { - return false, errors.Wrap(err, "unable to get container status") + return false, common.WrapErrorf(err, "unable to get container status") } if stat.Started == nil { @@ -94,7 +97,7 @@ func (h containerKubeHelper) IsStarted(pod *v1.Pod, containerName string) (bool, func (h containerKubeHelper) IsReady(pod *v1.Pod, containerName string) (bool, error) { stat, err := h.status(pod, containerName) if err != nil { - return false, errors.Wrap(err, "unable to get container status") + return false, common.WrapErrorf(err, "unable to get container status") } return stat.Ready, nil @@ -113,7 +116,7 @@ func (h containerKubeHelper) Requests(container *v1.Container, resourceName v1.R return *container.Resources.Requests.Memory() } - panic(errors.Errorf("resourceName '%s' not supported", resourceName)) + panic(fmt.Errorf("resourceName '%s' not supported", resourceName)) } // Limits returns limits for the supplied resourceName, from the supplied container. @@ -129,7 +132,7 @@ func (h containerKubeHelper) Limits(container *v1.Container, resourceName v1.Res return *container.Resources.Limits.Memory() } - panic(errors.Errorf("resourceName '%s' not supported", resourceName)) + panic(fmt.Errorf("resourceName '%s' not supported", resourceName)) } // ResizePolicy returns the resource resize restart policy for the supplied resourceName, from the supplied container. @@ -147,7 +150,7 @@ func (h containerKubeHelper) ResizePolicy( } } - panic(errors.Errorf("resourceName '%s' not supported", resourceName)) + panic(fmt.Errorf("resourceName '%s' not supported", resourceName)) } // AllocatedResources returns allocated resources for the supplied containerName and resourceName, from the supplied @@ -159,7 +162,7 @@ func (h containerKubeHelper) AllocatedResources( ) (resource.Quantity, error) { stat, err := h.status(pod, containerName) if err != nil { - return resource.Quantity{}, errors.Wrap(err, "unable to get container status") + return resource.Quantity{}, common.WrapErrorf(err, "unable to get container status") } if stat.AllocatedResources == nil { @@ -173,7 +176,7 @@ func (h containerKubeHelper) AllocatedResources( return *stat.AllocatedResources.Memory(), nil } - panic(errors.Errorf("resourceName '%s' not supported", resourceName)) + panic(fmt.Errorf("resourceName '%s' not supported", resourceName)) } // CurrentRequests returns currently enacted requests for the supplied containerName and resourceName, from the @@ -185,7 +188,7 @@ func (h containerKubeHelper) CurrentRequests( ) (resource.Quantity, error) { stat, err := h.status(pod, containerName) if err != nil { - return resource.Quantity{}, errors.Wrap(err, "unable to get container status") + return resource.Quantity{}, common.WrapErrorf(err, "unable to get container status") } if stat.Resources == nil { @@ -199,7 +202,7 @@ func (h containerKubeHelper) CurrentRequests( return *stat.Resources.Requests.Memory(), nil } - panic(errors.Errorf("resourceName '%s' not supported", resourceName)) + panic(fmt.Errorf("resourceName '%s' not supported", resourceName)) } // CurrentLimits returns currently enacted limits for the supplied containerName and resourceName, from the supplied @@ -211,7 +214,7 @@ func (h containerKubeHelper) CurrentLimits( ) (resource.Quantity, error) { stat, err := h.status(pod, containerName) if err != nil { - return resource.Quantity{}, errors.Wrap(err, "unable to get container status") + return resource.Quantity{}, common.WrapErrorf(err, "unable to get container status") } if stat.Resources == nil { @@ -225,7 +228,7 @@ func (h containerKubeHelper) CurrentLimits( return *stat.Resources.Limits.Memory(), nil } - panic(errors.Errorf("resourceName '%s' not supported", resourceName)) + panic(fmt.Errorf("resourceName '%s' not supported", resourceName)) } // status returns the container status for the supplied containerName, from the supplied pod. diff --git a/internal/pod/error.go b/internal/pod/error.go index 751eaa1..9ec0cd4 100644 --- a/internal/pod/error.go +++ b/internal/pod/error.go @@ -18,8 +18,6 @@ package pod import ( "fmt" - - "github.com/pkg/errors" ) // ValidationError is an error that indicates validation failed. It wraps another error. @@ -33,11 +31,9 @@ func NewValidationError(message string, toWrap error) error { return ValidationError{message: message} } - withMessage := errors.WithMessage(toWrap, message) - withStack := errors.WithStack(withMessage) return ValidationError{ message: message, - wrapped: withStack, + wrapped: toWrap, } } @@ -46,18 +42,13 @@ func (e ValidationError) Error() string { return fmt.Sprintf("validation error: %s", e.message) } - return fmt.Sprintf("validation error: %s", e.wrapped.Error()) + return fmt.Errorf("validation error: %s: %w", e.message, e.wrapped).Error() } -func (e ValidationError) Cause() error { +func (e ValidationError) Unwrap() error { return e.wrapped } -// Is required for errors.Is() since this error has additional fields. -func (e ValidationError) Is(target error) bool { - return target == ValidationError{} -} - // ContainerStatusNotPresentError is an error that indicates container status is not present. type ContainerStatusNotPresentError struct{} diff --git a/internal/pod/error_test.go b/internal/pod/error_test.go index 85b686d..615de39 100644 --- a/internal/pod/error_test.go +++ b/internal/pod/error_test.go @@ -17,43 +17,34 @@ limitations under the License. package pod import ( + "errors" "testing" - "github.com/pkg/errors" + "github.com/ExpediaGroup/container-startup-autoscaler/internal/common" "github.com/stretchr/testify/assert" ) func TestNewValidationError(t *testing.T) { err := NewValidationError("test", errors.New("")) - assert.True(t, errors.Is(err, ValidationError{})) + assert.True(t, errors.As(err, &ValidationError{})) } func TestValidationErrorError(t *testing.T) { - t.Run("NotNilCause", func(t *testing.T) { - e := NewValidationError("test1", errors.New("test2")) - assert.Equal(t, "validation error: test1: test2", e.Error()) + t.Run("Wrapped", func(t *testing.T) { + err1 := errors.New("err1") + err2 := common.WrapErrorf(err1, "err2") + e := NewValidationError("err3", err2) + assert.Equal(t, "validation error: err3: err2: err1", e.Error()) }) - t.Run("NilCause", func(t *testing.T) { + t.Run("NotWrapped", func(t *testing.T) { e := NewValidationError("test", nil) assert.Equal(t, "validation error: test", e.Error()) }) } -func TestValidationErrorCause(t *testing.T) { - t.Run("NotNilCause", func(t *testing.T) { - e := ValidationError{wrapped: errors.New("")} - assert.NotNil(t, e.Cause()) - }) - - t.Run("NilCause", func(t *testing.T) { - e := ValidationError{wrapped: nil} - assert.Nil(t, e.Cause()) - }) -} - func TestNewContainerStatusNotPresentError(t *testing.T) { - assert.True(t, errors.Is(NewContainerStatusNotPresentError(), ContainerStatusNotPresentError{})) + assert.True(t, errors.As(NewContainerStatusNotPresentError(), &ContainerStatusNotPresentError{})) } func TestContainerStatusNotPresentErrorError(t *testing.T) { @@ -62,7 +53,7 @@ func TestContainerStatusNotPresentErrorError(t *testing.T) { } func TestNewContainerStatusAllocatedResourcesNotPresentError(t *testing.T) { - assert.True(t, errors.Is(NewContainerStatusAllocatedResourcesNotPresentError(), ContainerStatusAllocatedResourcesNotPresentError{})) + assert.True(t, errors.As(NewContainerStatusAllocatedResourcesNotPresentError(), &ContainerStatusAllocatedResourcesNotPresentError{})) } func TestContainerStatusAllocatedResourcesNotPresentErrorError(t *testing.T) { @@ -71,7 +62,7 @@ func TestContainerStatusAllocatedResourcesNotPresentErrorError(t *testing.T) { } func TestNewContainerStatusResourcesNotPresentError(t *testing.T) { - assert.True(t, errors.Is(NewContainerStatusResourcesNotPresentError(), ContainerStatusResourcesNotPresentError{})) + assert.True(t, errors.As(NewContainerStatusResourcesNotPresentError(), &ContainerStatusResourcesNotPresentError{})) } func TestContainerStatusResourcesNotPresentErrorError(t *testing.T) { diff --git a/internal/pod/kubehelper.go b/internal/pod/kubehelper.go index a57c077..03d89e8 100644 --- a/internal/pod/kubehelper.go +++ b/internal/pod/kubehelper.go @@ -18,12 +18,14 @@ package pod import ( "context" + "errors" + "fmt" "strconv" + "github.com/ExpediaGroup/container-startup-autoscaler/internal/common" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" "github.com/ExpediaGroup/container-startup-autoscaler/internal/retry" retrygo "github.com/avast/retry-go/v4" - "github.com/pkg/errors" "k8s.io/api/core/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/resource" @@ -79,7 +81,7 @@ func (h *kubeHelper) Get(ctx context.Context, name types.NamespacedName) (bool, return false, &v1.Pod{}, nil } - return false, &v1.Pod{}, errors.Wrap(err, "unable to get pod") + return false, &v1.Pod{}, common.WrapErrorf(err, "unable to get pod") } return true, pod, nil @@ -95,7 +97,7 @@ func (h *kubeHelper) Patch( ) (*v1.Pod, error) { shouldPatch, mutatedPod, err := mutatePodFunc(pod) if err != nil { - return nil, errors.Wrap(err, "unable to mutate pod") + return nil, common.WrapErrorf(err, "unable to mutate pod") } if !shouldPatch { return pod, nil @@ -110,7 +112,7 @@ func (h *kubeHelper) Patch( Name: pod.Name, }) if getErr != nil { - return errors.Wrap(err, "unable to get pod when resolving conflict") + return common.WrapErrorf(err, "unable to get pod when resolving conflict") } if !exists { // Mark as unrecoverable so not to retry further. @@ -120,7 +122,7 @@ func (h *kubeHelper) Patch( _, mutatedPod, _ = mutatePodFunc(latestPod) } - return errors.WithStack(err) + return err } return nil @@ -128,7 +130,7 @@ func (h *kubeHelper) Patch( err = retry.DoStandardRetryWithMoreOpts(ctx, retryableFunc, kubeApiRetryOptions(ctx)) if err != nil { - return nil, errors.Wrap(err, "unable to patch pod") + return nil, common.WrapErrorf(err, "unable to patch pod") } return mutatedPod, nil @@ -169,7 +171,7 @@ func (h *kubeHelper) UpdateContainerResources( // 'Should patch' ignored here as supplementary to patching resources. _, mutatedPod, err = addMutations(mutatedPod) if err != nil { - return false, nil, errors.Wrap(err, "unable to apply additional pod mutations") + return false, nil, common.WrapErrorf(err, "unable to apply additional pod mutations") } } @@ -178,7 +180,7 @@ func (h *kubeHelper) UpdateContainerResources( newPod, err := h.Patch(ctx, pod, mutatePodFunc) if err != nil { - return nil, errors.Wrap(err, "unable to patch pod") + return nil, common.WrapErrorf(err, "unable to patch pod") } return newPod, nil @@ -232,7 +234,7 @@ func (h *kubeHelper) expectedLabelOrAnnotationAs( var value string var present bool if value, present = m[name]; !present { - return nil, errors.Errorf("%s '%s' not present", mapFor, name) + return nil, fmt.Errorf("%s '%s' not present", mapFor, name) } switch as { @@ -241,11 +243,11 @@ func (h *kubeHelper) expectedLabelOrAnnotationAs( case podcommon.TypeBool: valueBool, err := strconv.ParseBool(value) if err != nil { - return nil, errors.Wrapf(err, "unable to parse '%s' %s value '%s' as %s", name, mapFor, value, as) + return nil, common.WrapErrorf(err, "unable to parse '%s' %s value '%s' as %s", name, mapFor, value, as) } return valueBool, nil } - panic(errors.Errorf("as '%s' not supported", as)) + panic(fmt.Errorf("as '%s' not supported", as)) } diff --git a/internal/pod/kubehelper_test.go b/internal/pod/kubehelper_test.go index e2d0225..ab4941d 100644 --- a/internal/pod/kubehelper_test.go +++ b/internal/pod/kubehelper_test.go @@ -18,6 +18,7 @@ package pod import ( "context" + "errors" "fmt" "strings" "testing" @@ -26,7 +27,6 @@ import ( "github.com/ExpediaGroup/container-startup-autoscaler/internal/metrics/retry" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podtest" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" "k8s.io/api/core/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" @@ -246,14 +246,15 @@ func TestKubeHelperPatch(t *testing.T) { }, )) + beforeMetricVal, _ := testutil.GetCounterMetricValue(retry.Retry(strings.ToLower(string(metav1.StatusReasonConflict)))) got, err := h.Patch(contexttest.NewCtxBuilder(contexttest.NewOneRetryCtxConfig(nil)).Build(), pod, mutatePodFunc) assert.Nil(t, err) assert.True(t, got.Spec.Containers[0].Resources.Requests[v1.ResourceCPU].Equal(cpuRequests)) assert.True(t, got.Spec.Containers[0].Resources.Limits[v1.ResourceCPU].Equal(cpuLimits)) assert.True(t, got.Spec.Containers[0].Resources.Requests[v1.ResourceMemory].Equal(memoryRequests)) assert.True(t, got.Spec.Containers[0].Resources.Limits[v1.ResourceMemory].Equal(memoryLimits)) - metricVal, _ := testutil.GetCounterMetricValue(retry.Retry(strings.ToLower(string(metav1.StatusReasonConflict)))) - assert.Equal(t, float64(1), metricVal) + afterMetricVal, _ := testutil.GetCounterMetricValue(retry.Retry(strings.ToLower(string(metav1.StatusReasonConflict)))) + assert.Equal(t, beforeMetricVal+1, afterMetricVal) }) t.Run("OkNoPatch", func(t *testing.T) { diff --git a/internal/pod/podcommon/stateconst.go b/internal/pod/podcommon/stateconst.go index b740ca7..671d004 100644 --- a/internal/pod/podcommon/stateconst.go +++ b/internal/pod/podcommon/stateconst.go @@ -17,8 +17,9 @@ limitations under the License. package podcommon import ( + "fmt" + "github.com/ExpediaGroup/container-startup-autoscaler/internal/metrics/metricscommon" - "github.com/pkg/errors" ) // StateBool indicates the state of a boolean-like state. @@ -63,7 +64,7 @@ func (s StateResources) Direction() metricscommon.Direction { return metricscommon.DirectionDown } - panic(errors.Errorf("'%s' not supported", s)) + panic(fmt.Errorf("'%s' not supported", s)) } // HumanReadable returns a string suitable to include within human-readable messages. diff --git a/internal/pod/podcommon/statusannotation.go b/internal/pod/podcommon/statusannotation.go index 2a6e129..335d466 100644 --- a/internal/pod/podcommon/statusannotation.go +++ b/internal/pod/podcommon/statusannotation.go @@ -20,7 +20,6 @@ import ( "encoding/json" "github.com/ExpediaGroup/container-startup-autoscaler/internal/common" - "github.com/pkg/errors" ) // StatusAnnotation holds status information that's serialized to JSON for status reporting. @@ -63,7 +62,7 @@ func (s StatusAnnotation) Equal(to StatusAnnotation) bool { func StatusAnnotationFromString(s string) (StatusAnnotation, error) { ret := &StatusAnnotation{} if err := json.Unmarshal([]byte(s), ret); err != nil { - return *ret, errors.Wrap(err, "unable to unmarshal") + return *ret, common.WrapErrorf(err, "unable to unmarshal") } return *ret, nil diff --git a/internal/pod/podcommon/statusconst.go b/internal/pod/podcommon/statusconst.go index 1ac1562..cc14c6a 100644 --- a/internal/pod/podcommon/statusconst.go +++ b/internal/pod/podcommon/statusconst.go @@ -17,8 +17,9 @@ limitations under the License. package podcommon import ( + "fmt" + "github.com/ExpediaGroup/container-startup-autoscaler/internal/metrics/metricscommon" - "github.com/pkg/errors" ) // StatusScaleState indicates the scale state for status purposes. @@ -59,5 +60,5 @@ func (s StatusScaleState) Direction() metricscommon.Direction { return metricscommon.DirectionDown } - panic(errors.Errorf("'%s' not supported", s)) + panic(fmt.Errorf("'%s' not supported", s)) } diff --git a/internal/pod/podtest/container.go b/internal/pod/podtest/container.go index 6d3583f..d06b00c 100644 --- a/internal/pod/podtest/container.go +++ b/internal/pod/podtest/container.go @@ -17,8 +17,9 @@ limitations under the License. package podtest import ( + "errors" + "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" - "github.com/pkg/errors" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" ) diff --git a/internal/pod/podtest/pod.go b/internal/pod/podtest/pod.go index 56362a9..ae30a89 100644 --- a/internal/pod/podtest/pod.go +++ b/internal/pod/podtest/pod.go @@ -17,8 +17,9 @@ limitations under the License. package podtest import ( + "errors" + "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" - "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/internal/pod/podtest/podinterceptor.go b/internal/pod/podtest/podinterceptor.go index 22fd794..2610554 100644 --- a/internal/pod/podtest/podinterceptor.go +++ b/internal/pod/podtest/podinterceptor.go @@ -18,10 +18,10 @@ package podtest import ( "context" + "errors" "sync" "github.com/ExpediaGroup/container-startup-autoscaler/internal/context/contexttest" - "github.com/pkg/errors" "sigs.k8s.io/controller-runtime/pkg/client" ) diff --git a/internal/pod/retry.go b/internal/pod/retry.go index a9d5b22..eaf27c2 100644 --- a/internal/pod/retry.go +++ b/internal/pod/retry.go @@ -18,12 +18,12 @@ package pod import ( "context" + "errors" "strings" "github.com/ExpediaGroup/container-startup-autoscaler/internal/logging" metricsretry "github.com/ExpediaGroup/container-startup-autoscaler/internal/metrics/retry" "github.com/avast/retry-go/v4" - "github.com/pkg/errors" kerrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/internal/pod/scaleconfig.go b/internal/pod/scaleconfig.go index cf7deea..d3b587a 100644 --- a/internal/pod/scaleconfig.go +++ b/internal/pod/scaleconfig.go @@ -17,11 +17,11 @@ limitations under the License. package pod import ( + "errors" "fmt" "github.com/ExpediaGroup/container-startup-autoscaler/internal/common" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" - "github.com/pkg/errors" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" ) @@ -65,62 +65,62 @@ func (c *scaleConfig) StoreFromAnnotations(pod *v1.Pod) error { value, err := c.kubeHelper.ExpectedAnnotationValueAs(pod, podcommon.AnnotationTargetContainerName, podcommon.TypeString) if err != nil { - return errors.Wrapf(err, annErrFmt, podcommon.AnnotationTargetContainerName) + return common.WrapErrorf(err, annErrFmt, podcommon.AnnotationTargetContainerName) } targetContainerName := value.(string) value, err = c.kubeHelper.ExpectedAnnotationValueAs(pod, podcommon.AnnotationCpuStartup, podcommon.TypeString) if err != nil { - return errors.Wrapf(err, annErrFmt, podcommon.AnnotationCpuStartup) + return common.WrapErrorf(err, annErrFmt, podcommon.AnnotationCpuStartup) } cpuStartup, err := resource.ParseQuantity(value.(string)) if err != nil { - return errors.Wrapf(err, qParseErrFmt, podcommon.AnnotationCpuStartup, value) + return common.WrapErrorf(err, qParseErrFmt, podcommon.AnnotationCpuStartup, value) } value, err = c.kubeHelper.ExpectedAnnotationValueAs(pod, podcommon.AnnotationCpuPostStartupRequests, podcommon.TypeString) if err != nil { - return errors.Wrapf(err, annErrFmt, podcommon.AnnotationCpuPostStartupRequests) + return common.WrapErrorf(err, annErrFmt, podcommon.AnnotationCpuPostStartupRequests) } cpuPostStartupRequests, err := resource.ParseQuantity(value.(string)) if err != nil { - return errors.Wrapf(err, qParseErrFmt, podcommon.AnnotationCpuPostStartupRequests, value) + return common.WrapErrorf(err, qParseErrFmt, podcommon.AnnotationCpuPostStartupRequests, value) } value, err = c.kubeHelper.ExpectedAnnotationValueAs(pod, podcommon.AnnotationCpuPostStartupLimits, podcommon.TypeString) if err != nil { - return errors.Wrapf(err, annErrFmt, podcommon.AnnotationCpuPostStartupLimits) + return common.WrapErrorf(err, annErrFmt, podcommon.AnnotationCpuPostStartupLimits) } cpuPostStartupLimits, err := resource.ParseQuantity(value.(string)) if err != nil { - return errors.Wrapf(err, qParseErrFmt, podcommon.AnnotationCpuPostStartupLimits, value) + return common.WrapErrorf(err, qParseErrFmt, podcommon.AnnotationCpuPostStartupLimits, value) } value, err = c.kubeHelper.ExpectedAnnotationValueAs(pod, podcommon.AnnotationMemoryStartup, podcommon.TypeString) if err != nil { - return errors.Wrapf(err, annErrFmt, podcommon.AnnotationMemoryStartup) + return common.WrapErrorf(err, annErrFmt, podcommon.AnnotationMemoryStartup) } memoryStartup, err := resource.ParseQuantity(value.(string)) if err != nil { - return errors.Wrapf(err, qParseErrFmt, podcommon.AnnotationMemoryStartup, value) + return common.WrapErrorf(err, qParseErrFmt, podcommon.AnnotationMemoryStartup, value) } value, err = c.kubeHelper.ExpectedAnnotationValueAs(pod, podcommon.AnnotationMemoryPostStartupRequests, podcommon.TypeString) if err != nil { - return errors.Wrapf(err, annErrFmt, podcommon.AnnotationMemoryPostStartupRequests) + return common.WrapErrorf(err, annErrFmt, podcommon.AnnotationMemoryPostStartupRequests) } memoryPostStartupRequests, err := resource.ParseQuantity(value.(string)) if err != nil { - return errors.Wrapf(err, qParseErrFmt, podcommon.AnnotationMemoryPostStartupRequests, value) + return common.WrapErrorf(err, qParseErrFmt, podcommon.AnnotationMemoryPostStartupRequests, value) } value, err = c.kubeHelper.ExpectedAnnotationValueAs(pod, podcommon.AnnotationMemoryPostStartupLimits, podcommon.TypeString) if err != nil { - return errors.Wrapf(err, annErrFmt, podcommon.AnnotationMemoryPostStartupLimits) + return common.WrapErrorf(err, annErrFmt, podcommon.AnnotationMemoryPostStartupLimits) } memoryPostStartupLimits, err := resource.ParseQuantity(value.(string)) if err != nil { - return errors.Wrapf(err, qParseErrFmt, podcommon.AnnotationMemoryPostStartupLimits, value) + return common.WrapErrorf(err, qParseErrFmt, podcommon.AnnotationMemoryPostStartupLimits, value) } c.targetContainerName = targetContainerName @@ -143,7 +143,7 @@ func (c *scaleConfig) Validate() error { // TODO(wt) only guaranteed post-startup configuration is possible at the moment (pod QoS is immutable) if !c.cpuConfig.PostStartupRequests.Equal(c.cpuConfig.PostStartupLimits) { - return errors.Errorf( + return fmt.Errorf( "cpu post-startup requests (%s) must equal post-startup limits (%s) - change in qos class is not yet permitted by kube", c.cpuConfig.PostStartupRequests.String(), c.cpuConfig.PostStartupLimits.String(), @@ -152,7 +152,7 @@ func (c *scaleConfig) Validate() error { // TODO(wt) only guaranteed post-startup configuration is possible at the moment (pod QoS is immutable) if !c.memoryConfig.PostStartupRequests.Equal(c.memoryConfig.PostStartupLimits) { - return errors.Errorf( + return fmt.Errorf( "memory post-startup requests (%s) must equal post-startup limits (%s) - change in qos class is not yet permitted by kube", c.memoryConfig.PostStartupRequests.String(), c.memoryConfig.PostStartupLimits.String(), @@ -160,7 +160,7 @@ func (c *scaleConfig) Validate() error { } if c.cpuConfig.PostStartupRequests.Cmp(c.cpuConfig.Startup) == 1 { - return errors.Errorf( + return fmt.Errorf( "cpu post-startup requests (%s) is greater than startup value (%s)", c.cpuConfig.PostStartupRequests.String(), c.cpuConfig.Startup.String(), @@ -168,7 +168,7 @@ func (c *scaleConfig) Validate() error { } if c.memoryConfig.PostStartupRequests.Cmp(c.memoryConfig.Startup) == 1 { - return errors.Errorf( + return fmt.Errorf( "memory post-startup requests (%s) is greater than startup value (%s)", c.memoryConfig.PostStartupRequests.String(), c.memoryConfig.Startup.String(), @@ -177,7 +177,7 @@ func (c *scaleConfig) Validate() error { // TODO(wt) reinstate once change in qos class is permitted by Kube //if c.cpuConfig.PostStartupLimits.Cmp(c.cpuConfig.PostStartupRequests) == -1 { - // return errors.Errorf( + // return fmt.Errorf( // "cpu post-startup limits (%s) is less than post-startup requests (%s)", // c.cpuConfig.PostStartupLimits.String(), // c.cpuConfig.PostStartupRequests.String(), @@ -185,7 +185,7 @@ func (c *scaleConfig) Validate() error { //} // //if c.memoryConfig.PostStartupLimits.Cmp(c.memoryConfig.PostStartupRequests) == -1 { - // return errors.Errorf( + // return fmt.Errorf( // "memory post-startup limits (%s) is less than post-startup requests (%s)", // c.memoryConfig.PostStartupLimits.String(), // c.memoryConfig.PostStartupRequests.String(), diff --git a/internal/pod/scaleconfig_test.go b/internal/pod/scaleconfig_test.go index b344122..a339c66 100644 --- a/internal/pod/scaleconfig_test.go +++ b/internal/pod/scaleconfig_test.go @@ -17,12 +17,12 @@ limitations under the License. package pod import ( + "errors" "fmt" "testing" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podtest" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "k8s.io/api/core/v1" diff --git a/internal/pod/status.go b/internal/pod/status.go index 5c64755..ba5f322 100644 --- a/internal/pod/status.go +++ b/internal/pod/status.go @@ -18,6 +18,7 @@ package pod import ( "context" + "fmt" "time" "github.com/ExpediaGroup/container-startup-autoscaler/internal/common" @@ -25,7 +26,6 @@ import ( "github.com/ExpediaGroup/container-startup-autoscaler/internal/metrics/metricscommon" "github.com/ExpediaGroup/container-startup-autoscaler/internal/metrics/scale" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" - "github.com/pkg/errors" "k8s.io/api/core/v1" ) @@ -62,7 +62,7 @@ func (s *status) Update( newPod, err := s.kubeHelper.Patch(ctx, pod, mutatePodFunc) if err != nil { - return nil, errors.Wrap(err, "unable to patch pod") + return nil, common.WrapErrorf(err, "unable to patch pod") } return newPod, nil @@ -83,7 +83,7 @@ func (s *status) UpdateMutatePodFunc( var err error currentStat, err = podcommon.StatusAnnotationFromString(currentStatAnn) if err != nil { - return false, pod, errors.Wrap(err, "unable to get status annotation from string") + return false, pod, common.WrapErrorf(err, "unable to get status annotation from string") } } @@ -130,7 +130,7 @@ func (s *status) UpdateMutatePodFunc( ) } default: - panic(errors.Errorf("scaleState '%s' not supported", scaleState)) + panic(fmt.Errorf("scaleState '%s' not supported", scaleState)) } newStat := podcommon.NewStatusAnnotation(common.CapitalizeFirstChar(status), states, statScale, s.formattedNow(timeFormatSecs)) diff --git a/internal/pod/targetcontaineraction.go b/internal/pod/targetcontaineraction.go index 8a05559..3b6cb44 100644 --- a/internal/pod/targetcontaineraction.go +++ b/internal/pod/targetcontaineraction.go @@ -18,6 +18,7 @@ package pod import ( "context" + "errors" "fmt" "github.com/ExpediaGroup/container-startup-autoscaler/internal/common" @@ -25,7 +26,6 @@ import ( "github.com/ExpediaGroup/container-startup-autoscaler/internal/logging" "github.com/ExpediaGroup/container-startup-autoscaler/internal/metrics/scale" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" - "github.com/pkg/errors" "k8s.io/api/core/v1" "k8s.io/client-go/tools/record" ) @@ -73,11 +73,11 @@ func (a *targetContainerAction) Execute( config podcommon.ScaleConfig, ) error { if states.StartupProbe != podcommon.StateBoolTrue && states.StartupProbe != podcommon.StateBoolFalse { - panic(errors.Errorf("unsupported startup probe state '%s'", states.StartupProbe)) + panic(fmt.Errorf("unsupported startup probe state '%s'", states.StartupProbe)) } if states.ReadinessProbe != podcommon.StateBoolTrue && states.ReadinessProbe != podcommon.StateBoolFalse { - panic(errors.Errorf("unsupported readiness probe state '%s'", states.ReadinessProbe)) + panic(fmt.Errorf("unsupported readiness probe state '%s'", states.ReadinessProbe)) } if states.Container != podcommon.StateContainerRunning { @@ -145,7 +145,7 @@ func (a *targetContainerAction) Execute( return a.startedWithUnknownResAction(ctx, states, pod, config) } - panic(errors.Errorf("no action to invoke")) + panic(errors.New("no action to invoke")) } // containerNotRunningAction only logs and updates status since the target container isn't currently running. @@ -194,7 +194,7 @@ func (a *targetContainerAction) resUnknownAction( ) error { msg := "unknown resources applied" a.updateStatus(ctx, states, podcommon.StatusScaleStateNotApplicable, pod, msg) - return errors.Errorf("%s (%s)", msg, a.containerResourceConfig(ctx, pod, config)) + return fmt.Errorf("%s (%s)", msg, a.containerResourceConfig(ctx, pod, config)) } // notStartedWithStartupResAction examines conditions and provides relevant feedback since the container is not ready @@ -226,7 +226,7 @@ func (a *targetContainerAction) notStartedWithPostStartupResAction( a.status.UpdateMutatePodFunc(ctx, msg, states, podcommon.StatusScaleStateUpCommanded), ) if err != nil { - return errors.Wrap(err, "unable to patch container resources") + return common.WrapErrorf(err, "unable to patch container resources") } logging.Infof(ctx, logging.VInfo, msg) @@ -251,7 +251,7 @@ func (a *targetContainerAction) startedWithStartupResAction( a.status.UpdateMutatePodFunc(ctx, msg, states, podcommon.StatusScaleStateDownCommanded), ) if err != nil { - return errors.Wrap(err, "unable to patch container resources") + return common.WrapErrorf(err, "unable to patch container resources") } logging.Infof(ctx, logging.VInfo, msg) @@ -288,7 +288,7 @@ func (a *targetContainerAction) notStartedWithUnknownResAction( a.status.UpdateMutatePodFunc(ctx, msg, states, podcommon.StatusScaleStateUnknownCommanded), ) if err != nil { - return errors.Wrap(err, "unable to patch container resources") + return common.WrapErrorf(err, "unable to patch container resources") } logging.Infof(ctx, logging.VInfo, msg) @@ -314,7 +314,7 @@ func (a *targetContainerAction) startedWithUnknownResAction( a.status.UpdateMutatePodFunc(ctx, msg, states, podcommon.StatusScaleStateUnknownCommanded), ) if err != nil { - return errors.Wrap(err, "unable to patch container resources") + return common.WrapErrorf(err, "unable to patch container resources") } logging.Infof(ctx, logging.VInfo, msg) @@ -380,7 +380,7 @@ func (a *targetContainerAction) processConfigEnacted( a.updateStatus(ctx, states, scaleState, pod, msg) scale.Failure(states.Resources.Direction(), "infeasible").Inc() a.warningEvent(pod, eventReasonScaling, msg) - return errors.Errorf("%s (%s)", msg, a.containerResourceConfig(ctx, pod, config)) + return fmt.Errorf("%s (%s)", msg, a.containerResourceConfig(ctx, pod, config)) default: var scaleState podcommon.StatusScaleState @@ -396,7 +396,7 @@ func (a *targetContainerAction) processConfigEnacted( a.updateStatus(ctx, states, scaleState, pod, msg) scale.Failure(states.Resources.Direction(), "unknownstatus").Inc() a.warningEvent(pod, eventReasonScaling, msg) - return errors.Errorf("%s '%s'", msg, a.kubeHelper.ResizeStatus(pod)) + return fmt.Errorf("%s '%s'", msg, a.kubeHelper.ResizeStatus(pod)) } // Resize is not pending, so examine AllocatedResources. @@ -440,7 +440,7 @@ func (a *targetContainerAction) processConfigEnacted( return nil default: - panic(errors.Errorf("unknown state '%s'", states.AllocatedResources)) + panic(fmt.Errorf("unknown state '%s'", states.AllocatedResources)) } // AllocatedResources is as expected - finally examine StatusResources. @@ -484,7 +484,7 @@ func (a *targetContainerAction) processConfigEnacted( return nil default: - panic(errors.Errorf("unknown state '%s'", states.StatusResources)) + panic(fmt.Errorf("unknown state '%s'", states.StatusResources)) } // Desired state: target container resources correctly enacted. diff --git a/internal/pod/targetcontaineraction_test.go b/internal/pod/targetcontaineraction_test.go index f186bea..4f2fe4e 100644 --- a/internal/pod/targetcontaineraction_test.go +++ b/internal/pod/targetcontaineraction_test.go @@ -18,6 +18,7 @@ package pod import ( "bytes" + "errors" "fmt" "testing" "time" @@ -28,7 +29,6 @@ import ( "github.com/ExpediaGroup/container-startup-autoscaler/internal/metrics/scale" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podtest" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "k8s.io/api/core/v1" diff --git a/internal/pod/targetcontainerstate.go b/internal/pod/targetcontainerstate.go index 6be7f19..6dd094c 100644 --- a/internal/pod/targetcontainerstate.go +++ b/internal/pod/targetcontainerstate.go @@ -18,10 +18,11 @@ package pod import ( "context" + "errors" + "github.com/ExpediaGroup/container-startup-autoscaler/internal/common" "github.com/ExpediaGroup/container-startup-autoscaler/internal/logging" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" - "github.com/pkg/errors" "k8s.io/api/core/v1" ) @@ -44,7 +45,7 @@ func (s targetContainerState) States(ctx context.Context, pod *v1.Pod, config po container, err := s.containerKubeHelper.Get(pod, config.GetTargetContainerName()) if err != nil { return podcommon.NewStatesAllUnknown(), - errors.Wrap(err, "unable to get container") + common.WrapErrorf(err, "unable to get container") } ret := podcommon.NewStatesAllUnknown() @@ -56,7 +57,7 @@ func (s targetContainerState) States(ctx context.Context, pod *v1.Pod, config po if !s.shouldReturnError(ctx, err) { return ret, nil } - return ret, errors.Wrap(err, "unable to determine container state") + return ret, common.WrapErrorf(err, "unable to determine container state") } ret.Started, err = s.stateStarted(pod, config) @@ -64,7 +65,7 @@ func (s targetContainerState) States(ctx context.Context, pod *v1.Pod, config po if !s.shouldReturnError(ctx, err) { return ret, nil } - return ret, errors.Wrap(err, "unable to determine started state") + return ret, common.WrapErrorf(err, "unable to determine started state") } ret.Ready, err = s.stateReady(pod, config) @@ -72,7 +73,7 @@ func (s targetContainerState) States(ctx context.Context, pod *v1.Pod, config po if !s.shouldReturnError(ctx, err) { return ret, nil } - return ret, errors.Wrap(err, "unable to determine ready state") + return ret, common.WrapErrorf(err, "unable to determine ready state") } ret.Resources = s.stateResources( @@ -85,7 +86,7 @@ func (s targetContainerState) States(ctx context.Context, pod *v1.Pod, config po if !s.shouldReturnError(ctx, err) { return ret, nil } - return ret, errors.Wrap(err, "unable to determine allocated resources states") + return ret, common.WrapErrorf(err, "unable to determine allocated resources states") } ret.StatusResources, err = s.stateStatusResources(pod, container, config) @@ -93,7 +94,7 @@ func (s targetContainerState) States(ctx context.Context, pod *v1.Pod, config po if !s.shouldReturnError(ctx, err) { return ret, nil } - return ret, errors.Wrap(err, "unable to determine status resources states") + return ret, common.WrapErrorf(err, "unable to determine status resources states") } return ret, nil @@ -121,7 +122,7 @@ func (s targetContainerState) stateReadinessProbe(container *v1.Container) podco func (s targetContainerState) stateContainer(pod *v1.Pod, config podcommon.ScaleConfig) (podcommon.StateContainer, error) { state, err := s.containerKubeHelper.State(pod, config.GetTargetContainerName()) if err != nil { - return podcommon.StateContainerUnknown, errors.Wrap(err, "unable to get container state") + return podcommon.StateContainerUnknown, common.WrapErrorf(err, "unable to get container state") } if state.Running != nil { @@ -143,7 +144,7 @@ func (s targetContainerState) stateContainer(pod *v1.Pod, config podcommon.Scale func (s targetContainerState) stateStarted(pod *v1.Pod, config podcommon.ScaleConfig) (podcommon.StateBool, error) { started, err := s.containerKubeHelper.IsStarted(pod, config.GetTargetContainerName()) if err != nil { - return podcommon.StateBoolUnknown, errors.Wrap(err, "unable to get container ready status") + return podcommon.StateBoolUnknown, common.WrapErrorf(err, "unable to get container ready status") } if started { @@ -157,7 +158,7 @@ func (s targetContainerState) stateStarted(pod *v1.Pod, config podcommon.ScaleCo func (s targetContainerState) stateReady(pod *v1.Pod, config podcommon.ScaleConfig) (podcommon.StateBool, error) { ready, err := s.containerKubeHelper.IsReady(pod, config.GetTargetContainerName()) if err != nil { - return podcommon.StateBoolUnknown, errors.Wrap(err, "unable to get container ready status") + return podcommon.StateBoolUnknown, common.WrapErrorf(err, "unable to get container ready status") } if ready { @@ -189,12 +190,12 @@ func (s targetContainerState) stateAllocatedResources( ) (podcommon.StateAllocatedResources, error) { allocatedCpu, err := s.containerKubeHelper.AllocatedResources(pod, config.GetTargetContainerName(), v1.ResourceCPU) if err != nil { - return podcommon.StateAllocatedResourcesUnknown, errors.Wrap(err, "unable to get allocated cpu resources") + return podcommon.StateAllocatedResourcesUnknown, common.WrapErrorf(err, "unable to get allocated cpu resources") } allocatedMemory, err := s.containerKubeHelper.AllocatedResources(pod, config.GetTargetContainerName(), v1.ResourceMemory) if err != nil { - return podcommon.StateAllocatedResourcesUnknown, errors.Wrap(err, "unable to get allocated memory resources") + return podcommon.StateAllocatedResourcesUnknown, common.WrapErrorf(err, "unable to get allocated memory resources") } if allocatedCpu.IsZero() || allocatedMemory.IsZero() { @@ -219,22 +220,22 @@ func (s targetContainerState) stateStatusResources( ) (podcommon.StateStatusResources, error) { currentRequestsCpu, err := s.containerKubeHelper.CurrentRequests(pod, config.GetTargetContainerName(), v1.ResourceCPU) if err != nil { - return podcommon.StateStatusResourcesUnknown, errors.Wrap(err, "unable to get status resources cpu requests") + return podcommon.StateStatusResourcesUnknown, common.WrapErrorf(err, "unable to get status resources cpu requests") } currentLimitsCpu, err := s.containerKubeHelper.CurrentLimits(pod, config.GetTargetContainerName(), v1.ResourceCPU) if err != nil { - return podcommon.StateStatusResourcesUnknown, errors.Wrap(err, "unable to get status resources cpu limits") + return podcommon.StateStatusResourcesUnknown, common.WrapErrorf(err, "unable to get status resources cpu limits") } currentRequestsMemory, err := s.containerKubeHelper.CurrentRequests(pod, config.GetTargetContainerName(), v1.ResourceMemory) if err != nil { - return podcommon.StateStatusResourcesUnknown, errors.Wrap(err, "unable to get status resources memory requests") + return podcommon.StateStatusResourcesUnknown, common.WrapErrorf(err, "unable to get status resources memory requests") } currentLimitsMemory, err := s.containerKubeHelper.CurrentLimits(pod, config.GetTargetContainerName(), v1.ResourceMemory) if err != nil { - return podcommon.StateStatusResourcesUnknown, errors.Wrap(err, "unable to get status resources memory limits") + return podcommon.StateStatusResourcesUnknown, common.WrapErrorf(err, "unable to get status resources memory limits") } if currentRequestsCpu.IsZero() || currentLimitsCpu.IsZero() || currentRequestsMemory.IsZero() || currentLimitsMemory.IsZero() { @@ -287,17 +288,17 @@ func (s targetContainerState) isPostStartupConfigApplied(container *v1.Container // shouldReturnError reports whether to return an error after examining the type of the supplied err. Certain errors // should not propagate since they are likely transient in nature i.e. 'resolved' in future reconciles. func (s targetContainerState) shouldReturnError(ctx context.Context, err error) bool { - if errors.Is(err, ContainerStatusNotPresentError{}) { + if errors.As(err, &ContainerStatusNotPresentError{}) { logging.Infof(ctx, logging.VDebug, "container status not yet present") return false } - if errors.Is(err, ContainerStatusAllocatedResourcesNotPresentError{}) { + if errors.As(err, &ContainerStatusAllocatedResourcesNotPresentError{}) { logging.Infof(ctx, logging.VDebug, "container status allocated resources not yet present") return false } - if errors.Is(err, ContainerStatusResourcesNotPresentError{}) { + if errors.As(err, &ContainerStatusResourcesNotPresentError{}) { logging.Infof(ctx, logging.VDebug, "container status resources not yet present") return false } diff --git a/internal/pod/targetcontainerstate_test.go b/internal/pod/targetcontainerstate_test.go index 45ad7dd..facf6cd 100644 --- a/internal/pod/targetcontainerstate_test.go +++ b/internal/pod/targetcontainerstate_test.go @@ -17,12 +17,12 @@ limitations under the License. package pod import ( + "errors" "testing" "github.com/ExpediaGroup/container-startup-autoscaler/internal/context/contexttest" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podtest" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "k8s.io/api/core/v1" @@ -775,6 +775,7 @@ func TestTargetContainerStateShouldReturnError(t *testing.T) { }{ {"ContainerStatusResourcesNotPresentErrorFalse", NewContainerStatusResourcesNotPresentError(), false}, {"ContainerStatusAllocatedResourcesNotPresentErrorFalse", NewContainerStatusAllocatedResourcesNotPresentError(), false}, + {"NewContainerStatusResourcesNotPresentErrorFalse", NewContainerStatusResourcesNotPresentError(), false}, {"True", errors.New(""), true}, } for _, tt := range tests { diff --git a/internal/pod/validation_test.go b/internal/pod/validation_test.go index 5591a69..6255707 100644 --- a/internal/pod/validation_test.go +++ b/internal/pod/validation_test.go @@ -18,6 +18,7 @@ package pod import ( "bytes" + "errors" "fmt" "testing" "time" @@ -25,7 +26,6 @@ import ( "github.com/ExpediaGroup/container-startup-autoscaler/internal/context/contexttest" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podtest" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "k8s.io/api/core/v1" @@ -446,7 +446,7 @@ func TestValidationValidate(t *testing.T) { func(podcommon.ScaleConfig) {}, ) if tt.wantErrMsg != "" { - assert.True(t, errors.Is(err, ValidationError{})) + assert.True(t, errors.As(err, &ValidationError{})) assert.Contains(t, err.Error(), tt.wantErrMsg) } else { assert.Nil(t, err) diff --git a/internal/retry/retry_test.go b/internal/retry/retry_test.go index 6e19cc7..743e0bb 100644 --- a/internal/retry/retry_test.go +++ b/internal/retry/retry_test.go @@ -18,13 +18,13 @@ package retry import ( "bytes" + "errors" "testing" "time" "github.com/ExpediaGroup/container-startup-autoscaler/internal/context/contexttest" "github.com/ExpediaGroup/container-startup-autoscaler/internal/logging" "github.com/avast/retry-go/v4" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" ) diff --git a/test/integration/command.go b/test/integration/command.go index 1aca69d..136fde0 100644 --- a/test/integration/command.go +++ b/test/integration/command.go @@ -22,7 +22,7 @@ import ( "os/exec" "strings" - "github.com/pkg/errors" + "github.com/ExpediaGroup/container-startup-autoscaler/internal/common" ) func cmdRun(cmd *exec.Cmd, info string, coreErrMsg string, fatalOnErr bool, suppressInfo ...bool) (string, error) { @@ -38,7 +38,7 @@ func cmdRun(cmd *exec.Cmd, info string, coreErrMsg string, fatalOnErr bool, supp combinedOutput, err := cmd.CombinedOutput() if err != nil { trimmedOutput := strings.Trim(string(combinedOutput), "\n") - wrappedErr := errors.Wrapf(err, "%s (output: %s)", coreErrMsg, trimmedOutput) + wrappedErr := common.WrapErrorf(err, "%s (output: %s)", coreErrMsg, trimmedOutput) if fatalOnErr { fmt.Println(wrappedErr) diff --git a/test/integration/csa.go b/test/integration/csa.go index 61d4809..520efbe 100644 --- a/test/integration/csa.go +++ b/test/integration/csa.go @@ -23,8 +23,8 @@ import ( "sync" "time" + "github.com/ExpediaGroup/container-startup-autoscaler/internal/common" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" - "github.com/pkg/errors" v1 "k8s.io/api/core/v1" ) @@ -148,7 +148,7 @@ func csaWaitStatus( if int(time.Now().Sub(started).Seconds()) > timeoutSecs { return retPod, retStatusAnn, - errors.Errorf( + fmt.Errorf( "waiting for csa status '%s' for pod '%s/%s' timed out - last status '%s'", waitMsgContains, podNamespace, podName, lastStatusAnnJson, ) @@ -170,7 +170,7 @@ func csaWaitStatus( if err != nil { return retPod, retStatusAnn, - errors.Wrapf(err, "unable to convert csa status for pod '%s/%s'", podNamespace, podName) + common.WrapErrorf(err, "unable to convert csa status for pod '%s/%s'", podNamespace, podName) } lastStatusAnnJson = statusAnn.Json() diff --git a/test/integration/integration_test.go b/test/integration/integration_test.go index 558e834..75666d3 100644 --- a/test/integration/integration_test.go +++ b/test/integration/integration_test.go @@ -17,6 +17,7 @@ limitations under the License. package integration import ( + "errors" "flag" "fmt" "os" @@ -25,7 +26,6 @@ import ( "testing" "github.com/ExpediaGroup/container-startup-autoscaler/internal/pod/podcommon" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "k8s.io/api/core/v1" diff --git a/test/integration/kind.go b/test/integration/kind.go index be385a0..622021f 100644 --- a/test/integration/kind.go +++ b/test/integration/kind.go @@ -23,7 +23,7 @@ import ( "runtime" "strings" - "github.com/pkg/errors" + "github.com/ExpediaGroup/container-startup-autoscaler/internal/common" ) const ( @@ -81,7 +81,7 @@ func kindSetupCluster(reuseCluster bool, installMetricsServer bool) { case "arm64": kindNodeImage = kindNodeImageArm64 default: - fmt.Println(errors.Errorf("architecture '%s' not supported", runtime.GOARCH)) + fmt.Println(fmt.Errorf("architecture '%s' not supported", runtime.GOARCH)) os.Exit(1) } @@ -105,12 +105,12 @@ func kindSetupCluster(reuseCluster bool, installMetricsServer bool) { ) if err := os.WriteFile(kindKubeconfig, []byte(output), 0644); err != nil { - fmt.Println(errors.Wrapf(err, "unable to write kubeconfig")) + fmt.Println(common.WrapErrorf(err, "unable to write kubeconfig")) os.Exit(1) } if err := kubePrintNodeInfo(); err != nil { - fmt.Println(errors.Wrapf(err, "unable to print kube node info")) + fmt.Println(common.WrapErrorf(err, "unable to print kube node info")) os.Exit(1) } diff --git a/test/integration/kube.go b/test/integration/kube.go index f7e1577..7be203c 100644 --- a/test/integration/kube.go +++ b/test/integration/kube.go @@ -23,7 +23,6 @@ import ( "strings" "time" - "github.com/pkg/errors" v1 "k8s.io/api/core/v1" ) @@ -147,7 +146,7 @@ func kubeWaitPodsExist(namespace string, nameContains string, count int, timeout for { if int(time.Now().Sub(started).Seconds()) > timeoutSecs { - return errors.Errorf("waiting for %d pods (pod name contains '%s') to exist in namespace '%s' timed out", + return fmt.Errorf("waiting for %d pods (pod name contains '%s') to exist in namespace '%s' timed out", timeoutSecs, nameContains, namespace, ) }