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

Side by Side Diff: test/win/win_multiprocess.h

Issue 1164453003: Refactor multiprocess test code to allow multiple child processes to be launched. (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@multiprocess_test
Patch Set: Review comment. Created 5 years, 5 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
« no previous file with comments | « test/win/win_child_process_test.cc ('k') | test/win/win_multiprocess.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Crashpad Authors. All rights reserved. 1 // Copyright 2015 The Crashpad Authors. All rights reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License. 4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and 12 // See the License for the specific language governing permissions and
13 // limitations under the License. 13 // limitations under the License.
14 14
15 #ifndef CRASHPAD_TEST_WIN_WIN_MULTIPROCESS_H_ 15 #ifndef CRASHPAD_TEST_WIN_WIN_MULTIPROCESS_H_
16 #define CRASHPAD_TEST_WIN_WIN_MULTIPROCESS_H_ 16 #define CRASHPAD_TEST_WIN_WIN_MULTIPROCESS_H_
17 17
18 #include <windows.h> 18 #include <windows.h>
19 19
20 #include "base/basictypes.h" 20 #include "base/basictypes.h"
21 #include "gtest/gtest.h"
22 #include "test/win/win_child_process.h"
21 #include "util/file/file_io.h" 23 #include "util/file/file_io.h"
22 #include "util/win/scoped_handle.h" 24 #include "util/win/scoped_handle.h"
23 25
24 namespace crashpad { 26 namespace crashpad {
25 namespace test { 27 namespace test {
26 28
27 //! \brief Manages a multiprocess test on Windows. 29 //! \brief Manages a multiprocess test on Windows.
28 class WinMultiprocess { 30 class WinMultiprocess {
29 public: 31 public:
30 WinMultiprocess(); 32 WinMultiprocess();
31 33
32 //! \brief Runs the test. 34 //! \brief Runs the test.
33 //! 35 //!
34 //! This method establishes the testing environment by respawning the process 36 //! This method establishes the testing environment by respawning the process
35 //! as a child with additional flags. 37 //! as a child with additional flags.
36 //! 38 //!
37 //! In the parent process, WinMultiprocessParent() is run, and in the child 39 //! In the parent process, WinMultiprocessParent() is run, and in the child
38 //! WinMultiprocessChild(). 40 //! WinMultiprocessChild().
39 void Run(); 41 template <class T>
42 static void Run() {
43 ASSERT_NO_FATAL_FAILURE(
44 WinChildProcess::EntryPoint<ChildProcessHelper<T>>());
45 // If WinChildProcess::EntryPoint returns, we are in the parent process.
46 scoped_ptr<WinChildProcess::Handles> child_handles =
47 WinChildProcess::Launch();
48 ASSERT_TRUE(child_handles.get());
49 T parent_process;
50 parent_process.child_handles_ = child_handles.get();
51 static_cast<WinMultiprocess*>(&parent_process)->WinMultiprocessParent();
52
53 // Close our side of the handles now that we're done. The child can
54 // use this to know when it's safe to complete.
55 child_handles->read.reset();
56 child_handles->write.reset();
57
58 // Wait for the child to complete.
59 ASSERT_EQ(WAIT_OBJECT_0,
60 WaitForSingleObject(child_handles->process.get(), INFINITE));
61
62 DWORD exit_code;
63 ASSERT_TRUE(GetExitCodeProcess(child_handles->process.get(), &exit_code));
64 ASSERT_EQ(parent_process.exit_code_, exit_code);
65 }
66
67 protected:
68 virtual ~WinMultiprocess();
40 69
41 //! \brief Sets the expected exit code of the child process. 70 //! \brief Sets the expected exit code of the child process.
42 //! 71 //!
43 //! The default expected termination code is `EXIT_SUCCESS` (`0`). 72 //! The default expected termination code is `EXIT_SUCCESS` (`0`).
44 //! 73 //!
45 //! \param[in] code The expected exit status of the child. 74 //! \param[in] code The expected exit status of the child.
46 void SetExpectedChildExitCode(unsigned int exit_code); 75 void SetExpectedChildExitCode(unsigned int exit_code);
47 76
48 protected:
49 virtual ~WinMultiprocess();
50
51 //! \brief Returns the read pipe's file handle. 77 //! \brief Returns the read pipe's file handle.
52 //! 78 //!
53 //! This method may be called by either the parent or the child process. 79 //! This method may be called by either the parent or the child process.
54 //! Anything written to the write pipe in the partner process will appear 80 //! Anything written to the write pipe in the partner process will appear
55 //! on this file handle in this process. 81 //! on this file handle in this process.
56 //! 82 //!
57 //! It is an error to call this after CloseReadPipe() has been called. 83 //! It is an error to call this after CloseReadPipe() has been called.
58 //! 84 //!
59 //! \return The read pipe's file handle. 85 //! \return The read pipe's file handle.
60 FileHandle ReadPipeHandle() const; 86 FileHandle ReadPipeHandle() const;
(...skipping 21 matching lines...) Expand all
82 //! attempt to read from the read pipe in the partner process will indicate 108 //! attempt to read from the read pipe in the partner process will indicate
83 //! end-of-file. WritePipeHandle() must not be called after this. 109 //! end-of-file. WritePipeHandle() must not be called after this.
84 void CloseWritePipe(); 110 void CloseWritePipe();
85 111
86 //! \brief Returns a handle to the child process. 112 //! \brief Returns a handle to the child process.
87 //! 113 //!
88 //! This method may only be called by the parent process. 114 //! This method may only be called by the parent process.
89 HANDLE ChildProcess() const; 115 HANDLE ChildProcess() const;
90 116
91 private: 117 private:
118 // Implements an adapter to provide WinMultiprocess with access to the
119 // anonymous pipe handles from WinChildProcess.
120 class ChildProcessHelperBase : public WinChildProcess {
121 public:
122 ChildProcessHelperBase() {}
123 ~ChildProcessHelperBase() override {}
124
125 void CloseWritePipeForwarder() { CloseWritePipe(); }
126 void CloseReadPipeForwarder() { CloseReadPipe(); }
127 FileHandle ReadPipeHandleForwarder() const { return ReadPipeHandle(); }
128 FileHandle WritePipeHandleForwarder() const { return WritePipeHandle(); }
129
130 private:
131 DISALLOW_COPY_AND_ASSIGN(ChildProcessHelperBase);
132 };
133
134 // Forwards WinChildProcess::Run to T::WinMultiprocessChild.
135 template <class T>
136 class ChildProcessHelper : public ChildProcessHelperBase {
137 public:
138 ChildProcessHelper() {}
139 ~ChildProcessHelper() override {}
140
141 private:
142 int Run() override {
143 T child_process;
144 child_process.child_process_helper_ = this;
145 static_cast<WinMultiprocess*>(&child_process)->WinMultiprocessChild();
146 if (testing::Test::HasFailure())
147 return 255;
148 return EXIT_SUCCESS;
149 }
150
151 DISALLOW_COPY_AND_ASSIGN(ChildProcessHelper);
152 };
153
92 //! \brief The subclass-provided parent routine. 154 //! \brief The subclass-provided parent routine.
93 //! 155 //!
94 //! Test failures should be reported via gtest: `EXPECT_*()`, `ASSERT_*()`, 156 //! Test failures should be reported via gtest: `EXPECT_*()`, `ASSERT_*()`,
95 //! `FAIL()`, etc. 157 //! `FAIL()`, etc.
96 //! 158 //!
97 //! This method need not use `WaitForSingleObject()`-family call to wait for 159 //! This method need not use `WaitForSingleObject()`-family call to wait for
98 //! the child process to exit, as this is handled by this class. 160 //! the child process to exit, as this is handled by this class.
99 //! 161 //!
100 //! Subclasses must implement this method to define how the parent operates. 162 //! Subclasses must implement this method to define how the parent operates.
101 virtual void WinMultiprocessParent() = 0; 163 virtual void WinMultiprocessParent() = 0;
102 164
103 //! \brief The subclass-provided child routine. 165 //! \brief The subclass-provided child routine.
104 //! 166 //!
105 //! Test failures should be reported via gtest: `EXPECT_*()`, `ASSERT_*()`, 167 //! Test failures should be reported via gtest: `EXPECT_*()`, `ASSERT_*()`,
106 //! `FAIL()`, etc. 168 //! `FAIL()`, etc.
107 //! 169 //!
108 //! Subclasses must implement this method to define how the child operates. 170 //! Subclasses must implement this method to define how the child operates.
109 //! Subclasses may exit with a failure status by using `LOG(FATAL)`, 171 //! Subclasses may exit with a failure status by using `LOG(FATAL)`,
110 //! `abort()`, or similar. They may exit cleanly by returning from this 172 //! `abort()`, or similar. They may exit cleanly by returning from this
111 //! method. 173 //! method.
112 virtual void WinMultiprocessChild() = 0; 174 virtual void WinMultiprocessChild() = 0;
113 175
114 ScopedFileHANDLE pipe_c2p_read_;
115 ScopedFileHANDLE pipe_c2p_write_;
116 ScopedFileHANDLE pipe_p2c_read_;
117 ScopedFileHANDLE pipe_p2c_write_;
118 ScopedKernelHANDLE child_handle_;
119 unsigned int exit_code_; 176 unsigned int exit_code_;
177 WinChildProcess::Handles* child_handles_;
178 ChildProcessHelperBase* child_process_helper_;
120 179
121 DISALLOW_COPY_AND_ASSIGN(WinMultiprocess); 180 DISALLOW_COPY_AND_ASSIGN(WinMultiprocess);
122 }; 181 };
123 182
124 } // namespace test 183 } // namespace test
125 } // namespace crashpad 184 } // namespace crashpad
126 185
127 #endif // CRASHPAD_TEST_WIN_WIN_MULTIPROCESS_H_ 186 #endif // CRASHPAD_TEST_WIN_WIN_MULTIPROCESS_H_
OLDNEW
« no previous file with comments | « test/win/win_child_process_test.cc ('k') | test/win/win_multiprocess.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698