• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
886   PERFETTO_DS_TRACE(data_source_2, ctx) {
887     struct PerfettoDsRootTracePacket trace_packet;
888     PerfettoDsTracerPacketBegin(&ctx, &trace_packet);
889 
890     {
891       struct perfetto_protos_TestEvent for_testing;
892       perfetto_protos_TracePacket_begin_for_testing(&trace_packet.msg,
893                                                     &for_testing);
894       {
895         struct perfetto_protos_TestEvent_TestPayload payload;
896         perfetto_protos_TestEvent_begin_payload(&for_testing, &payload);
897         perfetto_protos_TestEvent_TestPayload_set_cstr_str(&payload,
898                                                            "After stop");
899         perfetto_protos_TestEvent_end_payload(&for_testing, &payload);
900       }
901       perfetto_protos_TracePacket_end_for_testing(&trace_packet.msg,
902                                                   &for_testing);
903     }
904     PerfettoDsTracerPacketEnd(&ctx, &trace_packet);
905   }
906 
907   PerfettoDsStopDone(stopper);
908 
909   t.join();
910 
911   PERFETTO_DS_TRACE(data_source_2, ctx) {
912     // After the postponed stop has been acknowledged, this should not be
913     // executed.
914     ADD_FAILURE();
915   }
916 
917   std::vector<uint8_t> data = tracing_session.ReadBlocking();
918   EXPECT_THAT(
919       FieldView(data),
920       Contains(PbField(
921           perfetto_protos_Trace_packet_field_number,
922           MsgField(Contains(PbField(
923               perfetto_protos_TracePacket_for_testing_field_number,
924               MsgField(Contains(PbField(
925                   perfetto_protos_TestEvent_payload_field_number,
926                   MsgField(ElementsAre(PbField(
927                       perfetto_protos_TestEvent_TestPayload_str_field_number,
928                       StringField("After stop")))))))))))));
929 }
930 
TEST_F(SharedLibDataSourceTest,FlushDone)931 TEST_F(SharedLibDataSourceTest, FlushDone) {
932   TracingSession tracing_session =
933       TracingSession::Builder().set_data_source_name(kDataSourceName2).Build();
934 
935   WaitableEvent flush_called;
936   WaitableEvent flush_done;
937   struct PerfettoDsAsyncFlusher* flusher;
938 
939   EXPECT_CALL(ds2_callbacks_, OnFlush(_, _, kDataSource2UserArg, _, _))
940       .WillOnce([&](struct PerfettoDsImpl*, PerfettoDsInstanceIndex, void*,
941                     void*, struct PerfettoDsOnFlushArgs* args) {
942         flusher = PerfettoDsOnFlushArgsPostpone(args);
943         flush_called.Notify();
944       });
945 
946   std::thread t([&]() {
947     tracing_session.FlushBlocking(/*timeout_ms=*/10000);
948     flush_done.Notify();
949   });
950 
951   flush_called.WaitForNotification();
952   EXPECT_FALSE(flush_done.IsNotified());
953   PerfettoDsFlushDone(flusher);
954   flush_done.WaitForNotification();
955 
956   t.join();
957 }
958 
TEST_F(SharedLibDataSourceTest,ThreadLocalState)959 TEST_F(SharedLibDataSourceTest, ThreadLocalState) {
960   bool ignored = false;
961   void* const kTlsPtr = &ignored;
962   TracingSession tracing_session =
963       TracingSession::Builder().set_data_source_name(kDataSourceName2).Build();
964 
965   EXPECT_CALL(ds2_callbacks_, OnCreateTls).WillOnce(Return(kTlsPtr));
966 
967   void* tls_state = nullptr;
968   PERFETTO_DS_TRACE(data_source_2, ctx) {
969     tls_state = PerfettoDsGetCustomTls(&data_source_2, &ctx);
970   }
971   EXPECT_EQ(Ds2ActualCustomState(tls_state), kTlsPtr);
972 
973   tracing_session.StopBlocking();
974 
975   EXPECT_CALL(ds2_callbacks_, OnDeleteTls(kTlsPtr));
976 
977   // The OnDelete callback will be called by
978   // DestroyStoppedTraceWritersForCurrentThread(). One way to trigger that is to
979   // trace with another data source.
980   TracingSession tracing_session_1 =
981       TracingSession::Builder().set_data_source_name(kDataSourceName1).Build();
982   PERFETTO_DS_TRACE(data_source_1, ctx) {}
983 }
984 
TEST_F(SharedLibDataSourceTest,IncrementalState)985 TEST_F(SharedLibDataSourceTest, IncrementalState) {
986   bool ignored = false;
987   void* const kIncrPtr = &ignored;
988   TracingSession tracing_session =
989       TracingSession::Builder().set_data_source_name(kDataSourceName2).Build();
990 
991   EXPECT_CALL(ds2_callbacks_, OnCreateIncr).WillOnce(Return(kIncrPtr));
992 
993   void* tls_state = nullptr;
994   PERFETTO_DS_TRACE(data_source_2, ctx) {
995     tls_state = PerfettoDsGetIncrementalState(&data_source_2, &ctx);
996   }
997   EXPECT_EQ(Ds2ActualCustomState(tls_state), kIncrPtr);
998 
999   tracing_session.StopBlocking();
1000 
1001   EXPECT_CALL(ds2_callbacks_, OnDeleteIncr(kIncrPtr));
1002 
1003   // The OnDelete callback will be called by
1004   // DestroyStoppedTraceWritersForCurrentThread(). One way to trigger that is to
1005   // trace with another data source.
1006   TracingSession tracing_session_1 =
1007       TracingSession::Builder().set_data_source_name(kDataSourceName1).Build();
1008   PERFETTO_DS_TRACE(data_source_1, ctx) {}
1009 }
1010 
TEST_F(SharedLibDataSourceTest,GetInstanceLockedSuccess)1011 TEST_F(SharedLibDataSourceTest, GetInstanceLockedSuccess) {
1012   bool ignored = false;
1013   void* const kInstancePtr = &ignored;
1014   EXPECT_CALL(ds2_callbacks_, OnSetup(_, _, _, _, kDataSource2UserArg, _))
1015       .WillOnce(Return(kInstancePtr));
1016   TracingSession tracing_session =
1017       TracingSession::Builder().set_data_source_name(kDataSourceName2).Build();
1018 
1019   void* arg = nullptr;
1020   PERFETTO_DS_TRACE(data_source_2, ctx) {
1021     arg = PerfettoDsImplGetInstanceLocked(data_source_2.impl, ctx.impl.inst_id);
1022     if (arg) {
1023       PerfettoDsImplReleaseInstanceLocked(data_source_2.impl, ctx.impl.inst_id);
1024     }
1025   }
1026 
1027   EXPECT_EQ(arg, kInstancePtr);
1028 }
1029 
TEST_F(SharedLibDataSourceTest,GetInstanceLockedFailure)1030 TEST_F(SharedLibDataSourceTest, GetInstanceLockedFailure) {
1031   bool ignored = false;
1032   void* const kInstancePtr = &ignored;
1033   EXPECT_CALL(ds2_callbacks_, OnSetup(_, _, _, _, kDataSource2UserArg, _))
1034       .WillOnce(Return(kInstancePtr));
1035   TracingSession tracing_session =
1036       TracingSession::Builder().set_data_source_name(kDataSourceName2).Build();
1037 
1038   WaitableEvent inside_tracing;
1039   WaitableEvent stopped;
1040 
1041   std::thread t([&] {
1042     PERFETTO_DS_TRACE(data_source_2, ctx) {
1043       inside_tracing.Notify();
1044       stopped.WaitForNotification();
1045       void* arg =
1046           PerfettoDsImplGetInstanceLocked(data_source_2.impl, ctx.impl.inst_id);
1047       if (arg) {
1048         PerfettoDsImplReleaseInstanceLocked(data_source_2.impl,
1049                                             ctx.impl.inst_id);
1050       }
1051       EXPECT_THAT(arg, IsNull());
1052     }
1053   });
1054 
1055   inside_tracing.WaitForNotification();
1056   tracing_session.StopBlocking();
1057   stopped.Notify();
1058   t.join();
1059 }
1060 
1061 // Regression test for a `PerfettoDsImplReleaseInstanceLocked()`. Under very
1062 // specific circumstances, that depends on the implementation details of
1063 // `TracingMuxerImpl`, the following events can happen:
1064 // * `PerfettoDsImplGetInstanceLocked()` is called after
1065 //   `TracingMuxerImpl::StopDataSource_AsyncBeginImpl`, but before
1066 //   `TracingMuxerImpl::StopDataSource_AsyncEnd`.
1067 //   `PerfettoDsImplGetInstanceLocked()` succeeds and returns a valid instance.
1068 // * `TracingMuxerImpl::StopDataSource_AsyncEnd()` is called.
1069 //   `DataSourceStaticState::valid_instances` is reset.
1070 // * `PerfettoDsImplReleaseInstanceLocked()` is called.
1071 //
1072 // In this case `PerfettoDsImplReleaseInstanceLocked()` should work even though
1073 // the instance is not there in the valid_instances bitmap anymore.
1074 //
1075 // In order to reproduce the specific failure, the test makes assumptions about
1076 // the internal implementation (that valid_instance is changed outside of the
1077 // lock). If that were to change and the test would fail, the test should be
1078 // changed/deleted.
TEST_F(SharedLibDataSourceTest,GetInstanceLockedStopBeforeRelease)1079 TEST_F(SharedLibDataSourceTest, GetInstanceLockedStopBeforeRelease) {
1080   bool ignored = false;
1081   void* const kInstancePtr = &ignored;
1082   EXPECT_CALL(ds2_callbacks_, OnSetup(_, _, _, _, kDataSource2UserArg, _))
1083       .WillOnce(Return(kInstancePtr));
1084   TracingSession tracing_session =
1085       TracingSession::Builder().set_data_source_name(kDataSourceName2).Build();
1086 
1087   WaitableEvent inside_tracing;
1088   WaitableEvent stopping;
1089   WaitableEvent locked;
1090   WaitableEvent fully_stopped;
1091 
1092   std::thread t([&] {
1093     PERFETTO_DS_TRACE(data_source_2, ctx) {
1094       inside_tracing.Notify();
1095       stopping.WaitForNotification();
1096       void* arg =
1097           PerfettoDsImplGetInstanceLocked(data_source_2.impl, ctx.impl.inst_id);
1098       EXPECT_EQ(arg, kInstancePtr);
1099       locked.Notify();
1100       fully_stopped.WaitForNotification();
1101       if (arg) {
1102         PerfettoDsImplReleaseInstanceLocked(data_source_2.impl,
1103                                             ctx.impl.inst_id);
1104       }
1105     }
1106   });
1107 
1108   inside_tracing.WaitForNotification();
1109 
1110   struct PerfettoDsAsyncStopper* stopper = nullptr;
1111 
1112   EXPECT_CALL(ds2_callbacks_, OnStop(_, _, kDataSource2UserArg, _, _))
1113       .WillOnce([&](struct PerfettoDsImpl*, PerfettoDsInstanceIndex, void*,
1114                     void*, struct PerfettoDsOnStopArgs* args) {
1115         stopper = PerfettoDsOnStopArgsPostpone(args);
1116         stopping.Notify();
1117       });
1118 
1119   tracing_session.StopAsync();
1120 
1121   locked.WaitForNotification();
1122   PerfettoDsStopDone(stopper);
1123   // Wait for PerfettoDsImplTraceIterateBegin to return a nullptr tracer. This
1124   // means that the valid_instances bitmap has been reset.
1125   for (;;) {
1126     PerfettoDsImplTracerIterator iterator =
1127         PerfettoDsImplTraceIterateBegin(data_source_2.impl);
1128     if (iterator.tracer == nullptr) {
1129       break;
1130     }
1131     PerfettoDsImplTraceIterateBreak(data_source_2.impl, &iterator);
1132     std::this_thread::yield();
1133   }
1134   fully_stopped.Notify();
1135   tracing_session.WaitForStopped();
1136   t.join();
1137 }
1138 
1139 class SharedLibProducerTest : public testing::Test {
1140  protected:
SetUp()1141   void SetUp() override {
1142     struct PerfettoProducerInitArgs args = PERFETTO_PRODUCER_INIT_ARGS_INIT();
1143     args.backends = PERFETTO_BACKEND_IN_PROCESS;
1144     PerfettoProducerInit(args);
1145   }
1146 
TearDown()1147   void TearDown() override { perfetto::shlib::ResetForTesting(); }
1148 };
1149 
TEST_F(SharedLibProducerTest,ActivateTriggers)1150 TEST_F(SharedLibProducerTest, ActivateTriggers) {
1151   struct PerfettoPbMsgWriter writer;
1152   struct PerfettoHeapBuffer* hb = PerfettoHeapBufferCreate(&writer.writer);
1153 
1154   struct perfetto_protos_TraceConfig cfg;
1155   PerfettoPbMsgInit(&cfg.msg, &writer);
1156   {
1157     struct perfetto_protos_TraceConfig_BufferConfig buffers;
1158     perfetto_protos_TraceConfig_begin_buffers(&cfg, &buffers);
1159     perfetto_protos_TraceConfig_BufferConfig_set_size_kb(&buffers, 1024);
1160     perfetto_protos_TraceConfig_end_buffers(&cfg, &buffers);
1161   }
1162   {
1163     struct perfetto_protos_TraceConfig_TriggerConfig trigger_config;
1164     perfetto_protos_TraceConfig_begin_trigger_config(&cfg, &trigger_config);
1165     perfetto_protos_TraceConfig_TriggerConfig_set_trigger_mode(
1166         &trigger_config,
1167         perfetto_protos_TraceConfig_TriggerConfig_STOP_TRACING);
1168     perfetto_protos_TraceConfig_TriggerConfig_set_trigger_timeout_ms(
1169         &trigger_config, 5000);
1170     {
1171       struct perfetto_protos_TraceConfig_TriggerConfig_Trigger trigger;
1172       perfetto_protos_TraceConfig_TriggerConfig_begin_triggers(&trigger_config,
1173                                                                &trigger);
1174       perfetto_protos_TraceConfig_TriggerConfig_Trigger_set_cstr_name(
1175           &trigger, "trigger1");
1176       perfetto_protos_TraceConfig_TriggerConfig_end_triggers(&trigger_config,
1177                                                              &trigger);
1178     }
1179     perfetto_protos_TraceConfig_end_trigger_config(&cfg, &trigger_config);
1180   }
1181   size_t cfg_size = PerfettoStreamWriterGetWrittenSize(&writer.writer);
1182   std::unique_ptr<uint8_t[]> ser(new uint8_t[cfg_size]);
1183   PerfettoHeapBufferCopyInto(hb, &writer.writer, ser.get(), cfg_size);
1184   PerfettoHeapBufferDestroy(hb, &writer.writer);
1185 
1186   struct PerfettoTracingSessionImpl* ts =
1187       PerfettoTracingSessionCreate(PERFETTO_BACKEND_IN_PROCESS);
1188 
1189   PerfettoTracingSessionSetup(ts, ser.get(), cfg_size);
1190 
1191   PerfettoTracingSessionStartBlocking(ts);
1192   TracingSession tracing_session = TracingSession::Adopt(ts);
1193 
1194   const char* triggers[3];
1195   triggers[0] = "trigger0";
1196   triggers[1] = "trigger1";
1197   triggers[2] = nullptr;
1198   PerfettoProducerActivateTriggers(triggers, 10000);
1199 
1200   tracing_session.WaitForStopped();
1201   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1202   EXPECT_THAT(FieldView(data),
1203               Contains(PbField(
1204                   perfetto_protos_Trace_packet_field_number,
1205                   MsgField(Contains(PbField(
1206                       perfetto_protos_TracePacket_trigger_field_number,
1207                       MsgField(Contains(PbField(
1208                           perfetto_protos_Trigger_trigger_name_field_number,
1209                           StringField("trigger1"))))))))));
1210 }
1211 
1212 class SharedLibTrackEventTest : public testing::Test {
1213  protected:
SetUp()1214   void SetUp() override {
1215     struct PerfettoProducerInitArgs args = PERFETTO_PRODUCER_INIT_ARGS_INIT();
1216     args.backends = PERFETTO_BACKEND_IN_PROCESS;
1217     PerfettoProducerInit(args);
1218     PerfettoTeInit();
1219     PERFETTO_TE_REGISTER_CATEGORIES(TEST_CATEGORIES);
1220   }
1221 
TearDown()1222   void TearDown() override {
1223     PERFETTO_TE_UNREGISTER_CATEGORIES(TEST_CATEGORIES);
1224     perfetto::shlib::ResetForTesting();
1225   }
1226 };
1227 
TEST_F(SharedLibTrackEventTest,TrackEventFastpathOtherDsCatDisabled)1228 TEST_F(SharedLibTrackEventTest, TrackEventFastpathOtherDsCatDisabled) {
1229   TracingSession tracing_session =
1230       TracingSession::Builder()
1231           .set_data_source_name("other_nonexisting_datasource")
1232           .Build();
1233   EXPECT_FALSE(std::atomic_load(cat1.enabled));
1234   EXPECT_FALSE(std::atomic_load(cat2.enabled));
1235   EXPECT_FALSE(std::atomic_load(cat3.enabled));
1236 }
1237 
TEST_F(SharedLibTrackEventTest,TrackEventFastpathEmptyConfigDisablesAllCats)1238 TEST_F(SharedLibTrackEventTest, TrackEventFastpathEmptyConfigDisablesAllCats) {
1239   ASSERT_FALSE(std::atomic_load(cat1.enabled));
1240   ASSERT_FALSE(std::atomic_load(cat2.enabled));
1241   ASSERT_FALSE(std::atomic_load(cat3.enabled));
1242 
1243   TracingSession tracing_session =
1244       TracingSession::Builder().set_data_source_name("track_event").Build();
1245 
1246   EXPECT_FALSE(std::atomic_load(cat1.enabled));
1247   EXPECT_FALSE(std::atomic_load(cat2.enabled));
1248   EXPECT_FALSE(std::atomic_load(cat3.enabled));
1249 }
1250 
TEST_F(SharedLibTrackEventTest,TrackEventFastpathOneCatEnabled)1251 TEST_F(SharedLibTrackEventTest, TrackEventFastpathOneCatEnabled) {
1252   ASSERT_FALSE(std::atomic_load(cat1.enabled));
1253   ASSERT_FALSE(std::atomic_load(cat2.enabled));
1254   ASSERT_FALSE(std::atomic_load(cat3.enabled));
1255 
1256   TracingSession tracing_session = TracingSession::Builder()
1257                                        .set_data_source_name("track_event")
1258                                        .add_enabled_category("cat1")
1259                                        .add_disabled_category("*")
1260                                        .Build();
1261 
1262   EXPECT_TRUE(std::atomic_load(cat1.enabled));
1263   EXPECT_FALSE(std::atomic_load(cat2.enabled));
1264   EXPECT_FALSE(std::atomic_load(cat3.enabled));
1265 }
1266 
TEST_F(SharedLibTrackEventTest,TrackEventHlCategory)1267 TEST_F(SharedLibTrackEventTest, TrackEventHlCategory) {
1268   TracingSession tracing_session = TracingSession::Builder()
1269                                        .set_data_source_name("track_event")
1270                                        .add_enabled_category("*")
1271                                        .Build();
1272 
1273   EXPECT_TRUE(std::atomic_load(cat1.enabled));
1274   PERFETTO_TE(cat1, PERFETTO_TE_INSTANT(""));
1275 
1276   tracing_session.StopBlocking();
1277   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1278   bool found = false;
1279   for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
1280     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1281                                      MsgField(_)));
1282     IdFieldView track_event(
1283         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1284     if (track_event.size() == 0) {
1285       continue;
1286     }
1287     found = true;
1288     IdFieldView cat_iid_fields(
1289         track_event.front(),
1290         perfetto_protos_TrackEvent_category_iids_field_number);
1291     ASSERT_THAT(cat_iid_fields, ElementsAre(VarIntField(_)));
1292     uint64_t cat_iid = cat_iid_fields.front().value.integer64;
1293     EXPECT_THAT(
1294         trace_field,
1295         AllFieldsWithId(
1296             perfetto_protos_TracePacket_interned_data_field_number,
1297             ElementsAre(AllFieldsWithId(
1298                 perfetto_protos_InternedData_event_categories_field_number,
1299                 ElementsAre(MsgField(UnorderedElementsAre(
1300                     PbField(perfetto_protos_EventCategory_iid_field_number,
1301                             VarIntField(cat_iid)),
1302                     PbField(perfetto_protos_EventCategory_name_field_number,
1303                             StringField("cat1")))))))));
1304   }
1305   EXPECT_TRUE(found);
1306 }
1307 
TEST_F(SharedLibTrackEventTest,TrackEventHlDynamicCategory)1308 TEST_F(SharedLibTrackEventTest, TrackEventHlDynamicCategory) {
1309   TracingSession tracing_session = TracingSession::Builder()
1310                                        .set_data_source_name("track_event")
1311                                        .add_enabled_category("dyn1")
1312                                        .add_enabled_category("cat1")
1313                                        .add_disabled_category("*")
1314                                        .Build();
1315 
1316   PERFETTO_TE(PERFETTO_TE_DYNAMIC_CATEGORY, PERFETTO_TE_INSTANT(""),
1317               PERFETTO_TE_DYNAMIC_CATEGORY_STRING("dyn2"));
1318   PERFETTO_TE(PERFETTO_TE_DYNAMIC_CATEGORY, PERFETTO_TE_INSTANT(""),
1319               PERFETTO_TE_DYNAMIC_CATEGORY_STRING("dyn1"));
1320 
1321   tracing_session.StopBlocking();
1322   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1323   bool found = false;
1324   for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
1325     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1326                                      MsgField(_)));
1327     IdFieldView track_event(
1328         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1329     if (track_event.size() == 0) {
1330       continue;
1331     }
1332     found = true;
1333     EXPECT_THAT(track_event,
1334                 ElementsAre(AllFieldsWithId(
1335                     perfetto_protos_TrackEvent_categories_field_number,
1336                     ElementsAre(StringField("dyn1")))));
1337   }
1338   EXPECT_TRUE(found);
1339 }
1340 
TEST_F(SharedLibTrackEventTest,TrackEventHlDynamicCategoryMultipleSessions)1341 TEST_F(SharedLibTrackEventTest, TrackEventHlDynamicCategoryMultipleSessions) {
1342   TracingSession tracing_session1 = TracingSession::Builder()
1343                                         .set_data_source_name("track_event")
1344                                         .add_enabled_category("cat1")
1345                                         .add_enabled_category("dyn1")
1346                                         .add_disabled_category("dyn2")
1347                                         .add_disabled_category("*")
1348                                         .Build();
1349 
1350   TracingSession tracing_session2 = TracingSession::Builder()
1351                                         .set_data_source_name("track_event")
1352                                         .add_enabled_category("cat1")
1353                                         .add_enabled_category("dyn2")
1354                                         .add_disabled_category("dyn1")
1355                                         .add_disabled_category("*")
1356                                         .Build();
1357 
1358   PERFETTO_TE(PERFETTO_TE_DYNAMIC_CATEGORY,
1359               PERFETTO_TE_INSTANT("interned_string"),
1360               PERFETTO_TE_DYNAMIC_CATEGORY_STRING("dyn1"));
1361   PERFETTO_TE(PERFETTO_TE_DYNAMIC_CATEGORY,
1362               PERFETTO_TE_INSTANT("interned_string"),
1363               PERFETTO_TE_DYNAMIC_CATEGORY_STRING("dyn2"));
1364   PERFETTO_TE(cat1, PERFETTO_TE_INSTANT(""));
1365 
1366   tracing_session1.StopBlocking();
1367   std::vector<uint8_t> data1 = tracing_session1.ReadBlocking();
1368   EXPECT_THAT(
1369       FieldView(data1),
1370       Contains(PbField(
1371           perfetto_protos_Trace_packet_field_number,
1372           MsgField(AllOf(
1373               Contains(PbField(
1374                   perfetto_protos_TracePacket_track_event_field_number,
1375                   MsgField(Contains(PbField(
1376                       perfetto_protos_TrackEvent_categories_field_number,
1377                       StringField("dyn1")))))),
1378               Contains(PbField(
1379                   perfetto_protos_TracePacket_interned_data_field_number,
1380                   MsgField(Contains(PbField(
1381                       perfetto_protos_InternedData_event_names_field_number,
1382                       MsgField(Contains(
1383                           PbField(perfetto_protos_EventName_name_field_number,
1384                                   StringField("interned_string"))))))))))))));
1385   tracing_session2.StopBlocking();
1386   std::vector<uint8_t> data2 = tracing_session2.ReadBlocking();
1387   EXPECT_THAT(
1388       FieldView(data2),
1389       Contains(PbField(
1390           perfetto_protos_Trace_packet_field_number,
1391           MsgField(AllOf(
1392               Contains(PbField(
1393                   perfetto_protos_TracePacket_track_event_field_number,
1394                   MsgField(Contains(PbField(
1395                       perfetto_protos_TrackEvent_categories_field_number,
1396                       StringField("dyn2")))))),
1397               Contains(PbField(
1398                   perfetto_protos_TracePacket_interned_data_field_number,
1399                   MsgField(Contains(PbField(
1400                       perfetto_protos_InternedData_event_names_field_number,
1401                       MsgField(Contains(
1402                           PbField(perfetto_protos_EventName_name_field_number,
1403                                   StringField("interned_string"))))))))))))));
1404 }
1405 
TEST_F(SharedLibTrackEventTest,TrackEventHlInstant)1406 TEST_F(SharedLibTrackEventTest, TrackEventHlInstant) {
1407   TracingSession tracing_session = TracingSession::Builder()
1408                                        .set_data_source_name("track_event")
1409                                        .add_enabled_category("*")
1410                                        .Build();
1411 
1412   PERFETTO_TE(cat1, PERFETTO_TE_INSTANT("event"));
1413 
1414   tracing_session.StopBlocking();
1415   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1416   bool found = false;
1417   for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
1418     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1419                                      MsgField(_)));
1420     IdFieldView track_event(
1421         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1422     if (track_event.size() == 0) {
1423       continue;
1424     }
1425     found = true;
1426     ASSERT_THAT(track_event,
1427                 ElementsAre(AllFieldsWithId(
1428                     perfetto_protos_TrackEvent_type_field_number,
1429                     ElementsAre(VarIntField(
1430                         perfetto_protos_TrackEvent_TYPE_INSTANT)))));
1431     IdFieldView name_iid_fields(
1432         track_event.front(), perfetto_protos_TrackEvent_name_iid_field_number);
1433     ASSERT_THAT(name_iid_fields, ElementsAre(VarIntField(_)));
1434     uint64_t name_iid = name_iid_fields.front().value.integer64;
1435     EXPECT_THAT(trace_field,
1436                 AllFieldsWithId(
1437                     perfetto_protos_TracePacket_interned_data_field_number,
1438                     ElementsAre(AllFieldsWithId(
1439                         perfetto_protos_InternedData_event_names_field_number,
1440                         ElementsAre(MsgField(UnorderedElementsAre(
1441                             PbField(perfetto_protos_EventName_iid_field_number,
1442                                     VarIntField(name_iid)),
1443                             PbField(perfetto_protos_EventName_name_field_number,
1444                                     StringField("event")))))))));
1445   }
1446   EXPECT_TRUE(found);
1447 }
1448 
TEST_F(SharedLibTrackEventTest,TrackEventLlInstant)1449 TEST_F(SharedLibTrackEventTest, TrackEventLlInstant) {
1450   TracingSession tracing_session = TracingSession::Builder()
1451                                        .set_data_source_name("track_event")
1452                                        .add_enabled_category("*")
1453                                        .Build();
1454 
1455   if (PERFETTO_UNLIKELY(PERFETTO_ATOMIC_LOAD_EXPLICIT(
1456           cat1.enabled, PERFETTO_MEMORY_ORDER_RELAXED))) {
1457     struct PerfettoTeTimestamp timestamp = PerfettoTeGetTimestamp();
1458     int32_t type = PERFETTO_TE_TYPE_INSTANT;
1459     const char* name = "event";
1460     for (struct PerfettoTeLlIterator ctx =
1461              PerfettoTeLlBeginSlowPath(&cat1, timestamp);
1462          ctx.impl.ds.tracer != nullptr;
1463          PerfettoTeLlNext(&cat1, timestamp, &ctx)) {
1464       uint64_t name_iid;
1465       {
1466         struct PerfettoDsRootTracePacket trace_packet;
1467         PerfettoTeLlPacketBegin(&ctx, &trace_packet);
1468         PerfettoTeLlWriteTimestamp(&trace_packet.msg, &timestamp);
1469         perfetto_protos_TracePacket_set_sequence_flags(
1470             &trace_packet.msg,
1471             perfetto_protos_TracePacket_SEQ_NEEDS_INCREMENTAL_STATE);
1472         {
1473           struct PerfettoTeLlInternContext intern_ctx;
1474           PerfettoTeLlInternContextInit(&intern_ctx, ctx.impl.incr,
1475                                         &trace_packet.msg);
1476           PerfettoTeLlInternRegisteredCat(&intern_ctx, &cat1);
1477           name_iid = PerfettoTeLlInternEventName(&intern_ctx, name);
1478           PerfettoTeLlInternContextDestroy(&intern_ctx);
1479         }
1480         {
1481           struct perfetto_protos_TrackEvent te_msg;
1482           perfetto_protos_TracePacket_begin_track_event(&trace_packet.msg,
1483                                                         &te_msg);
1484           perfetto_protos_TrackEvent_set_type(
1485               &te_msg, static_cast<enum perfetto_protos_TrackEvent_Type>(type));
1486           PerfettoTeLlWriteRegisteredCat(&te_msg, &cat1);
1487           PerfettoTeLlWriteInternedEventName(&te_msg, name_iid);
1488           perfetto_protos_TracePacket_end_track_event(&trace_packet.msg,
1489                                                       &te_msg);
1490         }
1491         PerfettoTeLlPacketEnd(&ctx, &trace_packet);
1492       }
1493     }
1494   }
1495 
1496   tracing_session.StopBlocking();
1497   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1498   bool found = false;
1499   for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
1500     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1501                                      MsgField(_)));
1502     IdFieldView track_event(
1503         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1504     if (track_event.size() == 0) {
1505       continue;
1506     }
1507     found = true;
1508     ASSERT_THAT(track_event,
1509                 ElementsAre(AllFieldsWithId(
1510                     perfetto_protos_TrackEvent_type_field_number,
1511                     ElementsAre(VarIntField(
1512                         perfetto_protos_TrackEvent_TYPE_INSTANT)))));
1513     IdFieldView name_iid_fields(
1514         track_event.front(), perfetto_protos_TrackEvent_name_iid_field_number);
1515     ASSERT_THAT(name_iid_fields, ElementsAre(VarIntField(_)));
1516     uint64_t name_iid = name_iid_fields.front().value.integer64;
1517     EXPECT_THAT(trace_field,
1518                 AllFieldsWithId(
1519                     perfetto_protos_TracePacket_interned_data_field_number,
1520                     ElementsAre(AllFieldsWithId(
1521                         perfetto_protos_InternedData_event_names_field_number,
1522                         ElementsAre(MsgField(UnorderedElementsAre(
1523                             PbField(perfetto_protos_EventName_iid_field_number,
1524                                     VarIntField(name_iid)),
1525                             PbField(perfetto_protos_EventName_name_field_number,
1526                                     StringField("event")))))))));
1527   }
1528   EXPECT_TRUE(found);
1529 }
1530 
TEST_F(SharedLibTrackEventTest,TrackEventHlInstantNoIntern)1531 TEST_F(SharedLibTrackEventTest, TrackEventHlInstantNoIntern) {
1532   TracingSession tracing_session = TracingSession::Builder()
1533                                        .set_data_source_name("track_event")
1534                                        .add_enabled_category("*")
1535                                        .Build();
1536 
1537   PERFETTO_TE(cat1, PERFETTO_TE_INSTANT("event"), PERFETTO_TE_NO_INTERN());
1538 
1539   tracing_session.StopBlocking();
1540   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1541   bool found = false;
1542   for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
1543     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1544                                      MsgField(_)));
1545     IdFieldView track_event(
1546         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1547     if (track_event.size() == 0) {
1548       continue;
1549     }
1550     found = true;
1551     ASSERT_THAT(
1552         track_event,
1553         ElementsAre(AllOf(
1554             AllFieldsWithId(perfetto_protos_TrackEvent_type_field_number,
1555                             ElementsAre(VarIntField(
1556                                 perfetto_protos_TrackEvent_TYPE_INSTANT))),
1557             AllFieldsWithId(perfetto_protos_TrackEvent_name_field_number,
1558                             ElementsAre(StringField("event"))))));
1559   }
1560   EXPECT_TRUE(found);
1561 }
1562 
TEST_F(SharedLibTrackEventTest,TrackEventHlDbgArg)1563 TEST_F(SharedLibTrackEventTest, TrackEventHlDbgArg) {
1564   TracingSession tracing_session = TracingSession::Builder()
1565                                        .set_data_source_name("track_event")
1566                                        .add_enabled_category("*")
1567                                        .Build();
1568 
1569   PERFETTO_TE(cat1, PERFETTO_TE_INSTANT("event"),
1570               PERFETTO_TE_ARG_UINT64("arg_name", 42));
1571 
1572   tracing_session.StopBlocking();
1573   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1574   bool found = false;
1575   for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
1576     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1577                                      MsgField(_)));
1578     IdFieldView track_event(
1579         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1580     if (track_event.size() == 0) {
1581       continue;
1582     }
1583     found = true;
1584     ASSERT_THAT(track_event,
1585                 ElementsAre(AllFieldsWithId(
1586                     perfetto_protos_TrackEvent_type_field_number,
1587                     ElementsAre(VarIntField(
1588                         perfetto_protos_TrackEvent_TYPE_INSTANT)))));
1589     IdFieldView name_iid_fields(
1590         track_event.front(), perfetto_protos_TrackEvent_name_iid_field_number);
1591     ASSERT_THAT(name_iid_fields, ElementsAre(VarIntField(_)));
1592     uint64_t name_iid = name_iid_fields.front().value.integer64;
1593     IdFieldView debug_annot_fields(
1594         track_event.front(),
1595         perfetto_protos_TrackEvent_debug_annotations_field_number);
1596     ASSERT_THAT(
1597         debug_annot_fields,
1598         ElementsAre(MsgField(UnorderedElementsAre(
1599             PbField(perfetto_protos_DebugAnnotation_name_iid_field_number,
1600                     VarIntField(_)),
1601             PbField(perfetto_protos_DebugAnnotation_uint_value_field_number,
1602                     VarIntField(42))))));
1603     uint64_t arg_name_iid =
1604         IdFieldView(debug_annot_fields.front(),
1605                     perfetto_protos_DebugAnnotation_name_iid_field_number)
1606             .front()
1607             .value.integer64;
1608     EXPECT_THAT(
1609         trace_field,
1610         AllFieldsWithId(
1611             perfetto_protos_TracePacket_interned_data_field_number,
1612             ElementsAre(AllOf(
1613                 AllFieldsWithId(
1614                     perfetto_protos_InternedData_event_names_field_number,
1615                     ElementsAre(MsgField(UnorderedElementsAre(
1616                         PbField(perfetto_protos_EventName_iid_field_number,
1617                                 VarIntField(name_iid)),
1618                         PbField(perfetto_protos_EventName_name_field_number,
1619                                 StringField("event")))))),
1620                 AllFieldsWithId(
1621                     perfetto_protos_InternedData_debug_annotation_names_field_number,
1622                     ElementsAre(MsgField(UnorderedElementsAre(
1623                         PbField(
1624                             perfetto_protos_DebugAnnotationName_iid_field_number,
1625                             VarIntField(arg_name_iid)),
1626                         PbField(
1627                             perfetto_protos_DebugAnnotationName_name_field_number,
1628                             StringField("arg_name"))))))))));
1629   }
1630   EXPECT_TRUE(found);
1631 }
1632 
TEST_F(SharedLibTrackEventTest,TrackEventHlNamedTrack)1633 TEST_F(SharedLibTrackEventTest, TrackEventHlNamedTrack) {
1634   TracingSession tracing_session = TracingSession::Builder()
1635                                        .set_data_source_name("track_event")
1636                                        .add_enabled_category("*")
1637                                        .Build();
1638 
1639   PERFETTO_TE(cat1, PERFETTO_TE_INSTANT("event"),
1640               PERFETTO_TE_NAMED_TRACK("MyTrack", 1, 2));
1641 
1642   uint64_t kExpectedUuid = PerfettoTeNamedTrackUuid("MyTrack", 1, 2);
1643 
1644   tracing_session.StopBlocking();
1645   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1646   EXPECT_THAT(
1647       FieldView(data),
1648       AllOf(
1649           Contains(PbField(
1650               perfetto_protos_Trace_packet_field_number,
1651               AllFieldsWithId(
1652                   perfetto_protos_TracePacket_track_descriptor_field_number,
1653                   ElementsAre(MsgField(UnorderedElementsAre(
1654                       PbField(perfetto_protos_TrackDescriptor_uuid_field_number,
1655                               VarIntField(kExpectedUuid)),
1656                       PbField(perfetto_protos_TrackDescriptor_name_field_number,
1657                               StringField("MyTrack")),
1658                       PbField(
1659                           perfetto_protos_TrackDescriptor_parent_uuid_field_number,
1660                           VarIntField(2)))))))),
1661           Contains(PbField(
1662               perfetto_protos_Trace_packet_field_number,
1663               AllFieldsWithId(
1664                   perfetto_protos_TracePacket_track_event_field_number,
1665                   ElementsAre(AllOf(
1666                       AllFieldsWithId(
1667                           perfetto_protos_TrackEvent_type_field_number,
1668                           ElementsAre(VarIntField(
1669                               perfetto_protos_TrackEvent_TYPE_INSTANT))),
1670                       AllFieldsWithId(
1671                           perfetto_protos_TrackEvent_track_uuid_field_number,
1672                           ElementsAre(VarIntField(kExpectedUuid))))))))));
1673 }
1674 
TEST_F(SharedLibTrackEventTest,TrackEventHlRegisteredCounter)1675 TEST_F(SharedLibTrackEventTest, TrackEventHlRegisteredCounter) {
1676   TracingSession tracing_session = TracingSession::Builder()
1677                                        .set_data_source_name("track_event")
1678                                        .add_enabled_category("*")
1679                                        .Build();
1680 
1681   PerfettoTeRegisteredTrack my_counter_track;
1682   PerfettoTeCounterTrackRegister(&my_counter_track, "MyCounter",
1683                                  PerfettoTeProcessTrackUuid());
1684 
1685   PERFETTO_TE(cat1, PERFETTO_TE_COUNTER(),
1686               PERFETTO_TE_REGISTERED_TRACK(&my_counter_track),
1687               PERFETTO_TE_INT_COUNTER(42));
1688 
1689   PerfettoTeRegisteredTrackUnregister(&my_counter_track);
1690 
1691   uint64_t kExpectedUuid =
1692       PerfettoTeCounterTrackUuid("MyCounter", PerfettoTeProcessTrackUuid());
1693 
1694   tracing_session.StopBlocking();
1695   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1696   EXPECT_THAT(
1697       FieldView(data),
1698       AllOf(
1699           Contains(PbField(
1700               perfetto_protos_Trace_packet_field_number,
1701               AllFieldsWithId(
1702                   perfetto_protos_TracePacket_track_descriptor_field_number,
1703                   ElementsAre(MsgField(UnorderedElementsAre(
1704                       PbField(perfetto_protos_TrackDescriptor_uuid_field_number,
1705                               VarIntField(kExpectedUuid)),
1706                       PbField(perfetto_protos_TrackDescriptor_name_field_number,
1707                               StringField("MyCounter")),
1708                       PbField(
1709                           perfetto_protos_TrackDescriptor_parent_uuid_field_number,
1710                           VarIntField(PerfettoTeProcessTrackUuid())),
1711                       PbField(
1712                           perfetto_protos_TrackDescriptor_counter_field_number,
1713                           MsgField(_)))))))),
1714           Contains(PbField(
1715               perfetto_protos_Trace_packet_field_number,
1716               AllFieldsWithId(
1717                   perfetto_protos_TracePacket_track_event_field_number,
1718                   ElementsAre(AllOf(
1719                       AllFieldsWithId(
1720                           perfetto_protos_TrackEvent_type_field_number,
1721                           ElementsAre(VarIntField(
1722                               perfetto_protos_TrackEvent_TYPE_COUNTER))),
1723                       AllFieldsWithId(
1724                           perfetto_protos_TrackEvent_counter_value_field_number,
1725                           ElementsAre(VarIntField(42))),
1726                       AllFieldsWithId(
1727                           perfetto_protos_TrackEvent_track_uuid_field_number,
1728                           ElementsAre(VarIntField(kExpectedUuid))))))))));
1729 }
1730 
TEST_F(SharedLibTrackEventTest,Scoped)1731 TEST_F(SharedLibTrackEventTest, Scoped) {
1732   TracingSession tracing_session = TracingSession::Builder()
1733                                        .set_data_source_name("track_event")
1734                                        .add_enabled_category("*")
1735                                        .Build();
1736 
1737   {
1738     PERFETTO_TE_SCOPED(cat1, PERFETTO_TE_SLICE("slice"),
1739                        PERFETTO_TE_ARG_UINT64("arg_name", 42));
1740     PERFETTO_TE(cat1, PERFETTO_TE_INSTANT("event"));
1741   }
1742 
1743   tracing_session.StopBlocking();
1744   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1745   auto trace_view = FieldView(data);
1746   auto it = trace_view.begin();
1747   for (; it != trace_view.end(); it++) {
1748     struct PerfettoPbDecoderField trace_field = *it;
1749     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1750                                      MsgField(_)));
1751     IdFieldView track_event(
1752         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1753     if (track_event.size() == 0) {
1754       continue;
1755     }
1756 
1757     ASSERT_THAT(track_event,
1758                 ElementsAre(AllFieldsWithId(
1759                     perfetto_protos_TrackEvent_type_field_number,
1760                     ElementsAre(VarIntField(
1761                         perfetto_protos_TrackEvent_TYPE_SLICE_BEGIN)))));
1762     IdFieldView name_iid_fields(
1763         track_event.front(), perfetto_protos_TrackEvent_name_iid_field_number);
1764     ASSERT_THAT(name_iid_fields, ElementsAre(VarIntField(_)));
1765     uint64_t name_iid = name_iid_fields.front().value.integer64;
1766     IdFieldView debug_annot_fields(
1767         track_event.front(),
1768         perfetto_protos_TrackEvent_debug_annotations_field_number);
1769     ASSERT_THAT(
1770         debug_annot_fields,
1771         ElementsAre(MsgField(UnorderedElementsAre(
1772             PbField(perfetto_protos_DebugAnnotation_name_iid_field_number,
1773                     VarIntField(_)),
1774             PbField(perfetto_protos_DebugAnnotation_uint_value_field_number,
1775                     VarIntField(42))))));
1776     uint64_t arg_name_iid =
1777         IdFieldView(debug_annot_fields.front(),
1778                     perfetto_protos_DebugAnnotation_name_iid_field_number)
1779             .front()
1780             .value.integer64;
1781     EXPECT_THAT(
1782         trace_field,
1783         AllFieldsWithId(
1784             perfetto_protos_TracePacket_interned_data_field_number,
1785             ElementsAre(AllOf(
1786                 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("slice")))))),
1793                 AllFieldsWithId(
1794                     perfetto_protos_InternedData_debug_annotation_names_field_number,
1795                     ElementsAre(MsgField(UnorderedElementsAre(
1796                         PbField(
1797                             perfetto_protos_DebugAnnotationName_iid_field_number,
1798                             VarIntField(arg_name_iid)),
1799                         PbField(
1800                             perfetto_protos_DebugAnnotationName_name_field_number,
1801                             StringField("arg_name"))))))))));
1802     it++;
1803     break;
1804   }
1805   ASSERT_NE(it, trace_view.end());
1806   for (; it != trace_view.end(); it++) {
1807     struct PerfettoPbDecoderField trace_field = *it;
1808     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1809                                      MsgField(_)));
1810     IdFieldView track_event(
1811         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1812     if (track_event.size() == 0) {
1813       continue;
1814     }
1815     ASSERT_THAT(track_event,
1816                 ElementsAre(AllFieldsWithId(
1817                     perfetto_protos_TrackEvent_type_field_number,
1818                     ElementsAre(VarIntField(
1819                         perfetto_protos_TrackEvent_TYPE_INSTANT)))));
1820     IdFieldView name_iid_fields(
1821         track_event.front(), perfetto_protos_TrackEvent_name_iid_field_number);
1822     ASSERT_THAT(name_iid_fields, ElementsAre(VarIntField(_)));
1823     uint64_t name_iid = name_iid_fields.front().value.integer64;
1824     EXPECT_THAT(trace_field,
1825                 AllFieldsWithId(
1826                     perfetto_protos_TracePacket_interned_data_field_number,
1827                     ElementsAre(AllFieldsWithId(
1828                         perfetto_protos_InternedData_event_names_field_number,
1829                         ElementsAre(MsgField(UnorderedElementsAre(
1830                             PbField(perfetto_protos_EventName_iid_field_number,
1831                                     VarIntField(name_iid)),
1832                             PbField(perfetto_protos_EventName_name_field_number,
1833                                     StringField("event")))))))));
1834     it++;
1835     break;
1836   }
1837   ASSERT_NE(it, trace_view.end());
1838   for (; it != trace_view.end(); it++) {
1839     struct PerfettoPbDecoderField trace_field = *it;
1840     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1841                                      MsgField(_)));
1842     IdFieldView track_event(
1843         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1844     if (track_event.size() == 0) {
1845       continue;
1846     }
1847     ASSERT_THAT(track_event,
1848                 ElementsAre(AllFieldsWithId(
1849                     perfetto_protos_TrackEvent_type_field_number,
1850                     ElementsAre(VarIntField(
1851                         perfetto_protos_TrackEvent_TYPE_SLICE_END)))));
1852     IdFieldView debug_annot_fields(
1853         track_event.front(),
1854         perfetto_protos_TrackEvent_debug_annotations_field_number);
1855     ASSERT_THAT(debug_annot_fields, ElementsAre());
1856     it++;
1857     break;
1858   }
1859 }
1860 
TEST_F(SharedLibTrackEventTest,ScopedDisabled)1861 TEST_F(SharedLibTrackEventTest, ScopedDisabled) {
1862   TracingSession tracing_session = TracingSession::Builder()
1863                                        .set_data_source_name("track_event")
1864                                        .add_disabled_category("cat1")
1865                                        .Build();
1866   // Check that the PERFETTO_TE_SCOPED macro does not have any effect if the
1867   // category is disabled.
1868   { PERFETTO_TE_SCOPED(cat1, PERFETTO_TE_SLICE("slice")); }
1869 
1870   tracing_session.StopBlocking();
1871   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1872   auto trace_view = FieldView(data);
1873   auto it = trace_view.begin();
1874   for (; it != trace_view.end(); it++) {
1875     struct PerfettoPbDecoderField trace_field = *it;
1876     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1877                                      MsgField(_)));
1878     IdFieldView track_event(
1879         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1880     ASSERT_EQ(track_event.size(), 0u);
1881   }
1882 }
1883 
TEST_F(SharedLibTrackEventTest,ScopedSingleLine)1884 TEST_F(SharedLibTrackEventTest, ScopedSingleLine) {
1885   TracingSession tracing_session = TracingSession::Builder()
1886                                        .set_data_source_name("track_event")
1887                                        .add_enabled_category("*")
1888                                        .Build();
1889 
1890   // Check that the PERFETTO_TE_SCOPED macro is expanded into a single
1891   // statement. Emitting the end event should not escape
1892   if (false)
1893     PERFETTO_TE_SCOPED(cat1, PERFETTO_TE_SLICE("slice"));
1894 
1895   tracing_session.StopBlocking();
1896   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1897   auto trace_view = FieldView(data);
1898   auto it = trace_view.begin();
1899   for (; it != trace_view.end(); it++) {
1900     struct PerfettoPbDecoderField trace_field = *it;
1901     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1902                                      MsgField(_)));
1903     IdFieldView track_event(
1904         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1905     ASSERT_EQ(track_event.size(), 0u);
1906   }
1907 }
1908 
TEST_F(SharedLibTrackEventTest,ScopedCapture)1909 TEST_F(SharedLibTrackEventTest, ScopedCapture) {
1910   TracingSession tracing_session = TracingSession::Builder()
1911                                        .set_data_source_name("track_event")
1912                                        .add_enabled_category("*")
1913                                        .Build();
1914 
1915   // Check that the PERFETTO_TE_SCOPED macro can capture variables.
1916   uint64_t value = 42;
1917   {
1918     PERFETTO_TE_SCOPED(cat1, PERFETTO_TE_SLICE("slice"),
1919                        PERFETTO_TE_ARG_UINT64("arg_name", value));
1920   }
1921 
1922   tracing_session.StopBlocking();
1923   std::vector<uint8_t> data = tracing_session.ReadBlocking();
1924   auto trace_view = FieldView(data);
1925   auto it = trace_view.begin();
1926   for (; it != trace_view.end(); it++) {
1927     struct PerfettoPbDecoderField trace_field = *it;
1928     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1929                                      MsgField(_)));
1930     IdFieldView track_event(
1931         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1932     if (track_event.size() == 0) {
1933       continue;
1934     }
1935 
1936     ASSERT_THAT(track_event,
1937                 ElementsAre(AllFieldsWithId(
1938                     perfetto_protos_TrackEvent_type_field_number,
1939                     ElementsAre(VarIntField(
1940                         perfetto_protos_TrackEvent_TYPE_SLICE_BEGIN)))));
1941     IdFieldView name_iid_fields(
1942         track_event.front(), perfetto_protos_TrackEvent_name_iid_field_number);
1943     ASSERT_THAT(name_iid_fields, ElementsAre(VarIntField(_)));
1944     uint64_t name_iid = name_iid_fields.front().value.integer64;
1945     IdFieldView debug_annot_fields(
1946         track_event.front(),
1947         perfetto_protos_TrackEvent_debug_annotations_field_number);
1948     ASSERT_THAT(
1949         debug_annot_fields,
1950         ElementsAre(MsgField(UnorderedElementsAre(
1951             PbField(perfetto_protos_DebugAnnotation_name_iid_field_number,
1952                     VarIntField(_)),
1953             PbField(perfetto_protos_DebugAnnotation_uint_value_field_number,
1954                     VarIntField(42))))));
1955     uint64_t arg_name_iid =
1956         IdFieldView(debug_annot_fields.front(),
1957                     perfetto_protos_DebugAnnotation_name_iid_field_number)
1958             .front()
1959             .value.integer64;
1960     EXPECT_THAT(
1961         trace_field,
1962         AllFieldsWithId(
1963             perfetto_protos_TracePacket_interned_data_field_number,
1964             ElementsAre(AllOf(
1965                 AllFieldsWithId(
1966                     perfetto_protos_InternedData_event_names_field_number,
1967                     ElementsAre(MsgField(UnorderedElementsAre(
1968                         PbField(perfetto_protos_EventName_iid_field_number,
1969                                 VarIntField(name_iid)),
1970                         PbField(perfetto_protos_EventName_name_field_number,
1971                                 StringField("slice")))))),
1972                 AllFieldsWithId(
1973                     perfetto_protos_InternedData_debug_annotation_names_field_number,
1974                     ElementsAre(MsgField(UnorderedElementsAre(
1975                         PbField(
1976                             perfetto_protos_DebugAnnotationName_iid_field_number,
1977                             VarIntField(arg_name_iid)),
1978                         PbField(
1979                             perfetto_protos_DebugAnnotationName_name_field_number,
1980                             StringField("arg_name"))))))))));
1981     it++;
1982     break;
1983   }
1984   ASSERT_NE(it, trace_view.end());
1985   for (; it != trace_view.end(); it++) {
1986     struct PerfettoPbDecoderField trace_field = *it;
1987     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
1988                                      MsgField(_)));
1989     IdFieldView track_event(
1990         trace_field, perfetto_protos_TracePacket_track_event_field_number);
1991     if (track_event.size() == 0) {
1992       continue;
1993     }
1994     ASSERT_THAT(track_event,
1995                 ElementsAre(AllFieldsWithId(
1996                     perfetto_protos_TrackEvent_type_field_number,
1997                     ElementsAre(VarIntField(
1998                         perfetto_protos_TrackEvent_TYPE_SLICE_END)))));
1999     IdFieldView debug_annot_fields(
2000         track_event.front(),
2001         perfetto_protos_TrackEvent_debug_annotations_field_number);
2002     ASSERT_THAT(debug_annot_fields, ElementsAre());
2003     it++;
2004     break;
2005   }
2006 }
2007 
TEST_F(SharedLibTrackEventTest,ScopedFunc)2008 TEST_F(SharedLibTrackEventTest, ScopedFunc) {
2009   TracingSession tracing_session = TracingSession::Builder()
2010                                        .set_data_source_name("track_event")
2011                                        .add_enabled_category("*")
2012                                        .Build();
2013 
2014   // Check that using __func__ works as expected.
2015   { PERFETTO_TE_SCOPED(cat1, PERFETTO_TE_SLICE(__func__)); }
2016 
2017   tracing_session.StopBlocking();
2018   std::vector<uint8_t> data = tracing_session.ReadBlocking();
2019   auto trace_view = FieldView(data);
2020   auto it = trace_view.begin();
2021   for (; it != trace_view.end(); it++) {
2022     struct PerfettoPbDecoderField trace_field = *it;
2023     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
2024                                      MsgField(_)));
2025     IdFieldView track_event(
2026         trace_field, perfetto_protos_TracePacket_track_event_field_number);
2027     if (track_event.size() == 0) {
2028       continue;
2029     }
2030 
2031     ASSERT_THAT(track_event,
2032                 ElementsAre(AllFieldsWithId(
2033                     perfetto_protos_TrackEvent_type_field_number,
2034                     ElementsAre(VarIntField(
2035                         perfetto_protos_TrackEvent_TYPE_SLICE_BEGIN)))));
2036     IdFieldView name_iid_fields(
2037         track_event.front(), perfetto_protos_TrackEvent_name_iid_field_number);
2038     ASSERT_THAT(name_iid_fields, ElementsAre(VarIntField(_)));
2039     uint64_t name_iid = name_iid_fields.front().value.integer64;
2040     EXPECT_THAT(trace_field,
2041                 AllFieldsWithId(
2042                     perfetto_protos_TracePacket_interned_data_field_number,
2043                     ElementsAre(AllFieldsWithId(
2044                         perfetto_protos_InternedData_event_names_field_number,
2045                         ElementsAre(MsgField(UnorderedElementsAre(
2046                             PbField(perfetto_protos_EventName_iid_field_number,
2047                                     VarIntField(name_iid)),
2048                             PbField(perfetto_protos_EventName_name_field_number,
2049                                     StringField(__func__)))))))));
2050     it++;
2051     break;
2052   }
2053   ASSERT_NE(it, trace_view.end());
2054   for (; it != trace_view.end(); it++) {
2055     struct PerfettoPbDecoderField trace_field = *it;
2056     ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
2057                                      MsgField(_)));
2058     IdFieldView track_event(
2059         trace_field, perfetto_protos_TracePacket_track_event_field_number);
2060     if (track_event.size() == 0) {
2061       continue;
2062     }
2063     ASSERT_THAT(track_event,
2064                 ElementsAre(AllFieldsWithId(
2065                     perfetto_protos_TrackEvent_type_field_number,
2066                     ElementsAre(VarIntField(
2067                         perfetto_protos_TrackEvent_TYPE_SLICE_END)))));
2068     IdFieldView debug_annot_fields(
2069         track_event.front(),
2070         perfetto_protos_TrackEvent_debug_annotations_field_number);
2071     ASSERT_THAT(debug_annot_fields, ElementsAre());
2072     it++;
2073     break;
2074   }
2075 }
2076 
TEST_F(SharedLibTrackEventTest,TrackEventHlProtoFieldString)2077 TEST_F(SharedLibTrackEventTest, TrackEventHlProtoFieldString) {
2078   TracingSession tracing_session = TracingSession::Builder()
2079                                        .set_data_source_name("track_event")
2080                                        .add_enabled_category("*")
2081                                        .Build();
2082 
2083   PERFETTO_TE(
2084       cat1, PERFETTO_TE_INSTANT("event"),
2085       PERFETTO_TE_PROTO_FIELDS(PERFETTO_TE_PROTO_FIELD_NESTED(
2086           perfetto_protos_TrackEvent_debug_annotations_field_number,
2087           PERFETTO_TE_PROTO_FIELD_CSTR(
2088               perfetto_protos_DebugAnnotation_name_field_number, "name"),
2089           PERFETTO_TE_PROTO_FIELD_VARINT(
2090               perfetto_protos_DebugAnnotation_uint_value_field_number, 42))));
2091 
2092   tracing_session.StopBlocking();
2093   std::vector<uint8_t> data = tracing_session.ReadBlocking();
2094   EXPECT_THAT(
2095       FieldView(data),
2096       Contains(PbField(
2097           perfetto_protos_Trace_packet_field_number,
2098           AllFieldsWithId(
2099               perfetto_protos_TracePacket_track_event_field_number,
2100               ElementsAre(AllFieldsWithId(
2101                   perfetto_protos_TrackEvent_debug_annotations_field_number,
2102                   ElementsAre(MsgField(UnorderedElementsAre(
2103                       PbField(perfetto_protos_DebugAnnotation_name_field_number,
2104                               StringField("name")),
2105                       PbField(
2106                           perfetto_protos_DebugAnnotation_uint_value_field_number,
2107                           VarIntField(42)))))))))));
2108 }
2109 
2110 }  // namespace
2111