blob: 9de69ef7dee002d1859b581e888a9fa207c14cf1 [file] [log] [blame]
[email protected]b8255e7a2013-10-02 19:11:131// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/common/crash_keys.h"
6
[email protected]f9d5a612014-01-21 18:40:577#include <set>
[email protected]b8255e7a2013-10-02 19:11:138#include <string>
9
10#include "base/command_line.h"
Ian Barkley-Yeungf9987412021-07-21 02:36:0411#include "base/strings/strcat.h"
[email protected]b8255e7a2013-10-02 19:11:1312#include "base/strings/stringprintf.h"
avi2729e442015-12-26 05:27:4513#include "build/build_config.h"
Ian Barkley-Yeungdcd6c072021-07-23 17:53:2214#include "build/buildflag.h"
Yuta Hijikata2bac1282020-11-24 03:51:2715#include "build/chromeos_buildflags.h"
Robert Sesekd89a06202017-11-20 22:54:0516#include "components/crash/core/common/crash_key.h"
Ian Barkley-Yeungf9987412021-07-21 02:36:0417#include "gpu/config/gpu_switches.h"
18#include "testing/gmock/include/gmock/gmock.h"
[email protected]b8255e7a2013-10-02 19:11:1319#include "testing/gtest/include/gtest/gtest.h"
20
Robert Sesekabcdd842017-12-19 02:34:1421using crash_reporter::GetCrashKeyValue;
Ian Barkley-Yeungf9987412021-07-21 02:36:0422using ::testing::IsEmpty;
Robert Sesekabcdd842017-12-19 02:34:1423
[email protected]b8255e7a2013-10-02 19:11:1324class CrashKeysTest : public testing::Test {
25 public:
Jeroen Dhollanderb93a8d172022-05-10 12:13:1326 void SetUp() override { crash_reporter::InitializeCrashKeys(); }
[email protected]b8255e7a2013-10-02 19:11:1327
dchengd0022752014-10-28 00:09:0628 void TearDown() override {
Ian Barkley-Yeungdcd6c072021-07-23 17:53:2229 // Breakpad doesn't properly support ResetCrashKeysForTesting() and usually
30 // CHECK fails after it is called.
31#if BUILDFLAG(USE_CRASHPAD_ANNOTATION)
32 crash_reporter::ResetCrashKeysForTesting();
33#endif
[email protected]b8255e7a2013-10-02 19:11:1334 }
[email protected]b8255e7a2013-10-02 19:11:1335};
36
[email protected]f9d5a612014-01-21 18:40:5737TEST_F(CrashKeysTest, Extensions) {
38 // Set three extensions.
39 {
40 std::set<std::string> extensions;
41 extensions.insert("ext.1");
42 extensions.insert("ext.2");
43 extensions.insert("ext.3");
44
45 crash_keys::SetActiveExtensions(extensions);
46
Robert Sesek0f93c582017-12-19 15:13:4347 extensions.erase(GetCrashKeyValue("extension-1"));
48 extensions.erase(GetCrashKeyValue("extension-2"));
49 extensions.erase(GetCrashKeyValue("extension-3"));
[email protected]f9d5a612014-01-21 18:40:5750 EXPECT_EQ(0u, extensions.size());
51
Robert Sesek0f93c582017-12-19 15:13:4352 EXPECT_EQ("3", GetCrashKeyValue("num-extensions"));
53 EXPECT_TRUE(GetCrashKeyValue("extension-4").empty());
[email protected]f9d5a612014-01-21 18:40:5754 }
55
56 // Set more than the max switches.
57 {
58 std::set<std::string> extensions;
Robert Sesek0f93c582017-12-19 15:13:4359 const int kMax = 12;
[email protected]f9d5a612014-01-21 18:40:5760 for (int i = 1; i <= kMax; ++i)
61 extensions.insert(base::StringPrintf("ext.%d", i));
62 crash_keys::SetActiveExtensions(extensions);
63
64 for (int i = 1; i <= kMax; ++i) {
Robert Sesek0f93c582017-12-19 15:13:4365 extensions.erase(GetCrashKeyValue(base::StringPrintf("extension-%d", i)));
[email protected]f9d5a612014-01-21 18:40:5766 }
67 EXPECT_EQ(2u, extensions.size());
68
Robert Sesek0f93c582017-12-19 15:13:4369 EXPECT_EQ("12", GetCrashKeyValue("num-extensions"));
70 EXPECT_TRUE(GetCrashKeyValue("extension-13").empty());
71 EXPECT_TRUE(GetCrashKeyValue("extension-14").empty());
[email protected]f9d5a612014-01-21 18:40:5772 }
73
74 // Set fewer to ensure that old ones are erased.
75 {
76 std::set<std::string> extensions;
77 for (int i = 1; i <= 5; ++i)
78 extensions.insert(base::StringPrintf("ext.%d", i));
79 crash_keys::SetActiveExtensions(extensions);
80
Robert Sesek0f93c582017-12-19 15:13:4381 extensions.erase(GetCrashKeyValue("extension-1"));
82 extensions.erase(GetCrashKeyValue("extension-2"));
83 extensions.erase(GetCrashKeyValue("extension-3"));
84 extensions.erase(GetCrashKeyValue("extension-4"));
85 extensions.erase(GetCrashKeyValue("extension-5"));
[email protected]f9d5a612014-01-21 18:40:5786 EXPECT_EQ(0u, extensions.size());
87
Robert Sesek0f93c582017-12-19 15:13:4388 EXPECT_EQ("5", GetCrashKeyValue("num-extensions"));
[email protected]f9d5a612014-01-21 18:40:5789 for (int i = 6; i < 20; ++i) {
Robert Sesek0f93c582017-12-19 15:13:4390 std::string key = base::StringPrintf("extension-%d", i);
91 EXPECT_TRUE(GetCrashKeyValue(key).empty()) << key;
[email protected]f9d5a612014-01-21 18:40:5792 }
[email protected]b8255e7a2013-10-02 19:11:1393 }
94}
[email protected]af7c0242014-04-11 07:27:2995
Jeroen Dhollanderb93a8d172022-05-10 12:13:1396TEST_F(CrashKeysTest, ShouldIgnoreBoringFlags) {
avi79bf9132014-12-25 17:48:0597 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
Ian Barkley-Yeungf9987412021-07-21 02:36:0498 std::string expected_num_switches = "7";
[email protected]af7c0242014-04-11 07:27:2999 command_line.AppendSwitch("--enable-logging");
[email protected]af7c0242014-04-11 07:27:29100 command_line.AppendSwitch("--v=1");
[email protected]af7c0242014-04-11 07:27:29101
102 command_line.AppendSwitch("--vv=1");
103 command_line.AppendSwitch("--vvv");
104 command_line.AppendSwitch("--enable-multi-profiles");
105 command_line.AppendSwitch("--device-management-url=https://foo/bar");
Ian Barkley-Yeungf9987412021-07-21 02:36:04106 command_line.AppendSwitch(
107 base::StrCat({"--", switches::kGpuPreferences, "=ABC123"}));
Yuta Hijikata2bac1282020-11-24 03:51:27108#if BUILDFLAG(IS_CHROMEOS_ASH)
joenotcharles0edd36d2015-12-01 16:57:32109 command_line.AppendSwitch("--user-data-dir=/tmp");
110 command_line.AppendSwitch("--default-wallpaper-small=test.png");
Ian Barkley-Yeungf9987412021-07-21 02:36:04111 expected_num_switches = "9";
joenotcharles0edd36d2015-12-01 16:57:32112#endif
[email protected]af7c0242014-04-11 07:27:29113
joenotcharles0edd36d2015-12-01 16:57:32114 crash_keys::SetCrashKeysFromCommandLine(command_line);
[email protected]af7c0242014-04-11 07:27:29115
Robert Sesekabcdd842017-12-19 02:34:14116 EXPECT_EQ("--vv=1", GetCrashKeyValue("switch-1"));
117 EXPECT_EQ("--vvv", GetCrashKeyValue("switch-2"));
118 EXPECT_EQ("--enable-multi-profiles", GetCrashKeyValue("switch-3"));
119 EXPECT_EQ("--device-management-url=https://foo/bar",
120 GetCrashKeyValue("switch-4"));
Ian Barkley-Yeungf9987412021-07-21 02:36:04121 EXPECT_EQ(expected_num_switches, GetCrashKeyValue("num-switches"));
Robert Sesekabcdd842017-12-19 02:34:14122 EXPECT_TRUE(GetCrashKeyValue("switch-5").empty());
[email protected]af7c0242014-04-11 07:27:29123}
Ian Barkley-Yeungf9987412021-07-21 02:36:04124
Xiaohan Wang4d5c5042022-01-18 21:54:37125#if BUILDFLAG(IS_CHROMEOS)
Ian Barkley-Yeungf9987412021-07-21 02:36:04126TEST_F(CrashKeysTest, EnabledDisabledFeaturesFlags) {
127 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
128 command_line.InitFromArgv(
Jeroen Dhollanderb93a8d172022-05-10 12:13:13129 {"program_name", "--example", "--enable-features=AEnabledFeatureFlag",
Ian Barkley-Yeungf9987412021-07-21 02:36:04130 "--unrelated-flag=23", "--disable-features=ADisabledFeaturesString",
131 "--more-example=yes"});
132
133 crash_keys::SetCrashKeysFromCommandLine(command_line);
134
Jeroen Dhollanderb93a8d172022-05-10 12:13:13135 EXPECT_EQ("AEnabledFeatureFlag",
136 GetCrashKeyValue("commandline-enabled-feature-1"));
Ian Barkley-Yeungf9987412021-07-21 02:36:04137 EXPECT_EQ("ADisabledFeaturesString",
Jeroen Dhollanderb93a8d172022-05-10 12:13:13138 GetCrashKeyValue("commandline-disabled-feature-1"));
Ian Barkley-Yeungf9987412021-07-21 02:36:04139
140 // Unrelated flags are not affected by the enable-features extraction.
141 EXPECT_EQ("--example", GetCrashKeyValue("switch-1"));
142 EXPECT_EQ("--unrelated-flag=23", GetCrashKeyValue("switch-2"));
143 EXPECT_EQ("--more-example=yes", GetCrashKeyValue("switch-3"));
144 // --enable-features and --disable-features are still counted in num-switches.
145 EXPECT_EQ("5", GetCrashKeyValue("num-switches"));
146}
147
Jeroen Dhollanderb93a8d172022-05-10 12:13:13148TEST_F(CrashKeysTest, ShouldCreateCrashKeyForEachEnabledFeature) {
Ian Barkley-Yeungf9987412021-07-21 02:36:04149 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
Jeroen Dhollanderb93a8d172022-05-10 12:13:13150 command_line.InitFromArgv({"program_name", "--example",
151 "--enable-features=FirstFeature,SecondFeature",
152 "--unrelated-flag=23", "--more-example=yes"});
Ian Barkley-Yeungf9987412021-07-21 02:36:04153
154 crash_keys::SetCrashKeysFromCommandLine(command_line);
155
Jeroen Dhollanderb93a8d172022-05-10 12:13:13156 EXPECT_EQ("FirstFeature", GetCrashKeyValue("commandline-enabled-feature-1"));
157 EXPECT_EQ("SecondFeature", GetCrashKeyValue("commandline-enabled-feature-2"));
158
159 EXPECT_EQ(GetCrashKeyValue("commandline-enabled-feature-3"), "");
Ian Barkley-Yeungf9987412021-07-21 02:36:04160}
161
Jeroen Dhollanderb93a8d172022-05-10 12:13:13162TEST_F(CrashKeysTest, ShouldCreateCrashKeyForEachDisabledFeature) {
163 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
164 command_line.InitFromArgv({"program_name", "--example",
165 "--disable-features=FirstFeature,SecondFeature",
166 "--unrelated-flag=23", "--more-example=yes"});
167
168 crash_keys::SetCrashKeysFromCommandLine(command_line);
169
170 EXPECT_EQ("FirstFeature", GetCrashKeyValue("commandline-disabled-feature-1"));
171 EXPECT_EQ("SecondFeature",
172 GetCrashKeyValue("commandline-disabled-feature-2"));
173
174 EXPECT_EQ(GetCrashKeyValue("commandline-disabled-feature-3"), "");
175}
176
177TEST_F(CrashKeysTest,
178 EnabledDisabledFeatures_LastCommandArgumentShouldBeRetained) {
179 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
180 command_line.InitFromArgv(
181 {"program_name", "--enable-features=FeatureEnabledInFirstArgument",
182 "--disable-features=FeatureDisabledInFirstArgument",
183 "--enable-features=FeatureEnabledInSecondArgument",
184 "--disable-features=FeatureDisabledInSecondArgument"});
185
186 crash_keys::SetCrashKeysFromCommandLine(command_line);
187
188 EXPECT_EQ("FeatureEnabledInSecondArgument",
189 GetCrashKeyValue("commandline-enabled-feature-1"));
190 EXPECT_EQ("FeatureDisabledInSecondArgument",
191 GetCrashKeyValue("commandline-disabled-feature-1"));
192}
193
194TEST_F(
195 CrashKeysTest,
196 EnabledDisabledFeatures_ShouldClearPreviousCrashKeysIfCommandLineIsReparsed) {
Ian Barkley-Yeungf9987412021-07-21 02:36:04197 {
198 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
Jeroen Dhollanderb93a8d172022-05-10 12:13:13199 command_line.InitFromArgv(
200 {"program_name", "--enable-features=OriginalEnable_1, OriginalEnable_2",
201 "--disable-features=OriginalDisable_1, OriginalDisable_2"});
Ian Barkley-Yeungf9987412021-07-21 02:36:04202 crash_keys::SetCrashKeysFromCommandLine(command_line);
Jeroen Dhollanderb93a8d172022-05-10 12:13:13203
204 EXPECT_EQ("OriginalEnable_1",
205 GetCrashKeyValue("commandline-enabled-feature-1"));
206 EXPECT_EQ("OriginalEnable_2",
207 GetCrashKeyValue("commandline-enabled-feature-2"));
208
209 EXPECT_EQ("OriginalDisable_1",
210 GetCrashKeyValue("commandline-disabled-feature-1"));
211 EXPECT_EQ("OriginalDisable_2",
212 GetCrashKeyValue("commandline-disabled-feature-2"));
213 }
214
215 // Parse a command line with only a single value in each flag.
216 {
217 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
218 command_line.InitFromArgv({"program_name", "--enable-features=NewEnable",
219 "--disable-features=NewDisable"});
220 crash_keys::SetCrashKeysFromCommandLine(command_line);
221
222 EXPECT_EQ("NewEnable", GetCrashKeyValue("commandline-enabled-feature-1"));
223 EXPECT_EQ(GetCrashKeyValue("commandline-enabled-feature-2"), "");
224
225 EXPECT_EQ("NewDisable", GetCrashKeyValue("commandline-disabled-feature-1"));
226 EXPECT_EQ(GetCrashKeyValue("commandline-disabled-feature-2"), "");
Ian Barkley-Yeungf9987412021-07-21 02:36:04227 }
228
229 // Parse a command line with no enable-features or disable-features flags.
230 {
231 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
232 command_line.InitFromArgv(
233 {"program_name", "--enable-logging", "--type=renderer"});
234 crash_keys::SetCrashKeysFromCommandLine(command_line);
Jeroen Dhollanderb93a8d172022-05-10 12:13:13235 EXPECT_EQ(GetCrashKeyValue("commandline-enabled-feature-1"), "");
236 EXPECT_EQ(GetCrashKeyValue("commandline-enabled-feature-2"), "");
237 EXPECT_EQ(GetCrashKeyValue("commandline-disabled-feature-1"), "");
238 EXPECT_EQ(GetCrashKeyValue("commandline-disabled-feature-2"), "");
Ian Barkley-Yeungf9987412021-07-21 02:36:04239 }
240
241 // Parse a new command line with enable-features or disable-features flags.
242 {
243 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
244 command_line.InitFromArgv({"program_name", "--enable-features=NewEnable",
245 "--disable-features=NewDisable"});
246 crash_keys::SetCrashKeysFromCommandLine(command_line);
Jeroen Dhollanderb93a8d172022-05-10 12:13:13247 EXPECT_EQ("NewEnable", GetCrashKeyValue("commandline-enabled-feature-1"));
248 EXPECT_EQ("NewDisable", GetCrashKeyValue("commandline-disabled-feature-1"));
Ian Barkley-Yeungf9987412021-07-21 02:36:04249 }
250}
251
Xiaohan Wang4d5c5042022-01-18 21:54:37252#endif // BUILDFLAG(IS_CHROMEOS)