xref: /aosp_15_r20/external/golang-protobuf/encoding/protodelim/protodelim_test.go (revision 1c12ee1efe575feb122dbf939ff15148a3b3e8f2)
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