1 // Copyright 2014 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.
5 #include "components/crash/app/crash_keys_win.h"
7 #include "base/command_line.h"
8 #include "base/files/file_path.h"
9 #include "base/strings/stringprintf.h"
10 #include "components/crash/app/crash_reporter_client.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
18 using testing::Return
;
19 using testing::SetArgPointee
;
21 class MockCrashReporterClient
: public crash_reporter::CrashReporterClient
{
23 MOCK_METHOD1(GetAlternativeCrashDumpLocation
,
24 bool(base::FilePath
* crash_dir
));
25 MOCK_METHOD5(GetProductNameAndVersion
, void(const base::FilePath
& exe_path
,
26 base::string16
* product_name
,
27 base::string16
* version
,
28 base::string16
* special_build
,
29 base::string16
* channel_name
));
30 MOCK_METHOD3(ShouldShowRestartDialog
, bool(base::string16
* title
,
31 base::string16
* message
,
32 bool* is_rtl_locale
));
33 MOCK_METHOD0(AboutToRestart
, bool());
34 MOCK_METHOD1(GetDeferredUploadsSupported
, bool(bool is_per_user_install
));
35 MOCK_METHOD1(GetIsPerUserInstall
, bool(const base::FilePath
& exe_path
));
36 MOCK_METHOD1(GetShouldDumpLargerDumps
, bool(bool is_per_user_install
));
37 MOCK_METHOD0(GetResultCodeRespawnFailed
, int());
38 MOCK_METHOD0(InitBrowserCrashDumpsRegKey
, void());
39 MOCK_METHOD1(RecordCrashDumpAttempt
, void(bool is_real_crash
));
41 MOCK_METHOD2(GetProductNameAndVersion
, void(std::string
* product_name
,
42 std::string
* version
));
43 MOCK_METHOD0(GetReporterLogFilename
, base::FilePath());
44 MOCK_METHOD1(GetCrashDumpLocation
, bool(base::FilePath
* crash_dir
));
45 MOCK_METHOD0(RegisterCrashKeys
, size_t());
46 MOCK_METHOD0(IsRunningUnattended
, bool());
47 MOCK_METHOD0(GetCollectStatsConsent
, bool());
48 MOCK_METHOD1(ReportingIsEnforcedByPolicy
, bool(bool* breakpad_enabled
));
49 MOCK_METHOD0(GetAndroidMinidumpDescriptor
, int());
50 #if defined(OS_MACOSX)
51 MOCK_METHOD1(InstallAdditionalFilters
, void(BreakpadRef breakpad
));
53 MOCK_METHOD1(EnableBreakpadForProcess
, bool(const std::string
& process_type
));
56 class CrashKeysWinTest
: public testing::Test
{
59 size_t CountKeyValueOccurences(
60 const google_breakpad::CustomClientInfo
* client_info
,
61 const wchar_t* key
, const wchar_t* value
);
64 testing::StrictMock
<MockCrashReporterClient
> crash_client_
;
67 size_t CrashKeysWinTest::CountKeyValueOccurences(
68 const google_breakpad::CustomClientInfo
* client_info
,
69 const wchar_t* key
, const wchar_t* value
) {
70 size_t occurrences
= 0;
71 for (size_t i
= 0; i
< client_info
->count
; ++i
) {
72 if (wcscmp(client_info
->entries
[i
].name
, key
) == 0 &&
73 wcscmp(client_info
->entries
[i
].value
, value
) == 0) {
81 TEST_F(CrashKeysWinTest
, RecordsSelf
) {
82 ASSERT_EQ(static_cast<CrashKeysWin
*>(NULL
), CrashKeysWin::keeper());
85 CrashKeysWin crash_keys
;
87 ASSERT_EQ(&crash_keys
, CrashKeysWin::keeper());
90 ASSERT_EQ(static_cast<CrashKeysWin
*>(NULL
), CrashKeysWin::keeper());
93 // Tests the crash keys set up for the most common official build consumer
94 // scenario. No policy controls, not running unattended and no explicit
96 TEST_F(CrashKeysWinTest
, OfficialLikeKeys
) {
97 CrashKeysWin crash_keys
;
99 const base::FilePath
kExePath(L
"C:\\temp\\exe_path.exe");
100 // The exe path ought to get passed through to the breakpad client.
101 EXPECT_CALL(crash_client_
, GetProductNameAndVersion(kExePath
, _
, _
, _
, _
))
102 .WillRepeatedly(DoAll(
103 SetArgPointee
<1>(L
"SomeProdName"),
104 SetArgPointee
<2>(L
"1.2.3.4"),
105 SetArgPointee
<3>(L
""),
106 SetArgPointee
<4>(L
"-devm")));
108 EXPECT_CALL(crash_client_
, GetAlternativeCrashDumpLocation(_
))
109 .WillRepeatedly(DoAll(
110 SetArgPointee
<0>(base::FilePath(L
"C:\\temp")),
113 EXPECT_CALL(crash_client_
, ReportingIsEnforcedByPolicy(_
))
114 .WillRepeatedly(Return(false));
116 EXPECT_CALL(crash_client_
, IsRunningUnattended())
117 .WillRepeatedly(Return(false));
119 // Provide an empty command line.
120 base::CommandLine
cmd_line(base::CommandLine::NO_PROGRAM
);
121 google_breakpad::CustomClientInfo
* info
=
122 crash_keys
.GetCustomInfo(kExePath
.value(),
128 ASSERT_TRUE(info
!= NULL
);
129 ASSERT_TRUE(info
->entries
!= NULL
);
131 // We expect 7 fixed keys and a "freeboard" of 256 keys for dynamic entries.
132 EXPECT_EQ(256U + 7U, info
->count
);
134 EXPECT_EQ(1, CountKeyValueOccurences(info
, L
"ver", L
"1.2.3.4"));
135 EXPECT_EQ(1, CountKeyValueOccurences(info
, L
"prod", L
"SomeProdName"));
136 EXPECT_EQ(1, CountKeyValueOccurences(info
, L
"plat", L
"Win32"));
137 EXPECT_EQ(1, CountKeyValueOccurences(info
, L
"ptype", L
"made_up_type"));
138 std::wstring
pid_str(base::StringPrintf(L
"%d", ::GetCurrentProcessId()));
139 EXPECT_EQ(1, CountKeyValueOccurences(info
, L
"pid", pid_str
.c_str()));
140 EXPECT_EQ(1, CountKeyValueOccurences(info
, L
"channel", L
"-devm"));
141 EXPECT_EQ(1, CountKeyValueOccurences(info
, L
"profile-type", L
"temporary"));
142 EXPECT_EQ(256, CountKeyValueOccurences(info
, L
"unspecified-crash-key", L
""));
145 } // namespace breakpad