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