Add integration tests for shared library track event
Bug: 237053982
Change-Id: I54757918d1de3ae4025e9c6e2d859cefbe8914a8
diff --git a/include/perfetto/public/protos/BUILD.gn b/include/perfetto/public/protos/BUILD.gn
index 64d324f..cd583ad 100644
--- a/include/perfetto/public/protos/BUILD.gn
+++ b/include/perfetto/public/protos/BUILD.gn
@@ -17,6 +17,7 @@
"common/builtin_clock.pzc.h",
"config/data_source_config.pzc.h",
"config/trace_config.pzc.h",
+ "config/track_event/track_event_config.pzc.h",
"trace/interned_data/interned_data.pzc.h",
"trace/test_event.pzc.h",
"trace/trace.pzc.h",
diff --git a/include/perfetto/public/protos/config/track_event/track_event_config.pzc.h b/include/perfetto/public/protos/config/track_event/track_event_config.pzc.h
new file mode 100644
index 0000000..271cd24
--- /dev/null
+++ b/include/perfetto/public/protos/config/track_event/track_event_config.pzc.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PUBLIC_PROTOS_CONFIG_TRACK_EVENT_TRACK_EVENT_CONFIG_PZC_H_
+#define INCLUDE_PERFETTO_PUBLIC_PROTOS_CONFIG_TRACK_EVENT_TRACK_EVENT_CONFIG_PZC_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "perfetto/public/pb_macros.h"
+
+PERFETTO_PB_MSG(perfetto_protos_TrackEventConfig);
+PERFETTO_PB_FIELD(perfetto_protos_TrackEventConfig,
+ STRING,
+ const char*,
+ disabled_categories,
+ 1);
+PERFETTO_PB_FIELD(perfetto_protos_TrackEventConfig,
+ STRING,
+ const char*,
+ enabled_categories,
+ 2);
+PERFETTO_PB_FIELD(perfetto_protos_TrackEventConfig,
+ STRING,
+ const char*,
+ disabled_tags,
+ 3);
+PERFETTO_PB_FIELD(perfetto_protos_TrackEventConfig,
+ STRING,
+ const char*,
+ enabled_tags,
+ 4);
+PERFETTO_PB_FIELD(perfetto_protos_TrackEventConfig,
+ VARINT,
+ bool,
+ disable_incremental_timestamps,
+ 5);
+PERFETTO_PB_FIELD(perfetto_protos_TrackEventConfig,
+ VARINT,
+ uint64_t,
+ timestamp_unit_multiplier,
+ 6);
+PERFETTO_PB_FIELD(perfetto_protos_TrackEventConfig,
+ VARINT,
+ bool,
+ filter_debug_annotations,
+ 7);
+PERFETTO_PB_FIELD(perfetto_protos_TrackEventConfig,
+ VARINT,
+ bool,
+ enable_thread_time_sampling,
+ 8);
+PERFETTO_PB_FIELD(perfetto_protos_TrackEventConfig,
+ VARINT,
+ bool,
+ filter_dynamic_event_names,
+ 9);
+
+#endif // INCLUDE_PERFETTO_PUBLIC_PROTOS_CONFIG_TRACK_EVENT_TRACK_EVENT_CONFIG_PZC_H_
diff --git a/src/shared_lib/test/api_integrationtest.cc b/src/shared_lib/test/api_integrationtest.cc
index 3ef111e..d572017 100644
--- a/src/shared_lib/test/api_integrationtest.cc
+++ b/src/shared_lib/test/api_integrationtest.cc
@@ -20,15 +20,22 @@
#include "perfetto/public/abi/heap_buffer.h"
#include "perfetto/public/abi/pb_decoder_abi.h"
#include "perfetto/public/abi/tracing_session_abi.h"
+#include "perfetto/public/abi/track_event_abi.h"
#include "perfetto/public/data_source.h"
#include "perfetto/public/pb_decoder.h"
#include "perfetto/public/producer.h"
-#include "perfetto/public/protos/config/data_source_config.pzc.h"
#include "perfetto/public/protos/config/trace_config.pzc.h"
+#include "perfetto/public/protos/trace/interned_data/interned_data.pzc.h"
#include "perfetto/public/protos/trace/test_event.pzc.h"
#include "perfetto/public/protos/trace/trace.pzc.h"
#include "perfetto/public/protos/trace/trace_packet.pzc.h"
+#include "perfetto/public/protos/trace/track_event/debug_annotation.pzc.h"
+#include "perfetto/public/protos/trace/track_event/track_descriptor.pzc.h"
+#include "perfetto/public/protos/trace/track_event/track_event.pzc.h"
#include "perfetto/public/protos/trace/trigger.pzc.h"
+#include "perfetto/public/te_category_macros.h"
+#include "perfetto/public/te_macros.h"
+#include "perfetto/public/track_event.h"
#include "test/gtest_and_gmock.h"
@@ -39,20 +46,24 @@
namespace {
+using ::perfetto::shlib::test_utils::AllFieldsWithId;
using ::perfetto::shlib::test_utils::FieldView;
using ::perfetto::shlib::test_utils::IdFieldView;
using ::perfetto::shlib::test_utils::MsgField;
using ::perfetto::shlib::test_utils::PbField;
using ::perfetto::shlib::test_utils::StringField;
using ::perfetto::shlib::test_utils::TracingSession;
+using ::perfetto::shlib::test_utils::VarIntField;
using ::perfetto::shlib::test_utils::WaitableEvent;
using ::testing::_;
+using ::testing::AllOf;
using ::testing::DoAll;
using ::testing::ElementsAre;
using ::testing::InSequence;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SaveArg;
+using ::testing::UnorderedElementsAre;
constexpr char kDataSourceName1[] = "dev.perfetto.example_data_source";
struct PerfettoDs data_source_1 = PERFETTO_DS_INIT();
@@ -61,6 +72,10 @@
struct PerfettoDs data_source_2 = PERFETTO_DS_INIT();
void* const kDataSource2UserArg = reinterpret_cast<void*>(0x555);
+#define TEST_CATEGORIES(C) \
+ C(cat1, "cat1", "") C(cat2, "cat2", "") C(cat3, "cat3", "")
+PERFETTO_TE_CATEGORIES_DEFINE(TEST_CATEGORIES)
+
class MockDs2Callbacks : testing::Mock {
public:
MOCK_METHOD(void*,
@@ -572,7 +587,7 @@
void TearDown() override { perfetto::shlib::ResetForTesting(); }
};
-TEST_F(SharedLibDataSourceTest, ActivateTriggers) {
+TEST_F(SharedLibProducerTest, ActivateTriggers) {
struct PerfettoPbMsgWriter writer;
struct PerfettoHeapBuffer* hb = PerfettoHeapBufferCreate(&writer.writer);
@@ -634,4 +649,451 @@
StringField("trigger1"))))))))));
}
+class SharedLibTrackEventTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ struct PerfettoProducerInitArgs args = {0};
+ args.backends = PERFETTO_BACKEND_IN_PROCESS;
+ PerfettoProducerInit(args);
+ PerfettoTeInit();
+ PERFETTO_TE_REGISTER_CATEGORIES(TEST_CATEGORIES);
+ }
+
+ void TearDown() override {
+ PERFETTO_TE_UNREGISTER_CATEGORIES(TEST_CATEGORIES);
+ perfetto::shlib::ResetForTesting();
+ }
+};
+
+TEST_F(SharedLibTrackEventTest, TrackEventFastpathOtherDsCatDisabled) {
+ TracingSession tracing_session =
+ TracingSession::Builder()
+ .set_data_source_name("other_nonexisting_datasource")
+ .Build();
+ EXPECT_FALSE(std::atomic_load(cat1.enabled));
+ EXPECT_FALSE(std::atomic_load(cat2.enabled));
+ EXPECT_FALSE(std::atomic_load(cat3.enabled));
+}
+
+TEST_F(SharedLibTrackEventTest, TrackEventFastpathEmptyConfigEnableAllCats) {
+ ASSERT_FALSE(std::atomic_load(cat1.enabled));
+ ASSERT_FALSE(std::atomic_load(cat2.enabled));
+ ASSERT_FALSE(std::atomic_load(cat3.enabled));
+
+ TracingSession tracing_session =
+ TracingSession::Builder().set_data_source_name("track_event").Build();
+
+ EXPECT_TRUE(std::atomic_load(cat1.enabled));
+ EXPECT_TRUE(std::atomic_load(cat2.enabled));
+ EXPECT_TRUE(std::atomic_load(cat3.enabled));
+}
+
+TEST_F(SharedLibTrackEventTest, TrackEventFastpathOneCatEnabled) {
+ ASSERT_FALSE(std::atomic_load(cat1.enabled));
+ ASSERT_FALSE(std::atomic_load(cat2.enabled));
+ ASSERT_FALSE(std::atomic_load(cat3.enabled));
+
+ TracingSession tracing_session = TracingSession::Builder()
+ .set_data_source_name("track_event")
+ .add_enabled_category("cat1")
+ .add_disabled_category("*")
+ .Build();
+
+ EXPECT_TRUE(std::atomic_load(cat1.enabled));
+ EXPECT_FALSE(std::atomic_load(cat2.enabled));
+ EXPECT_FALSE(std::atomic_load(cat3.enabled));
+}
+
+TEST_F(SharedLibTrackEventTest, TrackEventHlCategory) {
+ TracingSession tracing_session =
+ TracingSession::Builder().set_data_source_name("track_event").Build();
+
+ PERFETTO_TE(cat1, PERFETTO_TE_INSTANT(""));
+ PERFETTO_TE(cat1, PERFETTO_TE_INSTANT(""));
+
+ tracing_session.StopBlocking();
+ std::vector<uint8_t> data = tracing_session.ReadBlocking();
+ bool found = false;
+ for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
+ ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
+ MsgField(_)));
+ IdFieldView track_event(
+ trace_field, perfetto_protos_TracePacket_track_event_field_number);
+ if (track_event.size() == 0) {
+ continue;
+ }
+ found = true;
+ IdFieldView cat_iid_fields(
+ track_event.front(),
+ perfetto_protos_TrackEvent_category_iids_field_number);
+ ASSERT_THAT(cat_iid_fields, ElementsAre(VarIntField(_)));
+ uint64_t cat_iid = cat_iid_fields.front().value.integer64;
+ EXPECT_THAT(
+ trace_field,
+ AllFieldsWithId(
+ perfetto_protos_TracePacket_interned_data_field_number,
+ ElementsAre(AllFieldsWithId(
+ perfetto_protos_InternedData_event_categories_field_number,
+ ElementsAre(MsgField(UnorderedElementsAre(
+ PbField(perfetto_protos_EventCategory_iid_field_number,
+ VarIntField(cat_iid)),
+ PbField(perfetto_protos_EventCategory_name_field_number,
+ StringField("cat1")))))))));
+ }
+ EXPECT_TRUE(found);
+}
+
+TEST_F(SharedLibTrackEventTest, TrackEventHlDynamicCategory) {
+ TracingSession tracing_session = TracingSession::Builder()
+ .set_data_source_name("track_event")
+ .add_enabled_category("dyn1")
+ .add_enabled_category("cat1")
+ .add_disabled_category("*")
+ .Build();
+
+ PERFETTO_TE(PERFETTO_TE_DYNAMIC_CATEGORY, PERFETTO_TE_INSTANT(""),
+ PERFETTO_TE_DYNAMIC_CATEGORY_STRING("dyn2"));
+ PERFETTO_TE(PERFETTO_TE_DYNAMIC_CATEGORY, PERFETTO_TE_INSTANT(""),
+ PERFETTO_TE_DYNAMIC_CATEGORY_STRING("dyn1"));
+ PERFETTO_TE(cat1, PERFETTO_TE_INSTANT(""));
+
+ tracing_session.StopBlocking();
+ std::vector<uint8_t> data = tracing_session.ReadBlocking();
+ bool found = false;
+ for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
+ ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
+ MsgField(_)));
+ IdFieldView track_event(
+ trace_field, perfetto_protos_TracePacket_track_event_field_number);
+ if (track_event.size() == 0) {
+ continue;
+ }
+ found = true;
+ EXPECT_THAT(track_event,
+ ElementsAre(AllFieldsWithId(
+ perfetto_protos_TrackEvent_categories_field_number,
+ ElementsAre(StringField("dyn1")))));
+ }
+ EXPECT_TRUE(found);
+}
+
+TEST_F(SharedLibTrackEventTest, TrackEventHlInstant) {
+ TracingSession tracing_session =
+ TracingSession::Builder().set_data_source_name("track_event").Build();
+
+ PERFETTO_TE(cat1, PERFETTO_TE_INSTANT("event"));
+ PERFETTO_TE(cat1, PERFETTO_TE_INSTANT(""));
+
+ tracing_session.StopBlocking();
+ std::vector<uint8_t> data = tracing_session.ReadBlocking();
+ bool found = false;
+ for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
+ ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
+ MsgField(_)));
+ IdFieldView track_event(
+ trace_field, perfetto_protos_TracePacket_track_event_field_number);
+ if (track_event.size() == 0) {
+ continue;
+ }
+ found = true;
+ ASSERT_THAT(track_event,
+ ElementsAre(AllFieldsWithId(
+ perfetto_protos_TrackEvent_type_field_number,
+ ElementsAre(VarIntField(
+ perfetto_protos_TrackEvent_TYPE_INSTANT)))));
+ IdFieldView name_iid_fields(
+ track_event.front(), perfetto_protos_TrackEvent_name_iid_field_number);
+ ASSERT_THAT(name_iid_fields, ElementsAre(VarIntField(_)));
+ uint64_t name_iid = name_iid_fields.front().value.integer64;
+ EXPECT_THAT(trace_field,
+ AllFieldsWithId(
+ perfetto_protos_TracePacket_interned_data_field_number,
+ ElementsAre(AllFieldsWithId(
+ perfetto_protos_InternedData_event_names_field_number,
+ ElementsAre(MsgField(UnorderedElementsAre(
+ PbField(perfetto_protos_EventName_iid_field_number,
+ VarIntField(name_iid)),
+ PbField(perfetto_protos_EventName_name_field_number,
+ StringField("event")))))))));
+ }
+ EXPECT_TRUE(found);
+}
+
+TEST_F(SharedLibTrackEventTest, TrackEventLlInstant) {
+ TracingSession tracing_session =
+ TracingSession::Builder().set_data_source_name("track_event").Build();
+
+ if (PERFETTO_UNLIKELY(PERFETTO_ATOMIC_LOAD_EXPLICIT(
+ cat1.enabled, PERFETTO_MEMORY_ORDER_RELAXED))) {
+ struct PerfettoTeTimestamp timestamp = PerfettoTeGetTimestamp();
+ int32_t type = PERFETTO_TE_TYPE_INSTANT;
+ const char* name = "event";
+ for (struct PerfettoTeLlIterator ctx =
+ PerfettoTeLlBeginSlowPath(&cat1, timestamp);
+ ctx.impl.ds.tracer != nullptr;
+ PerfettoTeLlNext(&cat1, timestamp, &ctx)) {
+ uint64_t name_iid;
+ {
+ struct PerfettoDsRootTracePacket trace_packet;
+ PerfettoTeLlPacketBegin(&ctx, &trace_packet);
+ PerfettoTeLlWriteTimestamp(&trace_packet.msg, ×tamp);
+ perfetto_protos_TracePacket_set_sequence_flags(
+ &trace_packet.msg,
+ perfetto_protos_TracePacket_SEQ_NEEDS_INCREMENTAL_STATE);
+ {
+ struct PerfettoTeLlInternContext intern_ctx;
+ PerfettoTeLlInternContextInit(&intern_ctx, ctx.impl.incr,
+ &trace_packet.msg);
+ PerfettoTeLlInternRegisteredCat(&intern_ctx, &cat1);
+ name_iid = PerfettoTeLlInternEventName(&intern_ctx, name);
+ PerfettoTeLlInternContextDestroy(&intern_ctx);
+ }
+ {
+ struct perfetto_protos_TrackEvent te_msg;
+ perfetto_protos_TracePacket_begin_track_event(&trace_packet.msg,
+ &te_msg);
+ perfetto_protos_TrackEvent_set_type(
+ &te_msg, static_cast<enum perfetto_protos_TrackEvent_Type>(type));
+ PerfettoTeLlWriteRegisteredCat(&te_msg, &cat1);
+ PerfettoTeLlWriteInternedEventName(&te_msg, name_iid);
+ perfetto_protos_TracePacket_end_track_event(&trace_packet.msg,
+ &te_msg);
+ }
+ PerfettoTeLlPacketEnd(&ctx, &trace_packet);
+ }
+ }
+ }
+ PERFETTO_TE(cat1, PERFETTO_TE_INSTANT(""));
+
+ tracing_session.StopBlocking();
+ std::vector<uint8_t> data = tracing_session.ReadBlocking();
+ bool found = false;
+ for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
+ ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
+ MsgField(_)));
+ IdFieldView track_event(
+ trace_field, perfetto_protos_TracePacket_track_event_field_number);
+ if (track_event.size() == 0) {
+ continue;
+ }
+ found = true;
+ ASSERT_THAT(track_event,
+ ElementsAre(AllFieldsWithId(
+ perfetto_protos_TrackEvent_type_field_number,
+ ElementsAre(VarIntField(
+ perfetto_protos_TrackEvent_TYPE_INSTANT)))));
+ IdFieldView name_iid_fields(
+ track_event.front(), perfetto_protos_TrackEvent_name_iid_field_number);
+ ASSERT_THAT(name_iid_fields, ElementsAre(VarIntField(_)));
+ uint64_t name_iid = name_iid_fields.front().value.integer64;
+ EXPECT_THAT(trace_field,
+ AllFieldsWithId(
+ perfetto_protos_TracePacket_interned_data_field_number,
+ ElementsAre(AllFieldsWithId(
+ perfetto_protos_InternedData_event_names_field_number,
+ ElementsAre(MsgField(UnorderedElementsAre(
+ PbField(perfetto_protos_EventName_iid_field_number,
+ VarIntField(name_iid)),
+ PbField(perfetto_protos_EventName_name_field_number,
+ StringField("event")))))))));
+ }
+ EXPECT_TRUE(found);
+}
+
+TEST_F(SharedLibTrackEventTest, TrackEventHlInstantNoIntern) {
+ TracingSession tracing_session =
+ TracingSession::Builder().set_data_source_name("track_event").Build();
+
+ PERFETTO_TE(cat1, PERFETTO_TE_INSTANT("event"), PERFETTO_TE_NO_INTERN());
+ PERFETTO_TE(cat1, PERFETTO_TE_INSTANT(""));
+
+ tracing_session.StopBlocking();
+ std::vector<uint8_t> data = tracing_session.ReadBlocking();
+ bool found = false;
+ for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
+ ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
+ MsgField(_)));
+ IdFieldView track_event(
+ trace_field, perfetto_protos_TracePacket_track_event_field_number);
+ if (track_event.size() == 0) {
+ continue;
+ }
+ found = true;
+ ASSERT_THAT(
+ track_event,
+ ElementsAre(AllOf(
+ AllFieldsWithId(perfetto_protos_TrackEvent_type_field_number,
+ ElementsAre(VarIntField(
+ perfetto_protos_TrackEvent_TYPE_INSTANT))),
+ AllFieldsWithId(perfetto_protos_TrackEvent_name_field_number,
+ ElementsAre(StringField("event"))))));
+ }
+ EXPECT_TRUE(found);
+}
+
+TEST_F(SharedLibTrackEventTest, TrackEventHlDbgArg) {
+ TracingSession tracing_session =
+ TracingSession::Builder().set_data_source_name("track_event").Build();
+
+ PERFETTO_TE(cat1, PERFETTO_TE_INSTANT("event"),
+ PERFETTO_TE_ARG_UINT64("arg_name", 42));
+ PERFETTO_TE(cat1, PERFETTO_TE_INSTANT(""));
+
+ tracing_session.StopBlocking();
+ std::vector<uint8_t> data = tracing_session.ReadBlocking();
+ bool found = false;
+ for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
+ ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
+ MsgField(_)));
+ IdFieldView track_event(
+ trace_field, perfetto_protos_TracePacket_track_event_field_number);
+ if (track_event.size() == 0) {
+ continue;
+ }
+ found = true;
+ ASSERT_THAT(track_event,
+ ElementsAre(AllFieldsWithId(
+ perfetto_protos_TrackEvent_type_field_number,
+ ElementsAre(VarIntField(
+ perfetto_protos_TrackEvent_TYPE_INSTANT)))));
+ IdFieldView name_iid_fields(
+ track_event.front(), perfetto_protos_TrackEvent_name_iid_field_number);
+ ASSERT_THAT(name_iid_fields, ElementsAre(VarIntField(_)));
+ uint64_t name_iid = name_iid_fields.front().value.integer64;
+ IdFieldView debug_annot_fields(
+ track_event.front(),
+ perfetto_protos_TrackEvent_debug_annotations_field_number);
+ ASSERT_THAT(
+ debug_annot_fields,
+ ElementsAre(MsgField(UnorderedElementsAre(
+ PbField(perfetto_protos_DebugAnnotation_name_iid_field_number,
+ VarIntField(_)),
+ PbField(perfetto_protos_DebugAnnotation_uint_value_field_number,
+ VarIntField(42))))));
+ uint64_t arg_name_iid =
+ IdFieldView(debug_annot_fields.front(),
+ perfetto_protos_DebugAnnotation_name_iid_field_number)
+ .front()
+ .value.integer64;
+ EXPECT_THAT(
+ trace_field,
+ AllFieldsWithId(
+ perfetto_protos_TracePacket_interned_data_field_number,
+ ElementsAre(AllOf(
+ AllFieldsWithId(
+ perfetto_protos_InternedData_event_names_field_number,
+ ElementsAre(MsgField(UnorderedElementsAre(
+ PbField(perfetto_protos_EventName_iid_field_number,
+ VarIntField(name_iid)),
+ PbField(perfetto_protos_EventName_name_field_number,
+ StringField("event")))))),
+ AllFieldsWithId(
+ perfetto_protos_InternedData_debug_annotation_names_field_number,
+ ElementsAre(MsgField(UnorderedElementsAre(
+ PbField(
+ perfetto_protos_DebugAnnotationName_iid_field_number,
+ VarIntField(arg_name_iid)),
+ PbField(
+ perfetto_protos_DebugAnnotationName_name_field_number,
+ StringField("arg_name"))))))))));
+ }
+ EXPECT_TRUE(found);
+}
+
+TEST_F(SharedLibTrackEventTest, TrackEventHlNamedTrack) {
+ TracingSession tracing_session =
+ TracingSession::Builder().set_data_source_name("track_event").Build();
+
+ PERFETTO_TE(cat1, PERFETTO_TE_INSTANT("event"),
+ PERFETTO_TE_NAMED_TRACK("MyTrack", 1, 2));
+ PERFETTO_TE(cat1, PERFETTO_TE_INSTANT(""));
+
+ uint64_t kExpectedUuid = PerfettoTeNamedTrackUuid("MyTrack", 1, 2);
+
+ tracing_session.StopBlocking();
+ std::vector<uint8_t> data = tracing_session.ReadBlocking();
+ EXPECT_THAT(
+ FieldView(data),
+ AllOf(
+ Contains(PbField(
+ perfetto_protos_Trace_packet_field_number,
+ AllFieldsWithId(
+ perfetto_protos_TracePacket_track_descriptor_field_number,
+ ElementsAre(MsgField(UnorderedElementsAre(
+ PbField(perfetto_protos_TrackDescriptor_uuid_field_number,
+ VarIntField(kExpectedUuid)),
+ PbField(perfetto_protos_TrackDescriptor_name_field_number,
+ StringField("MyTrack")),
+ PbField(
+ perfetto_protos_TrackDescriptor_parent_uuid_field_number,
+ VarIntField(2)))))))),
+ Contains(PbField(
+ perfetto_protos_Trace_packet_field_number,
+ AllFieldsWithId(
+ perfetto_protos_TracePacket_track_event_field_number,
+ ElementsAre(AllOf(
+ AllFieldsWithId(
+ perfetto_protos_TrackEvent_type_field_number,
+ ElementsAre(VarIntField(
+ perfetto_protos_TrackEvent_TYPE_INSTANT))),
+ AllFieldsWithId(
+ perfetto_protos_TrackEvent_track_uuid_field_number,
+ ElementsAre(VarIntField(kExpectedUuid))))))))));
+}
+
+TEST_F(SharedLibTrackEventTest, TrackEventHlRegisteredCounter) {
+ TracingSession tracing_session =
+ TracingSession::Builder().set_data_source_name("track_event").Build();
+
+ PerfettoTeRegisteredTrack my_counter_track;
+ PerfettoTeCounterTrackRegister(&my_counter_track, "MyCounter",
+ PerfettoTeProcessTrackUuid());
+
+ PERFETTO_TE(cat1, PERFETTO_TE_COUNTER(),
+ PERFETTO_TE_REGISTERED_TRACK(&my_counter_track),
+ PERFETTO_TE_INT_COUNTER(42));
+ PERFETTO_TE(cat1, PERFETTO_TE_INSTANT(""));
+
+ PerfettoTeRegisteredTrackUnregister(&my_counter_track);
+
+ uint64_t kExpectedUuid =
+ PerfettoTeCounterTrackUuid("MyCounter", PerfettoTeProcessTrackUuid());
+
+ tracing_session.StopBlocking();
+ std::vector<uint8_t> data = tracing_session.ReadBlocking();
+ EXPECT_THAT(
+ FieldView(data),
+ AllOf(
+ Contains(PbField(
+ perfetto_protos_Trace_packet_field_number,
+ AllFieldsWithId(
+ perfetto_protos_TracePacket_track_descriptor_field_number,
+ ElementsAre(MsgField(UnorderedElementsAre(
+ PbField(perfetto_protos_TrackDescriptor_uuid_field_number,
+ VarIntField(kExpectedUuid)),
+ PbField(perfetto_protos_TrackDescriptor_name_field_number,
+ StringField("MyCounter")),
+ PbField(
+ perfetto_protos_TrackDescriptor_parent_uuid_field_number,
+ VarIntField(PerfettoTeProcessTrackUuid())),
+ PbField(
+ perfetto_protos_TrackDescriptor_counter_field_number,
+ MsgField(_)))))))),
+ Contains(PbField(
+ perfetto_protos_Trace_packet_field_number,
+ AllFieldsWithId(
+ perfetto_protos_TracePacket_track_event_field_number,
+ ElementsAre(AllOf(
+ AllFieldsWithId(
+ perfetto_protos_TrackEvent_type_field_number,
+ ElementsAre(VarIntField(
+ perfetto_protos_TrackEvent_TYPE_COUNTER))),
+ AllFieldsWithId(
+ perfetto_protos_TrackEvent_counter_value_field_number,
+ ElementsAre(VarIntField(42))),
+ AllFieldsWithId(
+ perfetto_protos_TrackEvent_track_uuid_field_number,
+ ElementsAre(VarIntField(kExpectedUuid))))))))));
+}
+
} // namespace
diff --git a/src/shared_lib/test/utils.cc b/src/shared_lib/test/utils.cc
index 69013bd..7c0ed8d 100644
--- a/src/shared_lib/test/utils.cc
+++ b/src/shared_lib/test/utils.cc
@@ -21,6 +21,7 @@
#include "perfetto/public/pb_utils.h"
#include "perfetto/public/protos/config/data_source_config.pzc.h"
#include "perfetto/public/protos/config/trace_config.pzc.h"
+#include "perfetto/public/protos/config/track_event/track_event_config.pzc.h"
#include "perfetto/public/tracing_session.h"
namespace perfetto {
@@ -67,6 +68,21 @@
perfetto_protos_DataSourceConfig_set_cstr_name(&ds_cfg,
data_source_name_.c_str());
+ if (!enabled_categories_.empty() && !disabled_categories_.empty()) {
+ perfetto_protos_TrackEventConfig te_cfg;
+ perfetto_protos_DataSourceConfig_begin_track_event_config(&ds_cfg,
+ &te_cfg);
+ for (const std::string& cat : enabled_categories_) {
+ perfetto_protos_TrackEventConfig_set_enabled_categories(
+ &te_cfg, cat.data(), cat.size());
+ }
+ for (const std::string& cat : disabled_categories_) {
+ perfetto_protos_TrackEventConfig_set_disabled_categories(
+ &te_cfg, cat.data(), cat.size());
+ }
+ perfetto_protos_DataSourceConfig_end_track_event_config(&ds_cfg,
+ &te_cfg);
+ }
perfetto_protos_TraceConfig_DataSource_end_config(&data_sources, &ds_cfg);
}
diff --git a/src/shared_lib/test/utils.h b/src/shared_lib/test/utils.h
index 875162f..e68376d 100644
--- a/src/shared_lib/test/utils.h
+++ b/src/shared_lib/test/utils.h
@@ -74,10 +74,20 @@
data_source_name_ = std::move(data_source_name);
return *this;
}
+ Builder& add_enabled_category(std::string category) {
+ enabled_categories_.push_back(std::move(category));
+ return *this;
+ }
+ Builder& add_disabled_category(std::string category) {
+ disabled_categories_.push_back(std::move(category));
+ return *this;
+ }
TracingSession Build();
private:
std::string data_source_name_;
+ std::vector<std::string> enabled_categories_;
+ std::vector<std::string> disabled_categories_;
};
static TracingSession Adopt(struct PerfettoTracingSessionImpl*);
@@ -332,6 +342,24 @@
testing::ResultOf(f, m));
}
+// Matches a PerfettoPbDecoderField submessage field. Accepts a container
+// matcher for the subfields.
+//
+// Example:
+// PerfettoPbDecoderField field = ...
+// EXPECT_THAT(field, AllFieldsWithId(900, ElementsAre(...)));
+template <typename M>
+auto AllFieldsWithId(int32_t id, M m) {
+ auto f = [id](const PerfettoPbDecoderField& field) {
+ return IdFieldView(field, id);
+ };
+ return testing::AllOf(
+ testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK),
+ testing::Field(&PerfettoPbDecoderField::wire_type,
+ PERFETTO_PB_WIRE_TYPE_DELIMITED),
+ testing::ResultOf(f, m));
+}
+
} // namespace test_utils
} // namespace shlib
} // namespace perfetto