blob: f1c5b55e7456ea23d2a83fd14d3b9cc797bd3fe1 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/tracing/common/background_tracing_utils.h"
#include <vector>
#include "base/base64.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/path_service.h"
#include "base/test/scoped_command_line.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/test/test_proto_loader.h"
#include "base/threading/thread_restrictions.h"
#include "components/prefs/testing_pref_service.h"
#include "components/tracing/common/background_tracing_state_manager.h"
#include "components/tracing/common/pref_names.h"
#include "components/tracing/common/tracing_scenarios_config.h"
#include "components/tracing/common/tracing_switches.h"
#include "content/public/browser/background_tracing_manager.h"
#include "content/public/browser/tracing_delegate.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/snappy/src/snappy.h"
namespace {
class BackgroundTracingUtilsTest : public testing::Test {
content::BrowserTaskEnvironment task_environment{
base::test::TaskEnvironment::TimeSource::MOCK_TIME};
content::TracingDelegate tracing_delegate_;
std::unique_ptr<content::BackgroundTracingManager>
background_tracing_manager =
content::BackgroundTracingManager::CreateInstance(&tracing_delegate_);
};
const char kInvalidTracingConfig[] = "{][}";
const char kValidProtoTracingConfig[] = R"pb(
scenarios: {
scenario_name: "test_scenario"
start_rules: { name: "start_trigger" manual_trigger_name: "start_trigger" }
upload_rules: {
name: "upload_trigger"
manual_trigger_name: "upload_trigger"
}
trace_config: {
data_sources: { config: { name: "org.chromium.trace_metadata2" } }
}
}
)pb";
const char kValidProtoRuleConfig[] = R"pb(
rules: { name: "trigger1" manual_trigger_name: "trigger1" }
rules: { name: "trigger2" manual_trigger_name: "trigger2" }
)pb";
std::string GetFieldTracingConfigFromText(const std::string& proto_text) {
base::ScopedAllowBlockingForTesting allow_blocking;
base::TestProtoLoader config_loader(
base::PathService::CheckedGet(base::DIR_GEN_TEST_DATA_ROOT)
.Append(
FILE_PATH_LITERAL("third_party/perfetto/protos/perfetto/"
"config/chrome/scenario_config.descriptor")),
"perfetto.protos.ChromeFieldTracingConfig");
std::string serialized_message;
config_loader.ParseFromText(proto_text, serialized_message);
return serialized_message;
}
std::string GetTracingRulesConfigFromText(const std::string& proto_text) {
base::ScopedAllowBlockingForTesting allow_blocking;
base::TestProtoLoader config_loader(
base::PathService::CheckedGet(base::DIR_GEN_TEST_DATA_ROOT)
.Append(
FILE_PATH_LITERAL("third_party/perfetto/protos/perfetto/"
"config/chrome/scenario_config.descriptor")),
"perfetto.protos.TracingTriggerRulesConfig");
std::string serialized_message;
config_loader.ParseFromText(proto_text, serialized_message);
return serialized_message;
}
TEST_F(BackgroundTracingUtilsTest, SetupFieldTracingFromFieldTrial) {
std::string serialized_config =
GetFieldTracingConfigFromText(kValidProtoTracingConfig);
std::string compressed_config;
ASSERT_TRUE(snappy::Compress(serialized_config.data(),
serialized_config.size(), &compressed_config));
std::string encoded_config = base::Base64Encode(compressed_config);
base::test::ScopedFeatureList scoped_list;
scoped_list.InitAndEnableFeatureWithParameters(tracing::kFieldTracing,
{{"config", encoded_config}});
ASSERT_FALSE(tracing::IsBackgroundTracingEnabledFromCommandLine());
EXPECT_FALSE(tracing::SetupSystemTracingFromFieldTrial());
EXPECT_TRUE(tracing::SetupFieldTracingFromFieldTrial());
}
TEST_F(BackgroundTracingUtilsTest, SetupSystemTracingFromFieldTrial) {
std::string serialized_config =
GetTracingRulesConfigFromText(kValidProtoRuleConfig);
std::string compressed_config;
ASSERT_TRUE(snappy::Compress(serialized_config.data(),
serialized_config.size(), &compressed_config));
std::string encoded_config = base::Base64Encode(compressed_config);
base::test::ScopedFeatureList scoped_list;
scoped_list.InitAndEnableFeatureWithParameters(tracing::kTracingTriggers,
{{"config", encoded_config}});
ASSERT_FALSE(tracing::IsBackgroundTracingEnabledFromCommandLine());
EXPECT_TRUE(tracing::SetupSystemTracingFromFieldTrial());
}
TEST_F(BackgroundTracingUtilsTest, SetupBackgroundTracingFromProtoConfigFile) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath file_path = temp_dir.GetPath().AppendASCII("config.pb");
base::WriteFile(file_path,
GetFieldTracingConfigFromText(kValidProtoTracingConfig));
base::test::ScopedCommandLine scoped_command_line;
base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine();
command_line->AppendSwitchPath(switches::kBackgroundTracingOutputPath,
temp_dir.GetPath());
command_line->AppendSwitchPath(switches::kEnableBackgroundTracing, file_path);
ASSERT_TRUE(tracing::IsBackgroundTracingEnabledFromCommandLine());
EXPECT_FALSE(tracing::SetupSystemTracingFromFieldTrial());
EXPECT_FALSE(tracing::SetupFieldTracingFromFieldTrial());
EXPECT_TRUE(tracing::SetupBackgroundTracingFromCommandLine());
}
TEST_F(BackgroundTracingUtilsTest, SetupFieldTracingFromFieldTrialOutputPath) {
auto pref_service = std::make_unique<TestingPrefServiceSimple>();
tracing::RegisterPrefs(pref_service->registry());
auto state_manager_ = tracing::BackgroundTracingStateManager::CreateInstance(
pref_service.get());
std::string serialized_config =
GetFieldTracingConfigFromText(kValidProtoTracingConfig);
std::string compressed_config;
ASSERT_TRUE(snappy::Compress(serialized_config.data(),
serialized_config.size(), &compressed_config));
std::string encoded_config = base::Base64Encode(compressed_config);
base::test::ScopedFeatureList scoped_list;
scoped_list.InitAndEnableFeatureWithParameters(tracing::kFieldTracing,
{{"config", encoded_config}});
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::test::ScopedCommandLine scoped_command_line;
base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine();
command_line->AppendSwitchPath(switches::kBackgroundTracingOutputPath,
temp_dir.GetPath());
ASSERT_TRUE(tracing::HasBackgroundTracingOutputPath());
ASSERT_FALSE(tracing::IsBackgroundTracingEnabledFromCommandLine());
EXPECT_TRUE(tracing::SetupFieldTracingFromFieldTrial());
}
TEST_F(BackgroundTracingUtilsTest,
SetupBackgroundTracingFromProtoConfigFileFailed) {
base::test::ScopedCommandLine scoped_command_line;
base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine();
command_line->AppendSwitchASCII(switches::kEnableBackgroundTracing, "");
ASSERT_TRUE(tracing::IsBackgroundTracingEnabledFromCommandLine());
EXPECT_FALSE(
tracing::SetupBackgroundTracingFromProtoConfigFile(base::FilePath()));
}
TEST_F(BackgroundTracingUtilsTest, SetupBackgroundTracingWithOutputPathFailed) {
base::test::ScopedCommandLine scoped_command_line;
base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine();
command_line->AppendSwitchASCII(switches::kBackgroundTracingOutputPath, "");
EXPECT_TRUE(tracing::HasBackgroundTracingOutputPath());
EXPECT_FALSE(tracing::SetBackgroundTracingOutputPath());
}
TEST_F(BackgroundTracingUtilsTest,
SetupBackgroundTracingFromProtoConfigFileInvalidConfig) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath config_file_path = temp_dir.GetPath().AppendASCII("config.pb");
base::WriteFile(config_file_path, kInvalidTracingConfig);
base::test::ScopedCommandLine scoped_command_line;
base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine();
command_line->AppendSwitchPath(switches::kEnableBackgroundTracing,
config_file_path);
ASSERT_TRUE(tracing::IsBackgroundTracingEnabledFromCommandLine());
EXPECT_FALSE(
tracing::SetupBackgroundTracingFromProtoConfigFile(config_file_path));
}
TEST_F(BackgroundTracingUtilsTest,
SetupBackgroundTracingFromCommandLineFieldTrial) {
ASSERT_FALSE(tracing::IsBackgroundTracingEnabledFromCommandLine());
EXPECT_FALSE(tracing::SetupBackgroundTracingFromCommandLine());
EXPECT_FALSE(
content::BackgroundTracingManager::GetInstance().HasActiveScenario());
}
} // namespace