#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"
#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)
#define MAYBE_SystemTraceEndToEnd …
#else
#define MAYBE_SystemTraceEndToEnd …
#endif
TEST_F(SystemPerfettoTest, MAYBE_SystemTraceEndToEnd) { … }
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_OneSystemSourceWithMultipleLocalSources …
#else
#define MAYBE_OneSystemSourceWithMultipleLocalSources …
#endif
TEST_F(SystemPerfettoTest, MAYBE_OneSystemSourceWithMultipleLocalSources) { … }
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_MultipleSystemSourceWithOneLocalSourcesLocalFirst …
#else
#define MAYBE_MultipleSystemSourceWithOneLocalSourcesLocalFirst …
#endif
TEST_F(SystemPerfettoTest,
MAYBE_MultipleSystemSourceWithOneLocalSourcesLocalFirst) { … }
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_MultipleSystemAndLocalSources …
#else
#define MAYBE_MultipleSystemAndLocalSources …
#endif
TEST_F(SystemPerfettoTest, MAYBE_MultipleSystemAndLocalSources) { … }
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_MultipleSystemAndLocalSourcesLocalFirst …
#else
#define MAYBE_MultipleSystemAndLocalSourcesLocalFirst …
#endif
TEST_F(SystemPerfettoTest, MAYBE_MultipleSystemAndLocalSourcesLocalFirst) { … }
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
#define MAYBE_SystemTraceWhileLocalStartupTracing …
#else
#define MAYBE_SystemTraceWhileLocalStartupTracing …
#endif
TEST_F(SystemPerfettoTest, MAYBE_SystemTraceWhileLocalStartupTracing) { … }
#if BUILDFLAG(IS_ANDROID)
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).";
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(),
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();
}
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();
};
EXPECT_EQ(1u, run_test( false));
EXPECT_EQ(0u, run_test( true));
}
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
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_RespectsFeatureList …
#else
#define MAYBE_RespectsFeatureList …
#endif
TEST_F(SystemPerfettoTest, MAYBE_RespectsFeatureList) { … }
#if BUILDFLAG(IS_ANDROID)
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(),
1,
&system_data_source_enabled_runloop,
&system_data_source_disabled_runloop, 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();
}
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( false));
EXPECT_EQ(1u, run_test( true));
}
#endif
TEST_F(SystemPerfettoTest, DISABLED_EnablePerfettoSystemTracingDefaultState) { … }
#if defined(ANDROID)
#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
}
}