xref: /aosp_15_r20/external/perfetto/src/shared_lib/test/api_integrationtest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <thread>
18 
19 #include "perfetto/public/abi/data_source_abi.h"
20 #include "perfetto/public/abi/heap_buffer.h"
21 #include "perfetto/public/abi/pb_decoder_abi.h"
22 #include "perfetto/public/abi/tracing_session_abi.h"
23 #include "perfetto/public/abi/track_event_abi.h"
24 #include "perfetto/public/data_source.h"
25 #include "perfetto/public/pb_decoder.h"
26 #include "perfetto/public/producer.h"
27 #include "perfetto/public/protos/config/trace_config.pzc.h"
28 #include "perfetto/public/protos/trace/interned_data/interned_data.pzc.h"
29 #include "perfetto/public/protos/trace/test_event.pzc.h"
30 #include "perfetto/public/protos/trace/trace.pzc.h"
31 #include "perfetto/public/protos/trace/trace_packet.pzc.h"
32 #include "perfetto/public/protos/trace/track_event/debug_annotation.pzc.h"
33 #include "perfetto/public/protos/trace/track_event/track_descriptor.pzc.h"
34 #include "perfetto/public/protos/trace/track_event/track_event.pzc.h"
35 #include "perfetto/public/protos/trace/trigger.pzc.h"
36 #include "perfetto/public/te_category_macros.h"
37 #include "perfetto/public/te_macros.h"
38 #include "perfetto/public/track_event.h"
39 
40 #include "test/gtest_and_gmock.h"
41 
42 #include "src/shared_lib/reset_for_testing.h"
43 #include "src/shared_lib/test/protos/extensions.pzc.h"
44 #include "src/shared_lib/test/protos/test_messages.pzc.h"
45 #include "src/shared_lib/test/utils.h"
46 
47 // Tests for the perfetto shared library.
48 
49 namespace {
50 
51 using ::perfetto::shlib::test_utils::AllFieldsWithId;
52 using ::perfetto::shlib::test_utils::DoubleField;
53 using ::perfetto::shlib::test_utils::FieldView;
54 using ::perfetto::shlib::test_utils::Fixed32Field;
55 using ::perfetto::shlib::test_utils::Fixed64Field;
56 using ::perfetto::shlib::test_utils::FloatField;
57 using ::perfetto::shlib::test_utils::IdFieldView;
58 using ::perfetto::shlib::test_utils::MsgField;
59 using ::perfetto::shlib::test_utils::PbField;
60 using ::perfetto::shlib::test_utils::StringField;
61 using ::perfetto::shlib::test_utils::TracingSession;
62 using ::perfetto::shlib::test_utils::VarIntField;
63 using ::perfetto::shlib::test_utils::WaitableEvent;
64 using ::testing::_;
65 using ::testing::AllOf;
66 using ::testing::DoAll;
67 using ::testing::ElementsAre;
68 using ::testing::InSequence;
69 using ::testing::IsNull;
70 using ::testing::NiceMock;
71 using ::testing::ResultOf;
72 using ::testing::Return;
73 using ::testing::SaveArg;
74 using ::testing::UnorderedElementsAre;
75 
76 constexpr char kDataSourceName1[] = "dev.perfetto.example_data_source";
77 struct PerfettoDs data_source_1 = PERFETTO_DS_INIT();
78 
79 constexpr char kDataSourceName2[] = "dev.perfetto.example_data_source2";
80 struct PerfettoDs data_source_2 = PERFETTO_DS_INIT();
81 void* const kDataSource2UserArg = reinterpret_cast<void*>(0x555);
82 
83 #define TEST_CATEGORIES(C) \
84   C(cat1, "cat1", "") C(cat2, "cat2", "") C(cat3, "cat3", "")
85 PERFETTO_TE_CATEGORIES_DEFINE(TEST_CATEGORIES)
86 
87 class MockDs2Callbacks : testing::Mock {
88  public:
89   MOCK_METHOD(void*,
90               OnSetup,
91               (struct PerfettoDsImpl*,
92                PerfettoDsInstanceIndex inst_id,
93                void* ds_config,
94                size_t ds_config_size,
95                void* user_arg,
96                struct PerfettoDsOnSetupArgs* args));
97   MOCK_METHOD(void,
98               OnStart,
99               (struct PerfettoDsImpl*,
100                PerfettoDsInstanceIndex inst_id,
101                void* user_arg,
102                void* inst_ctx,
103                struct PerfettoDsOnStartArgs* args));
104   MOCK_METHOD(void,
105               OnStop,
106               (struct PerfettoDsImpl*,
107                PerfettoDsInstanceIndex inst_id,
108                void* user_arg,
109                void* inst_ctx,
110                struct PerfettoDsOnStopArgs* args));
111   MOCK_METHOD(void,
112               OnDestroy,
113               (struct PerfettoDsImpl*, void* user_arg, void* inst_ctx));
114   MOCK_METHOD(void,
115               OnFlush,
116               (struct PerfettoDsImpl*,
117                PerfettoDsInstanceIndex inst_id,
118                void* user_arg,
119                void* inst_ctx,
120                struct PerfettoDsOnFlushArgs* args));
121   MOCK_METHOD(void*,
122               OnCreateTls,
123               (struct PerfettoDsImpl*,
124                PerfettoDsInstanceIndex inst_id,
125                struct PerfettoDsTracerImpl* tracer,
126                void* user_arg));
127   MOCK_METHOD(void, OnDeleteTls, (void*));
128   MOCK_METHOD(void*,
129               OnCreateIncr,
130               (struct PerfettoDsImpl*,
131                PerfettoDsInstanceIndex inst_id,
132                struct PerfettoDsTracerImpl* tracer,
133                void* user_arg));
134   MOCK_METHOD(void, OnDeleteIncr, (void*));
135 };
136 
TEST(SharedLibProtobufTest,PerfettoPbDecoderIteratorExample)137 TEST(SharedLibProtobufTest, PerfettoPbDecoderIteratorExample) {
138   // # proto-message: perfetto.protos.TestEvent
139   // counter: 5
140   // payload {
141   //   str: "hello"
142   //   single_int: -1
143   // }
144   std::string_view msg =
145       "\x18\x05\x2a\x12\x0a\x05\x68\x65\x6c\x6c\x6f\x28\xff\xff\xff\xff\xff\xff"
146       "\xff\xff\xff\x01";
147   size_t n_counter = 0;
148   size_t n_payload = 0;
149   size_t n_payload_str = 0;
150   size_t n_payload_single_int = 0;
151   for (struct PerfettoPbDecoderIterator it =
152            PerfettoPbDecoderIterateBegin(msg.data(), msg.size());
153        it.field.status != PERFETTO_PB_DECODER_DONE;
154        PerfettoPbDecoderIterateNext(&it)) {
155     if (it.field.status != PERFETTO_PB_DECODER_OK) {
156       ADD_FAILURE() << "Failed to parse main message";
157       break;
158     }
159     switch (it.field.id) {
160       case perfetto_protos_TestEvent_counter_field_number:
161         n_counter++;
162         EXPECT_EQ(it.field.wire_type, PERFETTO_PB_WIRE_TYPE_VARINT);
163         {
164           uint64_t val = 0;
165           EXPECT_TRUE(PerfettoPbDecoderFieldGetUint64(&it.field, &val));
166           EXPECT_EQ(val, 5u);
167         }
168         break;
169       case perfetto_protos_TestEvent_payload_field_number:
170         n_payload++;
171         EXPECT_EQ(it.field.wire_type, PERFETTO_PB_WIRE_TYPE_DELIMITED);
172         for (struct PerfettoPbDecoderIterator it2 =
173                  PerfettoPbDecoderIterateNestedBegin(it.field.value.delimited);
174              it2.field.status != PERFETTO_PB_DECODER_DONE;
175              PerfettoPbDecoderIterateNext(&it2)) {
176           if (it2.field.status != PERFETTO_PB_DECODER_OK) {
177             ADD_FAILURE() << "Failed to parse nested message";
178             break;
179           }
180           switch (it2.field.id) {
181             case perfetto_protos_TestEvent_TestPayload_str_field_number:
182               n_payload_str++;
183               EXPECT_EQ(it2.field.wire_type, PERFETTO_PB_WIRE_TYPE_DELIMITED);
184               EXPECT_EQ(std::string_view(reinterpret_cast<const char*>(
185                                              it2.field.value.delimited.start),
186                                          it2.field.value.delimited.len),
187                         "hello");
188               break;
189             case perfetto_protos_TestEvent_TestPayload_single_int_field_number:
190               EXPECT_EQ(it2.field.wire_type, PERFETTO_PB_WIRE_TYPE_VARINT);
191               n_payload_single_int++;
192               {
193                 int32_t val = 0;
194                 EXPECT_TRUE(PerfettoPbDecoderFieldGetInt32(&it2.field, &val));
195                 EXPECT_EQ(val, -1);
196               }
197               break;
198             default:
199               ADD_FAILURE() << "Unexpected nested field.id";
200               break;
201           }
202         }
203         break;
204       default:
205         ADD_FAILURE() << "Unexpected field.id";
206         break;
207     }
208   }
209   EXPECT_EQ(n_counter, 1u);
210   EXPECT_EQ(n_payload, 1u);
211   EXPECT_EQ(n_payload_str, 1u);
212   EXPECT_EQ(n_payload_single_int, 1u);
213 }
214 
215 class SharedLibProtozeroSerializationTest : public testing::Test {
216  protected:
SharedLibProtozeroSerializationTest()217   SharedLibProtozeroSerializationTest() {
218     hb = PerfettoHeapBufferCreate(&writer.writer);
219   }
220 
GetData()221   std::vector<uint8_t> GetData() {
222     std::vector<uint8_t> data;
223     size_t size = PerfettoStreamWriterGetWrittenSize(&writer.writer);
224     data.resize(size);
225     PerfettoHeapBufferCopyInto(hb, &writer.writer, data.data(), data.size());
226     return data;
227   }
228 
~SharedLibProtozeroSerializationTest()229   ~SharedLibProtozeroSerializationTest() {
230     PerfettoHeapBufferDestroy(hb, &writer.writer);
231   }
232 
233   template <typename T>
ParsePackedVarInt(const std::string & data)234   static std::vector<T> ParsePackedVarInt(const std::string& data) {
235     std::vector<T> ret;
236     const uint8_t* read_ptr = reinterpret_cast<const uint8_t*>(data.data());
237     const uint8_t* const end = read_ptr + data.size();
238     while (read_ptr != end) {
239       uint64_t val;
240       const uint8_t* new_read_ptr = PerfettoPbParseVarInt(read_ptr, end, &val);
241       if (new_read_ptr == read_ptr) {
242         ADD_FAILURE();
243         return ret;
244       }
245       read_ptr = new_read_ptr;
246       ret.push_back(static_cast<T>(val));
247     }
248     return ret;
249   }
250 
251   template <typename T>
ParsePackedFixed(const std::string & data)252   static std::vector<T> ParsePackedFixed(const std::string& data) {
253     std::vector<T> ret;
254     if (data.size() % sizeof(T)) {
255       ADD_FAILURE();
256       return ret;
257     }
258     const uint8_t* read_ptr = reinterpret_cast<const uint8_t*>(data.data());
259     const uint8_t* end = read_ptr + data.size();
260     while (read_ptr < end) {
261       ret.push_back(*reinterpret_cast<const T*>(read_ptr));
262       read_ptr += sizeof(T);
263     }
264     return ret;
265   }
266 
267   struct PerfettoPbMsgWriter writer;
268   struct PerfettoHeapBuffer* hb;
269 };
270 
TEST_F(SharedLibProtozeroSerializationTest,SimpleFieldsNoNesting)271 TEST_F(SharedLibProtozeroSerializationTest, SimpleFieldsNoNesting) {
272   struct protozero_test_protos_EveryField msg;
273   PerfettoPbMsgInit(&msg.msg, &writer);
274 
275   protozero_test_protos_EveryField_set_field_int32(&msg, -1);
276   protozero_test_protos_EveryField_set_field_int64(&msg, -333123456789ll);
277   protozero_test_protos_EveryField_set_field_uint32(&msg, 600);
278   protozero_test_protos_EveryField_set_field_uint64(&msg, 333123456789ll);
279   protozero_test_protos_EveryField_set_field_sint32(&msg, -5);
280   protozero_test_protos_EveryField_set_field_sint64(&msg, -9000);
281   protozero_test_protos_EveryField_set_field_fixed32(&msg, 12345);
282   protozero_test_protos_EveryField_set_field_fixed64(&msg, 444123450000ll);
283   protozero_test_protos_EveryField_set_field_sfixed32(&msg, -69999);
284   protozero_test_protos_EveryField_set_field_sfixed64(&msg, -200);
285   protozero_test_protos_EveryField_set_field_float(&msg, 3.14f);
286   protozero_test_protos_EveryField_set_field_double(&msg, 0.5555);
287   protozero_test_protos_EveryField_set_field_bool(&msg, true);
288   protozero_test_protos_EveryField_set_small_enum(&msg,
289                                                   protozero_test_protos_TO_BE);
290   protozero_test_protos_EveryField_set_signed_enum(
291       &msg, protozero_test_protos_NEGATIVE);
292   protozero_test_protos_EveryField_set_big_enum(&msg,
293                                                 protozero_test_protos_BEGIN);
294   protozero_test_protos_EveryField_set_cstr_field_string(&msg, "FizzBuzz");
295   protozero_test_protos_EveryField_set_field_bytes(&msg, "\x11\x00\xBE\xEF", 4);
296   protozero_test_protos_EveryField_set_repeated_int32(&msg, 1);
297   protozero_test_protos_EveryField_set_repeated_int32(&msg, -1);
298   protozero_test_protos_EveryField_set_repeated_int32(&msg, 100);
299   protozero_test_protos_EveryField_set_repeated_int32(&msg, 2000000);
300 
301   EXPECT_THAT(
302       FieldView(GetData()),
303       ElementsAre(
304           PbField(protozero_test_protos_EveryField_field_int32_field_number,
305                   VarIntField(static_cast<uint64_t>(-1))),
306           PbField(protozero_test_protos_EveryField_field_int64_field_number,
307                   VarIntField(static_cast<uint64_t>(INT64_C(-333123456789)))),
308           PbField(protozero_test_protos_EveryField_field_uint32_field_number,
309                   VarIntField(600)),
310           PbField(protozero_test_protos_EveryField_field_uint64_field_number,
311                   VarIntField(UINT64_C(333123456789))),
312           PbField(protozero_test_protos_EveryField_field_sint32_field_number,
313                   VarIntField(ResultOf(
314                       [](uint64_t val) {
315                         return PerfettoPbZigZagDecode32(
316                             static_cast<uint32_t>(val));
317                       },
318                       -5))),
319           PbField(protozero_test_protos_EveryField_field_sint64_field_number,
320                   VarIntField(ResultOf(PerfettoPbZigZagDecode64, -9000))),
321           PbField(protozero_test_protos_EveryField_field_fixed32_field_number,
322                   Fixed32Field(12345)),
323           PbField(protozero_test_protos_EveryField_field_fixed64_field_number,
324                   Fixed64Field(UINT64_C(444123450000))),
325           PbField(protozero_test_protos_EveryField_field_sfixed32_field_number,
326                   Fixed32Field(static_cast<uint32_t>(-69999))),
327           PbField(protozero_test_protos_EveryField_field_sfixed64_field_number,
328                   Fixed64Field(static_cast<uint64_t>(-200))),
329           PbField(protozero_test_protos_EveryField_field_float_field_number,
330                   FloatField(3.14f)),
331           PbField(protozero_test_protos_EveryField_field_double_field_number,
332                   DoubleField(0.5555)),
333           PbField(protozero_test_protos_EveryField_field_bool_field_number,
334                   VarIntField(true)),
335           PbField(protozero_test_protos_EveryField_small_enum_field_number,
336                   VarIntField(protozero_test_protos_TO_BE)),
337           PbField(protozero_test_protos_EveryField_signed_enum_field_number,
338                   VarIntField(protozero_test_protos_NEGATIVE)),
339           PbField(protozero_test_protos_EveryField_big_enum_field_number,
340                   VarIntField(protozero_test_protos_BEGIN)),
341           PbField(protozero_test_protos_EveryField_field_string_field_number,
342                   StringField("FizzBuzz")),
343           PbField(protozero_test_protos_EveryField_field_bytes_field_number,
344                   StringField(std::string_view("\x11\x00\xBE\xEF", 4))),
345           PbField(protozero_test_protos_EveryField_repeated_int32_field_number,
346                   VarIntField(1)),
347           PbField(protozero_test_protos_EveryField_repeated_int32_field_number,
348                   VarIntField(static_cast<uint64_t>(-1))),
349           PbField(protozero_test_protos_EveryField_repeated_int32_field_number,
350                   VarIntField(100)),
351           PbField(protozero_test_protos_EveryField_repeated_int32_field_number,
352                   VarIntField(2000000))));
353 }
354 
TEST_F(SharedLibProtozeroSerializationTest,NestedMessages)355 TEST_F(SharedLibProtozeroSerializationTest, NestedMessages) {
356   struct protozero_test_protos_NestedA msg_a;
357   PerfettoPbMsgInit(&msg_a.msg, &writer);
358 
359   {
360     struct protozero_test_protos_NestedA_NestedB msg_b;
361     protozero_test_protos_NestedA_begin_repeated_a(&msg_a, &msg_b);
362     {
363       struct protozero_test_protos_NestedA_NestedB_NestedC msg_c;
364       protozero_test_protos_NestedA_NestedB_begin_value_b(&msg_b, &msg_c);
365       protozero_test_protos_NestedA_NestedB_NestedC_set_value_c(&msg_c, 321);
366       protozero_test_protos_NestedA_NestedB_end_value_b(&msg_b, &msg_c);
367     }
368     protozero_test_protos_NestedA_end_repeated_a(&msg_a, &msg_b);
369   }
370   {
371     struct protozero_test_protos_NestedA_NestedB msg_b;
372     protozero_test_protos_NestedA_begin_repeated_a(&msg_a, &msg_b);
373     protozero_test_protos_NestedA_end_repeated_a(&msg_a, &msg_b);
374   }
375   {
376     struct protozero_test_protos_NestedA_NestedB_NestedC msg_c;
377     protozero_test_protos_NestedA_begin_super_nested(&msg_a, &msg_c);
378     protozero_test_protos_NestedA_NestedB_NestedC_set_value_c(&msg_c, 1000);
379     protozero_test_protos_NestedA_end_super_nested(&msg_a, &msg_c);
380   }
381 
382   EXPECT_THAT(
383       FieldView(GetData()),
384       ElementsAre(
385           PbField(
386               protozero_test_protos_NestedA_repeated_a_field_number,
387               MsgField(ElementsAre(PbField(
388                   protozero_test_protos_NestedA_NestedB_value_b_field_number,
389                   MsgField(ElementsAre(PbField(
390                       protozero_test_protos_NestedA_NestedB_NestedC_value_c_field_number,
391                       VarIntField(321)))))))),
392           PbField(protozero_test_protos_NestedA_repeated_a_field_number,
393                   MsgField(ElementsAre())),
394           PbField(
395               protozero_test_protos_NestedA_super_nested_field_number,
396               MsgField(ElementsAre(PbField(
397                   protozero_test_protos_NestedA_NestedB_NestedC_value_c_field_number,
398                   VarIntField(1000)))))));
399 }
400 
TEST_F(SharedLibProtozeroSerializationTest,Extensions)401 TEST_F(SharedLibProtozeroSerializationTest, Extensions) {
402   struct protozero_test_protos_RealFakeEvent base;
403   PerfettoPbMsgInit(&base.msg, &writer);
404 
405   {
406     struct protozero_test_protos_SystemA msg_a;
407     protozero_test_protos_BrowserExtension_begin_extension_a(&base, &msg_a);
408     protozero_test_protos_SystemA_set_cstr_string_a(&msg_a, "str_a");
409     protozero_test_protos_BrowserExtension_end_extension_a(&base, &msg_a);
410   }
411   {
412     struct protozero_test_protos_SystemB msg_b;
413     protozero_test_protos_BrowserExtension_begin_extension_b(&base, &msg_b);
414     protozero_test_protos_SystemB_set_cstr_string_b(&msg_b, "str_b");
415     protozero_test_protos_BrowserExtension_end_extension_b(&base, &msg_b);
416   }
417 
418   protozero_test_protos_RealFakeEvent_set_cstr_base_string(&base, "str");
419 
420   EXPECT_THAT(
421       FieldView(GetData()),
422       ElementsAre(
423           PbField(
424               protozero_test_protos_BrowserExtension_extension_a_field_number,
425               MsgField(ElementsAre(
426                   PbField(protozero_test_protos_SystemA_string_a_field_number,
427                           StringField("str_a"))))),
428           PbField(
429               protozero_test_protos_BrowserExtension_extension_b_field_number,
430               MsgField(ElementsAre(
431                   PbField(protozero_test_protos_SystemB_string_b_field_number,
432                           StringField("str_b"))))),
433           PbField(protozero_test_protos_RealFakeEvent_base_string_field_number,
434                   StringField("str"))));
435 }
436 
TEST_F(SharedLibProtozeroSerializationTest,PackedRepeatedMsgVarInt)437 TEST_F(SharedLibProtozeroSerializationTest, PackedRepeatedMsgVarInt) {
438   struct protozero_test_protos_PackedRepeatedFields msg;
439   PerfettoPbMsgInit(&msg.msg, &writer);
440 
441   {
442     PerfettoPbPackedMsgInt32 f;
443     protozero_test_protos_PackedRepeatedFields_begin_field_int32(&msg, &f);
444     PerfettoPbPackedMsgInt32Append(&f, 42);
445     PerfettoPbPackedMsgInt32Append(&f, 255);
446     PerfettoPbPackedMsgInt32Append(&f, -1);
447     protozero_test_protos_PackedRepeatedFields_end_field_int32(&msg, &f);
448   }
449 
450   {
451     PerfettoPbPackedMsgInt64 f;
452     protozero_test_protos_PackedRepeatedFields_begin_field_int64(&msg, &f);
453     PerfettoPbPackedMsgInt64Append(&f, INT64_C(3000000000));
454     PerfettoPbPackedMsgInt64Append(&f, INT64_C(-3000000000));
455     protozero_test_protos_PackedRepeatedFields_end_field_int64(&msg, &f);
456   }
457 
458   {
459     PerfettoPbPackedMsgUint32 f;
460     protozero_test_protos_PackedRepeatedFields_begin_field_uint32(&msg, &f);
461     PerfettoPbPackedMsgUint32Append(&f, 42);
462     PerfettoPbPackedMsgUint32Append(&f, UINT32_C(3000000000));
463     protozero_test_protos_PackedRepeatedFields_end_field_uint32(&msg, &f);
464   }
465 
466   {
467     PerfettoPbPackedMsgUint64 f;
468     protozero_test_protos_PackedRepeatedFields_begin_field_uint64(&msg, &f);
469     PerfettoPbPackedMsgUint64Append(&f, 42);
470     PerfettoPbPackedMsgUint64Append(&f, UINT64_C(5000000000));
471     protozero_test_protos_PackedRepeatedFields_end_field_uint64(&msg, &f);
472   }
473 
474   {
475     PerfettoPbPackedMsgInt32 f;
476     protozero_test_protos_PackedRepeatedFields_begin_signed_enum(&msg, &f);
477     PerfettoPbPackedMsgInt32Append(&f, protozero_test_protos_POSITIVE);
478     PerfettoPbPackedMsgInt32Append(&f, protozero_test_protos_NEGATIVE);
479     protozero_test_protos_PackedRepeatedFields_end_signed_enum(&msg, &f);
480   }
481 
482   EXPECT_THAT(
483       FieldView(GetData()),
484       ElementsAre(
485           PbField(
486               protozero_test_protos_PackedRepeatedFields_field_int32_field_number,
487               StringField(ResultOf(ParsePackedVarInt<int32_t>,
488                                    ElementsAre(42, 255, -1)))),
489           PbField(
490               protozero_test_protos_PackedRepeatedFields_field_int64_field_number,
491               StringField(ResultOf(
492                   ParsePackedVarInt<int64_t>,
493                   ElementsAre(INT64_C(3000000000), INT64_C(-3000000000))))),
494           PbField(
495               protozero_test_protos_PackedRepeatedFields_field_uint32_field_number,
496               StringField(ResultOf(ParsePackedVarInt<uint32_t>,
497                                    ElementsAre(42, UINT32_C(3000000000))))),
498           PbField(
499               protozero_test_protos_PackedRepeatedFields_field_uint64_field_number,
500               StringField(ResultOf(ParsePackedVarInt<uint64_t>,
501                                    ElementsAre(42, UINT64_C(5000000000))))),
502           PbField(
503               protozero_test_protos_PackedRepeatedFields_signed_enum_field_number,
504               StringField(
505                   ResultOf(ParsePackedVarInt<int32_t>,
506                            ElementsAre(protozero_test_protos_POSITIVE,
507                                        protozero_test_protos_NEGATIVE))))));
508 }
509 
TEST_F(SharedLibProtozeroSerializationTest,PackedRepeatedMsgFixed)510 TEST_F(SharedLibProtozeroSerializationTest, PackedRepeatedMsgFixed) {
511   struct protozero_test_protos_PackedRepeatedFields msg;
512   PerfettoPbMsgInit(&msg.msg, &writer);
513 
514   {
515     PerfettoPbPackedMsgFixed32 f;
516     protozero_test_protos_PackedRepeatedFields_begin_field_fixed32(&msg, &f);
517     PerfettoPbPackedMsgFixed32Append(&f, 42);
518     PerfettoPbPackedMsgFixed32Append(&f, UINT32_C(3000000000));
519     protozero_test_protos_PackedRepeatedFields_end_field_fixed32(&msg, &f);
520   }
521 
522   {
523     PerfettoPbPackedMsgFixed64 f;
524     protozero_test_protos_PackedRepeatedFields_begin_field_fixed64(&msg, &f);
525     PerfettoPbPackedMsgFixed64Append(&f, 42);
526     PerfettoPbPackedMsgFixed64Append(&f, UINT64_C(5000000000));
527     protozero_test_protos_PackedRepeatedFields_end_field_fixed64(&msg, &f);
528   }
529 
530   {
531     PerfettoPbPackedMsgSfixed32 f;
532     protozero_test_protos_PackedRepeatedFields_begin_field_sfixed32(&msg, &f);
533     PerfettoPbPackedMsgSfixed32Append(&f, 42);
534     PerfettoPbPackedMsgSfixed32Append(&f, 255);
535     PerfettoPbPackedMsgSfixed32Append(&f, -1);
536     protozero_test_protos_PackedRepeatedFields_end_field_sfixed32(&msg, &f);
537   }
538 
539   {
540     PerfettoPbPackedMsgSfixed64 f;
541     protozero_test_protos_PackedRepeatedFields_begin_field_sfixed64(&msg, &f);
542     PerfettoPbPackedMsgSfixed64Append(&f, INT64_C(3000000000));
543     PerfettoPbPackedMsgSfixed64Append(&f, INT64_C(-3000000000));
544     protozero_test_protos_PackedRepeatedFields_end_field_sfixed64(&msg, &f);
545   }
546 
547   {
548     PerfettoPbPackedMsgFloat f;
549     protozero_test_protos_PackedRepeatedFields_begin_field_float(&msg, &f);
550     PerfettoPbPackedMsgFloatAppend(&f, 3.14f);
551     PerfettoPbPackedMsgFloatAppend(&f, 42.1f);
552     protozero_test_protos_PackedRepeatedFields_end_field_float(&msg, &f);
553   }
554 
555   {
556     PerfettoPbPackedMsgDouble f;
557     protozero_test_protos_PackedRepeatedFields_begin_field_double(&msg, &f);
558     PerfettoPbPackedMsgDoubleAppend(&f, 3.14);
559     PerfettoPbPackedMsgDoubleAppend(&f, 42.1);
560     protozero_test_protos_PackedRepeatedFields_end_field_double(&msg, &f);
561   }
562 
563   EXPECT_THAT(
564       FieldView(GetData()),
565       ElementsAre(
566           PbField(
567               protozero_test_protos_PackedRepeatedFields_field_fixed32_field_number,
568               StringField(ResultOf(ParsePackedFixed<uint32_t>,
569                                    ElementsAre(42, UINT32_C(3000000000))))),
570           PbField(
571               protozero_test_protos_PackedRepeatedFields_field_fixed64_field_number,
572               StringField(ResultOf(ParsePackedFixed<uint64_t>,
573                                    ElementsAre(42, UINT64_C(5000000000))))),
574           PbField(
575               protozero_test_protos_PackedRepeatedFields_field_sfixed32_field_number,
576               StringField(ResultOf(ParsePackedFixed<int32_t>,
577                                    ElementsAre(42, 255, -1)))),
578           PbField(
579               protozero_test_protos_PackedRepeatedFields_field_sfixed64_field_number,
580               StringField(ResultOf(
581                   ParsePackedFixed<int64_t>,
582                   ElementsAre(INT64_C(3000000000), INT64_C(-3000000000))))),
583           PbField(
584               protozero_test_protos_PackedRepeatedFields_field_float_field_number,
585               StringField(ResultOf(ParsePackedFixed<float>,
586                                    ElementsAre(3.14f, 42.1f)))),
587           PbField(
588               protozero_test_protos_PackedRepeatedFields_field_double_field_number,
589               StringField(ResultOf(ParsePackedFixed<double>,
590                                    ElementsAre(3.14, 42.1))))));
591 }
592 
593 class SharedLibDataSourceTest : public testing::Test {
594  protected:
SetUp()595   void SetUp() override {
596     struct PerfettoProducerInitArgs args = PERFETTO_PRODUCER_INIT_ARGS_INIT();
597     args.backends = PERFETTO_BACKEND_IN_PROCESS;
598     PerfettoProducerInit(args);
599     PerfettoDsRegister(&data_source_1, kDataSourceName1,
600                        PerfettoDsParamsDefault());
601     RegisterDataSource2();
602   }
603 
TearDown()604   void TearDown() override {
605     perfetto::shlib::ResetForTesting();
606     data_source_1.enabled = &perfetto_atomic_false;
607     perfetto::shlib::DsImplDestroy(data_source_1.impl);
608     data_source_1.impl = nullptr;
609     data_source_2.enabled = &perfetto_atomic_false;
610     perfetto::shlib::DsImplDestroy(data_source_2.impl);
611     data_source_2.impl = nullptr;
612   }
613 
614   struct Ds2CustomState {
615     void* actual;
616     SharedLibDataSourceTest* thiz;
617   };
618 
RegisterDataSource2()619   void RegisterDataSource2() {
620     struct PerfettoDsParams params = PerfettoDsParamsDefault();
621     params.on_setup_cb = [](struct PerfettoDsImpl* ds_impl,
622                             PerfettoDsInstanceIndex inst_id, void* ds_config,
623                             size_t ds_config_size, void* user_arg,
624                             struct PerfettoDsOnSetupArgs* args) -> void* {
625       auto* thiz = static_cast<SharedLibDataSourceTest*>(user_arg);
626       return thiz->ds2_callbacks_.OnSetup(ds_impl, inst_id, ds_config,
627                                           ds_config_size, thiz->ds2_user_arg_,
628                                           args);
629     };
630     params.on_start_cb = [](struct PerfettoDsImpl* ds_impl,
631                             PerfettoDsInstanceIndex inst_id, void* user_arg,
632                             void* inst_ctx,
633                             struct PerfettoDsOnStartArgs* args) -> void {
634       auto* thiz = static_cast<SharedLibDataSourceTest*>(user_arg);
635       return thiz->ds2_callbacks_.OnStart(ds_impl, inst_id, thiz->ds2_user_arg_,
636                                           inst_ctx, args);
637     };
638     params.on_stop_cb = [](struct PerfettoDsImpl* ds_impl,
639                            PerfettoDsInstanceIndex inst_id, void* user_arg,
640                            void* inst_ctx, struct PerfettoDsOnStopArgs* args) {
641       auto* thiz = static_cast<SharedLibDataSourceTest*>(user_arg);
642       return thiz->ds2_callbacks_.OnStop(ds_impl, inst_id, thiz->ds2_user_arg_,
643                                          inst_ctx, args);
644     };
645     params.on_destroy_cb = [](struct PerfettoDsImpl* ds_impl, void* user_arg,
646                               void* inst_ctx) -> void {
647       auto* thiz = static_cast<SharedLibDataSourceTest*>(user_arg);
648       thiz->ds2_callbacks_.OnDestroy(ds_impl, thiz->ds2_user_arg_, inst_ctx);
649     };
650     params.on_flush_cb =
651         [](struct PerfettoDsImpl* ds_impl, PerfettoDsInstanceIndex inst_id,
652            void* user_arg, void* inst_ctx, struct PerfettoDsOnFlushArgs* args) {
653           auto* thiz = static_cast<SharedLibDataSourceTest*>(user_arg);
654           return thiz->ds2_callbacks_.OnFlush(
655               ds_impl, inst_id, thiz->ds2_user_arg_, inst_ctx, args);
656         };
657     params.on_create_tls_cb =
658         [](struct PerfettoDsImpl* ds_impl, PerfettoDsInstanceIndex inst_id,
659            struct PerfettoDsTracerImpl* tracer, void* user_arg) -> void* {
660       auto* thiz = static_cast<SharedLibDataSourceTest*>(user_arg);
661       auto* state = new Ds2CustomState();
662       state->thiz = thiz;
663       state->actual = thiz->ds2_callbacks_.OnCreateTls(ds_impl, inst_id, tracer,
664                                                        thiz->ds2_user_arg_);
665       return state;
666     };
667     params.on_delete_tls_cb = [](void* ptr) {
668       auto* state = static_cast<Ds2CustomState*>(ptr);
669       state->thiz->ds2_callbacks_.OnDeleteTls(state->actual);
670       delete state;
671     };
672     params.on_create_incr_cb =
673         [](struct PerfettoDsImpl* ds_impl, PerfettoDsInstanceIndex inst_id,
674            struct PerfettoDsTracerImpl* tracer, void* user_arg) -> void* {
675       auto* thiz = static_cast<SharedLibDataSourceTest*>(user_arg);
676       auto* state = new Ds2CustomState();
677       state->thiz = thiz;
678       state->actual = thiz->ds2_callbacks_.OnCreateIncr(
679           ds_impl, inst_id, tracer, thiz->ds2_user_arg_);
680       return state;
681     };
682     params.on_delete_incr_cb = [](void* ptr) {
683       auto* state = static_cast<Ds2CustomState*>(ptr);
684       state->thiz->ds2_callbacks_.OnDeleteIncr(state->actual);
685       delete state;
686     };
687     params.user_arg = this;
688     PerfettoDsRegister(&data_source_2, kDataSourceName2, params);
689   }
690 
Ds2ActualCustomState(void * ptr)691   void* Ds2ActualCustomState(void* ptr) {
692     auto* state = static_cast<Ds2CustomState*>(ptr);
693     return state->actual;
694   }
695 
696   NiceMock<MockDs2Callbacks> ds2_callbacks_;
697   void* ds2_user_arg_ = kDataSource2UserArg;
698 };
699 
TEST_F(SharedLibDataSourceTest,DisabledNotExecuted)700 TEST_F(SharedLibDataSourceTest, DisabledNotExecuted) {
701   bool executed = false;
702 
703   PERFETTO_DS_TRACE(data_source_1, ctx) {
704     executed = true;
705   }
706 
707   EXPECT_FALSE(executed);
708 }
709 
TEST_F(SharedLibDataSourceTest,EnabledOnce)710 TEST_F(SharedLibDataSourceTest, EnabledOnce) {
711   size_t executed = 0;
712   TracingSession tracing_session =
713       TracingSession::Builder().set_data_source_name(kDataSourceName1).Build();
714 
715   PERFETTO_DS_TRACE(data_source_1, ctx) {
716     executed++;
717   }
718 
719   EXPECT_EQ(executed, 1u);
720 }
721 
TEST_F(SharedLibDataSourceTest,EnabledTwice)722 TEST_F(SharedLibDataSourceTest, EnabledTwice) {
723   size_t executed = 0;
724   TracingSession tracing_session1 =
725       TracingSession::Builder().set_data_source_name(kDataSourceName1).Build();
726   TracingSession tracing_session2 =
727       TracingSession::Builder().set_data_source_name(kDataSourceName1).Build();
728 
729   PERFETTO_DS_TRACE(data_source_1, ctx) {
730     executed++;
731   }
732 
733   EXPECT_EQ(executed, 2u);
734 }
735 
TEST_F(SharedLibDataSourceTest,Serialization)736 TEST_F(SharedLibDataSourceTest, Serialization) {
737   TracingSession tracing_session =
738       TracingSession::Builder().set_data_source_name(kDataSourceName1).Build();
739 
740   PERFETTO_DS_TRACE(data_source_1, ctx) {
741     struct PerfettoDsRootTracePacket trace_packet;
742     PerfettoDsTracerPacketBegin(&ctx, &trace_packet);
743 
744     {
745       struct perfetto_protos_TestEvent for_testing;
746       perfetto_protos_TracePacket_begin_for_testing(&trace_packet.msg,
747                                                     &for_testing);
748       {
749         struct perfetto_protos_TestEvent_TestPayload payload;
750         perfetto_protos_TestEvent_begin_payload(&for_testing, &payload);
751         perfetto_protos_TestEvent_TestPayload_set_cstr_str(&payload,
752                                                            "ABCDEFGH");
753         perfetto_protos_TestEvent_end_payload(&for_testing, &payload);
754       }
755       perfetto_protos_TracePacket_end_for_testing(&trace_packet.msg,
756                                                   &for_testing);
757     }
758     PerfettoDsTracerPacketEnd(&ctx, &trace_packet);
759   }
760 
761   tracing_session.StopBlocking();
762   std::vector<uint8_t> data = tracing_session.ReadBlocking();
763   bool found_for_testing = false;
764   for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
765     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
766                                      MsgField(_)));
767     IdFieldView for_testing(
768         trace_field, perfetto_protos_TracePacket_for_testing_field_number);
769     ASSERT_TRUE(for_testing.ok());
770     if (for_testing.size() == 0) {
771       continue;
772     }
773     found_for_testing = true;
774     ASSERT_EQ(for_testing.size(), 1u);
775     ASSERT_THAT(FieldView(for_testing.front()),
776                 ElementsAre(PbField(
777                     perfetto_protos_TestEvent_payload_field_number,
778                     MsgField(ElementsAre(PbField(
779                         perfetto_protos_TestEvent_TestPayload_str_field_number,
780                         StringField("ABCDEFGH")))))));
781   }
782   EXPECT_TRUE(found_for_testing);
783 }
784 
TEST_F(SharedLibDataSourceTest,Break)785 TEST_F(SharedLibDataSourceTest, Break) {
786   TracingSession tracing_session1 =
787       TracingSession::Builder().set_data_source_name(kDataSourceName1).Build();
788   TracingSession tracing_session2 =
789       TracingSession::Builder().set_data_source_name(kDataSourceName1).Build();
790 
791   PERFETTO_DS_TRACE(data_source_1, ctx) {
792     struct PerfettoDsRootTracePacket trace_packet;
793     PerfettoDsTracerPacketBegin(&ctx, &trace_packet);
794 
795     {
796       struct perfetto_protos_TestEvent for_testing;
797       perfetto_protos_TracePacket_begin_for_testing(&trace_packet.msg,
798                                                     &for_testing);
799       perfetto_protos_TracePacket_end_for_testing(&trace_packet.msg,
800                                                   &for_testing);
801     }
802     PerfettoDsTracerPacketEnd(&ctx, &trace_packet);
803     // Break: the packet will be emitted only on the first data source instance
804     // and therefore will not show up on `tracing_session2`.
805     PERFETTO_DS_TRACE_BREAK(data_source_1, ctx);
806   }
807 
808   tracing_session1.StopBlocking();
809   std::vector<uint8_t> data1 = tracing_session1.ReadBlocking();
810   EXPECT_THAT(
811       FieldView(data1),
812       Contains(PbField(perfetto_protos_Trace_packet_field_number,
813                        MsgField(Contains(PbField(
814                            perfetto_protos_TracePacket_for_testing_field_number,
815                            MsgField(_)))))));
816   tracing_session2.StopBlocking();
817   std::vector<uint8_t> data2 = tracing_session2.ReadBlocking();
818   EXPECT_THAT(
819       FieldView(data2),
820       Each(PbField(
821           perfetto_protos_Trace_packet_field_number,
822           MsgField(Not(Contains(PbField(
823               perfetto_protos_TracePacket_for_testing_field_number, _)))))));
824 }
825 
TEST_F(SharedLibDataSourceTest,FlushCb)826 TEST_F(SharedLibDataSourceTest, FlushCb) {
827   TracingSession tracing_session =
828       TracingSession::Builder().set_data_source_name(kDataSourceName1).Build();
829   WaitableEvent notification;
830 
831   PERFETTO_DS_TRACE(data_source_1, ctx) {
832     PerfettoDsTracerFlush(
833         &ctx,
834         [](void* p_notification) {
835           static_cast<WaitableEvent*>(p_notification)->Notify();
836         },
837         &notification);
838   }
839 
840   notification.WaitForNotification();
841   EXPECT_TRUE(notification.IsNotified());
842 }
843 
TEST_F(SharedLibDataSourceTest,LifetimeCallbacks)844 TEST_F(SharedLibDataSourceTest, LifetimeCallbacks) {
845   void* const kInstancePtr = reinterpret_cast<void*>(0x44);
846   testing::InSequence seq;
847   PerfettoDsInstanceIndex setup_inst, start_inst, stop_inst;
848   EXPECT_CALL(ds2_callbacks_, OnSetup(_, _, _, _, kDataSource2UserArg, _))
849       .WillOnce(DoAll(SaveArg<1>(&setup_inst), Return(kInstancePtr)));
850   EXPECT_CALL(ds2_callbacks_,
851               OnStart(_, _, kDataSource2UserArg, kInstancePtr, _))
852       .WillOnce(SaveArg<1>(&start_inst));
853 
854   TracingSession tracing_session =
855       TracingSession::Builder().set_data_source_name(kDataSourceName2).Build();
856 
857   EXPECT_CALL(ds2_callbacks_,
858               OnStop(_, _, kDataSource2UserArg, kInstancePtr, _))
859       .WillOnce(SaveArg<1>(&stop_inst));
860   EXPECT_CALL(ds2_callbacks_, OnDestroy(_, kDataSource2UserArg, kInstancePtr));
861 
862   tracing_session.StopBlocking();
863 
864   EXPECT_EQ(setup_inst, start_inst);
865   EXPECT_EQ(setup_inst, stop_inst);
866 }
867 
TEST_F(SharedLibDataSourceTest,StopDone)868 TEST_F(SharedLibDataSourceTest, StopDone) {
869   TracingSession tracing_session =
870       TracingSession::Builder().set_data_source_name(kDataSourceName2).Build();
871 
872   WaitableEvent stop_called;
873   struct PerfettoDsAsyncStopper* stopper;
874 
875   EXPECT_CALL(ds2_callbacks_, OnStop(_, _, kDataSource2UserArg, _, _))
876       .WillOnce([&](struct PerfettoDsImpl*, PerfettoDsInstanceIndex, void*,
877                     void*, struct PerfettoDsOnStopArgs* args) {
878         stopper = PerfettoDsOnStopArgsPostpone(args);
879         stop_called.Notify();
880       });
881 
882   std::thread t([&]() { tracing_session.StopBlocking(); });
883 
884   stop_called.WaitForNotification();
885   PerfettoDsStopDone(stopper);
886 
887   t.join();
888 }
889 
TEST_F(SharedLibDataSourceTest,FlushDone)890 TEST_F(SharedLibDataSourceTest, FlushDone) {
891   TracingSession tracing_session =
892       TracingSession::Builder().set_data_source_name(kDataSourceName2).Build();
893 
894   WaitableEvent flush_called;
895   WaitableEvent flush_done;
896   struct PerfettoDsAsyncFlusher* flusher;
897 
898   EXPECT_CALL(ds2_callbacks_, OnFlush(_, _, kDataSource2UserArg, _, _))
899       .WillOnce([&](struct PerfettoDsImpl*, PerfettoDsInstanceIndex, void*,
900                     void*, struct PerfettoDsOnFlushArgs* args) {
901         flusher = PerfettoDsOnFlushArgsPostpone(args);
902         flush_called.Notify();
903       });
904 
905   std::thread t([&]() {
906     tracing_session.FlushBlocking(/*timeout_ms=*/10000);
907     flush_done.Notify();
908   });
909 
910   flush_called.WaitForNotification();
911   EXPECT_FALSE(flush_done.IsNotified());
912   PerfettoDsFlushDone(flusher);
913   flush_done.WaitForNotification();
914 
915   t.join();
916 }
917 
TEST_F(SharedLibDataSourceTest,ThreadLocalState)918 TEST_F(SharedLibDataSourceTest, ThreadLocalState) {
919   bool ignored = false;
920   void* const kTlsPtr = &ignored;
921   TracingSession tracing_session =
922       TracingSession::Builder().set_data_source_name(kDataSourceName2).Build();
923 
924   EXPECT_CALL(ds2_callbacks_, OnCreateTls).WillOnce(Return(kTlsPtr));
925 
926   void* tls_state = nullptr;
927   PERFETTO_DS_TRACE(data_source_2, ctx) {
928     tls_state = PerfettoDsGetCustomTls(&data_source_2, &ctx);
929   }
930   EXPECT_EQ(Ds2ActualCustomState(tls_state), kTlsPtr);
931 
932   tracing_session.StopBlocking();
933 
934   EXPECT_CALL(ds2_callbacks_, OnDeleteTls(kTlsPtr));
935 
936   // The OnDelete callback will be called by
937   // DestroyStoppedTraceWritersForCurrentThread(). One way to trigger that is to
938   // trace with another data source.
939   TracingSession tracing_session_1 =
940       TracingSession::Builder().set_data_source_name(kDataSourceName1).Build();
941   PERFETTO_DS_TRACE(data_source_1, ctx) {}
942 }
943 
TEST_F(SharedLibDataSourceTest,IncrementalState)944 TEST_F(SharedLibDataSourceTest, IncrementalState) {
945   bool ignored = false;
946   void* const kIncrPtr = &ignored;
947   TracingSession tracing_session =
948       TracingSession::Builder().set_data_source_name(kDataSourceName2).Build();
949 
950   EXPECT_CALL(ds2_callbacks_, OnCreateIncr).WillOnce(Return(kIncrPtr));
951 
952   void* tls_state = nullptr;
953   PERFETTO_DS_TRACE(data_source_2, ctx) {
954     tls_state = PerfettoDsGetIncrementalState(&data_source_2, &ctx);
955   }
956   EXPECT_EQ(Ds2ActualCustomState(tls_state), kIncrPtr);
957 
958   tracing_session.StopBlocking();
959 
960   EXPECT_CALL(ds2_callbacks_, OnDeleteIncr(kIncrPtr));
961 
962   // The OnDelete callback will be called by
963   // DestroyStoppedTraceWritersForCurrentThread(). One way to trigger that is to
964   // trace with another data source.
965   TracingSession tracing_session_1 =
966       TracingSession::Builder().set_data_source_name(kDataSourceName1).Build();
967   PERFETTO_DS_TRACE(data_source_1, ctx) {}
968 }
969 
TEST_F(SharedLibDataSourceTest,GetInstanceLockedSuccess)970 TEST_F(SharedLibDataSourceTest, GetInstanceLockedSuccess) {
971   bool ignored = false;
972   void* const kInstancePtr = &ignored;
973   EXPECT_CALL(ds2_callbacks_, OnSetup(_, _, _, _, kDataSource2UserArg, _))
974       .WillOnce(Return(kInstancePtr));
975   TracingSession tracing_session =
976       TracingSession::Builder().set_data_source_name(kDataSourceName2).Build();
977 
978   void* arg = nullptr;
979   PERFETTO_DS_TRACE(data_source_2, ctx) {
980     arg = PerfettoDsImplGetInstanceLocked(data_source_2.impl, ctx.impl.inst_id);
981     if (arg) {
982       PerfettoDsImplReleaseInstanceLocked(data_source_2.impl, ctx.impl.inst_id);
983     }
984   }
985 
986   EXPECT_EQ(arg, kInstancePtr);
987 }
988 
TEST_F(SharedLibDataSourceTest,GetInstanceLockedFailure)989 TEST_F(SharedLibDataSourceTest, GetInstanceLockedFailure) {
990   bool ignored = false;
991   void* const kInstancePtr = &ignored;
992   EXPECT_CALL(ds2_callbacks_, OnSetup(_, _, _, _, kDataSource2UserArg, _))
993       .WillOnce(Return(kInstancePtr));
994   TracingSession tracing_session =
995       TracingSession::Builder().set_data_source_name(kDataSourceName2).Build();
996 
997   WaitableEvent inside_tracing;
998   WaitableEvent stopped;
999 
1000   std::thread t([&] {
1001     PERFETTO_DS_TRACE(data_source_2, ctx) {
1002       inside_tracing.Notify();
1003       stopped.WaitForNotification();
1004       void* arg =
1005           PerfettoDsImplGetInstanceLocked(data_source_2.impl, ctx.impl.inst_id);
1006       if (arg) {
1007         PerfettoDsImplReleaseInstanceLocked(data_source_2.impl,
1008                                             ctx.impl.inst_id);
1009       }
1010       EXPECT_THAT(arg, IsNull());
1011     }
1012   });
1013 
1014   inside_tracing.WaitForNotification();
1015   tracing_session.StopBlocking();
1016   stopped.Notify();
1017   t.join();
1018 }
1019 
1020 // Regression test for a `PerfettoDsImplReleaseInstanceLocked()`. Under very
1021 // specific circumstances, that depends on the implementation details of
1022 // `TracingMuxerImpl`, the following events can happen:
1023 // * `PerfettoDsImplGetInstanceLocked()` is called after
1024 //   `TracingMuxerImpl::StopDataSource_AsyncBeginImpl`, but before
1025 //   `TracingMuxerImpl::StopDataSource_AsyncEnd`.
1026 //   `PerfettoDsImplGetInstanceLocked()` succeeds and returns a valid instance.
1027 // * `TracingMuxerImpl::StopDataSource_AsyncEnd()` is called.
1028 //   `DataSourceStaticState::valid_instances` is reset.
1029 // * `PerfettoDsImplReleaseInstanceLocked()` is called.
1030 //
1031 // In this case `PerfettoDsImplReleaseInstanceLocked()` should work even though
1032 // the instance is not there in the valid_instances bitmap anymore.
1033 //
1034 // In order to reproduce the specific failure, the test makes assumptions about
1035 // the internal implementation (that valid_instance is changed outside of the
1036 // lock). If that were to change and the test would fail, the test should be
1037 // changed/deleted.
TEST_F(SharedLibDataSourceTest,GetInstanceLockedStopBeforeRelease)1038 TEST_F(SharedLibDataSourceTest, GetInstanceLockedStopBeforeRelease) {
1039   bool ignored = false;
1040   void* const kInstancePtr = &ignored;
1041   EXPECT_CALL(ds2_callbacks_, OnSetup(_, _, _, _, kDataSource2UserArg, _))
1042       .WillOnce(Return(kInstancePtr));
1043   TracingSession tracing_session =
1044       TracingSession::Builder().set_data_source_name(kDataSourceName2).Build();
1045 
1046   WaitableEvent inside_tracing;
1047   WaitableEvent stopping;
1048   WaitableEvent locked;
1049   WaitableEvent fully_stopped;
1050 
1051   std::thread t([&] {
1052     PERFETTO_DS_TRACE(data_source_2, ctx) {
1053       inside_tracing.Notify();
1054       stopping.WaitForNotification();
1055       void* arg =
1056           PerfettoDsImplGetInstanceLocked(data_source_2.impl, ctx.impl.inst_id);
1057       EXPECT_EQ(arg, kInstancePtr);
1058       locked.Notify();
1059       fully_stopped.WaitForNotification();
1060       if (arg) {
1061         PerfettoDsImplReleaseInstanceLocked(data_source_2.impl,
1062                                             ctx.impl.inst_id);
1063       }
1064     }
1065   });
1066 
1067   inside_tracing.WaitForNotification();
1068 
1069   struct PerfettoDsAsyncStopper* stopper = nullptr;
1070 
1071   EXPECT_CALL(ds2_callbacks_, OnStop(_, _, kDataSource2UserArg, _, _))
1072       .WillOnce([&](struct PerfettoDsImpl*, PerfettoDsInstanceIndex, void*,
1073                     void*, struct PerfettoDsOnStopArgs* args) {
1074         stopper = PerfettoDsOnStopArgsPostpone(args);
1075         stopping.Notify();
1076       });
1077 
1078   tracing_session.StopAsync();
1079 
1080   locked.WaitForNotification();
1081   PerfettoDsStopDone(stopper);
1082   // Wait for PerfettoDsImplTraceIterateBegin to return a nullptr tracer. This
1083   // means that the valid_instances bitmap has been reset.
1084   for (;;) {
1085     PerfettoDsImplTracerIterator iterator =
1086         PerfettoDsImplTraceIterateBegin(data_source_2.impl);
1087     if (iterator.tracer == nullptr) {
1088       break;
1089     }
1090     PerfettoDsImplTraceIterateBreak(data_source_2.impl, &iterator);
1091     std::this_thread::yield();
1092   }
1093   fully_stopped.Notify();
1094   tracing_session.WaitForStopped();
1095   t.join();
1096 }
1097 
1098 class SharedLibProducerTest : public testing::Test {
1099  protected:
SetUp()1100   void SetUp() override {
1101     struct PerfettoProducerInitArgs args = PERFETTO_PRODUCER_INIT_ARGS_INIT();
1102     args.backends = PERFETTO_BACKEND_IN_PROCESS;
1103     PerfettoProducerInit(args);
1104   }
1105 
TearDown()1106   void TearDown() override { perfetto::shlib::ResetForTesting(); }
1107 };
1108 
TEST_F(SharedLibProducerTest,ActivateTriggers)1109 TEST_F(SharedLibProducerTest, ActivateTriggers) {
1110   struct PerfettoPbMsgWriter writer;
1111   struct PerfettoHeapBuffer* hb = PerfettoHeapBufferCreate(&writer.writer);
1112 
1113   struct perfetto_protos_TraceConfig cfg;
1114   PerfettoPbMsgInit(&cfg.msg, &writer);
1115   {
1116     struct perfetto_protos_TraceConfig_BufferConfig buffers;
1117     perfetto_protos_TraceConfig_begin_buffers(&cfg, &buffers);
1118     perfetto_protos_TraceConfig_BufferConfig_set_size_kb(&buffers, 1024);
1119     perfetto_protos_TraceConfig_end_buffers(&cfg, &buffers);
1120   }
1121   {
1122     struct perfetto_protos_TraceConfig_TriggerConfig trigger_config;
1123     perfetto_protos_TraceConfig_begin_trigger_config(&cfg, &trigger_config);
1124     perfetto_protos_TraceConfig_TriggerConfig_set_trigger_mode(
1125         &trigger_config,
1126         perfetto_protos_TraceConfig_TriggerConfig_STOP_TRACING);
1127     perfetto_protos_TraceConfig_TriggerConfig_set_trigger_timeout_ms(
1128         &trigger_config, 5000);
1129     {
1130       struct perfetto_protos_TraceConfig_TriggerConfig_Trigger trigger;
1131       perfetto_protos_TraceConfig_TriggerConfig_begin_triggers(&trigger_config,
1132                                                                &trigger);
1133       perfetto_protos_TraceConfig_TriggerConfig_Trigger_set_cstr_name(
1134           &trigger, "trigger1");
1135       perfetto_protos_TraceConfig_TriggerConfig_end_triggers(&trigger_config,
1136                                                              &trigger);
1137     }
1138     perfetto_protos_TraceConfig_end_trigger_config(&cfg, &trigger_config);
1139   }
1140   size_t cfg_size = PerfettoStreamWriterGetWrittenSize(&writer.writer);
1141   std::unique_ptr<uint8_t[]> ser(new uint8_t[cfg_size]);
1142   PerfettoHeapBufferCopyInto(hb, &writer.writer, ser.get(), cfg_size);
1143   PerfettoHeapBufferDestroy(hb, &writer.writer);
1144 
1145   struct PerfettoTracingSessionImpl* ts =
1146       PerfettoTracingSessionCreate(PERFETTO_BACKEND_IN_PROCESS);
1147 
1148   PerfettoTracingSessionSetup(ts, ser.get(), cfg_size);
1149 
1150   PerfettoTracingSessionStartBlocking(ts);
1151   TracingSession tracing_session = TracingSession::Adopt(ts);
1152 
1153   const char* triggers[3];
1154   triggers[0] = "trigger0";
1155   triggers[1] = "trigger1";
1156   triggers[2] = nullptr;
1157   PerfettoProducerActivateTriggers(triggers, 10000);
1158 
1159   tracing_session.WaitForStopped();
1160   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1161   EXPECT_THAT(FieldView(data),
1162               Contains(PbField(
1163                   perfetto_protos_Trace_packet_field_number,
1164                   MsgField(Contains(PbField(
1165                       perfetto_protos_TracePacket_trigger_field_number,
1166                       MsgField(Contains(PbField(
1167                           perfetto_protos_Trigger_trigger_name_field_number,
1168                           StringField("trigger1"))))))))));
1169 }
1170 
1171 class SharedLibTrackEventTest : public testing::Test {
1172  protected:
SetUp()1173   void SetUp() override {
1174     struct PerfettoProducerInitArgs args = PERFETTO_PRODUCER_INIT_ARGS_INIT();
1175     args.backends = PERFETTO_BACKEND_IN_PROCESS;
1176     PerfettoProducerInit(args);
1177     PerfettoTeInit();
1178     PERFETTO_TE_REGISTER_CATEGORIES(TEST_CATEGORIES);
1179   }
1180 
TearDown()1181   void TearDown() override {
1182     PERFETTO_TE_UNREGISTER_CATEGORIES(TEST_CATEGORIES);
1183     perfetto::shlib::ResetForTesting();
1184   }
1185 };
1186 
TEST_F(SharedLibTrackEventTest,TrackEventFastpathOtherDsCatDisabled)1187 TEST_F(SharedLibTrackEventTest, TrackEventFastpathOtherDsCatDisabled) {
1188   TracingSession tracing_session =
1189       TracingSession::Builder()
1190           .set_data_source_name("other_nonexisting_datasource")
1191           .Build();
1192   EXPECT_FALSE(std::atomic_load(cat1.enabled));
1193   EXPECT_FALSE(std::atomic_load(cat2.enabled));
1194   EXPECT_FALSE(std::atomic_load(cat3.enabled));
1195 }
1196 
TEST_F(SharedLibTrackEventTest,TrackEventFastpathEmptyConfigDisablesAllCats)1197 TEST_F(SharedLibTrackEventTest, TrackEventFastpathEmptyConfigDisablesAllCats) {
1198   ASSERT_FALSE(std::atomic_load(cat1.enabled));
1199   ASSERT_FALSE(std::atomic_load(cat2.enabled));
1200   ASSERT_FALSE(std::atomic_load(cat3.enabled));
1201 
1202   TracingSession tracing_session =
1203       TracingSession::Builder().set_data_source_name("track_event").Build();
1204 
1205   EXPECT_FALSE(std::atomic_load(cat1.enabled));
1206   EXPECT_FALSE(std::atomic_load(cat2.enabled));
1207   EXPECT_FALSE(std::atomic_load(cat3.enabled));
1208 }
1209 
TEST_F(SharedLibTrackEventTest,TrackEventFastpathOneCatEnabled)1210 TEST_F(SharedLibTrackEventTest, TrackEventFastpathOneCatEnabled) {
1211   ASSERT_FALSE(std::atomic_load(cat1.enabled));
1212   ASSERT_FALSE(std::atomic_load(cat2.enabled));
1213   ASSERT_FALSE(std::atomic_load(cat3.enabled));
1214 
1215   TracingSession tracing_session = TracingSession::Builder()
1216                                        .set_data_source_name("track_event")
1217                                        .add_enabled_category("cat1")
1218                                        .add_disabled_category("*")
1219                                        .Build();
1220 
1221   EXPECT_TRUE(std::atomic_load(cat1.enabled));
1222   EXPECT_FALSE(std::atomic_load(cat2.enabled));
1223   EXPECT_FALSE(std::atomic_load(cat3.enabled));
1224 }
1225 
TEST_F(SharedLibTrackEventTest,TrackEventHlCategory)1226 TEST_F(SharedLibTrackEventTest, TrackEventHlCategory) {
1227   TracingSession tracing_session = TracingSession::Builder()
1228                                        .set_data_source_name("track_event")
1229                                        .add_enabled_category("*")
1230                                        .Build();
1231 
1232   EXPECT_TRUE(std::atomic_load(cat1.enabled));
1233   PERFETTO_TE(cat1, PERFETTO_TE_INSTANT(""));
1234 
1235   tracing_session.StopBlocking();
1236   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1237   bool found = false;
1238   for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
1239     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1240                                      MsgField(_)));
1241     IdFieldView track_event(
1242         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1243     if (track_event.size() == 0) {
1244       continue;
1245     }
1246     found = true;
1247     IdFieldView cat_iid_fields(
1248         track_event.front(),
1249         perfetto_protos_TrackEvent_category_iids_field_number);
1250     ASSERT_THAT(cat_iid_fields, ElementsAre(VarIntField(_)));
1251     uint64_t cat_iid = cat_iid_fields.front().value.integer64;
1252     EXPECT_THAT(
1253         trace_field,
1254         AllFieldsWithId(
1255             perfetto_protos_TracePacket_interned_data_field_number,
1256             ElementsAre(AllFieldsWithId(
1257                 perfetto_protos_InternedData_event_categories_field_number,
1258                 ElementsAre(MsgField(UnorderedElementsAre(
1259                     PbField(perfetto_protos_EventCategory_iid_field_number,
1260                             VarIntField(cat_iid)),
1261                     PbField(perfetto_protos_EventCategory_name_field_number,
1262                             StringField("cat1")))))))));
1263   }
1264   EXPECT_TRUE(found);
1265 }
1266 
TEST_F(SharedLibTrackEventTest,TrackEventHlDynamicCategory)1267 TEST_F(SharedLibTrackEventTest, TrackEventHlDynamicCategory) {
1268   TracingSession tracing_session = TracingSession::Builder()
1269                                        .set_data_source_name("track_event")
1270                                        .add_enabled_category("dyn1")
1271                                        .add_enabled_category("cat1")
1272                                        .add_disabled_category("*")
1273                                        .Build();
1274 
1275   PERFETTO_TE(PERFETTO_TE_DYNAMIC_CATEGORY, PERFETTO_TE_INSTANT(""),
1276               PERFETTO_TE_DYNAMIC_CATEGORY_STRING("dyn2"));
1277   PERFETTO_TE(PERFETTO_TE_DYNAMIC_CATEGORY, PERFETTO_TE_INSTANT(""),
1278               PERFETTO_TE_DYNAMIC_CATEGORY_STRING("dyn1"));
1279 
1280   tracing_session.StopBlocking();
1281   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1282   bool found = false;
1283   for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
1284     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1285                                      MsgField(_)));
1286     IdFieldView track_event(
1287         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1288     if (track_event.size() == 0) {
1289       continue;
1290     }
1291     found = true;
1292     EXPECT_THAT(track_event,
1293                 ElementsAre(AllFieldsWithId(
1294                     perfetto_protos_TrackEvent_categories_field_number,
1295                     ElementsAre(StringField("dyn1")))));
1296   }
1297   EXPECT_TRUE(found);
1298 }
1299 
TEST_F(SharedLibTrackEventTest,TrackEventHlDynamicCategoryMultipleSessions)1300 TEST_F(SharedLibTrackEventTest, TrackEventHlDynamicCategoryMultipleSessions) {
1301   TracingSession tracing_session1 = TracingSession::Builder()
1302                                         .set_data_source_name("track_event")
1303                                         .add_enabled_category("cat1")
1304                                         .add_enabled_category("dyn1")
1305                                         .add_disabled_category("dyn2")
1306                                         .add_disabled_category("*")
1307                                         .Build();
1308 
1309   TracingSession tracing_session2 = TracingSession::Builder()
1310                                         .set_data_source_name("track_event")
1311                                         .add_enabled_category("cat1")
1312                                         .add_enabled_category("dyn2")
1313                                         .add_disabled_category("dyn1")
1314                                         .add_disabled_category("*")
1315                                         .Build();
1316 
1317   PERFETTO_TE(PERFETTO_TE_DYNAMIC_CATEGORY,
1318               PERFETTO_TE_INSTANT("interned_string"),
1319               PERFETTO_TE_DYNAMIC_CATEGORY_STRING("dyn1"));
1320   PERFETTO_TE(PERFETTO_TE_DYNAMIC_CATEGORY,
1321               PERFETTO_TE_INSTANT("interned_string"),
1322               PERFETTO_TE_DYNAMIC_CATEGORY_STRING("dyn2"));
1323   PERFETTO_TE(cat1, PERFETTO_TE_INSTANT(""));
1324 
1325   tracing_session1.StopBlocking();
1326   std::vector<uint8_t> data1 = tracing_session1.ReadBlocking();
1327   EXPECT_THAT(
1328       FieldView(data1),
1329       Contains(PbField(
1330           perfetto_protos_Trace_packet_field_number,
1331           MsgField(AllOf(
1332               Contains(PbField(
1333                   perfetto_protos_TracePacket_track_event_field_number,
1334                   MsgField(Contains(PbField(
1335                       perfetto_protos_TrackEvent_categories_field_number,
1336                       StringField("dyn1")))))),
1337               Contains(PbField(
1338                   perfetto_protos_TracePacket_interned_data_field_number,
1339                   MsgField(Contains(PbField(
1340                       perfetto_protos_InternedData_event_names_field_number,
1341                       MsgField(Contains(
1342                           PbField(perfetto_protos_EventName_name_field_number,
1343                                   StringField("interned_string"))))))))))))));
1344   tracing_session2.StopBlocking();
1345   std::vector<uint8_t> data2 = tracing_session2.ReadBlocking();
1346   EXPECT_THAT(
1347       FieldView(data2),
1348       Contains(PbField(
1349           perfetto_protos_Trace_packet_field_number,
1350           MsgField(AllOf(
1351               Contains(PbField(
1352                   perfetto_protos_TracePacket_track_event_field_number,
1353                   MsgField(Contains(PbField(
1354                       perfetto_protos_TrackEvent_categories_field_number,
1355                       StringField("dyn2")))))),
1356               Contains(PbField(
1357                   perfetto_protos_TracePacket_interned_data_field_number,
1358                   MsgField(Contains(PbField(
1359                       perfetto_protos_InternedData_event_names_field_number,
1360                       MsgField(Contains(
1361                           PbField(perfetto_protos_EventName_name_field_number,
1362                                   StringField("interned_string"))))))))))))));
1363 }
1364 
TEST_F(SharedLibTrackEventTest,TrackEventHlInstant)1365 TEST_F(SharedLibTrackEventTest, TrackEventHlInstant) {
1366   TracingSession tracing_session = TracingSession::Builder()
1367                                        .set_data_source_name("track_event")
1368                                        .add_enabled_category("*")
1369                                        .Build();
1370 
1371   PERFETTO_TE(cat1, PERFETTO_TE_INSTANT("event"));
1372 
1373   tracing_session.StopBlocking();
1374   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1375   bool found = false;
1376   for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
1377     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1378                                      MsgField(_)));
1379     IdFieldView track_event(
1380         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1381     if (track_event.size() == 0) {
1382       continue;
1383     }
1384     found = true;
1385     ASSERT_THAT(track_event,
1386                 ElementsAre(AllFieldsWithId(
1387                     perfetto_protos_TrackEvent_type_field_number,
1388                     ElementsAre(VarIntField(
1389                         perfetto_protos_TrackEvent_TYPE_INSTANT)))));
1390     IdFieldView name_iid_fields(
1391         track_event.front(), perfetto_protos_TrackEvent_name_iid_field_number);
1392     ASSERT_THAT(name_iid_fields, ElementsAre(VarIntField(_)));
1393     uint64_t name_iid = name_iid_fields.front().value.integer64;
1394     EXPECT_THAT(trace_field,
1395                 AllFieldsWithId(
1396                     perfetto_protos_TracePacket_interned_data_field_number,
1397                     ElementsAre(AllFieldsWithId(
1398                         perfetto_protos_InternedData_event_names_field_number,
1399                         ElementsAre(MsgField(UnorderedElementsAre(
1400                             PbField(perfetto_protos_EventName_iid_field_number,
1401                                     VarIntField(name_iid)),
1402                             PbField(perfetto_protos_EventName_name_field_number,
1403                                     StringField("event")))))))));
1404   }
1405   EXPECT_TRUE(found);
1406 }
1407 
TEST_F(SharedLibTrackEventTest,TrackEventLlInstant)1408 TEST_F(SharedLibTrackEventTest, TrackEventLlInstant) {
1409   TracingSession tracing_session = TracingSession::Builder()
1410                                        .set_data_source_name("track_event")
1411                                        .add_enabled_category("*")
1412                                        .Build();
1413 
1414   if (PERFETTO_UNLIKELY(PERFETTO_ATOMIC_LOAD_EXPLICIT(
1415           cat1.enabled, PERFETTO_MEMORY_ORDER_RELAXED))) {
1416     struct PerfettoTeTimestamp timestamp = PerfettoTeGetTimestamp();
1417     int32_t type = PERFETTO_TE_TYPE_INSTANT;
1418     const char* name = "event";
1419     for (struct PerfettoTeLlIterator ctx =
1420              PerfettoTeLlBeginSlowPath(&cat1, timestamp);
1421          ctx.impl.ds.tracer != nullptr;
1422          PerfettoTeLlNext(&cat1, timestamp, &ctx)) {
1423       uint64_t name_iid;
1424       {
1425         struct PerfettoDsRootTracePacket trace_packet;
1426         PerfettoTeLlPacketBegin(&ctx, &trace_packet);
1427         PerfettoTeLlWriteTimestamp(&trace_packet.msg, &timestamp);
1428         perfetto_protos_TracePacket_set_sequence_flags(
1429             &trace_packet.msg,
1430             perfetto_protos_TracePacket_SEQ_NEEDS_INCREMENTAL_STATE);
1431         {
1432           struct PerfettoTeLlInternContext intern_ctx;
1433           PerfettoTeLlInternContextInit(&intern_ctx, ctx.impl.incr,
1434                                         &trace_packet.msg);
1435           PerfettoTeLlInternRegisteredCat(&intern_ctx, &cat1);
1436           name_iid = PerfettoTeLlInternEventName(&intern_ctx, name);
1437           PerfettoTeLlInternContextDestroy(&intern_ctx);
1438         }
1439         {
1440           struct perfetto_protos_TrackEvent te_msg;
1441           perfetto_protos_TracePacket_begin_track_event(&trace_packet.msg,
1442                                                         &te_msg);
1443           perfetto_protos_TrackEvent_set_type(
1444               &te_msg, static_cast<enum perfetto_protos_TrackEvent_Type>(type));
1445           PerfettoTeLlWriteRegisteredCat(&te_msg, &cat1);
1446           PerfettoTeLlWriteInternedEventName(&te_msg, name_iid);
1447           perfetto_protos_TracePacket_end_track_event(&trace_packet.msg,
1448                                                       &te_msg);
1449         }
1450         PerfettoTeLlPacketEnd(&ctx, &trace_packet);
1451       }
1452     }
1453   }
1454 
1455   tracing_session.StopBlocking();
1456   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1457   bool found = false;
1458   for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
1459     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1460                                      MsgField(_)));
1461     IdFieldView track_event(
1462         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1463     if (track_event.size() == 0) {
1464       continue;
1465     }
1466     found = true;
1467     ASSERT_THAT(track_event,
1468                 ElementsAre(AllFieldsWithId(
1469                     perfetto_protos_TrackEvent_type_field_number,
1470                     ElementsAre(VarIntField(
1471                         perfetto_protos_TrackEvent_TYPE_INSTANT)))));
1472     IdFieldView name_iid_fields(
1473         track_event.front(), perfetto_protos_TrackEvent_name_iid_field_number);
1474     ASSERT_THAT(name_iid_fields, ElementsAre(VarIntField(_)));
1475     uint64_t name_iid = name_iid_fields.front().value.integer64;
1476     EXPECT_THAT(trace_field,
1477                 AllFieldsWithId(
1478                     perfetto_protos_TracePacket_interned_data_field_number,
1479                     ElementsAre(AllFieldsWithId(
1480                         perfetto_protos_InternedData_event_names_field_number,
1481                         ElementsAre(MsgField(UnorderedElementsAre(
1482                             PbField(perfetto_protos_EventName_iid_field_number,
1483                                     VarIntField(name_iid)),
1484                             PbField(perfetto_protos_EventName_name_field_number,
1485                                     StringField("event")))))))));
1486   }
1487   EXPECT_TRUE(found);
1488 }
1489 
TEST_F(SharedLibTrackEventTest,TrackEventHlInstantNoIntern)1490 TEST_F(SharedLibTrackEventTest, TrackEventHlInstantNoIntern) {
1491   TracingSession tracing_session = TracingSession::Builder()
1492                                        .set_data_source_name("track_event")
1493                                        .add_enabled_category("*")
1494                                        .Build();
1495 
1496   PERFETTO_TE(cat1, PERFETTO_TE_INSTANT("event"), PERFETTO_TE_NO_INTERN());
1497 
1498   tracing_session.StopBlocking();
1499   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1500   bool found = false;
1501   for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
1502     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1503                                      MsgField(_)));
1504     IdFieldView track_event(
1505         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1506     if (track_event.size() == 0) {
1507       continue;
1508     }
1509     found = true;
1510     ASSERT_THAT(
1511         track_event,
1512         ElementsAre(AllOf(
1513             AllFieldsWithId(perfetto_protos_TrackEvent_type_field_number,
1514                             ElementsAre(VarIntField(
1515                                 perfetto_protos_TrackEvent_TYPE_INSTANT))),
1516             AllFieldsWithId(perfetto_protos_TrackEvent_name_field_number,
1517                             ElementsAre(StringField("event"))))));
1518   }
1519   EXPECT_TRUE(found);
1520 }
1521 
TEST_F(SharedLibTrackEventTest,TrackEventHlDbgArg)1522 TEST_F(SharedLibTrackEventTest, TrackEventHlDbgArg) {
1523   TracingSession tracing_session = TracingSession::Builder()
1524                                        .set_data_source_name("track_event")
1525                                        .add_enabled_category("*")
1526                                        .Build();
1527 
1528   PERFETTO_TE(cat1, PERFETTO_TE_INSTANT("event"),
1529               PERFETTO_TE_ARG_UINT64("arg_name", 42));
1530 
1531   tracing_session.StopBlocking();
1532   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1533   bool found = false;
1534   for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
1535     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1536                                      MsgField(_)));
1537     IdFieldView track_event(
1538         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1539     if (track_event.size() == 0) {
1540       continue;
1541     }
1542     found = true;
1543     ASSERT_THAT(track_event,
1544                 ElementsAre(AllFieldsWithId(
1545                     perfetto_protos_TrackEvent_type_field_number,
1546                     ElementsAre(VarIntField(
1547                         perfetto_protos_TrackEvent_TYPE_INSTANT)))));
1548     IdFieldView name_iid_fields(
1549         track_event.front(), perfetto_protos_TrackEvent_name_iid_field_number);
1550     ASSERT_THAT(name_iid_fields, ElementsAre(VarIntField(_)));
1551     uint64_t name_iid = name_iid_fields.front().value.integer64;
1552     IdFieldView debug_annot_fields(
1553         track_event.front(),
1554         perfetto_protos_TrackEvent_debug_annotations_field_number);
1555     ASSERT_THAT(
1556         debug_annot_fields,
1557         ElementsAre(MsgField(UnorderedElementsAre(
1558             PbField(perfetto_protos_DebugAnnotation_name_iid_field_number,
1559                     VarIntField(_)),
1560             PbField(perfetto_protos_DebugAnnotation_uint_value_field_number,
1561                     VarIntField(42))))));
1562     uint64_t arg_name_iid =
1563         IdFieldView(debug_annot_fields.front(),
1564                     perfetto_protos_DebugAnnotation_name_iid_field_number)
1565             .front()
1566             .value.integer64;
1567     EXPECT_THAT(
1568         trace_field,
1569         AllFieldsWithId(
1570             perfetto_protos_TracePacket_interned_data_field_number,
1571             ElementsAre(AllOf(
1572                 AllFieldsWithId(
1573                     perfetto_protos_InternedData_event_names_field_number,
1574                     ElementsAre(MsgField(UnorderedElementsAre(
1575                         PbField(perfetto_protos_EventName_iid_field_number,
1576                                 VarIntField(name_iid)),
1577                         PbField(perfetto_protos_EventName_name_field_number,
1578                                 StringField("event")))))),
1579                 AllFieldsWithId(
1580                     perfetto_protos_InternedData_debug_annotation_names_field_number,
1581                     ElementsAre(MsgField(UnorderedElementsAre(
1582                         PbField(
1583                             perfetto_protos_DebugAnnotationName_iid_field_number,
1584                             VarIntField(arg_name_iid)),
1585                         PbField(
1586                             perfetto_protos_DebugAnnotationName_name_field_number,
1587                             StringField("arg_name"))))))))));
1588   }
1589   EXPECT_TRUE(found);
1590 }
1591 
TEST_F(SharedLibTrackEventTest,TrackEventHlNamedTrack)1592 TEST_F(SharedLibTrackEventTest, TrackEventHlNamedTrack) {
1593   TracingSession tracing_session = TracingSession::Builder()
1594                                        .set_data_source_name("track_event")
1595                                        .add_enabled_category("*")
1596                                        .Build();
1597 
1598   PERFETTO_TE(cat1, PERFETTO_TE_INSTANT("event"),
1599               PERFETTO_TE_NAMED_TRACK("MyTrack", 1, 2));
1600 
1601   uint64_t kExpectedUuid = PerfettoTeNamedTrackUuid("MyTrack", 1, 2);
1602 
1603   tracing_session.StopBlocking();
1604   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1605   EXPECT_THAT(
1606       FieldView(data),
1607       AllOf(
1608           Contains(PbField(
1609               perfetto_protos_Trace_packet_field_number,
1610               AllFieldsWithId(
1611                   perfetto_protos_TracePacket_track_descriptor_field_number,
1612                   ElementsAre(MsgField(UnorderedElementsAre(
1613                       PbField(perfetto_protos_TrackDescriptor_uuid_field_number,
1614                               VarIntField(kExpectedUuid)),
1615                       PbField(perfetto_protos_TrackDescriptor_name_field_number,
1616                               StringField("MyTrack")),
1617                       PbField(
1618                           perfetto_protos_TrackDescriptor_parent_uuid_field_number,
1619                           VarIntField(2)))))))),
1620           Contains(PbField(
1621               perfetto_protos_Trace_packet_field_number,
1622               AllFieldsWithId(
1623                   perfetto_protos_TracePacket_track_event_field_number,
1624                   ElementsAre(AllOf(
1625                       AllFieldsWithId(
1626                           perfetto_protos_TrackEvent_type_field_number,
1627                           ElementsAre(VarIntField(
1628                               perfetto_protos_TrackEvent_TYPE_INSTANT))),
1629                       AllFieldsWithId(
1630                           perfetto_protos_TrackEvent_track_uuid_field_number,
1631                           ElementsAre(VarIntField(kExpectedUuid))))))))));
1632 }
1633 
TEST_F(SharedLibTrackEventTest,TrackEventHlRegisteredCounter)1634 TEST_F(SharedLibTrackEventTest, TrackEventHlRegisteredCounter) {
1635   TracingSession tracing_session = TracingSession::Builder()
1636                                        .set_data_source_name("track_event")
1637                                        .add_enabled_category("*")
1638                                        .Build();
1639 
1640   PerfettoTeRegisteredTrack my_counter_track;
1641   PerfettoTeCounterTrackRegister(&my_counter_track, "MyCounter",
1642                                  PerfettoTeProcessTrackUuid());
1643 
1644   PERFETTO_TE(cat1, PERFETTO_TE_COUNTER(),
1645               PERFETTO_TE_REGISTERED_TRACK(&my_counter_track),
1646               PERFETTO_TE_INT_COUNTER(42));
1647 
1648   PerfettoTeRegisteredTrackUnregister(&my_counter_track);
1649 
1650   uint64_t kExpectedUuid =
1651       PerfettoTeCounterTrackUuid("MyCounter", PerfettoTeProcessTrackUuid());
1652 
1653   tracing_session.StopBlocking();
1654   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1655   EXPECT_THAT(
1656       FieldView(data),
1657       AllOf(
1658           Contains(PbField(
1659               perfetto_protos_Trace_packet_field_number,
1660               AllFieldsWithId(
1661                   perfetto_protos_TracePacket_track_descriptor_field_number,
1662                   ElementsAre(MsgField(UnorderedElementsAre(
1663                       PbField(perfetto_protos_TrackDescriptor_uuid_field_number,
1664                               VarIntField(kExpectedUuid)),
1665                       PbField(perfetto_protos_TrackDescriptor_name_field_number,
1666                               StringField("MyCounter")),
1667                       PbField(
1668                           perfetto_protos_TrackDescriptor_parent_uuid_field_number,
1669                           VarIntField(PerfettoTeProcessTrackUuid())),
1670                       PbField(
1671                           perfetto_protos_TrackDescriptor_counter_field_number,
1672                           MsgField(_)))))))),
1673           Contains(PbField(
1674               perfetto_protos_Trace_packet_field_number,
1675               AllFieldsWithId(
1676                   perfetto_protos_TracePacket_track_event_field_number,
1677                   ElementsAre(AllOf(
1678                       AllFieldsWithId(
1679                           perfetto_protos_TrackEvent_type_field_number,
1680                           ElementsAre(VarIntField(
1681                               perfetto_protos_TrackEvent_TYPE_COUNTER))),
1682                       AllFieldsWithId(
1683                           perfetto_protos_TrackEvent_counter_value_field_number,
1684                           ElementsAre(VarIntField(42))),
1685                       AllFieldsWithId(
1686                           perfetto_protos_TrackEvent_track_uuid_field_number,
1687                           ElementsAre(VarIntField(kExpectedUuid))))))))));
1688 }
1689 
TEST_F(SharedLibTrackEventTest,Scoped)1690 TEST_F(SharedLibTrackEventTest, Scoped) {
1691   TracingSession tracing_session = TracingSession::Builder()
1692                                        .set_data_source_name("track_event")
1693                                        .add_enabled_category("*")
1694                                        .Build();
1695 
1696   {
1697     PERFETTO_TE_SCOPED(cat1, PERFETTO_TE_SLICE("slice"),
1698                        PERFETTO_TE_ARG_UINT64("arg_name", 42));
1699     PERFETTO_TE(cat1, PERFETTO_TE_INSTANT("event"));
1700   }
1701 
1702   tracing_session.StopBlocking();
1703   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1704   auto trace_view = FieldView(data);
1705   auto it = trace_view.begin();
1706   for (; it != trace_view.end(); it++) {
1707     struct PerfettoPbDecoderField trace_field = *it;
1708     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1709                                      MsgField(_)));
1710     IdFieldView track_event(
1711         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1712     if (track_event.size() == 0) {
1713       continue;
1714     }
1715 
1716     ASSERT_THAT(track_event,
1717                 ElementsAre(AllFieldsWithId(
1718                     perfetto_protos_TrackEvent_type_field_number,
1719                     ElementsAre(VarIntField(
1720                         perfetto_protos_TrackEvent_TYPE_SLICE_BEGIN)))));
1721     IdFieldView name_iid_fields(
1722         track_event.front(), perfetto_protos_TrackEvent_name_iid_field_number);
1723     ASSERT_THAT(name_iid_fields, ElementsAre(VarIntField(_)));
1724     uint64_t name_iid = name_iid_fields.front().value.integer64;
1725     IdFieldView debug_annot_fields(
1726         track_event.front(),
1727         perfetto_protos_TrackEvent_debug_annotations_field_number);
1728     ASSERT_THAT(
1729         debug_annot_fields,
1730         ElementsAre(MsgField(UnorderedElementsAre(
1731             PbField(perfetto_protos_DebugAnnotation_name_iid_field_number,
1732                     VarIntField(_)),
1733             PbField(perfetto_protos_DebugAnnotation_uint_value_field_number,
1734                     VarIntField(42))))));
1735     uint64_t arg_name_iid =
1736         IdFieldView(debug_annot_fields.front(),
1737                     perfetto_protos_DebugAnnotation_name_iid_field_number)
1738             .front()
1739             .value.integer64;
1740     EXPECT_THAT(
1741         trace_field,
1742         AllFieldsWithId(
1743             perfetto_protos_TracePacket_interned_data_field_number,
1744             ElementsAre(AllOf(
1745                 AllFieldsWithId(
1746                     perfetto_protos_InternedData_event_names_field_number,
1747                     ElementsAre(MsgField(UnorderedElementsAre(
1748                         PbField(perfetto_protos_EventName_iid_field_number,
1749                                 VarIntField(name_iid)),
1750                         PbField(perfetto_protos_EventName_name_field_number,
1751                                 StringField("slice")))))),
1752                 AllFieldsWithId(
1753                     perfetto_protos_InternedData_debug_annotation_names_field_number,
1754                     ElementsAre(MsgField(UnorderedElementsAre(
1755                         PbField(
1756                             perfetto_protos_DebugAnnotationName_iid_field_number,
1757                             VarIntField(arg_name_iid)),
1758                         PbField(
1759                             perfetto_protos_DebugAnnotationName_name_field_number,
1760                             StringField("arg_name"))))))))));
1761     it++;
1762     break;
1763   }
1764   ASSERT_NE(it, trace_view.end());
1765   for (; it != trace_view.end(); it++) {
1766     struct PerfettoPbDecoderField trace_field = *it;
1767     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1768                                      MsgField(_)));
1769     IdFieldView track_event(
1770         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1771     if (track_event.size() == 0) {
1772       continue;
1773     }
1774     ASSERT_THAT(track_event,
1775                 ElementsAre(AllFieldsWithId(
1776                     perfetto_protos_TrackEvent_type_field_number,
1777                     ElementsAre(VarIntField(
1778                         perfetto_protos_TrackEvent_TYPE_INSTANT)))));
1779     IdFieldView name_iid_fields(
1780         track_event.front(), perfetto_protos_TrackEvent_name_iid_field_number);
1781     ASSERT_THAT(name_iid_fields, ElementsAre(VarIntField(_)));
1782     uint64_t name_iid = name_iid_fields.front().value.integer64;
1783     EXPECT_THAT(trace_field,
1784                 AllFieldsWithId(
1785                     perfetto_protos_TracePacket_interned_data_field_number,
1786                     ElementsAre(AllFieldsWithId(
1787                         perfetto_protos_InternedData_event_names_field_number,
1788                         ElementsAre(MsgField(UnorderedElementsAre(
1789                             PbField(perfetto_protos_EventName_iid_field_number,
1790                                     VarIntField(name_iid)),
1791                             PbField(perfetto_protos_EventName_name_field_number,
1792                                     StringField("event")))))))));
1793     it++;
1794     break;
1795   }
1796   ASSERT_NE(it, trace_view.end());
1797   for (; it != trace_view.end(); it++) {
1798     struct PerfettoPbDecoderField trace_field = *it;
1799     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1800                                      MsgField(_)));
1801     IdFieldView track_event(
1802         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1803     if (track_event.size() == 0) {
1804       continue;
1805     }
1806     ASSERT_THAT(track_event,
1807                 ElementsAre(AllFieldsWithId(
1808                     perfetto_protos_TrackEvent_type_field_number,
1809                     ElementsAre(VarIntField(
1810                         perfetto_protos_TrackEvent_TYPE_SLICE_END)))));
1811     IdFieldView debug_annot_fields(
1812         track_event.front(),
1813         perfetto_protos_TrackEvent_debug_annotations_field_number);
1814     ASSERT_THAT(debug_annot_fields, ElementsAre());
1815     it++;
1816     break;
1817   }
1818 }
1819 
TEST_F(SharedLibTrackEventTest,ScopedDisabled)1820 TEST_F(SharedLibTrackEventTest, ScopedDisabled) {
1821   TracingSession tracing_session = TracingSession::Builder()
1822                                        .set_data_source_name("track_event")
1823                                        .add_disabled_category("cat1")
1824                                        .Build();
1825   // Check that the PERFETTO_TE_SCOPED macro does not have any effect if the
1826   // category is disabled.
1827   { PERFETTO_TE_SCOPED(cat1, PERFETTO_TE_SLICE("slice")); }
1828 
1829   tracing_session.StopBlocking();
1830   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1831   auto trace_view = FieldView(data);
1832   auto it = trace_view.begin();
1833   for (; it != trace_view.end(); it++) {
1834     struct PerfettoPbDecoderField trace_field = *it;
1835     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1836                                      MsgField(_)));
1837     IdFieldView track_event(
1838         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1839     ASSERT_EQ(track_event.size(), 0u);
1840   }
1841 }
1842 
TEST_F(SharedLibTrackEventTest,ScopedSingleLine)1843 TEST_F(SharedLibTrackEventTest, ScopedSingleLine) {
1844   TracingSession tracing_session = TracingSession::Builder()
1845                                        .set_data_source_name("track_event")
1846                                        .add_enabled_category("*")
1847                                        .Build();
1848 
1849   // Check that the PERFETTO_TE_SCOPED macro is expanded into a single
1850   // statement. Emitting the end event should not escape
1851   if (false)
1852     PERFETTO_TE_SCOPED(cat1, PERFETTO_TE_SLICE("slice"));
1853 
1854   tracing_session.StopBlocking();
1855   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1856   auto trace_view = FieldView(data);
1857   auto it = trace_view.begin();
1858   for (; it != trace_view.end(); it++) {
1859     struct PerfettoPbDecoderField trace_field = *it;
1860     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1861                                      MsgField(_)));
1862     IdFieldView track_event(
1863         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1864     ASSERT_EQ(track_event.size(), 0u);
1865   }
1866 }
1867 
TEST_F(SharedLibTrackEventTest,ScopedCapture)1868 TEST_F(SharedLibTrackEventTest, ScopedCapture) {
1869   TracingSession tracing_session = TracingSession::Builder()
1870                                        .set_data_source_name("track_event")
1871                                        .add_enabled_category("*")
1872                                        .Build();
1873 
1874   // Check that the PERFETTO_TE_SCOPED macro can capture variables.
1875   uint64_t value = 42;
1876   {
1877     PERFETTO_TE_SCOPED(cat1, PERFETTO_TE_SLICE("slice"),
1878                        PERFETTO_TE_ARG_UINT64("arg_name", value));
1879   }
1880 
1881   tracing_session.StopBlocking();
1882   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1883   auto trace_view = FieldView(data);
1884   auto it = trace_view.begin();
1885   for (; it != trace_view.end(); it++) {
1886     struct PerfettoPbDecoderField trace_field = *it;
1887     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1888                                      MsgField(_)));
1889     IdFieldView track_event(
1890         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1891     if (track_event.size() == 0) {
1892       continue;
1893     }
1894 
1895     ASSERT_THAT(track_event,
1896                 ElementsAre(AllFieldsWithId(
1897                     perfetto_protos_TrackEvent_type_field_number,
1898                     ElementsAre(VarIntField(
1899                         perfetto_protos_TrackEvent_TYPE_SLICE_BEGIN)))));
1900     IdFieldView name_iid_fields(
1901         track_event.front(), perfetto_protos_TrackEvent_name_iid_field_number);
1902     ASSERT_THAT(name_iid_fields, ElementsAre(VarIntField(_)));
1903     uint64_t name_iid = name_iid_fields.front().value.integer64;
1904     IdFieldView debug_annot_fields(
1905         track_event.front(),
1906         perfetto_protos_TrackEvent_debug_annotations_field_number);
1907     ASSERT_THAT(
1908         debug_annot_fields,
1909         ElementsAre(MsgField(UnorderedElementsAre(
1910             PbField(perfetto_protos_DebugAnnotation_name_iid_field_number,
1911                     VarIntField(_)),
1912             PbField(perfetto_protos_DebugAnnotation_uint_value_field_number,
1913                     VarIntField(42))))));
1914     uint64_t arg_name_iid =
1915         IdFieldView(debug_annot_fields.front(),
1916                     perfetto_protos_DebugAnnotation_name_iid_field_number)
1917             .front()
1918             .value.integer64;
1919     EXPECT_THAT(
1920         trace_field,
1921         AllFieldsWithId(
1922             perfetto_protos_TracePacket_interned_data_field_number,
1923             ElementsAre(AllOf(
1924                 AllFieldsWithId(
1925                     perfetto_protos_InternedData_event_names_field_number,
1926                     ElementsAre(MsgField(UnorderedElementsAre(
1927                         PbField(perfetto_protos_EventName_iid_field_number,
1928                                 VarIntField(name_iid)),
1929                         PbField(perfetto_protos_EventName_name_field_number,
1930                                 StringField("slice")))))),
1931                 AllFieldsWithId(
1932                     perfetto_protos_InternedData_debug_annotation_names_field_number,
1933                     ElementsAre(MsgField(UnorderedElementsAre(
1934                         PbField(
1935                             perfetto_protos_DebugAnnotationName_iid_field_number,
1936                             VarIntField(arg_name_iid)),
1937                         PbField(
1938                             perfetto_protos_DebugAnnotationName_name_field_number,
1939                             StringField("arg_name"))))))))));
1940     it++;
1941     break;
1942   }
1943   ASSERT_NE(it, trace_view.end());
1944   for (; it != trace_view.end(); it++) {
1945     struct PerfettoPbDecoderField trace_field = *it;
1946     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1947                                      MsgField(_)));
1948     IdFieldView track_event(
1949         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1950     if (track_event.size() == 0) {
1951       continue;
1952     }
1953     ASSERT_THAT(track_event,
1954                 ElementsAre(AllFieldsWithId(
1955                     perfetto_protos_TrackEvent_type_field_number,
1956                     ElementsAre(VarIntField(
1957                         perfetto_protos_TrackEvent_TYPE_SLICE_END)))));
1958     IdFieldView debug_annot_fields(
1959         track_event.front(),
1960         perfetto_protos_TrackEvent_debug_annotations_field_number);
1961     ASSERT_THAT(debug_annot_fields, ElementsAre());
1962     it++;
1963     break;
1964   }
1965 }
1966 
TEST_F(SharedLibTrackEventTest,ScopedFunc)1967 TEST_F(SharedLibTrackEventTest, ScopedFunc) {
1968   TracingSession tracing_session = TracingSession::Builder()
1969                                        .set_data_source_name("track_event")
1970                                        .add_enabled_category("*")
1971                                        .Build();
1972 
1973   // Check that using __func__ works as expected.
1974   { PERFETTO_TE_SCOPED(cat1, PERFETTO_TE_SLICE(__func__)); }
1975 
1976   tracing_session.StopBlocking();
1977   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1978   auto trace_view = FieldView(data);
1979   auto it = trace_view.begin();
1980   for (; it != trace_view.end(); it++) {
1981     struct PerfettoPbDecoderField trace_field = *it;
1982     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1983                                      MsgField(_)));
1984     IdFieldView track_event(
1985         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1986     if (track_event.size() == 0) {
1987       continue;
1988     }
1989 
1990     ASSERT_THAT(track_event,
1991                 ElementsAre(AllFieldsWithId(
1992                     perfetto_protos_TrackEvent_type_field_number,
1993                     ElementsAre(VarIntField(
1994                         perfetto_protos_TrackEvent_TYPE_SLICE_BEGIN)))));
1995     IdFieldView name_iid_fields(
1996         track_event.front(), perfetto_protos_TrackEvent_name_iid_field_number);
1997     ASSERT_THAT(name_iid_fields, ElementsAre(VarIntField(_)));
1998     uint64_t name_iid = name_iid_fields.front().value.integer64;
1999     EXPECT_THAT(trace_field,
2000                 AllFieldsWithId(
2001                     perfetto_protos_TracePacket_interned_data_field_number,
2002                     ElementsAre(AllFieldsWithId(
2003                         perfetto_protos_InternedData_event_names_field_number,
2004                         ElementsAre(MsgField(UnorderedElementsAre(
2005                             PbField(perfetto_protos_EventName_iid_field_number,
2006                                     VarIntField(name_iid)),
2007                             PbField(perfetto_protos_EventName_name_field_number,
2008                                     StringField(__func__)))))))));
2009     it++;
2010     break;
2011   }
2012   ASSERT_NE(it, trace_view.end());
2013   for (; it != trace_view.end(); it++) {
2014     struct PerfettoPbDecoderField trace_field = *it;
2015     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
2016                                      MsgField(_)));
2017     IdFieldView track_event(
2018         trace_field, perfetto_protos_TracePacket_track_event_field_number);
2019     if (track_event.size() == 0) {
2020       continue;
2021     }
2022     ASSERT_THAT(track_event,
2023                 ElementsAre(AllFieldsWithId(
2024                     perfetto_protos_TrackEvent_type_field_number,
2025                     ElementsAre(VarIntField(
2026                         perfetto_protos_TrackEvent_TYPE_SLICE_END)))));
2027     IdFieldView debug_annot_fields(
2028         track_event.front(),
2029         perfetto_protos_TrackEvent_debug_annotations_field_number);
2030     ASSERT_THAT(debug_annot_fields, ElementsAre());
2031     it++;
2032     break;
2033   }
2034 }
2035 
TEST_F(SharedLibTrackEventTest,TrackEventHlProtoFieldString)2036 TEST_F(SharedLibTrackEventTest, TrackEventHlProtoFieldString) {
2037   TracingSession tracing_session = TracingSession::Builder()
2038                                        .set_data_source_name("track_event")
2039                                        .add_enabled_category("*")
2040                                        .Build();
2041 
2042   PERFETTO_TE(
2043       cat1, PERFETTO_TE_INSTANT("event"),
2044       PERFETTO_TE_PROTO_FIELDS(PERFETTO_TE_PROTO_FIELD_NESTED(
2045           perfetto_protos_TrackEvent_debug_annotations_field_number,
2046           PERFETTO_TE_PROTO_FIELD_CSTR(
2047               perfetto_protos_DebugAnnotation_name_field_number, "name"),
2048           PERFETTO_TE_PROTO_FIELD_VARINT(
2049               perfetto_protos_DebugAnnotation_uint_value_field_number, 42))));
2050 
2051   tracing_session.StopBlocking();
2052   std::vector<uint8_t> data = tracing_session.ReadBlocking();
2053   EXPECT_THAT(
2054       FieldView(data),
2055       Contains(PbField(
2056           perfetto_protos_Trace_packet_field_number,
2057           AllFieldsWithId(
2058               perfetto_protos_TracePacket_track_event_field_number,
2059               ElementsAre(AllFieldsWithId(
2060                   perfetto_protos_TrackEvent_debug_annotations_field_number,
2061                   ElementsAre(MsgField(UnorderedElementsAre(
2062                       PbField(perfetto_protos_DebugAnnotation_name_field_number,
2063                               StringField("name")),
2064                       PbField(
2065                           perfetto_protos_DebugAnnotation_uint_value_field_number,
2066                           VarIntField(42)))))))))));
2067 }
2068 
2069 }  // namespace
2070