Home | History | Annotate | Download | only in tests
      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