Merge pull request #114800 from haoruan/feature-8976-spew-sprintf-refactor

Capture spew.Sprintf() with all our favorite config into a util func
This commit is contained in:
Kubernetes Prow Robot 2023-04-11 15:34:57 -07:00 committed by GitHub
commit d0fc9d16ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 418 additions and 82 deletions

View File

@ -20,9 +20,9 @@ import (
"reflect"
"testing"
"github.com/davecgh/go-spew/spew"
"k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/dump"
)
func podRef(uid string) *v1.ObjectReference {
@ -458,7 +458,7 @@ func TestPackSubsets(t *testing.T) {
for _, tc := range testCases {
result := RepackSubsets(tc.given)
if !reflect.DeepEqual(result, SortSubsets(tc.expect)) {
t.Errorf("case %q: expected %s, got %s", tc.name, spew.Sprintf("%#v", SortSubsets(tc.expect)), spew.Sprintf("%#v", result))
t.Errorf("case %q: expected %s, got %s", tc.name, dump.Pretty(SortSubsets(tc.expect)), dump.Pretty(result))
}
}
}

View File

@ -21,12 +21,12 @@ import (
"strings"
"testing"
"github.com/davecgh/go-spew/spew"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/dump"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/validation/field"
utilfeature "k8s.io/apiserver/pkg/util/feature"
@ -2993,7 +2993,7 @@ func TestValidateDeploymentStatus(t *testing.T) {
errs := ValidateDeploymentStatus(&status, field.NewPath("status"))
if hasErr := len(errs) > 0; hasErr != test.expectedErr {
errString := spew.Sprintf("%#v", errs)
errString := dump.Pretty(errs)
t.Errorf("%s: expected error: %t, got error: %t\nerrors: %s", test.name, test.expectedErr, hasErr, errString)
}
}
@ -3064,7 +3064,7 @@ func TestValidateDeploymentStatusUpdate(t *testing.T) {
errs := ValidateDeploymentStatusUpdate(to, from)
if hasErr := len(errs) > 0; hasErr != test.expectedErr {
errString := spew.Sprintf("%#v", errs)
errString := dump.Pretty(errs)
t.Errorf("%s: expected error: %t, got error: %t\nerrors: %s", test.name, test.expectedErr, hasErr, errString)
}
}

View File

@ -18,11 +18,11 @@ package state
import (
"encoding/json"
"fmt"
"hash/fnv"
"strings"
"github.com/davecgh/go-spew/spew"
"k8s.io/apimachinery/pkg/util/dump"
"k8s.io/kubernetes/pkg/kubelet/checkpointmanager"
"k8s.io/kubernetes/pkg/kubelet/checkpointmanager/checksum"
"k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors"
@ -102,21 +102,14 @@ func (cp *CPUManagerCheckpointV1) VerifyChecksum() error {
return nil
}
printer := spew.ConfigState{
Indent: " ",
SortKeys: true,
DisableMethods: true,
SpewKeys: true,
}
ck := cp.Checksum
cp.Checksum = 0
object := printer.Sprintf("%#v", cp)
object := dump.ForHash(cp)
object = strings.Replace(object, "CPUManagerCheckpointV1", "CPUManagerCheckpoint", 1)
cp.Checksum = ck
hash := fnv.New32a()
printer.Fprintf(hash, "%v", object)
fmt.Fprintf(hash, "%v", object)
if cp.Checksum != checksum.Checksum(hash.Sum32()) {
return errors.ErrCorruptCheckpoint
}

View File

@ -18,11 +18,11 @@ package checkpoint
import (
"encoding/json"
"fmt"
"hash/fnv"
"strings"
"github.com/davecgh/go-spew/spew"
"k8s.io/apimachinery/pkg/util/dump"
"k8s.io/klog/v2"
"k8s.io/kubernetes/pkg/kubelet/checkpointmanager/checksum"
"k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors"
@ -48,18 +48,11 @@ type checkpointDataV1 struct {
// We need this special code path to be able to correctly validate the checksum k8s 1.19 wrote.
// credits to https://github.com/kubernetes/kubernetes/pull/102717/commits/353f93895118d2ffa2d59a29a1fbc225160ea1d6
func (cp checkpointDataV1) checksum() checksum.Checksum {
printer := spew.ConfigState{
Indent: " ",
SortKeys: true,
DisableMethods: true,
SpewKeys: true,
}
object := printer.Sprintf("%#v", cp)
object := dump.ForHash(cp)
object = strings.Replace(object, "checkpointDataV1", "checkpointData", 1)
object = strings.Replace(object, "PodDevicesEntryV1", "PodDevicesEntry", -1)
hash := fnv.New32a()
printer.Fprintf(hash, "%v", object)
fmt.Fprintf(hash, "%v", object)
return checksum.Checksum(hash.Sum32())
}

View File

@ -17,9 +17,10 @@ limitations under the License.
package hash
import (
"fmt"
"hash"
"github.com/davecgh/go-spew/spew"
"k8s.io/apimachinery/pkg/util/dump"
)
// DeepHashObject writes specified object to hash using the spew library
@ -27,11 +28,5 @@ import (
// ensuring the hash does not change when a pointer changes.
func DeepHashObject(hasher hash.Hash, objectToWrite interface{}) {
hasher.Reset()
printer := spew.ConfigState{
Indent: " ",
SortKeys: true,
DisableMethods: true,
SpewKeys: true,
}
printer.Fprintf(hasher, "%#v", objectToWrite)
fmt.Fprintf(hasher, "%v", dump.ForHash(objectToWrite))
}

View File

@ -21,7 +21,7 @@ import (
"hash/adler32"
"testing"
"github.com/davecgh/go-spew/spew"
"k8s.io/apimachinery/pkg/util/dump"
)
type A struct {
@ -93,7 +93,7 @@ func TestDeepHashObject(t *testing.T) {
}
func toString(obj interface{}) string {
return spew.Sprintf("%#v", obj)
return dump.Pretty(obj)
}
type wheel struct {

View File

@ -24,7 +24,6 @@ import (
"strings"
"testing"
"github.com/davecgh/go-spew/spew"
//nolint:staticcheck //iccheck // SA1019 Keep using deprecated module; it still seems to be maintained and the api of the recommended replacement differs
"github.com/golang/protobuf/proto"
fuzz "github.com/google/gofuzz"
@ -41,6 +40,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/serializer/json"
"k8s.io/apimachinery/pkg/runtime/serializer/protobuf"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apimachinery/pkg/util/dump"
"k8s.io/apimachinery/pkg/util/sets"
)
@ -299,7 +299,6 @@ func roundTripOfExternalType(t *testing.T, scheme *runtime.Scheme, codecFactory
//
// external -> json/protobuf -> external.
func roundTrip(t *testing.T, scheme *runtime.Scheme, codec runtime.Codec, object runtime.Object) {
printer := spew.ConfigState{DisableMethods: true}
original := object
// deep copy the original object
@ -307,8 +306,8 @@ func roundTrip(t *testing.T, scheme *runtime.Scheme, codec runtime.Codec, object
name := reflect.TypeOf(object).Elem().Name()
if !apiequality.Semantic.DeepEqual(original, object) {
t.Errorf("%v: DeepCopy altered the object, diff: %v", name, diff.ObjectReflectDiff(original, object))
t.Errorf("%s", spew.Sdump(original))
t.Errorf("%s", spew.Sdump(object))
t.Errorf("%s", dump.Pretty(original))
t.Errorf("%s", dump.Pretty(object))
return
}
@ -316,9 +315,9 @@ func roundTrip(t *testing.T, scheme *runtime.Scheme, codec runtime.Codec, object
data, err := runtime.Encode(codec, object)
if err != nil {
if runtime.IsNotRegisteredError(err) {
t.Logf("%v: not registered: %v (%s)", name, err, printer.Sprintf("%#v", object))
t.Logf("%v: not registered: %v (%s)", name, err, dump.Pretty(object))
} else {
t.Errorf("%v: %v (%s)", name, err, printer.Sprintf("%#v", object))
t.Errorf("%v: %v (%s)", name, err, dump.Pretty(object))
}
return
}
@ -335,9 +334,9 @@ func roundTrip(t *testing.T, scheme *runtime.Scheme, codec runtime.Codec, object
secondData, err := runtime.Encode(codec, object)
if err != nil {
if runtime.IsNotRegisteredError(err) {
t.Logf("%v: not registered: %v (%s)", name, err, printer.Sprintf("%#v", object))
t.Logf("%v: not registered: %v (%s)", name, err, dump.Pretty(object))
} else {
t.Errorf("%v: %v (%s)", name, err, printer.Sprintf("%#v", object))
t.Errorf("%v: %v (%s)", name, err, dump.Pretty(object))
}
return
}
@ -345,20 +344,20 @@ func roundTrip(t *testing.T, scheme *runtime.Scheme, codec runtime.Codec, object
// serialization to the wire must be stable to ensure that we don't write twice to the DB
// when the object hasn't changed.
if !bytes.Equal(data, secondData) {
t.Errorf("%v: serialization is not stable: %s", name, printer.Sprintf("%#v", object))
t.Errorf("%v: serialization is not stable: %s", name, dump.Pretty(object))
}
// decode (deserialize) the encoded data back into an object
obj2, err := runtime.Decode(codec, data)
if err != nil {
t.Errorf("%v: %v\nCodec: %#v\nData: %s\nSource: %#v", name, err, codec, dataAsString(data), printer.Sprintf("%#v", object))
t.Errorf("%v: %v\nCodec: %#v\nData: %s\nSource: %#v", name, err, codec, dataAsString(data), dump.Pretty(object))
panic("failed")
}
// ensure that the object produced from decoding the encoded data is equal
// to the original object
if !apiequality.Semantic.DeepEqual(original, obj2) {
t.Errorf("%v: diff: %v\nCodec: %#v\nSource:\n\n%#v\n\nEncoded:\n\n%s\n\nFinal:\n\n%#v", name, diff.ObjectReflectDiff(original, obj2), codec, printer.Sprintf("%#v", original), dataAsString(data), printer.Sprintf("%#v", obj2))
t.Errorf("%v: diff: %v\nCodec: %#v\nSource:\n\n%#v\n\nEncoded:\n\n%s\n\nFinal:\n\n%#v", name, diff.ObjectReflectDiff(original, obj2), codec, dump.Pretty(original), dataAsString(data), dump.Pretty(obj2))
return
}

View File

@ -23,8 +23,8 @@ import (
"strings"
"text/tabwriter"
"github.com/davecgh/go-spew/spew"
"github.com/google/go-cmp/cmp"
"k8s.io/apimachinery/pkg/util/dump"
)
// StringDiff diffs a and b and returns a human readable diff.
@ -75,13 +75,8 @@ func ObjectReflectDiff(a, b interface{}) string {
// ObjectGoPrintSideBySide prints a and b as textual dumps side by side,
// enabling easy visual scanning for mismatches.
func ObjectGoPrintSideBySide(a, b interface{}) string {
s := spew.ConfigState{
Indent: " ",
// Extra deep spew.
DisableMethods: true,
}
sA := s.Sdump(a)
sB := s.Sdump(b)
sA := dump.Pretty(a)
sB := dump.Pretty(b)
linesA := strings.Split(sA, "\n")
linesB := strings.Split(sB, "\n")

View File

@ -0,0 +1,54 @@
/*
Copyright 2021 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package dump
import (
"github.com/davecgh/go-spew/spew"
)
var prettyPrintConfig = &spew.ConfigState{
Indent: " ",
DisableMethods: true,
DisablePointerAddresses: true,
DisableCapacities: true,
}
// The config MUST NOT be changed because that could change the result of a hash operation
var prettyPrintConfigForHash = &spew.ConfigState{
Indent: " ",
SortKeys: true,
DisableMethods: true,
SpewKeys: true,
DisablePointerAddresses: true,
DisableCapacities: true,
}
// Pretty wrap the spew.Sdump with Indent, and disabled methods like error() and String()
// The output may change over time, so for guaranteed output please take more direct control
func Pretty(a interface{}) string {
return prettyPrintConfig.Sdump(a)
}
// ForHash keeps the original Spew.Sprintf format to ensure the same checksum
func ForHash(a interface{}) string {
return prettyPrintConfigForHash.Sprintf("%#v", a)
}
// OneLine outputs the object in one line
func OneLine(a interface{}) string {
return prettyPrintConfig.Sprintf("%#v", a)
}

View File

@ -0,0 +1,310 @@
/*
Copyright 2021 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package dump
import (
"fmt"
"testing"
)
func ptrint(i int) *int {
return &i
}
func ptrstr(s string) *string {
return &s
}
// custom type to test Stringer interface on non-pointer receiver.
type customString string
// String implements the Stringer interface for testing invocation
func (s customString) String() string {
return "custom string " + string(s)
}
// custom type to test error interface on non-pointer receiver.
type customError int
// Error implements the error interface for testing invocation
func (e customError) Error() string {
return fmt.Sprintf("custom error: %d", int(e))
}
// custom type to test Stringer interface on pointer receiver.
type pCustomString string
// String implements the Stringer interface for testing invocation
func (s *pCustomString) String() string {
return "custom string " + string(*s)
}
// custom type to test error interface on pointer receiver.
type pCustomError int
// Error implements the error interface for testing invocation
func (e *pCustomError) Error() string {
return fmt.Sprintf("custom error: %d", int(*e))
}
// embed is used to test embedded structures.
type embed struct {
s string
}
// embedwrap is used to test embedded structures.
type embedwrap struct {
embed
e *embed
}
func TestPretty(t *testing.T) {
tcs := customString("test")
tpcs := pCustomString("&test")
tce := customError(0)
tpce := pCustomError(0)
teb := embed{"test"}
tebw := embedwrap{teb, &teb}
testCases := []struct {
a interface{}
want string
}{
{int8(93), "(int8) 93\n"},
{int16(93), "(int16) 93\n"},
{int32(93), "(int32) 93\n"},
{int64(93), "(int64) 93\n"},
{int(-93), "(int) -93\n"},
{int8(-93), "(int8) -93\n"},
{int16(-93), "(int16) -93\n"},
{int32(-93), "(int32) -93\n"},
{int64(-93), "(int64) -93\n"},
{uint(93), "(uint) 93\n"},
{uint8(93), "(uint8) 93\n"},
{uint16(93), "(uint16) 93\n"},
{uint32(93), "(uint32) 93\n"},
{uint64(93), "(uint64) 93\n"},
{uintptr(93), "(uintptr) 0x5d\n"},
{ptrint(93), "(*int)(93)\n"},
{float32(93.76), "(float32) 93.76\n"},
{float64(93.76), "(float64) 93.76\n"},
{complex64(93i), "(complex64) (0+93i)\n"},
{complex128(93i), "(complex128) (0+93i)\n"},
{bool(true), "(bool) true\n"},
{bool(false), "(bool) false\n"},
{string("test"), "(string) (len=4) \"test\"\n"},
{ptrstr("test"), "(*string)((len=4) \"test\")\n"},
{[1]string{"arr"}, "([1]string) (len=1) {\n (string) (len=3) \"arr\"\n}\n"},
{[]string{"slice"}, "([]string) (len=1) {\n (string) (len=5) \"slice\"\n}\n"},
{tcs, "(dump.customString) (len=4) \"test\"\n"},
{&tcs, "(*dump.customString)((len=4) \"test\")\n"},
{tpcs, "(dump.pCustomString) (len=5) \"&test\"\n"},
{&tpcs, "(*dump.pCustomString)((len=5) \"&test\")\n"},
{tce, "(dump.customError) 0\n"},
{&tce, "(*dump.customError)(0)\n"},
{tpce, "(dump.pCustomError) 0\n"},
{&tpce, "(*dump.pCustomError)(0)\n"},
{
struct {
arr [1]string
slice []string
m map[string]int
}{
[1]string{"arr"},
[]string{"slice"},
map[string]int{"one": 1},
},
"(struct { arr [1]string; slice []string; m map[string]int }) {\n arr: ([1]string) (len=1) {\n (string) (len=3) \"arr\"\n },\n slice: ([]string) (len=1) {\n (string) (len=5) \"slice\"\n },\n m: (map[string]int) (len=1) {\n (string) (len=3) \"one\": (int) 1\n }\n}\n",
},
{teb, "(dump.embed) {\n s: (string) (len=4) \"test\"\n}\n"},
{tebw, "(dump.embedwrap) {\n embed: (dump.embed) {\n s: (string) (len=4) \"test\"\n },\n e: (*dump.embed)({\n s: (string) (len=4) \"test\"\n })\n}\n"},
{map[string]int{}, "(map[string]int) {\n}\n"},
{map[string]int{"one": 1}, "(map[string]int) (len=1) {\n (string) (len=3) \"one\": (int) 1\n}\n"},
{map[string]interface{}{"one": 1}, "(map[string]interface {}) (len=1) {\n (string) (len=3) \"one\": (int) 1\n}\n"},
{map[string]customString{"key": tcs}, "(map[string]dump.customString) (len=1) {\n (string) (len=3) \"key\": (dump.customString) (len=4) \"test\"\n}\n"},
{map[string]customError{"key": tce}, "(map[string]dump.customError) (len=1) {\n (string) (len=3) \"key\": (dump.customError) 0\n}\n"},
{map[string]embed{"key": teb}, "(map[string]dump.embed) (len=1) {\n (string) (len=3) \"key\": (dump.embed) {\n s: (string) (len=4) \"test\"\n }\n}\n"},
{map[string]embedwrap{"key": tebw}, "(map[string]dump.embedwrap) (len=1) {\n (string) (len=3) \"key\": (dump.embedwrap) {\n embed: (dump.embed) {\n s: (string) (len=4) \"test\"\n },\n e: (*dump.embed)({\n s: (string) (len=4) \"test\"\n })\n }\n}\n"},
}
for i, tc := range testCases {
s := Pretty(tc.a)
if tc.want != s {
t.Errorf("[%d]:\n\texpected %q\n\tgot %q", i, tc.want, s)
}
}
}
func TestForHash(t *testing.T) {
tcs := customString("test")
tpcs := pCustomString("&test")
tce := customError(0)
tpce := pCustomError(0)
teb := embed{"test"}
tebw := embedwrap{teb, &teb}
testCases := []struct {
a interface{}
want string
}{
{int8(93), "(int8)93"},
{int16(93), "(int16)93"},
{int32(93), "(int32)93"},
{int64(93), "(int64)93"},
{int(-93), "(int)-93"},
{int8(-93), "(int8)-93"},
{int16(-93), "(int16)-93"},
{int32(-93), "(int32)-93"},
{int64(-93), "(int64)-93"},
{uint(93), "(uint)93"},
{uint8(93), "(uint8)93"},
{uint16(93), "(uint16)93"},
{uint32(93), "(uint32)93"},
{uint64(93), "(uint64)93"},
{uintptr(93), "(uintptr)0x5d"},
{ptrint(93), "(*int)93"},
{float32(93.76), "(float32)93.76"},
{float64(93.76), "(float64)93.76"},
{complex64(93i), "(complex64)(0+93i)"},
{complex128(93i), "(complex128)(0+93i)"},
{bool(true), "(bool)true"},
{bool(false), "(bool)false"},
{string("test"), "(string)test"},
{ptrstr("test"), "(*string)test"},
{[1]string{"arr"}, "([1]string)[arr]"},
{[]string{"slice"}, "([]string)[slice]"},
{tcs, "(dump.customString)test"},
{&tcs, "(*dump.customString)test"},
{tpcs, "(dump.pCustomString)&test"},
{&tpcs, "(*dump.pCustomString)&test"},
{tce, "(dump.customError)0"},
{&tce, "(*dump.customError)0"},
{tpce, "(dump.pCustomError)0"},
{&tpce, "(*dump.pCustomError)0"},
{
struct {
arr [1]string
slice []string
m map[string]int
}{
[1]string{"arr"},
[]string{"slice"},
map[string]int{"one": 1},
},
"(struct { arr [1]string; slice []string; m map[string]int }){arr:([1]string)[arr] slice:([]string)[slice] m:(map[string]int)map[one:1]}",
},
{teb, "(dump.embed){s:(string)test}"},
{tebw, "(dump.embedwrap){embed:(dump.embed){s:(string)test} e:(*dump.embed){s:(string)test}}"},
{map[string]int{}, "(map[string]int)map[]"},
{map[string]int{"one": 1, "two": 2}, "(map[string]int)map[one:1 two:2]"},
{map[string]interface{}{"one": 1}, "(map[string]interface {})map[one:(int)1]"},
{map[string]customString{"key": tcs}, "(map[string]dump.customString)map[key:test]"},
{map[string]customError{"key": tce}, "(map[string]dump.customError)map[key:0]"},
{map[string]embed{"key": teb}, "(map[string]dump.embed)map[key:{s:(string)test}]"},
{map[string]embedwrap{"key": tebw}, "(map[string]dump.embedwrap)map[key:{embed:(dump.embed){s:(string)test} e:(*dump.embed){s:(string)test}}]"},
}
for i, tc := range testCases {
s := ForHash(tc.a)
if tc.want != s {
t.Errorf("[%d]:\n\texpected %q\n\tgot %q", i, tc.want, s)
}
}
}
func TestOneLine(t *testing.T) {
tcs := customString("test")
tpcs := pCustomString("&test")
tce := customError(0)
tpce := pCustomError(0)
teb := embed{"test"}
tebw := embedwrap{teb, &teb}
testCases := []struct {
a interface{}
want string
}{
{int8(93), "(int8)93"},
{int16(93), "(int16)93"},
{int32(93), "(int32)93"},
{int64(93), "(int64)93"},
{int(-93), "(int)-93"},
{int8(-93), "(int8)-93"},
{int16(-93), "(int16)-93"},
{int32(-93), "(int32)-93"},
{int64(-93), "(int64)-93"},
{uint(93), "(uint)93"},
{uint8(93), "(uint8)93"},
{uint16(93), "(uint16)93"},
{uint32(93), "(uint32)93"},
{uint64(93), "(uint64)93"},
{uintptr(93), "(uintptr)0x5d"},
{ptrint(93), "(*int)93"},
{float32(93.76), "(float32)93.76"},
{float64(93.76), "(float64)93.76"},
{complex64(93i), "(complex64)(0+93i)"},
{complex128(93i), "(complex128)(0+93i)"},
{bool(true), "(bool)true"},
{bool(false), "(bool)false"},
{string("test"), "(string)test"},
{ptrstr("test"), "(*string)test"},
{[1]string{"arr"}, "([1]string)[arr]"},
{[]string{"slice"}, "([]string)[slice]"},
{tcs, "(dump.customString)test"},
{&tcs, "(*dump.customString)test"},
{tpcs, "(dump.pCustomString)&test"},
{&tpcs, "(*dump.pCustomString)&test"},
{tce, "(dump.customError)0"},
{&tce, "(*dump.customError)0"},
{tpce, "(dump.pCustomError)0"},
{&tpce, "(*dump.pCustomError)0"},
{
struct {
arr [1]string
slice []string
m map[string]int
}{
[1]string{"arr"},
[]string{"slice"},
map[string]int{"one": 1},
},
"(struct { arr [1]string; slice []string; m map[string]int }){arr:([1]string)[arr] slice:([]string)[slice] m:(map[string]int)map[one:1]}",
},
{teb, "(dump.embed){s:(string)test}"},
{tebw, "(dump.embedwrap){embed:(dump.embed){s:(string)test} e:(*dump.embed){s:(string)test}}"},
{map[string]int{}, "(map[string]int)map[]"},
{map[string]int{"one": 1}, "(map[string]int)map[one:1]"},
{map[string]interface{}{"one": 1}, "(map[string]interface {})map[one:(int)1]"},
{map[string]customString{"key": tcs}, "(map[string]dump.customString)map[key:test]"},
{map[string]customError{"key": tce}, "(map[string]dump.customError)map[key:0]"},
{map[string]embed{"key": teb}, "(map[string]dump.embed)map[key:{s:(string)test}]"},
{map[string]embedwrap{"key": tebw}, "(map[string]dump.embedwrap)map[key:{embed:(dump.embed){s:(string)test} e:(*dump.embed){s:(string)test}}]"},
}
for i, tc := range testCases {
s := OneLine(tc.a)
if tc.want != s {
t.Errorf("[%d]:\n\texpected %q\n\tgot %q", i, tc.want, s)
}
}
}

View File

@ -20,7 +20,7 @@ import (
"fmt"
"reflect"
"github.com/davecgh/go-spew/spew"
"k8s.io/apimachinery/pkg/util/dump"
"sigs.k8s.io/yaml"
)
@ -76,7 +76,7 @@ func ToYAMLOrError(v interface{}) string {
func toYAML(v interface{}) (string, error) {
y, err := yaml.Marshal(v)
if err != nil {
return "", fmt.Errorf("yaml marshal failed:%v\n%v\n", err, spew.Sdump(v))
return "", fmt.Errorf("yaml marshal failed:%v\n%v\n", err, dump.Pretty(v))
}
return string(y), nil

View File

@ -32,12 +32,12 @@ import (
"sync"
"time"
"github.com/davecgh/go-spew/spew"
"golang.org/x/term"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/util/dump"
utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/client-go/pkg/apis/clientauthentication"
"k8s.io/client-go/pkg/apis/clientauthentication/install"
@ -81,8 +81,6 @@ func newCache() *cache {
return &cache{m: make(map[string]*Authenticator)}
}
var spewConfig = &spew.ConfigState{DisableMethods: true, Indent: " "}
func cacheKey(conf *api.ExecConfig, cluster *clientauthentication.Cluster) string {
key := struct {
conf *api.ExecConfig
@ -91,7 +89,7 @@ func cacheKey(conf *api.ExecConfig, cluster *clientauthentication.Cluster) strin
conf: conf,
cluster: cluster,
}
return spewConfig.Sprint(key)
return dump.Pretty(key)
}
type cache struct {

View File

@ -24,10 +24,9 @@ import (
"net/http"
"time"
"github.com/davecgh/go-spew/spew"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/dump"
"k8s.io/apimachinery/pkg/util/net"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/watch"
@ -191,7 +190,7 @@ func (rw *RetryWatcher) doReceive() (bool, time.Duration) {
errObject := apierrors.FromObject(event.Object)
statusErr, ok := errObject.(*apierrors.StatusError)
if !ok {
klog.Error(spew.Sprintf("Received an error which is not *metav1.Status but %#+v", event.Object))
klog.Error(fmt.Sprintf("Received an error which is not *metav1.Status but %s", dump.Pretty(event.Object)))
// Retry unknown errors
return false, 0
}
@ -220,7 +219,7 @@ func (rw *RetryWatcher) doReceive() (bool, time.Duration) {
// Log here so we have a record of hitting the unexpected error
// and we can whitelist some error codes if we missed any that are expected.
klog.V(5).Info(spew.Sprintf("Retrying after unexpected error: %#+v", event.Object))
klog.V(5).Info(fmt.Sprintf("Retrying after unexpected error: %s", dump.Pretty(event.Object)))
// Retry
return false, statusDelay

View File

@ -24,7 +24,6 @@ import (
"strings"
"time"
"github.com/davecgh/go-spew/spew"
"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"
"k8s.io/apimachinery/pkg/fields"
@ -40,6 +39,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/dump"
"k8s.io/apimachinery/pkg/util/intstr"
utilrand "k8s.io/apimachinery/pkg/util/rand"
"k8s.io/apimachinery/pkg/util/wait"
@ -626,7 +626,7 @@ func failureTrap(ctx context.Context, c clientset.Interface, ns string) {
for i := range deployments.Items {
d := deployments.Items[i]
framework.Logf(spew.Sprintf("Deployment %q:\n%+v\n", d.Name, d))
framework.Logf("Deployment %q:\n%s\n", d.Name, dump.Pretty(d))
_, allOldRSs, newRS, err := testutil.GetAllReplicaSets(&d, c)
if err != nil {
framework.Logf("Could not list ReplicaSets for Deployment %q: %v", d.Name, err)
@ -650,7 +650,7 @@ func failureTrap(ctx context.Context, c clientset.Interface, ns string) {
return
}
for _, rs := range rss.Items {
framework.Logf(spew.Sprintf("ReplicaSet %q:\n%+v\n", rs.Name, rs))
framework.Logf("ReplicaSet %q:\n%s\n", rs.Name, dump.Pretty(rs))
selector, err := metav1.LabelSelectorAsSelector(rs.Spec.Selector)
if err != nil {
framework.Logf("failed to get selector of ReplicaSet %s: %v", rs.Name, err)
@ -662,7 +662,7 @@ func failureTrap(ctx context.Context, c clientset.Interface, ns string) {
continue
}
for _, pod := range podList.Items {
framework.Logf(spew.Sprintf("pod: %q:\n%+v\n", pod.Name, pod))
framework.Logf("pod: %q:\n%s\n", pod.Name, dump.Pretty(pod))
}
}
}

View File

@ -22,13 +22,13 @@ import (
"sync"
"time"
"github.com/davecgh/go-spew/spew"
"github.com/onsi/ginkgo/v2"
v1 "k8s.io/api/core/v1"
storagev1 "k8s.io/api/storage/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/dump"
"k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/watch"
clientset "k8s.io/client-go/kubernetes"
@ -205,7 +205,7 @@ func (t *volumePerformanceTestSuite) DefineTests(driver storageframework.TestDri
ginkgo.By("Calculating performance metrics for provisioning operations")
createPerformanceStats(provisioningStats, l.options.ProvisioningOptions.Count, l.pvcs)
ginkgo.By(fmt.Sprintf("Validating performance metrics for provisioning operations against baseline %v", spew.Sdump(l.options.ProvisioningOptions.ExpectedMetrics)))
ginkgo.By(fmt.Sprintf("Validating performance metrics for provisioning operations against baseline %v", dump.Pretty(l.options.ProvisioningOptions.ExpectedMetrics)))
errList := validatePerformanceStats(provisioningStats.operationMetrics, l.options.ProvisioningOptions.ExpectedMetrics)
framework.ExpectNoError(errors.NewAggregate(errList), "while validating performance metrics")
})
@ -240,7 +240,7 @@ func createPerformanceStats(stats *performanceStats, provisionCount int, pvcs []
// validatePerformanceStats validates if test performance metrics meet the baseline target
func validatePerformanceStats(operationMetrics *storageframework.Metrics, baselineMetrics *storageframework.Metrics) []error {
var errList []error
framework.Logf("Metrics to evaluate: %+v", spew.Sdump(operationMetrics))
framework.Logf("Metrics to evaluate: %+v", dump.Pretty(operationMetrics))
if operationMetrics.AvgLatency > baselineMetrics.AvgLatency {
err := fmt.Errorf("expected latency to be less than %v but calculated latency %v", baselineMetrics.AvgLatency, operationMetrics.AvgLatency)

View File

@ -33,10 +33,10 @@ import (
"testing"
"time"
"github.com/davecgh/go-spew/spew"
"github.com/google/go-cmp/cmp"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/dump"
"k8s.io/apimachinery/pkg/util/rand"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
@ -612,7 +612,7 @@ func (is *informerSpy) waitForEvents(t *testing.T, wantEvents bool) {
if err != nil {
t.Fatalf("wanted no events, but got error: %v", err)
} else {
t.Fatalf("wanted no events, but got some: %s", spew.Sprintf("%#v", is))
t.Fatalf("wanted no events, but got some: %s", dump.Pretty(is))
}
}
}

View File

@ -21,11 +21,10 @@ import (
"fmt"
"time"
"github.com/davecgh/go-spew/spew"
apps "k8s.io/api/apps/v1"
"k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/dump"
"k8s.io/apimachinery/pkg/util/wait"
clientset "k8s.io/client-go/kubernetes"
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
@ -37,7 +36,7 @@ type LogfFn func(format string, args ...interface{})
func LogReplicaSetsOfDeployment(deployment *apps.Deployment, allOldRSs []*apps.ReplicaSet, newRS *apps.ReplicaSet, logf LogfFn) {
if newRS != nil {
logf(spew.Sprintf("New ReplicaSet %q of Deployment %q:\n%+v", newRS.Name, deployment.Name, *newRS))
logf("New ReplicaSet %q of Deployment %q:\n%s", newRS.Name, deployment.Name, dump.Pretty(*newRS))
} else {
logf("New ReplicaSet of Deployment %q is nil.", deployment.Name)
}
@ -45,7 +44,7 @@ func LogReplicaSetsOfDeployment(deployment *apps.Deployment, allOldRSs []*apps.R
logf("All old ReplicaSets of Deployment %q:", deployment.Name)
}
for i := range allOldRSs {
logf(spew.Sprintf("%+v", *allOldRSs[i]))
logf(dump.Pretty(*allOldRSs[i]))
}
}
@ -65,7 +64,7 @@ func LogPodsOfDeployment(c clientset.Interface, deployment *apps.Deployment, rsL
if podutil.IsPodAvailable(&pod, minReadySeconds, metav1.Now()) {
availability = "available"
}
logf(spew.Sprintf("Pod %q is %s:\n%+v", pod.Name, availability, pod))
logf("Pod %q is %s:\n%s", pod.Name, availability, dump.Pretty(pod))
}
}

1
vendor/modules.txt vendored
View File

@ -1355,6 +1355,7 @@ k8s.io/apimachinery/pkg/selection
k8s.io/apimachinery/pkg/types
k8s.io/apimachinery/pkg/util/cache
k8s.io/apimachinery/pkg/util/diff
k8s.io/apimachinery/pkg/util/dump
k8s.io/apimachinery/pkg/util/duration
k8s.io/apimachinery/pkg/util/errors
k8s.io/apimachinery/pkg/util/framer