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

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

Issue 2883103002: Quantify instability according to the stability instrumentation (Closed)
Patch Set: final nit 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 CollectReports(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 }
215 247
216 protected: 248 protected:
249 base::HistogramTester histogram_tester_;
217 base::ScopedTempDir temp_dir_; 250 base::ScopedTempDir temp_dir_;
218 base::FilePath debug_file_; 251 base::FilePath debug_file_;
219 MockCrashReportDatabase database_; 252 MockCrashReportDatabase database_;
220 MockPostmortemReportCollector collector_; 253 MockPostmortemReportCollector collector_;
221 base::FilePath::StringType debug_file_pattern_; 254 base::FilePath::StringType debug_file_pattern_;
222 std::set<base::FilePath> no_excluded_files_; 255 std::set<base::FilePath> no_excluded_files_;
223 CrashReportDatabase::NewReport crashpad_report_; 256 CrashReportDatabase::NewReport crashpad_report_;
224 }; 257 };
225 258
226 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest, 259 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest,
227 CollectAndSubmitAllPendingReports) { 260 CollectAndSubmitAllPendingReportsCleanSession) {
228 EXPECT_CALL(database_, FinishedWritingCrashReport(&crashpad_report_, _)) 261 CollectReports(true);
229 .Times(1) 262 int expected_unclean = 1;
230 .WillOnce(Return(CrashReportDatabase::kNoError)); 263 int expected_system_unclean = 0;
264 ValidateHistograms(expected_unclean, expected_system_unclean);
265 }
231 266
232 // Run the test. 267 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest,
233 int success_cnt = collector_.CollectAndSubmitAllPendingReports( 268 CollectAndSubmitAllPendingReportsUncleanSession) {
234 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_, 269 CollectReports(false);
235 &database_); 270 int expected_unclean = 1;
236 ASSERT_EQ(1, success_cnt); 271 int expected_system_unclean = 1;
237 ASSERT_FALSE(base::PathExists(debug_file_)); 272 ValidateHistograms(expected_unclean, expected_system_unclean);
238 } 273 }
239 274
240 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest, 275 TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest,
241 CollectAndSubmitAllPendingReportsStuckFile) { 276 CollectAndSubmitAllPendingReportsStuckFile) {
277 SetUpTest(true);
278
242 // Open the stability debug file to prevent its deletion. 279 // Open the stability debug file to prevent its deletion.
243 base::ScopedFILE file(base::OpenFile(debug_file_, "w")); 280 base::ScopedFILE file(base::OpenFile(debug_file_, "w"));
244 ASSERT_NE(file.get(), nullptr); 281 ASSERT_NE(file.get(), nullptr);
245 282
246 // Expect Crashpad is notified of an error writing the crash report. 283 // Expect Crashpad is notified of an error writing the crash report.
247 EXPECT_CALL(database_, ErrorWritingCrashReport(&crashpad_report_)) 284 EXPECT_CALL(database_, ErrorWritingCrashReport(&crashpad_report_))
248 .Times(1) 285 .Times(1)
249 .WillOnce(Return(CrashReportDatabase::kNoError)); 286 .WillOnce(Return(CrashReportDatabase::kNoError));
250 287
251 // Run the test. 288 // Run the test.
252 int success_cnt = collector_.CollectAndSubmitAllPendingReports( 289 int success_cnt = collector_.CollectAndSubmitAllPendingReports(
253 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_, 290 debug_file_.DirName(), debug_file_pattern_, no_excluded_files_,
254 &database_); 291 &database_);
255 ASSERT_EQ(0, success_cnt); 292 ASSERT_EQ(0, success_cnt);
256 ASSERT_TRUE(base::PathExists(debug_file_)); 293 ASSERT_TRUE(base::PathExists(debug_file_));
294
295 int expected_unclean = 0;
296 int expected_system_unclean = 0;
297 ValidateHistograms(expected_unclean, expected_system_unclean);
257 } 298 }
258 299
259 TEST(PostmortemReportCollectorTest, GetDebugStateFilePaths) { 300 TEST(PostmortemReportCollectorTest, GetDebugStateFilePaths) {
260 base::ScopedTempDir temp_dir; 301 base::ScopedTempDir temp_dir;
261 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 302 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
262 303
263 // Create files. 304 // Create files.
264 std::vector<base::FilePath> expected_paths; 305 std::vector<base::FilePath> expected_paths;
265 std::set<base::FilePath> excluded_paths; 306 std::set<base::FilePath> excluded_paths;
266 { 307 {
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
753 PostmortemReportCollector collector(kProductName, kVersionNumber, 794 PostmortemReportCollector collector(kProductName, kVersionNumber,
754 kChannelName, &analyzer); 795 kChannelName, &analyzer);
755 StabilityReport report; 796 StabilityReport report;
756 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report)); 797 ASSERT_EQ(SUCCESS, collector.CollectOneReport(debug_file_path(), &report));
757 798
758 // Validate the report. 799 // Validate the report.
759 ASSERT_EQ(SystemState::CLEAN, report.system_state().session_state()); 800 ASSERT_EQ(SystemState::CLEAN, report.system_state().session_state());
760 } 801 }
761 802
762 } // namespace browser_watcher 803 } // namespace browser_watcher
OLDNEW
« no previous file with comments | « components/browser_watcher/postmortem_report_collector.cc ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698