1 // Copyright (C) 2018 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <android-base/file.h>
16 #include <android-base/test_utils.h>
17 #include <android/util/protobuf.h>
18 #include <android/util/ProtoOutputStream.h>
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21
22 #include "frameworks/base/libs/protoutil/tests/test.pb.h"
23
24 using android::sp;
25 using namespace android::base;
26 using namespace android::util;
27 using ::testing::StrEq;
28
flushToString(ProtoOutputStream * proto)29 static std::string flushToString(ProtoOutputStream* proto) {
30 TemporaryFile tf;
31 std::string content;
32
33 EXPECT_NE(tf.fd, -1);
34 EXPECT_TRUE(proto->flush(tf.fd));
35 EXPECT_TRUE(ReadFileToString(tf.path, &content));
36 return content;
37 }
38
iterateToString(ProtoOutputStream * proto)39 static std::string iterateToString(ProtoOutputStream* proto) {
40 std::string content;
41 content.reserve(proto->size());
42 sp<ProtoReader> reader = proto->data();
43 while (reader->hasNext()) {
44 content.push_back(reader->next());
45 }
46 return content;
47 }
48
TEST(ProtoOutputStreamTest,Primitives)49 TEST(ProtoOutputStreamTest, Primitives) {
50 std::string s = "hello";
51 const char b[5] = { 'a', 'p', 'p', 'l', 'e' };
52
53 ProtoOutputStream proto;
54 EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | PrimitiveProto::kValInt32FieldNumber, 123));
55 EXPECT_TRUE(proto.write(FIELD_TYPE_INT64 | PrimitiveProto::kValInt64FieldNumber, -1LL));
56 EXPECT_TRUE(proto.write(FIELD_TYPE_FLOAT | PrimitiveProto::kValFloatFieldNumber, -23.5f));
57 EXPECT_TRUE(proto.write(FIELD_TYPE_DOUBLE | PrimitiveProto::kValDoubleFieldNumber, 324.5));
58 EXPECT_TRUE(proto.write(FIELD_TYPE_UINT32 | PrimitiveProto::kValUint32FieldNumber, 3424));
59 EXPECT_TRUE(proto.write(FIELD_TYPE_UINT64 | PrimitiveProto::kValUint64FieldNumber, 57LL));
60 EXPECT_TRUE(proto.write(FIELD_TYPE_FIXED32 | PrimitiveProto::kValFixed32FieldNumber, -20));
61 EXPECT_TRUE(proto.write(FIELD_TYPE_FIXED64 | PrimitiveProto::kValFixed64FieldNumber, -37LL));
62 EXPECT_TRUE(proto.write(FIELD_TYPE_BOOL | PrimitiveProto::kValBoolFieldNumber, true));
63 EXPECT_TRUE(proto.write(FIELD_TYPE_STRING | PrimitiveProto::kValStringFieldNumber, s));
64 EXPECT_TRUE(proto.write(FIELD_TYPE_BYTES | PrimitiveProto::kValBytesFieldNumber, b, 5));
65 EXPECT_TRUE(proto.write(FIELD_TYPE_SFIXED32 | PrimitiveProto::kValSfixed32FieldNumber, 63));
66 EXPECT_TRUE(proto.write(FIELD_TYPE_SFIXED64 | PrimitiveProto::kValSfixed64FieldNumber, -54));
67 EXPECT_TRUE(proto.write(FIELD_TYPE_SINT32 | PrimitiveProto::kValSint32FieldNumber, -533));
68 EXPECT_TRUE(proto.write(FIELD_TYPE_SINT64 | PrimitiveProto::kValSint64FieldNumber, -61224762453LL));
69 EXPECT_TRUE(proto.write(FIELD_TYPE_ENUM | PrimitiveProto::kValEnumFieldNumber, 2));
70
71 PrimitiveProto primitives;
72 ASSERT_TRUE(primitives.ParseFromString(flushToString(&proto)));
73 EXPECT_EQ(primitives.val_int32(), 123);
74 EXPECT_EQ(primitives.val_int64(), -1);
75 EXPECT_EQ(primitives.val_float(), -23.5f);
76 EXPECT_EQ(primitives.val_double(), 324.5f);
77 EXPECT_EQ(primitives.val_uint32(), 3424);
78 EXPECT_EQ(primitives.val_uint64(), 57);
79 EXPECT_EQ(primitives.val_fixed32(), -20);
80 EXPECT_EQ(primitives.val_fixed64(), -37);
81 EXPECT_EQ(primitives.val_bool(), true);
82 EXPECT_THAT(primitives.val_string(), StrEq(s.c_str()));
83 EXPECT_THAT(primitives.val_bytes(), StrEq("apple"));
84 EXPECT_EQ(primitives.val_sfixed32(), 63);
85 EXPECT_EQ(primitives.val_sfixed64(), -54);
86 EXPECT_EQ(primitives.val_sint32(), -533);
87 EXPECT_EQ(primitives.val_sint64(), -61224762453LL);
88 EXPECT_EQ(primitives.val_enum(), PrimitiveProto_Count_TWO);
89 }
90
TEST(ProtoOutputStreamTest,SerializeToStringPrimitives)91 TEST(ProtoOutputStreamTest, SerializeToStringPrimitives) {
92 std::string s = "hello";
93 const char b[5] = { 'a', 'p', 'p', 'l', 'e' };
94
95 ProtoOutputStream proto;
96 EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | PrimitiveProto::kValInt32FieldNumber, 123));
97 EXPECT_TRUE(proto.write(FIELD_TYPE_INT64 | PrimitiveProto::kValInt64FieldNumber, -1LL));
98 EXPECT_TRUE(proto.write(FIELD_TYPE_FLOAT | PrimitiveProto::kValFloatFieldNumber, -23.5f));
99 EXPECT_TRUE(proto.write(FIELD_TYPE_DOUBLE | PrimitiveProto::kValDoubleFieldNumber, 324.5));
100 EXPECT_TRUE(proto.write(FIELD_TYPE_UINT32 | PrimitiveProto::kValUint32FieldNumber, 3424));
101 EXPECT_TRUE(proto.write(FIELD_TYPE_UINT64 | PrimitiveProto::kValUint64FieldNumber, 57LL));
102 EXPECT_TRUE(proto.write(FIELD_TYPE_FIXED32 | PrimitiveProto::kValFixed32FieldNumber, -20));
103 EXPECT_TRUE(proto.write(FIELD_TYPE_FIXED64 | PrimitiveProto::kValFixed64FieldNumber, -37LL));
104 EXPECT_TRUE(proto.write(FIELD_TYPE_BOOL | PrimitiveProto::kValBoolFieldNumber, true));
105 EXPECT_TRUE(proto.write(FIELD_TYPE_STRING | PrimitiveProto::kValStringFieldNumber, s));
106 EXPECT_TRUE(proto.write(FIELD_TYPE_BYTES | PrimitiveProto::kValBytesFieldNumber, b, 5));
107 EXPECT_TRUE(proto.write(FIELD_TYPE_SFIXED32 | PrimitiveProto::kValSfixed32FieldNumber, 63));
108 EXPECT_TRUE(proto.write(FIELD_TYPE_SFIXED64 | PrimitiveProto::kValSfixed64FieldNumber, -54));
109 EXPECT_TRUE(proto.write(FIELD_TYPE_SINT32 | PrimitiveProto::kValSint32FieldNumber, -533));
110 EXPECT_TRUE(proto.write(FIELD_TYPE_SINT64 | PrimitiveProto::kValSint64FieldNumber, -61224762453LL));
111 EXPECT_TRUE(proto.write(FIELD_TYPE_ENUM | PrimitiveProto::kValEnumFieldNumber, 2));
112
113 PrimitiveProto primitives;
114 std::string serialized;
115 ASSERT_TRUE(proto.serializeToString(&serialized));
116 ASSERT_TRUE(primitives.ParseFromString(serialized));
117 EXPECT_EQ(primitives.val_int32(), 123);
118 EXPECT_EQ(primitives.val_int64(), -1);
119 EXPECT_EQ(primitives.val_float(), -23.5f);
120 EXPECT_EQ(primitives.val_double(), 324.5f);
121 EXPECT_EQ(primitives.val_uint32(), 3424);
122 EXPECT_EQ(primitives.val_uint64(), 57);
123 EXPECT_EQ(primitives.val_fixed32(), -20);
124 EXPECT_EQ(primitives.val_fixed64(), -37);
125 EXPECT_EQ(primitives.val_bool(), true);
126 EXPECT_THAT(primitives.val_string(), StrEq(s.c_str()));
127 EXPECT_THAT(primitives.val_bytes(), StrEq("apple"));
128 EXPECT_EQ(primitives.val_sfixed32(), 63);
129 EXPECT_EQ(primitives.val_sfixed64(), -54);
130 EXPECT_EQ(primitives.val_sint32(), -533);
131 EXPECT_EQ(primitives.val_sint64(), -61224762453LL);
132 EXPECT_EQ(primitives.val_enum(), PrimitiveProto_Count_TWO);
133 }
134
TEST(ProtoOutputStreamTest,SerializeToVectorPrimitives)135 TEST(ProtoOutputStreamTest, SerializeToVectorPrimitives) {
136 std::string s = "hello";
137 const char b[5] = { 'a', 'p', 'p', 'l', 'e' };
138
139 ProtoOutputStream proto;
140 EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | PrimitiveProto::kValInt32FieldNumber, 123));
141 EXPECT_TRUE(proto.write(FIELD_TYPE_INT64 | PrimitiveProto::kValInt64FieldNumber, -1LL));
142 EXPECT_TRUE(proto.write(FIELD_TYPE_FLOAT | PrimitiveProto::kValFloatFieldNumber, -23.5f));
143 EXPECT_TRUE(proto.write(FIELD_TYPE_DOUBLE | PrimitiveProto::kValDoubleFieldNumber, 324.5));
144 EXPECT_TRUE(proto.write(FIELD_TYPE_UINT32 | PrimitiveProto::kValUint32FieldNumber, 3424));
145 EXPECT_TRUE(proto.write(FIELD_TYPE_UINT64 | PrimitiveProto::kValUint64FieldNumber, 57LL));
146 EXPECT_TRUE(proto.write(FIELD_TYPE_FIXED32 | PrimitiveProto::kValFixed32FieldNumber, -20));
147 EXPECT_TRUE(proto.write(FIELD_TYPE_FIXED64 | PrimitiveProto::kValFixed64FieldNumber, -37LL));
148 EXPECT_TRUE(proto.write(FIELD_TYPE_BOOL | PrimitiveProto::kValBoolFieldNumber, true));
149 EXPECT_TRUE(proto.write(FIELD_TYPE_STRING | PrimitiveProto::kValStringFieldNumber, s));
150 EXPECT_TRUE(proto.write(FIELD_TYPE_BYTES | PrimitiveProto::kValBytesFieldNumber, b, 5));
151 EXPECT_TRUE(proto.write(FIELD_TYPE_SFIXED32 | PrimitiveProto::kValSfixed32FieldNumber, 63));
152 EXPECT_TRUE(proto.write(FIELD_TYPE_SFIXED64 | PrimitiveProto::kValSfixed64FieldNumber, -54));
153 EXPECT_TRUE(proto.write(FIELD_TYPE_SINT32 | PrimitiveProto::kValSint32FieldNumber, -533));
154 EXPECT_TRUE(proto.write(FIELD_TYPE_SINT64 | PrimitiveProto::kValSint64FieldNumber, -61224762453LL));
155 EXPECT_TRUE(proto.write(FIELD_TYPE_ENUM | PrimitiveProto::kValEnumFieldNumber, 2));
156
157 PrimitiveProto primitives;
158 std::vector<uint8_t> vec;
159 ASSERT_TRUE(proto.serializeToVector(&vec));
160
161 std::string serialized(vec.data(), vec.data() + vec.size());
162 ASSERT_TRUE(primitives.ParseFromString(serialized));
163
164 EXPECT_EQ(primitives.val_int32(), 123);
165 EXPECT_EQ(primitives.val_int64(), -1);
166 EXPECT_EQ(primitives.val_float(), -23.5f);
167 EXPECT_EQ(primitives.val_double(), 324.5f);
168 EXPECT_EQ(primitives.val_uint32(), 3424);
169 EXPECT_EQ(primitives.val_uint64(), 57);
170 EXPECT_EQ(primitives.val_fixed32(), -20);
171 EXPECT_EQ(primitives.val_fixed64(), -37);
172 EXPECT_EQ(primitives.val_bool(), true);
173 EXPECT_THAT(primitives.val_string(), StrEq(s.c_str()));
174 EXPECT_THAT(primitives.val_bytes(), StrEq("apple"));
175 EXPECT_EQ(primitives.val_sfixed32(), 63);
176 EXPECT_EQ(primitives.val_sfixed64(), -54);
177 EXPECT_EQ(primitives.val_sint32(), -533);
178 EXPECT_EQ(primitives.val_sint64(), -61224762453LL);
179 EXPECT_EQ(primitives.val_enum(), PrimitiveProto_Count_TWO);
180 }
181
TEST(ProtoOutputStreamTest,Complex)182 TEST(ProtoOutputStreamTest, Complex) {
183 std::string name1 = "cat";
184 std::string name2 = "dog";
185 const char data1[6] = { 'f', 'u', 'n', 'n', 'y', '!' };
186 const char data2[4] = { 'f', 'o', 'o', 'd' };
187
188 ProtoOutputStream proto;
189 EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 23));
190 EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 101));
191 EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, -72));
192 uint64_t token1 = proto.start(FIELD_TYPE_MESSAGE | ComplexProto::kLogsFieldNumber);
193 EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 12));
194 EXPECT_TRUE(proto.write(FIELD_TYPE_STRING | ComplexProto::Log::kNameFieldNumber, name1));
195 // specify the length to test the write(id, bytes, length) function.
196 EXPECT_TRUE(proto.write(FIELD_TYPE_BYTES | ComplexProto::Log::kDataFieldNumber, data1, 5));
197 proto.end(token1);
198 uint64_t token2 = proto.start(FIELD_TYPE_MESSAGE | ComplexProto::kLogsFieldNumber);
199 EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 98));
200 EXPECT_TRUE(proto.write(FIELD_TYPE_STRING | ComplexProto::Log::kNameFieldNumber, name2));
201 EXPECT_TRUE(proto.write(FIELD_TYPE_BYTES | ComplexProto::Log::kDataFieldNumber, data2, 4));
202 proto.end(token2);
203
204 ComplexProto complex;
205 ASSERT_TRUE(complex.ParseFromString(iterateToString(&proto)));
206 EXPECT_EQ(complex.ints_size(), 3);
207 EXPECT_EQ(complex.ints(0), 23);
208 EXPECT_EQ(complex.ints(1), 101);
209 EXPECT_EQ(complex.ints(2), -72);
210 EXPECT_EQ(complex.logs_size(), 2);
211 ComplexProto::Log log1 = complex.logs(0);
212 EXPECT_EQ(log1.id(), 12);
213 EXPECT_THAT(log1.name(), StrEq(name1.c_str()));
214 EXPECT_THAT(log1.data(), StrEq("funny")); // should not contain '!'
215 ComplexProto::Log log2 = complex.logs(1);
216 EXPECT_EQ(log2.id(), 98);
217 EXPECT_THAT(log2.name(), StrEq(name2.c_str()));
218 EXPECT_THAT(log2.data(), StrEq("food"));
219 }
220
TEST(ProtoOutputStreamTest,SerializeToStringComplex)221 TEST(ProtoOutputStreamTest, SerializeToStringComplex) {
222 std::string name1 = "cat";
223 std::string name2 = "dog";
224 const char data1[6] = { 'f', 'u', 'n', 'n', 'y', '!' };
225 const char data2[4] = { 'f', 'o', 'o', 'd' };
226
227 ProtoOutputStream proto;
228 EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 23));
229 EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 101));
230 EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, -72));
231 uint64_t token1 = proto.start(FIELD_TYPE_MESSAGE | ComplexProto::kLogsFieldNumber);
232 EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 12));
233 EXPECT_TRUE(proto.write(FIELD_TYPE_STRING | ComplexProto::Log::kNameFieldNumber, name1));
234 // specify the length to test the write(id, bytes, length) function.
235 EXPECT_TRUE(proto.write(FIELD_TYPE_BYTES | ComplexProto::Log::kDataFieldNumber, data1, 5));
236 proto.end(token1);
237 uint64_t token2 = proto.start(FIELD_TYPE_MESSAGE | ComplexProto::kLogsFieldNumber);
238 EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 98));
239 EXPECT_TRUE(proto.write(FIELD_TYPE_STRING | ComplexProto::Log::kNameFieldNumber, name2));
240 EXPECT_TRUE(proto.write(FIELD_TYPE_BYTES | ComplexProto::Log::kDataFieldNumber, data2, 4));
241 proto.end(token2);
242
243 ComplexProto complex;
244 std::string serialized;
245 ASSERT_TRUE(proto.serializeToString(&serialized));
246 ASSERT_TRUE(complex.ParseFromString(serialized));
247 EXPECT_EQ(complex.ints_size(), 3);
248 EXPECT_EQ(complex.ints(0), 23);
249 EXPECT_EQ(complex.ints(1), 101);
250 EXPECT_EQ(complex.ints(2), -72);
251 EXPECT_EQ(complex.logs_size(), 2);
252 ComplexProto::Log log1 = complex.logs(0);
253 EXPECT_EQ(log1.id(), 12);
254 EXPECT_THAT(log1.name(), StrEq(name1.c_str()));
255 EXPECT_THAT(log1.data(), StrEq("funny")); // should not contain '!'
256 ComplexProto::Log log2 = complex.logs(1);
257 EXPECT_EQ(log2.id(), 98);
258 EXPECT_THAT(log2.name(), StrEq(name2.c_str()));
259 EXPECT_THAT(log2.data(), StrEq("food"));
260 }
261
TEST(ProtoOutputStreamTest,Reusability)262 TEST(ProtoOutputStreamTest, Reusability) {
263 ProtoOutputStream proto;
264 EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 32));
265 EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 15));
266 EXPECT_EQ(proto.bytesWritten(), 4);
267 EXPECT_EQ(proto.size(), 4);
268 // Can't write to proto after compact
269 EXPECT_FALSE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 94));
270
271 ComplexProto beforeClear;
272 ASSERT_TRUE(beforeClear.ParseFromString(flushToString(&proto)));
273 EXPECT_EQ(beforeClear.ints_size(), 2);
274 EXPECT_EQ(beforeClear.ints(0), 32);
275 EXPECT_EQ(beforeClear.ints(1), 15);
276
277 proto.clear();
278 EXPECT_EQ(proto.bytesWritten(), 0);
279 EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 1076));
280
281 ComplexProto afterClear;
282 ASSERT_TRUE(afterClear.ParseFromString(flushToString(&proto)));
283 EXPECT_EQ(afterClear.ints_size(), 1);
284 EXPECT_EQ(afterClear.ints(0), 1076);
285 }
286
TEST(ProtoOutputStreamTest,AdvancedEncoding)287 TEST(ProtoOutputStreamTest, AdvancedEncoding) {
288 ProtoOutputStream proto;
289 proto.writeRawVarint((ComplexProto::kIntsFieldNumber << FIELD_ID_SHIFT) + WIRE_TYPE_VARINT);
290 proto.writeRawVarint(UINT64_C(-123809234));
291 proto.writeLengthDelimitedHeader(ComplexProto::kLogsFieldNumber, 8);
292 proto.writeRawByte((ComplexProto::Log::kDataFieldNumber << FIELD_ID_SHIFT) + WIRE_TYPE_LENGTH_DELIMITED);
293 proto.writeRawByte(6);
294 proto.writeRawByte('b');
295 proto.writeRawByte('a');
296 proto.writeRawByte('n');
297 proto.writeRawByte('a');
298 proto.writeRawByte('n');
299 proto.writeRawByte('a');
300 uint64_t token = proto.start(FIELD_TYPE_MESSAGE | ComplexProto::kLogsFieldNumber);
301 proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 14);
302 proto.end(token);
303
304 ComplexProto complex;
305 ASSERT_TRUE(complex.ParseFromString(flushToString(&proto)));
306 EXPECT_EQ(complex.ints_size(), 1);
307 EXPECT_EQ(complex.ints(0), UINT64_C(-123809234));
308 EXPECT_EQ(complex.logs_size(), 2);
309 ComplexProto::Log log1 = complex.logs(0);
310 EXPECT_FALSE(log1.has_id());
311 EXPECT_FALSE(log1.has_name());
312 EXPECT_THAT(log1.data(), StrEq("banana"));
313 ComplexProto::Log log2 = complex.logs(1);
314 EXPECT_EQ(log2.id(), 14);
315 EXPECT_FALSE(log2.has_name());
316 EXPECT_FALSE(log2.has_data());
317 }
318
TEST(ProtoOutputStreamTest,InvalidTypes)319 TEST(ProtoOutputStreamTest, InvalidTypes) {
320 ProtoOutputStream proto;
321 EXPECT_FALSE(proto.write(FIELD_TYPE_UNKNOWN | PrimitiveProto::kValInt32FieldNumber, 790));
322 EXPECT_FALSE(proto.write(FIELD_TYPE_ENUM | PrimitiveProto::kValEnumFieldNumber, 234.34));
323 EXPECT_FALSE(proto.write(FIELD_TYPE_BOOL | PrimitiveProto::kValBoolFieldNumber, 18.73f));
324 EXPECT_EQ(proto.size(), 0);
325 }
326
TEST(ProtoOutputStreamTest,NoEndCalled)327 TEST(ProtoOutputStreamTest, NoEndCalled) {
328 ProtoOutputStream proto;
329 proto.start(FIELD_TYPE_MESSAGE | ComplexProto::kLogsFieldNumber);
330 proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 53);
331 // no proto.end called
332 EXPECT_NE(proto.bytesWritten(), 0);
333 EXPECT_EQ(proto.size(), 0);
334 EXPECT_FALSE(proto.flush(STDOUT_FILENO));
335 }
336
337
TEST(ProtoOutputStreamTest,TwoEndCalled)338 TEST(ProtoOutputStreamTest, TwoEndCalled) {
339 ProtoOutputStream proto;
340 uint64_t token = proto.start(FIELD_TYPE_MESSAGE | ComplexProto::kLogsFieldNumber);
341 proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 53);
342 proto.end(token);
343 proto.end(token);
344 EXPECT_NE(proto.bytesWritten(), 0);
345 EXPECT_EQ(proto.size(), 0);
346 EXPECT_FALSE(proto.flush(STDOUT_FILENO));
347 }
348
TEST(ProtoOutputStreamTest,NoStartCalled)349 TEST(ProtoOutputStreamTest, NoStartCalled) {
350 ProtoOutputStream proto;
351 uint64_t wrongToken = UINT64_C(324536345);
352 // no proto.start called
353 proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 53);
354 proto.end(wrongToken);
355 EXPECT_NE(proto.bytesWritten(), 0);
356 EXPECT_EQ(proto.size(), 0);
357 EXPECT_FALSE(proto.flush(STDOUT_FILENO));
358 }
359