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

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

Issue 2927653003: Stability instrumentation: add a Vectored Exception Handler (Closed)
Patch Set: Add unittest Created 3 years, 6 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 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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/stability_report_extractor.h" 5 #include "components/browser_watcher/stability_report_extractor.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/debug/activity_tracker.h" 10 #include "base/debug/activity_tracker.h"
11 #include "base/files/file.h" 11 #include "base/files/file.h"
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/files/memory_mapped_file.h" 13 #include "base/files/memory_mapped_file.h"
14 #include "base/files/scoped_temp_dir.h" 14 #include "base/files/scoped_temp_dir.h"
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "base/metrics/persistent_memory_allocator.h" 16 #include "base/metrics/persistent_memory_allocator.h"
17 #include "base/stl_util.h" 17 #include "base/stl_util.h"
18 #include "base/time/time.h"
18 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
19 #include "third_party/crashpad/crashpad/client/crash_report_database.h" 20 #include "third_party/crashpad/crashpad/client/crash_report_database.h"
20 21
21 namespace browser_watcher { 22 namespace browser_watcher {
22 23
23 using base::debug::ActivityData; 24 using base::debug::ActivityData;
24 using base::debug::ActivityTrackerMemoryAllocator; 25 using base::debug::ActivityTrackerMemoryAllocator;
25 using base::debug::ActivityUserData; 26 using base::debug::ActivityUserData;
26 using base::debug::GlobalActivityTracker; 27 using base::debug::GlobalActivityTracker;
27 using base::debug::ThreadActivityTracker; 28 using base::debug::ThreadActivityTracker;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 mem_reference, GlobalActivityTracker::kTypeIdActivityTracker, 112 mem_reference, GlobalActivityTracker::kTypeIdActivityTracker,
112 PersistentMemoryAllocator::kSizeAny); 113 PersistentMemoryAllocator::kSizeAny);
113 if (mem_base == nullptr) 114 if (mem_base == nullptr)
114 return nullptr; 115 return nullptr;
115 116
116 // Make the allocation iterable so it can be found by other processes. 117 // Make the allocation iterable so it can be found by other processes.
117 allocator->MakeIterable(mem_reference); 118 allocator->MakeIterable(mem_reference);
118 119
119 return WrapUnique(new ThreadActivityTracker(mem_base, tracker_mem_size)); 120 return WrapUnique(new ThreadActivityTracker(mem_base, tracker_mem_size));
120 } 121 }
122 void PerformBasicReportValidation(const StabilityReport& report) {
123 // One report with one thread that has the expected name and id.
124 ASSERT_EQ(1, report.process_states_size());
125 const ProcessState& process_state = report.process_states(0);
126 EXPECT_EQ(base::GetCurrentProcId(), process_state.process_id());
127 ASSERT_EQ(1, process_state.threads_size());
128 const ThreadState& thread_state = process_state.threads(0);
129 EXPECT_EQ(base::PlatformThread::GetName(), thread_state.thread_name());
130 #if defined(OS_WIN)
131 EXPECT_EQ(base::PlatformThread::CurrentId(), thread_state.thread_id());
132 #elif defined(OS_POSIX)
133 EXPECT_EQ(base::PlatformThread::CurrentHandle().platform_handle(),
134 thread_state.thread_id());
135 #endif
136 }
121 137
122 const FilePath& debug_file_path() const { return debug_file_path_; } 138 const FilePath& debug_file_path() const { return debug_file_path_; }
123 139
124 protected: 140 protected:
125 base::ScopedTempDir temp_dir_; 141 base::ScopedTempDir temp_dir_;
126 FilePath debug_file_path_; 142 FilePath debug_file_path_;
127 143
128 std::unique_ptr<PersistentMemoryAllocator> allocator_; 144 std::unique_ptr<PersistentMemoryAllocator> allocator_;
129 std::unique_ptr<ThreadActivityTracker> tracker_; 145 std::unique_ptr<ThreadActivityTracker> tracker_;
130 }; 146 };
(...skipping 25 matching lines...) Expand all
156 GlobalActivityTracker::kTypeIdUserDataRecordFree, 1024U, 10U, false); 172 GlobalActivityTracker::kTypeIdUserDataRecordFree, 1024U, 10U, false);
157 std::unique_ptr<ActivityUserData> user_data = 173 std::unique_ptr<ActivityUserData> user_data =
158 tracker_->GetUserData(activity_id, &user_data_allocator); 174 tracker_->GetUserData(activity_id, &user_data_allocator);
159 user_data->SetInt("some_int", 42); 175 user_data->SetInt("some_int", 42);
160 176
161 // Validate collection returns the expected report. 177 // Validate collection returns the expected report.
162 StabilityReport report; 178 StabilityReport report;
163 ASSERT_EQ(SUCCESS, Extract(debug_file_path(), &report)); 179 ASSERT_EQ(SUCCESS, Extract(debug_file_path(), &report));
164 180
165 // Validate the report. 181 // Validate the report.
166 ASSERT_EQ(1, report.process_states_size()); 182 ASSERT_NO_FATAL_FAILURE(PerformBasicReportValidation(report));
167 const ProcessState& process_state = report.process_states(0); 183 const ThreadState& thread_state = report.process_states(0).threads(0);
168 EXPECT_EQ(base::GetCurrentProcId(), process_state.process_id());
169 ASSERT_EQ(1, process_state.threads_size());
170
171 const ThreadState& thread_state = process_state.threads(0);
172 EXPECT_EQ(base::PlatformThread::GetName(), thread_state.thread_name());
173 #if defined(OS_WIN)
174 EXPECT_EQ(base::PlatformThread::CurrentId(), thread_state.thread_id());
175 #elif defined(OS_POSIX)
176 EXPECT_EQ(base::PlatformThread::CurrentHandle().platform_handle(),
177 thread_state.thread_id());
178 #endif
179 184
180 EXPECT_EQ(7, thread_state.activity_count()); 185 EXPECT_EQ(7, thread_state.activity_count());
181 ASSERT_EQ(6, thread_state.activities_size()); 186 ASSERT_EQ(6, thread_state.activities_size());
182 { 187 {
183 const Activity& activity = thread_state.activities(0); 188 const Activity& activity = thread_state.activities(0);
184 EXPECT_EQ(Activity::ACT_TASK_RUN, activity.type()); 189 EXPECT_EQ(Activity::ACT_TASK_RUN, activity.type());
185 EXPECT_EQ(kTaskOrigin, activity.origin_address()); 190 EXPECT_EQ(kTaskOrigin, activity.origin_address());
186 EXPECT_EQ(kTaskSequenceNum, activity.task_sequence_id()); 191 EXPECT_EQ(kTaskSequenceNum, activity.task_sequence_id());
187 EXPECT_EQ(0U, activity.user_data().size()); 192 EXPECT_EQ(0U, activity.user_data().size());
188 } 193 }
(...skipping 27 matching lines...) Expand all
216 } 221 }
217 { 222 {
218 const Activity& activity = thread_state.activities(5); 223 const Activity& activity = thread_state.activities(5);
219 EXPECT_EQ(Activity::ACT_GENERIC, activity.type()); 224 EXPECT_EQ(Activity::ACT_GENERIC, activity.type());
220 EXPECT_EQ(kGenericId, activity.generic_id()); 225 EXPECT_EQ(kGenericId, activity.generic_id());
221 EXPECT_EQ(kGenericData, activity.generic_data()); 226 EXPECT_EQ(kGenericData, activity.generic_data());
222 EXPECT_EQ(0U, activity.user_data().size()); 227 EXPECT_EQ(0U, activity.user_data().size());
223 } 228 }
224 } 229 }
225 230
231 TEST_F(StabilityReportExtractorThreadTrackerTest, CollectException) {
232 const void* expected_pc = reinterpret_cast<void*>(0xCAFE);
233 const void* expected_address = nullptr;
234 const uint32_t expected_code = 42U;
235
236 // Record an exception.
237 const int64_t timestamp = base::Time::Now().ToInternalValue();
238 tracker_->RecordExceptionActivity(expected_pc, expected_address,
239 base::debug::Activity::ACT_EXCEPTION,
240 ActivityData::ForException(expected_code));
241
242 // Collect report and validate.
243 StabilityReport report;
244 ASSERT_EQ(SUCCESS, Extract(debug_file_path(), &report));
245
246 // Validate the presence of the exception.
247 ASSERT_NO_FATAL_FAILURE(PerformBasicReportValidation(report));
248 const ThreadState& thread_state = report.process_states(0).threads(0);
249 ASSERT_TRUE(thread_state.has_exception());
250 const Exception& exception = thread_state.exception();
251 EXPECT_EQ(expected_code, exception.code());
252 EXPECT_EQ(expected_pc, reinterpret_cast<void*>(exception.program_counter()));
253 EXPECT_EQ(expected_address,
254 reinterpret_cast<void*>(exception.exception_address()));
255 const int64_t tolerance_us = 1000ULL;
256 EXPECT_LE(std::abs(timestamp - exception.time()), tolerance_us);
257 }
258
259 TEST_F(StabilityReportExtractorThreadTrackerTest, CollectNoException) {
Sigurður Ásgeirsson 2017/06/09 13:55:15 nice testing, I like it!
manzagop (departed) 2017/06/09 21:27:35 Thanks you sir! Ack.
260 // Record something.
261 tracker_->PushActivity(reinterpret_cast<void*>(kTaskOrigin),
262 base::debug::Activity::ACT_TASK_RUN,
263 ActivityData::ForTask(kTaskSequenceNum));
264
265 // Collect report and validate there is no exception.
266 StabilityReport report;
267 ASSERT_EQ(SUCCESS, Extract(debug_file_path(), &report));
268 ASSERT_NO_FATAL_FAILURE(PerformBasicReportValidation(report));
269 const ThreadState& thread_state = report.process_states(0).threads(0);
270 ASSERT_FALSE(thread_state.has_exception());
271 }
272
226 // Tests stability report extraction. 273 // Tests stability report extraction.
227 class StabilityReportExtractorTest : public testing::Test { 274 class StabilityReportExtractorTest : public testing::Test {
228 public: 275 public:
229 const int kMemorySize = 1 << 20; // 1MiB 276 const int kMemorySize = 1 << 20; // 1MiB
230 277
231 StabilityReportExtractorTest() {} 278 StabilityReportExtractorTest() {}
232 ~StabilityReportExtractorTest() override { 279 ~StabilityReportExtractorTest() override {
233 GlobalActivityTracker* global_tracker = GlobalActivityTracker::Get(); 280 GlobalActivityTracker* global_tracker = GlobalActivityTracker::Get();
234 if (global_tracker) { 281 if (global_tracker) {
235 global_tracker->ReleaseTrackerForCurrentThreadForTesting(); 282 global_tracker->ReleaseTrackerForCurrentThreadForTesting();
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 EXPECT_EQ("CAFECAFE2d000", collected_module.code_identifier()); 447 EXPECT_EQ("CAFECAFE2d000", collected_module.code_identifier());
401 EXPECT_EQ(module_info.debug_file, collected_module.debug_file()); 448 EXPECT_EQ(module_info.debug_file, collected_module.debug_file());
402 EXPECT_EQ("1122334455667788ABCD0123456789AB1", 449 EXPECT_EQ("1122334455667788ABCD0123456789AB1",
403 collected_module.debug_identifier()); 450 collected_module.debug_identifier());
404 EXPECT_EQ("", collected_module.version()); 451 EXPECT_EQ("", collected_module.version());
405 EXPECT_EQ(0LL, collected_module.shrink_down_delta()); 452 EXPECT_EQ(0LL, collected_module.shrink_down_delta());
406 EXPECT_EQ(!module_info.is_loaded, collected_module.is_unloaded()); 453 EXPECT_EQ(!module_info.is_loaded, collected_module.is_unloaded());
407 } 454 }
408 455
409 } // namespace browser_watcher 456 } // namespace browser_watcher
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698