blob: 9d775348b8299112e4a12a517f9dc1e6a42b4e1d [file] [log] [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/tracing/background_tracing_field_trial.h"
#include "base/base64.h"
#include "base/files/file_util.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_params.h"
#include "base/path_service.h"
#include "base/test/scoped_command_line.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_proto_loader.h"
#include "base/threading/thread_restrictions.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/tracing/common/background_tracing_state_manager.h"
#include "components/tracing/common/background_tracing_utils.h"
#include "components/tracing/common/tracing_switches.h"
#include "content/public/browser/background_tracing_config.h"
#include "content/public/browser/background_tracing_manager.h"
#include "content/public/test/browser_task_environment.h"
#include "services/tracing/public/cpp/tracing_features.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace tracing {
class BackgroundTracingTest : public testing::Test {
public:
BackgroundTracingTest() {
testing_profile_manager_ = std::make_unique<TestingProfileManager>(
TestingBrowserProcess::GetGlobal());
background_tracing_manager_ =
content::BackgroundTracingManager::CreateInstance();
}
void SetUp() override { ASSERT_TRUE(testing_profile_manager_->SetUp()); }
void TearDown() override {
content::BackgroundTracingManager::GetInstance().AbortScenarioForTesting();
}
protected:
// Needs to stay alive through TearDown().
std::unique_ptr<TestingProfileManager> testing_profile_manager_;
private:
content::BrowserTaskEnvironment task_environment_;
std::unique_ptr<content::BackgroundTracingManager>
background_tracing_manager_;
};
namespace {
const char kValidJsonTracingConfig[] = R"(
{
"scenario_name": "BrowserProcess",
"configs": [
{
"custom_categories": "base,toplevel",
"rule": "MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE",
"histogram_name": "Omnibox.CharTypedToRepaintLatency.ToPaint",
"histogram_lower_value": 1
}
],
"mode": "REACTIVE_TRACING_MODE"
}
)";
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_metadata" } }
}
}
)pb";
using tracing::BackgroundTracingSetupMode;
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;
}
} // namespace
TEST_F(BackgroundTracingTest, MaybeSetupBackgroundTracingFromFieldTrial) {
const std::string kTrialName = "BackgroundTracing";
const std::string kExperimentName = "SlowStart";
base::AssociateFieldTrialParams(kTrialName, kExperimentName,
{{"config", kValidJsonTracingConfig}});
base::FieldTrialList::CreateFieldTrial(kTrialName, kExperimentName);
ASSERT_EQ(tracing::GetBackgroundTracingSetupMode(),
BackgroundTracingSetupMode::kFromFieldTrial);
EXPECT_FALSE(tracing::MaybeSetupSystemTracingFromFieldTrial());
EXPECT_TRUE(tracing::MaybeSetupBackgroundTracingFromFieldTrial());
EXPECT_TRUE(
content::BackgroundTracingManager::GetInstance().HasActiveScenario());
}
TEST_F(BackgroundTracingTest, MaybeSetupFieldTracingFromFieldTrial) {
std::string serialized_config =
GetFieldTracingConfigFromText(kValidProtoTracingConfig);
std::string encoded_config = base::Base64Encode(serialized_config);
base::test::ScopedFeatureList scoped_list;
scoped_list.InitAndEnableFeatureWithParameters(tracing::kFieldTracing,
{{"config", encoded_config}});
ASSERT_EQ(tracing::GetBackgroundTracingSetupMode(),
BackgroundTracingSetupMode::kFromFieldTrial);
EXPECT_FALSE(tracing::MaybeSetupSystemTracingFromFieldTrial());
EXPECT_TRUE(tracing::MaybeSetupBackgroundTracingFromFieldTrial());
}
TEST_F(BackgroundTracingTest, 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_EQ(tracing::GetBackgroundTracingSetupMode(),
BackgroundTracingSetupMode::kFromProtoConfigFile);
EXPECT_FALSE(tracing::MaybeSetupSystemTracingFromFieldTrial());
EXPECT_FALSE(tracing::MaybeSetupBackgroundTracingFromFieldTrial());
EXPECT_TRUE(tracing::SetupBackgroundTracingFromCommandLine());
}
TEST_F(BackgroundTracingTest, SetupBackgroundTracingFromJsonConfigFile) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath file_path = temp_dir.GetPath().AppendASCII("config.json");
base::WriteFile(file_path, kValidJsonTracingConfig);
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::kEnableLegacyBackgroundTracing,
file_path);
ASSERT_EQ(tracing::GetBackgroundTracingSetupMode(),
BackgroundTracingSetupMode::kFromJsonConfigFile);
EXPECT_FALSE(tracing::MaybeSetupBackgroundTracingFromFieldTrial());
EXPECT_FALSE(
content::BackgroundTracingManager::GetInstance().HasActiveScenario());
}
TEST_F(BackgroundTracingTest, SetupBackgroundTracingFieldTrialOutputPath) {
const std::string kTrialName = "BackgroundTracing";
const std::string kExperimentName = "LocalOutput";
base::AssociateFieldTrialParams(kTrialName, kExperimentName,
{{"config", kValidJsonTracingConfig}});
base::FieldTrialList::CreateFieldTrial(kTrialName, kExperimentName);
EXPECT_FALSE(
content::BackgroundTracingManager::GetInstance().HasActiveScenario());
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_EQ(tracing::GetBackgroundTracingSetupMode(),
BackgroundTracingSetupMode::kFromFieldTrial);
EXPECT_TRUE(tracing::MaybeSetupBackgroundTracingFromFieldTrial());
EXPECT_TRUE(
content::BackgroundTracingManager::GetInstance().HasActiveScenario());
}
} // namespace tracing