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