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 ¬ification);
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, ×tamp);
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