xref: /aosp_15_r20/frameworks/native/libs/tracing_perfetto/tests/tracing_perfetto_test.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright 2024 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 "tracing_perfetto.h"
18 
19 #include <android_os.h>
20 #include <flag_macros.h>
21 #include <thread>
22 #include <unistd.h>
23 
24 #include "gtest/gtest.h"
25 #include "perfetto/public/abi/data_source_abi.h"
26 #include "perfetto/public/abi/heap_buffer.h"
27 #include "perfetto/public/abi/pb_decoder_abi.h"
28 #include "perfetto/public/abi/tracing_session_abi.h"
29 #include "perfetto/public/abi/track_event_abi.h"
30 #include "perfetto/public/data_source.h"
31 #include "perfetto/public/pb_decoder.h"
32 #include "perfetto/public/producer.h"
33 #include "perfetto/public/protos/config/trace_config.pzc.h"
34 #include "perfetto/public/protos/trace/interned_data/interned_data.pzc.h"
35 #include "perfetto/public/protos/trace/test_event.pzc.h"
36 #include "perfetto/public/protos/trace/trace.pzc.h"
37 #include "perfetto/public/protos/trace/trace_packet.pzc.h"
38 #include "perfetto/public/protos/trace/track_event/debug_annotation.pzc.h"
39 #include "perfetto/public/protos/trace/track_event/track_descriptor.pzc.h"
40 #include "perfetto/public/protos/trace/track_event/track_event.pzc.h"
41 #include "perfetto/public/protos/trace/trigger.pzc.h"
42 #include "perfetto/public/te_category_macros.h"
43 #include "perfetto/public/te_macros.h"
44 #include "perfetto/public/track_event.h"
45 #include "trace_categories.h"
46 #include "utils.h"
47 
48 #include "protos/perfetto/trace/trace.pb.h"
49 #include "protos/perfetto/trace/trace_packet.pb.h"
50 #include "protos/perfetto/trace/interned_data/interned_data.pb.h"
51 
52 #include <fstream>
53 #include <iterator>
54 namespace tracing_perfetto {
55 
56 using ::perfetto::protos::Trace;
57 using ::perfetto::protos::TracePacket;
58 using ::perfetto::protos::EventCategory;
59 using ::perfetto::protos::EventName;
60 using ::perfetto::protos::FtraceEvent;
61 using ::perfetto::protos::FtraceEventBundle;
62 using ::perfetto::protos::InternedData;
63 
64 using ::perfetto::shlib::test_utils::TracingSession;
65 
66 const auto PERFETTO_SDK_TRACING = ACONFIG_FLAG(android::os, perfetto_sdk_tracing);
67 
68 // TODO(b/303199244): Add tests for all the library functions.
69 class TracingPerfettoTest : public testing::Test {
70  protected:
SetUp()71   void SetUp() override {
72     tracing_perfetto::registerWithPerfetto(false /* test */);
73   }
74 };
75 
stopSession(TracingSession & tracing_session)76 Trace stopSession(TracingSession& tracing_session) {
77   tracing_session.FlushBlocking(5000);
78   tracing_session.StopBlocking();
79   std::vector<uint8_t> data = tracing_session.ReadBlocking();
80   std::string data_string(data.begin(), data.end());
81 
82   perfetto::protos::Trace trace;
83   trace.ParseFromString(data_string);
84 
85   return trace;
86 }
87 
verifyTrackEvent(const Trace & trace,const std::string expected_category,const std::string & expected_name)88 void verifyTrackEvent(const Trace& trace, const std::string expected_category,
89                       const std::string& expected_name) {
90   bool found = false;
91   for (const TracePacket& packet: trace.packet()) {
92     if (packet.has_track_event() && packet.has_interned_data()) {
93 
94       const InternedData& interned_data = packet.interned_data();
95       if (interned_data.event_categories_size() > 0) {
96         const EventCategory& event_category = packet.interned_data().event_categories(0);
97         if (event_category.name() == expected_category) {
98           found = true;
99         }
100       }
101 
102       if (interned_data.event_names_size() > 0) {
103         const EventName& event_name = packet.interned_data().event_names(0);
104         if (event_name.name() == expected_name) {
105           found &= true;
106         }
107       }
108 
109       if (found) {
110         break;
111       }
112     }
113   }
114   EXPECT_TRUE(found);
115 }
116 
verifyAtraceEvent(const Trace & trace,const std::string & expected_name)117 void verifyAtraceEvent(const Trace& trace, const std::string& expected_name) {
118   std::string expected_print_buf = "I|" + std::to_string(gettid()) + "|" + expected_name + "\n";
119 
120   bool found = false;
121   for (const TracePacket& packet: trace.packet()) {
122     if (packet.has_ftrace_events()) {
123       const FtraceEventBundle& ftrace_events_bundle = packet.ftrace_events();
124 
125       if (ftrace_events_bundle.event_size() > 0) {
126         const FtraceEvent& ftrace_event = ftrace_events_bundle.event(0);
127         if (ftrace_event.has_print() && (ftrace_event.print().buf() == expected_print_buf)) {
128           found = true;
129           break;
130         }
131       }
132     }
133   }
134   EXPECT_TRUE(found);
135 }
136 
TEST_F_WITH_FLAGS(TracingPerfettoTest,traceInstantWithPerfetto,REQUIRES_FLAGS_ENABLED (PERFETTO_SDK_TRACING))137 TEST_F_WITH_FLAGS(TracingPerfettoTest, traceInstantWithPerfetto,
138                   REQUIRES_FLAGS_ENABLED(PERFETTO_SDK_TRACING)) {
139   std::string event_category = "input";
140   std::string event_name = "traceInstantWithPerfetto";
141 
142   TracingSession tracing_session =
143       TracingSession::Builder().add_enabled_category(event_category).Build();
144 
145   tracing_perfetto::traceInstant(TRACE_CATEGORY_INPUT, event_name.c_str());
146 
147   Trace trace = stopSession(tracing_session);
148 
149   verifyTrackEvent(trace, event_category, event_name);
150 }
151 
TEST_F_WITH_FLAGS(TracingPerfettoTest,traceInstantWithAtrace,REQUIRES_FLAGS_ENABLED (PERFETTO_SDK_TRACING))152 TEST_F_WITH_FLAGS(TracingPerfettoTest, traceInstantWithAtrace,
153                   REQUIRES_FLAGS_ENABLED(PERFETTO_SDK_TRACING)) {
154   std::string event_category = "input";
155   std::string event_name = "traceInstantWithAtrace";
156 
157   TracingSession tracing_session =
158       TracingSession::Builder().add_atrace_category(event_category).Build();
159 
160   tracing_perfetto::traceInstant(TRACE_CATEGORY_INPUT, event_name.c_str());
161 
162   Trace trace = stopSession(tracing_session);
163 
164   verifyAtraceEvent(trace, event_name);
165 }
166 
TEST_F_WITH_FLAGS(TracingPerfettoTest,traceInstantWithPerfettoAndAtrace,REQUIRES_FLAGS_ENABLED (PERFETTO_SDK_TRACING))167 TEST_F_WITH_FLAGS(TracingPerfettoTest, traceInstantWithPerfettoAndAtrace,
168                   REQUIRES_FLAGS_ENABLED(PERFETTO_SDK_TRACING)) {
169   std::string event_category = "input";
170   std::string event_name = "traceInstantWithPerfettoAndAtrace";
171 
172   TracingSession tracing_session =
173       TracingSession::Builder()
174       .add_atrace_category(event_category)
175       .add_enabled_category(event_category).Build();
176 
177   tracing_perfetto::traceInstant(TRACE_CATEGORY_INPUT, event_name.c_str());
178 
179   Trace trace = stopSession(tracing_session);
180 
181   verifyAtraceEvent(trace, event_name);
182 }
183 
TEST_F_WITH_FLAGS(TracingPerfettoTest,traceInstantWithPerfettoAndAtraceAndPreferTrackEvent,REQUIRES_FLAGS_ENABLED (PERFETTO_SDK_TRACING))184 TEST_F_WITH_FLAGS(TracingPerfettoTest, traceInstantWithPerfettoAndAtraceAndPreferTrackEvent,
185                   REQUIRES_FLAGS_ENABLED(PERFETTO_SDK_TRACING)) {
186   std::string event_category = "input";
187   std::string event_name = "traceInstantWithPerfettoAndAtraceAndPreferTrackEvent";
188 
189   TracingSession tracing_session =
190       TracingSession::Builder()
191       .add_atrace_category(event_category)
192       .add_atrace_category_prefer_sdk(event_category)
193       .add_enabled_category(event_category).Build();
194 
195   tracing_perfetto::traceInstant(TRACE_CATEGORY_INPUT, event_name.c_str());
196 
197   Trace trace = stopSession(tracing_session);
198 
199   verifyTrackEvent(trace, event_category, event_name);
200 }
201 
TEST_F_WITH_FLAGS(TracingPerfettoTest,traceInstantWithPerfettoAndAtraceConcurrently,REQUIRES_FLAGS_ENABLED (PERFETTO_SDK_TRACING))202 TEST_F_WITH_FLAGS(TracingPerfettoTest, traceInstantWithPerfettoAndAtraceConcurrently,
203                   REQUIRES_FLAGS_ENABLED(PERFETTO_SDK_TRACING)) {
204   std::string event_category = "input";
205   std::string event_name = "traceInstantWithPerfettoAndAtraceConcurrently";
206 
207   TracingSession perfetto_tracing_session =
208       TracingSession::Builder()
209       .add_atrace_category(event_category)
210       .add_atrace_category_prefer_sdk(event_category)
211       .add_enabled_category(event_category).Build();
212 
213   TracingSession atrace_tracing_session =
214       TracingSession::Builder()
215       .add_atrace_category(event_category)
216       .add_enabled_category(event_category).Build();
217 
218   tracing_perfetto::traceInstant(TRACE_CATEGORY_INPUT, event_name.c_str());
219 
220   Trace atrace_trace = stopSession(atrace_tracing_session);
221   Trace perfetto_trace = stopSession(perfetto_tracing_session);
222 
223   verifyAtraceEvent(atrace_trace, event_name);
224   verifyAtraceEvent(perfetto_trace, event_name);
225 }
226 }  // namespace tracing_perfetto
227