Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(452)

Side by Side Diff: components/browser_watcher/postmortem_report_collector_unittest.cc

Issue 2883103002: Quantify instability according to the stability instrumentation (Closed)
Patch Set: address Siggi's comments Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/browser_watcher/postmortem_report_collector.h" 5 #include "components/browser_watcher/postmortem_report_collector.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <memory> 9 #include <memory>
10 #include <set> 10 #include <set>
11 #include <string> 11 #include <string>
12 #include <utility> 12 #include <utility>
13 #include <vector> 13 #include <vector>
14 14
15 #include "base/debug/activity_analyzer.h" 15 #include "base/debug/activity_analyzer.h"
16 #include "base/debug/activity_tracker.h" 16 #include "base/debug/activity_tracker.h"
17 #include "base/files/file.h" 17 #include "base/files/file.h"
18 #include "base/files/file_path.h" 18 #include "base/files/file_path.h"
19 #include "base/files/file_util.h" 19 #include "base/files/file_util.h"
20 #include "base/files/memory_mapped_file.h" 20 #include "base/files/memory_mapped_file.h"
21 #include "base/files/scoped_file.h" 21 #include "base/files/scoped_file.h"
22 #include "base/files/scoped_temp_dir.h" 22 #include "base/files/scoped_temp_dir.h"
23 #include "base/memory/ptr_util.h" 23 #include "base/memory/ptr_util.h"
24 #include "base/metrics/persistent_memory_allocator.h" 24 #include "base/metrics/persistent_memory_allocator.h"
25 #include "base/process/process_handle.h" 25 #include "base/process/process_handle.h"
26 #include "base/stl_util.h" 26 #include "base/stl_util.h"
27 #include "base/test/histogram_tester.h"
27 #include "base/threading/platform_thread.h" 28 #include "base/threading/platform_thread.h"
28 #include "components/browser_watcher/stability_data_names.h" 29 #include "components/browser_watcher/stability_data_names.h"
29 #include "components/browser_watcher/stability_report_extractor.h" 30 #include "components/browser_watcher/stability_report_extractor.h"
30 #include "testing/gmock/include/gmock/gmock.h" 31 #include "testing/gmock/include/gmock/gmock.h"
31 #include "testing/gtest/include/gtest/gtest.h" 32 #include "testing/gtest/include/gtest/gtest.h"
32 #include "third_party/crashpad/crashpad/client/crash_report_database.h" 33 #include "third_party/crashpad/crashpad/client/crash_report_database.h"
33 34
34 namespace browser_watcher { 35 namespace browser_watcher {
35 36
36 using base::debug::ActivityData; 37 using base::debug::ActivityData;
37 using base::debug::ActivityTrackerMemoryAllocator; 38 using base::debug::ActivityTrackerMemoryAllocator;
38 using base::debug::ActivityUserData; 39 using base::debug::ActivityUserData;
39 using base::debug::GlobalActivityTracker; 40 using base::debug::GlobalActivityTracker;
40 using base::debug::ThreadActivityTracker; 41 using base::debug::ThreadActivityTracker;
41 using base::File; 42 using base::File;
42 using base::FilePersistentMemoryAllocator; 43 using base::FilePersistentMemoryAllocator;
43 using base::MemoryMappedFile; 44 using base::MemoryMappedFile;
44 using base::PersistentMemoryAllocator; 45 using base::PersistentMemoryAllocator;
45 using base::WrapUnique; 46 using base::WrapUnique;
46 using crashpad::CrashReportDatabase; 47 using crashpad::CrashReportDatabase;
47 using crashpad::Settings; 48 using crashpad::Settings;
48 using crashpad::UUID; 49 using crashpad::UUID;
49 using testing::_; 50 using testing::_;
51 using testing::DoAll;
50 using testing::Return; 52 using testing::Return;
51 using testing::SetArgPointee; 53 using testing::SetArgPointee;
52 54
53 namespace { 55 namespace {
54 56
55 const char kProductName[] = "TestProduct"; 57 const char kProductName[] = "TestProduct";
56 const char kVersionNumber[] = "TestVersionNumber"; 58 const char kVersionNumber[] = "TestVersionNumber";
57 const char kChannelName[] = "TestChannel"; 59 const char kChannelName[] = "TestChannel";
58 60
59 // The tracker creates some data entries internally. 61 // The tracker creates some data entries internally.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 message.SerializeToString(&expected_serialized); 160 message.SerializeToString(&expected_serialized);
159 arg.SerializeToString(&actual_serialized); 161 arg.SerializeToString(&actual_serialized);
160 return expected_serialized == actual_serialized; 162 return expected_serialized == actual_serialized;
161 } 163 }
162 164
163 } // namespace 165 } // namespace
164 166
165 class PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest 167 class PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest
166 : public testing::Test { 168 : public testing::Test {
167 public: 169 public:
168 void SetUp() override { 170 void SetUpTest(bool system_session_clean) {
169 testing::Test::SetUp();
170 // Create a dummy debug file. 171 // Create a dummy debug file.
171 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 172 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
172 debug_file_ = temp_dir_.GetPath().AppendASCII("foo-1.pma"); 173 debug_file_ = temp_dir_.GetPath().AppendASCII("foo-1.pma");
173 { 174 {
174 base::ScopedFILE file(base::OpenFile(debug_file_, "w")); 175 base::ScopedFILE file(base::OpenFile(debug_file_, "w"));
175 ASSERT_NE(file.get(), nullptr); 176 ASSERT_NE(file.get(), nullptr);
176 } 177 }
177 ASSERT_TRUE(base::PathExists(debug_file_)); 178 ASSERT_TRUE(base::PathExists(debug_file_));
178 179
179 // Expect collection of the debug file paths. 180 // Expect collection of the debug file paths.
180 debug_file_pattern_ = FILE_PATH_LITERAL("foo-*.pma"); 181 debug_file_pattern_ = FILE_PATH_LITERAL("foo-*.pma");
181 std::vector<base::FilePath> debug_files{debug_file_}; 182 std::vector<base::FilePath> debug_files{debug_file_};
182 EXPECT_CALL(collector_, 183 EXPECT_CALL(collector_,
183 GetDebugStateFilePaths(debug_file_.DirName(), 184 GetDebugStateFilePaths(debug_file_.DirName(),
184 debug_file_pattern_, no_excluded_files_)) 185 debug_file_pattern_, no_excluded_files_))
185 .Times(1) 186 .Times(1)
186 .WillOnce(Return(debug_files)); 187 .WillOnce(Return(debug_files));
187 188
188 EXPECT_CALL(database_, GetSettings()).Times(1).WillOnce(Return(nullptr)); 189 EXPECT_CALL(database_, GetSettings()).Times(1).WillOnce(Return(nullptr));
189 190
190 // Expect a single collection call. 191 // Expect a single collection call.
192 StabilityReport report;
193 report.mutable_system_state()->set_session_state(
194 system_session_clean ? SystemState::CLEAN : SystemState::UNCLEAN);
191 EXPECT_CALL(collector_, CollectOneReport(debug_file_, _)) 195 EXPECT_CALL(collector_, CollectOneReport(debug_file_, _))
192 .Times(1) 196 .Times(1)
193 .WillOnce(Return(SUCCESS)); 197 .WillOnce(DoAll(SetArgPointee<1>(report), Return(SUCCESS)));
194 198
195 // Expect the call to write the proto to a minidump. This involves 199 // Expect the call to write the proto to a minidump. This involves
196 // requesting a report from the crashpad database, writing the report, then 200 // requesting a report from the crashpad database, writing the report, then
197 // finalizing it with the database. 201 // finalizing it with the database.
198 base::FilePath minidump_path = temp_dir_.GetPath().AppendASCII("foo-1.dmp"); 202 base::FilePath minidump_path = temp_dir_.GetPath().AppendASCII("foo-1.dmp");
199 base::File minidump_file( 203 base::File minidump_file(
200 minidump_path, base::File::FLAG_CREATE | base::File::File::FLAG_WRITE); 204 minidump_path, base::File::FLAG_CREATE | base::File::File::FLAG_WRITE);
201 crashpad::UUID new_report_uuid; 205 crashpad::UUID new_report_uuid;
202 new_report_uuid.InitializeWithNew(); 206 new_report_uuid.InitializeWithNew();
203 crashpad_report_ = {minidump_file.GetPlatformFile(), new_report_uuid, 207 crashpad_report_ = {minidump_file.GetPlatformFile(), new_report_uuid,
204 minidump_path}; 208 minidump_path};
205 EXPECT_CALL(database_, PrepareNewCrashReport(_)) 209 EXPECT_CALL(database_, PrepareNewCrashReport(_))
206 .Times(1) 210 .Times(1)
207 .WillOnce(DoAll(SetArgPointee<0>(&crashpad_report_), 211 .WillOnce(DoAll(SetArgPointee<0>(&crashpad_report_),
208 Return(CrashReportDatabase::kNoError))); 212 Return(CrashReportDatabase::kNoError)));
209 213
210 EXPECT_CALL(collector_, 214 EXPECT_CALL(collector_,
211 WriteReportToMinidump(_, _, _, minidump_file.GetPlatformFile())) 215 WriteReportToMinidump(_, _, _, minidump_file.GetPlatformFile()))
212 .Times(1) 216 .Times(1)
213 .WillOnce(Return(true)); 217 .WillOnce(Return(true));
214 } 218 }
219 void ValidateHistograms(int unclean_cnt, int unclean_system_cnt) {
220 histogram_tester_.ExpectTotalCount(
221 "ActivityTracker.Collect.StabilityFileCount", 1);
222 histogram_tester_.ExpectBucketCount(
223 "ActivityTracker.Collect.StabilityFileCount", 1, 1);
224 histogram_tester_.ExpectTotalCount(
225 "ActivityTracker.Collect.UncleanShutdownCount", 1);
226 histogram_tester_.ExpectBucketCount(
227 "ActivityTracker.Collect.UncleanShutdownCount", unclean_cnt, 1);
228 histogram_tester_.ExpectTotalCount(
229 "ActivityTracker.Collect.UncleanSystemCount", 1);
230 histogram_tester_.ExpectBucketCount(
231 "ActivityTracker.Collect.UncleanSystemCount", unclean_system_cnt, 1);
232 }
233 void RunBasicTest(bool is_session_clean) {
234 SetUpTest(is_session_clean);
235
236 EXPECT_CALL(database_, FinishedWritingCrashReport(&crashpad_report_, _))
237 .Times(1)
238 .WillOnce(Return(CrashReportDatabase::kNoError));
239
240 // Run the test.
241 int success_cnt = collector_.CollectAndSubmitAllPendingReports(
242 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_,
243 &database_);
244 ASSERT_EQ(1, success_cnt);
245 ASSERT_FALSE(base::PathExists(debug_file_));
246 ValidateHistograms(1, is_session_clean ? 0 : 1);
247 }
215 248
216 protected: 249 protected:
250 base::HistogramTester histogram_tester_;
217 base::ScopedTempDir temp_dir_; 251 base::ScopedTempDir temp_dir_;
218 base::FilePath debug_file_; 252 base::FilePath debug_file_;
219 MockCrashReportDatabase database_; 253 MockCrashReportDatabase database_;
220 MockPostmortemReportCollector collector_; 254 MockPostmortemReportCollector collector_;
221 base::FilePath::StringType debug_file_pattern_; 255 base::FilePath::StringType debug_file_pattern_;
222 std::set<base::FilePath> no_excluded_files_; 256 std::set<base::FilePath> no_excluded_files_;
223 CrashReportDatabase::NewReport crashpad_report_; 257 CrashReportDatabase::NewReport crashpad_report_;
224 }; 258 };
225 259
226 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest, 260 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest,
227 CollectAndSubmitAllPendingReports) { 261 CollectAndSubmitAllPendingReportsCleanSession) {
228 EXPECT_CALL(database_, FinishedWritingCrashReport(&crashpad_report_, _)) 262 RunBasicTest(true);
Sigurður Ásgeirsson 2017/05/18 12:45:03 ubernit: at the cost of a single additional line o
manzagop (departed) 2017/05/18 14:52:12 Done.
229 .Times(1) 263 }
230 .WillOnce(Return(CrashReportDatabase::kNoError));
231 264
232 // Run the test. 265 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest,
233 int success_cnt = collector_.CollectAndSubmitAllPendingReports( 266 CollectAndSubmitAllPendingReportsUncleanSession) {
234 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_, 267 RunBasicTest(false);
235 &database_);
236 ASSERT_EQ(1, success_cnt);
237 ASSERT_FALSE(base::PathExists(debug_file_));
238 } 268 }
239 269
240 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest, 270 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest,
241 CollectAndSubmitAllPendingReportsStuckFile) { 271 CollectAndSubmitAllPendingReportsStuckFile) {
272 SetUpTest(true);
273 base::HistogramTester histogram_tester;
Sigurður Ásgeirsson 2017/05/18 12:45:03 do you need this in addition to the member variabl
manzagop (departed) 2017/05/18 14:52:12 Done.
274
242 // Open the stability debug file to prevent its deletion. 275 // Open the stability debug file to prevent its deletion.
243 base::ScopedFILE file(base::OpenFile(debug_file_, "w")); 276 base::ScopedFILE file(base::OpenFile(debug_file_, "w"));
244 ASSERT_NE(file.get(), nullptr); 277 ASSERT_NE(file.get(), nullptr);
245 278
246 // Expect Crashpad is notified of an error writing the crash report. 279 // Expect Crashpad is notified of an error writing the crash report.
247 EXPECT_CALL(database_, ErrorWritingCrashReport(&crashpad_report_)) 280 EXPECT_CALL(database_, ErrorWritingCrashReport(&crashpad_report_))
248 .Times(1) 281 .Times(1)
249 .WillOnce(Return(CrashReportDatabase::kNoError)); 282 .WillOnce(Return(CrashReportDatabase::kNoError));
250 283
251 // Run the test. 284 // Run the test.
252 int success_cnt = collector_.CollectAndSubmitAllPendingReports( 285 int success_cnt = collector_.CollectAndSubmitAllPendingReports(
253 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_, 286 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_,
254 &database_); 287 &database_);
255 ASSERT_EQ(0, success_cnt); 288 ASSERT_EQ(0, success_cnt);
256 ASSERT_TRUE(base::PathExists(debug_file_)); 289 ASSERT_TRUE(base::PathExists(debug_file_));
290 ValidateHistograms(0, 0);
257 } 291 }
258 292
259 TEST(PostmortemReportCollectorTest, GetDebugStateFilePaths) { 293 TEST(PostmortemReportCollectorTest, GetDebugStateFilePaths) {
260 base::ScopedTempDir temp_dir; 294 base::ScopedTempDir temp_dir;
261 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 295 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
262 296
263 // Create files. 297 // Create files.
264 std::vector<base::FilePath> expected_paths; 298 std::vector<base::FilePath> expected_paths;
265 std::set<base::FilePath> excluded_paths; 299 std::set<base::FilePath> excluded_paths;
266 { 300 {
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
753 PostmortemReportCollector collector(kProductName, kVersionNumber, 787 PostmortemReportCollector collector(kProductName, kVersionNumber,
754 kChannelName, &analyzer); 788 kChannelName, &analyzer);
755 StabilityReport report; 789 StabilityReport report;
756 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); 790 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report));
757 791
758 // Validate the report. 792 // Validate the report.
759 ASSERT_EQ(SystemState::CLEAN, report.system_state().session_state()); 793 ASSERT_EQ(SystemState::CLEAN, report.system_state().session_state());
760 } 794 }
761 795
762 } // namespace browser_watcher 796 } // namespace browser_watcher
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698