xref: /aosp_15_r20/external/perfetto/src/tracing/service/tracing_service_impl_unittest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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::__anon65f12d490111::TracingServiceImplScrapingWithSmbTest::__anon65f12d4913083435     protozero::ContiguousMemoryRange GetNewBuffer() override {
3436       PERFETTO_FATAL("Unreachable");
3437     }
3438 
AnnotatePatchperfetto::__anon65f12d490111::TracingServiceImplScrapingWithSmbTest::__anon65f12d4913083439     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,QueryServiceState)4216 TEST_F(TracingServiceImplTest, QueryServiceState) {
4217   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4218   consumer->Connect(svc.get());
4219 
4220   std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
4221   producer1->Connect(svc.get(), "producer1", /*uid=*/0);
4222 
4223   std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
4224   producer2->Connect(svc.get(), "producer2", /*uid=*/1002);
4225 
4226   producer1->RegisterDataSource("common_ds");
4227   producer2->RegisterDataSource("common_ds");
4228 
4229   producer1->RegisterDataSource("p1_ds");
4230   producer2->RegisterDataSource("p2_ds");
4231 
4232   producer2->RegisterDataSource("common_ds");
4233 
4234   TracingServiceState svc_state = consumer->QueryServiceState();
4235 
4236   EXPECT_EQ(svc_state.producers_size(), 2);
4237   EXPECT_EQ(svc_state.producers().at(0).id(), 1);
4238   EXPECT_EQ(svc_state.producers().at(0).name(), "producer1");
4239   EXPECT_EQ(svc_state.producers().at(0).uid(), 0);
4240   EXPECT_EQ(svc_state.producers().at(1).id(), 2);
4241   EXPECT_EQ(svc_state.producers().at(1).name(), "producer2");
4242   EXPECT_EQ(svc_state.producers().at(1).uid(), 1002);
4243 
4244   EXPECT_EQ(svc_state.data_sources_size(), 5);
4245 
4246   auto count_ds = [&](int32_t producer_id, const std::string& ds_name) {
4247     int count = 0;
4248     for (const auto& ds : svc_state.data_sources()) {
4249       if (ds.producer_id() == producer_id &&
4250           ds.ds_descriptor().name() == ds_name)
4251         ++count;
4252     }
4253     return count;
4254   };
4255 
4256   EXPECT_EQ(count_ds(1, "common_ds"), 1);
4257   EXPECT_EQ(count_ds(1, "p1_ds"), 1);
4258   EXPECT_EQ(count_ds(2, "common_ds"), 2);
4259   EXPECT_EQ(count_ds(2, "p2_ds"), 1);
4260 
4261   // Test that descriptors are cleared when a producer disconnects.
4262   producer1.reset();
4263   svc_state = consumer->QueryServiceState();
4264 
4265   EXPECT_EQ(svc_state.producers_size(), 1);
4266   EXPECT_EQ(svc_state.data_sources_size(), 3);
4267 
4268   EXPECT_EQ(count_ds(1, "common_ds"), 0);
4269   EXPECT_EQ(count_ds(1, "p1_ds"), 0);
4270   EXPECT_EQ(count_ds(2, "common_ds"), 2);
4271   EXPECT_EQ(count_ds(2, "p2_ds"), 1);
4272 }
4273 
TEST_F(TracingServiceImplTest,UpdateDataSource)4274 TEST_F(TracingServiceImplTest, UpdateDataSource) {
4275   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4276   consumer->Connect(svc.get());
4277 
4278   std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
4279   producer1->Connect(svc.get(), "producer1", /*uid=*/0);
4280 
4281   std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
4282   producer2->Connect(svc.get(), "producer2", /*uid=*/1002);
4283 
4284   producer1->RegisterTrackEventDataSource({"cat1"}, 1);
4285   producer2->RegisterTrackEventDataSource({}, 1);
4286   producer2->RegisterTrackEventDataSource({}, 2);
4287 
4288   // This request should fail because ID=2 is already registered.
4289   producer2->RegisterTrackEventDataSource({"this_should_fail"}, 2);
4290 
4291   TracingServiceState svc_state = consumer->QueryServiceState();
4292 
4293   auto parse_desc = [](const perfetto::protos::gen::DataSourceDescriptor& dsd) {
4294     perfetto::protos::gen::TrackEventDescriptor desc;
4295     auto desc_raw = dsd.track_event_descriptor_raw();
4296     EXPECT_TRUE(desc.ParseFromArray(desc_raw.data(), desc_raw.size()));
4297     return desc;
4298   };
4299 
4300   EXPECT_EQ(svc_state.data_sources_size(), 3);
4301 
4302   EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 1);
4303   EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().name(),
4304             "track_event");
4305   EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().id(), 1u);
4306   auto ted = parse_desc(svc_state.data_sources().at(0).ds_descriptor());
4307   EXPECT_EQ(ted.available_categories_size(), 1);
4308   EXPECT_EQ(ted.available_categories()[0].name(), "cat1");
4309 
4310   EXPECT_EQ(svc_state.data_sources().at(1).producer_id(), 2);
4311   EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().name(),
4312             "track_event");
4313   EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().id(), 1u);
4314   ted = parse_desc(svc_state.data_sources().at(1).ds_descriptor());
4315   EXPECT_EQ(ted.available_categories_size(), 0);
4316 
4317   EXPECT_EQ(svc_state.data_sources().at(2).ds_descriptor().id(), 2u);
4318 
4319   // Test that TrackEvent DataSource is updated.
4320   producer2->UpdateTrackEventDataSource({"cat1", "cat2"}, 2);
4321 
4322   svc_state = consumer->QueryServiceState();
4323 
4324   EXPECT_EQ(svc_state.data_sources_size(), 3);
4325 
4326   EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 1);
4327   EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().id(), 1u);
4328   ted = parse_desc(svc_state.data_sources().at(0).ds_descriptor());
4329   EXPECT_EQ(ted.available_categories_size(), 1);
4330 
4331   EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().id(), 1u);
4332   ted = parse_desc(svc_state.data_sources().at(1).ds_descriptor());
4333   EXPECT_EQ(ted.available_categories_size(), 0);
4334 
4335   EXPECT_EQ(svc_state.data_sources().at(2).producer_id(), 2);
4336   EXPECT_EQ(svc_state.data_sources().at(2).ds_descriptor().id(), 2u);
4337   ted = parse_desc(svc_state.data_sources().at(2).ds_descriptor());
4338   EXPECT_EQ(ted.available_categories_size(), 2);
4339   EXPECT_EQ(ted.available_categories()[0].name(), "cat1");
4340   EXPECT_EQ(ted.available_categories()[1].name(), "cat2");
4341 
4342   // Test removal of a category.
4343   producer2->UpdateTrackEventDataSource({"cat2"}, 2);
4344 
4345   svc_state = consumer->QueryServiceState();
4346 
4347   EXPECT_EQ(svc_state.data_sources_size(), 3);
4348   EXPECT_EQ(svc_state.data_sources().at(2).ds_descriptor().id(), 2u);
4349   ted = parse_desc(svc_state.data_sources().at(2).ds_descriptor());
4350   EXPECT_EQ(ted.available_categories_size(), 1);
4351   EXPECT_EQ(ted.available_categories()[0].name(), "cat2");
4352 
4353   // Test adding a category to the first data source.
4354   producer2->UpdateTrackEventDataSource({"cat3"}, 1);
4355 
4356   svc_state = consumer->QueryServiceState();
4357 
4358   EXPECT_EQ(svc_state.data_sources_size(), 3);
4359   EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().id(), 1u);
4360   ted = parse_desc(svc_state.data_sources().at(1).ds_descriptor());
4361   EXPECT_EQ(ted.available_categories_size(), 1);
4362   EXPECT_EQ(ted.available_categories()[0].name(), "cat3");
4363 }
4364 
TEST_F(TracingServiceImplTest,LimitSessionsPerUid)4365 TEST_F(TracingServiceImplTest, LimitSessionsPerUid) {
4366   std::vector<std::unique_ptr<MockConsumer>> consumers;
4367 
4368   auto start_new_session = [&](uid_t uid) -> MockConsumer* {
4369     TraceConfig trace_config;
4370     trace_config.add_buffers()->set_size_kb(128);
4371     trace_config.set_duration_ms(0);  // Unlimited.
4372     consumers.emplace_back(CreateMockConsumer());
4373     consumers.back()->Connect(svc.get(), uid);
4374     consumers.back()->EnableTracing(trace_config);
4375     return &*consumers.back();
4376   };
4377 
4378   const int kMaxConcurrentTracingSessionsPerUid = 5;
4379   const int kUids = 2;
4380 
4381   // Create a bunch of legit sessions (2 uids * 5 sessions).
4382   for (int i = 0; i < kMaxConcurrentTracingSessionsPerUid * kUids; i++) {
4383     start_new_session(/*uid=*/static_cast<uid_t>(i) % kUids);
4384   }
4385 
4386   // Any other session now should fail for the two uids.
4387   for (int i = 0; i <= kUids; i++) {
4388     auto* consumer = start_new_session(/*uid=*/static_cast<uid_t>(i) % kUids);
4389     auto on_fail = task_runner.CreateCheckpoint("uid_" + std::to_string(i));
4390     EXPECT_CALL(*consumer, OnTracingDisabled(StrNe("")))
4391         .WillOnce(InvokeWithoutArgs(on_fail));
4392   }
4393 
4394   // Wait for failure (only after both attempts).
4395   for (int i = 0; i <= kUids; i++) {
4396     task_runner.RunUntilCheckpoint("uid_" + std::to_string(i));
4397   }
4398 
4399   // The destruction of |consumers| will tear down and stop the good sessions.
4400 }
4401 
TEST_F(TracingServiceImplTest,ProducerProvidedSMB)4402 TEST_F(TracingServiceImplTest, ProducerProvidedSMB) {
4403   static constexpr size_t kShmSizeBytes = 1024 * 1024;
4404   static constexpr size_t kShmPageSizeBytes = 4 * 1024;
4405 
4406   std::unique_ptr<MockProducer> producer = CreateMockProducer();
4407 
4408   TestSharedMemory::Factory factory;
4409   auto shm = factory.CreateSharedMemory(kShmSizeBytes);
4410   SharedMemory* shm_raw = shm.get();
4411 
4412   // Service should adopt the SMB provided by the producer.
4413   producer->Connect(svc.get(), "mock_producer", /*uid=*/42, /*pid=*/1025,
4414                     /*shared_memory_size_hint_bytes=*/0, kShmPageSizeBytes,
4415                     std::move(shm));
4416   EXPECT_TRUE(producer->endpoint()->IsShmemProvidedByProducer());
4417   EXPECT_NE(producer->endpoint()->MaybeSharedMemoryArbiter(), nullptr);
4418   EXPECT_EQ(producer->endpoint()->shared_memory(), shm_raw);
4419 
4420   producer->WaitForTracingSetup();
4421   producer->RegisterDataSource("data_source");
4422 
4423   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4424   consumer->Connect(svc.get());
4425 
4426   TraceConfig trace_config;
4427   trace_config.add_buffers()->set_size_kb(128);
4428   auto* ds_config = trace_config.add_data_sources()->mutable_config();
4429   ds_config->set_name("data_source");
4430 
4431   consumer->EnableTracing(trace_config);
4432   producer->WaitForDataSourceSetup("data_source");
4433   producer->WaitForDataSourceStart("data_source");
4434 
4435   // Verify that data written to the producer-provided SMB ends up in trace
4436   // buffer correctly.
4437   std::unique_ptr<TraceWriter> writer =
4438       producer->CreateTraceWriter("data_source");
4439   {
4440     auto tp = writer->NewTracePacket();
4441     tp->set_for_testing()->set_str("payload");
4442   }
4443 
4444   auto flush_request = consumer->Flush();
4445   producer->ExpectFlush(writer.get());
4446   ASSERT_TRUE(flush_request.WaitForReply());
4447 
4448   consumer->DisableTracing();
4449   producer->WaitForDataSourceStop("data_source");
4450   consumer->WaitForTracingDisabled();
4451   EXPECT_THAT(consumer->ReadBuffers(),
4452               Contains(Property(
4453                   &protos::gen::TracePacket::for_testing,
4454                   Property(&protos::gen::TestEvent::str, Eq("payload")))));
4455 }
4456 
TEST_F(TracingServiceImplTest,ProducerProvidedSMBInvalidSizes)4457 TEST_F(TracingServiceImplTest, ProducerProvidedSMBInvalidSizes) {
4458   static constexpr size_t kShmSizeBytes = 1024 * 1024;
4459   static constexpr size_t kShmPageSizeBytes = 20 * 1024;
4460 
4461   std::unique_ptr<MockProducer> producer = CreateMockProducer();
4462 
4463   TestSharedMemory::Factory factory;
4464   auto shm = factory.CreateSharedMemory(kShmSizeBytes);
4465 
4466   // Service should not adopt the SMB provided by the producer, because the SMB
4467   // size isn't a multiple of the page size.
4468   producer->Connect(svc.get(), "mock_producer", /*uid=*/42, /*pid=*/1025,
4469                     /*shared_memory_size_hint_bytes=*/0, kShmPageSizeBytes,
4470                     std::move(shm));
4471   EXPECT_FALSE(producer->endpoint()->IsShmemProvidedByProducer());
4472   EXPECT_EQ(producer->endpoint()->shared_memory(), nullptr);
4473 }
4474 
4475 // If the consumer specifies a UUID in the TraceConfig, the TraceUuid packet
4476 // must match that.
TEST_F(TracingServiceImplTest,UuidPacketMatchesConfigUuid)4477 TEST_F(TracingServiceImplTest, UuidPacketMatchesConfigUuid) {
4478   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4479   consumer->Connect(svc.get());
4480   TraceConfig trace_config;
4481   trace_config.set_trace_uuid_lsb(1);
4482   trace_config.set_trace_uuid_msb(2);
4483   trace_config.add_buffers()->set_size_kb(8);
4484   auto* ds_config = trace_config.add_data_sources()->mutable_config();
4485   ds_config->set_name("data_source");
4486 
4487   consumer->EnableTracing(trace_config);
4488   consumer->DisableTracing();
4489   consumer->WaitForTracingDisabled();
4490 
4491   auto packets = consumer->ReadBuffers();
4492 
4493   EXPECT_THAT(
4494       packets,
4495       Contains(Property(&protos::gen::TracePacket::trace_uuid,
4496                         AllOf(Property(&protos::gen::TraceUuid::lsb, Eq(1)),
4497                               Property(&protos::gen::TraceUuid::msb, Eq(2))))));
4498 }
4499 
4500 // If the consumer does not specify any UUID in the TraceConfig, a random
4501 // UUID must be generated and reported in the TraceUuid packet.
TEST_F(TracingServiceImplTest,RandomUuidIfNoConfigUuid)4502 TEST_F(TracingServiceImplTest, RandomUuidIfNoConfigUuid) {
4503   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4504   consumer->Connect(svc.get());
4505   TraceConfig trace_config;
4506   trace_config.add_buffers()->set_size_kb(8);
4507   auto* ds_config = trace_config.add_data_sources()->mutable_config();
4508   ds_config->set_name("data_source");
4509 
4510   consumer->EnableTracing(trace_config);
4511   consumer->DisableTracing();
4512   consumer->WaitForTracingDisabled();
4513 
4514   auto packets = consumer->ReadBuffers();
4515 
4516   EXPECT_THAT(packets,
4517               Contains(Property(
4518                   &protos::gen::TracePacket::trace_uuid,
4519                   Not(AnyOf(Property(&protos::gen::TraceUuid::lsb, Eq(0)),
4520                             Property(&protos::gen::TraceUuid::msb, Eq(0)))))));
4521 }
4522 
TEST_F(TracingServiceImplTest,CloneSession)4523 TEST_F(TracingServiceImplTest, CloneSession) {
4524   // The consumer the creates the initial tracing session.
4525   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4526   consumer->Connect(svc.get());
4527 
4528   // The consumer that clones it and reads back the data.
4529   std::unique_ptr<MockConsumer> consumer2 = CreateMockConsumer();
4530   consumer2->Connect(svc.get());
4531 
4532   std::unique_ptr<MockProducer> producer = CreateMockProducer();
4533   producer->Connect(svc.get(), "mock_producer");
4534 
4535   // Create two data sources, as we'll write on two distinct buffers.
4536   producer->RegisterDataSource("ds_1");
4537   producer->RegisterDataSource("ds_2");
4538 
4539   TraceConfig trace_config;
4540   trace_config.add_buffers()->set_size_kb(32);  // Buf 0.
4541   trace_config.add_buffers()->set_size_kb(32);  // Buf 1.
4542   trace_config.set_trace_uuid_lsb(4242);
4543   trace_config.set_trace_uuid_msb(3737);
4544   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
4545   ds_cfg->set_name("ds_1");
4546   ds_cfg->set_target_buffer(0);
4547   ds_cfg = trace_config.add_data_sources()->mutable_config();
4548   ds_cfg->set_name("ds_2");
4549   ds_cfg->set_target_buffer(1);
4550 
4551   // Add a filter and check that the filter is propagated to the cloned session.
4552   // The filter allows the `for_testing` field but not the root `timestamp`.
4553   protozero::FilterBytecodeGenerator filt;
4554   // Message 0: root Trace proto.
4555   filt.AddNestedField(1 /* root trace.packet*/, 1);
4556   filt.EndMessage();
4557   // Message 1: TracePacket proto. Allow only the `for_testing` and `trace_uuid`
4558   // sub-fields.
4559   filt.AddSimpleField(protos::pbzero::TracePacket::kTraceUuidFieldNumber);
4560   filt.AddSimpleField(protos::pbzero::TracePacket::kForTestingFieldNumber);
4561   filt.EndMessage();
4562   trace_config.mutable_trace_filter()->set_bytecode(filt.Serialize());
4563 
4564   consumer->EnableTracing(trace_config);
4565   producer->WaitForTracingSetup();
4566 
4567   producer->WaitForDataSourceSetup("ds_1");
4568   producer->WaitForDataSourceSetup("ds_2");
4569 
4570   producer->WaitForDataSourceStart("ds_1");
4571   producer->WaitForDataSourceStart("ds_2");
4572 
4573   std::unique_ptr<TraceWriter> writers[] = {
4574       producer->CreateTraceWriter("ds_1"),
4575       producer->CreateTraceWriter("ds_2"),
4576   };
4577 
4578   // Add some data to both buffers.
4579   static constexpr size_t kNumTestPackets = 20;
4580   for (size_t i = 0; i < kNumTestPackets; i++) {
4581     auto tp = writers[i % 1]->NewTracePacket();
4582     std::string payload("payload" + std::to_string(i));
4583     tp->set_for_testing()->set_str(payload.c_str(), payload.size());
4584     tp->set_timestamp(static_cast<uint64_t>(i));
4585   }
4586 
4587   auto clone_done = task_runner.CreateCheckpoint("clone_done");
4588   base::Uuid clone_uuid;
4589   EXPECT_CALL(*consumer2, OnSessionCloned(_))
4590       .WillOnce(Invoke(
4591           [clone_done, &clone_uuid](const Consumer::OnSessionClonedArgs& args) {
4592             ASSERT_TRUE(args.success);
4593             ASSERT_TRUE(args.error.empty());
4594             // Ensure the LSB is preserved, but the MSB is different. See
4595             // comments in tracing_service_impl.cc and perfetto_cmd.cc around
4596             // triggering_subscription_id().
4597             ASSERT_EQ(args.uuid.lsb(), 4242);
4598             ASSERT_NE(args.uuid.msb(), 3737);
4599             clone_uuid = args.uuid;
4600             clone_done();
4601           }));
4602   consumer2->CloneSession(1);
4603   // CloneSession() will implicitly issue a flush. Linearize with that.
4604   producer->ExpectFlush({writers[0].get(), writers[1].get()});
4605   task_runner.RunUntilCheckpoint("clone_done");
4606 
4607   // Overwrite the ring buffer of the original session to check that clone
4608   // actually returns a copy.
4609   for (size_t i = 0; i < 1000; i++) {
4610     auto tp = writers[i % 2]->NewTracePacket();
4611     std::string payload(1000u, 'x');
4612     tp->set_for_testing()->set_str(payload.c_str(), payload.size());
4613   }
4614 
4615   auto flush_request = consumer->Flush();
4616   producer->ExpectFlush({writers[0].get(), writers[1].get()});
4617   ASSERT_TRUE(flush_request.WaitForReply());
4618 
4619   // Delete the initial tracing session.
4620   consumer->DisableTracing();
4621   consumer->FreeBuffers();
4622   producer->WaitForDataSourceStop("ds_1");
4623   producer->WaitForDataSourceStop("ds_2");
4624   consumer->WaitForTracingDisabled();
4625 
4626   // Read back the cloned trace and check the contents.
4627   auto packets = consumer2->ReadBuffers();
4628   for (size_t i = 0; i < kNumTestPackets; i++) {
4629     std::string payload = "payload" + std::to_string(i);
4630     EXPECT_THAT(packets,
4631                 Contains(Property(
4632                     &protos::gen::TracePacket::for_testing,
4633                     Property(&protos::gen::TestEvent::str, Eq(payload)))));
4634   }
4635 
4636   // Check that the "x" payload written after cloning the session is not there.
4637   EXPECT_THAT(packets,
4638               Not(Contains(Property(&protos::gen::TracePacket::for_testing,
4639                                     Property(&protos::gen::TestEvent::str,
4640                                              testing::StartsWith("x"))))));
4641 
4642   // Check that the `timestamp` field is filtered out.
4643   EXPECT_THAT(packets,
4644               Each(Property(&protos::gen::TracePacket::has_timestamp, false)));
4645 
4646   // Check that the UUID in the trace matches the UUID passed to to the
4647   // OnCloneSession consumer API.
4648   EXPECT_THAT(
4649       packets,
4650       Contains(Property(
4651           &protos::gen::TracePacket::trace_uuid,
4652           AllOf(
4653               Property(&protos::gen::TraceUuid::msb, Eq(clone_uuid.msb())),
4654               Property(&protos::gen::TraceUuid::lsb, Eq(clone_uuid.lsb()))))));
4655 }
4656 
4657 // Test that a consumer cannot clone a session from a consumer with a different
4658 // uid (unless it's marked as eligible for bugreport, see next test).
TEST_F(TracingServiceImplTest,CloneSessionAcrossUidDenied)4659 TEST_F(TracingServiceImplTest, CloneSessionAcrossUidDenied) {
4660   // The consumer the creates the initial tracing session.
4661   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4662   consumer->Connect(svc.get());
4663 
4664   // The consumer that clones it and reads back the data.
4665   std::unique_ptr<MockConsumer> consumer2 = CreateMockConsumer();
4666   consumer2->Connect(svc.get(), 1234);
4667 
4668   TraceConfig trace_config;
4669   trace_config.add_buffers()->set_size_kb(32);
4670 
4671   consumer->EnableTracing(trace_config);
4672   auto flush_request = consumer->Flush();
4673   ASSERT_TRUE(flush_request.WaitForReply());
4674 
4675   auto clone_done = task_runner.CreateCheckpoint("clone_done");
4676   EXPECT_CALL(*consumer2, OnSessionCloned(_))
4677       .WillOnce(Invoke([clone_done](const Consumer::OnSessionClonedArgs& args) {
4678         clone_done();
4679         ASSERT_FALSE(args.success);
4680         ASSERT_TRUE(base::Contains(args.error, "session from another UID"));
4681       }));
4682   consumer2->CloneSession(1);
4683   task_runner.RunUntilCheckpoint("clone_done");
4684 }
4685 
4686 // Test that a consumer can clone a session from the shell uid if the trace is
4687 // marked as eligible for bugreport. Android only.
4688 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
TEST_F(TracingServiceImplTest,CloneSessionAcrossUidForBugreport)4689 TEST_F(TracingServiceImplTest, CloneSessionAcrossUidForBugreport) {
4690   // The consumer the creates the initial tracing session.
4691   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4692   consumer->Connect(svc.get());
4693 
4694   std::unique_ptr<MockProducer> producer = CreateMockProducer();
4695   producer->Connect(svc.get(), "mock_producer");
4696   producer->RegisterDataSource("ds_1");
4697 
4698   // The consumer that clones it and reads back the data.
4699   std::unique_ptr<MockConsumer> clone_consumer = CreateMockConsumer();
4700   clone_consumer->Connect(svc.get(), AID_SHELL);
4701 
4702   TraceConfig trace_config;
4703   trace_config.add_buffers()->set_size_kb(32);
4704   trace_config.set_bugreport_score(1);
4705   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
4706 
4707   // Add a trace filter and ensure it's ignored for bugreports (b/317065412).
4708   protozero::FilterBytecodeGenerator filt;
4709   filt.AddNestedField(1 /* root trace.packet*/, 1);
4710   filt.EndMessage();
4711   // Add a random field to keep the generator happy. This technically still
4712   // filters out the for_testing packet that we are using below.
4713   filt.AddSimpleField(protos::pbzero::TracePacket::kTraceUuidFieldNumber);
4714   filt.EndMessage();
4715   trace_config.mutable_trace_filter()->set_bytecode_v2(filt.Serialize());
4716 
4717   consumer->EnableTracing(trace_config);
4718   producer->WaitForTracingSetup();
4719   producer->WaitForDataSourceSetup("ds_1");
4720   producer->WaitForDataSourceStart("ds_1");
4721   std::unique_ptr<TraceWriter> writer = producer->CreateTraceWriter("ds_1");
4722   writer->NewTracePacket()->set_for_testing()->set_str("payload");
4723   writer.reset();
4724 
4725   auto flush_request = consumer->Flush();
4726   FlushFlags flush_flags(FlushFlags::Initiator::kConsumerSdk,
4727                          FlushFlags::Reason::kExplicit);
4728   producer->ExpectFlush({}, /*reply=*/true, flush_flags);
4729   ASSERT_TRUE(flush_request.WaitForReply());
4730 
4731   auto clone_done = task_runner.CreateCheckpoint("clone_done");
4732   EXPECT_CALL(*clone_consumer, OnSessionCloned(_))
4733       .WillOnce(Invoke([clone_done](const Consumer::OnSessionClonedArgs& args) {
4734         clone_done();
4735         ASSERT_TRUE(args.success);
4736       }));
4737 
4738   FlushFlags flush_flags2(FlushFlags::Initiator::kTraced,
4739                           FlushFlags::Reason::kTraceClone,
4740                           FlushFlags::CloneTarget::kBugreport);
4741   producer->ExpectFlush({}, /*reply=*/true, flush_flags2);
4742 
4743   clone_consumer->CloneSession(kBugreportSessionId);
4744   task_runner.RunUntilCheckpoint("clone_done");
4745 
4746   auto packets = clone_consumer->ReadBuffers();
4747   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
4748                                          Property(&protos::gen::TestEvent::str,
4749                                                   HasSubstr("payload")))));
4750 }
4751 #endif  // OS_ANDROID
4752 
TEST_F(TracingServiceImplTest,TransferOnClone)4753 TEST_F(TracingServiceImplTest, TransferOnClone) {
4754   // The consumer the creates the initial tracing session.
4755   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4756   consumer->Connect(svc.get());
4757 
4758   std::unique_ptr<MockProducer> producer = CreateMockProducer();
4759   producer->Connect(svc.get(), "mock_producer");
4760 
4761   // Create two data sources, as we'll write on two distinct buffers.
4762   producer->RegisterDataSource("ds_1");
4763   producer->RegisterDataSource("ds_2");
4764 
4765   TraceConfig trace_config;
4766   trace_config.add_buffers()->set_size_kb(1024);  // Buf 0.
4767   auto* buf1_cfg = trace_config.add_buffers();    // Buf 1 (transfer_on_clone).
4768   buf1_cfg->set_size_kb(1024);
4769   buf1_cfg->set_transfer_on_clone(true);
4770   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
4771   ds_cfg->set_name("ds_1");
4772   ds_cfg->set_target_buffer(0);
4773   ds_cfg = trace_config.add_data_sources()->mutable_config();
4774   ds_cfg->set_name("ds_2");
4775   ds_cfg->set_target_buffer(1);
4776 
4777   consumer->EnableTracing(trace_config);
4778   producer->WaitForTracingSetup();
4779 
4780   producer->WaitForDataSourceSetup("ds_1");
4781   producer->WaitForDataSourceSetup("ds_2");
4782 
4783   producer->WaitForDataSourceStart("ds_1");
4784   producer->WaitForDataSourceStart("ds_2");
4785 
4786   std::unique_ptr<TraceWriter> writers[] = {
4787       producer->CreateTraceWriter("ds_1"),
4788       producer->CreateTraceWriter("ds_2"),
4789   };
4790 
4791   // Write once in the first buffer. This is expected persist across clones.
4792   static constexpr int kNumTestPackets = 10;
4793   for (int n = 0; n < kNumTestPackets; n++) {
4794     auto tp = writers[0]->NewTracePacket();
4795     base::StackString<64> payload("persistent_%d", n);
4796     tp->set_for_testing()->set_str(payload.c_str(), payload.len());
4797   }
4798 
4799   const int kLastIteration = 3;
4800   for (int iteration = 1; iteration <= kLastIteration; iteration++) {
4801     // The consumer the creates the initial tracing session.
4802     std::unique_ptr<MockConsumer> clone_consumer = CreateMockConsumer();
4803     clone_consumer->Connect(svc.get());
4804 
4805     // Add some new data to the 2nd buffer, which is transferred.
4806     // Omit the writing the last iteration to test we get an empty buffer.
4807     for (int n = 0; n < kNumTestPackets && iteration != kLastIteration; n++) {
4808       auto tp = writers[1]->NewTracePacket();
4809       base::StackString<64> payload("transferred_%d_%d", iteration, n);
4810       tp->set_for_testing()->set_str(payload.c_str(), payload.len());
4811     }
4812 
4813     std::string clone_checkpoint_name = "clone_" + std::to_string(iteration);
4814     auto clone_done = task_runner.CreateCheckpoint(clone_checkpoint_name);
4815     base::Uuid clone_uuid;
4816     EXPECT_CALL(*clone_consumer, OnSessionCloned(_))
4817         .WillOnce(InvokeWithoutArgs(clone_done));
4818     clone_consumer->CloneSession(1);
4819 
4820     // CloneSession() will implicitly issue a flush. Linearize with that.
4821     EXPECT_CALL(
4822         *producer,
4823         Flush(_, Pointee(producer->GetDataSourceInstanceId("ds_1")), 1, _))
4824         .WillOnce(Invoke([&](FlushRequestID flush_req_id,
4825                              const DataSourceInstanceID*, size_t, FlushFlags) {
4826           writers[0]->Flush();
4827           producer->endpoint()->NotifyFlushComplete(flush_req_id);
4828         }));
4829     EXPECT_CALL(
4830         *producer,
4831         Flush(_, Pointee(producer->GetDataSourceInstanceId("ds_2")), 1, _))
4832         .WillOnce(Invoke([&](FlushRequestID flush_req_id,
4833                              const DataSourceInstanceID*, size_t, FlushFlags) {
4834           writers[1]->Flush();
4835           producer->endpoint()->NotifyFlushComplete(flush_req_id);
4836         }));
4837     task_runner.RunUntilCheckpoint(clone_checkpoint_name);
4838 
4839     auto packets = clone_consumer->ReadBuffers();
4840     std::vector<std::string> actual_payloads;
4841     for (const auto& packet : packets) {
4842       if (packet.has_for_testing())
4843         actual_payloads.emplace_back(packet.for_testing().str());
4844     }
4845     std::vector<std::string> expected_payloads;
4846     for (int n = 0; n < kNumTestPackets; n++) {
4847       base::StackString<64> expected_payload("persistent_%d", n);
4848       expected_payloads.emplace_back(expected_payload.ToStdString());
4849     }
4850     for (int n = 0; n < kNumTestPackets && iteration != kLastIteration; n++) {
4851       base::StackString<64> expected_payload("transferred_%d_%d", iteration, n);
4852       expected_payloads.emplace_back(expected_payload.ToStdString());
4853     }
4854     ASSERT_THAT(actual_payloads, ElementsAreArray(expected_payloads));
4855   }  // for (iteration)
4856 
4857   consumer->DisableTracing();
4858   producer->WaitForDataSourceStop("ds_1");
4859   producer->WaitForDataSourceStop("ds_2");
4860   consumer->WaitForTracingDisabled();
4861 
4862   // Read the data from the primary (non-cloned) tracing session. Check that
4863   // it doesn't have any "transferred_xxx" payload but only the "persistent_xxx"
4864   // coming from the standard non-transferred buffer.
4865   auto packets = consumer->ReadBuffers();
4866   EXPECT_THAT(packets,
4867               Not(Contains(Property(&protos::gen::TracePacket::for_testing,
4868                                     Property(&protos::gen::TestEvent::str,
4869                                              HasSubstr("transferred_"))))));
4870   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
4871                                          Property(&protos::gen::TestEvent::str,
4872                                                   HasSubstr("persistent_")))));
4873 }
4874 
TEST_F(TracingServiceImplTest,ClearBeforeClone)4875 TEST_F(TracingServiceImplTest, ClearBeforeClone) {
4876   // The consumer that creates the initial tracing session.
4877   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4878   consumer->Connect(svc.get());
4879 
4880   std::unique_ptr<MockProducer> producer = CreateMockProducer();
4881   producer->Connect(svc.get(), "mock_producer");
4882 
4883   producer->RegisterDataSource("ds_1");
4884 
4885   TraceConfig trace_config;
4886   // Unused. This buffer is created only to make the test less trivial and cover
4887   // the case of the clear-bufferd to be the beyond the 0th entry.
4888   trace_config.add_buffers()->set_size_kb(32);
4889 
4890   auto* buf_cfg = trace_config.add_buffers();
4891   buf_cfg->set_size_kb(1024);
4892   buf_cfg->set_clear_before_clone(true);
4893   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
4894   ds_cfg->set_name("ds_1");
4895   ds_cfg->set_target_buffer(1);
4896 
4897   consumer->EnableTracing(trace_config);
4898   producer->WaitForTracingSetup();
4899   producer->WaitForDataSourceSetup("ds_1");
4900   producer->WaitForDataSourceStart("ds_1");
4901 
4902   std::unique_ptr<TraceWriter> writer = producer->CreateTraceWriter("ds_1");
4903 
4904   // These packets, emitted before the clone, should be dropped.
4905   for (int i = 0; i < 3; i++) {
4906     writer->NewTracePacket()->set_for_testing()->set_str("before_clone");
4907   }
4908   auto flush_request = consumer->Flush();
4909   producer->ExpectFlush(writer.get());
4910   ASSERT_TRUE(flush_request.WaitForReply());
4911 
4912   // The consumer the creates the initial tracing session.
4913   std::unique_ptr<MockConsumer> clone_consumer = CreateMockConsumer();
4914   clone_consumer->Connect(svc.get());
4915 
4916   auto clone_done = task_runner.CreateCheckpoint("clone_done");
4917   EXPECT_CALL(*clone_consumer, OnSessionCloned(_))
4918       .WillOnce(InvokeWithoutArgs(clone_done));
4919   clone_consumer->CloneSession(1);
4920 
4921   // CloneSession() will implicitly issue a flush. Write some other packets
4922   // in that callback. Those are the only ones that should survive in the cloned
4923   // session.
4924   FlushFlags flush_flags(FlushFlags::Initiator::kTraced,
4925                          FlushFlags::Reason::kTraceClone);
4926   EXPECT_CALL(*producer, Flush(_, _, _, flush_flags))
4927       .WillOnce(Invoke([&](FlushRequestID flush_req_id,
4928                            const DataSourceInstanceID*, size_t, FlushFlags) {
4929         writer->NewTracePacket()->set_for_testing()->set_str("after_clone");
4930         writer->Flush(
4931             [&] { producer->endpoint()->NotifyFlushComplete(flush_req_id); });
4932       }));
4933 
4934   task_runner.RunUntilCheckpoint("clone_done");
4935 
4936   auto packets = clone_consumer->ReadBuffers();
4937   EXPECT_THAT(packets,
4938               Not(Contains(Property(&protos::gen::TracePacket::for_testing,
4939                                     Property(&protos::gen::TestEvent::str,
4940                                              HasSubstr("before_clone"))))));
4941   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
4942                                          Property(&protos::gen::TestEvent::str,
4943                                                   HasSubstr("after_clone")))));
4944 }
4945 
TEST_F(TracingServiceImplTest,CloneMainSessionStopped)4946 TEST_F(TracingServiceImplTest, CloneMainSessionStopped) {
4947   // The consumer that creates the initial tracing session.
4948   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4949   consumer->Connect(svc.get());
4950 
4951   std::unique_ptr<MockProducer> producer = CreateMockProducer();
4952   producer->Connect(svc.get(), "mock_producer1");
4953   producer->RegisterDataSource("ds_1");
4954 
4955   TraceConfig trace_config;
4956   trace_config.add_buffers()->set_size_kb(1024);  // Buf 0.
4957   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
4958   ds_cfg->set_name("ds_1");
4959   ds_cfg->set_target_buffer(0);
4960 
4961   consumer->EnableTracing(trace_config);
4962   producer->WaitForTracingSetup();
4963   producer->WaitForDataSourceSetup("ds_1");
4964   producer->WaitForDataSourceStart("ds_1");
4965 
4966   std::unique_ptr<TraceWriter> writer = producer->CreateTraceWriter("ds_1");
4967   {
4968     auto packet = writer->NewTracePacket();
4969     packet->set_for_testing()->set_str("before_clone");
4970   }
4971   writer->Flush();
4972 
4973   consumer->DisableTracing();
4974   producer->WaitForDataSourceStop("ds_1");
4975   consumer->WaitForTracingDisabled();
4976 
4977   // The tracing session is disabled, but it's still there. We can still clone
4978   // it.
4979   std::unique_ptr<MockConsumer> clone_consumer = CreateMockConsumer();
4980   clone_consumer->Connect(svc.get());
4981 
4982   auto clone_done = task_runner.CreateCheckpoint("clone_done");
4983   EXPECT_CALL(*clone_consumer, OnSessionCloned(_))
4984       .WillOnce(InvokeWithoutArgs(clone_done));
4985   clone_consumer->CloneSession(1);
4986 
4987   auto packets = clone_consumer->ReadBuffers();
4988   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
4989                                          Property(&protos::gen::TestEvent::str,
4990                                                   HasSubstr("before_clone")))));
4991 }
4992 
TEST_F(TracingServiceImplTest,CloneConsumerDisconnect)4993 TEST_F(TracingServiceImplTest, CloneConsumerDisconnect) {
4994   // The consumer that creates the initial tracing session.
4995   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
4996   consumer->Connect(svc.get());
4997 
4998   std::unique_ptr<MockProducer> producer = CreateMockProducer();
4999   producer->Connect(svc.get(), "mock_producer1");
5000   producer->RegisterDataSource("ds_1");
5001 
5002   TraceConfig trace_config;
5003   trace_config.add_buffers()->set_size_kb(1024);  // Buf 0.
5004   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5005   ds_cfg->set_name("ds_1");
5006   ds_cfg->set_target_buffer(0);
5007 
5008   consumer->EnableTracing(trace_config);
5009   producer->WaitForTracingSetup();
5010   producer->WaitForDataSourceSetup("ds_1");
5011   producer->WaitForDataSourceStart("ds_1");
5012 
5013   std::unique_ptr<TraceWriter> writer1 = producer->CreateTraceWriter("ds_1");
5014 
5015   std::unique_ptr<MockConsumer> clone_consumer = CreateMockConsumer();
5016   clone_consumer->Connect(svc.get());
5017 
5018   // CloneSession() will issue a flush.
5019   std::string producer1_flush_checkpoint_name = "producer1_flush_requested";
5020   FlushRequestID flush1_req_id;
5021   auto flush1_requested =
5022       task_runner.CreateCheckpoint(producer1_flush_checkpoint_name);
5023   EXPECT_CALL(*producer, Flush(_, _, _, _))
5024       .WillOnce([&](FlushRequestID req_id, const DataSourceInstanceID*, size_t,
5025                     FlushFlags) {
5026         flush1_req_id = req_id;
5027         flush1_requested();
5028       });
5029   clone_consumer->CloneSession(1);
5030 
5031   task_runner.RunUntilCheckpoint(producer1_flush_checkpoint_name);
5032 
5033   // producer hasn't replied to the flush yet, so the clone operation is still
5034   // pending.
5035 
5036   // The clone_consumer disconnect and goes away.
5037   clone_consumer.reset();
5038 
5039   // producer replies to the flush request now.
5040   writer1->Flush();
5041   producer->endpoint()->NotifyFlushComplete(flush1_req_id);
5042   task_runner.RunUntilIdle();
5043 
5044   consumer->DisableTracing();
5045   producer->WaitForDataSourceStop("ds_1");
5046   consumer->WaitForTracingDisabled();
5047 }
5048 
TEST_F(TracingServiceImplTest,CloneMainSessionGoesAwayDuringFlush)5049 TEST_F(TracingServiceImplTest, CloneMainSessionGoesAwayDuringFlush) {
5050   // The consumer that creates the initial tracing session.
5051   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5052   consumer->Connect(svc.get());
5053 
5054   std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
5055   producer1->Connect(svc.get(), "mock_producer1");
5056   producer1->RegisterDataSource("ds_1");
5057 
5058   TraceConfig trace_config;
5059   trace_config.add_buffers()->set_size_kb(1024);  // Buf 0.
5060   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5061   ds_cfg->set_name("ds_1");
5062   ds_cfg->set_target_buffer(0);
5063 
5064   consumer->EnableTracing(trace_config);
5065   producer1->WaitForTracingSetup();
5066   producer1->WaitForDataSourceSetup("ds_1");
5067   producer1->WaitForDataSourceStart("ds_1");
5068 
5069   std::unique_ptr<TraceWriter> writer1 = producer1->CreateTraceWriter("ds_1");
5070 
5071   {
5072     auto tp = writer1->NewTracePacket();
5073     tp->set_for_testing()->set_str("buf1_beforeflush");
5074   }
5075   writer1->Flush();
5076 
5077   std::unique_ptr<MockConsumer> clone_consumer = CreateMockConsumer();
5078   clone_consumer->Connect(svc.get());
5079 
5080   std::string clone_done_name = "consumer1_clone_done";
5081   auto clone_done = task_runner.CreateCheckpoint(clone_done_name);
5082   EXPECT_CALL(*clone_consumer, OnSessionCloned)
5083       .Times(1)
5084       .WillOnce(Invoke([&](const Consumer::OnSessionClonedArgs& args) {
5085         EXPECT_FALSE(args.success);
5086         EXPECT_THAT(args.error, HasSubstr("Original session ended"));
5087         clone_done();
5088       }));
5089   clone_consumer->CloneSession(1);
5090 
5091   std::string producer1_flush_checkpoint_name = "producer1_flush_requested";
5092   auto flush1_requested =
5093       task_runner.CreateCheckpoint(producer1_flush_checkpoint_name);
5094   FlushRequestID flush1_req_id;
5095 
5096   // CloneSession() will issue a flush.
5097   EXPECT_CALL(*producer1, Flush(_, _, _, _))
5098       .WillOnce([&](FlushRequestID flush_id, const DataSourceInstanceID*,
5099                     size_t, FlushFlags) {
5100         flush1_req_id = flush_id;
5101         flush1_requested();
5102       });
5103 
5104   task_runner.RunUntilCheckpoint(producer1_flush_checkpoint_name);
5105 
5106   // The main session goes away.
5107   consumer->DisableTracing();
5108   producer1->WaitForDataSourceStop("ds_1");
5109   consumer->WaitForTracingDisabled();
5110   consumer.reset();
5111 
5112   task_runner.RunUntilCheckpoint(clone_done_name);
5113 
5114   // producer1 replies to flush much later.
5115   producer1->endpoint()->NotifyFlushComplete(flush1_req_id);
5116   task_runner.RunUntilIdle();
5117 }
5118 
TEST_F(TracingServiceImplTest,CloneTransferFlush)5119 TEST_F(TracingServiceImplTest, CloneTransferFlush) {
5120   // The consumer the creates the initial tracing session.
5121   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5122   consumer->Connect(svc.get());
5123 
5124   std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
5125   producer1->Connect(svc.get(), "mock_producer1");
5126   producer1->RegisterDataSource("ds_1");
5127 
5128   std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
5129   producer2->Connect(svc.get(), "mock_producer2");
5130   producer2->RegisterDataSource("ds_2");
5131 
5132   TraceConfig trace_config;
5133   trace_config.add_buffers()->set_size_kb(1024);  // Buf 0.
5134   auto* buf1_cfg = trace_config.add_buffers();    // Buf 1 (transfer_on_clone).
5135   buf1_cfg->set_size_kb(1024);
5136   buf1_cfg->set_transfer_on_clone(true);
5137   buf1_cfg->set_clear_before_clone(true);
5138   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5139   ds_cfg->set_name("ds_1");
5140   ds_cfg->set_target_buffer(0);
5141   ds_cfg = trace_config.add_data_sources()->mutable_config();
5142   ds_cfg->set_name("ds_2");
5143   ds_cfg->set_target_buffer(1);
5144 
5145   consumer->EnableTracing(trace_config);
5146   producer1->WaitForTracingSetup();
5147   producer1->WaitForDataSourceSetup("ds_1");
5148 
5149   producer2->WaitForTracingSetup();
5150   producer2->WaitForDataSourceSetup("ds_2");
5151 
5152   producer1->WaitForDataSourceStart("ds_1");
5153   producer2->WaitForDataSourceStart("ds_2");
5154 
5155   std::unique_ptr<TraceWriter> writer1 = producer1->CreateTraceWriter("ds_1");
5156   std::unique_ptr<TraceWriter> writer2 = producer2->CreateTraceWriter("ds_2");
5157 
5158   {
5159     auto tp = writer1->NewTracePacket();
5160     tp->set_for_testing()->set_str("buf1_beforeflush");
5161   }
5162 
5163   {
5164     std::unique_ptr<MockConsumer> clone_consumer = CreateMockConsumer();
5165     clone_consumer->Connect(svc.get());
5166 
5167     {
5168       auto tp = writer2->NewTracePacket();
5169       tp->set_for_testing()->set_str("buf2_beforeflush");
5170     }
5171 
5172     std::string clone_checkpoint_name = "clone";
5173     auto clone_done = task_runner.CreateCheckpoint(clone_checkpoint_name);
5174     EXPECT_CALL(*clone_consumer, OnSessionCloned(_))
5175         .WillOnce(InvokeWithoutArgs(clone_done));
5176     clone_consumer->CloneSession(1);
5177 
5178     std::string producer1_flush_checkpoint_name = "producer1_flush_requested";
5179     FlushRequestID flush1_req_id;
5180     auto flush1_requested =
5181         task_runner.CreateCheckpoint(producer1_flush_checkpoint_name);
5182     std::string producer2_flush_checkpoint_name = "producer2_flush_requested";
5183     FlushRequestID flush2_req_id;
5184     auto flush2_requested =
5185         task_runner.CreateCheckpoint(producer2_flush_checkpoint_name);
5186 
5187     // CloneSession() will issue a flush.
5188     EXPECT_CALL(*producer1, Flush(_, _, _, _))
5189         .WillOnce([&](FlushRequestID req_id, const DataSourceInstanceID*,
5190                       size_t, FlushFlags) {
5191           flush1_req_id = req_id;
5192           flush1_requested();
5193         });
5194     EXPECT_CALL(*producer2, Flush(_, _, _, _))
5195         .WillOnce([&](FlushRequestID req_id, const DataSourceInstanceID*,
5196                       size_t, FlushFlags) {
5197           flush2_req_id = req_id;
5198           flush2_requested();
5199         });
5200 
5201     task_runner.RunUntilCheckpoint(producer1_flush_checkpoint_name);
5202     task_runner.RunUntilCheckpoint(producer2_flush_checkpoint_name);
5203 
5204     // producer1 is fast and replies to the Flush request immediately.
5205     writer1->Flush();
5206     producer1->endpoint()->NotifyFlushComplete(flush1_req_id);
5207     task_runner.RunUntilIdle();
5208 
5209     // producer1 writes another packet, after acking the flush.
5210     {
5211       auto tp = writer1->NewTracePacket();
5212       tp->set_for_testing()->set_str("buf1_afterflush");
5213     }
5214     writer1->Flush();
5215 
5216     // producer2 is slower and is still writing data.
5217     {
5218       auto tp = writer2->NewTracePacket();
5219       tp->set_for_testing()->set_str("buf2_afterflush");
5220     }
5221 
5222     // now producer2 replies to the Flush request.
5223     writer2->Flush();
5224     producer2->endpoint()->NotifyFlushComplete(flush2_req_id);
5225     task_runner.RunUntilCheckpoint(clone_checkpoint_name);
5226 
5227     auto packets = clone_consumer->ReadBuffers();
5228     std::vector<std::string> actual_payloads;
5229     for (const auto& packet : packets) {
5230       if (packet.has_for_testing())
5231         actual_payloads.emplace_back(packet.for_testing().str());
5232     }
5233     EXPECT_THAT(actual_payloads, Contains("buf1_beforeflush"));
5234     EXPECT_THAT(actual_payloads, Contains("buf2_beforeflush"));
5235     // This packet was sent after producer1 acked the flush. producer2 hadn't
5236     // acked the flush yet, but producer2's buffer is on a separate flush group.
5237     EXPECT_THAT(actual_payloads, Not(Contains("buf1_afterflush")));
5238     EXPECT_THAT(actual_payloads, Contains("buf2_afterflush"));
5239   }
5240 
5241   consumer->DisableTracing();
5242   producer1->WaitForDataSourceStop("ds_1");
5243   producer2->WaitForDataSourceStop("ds_2");
5244   consumer->WaitForTracingDisabled();
5245 }
5246 
TEST_F(TracingServiceImplTest,CloneSessionByName)5247 TEST_F(TracingServiceImplTest, CloneSessionByName) {
5248   // The consumer the creates the initial tracing session.
5249   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5250   consumer->Connect(svc.get());
5251 
5252   // The consumer that clones it and reads back the data.
5253   std::unique_ptr<MockConsumer> consumer2 = CreateMockConsumer();
5254   consumer2->Connect(svc.get());
5255 
5256   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5257   producer->Connect(svc.get(), "mock_producer");
5258 
5259   producer->RegisterDataSource("ds_1");
5260 
5261   TraceConfig trace_config;
5262   trace_config.add_buffers()->set_size_kb(32);
5263   trace_config.set_unique_session_name("my_unique_session_name");
5264   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5265   ds_cfg->set_name("ds_1");
5266   ds_cfg->set_target_buffer(0);
5267 
5268   consumer->EnableTracing(trace_config);
5269   producer->WaitForTracingSetup();
5270   producer->WaitForDataSourceSetup("ds_1");
5271   producer->WaitForDataSourceStart("ds_1");
5272 
5273   std::unique_ptr<TraceWriter> writer = producer->CreateTraceWriter("ds_1");
5274 
5275   static constexpr size_t kNumTestPackets = 20;
5276   for (size_t i = 0; i < kNumTestPackets; i++) {
5277     auto tp = writer->NewTracePacket();
5278     std::string payload("payload" + std::to_string(i));
5279     tp->set_for_testing()->set_str(payload.c_str(), payload.size());
5280     tp->set_timestamp(static_cast<uint64_t>(i));
5281   }
5282 
5283   {
5284     auto clone_done = task_runner.CreateCheckpoint("clone_done");
5285     EXPECT_CALL(*consumer2, OnSessionCloned(_))
5286         .WillOnce(
5287             Invoke([clone_done](const Consumer::OnSessionClonedArgs& args) {
5288               ASSERT_TRUE(args.success);
5289               ASSERT_TRUE(args.error.empty());
5290               clone_done();
5291             }));
5292     ConsumerEndpoint::CloneSessionArgs args;
5293     args.unique_session_name = "my_unique_session_name";
5294     consumer2->endpoint()->CloneSession(args);
5295     // CloneSession() will implicitly issue a flush. Linearize with that.
5296     producer->ExpectFlush(writer.get());
5297     task_runner.RunUntilCheckpoint("clone_done");
5298   }
5299 
5300   // Disable the initial tracing session.
5301   consumer->DisableTracing();
5302   producer->WaitForDataSourceStop("ds_1");
5303   consumer->WaitForTracingDisabled();
5304 
5305   // Read back the cloned trace and the original trace.
5306   auto packets = consumer->ReadBuffers();
5307   auto cloned_packets = consumer2->ReadBuffers();
5308   for (size_t i = 0; i < kNumTestPackets; i++) {
5309     std::string payload = "payload" + std::to_string(i);
5310     EXPECT_THAT(packets,
5311                 Contains(Property(
5312                     &protos::gen::TracePacket::for_testing,
5313                     Property(&protos::gen::TestEvent::str, Eq(payload)))));
5314     EXPECT_THAT(cloned_packets,
5315                 Contains(Property(
5316                     &protos::gen::TracePacket::for_testing,
5317                     Property(&protos::gen::TestEvent::str, Eq(payload)))));
5318   }
5319 
5320   // Delete the original tracing session.
5321   consumer->FreeBuffers();
5322 
5323   {
5324     std::unique_ptr<MockConsumer> consumer3 = CreateMockConsumer();
5325     consumer3->Connect(svc.get());
5326 
5327     // The original session is gone. The cloned session is still there. It
5328     // should not be possible to clone that by name.
5329 
5330     auto clone_failed = task_runner.CreateCheckpoint("clone_failed");
5331     EXPECT_CALL(*consumer3, OnSessionCloned(_))
5332         .WillOnce(
5333             Invoke([clone_failed](const Consumer::OnSessionClonedArgs& args) {
5334               EXPECT_FALSE(args.success);
5335               EXPECT_THAT(args.error, HasSubstr("Tracing session not found"));
5336               clone_failed();
5337             }));
5338     ConsumerEndpoint::CloneSessionArgs args_f;
5339     args_f.unique_session_name = "my_unique_session_name";
5340     consumer3->endpoint()->CloneSession(args_f);
5341     task_runner.RunUntilCheckpoint("clone_failed");
5342 
5343     // But it should be possible to clone that by id.
5344     auto clone_success = task_runner.CreateCheckpoint("clone_success");
5345     EXPECT_CALL(*consumer3, OnSessionCloned(_))
5346         .WillOnce(
5347             Invoke([clone_success](const Consumer::OnSessionClonedArgs& args) {
5348               EXPECT_TRUE(args.success);
5349               clone_success();
5350             }));
5351     ConsumerEndpoint::CloneSessionArgs args_s;
5352     args_s.tsid = GetLastTracingSessionId(consumer3.get());
5353     consumer3->endpoint()->CloneSession(args_s);
5354     task_runner.RunUntilCheckpoint("clone_success");
5355   }
5356 }
5357 
TEST_F(TracingServiceImplTest,CloneSnapshotTriggerProducesEvent)5358 TEST_F(TracingServiceImplTest, CloneSnapshotTriggerProducesEvent) {
5359   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5360   consumer->Connect(svc.get());
5361 
5362   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5363   constexpr uid_t kMockProducerUid = 77777;
5364   constexpr auto kMockProducerName = "mock_producer";
5365   producer->Connect(svc.get(), kMockProducerName, kMockProducerUid);
5366   producer->RegisterDataSource("ds_1");
5367 
5368   TraceConfig trace_config;
5369   trace_config.add_buffers()->set_size_kb(128);
5370   trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
5371   auto* trigger_config = trace_config.mutable_trigger_config();
5372   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::CLONE_SNAPSHOT);
5373   trigger_config->set_trigger_timeout_ms(8.64e+7);
5374   auto* trigger = trigger_config->add_triggers();
5375   static constexpr auto kCloneTriggerName = "clone_trigger_name";
5376   trigger->set_name(kCloneTriggerName);
5377   trigger->set_stop_delay_ms(1);
5378 
5379   consumer->ObserveEvents(ObservableEvents::TYPE_CLONE_TRIGGER_HIT);
5380   consumer->EnableTracing(trace_config);
5381   producer->WaitForTracingSetup();
5382 
5383   producer->WaitForDataSourceSetup("ds_1");
5384   producer->WaitForDataSourceStart("ds_1");
5385 
5386   producer->endpoint()->ActivateTriggers({"clone_trigger_name"});
5387 
5388   const auto events = consumer->WaitForObservableEvents();
5389   ASSERT_TRUE(events.has_clone_trigger_hit());
5390   const auto& trigger_hit_event = events.clone_trigger_hit();
5391   EXPECT_EQ(trigger_hit_event.trigger_name(), kCloneTriggerName);
5392   EXPECT_EQ(trigger_hit_event.producer_name(), kMockProducerName);
5393   EXPECT_EQ(trigger_hit_event.producer_uid(), kMockProducerUid);
5394   EXPECT_GT(trigger_hit_event.boot_time_ns(), 0ul);
5395 
5396   consumer->DisableTracing();
5397   producer->WaitForDataSourceStop("ds_1");
5398   consumer->WaitForTracingDisabled();
5399 }
5400 
TEST_F(TracingServiceImplTest,CloneSessionEmitsTrigger)5401 TEST_F(TracingServiceImplTest, CloneSessionEmitsTrigger) {
5402   // The consumer the creates the initial tracing session.
5403   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5404   consumer->Connect(svc.get());
5405 
5406   // The consumer that clones and read the trace.
5407   std::unique_ptr<MockConsumer> consumer2 = CreateMockConsumer();
5408   consumer2->Connect(svc.get());
5409 
5410   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5411   producer->Connect(svc.get(), "mock_producer");
5412 
5413   producer->RegisterDataSource("ds_1");
5414 
5415   TraceConfig trace_config;
5416   trace_config.add_buffers()->set_size_kb(32);
5417   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5418   ds_cfg->set_name("ds_1");
5419   ds_cfg->set_target_buffer(0);
5420 
5421   consumer->EnableTracing(trace_config);
5422   producer->WaitForTracingSetup();
5423   producer->WaitForDataSourceSetup("ds_1");
5424   producer->WaitForDataSourceStart("ds_1");
5425 
5426   std::unique_ptr<TraceWriter> writer = producer->CreateTraceWriter("ds_1");
5427 
5428   static constexpr auto kTestPayload = "test_payload_string";
5429   writer->NewTracePacket()->set_for_testing()->set_str(kTestPayload);
5430 
5431   static constexpr auto kCloneTriggerName = "trigger_name";
5432   static constexpr auto kCloneTriggerProducerName = "trigger_producer_name";
5433   static constexpr uid_t kCloneTriggerProducerUid = 42;
5434   static constexpr uint64_t kCloneTriggerTimestamp = 456789123;
5435   {
5436     auto clone_done = task_runner.CreateCheckpoint("clone_done");
5437     EXPECT_CALL(*consumer2, OnSessionCloned(_))
5438         .WillOnce(
5439             Invoke([clone_done](const Consumer::OnSessionClonedArgs& args) {
5440               ASSERT_TRUE(args.success);
5441               ASSERT_TRUE(args.error.empty());
5442               clone_done();
5443             }));
5444     ConsumerEndpoint::CloneSessionArgs args;
5445     args.tsid = GetLastTracingSessionId(consumer2.get());
5446     args.clone_trigger_name = kCloneTriggerName;
5447     args.clone_trigger_producer_name = kCloneTriggerProducerName;
5448     args.clone_trigger_trusted_producer_uid = kCloneTriggerProducerUid;
5449     args.clone_trigger_boot_time_ns = kCloneTriggerTimestamp;
5450     consumer2->endpoint()->CloneSession(args);
5451     // CloneSession() will implicitly issue a flush. Linearize with that.
5452     producer->ExpectFlush(writer.get());
5453     task_runner.RunUntilCheckpoint("clone_done");
5454   }
5455 
5456   // Disable the initial tracing session.
5457   consumer->DisableTracing();
5458   producer->WaitForDataSourceStop("ds_1");
5459   consumer->WaitForTracingDisabled();
5460 
5461   // Read back the cloned trace and the original trace.
5462   auto packets = consumer->ReadBuffers();
5463   auto cloned_packets = consumer2->ReadBuffers();
5464 
5465   const auto test_payload_matcher =
5466       Property(&protos::gen::TracePacket::for_testing,
5467                Property(&protos::gen::TestEvent::str, Eq(kTestPayload)));
5468 
5469   EXPECT_THAT(packets, Contains(test_payload_matcher));
5470   // Assert original trace doesn't contain "clone_snapshot_trigger" packet.
5471   EXPECT_THAT(
5472       packets,
5473       Not(Contains(Property(
5474           &protos::gen::TracePacket::has_clone_snapshot_trigger, Eq(true)))));
5475 
5476   EXPECT_THAT(cloned_packets, Contains(test_payload_matcher));
5477   std::vector<protos::gen::TracePacket> clone_trigger_packets;
5478   for (const auto& packet : cloned_packets) {
5479     if (packet.has_clone_snapshot_trigger()) {
5480       clone_trigger_packets.push_back(packet);
5481     }
5482   }
5483   ASSERT_EQ(clone_trigger_packets.size(), 1ul);
5484   EXPECT_EQ(clone_trigger_packets[0].timestamp(), kCloneTriggerTimestamp);
5485 
5486   const auto trigger = clone_trigger_packets[0].clone_snapshot_trigger();
5487   EXPECT_EQ(trigger.trigger_name(), kCloneTriggerName);
5488   EXPECT_EQ(trigger.producer_name(), kCloneTriggerProducerName);
5489   EXPECT_EQ(trigger.trusted_producer_uid(),
5490             static_cast<int32_t>(kCloneTriggerProducerUid));
5491 }
5492 
TEST_F(TracingServiceImplTest,InvalidBufferSizes)5493 TEST_F(TracingServiceImplTest, InvalidBufferSizes) {
5494   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5495   consumer->Connect(svc.get());
5496 
5497   TraceConfig trace_config;
5498   trace_config.add_buffers()->set_size_kb(128);
5499   trace_config.add_buffers()->set_size_kb(256);
5500   trace_config.add_buffers()->set_size_kb(4 * 1024 * 1024);
5501   auto* ds = trace_config.add_data_sources();
5502   auto* ds_config = ds->mutable_config();
5503   ds_config->set_name("data_source");
5504   consumer->EnableTracing(trace_config);
5505 
5506   std::string error;
5507   auto checkpoint = task_runner.CreateCheckpoint("tracing_disabled");
5508   EXPECT_CALL(*consumer, OnTracingDisabled(_))
5509       .WillOnce(DoAll(SaveArg<0>(&error), checkpoint));
5510   task_runner.RunUntilCheckpoint("tracing_disabled");
5511   EXPECT_THAT(error, HasSubstr("Invalid buffer sizes"));
5512 }
5513 
TEST_F(TracingServiceImplTest,StringFiltering)5514 TEST_F(TracingServiceImplTest, StringFiltering) {
5515   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5516   consumer->Connect(svc.get());
5517 
5518   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5519   producer->Connect(svc.get(), "mock_producer");
5520 
5521   producer->RegisterDataSource("ds_1");
5522 
5523   TraceConfig trace_config;
5524   trace_config.add_buffers()->set_size_kb(32);  // Buf 0.
5525   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5526   ds_cfg->set_name("ds_1");
5527   ds_cfg->set_target_buffer(0);
5528 
5529   protozero::FilterBytecodeGenerator filt;
5530   // Message 0: root Trace proto.
5531   filt.AddNestedField(1 /* root trace.packet*/, 1);
5532   filt.EndMessage();
5533   // Message 1: TracePacket proto. Allow only the `for_testing` sub-field.
5534   filt.AddNestedField(protos::pbzero::TracePacket::kForTestingFieldNumber, 2);
5535   filt.EndMessage();
5536   // Message 2: TestEvent proto. Allow only the `str` sub-field as a striong.
5537   filt.AddFilterStringField(protos::pbzero::TestEvent::kStrFieldNumber);
5538   filt.EndMessage();
5539   trace_config.mutable_trace_filter()->set_bytecode_v2(filt.Serialize());
5540 
5541   auto* chain =
5542       trace_config.mutable_trace_filter()->mutable_string_filter_chain();
5543   auto* rule = chain->add_rules();
5544   rule->set_policy(
5545       protos::gen::TraceConfig::TraceFilter::SFP_ATRACE_MATCH_REDACT_GROUPS);
5546   rule->set_atrace_payload_starts_with("payload1");
5547   rule->set_regex_pattern(R"(B\|\d+\|pay(lo)ad1(\d*))");
5548 
5549   consumer->EnableTracing(trace_config);
5550   producer->WaitForTracingSetup();
5551 
5552   producer->WaitForDataSourceSetup("ds_1");
5553   producer->WaitForDataSourceStart("ds_1");
5554 
5555   std::unique_ptr<TraceWriter> writer = producer->CreateTraceWriter("ds_1");
5556   static constexpr size_t kNumTestPackets = 20;
5557   for (size_t i = 0; i < kNumTestPackets; i++) {
5558     auto tp = writer->NewTracePacket();
5559     std::string payload("B|1023|payload" + std::to_string(i));
5560     tp->set_for_testing()->set_str(payload.c_str(), payload.size());
5561   }
5562 
5563   auto flush_request = consumer->Flush();
5564   producer->ExpectFlush(writer.get());
5565   ASSERT_TRUE(flush_request.WaitForReply());
5566 
5567   const DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_1");
5568   EXPECT_CALL(*producer, StopDataSource(id1));
5569 
5570   consumer->DisableTracing();
5571   consumer->WaitForTracingDisabled();
5572 
5573   auto packets = consumer->ReadBuffers();
5574   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
5575                                          Property(&protos::gen::TestEvent::str,
5576                                                   Eq("B|1023|payP6ad1")))));
5577   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
5578                                          Property(&protos::gen::TestEvent::str,
5579                                                   Eq("B|1023|payP6ad1P")))));
5580 }
5581 
TEST_F(TracingServiceImplTest,StringFilteringAndCloneSession)5582 TEST_F(TracingServiceImplTest, StringFilteringAndCloneSession) {
5583   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5584   consumer->Connect(svc.get());
5585 
5586   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5587   producer->Connect(svc.get(), "mock_producer");
5588 
5589   producer->RegisterDataSource("ds_1");
5590 
5591   TraceConfig trace_config;
5592   trace_config.add_buffers()->set_size_kb(32);  // Buf 0.
5593   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5594   ds_cfg->set_name("ds_1");
5595   ds_cfg->set_target_buffer(0);
5596 
5597   protozero::FilterBytecodeGenerator filt;
5598   // Message 0: root Trace proto.
5599   filt.AddNestedField(1 /* root trace.packet*/, 1);
5600   filt.EndMessage();
5601   // Message 1: TracePacket proto. Allow only the `for_testing` sub-field.
5602   filt.AddNestedField(protos::pbzero::TracePacket::kForTestingFieldNumber, 2);
5603   filt.EndMessage();
5604   // Message 2: TestEvent proto. Allow only the `str` sub-field as a string.
5605   filt.AddFilterStringField(protos::pbzero::TestEvent::kStrFieldNumber);
5606   filt.EndMessage();
5607   trace_config.mutable_trace_filter()->set_bytecode_v2(filt.Serialize());
5608 
5609   auto* chain =
5610       trace_config.mutable_trace_filter()->mutable_string_filter_chain();
5611   auto* rule = chain->add_rules();
5612   rule->set_policy(
5613       protos::gen::TraceConfig::TraceFilter::SFP_ATRACE_MATCH_REDACT_GROUPS);
5614   rule->set_atrace_payload_starts_with("payload");
5615   rule->set_regex_pattern(R"(B\|\d+\|pay(lo)ad(\d*))");
5616 
5617   consumer->EnableTracing(trace_config);
5618   producer->WaitForTracingSetup();
5619 
5620   producer->WaitForDataSourceSetup("ds_1");
5621   producer->WaitForDataSourceStart("ds_1");
5622 
5623   std::unique_ptr<TraceWriter> writer = producer->CreateTraceWriter("ds_1");
5624 
5625   {
5626     auto tp = writer->NewTracePacket();
5627     tp->set_for_testing()->set_str("B|1023|payload");
5628   }
5629 
5630   std::unique_ptr<MockConsumer> consumer2 = CreateMockConsumer();
5631   consumer2->Connect(svc.get());
5632 
5633   auto clone_done = task_runner.CreateCheckpoint("clone_done");
5634   EXPECT_CALL(*consumer2, OnSessionCloned(_))
5635       .WillOnce(Invoke([clone_done](const Consumer::OnSessionClonedArgs&) {
5636         clone_done();
5637       }));
5638   consumer2->CloneSession(1);
5639   // CloneSession() will implicitly issue a flush. Linearize with that.
5640   producer->ExpectFlush(std::vector<TraceWriter*>{writer.get()});
5641   task_runner.RunUntilCheckpoint("clone_done");
5642 
5643   const DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("ds_1");
5644   EXPECT_CALL(*producer, StopDataSource(id1));
5645 
5646   consumer->DisableTracing();
5647   consumer->WaitForTracingDisabled();
5648 
5649   auto packets = consumer->ReadBuffers();
5650   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
5651                                          Property(&protos::gen::TestEvent::str,
5652                                                   Eq("B|1023|payP6ad")))));
5653   EXPECT_THAT(packets,
5654               Not(Contains(Property(&protos::gen::TracePacket::for_testing,
5655                                     Property(&protos::gen::TestEvent::str,
5656                                              Eq("B|1023|payload"))))));
5657 
5658   auto cloned_packets = consumer2->ReadBuffers();
5659   EXPECT_THAT(cloned_packets,
5660               Contains(Property(&protos::gen::TracePacket::for_testing,
5661                                 Property(&protos::gen::TestEvent::str,
5662                                          Eq("B|1023|payP6ad")))));
5663   EXPECT_THAT(cloned_packets,
5664               Not(Contains(Property(&protos::gen::TracePacket::for_testing,
5665                                     Property(&protos::gen::TestEvent::str,
5666                                              Eq("B|1023|payload"))))));
5667 }
5668 
5669 // This is a regression test for https://b.corp.google.com/issues/307601836. The
5670 // test covers the case of a consumer disconnecting while the tracing session is
5671 // executing the final flush.
TEST_F(TracingServiceImplTest,ConsumerDisconnectionRacesFlushAndDisable)5672 TEST_F(TracingServiceImplTest, ConsumerDisconnectionRacesFlushAndDisable) {
5673   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5674   consumer->Connect(svc.get());
5675 
5676   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5677   producer->Connect(svc.get(), "mock_producer");
5678 
5679   producer->RegisterDataSource("ds");
5680 
5681   TraceConfig trace_config;
5682   trace_config.add_buffers()->set_size_kb(128);
5683   auto* trigger_config = trace_config.mutable_trigger_config();
5684   trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
5685   trigger_config->set_trigger_timeout_ms(100000);
5686   auto* trigger = trigger_config->add_triggers();
5687   trigger->set_name("trigger_name");
5688   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5689   ds_cfg->set_name("ds");
5690 
5691   consumer->EnableTracing(trace_config);
5692   producer->WaitForTracingSetup();
5693   producer->WaitForDataSourceSetup("ds");
5694   producer->WaitForDataSourceStart("ds");
5695 
5696   auto writer1 = producer->CreateTraceWriter("ds");
5697 
5698   auto producer_flush_cb = [&](FlushRequestID flush_req_id,
5699                                const DataSourceInstanceID* /*id*/, size_t,
5700                                FlushFlags) {
5701     // Notify the tracing service that the flush is complete.
5702     producer->endpoint()->NotifyFlushComplete(flush_req_id);
5703     // Also disconnect the consumer (this terminates the tracing session). The
5704     // consumer disconnection is postponed with a PostTask(). The goal is to run
5705     // the lambda inside TracingServiceImpl::FlushAndDisableTracing() with an
5706     // empty `tracing_sessions_` map.
5707     task_runner.PostTask([&]() { consumer.reset(); });
5708   };
5709   EXPECT_CALL(*producer, Flush(_, _, _, _)).WillOnce(Invoke(producer_flush_cb));
5710 
5711   // Cause the tracing session to stop. Note that
5712   // TracingServiceImpl::FlushAndDisableTracing() is also called when
5713   // duration_ms expires, but in a test it's faster to use a trigger.
5714   producer->endpoint()->ActivateTriggers({"trigger_name"});
5715   producer->WaitForDataSourceStop("ds");
5716 
5717   task_runner.RunUntilIdle();
5718 }
5719 
TEST_F(TracingServiceImplTest,RelayEndpointClockSync)5720 TEST_F(TracingServiceImplTest, RelayEndpointClockSync) {
5721   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5722   consumer->Connect(svc.get());
5723 
5724   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5725   producer->Connect(svc.get(), "mock_producer");
5726 
5727   auto relay_client = svc->ConnectRelayClient(
5728       std::make_pair<uint32_t, uint64_t>(/*base::MachineID=*/0x103, 1));
5729 
5730   uint32_t clock_id =
5731       static_cast<uint32_t>(protos::gen::BuiltinClock::BUILTIN_CLOCK_BOOTTIME);
5732 
5733   relay_client->SyncClocks(RelayEndpoint::SyncMode::PING,
5734                            /*client_clocks=*/{{clock_id, 100}},
5735                            /*host_clocks=*/{{clock_id, 1000}});
5736   relay_client->SyncClocks(RelayEndpoint::SyncMode::UPDATE,
5737                            /*client_clocks=*/{{clock_id, 300}},
5738                            /*host_clocks=*/{{clock_id, 1200}});
5739 
5740   producer->RegisterDataSource("ds");
5741 
5742   TraceConfig trace_config;
5743   trace_config.add_buffers()->set_size_kb(128);
5744   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5745   ds_cfg->set_name("ds");
5746 
5747   consumer->EnableTracing(trace_config);
5748   producer->WaitForTracingSetup();
5749   producer->WaitForDataSourceSetup("ds");
5750   producer->WaitForDataSourceStart("ds");
5751 
5752   auto writer1 = producer->CreateTraceWriter("ds");
5753 
5754   consumer->DisableTracing();
5755   producer->WaitForDataSourceStop("ds");
5756   consumer->WaitForTracingDisabled();
5757 
5758   task_runner.RunUntilIdle();
5759 
5760   auto trace_packets = consumer->ReadBuffers();
5761   bool clock_sync_packet_seen = false;
5762   for (auto& packet : trace_packets) {
5763     if (!packet.has_remote_clock_sync())
5764       continue;
5765     clock_sync_packet_seen = true;
5766 
5767     auto& remote_clock_sync = packet.remote_clock_sync();
5768     ASSERT_EQ(remote_clock_sync.synced_clocks_size(), 2);
5769 
5770     auto& snapshots = remote_clock_sync.synced_clocks();
5771     ASSERT_TRUE(snapshots[0].has_client_clocks());
5772     auto* snapshot = &snapshots[0].client_clocks();
5773     ASSERT_EQ(snapshot->clocks_size(), 1);
5774     ASSERT_EQ(snapshot->clocks()[0].clock_id(), clock_id);
5775     ASSERT_EQ(snapshot->clocks()[0].timestamp(), 100u);
5776 
5777     snapshot = &snapshots[0].host_clocks();
5778     ASSERT_EQ(snapshot->clocks_size(), 1);
5779     ASSERT_EQ(snapshot->clocks()[0].clock_id(), clock_id);
5780     ASSERT_EQ(snapshot->clocks()[0].timestamp(), 1000u);
5781 
5782     snapshot = &snapshots[1].client_clocks();
5783     ASSERT_EQ(snapshot->clocks_size(), 1);
5784     ASSERT_EQ(snapshot->clocks()[0].clock_id(), clock_id);
5785     ASSERT_EQ(snapshot->clocks()[0].timestamp(), 300u);
5786 
5787     snapshot = &snapshots[1].host_clocks();
5788     ASSERT_EQ(snapshot->clocks_size(), 1);
5789     ASSERT_EQ(snapshot->clocks()[0].clock_id(), clock_id);
5790     ASSERT_EQ(snapshot->clocks()[0].timestamp(), 1200u);
5791   }
5792   ASSERT_TRUE(clock_sync_packet_seen);
5793 }
5794 
TEST_F(TracingServiceImplTest,RelayEndpointDisconnect)5795 TEST_F(TracingServiceImplTest, RelayEndpointDisconnect) {
5796   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5797   consumer->Connect(svc.get());
5798 
5799   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5800   producer->Connect(svc.get(), "mock_producer");
5801 
5802   auto relay_client = svc->ConnectRelayClient(
5803       std::make_pair<uint32_t, uint64_t>(/*base::MachineID=*/0x103, 1));
5804   uint32_t clock_id =
5805       static_cast<uint32_t>(protos::gen::BuiltinClock::BUILTIN_CLOCK_BOOTTIME);
5806 
5807   relay_client->SyncClocks(RelayEndpoint::SyncMode::PING,
5808                            /*client_clocks=*/{{clock_id, 100}},
5809                            /*host_clocks=*/{{clock_id, 1000}});
5810   relay_client->SyncClocks(RelayEndpoint::SyncMode::UPDATE,
5811                            /*client_clocks=*/{{clock_id, 300}},
5812                            /*host_clocks=*/{{clock_id, 1200}});
5813 
5814   relay_client->Disconnect();
5815 
5816   producer->RegisterDataSource("ds");
5817 
5818   TraceConfig trace_config;
5819   trace_config.add_buffers()->set_size_kb(128);
5820   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
5821   ds_cfg->set_name("ds");
5822 
5823   consumer->EnableTracing(trace_config);
5824   producer->WaitForTracingSetup();
5825   producer->WaitForDataSourceSetup("ds");
5826   producer->WaitForDataSourceStart("ds");
5827 
5828   auto writer1 = producer->CreateTraceWriter("ds");
5829 
5830   consumer->DisableTracing();
5831   producer->WaitForDataSourceStop("ds");
5832   consumer->WaitForTracingDisabled();
5833 
5834   task_runner.RunUntilIdle();
5835 
5836   auto trace_packets = consumer->ReadBuffers();
5837   bool clock_sync_packet_seen = false;
5838   for (auto& packet : trace_packets) {
5839     if (!packet.has_remote_clock_sync())
5840       continue;
5841     clock_sync_packet_seen = true;
5842   }
5843   ASSERT_FALSE(clock_sync_packet_seen);
5844 }
5845 
TEST_F(TracingServiceImplTest,SessionSemaphoreMutexSingleSession)5846 TEST_F(TracingServiceImplTest, SessionSemaphoreMutexSingleSession) {
5847   TraceConfig trace_config;
5848   trace_config.add_buffers()->set_size_kb(32);  // Buf 0.
5849   trace_config.add_session_semaphores()->set_name("mutex");
5850 
5851   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5852   producer->Connect(svc.get(), "mock_producer");
5853 
5854   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5855   consumer->Connect(svc.get());
5856   consumer->EnableTracing(trace_config);
5857   consumer->DisableTracing();
5858   consumer->WaitForTracingDisabledWithError(IsEmpty());
5859 }
5860 
TEST_F(TracingServiceImplTest,SessionSemaphoreMutexMultipleSession)5861 TEST_F(TracingServiceImplTest, SessionSemaphoreMutexMultipleSession) {
5862   TraceConfig trace_config;
5863   trace_config.add_buffers()->set_size_kb(32);
5864   trace_config.add_session_semaphores()->set_name("mutex");
5865 
5866   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5867   consumer->Connect(svc.get());
5868   consumer->EnableTracing(trace_config);
5869 
5870   std::unique_ptr<MockConsumer> consumer2 = CreateMockConsumer();
5871   consumer2->Connect(svc.get());
5872   consumer2->EnableTracing(trace_config);
5873   consumer2->WaitForTracingDisabledWithError(LowerCase(HasSubstr("semaphore")));
5874 
5875   consumer->DisableTracing();
5876   consumer->WaitForTracingDisabledWithError(IsEmpty());
5877 }
5878 
TEST_F(TracingServiceImplTest,SessionSemaphoreHigherCurrentFails)5879 TEST_F(TracingServiceImplTest, SessionSemaphoreHigherCurrentFails) {
5880   TraceConfig trace_config;
5881   trace_config.add_buffers()->set_size_kb(32);
5882 
5883   auto* session_semaphore = trace_config.add_session_semaphores();
5884   session_semaphore->set_name("diff_value_semaphore");
5885   session_semaphore->set_max_other_session_count(0);
5886 
5887   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5888   consumer->Connect(svc.get());
5889   consumer->EnableTracing(trace_config);
5890 
5891   // The second consumer sets a higher count.
5892   session_semaphore->set_max_other_session_count(1);
5893 
5894   std::unique_ptr<MockConsumer> consumer2 = CreateMockConsumer();
5895   consumer2->Connect(svc.get());
5896   consumer2->EnableTracing(trace_config);
5897   consumer2->WaitForTracingDisabledWithError(LowerCase(HasSubstr("semaphore")));
5898 
5899   consumer->DisableTracing();
5900   consumer->WaitForTracingDisabledWithError(IsEmpty());
5901 }
5902 
TEST_F(TracingServiceImplTest,SessionSemaphoreHigherPreviousFails)5903 TEST_F(TracingServiceImplTest, SessionSemaphoreHigherPreviousFails) {
5904   TraceConfig trace_config;
5905   trace_config.add_buffers()->set_size_kb(32);
5906 
5907   auto* session_semaphore = trace_config.add_session_semaphores();
5908   session_semaphore->set_name("diff_value_semaphore");
5909   session_semaphore->set_max_other_session_count(1);
5910 
5911   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5912   consumer->Connect(svc.get());
5913   consumer->EnableTracing(trace_config);
5914 
5915   // The second consumer sets a lower count.
5916   session_semaphore->set_max_other_session_count(0);
5917 
5918   std::unique_ptr<MockConsumer> consumer2 = CreateMockConsumer();
5919   consumer2->Connect(svc.get());
5920   consumer2->EnableTracing(trace_config);
5921   consumer2->WaitForTracingDisabledWithError(LowerCase(HasSubstr("semaphore")));
5922 
5923   consumer->DisableTracing();
5924   consumer->WaitForTracingDisabledWithError(IsEmpty());
5925 }
5926 
TEST_F(TracingServiceImplTest,SessionSemaphoreAllowedUpToLimit)5927 TEST_F(TracingServiceImplTest, SessionSemaphoreAllowedUpToLimit) {
5928   TraceConfig trace_config;
5929   trace_config.add_buffers()->set_size_kb(32);
5930 
5931   auto* session_semaphore = trace_config.add_session_semaphores();
5932   session_semaphore->set_name("multi_semaphore");
5933   session_semaphore->set_max_other_session_count(3);
5934 
5935   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5936   consumer->Connect(svc.get());
5937   consumer->EnableTracing(trace_config);
5938 
5939   std::unique_ptr<MockConsumer> consumer2 = CreateMockConsumer();
5940   consumer2->Connect(svc.get());
5941   consumer2->EnableTracing(trace_config);
5942 
5943   std::unique_ptr<MockConsumer> consumer3 = CreateMockConsumer();
5944   consumer3->Connect(svc.get());
5945   consumer3->EnableTracing(trace_config);
5946 
5947   std::unique_ptr<MockConsumer> consumer4 = CreateMockConsumer();
5948   consumer4->Connect(svc.get());
5949   consumer4->EnableTracing(trace_config);
5950 
5951   std::unique_ptr<MockConsumer> consumer5 = CreateMockConsumer();
5952   consumer5->Connect(svc.get());
5953   consumer5->EnableTracing(trace_config);
5954   consumer5->WaitForTracingDisabledWithError(LowerCase(HasSubstr("semaphore")));
5955 
5956   consumer4->DisableTracing();
5957   consumer4->WaitForTracingDisabledWithError(IsEmpty());
5958 
5959   consumer3->DisableTracing();
5960   consumer3->WaitForTracingDisabledWithError(IsEmpty());
5961 
5962   consumer2->DisableTracing();
5963   consumer2->WaitForTracingDisabledWithError(IsEmpty());
5964 
5965   consumer->DisableTracing();
5966   consumer->WaitForTracingDisabledWithError(IsEmpty());
5967 }
5968 
TEST_F(TracingServiceImplTest,DetachAttach)5969 TEST_F(TracingServiceImplTest, DetachAttach) {
5970   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
5971   consumer->Connect(svc.get());
5972 
5973   std::unique_ptr<MockProducer> producer = CreateMockProducer();
5974   producer->Connect(svc.get(), "mock_producer");
5975   producer->RegisterDataSource("data_source");
5976 
5977   TraceConfig trace_config;
5978   trace_config.add_buffers()->set_size_kb(128);
5979   auto* ds_config = trace_config.add_data_sources()->mutable_config();
5980   ds_config->set_name("data_source");
5981   ds_config->set_target_buffer(0);
5982   consumer->EnableTracing(trace_config);
5983 
5984   producer->WaitForTracingSetup();
5985   producer->WaitForDataSourceSetup("data_source");
5986   producer->WaitForDataSourceStart("data_source");
5987 
5988   std::string on_detach_name = "on_detach";
5989   auto on_detach = task_runner.CreateCheckpoint(on_detach_name);
5990   EXPECT_CALL(*consumer, OnDetach(Eq(true))).WillOnce(Invoke(on_detach));
5991 
5992   consumer->Detach("mykey");
5993 
5994   task_runner.RunUntilCheckpoint(on_detach_name);
5995 
5996   consumer.reset();
5997 
5998   std::unique_ptr<TraceWriter> writer =
5999       producer->CreateTraceWriter("data_source");
6000   {
6001     auto tp = writer->NewTracePacket();
6002     tp->set_for_testing()->set_str("payload-1");
6003   }
6004   {
6005     auto tp = writer->NewTracePacket();
6006     tp->set_for_testing()->set_str("payload-2");
6007   }
6008 
6009   writer->Flush();
6010   writer.reset();
6011 
6012   consumer = CreateMockConsumer();
6013   consumer->Connect(svc.get());
6014 
6015   TraceConfig attached_config;
6016   std::string on_attach_name = "on_attach";
6017   auto on_attach = task_runner.CreateCheckpoint(on_attach_name);
6018   EXPECT_CALL(*consumer, OnAttach(Eq(true), _))
6019       .WillOnce(Invoke([&](bool, const TraceConfig& cfg) {
6020         attached_config = cfg;
6021         on_attach();
6022       }));
6023 
6024   consumer->Attach("mykey");
6025 
6026   task_runner.RunUntilCheckpoint(on_attach_name);
6027 
6028   EXPECT_EQ(attached_config, trace_config);
6029 
6030   consumer->DisableTracing();
6031   producer->WaitForDataSourceStop("data_source");
6032   consumer->WaitForTracingDisabled();
6033 
6034   std::vector<protos::gen::TracePacket> packets = consumer->ReadBuffers();
6035   EXPECT_THAT(packets, Not(IsEmpty()));
6036   EXPECT_THAT(
6037       packets,
6038       Each(Property(&protos::gen::TracePacket::has_compressed_packets, false)));
6039   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
6040                                          Property(&protos::gen::TestEvent::str,
6041                                                   Eq("payload-1")))));
6042   EXPECT_THAT(packets, Contains(Property(&protos::gen::TracePacket::for_testing,
6043                                          Property(&protos::gen::TestEvent::str,
6044                                                   Eq("payload-2")))));
6045 }
6046 
TEST_F(TracingServiceImplTest,DetachDurationTimeoutFreeBuffers)6047 TEST_F(TracingServiceImplTest, DetachDurationTimeoutFreeBuffers) {
6048   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
6049   consumer->Connect(svc.get());
6050 
6051   TraceConfig trace_config;
6052   trace_config.add_buffers()->set_size_kb(128);
6053   auto* ds_config = trace_config.add_data_sources()->mutable_config();
6054   ds_config->set_name("data_source");
6055   trace_config.set_duration_ms(1);
6056   trace_config.set_write_into_file(true);
6057   trace_config.set_file_write_period_ms(100000);
6058   auto pipe_pair = base::Pipe::Create();
6059   consumer->EnableTracing(trace_config, std::move(pipe_pair.wr));
6060 
6061   std::string on_detach_name = "on_detach";
6062   auto on_detach = task_runner.CreateCheckpoint(on_detach_name);
6063   EXPECT_CALL(*consumer, OnDetach(Eq(true))).WillOnce(Invoke(on_detach));
6064 
6065   consumer->Detach("mykey");
6066 
6067   task_runner.RunUntilCheckpoint(on_detach_name);
6068 
6069   std::string file_closed_name = "file_closed";
6070   auto file_closed = task_runner.CreateCheckpoint(file_closed_name);
6071   task_runner.AddFileDescriptorWatch(*pipe_pair.rd, [&] {
6072     char buf[1024];
6073     if (base::Read(*pipe_pair.rd, buf, sizeof(buf)) <= 0) {
6074       file_closed();
6075     }
6076   });
6077   task_runner.RunUntilCheckpoint(file_closed_name);
6078 
6079   // Disabled and detached tracing sessions are automatically deleted:
6080   // reattaching fails.
6081   std::string on_attach_name = "on_attach";
6082   auto on_attach = task_runner.CreateCheckpoint(on_attach_name);
6083   EXPECT_CALL(*consumer, OnAttach(Eq(false), _))
6084       .WillOnce(InvokeWithoutArgs(on_attach));
6085   consumer->Attach("mykey");
6086   task_runner.RunUntilCheckpoint(on_attach_name);
6087 }
6088 
TEST_F(TracingServiceImplTest,SlowStartingDataSources)6089 TEST_F(TracingServiceImplTest, SlowStartingDataSources) {
6090   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
6091   consumer->Connect(svc.get());
6092 
6093   std::unique_ptr<MockProducer> producer = CreateMockProducer();
6094   producer->Connect(svc.get(), "mock_producer");
6095   producer->RegisterDataSource("data_source1", /*ack_stop=*/false,
6096                                /*ack_start=*/true);
6097   producer->RegisterDataSource("data_source2", /*ack_stop=*/false,
6098                                /*ack_start=*/true);
6099   producer->RegisterDataSource("data_source3", /*ack_stop=*/false,
6100                                /*ack_start=*/true);
6101 
6102   TraceConfig trace_config;
6103   trace_config.add_buffers()->set_size_kb(128);
6104   trace_config.add_data_sources()->mutable_config()->set_name("data_source1");
6105   trace_config.add_data_sources()->mutable_config()->set_name("data_source2");
6106   trace_config.add_data_sources()->mutable_config()->set_name("data_source3");
6107   consumer->EnableTracing(trace_config);
6108 
6109   producer->WaitForTracingSetup();
6110   producer->WaitForDataSourceSetup("data_source1");
6111   producer->WaitForDataSourceSetup("data_source2");
6112   producer->WaitForDataSourceSetup("data_source3");
6113 
6114   producer->WaitForDataSourceStart("data_source1");
6115   producer->WaitForDataSourceStart("data_source2");
6116   producer->WaitForDataSourceStart("data_source3");
6117 
6118   DataSourceInstanceID id1 = producer->GetDataSourceInstanceId("data_source1");
6119   DataSourceInstanceID id3 = producer->GetDataSourceInstanceId("data_source3");
6120 
6121   producer->endpoint()->NotifyDataSourceStarted(id1);
6122   producer->endpoint()->NotifyDataSourceStarted(id3);
6123 
6124   // This matches kAllDataSourceStartedTimeout.
6125   AdvanceTimeAndRunUntilIdle(20000);
6126 
6127   consumer->DisableTracing();
6128   producer->WaitForDataSourceStop("data_source1");
6129   producer->WaitForDataSourceStop("data_source2");
6130   producer->WaitForDataSourceStop("data_source3");
6131   consumer->WaitForTracingDisabled();
6132 
6133   std::vector<protos::gen::TracePacket> packets = consumer->ReadBuffers();
6134   EXPECT_THAT(
6135       packets,
6136       Contains(Property(
6137           &protos::gen::TracePacket::service_event,
6138           Property(
6139               &protos::gen::TracingServiceEvent::slow_starting_data_sources,
6140               Property(
6141                   &protos::gen::TracingServiceEvent::DataSources::data_source,
6142                   ElementsAre(
6143                       Property(&protos::gen::TracingServiceEvent::DataSources::
6144                                    DataSource::data_source_name,
6145                                "data_source2")))))));
6146 }
6147 
TEST_F(TracingServiceImplTest,FlushTimeoutEventsEmitted)6148 TEST_F(TracingServiceImplTest, FlushTimeoutEventsEmitted) {
6149   std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
6150   consumer->Connect(svc.get());
6151 
6152   std::unique_ptr<MockProducer> producer = CreateMockProducer();
6153   producer->Connect(svc.get(), "mock_producer1");
6154   producer->RegisterDataSource("ds_1");
6155 
6156   TraceConfig trace_config;
6157   trace_config.add_buffers()->set_size_kb(1024);  // Buf 0.
6158   auto* ds_cfg = trace_config.add_data_sources()->mutable_config();
6159   ds_cfg->set_name("ds_1");
6160   ds_cfg->set_target_buffer(0);
6161 
6162   consumer->EnableTracing(trace_config);
6163   producer->WaitForTracingSetup();
6164   producer->WaitForDataSourceSetup("ds_1");
6165   producer->WaitForDataSourceStart("ds_1");
6166 
6167   std::unique_ptr<TraceWriter> writer1 = producer->CreateTraceWriter("ds_1");
6168 
6169   // Do not reply to Flush.
6170   std::string producer_flush1_checkpoint_name = "producer_flush1_requested";
6171   auto flush1_requested =
6172       task_runner.CreateCheckpoint(producer_flush1_checkpoint_name);
6173   EXPECT_CALL(*producer, Flush).WillOnce(Invoke(flush1_requested));
6174   consumer->Flush(5000, FlushFlags(FlushFlags::Initiator::kTraced,
6175                                    FlushFlags::Reason::kTraceStop));
6176 
6177   task_runner.RunUntilCheckpoint(producer_flush1_checkpoint_name);
6178 
6179   AdvanceTimeAndRunUntilIdle(5000);
6180 
6181   // ReadBuffers returns a last_flush_slow_data_source event.
6182   std::vector<protos::gen::TracePacket> packets = consumer->ReadBuffers();
6183   EXPECT_THAT(
6184       packets,
6185       Contains(Property(
6186           &protos::gen::TracePacket::service_event,
6187           Property(
6188               &protos::gen::TracingServiceEvent::last_flush_slow_data_sources,
6189               Property(
6190                   &protos::gen::TracingServiceEvent::DataSources::data_source,
6191                   ElementsAre(
6192                       Property(&protos::gen::TracingServiceEvent::DataSources::
6193                                    DataSource::data_source_name,
6194                                "ds_1")))))));
6195 
6196   // Reply to Flush.
6197   std::string producer_flush2_checkpoint_name = "producer_flush2_requested";
6198   auto flush2_requested =
6199       task_runner.CreateCheckpoint(producer_flush2_checkpoint_name);
6200   FlushRequestID flush2_req_id;
6201   EXPECT_CALL(*producer, Flush(_, _, _, _))
6202       .WillOnce([&](FlushRequestID req_id, const DataSourceInstanceID*, size_t,
6203                     FlushFlags) {
6204         flush2_req_id = req_id;
6205         flush2_requested();
6206       });
6207   consumer->Flush(5000, FlushFlags(FlushFlags::Initiator::kTraced,
6208                                    FlushFlags::Reason::kTraceStop));
6209 
6210   task_runner.RunUntilCheckpoint(producer_flush2_checkpoint_name);
6211 
6212   producer->endpoint()->NotifyFlushComplete(flush2_req_id);
6213 
6214   AdvanceTimeAndRunUntilIdle(5000);
6215 
6216   // ReadBuffers returns a last_flush_slow_data_source event.
6217   packets = consumer->ReadBuffers();
6218   EXPECT_THAT(
6219       packets,
6220       Not(Contains(Property(&protos::gen::TracePacket::service_event,
6221                             Property(&protos::gen::TracingServiceEvent::
6222                                          has_last_flush_slow_data_sources,
6223                                      Eq(true))))));
6224 
6225   consumer->DisableTracing();
6226   producer->WaitForDataSourceStop("ds_1");
6227   consumer->WaitForTracingDisabled();
6228 }
6229 
6230 }  // namespace
6231 
6232 }  // namespace perfetto
6233