xref: /aosp_15_r20/external/libchrome/ipc/sync_socket_unittest.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #include "base/sync_socket.h"
6*635a8641SAndroid Build Coastguard Worker 
7*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
8*635a8641SAndroid Build Coastguard Worker #include <stdio.h>
9*635a8641SAndroid Build Coastguard Worker #include <memory>
10*635a8641SAndroid Build Coastguard Worker #include <sstream>
11*635a8641SAndroid Build Coastguard Worker #include <string>
12*635a8641SAndroid Build Coastguard Worker 
13*635a8641SAndroid Build Coastguard Worker #include "base/bind.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/location.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/run_loop.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/single_thread_task_runner.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread.h"
19*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
20*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_test_base.h"
21*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
22*635a8641SAndroid Build Coastguard Worker 
23*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
24*635a8641SAndroid Build Coastguard Worker #include "base/file_descriptor_posix.h"
25*635a8641SAndroid Build Coastguard Worker #endif
26*635a8641SAndroid Build Coastguard Worker 
27*635a8641SAndroid Build Coastguard Worker // IPC messages for testing ----------------------------------------------------
28*635a8641SAndroid Build Coastguard Worker 
29*635a8641SAndroid Build Coastguard Worker #define IPC_MESSAGE_IMPL
30*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_message_macros.h"
31*635a8641SAndroid Build Coastguard Worker 
32*635a8641SAndroid Build Coastguard Worker #define IPC_MESSAGE_START TestMsgStart
33*635a8641SAndroid Build Coastguard Worker 
34*635a8641SAndroid Build Coastguard Worker // Message class to pass a base::SyncSocket::Handle to another process.  This
35*635a8641SAndroid Build Coastguard Worker // is not as easy as it sounds, because of the differences in transferring
36*635a8641SAndroid Build Coastguard Worker // Windows HANDLEs versus posix file descriptors.
37*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
38*635a8641SAndroid Build Coastguard Worker IPC_MESSAGE_CONTROL1(MsgClassSetHandle, base::SyncSocket::Handle)
39*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX)
40*635a8641SAndroid Build Coastguard Worker IPC_MESSAGE_CONTROL1(MsgClassSetHandle, base::FileDescriptor)
41*635a8641SAndroid Build Coastguard Worker #endif
42*635a8641SAndroid Build Coastguard Worker 
43*635a8641SAndroid Build Coastguard Worker // Message class to pass a response to the server.
44*635a8641SAndroid Build Coastguard Worker IPC_MESSAGE_CONTROL1(MsgClassResponse, std::string)
45*635a8641SAndroid Build Coastguard Worker 
46*635a8641SAndroid Build Coastguard Worker // Message class to tell the server to shut down.
47*635a8641SAndroid Build Coastguard Worker IPC_MESSAGE_CONTROL0(MsgClassShutdown)
48*635a8641SAndroid Build Coastguard Worker 
49*635a8641SAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
50*635a8641SAndroid Build Coastguard Worker 
51*635a8641SAndroid Build Coastguard Worker namespace {
52*635a8641SAndroid Build Coastguard Worker 
53*635a8641SAndroid Build Coastguard Worker const char kHelloString[] = "Hello, SyncSocket Client";
54*635a8641SAndroid Build Coastguard Worker const size_t kHelloStringLength = arraysize(kHelloString);
55*635a8641SAndroid Build Coastguard Worker 
56*635a8641SAndroid Build Coastguard Worker // The SyncSocket server listener class processes two sorts of
57*635a8641SAndroid Build Coastguard Worker // messages from the client.
58*635a8641SAndroid Build Coastguard Worker class SyncSocketServerListener : public IPC::Listener {
59*635a8641SAndroid Build Coastguard Worker  public:
SyncSocketServerListener()60*635a8641SAndroid Build Coastguard Worker   SyncSocketServerListener() : chan_(NULL) {
61*635a8641SAndroid Build Coastguard Worker   }
62*635a8641SAndroid Build Coastguard Worker 
Init(IPC::Channel * chan)63*635a8641SAndroid Build Coastguard Worker   void Init(IPC::Channel* chan) {
64*635a8641SAndroid Build Coastguard Worker     chan_ = chan;
65*635a8641SAndroid Build Coastguard Worker   }
66*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & msg)67*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& msg) override {
68*635a8641SAndroid Build Coastguard Worker     if (msg.routing_id() == MSG_ROUTING_CONTROL) {
69*635a8641SAndroid Build Coastguard Worker       IPC_BEGIN_MESSAGE_MAP(SyncSocketServerListener, msg)
70*635a8641SAndroid Build Coastguard Worker         IPC_MESSAGE_HANDLER(MsgClassSetHandle, OnMsgClassSetHandle)
71*635a8641SAndroid Build Coastguard Worker         IPC_MESSAGE_HANDLER(MsgClassShutdown, OnMsgClassShutdown)
72*635a8641SAndroid Build Coastguard Worker       IPC_END_MESSAGE_MAP()
73*635a8641SAndroid Build Coastguard Worker     }
74*635a8641SAndroid Build Coastguard Worker     return true;
75*635a8641SAndroid Build Coastguard Worker   }
76*635a8641SAndroid Build Coastguard Worker 
77*635a8641SAndroid Build Coastguard Worker  private:
78*635a8641SAndroid Build Coastguard Worker   // This sort of message is sent first, causing the transfer of
79*635a8641SAndroid Build Coastguard Worker   // the handle for the SyncSocket.  This message sends a buffer
80*635a8641SAndroid Build Coastguard Worker   // on the SyncSocket and then sends a response to the client.
81*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
OnMsgClassSetHandle(const base::SyncSocket::Handle handle)82*635a8641SAndroid Build Coastguard Worker   void OnMsgClassSetHandle(const base::SyncSocket::Handle handle) {
83*635a8641SAndroid Build Coastguard Worker     SetHandle(handle);
84*635a8641SAndroid Build Coastguard Worker   }
85*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX)
86*635a8641SAndroid Build Coastguard Worker   void OnMsgClassSetHandle(const base::FileDescriptor& fd_struct) {
87*635a8641SAndroid Build Coastguard Worker     SetHandle(fd_struct.fd);
88*635a8641SAndroid Build Coastguard Worker   }
89*635a8641SAndroid Build Coastguard Worker #else
90*635a8641SAndroid Build Coastguard Worker # error "What platform?"
91*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_WIN)
92*635a8641SAndroid Build Coastguard Worker 
SetHandle(base::SyncSocket::Handle handle)93*635a8641SAndroid Build Coastguard Worker   void SetHandle(base::SyncSocket::Handle handle) {
94*635a8641SAndroid Build Coastguard Worker     base::SyncSocket sync_socket(handle);
95*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(sync_socket.Send(kHelloString, kHelloStringLength),
96*635a8641SAndroid Build Coastguard Worker               kHelloStringLength);
97*635a8641SAndroid Build Coastguard Worker     IPC::Message* msg = new MsgClassResponse(kHelloString);
98*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(chan_->Send(msg));
99*635a8641SAndroid Build Coastguard Worker   }
100*635a8641SAndroid Build Coastguard Worker 
101*635a8641SAndroid Build Coastguard Worker   // When the client responds, it sends back a shutdown message,
102*635a8641SAndroid Build Coastguard Worker   // which causes the message loop to exit.
OnMsgClassShutdown()103*635a8641SAndroid Build Coastguard Worker   void OnMsgClassShutdown() { base::RunLoop::QuitCurrentWhenIdleDeprecated(); }
104*635a8641SAndroid Build Coastguard Worker 
105*635a8641SAndroid Build Coastguard Worker   IPC::Channel* chan_;
106*635a8641SAndroid Build Coastguard Worker 
107*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(SyncSocketServerListener);
108*635a8641SAndroid Build Coastguard Worker };
109*635a8641SAndroid Build Coastguard Worker 
110*635a8641SAndroid Build Coastguard Worker // Runs the fuzzing server child mode. Returns when the preset number of
111*635a8641SAndroid Build Coastguard Worker // messages have been received.
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SyncSocketServerClient)112*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SyncSocketServerClient) {
113*635a8641SAndroid Build Coastguard Worker   SyncSocketServerListener listener;
114*635a8641SAndroid Build Coastguard Worker   Connect(&listener);
115*635a8641SAndroid Build Coastguard Worker   listener.Init(channel());
116*635a8641SAndroid Build Coastguard Worker   base::RunLoop().Run();
117*635a8641SAndroid Build Coastguard Worker   Close();
118*635a8641SAndroid Build Coastguard Worker }
119*635a8641SAndroid Build Coastguard Worker 
120*635a8641SAndroid Build Coastguard Worker // The SyncSocket client listener only processes one sort of message,
121*635a8641SAndroid Build Coastguard Worker // a response from the server.
122*635a8641SAndroid Build Coastguard Worker class SyncSocketClientListener : public IPC::Listener {
123*635a8641SAndroid Build Coastguard Worker  public:
124*635a8641SAndroid Build Coastguard Worker   SyncSocketClientListener() = default;
125*635a8641SAndroid Build Coastguard Worker 
Init(base::SyncSocket * socket,IPC::Channel * chan)126*635a8641SAndroid Build Coastguard Worker   void Init(base::SyncSocket* socket, IPC::Channel* chan) {
127*635a8641SAndroid Build Coastguard Worker     socket_ = socket;
128*635a8641SAndroid Build Coastguard Worker     chan_ = chan;
129*635a8641SAndroid Build Coastguard Worker   }
130*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & msg)131*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& msg) override {
132*635a8641SAndroid Build Coastguard Worker     if (msg.routing_id() == MSG_ROUTING_CONTROL) {
133*635a8641SAndroid Build Coastguard Worker       IPC_BEGIN_MESSAGE_MAP(SyncSocketClientListener, msg)
134*635a8641SAndroid Build Coastguard Worker         IPC_MESSAGE_HANDLER(MsgClassResponse, OnMsgClassResponse)
135*635a8641SAndroid Build Coastguard Worker       IPC_END_MESSAGE_MAP()
136*635a8641SAndroid Build Coastguard Worker     }
137*635a8641SAndroid Build Coastguard Worker     return true;
138*635a8641SAndroid Build Coastguard Worker   }
139*635a8641SAndroid Build Coastguard Worker 
140*635a8641SAndroid Build Coastguard Worker  private:
141*635a8641SAndroid Build Coastguard Worker   // When a response is received from the server, it sends the same
142*635a8641SAndroid Build Coastguard Worker   // string as was written on the SyncSocket.  These are compared
143*635a8641SAndroid Build Coastguard Worker   // and a shutdown message is sent back to the server.
OnMsgClassResponse(const std::string & str)144*635a8641SAndroid Build Coastguard Worker   void OnMsgClassResponse(const std::string& str) {
145*635a8641SAndroid Build Coastguard Worker     // We rely on the order of sync_socket.Send() and chan_->Send() in
146*635a8641SAndroid Build Coastguard Worker     // the SyncSocketServerListener object.
147*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(kHelloStringLength, socket_->Peek());
148*635a8641SAndroid Build Coastguard Worker     char buf[kHelloStringLength];
149*635a8641SAndroid Build Coastguard Worker     socket_->Receive(static_cast<void*>(buf), kHelloStringLength);
150*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(strcmp(str.c_str(), buf), 0);
151*635a8641SAndroid Build Coastguard Worker     // After receiving from the socket there should be no bytes left.
152*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(0U, socket_->Peek());
153*635a8641SAndroid Build Coastguard Worker     IPC::Message* msg = new MsgClassShutdown();
154*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(chan_->Send(msg));
155*635a8641SAndroid Build Coastguard Worker     base::RunLoop::QuitCurrentWhenIdleDeprecated();
156*635a8641SAndroid Build Coastguard Worker   }
157*635a8641SAndroid Build Coastguard Worker 
158*635a8641SAndroid Build Coastguard Worker   base::SyncSocket* socket_;
159*635a8641SAndroid Build Coastguard Worker   IPC::Channel* chan_;
160*635a8641SAndroid Build Coastguard Worker 
161*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(SyncSocketClientListener);
162*635a8641SAndroid Build Coastguard Worker };
163*635a8641SAndroid Build Coastguard Worker 
164*635a8641SAndroid Build Coastguard Worker using SyncSocketTest = IPCChannelMojoTestBase;
165*635a8641SAndroid Build Coastguard Worker 
TEST_F(SyncSocketTest,SanityTest)166*635a8641SAndroid Build Coastguard Worker TEST_F(SyncSocketTest, SanityTest) {
167*635a8641SAndroid Build Coastguard Worker   Init("SyncSocketServerClient");
168*635a8641SAndroid Build Coastguard Worker 
169*635a8641SAndroid Build Coastguard Worker   SyncSocketClientListener listener;
170*635a8641SAndroid Build Coastguard Worker   CreateChannel(&listener);
171*635a8641SAndroid Build Coastguard Worker   // Create a pair of SyncSockets.
172*635a8641SAndroid Build Coastguard Worker   base::SyncSocket pair[2];
173*635a8641SAndroid Build Coastguard Worker   base::SyncSocket::CreatePair(&pair[0], &pair[1]);
174*635a8641SAndroid Build Coastguard Worker   // Immediately after creation there should be no pending bytes.
175*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0U, pair[0].Peek());
176*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0U, pair[1].Peek());
177*635a8641SAndroid Build Coastguard Worker   base::SyncSocket::Handle target_handle;
178*635a8641SAndroid Build Coastguard Worker   // Connect the channel and listener.
179*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
180*635a8641SAndroid Build Coastguard Worker   listener.Init(&pair[0], channel());
181*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
182*635a8641SAndroid Build Coastguard Worker   // On windows we need to duplicate the handle into the server process.
183*635a8641SAndroid Build Coastguard Worker   BOOL retval = DuplicateHandle(GetCurrentProcess(), pair[1].handle(),
184*635a8641SAndroid Build Coastguard Worker                                 client_process().Handle(), &target_handle,
185*635a8641SAndroid Build Coastguard Worker                                 0, FALSE, DUPLICATE_SAME_ACCESS);
186*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(retval);
187*635a8641SAndroid Build Coastguard Worker   // Set up a message to pass the handle to the server.
188*635a8641SAndroid Build Coastguard Worker   IPC::Message* msg = new MsgClassSetHandle(target_handle);
189*635a8641SAndroid Build Coastguard Worker #else
190*635a8641SAndroid Build Coastguard Worker   target_handle = pair[1].handle();
191*635a8641SAndroid Build Coastguard Worker   // Set up a message to pass the handle to the server.
192*635a8641SAndroid Build Coastguard Worker   base::FileDescriptor filedesc(target_handle, false);
193*635a8641SAndroid Build Coastguard Worker   IPC::Message* msg = new MsgClassSetHandle(filedesc);
194*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_WIN)
195*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(sender()->Send(msg));
196*635a8641SAndroid Build Coastguard Worker   // Use the current thread as the I/O thread.
197*635a8641SAndroid Build Coastguard Worker   base::RunLoop().Run();
198*635a8641SAndroid Build Coastguard Worker   // Shut down.
199*635a8641SAndroid Build Coastguard Worker   pair[0].Close();
200*635a8641SAndroid Build Coastguard Worker   pair[1].Close();
201*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
202*635a8641SAndroid Build Coastguard Worker   DestroyChannel();
203*635a8641SAndroid Build Coastguard Worker }
204*635a8641SAndroid Build Coastguard Worker 
205*635a8641SAndroid Build Coastguard Worker // A blocking read operation that will block the thread until it receives
206*635a8641SAndroid Build Coastguard Worker // |length| bytes of packets or Shutdown() is called on another thread.
BlockingRead(base::SyncSocket * socket,char * buf,size_t length,size_t * received)207*635a8641SAndroid Build Coastguard Worker static void BlockingRead(base::SyncSocket* socket, char* buf,
208*635a8641SAndroid Build Coastguard Worker                          size_t length, size_t* received) {
209*635a8641SAndroid Build Coastguard Worker   DCHECK(buf != NULL);
210*635a8641SAndroid Build Coastguard Worker   // Notify the parent thread that we're up and running.
211*635a8641SAndroid Build Coastguard Worker   socket->Send(kHelloString, kHelloStringLength);
212*635a8641SAndroid Build Coastguard Worker   *received = socket->Receive(buf, length);
213*635a8641SAndroid Build Coastguard Worker }
214*635a8641SAndroid Build Coastguard Worker 
215*635a8641SAndroid Build Coastguard Worker // Tests that we can safely end a blocking Receive operation on one thread
216*635a8641SAndroid Build Coastguard Worker // from another thread by disconnecting (but not closing) the socket.
TEST_F(SyncSocketTest,DisconnectTest)217*635a8641SAndroid Build Coastguard Worker TEST_F(SyncSocketTest, DisconnectTest) {
218*635a8641SAndroid Build Coastguard Worker   base::CancelableSyncSocket pair[2];
219*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1]));
220*635a8641SAndroid Build Coastguard Worker 
221*635a8641SAndroid Build Coastguard Worker   base::Thread worker("BlockingThread");
222*635a8641SAndroid Build Coastguard Worker   worker.Start();
223*635a8641SAndroid Build Coastguard Worker 
224*635a8641SAndroid Build Coastguard Worker   // Try to do a blocking read from one of the sockets on the worker thread.
225*635a8641SAndroid Build Coastguard Worker   char buf[0xff];
226*635a8641SAndroid Build Coastguard Worker   size_t received = 1U;  // Initialize to an unexpected value.
227*635a8641SAndroid Build Coastguard Worker   worker.task_runner()->PostTask(
228*635a8641SAndroid Build Coastguard Worker       FROM_HERE,
229*635a8641SAndroid Build Coastguard Worker       base::Bind(&BlockingRead, &pair[0], &buf[0], arraysize(buf), &received));
230*635a8641SAndroid Build Coastguard Worker 
231*635a8641SAndroid Build Coastguard Worker   // Wait for the worker thread to say hello.
232*635a8641SAndroid Build Coastguard Worker   char hello[kHelloStringLength] = {0};
233*635a8641SAndroid Build Coastguard Worker   pair[1].Receive(&hello[0], sizeof(hello));
234*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, strcmp(hello, kHelloString));
235*635a8641SAndroid Build Coastguard Worker   // Give the worker a chance to start Receive().
236*635a8641SAndroid Build Coastguard Worker   base::PlatformThread::YieldCurrentThread();
237*635a8641SAndroid Build Coastguard Worker 
238*635a8641SAndroid Build Coastguard Worker   // Now shut down the socket that the thread is issuing a blocking read on
239*635a8641SAndroid Build Coastguard Worker   // which should cause Receive to return with an error.
240*635a8641SAndroid Build Coastguard Worker   pair[0].Shutdown();
241*635a8641SAndroid Build Coastguard Worker 
242*635a8641SAndroid Build Coastguard Worker   worker.Stop();
243*635a8641SAndroid Build Coastguard Worker 
244*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0U, received);
245*635a8641SAndroid Build Coastguard Worker }
246*635a8641SAndroid Build Coastguard Worker 
247*635a8641SAndroid Build Coastguard Worker // Tests that read is a blocking operation.
TEST_F(SyncSocketTest,BlockingReceiveTest)248*635a8641SAndroid Build Coastguard Worker TEST_F(SyncSocketTest, BlockingReceiveTest) {
249*635a8641SAndroid Build Coastguard Worker   base::CancelableSyncSocket pair[2];
250*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1]));
251*635a8641SAndroid Build Coastguard Worker 
252*635a8641SAndroid Build Coastguard Worker   base::Thread worker("BlockingThread");
253*635a8641SAndroid Build Coastguard Worker   worker.Start();
254*635a8641SAndroid Build Coastguard Worker 
255*635a8641SAndroid Build Coastguard Worker   // Try to do a blocking read from one of the sockets on the worker thread.
256*635a8641SAndroid Build Coastguard Worker   char buf[kHelloStringLength] = {0};
257*635a8641SAndroid Build Coastguard Worker   size_t received = 1U;  // Initialize to an unexpected value.
258*635a8641SAndroid Build Coastguard Worker   worker.task_runner()->PostTask(FROM_HERE,
259*635a8641SAndroid Build Coastguard Worker                                  base::Bind(&BlockingRead, &pair[0], &buf[0],
260*635a8641SAndroid Build Coastguard Worker                                             kHelloStringLength, &received));
261*635a8641SAndroid Build Coastguard Worker 
262*635a8641SAndroid Build Coastguard Worker   // Wait for the worker thread to say hello.
263*635a8641SAndroid Build Coastguard Worker   char hello[kHelloStringLength] = {0};
264*635a8641SAndroid Build Coastguard Worker   pair[1].Receive(&hello[0], sizeof(hello));
265*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, strcmp(hello, kHelloString));
266*635a8641SAndroid Build Coastguard Worker   // Give the worker a chance to start Receive().
267*635a8641SAndroid Build Coastguard Worker   base::PlatformThread::YieldCurrentThread();
268*635a8641SAndroid Build Coastguard Worker 
269*635a8641SAndroid Build Coastguard Worker   // Send a message to the socket on the blocking thead, it should free the
270*635a8641SAndroid Build Coastguard Worker   // socket from Receive().
271*635a8641SAndroid Build Coastguard Worker   pair[1].Send(kHelloString, kHelloStringLength);
272*635a8641SAndroid Build Coastguard Worker   worker.Stop();
273*635a8641SAndroid Build Coastguard Worker 
274*635a8641SAndroid Build Coastguard Worker   // Verify the socket has received the message.
275*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(strcmp(buf, kHelloString) == 0);
276*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kHelloStringLength, received);
277*635a8641SAndroid Build Coastguard Worker }
278*635a8641SAndroid Build Coastguard Worker 
279*635a8641SAndroid Build Coastguard Worker // Tests that the write operation is non-blocking and returns immediately
280*635a8641SAndroid Build Coastguard Worker // when there is insufficient space in the socket's buffer.
TEST_F(SyncSocketTest,NonBlockingWriteTest)281*635a8641SAndroid Build Coastguard Worker TEST_F(SyncSocketTest, NonBlockingWriteTest) {
282*635a8641SAndroid Build Coastguard Worker   base::CancelableSyncSocket pair[2];
283*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1]));
284*635a8641SAndroid Build Coastguard Worker 
285*635a8641SAndroid Build Coastguard Worker   // Fill up the buffer for one of the socket, Send() should not block the
286*635a8641SAndroid Build Coastguard Worker   // thread even when the buffer is full.
287*635a8641SAndroid Build Coastguard Worker   while (pair[0].Send(kHelloString, kHelloStringLength) != 0) {}
288*635a8641SAndroid Build Coastguard Worker 
289*635a8641SAndroid Build Coastguard Worker   // Data should be avialble on another socket.
290*635a8641SAndroid Build Coastguard Worker   size_t bytes_in_buffer = pair[1].Peek();
291*635a8641SAndroid Build Coastguard Worker   EXPECT_NE(bytes_in_buffer, 0U);
292*635a8641SAndroid Build Coastguard Worker 
293*635a8641SAndroid Build Coastguard Worker   // No more data can be written to the buffer since socket has been full,
294*635a8641SAndroid Build Coastguard Worker   // verify that the amount of avialble data on another socket is unchanged.
295*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0U, pair[0].Send(kHelloString, kHelloStringLength));
296*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(bytes_in_buffer, pair[1].Peek());
297*635a8641SAndroid Build Coastguard Worker 
298*635a8641SAndroid Build Coastguard Worker   // Read from another socket to free some space for a new write.
299*635a8641SAndroid Build Coastguard Worker   char hello[kHelloStringLength] = {0};
300*635a8641SAndroid Build Coastguard Worker   pair[1].Receive(&hello[0], sizeof(hello));
301*635a8641SAndroid Build Coastguard Worker 
302*635a8641SAndroid Build Coastguard Worker   // Should be able to write more data to the buffer now.
303*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kHelloStringLength, pair[0].Send(kHelloString, kHelloStringLength));
304*635a8641SAndroid Build Coastguard Worker }
305*635a8641SAndroid Build Coastguard Worker 
306*635a8641SAndroid Build Coastguard Worker }  // namespace
307