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