mirror of https://github.com/grpc/grpc-go.git
attributes: print typed nil values instead of panic (#6574)
Co-authored-by: Easwar Swaminathan <easwars@google.com>
This commit is contained in:
parent
fe0dc2275d
commit
58e2f2b105
|
|
@ -121,13 +121,13 @@ func (a *Attributes) String() string {
|
|||
return sb.String()
|
||||
}
|
||||
|
||||
func str(x any) string {
|
||||
func str(x any) (s string) {
|
||||
if v, ok := x.(fmt.Stringer); ok {
|
||||
return v.String()
|
||||
return fmt.Sprint(v)
|
||||
} else if v, ok := x.(string); ok {
|
||||
return v
|
||||
}
|
||||
return fmt.Sprintf("<%p>", x)
|
||||
return fmt.Sprintf("%#v", x)
|
||||
}
|
||||
|
||||
// MarshalJSON helps implement the json.Marshaler interface, thereby rendering
|
||||
|
|
|
|||
|
|
@ -34,6 +34,14 @@ func (s stringVal) Equal(o any) bool {
|
|||
return ok && s.s == os.s
|
||||
}
|
||||
|
||||
type stringerVal struct {
|
||||
s string
|
||||
}
|
||||
|
||||
func (s stringerVal) String() string {
|
||||
return s.s
|
||||
}
|
||||
|
||||
func ExampleAttributes() {
|
||||
type keyOne struct{}
|
||||
type keyTwo struct{}
|
||||
|
|
@ -57,6 +65,36 @@ func ExampleAttributes_WithValue() {
|
|||
// Key two: {two}
|
||||
}
|
||||
|
||||
func ExampleAttributes_String() {
|
||||
type key struct{}
|
||||
var typedNil *stringerVal
|
||||
a1 := attributes.New(key{}, typedNil) // typed nil implements [fmt.Stringer]
|
||||
a2 := attributes.New(key{}, (*stringerVal)(nil)) // typed nil implements [fmt.Stringer]
|
||||
a3 := attributes.New(key{}, (*stringVal)(nil)) // typed nil not implements [fmt.Stringer]
|
||||
a4 := attributes.New(key{}, nil) // untyped nil
|
||||
a5 := attributes.New(key{}, 1)
|
||||
a6 := attributes.New(key{}, stringerVal{s: "two"})
|
||||
a7 := attributes.New(key{}, stringVal{s: "two"})
|
||||
a8 := attributes.New(1, true)
|
||||
fmt.Println("a1:", a1.String())
|
||||
fmt.Println("a2:", a2.String())
|
||||
fmt.Println("a3:", a3.String())
|
||||
fmt.Println("a4:", a4.String())
|
||||
fmt.Println("a5:", a5.String())
|
||||
fmt.Println("a6:", a6.String())
|
||||
fmt.Println("a7:", a7.String())
|
||||
fmt.Println("a8:", a8.String())
|
||||
// Output:
|
||||
// a1: {"attributes_test.key{}": "<nil>" }
|
||||
// a2: {"attributes_test.key{}": "<nil>" }
|
||||
// a3: {"attributes_test.key{}": "(*attributes_test.stringVal)(nil)" }
|
||||
// a4: {"attributes_test.key{}": "<nil>" }
|
||||
// a5: {"attributes_test.key{}": "1" }
|
||||
// a6: {"attributes_test.key{}": "two" }
|
||||
// a7: {"attributes_test.key{}": "attributes_test.stringVal{s:\"two\"}" }
|
||||
// a8: {"1": "true" }
|
||||
}
|
||||
|
||||
// Test that two attributes with the same content are Equal.
|
||||
func TestEqual(t *testing.T) {
|
||||
type keyOne struct{}
|
||||
|
|
|
|||
|
|
@ -142,3 +142,23 @@ func (s) TestResolverAddressesToEndpoints(t *testing.T) {
|
|||
t.Fatalf("timed out waiting for endpoints")
|
||||
}
|
||||
}
|
||||
|
||||
// Test ensures that there is no panic if the attributes within
|
||||
// resolver.State.Addresses contains a typed-nil value.
|
||||
func (s) TestResolverAddressesWithTypedNilAttribute(t *testing.T) {
|
||||
r := manual.NewBuilderWithScheme(t.Name())
|
||||
resolver.Register(r)
|
||||
|
||||
addrAttr := attributes.New("typed_nil", (*stringerVal)(nil))
|
||||
r.InitialState(resolver.State{Addresses: []resolver.Address{{Addr: "addr1", Attributes: addrAttr}}})
|
||||
|
||||
cc, err := Dial(r.Scheme()+":///", WithTransportCredentials(insecure.NewCredentials()), WithResolvers(r))
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error dialing: %v", err)
|
||||
}
|
||||
defer cc.Close()
|
||||
}
|
||||
|
||||
type stringerVal struct{ s string }
|
||||
|
||||
func (s stringerVal) String() string { return s.s }
|
||||
|
|
|
|||
Loading…
Reference in New Issue