Home | History | Annotate | Download | only in test
      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 <condition_variable>
     21 #include <functional>
     22 #include <initializer_list>
     23 #include <random>
     24 #include <thread>
     25 
     26 #include "gmock/gmock.h"
     27 #include "gtest/gtest.h"
     28 #include "perfetto/base/build_config.h"
     29 #include "perfetto/base/file_utils.h"
     30 #include "perfetto/base/logging.h"
     31 #include "perfetto/base/pipe.h"
     32 #include "perfetto/base/temp_file.h"
     33 #include "perfetto/traced/traced.h"
     34 #include "perfetto/tracing/core/trace_config.h"
     35 #include "perfetto/tracing/core/trace_packet.h"
     36 #include "src/base/test/test_task_runner.h"
     37 #include "src/traced/probes/ftrace/ftrace_controller.h"
     38 #include "src/traced/probes/ftrace/ftrace_procfs.h"
     39 #include "src/tracing/ipc/default_socket.h"
     40 #include "test/task_runner_thread.h"
     41 #include "test/task_runner_thread_delegates.h"
     42 #include "test/test_helper.h"
     43 
     44 #include "perfetto/trace/trace.pb.h"
     45 #include "perfetto/trace/trace_packet.pb.h"
     46 #include "perfetto/trace/trace_packet.pbzero.h"
     47 
     48 namespace perfetto {
     49 
     50 namespace {
     51 
     52 using ::testing::ContainsRegex;
     53 using ::testing::HasSubstr;
     54 
     55 std::string RandomTraceFileName() {
     56 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
     57   constexpr char kSysTmpPath[] = "/data/misc/perfetto-traces";
     58 #else
     59   constexpr char kSysTmpPath[] = "/tmp";
     60 #endif
     61   static int suffix = 0;
     62 
     63   std::string path;
     64   path.assign(kSysTmpPath);
     65   path.append("/trace-");
     66   path.append(std::to_string(base::GetBootTimeNs().count()));
     67   path.append("-");
     68   path.append(std::to_string(suffix++));
     69   return path;
     70 }
     71 
     72 class PerfettoTest : public ::testing::Test {
     73  public:
     74   void SetUp() override {
     75     // TODO(primiano): refactor this, it's copy/pasted in three places now.
     76     size_t index = 0;
     77     constexpr auto kTracingPaths = FtraceController::kTracingPaths;
     78     while (!ftrace_procfs_ && kTracingPaths[index]) {
     79       ftrace_procfs_ = FtraceProcfs::Create(kTracingPaths[index++]);
     80     }
     81     if (!ftrace_procfs_)
     82       return;
     83     ftrace_procfs_->SetTracingOn(false);
     84   }
     85 
     86   void TearDown() override {
     87     if (ftrace_procfs_)
     88       ftrace_procfs_->SetTracingOn(false);
     89   }
     90 
     91   std::unique_ptr<FtraceProcfs> ftrace_procfs_;
     92 };
     93 
     94 class PerfettoCmdlineTest : public ::testing::Test {
     95  public:
     96   void SetUp() override {
     97     test_helper_.StartServiceIfRequired();
     98   }
     99 
    100   void TearDown() override {}
    101 
    102   int ExecPerfetto(std::initializer_list<std::string> args,
    103                    std::string input = "") {
    104     return Exec("perfetto", args, input);
    105   }
    106 
    107   int ExecTrigger(std::initializer_list<std::string> args,
    108                   std::string input = "") {
    109     return Exec("trigger_perfetto", args, input);
    110   }
    111 
    112   // Fork() + executes the perfetto cmdline client with the given args and
    113   // returns the exit code.
    114   int Exec(const std::string& argv0,
    115            std::initializer_list<std::string> args,
    116            std::string input = "") {
    117     std::vector<char> argv_buffer;
    118     std::vector<size_t> argv_offsets;
    119     std::vector<char*> argv;
    120     argv_offsets.push_back(0);
    121 
    122     argv_buffer.insert(argv_buffer.end(), argv0.begin(), argv0.end());
    123     argv_buffer.push_back('\0');
    124 
    125     for (const std::string& arg : args) {
    126       argv_offsets.push_back(argv_buffer.size());
    127       argv_buffer.insert(argv_buffer.end(), arg.begin(), arg.end());
    128       argv_buffer.push_back('\0');
    129     }
    130 
    131     for (size_t off : argv_offsets)
    132       argv.push_back(&argv_buffer[off]);
    133     argv.push_back(nullptr);
    134 
    135     // Create the pipe for the child process to return stderr.
    136     base::Pipe err_pipe = base::Pipe::Create();
    137     base::Pipe in_pipe = base::Pipe::Create();
    138 
    139     pid_t pid = fork();
    140     PERFETTO_CHECK(pid >= 0);
    141     if (pid == 0) {
    142       // Child process.
    143       err_pipe.rd.reset();
    144       in_pipe.wr.reset();
    145 
    146       int devnull = open("/dev/null", O_RDWR);
    147       PERFETTO_CHECK(devnull >= 0);
    148       PERFETTO_CHECK(dup2(*in_pipe.rd, STDIN_FILENO) != -1);
    149       PERFETTO_CHECK(dup2(devnull, STDOUT_FILENO) != -1);
    150       PERFETTO_CHECK(dup2(*err_pipe.wr, STDERR_FILENO) != -1);
    151 #if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
    152       setenv("PERFETTO_CONSUMER_SOCK_NAME", TestHelper::GetConsumerSocketName(),
    153              1);
    154       setenv("PERFETTO_PRODUCER_SOCK_NAME", TestHelper::GetProducerSocketName(),
    155              1);
    156       if (argv0 == "perfetto") {
    157         _exit(PerfettoCmdMain(static_cast<int>(argv.size() - 1), argv.data()));
    158       } else if (argv0 == "trigger_perfetto") {
    159         _exit(TriggerPerfettoMain(static_cast<int>(argv.size() - 1),
    160                                   argv.data()));
    161       } else {
    162         ADD_FAILURE() << "Unknown binary: " << argv0.c_str();
    163       }
    164 #else
    165       execv((std::string("/system/bin/") + argv0).c_str(), &argv[0]);
    166       _exit(3);
    167 #endif
    168     }
    169 
    170     // Parent.
    171     err_pipe.wr.reset();
    172     stderr_ = std::string(1024 * 1024, '\0');
    173 
    174     // This is generally an unsafe pattern because the child process might be
    175     // blocked on stdout and stall the stdin reads. It's pragmatically okay for
    176     // our test cases because stdin is not expected to exceed the pipe buffer.
    177     PERFETTO_CHECK(input.size() <= base::kPageSize);
    178     PERFETTO_CHECK(
    179         PERFETTO_EINTR(write(*in_pipe.wr, input.data(), input.size())) ==
    180         static_cast<ssize_t>(input.size()));
    181     in_pipe.wr.reset();
    182 
    183     // Close the input pipe only after the write so we don't get an EPIPE signal
    184     // in the cases when the child process earlies out without reading stdin.
    185     in_pipe.rd.reset();
    186 
    187     ssize_t rsize = 0;
    188     size_t stderr_pos = 0;
    189     while (stderr_pos < stderr_.size()) {
    190       rsize = PERFETTO_EINTR(read(*err_pipe.rd, &stderr_[stderr_pos],
    191                                   stderr_.size() - stderr_pos - 1));
    192       if (rsize <= 0)
    193         break;
    194       stderr_pos += static_cast<size_t>(rsize);
    195     }
    196     stderr_.resize(stderr_pos);
    197     int status = 1;
    198     PERFETTO_CHECK(PERFETTO_EINTR(waitpid(pid, &status, 0)) == pid);
    199     int exit_code;
    200     if (WIFEXITED(status)) {
    201       exit_code = WEXITSTATUS(status);
    202     } else if (WIFSIGNALED(status)) {
    203       exit_code = -(WTERMSIG(status));
    204       PERFETTO_CHECK(exit_code < 0);
    205     } else {
    206       PERFETTO_FATAL("Unexpected exit status: %d", status);
    207     }
    208     return exit_code;
    209   }
    210 
    211   std::string stderr_;
    212   base::TestTaskRunner task_runner_;
    213   TestHelper test_helper_{&task_runner_};
    214 };
    215 
    216 }  // namespace
    217 
    218 // If we're building on Android and starting the daemons ourselves,
    219 // create the sockets in a world-writable location.
    220 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
    221     PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
    222 #define TEST_PRODUCER_SOCK_NAME "/data/local/tmp/traced_producer"
    223 #else
    224 #define TEST_PRODUCER_SOCK_NAME ::perfetto::GetProducerSocket()
    225 #endif
    226 
    227 // TODO(b/73453011): reenable on more platforms (including standalone Android).
    228 #if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
    229 #define TreeHuggerOnly(x) x
    230 #else
    231 #define TreeHuggerOnly(x) DISABLED_##x
    232 #endif
    233 
    234 TEST_F(PerfettoTest, TreeHuggerOnly(TestFtraceProducer)) {
    235   base::TestTaskRunner task_runner;
    236 
    237   TestHelper helper(&task_runner);
    238   helper.StartServiceIfRequired();
    239 
    240 #if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
    241   TaskRunnerThread producer_thread("perfetto.prd");
    242   producer_thread.Start(std::unique_ptr<ProbesProducerDelegate>(
    243       new ProbesProducerDelegate(TEST_PRODUCER_SOCK_NAME)));
    244 #endif
    245 
    246   helper.ConnectConsumer();
    247   helper.WaitForConsumerConnect();
    248 
    249   TraceConfig trace_config;
    250   trace_config.add_buffers()->set_size_kb(1024);
    251   trace_config.set_duration_ms(3000);
    252 
    253   auto* ds_config = trace_config.add_data_sources()->mutable_config();
    254   ds_config->set_name("linux.ftrace");
    255   ds_config->set_target_buffer(0);
    256 
    257   auto* ftrace_config = ds_config->mutable_ftrace_config();
    258   *ftrace_config->add_ftrace_events() = "sched_switch";
    259   *ftrace_config->add_ftrace_events() = "bar";
    260 
    261   helper.StartTracing(trace_config);
    262   helper.WaitForTracingDisabled();
    263 
    264   helper.ReadData();
    265   helper.WaitForReadData();
    266 
    267   const auto& packets = helper.trace();
    268   ASSERT_GT(packets.size(), 0u);
    269 
    270   for (const auto& packet : packets) {
    271     for (int ev = 0; ev < packet.ftrace_events().event_size(); ev++) {
    272       ASSERT_TRUE(packet.ftrace_events().event(ev).has_sched_switch());
    273     }
    274   }
    275 }
    276 
    277 TEST_F(PerfettoTest, TreeHuggerOnly(TestFtraceFlush)) {
    278   base::TestTaskRunner task_runner;
    279 
    280   TestHelper helper(&task_runner);
    281   helper.StartServiceIfRequired();
    282 
    283 #if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
    284   TaskRunnerThread producer_thread("perfetto.prd");
    285   producer_thread.Start(std::unique_ptr<ProbesProducerDelegate>(
    286       new ProbesProducerDelegate(TEST_PRODUCER_SOCK_NAME)));
    287 #endif
    288 
    289   helper.ConnectConsumer();
    290   helper.WaitForConsumerConnect();
    291 
    292   const uint32_t kTestTimeoutMs = 30000;
    293   TraceConfig trace_config;
    294   trace_config.add_buffers()->set_size_kb(16);
    295   trace_config.set_duration_ms(kTestTimeoutMs);
    296 
    297   auto* ds_config = trace_config.add_data_sources()->mutable_config();
    298   ds_config->set_name("linux.ftrace");
    299 
    300   auto* ftrace_config = ds_config->mutable_ftrace_config();
    301   *ftrace_config->add_ftrace_events() = "print";
    302 
    303   helper.StartTracing(trace_config);
    304 
    305   // Do a first flush just to synchronize with the producer. The problem here
    306   // is that, on a Linux workstation, the producer can take several seconds just
    307   // to get to the point where ftrace is ready. We use the flush ack as a
    308   // synchronization point.
    309   helper.FlushAndWait(kTestTimeoutMs);
    310 
    311   EXPECT_TRUE(ftrace_procfs_->IsTracingEnabled());
    312   const char kMarker[] = "just_one_event";
    313   EXPECT_TRUE(ftrace_procfs_->WriteTraceMarker(kMarker));
    314 
    315   // This is the real flush we are testing.
    316   helper.FlushAndWait(kTestTimeoutMs);
    317 
    318   helper.DisableTracing();
    319   helper.WaitForTracingDisabled(kTestTimeoutMs);
    320 
    321   helper.ReadData();
    322   helper.WaitForReadData();
    323 
    324   int marker_found = 0;
    325   for (const auto& packet : helper.trace()) {
    326     for (int i = 0; i < packet.ftrace_events().event_size(); i++) {
    327       const auto& ev = packet.ftrace_events().event(i);
    328       if (ev.has_print() && ev.print().buf().find(kMarker) != std::string::npos)
    329         marker_found++;
    330     }
    331   }
    332   ASSERT_EQ(marker_found, 1);
    333 }
    334 
    335 TEST_F(PerfettoTest, TreeHuggerOnly(TestBatteryTracing)) {
    336   base::TestTaskRunner task_runner;
    337 
    338   TestHelper helper(&task_runner);
    339   helper.StartServiceIfRequired();
    340 
    341 #if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
    342   TaskRunnerThread producer_thread("perfetto.prd");
    343   producer_thread.Start(std::unique_ptr<ProbesProducerDelegate>(
    344       new ProbesProducerDelegate(TEST_PRODUCER_SOCK_NAME)));
    345 #else
    346   base::ignore_result(TEST_PRODUCER_SOCK_NAME);
    347 #endif
    348 
    349   helper.ConnectConsumer();
    350   helper.WaitForConsumerConnect();
    351 
    352   TraceConfig trace_config;
    353   trace_config.add_buffers()->set_size_kb(128);
    354   trace_config.set_duration_ms(3000);
    355 
    356   auto* ds_config = trace_config.add_data_sources()->mutable_config();
    357   ds_config->set_name("android.power");
    358   ds_config->set_target_buffer(0);
    359   auto* power_config = ds_config->mutable_android_power_config();
    360   power_config->set_battery_poll_ms(250);
    361   *power_config->add_battery_counters() =
    362       AndroidPowerConfig::BATTERY_COUNTER_CHARGE;
    363   *power_config->add_battery_counters() =
    364       AndroidPowerConfig::BATTERY_COUNTER_CAPACITY_PERCENT;
    365 
    366   helper.StartTracing(trace_config);
    367   helper.WaitForTracingDisabled();
    368 
    369   helper.ReadData();
    370   helper.WaitForReadData();
    371 
    372   const auto& packets = helper.trace();
    373   ASSERT_GT(packets.size(), 0u);
    374 
    375   bool has_battery_packet = false;
    376   for (const auto& packet : packets) {
    377     if (!packet.has_battery())
    378       continue;
    379     has_battery_packet = true;
    380     // Unfortunately we cannot make any assertions on the charge counter.
    381     // On some devices it can reach negative values (b/64685329).
    382     EXPECT_GE(packet.battery().capacity_percent(), 0);
    383     EXPECT_LE(packet.battery().capacity_percent(), 100);
    384   }
    385 
    386   ASSERT_TRUE(has_battery_packet);
    387 }
    388 
    389 TEST_F(PerfettoTest, TestFakeProducer) {
    390   base::TestTaskRunner task_runner;
    391 
    392   TestHelper helper(&task_runner);
    393   helper.StartServiceIfRequired();
    394   helper.ConnectFakeProducer();
    395   helper.ConnectConsumer();
    396   helper.WaitForConsumerConnect();
    397 
    398   TraceConfig trace_config;
    399   trace_config.add_buffers()->set_size_kb(1024);
    400   trace_config.set_duration_ms(200);
    401 
    402   auto* ds_config = trace_config.add_data_sources()->mutable_config();
    403   ds_config->set_name("android.perfetto.FakeProducer");
    404   ds_config->set_target_buffer(0);
    405 
    406   static constexpr size_t kNumPackets = 11;
    407   static constexpr uint32_t kRandomSeed = 42;
    408   static constexpr uint32_t kMsgSize = 1024;
    409   ds_config->mutable_for_testing()->set_seed(kRandomSeed);
    410   ds_config->mutable_for_testing()->set_message_count(kNumPackets);
    411   ds_config->mutable_for_testing()->set_message_size(kMsgSize);
    412   ds_config->mutable_for_testing()->set_send_batch_on_register(true);
    413 
    414   helper.StartTracing(trace_config);
    415   helper.WaitForTracingDisabled();
    416 
    417   helper.ReadData();
    418   helper.WaitForReadData();
    419 
    420   const auto& packets = helper.trace();
    421   ASSERT_EQ(packets.size(), kNumPackets);
    422 
    423   std::minstd_rand0 rnd_engine(kRandomSeed);
    424   for (const auto& packet : packets) {
    425     ASSERT_TRUE(packet.has_for_testing());
    426     ASSERT_EQ(packet.for_testing().seq_value(), rnd_engine());
    427   }
    428 }
    429 
    430 TEST_F(PerfettoTest, VeryLargePackets) {
    431   base::TestTaskRunner task_runner;
    432 
    433   TestHelper helper(&task_runner);
    434   helper.StartServiceIfRequired();
    435   helper.ConnectFakeProducer();
    436   helper.ConnectConsumer();
    437   helper.WaitForConsumerConnect();
    438 
    439   TraceConfig trace_config;
    440   trace_config.add_buffers()->set_size_kb(4096 * 10);
    441   trace_config.set_duration_ms(500);
    442 
    443   auto* ds_config = trace_config.add_data_sources()->mutable_config();
    444   ds_config->set_name("android.perfetto.FakeProducer");
    445   ds_config->set_target_buffer(0);
    446 
    447   static constexpr size_t kNumPackets = 7;
    448   static constexpr uint32_t kRandomSeed = 42;
    449   static constexpr uint32_t kMsgSize = 1024 * 1024 - 42;
    450   ds_config->mutable_for_testing()->set_seed(kRandomSeed);
    451   ds_config->mutable_for_testing()->set_message_count(kNumPackets);
    452   ds_config->mutable_for_testing()->set_message_size(kMsgSize);
    453   ds_config->mutable_for_testing()->set_send_batch_on_register(true);
    454 
    455   helper.StartTracing(trace_config);
    456   helper.WaitForTracingDisabled();
    457 
    458   helper.ReadData();
    459   helper.WaitForReadData();
    460 
    461   const auto& packets = helper.trace();
    462   ASSERT_EQ(packets.size(), kNumPackets);
    463 
    464   std::minstd_rand0 rnd_engine(kRandomSeed);
    465   for (const auto& packet : packets) {
    466     ASSERT_TRUE(packet.has_for_testing());
    467     ASSERT_EQ(packet.for_testing().seq_value(), rnd_engine());
    468     size_t msg_size = packet.for_testing().str().size();
    469     ASSERT_EQ(kMsgSize, msg_size);
    470     for (size_t i = 0; i < msg_size; i++)
    471       ASSERT_EQ(i < msg_size - 1 ? '.' : 0, packet.for_testing().str()[i]);
    472   }
    473 }
    474 
    475 TEST_F(PerfettoTest, DetachAndReattach) {
    476   base::TestTaskRunner task_runner;
    477 
    478   TraceConfig trace_config;
    479   trace_config.add_buffers()->set_size_kb(1024);
    480   trace_config.set_duration_ms(10000);  // Max timeout, session is ended before.
    481   auto* ds_config = trace_config.add_data_sources()->mutable_config();
    482   ds_config->set_name("android.perfetto.FakeProducer");
    483   static constexpr size_t kNumPackets = 11;
    484   ds_config->mutable_for_testing()->set_message_count(kNumPackets);
    485   ds_config->mutable_for_testing()->set_message_size(32);
    486 
    487   // Enable tracing and detach as soon as it gets started.
    488   TestHelper helper(&task_runner);
    489   helper.StartServiceIfRequired();
    490   auto* fake_producer = helper.ConnectFakeProducer();
    491   helper.ConnectConsumer();
    492   helper.WaitForConsumerConnect();
    493   helper.StartTracing(trace_config);
    494 
    495   // Detach.
    496   helper.DetachConsumer("key");
    497 
    498   // Write data while detached.
    499   helper.WaitForProducerEnabled();
    500   auto on_data_written = task_runner.CreateCheckpoint("data_written");
    501   fake_producer->ProduceEventBatch(helper.WrapTask(on_data_written));
    502   task_runner.RunUntilCheckpoint("data_written");
    503 
    504   // Then reattach the consumer.
    505   helper.ConnectConsumer();
    506   helper.WaitForConsumerConnect();
    507   helper.AttachConsumer("key");
    508 
    509   helper.DisableTracing();
    510   helper.WaitForTracingDisabled();
    511 
    512   helper.ReadData();
    513   helper.WaitForReadData();
    514   const auto& packets = helper.trace();
    515   ASSERT_EQ(packets.size(), kNumPackets);
    516 }
    517 
    518 // Tests that a detached trace session is automatically cleaned up if the
    519 // consumer doesn't re-attach before its expiration time.
    520 TEST_F(PerfettoTest, ReattachFailsAfterTimeout) {
    521   base::TestTaskRunner task_runner;
    522 
    523   TraceConfig trace_config;
    524   trace_config.add_buffers()->set_size_kb(1024);
    525   trace_config.set_duration_ms(250);
    526   trace_config.set_write_into_file(true);
    527   trace_config.set_file_write_period_ms(100000);
    528   auto* ds_config = trace_config.add_data_sources()->mutable_config();
    529   ds_config->set_name("android.perfetto.FakeProducer");
    530   ds_config->mutable_for_testing()->set_message_count(1);
    531   ds_config->mutable_for_testing()->set_message_size(32);
    532   ds_config->mutable_for_testing()->set_send_batch_on_register(true);
    533 
    534   // Enable tracing and detach as soon as it gets started.
    535   TestHelper helper(&task_runner);
    536   helper.StartServiceIfRequired();
    537   helper.ConnectFakeProducer();
    538   helper.ConnectConsumer();
    539   helper.WaitForConsumerConnect();
    540 
    541   auto pipe_pair = base::Pipe::Create();
    542   helper.StartTracing(trace_config, std::move(pipe_pair.wr));
    543 
    544   // Detach.
    545   helper.DetachConsumer("key");
    546 
    547   // Use the file EOF (write end closed) as a way to detect when the trace
    548   // session is ended.
    549   char buf[1024];
    550   while (PERFETTO_EINTR(read(*pipe_pair.rd, buf, sizeof(buf))) > 0) {
    551   }
    552 
    553   // Give some margin for the tracing service to destroy the session.
    554   usleep(250000);
    555 
    556   // Reconnect and find out that it's too late and the session is gone.
    557   helper.ConnectConsumer();
    558   helper.WaitForConsumerConnect();
    559   EXPECT_FALSE(helper.AttachConsumer("key"));
    560 }
    561 
    562 // Disable cmdline tests on sanitizets because they use fork() and that messes
    563 // up leak / races detections, which has been fixed only recently (see
    564 // https://github.com/google/sanitizers/issues/836 ).
    565 #if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
    566     defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER)
    567 #define NoSanitizers(X) DISABLED_##X
    568 #else
    569 #define NoSanitizers(X) X
    570 #endif
    571 
    572 TEST_F(PerfettoCmdlineTest, NoSanitizers(InvalidCases)) {
    573   std::string cfg("duration_ms: 100");
    574 
    575   EXPECT_EQ(1, ExecPerfetto({"--invalid-arg"}));
    576 
    577   EXPECT_EQ(1, ExecPerfetto({"-c", "-", "-o", "-"}, ""));
    578   EXPECT_THAT(stderr_, HasSubstr("TraceConfig is empty"));
    579 
    580   // Cannot make assertions on --dropbox because on standalone builds it fails
    581   // prematurely due to lack of dropbox.
    582   EXPECT_EQ(
    583       1, ExecPerfetto({"-c", "-", "--txt", "-o", "-", "--dropbox=foo"}, cfg));
    584 
    585   EXPECT_EQ(1, ExecPerfetto({"-c", "-", "--txt"}, cfg));
    586   EXPECT_THAT(stderr_, HasSubstr("Either --out or --dropbox"));
    587 
    588   // Disallow mixing simple and file config.
    589   EXPECT_EQ(1, ExecPerfetto({"-o", "-", "-c", "-", "-t", "2s"}, cfg));
    590   EXPECT_THAT(stderr_, HasSubstr("Cannot specify both -c"));
    591 
    592   EXPECT_EQ(1, ExecPerfetto({"-o", "-", "-c", "-", "-b", "2m"}, cfg));
    593   EXPECT_THAT(stderr_, HasSubstr("Cannot specify both -c"));
    594 
    595   EXPECT_EQ(1, ExecPerfetto({"-o", "-", "-c", "-", "-s", "2m"}, cfg));
    596   EXPECT_THAT(stderr_, HasSubstr("Cannot specify both -c"));
    597 
    598   // Invalid --attach / --detach cases.
    599   EXPECT_EQ(1, ExecPerfetto({"-c", "-", "--txt", "-o", "-", "--stop"}, cfg));
    600   EXPECT_THAT(stderr_, HasSubstr("--stop is supported only in combination"));
    601 
    602   EXPECT_EQ(1,
    603             ExecPerfetto({"-c", "-", "--txt", "-o", "-", "--attach=foo"}, cfg));
    604   EXPECT_THAT(stderr_, HasSubstr("trace config with --attach"));
    605 
    606   EXPECT_EQ(1, ExecPerfetto({"-t", "2s", "-o", "-", "--attach=foo"}, cfg));
    607   EXPECT_THAT(stderr_, HasSubstr("trace config with --attach"));
    608 
    609   EXPECT_EQ(1, ExecPerfetto({"--attach"}, cfg));
    610   EXPECT_THAT(stderr_, ContainsRegex("option.*--attach.*requires an argument"));
    611 
    612   EXPECT_EQ(1, ExecPerfetto({"-t", "2s", "-o", "-", "--detach"}, cfg));
    613   EXPECT_THAT(stderr_, ContainsRegex("option.*--detach.*requires an argument"));
    614 
    615   EXPECT_EQ(1, ExecPerfetto({"-t", "2s", "--detach=foo"}, cfg));
    616   EXPECT_THAT(stderr_, HasSubstr("--out or --dropbox is required"));
    617 }
    618 
    619 TEST_F(PerfettoCmdlineTest, NoSanitizers(TxtConfig)) {
    620   std::string cfg("duration_ms: 100");
    621   EXPECT_EQ(0, ExecPerfetto({"-c", "-", "--txt", "-o", "-"}, cfg)) << stderr_;
    622 }
    623 
    624 TEST_F(PerfettoCmdlineTest, NoSanitizers(SimpleConfig)) {
    625   EXPECT_EQ(0, ExecPerfetto({"-o", "-", "-c", "-", "-t", "100ms"}));
    626 }
    627 
    628 TEST_F(PerfettoCmdlineTest, NoSanitizers(DetachAndAttach)) {
    629   EXPECT_NE(0, ExecPerfetto({"--attach=not_existent"}));
    630   EXPECT_THAT(stderr_, HasSubstr("Session re-attach failed"));
    631 
    632   std::string cfg("duration_ms: 10000; write_into_file: true");
    633   EXPECT_EQ(0, ExecPerfetto(
    634                    {"-o", "-", "-c", "-", "--txt", "--detach=valid_stop"}, cfg))
    635       << stderr_;
    636   EXPECT_EQ(0, ExecPerfetto({"--attach=valid_stop", "--stop"}));
    637 }
    638 
    639 TEST_F(PerfettoCmdlineTest, NoSanitizers(StartTracingTrigger)) {
    640   // See |message_count| and |message_size| in the TraceConfig above.
    641   constexpr size_t kMessageCount = 11;
    642   constexpr size_t kMessageSize = 32;
    643   protos::TraceConfig trace_config;
    644   trace_config.add_buffers()->set_size_kb(1024);
    645   auto* ds_config = trace_config.add_data_sources()->mutable_config();
    646   ds_config->set_name("android.perfetto.FakeProducer");
    647   ds_config->mutable_for_testing()->set_message_count(kMessageCount);
    648   ds_config->mutable_for_testing()->set_message_size(kMessageSize);
    649   auto* trigger_cfg = trace_config.mutable_trigger_config();
    650   trigger_cfg->set_trigger_mode(
    651       protos::TraceConfig::TriggerConfig::START_TRACING);
    652   trigger_cfg->set_trigger_timeout_ms(15000);
    653   auto* trigger = trigger_cfg->add_triggers();
    654   trigger->set_name("trigger_name");
    655   // |stop_delay_ms| must be long enough that we can write the packets in
    656   // before the trace finishes. This has to be long enough for the slowest
    657   // emulator. But as short as possible to prevent the test running a long
    658   // time.
    659   trigger->set_stop_delay_ms(500);
    660 
    661   // We have 6 normal preamble packets (start clock, trace config, clock,
    662   // system info, sync marker, stats) and then since this is a trace with a
    663   // trigger config we have an additional ReceivedTriggers packet.
    664   constexpr size_t kPreamblePackets = 7;
    665 
    666   base::TestTaskRunner task_runner;
    667 
    668   // Enable tracing and detach as soon as it gets started.
    669   TestHelper helper(&task_runner);
    670   helper.StartServiceIfRequired();
    671   auto* fake_producer = helper.ConnectFakeProducer();
    672   EXPECT_TRUE(fake_producer);
    673   const std::string path = RandomTraceFileName();
    674   std::thread background_trace([&path, &trace_config, this]() {
    675     EXPECT_EQ(0, ExecPerfetto(
    676                      {
    677                          "-o", path, "-c", "-",
    678                      },
    679                      trace_config.SerializeAsString()));
    680   });
    681 
    682   helper.WaitForProducerSetup();
    683   EXPECT_EQ(0, ExecTrigger({"trigger_name"})) << "stderr: " << stderr_;
    684 
    685   // Wait for the producer to start, and then write out 11 packets.
    686   helper.WaitForProducerEnabled();
    687   auto on_data_written = task_runner.CreateCheckpoint("data_written");
    688   fake_producer->ProduceEventBatch(helper.WrapTask(on_data_written));
    689   task_runner.RunUntilCheckpoint("data_written");
    690   background_trace.join();
    691 
    692   std::string trace_str;
    693   base::ReadFile(path, &trace_str);
    694   protos::Trace trace;
    695   ASSERT_TRUE(trace.ParseFromString(trace_str));
    696   EXPECT_EQ(kPreamblePackets + kMessageCount, trace.packet_size());
    697   for (const auto& packet : trace.packet()) {
    698     if (packet.data_case() == protos::TracePacket::kTraceConfig) {
    699       // Ensure the trace config properly includes the trigger mode we set.
    700       EXPECT_EQ(protos::TraceConfig::TriggerConfig::START_TRACING,
    701                 packet.trace_config().trigger_config().trigger_mode());
    702     } else if (packet.data_case() == protos::TracePacket::kTrigger) {
    703       // validate that the triggers are properly added to the trace.
    704       EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
    705     } else if (packet.data_case() == protos::TracePacket::kForTesting) {
    706       // Make sure that the data size is correctly set based on what we
    707       // requested.
    708       EXPECT_EQ(kMessageSize, packet.for_testing().str().size());
    709     }
    710   }
    711 }
    712 
    713 TEST_F(PerfettoCmdlineTest, NoSanitizers(StopTracingTrigger)) {
    714   // See |message_count| and |message_size| in the TraceConfig above.
    715   constexpr size_t kMessageCount = 11;
    716   constexpr size_t kMessageSize = 32;
    717   protos::TraceConfig trace_config;
    718   trace_config.add_buffers()->set_size_kb(1024);
    719   auto* ds_config = trace_config.add_data_sources()->mutable_config();
    720   ds_config->set_name("android.perfetto.FakeProducer");
    721   ds_config->mutable_for_testing()->set_message_count(kMessageCount);
    722   ds_config->mutable_for_testing()->set_message_size(kMessageSize);
    723   auto* trigger_cfg = trace_config.mutable_trigger_config();
    724   trigger_cfg->set_trigger_mode(
    725       protos::TraceConfig::TriggerConfig::STOP_TRACING);
    726   trigger_cfg->set_trigger_timeout_ms(15000);
    727   auto* trigger = trigger_cfg->add_triggers();
    728   trigger->set_name("trigger_name");
    729   // |stop_delay_ms| must be long enough that we can write the packets in
    730   // before the trace finishes. This has to be long enough for the slowest
    731   // emulator. But as short as possible to prevent the test running a long
    732   // time.
    733   trigger->set_stop_delay_ms(500);
    734   trigger = trigger_cfg->add_triggers();
    735   trigger->set_name("trigger_name_3");
    736   trigger->set_stop_delay_ms(60000);
    737 
    738   // We have 6 normal preamble packets (start clock, trace config, clock,
    739   // system info, sync marker, stats) and then since this is a trace with a
    740   // trigger config we have an additional ReceivedTriggers packet.
    741   constexpr size_t kPreamblePackets = 8;
    742 
    743   base::TestTaskRunner task_runner;
    744 
    745   // Enable tracing and detach as soon as it gets started.
    746   TestHelper helper(&task_runner);
    747   helper.StartServiceIfRequired();
    748   auto* fake_producer = helper.ConnectFakeProducer();
    749   EXPECT_TRUE(fake_producer);
    750 
    751   const std::string path = RandomTraceFileName();
    752   std::thread background_trace([&path, &trace_config, this]() {
    753     EXPECT_EQ(0, ExecPerfetto(
    754                      {
    755                          "-o", path, "-c", "-",
    756                      },
    757                      trace_config.SerializeAsString()));
    758   });
    759 
    760   helper.WaitForProducerEnabled();
    761   // Wait for the producer to start, and then write out 11 packets, before the
    762   // trace actually starts (the trigger is seen).
    763   auto on_data_written = task_runner.CreateCheckpoint("data_written_1");
    764   fake_producer->ProduceEventBatch(helper.WrapTask(on_data_written));
    765   task_runner.RunUntilCheckpoint("data_written_1");
    766 
    767   EXPECT_EQ(0,
    768             ExecTrigger({"trigger_name_2", "trigger_name", "trigger_name_3"}))
    769       << "stderr: " << stderr_;
    770 
    771   background_trace.join();
    772 
    773   std::string trace_str;
    774   base::ReadFile(path, &trace_str);
    775   protos::Trace trace;
    776   ASSERT_TRUE(trace.ParseFromString(trace_str));
    777   EXPECT_EQ(kPreamblePackets + kMessageCount, trace.packet_size());
    778   bool seen_first_trigger = false;
    779   for (const auto& packet : trace.packet()) {
    780     if (packet.data_case() == protos::TracePacket::kTraceConfig) {
    781       // Ensure the trace config properly includes the trigger mode we set.
    782       EXPECT_EQ(protos::TraceConfig::TriggerConfig::STOP_TRACING,
    783                 packet.trace_config().trigger_config().trigger_mode());
    784     } else if (packet.data_case() == protos::TracePacket::kTrigger) {
    785       // validate that the triggers are properly added to the trace.
    786       if (!seen_first_trigger) {
    787         EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
    788         seen_first_trigger = true;
    789       } else {
    790         EXPECT_EQ("trigger_name_3", packet.trigger().trigger_name());
    791       }
    792     } else if (packet.data_case() == protos::TracePacket::kForTesting) {
    793       // Make sure that the data size is correctly set based on what we
    794       // requested.
    795       EXPECT_EQ(kMessageSize, packet.for_testing().str().size());
    796     }
    797   }
    798 }
    799 
    800 // Dropbox on the commandline client only works on android builds. So disable
    801 // this test on all other builds.
    802 #if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
    803 TEST_F(PerfettoCmdlineTest, NoSanitizers(NoDataNoFileWithoutTrigger)) {
    804 #else
    805 TEST_F(PerfettoCmdlineTest, DISABLED_NoDataNoFileWithoutTrigger) {
    806 #endif
    807   // See |message_count| and |message_size| in the TraceConfig above.
    808   constexpr size_t kMessageCount = 11;
    809   constexpr size_t kMessageSize = 32;
    810   protos::TraceConfig trace_config;
    811   trace_config.add_buffers()->set_size_kb(1024);
    812   trace_config.set_allow_user_build_tracing(true);
    813   auto* ds_config = trace_config.add_data_sources()->mutable_config();
    814   ds_config->set_name("android.perfetto.FakeProducer");
    815   ds_config->mutable_for_testing()->set_message_count(kMessageCount);
    816   ds_config->mutable_for_testing()->set_message_size(kMessageSize);
    817   auto* trigger_cfg = trace_config.mutable_trigger_config();
    818   trigger_cfg->set_trigger_mode(
    819       protos::TraceConfig::TriggerConfig::STOP_TRACING);
    820   trigger_cfg->set_trigger_timeout_ms(1000);
    821   auto* trigger = trigger_cfg->add_triggers();
    822   trigger->set_name("trigger_name");
    823   // |stop_delay_ms| must be long enough that we can write the packets in
    824   // before the trace finishes. This has to be long enough for the slowest
    825   // emulator. But as short as possible to prevent the test running a long
    826   // time.
    827   trigger->set_stop_delay_ms(500);
    828   trigger = trigger_cfg->add_triggers();
    829 
    830   // Enable tracing and detach as soon as it gets started.
    831   base::TestTaskRunner task_runner;
    832   TestHelper helper(&task_runner);
    833   helper.StartServiceIfRequired();
    834   auto* fake_producer = helper.ConnectFakeProducer();
    835   EXPECT_TRUE(fake_producer);
    836 
    837   std::thread background_trace([&trace_config, this]() {
    838     EXPECT_EQ(0, ExecPerfetto(
    839                      {
    840                          "--dropbox", "TAG", "--no-guardrails", "-c", "-",
    841                      },
    842                      trace_config.SerializeAsString()));
    843   });
    844   background_trace.join();
    845 
    846   EXPECT_THAT(stderr_,
    847               ::testing::HasSubstr("Skipping write to dropbox. Empty trace."));
    848 }
    849 
    850 TEST_F(PerfettoCmdlineTest, NoSanitizers(StopTracingTriggerFromConfig)) {
    851   // See |message_count| and |message_size| in the TraceConfig above.
    852   constexpr size_t kMessageCount = 11;
    853   constexpr size_t kMessageSize = 32;
    854   protos::TraceConfig trace_config;
    855   trace_config.add_buffers()->set_size_kb(1024);
    856   auto* ds_config = trace_config.add_data_sources()->mutable_config();
    857   ds_config->set_name("android.perfetto.FakeProducer");
    858   ds_config->mutable_for_testing()->set_message_count(kMessageCount);
    859   ds_config->mutable_for_testing()->set_message_size(kMessageSize);
    860   auto* trigger_cfg = trace_config.mutable_trigger_config();
    861   trigger_cfg->set_trigger_mode(
    862       protos::TraceConfig::TriggerConfig::STOP_TRACING);
    863   trigger_cfg->set_trigger_timeout_ms(15000);
    864   auto* trigger = trigger_cfg->add_triggers();
    865   trigger->set_name("trigger_name");
    866   // |stop_delay_ms| must be long enough that we can write the packets in
    867   // before the trace finishes. This has to be long enough for the slowest
    868   // emulator. But as short as possible to prevent the test running a long
    869   // time.
    870   trigger->set_stop_delay_ms(500);
    871   trigger = trigger_cfg->add_triggers();
    872   trigger->set_name("trigger_name_3");
    873   trigger->set_stop_delay_ms(60000);
    874 
    875   // We have 5 normal preample packets (trace config, clock, system info, sync
    876   // marker, stats) and then since this is a trace with a trigger config we have
    877   // an additional ReceivedTriggers packet.
    878   base::TestTaskRunner task_runner;
    879 
    880   // Enable tracing and detach as soon as it gets started.
    881   TestHelper helper(&task_runner);
    882   helper.StartServiceIfRequired();
    883   auto* fake_producer = helper.ConnectFakeProducer();
    884   EXPECT_TRUE(fake_producer);
    885 
    886   const std::string path = RandomTraceFileName();
    887   std::thread background_trace([&path, &trace_config, this]() {
    888     EXPECT_EQ(0, ExecPerfetto(
    889                      {
    890                          "-o", path, "-c", "-",
    891                      },
    892                      trace_config.SerializeAsString()));
    893   });
    894 
    895   helper.WaitForProducerEnabled();
    896   // Wait for the producer to start, and then write out 11 packets, before the
    897   // trace actually starts (the trigger is seen).
    898   auto on_data_written = task_runner.CreateCheckpoint("data_written_1");
    899   fake_producer->ProduceEventBatch(helper.WrapTask(on_data_written));
    900   task_runner.RunUntilCheckpoint("data_written_1");
    901 
    902   std::string triggers = R"(
    903     activate_triggers: "trigger_name_2"
    904     activate_triggers: "trigger_name"
    905     activate_triggers: "trigger_name_3"
    906   )";
    907 
    908   EXPECT_EQ(0, ExecPerfetto(
    909                    {
    910                        "-o", path, "-c", "-", "--txt",
    911                    },
    912                    triggers))
    913       << "stderr: " << stderr_;
    914 
    915   background_trace.join();
    916 
    917   std::string trace_str;
    918   base::ReadFile(path, &trace_str);
    919   protos::Trace trace;
    920   ASSERT_TRUE(trace.ParseFromString(trace_str));
    921   EXPECT_LT(kMessageCount, trace.packet_size());
    922   bool seen_first_trigger = false;
    923   for (const auto& packet : trace.packet()) {
    924     if (packet.data_case() == protos::TracePacket::kTraceConfig) {
    925       // Ensure the trace config properly includes the trigger mode we set.
    926       EXPECT_EQ(protos::TraceConfig::TriggerConfig::STOP_TRACING,
    927                 packet.trace_config().trigger_config().trigger_mode());
    928     } else if (packet.data_case() == protos::TracePacket::kTrigger) {
    929       // validate that the triggers are properly added to the trace.
    930       if (!seen_first_trigger) {
    931         EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
    932         seen_first_trigger = true;
    933       } else {
    934         EXPECT_EQ("trigger_name_3", packet.trigger().trigger_name());
    935       }
    936     } else if (packet.data_case() == protos::TracePacket::kForTesting) {
    937       // Make sure that the data size is correctly set based on what we
    938       // requested.
    939       EXPECT_EQ(kMessageSize, packet.for_testing().str().size());
    940     }
    941   }
    942 }
    943 
    944 TEST_F(PerfettoCmdlineTest, NoSanitizers(TriggerFromConfigStopsFileOpening)) {
    945   // See |message_count| and |message_size| in the TraceConfig above.
    946   constexpr size_t kMessageCount = 11;
    947   constexpr size_t kMessageSize = 32;
    948   protos::TraceConfig trace_config;
    949   trace_config.add_buffers()->set_size_kb(1024);
    950   auto* ds_config = trace_config.add_data_sources()->mutable_config();
    951   ds_config->set_name("android.perfetto.FakeProducer");
    952   ds_config->mutable_for_testing()->set_message_count(kMessageCount);
    953   ds_config->mutable_for_testing()->set_message_size(kMessageSize);
    954   auto* trigger_cfg = trace_config.mutable_trigger_config();
    955   trigger_cfg->set_trigger_mode(
    956       protos::TraceConfig::TriggerConfig::STOP_TRACING);
    957   trigger_cfg->set_trigger_timeout_ms(15000);
    958   auto* trigger = trigger_cfg->add_triggers();
    959   trigger->set_name("trigger_name");
    960   // |stop_delay_ms| must be long enough that we can write the packets in
    961   // before the trace finishes. This has to be long enough for the slowest
    962   // emulator. But as short as possible to prevent the test running a long
    963   // time.
    964   trigger->set_stop_delay_ms(500);
    965   trigger = trigger_cfg->add_triggers();
    966   trigger->set_name("trigger_name_3");
    967   trigger->set_stop_delay_ms(60000);
    968 
    969   // We have 5 normal preample packets (trace config, clock, system info, sync
    970   // marker, stats) and then since this is a trace with a trigger config we have
    971   // an additional ReceivedTriggers packet.
    972   base::TestTaskRunner task_runner;
    973 
    974   // Enable tracing and detach as soon as it gets started.
    975   TestHelper helper(&task_runner);
    976   helper.StartServiceIfRequired();
    977   auto* fake_producer = helper.ConnectFakeProducer();
    978   EXPECT_TRUE(fake_producer);
    979 
    980   const std::string path = RandomTraceFileName();
    981 
    982   std::string trace_str;
    983   EXPECT_FALSE(base::ReadFile(path, &trace_str));
    984 
    985   std::string triggers = R"(
    986     activate_triggers: "trigger_name_2"
    987     activate_triggers: "trigger_name"
    988     activate_triggers: "trigger_name_3"
    989   )";
    990 
    991   EXPECT_EQ(0, ExecPerfetto(
    992                    {
    993                        "-o", path, "-c", "-", "--txt",
    994                    },
    995                    triggers))
    996       << "stderr: " << stderr_;
    997 
    998   EXPECT_FALSE(base::ReadFile(path, &trace_str));
    999 }
   1000 
   1001 }  // namespace perfetto
   1002