mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 19:17:58 +00:00
New helper methods for generating readable loggable strings (#20911)
This commit is contained in:
81
sdk/helper/testhelpers/output.go
Normal file
81
sdk/helper/testhelpers/output.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package testhelpers
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/mitchellh/go-testing-interface"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
// ToMap renders an input value of any type as a map. This is intended for
|
||||
// logging human-readable data dumps in test logs, so it uses the `json`
|
||||
// tags on struct fields: this makes it easy to exclude `"-"` values that
|
||||
// are typically not interesting, respect omitempty, etc.
|
||||
//
|
||||
// We also replace any []byte fields with a hash of their value.
|
||||
// This is usually sufficient for test log purposes, and is a lot more readable
|
||||
// than a big array of individual byte values like Go would normally stringify a
|
||||
// byte slice.
|
||||
func ToMap(in any) (map[string]any, error) {
|
||||
temp := make(map[string]any)
|
||||
cfg := &mapstructure.DecoderConfig{
|
||||
TagName: "json",
|
||||
IgnoreUntaggedFields: true,
|
||||
Result: &temp,
|
||||
}
|
||||
md, err := mapstructure.NewDecoder(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = md.Decode(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// mapstructure doesn't call the DecodeHook for each field when doing
|
||||
// struct->map conversions, but it does for map->map, so call it a second
|
||||
// time to convert each []byte field.
|
||||
out := make(map[string]any)
|
||||
md2, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
|
||||
Result: &out,
|
||||
DecodeHook: func(from reflect.Type, to reflect.Type, data interface{}) (interface{}, error) {
|
||||
if from.Kind() != reflect.Slice || from.Elem().Kind() != reflect.Uint8 {
|
||||
return data, nil
|
||||
}
|
||||
b := data.([]byte)
|
||||
return fmt.Sprintf("%x", sha256.Sum256(b)), nil
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = md2.Decode(temp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ToString renders its input using ToMap, and returns a string containing the
|
||||
// result or an error if that fails.
|
||||
func ToString(in any) string {
|
||||
m, err := ToMap(in)
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
return fmt.Sprintf("%v", m)
|
||||
}
|
||||
|
||||
// StringOrDie renders its input using ToMap, and returns a string containing the
|
||||
// result. If rendering yields an error, calls t.Fatal.
|
||||
func StringOrDie(t testing.T, in any) string {
|
||||
t.Helper()
|
||||
m, err := ToMap(in)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return fmt.Sprintf("%v", m)
|
||||
}
|
||||
45
sdk/helper/testhelpers/output_test.go
Normal file
45
sdk/helper/testhelpers/output_test.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package testhelpers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestToMap(t *testing.T) {
|
||||
type s struct {
|
||||
A string `json:"a"`
|
||||
B []byte `json:"b"`
|
||||
C map[string]string `json:"c"`
|
||||
D string `json:"-"`
|
||||
}
|
||||
type args struct {
|
||||
in s
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "basic",
|
||||
args: args{s{A: "a", B: []byte("bytes"), C: map[string]string{"k": "v"}, D: "d"}},
|
||||
want: "map[a:a b:277089d91c0bdf4f2e6862ba7e4a07605119431f5d13f726dd352b06f1b206a9 c:map[k:v]]",
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m, err := ToMap(&tt.args.in)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ToMap() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
got := fmt.Sprintf("%s", m)
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("ToMap() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user