• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 "src/tracing/service/tracing_service_impl.h"
18 
19 #include <atomic>
20 #include <cinttypes>
21 #include <cstdint>
22 #include <cstring>
23 #include <functional>
24 #include <map>
25 #include <memory>
26 #include <optional>
27 #include <set>
28 #include <string>
29 #include <thread>
30 #include <utility>
31 #include <vector>
32 
33 #include "perfetto/base/build_config.h"
34 #include "perfetto/base/logging.h"
35 #include "perfetto/base/proc_utils.h"
36 #include "perfetto/base/time.h"
37 #include "perfetto/ext/base/file_utils.h"
38 #include "perfetto/ext/base/string_utils.h"
39 #include "perfetto/ext/base/sys_types.h"
40 #include "perfetto/ext/base/temp_file.h"
41 #include "perfetto/ext/base/utils.h"
42 #include "perfetto/ext/base/uuid.h"
43 #include "perfetto/ext/tracing/core/basic_types.h"
44 #include "perfetto/ext/tracing/core/client_identity.h"
45 #include "perfetto/ext/tracing/core/consumer.h"
46 #include "perfetto/ext/tracing/core/producer.h"
47 #include "perfetto/ext/tracing/core/shared_memory.h"
48 #include "perfetto/ext/tracing/core/shared_memory_abi.h"
49 #include "perfetto/ext/tracing/core/trace_writer.h"
50 #include "perfetto/ext/tracing/core/tracing_service.h"
51 #include "perfetto/protozero/contiguous_memory_range.h"
52 #include "perfetto/protozero/message_arena.h"
53 #include "perfetto/protozero/scattered_stream_writer.h"
54 #include "perfetto/tracing/buffer_exhausted_policy.h"
55 #include "perfetto/tracing/core/flush_flags.h"
56 #include "perfetto/tracing/core/forward_decls.h"
57 #include "protos/perfetto/common/builtin_clock.gen.h"
58 #include "protos/perfetto/trace/clock_snapshot.gen.h"
59 #include "protos/perfetto/trace/remote_clock_sync.gen.h"
60 #include "src/base/test/test_task_runner.h"
61 #include "src/protozero/filtering/filter_bytecode_generator.h"
62 #include "src/tracing/core/shared_memory_arbiter_impl.h"
63 #include "src/tracing/core/trace_writer_impl.h"
64 #include "src/tracing/test/mock_consumer.h"
65 #include "src/tracing/test/mock_producer.h"
66 #include "src/tracing/test/test_shared_memory.h"
67 #include "test/gtest_and_gmock.h"
68 
69 #include "protos/perfetto/common/track_event_descriptor.gen.h"
70 #include "protos/perfetto/trace/perfetto/tracing_service_event.gen.h"
71 #include "protos/perfetto/trace/test_event.gen.h"
72 #include "protos/perfetto/trace/test_event.pbzero.h"
73 #include "protos/perfetto/trace/trace.gen.h"
74 #include "protos/perfetto/trace/trace_packet.gen.h"
75 #include "protos/perfetto/trace/trace_packet.pbzero.h"
76 #include "protos/perfetto/trace/trace_uuid.gen.h"
77 #include "protos/perfetto/trace/trigger.gen.h"
78 
79 #if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
80 #include <zlib.h>
81 #include "src/tracing/service/zlib_compressor.h"
82 #endif
83 
84 using ::testing::_;
85 using ::testing::AssertionFailure;
86 using ::testing::AssertionResult;
87 using ::testing::AssertionSuccess;
88 using ::testing::Contains;
89 using ::testing::ContainsRegex;
90 using ::testing::DoAll;
91 using ::testing::Each;
92 using ::testing::ElementsAreArray;
93 using ::testing::Eq;
94 using ::testing::ExplainMatchResult;
95 using ::testing::HasSubstr;
96 using ::testing::InSequence;
97 using ::testing::Invoke;
98 using ::testing::InvokeWithoutArgs;
99 using ::testing::IsEmpty;
100 using ::testing::Mock;
101 using ::testing::Ne;
102 using ::testing::Not;
103 using ::testing::Pointee;
104 using ::testing::Property;
105 using ::testing::SaveArg;
106 using ::testing::StrictMock;
107 using ::testing::StringMatchResultListener;
108 using ::testing::StrNe;
109 using ::testing::UnorderedElementsAre;
110 
111 namespace perfetto {
112 
113 namespace {
114 constexpr size_t kDefaultShmSizeKb = TracingServiceImpl::kDefaultShmSize / 1024;
115 constexpr size_t kDefaultShmPageSizeKb =
116     TracingServiceImpl::kDefaultShmPageSize / 1024;
117 constexpr size_t kMaxShmSizeKb = TracingServiceImpl::kMaxShmSize / 1024;
118 
HasTriggerModeInternal(const std::vector<protos::gen::TracePacket> & packets,protos::gen::TraceConfig::TriggerConfig::TriggerMode mode)119 AssertionResult HasTriggerModeInternal(
120     const std::vector<protos::gen::TracePacket>& packets,
121     protos::gen::TraceConfig::TriggerConfig::TriggerMode mode) {
122   StringMatchResultListener matcher_result_string;
123   bool contains = ExplainMatchResult(
124       Contains(Property(
125           &protos::gen::TracePacket::trace_config,
126           Property(
127               &protos::gen::TraceConfig::trigger_config,
128               Property(&protos::gen::TraceConfig::TriggerConfig::trigger_mode,
129                        Eq(mode))))),
130       packets, &matcher_result_string);
131   if (contains) {
132     return AssertionSuccess();
133   }
134   return AssertionFailure() << matcher_result_string.str();
135 }
136 
137 MATCHER_P(HasTriggerMode, mode, "") {
138   return HasTriggerModeInternal(arg, mode);
139 }
140 
141 MATCHER_P(LowerCase,
142           m,
143           "Lower case " + testing::DescribeMatcher<std::string>(m, negation)) {
144   return ExplainMatchResult(m, base::ToLower(arg), result_listener);
145 }
146 
147 #if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
Decompress(const std::string & data)148 std::string Decompress(const std::string& data) {
149   uint8_t out[1024];
150 
151   z_stream stream{};
152   stream.next_in = reinterpret_cast<uint8_t*>(const_cast<char*>(data.data()));
153   stream.avail_in = static_cast<unsigned int>(data.size());
154 
155   EXPECT_EQ(inflateInit(&stream), Z_OK);
156   std::string s;
157 
158   int ret;
159   do {
160     stream.next_out = out;
161     stream.avail_out = sizeof(out);
162     ret = inflate(&stream, Z_NO_FLUSH);
163     EXPECT_NE(ret, Z_STREAM_ERROR);
164     EXPECT_NE(ret, Z_NEED_DICT);
165     EXPECT_NE(ret, Z_DATA_ERROR);
166     EXPECT_NE(ret, Z_MEM_ERROR);
167     s.append(reinterpret_cast<char*>(out), sizeof(out) - stream.avail_out);
168   } while (ret != Z_STREAM_END);
169 
170   inflateEnd(&stream);
171   return s;
172 }
173 
DecompressTrace(const std::vector<protos::gen::TracePacket> compressed)174 std::vector<protos::gen::TracePacket> DecompressTrace(
175     const std::vector<protos::gen::TracePacket> compressed) {
176   std::vector<protos::gen::TracePacket> decompressed;
177 
178   for (const protos::gen::TracePacket& c : compressed) {
179     if (c.compressed_packets().empty()) {
180       decompressed.push_back(c);
181       continue;
182     }
183 
184     std::string s = Decompress(c.compressed_packets());
185     protos::gen::Trace t;
186     EXPECT_TRUE(t.ParseFromString(s));
187     decompressed.insert(decompressed.end(), t.packet().begin(),
188                         t.packet().end());
189   }
190   return decompressed;
191 }
192 #endif  // PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
193 
194 }  // namespace
195 
196 class TracingServiceImplTest : public testing::Test {
197  public:
198   using DataSourceInstanceState =
199       TracingServiceImpl::DataSourceInstance::DataSourceInstanceState;
200 
TracingServiceImplTest()201   TracingServiceImplTest() { InitializeSvcWithOpts({}); }
202 
InitializeSvcWithOpts(TracingService::InitOpts init_opts)203   void InitializeSvcWithOpts(TracingService::InitOpts init_opts) {
204     auto shm_factory =
205         std::unique_ptr<SharedMemory::Factory>(new TestSharedMemory::Factory());
206     svc.reset(static_cast<TracingServiceImpl*>(
207         TracingService::CreateInstance(std::move(shm_factory), &task_runner,
208                                        init_opts)
209             .release()));
210     svc->min_write_period_ms_ = 1;
211   }
212 
CreateMockProducer()213   std::unique_ptr<MockProducer> CreateMockProducer() {
214     return std::unique_ptr<MockProducer>(
215         new StrictMock<MockProducer>(&task_runner));
216   }
217 
CreateMockConsumer()218   std::unique_ptr<MockConsumer> CreateMockConsumer() {
219     return std::unique_ptr<MockConsumer>(
220         new StrictMock<MockConsumer>(&task_runner));
221   }
222 
last_producer_id()223   ProducerID* last_producer_id() { return &svc->last_producer_id_; }
224 
GetProducerUid(ProducerID producer_id)225   uid_t GetProducerUid(ProducerID producer_id) {
226     return svc->GetProducer(producer_id)->uid();
227   }
228 
GetTracingSession(TracingSessionID tsid)229   TracingServiceImpl::TracingSession* GetTracingSession(TracingSessionID tsid) {
230     auto* session = svc->GetTracingSession(tsid);
231     EXPECT_NE(nullptr, session);
232     return session;
233   }
234 
tracing_session()235   TracingServiceImpl::TracingSession* tracing_session() {
236     return GetTracingSession(GetTracingSessionID());
237   }
238 
GetTracingSessionID()239   TracingSessionID GetTracingSessionID() {
240     return svc->last_tracing_session_id_;
241   }
242 
GetAllowedTargetBuffers(ProducerID producer_id)243   const std::set<BufferID>& GetAllowedTargetBuffers(ProducerID producer_id) {
244     return svc->GetProducer(producer_id)->allowed_target_buffers_;
245   }
246 
GetWriters(ProducerID producer_id)247   const std::map<WriterID, BufferID>& GetWriters(ProducerID producer_id) {
248     return svc->GetProducer(producer_id)->writers_;
249   }
250 
GetShmemArbiterForProducer(ProducerID producer_id)251   SharedMemoryArbiterImpl* GetShmemArbiterForProducer(ProducerID producer_id) {
252     return svc->GetProducer(producer_id)->inproc_shmem_arbiter_.get();
253   }
254 
StealShmemArbiterForProducer(ProducerID producer_id)255   std::unique_ptr<SharedMemoryArbiterImpl> StealShmemArbiterForProducer(
256       ProducerID producer_id) {
257     return std::move(svc->GetProducer(producer_id)->inproc_shmem_arbiter_);
258   }
259 
GetNumPendingFlushes()260   size_t GetNumPendingFlushes() {
261     return tracing_session()->pending_flushes.size();
262   }
263 
WaitForNextSyncMarker()264   void WaitForNextSyncMarker() {
265     tracing_session()->should_emit_sync_marker = true;
266     static int attempt = 0;
267     while (tracing_session()->should_emit_sync_marker) {
268       auto checkpoint_name = "wait_snapshot_" + std::to_string(attempt++);
269       auto timer_expired = task_runner.CreateCheckpoint(checkpoint_name);
270       task_runner.PostDelayedTask([timer_expired] { timer_expired(); }, 1);
271       task_runner.RunUntilCheckpoint(checkpoint_name);
272     }
273   }
274 
WaitForTraceWritersChanged(ProducerID producer_id)275   void WaitForTraceWritersChanged(ProducerID producer_id) {
276     static int i = 0;
277     auto checkpoint_name = "writers_changed_" + std::to_string(producer_id) +
278                            "_" + std::to_string(i++);
279     auto writers_changed = task_runner.CreateCheckpoint(checkpoint_name);
280     auto writers = GetWriters(producer_id);
281     std::function<void()> task;
282     task = [&task, writers, writers_changed, producer_id, this]() {
283       if (writers != GetWriters(producer_id)) {
284         writers_changed();
285         return;
286       }
287       task_runner.PostDelayedTask(task, 1);
288     };
289     task_runner.PostDelayedTask(task, 1);
290     task_runner.RunUntilCheckpoint(checkpoint_name);
291   }
292 
GetDataSourceInstanceState(const std::string & name)293   DataSourceInstanceState GetDataSourceInstanceState(const std::string& name) {
294     for (const auto& kv : tracing_session()->data_source_instances) {
295       if (kv.second.data_source_name == name)
296         return kv.second.state;
297     }
298     PERFETTO_FATAL("Can't find data source instance with name %s",
299                    name.c_str());
300   }
301 
SetTriggerWindowNs(int64_t window_ns)302   void SetTriggerWindowNs(int64_t window_ns) {
303     svc->trigger_window_ns_ = window_ns;
304   }
305 
OverrideNextTriggerRandomNumber(double number)306   void OverrideNextTriggerRandomNumber(double number) {
307     svc->trigger_rnd_override_for_testing_ = number;
308   }
309 
310   base::TestTaskRunner task_runner;
311   std::unique_ptr<TracingServiceImpl> svc;
312 };
313 
TEST_F(TracingServiceImplTest,AtMostOneConfig)314 TEST_F(TracingServiceImplTest, AtMostOneConfig) {
315   std::unique_ptr<MockConsumer> consumer_a = CreateMockConsumer();
316   std::unique_ptr<MockConsumer> consumer_b = CreateMockConsumer();
317 
318   consumer_a->Connect(svc.get());
319   consumer_b->Connect(svc.get());
320 
321   TraceConfig trace_config_a;
322   trace_config_a.add_buffers()->set_size_kb(128);
323   trace_config_a.set_duration_ms(0);
324   trace_config_a.set_unique_session_name("foo");
325 
326   TraceConfig trace_config_b;
327   trace_config_b.add_buffers()->set_size_kb(128);
328   trace_config_b.set_duration_ms(0);
329   trace_config_b.set_unique_session_name("foo");
330 
331   consumer_a->EnableTracing(trace_config_a);
332   consumer_b->EnableTracing(trace_config_b);
333 
334   // This will stop immediately since it has the same unique session name.
335   consumer_b->WaitForTracingDisabled();
336 
337   consumer_a->DisableTracing();
338   consumer_a->WaitForTracingDisabled();
339 
340   EXPECT_THAT(consumer_b->ReadBuffers(), IsEmpty());
341 }
342 
TEST_F(TracingServiceImplTest,CantBackToBackConfigsForWithExtraGuardrails)343 TEST_F(TracingServiceImplTest, CantBackToBackConfigsForWithExtraGuardrails) {
344   {
345     std::unique_ptr<MockConsumer> consumer_a = CreateMockConsumer();
346     consumer_a->Connect(svc.get());
347 
348     TraceConfig trace_config_a;
349     trace_config_a.add_buffers()->set_size_kb(128);
350     trace_config_a.set_duration_ms(0);
351     trace_config_a.set_enable_extra_guardrails(true);
352     trace_config_a.set_unique_session_name("foo");
353 
354     consumer_a->EnableTracing(trace_config_a);
355     consumer_a->DisableTracing();
356     consumer_a->WaitForTracingDisabled();
357     EXPECT_THAT(consumer_a->ReadBuffers(), Not(IsEmpty()));
358   }
359 
360   {
361     std::unique_ptr<MockConsumer> consumer_b = CreateMockConsumer();
362     consumer_b->Connect(svc.get());
363 
364     TraceConfig trace_config_b;
365     trace_config_b.add_buffers()->set_size_kb(128);
366     trace_config_b.set_duration_ms(10000);
367     trace_config_b.set_enable_extra_guardrails(true);
368     trace_config_b.set_unique_session_name("foo");
369 
370     consumer_b->EnableTracing(trace_config_b);
371     consumer_b->WaitForTracingDisabled(2000);
372     EXPECT_THAT(consumer_b->ReadBuffers(), IsEmpty());
373   }
374 }
375 
TEST_F(TracingServiceImplTest,RegisterAndUnregister)376 TEST_F(TracingServiceImplTest, RegisterAndUnregister) {
377   std::unique_ptr<MockProducer> mock_producer_1 = CreateMockProducer();
378   std::unique_ptr<MockProducer> mock_producer_2 = CreateMockProducer();
379 
380   mock_producer_1->Connect(svc.get(), "mock_producer_1", 123u /* uid */);
381   mock_producer_2->Connect(svc.get(), "mock_producer_2", 456u /* uid */);
382 
383   ASSERT_EQ(2u, svc->num_producers());
384   ASSERT_EQ(mock_producer_1->endpoint(), svc->GetProducer(1));
385   ASSERT_EQ(mock_producer_2->endpoint(), svc->GetProducer(2));
386   ASSERT_EQ(123u, GetProducerUid(1));
387   ASSERT_EQ(456u, GetProducerUid(2));
388 
389   mock_producer_1->RegisterDataSource("foo");
390   mock_producer_2->RegisterDataSource("bar");
391 
392   mock_producer_1->UnregisterDataSource("foo");
393   mock_producer_2->UnregisterDataSource("bar");
394 
395   mock_producer_1.reset();
396   ASSERT_EQ(1u, svc->num_producers());
397   ASSERT_EQ(nullptr, svc->GetProducer(1));
398 
399   mock_producer_2.reset();
400   ASSERT_EQ(nullptr, svc->GetProducer(2));
401 
402   ASSERT_EQ(0u, svc->num_producers());
403 }
404 
TEST_F(TracingServiceImplTest,EnableAndDisableTracing)405 TEST_F(TracingServiceImplTest, EnableAndDisableTracing) {
406   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
407   consumer->Connect(svc.get());
408 
409   std::unique_ptr<MockProducer> producer = CreateMockProducer();
410   producer->Connect(svc.get(), "mock_producer");
411   producer->RegisterDataSource("data_source");
412 
413   TraceConfig trace_config;
414   trace_config.add_buffers()->set_size_kb(128);
415   auto* ds = trace_config.add_data_sources();
416   *ds->add_producer_name_regex_filter() = "mock_[p]roducer";
417   auto* ds_config = ds->mutable_config();
418   ds_config->set_name("data_source");
419   consumer->EnableTracing(trace_config);
420 
421   producer->WaitForTracingSetup();
422   producer->WaitForDataSourceSetup("data_source");
423   producer->WaitForDataSourceStart("data_source");
424 
425   // Calling StartTracing() should be a noop (% a DLOG statement) because the
426   // trace config didn't have the |deferred_start| flag set.
427   consumer->StartTracing();
428 
429   consumer->DisableTracing();
430   producer->WaitForDataSourceStop("data_source");
431   consumer->WaitForTracingDisabled();
432 }
433 
434 // Creates a tracing session with a START_TRACING trigger and checks that data
435 // sources are started only after the service receives a trigger.
TEST_F(TracingServiceImplTest,StartTracingTriggerDeferredStart)436 TEST_F(TracingServiceImplTest, StartTracingTriggerDeferredStart) {
437   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
438   consumer->Connect(svc.get());
439 
440   std::unique_ptr<MockProducer> producer = CreateMockProducer();
441   producer->Connect(svc.get(), "mock_producer");
442 
443   // Create two data sources but enable only one of them.
444   producer->RegisterDataSource("ds_1");
445   producer->RegisterDataSource("ds_2");
446 
447   TraceConfig trace_config;
448   trace_config.add_buffers()->set_size_kb(128);
449   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
450   auto* trigger_config = trace_config.mutable_trigger_config();
451   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
452   auto* trigger = trigger_config->add_triggers();
453   trigger->set_name("trigger_name");
454   trigger->set_stop_delay_ms(1);
455 
456   trigger_config->set_trigger_timeout_ms(8.64e+7);
457 
458   // Make sure we don't get unexpected DataSourceStart() notifications yet.
459   EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
460 
461   consumer->EnableTracing(trace_config);
462   producer->WaitForTracingSetup();
463 
464   producer->WaitForDataSourceSetup("ds_1");
465 
466   // The trace won't start until we send the trigger. since we have a
467   // START_TRACING trigger defined.
468   std::vector<std::string> req;
469   req.push_back("trigger_name");
470   producer->endpoint()->ActivateTriggers(req);
471 
472   producer->WaitForDataSourceStart("ds_1");
473 
474   auto writer1 = producer->CreateTraceWriter("ds_1");
475   producer->ExpectFlush(writer1.get());
476 
477   producer->WaitForDataSourceStop("ds_1");
478   consumer->WaitForTracingDisabled();
479 
480   ASSERT_EQ(1u, tracing_session()->received_triggers.size());
481   EXPECT_EQ("trigger_name",
482             tracing_session()->received_triggers[0].trigger_name);
483 
484   EXPECT_THAT(
485       consumer->ReadBuffers(),
486       HasTriggerMode(protos::gen::TraceConfig::TriggerConfig::START_TRACING));
487 }
488 
489 // Creates a tracing session with a START_TRACING trigger and checks that the
490 // session is cleaned up when no trigger is received after |trigger_timeout_ms|.
TEST_F(TracingServiceImplTest,StartTracingTriggerTimeOut)491 TEST_F(TracingServiceImplTest, StartTracingTriggerTimeOut) {
492   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
493   consumer->Connect(svc.get());
494 
495   std::unique_ptr<MockProducer> producer = CreateMockProducer();
496   producer->Connect(svc.get(), "mock_producer");
497 
498   // Create two data sources but enable only one of them.
499   producer->RegisterDataSource("ds_1");
500   producer->RegisterDataSource("ds_2");
501 
502   TraceConfig trace_config;
503   trace_config.add_buffers()->set_size_kb(128);
504   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
505   auto* trigger_config = trace_config.mutable_trigger_config();
506   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
507   auto* trigger = trigger_config->add_triggers();
508   trigger->set_name("trigger_name");
509   trigger->set_stop_delay_ms(8.64e+7);
510 
511   trigger_config->set_trigger_timeout_ms(1);
512 
513   // Make sure we don't get unexpected DataSourceStart() notifications yet.
514   EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
515 
516   consumer->EnableTracing(trace_config);
517   producer->WaitForTracingSetup();
518 
519   producer->WaitForDataSourceSetup("ds_1");
520 
521   // The trace won't start until we send the trigger. since we have a
522   // START_TRACING trigger defined. This is where we'd expect to have an
523   // ActivateTriggers call to the producer->endpoint().
524 
525   producer->WaitForDataSourceStop("ds_1");
526   consumer->WaitForTracingDisabled();
527   EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
528 }
529 
530 // Regression test for b/274931668. An unkonwn trigger should not cause a trace
531 // that runs indefinitely.
TEST_F(TracingServiceImplTest,FailOnUnknownTrigger)532 TEST_F(TracingServiceImplTest, FailOnUnknownTrigger) {
533   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
534   consumer->Connect(svc.get());
535 
536   std::unique_ptr<MockProducer> producer = CreateMockProducer();
537   producer->Connect(svc.get(), "mock_producer");
538   producer->RegisterDataSource("ds_1");
539 
540   TraceConfig trace_config;
541   trace_config.add_buffers()->set_size_kb(128);
542   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
543   auto* trigger_config = trace_config.mutable_trigger_config();
544   trigger_config->set_trigger_mode(
545       static_cast<TraceConfig::TriggerConfig::TriggerMode>(
546           TraceConfig::TriggerConfig::TriggerMode_MAX + 1));
547   auto* trigger = trigger_config->add_triggers();
548   trigger->set_name("trigger_from_the_future");
549   trigger_config->set_trigger_timeout_ms(1);
550 
551   consumer->EnableTracing(trace_config);
552   consumer->WaitForTracingDisabled();
553 }
554 
555 // Creates a tracing session with a START_TRACING trigger and checks that
556 // the session is not started when the configured trigger producer is different
557 // than the producer that sent the trigger.
TEST_F(TracingServiceImplTest,StartTracingTriggerDifferentProducer)558 TEST_F(TracingServiceImplTest, StartTracingTriggerDifferentProducer) {
559   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
560   consumer->Connect(svc.get());
561 
562   std::unique_ptr<MockProducer> producer = CreateMockProducer();
563   producer->Connect(svc.get(), "mock_producer");
564 
565   // Create two data sources but enable only one of them.
566   producer->RegisterDataSource("ds_1");
567   producer->RegisterDataSource("ds_2");
568 
569   TraceConfig trace_config;
570   trace_config.add_buffers()->set_size_kb(128);
571   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
572   auto* trigger_config = trace_config.mutable_trigger_config();
573   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
574   auto* trigger = trigger_config->add_triggers();
575   trigger->set_name("trigger_name");
576   trigger->set_stop_delay_ms(8.64e+7);
577   trigger->set_producer_name_regex("correct_name");
578 
579   trigger_config->set_trigger_timeout_ms(1);
580 
581   // Make sure we don't get unexpected DataSourceStart() notifications yet.
582   EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
583 
584   consumer->EnableTracing(trace_config);
585   producer->WaitForTracingSetup();
586 
587   producer->WaitForDataSourceSetup("ds_1");
588 
589   // The trace won't start until we send the trigger called "trigger_name"
590   // coming from a producer called "correct_name", since we have a
591   // START_TRACING trigger defined. This is where we'd expect to have an
592   // ActivateTriggers call to the producer->endpoint(), but we send the trigger
593   // from a different producer so it is ignored.
594   std::vector<std::string> req;
595   req.push_back("trigger_name");
596   producer->endpoint()->ActivateTriggers(req);
597 
598   producer->WaitForDataSourceStop("ds_1");
599   consumer->WaitForTracingDisabled();
600   EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
601 }
602 
603 // Creates a tracing session with a START_TRACING trigger and checks that the
604 // session is started when the trigger is received from the correct producer.
TEST_F(TracingServiceImplTest,StartTracingTriggerCorrectProducer)605 TEST_F(TracingServiceImplTest, StartTracingTriggerCorrectProducer) {
606   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
607   consumer->Connect(svc.get());
608 
609   std::unique_ptr<MockProducer> producer = CreateMockProducer();
610   producer->Connect(svc.get(), "mock_producer");
611 
612   // Create two data sources but enable only one of them.
613   producer->RegisterDataSource("ds_1");
614   producer->RegisterDataSource("ds_2");
615 
616   TraceConfig trace_config;
617   trace_config.add_buffers()->set_size_kb(128);
618   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
619   auto* trigger_config = trace_config.mutable_trigger_config();
620   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
621   auto* trigger = trigger_config->add_triggers();
622   trigger->set_name("trigger_name");
623   trigger->set_stop_delay_ms(1);
624   trigger->set_producer_name_regex("mock_produc[e-r]+");
625 
626   trigger_config->set_trigger_timeout_ms(8.64e+7);
627 
628   consumer->EnableTracing(trace_config);
629   producer->WaitForTracingSetup();
630 
631   producer->WaitForDataSourceSetup("ds_1");
632 
633   // Start the trace at this point with ActivateTriggers.
634   std::vector<std::string> req;
635   req.push_back("trigger_name");
636   producer->endpoint()->ActivateTriggers(req);
637 
638   producer->WaitForDataSourceStart("ds_1");
639 
640   auto writer = producer->CreateTraceWriter("ds_1");
641   producer->ExpectFlush(writer.get());
642 
643   producer->WaitForDataSourceStop("ds_1");
644   consumer->WaitForTracingDisabled();
645   EXPECT_THAT(
646       consumer->ReadBuffers(),
647       HasTriggerMode(protos::gen::TraceConfig::TriggerConfig::START_TRACING));
648 }
649 
650 // Creates a tracing session with a START_TRACING trigger and checks that the
651 // session is cleaned up even when a different trigger is received.
TEST_F(TracingServiceImplTest,StartTracingTriggerDifferentTrigger)652 TEST_F(TracingServiceImplTest, StartTracingTriggerDifferentTrigger) {
653   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
654   consumer->Connect(svc.get());
655 
656   std::unique_ptr<MockProducer> producer = CreateMockProducer();
657   producer->Connect(svc.get(), "mock_producer");
658 
659   // Create two data sources but enable only one of them.
660   producer->RegisterDataSource("ds_1");
661   producer->RegisterDataSource("ds_2");
662 
663   TraceConfig trace_config;
664   trace_config.add_buffers()->set_size_kb(128);
665   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
666   auto* trigger_config = trace_config.mutable_trigger_config();
667   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
668   auto* trigger = trigger_config->add_triggers();
669   trigger->set_name("trigger_name");
670   trigger->set_stop_delay_ms(8.64e+7);
671 
672   trigger_config->set_trigger_timeout_ms(1);
673 
674   // Make sure we don't get unexpected DataSourceStart() notifications yet.
675   EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
676 
677   consumer->EnableTracing(trace_config);
678   producer->WaitForTracingSetup();
679 
680   producer->WaitForDataSourceSetup("ds_1");
681 
682   // The trace won't start until we send the trigger called "trigger_name",
683   // since we have a START_TRACING trigger defined. This is where we'd expect to
684   // have an ActivateTriggers call to the producer->endpoint(), but we send a
685   // different trigger.
686   std::vector<std::string> req;
687   req.push_back("not_correct_trigger");
688   producer->endpoint()->ActivateTriggers(req);
689 
690   producer->WaitForDataSourceStop("ds_1");
691   consumer->WaitForTracingDisabled();
692   EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
693 }
694 
695 // Creates a tracing session with a START_TRACING trigger and checks that any
696 // trigger can start the TracingSession.
TEST_F(TracingServiceImplTest,StartTracingTriggerMultipleTriggers)697 TEST_F(TracingServiceImplTest, StartTracingTriggerMultipleTriggers) {
698   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
699   consumer->Connect(svc.get());
700 
701   std::unique_ptr<MockProducer> producer = CreateMockProducer();
702   producer->Connect(svc.get(), "mock_producer");
703 
704   // Create two data sources but enable only one of them.
705   producer->RegisterDataSource("ds_1");
706   producer->RegisterDataSource("ds_2");
707 
708   TraceConfig trace_config;
709   trace_config.add_buffers()->set_size_kb(128);
710   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
711   auto* trigger_config = trace_config.mutable_trigger_config();
712   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
713   auto* trigger = trigger_config->add_triggers();
714   trigger->set_name("trigger_name");
715   trigger->set_stop_delay_ms(1);
716 
717   trigger_config->set_trigger_timeout_ms(8.64e+7);
718 
719   consumer->EnableTracing(trace_config);
720   producer->WaitForTracingSetup();
721 
722   producer->WaitForDataSourceSetup("ds_1");
723 
724   std::vector<std::string> req;
725   req.push_back("not_correct_trigger");
726   req.push_back("trigger_name");
727   producer->endpoint()->ActivateTriggers(req);
728 
729   producer->WaitForDataSourceStart("ds_1");
730 
731   auto writer = producer->CreateTraceWriter("ds_1");
732   producer->ExpectFlush(writer.get());
733 
734   producer->WaitForDataSourceStop("ds_1");
735   consumer->WaitForTracingDisabled();
736   EXPECT_THAT(
737       consumer->ReadBuffers(),
738       HasTriggerMode(protos::gen::TraceConfig::TriggerConfig::START_TRACING));
739 }
740 
741 // Creates two tracing sessions with a START_TRACING trigger and checks that
742 // both are able to be triggered simultaneously.
TEST_F(TracingServiceImplTest,StartTracingTriggerMultipleTraces)743 TEST_F(TracingServiceImplTest, StartTracingTriggerMultipleTraces) {
744   std::unique_ptr<MockConsumer> consumer_1 = CreateMockConsumer();
745   consumer_1->Connect(svc.get());
746   std::unique_ptr<MockConsumer> consumer_2 = CreateMockConsumer();
747   consumer_2->Connect(svc.get());
748 
749   std::unique_ptr<MockProducer> producer = CreateMockProducer();
750   producer->Connect(svc.get(), "mock_producer");
751 
752   // Create two data sources but each TracingSession will only enable one of
753   // them.
754   producer->RegisterDataSource("ds_1");
755   producer->RegisterDataSource("ds_2");
756 
757   TraceConfig trace_config;
758   trace_config.add_buffers()->set_size_kb(128);
759   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
760   auto* trigger_config = trace_config.mutable_trigger_config();
761   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
762   auto* trigger = trigger_config->add_triggers();
763   trigger->set_name("trigger_name");
764   trigger->set_stop_delay_ms(1);
765 
766   trigger_config->set_trigger_timeout_ms(8.64e+7);
767 
768   consumer_1->EnableTracing(trace_config);
769   producer->WaitForTracingSetup();
770 
771   producer->WaitForDataSourceSetup("ds_1");
772 
773   auto tracing_session_1_id = GetTracingSessionID();
774 
775   (*trace_config.mutable_data_sources())[0].mutable_config()->set_name("ds_2");
776   trigger = trace_config.mutable_trigger_config()->add_triggers();
777   trigger->set_name("trigger_name_2");
778   trigger->set_stop_delay_ms(8.64e+7);
779 
780   consumer_2->EnableTracing(trace_config);
781 
782   producer->WaitForDataSourceSetup("ds_2");
783 
784   auto tracing_session_2_id = GetTracingSessionID();
785   EXPECT_NE(tracing_session_1_id, tracing_session_2_id);
786 
787   const DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_1");
788   const DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds_2");
789 
790   std::vector<std::string> req;
791   req.push_back("not_correct_trigger");
792   req.push_back("trigger_name");
793   req.push_back("trigger_name_2");
794   producer->endpoint()->ActivateTriggers(req);
795 
796   // The order has to be the same as the triggers or else we're incorrectly wait
797   // on the wrong checkpoint in the |task_runner|.
798   producer->WaitForDataSourceStart("ds_1");
799   producer->WaitForDataSourceStart("ds_2");
800 
801   // Now that they've started we can check the triggers they've seen.
802   auto* tracing_session_1 = GetTracingSession(tracing_session_1_id);
803   ASSERT_EQ(1u, tracing_session_1->received_triggers.size());
804   EXPECT_EQ("trigger_name",
805             tracing_session_1->received_triggers[0].trigger_name);
806 
807   // This is actually dependent on the order in which the triggers were received
808   // but there isn't really a better way than iteration order so probably not to
809   // brittle of a test. And this caught a real bug in implementation.
810   auto* tracing_session_2 = GetTracingSession(tracing_session_2_id);
811   ASSERT_EQ(2u, tracing_session_2->received_triggers.size());
812 
813   EXPECT_EQ("trigger_name",
814             tracing_session_2->received_triggers[0].trigger_name);
815 
816   EXPECT_EQ("trigger_name_2",
817             tracing_session_2->received_triggers[1].trigger_name);
818 
819   auto writer1 = producer->CreateTraceWriter("ds_1");
820   auto writer2 = producer->CreateTraceWriter("ds_2");
821 
822   // We can't use the standard WaitForX in the MockProducer and MockConsumer
823   // because they assume only a single trace is going on. So we perform our own
824   // expectations and wait at the end for the two consumers to receive
825   // OnTracingDisabled.
826   bool flushed_writer_1 = false;
827   bool flushed_writer_2 = false;
828   auto flush_correct_writer = [&](FlushRequestID flush_req_id,
829                                   const DataSourceInstanceID* id, size_t,
830                                   FlushFlags) {
831     if (*id == id1) {
832       flushed_writer_1 = true;
833       writer1->Flush();
834       producer->endpoint()->NotifyFlushComplete(flush_req_id);
835     } else if (*id == id2) {
836       flushed_writer_2 = true;
837       writer2->Flush();
838       producer->endpoint()->NotifyFlushComplete(flush_req_id);
839     }
840   };
841   FlushFlags flush_flags(FlushFlags::Initiator::kTraced,
842                          FlushFlags::Reason::kTraceStop);
843   EXPECT_CALL(*producer, Flush(_, _, _, flush_flags))
844       .WillOnce(Invoke(flush_correct_writer))
845       .WillOnce(Invoke(flush_correct_writer));
846 
847   auto checkpoint_name = "on_tracing_disabled_consumer_1_and_2";
848   auto on_tracing_disabled = task_runner.CreateCheckpoint(checkpoint_name);
849   std::atomic<size_t> counter(0);
850   EXPECT_CALL(*consumer_1, OnTracingDisabled(_))
851       .WillOnce(InvokeWithoutArgs([&]() {
852         if (++counter == 2u) {
853           on_tracing_disabled();
854         }
855       }));
856   EXPECT_CALL(*consumer_2, OnTracingDisabled(_))
857       .WillOnce(InvokeWithoutArgs([&]() {
858         if (++counter == 2u) {
859           on_tracing_disabled();
860         }
861       }));
862 
863   EXPECT_CALL(*producer, StopDataSource(id1));
864   EXPECT_CALL(*producer, StopDataSource(id2));
865 
866   task_runner.RunUntilCheckpoint(checkpoint_name, 1000);
867 
868   EXPECT_TRUE(flushed_writer_1);
869   EXPECT_TRUE(flushed_writer_2);
870   EXPECT_THAT(
871       consumer_1->ReadBuffers(),
872       HasTriggerMode(protos::gen::TraceConfig::TriggerConfig::START_TRACING));
873   EXPECT_THAT(
874       consumer_2->ReadBuffers(),
875       HasTriggerMode(protos::gen::TraceConfig::TriggerConfig::START_TRACING));
876 }
877 
878 // Creates a tracing session with a START_TRACING trigger and checks that the
879 // received_triggers are emitted as packets.
TEST_F(TracingServiceImplTest,EmitTriggersWithStartTracingTrigger)880 TEST_F(TracingServiceImplTest, EmitTriggersWithStartTracingTrigger) {
881   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
882   consumer->Connect(svc.get());
883 
884   std::unique_ptr<MockProducer> producer = CreateMockProducer();
885   producer->Connect(svc.get(), "mock_producer", /* uid = */ 123u);
886 
887   producer->RegisterDataSource("ds_1");
888 
889   TraceConfig trace_config;
890   trace_config.add_buffers()->set_size_kb(128);
891   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
892   auto* trigger_config = trace_config.mutable_trigger_config();
893   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::START_TRACING);
894   auto* trigger = trigger_config->add_triggers();
895   trigger->set_name("trigger_name");
896   trigger->set_stop_delay_ms(1);
897   trigger->set_producer_name_regex("mock_produc[e-r]+");
898 
899   trigger_config->set_trigger_timeout_ms(30000);
900 
901   consumer->EnableTracing(trace_config);
902   producer->WaitForTracingSetup();
903   producer->WaitForDataSourceSetup("ds_1");
904 
905   // The trace won't start until we send the trigger since we have a
906   // START_TRACING trigger defined.
907   std::vector<std::string> req;
908   req.push_back("trigger_name");
909   req.push_back("trigger_name_2");
910   req.push_back("trigger_name_3");
911   producer->endpoint()->ActivateTriggers(req);
912 
913   producer->WaitForDataSourceStart("ds_1");
914   auto writer1 = producer->CreateTraceWriter("ds_1");
915   producer->ExpectFlush(writer1.get());
916   producer->WaitForDataSourceStop("ds_1");
917   consumer->WaitForTracingDisabled();
918 
919   ASSERT_EQ(1u, tracing_session()->received_triggers.size());
920   EXPECT_EQ("trigger_name",
921             tracing_session()->received_triggers[0].trigger_name);
922 
923   auto packets = consumer->ReadBuffers();
924   EXPECT_THAT(
925       packets,
926       Contains(Property(
927           &protos::gen::TracePacket::trace_config,
928           Property(
929               &protos::gen::TraceConfig::trigger_config,
930               Property(&protos::gen::TraceConfig::TriggerConfig::trigger_mode,
931                        Eq(protos::gen::TraceConfig::TriggerConfig::
932                               START_TRACING))))));
933   auto expect_received_trigger = [&](const std::string& name) {
934     return Contains(AllOf(
935         Property(&protos::gen::TracePacket::trigger,
936                  AllOf(Property(&protos::gen::Trigger::trigger_name, Eq(name)),
937                        Property(&protos::gen::Trigger::trusted_producer_uid,
938                                 Eq(123)),
939                        Property(&protos::gen::Trigger::producer_name,
940                                 Eq("mock_producer")))),
941         Property(&protos::gen::TracePacket::trusted_packet_sequence_id,
942                  Eq(kServicePacketSequenceID))));
943   };
944   EXPECT_THAT(packets, expect_received_trigger("trigger_name"));
945   EXPECT_THAT(packets, Not(expect_received_trigger("trigger_name_2")));
946   EXPECT_THAT(packets, Not(expect_received_trigger("trigger_name_3")));
947 }
948 
949 // Creates a tracing session with a START_TRACING trigger and checks that the
950 // received_triggers are emitted as packets.
TEST_F(TracingServiceImplTest,EmitTriggersWithStopTracingTrigger)951 TEST_F(TracingServiceImplTest, EmitTriggersWithStopTracingTrigger) {
952   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
953   consumer->Connect(svc.get());
954 
955   std::unique_ptr<MockProducer> producer = CreateMockProducer();
956   producer->Connect(svc.get(), "mock_producer", /* uid = */ 321u);
957 
958   producer->RegisterDataSource("ds_1");
959 
960   TraceConfig trace_config;
961   trace_config.add_buffers()->set_size_kb(128);
962   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
963   auto* trigger_config = trace_config.mutable_trigger_config();
964   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
965   auto* trigger = trigger_config->add_triggers();
966   trigger->set_name("trigger_name");
967   trigger->set_stop_delay_ms(1);
968   trigger = trigger_config->add_triggers();
969   trigger->set_name("trigger_name_3");
970   trigger->set_stop_delay_ms(30000);
971 
972   trigger_config->set_trigger_timeout_ms(30000);
973 
974   consumer->EnableTracing(trace_config);
975   producer->WaitForTracingSetup();
976   producer->WaitForDataSourceSetup("ds_1");
977   producer->WaitForDataSourceStart("ds_1");
978 
979   // The trace won't start until we send the trigger since we have a
980   // START_TRACING trigger defined.
981   std::vector<std::string> req;
982   req.push_back("trigger_name");
983   req.push_back("trigger_name_2");
984   req.push_back("trigger_name_3");
985   producer->endpoint()->ActivateTriggers(req);
986 
987   auto writer1 = producer->CreateTraceWriter("ds_1");
988   producer->ExpectFlush(writer1.get());
989   producer->WaitForDataSourceStop("ds_1");
990   consumer->WaitForTracingDisabled();
991 
992   ASSERT_EQ(2u, tracing_session()->received_triggers.size());
993   EXPECT_EQ("trigger_name",
994             tracing_session()->received_triggers[0].trigger_name);
995   EXPECT_EQ("trigger_name_3",
996             tracing_session()->received_triggers[1].trigger_name);
997 
998   auto packets = consumer->ReadBuffers();
999   EXPECT_THAT(
1000       packets,
1001       Contains(Property(
1002           &protos::gen::TracePacket::trace_config,
1003           Property(
1004               &protos::gen::TraceConfig::trigger_config,
1005               Property(&protos::gen::TraceConfig::TriggerConfig::trigger_mode,
1006                        Eq(protos::gen::TraceConfig::TriggerConfig::
1007                               STOP_TRACING))))));
1008 
1009   auto expect_received_trigger = [&](const std::string& name) {
1010     return Contains(AllOf(
1011         Property(&protos::gen::TracePacket::trigger,
1012                  AllOf(Property(&protos::gen::Trigger::trigger_name, Eq(name)),
1013                        Property(&protos::gen::Trigger::trusted_producer_uid,
1014                                 Eq(321)),
1015                        Property(&protos::gen::Trigger::producer_name,
1016                                 Eq("mock_producer")))),
1017         Property(&protos::gen::TracePacket::trusted_packet_sequence_id,
1018                  Eq(kServicePacketSequenceID))));
1019   };
1020   EXPECT_THAT(packets, expect_received_trigger("trigger_name"));
1021   EXPECT_THAT(packets, Not(expect_received_trigger("trigger_name_2")));
1022   EXPECT_THAT(packets, expect_received_trigger("trigger_name_3"));
1023 }
1024 
1025 // Creates a tracing session with a START_TRACING trigger and checks that the
1026 // received_triggers are emitted as packets even ones after the initial
1027 // ReadBuffers() call.
TEST_F(TracingServiceImplTest,EmitTriggersRepeatedly)1028 TEST_F(TracingServiceImplTest, EmitTriggersRepeatedly) {
1029   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1030   consumer->Connect(svc.get());
1031 
1032   std::unique_ptr<MockProducer> producer = CreateMockProducer();
1033   producer->Connect(svc.get(), "mock_producer");
1034 
1035   // Create two data sources but enable only one of them.
1036   producer->RegisterDataSource("ds_1");
1037   producer->RegisterDataSource("ds_2");
1038 
1039   TraceConfig trace_config;
1040   trace_config.add_buffers()->set_size_kb(128);
1041   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
1042   auto* trigger_config = trace_config.mutable_trigger_config();
1043   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
1044   auto* trigger = trigger_config->add_triggers();
1045   trigger->set_name("trigger_name");
1046   trigger->set_stop_delay_ms(1);
1047   trigger = trigger_config->add_triggers();
1048   trigger->set_name("trigger_name_2");
1049   trigger->set_stop_delay_ms(1);
1050 
1051   trigger_config->set_trigger_timeout_ms(30000);
1052 
1053   auto expect_received_trigger = [&](const std::string& name) {
1054     return Contains(AllOf(
1055         Property(&protos::gen::TracePacket::trigger,
1056                  AllOf(Property(&protos::gen::Trigger::trigger_name, Eq(name)),
1057                        Property(&protos::gen::Trigger::producer_name,
1058                                 Eq("mock_producer")))),
1059         Property(&protos::gen::TracePacket::trusted_packet_sequence_id,
1060                  Eq(kServicePacketSequenceID))));
1061   };
1062 
1063   consumer->EnableTracing(trace_config);
1064   producer->WaitForTracingSetup();
1065   producer->WaitForDataSourceSetup("ds_1");
1066   producer->WaitForDataSourceStart("ds_1");
1067 
1068   // The trace won't start until we send the trigger. since we have a
1069   // START_TRACING trigger defined.
1070   producer->endpoint()->ActivateTriggers({"trigger_name"});
1071 
1072   auto packets = consumer->ReadBuffers();
1073   EXPECT_THAT(
1074       packets,
1075       Contains(Property(
1076           &protos::gen::TracePacket::trace_config,
1077           Property(
1078               &protos::gen::TraceConfig::trigger_config,
1079               Property(&protos::gen::TraceConfig::TriggerConfig::trigger_mode,
1080                        Eq(protos::gen::TraceConfig::TriggerConfig::
1081                               STOP_TRACING))))));
1082   EXPECT_THAT(packets, expect_received_trigger("trigger_name"));
1083   EXPECT_THAT(packets, Not(expect_received_trigger("trigger_name_2")));
1084 
1085   // Send a new trigger.
1086   producer->endpoint()->ActivateTriggers({"trigger_name_2"});
1087 
1088   auto writer1 = producer->CreateTraceWriter("ds_1");
1089   producer->ExpectFlush(writer1.get());
1090   producer->WaitForDataSourceStop("ds_1");
1091   consumer->WaitForTracingDisabled();
1092 
1093   ASSERT_EQ(2u, tracing_session()->received_triggers.size());
1094   EXPECT_EQ("trigger_name",
1095             tracing_session()->received_triggers[0].trigger_name);
1096   EXPECT_EQ("trigger_name_2",
1097             tracing_session()->received_triggers[1].trigger_name);
1098 
1099   packets = consumer->ReadBuffers();
1100   // We don't rewrite the old trigger.
1101   EXPECT_THAT(packets, Not(expect_received_trigger("trigger_name")));
1102   EXPECT_THAT(packets, expect_received_trigger("trigger_name_2"));
1103 }
1104 
1105 // Creates a tracing session with a STOP_TRACING trigger and checks that the
1106 // session is cleaned up after |trigger_timeout_ms|.
TEST_F(TracingServiceImplTest,StopTracingTriggerTimeout)1107 TEST_F(TracingServiceImplTest, StopTracingTriggerTimeout) {
1108   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1109   consumer->Connect(svc.get());
1110 
1111   std::unique_ptr<MockProducer> producer = CreateMockProducer();
1112   producer->Connect(svc.get(), "mock_producer");
1113 
1114   // Create two data sources but enable only one of them.
1115   producer->RegisterDataSource("ds_1");
1116   producer->RegisterDataSource("ds_2");
1117 
1118   TraceConfig trace_config;
1119   trace_config.add_buffers()->set_size_kb(128);
1120   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
1121   auto* trigger_config = trace_config.mutable_trigger_config();
1122   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
1123   auto* trigger = trigger_config->add_triggers();
1124   trigger->set_name("trigger_name");
1125   trigger->set_stop_delay_ms(8.64e+7);
1126 
1127   trigger_config->set_trigger_timeout_ms(1);
1128 
1129   // Make sure we don't get unexpected DataSourceStart() notifications yet.
1130   EXPECT_CALL(*producer, StartDataSource(_, _)).Times(0);
1131 
1132   consumer->EnableTracing(trace_config);
1133   producer->WaitForTracingSetup();
1134 
1135   producer->WaitForDataSourceSetup("ds_1");
1136   producer->WaitForDataSourceStart("ds_1");
1137 
1138   // The trace won't return data until unless we send a trigger at this point.
1139   EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
1140 
1141   auto writer = producer->CreateTraceWriter("ds_1");
1142   producer->ExpectFlush(writer.get());
1143 
1144   ASSERT_EQ(0u, tracing_session()->received_triggers.size());
1145 
1146   producer->WaitForDataSourceStop("ds_1");
1147   consumer->WaitForTracingDisabled();
1148   EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
1149 }
1150 
1151 // Creates a tracing session with a STOP_TRACING trigger and checks that the
1152 // session returns data after a trigger is received, but only what is currently
1153 // in the buffer.
TEST_F(TracingServiceImplTest,StopTracingTriggerRingBuffer)1154 TEST_F(TracingServiceImplTest, StopTracingTriggerRingBuffer) {
1155   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1156   consumer->Connect(svc.get());
1157 
1158   std::unique_ptr<MockProducer> producer = CreateMockProducer();
1159   producer->Connect(svc.get(), "mock_producer");
1160 
1161   // Create two data sources but enable only one of them.
1162   producer->RegisterDataSource("ds_1");
1163   producer->RegisterDataSource("ds_2");
1164 
1165   TraceConfig trace_config;
1166   trace_config.add_buffers()->set_size_kb(128);
1167   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
1168   auto* trigger_config = trace_config.mutable_trigger_config();
1169   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
1170   auto* trigger = trigger_config->add_triggers();
1171   trigger->set_name("trigger_name");
1172   trigger->set_stop_delay_ms(1);
1173 
1174   trigger_config->set_trigger_timeout_ms(8.64e+7);
1175 
1176   consumer->EnableTracing(trace_config);
1177   producer->WaitForTracingSetup();
1178 
1179   producer->WaitForDataSourceSetup("ds_1");
1180   producer->WaitForDataSourceStart("ds_1");
1181 
1182   // The trace won't return data until unless we send a trigger at this point.
1183   EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
1184 
1185   // We write into the buffer a large packet which takes up the whole buffer. We
1186   // then add a bunch of smaller ones which causes the larger packet to be
1187   // dropped. After we activate the session we should only see a bunch of the
1188   // smaller ones.
1189   static const size_t kNumTestPackets = 10;
1190   static const char kPayload[] = "1234567890abcdef-";
1191 
1192   auto writer = producer->CreateTraceWriter("ds_1");
1193   // Buffer is 1kb so we write a packet which is slightly smaller so it fits in
1194   // the buffer.
1195   const std::string large_payload(1024 * 128 - 20, 'a');
1196   {
1197     auto tp = writer->NewTracePacket();
1198     tp->set_for_testing()->set_str(large_payload.c_str(), large_payload.size());
1199   }
1200 
1201   // Now we add a bunch of data before the trigger and after.
1202   for (size_t i = 0; i < kNumTestPackets; i++) {
1203     if (i == kNumTestPackets / 2) {
1204       std::vector<std::string> req;
1205       req.push_back("trigger_name");
1206       producer->endpoint()->ActivateTriggers(req);
1207     }
1208     auto tp = writer->NewTracePacket();
1209     std::string payload(kPayload);
1210     payload.append(std::to_string(i));
1211     tp->set_for_testing()->set_str(payload.c_str(), payload.size());
1212   }
1213   producer->ExpectFlush(writer.get());
1214 
1215   ASSERT_EQ(1u, tracing_session()->received_triggers.size());
1216   EXPECT_EQ("trigger_name",
1217             tracing_session()->received_triggers[0].trigger_name);
1218 
1219   producer->WaitForDataSourceStop("ds_1");
1220   consumer->WaitForTracingDisabled();
1221 
1222   auto packets = consumer->ReadBuffers();
1223   EXPECT_LT(kNumTestPackets, packets.size());
1224   // We expect for the TraceConfig preamble packet to be there correctly and
1225   // then we expect each payload to be there, but not the |large_payload|
1226   // packet.
1227   EXPECT_THAT(
1228       packets,
1229       HasTriggerMode(protos::gen::TraceConfig::TriggerConfig::STOP_TRACING));
1230   for (size_t i = 0; i < kNumTestPackets; i++) {
1231     std::string payload = kPayload;
1232     payload += std::to_string(i);
1233     EXPECT_THAT(packets,
1234                 Contains(Property(
1235                     &protos::gen::TracePacket::for_testing,
1236                     Property(&protos::gen::TestEvent::str, Eq(payload)))));
1237   }
1238 
1239   // The large payload was overwritten before we trigger and ReadBuffers so it
1240   // should not be in the returned data.
1241   EXPECT_THAT(packets,
1242               Not(Contains(Property(
1243                   &protos::gen::TracePacket::for_testing,
1244                   Property(&protos::gen::TestEvent::str, Eq(large_payload))))));
1245 }
1246 
1247 // Creates a tracing session with a STOP_TRACING trigger and checks that the
1248 // session only cleans up once even with multiple triggers.
TEST_F(TracingServiceImplTest,StopTracingTriggerMultipleTriggers)1249 TEST_F(TracingServiceImplTest, StopTracingTriggerMultipleTriggers) {
1250   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1251   consumer->Connect(svc.get());
1252 
1253   std::unique_ptr<MockProducer> producer = CreateMockProducer();
1254   producer->Connect(svc.get(), "mock_producer");
1255 
1256   // Create two data sources but enable only one of them.
1257   producer->RegisterDataSource("ds_1");
1258   producer->RegisterDataSource("ds_2");
1259 
1260   TraceConfig trace_config;
1261   trace_config.add_buffers()->set_size_kb(128);
1262   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
1263   auto* trigger_config = trace_config.mutable_trigger_config();
1264   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
1265   auto* trigger = trigger_config->add_triggers();
1266   trigger->set_name("trigger_name");
1267   trigger->set_stop_delay_ms(1);
1268   trigger = trigger_config->add_triggers();
1269   trigger->set_name("trigger_name_2");
1270   trigger->set_stop_delay_ms(8.64e+7);
1271 
1272   trigger_config->set_trigger_timeout_ms(8.64e+7);
1273 
1274   consumer->EnableTracing(trace_config);
1275   producer->WaitForTracingSetup();
1276 
1277   producer->WaitForDataSourceSetup("ds_1");
1278   producer->WaitForDataSourceStart("ds_1");
1279 
1280   // The trace won't return data until unless we send a trigger at this point.
1281   EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
1282 
1283   std::vector<std::string> req;
1284   req.push_back("trigger_name");
1285   req.push_back("trigger_name_3");
1286   req.push_back("trigger_name_2");
1287   producer->endpoint()->ActivateTriggers(req);
1288 
1289   auto writer = producer->CreateTraceWriter("ds_1");
1290   producer->ExpectFlush(writer.get());
1291 
1292   ASSERT_EQ(2u, tracing_session()->received_triggers.size());
1293   EXPECT_EQ("trigger_name",
1294             tracing_session()->received_triggers[0].trigger_name);
1295   EXPECT_EQ("trigger_name_2",
1296             tracing_session()->received_triggers[1].trigger_name);
1297 
1298   producer->WaitForDataSourceStop("ds_1");
1299   consumer->WaitForTracingDisabled();
1300   EXPECT_THAT(
1301       consumer->ReadBuffers(),
1302       HasTriggerMode(protos::gen::TraceConfig::TriggerConfig::STOP_TRACING));
1303 }
1304 
TEST_F(TracingServiceImplTest,SecondTriggerHitsLimit)1305 TEST_F(TracingServiceImplTest, SecondTriggerHitsLimit) {
1306   TraceConfig trace_config;
1307   trace_config.add_buffers()->set_size_kb(128);
1308 
1309   auto* trigger_config = trace_config.mutable_trigger_config();
1310   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
1311   trigger_config->set_trigger_timeout_ms(8.64e+7);
1312 
1313   auto* trigger = trigger_config->add_triggers();
1314   trigger->set_name("trigger_name");
1315   trigger->set_stop_delay_ms(1);
1316   trigger->set_max_per_24_h(1);
1317 
1318   auto* ds = trace_config.add_data_sources()->mutable_config();
1319 
1320   // First session.
1321   {
1322     std::unique_ptr<MockProducer> producer = CreateMockProducer();
1323     producer->Connect(svc.get(), "mock_producer_a");
1324     producer->RegisterDataSource("data_source_a");
1325 
1326     std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1327     consumer->Connect(svc.get());
1328 
1329     ds->set_name("data_source_a");
1330     consumer->EnableTracing(trace_config);
1331     producer->WaitForTracingSetup();
1332 
1333     producer->WaitForDataSourceSetup("data_source_a");
1334     producer->WaitForDataSourceStart("data_source_a");
1335 
1336     std::vector<std::string> req;
1337     req.push_back("trigger_name");
1338     producer->endpoint()->ActivateTriggers(req);
1339 
1340     ASSERT_EQ(1u, tracing_session()->received_triggers.size());
1341     EXPECT_EQ("trigger_name",
1342               tracing_session()->received_triggers[0].trigger_name);
1343 
1344     auto writer = producer->CreateTraceWriter("data_source_a");
1345     producer->ExpectFlush(writer.get());
1346 
1347     producer->WaitForDataSourceStop("data_source_a");
1348     consumer->WaitForTracingDisabled();
1349     EXPECT_THAT(
1350         consumer->ReadBuffers(),
1351         HasTriggerMode(protos::gen::TraceConfig::TriggerConfig::STOP_TRACING));
1352   }
1353 
1354   // Second session.
1355   {
1356     std::unique_ptr<MockProducer> producer = CreateMockProducer();
1357     producer->Connect(svc.get(), "mock_producer_b");
1358     producer->RegisterDataSource("data_source_b");
1359 
1360     std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1361     consumer->Connect(svc.get());
1362 
1363     ds->set_name("data_source_b");
1364     consumer->EnableTracing(trace_config);
1365     producer->WaitForTracingSetup();
1366 
1367     producer->WaitForDataSourceSetup("data_source_b");
1368     producer->WaitForDataSourceStart("data_source_b");
1369 
1370     std::vector<std::string> req;
1371     req.push_back("trigger_name");
1372     producer->endpoint()->ActivateTriggers(req);
1373 
1374     ASSERT_EQ(0u, tracing_session()->received_triggers.size());
1375 
1376     consumer->DisableTracing();
1377     consumer->FreeBuffers();
1378 
1379     producer->WaitForDataSourceStop("data_source_b");
1380     consumer->WaitForTracingDisabled();
1381   }
1382 }
1383 
TEST_F(TracingServiceImplTest,SecondTriggerDoesntHitLimit)1384 TEST_F(TracingServiceImplTest, SecondTriggerDoesntHitLimit) {
1385   TraceConfig trace_config;
1386   trace_config.add_buffers()->set_size_kb(128);
1387 
1388   auto* trigger_config = trace_config.mutable_trigger_config();
1389   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
1390   trigger_config->set_trigger_timeout_ms(8.64e+7);
1391 
1392   auto* trigger = trigger_config->add_triggers();
1393   trigger->set_name("trigger_name");
1394   trigger->set_stop_delay_ms(1);
1395   trigger->set_max_per_24_h(1);
1396 
1397   auto* ds = trace_config.add_data_sources()->mutable_config();
1398 
1399   // Set the trigger window size to something really small so the second
1400   // session is still allowed through.
1401   SetTriggerWindowNs(1);
1402 
1403   // First session.
1404   {
1405     std::unique_ptr<MockProducer> producer = CreateMockProducer();
1406     producer->Connect(svc.get(), "mock_producer_a");
1407     producer->RegisterDataSource("data_source_a");
1408 
1409     std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1410     consumer->Connect(svc.get());
1411 
1412     ds->set_name("data_source_a");
1413     consumer->EnableTracing(trace_config);
1414     producer->WaitForTracingSetup();
1415 
1416     producer->WaitForDataSourceSetup("data_source_a");
1417     producer->WaitForDataSourceStart("data_source_a");
1418 
1419     std::vector<std::string> req;
1420     req.push_back("trigger_name");
1421     producer->endpoint()->ActivateTriggers(req);
1422 
1423     ASSERT_EQ(1u, tracing_session()->received_triggers.size());
1424     EXPECT_EQ("trigger_name",
1425               tracing_session()->received_triggers[0].trigger_name);
1426 
1427     auto writer = producer->CreateTraceWriter("data_source_a");
1428     producer->ExpectFlush(writer.get());
1429 
1430     producer->WaitForDataSourceStop("data_source_a");
1431     consumer->WaitForTracingDisabled();
1432     EXPECT_THAT(
1433         consumer->ReadBuffers(),
1434         HasTriggerMode(protos::gen::TraceConfig::TriggerConfig::STOP_TRACING));
1435   }
1436 
1437   // Sleep 1 micro so that we're sure that the window time would have elapsed.
1438   base::SleepMicroseconds(1);
1439 
1440   // Second session.
1441   {
1442     std::unique_ptr<MockProducer> producer = CreateMockProducer();
1443     producer->Connect(svc.get(), "mock_producer_b");
1444     producer->RegisterDataSource("data_source_b");
1445 
1446     std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1447     consumer->Connect(svc.get());
1448 
1449     ds->set_name("data_source_b");
1450     consumer->EnableTracing(trace_config);
1451     producer->WaitForTracingSetup();
1452 
1453     producer->WaitForDataSourceSetup("data_source_b");
1454     producer->WaitForDataSourceStart("data_source_b");
1455 
1456     std::vector<std::string> req;
1457     req.push_back("trigger_name");
1458     producer->endpoint()->ActivateTriggers(req);
1459 
1460     ASSERT_EQ(1u, tracing_session()->received_triggers.size());
1461     EXPECT_EQ("trigger_name",
1462               tracing_session()->received_triggers[0].trigger_name);
1463 
1464     auto writer = producer->CreateTraceWriter("data_source_b");
1465     producer->ExpectFlush(writer.get());
1466 
1467     producer->WaitForDataSourceStop("data_source_b");
1468     consumer->WaitForTracingDisabled();
1469     EXPECT_THAT(
1470         consumer->ReadBuffers(),
1471         HasTriggerMode(protos::gen::TraceConfig::TriggerConfig::STOP_TRACING));
1472   }
1473 }
1474 
TEST_F(TracingServiceImplTest,SkipProbability)1475 TEST_F(TracingServiceImplTest, SkipProbability) {
1476   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1477   consumer->Connect(svc.get());
1478 
1479   std::unique_ptr<MockProducer> producer = CreateMockProducer();
1480   producer->Connect(svc.get(), "mock_producer");
1481 
1482   producer->RegisterDataSource("data_source");
1483 
1484   TraceConfig trace_config;
1485   trace_config.add_buffers()->set_size_kb(128);
1486   trace_config.add_data_sources()->mutable_config()->set_name("data_source");
1487   auto* trigger_config = trace_config.mutable_trigger_config();
1488   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
1489   auto* trigger = trigger_config->add_triggers();
1490   trigger->set_name("trigger_name");
1491   trigger->set_stop_delay_ms(1);
1492   trigger->set_skip_probability(0.15);
1493 
1494   trigger_config->set_trigger_timeout_ms(8.64e+7);
1495 
1496   consumer->EnableTracing(trace_config);
1497   producer->WaitForTracingSetup();
1498 
1499   producer->WaitForDataSourceSetup("data_source");
1500   producer->WaitForDataSourceStart("data_source");
1501 
1502   std::vector<std::string> req;
1503   req.push_back("trigger_name");
1504 
1505   // This is below the probability of 0.15 so should be skipped.
1506   OverrideNextTriggerRandomNumber(0.14);
1507   producer->endpoint()->ActivateTriggers(req);
1508 
1509   ASSERT_EQ(0u, tracing_session()->received_triggers.size());
1510 
1511   // This is above the probaility of 0.15 so should be allowed.
1512   OverrideNextTriggerRandomNumber(0.16);
1513   producer->endpoint()->ActivateTriggers(req);
1514 
1515   auto writer = producer->CreateTraceWriter("data_source");
1516   producer->ExpectFlush(writer.get());
1517 
1518   ASSERT_EQ(1u, tracing_session()->received_triggers.size());
1519   EXPECT_EQ("trigger_name",
1520             tracing_session()->received_triggers[0].trigger_name);
1521 
1522   producer->WaitForDataSourceStop("data_source");
1523   consumer->WaitForTracingDisabled();
1524   EXPECT_THAT(
1525       consumer->ReadBuffers(),
1526       HasTriggerMode(protos::gen::TraceConfig::TriggerConfig::STOP_TRACING));
1527 }
1528 
1529 // Creates a tracing session with a CLONE_SNAPSHOT trigger and checks that
1530 // ReadBuffer calls on it return consistently no data (as in the case of
1531 // STOP_TRACING with no triggers hit) to avoid double uploads (b/290799105 and
1532 // b/290798988).
TEST_F(TracingServiceImplTest,CloneSnapshotTriggers)1533 TEST_F(TracingServiceImplTest, CloneSnapshotTriggers) {
1534   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1535   consumer->Connect(svc.get());
1536 
1537   std::unique_ptr<MockProducer> producer = CreateMockProducer();
1538   producer->Connect(svc.get(), "mock_producer");
1539   producer->RegisterDataSource("ds_1");
1540 
1541   TraceConfig trace_config;
1542   trace_config.add_buffers()->set_size_kb(128);
1543   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
1544   auto* trigger_config = trace_config.mutable_trigger_config();
1545   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::CLONE_SNAPSHOT);
1546   trigger_config->set_trigger_timeout_ms(8.64e+7);
1547   for (int i = 0; i < 3; i++) {
1548     auto* trigger = trigger_config->add_triggers();
1549     trigger->set_name("trigger_" + std::to_string(i));
1550     trigger->set_stop_delay_ms(1);
1551   }
1552 
1553   consumer->EnableTracing(trace_config);
1554   producer->WaitForTracingSetup();
1555 
1556   producer->WaitForDataSourceSetup("ds_1");
1557   producer->WaitForDataSourceStart("ds_1");
1558 
1559   EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
1560 
1561   auto writer = producer->CreateTraceWriter("ds_1");
1562 
1563   TracingSessionID orig_tsid = GetTracingSessionID();
1564 
1565   // Iterate over a sequence of trigger + CloneSession, to emulate a long trace
1566   // receiving different triggers and being cloned several times.
1567   for (int iter = 0; iter < 3; iter++) {
1568     std::string trigger_name = "trigger_" + std::to_string(iter);
1569     producer->endpoint()->ActivateTriggers({trigger_name});
1570 
1571     auto* orig_session = GetTracingSession(orig_tsid);
1572     ASSERT_EQ(orig_session->received_triggers.size(), 1u);
1573     EXPECT_EQ(trigger_name, orig_session->received_triggers[0].trigger_name);
1574 
1575     // Reading the original trace session should always return nothing. Only the
1576     // cloned sessions should return data.
1577     EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
1578 
1579     // Now clone the session and check that the cloned session has the triggers.
1580     std::unique_ptr<MockConsumer> clone_cons = CreateMockConsumer();
1581     clone_cons->Connect(svc.get());
1582 
1583     std::string checkpoint_name = "clone_done_" + std::to_string(iter);
1584     auto clone_done = task_runner.CreateCheckpoint(checkpoint_name);
1585     EXPECT_CALL(*clone_cons, OnSessionCloned(_))
1586         .WillOnce(InvokeWithoutArgs(clone_done));
1587     clone_cons->CloneSession(orig_tsid);
1588     // CloneSession() will implicitly issue a flush. Linearize with that.
1589     producer->ExpectFlush(writer.get());
1590     task_runner.RunUntilCheckpoint(checkpoint_name);
1591 
1592     // Read the cloned session and ensure it only contains the last trigger
1593     // (i.e. check that the trigger history is reset after each clone and
1594     // doesn't pile up).
1595     auto packets = clone_cons->ReadBuffers();
1596     auto expect_received_trigger = [](const std::string& name) {
1597       return Contains(
1598           Property(&protos::gen::TracePacket::trigger,
1599                    Property(&protos::gen::Trigger::trigger_name, Eq(name))));
1600     };
1601     EXPECT_THAT(packets, expect_received_trigger(trigger_name));
1602     EXPECT_THAT(
1603         packets,
1604         Not(expect_received_trigger("trigger_" + std::to_string(iter - 1))));
1605   }  // for (iter)
1606 
1607   consumer->DisableTracing();
1608   producer->WaitForDataSourceStop("ds_1");
1609   consumer->WaitForTracingDisabled();
1610 }
1611 
TEST_F(TracingServiceImplTest,LockdownMode)1612 TEST_F(TracingServiceImplTest, LockdownMode) {
1613   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1614   consumer->Connect(svc.get());
1615 
1616   std::unique_ptr<MockProducer> producer = CreateMockProducer();
1617   producer->Connect(svc.get(), "mock_producer_sameuid",
1618                     base::GetCurrentUserId());
1619   producer->RegisterDataSource("data_source");
1620 
1621   TraceConfig trace_config;
1622   trace_config.add_buffers()->set_size_kb(128);
1623   auto* ds_config = trace_config.add_data_sources()->mutable_config();
1624   ds_config->set_name("data_source");
1625   trace_config.set_lockdown_mode(TraceConfig::LOCKDOWN_SET);
1626   consumer->EnableTracing(trace_config);
1627 
1628   producer->WaitForTracingSetup();
1629   producer->WaitForDataSourceSetup("data_source");
1630   producer->WaitForDataSourceStart("data_source");
1631 
1632   std::unique_ptr<MockProducer> producer_otheruid = CreateMockProducer();
1633   auto x = svc->ConnectProducer(
1634       producer_otheruid.get(),
1635       ClientIdentity(base::GetCurrentUserId() + 1, base::GetProcessId()),
1636       "mock_producer_ouid");
1637   EXPECT_CALL(*producer_otheruid, OnConnect()).Times(0);
1638   task_runner.RunUntilIdle();
1639   Mock::VerifyAndClearExpectations(producer_otheruid.get());
1640 
1641   consumer->DisableTracing();
1642   consumer->FreeBuffers();
1643   producer->WaitForDataSourceStop("data_source");
1644   consumer->WaitForTracingDisabled();
1645 
1646   trace_config.set_lockdown_mode(TraceConfig::LOCKDOWN_CLEAR);
1647   consumer->EnableTracing(trace_config);
1648   producer->WaitForDataSourceSetup("data_source");
1649   producer->WaitForDataSourceStart("data_source");
1650 
1651   std::unique_ptr<MockProducer> producer_otheruid2 = CreateMockProducer();
1652   producer_otheruid->Connect(svc.get(), "mock_producer_ouid2",
1653                              base::GetCurrentUserId() + 1);
1654 
1655   consumer->DisableTracing();
1656   producer->WaitForDataSourceStop("data_source");
1657   consumer->WaitForTracingDisabled();
1658 }
1659 
TEST_F(TracingServiceImplTest,ProducerNameFilterChange)1660 TEST_F(TracingServiceImplTest, ProducerNameFilterChange) {
1661   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1662   consumer->Connect(svc.get());
1663 
1664   std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1665   producer1->Connect(svc.get(), "mock_producer_1");
1666   producer1->RegisterDataSource("data_source");
1667 
1668   std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1669   producer2->Connect(svc.get(), "mock_producer_2");
1670   producer2->RegisterDataSource("data_source");
1671 
1672   std::unique_ptr<MockProducer> producer3 = CreateMockProducer();
1673   producer3->Connect(svc.get(), "mock_producer_3");
1674   producer3->RegisterDataSource("data_source");
1675   producer3->RegisterDataSource("unused_data_source");
1676 
1677   TraceConfig trace_config;
1678   trace_config.add_buffers()->set_size_kb(128);
1679   auto* data_source = trace_config.add_data_sources();
1680   data_source->mutable_config()->set_name("data_source");
1681   *data_source->add_producer_name_filter() = "mock_producer_1";
1682 
1683   // Enable tracing with only mock_producer_1 enabled;
1684   // the rest should not start up.
1685   consumer->EnableTracing(trace_config);
1686 
1687   producer1->WaitForTracingSetup();
1688   producer1->WaitForDataSourceSetup("data_source");
1689   producer1->WaitForDataSourceStart("data_source");
1690 
1691   EXPECT_CALL(*producer2, OnConnect()).Times(0);
1692   EXPECT_CALL(*producer3, OnConnect()).Times(0);
1693   task_runner.RunUntilIdle();
1694   Mock::VerifyAndClearExpectations(producer2.get());
1695   Mock::VerifyAndClearExpectations(producer3.get());
1696 
1697   // Enable mock_producer_2, the third one should still
1698   // not get connected.
1699   *data_source->add_producer_name_regex_filter() = ".*_producer_[2]";
1700   consumer->ChangeTraceConfig(trace_config);
1701 
1702   producer2->WaitForTracingSetup();
1703   producer2->WaitForDataSourceSetup("data_source");
1704   producer2->WaitForDataSourceStart("data_source");
1705 
1706   // Enable mock_producer_3 but also try to do an
1707   // unsupported change (adding a new data source);
1708   // mock_producer_3 should get enabled but not
1709   // for the new data source.
1710   *data_source->add_producer_name_filter() = "mock_producer_3";
1711   auto* dummy_data_source = trace_config.add_data_sources();
1712   dummy_data_source->mutable_config()->set_name("unused_data_source");
1713   *dummy_data_source->add_producer_name_filter() = "mock_producer_3";
1714 
1715   consumer->ChangeTraceConfig(trace_config);
1716 
1717   producer3->WaitForTracingSetup();
1718   EXPECT_CALL(*producer3, SetupDataSource(_, _)).Times(1);
1719   EXPECT_CALL(*producer3, StartDataSource(_, _)).Times(1);
1720   task_runner.RunUntilIdle();
1721   Mock::VerifyAndClearExpectations(producer3.get());
1722 
1723   consumer->DisableTracing();
1724   consumer->FreeBuffers();
1725   producer1->WaitForDataSourceStop("data_source");
1726   producer2->WaitForDataSourceStop("data_source");
1727 
1728   EXPECT_CALL(*producer3, StopDataSource(_)).Times(1);
1729 
1730   consumer->WaitForTracingDisabled();
1731 
1732   task_runner.RunUntilIdle();
1733   Mock::VerifyAndClearExpectations(producer3.get());
1734 }
1735 
TEST_F(TracingServiceImplTest,ProducerNameFilterChangeTwoDataSources)1736 TEST_F(TracingServiceImplTest, ProducerNameFilterChangeTwoDataSources) {
1737   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1738   consumer->Connect(svc.get());
1739 
1740   std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
1741   producer1->Connect(svc.get(), "mock_producer_1");
1742   producer1->RegisterDataSource("data_source");
1743 
1744   std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
1745   producer2->Connect(svc.get(), "mock_producer_2");
1746   producer2->RegisterDataSource("data_source");
1747   producer2->RegisterDataSource("data_source");
1748 
1749   TraceConfig trace_config;
1750   trace_config.add_buffers()->set_size_kb(128);
1751   auto* data_source = trace_config.add_data_sources();
1752   data_source->mutable_config()->set_name("data_source");
1753   *data_source->add_producer_name_filter() = "mock_producer_1";
1754 
1755   // Enable tracing with only mock_producer_1 enabled;
1756   // the rest should not start up.
1757   consumer->EnableTracing(trace_config);
1758 
1759   producer1->WaitForTracingSetup();
1760   EXPECT_CALL(*producer1, SetupDataSource(_, _)).Times(1);
1761   EXPECT_CALL(*producer1, StartDataSource(_, _)).Times(1);
1762 
1763   task_runner.RunUntilIdle();
1764   Mock::VerifyAndClearExpectations(producer1.get());
1765   Mock::VerifyAndClearExpectations(producer2.get());
1766 
1767   // Enable mock_producer_2, both instances of "data_source" should start
1768   *data_source->add_producer_name_regex_filter() = ".*_producer_[2]";
1769   consumer->ChangeTraceConfig(trace_config);
1770 
1771   producer2->WaitForTracingSetup();
1772   EXPECT_CALL(*producer2, SetupDataSource(_, _)).Times(2);
1773   EXPECT_CALL(*producer2, StartDataSource(_, _)).Times(2);
1774 
1775   task_runner.RunUntilIdle();
1776   Mock::VerifyAndClearExpectations(producer1.get());
1777   Mock::VerifyAndClearExpectations(producer2.get());
1778 
1779   consumer->DisableTracing();
1780   consumer->FreeBuffers();
1781 
1782   EXPECT_CALL(*producer1, StopDataSource(_)).Times(1);
1783   EXPECT_CALL(*producer2, StopDataSource(_)).Times(2);
1784 
1785   consumer->WaitForTracingDisabled();
1786 
1787   task_runner.RunUntilIdle();
1788   Mock::VerifyAndClearExpectations(producer1.get());
1789   Mock::VerifyAndClearExpectations(producer2.get());
1790 }
1791 
TEST_F(TracingServiceImplTest,DisconnectConsumerWhileTracing)1792 TEST_F(TracingServiceImplTest, DisconnectConsumerWhileTracing) {
1793   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1794   consumer->Connect(svc.get());
1795 
1796   std::unique_ptr<MockProducer> producer = CreateMockProducer();
1797   producer->Connect(svc.get(), "mock_producer");
1798   producer->RegisterDataSource("data_source");
1799 
1800   TraceConfig trace_config;
1801   trace_config.add_buffers()->set_size_kb(128);
1802   auto* ds_config = trace_config.add_data_sources()->mutable_config();
1803   ds_config->set_name("data_source");
1804   consumer->EnableTracing(trace_config);
1805 
1806   producer->WaitForTracingSetup();
1807   producer->WaitForDataSourceSetup("data_source");
1808   producer->WaitForDataSourceStart("data_source");
1809 
1810   // Disconnecting the consumer while tracing should trigger data source
1811   // teardown.
1812   consumer.reset();
1813   producer->WaitForDataSourceStop("data_source");
1814 }
1815 
TEST_F(TracingServiceImplTest,ReconnectProducerWhileTracing)1816 TEST_F(TracingServiceImplTest, ReconnectProducerWhileTracing) {
1817   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1818   consumer->Connect(svc.get());
1819 
1820   std::unique_ptr<MockProducer> producer = CreateMockProducer();
1821   producer->Connect(svc.get(), "mock_producer");
1822   producer->RegisterDataSource("data_source");
1823 
1824   TraceConfig trace_config;
1825   trace_config.add_buffers()->set_size_kb(128);
1826   auto* ds_config = trace_config.add_data_sources()->mutable_config();
1827   ds_config->set_name("data_source");
1828   consumer->EnableTracing(trace_config);
1829 
1830   producer->WaitForTracingSetup();
1831   producer->WaitForDataSourceSetup("data_source");
1832   producer->WaitForDataSourceStart("data_source");
1833 
1834   // Disconnecting and reconnecting a producer with a matching data source.
1835   // The Producer should see that data source getting enabled again.
1836   producer.reset();
1837   producer = CreateMockProducer();
1838   producer->Connect(svc.get(), "mock_producer_2");
1839   producer->RegisterDataSource("data_source");
1840   producer->WaitForTracingSetup();
1841   producer->WaitForDataSourceSetup("data_source");
1842   producer->WaitForDataSourceStart("data_source");
1843 }
1844 
TEST_F(TracingServiceImplTest,ProducerIDWrapping)1845 TEST_F(TracingServiceImplTest, ProducerIDWrapping) {
1846   std::vector<std::unique_ptr<MockProducer>> producers;
1847   producers.push_back(nullptr);
1848 
1849   auto connect_producer_and_get_id = [&producers,
1850                                       this](const std::string& name) {
1851     producers.emplace_back(CreateMockProducer());
1852     producers.back()->Connect(svc.get(), "mock_producer_" + name);
1853     return *last_producer_id();
1854   };
1855 
1856   // Connect producers 1-4.
1857   for (ProducerID i = 1; i <= 4; i++)
1858     ASSERT_EQ(i, connect_producer_and_get_id(std::to_string(i)));
1859 
1860   // Disconnect producers 1,3.
1861   producers[1].reset();
1862   producers[3].reset();
1863 
1864   *last_producer_id() = kMaxProducerID - 1;
1865   ASSERT_EQ(kMaxProducerID, connect_producer_and_get_id("maxid"));
1866   ASSERT_EQ(1u, connect_producer_and_get_id("1_again"));
1867   ASSERT_EQ(3u, connect_producer_and_get_id("3_again"));
1868   ASSERT_EQ(5u, connect_producer_and_get_id("5"));
1869   ASSERT_EQ(6u, connect_producer_and_get_id("6"));
1870 }
1871 
TEST_F(TracingServiceImplTest,CompressionConfiguredButUnsupported)1872 TEST_F(TracingServiceImplTest, CompressionConfiguredButUnsupported) {
1873   // Initialize the service without support for compression.
1874   TracingService::InitOpts init_opts;
1875   init_opts.compressor_fn = nullptr;
1876   InitializeSvcWithOpts(init_opts);
1877 
1878   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1879   consumer->Connect(svc.get());
1880 
1881   std::unique_ptr<MockProducer> producer = CreateMockProducer();
1882   producer->Connect(svc.get(), "mock_producer");
1883   producer->RegisterDataSource("data_source");
1884 
1885   TraceConfig trace_config;
1886   trace_config.add_buffers()->set_size_kb(4096);
1887   auto* ds_config = trace_config.add_data_sources()->mutable_config();
1888   ds_config->set_name("data_source");
1889   ds_config->set_target_buffer(0);
1890   // Ask for compression in the config.
1891   trace_config.set_compression_type(TraceConfig::COMPRESSION_TYPE_DEFLATE);
1892   consumer->EnableTracing(trace_config);
1893 
1894   producer->WaitForTracingSetup();
1895   producer->WaitForDataSourceSetup("data_source");
1896   producer->WaitForDataSourceStart("data_source");
1897 
1898   std::unique_ptr<TraceWriter> writer =
1899       producer->CreateTraceWriter("data_source");
1900   {
1901     auto tp = writer->NewTracePacket();
1902     tp->set_for_testing()->set_str("payload-1");
1903   }
1904   {
1905     auto tp = writer->NewTracePacket();
1906     tp->set_for_testing()->set_str("payload-2");
1907   }
1908 
1909   writer->Flush();
1910   writer.reset();
1911 
1912   consumer->DisableTracing();
1913   producer->WaitForDataSourceStop("data_source");
1914   consumer->WaitForTracingDisabled();
1915 
1916   // The packets should NOT be compressed.
1917   std::vector<protos::gen::TracePacket> packets = consumer->ReadBuffers();
1918   EXPECT_THAT(packets, Not(IsEmpty()));
1919   EXPECT_THAT(
1920       packets,
1921       Each(Property(&protos::gen::TracePacket::has_compressed_packets, false)));
1922   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
1923                                          Property(&protos::gen::TestEvent::str,
1924                                                   Eq("payload-1")))));
1925   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
1926                                          Property(&protos::gen::TestEvent::str,
1927                                                   Eq("payload-2")))));
1928 }
1929 
1930 #if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
TEST_F(TracingServiceImplTest,CompressionReadIpc)1931 TEST_F(TracingServiceImplTest, CompressionReadIpc) {
1932   TracingService::InitOpts init_opts;
1933   init_opts.compressor_fn = ZlibCompressFn;
1934   InitializeSvcWithOpts(init_opts);
1935 
1936   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1937   consumer->Connect(svc.get());
1938 
1939   std::unique_ptr<MockProducer> producer = CreateMockProducer();
1940   producer->Connect(svc.get(), "mock_producer");
1941   producer->RegisterDataSource("data_source");
1942 
1943   TraceConfig trace_config;
1944   trace_config.add_buffers()->set_size_kb(4096);
1945   auto* ds_config = trace_config.add_data_sources()->mutable_config();
1946   ds_config->set_name("data_source");
1947   ds_config->set_target_buffer(0);
1948   trace_config.set_compression_type(TraceConfig::COMPRESSION_TYPE_DEFLATE);
1949   consumer->EnableTracing(trace_config);
1950 
1951   producer->WaitForTracingSetup();
1952   producer->WaitForDataSourceSetup("data_source");
1953   producer->WaitForDataSourceStart("data_source");
1954 
1955   std::unique_ptr<TraceWriter> writer =
1956       producer->CreateTraceWriter("data_source");
1957   {
1958     auto tp = writer->NewTracePacket();
1959     tp->set_for_testing()->set_str("payload-1");
1960   }
1961   {
1962     auto tp = writer->NewTracePacket();
1963     tp->set_for_testing()->set_str("payload-2");
1964   }
1965 
1966   writer->Flush();
1967   writer.reset();
1968 
1969   consumer->DisableTracing();
1970   producer->WaitForDataSourceStop("data_source");
1971   consumer->WaitForTracingDisabled();
1972 
1973   std::vector<protos::gen::TracePacket> compressed_packets =
1974       consumer->ReadBuffers();
1975   EXPECT_THAT(compressed_packets, Not(IsEmpty()));
1976   EXPECT_THAT(compressed_packets,
1977               Each(Property(&protos::gen::TracePacket::compressed_packets,
1978                             Not(IsEmpty()))));
1979   std::vector<protos::gen::TracePacket> decompressed_packets =
1980       DecompressTrace(compressed_packets);
1981   EXPECT_THAT(decompressed_packets,
1982               Contains(Property(
1983                   &protos::gen::TracePacket::for_testing,
1984                   Property(&protos::gen::TestEvent::str, Eq("payload-1")))));
1985   EXPECT_THAT(decompressed_packets,
1986               Contains(Property(
1987                   &protos::gen::TracePacket::for_testing,
1988                   Property(&protos::gen::TestEvent::str, Eq("payload-2")))));
1989 }
1990 
TEST_F(TracingServiceImplTest,CompressionWriteIntoFile)1991 TEST_F(TracingServiceImplTest, CompressionWriteIntoFile) {
1992   TracingService::InitOpts init_opts;
1993   init_opts.compressor_fn = ZlibCompressFn;
1994   InitializeSvcWithOpts(init_opts);
1995 
1996   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
1997   consumer->Connect(svc.get());
1998 
1999   std::unique_ptr<MockProducer> producer = CreateMockProducer();
2000   producer->Connect(svc.get(), "mock_producer");
2001   producer->RegisterDataSource("data_source");
2002 
2003   TraceConfig trace_config;
2004   trace_config.add_buffers()->set_size_kb(4096);
2005   auto* ds_config = trace_config.add_data_sources()->mutable_config();
2006   ds_config->set_name("data_source");
2007   ds_config->set_target_buffer(0);
2008   trace_config.set_write_into_file(true);
2009   trace_config.set_compression_type(TraceConfig::COMPRESSION_TYPE_DEFLATE);
2010   base::TempFile tmp_file = base::TempFile::Create();
2011   consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
2012 
2013   producer->WaitForTracingSetup();
2014   producer->WaitForDataSourceSetup("data_source");
2015   producer->WaitForDataSourceStart("data_source");
2016 
2017   std::unique_ptr<TraceWriter> writer =
2018       producer->CreateTraceWriter("data_source");
2019   {
2020     auto tp = writer->NewTracePacket();
2021     tp->set_for_testing()->set_str("payload-1");
2022   }
2023   {
2024     auto tp = writer->NewTracePacket();
2025     tp->set_for_testing()->set_str("payload-2");
2026   }
2027 
2028   writer->Flush();
2029   writer.reset();
2030 
2031   consumer->DisableTracing();
2032   producer->WaitForDataSourceStop("data_source");
2033   consumer->WaitForTracingDisabled();
2034 
2035   // Verify the contents of the file.
2036   std::string trace_raw;
2037   ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
2038   protos::gen::Trace trace;
2039   ASSERT_TRUE(trace.ParseFromString(trace_raw));
2040   EXPECT_THAT(trace.packet(), Not(IsEmpty()));
2041   EXPECT_THAT(trace.packet(),
2042               Each(Property(&protos::gen::TracePacket::compressed_packets,
2043                             Not(IsEmpty()))));
2044   std::vector<protos::gen::TracePacket> decompressed_packets =
2045       DecompressTrace(trace.packet());
2046   EXPECT_THAT(decompressed_packets,
2047               Contains(Property(
2048                   &protos::gen::TracePacket::for_testing,
2049                   Property(&protos::gen::TestEvent::str, Eq("payload-1")))));
2050   EXPECT_THAT(decompressed_packets,
2051               Contains(Property(
2052                   &protos::gen::TracePacket::for_testing,
2053                   Property(&protos::gen::TestEvent::str, Eq("payload-2")))));
2054 }
2055 
TEST_F(TracingServiceImplTest,CloneSessionWithCompression)2056 TEST_F(TracingServiceImplTest, CloneSessionWithCompression) {
2057   TracingService::InitOpts init_opts;
2058   init_opts.compressor_fn = ZlibCompressFn;
2059   InitializeSvcWithOpts(init_opts);
2060 
2061   // The consumer the creates the initial tracing session.
2062   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2063   consumer->Connect(svc.get());
2064 
2065   // The consumer that clones it and reads back the data.
2066   std::unique_ptr<MockConsumer> consumer2 = CreateMockConsumer();
2067   consumer2->Connect(svc.get());
2068 
2069   std::unique_ptr<MockProducer> producer = CreateMockProducer();
2070   producer->Connect(svc.get(), "mock_producer");
2071 
2072   producer->RegisterDataSource("ds_1");
2073 
2074   TraceConfig trace_config;
2075   trace_config.add_buffers()->set_size_kb(32);
2076   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
2077   ds_cfg->set_name("ds_1");
2078   trace_config.set_compression_type(TraceConfig::COMPRESSION_TYPE_DEFLATE);
2079 
2080   consumer->EnableTracing(trace_config);
2081   producer->WaitForTracingSetup();
2082 
2083   producer->WaitForDataSourceSetup("ds_1");
2084 
2085   producer->WaitForDataSourceStart("ds_1");
2086 
2087   std::unique_ptr<TraceWriter> writer = producer->CreateTraceWriter("ds_1");
2088 
2089   // Add some data.
2090   static constexpr size_t kNumTestPackets = 20;
2091   for (size_t i = 0; i < kNumTestPackets; i++) {
2092     auto tp = writer->NewTracePacket();
2093     std::string payload("payload" + std::to_string(i));
2094     tp->set_for_testing()->set_str(payload.c_str(), payload.size());
2095     tp->set_timestamp(static_cast<uint64_t>(i));
2096   }
2097 
2098   auto clone_done = task_runner.CreateCheckpoint("clone_done");
2099   EXPECT_CALL(*consumer2, OnSessionCloned(_))
2100       .WillOnce(Invoke([clone_done](const Consumer::OnSessionClonedArgs&) {
2101         clone_done();
2102       }));
2103   consumer2->CloneSession(1);
2104   // CloneSession() will implicitly issue a flush. Linearize with that.
2105   FlushFlags expected_flags(FlushFlags::Initiator::kTraced,
2106                             FlushFlags::Reason::kTraceClone);
2107   producer->ExpectFlush(writer.get(), /*reply=*/true, expected_flags);
2108   task_runner.RunUntilCheckpoint("clone_done");
2109 
2110   // Delete the initial tracing session.
2111   consumer->DisableTracing();
2112   consumer->FreeBuffers();
2113   producer->WaitForDataSourceStop("ds_1");
2114   consumer->WaitForTracingDisabled();
2115 
2116   // Read back the cloned trace and check that it's compressed
2117   std::vector<protos::gen::TracePacket> compressed_packets =
2118       consumer2->ReadBuffers();
2119   EXPECT_THAT(compressed_packets, Not(IsEmpty()));
2120   EXPECT_THAT(compressed_packets,
2121               Each(Property(&protos::gen::TracePacket::compressed_packets,
2122                             Not(IsEmpty()))));
2123 }
2124 
2125 #endif  // PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
2126 
2127 // Note: file_write_period_ms is set to a large enough to have exactly one flush
2128 // of the tracing buffers (and therefore at most one synchronization section),
2129 // unless the test runs unrealistically slowly, or the implementation of the
2130 // tracing snapshot packets changes.
TEST_F(TracingServiceImplTest,WriteIntoFileAndStopOnMaxSize)2131 TEST_F(TracingServiceImplTest, WriteIntoFileAndStopOnMaxSize) {
2132   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2133   consumer->Connect(svc.get());
2134 
2135   std::unique_ptr<MockProducer> producer = CreateMockProducer();
2136   producer->Connect(svc.get(), "mock_producer");
2137   producer->RegisterDataSource("data_source");
2138 
2139   TraceConfig trace_config;
2140   trace_config.add_buffers()->set_size_kb(4096);
2141   auto* ds_config = trace_config.add_data_sources()->mutable_config();
2142   ds_config->set_name("data_source");
2143   ds_config->set_target_buffer(0);
2144   trace_config.set_write_into_file(true);
2145   trace_config.set_file_write_period_ms(100000);  // 100s
2146   const uint64_t kMaxFileSize = 1024;
2147   trace_config.set_max_file_size_bytes(kMaxFileSize);
2148   base::TempFile tmp_file = base::TempFile::Create();
2149   consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
2150 
2151   producer->WaitForTracingSetup();
2152   producer->WaitForDataSourceSetup("data_source");
2153   producer->WaitForDataSourceStart("data_source");
2154 
2155   // The preamble packets are:
2156   // Trace start clock snapshot
2157   // Trace most recent clock snapshot
2158   // Trace synchronisation
2159   // TraceUuid
2160   // Config
2161   // SystemInfo
2162   // Tracing started (TracingServiceEvent)
2163   // All data source started (TracingServiceEvent)
2164   // Tracing disabled (TracingServiceEvent)
2165   static const int kNumPreamblePackets = 9;
2166   static const int kNumTestPackets = 9;
2167   static const char kPayload[] = "1234567890abcdef-";
2168 
2169   std::unique_ptr<TraceWriter> writer =
2170       producer->CreateTraceWriter("data_source");
2171   // Tracing service will emit a preamble of packets (a synchronization section,
2172   // followed by a tracing config packet). The preamble and these test packets
2173   // should fit within kMaxFileSize.
2174   for (int i = 0; i < kNumTestPackets; i++) {
2175     auto tp = writer->NewTracePacket();
2176     std::string payload(kPayload);
2177     payload.append(std::to_string(i));
2178     tp->set_for_testing()->set_str(payload.c_str(), payload.size());
2179   }
2180 
2181   // Finally add a packet that overflows kMaxFileSize. This should cause the
2182   // implicit stop of the trace and should *not* be written in the trace.
2183   {
2184     auto tp = writer->NewTracePacket();
2185     char big_payload[kMaxFileSize] = "BIG!";
2186     tp->set_for_testing()->set_str(big_payload, sizeof(big_payload));
2187   }
2188   writer->Flush();
2189   writer.reset();
2190 
2191   consumer->DisableTracing();
2192   producer->WaitForDataSourceStop("data_source");
2193   consumer->WaitForTracingDisabled();
2194 
2195   // Verify the contents of the file.
2196   std::string trace_raw;
2197   ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
2198   protos::gen::Trace trace;
2199   ASSERT_TRUE(trace.ParseFromString(trace_raw));
2200 
2201   ASSERT_EQ(trace.packet_size(), kNumPreamblePackets + kNumTestPackets);
2202   for (size_t i = 0; i < kNumTestPackets; i++) {
2203     const protos::gen::TracePacket& tp =
2204         trace.packet()[kNumPreamblePackets + i];
2205     ASSERT_EQ(kPayload + std::to_string(i++), tp.for_testing().str());
2206   }
2207 }
2208 
TEST_F(TracingServiceImplTest,WriteIntoFileWithPath)2209 TEST_F(TracingServiceImplTest, WriteIntoFileWithPath) {
2210   auto tmp_file = base::TempFile::Create();
2211   // Deletes the file (the service would refuse to overwrite an existing file)
2212   // without telling it to the underlying TempFile, so that its dtor will
2213   // unlink the file created by the service.
2214   unlink(tmp_file.path().c_str());
2215 
2216   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2217   consumer->Connect(svc.get());
2218 
2219   std::unique_ptr<MockProducer> producer = CreateMockProducer();
2220   producer->Connect(svc.get(), "mock_producer");
2221   producer->RegisterDataSource("data_source");
2222 
2223   TraceConfig trace_config;
2224   trace_config.add_buffers()->set_size_kb(4096);
2225   auto* ds_config = trace_config.add_data_sources()->mutable_config();
2226   ds_config->set_name("data_source");
2227   ds_config->set_target_buffer(0);
2228   trace_config.set_write_into_file(true);
2229   trace_config.set_output_path(tmp_file.path());
2230   consumer->EnableTracing(trace_config);
2231 
2232   producer->WaitForTracingSetup();
2233   producer->WaitForDataSourceSetup("data_source");
2234   producer->WaitForDataSourceStart("data_source");
2235   std::unique_ptr<TraceWriter> writer =
2236       producer->CreateTraceWriter("data_source");
2237 
2238   {
2239     auto tp = writer->NewTracePacket();
2240     tp->set_for_testing()->set_str("payload");
2241   }
2242   writer->Flush();
2243   writer.reset();
2244 
2245   consumer->DisableTracing();
2246   producer->WaitForDataSourceStop("data_source");
2247   consumer->WaitForTracingDisabled();
2248 
2249   // Verify the contents of the file.
2250   std::string trace_raw;
2251   ASSERT_TRUE(base::ReadFile(tmp_file.path(), &trace_raw));
2252   protos::gen::Trace trace;
2253   ASSERT_TRUE(trace.ParseFromString(trace_raw));
2254   // ASSERT_EQ(trace.packet_size(), 33);
2255   EXPECT_THAT(trace.packet(),
2256               Contains(Property(
2257                   &protos::gen::TracePacket::for_testing,
2258                   Property(&protos::gen::TestEvent::str, Eq("payload")))));
2259 }
2260 
TEST_F(TracingServiceImplTest,WriteIntoFileFilterMultipleChunks)2261 TEST_F(TracingServiceImplTest, WriteIntoFileFilterMultipleChunks) {
2262   static const size_t kNumTestPackets = 5;
2263   static const size_t kPayloadSize = 500 * 1024UL;
2264   static_assert(kNumTestPackets * kPayloadSize >
2265                     TracingServiceImpl::kWriteIntoFileChunkSize,
2266                 "This test covers filtering multiple chunks");
2267 
2268   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2269   consumer->Connect(svc.get());
2270 
2271   std::unique_ptr<MockProducer> producer = CreateMockProducer();
2272   producer->Connect(svc.get(), "mock_producer");
2273   producer->RegisterDataSource("data_source");
2274 
2275   TraceConfig trace_config;
2276   trace_config.add_buffers()->set_size_kb(4096);
2277   auto* ds_config = trace_config.add_data_sources()->mutable_config();
2278   ds_config->set_name("data_source");
2279   ds_config->set_target_buffer(0);
2280   trace_config.set_write_into_file(true);
2281   trace_config.set_file_write_period_ms(100000);  // 100s
2282 
2283   protozero::FilterBytecodeGenerator filt;
2284   // Message 0: root Trace proto.
2285   filt.AddNestedField(1 /* root trace.packet*/, 1);
2286   filt.EndMessage();
2287   // Message 1: TracePacket proto. Allow all fields.
2288   filt.AddSimpleFieldRange(1, 1000);
2289   filt.EndMessage();
2290   trace_config.mutable_trace_filter()->set_bytecode(filt.Serialize());
2291 
2292   base::TempFile tmp_file = base::TempFile::Create();
2293   consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
2294 
2295   producer->WaitForTracingSetup();
2296   producer->WaitForDataSourceSetup("data_source");
2297   producer->WaitForDataSourceStart("data_source");
2298 
2299   std::unique_ptr<TraceWriter> writer =
2300       producer->CreateTraceWriter("data_source");
2301   for (size_t i = 0; i < kNumTestPackets; i++) {
2302     auto tp = writer->NewTracePacket();
2303     std::string payload(kPayloadSize, 'c');
2304     tp->set_for_testing()->set_str(payload.c_str(), payload.size());
2305   }
2306 
2307   writer->Flush();
2308   writer.reset();
2309 
2310   consumer->DisableTracing();
2311   producer->WaitForDataSourceStop("data_source");
2312   consumer->WaitForTracingDisabled();
2313 
2314   consumer->GetTraceStats();
2315   TraceStats stats = consumer->WaitForTraceStats(true);
2316 
2317   std::string trace_raw;
2318   ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
2319   protozero::ProtoDecoder dec(trace_raw.data(), trace_raw.size());
2320   size_t total_size = 0;
2321   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
2322     total_size += field.size();
2323   }
2324   EXPECT_EQ(total_size, stats.filter_stats().output_bytes());
2325   EXPECT_GT(total_size, kNumTestPackets * kPayloadSize);
2326 }
2327 
2328 // Test the logic that allows the trace config to set the shm total size and
2329 // page size from the trace config. Also check that, if the config doesn't
2330 // specify a value we fall back on the hint provided by the producer.
TEST_F(TracingServiceImplTest,ProducerShmAndPageSizeOverriddenByTraceConfig)2331 TEST_F(TracingServiceImplTest, ProducerShmAndPageSizeOverriddenByTraceConfig) {
2332   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2333   consumer->Connect(svc.get());
2334   const size_t kMaxPageSizeKb = 32;
2335 
2336   struct ConfiguredAndExpectedSizes {
2337     size_t config_page_size_kb;
2338     size_t hint_page_size_kb;
2339     size_t expected_page_size_kb;
2340 
2341     size_t config_size_kb;
2342     size_t hint_size_kb;
2343     size_t expected_size_kb;
2344   };
2345 
2346   ConfiguredAndExpectedSizes kSizes[] = {
2347       // Config and hint are 0, fallback to default values.
2348       {0, 0, kDefaultShmPageSizeKb, 0, 0, kDefaultShmSizeKb},
2349       // Use configured sizes.
2350       {16, 0, 16, 16, 0, 16},
2351       // Config is 0, use hint.
2352       {0, 4, 4, 0, 16, 16},
2353       // Config takes precendence over hint.
2354       {4, 8, 4, 16, 32, 16},
2355       // Config takes precendence over hint, even if it's larger.
2356       {8, 4, 8, 32, 16, 32},
2357       // Config page size % 4 != 0, fallback to defaults.
2358       {3, 0, kDefaultShmPageSizeKb, 0, 0, kDefaultShmSizeKb},
2359       // Config page size less than system page size, fallback to defaults.
2360       {2, 0, kDefaultShmPageSizeKb, 0, 0, kDefaultShmSizeKb},
2361       // Config sizes too large, use max.
2362       {4096, 0, kMaxPageSizeKb, 4096000, 0, kMaxShmSizeKb},
2363       // Hint sizes too large, use max.
2364       {0, 4096, kMaxPageSizeKb, 0, 4096000, kMaxShmSizeKb},
2365       // Config buffer size isn't a multiple of 4KB, fallback to defaults.
2366       {0, 0, kDefaultShmPageSizeKb, 18, 0, kDefaultShmSizeKb},
2367       // Invalid page size -> also ignore buffer size config.
2368       {2, 0, kDefaultShmPageSizeKb, 32, 0, kDefaultShmSizeKb},
2369       // Invalid buffer size -> also ignore page size config.
2370       {16, 0, kDefaultShmPageSizeKb, 18, 0, kDefaultShmSizeKb},
2371       // Config page size % buffer size != 0, fallback to defaults.
2372       {8, 0, kDefaultShmPageSizeKb, 20, 0, kDefaultShmSizeKb},
2373       // Config page size % default buffer size != 0, fallback to defaults.
2374       {28, 0, kDefaultShmPageSizeKb, 0, 0, kDefaultShmSizeKb},
2375   };
2376 
2377   const size_t kNumProducers = base::ArraySize(kSizes);
2378   std::unique_ptr<MockProducer> producer[kNumProducers];
2379   for (size_t i = 0; i < kNumProducers; i++) {
2380     auto name = "mock_producer_" + std::to_string(i);
2381     producer[i] = CreateMockProducer();
2382     producer[i]->Connect(svc.get(), name, base::GetCurrentUserId(),
2383                          base::GetProcessId(), kSizes[i].hint_size_kb * 1024,
2384                          kSizes[i].hint_page_size_kb * 1024);
2385     producer[i]->RegisterDataSource("data_source");
2386   }
2387 
2388   TraceConfig trace_config;
2389   trace_config.add_buffers()->set_size_kb(128);
2390   auto* ds_config = trace_config.add_data_sources()->mutable_config();
2391   ds_config->set_name("data_source");
2392   for (size_t i = 0; i < kNumProducers; i++) {
2393     auto* producer_config = trace_config.add_producers();
2394     producer_config->set_producer_name("mock_producer_" + std::to_string(i));
2395     producer_config->set_shm_size_kb(
2396         static_cast<uint32_t>(kSizes[i].config_size_kb));
2397     producer_config->set_page_size_kb(
2398         static_cast<uint32_t>(kSizes[i].config_page_size_kb));
2399   }
2400 
2401   consumer->EnableTracing(trace_config);
2402   size_t expected_shm_sizes_kb[kNumProducers]{};
2403   size_t expected_page_sizes_kb[kNumProducers]{};
2404   size_t actual_shm_sizes_kb[kNumProducers]{};
2405   size_t actual_page_sizes_kb[kNumProducers]{};
2406   for (size_t i = 0; i < kNumProducers; i++) {
2407     expected_shm_sizes_kb[i] = kSizes[i].expected_size_kb;
2408     expected_page_sizes_kb[i] = kSizes[i].expected_page_size_kb;
2409 
2410     producer[i]->WaitForTracingSetup();
2411     producer[i]->WaitForDataSourceSetup("data_source");
2412     actual_shm_sizes_kb[i] =
2413         producer[i]->endpoint()->shared_memory()->size() / 1024;
2414     actual_page_sizes_kb[i] =
2415         producer[i]->endpoint()->shared_buffer_page_size_kb();
2416   }
2417   for (size_t i = 0; i < kNumProducers; i++) {
2418     producer[i]->WaitForDataSourceStart("data_source");
2419   }
2420   ASSERT_THAT(actual_page_sizes_kb, ElementsAreArray(expected_page_sizes_kb));
2421   ASSERT_THAT(actual_shm_sizes_kb, ElementsAreArray(expected_shm_sizes_kb));
2422 }
2423 
TEST_F(TracingServiceImplTest,ExplicitFlush)2424 TEST_F(TracingServiceImplTest, ExplicitFlush) {
2425   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2426   consumer->Connect(svc.get());
2427 
2428   std::unique_ptr<MockProducer> producer = CreateMockProducer();
2429   producer->Connect(svc.get(), "mock_producer");
2430   producer->RegisterDataSource("data_source");
2431 
2432   TraceConfig trace_config;
2433   trace_config.add_buffers()->set_size_kb(128);
2434   auto* ds_config = trace_config.add_data_sources()->mutable_config();
2435   ds_config->set_name("data_source");
2436 
2437   consumer->EnableTracing(trace_config);
2438   producer->WaitForTracingSetup();
2439   producer->WaitForDataSourceSetup("data_source");
2440   producer->WaitForDataSourceStart("data_source");
2441 
2442   std::unique_ptr<TraceWriter> writer =
2443       producer->CreateTraceWriter("data_source");
2444   {
2445     auto tp = writer->NewTracePacket();
2446     tp->set_for_testing()->set_str("payload");
2447   }
2448 
2449   auto flush_request = consumer->Flush();
2450   FlushFlags expected_flags(FlushFlags::Initiator::kConsumerSdk,
2451                             FlushFlags::Reason::kExplicit);
2452   producer->ExpectFlush(writer.get(), /*reply=*/true, expected_flags);
2453   ASSERT_TRUE(flush_request.WaitForReply());
2454 
2455   consumer->DisableTracing();
2456   producer->WaitForDataSourceStop("data_source");
2457   consumer->WaitForTracingDisabled();
2458   EXPECT_THAT(consumer->ReadBuffers(),
2459               Contains(Property(
2460                   &protos::gen::TracePacket::for_testing,
2461                   Property(&protos::gen::TestEvent::str, Eq("payload")))));
2462 }
2463 
TEST_F(TracingServiceImplTest,ImplicitFlushOnTimedTraces)2464 TEST_F(TracingServiceImplTest, ImplicitFlushOnTimedTraces) {
2465   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2466   consumer->Connect(svc.get());
2467 
2468   std::unique_ptr<MockProducer> producer = CreateMockProducer();
2469   producer->Connect(svc.get(), "mock_producer");
2470   producer->RegisterDataSource("data_source");
2471 
2472   TraceConfig trace_config;
2473   trace_config.add_buffers()->set_size_kb(128);
2474   auto* ds_config = trace_config.add_data_sources()->mutable_config();
2475   ds_config->set_name("data_source");
2476   trace_config.set_duration_ms(1);
2477 
2478   consumer->EnableTracing(trace_config);
2479   producer->WaitForTracingSetup();
2480   producer->WaitForDataSourceSetup("data_source");
2481   producer->WaitForDataSourceStart("data_source");
2482 
2483   std::unique_ptr<TraceWriter> writer =
2484       producer->CreateTraceWriter("data_source");
2485   {
2486     auto tp = writer->NewTracePacket();
2487     tp->set_for_testing()->set_str("payload");
2488   }
2489 
2490   FlushFlags expected_flags(FlushFlags::Initiator::kTraced,
2491                             FlushFlags::Reason::kTraceStop);
2492   producer->ExpectFlush(writer.get(), /*reply=*/true, expected_flags);
2493 
2494   producer->WaitForDataSourceStop("data_source");
2495   consumer->WaitForTracingDisabled();
2496 
2497   EXPECT_THAT(consumer->ReadBuffers(),
2498               Contains(Property(
2499                   &protos::gen::TracePacket::for_testing,
2500                   Property(&protos::gen::TestEvent::str, Eq("payload")))));
2501 }
2502 
2503 // Tests the monotonic semantic of flush request IDs, i.e., once a producer
2504 // acks flush request N, all flush requests <= N are considered successful and
2505 // acked to the consumer.
TEST_F(TracingServiceImplTest,BatchFlushes)2506 TEST_F(TracingServiceImplTest, BatchFlushes) {
2507   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2508   consumer->Connect(svc.get());
2509 
2510   std::unique_ptr<MockProducer> producer = CreateMockProducer();
2511   producer->Connect(svc.get(), "mock_producer");
2512   producer->RegisterDataSource("data_source");
2513 
2514   TraceConfig trace_config;
2515   trace_config.add_buffers()->set_size_kb(128);
2516   auto* ds_config = trace_config.add_data_sources()->mutable_config();
2517   ds_config->set_name("data_source");
2518 
2519   consumer->EnableTracing(trace_config);
2520   producer->WaitForTracingSetup();
2521   producer->WaitForDataSourceSetup("data_source");
2522   producer->WaitForDataSourceStart("data_source");
2523 
2524   std::unique_ptr<TraceWriter> writer =
2525       producer->CreateTraceWriter("data_source");
2526   {
2527     auto tp = writer->NewTracePacket();
2528     tp->set_for_testing()->set_str("payload");
2529   }
2530 
2531   auto flush_req_1 = consumer->Flush();
2532   auto flush_req_2 = consumer->Flush();
2533   auto flush_req_3 = consumer->Flush();
2534 
2535   // We'll deliberately let the 4th flush request timeout. Use a lower timeout
2536   // to keep test time short.
2537   auto flush_req_4 = consumer->Flush(/*timeout_ms=*/10);
2538   ASSERT_EQ(4u, GetNumPendingFlushes());
2539 
2540   // Make the producer reply only to the 3rd flush request.
2541   InSequence seq;
2542   producer->ExpectFlush(nullptr, /*reply=*/false);  // Do NOT reply to flush 1.
2543   producer->ExpectFlush(nullptr, /*reply=*/false);  // Do NOT reply to flush 2.
2544   producer->ExpectFlush(writer.get());              // Reply only to flush 3.
2545   producer->ExpectFlush(nullptr, /*reply=*/false);  // Do NOT reply to flush 4.
2546 
2547   // Even if the producer explicily replied only to flush ID == 3, all the
2548   // previous flushed < 3 should be implicitly acked.
2549   ASSERT_TRUE(flush_req_1.WaitForReply());
2550   ASSERT_TRUE(flush_req_2.WaitForReply());
2551   ASSERT_TRUE(flush_req_3.WaitForReply());
2552 
2553   // At this point flush id == 4 should still be pending and should fail because
2554   // of reaching its timeout.
2555   ASSERT_FALSE(flush_req_4.WaitForReply());
2556 
2557   consumer->DisableTracing();
2558   producer->WaitForDataSourceStop("data_source");
2559   consumer->WaitForTracingDisabled();
2560   EXPECT_THAT(consumer->ReadBuffers(),
2561               Contains(Property(
2562                   &protos::gen::TracePacket::for_testing,
2563                   Property(&protos::gen::TestEvent::str, Eq("payload")))));
2564 }
2565 
TEST_F(TracingServiceImplTest,PeriodicFlush)2566 TEST_F(TracingServiceImplTest, PeriodicFlush) {
2567   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2568   consumer->Connect(svc.get());
2569 
2570   std::unique_ptr<MockProducer> producer = CreateMockProducer();
2571   producer->Connect(svc.get(), "mock_producer");
2572   producer->RegisterDataSource("data_source");
2573 
2574   TraceConfig trace_config;
2575   trace_config.add_buffers()->set_size_kb(128);
2576   trace_config.set_flush_period_ms(1);
2577   auto* ds_config = trace_config.add_data_sources()->mutable_config();
2578   ds_config->set_name("data_source");
2579 
2580   consumer->EnableTracing(trace_config);
2581   producer->WaitForTracingSetup();
2582   producer->WaitForDataSourceSetup("data_source");
2583   producer->WaitForDataSourceStart("data_source");
2584 
2585   std::unique_ptr<TraceWriter> writer =
2586       producer->CreateTraceWriter("data_source");
2587 
2588   const int kNumFlushes = 3;
2589   auto checkpoint = task_runner.CreateCheckpoint("all_flushes_done");
2590   int flushes_seen = 0;
2591   FlushFlags flush_flags(FlushFlags::Initiator::kTraced,
2592                          FlushFlags::Reason::kPeriodic);
2593   EXPECT_CALL(*producer, Flush(_, _, _, flush_flags))
2594       .WillRepeatedly(Invoke([&producer, &writer, &flushes_seen, checkpoint](
2595                                  FlushRequestID flush_req_id,
2596                                  const DataSourceInstanceID*, size_t,
2597                                  FlushFlags) {
2598         {
2599           auto tp = writer->NewTracePacket();
2600           char payload[32];
2601           base::SprintfTrunc(payload, sizeof(payload), "f_%d", flushes_seen);
2602           tp->set_for_testing()->set_str(payload);
2603         }
2604         writer->Flush();
2605         producer->endpoint()->NotifyFlushComplete(flush_req_id);
2606         if (++flushes_seen == kNumFlushes)
2607           checkpoint();
2608       }));
2609   task_runner.RunUntilCheckpoint("all_flushes_done");
2610 
2611   consumer->DisableTracing();
2612   producer->WaitForDataSourceStop("data_source");
2613   consumer->WaitForTracingDisabled();
2614   auto trace_packets = consumer->ReadBuffers();
2615   for (int i = 0; i < kNumFlushes; i++) {
2616     EXPECT_THAT(trace_packets,
2617                 Contains(Property(&protos::gen::TracePacket::for_testing,
2618                                   Property(&protos::gen::TestEvent::str,
2619                                            Eq("f_" + std::to_string(i))))));
2620   }
2621 }
2622 
TEST_F(TracingServiceImplTest,NoFlush)2623 TEST_F(TracingServiceImplTest, NoFlush) {
2624   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2625   consumer->Connect(svc.get());
2626 
2627   std::unique_ptr<MockProducer> producer_1 = CreateMockProducer();
2628   producer_1->Connect(svc.get(), "mock_producer_1");
2629   producer_1->RegisterDataSource("ds_flush");
2630   producer_1->RegisterDataSource("ds_noflush", false, false, false, true);
2631 
2632   TraceConfig trace_config;
2633   trace_config.add_buffers()->set_size_kb(128);
2634   trace_config.add_data_sources()->mutable_config()->set_name("ds_flush");
2635   trace_config.add_data_sources()->mutable_config()->set_name("ds_noflush");
2636 
2637   consumer->EnableTracing(trace_config);
2638   producer_1->WaitForTracingSetup();
2639   producer_1->WaitForDataSourceSetup("ds_flush");
2640   producer_1->WaitForDataSourceSetup("ds_noflush");
2641   producer_1->WaitForDataSourceStart("ds_flush");
2642   producer_1->WaitForDataSourceStart("ds_noflush");
2643 
2644   std::unique_ptr<MockProducer> producer_2 = CreateMockProducer();
2645   producer_2->Connect(svc.get(), "mock_producer_2");
2646   producer_2->RegisterDataSource("ds_noflush", false, false, false,
2647                                  /*no_flush=*/true);
2648   producer_2->WaitForTracingSetup();
2649   producer_2->WaitForDataSourceSetup("ds_noflush");
2650   producer_2->WaitForDataSourceStart("ds_noflush");
2651 
2652   auto wr_p1_ds1 = producer_1->CreateTraceWriter("ds_flush");
2653   producer_1->ExpectFlush(wr_p1_ds1.get());
2654 
2655   EXPECT_CALL(*producer_2, Flush(_, _, _, _)).Times(0);
2656 
2657   auto flush_request = consumer->Flush();
2658   ASSERT_TRUE(flush_request.WaitForReply());
2659 
2660   consumer->DisableTracing();
2661 }
2662 
TEST_F(TracingServiceImplTest,PeriodicClearIncrementalState)2663 TEST_F(TracingServiceImplTest, PeriodicClearIncrementalState) {
2664   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2665   consumer->Connect(svc.get());
2666   std::unique_ptr<MockProducer> producer = CreateMockProducer();
2667   producer->Connect(svc.get(), "mock_producer");
2668 
2669   // Incremental data source that expects to receive the clear.
2670   producer->RegisterDataSource("ds_incremental1", false, false,
2671                                /*handles_incremental_state_clear=*/true);
2672 
2673   // Incremental data source that expects to receive the clear.
2674   producer->RegisterDataSource("ds_incremental2", false, false,
2675                                /*handles_incremental_state_clear=*/true);
2676 
2677   // Data source that does *not* advertise itself as supporting incremental
2678   // state clears.
2679   producer->RegisterDataSource("ds_selfcontained", false, false,
2680                                /*handles_incremental_state_clear=*/false);
2681 
2682   // Incremental data source that is registered, but won't be active within the
2683   // test's tracing session.
2684   producer->RegisterDataSource("ds_inactive", false, false,
2685                                /*handles_incremental_state_clear=*/true);
2686 
2687   TraceConfig trace_config;
2688   trace_config.add_buffers()->set_size_kb(128);
2689   trace_config.mutable_incremental_state_config()->set_clear_period_ms(1);
2690   trace_config.add_data_sources()->mutable_config()->set_name(
2691       "ds_selfcontained");
2692   trace_config.add_data_sources()->mutable_config()->set_name(
2693       "ds_incremental1");
2694   trace_config.add_data_sources()->mutable_config()->set_name(
2695       "ds_incremental2");
2696 
2697   // note: the mocking is very brittle, and has to assume a specific order of
2698   // the data sources' setup/start.
2699   consumer->EnableTracing(trace_config);
2700   producer->WaitForTracingSetup();
2701   producer->WaitForDataSourceSetup("ds_selfcontained");
2702   producer->WaitForDataSourceSetup("ds_incremental1");
2703   producer->WaitForDataSourceSetup("ds_incremental2");
2704   producer->WaitForDataSourceStart("ds_selfcontained");
2705   producer->WaitForDataSourceStart("ds_incremental1");
2706   producer->WaitForDataSourceStart("ds_incremental2");
2707 
2708   DataSourceInstanceID ds_incremental1 =
2709       producer->GetDataSourceInstanceId("ds_incremental1");
2710   DataSourceInstanceID ds_incremental2 =
2711       producer->GetDataSourceInstanceId("ds_incremental2");
2712 
2713   const size_t kNumClears = 3;
2714   std::function<void()> checkpoint =
2715       task_runner.CreateCheckpoint("clears_received");
2716   std::vector<std::vector<DataSourceInstanceID>> clears_seen;
2717   EXPECT_CALL(*producer, ClearIncrementalState(_, _))
2718       .WillRepeatedly(Invoke([&clears_seen, &checkpoint](
2719                                  const DataSourceInstanceID* data_source_ids,
2720                                  size_t num_data_sources) {
2721         std::vector<DataSourceInstanceID> ds_ids;
2722         for (size_t i = 0; i < num_data_sources; i++) {
2723           ds_ids.push_back(*data_source_ids++);
2724         }
2725         clears_seen.push_back(ds_ids);
2726         if (clears_seen.size() >= kNumClears)
2727           checkpoint();
2728       }));
2729   task_runner.RunUntilCheckpoint("clears_received");
2730 
2731   consumer->DisableTracing();
2732 
2733   // Assert that the clears were only for the active incremental data sources.
2734   ASSERT_EQ(clears_seen.size(), kNumClears);
2735   for (const std::vector<DataSourceInstanceID>& ds_ids : clears_seen) {
2736     ASSERT_THAT(ds_ids, ElementsAreArray({ds_incremental1, ds_incremental2}));
2737   }
2738 }
2739 
2740 // Creates a tracing session where some of the data sources set the
2741 // |will_notify_on_stop| flag and checks that the OnTracingDisabled notification
2742 // to the consumer is delayed until the acks are received.
TEST_F(TracingServiceImplTest,OnTracingDisabledWaitsForDataSourceStopAcks)2743 TEST_F(TracingServiceImplTest, OnTracingDisabledWaitsForDataSourceStopAcks) {
2744   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2745   consumer->Connect(svc.get());
2746 
2747   std::unique_ptr<MockProducer> producer = CreateMockProducer();
2748   producer->Connect(svc.get(), "mock_producer");
2749   producer->RegisterDataSource("ds_will_ack_1", /*ack_stop=*/true,
2750                                /*ack_start=*/true);
2751   producer->RegisterDataSource("ds_wont_ack");
2752   producer->RegisterDataSource("ds_will_ack_2", /*ack_stop=*/true,
2753                                /*ack_start=*/false);
2754 
2755   TraceConfig trace_config;
2756   trace_config.add_buffers()->set_size_kb(128);
2757   trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_1");
2758   trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
2759   trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack_2");
2760   trace_config.set_duration_ms(1);
2761   trace_config.set_deferred_start(true);
2762 
2763   consumer->EnableTracing(trace_config);
2764 
2765   EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
2766             DataSourceInstanceState::CONFIGURED);
2767   EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
2768             DataSourceInstanceState::CONFIGURED);
2769   EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
2770             DataSourceInstanceState::CONFIGURED);
2771 
2772   producer->WaitForTracingSetup();
2773 
2774   producer->WaitForDataSourceSetup("ds_will_ack_1");
2775   producer->WaitForDataSourceSetup("ds_wont_ack");
2776   producer->WaitForDataSourceSetup("ds_will_ack_2");
2777 
2778   DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_will_ack_1");
2779   DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds_will_ack_2");
2780 
2781   consumer->StartTracing();
2782 
2783   EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
2784             DataSourceInstanceState::STARTING);
2785   EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
2786             DataSourceInstanceState::STARTED);
2787   EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
2788             DataSourceInstanceState::STARTED);
2789 
2790   producer->WaitForDataSourceStart("ds_will_ack_1");
2791   producer->WaitForDataSourceStart("ds_wont_ack");
2792   producer->WaitForDataSourceStart("ds_will_ack_2");
2793 
2794   producer->endpoint()->NotifyDataSourceStarted(id1);
2795 
2796   EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
2797             DataSourceInstanceState::STARTED);
2798 
2799   std::unique_ptr<TraceWriter> writer =
2800       producer->CreateTraceWriter("ds_wont_ack");
2801   producer->ExpectFlush(writer.get());
2802 
2803   producer->WaitForDataSourceStop("ds_will_ack_1");
2804   producer->WaitForDataSourceStop("ds_wont_ack");
2805   producer->WaitForDataSourceStop("ds_will_ack_2");
2806 
2807   EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
2808             DataSourceInstanceState::STOPPING);
2809   EXPECT_EQ(GetDataSourceInstanceState("ds_wont_ack"),
2810             DataSourceInstanceState::STOPPED);
2811   EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
2812             DataSourceInstanceState::STOPPING);
2813 
2814   producer->endpoint()->NotifyDataSourceStopped(id1);
2815   producer->endpoint()->NotifyDataSourceStopped(id2);
2816 
2817   EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_1"),
2818             DataSourceInstanceState::STOPPED);
2819   EXPECT_EQ(GetDataSourceInstanceState("ds_will_ack_2"),
2820             DataSourceInstanceState::STOPPED);
2821 
2822   // Wait for at most half of the service timeout, so that this test fails if
2823   // the service falls back on calling the OnTracingDisabled() because some of
2824   // the expected acks weren't received.
2825   consumer->WaitForTracingDisabled(
2826       TracingServiceImpl::kDataSourceStopTimeoutMs / 2);
2827 }
2828 
2829 // Creates a tracing session where a second data source
2830 // is added while the service is waiting for DisableTracing
2831 // acks; the service should not enable the new datasource
2832 // and should not hit any asserts when the consumer is
2833 // subsequently destroyed.
TEST_F(TracingServiceImplTest,OnDataSourceAddedWhilePendingDisableAcks)2834 TEST_F(TracingServiceImplTest, OnDataSourceAddedWhilePendingDisableAcks) {
2835   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2836   consumer->Connect(svc.get());
2837 
2838   std::unique_ptr<MockProducer> producer = CreateMockProducer();
2839   producer->Connect(svc.get(), "mock_producer");
2840   producer->RegisterDataSource("ds_will_ack", /*ack_stop=*/true);
2841 
2842   TraceConfig trace_config;
2843   trace_config.add_buffers()->set_size_kb(128);
2844   trace_config.add_data_sources()->mutable_config()->set_name("ds_will_ack");
2845   trace_config.add_data_sources()->mutable_config()->set_name("ds_wont_ack");
2846 
2847   consumer->EnableTracing(trace_config);
2848   producer->WaitForTracingSetup();
2849 
2850   consumer->DisableTracing();
2851 
2852   producer->RegisterDataSource("ds_wont_ack");
2853 
2854   consumer.reset();
2855 }
2856 
2857 // Similar to OnTracingDisabledWaitsForDataSourceStopAcks, but deliberately
2858 // skips the ack and checks that the service invokes the OnTracingDisabled()
2859 // after the timeout.
TEST_F(TracingServiceImplTest,OnTracingDisabledCalledAnywaysInCaseOfTimeout)2860 TEST_F(TracingServiceImplTest, OnTracingDisabledCalledAnywaysInCaseOfTimeout) {
2861   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2862   consumer->Connect(svc.get());
2863 
2864   std::unique_ptr<MockProducer> producer = CreateMockProducer();
2865   producer->Connect(svc.get(), "mock_producer");
2866   producer->RegisterDataSource("data_source", /*ack_stop=*/true);
2867 
2868   TraceConfig trace_config;
2869   trace_config.add_buffers()->set_size_kb(128);
2870   trace_config.add_data_sources()->mutable_config()->set_name("data_source");
2871   trace_config.set_duration_ms(1);
2872   trace_config.set_data_source_stop_timeout_ms(1);
2873 
2874   consumer->EnableTracing(trace_config);
2875   producer->WaitForTracingSetup();
2876   producer->WaitForDataSourceSetup("data_source");
2877   producer->WaitForDataSourceStart("data_source");
2878 
2879   std::unique_ptr<TraceWriter> writer =
2880       producer->CreateTraceWriter("data_source");
2881   producer->ExpectFlush(writer.get());
2882 
2883   producer->WaitForDataSourceStop("data_source");
2884   consumer->WaitForTracingDisabled();
2885 }
2886 
2887 // Tests the session_id logic. Two data sources in the same tracing session
2888 // should see the same session id.
TEST_F(TracingServiceImplTest,SessionId)2889 TEST_F(TracingServiceImplTest, SessionId) {
2890   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2891   consumer->Connect(svc.get());
2892 
2893   std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
2894   producer1->Connect(svc.get(), "mock_producer1");
2895   producer1->RegisterDataSource("ds_1A");
2896   producer1->RegisterDataSource("ds_1B");
2897 
2898   std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
2899   producer2->Connect(svc.get(), "mock_producer2");
2900   producer2->RegisterDataSource("ds_2A");
2901 
2902   InSequence seq;
2903   TracingSessionID last_session_id = 0;
2904   for (int i = 0; i < 3; i++) {
2905     TraceConfig trace_config;
2906     trace_config.add_buffers()->set_size_kb(128);
2907     trace_config.add_data_sources()->mutable_config()->set_name("ds_1A");
2908     trace_config.add_data_sources()->mutable_config()->set_name("ds_1B");
2909     trace_config.add_data_sources()->mutable_config()->set_name("ds_2A");
2910     trace_config.set_duration_ms(1);
2911 
2912     consumer->EnableTracing(trace_config);
2913 
2914     if (i == 0)
2915       producer1->WaitForTracingSetup();
2916 
2917     producer1->WaitForDataSourceSetup("ds_1A");
2918     producer1->WaitForDataSourceSetup("ds_1B");
2919     if (i == 0)
2920       producer2->WaitForTracingSetup();
2921     producer2->WaitForDataSourceSetup("ds_2A");
2922 
2923     producer1->WaitForDataSourceStart("ds_1A");
2924     producer1->WaitForDataSourceStart("ds_1B");
2925     producer2->WaitForDataSourceStart("ds_2A");
2926 
2927     auto* ds1 = producer1->GetDataSourceInstance("ds_1A");
2928     auto* ds2 = producer1->GetDataSourceInstance("ds_1B");
2929     auto* ds3 = producer2->GetDataSourceInstance("ds_2A");
2930     ASSERT_EQ(ds1->session_id, ds2->session_id);
2931     ASSERT_EQ(ds1->session_id, ds3->session_id);
2932     ASSERT_NE(ds1->session_id, last_session_id);
2933     last_session_id = ds1->session_id;
2934 
2935     auto writer1 = producer1->CreateTraceWriter("ds_1A");
2936     producer1->ExpectFlush(writer1.get());
2937 
2938     auto writer2 = producer2->CreateTraceWriter("ds_2A");
2939     producer2->ExpectFlush(writer2.get());
2940 
2941     producer1->WaitForDataSourceStop("ds_1A");
2942     producer1->WaitForDataSourceStop("ds_1B");
2943     producer2->WaitForDataSourceStop("ds_2A");
2944     consumer->WaitForTracingDisabled();
2945     consumer->FreeBuffers();
2946   }
2947 }
2948 
2949 // Writes a long trace and then tests that the trace parsed in partitions
2950 // derived by the synchronization markers is identical to the whole trace parsed
2951 // in one go.
TEST_F(TracingServiceImplTest,ResynchronizeTraceStreamUsingSyncMarker)2952 TEST_F(TracingServiceImplTest, ResynchronizeTraceStreamUsingSyncMarker) {
2953   // Setup tracing.
2954   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
2955   consumer->Connect(svc.get());
2956   std::unique_ptr<MockProducer> producer = CreateMockProducer();
2957   producer->Connect(svc.get(), "mock_producer");
2958   producer->RegisterDataSource("data_source");
2959   TraceConfig trace_config;
2960   trace_config.add_buffers()->set_size_kb(4096);
2961   auto* ds_config = trace_config.add_data_sources()->mutable_config();
2962   ds_config->set_name("data_source");
2963   trace_config.set_write_into_file(true);
2964   trace_config.set_file_write_period_ms(1);
2965   base::TempFile tmp_file = base::TempFile::Create();
2966   consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
2967   producer->WaitForTracingSetup();
2968   producer->WaitForDataSourceSetup("data_source");
2969   producer->WaitForDataSourceStart("data_source");
2970 
2971   // Write some variable length payload, waiting for sync markers every now
2972   // and then.
2973   const int kNumMarkers = 5;
2974   auto writer = producer->CreateTraceWriter("data_source");
2975   for (int i = 1; i <= 100; i++) {
2976     std::string payload(static_cast<size_t>(i),
2977                         'A' + static_cast<char>(i % 25));
2978     writer->NewTracePacket()->set_for_testing()->set_str(payload.c_str());
2979     if (i % (100 / kNumMarkers) == 0) {
2980       writer->Flush();
2981       WaitForNextSyncMarker();
2982     }
2983   }
2984   writer->Flush();
2985   writer.reset();
2986   consumer->DisableTracing();
2987   producer->WaitForDataSourceStop("data_source");
2988   consumer->WaitForTracingDisabled();
2989 
2990   std::string trace_raw;
2991   ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
2992 
2993   const auto kMarkerSize = sizeof(TracingServiceImpl::kSyncMarker);
2994   const std::string kSyncMarkerStr(
2995       reinterpret_cast<const char*>(TracingServiceImpl::kSyncMarker),
2996       kMarkerSize);
2997 
2998   // Read back the trace in partitions derived from the marker.
2999   // The trace should look like this:
3000   // [uid, marker] [event] [event] [uid, marker] [event] [event]
3001   size_t num_markers = 0;
3002   size_t start = 0;
3003   size_t end = 0;
3004   std::string merged_trace_raw;
3005   for (size_t pos = 0; pos != std::string::npos; start = end) {
3006     pos = trace_raw.find(kSyncMarkerStr, pos + 1);
3007     num_markers++;
3008     end = (pos == std::string::npos) ? trace_raw.size() : pos + kMarkerSize;
3009     size_t size = end - start;
3010     ASSERT_GT(size, 0u);
3011     std::string trace_partition_raw = trace_raw.substr(start, size);
3012     protos::gen::Trace trace_partition;
3013     ASSERT_TRUE(trace_partition.ParseFromString(trace_partition_raw));
3014     merged_trace_raw += trace_partition_raw;
3015   }
3016   EXPECT_GE(num_markers, static_cast<size_t>(kNumMarkers));
3017 
3018   protos::gen::Trace whole_trace;
3019   ASSERT_TRUE(whole_trace.ParseFromString(trace_raw));
3020 
3021   protos::gen::Trace merged_trace;
3022   merged_trace.ParseFromString(merged_trace_raw);
3023 
3024   ASSERT_EQ(whole_trace.packet_size(), merged_trace.packet_size());
3025   EXPECT_EQ(whole_trace.SerializeAsString(), merged_trace.SerializeAsString());
3026 }
3027 
3028 // Creates a tracing session with |deferred_start| and checks that data sources
3029 // are started only after calling StartTracing().
TEST_F(TracingServiceImplTest,DeferredStart)3030 TEST_F(TracingServiceImplTest, DeferredStart) {
3031   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
3032   consumer->Connect(svc.get());
3033 
3034   std::unique_ptr<MockProducer> producer = CreateMockProducer();
3035   producer->Connect(svc.get(), "mock_producer");
3036 
3037   // Create two data sources but enable only one of them.
3038   producer->RegisterDataSource("ds_1");
3039   producer->RegisterDataSource("ds_2");
3040 
3041   TraceConfig trace_config;
3042   trace_config.add_buffers()->set_size_kb(128);
3043   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
3044   trace_config.set_deferred_start(true);
3045   trace_config.set_duration_ms(1);
3046 
3047   consumer->EnableTracing(trace_config);
3048   producer->WaitForTracingSetup();
3049 
3050   producer->WaitForDataSourceSetup("ds_1");
3051 
3052   // Make sure we don't get unexpected DataSourceStart() notifications yet.
3053   task_runner.RunUntilIdle();
3054 
3055   consumer->StartTracing();
3056 
3057   producer->WaitForDataSourceStart("ds_1");
3058 
3059   auto writer = producer->CreateTraceWriter("ds_1");
3060   producer->ExpectFlush(writer.get());
3061 
3062   producer->WaitForDataSourceStop("ds_1");
3063   consumer->WaitForTracingDisabled();
3064 }
3065 
TEST_F(TracingServiceImplTest,ProducerUIDsAndPacketSequenceIDs)3066 TEST_F(TracingServiceImplTest, ProducerUIDsAndPacketSequenceIDs) {
3067   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
3068   consumer->Connect(svc.get());
3069 
3070   std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
3071   producer1->Connect(svc.get(), "mock_producer1", 123u /* uid */,
3072                      1001 /* pid */);
3073   producer1->RegisterDataSource("data_source");
3074 
3075   std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
3076   producer2->Connect(svc.get(), "mock_producer2", 456u /* uid */,
3077                      2002 /* pid */);
3078   producer2->RegisterDataSource("data_source");
3079 
3080   TraceConfig trace_config;
3081   trace_config.add_buffers()->set_size_kb(128);
3082   auto* ds_config = trace_config.add_data_sources()->mutable_config();
3083   ds_config->set_name("data_source");
3084 
3085   consumer->EnableTracing(trace_config);
3086   producer1->WaitForTracingSetup();
3087   producer1->WaitForDataSourceSetup("data_source");
3088   producer2->WaitForTracingSetup();
3089   producer2->WaitForDataSourceSetup("data_source");
3090   producer1->WaitForDataSourceStart("data_source");
3091   producer2->WaitForDataSourceStart("data_source");
3092 
3093   std::unique_ptr<TraceWriter> writer1a =
3094       producer1->CreateTraceWriter("data_source");
3095   std::unique_ptr<TraceWriter> writer1b =
3096       producer1->CreateTraceWriter("data_source");
3097   std::unique_ptr<TraceWriter> writer2a =
3098       producer2->CreateTraceWriter("data_source");
3099   {
3100     auto tp = writer1a->NewTracePacket();
3101     tp->set_for_testing()->set_str("payload1a1");
3102     tp = writer1b->NewTracePacket();
3103     tp->set_for_testing()->set_str("payload1b1");
3104     tp = writer1a->NewTracePacket();
3105     tp->set_for_testing()->set_str("payload1a2");
3106     tp = writer2a->NewTracePacket();
3107     tp->set_for_testing()->set_str("payload2a1");
3108     tp = writer1b->NewTracePacket();
3109     tp->set_for_testing()->set_str("payload1b2");
3110   }
3111 
3112   auto flush_request = consumer->Flush();
3113   producer1->ExpectFlush({writer1a.get(), writer1b.get()});
3114   producer2->ExpectFlush(writer2a.get());
3115   ASSERT_TRUE(flush_request.WaitForReply());
3116 
3117   consumer->DisableTracing();
3118   producer1->WaitForDataSourceStop("data_source");
3119   producer2->WaitForDataSourceStop("data_source");
3120   consumer->WaitForTracingDisabled();
3121   auto packets = consumer->ReadBuffers();
3122   EXPECT_THAT(
3123       packets,
3124       Contains(AllOf(
3125           Property(&protos::gen::TracePacket::for_testing,
3126                    Property(&protos::gen::TestEvent::str, Eq("payload1a1"))),
3127           Property(&protos::gen::TracePacket::trusted_uid, Eq(123)),
3128           Property(&protos::gen::TracePacket::trusted_pid, Eq(1001)),
3129           Property(&protos::gen::TracePacket::trusted_packet_sequence_id,
3130                    Eq(2u)))));
3131   EXPECT_THAT(
3132       packets,
3133       Contains(AllOf(
3134           Property(&protos::gen::TracePacket::for_testing,
3135                    Property(&protos::gen::TestEvent::str, Eq("payload1a2"))),
3136           Property(&protos::gen::TracePacket::trusted_uid, Eq(123)),
3137           Property(&protos::gen::TracePacket::trusted_pid, Eq(1001)),
3138           Property(&protos::gen::TracePacket::trusted_packet_sequence_id,
3139                    Eq(2u)))));
3140   EXPECT_THAT(
3141       packets,
3142       Contains(AllOf(
3143           Property(&protos::gen::TracePacket::for_testing,
3144                    Property(&protos::gen::TestEvent::str, Eq("payload1b1"))),
3145           Property(&protos::gen::TracePacket::trusted_uid, Eq(123)),
3146           Property(&protos::gen::TracePacket::trusted_pid, Eq(1001)),
3147           Property(&protos::gen::TracePacket::trusted_packet_sequence_id,
3148                    Eq(3u)))));
3149   EXPECT_THAT(
3150       packets,
3151       Contains(AllOf(
3152           Property(&protos::gen::TracePacket::for_testing,
3153                    Property(&protos::gen::TestEvent::str, Eq("payload1b2"))),
3154           Property(&protos::gen::TracePacket::trusted_uid, Eq(123)),
3155           Property(&protos::gen::TracePacket::trusted_pid, Eq(1001)),
3156           Property(&protos::gen::TracePacket::trusted_packet_sequence_id,
3157                    Eq(3u)))));
3158   EXPECT_THAT(
3159       packets,
3160       Contains(AllOf(
3161           Property(&protos::gen::TracePacket::for_testing,
3162                    Property(&protos::gen::TestEvent::str, Eq("payload2a1"))),
3163           Property(&protos::gen::TracePacket::trusted_uid, Eq(456)),
3164           Property(&protos::gen::TracePacket::trusted_pid, Eq(2002)),
3165           Property(&protos::gen::TracePacket::trusted_packet_sequence_id,
3166                    Eq(4u)))));
3167 }
3168 
TEST_F(TracingServiceImplTest,AllowedBuffers)3169 TEST_F(TracingServiceImplTest, AllowedBuffers) {
3170   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
3171   consumer->Connect(svc.get());
3172 
3173   std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
3174   producer1->Connect(svc.get(), "mock_producer1");
3175   ProducerID producer1_id = *last_producer_id();
3176   producer1->RegisterDataSource("data_source1");
3177   std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
3178   producer2->Connect(svc.get(), "mock_producer2");
3179   ProducerID producer2_id = *last_producer_id();
3180   producer2->RegisterDataSource("data_source2.1");
3181   producer2->RegisterDataSource("data_source2.2");
3182   producer2->RegisterDataSource("data_source2.3");
3183 
3184   EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
3185   EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
3186 
3187   TraceConfig trace_config;
3188   trace_config.add_buffers()->set_size_kb(128);
3189   trace_config.add_buffers()->set_size_kb(128);
3190   trace_config.add_buffers()->set_size_kb(128);
3191   auto* ds_config1 = trace_config.add_data_sources()->mutable_config();
3192   ds_config1->set_name("data_source1");
3193   ds_config1->set_target_buffer(0);
3194   auto* ds_config21 = trace_config.add_data_sources()->mutable_config();
3195   ds_config21->set_name("data_source2.1");
3196   ds_config21->set_target_buffer(1);
3197   auto* ds_config22 = trace_config.add_data_sources()->mutable_config();
3198   ds_config22->set_name("data_source2.2");
3199   ds_config22->set_target_buffer(2);
3200   auto* ds_config23 = trace_config.add_data_sources()->mutable_config();
3201   ds_config23->set_name("data_source2.3");
3202   ds_config23->set_target_buffer(2);  // same buffer as data_source2.2.
3203   consumer->EnableTracing(trace_config);
3204 
3205   ASSERT_EQ(3u, tracing_session()->num_buffers());
3206   std::set<BufferID> expected_buffers_producer1 = {
3207       tracing_session()->buffers_index[0]};
3208   std::set<BufferID> expected_buffers_producer2 = {
3209       tracing_session()->buffers_index[1], tracing_session()->buffers_index[2]};
3210   EXPECT_EQ(expected_buffers_producer1, GetAllowedTargetBuffers(producer1_id));
3211   EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
3212 
3213   producer1->WaitForTracingSetup();
3214   producer1->WaitForDataSourceSetup("data_source1");
3215 
3216   producer2->WaitForTracingSetup();
3217   producer2->WaitForDataSourceSetup("data_source2.1");
3218   producer2->WaitForDataSourceSetup("data_source2.2");
3219   producer2->WaitForDataSourceSetup("data_source2.3");
3220 
3221   producer1->WaitForDataSourceStart("data_source1");
3222   producer2->WaitForDataSourceStart("data_source2.1");
3223   producer2->WaitForDataSourceStart("data_source2.2");
3224   producer2->WaitForDataSourceStart("data_source2.3");
3225 
3226   producer2->UnregisterDataSource("data_source2.3");
3227   producer2->WaitForDataSourceStop("data_source2.3");
3228 
3229   // Should still be allowed to write to buffers 1 (data_source2.1) and 2
3230   // (data_source2.2).
3231   EXPECT_EQ(expected_buffers_producer2, GetAllowedTargetBuffers(producer2_id));
3232 
3233   // Calling StartTracing() should be a noop (% a DLOG statement) because the
3234   // trace config didn't have the |deferred_start| flag set.
3235   consumer->StartTracing();
3236 
3237   consumer->DisableTracing();
3238   producer1->WaitForDataSourceStop("data_source1");
3239   producer2->WaitForDataSourceStop("data_source2.1");
3240   producer2->WaitForDataSourceStop("data_source2.2");
3241   consumer->WaitForTracingDisabled();
3242 
3243   consumer->FreeBuffers();
3244   EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer1_id));
3245   EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer2_id));
3246 }
3247 
3248 #if !PERFETTO_DCHECK_IS_ON()
TEST_F(TracingServiceImplTest,CommitToForbiddenBufferIsDiscarded)3249 TEST_F(TracingServiceImplTest, CommitToForbiddenBufferIsDiscarded) {
3250   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
3251   consumer->Connect(svc.get());
3252 
3253   std::unique_ptr<MockProducer> producer = CreateMockProducer();
3254   producer->Connect(svc.get(), "mock_producer");
3255   ProducerID producer_id = *last_producer_id();
3256   producer->RegisterDataSource("data_source");
3257 
3258   EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
3259 
3260   TraceConfig trace_config;
3261   trace_config.add_buffers()->set_size_kb(128);
3262   trace_config.add_buffers()->set_size_kb(128);
3263   auto* ds_config = trace_config.add_data_sources()->mutable_config();
3264   ds_config->set_name("data_source");
3265   ds_config->set_target_buffer(0);
3266   consumer->EnableTracing(trace_config);
3267 
3268   ASSERT_EQ(2u, tracing_session()->num_buffers());
3269   std::set<BufferID> expected_buffers = {tracing_session()->buffers_index[0]};
3270   EXPECT_EQ(expected_buffers, GetAllowedTargetBuffers(producer_id));
3271 
3272   producer->WaitForTracingSetup();
3273   producer->WaitForDataSourceSetup("data_source");
3274   producer->WaitForDataSourceStart("data_source");
3275 
3276   // Calling StartTracing() should be a noop (% a DLOG statement) because the
3277   // trace config didn't have the |deferred_start| flag set.
3278   consumer->StartTracing();
3279 
3280   // Try to write to the correct buffer.
3281   std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
3282       tracing_session()->buffers_index[0]);
3283   {
3284     auto tp = writer->NewTracePacket();
3285     tp->set_for_testing()->set_str("good_payload");
3286   }
3287 
3288   auto flush_request = consumer->Flush();
3289   producer->ExpectFlush(writer.get());
3290   ASSERT_TRUE(flush_request.WaitForReply());
3291 
3292   // Try to write to the wrong buffer.
3293   writer = producer->endpoint()->CreateTraceWriter(
3294       tracing_session()->buffers_index[1]);
3295   {
3296     auto tp = writer->NewTracePacket();
3297     tp->set_for_testing()->set_str("bad_payload");
3298   }
3299 
3300   flush_request = consumer->Flush();
3301   producer->ExpectFlush(writer.get());
3302   ASSERT_TRUE(flush_request.WaitForReply());
3303 
3304   consumer->DisableTracing();
3305   producer->WaitForDataSourceStop("data_source");
3306   consumer->WaitForTracingDisabled();
3307 
3308   auto packets = consumer->ReadBuffers();
3309   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
3310                                          Property(&protos::gen::TestEvent::str,
3311                                                   Eq("good_payload")))));
3312   EXPECT_THAT(packets,
3313               Not(Contains(Property(
3314                   &protos::gen::TracePacket::for_testing,
3315                   Property(&protos::gen::TestEvent::str, Eq("bad_payload"))))));
3316 
3317   consumer->FreeBuffers();
3318   EXPECT_EQ(std::set<BufferID>(), GetAllowedTargetBuffers(producer_id));
3319 }
3320 #endif  // !PERFETTO_DCHECK_IS_ON()
3321 
TEST_F(TracingServiceImplTest,RegisterAndUnregisterTraceWriter)3322 TEST_F(TracingServiceImplTest, RegisterAndUnregisterTraceWriter) {
3323   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
3324   consumer->Connect(svc.get());
3325 
3326   std::unique_ptr<MockProducer> producer = CreateMockProducer();
3327   producer->Connect(svc.get(), "mock_producer");
3328   ProducerID producer_id = *last_producer_id();
3329   producer->RegisterDataSource("data_source");
3330 
3331   EXPECT_TRUE(GetWriters(producer_id).empty());
3332 
3333   TraceConfig trace_config;
3334   trace_config.add_buffers()->set_size_kb(128);
3335   auto* ds_config = trace_config.add_data_sources()->mutable_config();
3336   ds_config->set_name("data_source");
3337   ds_config->set_target_buffer(0);
3338   consumer->EnableTracing(trace_config);
3339 
3340   producer->WaitForTracingSetup();
3341   producer->WaitForDataSourceSetup("data_source");
3342   producer->WaitForDataSourceStart("data_source");
3343 
3344   // Calling StartTracing() should be a noop (% a DLOG statement) because the
3345   // trace config didn't have the |deferred_start| flag set.
3346   consumer->StartTracing();
3347 
3348   // Creating the trace writer should register it with the service.
3349   std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
3350       tracing_session()->buffers_index[0]);
3351 
3352   WaitForTraceWritersChanged(producer_id);
3353 
3354   std::map<WriterID, BufferID> expected_writers;
3355   expected_writers[writer->writer_id()] = tracing_session()->buffers_index[0];
3356   EXPECT_EQ(expected_writers, GetWriters(producer_id));
3357 
3358   // Verify writing works.
3359   {
3360     auto tp = writer->NewTracePacket();
3361     tp->set_for_testing()->set_str("payload");
3362   }
3363 
3364   auto flush_request = consumer->Flush();
3365   producer->ExpectFlush(writer.get());
3366   ASSERT_TRUE(flush_request.WaitForReply());
3367 
3368   // Destroying the writer should unregister it.
3369   writer.reset();
3370   WaitForTraceWritersChanged(producer_id);
3371   EXPECT_TRUE(GetWriters(producer_id).empty());
3372 
3373   consumer->DisableTracing();
3374   producer->WaitForDataSourceStop("data_source");
3375   consumer->WaitForTracingDisabled();
3376 
3377   auto packets = consumer->ReadBuffers();
3378   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
3379                                          Property(&protos::gen::TestEvent::str,
3380                                                   Eq("payload")))));
3381 }
3382 
TEST_F(TracingServiceImplTest,ScrapeBuffersOnFlush)3383 TEST_F(TracingServiceImplTest, ScrapeBuffersOnFlush) {
3384   svc->SetSMBScrapingEnabled(true);
3385 
3386   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
3387   consumer->Connect(svc.get());
3388 
3389   std::unique_ptr<MockProducer> producer = CreateMockProducer();
3390   producer->Connect(svc.get(), "mock_producer");
3391   ProducerID producer_id = *last_producer_id();
3392   producer->RegisterDataSource("data_source");
3393 
3394   TraceConfig trace_config;
3395   trace_config.add_buffers()->set_size_kb(128);
3396   auto* ds_config = trace_config.add_data_sources()->mutable_config();
3397   ds_config->set_name("data_source");
3398   ds_config->set_target_buffer(0);
3399   consumer->EnableTracing(trace_config);
3400 
3401   producer->WaitForTracingSetup();
3402   producer->WaitForDataSourceSetup("data_source");
3403   producer->WaitForDataSourceStart("data_source");
3404 
3405   // Calling StartTracing() should be a noop (% a DLOG statement) because the
3406   // trace config didn't have the |deferred_start| flag set.
3407   consumer->StartTracing();
3408 
3409   std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
3410       tracing_session()->buffers_index[0]);
3411   WaitForTraceWritersChanged(producer_id);
3412 
3413   // Write a few trace packets.
3414   writer->NewTracePacket()->set_for_testing()->set_str("payload1");
3415   writer->NewTracePacket()->set_for_testing()->set_str("payload2");
3416   writer->NewTracePacket()->set_for_testing()->set_str("payload3");
3417 
3418   // Flush but don't actually flush the chunk from TraceWriter.
3419   auto flush_request = consumer->Flush();
3420   producer->ExpectFlush(nullptr, /*reply=*/true);
3421   ASSERT_TRUE(flush_request.WaitForReply());
3422 
3423   // Chunk with the packets should have been scraped.
3424   auto packets = consumer->ReadBuffers();
3425   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
3426                                          Property(&protos::gen::TestEvent::str,
3427                                                   Eq("payload1")))));
3428   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
3429                                          Property(&protos::gen::TestEvent::str,
3430                                                   Eq("payload2")))));
3431   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
3432                                          Property(&protos::gen::TestEvent::str,
3433                                                   Eq("payload3")))));
3434 
3435   // Write some more packets.
3436   writer->NewTracePacket()->set_for_testing()->set_str("payload4");
3437   writer->NewTracePacket()->set_for_testing()->set_str("payload5");
3438 
3439   // Don't reply to flush, causing a timeout. This should scrape again.
3440   flush_request = consumer->Flush(/*timeout=*/100);
3441   producer->ExpectFlush(nullptr, /*reply=*/false);
3442   ASSERT_FALSE(flush_request.WaitForReply());
3443 
3444   // Chunk with the packets should have been scraped again, overriding the
3445   // original one. The first three should not be read twice.
3446   packets = consumer->ReadBuffers();
3447   EXPECT_THAT(packets,
3448               Not(Contains(Property(
3449                   &protos::gen::TracePacket::for_testing,
3450                   Property(&protos::gen::TestEvent::str, Eq("payload1"))))));
3451   EXPECT_THAT(packets,
3452               Not(Contains(Property(
3453                   &protos::gen::TracePacket::for_testing,
3454                   Property(&protos::gen::TestEvent::str, Eq("payload2"))))));
3455   EXPECT_THAT(packets,
3456               Not(Contains(Property(
3457                   &protos::gen::TracePacket::for_testing,
3458                   Property(&protos::gen::TestEvent::str, Eq("payload3"))))));
3459   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
3460                                          Property(&protos::gen::TestEvent::str,
3461                                                   Eq("payload4")))));
3462   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
3463                                          Property(&protos::gen::TestEvent::str,
3464                                                   Eq("payload5")))));
3465 
3466   consumer->DisableTracing();
3467   producer->WaitForDataSourceStop("data_source");
3468   consumer->WaitForTracingDisabled();
3469 }
3470 
TEST_F(TracingServiceImplTest,ScrapeBuffersFromAnotherThread)3471 TEST_F(TracingServiceImplTest, ScrapeBuffersFromAnotherThread) {
3472   // This test verifies that there are no reported TSAN races while scraping
3473   // buffers from a producer which is actively writing more trace data
3474   // concurrently.
3475   svc->SetSMBScrapingEnabled(true);
3476 
3477   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
3478   consumer->Connect(svc.get());
3479 
3480   std::unique_ptr<MockProducer> producer = CreateMockProducer();
3481   producer->Connect(svc.get(), "mock_producer");
3482   ProducerID producer_id = *last_producer_id();
3483   producer->RegisterDataSource("data_source");
3484 
3485   TraceConfig trace_config;
3486   trace_config.add_buffers()->set_size_kb(128);
3487   auto* ds_config = trace_config.add_data_sources()->mutable_config();
3488   ds_config->set_name("data_source");
3489   ds_config->set_target_buffer(0);
3490   consumer->EnableTracing(trace_config);
3491 
3492   producer->WaitForTracingSetup();
3493   producer->WaitForDataSourceSetup("data_source");
3494   producer->WaitForDataSourceStart("data_source");
3495   consumer->StartTracing();
3496 
3497   std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
3498       tracing_session()->buffers_index[0]);
3499   WaitForTraceWritersChanged(producer_id);
3500 
3501   constexpr int kPacketCount = 10;
3502   std::atomic<int> packets_written{};
3503   std::thread writer_thread([&] {
3504     for (int i = 0; i < kPacketCount; i++) {
3505       writer->NewTracePacket()->set_for_testing()->set_str("payload");
3506       packets_written.store(i, std::memory_order_relaxed);
3507     }
3508   });
3509 
3510   // Wait until the thread has had some time to write some packets.
3511   while (packets_written.load(std::memory_order_relaxed) < kPacketCount / 2)
3512     base::SleepMicroseconds(5000);
3513 
3514   // Disabling tracing will trigger scraping.
3515   consumer->DisableTracing();
3516   writer_thread.join();
3517 
3518   // Because we don't synchronize with the producer thread, we can't make any
3519   // guarantees about the number of packets we will successfully read. We just
3520   // verify that no TSAN races are reported.
3521   consumer->ReadBuffers();
3522 
3523   producer->WaitForDataSourceStop("data_source");
3524   consumer->WaitForTracingDisabled();
3525 }
3526 
3527 // Test scraping on producer disconnect.
TEST_F(TracingServiceImplTest,ScrapeBuffersOnProducerDisconnect)3528 TEST_F(TracingServiceImplTest, ScrapeBuffersOnProducerDisconnect) {
3529   svc->SetSMBScrapingEnabled(true);
3530 
3531   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
3532   consumer->Connect(svc.get());
3533 
3534   std::unique_ptr<MockProducer> producer = CreateMockProducer();
3535   producer->Connect(svc.get(), "mock_producer");
3536   ProducerID producer_id = *last_producer_id();
3537   producer->RegisterDataSource("data_source");
3538 
3539   TraceConfig trace_config;
3540   trace_config.add_buffers()->set_size_kb(128);
3541   auto* ds_config = trace_config.add_data_sources()->mutable_config();
3542   ds_config->set_name("data_source");
3543   ds_config->set_target_buffer(0);
3544   consumer->EnableTracing(trace_config);
3545 
3546   producer->WaitForTracingSetup();
3547   producer->WaitForDataSourceSetup("data_source");
3548   producer->WaitForDataSourceStart("data_source");
3549 
3550   // Calling StartTracing() should be a noop (% a DLOG statement) because the
3551   // trace config didn't have the |deferred_start| flag set.
3552   consumer->StartTracing();
3553 
3554   std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
3555       tracing_session()->buffers_index[0]);
3556   WaitForTraceWritersChanged(producer_id);
3557 
3558   // Write a few trace packets.
3559   writer->NewTracePacket()->set_for_testing()->set_str("payload1");
3560   writer->NewTracePacket()->set_for_testing()->set_str("payload2");
3561   writer->NewTracePacket()->set_for_testing()->set_str("payload3");
3562 
3563   // Disconnect the producer without committing the chunk. This should cause a
3564   // scrape of the SMB. Avoid destroying the ShmemArbiter until writer is
3565   // destroyed.
3566   auto shmem_arbiter = StealShmemArbiterForProducer(producer_id);
3567   producer.reset();
3568 
3569   // Chunk with the packets should have been scraped.
3570   auto packets = consumer->ReadBuffers();
3571   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
3572                                          Property(&protos::gen::TestEvent::str,
3573                                                   Eq("payload1")))));
3574   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
3575                                          Property(&protos::gen::TestEvent::str,
3576                                                   Eq("payload2")))));
3577   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
3578                                          Property(&protos::gen::TestEvent::str,
3579                                                   Eq("payload3")))));
3580 
3581   // Cleanup writer without causing a crash because the producer already went
3582   // away.
3583   static_cast<TraceWriterImpl*>(writer.get())->ResetChunkForTesting();
3584   writer.reset();
3585   shmem_arbiter.reset();
3586 
3587   consumer->DisableTracing();
3588   consumer->WaitForTracingDisabled();
3589 }
3590 
TEST_F(TracingServiceImplTest,ScrapeBuffersOnDisable)3591 TEST_F(TracingServiceImplTest, ScrapeBuffersOnDisable) {
3592   svc->SetSMBScrapingEnabled(true);
3593 
3594   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
3595   consumer->Connect(svc.get());
3596 
3597   std::unique_ptr<MockProducer> producer = CreateMockProducer();
3598   producer->Connect(svc.get(), "mock_producer");
3599   ProducerID producer_id = *last_producer_id();
3600   producer->RegisterDataSource("data_source");
3601 
3602   TraceConfig trace_config;
3603   trace_config.add_buffers()->set_size_kb(128);
3604   auto* ds_config = trace_config.add_data_sources()->mutable_config();
3605   ds_config->set_name("data_source");
3606   ds_config->set_target_buffer(0);
3607   consumer->EnableTracing(trace_config);
3608 
3609   producer->WaitForTracingSetup();
3610   producer->WaitForDataSourceSetup("data_source");
3611   producer->WaitForDataSourceStart("data_source");
3612 
3613   // Calling StartTracing() should be a noop (% a DLOG statement) because the
3614   // trace config didn't have the |deferred_start| flag set.
3615   consumer->StartTracing();
3616 
3617   std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
3618       tracing_session()->buffers_index[0]);
3619   WaitForTraceWritersChanged(producer_id);
3620 
3621   // Write a few trace packets.
3622   writer->NewTracePacket()->set_for_testing()->set_str("payload1");
3623   writer->NewTracePacket()->set_for_testing()->set_str("payload2");
3624   writer->NewTracePacket()->set_for_testing()->set_str("payload3");
3625 
3626   consumer->DisableTracing();
3627   producer->WaitForDataSourceStop("data_source");
3628   consumer->WaitForTracingDisabled();
3629 
3630   // Chunk with the packets should have been scraped.
3631   auto packets = consumer->ReadBuffers();
3632   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
3633                                          Property(&protos::gen::TestEvent::str,
3634                                                   Eq("payload1")))));
3635   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
3636                                          Property(&protos::gen::TestEvent::str,
3637                                                   Eq("payload2")))));
3638   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
3639                                          Property(&protos::gen::TestEvent::str,
3640                                                   Eq("payload3")))));
3641 }
3642 
3643 // Fixture for testing scraping from a single data source that writes directly
3644 // to the shared memory, to cover all cases.
3645 class TracingServiceImplScrapingWithSmbTest : public TracingServiceImplTest {
3646  public:
SetUp()3647   void SetUp() override {
3648     TracingServiceImplTest::SetUp();
3649     svc->SetSMBScrapingEnabled(true);
3650 
3651     consumer_ = CreateMockConsumer();
3652     consumer_->Connect(svc.get());
3653     producer_ = CreateMockProducer();
3654     producer_->Connect(svc.get(), "mock_producer");
3655     ProducerID producer_id = *last_producer_id();
3656     producer_->RegisterDataSource("data_source");
3657 
3658     TraceConfig trace_config;
3659     trace_config.add_buffers()->set_size_kb(128);
3660     auto* ds_config = trace_config.add_data_sources()->mutable_config();
3661     ds_config->set_name("data_source");
3662     ds_config->set_target_buffer(0);
3663     consumer_->EnableTracing(trace_config);
3664 
3665     producer_->WaitForTracingSetup();
3666     producer_->WaitForDataSourceSetup("data_source");
3667     producer_->WaitForDataSourceStart("data_source");
3668 
3669     writer_ = producer_->endpoint()->CreateTraceWriter(
3670         tracing_session()->buffers_index[0]);
3671     WaitForTraceWritersChanged(producer_id);
3672 
3673     arbiter_ = GetShmemArbiterForProducer(producer_id);
3674   }
3675 
TearDown()3676   void TearDown() override {
3677     TracingServiceImplTest::TearDown();
3678 
3679     consumer_->DisableTracing();
3680     producer_->WaitForDataSourceStop("data_source");
3681     consumer_->WaitForTracingDisabled();
3682   }
3683 
3684  protected:
FlushAndRead()3685   std::optional<std::vector<protos::gen::TracePacket>> FlushAndRead() {
3686     // Scrape: ask the service to flush but don't flush the chunk.
3687     auto flush_request = consumer_->Flush();
3688     producer_->ExpectFlush(nullptr, /*reply=*/true);
3689     if (flush_request.WaitForReply()) {
3690       return consumer_->ReadBuffers();
3691     }
3692     return std::nullopt;
3693   }
3694   std::unique_ptr<MockConsumer> consumer_;
3695   std::unique_ptr<MockProducer> producer_;
3696   std::unique_ptr<TraceWriter> writer_;
3697   // Owned by `svc`.
3698   SharedMemoryArbiterImpl* arbiter_;
3699 
3700   struct : public protozero::ScatteredStreamWriter::Delegate {
GetNewBufferperfetto::TracingServiceImplScrapingWithSmbTest::__anon204cd52710083701     protozero::ContiguousMemoryRange GetNewBuffer() override {
3702       PERFETTO_FATAL("Unreachable");
3703     }
3704 
AnnotatePatchperfetto::TracingServiceImplScrapingWithSmbTest::__anon204cd52710083705     uint8_t* AnnotatePatch(uint8_t*) override { PERFETTO_FATAL("Unreachable"); }
3706   } empty_delegate_;
3707   PatchList empty_patch_list_;
3708 };
3709 
TEST_F(TracingServiceImplScrapingWithSmbTest,ScrapeAfterInflatedCount)3710 TEST_F(TracingServiceImplScrapingWithSmbTest, ScrapeAfterInflatedCount) {
3711   SharedMemoryABI::ChunkHeader header = {};
3712   header.writer_id.store(writer_->writer_id(), std::memory_order_relaxed);
3713   header.chunk_id.store(0, std::memory_order_relaxed);
3714   header.packets.store({}, std::memory_order_relaxed);
3715 
3716   SharedMemoryABI::Chunk chunk =
3717       arbiter_->GetNewChunk(header, BufferExhaustedPolicy::kDrop);
3718   ASSERT_TRUE(chunk.is_valid());
3719 
3720   protozero::ScatteredStreamWriter stream_writer(&empty_delegate_);
3721   stream_writer.Reset({chunk.payload_begin(), chunk.end()});
3722 
3723   chunk.IncrementPacketCount();
3724 
3725   perfetto::protos::pbzero::TracePacket trace_packet;
3726   protozero::MessageArena arena;
3727   trace_packet.Reset(&stream_writer, &arena);
3728   trace_packet.set_size_field(stream_writer.ReserveBytes(4));
3729 
3730   trace_packet.set_for_testing()->set_str("payload1");
3731 
3732   trace_packet.Finalize();
3733 
3734   auto packets = FlushAndRead();
3735   ASSERT_TRUE(packets.has_value());
3736   // The scraping should not have seen the packet.
3737   EXPECT_THAT(*packets,
3738               Not(Contains(Property(
3739                   &protos::gen::TracePacket::for_testing,
3740                   Property(&protos::gen::TestEvent::str, Eq("payload1"))))));
3741 
3742   // Inflate the packet count: this is what
3743   // TraceWriterImpl::FinishTracePacket() does.
3744   chunk.IncrementPacketCount();
3745 
3746   packets = FlushAndRead();
3747   ASSERT_TRUE(packets.has_value());
3748   // The scraping now should see the packet.
3749   EXPECT_THAT(*packets,
3750               Contains(Property(
3751                   &protos::gen::TracePacket::for_testing,
3752                   Property(&protos::gen::TestEvent::str, Eq("payload1")))));
3753 
3754   // Before marking the chunk as complete, the trace writer writes an empty
3755   // trace packet (a single byte with zero size), to account for the inflated
3756   // trace count.
3757   ASSERT_GT(stream_writer.bytes_available(), 0u);
3758   uint8_t zero_size = 0;
3759   stream_writer.WriteBytesUnsafe(&zero_size, sizeof zero_size);
3760 
3761   packets = FlushAndRead();
3762   ASSERT_TRUE(packets.has_value());
3763   // The past scraping has already seen the packet.
3764   EXPECT_THAT(*packets,
3765               Not(Contains(Property(
3766                   &protos::gen::TracePacket::for_testing,
3767                   Property(&protos::gen::TestEvent::str, Eq("payload1"))))));
3768 
3769   arbiter_->ReturnCompletedChunk(std::move(chunk),
3770                                  tracing_session()->buffers_index[0],
3771                                  &empty_patch_list_);
3772 
3773   packets = FlushAndRead();
3774   ASSERT_TRUE(packets.has_value());
3775   // The past scraping has already seen the packet.
3776   EXPECT_THAT(*packets,
3777               Not(Contains(Property(
3778                   &protos::gen::TracePacket::for_testing,
3779                   Property(&protos::gen::TestEvent::str, Eq("payload1"))))));
3780 }
3781 
TEST_F(TracingServiceImplScrapingWithSmbTest,ScrapeAfterCompleteChunk)3782 TEST_F(TracingServiceImplScrapingWithSmbTest, ScrapeAfterCompleteChunk) {
3783   SharedMemoryABI::ChunkHeader header = {};
3784   header.writer_id.store(writer_->writer_id(), std::memory_order_relaxed);
3785   header.chunk_id.store(0, std::memory_order_relaxed);
3786   header.packets.store({}, std::memory_order_relaxed);
3787 
3788   SharedMemoryABI::Chunk chunk =
3789       arbiter_->GetNewChunk(header, BufferExhaustedPolicy::kDrop);
3790   ASSERT_TRUE(chunk.is_valid());
3791 
3792   protozero::ScatteredStreamWriter stream_writer(&empty_delegate_);
3793   stream_writer.Reset({chunk.payload_begin(), chunk.end()});
3794 
3795   chunk.IncrementPacketCount();
3796 
3797   perfetto::protos::pbzero::TracePacket trace_packet;
3798   protozero::MessageArena arena;
3799   trace_packet.Reset(&stream_writer, &arena);
3800   trace_packet.set_size_field(stream_writer.ReserveBytes(4));
3801 
3802   trace_packet.set_for_testing()->set_str("payload1");
3803 
3804   trace_packet.Finalize();
3805 
3806   auto packets = FlushAndRead();
3807   ASSERT_TRUE(packets.has_value());
3808   // The scraping should not have seen the packet.
3809   EXPECT_THAT(*packets,
3810               Not(Contains(Property(
3811                   &protos::gen::TracePacket::for_testing,
3812                   Property(&protos::gen::TestEvent::str, Eq("payload1"))))));
3813 
3814   // Inflate the packet count: this is what
3815   // TraceWriterImpl::FinishTracePacket() does.
3816   chunk.IncrementPacketCount();
3817 
3818   // Before marking the chunk as complete, the trace writer writes an empty
3819   // trace packet (a single byte with zero size), to account for the inflated
3820   // trace count.
3821   ASSERT_GT(stream_writer.bytes_available(), 0u);
3822   uint8_t zero_size = 0;
3823   stream_writer.WriteBytesUnsafe(&zero_size, sizeof zero_size);
3824 
3825   arbiter_->ReturnCompletedChunk(std::move(chunk),
3826                                  tracing_session()->buffers_index[0],
3827                                  &empty_patch_list_);
3828 
3829   packets = FlushAndRead();
3830   ASSERT_TRUE(packets.has_value());
3831   // The chunk has been marked as completed. Flushing should see the packet.
3832   EXPECT_THAT(*packets,
3833               Contains(Property(
3834                   &protos::gen::TracePacket::for_testing,
3835                   Property(&protos::gen::TestEvent::str, Eq("payload1")))));
3836 }
3837 
TEST_F(TracingServiceImplTest,AbortIfTraceDurationIsTooLong)3838 TEST_F(TracingServiceImplTest, AbortIfTraceDurationIsTooLong) {
3839   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
3840   consumer->Connect(svc.get());
3841 
3842   std::unique_ptr<MockProducer> producer = CreateMockProducer();
3843   producer->Connect(svc.get(), "mock_producer");
3844   producer->RegisterDataSource("datasource");
3845 
3846   TraceConfig trace_config;
3847   trace_config.add_buffers()->set_size_kb(128);
3848   trace_config.add_data_sources()->mutable_config()->set_name("datasource");
3849   trace_config.set_duration_ms(0x7fffffff);
3850 
3851   EXPECT_CALL(*producer, SetupDataSource(_, _)).Times(0);
3852   consumer->EnableTracing(trace_config);
3853 
3854   // The trace is aborted immediately, the default timeout here is just some
3855   // slack for the thread ping-pongs for slow devices.
3856   consumer->WaitForTracingDisabled();
3857 }
3858 
TEST_F(TracingServiceImplTest,GetTraceStats)3859 TEST_F(TracingServiceImplTest, GetTraceStats) {
3860   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
3861   consumer->Connect(svc.get());
3862 
3863   consumer->GetTraceStats();
3864   consumer->WaitForTraceStats(false);
3865 
3866   std::unique_ptr<MockProducer> producer = CreateMockProducer();
3867   producer->Connect(svc.get(), "mock_producer");
3868   producer->RegisterDataSource("data_source");
3869 
3870   TraceConfig trace_config;
3871   trace_config.add_buffers()->set_size_kb(128);
3872   auto* ds_config = trace_config.add_data_sources()->mutable_config();
3873   ds_config->set_name("data_source");
3874 
3875   consumer->EnableTracing(trace_config);
3876   producer->WaitForTracingSetup();
3877   producer->WaitForDataSourceSetup("data_source");
3878   producer->WaitForDataSourceStart("data_source");
3879 
3880   consumer->GetTraceStats();
3881   consumer->WaitForTraceStats(true);
3882 
3883   consumer->DisableTracing();
3884   producer->WaitForDataSourceStop("data_source");
3885   consumer->WaitForTracingDisabled();
3886 }
3887 
TEST_F(TracingServiceImplTest,TraceWriterStats)3888 TEST_F(TracingServiceImplTest, TraceWriterStats) {
3889   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
3890   consumer->Connect(svc.get());
3891 
3892   std::unique_ptr<MockProducer> producer = CreateMockProducer();
3893   producer->Connect(svc.get(), "mock_producer");
3894   producer->RegisterDataSource("data_source_1");
3895   producer->RegisterDataSource("data_source_2");
3896 
3897   TraceConfig trace_config;
3898   for (uint32_t i = 0; i < 3; i++)
3899     trace_config.add_buffers()->set_size_kb(512);
3900   for (uint32_t i = 1; i <= 2; i++) {
3901     auto* ds_config = trace_config.add_data_sources()->mutable_config();
3902     ds_config->set_name("data_source_" + std::to_string(i));
3903     ds_config->set_target_buffer(i);  // DS1 : buf[1], DS2: buf[2].
3904     // buf[0] is deliberately unused, to check we get the buffer_idx right.
3905   }
3906 
3907   consumer->EnableTracing(trace_config);
3908   producer->WaitForTracingSetup();
3909   producer->WaitForDataSourceSetup("data_source_1");
3910   producer->WaitForDataSourceSetup("data_source_2");
3911   producer->WaitForDataSourceStart("data_source_1");
3912   producer->WaitForDataSourceStart("data_source_2");
3913 
3914   const std::string payload_128(128 - 32, 'a');
3915   const std::string payload_512(512 - 32, 'b');
3916   const std::string payload_1k(1024 - 32, 'c');
3917   const std::string payload_2k(2048 - 32, 'd');
3918 
3919   auto writer1 = producer->CreateTraceWriter("data_source_1");
3920   auto writer2 = producer->CreateTraceWriter("data_source_2");
3921 
3922   // Flush after each packet to create chunks that match packets.
3923   writer1->NewTracePacket()->set_for_testing()->set_str(payload_128);
3924   writer1->Flush();
3925 
3926   writer1->NewTracePacket()->set_for_testing()->set_str(payload_1k);
3927   writer1->Flush();
3928 
3929   writer2->NewTracePacket()->set_for_testing()->set_str(payload_512);
3930   writer2->Flush();
3931 
3932   writer2->NewTracePacket()->set_for_testing()->set_str(payload_2k);
3933   writer2->Flush();
3934 
3935   writer2->NewTracePacket()->set_for_testing()->set_str(payload_2k);
3936   writer2->Flush();
3937 
3938   auto flush_request = consumer->Flush();
3939   producer->ExpectFlush({writer1.get(), writer2.get()});
3940   ASSERT_TRUE(flush_request.WaitForReply());
3941 
3942   writer1.reset();
3943   writer2.reset();
3944 
3945   consumer->DisableTracing();
3946   producer->WaitForDataSourceStop("data_source_1");
3947   producer->WaitForDataSourceStop("data_source_2");
3948   consumer->WaitForTracingDisabled();
3949 
3950   auto packets = consumer->ReadBuffers();
3951   EXPECT_THAT(
3952       packets,
3953       Contains(Property(&protos::gen::TracePacket::has_trace_stats, Eq(true))));
3954   for (const auto& packet : packets) {
3955     if (!packet.has_trace_stats())
3956       continue;
3957 
3958     EXPECT_GT(packet.trace_stats().writer_stats().size(), 0u);
3959     for (const auto& wri : packet.trace_stats().writer_stats()) {
3960       for (size_t i = 0; i < wri.chunk_payload_histogram_counts().size() - 1;
3961            i++) {
3962         PERFETTO_DLOG("Seq=%" PRIu64 ", %" PRIu64 " : %" PRIu64,
3963                       wri.sequence_id(),
3964                       packet.trace_stats().chunk_payload_histogram_def()[i],
3965                       wri.chunk_payload_histogram_counts()[i]);
3966       }
3967 
3968       switch (wri.sequence_id()) {
3969         case 1:  // Ignore service-generated packets.
3970           continue;
3971         case 2:  // writer1
3972           EXPECT_EQ(wri.buffer(), 1u);
3973           EXPECT_THAT(wri.chunk_payload_histogram_counts(),
3974                       ElementsAreArray({0 /*8*/, 0 /*32*/, 1 /*128*/, 0 /*512*/,
3975                                         1 /*1K*/, 0 /*2K*/, 0 /*4K*/, 0 /*8K*/,
3976                                         0 /*12K*/, 0 /*16K*/, 0 /*>16K*/}));
3977           continue;
3978         case 3:  // writer2
3979           EXPECT_EQ(wri.buffer(), 2u);
3980           EXPECT_THAT(wri.chunk_payload_histogram_counts(),
3981                       ElementsAreArray({0 /*8*/, 0 /*32*/, 0 /*128*/, 1 /*512*/,
3982                                         0 /*1K*/, 2 /*2K*/, 0 /*4K*/, 0 /*8K*/,
3983                                         0 /*12K*/, 0 /*16K*/, 0 /*>16K*/}));
3984           continue;
3985         default:
3986           ASSERT_TRUE(false) << "Unexpected sequence " << wri.sequence_id();
3987       }
3988     }
3989   }
3990 }
3991 
TEST_F(TracingServiceImplTest,ObserveEventsDataSourceInstances)3992 TEST_F(TracingServiceImplTest, ObserveEventsDataSourceInstances) {
3993   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
3994   consumer->Connect(svc.get());
3995 
3996   std::unique_ptr<MockProducer> producer = CreateMockProducer();
3997   producer->Connect(svc.get(), "mock_producer");
3998   producer->RegisterDataSource("data_source");
3999 
4000   TraceConfig trace_config;
4001   trace_config.add_buffers()->set_size_kb(128);
4002   auto* ds_config = trace_config.add_data_sources()->mutable_config();
4003   ds_config->set_name("data_source");
4004 
4005   // Start tracing before the consumer is interested in events. The consumer's
4006   // OnObservableEvents() should not be called yet.
4007   consumer->EnableTracing(trace_config);
4008   producer->WaitForTracingSetup();
4009   producer->WaitForDataSourceSetup("data_source");
4010   producer->WaitForDataSourceStart("data_source");
4011 
4012   // Calling ObserveEvents should cause an event for the initial instance state.
4013   consumer->ObserveEvents(ObservableEvents::TYPE_DATA_SOURCES_INSTANCES);
4014   {
4015     auto events = consumer->WaitForObservableEvents();
4016 
4017     ObservableEvents::DataSourceInstanceStateChange change;
4018     change.set_producer_name("mock_producer");
4019     change.set_data_source_name("data_source");
4020     change.set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STARTED);
4021     EXPECT_EQ(events.instance_state_changes_size(), 1);
4022     EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
4023   }
4024 
4025   // Disabling should cause an instance state change to STOPPED.
4026   consumer->DisableTracing();
4027 
4028   {
4029     auto events = consumer->WaitForObservableEvents();
4030 
4031     ObservableEvents::DataSourceInstanceStateChange change;
4032     change.set_producer_name("mock_producer");
4033     change.set_data_source_name("data_source");
4034     change.set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STOPPED);
4035     EXPECT_EQ(events.instance_state_changes_size(), 1);
4036     EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
4037   }
4038 
4039   producer->WaitForDataSourceStop("data_source");
4040   consumer->WaitForTracingDisabled();
4041   consumer->FreeBuffers();
4042 
4043   // Enable again, this should cause a state change for a new instance to
4044   // its initial state STOPPED.
4045   trace_config.set_deferred_start(true);
4046   consumer->EnableTracing(trace_config);
4047 
4048   {
4049     auto events = consumer->WaitForObservableEvents();
4050 
4051     ObservableEvents::DataSourceInstanceStateChange change;
4052     change.set_producer_name("mock_producer");
4053     change.set_data_source_name("data_source");
4054     change.set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STOPPED);
4055     EXPECT_EQ(events.instance_state_changes_size(), 1);
4056     EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
4057   }
4058 
4059   producer->WaitForDataSourceSetup("data_source");
4060 
4061   // Should move the instance into STARTED state and thus cause an event.
4062   consumer->StartTracing();
4063 
4064   {
4065     auto events = consumer->WaitForObservableEvents();
4066 
4067     ObservableEvents::DataSourceInstanceStateChange change;
4068     change.set_producer_name("mock_producer");
4069     change.set_data_source_name("data_source");
4070     change.set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STARTED);
4071     EXPECT_EQ(events.instance_state_changes_size(), 1);
4072     EXPECT_THAT(events.instance_state_changes(), Contains(Eq(change)));
4073   }
4074 
4075   producer->WaitForDataSourceStart("data_source");
4076 
4077   // Stop observing events.
4078   consumer->ObserveEvents(0);
4079 
4080   // Disabling should now no longer cause events to be sent to the consumer.
4081   consumer->DisableTracing();
4082   producer->WaitForDataSourceStop("data_source");
4083   consumer->WaitForTracingDisabled();
4084 }
4085 
TEST_F(TracingServiceImplTest,ObserveEventsDataSourceInstancesUnregister)4086 TEST_F(TracingServiceImplTest, ObserveEventsDataSourceInstancesUnregister) {
4087   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4088   consumer->Connect(svc.get());
4089 
4090   std::unique_ptr<MockProducer> producer = CreateMockProducer();
4091   producer->Connect(svc.get(), "mock_producer");
4092   producer->RegisterDataSource("data_source");
4093 
4094   TraceConfig trace_config;
4095   trace_config.add_buffers()->set_size_kb(128);
4096   auto* ds_config = trace_config.add_data_sources()->mutable_config();
4097   ds_config->set_name("data_source");
4098 
4099   // Start tracing before the consumer is interested in events. The consumer's
4100   // OnObservableEvents() should not be called yet.
4101   consumer->EnableTracing(trace_config);
4102   producer->WaitForTracingSetup();
4103   producer->WaitForDataSourceSetup("data_source");
4104   producer->WaitForDataSourceStart("data_source");
4105 
4106   // Calling ObserveEvents should cause an event for the initial instance state.
4107   consumer->ObserveEvents(ObservableEvents::TYPE_DATA_SOURCES_INSTANCES);
4108   {
4109     ObservableEvents event;
4110     ObservableEvents::DataSourceInstanceStateChange* change =
4111         event.add_instance_state_changes();
4112     change->set_producer_name("mock_producer");
4113     change->set_data_source_name("data_source");
4114     change->set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STARTED);
4115     EXPECT_CALL(*consumer, OnObservableEvents(Eq(event)))
4116         .WillOnce(InvokeWithoutArgs(
4117             task_runner.CreateCheckpoint("data_source_started")));
4118 
4119     task_runner.RunUntilCheckpoint("data_source_started");
4120   }
4121   {
4122     ObservableEvents event;
4123     ObservableEvents::DataSourceInstanceStateChange* change =
4124         event.add_instance_state_changes();
4125     change->set_producer_name("mock_producer");
4126     change->set_data_source_name("data_source");
4127     change->set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STOPPED);
4128     EXPECT_CALL(*consumer, OnObservableEvents(Eq(event)))
4129         .WillOnce(InvokeWithoutArgs(
4130             task_runner.CreateCheckpoint("data_source_stopped")));
4131   }
4132   producer->UnregisterDataSource("data_source");
4133   producer->WaitForDataSourceStop("data_source");
4134   task_runner.RunUntilCheckpoint("data_source_stopped");
4135 
4136   consumer->DisableTracing();
4137   consumer->WaitForTracingDisabled();
4138 }
4139 
TEST_F(TracingServiceImplTest,ObserveAllDataSourceStarted)4140 TEST_F(TracingServiceImplTest, ObserveAllDataSourceStarted) {
4141   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4142   consumer->Connect(svc.get());
4143 
4144   std::unique_ptr<MockProducer> producer = CreateMockProducer();
4145   producer->Connect(svc.get(), "mock_producer");
4146   producer->RegisterDataSource("ds1", /*ack_stop=*/false, /*ack_start=*/true);
4147   producer->RegisterDataSource("ds2", /*ack_stop=*/false, /*ack_start=*/true);
4148 
4149   TraceConfig trace_config;
4150   trace_config.set_deferred_start(true);
4151   trace_config.add_buffers()->set_size_kb(128);
4152   auto* ds_config = trace_config.add_data_sources()->mutable_config();
4153   ds_config->set_name("ds1");
4154   ds_config = trace_config.add_data_sources()->mutable_config();
4155   ds_config->set_name("ds2");
4156 
4157   for (int repetition = 0; repetition < 3; repetition++) {
4158     consumer->EnableTracing(trace_config);
4159 
4160     if (repetition == 0)
4161       producer->WaitForTracingSetup();
4162 
4163     producer->WaitForDataSourceSetup("ds1");
4164     producer->WaitForDataSourceSetup("ds2");
4165     task_runner.RunUntilIdle();
4166 
4167     consumer->ObserveEvents(ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);
4168     consumer->StartTracing();
4169     producer->WaitForDataSourceStart("ds1");
4170     producer->WaitForDataSourceStart("ds2");
4171 
4172     DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds1");
4173     producer->endpoint()->NotifyDataSourceStarted(id1);
4174 
4175     // The notification shouldn't happen yet, ds2 has not acked.
4176     task_runner.RunUntilIdle();
4177     Mock::VerifyAndClearExpectations(consumer.get());
4178 
4179     EXPECT_THAT(
4180         consumer->ReadBuffers(),
4181         Contains(Property(
4182             &protos::gen::TracePacket::service_event,
4183             Property(
4184                 &protos::gen::TracingServiceEvent::all_data_sources_started,
4185                 Eq(false)))));
4186 
4187     DataSourceInstanceID id2 = producer->GetDataSourceInstanceId("ds2");
4188     producer->endpoint()->NotifyDataSourceStarted(id2);
4189 
4190     // Now the |all_data_sources_started| notification should be sent.
4191 
4192     auto events = consumer->WaitForObservableEvents();
4193     ObservableEvents::DataSourceInstanceStateChange change;
4194     EXPECT_TRUE(events.all_data_sources_started());
4195 
4196     // Disabling should cause an instance state change to STOPPED.
4197     consumer->DisableTracing();
4198     producer->WaitForDataSourceStop("ds1");
4199     producer->WaitForDataSourceStop("ds2");
4200     consumer->WaitForTracingDisabled();
4201 
4202     EXPECT_THAT(
4203         consumer->ReadBuffers(),
4204         Contains(Property(
4205             &protos::gen::TracePacket::service_event,
4206             Property(
4207                 &protos::gen::TracingServiceEvent::all_data_sources_started,
4208                 Eq(true)))));
4209     consumer->FreeBuffers();
4210 
4211     task_runner.RunUntilIdle();
4212 
4213     Mock::VerifyAndClearExpectations(consumer.get());
4214     Mock::VerifyAndClearExpectations(producer.get());
4215   }
4216 }
4217 
TEST_F(TracingServiceImplTest,ObserveAllDataSourceStartedWithoutMatchingInstances)4218 TEST_F(TracingServiceImplTest,
4219        ObserveAllDataSourceStartedWithoutMatchingInstances) {
4220   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4221   consumer->Connect(svc.get());
4222 
4223   TraceConfig trace_config;
4224   trace_config.add_buffers()->set_size_kb(128);
4225 
4226   consumer->ObserveEvents(ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);
4227 
4228   // EnableTracing() should immediately cause ALL_DATA_SOURCES_STARTED, because
4229   // there aren't any matching data sources registered.
4230   consumer->EnableTracing(trace_config);
4231 
4232   auto events = consumer->WaitForObservableEvents();
4233   ObservableEvents::DataSourceInstanceStateChange change;
4234   EXPECT_TRUE(events.all_data_sources_started());
4235 
4236   consumer->DisableTracing();
4237   consumer->WaitForTracingDisabled();
4238 
4239   EXPECT_THAT(
4240       consumer->ReadBuffers(),
4241       Contains(Property(
4242           &protos::gen::TracePacket::service_event,
4243           Property(&protos::gen::TracingServiceEvent::all_data_sources_started,
4244                    Eq(true)))));
4245   consumer->FreeBuffers();
4246 
4247   task_runner.RunUntilIdle();
4248 
4249   Mock::VerifyAndClearExpectations(consumer.get());
4250 }
4251 
4252 // Similar to ObserveAllDataSourceStarted, but covers the case of some data
4253 // sources not supporting the |notify_on_start|.
TEST_F(TracingServiceImplTest,ObserveAllDataSourceStartedOnlySomeWillAck)4254 TEST_F(TracingServiceImplTest, ObserveAllDataSourceStartedOnlySomeWillAck) {
4255   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4256   consumer->Connect(svc.get());
4257 
4258   std::unique_ptr<MockProducer> producer = CreateMockProducer();
4259   producer->Connect(svc.get(), "mock_producer");
4260   producer->RegisterDataSource("ds1", /*ack_stop=*/false, /*ack_start=*/true);
4261   producer->RegisterDataSource("ds2_no_ack");
4262 
4263   TraceConfig trace_config;
4264   trace_config.set_deferred_start(true);
4265   trace_config.add_buffers()->set_size_kb(128);
4266   auto* ds_config = trace_config.add_data_sources()->mutable_config();
4267   ds_config->set_name("ds1");
4268   ds_config = trace_config.add_data_sources()->mutable_config();
4269   ds_config->set_name("ds2_no_ack");
4270 
4271   for (int repetition = 0; repetition < 3; repetition++) {
4272     consumer->EnableTracing(trace_config);
4273 
4274     if (repetition == 0)
4275       producer->WaitForTracingSetup();
4276 
4277     producer->WaitForDataSourceSetup("ds1");
4278     producer->WaitForDataSourceSetup("ds2_no_ack");
4279     task_runner.RunUntilIdle();
4280 
4281     consumer->ObserveEvents(ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);
4282     consumer->StartTracing();
4283     producer->WaitForDataSourceStart("ds1");
4284     producer->WaitForDataSourceStart("ds2_no_ack");
4285 
4286     DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds1");
4287     producer->endpoint()->NotifyDataSourceStarted(id1);
4288 
4289     auto events = consumer->WaitForObservableEvents();
4290     ObservableEvents::DataSourceInstanceStateChange change;
4291     EXPECT_TRUE(events.all_data_sources_started());
4292 
4293     // Disabling should cause an instance state change to STOPPED.
4294     consumer->DisableTracing();
4295     producer->WaitForDataSourceStop("ds1");
4296     producer->WaitForDataSourceStop("ds2_no_ack");
4297     consumer->FreeBuffers();
4298     consumer->WaitForTracingDisabled();
4299 
4300     task_runner.RunUntilIdle();
4301     Mock::VerifyAndClearExpectations(consumer.get());
4302     Mock::VerifyAndClearExpectations(producer.get());
4303   }
4304 }
4305 
4306 // Similar to ObserveAllDataSourceStarted, but covers the case of no data
4307 // sources supporting the |notify_on_start|. In this case the
4308 // TYPE_ALL_DATA_SOURCES_STARTED notification should be sent immediately after
4309 // calling Start().
TEST_F(TracingServiceImplTest,ObserveAllDataSourceStartedNoAck)4310 TEST_F(TracingServiceImplTest, ObserveAllDataSourceStartedNoAck) {
4311   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4312   consumer->Connect(svc.get());
4313 
4314   std::unique_ptr<MockProducer> producer = CreateMockProducer();
4315   producer->Connect(svc.get(), "mock_producer");
4316   producer->RegisterDataSource("ds1_no_ack");
4317   producer->RegisterDataSource("ds2_no_ack");
4318 
4319   TraceConfig trace_config;
4320   trace_config.set_deferred_start(true);
4321   trace_config.add_buffers()->set_size_kb(128);
4322   auto* ds_config = trace_config.add_data_sources()->mutable_config();
4323   ds_config->set_name("ds1_no_ack");
4324   ds_config = trace_config.add_data_sources()->mutable_config();
4325   ds_config->set_name("ds2_no_ack");
4326 
4327   for (int repetition = 0; repetition < 3; repetition++) {
4328     consumer->EnableTracing(trace_config);
4329 
4330     if (repetition == 0)
4331       producer->WaitForTracingSetup();
4332 
4333     producer->WaitForDataSourceSetup("ds1_no_ack");
4334     producer->WaitForDataSourceSetup("ds2_no_ack");
4335     task_runner.RunUntilIdle();
4336 
4337     consumer->ObserveEvents(ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);
4338     consumer->StartTracing();
4339     producer->WaitForDataSourceStart("ds1_no_ack");
4340     producer->WaitForDataSourceStart("ds2_no_ack");
4341 
4342     auto events = consumer->WaitForObservableEvents();
4343     ObservableEvents::DataSourceInstanceStateChange change;
4344     EXPECT_TRUE(events.all_data_sources_started());
4345 
4346     // Disabling should cause an instance state change to STOPPED.
4347     consumer->DisableTracing();
4348     producer->WaitForDataSourceStop("ds1_no_ack");
4349     producer->WaitForDataSourceStop("ds2_no_ack");
4350     consumer->FreeBuffers();
4351     consumer->WaitForTracingDisabled();
4352 
4353     task_runner.RunUntilIdle();
4354     Mock::VerifyAndClearExpectations(consumer.get());
4355     Mock::VerifyAndClearExpectations(producer.get());
4356   }
4357 }
4358 
TEST_F(TracingServiceImplTest,LifecycleEventSmoke)4359 TEST_F(TracingServiceImplTest, LifecycleEventSmoke) {
4360   using TracingServiceEvent = protos::gen::TracingServiceEvent;
4361   using TracingServiceEventFnPtr = bool (TracingServiceEvent::*)() const;
4362   auto has_lifecycle_field = [](TracingServiceEventFnPtr ptr) {
4363     return Contains(Property(&protos::gen::TracePacket::service_event,
4364                              Property(ptr, Eq(true))));
4365   };
4366   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4367   consumer->Connect(svc.get());
4368 
4369   std::unique_ptr<MockProducer> producer = CreateMockProducer();
4370   producer->Connect(svc.get(), "mock_producer");
4371   producer->RegisterDataSource("data_source");
4372 
4373   TraceConfig trace_config;
4374   trace_config.add_buffers()->set_size_kb(128);
4375   trace_config.add_data_sources()->mutable_config()->set_name("data_source");
4376 
4377   consumer->EnableTracing(trace_config);
4378 
4379   producer->WaitForTracingSetup();
4380   producer->WaitForDataSourceSetup("data_source");
4381   producer->WaitForDataSourceStart("data_source");
4382   task_runner.RunUntilIdle();
4383 
4384   auto packets = consumer->ReadBuffers();
4385   EXPECT_THAT(packets,
4386               has_lifecycle_field(&TracingServiceEvent::tracing_started));
4387   EXPECT_THAT(packets, has_lifecycle_field(
4388                            &TracingServiceEvent::all_data_sources_started));
4389   EXPECT_THAT(packets,
4390               has_lifecycle_field(
4391                   &TracingServiceEvent::read_tracing_buffers_completed));
4392 
4393   std::unique_ptr<TraceWriter> writer =
4394       producer->CreateTraceWriter("data_source");
4395   {
4396     auto tp = writer->NewTracePacket();
4397     tp->set_for_testing()->set_str("payload");
4398   }
4399 
4400   auto flush_request = consumer->Flush();
4401   producer->ExpectFlush(writer.get());
4402   ASSERT_TRUE(flush_request.WaitForReply());
4403 
4404   packets = consumer->ReadBuffers();
4405   EXPECT_THAT(packets, has_lifecycle_field(
4406                            &TracingServiceEvent::all_data_sources_flushed));
4407   EXPECT_THAT(packets,
4408               has_lifecycle_field(
4409                   &TracingServiceEvent::read_tracing_buffers_completed));
4410 
4411   consumer->DisableTracing();
4412   producer->WaitForDataSourceStop("data_source");
4413   consumer->WaitForTracingDisabled();
4414 
4415   packets = consumer->ReadBuffers();
4416   EXPECT_THAT(packets,
4417               has_lifecycle_field(&TracingServiceEvent::tracing_disabled));
4418   EXPECT_THAT(packets,
4419               has_lifecycle_field(
4420                   &TracingServiceEvent::read_tracing_buffers_completed));
4421 }
4422 
TEST_F(TracingServiceImplTest,LifecycleMultipleFlushEventsQueued)4423 TEST_F(TracingServiceImplTest, LifecycleMultipleFlushEventsQueued) {
4424   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4425   consumer->Connect(svc.get());
4426 
4427   std::unique_ptr<MockProducer> producer = CreateMockProducer();
4428   producer->Connect(svc.get(), "mock_producer");
4429   producer->RegisterDataSource("data_source");
4430 
4431   TraceConfig trace_config;
4432   trace_config.add_buffers()->set_size_kb(128);
4433   trace_config.add_data_sources()->mutable_config()->set_name("data_source");
4434 
4435   consumer->EnableTracing(trace_config);
4436 
4437   producer->WaitForTracingSetup();
4438   producer->WaitForDataSourceSetup("data_source");
4439   producer->WaitForDataSourceStart("data_source");
4440   task_runner.RunUntilIdle();
4441 
4442   std::unique_ptr<TraceWriter> writer =
4443       producer->CreateTraceWriter("data_source");
4444   {
4445     auto tp = writer->NewTracePacket();
4446     tp->set_for_testing()->set_str("payload");
4447   }
4448 
4449   auto flush_request = consumer->Flush();
4450   producer->ExpectFlush(writer.get());
4451   ASSERT_TRUE(flush_request.WaitForReply());
4452 
4453   {
4454     auto tp = writer->NewTracePacket();
4455     tp->set_for_testing()->set_str("payload");
4456   }
4457 
4458   flush_request = consumer->Flush();
4459   producer->ExpectFlush(writer.get());
4460   ASSERT_TRUE(flush_request.WaitForReply());
4461 
4462   auto packets = consumer->ReadBuffers();
4463   uint32_t count = 0;
4464   for (const auto& packet : packets) {
4465     count += packet.service_event().all_data_sources_flushed();
4466   }
4467   ASSERT_EQ(count, 2u);
4468 
4469   consumer->DisableTracing();
4470   producer->WaitForDataSourceStop("data_source");
4471   consumer->WaitForTracingDisabled();
4472 }
4473 
TEST_F(TracingServiceImplTest,QueryServiceState)4474 TEST_F(TracingServiceImplTest, QueryServiceState) {
4475   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4476   consumer->Connect(svc.get());
4477 
4478   std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
4479   producer1->Connect(svc.get(), "producer1", /*uid=*/0);
4480 
4481   std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
4482   producer2->Connect(svc.get(), "producer2", /*uid=*/1002);
4483 
4484   producer1->RegisterDataSource("common_ds");
4485   producer2->RegisterDataSource("common_ds");
4486 
4487   producer1->RegisterDataSource("p1_ds");
4488   producer2->RegisterDataSource("p2_ds");
4489 
4490   producer2->RegisterDataSource("common_ds");
4491 
4492   TracingServiceState svc_state = consumer->QueryServiceState();
4493 
4494   EXPECT_EQ(svc_state.producers_size(), 2);
4495   EXPECT_EQ(svc_state.producers().at(0).id(), 1);
4496   EXPECT_EQ(svc_state.producers().at(0).name(), "producer1");
4497   EXPECT_EQ(svc_state.producers().at(0).uid(), 0);
4498   EXPECT_EQ(svc_state.producers().at(1).id(), 2);
4499   EXPECT_EQ(svc_state.producers().at(1).name(), "producer2");
4500   EXPECT_EQ(svc_state.producers().at(1).uid(), 1002);
4501 
4502   EXPECT_EQ(svc_state.data_sources_size(), 5);
4503 
4504   auto count_ds = [&](int32_t producer_id, const std::string& ds_name) {
4505     int count = 0;
4506     for (const auto& ds : svc_state.data_sources()) {
4507       if (ds.producer_id() == producer_id &&
4508           ds.ds_descriptor().name() == ds_name)
4509         ++count;
4510     }
4511     return count;
4512   };
4513 
4514   EXPECT_EQ(count_ds(1, "common_ds"), 1);
4515   EXPECT_EQ(count_ds(1, "p1_ds"), 1);
4516   EXPECT_EQ(count_ds(2, "common_ds"), 2);
4517   EXPECT_EQ(count_ds(2, "p2_ds"), 1);
4518 
4519   // Test that descriptors are cleared when a producer disconnects.
4520   producer1.reset();
4521   svc_state = consumer->QueryServiceState();
4522 
4523   EXPECT_EQ(svc_state.producers_size(), 1);
4524   EXPECT_EQ(svc_state.data_sources_size(), 3);
4525 
4526   EXPECT_EQ(count_ds(1, "common_ds"), 0);
4527   EXPECT_EQ(count_ds(1, "p1_ds"), 0);
4528   EXPECT_EQ(count_ds(2, "common_ds"), 2);
4529   EXPECT_EQ(count_ds(2, "p2_ds"), 1);
4530 }
4531 
TEST_F(TracingServiceImplTest,UpdateDataSource)4532 TEST_F(TracingServiceImplTest, UpdateDataSource) {
4533   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4534   consumer->Connect(svc.get());
4535 
4536   std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
4537   producer1->Connect(svc.get(), "producer1", /*uid=*/0);
4538 
4539   std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
4540   producer2->Connect(svc.get(), "producer2", /*uid=*/1002);
4541 
4542   producer1->RegisterTrackEventDataSource({"cat1"}, 1);
4543   producer2->RegisterTrackEventDataSource({}, 1);
4544   producer2->RegisterTrackEventDataSource({}, 2);
4545 
4546   // This request should fail because ID=2 is already registered.
4547   producer2->RegisterTrackEventDataSource({"this_should_fail"}, 2);
4548 
4549   TracingServiceState svc_state = consumer->QueryServiceState();
4550 
4551   auto parse_desc = [](const perfetto::protos::gen::DataSourceDescriptor& dsd) {
4552     perfetto::protos::gen::TrackEventDescriptor desc;
4553     auto desc_raw = dsd.track_event_descriptor_raw();
4554     EXPECT_TRUE(desc.ParseFromArray(desc_raw.data(), desc_raw.size()));
4555     return desc;
4556   };
4557 
4558   EXPECT_EQ(svc_state.data_sources_size(), 3);
4559 
4560   EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 1);
4561   EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().name(),
4562             "track_event");
4563   EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().id(), 1u);
4564   auto ted = parse_desc(svc_state.data_sources().at(0).ds_descriptor());
4565   EXPECT_EQ(ted.available_categories_size(), 1);
4566   EXPECT_EQ(ted.available_categories()[0].name(), "cat1");
4567 
4568   EXPECT_EQ(svc_state.data_sources().at(1).producer_id(), 2);
4569   EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().name(),
4570             "track_event");
4571   EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().id(), 1u);
4572   ted = parse_desc(svc_state.data_sources().at(1).ds_descriptor());
4573   EXPECT_EQ(ted.available_categories_size(), 0);
4574 
4575   EXPECT_EQ(svc_state.data_sources().at(2).ds_descriptor().id(), 2u);
4576 
4577   // Test that TrackEvent DataSource is updated.
4578   producer2->UpdateTrackEventDataSource({"cat1", "cat2"}, 2);
4579 
4580   svc_state = consumer->QueryServiceState();
4581 
4582   EXPECT_EQ(svc_state.data_sources_size(), 3);
4583 
4584   EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 1);
4585   EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().id(), 1u);
4586   ted = parse_desc(svc_state.data_sources().at(0).ds_descriptor());
4587   EXPECT_EQ(ted.available_categories_size(), 1);
4588 
4589   EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().id(), 1u);
4590   ted = parse_desc(svc_state.data_sources().at(1).ds_descriptor());
4591   EXPECT_EQ(ted.available_categories_size(), 0);
4592 
4593   EXPECT_EQ(svc_state.data_sources().at(2).producer_id(), 2);
4594   EXPECT_EQ(svc_state.data_sources().at(2).ds_descriptor().id(), 2u);
4595   ted = parse_desc(svc_state.data_sources().at(2).ds_descriptor());
4596   EXPECT_EQ(ted.available_categories_size(), 2);
4597   EXPECT_EQ(ted.available_categories()[0].name(), "cat1");
4598   EXPECT_EQ(ted.available_categories()[1].name(), "cat2");
4599 
4600   // Test removal of a category.
4601   producer2->UpdateTrackEventDataSource({"cat2"}, 2);
4602 
4603   svc_state = consumer->QueryServiceState();
4604 
4605   EXPECT_EQ(svc_state.data_sources_size(), 3);
4606   EXPECT_EQ(svc_state.data_sources().at(2).ds_descriptor().id(), 2u);
4607   ted = parse_desc(svc_state.data_sources().at(2).ds_descriptor());
4608   EXPECT_EQ(ted.available_categories_size(), 1);
4609   EXPECT_EQ(ted.available_categories()[0].name(), "cat2");
4610 
4611   // Test adding a category to the first data source.
4612   producer2->UpdateTrackEventDataSource({"cat3"}, 1);
4613 
4614   svc_state = consumer->QueryServiceState();
4615 
4616   EXPECT_EQ(svc_state.data_sources_size(), 3);
4617   EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().id(), 1u);
4618   ted = parse_desc(svc_state.data_sources().at(1).ds_descriptor());
4619   EXPECT_EQ(ted.available_categories_size(), 1);
4620   EXPECT_EQ(ted.available_categories()[0].name(), "cat3");
4621 }
4622 
TEST_F(TracingServiceImplTest,LimitSessionsPerUid)4623 TEST_F(TracingServiceImplTest, LimitSessionsPerUid) {
4624   std::vector<std::unique_ptr<MockConsumer>> consumers;
4625 
4626   auto start_new_session = [&](uid_t uid) -> MockConsumer* {
4627     TraceConfig trace_config;
4628     trace_config.add_buffers()->set_size_kb(128);
4629     trace_config.set_duration_ms(0);  // Unlimited.
4630     consumers.emplace_back(CreateMockConsumer());
4631     consumers.back()->Connect(svc.get(), uid);
4632     consumers.back()->EnableTracing(trace_config);
4633     return &*consumers.back();
4634   };
4635 
4636   const int kMaxConcurrentTracingSessionsPerUid = 5;
4637   const int kUids = 2;
4638 
4639   // Create a bunch of legit sessions (2 uids * 5 sessions).
4640   for (int i = 0; i < kMaxConcurrentTracingSessionsPerUid * kUids; i++) {
4641     start_new_session(/*uid=*/static_cast<uid_t>(i) % kUids);
4642   }
4643 
4644   // Any other session now should fail for the two uids.
4645   for (int i = 0; i <= kUids; i++) {
4646     auto* consumer = start_new_session(/*uid=*/static_cast<uid_t>(i) % kUids);
4647     auto on_fail = task_runner.CreateCheckpoint("uid_" + std::to_string(i));
4648     EXPECT_CALL(*consumer, OnTracingDisabled(StrNe("")))
4649         .WillOnce(InvokeWithoutArgs(on_fail));
4650   }
4651 
4652   // Wait for failure (only after both attempts).
4653   for (int i = 0; i <= kUids; i++) {
4654     task_runner.RunUntilCheckpoint("uid_" + std::to_string(i));
4655   }
4656 
4657   // The destruction of |consumers| will tear down and stop the good sessions.
4658 }
4659 
TEST_F(TracingServiceImplTest,ProducerProvidedSMB)4660 TEST_F(TracingServiceImplTest, ProducerProvidedSMB) {
4661   static constexpr size_t kShmSizeBytes = 1024 * 1024;
4662   static constexpr size_t kShmPageSizeBytes = 4 * 1024;
4663 
4664   std::unique_ptr<MockProducer> producer = CreateMockProducer();
4665 
4666   TestSharedMemory::Factory factory;
4667   auto shm = factory.CreateSharedMemory(kShmSizeBytes);
4668   SharedMemory* shm_raw = shm.get();
4669 
4670   // Service should adopt the SMB provided by the producer.
4671   producer->Connect(svc.get(), "mock_producer", /*uid=*/42, /*pid=*/1025,
4672                     /*shared_memory_size_hint_bytes=*/0, kShmPageSizeBytes,
4673                     std::move(shm));
4674   EXPECT_TRUE(producer->endpoint()->IsShmemProvidedByProducer());
4675   EXPECT_NE(producer->endpoint()->MaybeSharedMemoryArbiter(), nullptr);
4676   EXPECT_EQ(producer->endpoint()->shared_memory(), shm_raw);
4677 
4678   producer->WaitForTracingSetup();
4679   producer->RegisterDataSource("data_source");
4680 
4681   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4682   consumer->Connect(svc.get());
4683 
4684   TraceConfig trace_config;
4685   trace_config.add_buffers()->set_size_kb(128);
4686   auto* ds_config = trace_config.add_data_sources()->mutable_config();
4687   ds_config->set_name("data_source");
4688 
4689   consumer->EnableTracing(trace_config);
4690   producer->WaitForDataSourceSetup("data_source");
4691   producer->WaitForDataSourceStart("data_source");
4692 
4693   // Verify that data written to the producer-provided SMB ends up in trace
4694   // buffer correctly.
4695   std::unique_ptr<TraceWriter> writer =
4696       producer->CreateTraceWriter("data_source");
4697   {
4698     auto tp = writer->NewTracePacket();
4699     tp->set_for_testing()->set_str("payload");
4700   }
4701 
4702   auto flush_request = consumer->Flush();
4703   producer->ExpectFlush(writer.get());
4704   ASSERT_TRUE(flush_request.WaitForReply());
4705 
4706   consumer->DisableTracing();
4707   producer->WaitForDataSourceStop("data_source");
4708   consumer->WaitForTracingDisabled();
4709   EXPECT_THAT(consumer->ReadBuffers(),
4710               Contains(Property(
4711                   &protos::gen::TracePacket::for_testing,
4712                   Property(&protos::gen::TestEvent::str, Eq("payload")))));
4713 }
4714 
TEST_F(TracingServiceImplTest,ProducerProvidedSMBInvalidSizes)4715 TEST_F(TracingServiceImplTest, ProducerProvidedSMBInvalidSizes) {
4716   static constexpr size_t kShmSizeBytes = 1024 * 1024;
4717   static constexpr size_t kShmPageSizeBytes = 20 * 1024;
4718 
4719   std::unique_ptr<MockProducer> producer = CreateMockProducer();
4720 
4721   TestSharedMemory::Factory factory;
4722   auto shm = factory.CreateSharedMemory(kShmSizeBytes);
4723 
4724   // Service should not adopt the SMB provided by the producer, because the SMB
4725   // size isn't a multiple of the page size.
4726   producer->Connect(svc.get(), "mock_producer", /*uid=*/42, /*pid=*/1025,
4727                     /*shared_memory_size_hint_bytes=*/0, kShmPageSizeBytes,
4728                     std::move(shm));
4729   EXPECT_FALSE(producer->endpoint()->IsShmemProvidedByProducer());
4730   EXPECT_EQ(producer->endpoint()->shared_memory(), nullptr);
4731 }
4732 
4733 // If the consumer specifies a UUID in the TraceConfig, the TraceUuid packet
4734 // must match that.
TEST_F(TracingServiceImplTest,UuidPacketMatchesConfigUuid)4735 TEST_F(TracingServiceImplTest, UuidPacketMatchesConfigUuid) {
4736   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4737   consumer->Connect(svc.get());
4738   TraceConfig trace_config;
4739   trace_config.set_trace_uuid_lsb(1);
4740   trace_config.set_trace_uuid_msb(2);
4741   trace_config.add_buffers()->set_size_kb(8);
4742   auto* ds_config = trace_config.add_data_sources()->mutable_config();
4743   ds_config->set_name("data_source");
4744 
4745   consumer->EnableTracing(trace_config);
4746   consumer->DisableTracing();
4747   consumer->WaitForTracingDisabled();
4748 
4749   auto packets = consumer->ReadBuffers();
4750 
4751   EXPECT_THAT(
4752       packets,
4753       Contains(Property(&protos::gen::TracePacket::trace_uuid,
4754                         AllOf(Property(&protos::gen::TraceUuid::lsb, Eq(1)),
4755                               Property(&protos::gen::TraceUuid::msb, Eq(2))))));
4756 }
4757 
4758 // If the consumer does not specify any UUID in the TraceConfig, a random
4759 // UUID must be generated and reported in the TraceUuid packet.
TEST_F(TracingServiceImplTest,RandomUuidIfNoConfigUuid)4760 TEST_F(TracingServiceImplTest, RandomUuidIfNoConfigUuid) {
4761   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4762   consumer->Connect(svc.get());
4763   TraceConfig trace_config;
4764   trace_config.add_buffers()->set_size_kb(8);
4765   auto* ds_config = trace_config.add_data_sources()->mutable_config();
4766   ds_config->set_name("data_source");
4767 
4768   consumer->EnableTracing(trace_config);
4769   consumer->DisableTracing();
4770   consumer->WaitForTracingDisabled();
4771 
4772   auto packets = consumer->ReadBuffers();
4773 
4774   EXPECT_THAT(packets,
4775               Contains(Property(
4776                   &protos::gen::TracePacket::trace_uuid,
4777                   Not(AnyOf(Property(&protos::gen::TraceUuid::lsb, Eq(0)),
4778                             Property(&protos::gen::TraceUuid::msb, Eq(0)))))));
4779 }
4780 
TEST_F(TracingServiceImplTest,CloneSession)4781 TEST_F(TracingServiceImplTest, CloneSession) {
4782   // The consumer the creates the initial tracing session.
4783   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4784   consumer->Connect(svc.get());
4785 
4786   // The consumer that clones it and reads back the data.
4787   std::unique_ptr<MockConsumer> consumer2 = CreateMockConsumer();
4788   consumer2->Connect(svc.get());
4789 
4790   std::unique_ptr<MockProducer> producer = CreateMockProducer();
4791   producer->Connect(svc.get(), "mock_producer");
4792 
4793   // Create two data sources, as we'll write on two distinct buffers.
4794   producer->RegisterDataSource("ds_1");
4795   producer->RegisterDataSource("ds_2");
4796 
4797   TraceConfig trace_config;
4798   trace_config.add_buffers()->set_size_kb(32);  // Buf 0.
4799   trace_config.add_buffers()->set_size_kb(32);  // Buf 1.
4800   trace_config.set_trace_uuid_lsb(4242);
4801   trace_config.set_trace_uuid_msb(3737);
4802   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
4803   ds_cfg->set_name("ds_1");
4804   ds_cfg->set_target_buffer(0);
4805   ds_cfg = trace_config.add_data_sources()->mutable_config();
4806   ds_cfg->set_name("ds_2");
4807   ds_cfg->set_target_buffer(1);
4808 
4809   // Add a filter and check that the filter is propagated to the cloned session.
4810   // The filter allows the `for_testing` field but not the root `timestamp`.
4811   protozero::FilterBytecodeGenerator filt;
4812   // Message 0: root Trace proto.
4813   filt.AddNestedField(1 /* root trace.packet*/, 1);
4814   filt.EndMessage();
4815   // Message 1: TracePacket proto. Allow only the `for_testing` and `trace_uuid`
4816   // sub-fields.
4817   filt.AddSimpleField(protos::pbzero::TracePacket::kTraceUuidFieldNumber);
4818   filt.AddSimpleField(protos::pbzero::TracePacket::kForTestingFieldNumber);
4819   filt.EndMessage();
4820   trace_config.mutable_trace_filter()->set_bytecode(filt.Serialize());
4821 
4822   consumer->EnableTracing(trace_config);
4823   producer->WaitForTracingSetup();
4824 
4825   producer->WaitForDataSourceSetup("ds_1");
4826   producer->WaitForDataSourceSetup("ds_2");
4827 
4828   producer->WaitForDataSourceStart("ds_1");
4829   producer->WaitForDataSourceStart("ds_2");
4830 
4831   std::unique_ptr<TraceWriter> writers[] = {
4832       producer->CreateTraceWriter("ds_1"),
4833       producer->CreateTraceWriter("ds_2"),
4834   };
4835 
4836   // Add some data to both buffers.
4837   static constexpr size_t kNumTestPackets = 20;
4838   for (size_t i = 0; i < kNumTestPackets; i++) {
4839     auto tp = writers[i % 1]->NewTracePacket();
4840     std::string payload("payload" + std::to_string(i));
4841     tp->set_for_testing()->set_str(payload.c_str(), payload.size());
4842     tp->set_timestamp(static_cast<uint64_t>(i));
4843   }
4844 
4845   auto clone_done = task_runner.CreateCheckpoint("clone_done");
4846   base::Uuid clone_uuid;
4847   EXPECT_CALL(*consumer2, OnSessionCloned(_))
4848       .WillOnce(Invoke(
4849           [clone_done, &clone_uuid](const Consumer::OnSessionClonedArgs& args) {
4850             ASSERT_TRUE(args.success);
4851             ASSERT_TRUE(args.error.empty());
4852             // Ensure the LSB is preserved, but the MSB is different. See
4853             // comments in tracing_service_impl.cc and perfetto_cmd.cc around
4854             // triggering_subscription_id().
4855             ASSERT_EQ(args.uuid.lsb(), 4242);
4856             ASSERT_NE(args.uuid.msb(), 3737);
4857             clone_uuid = args.uuid;
4858             clone_done();
4859           }));
4860   consumer2->CloneSession(1);
4861   // CloneSession() will implicitly issue a flush. Linearize with that.
4862   producer->ExpectFlush({writers[0].get(), writers[1].get()});
4863   task_runner.RunUntilCheckpoint("clone_done");
4864 
4865   // Overwrite the ring buffer of the original session to check that clone
4866   // actually returns a copy.
4867   for (size_t i = 0; i < 1000; i++) {
4868     auto tp = writers[i % 2]->NewTracePacket();
4869     std::string payload(1000u, 'x');
4870     tp->set_for_testing()->set_str(payload.c_str(), payload.size());
4871   }
4872 
4873   auto flush_request = consumer->Flush();
4874   producer->ExpectFlush({writers[0].get(), writers[1].get()});
4875   ASSERT_TRUE(flush_request.WaitForReply());
4876 
4877   // Delete the initial tracing session.
4878   consumer->DisableTracing();
4879   consumer->FreeBuffers();
4880   producer->WaitForDataSourceStop("ds_1");
4881   producer->WaitForDataSourceStop("ds_2");
4882   consumer->WaitForTracingDisabled();
4883 
4884   // Read back the cloned trace and check the contents.
4885   auto packets = consumer2->ReadBuffers();
4886   for (size_t i = 0; i < kNumTestPackets; i++) {
4887     std::string payload = "payload" + std::to_string(i);
4888     EXPECT_THAT(packets,
4889                 Contains(Property(
4890                     &protos::gen::TracePacket::for_testing,
4891                     Property(&protos::gen::TestEvent::str, Eq(payload)))));
4892   }
4893 
4894   // Check that the "x" payload written after cloning the session is not there.
4895   EXPECT_THAT(packets,
4896               Not(Contains(Property(&protos::gen::TracePacket::for_testing,
4897                                     Property(&protos::gen::TestEvent::str,
4898                                              testing::StartsWith("x"))))));
4899 
4900   // Check that the `timestamp` field is filtered out.
4901   EXPECT_THAT(packets,
4902               Each(Property(&protos::gen::TracePacket::has_timestamp, false)));
4903 
4904   // Check that the UUID in the trace matches the UUID passed to to the
4905   // OnCloneSession consumer API.
4906   EXPECT_THAT(
4907       packets,
4908       Contains(Property(
4909           &protos::gen::TracePacket::trace_uuid,
4910           AllOf(
4911               Property(&protos::gen::TraceUuid::msb, Eq(clone_uuid.msb())),
4912               Property(&protos::gen::TraceUuid::lsb, Eq(clone_uuid.lsb()))))));
4913 }
4914 
4915 // Test that a consumer cannot clone a session from a consumer with a different
4916 // uid (unless it's marked as eligible for bugreport, see next test).
TEST_F(TracingServiceImplTest,CloneSessionAcrossUidDenied)4917 TEST_F(TracingServiceImplTest, CloneSessionAcrossUidDenied) {
4918   // The consumer the creates the initial tracing session.
4919   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4920   consumer->Connect(svc.get());
4921 
4922   // The consumer that clones it and reads back the data.
4923   std::unique_ptr<MockConsumer> consumer2 = CreateMockConsumer();
4924   consumer2->Connect(svc.get(), 1234);
4925 
4926   TraceConfig trace_config;
4927   trace_config.add_buffers()->set_size_kb(32);
4928 
4929   consumer->EnableTracing(trace_config);
4930   auto flush_request = consumer->Flush();
4931   ASSERT_TRUE(flush_request.WaitForReply());
4932 
4933   auto clone_done = task_runner.CreateCheckpoint("clone_done");
4934   EXPECT_CALL(*consumer2, OnSessionCloned(_))
4935       .WillOnce(Invoke([clone_done](const Consumer::OnSessionClonedArgs& args) {
4936         clone_done();
4937         ASSERT_FALSE(args.success);
4938         ASSERT_TRUE(base::Contains(args.error, "session from another UID"));
4939       }));
4940   consumer2->CloneSession(1);
4941   task_runner.RunUntilCheckpoint("clone_done");
4942 }
4943 
4944 // Test that a consumer can clone a session from the shell uid if the trace is
4945 // marked as eligible for bugreport. Android only.
4946 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
TEST_F(TracingServiceImplTest,CloneSessionAcrossUidForBugreport)4947 TEST_F(TracingServiceImplTest, CloneSessionAcrossUidForBugreport) {
4948   // The consumer the creates the initial tracing session.
4949   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4950   consumer->Connect(svc.get());
4951 
4952   std::unique_ptr<MockProducer> producer = CreateMockProducer();
4953   producer->Connect(svc.get(), "mock_producer");
4954   producer->RegisterDataSource("ds_1");
4955 
4956   // The consumer that clones it and reads back the data.
4957   std::unique_ptr<MockConsumer> clone_consumer = CreateMockConsumer();
4958   clone_consumer->Connect(svc.get(), AID_SHELL);
4959 
4960   TraceConfig trace_config;
4961   trace_config.add_buffers()->set_size_kb(32);
4962   trace_config.set_bugreport_score(1);
4963   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
4964 
4965   // Add a trace filter and ensure it's ignored for bugreports (b/317065412).
4966   protozero::FilterBytecodeGenerator filt;
4967   filt.AddNestedField(1 /* root trace.packet*/, 1);
4968   filt.EndMessage();
4969   // Add a random field to keep the generator happy. This technically still
4970   // filters out the for_testing packet that we are using below.
4971   filt.AddSimpleField(protos::pbzero::TracePacket::kTraceUuidFieldNumber);
4972   filt.EndMessage();
4973   trace_config.mutable_trace_filter()->set_bytecode_v2(filt.Serialize());
4974 
4975   consumer->EnableTracing(trace_config);
4976   producer->WaitForTracingSetup();
4977   producer->WaitForDataSourceSetup("ds_1");
4978   producer->WaitForDataSourceStart("ds_1");
4979   std::unique_ptr<TraceWriter> writer = producer->CreateTraceWriter("ds_1");
4980   writer->NewTracePacket()->set_for_testing()->set_str("payload");
4981   writer.reset();
4982 
4983   auto flush_request = consumer->Flush();
4984   FlushFlags flush_flags(FlushFlags::Initiator::kConsumerSdk,
4985                          FlushFlags::Reason::kExplicit);
4986   producer->ExpectFlush({}, /*reply=*/true, flush_flags);
4987   ASSERT_TRUE(flush_request.WaitForReply());
4988 
4989   auto clone_done = task_runner.CreateCheckpoint("clone_done");
4990   EXPECT_CALL(*clone_consumer, OnSessionCloned(_))
4991       .WillOnce(Invoke([clone_done](const Consumer::OnSessionClonedArgs& args) {
4992         clone_done();
4993         ASSERT_TRUE(args.success);
4994       }));
4995 
4996   FlushFlags flush_flags2(FlushFlags::Initiator::kTraced,
4997                           FlushFlags::Reason::kTraceClone,
4998                           FlushFlags::CloneTarget::kBugreport);
4999   producer->ExpectFlush({}, /*reply=*/true, flush_flags2);
5000 
5001   clone_consumer->CloneSession(kBugreportSessionId);
5002   task_runner.RunUntilCheckpoint("clone_done");
5003 
5004   auto packets = clone_consumer->ReadBuffers();
5005   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
5006                                          Property(&protos::gen::TestEvent::str,
5007                                                   HasSubstr("payload")))));
5008 }
5009 #endif  // OS_ANDROID
5010 
TEST_F(TracingServiceImplTest,TransferOnClone)5011 TEST_F(TracingServiceImplTest, TransferOnClone) {
5012   // The consumer the creates the initial tracing session.
5013   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5014   consumer->Connect(svc.get());
5015 
5016   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5017   producer->Connect(svc.get(), "mock_producer");
5018 
5019   // Create two data sources, as we'll write on two distinct buffers.
5020   producer->RegisterDataSource("ds_1");
5021   producer->RegisterDataSource("ds_2");
5022 
5023   TraceConfig trace_config;
5024   trace_config.add_buffers()->set_size_kb(1024);  // Buf 0.
5025   auto* buf1_cfg = trace_config.add_buffers();    // Buf 1 (transfer_on_clone).
5026   buf1_cfg->set_size_kb(1024);
5027   buf1_cfg->set_transfer_on_clone(true);
5028   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5029   ds_cfg->set_name("ds_1");
5030   ds_cfg->set_target_buffer(0);
5031   ds_cfg = trace_config.add_data_sources()->mutable_config();
5032   ds_cfg->set_name("ds_2");
5033   ds_cfg->set_target_buffer(1);
5034 
5035   consumer->EnableTracing(trace_config);
5036   producer->WaitForTracingSetup();
5037 
5038   producer->WaitForDataSourceSetup("ds_1");
5039   producer->WaitForDataSourceSetup("ds_2");
5040 
5041   producer->WaitForDataSourceStart("ds_1");
5042   producer->WaitForDataSourceStart("ds_2");
5043 
5044   std::unique_ptr<TraceWriter> writers[] = {
5045       producer->CreateTraceWriter("ds_1"),
5046       producer->CreateTraceWriter("ds_2"),
5047   };
5048 
5049   // Write once in the first buffer. This is expected persist across clones.
5050   static constexpr int kNumTestPackets = 10;
5051   for (int n = 0; n < kNumTestPackets; n++) {
5052     auto tp = writers[0]->NewTracePacket();
5053     base::StackString<64> payload("persistent_%d", n);
5054     tp->set_for_testing()->set_str(payload.c_str(), payload.len());
5055   }
5056 
5057   const int kLastIteration = 3;
5058   for (int iteration = 1; iteration <= kLastIteration; iteration++) {
5059     // The consumer the creates the initial tracing session.
5060     std::unique_ptr<MockConsumer> clone_consumer = CreateMockConsumer();
5061     clone_consumer->Connect(svc.get());
5062 
5063     // Add some new data to the 2nd buffer, which is transferred.
5064     // Omit the writing the last iteration to test we get an empty buffer.
5065     for (int n = 0; n < kNumTestPackets && iteration != kLastIteration; n++) {
5066       auto tp = writers[1]->NewTracePacket();
5067       base::StackString<64> payload("transferred_%d_%d", iteration, n);
5068       tp->set_for_testing()->set_str(payload.c_str(), payload.len());
5069     }
5070 
5071     std::string clone_checkpoint_name = "clone_" + std::to_string(iteration);
5072     auto clone_done = task_runner.CreateCheckpoint(clone_checkpoint_name);
5073     base::Uuid clone_uuid;
5074     EXPECT_CALL(*clone_consumer, OnSessionCloned(_))
5075         .WillOnce(InvokeWithoutArgs(clone_done));
5076     clone_consumer->CloneSession(1);
5077 
5078     // CloneSession() will implicitly issue a flush. Linearize with that.
5079     EXPECT_CALL(
5080         *producer,
5081         Flush(_, Pointee(producer->GetDataSourceInstanceId("ds_1")), 1, _))
5082         .WillOnce(Invoke([&](FlushRequestID flush_req_id,
5083                              const DataSourceInstanceID*, size_t, FlushFlags) {
5084           writers[0]->Flush();
5085           producer->endpoint()->NotifyFlushComplete(flush_req_id);
5086         }));
5087     EXPECT_CALL(
5088         *producer,
5089         Flush(_, Pointee(producer->GetDataSourceInstanceId("ds_2")), 1, _))
5090         .WillOnce(Invoke([&](FlushRequestID flush_req_id,
5091                              const DataSourceInstanceID*, size_t, FlushFlags) {
5092           writers[1]->Flush();
5093           producer->endpoint()->NotifyFlushComplete(flush_req_id);
5094         }));
5095     task_runner.RunUntilCheckpoint(clone_checkpoint_name);
5096 
5097     auto packets = clone_consumer->ReadBuffers();
5098     std::vector<std::string> actual_payloads;
5099     for (const auto& packet : packets) {
5100       if (packet.has_for_testing())
5101         actual_payloads.emplace_back(packet.for_testing().str());
5102     }
5103     std::vector<std::string> expected_payloads;
5104     for (int n = 0; n < kNumTestPackets; n++) {
5105       base::StackString<64> expected_payload("persistent_%d", n);
5106       expected_payloads.emplace_back(expected_payload.ToStdString());
5107     }
5108     for (int n = 0; n < kNumTestPackets && iteration != kLastIteration; n++) {
5109       base::StackString<64> expected_payload("transferred_%d_%d", iteration, n);
5110       expected_payloads.emplace_back(expected_payload.ToStdString());
5111     }
5112     ASSERT_THAT(actual_payloads, ElementsAreArray(expected_payloads));
5113   }  // for (iteration)
5114 
5115   consumer->DisableTracing();
5116   producer->WaitForDataSourceStop("ds_1");
5117   producer->WaitForDataSourceStop("ds_2");
5118   consumer->WaitForTracingDisabled();
5119 
5120   // Read the data from the primary (non-cloned) tracing session. Check that
5121   // it doesn't have any "transferred_xxx" payload but only the "persistent_xxx"
5122   // coming from the standard non-transferred buffer.
5123   auto packets = consumer->ReadBuffers();
5124   EXPECT_THAT(packets,
5125               Not(Contains(Property(&protos::gen::TracePacket::for_testing,
5126                                     Property(&protos::gen::TestEvent::str,
5127                                              HasSubstr("transferred_"))))));
5128   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
5129                                          Property(&protos::gen::TestEvent::str,
5130                                                   HasSubstr("persistent_")))));
5131 }
5132 
TEST_F(TracingServiceImplTest,ClearBeforeClone)5133 TEST_F(TracingServiceImplTest, ClearBeforeClone) {
5134   // The consumer that creates the initial tracing session.
5135   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5136   consumer->Connect(svc.get());
5137 
5138   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5139   producer->Connect(svc.get(), "mock_producer");
5140 
5141   producer->RegisterDataSource("ds_1");
5142 
5143   TraceConfig trace_config;
5144   // Unused. This buffer is created only to make the test less trivial and cover
5145   // the case of the clear-bufferd to be the beyond the 0th entry.
5146   trace_config.add_buffers()->set_size_kb(32);
5147 
5148   auto* buf_cfg = trace_config.add_buffers();
5149   buf_cfg->set_size_kb(1024);
5150   buf_cfg->set_clear_before_clone(true);
5151   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5152   ds_cfg->set_name("ds_1");
5153   ds_cfg->set_target_buffer(1);
5154 
5155   consumer->EnableTracing(trace_config);
5156   producer->WaitForTracingSetup();
5157   producer->WaitForDataSourceSetup("ds_1");
5158   producer->WaitForDataSourceStart("ds_1");
5159 
5160   std::unique_ptr<TraceWriter> writer = producer->CreateTraceWriter("ds_1");
5161 
5162   // These packets, emitted before the clone, should be dropped.
5163   for (int i = 0; i < 3; i++) {
5164     writer->NewTracePacket()->set_for_testing()->set_str("before_clone");
5165   }
5166   auto flush_request = consumer->Flush();
5167   producer->ExpectFlush(writer.get());
5168   ASSERT_TRUE(flush_request.WaitForReply());
5169 
5170   // The consumer the creates the initial tracing session.
5171   std::unique_ptr<MockConsumer> clone_consumer = CreateMockConsumer();
5172   clone_consumer->Connect(svc.get());
5173 
5174   auto clone_done = task_runner.CreateCheckpoint("clone_done");
5175   EXPECT_CALL(*clone_consumer, OnSessionCloned(_))
5176       .WillOnce(InvokeWithoutArgs(clone_done));
5177   clone_consumer->CloneSession(1);
5178 
5179   // CloneSession() will implicitly issue a flush. Write some other packets
5180   // in that callback. Those are the only ones that should survive in the cloned
5181   // session.
5182   FlushFlags flush_flags(FlushFlags::Initiator::kTraced,
5183                          FlushFlags::Reason::kTraceClone);
5184   EXPECT_CALL(*producer, Flush(_, _, _, flush_flags))
5185       .WillOnce(Invoke([&](FlushRequestID flush_req_id,
5186                            const DataSourceInstanceID*, size_t, FlushFlags) {
5187         writer->NewTracePacket()->set_for_testing()->set_str("after_clone");
5188         writer->Flush(
5189             [&] { producer->endpoint()->NotifyFlushComplete(flush_req_id); });
5190       }));
5191 
5192   task_runner.RunUntilCheckpoint("clone_done");
5193 
5194   auto packets = clone_consumer->ReadBuffers();
5195   EXPECT_THAT(packets,
5196               Not(Contains(Property(&protos::gen::TracePacket::for_testing,
5197                                     Property(&protos::gen::TestEvent::str,
5198                                              HasSubstr("before_clone"))))));
5199   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
5200                                          Property(&protos::gen::TestEvent::str,
5201                                                   HasSubstr("after_clone")))));
5202 }
5203 
TEST_F(TracingServiceImplTest,CloneMainSessionStopped)5204 TEST_F(TracingServiceImplTest, CloneMainSessionStopped) {
5205   // The consumer that creates the initial tracing session.
5206   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5207   consumer->Connect(svc.get());
5208 
5209   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5210   producer->Connect(svc.get(), "mock_producer1");
5211   producer->RegisterDataSource("ds_1");
5212 
5213   TraceConfig trace_config;
5214   trace_config.add_buffers()->set_size_kb(1024);  // Buf 0.
5215   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5216   ds_cfg->set_name("ds_1");
5217   ds_cfg->set_target_buffer(0);
5218 
5219   consumer->EnableTracing(trace_config);
5220   producer->WaitForTracingSetup();
5221   producer->WaitForDataSourceSetup("ds_1");
5222   producer->WaitForDataSourceStart("ds_1");
5223 
5224   std::unique_ptr<TraceWriter> writer = producer->CreateTraceWriter("ds_1");
5225   {
5226     auto packet = writer->NewTracePacket();
5227     packet->set_for_testing()->set_str("before_clone");
5228   }
5229   writer->Flush();
5230 
5231   consumer->DisableTracing();
5232   producer->WaitForDataSourceStop("ds_1");
5233   consumer->WaitForTracingDisabled();
5234 
5235   // The tracing session is disabled, but it's still there. We can still clone
5236   // it.
5237   std::unique_ptr<MockConsumer> clone_consumer = CreateMockConsumer();
5238   clone_consumer->Connect(svc.get());
5239 
5240   auto clone_done = task_runner.CreateCheckpoint("clone_done");
5241   EXPECT_CALL(*clone_consumer, OnSessionCloned(_))
5242       .WillOnce(InvokeWithoutArgs(clone_done));
5243   clone_consumer->CloneSession(1);
5244 
5245   auto packets = clone_consumer->ReadBuffers();
5246   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
5247                                          Property(&protos::gen::TestEvent::str,
5248                                                   HasSubstr("before_clone")))));
5249 }
5250 
TEST_F(TracingServiceImplTest,CloneConsumerDisconnect)5251 TEST_F(TracingServiceImplTest, CloneConsumerDisconnect) {
5252   // The consumer that creates the initial tracing session.
5253   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5254   consumer->Connect(svc.get());
5255 
5256   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5257   producer->Connect(svc.get(), "mock_producer1");
5258   producer->RegisterDataSource("ds_1");
5259 
5260   TraceConfig trace_config;
5261   trace_config.add_buffers()->set_size_kb(1024);  // Buf 0.
5262   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5263   ds_cfg->set_name("ds_1");
5264   ds_cfg->set_target_buffer(0);
5265 
5266   consumer->EnableTracing(trace_config);
5267   producer->WaitForTracingSetup();
5268   producer->WaitForDataSourceSetup("ds_1");
5269   producer->WaitForDataSourceStart("ds_1");
5270 
5271   std::unique_ptr<TraceWriter> writer1 = producer->CreateTraceWriter("ds_1");
5272 
5273   std::unique_ptr<MockConsumer> clone_consumer = CreateMockConsumer();
5274   clone_consumer->Connect(svc.get());
5275 
5276   // CloneSession() will issue a flush.
5277   std::string producer1_flush_checkpoint_name = "producer1_flush_requested";
5278   FlushRequestID flush1_req_id;
5279   auto flush1_requested =
5280       task_runner.CreateCheckpoint(producer1_flush_checkpoint_name);
5281   EXPECT_CALL(*producer, Flush(_, _, _, _))
5282       .WillOnce([&](FlushRequestID req_id, const DataSourceInstanceID*, size_t,
5283                     FlushFlags) {
5284         flush1_req_id = req_id;
5285         flush1_requested();
5286       });
5287   clone_consumer->CloneSession(1);
5288 
5289   task_runner.RunUntilCheckpoint(producer1_flush_checkpoint_name);
5290 
5291   // producer hasn't replied to the flush yet, so the clone operation is still
5292   // pending.
5293 
5294   // The clone_consumer disconnect and goes away.
5295   clone_consumer.reset();
5296 
5297   // producer replies to the flush request now.
5298   writer1->Flush();
5299   producer->endpoint()->NotifyFlushComplete(flush1_req_id);
5300   task_runner.RunUntilIdle();
5301 
5302   consumer->DisableTracing();
5303   producer->WaitForDataSourceStop("ds_1");
5304   consumer->WaitForTracingDisabled();
5305 }
5306 
TEST_F(TracingServiceImplTest,CloneMainSessionGoesAwayDuringFlush)5307 TEST_F(TracingServiceImplTest, CloneMainSessionGoesAwayDuringFlush) {
5308   // The consumer that creates the initial tracing session.
5309   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5310   consumer->Connect(svc.get());
5311 
5312   std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
5313   producer1->Connect(svc.get(), "mock_producer1");
5314   producer1->RegisterDataSource("ds_1");
5315 
5316   TraceConfig trace_config;
5317   trace_config.add_buffers()->set_size_kb(1024);  // Buf 0.
5318   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5319   ds_cfg->set_name("ds_1");
5320   ds_cfg->set_target_buffer(0);
5321 
5322   consumer->EnableTracing(trace_config);
5323   producer1->WaitForTracingSetup();
5324   producer1->WaitForDataSourceSetup("ds_1");
5325   producer1->WaitForDataSourceStart("ds_1");
5326 
5327   std::unique_ptr<TraceWriter> writer1 = producer1->CreateTraceWriter("ds_1");
5328 
5329   {
5330     auto tp = writer1->NewTracePacket();
5331     tp->set_for_testing()->set_str("buf1_beforeflush");
5332   }
5333   writer1->Flush();
5334 
5335   std::unique_ptr<MockConsumer> clone_consumer = CreateMockConsumer();
5336   clone_consumer->Connect(svc.get());
5337 
5338   EXPECT_CALL(*clone_consumer, OnSessionCloned)
5339       .Times(1)
5340       .WillOnce(Invoke([](const Consumer::OnSessionClonedArgs& args) {
5341         EXPECT_FALSE(args.success);
5342         EXPECT_THAT(args.error, HasSubstr("Original session ended"));
5343       }));
5344   clone_consumer->CloneSession(1);
5345 
5346   std::string producer1_flush_checkpoint_name = "producer1_flush_requested";
5347   auto flush1_requested =
5348       task_runner.CreateCheckpoint(producer1_flush_checkpoint_name);
5349   FlushRequestID flush1_req_id;
5350 
5351   // CloneSession() will issue a flush.
5352   EXPECT_CALL(*producer1, Flush(_, _, _, _))
5353       .WillOnce([&](FlushRequestID flush_id, const DataSourceInstanceID*,
5354                     size_t, FlushFlags) {
5355         flush1_req_id = flush_id;
5356         flush1_requested();
5357       });
5358 
5359   task_runner.RunUntilCheckpoint(producer1_flush_checkpoint_name);
5360 
5361   // The main session goes away.
5362   consumer->DisableTracing();
5363   producer1->WaitForDataSourceStop("ds_1");
5364   consumer->WaitForTracingDisabled();
5365   consumer.reset();
5366 
5367   // producer1 replies to flush much later.
5368   producer1->endpoint()->NotifyFlushComplete(flush1_req_id);
5369   task_runner.RunUntilIdle();
5370 }
5371 
TEST_F(TracingServiceImplTest,CloneTransferFlush)5372 TEST_F(TracingServiceImplTest, CloneTransferFlush) {
5373   // The consumer the creates the initial tracing session.
5374   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5375   consumer->Connect(svc.get());
5376 
5377   std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
5378   producer1->Connect(svc.get(), "mock_producer1");
5379   producer1->RegisterDataSource("ds_1");
5380 
5381   std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
5382   producer2->Connect(svc.get(), "mock_producer2");
5383   producer2->RegisterDataSource("ds_2");
5384 
5385   TraceConfig trace_config;
5386   trace_config.add_buffers()->set_size_kb(1024);  // Buf 0.
5387   auto* buf1_cfg = trace_config.add_buffers();    // Buf 1 (transfer_on_clone).
5388   buf1_cfg->set_size_kb(1024);
5389   buf1_cfg->set_transfer_on_clone(true);
5390   buf1_cfg->set_clear_before_clone(true);
5391   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5392   ds_cfg->set_name("ds_1");
5393   ds_cfg->set_target_buffer(0);
5394   ds_cfg = trace_config.add_data_sources()->mutable_config();
5395   ds_cfg->set_name("ds_2");
5396   ds_cfg->set_target_buffer(1);
5397 
5398   consumer->EnableTracing(trace_config);
5399   producer1->WaitForTracingSetup();
5400   producer1->WaitForDataSourceSetup("ds_1");
5401 
5402   producer2->WaitForTracingSetup();
5403   producer2->WaitForDataSourceSetup("ds_2");
5404 
5405   producer1->WaitForDataSourceStart("ds_1");
5406   producer2->WaitForDataSourceStart("ds_2");
5407 
5408   std::unique_ptr<TraceWriter> writer1 = producer1->CreateTraceWriter("ds_1");
5409   std::unique_ptr<TraceWriter> writer2 = producer2->CreateTraceWriter("ds_2");
5410 
5411   {
5412     auto tp = writer1->NewTracePacket();
5413     tp->set_for_testing()->set_str("buf1_beforeflush");
5414   }
5415 
5416   {
5417     std::unique_ptr<MockConsumer> clone_consumer = CreateMockConsumer();
5418     clone_consumer->Connect(svc.get());
5419 
5420     {
5421       auto tp = writer2->NewTracePacket();
5422       tp->set_for_testing()->set_str("buf2_beforeflush");
5423     }
5424 
5425     std::string clone_checkpoint_name = "clone";
5426     auto clone_done = task_runner.CreateCheckpoint(clone_checkpoint_name);
5427     EXPECT_CALL(*clone_consumer, OnSessionCloned(_))
5428         .WillOnce(InvokeWithoutArgs(clone_done));
5429     clone_consumer->CloneSession(1);
5430 
5431     std::string producer1_flush_checkpoint_name = "producer1_flush_requested";
5432     FlushRequestID flush1_req_id;
5433     auto flush1_requested =
5434         task_runner.CreateCheckpoint(producer1_flush_checkpoint_name);
5435     std::string producer2_flush_checkpoint_name = "producer2_flush_requested";
5436     FlushRequestID flush2_req_id;
5437     auto flush2_requested =
5438         task_runner.CreateCheckpoint(producer2_flush_checkpoint_name);
5439 
5440     // CloneSession() will issue a flush.
5441     EXPECT_CALL(*producer1, Flush(_, _, _, _))
5442         .WillOnce([&](FlushRequestID req_id, const DataSourceInstanceID*,
5443                       size_t, FlushFlags) {
5444           flush1_req_id = req_id;
5445           flush1_requested();
5446         });
5447     EXPECT_CALL(*producer2, Flush(_, _, _, _))
5448         .WillOnce([&](FlushRequestID req_id, const DataSourceInstanceID*,
5449                       size_t, FlushFlags) {
5450           flush2_req_id = req_id;
5451           flush2_requested();
5452         });
5453 
5454     task_runner.RunUntilCheckpoint(producer1_flush_checkpoint_name);
5455     task_runner.RunUntilCheckpoint(producer2_flush_checkpoint_name);
5456 
5457     // producer1 is fast and replies to the Flush request immediately.
5458     writer1->Flush();
5459     producer1->endpoint()->NotifyFlushComplete(flush1_req_id);
5460     task_runner.RunUntilIdle();
5461 
5462     // producer1 writes another packet, after acking the flush.
5463     {
5464       auto tp = writer1->NewTracePacket();
5465       tp->set_for_testing()->set_str("buf1_afterflush");
5466     }
5467     writer1->Flush();
5468 
5469     // producer2 is slower and is still writing data.
5470     {
5471       auto tp = writer2->NewTracePacket();
5472       tp->set_for_testing()->set_str("buf2_afterflush");
5473     }
5474 
5475     // now producer2 replies to the Flush request.
5476     writer2->Flush();
5477     producer2->endpoint()->NotifyFlushComplete(flush2_req_id);
5478     task_runner.RunUntilCheckpoint(clone_checkpoint_name);
5479 
5480     auto packets = clone_consumer->ReadBuffers();
5481     std::vector<std::string> actual_payloads;
5482     for (const auto& packet : packets) {
5483       if (packet.has_for_testing())
5484         actual_payloads.emplace_back(packet.for_testing().str());
5485     }
5486     EXPECT_THAT(actual_payloads, Contains("buf1_beforeflush"));
5487     EXPECT_THAT(actual_payloads, Contains("buf2_beforeflush"));
5488     // This packet was sent after producer1 acked the flush. producer2 hadn't
5489     // acked the flush yet, but producer2's buffer is on a separate flush group.
5490     EXPECT_THAT(actual_payloads, Not(Contains("buf1_afterflush")));
5491     EXPECT_THAT(actual_payloads, Contains("buf2_afterflush"));
5492   }
5493 
5494   consumer->DisableTracing();
5495   producer1->WaitForDataSourceStop("ds_1");
5496   producer2->WaitForDataSourceStop("ds_2");
5497   consumer->WaitForTracingDisabled();
5498 }
5499 
TEST_F(TracingServiceImplTest,InvalidBufferSizes)5500 TEST_F(TracingServiceImplTest, InvalidBufferSizes) {
5501   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5502   consumer->Connect(svc.get());
5503 
5504   TraceConfig trace_config;
5505   trace_config.add_buffers()->set_size_kb(128);
5506   trace_config.add_buffers()->set_size_kb(256);
5507   trace_config.add_buffers()->set_size_kb(4 * 1024 * 1024);
5508   auto* ds = trace_config.add_data_sources();
5509   auto* ds_config = ds->mutable_config();
5510   ds_config->set_name("data_source");
5511   consumer->EnableTracing(trace_config);
5512 
5513   std::string error;
5514   auto checkpoint = task_runner.CreateCheckpoint("tracing_disabled");
5515   EXPECT_CALL(*consumer, OnTracingDisabled(_))
5516       .WillOnce(DoAll(SaveArg<0>(&error), checkpoint));
5517   task_runner.RunUntilCheckpoint("tracing_disabled");
5518   EXPECT_THAT(error, HasSubstr("Invalid buffer sizes"));
5519 }
5520 
TEST_F(TracingServiceImplTest,StringFiltering)5521 TEST_F(TracingServiceImplTest, StringFiltering) {
5522   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5523   consumer->Connect(svc.get());
5524 
5525   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5526   producer->Connect(svc.get(), "mock_producer");
5527 
5528   producer->RegisterDataSource("ds_1");
5529 
5530   TraceConfig trace_config;
5531   trace_config.add_buffers()->set_size_kb(32);  // Buf 0.
5532   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5533   ds_cfg->set_name("ds_1");
5534   ds_cfg->set_target_buffer(0);
5535 
5536   protozero::FilterBytecodeGenerator filt;
5537   // Message 0: root Trace proto.
5538   filt.AddNestedField(1 /* root trace.packet*/, 1);
5539   filt.EndMessage();
5540   // Message 1: TracePacket proto. Allow only the `for_testing` sub-field.
5541   filt.AddNestedField(protos::pbzero::TracePacket::kForTestingFieldNumber, 2);
5542   filt.EndMessage();
5543   // Message 2: TestEvent proto. Allow only the `str` sub-field as a striong.
5544   filt.AddFilterStringField(protos::pbzero::TestEvent::kStrFieldNumber);
5545   filt.EndMessage();
5546   trace_config.mutable_trace_filter()->set_bytecode_v2(filt.Serialize());
5547 
5548   auto* chain =
5549       trace_config.mutable_trace_filter()->mutable_string_filter_chain();
5550   auto* rule = chain->add_rules();
5551   rule->set_policy(
5552       protos::gen::TraceConfig::TraceFilter::SFP_ATRACE_MATCH_REDACT_GROUPS);
5553   rule->set_atrace_payload_starts_with("payload1");
5554   rule->set_regex_pattern(R"(B\|\d+\|pay(lo)ad1(\d*))");
5555 
5556   consumer->EnableTracing(trace_config);
5557   producer->WaitForTracingSetup();
5558 
5559   producer->WaitForDataSourceSetup("ds_1");
5560   producer->WaitForDataSourceStart("ds_1");
5561 
5562   std::unique_ptr<TraceWriter> writer = producer->CreateTraceWriter("ds_1");
5563   static constexpr size_t kNumTestPackets = 20;
5564   for (size_t i = 0; i < kNumTestPackets; i++) {
5565     auto tp = writer->NewTracePacket();
5566     std::string payload("B|1023|payload" + std::to_string(i));
5567     tp->set_for_testing()->set_str(payload.c_str(), payload.size());
5568   }
5569 
5570   auto flush_request = consumer->Flush();
5571   producer->ExpectFlush(writer.get());
5572   ASSERT_TRUE(flush_request.WaitForReply());
5573 
5574   const DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_1");
5575   EXPECT_CALL(*producer, StopDataSource(id1));
5576 
5577   consumer->DisableTracing();
5578   consumer->WaitForTracingDisabled();
5579 
5580   auto packets = consumer->ReadBuffers();
5581   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
5582                                          Property(&protos::gen::TestEvent::str,
5583                                                   Eq("B|1023|payP6ad1")))));
5584   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
5585                                          Property(&protos::gen::TestEvent::str,
5586                                                   Eq("B|1023|payP6ad1P")))));
5587 }
5588 
TEST_F(TracingServiceImplTest,StringFilteringAndCloneSession)5589 TEST_F(TracingServiceImplTest, StringFilteringAndCloneSession) {
5590   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5591   consumer->Connect(svc.get());
5592 
5593   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5594   producer->Connect(svc.get(), "mock_producer");
5595 
5596   producer->RegisterDataSource("ds_1");
5597 
5598   TraceConfig trace_config;
5599   trace_config.add_buffers()->set_size_kb(32);  // Buf 0.
5600   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5601   ds_cfg->set_name("ds_1");
5602   ds_cfg->set_target_buffer(0);
5603 
5604   protozero::FilterBytecodeGenerator filt;
5605   // Message 0: root Trace proto.
5606   filt.AddNestedField(1 /* root trace.packet*/, 1);
5607   filt.EndMessage();
5608   // Message 1: TracePacket proto. Allow only the `for_testing` sub-field.
5609   filt.AddNestedField(protos::pbzero::TracePacket::kForTestingFieldNumber, 2);
5610   filt.EndMessage();
5611   // Message 2: TestEvent proto. Allow only the `str` sub-field as a string.
5612   filt.AddFilterStringField(protos::pbzero::TestEvent::kStrFieldNumber);
5613   filt.EndMessage();
5614   trace_config.mutable_trace_filter()->set_bytecode_v2(filt.Serialize());
5615 
5616   auto* chain =
5617       trace_config.mutable_trace_filter()->mutable_string_filter_chain();
5618   auto* rule = chain->add_rules();
5619   rule->set_policy(
5620       protos::gen::TraceConfig::TraceFilter::SFP_ATRACE_MATCH_REDACT_GROUPS);
5621   rule->set_atrace_payload_starts_with("payload");
5622   rule->set_regex_pattern(R"(B\|\d+\|pay(lo)ad(\d*))");
5623 
5624   consumer->EnableTracing(trace_config);
5625   producer->WaitForTracingSetup();
5626 
5627   producer->WaitForDataSourceSetup("ds_1");
5628   producer->WaitForDataSourceStart("ds_1");
5629 
5630   std::unique_ptr<TraceWriter> writer = producer->CreateTraceWriter("ds_1");
5631 
5632   {
5633     auto tp = writer->NewTracePacket();
5634     tp->set_for_testing()->set_str("B|1023|payload");
5635   }
5636 
5637   std::unique_ptr<MockConsumer> consumer2 = CreateMockConsumer();
5638   consumer2->Connect(svc.get());
5639 
5640   auto clone_done = task_runner.CreateCheckpoint("clone_done");
5641   EXPECT_CALL(*consumer2, OnSessionCloned(_))
5642       .WillOnce(Invoke([clone_done](const Consumer::OnSessionClonedArgs&) {
5643         clone_done();
5644       }));
5645   consumer2->CloneSession(1);
5646   // CloneSession() will implicitly issue a flush. Linearize with that.
5647   producer->ExpectFlush(std::vector<TraceWriter*>{writer.get()});
5648   task_runner.RunUntilCheckpoint("clone_done");
5649 
5650   const DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_1");
5651   EXPECT_CALL(*producer, StopDataSource(id1));
5652 
5653   consumer->DisableTracing();
5654   consumer->WaitForTracingDisabled();
5655 
5656   auto packets = consumer->ReadBuffers();
5657   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
5658                                          Property(&protos::gen::TestEvent::str,
5659                                                   Eq("B|1023|payP6ad")))));
5660   EXPECT_THAT(packets,
5661               Not(Contains(Property(&protos::gen::TracePacket::for_testing,
5662                                     Property(&protos::gen::TestEvent::str,
5663                                              Eq("B|1023|payload"))))));
5664 
5665   auto cloned_packets = consumer2->ReadBuffers();
5666   EXPECT_THAT(cloned_packets,
5667               Contains(Property(&protos::gen::TracePacket::for_testing,
5668                                 Property(&protos::gen::TestEvent::str,
5669                                          Eq("B|1023|payP6ad")))));
5670   EXPECT_THAT(cloned_packets,
5671               Not(Contains(Property(&protos::gen::TracePacket::for_testing,
5672                                     Property(&protos::gen::TestEvent::str,
5673                                              Eq("B|1023|payload"))))));
5674 }
5675 
5676 // This is a regression test for https://b.corp.google.com/issues/307601836. The
5677 // test covers the case of a consumer disconnecting while the tracing session is
5678 // executing the final flush.
TEST_F(TracingServiceImplTest,ConsumerDisconnectionRacesFlushAndDisable)5679 TEST_F(TracingServiceImplTest, ConsumerDisconnectionRacesFlushAndDisable) {
5680   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5681   consumer->Connect(svc.get());
5682 
5683   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5684   producer->Connect(svc.get(), "mock_producer");
5685 
5686   producer->RegisterDataSource("ds");
5687 
5688   TraceConfig trace_config;
5689   trace_config.add_buffers()->set_size_kb(128);
5690   auto* trigger_config = trace_config.mutable_trigger_config();
5691   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
5692   trigger_config->set_trigger_timeout_ms(100000);
5693   auto* trigger = trigger_config->add_triggers();
5694   trigger->set_name("trigger_name");
5695   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5696   ds_cfg->set_name("ds");
5697 
5698   consumer->EnableTracing(trace_config);
5699   producer->WaitForTracingSetup();
5700   producer->WaitForDataSourceSetup("ds");
5701   producer->WaitForDataSourceStart("ds");
5702 
5703   auto writer1 = producer->CreateTraceWriter("ds");
5704 
5705   auto producer_flush_cb = [&](FlushRequestID flush_req_id,
5706                                const DataSourceInstanceID* /*id*/, size_t,
5707                                FlushFlags) {
5708     // Notify the tracing service that the flush is complete.
5709     producer->endpoint()->NotifyFlushComplete(flush_req_id);
5710     // Also disconnect the consumer (this terminates the tracing session). The
5711     // consumer disconnection is postponed with a PostTask(). The goal is to run
5712     // the lambda inside TracingServiceImpl::FlushAndDisableTracing() with an
5713     // empty `tracing_sessions_` map.
5714     task_runner.PostTask([&]() { consumer.reset(); });
5715   };
5716   EXPECT_CALL(*producer, Flush(_, _, _, _)).WillOnce(Invoke(producer_flush_cb));
5717 
5718   // Cause the tracing session to stop. Note that
5719   // TracingServiceImpl::FlushAndDisableTracing() is also called when
5720   // duration_ms expires, but in a test it's faster to use a trigger.
5721   producer->endpoint()->ActivateTriggers({"trigger_name"});
5722   producer->WaitForDataSourceStop("ds");
5723 
5724   task_runner.RunUntilIdle();
5725 }
5726 
TEST_F(TracingServiceImplTest,RelayEndpointClockSync)5727 TEST_F(TracingServiceImplTest, RelayEndpointClockSync) {
5728   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5729   consumer->Connect(svc.get());
5730 
5731   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5732   producer->Connect(svc.get(), "mock_producer");
5733 
5734   auto relay_client = svc->ConnectRelayClient(
5735       std::make_pair<uint32_t, uint64_t>(/*base::MachineID=*/0x103, 1));
5736 
5737   uint32_t clock_id =
5738       static_cast<uint32_t>(protos::gen::BuiltinClock::BUILTIN_CLOCK_BOOTTIME);
5739 
5740   relay_client->SyncClocks(RelayEndpoint::SyncMode::PING,
5741                            /*client_clocks=*/{{clock_id, 100}},
5742                            /*host_clocks=*/{{clock_id, 1000}});
5743   relay_client->SyncClocks(RelayEndpoint::SyncMode::UPDATE,
5744                            /*client_clocks=*/{{clock_id, 300}},
5745                            /*host_clocks=*/{{clock_id, 1200}});
5746 
5747   producer->RegisterDataSource("ds");
5748 
5749   TraceConfig trace_config;
5750   trace_config.add_buffers()->set_size_kb(128);
5751   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5752   ds_cfg->set_name("ds");
5753 
5754   consumer->EnableTracing(trace_config);
5755   producer->WaitForTracingSetup();
5756   producer->WaitForDataSourceSetup("ds");
5757   producer->WaitForDataSourceStart("ds");
5758 
5759   auto writer1 = producer->CreateTraceWriter("ds");
5760 
5761   consumer->DisableTracing();
5762   producer->WaitForDataSourceStop("ds");
5763   consumer->WaitForTracingDisabled();
5764 
5765   task_runner.RunUntilIdle();
5766 
5767   auto trace_packets = consumer->ReadBuffers();
5768   bool clock_sync_packet_seen = false;
5769   for (auto& packet : trace_packets) {
5770     if (!packet.has_remote_clock_sync())
5771       continue;
5772     clock_sync_packet_seen = true;
5773 
5774     auto& remote_clock_sync = packet.remote_clock_sync();
5775     ASSERT_EQ(remote_clock_sync.synced_clocks_size(), 2);
5776 
5777     auto& snapshots = remote_clock_sync.synced_clocks();
5778     ASSERT_TRUE(snapshots[0].has_client_clocks());
5779     auto* snapshot = &snapshots[0].client_clocks();
5780     ASSERT_EQ(snapshot->clocks_size(), 1);
5781     ASSERT_EQ(snapshot->clocks()[0].clock_id(), clock_id);
5782     ASSERT_EQ(snapshot->clocks()[0].timestamp(), 100u);
5783 
5784     snapshot = &snapshots[0].host_clocks();
5785     ASSERT_EQ(snapshot->clocks_size(), 1);
5786     ASSERT_EQ(snapshot->clocks()[0].clock_id(), clock_id);
5787     ASSERT_EQ(snapshot->clocks()[0].timestamp(), 1000u);
5788 
5789     snapshot = &snapshots[1].client_clocks();
5790     ASSERT_EQ(snapshot->clocks_size(), 1);
5791     ASSERT_EQ(snapshot->clocks()[0].clock_id(), clock_id);
5792     ASSERT_EQ(snapshot->clocks()[0].timestamp(), 300u);
5793 
5794     snapshot = &snapshots[1].host_clocks();
5795     ASSERT_EQ(snapshot->clocks_size(), 1);
5796     ASSERT_EQ(snapshot->clocks()[0].clock_id(), clock_id);
5797     ASSERT_EQ(snapshot->clocks()[0].timestamp(), 1200u);
5798   }
5799   ASSERT_TRUE(clock_sync_packet_seen);
5800 }
5801 
TEST_F(TracingServiceImplTest,RelayEndpointDisconnect)5802 TEST_F(TracingServiceImplTest, RelayEndpointDisconnect) {
5803   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5804   consumer->Connect(svc.get());
5805 
5806   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5807   producer->Connect(svc.get(), "mock_producer");
5808 
5809   auto relay_client = svc->ConnectRelayClient(
5810       std::make_pair<uint32_t, uint64_t>(/*base::MachineID=*/0x103, 1));
5811   uint32_t clock_id =
5812       static_cast<uint32_t>(protos::gen::BuiltinClock::BUILTIN_CLOCK_BOOTTIME);
5813 
5814   relay_client->SyncClocks(RelayEndpoint::SyncMode::PING,
5815                            /*client_clocks=*/{{clock_id, 100}},
5816                            /*host_clocks=*/{{clock_id, 1000}});
5817   relay_client->SyncClocks(RelayEndpoint::SyncMode::UPDATE,
5818                            /*client_clocks=*/{{clock_id, 300}},
5819                            /*host_clocks=*/{{clock_id, 1200}});
5820 
5821   relay_client->Disconnect();
5822 
5823   producer->RegisterDataSource("ds");
5824 
5825   TraceConfig trace_config;
5826   trace_config.add_buffers()->set_size_kb(128);
5827   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5828   ds_cfg->set_name("ds");
5829 
5830   consumer->EnableTracing(trace_config);
5831   producer->WaitForTracingSetup();
5832   producer->WaitForDataSourceSetup("ds");
5833   producer->WaitForDataSourceStart("ds");
5834 
5835   auto writer1 = producer->CreateTraceWriter("ds");
5836 
5837   consumer->DisableTracing();
5838   producer->WaitForDataSourceStop("ds");
5839   consumer->WaitForTracingDisabled();
5840 
5841   task_runner.RunUntilIdle();
5842 
5843   auto trace_packets = consumer->ReadBuffers();
5844   bool clock_sync_packet_seen = false;
5845   for (auto& packet : trace_packets) {
5846     if (!packet.has_remote_clock_sync())
5847       continue;
5848     clock_sync_packet_seen = true;
5849   }
5850   ASSERT_FALSE(clock_sync_packet_seen);
5851 }
5852 
TEST_F(TracingServiceImplTest,SessionSemaphoreMutexSingleSession)5853 TEST_F(TracingServiceImplTest, SessionSemaphoreMutexSingleSession) {
5854   TraceConfig trace_config;
5855   trace_config.add_buffers()->set_size_kb(32);  // Buf 0.
5856   trace_config.add_session_semaphores()->set_name("mutex");
5857 
5858   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5859   producer->Connect(svc.get(), "mock_producer");
5860 
5861   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5862   consumer->Connect(svc.get());
5863   consumer->EnableTracing(trace_config);
5864   consumer->DisableTracing();
5865   consumer->WaitForTracingDisabledWithError(IsEmpty());
5866 }
5867 
TEST_F(TracingServiceImplTest,SessionSemaphoreMutexMultipleSession)5868 TEST_F(TracingServiceImplTest, SessionSemaphoreMutexMultipleSession) {
5869   TraceConfig trace_config;
5870   trace_config.add_buffers()->set_size_kb(32);
5871   trace_config.add_session_semaphores()->set_name("mutex");
5872 
5873   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5874   consumer->Connect(svc.get());
5875   consumer->EnableTracing(trace_config);
5876 
5877   std::unique_ptr<MockConsumer> consumer2 = CreateMockConsumer();
5878   consumer2->Connect(svc.get());
5879   consumer2->EnableTracing(trace_config);
5880   consumer2->WaitForTracingDisabledWithError(LowerCase(HasSubstr("semaphore")));
5881 
5882   consumer->DisableTracing();
5883   consumer->WaitForTracingDisabledWithError(IsEmpty());
5884 }
5885 
TEST_F(TracingServiceImplTest,SessionSemaphoreHigherCurrentFails)5886 TEST_F(TracingServiceImplTest, SessionSemaphoreHigherCurrentFails) {
5887   TraceConfig trace_config;
5888   trace_config.add_buffers()->set_size_kb(32);
5889 
5890   auto* session_semaphore = trace_config.add_session_semaphores();
5891   session_semaphore->set_name("diff_value_semaphore");
5892   session_semaphore->set_max_other_session_count(0);
5893 
5894   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5895   consumer->Connect(svc.get());
5896   consumer->EnableTracing(trace_config);
5897 
5898   // The second consumer sets a higher count.
5899   session_semaphore->set_max_other_session_count(1);
5900 
5901   std::unique_ptr<MockConsumer> consumer2 = CreateMockConsumer();
5902   consumer2->Connect(svc.get());
5903   consumer2->EnableTracing(trace_config);
5904   consumer2->WaitForTracingDisabledWithError(LowerCase(HasSubstr("semaphore")));
5905 
5906   consumer->DisableTracing();
5907   consumer->WaitForTracingDisabledWithError(IsEmpty());
5908 }
5909 
TEST_F(TracingServiceImplTest,SessionSemaphoreHigherPreviousFails)5910 TEST_F(TracingServiceImplTest, SessionSemaphoreHigherPreviousFails) {
5911   TraceConfig trace_config;
5912   trace_config.add_buffers()->set_size_kb(32);
5913 
5914   auto* session_semaphore = trace_config.add_session_semaphores();
5915   session_semaphore->set_name("diff_value_semaphore");
5916   session_semaphore->set_max_other_session_count(1);
5917 
5918   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5919   consumer->Connect(svc.get());
5920   consumer->EnableTracing(trace_config);
5921 
5922   // The second consumer sets a lower count.
5923   session_semaphore->set_max_other_session_count(0);
5924 
5925   std::unique_ptr<MockConsumer> consumer2 = CreateMockConsumer();
5926   consumer2->Connect(svc.get());
5927   consumer2->EnableTracing(trace_config);
5928   consumer2->WaitForTracingDisabledWithError(LowerCase(HasSubstr("semaphore")));
5929 
5930   consumer->DisableTracing();
5931   consumer->WaitForTracingDisabledWithError(IsEmpty());
5932 }
5933 
TEST_F(TracingServiceImplTest,SessionSemaphoreAllowedUpToLimit)5934 TEST_F(TracingServiceImplTest, SessionSemaphoreAllowedUpToLimit) {
5935   TraceConfig trace_config;
5936   trace_config.add_buffers()->set_size_kb(32);
5937 
5938   auto* session_semaphore = trace_config.add_session_semaphores();
5939   session_semaphore->set_name("multi_semaphore");
5940   session_semaphore->set_max_other_session_count(3);
5941 
5942   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5943   consumer->Connect(svc.get());
5944   consumer->EnableTracing(trace_config);
5945 
5946   std::unique_ptr<MockConsumer> consumer2 = CreateMockConsumer();
5947   consumer2->Connect(svc.get());
5948   consumer2->EnableTracing(trace_config);
5949 
5950   std::unique_ptr<MockConsumer> consumer3 = CreateMockConsumer();
5951   consumer3->Connect(svc.get());
5952   consumer3->EnableTracing(trace_config);
5953 
5954   std::unique_ptr<MockConsumer> consumer4 = CreateMockConsumer();
5955   consumer4->Connect(svc.get());
5956   consumer4->EnableTracing(trace_config);
5957 
5958   std::unique_ptr<MockConsumer> consumer5 = CreateMockConsumer();
5959   consumer5->Connect(svc.get());
5960   consumer5->EnableTracing(trace_config);
5961   consumer5->WaitForTracingDisabledWithError(LowerCase(HasSubstr("semaphore")));
5962 
5963   consumer4->DisableTracing();
5964   consumer4->WaitForTracingDisabledWithError(IsEmpty());
5965 
5966   consumer3->DisableTracing();
5967   consumer3->WaitForTracingDisabledWithError(IsEmpty());
5968 
5969   consumer2->DisableTracing();
5970   consumer2->WaitForTracingDisabledWithError(IsEmpty());
5971 
5972   consumer->DisableTracing();
5973   consumer->WaitForTracingDisabledWithError(IsEmpty());
5974 }
5975 
5976 }  // namespace perfetto
5977