multiprocess_message_pipe_unittest.cc 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <stddef.h>
  5. #include <stdint.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <string>
  9. #include <unordered_map>
  10. #include <utility>
  11. #include <vector>
  12. #include "base/bind.h"
  13. #include "base/files/file_path.h"
  14. #include "base/files/file_util.h"
  15. #include "base/files/scoped_file.h"
  16. #include "base/files/scoped_temp_dir.h"
  17. #include "base/logging.h"
  18. #include "base/run_loop.h"
  19. #include "base/strings/string_split.h"
  20. #include "base/test/task_environment.h"
  21. #include "build/build_config.h"
  22. #include "mojo/core/handle_signals_state.h"
  23. #include "mojo/core/test/mojo_test_base.h"
  24. #include "mojo/core/test/test_utils.h"
  25. #include "mojo/public/c/system/buffer.h"
  26. #include "mojo/public/c/system/functions.h"
  27. #include "mojo/public/c/system/types.h"
  28. #include "mojo/public/cpp/system/message_pipe.h"
  29. #include "mojo/public/cpp/system/platform_handle.h"
  30. #include "mojo/public/cpp/system/simple_watcher.h"
  31. #include "mojo/public/cpp/system/wait.h"
  32. #include "testing/gtest/include/gtest/gtest.h"
  33. namespace mojo {
  34. namespace core {
  35. namespace {
  36. // Temporary helpers to avoid tons of churn as old APIs are removed. These
  37. // support only enough of a subset of the old APIs to satisfy the usage in these
  38. // tests.
  39. //
  40. // TODO(rockot): Remove these.
  41. MojoResult MojoReadMessage(MojoHandle pipe,
  42. void* out_bytes,
  43. uint32_t* num_bytes,
  44. MojoHandle* out_handles,
  45. uint32_t* num_handles,
  46. MojoReadMessageFlags flags) {
  47. std::vector<uint8_t> bytes;
  48. std::vector<ScopedHandle> handles;
  49. MojoResult rv =
  50. ReadMessageRaw(MessagePipeHandle(pipe), &bytes, &handles, flags);
  51. if (rv != MOJO_RESULT_OK)
  52. return rv;
  53. if (num_bytes)
  54. *num_bytes = static_cast<uint32_t>(bytes.size());
  55. if (!bytes.empty()) {
  56. CHECK(out_bytes && num_bytes && *num_bytes >= bytes.size());
  57. memcpy(out_bytes, bytes.data(), bytes.size());
  58. }
  59. if (num_handles)
  60. *num_handles = static_cast<uint32_t>(handles.size());
  61. if (!handles.empty()) {
  62. CHECK(out_handles && num_handles && *num_handles >= handles.size());
  63. for (size_t i = 0; i < handles.size(); ++i)
  64. out_handles[i] = handles[i].release().value();
  65. }
  66. return MOJO_RESULT_OK;
  67. }
  68. MojoResult MojoWriteMessage(MojoHandle pipe,
  69. const void* bytes,
  70. uint32_t num_bytes,
  71. const MojoHandle* handles,
  72. uint32_t num_handles,
  73. MojoWriteMessageFlags flags) {
  74. return WriteMessageRaw(MessagePipeHandle(pipe), bytes, num_bytes, handles,
  75. num_handles, flags);
  76. }
  77. class MultiprocessMessagePipeTest : public test::MojoTestBase {
  78. protected:
  79. // Convenience class for tests which will control command-driven children.
  80. // See the CommandDrivenClient definition below.
  81. class CommandDrivenClientController {
  82. public:
  83. explicit CommandDrivenClientController(MojoHandle h) : h_(h) {}
  84. void Send(const std::string& command) {
  85. WriteMessage(h_, command);
  86. EXPECT_EQ("ok", ReadMessage(h_));
  87. }
  88. void SendHandle(const std::string& name, MojoHandle p) {
  89. WriteMessageWithHandles(h_, "take:" + name, &p, 1);
  90. EXPECT_EQ("ok", ReadMessage(h_));
  91. }
  92. MojoHandle RetrieveHandle(const std::string& name) {
  93. WriteMessage(h_, "return:" + name);
  94. MojoHandle p;
  95. EXPECT_EQ("ok", ReadMessageWithHandles(h_, &p, 1));
  96. return p;
  97. }
  98. void Exit() { WriteMessage(h_, "exit"); }
  99. private:
  100. MojoHandle h_;
  101. };
  102. };
  103. class MultiprocessMessagePipeTestWithPeerSupport
  104. : public MultiprocessMessagePipeTest,
  105. public testing::WithParamInterface<test::MojoTestBase::LaunchType> {
  106. protected:
  107. void SetUp() override {
  108. test::MojoTestBase::SetUp();
  109. set_launch_type(GetParam());
  110. }
  111. };
  112. // For each message received, sends a reply message with the same contents
  113. // repeated twice, until the other end is closed or it receives "quitquitquit"
  114. // (which it doesn't reply to). It'll return the number of messages received,
  115. // not including any "quitquitquit" message, modulo 100.
  116. DEFINE_TEST_CLIENT_WITH_PIPE(EchoEcho, MultiprocessMessagePipeTest, h) {
  117. const std::string quitquitquit("quitquitquit");
  118. int rv = 0;
  119. for (;; rv = (rv + 1) % 100) {
  120. // Wait for our end of the message pipe to be readable.
  121. HandleSignalsState hss;
  122. MojoResult result = WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss);
  123. if (result != MOJO_RESULT_OK) {
  124. // It was closed, probably.
  125. CHECK_EQ(result, MOJO_RESULT_FAILED_PRECONDITION);
  126. CHECK_EQ(hss.satisfied_signals, MOJO_HANDLE_SIGNAL_PEER_CLOSED);
  127. CHECK_EQ(hss.satisfiable_signals, MOJO_HANDLE_SIGNAL_PEER_CLOSED);
  128. break;
  129. } else {
  130. CHECK((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
  131. CHECK((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
  132. }
  133. std::string read_buffer(1000, '\0');
  134. uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
  135. CHECK_EQ(MojoReadMessage(h, &read_buffer[0], &read_buffer_size, nullptr, 0,
  136. MOJO_READ_MESSAGE_FLAG_NONE),
  137. MOJO_RESULT_OK);
  138. read_buffer.resize(read_buffer_size);
  139. VLOG(2) << "Child got: " << read_buffer;
  140. if (read_buffer == quitquitquit) {
  141. VLOG(2) << "Child quitting.";
  142. break;
  143. }
  144. std::string write_buffer = read_buffer + read_buffer;
  145. CHECK_EQ(MojoWriteMessage(h, write_buffer.data(),
  146. static_cast<uint32_t>(write_buffer.size()),
  147. nullptr, 0u, MOJO_WRITE_MESSAGE_FLAG_NONE),
  148. MOJO_RESULT_OK);
  149. }
  150. return rv;
  151. }
  152. TEST_P(MultiprocessMessagePipeTestWithPeerSupport, Basic) {
  153. int exit_code = RunTestClientAndGetExitCode("EchoEcho", [&](MojoHandle h) {
  154. std::string hello("hello");
  155. ASSERT_EQ(
  156. MOJO_RESULT_OK,
  157. MojoWriteMessage(h, hello.data(), static_cast<uint32_t>(hello.size()),
  158. nullptr, 0u, MOJO_WRITE_MESSAGE_FLAG_NONE));
  159. HandleSignalsState hss;
  160. ASSERT_EQ(MOJO_RESULT_OK,
  161. WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss));
  162. // The child may or may not have closed its end of the message pipe and died
  163. // (and we may or may not know it yet), so our end may or may not appear as
  164. // writable.
  165. EXPECT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
  166. EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
  167. std::string read_buffer(1000, '\0');
  168. uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
  169. CHECK_EQ(MojoReadMessage(h, &read_buffer[0], &read_buffer_size, nullptr, 0,
  170. MOJO_READ_MESSAGE_FLAG_NONE),
  171. MOJO_RESULT_OK);
  172. read_buffer.resize(read_buffer_size);
  173. VLOG(2) << "Parent got: " << read_buffer;
  174. ASSERT_EQ(hello + hello, read_buffer);
  175. std::string quitquitquit("quitquitquit");
  176. CHECK_EQ(MojoWriteMessage(h, quitquitquit.data(),
  177. static_cast<uint32_t>(quitquitquit.size()),
  178. nullptr, 0u, MOJO_WRITE_MESSAGE_FLAG_NONE),
  179. MOJO_RESULT_OK);
  180. });
  181. EXPECT_EQ(1, exit_code);
  182. }
  183. TEST_P(MultiprocessMessagePipeTestWithPeerSupport, QueueMessages) {
  184. static const size_t kNumMessages = 1001;
  185. int exit_code = RunTestClientAndGetExitCode("EchoEcho", [&](MojoHandle h) {
  186. for (size_t i = 0; i < kNumMessages; i++) {
  187. std::string write_buffer(i, 'A' + (i % 26));
  188. ASSERT_EQ(MOJO_RESULT_OK,
  189. MojoWriteMessage(h, write_buffer.data(),
  190. static_cast<uint32_t>(write_buffer.size()),
  191. nullptr, 0u, MOJO_WRITE_MESSAGE_FLAG_NONE));
  192. }
  193. for (size_t i = 0; i < kNumMessages; i++) {
  194. HandleSignalsState hss;
  195. ASSERT_EQ(MOJO_RESULT_OK,
  196. WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss));
  197. // The child may or may not have closed its end of the message pipe and
  198. // died (and we may or may not know it yet), so our end may or may not
  199. // appear as writable.
  200. ASSERT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
  201. ASSERT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
  202. std::string read_buffer(kNumMessages * 2, '\0');
  203. uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
  204. ASSERT_EQ(MojoReadMessage(h, &read_buffer[0], &read_buffer_size, nullptr,
  205. 0, MOJO_READ_MESSAGE_FLAG_NONE),
  206. MOJO_RESULT_OK);
  207. read_buffer.resize(read_buffer_size);
  208. ASSERT_EQ(std::string(i * 2, 'A' + (i % 26)), read_buffer);
  209. }
  210. const std::string quitquitquit("quitquitquit");
  211. ASSERT_EQ(MOJO_RESULT_OK,
  212. MojoWriteMessage(h, quitquitquit.data(),
  213. static_cast<uint32_t>(quitquitquit.size()),
  214. nullptr, 0u, MOJO_WRITE_MESSAGE_FLAG_NONE));
  215. // Wait for it to become readable, which should fail (since we sent
  216. // "quitquitquit").
  217. HandleSignalsState hss;
  218. ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
  219. WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss));
  220. ASSERT_FALSE(hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
  221. ASSERT_FALSE(hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE);
  222. });
  223. EXPECT_EQ(static_cast<int>(kNumMessages % 100), exit_code);
  224. }
  225. DEFINE_TEST_CLIENT_WITH_PIPE(CheckSharedBuffer,
  226. MultiprocessMessagePipeTest,
  227. h) {
  228. // Wait for the first message from our parent.
  229. HandleSignalsState hss;
  230. CHECK_EQ(WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss),
  231. MOJO_RESULT_OK);
  232. // In this test, the parent definitely doesn't close its end of the message
  233. // pipe before we do.
  234. CHECK(hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
  235. CHECK(hss.satisfied_signals & MOJO_HANDLE_SIGNAL_WRITABLE);
  236. // It should have a shared buffer.
  237. std::string read_buffer(100, '\0');
  238. uint32_t num_bytes = static_cast<uint32_t>(read_buffer.size());
  239. MojoHandle handles[10];
  240. uint32_t num_handlers = std::size(handles); // Maximum number to receive
  241. CHECK_EQ(MojoReadMessage(h, &read_buffer[0], &num_bytes, &handles[0],
  242. &num_handlers, MOJO_READ_MESSAGE_FLAG_NONE),
  243. MOJO_RESULT_OK);
  244. read_buffer.resize(num_bytes);
  245. CHECK_EQ(read_buffer, std::string("go 1"));
  246. CHECK_EQ(num_handlers, 1u);
  247. // Make a mapping.
  248. void* buffer;
  249. CHECK_EQ(MojoMapBuffer(handles[0], 0, 100, nullptr, &buffer), MOJO_RESULT_OK);
  250. // Write some stuff to the shared buffer.
  251. static const char kHello[] = "hello";
  252. memcpy(buffer, kHello, sizeof(kHello));
  253. // We should be able to close the dispatcher now.
  254. MojoClose(handles[0]);
  255. // And send a message to signal that we've written stuff.
  256. const std::string go2("go 2");
  257. CHECK_EQ(MojoWriteMessage(h, go2.data(), static_cast<uint32_t>(go2.size()),
  258. nullptr, 0u, MOJO_WRITE_MESSAGE_FLAG_NONE),
  259. MOJO_RESULT_OK);
  260. // Now wait for our parent to send us a message.
  261. hss = HandleSignalsState();
  262. CHECK_EQ(WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss),
  263. MOJO_RESULT_OK);
  264. CHECK(hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
  265. CHECK(hss.satisfied_signals & MOJO_HANDLE_SIGNAL_WRITABLE);
  266. read_buffer = std::string(100, '\0');
  267. num_bytes = static_cast<uint32_t>(read_buffer.size());
  268. CHECK_EQ(MojoReadMessage(h, &read_buffer[0], &num_bytes, nullptr, 0,
  269. MOJO_READ_MESSAGE_FLAG_NONE),
  270. MOJO_RESULT_OK);
  271. read_buffer.resize(num_bytes);
  272. CHECK_EQ(read_buffer, std::string("go 3"));
  273. // It should have written something to the shared buffer.
  274. static const char kWorld[] = "world!!!";
  275. CHECK_EQ(memcmp(buffer, kWorld, sizeof(kWorld)), 0);
  276. // And we're done.
  277. return 0;
  278. }
  279. TEST_F(MultiprocessMessagePipeTest, SharedBufferPassing) {
  280. RunTestClient("CheckSharedBuffer", [&](MojoHandle h) {
  281. // Make a shared buffer.
  282. MojoCreateSharedBufferOptions options;
  283. options.struct_size = sizeof(options);
  284. options.flags = MOJO_CREATE_SHARED_BUFFER_FLAG_NONE;
  285. MojoHandle shared_buffer;
  286. ASSERT_EQ(MOJO_RESULT_OK,
  287. MojoCreateSharedBuffer(100, &options, &shared_buffer));
  288. MojoSharedBufferInfo buffer_info;
  289. buffer_info.struct_size = sizeof(buffer_info);
  290. ASSERT_EQ(MOJO_RESULT_OK,
  291. MojoGetBufferInfo(shared_buffer, nullptr, &buffer_info));
  292. EXPECT_GE(buffer_info.size, 100U);
  293. // Send the shared buffer.
  294. const std::string go1("go 1");
  295. MojoHandle duplicated_shared_buffer;
  296. ASSERT_EQ(MOJO_RESULT_OK,
  297. MojoDuplicateBufferHandle(shared_buffer, nullptr,
  298. &duplicated_shared_buffer));
  299. buffer_info.size = 0;
  300. ASSERT_EQ(MOJO_RESULT_OK,
  301. MojoGetBufferInfo(shared_buffer, nullptr, &buffer_info));
  302. EXPECT_GE(buffer_info.size, 100U);
  303. MojoHandle handles[1];
  304. handles[0] = duplicated_shared_buffer;
  305. ASSERT_EQ(MOJO_RESULT_OK,
  306. MojoWriteMessage(h, &go1[0], static_cast<uint32_t>(go1.size()),
  307. &handles[0], std::size(handles),
  308. MOJO_WRITE_MESSAGE_FLAG_NONE));
  309. // Wait for a message from the child.
  310. HandleSignalsState hss;
  311. ASSERT_EQ(MOJO_RESULT_OK,
  312. WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss));
  313. EXPECT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
  314. EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
  315. std::string read_buffer(100, '\0');
  316. uint32_t num_bytes = static_cast<uint32_t>(read_buffer.size());
  317. ASSERT_EQ(MOJO_RESULT_OK,
  318. MojoReadMessage(h, &read_buffer[0], &num_bytes, nullptr, 0,
  319. MOJO_READ_MESSAGE_FLAG_NONE));
  320. read_buffer.resize(num_bytes);
  321. ASSERT_EQ(std::string("go 2"), read_buffer);
  322. // After we get it, the child should have written something to the shared
  323. // buffer.
  324. static const char kHello[] = "hello";
  325. void* buffer;
  326. CHECK_EQ(MojoMapBuffer(shared_buffer, 0, 100, nullptr, &buffer),
  327. MOJO_RESULT_OK);
  328. ASSERT_EQ(0, memcmp(buffer, kHello, sizeof(kHello)));
  329. // Now we'll write some stuff to the shared buffer.
  330. static const char kWorld[] = "world!!!";
  331. memcpy(buffer, kWorld, sizeof(kWorld));
  332. // And send a message to signal that we've written stuff.
  333. const std::string go3("go 3");
  334. ASSERT_EQ(MOJO_RESULT_OK,
  335. MojoWriteMessage(h, &go3[0], static_cast<uint32_t>(go3.size()),
  336. nullptr, 0u, MOJO_WRITE_MESSAGE_FLAG_NONE));
  337. // Wait for |h| to become readable, which should fail.
  338. hss = HandleSignalsState();
  339. ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
  340. WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss));
  341. ASSERT_FALSE(hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
  342. ASSERT_FALSE(hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE);
  343. });
  344. }
  345. DEFINE_TEST_CLIENT_WITH_PIPE(CheckPlatformHandleFile,
  346. MultiprocessMessagePipeTest,
  347. h) {
  348. HandleSignalsState hss;
  349. CHECK_EQ(WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss),
  350. MOJO_RESULT_OK);
  351. CHECK(hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
  352. CHECK(hss.satisfied_signals & MOJO_HANDLE_SIGNAL_WRITABLE);
  353. std::string read_buffer(100, '\0');
  354. uint32_t num_bytes = static_cast<uint32_t>(read_buffer.size());
  355. MojoHandle handles[255]; // Maximum number to receive.
  356. uint32_t num_handlers = std::size(handles);
  357. CHECK_EQ(MojoReadMessage(h, &read_buffer[0], &num_bytes, &handles[0],
  358. &num_handlers, MOJO_READ_MESSAGE_FLAG_NONE),
  359. MOJO_RESULT_OK);
  360. read_buffer.resize(num_bytes);
  361. char hello[32];
  362. int num_handles = 0;
  363. sscanf(read_buffer.c_str(), "%s %d", hello, &num_handles);
  364. CHECK_EQ(std::string("hello"), std::string(hello));
  365. CHECK_GT(num_handles, 0);
  366. for (int i = 0; i < num_handles; ++i) {
  367. PlatformHandle handle =
  368. UnwrapPlatformHandle(ScopedHandle(Handle(handles[i])));
  369. CHECK(handle.is_valid());
  370. base::ScopedFILE fp = test::FILEFromPlatformHandle(std::move(handle), "r");
  371. CHECK(fp);
  372. std::string fread_buffer(100, '\0');
  373. size_t bytes_read =
  374. fread(&fread_buffer[0], 1, fread_buffer.size(), fp.get());
  375. fread_buffer.resize(bytes_read);
  376. CHECK_EQ(fread_buffer, "world");
  377. }
  378. return 0;
  379. }
  380. #if !BUILDFLAG(IS_ANDROID)
  381. class MultiprocessMessagePipeTestWithPipeCount
  382. : public MultiprocessMessagePipeTest,
  383. public testing::WithParamInterface<size_t> {};
  384. TEST_P(MultiprocessMessagePipeTestWithPipeCount, PlatformHandlePassing) {
  385. base::ScopedTempDir temp_dir;
  386. ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  387. RunTestClient("CheckPlatformHandleFile", [&](MojoHandle h) {
  388. std::vector<MojoHandle> handles;
  389. size_t pipe_count = GetParam();
  390. for (size_t i = 0; i < pipe_count; ++i) {
  391. base::FilePath unused;
  392. base::ScopedFILE fp =
  393. CreateAndOpenTemporaryStreamInDir(temp_dir.GetPath(), &unused);
  394. const std::string world("world");
  395. CHECK_EQ(fwrite(&world[0], 1, world.size(), fp.get()), world.size());
  396. fflush(fp.get());
  397. rewind(fp.get());
  398. ScopedHandle handle =
  399. WrapPlatformHandle(test::PlatformHandleFromFILE(std::move(fp)));
  400. ASSERT_TRUE(handle.is_valid());
  401. handles.push_back(handle.release().value());
  402. }
  403. char message[128];
  404. snprintf(message, sizeof(message), "hello %d",
  405. static_cast<int>(pipe_count));
  406. ASSERT_EQ(
  407. MOJO_RESULT_OK,
  408. MojoWriteMessage(h, message, static_cast<uint32_t>(strlen(message)),
  409. &handles[0], static_cast<uint32_t>(handles.size()),
  410. MOJO_WRITE_MESSAGE_FLAG_NONE));
  411. // Wait for it to become readable, which should fail.
  412. HandleSignalsState hss;
  413. ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
  414. WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss));
  415. ASSERT_FALSE(hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
  416. ASSERT_FALSE(hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE);
  417. });
  418. }
  419. // Android multi-process tests are not executing the new process. This is flaky.
  420. INSTANTIATE_TEST_SUITE_P(PipeCount,
  421. MultiprocessMessagePipeTestWithPipeCount,
  422. // TODO(rockot): Enable the 128 and 250 pipe cases when
  423. // ChannelPosix and ChannelFuchsia have support for
  424. // sending larger numbers of handles per-message. See
  425. // kMaxAttachedHandles in channel.cc for details.
  426. testing::Values(1u, 64u /*, 128u, 250u*/));
  427. #endif
  428. DEFINE_TEST_CLIENT_WITH_PIPE(CheckMessagePipe, MultiprocessMessagePipeTest, h) {
  429. // Wait for the first message from our parent.
  430. HandleSignalsState hss;
  431. CHECK_EQ(WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss),
  432. MOJO_RESULT_OK);
  433. // In this test, the parent definitely doesn't close its end of the message
  434. // pipe before we do.
  435. CHECK(hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
  436. CHECK(hss.satisfied_signals & MOJO_HANDLE_SIGNAL_WRITABLE);
  437. // It should have a message pipe.
  438. MojoHandle handles[10];
  439. uint32_t num_handlers = std::size(handles);
  440. CHECK_EQ(MojoReadMessage(h, nullptr, nullptr, &handles[0], &num_handlers,
  441. MOJO_READ_MESSAGE_FLAG_NONE),
  442. MOJO_RESULT_OK);
  443. CHECK_EQ(num_handlers, 1u);
  444. // Read data from the received message pipe.
  445. CHECK_EQ(WaitForSignals(handles[0], MOJO_HANDLE_SIGNAL_READABLE, &hss),
  446. MOJO_RESULT_OK);
  447. CHECK(hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
  448. CHECK(hss.satisfied_signals & MOJO_HANDLE_SIGNAL_WRITABLE);
  449. std::string read_buffer(100, '\0');
  450. uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
  451. CHECK_EQ(MojoReadMessage(handles[0], &read_buffer[0], &read_buffer_size,
  452. nullptr, 0, MOJO_READ_MESSAGE_FLAG_NONE),
  453. MOJO_RESULT_OK);
  454. read_buffer.resize(read_buffer_size);
  455. CHECK_EQ(read_buffer, std::string("hello"));
  456. // Now write some data into the message pipe.
  457. std::string write_buffer = "world";
  458. CHECK_EQ(MojoWriteMessage(handles[0], write_buffer.data(),
  459. static_cast<uint32_t>(write_buffer.size()), nullptr,
  460. 0u, MOJO_WRITE_MESSAGE_FLAG_NONE),
  461. MOJO_RESULT_OK);
  462. MojoClose(handles[0]);
  463. return 0;
  464. }
  465. TEST_P(MultiprocessMessagePipeTestWithPeerSupport, MessagePipePassing) {
  466. RunTestClient("CheckMessagePipe", [&](MojoHandle h) {
  467. MojoCreateSharedBufferOptions options;
  468. options.struct_size = sizeof(options);
  469. options.flags = MOJO_CREATE_SHARED_BUFFER_FLAG_NONE;
  470. MojoHandle mp1, mp2;
  471. ASSERT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &mp1, &mp2));
  472. // Write a string into one end of the new message pipe and send the other
  473. // end.
  474. const std::string hello("hello");
  475. ASSERT_EQ(
  476. MOJO_RESULT_OK,
  477. MojoWriteMessage(mp1, &hello[0], static_cast<uint32_t>(hello.size()),
  478. nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
  479. ASSERT_EQ(MOJO_RESULT_OK, MojoWriteMessage(h, nullptr, 0, &mp2, 1,
  480. MOJO_WRITE_MESSAGE_FLAG_NONE));
  481. // Wait for a message from the child.
  482. HandleSignalsState hss;
  483. ASSERT_EQ(MOJO_RESULT_OK,
  484. WaitForSignals(mp1, MOJO_HANDLE_SIGNAL_READABLE, &hss));
  485. EXPECT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
  486. EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
  487. std::string read_buffer(100, '\0');
  488. uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
  489. CHECK_EQ(MojoReadMessage(mp1, &read_buffer[0], &read_buffer_size, nullptr,
  490. 0, MOJO_READ_MESSAGE_FLAG_NONE),
  491. MOJO_RESULT_OK);
  492. read_buffer.resize(read_buffer_size);
  493. CHECK_EQ(read_buffer, std::string("world"));
  494. MojoClose(mp1);
  495. });
  496. }
  497. TEST_P(MultiprocessMessagePipeTestWithPeerSupport, MessagePipeTwoPassing) {
  498. RunTestClient("CheckMessagePipe", [&](MojoHandle h) {
  499. MojoHandle mp1, mp2;
  500. ASSERT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &mp2, &mp1));
  501. // Write a string into one end of the new message pipe and send the other
  502. // end.
  503. const std::string hello("hello");
  504. ASSERT_EQ(
  505. MOJO_RESULT_OK,
  506. MojoWriteMessage(mp1, &hello[0], static_cast<uint32_t>(hello.size()),
  507. nullptr, 0u, MOJO_WRITE_MESSAGE_FLAG_NONE));
  508. ASSERT_EQ(MOJO_RESULT_OK, MojoWriteMessage(h, nullptr, 0u, &mp2, 1u,
  509. MOJO_WRITE_MESSAGE_FLAG_NONE));
  510. // Wait for a message from the child.
  511. HandleSignalsState hss;
  512. ASSERT_EQ(MOJO_RESULT_OK,
  513. WaitForSignals(mp1, MOJO_HANDLE_SIGNAL_READABLE, &hss));
  514. EXPECT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
  515. EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
  516. std::string read_buffer(100, '\0');
  517. uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
  518. CHECK_EQ(MojoReadMessage(mp1, &read_buffer[0], &read_buffer_size, nullptr,
  519. 0, MOJO_READ_MESSAGE_FLAG_NONE),
  520. MOJO_RESULT_OK);
  521. read_buffer.resize(read_buffer_size);
  522. CHECK_EQ(read_buffer, std::string("world"));
  523. });
  524. }
  525. DEFINE_TEST_CLIENT_WITH_PIPE(DataPipeConsumer, MultiprocessMessagePipeTest, h) {
  526. // Wait for the first message from our parent.
  527. HandleSignalsState hss;
  528. CHECK_EQ(WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE, &hss),
  529. MOJO_RESULT_OK);
  530. // In this test, the parent definitely doesn't close its end of the message
  531. // pipe before we do.
  532. CHECK(hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
  533. CHECK(hss.satisfied_signals & MOJO_HANDLE_SIGNAL_WRITABLE);
  534. CHECK_EQ(hss.satisfiable_signals,
  535. MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE |
  536. MOJO_HANDLE_SIGNAL_PEER_CLOSED | MOJO_HANDLE_SIGNAL_PEER_REMOTE |
  537. MOJO_HANDLE_SIGNAL_QUOTA_EXCEEDED);
  538. // It should have a message pipe.
  539. MojoHandle handles[10];
  540. uint32_t num_handlers = std::size(handles);
  541. CHECK_EQ(MojoReadMessage(h, nullptr, nullptr, &handles[0], &num_handlers,
  542. MOJO_READ_MESSAGE_FLAG_NONE),
  543. MOJO_RESULT_OK);
  544. CHECK_EQ(num_handlers, 1u);
  545. // Read data from the received message pipe.
  546. CHECK_EQ(WaitForSignals(handles[0], MOJO_HANDLE_SIGNAL_READABLE, &hss),
  547. MOJO_RESULT_OK);
  548. CHECK(hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
  549. CHECK(hss.satisfied_signals & MOJO_HANDLE_SIGNAL_WRITABLE);
  550. CHECK_EQ(hss.satisfiable_signals,
  551. MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE |
  552. MOJO_HANDLE_SIGNAL_PEER_CLOSED | MOJO_HANDLE_SIGNAL_PEER_REMOTE |
  553. MOJO_HANDLE_SIGNAL_QUOTA_EXCEEDED);
  554. std::string read_buffer(100, '\0');
  555. uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
  556. CHECK_EQ(MojoReadMessage(handles[0], &read_buffer[0], &read_buffer_size,
  557. nullptr, 0, MOJO_READ_MESSAGE_FLAG_NONE),
  558. MOJO_RESULT_OK);
  559. read_buffer.resize(read_buffer_size);
  560. CHECK_EQ(read_buffer, std::string("hello"));
  561. // Now write some data into the message pipe.
  562. std::string write_buffer = "world";
  563. CHECK_EQ(MojoWriteMessage(handles[0], write_buffer.data(),
  564. static_cast<uint32_t>(write_buffer.size()), nullptr,
  565. 0u, MOJO_WRITE_MESSAGE_FLAG_NONE),
  566. MOJO_RESULT_OK);
  567. MojoClose(handles[0]);
  568. return 0;
  569. }
  570. TEST_F(MultiprocessMessagePipeTest, DataPipeConsumer) {
  571. RunTestClient("DataPipeConsumer", [&](MojoHandle h) {
  572. MojoCreateSharedBufferOptions options;
  573. options.struct_size = sizeof(options);
  574. options.flags = MOJO_CREATE_SHARED_BUFFER_FLAG_NONE;
  575. MojoHandle mp1, mp2;
  576. ASSERT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &mp2, &mp1));
  577. // Write a string into one end of the new message pipe and send the other
  578. // end.
  579. const std::string hello("hello");
  580. ASSERT_EQ(
  581. MOJO_RESULT_OK,
  582. MojoWriteMessage(mp1, &hello[0], static_cast<uint32_t>(hello.size()),
  583. nullptr, 0u, MOJO_WRITE_MESSAGE_FLAG_NONE));
  584. ASSERT_EQ(MOJO_RESULT_OK, MojoWriteMessage(h, nullptr, 0, &mp2, 1u,
  585. MOJO_WRITE_MESSAGE_FLAG_NONE));
  586. // Wait for a message from the child.
  587. HandleSignalsState hss;
  588. ASSERT_EQ(MOJO_RESULT_OK,
  589. WaitForSignals(mp1, MOJO_HANDLE_SIGNAL_READABLE, &hss));
  590. EXPECT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
  591. EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
  592. std::string read_buffer(100, '\0');
  593. uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
  594. CHECK_EQ(MojoReadMessage(mp1, &read_buffer[0], &read_buffer_size, nullptr,
  595. 0, MOJO_READ_MESSAGE_FLAG_NONE),
  596. MOJO_RESULT_OK);
  597. read_buffer.resize(read_buffer_size);
  598. CHECK_EQ(read_buffer, std::string("world"));
  599. MojoClose(mp1);
  600. });
  601. }
  602. TEST_P(MultiprocessMessagePipeTestWithPeerSupport, CreateMessagePipe) {
  603. MojoHandle p0, p1;
  604. CreateMessagePipe(&p0, &p1);
  605. VerifyTransmission(p0, p1, std::string(10 * 1024 * 1024, 'a'));
  606. VerifyTransmission(p1, p0, std::string(10 * 1024 * 1024, 'e'));
  607. CloseHandle(p0);
  608. CloseHandle(p1);
  609. }
  610. TEST_P(MultiprocessMessagePipeTestWithPeerSupport, PassMessagePipeLocal) {
  611. MojoHandle p0, p1;
  612. CreateMessagePipe(&p0, &p1);
  613. VerifyTransmission(p0, p1, "testing testing");
  614. VerifyTransmission(p1, p0, "one two three");
  615. MojoHandle p2, p3;
  616. CreateMessagePipe(&p2, &p3);
  617. VerifyTransmission(p2, p3, "testing testing");
  618. VerifyTransmission(p3, p2, "one two three");
  619. // Pass p2 over p0 to p1.
  620. const std::string message = "ceci n'est pas une pipe";
  621. WriteMessageWithHandles(p0, message, &p2, 1);
  622. EXPECT_EQ(message, ReadMessageWithHandles(p1, &p2, 1));
  623. CloseHandle(p0);
  624. CloseHandle(p1);
  625. // Verify that the received handle (now in p2) still works.
  626. VerifyTransmission(p2, p3, "Easy come, easy go; will you let me go?");
  627. VerifyTransmission(p3, p2, "Bismillah! NO! We will not let you go!");
  628. CloseHandle(p2);
  629. CloseHandle(p3);
  630. }
  631. // Echos the primordial channel until "exit".
  632. DEFINE_TEST_CLIENT_WITH_PIPE(ChannelEchoClient,
  633. MultiprocessMessagePipeTest,
  634. h) {
  635. for (;;) {
  636. std::string message = ReadMessage(h);
  637. if (message == "exit")
  638. break;
  639. WriteMessage(h, message);
  640. }
  641. return 0;
  642. }
  643. TEST_P(MultiprocessMessagePipeTestWithPeerSupport, MultiprocessChannelPipe) {
  644. RunTestClient("ChannelEchoClient", [&](MojoHandle h) {
  645. VerifyEcho(h, "in an interstellar burst");
  646. VerifyEcho(h, "i am back to save the universe");
  647. VerifyEcho(h, std::string(10 * 1024 * 1024, 'o'));
  648. WriteMessage(h, "exit");
  649. });
  650. }
  651. // Receives a pipe handle from the primordial channel and echos on it until
  652. // "exit". Used to test simple pipe transfer across processes via channels.
  653. DEFINE_TEST_CLIENT_WITH_PIPE(EchoServiceClient,
  654. MultiprocessMessagePipeTest,
  655. h) {
  656. MojoHandle p;
  657. ReadMessageWithHandles(h, &p, 1);
  658. for (;;) {
  659. std::string message = ReadMessage(p);
  660. if (message == "exit")
  661. break;
  662. WriteMessage(p, message);
  663. }
  664. return 0;
  665. }
  666. TEST_P(MultiprocessMessagePipeTestWithPeerSupport,
  667. PassMessagePipeCrossProcess) {
  668. MojoHandle p0, p1;
  669. CreateMessagePipe(&p0, &p1);
  670. RunTestClient("EchoServiceClient", [&](MojoHandle h) {
  671. // Pass one end of the pipe to the other process.
  672. WriteMessageWithHandles(h, "here take this", &p1, 1);
  673. VerifyEcho(p0, "and you may ask yourself");
  674. VerifyEcho(p0, "where does that highway go?");
  675. VerifyEcho(p0, std::string(20 * 1024 * 1024, 'i'));
  676. WriteMessage(p0, "exit");
  677. });
  678. CloseHandle(p0);
  679. }
  680. // Receives a pipe handle from the primordial channel and reads new handles
  681. // from it. Each read handle establishes a new echo channel.
  682. DEFINE_TEST_CLIENT_WITH_PIPE(EchoServiceFactoryClient,
  683. MultiprocessMessagePipeTest,
  684. h) {
  685. MojoHandle p;
  686. ReadMessageWithHandles(h, &p, 1);
  687. std::vector<Handle> handles(2);
  688. handles[0] = Handle(h);
  689. handles[1] = Handle(p);
  690. std::vector<MojoHandleSignals> signals(2, MOJO_HANDLE_SIGNAL_READABLE);
  691. for (;;) {
  692. size_t index;
  693. CHECK_EQ(
  694. mojo::WaitMany(handles.data(), signals.data(), handles.size(), &index),
  695. MOJO_RESULT_OK);
  696. DCHECK_LE(index, handles.size());
  697. if (index == 0) {
  698. // If data is available on the first pipe, it should be an exit command.
  699. EXPECT_EQ(std::string("exit"), ReadMessage(h));
  700. break;
  701. } else if (index == 1) {
  702. // If the second pipe, it should be a new handle requesting echo service.
  703. MojoHandle echo_request;
  704. ReadMessageWithHandles(p, &echo_request, 1);
  705. handles.push_back(Handle(echo_request));
  706. signals.push_back(MOJO_HANDLE_SIGNAL_READABLE);
  707. } else {
  708. // Otherwise it was one of our established echo pipes. Echo!
  709. WriteMessage(handles[index].value(), ReadMessage(handles[index].value()));
  710. }
  711. }
  712. for (size_t i = 1; i < handles.size(); ++i)
  713. CloseHandle(handles[i].value());
  714. return 0;
  715. }
  716. TEST_P(MultiprocessMessagePipeTestWithPeerSupport,
  717. PassMoarMessagePipesCrossProcess) {
  718. MojoHandle echo_factory_proxy, echo_factory_request;
  719. CreateMessagePipe(&echo_factory_proxy, &echo_factory_request);
  720. MojoHandle echo_proxy_a, echo_request_a;
  721. CreateMessagePipe(&echo_proxy_a, &echo_request_a);
  722. MojoHandle echo_proxy_b, echo_request_b;
  723. CreateMessagePipe(&echo_proxy_b, &echo_request_b);
  724. MojoHandle echo_proxy_c, echo_request_c;
  725. CreateMessagePipe(&echo_proxy_c, &echo_request_c);
  726. RunTestClient("EchoServiceFactoryClient", [&](MojoHandle h) {
  727. WriteMessageWithHandles(h, "gief factory naow plz", &echo_factory_request,
  728. 1);
  729. WriteMessageWithHandles(echo_factory_proxy, "give me an echo service plz!",
  730. &echo_request_a, 1);
  731. WriteMessageWithHandles(echo_factory_proxy, "give me one too!",
  732. &echo_request_b, 1);
  733. VerifyEcho(echo_proxy_a, "i came here for an argument");
  734. VerifyEcho(echo_proxy_a, "shut your festering gob");
  735. VerifyEcho(echo_proxy_a, "mumble mumble mumble");
  736. VerifyEcho(echo_proxy_b, "wubalubadubdub");
  737. VerifyEcho(echo_proxy_b, "wubalubadubdub");
  738. WriteMessageWithHandles(echo_factory_proxy, "hook me up also thanks",
  739. &echo_request_c, 1);
  740. VerifyEcho(echo_proxy_a, "the frobinators taste like frobinators");
  741. VerifyEcho(echo_proxy_b, "beep bop boop");
  742. VerifyEcho(echo_proxy_c, "zzzzzzzzzzzzzzzzzzzzzzzzzz");
  743. WriteMessage(h, "exit");
  744. });
  745. CloseHandle(echo_factory_proxy);
  746. CloseHandle(echo_proxy_a);
  747. CloseHandle(echo_proxy_b);
  748. CloseHandle(echo_proxy_c);
  749. }
  750. // Flaky on Android. See https://crbug.com/905620.
  751. #if BUILDFLAG(IS_ANDROID)
  752. #define MAYBE_ChannelPipesWithMultipleChildren \
  753. DISABLED_ChannelPipesWithMultipleChildren
  754. #else
  755. #define MAYBE_ChannelPipesWithMultipleChildren ChannelPipesWithMultipleChildren
  756. #endif
  757. TEST_P(MultiprocessMessagePipeTestWithPeerSupport,
  758. MAYBE_ChannelPipesWithMultipleChildren) {
  759. RunTestClient("ChannelEchoClient", [&](MojoHandle a) {
  760. RunTestClient("ChannelEchoClient", [&](MojoHandle b) {
  761. VerifyEcho(a, "hello child 0");
  762. VerifyEcho(b, "hello child 1");
  763. WriteMessage(a, "exit");
  764. WriteMessage(b, "exit");
  765. });
  766. });
  767. }
  768. // Reads and turns a pipe handle some number of times to create lots of
  769. // transient proxies.
  770. DEFINE_TEST_CLIENT_TEST_WITH_PIPE(PingPongPipeClient,
  771. MultiprocessMessagePipeTest,
  772. h) {
  773. const size_t kNumBounces = 50;
  774. MojoHandle p0, p1;
  775. ReadMessageWithHandles(h, &p0, 1);
  776. ReadMessageWithHandles(h, &p1, 1);
  777. for (size_t i = 0; i < kNumBounces; ++i) {
  778. WriteMessageWithHandles(h, "", &p1, 1);
  779. ReadMessageWithHandles(h, &p1, 1);
  780. }
  781. WriteMessageWithHandles(h, "", &p0, 1);
  782. WriteMessage(p1, "bye");
  783. MojoClose(p1);
  784. EXPECT_EQ("quit", ReadMessage(h));
  785. }
  786. TEST_P(MultiprocessMessagePipeTestWithPeerSupport, PingPongPipe) {
  787. MojoHandle p0, p1;
  788. CreateMessagePipe(&p0, &p1);
  789. RunTestClient("PingPongPipeClient", [&](MojoHandle h) {
  790. const size_t kNumBounces = 50;
  791. WriteMessageWithHandles(h, "", &p0, 1);
  792. WriteMessageWithHandles(h, "", &p1, 1);
  793. for (size_t i = 0; i < kNumBounces; ++i) {
  794. ReadMessageWithHandles(h, &p1, 1);
  795. WriteMessageWithHandles(h, "", &p1, 1);
  796. }
  797. ReadMessageWithHandles(h, &p0, 1);
  798. WriteMessage(h, "quit");
  799. });
  800. EXPECT_EQ("bye", ReadMessage(p0));
  801. // We should still be able to observe peer closure from the other end.
  802. EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(p0, MOJO_HANDLE_SIGNAL_PEER_CLOSED));
  803. }
  804. // Parses commands from the parent pipe and does whatever it's asked to do.
  805. DEFINE_TEST_CLIENT_WITH_PIPE(CommandDrivenClient,
  806. MultiprocessMessagePipeTest,
  807. h) {
  808. std::unordered_map<std::string, MojoHandle> named_pipes;
  809. for (;;) {
  810. MojoHandle p;
  811. auto parts = base::SplitString(ReadMessageWithOptionalHandle(h, &p), ":",
  812. base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  813. CHECK(!parts.empty());
  814. std::string command = parts[0];
  815. if (command == "take") {
  816. // Take a pipe.
  817. CHECK_EQ(parts.size(), 2u);
  818. CHECK_NE(p, MOJO_HANDLE_INVALID);
  819. named_pipes[parts[1]] = p;
  820. WriteMessage(h, "ok");
  821. } else if (command == "return") {
  822. // Return a pipe.
  823. CHECK_EQ(parts.size(), 2u);
  824. CHECK_EQ(p, MOJO_HANDLE_INVALID);
  825. p = named_pipes[parts[1]];
  826. CHECK_NE(p, MOJO_HANDLE_INVALID);
  827. named_pipes.erase(parts[1]);
  828. WriteMessageWithHandles(h, "ok", &p, 1);
  829. } else if (command == "say") {
  830. // Say something to a named pipe.
  831. CHECK_EQ(parts.size(), 3u);
  832. CHECK_EQ(p, MOJO_HANDLE_INVALID);
  833. p = named_pipes[parts[1]];
  834. CHECK_NE(p, MOJO_HANDLE_INVALID);
  835. CHECK(!parts[2].empty());
  836. WriteMessage(p, parts[2]);
  837. WriteMessage(h, "ok");
  838. } else if (command == "hear") {
  839. // Expect to read something from a named pipe.
  840. CHECK_EQ(parts.size(), 3u);
  841. CHECK_EQ(p, MOJO_HANDLE_INVALID);
  842. p = named_pipes[parts[1]];
  843. CHECK_NE(p, MOJO_HANDLE_INVALID);
  844. CHECK(!parts[2].empty());
  845. CHECK_EQ(parts[2], ReadMessage(p));
  846. WriteMessage(h, "ok");
  847. } else if (command == "pass") {
  848. // Pass one named pipe over another named pipe.
  849. CHECK_EQ(parts.size(), 3u);
  850. CHECK_EQ(p, MOJO_HANDLE_INVALID);
  851. p = named_pipes[parts[1]];
  852. MojoHandle carrier = named_pipes[parts[2]];
  853. CHECK_NE(p, MOJO_HANDLE_INVALID);
  854. CHECK_NE(carrier, MOJO_HANDLE_INVALID);
  855. named_pipes.erase(parts[1]);
  856. WriteMessageWithHandles(carrier, "got a pipe for ya", &p, 1);
  857. WriteMessage(h, "ok");
  858. } else if (command == "catch") {
  859. // Expect to receive one named pipe from another named pipe.
  860. CHECK_EQ(parts.size(), 3u);
  861. CHECK_EQ(p, MOJO_HANDLE_INVALID);
  862. MojoHandle carrier = named_pipes[parts[2]];
  863. CHECK_NE(carrier, MOJO_HANDLE_INVALID);
  864. ReadMessageWithHandles(carrier, &p, 1);
  865. CHECK_NE(p, MOJO_HANDLE_INVALID);
  866. named_pipes[parts[1]] = p;
  867. WriteMessage(h, "ok");
  868. } else if (command == "exit") {
  869. CHECK_EQ(parts.size(), 1u);
  870. break;
  871. }
  872. }
  873. for (auto& pipe : named_pipes)
  874. CloseHandle(pipe.second);
  875. return 0;
  876. }
  877. TEST_F(MultiprocessMessagePipeTest, ChildToChildPipes) {
  878. RunTestClient("CommandDrivenClient", [&](MojoHandle h0) {
  879. RunTestClient("CommandDrivenClient", [&](MojoHandle h1) {
  880. CommandDrivenClientController a(h0);
  881. CommandDrivenClientController b(h1);
  882. // Create a pipe and pass each end to a different client.
  883. MojoHandle p0, p1;
  884. CreateMessagePipe(&p0, &p1);
  885. a.SendHandle("x", p0);
  886. b.SendHandle("y", p1);
  887. // Make sure they can talk.
  888. a.Send("say:x:hello");
  889. b.Send("hear:y:hello");
  890. b.Send("say:y:i love multiprocess pipes!");
  891. a.Send("hear:x:i love multiprocess pipes!");
  892. a.Exit();
  893. b.Exit();
  894. });
  895. });
  896. }
  897. TEST_F(MultiprocessMessagePipeTest, MoreChildToChildPipes) {
  898. RunTestClient("CommandDrivenClient", [&](MojoHandle h0) {
  899. RunTestClient("CommandDrivenClient", [&](MojoHandle h1) {
  900. RunTestClient("CommandDrivenClient", [&](MojoHandle h2) {
  901. RunTestClient("CommandDrivenClient", [&](MojoHandle h3) {
  902. CommandDrivenClientController a(h0), b(h1), c(h2), d(h3);
  903. // Connect a to b and c to d
  904. MojoHandle p0, p1;
  905. CreateMessagePipe(&p0, &p1);
  906. a.SendHandle("b_pipe", p0);
  907. b.SendHandle("a_pipe", p1);
  908. MojoHandle p2, p3;
  909. CreateMessagePipe(&p2, &p3);
  910. c.SendHandle("d_pipe", p2);
  911. d.SendHandle("c_pipe", p3);
  912. // Connect b to c via a and d
  913. MojoHandle p4, p5;
  914. CreateMessagePipe(&p4, &p5);
  915. a.SendHandle("d_pipe", p4);
  916. d.SendHandle("a_pipe", p5);
  917. // Have |a| pass its new |d|-pipe to |b|. It will eventually connect
  918. // to |c|.
  919. a.Send("pass:d_pipe:b_pipe");
  920. b.Send("catch:c_pipe:a_pipe");
  921. // Have |d| pass its new |a|-pipe to |c|. It will now be connected to
  922. // |b|.
  923. d.Send("pass:a_pipe:c_pipe");
  924. c.Send("catch:b_pipe:d_pipe");
  925. // Make sure b and c and talk.
  926. b.Send("say:c_pipe:it's a beautiful day");
  927. c.Send("hear:b_pipe:it's a beautiful day");
  928. // Create x and y and have b and c exchange them.
  929. MojoHandle x, y;
  930. CreateMessagePipe(&x, &y);
  931. b.SendHandle("x", x);
  932. c.SendHandle("y", y);
  933. b.Send("pass:x:c_pipe");
  934. c.Send("pass:y:b_pipe");
  935. b.Send("catch:y:c_pipe");
  936. c.Send("catch:x:b_pipe");
  937. // Make sure the pipe still works in both directions.
  938. b.Send("say:y:hello");
  939. c.Send("hear:x:hello");
  940. c.Send("say:x:goodbye");
  941. b.Send("hear:y:goodbye");
  942. // Take both pipes back.
  943. y = c.RetrieveHandle("x");
  944. x = b.RetrieveHandle("y");
  945. VerifyTransmission(x, y, "still works");
  946. VerifyTransmission(y, x, "in both directions");
  947. CloseHandle(x);
  948. CloseHandle(y);
  949. a.Exit();
  950. b.Exit();
  951. c.Exit();
  952. d.Exit();
  953. });
  954. });
  955. });
  956. });
  957. }
  958. DEFINE_TEST_CLIENT_TEST_WITH_PIPE(ReceivePipeWithClosedPeer,
  959. MultiprocessMessagePipeTest,
  960. h) {
  961. MojoHandle p;
  962. EXPECT_EQ("foo", ReadMessageWithHandles(h, &p, 1));
  963. EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(p, MOJO_HANDLE_SIGNAL_PEER_CLOSED));
  964. }
  965. TEST_P(MultiprocessMessagePipeTestWithPeerSupport, SendPipeThenClosePeer) {
  966. RunTestClient("ReceivePipeWithClosedPeer", [&](MojoHandle h) {
  967. MojoHandle a, b;
  968. CreateMessagePipe(&a, &b);
  969. // Send |a| and immediately close |b|. The child should observe closure.
  970. WriteMessageWithHandles(h, "foo", &a, 1);
  971. MojoClose(b);
  972. });
  973. }
  974. DEFINE_TEST_CLIENT_TEST_WITH_PIPE(SendOtherChildPipeWithClosedPeer,
  975. MultiprocessMessagePipeTest,
  976. h) {
  977. // Create a new pipe and send one end to the parent, who will connect it to
  978. // a client running ReceivePipeWithClosedPeerFromOtherChild.
  979. MojoHandle application_proxy, application_request;
  980. CreateMessagePipe(&application_proxy, &application_request);
  981. WriteMessageWithHandles(h, "c2a plz", &application_request, 1);
  982. // Create another pipe and send one end to the remote "application".
  983. MojoHandle service_proxy, service_request;
  984. CreateMessagePipe(&service_proxy, &service_request);
  985. WriteMessageWithHandles(application_proxy, "c2s lol", &service_request, 1);
  986. // Immediately close the service proxy. The "application" should detect this.
  987. EXPECT_EQ(MOJO_RESULT_OK, MojoClose(service_proxy));
  988. // Wait for quit.
  989. EXPECT_EQ("quit", ReadMessage(h));
  990. }
  991. DEFINE_TEST_CLIENT_TEST_WITH_PIPE(ReceivePipeWithClosedPeerFromOtherChild,
  992. MultiprocessMessagePipeTest,
  993. h) {
  994. // Receive a pipe from the parent. This is akin to an "application request".
  995. MojoHandle application_client;
  996. EXPECT_EQ("c2a", ReadMessageWithHandles(h, &application_client, 1));
  997. // Receive a pipe from the "application" "client".
  998. MojoHandle service_client;
  999. EXPECT_EQ("c2s lol",
  1000. ReadMessageWithHandles(application_client, &service_client, 1));
  1001. // Wait for the service client to signal closure.
  1002. EXPECT_EQ(MOJO_RESULT_OK,
  1003. WaitForSignals(service_client, MOJO_HANDLE_SIGNAL_PEER_CLOSED));
  1004. EXPECT_EQ(MOJO_RESULT_OK, MojoClose(service_client));
  1005. EXPECT_EQ(MOJO_RESULT_OK, MojoClose(application_client));
  1006. }
  1007. #if BUILDFLAG(IS_ANDROID)
  1008. // Android multi-process tests are not executing the new process. This is flaky.
  1009. #define MAYBE_SendPipeWithClosedPeerBetweenChildren \
  1010. DISABLED_SendPipeWithClosedPeerBetweenChildren
  1011. #else
  1012. #define MAYBE_SendPipeWithClosedPeerBetweenChildren \
  1013. SendPipeWithClosedPeerBetweenChildren
  1014. #endif
  1015. TEST_F(MultiprocessMessagePipeTest,
  1016. MAYBE_SendPipeWithClosedPeerBetweenChildren) {
  1017. RunTestClient("SendOtherChildPipeWithClosedPeer", [&](MojoHandle kid_a) {
  1018. RunTestClient(
  1019. "ReceivePipeWithClosedPeerFromOtherChild", [&](MojoHandle kid_b) {
  1020. // Receive an "application request" from the first child and forward
  1021. // it to the second child.
  1022. MojoHandle application_request;
  1023. EXPECT_EQ("c2a plz",
  1024. ReadMessageWithHandles(kid_a, &application_request, 1));
  1025. WriteMessageWithHandles(kid_b, "c2a", &application_request, 1);
  1026. });
  1027. WriteMessage(kid_a, "quit");
  1028. });
  1029. }
  1030. TEST_P(MultiprocessMessagePipeTestWithPeerSupport, SendClosePeerSend) {
  1031. MojoHandle a, b;
  1032. CreateMessagePipe(&a, &b);
  1033. MojoHandle c, d;
  1034. CreateMessagePipe(&c, &d);
  1035. // Send |a| over |c|, immediately close |b|, then send |a| back over |d|.
  1036. WriteMessageWithHandles(c, "foo", &a, 1);
  1037. EXPECT_EQ("foo", ReadMessageWithHandles(d, &a, 1));
  1038. WriteMessageWithHandles(d, "bar", &a, 1);
  1039. EXPECT_EQ("bar", ReadMessageWithHandles(c, &a, 1));
  1040. EXPECT_EQ(MOJO_RESULT_OK, MojoClose(b));
  1041. // We should be able to detect peer closure on |a|.
  1042. EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(a, MOJO_HANDLE_SIGNAL_PEER_CLOSED));
  1043. }
  1044. DEFINE_TEST_CLIENT_TEST_WITH_PIPE(WriteCloseSendPeerClient,
  1045. MultiprocessMessagePipeTest,
  1046. h) {
  1047. MojoHandle pipe[2];
  1048. EXPECT_EQ("foo", ReadMessageWithHandles(h, pipe, 2));
  1049. // Write some messages to the first endpoint and then close it.
  1050. WriteMessage(pipe[0], "baz");
  1051. WriteMessage(pipe[0], "qux");
  1052. EXPECT_EQ(MOJO_RESULT_OK, MojoClose(pipe[0]));
  1053. MojoHandle c, d;
  1054. CreateMessagePipe(&c, &d);
  1055. // Pass the orphaned endpoint over another pipe before passing it back to
  1056. // the parent, just for some extra proxying goodness.
  1057. WriteMessageWithHandles(c, "foo", &pipe[1], 1);
  1058. EXPECT_EQ("foo", ReadMessageWithHandles(d, &pipe[1], 1));
  1059. // And finally pass it back to the parent.
  1060. WriteMessageWithHandles(h, "bar", &pipe[1], 1);
  1061. EXPECT_EQ("quit", ReadMessage(h));
  1062. }
  1063. TEST_P(MultiprocessMessagePipeTestWithPeerSupport, WriteCloseSendPeer) {
  1064. MojoHandle pipe[2];
  1065. CreateMessagePipe(&pipe[0], &pipe[1]);
  1066. RunTestClient("WriteCloseSendPeerClient", [&](MojoHandle h) {
  1067. // Pass the pipe to the child.
  1068. WriteMessageWithHandles(h, "foo", pipe, 2);
  1069. // Read back an endpoint which should have messages on it.
  1070. MojoHandle p;
  1071. EXPECT_EQ("bar", ReadMessageWithHandles(h, &p, 1));
  1072. EXPECT_EQ("baz", ReadMessage(p));
  1073. EXPECT_EQ("qux", ReadMessage(p));
  1074. // Expect to have peer closure signaled.
  1075. EXPECT_EQ(MOJO_RESULT_OK,
  1076. WaitForSignals(p, MOJO_HANDLE_SIGNAL_PEER_CLOSED));
  1077. WriteMessage(h, "quit");
  1078. });
  1079. }
  1080. DEFINE_TEST_CLIENT_TEST_WITH_PIPE(MessagePipeStatusChangeInTransitClient,
  1081. MultiprocessMessagePipeTest,
  1082. parent) {
  1083. // This test verifies that peer closure is detectable through various
  1084. // mechanisms when it races with handle transfer.
  1085. MojoHandle handles[4];
  1086. EXPECT_EQ("o_O", ReadMessageWithHandles(parent, handles, 4));
  1087. EXPECT_EQ(MOJO_RESULT_OK,
  1088. WaitForSignals(handles[0], MOJO_HANDLE_SIGNAL_PEER_CLOSED));
  1089. base::test::SingleThreadTaskEnvironment task_environment;
  1090. // Wait on handle 1 using a SimpleWatcher.
  1091. {
  1092. base::RunLoop run_loop;
  1093. SimpleWatcher watcher(FROM_HERE, SimpleWatcher::ArmingPolicy::AUTOMATIC,
  1094. base::SequencedTaskRunnerHandle::Get());
  1095. watcher.Watch(Handle(handles[1]), MOJO_HANDLE_SIGNAL_PEER_CLOSED,
  1096. base::BindRepeating(
  1097. [](base::RunLoop* loop, MojoResult result) {
  1098. EXPECT_EQ(MOJO_RESULT_OK, result);
  1099. loop->Quit();
  1100. },
  1101. &run_loop));
  1102. run_loop.Run();
  1103. }
  1104. // Wait on handle 2 by polling with MojoReadMessage.
  1105. MojoResult result;
  1106. do {
  1107. result = MojoReadMessage(handles[2], nullptr, nullptr, nullptr, nullptr,
  1108. MOJO_READ_MESSAGE_FLAG_NONE);
  1109. } while (result == MOJO_RESULT_SHOULD_WAIT);
  1110. EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
  1111. // Wait on handle 3 by polling with MojoWriteMessage.
  1112. do {
  1113. result = MojoWriteMessage(handles[3], nullptr, 0, nullptr, 0,
  1114. MOJO_WRITE_MESSAGE_FLAG_NONE);
  1115. } while (result == MOJO_RESULT_OK);
  1116. EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
  1117. for (size_t i = 0; i < 4; ++i)
  1118. CloseHandle(handles[i]);
  1119. }
  1120. TEST_P(MultiprocessMessagePipeTestWithPeerSupport,
  1121. ReceiveMessagesSentJustBeforeProcessDeath) {
  1122. // Regression test for https://crbug.com/1005510. The client will write a
  1123. // message to the pipe it gives us and then it will die immediately. We should
  1124. // always be able to read the message received on that pipe.
  1125. RunTestClient("SpotaneouslyDyingProcess", [&](MojoHandle child) {
  1126. MojoHandle receiver;
  1127. EXPECT_EQ("receiver", ReadMessageWithHandles(child, &receiver, 1));
  1128. EXPECT_EQ("ok", ReadMessage(receiver));
  1129. });
  1130. }
  1131. DEFINE_TEST_CLIENT_TEST_WITH_PIPE(SpotaneouslyDyingProcess,
  1132. MultiprocessMessagePipeTest,
  1133. parent) {
  1134. MojoHandle sender;
  1135. MojoHandle receiver;
  1136. CreateMessagePipe(&sender, &receiver);
  1137. WriteMessageWithHandles(parent, "receiver", &receiver, 1);
  1138. // Wait for the pipe to actually appear as remote. Before this happens, it's
  1139. // possible for message transmission to be deferred to the IO thread, and
  1140. // sudden termination might preempt that work.
  1141. WaitForSignals(sender, MOJO_HANDLE_SIGNAL_PEER_REMOTE);
  1142. WriteMessage(sender, "ok");
  1143. // Here process termination is imminent. If the bug reappears this test will
  1144. // fail flakily.
  1145. }
  1146. TEST_F(MultiprocessMessagePipeTest, MessagePipeStatusChangeInTransit) {
  1147. MojoHandle local_handles[4];
  1148. MojoHandle sent_handles[4];
  1149. for (size_t i = 0; i < 4; ++i)
  1150. CreateMessagePipe(&local_handles[i], &sent_handles[i]);
  1151. RunTestClient("MessagePipeStatusChangeInTransitClient",
  1152. [&](MojoHandle child) {
  1153. // Send 4 handles and let their transfer race with their
  1154. // peers' closure.
  1155. WriteMessageWithHandles(child, "o_O", sent_handles, 4);
  1156. for (size_t i = 0; i < 4; ++i)
  1157. CloseHandle(local_handles[i]);
  1158. });
  1159. }
  1160. DEFINE_TEST_CLIENT_TEST_WITH_PIPE(BadMessageClient,
  1161. MultiprocessMessagePipeTest,
  1162. parent) {
  1163. MojoHandle pipe;
  1164. EXPECT_EQ("hi", ReadMessageWithHandles(parent, &pipe, 1));
  1165. WriteMessage(pipe, "derp");
  1166. EXPECT_EQ("bye", ReadMessage(parent));
  1167. }
  1168. INSTANTIATE_TEST_SUITE_P(
  1169. All,
  1170. MultiprocessMessagePipeTestWithPeerSupport,
  1171. testing::Values(test::MojoTestBase::LaunchType::CHILD,
  1172. test::MojoTestBase::LaunchType::CHILD_WITHOUT_CAPABILITIES,
  1173. test::MojoTestBase::LaunchType::PEER,
  1174. test::MojoTestBase::LaunchType::ASYNC
  1175. #if !BUILDFLAG(IS_FUCHSIA)
  1176. // Fuchsia has no named pipe support.
  1177. ,
  1178. test::MojoTestBase::LaunchType::NAMED_CHILD,
  1179. test::MojoTestBase::LaunchType::NAMED_PEER
  1180. #endif // !BUILDFLAG(IS_FUCHSIA)
  1181. ));
  1182. } // namespace
  1183. } // namespace core
  1184. } // namespace mojo