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

Side by Side Diff: util/test/multiprocess_posix_test.cc

Issue 1051533002: test: Move util/test to its own top-level directory, test (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Rebase Created 5 years, 8 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
(Empty)
1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (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
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "util/test/multiprocess.h"
16
17 #include <stdlib.h>
18 #include <sys/signal.h>
19 #include <unistd.h>
20
21 #include "base/basictypes.h"
22 #include "gtest/gtest.h"
23 #include "util/file/file_io.h"
24 #include "util/test/gtest_death_check.h"
25
26 namespace crashpad {
27 namespace test {
28 namespace {
29
30 class TestMultiprocess final : public Multiprocess {
31 public:
32 TestMultiprocess() : Multiprocess() {}
33
34 ~TestMultiprocess() {}
35
36 private:
37 // Multiprocess:
38
39 void MultiprocessParent() override {
40 FileHandle read_handle = ReadPipeHandle();
41 char c;
42 CheckedReadFile(read_handle, &c, 1);
43 EXPECT_EQ('M', c);
44
45 pid_t pid;
46 CheckedReadFile(read_handle, &pid, sizeof(pid));
47 EXPECT_EQ(pid, ChildPID());
48
49 c = 'm';
50 CheckedWriteFile(WritePipeHandle(), &c, 1);
51
52 // The child will close its end of the pipe and exit. Make sure that the
53 // parent sees EOF.
54 CheckedReadFileAtEOF(read_handle);
55 }
56
57 void MultiprocessChild() override {
58 FileHandle write_handle = WritePipeHandle();
59
60 char c = 'M';
61 CheckedWriteFile(write_handle, &c, 1);
62
63 pid_t pid = getpid();
64 CheckedWriteFile(write_handle, &pid, sizeof(pid));
65
66 CheckedReadFile(ReadPipeHandle(), &c, 1);
67 EXPECT_EQ('m', c);
68 }
69
70 DISALLOW_COPY_AND_ASSIGN(TestMultiprocess);
71 };
72
73 TEST(Multiprocess, Multiprocess) {
74 TestMultiprocess multiprocess;
75 multiprocess.Run();
76 }
77
78 class TestMultiprocessUnclean final : public Multiprocess {
79 public:
80 enum TerminationType {
81 kExitSuccess = 0,
82 kExitFailure,
83 kExit2,
84 kAbort,
85 };
86
87 explicit TestMultiprocessUnclean(TerminationType type)
88 : Multiprocess(),
89 type_(type) {
90 if (type_ == kAbort) {
91 SetExpectedChildTermination(kTerminationSignal, SIGABRT);
92 } else {
93 SetExpectedChildTermination(kTerminationNormal, ExitCode());
94 }
95 }
96
97 ~TestMultiprocessUnclean() {}
98
99 private:
100 int ExitCode() const {
101 return type_;
102 }
103
104 // Multiprocess:
105
106 void MultiprocessParent() override {
107 }
108
109 void MultiprocessChild() override {
110 if (type_ == kAbort) {
111 abort();
112 } else {
113 _exit(ExitCode());
114 }
115 }
116
117 TerminationType type_;
118
119 DISALLOW_COPY_AND_ASSIGN(TestMultiprocessUnclean);
120 };
121
122 TEST(Multiprocess, SuccessfulExit) {
123 TestMultiprocessUnclean multiprocess(TestMultiprocessUnclean::kExitSuccess);
124 multiprocess.Run();
125 }
126
127 TEST(Multiprocess, UnsuccessfulExit) {
128 TestMultiprocessUnclean multiprocess(TestMultiprocessUnclean::kExitFailure);
129 multiprocess.Run();
130 }
131
132 TEST(Multiprocess, Exit2) {
133 TestMultiprocessUnclean multiprocess(TestMultiprocessUnclean::kExit2);
134 multiprocess.Run();
135 }
136
137 TEST(Multiprocess, AbortSignal) {
138 TestMultiprocessUnclean multiprocess(TestMultiprocessUnclean::kAbort);
139 multiprocess.Run();
140 }
141
142 class TestMultiprocessClosePipe final : public Multiprocess {
143 public:
144 enum WhoCloses {
145 kParentCloses = 0,
146 kChildCloses,
147 };
148 enum WhatCloses {
149 kReadCloses = 0,
150 kWriteCloses,
151 kReadAndWriteClose,
152 };
153
154 TestMultiprocessClosePipe(WhoCloses who_closes, WhatCloses what_closes)
155 : Multiprocess(),
156 who_closes_(who_closes),
157 what_closes_(what_closes) {
158 }
159
160 ~TestMultiprocessClosePipe() {}
161
162 private:
163 void VerifyInitial() {
164 ASSERT_NE(-1, ReadPipeHandle());
165 ASSERT_NE(-1, WritePipeHandle());
166 }
167
168 // Verifies that the partner process did what it was supposed to do. This must
169 // only be called when who_closes_ names the partner process, not this
170 // process.
171 //
172 // If the partner was supposed to close its write pipe, the read pipe will be
173 // checked to ensure that it shows end-of-file.
174 //
175 // If the partner was supposed to close its read pipe, the write pipe will be
176 // checked to ensure that a checked write causes death. This can only be done
177 // if the partner also provides some type of signal when it has closed its
178 // read pipe, which is done in the form of it closing its write pipe, causing
179 // the read pipe in this process to show end-of-file.
180 void VerifyPartner() {
181 if (what_closes_ == kWriteCloses) {
182 CheckedReadFileAtEOF(ReadPipeHandle());
183 } else if (what_closes_ == kReadAndWriteClose) {
184 CheckedReadFileAtEOF(ReadPipeHandle());
185 char c = '\0';
186
187 // This will raise SIGPIPE. If fatal (the normal case), that will cause
188 // process termination. If SIGPIPE is being handled somewhere, the write
189 // will still fail and set errno to EPIPE, and CheckedWriteFile() will
190 // abort execution. Regardless of how SIGPIPE is handled, the process will
191 // be terminated. Because the actual termination mechanism is not known,
192 // no regex can be specified.
193 EXPECT_DEATH_CHECK(CheckedWriteFile(WritePipeHandle(), &c, 1), "");
194 }
195 }
196
197 void Close() {
198 switch (what_closes_) {
199 case kReadCloses:
200 CloseReadPipe();
201 EXPECT_NE(-1, WritePipeHandle());
202 EXPECT_DEATH_CHECK(ReadPipeHandle(), "fd");
203 break;
204 case kWriteCloses:
205 CloseWritePipe();
206 EXPECT_NE(-1, ReadPipeHandle());
207 EXPECT_DEATH_CHECK(WritePipeHandle(), "fd");
208 break;
209 case kReadAndWriteClose:
210 CloseReadPipe();
211 CloseWritePipe();
212 EXPECT_DEATH_CHECK(ReadPipeHandle(), "fd");
213 EXPECT_DEATH_CHECK(WritePipeHandle(), "fd");
214 break;
215 }
216 }
217
218 // Multiprocess:
219
220 void MultiprocessParent() override {
221 ASSERT_NO_FATAL_FAILURE(VerifyInitial());
222
223 if (who_closes_ == kParentCloses) {
224 Close();
225 } else {
226 VerifyPartner();
227 }
228 }
229
230 void MultiprocessChild() override {
231 ASSERT_NO_FATAL_FAILURE(VerifyInitial());
232
233 if (who_closes_ == kChildCloses) {
234 Close();
235 } else {
236 VerifyPartner();
237 }
238 }
239
240 WhoCloses who_closes_;
241 WhatCloses what_closes_;
242
243 DISALLOW_COPY_AND_ASSIGN(TestMultiprocessClosePipe);
244 };
245
246 TEST(MultiprocessDeathTest, ParentClosesReadPipe) {
247 TestMultiprocessClosePipe multiprocess(
248 TestMultiprocessClosePipe::kParentCloses,
249 TestMultiprocessClosePipe::kReadCloses);
250 multiprocess.Run();
251 }
252
253 TEST(MultiprocessDeathTest, ParentClosesWritePipe) {
254 TestMultiprocessClosePipe multiprocess(
255 TestMultiprocessClosePipe::kParentCloses,
256 TestMultiprocessClosePipe::kWriteCloses);
257 multiprocess.Run();
258 }
259
260 TEST(MultiprocessDeathTest, ParentClosesReadAndWritePipe) {
261 TestMultiprocessClosePipe multiprocess(
262 TestMultiprocessClosePipe::kParentCloses,
263 TestMultiprocessClosePipe::kReadAndWriteClose);
264 multiprocess.Run();
265 }
266
267 TEST(MultiprocessDeathTest, ChildClosesReadPipe) {
268 TestMultiprocessClosePipe multiprocess(
269 TestMultiprocessClosePipe::kChildCloses,
270 TestMultiprocessClosePipe::kReadCloses);
271 multiprocess.Run();
272 }
273
274 TEST(MultiprocessDeathTest, ChildClosesWritePipe) {
275 TestMultiprocessClosePipe multiprocess(
276 TestMultiprocessClosePipe::kChildCloses,
277 TestMultiprocessClosePipe::kWriteCloses);
278 multiprocess.Run();
279 }
280
281 TEST(MultiprocessDeathTest, ChildClosesReadAndWritePipe) {
282 TestMultiprocessClosePipe multiprocess(
283 TestMultiprocessClosePipe::kChildCloses,
284 TestMultiprocessClosePipe::kReadAndWriteClose);
285 multiprocess.Run();
286 }
287
288 } // namespace
289 } // namespace test
290 } // namespace crashpad
OLDNEW
« no previous file with comments | « util/test/multiprocess_posix.cc ('k') | util/test/paths.h » ('j') | util/util_test.gyp » ('J')

Powered by Google App Engine
This is Rietveld 408576698