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

Unified Diff: util/test/multiprocess_test.cc

Issue 586053002: MachMultiprocess test: the child process must wait for the parent to finish (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Handle it in the base class Created 6 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « util/test/multiprocess.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: util/test/multiprocess_test.cc
diff --git a/util/test/multiprocess_test.cc b/util/test/multiprocess_test.cc
index aab0181b1f1e40260b38585e00cee268131b4100..b1a9685645186262b3082bfd74061e96d455d795 100644
--- a/util/test/multiprocess_test.cc
+++ b/util/test/multiprocess_test.cc
@@ -34,6 +34,8 @@ class TestMultiprocess final : public Multiprocess {
~TestMultiprocess() {}
private:
+ // Multiprocess:
+
virtual void MultiprocessParent() override {
int read_fd = ReadPipeFD();
char c;
@@ -99,6 +101,8 @@ class TestMultiprocessUnclean final : public Multiprocess {
return type_;
}
+ // Multiprocess:
+
virtual void MultiprocessParent() override {
}
@@ -115,24 +119,176 @@ class TestMultiprocessUnclean final : public Multiprocess {
DISALLOW_COPY_AND_ASSIGN(TestMultiprocessUnclean);
};
-TEST(Multiprocess, MultiprocessSuccessfulExit) {
+TEST(Multiprocess, SuccessfulExit) {
TestMultiprocessUnclean multiprocess(TestMultiprocessUnclean::kExitSuccess);
multiprocess.Run();
}
-TEST(Multiprocess, MultiprocessUnsuccessfulExit) {
+TEST(Multiprocess, UnsuccessfulExit) {
TestMultiprocessUnclean multiprocess(TestMultiprocessUnclean::kExitFailure);
multiprocess.Run();
}
-TEST(Multiprocess, MultiprocessExit2) {
+TEST(Multiprocess, Exit2) {
TestMultiprocessUnclean multiprocess(TestMultiprocessUnclean::kExit2);
multiprocess.Run();
}
-TEST(Multiprocess, MultiprocessAbortSignal) {
+TEST(Multiprocess, AbortSignal) {
TestMultiprocessUnclean multiprocess(TestMultiprocessUnclean::kAbort);
multiprocess.Run();
}
+class TestMultiprocessClosePipe final : public Multiprocess {
+ public:
+ enum WhoCloses {
+ kParentCloses = 0,
+ kChildCloses,
+ };
+ enum WhatCloses {
+ kReadCloses = 0,
+ kWriteCloses,
+ kReadAndWriteClose,
+ };
+
+ TestMultiprocessClosePipe(WhoCloses who_closes, WhatCloses what_closes)
+ : Multiprocess(),
+ who_closes_(who_closes),
+ what_closes_(what_closes) {
+ }
+
+ ~TestMultiprocessClosePipe() {}
+
+ private:
+ void VerifyInitial() {
+ ASSERT_NE(-1, ReadPipeFD());
+ ASSERT_NE(-1, WritePipeFD());
+ }
+
+ // Verifies that the partner process did what it was supposed to do. This must
+ // only be called when who_closes_ names the partner process, not this
+ // process.
+ //
+ // If the partner was supposed to close its write pipe, the read pipe will be
+ // checked to ensure that it shows end-of-file.
+ //
+ // If the partner was supposed to close its read pipe, the write pipe will be
+ // checked to ensure that a checked write causes death. This can only be done
+ // if the partner also provides some type of signal when it has closed its
+ // read pipe, which is done in the form of it closing its write pipe, causing
+ // the read pipe in this process to show end-of-file.
+ void VerifyPartner() {
+ if (what_closes_ == kWriteCloses) {
+ CheckedReadFDAtEOF(ReadPipeFD());
+ } else if (what_closes_ == kReadAndWriteClose) {
+ CheckedReadFDAtEOF(ReadPipeFD());
+ char c = '\0';
+
+ // This will raise SIGPIPE. If fatal (the normal case), that will cause
+ // process termination. If SIGPIPE is being handled somewhere, the write
+ // will still fail and set errno to EPIPE, and CheckedWriteFD() will abort
+ // execution. Regardless of how SIGPIPE is handled, the process will be
+ // terminated. Because the actual termination mechanism is not known, no
+ // regex can be specified.
+ EXPECT_DEATH(CheckedWriteFD(WritePipeFD(), &c, 1), "");
+ }
+ }
+
+ void Close() {
+ switch (what_closes_) {
+ case kReadCloses:
+ CloseReadPipe();
+ EXPECT_NE(-1, WritePipeFD());
+ EXPECT_DEATH(ReadPipeFD(), "fd");
+ break;
+ case kWriteCloses:
+ CloseWritePipe();
+ EXPECT_NE(-1, ReadPipeFD());
+ EXPECT_DEATH(WritePipeFD(), "fd");
+ break;
+ case kReadAndWriteClose:
+ CloseReadPipe();
+ CloseWritePipe();
+ EXPECT_DEATH(ReadPipeFD(), "fd");
+ EXPECT_DEATH(WritePipeFD(), "fd");
+ break;
+ }
+ }
+
+ // Multiprocess:
+
+ virtual void MultiprocessParent() override {
+ VerifyInitial();
+ if (testing::Test::HasFatalFailure()) {
+ return;
+ }
+
+ if (who_closes_ == kParentCloses) {
+ Close();
+ } else {
+ VerifyPartner();
+ }
+ }
+
+ virtual void MultiprocessChild() override {
+ VerifyInitial();
+ if (testing::Test::HasFatalFailure()) {
+ return;
+ }
+
+ if (who_closes_ == kChildCloses) {
+ Close();
+ } else {
+ VerifyPartner();
+ }
+ }
+
+ WhoCloses who_closes_;
+ WhatCloses what_closes_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestMultiprocessClosePipe);
+};
+
+TEST(MultiprocessDeathTest, ParentClosesReadPipe) {
+ TestMultiprocessClosePipe multiprocess(
+ TestMultiprocessClosePipe::kParentCloses,
+ TestMultiprocessClosePipe::kReadCloses);
+ multiprocess.Run();
+}
+
+TEST(MultiprocessDeathTest, ParentClosesWritePipe) {
+ TestMultiprocessClosePipe multiprocess(
+ TestMultiprocessClosePipe::kParentCloses,
+ TestMultiprocessClosePipe::kWriteCloses);
+ multiprocess.Run();
+}
+
+TEST(MultiprocessDeathTest, ParentClosesReadAndWritePipe) {
+ TestMultiprocessClosePipe multiprocess(
+ TestMultiprocessClosePipe::kParentCloses,
+ TestMultiprocessClosePipe::kReadAndWriteClose);
+ multiprocess.Run();
+}
+
+TEST(MultiprocessDeathTest, ChildClosesReadPipe) {
+ TestMultiprocessClosePipe multiprocess(
+ TestMultiprocessClosePipe::kChildCloses,
+ TestMultiprocessClosePipe::kReadCloses);
+ multiprocess.Run();
+}
+
+TEST(MultiprocessDeathTest, ChildClosesWritePipe) {
+ TestMultiprocessClosePipe multiprocess(
+ TestMultiprocessClosePipe::kChildCloses,
+ TestMultiprocessClosePipe::kWriteCloses);
+ multiprocess.Run();
+}
+
+TEST(MultiprocessDeathTest, ChildClosesReadAndWritePipe) {
+ TestMultiprocessClosePipe multiprocess(
+ TestMultiprocessClosePipe::kChildCloses,
+ TestMultiprocessClosePipe::kReadAndWriteClose);
+ multiprocess.Run();
+}
+
} // namespace
« no previous file with comments | « util/test/multiprocess.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698