1 /*
2 * Copyright (C) 2018 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 <unistd.h>
18
19 #include <chrono>
20 #include <functional>
21 #include <initializer_list>
22 #include <random>
23 #include <thread>
24
25 #include "perfetto/base/build_config.h"
26 #include "perfetto/base/logging.h"
27 #include "perfetto/ext/base/file_utils.h"
28 #include "perfetto/ext/base/pipe.h"
29 #include "perfetto/ext/base/scoped_file.h"
30 #include "perfetto/ext/base/string_utils.h"
31 #include "perfetto/ext/base/subprocess.h"
32 #include "perfetto/ext/base/temp_file.h"
33 #include "perfetto/ext/ipc/basic_types.h"
34 #include "perfetto/ext/traced/traced.h"
35 #include "perfetto/ext/tracing/core/commit_data_request.h"
36 #include "perfetto/ext/tracing/core/trace_packet.h"
37 #include "perfetto/ext/tracing/ipc/default_socket.h"
38 #include "perfetto/protozero/scattered_heap_buffer.h"
39 #include "perfetto/tracing/core/tracing_service_state.h"
40 #include "src/base/test/test_task_runner.h"
41 #include "src/base/test/utils.h"
42 #include "src/traced/probes/ftrace/ftrace_controller.h"
43 #include "src/traced/probes/ftrace/ftrace_procfs.h"
44 #include "test/gtest_and_gmock.h"
45 #include "test/test_helper.h"
46
47 #include "protos/perfetto/config/power/android_power_config.pbzero.h"
48 #include "protos/perfetto/config/test_config.gen.h"
49 #include "protos/perfetto/config/trace_config.gen.h"
50 #include "protos/perfetto/trace/ftrace/ftrace.gen.h"
51 #include "protos/perfetto/trace/ftrace/ftrace_event.gen.h"
52 #include "protos/perfetto/trace/ftrace/ftrace_event_bundle.gen.h"
53 #include "protos/perfetto/trace/power/battery_counters.gen.h"
54 #include "protos/perfetto/trace/test_event.gen.h"
55 #include "protos/perfetto/trace/trace.gen.h"
56 #include "protos/perfetto/trace/trace_packet.gen.h"
57 #include "protos/perfetto/trace/trace_packet.pbzero.h"
58 #include "protos/perfetto/trace/trigger.gen.h"
59
60 namespace perfetto {
61
62 namespace {
63
64 using ::testing::ContainsRegex;
65 using ::testing::ElementsAreArray;
66 using ::testing::HasSubstr;
67
68 constexpr size_t kBuiltinPackets = 8;
69
RandomTraceFileName()70 std::string RandomTraceFileName() {
71 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
72 constexpr char kSysTmpPath[] = "/data/misc/perfetto-traces";
73 #else
74 constexpr char kSysTmpPath[] = "/tmp";
75 #endif
76 static int suffix = 0;
77
78 std::string path;
79 path.assign(kSysTmpPath);
80 path.append("/trace-");
81 path.append(std::to_string(base::GetBootTimeNs().count()));
82 path.append("-");
83 path.append(std::to_string(suffix++));
84 return path;
85 }
86
87 // This class is a reference to a child process that has in essence been execv
88 // to the requested binary. The process will start and then wait for Run()
89 // before proceeding. We use this to fork new processes before starting any
90 // additional threads in the parent process (otherwise you would risk
91 // deadlocks), but pause the forked processes until remaining setup (including
92 // any necessary threads) in the parent process is complete.
93 class Exec {
94 public:
95 // Starts the forked process that was created. If not null then |stderr_out|
96 // will contain the stderr of the process.
Run(std::string * stderr_out=nullptr)97 int Run(std::string* stderr_out = nullptr) {
98 // We can't be the child process.
99 PERFETTO_CHECK(getpid() != subprocess_.pid());
100 // Will cause the entrypoint to continue.
101 PERFETTO_CHECK(write(*sync_pipe_.wr, "1", 1) == 1);
102 sync_pipe_.wr.reset();
103 subprocess_.Wait();
104
105 if (stderr_out) {
106 *stderr_out = std::move(subprocess_.output());
107 } else {
108 PERFETTO_LOG("Child proc %d exited with stderr: \"%s\"",
109 subprocess_.pid(), subprocess_.output().c_str());
110 }
111 return subprocess_.returncode();
112 }
113
114 private:
Exec(const std::string & argv0,std::initializer_list<std::string> args,std::string input="")115 Exec(const std::string& argv0,
116 std::initializer_list<std::string> args,
117 std::string input = "") {
118 subprocess_.args.stderr_mode = base::Subprocess::kBuffer;
119 subprocess_.args.stdout_mode = base::Subprocess::kDevNull;
120 subprocess_.args.input = input;
121
122 #if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
123 constexpr bool kUseSystemBinaries = false;
124 #else
125 constexpr bool kUseSystemBinaries = true;
126 #endif
127
128 std::vector<std::string>& cmd = subprocess_.args.exec_cmd;
129 if (kUseSystemBinaries) {
130 cmd.push_back("/system/bin/" + argv0);
131 cmd.insert(cmd.end(), args.begin(), args.end());
132 } else {
133 subprocess_.args.env.push_back(
134 std::string("PERFETTO_PRODUCER_SOCK_NAME=") +
135 TestHelper::GetProducerSocketName());
136 subprocess_.args.env.push_back(
137 std::string("PERFETTO_CONSUMER_SOCK_NAME=") +
138 TestHelper::GetConsumerSocketName());
139 cmd.push_back(base::GetCurExecutableDir() + "/" + argv0);
140 cmd.insert(cmd.end(), args.begin(), args.end());
141 }
142
143 if (access(cmd[0].c_str(), F_OK)) {
144 PERFETTO_FATAL(
145 "Cannot find %s. Make sure that the target has been built and, on "
146 "Android, pushed to the device.",
147 cmd[0].c_str());
148 }
149
150 // This pipe blocks the execution of the child process until the main test
151 // process calls Run(). There are two conflicting problems here:
152 // 1) We can't fork() subprocesses too late, because the test spawns threads
153 // for hosting the service. fork+threads = bad (see aosp/1089744).
154 // 2) We can't run the subprocess too early, because we need to wait that
155 // the service threads are ready before trying to connect from the child
156 // process.
157 sync_pipe_ = base::Pipe::Create();
158 int sync_pipe_rd = *sync_pipe_.rd;
159 subprocess_.args.preserve_fds.push_back(sync_pipe_rd);
160
161 // This lambda will be called on the forked child process after having
162 // setup pipe redirection and closed all FDs, right before the exec().
163 // The Subprocesss harness will take care of closing also |sync_pipe_.wr|.
164 subprocess_.args.entrypoint_for_testing = [sync_pipe_rd] {
165 // Don't add any logging here, all file descriptors are closed and trying
166 // to log will likely cause undefined behaviors.
167 char ignored = 0;
168 PERFETTO_CHECK(PERFETTO_EINTR(read(sync_pipe_rd, &ignored, 1)) > 0);
169 PERFETTO_CHECK(close(sync_pipe_rd) == 0 || errno == EINTR);
170 };
171
172 subprocess_.Start();
173 sync_pipe_.rd.reset();
174 }
175
176 friend class PerfettoCmdlineTest;
177 base::Subprocess subprocess_;
178 base::Pipe sync_pipe_;
179 };
180
181 class PerfettoTest : public ::testing::Test {
182 public:
SetUp()183 void SetUp() override {
184 // TODO(primiano): refactor this, it's copy/pasted in three places now.
185 size_t index = 0;
186 constexpr auto kTracingPaths = FtraceController::kTracingPaths;
187 while (!ftrace_procfs_ && kTracingPaths[index]) {
188 ftrace_procfs_ = FtraceProcfs::Create(kTracingPaths[index++]);
189 }
190 }
191
192 std::unique_ptr<FtraceProcfs> ftrace_procfs_;
193 };
194
195 class PerfettoCmdlineTest : public ::testing::Test {
196 public:
SetUp()197 void SetUp() override { exec_allowed_ = true; }
198
TearDown()199 void TearDown() override {}
200
StartServiceIfRequiredNoNewExecsAfterThis()201 void StartServiceIfRequiredNoNewExecsAfterThis() {
202 exec_allowed_ = false;
203 test_helper_.StartServiceIfRequired();
204 }
205
ConnectFakeProducer()206 FakeProducer* ConnectFakeProducer() {
207 return test_helper_.ConnectFakeProducer();
208 }
209
WrapTask(const std::function<void ()> & function)210 std::function<void()> WrapTask(const std::function<void()>& function) {
211 return test_helper_.WrapTask(function);
212 }
213
WaitForProducerSetup()214 void WaitForProducerSetup() { test_helper_.WaitForProducerSetup(); }
215
WaitForProducerEnabled()216 void WaitForProducerEnabled() { test_helper_.WaitForProducerEnabled(); }
217
218 // Creates a process that represents the perfetto binary that will
219 // start when Run() is called. |args| will be passed as part of
220 // the command line and |std_in| will be piped into std::cin.
ExecPerfetto(std::initializer_list<std::string> args,std::string std_in="")221 Exec ExecPerfetto(std::initializer_list<std::string> args,
222 std::string std_in = "") {
223 // You can not fork after you've started the service due to risk of
224 // deadlocks.
225 PERFETTO_CHECK(exec_allowed_);
226 return Exec("perfetto", std::move(args), std::move(std_in));
227 }
228
229 // Creates a process that represents the trigger_perfetto binary that will
230 // start when Run() is called. |args| will be passed as part of
231 // the command line and |std_in| will be piped into std::cin.
ExecTrigger(std::initializer_list<std::string> args,std::string std_in="")232 Exec ExecTrigger(std::initializer_list<std::string> args,
233 std::string std_in = "") {
234 // You can not fork after you've started the service due to risk of
235 // deadlocks.
236 PERFETTO_CHECK(exec_allowed_);
237 return Exec("trigger_perfetto", std::move(args), std::move(std_in));
238 }
239
240 // Tests are allowed to freely use these variables.
241 std::string stderr_;
242 base::TestTaskRunner task_runner_;
243
244 private:
245 bool exec_allowed_;
246 TestHelper test_helper_{&task_runner_};
247 };
248
249 } // namespace
250
251 // If we're building on Android and starting the daemons ourselves,
252 // create the sockets in a world-writable location.
253 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
254 PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
255 #define TEST_PRODUCER_SOCK_NAME "/data/local/tmp/traced_producer"
256 #else
257 #define TEST_PRODUCER_SOCK_NAME ::perfetto::GetProducerSocket()
258 #endif
259
260 #if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
261 #define TreeHuggerOnly(x) x
262 #else
263 #define TreeHuggerOnly(x) DISABLED_##x
264 #endif
265
266 // TODO(b/73453011): reenable on more platforms (including standalone Android).
TEST_F(PerfettoTest,TreeHuggerOnly (TestFtraceProducer))267 TEST_F(PerfettoTest, TreeHuggerOnly(TestFtraceProducer)) {
268 base::TestTaskRunner task_runner;
269
270 TestHelper helper(&task_runner);
271 helper.StartServiceIfRequired();
272
273 #if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
274 ProbesProducerThread probes(TEST_PRODUCER_SOCK_NAME);
275 probes.Connect();
276 #endif
277
278 helper.ConnectConsumer();
279 helper.WaitForConsumerConnect();
280
281 TraceConfig trace_config;
282 trace_config.add_buffers()->set_size_kb(1024);
283 trace_config.set_duration_ms(3000);
284
285 auto* ds_config = trace_config.add_data_sources()->mutable_config();
286 ds_config->set_name("linux.ftrace");
287 ds_config->set_target_buffer(0);
288
289 protos::gen::FtraceConfig ftrace_config;
290 ftrace_config.add_ftrace_events("sched_switch");
291 ftrace_config.add_ftrace_events("bar");
292 ds_config->set_ftrace_config_raw(ftrace_config.SerializeAsString());
293
294 helper.StartTracing(trace_config);
295 helper.WaitForTracingDisabled();
296
297 helper.ReadData();
298 helper.WaitForReadData();
299
300 const auto& packets = helper.trace();
301 ASSERT_GT(packets.size(), 0u);
302
303 for (const auto& packet : packets) {
304 for (int ev = 0; ev < packet.ftrace_events().event_size(); ev++) {
305 ASSERT_TRUE(packet.ftrace_events()
306 .event()[static_cast<size_t>(ev)]
307 .has_sched_switch());
308 }
309 }
310 }
311
312 // TODO(b/73453011): reenable on more platforms (including standalone Android).
TEST_F(PerfettoTest,TreeHuggerOnly (TestFtraceFlush))313 TEST_F(PerfettoTest, TreeHuggerOnly(TestFtraceFlush)) {
314 base::TestTaskRunner task_runner;
315
316 TestHelper helper(&task_runner);
317 helper.StartServiceIfRequired();
318
319 #if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
320 ProbesProducerThread probes(TEST_PRODUCER_SOCK_NAME);
321 probes.Connect();
322 #endif
323
324 helper.ConnectConsumer();
325 helper.WaitForConsumerConnect();
326
327 const uint32_t kTestTimeoutMs = 30000;
328 TraceConfig trace_config;
329 trace_config.add_buffers()->set_size_kb(32);
330 trace_config.set_duration_ms(kTestTimeoutMs);
331
332 auto* ds_config = trace_config.add_data_sources()->mutable_config();
333 ds_config->set_name("linux.ftrace");
334
335 protos::gen::FtraceConfig ftrace_config;
336 ftrace_config.add_ftrace_events("print");
337 ds_config->set_ftrace_config_raw(ftrace_config.SerializeAsString());
338
339 helper.StartTracing(trace_config);
340
341 // Do a first flush just to synchronize with the producer. The problem here
342 // is that, on a Linux workstation, the producer can take several seconds just
343 // to get to the point where ftrace is ready. We use the flush ack as a
344 // synchronization point.
345 helper.FlushAndWait(kTestTimeoutMs);
346
347 EXPECT_TRUE(ftrace_procfs_->IsTracingEnabled());
348 const char kMarker[] = "just_one_event";
349 EXPECT_TRUE(ftrace_procfs_->WriteTraceMarker(kMarker));
350
351 // This is the real flush we are testing.
352 helper.FlushAndWait(kTestTimeoutMs);
353
354 helper.DisableTracing();
355 helper.WaitForTracingDisabled(kTestTimeoutMs);
356
357 helper.ReadData();
358 helper.WaitForReadData();
359
360 int marker_found = 0;
361 for (const auto& packet : helper.trace()) {
362 for (int i = 0; i < packet.ftrace_events().event_size(); i++) {
363 const auto& ev = packet.ftrace_events().event()[static_cast<size_t>(i)];
364 if (ev.has_print() && ev.print().buf().find(kMarker) != std::string::npos)
365 marker_found++;
366 }
367 }
368 ASSERT_EQ(marker_found, 1);
369 }
370
371 // TODO(b/73453011): reenable on more platforms (including standalone Android).
TEST_F(PerfettoTest,TreeHuggerOnly (TestBatteryTracing))372 TEST_F(PerfettoTest, TreeHuggerOnly(TestBatteryTracing)) {
373 base::TestTaskRunner task_runner;
374
375 TestHelper helper(&task_runner);
376 helper.StartServiceIfRequired();
377
378 #if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
379 ProbesProducerThread probes(TEST_PRODUCER_SOCK_NAME);
380 probes.Connect();
381 #else
382 base::ignore_result(TEST_PRODUCER_SOCK_NAME);
383 #endif
384
385 helper.ConnectConsumer();
386 helper.WaitForConsumerConnect();
387
388 TraceConfig trace_config;
389 trace_config.add_buffers()->set_size_kb(128);
390 trace_config.set_duration_ms(3000);
391
392 auto* ds_config = trace_config.add_data_sources()->mutable_config();
393 ds_config->set_name("android.power");
394 ds_config->set_target_buffer(0);
395
396 using protos::pbzero::AndroidPowerConfig;
397 protozero::HeapBuffered<AndroidPowerConfig> power_config;
398 power_config->set_battery_poll_ms(250);
399 power_config->add_battery_counters(
400 AndroidPowerConfig::BATTERY_COUNTER_CHARGE);
401 power_config->add_battery_counters(
402 AndroidPowerConfig::BATTERY_COUNTER_CAPACITY_PERCENT);
403 ds_config->set_android_power_config_raw(power_config.SerializeAsString());
404
405 helper.StartTracing(trace_config);
406 helper.WaitForTracingDisabled();
407
408 helper.ReadData();
409 helper.WaitForReadData();
410
411 const auto& packets = helper.trace();
412 ASSERT_GT(packets.size(), 0u);
413
414 bool has_battery_packet = false;
415 for (const auto& packet : packets) {
416 if (!packet.has_battery())
417 continue;
418 has_battery_packet = true;
419 // Unfortunately we cannot make any assertions on the charge counter.
420 // On some devices it can reach negative values (b/64685329).
421 EXPECT_GE(packet.battery().capacity_percent(), 0);
422 EXPECT_LE(packet.battery().capacity_percent(), 100);
423 }
424
425 ASSERT_TRUE(has_battery_packet);
426 }
427
TEST_F(PerfettoTest,TestFakeProducer)428 TEST_F(PerfettoTest, TestFakeProducer) {
429 base::TestTaskRunner task_runner;
430
431 TestHelper helper(&task_runner);
432 helper.StartServiceIfRequired();
433 helper.ConnectFakeProducer();
434 helper.ConnectConsumer();
435 helper.WaitForConsumerConnect();
436
437 TraceConfig trace_config;
438 trace_config.add_buffers()->set_size_kb(1024);
439 trace_config.set_duration_ms(200);
440
441 auto* ds_config = trace_config.add_data_sources()->mutable_config();
442 ds_config->set_name("android.perfetto.FakeProducer");
443 ds_config->set_target_buffer(0);
444
445 static constexpr size_t kNumPackets = 11;
446 static constexpr uint32_t kRandomSeed = 42;
447 static constexpr uint32_t kMsgSize = 1024;
448 ds_config->mutable_for_testing()->set_seed(kRandomSeed);
449 ds_config->mutable_for_testing()->set_message_count(kNumPackets);
450 ds_config->mutable_for_testing()->set_message_size(kMsgSize);
451 ds_config->mutable_for_testing()->set_send_batch_on_register(true);
452
453 helper.StartTracing(trace_config);
454 helper.WaitForTracingDisabled();
455
456 helper.ReadData();
457 helper.WaitForReadData();
458
459 const auto& packets = helper.trace();
460 ASSERT_EQ(packets.size(), kNumPackets);
461
462 std::minstd_rand0 rnd_engine(kRandomSeed);
463 for (const auto& packet : packets) {
464 ASSERT_TRUE(packet.has_for_testing());
465 ASSERT_EQ(packet.for_testing().seq_value(), rnd_engine());
466 }
467 }
468
TEST_F(PerfettoTest,VeryLargePackets)469 TEST_F(PerfettoTest, VeryLargePackets) {
470 base::TestTaskRunner task_runner;
471
472 TestHelper helper(&task_runner);
473 helper.StartServiceIfRequired();
474 helper.ConnectFakeProducer();
475 helper.ConnectConsumer();
476 helper.WaitForConsumerConnect();
477
478 TraceConfig trace_config;
479 trace_config.add_buffers()->set_size_kb(4096 * 10);
480 trace_config.set_duration_ms(500);
481
482 auto* ds_config = trace_config.add_data_sources()->mutable_config();
483 ds_config->set_name("android.perfetto.FakeProducer");
484 ds_config->set_target_buffer(0);
485
486 static constexpr size_t kNumPackets = 7;
487 static constexpr uint32_t kRandomSeed = 42;
488 static constexpr uint32_t kMsgSize = 1024 * 1024 - 42;
489 ds_config->mutable_for_testing()->set_seed(kRandomSeed);
490 ds_config->mutable_for_testing()->set_message_count(kNumPackets);
491 ds_config->mutable_for_testing()->set_message_size(kMsgSize);
492 ds_config->mutable_for_testing()->set_send_batch_on_register(true);
493
494 helper.StartTracing(trace_config);
495 helper.WaitForTracingDisabled();
496
497 helper.ReadData();
498 helper.WaitForReadData(/* read_count */ 0, /* timeout_ms */ 10000);
499
500 const auto& packets = helper.trace();
501 ASSERT_EQ(packets.size(), kNumPackets);
502
503 std::minstd_rand0 rnd_engine(kRandomSeed);
504 for (const auto& packet : packets) {
505 ASSERT_TRUE(packet.has_for_testing());
506 ASSERT_EQ(packet.for_testing().seq_value(), rnd_engine());
507 size_t msg_size = packet.for_testing().str().size();
508 ASSERT_EQ(kMsgSize, msg_size);
509 for (size_t i = 0; i < msg_size; i++)
510 ASSERT_EQ(i < msg_size - 1 ? '.' : 0, packet.for_testing().str()[i]);
511 }
512 }
513
TEST_F(PerfettoTest,DetachAndReattach)514 TEST_F(PerfettoTest, DetachAndReattach) {
515 base::TestTaskRunner task_runner;
516
517 TraceConfig trace_config;
518 trace_config.add_buffers()->set_size_kb(1024);
519 trace_config.set_duration_ms(10000); // Max timeout, session is ended before.
520 auto* ds_config = trace_config.add_data_sources()->mutable_config();
521 ds_config->set_name("android.perfetto.FakeProducer");
522 static constexpr size_t kNumPackets = 11;
523 ds_config->mutable_for_testing()->set_message_count(kNumPackets);
524 ds_config->mutable_for_testing()->set_message_size(32);
525
526 // Enable tracing and detach as soon as it gets started.
527 TestHelper helper(&task_runner);
528 helper.StartServiceIfRequired();
529 auto* fake_producer = helper.ConnectFakeProducer();
530 helper.ConnectConsumer();
531 helper.WaitForConsumerConnect();
532 helper.StartTracing(trace_config);
533
534 // Detach.
535 helper.DetachConsumer("key");
536
537 // Write data while detached.
538 helper.WaitForProducerEnabled();
539 auto on_data_written = task_runner.CreateCheckpoint("data_written");
540 fake_producer->ProduceEventBatch(helper.WrapTask(on_data_written));
541 task_runner.RunUntilCheckpoint("data_written");
542
543 // Then reattach the consumer.
544 helper.ConnectConsumer();
545 helper.WaitForConsumerConnect();
546 helper.AttachConsumer("key");
547
548 helper.DisableTracing();
549 helper.WaitForTracingDisabled();
550
551 helper.ReadData();
552 helper.WaitForReadData();
553 const auto& packets = helper.trace();
554 ASSERT_EQ(packets.size(), kNumPackets);
555 }
556
557 // Tests that a detached trace session is automatically cleaned up if the
558 // consumer doesn't re-attach before its expiration time.
TEST_F(PerfettoTest,ReattachFailsAfterTimeout)559 TEST_F(PerfettoTest, ReattachFailsAfterTimeout) {
560 base::TestTaskRunner task_runner;
561
562 TraceConfig trace_config;
563 trace_config.add_buffers()->set_size_kb(1024);
564 trace_config.set_duration_ms(250);
565 trace_config.set_write_into_file(true);
566 trace_config.set_file_write_period_ms(100000);
567 auto* ds_config = trace_config.add_data_sources()->mutable_config();
568 ds_config->set_name("android.perfetto.FakeProducer");
569 ds_config->mutable_for_testing()->set_message_count(1);
570 ds_config->mutable_for_testing()->set_message_size(32);
571 ds_config->mutable_for_testing()->set_send_batch_on_register(true);
572
573 // Enable tracing and detach as soon as it gets started.
574 TestHelper helper(&task_runner);
575 helper.StartServiceIfRequired();
576 helper.ConnectFakeProducer();
577 helper.ConnectConsumer();
578 helper.WaitForConsumerConnect();
579
580 auto pipe_pair = base::Pipe::Create();
581 helper.StartTracing(trace_config, std::move(pipe_pair.wr));
582
583 // Detach.
584 helper.DetachConsumer("key");
585
586 // Use the file EOF (write end closed) as a way to detect when the trace
587 // session is ended.
588 char buf[1024];
589 while (PERFETTO_EINTR(read(*pipe_pair.rd, buf, sizeof(buf))) > 0) {
590 }
591
592 // Give some margin for the tracing service to destroy the session.
593 usleep(250000);
594
595 // Reconnect and find out that it's too late and the session is gone.
596 helper.ConnectConsumer();
597 helper.WaitForConsumerConnect();
598 EXPECT_FALSE(helper.AttachConsumer("key"));
599 }
600
TEST_F(PerfettoTest,TestProducerProvidedSMB)601 TEST_F(PerfettoTest, TestProducerProvidedSMB) {
602 base::TestTaskRunner task_runner;
603
604 TestHelper helper(&task_runner);
605 helper.CreateProducerProvidedSmb();
606
607 protos::gen::TestConfig test_config;
608 test_config.set_seed(42);
609 test_config.set_message_count(1);
610 test_config.set_message_size(1024);
611 test_config.set_send_batch_on_register(true);
612
613 // Write a first batch before connection.
614 helper.ProduceStartupEventBatch(test_config);
615
616 helper.StartServiceIfRequired();
617 helper.ConnectFakeProducer();
618 helper.ConnectConsumer();
619 helper.WaitForConsumerConnect();
620
621 TraceConfig trace_config;
622 trace_config.add_buffers()->set_size_kb(1024);
623 trace_config.set_duration_ms(200);
624
625 auto* ds_config = trace_config.add_data_sources()->mutable_config();
626 ds_config->set_name("android.perfetto.FakeProducer");
627 ds_config->set_target_buffer(0);
628 *ds_config->mutable_for_testing() = test_config;
629
630 // The data source is configured to emit another batch when it is started via
631 // send_batch_on_register in the TestConfig.
632 helper.StartTracing(trace_config);
633 helper.WaitForTracingDisabled();
634
635 EXPECT_TRUE(helper.IsShmemProvidedByProducer());
636
637 helper.ReadData();
638 helper.WaitForReadData();
639
640 const auto& packets = helper.trace();
641 // We should have produced two batches, one before the producer connected and
642 // another one when the data source was started.
643 ASSERT_EQ(packets.size(), 2u);
644 ASSERT_TRUE(packets[0].has_for_testing());
645 ASSERT_TRUE(packets[1].has_for_testing());
646 }
647
648 // Regression test for b/153142114.
TEST_F(PerfettoTest,QueryServiceStateLargeResponse)649 TEST_F(PerfettoTest, QueryServiceStateLargeResponse) {
650 base::TestTaskRunner task_runner;
651
652 TestHelper helper(&task_runner);
653 helper.StartServiceIfRequired();
654 helper.ConnectConsumer();
655 helper.WaitForConsumerConnect();
656
657 FakeProducer* producer = helper.ConnectFakeProducer();
658
659 // Register 5 data sources with very large descriptors. Each descriptor will
660 // max out the IPC message size, so that the service has no other choice
661 // than chunking them.
662 std::map<std::string, std::string> ds_expected;
663 for (int i = 0; i < 5; i++) {
664 DataSourceDescriptor dsd;
665 std::string name = "big_ds_" + std::to_string(i);
666 dsd.set_name(name);
667 std::string descriptor(ipc::kIPCBufferSize - 64, (' ' + i) % 64);
668 dsd.set_track_event_descriptor_raw(descriptor);
669 ds_expected[name] = std::move(descriptor);
670 producer->RegisterDataSource(dsd);
671 }
672
673 // Linearize the producer with the service. We need to make sure that all the
674 // RegisterDataSource() calls above have been seen by the service before
675 // continuing.
676 helper.SyncAndWaitProducer();
677
678 // Now invoke QueryServiceState() and wait for the reply. The service will
679 // send 6 (1 + 5) IPCs which will be merged together in
680 // producer_ipc_client_impl.cc.
681 auto svc_state = helper.QueryServiceStateAndWait();
682
683 ASSERT_GE(svc_state.producers().size(), 1u);
684
685 std::map<std::string, std::string> ds_found;
686 for (const auto& ds : svc_state.data_sources()) {
687 if (!base::StartsWith(ds.ds_descriptor().name(), "big_ds_"))
688 continue;
689 ds_found[ds.ds_descriptor().name()] =
690 ds.ds_descriptor().track_event_descriptor_raw();
691 }
692 EXPECT_THAT(ds_found, ElementsAreArray(ds_expected));
693 }
694
695 // Disable cmdline tests on sanitizets because they use fork() and that messes
696 // up leak / races detections, which has been fixed only recently (see
697 // https://github.com/google/sanitizers/issues/836 ).
698 #if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
699 defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER)
700 #define NoSanitizers(X) DISABLED_##X
701 #else
702 #define NoSanitizers(X) X
703 #endif
704
TEST_F(PerfettoCmdlineTest,NoSanitizers (InvalidCases))705 TEST_F(PerfettoCmdlineTest, NoSanitizers(InvalidCases)) {
706 std::string cfg("duration_ms: 100");
707
708 auto invalid_arg = ExecPerfetto({"--invalid-arg"});
709 auto empty_config = ExecPerfetto({"-c", "-", "-o", "-"}, "");
710
711 // Cannot make assertions on --dropbox because on standalone builds it fails
712 // prematurely due to lack of dropbox.
713 auto missing_dropbox =
714 ExecPerfetto({"-c", "-", "--txt", "-o", "-", "--dropbox=foo"}, cfg);
715 auto either_out_or_dropbox = ExecPerfetto({"-c", "-", "--txt"}, cfg);
716
717 // Disallow mixing simple and file config.
718 auto simple_and_file_1 =
719 ExecPerfetto({"-o", "-", "-c", "-", "-t", "2s"}, cfg);
720 auto simple_and_file_2 =
721 ExecPerfetto({"-o", "-", "-c", "-", "-b", "2m"}, cfg);
722 auto simple_and_file_3 =
723 ExecPerfetto({"-o", "-", "-c", "-", "-s", "2m"}, cfg);
724
725 // Invalid --attach / --detach cases.
726 auto invalid_stop =
727 ExecPerfetto({"-c", "-", "--txt", "-o", "-", "--stop"}, cfg);
728 auto attach_and_config_1 =
729 ExecPerfetto({"-c", "-", "--txt", "-o", "-", "--attach=foo"}, cfg);
730 auto attach_and_config_2 =
731 ExecPerfetto({"-t", "2s", "-o", "-", "--attach=foo"}, cfg);
732 auto attach_needs_argument = ExecPerfetto({"--attach"}, cfg);
733 auto detach_needs_argument =
734 ExecPerfetto({"-t", "2s", "-o", "-", "--detach"}, cfg);
735 auto detach_without_out_or_dropbox =
736 ExecPerfetto({"-t", "2s", "--detach=foo"}, cfg);
737
738 // Cannot trace and use --query.
739 auto trace_and_query_1 = ExecPerfetto({"-t", "2s", "--query"}, cfg);
740 auto trace_and_query_2 = ExecPerfetto({"-c", "-", "--query"}, cfg);
741
742 // Ensure all Exec:: calls have been saved to prevent deadlocks.
743 StartServiceIfRequiredNoNewExecsAfterThis();
744
745 EXPECT_EQ(1, invalid_arg.Run(&stderr_));
746
747 EXPECT_EQ(1, empty_config.Run(&stderr_));
748 EXPECT_THAT(stderr_, HasSubstr("TraceConfig is empty"));
749
750 // Cannot make assertions on --dropbox because on standalone builds it fails
751 // prematurely due to lack of dropbox.
752 EXPECT_EQ(1, missing_dropbox.Run(&stderr_));
753
754 EXPECT_EQ(1, either_out_or_dropbox.Run(&stderr_));
755 EXPECT_THAT(stderr_, HasSubstr("Either --out or --dropbox"));
756
757 // Disallow mixing simple and file config.
758 EXPECT_EQ(1, simple_and_file_1.Run(&stderr_));
759 EXPECT_THAT(stderr_, HasSubstr("Cannot specify both -c"));
760
761 EXPECT_EQ(1, simple_and_file_2.Run(&stderr_));
762 EXPECT_THAT(stderr_, HasSubstr("Cannot specify both -c"));
763
764 EXPECT_EQ(1, simple_and_file_3.Run(&stderr_));
765 EXPECT_THAT(stderr_, HasSubstr("Cannot specify both -c"));
766
767 // Invalid --attach / --detach cases.
768 EXPECT_EQ(1, invalid_stop.Run(&stderr_));
769 EXPECT_THAT(stderr_, HasSubstr("--stop is supported only in combination"));
770
771 EXPECT_EQ(1, attach_and_config_1.Run(&stderr_));
772 EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
773
774 EXPECT_EQ(1, attach_and_config_2.Run(&stderr_));
775 EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
776
777 EXPECT_EQ(1, attach_needs_argument.Run(&stderr_));
778 EXPECT_THAT(stderr_, ContainsRegex("option.*--attach.*requires an argument"));
779
780 EXPECT_EQ(1, detach_needs_argument.Run(&stderr_));
781 EXPECT_THAT(stderr_, ContainsRegex("option.*--detach.*requires an argument"));
782
783 EXPECT_EQ(1, detach_without_out_or_dropbox.Run(&stderr_));
784 EXPECT_THAT(stderr_, HasSubstr("--out or --dropbox is required"));
785
786 // Cannot trace and use --query.
787 EXPECT_EQ(1, trace_and_query_1.Run(&stderr_));
788 EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
789
790 EXPECT_EQ(1, trace_and_query_2.Run(&stderr_));
791 EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
792 }
793
TEST_F(PerfettoCmdlineTest,NoSanitizers (TxtConfig))794 TEST_F(PerfettoCmdlineTest, NoSanitizers(TxtConfig)) {
795 std::string cfg("duration_ms: 100");
796 auto perfetto = ExecPerfetto({"-c", "-", "--txt", "-o", "-"}, cfg);
797 StartServiceIfRequiredNoNewExecsAfterThis();
798 EXPECT_EQ(0, perfetto.Run(&stderr_)) << stderr_;
799 }
800
TEST_F(PerfettoCmdlineTest,NoSanitizers (SimpleConfig))801 TEST_F(PerfettoCmdlineTest, NoSanitizers(SimpleConfig)) {
802 auto perfetto = ExecPerfetto({"-o", "-", "-c", "-", "-t", "100ms"});
803 StartServiceIfRequiredNoNewExecsAfterThis();
804 EXPECT_EQ(0, perfetto.Run(&stderr_)) << stderr_;
805 }
806
TEST_F(PerfettoCmdlineTest,NoSanitizers (DetachAndAttach))807 TEST_F(PerfettoCmdlineTest, NoSanitizers(DetachAndAttach)) {
808 auto attach_to_not_existing = ExecPerfetto({"--attach=not_existent"});
809
810 std::string cfg("duration_ms: 10000; write_into_file: true");
811 auto detach_valid_stop =
812 ExecPerfetto({"-o", "-", "-c", "-", "--txt", "--detach=valid_stop"}, cfg);
813 auto stop_valid_stop = ExecPerfetto({"--attach=valid_stop", "--stop"});
814
815 StartServiceIfRequiredNoNewExecsAfterThis();
816
817 EXPECT_NE(0, attach_to_not_existing.Run(&stderr_));
818 EXPECT_THAT(stderr_, HasSubstr("Session re-attach failed"));
819
820 EXPECT_EQ(0, detach_valid_stop.Run(&stderr_)) << stderr_;
821 EXPECT_EQ(0, stop_valid_stop.Run(&stderr_));
822 }
823
TEST_F(PerfettoCmdlineTest,NoSanitizers (StartTracingTrigger))824 TEST_F(PerfettoCmdlineTest, NoSanitizers(StartTracingTrigger)) {
825 // See |message_count| and |message_size| in the TraceConfig above.
826 constexpr size_t kMessageCount = 11;
827 constexpr size_t kMessageSize = 32;
828 protos::gen::TraceConfig trace_config;
829 trace_config.add_buffers()->set_size_kb(1024);
830 auto* ds_config = trace_config.add_data_sources()->mutable_config();
831 ds_config->set_name("android.perfetto.FakeProducer");
832 ds_config->mutable_for_testing()->set_message_count(kMessageCount);
833 ds_config->mutable_for_testing()->set_message_size(kMessageSize);
834 auto* trigger_cfg = trace_config.mutable_trigger_config();
835 trigger_cfg->set_trigger_mode(
836 protos::gen::TraceConfig::TriggerConfig::START_TRACING);
837 trigger_cfg->set_trigger_timeout_ms(15000);
838 auto* trigger = trigger_cfg->add_triggers();
839 trigger->set_name("trigger_name");
840 // |stop_delay_ms| must be long enough that we can write the packets in
841 // before the trace finishes. This has to be long enough for the slowest
842 // emulator. But as short as possible to prevent the test running a long
843 // time.
844 trigger->set_stop_delay_ms(500);
845
846 // We have to construct all the processes we want to fork before we start the
847 // service with |StartServiceIfRequired()|. this is because it is unsafe
848 // (could deadlock) to fork after we've spawned some threads which might
849 // printf (and thus hold locks).
850 const std::string path = RandomTraceFileName();
851 auto perfetto_proc = ExecPerfetto(
852 {
853 "-o",
854 path,
855 "-c",
856 "-",
857 },
858 trace_config.SerializeAsString());
859
860 auto trigger_proc = ExecTrigger({"trigger_name"});
861
862 // Start the service and connect a simple fake producer.
863 StartServiceIfRequiredNoNewExecsAfterThis();
864
865 auto* fake_producer = ConnectFakeProducer();
866 EXPECT_TRUE(fake_producer);
867
868 // Start a background thread that will deliver the config now that we've
869 // started the service. See |perfetto_proc| above for the args passed.
870 std::thread background_trace([&perfetto_proc]() {
871 std::string stderr_str;
872 EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
873 });
874
875 WaitForProducerSetup();
876 EXPECT_EQ(0, trigger_proc.Run(&stderr_));
877
878 // Wait for the producer to start, and then write out 11 packets.
879 WaitForProducerEnabled();
880 auto on_data_written = task_runner_.CreateCheckpoint("data_written");
881 fake_producer->ProduceEventBatch(WrapTask(on_data_written));
882 task_runner_.RunUntilCheckpoint("data_written");
883 background_trace.join();
884
885 std::string trace_str;
886 base::ReadFile(path, &trace_str);
887 protos::gen::Trace trace;
888 ASSERT_TRUE(trace.ParseFromString(trace_str));
889 EXPECT_EQ(static_cast<int>(kBuiltinPackets + kMessageCount),
890 trace.packet_size());
891 for (const auto& packet : trace.packet()) {
892 if (packet.has_trace_config()) {
893 // Ensure the trace config properly includes the trigger mode we set.
894 auto kStartTrig = protos::gen::TraceConfig::TriggerConfig::START_TRACING;
895 EXPECT_EQ(kStartTrig,
896 packet.trace_config().trigger_config().trigger_mode());
897 } else if (packet.has_trigger()) {
898 // validate that the triggers are properly added to the trace.
899 EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
900 } else if (packet.has_for_testing()) {
901 // Make sure that the data size is correctly set based on what we
902 // requested.
903 EXPECT_EQ(kMessageSize, packet.for_testing().str().size());
904 }
905 }
906 }
907
TEST_F(PerfettoCmdlineTest,NoSanitizers (StopTracingTrigger))908 TEST_F(PerfettoCmdlineTest, NoSanitizers(StopTracingTrigger)) {
909 // See |message_count| and |message_size| in the TraceConfig above.
910 constexpr size_t kMessageCount = 11;
911 constexpr size_t kMessageSize = 32;
912 protos::gen::TraceConfig trace_config;
913 trace_config.add_buffers()->set_size_kb(1024);
914 auto* ds_config = trace_config.add_data_sources()->mutable_config();
915 ds_config->set_name("android.perfetto.FakeProducer");
916 ds_config->mutable_for_testing()->set_message_count(kMessageCount);
917 ds_config->mutable_for_testing()->set_message_size(kMessageSize);
918 auto* trigger_cfg = trace_config.mutable_trigger_config();
919 trigger_cfg->set_trigger_mode(
920 protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
921 trigger_cfg->set_trigger_timeout_ms(15000);
922 auto* trigger = trigger_cfg->add_triggers();
923 trigger->set_name("trigger_name");
924 // |stop_delay_ms| must be long enough that we can write the packets in
925 // before the trace finishes. This has to be long enough for the slowest
926 // emulator. But as short as possible to prevent the test running a long
927 // time.
928 trigger->set_stop_delay_ms(500);
929 trigger = trigger_cfg->add_triggers();
930 trigger->set_name("trigger_name_3");
931 trigger->set_stop_delay_ms(60000);
932
933 // We have to construct all the processes we want to fork before we start the
934 // service with |StartServiceIfRequired()|. this is because it is unsafe
935 // (could deadlock) to fork after we've spawned some threads which might
936 // printf (and thus hold locks).
937 const std::string path = RandomTraceFileName();
938 auto perfetto_proc = ExecPerfetto(
939 {
940 "-o",
941 path,
942 "-c",
943 "-",
944 },
945 trace_config.SerializeAsString());
946
947 auto trigger_proc =
948 ExecTrigger({"trigger_name_2", "trigger_name", "trigger_name_3"});
949
950 // Start the service and connect a simple fake producer.
951 StartServiceIfRequiredNoNewExecsAfterThis();
952 auto* fake_producer = ConnectFakeProducer();
953 EXPECT_TRUE(fake_producer);
954
955 // Start a background thread that will deliver the config now that we've
956 // started the service. See |perfetto_proc| above for the args passed.
957 std::thread background_trace([&perfetto_proc]() {
958 std::string stderr_str;
959 EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
960 });
961
962 WaitForProducerEnabled();
963 // Wait for the producer to start, and then write out 11 packets, before the
964 // trace actually starts (the trigger is seen).
965 auto on_data_written = task_runner_.CreateCheckpoint("data_written_1");
966 fake_producer->ProduceEventBatch(WrapTask(on_data_written));
967 task_runner_.RunUntilCheckpoint("data_written_1");
968
969 EXPECT_EQ(0, trigger_proc.Run(&stderr_)) << "stderr: " << stderr_;
970
971 background_trace.join();
972
973 std::string trace_str;
974 base::ReadFile(path, &trace_str);
975 protos::gen::Trace trace;
976 ASSERT_TRUE(trace.ParseFromString(trace_str));
977 EXPECT_EQ(static_cast<int>(kBuiltinPackets + 1 + kMessageCount),
978 trace.packet_size());
979 bool seen_first_trigger = false;
980 for (const auto& packet : trace.packet()) {
981 if (packet.has_trace_config()) {
982 // Ensure the trace config properly includes the trigger mode we set.
983 auto kStopTrig = protos::gen::TraceConfig::TriggerConfig::STOP_TRACING;
984 EXPECT_EQ(kStopTrig,
985 packet.trace_config().trigger_config().trigger_mode());
986 } else if (packet.has_trigger()) {
987 // validate that the triggers are properly added to the trace.
988 if (!seen_first_trigger) {
989 EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
990 seen_first_trigger = true;
991 } else {
992 EXPECT_EQ("trigger_name_3", packet.trigger().trigger_name());
993 }
994 } else if (packet.has_for_testing()) {
995 // Make sure that the data size is correctly set based on what we
996 // requested.
997 EXPECT_EQ(kMessageSize, packet.for_testing().str().size());
998 }
999 }
1000 }
1001
1002 // Dropbox on the commandline client only works on android builds. So disable
1003 // this test on all other builds.
1004 #if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
TEST_F(PerfettoCmdlineTest,NoSanitizers (NoDataNoFileWithoutTrigger))1005 TEST_F(PerfettoCmdlineTest, NoSanitizers(NoDataNoFileWithoutTrigger)) {
1006 #else
1007 TEST_F(PerfettoCmdlineTest, DISABLED_NoDataNoFileWithoutTrigger) {
1008 #endif
1009 // See |message_count| and |message_size| in the TraceConfig above.
1010 constexpr size_t kMessageCount = 11;
1011 constexpr size_t kMessageSize = 32;
1012 protos::gen::TraceConfig trace_config;
1013 trace_config.add_buffers()->set_size_kb(1024);
1014 trace_config.set_allow_user_build_tracing(true);
1015 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1016 ds_config->set_name("android.perfetto.FakeProducer");
1017 ds_config->mutable_for_testing()->set_message_count(kMessageCount);
1018 ds_config->mutable_for_testing()->set_message_size(kMessageSize);
1019 auto* trigger_cfg = trace_config.mutable_trigger_config();
1020 trigger_cfg->set_trigger_mode(
1021 protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
1022 trigger_cfg->set_trigger_timeout_ms(1000);
1023 auto* trigger = trigger_cfg->add_triggers();
1024 trigger->set_name("trigger_name");
1025 // |stop_delay_ms| must be long enough that we can write the packets in
1026 // before the trace finishes. This has to be long enough for the slowest
1027 // emulator. But as short as possible to prevent the test running a long
1028 // time.
1029 trigger->set_stop_delay_ms(500);
1030 trigger = trigger_cfg->add_triggers();
1031
1032 // We have to construct all the processes we want to fork before we start the
1033 // service with |StartServiceIfRequired()|. this is because it is unsafe
1034 // (could deadlock) to fork after we've spawned some threads which might
1035 // printf (and thus hold locks).
1036 const std::string path = RandomTraceFileName();
1037 auto perfetto_proc = ExecPerfetto(
1038 {
1039 "--dropbox",
1040 "TAG",
1041 "--no-guardrails",
1042 "-c",
1043 "-",
1044 },
1045 trace_config.SerializeAsString());
1046
1047 StartServiceIfRequiredNoNewExecsAfterThis();
1048 auto* fake_producer = ConnectFakeProducer();
1049 EXPECT_TRUE(fake_producer);
1050
1051 std::string stderr_str;
1052 std::thread background_trace([&perfetto_proc, &stderr_str]() {
1053 EXPECT_EQ(0, perfetto_proc.Run(&stderr_str));
1054 });
1055 background_trace.join();
1056
1057 EXPECT_THAT(stderr_str,
1058 ::testing::HasSubstr("Skipping write to dropbox. Empty trace."));
1059 }
1060
1061 TEST_F(PerfettoCmdlineTest, NoSanitizers(StopTracingTriggerFromConfig)) {
1062 // See |message_count| and |message_size| in the TraceConfig above.
1063 constexpr size_t kMessageCount = 11;
1064 constexpr size_t kMessageSize = 32;
1065 protos::gen::TraceConfig trace_config;
1066 trace_config.add_buffers()->set_size_kb(1024);
1067 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1068 ds_config->set_name("android.perfetto.FakeProducer");
1069 ds_config->mutable_for_testing()->set_message_count(kMessageCount);
1070 ds_config->mutable_for_testing()->set_message_size(kMessageSize);
1071 auto* trigger_cfg = trace_config.mutable_trigger_config();
1072 trigger_cfg->set_trigger_mode(
1073 protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
1074 trigger_cfg->set_trigger_timeout_ms(15000);
1075 auto* trigger = trigger_cfg->add_triggers();
1076 trigger->set_name("trigger_name");
1077 // |stop_delay_ms| must be long enough that we can write the packets in
1078 // before the trace finishes. This has to be long enough for the slowest
1079 // emulator. But as short as possible to prevent the test running a long
1080 // time.
1081 trigger->set_stop_delay_ms(500);
1082 trigger = trigger_cfg->add_triggers();
1083 trigger->set_name("trigger_name_3");
1084 trigger->set_stop_delay_ms(60000);
1085
1086 // We have to construct all the processes we want to fork before we start the
1087 // service with |StartServiceIfRequired()|. this is because it is unsafe
1088 // (could deadlock) to fork after we've spawned some threads which might
1089 // printf (and thus hold locks).
1090 const std::string path = RandomTraceFileName();
1091 auto perfetto_proc = ExecPerfetto(
1092 {
1093 "-o",
1094 path,
1095 "-c",
1096 "-",
1097 },
1098 trace_config.SerializeAsString());
1099
1100 std::string triggers = R"(
1101 activate_triggers: "trigger_name_2"
1102 activate_triggers: "trigger_name"
1103 activate_triggers: "trigger_name_3"
1104 )";
1105 auto perfetto_proc_2 = ExecPerfetto(
1106 {
1107 "-o",
1108 path,
1109 "-c",
1110 "-",
1111 "--txt",
1112 },
1113 triggers);
1114
1115 // Start the service and connect a simple fake producer.
1116 StartServiceIfRequiredNoNewExecsAfterThis();
1117 auto* fake_producer = ConnectFakeProducer();
1118 EXPECT_TRUE(fake_producer);
1119
1120 std::thread background_trace([&perfetto_proc]() {
1121 std::string stderr_str;
1122 EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
1123 });
1124
1125 WaitForProducerEnabled();
1126 // Wait for the producer to start, and then write out 11 packets, before the
1127 // trace actually starts (the trigger is seen).
1128 auto on_data_written = task_runner_.CreateCheckpoint("data_written_1");
1129 fake_producer->ProduceEventBatch(WrapTask(on_data_written));
1130 task_runner_.RunUntilCheckpoint("data_written_1");
1131
1132 EXPECT_EQ(0, perfetto_proc_2.Run(&stderr_)) << "stderr: " << stderr_;
1133
1134 background_trace.join();
1135
1136 std::string trace_str;
1137 base::ReadFile(path, &trace_str);
1138 protos::gen::Trace trace;
1139 ASSERT_TRUE(trace.ParseFromString(trace_str));
1140 EXPECT_LT(static_cast<int>(kMessageCount), trace.packet_size());
1141 bool seen_first_trigger = false;
1142 for (const auto& packet : trace.packet()) {
1143 if (packet.has_trace_config()) {
1144 // Ensure the trace config properly includes the trigger mode we set.
1145 auto kStopTrig = protos::gen::TraceConfig::TriggerConfig::STOP_TRACING;
1146 EXPECT_EQ(kStopTrig,
1147 packet.trace_config().trigger_config().trigger_mode());
1148 } else if (packet.has_trigger()) {
1149 // validate that the triggers are properly added to the trace.
1150 if (!seen_first_trigger) {
1151 EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
1152 seen_first_trigger = true;
1153 } else {
1154 EXPECT_EQ("trigger_name_3", packet.trigger().trigger_name());
1155 }
1156 } else if (packet.has_for_testing()) {
1157 // Make sure that the data size is correctly set based on what we
1158 // requested.
1159 EXPECT_EQ(kMessageSize, packet.for_testing().str().size());
1160 }
1161 }
1162 }
1163
1164 TEST_F(PerfettoCmdlineTest, NoSanitizers(TriggerFromConfigStopsFileOpening)) {
1165 // See |message_count| and |message_size| in the TraceConfig above.
1166 constexpr size_t kMessageCount = 11;
1167 constexpr size_t kMessageSize = 32;
1168 protos::gen::TraceConfig trace_config;
1169 trace_config.add_buffers()->set_size_kb(1024);
1170 auto* ds_config = trace_config.add_data_sources()->mutable_config();
1171 ds_config->set_name("android.perfetto.FakeProducer");
1172 ds_config->mutable_for_testing()->set_message_count(kMessageCount);
1173 ds_config->mutable_for_testing()->set_message_size(kMessageSize);
1174 auto* trigger_cfg = trace_config.mutable_trigger_config();
1175 trigger_cfg->set_trigger_mode(
1176 protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
1177 trigger_cfg->set_trigger_timeout_ms(15000);
1178 auto* trigger = trigger_cfg->add_triggers();
1179 trigger->set_name("trigger_name");
1180 // |stop_delay_ms| must be long enough that we can write the packets in
1181 // before the trace finishes. This has to be long enough for the slowest
1182 // emulator. But as short as possible to prevent the test running a long
1183 // time.
1184 trigger->set_stop_delay_ms(500);
1185 trigger = trigger_cfg->add_triggers();
1186 trigger->set_name("trigger_name_3");
1187 trigger->set_stop_delay_ms(60000);
1188
1189 // We have to construct all the processes we want to fork before we start the
1190 // service with |StartServiceIfRequired()|. this is because it is unsafe
1191 // (could deadlock) to fork after we've spawned some threads which might
1192 // printf (and thus hold locks).
1193 const std::string path = RandomTraceFileName();
1194 std::string triggers = R"(
1195 activate_triggers: "trigger_name_2"
1196 activate_triggers: "trigger_name"
1197 activate_triggers: "trigger_name_3"
1198 )";
1199 auto perfetto_proc = ExecPerfetto(
1200 {
1201 "-o",
1202 path,
1203 "-c",
1204 "-",
1205 "--txt",
1206 },
1207 triggers);
1208
1209 // Start the service and connect a simple fake producer.
1210 StartServiceIfRequiredNoNewExecsAfterThis();
1211 auto* fake_producer = ConnectFakeProducer();
1212 EXPECT_TRUE(fake_producer);
1213
1214 std::string trace_str;
1215 EXPECT_FALSE(base::ReadFile(path, &trace_str));
1216
1217 EXPECT_EQ(0, perfetto_proc.Run(&stderr_)) << "stderr: " << stderr_;
1218
1219 EXPECT_FALSE(base::ReadFile(path, &trace_str));
1220 }
1221
1222 TEST_F(PerfettoCmdlineTest, NoSanitizers(Query)) {
1223 auto query = ExecPerfetto({"--query"});
1224 auto query_raw = ExecPerfetto({"--query-raw"});
1225 StartServiceIfRequiredNoNewExecsAfterThis();
1226 EXPECT_EQ(0, query.Run(&stderr_)) << stderr_;
1227 EXPECT_EQ(0, query_raw.Run(&stderr_)) << stderr_;
1228 }
1229
1230 } // namespace perfetto
1231