mirror of https://github.com/status-im/consul.git
proto: Add a round trip test for converting types
This commit is contained in:
parent
627449a870
commit
20236e9b6e
|
@ -74,7 +74,7 @@ func NewCheckServiceNodeFromStructs(t *structs.CheckServiceNode) *CheckServiceNo
|
||||||
r := NewNodeServiceFromStructs(*t.Service)
|
r := NewNodeServiceFromStructs(*t.Service)
|
||||||
s.Service = &r
|
s.Service = &r
|
||||||
}
|
}
|
||||||
t.Checks = make(structs.HealthChecks, len(t.Checks))
|
s.Checks = make([]*HealthCheck, len(t.Checks))
|
||||||
for i, c := range t.Checks {
|
for i, c := range t.Checks {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
package pbservice
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
|
"github.com/google/go-cmp/cmp/cmpopts"
|
||||||
|
fuzz "github.com/google/gofuzz"
|
||||||
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewCheckServiceNodeFromStructs_RoundTrip(t *testing.T) {
|
||||||
|
repeat(t, func(t *testing.T, fuzzer *fuzz.Fuzzer) {
|
||||||
|
fuzzer.Funcs(randInt32, randUint32, randInterface, randStructsUpstream)
|
||||||
|
var target structs.CheckServiceNode
|
||||||
|
fuzzer.Fuzz(&target)
|
||||||
|
|
||||||
|
result := CheckServiceNodeToStructs(NewCheckServiceNodeFromStructs(&target))
|
||||||
|
assertEqual(t, &target, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func repeat(t *testing.T, fn func(t *testing.T, fuzzer *fuzz.Fuzzer)) {
|
||||||
|
reps := getEnvIntWithDefault(t, "TEST_REPEAT_COUNT", 5)
|
||||||
|
seed := getEnvIntWithDefault(t, "TEST_RANDOM_SEED", time.Now().UnixNano())
|
||||||
|
t.Logf("using seed %d for %d repetitions", seed, reps)
|
||||||
|
|
||||||
|
fuzzer := fuzz.NewWithSeed(seed)
|
||||||
|
for i := 0; i < int(reps); i++ {
|
||||||
|
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||||
|
fn(t, fuzzer)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getEnvIntWithDefault(t *testing.T, key string, d int64) int64 {
|
||||||
|
t.Helper()
|
||||||
|
raw, ok := os.LookupEnv(key)
|
||||||
|
if !ok {
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
v, err := strconv.Atoi(raw)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("invald value for %v: %v", key, err.Error())
|
||||||
|
}
|
||||||
|
return int64(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertEqual(t *testing.T, x, y interface{}) {
|
||||||
|
t.Helper()
|
||||||
|
if diff := cmp.Diff(x, y, cmpopts.EquateEmpty()); diff != "" {
|
||||||
|
t.Fatalf("assertion failed: values are not equal\n--- original\n+++ result\n\n%v", diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// randUint32 is a custom fuzzer function which limits all uints to 32 bits.
|
||||||
|
// This is necessary because the structs types use un-sized uints, however in
|
||||||
|
// practice they are constrained to 32 bits, and the protobuf types use (u)int32.
|
||||||
|
// The structs types use (u)int64 for any fields that require 64 bits.
|
||||||
|
func randUint32(i *uint, c fuzz.Continue) {
|
||||||
|
*i = uint(c.Rand.Uint32())
|
||||||
|
}
|
||||||
|
|
||||||
|
// see randUint32
|
||||||
|
func randInt32(i *int, c fuzz.Continue) {
|
||||||
|
*i = int(c.Rand.Int31())
|
||||||
|
}
|
||||||
|
|
||||||
|
// randStructsUpstream is a custom fuzzer function which skips generating values
|
||||||
|
// for fields enumerated in the ignore-fields annotation.
|
||||||
|
func randStructsUpstream(u *structs.Upstream, c fuzz.Continue) {
|
||||||
|
v := reflect.ValueOf(u).Elem()
|
||||||
|
for i := 0; i < v.NumField(); i++ {
|
||||||
|
switch v.Type().Field(i).Name {
|
||||||
|
case "IngressHosts":
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
c.Fuzz(v.Field(i).Addr().Interface())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// randInterface is a custom fuzzer function which generates random data for
|
||||||
|
// interface{} (most likely used in a map[string]interface{}).
|
||||||
|
// The random data does not contain any ints (or float32) because protobuf
|
||||||
|
// converts them to float64, which will cause the test to fail.
|
||||||
|
func randInterface(m *interface{}, c fuzz.Continue) {
|
||||||
|
switch c.Rand.Intn(6) {
|
||||||
|
case 0:
|
||||||
|
*m = nil
|
||||||
|
case 1:
|
||||||
|
*m = c.RandBool()
|
||||||
|
case 2:
|
||||||
|
*m = c.Rand.Float64()
|
||||||
|
case 3:
|
||||||
|
*m = c.RandString()
|
||||||
|
case 4:
|
||||||
|
*m = []interface{}{c.RandString(), c.RandBool(), nil, c.Rand.Float64()}
|
||||||
|
case 5:
|
||||||
|
*m = map[string]interface{}{
|
||||||
|
c.RandString(): c.RandString(),
|
||||||
|
c.RandString(): c.Rand.Float64(),
|
||||||
|
c.RandString(): nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue