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 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 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 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 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 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 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 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 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 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 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 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 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 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