diff --git a/Android.bp b/Android.bp
index 1fad0af..19a10f2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1111,7 +1111,7 @@
         ":perfetto_src_tracing_ipc_default_socket",
         ":perfetto_src_tracing_ipc_producer_producer",
         ":perfetto_src_tracing_ipc_service_service",
-        ":perfetto_test_end_to_end_integrationtests",
+        ":perfetto_test_integrationtests",
         ":perfetto_test_test_helper",
         "test/cts/device_feature_test_cts.cc",
         "test/cts/end_to_end_integrationtest_cts.cc",
@@ -1814,7 +1814,7 @@
         ":perfetto_src_tracing_system_backend",
         ":perfetto_src_tracing_test_api_test_support",
         ":perfetto_src_tracing_test_client_api_integrationtests",
-        ":perfetto_test_end_to_end_integrationtests",
+        ":perfetto_test_integrationtests",
         ":perfetto_test_test_helper",
     ],
     shared_libs: [
@@ -9072,11 +9072,14 @@
     ],
 }
 
-// GN: //test:end_to_end_integrationtests
+// GN: //test:integrationtests
 filegroup {
-    name: "perfetto_test_end_to_end_integrationtests",
+    name: "perfetto_test_integrationtests",
     srcs: [
-        "test/end_to_end_integrationtest.cc",
+        "test/android_integrationtest.cc",
+        "test/cmdline_integrationtest.cc",
+        "test/ftrace_integrationtest.cc",
+        "test/traced_integrationtest.cc",
     ],
 }
 
diff --git a/gn/perfetto_integrationtests.gni b/gn/perfetto_integrationtests.gni
index d1005fd..7527a55 100644
--- a/gn/perfetto_integrationtests.gni
+++ b/gn/perfetto_integrationtests.gni
@@ -24,7 +24,7 @@
   # enable_perfetto_traced_probes implies enable_perfetto_platform_services.
   perfetto_integrationtests_targets += [
     "src/traced/probes/ftrace:integrationtests",
-    "test:end_to_end_integrationtests",
+    "test:integrationtests",
   ]
 }
 
diff --git a/src/profiling/memory/BUILD.gn b/src/profiling/memory/BUILD.gn
index 804f70e..5400d07 100644
--- a/src/profiling/memory/BUILD.gn
+++ b/src/profiling/memory/BUILD.gn
@@ -365,9 +365,6 @@
   } else {
     deps += [ ":heapprofd_standalone_client" ]
   }
-  if (start_daemons_for_testing) {
-    defines = [ "PERFETTO_START_DAEMONS_FOR_TESTING" ]
-  }
 }
 
 perfetto_fuzzer_test("unwinding_fuzzer") {
diff --git a/test/BUILD.gn b/test/BUILD.gn
index 01ae3c6..768b8ad 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -17,7 +17,7 @@
 import("../gn/perfetto.gni")
 
 if (!build_with_chromium && enable_perfetto_integration_tests) {
-  source_set("end_to_end_integrationtests") {
+  source_set("integrationtests") {
     testonly = true
     deps = [
       ":test_helper",
@@ -54,10 +54,13 @@
       "../src/perfetto_cmd:trigger_perfetto",
     ]
 
-    sources = [ "end_to_end_integrationtest.cc" ]
+    sources = [
+      "android_integrationtest.cc",
+      "cmdline_integrationtest.cc",
+      "ftrace_integrationtest.cc",
+      "traced_integrationtest.cc",
+    ]
     if (start_daemons_for_testing) {
-      cflags = [ "-DPERFETTO_START_DAEMONS_FOR_TESTING" ]
-
       # In CTS mode we use /syste/bin/perfetto for the cmdline tests and the
       # perfetto_cmd is not required. Outside of CTS mode, instead, we need to
       # build the cmdline code as part of the test executable.
@@ -138,9 +141,6 @@
         "android_test_utils.h",
       ]
     }
-    if (start_daemons_for_testing) {
-      cflags = [ "-DPERFETTO_START_DAEMONS_FOR_TESTING" ]
-    }
     if (!build_with_chromium && enable_perfetto_traced_probes) {
       deps += [
         "../include/perfetto/ext/traced",
@@ -165,9 +165,6 @@
       "../src/base:test_support",
     ]
     sources = [ "end_to_end_benchmark.cc" ]
-    if (start_daemons_for_testing) {
-      cflags = [ "-DPERFETTO_START_DAEMONS_FOR_TESTING" ]
-    }
   }
 
   source_set("benchmark_main") {
diff --git a/test/android_integrationtest.cc b/test/android_integrationtest.cc
new file mode 100644
index 0000000..19e894d
--- /dev/null
+++ b/test/android_integrationtest.cc
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/pipe.h"
+#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/utils.h"
+#include "perfetto/ext/tracing/core/commit_data_request.h"
+#include "perfetto/ext/tracing/core/trace_packet.h"
+#include "perfetto/ext/tracing/core/tracing_service.h"
+#include "perfetto/protozero/scattered_heap_buffer.h"
+#include "src/base/test/test_task_runner.h"
+#include "src/base/test/utils.h"
+#include "test/gtest_and_gmock.h"
+#include "test/test_helper.h"
+
+#include "protos/perfetto/config/power/android_power_config.pbzero.h"
+#include "protos/perfetto/config/test_config.gen.h"
+#include "protos/perfetto/config/trace_config.gen.h"
+#include "protos/perfetto/trace/ftrace/ftrace.gen.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event.gen.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.gen.h"
+#include "protos/perfetto/trace/ftrace/ftrace_stats.gen.h"
+#include "protos/perfetto/trace/perfetto/tracing_service_event.gen.h"
+#include "protos/perfetto/trace/power/battery_counters.gen.h"
+#include "protos/perfetto/trace/test_event.gen.h"
+#include "protos/perfetto/trace/trace.gen.h"
+#include "protos/perfetto/trace/trace_packet.gen.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+#include "protos/perfetto/trace/trigger.gen.h"
+
+#include "protos/perfetto/common/sys_stats_counters.gen.h"
+#include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
+#include "protos/perfetto/trace/sys_stats/sys_stats.gen.h"
+
+namespace perfetto {
+
+namespace {
+
+using ::testing::ContainsRegex;
+using ::testing::Each;
+using ::testing::ElementsAreArray;
+using ::testing::HasSubstr;
+using ::testing::Property;
+using ::testing::SizeIs;
+
+// For the SaveForBugreport* tests.
+void SetTraceConfigForBugreportTest(TraceConfig* trace_config) {
+  trace_config->add_buffers()->set_size_kb(4096);
+  trace_config->set_duration_ms(60000);  // Will never hit this.
+  trace_config->set_bugreport_score(10);
+  auto* ds_config = trace_config->add_data_sources()->mutable_config();
+  ds_config->set_name("android.perfetto.FakeProducer");
+  ds_config->mutable_for_testing()->set_message_count(3);
+  ds_config->mutable_for_testing()->set_message_size(10);
+  ds_config->mutable_for_testing()->set_send_batch_on_register(true);
+}
+
+// For the SaveForBugreport* tests.
+static void VerifyBugreportTraceContents() {
+  // Read the trace written in the fixed location (/data/misc/perfetto-traces/
+  // on Android, /tmp/ on Linux/Mac) and make sure it has the right contents.
+  std::string trace_str;
+  base::ReadFile(GetBugreportPath(), &trace_str);
+  ASSERT_FALSE(trace_str.empty());
+  protos::gen::Trace trace;
+  ASSERT_TRUE(trace.ParseFromString(trace_str));
+  int test_packets = 0;
+  for (const auto& p : trace.packet())
+    test_packets += p.has_for_testing() ? 1 : 0;
+  ASSERT_EQ(test_packets, 3);
+}
+
+}  // namespace
+
+TEST(PerfettoAndroidIntegrationTest, TestKmemActivity) {
+  using C = protos::gen::VmstatCounters;
+
+  base::TestTaskRunner task_runner;
+
+  TestHelper helper(&task_runner);
+
+  helper.StartServiceIfRequired();
+
+#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
+  ProbesProducerThread probes(GetTestProducerSockName());
+  probes.Connect();
+#endif
+
+  auto* producer = helper.ConnectFakeProducer();
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+  helper.WaitForDataSourceConnected("linux.ftrace");
+
+  TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(1024);
+  trace_config.set_unique_session_name("kmem_activity_test");
+
+  auto* ftrace_ds_config = trace_config.add_data_sources()->mutable_config();
+  ftrace_ds_config->set_name("linux.ftrace");
+  protos::gen::FtraceConfig ftrace_config = CreateFtraceConfig({
+      "vmscan/mm_vmscan_kswapd_wake",
+      "vmscan/mm_vmscan_kswapd_sleep",
+      "vmscan/mm_vmscan_direct_reclaim_begin",
+      "vmscan/mm_vmscan_direct_reclaim_end",
+      "compaction/mm_compaction_begin",
+      "compaction/mm_compaction_end",
+  });
+  ftrace_ds_config->set_ftrace_config_raw(ftrace_config.SerializeAsString());
+
+  auto* sys_stats_ds_config = trace_config.add_data_sources()->mutable_config();
+  sys_stats_ds_config->set_name("linux.sys_stats");
+  protos::gen::SysStatsConfig sys_stats_config;
+  sys_stats_config.set_vmstat_period_ms(50);
+  std::vector<C> vmstat_counters = {
+      C::VMSTAT_NR_FREE_PAGES,
+      C::VMSTAT_NR_SLAB_RECLAIMABLE,
+      C::VMSTAT_NR_SLAB_UNRECLAIMABLE,
+      C::VMSTAT_NR_ACTIVE_FILE,
+      C::VMSTAT_NR_INACTIVE_FILE,
+      C::VMSTAT_NR_ACTIVE_ANON,
+      C::VMSTAT_NR_INACTIVE_ANON,
+      C::VMSTAT_WORKINGSET_REFAULT,
+      C::VMSTAT_WORKINGSET_ACTIVATE,
+      C::VMSTAT_NR_FILE_PAGES,
+      C::VMSTAT_PGPGIN,
+      C::VMSTAT_PGPGOUT,
+      C::VMSTAT_PSWPIN,
+      C::VMSTAT_PSWPOUT,
+      C::VMSTAT_PGSTEAL_KSWAPD_DMA,
+      C::VMSTAT_PGSTEAL_KSWAPD_NORMAL,
+      C::VMSTAT_PGSTEAL_KSWAPD_MOVABLE,
+      C::VMSTAT_PGSTEAL_DIRECT_DMA,
+      C::VMSTAT_PGSTEAL_DIRECT_NORMAL,
+      C::VMSTAT_PGSTEAL_DIRECT_MOVABLE,
+      C::VMSTAT_PGSCAN_KSWAPD_DMA,
+      C::VMSTAT_PGSCAN_KSWAPD_NORMAL,
+      C::VMSTAT_PGSCAN_KSWAPD_MOVABLE,
+      C::VMSTAT_PGSCAN_DIRECT_DMA,
+      C::VMSTAT_PGSCAN_DIRECT_NORMAL,
+      C::VMSTAT_PGSCAN_DIRECT_MOVABLE,
+      C::VMSTAT_COMPACT_MIGRATE_SCANNED,
+      C::VMSTAT_COMPACT_FREE_SCANNED,
+  };
+  for (const auto& counter : vmstat_counters) {
+    sys_stats_config.add_vmstat_counters(counter);
+  }
+  sys_stats_ds_config->set_sys_stats_config_raw(
+      sys_stats_config.SerializeAsString());
+
+  auto* trigger_cfg = trace_config.mutable_trigger_config();
+  trigger_cfg->set_trigger_mode(
+      protos::gen::TraceConfig::TriggerConfig::START_TRACING);
+  trigger_cfg->set_trigger_timeout_ms(15000);
+  auto* trigger = trigger_cfg->add_triggers();
+  trigger->set_name("kmem_activity");
+  // |stop_delay_ms| must be long enough that we can write the packets in
+  // before the trace finishes.
+  trigger->set_stop_delay_ms(1000);
+
+  helper.StartTracing(trace_config);
+
+  // Linearize with StartTracing. This ensures that the service has seen the
+  // StartTracing IPC and has armed the triggers.
+  helper.FlushAndWait(kDefaultTestTimeoutMs);
+
+  // Generating synthetic memory pressure to trigger kmem activity is
+  // inherently flaky on different devices. The same goes for writing
+  // /proc/sys/vm/compact_memory to trigger compaction, since compaction is
+  // only started if needed (even if explicitly triggered from proc).
+  // Trigger kmem activity using perfetto trigger.
+  producer->ActivateTrigger("kmem_activity");
+
+  helper.WaitForTracingDisabled();
+
+  helper.ReadData();
+  helper.WaitForReadData();
+
+  const auto& packets = helper.trace();
+  ASSERT_GT(packets.size(), 0u);
+
+  bool sys_stats_captured = false;
+  for (const auto& packet : packets) {
+    for (int ev = 0; ev < packet.ftrace_events().event_size(); ev++) {
+      auto ftrace_event =
+          packet.ftrace_events().event()[static_cast<size_t>(ev)];
+      ASSERT_TRUE(ftrace_event.has_mm_vmscan_kswapd_wake() ||
+                  ftrace_event.has_mm_vmscan_kswapd_sleep() ||
+                  ftrace_event.has_mm_vmscan_direct_reclaim_begin() ||
+                  ftrace_event.has_mm_vmscan_direct_reclaim_end() ||
+                  ftrace_event.has_mm_compaction_begin() ||
+                  ftrace_event.has_mm_compaction_end());
+    }
+
+    if (packet.has_sys_stats()) {
+      sys_stats_captured = true;
+      const auto& sys_stats = packet.sys_stats();
+      const auto& vmstat = sys_stats.vmstat();
+      ASSERT_GT(vmstat.size(), 0u);
+      for (const auto& vmstat_value : vmstat) {
+        ASSERT_NE(std::find(vmstat_counters.begin(), vmstat_counters.end(),
+                            vmstat_value.key()),
+                  vmstat_counters.end());
+      }
+    }
+  }
+
+  // Don't explicitly check that ftrace events were captured, since this test
+  // doesn't rely on memory pressure.
+  ASSERT_TRUE(sys_stats_captured);
+}
+
+TEST(PerfettoAndroidIntegrationTest, TestBatteryTracing) {
+  base::TestTaskRunner task_runner;
+
+  TestHelper helper(&task_runner);
+  helper.StartServiceIfRequired();
+
+#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
+  ProbesProducerThread probes(GetTestProducerSockName());
+  probes.Connect();
+#endif
+
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+
+  TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(128);
+  trace_config.set_duration_ms(3000);
+
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("android.power");
+  ds_config->set_target_buffer(0);
+
+  using protos::pbzero::AndroidPowerConfig;
+  protozero::HeapBuffered<AndroidPowerConfig> power_config;
+  power_config->set_battery_poll_ms(250);
+  power_config->add_battery_counters(
+      AndroidPowerConfig::BATTERY_COUNTER_CHARGE);
+  power_config->add_battery_counters(
+      AndroidPowerConfig::BATTERY_COUNTER_CAPACITY_PERCENT);
+  ds_config->set_android_power_config_raw(power_config.SerializeAsString());
+
+  helper.StartTracing(trace_config);
+  helper.WaitForTracingDisabled();
+
+  helper.ReadData();
+  helper.WaitForReadData();
+
+  const auto& packets = helper.trace();
+  ASSERT_GT(packets.size(), 0u);
+
+  bool has_battery_packet = false;
+  for (const auto& packet : packets) {
+    if (!packet.has_battery())
+      continue;
+    has_battery_packet = true;
+    // Unfortunately we cannot make any assertions on the charge counter.
+    // On some devices it can reach negative values (b/64685329).
+    EXPECT_GE(packet.battery().capacity_percent(), 0.f);
+    EXPECT_LE(packet.battery().capacity_percent(), 100.f);
+  }
+
+  ASSERT_TRUE(has_battery_packet);
+}
+
+TEST(PerfettoAndroidIntegrationTest, SaveForBugreport) {
+  base::TestTaskRunner task_runner;
+
+  TestHelper helper(&task_runner);
+  helper.StartServiceIfRequired();
+  helper.ConnectFakeProducer();
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+
+  TraceConfig trace_config;
+  SetTraceConfigForBugreportTest(&trace_config);
+
+  helper.StartTracing(trace_config);
+  helper.WaitForProducerEnabled();
+
+  EXPECT_TRUE(helper.SaveTraceForBugreportAndWait());
+  helper.WaitForTracingDisabled();
+
+  VerifyBugreportTraceContents();
+
+  // Now read the trace returned to the consumer via ReadBuffers. This should
+  // be always empty because --save-for-bugreport takes it over and makes the
+  // buffers unreadable by the consumer (by virtue of force-setting
+  // write_into_file, which is incompatible with ReadBuffers()). The only
+  // content should be the |seized_for_bugreport| flag.
+  helper.ReadData();
+  helper.WaitForReadData();
+  const auto& packets = helper.full_trace();
+  ASSERT_EQ(packets.size(), 1u);
+  for (const auto& p : packets) {
+    ASSERT_TRUE(p.has_service_event());
+    ASSERT_TRUE(p.service_event().seized_for_bugreport());
+  }
+}
+
+// Tests that the SaveForBugreport logic works also for traces with
+// write_into_file = true (with a passed file descriptor).
+TEST(PerfettoAndroidIntegrationTest, SaveForBugreport_WriteIntoFile) {
+  base::TestTaskRunner task_runner;
+
+  TestHelper helper(&task_runner);
+  helper.StartServiceIfRequired();
+  helper.ConnectFakeProducer();
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+
+  TraceConfig trace_config;
+  SetTraceConfigForBugreportTest(&trace_config);
+  trace_config.set_file_write_period_ms(60000);  // Will never hit this.
+  trace_config.set_write_into_file(true);
+
+  auto pipe_pair = base::Pipe::Create();
+  helper.StartTracing(trace_config, std::move(pipe_pair.wr));
+  helper.WaitForProducerEnabled();
+
+  EXPECT_TRUE(helper.SaveTraceForBugreportAndWait());
+  helper.WaitForTracingDisabled();
+
+  VerifyBugreportTraceContents();
+
+  // Now read the original file descriptor passed in.
+  std::string trace_bytes;
+  ASSERT_TRUE(base::ReadPlatformHandle(*pipe_pair.rd, &trace_bytes));
+  protos::gen::Trace trace;
+  ASSERT_TRUE(trace.ParseFromString(trace_bytes));
+  ASSERT_EQ(trace.packet().size(), 1u);
+  for (const auto& p : trace.packet()) {
+    ASSERT_TRUE(p.has_service_event());
+    ASSERT_TRUE(p.service_event().seized_for_bugreport());
+  }
+}
+
+// Tests that SaveTraceForBugreport() works also if the trace has triggers
+// defined and those triggers have not been hit. This is a regression test for
+// b/188008375 .
+#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+// Disabled due to b/191940560
+#define MAYBE_SaveForBugreport_Triggers DISABLED_SaveForBugreport_Triggers
+#else
+#define MAYBE_SaveForBugreport_Triggers SaveForBugreport_Triggers
+#endif
+TEST(PerfettoAndroidIntegrationTest, MAYBE_SaveForBugreport_Triggers) {
+  base::TestTaskRunner task_runner;
+
+  TestHelper helper(&task_runner);
+  helper.StartServiceIfRequired();
+  helper.ConnectFakeProducer();
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+
+  TraceConfig trace_config;
+  SetTraceConfigForBugreportTest(&trace_config);
+  trace_config.set_duration_ms(0);  // set_trigger_timeout_ms is used instead.
+  auto* trigger_config = trace_config.mutable_trigger_config();
+  trigger_config->set_trigger_timeout_ms(8.64e+7);
+  trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
+  auto* trigger = trigger_config->add_triggers();
+  trigger->set_name("trigger_name");
+  trigger->set_stop_delay_ms(1);
+
+  helper.StartTracing(trace_config);
+  helper.WaitForProducerEnabled();
+
+  EXPECT_TRUE(helper.SaveTraceForBugreportAndWait());
+  helper.WaitForTracingDisabled();
+
+  VerifyBugreportTraceContents();
+
+  // Now read the original trace.
+  helper.ReadData();
+  helper.WaitForReadData();
+  const auto& packets = helper.full_trace();
+  ASSERT_EQ(packets.size(), 1u);
+  for (const auto& p : packets) {
+    ASSERT_TRUE(p.has_service_event());
+    ASSERT_TRUE(p.service_event().seized_for_bugreport());
+  }
+}
+
+}  // namespace perfetto
+
+#endif  // PERFETTO_OS_ANDROID
diff --git a/test/cmdline_integrationtest.cc b/test/cmdline_integrationtest.cc
new file mode 100644
index 0000000..0fc0520
--- /dev/null
+++ b/test/cmdline_integrationtest.cc
@@ -0,0 +1,862 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <functional>
+#include <initializer_list>
+#include <thread>
+
+#include "perfetto/base/build_config.h"
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/pipe.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/subprocess.h"
+#include "perfetto/ext/base/utils.h"
+#include "perfetto/ext/traced/traced.h"
+#include "perfetto/protozero/scattered_heap_buffer.h"
+#include "src/base/test/test_task_runner.h"
+#include "src/base/test/utils.h"
+#include "test/gtest_and_gmock.h"
+#include "test/test_helper.h"
+
+#include "protos/perfetto/config/test_config.gen.h"
+#include "protos/perfetto/config/trace_config.gen.h"
+#include "protos/perfetto/trace/test_event.gen.h"
+#include "protos/perfetto/trace/trace.gen.h"
+#include "protos/perfetto/trace/trace_packet.gen.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+#include "protos/perfetto/trace/trigger.gen.h"
+
+namespace perfetto {
+
+namespace {
+
+using ::testing::ContainsRegex;
+using ::testing::Each;
+using ::testing::ElementsAreArray;
+using ::testing::HasSubstr;
+using ::testing::Property;
+using ::testing::SizeIs;
+
+std::string RandomTraceFileName() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  constexpr char kSysTmpPath[] = "/data/misc/perfetto-traces";
+#else
+  constexpr char kSysTmpPath[] = "/tmp";
+#endif
+  static int suffix = 0;
+
+  std::string path;
+  path.assign(kSysTmpPath);
+  path.append("/trace-");
+  path.append(std::to_string(base::GetBootTimeNs().count()));
+  path.append("-");
+  path.append(std::to_string(suffix++));
+  return path;
+}
+
+// This class is a reference to a child process that has in essence been execv
+// to the requested binary. The process will start and then wait for Run()
+// before proceeding. We use this to fork new processes before starting any
+// additional threads in the parent process (otherwise you would risk
+// deadlocks), but pause the forked processes until remaining setup (including
+// any necessary threads) in the parent process is complete.
+class Exec {
+ public:
+  // Starts the forked process that was created. If not null then |stderr_out|
+  // will contain the stderr of the process.
+  int Run(std::string* stderr_out = nullptr) {
+    // We can't be the child process.
+    PERFETTO_CHECK(getpid() != subprocess_.pid());
+    // Will cause the entrypoint to continue.
+    PERFETTO_CHECK(write(*sync_pipe_.wr, "1", 1) == 1);
+    sync_pipe_.wr.reset();
+    subprocess_.Wait();
+
+    if (stderr_out) {
+      *stderr_out = std::move(subprocess_.output());
+    } else {
+      PERFETTO_LOG("Child proc %d exited with stderr: \"%s\"",
+                   subprocess_.pid(), subprocess_.output().c_str());
+    }
+    return subprocess_.returncode();
+  }
+
+  Exec(const std::string& argv0,
+       std::initializer_list<std::string> args,
+       std::string input = "") {
+    subprocess_.args.stderr_mode = base::Subprocess::kBuffer;
+    subprocess_.args.stdout_mode = base::Subprocess::kDevNull;
+    subprocess_.args.input = input;
+
+#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
+    constexpr bool kUseSystemBinaries = false;
+#else
+    constexpr bool kUseSystemBinaries = true;
+#endif
+
+    std::vector<std::string>& cmd = subprocess_.args.exec_cmd;
+    if (kUseSystemBinaries) {
+      PERFETTO_CHECK(TestHelper::kDefaultMode ==
+                     TestHelper::Mode::kUseSystemService);
+      cmd.push_back("/system/bin/" + argv0);
+      cmd.insert(cmd.end(), args.begin(), args.end());
+    } else {
+      PERFETTO_CHECK(TestHelper::kDefaultMode ==
+                     TestHelper::Mode::kStartDaemons);
+      subprocess_.args.env.push_back(
+          std::string("PERFETTO_PRODUCER_SOCK_NAME=") +
+          TestHelper::GetDefaultModeProducerSocketName());
+      subprocess_.args.env.push_back(
+          std::string("PERFETTO_CONSUMER_SOCK_NAME=") +
+          TestHelper::GetDefaultModeConsumerSocketName());
+      cmd.push_back(base::GetCurExecutableDir() + "/" + argv0);
+      cmd.insert(cmd.end(), args.begin(), args.end());
+    }
+
+    if (!base::FileExists(cmd[0])) {
+      PERFETTO_FATAL(
+          "Cannot find %s. Make sure that the target has been built and, on "
+          "Android, pushed to the device.",
+          cmd[0].c_str());
+    }
+
+    // This pipe blocks the execution of the child process until the main test
+    // process calls Run(). There are two conflicting problems here:
+    // 1) We can't fork() subprocesses too late, because the test spawns threads
+    //    for hosting the service. fork+threads = bad (see aosp/1089744).
+    // 2) We can't run the subprocess too early, because we need to wait that
+    //    the service threads are ready before trying to connect from the child
+    //    process.
+    sync_pipe_ = base::Pipe::Create();
+    int sync_pipe_rd = *sync_pipe_.rd;
+    subprocess_.args.preserve_fds.push_back(sync_pipe_rd);
+
+    // This lambda will be called on the forked child process after having
+    // setup pipe redirection and closed all FDs, right before the exec().
+    // The Subprocesss harness will take care of closing also |sync_pipe_.wr|.
+    subprocess_.args.posix_entrypoint_for_testing = [sync_pipe_rd] {
+      // Don't add any logging here, all file descriptors are closed and trying
+      // to log will likely cause undefined behaviors.
+      char ignored = 0;
+      PERFETTO_CHECK(PERFETTO_EINTR(read(sync_pipe_rd, &ignored, 1)) > 0);
+      PERFETTO_CHECK(close(sync_pipe_rd) == 0 || errno == EINTR);
+    };
+
+    subprocess_.Start();
+    sync_pipe_.rd.reset();
+  }
+
+ private:
+  base::Subprocess subprocess_;
+  base::Pipe sync_pipe_;
+};
+
+class PerfettoCmdlineTest : public ::testing::Test {
+ public:
+  void SetUp() override {
+#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
+    defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER)
+    // Disable cmdline tests on sanitizets because they use fork() and that
+    // messes up leak / races detections, which has been fixed only recently
+    // (see https://github.com/google/sanitizers/issues/836 ).
+    PERFETTO_LOG("Skipping cmdline integration tests on sanitizers");
+    GTEST_SKIP();
+#endif
+  }
+
+  void TearDown() override {}
+
+  void StartServiceIfRequiredNoNewExecsAfterThis() {
+    exec_allowed_ = false;
+    test_helper_.StartServiceIfRequired();
+  }
+
+  FakeProducer* ConnectFakeProducer() {
+    return test_helper_.ConnectFakeProducer();
+  }
+
+  std::function<void()> WrapTask(const std::function<void()>& function) {
+    return test_helper_.WrapTask(function);
+  }
+
+  void WaitForProducerSetup() { test_helper_.WaitForProducerSetup(); }
+
+  void WaitForProducerEnabled() { test_helper_.WaitForProducerEnabled(); }
+
+  // Creates a process that represents the perfetto binary that will
+  // start when Run() is called. |args| will be passed as part of
+  // the command line and |std_in| will be piped into std::cin.
+  Exec ExecPerfetto(std::initializer_list<std::string> args,
+                    std::string std_in = "") {
+    // You can not fork after you've started the service due to risk of
+    // deadlocks.
+    PERFETTO_CHECK(exec_allowed_);
+    return Exec("perfetto", std::move(args), std::move(std_in));
+  }
+
+  // Creates a process that represents the trigger_perfetto binary that will
+  // start when Run() is called. |args| will be passed as part of
+  // the command line and |std_in| will be piped into std::cin.
+  Exec ExecTrigger(std::initializer_list<std::string> args,
+                   std::string std_in = "") {
+    // You can not fork after you've started the service due to risk of
+    // deadlocks.
+    PERFETTO_CHECK(exec_allowed_);
+    return Exec("trigger_perfetto", std::move(args), std::move(std_in));
+  }
+
+  // Tests are allowed to freely use these variables.
+  std::string stderr_;
+  base::TestTaskRunner task_runner_;
+
+ private:
+  bool exec_allowed_ = true;
+  TestHelper test_helper_{&task_runner_};
+};
+
+}  // namespace
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#define AndroidOnly(x) x
+#else
+#define AndroidOnly(x) DISABLED_##x
+#endif
+
+TEST_F(PerfettoCmdlineTest, InvalidCases) {
+  std::string cfg("duration_ms: 100");
+
+  auto invalid_arg = ExecPerfetto({"--invalid-arg"});
+  auto empty_config = ExecPerfetto({"-c", "-", "-o", "-"}, "");
+
+  // Cannot make assertions on --dropbox because on standalone builds it fails
+  // prematurely due to lack of dropbox.
+  auto missing_dropbox =
+      ExecPerfetto({"-c", "-", "--txt", "-o", "-", "--dropbox=foo"}, cfg);
+  auto either_out_or_dropbox = ExecPerfetto({"-c", "-", "--txt"}, cfg);
+
+  // Disallow mixing simple and file config.
+  auto simple_and_file_1 =
+      ExecPerfetto({"-o", "-", "-c", "-", "-t", "2s"}, cfg);
+  auto simple_and_file_2 =
+      ExecPerfetto({"-o", "-", "-c", "-", "-b", "2m"}, cfg);
+  auto simple_and_file_3 =
+      ExecPerfetto({"-o", "-", "-c", "-", "-s", "2m"}, cfg);
+
+  // Invalid --attach / --detach cases.
+  auto invalid_stop =
+      ExecPerfetto({"-c", "-", "--txt", "-o", "-", "--stop"}, cfg);
+  auto attach_and_config_1 =
+      ExecPerfetto({"-c", "-", "--txt", "-o", "-", "--attach=foo"}, cfg);
+  auto attach_and_config_2 =
+      ExecPerfetto({"-t", "2s", "-o", "-", "--attach=foo"}, cfg);
+  auto attach_needs_argument = ExecPerfetto({"--attach"}, cfg);
+  auto detach_needs_argument =
+      ExecPerfetto({"-t", "2s", "-o", "-", "--detach"}, cfg);
+  auto detach_without_out_or_dropbox =
+      ExecPerfetto({"-t", "2s", "--detach=foo"}, cfg);
+
+  // Cannot trace and use --query.
+  auto trace_and_query_1 = ExecPerfetto({"-t", "2s", "--query"}, cfg);
+  auto trace_and_query_2 = ExecPerfetto({"-c", "-", "--query"}, cfg);
+
+  // Ensure all Exec:: calls have been saved to prevent deadlocks.
+  StartServiceIfRequiredNoNewExecsAfterThis();
+
+  EXPECT_EQ(1, invalid_arg.Run(&stderr_));
+
+  EXPECT_EQ(1, empty_config.Run(&stderr_));
+  EXPECT_THAT(stderr_, HasSubstr("TraceConfig is empty"));
+
+  // Cannot make assertions on --upload because on standalone builds it fails
+  // prematurely due to lack of dropbox.
+  EXPECT_EQ(1, missing_dropbox.Run(&stderr_));
+
+  EXPECT_EQ(1, either_out_or_dropbox.Run(&stderr_));
+  EXPECT_THAT(stderr_, HasSubstr("Either --out or --upload"));
+
+  // Disallow mixing simple and file config.
+  EXPECT_EQ(1, simple_and_file_1.Run(&stderr_));
+  EXPECT_THAT(stderr_, HasSubstr("Cannot specify both -c"));
+
+  EXPECT_EQ(1, simple_and_file_2.Run(&stderr_));
+  EXPECT_THAT(stderr_, HasSubstr("Cannot specify both -c"));
+
+  EXPECT_EQ(1, simple_and_file_3.Run(&stderr_));
+  EXPECT_THAT(stderr_, HasSubstr("Cannot specify both -c"));
+
+  // Invalid --attach / --detach cases.
+  EXPECT_EQ(1, invalid_stop.Run(&stderr_));
+  EXPECT_THAT(stderr_, HasSubstr("--stop is supported only in combination"));
+
+  EXPECT_EQ(1, attach_and_config_1.Run(&stderr_));
+  EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
+
+  EXPECT_EQ(1, attach_and_config_2.Run(&stderr_));
+  EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
+
+  EXPECT_EQ(1, attach_needs_argument.Run(&stderr_));
+  EXPECT_THAT(stderr_, ContainsRegex("option.*--attach.*requires an argument"));
+
+  EXPECT_EQ(1, detach_needs_argument.Run(&stderr_));
+  EXPECT_THAT(stderr_, ContainsRegex("option.*--detach.*requires an argument"));
+
+  EXPECT_EQ(1, detach_without_out_or_dropbox.Run(&stderr_));
+  EXPECT_THAT(stderr_, HasSubstr("--out or --upload is required"));
+
+  // Cannot trace and use --query.
+  EXPECT_EQ(1, trace_and_query_1.Run(&stderr_));
+  EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
+
+  EXPECT_EQ(1, trace_and_query_2.Run(&stderr_));
+  EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
+}
+
+TEST_F(PerfettoCmdlineTest, Version) {
+  auto perfetto = ExecPerfetto({"--version"});
+  EXPECT_EQ(0, perfetto.Run(&stderr_)) << stderr_;
+}
+
+TEST_F(PerfettoCmdlineTest, TxtConfig) {
+  std::string cfg("duration_ms: 100");
+  auto perfetto = ExecPerfetto({"-c", "-", "--txt", "-o", "-"}, cfg);
+  StartServiceIfRequiredNoNewExecsAfterThis();
+  EXPECT_EQ(0, perfetto.Run(&stderr_)) << stderr_;
+}
+
+TEST_F(PerfettoCmdlineTest, SimpleConfig) {
+  auto perfetto = ExecPerfetto({"-o", "-", "-c", "-", "-t", "100ms"});
+  StartServiceIfRequiredNoNewExecsAfterThis();
+  EXPECT_EQ(0, perfetto.Run(&stderr_)) << stderr_;
+}
+
+TEST_F(PerfettoCmdlineTest, DetachAndAttach) {
+  auto attach_to_not_existing = ExecPerfetto({"--attach=not_existent"});
+
+  std::string cfg("duration_ms: 10000; write_into_file: true");
+  auto detach_valid_stop =
+      ExecPerfetto({"-o", "-", "-c", "-", "--txt", "--detach=valid_stop"}, cfg);
+  auto stop_valid_stop = ExecPerfetto({"--attach=valid_stop", "--stop"});
+
+  StartServiceIfRequiredNoNewExecsAfterThis();
+
+  EXPECT_NE(0, attach_to_not_existing.Run(&stderr_));
+  EXPECT_THAT(stderr_, HasSubstr("Session re-attach failed"));
+
+  EXPECT_EQ(0, detach_valid_stop.Run(&stderr_)) << stderr_;
+  EXPECT_EQ(0, stop_valid_stop.Run(&stderr_));
+}
+
+TEST_F(PerfettoCmdlineTest, StartTracingTrigger) {
+  // See |message_count| and |message_size| in the TraceConfig above.
+  constexpr size_t kMessageCount = 11;
+  constexpr size_t kMessageSize = 32;
+  protos::gen::TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(1024);
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("android.perfetto.FakeProducer");
+  ds_config->mutable_for_testing()->set_message_count(kMessageCount);
+  ds_config->mutable_for_testing()->set_message_size(kMessageSize);
+  auto* trigger_cfg = trace_config.mutable_trigger_config();
+  trigger_cfg->set_trigger_mode(
+      protos::gen::TraceConfig::TriggerConfig::START_TRACING);
+  trigger_cfg->set_trigger_timeout_ms(15000);
+  auto* trigger = trigger_cfg->add_triggers();
+  trigger->set_name("trigger_name");
+  // |stop_delay_ms| must be long enough that we can write the packets in
+  // before the trace finishes. This has to be long enough for the slowest
+  // emulator. But as short as possible to prevent the test running a long
+  // time.
+  trigger->set_stop_delay_ms(500);
+
+  // We have to construct all the processes we want to fork before we start the
+  // service with |StartServiceIfRequired()|. this is because it is unsafe
+  // (could deadlock) to fork after we've spawned some threads which might
+  // printf (and thus hold locks).
+  const std::string path = RandomTraceFileName();
+  auto perfetto_proc = ExecPerfetto(
+      {
+          "-o",
+          path,
+          "-c",
+          "-",
+      },
+      trace_config.SerializeAsString());
+
+  auto trigger_proc = ExecTrigger({"trigger_name"});
+
+  // Start the service and connect a simple fake producer.
+  StartServiceIfRequiredNoNewExecsAfterThis();
+
+  auto* fake_producer = ConnectFakeProducer();
+  EXPECT_TRUE(fake_producer);
+
+  // Start a background thread that will deliver the config now that we've
+  // started the service. See |perfetto_proc| above for the args passed.
+  std::thread background_trace([&perfetto_proc]() {
+    std::string stderr_str;
+    EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
+  });
+
+  WaitForProducerSetup();
+  EXPECT_EQ(0, trigger_proc.Run(&stderr_));
+
+  // Wait for the producer to start, and then write out 11 packets.
+  WaitForProducerEnabled();
+  auto on_data_written = task_runner_.CreateCheckpoint("data_written");
+  fake_producer->ProduceEventBatch(WrapTask(on_data_written));
+  task_runner_.RunUntilCheckpoint("data_written");
+  background_trace.join();
+
+  std::string trace_str;
+  base::ReadFile(path, &trace_str);
+  protos::gen::Trace trace;
+  ASSERT_TRUE(trace.ParseFromString(trace_str));
+  size_t for_testing_packets = 0;
+  size_t trigger_packets = 0;
+  size_t trace_config_packets = 0;
+  for (const auto& packet : trace.packet()) {
+    if (packet.has_trace_config()) {
+      // Ensure the trace config properly includes the trigger mode we set.
+      auto kStartTrig = protos::gen::TraceConfig::TriggerConfig::START_TRACING;
+      EXPECT_EQ(kStartTrig,
+                packet.trace_config().trigger_config().trigger_mode());
+      ++trace_config_packets;
+    } else if (packet.has_trigger()) {
+      // validate that the triggers are properly added to the trace.
+      EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
+      ++trigger_packets;
+    } else if (packet.has_for_testing()) {
+      // Make sure that the data size is correctly set based on what we
+      // requested.
+      EXPECT_EQ(kMessageSize, packet.for_testing().str().size());
+      ++for_testing_packets;
+    }
+  }
+  EXPECT_EQ(trace_config_packets, 1u);
+  EXPECT_EQ(trigger_packets, 1u);
+  EXPECT_EQ(for_testing_packets, kMessageCount);
+}
+
+TEST_F(PerfettoCmdlineTest, StopTracingTrigger) {
+  // See |message_count| and |message_size| in the TraceConfig above.
+  constexpr size_t kMessageCount = 11;
+  constexpr size_t kMessageSize = 32;
+  protos::gen::TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(1024);
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("android.perfetto.FakeProducer");
+  ds_config->mutable_for_testing()->set_message_count(kMessageCount);
+  ds_config->mutable_for_testing()->set_message_size(kMessageSize);
+  auto* trigger_cfg = trace_config.mutable_trigger_config();
+  trigger_cfg->set_trigger_mode(
+      protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
+  trigger_cfg->set_trigger_timeout_ms(15000);
+  auto* trigger = trigger_cfg->add_triggers();
+  trigger->set_name("trigger_name");
+  // |stop_delay_ms| must be long enough that we can write the packets in
+  // before the trace finishes. This has to be long enough for the slowest
+  // emulator. But as short as possible to prevent the test running a long
+  // time.
+  trigger->set_stop_delay_ms(500);
+  trigger = trigger_cfg->add_triggers();
+  trigger->set_name("trigger_name_3");
+  trigger->set_stop_delay_ms(60000);
+
+  // We have to construct all the processes we want to fork before we start the
+  // service with |StartServiceIfRequired()|. this is because it is unsafe
+  // (could deadlock) to fork after we've spawned some threads which might
+  // printf (and thus hold locks).
+  const std::string path = RandomTraceFileName();
+  auto perfetto_proc = ExecPerfetto(
+      {
+          "-o",
+          path,
+          "-c",
+          "-",
+      },
+      trace_config.SerializeAsString());
+
+  auto trigger_proc =
+      ExecTrigger({"trigger_name_2", "trigger_name", "trigger_name_3"});
+
+  // Start the service and connect a simple fake producer.
+  StartServiceIfRequiredNoNewExecsAfterThis();
+  auto* fake_producer = ConnectFakeProducer();
+  EXPECT_TRUE(fake_producer);
+
+  // Start a background thread that will deliver the config now that we've
+  // started the service. See |perfetto_proc| above for the args passed.
+  std::thread background_trace([&perfetto_proc]() {
+    std::string stderr_str;
+    EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
+  });
+
+  WaitForProducerEnabled();
+  // Wait for the producer to start, and then write out 11 packets, before the
+  // trace actually starts (the trigger is seen).
+  auto on_data_written = task_runner_.CreateCheckpoint("data_written_1");
+  fake_producer->ProduceEventBatch(WrapTask(on_data_written));
+  task_runner_.RunUntilCheckpoint("data_written_1");
+
+  EXPECT_EQ(0, trigger_proc.Run(&stderr_)) << "stderr: " << stderr_;
+
+  background_trace.join();
+
+  std::string trace_str;
+  base::ReadFile(path, &trace_str);
+  protos::gen::Trace trace;
+  ASSERT_TRUE(trace.ParseFromString(trace_str));
+  bool seen_first_trigger = false;
+  size_t for_testing_packets = 0;
+  size_t trigger_packets = 0;
+  size_t trace_config_packets = 0;
+  for (const auto& packet : trace.packet()) {
+    if (packet.has_trace_config()) {
+      // Ensure the trace config properly includes the trigger mode we set.
+      auto kStopTrig = protos::gen::TraceConfig::TriggerConfig::STOP_TRACING;
+      EXPECT_EQ(kStopTrig,
+                packet.trace_config().trigger_config().trigger_mode());
+      ++trace_config_packets;
+    } else if (packet.has_trigger()) {
+      // validate that the triggers are properly added to the trace.
+      if (!seen_first_trigger) {
+        EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
+        seen_first_trigger = true;
+      } else {
+        EXPECT_EQ("trigger_name_3", packet.trigger().trigger_name());
+      }
+      ++trigger_packets;
+    } else if (packet.has_for_testing()) {
+      // Make sure that the data size is correctly set based on what we
+      // requested.
+      EXPECT_EQ(kMessageSize, packet.for_testing().str().size());
+      ++for_testing_packets;
+    }
+  }
+  EXPECT_EQ(trace_config_packets, 1u);
+  EXPECT_EQ(trigger_packets, 2u);
+  EXPECT_EQ(for_testing_packets, kMessageCount);
+}
+
+// Dropbox on the commandline client only works on android builds. So disable
+// this test on all other builds.
+TEST_F(PerfettoCmdlineTest, AndroidOnly(NoDataNoFileWithoutTrigger)) {
+  // See |message_count| and |message_size| in the TraceConfig above.
+  constexpr size_t kMessageCount = 11;
+  constexpr size_t kMessageSize = 32;
+  protos::gen::TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(1024);
+  trace_config.set_allow_user_build_tracing(true);
+  auto* incident_config = trace_config.mutable_incident_report_config();
+  incident_config->set_destination_package("foo.bar.baz");
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("android.perfetto.FakeProducer");
+  ds_config->mutable_for_testing()->set_message_count(kMessageCount);
+  ds_config->mutable_for_testing()->set_message_size(kMessageSize);
+  auto* trigger_cfg = trace_config.mutable_trigger_config();
+  trigger_cfg->set_trigger_mode(
+      protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
+  trigger_cfg->set_trigger_timeout_ms(1000);
+  auto* trigger = trigger_cfg->add_triggers();
+  trigger->set_name("trigger_name");
+  // |stop_delay_ms| must be long enough that we can write the packets in
+  // before the trace finishes. This has to be long enough for the slowest
+  // emulator. But as short as possible to prevent the test running a long
+  // time.
+  trigger->set_stop_delay_ms(500);
+  trigger = trigger_cfg->add_triggers();
+
+  // We have to construct all the processes we want to fork before we start the
+  // service with |StartServiceIfRequired()|. this is because it is unsafe
+  // (could deadlock) to fork after we've spawned some threads which might
+  // printf (and thus hold locks).
+  const std::string path = RandomTraceFileName();
+  auto perfetto_proc = ExecPerfetto(
+      {
+          "--dropbox",
+          "TAG",
+          "--no-guardrails",
+          "-c",
+          "-",
+      },
+      trace_config.SerializeAsString());
+
+  StartServiceIfRequiredNoNewExecsAfterThis();
+  auto* fake_producer = ConnectFakeProducer();
+  EXPECT_TRUE(fake_producer);
+
+  std::string stderr_str;
+  std::thread background_trace([&perfetto_proc, &stderr_str]() {
+    EXPECT_EQ(0, perfetto_proc.Run(&stderr_str));
+  });
+  background_trace.join();
+
+  EXPECT_THAT(stderr_str,
+              ::testing::HasSubstr("Skipping write to incident. Empty trace."));
+}
+
+TEST_F(PerfettoCmdlineTest, StopTracingTriggerFromConfig) {
+  // See |message_count| and |message_size| in the TraceConfig above.
+  constexpr size_t kMessageCount = 11;
+  constexpr size_t kMessageSize = 32;
+  protos::gen::TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(1024);
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("android.perfetto.FakeProducer");
+  ds_config->mutable_for_testing()->set_message_count(kMessageCount);
+  ds_config->mutable_for_testing()->set_message_size(kMessageSize);
+  auto* trigger_cfg = trace_config.mutable_trigger_config();
+  trigger_cfg->set_trigger_mode(
+      protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
+  trigger_cfg->set_trigger_timeout_ms(15000);
+  auto* trigger = trigger_cfg->add_triggers();
+  trigger->set_name("trigger_name");
+  // |stop_delay_ms| must be long enough that we can write the packets in
+  // before the trace finishes. This has to be long enough for the slowest
+  // emulator. But as short as possible to prevent the test running a long
+  // time.
+  trigger->set_stop_delay_ms(500);
+  trigger = trigger_cfg->add_triggers();
+  trigger->set_name("trigger_name_3");
+  trigger->set_stop_delay_ms(60000);
+
+  // We have to construct all the processes we want to fork before we start the
+  // service with |StartServiceIfRequired()|. this is because it is unsafe
+  // (could deadlock) to fork after we've spawned some threads which might
+  // printf (and thus hold locks).
+  const std::string path = RandomTraceFileName();
+  auto perfetto_proc = ExecPerfetto(
+      {
+          "-o",
+          path,
+          "-c",
+          "-",
+      },
+      trace_config.SerializeAsString());
+
+  std::string triggers = R"(
+    activate_triggers: "trigger_name_2"
+    activate_triggers: "trigger_name"
+    activate_triggers: "trigger_name_3"
+  )";
+  auto perfetto_proc_2 = ExecPerfetto(
+      {
+          "-o",
+          path,
+          "-c",
+          "-",
+          "--txt",
+      },
+      triggers);
+
+  // Start the service and connect a simple fake producer.
+  StartServiceIfRequiredNoNewExecsAfterThis();
+  auto* fake_producer = ConnectFakeProducer();
+  EXPECT_TRUE(fake_producer);
+
+  std::thread background_trace([&perfetto_proc]() {
+    std::string stderr_str;
+    EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
+  });
+
+  WaitForProducerEnabled();
+  // Wait for the producer to start, and then write out 11 packets, before the
+  // trace actually starts (the trigger is seen).
+  auto on_data_written = task_runner_.CreateCheckpoint("data_written_1");
+  fake_producer->ProduceEventBatch(WrapTask(on_data_written));
+  task_runner_.RunUntilCheckpoint("data_written_1");
+
+  EXPECT_EQ(0, perfetto_proc_2.Run(&stderr_)) << "stderr: " << stderr_;
+
+  background_trace.join();
+
+  std::string trace_str;
+  base::ReadFile(path, &trace_str);
+  protos::gen::Trace trace;
+  ASSERT_TRUE(trace.ParseFromString(trace_str));
+  EXPECT_LT(static_cast<int>(kMessageCount), trace.packet_size());
+  bool seen_first_trigger = false;
+  for (const auto& packet : trace.packet()) {
+    if (packet.has_trace_config()) {
+      // Ensure the trace config properly includes the trigger mode we set.
+      auto kStopTrig = protos::gen::TraceConfig::TriggerConfig::STOP_TRACING;
+      EXPECT_EQ(kStopTrig,
+                packet.trace_config().trigger_config().trigger_mode());
+    } else if (packet.has_trigger()) {
+      // validate that the triggers are properly added to the trace.
+      if (!seen_first_trigger) {
+        EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
+        seen_first_trigger = true;
+      } else {
+        EXPECT_EQ("trigger_name_3", packet.trigger().trigger_name());
+      }
+    } else if (packet.has_for_testing()) {
+      // Make sure that the data size is correctly set based on what we
+      // requested.
+      EXPECT_EQ(kMessageSize, packet.for_testing().str().size());
+    }
+  }
+}
+
+TEST_F(PerfettoCmdlineTest, TriggerFromConfigStopsFileOpening) {
+  // See |message_count| and |message_size| in the TraceConfig above.
+  constexpr size_t kMessageCount = 11;
+  constexpr size_t kMessageSize = 32;
+  protos::gen::TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(1024);
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("android.perfetto.FakeProducer");
+  ds_config->mutable_for_testing()->set_message_count(kMessageCount);
+  ds_config->mutable_for_testing()->set_message_size(kMessageSize);
+  auto* trigger_cfg = trace_config.mutable_trigger_config();
+  trigger_cfg->set_trigger_mode(
+      protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
+  trigger_cfg->set_trigger_timeout_ms(15000);
+  auto* trigger = trigger_cfg->add_triggers();
+  trigger->set_name("trigger_name");
+  // |stop_delay_ms| must be long enough that we can write the packets in
+  // before the trace finishes. This has to be long enough for the slowest
+  // emulator. But as short as possible to prevent the test running a long
+  // time.
+  trigger->set_stop_delay_ms(500);
+  trigger = trigger_cfg->add_triggers();
+  trigger->set_name("trigger_name_3");
+  trigger->set_stop_delay_ms(60000);
+
+  // We have to construct all the processes we want to fork before we start the
+  // service with |StartServiceIfRequired()|. this is because it is unsafe
+  // (could deadlock) to fork after we've spawned some threads which might
+  // printf (and thus hold locks).
+  const std::string path = RandomTraceFileName();
+  std::string triggers = R"(
+    activate_triggers: "trigger_name_2"
+    activate_triggers: "trigger_name"
+    activate_triggers: "trigger_name_3"
+  )";
+  auto perfetto_proc = ExecPerfetto(
+      {
+          "-o",
+          path,
+          "-c",
+          "-",
+          "--txt",
+      },
+      triggers);
+
+  // Start the service and connect a simple fake producer.
+  StartServiceIfRequiredNoNewExecsAfterThis();
+  auto* fake_producer = ConnectFakeProducer();
+  EXPECT_TRUE(fake_producer);
+
+  std::string trace_str;
+  EXPECT_FALSE(base::ReadFile(path, &trace_str));
+
+  EXPECT_EQ(0, perfetto_proc.Run(&stderr_)) << "stderr: " << stderr_;
+
+  EXPECT_FALSE(base::ReadFile(path, &trace_str));
+}
+
+TEST_F(PerfettoCmdlineTest, Query) {
+  auto query = ExecPerfetto({"--query"});
+  auto query_raw = ExecPerfetto({"--query-raw"});
+  StartServiceIfRequiredNoNewExecsAfterThis();
+  EXPECT_EQ(0, query.Run(&stderr_)) << stderr_;
+  EXPECT_EQ(0, query_raw.Run(&stderr_)) << stderr_;
+}
+
+TEST_F(PerfettoCmdlineTest, AndroidOnly(CmdTriggerWithUploadFlag)) {
+  // See |message_count| and |message_size| in the TraceConfig above.
+  constexpr size_t kMessageCount = 2;
+  constexpr size_t kMessageSize = 2;
+  protos::gen::TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(1024);
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("android.perfetto.FakeProducer");
+  ds_config->mutable_for_testing()->set_message_count(kMessageCount);
+  ds_config->mutable_for_testing()->set_message_size(kMessageSize);
+  auto* trigger_cfg = trace_config.mutable_trigger_config();
+  trigger_cfg->set_trigger_mode(
+      protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
+  trigger_cfg->set_trigger_timeout_ms(15000);
+  auto* trigger = trigger_cfg->add_triggers();
+  trigger->set_name("trigger_name");
+  // |stop_delay_ms| must be long enough that we can write the packets in
+  // before the trace finishes. This has to be long enough for the slowest
+  // emulator. But as short as possible to prevent the test running a long
+  // time.
+  trigger->set_stop_delay_ms(500);
+
+  // We have to construct all the processes we want to fork before we start the
+  // service with |StartServiceIfRequired()|. this is because it is unsafe
+  // (could deadlock) to fork after we've spawned some threads which might
+  // printf (and thus hold locks).
+  const std::string path = RandomTraceFileName();
+  auto perfetto_proc = ExecPerfetto(
+      {
+          "-o",
+          path,
+          "-c",
+          "-",
+      },
+      trace_config.SerializeAsString());
+
+  std::string triggers = R"(
+    activate_triggers: "trigger_name"
+  )";
+  auto perfetto_proc_2 = ExecPerfetto(
+      {
+          "--upload",
+          "-c",
+          "-",
+          "--txt",
+      },
+      triggers);
+
+  // Start the service and connect a simple fake producer.
+  StartServiceIfRequiredNoNewExecsAfterThis();
+  auto* fake_producer = ConnectFakeProducer();
+  EXPECT_TRUE(fake_producer);
+
+  std::thread background_trace([&perfetto_proc]() {
+    std::string stderr_str;
+    EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
+  });
+
+  WaitForProducerEnabled();
+  // Wait for the producer to start, and then write out 11 packets, before the
+  // trace actually starts (the trigger is seen).
+  auto on_data_written = task_runner_.CreateCheckpoint("data_written_1");
+  fake_producer->ProduceEventBatch(WrapTask(on_data_written));
+  task_runner_.RunUntilCheckpoint("data_written_1");
+
+  EXPECT_EQ(0, perfetto_proc_2.Run(&stderr_)) << "stderr: " << stderr_;
+
+  background_trace.join();
+
+  std::string trace_str;
+  base::ReadFile(path, &trace_str);
+  protos::gen::Trace trace;
+  ASSERT_TRUE(trace.ParseFromString(trace_str));
+  EXPECT_LT(static_cast<int>(kMessageCount), trace.packet_size());
+  for (const auto& packet : trace.packet()) {
+    if (packet.has_trigger()) {
+      EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
+    }
+  }
+}
+
+}  // namespace perfetto
diff --git a/test/cts/BUILD.gn b/test/cts/BUILD.gn
index 0404ceb..e821de8 100644
--- a/test/cts/BUILD.gn
+++ b/test/cts/BUILD.gn
@@ -20,7 +20,7 @@
   complete_static_lib = true
   testonly = true
   deps = [
-    "..:end_to_end_integrationtests",
+    "..:integrationtests",
     "../..:libperfetto_client_experimental",
     "../../gn:default_deps",
     "../../gn:gtest_and_gmock",
diff --git a/test/end_to_end_integrationtest.cc b/test/end_to_end_integrationtest.cc
deleted file mode 100644
index 788b67c..0000000
--- a/test/end_to_end_integrationtest.cc
+++ /dev/null
@@ -1,1847 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <unistd.h>
-
-#include <chrono>
-#include <functional>
-#include <initializer_list>
-#include <random>
-#include <thread>
-
-#include "perfetto/base/build_config.h"
-#include "perfetto/base/logging.h"
-#include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/pipe.h"
-#include "perfetto/ext/base/scoped_file.h"
-#include "perfetto/ext/base/string_utils.h"
-#include "perfetto/ext/base/subprocess.h"
-#include "perfetto/ext/base/temp_file.h"
-#include "perfetto/ext/base/utils.h"
-#include "perfetto/ext/ipc/basic_types.h"
-#include "perfetto/ext/traced/traced.h"
-#include "perfetto/ext/tracing/core/commit_data_request.h"
-#include "perfetto/ext/tracing/core/trace_packet.h"
-#include "perfetto/ext/tracing/core/tracing_service.h"
-#include "perfetto/ext/tracing/ipc/default_socket.h"
-#include "perfetto/protozero/scattered_heap_buffer.h"
-#include "perfetto/tracing/core/tracing_service_state.h"
-#include "src/base/test/test_task_runner.h"
-#include "src/base/test/utils.h"
-#include "src/protozero/filtering/filter_bytecode_generator.h"
-#include "src/traced/probes/ftrace/ftrace_controller.h"
-#include "src/traced/probes/ftrace/ftrace_procfs.h"
-#include "test/gtest_and_gmock.h"
-#include "test/test_helper.h"
-
-#include "protos/perfetto/config/power/android_power_config.pbzero.h"
-#include "protos/perfetto/config/test_config.gen.h"
-#include "protos/perfetto/config/trace_config.gen.h"
-#include "protos/perfetto/trace/ftrace/ftrace.gen.h"
-#include "protos/perfetto/trace/ftrace/ftrace_event.gen.h"
-#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.gen.h"
-#include "protos/perfetto/trace/ftrace/ftrace_stats.gen.h"
-#include "protos/perfetto/trace/perfetto/tracing_service_event.gen.h"
-#include "protos/perfetto/trace/power/battery_counters.gen.h"
-#include "protos/perfetto/trace/test_event.gen.h"
-#include "protos/perfetto/trace/trace.gen.h"
-#include "protos/perfetto/trace/trace_packet.gen.h"
-#include "protos/perfetto/trace/trace_packet.pbzero.h"
-#include "protos/perfetto/trace/trigger.gen.h"
-
-#include "protos/perfetto/common/sys_stats_counters.gen.h"
-#include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
-#include "protos/perfetto/trace/sys_stats/sys_stats.gen.h"
-
-#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
-#include "test/android_test_utils.h"
-#endif
-
-namespace perfetto {
-
-namespace {
-
-using ::testing::ContainsRegex;
-using ::testing::Each;
-using ::testing::ElementsAreArray;
-using ::testing::HasSubstr;
-using ::testing::Property;
-using ::testing::SizeIs;
-
-std::string RandomTraceFileName() {
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-  constexpr char kSysTmpPath[] = "/data/misc/perfetto-traces";
-#else
-  constexpr char kSysTmpPath[] = "/tmp";
-#endif
-  static int suffix = 0;
-
-  std::string path;
-  path.assign(kSysTmpPath);
-  path.append("/trace-");
-  path.append(std::to_string(base::GetBootTimeNs().count()));
-  path.append("-");
-  path.append(std::to_string(suffix++));
-  return path;
-}
-
-// This class is a reference to a child process that has in essence been execv
-// to the requested binary. The process will start and then wait for Run()
-// before proceeding. We use this to fork new processes before starting any
-// additional threads in the parent process (otherwise you would risk
-// deadlocks), but pause the forked processes until remaining setup (including
-// any necessary threads) in the parent process is complete.
-class Exec {
- public:
-  // Starts the forked process that was created. If not null then |stderr_out|
-  // will contain the stderr of the process.
-  int Run(std::string* stderr_out = nullptr) {
-    // We can't be the child process.
-    PERFETTO_CHECK(getpid() != subprocess_.pid());
-    // Will cause the entrypoint to continue.
-    PERFETTO_CHECK(write(*sync_pipe_.wr, "1", 1) == 1);
-    sync_pipe_.wr.reset();
-    subprocess_.Wait();
-
-    if (stderr_out) {
-      *stderr_out = std::move(subprocess_.output());
-    } else {
-      PERFETTO_LOG("Child proc %d exited with stderr: \"%s\"",
-                   subprocess_.pid(), subprocess_.output().c_str());
-    }
-    return subprocess_.returncode();
-  }
-
-  Exec(const std::string& argv0,
-       std::initializer_list<std::string> args,
-       std::string input = "") {
-    subprocess_.args.stderr_mode = base::Subprocess::kBuffer;
-    subprocess_.args.stdout_mode = base::Subprocess::kDevNull;
-    subprocess_.args.input = input;
-
-#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
-    constexpr bool kUseSystemBinaries = false;
-#else
-    constexpr bool kUseSystemBinaries = true;
-#endif
-
-    std::vector<std::string>& cmd = subprocess_.args.exec_cmd;
-    if (kUseSystemBinaries) {
-      PERFETTO_CHECK(TestHelper::kDefaultMode ==
-                     TestHelper::Mode::kUseSystemService);
-      cmd.push_back("/system/bin/" + argv0);
-      cmd.insert(cmd.end(), args.begin(), args.end());
-    } else {
-      PERFETTO_CHECK(TestHelper::kDefaultMode ==
-                     TestHelper::Mode::kStartDaemons);
-      subprocess_.args.env.push_back(
-          std::string("PERFETTO_PRODUCER_SOCK_NAME=") +
-          TestHelper::GetDefaultModeProducerSocketName());
-      subprocess_.args.env.push_back(
-          std::string("PERFETTO_CONSUMER_SOCK_NAME=") +
-          TestHelper::GetDefaultModeConsumerSocketName());
-      cmd.push_back(base::GetCurExecutableDir() + "/" + argv0);
-      cmd.insert(cmd.end(), args.begin(), args.end());
-    }
-
-    if (!base::FileExists(cmd[0])) {
-      PERFETTO_FATAL(
-          "Cannot find %s. Make sure that the target has been built and, on "
-          "Android, pushed to the device.",
-          cmd[0].c_str());
-    }
-
-    // This pipe blocks the execution of the child process until the main test
-    // process calls Run(). There are two conflicting problems here:
-    // 1) We can't fork() subprocesses too late, because the test spawns threads
-    //    for hosting the service. fork+threads = bad (see aosp/1089744).
-    // 2) We can't run the subprocess too early, because we need to wait that
-    //    the service threads are ready before trying to connect from the child
-    //    process.
-    sync_pipe_ = base::Pipe::Create();
-    int sync_pipe_rd = *sync_pipe_.rd;
-    subprocess_.args.preserve_fds.push_back(sync_pipe_rd);
-
-    // This lambda will be called on the forked child process after having
-    // setup pipe redirection and closed all FDs, right before the exec().
-    // The Subprocesss harness will take care of closing also |sync_pipe_.wr|.
-    subprocess_.args.posix_entrypoint_for_testing = [sync_pipe_rd] {
-      // Don't add any logging here, all file descriptors are closed and trying
-      // to log will likely cause undefined behaviors.
-      char ignored = 0;
-      PERFETTO_CHECK(PERFETTO_EINTR(read(sync_pipe_rd, &ignored, 1)) > 0);
-      PERFETTO_CHECK(close(sync_pipe_rd) == 0 || errno == EINTR);
-    };
-
-    subprocess_.Start();
-    sync_pipe_.rd.reset();
-  }
-
- private:
-  base::Subprocess subprocess_;
-  base::Pipe sync_pipe_;
-};
-
-class PerfettoTest : public ::testing::Test {
- public:
-  void SetUp() override {
-    ftrace_procfs_ = FtraceProcfs::CreateGuessingMountPoint();
-
-// On android we do expect that tracefs is accessible, both in the case of
-// running as part of traced/probes system daemons and shell. On Linux this is
-// up to the system admin, don't hard fail.
-#if !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-    if (!ftrace_procfs_) {
-      PERFETTO_ELOG(
-          "Cannot acces tracefs. On Linux you need to manually run `sudo chown "
-          "-R $USER /sys/kernel/tracing` to enable these tests. Skipping");
-      GTEST_SKIP();
-    } else {
-      // Recent kernels set tracing_on=1 by default. On Android this is
-      // disabled by initrc scripts. Be tolerant on Linux where we don't have
-      // that and force disable ftrace.
-      ftrace_procfs_->SetTracingOn(false);
-    }
-#endif
-  }
-
-  std::unique_ptr<FtraceProcfs> ftrace_procfs_;
-};
-
-class PerfettoCmdlineTest : public ::testing::Test {
- public:
-  void SetUp() override {
-#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
-    defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER)
-    // Disable cmdline tests on sanitizets because they use fork() and that
-    // messes up leak / races detections, which has been fixed only recently
-    // (see https://github.com/google/sanitizers/issues/836 ).
-    PERFETTO_LOG("Skipping cmdline integration tests on sanitizers");
-    GTEST_SKIP();
-#endif
-  }
-
-  void TearDown() override {}
-
-  void StartServiceIfRequiredNoNewExecsAfterThis() {
-    exec_allowed_ = false;
-    test_helper_.StartServiceIfRequired();
-  }
-
-  FakeProducer* ConnectFakeProducer() {
-    return test_helper_.ConnectFakeProducer();
-  }
-
-  std::function<void()> WrapTask(const std::function<void()>& function) {
-    return test_helper_.WrapTask(function);
-  }
-
-  void WaitForProducerSetup() { test_helper_.WaitForProducerSetup(); }
-
-  void WaitForProducerEnabled() { test_helper_.WaitForProducerEnabled(); }
-
-  // Creates a process that represents the perfetto binary that will
-  // start when Run() is called. |args| will be passed as part of
-  // the command line and |std_in| will be piped into std::cin.
-  Exec ExecPerfetto(std::initializer_list<std::string> args,
-                    std::string std_in = "") {
-    // You can not fork after you've started the service due to risk of
-    // deadlocks.
-    PERFETTO_CHECK(exec_allowed_);
-    return Exec("perfetto", std::move(args), std::move(std_in));
-  }
-
-  // Creates a process that represents the trigger_perfetto binary that will
-  // start when Run() is called. |args| will be passed as part of
-  // the command line and |std_in| will be piped into std::cin.
-  Exec ExecTrigger(std::initializer_list<std::string> args,
-                   std::string std_in = "") {
-    // You can not fork after you've started the service due to risk of
-    // deadlocks.
-    PERFETTO_CHECK(exec_allowed_);
-    return Exec("trigger_perfetto", std::move(args), std::move(std_in));
-  }
-
-  // Tests are allowed to freely use these variables.
-  std::string stderr_;
-  base::TestTaskRunner task_runner_;
-
- private:
-  bool exec_allowed_ = true;
-  TestHelper test_helper_{&task_runner_};
-};
-
-// For the SaveForBugreport* tests.
-void SetTraceConfigForBugreportTest(TraceConfig* trace_config) {
-  trace_config->add_buffers()->set_size_kb(4096);
-  trace_config->set_duration_ms(60000);  // Will never hit this.
-  trace_config->set_bugreport_score(10);
-  auto* ds_config = trace_config->add_data_sources()->mutable_config();
-  ds_config->set_name("android.perfetto.FakeProducer");
-  ds_config->mutable_for_testing()->set_message_count(3);
-  ds_config->mutable_for_testing()->set_message_size(10);
-  ds_config->mutable_for_testing()->set_send_batch_on_register(true);
-}
-
-// For the SaveForBugreport* tests.
-static void VerifyBugreportTraceContents() {
-  // Read the trace written in the fixed location (/data/misc/perfetto-traces/
-  // on Android, /tmp/ on Linux/Mac) and make sure it has the right contents.
-  std::string trace_str;
-  base::ReadFile(GetBugreportPath(), &trace_str);
-  ASSERT_FALSE(trace_str.empty());
-  protos::gen::Trace trace;
-  ASSERT_TRUE(trace.ParseFromString(trace_str));
-  int test_packets = 0;
-  for (const auto& p : trace.packet())
-    test_packets += p.has_for_testing() ? 1 : 0;
-  ASSERT_EQ(test_packets, 3);
-}
-
-}  // namespace
-
-// If we're building on Android and starting the daemons ourselves,
-// create the sockets in a world-writable location.
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
-    PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
-#define TEST_PRODUCER_SOCK_NAME "/data/local/tmp/traced_producer"
-#else
-#define TEST_PRODUCER_SOCK_NAME ::perfetto::GetProducerSocket()
-#endif
-
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-#define AndroidOnly(x) x
-#else
-#define AndroidOnly(x) DISABLED_##x
-#endif
-
-TEST_F(PerfettoTest, TestFtraceProducer) {
-  base::TestTaskRunner task_runner;
-
-  TestHelper helper(&task_runner);
-  helper.StartServiceIfRequired();
-
-#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
-  ProbesProducerThread probes(TEST_PRODUCER_SOCK_NAME);
-  probes.Connect();
-#endif
-
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-
-  TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(1024);
-  trace_config.set_duration_ms(3000);
-
-  auto* ds_config = trace_config.add_data_sources()->mutable_config();
-  ds_config->set_name("linux.ftrace");
-  ds_config->set_target_buffer(0);
-
-  protos::gen::FtraceConfig ftrace_config;
-  ftrace_config.add_ftrace_events("sched_switch");
-  ftrace_config.add_ftrace_events("bar");
-  ds_config->set_ftrace_config_raw(ftrace_config.SerializeAsString());
-
-  helper.StartTracing(trace_config);
-  helper.WaitForTracingDisabled();
-
-  helper.ReadData();
-  helper.WaitForReadData();
-
-  const auto& packets = helper.trace();
-  ASSERT_GT(packets.size(), 0u);
-
-  for (const auto& packet : packets) {
-    for (int ev = 0; ev < packet.ftrace_events().event_size(); ev++) {
-      ASSERT_TRUE(packet.ftrace_events()
-                      .event()[static_cast<size_t>(ev)]
-                      .has_sched_switch());
-    }
-  }
-}
-
-TEST_F(PerfettoTest, TestFtraceFlush) {
-  base::TestTaskRunner task_runner;
-
-  TestHelper helper(&task_runner);
-  helper.StartServiceIfRequired();
-
-#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
-  ProbesProducerThread probes(TEST_PRODUCER_SOCK_NAME);
-  probes.Connect();
-#endif
-
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-
-  // Wait for the traced_probes service to connect. We want to start tracing
-  // only after it connects, otherwise we'll start a tracing session with 0
-  // producers connected (which is valid but not what we want here).
-  helper.WaitForDataSourceConnected("linux.ftrace");
-
-  TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(32);
-  trace_config.set_duration_ms(kDefaultTestTimeoutMs);
-
-  auto* ds_config = trace_config.add_data_sources()->mutable_config();
-  ds_config->set_name("linux.ftrace");
-
-  protos::gen::FtraceConfig ftrace_config;
-  ftrace_config.add_ftrace_events("print");
-  ds_config->set_ftrace_config_raw(ftrace_config.SerializeAsString());
-
-  helper.StartTracing(trace_config);
-
-  // Wait for traced_probes to start.
-  helper.WaitFor([&] { return ftrace_procfs_->IsTracingEnabled(); }, "ftrace");
-
-  // Do a first flush just to synchronize with the producer. The problem here
-  // is that, on a Linux workstation, the producer can take several seconds just
-  // to get to the point where it is fully ready. We use the flush ack as a
-  // synchronization point.
-  helper.FlushAndWait(kDefaultTestTimeoutMs);
-
-  const char kMarker[] = "just_one_event";
-  EXPECT_TRUE(ftrace_procfs_->WriteTraceMarker(kMarker));
-
-  // This is the real flush we are testing.
-  helper.FlushAndWait(kDefaultTestTimeoutMs);
-
-  helper.DisableTracing();
-  helper.WaitForTracingDisabled(kDefaultTestTimeoutMs);
-
-  helper.ReadData();
-  helper.WaitForReadData();
-
-  int marker_found = 0;
-  for (const auto& packet : helper.trace()) {
-    for (int i = 0; i < packet.ftrace_events().event_size(); i++) {
-      const auto& ev = packet.ftrace_events().event()[static_cast<size_t>(i)];
-      if (ev.has_print() && ev.print().buf().find(kMarker) != std::string::npos)
-        marker_found++;
-    }
-  }
-  ASSERT_EQ(marker_found, 1);
-}
-
-TEST_F(PerfettoTest, TestKmemActivity) {
-  using C = protos::gen::VmstatCounters;
-
-  base::TestTaskRunner task_runner;
-
-  TestHelper helper(&task_runner);
-
-  helper.StartServiceIfRequired();
-
-#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
-  ProbesProducerThread probes(TEST_PRODUCER_SOCK_NAME);
-  probes.Connect();
-#endif
-
-  auto* producer = helper.ConnectFakeProducer();
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-  helper.WaitForDataSourceConnected("linux.ftrace");
-
-  TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(1024);
-  trace_config.set_unique_session_name("kmem_activity_test");
-
-  auto* ftrace_ds_config = trace_config.add_data_sources()->mutable_config();
-  ftrace_ds_config->set_name("linux.ftrace");
-  protos::gen::FtraceConfig ftrace_config = CreateFtraceConfig({
-      "vmscan/mm_vmscan_kswapd_wake",
-      "vmscan/mm_vmscan_kswapd_sleep",
-      "vmscan/mm_vmscan_direct_reclaim_begin",
-      "vmscan/mm_vmscan_direct_reclaim_end",
-      "compaction/mm_compaction_begin",
-      "compaction/mm_compaction_end",
-  });
-  ftrace_ds_config->set_ftrace_config_raw(ftrace_config.SerializeAsString());
-
-  auto* sys_stats_ds_config = trace_config.add_data_sources()->mutable_config();
-  sys_stats_ds_config->set_name("linux.sys_stats");
-  protos::gen::SysStatsConfig sys_stats_config;
-  sys_stats_config.set_vmstat_period_ms(50);
-  std::vector<C> vmstat_counters = {
-      C::VMSTAT_NR_FREE_PAGES,
-      C::VMSTAT_NR_SLAB_RECLAIMABLE,
-      C::VMSTAT_NR_SLAB_UNRECLAIMABLE,
-      C::VMSTAT_NR_ACTIVE_FILE,
-      C::VMSTAT_NR_INACTIVE_FILE,
-      C::VMSTAT_NR_ACTIVE_ANON,
-      C::VMSTAT_NR_INACTIVE_ANON,
-      C::VMSTAT_WORKINGSET_REFAULT,
-      C::VMSTAT_WORKINGSET_ACTIVATE,
-      C::VMSTAT_NR_FILE_PAGES,
-      C::VMSTAT_PGPGIN,
-      C::VMSTAT_PGPGOUT,
-      C::VMSTAT_PSWPIN,
-      C::VMSTAT_PSWPOUT,
-      C::VMSTAT_PGSTEAL_KSWAPD_DMA,
-      C::VMSTAT_PGSTEAL_KSWAPD_NORMAL,
-      C::VMSTAT_PGSTEAL_KSWAPD_MOVABLE,
-      C::VMSTAT_PGSTEAL_DIRECT_DMA,
-      C::VMSTAT_PGSTEAL_DIRECT_NORMAL,
-      C::VMSTAT_PGSTEAL_DIRECT_MOVABLE,
-      C::VMSTAT_PGSCAN_KSWAPD_DMA,
-      C::VMSTAT_PGSCAN_KSWAPD_NORMAL,
-      C::VMSTAT_PGSCAN_KSWAPD_MOVABLE,
-      C::VMSTAT_PGSCAN_DIRECT_DMA,
-      C::VMSTAT_PGSCAN_DIRECT_NORMAL,
-      C::VMSTAT_PGSCAN_DIRECT_MOVABLE,
-      C::VMSTAT_COMPACT_MIGRATE_SCANNED,
-      C::VMSTAT_COMPACT_FREE_SCANNED,
-  };
-  for (const auto& counter : vmstat_counters) {
-    sys_stats_config.add_vmstat_counters(counter);
-  }
-  sys_stats_ds_config->set_sys_stats_config_raw(
-      sys_stats_config.SerializeAsString());
-
-  auto* trigger_cfg = trace_config.mutable_trigger_config();
-  trigger_cfg->set_trigger_mode(
-      protos::gen::TraceConfig::TriggerConfig::START_TRACING);
-  trigger_cfg->set_trigger_timeout_ms(15000);
-  auto* trigger = trigger_cfg->add_triggers();
-  trigger->set_name("kmem_activity");
-  // |stop_delay_ms| must be long enough that we can write the packets in
-  // before the trace finishes.
-  trigger->set_stop_delay_ms(1000);
-
-  helper.StartTracing(trace_config);
-
-  // Linearize with StartTracing. This ensures that the service has seen the
-  // StartTracing IPC and has armed the triggers.
-  helper.FlushAndWait(kDefaultTestTimeoutMs);
-
-  // Generating synthetic memory pressure to trigger kmem activity is
-  // inherently flaky on different devices. The same goes for writing
-  // /proc/sys/vm/compact_memory to trigger compaction, since compaction is
-  // only started if needed (even if explicitly triggered from proc).
-  // Trigger kmem activity using perfetto trigger.
-  producer->ActivateTrigger("kmem_activity");
-
-  helper.WaitForTracingDisabled();
-
-  helper.ReadData();
-  helper.WaitForReadData();
-
-  const auto& packets = helper.trace();
-  ASSERT_GT(packets.size(), 0u);
-
-  bool sys_stats_captured = false;
-  for (const auto& packet : packets) {
-    for (int ev = 0; ev < packet.ftrace_events().event_size(); ev++) {
-      auto ftrace_event =
-          packet.ftrace_events().event()[static_cast<size_t>(ev)];
-      ASSERT_TRUE(ftrace_event.has_mm_vmscan_kswapd_wake() ||
-                  ftrace_event.has_mm_vmscan_kswapd_sleep() ||
-                  ftrace_event.has_mm_vmscan_direct_reclaim_begin() ||
-                  ftrace_event.has_mm_vmscan_direct_reclaim_end() ||
-                  ftrace_event.has_mm_compaction_begin() ||
-                  ftrace_event.has_mm_compaction_end());
-    }
-
-    if (packet.has_sys_stats()) {
-      sys_stats_captured = true;
-      const auto& sys_stats = packet.sys_stats();
-      const auto& vmstat = sys_stats.vmstat();
-      ASSERT_GT(vmstat.size(), 0u);
-      for (const auto& vmstat_value : vmstat) {
-        ASSERT_NE(std::find(vmstat_counters.begin(), vmstat_counters.end(),
-                            vmstat_value.key()),
-                  vmstat_counters.end());
-      }
-    }
-  }
-
-  // Don't explicitly check that ftrace events were captured, since this test
-  // doesn't rely on memory pressure.
-  ASSERT_TRUE(sys_stats_captured);
-}
-
-// Disable this test:
-// 1. On cuttlefish (x86-kvm). It's too slow when running on GCE (b/171771440).
-//    We cannot change the length of the production code in
-//    CanReadKernelSymbolAddresses() to deal with it.
-// 2. On user (i.e. non-userdebug) builds. As that doesn't work there by design.
-// 3. On ARM builds, because they fail on our CI.
-#if (PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD) && defined(__i386__)) || \
-    defined(__arm__)
-#define MAYBE_KernelAddressSymbolization DISABLED_KernelAddressSymbolization
-#else
-#define MAYBE_KernelAddressSymbolization KernelAddressSymbolization
-#endif
-TEST_F(PerfettoTest, MAYBE_KernelAddressSymbolization) {
-  // On Android in-tree builds (TreeHugger): this test must always run to
-  // prevent selinux / property-related regressions. However it can run only on
-  // userdebug.
-  // On standalone builds and Linux, this can be optionally skipped because
-  // there it requires root to lower kptr_restrict.
-#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
-  if (!IsDebuggableBuild())
-    GTEST_SKIP();
-#else
-  if (geteuid() != 0)
-    GTEST_SKIP();
-#endif
-
-  base::TestTaskRunner task_runner;
-
-  TestHelper helper(&task_runner);
-  helper.StartServiceIfRequired();
-
-#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
-  ProbesProducerThread probes(TEST_PRODUCER_SOCK_NAME);
-  probes.Connect();
-#endif
-
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-
-  TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(1024);
-
-  auto* ds_config = trace_config.add_data_sources()->mutable_config();
-  ds_config->set_name("linux.ftrace");
-  protos::gen::FtraceConfig ftrace_cfg;
-  ftrace_cfg.set_symbolize_ksyms(true);
-  ftrace_cfg.set_initialize_ksyms_synchronously_for_testing(true);
-  ds_config->set_ftrace_config_raw(ftrace_cfg.SerializeAsString());
-
-  helper.StartTracing(trace_config);
-
-  // Synchronize with the ftrace data source. The kernel symbol map is loaded
-  // at this point.
-  helper.FlushAndWait(kDefaultTestTimeoutMs);
-  helper.DisableTracing();
-  helper.WaitForTracingDisabled();
-  helper.ReadData();
-  helper.WaitForReadData();
-
-  const auto& packets = helper.trace();
-  ASSERT_GT(packets.size(), 0u);
-
-  int symbols_parsed = -1;
-  for (const auto& packet : packets) {
-    if (!packet.has_ftrace_stats())
-      continue;
-    if (packet.ftrace_stats().phase() != protos::gen::FtraceStats::END_OF_TRACE)
-      continue;
-    symbols_parsed =
-        static_cast<int>(packet.ftrace_stats().kernel_symbols_parsed());
-  }
-  ASSERT_GT(symbols_parsed, 100);
-}
-
-TEST_F(PerfettoTest, AndroidOnly(TestBatteryTracing)) {
-  base::TestTaskRunner task_runner;
-
-  TestHelper helper(&task_runner);
-  helper.StartServiceIfRequired();
-
-#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
-  ProbesProducerThread probes(TEST_PRODUCER_SOCK_NAME);
-  probes.Connect();
-#else
-  base::ignore_result(TEST_PRODUCER_SOCK_NAME);
-#endif
-
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-
-  TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(128);
-  trace_config.set_duration_ms(3000);
-
-  auto* ds_config = trace_config.add_data_sources()->mutable_config();
-  ds_config->set_name("android.power");
-  ds_config->set_target_buffer(0);
-
-  using protos::pbzero::AndroidPowerConfig;
-  protozero::HeapBuffered<AndroidPowerConfig> power_config;
-  power_config->set_battery_poll_ms(250);
-  power_config->add_battery_counters(
-      AndroidPowerConfig::BATTERY_COUNTER_CHARGE);
-  power_config->add_battery_counters(
-      AndroidPowerConfig::BATTERY_COUNTER_CAPACITY_PERCENT);
-  ds_config->set_android_power_config_raw(power_config.SerializeAsString());
-
-  helper.StartTracing(trace_config);
-  helper.WaitForTracingDisabled();
-
-  helper.ReadData();
-  helper.WaitForReadData();
-
-  const auto& packets = helper.trace();
-  ASSERT_GT(packets.size(), 0u);
-
-  bool has_battery_packet = false;
-  for (const auto& packet : packets) {
-    if (!packet.has_battery())
-      continue;
-    has_battery_packet = true;
-    // Unfortunately we cannot make any assertions on the charge counter.
-    // On some devices it can reach negative values (b/64685329).
-    EXPECT_GE(packet.battery().capacity_percent(), 0.f);
-    EXPECT_LE(packet.battery().capacity_percent(), 100.f);
-  }
-
-  ASSERT_TRUE(has_battery_packet);
-}
-
-TEST_F(PerfettoTest, TestFakeProducer) {
-  base::TestTaskRunner task_runner;
-
-  TestHelper helper(&task_runner);
-  helper.StartServiceIfRequired();
-  helper.ConnectFakeProducer();
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-
-  TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(1024);
-  trace_config.set_duration_ms(200);
-
-  auto* ds_config = trace_config.add_data_sources()->mutable_config();
-  ds_config->set_name("android.perfetto.FakeProducer");
-  ds_config->set_target_buffer(0);
-
-  static constexpr size_t kNumPackets = 11;
-  static constexpr uint32_t kRandomSeed = 42;
-  static constexpr uint32_t kMsgSize = 1024;
-  ds_config->mutable_for_testing()->set_seed(kRandomSeed);
-  ds_config->mutable_for_testing()->set_message_count(kNumPackets);
-  ds_config->mutable_for_testing()->set_message_size(kMsgSize);
-  ds_config->mutable_for_testing()->set_send_batch_on_register(true);
-
-  helper.StartTracing(trace_config);
-  helper.WaitForTracingDisabled();
-
-  helper.ReadData();
-  helper.WaitForReadData();
-
-  const auto& packets = helper.trace();
-  ASSERT_EQ(packets.size(), kNumPackets);
-
-  std::minstd_rand0 rnd_engine(kRandomSeed);
-  for (const auto& packet : packets) {
-    ASSERT_TRUE(packet.has_for_testing());
-    ASSERT_EQ(packet.for_testing().seq_value(), rnd_engine());
-  }
-}
-
-TEST_F(PerfettoTest, VeryLargePackets) {
-  base::TestTaskRunner task_runner;
-
-  TestHelper helper(&task_runner);
-  helper.StartServiceIfRequired();
-  helper.ConnectFakeProducer();
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-
-  TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(4096 * 10);
-  trace_config.set_duration_ms(500);
-
-  auto* ds_config = trace_config.add_data_sources()->mutable_config();
-  ds_config->set_name("android.perfetto.FakeProducer");
-  ds_config->set_target_buffer(0);
-
-  static constexpr size_t kNumPackets = 7;
-  static constexpr uint32_t kRandomSeed = 42;
-  static constexpr uint32_t kMsgSize = 1024 * 1024 - 42;
-  ds_config->mutable_for_testing()->set_seed(kRandomSeed);
-  ds_config->mutable_for_testing()->set_message_count(kNumPackets);
-  ds_config->mutable_for_testing()->set_message_size(kMsgSize);
-  ds_config->mutable_for_testing()->set_send_batch_on_register(true);
-
-  helper.StartTracing(trace_config);
-  helper.WaitForTracingDisabled();
-
-  helper.ReadData();
-  helper.WaitForReadData(/* read_count */ 0, /* timeout_ms */ 10000);
-
-  const auto& packets = helper.trace();
-  ASSERT_EQ(packets.size(), kNumPackets);
-
-  std::minstd_rand0 rnd_engine(kRandomSeed);
-  for (const auto& packet : packets) {
-    ASSERT_TRUE(packet.has_for_testing());
-    ASSERT_EQ(packet.for_testing().seq_value(), rnd_engine());
-    size_t msg_size = packet.for_testing().str().size();
-    ASSERT_EQ(kMsgSize, msg_size);
-    for (size_t i = 0; i < msg_size; i++)
-      ASSERT_EQ(i < msg_size - 1 ? '.' : 0, packet.for_testing().str()[i]);
-  }
-}
-
-// This is a regression test see b/169051440 for context.
-//
-// In this test we ensure that traced will not crash if a Producer stops
-// responding or draining the socket (i.e. after we fill up the IPC buffer
-// traced doesn't block on trying to write to the IPC buffer and watchdog
-// doesn't kill it).
-TEST_F(PerfettoTest, UnresponsiveProducer) {
-  base::TestTaskRunner task_runner;
-
-  TestHelper helper(&task_runner);
-  helper.StartServiceIfRequired();
-  auto* producer = helper.ConnectFakeProducer();
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-
-  TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(4096 * 10);
-  trace_config.set_duration_ms(100);
-  trace_config.set_flush_timeout_ms(1);
-  trace_config.set_data_source_stop_timeout_ms(1);
-
-  auto* ds_config = trace_config.add_data_sources()->mutable_config();
-  ds_config->set_name("android.perfetto.FakeProducer");
-
-  static constexpr size_t kNumPackets = 1;
-  static constexpr uint32_t kRandomSeed = 42;
-  static constexpr uint32_t kMsgSize = 1024 * 1024 - 42;
-  ds_config->mutable_for_testing()->set_seed(kRandomSeed);
-  ds_config->mutable_for_testing()->set_message_count(kNumPackets);
-  ds_config->mutable_for_testing()->set_message_size(kMsgSize);
-  ds_config->mutable_for_testing()->set_send_batch_on_register(true);
-
-  // This string is just used to make the StartDataSource IPC larger.
-  ds_config->set_legacy_config(std::string(8192, '.'));
-  ds_config->set_target_buffer(0);
-
-  // Run one legit trace, this ensures that the producer above is
-  // valid and correct and mirrors real life producers.
-  helper.StartTracing(trace_config);
-  helper.WaitForProducerEnabled();
-  helper.WaitForTracingDisabled();
-
-  helper.ReadData();
-  helper.WaitForReadData(/* read_count */ 0, /* timeout_ms */ 10000);
-
-  const auto& packets = helper.trace();
-  ASSERT_EQ(packets.size(), 1u);
-  ASSERT_TRUE(packets[0].has_for_testing());
-  ASSERT_FALSE(packets[0].for_testing().str().empty());
-  helper.FreeBuffers();
-
-  // Switch the producer to ignoring the IPC socket. On a pixel 4 it took 13
-  // traces to fill up the IPC buffer and cause traced to block (and eventually
-  // watchdog to kill it).
-  helper.producer_thread()->get()->RemoveFileDescriptorWatch(
-      producer->unix_socket_fd());
-
-  trace_config.set_duration_ms(1);
-  for (uint32_t i = 0u; i < 15u; i++) {
-    helper.StartTracing(trace_config, base::ScopedFile());
-    helper.WaitForTracingDisabled(/* timeout_ms = */ 20000);
-    helper.FreeBuffers();
-  }
-  // We need to readd the FileDescriptor (otherwise when the UnixSocket attempts
-  // to remove it a the FakeProducer is destroyed will hit a CHECK failure.
-  helper.producer_thread()->get()->AddFileDescriptorWatch(
-      producer->unix_socket_fd(), []() {});
-}
-
-TEST_F(PerfettoTest, DetachAndReattach) {
-  base::TestTaskRunner task_runner;
-
-  TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(1024);
-  trace_config.set_duration_ms(10000);  // Max timeout, session is ended before.
-  auto* ds_config = trace_config.add_data_sources()->mutable_config();
-  ds_config->set_name("android.perfetto.FakeProducer");
-  static constexpr size_t kNumPackets = 11;
-  ds_config->mutable_for_testing()->set_message_count(kNumPackets);
-  ds_config->mutable_for_testing()->set_message_size(32);
-
-  // Enable tracing and detach as soon as it gets started.
-  TestHelper helper(&task_runner);
-  helper.StartServiceIfRequired();
-  auto* fake_producer = helper.ConnectFakeProducer();
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-  helper.StartTracing(trace_config);
-
-  // Detach.
-  helper.DetachConsumer("key");
-
-  // Write data while detached.
-  helper.WaitForProducerEnabled();
-  auto on_data_written = task_runner.CreateCheckpoint("data_written");
-  fake_producer->ProduceEventBatch(helper.WrapTask(on_data_written));
-  task_runner.RunUntilCheckpoint("data_written");
-
-  // Then reattach the consumer.
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-  helper.AttachConsumer("key");
-
-  helper.DisableTracing();
-  helper.WaitForTracingDisabled();
-
-  helper.ReadData();
-  helper.WaitForReadData();
-  const auto& packets = helper.trace();
-  ASSERT_EQ(packets.size(), kNumPackets);
-}
-
-// Tests that a detached trace session is automatically cleaned up if the
-// consumer doesn't re-attach before its expiration time.
-TEST_F(PerfettoTest, ReattachFailsAfterTimeout) {
-  base::TestTaskRunner task_runner;
-
-  TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(1024);
-  trace_config.set_duration_ms(250);
-  trace_config.set_write_into_file(true);
-  trace_config.set_file_write_period_ms(100000);
-  auto* ds_config = trace_config.add_data_sources()->mutable_config();
-  ds_config->set_name("android.perfetto.FakeProducer");
-  ds_config->mutable_for_testing()->set_message_count(1);
-  ds_config->mutable_for_testing()->set_message_size(32);
-  ds_config->mutable_for_testing()->set_send_batch_on_register(true);
-
-  // Enable tracing and detach as soon as it gets started.
-  TestHelper helper(&task_runner);
-  helper.StartServiceIfRequired();
-  helper.ConnectFakeProducer();
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-
-  auto pipe_pair = base::Pipe::Create();
-  helper.StartTracing(trace_config, std::move(pipe_pair.wr));
-
-  // Detach.
-  helper.DetachConsumer("key");
-
-  // Use the file EOF (write end closed) as a way to detect when the trace
-  // session is ended.
-  char buf[1024];
-  while (PERFETTO_EINTR(read(*pipe_pair.rd, buf, sizeof(buf))) > 0) {
-  }
-
-  // Give some margin for the tracing service to destroy the session.
-  usleep(250000);
-
-  // Reconnect and find out that it's too late and the session is gone.
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-  EXPECT_FALSE(helper.AttachConsumer("key"));
-}
-
-TEST_F(PerfettoTest, TestProducerProvidedSMB) {
-  base::TestTaskRunner task_runner;
-
-  TestHelper helper(&task_runner);
-  helper.CreateProducerProvidedSmb();
-
-  protos::gen::TestConfig test_config;
-  test_config.set_seed(42);
-  test_config.set_message_count(1);
-  test_config.set_message_size(1024);
-  test_config.set_send_batch_on_register(true);
-
-  // Write a first batch before connection.
-  helper.ProduceStartupEventBatch(test_config);
-
-  helper.StartServiceIfRequired();
-  helper.ConnectFakeProducer();
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-
-  TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(1024);
-  trace_config.set_duration_ms(200);
-
-  auto* ds_config = trace_config.add_data_sources()->mutable_config();
-  ds_config->set_name("android.perfetto.FakeProducer");
-  ds_config->set_target_buffer(0);
-  *ds_config->mutable_for_testing() = test_config;
-
-  // The data source is configured to emit another batch when it is started via
-  // send_batch_on_register in the TestConfig.
-  helper.StartTracing(trace_config);
-  helper.WaitForTracingDisabled();
-
-  EXPECT_TRUE(helper.IsShmemProvidedByProducer());
-
-  helper.ReadData();
-  helper.WaitForReadData();
-
-  const auto& packets = helper.trace();
-  // We should have produced two batches, one before the producer connected and
-  // another one when the data source was started.
-  ASSERT_EQ(packets.size(), 2u);
-  ASSERT_TRUE(packets[0].has_for_testing());
-  ASSERT_TRUE(packets[1].has_for_testing());
-}
-
-// Regression test for b/153142114.
-TEST_F(PerfettoTest, QueryServiceStateLargeResponse) {
-  base::TestTaskRunner task_runner;
-
-  TestHelper helper(&task_runner);
-  helper.StartServiceIfRequired();
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-
-  FakeProducer* producer = helper.ConnectFakeProducer();
-
-  // Register 5 data sources with very large descriptors. Each descriptor will
-  // max out the IPC message size, so that the service has no other choice
-  // than chunking them.
-  std::map<std::string, std::string> ds_expected;
-  for (int i = 0; i < 5; i++) {
-    DataSourceDescriptor dsd;
-    std::string name = "big_ds_" + std::to_string(i);
-    dsd.set_name(name);
-    std::string descriptor(ipc::kIPCBufferSize - 64,
-                           static_cast<char>((' ' + i) % 64));
-    dsd.set_track_event_descriptor_raw(descriptor);
-    ds_expected[name] = std::move(descriptor);
-    producer->RegisterDataSource(dsd);
-  }
-
-  // Linearize the producer with the service. We need to make sure that all the
-  // RegisterDataSource() calls above have been seen by the service before
-  // continuing.
-  helper.SyncAndWaitProducer();
-
-  // Now invoke QueryServiceState() and wait for the reply. The service will
-  // send 6 (1 + 5) IPCs which will be merged together in
-  // producer_ipc_client_impl.cc.
-  auto svc_state = helper.QueryServiceStateAndWait();
-
-  ASSERT_GE(svc_state.producers().size(), 1u);
-
-  std::map<std::string, std::string> ds_found;
-  for (const auto& ds : svc_state.data_sources()) {
-    if (!base::StartsWith(ds.ds_descriptor().name(), "big_ds_"))
-      continue;
-    ds_found[ds.ds_descriptor().name()] =
-        ds.ds_descriptor().track_event_descriptor_raw();
-  }
-  EXPECT_THAT(ds_found, ElementsAreArray(ds_expected));
-}
-
-TEST_F(PerfettoTest, SaveForBugreport) {
-  base::TestTaskRunner task_runner;
-
-  TestHelper helper(&task_runner);
-  helper.StartServiceIfRequired();
-  helper.ConnectFakeProducer();
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-
-  TraceConfig trace_config;
-  SetTraceConfigForBugreportTest(&trace_config);
-
-  helper.StartTracing(trace_config);
-  helper.WaitForProducerEnabled();
-
-  EXPECT_TRUE(helper.SaveTraceForBugreportAndWait());
-  helper.WaitForTracingDisabled();
-
-  VerifyBugreportTraceContents();
-
-  // Now read the trace returned to the consumer via ReadBuffers. This should
-  // be always empty because --save-for-bugreport takes it over and makes the
-  // buffers unreadable by the consumer (by virtue of force-setting
-  // write_into_file, which is incompatible with ReadBuffers()). The only
-  // content should be the |seized_for_bugreport| flag.
-  helper.ReadData();
-  helper.WaitForReadData();
-  const auto& packets = helper.full_trace();
-  ASSERT_EQ(packets.size(), 1u);
-  for (const auto& p : packets) {
-    ASSERT_TRUE(p.has_service_event());
-    ASSERT_TRUE(p.service_event().seized_for_bugreport());
-  }
-}
-
-// Tests that the SaveForBugreport logic works also for traces with
-// write_into_file = true (with a passed file descriptor).
-TEST_F(PerfettoTest, SaveForBugreport_WriteIntoFile) {
-  base::TestTaskRunner task_runner;
-
-  TestHelper helper(&task_runner);
-  helper.StartServiceIfRequired();
-  helper.ConnectFakeProducer();
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-
-  TraceConfig trace_config;
-  SetTraceConfigForBugreportTest(&trace_config);
-  trace_config.set_file_write_period_ms(60000);  // Will never hit this.
-  trace_config.set_write_into_file(true);
-
-  auto pipe_pair = base::Pipe::Create();
-  helper.StartTracing(trace_config, std::move(pipe_pair.wr));
-  helper.WaitForProducerEnabled();
-
-  EXPECT_TRUE(helper.SaveTraceForBugreportAndWait());
-  helper.WaitForTracingDisabled();
-
-  VerifyBugreportTraceContents();
-
-  // Now read the original file descriptor passed in.
-  std::string trace_bytes;
-  ASSERT_TRUE(base::ReadPlatformHandle(*pipe_pair.rd, &trace_bytes));
-  protos::gen::Trace trace;
-  ASSERT_TRUE(trace.ParseFromString(trace_bytes));
-  ASSERT_EQ(trace.packet().size(), 1u);
-  for (const auto& p : trace.packet()) {
-    ASSERT_TRUE(p.has_service_event());
-    ASSERT_TRUE(p.service_event().seized_for_bugreport());
-  }
-}
-
-// Tests that SaveTraceForBugreport() works also if the trace has triggers
-// defined and those triggers have not been hit. This is a regression test for
-// b/188008375 .
-#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
-// Disabled due to b/191940560
-#define MAYBE_SaveForBugreport_Triggers DISABLED_SaveForBugreport_Triggers
-#else
-#define MAYBE_SaveForBugreport_Triggers SaveForBugreport_Triggers
-#endif
-TEST_F(PerfettoTest, MAYBE_SaveForBugreport_Triggers) {
-  base::TestTaskRunner task_runner;
-
-  TestHelper helper(&task_runner);
-  helper.StartServiceIfRequired();
-  helper.ConnectFakeProducer();
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-
-  TraceConfig trace_config;
-  SetTraceConfigForBugreportTest(&trace_config);
-  trace_config.set_duration_ms(0);  // set_trigger_timeout_ms is used instead.
-  auto* trigger_config = trace_config.mutable_trigger_config();
-  trigger_config->set_trigger_timeout_ms(8.64e+7);
-  trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
-  auto* trigger = trigger_config->add_triggers();
-  trigger->set_name("trigger_name");
-  trigger->set_stop_delay_ms(1);
-
-  helper.StartTracing(trace_config);
-  helper.WaitForProducerEnabled();
-
-  EXPECT_TRUE(helper.SaveTraceForBugreportAndWait());
-  helper.WaitForTracingDisabled();
-
-  VerifyBugreportTraceContents();
-
-  // Now read the original trace.
-  helper.ReadData();
-  helper.WaitForReadData();
-  const auto& packets = helper.full_trace();
-  ASSERT_EQ(packets.size(), 1u);
-  for (const auto& p : packets) {
-    ASSERT_TRUE(p.has_service_event());
-    ASSERT_TRUE(p.service_event().seized_for_bugreport());
-  }
-}
-
-// Regression test for b/195065199. Check that trace filtering works when a
-// packet size exceeds the IPC limit. This tests that the tracing service, when
-// reassembling packets after filtering, doesn't "overglue" them. They still
-// need to be slice-able to fit into the ReadBuffers ipc.
-TEST_F(PerfettoTest, TraceFilterLargePackets) {
-  base::TestTaskRunner task_runner;
-  TestHelper helper(&task_runner);
-
-  helper.StartServiceIfRequired();
-  helper.ConnectFakeProducer();
-  helper.ConnectConsumer();
-  helper.WaitForConsumerConnect();
-
-  TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(1024 * 16);
-  trace_config.set_duration_ms(500);
-  auto* prod_config = trace_config.add_producers();
-  prod_config->set_producer_name("android.perfetto.FakeProducer");
-  prod_config->set_shm_size_kb(1024 * 16);
-  prod_config->set_page_size_kb(32);
-
-  static constexpr size_t kNumPackets = 3;
-  static constexpr uint32_t kRandomSeed = 42;
-  static constexpr uint32_t kMsgSize = 8 * ipc::kIPCBufferSize;
-  auto* ds_config = trace_config.add_data_sources()->mutable_config();
-  ds_config->set_name("android.perfetto.FakeProducer");
-  auto* test_config = ds_config->mutable_for_testing();
-  test_config->set_seed(kRandomSeed);
-  test_config->set_message_count(kNumPackets);
-  test_config->set_message_size(kMsgSize);
-  test_config->set_send_batch_on_register(true);
-
-  protozero::FilterBytecodeGenerator filt;
-  // Message 0: root Trace proto.
-  filt.AddNestedField(1 /* root trace.packet*/, 1);
-  filt.EndMessage();
-
-  // Message 1: TracePacket proto. Allow all fields.
-  filt.AddSimpleFieldRange(1, 1000);
-  filt.EndMessage();
-
-  trace_config.mutable_trace_filter()->set_bytecode(filt.Serialize());
-
-  // The data source is configured to emit another batch when it is started via
-  // send_batch_on_register in the TestConfig.
-  helper.StartTracing(trace_config);
-  helper.WaitForTracingDisabled();
-
-  helper.ReadData();
-  helper.WaitForReadData(/* read_count */ 0, /* timeout_ms */ 10000);
-
-  const std::vector<protos::gen::TracePacket>& packets = helper.trace();
-  EXPECT_EQ(packets.size(), kNumPackets);
-  EXPECT_THAT(packets,
-              Each(Property(&protos::gen::TracePacket::has_for_testing, true)));
-  EXPECT_THAT(
-      packets,
-      Each(Property(&protos::gen::TracePacket::for_testing,
-                    Property(&protos::gen::TestEvent::str, SizeIs(kMsgSize)))));
-}
-
-TEST_F(PerfettoCmdlineTest, InvalidCases) {
-  std::string cfg("duration_ms: 100");
-
-  auto invalid_arg = ExecPerfetto({"--invalid-arg"});
-  auto empty_config = ExecPerfetto({"-c", "-", "-o", "-"}, "");
-
-  // Cannot make assertions on --dropbox because on standalone builds it fails
-  // prematurely due to lack of dropbox.
-  auto missing_dropbox =
-      ExecPerfetto({"-c", "-", "--txt", "-o", "-", "--dropbox=foo"}, cfg);
-  auto either_out_or_dropbox = ExecPerfetto({"-c", "-", "--txt"}, cfg);
-
-  // Disallow mixing simple and file config.
-  auto simple_and_file_1 =
-      ExecPerfetto({"-o", "-", "-c", "-", "-t", "2s"}, cfg);
-  auto simple_and_file_2 =
-      ExecPerfetto({"-o", "-", "-c", "-", "-b", "2m"}, cfg);
-  auto simple_and_file_3 =
-      ExecPerfetto({"-o", "-", "-c", "-", "-s", "2m"}, cfg);
-
-  // Invalid --attach / --detach cases.
-  auto invalid_stop =
-      ExecPerfetto({"-c", "-", "--txt", "-o", "-", "--stop"}, cfg);
-  auto attach_and_config_1 =
-      ExecPerfetto({"-c", "-", "--txt", "-o", "-", "--attach=foo"}, cfg);
-  auto attach_and_config_2 =
-      ExecPerfetto({"-t", "2s", "-o", "-", "--attach=foo"}, cfg);
-  auto attach_needs_argument = ExecPerfetto({"--attach"}, cfg);
-  auto detach_needs_argument =
-      ExecPerfetto({"-t", "2s", "-o", "-", "--detach"}, cfg);
-  auto detach_without_out_or_dropbox =
-      ExecPerfetto({"-t", "2s", "--detach=foo"}, cfg);
-
-  // Cannot trace and use --query.
-  auto trace_and_query_1 = ExecPerfetto({"-t", "2s", "--query"}, cfg);
-  auto trace_and_query_2 = ExecPerfetto({"-c", "-", "--query"}, cfg);
-
-  // Ensure all Exec:: calls have been saved to prevent deadlocks.
-  StartServiceIfRequiredNoNewExecsAfterThis();
-
-  EXPECT_EQ(1, invalid_arg.Run(&stderr_));
-
-  EXPECT_EQ(1, empty_config.Run(&stderr_));
-  EXPECT_THAT(stderr_, HasSubstr("TraceConfig is empty"));
-
-  // Cannot make assertions on --upload because on standalone builds it fails
-  // prematurely due to lack of dropbox.
-  EXPECT_EQ(1, missing_dropbox.Run(&stderr_));
-
-  EXPECT_EQ(1, either_out_or_dropbox.Run(&stderr_));
-  EXPECT_THAT(stderr_, HasSubstr("Either --out or --upload"));
-
-  // Disallow mixing simple and file config.
-  EXPECT_EQ(1, simple_and_file_1.Run(&stderr_));
-  EXPECT_THAT(stderr_, HasSubstr("Cannot specify both -c"));
-
-  EXPECT_EQ(1, simple_and_file_2.Run(&stderr_));
-  EXPECT_THAT(stderr_, HasSubstr("Cannot specify both -c"));
-
-  EXPECT_EQ(1, simple_and_file_3.Run(&stderr_));
-  EXPECT_THAT(stderr_, HasSubstr("Cannot specify both -c"));
-
-  // Invalid --attach / --detach cases.
-  EXPECT_EQ(1, invalid_stop.Run(&stderr_));
-  EXPECT_THAT(stderr_, HasSubstr("--stop is supported only in combination"));
-
-  EXPECT_EQ(1, attach_and_config_1.Run(&stderr_));
-  EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
-
-  EXPECT_EQ(1, attach_and_config_2.Run(&stderr_));
-  EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
-
-  EXPECT_EQ(1, attach_needs_argument.Run(&stderr_));
-  EXPECT_THAT(stderr_, ContainsRegex("option.*--attach.*requires an argument"));
-
-  EXPECT_EQ(1, detach_needs_argument.Run(&stderr_));
-  EXPECT_THAT(stderr_, ContainsRegex("option.*--detach.*requires an argument"));
-
-  EXPECT_EQ(1, detach_without_out_or_dropbox.Run(&stderr_));
-  EXPECT_THAT(stderr_, HasSubstr("--out or --upload is required"));
-
-  // Cannot trace and use --query.
-  EXPECT_EQ(1, trace_and_query_1.Run(&stderr_));
-  EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
-
-  EXPECT_EQ(1, trace_and_query_2.Run(&stderr_));
-  EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
-}
-
-TEST_F(PerfettoCmdlineTest, Version) {
-  auto perfetto = ExecPerfetto({"--version"});
-  EXPECT_EQ(0, perfetto.Run(&stderr_)) << stderr_;
-}
-
-TEST_F(PerfettoCmdlineTest, TxtConfig) {
-  std::string cfg("duration_ms: 100");
-  auto perfetto = ExecPerfetto({"-c", "-", "--txt", "-o", "-"}, cfg);
-  StartServiceIfRequiredNoNewExecsAfterThis();
-  EXPECT_EQ(0, perfetto.Run(&stderr_)) << stderr_;
-}
-
-TEST_F(PerfettoCmdlineTest, SimpleConfig) {
-  auto perfetto = ExecPerfetto({"-o", "-", "-c", "-", "-t", "100ms"});
-  StartServiceIfRequiredNoNewExecsAfterThis();
-  EXPECT_EQ(0, perfetto.Run(&stderr_)) << stderr_;
-}
-
-TEST_F(PerfettoCmdlineTest, DetachAndAttach) {
-  auto attach_to_not_existing = ExecPerfetto({"--attach=not_existent"});
-
-  std::string cfg("duration_ms: 10000; write_into_file: true");
-  auto detach_valid_stop =
-      ExecPerfetto({"-o", "-", "-c", "-", "--txt", "--detach=valid_stop"}, cfg);
-  auto stop_valid_stop = ExecPerfetto({"--attach=valid_stop", "--stop"});
-
-  StartServiceIfRequiredNoNewExecsAfterThis();
-
-  EXPECT_NE(0, attach_to_not_existing.Run(&stderr_));
-  EXPECT_THAT(stderr_, HasSubstr("Session re-attach failed"));
-
-  EXPECT_EQ(0, detach_valid_stop.Run(&stderr_)) << stderr_;
-  EXPECT_EQ(0, stop_valid_stop.Run(&stderr_));
-}
-
-TEST_F(PerfettoCmdlineTest, StartTracingTrigger) {
-  // See |message_count| and |message_size| in the TraceConfig above.
-  constexpr size_t kMessageCount = 11;
-  constexpr size_t kMessageSize = 32;
-  protos::gen::TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(1024);
-  auto* ds_config = trace_config.add_data_sources()->mutable_config();
-  ds_config->set_name("android.perfetto.FakeProducer");
-  ds_config->mutable_for_testing()->set_message_count(kMessageCount);
-  ds_config->mutable_for_testing()->set_message_size(kMessageSize);
-  auto* trigger_cfg = trace_config.mutable_trigger_config();
-  trigger_cfg->set_trigger_mode(
-      protos::gen::TraceConfig::TriggerConfig::START_TRACING);
-  trigger_cfg->set_trigger_timeout_ms(15000);
-  auto* trigger = trigger_cfg->add_triggers();
-  trigger->set_name("trigger_name");
-  // |stop_delay_ms| must be long enough that we can write the packets in
-  // before the trace finishes. This has to be long enough for the slowest
-  // emulator. But as short as possible to prevent the test running a long
-  // time.
-  trigger->set_stop_delay_ms(500);
-
-  // We have to construct all the processes we want to fork before we start the
-  // service with |StartServiceIfRequired()|. this is because it is unsafe
-  // (could deadlock) to fork after we've spawned some threads which might
-  // printf (and thus hold locks).
-  const std::string path = RandomTraceFileName();
-  auto perfetto_proc = ExecPerfetto(
-      {
-          "-o",
-          path,
-          "-c",
-          "-",
-      },
-      trace_config.SerializeAsString());
-
-  auto trigger_proc = ExecTrigger({"trigger_name"});
-
-  // Start the service and connect a simple fake producer.
-  StartServiceIfRequiredNoNewExecsAfterThis();
-
-  auto* fake_producer = ConnectFakeProducer();
-  EXPECT_TRUE(fake_producer);
-
-  // Start a background thread that will deliver the config now that we've
-  // started the service. See |perfetto_proc| above for the args passed.
-  std::thread background_trace([&perfetto_proc]() {
-    std::string stderr_str;
-    EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
-  });
-
-  WaitForProducerSetup();
-  EXPECT_EQ(0, trigger_proc.Run(&stderr_));
-
-  // Wait for the producer to start, and then write out 11 packets.
-  WaitForProducerEnabled();
-  auto on_data_written = task_runner_.CreateCheckpoint("data_written");
-  fake_producer->ProduceEventBatch(WrapTask(on_data_written));
-  task_runner_.RunUntilCheckpoint("data_written");
-  background_trace.join();
-
-  std::string trace_str;
-  base::ReadFile(path, &trace_str);
-  protos::gen::Trace trace;
-  ASSERT_TRUE(trace.ParseFromString(trace_str));
-  size_t for_testing_packets = 0;
-  size_t trigger_packets = 0;
-  size_t trace_config_packets = 0;
-  for (const auto& packet : trace.packet()) {
-    if (packet.has_trace_config()) {
-      // Ensure the trace config properly includes the trigger mode we set.
-      auto kStartTrig = protos::gen::TraceConfig::TriggerConfig::START_TRACING;
-      EXPECT_EQ(kStartTrig,
-                packet.trace_config().trigger_config().trigger_mode());
-      ++trace_config_packets;
-    } else if (packet.has_trigger()) {
-      // validate that the triggers are properly added to the trace.
-      EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
-      ++trigger_packets;
-    } else if (packet.has_for_testing()) {
-      // Make sure that the data size is correctly set based on what we
-      // requested.
-      EXPECT_EQ(kMessageSize, packet.for_testing().str().size());
-      ++for_testing_packets;
-    }
-  }
-  EXPECT_EQ(trace_config_packets, 1u);
-  EXPECT_EQ(trigger_packets, 1u);
-  EXPECT_EQ(for_testing_packets, kMessageCount);
-}
-
-TEST_F(PerfettoCmdlineTest, StopTracingTrigger) {
-  // See |message_count| and |message_size| in the TraceConfig above.
-  constexpr size_t kMessageCount = 11;
-  constexpr size_t kMessageSize = 32;
-  protos::gen::TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(1024);
-  auto* ds_config = trace_config.add_data_sources()->mutable_config();
-  ds_config->set_name("android.perfetto.FakeProducer");
-  ds_config->mutable_for_testing()->set_message_count(kMessageCount);
-  ds_config->mutable_for_testing()->set_message_size(kMessageSize);
-  auto* trigger_cfg = trace_config.mutable_trigger_config();
-  trigger_cfg->set_trigger_mode(
-      protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
-  trigger_cfg->set_trigger_timeout_ms(15000);
-  auto* trigger = trigger_cfg->add_triggers();
-  trigger->set_name("trigger_name");
-  // |stop_delay_ms| must be long enough that we can write the packets in
-  // before the trace finishes. This has to be long enough for the slowest
-  // emulator. But as short as possible to prevent the test running a long
-  // time.
-  trigger->set_stop_delay_ms(500);
-  trigger = trigger_cfg->add_triggers();
-  trigger->set_name("trigger_name_3");
-  trigger->set_stop_delay_ms(60000);
-
-  // We have to construct all the processes we want to fork before we start the
-  // service with |StartServiceIfRequired()|. this is because it is unsafe
-  // (could deadlock) to fork after we've spawned some threads which might
-  // printf (and thus hold locks).
-  const std::string path = RandomTraceFileName();
-  auto perfetto_proc = ExecPerfetto(
-      {
-          "-o",
-          path,
-          "-c",
-          "-",
-      },
-      trace_config.SerializeAsString());
-
-  auto trigger_proc =
-      ExecTrigger({"trigger_name_2", "trigger_name", "trigger_name_3"});
-
-  // Start the service and connect a simple fake producer.
-  StartServiceIfRequiredNoNewExecsAfterThis();
-  auto* fake_producer = ConnectFakeProducer();
-  EXPECT_TRUE(fake_producer);
-
-  // Start a background thread that will deliver the config now that we've
-  // started the service. See |perfetto_proc| above for the args passed.
-  std::thread background_trace([&perfetto_proc]() {
-    std::string stderr_str;
-    EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
-  });
-
-  WaitForProducerEnabled();
-  // Wait for the producer to start, and then write out 11 packets, before the
-  // trace actually starts (the trigger is seen).
-  auto on_data_written = task_runner_.CreateCheckpoint("data_written_1");
-  fake_producer->ProduceEventBatch(WrapTask(on_data_written));
-  task_runner_.RunUntilCheckpoint("data_written_1");
-
-  EXPECT_EQ(0, trigger_proc.Run(&stderr_)) << "stderr: " << stderr_;
-
-  background_trace.join();
-
-  std::string trace_str;
-  base::ReadFile(path, &trace_str);
-  protos::gen::Trace trace;
-  ASSERT_TRUE(trace.ParseFromString(trace_str));
-  bool seen_first_trigger = false;
-  size_t for_testing_packets = 0;
-  size_t trigger_packets = 0;
-  size_t trace_config_packets = 0;
-  for (const auto& packet : trace.packet()) {
-    if (packet.has_trace_config()) {
-      // Ensure the trace config properly includes the trigger mode we set.
-      auto kStopTrig = protos::gen::TraceConfig::TriggerConfig::STOP_TRACING;
-      EXPECT_EQ(kStopTrig,
-                packet.trace_config().trigger_config().trigger_mode());
-      ++trace_config_packets;
-    } else if (packet.has_trigger()) {
-      // validate that the triggers are properly added to the trace.
-      if (!seen_first_trigger) {
-        EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
-        seen_first_trigger = true;
-      } else {
-        EXPECT_EQ("trigger_name_3", packet.trigger().trigger_name());
-      }
-      ++trigger_packets;
-    } else if (packet.has_for_testing()) {
-      // Make sure that the data size is correctly set based on what we
-      // requested.
-      EXPECT_EQ(kMessageSize, packet.for_testing().str().size());
-      ++for_testing_packets;
-    }
-  }
-  EXPECT_EQ(trace_config_packets, 1u);
-  EXPECT_EQ(trigger_packets, 2u);
-  EXPECT_EQ(for_testing_packets, kMessageCount);
-}
-
-// Dropbox on the commandline client only works on android builds. So disable
-// this test on all other builds.
-TEST_F(PerfettoCmdlineTest, AndroidOnly(NoDataNoFileWithoutTrigger)) {
-  // See |message_count| and |message_size| in the TraceConfig above.
-  constexpr size_t kMessageCount = 11;
-  constexpr size_t kMessageSize = 32;
-  protos::gen::TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(1024);
-  trace_config.set_allow_user_build_tracing(true);
-  auto* incident_config = trace_config.mutable_incident_report_config();
-  incident_config->set_destination_package("foo.bar.baz");
-  auto* ds_config = trace_config.add_data_sources()->mutable_config();
-  ds_config->set_name("android.perfetto.FakeProducer");
-  ds_config->mutable_for_testing()->set_message_count(kMessageCount);
-  ds_config->mutable_for_testing()->set_message_size(kMessageSize);
-  auto* trigger_cfg = trace_config.mutable_trigger_config();
-  trigger_cfg->set_trigger_mode(
-      protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
-  trigger_cfg->set_trigger_timeout_ms(1000);
-  auto* trigger = trigger_cfg->add_triggers();
-  trigger->set_name("trigger_name");
-  // |stop_delay_ms| must be long enough that we can write the packets in
-  // before the trace finishes. This has to be long enough for the slowest
-  // emulator. But as short as possible to prevent the test running a long
-  // time.
-  trigger->set_stop_delay_ms(500);
-  trigger = trigger_cfg->add_triggers();
-
-  // We have to construct all the processes we want to fork before we start the
-  // service with |StartServiceIfRequired()|. this is because it is unsafe
-  // (could deadlock) to fork after we've spawned some threads which might
-  // printf (and thus hold locks).
-  const std::string path = RandomTraceFileName();
-  auto perfetto_proc = ExecPerfetto(
-      {
-          "--dropbox",
-          "TAG",
-          "--no-guardrails",
-          "-c",
-          "-",
-      },
-      trace_config.SerializeAsString());
-
-  StartServiceIfRequiredNoNewExecsAfterThis();
-  auto* fake_producer = ConnectFakeProducer();
-  EXPECT_TRUE(fake_producer);
-
-  std::string stderr_str;
-  std::thread background_trace([&perfetto_proc, &stderr_str]() {
-    EXPECT_EQ(0, perfetto_proc.Run(&stderr_str));
-  });
-  background_trace.join();
-
-  EXPECT_THAT(stderr_str,
-              ::testing::HasSubstr("Skipping write to incident. Empty trace."));
-}
-
-TEST_F(PerfettoCmdlineTest, StopTracingTriggerFromConfig) {
-  // See |message_count| and |message_size| in the TraceConfig above.
-  constexpr size_t kMessageCount = 11;
-  constexpr size_t kMessageSize = 32;
-  protos::gen::TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(1024);
-  auto* ds_config = trace_config.add_data_sources()->mutable_config();
-  ds_config->set_name("android.perfetto.FakeProducer");
-  ds_config->mutable_for_testing()->set_message_count(kMessageCount);
-  ds_config->mutable_for_testing()->set_message_size(kMessageSize);
-  auto* trigger_cfg = trace_config.mutable_trigger_config();
-  trigger_cfg->set_trigger_mode(
-      protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
-  trigger_cfg->set_trigger_timeout_ms(15000);
-  auto* trigger = trigger_cfg->add_triggers();
-  trigger->set_name("trigger_name");
-  // |stop_delay_ms| must be long enough that we can write the packets in
-  // before the trace finishes. This has to be long enough for the slowest
-  // emulator. But as short as possible to prevent the test running a long
-  // time.
-  trigger->set_stop_delay_ms(500);
-  trigger = trigger_cfg->add_triggers();
-  trigger->set_name("trigger_name_3");
-  trigger->set_stop_delay_ms(60000);
-
-  // We have to construct all the processes we want to fork before we start the
-  // service with |StartServiceIfRequired()|. this is because it is unsafe
-  // (could deadlock) to fork after we've spawned some threads which might
-  // printf (and thus hold locks).
-  const std::string path = RandomTraceFileName();
-  auto perfetto_proc = ExecPerfetto(
-      {
-          "-o",
-          path,
-          "-c",
-          "-",
-      },
-      trace_config.SerializeAsString());
-
-  std::string triggers = R"(
-    activate_triggers: "trigger_name_2"
-    activate_triggers: "trigger_name"
-    activate_triggers: "trigger_name_3"
-  )";
-  auto perfetto_proc_2 = ExecPerfetto(
-      {
-          "-o",
-          path,
-          "-c",
-          "-",
-          "--txt",
-      },
-      triggers);
-
-  // Start the service and connect a simple fake producer.
-  StartServiceIfRequiredNoNewExecsAfterThis();
-  auto* fake_producer = ConnectFakeProducer();
-  EXPECT_TRUE(fake_producer);
-
-  std::thread background_trace([&perfetto_proc]() {
-    std::string stderr_str;
-    EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
-  });
-
-  WaitForProducerEnabled();
-  // Wait for the producer to start, and then write out 11 packets, before the
-  // trace actually starts (the trigger is seen).
-  auto on_data_written = task_runner_.CreateCheckpoint("data_written_1");
-  fake_producer->ProduceEventBatch(WrapTask(on_data_written));
-  task_runner_.RunUntilCheckpoint("data_written_1");
-
-  EXPECT_EQ(0, perfetto_proc_2.Run(&stderr_)) << "stderr: " << stderr_;
-
-  background_trace.join();
-
-  std::string trace_str;
-  base::ReadFile(path, &trace_str);
-  protos::gen::Trace trace;
-  ASSERT_TRUE(trace.ParseFromString(trace_str));
-  EXPECT_LT(static_cast<int>(kMessageCount), trace.packet_size());
-  bool seen_first_trigger = false;
-  for (const auto& packet : trace.packet()) {
-    if (packet.has_trace_config()) {
-      // Ensure the trace config properly includes the trigger mode we set.
-      auto kStopTrig = protos::gen::TraceConfig::TriggerConfig::STOP_TRACING;
-      EXPECT_EQ(kStopTrig,
-                packet.trace_config().trigger_config().trigger_mode());
-    } else if (packet.has_trigger()) {
-      // validate that the triggers are properly added to the trace.
-      if (!seen_first_trigger) {
-        EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
-        seen_first_trigger = true;
-      } else {
-        EXPECT_EQ("trigger_name_3", packet.trigger().trigger_name());
-      }
-    } else if (packet.has_for_testing()) {
-      // Make sure that the data size is correctly set based on what we
-      // requested.
-      EXPECT_EQ(kMessageSize, packet.for_testing().str().size());
-    }
-  }
-}
-
-TEST_F(PerfettoCmdlineTest, TriggerFromConfigStopsFileOpening) {
-  // See |message_count| and |message_size| in the TraceConfig above.
-  constexpr size_t kMessageCount = 11;
-  constexpr size_t kMessageSize = 32;
-  protos::gen::TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(1024);
-  auto* ds_config = trace_config.add_data_sources()->mutable_config();
-  ds_config->set_name("android.perfetto.FakeProducer");
-  ds_config->mutable_for_testing()->set_message_count(kMessageCount);
-  ds_config->mutable_for_testing()->set_message_size(kMessageSize);
-  auto* trigger_cfg = trace_config.mutable_trigger_config();
-  trigger_cfg->set_trigger_mode(
-      protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
-  trigger_cfg->set_trigger_timeout_ms(15000);
-  auto* trigger = trigger_cfg->add_triggers();
-  trigger->set_name("trigger_name");
-  // |stop_delay_ms| must be long enough that we can write the packets in
-  // before the trace finishes. This has to be long enough for the slowest
-  // emulator. But as short as possible to prevent the test running a long
-  // time.
-  trigger->set_stop_delay_ms(500);
-  trigger = trigger_cfg->add_triggers();
-  trigger->set_name("trigger_name_3");
-  trigger->set_stop_delay_ms(60000);
-
-  // We have to construct all the processes we want to fork before we start the
-  // service with |StartServiceIfRequired()|. this is because it is unsafe
-  // (could deadlock) to fork after we've spawned some threads which might
-  // printf (and thus hold locks).
-  const std::string path = RandomTraceFileName();
-  std::string triggers = R"(
-    activate_triggers: "trigger_name_2"
-    activate_triggers: "trigger_name"
-    activate_triggers: "trigger_name_3"
-  )";
-  auto perfetto_proc = ExecPerfetto(
-      {
-          "-o",
-          path,
-          "-c",
-          "-",
-          "--txt",
-      },
-      triggers);
-
-  // Start the service and connect a simple fake producer.
-  StartServiceIfRequiredNoNewExecsAfterThis();
-  auto* fake_producer = ConnectFakeProducer();
-  EXPECT_TRUE(fake_producer);
-
-  std::string trace_str;
-  EXPECT_FALSE(base::ReadFile(path, &trace_str));
-
-  EXPECT_EQ(0, perfetto_proc.Run(&stderr_)) << "stderr: " << stderr_;
-
-  EXPECT_FALSE(base::ReadFile(path, &trace_str));
-}
-
-TEST_F(PerfettoCmdlineTest, Query) {
-  auto query = ExecPerfetto({"--query"});
-  auto query_raw = ExecPerfetto({"--query-raw"});
-  StartServiceIfRequiredNoNewExecsAfterThis();
-  EXPECT_EQ(0, query.Run(&stderr_)) << stderr_;
-  EXPECT_EQ(0, query_raw.Run(&stderr_)) << stderr_;
-}
-
-TEST_F(PerfettoCmdlineTest, AndroidOnly(CmdTriggerWithUploadFlag)) {
-  // See |message_count| and |message_size| in the TraceConfig above.
-  constexpr size_t kMessageCount = 2;
-  constexpr size_t kMessageSize = 2;
-  protos::gen::TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(1024);
-  auto* ds_config = trace_config.add_data_sources()->mutable_config();
-  ds_config->set_name("android.perfetto.FakeProducer");
-  ds_config->mutable_for_testing()->set_message_count(kMessageCount);
-  ds_config->mutable_for_testing()->set_message_size(kMessageSize);
-  auto* trigger_cfg = trace_config.mutable_trigger_config();
-  trigger_cfg->set_trigger_mode(
-      protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
-  trigger_cfg->set_trigger_timeout_ms(15000);
-  auto* trigger = trigger_cfg->add_triggers();
-  trigger->set_name("trigger_name");
-  // |stop_delay_ms| must be long enough that we can write the packets in
-  // before the trace finishes. This has to be long enough for the slowest
-  // emulator. But as short as possible to prevent the test running a long
-  // time.
-  trigger->set_stop_delay_ms(500);
-
-  // We have to construct all the processes we want to fork before we start the
-  // service with |StartServiceIfRequired()|. this is because it is unsafe
-  // (could deadlock) to fork after we've spawned some threads which might
-  // printf (and thus hold locks).
-  const std::string path = RandomTraceFileName();
-  auto perfetto_proc = ExecPerfetto(
-      {
-          "-o",
-          path,
-          "-c",
-          "-",
-      },
-      trace_config.SerializeAsString());
-
-  std::string triggers = R"(
-    activate_triggers: "trigger_name"
-  )";
-  auto perfetto_proc_2 = ExecPerfetto(
-      {
-          "--upload",
-          "-c",
-          "-",
-          "--txt",
-      },
-      triggers);
-
-  // Start the service and connect a simple fake producer.
-  StartServiceIfRequiredNoNewExecsAfterThis();
-  auto* fake_producer = ConnectFakeProducer();
-  EXPECT_TRUE(fake_producer);
-
-  std::thread background_trace([&perfetto_proc]() {
-    std::string stderr_str;
-    EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
-  });
-
-  WaitForProducerEnabled();
-  // Wait for the producer to start, and then write out 11 packets, before the
-  // trace actually starts (the trigger is seen).
-  auto on_data_written = task_runner_.CreateCheckpoint("data_written_1");
-  fake_producer->ProduceEventBatch(WrapTask(on_data_written));
-  task_runner_.RunUntilCheckpoint("data_written_1");
-
-  EXPECT_EQ(0, perfetto_proc_2.Run(&stderr_)) << "stderr: " << stderr_;
-
-  background_trace.join();
-
-  std::string trace_str;
-  base::ReadFile(path, &trace_str);
-  protos::gen::Trace trace;
-  ASSERT_TRUE(trace.ParseFromString(trace_str));
-  EXPECT_LT(static_cast<int>(kMessageCount), trace.packet_size());
-  for (const auto& packet : trace.packet()) {
-    if (packet.has_trigger()) {
-      EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
-    }
-  }
-}
-
-}  // namespace perfetto
diff --git a/test/ftrace_integrationtest.cc b/test/ftrace_integrationtest.cc
new file mode 100644
index 0000000..2553d40
--- /dev/null
+++ b/test/ftrace_integrationtest.cc
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX)
+
+#include "perfetto/base/build_config.h"
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/temp_file.h"
+#include "perfetto/ext/base/utils.h"
+#include "perfetto/ext/traced/traced.h"
+#include "perfetto/ext/tracing/core/commit_data_request.h"
+#include "perfetto/ext/tracing/core/trace_packet.h"
+#include "perfetto/ext/tracing/core/tracing_service.h"
+#include "perfetto/protozero/scattered_heap_buffer.h"
+#include "perfetto/tracing/core/tracing_service_state.h"
+#include "src/base/test/test_task_runner.h"
+#include "src/base/test/utils.h"
+#include "src/traced/probes/ftrace/ftrace_controller.h"
+#include "src/traced/probes/ftrace/ftrace_procfs.h"
+#include "test/gtest_and_gmock.h"
+#include "test/test_helper.h"
+
+#include "protos/perfetto/config/test_config.gen.h"
+#include "protos/perfetto/config/trace_config.gen.h"
+#include "protos/perfetto/trace/ftrace/ftrace.gen.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event.gen.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.gen.h"
+#include "protos/perfetto/trace/ftrace/ftrace_stats.gen.h"
+#include "protos/perfetto/trace/perfetto/tracing_service_event.gen.h"
+#include "protos/perfetto/trace/test_event.gen.h"
+#include "protos/perfetto/trace/trace.gen.h"
+#include "protos/perfetto/trace/trace_packet.gen.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+#include "test/android_test_utils.h"
+#endif
+
+namespace perfetto {
+
+namespace {
+
+using ::testing::ContainsRegex;
+using ::testing::Each;
+using ::testing::ElementsAreArray;
+using ::testing::HasSubstr;
+using ::testing::Property;
+using ::testing::SizeIs;
+
+class PerfettoFtraceIntegrationTest : public ::testing::Test {
+ public:
+  void SetUp() override {
+    ftrace_procfs_ = FtraceProcfs::CreateGuessingMountPoint();
+
+// On android we do expect that tracefs is accessible, both in the case of
+// running as part of traced/probes system daemons and shell. On Linux this is
+// up to the system admin, don't hard fail.
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+    if (!ftrace_procfs_) {
+      PERFETTO_ELOG(
+          "Cannot acces tracefs. On Linux you need to manually run `sudo chown "
+          "-R $USER /sys/kernel/tracing` to enable these tests. Skipping");
+      GTEST_SKIP();
+    } else {
+      // Recent kernels set tracing_on=1 by default. On Android this is
+      // disabled by initrc scripts. Be tolerant on Linux where we don't have
+      // that and force disable ftrace.
+      ftrace_procfs_->SetTracingOn(false);
+    }
+#endif
+  }
+
+  std::unique_ptr<FtraceProcfs> ftrace_procfs_;
+};
+
+}  // namespace
+
+TEST_F(PerfettoFtraceIntegrationTest, TestFtraceProducer) {
+  base::TestTaskRunner task_runner;
+
+  TestHelper helper(&task_runner);
+  helper.StartServiceIfRequired();
+
+#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
+  ProbesProducerThread probes(GetTestProducerSockName());
+  probes.Connect();
+#endif
+
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+
+  TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(1024);
+  trace_config.set_duration_ms(3000);
+
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("linux.ftrace");
+  ds_config->set_target_buffer(0);
+
+  protos::gen::FtraceConfig ftrace_config;
+  ftrace_config.add_ftrace_events("sched_switch");
+  ftrace_config.add_ftrace_events("bar");
+  ds_config->set_ftrace_config_raw(ftrace_config.SerializeAsString());
+
+  helper.StartTracing(trace_config);
+  helper.WaitForTracingDisabled();
+
+  helper.ReadData();
+  helper.WaitForReadData();
+
+  const auto& packets = helper.trace();
+  ASSERT_GT(packets.size(), 0u);
+
+  for (const auto& packet : packets) {
+    for (int ev = 0; ev < packet.ftrace_events().event_size(); ev++) {
+      ASSERT_TRUE(packet.ftrace_events()
+                      .event()[static_cast<size_t>(ev)]
+                      .has_sched_switch());
+    }
+  }
+}
+
+TEST_F(PerfettoFtraceIntegrationTest, TestFtraceFlush) {
+  base::TestTaskRunner task_runner;
+
+  TestHelper helper(&task_runner);
+  helper.StartServiceIfRequired();
+
+#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
+  ProbesProducerThread probes(GetTestProducerSockName());
+  probes.Connect();
+#endif
+
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+
+  // Wait for the traced_probes service to connect. We want to start tracing
+  // only after it connects, otherwise we'll start a tracing session with 0
+  // producers connected (which is valid but not what we want here).
+  helper.WaitForDataSourceConnected("linux.ftrace");
+
+  TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(32);
+  trace_config.set_duration_ms(kDefaultTestTimeoutMs);
+
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("linux.ftrace");
+
+  protos::gen::FtraceConfig ftrace_config;
+  ftrace_config.add_ftrace_events("print");
+  ds_config->set_ftrace_config_raw(ftrace_config.SerializeAsString());
+
+  helper.StartTracing(trace_config);
+
+  // Wait for traced_probes to start.
+  helper.WaitFor([&] { return ftrace_procfs_->IsTracingEnabled(); }, "ftrace");
+
+  // Do a first flush just to synchronize with the producer. The problem here
+  // is that, on a Linux workstation, the producer can take several seconds just
+  // to get to the point where it is fully ready. We use the flush ack as a
+  // synchronization point.
+  helper.FlushAndWait(kDefaultTestTimeoutMs);
+
+  const char kMarker[] = "just_one_event";
+  EXPECT_TRUE(ftrace_procfs_->WriteTraceMarker(kMarker));
+
+  // This is the real flush we are testing.
+  helper.FlushAndWait(kDefaultTestTimeoutMs);
+
+  helper.DisableTracing();
+  helper.WaitForTracingDisabled(kDefaultTestTimeoutMs);
+
+  helper.ReadData();
+  helper.WaitForReadData();
+
+  int marker_found = 0;
+  for (const auto& packet : helper.trace()) {
+    for (int i = 0; i < packet.ftrace_events().event_size(); i++) {
+      const auto& ev = packet.ftrace_events().event()[static_cast<size_t>(i)];
+      if (ev.has_print() && ev.print().buf().find(kMarker) != std::string::npos)
+        marker_found++;
+    }
+  }
+  ASSERT_EQ(marker_found, 1);
+}
+
+// Disable this test:
+// 1. On cuttlefish (x86-kvm). It's too slow when running on GCE (b/171771440).
+//    We cannot change the length of the production code in
+//    CanReadKernelSymbolAddresses() to deal with it.
+// 2. On user (i.e. non-userdebug) builds. As that doesn't work there by design.
+// 3. On ARM builds, because they fail on our CI.
+#if (PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD) && defined(__i386__)) || \
+    defined(__arm__)
+#define MAYBE_KernelAddressSymbolization DISABLED_KernelAddressSymbolization
+#else
+#define MAYBE_KernelAddressSymbolization KernelAddressSymbolization
+#endif
+TEST_F(PerfettoFtraceIntegrationTest, MAYBE_KernelAddressSymbolization) {
+  // On Android in-tree builds (TreeHugger): this test must always run to
+  // prevent selinux / property-related regressions. However it can run only on
+  // userdebug.
+  // On standalone builds and Linux, this can be optionally skipped because
+  // there it requires root to lower kptr_restrict.
+#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+  if (!IsDebuggableBuild())
+    GTEST_SKIP();
+#else
+  if (geteuid() != 0)
+    GTEST_SKIP();
+#endif
+
+  base::TestTaskRunner task_runner;
+
+  TestHelper helper(&task_runner);
+  helper.StartServiceIfRequired();
+
+#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
+  ProbesProducerThread probes(GetTestProducerSockName());
+  probes.Connect();
+#endif
+
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+
+  TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(1024);
+
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("linux.ftrace");
+  protos::gen::FtraceConfig ftrace_cfg;
+  ftrace_cfg.set_symbolize_ksyms(true);
+  ftrace_cfg.set_initialize_ksyms_synchronously_for_testing(true);
+  ds_config->set_ftrace_config_raw(ftrace_cfg.SerializeAsString());
+
+  helper.StartTracing(trace_config);
+
+  // Synchronize with the ftrace data source. The kernel symbol map is loaded
+  // at this point.
+  helper.FlushAndWait(kDefaultTestTimeoutMs);
+  helper.DisableTracing();
+  helper.WaitForTracingDisabled();
+  helper.ReadData();
+  helper.WaitForReadData();
+
+  const auto& packets = helper.trace();
+  ASSERT_GT(packets.size(), 0u);
+
+  int symbols_parsed = -1;
+  for (const auto& packet : packets) {
+    if (!packet.has_ftrace_stats())
+      continue;
+    if (packet.ftrace_stats().phase() != protos::gen::FtraceStats::END_OF_TRACE)
+      continue;
+    symbols_parsed =
+        static_cast<int>(packet.ftrace_stats().kernel_symbols_parsed());
+  }
+  ASSERT_GT(symbols_parsed, 100);
+}
+
+}  // namespace perfetto
+#endif  // OS_ANDROID || OS_LINUX
diff --git a/test/test_helper.h b/test/test_helper.h
index cd7e415..904623f 100644
--- a/test/test_helper.h
+++ b/test/test_helper.h
@@ -28,6 +28,7 @@
 #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
 #include "perfetto/ext/tracing/core/trace_packet.h"
 #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
+#include "perfetto/ext/tracing/ipc/default_socket.h"
 #include "perfetto/ext/tracing/ipc/service_ipc_host.h"
 #include "perfetto/tracing/core/trace_config.h"
 #include "src/base/test/test_task_runner.h"
@@ -49,6 +50,17 @@
 // See bugs duped against b/171771440.
 constexpr uint32_t kDefaultTestTimeoutMs = 10000;
 
+inline const char* GetTestProducerSockName() {
+// If we're building on Android and starting the daemons ourselves,
+// create the sockets in a world-writable location.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
+    PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
+  return "/data/local/tmp/traced_producer";
+#else
+  return ::perfetto::GetProducerSocket();
+#endif
+}
+
 // This is used only in daemon starting integrations tests.
 class ServiceThread {
  public:
diff --git a/test/traced_integrationtest.cc b/test/traced_integrationtest.cc
new file mode 100644
index 0000000..de71c27
--- /dev/null
+++ b/test/traced_integrationtest.cc
@@ -0,0 +1,455 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/base/build_config.h"
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/pipe.h"
+#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/temp_file.h"
+#include "perfetto/ext/base/utils.h"
+#include "perfetto/ext/tracing/core/commit_data_request.h"
+#include "perfetto/ext/tracing/core/trace_packet.h"
+#include "perfetto/ext/tracing/core/tracing_service.h"
+#include "perfetto/protozero/scattered_heap_buffer.h"
+#include "perfetto/tracing/core/tracing_service_state.h"
+#include "src/base/test/test_task_runner.h"
+#include "src/base/test/utils.h"
+#include "src/protozero/filtering/filter_bytecode_generator.h"
+#include "test/gtest_and_gmock.h"
+#include "test/test_helper.h"
+
+#include "protos/perfetto/config/test_config.gen.h"
+#include "protos/perfetto/config/trace_config.gen.h"
+#include "protos/perfetto/trace/perfetto/tracing_service_event.gen.h"
+#include "protos/perfetto/trace/test_event.gen.h"
+#include "protos/perfetto/trace/trace.gen.h"
+#include "protos/perfetto/trace/trace_packet.gen.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+
+namespace {
+
+using ::testing::ContainsRegex;
+using ::testing::Each;
+using ::testing::ElementsAreArray;
+using ::testing::HasSubstr;
+using ::testing::Property;
+using ::testing::SizeIs;
+
+}  // namespace
+
+TEST(PerfettoTracedIntegrationTest, TestFakeProducer) {
+  base::TestTaskRunner task_runner;
+
+  TestHelper helper(&task_runner);
+  helper.StartServiceIfRequired();
+  helper.ConnectFakeProducer();
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+
+  TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(1024);
+  trace_config.set_duration_ms(200);
+
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("android.perfetto.FakeProducer");
+  ds_config->set_target_buffer(0);
+
+  static constexpr size_t kNumPackets = 11;
+  static constexpr uint32_t kRandomSeed = 42;
+  static constexpr uint32_t kMsgSize = 1024;
+  ds_config->mutable_for_testing()->set_seed(kRandomSeed);
+  ds_config->mutable_for_testing()->set_message_count(kNumPackets);
+  ds_config->mutable_for_testing()->set_message_size(kMsgSize);
+  ds_config->mutable_for_testing()->set_send_batch_on_register(true);
+
+  helper.StartTracing(trace_config);
+  helper.WaitForTracingDisabled();
+
+  helper.ReadData();
+  helper.WaitForReadData();
+
+  const auto& packets = helper.trace();
+  ASSERT_EQ(packets.size(), kNumPackets);
+
+  std::minstd_rand0 rnd_engine(kRandomSeed);
+  for (const auto& packet : packets) {
+    ASSERT_TRUE(packet.has_for_testing());
+    ASSERT_EQ(packet.for_testing().seq_value(), rnd_engine());
+  }
+}
+
+TEST(PerfettoTracedIntegrationTest, VeryLargePackets) {
+  base::TestTaskRunner task_runner;
+
+  TestHelper helper(&task_runner);
+  helper.StartServiceIfRequired();
+  helper.ConnectFakeProducer();
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+
+  TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(4096 * 10);
+  trace_config.set_duration_ms(500);
+
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("android.perfetto.FakeProducer");
+  ds_config->set_target_buffer(0);
+
+  static constexpr size_t kNumPackets = 7;
+  static constexpr uint32_t kRandomSeed = 42;
+  static constexpr uint32_t kMsgSize = 1024 * 1024 - 42;
+  ds_config->mutable_for_testing()->set_seed(kRandomSeed);
+  ds_config->mutable_for_testing()->set_message_count(kNumPackets);
+  ds_config->mutable_for_testing()->set_message_size(kMsgSize);
+  ds_config->mutable_for_testing()->set_send_batch_on_register(true);
+
+  helper.StartTracing(trace_config);
+  helper.WaitForTracingDisabled();
+
+  helper.ReadData();
+  helper.WaitForReadData(/* read_count */ 0, /* timeout_ms */ 10000);
+
+  const auto& packets = helper.trace();
+  ASSERT_EQ(packets.size(), kNumPackets);
+
+  std::minstd_rand0 rnd_engine(kRandomSeed);
+  for (const auto& packet : packets) {
+    ASSERT_TRUE(packet.has_for_testing());
+    ASSERT_EQ(packet.for_testing().seq_value(), rnd_engine());
+    size_t msg_size = packet.for_testing().str().size();
+    ASSERT_EQ(kMsgSize, msg_size);
+    for (size_t i = 0; i < msg_size; i++)
+      ASSERT_EQ(i < msg_size - 1 ? '.' : 0, packet.for_testing().str()[i]);
+  }
+}
+
+// This is a regression test see b/169051440 for context.
+//
+// In this test we ensure that traced will not crash if a Producer stops
+// responding or draining the socket (i.e. after we fill up the IPC buffer
+// traced doesn't block on trying to write to the IPC buffer and watchdog
+// doesn't kill it).
+TEST(PerfettoTracedIntegrationTest, UnresponsiveProducer) {
+  base::TestTaskRunner task_runner;
+
+  TestHelper helper(&task_runner);
+  helper.StartServiceIfRequired();
+  auto* producer = helper.ConnectFakeProducer();
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+
+  TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(4096 * 10);
+  trace_config.set_duration_ms(100);
+  trace_config.set_flush_timeout_ms(1);
+  trace_config.set_data_source_stop_timeout_ms(1);
+
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("android.perfetto.FakeProducer");
+
+  static constexpr size_t kNumPackets = 1;
+  static constexpr uint32_t kRandomSeed = 42;
+  static constexpr uint32_t kMsgSize = 1024 * 1024 - 42;
+  ds_config->mutable_for_testing()->set_seed(kRandomSeed);
+  ds_config->mutable_for_testing()->set_message_count(kNumPackets);
+  ds_config->mutable_for_testing()->set_message_size(kMsgSize);
+  ds_config->mutable_for_testing()->set_send_batch_on_register(true);
+
+  // This string is just used to make the StartDataSource IPC larger.
+  ds_config->set_legacy_config(std::string(8192, '.'));
+  ds_config->set_target_buffer(0);
+
+  // Run one legit trace, this ensures that the producer above is
+  // valid and correct and mirrors real life producers.
+  helper.StartTracing(trace_config);
+  helper.WaitForProducerEnabled();
+  helper.WaitForTracingDisabled();
+
+  helper.ReadData();
+  helper.WaitForReadData(/* read_count */ 0, /* timeout_ms */ 10000);
+
+  const auto& packets = helper.trace();
+  ASSERT_EQ(packets.size(), 1u);
+  ASSERT_TRUE(packets[0].has_for_testing());
+  ASSERT_FALSE(packets[0].for_testing().str().empty());
+  helper.FreeBuffers();
+
+  // Switch the producer to ignoring the IPC socket. On a pixel 4 it took 13
+  // traces to fill up the IPC buffer and cause traced to block (and eventually
+  // watchdog to kill it).
+  helper.producer_thread()->get()->RemoveFileDescriptorWatch(
+      producer->unix_socket_fd());
+
+  trace_config.set_duration_ms(1);
+  for (uint32_t i = 0u; i < 15u; i++) {
+    helper.StartTracing(trace_config, base::ScopedFile());
+    helper.WaitForTracingDisabled(/* timeout_ms = */ 20000);
+    helper.FreeBuffers();
+  }
+  // We need to readd the FileDescriptor (otherwise when the UnixSocket attempts
+  // to remove it a the FakeProducer is destroyed will hit a CHECK failure.
+  helper.producer_thread()->get()->AddFileDescriptorWatch(
+      producer->unix_socket_fd(), []() {});
+}
+
+TEST(PerfettoTracedIntegrationTest, DetachAndReattach) {
+  base::TestTaskRunner task_runner;
+
+  TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(1024);
+  trace_config.set_duration_ms(10000);  // Max timeout, session is ended before.
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("android.perfetto.FakeProducer");
+  static constexpr size_t kNumPackets = 11;
+  ds_config->mutable_for_testing()->set_message_count(kNumPackets);
+  ds_config->mutable_for_testing()->set_message_size(32);
+
+  // Enable tracing and detach as soon as it gets started.
+  TestHelper helper(&task_runner);
+  helper.StartServiceIfRequired();
+  auto* fake_producer = helper.ConnectFakeProducer();
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+  helper.StartTracing(trace_config);
+
+  // Detach.
+  helper.DetachConsumer("key");
+
+  // Write data while detached.
+  helper.WaitForProducerEnabled();
+  auto on_data_written = task_runner.CreateCheckpoint("data_written");
+  fake_producer->ProduceEventBatch(helper.WrapTask(on_data_written));
+  task_runner.RunUntilCheckpoint("data_written");
+
+  // Then reattach the consumer.
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+  helper.AttachConsumer("key");
+
+  helper.DisableTracing();
+  helper.WaitForTracingDisabled();
+
+  helper.ReadData();
+  helper.WaitForReadData();
+  const auto& packets = helper.trace();
+  ASSERT_EQ(packets.size(), kNumPackets);
+}
+
+// Tests that a detached trace session is automatically cleaned up if the
+// consumer doesn't re-attach before its expiration time.
+TEST(PerfettoTracedIntegrationTest, ReattachFailsAfterTimeout) {
+  base::TestTaskRunner task_runner;
+
+  TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(1024);
+  trace_config.set_duration_ms(250);
+  trace_config.set_write_into_file(true);
+  trace_config.set_file_write_period_ms(100000);
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("android.perfetto.FakeProducer");
+  ds_config->mutable_for_testing()->set_message_count(1);
+  ds_config->mutable_for_testing()->set_message_size(32);
+  ds_config->mutable_for_testing()->set_send_batch_on_register(true);
+
+  // Enable tracing and detach as soon as it gets started.
+  TestHelper helper(&task_runner);
+  helper.StartServiceIfRequired();
+  helper.ConnectFakeProducer();
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+
+  auto pipe_pair = base::Pipe::Create();
+  helper.StartTracing(trace_config, std::move(pipe_pair.wr));
+
+  // Detach.
+  helper.DetachConsumer("key");
+
+  // Use the file EOF (write end closed) as a way to detect when the trace
+  // session is ended.
+  char buf[1024];
+  while (PERFETTO_EINTR(read(*pipe_pair.rd, buf, sizeof(buf))) > 0) {
+  }
+
+  // Give some margin for the tracing service to destroy the session.
+  usleep(250000);
+
+  // Reconnect and find out that it's too late and the session is gone.
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+  EXPECT_FALSE(helper.AttachConsumer("key"));
+}
+
+TEST(PerfettoTracedIntegrationTest, TestProducerProvidedSMB) {
+  base::TestTaskRunner task_runner;
+
+  TestHelper helper(&task_runner);
+  helper.CreateProducerProvidedSmb();
+
+  protos::gen::TestConfig test_config;
+  test_config.set_seed(42);
+  test_config.set_message_count(1);
+  test_config.set_message_size(1024);
+  test_config.set_send_batch_on_register(true);
+
+  // Write a first batch before connection.
+  helper.ProduceStartupEventBatch(test_config);
+
+  helper.StartServiceIfRequired();
+  helper.ConnectFakeProducer();
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+
+  TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(1024);
+  trace_config.set_duration_ms(200);
+
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("android.perfetto.FakeProducer");
+  ds_config->set_target_buffer(0);
+  *ds_config->mutable_for_testing() = test_config;
+
+  // The data source is configured to emit another batch when it is started via
+  // send_batch_on_register in the TestConfig.
+  helper.StartTracing(trace_config);
+  helper.WaitForTracingDisabled();
+
+  EXPECT_TRUE(helper.IsShmemProvidedByProducer());
+
+  helper.ReadData();
+  helper.WaitForReadData();
+
+  const auto& packets = helper.trace();
+  // We should have produced two batches, one before the producer connected and
+  // another one when the data source was started.
+  ASSERT_EQ(packets.size(), 2u);
+  ASSERT_TRUE(packets[0].has_for_testing());
+  ASSERT_TRUE(packets[1].has_for_testing());
+}
+
+// Regression test for b/153142114.
+TEST(PerfettoTracedIntegrationTest, QueryServiceStateLargeResponse) {
+  base::TestTaskRunner task_runner;
+
+  TestHelper helper(&task_runner);
+  helper.StartServiceIfRequired();
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+
+  FakeProducer* producer = helper.ConnectFakeProducer();
+
+  // Register 5 data sources with very large descriptors. Each descriptor will
+  // max out the IPC message size, so that the service has no other choice
+  // than chunking them.
+  std::map<std::string, std::string> ds_expected;
+  for (int i = 0; i < 5; i++) {
+    DataSourceDescriptor dsd;
+    std::string name = "big_ds_" + std::to_string(i);
+    dsd.set_name(name);
+    std::string descriptor(ipc::kIPCBufferSize - 64,
+                           static_cast<char>((' ' + i) % 64));
+    dsd.set_track_event_descriptor_raw(descriptor);
+    ds_expected[name] = std::move(descriptor);
+    producer->RegisterDataSource(dsd);
+  }
+
+  // Linearize the producer with the service. We need to make sure that all the
+  // RegisterDataSource() calls above have been seen by the service before
+  // continuing.
+  helper.SyncAndWaitProducer();
+
+  // Now invoke QueryServiceState() and wait for the reply. The service will
+  // send 6 (1 + 5) IPCs which will be merged together in
+  // producer_ipc_client_impl.cc.
+  auto svc_state = helper.QueryServiceStateAndWait();
+
+  ASSERT_GE(svc_state.producers().size(), 1u);
+
+  std::map<std::string, std::string> ds_found;
+  for (const auto& ds : svc_state.data_sources()) {
+    if (!base::StartsWith(ds.ds_descriptor().name(), "big_ds_"))
+      continue;
+    ds_found[ds.ds_descriptor().name()] =
+        ds.ds_descriptor().track_event_descriptor_raw();
+  }
+  EXPECT_THAT(ds_found, ElementsAreArray(ds_expected));
+}
+
+// Regression test for b/195065199. Check that trace filtering works when a
+// packet size exceeds the IPC limit. This tests that the tracing service, when
+// reassembling packets after filtering, doesn't "overglue" them. They still
+// need to be slice-able to fit into the ReadBuffers ipc.
+TEST(PerfettoTracedIntegrationTest, TraceFilterLargePackets) {
+  base::TestTaskRunner task_runner;
+  TestHelper helper(&task_runner);
+
+  helper.StartServiceIfRequired();
+  helper.ConnectFakeProducer();
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+
+  TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(1024 * 16);
+  trace_config.set_duration_ms(500);
+  auto* prod_config = trace_config.add_producers();
+  prod_config->set_producer_name("android.perfetto.FakeProducer");
+  prod_config->set_shm_size_kb(1024 * 16);
+  prod_config->set_page_size_kb(32);
+
+  static constexpr size_t kNumPackets = 3;
+  static constexpr uint32_t kRandomSeed = 42;
+  static constexpr uint32_t kMsgSize = 8 * ipc::kIPCBufferSize;
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("android.perfetto.FakeProducer");
+  auto* test_config = ds_config->mutable_for_testing();
+  test_config->set_seed(kRandomSeed);
+  test_config->set_message_count(kNumPackets);
+  test_config->set_message_size(kMsgSize);
+  test_config->set_send_batch_on_register(true);
+
+  protozero::FilterBytecodeGenerator filt;
+  // Message 0: root Trace proto.
+  filt.AddNestedField(1 /* root trace.packet*/, 1);
+  filt.EndMessage();
+
+  // Message 1: TracePacket proto. Allow all fields.
+  filt.AddSimpleFieldRange(1, 1000);
+  filt.EndMessage();
+
+  trace_config.mutable_trace_filter()->set_bytecode(filt.Serialize());
+
+  // The data source is configured to emit another batch when it is started via
+  // send_batch_on_register in the TestConfig.
+  helper.StartTracing(trace_config);
+  helper.WaitForTracingDisabled();
+
+  helper.ReadData();
+  helper.WaitForReadData(/* read_count */ 0, /* timeout_ms */ 10000);
+
+  const std::vector<protos::gen::TracePacket>& packets = helper.trace();
+  EXPECT_EQ(packets.size(), kNumPackets);
+  EXPECT_THAT(packets,
+              Each(Property(&protos::gen::TracePacket::has_for_testing, true)));
+  EXPECT_THAT(
+      packets,
+      Each(Property(&protos::gen::TracePacket::for_testing,
+                    Property(&protos::gen::TestEvent::str, SizeIs(kMsgSize)))));
+}
+
+}  // namespace perfetto
