func TestProto3SetDefaults(t *testing.T) { in := &pb.Message{ Terrain: map[string]*pb.Nested{ "meadow": new(pb.Nested), }, Proto2Field: new(tpb.SubDefaults), Proto2Value: map[string]*tpb.SubDefaults{ "badlands": new(tpb.SubDefaults), }, } got := proto.Clone(in).(*pb.Message) proto.SetDefaults(got) // There are no defaults in proto3. Everything should be the zero value, but // we need to remember to set defaults for nested proto2 messages. want := &pb.Message{ Terrain: map[string]*pb.Nested{ "meadow": new(pb.Nested), }, Proto2Field: &tpb.SubDefaults{N: proto.Int64(7)}, Proto2Value: map[string]*tpb.SubDefaults{ "badlands": {N: proto.Int64(7)}, }, } if !proto.Equal(got, want) { t.Errorf("with in = %v\nproto.SetDefaults(in) =>\ngot %v\nwant %v", in, got, want) } }
func readHealthcheck(f string) (*pb.Healthcheck, error) { p := &pb.Healthcheck{} b, err := ioutil.ReadFile(f) if err != nil { return nil, err } if err = proto.UnmarshalText(string(b), p); err != nil { return nil, err } proto.SetDefaults(p) return p, nil }
func fuzz(data []byte, text bool) int { ctors := []func() proto.Message{ func() proto.Message { return new(pb.M0) }, func() proto.Message { return new(pb.M1) }, func() proto.Message { return new(pb.M2) }, func() proto.Message { return new(pb.M3) }, func() proto.Message { return new(pb.M4) }, func() proto.Message { return new(pb.M5) }, func() proto.Message { return new(pb.M6) }, func() proto.Message { return new(pb.M7) }, func() proto.Message { return new(pb.M8) }, func() proto.Message { return new(pb.M9) }, func() proto.Message { return new(pb.M10) }, func() proto.Message { return new(pb.M11) }, func() proto.Message { return new(pb.M12) }, func() proto.Message { return new(pb.M13) }, func() proto.Message { return new(pb.M14) }, func() proto.Message { return new(pb.M15) }, func() proto.Message { return new(pb.M16) }, func() proto.Message { return new(pb.M17) }, func() proto.Message { return new(pb.M18) }, func() proto.Message { return new(pb.M19) }, func() proto.Message { return new(pb.M20) }, func() proto.Message { return new(pb.M21) }, func() proto.Message { return new(pb.M22) }, func() proto.Message { return new(pb.M23) }, func() proto.Message { return new(pb.M24) }, func() proto.Message { return new(pb.M25) }, } datas := "" if text { datas = string(data) } score := 0 for _, ctor := range ctors { v := ctor() var err error if text { err = proto.UnmarshalText(datas, v) } else { err = proto.Unmarshal(data, v) } if err != nil { continue } score = 1 sz := proto.Size(v) var data1 []byte if text { var buf bytes.Buffer err = proto.MarshalText(&buf, v) data1 = buf.Bytes() } else { data1, err = proto.Marshal(v) } if err != nil { panic(err) } v1 := ctor() if text { err = proto.UnmarshalText(string(data1), v1) } else { if sz != len(data1) { panic(fmt.Sprintf("Size returned %v, while Marshal returned %v", sz, len(data1))) } err = proto.Unmarshal(data1, v1) } if err != nil { panic(err) } if !DeepEqual(v, v1) { fmt.Printf("v0: %#v\n", v) fmt.Printf("v1: %#v\n", v1) panic(fmt.Sprintf("non idempotent marshal of %T", v)) } if !proto.Equal(v, v1) { fmt.Printf("v0: %#v\n", v) fmt.Printf("v1: %#v\n", v1) panic(fmt.Sprintf("non idempotent marshal of %T", v)) } if text { // TODO: Marshal/Unmarshal to binary. } else { var buf bytes.Buffer err := proto.MarshalText(&buf, v) if err != nil { fmt.Printf("failed to MarshalText: %#v\n", v) panic(err) } v2 := ctor() err = proto.UnmarshalText(buf.String(), v2) if err != nil { if strings.Contains(err.Error(), "unexpected byte 0x2f") { continue // known bug } fmt.Printf("failed to UnmarshalText: %q\n", buf.Bytes()) panic(err) } if !proto.Equal(v, v2) { fmt.Printf("v0: %#v\n", v) fmt.Printf("v2: %#v\n", v2) panic(fmt.Sprintf("non idempotent text marshal of %T", v)) } } v3 := proto.Clone(v) if !DeepEqual(v, v3) { fmt.Printf("v0: %#v\n", v) fmt.Printf("v3: %#v\n", v3) panic(fmt.Sprintf("bad clone of %T", v)) } proto.SetDefaults(v3) if !proto.Equal(v, v3) { fmt.Printf("v0: %#v\n", v) fmt.Printf("v3: %#v\n", v3) panic(fmt.Sprintf("SetDefaults changed data %T", v)) } proto.Merge(v3, v1) if idempotentMerge(v) && !proto.Equal(v, v3) { fmt.Printf("v0: %#v\n", v) fmt.Printf("v3: %#v\n", v3) panic(fmt.Sprintf("Merge changed data %T", v)) } } return score }