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/stability_debugging_win_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 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/stability_debugging.h" 5 #include "components/browser_watcher/stability_debugging.h"
6 6
7 #include "base/files/file_enumerator.h" 7 #include <windows.h>
8
9 #include "base/command_line.h"
10 #include "base/debug/activity_tracker.h"
8 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
9 #include "base/files/file_util.h" 12 #include "base/files/file_util.h"
10 #include "base/files/scoped_temp_dir.h" 13 #include "base/files/scoped_temp_dir.h"
11 #include "base/process/process.h" 14 #include "base/process/process.h"
12 #include "base/test/multiprocess_test.h" 15 #include "base/test/multiprocess_test.h"
13 #include "components/browser_watcher/stability_paths.h" 16 #include "base/test/test_timeouts.h"
17 #include "components/browser_watcher/stability_report.pb.h"
18 #include "components/browser_watcher/stability_report_extractor.h"
14 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
15 #include "testing/multiprocess_func_list.h" 20 #include "testing/multiprocess_func_list.h"
16 21
17 namespace browser_watcher { 22 namespace browser_watcher {
18 23
19 class StabilityDebuggingWinMultiProcTest : public base::MultiProcessTest {}; 24 using base::debug::GlobalActivityTracker;
20 25
21 MULTIPROCESS_TEST_MAIN(DummyProcess) { 26 const int kMemorySize = 1 << 20; // 1MiB
27 const char* kDebugFileSwitch = "stability_debugging_test_debug_file_switch";
28
29 class StabilityDebuggingTest : public base::MultiProcessTest {
30 public:
31 StabilityDebuggingTest() {}
32 ~StabilityDebuggingTest() override = default;
33
34 void SetUp() override {
35 testing::Test::SetUp();
36
37 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
38 debug_file_path_ = temp_dir_.GetPath().AppendASCII("debug.pma");
39 }
40
41 const base::FilePath& debug_file_path() { return debug_file_path_; }
42
43 protected:
44 base::CommandLine MakeCmdLine(const std::string& procname) override {
45 base::CommandLine cmd = base::MultiProcessTest::MakeCmdLine(procname);
46 cmd.AppendSwitchPath(kDebugFileSwitch, debug_file_path_);
47 return cmd;
48 }
49
50 base::ScopedTempDir temp_dir_;
51 base::FilePath debug_file_path_;
52 };
53
54 // Creates a global tracker, registers a vectored exception handler, then
55 // crashes.
56 MULTIPROCESS_TEST_MAIN(CrashingProcess) {
57 base::FilePath debug_path =
58 base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
59 kDebugFileSwitch);
60 GlobalActivityTracker::CreateWithFile(debug_path, kMemorySize, 0ULL, "", 3);
61 RegisterStabilityVEH();
62
63 // Crash!
64 char* invalid = nullptr;
Sigurður Ásgeirsson 2017/06/09 13:55:15 I'm not sure the compiler is obliged to honor your
manzagop (departed) 2017/06/09 21:27:35 Switched to a single process test, as that's simpl
65 *invalid = 42;
66
22 return 0; 67 return 0;
23 } 68 }
24 69
25 TEST_F(StabilityDebuggingWinMultiProcTest, GetStabilityFileForProcessTest) { 70 TEST_F(StabilityDebuggingTest, CrashingTest) {
26 const base::FilePath empty_path; 71 base::SpawnChildResult spawn_result = SpawnChild("CrashingProcess");
72 int exit_code;
73 EXPECT_TRUE(spawn_result.process.WaitForExitWithTimeout(
74 TestTimeouts::action_max_timeout(), &exit_code));
27 75
28 // Get the path for the current process. 76 // Collect the report.
29 base::FilePath stability_path; 77 StabilityReport report;
30 ASSERT_TRUE(GetStabilityFileForProcess(base::Process::Current(), empty_path, 78 ASSERT_EQ(SUCCESS, Extract(debug_file_path(), &report));
31 &stability_path));
32 79
33 // Ensure requesting a second time produces the same. 80 // Validate expectations: 1 process with 1 thread that has an exception.
Sigurður Ásgeirsson 2017/06/09 13:55:15 My bet is that this is going to flake a bit, as yo
manzagop (departed) 2017/06/09 21:27:35 Sgtm! Actually, I'm in the same thread it's easy t
34 base::FilePath stability_path_two; 81 ASSERT_EQ(1, report.process_states_size());
35 ASSERT_TRUE(GetStabilityFileForProcess(base::Process::Current(), empty_path, 82 const ProcessState& process_state = report.process_states(0);
36 &stability_path_two)); 83 EXPECT_EQ(spawn_result.process.Pid(), process_state.process_id());
37 EXPECT_EQ(stability_path, stability_path_two); 84 ASSERT_EQ(1, process_state.threads_size());
38 85 const ThreadState& thread_state = process_state.threads(0);
39 // Ensure a different process has a different stability path. 86 ASSERT_TRUE(thread_state.has_exception());
40 base::SpawnChildResult spawn_result = SpawnChild("DummyProcess"); 87 const Exception& exception = thread_state.exception();
41 base::FilePath stability_path_other; 88 EXPECT_EQ(EXCEPTION_ACCESS_VIOLATION, exception.code());
42 ASSERT_TRUE(GetStabilityFileForProcess(spawn_result.process, empty_path,
43 &stability_path_other));
44 EXPECT_NE(stability_path, stability_path_other);
45 }
46
47 TEST(StabilityDebuggingWinTest,
48 GetStabilityFilePatternMatchesGetStabilityFileForProcessResult) {
49 // GetStabilityFileForProcess file names must match GetStabilityFilePattern
50 // according to
51 // FileEnumerator's algorithm. We test this by writing out some files and
52 // validating what is matched.
53
54 base::ScopedTempDir temp_dir;
55 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
56 base::FilePath user_data_dir = temp_dir.GetPath();
57
58 // Create the stability directory.
59 base::FilePath stability_dir = GetStabilityDir(user_data_dir);
60 ASSERT_TRUE(base::CreateDirectory(stability_dir));
61
62 // Write a stability file.
63 base::FilePath stability_file;
64 ASSERT_TRUE(GetStabilityFileForProcess(base::Process::Current(),
65 user_data_dir, &stability_file));
66 {
67 base::ScopedFILE file(base::OpenFile(stability_file, "w"));
68 ASSERT_TRUE(file.get());
69 }
70
71 // Write a file that shouldn't match.
72 base::FilePath non_matching_file =
73 stability_dir.AppendASCII("non_matching.foo");
74 {
75 base::ScopedFILE file(base::OpenFile(non_matching_file, "w"));
76 ASSERT_TRUE(file.get());
77 }
78
79 // Validate only the stability file matches.
80 base::FileEnumerator enumerator(stability_dir, false /* recursive */,
81 base::FileEnumerator::FILES,
82 GetStabilityFilePattern());
83 ASSERT_EQ(stability_file, enumerator.Next());
84 ASSERT_TRUE(enumerator.Next().empty());
85 } 89 }
86 90
87 } // namespace browser_watcher 91 } // namespace browser_watcher
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698