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