chromium/services/tracing/perfetto/system_perfetto_unittest.cc

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <cerrno>
#include <cstdlib>
#include <memory>
#include <string>
#include <thread>
#include <utility>

#include "base/compiler_specific.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/process/launch.h"
#include "base/rand_util.h"
#include "base/run_loop.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/trace_event/trace_config.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "services/tracing/perfetto/perfetto_service.h"
#include "services/tracing/perfetto/producer_host.h"
#include "services/tracing/perfetto/system_test_utils.h"
#include "services/tracing/perfetto/test_utils.h"
#include "services/tracing/public/cpp/perfetto/dummy_producer.h"
#include "services/tracing/public/cpp/perfetto/producer_client.h"
#include "services/tracing/public/cpp/system_tracing_service.h"
#include "services/tracing/public/cpp/trace_startup.h"
#include "services/tracing/public/cpp/traced_process_impl.h"
#include "services/tracing/public/cpp/tracing_features.h"
#include "testing/gtest/include/gtest/gtest-death-test.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/perfetto/include/perfetto/tracing/default_socket.h"
#include "third_party/perfetto/protos/perfetto/config/trace_config.pb.h"
#include "third_party/perfetto/protos/perfetto/trace/trace.pb.h"

#if BUILDFLAG(IS_ANDROID)
#include "base/android/build_info.h"  // nogncheck
#endif

namespace tracing {

namespace {

const char kPerfettoTestDataSourceName[] =;

std::string GetPerfettoProducerName() {}

std::string RandomASCII(size_t length) {}

class ClearAndRestoreSystemProducerScope {};

class SystemPerfettoTest : public TracingUnitTest {};

#if BUILDFLAG(IS_ANDROID)
// Flaky on Android: crbug.com/1262132#c17
#define MAYBE_SystemTraceEndToEnd
#else
#define MAYBE_SystemTraceEndToEnd
#endif
TEST_F(SystemPerfettoTest, MAYBE_SystemTraceEndToEnd) {}

#if BUILDFLAG(IS_ANDROID)
// Flaky on Android: crbug.com/1262132#c17
#define MAYBE_OneSystemSourceWithMultipleLocalSources
#else
#define MAYBE_OneSystemSourceWithMultipleLocalSources
#endif
TEST_F(SystemPerfettoTest, MAYBE_OneSystemSourceWithMultipleLocalSources) {}

#if BUILDFLAG(IS_ANDROID)
// Flaky on Android: crbug.com/1262132#c17
#define MAYBE_MultipleSystemSourceWithOneLocalSourcesLocalFirst
#else
#define MAYBE_MultipleSystemSourceWithOneLocalSourcesLocalFirst
#endif
TEST_F(SystemPerfettoTest,
       MAYBE_MultipleSystemSourceWithOneLocalSourcesLocalFirst) {}

#if BUILDFLAG(IS_ANDROID)
// Flaky on Android: crbug.com/1262132#c17
#define MAYBE_MultipleSystemAndLocalSources
#else
#define MAYBE_MultipleSystemAndLocalSources
#endif
TEST_F(SystemPerfettoTest, MAYBE_MultipleSystemAndLocalSources) {}

#if BUILDFLAG(IS_ANDROID)
// Flaky on Android: crbug.com/1262132#c17
#define MAYBE_MultipleSystemAndLocalSourcesLocalFirst
#else
#define MAYBE_MultipleSystemAndLocalSourcesLocalFirst
#endif
TEST_F(SystemPerfettoTest, MAYBE_MultipleSystemAndLocalSourcesLocalFirst) {}

#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
// Flaky on all CrOS platforms: crbug.com/1262132#c18
// Flaky on Android: crbug.com/1262132
#define MAYBE_SystemTraceWhileLocalStartupTracing
#else
#define MAYBE_SystemTraceWhileLocalStartupTracing
#endif
// Attempts to start a system trace while a local startup trace is active. The
// system trace should only be started after the local trace is completed.
TEST_F(SystemPerfettoTest, MAYBE_SystemTraceWhileLocalStartupTracing) {}

#if BUILDFLAG(IS_ANDROID)
// Failing on android-pie-arm64-dbg, see crbug.com/1262132.
TEST_F(SystemPerfettoTest, DISABLED_SystemToLowAPILevel) {
  if (base::android::BuildInfo::GetInstance()->sdk_int() >=
      base::android::SDK_VERSION_P) {
    LOG(INFO) << "Skipping SystemToLowAPILevel test, this phone supports the "
              << "P SDK (or above).";
    // This test will do exactly the same thing on versions beyond P so just
    // exit. Once we are no longer testing on O and below we can remove this
    // test.
    return;
  }

  auto run_test = [this](bool check_sdk_level) {
    PerfettoTracedProcess::Get()->ClearDataSourcesForTesting();

    std::string data_source_name = "temp_name";
    data_source_name += check_sdk_level ? "true" : "false";

    base::RunLoop data_source_started_runloop;
    std::unique_ptr<TestDataSource> data_source =
        TestDataSource::CreateAndRegisterDataSource(data_source_name, 1);
    data_source->set_start_tracing_callback(
        data_source_started_runloop.QuitClosure());

    auto system_service = CreateMockSystemService();

    base::RunLoop system_no_more_packets_runloop;
    MockConsumer system_consumer(
        {data_source_name}, system_service->GetService(),
        [&system_no_more_packets_runloop](bool has_more) {
          if (!has_more) {
            system_no_more_packets_runloop.Quit();
          }
        });

    base::RunLoop system_data_source_enabled_runloop;
    base::RunLoop system_data_source_disabled_runloop;
    auto system_producer = CreateMockPosixSystemProducer(
        system_service.get(),
        /* num_data_sources_expected = */ 1,
        &system_data_source_enabled_runloop,
        &system_data_source_disabled_runloop, check_sdk_level);

    if (!check_sdk_level) {
      system_data_source_enabled_runloop.Run();
      data_source_started_runloop.Run();
      system_consumer.WaitForAllDataSourcesStarted();
    }

    // Post the task to ensure that the data will have been written and
    // committed if any tracing is being done.
    base::RunLoop stop_tracing;
    PerfettoTracedProcess::GetTaskRunner()->PostTask(
        [&system_consumer, &stop_tracing]() {
          system_consumer.StopTracing();
          stop_tracing.Quit();
        });
    stop_tracing.Run();

    if (!check_sdk_level) {
      system_data_source_disabled_runloop.Run();
      system_consumer.WaitForAllDataSourcesStopped();
    }
    system_no_more_packets_runloop.Run();

    PerfettoProducer::DeleteSoonForTesting(std::move(system_producer));
    return system_consumer.received_test_packets();
  };

  // If |check_sdk_level| == true, the |system_producer| will not even attempt
  // to connect to the |system_service| and therefore we should see no packets.
  EXPECT_EQ(1u, run_test(/* check_sdk_level = */ false));
  EXPECT_EQ(0u, run_test(/* check_sdk_level = */ true));
}

// Flaky on Android: crbug.com/1262132#c17
TEST_F(SystemPerfettoTest, DISABLED_EnabledOnDebugBuilds) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndDisableFeature(features::kEnablePerfettoSystemTracing);
  if (base::android::BuildInfo::GetInstance()->is_debug_android()) {
    EXPECT_TRUE(ShouldSetupSystemTracing());
  } else {
    EXPECT_FALSE(ShouldSetupSystemTracing());
  }
}
#endif  // BUILDFLAG(IS_ANDROID)

#if BUILDFLAG(IS_ANDROID)
// Flaky on Android: crbug.com/1262132#c17
#define MAYBE_RespectsFeatureList
#else
#define MAYBE_RespectsFeatureList
#endif
TEST_F(SystemPerfettoTest, MAYBE_RespectsFeatureList) {}

#if BUILDFLAG(IS_ANDROID)
// Flaky on Android: crbug.com/1262132#c17
TEST_F(SystemPerfettoTest, DISABLED_RespectsFeaturePreAndroidPie) {
  if (base::android::BuildInfo::GetInstance()->sdk_int() >=
      base::android::SDK_VERSION_P) {
    return;
  }

  auto run_test = [this](bool enable_feature) {
    PerfettoTracedProcess::Get()->ClearDataSourcesForTesting();

    base::test::ScopedFeatureList feature_list;
    if (enable_feature) {
      feature_list.InitAndEnableFeature(features::kEnablePerfettoSystemTracing);
    } else {
      feature_list.InitAndDisableFeature(
          features::kEnablePerfettoSystemTracing);
    }

    std::string data_source_name = "temp_name";

    base::RunLoop data_source_started_runloop;
    std::unique_ptr<TestDataSource> data_source =
        TestDataSource::CreateAndRegisterDataSource(data_source_name, 1);
    data_source->set_start_tracing_callback(
        data_source_started_runloop.QuitClosure());

    auto system_service = CreateMockSystemService();

    base::RunLoop system_no_more_packets_runloop;
    MockConsumer system_consumer(
        {data_source_name}, system_service->GetService(),
        [&system_no_more_packets_runloop](bool has_more) {
          if (!has_more) {
            system_no_more_packets_runloop.Quit();
          }
        });

    base::RunLoop system_data_source_enabled_runloop;
    base::RunLoop system_data_source_disabled_runloop;
    auto system_producer = CreateMockPosixSystemProducer(
        system_service.get(),
        /* num_data_sources_expected = */ 1,
        &system_data_source_enabled_runloop,
        &system_data_source_disabled_runloop, /* check_sdk_level = */ true);
    PerfettoTracedProcess::GetTaskRunner()->PostTask(
        [&system_producer]() { system_producer->ConnectToSystemService(); });

    if (enable_feature) {
      system_data_source_enabled_runloop.Run();
      data_source_started_runloop.Run();
      system_consumer.WaitForAllDataSourcesStarted();
    }

    // Post the task to ensure that the data will have been written and
    // committed if any tracing is being done.
    base::RunLoop stop_tracing;
    PerfettoTracedProcess::GetTaskRunner()->PostTask(
        [&system_consumer, &stop_tracing]() {
          system_consumer.StopTracing();
          stop_tracing.Quit();
        });
    stop_tracing.Run();

    if (enable_feature) {
      system_data_source_disabled_runloop.Run();
      system_consumer.WaitForAllDataSourcesStopped();
    }
    system_no_more_packets_runloop.Run();

    PerfettoProducer::DeleteSoonForTesting(std::move(system_producer));
    return system_consumer.received_test_packets();
  };

  EXPECT_EQ(0u, run_test(/* enable_feature = */ false));
  EXPECT_EQ(1u, run_test(/* enable_feature = */ true));
}
#endif  // BUILDFLAG(IS_ANDROID)

TEST_F(SystemPerfettoTest, DISABLED_EnablePerfettoSystemTracingDefaultState) {}

#if defined(ANDROID)
// Flaky on Android: crbug.com/1262132#c17
#define MAYBE_SetupSystemTracing
#else
#define MAYBE_SetupSystemTracing
#endif
TEST_F(SystemPerfettoTest, MAYBE_SetupSystemTracing) {}

#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
TEST_F(SystemPerfettoTest, SandboxedOpenProducerSocket) {}
#endif  // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)

}  // namespace
}  // namespace tracing