• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 <fcntl.h>
18 
19 #include <chrono>
20 #include <condition_variable>
21 #include <fstream>
22 #include <functional>
23 #include <list>
24 #include <mutex>
25 #include <regex>
26 #include <string_view>
27 #include <thread>
28 #include <unordered_set>
29 #include <vector>
30 
31 // We also want to test legacy trace events.
32 #define PERFETTO_ENABLE_LEGACY_TRACE_EVENTS 1
33 
34 #include "perfetto/tracing.h"
35 #include "test/gtest_and_gmock.h"
36 
37 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
38 #include <Windows.h>  // For CreateFile().
39 #else
40 #include <sys/socket.h>
41 #include <sys/types.h>
42 #include <sys/un.h>
43 #endif
44 
45 // Deliberately not pulling any non-public perfetto header to spot accidental
46 // header public -> non-public dependency while building this file.
47 
48 // These two are the only headers allowed here, see comments in
49 // api_test_support.h.
50 #include "src/tracing/test/api_test_support.h"
51 #include "src/tracing/test/tracing_module.h"
52 
53 #include "perfetto/base/time.h"
54 #include "perfetto/protozero/scattered_heap_buffer.h"
55 #include "perfetto/tracing/core/data_source_descriptor.h"
56 #include "perfetto/tracing/core/trace_config.h"
57 
58 // xxx.pbzero.h includes are for the writing path (the code that pretends to be
59 // production code).
60 // yyy.gen.h includes are for the test readback path (the code in the test that
61 // checks that the results are valid).
62 #include "protos/perfetto/common/builtin_clock.pbzero.h"
63 #include "protos/perfetto/common/interceptor_descriptor.gen.h"
64 #include "protos/perfetto/common/trace_stats.gen.h"
65 #include "protos/perfetto/common/tracing_service_state.gen.h"
66 #include "protos/perfetto/common/track_event_descriptor.gen.h"
67 #include "protos/perfetto/common/track_event_descriptor.pbzero.h"
68 #include "protos/perfetto/config/interceptor_config.gen.h"
69 #include "protos/perfetto/config/track_event/track_event_config.gen.h"
70 #include "protos/perfetto/trace/clock_snapshot.gen.h"
71 #include "protos/perfetto/trace/clock_snapshot.pbzero.h"
72 #include "protos/perfetto/trace/gpu/gpu_render_stage_event.gen.h"
73 #include "protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.h"
74 #include "protos/perfetto/trace/interned_data/interned_data.gen.h"
75 #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
76 #include "protos/perfetto/trace/profiling/profile_common.gen.h"
77 #include "protos/perfetto/trace/test_event.gen.h"
78 #include "protos/perfetto/trace/test_event.pbzero.h"
79 #include "protos/perfetto/trace/test_extensions.pbzero.h"
80 #include "protos/perfetto/trace/trace.gen.h"
81 #include "protos/perfetto/trace/trace.pbzero.h"
82 #include "protos/perfetto/trace/trace_packet.gen.h"
83 #include "protos/perfetto/trace/trace_packet.pbzero.h"
84 #include "protos/perfetto/trace/trace_packet_defaults.gen.h"
85 #include "protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h"
86 #include "protos/perfetto/trace/track_event/chrome_process_descriptor.pbzero.h"
87 #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
88 #include "protos/perfetto/trace/track_event/debug_annotation.gen.h"
89 #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
90 #include "protos/perfetto/trace/track_event/log_message.gen.h"
91 #include "protos/perfetto/trace/track_event/log_message.pbzero.h"
92 #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
93 #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
94 #include "protos/perfetto/trace/track_event/source_location.gen.h"
95 #include "protos/perfetto/trace/track_event/source_location.pbzero.h"
96 #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
97 #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
98 #include "protos/perfetto/trace/track_event/track_descriptor.gen.h"
99 #include "protos/perfetto/trace/track_event/track_event.gen.h"
100 #include "protos/perfetto/trace/trigger.gen.h"
101 
102 // Events in categories starting with "dynamic" will use dynamic category
103 // lookup.
104 PERFETTO_DEFINE_TEST_CATEGORY_PREFIXES("dynamic");
105 
106 // Trace categories used in the tests.
107 PERFETTO_DEFINE_CATEGORIES(
108     perfetto::Category("test")
109         .SetDescription("This is a test category")
110         .SetTags("tag"),
111     perfetto::Category("foo"),
112     perfetto::Category("bar"),
113     perfetto::Category("cat").SetTags("slow"),
114     perfetto::Category("cat.verbose").SetTags("debug"),
115     perfetto::Category("cat-with-dashes"),
116     perfetto::Category::Group("foo,bar"),
117     perfetto::Category::Group("baz,bar,quux"),
118     perfetto::Category::Group("red,green,blue,foo"),
119     perfetto::Category::Group("red,green,blue,yellow"),
120     perfetto::Category(TRACE_DISABLED_BY_DEFAULT("cat")));
121 PERFETTO_TRACK_EVENT_STATIC_STORAGE();
122 
123 // Test declaring an extra set of categories in a namespace in addition to the
124 // default one.
125 PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE(other_ns,
126                                         perfetto::Category("other_ns"));
127 PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE(other_ns);
128 
129 // For testing interning of complex objects.
130 using SourceLocation = std::tuple<const char* /* file_name */,
131                                   const char* /* function_name */,
132                                   uint32_t /* line_number */>;
133 
134 template <>
135 struct std::hash<SourceLocation> {
operator ()std::hash136   size_t operator()(const SourceLocation& value) const {
137     auto hasher = hash<size_t>();
138     return hasher(reinterpret_cast<size_t>(get<0>(value))) ^
139            hasher(reinterpret_cast<size_t>(get<1>(value))) ^
140            hasher(get<2>(value));
141   }
142 };
143 
WriteFile(const std::string & file_name,const char * content,size_t len)144 static void WriteFile(const std::string& file_name,
145                       const char* content,
146                       size_t len) {
147   std::ofstream output;
148   output.open(file_name.c_str(), std::ios::out | std::ios::binary);
149   output.write(content, static_cast<std::streamsize>(len));
150   output.close();
151 }
152 
153 // Unused in merged code, but very handy for debugging when trace generated in
154 // a test needs to be exported, to understand it further with other tools.
WriteFile(const std::string & file_name,const std::vector<char> & data)155 PERFETTO_UNUSED static void WriteFile(const std::string& file_name,
156                                       const std::vector<char>& data) {
157   return WriteFile(file_name, data.data(), data.size());
158 }
159 
160 // Returns true if the |key| is present in |container|.
161 template <typename ContainerType, class KeyType>
ContainsKey(const ContainerType & container,const KeyType & key)162 bool ContainsKey(const ContainerType& container, const KeyType& key) {
163   return container.find(key) != container.end();
164 }
165 
166 // Represents an opaque (from Perfetto's point of view) thread identifier (e.g.,
167 // base::PlatformThreadId in Chromium).
168 struct MyThreadId {
MyThreadIdMyThreadId169   explicit MyThreadId(int tid_) : tid(tid_) {}
170 
171   const int tid = 0;
172 };
173 
174 // Represents an opaque timestamp (e.g., base::TimeTicks in Chromium).
175 class MyTimestamp {
176  public:
MyTimestamp(uint64_t ts_)177   explicit MyTimestamp(uint64_t ts_) : ts(ts_) {}
178 
179   const uint64_t ts;
180 };
181 
182 namespace perfetto {
183 namespace legacy {
184 
185 template <>
ConvertThreadId(const MyThreadId & thread)186 ThreadTrack ConvertThreadId(const MyThreadId& thread) {
187   return perfetto::ThreadTrack::ForThread(
188       static_cast<base::PlatformThreadId>(thread.tid));
189 }
190 
191 }  // namespace legacy
192 
193 template <>
194 struct TraceTimestampTraits<MyTimestamp> {
ConvertTimestampToTraceTimeNsperfetto::TraceTimestampTraits195   static TraceTimestamp ConvertTimestampToTraceTimeNs(
196       const MyTimestamp& timestamp) {
197     return {static_cast<uint32_t>(TrackEvent::GetTraceClockId()), timestamp.ts};
198   }
199 };
200 
201 }  // namespace perfetto
202 
203 namespace {
204 
205 using perfetto::TracingInitArgs;
206 using perfetto::internal::TrackEventIncrementalState;
207 using perfetto::internal::TrackEventInternal;
208 using ::perfetto::test::DataSourceInternalForTest;
209 using ::testing::_;
210 using ::testing::AllOf;
211 using ::testing::ContainerEq;
212 using ::testing::Contains;
213 using ::testing::Each;
214 using ::testing::ElementsAre;
215 using ::testing::HasSubstr;
216 using ::testing::Invoke;
217 using ::testing::InvokeWithoutArgs;
218 using ::testing::IsEmpty;
219 using ::testing::NiceMock;
220 using ::testing::Not;
221 using ::testing::Property;
222 using ::testing::StrEq;
223 
224 // ------------------------------
225 // Declarations of helper classes
226 // ------------------------------
227 
228 class WaitableTestEvent {
229  public:
notified()230   bool notified() {
231     std::unique_lock<std::mutex> lock(mutex_);
232     return notified_;
233   }
234 
Wait()235   void Wait() {
236     std::unique_lock<std::mutex> lock(mutex_);
237     // TSAN gets confused by wait_for, which we would use here in a perfect
238     // world.
239     cv_.wait(lock, [this] { return notified_; });
240   }
241 
Notify()242   void Notify() {
243     std::lock_guard<std::mutex> lock(mutex_);
244     notified_ = true;
245     cv_.notify_one();
246   }
247 
248  private:
249   std::mutex mutex_;
250   std::condition_variable cv_;
251   bool notified_ = false;
252 };
253 
254 template <typename Func>
255 class Cleanup {
256  public:
Cleanup(Func f)257   explicit Cleanup(Func f) : f_(std::move(f)) {}
~Cleanup()258   ~Cleanup() { f_(); }
259   Cleanup(Cleanup&&) noexcept = default;
260   Cleanup& operator=(Cleanup&&) noexcept = default;
261   Cleanup(const Cleanup&) = delete;
262   Cleanup& operator=(const Cleanup&) = delete;
263 
264  private:
265   Func f_;
266 };
267 template <typename Func>
MakeCleanup(Func f)268 Cleanup<Func> MakeCleanup(Func f) {
269   return Cleanup<Func>(std::move(f));
270 }
271 
272 class CustomDataSource : public perfetto::DataSource<CustomDataSource> {};
273 
274 class MockDataSource;
275 
276 // We can't easily use gmock here because instances of data sources are lazily
277 // created by the service and are not owned by the test fixture.
278 struct TestDataSourceHandle {
279   WaitableTestEvent on_create;
280   WaitableTestEvent on_setup;
281   WaitableTestEvent on_start;
282   WaitableTestEvent on_stop;
283   WaitableTestEvent on_flush;
284   MockDataSource* instance;
285   perfetto::DataSourceConfig config;
286   bool is_datasource_started = false;
287   bool handle_stop_asynchronously = false;
288   bool handle_flush_asynchronously = false;
289   std::function<void()> on_start_callback;
290   std::function<void()> on_stop_callback;
291   std::function<void(perfetto::FlushFlags)> on_flush_callback;
292   std::function<void()> async_stop_closure;
293   std::function<void()> async_flush_closure;
294 };
295 
296 class MockDataSource : public perfetto::DataSource<MockDataSource> {
297  public:
298   void OnSetup(const SetupArgs&) override;
299   void OnStart(const StartArgs&) override;
300   void OnStop(const StopArgs&) override;
301   void OnFlush(const FlushArgs&) override;
302   TestDataSourceHandle* handle_ = nullptr;
303 };
304 
305 constexpr int kTestDataSourceArg = 123;
306 
307 class MockDataSource2 : public perfetto::DataSource<MockDataSource2> {
308  public:
MockDataSource2(int arg)309   MockDataSource2(int arg) { EXPECT_EQ(arg, kTestDataSourceArg); }
OnSetup(const SetupArgs &)310   void OnSetup(const SetupArgs&) override {}
OnStart(const StartArgs &)311   void OnStart(const StartArgs&) override {}
OnStop(const StopArgs &)312   void OnStop(const StopArgs&) override {}
313 };
314 
315 // Used to verify that track event data sources in different namespaces register
316 // themselves correctly in the muxer.
317 class MockTracingMuxer : public perfetto::internal::TracingMuxer {
318  public:
319   struct DataSource {
320     perfetto::DataSourceDescriptor dsd;
321     perfetto::internal::DataSourceStaticState* static_state;
322   };
323 
MockTracingMuxer()324   MockTracingMuxer() : TracingMuxer(nullptr), prev_instance_(instance_) {
325     instance_ = this;
326   }
~MockTracingMuxer()327   ~MockTracingMuxer() override { instance_ = prev_instance_; }
328 
RegisterDataSource(const perfetto::DataSourceDescriptor & dsd,DataSourceFactory,perfetto::internal::DataSourceParams,bool,perfetto::internal::DataSourceStaticState * static_state)329   bool RegisterDataSource(
330       const perfetto::DataSourceDescriptor& dsd,
331       DataSourceFactory,
332       perfetto::internal::DataSourceParams,
333       bool,
334       perfetto::internal::DataSourceStaticState* static_state) override {
335     data_sources.emplace_back(DataSource{dsd, static_state});
336     return true;
337   }
338 
UpdateDataSourceDescriptor(const perfetto::DataSourceDescriptor & dsd,const perfetto::internal::DataSourceStaticState * static_state)339   void UpdateDataSourceDescriptor(
340       const perfetto::DataSourceDescriptor& dsd,
341       const perfetto::internal::DataSourceStaticState* static_state) override {
342     for (auto& rds : data_sources) {
343       if (rds.static_state == static_state) {
344         rds.dsd = dsd;
345         return;
346       }
347     }
348   }
349 
CreateTraceWriter(perfetto::internal::DataSourceStaticState *,uint32_t,perfetto::internal::DataSourceState *,perfetto::BufferExhaustedPolicy)350   std::unique_ptr<perfetto::TraceWriterBase> CreateTraceWriter(
351       perfetto::internal::DataSourceStaticState*,
352       uint32_t,
353       perfetto::internal::DataSourceState*,
354       perfetto::BufferExhaustedPolicy) override {
355     return nullptr;
356   }
357 
DestroyStoppedTraceWritersForCurrentThread()358   void DestroyStoppedTraceWritersForCurrentThread() override {}
RegisterInterceptor(const perfetto::InterceptorDescriptor &,InterceptorFactory,perfetto::InterceptorBase::TLSFactory,perfetto::InterceptorBase::TracePacketCallback)359   void RegisterInterceptor(
360       const perfetto::InterceptorDescriptor&,
361       InterceptorFactory,
362       perfetto::InterceptorBase::TLSFactory,
363       perfetto::InterceptorBase::TracePacketCallback) override {}
364 
ActivateTriggers(const std::vector<std::string> &,uint32_t)365   void ActivateTriggers(const std::vector<std::string>&, uint32_t) override {}
366 
367   std::vector<DataSource> data_sources;
368 
369  private:
370   TracingMuxer* prev_instance_;
371 };
372 
373 struct TestIncrementalState {
TestIncrementalState__anon1b44a82b0111::TestIncrementalState374   TestIncrementalState() { constructed = true; }
375   // Note: a virtual destructor is not required for incremental state.
~TestIncrementalState__anon1b44a82b0111::TestIncrementalState376   ~TestIncrementalState() { destroyed = true; }
377 
378   int count = 100;
379   bool flag = false;
380   static bool constructed;
381   static bool destroyed;
382 };
383 
384 bool TestIncrementalState::constructed;
385 bool TestIncrementalState::destroyed;
386 
387 struct TestIncrementalDataSourceTraits
388     : public perfetto::DefaultDataSourceTraits {
389   using IncrementalStateType = TestIncrementalState;
390   using CustomTlsState = void;
391 };
392 
393 class TestIncrementalDataSource
394     : public perfetto::DataSource<TestIncrementalDataSource,
395                                   TestIncrementalDataSourceTraits> {
396  public:
OnSetup(const SetupArgs &)397   void OnSetup(const SetupArgs&) override {}
OnStart(const StartArgs &)398   void OnStart(const StartArgs&) override {}
OnStop(const StopArgs &)399   void OnStop(const StopArgs&) override {}
400 };
401 
402 // A convenience wrapper around TracingSession that allows to do block on
403 //
404 struct TestTracingSessionHandle {
get__anon1b44a82b0111::TestTracingSessionHandle405   perfetto::TracingSession* get() { return session.get(); }
406   std::unique_ptr<perfetto::TracingSession> session;
407   WaitableTestEvent on_stop;
408 };
409 
410 class MyDebugAnnotation : public perfetto::DebugAnnotation {
411  public:
412   ~MyDebugAnnotation() override = default;
413 
Add(perfetto::protos::pbzero::DebugAnnotation * annotation) const414   void Add(
415       perfetto::protos::pbzero::DebugAnnotation* annotation) const override {
416     annotation->set_legacy_json_value(R"({"key": 123})");
417   }
418 };
419 
420 class TestTracingPolicy : public perfetto::TracingPolicy {
421  public:
ShouldAllowConsumerSession(const ShouldAllowConsumerSessionArgs & args)422   void ShouldAllowConsumerSession(
423       const ShouldAllowConsumerSessionArgs& args) override {
424     EXPECT_NE(args.backend_type, perfetto::BackendType::kUnspecifiedBackend);
425     args.result_callback(should_allow_consumer_connection);
426   }
427 
428   bool should_allow_consumer_connection = true;
429 };
430 
431 TestTracingPolicy* g_test_tracing_policy = new TestTracingPolicy();  // Leaked.
432 
433 class ParsedIncrementalState {
434  public:
ClearIfNeeded(const perfetto::protos::gen::TracePacket & packet)435   void ClearIfNeeded(const perfetto::protos::gen::TracePacket& packet) {
436     if (packet.sequence_flags() &
437         perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED) {
438       incremental_state_was_cleared_ = true;
439       categories_.clear();
440       event_names_.clear();
441       debug_annotation_names_.clear();
442       seen_tracks_.clear();
443     }
444   }
445 
Parse(const perfetto::protos::gen::TracePacket & packet)446   void Parse(const perfetto::protos::gen::TracePacket& packet) {
447     // Update incremental state.
448     if (packet.has_interned_data()) {
449       const auto& interned_data = packet.interned_data();
450       for (const auto& it : interned_data.event_categories()) {
451         EXPECT_EQ(categories_.find(it.iid()), categories_.end());
452         categories_[it.iid()] = it.name();
453       }
454       for (const auto& it : interned_data.event_names()) {
455         EXPECT_EQ(event_names_.find(it.iid()), event_names_.end());
456         event_names_[it.iid()] = it.name();
457       }
458       for (const auto& it : interned_data.debug_annotation_names()) {
459         EXPECT_EQ(debug_annotation_names_.find(it.iid()),
460                   debug_annotation_names_.end());
461         debug_annotation_names_[it.iid()] = it.name();
462       }
463     }
464   }
465 
HasSeenTrack(uint64_t uuid) const466   bool HasSeenTrack(uint64_t uuid) const {
467     return seen_tracks_.count(uuid) != 0;
468   }
469 
InsertTrack(uint64_t uuid)470   void InsertTrack(uint64_t uuid) { seen_tracks_.insert(uuid); }
471 
GetCategory(uint64_t iid)472   std::string GetCategory(uint64_t iid) { return categories_[iid]; }
473 
GetEventName(const perfetto::protos::gen::TrackEvent & event)474   std::string GetEventName(const perfetto::protos::gen::TrackEvent& event) {
475     if (event.has_name_iid())
476       return event_names_[event.name_iid()];
477     return event.name();
478   }
479 
GetDebugAnnotationName(uint64_t iid)480   std::string GetDebugAnnotationName(uint64_t iid) {
481     return debug_annotation_names_[iid];
482   }
483 
WasCleared() const484   bool WasCleared() const { return incremental_state_was_cleared_; }
485 
486  private:
487   bool incremental_state_was_cleared_ = false;
488   std::map<uint64_t, std::string> categories_;
489   std::map<uint64_t, std::string> event_names_;
490   std::map<uint64_t, std::string> debug_annotation_names_;
491   std::set<uint64_t> seen_tracks_;
492 };
493 
ReadSlicesFromTrace(const perfetto::protos::gen::Trace & parsed_trace,bool expect_incremental_state_cleared=true)494 std::vector<std::string> ReadSlicesFromTrace(
495     const perfetto::protos::gen::Trace& parsed_trace,
496     bool expect_incremental_state_cleared = true) {
497   // Read back the trace, maintaining interning tables as we go.
498   std::vector<std::string> slices;
499   if (parsed_trace.packet().size() == 0)
500     return slices;
501   ParsedIncrementalState incremental_state;
502 
503   uint32_t sequence_id = 0;
504   for (const auto& packet : parsed_trace.packet()) {
505     incremental_state.ClearIfNeeded(packet);
506 
507     if (packet.has_track_descriptor()) {
508       // Make sure we haven't seen any events on this track before the
509       // descriptor was written.
510       EXPECT_FALSE(
511           incremental_state.HasSeenTrack(packet.track_descriptor().uuid()));
512     }
513 
514     if (!packet.has_track_event())
515       continue;
516 
517     // Make sure we only see track events on one sequence.
518     if (packet.trusted_packet_sequence_id()) {
519       if (!sequence_id)
520         sequence_id = packet.trusted_packet_sequence_id();
521       EXPECT_EQ(sequence_id, packet.trusted_packet_sequence_id());
522     }
523 
524     incremental_state.Parse(packet);
525 
526     const auto& track_event = packet.track_event();
527     std::string slice;
528 
529     if (track_event.has_track_uuid()) {
530       incremental_state.InsertTrack(track_event.track_uuid());
531       std::stringstream track;
532       track << "[track=" << track_event.track_uuid() << "]";
533       slice += track.str();
534     }
535 
536     switch (track_event.type()) {
537       case perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN:
538         slice += "B";
539         break;
540       case perfetto::protos::gen::TrackEvent::TYPE_SLICE_END:
541         slice += "E";
542         break;
543       case perfetto::protos::gen::TrackEvent::TYPE_INSTANT:
544         slice += "I";
545         break;
546       case perfetto::protos::gen::TrackEvent::TYPE_UNSPECIFIED: {
547         EXPECT_TRUE(track_event.has_legacy_event());
548         EXPECT_FALSE(track_event.type());
549         auto legacy_event = track_event.legacy_event();
550         slice +=
551             "Legacy_" + std::string(1, static_cast<char>(legacy_event.phase()));
552         break;
553       }
554       case perfetto::protos::gen::TrackEvent::TYPE_COUNTER:
555         slice += "C";
556         break;
557       default:
558         ADD_FAILURE();
559     }
560     if (track_event.has_legacy_event()) {
561       auto legacy_event = track_event.legacy_event();
562       std::stringstream id;
563       if (legacy_event.has_unscoped_id()) {
564         id << "(unscoped_id=" << legacy_event.unscoped_id() << ")";
565       } else if (legacy_event.has_local_id()) {
566         id << "(local_id=" << legacy_event.local_id() << ")";
567       } else if (legacy_event.has_global_id()) {
568         id << "(global_id=" << legacy_event.global_id() << ")";
569       } else if (legacy_event.has_bind_id()) {
570         id << "(bind_id=" << legacy_event.bind_id() << ")";
571       }
572       if (legacy_event.has_id_scope())
573         id << "(id_scope=\"" << legacy_event.id_scope() << "\")";
574       if (legacy_event.use_async_tts())
575         id << "(use_async_tts)";
576       if (legacy_event.bind_to_enclosing())
577         id << "(bind_to_enclosing)";
578       if (legacy_event.has_flow_direction())
579         id << "(flow_direction=" << legacy_event.flow_direction() << ")";
580       if (legacy_event.has_pid_override())
581         id << "(pid_override=" << legacy_event.pid_override() << ")";
582       if (legacy_event.has_tid_override())
583         id << "(tid_override=" << legacy_event.tid_override() << ")";
584       slice += id.str();
585     }
586     size_t category_count = 0;
587     for (const auto& it : track_event.category_iids())
588       slice +=
589           (category_count++ ? "," : ":") + incremental_state.GetCategory(it);
590     for (const auto& it : track_event.categories())
591       slice += (category_count++ ? ",$" : ":$") + it;
592     if (track_event.has_name() || track_event.has_name_iid())
593       slice += "." + incremental_state.GetEventName(track_event);
594 
595     if (track_event.debug_annotations_size()) {
596       slice += "(";
597       bool first_annotation = true;
598       for (const auto& it : track_event.debug_annotations()) {
599         if (!first_annotation) {
600           slice += ",";
601         }
602         if (it.has_name_iid()) {
603           slice += incremental_state.GetDebugAnnotationName(it.name_iid());
604         } else {
605           slice += it.name();
606         }
607         slice += "=";
608         std::stringstream value;
609         if (it.has_bool_value()) {
610           value << "(bool)" << it.bool_value();
611         } else if (it.has_uint_value()) {
612           value << "(uint)" << it.uint_value();
613         } else if (it.has_int_value()) {
614           value << "(int)" << it.int_value();
615         } else if (it.has_double_value()) {
616           value << "(double)" << it.double_value();
617         } else if (it.has_string_value()) {
618           value << "(string)" << it.string_value();
619         } else if (it.has_pointer_value()) {
620           value << "(pointer)" << std::hex << it.pointer_value();
621         } else if (it.has_legacy_json_value()) {
622           value << "(json)" << it.legacy_json_value();
623         } else if (it.has_nested_value()) {
624           value << "(nested)" << it.nested_value().string_value();
625         }
626         slice += value.str();
627         first_annotation = false;
628       }
629       slice += ")";
630     }
631 
632     if (track_event.flow_ids_old_size()) {
633       slice += "(flow_ids_old=";
634       std::stringstream value;
635       bool first_annotation = true;
636       for (uint64_t id : track_event.flow_ids_old()) {
637         if (!first_annotation) {
638           value << ",";
639         }
640         first_annotation = false;
641         value << id;
642       }
643       slice += value.str() + ")";
644     }
645 
646     if (track_event.flow_ids_size()) {
647       slice += "(flow_ids=";
648       std::stringstream value;
649       bool first_annotation = true;
650       for (uint64_t id : track_event.flow_ids()) {
651         if (!first_annotation) {
652           value << ",";
653         }
654         first_annotation = false;
655         value << id;
656       }
657       slice += value.str() + ")";
658     }
659 
660     if (track_event.terminating_flow_ids_old_size()) {
661       slice += "(terminating_flow_ids_old=";
662       std::stringstream value;
663       bool first_annotation = true;
664       for (uint64_t id : track_event.terminating_flow_ids_old()) {
665         if (!first_annotation) {
666           value << ",";
667         }
668         value << id;
669         first_annotation = false;
670       }
671       slice += value.str() + ")";
672     }
673 
674     if (track_event.terminating_flow_ids_size()) {
675       slice += "(terminating_flow_ids=";
676       std::stringstream value;
677       bool first_annotation = true;
678       for (uint64_t id : track_event.terminating_flow_ids()) {
679         if (!first_annotation) {
680           value << ",";
681         }
682         value << id;
683         first_annotation = false;
684       }
685       slice += value.str() + ")";
686     }
687 
688     slices.push_back(slice);
689   }
690   if (expect_incremental_state_cleared) {
691     EXPECT_TRUE(incremental_state.WasCleared());
692   }
693   return slices;
694 }
695 
ReadSlicesFromTrace(const std::vector<char> & raw_trace,bool expect_incremental_state_cleared=true)696 std::vector<std::string> ReadSlicesFromTrace(
697     const std::vector<char>& raw_trace,
698     bool expect_incremental_state_cleared = true) {
699   EXPECT_GE(raw_trace.size(), 0u);
700 
701   perfetto::protos::gen::Trace parsed_trace;
702   EXPECT_TRUE(parsed_trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
703   return ReadSlicesFromTrace(parsed_trace, expect_incremental_state_cleared);
704 }
705 
WaitForOneProducerConnected(perfetto::TracingSession * session)706 bool WaitForOneProducerConnected(perfetto::TracingSession* session) {
707   for (size_t i = 0; i < 100; i++) {
708     // Blocking read.
709     auto result = session->QueryServiceStateBlocking();
710     perfetto::protos::gen::TracingServiceState state;
711     EXPECT_TRUE(result.success);
712     EXPECT_TRUE(state.ParseFromArray(result.service_state_data.data(),
713                                      result.service_state_data.size()));
714     // The producer has connected to the new restarted system service.
715     if (state.producers().size() == 1) {
716       return true;
717     }
718     std::this_thread::sleep_for(std::chrono::milliseconds(100));
719   }
720   ADD_FAILURE() << "Producer not connected";
721   return false;
722 }
723 
724 // -------------------------
725 // Declaration of test class
726 // -------------------------
727 class PerfettoApiTest : public ::testing::TestWithParam<perfetto::BackendType> {
728  public:
729   static PerfettoApiTest* instance;
730 
SetUp()731   void SetUp() override {
732     instance = this;
733     g_test_tracing_policy->should_allow_consumer_connection = true;
734 
735     // Start a fresh system service for this test, tearing down any previous
736     // service that was running.
737     if (GetParam() == perfetto::kSystemBackend) {
738       system_service_ = perfetto::test::SystemService::Start();
739       // If the system backend isn't supported, skip all system backend tests.
740       if (!system_service_.valid()) {
741         GTEST_SKIP();
742       }
743     }
744 
745     EXPECT_FALSE(perfetto::Tracing::IsInitialized());
746     TracingInitArgs args;
747     args.backends = GetParam();
748     args.tracing_policy = g_test_tracing_policy;
749     perfetto::Tracing::Initialize(args);
750     RegisterDataSource<MockDataSource>("my_data_source");
751     {
752       perfetto::DataSourceDescriptor dsd;
753       dsd.set_name("CustomDataSource");
754       CustomDataSource::Register(dsd);
755     }
756     perfetto::TrackEvent::Register();
757 
758     // Make sure our data source always has a valid handle.
759     data_sources_["my_data_source"];
760 
761     // If this wasn't the first test to run in this process, any producers
762     // connected to the old system service will have been disconnected by the
763     // service restarting above. Wait for all producers to connect again before
764     // proceeding with the test.
765     perfetto::test::SyncProducers();
766 
767     perfetto::test::DisableReconnectLimit();
768   }
769 
TearDown()770   void TearDown() override {
771     instance = nullptr;
772     sessions_.clear();
773     perfetto::test::TracingMuxerImplInternalsForTest::
774         ClearDataSourceTlsStateOnReset<MockDataSource>();
775     perfetto::test::TracingMuxerImplInternalsForTest::
776         ClearDataSourceTlsStateOnReset<CustomDataSource>();
777     perfetto::test::TracingMuxerImplInternalsForTest::
778         ClearDataSourceTlsStateOnReset<perfetto::TrackEvent>();
779     perfetto::Tracing::ResetForTesting();
780   }
781 
782   template <typename DerivedDataSource>
RegisterDataSource(std::string name)783   TestDataSourceHandle* RegisterDataSource(std::string name) {
784     perfetto::DataSourceDescriptor dsd;
785     dsd.set_name(name);
786     return RegisterDataSource<DerivedDataSource>(dsd);
787   }
788 
789   template <typename DerivedDataSource>
RegisterDataSource(const perfetto::DataSourceDescriptor & dsd)790   TestDataSourceHandle* RegisterDataSource(
791       const perfetto::DataSourceDescriptor& dsd) {
792     EXPECT_EQ(data_sources_.count(dsd.name()), 0u);
793     TestDataSourceHandle* handle = &data_sources_[dsd.name()];
794     DerivedDataSource::Register(dsd);
795     return handle;
796   }
797 
798   template <typename DerivedDataSource>
UpdateDataSource(const perfetto::DataSourceDescriptor & dsd)799   TestDataSourceHandle* UpdateDataSource(
800       const perfetto::DataSourceDescriptor& dsd) {
801     EXPECT_EQ(data_sources_.count(dsd.name()), 1u);
802     TestDataSourceHandle* handle = &data_sources_[dsd.name()];
803     DerivedDataSource::UpdateDescriptor(dsd);
804     return handle;
805   }
806 
NewTrace(const perfetto::TraceConfig & cfg,int fd=-1)807   TestTracingSessionHandle* NewTrace(const perfetto::TraceConfig& cfg,
808                                      int fd = -1) {
809     return NewTrace(cfg, /*backend_type=*/GetParam(), fd);
810   }
811 
NewTrace(const perfetto::TraceConfig & cfg,perfetto::BackendType backend_type,int fd=-1)812   TestTracingSessionHandle* NewTrace(const perfetto::TraceConfig& cfg,
813                                      perfetto::BackendType backend_type,
814                                      int fd = -1) {
815     sessions_.emplace_back();
816     TestTracingSessionHandle* handle = &sessions_.back();
817     handle->session = perfetto::Tracing::NewTrace(backend_type);
818     handle->session->SetOnStopCallback([handle] { handle->on_stop.Notify(); });
819     handle->session->Setup(cfg, fd);
820     return handle;
821   }
822 
NewTraceWithCategories(std::vector<std::string> categories,perfetto::protos::gen::TrackEventConfig te_cfg={},perfetto::TraceConfig cfg={})823   TestTracingSessionHandle* NewTraceWithCategories(
824       std::vector<std::string> categories,
825       perfetto::protos::gen::TrackEventConfig te_cfg = {},
826       perfetto::TraceConfig cfg = {}) {
827     cfg.set_duration_ms(500);
828     cfg.add_buffers()->set_size_kb(1024);
829     auto* ds_cfg = cfg.add_data_sources()->mutable_config();
830     ds_cfg->set_name("track_event");
831     te_cfg.add_disabled_categories("*");
832     for (const auto& category : categories)
833       te_cfg.add_enabled_categories(category);
834     ds_cfg->set_track_event_config_raw(te_cfg.SerializeAsString());
835 
836     return NewTrace(cfg);
837   }
838 
ReadLogMessagesFromTrace(perfetto::TracingSession * tracing_session)839   std::vector<std::string> ReadLogMessagesFromTrace(
840       perfetto::TracingSession* tracing_session) {
841     std::vector<char> raw_trace = tracing_session->ReadTraceBlocking();
842     EXPECT_GE(raw_trace.size(), 0u);
843 
844     // Read back the trace, maintaining interning tables as we go.
845     std::vector<std::string> log_messages;
846     std::map<uint64_t, std::string> log_message_bodies;
847     std::map<uint64_t, perfetto::protos::gen::SourceLocation> source_locations;
848     perfetto::protos::gen::Trace parsed_trace;
849     EXPECT_TRUE(
850         parsed_trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
851 
852     for (const auto& packet : parsed_trace.packet()) {
853       if (!packet.has_track_event())
854         continue;
855 
856       if (packet.has_interned_data()) {
857         const auto& interned_data = packet.interned_data();
858         for (const auto& it : interned_data.log_message_body()) {
859           EXPECT_GE(it.iid(), 1u);
860           EXPECT_EQ(log_message_bodies.find(it.iid()),
861                     log_message_bodies.end());
862           log_message_bodies[it.iid()] = it.body();
863         }
864         for (const auto& it : interned_data.source_locations()) {
865           EXPECT_GE(it.iid(), 1u);
866           EXPECT_EQ(source_locations.find(it.iid()), source_locations.end());
867           source_locations[it.iid()] = it;
868         }
869       }
870       const auto& track_event = packet.track_event();
871       if (track_event.type() !=
872           perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN)
873         continue;
874 
875       EXPECT_TRUE(track_event.has_log_message());
876       const auto& log = track_event.log_message();
877       if (log.source_location_iid()) {
878         std::stringstream msg;
879         const auto& source_location =
880             source_locations[log.source_location_iid()];
881         msg << source_location.function_name() << "("
882             << source_location.file_name() << ":"
883             << source_location.line_number()
884             << "): " << log_message_bodies[log.body_iid()];
885         log_messages.emplace_back(msg.str());
886       } else {
887         log_messages.emplace_back(log_message_bodies[log.body_iid()]);
888       }
889     }
890     return log_messages;
891   }
892 
ReadSlicesFromTraceSession(perfetto::TracingSession * tracing_session)893   std::vector<std::string> ReadSlicesFromTraceSession(
894       perfetto::TracingSession* tracing_session) {
895     return ReadSlicesFromTrace(tracing_session->ReadTraceBlocking());
896   }
897 
StopSessionAndReadSlicesFromTrace(TestTracingSessionHandle * tracing_session)898   std::vector<std::string> StopSessionAndReadSlicesFromTrace(
899       TestTracingSessionHandle* tracing_session) {
900     return ReadSlicesFromTrace(StopSessionAndReturnBytes(tracing_session));
901   }
902 
GetMainThreadPacketSequenceId(const perfetto::protos::gen::Trace & trace)903   uint32_t GetMainThreadPacketSequenceId(
904       const perfetto::protos::gen::Trace& trace) {
905     for (const auto& packet : trace.packet()) {
906       if (packet.has_track_descriptor() &&
907           packet.track_descriptor().thread().tid() ==
908               static_cast<int32_t>(perfetto::base::GetThreadId())) {
909         return packet.trusted_packet_sequence_id();
910       }
911     }
912     ADD_FAILURE() << "Main thread not found";
913     return 0;
914   }
915 
StopSessionAndReturnBytes(TestTracingSessionHandle * tracing_session)916   static std::vector<char> StopSessionAndReturnBytes(
917       TestTracingSessionHandle* tracing_session) {
918     perfetto::TrackEvent::Flush();
919     tracing_session->get()->StopBlocking();
920     return tracing_session->get()->ReadTraceBlocking();
921   }
922 
StopSessionAndReturnParsedTrace(TestTracingSessionHandle * tracing_session)923   static perfetto::protos::gen::Trace StopSessionAndReturnParsedTrace(
924       TestTracingSessionHandle* tracing_session) {
925     std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
926     perfetto::protos::gen::Trace trace;
927     if (trace.ParseFromArray(raw_trace.data(), raw_trace.size())) {
928       return trace;
929     } else {
930       ADD_FAILURE() << "trace.ParseFromArray failed";
931       return perfetto::protos::gen::Trace();
932     }
933   }
934 
935   perfetto::test::SystemService system_service_;
936   std::map<std::string, TestDataSourceHandle> data_sources_;
937   std::list<TestTracingSessionHandle> sessions_;  // Needs stable pointers.
938 };
939 
940 // ---------------------------------------------
941 // Definitions for non-inlineable helper methods
942 // ---------------------------------------------
943 PerfettoApiTest* PerfettoApiTest::instance;
944 
OnSetup(const SetupArgs & args)945 void MockDataSource::OnSetup(const SetupArgs& args) {
946   EXPECT_EQ(handle_, nullptr);
947   auto it = PerfettoApiTest::instance->data_sources_.find(args.config->name());
948 
949   // We should not see an OnSetup for a data source that we didn't register
950   // before via PerfettoApiTest::RegisterDataSource().
951   EXPECT_NE(it, PerfettoApiTest::instance->data_sources_.end());
952   handle_ = &it->second;
953   handle_->config = *args.config;  // Deliberate copy.
954   handle_->on_setup.Notify();
955 }
956 
OnStart(const StartArgs &)957 void MockDataSource::OnStart(const StartArgs&) {
958   EXPECT_NE(handle_, nullptr);
959   EXPECT_FALSE(handle_->is_datasource_started);
960   handle_->is_datasource_started = true;
961   if (handle_->on_start_callback)
962     handle_->on_start_callback();
963   handle_->on_start.Notify();
964 }
965 
OnStop(const StopArgs & args)966 void MockDataSource::OnStop(const StopArgs& args) {
967   EXPECT_NE(handle_, nullptr);
968   EXPECT_TRUE(handle_->is_datasource_started);
969   handle_->is_datasource_started = false;
970   if (handle_->handle_stop_asynchronously)
971     handle_->async_stop_closure = args.HandleStopAsynchronously();
972   if (handle_->on_stop_callback)
973     handle_->on_stop_callback();
974   handle_->on_stop.Notify();
975 }
976 
OnFlush(const FlushArgs & args)977 void MockDataSource::OnFlush(const FlushArgs& args) {
978   EXPECT_NE(handle_, nullptr);
979   EXPECT_TRUE(handle_->is_datasource_started);
980   if (handle_->handle_flush_asynchronously)
981     handle_->async_flush_closure = args.HandleFlushAsynchronously();
982   if (handle_->on_flush_callback) {
983     handle_->on_flush_callback(args.flush_flags);
984   }
985   handle_->on_flush.Notify();
986 }
987 
988 // -------------
989 // Test fixtures
990 // -------------
991 
TEST_P(PerfettoApiTest,StartAndStopWithoutDataSources)992 TEST_P(PerfettoApiTest, StartAndStopWithoutDataSources) {
993   // Create a new trace session without any data sources configured.
994   perfetto::TraceConfig cfg;
995   cfg.add_buffers()->set_size_kb(1024);
996   auto* tracing_session = NewTrace(cfg);
997   // This should not timeout.
998   tracing_session->get()->StartBlocking();
999   tracing_session->get()->StopBlocking();
1000 }
1001 
1002 // Disabled by default because it leaks tracing sessions into subsequent tests,
1003 // which can result in the per-uid tracing session limit (5) to be hit in later
1004 // tests.
1005 // TODO(b/261493947): fix or remove.
TEST_P(PerfettoApiTest,DISABLED_TrackEventStartStopAndDestroy)1006 TEST_P(PerfettoApiTest, DISABLED_TrackEventStartStopAndDestroy) {
1007   // This test used to cause a use after free as the tracing session got
1008   // destroyed. It needed to be run approximately 2000 times to catch it so test
1009   // with --gtest_repeat=3000 (less if running under GDB).
1010 
1011   // Setup the trace config.
1012   perfetto::TraceConfig cfg;
1013   cfg.set_duration_ms(500);
1014   cfg.add_buffers()->set_size_kb(1024);
1015   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
1016   ds_cfg->set_name("track_event");
1017 
1018   // Create five new trace sessions.
1019   std::vector<std::unique_ptr<perfetto::TracingSession>> sessions;
1020   for (size_t i = 0; i < 5; ++i) {
1021     sessions.push_back(perfetto::Tracing::NewTrace(/*BackendType=*/GetParam()));
1022     sessions[i]->Setup(cfg);
1023     sessions[i]->Start();
1024     sessions[i]->Stop();
1025   }
1026 }
1027 
TEST_P(PerfettoApiTest,TrackEventStartStopAndStopBlocking)1028 TEST_P(PerfettoApiTest, TrackEventStartStopAndStopBlocking) {
1029   // This test used to cause a deadlock (due to StopBlocking() after the session
1030   // already stopped). This usually occurred within 1 or 2 runs of the test so
1031   // use --gtest_repeat=10
1032 
1033   // Setup the trace config.
1034   perfetto::TraceConfig cfg;
1035   cfg.set_duration_ms(500);
1036   cfg.add_buffers()->set_size_kb(1024);
1037   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
1038   ds_cfg->set_name("track_event");
1039 
1040   // Create five new trace sessions.
1041   std::vector<std::unique_ptr<perfetto::TracingSession>> sessions;
1042   for (size_t i = 0; i < 5; ++i) {
1043     sessions.push_back(perfetto::Tracing::NewTrace(/*BackendType=*/GetParam()));
1044     sessions[i]->Setup(cfg);
1045     sessions[i]->Start();
1046     sessions[i]->Stop();
1047   }
1048   for (auto& session : sessions) {
1049     session->StopBlocking();
1050   }
1051 }
1052 
TEST_P(PerfettoApiTest,ChangeTraceConfiguration)1053 TEST_P(PerfettoApiTest, ChangeTraceConfiguration) {
1054   // Setup the trace config.
1055   perfetto::TraceConfig trace_config;
1056   trace_config.set_duration_ms(2000);
1057   trace_config.add_buffers()->set_size_kb(1024);
1058   auto* data_source = trace_config.add_data_sources();
1059 
1060   // Configure track events with category "foo".
1061   auto* ds_cfg = data_source->mutable_config();
1062   ds_cfg->set_name("track_event");
1063   perfetto::protos::gen::TrackEventConfig te_cfg;
1064   te_cfg.add_disabled_categories("*");
1065   te_cfg.add_enabled_categories("foo");
1066   ds_cfg->set_track_event_config_raw(te_cfg.SerializeAsString());
1067 
1068   // Initially, exclude all producers (the client library's producer is named
1069   // after current process's name, which will not match
1070   // "all_producers_excluded").
1071   data_source->add_producer_name_filter("all_producers_excluded");
1072 
1073   auto* tracing_session = NewTrace(trace_config);
1074 
1075   tracing_session->get()->StartBlocking();
1076 
1077   // Emit a first trace event, this one should be filtered out due
1078   // to the mismatching producer name filter.
1079   TRACE_EVENT_BEGIN("foo", "EventFilteredOut");
1080   TRACE_EVENT_END("foo");
1081 
1082   // Remove the producer name filter by changing configs.
1083   data_source->clear_producer_name_filter();
1084   tracing_session->get()->ChangeTraceConfig(trace_config);
1085 
1086   // We don't have a blocking version of ChangeTraceConfig, because there is
1087   // currently no response to it from producers or the service. Instead, we sync
1088   // the consumer and producer IPC streams for this test, to ensure that the
1089   // producer_name_filter change has propagated.
1090   tracing_session->get()->GetTraceStatsBlocking();  // sync consumer stream.
1091   perfetto::test::SyncProducers();                  // sync producer stream.
1092 
1093   // Emit a second trace event, this one should be included because
1094   // the producer name filter was cleared.
1095   TRACE_EVENT_BEGIN("foo", "EventIncluded");
1096   TRACE_EVENT_END("foo");
1097 
1098   // Verify that only the second event is in the trace data.
1099   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
1100   std::string trace(raw_trace.data(), raw_trace.size());
1101   EXPECT_THAT(trace, Not(HasSubstr("EventFilteredOut")));
1102   EXPECT_THAT(trace, HasSubstr("EventIncluded"));
1103 }
1104 
1105 // This is a build-only regression test that checks you can have a track event
1106 // inside a template.
1107 template <typename T>
TestTrackEventInsideTemplate(T)1108 void TestTrackEventInsideTemplate(T) {
1109   TRACE_EVENT_BEGIN("cat", "Name");
1110 }
1111 
1112 // This is a build-only regression test that checks you can specify the tracing
1113 // category as a template argument.
1114 constexpr const char kTestCategory[] = "foo";
1115 template <const char* category>
TestCategoryAsTemplateParameter()1116 void TestCategoryAsTemplateParameter() {
1117   TRACE_EVENT_BEGIN(category, "Name");
1118 }
1119 
1120 // Sleep for |nano_seconds| in a way that this duration is counted in
1121 // thread_time. i.e. sleep without using OS's sleep method, which blocks the
1122 // thread and OS doesn't schedule it until expected wake-up-time.
SpinForThreadTimeNanos(int64_t nano_seconds)1123 void SpinForThreadTimeNanos(int64_t nano_seconds) {
1124   auto time_now = perfetto::base::GetThreadCPUTimeNs().count();
1125   auto goal_time = time_now + nano_seconds;
1126   while (perfetto::base::GetThreadCPUTimeNs().count() < goal_time) {
1127   }
1128 }
1129 
TEST_P(PerfettoApiTest,TrackEventTimestampUnitAbsolute)1130 TEST_P(PerfettoApiTest, TrackEventTimestampUnitAbsolute) {
1131   for (auto unit_multiplier : {1u, 1000u}) {
1132     perfetto::protos::gen::TrackEventConfig te_cfg;
1133     te_cfg.set_disable_incremental_timestamps(true);
1134     te_cfg.set_timestamp_unit_multiplier(unit_multiplier);
1135     auto* tracing_session = NewTraceWithCategories({"foo"}, te_cfg);
1136     tracing_session->get()->StartBlocking();
1137     int64_t t_before = static_cast<int64_t>(TrackEventInternal::GetTimeNs());
1138     TRACE_EVENT_BEGIN("foo", "Event1");
1139     SpinForThreadTimeNanos(1000000);
1140     TRACE_EVENT_BEGIN("foo", "Event2");
1141     SpinForThreadTimeNanos(1000000);
1142     TRACE_EVENT_BEGIN("foo", "Event3");
1143     int64_t t_after = static_cast<int64_t>(TrackEventInternal::GetTimeNs());
1144     auto trace = StopSessionAndReturnParsedTrace(tracing_session);
1145     std::unordered_map<std::string, int64_t> event_map;
1146     bool found_absolute_clock = false;
1147     for (const auto& packet : trace.packet()) {
1148       if (packet.has_interned_data()) {
1149         if (packet.interned_data().event_names().size() == 1) {
1150           auto& event_name = packet.interned_data().event_names()[0].name();
1151           event_map[event_name] = static_cast<int64_t>(packet.timestamp());
1152         }
1153       }
1154       if (packet.has_trace_packet_defaults()) {
1155         auto clock_id = packet.trace_packet_defaults().timestamp_clock_id();
1156         EXPECT_EQ(unit_multiplier == 1
1157                       ? static_cast<uint32_t>(TrackEventInternal::GetClockId())
1158                       : TrackEventIncrementalState::kClockIdAbsolute,
1159                   clock_id);
1160         if (packet.has_clock_snapshot()) {
1161           for (auto& clock : packet.clock_snapshot().clocks()) {
1162             if (clock.clock_id() ==
1163                 TrackEventIncrementalState::kClockIdAbsolute) {
1164               found_absolute_clock = true;
1165               EXPECT_EQ(unit_multiplier, clock.unit_multiplier_ns());
1166               EXPECT_FALSE(clock.is_incremental());
1167             }
1168           }
1169         }
1170       }
1171     }
1172 
1173     EXPECT_EQ((unit_multiplier == 1000), found_absolute_clock);
1174 
1175     auto e1_t = event_map.at("Event1");
1176     auto e2_t = event_map.at("Event2");
1177     auto e3_t = event_map.at("Event3");
1178 
1179     int64_t min_delta = 1000000 / unit_multiplier;
1180     int64_t max_delta = (t_after - t_before) / unit_multiplier;
1181 
1182     EXPECT_LE(t_before / unit_multiplier, e1_t);
1183     EXPECT_LE(e3_t, t_after / unit_multiplier);
1184 
1185     EXPECT_GE(e2_t - e1_t, min_delta);
1186     EXPECT_GE(e3_t - e2_t, min_delta);
1187 
1188     EXPECT_LE(e2_t - e1_t, max_delta);
1189     EXPECT_LE(e3_t - e2_t, max_delta);
1190   }
1191 }
1192 
TEST_P(PerfettoApiTest,TrackEventTimestampUnitIncremental)1193 TEST_P(PerfettoApiTest, TrackEventTimestampUnitIncremental) {
1194   for (auto unit_multiplier : {1u, 1000u}) {
1195     perfetto::protos::gen::TrackEventConfig te_cfg;
1196     te_cfg.set_enable_thread_time_sampling(true);
1197     te_cfg.set_timestamp_unit_multiplier(unit_multiplier);
1198     auto* tracing_session = NewTraceWithCategories({"foo"}, te_cfg);
1199     tracing_session->get()->StartBlocking();
1200     SpinForThreadTimeNanos(1000000);
1201     TRACE_EVENT_BEGIN("foo", "Event1");
1202     SpinForThreadTimeNanos(1000000);
1203     TRACE_EVENT_BEGIN("foo", "Event2");
1204     SpinForThreadTimeNanos(1000000);
1205     TRACE_EVENT_BEGIN("foo", "Event3");
1206     auto trace = StopSessionAndReturnParsedTrace(tracing_session);
1207     struct TimeInfo {
1208       int64_t timestamp;
1209       int64_t thread_time;
1210     };
1211     std::unordered_map<std::string, TimeInfo> event_map;
1212     for (const auto& packet : trace.packet()) {
1213       if (packet.has_interned_data()) {
1214         if (packet.interned_data().event_names().size() == 1) {
1215           auto& event_name = packet.interned_data().event_names()[0].name();
1216           if (packet.has_track_event() &&
1217               packet.track_event().extra_counter_values().size() > 0) {
1218             auto thread_time = packet.track_event().extra_counter_values()[0];
1219             event_map[event_name] = {static_cast<int64_t>(packet.timestamp()),
1220                                      thread_time};
1221           }
1222         }
1223       }
1224     }
1225     int min_delta = 1000 * (unit_multiplier == 1 ? 1000 : 1);
1226 
1227     EXPECT_EQ(0, event_map.at("Event1").timestamp);
1228     EXPECT_GT(event_map.at("Event2").timestamp, min_delta);
1229     EXPECT_GT(event_map.at("Event3").timestamp, min_delta);
1230 
1231     EXPECT_GT(event_map.at("Event2").thread_time, min_delta);
1232     EXPECT_GT(event_map.at("Event3").thread_time, min_delta);
1233   }
1234 }
1235 
1236 // Tests that we don't accumulate error when using incremental timestamps with
1237 // timestamp unit multiplier.
TEST_P(PerfettoApiTest,TrackEventTimestampIncrementalAccumulatedError)1238 TEST_P(PerfettoApiTest, TrackEventTimestampIncrementalAccumulatedError) {
1239   constexpr uint64_t kUnitMultiplier = 100000;
1240   constexpr uint64_t kNumberOfEvents = 1000;
1241   constexpr uint64_t kTimeBetweenEventsNs = 50000;
1242 
1243   perfetto::protos::gen::TrackEventConfig te_cfg;
1244   te_cfg.set_timestamp_unit_multiplier(kUnitMultiplier);
1245   auto* tracing_session = NewTraceWithCategories({"foo"}, te_cfg);
1246   tracing_session->get()->StartBlocking();
1247   auto start = perfetto::TrackEvent::GetTraceTimeNs();
1248   TRACE_EVENT_BEGIN("foo", "Start");
1249   for (uint64_t i = 0; i < kNumberOfEvents; ++i) {
1250     SpinForThreadTimeNanos(kTimeBetweenEventsNs);
1251     TRACE_EVENT_BEGIN("foo", "Event");
1252   }
1253   auto end = perfetto::TrackEvent::GetTraceTimeNs();
1254   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
1255   uint64_t accumulated_timestamp = 0;
1256   for (const auto& packet : trace.packet()) {
1257     if (packet.has_track_event()) {
1258       accumulated_timestamp += packet.timestamp() * kUnitMultiplier;
1259     }
1260   }
1261 
1262   EXPECT_GE(accumulated_timestamp, kNumberOfEvents * kTimeBetweenEventsNs);
1263   EXPECT_LE(accumulated_timestamp, end - start);
1264 }
1265 
TEST_P(PerfettoApiTest,TrackEvent)1266 TEST_P(PerfettoApiTest, TrackEvent) {
1267   // Create a new trace session.
1268   auto* tracing_session = NewTraceWithCategories({"test"});
1269   tracing_session->get()->StartBlocking();
1270 
1271   // Emit one complete track event.
1272   TRACE_EVENT_BEGIN("test", "TestEvent");
1273   TRACE_EVENT_END("test");
1274   perfetto::TrackEvent::Flush();
1275 
1276   tracing_session->on_stop.Wait();
1277   std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
1278   ASSERT_GE(raw_trace.size(), 0u);
1279 
1280   // Read back the trace, maintaining interning tables as we go.
1281   perfetto::protos::gen::Trace trace;
1282   std::map<uint64_t, std::string> categories;
1283   std::map<uint64_t, std::string> event_names;
1284   ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
1285 
1286   auto now = perfetto::TrackEvent::GetTraceTimeNs();
1287 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) && \
1288     !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1289   auto clock_id = perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME;
1290 #else
1291   auto clock_id = perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC;
1292 #endif
1293   EXPECT_EQ(clock_id, perfetto::TrackEvent::GetTraceClockId());
1294 
1295   bool incremental_state_was_cleared = false;
1296   bool begin_found = false;
1297   bool end_found = false;
1298   bool process_descriptor_found = false;
1299   uint32_t sequence_id = 0;
1300   int32_t cur_pid = perfetto::test::GetCurrentProcessId();
1301   uint64_t recent_absolute_time_ns = 0;
1302   bool found_incremental_clock = false;
1303   constexpr auto kClockIdIncremental =
1304       TrackEventIncrementalState::kClockIdIncremental;
1305 
1306   for (const auto& packet : trace.packet()) {
1307     if (packet.has_track_descriptor()) {
1308       const auto& desc = packet.track_descriptor();
1309       if (desc.has_process()) {
1310         EXPECT_FALSE(process_descriptor_found);
1311         const auto& pd = desc.process();
1312         EXPECT_EQ(cur_pid, pd.pid());
1313         process_descriptor_found = true;
1314       }
1315     }
1316     if (packet.sequence_flags() &
1317         perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED) {
1318       EXPECT_TRUE(packet.has_trace_packet_defaults());
1319       incremental_state_was_cleared = true;
1320       categories.clear();
1321       event_names.clear();
1322       EXPECT_EQ(kClockIdIncremental,
1323                 packet.trace_packet_defaults().timestamp_clock_id());
1324     }
1325     if (packet.has_clock_snapshot()) {
1326       for (auto& clock : packet.clock_snapshot().clocks()) {
1327         if (clock.is_incremental()) {
1328           found_incremental_clock = true;
1329           recent_absolute_time_ns = clock.timestamp();
1330           EXPECT_EQ(kClockIdIncremental, clock.clock_id());
1331         }
1332       }
1333     }
1334 
1335     if (!packet.has_track_event())
1336       continue;
1337     EXPECT_TRUE(
1338         packet.sequence_flags() &
1339         (perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED |
1340          perfetto::protos::pbzero::TracePacket::SEQ_NEEDS_INCREMENTAL_STATE));
1341     const auto& track_event = packet.track_event();
1342 
1343     // Make sure we only see track events on one sequence.
1344     if (packet.trusted_packet_sequence_id()) {
1345       if (!sequence_id)
1346         sequence_id = packet.trusted_packet_sequence_id();
1347       EXPECT_EQ(sequence_id, packet.trusted_packet_sequence_id());
1348     }
1349 
1350     // Update incremental state.
1351     if (packet.has_interned_data()) {
1352       const auto& interned_data = packet.interned_data();
1353       for (const auto& it : interned_data.event_categories()) {
1354         EXPECT_EQ(categories.find(it.iid()), categories.end());
1355         categories[it.iid()] = it.name();
1356       }
1357       for (const auto& it : interned_data.event_names()) {
1358         EXPECT_EQ(event_names.find(it.iid()), event_names.end());
1359         event_names[it.iid()] = it.name();
1360       }
1361     }
1362     EXPECT_TRUE(found_incremental_clock);
1363     uint64_t absolute_timestamp = packet.timestamp() + recent_absolute_time_ns;
1364     recent_absolute_time_ns = absolute_timestamp;
1365     EXPECT_GT(absolute_timestamp, 0u);
1366     EXPECT_LE(absolute_timestamp, now);
1367     // Packet uses default (incremental) clock.
1368     EXPECT_FALSE(packet.has_timestamp_clock_id());
1369     if (track_event.type() ==
1370         perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN) {
1371       EXPECT_FALSE(begin_found);
1372       EXPECT_EQ(track_event.category_iids().size(), 1u);
1373       EXPECT_GE(track_event.category_iids()[0], 1u);
1374       EXPECT_EQ("test", categories[track_event.category_iids()[0]]);
1375       EXPECT_EQ("TestEvent", event_names[track_event.name_iid()]);
1376       begin_found = true;
1377     } else if (track_event.type() ==
1378                perfetto::protos::gen::TrackEvent::TYPE_SLICE_END) {
1379       EXPECT_FALSE(end_found);
1380       EXPECT_EQ(track_event.category_iids().size(), 0u);
1381       EXPECT_EQ(0u, track_event.name_iid());
1382       end_found = true;
1383     }
1384   }
1385   EXPECT_TRUE(incremental_state_was_cleared);
1386   EXPECT_TRUE(process_descriptor_found);
1387   EXPECT_TRUE(begin_found);
1388   EXPECT_TRUE(end_found);
1389 
1390   // Dummy instantiation of test templates.
1391   TestTrackEventInsideTemplate(true);
1392   TestCategoryAsTemplateParameter<kTestCategory>();
1393 }
1394 
TEST_P(PerfettoApiTest,TrackEventWithIncrementalTimestamp)1395 TEST_P(PerfettoApiTest, TrackEventWithIncrementalTimestamp) {
1396   for (auto disable_incremental_timestamps : {false, true}) {
1397     // Create a new trace session.
1398     perfetto::protos::gen::TrackEventConfig te_cfg;
1399     te_cfg.set_disable_incremental_timestamps(disable_incremental_timestamps);
1400     auto* tracing_session = NewTraceWithCategories({"bar"}, te_cfg);
1401     constexpr auto kClockIdIncremental =
1402         TrackEventIncrementalState::kClockIdIncremental;
1403     tracing_session->get()->StartBlocking();
1404 
1405     std::map<uint64_t, std::string> event_names;
1406 
1407     auto empty_lambda = [](perfetto::EventContext) {};
1408 
1409     constexpr uint64_t kInstantEvent1Time = 92718891479583;
1410     TRACE_EVENT_INSTANT(
1411         "bar", "InstantEvent1",
1412         perfetto::TraceTimestamp{kClockIdIncremental, kInstantEvent1Time},
1413         empty_lambda);
1414 
1415     constexpr uint64_t kInstantEvent2Time = 92718891618959;
1416     TRACE_EVENT_INSTANT(
1417         "bar", "InstantEvent2",
1418         perfetto::TraceTimestamp{kClockIdIncremental, kInstantEvent2Time},
1419         empty_lambda);
1420 
1421     auto trace = StopSessionAndReturnParsedTrace(tracing_session);
1422     uint64_t absolute_timestamp = 0;
1423     uint64_t prv_timestamp = 0;
1424     int event_count = 0;
1425     // Go through the packets and add the timestamps of those packets that use
1426     // the incremental clock - in order to get the absolute timestamps of the
1427     // track events.
1428 
1429     uint64_t default_clock_id = 0;
1430     bool is_incremental = false;
1431 
1432     for (const auto& packet : trace.packet()) {
1433       if (!packet.has_track_event() && !packet.has_clock_snapshot())
1434         continue;
1435       if (packet.has_trace_packet_defaults()) {
1436         auto& defaults = packet.trace_packet_defaults();
1437         if (defaults.has_timestamp_clock_id()) {
1438           default_clock_id = defaults.timestamp_clock_id();
1439         }
1440       }
1441       if (packet.has_clock_snapshot()) {
1442         for (auto& clock : packet.clock_snapshot().clocks()) {
1443           if (clock.is_incremental()) {
1444             is_incremental = true;
1445             absolute_timestamp = clock.timestamp();
1446             EXPECT_EQ(clock.clock_id(), kClockIdIncremental);
1447             EXPECT_FALSE(disable_incremental_timestamps);
1448           }
1449         }
1450       } else {
1451         auto clock_id = packet.has_timestamp_clock_id()
1452                             ? packet.timestamp_clock_id()
1453                             : default_clock_id;
1454         if (clock_id == kClockIdIncremental) {
1455           absolute_timestamp = prv_timestamp + packet.timestamp();
1456           EXPECT_FALSE(disable_incremental_timestamps);
1457         } else {
1458           absolute_timestamp = packet.timestamp();
1459           EXPECT_TRUE(disable_incremental_timestamps);
1460         }
1461       }
1462       prv_timestamp = absolute_timestamp;
1463 
1464       if (packet.sequence_flags() & perfetto::protos::pbzero::TracePacket::
1465                                         SEQ_INCREMENTAL_STATE_CLEARED) {
1466         event_names.clear();
1467       }
1468 
1469       // Update incremental state.
1470       if (packet.has_interned_data()) {
1471         const auto& interned_data = packet.interned_data();
1472         for (const auto& it : interned_data.event_names()) {
1473           EXPECT_EQ(event_names.find(it.iid()), event_names.end());
1474           event_names[it.iid()] = it.name();
1475         }
1476       }
1477 
1478       if (event_names[packet.track_event().name_iid()] == "InstantEvent1") {
1479         event_count++;
1480         EXPECT_EQ(absolute_timestamp, kInstantEvent1Time);
1481       } else if (event_names[packet.track_event().name_iid()] ==
1482                  "InstantEvent2") {
1483         event_count++;
1484         EXPECT_EQ(absolute_timestamp, kInstantEvent2Time);
1485       }
1486     }
1487     EXPECT_NE(is_incremental, disable_incremental_timestamps);
1488     EXPECT_EQ(event_count, 2);
1489   }
1490 }
1491 
TEST_P(PerfettoApiTest,TrackEventCategories)1492 TEST_P(PerfettoApiTest, TrackEventCategories) {
1493   // Create a new trace session.
1494   auto* tracing_session = NewTraceWithCategories({"bar"});
1495   tracing_session->get()->StartBlocking();
1496 
1497   // Emit some track events.
1498   TRACE_EVENT_BEGIN("foo", "NotEnabled");
1499   TRACE_EVENT_END("foo");
1500   TRACE_EVENT_BEGIN("bar", "Enabled");
1501   TRACE_EVENT_END("bar");
1502 
1503   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
1504   std::string trace(raw_trace.data(), raw_trace.size());
1505   // TODO(skyostil): Come up with a nicer way to verify trace contents.
1506   EXPECT_THAT(trace, HasSubstr("Enabled"));
1507   EXPECT_THAT(trace, Not(HasSubstr("NotEnabled")));
1508 }
1509 
TEST_P(PerfettoApiTest,ClearIncrementalState)1510 TEST_P(PerfettoApiTest, ClearIncrementalState) {
1511   perfetto::DataSourceDescriptor dsd;
1512   dsd.set_name("incr_data_source");
1513   TestIncrementalDataSource::Register(dsd);
1514   perfetto::test::SyncProducers();
1515 
1516   // Setup the trace config with an incremental state clearing period.
1517   perfetto::TraceConfig cfg;
1518   cfg.set_duration_ms(500);
1519   cfg.add_buffers()->set_size_kb(1024);
1520   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
1521   ds_cfg->set_name("incr_data_source");
1522   auto* is_cfg = cfg.mutable_incremental_state_config();
1523   is_cfg->set_clear_period_ms(10);
1524 
1525   // Create a new trace session.
1526   auto* tracing_session = NewTrace(cfg);
1527   tracing_session->get()->StartBlocking();
1528 
1529   // Observe at least 5 incremental state resets.
1530   constexpr size_t kMaxLoops = 100;
1531   size_t loops = 0;
1532   size_t times_cleared = 0;
1533   while (times_cleared < 5) {
1534     ASSERT_LT(loops++, kMaxLoops);
1535     TestIncrementalDataSource::Trace(
1536         [&](TestIncrementalDataSource::TraceContext ctx) {
1537           auto* incr_state = ctx.GetIncrementalState();
1538           if (!incr_state->flag) {
1539             incr_state->flag = true;
1540             times_cleared++;
1541           }
1542         });
1543     std::this_thread::sleep_for(std::chrono::milliseconds(10));
1544   }
1545   tracing_session->get()->StopBlocking();
1546   perfetto::test::TracingMuxerImplInternalsForTest::
1547       ClearDataSourceTlsStateOnReset<TestIncrementalDataSource>();
1548 }
1549 
TEST_P(PerfettoApiTest,TrackEventRegistrationWithModule)1550 TEST_P(PerfettoApiTest, TrackEventRegistrationWithModule) {
1551   MockTracingMuxer muxer;
1552 
1553   // Each track event namespace registers its own data source.
1554   perfetto::TrackEvent::Register();
1555   EXPECT_EQ(1u, muxer.data_sources.size());
1556 
1557   tracing_module::InitializeCategories();
1558   EXPECT_EQ(3u, muxer.data_sources.size());
1559 
1560   // Both data sources have the same name but distinct static data (i.e.,
1561   // individual instance states).
1562   EXPECT_EQ("track_event", muxer.data_sources[0].dsd.name());
1563   EXPECT_EQ("track_event", muxer.data_sources[1].dsd.name());
1564   EXPECT_EQ("track_event", muxer.data_sources[2].dsd.name());
1565   EXPECT_NE(muxer.data_sources[0].static_state,
1566             muxer.data_sources[1].static_state);
1567   EXPECT_NE(muxer.data_sources[0].static_state,
1568             muxer.data_sources[2].static_state);
1569 }
1570 
TEST_P(PerfettoApiTest,TrackEventDescriptor)1571 TEST_P(PerfettoApiTest, TrackEventDescriptor) {
1572   MockTracingMuxer muxer;
1573 
1574   perfetto::TrackEvent::Register();
1575   EXPECT_EQ(1u, muxer.data_sources.size());
1576   EXPECT_EQ("track_event", muxer.data_sources[0].dsd.name());
1577 
1578   perfetto::protos::gen::TrackEventDescriptor desc;
1579   auto desc_raw = muxer.data_sources[0].dsd.track_event_descriptor_raw();
1580   EXPECT_TRUE(desc.ParseFromArray(desc_raw.data(), desc_raw.size()));
1581 
1582   // Check that the advertised categories match PERFETTO_DEFINE_CATEGORIES (see
1583   // above).
1584   EXPECT_EQ(7, desc.available_categories_size());
1585   EXPECT_EQ("test", desc.available_categories()[0].name());
1586   EXPECT_EQ("This is a test category",
1587             desc.available_categories()[0].description());
1588   EXPECT_EQ("tag", desc.available_categories()[0].tags()[0]);
1589   EXPECT_EQ("foo", desc.available_categories()[1].name());
1590   EXPECT_EQ("bar", desc.available_categories()[2].name());
1591   EXPECT_EQ("cat", desc.available_categories()[3].name());
1592   EXPECT_EQ("slow", desc.available_categories()[3].tags()[0]);
1593   EXPECT_EQ("cat.verbose", desc.available_categories()[4].name());
1594   EXPECT_EQ("debug", desc.available_categories()[4].tags()[0]);
1595   EXPECT_EQ("cat-with-dashes", desc.available_categories()[5].name());
1596   EXPECT_EQ("disabled-by-default-cat", desc.available_categories()[6].name());
1597   EXPECT_EQ("slow", desc.available_categories()[6].tags()[0]);
1598 }
1599 
TEST_P(PerfettoApiTest,TrackEventSharedIncrementalState)1600 TEST_P(PerfettoApiTest, TrackEventSharedIncrementalState) {
1601   tracing_module::InitializeCategories();
1602 
1603   // Setup the trace config.
1604   perfetto::TraceConfig cfg;
1605   cfg.set_duration_ms(500);
1606   cfg.add_buffers()->set_size_kb(1024);
1607   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
1608   ds_cfg->set_name("track_event");
1609   auto* tracing_session = NewTrace(cfg);
1610   tracing_session->get()->StartBlocking();
1611 
1612   perfetto::internal::TrackEventIncrementalState* main_state = nullptr;
1613   perfetto::TrackEvent::Trace(
1614       [&main_state](perfetto::TrackEvent::TraceContext ctx) {
1615         main_state = ctx.GetIncrementalState();
1616       });
1617   perfetto::internal::TrackEventIncrementalState* module_state =
1618       tracing_module::GetIncrementalState();
1619 
1620   // Both track event data sources should use the same incremental state (thanks
1621   // to sharing TLS).
1622   EXPECT_NE(nullptr, main_state);
1623   EXPECT_EQ(main_state, module_state);
1624   tracing_session->get()->StopBlocking();
1625 }
1626 
TEST_P(PerfettoApiTest,TrackEventCategoriesWithModule)1627 TEST_P(PerfettoApiTest, TrackEventCategoriesWithModule) {
1628   // Check that categories defined in two different category registries are
1629   // enabled and disabled correctly.
1630   tracing_module::InitializeCategories();
1631 
1632   // Create a new trace session. Only the "foo" category is enabled. It also
1633   // exists both locally and in the existing module.
1634   auto* tracing_session = NewTraceWithCategories({"foo"});
1635   tracing_session->get()->StartBlocking();
1636 
1637   // Emit some track events locally and from the test module.
1638   TRACE_EVENT_BEGIN("foo", "FooEventFromMain");
1639   TRACE_EVENT_END("foo");
1640   tracing_module::EmitTrackEvents();
1641   tracing_module::EmitTrackEvents2();
1642   TRACE_EVENT_BEGIN("bar", "DisabledEventFromMain");
1643   TRACE_EVENT_END("bar");
1644 
1645   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
1646   std::string trace(raw_trace.data(), raw_trace.size());
1647   EXPECT_THAT(trace, HasSubstr("FooEventFromMain"));
1648   EXPECT_THAT(trace, Not(HasSubstr("DisabledEventFromMain")));
1649   EXPECT_THAT(trace, HasSubstr("FooEventFromModule"));
1650   EXPECT_THAT(trace, Not(HasSubstr("DisabledEventFromModule")));
1651   EXPECT_THAT(trace, HasSubstr("FooEventFromModule2"));
1652   EXPECT_THAT(trace, Not(HasSubstr("DisabledEventFromModule2")));
1653 
1654   perfetto::protos::gen::Trace parsed_trace;
1655   ASSERT_TRUE(parsed_trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
1656 
1657   uint32_t sequence_id = 0;
1658   for (const auto& packet : parsed_trace.packet()) {
1659     if (!packet.has_track_event())
1660       continue;
1661 
1662     // Make sure we only see track events on one sequence. This means all track
1663     // event modules are sharing the same trace writer (by using the same TLS
1664     // index).
1665     if (packet.trusted_packet_sequence_id()) {
1666       if (!sequence_id)
1667         sequence_id = packet.trusted_packet_sequence_id();
1668       EXPECT_EQ(sequence_id, packet.trusted_packet_sequence_id());
1669     }
1670   }
1671 }
1672 
TEST_P(PerfettoApiTest,TrackEventNamespaces)1673 TEST_P(PerfettoApiTest, TrackEventNamespaces) {
1674   perfetto::TrackEvent::Register();
1675   other_ns::TrackEvent::Register();
1676   tracing_module::InitializeCategories();
1677 
1678   auto* tracing_session =
1679       NewTraceWithCategories({"test", "cat1", "extra", "other_ns"});
1680   tracing_session->get()->StartBlocking();
1681 
1682   // Default namespace.
1683   TRACE_EVENT_INSTANT("test", "MainNamespaceEvent");
1684   EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("test"));
1685 
1686   // Other namespace in a block scope.
1687   {
1688     PERFETTO_USE_CATEGORIES_FROM_NAMESPACE_SCOPED(other_ns);
1689     TRACE_EVENT_INSTANT("other_ns", "OtherNamespaceEvent");
1690     EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("other_ns"));
1691   }
1692 
1693   // Back to the default namespace.
1694   TRACE_EVENT_INSTANT("test", "MainNamespaceEvent2");
1695 
1696   // More namespaces defined in another module.
1697   tracing_module::EmitTrackEventsFromAllNamespaces();
1698 
1699   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
1700   EXPECT_THAT(
1701       slices,
1702       ElementsAre("I:test.MainNamespaceEvent", "I:other_ns.OtherNamespaceEvent",
1703                   "I:test.MainNamespaceEvent2",
1704                   "B:cat1.DefaultNamespaceFromModule",
1705                   "B:extra.ExtraNamespaceFromModule",
1706                   "B:extra.OverrideNamespaceFromModule",
1707                   "B:extra.DefaultNamespace", "B:cat1.DefaultNamespace"));
1708 }
1709 
TEST_P(PerfettoApiTest,TrackEventDynamicCategories)1710 TEST_P(PerfettoApiTest, TrackEventDynamicCategories) {
1711   // Setup the trace config.
1712   perfetto::TraceConfig cfg;
1713   cfg.set_duration_ms(500);
1714   cfg.add_buffers()->set_size_kb(1024);
1715   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
1716   ds_cfg->set_name("track_event");
1717 
1718   // Session #1 enabled the "dynamic" category.
1719   auto* tracing_session = NewTraceWithCategories({"dynamic"});
1720   tracing_session->get()->StartBlocking();
1721 
1722   EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("dynamic"));
1723   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("dynamic_2"));
1724 
1725   // Session #2 enables "dynamic_2".
1726   auto* tracing_session2 = NewTraceWithCategories({"dynamic_2"});
1727   tracing_session2->get()->StartBlocking();
1728 
1729   // Test naming dynamic categories with std::string.
1730   perfetto::DynamicCategory dynamic{"dynamic"};
1731   TRACE_EVENT_BEGIN(dynamic, "EventInDynamicCategory");
1732   perfetto::DynamicCategory dynamic_disabled{"dynamic_disabled"};
1733   TRACE_EVENT_BEGIN(dynamic_disabled, "EventInDisabledDynamicCategory");
1734 
1735   // Test naming dynamic categories statically.
1736   TRACE_EVENT_BEGIN("dynamic", "EventInStaticallyNamedDynamicCategory");
1737 
1738   perfetto::DynamicCategory dynamic_2{"dynamic_2"};
1739   TRACE_EVENT_BEGIN(dynamic_2, "EventInSecondDynamicCategory");
1740   TRACE_EVENT_BEGIN("dynamic_2", "EventInSecondStaticallyNamedDynamicCategory");
1741 
1742   EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED(dynamic));
1743   EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED(dynamic_2));
1744 
1745   std::thread thread([] {
1746     // Make sure the category name can actually be computed at runtime.
1747     std::string name = "dyn";
1748     if (perfetto::base::GetThreadId())
1749       name += "amic";
1750     perfetto::DynamicCategory cat{name};
1751     TRACE_EVENT_BEGIN(cat, "DynamicFromOtherThread");
1752     perfetto::DynamicCategory cat2{"dynamic_disabled"};
1753     TRACE_EVENT_BEGIN(cat2, "EventInDisabledDynamicCategory");
1754   });
1755   thread.join();
1756 
1757   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
1758   std::string trace(raw_trace.data(), raw_trace.size());
1759   EXPECT_THAT(trace, HasSubstr("EventInDynamicCategory"));
1760   EXPECT_THAT(trace, Not(HasSubstr("EventInDisabledDynamicCategory")));
1761   EXPECT_THAT(trace, HasSubstr("DynamicFromOtherThread"));
1762   EXPECT_THAT(trace, Not(HasSubstr("EventInSecondDynamicCategory")));
1763   EXPECT_THAT(trace, HasSubstr("EventInStaticallyNamedDynamicCategory"));
1764   EXPECT_THAT(trace,
1765               Not(HasSubstr("EventInSecondStaticallyNamedDynamicCategory")));
1766 
1767   raw_trace = StopSessionAndReturnBytes(tracing_session2);
1768   trace = std::string(raw_trace.data(), raw_trace.size());
1769   EXPECT_THAT(trace, Not(HasSubstr("EventInDynamicCategory")));
1770   EXPECT_THAT(trace, Not(HasSubstr("EventInDisabledDynamicCategory")));
1771   EXPECT_THAT(trace, Not(HasSubstr("DynamicFromOtherThread")));
1772   EXPECT_THAT(trace, HasSubstr("EventInSecondDynamicCategory"));
1773   EXPECT_THAT(trace, Not(HasSubstr("EventInStaticallyNamedDynamicCategory")));
1774   EXPECT_THAT(trace, HasSubstr("EventInSecondStaticallyNamedDynamicCategory"));
1775 }
1776 
TEST_P(PerfettoApiTest,TrackEventConcurrentSessions)1777 TEST_P(PerfettoApiTest, TrackEventConcurrentSessions) {
1778   // Check that categories that are enabled and disabled in two parallel tracing
1779   // sessions don't interfere.
1780 
1781   // Session #1 enables the "foo" category.
1782   auto* tracing_session = NewTraceWithCategories({"foo"});
1783   tracing_session->get()->StartBlocking();
1784 
1785   // Session #2 enables the "bar" category.
1786   auto* tracing_session2 = NewTraceWithCategories({"bar"});
1787   tracing_session2->get()->StartBlocking();
1788 
1789   // Emit some track events under both categories.
1790   TRACE_EVENT_BEGIN("foo", "Session1_First");
1791   TRACE_EVENT_END("foo");
1792   TRACE_EVENT_BEGIN("bar", "Session2_First");
1793   TRACE_EVENT_END("bar");
1794 
1795   tracing_session->get()->StopBlocking();
1796   TRACE_EVENT_BEGIN("foo", "Session1_Second");
1797   TRACE_EVENT_END("foo");
1798   TRACE_EVENT_BEGIN("bar", "Session2_Second");
1799   TRACE_EVENT_END("bar");
1800 
1801   tracing_session2->get()->StopBlocking();
1802   TRACE_EVENT_BEGIN("foo", "Session1_Third");
1803   TRACE_EVENT_END("foo");
1804   TRACE_EVENT_BEGIN("bar", "Session2_Third");
1805   TRACE_EVENT_END("bar");
1806 
1807   std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
1808   std::string trace(raw_trace.data(), raw_trace.size());
1809   EXPECT_THAT(trace, HasSubstr("Session1_First"));
1810   EXPECT_THAT(trace, Not(HasSubstr("Session1_Second")));
1811   EXPECT_THAT(trace, Not(HasSubstr("Session1_Third")));
1812   EXPECT_THAT(trace, Not(HasSubstr("Session2_First")));
1813   EXPECT_THAT(trace, Not(HasSubstr("Session2_Second")));
1814   EXPECT_THAT(trace, Not(HasSubstr("Session2_Third")));
1815 
1816   std::vector<char> raw_trace2 = tracing_session2->get()->ReadTraceBlocking();
1817   std::string trace2(raw_trace2.data(), raw_trace2.size());
1818   EXPECT_THAT(trace2, Not(HasSubstr("Session1_First")));
1819   EXPECT_THAT(trace2, Not(HasSubstr("Session1_Second")));
1820   EXPECT_THAT(trace2, Not(HasSubstr("Session1_Third")));
1821   EXPECT_THAT(trace2, HasSubstr("Session2_First"));
1822   EXPECT_THAT(trace2, HasSubstr("Session2_Second"));
1823   EXPECT_THAT(trace2, Not(HasSubstr("Session2_Third")));
1824 }
1825 
TEST_P(PerfettoApiTest,TrackEventProcessAndThreadDescriptors)1826 TEST_P(PerfettoApiTest, TrackEventProcessAndThreadDescriptors) {
1827   // Thread and process descriptors can be set before tracing is enabled.
1828   {
1829     auto track = perfetto::ProcessTrack::Current();
1830     auto desc = track.Serialize();
1831     desc.set_name("hello.exe");
1832     desc.mutable_chrome_process()->set_process_priority(1);
1833     perfetto::TrackEvent::SetTrackDescriptor(track, std::move(desc));
1834   }
1835 
1836   // Erased tracks shouldn't show up anywhere.
1837   {
1838     perfetto::Track erased(1234u);
1839     auto desc = erased.Serialize();
1840     desc.set_name("ErasedTrack");
1841     perfetto::TrackEvent::SetTrackDescriptor(erased, std::move(desc));
1842     perfetto::TrackEvent::EraseTrackDescriptor(erased);
1843   }
1844 
1845   // Setup the trace config.
1846   perfetto::TraceConfig cfg;
1847   cfg.set_duration_ms(500);
1848   cfg.add_buffers()->set_size_kb(1024);
1849   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
1850   ds_cfg->set_name("track_event");
1851 
1852   // Create a new trace session.
1853   auto* tracing_session = NewTrace(cfg);
1854   tracing_session->get()->StartBlocking();
1855   TRACE_EVENT_INSTANT("test", "MainThreadEvent");
1856 
1857   std::thread thread([&] {
1858     auto track = perfetto::ThreadTrack::Current();
1859     auto desc = track.Serialize();
1860     desc.set_name("TestThread");
1861     perfetto::TrackEvent::SetTrackDescriptor(track, std::move(desc));
1862     TRACE_EVENT_INSTANT("test", "ThreadEvent");
1863   });
1864   thread.join();
1865 
1866   // Update the process descriptor while tracing is enabled. It should be
1867   // immediately reflected in the trace.
1868   {
1869     auto track = perfetto::ProcessTrack::Current();
1870     auto desc = track.Serialize();
1871     desc.set_name("goodbye.exe");
1872     perfetto::TrackEvent::SetTrackDescriptor(track, std::move(desc));
1873     perfetto::TrackEvent::Flush();
1874   }
1875 
1876   tracing_session->get()->StopBlocking();
1877 
1878   // After tracing ends, setting the descriptor has no immediate effect.
1879   {
1880     auto track = perfetto::ProcessTrack::Current();
1881     auto desc = track.Serialize();
1882     desc.set_name("noop.exe");
1883     perfetto::TrackEvent::SetTrackDescriptor(track, std::move(desc));
1884   }
1885 
1886   std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
1887   perfetto::protos::gen::Trace trace;
1888   ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
1889 
1890   std::vector<perfetto::protos::gen::TrackDescriptor> descs;
1891   std::vector<perfetto::protos::gen::TrackDescriptor> thread_descs;
1892   uint32_t main_thread_sequence = GetMainThreadPacketSequenceId(trace);
1893   for (const auto& packet : trace.packet()) {
1894     if (packet.has_track_descriptor()) {
1895       if (packet.trusted_packet_sequence_id() == main_thread_sequence) {
1896         descs.push_back(packet.track_descriptor());
1897       } else if (packet.track_descriptor().has_thread()) {
1898         thread_descs.push_back(packet.track_descriptor());
1899       }
1900     }
1901   }
1902 
1903   // The main thread records the initial process name as well as the one that's
1904   // set during tracing. Additionally it records a thread descriptor for the
1905   // main thread.
1906 
1907   EXPECT_EQ(3u, descs.size());
1908 
1909   // Default track for the main thread.
1910   EXPECT_EQ(0, descs[0].process().pid());
1911   EXPECT_NE(0, descs[0].thread().pid());
1912 
1913   // First process descriptor.
1914   EXPECT_NE(0, descs[1].process().pid());
1915   EXPECT_EQ("hello.exe", descs[1].name());
1916 
1917   // Second process descriptor.
1918   EXPECT_NE(0, descs[2].process().pid());
1919   EXPECT_EQ("goodbye.exe", descs[2].name());
1920 
1921   // The child thread records only its own thread descriptor (twice, since it
1922   // was mutated).
1923   ASSERT_EQ(2u, thread_descs.size());
1924   EXPECT_EQ("TestThread", thread_descs[0].name());
1925   EXPECT_NE(0, thread_descs[0].thread().pid());
1926   EXPECT_NE(0, thread_descs[0].thread().tid());
1927   EXPECT_EQ("TestThread", thread_descs[1].name());
1928   EXPECT_NE(0, thread_descs[1].thread().pid());
1929   EXPECT_NE(0, thread_descs[1].thread().tid());
1930   EXPECT_NE(0, descs[2].process().pid());
1931   EXPECT_EQ("goodbye.exe", descs[2].name());
1932 }
1933 
TEST_P(PerfettoApiTest,CustomTrackDescriptor)1934 TEST_P(PerfettoApiTest, CustomTrackDescriptor) {
1935   // Setup the trace config.
1936   perfetto::TraceConfig cfg;
1937   cfg.set_duration_ms(500);
1938   cfg.add_buffers()->set_size_kb(1024);
1939   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
1940   ds_cfg->set_name("track_event");
1941 
1942   // Create a new trace session.
1943   auto* tracing_session = NewTrace(cfg);
1944   tracing_session->get()->StartBlocking();
1945 
1946   auto track = perfetto::ProcessTrack::Current();
1947   auto desc = track.Serialize();
1948   desc.mutable_process()->set_process_name("testing.exe");
1949   desc.mutable_thread()->set_tid(
1950       static_cast<int32_t>(perfetto::base::GetThreadId()));
1951   desc.mutable_chrome_process()->set_process_priority(123);
1952   perfetto::TrackEvent::SetTrackDescriptor(track, std::move(desc));
1953 
1954   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
1955 
1956   uint32_t main_thread_sequence = GetMainThreadPacketSequenceId(trace);
1957   bool found_desc = false;
1958   for (const auto& packet : trace.packet()) {
1959     if (packet.trusted_packet_sequence_id() != main_thread_sequence)
1960       continue;
1961     if (packet.has_track_descriptor()) {
1962       auto td = packet.track_descriptor();
1963       if (!td.has_process())
1964         continue;
1965       EXPECT_NE(0, td.process().pid());
1966       EXPECT_TRUE(td.has_chrome_process());
1967       EXPECT_EQ("testing.exe", td.process().process_name());
1968       EXPECT_EQ(123, td.chrome_process().process_priority());
1969       found_desc = true;
1970     }
1971   }
1972   EXPECT_TRUE(found_desc);
1973 }
1974 
TEST_P(PerfettoApiTest,TrackEventCustomTrack)1975 TEST_P(PerfettoApiTest, TrackEventCustomTrack) {
1976   // Create a new trace session.
1977   auto* tracing_session = NewTraceWithCategories({"bar"});
1978   tracing_session->get()->StartBlocking();
1979 
1980   // Declare a custom track and give it a name.
1981   uint64_t async_id = 123;
1982 
1983   {
1984     auto track = perfetto::Track(async_id);
1985     auto desc = track.Serialize();
1986     desc.set_name("MyCustomTrack");
1987     perfetto::TrackEvent::SetTrackDescriptor(track, std::move(desc));
1988   }
1989 
1990   // Start events on one thread and end them on another.
1991   TRACE_EVENT_BEGIN("bar", "AsyncEvent", perfetto::Track(async_id), "debug_arg",
1992                     123);
1993 
1994   TRACE_EVENT_BEGIN("bar", "SubEvent", perfetto::Track(async_id),
1995                     [](perfetto::EventContext) {});
1996   const auto main_thread_track =
1997       perfetto::Track(async_id, perfetto::ThreadTrack::Current());
1998   std::thread thread([&] {
1999     TRACE_EVENT_END("bar", perfetto::Track(async_id));
2000     TRACE_EVENT_END("bar", perfetto::Track(async_id), "arg1", false, "arg2",
2001                     true);
2002     const auto thread_track =
2003         perfetto::Track(async_id, perfetto::ThreadTrack::Current());
2004     // Thread-scoped tracks will have different uuids on different thread even
2005     // if the id matches.
2006     ASSERT_NE(main_thread_track.uuid, thread_track.uuid);
2007   });
2008   thread.join();
2009 
2010   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2011 
2012   // Check that the track uuids match on the begin and end events.
2013   const auto track = perfetto::Track(async_id);
2014   uint32_t main_thread_sequence = GetMainThreadPacketSequenceId(trace);
2015   int event_count = 0;
2016   bool found_descriptor = false;
2017   for (const auto& packet : trace.packet()) {
2018     if (packet.has_track_descriptor() &&
2019         !packet.track_descriptor().has_process() &&
2020         !packet.track_descriptor().has_thread()) {
2021       auto td = packet.track_descriptor();
2022       EXPECT_EQ("MyCustomTrack", td.name());
2023       EXPECT_EQ(track.uuid, td.uuid());
2024       EXPECT_EQ(perfetto::ProcessTrack::Current().uuid, td.parent_uuid());
2025       found_descriptor = true;
2026       continue;
2027     }
2028 
2029     if (!packet.has_track_event())
2030       continue;
2031     auto track_event = packet.track_event();
2032     if (track_event.type() ==
2033         perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN) {
2034       EXPECT_EQ(main_thread_sequence, packet.trusted_packet_sequence_id());
2035       EXPECT_EQ(track.uuid, track_event.track_uuid());
2036     } else {
2037       EXPECT_NE(main_thread_sequence, packet.trusted_packet_sequence_id());
2038       EXPECT_EQ(track.uuid, track_event.track_uuid());
2039     }
2040     event_count++;
2041   }
2042   EXPECT_TRUE(found_descriptor);
2043   EXPECT_EQ(4, event_count);
2044   perfetto::TrackEvent::EraseTrackDescriptor(track);
2045 }
2046 
TEST_P(PerfettoApiTest,TrackEventCustomTimestampClock)2047 TEST_P(PerfettoApiTest, TrackEventCustomTimestampClock) {
2048   // Create a new trace session.
2049   auto* tracing_session = NewTraceWithCategories({"foo"});
2050   tracing_session->get()->StartBlocking();
2051 
2052   static constexpr perfetto::protos::pbzero::BuiltinClock kMyClockId =
2053       static_cast<perfetto::protos::pbzero::BuiltinClock>(700);
2054   static constexpr uint64_t kTimestamp = 12345678;
2055 
2056   // First emit a clock snapshot that maps our custom clock to regular trace
2057   // time. Note that the clock snapshot should come before any events
2058   // referencing that clock.
2059   perfetto::TrackEvent::Trace([](perfetto::TrackEvent::TraceContext ctx) {
2060     auto packet = ctx.NewTracePacket();
2061     packet->set_timestamp_clock_id(
2062         static_cast<uint32_t>(perfetto::TrackEvent::GetTraceClockId()));
2063     packet->set_timestamp(perfetto::TrackEvent::GetTraceTimeNs());
2064     auto* clock_snapshot = packet->set_clock_snapshot();
2065     // First set the reference clock, i.e., the default trace clock in this
2066     // case.
2067     auto* clock = clock_snapshot->add_clocks();
2068     clock->set_clock_id(
2069         static_cast<uint32_t>(perfetto::TrackEvent::GetTraceClockId()));
2070     clock->set_timestamp(perfetto::TrackEvent::GetTraceTimeNs());
2071     // Then set the value of our reference clock at the same point in time. We
2072     // pretend our clock is one second behind trace time.
2073     clock = clock_snapshot->add_clocks();
2074     clock->set_clock_id(kMyClockId);
2075     clock->set_timestamp(kTimestamp + 1000000000ull);
2076   });
2077 
2078   // Next emit a trace event with a custom timestamp and a custom clock.
2079   TRACE_EVENT_INSTANT("foo", "EventWithCustomTime",
2080                       perfetto::TraceTimestamp{kMyClockId, kTimestamp});
2081   TRACE_EVENT_INSTANT("foo", "EventWithNormalTime");
2082 
2083   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2084 
2085   // Check that both the clock id and the timestamp got written together with
2086   // the packet. Note that we don't check the actual clock sync behavior here
2087   // since that happens in the Trace Processor instead.
2088   bool found_clock_snapshot = false;
2089   bool found_event = false;
2090   for (const auto& packet : trace.packet()) {
2091     if (packet.has_clock_snapshot())
2092       found_clock_snapshot = true;
2093     if (!packet.has_track_event() || packet.timestamp() != kTimestamp)
2094       continue;
2095     found_event = true;
2096     EXPECT_EQ(static_cast<uint32_t>(kMyClockId), packet.timestamp_clock_id());
2097     EXPECT_EQ(kTimestamp, packet.timestamp());
2098   }
2099   EXPECT_TRUE(found_clock_snapshot);
2100   EXPECT_TRUE(found_event);
2101 }
2102 
2103 // Only synchronous phases are supported for other threads. Hence disabled this
2104 // test.
2105 // TODO(b/261493947): fix or remove.
TEST_P(PerfettoApiTest,DISABLED_LegacyEventWithThreadOverride)2106 TEST_P(PerfettoApiTest, DISABLED_LegacyEventWithThreadOverride) {
2107   // Create a new trace session.
2108   auto* tracing_session = NewTraceWithCategories({"cat"});
2109   tracing_session->get()->StartBlocking();
2110 
2111   TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0("cat", "Name", 1,
2112                                                MyThreadId(456), MyTimestamp{0});
2113   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2114 
2115   // Check that we wrote a track descriptor for the custom thread track, and
2116   // that the event was associated with that track.
2117   const auto track = perfetto::ThreadTrack::ForThread(456);
2118   bool found_descriptor = false;
2119   bool found_event = false;
2120   for (const auto& packet : trace.packet()) {
2121     if (packet.has_track_descriptor() &&
2122         packet.track_descriptor().has_thread()) {
2123       auto td = packet.track_descriptor().thread();
2124       if (td.tid() == 456) {
2125         EXPECT_EQ(track.uuid, packet.track_descriptor().uuid());
2126         found_descriptor = true;
2127       }
2128     }
2129 
2130     if (!packet.has_track_event())
2131       continue;
2132     auto track_event = packet.track_event();
2133     if (track_event.legacy_event().phase() == TRACE_EVENT_PHASE_ASYNC_BEGIN) {
2134       EXPECT_EQ(0u, track_event.track_uuid());
2135       found_event = true;
2136     }
2137   }
2138   EXPECT_TRUE(found_descriptor);
2139   EXPECT_TRUE(found_event);
2140   perfetto::TrackEvent::EraseTrackDescriptor(track);
2141 }
2142 
2143 // Only synchronous phases are supported for other threads. Hence disabled this
2144 // test.
TEST_P(PerfettoApiTest,DISABLED_LegacyEventWithProcessOverride)2145 TEST_P(PerfettoApiTest, DISABLED_LegacyEventWithProcessOverride) {
2146   // Create a new trace session.
2147   auto* tracing_session = NewTraceWithCategories({"cat"});
2148   tracing_session->get()->StartBlocking();
2149 
2150   // Note: there's no direct entrypoint for adding trace events for another
2151   // process, so we're using the internal support macro here.
2152   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(
2153       TRACE_EVENT_PHASE_INSTANT, "cat", "Name", 0, MyThreadId{789},
2154       MyTimestamp{0}, TRACE_EVENT_FLAG_HAS_PROCESS_ID);
2155   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2156 
2157   // Check that the event has a pid_override matching MyThread above.
2158   bool found_event = false;
2159   for (const auto& packet : trace.packet()) {
2160     if (!packet.has_track_event())
2161       continue;
2162     auto track_event = packet.track_event();
2163     if (track_event.type() == perfetto::protos::gen::TrackEvent::TYPE_INSTANT) {
2164       EXPECT_EQ(789, track_event.legacy_event().pid_override());
2165       EXPECT_EQ(-1, track_event.legacy_event().tid_override());
2166       found_event = true;
2167     }
2168   }
2169   EXPECT_TRUE(found_event);
2170 }
2171 
TEST_P(PerfettoApiTest,TrackDescriptorWrittenBeforeEvent)2172 TEST_P(PerfettoApiTest, TrackDescriptorWrittenBeforeEvent) {
2173   // Create a new trace session.
2174   auto* tracing_session = NewTraceWithCategories({"bar"});
2175   tracing_session->get()->StartBlocking();
2176 
2177   // Emit an event on a custom track.
2178   TRACE_EVENT_INSTANT("bar", "Event", perfetto::Track(8086));
2179   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2180 
2181   // Check that the descriptor was written before the event.
2182   std::set<uint64_t> seen_descriptors;
2183   for (const auto& packet : trace.packet()) {
2184     if (packet.has_track_descriptor())
2185       seen_descriptors.insert(packet.track_descriptor().uuid());
2186 
2187     if (!packet.has_track_event())
2188       continue;
2189     auto track_event = packet.track_event();
2190     EXPECT_TRUE(seen_descriptors.find(track_event.track_uuid()) !=
2191                 seen_descriptors.end());
2192   }
2193 }
2194 
TEST_P(PerfettoApiTest,TrackEventCustomTrackAndTimestamp)2195 TEST_P(PerfettoApiTest, TrackEventCustomTrackAndTimestamp) {
2196   // Create a new trace session.
2197   auto* tracing_session = NewTraceWithCategories({"bar"});
2198   tracing_session->get()->StartBlocking();
2199 
2200   // Custom track.
2201   perfetto::Track track(789);
2202 
2203   auto empty_lambda = [](perfetto::EventContext) {};
2204   constexpr uint64_t kBeginEventTime = 10;
2205   const MyTimestamp kEndEventTime{15};
2206   TRACE_EVENT_BEGIN("bar", "Event", track, kBeginEventTime, empty_lambda);
2207   TRACE_EVENT_END("bar", track, kEndEventTime, empty_lambda);
2208 
2209   constexpr uint64_t kInstantEventTime = 1;
2210   TRACE_EVENT_INSTANT("bar", "InstantEvent", track, kInstantEventTime,
2211                       empty_lambda);
2212 
2213   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2214 
2215   int event_count = 0;
2216   for (const auto& packet : trace.packet()) {
2217     if (!packet.has_track_event())
2218       continue;
2219 
2220     EXPECT_EQ(packet.timestamp_clock_id(),
2221               static_cast<uint32_t>(perfetto::TrackEvent::GetTraceClockId()));
2222     event_count++;
2223     switch (packet.track_event().type()) {
2224       case perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN:
2225         EXPECT_EQ(packet.timestamp(), kBeginEventTime);
2226         break;
2227       case perfetto::protos::gen::TrackEvent::TYPE_SLICE_END:
2228         EXPECT_EQ(packet.timestamp(), kEndEventTime.ts);
2229         break;
2230       case perfetto::protos::gen::TrackEvent::TYPE_INSTANT:
2231         EXPECT_EQ(packet.timestamp(), kInstantEventTime);
2232         break;
2233       case perfetto::protos::gen::TrackEvent::TYPE_COUNTER:
2234       case perfetto::protos::gen::TrackEvent::TYPE_UNSPECIFIED:
2235         ADD_FAILURE();
2236     }
2237   }
2238   EXPECT_EQ(event_count, 3);
2239   perfetto::TrackEvent::EraseTrackDescriptor(track);
2240 }
2241 
TEST_P(PerfettoApiTest,TrackEventCustomTrackAndTimestampNoLambda)2242 TEST_P(PerfettoApiTest, TrackEventCustomTrackAndTimestampNoLambda) {
2243   auto* tracing_session = NewTraceWithCategories({"bar"});
2244   tracing_session->get()->StartBlocking();
2245 
2246   perfetto::Track track(789);
2247 
2248   constexpr uint64_t kBeginEventTime = 10;
2249   constexpr uint64_t kEndEventTime = 15;
2250   TRACE_EVENT_BEGIN("bar", "Event", track, kBeginEventTime);
2251   TRACE_EVENT_END("bar", track, kEndEventTime);
2252 
2253   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2254 
2255   int event_count = 0;
2256   for (const auto& packet : trace.packet()) {
2257     if (!packet.has_track_event())
2258       continue;
2259     event_count++;
2260     switch (packet.track_event().type()) {
2261       case perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN:
2262         EXPECT_EQ(packet.timestamp(), kBeginEventTime);
2263         break;
2264       case perfetto::protos::gen::TrackEvent::TYPE_SLICE_END:
2265         EXPECT_EQ(packet.timestamp(), kEndEventTime);
2266         break;
2267       case perfetto::protos::gen::TrackEvent::TYPE_INSTANT:
2268       case perfetto::protos::gen::TrackEvent::TYPE_COUNTER:
2269       case perfetto::protos::gen::TrackEvent::TYPE_UNSPECIFIED:
2270         ADD_FAILURE();
2271     }
2272   }
2273 
2274   EXPECT_EQ(event_count, 2);
2275 }
2276 
TEST_P(PerfettoApiTest,TrackEventAnonymousCustomTrack)2277 TEST_P(PerfettoApiTest, TrackEventAnonymousCustomTrack) {
2278   // Create a new trace session.
2279   auto* tracing_session = NewTraceWithCategories({"bar"});
2280   tracing_session->get()->StartBlocking();
2281 
2282   // Emit an async event without giving it an explicit descriptor.
2283   uint64_t async_id = 4004;
2284   auto track = perfetto::Track(async_id, perfetto::ThreadTrack::Current());
2285   TRACE_EVENT_BEGIN("bar", "AsyncEvent", track);
2286   std::thread thread([&] { TRACE_EVENT_END("bar", track); });
2287   thread.join();
2288 
2289   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2290 
2291   // Check that a descriptor for the track was emitted.
2292   bool found_descriptor = false;
2293   for (const auto& packet : trace.packet()) {
2294     if (packet.has_track_descriptor() &&
2295         !packet.track_descriptor().has_process() &&
2296         !packet.track_descriptor().has_thread()) {
2297       auto td = packet.track_descriptor();
2298       EXPECT_EQ(track.uuid, td.uuid());
2299       EXPECT_EQ(perfetto::ThreadTrack::Current().uuid, td.parent_uuid());
2300       found_descriptor = true;
2301     }
2302   }
2303   EXPECT_TRUE(found_descriptor);
2304 }
2305 
TEST_P(PerfettoApiTest,TrackEventTypedArgs)2306 TEST_P(PerfettoApiTest, TrackEventTypedArgs) {
2307   // Create a new trace session.
2308   auto* tracing_session = NewTraceWithCategories({"foo"});
2309   tracing_session->get()->StartBlocking();
2310 
2311   auto random_value = rand();
2312   TRACE_EVENT_BEGIN("foo", "EventWithTypedArg",
2313                     [random_value](perfetto::EventContext ctx) {
2314                       auto* log = ctx.event()->set_log_message();
2315                       log->set_source_location_iid(1);
2316                       log->set_body_iid(2);
2317                       auto* dbg = ctx.event()->add_debug_annotations();
2318                       dbg->set_name("random");
2319                       dbg->set_int_value(random_value);
2320                     });
2321   TRACE_EVENT_END("foo");
2322 
2323   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2324 
2325   bool found_args = false;
2326   for (const auto& packet : trace.packet()) {
2327     if (!packet.has_track_event())
2328       continue;
2329     const auto& track_event = packet.track_event();
2330     if (track_event.type() !=
2331         perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN)
2332       continue;
2333 
2334     EXPECT_TRUE(track_event.has_log_message());
2335     const auto& log = track_event.log_message();
2336     EXPECT_EQ(1u, log.source_location_iid());
2337     EXPECT_EQ(2u, log.body_iid());
2338 
2339     const auto& dbg = track_event.debug_annotations()[0];
2340     EXPECT_EQ("random", dbg.name());
2341     EXPECT_EQ(random_value, dbg.int_value());
2342 
2343     found_args = true;
2344   }
2345   EXPECT_TRUE(found_args);
2346 }
2347 
TEST_P(PerfettoApiTest,InlineTrackEventTypedArgs_SimpleRepeated)2348 TEST_P(PerfettoApiTest, InlineTrackEventTypedArgs_SimpleRepeated) {
2349   // Create a new trace session.
2350   auto* tracing_session = NewTraceWithCategories({"foo"});
2351   tracing_session->get()->StartBlocking();
2352 
2353   std::vector<uint64_t> flow_ids_old{1, 2, 3};
2354   std::vector<uint64_t> flow_ids{4, 5, 6};
2355   TRACE_EVENT_BEGIN("foo", "EventWithTypedArg",
2356                     perfetto::protos::pbzero::TrackEvent::kFlowIdsOld,
2357                     flow_ids_old,
2358                     perfetto::protos::pbzero::TrackEvent::kFlowIds, flow_ids);
2359   TRACE_EVENT_END("foo");
2360 
2361   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2362 
2363   bool found_args = false;
2364   for (const auto& packet : trace.packet()) {
2365     if (!packet.has_track_event())
2366       continue;
2367     const auto& track_event = packet.track_event();
2368     if (track_event.type() !=
2369         perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN) {
2370       continue;
2371     }
2372 
2373     EXPECT_THAT(track_event.flow_ids_old(), testing::ElementsAre(1u, 2u, 3u));
2374     EXPECT_THAT(track_event.flow_ids(), testing::ElementsAre(4u, 5u, 6u));
2375     found_args = true;
2376   }
2377   EXPECT_TRUE(found_args);
2378 }
2379 
2380 namespace {
2381 
2382 struct LogMessage {
WriteIntoTrace__anon1b44a82b0111::__anon1b44a82b0f11::LogMessage2383   void WriteIntoTrace(
2384       perfetto::TracedProto<perfetto::protos::pbzero::LogMessage> context)
2385       const {
2386     context->set_source_location_iid(1);
2387     context->set_body_iid(2);
2388   }
2389 };
2390 
__anon1b44a82b1002() 2391 auto GetWriteLogMessageRefLambda = []() {
2392   return [](perfetto::EventContext& ctx) {
2393     auto* log = ctx.event()->set_log_message();
2394     log->set_source_location_iid(1);
2395     log->set_body_iid(2);
2396   };
2397 };
2398 
CheckTypedArguments(const std::vector<char> & raw_trace,const char * event_name,perfetto::protos::gen::TrackEvent::Type type,std::function<void (const perfetto::protos::gen::TrackEvent &)> checker)2399 void CheckTypedArguments(
2400     const std::vector<char>& raw_trace,
2401     const char* event_name,
2402     perfetto::protos::gen::TrackEvent::Type type,
2403     std::function<void(const perfetto::protos::gen::TrackEvent&)> checker) {
2404   perfetto::protos::gen::Trace parsed_trace;
2405   ASSERT_TRUE(parsed_trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
2406 
2407   bool found_slice = false;
2408   ParsedIncrementalState incremental_state;
2409 
2410   for (const auto& packet : parsed_trace.packet()) {
2411     incremental_state.ClearIfNeeded(packet);
2412     incremental_state.Parse(packet);
2413 
2414     if (!packet.has_track_event())
2415       continue;
2416     const auto& track_event = packet.track_event();
2417     if (track_event.type() != type) {
2418       continue;
2419     }
2420     if (event_name &&
2421         incremental_state.GetEventName(track_event) != event_name) {
2422       continue;
2423     }
2424 
2425     checker(track_event);
2426     found_slice = true;
2427   }
2428   EXPECT_TRUE(found_slice);
2429 }
2430 
CheckLogMessagePresent(const std::vector<char> & raw_trace)2431 void CheckLogMessagePresent(const std::vector<char>& raw_trace) {
2432   CheckTypedArguments(raw_trace, nullptr,
2433                       perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN,
2434                       [](const perfetto::protos::gen::TrackEvent& track_event) {
2435                         EXPECT_TRUE(track_event.has_log_message());
2436                         const auto& log = track_event.log_message();
2437                         EXPECT_EQ(1u, log.source_location_iid());
2438                         EXPECT_EQ(2u, log.body_iid());
2439                       });
2440 }
2441 
2442 }  // namespace
2443 
TEST_P(PerfettoApiTest,InlineTrackEventTypedArgs_NestedSingle)2444 TEST_P(PerfettoApiTest, InlineTrackEventTypedArgs_NestedSingle) {
2445   // Create a new trace session.
2446   auto* tracing_session = NewTraceWithCategories({"foo"});
2447   tracing_session->get()->StartBlocking();
2448 
2449   TRACE_EVENT_BEGIN("foo", "EventWithTypedArg",
2450                     perfetto::protos::pbzero::TrackEvent::kLogMessage,
2451                     LogMessage());
2452   TRACE_EVENT_END("foo");
2453 
2454   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2455 }
2456 
TEST_P(PerfettoApiTest,TrackEventThreadTime)2457 TEST_P(PerfettoApiTest, TrackEventThreadTime) {
2458   for (auto enable_thread_time : {true, false}) {
2459     perfetto::protos::gen::TrackEventConfig te_cfg;
2460     te_cfg.set_enable_thread_time_sampling(enable_thread_time);
2461     auto* tracing_session = NewTraceWithCategories({"foo"}, te_cfg);
2462 
2463     tracing_session->get()->StartBlocking();
2464 
2465     perfetto::Track custom_track(1);
2466 
2467     TRACE_EVENT_BEGIN("foo", "event1");
2468     TRACE_EVENT_BEGIN("foo", "event2");
2469     TRACE_EVENT_BEGIN("foo", "event3");
2470     TRACE_EVENT_BEGIN("foo", "event4", custom_track);
2471     TRACE_EVENT_END("foo");
2472     TRACE_EVENT_END("foo");
2473     TRACE_EVENT_END("foo");
2474     TRACE_EVENT_END("foo");
2475 
2476     auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2477 
2478     bool found_counter_track_descriptor = false;
2479     uint64_t thread_time_counter_uuid = 0;
2480     uint64_t default_counter_uuid = 0;
2481     std::unordered_set<std::string> event_names;
2482     for (const auto& packet : trace.packet()) {
2483       if (packet.has_track_descriptor() &&
2484           packet.track_descriptor().has_counter()) {
2485         EXPECT_FALSE(found_counter_track_descriptor);
2486         found_counter_track_descriptor = true;
2487         thread_time_counter_uuid = packet.track_descriptor().uuid();
2488         EXPECT_EQ("thread_time", packet.track_descriptor().static_name());
2489         auto counter = packet.track_descriptor().counter();
2490         EXPECT_EQ(
2491             perfetto::protos::gen::
2492                 CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_TIME_NS,
2493             counter.type());
2494         EXPECT_TRUE(counter.is_incremental());
2495       }
2496       if (packet.has_trace_packet_defaults()) {
2497         auto& defaults = packet.trace_packet_defaults().track_event_defaults();
2498         ASSERT_EQ(enable_thread_time ? 1u : 0u,
2499                   defaults.extra_counter_track_uuids().size());
2500         if (enable_thread_time) {
2501           default_counter_uuid = defaults.extra_counter_track_uuids().at(0);
2502         }
2503       }
2504       if (packet.has_track_event()) {
2505         std::string event_name;
2506         if (packet.has_interned_data()) {
2507           auto& event_names_info = packet.interned_data().event_names();
2508           if (event_names_info.size() > 0) {
2509             event_name = event_names_info[0].name();
2510           }
2511         }
2512         event_names.insert(event_name);
2513         EXPECT_EQ((enable_thread_time && event_name != "event4") ? 1u : 0u,
2514                   packet.track_event().extra_counter_values().size());
2515       }
2516     }
2517     EXPECT_TRUE(ContainsKey(event_names, "event1"));
2518     EXPECT_TRUE(ContainsKey(event_names, "event2"));
2519     EXPECT_TRUE(ContainsKey(event_names, "event3"));
2520     EXPECT_TRUE(ContainsKey(event_names, "event4"));
2521     EXPECT_EQ(enable_thread_time, found_counter_track_descriptor);
2522     EXPECT_EQ(default_counter_uuid, thread_time_counter_uuid);
2523     if (enable_thread_time) {
2524       EXPECT_GT(thread_time_counter_uuid, 0u);
2525     } else {
2526       EXPECT_EQ(thread_time_counter_uuid, 0u);
2527     }
2528   }
2529 }
2530 
TEST_P(PerfettoApiTest,TrackEventArgs_TypedAndUntyped)2531 TEST_P(PerfettoApiTest, TrackEventArgs_TypedAndUntyped) {
2532   // Create a new trace session.
2533   auto* tracing_session = NewTraceWithCategories({"foo"});
2534   tracing_session->get()->StartBlocking();
2535 
2536   TRACE_EVENT_BEGIN("foo", "E",
2537                     perfetto::protos::pbzero::TrackEvent::kLogMessage,
2538                     LogMessage(), "arg", "value");
2539   TRACE_EVENT_END("foo");
2540 
2541   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2542   std::string trace(raw_trace.data(), raw_trace.size());
2543 
2544   // Find typed argument.
2545   CheckLogMessagePresent(raw_trace);
2546 
2547   // Find untyped argument.
2548   EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
2549               ElementsAre("B:foo.E(arg=(string)value)", "E"));
2550 }
2551 
TEST_P(PerfettoApiTest,TrackEventArgs_UntypedAndTyped)2552 TEST_P(PerfettoApiTest, TrackEventArgs_UntypedAndTyped) {
2553   // Create a new trace session.
2554   auto* tracing_session = NewTraceWithCategories({"foo"});
2555   tracing_session->get()->StartBlocking();
2556 
2557   TRACE_EVENT_BEGIN("foo", "E", "arg", "value",
2558                     perfetto::protos::pbzero::TrackEvent::kLogMessage,
2559                     LogMessage());
2560   TRACE_EVENT_END("foo");
2561 
2562   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2563 
2564   // Find typed argument.
2565   CheckLogMessagePresent(raw_trace);
2566 
2567   // Find untyped argument.
2568   EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
2569               ElementsAre("B:foo.E(arg=(string)value)", "E"));
2570 }
2571 
TEST_P(PerfettoApiTest,TrackEventArgs_UntypedAndRefLambda)2572 TEST_P(PerfettoApiTest, TrackEventArgs_UntypedAndRefLambda) {
2573   // Create a new trace session.
2574   auto* tracing_session = NewTraceWithCategories({"foo"});
2575   tracing_session->get()->StartBlocking();
2576 
2577   TRACE_EVENT_BEGIN("foo", "E", "arg", "value", GetWriteLogMessageRefLambda());
2578   TRACE_EVENT_END("foo");
2579 
2580   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2581 
2582   // Find typed argument.
2583   CheckLogMessagePresent(raw_trace);
2584 
2585   // Find untyped argument.
2586   EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
2587               ElementsAre("B:foo.E(arg=(string)value)", "E"));
2588 }
2589 
TEST_P(PerfettoApiTest,TrackEventArgs_RefLambdaAndUntyped)2590 TEST_P(PerfettoApiTest, TrackEventArgs_RefLambdaAndUntyped) {
2591   // Create a new trace session.
2592   auto* tracing_session = NewTraceWithCategories({"foo"});
2593   tracing_session->get()->StartBlocking();
2594 
2595   TRACE_EVENT_BEGIN("foo", "E", GetWriteLogMessageRefLambda(), "arg", "value");
2596   TRACE_EVENT_END("foo");
2597 
2598   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2599 
2600   // Find typed argument.
2601   CheckLogMessagePresent(raw_trace);
2602 
2603   // Find untyped argument.
2604   EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
2605               ElementsAre("B:foo.E(arg=(string)value)", "E"));
2606 }
2607 
TEST_P(PerfettoApiTest,TrackEventArgs_RefLambdaAndTyped)2608 TEST_P(PerfettoApiTest, TrackEventArgs_RefLambdaAndTyped) {
2609   // Create a new trace session.
2610   auto* tracing_session = NewTraceWithCategories({"foo"});
2611   tracing_session->get()->StartBlocking();
2612 
2613   TRACE_EVENT_BEGIN(
2614       "foo", "E",
2615       [](perfetto::EventContext& ctx) {
2616         ctx.AddDebugAnnotation("arg", "value");
2617       },
2618       perfetto::protos::pbzero::TrackEvent::kLogMessage, LogMessage());
2619   TRACE_EVENT_END("foo");
2620 
2621   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2622 
2623   // Find typed argument.
2624   CheckLogMessagePresent(raw_trace);
2625 
2626   // Find untyped argument.
2627   EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
2628               ElementsAre("B:foo.E(arg=(string)value)", "E"));
2629 }
2630 
TEST_P(PerfettoApiTest,TrackEventArgs_TypedAndRefLambda)2631 TEST_P(PerfettoApiTest, TrackEventArgs_TypedAndRefLambda) {
2632   // Create a new trace session.
2633   auto* tracing_session = NewTraceWithCategories({"foo"});
2634   tracing_session->get()->StartBlocking();
2635 
2636   TRACE_EVENT_BEGIN("foo", "E",
2637                     perfetto::protos::pbzero::TrackEvent::kLogMessage,
2638                     LogMessage(), [](perfetto::EventContext& ctx) {
2639                       ctx.AddDebugAnnotation("arg", "value");
2640                     });
2641   TRACE_EVENT_END("foo");
2642 
2643   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2644 
2645   // Find typed argument.
2646   CheckLogMessagePresent(raw_trace);
2647 
2648   // Find untyped argument.
2649   EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
2650               ElementsAre("B:foo.E(arg=(string)value)", "E"));
2651 }
2652 
TEST_P(PerfettoApiTest,TrackEventArgs_RefLambdaAndRefLambda)2653 TEST_P(PerfettoApiTest, TrackEventArgs_RefLambdaAndRefLambda) {
2654   // Create a new trace session.
2655   auto* tracing_session = NewTraceWithCategories({"foo"});
2656   tracing_session->get()->StartBlocking();
2657 
2658   TRACE_EVENT_BEGIN(
2659       "foo", "E",
2660       [](perfetto::EventContext& ctx) {
2661         ctx.AddDebugAnnotation("arg1", "value1");
2662       },
2663       [](perfetto::EventContext& ctx) {
2664         ctx.AddDebugAnnotation("arg2", "value2");
2665       });
2666   TRACE_EVENT_END("foo");
2667 
2668   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2669 
2670   // Find untyped arguments.
2671   EXPECT_THAT(
2672       ReadSlicesFromTrace(raw_trace),
2673       ElementsAre("B:foo.E(arg1=(string)value1,arg2=(string)value2)", "E"));
2674 }
2675 
TEST_P(PerfettoApiTest,TrackEventArgs_RefLambdaAndLambda)2676 TEST_P(PerfettoApiTest, TrackEventArgs_RefLambdaAndLambda) {
2677   // Create a new trace session.
2678   auto* tracing_session = NewTraceWithCategories({"foo"});
2679   tracing_session->get()->StartBlocking();
2680 
2681   TRACE_EVENT_BEGIN(
2682       "foo", "E",
2683       [](perfetto::EventContext& ctx) {
2684         ctx.AddDebugAnnotation("arg1", "value1");
2685       },
2686       [](perfetto::EventContext ctx) {
2687         ctx.AddDebugAnnotation("arg2", "value2");
2688       });
2689   TRACE_EVENT_END("foo");
2690 
2691   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2692 
2693   // Find untyped arguments.
2694   EXPECT_THAT(
2695       ReadSlicesFromTrace(raw_trace),
2696       ElementsAre("B:foo.E(arg1=(string)value1,arg2=(string)value2)", "E"));
2697 }
2698 
TEST_P(PerfettoApiTest,TrackEventArgs_RefLambda)2699 TEST_P(PerfettoApiTest, TrackEventArgs_RefLambda) {
2700   // Create a new trace session.
2701   auto* tracing_session = NewTraceWithCategories({"foo"});
2702   tracing_session->get()->StartBlocking();
2703 
2704   TRACE_EVENT_BEGIN("foo", "E", [](perfetto::EventContext& ctx) {
2705     ctx.AddDebugAnnotation("arg", "value");
2706   });
2707   TRACE_EVENT_END("foo");
2708 
2709   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2710 
2711   // Find untyped argument.
2712   EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
2713               ElementsAre("B:foo.E(arg=(string)value)", "E"));
2714 }
2715 
TEST_P(PerfettoApiTest,TrackEventArgs_Flow_Global)2716 TEST_P(PerfettoApiTest, TrackEventArgs_Flow_Global) {
2717   // Create a new trace session.
2718   auto* tracing_session = NewTraceWithCategories({"foo"});
2719   tracing_session->get()->StartBlocking();
2720 
2721   TRACE_EVENT_INSTANT("foo", "E1", perfetto::Flow::Global(42));
2722   TRACE_EVENT_INSTANT("foo", "E2", perfetto::TerminatingFlow::Global(42));
2723 
2724   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2725 
2726   // Find typed argument.
2727   CheckTypedArguments(
2728       raw_trace, "E1", perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
2729       [](const perfetto::protos::gen::TrackEvent& track_event) {
2730         EXPECT_TRUE(track_event.flow_ids_old().empty());
2731         EXPECT_THAT(track_event.flow_ids(), testing::ElementsAre(42u));
2732       });
2733 }
2734 
TEST_P(PerfettoApiTest,TrackEventArgs_Lambda_Multisession)2735 TEST_P(PerfettoApiTest, TrackEventArgs_Lambda_Multisession) {
2736   // Create two simultaneous tracing sessions.
2737   auto* tracing_session = NewTraceWithCategories({"foo"});
2738   auto* tracing_session2 = NewTraceWithCategories({"foo"});
2739   tracing_session->get()->StartBlocking();
2740   tracing_session2->get()->StartBlocking();
2741 
2742   // Emit an event in both sessions using an argument function.
2743   auto make_arg = []() -> std::function<void(perfetto::EventContext&)> {
2744     return [](perfetto::EventContext& ctx) {
2745       ctx.event()->set_type(perfetto::protos::pbzero::TrackEvent::TYPE_INSTANT);
2746       ctx.event()->add_flow_ids(42);
2747     };
2748   };
2749   TRACE_EVENT_INSTANT("foo", "E1", make_arg());
2750 
2751   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2752   std::vector<char> raw_trace2 = StopSessionAndReturnBytes(tracing_session2);
2753 
2754   // Check that the event was output twice.
2755   CheckTypedArguments(
2756       raw_trace, "E1", perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
2757       [](const perfetto::protos::gen::TrackEvent& track_event) {
2758         EXPECT_TRUE(track_event.flow_ids_old().empty());
2759         EXPECT_THAT(track_event.flow_ids(), testing::ElementsAre(42u));
2760       });
2761   CheckTypedArguments(
2762       raw_trace2, "E1", perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
2763       [](const perfetto::protos::gen::TrackEvent& track_event) {
2764         EXPECT_TRUE(track_event.flow_ids_old().empty());
2765         EXPECT_THAT(track_event.flow_ids(), testing::ElementsAre(42u));
2766       });
2767 }
2768 
TEST_P(PerfettoApiTest,TrackEventArgs_MultipleFlows)2769 TEST_P(PerfettoApiTest, TrackEventArgs_MultipleFlows) {
2770   // Create a new trace session.
2771   auto* tracing_session = NewTraceWithCategories({"foo"});
2772   tracing_session->get()->StartBlocking();
2773 
2774   {
2775     TRACE_EVENT("foo", "E1", perfetto::Flow::Global(1),
2776                 perfetto::Flow::Global(2), perfetto::Flow::Global(3));
2777   }
2778   {
2779     TRACE_EVENT("foo", "E2", perfetto::Flow::Global(1),
2780                 perfetto::TerminatingFlow::Global(2));
2781   }
2782   { TRACE_EVENT("foo", "E3", perfetto::TerminatingFlow::Global(3)); }
2783 
2784   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2785   EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
2786               ElementsAre("B:foo.E1(flow_ids=1,2,3)", "E",
2787                           "B:foo.E2(flow_ids=1)(terminating_flow_ids=2)", "E",
2788                           "B:foo.E3(terminating_flow_ids=3)", "E"));
2789 }
2790 
TEST_P(PerfettoApiTest,TrackEventArgs_Flow_ProcessScoped)2791 TEST_P(PerfettoApiTest, TrackEventArgs_Flow_ProcessScoped) {
2792   // Create a new trace session.
2793   auto* tracing_session = NewTraceWithCategories({"foo"});
2794   tracing_session->get()->StartBlocking();
2795 
2796   TRACE_EVENT_INSTANT("foo", "E1", perfetto::Flow::ProcessScoped(1));
2797   TRACE_EVENT_INSTANT("foo", "E2", perfetto::TerminatingFlow::ProcessScoped(1));
2798   TRACE_EVENT_INSTANT("foo", "Flush");
2799 
2800   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2801 
2802   // Find typed arguments.
2803   CheckTypedArguments(raw_trace, "E1",
2804                       perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
2805                       [](const perfetto::protos::gen::TrackEvent& track_event) {
2806                         EXPECT_EQ(track_event.flow_ids_old_size(), 0);
2807                         EXPECT_EQ(track_event.flow_ids_size(), 1);
2808                       });
2809   CheckTypedArguments(
2810       raw_trace, "E2", perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
2811       [](const perfetto::protos::gen::TrackEvent& track_event) {
2812         EXPECT_EQ(track_event.terminating_flow_ids_old_size(), 0);
2813         EXPECT_EQ(track_event.terminating_flow_ids_size(), 1);
2814       });
2815 }
2816 
TEST_P(PerfettoApiTest,TrackEventArgs_Flow_FromPointer)2817 TEST_P(PerfettoApiTest, TrackEventArgs_Flow_FromPointer) {
2818   // Create a new trace session.
2819   auto* tracing_session = NewTraceWithCategories({"foo"});
2820   tracing_session->get()->StartBlocking();
2821 
2822   int a;
2823   int* ptr = &a;
2824   TRACE_EVENT_INSTANT("foo", "E1", perfetto::Flow::FromPointer(ptr));
2825   TRACE_EVENT_INSTANT("foo", "E2", perfetto::TerminatingFlow::FromPointer(ptr));
2826   TRACE_EVENT_INSTANT("foo", "Flush");
2827 
2828   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2829 
2830   // Find typed arguments.
2831   CheckTypedArguments(raw_trace, "E1",
2832                       perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
2833                       [](const perfetto::protos::gen::TrackEvent& track_event) {
2834                         EXPECT_EQ(track_event.flow_ids_old_size(), 0);
2835                         EXPECT_EQ(track_event.flow_ids_size(), 1);
2836                       });
2837   CheckTypedArguments(
2838       raw_trace, "E2", perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
2839       [](const perfetto::protos::gen::TrackEvent& track_event) {
2840         EXPECT_EQ(track_event.terminating_flow_ids_old_size(), 0);
2841         EXPECT_EQ(track_event.terminating_flow_ids_size(), 1);
2842       });
2843 }
2844 
2845 struct InternedLogMessageBody
2846     : public perfetto::TrackEventInternedDataIndex<
2847           InternedLogMessageBody,
2848           perfetto::protos::pbzero::InternedData::kLogMessageBodyFieldNumber,
2849           std::string> {
Add__anon1b44a82b0111::InternedLogMessageBody2850   static void Add(perfetto::protos::pbzero::InternedData* interned_data,
2851                   size_t iid,
2852                   const std::string& value) {
2853     auto l = interned_data->add_log_message_body();
2854     l->set_iid(iid);
2855     l->set_body(value.data(), value.size());
2856     commit_count++;
2857   }
2858 
2859   static int commit_count;
2860 };
2861 
2862 int InternedLogMessageBody::commit_count = 0;
2863 
TEST_P(PerfettoApiTest,TrackEventTypedArgsWithInterning)2864 TEST_P(PerfettoApiTest, TrackEventTypedArgsWithInterning) {
2865   // Create a new trace session.
2866   auto* tracing_session = NewTraceWithCategories({"foo"});
2867   tracing_session->get()->StartBlocking();
2868 
2869   std::stringstream large_message;
2870   for (size_t i = 0; i < 512; i++)
2871     large_message << i << ". Something wicked this way comes. ";
2872 
2873   size_t body_iid;
2874   InternedLogMessageBody::commit_count = 0;
2875   TRACE_EVENT_BEGIN("foo", "EventWithState", [&](perfetto::EventContext ctx) {
2876     EXPECT_EQ(0, InternedLogMessageBody::commit_count);
2877     body_iid = InternedLogMessageBody::Get(&ctx, "Alas, poor Yorick!");
2878     auto log = ctx.event()->set_log_message();
2879     log->set_body_iid(body_iid);
2880     EXPECT_EQ(1, InternedLogMessageBody::commit_count);
2881 
2882     auto body_iid2 = InternedLogMessageBody::Get(&ctx, "Alas, poor Yorick!");
2883     EXPECT_EQ(body_iid, body_iid2);
2884     EXPECT_EQ(1, InternedLogMessageBody::commit_count);
2885   });
2886   TRACE_EVENT_END("foo");
2887 
2888   TRACE_EVENT_BEGIN("foo", "EventWithState", [&](perfetto::EventContext ctx) {
2889     // Check that very large amounts of interned data works.
2890     auto log = ctx.event()->set_log_message();
2891     log->set_body_iid(InternedLogMessageBody::Get(&ctx, large_message.str()));
2892     EXPECT_EQ(2, InternedLogMessageBody::commit_count);
2893   });
2894   TRACE_EVENT_END("foo");
2895 
2896   // Make sure interned data persists across trace points.
2897   TRACE_EVENT_BEGIN("foo", "EventWithState", [&](perfetto::EventContext ctx) {
2898     auto body_iid2 = InternedLogMessageBody::Get(&ctx, "Alas, poor Yorick!");
2899     EXPECT_EQ(body_iid, body_iid2);
2900 
2901     auto body_iid3 = InternedLogMessageBody::Get(&ctx, "I knew him, Horatio");
2902     EXPECT_NE(body_iid, body_iid3);
2903     auto log = ctx.event()->set_log_message();
2904     log->set_body_iid(body_iid3);
2905     EXPECT_EQ(3, InternedLogMessageBody::commit_count);
2906   });
2907   TRACE_EVENT_END("foo");
2908 
2909   tracing_session->get()->StopBlocking();
2910   auto log_messages = ReadLogMessagesFromTrace(tracing_session->get());
2911   EXPECT_THAT(log_messages,
2912               ElementsAre("Alas, poor Yorick!", large_message.str(),
2913                           "I knew him, Horatio"));
2914 }
2915 
2916 struct InternedLogMessageBodySmall
2917     : public perfetto::TrackEventInternedDataIndex<
2918           InternedLogMessageBodySmall,
2919           perfetto::protos::pbzero::InternedData::kLogMessageBodyFieldNumber,
2920           const char*,
2921           perfetto::SmallInternedDataTraits> {
Add__anon1b44a82b0111::InternedLogMessageBodySmall2922   static void Add(perfetto::protos::pbzero::InternedData* interned_data,
2923                   size_t iid,
2924                   const char* value) {
2925     auto l = interned_data->add_log_message_body();
2926     l->set_iid(iid);
2927     l->set_body(value);
2928   }
2929 };
2930 
TEST_P(PerfettoApiTest,TrackEventTypedArgsWithInterningByValue)2931 TEST_P(PerfettoApiTest, TrackEventTypedArgsWithInterningByValue) {
2932   // Create a new trace session.
2933   auto* tracing_session = NewTraceWithCategories({"foo"});
2934   tracing_session->get()->StartBlocking();
2935 
2936   size_t body_iid;
2937   TRACE_EVENT_BEGIN("foo", "EventWithState", [&](perfetto::EventContext ctx) {
2938     body_iid = InternedLogMessageBodySmall::Get(&ctx, "This above all:");
2939     auto log = ctx.event()->set_log_message();
2940     log->set_body_iid(body_iid);
2941 
2942     auto body_iid2 = InternedLogMessageBodySmall::Get(&ctx, "This above all:");
2943     EXPECT_EQ(body_iid, body_iid2);
2944 
2945     auto body_iid3 =
2946         InternedLogMessageBodySmall::Get(&ctx, "to thine own self be true");
2947     EXPECT_NE(body_iid, body_iid3);
2948   });
2949   TRACE_EVENT_END("foo");
2950 
2951   tracing_session->get()->StopBlocking();
2952   auto log_messages = ReadLogMessagesFromTrace(tracing_session->get());
2953   EXPECT_THAT(log_messages, ElementsAre("This above all:"));
2954 }
2955 
2956 struct InternedLogMessageBodyHashed
2957     : public perfetto::TrackEventInternedDataIndex<
2958           InternedLogMessageBodyHashed,
2959           perfetto::protos::pbzero::InternedData::kLogMessageBodyFieldNumber,
2960           std::string,
2961           perfetto::HashedInternedDataTraits> {
Add__anon1b44a82b0111::InternedLogMessageBodyHashed2962   static void Add(perfetto::protos::pbzero::InternedData* interned_data,
2963                   size_t iid,
2964                   const std::string& value) {
2965     auto l = interned_data->add_log_message_body();
2966     l->set_iid(iid);
2967     l->set_body(value.data(), value.size());
2968   }
2969 };
2970 
TEST_P(PerfettoApiTest,TrackEventTypedArgsWithInterningByHashing)2971 TEST_P(PerfettoApiTest, TrackEventTypedArgsWithInterningByHashing) {
2972   // Create a new trace session.
2973   auto* tracing_session = NewTraceWithCategories({"foo"});
2974   tracing_session->get()->StartBlocking();
2975 
2976   size_t body_iid;
2977   TRACE_EVENT_BEGIN("foo", "EventWithState", [&](perfetto::EventContext ctx) {
2978     // Test using a dynamically created interned value.
2979     body_iid = InternedLogMessageBodyHashed::Get(
2980         &ctx, std::string("Though this ") + "be madness,");
2981     auto log = ctx.event()->set_log_message();
2982     log->set_body_iid(body_iid);
2983 
2984     auto body_iid2 =
2985         InternedLogMessageBodyHashed::Get(&ctx, "Though this be madness,");
2986     EXPECT_EQ(body_iid, body_iid2);
2987 
2988     auto body_iid3 =
2989         InternedLogMessageBodyHashed::Get(&ctx, "yet there is method in’t");
2990     EXPECT_NE(body_iid, body_iid3);
2991   });
2992   TRACE_EVENT_END("foo");
2993 
2994   tracing_session->get()->StopBlocking();
2995   auto log_messages = ReadLogMessagesFromTrace(tracing_session->get());
2996   EXPECT_THAT(log_messages, ElementsAre("Though this be madness,"));
2997 }
2998 
2999 struct InternedSourceLocation
3000     : public perfetto::TrackEventInternedDataIndex<
3001           InternedSourceLocation,
3002           perfetto::protos::pbzero::InternedData::kSourceLocationsFieldNumber,
3003           SourceLocation> {
Add__anon1b44a82b0111::InternedSourceLocation3004   static void Add(perfetto::protos::pbzero::InternedData* interned_data,
3005                   size_t iid,
3006                   const SourceLocation& value) {
3007     auto l = interned_data->add_source_locations();
3008     auto file_name = std::get<0>(value);
3009     auto function_name = std::get<1>(value);
3010     auto line_number = std::get<2>(value);
3011     l->set_iid(iid);
3012     l->set_file_name(file_name);
3013     l->set_function_name(function_name);
3014     l->set_line_number(line_number);
3015   }
3016 };
3017 
TEST_P(PerfettoApiTest,TrackEventTypedArgsWithInterningComplexValue)3018 TEST_P(PerfettoApiTest, TrackEventTypedArgsWithInterningComplexValue) {
3019   // Create a new trace session.
3020   auto* tracing_session = NewTraceWithCategories({"foo"});
3021   tracing_session->get()->StartBlocking();
3022 
3023   TRACE_EVENT_BEGIN("foo", "EventWithState", [&](perfetto::EventContext ctx) {
3024     const SourceLocation location{"file.cc", "SomeFunction", 123};
3025     auto location_iid = InternedSourceLocation::Get(&ctx, location);
3026     auto body_iid = InternedLogMessageBody::Get(&ctx, "To be, or not to be");
3027     auto log = ctx.event()->set_log_message();
3028     log->set_source_location_iid(location_iid);
3029     log->set_body_iid(body_iid);
3030 
3031     auto location_iid2 = InternedSourceLocation::Get(&ctx, location);
3032     EXPECT_EQ(location_iid, location_iid2);
3033 
3034     const SourceLocation location2{"file.cc", "SomeFunction", 456};
3035     auto location_iid3 = InternedSourceLocation::Get(&ctx, location2);
3036     EXPECT_NE(location_iid, location_iid3);
3037   });
3038   TRACE_EVENT_END("foo");
3039 
3040   tracing_session->get()->StopBlocking();
3041   auto log_messages = ReadLogMessagesFromTrace(tracing_session->get());
3042   EXPECT_THAT(log_messages,
3043               ElementsAre("SomeFunction(file.cc:123): To be, or not to be"));
3044 }
3045 
TEST_P(PerfettoApiTest,TrackEventScoped)3046 TEST_P(PerfettoApiTest, TrackEventScoped) {
3047   // Create a new trace session.
3048   auto* tracing_session = NewTraceWithCategories({"test"});
3049   tracing_session->get()->StartBlocking();
3050 
3051   {
3052     uint64_t arg = 123;
3053     TRACE_EVENT("test", "TestEventWithArgs", [&](perfetto::EventContext ctx) {
3054       ctx.event()->set_log_message()->set_body_iid(arg);
3055     });
3056   }
3057 
3058   // Ensure a single line if statement counts as a valid scope for the macro.
3059   if (true)
3060     TRACE_EVENT("test", "SingleLineTestEvent");
3061 
3062   {
3063     // Make sure you can have multiple scoped events in the same scope.
3064     TRACE_EVENT("test", "TestEvent");
3065     TRACE_EVENT("test", "AnotherEvent");
3066     TRACE_EVENT("foo", "DisabledEvent");
3067   }
3068   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3069   EXPECT_THAT(
3070       slices,
3071       ElementsAre("B:test.TestEventWithArgs", "E", "B:test.SingleLineTestEvent",
3072                   "E", "B:test.TestEvent", "B:test.AnotherEvent", "E", "E"));
3073 }
3074 
3075 // A class similar to what Protozero generates for extended message.
3076 class TestTrackEvent : public perfetto::protos::pbzero::TrackEvent {
3077  public:
3078   static const int field_number = 9901;
3079 
set_extension_value(int value)3080   void set_extension_value(int value) {
3081     // 9900-10000 is the range of extension field numbers reserved for testing.
3082     AppendTinyVarInt(field_number, value);
3083   }
3084 };
3085 
TEST_P(PerfettoApiTest,ExtensionClass)3086 TEST_P(PerfettoApiTest, ExtensionClass) {
3087   auto* tracing_session = NewTraceWithCategories({"test"});
3088   tracing_session->get()->StartBlocking();
3089 
3090   {
3091     TRACE_EVENT("test", "TestEventWithExtensionArgs",
3092                 [&](perfetto::EventContext ctx) {
3093                   ctx.event<perfetto::protos::pbzero::TestExtension>()
3094                       ->add_int_extension_for_testing(42);
3095                 });
3096   }
3097 
3098   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
3099   EXPECT_GE(raw_trace.size(), 0u);
3100 
3101   bool found_extension = false;
3102   perfetto::protos::pbzero::Trace_Decoder trace(
3103       reinterpret_cast<uint8_t*>(raw_trace.data()), raw_trace.size());
3104 
3105   for (auto it = trace.packet(); it; ++it) {
3106     perfetto::protos::pbzero::TracePacket_Decoder packet(it->data(),
3107                                                          it->size());
3108 
3109     if (!packet.has_track_event())
3110       continue;
3111 
3112     auto track_event = packet.track_event();
3113     protozero::ProtoDecoder decoder(track_event.data, track_event.size);
3114 
3115     for (protozero::Field f = decoder.ReadField(); f.valid();
3116          f = decoder.ReadField()) {
3117       if (f.id() == perfetto::protos::pbzero::TestExtension::
3118                         FieldMetadata_IntExtensionForTesting::kFieldId) {
3119         found_extension = true;
3120       }
3121     }
3122   }
3123 
3124   EXPECT_TRUE(found_extension);
3125 }
3126 
TEST_P(PerfettoApiTest,InlineTypedExtensionField)3127 TEST_P(PerfettoApiTest, InlineTypedExtensionField) {
3128   auto* tracing_session = NewTraceWithCategories({"test"});
3129   tracing_session->get()->StartBlocking();
3130 
3131   {
3132     TRACE_EVENT(
3133         "test", "TestEventWithExtensionArgs",
3134         perfetto::protos::pbzero::TestExtension::kIntExtensionForTesting,
3135         std::vector<int>{42},
3136         perfetto::protos::pbzero::TestExtension::kUintExtensionForTesting, 42u);
3137   }
3138 
3139   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
3140   EXPECT_GE(raw_trace.size(), 0u);
3141 
3142   bool found_int_extension = false;
3143   bool found_uint_extension = false;
3144   perfetto::protos::pbzero::Trace_Decoder trace(
3145       reinterpret_cast<uint8_t*>(raw_trace.data()), raw_trace.size());
3146 
3147   for (auto it = trace.packet(); it; ++it) {
3148     perfetto::protos::pbzero::TracePacket_Decoder packet(it->data(),
3149                                                          it->size());
3150 
3151     if (!packet.has_track_event())
3152       continue;
3153 
3154     auto track_event = packet.track_event();
3155     protozero::ProtoDecoder decoder(track_event.data, track_event.size);
3156 
3157     for (protozero::Field f = decoder.ReadField(); f.valid();
3158          f = decoder.ReadField()) {
3159       if (f.id() == perfetto::protos::pbzero::TestExtension::
3160                         FieldMetadata_IntExtensionForTesting::kFieldId) {
3161         found_int_extension = true;
3162       } else if (f.id() ==
3163                  perfetto::protos::pbzero::TestExtension::
3164                      FieldMetadata_UintExtensionForTesting::kFieldId) {
3165         found_uint_extension = true;
3166       }
3167     }
3168   }
3169 
3170   EXPECT_TRUE(found_int_extension);
3171   EXPECT_TRUE(found_uint_extension);
3172 }
3173 
TEST_P(PerfettoApiTest,TrackEventInstant)3174 TEST_P(PerfettoApiTest, TrackEventInstant) {
3175   // Create a new trace session.
3176   auto* tracing_session = NewTraceWithCategories({"test"});
3177   tracing_session->get()->StartBlocking();
3178 
3179   TRACE_EVENT_INSTANT("test", "TestEvent");
3180   TRACE_EVENT_INSTANT("test", "AnotherEvent");
3181   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3182   EXPECT_THAT(slices, ElementsAre("I:test.TestEvent", "I:test.AnotherEvent"));
3183 }
3184 
TEST_P(PerfettoApiTest,TrackEventDefaultGlobalTrack)3185 TEST_P(PerfettoApiTest, TrackEventDefaultGlobalTrack) {
3186   // Create a new trace session.
3187   auto* tracing_session = NewTraceWithCategories({"test"});
3188   tracing_session->get()->StartBlocking();
3189 
3190   TRACE_EVENT_INSTANT("test", "ThreadEvent");
3191   TRACE_EVENT_INSTANT("test", "GlobalEvent", perfetto::Track::Global(0u));
3192   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3193   EXPECT_THAT(slices,
3194               ElementsAre("I:test.ThreadEvent", "[track=0]I:test.GlobalEvent"));
3195 }
3196 
TEST_P(PerfettoApiTest,TrackEventTrackFromPointer)3197 TEST_P(PerfettoApiTest, TrackEventTrackFromPointer) {
3198   // Create a new trace session.
3199   auto* tracing_session = NewTraceWithCategories({"test"});
3200   tracing_session->get()->StartBlocking();
3201 
3202   perfetto::Track parent_track(1);
3203   int* ptr = reinterpret_cast<int*>(2);
3204   TRACE_EVENT_INSTANT("test", "Event",
3205                       perfetto::Track::FromPointer(ptr, parent_track));
3206 
3207   perfetto::Track track(reinterpret_cast<uintptr_t>(ptr), parent_track);
3208 
3209   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3210   EXPECT_THAT(slices, ElementsAre("[track=" + std::to_string(track.uuid) +
3211                                   "]I:test.Event"));
3212 }
3213 
TEST_P(PerfettoApiTest,TrackEventTrackFromThreadScopedPointer)3214 TEST_P(PerfettoApiTest, TrackEventTrackFromThreadScopedPointer) {
3215   // Create a new trace session.
3216   auto* tracing_session = NewTraceWithCategories({"test"});
3217   tracing_session->get()->StartBlocking();
3218 
3219   int num = 2;
3220   TRACE_EVENT_INSTANT("test", "Event0.1");
3221   TRACE_EVENT_INSTANT("test", "Event0.2");
3222   TRACE_EVENT_INSTANT("test", "Event1.1", perfetto::Track::ThreadScoped(&num));
3223   TRACE_EVENT_INSTANT("test", "Event1.2", perfetto::Track::ThreadScoped(&num));
3224   std::thread t1([&]() {
3225     TRACE_EVENT_INSTANT("test", "Event2.1",
3226                         perfetto::Track::ThreadScoped(&num));
3227     TRACE_EVENT_INSTANT("test", "Event2.2",
3228                         perfetto::Track::ThreadScoped(&num));
3229   });
3230   t1.join();
3231   std::thread t2([&]() {
3232     TRACE_EVENT_INSTANT("test", "Event3.1",
3233                         perfetto::Track::ThreadScoped(&num));
3234     TRACE_EVENT_INSTANT("test", "Event3.2",
3235                         perfetto::Track::ThreadScoped(&num));
3236   });
3237   t2.join();
3238 
3239   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
3240 
3241   std::unordered_map<std::string, uint64_t> track_uuid_map;
3242   for (auto packet : trace.packet()) {
3243     if (packet.has_interned_data()) {
3244       for (auto& ename : packet.interned_data().event_names()) {
3245         track_uuid_map.emplace(ename.name(), packet.track_event().track_uuid());
3246       }
3247     }
3248   }
3249   EXPECT_EQ(track_uuid_map.at("Event0.1"), track_uuid_map.at("Event0.2"));
3250   EXPECT_EQ(track_uuid_map.at("Event1.1"), track_uuid_map.at("Event1.2"));
3251   EXPECT_EQ(track_uuid_map.at("Event2.1"), track_uuid_map.at("Event2.2"));
3252   EXPECT_EQ(track_uuid_map.at("Event3.1"), track_uuid_map.at("Event3.2"));
3253 
3254   EXPECT_EQ(4u,
3255             (std::unordered_set<uint64_t>{
3256                  track_uuid_map.at("Event0.1"), track_uuid_map.at("Event1.1"),
3257                  track_uuid_map.at("Event2.1"), track_uuid_map.at("Event3.1")})
3258                 .size());
3259 }
3260 
TEST_P(PerfettoApiTest,FilterDebugAnnotations)3261 TEST_P(PerfettoApiTest, FilterDebugAnnotations) {
3262   for (auto flag : {false, true}) {
3263     // Create a new trace session.
3264     perfetto::protos::gen::TrackEventConfig te_cfg;
3265     te_cfg.set_filter_debug_annotations(flag);
3266     auto* tracing_session = NewTraceWithCategories({"test"}, te_cfg);
3267     tracing_session->get()->StartBlocking();
3268 
3269     TRACE_EVENT_BEGIN("test", "Event1");
3270     TRACE_EVENT_BEGIN("test", "Event2", [&](perfetto::EventContext ctx) {
3271       ctx.AddDebugAnnotation("debug_name", "debug_value");
3272     });
3273     TRACE_EVENT_BEGIN("test", "Event3");
3274     auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3275     ASSERT_EQ(3u, slices.size());
3276     if (flag) {
3277       EXPECT_EQ("B:test.Event2", slices[1]);
3278     } else {
3279       EXPECT_EQ("B:test.Event2(debug_name=(string)debug_value)", slices[1]);
3280     }
3281   }
3282 }
3283 
TEST_P(PerfettoApiTest,TrackEventDebugAnnotations)3284 TEST_P(PerfettoApiTest, TrackEventDebugAnnotations) {
3285   // Create a new trace session.
3286   auto* tracing_session = NewTraceWithCategories({"test"});
3287   tracing_session->get()->StartBlocking();
3288 
3289   enum MyEnum : uint32_t { ENUM_FOO, ENUM_BAR };
3290   enum MySignedEnum : int32_t { SIGNED_ENUM_FOO = -1, SIGNED_ENUM_BAR };
3291   enum class MyClassEnum { VALUE };
3292 
3293   TRACE_EVENT_BEGIN("test", "E", "bool_arg", false);
3294   TRACE_EVENT_BEGIN("test", "E", "int_arg", -123);
3295   TRACE_EVENT_BEGIN("test", "E", "uint_arg", 456u);
3296   TRACE_EVENT_BEGIN("test", "E", "float_arg", 3.14159262f);
3297   TRACE_EVENT_BEGIN("test", "E", "double_arg", 6.22);
3298   TRACE_EVENT_BEGIN("test", "E", "str_arg", "hello", "str_arg2",
3299                     std::string("tracing"), "str_arg3",
3300                     std::string_view("view"));
3301   TRACE_EVENT_BEGIN("test", "E", "ptr_arg",
3302                     reinterpret_cast<void*>(static_cast<intptr_t>(0xbaadf00d)));
3303   TRACE_EVENT_BEGIN("test", "E", "size_t_arg", size_t{42});
3304   TRACE_EVENT_BEGIN("test", "E", "ptrdiff_t_arg", ptrdiff_t{-7});
3305   TRACE_EVENT_BEGIN("test", "E", "enum_arg", ENUM_BAR);
3306   TRACE_EVENT_BEGIN("test", "E", "signed_enum_arg", SIGNED_ENUM_FOO);
3307   TRACE_EVENT_BEGIN("test", "E", "class_enum_arg", MyClassEnum::VALUE);
3308   TRACE_EVENT_BEGIN("test", "E", "traced_value",
3309                     [&](perfetto::TracedValue context) {
3310                       std::move(context).WriteInt64(42);
3311                     });
3312   TRACE_EVENT_BEGIN("test", "E", [&](perfetto::EventContext ctx) {
3313     ctx.AddDebugAnnotation("debug_annotation", "value");
3314   });
3315   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3316   EXPECT_THAT(
3317       slices,
3318       ElementsAre(
3319           "B:test.E(bool_arg=(bool)0)", "B:test.E(int_arg=(int)-123)",
3320           "B:test.E(uint_arg=(uint)456)", "B:test.E(float_arg=(double)3.14159)",
3321           "B:test.E(double_arg=(double)6.22)",
3322           "B:test.E(str_arg=(string)hello,str_arg2=(string)tracing,"
3323           "str_arg3=(string)view)",
3324           "B:test.E(ptr_arg=(pointer)baadf00d)",
3325           "B:test.E(size_t_arg=(uint)42)", "B:test.E(ptrdiff_t_arg=(int)-7)",
3326           "B:test.E(enum_arg=(uint)1)", "B:test.E(signed_enum_arg=(int)-1)",
3327           "B:test.E(class_enum_arg=(int)0)", "B:test.E(traced_value=(int)42)",
3328           "B:test.E(debug_annotation=(string)value)"));
3329 }
3330 
TEST_P(PerfettoApiTest,TrackEventCustomDebugAnnotations)3331 TEST_P(PerfettoApiTest, TrackEventCustomDebugAnnotations) {
3332   // Create a new trace session.
3333   auto* tracing_session = NewTraceWithCategories({"test"});
3334   tracing_session->get()->StartBlocking();
3335 
3336   std::unique_ptr<MyDebugAnnotation> owned_annotation(new MyDebugAnnotation());
3337 
3338   TRACE_EVENT_BEGIN("test", "E", "custom_arg", MyDebugAnnotation());
3339   TRACE_EVENT_BEGIN("test", "E", "normal_arg", "x", "custom_arg",
3340                     std::move(owned_annotation));
3341   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3342   EXPECT_THAT(
3343       slices,
3344       ElementsAre(
3345           R"(B:test.E(custom_arg=(json){"key": 123}))",
3346           R"(B:test.E(normal_arg=(string)x,custom_arg=(json){"key": 123}))"));
3347 }
3348 
TEST_P(PerfettoApiTest,TrackEventCustomRawDebugAnnotations)3349 TEST_P(PerfettoApiTest, TrackEventCustomRawDebugAnnotations) {
3350   // Note: this class is also testing a non-moveable and non-copiable argument.
3351   class MyRawDebugAnnotation : public perfetto::DebugAnnotation {
3352    public:
3353     MyRawDebugAnnotation() { msg_->set_string_value("nested_value"); }
3354     ~MyRawDebugAnnotation() = default;
3355 
3356     // |msg_| already deletes these implicitly, but let's be explicit for safety
3357     // against future changes.
3358     MyRawDebugAnnotation(const MyRawDebugAnnotation&) = delete;
3359     MyRawDebugAnnotation(MyRawDebugAnnotation&&) = delete;
3360 
3361     void Add(perfetto::protos::pbzero::DebugAnnotation* annotation) const {
3362       auto ranges = msg_.GetRanges();
3363       annotation->AppendScatteredBytes(
3364           perfetto::protos::pbzero::DebugAnnotation::kNestedValueFieldNumber,
3365           &ranges[0], ranges.size());
3366     }
3367 
3368    private:
3369     mutable protozero::HeapBuffered<
3370         perfetto::protos::pbzero::DebugAnnotation::NestedValue>
3371         msg_;
3372   };
3373 
3374   // Create a new trace session.
3375   auto* tracing_session = NewTraceWithCategories({"test"});
3376   tracing_session->get()->StartBlocking();
3377 
3378   TRACE_EVENT_BEGIN("test", "E", "raw_arg", MyRawDebugAnnotation());
3379   TRACE_EVENT_BEGIN("test", "E", "plain_arg", 42, "raw_arg",
3380                     MyRawDebugAnnotation());
3381   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3382   EXPECT_THAT(
3383       slices,
3384       ElementsAre("B:test.E(raw_arg=(nested)nested_value)",
3385                   "B:test.E(plain_arg=(int)42,raw_arg=(nested)nested_value)"));
3386 }
3387 
TEST_P(PerfettoApiTest,ManyDebugAnnotations)3388 TEST_P(PerfettoApiTest, ManyDebugAnnotations) {
3389   // Create a new trace session.
3390   auto* tracing_session = NewTraceWithCategories({"test"});
3391   tracing_session->get()->StartBlocking();
3392 
3393   TRACE_EVENT_BEGIN("test", "E", "arg1", 1, "arg2", 2, "arg3", 3);
3394   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3395   EXPECT_THAT(slices,
3396               ElementsAre("B:test.E(arg1=(int)1,arg2=(int)2,arg3=(int)3)"));
3397 }
3398 
TEST_P(PerfettoApiTest,DebugAnnotationAndLambda)3399 TEST_P(PerfettoApiTest, DebugAnnotationAndLambda) {
3400   // Create a new trace session.
3401   auto* tracing_session = NewTraceWithCategories({"test"});
3402   tracing_session->get()->StartBlocking();
3403 
3404   enum MyEnum : uint32_t { ENUM_FOO, ENUM_BAR };
3405   enum MySignedEnum : int32_t { SIGNED_ENUM_FOO = -1, SIGNED_ENUM_BAR };
3406   enum class MyClassEnum { VALUE };
3407 
3408   TRACE_EVENT_BEGIN(
3409       "test", "E", "key", "value", [](perfetto::EventContext ctx) {
3410         ctx.event()->set_log_message()->set_source_location_iid(42);
3411       });
3412   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
3413 
3414   bool found_args = false;
3415   for (const auto& packet : trace.packet()) {
3416     if (!packet.has_track_event())
3417       continue;
3418     const auto& track_event = packet.track_event();
3419     if (track_event.type() !=
3420         perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN)
3421       continue;
3422 
3423     EXPECT_TRUE(track_event.has_log_message());
3424     const auto& log = track_event.log_message();
3425     EXPECT_EQ(42u, log.source_location_iid());
3426 
3427     const auto& dbg = track_event.debug_annotations()[0];
3428     EXPECT_EQ("value", dbg.string_value());
3429 
3430     found_args = true;
3431   }
3432   EXPECT_TRUE(found_args);
3433 }
3434 
TEST_P(PerfettoApiTest,ProtoInsideDebugAnnotation)3435 TEST_P(PerfettoApiTest, ProtoInsideDebugAnnotation) {
3436   auto* tracing_session = NewTraceWithCategories({"test"});
3437   tracing_session->get()->StartBlocking();
3438 
3439   TRACE_EVENT_INSTANT(
3440       "test", "E", "key",
3441       [](perfetto::TracedProto<perfetto::protos::pbzero::LogMessage> ctx) {
3442         ctx->set_source_location_iid(42);
3443       });
3444 
3445   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
3446 
3447   std::vector<std::string> interned_debug_annotation_names;
3448   std::vector<std::string> interned_debug_annotation_proto_type_names;
3449 
3450   bool found_args = false;
3451   for (const auto& packet : trace.packet()) {
3452     if (packet.has_interned_data()) {
3453       for (const auto& interned_name :
3454            packet.interned_data().debug_annotation_names()) {
3455         interned_debug_annotation_names.push_back(interned_name.name());
3456       }
3457       for (const auto& interned_type_name :
3458            packet.interned_data().debug_annotation_value_type_names()) {
3459         interned_debug_annotation_proto_type_names.push_back(
3460             interned_type_name.name());
3461       }
3462     }
3463 
3464     if (!packet.has_track_event())
3465       continue;
3466     const auto& track_event = packet.track_event();
3467     if (track_event.type() != perfetto::protos::gen::TrackEvent::TYPE_INSTANT) {
3468       continue;
3469     }
3470 
3471     EXPECT_EQ(track_event.debug_annotations_size(), 1);
3472     found_args = true;
3473   }
3474   // TODO(altimin): Use DebugAnnotationParser here to parse the debug
3475   // annotations.
3476   EXPECT_TRUE(found_args);
3477   EXPECT_THAT(interned_debug_annotation_names,
3478               testing::UnorderedElementsAre("key"));
3479   EXPECT_THAT(interned_debug_annotation_proto_type_names,
3480               testing::UnorderedElementsAre(".perfetto.protos.LogMessage"));
3481 }
3482 
TEST_P(PerfettoApiTest,TrackEventComputedName)3483 TEST_P(PerfettoApiTest, TrackEventComputedName) {
3484   // Setup the trace config.
3485   perfetto::TraceConfig cfg;
3486   cfg.set_duration_ms(500);
3487   cfg.add_buffers()->set_size_kb(1024);
3488   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
3489   ds_cfg->set_name("track_event");
3490 
3491   // Create a new trace session.
3492   auto* tracing_session = NewTrace(cfg);
3493   tracing_session->get()->StartBlocking();
3494 
3495   // New macros require perfetto::StaticString{} annotation.
3496   for (int i = 0; i < 3; i++)
3497     TRACE_EVENT_BEGIN("test", perfetto::StaticString{i % 2 ? "Odd" : "Even"});
3498 
3499   // Legacy macros assume all arguments are static strings.
3500   for (int i = 0; i < 3; i++)
3501     TRACE_EVENT_BEGIN0("test", i % 2 ? "Odd" : "Even");
3502 
3503   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3504   EXPECT_THAT(slices, ElementsAre("B:test.Even", "B:test.Odd", "B:test.Even",
3505                                   "B:test.Even", "B:test.Odd", "B:test.Even"));
3506 }
3507 
TEST_P(PerfettoApiTest,TrackEventEventNameDynamicString)3508 TEST_P(PerfettoApiTest, TrackEventEventNameDynamicString) {
3509   // Create a new trace session.
3510   auto* tracing_session = NewTraceWithCategories({"foo"});
3511   tracing_session->get()->StartBlocking();
3512   TRACE_EVENT_BEGIN("foo", perfetto::DynamicString{std::string("Event1")});
3513   TRACE_EVENT_BEGIN("foo", perfetto::DynamicString{std::string("Event2")});
3514 
3515   TRACE_EVENT0("foo", TRACE_STR_COPY(std::string("Event3")));
3516   const char* event4 = "Event4";
3517   TRACE_EVENT0("foo", event4);
3518 
3519   // Ensure that event-name is not emitted in case of `_END` events.
3520   PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(
3521       TraceForCategory, "foo", perfetto::DynamicString{std::string("Event5")},
3522       ::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_END);
3523   PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(
3524       TraceForCategory, "foo", perfetto::StaticString{"Event6"},
3525       ::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_END);
3526 
3527   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3528   ASSERT_EQ(6u, slices.size());
3529   EXPECT_EQ("B:foo.Event1", slices[0]);
3530   EXPECT_EQ("B:foo.Event2", slices[1]);
3531   EXPECT_EQ("B:foo.Event3", slices[2]);
3532   EXPECT_EQ("B:foo.Event4", slices[3]);
3533   EXPECT_EQ("E", slices[4]);
3534   EXPECT_EQ("E", slices[5]);
3535 }
3536 
TEST_P(PerfettoApiTest,TrackEventDynamicStringInDebugArgs)3537 TEST_P(PerfettoApiTest, TrackEventDynamicStringInDebugArgs) {
3538   auto* tracing_session = NewTraceWithCategories({"foo"});
3539   tracing_session->get()->StartBlocking();
3540 
3541   TRACE_EVENT1("foo", "Event1", "arg1",
3542                TRACE_STR_COPY(std::string("arg1_value1")));
3543   const char* value2 = "arg1_value2";
3544   TRACE_EVENT1("foo", "Event2", "arg1", value2);
3545   const char* value4 = "arg1_value4";
3546   TRACE_EVENT1("foo", "Event3", "arg1",
3547                perfetto::DynamicString(std::string("arg1_value3")));
3548   TRACE_EVENT1("foo", "Event4", "arg1", perfetto::StaticString(value4));
3549 
3550   TRACE_EVENT_BEGIN("foo", "Event5", "arg1",
3551                     TRACE_STR_COPY(std::string("arg1_value5")));
3552   TRACE_EVENT_BEGIN("foo", "Event6", "arg1",
3553                     perfetto::DynamicString(std::string("arg1_value6")));
3554   const char* value7 = "arg1_value7";
3555   TRACE_EVENT_BEGIN("foo", "Event7", "arg1", perfetto::StaticString(value7));
3556   const char* arg_name = "new_arg1";
3557   TRACE_EVENT_BEGIN("foo", "Event8", perfetto::DynamicString{arg_name}, 5);
3558 
3559   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3560   ASSERT_EQ(8u, slices.size());
3561   EXPECT_EQ("B:foo.Event1(arg1=(string)arg1_value1)", slices[0]);
3562   EXPECT_EQ("B:foo.Event2(arg1=(string)arg1_value2)", slices[1]);
3563   EXPECT_EQ("B:foo.Event3(arg1=(string)arg1_value3)", slices[2]);
3564   EXPECT_EQ("B:foo.Event4(arg1=(string)arg1_value4)", slices[3]);
3565   EXPECT_EQ("B:foo.Event5(arg1=(string)arg1_value5)", slices[4]);
3566   EXPECT_EQ("B:foo.Event6(arg1=(string)arg1_value6)", slices[5]);
3567   EXPECT_EQ("B:foo.Event7(arg1=(string)arg1_value7)", slices[6]);
3568   EXPECT_EQ("B:foo.Event8(new_arg1=(int)5)", slices[7]);
3569 }
3570 
TEST_P(PerfettoApiTest,TrackEventLegacyNullStringInArgs)3571 TEST_P(PerfettoApiTest, TrackEventLegacyNullStringInArgs) {
3572   auto* tracing_session = NewTraceWithCategories({"foo"});
3573   tracing_session->get()->StartBlocking();
3574 
3575   const char* null_str = nullptr;
3576 
3577   TRACE_EVENT1("foo", "Event1", "arg1", null_str);
3578   TRACE_EVENT1("foo", "Event2", "arg1", TRACE_STR_COPY(null_str));
3579 
3580   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3581   ASSERT_EQ(2u, slices.size());
3582   EXPECT_EQ("B:foo.Event1(arg1=(string)NULL)", slices[0]);
3583   EXPECT_EQ("B:foo.Event2(arg1=(string)NULL)", slices[1]);
3584 }
3585 
TEST_P(PerfettoApiTest,FilterDynamicEventName)3586 TEST_P(PerfettoApiTest, FilterDynamicEventName) {
3587   for (auto filter_dynamic_names : {false, true}) {
3588     // Create a new trace session.
3589     perfetto::protos::gen::TrackEventConfig te_cfg;
3590     te_cfg.set_filter_dynamic_event_names(filter_dynamic_names);
3591     auto* tracing_session = NewTraceWithCategories({"test"}, te_cfg);
3592     tracing_session->get()->StartBlocking();
3593 
3594     TRACE_EVENT_BEGIN("test", "Event1");
3595     TRACE_EVENT_BEGIN("test", perfetto::DynamicString("Event2"));
3596     const char* event3 = "Event3";
3597     TRACE_EVENT_BEGIN("test", perfetto::StaticString(event3));
3598     auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3599     ASSERT_EQ(3u, slices.size());
3600     EXPECT_EQ("B:test.Event1", slices[0]);
3601     EXPECT_EQ(filter_dynamic_names ? "B:test.FILTERED" : "B:test.Event2",
3602               slices[1]);
3603     EXPECT_EQ("B:test.Event3", slices[2]);
3604   }
3605 }
3606 
TEST_P(PerfettoApiTest,TrackEventArgumentsNotEvaluatedWhenDisabled)3607 TEST_P(PerfettoApiTest, TrackEventArgumentsNotEvaluatedWhenDisabled) {
3608   // Create a new trace session.
3609   auto* tracing_session = NewTraceWithCategories({"foo"});
3610   tracing_session->get()->StartBlocking();
3611 
3612   bool called = false;
3613   auto ArgumentFunction = [&] {
3614     called = true;
3615     return 123;
3616   };
3617 
3618   TRACE_EVENT_BEGIN("test", "DisabledEvent", "arg", ArgumentFunction());
3619   { TRACE_EVENT("test", "DisabledScopedEvent", "arg", ArgumentFunction()); }
3620   perfetto::TrackEvent::Flush();
3621 
3622   tracing_session->get()->StopBlocking();
3623   EXPECT_FALSE(called);
3624 
3625   ArgumentFunction();
3626   EXPECT_TRUE(called);
3627 }
3628 
TEST_P(PerfettoApiTest,TrackEventConfig)3629 TEST_P(PerfettoApiTest, TrackEventConfig) {
3630   auto check_config = [&](perfetto::protos::gen::TrackEventConfig te_cfg) {
3631     perfetto::TraceConfig cfg;
3632     cfg.set_duration_ms(500);
3633     cfg.add_buffers()->set_size_kb(1024);
3634     auto* ds_cfg = cfg.add_data_sources()->mutable_config();
3635     ds_cfg->set_name("track_event");
3636     ds_cfg->set_track_event_config_raw(te_cfg.SerializeAsString());
3637 
3638     auto* tracing_session = NewTrace(cfg);
3639     tracing_session->get()->StartBlocking();
3640 
3641     TRACE_EVENT_BEGIN("foo", "FooEvent");
3642     TRACE_EVENT_BEGIN("bar", "BarEvent");
3643     TRACE_EVENT_BEGIN("foo,bar", "MultiFooBar");
3644     TRACE_EVENT_BEGIN("baz,bar,quux", "MultiBar");
3645     TRACE_EVENT_BEGIN("red,green,blue,foo", "MultiFoo");
3646     TRACE_EVENT_BEGIN("red,green,blue,yellow", "MultiNone");
3647     TRACE_EVENT_BEGIN("cat", "SlowEvent");
3648     TRACE_EVENT_BEGIN("cat.verbose", "DebugEvent");
3649     TRACE_EVENT_BEGIN("test", "TagEvent");
3650     TRACE_EVENT_BEGIN(TRACE_DISABLED_BY_DEFAULT("cat"), "SlowDisabledEvent");
3651     TRACE_EVENT_BEGIN("dynamic,foo", "DynamicGroupFooEvent");
3652     perfetto::DynamicCategory dyn{"dynamic,bar"};
3653     TRACE_EVENT_BEGIN(dyn, "DynamicGroupBarEvent");
3654 
3655     auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3656     tracing_session->session.reset();
3657     return slices;
3658   };
3659 
3660   // Empty config should enable all categories except slow ones.
3661   {
3662     perfetto::protos::gen::TrackEventConfig te_cfg;
3663     auto slices = check_config(te_cfg);
3664     EXPECT_THAT(
3665         slices,
3666         ElementsAre("B:foo.FooEvent", "B:bar.BarEvent", "B:foo,bar.MultiFooBar",
3667                     "B:baz,bar,quux.MultiBar", "B:red,green,blue,foo.MultiFoo",
3668                     "B:red,green,blue,yellow.MultiNone", "B:test.TagEvent",
3669                     "B:$dynamic,$foo.DynamicGroupFooEvent",
3670                     "B:$dynamic,$bar.DynamicGroupBarEvent"));
3671   }
3672 
3673   // Enable exactly one category.
3674   {
3675     perfetto::protos::gen::TrackEventConfig te_cfg;
3676     te_cfg.add_disabled_categories("*");
3677     te_cfg.add_enabled_categories("foo");
3678     auto slices = check_config(te_cfg);
3679     EXPECT_THAT(slices, ElementsAre("B:foo.FooEvent", "B:foo,bar.MultiFooBar",
3680                                     "B:red,green,blue,foo.MultiFoo",
3681                                     "B:$dynamic,$foo.DynamicGroupFooEvent"));
3682   }
3683 
3684   // Enable exactly one dynamic category.
3685   {
3686     perfetto::protos::gen::TrackEventConfig te_cfg;
3687     te_cfg.add_disabled_categories("*");
3688     te_cfg.add_enabled_categories("dynamic");
3689     auto slices = check_config(te_cfg);
3690     EXPECT_THAT(slices, ElementsAre("B:$dynamic,$foo.DynamicGroupFooEvent",
3691                                     "B:$dynamic,$bar.DynamicGroupBarEvent"));
3692   }
3693 
3694   // Enable two categories.
3695   {
3696     perfetto::protos::gen::TrackEventConfig te_cfg;
3697     te_cfg.add_disabled_categories("*");
3698     te_cfg.add_enabled_categories("foo");
3699     te_cfg.add_enabled_categories("baz");
3700     te_cfg.add_enabled_categories("bar");
3701     auto slices = check_config(te_cfg);
3702     EXPECT_THAT(
3703         slices,
3704         ElementsAre("B:foo.FooEvent", "B:bar.BarEvent", "B:foo,bar.MultiFooBar",
3705                     "B:baz,bar,quux.MultiBar", "B:red,green,blue,foo.MultiFoo",
3706                     "B:$dynamic,$foo.DynamicGroupFooEvent",
3707                     "B:$dynamic,$bar.DynamicGroupBarEvent"));
3708   }
3709 
3710   // Enabling all categories with a pattern doesn't enable slow ones.
3711   {
3712     perfetto::protos::gen::TrackEventConfig te_cfg;
3713     te_cfg.add_enabled_categories("*");
3714     auto slices = check_config(te_cfg);
3715     EXPECT_THAT(
3716         slices,
3717         ElementsAre("B:foo.FooEvent", "B:bar.BarEvent", "B:foo,bar.MultiFooBar",
3718                     "B:baz,bar,quux.MultiBar", "B:red,green,blue,foo.MultiFoo",
3719                     "B:red,green,blue,yellow.MultiNone", "B:test.TagEvent",
3720                     "B:$dynamic,$foo.DynamicGroupFooEvent",
3721                     "B:$dynamic,$bar.DynamicGroupBarEvent"));
3722   }
3723 
3724   // Enable with a pattern.
3725   {
3726     perfetto::protos::gen::TrackEventConfig te_cfg;
3727     te_cfg.add_disabled_categories("*");
3728     te_cfg.add_enabled_categories("fo*");
3729     auto slices = check_config(te_cfg);
3730     EXPECT_THAT(slices, ElementsAre("B:foo.FooEvent", "B:foo,bar.MultiFooBar",
3731                                     "B:red,green,blue,foo.MultiFoo",
3732                                     "B:$dynamic,$foo.DynamicGroupFooEvent"));
3733   }
3734 
3735   // Enable with a tag.
3736   {
3737     perfetto::protos::gen::TrackEventConfig te_cfg;
3738     te_cfg.add_disabled_categories("*");
3739     te_cfg.add_enabled_tags("tag");
3740     auto slices = check_config(te_cfg);
3741     EXPECT_THAT(slices, ElementsAre("B:test.TagEvent"));
3742   }
3743 
3744   // Enable just slow categories.
3745   {
3746     perfetto::protos::gen::TrackEventConfig te_cfg;
3747     te_cfg.add_disabled_categories("*");
3748     te_cfg.add_enabled_tags("slow");
3749     auto slices = check_config(te_cfg);
3750     EXPECT_THAT(slices,
3751                 ElementsAre("B:cat.SlowEvent",
3752                             "B:disabled-by-default-cat.SlowDisabledEvent"));
3753   }
3754 
3755   // Enable all legacy disabled-by-default categories by a pattern
3756   {
3757     perfetto::protos::gen::TrackEventConfig te_cfg;
3758     te_cfg.add_disabled_categories("*");
3759     te_cfg.add_enabled_categories("disabled-by-default-*");
3760     auto slices = check_config(te_cfg);
3761     EXPECT_THAT(slices,
3762                 ElementsAre("B:disabled-by-default-cat.SlowDisabledEvent"));
3763   }
3764 
3765   // Enable everything including slow/debug categories.
3766   {
3767     perfetto::protos::gen::TrackEventConfig te_cfg;
3768     te_cfg.add_enabled_categories("*");
3769     te_cfg.add_enabled_tags("slow");
3770     te_cfg.add_enabled_tags("debug");
3771     auto slices = check_config(te_cfg);
3772     EXPECT_THAT(
3773         slices,
3774         ElementsAre("B:foo.FooEvent", "B:bar.BarEvent", "B:foo,bar.MultiFooBar",
3775                     "B:baz,bar,quux.MultiBar", "B:red,green,blue,foo.MultiFoo",
3776                     "B:red,green,blue,yellow.MultiNone", "B:cat.SlowEvent",
3777                     "B:cat.verbose.DebugEvent", "B:test.TagEvent",
3778                     "B:disabled-by-default-cat.SlowDisabledEvent",
3779                     "B:$dynamic,$foo.DynamicGroupFooEvent",
3780                     "B:$dynamic,$bar.DynamicGroupBarEvent"));
3781   }
3782 }
3783 
TEST_P(PerfettoApiTest,OneDataSourceOneEvent)3784 TEST_P(PerfettoApiTest, OneDataSourceOneEvent) {
3785   auto* data_source = &data_sources_["my_data_source"];
3786 
3787   // Setup the trace config.
3788   perfetto::TraceConfig cfg;
3789   cfg.set_duration_ms(500);
3790   cfg.add_buffers()->set_size_kb(1024);
3791   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
3792   ds_cfg->set_name("my_data_source");
3793   ds_cfg->set_legacy_config("test config");
3794 
3795   // Create a new trace session.
3796   auto* tracing_session = NewTrace(cfg);
3797 
3798   MockDataSource::Trace([](MockDataSource::TraceContext) {
3799     FAIL() << "Should not be called because the trace was not started";
3800   });
3801   MockDataSource::CallIfEnabled([](uint32_t) {
3802     FAIL() << "Should not be called because the trace was not started";
3803   });
3804 
3805   tracing_session->get()->Start();
3806   data_source->on_setup.Wait();
3807   EXPECT_EQ(data_source->config.legacy_config(), "test config");
3808   data_source->on_start.Wait();
3809 
3810   // Emit one trace event.
3811   std::atomic<int> trace_lambda_calls{0};
3812   MockDataSource::Trace(
3813       [&trace_lambda_calls](MockDataSource::TraceContext ctx) {
3814         auto packet = ctx.NewTracePacket();
3815         packet->set_timestamp(42);
3816         packet->set_for_testing()->set_str("event 1");
3817         trace_lambda_calls++;
3818         packet->Finalize();
3819 
3820         // The SMB scraping logic will skip the last packet because it cannot
3821         // guarantee it's finalized. Create an empty packet so we get the
3822         // previous one and this empty one is ignored.
3823         packet = ctx.NewTracePacket();
3824       });
3825 
3826   uint32_t active_instances = 0;
3827   MockDataSource::CallIfEnabled([&active_instances](uint32_t instances) {
3828     active_instances = instances;
3829   });
3830   EXPECT_EQ(1u, active_instances);
3831 
3832   data_source->on_stop.Wait();
3833   tracing_session->on_stop.Wait();
3834   EXPECT_EQ(trace_lambda_calls, 1);
3835 
3836   MockDataSource::Trace([](MockDataSource::TraceContext) {
3837     FAIL() << "Should not be called because the trace is now stopped";
3838   });
3839   MockDataSource::CallIfEnabled([](uint32_t) {
3840     FAIL() << "Should not be called because the trace is now stopped";
3841   });
3842 
3843   std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
3844   ASSERT_GE(raw_trace.size(), 0u);
3845 
3846   perfetto::protos::gen::Trace trace;
3847   ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
3848   bool test_packet_found = false;
3849   for (const auto& packet : trace.packet()) {
3850     if (!packet.has_for_testing())
3851       continue;
3852     EXPECT_FALSE(test_packet_found);
3853     EXPECT_EQ(packet.timestamp(), 42U);
3854     EXPECT_EQ(packet.for_testing().str(), "event 1");
3855     test_packet_found = true;
3856   }
3857   EXPECT_TRUE(test_packet_found);
3858 }
3859 
TEST_P(PerfettoApiTest,ReentrantTracing)3860 TEST_P(PerfettoApiTest, ReentrantTracing) {
3861   auto* data_source = &data_sources_["my_data_source"];
3862 
3863   // Setup the trace config.
3864   perfetto::TraceConfig cfg;
3865   cfg.set_duration_ms(500);
3866   cfg.add_buffers()->set_size_kb(1024);
3867   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
3868   ds_cfg->set_name("my_data_source");
3869 
3870   // Create a new trace session.
3871   auto* tracing_session = NewTrace(cfg);
3872   tracing_session->get()->Start();
3873   data_source->on_start.Wait();
3874 
3875   // Check that only one level of trace lambda calls is allowed.
3876   std::atomic<int> trace_lambda_calls{0};
3877   MockDataSource::Trace([&trace_lambda_calls](MockDataSource::TraceContext) {
3878     trace_lambda_calls++;
3879     MockDataSource::Trace([&trace_lambda_calls](MockDataSource::TraceContext) {
3880       trace_lambda_calls++;
3881     });
3882   });
3883 
3884   tracing_session->get()->StopBlocking();
3885   EXPECT_EQ(trace_lambda_calls, 1);
3886 }
3887 
TEST_P(PerfettoApiTest,ConsumerFlush)3888 TEST_P(PerfettoApiTest, ConsumerFlush) {
3889   auto* data_source = &data_sources_["my_data_source"];
3890 
3891   // Setup the trace config.
3892   perfetto::TraceConfig cfg;
3893   cfg.add_buffers()->set_size_kb(1024);
3894   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
3895   ds_cfg->set_name("my_data_source");
3896   ds_cfg->set_legacy_config("test config");
3897 
3898   // Create a new trace session.
3899   auto* tracing_session = NewTrace(cfg);
3900 
3901   tracing_session->get()->Start();
3902   data_source->on_start.Wait();
3903 
3904   MockDataSource::Trace([&](MockDataSource::TraceContext ctx) {
3905     auto packet = ctx.NewTracePacket();
3906     packet->set_timestamp(42);
3907     packet->set_for_testing()->set_str("flushed event");
3908     packet->Finalize();
3909 
3910     // The SMB scraping logic will skip the last packet because it cannot
3911     // guarantee it's finalized. Create an empty packet so we get the
3912     // previous one and this empty one is ignored.
3913     packet = ctx.NewTracePacket();
3914   });
3915 
3916   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
3917 
3918   bool test_packet_found = false;
3919   for (const auto& packet : trace.packet()) {
3920     if (!packet.has_for_testing())
3921       continue;
3922     EXPECT_FALSE(test_packet_found);
3923     EXPECT_EQ(packet.timestamp(), 42U);
3924     EXPECT_EQ(packet.for_testing().str(), "flushed event");
3925     test_packet_found = true;
3926   }
3927   EXPECT_TRUE(test_packet_found);
3928 }
3929 
TEST_P(PerfettoApiTest,WithBatching)3930 TEST_P(PerfettoApiTest, WithBatching) {
3931   auto* data_source = &data_sources_["my_data_source"];
3932 
3933   // Setup the trace config.
3934   perfetto::TraceConfig cfg;
3935   cfg.set_duration_ms(500);
3936   cfg.add_buffers()->set_size_kb(1024);
3937   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
3938   ds_cfg->set_name("my_data_source");
3939   ds_cfg->set_legacy_config("test config");
3940 
3941   // Create a new trace session.
3942   auto* tracing_session = NewTrace(cfg);
3943 
3944   tracing_session->get()->Start();
3945   data_source->on_setup.Wait();
3946   data_source->on_start.Wait();
3947 
3948   std::stringstream first_large_message;
3949   for (size_t i = 0; i < 512; i++)
3950     first_large_message << i << ". Something wicked this way comes. ";
3951   auto first_large_message_str = first_large_message.str();
3952 
3953   // Emit one trace event before we begin batching.
3954   MockDataSource::Trace(
3955       [&first_large_message_str](MockDataSource::TraceContext ctx) {
3956         auto packet = ctx.NewTracePacket();
3957         packet->set_timestamp(42);
3958         packet->set_for_testing()->set_str(first_large_message_str);
3959         packet->Finalize();
3960       });
3961 
3962   // Simulate the start of a batching cycle by first setting the batching period
3963   // to a very large value and then force-flushing when we are done writing
3964   // data.
3965   ASSERT_TRUE(
3966       perfetto::test::EnableDirectSMBPatching(/*BackendType=*/GetParam()));
3967   perfetto::test::SetBatchCommitsDuration(UINT32_MAX,
3968                                           /*BackendType=*/GetParam());
3969 
3970   std::stringstream second_large_message;
3971   for (size_t i = 0; i < 512; i++)
3972     second_large_message << i << ". Something else wicked this way comes. ";
3973   auto second_large_message_str = second_large_message.str();
3974 
3975   // Emit another trace event.
3976   MockDataSource::Trace(
3977       [&second_large_message_str](MockDataSource::TraceContext ctx) {
3978         auto packet = ctx.NewTracePacket();
3979         packet->set_timestamp(43);
3980         packet->set_for_testing()->set_str(second_large_message_str);
3981         packet->Finalize();
3982 
3983         // Simulate the end of the batching cycle.
3984         ctx.Flush();
3985       });
3986 
3987   data_source->on_stop.Wait();
3988   tracing_session->on_stop.Wait();
3989 
3990   std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
3991   ASSERT_GE(raw_trace.size(), 0u);
3992 
3993   perfetto::protos::gen::Trace trace;
3994   ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
3995   bool test_packet_1_found = false;
3996   bool test_packet_2_found = false;
3997   for (const auto& packet : trace.packet()) {
3998     if (!packet.has_for_testing())
3999       continue;
4000     EXPECT_TRUE(packet.timestamp() == 42U || packet.timestamp() == 43U);
4001     if (packet.timestamp() == 42U) {
4002       EXPECT_FALSE(test_packet_1_found);
4003       EXPECT_EQ(packet.for_testing().str(), first_large_message_str);
4004       test_packet_1_found = true;
4005     } else {
4006       EXPECT_FALSE(test_packet_2_found);
4007       EXPECT_EQ(packet.for_testing().str(), second_large_message_str);
4008       test_packet_2_found = true;
4009     }
4010   }
4011   EXPECT_TRUE(test_packet_1_found && test_packet_2_found);
4012 }
4013 
TEST_P(PerfettoApiTest,BlockingStartAndStop)4014 TEST_P(PerfettoApiTest, BlockingStartAndStop) {
4015   auto* data_source = &data_sources_["my_data_source"];
4016 
4017   // Register a second data source to get a bit more coverage.
4018   perfetto::DataSourceDescriptor dsd;
4019   dsd.set_name("my_data_source2");
4020   MockDataSource2::Register(dsd, kTestDataSourceArg);
4021   perfetto::test::SyncProducers();
4022 
4023   // Setup the trace config.
4024   perfetto::TraceConfig cfg;
4025   cfg.set_duration_ms(500);
4026   cfg.add_buffers()->set_size_kb(1024);
4027   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4028   ds_cfg->set_name("my_data_source");
4029   ds_cfg = cfg.add_data_sources()->mutable_config();
4030   ds_cfg->set_name("my_data_source2");
4031 
4032   // Create a new trace session.
4033   auto* tracing_session = NewTrace(cfg);
4034 
4035   tracing_session->get()->StartBlocking();
4036   EXPECT_TRUE(data_source->on_setup.notified());
4037   EXPECT_TRUE(data_source->on_start.notified());
4038 
4039   tracing_session->get()->StopBlocking();
4040   EXPECT_TRUE(data_source->on_stop.notified());
4041   EXPECT_TRUE(tracing_session->on_stop.notified());
4042   perfetto::test::TracingMuxerImplInternalsForTest::
4043       ClearDataSourceTlsStateOnReset<MockDataSource2>();
4044 }
4045 
TEST_P(PerfettoApiTest,BlockingStartAndStopOnEmptySession)4046 TEST_P(PerfettoApiTest, BlockingStartAndStopOnEmptySession) {
4047   // Setup the trace config.
4048   perfetto::TraceConfig cfg;
4049   cfg.set_duration_ms(500);
4050   cfg.add_buffers()->set_size_kb(1024);
4051   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4052   ds_cfg->set_name("non_existent_data_source");
4053 
4054   // Create a new trace session.
4055   auto* tracing_session = NewTrace(cfg);
4056   tracing_session->get()->StartBlocking();
4057   tracing_session->get()->StopBlocking();
4058   EXPECT_TRUE(tracing_session->on_stop.notified());
4059 }
4060 
TEST_P(PerfettoApiTest,WriteEventsAfterDeferredStop)4061 TEST_P(PerfettoApiTest, WriteEventsAfterDeferredStop) {
4062   auto* data_source = &data_sources_["my_data_source"];
4063   data_source->handle_stop_asynchronously = true;
4064 
4065   // Setup the trace config and start the tracing session.
4066   perfetto::TraceConfig cfg;
4067   cfg.set_duration_ms(500);
4068   cfg.add_buffers()->set_size_kb(1024);
4069   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4070   ds_cfg->set_name("my_data_source");
4071   auto* tracing_session = NewTrace(cfg);
4072   tracing_session->get()->StartBlocking();
4073 
4074   // Stop and wait for the producer to have seen the stop event.
4075   WaitableTestEvent consumer_stop_signal;
4076   tracing_session->get()->SetOnStopCallback(
4077       [&consumer_stop_signal] { consumer_stop_signal.Notify(); });
4078   tracing_session->get()->Stop();
4079   data_source->on_stop.Wait();
4080 
4081   // At this point tracing should be still allowed because of the
4082   // HandleStopAsynchronously() call.
4083   bool lambda_called = false;
4084 
4085   // This usleep is here just to prevent that we accidentally pass the test
4086   // just by virtue of hitting some race. We should be able to trace up until
4087   // 5 seconds after seeing the stop when using the deferred stop mechanism.
4088   std::this_thread::sleep_for(std::chrono::milliseconds(250));
4089 
4090   MockDataSource::Trace([&lambda_called](MockDataSource::TraceContext ctx) {
4091     auto packet = ctx.NewTracePacket();
4092     packet->set_for_testing()->set_str("event written after OnStop");
4093     packet->Finalize();
4094     ctx.Flush();
4095     lambda_called = true;
4096   });
4097   ASSERT_TRUE(lambda_called);
4098 
4099   // Now call the async stop closure. This acks the stop to the service and
4100   // disallows further Trace() calls.
4101   EXPECT_TRUE(data_source->async_stop_closure);
4102   data_source->async_stop_closure();
4103 
4104   // Wait that the stop is propagated to the consumer.
4105   consumer_stop_signal.Wait();
4106 
4107   MockDataSource::Trace([](MockDataSource::TraceContext) {
4108     FAIL() << "Should not be called after the stop is acked";
4109   });
4110 
4111   // Check the contents of the trace.
4112   std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
4113   ASSERT_GE(raw_trace.size(), 0u);
4114   perfetto::protos::gen::Trace trace;
4115   ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
4116   int test_packet_found = 0;
4117   for (const auto& packet : trace.packet()) {
4118     if (!packet.has_for_testing())
4119       continue;
4120     EXPECT_EQ(packet.for_testing().str(), "event written after OnStop");
4121     test_packet_found++;
4122   }
4123   EXPECT_EQ(test_packet_found, 1);
4124 }
4125 
TEST_P(PerfettoApiTest,RepeatedStartAndStop)4126 TEST_P(PerfettoApiTest, RepeatedStartAndStop) {
4127   perfetto::TraceConfig cfg;
4128   cfg.set_duration_ms(500);
4129   cfg.add_buffers()->set_size_kb(1024);
4130   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4131   ds_cfg->set_name("my_data_source");
4132 
4133   for (int i = 0; i < 5; i++) {
4134     auto* tracing_session = NewTrace(cfg);
4135     tracing_session->get()->Start();
4136     std::atomic<bool> stop_called{false};
4137     tracing_session->get()->SetOnStopCallback(
4138         [&stop_called] { stop_called = true; });
4139     tracing_session->get()->StopBlocking();
4140     EXPECT_TRUE(stop_called);
4141   }
4142 }
4143 
TEST_P(PerfettoApiTest,SetupWithFile)4144 TEST_P(PerfettoApiTest, SetupWithFile) {
4145 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4146   if (GetParam() == perfetto::kSystemBackend)
4147     GTEST_SKIP() << "write_into_file + system mode is not supported on Windows";
4148 #endif
4149   auto temp_file = perfetto::test::CreateTempFile();
4150   perfetto::TraceConfig cfg;
4151   cfg.set_duration_ms(500);
4152   cfg.add_buffers()->set_size_kb(1024);
4153   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4154   ds_cfg->set_name("my_data_source");
4155   // Write a trace into |fd|.
4156   auto* tracing_session = NewTrace(cfg, temp_file.fd);
4157   tracing_session->get()->StartBlocking();
4158   tracing_session->get()->StopBlocking();
4159 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4160   // Check that |fd| didn't get closed.
4161   EXPECT_EQ(0, fcntl(temp_file.fd, F_GETFD, 0));
4162 #endif
4163   // Check that the trace got written.
4164   EXPECT_GT(lseek(temp_file.fd, 0, SEEK_END), 0);
4165   EXPECT_EQ(0, close(temp_file.fd));
4166   // Clean up.
4167   EXPECT_EQ(0, remove(temp_file.path.c_str()));
4168 }
4169 
TEST_P(PerfettoApiTest,MultipleRegistrations)4170 TEST_P(PerfettoApiTest, MultipleRegistrations) {
4171   // Attempt to register the same data source again.
4172   perfetto::DataSourceDescriptor dsd;
4173   dsd.set_name("my_data_source");
4174   EXPECT_TRUE(MockDataSource::Register(dsd));
4175   perfetto::test::SyncProducers();
4176 
4177   // Setup the trace config.
4178   perfetto::TraceConfig cfg;
4179   cfg.set_duration_ms(500);
4180   cfg.add_buffers()->set_size_kb(1024);
4181   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4182   ds_cfg->set_name("my_data_source");
4183 
4184   // Create a new trace session.
4185   auto* tracing_session = NewTrace(cfg);
4186   tracing_session->get()->StartBlocking();
4187 
4188   // Emit one trace event.
4189   std::atomic<int> trace_lambda_calls{0};
4190   MockDataSource::Trace([&trace_lambda_calls](MockDataSource::TraceContext) {
4191     trace_lambda_calls++;
4192   });
4193 
4194   // Make sure the data source got called only once.
4195   tracing_session->get()->StopBlocking();
4196   EXPECT_EQ(trace_lambda_calls, 1);
4197 }
4198 
TEST_P(PerfettoApiTest,CustomIncrementalState)4199 TEST_P(PerfettoApiTest, CustomIncrementalState) {
4200   perfetto::DataSourceDescriptor dsd;
4201   dsd.set_name("incr_data_source");
4202   TestIncrementalDataSource::Register(dsd);
4203   perfetto::test::SyncProducers();
4204 
4205   // Setup the trace config.
4206   perfetto::TraceConfig cfg;
4207   cfg.set_duration_ms(500);
4208   cfg.add_buffers()->set_size_kb(1024);
4209   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4210   ds_cfg->set_name("incr_data_source");
4211 
4212   // Create a new trace session.
4213   auto* tracing_session = NewTrace(cfg);
4214   tracing_session->get()->StartBlocking();
4215 
4216   // First emit a no-op trace event that initializes the incremental state as a
4217   // side effect.
4218   TestIncrementalDataSource::Trace(
4219       [](TestIncrementalDataSource::TraceContext) {});
4220   EXPECT_TRUE(TestIncrementalState::constructed);
4221 
4222   // Check that the incremental state is carried across trace events.
4223   TestIncrementalDataSource::Trace(
4224       [](TestIncrementalDataSource::TraceContext ctx) {
4225         auto* state = ctx.GetIncrementalState();
4226         EXPECT_TRUE(state);
4227         EXPECT_EQ(100, state->count);
4228         state->count++;
4229       });
4230 
4231   TestIncrementalDataSource::Trace(
4232       [](TestIncrementalDataSource::TraceContext ctx) {
4233         auto* state = ctx.GetIncrementalState();
4234         EXPECT_EQ(101, state->count);
4235       });
4236 
4237   // Make sure the incremental state gets cleaned up between sessions.
4238   tracing_session->get()->StopBlocking();
4239   tracing_session = NewTrace(cfg);
4240   tracing_session->get()->StartBlocking();
4241   TestIncrementalDataSource::Trace(
4242       [](TestIncrementalDataSource::TraceContext ctx) {
4243         auto* state = ctx.GetIncrementalState();
4244         EXPECT_TRUE(TestIncrementalState::destroyed);
4245         EXPECT_TRUE(state);
4246         EXPECT_EQ(100, state->count);
4247       });
4248   tracing_session->get()->StopBlocking();
4249   perfetto::test::TracingMuxerImplInternalsForTest::
4250       ClearDataSourceTlsStateOnReset<TestIncrementalDataSource>();
4251 }
4252 
4253 const void* const kKey1 = &kKey1;
4254 const void* const kKey2 = &kKey2;
4255 
TEST_P(PerfettoApiTest,TrackEventUserData)4256 TEST_P(PerfettoApiTest, TrackEventUserData) {
4257   // Create a new trace session.
4258   auto* tracing_session = NewTraceWithCategories({"foo"});
4259   tracing_session->get()->StartBlocking();
4260   perfetto::TrackEventTlsStateUserData* data_1_ptr = nullptr;
4261   perfetto::TrackEventTlsStateUserData* data_2_ptr = nullptr;
4262 
4263   TRACE_EVENT_BEGIN(
4264       "foo", "E", [&data_1_ptr, &data_2_ptr](perfetto::EventContext& ctx) {
4265         EXPECT_EQ(nullptr, ctx.GetTlsUserData(kKey1));
4266         EXPECT_EQ(nullptr, ctx.GetTlsUserData(kKey2));
4267         std::unique_ptr<perfetto::TrackEventTlsStateUserData> data_1 =
4268             std::make_unique<perfetto::TrackEventTlsStateUserData>();
4269         data_1_ptr = data_1.get();
4270         std::unique_ptr<perfetto::TrackEventTlsStateUserData> data_2 =
4271             std::make_unique<perfetto::TrackEventTlsStateUserData>();
4272         data_2_ptr = data_2.get();
4273         ctx.SetTlsUserData(kKey1, std::move(data_1));
4274         ctx.SetTlsUserData(kKey2, std::move(data_2));
4275         EXPECT_EQ(data_1_ptr, ctx.GetTlsUserData(kKey1));
4276         EXPECT_EQ(data_2_ptr, ctx.GetTlsUserData(kKey2));
4277       });
4278   TRACE_EVENT_END("foo");
4279   TRACE_EVENT_BEGIN("foo", "F",
4280                     [&data_1_ptr, &data_2_ptr](perfetto::EventContext& ctx) {
4281                       EXPECT_EQ(data_1_ptr, ctx.GetTlsUserData(kKey1));
4282                       EXPECT_EQ(data_2_ptr, ctx.GetTlsUserData(kKey2));
4283                     });
4284   TRACE_EVENT_END("foo");
4285 
4286   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
4287 
4288   EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
4289               ElementsAre("B:foo.E", "E", "B:foo.F", "E"));
4290 
4291   // Expect that the TLS User Data is cleared between tracing sessions.
4292   tracing_session = NewTraceWithCategories({"foo"});
4293   tracing_session->get()->StartBlocking();
4294 
4295   TRACE_EVENT_BEGIN("foo", "E", [](perfetto::EventContext& ctx) {
4296     EXPECT_EQ(nullptr, ctx.GetTlsUserData(kKey1));
4297     EXPECT_EQ(nullptr, ctx.GetTlsUserData(kKey2));
4298   });
4299   TRACE_EVENT_END("foo");
4300 
4301   raw_trace = StopSessionAndReturnBytes(tracing_session);
4302   EXPECT_THAT(ReadSlicesFromTrace(raw_trace), ElementsAre("B:foo.E", "E"));
4303 }
4304 
TEST_P(PerfettoApiTest,OnFlush)4305 TEST_P(PerfettoApiTest, OnFlush) {
4306   auto* data_source = &data_sources_["my_data_source"];
4307 
4308   // Setup the trace config.
4309   perfetto::TraceConfig cfg;
4310   cfg.add_buffers()->set_size_kb(1024);
4311   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4312   ds_cfg->set_name("my_data_source");
4313 
4314   // Create a new trace session.
4315   auto* tracing_session = NewTrace(cfg);
4316 
4317   tracing_session->get()->StartBlocking();
4318 
4319   WaitableTestEvent producer_on_flush;
4320   WaitableTestEvent consumer_flush_done;
4321 
4322   data_source->on_flush_callback = [&](perfetto::FlushFlags flush_flags) {
4323     EXPECT_FALSE(consumer_flush_done.notified());
4324     EXPECT_EQ(flush_flags.initiator(),
4325               perfetto::FlushFlags::Initiator::kConsumerSdk);
4326     EXPECT_EQ(flush_flags.reason(), perfetto::FlushFlags::Reason::kExplicit);
4327     producer_on_flush.Notify();
4328     MockDataSource::Trace([](MockDataSource::TraceContext ctx) {
4329       ctx.NewTracePacket()->set_for_testing()->set_str("on-flush");
4330       ctx.Flush();
4331     });
4332   };
4333 
4334   tracing_session->get()->Flush([&](bool success) {
4335     EXPECT_TRUE(success);
4336     EXPECT_TRUE(producer_on_flush.notified());
4337     consumer_flush_done.Notify();
4338   });
4339 
4340   producer_on_flush.Wait();
4341   consumer_flush_done.Wait();
4342 
4343   tracing_session->get()->StopBlocking();
4344 
4345   data_source->on_stop.Wait();
4346 
4347   std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
4348   ASSERT_GE(raw_trace.size(), 0u);
4349 
4350   perfetto::protos::gen::Trace trace;
4351   ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
4352   EXPECT_THAT(
4353       trace.packet(),
4354       Contains(Property(
4355           &perfetto::protos::gen::TracePacket::for_testing,
4356           Property(&perfetto::protos::gen::TestEvent::str, "on-flush"))));
4357 }
4358 
TEST_P(PerfettoApiTest,OnFlushAsync)4359 TEST_P(PerfettoApiTest, OnFlushAsync) {
4360   auto* data_source = &data_sources_["my_data_source"];
4361 
4362   // Setup the trace config.
4363   perfetto::TraceConfig cfg;
4364   cfg.add_buffers()->set_size_kb(1024);
4365   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4366   ds_cfg->set_name("my_data_source");
4367 
4368   // Create a new trace session.
4369   auto* tracing_session = NewTrace(cfg);
4370 
4371   tracing_session->get()->StartBlocking();
4372 
4373   WaitableTestEvent consumer_flush_done;
4374 
4375   data_source->handle_flush_asynchronously = true;
4376   data_source->on_flush_callback = [&](perfetto::FlushFlags) {
4377     EXPECT_FALSE(consumer_flush_done.notified());
4378   };
4379 
4380   tracing_session->get()->Flush([&](bool success) {
4381     EXPECT_TRUE(success);
4382     consumer_flush_done.Notify();
4383   });
4384 
4385   data_source->on_flush.Wait();
4386   perfetto::test::SyncProducers();
4387   EXPECT_FALSE(consumer_flush_done.notified());
4388 
4389   // Finish the flush asynchronously
4390   MockDataSource::Trace([](MockDataSource::TraceContext ctx) {
4391     ctx.NewTracePacket()->set_for_testing()->set_str("on-flush");
4392     ctx.Flush();
4393   });
4394   data_source->async_flush_closure();
4395 
4396   consumer_flush_done.Wait();
4397 
4398   tracing_session->get()->StopBlocking();
4399 
4400   data_source->on_stop.Wait();
4401 
4402   std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
4403   ASSERT_GE(raw_trace.size(), 0u);
4404 
4405   perfetto::protos::gen::Trace trace;
4406   ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
4407   EXPECT_THAT(
4408       trace.packet(),
4409       Contains(Property(
4410           &perfetto::protos::gen::TracePacket::for_testing,
4411           Property(&perfetto::protos::gen::TestEvent::str, "on-flush"))));
4412 }
4413 
4414 // Regression test for b/139110180. Checks that GetDataSourceLocked() can be
4415 // called from OnStart() and OnStop() callbacks without deadlocking.
TEST_P(PerfettoApiTest,GetDataSourceLockedFromCallbacks)4416 TEST_P(PerfettoApiTest, GetDataSourceLockedFromCallbacks) {
4417   auto* data_source = &data_sources_["my_data_source"];
4418 
4419   // Setup the trace config.
4420   perfetto::TraceConfig cfg;
4421   cfg.set_duration_ms(1);
4422   cfg.add_buffers()->set_size_kb(1024);
4423   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4424   ds_cfg->set_name("my_data_source");
4425 
4426   // Create a new trace session.
4427   auto* tracing_session = NewTrace(cfg);
4428 
4429   data_source->on_start_callback = [] {
4430     MockDataSource::Trace([](MockDataSource::TraceContext ctx) {
4431       ctx.NewTracePacket()->set_for_testing()->set_str("on-start");
4432       auto ds = ctx.GetDataSourceLocked();
4433       ASSERT_TRUE(!!ds);
4434       ctx.NewTracePacket()->set_for_testing()->set_str("on-start-locked");
4435     });
4436   };
4437 
4438   data_source->on_stop_callback = [] {
4439     MockDataSource::Trace([](MockDataSource::TraceContext ctx) {
4440       ctx.NewTracePacket()->set_for_testing()->set_str("on-stop");
4441       auto ds = ctx.GetDataSourceLocked();
4442       ASSERT_TRUE(!!ds);
4443       ctx.NewTracePacket()->set_for_testing()->set_str("on-stop-locked");
4444       ctx.Flush();
4445     });
4446   };
4447 
4448   tracing_session->get()->Start();
4449   data_source->on_stop.Wait();
4450   tracing_session->on_stop.Wait();
4451 
4452   std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
4453   ASSERT_GE(raw_trace.size(), 0u);
4454 
4455   perfetto::protos::gen::Trace trace;
4456   ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
4457   int packets_found = 0;
4458   for (const auto& packet : trace.packet()) {
4459     if (!packet.has_for_testing())
4460       continue;
4461     packets_found |= packet.for_testing().str() == "on-start" ? 1 : 0;
4462     packets_found |= packet.for_testing().str() == "on-start-locked" ? 2 : 0;
4463     packets_found |= packet.for_testing().str() == "on-stop" ? 4 : 0;
4464     packets_found |= packet.for_testing().str() == "on-stop-locked" ? 8 : 0;
4465   }
4466   EXPECT_EQ(packets_found, 1 | 2 | 4 | 8);
4467 }
4468 
TEST_P(PerfettoApiTest,OnStartCallback)4469 TEST_P(PerfettoApiTest, OnStartCallback) {
4470   perfetto::TraceConfig cfg;
4471   cfg.set_duration_ms(60000);
4472   cfg.add_buffers()->set_size_kb(1024);
4473   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4474   ds_cfg->set_name("track_event");
4475   auto* tracing_session = NewTrace(cfg);
4476 
4477   WaitableTestEvent got_start;
4478   tracing_session->get()->SetOnStartCallback([&] { got_start.Notify(); });
4479   tracing_session->get()->Start();
4480   got_start.Wait();
4481 
4482   tracing_session->get()->StopBlocking();
4483 }
4484 
TEST_P(PerfettoApiTest,OnErrorCallback)4485 TEST_P(PerfettoApiTest, OnErrorCallback) {
4486   perfetto::TraceConfig cfg;
4487 
4488   // Requesting too long |duration_ms| will cause EnableTracing() to fail.
4489   cfg.set_duration_ms(static_cast<uint32_t>(-1));
4490   cfg.add_buffers()->set_size_kb(1024);
4491   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4492   ds_cfg->set_name("track_event");
4493   auto* tracing_session = NewTrace(cfg);
4494 
4495   WaitableTestEvent got_error;
4496   tracing_session->get()->SetOnErrorCallback([&](perfetto::TracingError error) {
4497     EXPECT_EQ(perfetto::TracingError::kTracingFailed, error.code);
4498     EXPECT_FALSE(error.message.empty());
4499     got_error.Notify();
4500   });
4501 
4502   tracing_session->get()->Start();
4503   got_error.Wait();
4504 
4505   // Registered error callback will be triggered also by OnDisconnect()
4506   // function. This may happen after exiting this test what would result in
4507   // system crash (|got_error| will not exist at that time). To prevent that
4508   // scenario, error callback has to be cleared.
4509   tracing_session->get()->SetOnErrorCallback(nullptr);
4510   tracing_session->get()->StopBlocking();
4511 }
4512 
TEST_P(PerfettoApiTest,UnsupportedBackend)4513 TEST_P(PerfettoApiTest, UnsupportedBackend) {
4514   // Create a new trace session with an invalid backend type specified.
4515   // Specifically, the custom backend isn't initialized for these tests.
4516   perfetto::TraceConfig cfg;
4517   cfg.add_buffers()->set_size_kb(1024);
4518   auto* tracing_session = NewTrace(cfg, perfetto::BackendType::kCustomBackend);
4519 
4520   // Creating the consumer should cause an asynchronous disconnect error.
4521   WaitableTestEvent got_error;
4522   tracing_session->get()->SetOnErrorCallback([&](perfetto::TracingError error) {
4523     EXPECT_EQ(perfetto::TracingError::kDisconnected, error.code);
4524     EXPECT_FALSE(error.message.empty());
4525     got_error.Notify();
4526   });
4527   got_error.Wait();
4528 
4529   // Clear the callback for test tear down.
4530   tracing_session->get()->SetOnErrorCallback(nullptr);
4531   // Synchronize the consumer channel to ensure the callback has propagated.
4532   tracing_session->get()->StopBlocking();
4533 }
4534 
TEST_P(PerfettoApiTest,ForbiddenConsumer)4535 TEST_P(PerfettoApiTest, ForbiddenConsumer) {
4536   g_test_tracing_policy->should_allow_consumer_connection = false;
4537 
4538   // Create a new trace session while consumer connections are forbidden.
4539   perfetto::TraceConfig cfg;
4540   cfg.add_buffers()->set_size_kb(1024);
4541   auto* tracing_session = NewTrace(cfg);
4542 
4543   // Creating the consumer should cause an asynchronous disconnect error.
4544   WaitableTestEvent got_error;
4545   tracing_session->get()->SetOnErrorCallback([&](perfetto::TracingError error) {
4546     EXPECT_EQ(perfetto::TracingError::kDisconnected, error.code);
4547     EXPECT_FALSE(error.message.empty());
4548     got_error.Notify();
4549   });
4550   got_error.Wait();
4551 
4552   // Clear the callback for test tear down.
4553   tracing_session->get()->SetOnErrorCallback(nullptr);
4554   // Synchronize the consumer channel to ensure the callback has propagated.
4555   tracing_session->get()->StopBlocking();
4556 
4557   g_test_tracing_policy->should_allow_consumer_connection = true;
4558 }
4559 
TEST_P(PerfettoApiTest,GetTraceStats)4560 TEST_P(PerfettoApiTest, GetTraceStats) {
4561   perfetto::TraceConfig cfg;
4562   cfg.set_duration_ms(500);
4563   cfg.add_buffers()->set_size_kb(1024);
4564   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4565   ds_cfg->set_name("track_event");
4566   auto* tracing_session = NewTrace(cfg);
4567   tracing_session->get()->StartBlocking();
4568 
4569   // Asynchronous read.
4570   WaitableTestEvent got_stats;
4571   tracing_session->get()->GetTraceStats(
4572       [&got_stats](perfetto::TracingSession::GetTraceStatsCallbackArgs args) {
4573         perfetto::protos::gen::TraceStats trace_stats;
4574         EXPECT_TRUE(args.success);
4575         EXPECT_TRUE(trace_stats.ParseFromArray(args.trace_stats_data.data(),
4576                                                args.trace_stats_data.size()));
4577         EXPECT_EQ(1, trace_stats.buffer_stats_size());
4578         got_stats.Notify();
4579       });
4580   got_stats.Wait();
4581 
4582   // Blocking read.
4583   auto stats = tracing_session->get()->GetTraceStatsBlocking();
4584   perfetto::protos::gen::TraceStats trace_stats;
4585   EXPECT_TRUE(stats.success);
4586   EXPECT_TRUE(trace_stats.ParseFromArray(stats.trace_stats_data.data(),
4587                                          stats.trace_stats_data.size()));
4588   EXPECT_EQ(1, trace_stats.buffer_stats_size());
4589 
4590   tracing_session->get()->StopBlocking();
4591 }
4592 
TEST_P(PerfettoApiTest,CustomDataSource)4593 TEST_P(PerfettoApiTest, CustomDataSource) {
4594   perfetto::TraceConfig cfg;
4595   cfg.add_buffers()->set_size_kb(1024);
4596   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4597   ds_cfg->set_name("CustomDataSource");
4598   auto* tracing_session = NewTrace(cfg);
4599   tracing_session->get()->StartBlocking();
4600   CustomDataSource::Trace([](CustomDataSource::TraceContext ctx) {
4601     auto packet = ctx.NewTracePacket();
4602     packet->set_timestamp(4200000);
4603     packet->set_for_testing()->set_str("Test String");
4604   });
4605   CustomDataSource::Trace(
4606       [](CustomDataSource::TraceContext ctx) { ctx.Flush(); });
4607 
4608   tracing_session->get()->StopBlocking();
4609   auto bytes = tracing_session->get()->ReadTraceBlocking();
4610   perfetto::protos::gen::Trace parsed_trace;
4611   EXPECT_TRUE(parsed_trace.ParseFromArray(bytes.data(), bytes.size()));
4612   bool found_for_testing = false;
4613   for (auto& packet : parsed_trace.packet()) {
4614     if (packet.has_for_testing()) {
4615       EXPECT_FALSE(found_for_testing);
4616       found_for_testing = true;
4617       EXPECT_EQ(4200000u, packet.timestamp());
4618       EXPECT_EQ("Test String", packet.for_testing().str());
4619     }
4620   }
4621   EXPECT_TRUE(found_for_testing);
4622 }
4623 
TEST_P(PerfettoApiTest,QueryServiceState)4624 TEST_P(PerfettoApiTest, QueryServiceState) {
4625   class QueryTestDataSource : public perfetto::DataSource<QueryTestDataSource> {
4626   };
4627   RegisterDataSource<QueryTestDataSource>("query_test_data_source");
4628   perfetto::test::SyncProducers();
4629 
4630   auto tracing_session =
4631       perfetto::Tracing::NewTrace(/*BackendType=*/GetParam());
4632   // Asynchronous read.
4633   WaitableTestEvent got_state;
4634   tracing_session->QueryServiceState(
4635       [&got_state](
4636           perfetto::TracingSession::QueryServiceStateCallbackArgs result) {
4637         perfetto::protos::gen::TracingServiceState state;
4638         EXPECT_TRUE(result.success);
4639         EXPECT_TRUE(state.ParseFromArray(result.service_state_data.data(),
4640                                          result.service_state_data.size()));
4641         EXPECT_EQ(1, state.producers_size());
4642         EXPECT_NE(std::string::npos,
4643                   state.producers()[0].name().find("integrationtest"));
4644         bool found_ds = false;
4645         for (const auto& ds : state.data_sources())
4646           found_ds |= ds.ds_descriptor().name() == "query_test_data_source";
4647         EXPECT_TRUE(found_ds);
4648         got_state.Notify();
4649       });
4650   got_state.Wait();
4651 
4652   // Blocking read.
4653   auto result = tracing_session->QueryServiceStateBlocking();
4654   perfetto::protos::gen::TracingServiceState state;
4655   EXPECT_TRUE(result.success);
4656   EXPECT_TRUE(state.ParseFromArray(result.service_state_data.data(),
4657                                    result.service_state_data.size()));
4658   EXPECT_EQ(1, state.producers_size());
4659   EXPECT_NE(std::string::npos,
4660             state.producers()[0].name().find("integrationtest"));
4661   bool found_ds = false;
4662   for (const auto& ds : state.data_sources())
4663     found_ds |= ds.ds_descriptor().name() == "query_test_data_source";
4664   EXPECT_TRUE(found_ds);
4665   perfetto::test::TracingMuxerImplInternalsForTest::
4666       ClearDataSourceTlsStateOnReset<QueryTestDataSource>();
4667 }
4668 
TEST_P(PerfettoApiTest,UpdateDataSource)4669 TEST_P(PerfettoApiTest, UpdateDataSource) {
4670   class UpdateTestDataSource
4671       : public perfetto::DataSource<UpdateTestDataSource> {};
4672 
4673   perfetto::DataSourceDescriptor dsd;
4674   dsd.set_name("update_test_data_source");
4675 
4676   RegisterDataSource<UpdateTestDataSource>(dsd);
4677 
4678   {
4679     protozero::HeapBuffered<perfetto::protos::pbzero::TrackEventDescriptor> ted;
4680     auto cat = ted->add_available_categories();
4681     cat->set_name("new_cat");
4682     dsd.set_track_event_descriptor_raw(ted.SerializeAsString());
4683   }
4684 
4685   UpdateDataSource<UpdateTestDataSource>(dsd);
4686 
4687   perfetto::test::SyncProducers();
4688 
4689   auto tracing_session =
4690       perfetto::Tracing::NewTrace(/*BackendType=*/GetParam());
4691   // Blocking read.
4692   auto result = tracing_session->QueryServiceStateBlocking();
4693   perfetto::protos::gen::TracingServiceState state;
4694   EXPECT_TRUE(result.success);
4695   EXPECT_TRUE(state.ParseFromArray(result.service_state_data.data(),
4696                                    result.service_state_data.size()));
4697   EXPECT_EQ(1, state.producers_size());
4698   EXPECT_NE(std::string::npos,
4699             state.producers()[0].name().find("integrationtest"));
4700   bool found_ds = false;
4701   for (const auto& ds : state.data_sources()) {
4702     if (ds.ds_descriptor().name() == "update_test_data_source") {
4703       found_ds = true;
4704       perfetto::protos::gen::TrackEventDescriptor ted;
4705       auto desc_raw = ds.ds_descriptor().track_event_descriptor_raw();
4706       EXPECT_TRUE(ted.ParseFromArray(desc_raw.data(), desc_raw.size()));
4707       EXPECT_EQ(ted.available_categories_size(), 1);
4708       EXPECT_EQ(ted.available_categories()[0].name(), "new_cat");
4709     }
4710   }
4711   EXPECT_TRUE(found_ds);
4712   perfetto::test::TracingMuxerImplInternalsForTest::
4713       ClearDataSourceTlsStateOnReset<UpdateTestDataSource>();
4714 }
4715 
TEST_P(PerfettoApiTest,NoFlushFlag)4716 TEST_P(PerfettoApiTest, NoFlushFlag) {
4717   class NoFlushDataSource : public perfetto::DataSource<NoFlushDataSource> {};
4718 
4719   class FlushDataSource : public perfetto::DataSource<FlushDataSource> {
4720    public:
4721     void OnFlush(const FlushArgs&) override {}
4722   };
4723 
4724   perfetto::DataSourceDescriptor dsd_no_flush;
4725   dsd_no_flush.set_name("no_flush_data_source");
4726   RegisterDataSource<NoFlushDataSource>(dsd_no_flush);
4727 
4728   perfetto::DataSourceDescriptor dsd_flush;
4729   dsd_flush.set_name("flush_data_source");
4730   RegisterDataSource<FlushDataSource>(dsd_flush);
4731 
4732   auto cleanup = MakeCleanup([&] {
4733     perfetto::test::TracingMuxerImplInternalsForTest::
4734         ClearDataSourceTlsStateOnReset<FlushDataSource>();
4735     perfetto::test::TracingMuxerImplInternalsForTest::
4736         ClearDataSourceTlsStateOnReset<NoFlushDataSource>();
4737   });
4738 
4739   auto tracing_session = perfetto::Tracing::NewTrace(/*backend=*/GetParam());
4740 
4741   perfetto::test::SyncProducers();
4742 
4743   auto result = tracing_session->QueryServiceStateBlocking();
4744   perfetto::protos::gen::TracingServiceState state;
4745   ASSERT_TRUE(result.success);
4746   ASSERT_TRUE(state.ParseFromArray(result.service_state_data.data(),
4747                                    result.service_state_data.size()));
4748   size_t ds_count_no_flush = 0;
4749   size_t ds_count_flush = 0;
4750   size_t ds_count_track_event = 0;
4751   for (const auto& ds : state.data_sources()) {
4752     if (ds.ds_descriptor().name() == "no_flush_data_source") {
4753       EXPECT_TRUE(ds.ds_descriptor().no_flush());
4754       ds_count_no_flush++;
4755     } else if (ds.ds_descriptor().name() == "flush_data_source") {
4756       EXPECT_FALSE(ds.ds_descriptor().no_flush());
4757       ds_count_flush++;
4758     } else if (ds.ds_descriptor().name() == "track_event") {
4759       EXPECT_TRUE(ds.ds_descriptor().no_flush());
4760       ds_count_track_event++;
4761     }
4762   }
4763   EXPECT_EQ(ds_count_no_flush, 1u);
4764   EXPECT_EQ(ds_count_flush, 1u);
4765   EXPECT_EQ(ds_count_track_event, 1u);
4766 
4767   dsd_no_flush.set_track_event_descriptor_raw("DESC_NO");
4768   UpdateDataSource<NoFlushDataSource>(dsd_no_flush);
4769   dsd_flush.set_track_event_descriptor_raw("DESC_");
4770   UpdateDataSource<FlushDataSource>(dsd_flush);
4771 
4772   result = tracing_session->QueryServiceStateBlocking();
4773   ASSERT_TRUE(result.success);
4774   ASSERT_TRUE(state.ParseFromArray(result.service_state_data.data(),
4775                                    result.service_state_data.size()));
4776   ds_count_no_flush = 0;
4777   ds_count_flush = 0;
4778   for (const auto& ds : state.data_sources()) {
4779     if (ds.ds_descriptor().name() == "no_flush_data_source") {
4780       EXPECT_TRUE(ds.ds_descriptor().no_flush());
4781       EXPECT_EQ(ds.ds_descriptor().track_event_descriptor_raw(), "DESC_NO");
4782       ds_count_no_flush++;
4783     } else if (ds.ds_descriptor().name() == "flush_data_source") {
4784       EXPECT_FALSE(ds.ds_descriptor().no_flush());
4785       EXPECT_EQ(ds.ds_descriptor().track_event_descriptor_raw(), "DESC_");
4786       ds_count_flush++;
4787     }
4788   }
4789   EXPECT_EQ(ds_count_no_flush, 1u);
4790   EXPECT_EQ(ds_count_flush, 1u);
4791 }
4792 
TEST_P(PerfettoApiTest,LegacyTraceEventsCopyDynamicString)4793 TEST_P(PerfettoApiTest, LegacyTraceEventsCopyDynamicString) {
4794   char ptr1[] = "A1";
4795   char ptr2[] = "B1";
4796   char arg_name1[] = "C1";
4797   char arg_name2[] = "D1";
4798   auto* tracing_session = NewTraceWithCategories({"cat"});
4799   tracing_session->get()->StartBlocking();
4800   {
4801     TRACE_EVENT_MARK_WITH_TIMESTAMP0("cat", ptr1, MyTimestamp{0});
4802     ptr1[1] = '3';
4803     // Old value of event name ("A1") is recorded here in trace.
4804     // The reason being, in legacy macros, event name was expected to be static
4805     // by default unless `_COPY` version of these macro is used.
4806     // Perfetto is caching pointer values and if a event-name-pointer matches an
4807     // existing pointer, it ASSUMES the string-value of new pointer is same as
4808     // string-value of the cached pointer when it was cached.
4809     // and hence it assign the same intern-id to second event.
4810     TRACE_EVENT_MARK_WITH_TIMESTAMP0("cat", ptr1, MyTimestamp{0});
4811   }
4812   {
4813     TRACE_EVENT_COPY_MARK_WITH_TIMESTAMP("cat", ptr2, MyTimestamp{0});
4814     ptr2[1] = '4';
4815     TRACE_EVENT_COPY_MARK_WITH_TIMESTAMP("cat", ptr2, MyTimestamp{0});
4816   }
4817   {
4818     TRACE_EVENT_INSTANT1("cat", "event_name", TRACE_EVENT_FLAG_NONE, arg_name1,
4819                          /*arg_value=*/5);
4820     arg_name1[1] = '5';
4821     // Since we don't use the _COPY version here, this event will record the old
4822     // value of arg_name1 (see earlier comment for full explanation).
4823     TRACE_EVENT_INSTANT1("cat", "event_name", TRACE_EVENT_FLAG_NONE, arg_name1,
4824                          /*arg_value=*/5);
4825   }
4826   {
4827     TRACE_EVENT_COPY_INSTANT1("cat", "event_name", TRACE_EVENT_FLAG_NONE,
4828                               arg_name2, /*arg_value=*/5);
4829     arg_name2[1] = '6';
4830     TRACE_EVENT_COPY_INSTANT1("cat", "event_name", TRACE_EVENT_FLAG_NONE,
4831                               arg_name2, /*arg_value=*/5);
4832   }
4833   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
4834   EXPECT_THAT(
4835       slices,
4836       ElementsAre("[track=0]Legacy_R:cat.A1", "[track=0]Legacy_R:cat.A1",
4837                   "[track=0]Legacy_R:cat.B1", "[track=0]Legacy_R:cat.B4",
4838                   "[track=0]I:cat.event_name(C1=(int)5)",
4839                   "[track=0]I:cat.event_name(C1=(int)5)",
4840                   "[track=0]I:cat.event_name(D1=(int)5)",
4841                   "[track=0]I:cat.event_name(D6=(int)5)"));
4842 }
4843 
TEST_P(PerfettoApiTest,LegacyTraceEvents)4844 TEST_P(PerfettoApiTest, LegacyTraceEvents) {
4845   auto is_new_session = [] {
4846     bool result;
4847     TRACE_EVENT_IS_NEW_TRACE(&result);
4848     return result;
4849   };
4850 
4851   // Create a new trace session.
4852   EXPECT_FALSE(is_new_session());
4853   auto* tracing_session =
4854       NewTraceWithCategories({"cat", TRACE_DISABLED_BY_DEFAULT("cat")});
4855   tracing_session->get()->StartBlocking();
4856   EXPECT_TRUE(is_new_session());
4857   EXPECT_FALSE(is_new_session());
4858 
4859   // Basic events.
4860   TRACE_EVENT_INSTANT0("cat", "LegacyEvent", TRACE_EVENT_SCOPE_GLOBAL);
4861   TRACE_EVENT_BEGIN1("cat", "LegacyEvent", "arg", 123);
4862   TRACE_EVENT_END2("cat", "LegacyEvent", "arg", "string", "arg2", 0.123f);
4863 
4864   // Scoped event.
4865   { TRACE_EVENT0("cat", "ScopedLegacyEvent"); }
4866 
4867   // Event with flow (and disabled category).
4868   TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("cat"), "LegacyFlowEvent",
4869                          0xdadacafe, TRACE_EVENT_FLAG_FLOW_IN);
4870 
4871   // Event with timestamp.
4872   TRACE_EVENT_INSTANT_WITH_TIMESTAMP0("cat", "LegacyInstantEvent",
4873                                       TRACE_EVENT_SCOPE_GLOBAL,
4874                                       MyTimestamp{123456789ul});
4875 
4876   // Event with id.
4877   TRACE_COUNTER1("cat", "LegacyCounter", 1234);
4878   TRACE_COUNTER_ID1("cat", "LegacyCounterWithId", 1234, 9000);
4879 
4880   // Metadata event.
4881   TRACE_EVENT_METADATA1("cat", "LegacyMetadata", "obsolete", true);
4882 
4883   // Async events.
4884   TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP_AND_FLAGS0(
4885       "cat", "LegacyAsync", 5678, MyTimestamp{4}, TRACE_EVENT_FLAG_NONE);
4886   TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0("cat", "LegacyAsync", 5678,
4887                                                  MyTimestamp{5});
4888   TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_FLAGS0("cat", "LegacyAsync2", 9000,
4889                                                TRACE_EVENT_FLAG_NONE);
4890   TRACE_EVENT_NESTABLE_ASYNC_END_WITH_FLAGS0("cat", "LegacyAsync2", 9000,
4891                                              TRACE_EVENT_FLAG_NONE);
4892   TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_FLAGS0("cat", "LegacyAsync3", 9001,
4893                                                TRACE_EVENT_FLAG_NONE);
4894   TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP_AND_FLAGS0(
4895       "cat", "LegacyAsync3", 9001, MyTimestamp{6}, TRACE_EVENT_FLAG_NONE);
4896 
4897   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
4898   EXPECT_THAT(
4899       slices,
4900       ElementsAre(
4901           "[track=0]I:cat.LegacyEvent", "B:cat.LegacyEvent(arg=(int)123)",
4902           "E(arg=(string)string,arg2=(double)0.123)", "B:cat.ScopedLegacyEvent",
4903           "E",
4904           "B(bind_id=3671771902)(flow_direction=1):disabled-by-default-cat."
4905           "LegacyFlowEvent",
4906           "[track=0]I:cat.LegacyInstantEvent",
4907           "[track=0]Legacy_C:cat.LegacyCounter(value=(int)1234)",
4908           "[track=0]Legacy_C(unscoped_id=1234):cat.LegacyCounterWithId(value=("
4909           "int)9000)",
4910           "[track=0]Legacy_M:cat.LegacyMetadata",
4911           "[track=0]Legacy_b(unscoped_id=5678):cat.LegacyAsync",
4912           "[track=0]Legacy_e(unscoped_id=5678):cat.LegacyAsync",
4913           "[track=0]Legacy_b(unscoped_id=9000):cat.LegacyAsync2",
4914           "[track=0]Legacy_e(unscoped_id=9000):cat.LegacyAsync2",
4915           "[track=0]Legacy_b(unscoped_id=9001):cat.LegacyAsync3",
4916           "[track=0]Legacy_e(unscoped_id=9001):cat.LegacyAsync3"));
4917 }
4918 
TEST_P(PerfettoApiTest,LegacyTraceEventsAndClockSnapshots)4919 TEST_P(PerfettoApiTest, LegacyTraceEventsAndClockSnapshots) {
4920   auto* tracing_session = NewTraceWithCategories({"cat"});
4921   tracing_session->get()->StartBlocking();
4922 
4923   {
4924     TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("cat", "LegacyAsync", 5678);
4925 
4926     perfetto::test::TracingMuxerImplInternalsForTest::ClearIncrementalState();
4927 
4928     TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(
4929         "cat", "LegacyAsyncWithTimestamp", 5678, MyTimestamp{1});
4930     TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(
4931         "cat", "LegacyAsyncWithTimestamp", 5678, MyTimestamp{2});
4932 
4933     perfetto::test::TracingMuxerImplInternalsForTest::ClearIncrementalState();
4934 
4935     TRACE_EVENT_NESTABLE_ASYNC_END0("cat", "LegacyAsync", 5678);
4936   }
4937 
4938   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
4939 
4940   // Check that clock snapshots are monotonic (per sequence) and don't contain
4941   // timestamps from trace events with explicit timestamps.
4942   struct ClockPerSequence {
4943     uint64_t seq_id = 0;
4944     uint64_t clock_id = 0;
4945     bool operator<(const struct ClockPerSequence& other) const {
4946       return std::tie(seq_id, clock_id) <
4947              std::tie(other.seq_id, other.clock_id);
4948     }
4949   };
4950   std::map<ClockPerSequence, uint64_t> last_clock_ts;
4951   for (const auto& packet : trace.packet()) {
4952     if (packet.has_clock_snapshot()) {
4953       for (auto& clock : packet.clock_snapshot().clocks()) {
4954         if (!clock.is_incremental()) {
4955           uint64_t ts = clock.timestamp();
4956           ClockPerSequence c;
4957           c.seq_id = packet.trusted_packet_sequence_id();
4958           c.clock_id = clock.clock_id();
4959 
4960           uint64_t& last = last_clock_ts[c];
4961 
4962           EXPECT_LE(last, ts)
4963               << "This sequence:" << c.seq_id << " clock_id:" << c.clock_id;
4964           last = ts;
4965         }
4966       }
4967 
4968       // Events that don't use explicit timestamps should have exactly the same
4969       // timestamp as in the snapshot (i.e. the relative ts of 0).
4970       // Here we assume that timestamps are incremental by default.
4971       if (!packet.has_timestamp_clock_id()) {
4972         EXPECT_EQ(packet.timestamp(), 0u);
4973       }
4974     }
4975   }
4976 }
4977 
TEST_P(PerfettoApiTest,LegacyTraceEventsWithCustomAnnotation)4978 TEST_P(PerfettoApiTest, LegacyTraceEventsWithCustomAnnotation) {
4979   // Create a new trace session.
4980   auto* tracing_session = NewTraceWithCategories({"cat"});
4981   tracing_session->get()->StartBlocking();
4982 
4983   MyDebugAnnotation annotation;
4984   TRACE_EVENT_BEGIN1("cat", "LegacyEvent", "arg", annotation);
4985 
4986   std::unique_ptr<MyDebugAnnotation> owned_annotation(new MyDebugAnnotation());
4987   TRACE_EVENT_BEGIN1("cat", "LegacyEvent", "arg", std::move(owned_annotation));
4988 
4989   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
4990   EXPECT_THAT(slices,
4991               ElementsAre("B:cat.LegacyEvent(arg=(json){\"key\": 123})",
4992                           "B:cat.LegacyEvent(arg=(json){\"key\": 123})"));
4993 }
4994 
TEST_P(PerfettoApiTest,LegacyTraceEventsWithConcurrentSessions)4995 TEST_P(PerfettoApiTest, LegacyTraceEventsWithConcurrentSessions) {
4996   // Make sure that a uniquely owned debug annotation can be written into
4997   // multiple concurrent tracing sessions.
4998 
4999   auto* tracing_session = NewTraceWithCategories({"cat"});
5000   tracing_session->get()->StartBlocking();
5001 
5002   auto* tracing_session2 = NewTraceWithCategories({"cat"});
5003   tracing_session2->get()->StartBlocking();
5004 
5005   std::unique_ptr<MyDebugAnnotation> owned_annotation(new MyDebugAnnotation());
5006   TRACE_EVENT_BEGIN1("cat", "LegacyEvent", "arg", std::move(owned_annotation));
5007 
5008   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
5009   EXPECT_THAT(slices,
5010               ElementsAre("B:cat.LegacyEvent(arg=(json){\"key\": 123})"));
5011 
5012   slices = StopSessionAndReadSlicesFromTrace(tracing_session2);
5013   EXPECT_THAT(slices,
5014               ElementsAre("B:cat.LegacyEvent(arg=(json){\"key\": 123})"));
5015 }
5016 
TEST_P(PerfettoApiTest,LegacyTraceEventsWithId)5017 TEST_P(PerfettoApiTest, LegacyTraceEventsWithId) {
5018   auto* tracing_session = NewTraceWithCategories({"cat"});
5019   tracing_session->get()->StartBlocking();
5020 
5021   TRACE_EVENT_ASYNC_BEGIN0("cat", "UnscopedId", 0x1000);
5022   TRACE_EVENT_ASYNC_BEGIN0("cat", "LocalId", TRACE_ID_LOCAL(0x2000));
5023   TRACE_EVENT_ASYNC_BEGIN0("cat", "GlobalId", TRACE_ID_GLOBAL(0x3000));
5024   TRACE_EVENT_ASYNC_BEGIN0(
5025       "cat", "WithScope",
5026       TRACE_ID_WITH_SCOPE("scope string", TRACE_ID_GLOBAL(0x4000)));
5027 
5028   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
5029   EXPECT_THAT(slices,
5030               ElementsAre("[track=0]Legacy_S(unscoped_id=4096):cat.UnscopedId",
5031                           "[track=0]Legacy_S(local_id=8192):cat.LocalId",
5032                           "[track=0]Legacy_S(global_id=12288):cat.GlobalId",
5033                           "[track=0]Legacy_S(global_id=16384)(id_scope=\"scope "
5034                           "string\"):cat.WithScope"));
5035 }
5036 
TEST_P(PerfettoApiTest,NestableAsyncTraceEvent)5037 TEST_P(PerfettoApiTest, NestableAsyncTraceEvent) {
5038   auto* tracing_session = NewTraceWithCategories({"cat"});
5039   tracing_session->get()->StartBlocking();
5040   TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("cat", "foo",
5041                                     TRACE_ID_WITH_SCOPE("foo", 1));
5042   // Same id, different scope.
5043   TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("cat", "bar",
5044                                     TRACE_ID_WITH_SCOPE("bar", 1));
5045   // Same scope, different id.
5046   TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("cat", "bar",
5047                                     TRACE_ID_WITH_SCOPE("bar", 2));
5048 
5049   TRACE_EVENT_NESTABLE_ASYNC_END0("cat", "bar", TRACE_ID_WITH_SCOPE("bar", 2));
5050   TRACE_EVENT_NESTABLE_ASYNC_END0("cat", "bar", TRACE_ID_WITH_SCOPE("bar", 1));
5051   TRACE_EVENT_NESTABLE_ASYNC_END0("cat", "foo", TRACE_ID_WITH_SCOPE("foo", 1));
5052   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
5053   using LegacyEvent = perfetto::protos::gen::TrackEvent::LegacyEvent;
5054   std::vector<const LegacyEvent*> legacy_events;
5055   for (const auto& packet : trace.packet()) {
5056     if (packet.has_track_event() && packet.track_event().has_legacy_event()) {
5057       legacy_events.push_back(&packet.track_event().legacy_event());
5058     }
5059   }
5060   ASSERT_EQ(6u, legacy_events.size());
5061   EXPECT_EQ("foo", legacy_events[0]->id_scope());
5062   EXPECT_EQ("bar", legacy_events[1]->id_scope());
5063   EXPECT_EQ("bar", legacy_events[2]->id_scope());
5064   EXPECT_EQ("bar", legacy_events[3]->id_scope());
5065   EXPECT_EQ("bar", legacy_events[4]->id_scope());
5066   EXPECT_EQ("foo", legacy_events[5]->id_scope());
5067 
5068   EXPECT_EQ(legacy_events[0]->unscoped_id(), legacy_events[5]->unscoped_id());
5069   EXPECT_EQ(legacy_events[1]->unscoped_id(), legacy_events[4]->unscoped_id());
5070   EXPECT_EQ(legacy_events[2]->unscoped_id(), legacy_events[3]->unscoped_id());
5071 
5072   EXPECT_NE(legacy_events[0]->unscoped_id(), legacy_events[1]->unscoped_id());
5073   EXPECT_NE(legacy_events[1]->unscoped_id(), legacy_events[2]->unscoped_id());
5074   EXPECT_NE(legacy_events[2]->unscoped_id(), legacy_events[0]->unscoped_id());
5075 }
5076 
TEST_P(PerfettoApiTest,LegacyTraceEventsWithFlow)5077 TEST_P(PerfettoApiTest, LegacyTraceEventsWithFlow) {
5078   auto* tracing_session = NewTraceWithCategories({"cat"});
5079   tracing_session->get()->StartBlocking();
5080 
5081   const uint64_t flow_id = 1234;
5082   {
5083     TRACE_EVENT_WITH_FLOW1("cat", "LatencyInfo.Flow", TRACE_ID_GLOBAL(flow_id),
5084                            TRACE_EVENT_FLAG_FLOW_OUT, "step", "Begin");
5085   }
5086 
5087   {
5088     TRACE_EVENT_WITH_FLOW2("cat", "LatencyInfo.Flow", TRACE_ID_GLOBAL(flow_id),
5089                            TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
5090                            "step", "Middle", "value", false);
5091   }
5092 
5093   {
5094     TRACE_EVENT_WITH_FLOW1("cat", "LatencyInfo.Flow", TRACE_ID_GLOBAL(flow_id),
5095                            TRACE_EVENT_FLAG_FLOW_IN, "step", "End");
5096   }
5097 
5098   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
5099   EXPECT_THAT(slices,
5100               ElementsAre("B(bind_id=1234)(flow_direction=2):cat.LatencyInfo."
5101                           "Flow(step=(string)Begin)",
5102                           "E",
5103                           "B(bind_id=1234)(flow_direction=3):cat.LatencyInfo."
5104                           "Flow(step=(string)Middle,value=(bool)0)",
5105                           "E",
5106                           "B(bind_id=1234)(flow_direction=1):cat.LatencyInfo."
5107                           "Flow(step=(string)End)",
5108                           "E"));
5109 }
5110 
TEST_P(PerfettoApiTest,LegacyCategoryGroupEnabledState)5111 TEST_P(PerfettoApiTest, LegacyCategoryGroupEnabledState) {
5112   bool foo_status;
5113   bool bar_status;
5114   bool dynamic_status;
5115   TRACE_EVENT_CATEGORY_GROUP_ENABLED("foo", &foo_status);
5116   TRACE_EVENT_CATEGORY_GROUP_ENABLED("bar", &bar_status);
5117   TRACE_EVENT_CATEGORY_GROUP_ENABLED("dynamic", &dynamic_status);
5118   EXPECT_FALSE(foo_status);
5119   EXPECT_FALSE(bar_status);
5120   EXPECT_FALSE(dynamic_status);
5121 
5122   const uint8_t* foo_enabled =
5123       TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("foo");
5124   const uint8_t* bar_enabled =
5125       TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("bar");
5126   EXPECT_FALSE(*foo_enabled);
5127   EXPECT_FALSE(*bar_enabled);
5128 
5129   // The category group enabled pointer can also be retrieved with a
5130   // runtime-computed category name.
5131   std::string computed_cat("cat");
5132   const uint8_t* computed_enabled =
5133       TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(computed_cat.c_str());
5134   EXPECT_FALSE(*computed_enabled);
5135 
5136   // The enabled pointers can be converted back to category names.
5137   EXPECT_EQ("foo", TRACE_EVENT_API_GET_CATEGORY_GROUP_NAME(foo_enabled));
5138   EXPECT_EQ("bar", TRACE_EVENT_API_GET_CATEGORY_GROUP_NAME(bar_enabled));
5139   EXPECT_EQ("cat", TRACE_EVENT_API_GET_CATEGORY_GROUP_NAME(computed_enabled));
5140 
5141   auto* tracing_session = NewTraceWithCategories({"foo", "dynamic", "cat"});
5142   tracing_session->get()->StartBlocking();
5143   TRACE_EVENT_CATEGORY_GROUP_ENABLED("foo", &foo_status);
5144   TRACE_EVENT_CATEGORY_GROUP_ENABLED("bar", &bar_status);
5145   TRACE_EVENT_CATEGORY_GROUP_ENABLED("dynamic", &dynamic_status);
5146   EXPECT_TRUE(foo_status);
5147   EXPECT_FALSE(bar_status);
5148   EXPECT_TRUE(dynamic_status);
5149 
5150   EXPECT_TRUE(*foo_enabled);
5151   EXPECT_FALSE(*bar_enabled);
5152   EXPECT_TRUE(*computed_enabled);
5153 
5154   tracing_session->get()->StopBlocking();
5155   TRACE_EVENT_CATEGORY_GROUP_ENABLED("foo", &foo_status);
5156   TRACE_EVENT_CATEGORY_GROUP_ENABLED("bar", &bar_status);
5157   TRACE_EVENT_CATEGORY_GROUP_ENABLED("dynamic", &dynamic_status);
5158   EXPECT_FALSE(foo_status);
5159   EXPECT_FALSE(bar_status);
5160   EXPECT_FALSE(dynamic_status);
5161   EXPECT_FALSE(*foo_enabled);
5162   EXPECT_FALSE(*bar_enabled);
5163   EXPECT_FALSE(*computed_enabled);
5164 }
5165 
TEST_P(PerfettoApiTest,CategoryEnabledState)5166 TEST_P(PerfettoApiTest, CategoryEnabledState) {
5167   perfetto::DynamicCategory dynamic{"dynamic"};
5168   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
5169   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("bar"));
5170   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("red,green,blue,foo"));
5171   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("dynamic"));
5172   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("dynamic_2"));
5173   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED(dynamic));
5174 
5175   auto* tracing_session = NewTraceWithCategories({"foo", "dynamic"});
5176   tracing_session->get()->StartBlocking();
5177   EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
5178   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("bar"));
5179   EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("red,green,blue,foo"));
5180   EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("dynamic"));
5181   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("dynamic_2"));
5182   EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED(dynamic));
5183 
5184   tracing_session->get()->StopBlocking();
5185   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
5186   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("bar"));
5187   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("red,green,blue,foo"));
5188   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("dynamic"));
5189   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("dynamic_2"));
5190   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED(dynamic));
5191 }
5192 
5193 class TestInterceptor : public perfetto::Interceptor<TestInterceptor> {
5194  public:
5195   static TestInterceptor* instance;
5196 
5197   struct ThreadLocalState : public perfetto::InterceptorBase::ThreadLocalState {
ThreadLocalState__anon1b44a82b0111::TestInterceptor::ThreadLocalState5198     ThreadLocalState(ThreadLocalStateArgs& args) {
5199       // Test accessing instance state from the TLS constructor.
5200       if (auto self = args.GetInterceptorLocked()) {
5201         self->tls_initialized = true;
5202       }
5203     }
5204 
5205     std::map<uint64_t, std::string> event_names;
5206   };
5207 
TestInterceptor(const std::string & constructor_arg)5208   TestInterceptor(const std::string& constructor_arg) {
5209     EXPECT_EQ(constructor_arg, "Constructor argument");
5210     // Note: some tests in this suite register multiple track event data
5211     // sources. We only track data for the first in this test.
5212     if (!instance)
5213       instance = this;
5214   }
5215 
~TestInterceptor()5216   ~TestInterceptor() override {
5217     if (instance != this)
5218       return;
5219     instance = nullptr;
5220     EXPECT_TRUE(setup_called);
5221     EXPECT_TRUE(start_called);
5222     EXPECT_TRUE(stop_called);
5223     EXPECT_TRUE(tls_initialized);
5224   }
5225 
OnSetup(const SetupArgs &)5226   void OnSetup(const SetupArgs&) override {
5227     EXPECT_FALSE(setup_called);
5228     EXPECT_FALSE(start_called);
5229     EXPECT_FALSE(stop_called);
5230     setup_called = true;
5231   }
5232 
OnStart(const StartArgs &)5233   void OnStart(const StartArgs&) override {
5234     EXPECT_TRUE(setup_called);
5235     EXPECT_FALSE(start_called);
5236     EXPECT_FALSE(stop_called);
5237     start_called = true;
5238   }
5239 
OnStop(const StopArgs &)5240   void OnStop(const StopArgs&) override {
5241     EXPECT_TRUE(setup_called);
5242     EXPECT_TRUE(start_called);
5243     EXPECT_FALSE(stop_called);
5244     stop_called = true;
5245   }
5246 
OnTracePacket(InterceptorContext context)5247   static void OnTracePacket(InterceptorContext context) {
5248     perfetto::protos::pbzero::TracePacket::Decoder packet(
5249         context.packet_data.data, context.packet_data.size);
5250     EXPECT_TRUE(packet.trusted_packet_sequence_id() > 0);
5251     {
5252       auto self = context.GetInterceptorLocked();
5253       ASSERT_TRUE(self);
5254       EXPECT_TRUE(self->setup_called);
5255       EXPECT_TRUE(self->start_called);
5256       EXPECT_FALSE(self->stop_called);
5257       EXPECT_TRUE(self->tls_initialized);
5258     }
5259 
5260     auto& tls = context.GetThreadLocalState();
5261     if (packet.sequence_flags() &
5262         perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED) {
5263       tls.event_names.clear();
5264     }
5265     if (packet.has_interned_data()) {
5266       perfetto::protos::pbzero::InternedData::Decoder interned_data(
5267           packet.interned_data());
5268       for (auto it = interned_data.event_names(); it; it++) {
5269         perfetto::protos::pbzero::EventName::Decoder entry(*it);
5270         tls.event_names[entry.iid()] = entry.name().ToStdString();
5271       }
5272     }
5273     if (packet.has_track_event()) {
5274       perfetto::protos::pbzero::TrackEvent::Decoder track_event(
5275           packet.track_event());
5276       uint64_t name_iid = track_event.name_iid();
5277       auto self = context.GetInterceptorLocked();
5278       self->events.push_back(tls.event_names[name_iid].c_str());
5279     }
5280   }
5281 
5282   bool setup_called = false;
5283   bool start_called = false;
5284   bool stop_called = false;
5285   bool tls_initialized = false;
5286   std::vector<std::string> events;
5287 };
5288 
5289 TestInterceptor* TestInterceptor::instance;
5290 
TEST_P(PerfettoApiTest,TracePacketInterception)5291 TEST_P(PerfettoApiTest, TracePacketInterception) {
5292   perfetto::InterceptorDescriptor desc;
5293   desc.set_name("test_interceptor");
5294   TestInterceptor::Register(desc, std::string("Constructor argument"));
5295 
5296   perfetto::TraceConfig cfg;
5297   cfg.set_duration_ms(500);
5298   cfg.add_buffers()->set_size_kb(1024);
5299   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
5300   ds_cfg->set_name("track_event");
5301   ds_cfg->mutable_interceptor_config()->set_name("test_interceptor");
5302 
5303   auto* tracing_session = NewTrace(cfg);
5304   tracing_session->get()->StartBlocking();
5305   EXPECT_EQ(0u, TestInterceptor::instance->events.size());
5306 
5307   // The interceptor should see an event immediately without any explicit
5308   // flushing.
5309   TRACE_EVENT_BEGIN("foo", "Hip");
5310   EXPECT_THAT(TestInterceptor::instance->events, ElementsAre("Hip"));
5311 
5312   // Emit another event with the same title to test interning.
5313   TRACE_EVENT_BEGIN("foo", "Hip");
5314   EXPECT_THAT(TestInterceptor::instance->events, ElementsAre("Hip", "Hip"));
5315 
5316   // Emit an event from another thread. It should still reach the same
5317   // interceptor instance.
5318   std::thread thread([] { TRACE_EVENT_BEGIN("foo", "Hooray"); });
5319   thread.join();
5320   EXPECT_THAT(TestInterceptor::instance->events,
5321               ElementsAre("Hip", "Hip", "Hooray"));
5322 
5323   // Emit a packet that spans multiple segments and must be stitched together.
5324   TestInterceptor::instance->events.clear();
5325   static char long_title[8192];
5326   memset(long_title, 'a', sizeof(long_title) - 1);
5327   long_title[sizeof(long_title) - 1] = 0;
5328   TRACE_EVENT_BEGIN("foo", long_title);
5329   EXPECT_THAT(TestInterceptor::instance->events, ElementsAre(long_title));
5330 
5331   tracing_session->get()->StopBlocking();
5332 }
5333 
EmitConsoleEvents()5334 void EmitConsoleEvents() {
5335   TRACE_EVENT_INSTANT("foo", "Instant event");
5336   TRACE_EVENT("foo", "Scoped event");
5337   TRACE_EVENT_BEGIN("foo", "Nested event");
5338   TRACE_EVENT_INSTANT("foo", "Instant event");
5339   TRACE_EVENT_INSTANT("foo", "Annotated event", "foo", 1, "bar", "hello");
5340   TRACE_EVENT_END("foo");
5341   uint64_t async_id = 4004;
5342   auto track = perfetto::Track(async_id, perfetto::ThreadTrack::Current());
5343   auto desc = track.Serialize();
5344   desc.set_name("AsyncTrack");
5345   perfetto::TrackEvent::SetTrackDescriptor(track, std::move(desc));
5346   TRACE_EVENT_BEGIN("test", "AsyncEvent", track);
5347 
5348   std::thread thread([&] {
5349     TRACE_EVENT("foo", "EventFromAnotherThread");
5350     TRACE_EVENT_INSTANT("foo", "Instant event");
5351     TRACE_EVENT_END("test", track);
5352   });
5353   thread.join();
5354 
5355   TRACE_EVENT_INSTANT(
5356       "foo", "More annotations", "dict",
5357       [](perfetto::TracedValue context) {
5358         auto dict = std::move(context).WriteDictionary();
5359         dict.Add("key", 123);
5360       },
5361       "array",
5362       [](perfetto::TracedValue context) {
5363         auto array = std::move(context).WriteArray();
5364         array.Append("first");
5365         array.Append("second");
5366       });
5367 }
5368 
TEST_P(PerfettoApiTest,ConsoleInterceptorPrint)5369 TEST_P(PerfettoApiTest, ConsoleInterceptorPrint) {
5370   perfetto::ConsoleInterceptor::Register();
5371 
5372   perfetto::TraceConfig cfg;
5373   cfg.set_duration_ms(500);
5374   cfg.add_buffers()->set_size_kb(1024);
5375   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
5376   ds_cfg->set_name("track_event");
5377   ds_cfg->mutable_interceptor_config()->set_name("console");
5378 
5379   auto* tracing_session = NewTrace(cfg);
5380   tracing_session->get()->StartBlocking();
5381   EmitConsoleEvents();
5382   tracing_session->get()->StopBlocking();
5383 }
5384 
TEST_P(PerfettoApiTest,ConsoleInterceptorVerify)5385 TEST_P(PerfettoApiTest, ConsoleInterceptorVerify) {
5386   perfetto::ConsoleInterceptor::Register();
5387   auto temp_file = perfetto::test::CreateTempFile();
5388   perfetto::ConsoleInterceptor::SetOutputFdForTesting(temp_file.fd);
5389 
5390   perfetto::TraceConfig cfg;
5391   cfg.set_duration_ms(500);
5392   cfg.add_buffers()->set_size_kb(1024);
5393   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
5394   ds_cfg->set_name("track_event");
5395   ds_cfg->mutable_interceptor_config()->set_name("console");
5396 
5397   auto* tracing_session = NewTrace(cfg);
5398   tracing_session->get()->StartBlocking();
5399   EmitConsoleEvents();
5400   tracing_session->get()->StopBlocking();
5401   perfetto::ConsoleInterceptor::SetOutputFdForTesting(0);
5402 
5403   std::vector<std::string> lines;
5404   FILE* f = fdopen(temp_file.fd, "r");
5405   fseek(f, 0u, SEEK_SET);
5406   std::array<char, 128> line{};
5407   while (fgets(line.data(), line.size(), f)) {
5408     // Ignore timestamps and process/thread ids.
5409     std::string s(line.data() + 28);
5410     // Filter out durations.
5411     s = std::regex_replace(s, std::regex(" [+][0-9]*ms"), "");
5412     lines.push_back(std::move(s));
5413   }
5414   fclose(f);
5415   EXPECT_EQ(0, remove(temp_file.path.c_str()));
5416 
5417   // clang-format off
5418   std::vector<std::string> golden_lines = {
5419       "foo   Instant event\n",
5420       "foo   Scoped event {\n",
5421       "foo   -  Nested event {\n",
5422       "foo   -  -  Instant event\n",
5423       "foo   -  -  Annotated event(foo:1, bar:hello)\n",
5424       "foo   -  } Nested event\n",
5425       "test  AsyncEvent {\n",
5426       "foo   EventFromAnotherThread {\n",
5427       "foo   -  Instant event\n",
5428       "test  } AsyncEvent\n",
5429       "foo   } EventFromAnotherThread\n",
5430       "foo   -  More annotations(dict:{key:123}, array:[first, second])\n",
5431       "foo   } Scoped event\n",
5432   };
5433   // clang-format on
5434   EXPECT_THAT(lines, ContainerEq(golden_lines));
5435 }
5436 
TEST_P(PerfettoApiTest,TrackEventObserver)5437 TEST_P(PerfettoApiTest, TrackEventObserver) {
5438   class Observer : public perfetto::TrackEventSessionObserver {
5439    public:
5440     ~Observer() override = default;
5441 
5442     void OnSetup(const perfetto::DataSourceBase::SetupArgs&) {
5443       // Since other tests here register multiple track event data sources,
5444       // ignore all but the first notifications.
5445       if (setup_called)
5446         return;
5447       setup_called = true;
5448       if (unsubscribe_at_setup)
5449         perfetto::TrackEvent::RemoveSessionObserver(this);
5450       // This event isn't recorded in the trace because tracing isn't active yet
5451       // when OnSetup is called.
5452       TRACE_EVENT_INSTANT("foo", "OnSetup");
5453       // However the active tracing categories have already been updated at this
5454       // point.
5455       EXPECT_TRUE(perfetto::TrackEvent::IsEnabled());
5456       EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
5457     }
5458 
5459     void OnStart(const perfetto::DataSourceBase::StartArgs&) {
5460       if (start_called)
5461         return;
5462       start_called = true;
5463       EXPECT_TRUE(perfetto::TrackEvent::IsEnabled());
5464       EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
5465       TRACE_EVENT_INSTANT("foo", "OnStart");
5466     }
5467 
5468     void OnStop(const perfetto::DataSourceBase::StopArgs&) {
5469       if (stop_called)
5470         return;
5471       stop_called = true;
5472       EXPECT_TRUE(perfetto::TrackEvent::IsEnabled());
5473       EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
5474       TRACE_EVENT_INSTANT("foo", "OnStop");
5475       perfetto::TrackEvent::Flush();
5476     }
5477 
5478     bool setup_called{};
5479     bool start_called{};
5480     bool stop_called{};
5481     bool unsubscribe_at_setup{};
5482   };
5483 
5484   EXPECT_FALSE(perfetto::TrackEvent::IsEnabled());
5485   {
5486     Observer observer;
5487     perfetto::TrackEvent::AddSessionObserver(&observer);
5488 
5489     auto* tracing_session = NewTraceWithCategories({"foo"});
5490     tracing_session->get()->StartBlocking();
5491     EXPECT_TRUE(observer.setup_called);
5492     EXPECT_TRUE(observer.start_called);
5493     tracing_session->get()->StopBlocking();
5494     EXPECT_TRUE(observer.stop_called);
5495     perfetto::TrackEvent::RemoveSessionObserver(&observer);
5496     auto slices = ReadSlicesFromTraceSession(tracing_session->get());
5497     EXPECT_THAT(slices, ElementsAre("I:foo.OnStart", "I:foo.OnStop"));
5498   }
5499 
5500   // No notifications after removing observer.
5501   {
5502     Observer observer;
5503     perfetto::TrackEvent::AddSessionObserver(&observer);
5504     perfetto::TrackEvent::RemoveSessionObserver(&observer);
5505     auto* tracing_session = NewTraceWithCategories({"foo"});
5506     tracing_session->get()->StartBlocking();
5507     EXPECT_FALSE(observer.setup_called);
5508     EXPECT_FALSE(observer.start_called);
5509     tracing_session->get()->StopBlocking();
5510     EXPECT_FALSE(observer.stop_called);
5511   }
5512 
5513   // Removing observer in a callback.
5514   {
5515     Observer observer;
5516     observer.unsubscribe_at_setup = true;
5517     perfetto::TrackEvent::AddSessionObserver(&observer);
5518     auto* tracing_session = NewTraceWithCategories({"foo"});
5519     tracing_session->get()->StartBlocking();
5520     EXPECT_TRUE(observer.setup_called);
5521     EXPECT_FALSE(observer.start_called);
5522     tracing_session->get()->StopBlocking();
5523     EXPECT_FALSE(observer.stop_called);
5524     perfetto::TrackEvent::RemoveSessionObserver(&observer);
5525   }
5526 
5527   // Multiple observers.
5528   {
5529     Observer observer1;
5530     Observer observer2;
5531     perfetto::TrackEvent::AddSessionObserver(&observer1);
5532     perfetto::TrackEvent::AddSessionObserver(&observer2);
5533     auto* tracing_session = NewTraceWithCategories({"foo"});
5534     tracing_session->get()->StartBlocking();
5535     tracing_session->get()->StopBlocking();
5536     perfetto::TrackEvent::RemoveSessionObserver(&observer1);
5537     perfetto::TrackEvent::RemoveSessionObserver(&observer2);
5538     auto slices = ReadSlicesFromTraceSession(tracing_session->get());
5539     EXPECT_THAT(slices, ElementsAre("I:foo.OnStart", "I:foo.OnStart",
5540                                     "I:foo.OnStop", "I:foo.OnStop"));
5541   }
5542 
5543   // Multiple observers with one being removed midway.
5544   {
5545     Observer observer1;
5546     Observer observer2;
5547     perfetto::TrackEvent::AddSessionObserver(&observer1);
5548     perfetto::TrackEvent::AddSessionObserver(&observer2);
5549     auto* tracing_session = NewTraceWithCategories({"foo"});
5550     tracing_session->get()->StartBlocking();
5551     perfetto::TrackEvent::RemoveSessionObserver(&observer1);
5552     tracing_session->get()->StopBlocking();
5553     perfetto::TrackEvent::RemoveSessionObserver(&observer2);
5554     auto slices = ReadSlicesFromTraceSession(tracing_session->get());
5555     EXPECT_THAT(slices,
5556                 ElementsAre("I:foo.OnStart", "I:foo.OnStart", "I:foo.OnStop"));
5557   }
5558   EXPECT_FALSE(perfetto::TrackEvent::IsEnabled());
5559 }
5560 
TEST_P(PerfettoApiTest,TrackEventObserver_ClearIncrementalState)5561 TEST_P(PerfettoApiTest, TrackEventObserver_ClearIncrementalState) {
5562   class Observer : public perfetto::TrackEventSessionObserver {
5563    public:
5564     ~Observer() override = default;
5565 
5566     void OnStart(const perfetto::DataSourceBase::StartArgs&) {
5567       EXPECT_TRUE(perfetto::TrackEvent::IsEnabled());
5568       EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
5569       TRACE_EVENT_INSTANT("foo", "OnStart");
5570     }
5571 
5572     void WillClearIncrementalState(
5573         const perfetto::DataSourceBase::ClearIncrementalStateArgs&) {
5574       if (clear_incremental_state_called)
5575         return;
5576       clear_incremental_state_called = true;
5577       EXPECT_TRUE(perfetto::TrackEvent::IsEnabled());
5578       EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
5579       TRACE_EVENT_INSTANT("foo", "WillClearIncrementalState");
5580       perfetto::TrackEvent::Flush();
5581     }
5582 
5583     bool clear_incremental_state_called{};
5584   };
5585 
5586   EXPECT_FALSE(perfetto::TrackEvent::IsEnabled());
5587   {
5588     Observer observer;
5589     perfetto::TrackEvent::AddSessionObserver(&observer);
5590 
5591     perfetto::TraceConfig cfg;
5592     cfg.mutable_incremental_state_config()->set_clear_period_ms(100);
5593     auto* tracing_session = NewTraceWithCategories({"foo"}, {}, cfg);
5594 
5595     tracing_session->get()->StartBlocking();
5596     tracing_session->on_stop.Wait();
5597 
5598     EXPECT_TRUE(observer.clear_incremental_state_called);
5599     perfetto::TrackEvent::RemoveSessionObserver(&observer);
5600     auto slices = ReadSlicesFromTraceSession(tracing_session->get());
5601     EXPECT_THAT(slices, ElementsAre("I:foo.OnStart",
5602                                     "I:foo.WillClearIncrementalState"));
5603   }
5604   EXPECT_FALSE(perfetto::TrackEvent::IsEnabled());
5605 }
5606 
TEST_P(PerfettoApiTest,TrackEventObserver_TwoDataSources)5607 TEST_P(PerfettoApiTest, TrackEventObserver_TwoDataSources) {
5608   class Observer : public perfetto::TrackEventSessionObserver {
5609    public:
5610     ~Observer() override = default;
5611 
5612     void OnStart(const perfetto::DataSourceBase::StartArgs&) {
5613       EXPECT_FALSE(start_called);
5614       start_called = true;
5615     }
5616 
5617     bool start_called{};
5618   };
5619 
5620   EXPECT_FALSE(perfetto::TrackEvent::IsEnabled());
5621   EXPECT_FALSE(tracing_module::IsEnabled());
5622 
5623   {
5624     Observer observer1, observer2;
5625     perfetto::TrackEvent::AddSessionObserver(&observer1);
5626     tracing_module::AddSessionObserver(&observer2);
5627 
5628     perfetto::TraceConfig cfg;
5629     auto* tracing_session = NewTraceWithCategories({"foo"}, {}, cfg);
5630 
5631     tracing_session->get()->StartBlocking();
5632     tracing_session->on_stop.Wait();
5633 
5634     // The tracing_module hasn't registered its data source yet, so observer2
5635     // should not be notified.
5636     EXPECT_TRUE(observer1.start_called);
5637     EXPECT_FALSE(observer2.start_called);
5638     perfetto::TrackEvent::RemoveSessionObserver(&observer1);
5639     tracing_module::RemoveSessionObserver(&observer2);
5640   }
5641 
5642   tracing_module::InitializeCategories();
5643 
5644   {
5645     Observer observer1, observer2;
5646     perfetto::TrackEvent::AddSessionObserver(&observer1);
5647     tracing_module::AddSessionObserver(&observer2);
5648 
5649     perfetto::TraceConfig cfg;
5650     auto* tracing_session = NewTraceWithCategories({"foo"}, {}, cfg);
5651 
5652     tracing_session->get()->StartBlocking();
5653     tracing_session->on_stop.Wait();
5654 
5655     // Each observer should be notified exactly once.
5656     EXPECT_TRUE(observer1.start_called);
5657     EXPECT_TRUE(observer2.start_called);
5658     perfetto::TrackEvent::RemoveSessionObserver(&observer1);
5659     tracing_module::RemoveSessionObserver(&observer2);
5660   }
5661 
5662   EXPECT_FALSE(perfetto::TrackEvent::IsEnabled());
5663   EXPECT_FALSE(tracing_module::IsEnabled());
5664 }
5665 
TEST_P(PerfettoApiTest,TrackEventObserver_AsyncStop)5666 TEST_P(PerfettoApiTest, TrackEventObserver_AsyncStop) {
5667   class Observer : public perfetto::TrackEventSessionObserver {
5668    public:
5669     ~Observer() override = default;
5670 
5671     void OnStop(const perfetto::DataSourceBase::StopArgs& args) {
5672       async_stop_closure_ = args.HandleStopAsynchronously();
5673     }
5674 
5675     void EmitFinalEvents() {
5676       EXPECT_TRUE(perfetto::TrackEvent::IsEnabled());
5677       EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
5678       TRACE_EVENT_INSTANT("foo", "FinalEvent");
5679       perfetto::TrackEvent::Flush();
5680       async_stop_closure_();
5681     }
5682 
5683    private:
5684     std::function<void()> async_stop_closure_;
5685   };
5686 
5687   EXPECT_FALSE(perfetto::TrackEvent::IsEnabled());
5688   {
5689     Observer observer;
5690     perfetto::TrackEvent::AddSessionObserver(&observer);
5691 
5692     auto* tracing_session = NewTraceWithCategories({"foo"});
5693     WaitableTestEvent consumer_stop_signal;
5694     tracing_session->get()->SetOnStopCallback(
5695         [&consumer_stop_signal] { consumer_stop_signal.Notify(); });
5696     tracing_session->get()->StartBlocking();
5697 
5698     // Stop and wait for the producer to have seen the stop event.
5699     tracing_session->get()->Stop();
5700 
5701     // At this point tracing should be still allowed because of the
5702     // HandleStopAsynchronously() call. This usleep is here just to prevent that
5703     // we accidentally pass the test just by virtue of hitting some race. We
5704     // should be able to trace up until 5 seconds after seeing the stop when
5705     // using the deferred stop mechanism.
5706     std::this_thread::sleep_for(std::chrono::milliseconds(250));
5707     observer.EmitFinalEvents();
5708 
5709     // Wait that the stop is propagated to the consumer.
5710     consumer_stop_signal.Wait();
5711 
5712     perfetto::TrackEvent::RemoveSessionObserver(&observer);
5713     auto slices = ReadSlicesFromTraceSession(tracing_session->get());
5714     EXPECT_THAT(slices, ElementsAre("I:foo.FinalEvent"));
5715   }
5716   EXPECT_FALSE(perfetto::TrackEvent::IsEnabled());
5717 }
5718 
5719 #if PERFETTO_BUILDFLAG(PERFETTO_COMPILER_CLANG)
5720 struct __attribute__((capability("mutex"))) MockMutex {
Lock__anon1b44a82b0111::MockMutex5721   void Lock() __attribute__((acquire_capability())) {}
Unlock__anon1b44a82b0111::MockMutex5722   void Unlock() __attribute__((release_capability())) {}
5723 };
5724 
5725 struct AnnotatedObject {
5726   MockMutex mutex;
5727   int value __attribute__((guarded_by(mutex))) = {};
5728 };
5729 
TEST_P(PerfettoApiTest,ThreadSafetyAnnotation)5730 TEST_P(PerfettoApiTest, ThreadSafetyAnnotation) {
5731   AnnotatedObject obj;
5732 
5733   // Access to the locked field is only allowed while holding the mutex.
5734   obj.mutex.Lock();
5735   obj.value = 1;
5736   obj.mutex.Unlock();
5737 
5738   auto* tracing_session = NewTraceWithCategories({"cat"});
5739   tracing_session->get()->StartBlocking();
5740 
5741   // It should be possible to trace the field while holding the lock.
5742   obj.mutex.Lock();
5743   TRACE_EVENT_INSTANT("cat", "Instant", "value", obj.value);
5744   TRACE_EVENT_INSTANT1("cat", "InstantLegacy", 0, "value", obj.value);
5745   { TRACE_EVENT("cat", "Scoped", "value", obj.value); }
5746   { TRACE_EVENT1("cat", "ScopedLegacy", "value", obj.value); }
5747   obj.mutex.Unlock();
5748 
5749   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
5750   EXPECT_THAT(slices, ElementsAre("I:cat.Instant(value=(int)1)",
5751                                   "[track=0]I:cat.InstantLegacy(value=(int)1)",
5752                                   "B:cat.Scoped(value=(int)1)", "E",
5753                                   "B:cat.ScopedLegacy(value=(int)1)", "E"));
5754 }
5755 #endif  // PERFETTO_BUILDFLAG(PERFETTO_COMPILER_CLANG)
5756 
TEST_P(PerfettoApiTest,CountersDeltaEncoding)5757 TEST_P(PerfettoApiTest, CountersDeltaEncoding) {
5758   auto* tracing_session = NewTraceWithCategories({"cat"});
5759   tracing_session->get()->StartBlocking();
5760 
5761   // Describe a counter track.
5762   perfetto::CounterTrack track1 =
5763       perfetto::CounterTrack("Framerate1", "fps1").set_is_incremental(true);
5764   // Global tracks can be constructed at build time.
5765   constexpr perfetto::CounterTrack track2 =
5766       perfetto::CounterTrack::Global("Framerate2", "fps2")
5767           .set_is_incremental(true);
5768   perfetto::CounterTrack track3 = perfetto::CounterTrack("Framerate3", "fps3");
5769 
5770   TRACE_COUNTER("cat", track1, 120);
5771   TRACE_COUNTER("cat", track2, 1000);
5772   TRACE_COUNTER("cat", track3, 10009);
5773 
5774   TRACE_COUNTER("cat", track1, 10);
5775   TRACE_COUNTER("cat", track1, 1200);
5776   TRACE_COUNTER("cat", track1, 34);
5777 
5778   TRACE_COUNTER("cat", track3, 975);
5779   TRACE_COUNTER("cat", track2, 449);
5780   TRACE_COUNTER("cat", track2, 2);
5781 
5782   TRACE_COUNTER("cat", track3, 1091);
5783   TRACE_COUNTER("cat", track3, 110);
5784   TRACE_COUNTER("cat", track3, 1081);
5785 
5786   TRACE_COUNTER("cat", track1, 98);
5787   TRACE_COUNTER("cat", track2, 1084);
5788 
5789   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
5790   std::unordered_map<uint64_t, std::string> counter_names;
5791   // Map(Counter name -> counter values)
5792   std::unordered_map<std::string, std::vector<int64_t>> values;
5793   for (const auto& packet : trace.packet()) {
5794     if (packet.has_track_descriptor()) {
5795       auto& desc = packet.track_descriptor();
5796       if (!desc.has_counter())
5797         continue;
5798       counter_names[desc.uuid()] =
5799           desc.has_name() ? desc.name() : desc.static_name();
5800       EXPECT_EQ((desc.static_name() != "Framerate3"),
5801                 desc.counter().is_incremental());
5802     }
5803     if (packet.has_track_event()) {
5804       auto event = packet.track_event();
5805       EXPECT_EQ(perfetto::protos::gen::TrackEvent_Type_TYPE_COUNTER,
5806                 event.type());
5807       auto& counter_name = counter_names.at(event.track_uuid());
5808       values[counter_name].push_back(event.counter_value());
5809     }
5810   }
5811   ASSERT_EQ(3u, values.size());
5812   using IntVector = std::vector<int64_t>;
5813   EXPECT_EQ((IntVector{120, -110, 1190, -1166, 64}), values.at("Framerate1"));
5814   EXPECT_EQ((IntVector{1000, -551, -447, 1082}), values.at("Framerate2"));
5815   EXPECT_EQ((IntVector{10009, 975, 1091, 110, 1081}), values.at("Framerate3"));
5816 }
5817 
TEST_P(PerfettoApiTest,Counters)5818 TEST_P(PerfettoApiTest, Counters) {
5819   auto* tracing_session = NewTraceWithCategories({"cat"});
5820   tracing_session->get()->StartBlocking();
5821 
5822   // Describe a counter track.
5823   perfetto::CounterTrack fps_track = perfetto::CounterTrack("Framerate", "fps");
5824 
5825   // Emit an integer sample.
5826   TRACE_COUNTER("cat", fps_track, 120);
5827 
5828   // Global tracks can be constructed at build time.
5829   constexpr auto goats_track =
5830       perfetto::CounterTrack::Global("Goats teleported", "goats x 1000")
5831           .set_unit_multiplier(1000);
5832   static_assert(goats_track.uuid == 0x6072fc234f82df11,
5833                 "Counter track uuid mismatch");
5834 
5835   // Emit some floating point samples.
5836   TRACE_COUNTER("cat", goats_track, 0.25);
5837   TRACE_COUNTER("cat", goats_track, 0.5);
5838   TRACE_COUNTER("cat", goats_track, 0.75);
5839 
5840   // Emit a sample using an inline track name.
5841   TRACE_COUNTER("cat", "Voltage", 220);
5842 
5843   // Emit sample with a custom timestamp.
5844   TRACE_COUNTER("cat",
5845                 perfetto::CounterTrack("Power", "GW").set_category("dmc"),
5846                 MyTimestamp(1985u), 1.21f);
5847   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
5848   std::map<uint64_t, std::string> counter_names;
5849   std::vector<std::string> counter_samples;
5850   for (const auto& packet : trace.packet()) {
5851     if (packet.has_track_event()) {
5852       auto event = packet.track_event();
5853       EXPECT_EQ(perfetto::protos::gen::TrackEvent_Type_TYPE_COUNTER,
5854                 event.type());
5855       std::stringstream sample;
5856       std::string counter_name = counter_names[event.track_uuid()];
5857       sample << counter_name << " = ";
5858       if (event.has_counter_value()) {
5859         sample << event.counter_value();
5860       } else if (event.has_double_counter_value()) {
5861         sample << event.double_counter_value();
5862       }
5863       if (counter_name == "Power") {
5864         EXPECT_EQ(1985u, packet.timestamp());
5865       }
5866       counter_samples.push_back(sample.str());
5867     }
5868 
5869     if (!packet.has_track_descriptor() ||
5870         !packet.track_descriptor().has_counter()) {
5871       continue;
5872     }
5873     auto desc = packet.track_descriptor();
5874     counter_names[desc.uuid()] =
5875         desc.has_name() ? desc.name() : desc.static_name();
5876     if (desc.name() == "Framerate") {
5877       EXPECT_EQ("fps", desc.counter().unit_name());
5878     } else if (desc.name() == "Goats teleported") {
5879       EXPECT_EQ("goats x 1000", desc.counter().unit_name());
5880       EXPECT_EQ(1000, desc.counter().unit_multiplier());
5881     } else if (desc.name() == "Power") {
5882       EXPECT_EQ("GW", desc.counter().unit_name());
5883       EXPECT_EQ("dmc", desc.counter().categories()[0]);
5884     }
5885   }
5886   EXPECT_EQ(4u, counter_names.size());
5887   EXPECT_THAT(counter_samples,
5888               ElementsAre("Framerate = 120", "Goats teleported = 0.25",
5889                           "Goats teleported = 0.5", "Goats teleported = 0.75",
5890                           "Voltage = 220", "Power = 1.21"));
5891 }
5892 
TEST_P(PerfettoApiTest,ScrapingTrackEventBegin)5893 TEST_P(PerfettoApiTest, ScrapingTrackEventBegin) {
5894   auto* tracing_session = NewTraceWithCategories({"test"});
5895   tracing_session->get()->StartBlocking();
5896 
5897   TRACE_EVENT_BEGIN("test", "MainEvent");
5898 
5899   // Stop tracing but don't flush. Rely on scraping to get the chunk contents.
5900   tracing_session->get()->StopBlocking();
5901 
5902   auto slices = ReadSlicesFromTraceSession(tracing_session->get());
5903 
5904   EXPECT_THAT(slices, ElementsAre("B:test.MainEvent"));
5905 }
5906 
TEST_P(PerfettoApiTest,ScrapingTrackEventEnd)5907 TEST_P(PerfettoApiTest, ScrapingTrackEventEnd) {
5908   auto* tracing_session = NewTraceWithCategories({"test"});
5909   tracing_session->get()->StartBlocking();
5910 
5911   TRACE_EVENT_BEGIN("test", "MainEvent");
5912   TRACE_EVENT_END("test");
5913 
5914   // Stop tracing but don't flush. Rely on scraping to get the chunk contents.
5915   tracing_session->get()->StopBlocking();
5916 
5917   auto slices = ReadSlicesFromTraceSession(tracing_session->get());
5918 
5919   EXPECT_THAT(slices, ElementsAre("B:test.MainEvent", "E"));
5920 }
5921 
TEST_P(PerfettoApiTest,EmptyEvent)5922 TEST_P(PerfettoApiTest, EmptyEvent) {
5923   auto* tracing_session = NewTraceWithCategories({"test"});
5924   tracing_session->get()->StartBlocking();
5925 
5926   TRACE_EVENT_BEGIN("test", "MainEvent");
5927 
5928   // An empty event will allow the previous track packet to be scraped.
5929   PERFETTO_INTERNAL_ADD_EMPTY_EVENT();
5930 
5931   // Stop tracing but don't flush. Rely on scraping to get the chunk contents.
5932   tracing_session->get()->StopBlocking();
5933 
5934   auto slices = ReadSlicesFromTraceSession(tracing_session->get());
5935 
5936   EXPECT_THAT(slices, ElementsAre("B:test.MainEvent"));
5937 }
5938 
TEST_P(PerfettoApiTest,ConsecutiveEmptyEventsSkipped)5939 TEST_P(PerfettoApiTest, ConsecutiveEmptyEventsSkipped) {
5940   auto* tracing_session = NewTraceWithCategories({"test"});
5941   tracing_session->get()->StartBlocking();
5942 
5943   TRACE_EVENT_BEGIN("test", "MainEvent");
5944 
5945   // Emit many empty events that wouldn't fit into one chunk.
5946   constexpr int kNumEvents = 10000;
5947   for (int i = 0; i < kNumEvents; ++i) {
5948     PERFETTO_INTERNAL_ADD_EMPTY_EVENT();
5949   }
5950   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
5951   auto it = std::find_if(trace.packet().begin(), trace.packet().end(),
5952                          [](const perfetto::protos::gen::TracePacket& packet) {
5953                            return packet.has_trace_stats();
5954                          });
5955   EXPECT_NE(it, trace.packet().end());
5956   // Extra empty events should be skipped so only one chunk should be allocated.
5957   EXPECT_EQ(it->trace_stats().buffer_stats()[0].chunks_read(), 1u);
5958 }
5959 
5960 // Make sure that we set correct track_uuid for legacy events
5961 // of type TrackEvent::TYPE_UNSPECIFIED.
5962 // For such events we set fields of `track_event.legacy_event` and
5963 // we set `track_event.track_uuid` to zero to dissociate it with
5964 // default track.
TEST_P(PerfettoApiTest,CorrectTrackUUIDForLegacyEvents)5965 TEST_P(PerfettoApiTest, CorrectTrackUUIDForLegacyEvents) {
5966   auto* tracing_session = NewTraceWithCategories({"cat"});
5967   tracing_session->get()->StartBlocking();
5968   TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("cat", "foo",
5969                                     TRACE_ID_WITH_SCOPE("foo", 1));
5970 
5971   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
5972   EXPECT_THAT(slices,
5973               ElementsAre("[track=0]Legacy_b(unscoped_id=11250026935264495724)("
5974                           "id_scope=\"foo\"):cat.foo"));
5975 }
5976 
TEST_P(PerfettoApiTest,ActivateTriggers)5977 TEST_P(PerfettoApiTest, ActivateTriggers) {
5978   perfetto::TraceConfig cfg;
5979   cfg.add_buffers()->set_size_kb(1024);
5980   perfetto::TraceConfig::TriggerConfig* tr_cfg = cfg.mutable_trigger_config();
5981   tr_cfg->set_trigger_mode(perfetto::TraceConfig::TriggerConfig::STOP_TRACING);
5982   tr_cfg->set_trigger_timeout_ms(5000);
5983   perfetto::TraceConfig::TriggerConfig::Trigger* trigger =
5984       tr_cfg->add_triggers();
5985   trigger->set_name("trigger1");
5986   auto* tracing_session = NewTrace(cfg);
5987   tracing_session->get()->StartBlocking();
5988 
5989   perfetto::Tracing::ActivateTriggers({"trigger2", "trigger1"}, 10000);
5990 
5991   tracing_session->on_stop.Wait();
5992 
5993   std::vector<char> bytes = tracing_session->get()->ReadTraceBlocking();
5994   perfetto::protos::gen::Trace parsed_trace;
5995   ASSERT_TRUE(parsed_trace.ParseFromArray(bytes.data(), bytes.size()));
5996   EXPECT_THAT(
5997       parsed_trace,
5998       Property(&perfetto::protos::gen::Trace::packet,
5999                Contains(Property(
6000                    &perfetto::protos::gen::TracePacket::trigger,
6001                    Property(&perfetto::protos::gen::Trigger::trigger_name,
6002                             "trigger1")))));
6003 }
6004 
TEST_P(PerfettoApiTest,StartTracingWhileExecutingTracepoint)6005 TEST_P(PerfettoApiTest, StartTracingWhileExecutingTracepoint) {
6006   perfetto::TraceConfig cfg;
6007   auto* buffer = cfg.add_buffers();
6008   buffer->set_size_kb(64);
6009   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6010   ds_cfg->set_name("my_data_source");
6011 
6012   std::atomic<bool> quit{false};
6013   WaitableTestEvent outside_tracing;
6014   WaitableTestEvent tracing;
6015   std::thread t([&] {
6016     while (!quit) {
6017       MockDataSource::Trace([&](MockDataSource::TraceContext ctx) {
6018         {
6019           auto packet = ctx.NewTracePacket();
6020           packet->set_for_testing()->set_str("My String");
6021         }
6022         { auto packet = ctx.NewTracePacket(); }
6023         tracing.Notify();
6024       });
6025       outside_tracing.Notify();
6026       std::this_thread::yield();
6027     }
6028   });
6029   outside_tracing.Wait();
6030 
6031   auto* tracing_session = NewTrace(cfg);
6032   tracing_session->get()->StartBlocking();
6033   tracing.Wait();
6034   tracing_session->get()->StopBlocking();
6035 
6036   // The data source instance should be stopped.
6037   auto* data_source = &data_sources_["my_data_source"];
6038   data_source->on_stop.Wait();
6039 
6040   quit = true;
6041   t.join();
6042 
6043   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
6044   std::vector<std::string> test_strings;
6045   for (auto& trace_packet : trace.packet()) {
6046     if (trace_packet.has_for_testing()) {
6047       test_strings.push_back(trace_packet.for_testing().str());
6048     }
6049   }
6050   EXPECT_THAT(test_strings, AllOf(Not(IsEmpty()), Each("My String")));
6051 }
6052 
TEST_P(PerfettoApiTest,SystemDisconnect)6053 TEST_P(PerfettoApiTest, SystemDisconnect) {
6054   if (GetParam() != perfetto::kSystemBackend) {
6055     GTEST_SKIP();
6056   }
6057   auto* data_source = &data_sources_["my_data_source"];
6058   data_source->handle_stop_asynchronously = true;
6059 
6060   perfetto::TraceConfig cfg;
6061   auto* buffer = cfg.add_buffers();
6062   buffer->set_size_kb(64);
6063   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6064   ds_cfg->set_name("my_data_source");
6065   auto* tracing_session = NewTrace(cfg);
6066   tracing_session->get()->StartBlocking();
6067 
6068   std::atomic<bool> quit1{false};
6069   WaitableTestEvent tracing1;
6070   std::atomic<bool> quit2{false};
6071   WaitableTestEvent tracing2;
6072   std::thread t([&] {
6073     while (!quit1) {
6074       MockDataSource::Trace(
6075           [&](MockDataSource::TraceContext) { tracing1.Notify(); });
6076       std::this_thread::yield();
6077     }
6078     while (!quit2) {
6079       MockDataSource::Trace([&](MockDataSource::TraceContext ctx) {
6080         {
6081           auto packet = ctx.NewTracePacket();
6082           packet->set_for_testing()->set_str("New session");
6083         }
6084         { auto packet = ctx.NewTracePacket(); }
6085         tracing2.Notify();
6086       });
6087       std::this_thread::yield();
6088     }
6089   });
6090   auto cleanup = MakeCleanup([&] {
6091     if (t.joinable()) {
6092       quit1 = true;
6093       quit2 = true;
6094       t.join();
6095     }
6096   });
6097   tracing1.Wait();
6098 
6099   // Restarts the system service. This will cause the producer and consumer to
6100   // disconnect.
6101   system_service_.Restart();
6102 
6103   // The data source instance should be stopped.
6104   data_source->on_stop.Wait();
6105 
6106   // The stop is not finalized yet. Test that creating a new trace writer
6107   // doesn't cause any problem.
6108   MockDataSource::Trace([&](MockDataSource::TraceContext ctx) {
6109     {
6110       auto packet = ctx.NewTracePacket();
6111       packet->set_for_testing()->set_str("Content");
6112     }
6113     { auto packet = ctx.NewTracePacket(); }
6114   });
6115 
6116   data_source->async_stop_closure();
6117 
6118   tracing_session->on_stop.Wait();
6119 
6120   std::unique_ptr<perfetto::TracingSession> new_session =
6121       perfetto::Tracing::NewTrace(/*backend=*/GetParam());
6122   // Wait for reconnection
6123   ASSERT_TRUE(WaitForOneProducerConnected(new_session.get()));
6124 
6125   auto* tracing_session2 = NewTrace(cfg);
6126   tracing_session2->get()->StartBlocking();
6127 
6128   quit1 = true;
6129   tracing2.Wait();
6130   quit2 = true;
6131   t.join();
6132 
6133   data_source->handle_stop_asynchronously = false;
6134 
6135   auto trace = StopSessionAndReturnParsedTrace(tracing_session2);
6136   std::vector<std::string> test_strings;
6137   for (auto& trace_packet : trace.packet()) {
6138     if (trace_packet.has_for_testing()) {
6139       test_strings.push_back(trace_packet.for_testing().str());
6140     }
6141   }
6142   EXPECT_THAT(test_strings, AllOf(Not(IsEmpty()), Each("New session")));
6143 }
6144 
TEST_P(PerfettoApiTest,SystemDisconnectAsyncOnStopNoTracing)6145 TEST_P(PerfettoApiTest, SystemDisconnectAsyncOnStopNoTracing) {
6146   if (GetParam() != perfetto::kSystemBackend) {
6147     GTEST_SKIP();
6148   }
6149   auto* data_source = &data_sources_["my_data_source"];
6150   data_source->handle_stop_asynchronously = true;
6151 
6152   perfetto::TraceConfig cfg;
6153   auto* buffer = cfg.add_buffers();
6154   buffer->set_size_kb(64);
6155   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6156   ds_cfg->set_name("my_data_source");
6157   auto* tracing_session = NewTrace(cfg);
6158   tracing_session->get()->StartBlocking();
6159 
6160   std::atomic<bool> quit1{false};
6161   WaitableTestEvent tracing1;
6162   std::thread t([&] {
6163     while (!quit1) {
6164       MockDataSource::Trace(
6165           [&](MockDataSource::TraceContext) { tracing1.Notify(); });
6166       std::this_thread::yield();
6167     }
6168   });
6169   auto cleanup = MakeCleanup([&] {
6170     if (t.joinable()) {
6171       quit1 = true;
6172       t.join();
6173     }
6174   });
6175   tracing1.Wait();
6176 
6177   // Restarts the system service. This will cause the producer and consumer to
6178   // disconnect.
6179   system_service_.Restart();
6180 
6181   // The data source instance should be stopped. Don't acknowledge the stop yet.
6182   data_source->on_stop.Wait();
6183 
6184   tracing_session->on_stop.Wait();
6185 
6186   std::unique_ptr<perfetto::TracingSession> new_session =
6187       perfetto::Tracing::NewTrace(/*backend=*/GetParam());
6188   // Wait for reconnection
6189   ASSERT_TRUE(WaitForOneProducerConnected(new_session.get()));
6190 
6191   data_source->async_stop_closure();
6192 
6193   data_source->handle_stop_asynchronously = false;
6194 }
6195 
TEST_P(PerfettoApiTest,SystemDisconnectAsyncOnStopRestartTracing)6196 TEST_P(PerfettoApiTest, SystemDisconnectAsyncOnStopRestartTracing) {
6197   if (GetParam() != perfetto::kSystemBackend) {
6198     GTEST_SKIP();
6199   }
6200   auto* data_source = &data_sources_["my_data_source"];
6201   data_source->handle_stop_asynchronously = true;
6202 
6203   perfetto::TraceConfig cfg;
6204   auto* buffer = cfg.add_buffers();
6205   buffer->set_size_kb(64);
6206   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6207   ds_cfg->set_name("my_data_source");
6208   auto* tracing_session = NewTrace(cfg);
6209   tracing_session->get()->StartBlocking();
6210 
6211   std::atomic<bool> quit1{false};
6212   WaitableTestEvent tracing1;
6213   std::atomic<bool> quit2{false};
6214   WaitableTestEvent tracing2;
6215   std::thread t([&] {
6216     while (!quit1) {
6217       MockDataSource::Trace(
6218           [&](MockDataSource::TraceContext) { tracing1.Notify(); });
6219       std::this_thread::yield();
6220     }
6221     while (!quit2) {
6222       MockDataSource::Trace([&](MockDataSource::TraceContext ctx) {
6223         {
6224           auto packet = ctx.NewTracePacket();
6225           packet->set_for_testing()->set_str("New session");
6226         }
6227         { auto packet = ctx.NewTracePacket(); }
6228         tracing2.Notify();
6229       });
6230       std::this_thread::yield();
6231     }
6232   });
6233   auto cleanup = MakeCleanup([&] {
6234     if (t.joinable()) {
6235       quit1 = true;
6236       quit2 = true;
6237       t.join();
6238     }
6239   });
6240   tracing1.Wait();
6241 
6242   // Restarts the system service. This will cause the producer and consumer to
6243   // disconnect.
6244   system_service_.Restart();
6245 
6246   // The data source instance should be stopped. Don't acknowledge the stop yet.
6247   data_source->on_stop.Wait();
6248 
6249   tracing_session->on_stop.Wait();
6250 
6251   std::unique_ptr<perfetto::TracingSession> new_session =
6252       perfetto::Tracing::NewTrace(/*backend=*/GetParam());
6253   // Wait for reconnection
6254   ASSERT_TRUE(WaitForOneProducerConnected(new_session.get()));
6255 
6256   auto* tracing_session2 = NewTrace(cfg);
6257   tracing_session2->get()->StartBlocking();
6258 
6259   data_source->async_stop_closure();
6260 
6261   quit1 = true;
6262   tracing2.Wait();
6263   quit2 = true;
6264   t.join();
6265 
6266   data_source->handle_stop_asynchronously = false;
6267 
6268   auto trace = StopSessionAndReturnParsedTrace(tracing_session2);
6269   std::vector<std::string> test_strings;
6270   for (auto& trace_packet : trace.packet()) {
6271     if (trace_packet.has_for_testing()) {
6272       test_strings.push_back(trace_packet.for_testing().str());
6273     }
6274   }
6275   EXPECT_THAT(test_strings, AllOf(Not(IsEmpty()), Each("New session")));
6276 }
6277 
TEST_P(PerfettoApiTest,SystemDisconnectWhileStopping)6278 TEST_P(PerfettoApiTest, SystemDisconnectWhileStopping) {
6279   if (GetParam() != perfetto::kSystemBackend) {
6280     GTEST_SKIP();
6281   }
6282   auto* data_source = &data_sources_["my_data_source"];
6283   data_source->handle_stop_asynchronously = true;
6284 
6285   perfetto::TraceConfig cfg;
6286   auto* buffer = cfg.add_buffers();
6287   buffer->set_size_kb(64);
6288   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6289   ds_cfg->set_name("my_data_source");
6290   auto* tracing_session = NewTrace(cfg);
6291   tracing_session->get()->StartBlocking();
6292   data_source->on_start.Wait();
6293 
6294   // Stop the session and wait until DataSource::OnStop is called. Don't
6295   // complete the async stop yet.
6296   tracing_session->get()->Stop();
6297   data_source->on_stop.Wait();
6298 
6299   // Restart the service. This should not call DataSource::OnStop again while
6300   // another async stop is in progress.
6301   system_service_.Restart();
6302   tracing_session->on_stop.Wait();
6303 
6304   data_source->async_stop_closure();
6305   data_source->handle_stop_asynchronously = false;
6306 }
6307 
6308 class PerfettoStartupTracingApiTest : public PerfettoApiTest {
6309  public:
6310   using SetupStartupTracingOpts = perfetto::Tracing::SetupStartupTracingOpts;
SetupStartupTracing(perfetto::TraceConfig cfg={},SetupStartupTracingOpts opts={})6311   void SetupStartupTracing(perfetto::TraceConfig cfg = {},
6312                            SetupStartupTracingOpts opts = {}) {
6313     // Setup startup tracing in the current process.
6314     cfg.set_duration_ms(500);
6315     cfg.add_buffers()->set_size_kb(1024);
6316     auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6317     ds_cfg->set_name("track_event");
6318 
6319     perfetto::protos::gen::TrackEventConfig te_cfg;
6320     te_cfg.add_disabled_categories("*");
6321     te_cfg.add_enabled_categories("test");
6322     ds_cfg->set_track_event_config_raw(te_cfg.SerializeAsString());
6323 
6324     opts.backend = GetParam();
6325     session_ =
6326         perfetto::Tracing::SetupStartupTracingBlocking(cfg, std::move(opts));
6327     EXPECT_EQ(TRACE_EVENT_CATEGORY_ENABLED("test"), true);
6328   }
6329 
AbortStartupTracing()6330   void AbortStartupTracing() {
6331     session_->AbortBlocking();
6332     session_.reset();
6333   }
6334 
TearDown()6335   void TearDown() override {
6336     if (session_) {
6337       AbortStartupTracing();
6338     }
6339     // We need to sync producer because when we start StartupTracing, the
6340     // producer is disconnected to reconnect again. Note that
6341     // `SetupStartupTracingBlocking` returns right after data sources are
6342     // started. `SetupStartupTracingBlocking` doesn't wait for reconnection
6343     // to succeed before returning. Hence we need to wait for reconnection here
6344     // because `TracingMuxerImpl::ResetForTesting` will destroy the
6345     // producer if it find it is not connected to service. Which is problematic
6346     // because when reconnection happens (via service transport), it will be
6347     // referencing a deleted producer, which will lead to crash.
6348     perfetto::test::SyncProducers();
6349     this->PerfettoApiTest::TearDown();
6350   }
6351 
6352  protected:
6353   std::unique_ptr<perfetto::StartupTracingSession> session_;
6354 };
6355 
6356 // Test `SetupStartupTracing` API (non block version).
TEST_P(PerfettoStartupTracingApiTest,NonBlockingAPI)6357 TEST_P(PerfettoStartupTracingApiTest, NonBlockingAPI) {
6358   // Setup startup tracing in the current process.
6359   perfetto::TraceConfig cfg;
6360   cfg.set_duration_ms(500);
6361   cfg.add_buffers()->set_size_kb(1024);
6362   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6363   ds_cfg->set_name("track_event");
6364 
6365   perfetto::protos::gen::TrackEventConfig te_cfg;
6366   te_cfg.add_disabled_categories("*");
6367   te_cfg.add_enabled_categories("test");
6368   ds_cfg->set_track_event_config_raw(te_cfg.SerializeAsString());
6369 
6370   SetupStartupTracingOpts opts;
6371   opts.backend = GetParam();
6372   session_ = perfetto::Tracing::SetupStartupTracing(cfg, std::move(opts));
6373   // We need perfetto::test::SyncProducers() to Round-trip to ensure that the
6374   // muxer has enabled startup tracing.
6375   perfetto::test::SyncProducers();
6376   EXPECT_EQ(TRACE_EVENT_CATEGORY_ENABLED("test"), true);
6377 
6378   TRACE_EVENT_BEGIN("test", "Event");
6379 
6380   // Create a new trace session.
6381   auto* tracing_session = NewTraceWithCategories({"test"});
6382   tracing_session->get()->StartBlocking();
6383 
6384   // Emit another event after starting.
6385   TRACE_EVENT_END("test");
6386   // Both events should be retained.
6387   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
6388   EXPECT_THAT(slices, ElementsAre("B:test.Event", "E"));
6389 }
6390 
6391 // Test that a startup tracing session will be adopted even when the config
6392 // is not exactly identical (but still compatible).
TEST_P(PerfettoStartupTracingApiTest,CompatibleConfig)6393 TEST_P(PerfettoStartupTracingApiTest, CompatibleConfig) {
6394   perfetto::TraceConfig cfg;
6395   cfg.set_duration_ms(500);
6396   cfg.add_buffers()->set_size_kb(1024);
6397   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6398   ds_cfg->set_name("track_event");
6399 
6400   perfetto::protos::gen::TrackEventConfig te_cfg;
6401   te_cfg.add_disabled_categories("*");
6402   te_cfg.add_enabled_categories("foo");
6403   te_cfg.add_enabled_categories("bar");
6404   ds_cfg->set_track_event_config_raw(te_cfg.SerializeAsString());
6405 
6406   SetupStartupTracingOpts opts;
6407   opts.backend = GetParam();
6408   session_ = perfetto::Tracing::SetupStartupTracing(cfg, std::move(opts));
6409   // We need perfetto::test::SyncProducers() to Round-trip to ensure that the
6410   // muxer has enabled startup tracing.
6411   perfetto::test::SyncProducers();
6412 
6413   TRACE_EVENT_BEGIN("foo", "Event");
6414 
6415   // Note the different order of categories. The config is essentially the same,
6416   // but is not byte-by-byte identical.
6417   auto* tracing_session = NewTraceWithCategories({"bar", "foo"});
6418   tracing_session->get()->StartBlocking();
6419 
6420   // Emit another event after starting.
6421   TRACE_EVENT_END("foo");
6422 
6423   // Both events should be retained.
6424   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
6425   EXPECT_THAT(slices, ElementsAre("B:foo.Event", "E"));
6426 }
6427 
6428 // Test that a startup tracing session won't be adopted when the config is not
6429 // compatible (in this case, the privacy setting is different).
TEST_P(PerfettoStartupTracingApiTest,IncompatibleConfig)6430 TEST_P(PerfettoStartupTracingApiTest, IncompatibleConfig) {
6431   perfetto::TraceConfig cfg;
6432   cfg.set_duration_ms(500);
6433   cfg.add_buffers()->set_size_kb(1024);
6434   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6435   ds_cfg->set_name("track_event");
6436 
6437   perfetto::protos::gen::TrackEventConfig te_cfg;
6438   te_cfg.add_disabled_categories("*");
6439   te_cfg.add_enabled_categories("foo");
6440   te_cfg.set_filter_debug_annotations(true);
6441   ds_cfg->set_track_event_config_raw(te_cfg.SerializeAsString());
6442 
6443   SetupStartupTracingOpts opts;
6444   opts.backend = GetParam();
6445   session_ = perfetto::Tracing::SetupStartupTracing(cfg, std::move(opts));
6446   // We need perfetto::test::SyncProducers() to Round-trip to ensure that the
6447   // muxer has enabled startup tracing.
6448   perfetto::test::SyncProducers();
6449 
6450   TRACE_EVENT_BEGIN("foo", "Event");
6451 
6452   // This config will have |filter_debug_annotations| set to false.
6453   auto* tracing_session = NewTraceWithCategories({"foo"});
6454   tracing_session->get()->StartBlocking();
6455 
6456   // Emit another event after starting.
6457   TRACE_EVENT_END("foo");
6458 
6459   // The startup session should not be adopted, so we should only see the end
6460   // event.
6461   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
6462   EXPECT_THAT(slices, ElementsAre("E"));
6463 }
6464 
TEST_P(PerfettoStartupTracingApiTest,WithExistingSmb)6465 TEST_P(PerfettoStartupTracingApiTest, WithExistingSmb) {
6466   {
6467     // Start and tear down a first session, just to set up the SMB.
6468     auto* tracing_session = NewTraceWithCategories({"foo"});
6469     tracing_session->get()->StartBlocking();
6470     tracing_session->get()->StopBlocking();
6471   }
6472 
6473   SetupStartupTracing();
6474   TRACE_EVENT_BEGIN("test", "Event");
6475 
6476   // Create a new trace session.
6477   auto* tracing_session = NewTraceWithCategories({"test"});
6478   ASSERT_TRUE(WaitForOneProducerConnected(tracing_session->get()));
6479   tracing_session->get()->StartBlocking();
6480 
6481   // Emit another event after starting.
6482   TRACE_EVENT_END("test");
6483 
6484   // Both events should be retained.
6485   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
6486   EXPECT_THAT(slices, ElementsAre("B:test.Event", "E"));
6487 }
6488 
TEST_P(PerfettoStartupTracingApiTest,WithProducerProvidedSmb)6489 TEST_P(PerfettoStartupTracingApiTest, WithProducerProvidedSmb) {
6490   ASSERT_FALSE(perfetto::test::TracingMuxerImplInternalsForTest::
6491                    DoesSystemBackendHaveSMB());
6492   // The backend has no SMB set up yet. Instead, the SDK will
6493   // reconnect to the backend with a producer-provided SMB.
6494   SetupStartupTracing();
6495   TRACE_EVENT_BEGIN("test", "Event");
6496 
6497   // Create a new trace session.
6498   auto* tracing_session = NewTraceWithCategories({"test"});
6499   ASSERT_TRUE(WaitForOneProducerConnected(tracing_session->get()));
6500   tracing_session->get()->StartBlocking();
6501 
6502   // Emit another event after starting.
6503   TRACE_EVENT_END("test");
6504 
6505   // Both events should be retained.
6506   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
6507   EXPECT_THAT(slices, ElementsAre("B:test.Event", "E"));
6508 }
6509 
TEST_P(PerfettoStartupTracingApiTest,DontTraceBeforeStartupSetup)6510 TEST_P(PerfettoStartupTracingApiTest, DontTraceBeforeStartupSetup) {
6511   // This event should not be recorded.
6512   TRACE_EVENT_BEGIN("test", "EventBeforeStartupTrace");
6513   SetupStartupTracing();
6514   TRACE_EVENT_BEGIN("test", "Event");
6515 
6516   auto* tracing_session = NewTraceWithCategories({"test"});
6517   ASSERT_TRUE(WaitForOneProducerConnected(tracing_session->get()));
6518   tracing_session->get()->StartBlocking();
6519 
6520   TRACE_EVENT_END("test");
6521 
6522   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
6523 
6524   EXPECT_THAT(slices, ElementsAre("B:test.Event", "E"));
6525 }
6526 
6527 // Test the StartupTracing when there are multiple data sources registered
6528 // (2 data sources in this test) but only a few of them contribute in startup
6529 // tracing.
TEST_P(PerfettoStartupTracingApiTest,MultipleDataSourceFewContributing)6530 TEST_P(PerfettoStartupTracingApiTest, MultipleDataSourceFewContributing) {
6531   perfetto::TraceConfig cfg;
6532   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6533   ds_cfg->set_name("CustomDataSource");
6534   SetupStartupTracing(cfg);
6535   TRACE_EVENT_BEGIN("test", "TrackEvent.Startup");
6536 
6537   auto* tracing_session = NewTraceWithCategories({"test"}, {}, cfg);
6538   ASSERT_TRUE(WaitForOneProducerConnected(tracing_session->get()));
6539   tracing_session->get()->StartBlocking();
6540 
6541   TRACE_EVENT_BEGIN("test", "TrackEvent.Main");
6542   perfetto::TrackEvent::Flush();
6543   CustomDataSource::Trace([](CustomDataSource::TraceContext ctx) {
6544     {
6545       auto packet = ctx.NewTracePacket();
6546       packet->set_for_testing()->set_str("CustomDataSource.Main");
6547     }
6548     ctx.Flush();
6549   });
6550 
6551   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
6552   auto slices = ReadSlicesFromTrace(trace);
6553   EXPECT_THAT(slices, ElementsAre("B:test.TrackEvent.Startup",
6554                                   "B:test.TrackEvent.Main"));
6555   std::vector<std::string> test_strings;
6556   for (auto& trace_packet : trace.packet()) {
6557     if (trace_packet.has_for_testing()) {
6558       test_strings.push_back(trace_packet.for_testing().str());
6559     }
6560   }
6561   EXPECT_THAT(test_strings, ElementsAre("CustomDataSource.Main"));
6562 }
6563 
6564 // Test the StartupTracing when there are multiple data sources registered
6565 // (2 data sources in this test) and all of them are contributing in startup
6566 // tracing.
TEST_P(PerfettoStartupTracingApiTest,MultipleDataSourceAllContributing)6567 TEST_P(PerfettoStartupTracingApiTest, MultipleDataSourceAllContributing) {
6568   perfetto::TraceConfig cfg;
6569   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6570   ds_cfg->set_name("CustomDataSource");
6571   SetupStartupTracing(cfg);
6572   TRACE_EVENT_BEGIN("test", "TrackEvent.Startup");
6573   CustomDataSource::Trace([](CustomDataSource::TraceContext ctx) {
6574     auto packet = ctx.NewTracePacket();
6575     packet->set_for_testing()->set_str("CustomDataSource.Startup");
6576   });
6577 
6578   auto* tracing_session = NewTraceWithCategories({"test"}, {}, cfg);
6579   ASSERT_TRUE(WaitForOneProducerConnected(tracing_session->get()));
6580   tracing_session->get()->StartBlocking();
6581 
6582   TRACE_EVENT_BEGIN("test", "TrackEvent.Main");
6583   perfetto::TrackEvent::Flush();
6584   CustomDataSource::Trace([](CustomDataSource::TraceContext ctx) {
6585     {
6586       auto packet = ctx.NewTracePacket();
6587       packet->set_for_testing()->set_str("CustomDataSource.Main");
6588     }
6589     ctx.Flush();
6590   });
6591 
6592   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
6593   auto slices = ReadSlicesFromTrace(trace);
6594   EXPECT_THAT(slices, ElementsAre("B:test.TrackEvent.Startup",
6595                                   "B:test.TrackEvent.Main"));
6596   std::vector<std::string> test_strings;
6597   for (auto& trace_packet : trace.packet()) {
6598     if (trace_packet.has_for_testing()) {
6599       test_strings.push_back(trace_packet.for_testing().str());
6600     }
6601   }
6602   EXPECT_THAT(test_strings,
6603               ElementsAre("CustomDataSource.Startup", "CustomDataSource.Main"));
6604 }
6605 
6606 // Startup tracing requires BufferExhaustedPolicy::kDrop, i.e. once the SMB is
6607 // filled with startup events, any further events should be dropped.
6608 // TODO(b/261493947): fix or remove. go/aosp_ci_failure23
TEST_P(PerfettoStartupTracingApiTest,DISABLED_DropPolicy)6609 TEST_P(PerfettoStartupTracingApiTest, DISABLED_DropPolicy) {
6610   SetupStartupTracing();
6611   constexpr int kNumEvents = 100000;
6612   for (int i = 0; i < kNumEvents; i++) {
6613     TRACE_EVENT_BEGIN("test", "StartupEvent");
6614   }
6615 
6616   auto* tracing_session = NewTraceWithCategories({"test"});
6617   tracing_session->get()->StartBlocking();
6618 
6619   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
6620   std::unordered_map<std::string, int> freq_map;
6621   for (auto& slice : slices) {
6622     freq_map[slice]++;
6623   }
6624   EXPECT_GT(freq_map["B:test.StartupEvent"], 0);
6625   EXPECT_LT(freq_map["B:test.StartupEvent"], kNumEvents);
6626 }
6627 
6628 // TODO(b/261493947): fix or remove.
TEST_P(PerfettoStartupTracingApiTest,DISABLED_Abort)6629 TEST_P(PerfettoStartupTracingApiTest, DISABLED_Abort) {
6630   SetupStartupTracing();
6631   TRACE_EVENT_BEGIN("test", "StartupEvent");
6632   AbortStartupTracing();
6633 
6634   auto* tracing_session = NewTraceWithCategories({"test"});
6635   tracing_session->get()->StartBlocking();
6636 
6637   TRACE_EVENT_BEGIN("test", "MainEvent");
6638 
6639   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
6640 
6641   EXPECT_THAT(slices, ElementsAre("B:test.MainEvent"));
6642 }
6643 
TEST_P(PerfettoStartupTracingApiTest,AbortAndRestart)6644 TEST_P(PerfettoStartupTracingApiTest, AbortAndRestart) {
6645   SetupStartupTracing();
6646   TRACE_EVENT_BEGIN("test", "StartupEvent1");
6647   AbortStartupTracing();
6648   SetupStartupTracing();
6649   TRACE_EVENT_BEGIN("test", "StartupEvent2");
6650 
6651   auto* tracing_session = NewTraceWithCategories({"test"});
6652   ASSERT_TRUE(WaitForOneProducerConnected(tracing_session->get()));
6653   tracing_session->get()->StartBlocking();
6654 
6655   TRACE_EVENT_BEGIN("test", "MainEvent");
6656   perfetto::TrackEvent::Flush();
6657 
6658   tracing_session->get()->StopBlocking();
6659 
6660   auto slices = ReadSlicesFromTraceSession(tracing_session->get());
6661 
6662   EXPECT_THAT(slices, ElementsAre("B:test.StartupEvent2", "B:test.MainEvent"));
6663 }
6664 
TEST_P(PerfettoStartupTracingApiTest,Timeout)6665 TEST_P(PerfettoStartupTracingApiTest, Timeout) {
6666   SetupStartupTracingOpts args;
6667   args.timeout_ms = 2000;
6668   SetupStartupTracing({}, args);
6669   for (int i = 0; i < 25; i++) {
6670     TRACE_EVENT_BEGIN("test", "StartupEvent");
6671     std::this_thread::sleep_for(std::chrono::milliseconds(100));
6672   }
6673 
6674   auto* tracing_session = NewTraceWithCategories({"test"});
6675   tracing_session->get()->StartBlocking();
6676   TRACE_EVENT_BEGIN("test", "MainEvent");
6677 
6678   perfetto::TrackEvent::Flush();
6679 
6680   tracing_session->get()->StopBlocking();
6681 
6682   auto slices = ReadSlicesFromTraceSession(tracing_session->get());
6683   EXPECT_THAT(slices, ElementsAre("B:test.MainEvent"));
6684 }
6685 
6686 // TODO(b/261493947): fix or remove.
TEST_P(PerfettoStartupTracingApiTest,DISABLED_Callbacks)6687 TEST_P(PerfettoStartupTracingApiTest, DISABLED_Callbacks) {
6688   for (bool abort : {true, false}) {
6689     SetupStartupTracingOpts args;
6690     std::vector<std::string> callback_events;
6691     using CallbackArgs = perfetto::Tracing::OnStartupTracingSetupCallbackArgs;
6692     args.on_setup = [&](CallbackArgs callback_arg) {
6693       callback_events.push_back(
6694           "OnSetup(num_data_sources_started=" +
6695           std::to_string(callback_arg.num_data_sources_started) + ")");
6696     };
6697     args.on_adopted = [&]() { callback_events.push_back("OnAdopted()"); };
6698     args.on_aborted = [&]() { callback_events.push_back("OnAborted()"); };
6699     SetupStartupTracing({}, args);
6700     TRACE_EVENT_BEGIN("test", "StartupEvent");
6701     if (abort) {
6702       AbortStartupTracing();
6703     }
6704     auto* tracing_session = NewTraceWithCategories({"test"});
6705     tracing_session->get()->StartBlocking();
6706 
6707     TRACE_EVENT_BEGIN("test", "MainEvent");
6708     perfetto::TrackEvent::Flush();
6709 
6710     tracing_session->get()->StopBlocking();
6711 
6712     auto slices = ReadSlicesFromTraceSession(tracing_session->get());
6713 
6714     ASSERT_EQ(2u, callback_events.size());
6715     EXPECT_EQ("OnSetup(num_data_sources_started=1)", callback_events.at(0));
6716     if (abort) {
6717       EXPECT_THAT(slices, ElementsAre("B:test.MainEvent"));
6718       EXPECT_EQ("OnAborted()", callback_events.at(1));
6719     } else {
6720       EXPECT_THAT(slices,
6721                   ElementsAre("B:test.StartupEvent", "B:test.MainEvent"));
6722       EXPECT_EQ("OnAdopted()", callback_events.at(1));
6723     }
6724   }
6725 }
6726 
6727 // Test that it's ok if main tracing is never started.
6728 // TODO(b/261493947): fix or remove.
TEST_P(PerfettoStartupTracingApiTest,DISABLED_MainTracingNeverStarted)6729 TEST_P(PerfettoStartupTracingApiTest, DISABLED_MainTracingNeverStarted) {
6730   SetupStartupTracing();
6731   TRACE_EVENT_BEGIN("test", "StartupEvent");
6732 }
6733 
6734 // Validates that Startup Trace works fine if we dont emit any event
6735 // during startup tracing session.
TEST_P(PerfettoStartupTracingApiTest,NoEventInStartupTracing)6736 TEST_P(PerfettoStartupTracingApiTest, NoEventInStartupTracing) {
6737   SetupStartupTracing();
6738 
6739   auto* tracing_session = NewTraceWithCategories({"test"});
6740   ASSERT_TRUE(WaitForOneProducerConnected(tracing_session->get()));
6741   tracing_session->get()->StartBlocking();
6742   // Emit an event now that the session was fully started. This should go
6743   // strait to the SMB.
6744   TRACE_EVENT_BEGIN("test", "MainEvent");
6745   perfetto::TrackEvent::Flush();
6746   tracing_session->get()->StopBlocking();
6747   auto slices = ReadSlicesFromTraceSession(tracing_session->get());
6748   EXPECT_THAT(slices, ElementsAre("B:test.MainEvent"));
6749 }
6750 
6751 class ConcurrentSessionTest : public ::testing::Test {
6752  public:
SetUp()6753   void SetUp() override {
6754     system_service_ = perfetto::test::SystemService::Start();
6755     if (!system_service_.valid()) {
6756       GTEST_SKIP();
6757     }
6758     ASSERT_FALSE(perfetto::Tracing::IsInitialized());
6759   }
6760 
InitPerfetto(bool supports_multiple_data_source_instances=true)6761   void InitPerfetto(bool supports_multiple_data_source_instances = true) {
6762     TracingInitArgs args;
6763     args.backends = perfetto::kInProcessBackend | perfetto::kSystemBackend;
6764     args.supports_multiple_data_source_instances =
6765         supports_multiple_data_source_instances;
6766     g_test_tracing_policy->should_allow_consumer_connection = true;
6767     args.tracing_policy = g_test_tracing_policy;
6768     perfetto::Tracing::Initialize(args);
6769     perfetto::TrackEvent::Register();
6770     perfetto::test::SyncProducers();
6771     perfetto::test::DisableReconnectLimit();
6772   }
6773 
TearDown()6774   void TearDown() override { perfetto::Tracing::ResetForTesting(); }
6775 
StartTracing(perfetto::BackendType backend_type,bool short_stop_timeout=false)6776   static std::unique_ptr<perfetto::TracingSession> StartTracing(
6777       perfetto::BackendType backend_type,
6778       bool short_stop_timeout = false) {
6779     perfetto::TraceConfig cfg;
6780     if (short_stop_timeout) {
6781       cfg.set_data_source_stop_timeout_ms(500);
6782     }
6783     cfg.add_buffers()->set_size_kb(1024);
6784     auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6785     ds_cfg->set_name("track_event");
6786     auto tracing_session = perfetto::Tracing::NewTrace(backend_type);
6787     tracing_session->Setup(cfg);
6788     tracing_session->StartBlocking();
6789     return tracing_session;
6790   }
StopTracing(std::unique_ptr<perfetto::TracingSession> tracing_session,bool expect_incremental_state_cleared=true)6791   std::vector<std::string> StopTracing(
6792       std::unique_ptr<perfetto::TracingSession> tracing_session,
6793       bool expect_incremental_state_cleared = true) {
6794     perfetto::TrackEvent::Flush();
6795     tracing_session->StopBlocking();
6796     std::vector<char> trace_data(tracing_session->ReadTraceBlocking());
6797     return ReadSlicesFromTrace(trace_data, expect_incremental_state_cleared);
6798   }
6799 
6800   perfetto::test::SystemService system_service_;
6801 };
6802 
6803 // Verify that concurrent sessions works well by default.
6804 // (i.e. when `disallow_concurrent_sessions` param is not set)
TEST_F(ConcurrentSessionTest,ConcurrentBackends)6805 TEST_F(ConcurrentSessionTest, ConcurrentBackends) {
6806   InitPerfetto();
6807   auto tracing_session1 = StartTracing(perfetto::kSystemBackend);
6808   TRACE_EVENT_BEGIN("test", "DrawGame1");
6809 
6810   auto tracing_session2 = StartTracing(perfetto::kInProcessBackend);
6811   // Should be recorded by both sessions.
6812   TRACE_EVENT_BEGIN("test", "DrawGame2");
6813 
6814   auto slices1 = StopTracing(std::move(tracing_session1));
6815   EXPECT_THAT(slices1, ElementsAre("B:test.DrawGame1", "B:test.DrawGame2"));
6816 
6817   auto slices2 = StopTracing(std::move(tracing_session2));
6818   EXPECT_THAT(slices2, ElementsAre("B:test.DrawGame2"));
6819 
6820   auto tracing_session3 = StartTracing(perfetto::kInProcessBackend);
6821   TRACE_EVENT_BEGIN("test", "DrawGame3");
6822 
6823   auto slices3 = StopTracing(std::move(tracing_session3));
6824   EXPECT_THAT(slices3, ElementsAre("B:test.DrawGame3"));
6825 }
6826 
6827 // When `supports_multiple_data_source_instances = false`, second session
6828 // should not be started.
TEST_F(ConcurrentSessionTest,DisallowMultipleSessionBasic)6829 TEST_F(ConcurrentSessionTest, DisallowMultipleSessionBasic) {
6830   InitPerfetto(/* supports_multiple_data_source_instances = */ false);
6831   auto tracing_session1 = StartTracing(perfetto::kInProcessBackend);
6832   TRACE_EVENT_BEGIN("test", "DrawGame1");
6833 
6834   auto tracing_session2 =
6835       StartTracing(perfetto::kInProcessBackend, /*short_stop_timeout=*/true);
6836   TRACE_EVENT_BEGIN("test", "DrawGame2");
6837 
6838   auto slices1 = StopTracing(std::move(tracing_session1));
6839   EXPECT_THAT(slices1, ElementsAre("B:test.DrawGame1", "B:test.DrawGame2"));
6840 
6841   auto slices2 = StopTracing(std::move(tracing_session2),
6842                              false /* expect_incremental_state_cleared */);
6843   // Because `tracing_session2` was not really started.
6844   EXPECT_THAT(slices2, ElementsAre());
6845 
6846   auto tracing_session3 = StartTracing(perfetto::kInProcessBackend);
6847   TRACE_EVENT_BEGIN("test", "DrawGame3");
6848 
6849   auto slices3 = StopTracing(std::move(tracing_session3));
6850   EXPECT_THAT(slices3, ElementsAre("B:test.DrawGame3"));
6851 }
6852 
TEST(PerfettoApiInitTest,DisableSystemConsumer)6853 TEST(PerfettoApiInitTest, DisableSystemConsumer) {
6854   g_test_tracing_policy->should_allow_consumer_connection = true;
6855 
6856   auto system_service = perfetto::test::SystemService::Start();
6857   // If the system backend isn't supported, skip
6858   if (!system_service.valid()) {
6859     GTEST_SKIP();
6860   }
6861 
6862   EXPECT_FALSE(perfetto::Tracing::IsInitialized());
6863   TracingInitArgs args;
6864   args.backends = perfetto::kSystemBackend;
6865   args.tracing_policy = g_test_tracing_policy;
6866   args.enable_system_consumer = false;
6867   perfetto::Tracing::Initialize(args);
6868 
6869   // If this wasn't the first test to run in this process, any producers
6870   // connected to the old system service will have been disconnected by the
6871   // service restarting above. Wait for all producers to connect again before
6872   // proceeding with the test.
6873   perfetto::test::SyncProducers();
6874 
6875   perfetto::test::DisableReconnectLimit();
6876 
6877   // Creating the consumer with kUnspecifiedBackend should cause a connection
6878   // error: there's no consumer backend.
6879   {
6880     std::unique_ptr<perfetto::TracingSession> ts =
6881         perfetto::Tracing::NewTrace(perfetto::kUnspecifiedBackend);
6882 
6883     WaitableTestEvent got_error;
6884     ts->SetOnErrorCallback([&](perfetto::TracingError error) {
6885       EXPECT_EQ(perfetto::TracingError::kDisconnected, error.code);
6886       EXPECT_FALSE(error.message.empty());
6887       got_error.Notify();
6888     });
6889     got_error.Wait();
6890   }
6891 
6892   // Creating the consumer with kSystemBackend should create a system consumer
6893   // backend on the spot.
6894   EXPECT_TRUE(perfetto::Tracing::NewTrace(perfetto::kSystemBackend)
6895                   ->QueryServiceStateBlocking()
6896                   .success);
6897 
6898   // Now even a consumer with kUnspecifiedBackend should succeed, because the
6899   // backend has been created.
6900   EXPECT_TRUE(perfetto::Tracing::NewTrace(perfetto::kUnspecifiedBackend)
6901                   ->QueryServiceStateBlocking()
6902                   .success);
6903 
6904   perfetto::Tracing::ResetForTesting();
6905 }
6906 
TEST(PerfettoApiInitTest,SeparateInitializations)6907 TEST(PerfettoApiInitTest, SeparateInitializations) {
6908   auto system_service = perfetto::test::SystemService::Start();
6909   // If the system backend isn't supported, skip
6910   if (!system_service.valid()) {
6911     GTEST_SKIP();
6912   }
6913 
6914   {
6915     EXPECT_FALSE(perfetto::Tracing::IsInitialized());
6916     TracingInitArgs args;
6917     args.backends = perfetto::kInProcessBackend;
6918     perfetto::Tracing::Initialize(args);
6919   }
6920 
6921   // If this wasn't the first test to run in this process, any producers
6922   // connected to the old system service will have been disconnected by the
6923   // service restarting above. Wait for all producers to connect again before
6924   // proceeding with the test.
6925   perfetto::test::SyncProducers();
6926 
6927   perfetto::test::DisableReconnectLimit();
6928 
6929   {
6930     perfetto::DataSourceDescriptor dsd;
6931     dsd.set_name("CustomDataSource");
6932     CustomDataSource::Register(dsd);
6933   }
6934 
6935   {
6936     std::unique_ptr<perfetto::TracingSession> tracing_session =
6937         perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
6938     auto result = tracing_session->QueryServiceStateBlocking();
6939     perfetto::protos::gen::TracingServiceState state;
6940     ASSERT_TRUE(result.success);
6941     ASSERT_TRUE(state.ParseFromArray(result.service_state_data.data(),
6942                                      result.service_state_data.size()));
6943     EXPECT_THAT(state.data_sources(),
6944                 Contains(Property(
6945                     &perfetto::protos::gen::TracingServiceState::DataSource::
6946                         ds_descriptor,
6947                     Property(&perfetto::protos::gen::DataSourceDescriptor::name,
6948                              "CustomDataSource"))));
6949   }
6950 
6951   {
6952     EXPECT_TRUE(perfetto::Tracing::IsInitialized());
6953     TracingInitArgs args;
6954     args.backends = perfetto::kSystemBackend;
6955     args.enable_system_consumer = false;
6956     perfetto::Tracing::Initialize(args);
6957   }
6958 
6959   perfetto::test::SyncProducers();
6960 
6961   {
6962     std::unique_ptr<perfetto::TracingSession> tracing_session =
6963         perfetto::Tracing::NewTrace(perfetto::kSystemBackend);
6964     auto result = tracing_session->QueryServiceStateBlocking();
6965     perfetto::protos::gen::TracingServiceState state;
6966     ASSERT_TRUE(result.success);
6967     ASSERT_TRUE(state.ParseFromArray(result.service_state_data.data(),
6968                                      result.service_state_data.size()));
6969     EXPECT_THAT(state.data_sources(),
6970                 Contains(Property(
6971                     &perfetto::protos::gen::TracingServiceState::DataSource::
6972                         ds_descriptor,
6973                     Property(&perfetto::protos::gen::DataSourceDescriptor::name,
6974                              "CustomDataSource"))));
6975   }
6976   perfetto::test::TracingMuxerImplInternalsForTest::
6977       ClearDataSourceTlsStateOnReset<CustomDataSource>();
6978 
6979   perfetto::Tracing::ResetForTesting();
6980 }
6981 
6982 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6983 namespace {
6984 
ConnectUnixSocket()6985 int ConnectUnixSocket() {
6986   std::string socket_name = perfetto::GetProducerSocket();
6987   int fd = socket(AF_UNIX, SOCK_STREAM, 0);
6988   struct sockaddr_un saddr;
6989   memset(&saddr, 0, sizeof(saddr));
6990   memcpy(saddr.sun_path, socket_name.data(), socket_name.size());
6991   saddr.sun_family = AF_UNIX;
6992   auto size = static_cast<socklen_t>(__builtin_offsetof(sockaddr_un, sun_path) +
6993                                      socket_name.size() + 1);
6994   connect(fd, reinterpret_cast<const struct sockaddr*>(&saddr), size);
6995   return fd;
6996 }
6997 
6998 using CreateSocketFunction =
6999     std::function<void(perfetto::CreateSocketCallback)>;
7000 
7001 CreateSocketFunction* g_std_function = nullptr;
7002 
SetCreateSocketFunction(CreateSocketFunction func)7003 void SetCreateSocketFunction(CreateSocketFunction func) {
7004   g_std_function = new CreateSocketFunction(func);
7005 }
7006 
ResetCreateSocketFunction()7007 void ResetCreateSocketFunction() {
7008   delete g_std_function;
7009 }
7010 
CallCreateSocketFunction(perfetto::CreateSocketCallback cb)7011 void CallCreateSocketFunction(perfetto::CreateSocketCallback cb) {
7012   PERFETTO_DCHECK(g_std_function);
7013   (*g_std_function)(cb);
7014 }
7015 
7016 }  // namespace
7017 
TEST(PerfettoApiInitTest,AsyncSocket)7018 TEST(PerfettoApiInitTest, AsyncSocket) {
7019   auto system_service = perfetto::test::SystemService::Start();
7020   // If the system backend isn't supported, skip
7021   if (!system_service.valid()) {
7022     GTEST_SKIP();
7023   }
7024 
7025   EXPECT_FALSE(perfetto::Tracing::IsInitialized());
7026 
7027   perfetto::CreateSocketCallback socket_callback;
7028   WaitableTestEvent create_socket_called;
7029 
7030   TracingInitArgs args;
7031   args.backends = perfetto::kSystemBackend;
7032   args.tracing_policy = g_test_tracing_policy;
7033   args.create_socket_async = &CallCreateSocketFunction;
7034   SetCreateSocketFunction([&socket_callback, &create_socket_called](
7035                               perfetto::CreateSocketCallback cb) {
7036     socket_callback = cb;
7037     create_socket_called.Notify();
7038   });
7039 
7040   perfetto::Tracing::Initialize(args);
7041   create_socket_called.Wait();
7042 
7043   int fd = ConnectUnixSocket();
7044   socket_callback(fd);
7045 
7046   perfetto::test::SyncProducers();
7047   EXPECT_TRUE(perfetto::Tracing::NewTrace(perfetto::kSystemBackend)
7048                   ->QueryServiceStateBlocking()
7049                   .success);
7050 
7051   perfetto::Tracing::ResetForTesting();
7052   ResetCreateSocketFunction();
7053 }
7054 
TEST(PerfettoApiInitTest,AsyncSocketDisconnect)7055 TEST(PerfettoApiInitTest, AsyncSocketDisconnect) {
7056   auto system_service = perfetto::test::SystemService::Start();
7057   // If the system backend isn't supported, skip
7058   if (!system_service.valid()) {
7059     GTEST_SKIP();
7060   }
7061 
7062   EXPECT_FALSE(perfetto::Tracing::IsInitialized());
7063 
7064   perfetto::CreateSocketCallback socket_callback;
7065   testing::MockFunction<CreateSocketFunction> mock_create_socket;
7066   WaitableTestEvent create_socket_called1, create_socket_called2;
7067 
7068   TracingInitArgs args;
7069   args.backends = perfetto::kSystemBackend;
7070   args.tracing_policy = g_test_tracing_policy;
7071   args.create_socket_async = &CallCreateSocketFunction;
7072   SetCreateSocketFunction(mock_create_socket.AsStdFunction());
7073 
7074   EXPECT_CALL(mock_create_socket, Call)
7075       .WillOnce(Invoke([&socket_callback, &create_socket_called1](
7076                            perfetto::CreateSocketCallback cb) {
7077         socket_callback = cb;
7078         create_socket_called1.Notify();
7079       }))
7080       .WillOnce(Invoke([&socket_callback, &create_socket_called2](
7081                            perfetto::CreateSocketCallback cb) {
7082         socket_callback = cb;
7083         create_socket_called2.Notify();
7084       }));
7085 
7086   perfetto::Tracing::Initialize(args);
7087   create_socket_called1.Wait();
7088   int fd = ConnectUnixSocket();
7089   socket_callback(fd);
7090 
7091   perfetto::test::SyncProducers();
7092   EXPECT_TRUE(perfetto::Tracing::NewTrace(perfetto::kSystemBackend)
7093                   ->QueryServiceStateBlocking()
7094                   .success);
7095 
7096   // Restart the system service. This will cause the producer and consumer to
7097   // disconnect and reconnect. The create_socket_async function should be called
7098   // for the second time.
7099   system_service.Restart();
7100   create_socket_called2.Wait();
7101   fd = ConnectUnixSocket();
7102   socket_callback(fd);
7103 
7104   perfetto::test::SyncProducers();
7105   EXPECT_TRUE(perfetto::Tracing::NewTrace(perfetto::kSystemBackend)
7106                   ->QueryServiceStateBlocking()
7107                   .success);
7108 
7109   perfetto::Tracing::ResetForTesting();
7110   ResetCreateSocketFunction();
7111 }
7112 
TEST(PerfettoApiInitTest,AsyncSocketStartupTracing)7113 TEST(PerfettoApiInitTest, AsyncSocketStartupTracing) {
7114   auto system_service = perfetto::test::SystemService::Start();
7115   // If the system backend isn't supported, skip
7116   if (!system_service.valid()) {
7117     GTEST_SKIP();
7118   }
7119 
7120   EXPECT_FALSE(perfetto::Tracing::IsInitialized());
7121 
7122   perfetto::CreateSocketCallback socket_callback;
7123   WaitableTestEvent create_socket_called;
7124 
7125   TracingInitArgs args;
7126   args.backends = perfetto::kSystemBackend;
7127   args.tracing_policy = g_test_tracing_policy;
7128   args.create_socket_async = &CallCreateSocketFunction;
7129   SetCreateSocketFunction([&socket_callback, &create_socket_called](
7130                               perfetto::CreateSocketCallback cb) {
7131     socket_callback = cb;
7132     create_socket_called.Notify();
7133   });
7134 
7135   perfetto::Tracing::Initialize(args);
7136   perfetto::TrackEvent::Register();
7137 
7138   perfetto::TraceConfig cfg;
7139   cfg.set_duration_ms(500);
7140   cfg.add_buffers()->set_size_kb(1024);
7141   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
7142   ds_cfg->set_name("track_event");
7143 
7144   perfetto::protos::gen::TrackEventConfig te_cfg;
7145   te_cfg.add_disabled_categories("*");
7146   te_cfg.add_enabled_categories("test");
7147   ds_cfg->set_track_event_config_raw(te_cfg.SerializeAsString());
7148 
7149   perfetto::Tracing::SetupStartupTracingOpts opts;
7150   opts.backend = perfetto::kSystemBackend;
7151   auto startup_session =
7152       perfetto::Tracing::SetupStartupTracingBlocking(cfg, std::move(opts));
7153 
7154   // Emit a significant number of events to write >1 chunk of data.
7155   constexpr size_t kNumEvents = 1000;
7156   for (size_t i = 0; i < kNumEvents; i++) {
7157     TRACE_EVENT_INSTANT("test", "StartupEvent");
7158   }
7159 
7160   // Now proceed with the connection to the service and wait until it completes.
7161   int fd = ConnectUnixSocket();
7162   socket_callback(fd);
7163   perfetto::test::SyncProducers();
7164 
7165   auto session = perfetto::Tracing::NewTrace(perfetto::kSystemBackend);
7166   session->Setup(cfg);
7167   session->StartBlocking();
7168 
7169   // Write even more events, now with connection established.
7170   for (size_t i = 0; i < kNumEvents; i++) {
7171     TRACE_EVENT_INSTANT("test", "TraceEvent");
7172   }
7173 
7174   perfetto::TrackEvent::Flush();
7175   session->StopBlocking();
7176 
7177   auto raw_trace = session->ReadTraceBlocking();
7178   perfetto::protos::gen::Trace parsed_trace;
7179   EXPECT_TRUE(parsed_trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
7180 
7181   size_t n_track_events = 0;
7182   for (const auto& packet : parsed_trace.packet()) {
7183     if (packet.has_track_event()) {
7184       ++n_track_events;
7185     }
7186   }
7187 
7188   // Events from both startup and service-initiated sessions should be retained.
7189   EXPECT_EQ(n_track_events, kNumEvents * 2);
7190 
7191   startup_session.reset();
7192   session.reset();
7193   perfetto::Tracing::ResetForTesting();
7194   ResetCreateSocketFunction();
7195 }
7196 #endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
7197 
7198 struct BackendTypeAsString {
operator ()__anon1b44a82b0111::BackendTypeAsString7199   std::string operator()(
7200       const ::testing::TestParamInfo<perfetto::BackendType>& info) const {
7201     switch (info.param) {
7202       case perfetto::kInProcessBackend:
7203         return "InProc";
7204       case perfetto::kSystemBackend:
7205         return "System";
7206       case perfetto::kCustomBackend:
7207         return "Custom";
7208       case perfetto::kUnspecifiedBackend:
7209         return "Unspec";
7210     }
7211     return nullptr;
7212   }
7213 };
7214 
7215 INSTANTIATE_TEST_SUITE_P(PerfettoApiTest,
7216                          PerfettoApiTest,
7217                          ::testing::Values(perfetto::kInProcessBackend,
7218                                            perfetto::kSystemBackend),
7219                          BackendTypeAsString());
7220 
7221 // In-process backend doesn't support startup tracing.
7222 INSTANTIATE_TEST_SUITE_P(PerfettoStartupTracingApiTest,
7223                          PerfettoStartupTracingApiTest,
7224                          ::testing::Values(perfetto::kSystemBackend),
7225                          BackendTypeAsString());
7226 
7227 }  // namespace
7228 
7229 PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(CustomDataSource);
7230 PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(MockDataSource);
7231 PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(MockDataSource2);
7232 PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(TestIncrementalDataSource,
7233                                             TestIncrementalDataSourceTraits);
7234 
7235 PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(CustomDataSource);
7236 PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(MockDataSource);
7237 PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(MockDataSource2);
7238 PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(TestIncrementalDataSource,
7239                                            TestIncrementalDataSourceTraits);
7240