OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 <signal.h> | 5 #include <signal.h> |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 base::MessageLoop::current()->Run(); | 28 base::MessageLoop::current()->Run(); |
29 } | 29 } |
30 | 30 |
31 // Note: We already tested success (zero) versus failure (non-zero) exit | 31 // Note: We already tested success (zero) versus failure (non-zero) exit |
32 // statuses in |ProcessControllerTest.Spawn|. | 32 // statuses in |ProcessControllerTest.Spawn|. |
33 TEST_F(ProcessControllerImplTest, Wait) { | 33 TEST_F(ProcessControllerImplTest, Wait) { |
34 mojo::files::Error error; | 34 mojo::files::Error error; |
35 | 35 |
36 { | 36 { |
37 ProcessControllerPtr process_controller; | 37 ProcessControllerPtr process_controller; |
38 error = mojo::files::ERROR_INTERNAL; | 38 error = mojo::files::Error::INTERNAL; |
39 const char kPath[] = "/bin/sh"; | 39 const char kPath[] = "/bin/sh"; |
40 mojo::Array<mojo::String> argv; | 40 mojo::Array<mojo::String> argv; |
41 argv.push_back(kPath); | 41 argv.push_back(kPath); |
42 argv.push_back("-c"); | 42 argv.push_back("-c"); |
43 argv.push_back("exit 42"); | 43 argv.push_back("exit 42"); |
44 process()->Spawn(kPath, argv.Pass(), mojo::Array<mojo::String>(), nullptr, | 44 process()->Spawn(kPath, argv.Pass(), mojo::Array<mojo::String>(), nullptr, |
45 nullptr, nullptr, GetProxy(&process_controller), | 45 nullptr, nullptr, GetProxy(&process_controller), |
46 Capture(&error)); | 46 Capture(&error)); |
47 ASSERT_TRUE(process().WaitForIncomingResponse()); | 47 ASSERT_TRUE(process().WaitForIncomingResponse()); |
48 EXPECT_EQ(mojo::files::ERROR_OK, error); | 48 EXPECT_EQ(mojo::files::Error::OK, error); |
49 | 49 |
50 error = mojo::files::ERROR_INTERNAL; | 50 error = mojo::files::Error::INTERNAL; |
51 int32_t exit_status = 0; | 51 int32_t exit_status = 0; |
52 process_controller->Wait(Capture(&error, &exit_status)); | 52 process_controller->Wait(Capture(&error, &exit_status)); |
53 ASSERT_TRUE(process_controller.WaitForIncomingResponse()); | 53 ASSERT_TRUE(process_controller.WaitForIncomingResponse()); |
54 EXPECT_EQ(mojo::files::ERROR_OK, error); | 54 EXPECT_EQ(mojo::files::Error::OK, error); |
55 EXPECT_EQ(42, exit_status); | 55 EXPECT_EQ(42, exit_status); |
56 } | 56 } |
57 } | 57 } |
58 | 58 |
59 // An output file stream that captures output and quits when "ready" is seen. | 59 // An output file stream that captures output and quits when "ready" is seen. |
60 class QuitOnReadyFile : public files_impl::OutputStreamFile::Client { | 60 class QuitOnReadyFile : public files_impl::OutputStreamFile::Client { |
61 public: | 61 public: |
62 explicit QuitOnReadyFile(mojo::InterfaceRequest<mojo::files::File> request) | 62 explicit QuitOnReadyFile(mojo::InterfaceRequest<mojo::files::File> request) |
63 : impl_(files_impl::OutputStreamFile::Create(this, request.Pass())) {} | 63 : impl_(files_impl::OutputStreamFile::Create(this, request.Pass())) {} |
64 ~QuitOnReadyFile() override {} | 64 ~QuitOnReadyFile() override {} |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 // So instead we use "read" with a timeout (note that "-t" is a bash | 120 // So instead we use "read" with a timeout (note that "-t" is a bash |
121 // extension, and not specified by POSIX for /bin/sh). Thus we have to give | 121 // extension, and not specified by POSIX for /bin/sh). Thus we have to give |
122 // something for stdin (otherwise, it'd come from /dev/null and the read would | 122 // something for stdin (otherwise, it'd come from /dev/null and the read would |
123 // be completed immediately). | 123 // be completed immediately). |
124 mojo::files::FilePtr ifile; | 124 mojo::files::FilePtr ifile; |
125 IgnoreReadsFile ifile_impl(GetProxy(&ifile)); | 125 IgnoreReadsFile ifile_impl(GetProxy(&ifile)); |
126 mojo::files::FilePtr ofile; | 126 mojo::files::FilePtr ofile; |
127 QuitOnReadyFile ofile_impl(GetProxy(&ofile)); | 127 QuitOnReadyFile ofile_impl(GetProxy(&ofile)); |
128 | 128 |
129 ProcessControllerPtr process_controller; | 129 ProcessControllerPtr process_controller; |
130 mojo::files::Error error = mojo::files::ERROR_INTERNAL; | 130 mojo::files::Error error = mojo::files::Error::INTERNAL; |
131 const char kPath[] = "/bin/bash"; | 131 const char kPath[] = "/bin/bash"; |
132 mojo::Array<mojo::String> argv; | 132 mojo::Array<mojo::String> argv; |
133 argv.push_back(kPath); | 133 argv.push_back(kPath); |
134 argv.push_back("-c"); | 134 argv.push_back("-c"); |
135 argv.push_back("trap 'exit 42' INT; echo ready; read -t30; exit 1"); | 135 argv.push_back("trap 'exit 42' INT; echo ready; read -t30; exit 1"); |
136 process()->Spawn(kPath, argv.Pass(), mojo::Array<mojo::String>(), | 136 process()->Spawn(kPath, argv.Pass(), mojo::Array<mojo::String>(), |
137 ifile.Pass(), ofile.Pass(), nullptr, | 137 ifile.Pass(), ofile.Pass(), nullptr, |
138 GetProxy(&process_controller), Capture(&error)); | 138 GetProxy(&process_controller), Capture(&error)); |
139 ASSERT_TRUE(process().WaitForIncomingResponse()); | 139 ASSERT_TRUE(process().WaitForIncomingResponse()); |
140 EXPECT_EQ(mojo::files::ERROR_OK, error); | 140 EXPECT_EQ(mojo::files::Error::OK, error); |
141 | 141 |
142 // |ofile_impl| will quit the message loop once it sees "ready". | 142 // |ofile_impl| will quit the message loop once it sees "ready". |
143 RunMessageLoop(); | 143 RunMessageLoop(); |
144 ASSERT_TRUE(ofile_impl.got_ready()); | 144 ASSERT_TRUE(ofile_impl.got_ready()); |
145 | 145 |
146 // Send SIGINT. | 146 // Send SIGINT. |
147 error = mojo::files::ERROR_INTERNAL; | 147 error = mojo::files::Error::INTERNAL; |
148 process_controller->Kill(static_cast<int32_t>(SIGINT), Capture(&error)); | 148 process_controller->Kill(static_cast<int32_t>(SIGINT), Capture(&error)); |
149 ASSERT_TRUE(process_controller.WaitForIncomingResponse()); | 149 ASSERT_TRUE(process_controller.WaitForIncomingResponse()); |
150 EXPECT_EQ(mojo::files::ERROR_OK, error); | 150 EXPECT_EQ(mojo::files::Error::OK, error); |
151 | 151 |
152 error = mojo::files::ERROR_INTERNAL; | 152 error = mojo::files::Error::INTERNAL; |
153 int32_t exit_status = 0; | 153 int32_t exit_status = 0; |
154 process_controller->Wait(Capture(&error, &exit_status)); | 154 process_controller->Wait(Capture(&error, &exit_status)); |
155 ASSERT_TRUE(process_controller.WaitForIncomingResponse()); | 155 ASSERT_TRUE(process_controller.WaitForIncomingResponse()); |
156 EXPECT_EQ(mojo::files::ERROR_OK, error); | 156 EXPECT_EQ(mojo::files::Error::OK, error); |
157 EXPECT_EQ(42, exit_status); | 157 EXPECT_EQ(42, exit_status); |
158 } | 158 } |
159 | 159 |
160 TEST_F(ProcessControllerImplTest, DestroyingControllerKills) { | 160 TEST_F(ProcessControllerImplTest, DestroyingControllerKills) { |
161 // We want to make sure that we've exec-ed before killing, so we do what we do | 161 // We want to make sure that we've exec-ed before killing, so we do what we do |
162 // in |ProcessControllerImplTest.Kill| (without the trap). | 162 // in |ProcessControllerImplTest.Kill| (without the trap). |
163 { | 163 { |
164 mojo::files::FilePtr ifile; | 164 mojo::files::FilePtr ifile; |
165 IgnoreReadsFile ifile_impl(GetProxy(&ifile)); | 165 IgnoreReadsFile ifile_impl(GetProxy(&ifile)); |
166 mojo::files::FilePtr ofile; | 166 mojo::files::FilePtr ofile; |
167 QuitOnReadyFile ofile_impl(GetProxy(&ofile)); | 167 QuitOnReadyFile ofile_impl(GetProxy(&ofile)); |
168 | 168 |
169 ProcessControllerPtr process_controller; | 169 ProcessControllerPtr process_controller; |
170 mojo::files::Error error = mojo::files::ERROR_INTERNAL; | 170 mojo::files::Error error = mojo::files::Error::INTERNAL; |
171 const char kPath[] = "/bin/bash"; | 171 const char kPath[] = "/bin/bash"; |
172 mojo::Array<mojo::String> argv; | 172 mojo::Array<mojo::String> argv; |
173 argv.push_back(kPath); | 173 argv.push_back(kPath); |
174 argv.push_back("-c"); | 174 argv.push_back("-c"); |
175 argv.push_back("echo ready; read -t30"); | 175 argv.push_back("echo ready; read -t30"); |
176 process()->Spawn(kPath, argv.Pass(), mojo::Array<mojo::String>(), | 176 process()->Spawn(kPath, argv.Pass(), mojo::Array<mojo::String>(), |
177 ifile.Pass(), ofile.Pass(), nullptr, | 177 ifile.Pass(), ofile.Pass(), nullptr, |
178 GetProxy(&process_controller), Capture(&error)); | 178 GetProxy(&process_controller), Capture(&error)); |
179 ASSERT_TRUE(process().WaitForIncomingResponse()); | 179 ASSERT_TRUE(process().WaitForIncomingResponse()); |
180 EXPECT_EQ(mojo::files::ERROR_OK, error); | 180 EXPECT_EQ(mojo::files::Error::OK, error); |
181 | 181 |
182 // |ofile_impl| will quit the message loop once it sees "ready". | 182 // |ofile_impl| will quit the message loop once it sees "ready". |
183 RunMessageLoop(); | 183 RunMessageLoop(); |
184 ASSERT_TRUE(ofile_impl.got_ready()); | 184 ASSERT_TRUE(ofile_impl.got_ready()); |
185 } | 185 } |
186 | 186 |
187 // The child should be killed. | 187 // The child should be killed. |
188 // TODO(vtl): It's pretty hard to verify that the child process was actually | 188 // TODO(vtl): It's pretty hard to verify that the child process was actually |
189 // killed. This could be done, e.g., by having the child trap SIGTERM and | 189 // killed. This could be done, e.g., by having the child trap SIGTERM and |
190 // writing something to a file, and then separately checking for that file. | 190 // writing something to a file, and then separately checking for that file. |
191 // For now now, just be happy if it doesn't crash. (I've actually verified it | 191 // For now now, just be happy if it doesn't crash. (I've actually verified it |
192 // "manually", but automation is hard.) | 192 // "manually", but automation is hard.) |
193 } | 193 } |
194 | 194 |
195 } // namespace | 195 } // namespace |
196 } // namespace native_support | 196 } // namespace native_support |
OLD | NEW |