1// Copyright 2022 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package protodelim_test 6 7import ( 8 "bufio" 9 "bytes" 10 "errors" 11 "io" 12 "testing" 13 14 "github.com/google/go-cmp/cmp" 15 "google.golang.org/protobuf/encoding/protodelim" 16 "google.golang.org/protobuf/encoding/protowire" 17 "google.golang.org/protobuf/internal/testprotos/test3" 18 "google.golang.org/protobuf/testing/protocmp" 19) 20 21func TestRoundTrip(t *testing.T) { 22 msgs := []*test3.TestAllTypes{ 23 {SingularInt32: 1}, 24 {SingularString: "hello"}, 25 {RepeatedDouble: []float64{1.2, 3.4}}, 26 { 27 SingularNestedMessage: &test3.TestAllTypes_NestedMessage{A: 1}, 28 RepeatedForeignMessage: []*test3.ForeignMessage{{C: 2}, {D: 3}}, 29 }, 30 } 31 32 buf := &bytes.Buffer{} 33 34 // Write all messages to buf. 35 for _, m := range msgs { 36 if n, err := protodelim.MarshalTo(buf, m); err != nil { 37 t.Errorf("protodelim.MarshalTo(_, %v) = %d, %v", m, n, err) 38 } 39 } 40 41 // Read and collect messages from buf. 42 var got []*test3.TestAllTypes 43 r := bufio.NewReader(buf) 44 for { 45 m := &test3.TestAllTypes{} 46 err := protodelim.UnmarshalFrom(r, m) 47 if errors.Is(err, io.EOF) { 48 break 49 } 50 if err != nil { 51 t.Errorf("protodelim.UnmarshalFrom(_) = %v", err) 52 continue 53 } 54 got = append(got, m) 55 } 56 57 want := msgs 58 if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" { 59 t.Errorf("Unmarshaler collected messages: diff -want +got = %s", diff) 60 } 61} 62 63func TestMaxSize(t *testing.T) { 64 in := &test3.TestAllTypes{SingularInt32: 1} 65 66 buf := &bytes.Buffer{} 67 68 if n, err := protodelim.MarshalTo(buf, in); err != nil { 69 t.Errorf("protodelim.MarshalTo(_, %v) = %d, %v", in, n, err) 70 } 71 72 out := &test3.TestAllTypes{} 73 err := protodelim.UnmarshalOptions{MaxSize: 1}.UnmarshalFrom(bufio.NewReader(buf), out) 74 75 var errSize *protodelim.SizeTooLargeError 76 if !errors.As(err, &errSize) { 77 t.Errorf("protodelim.UnmarshalOptions{MaxSize: 1}.UnmarshalFrom(_, _) = %v (%T), want %T", err, err, errSize) 78 } 79 got, want := errSize, &protodelim.SizeTooLargeError{Size: 3, MaxSize: 1} 80 if diff := cmp.Diff(want, got); diff != "" { 81 t.Errorf("protodelim.UnmarshalOptions{MaxSize: 1}.UnmarshalFrom(_, _): diff -want +got = %s", diff) 82 } 83} 84 85func TestUnmarshalFrom_UnexpectedEOF(t *testing.T) { 86 buf := &bytes.Buffer{} 87 88 // Write a size (42), but no subsequent message. 89 sb := protowire.AppendVarint(nil, 42) 90 if _, err := buf.Write(sb); err != nil { 91 t.Fatalf("buf.Write(%v) = _, %v", sb, err) 92 } 93 94 out := &test3.TestAllTypes{} 95 err := protodelim.UnmarshalFrom(bufio.NewReader(buf), out) 96 if got, want := err, io.ErrUnexpectedEOF; got != want { 97 t.Errorf("protodelim.UnmarshalFrom(size-only buf, _) = %v, want %v", got, want) 98 } 99} 100