xref: /third_party/libuv/test/test-tcp-open.c (revision e66f31c5)
1e66f31c5Sopenharmony_ci/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2e66f31c5Sopenharmony_ci *
3e66f31c5Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy
4e66f31c5Sopenharmony_ci * of this software and associated documentation files (the "Software"), to
5e66f31c5Sopenharmony_ci * deal in the Software without restriction, including without limitation the
6e66f31c5Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7e66f31c5Sopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is
8e66f31c5Sopenharmony_ci * furnished to do so, subject to the following conditions:
9e66f31c5Sopenharmony_ci *
10e66f31c5Sopenharmony_ci * The above copyright notice and this permission notice shall be included in
11e66f31c5Sopenharmony_ci * all copies or substantial portions of the Software.
12e66f31c5Sopenharmony_ci *
13e66f31c5Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14e66f31c5Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15e66f31c5Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16e66f31c5Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17e66f31c5Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18e66f31c5Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19e66f31c5Sopenharmony_ci * IN THE SOFTWARE.
20e66f31c5Sopenharmony_ci */
21e66f31c5Sopenharmony_ci
22e66f31c5Sopenharmony_ci#include "uv.h"
23e66f31c5Sopenharmony_ci#include "task.h"
24e66f31c5Sopenharmony_ci#include <stdio.h>
25e66f31c5Sopenharmony_ci#include <stdlib.h>
26e66f31c5Sopenharmony_ci#include <string.h>
27e66f31c5Sopenharmony_ci
28e66f31c5Sopenharmony_ci#ifndef _WIN32
29e66f31c5Sopenharmony_ci# include <unistd.h>
30e66f31c5Sopenharmony_ci#endif
31e66f31c5Sopenharmony_ci
32e66f31c5Sopenharmony_cistatic int shutdown_cb_called = 0;
33e66f31c5Sopenharmony_cistatic int shutdown_requested = 0;
34e66f31c5Sopenharmony_cistatic int connect_cb_called = 0;
35e66f31c5Sopenharmony_cistatic int write_cb_called = 0;
36e66f31c5Sopenharmony_cistatic int close_cb_called = 0;
37e66f31c5Sopenharmony_ci
38e66f31c5Sopenharmony_cistatic uv_connect_t connect_req;
39e66f31c5Sopenharmony_cistatic uv_shutdown_t shutdown_req;
40e66f31c5Sopenharmony_cistatic uv_write_t write_req;
41e66f31c5Sopenharmony_cistatic uv_timer_t tm;
42e66f31c5Sopenharmony_cistatic uv_tcp_t client;
43e66f31c5Sopenharmony_ci
44e66f31c5Sopenharmony_ci
45e66f31c5Sopenharmony_cistatic void startup(void) {
46e66f31c5Sopenharmony_ci#ifdef _WIN32
47e66f31c5Sopenharmony_ci    struct WSAData wsa_data;
48e66f31c5Sopenharmony_ci    int r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
49e66f31c5Sopenharmony_ci    ASSERT_OK(r);
50e66f31c5Sopenharmony_ci#endif
51e66f31c5Sopenharmony_ci}
52e66f31c5Sopenharmony_ci
53e66f31c5Sopenharmony_ci
54e66f31c5Sopenharmony_cistatic uv_os_sock_t create_tcp_socket(void) {
55e66f31c5Sopenharmony_ci  uv_os_sock_t sock;
56e66f31c5Sopenharmony_ci
57e66f31c5Sopenharmony_ci  sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
58e66f31c5Sopenharmony_ci#ifdef _WIN32
59e66f31c5Sopenharmony_ci  ASSERT_NE(sock, INVALID_SOCKET);
60e66f31c5Sopenharmony_ci#else
61e66f31c5Sopenharmony_ci  ASSERT_GE(sock, 0);
62e66f31c5Sopenharmony_ci#endif
63e66f31c5Sopenharmony_ci
64e66f31c5Sopenharmony_ci#ifndef _WIN32
65e66f31c5Sopenharmony_ci  {
66e66f31c5Sopenharmony_ci    /* Allow reuse of the port. */
67e66f31c5Sopenharmony_ci    int yes = 1;
68e66f31c5Sopenharmony_ci    int r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
69e66f31c5Sopenharmony_ci    ASSERT_OK(r);
70e66f31c5Sopenharmony_ci  }
71e66f31c5Sopenharmony_ci#endif
72e66f31c5Sopenharmony_ci
73e66f31c5Sopenharmony_ci  return sock;
74e66f31c5Sopenharmony_ci}
75e66f31c5Sopenharmony_ci
76e66f31c5Sopenharmony_ci
77e66f31c5Sopenharmony_cistatic void close_socket(uv_os_sock_t sock) {
78e66f31c5Sopenharmony_ci  int r;
79e66f31c5Sopenharmony_ci#ifdef _WIN32
80e66f31c5Sopenharmony_ci  r = closesocket(sock);
81e66f31c5Sopenharmony_ci#else
82e66f31c5Sopenharmony_ci  r = close(sock);
83e66f31c5Sopenharmony_ci#endif
84e66f31c5Sopenharmony_ci  ASSERT_OK(r);
85e66f31c5Sopenharmony_ci}
86e66f31c5Sopenharmony_ci
87e66f31c5Sopenharmony_ci
88e66f31c5Sopenharmony_cistatic void alloc_cb(uv_handle_t* handle,
89e66f31c5Sopenharmony_ci                     size_t suggested_size,
90e66f31c5Sopenharmony_ci                     uv_buf_t* buf) {
91e66f31c5Sopenharmony_ci  static char slab[65536];
92e66f31c5Sopenharmony_ci  ASSERT_LE(suggested_size, sizeof(slab));
93e66f31c5Sopenharmony_ci  buf->base = slab;
94e66f31c5Sopenharmony_ci  buf->len = sizeof(slab);
95e66f31c5Sopenharmony_ci}
96e66f31c5Sopenharmony_ci
97e66f31c5Sopenharmony_ci
98e66f31c5Sopenharmony_cistatic void close_cb(uv_handle_t* handle) {
99e66f31c5Sopenharmony_ci  ASSERT_NOT_NULL(handle);
100e66f31c5Sopenharmony_ci  close_cb_called++;
101e66f31c5Sopenharmony_ci}
102e66f31c5Sopenharmony_ci
103e66f31c5Sopenharmony_ci
104e66f31c5Sopenharmony_cistatic void shutdown_cb(uv_shutdown_t* req, int status) {
105e66f31c5Sopenharmony_ci  ASSERT_PTR_EQ(req, &shutdown_req);
106e66f31c5Sopenharmony_ci  ASSERT_OK(status);
107e66f31c5Sopenharmony_ci
108e66f31c5Sopenharmony_ci  /* Now we wait for the EOF */
109e66f31c5Sopenharmony_ci  shutdown_cb_called++;
110e66f31c5Sopenharmony_ci}
111e66f31c5Sopenharmony_ci
112e66f31c5Sopenharmony_ci
113e66f31c5Sopenharmony_cistatic void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
114e66f31c5Sopenharmony_ci  ASSERT_NOT_NULL(tcp);
115e66f31c5Sopenharmony_ci
116e66f31c5Sopenharmony_ci  if (nread >= 0) {
117e66f31c5Sopenharmony_ci    ASSERT_EQ(4, nread);
118e66f31c5Sopenharmony_ci    ASSERT_OK(memcmp("PING", buf->base, nread));
119e66f31c5Sopenharmony_ci  }
120e66f31c5Sopenharmony_ci  else {
121e66f31c5Sopenharmony_ci    ASSERT_EQ(nread, UV_EOF);
122e66f31c5Sopenharmony_ci    uv_close((uv_handle_t*)tcp, close_cb);
123e66f31c5Sopenharmony_ci  }
124e66f31c5Sopenharmony_ci}
125e66f31c5Sopenharmony_ci
126e66f31c5Sopenharmony_ci
127e66f31c5Sopenharmony_cistatic void read1_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
128e66f31c5Sopenharmony_ci  int i;
129e66f31c5Sopenharmony_ci  ASSERT_NOT_NULL(tcp);
130e66f31c5Sopenharmony_ci
131e66f31c5Sopenharmony_ci  if (nread >= 0) {
132e66f31c5Sopenharmony_ci    for (i = 0; i < nread; ++i)
133e66f31c5Sopenharmony_ci      ASSERT_EQ(buf->base[i], 'P');
134e66f31c5Sopenharmony_ci  } else {
135e66f31c5Sopenharmony_ci    ASSERT_EQ(nread, UV_EOF);
136e66f31c5Sopenharmony_ci    printf("GOT EOF\n");
137e66f31c5Sopenharmony_ci    uv_close((uv_handle_t*)tcp, close_cb);
138e66f31c5Sopenharmony_ci  }
139e66f31c5Sopenharmony_ci}
140e66f31c5Sopenharmony_ci
141e66f31c5Sopenharmony_ci
142e66f31c5Sopenharmony_cistatic void write_cb(uv_write_t* req, int status) {
143e66f31c5Sopenharmony_ci  ASSERT_NOT_NULL(req);
144e66f31c5Sopenharmony_ci
145e66f31c5Sopenharmony_ci  if (status) {
146e66f31c5Sopenharmony_ci    fprintf(stderr, "uv_write error: %s\n", uv_strerror(status));
147e66f31c5Sopenharmony_ci    ASSERT(0);
148e66f31c5Sopenharmony_ci  }
149e66f31c5Sopenharmony_ci
150e66f31c5Sopenharmony_ci  write_cb_called++;
151e66f31c5Sopenharmony_ci}
152e66f31c5Sopenharmony_ci
153e66f31c5Sopenharmony_ci
154e66f31c5Sopenharmony_cistatic void write1_cb(uv_write_t* req, int status) {
155e66f31c5Sopenharmony_ci  uv_buf_t buf;
156e66f31c5Sopenharmony_ci  int r;
157e66f31c5Sopenharmony_ci
158e66f31c5Sopenharmony_ci  ASSERT_NOT_NULL(req);
159e66f31c5Sopenharmony_ci  if (status) {
160e66f31c5Sopenharmony_ci    ASSERT(shutdown_cb_called);
161e66f31c5Sopenharmony_ci    return;
162e66f31c5Sopenharmony_ci  }
163e66f31c5Sopenharmony_ci
164e66f31c5Sopenharmony_ci  if (shutdown_requested)
165e66f31c5Sopenharmony_ci    return;
166e66f31c5Sopenharmony_ci
167e66f31c5Sopenharmony_ci  buf = uv_buf_init("P", 1);
168e66f31c5Sopenharmony_ci  r = uv_write(&write_req, req->handle, &buf, 1, write1_cb);
169e66f31c5Sopenharmony_ci  ASSERT_OK(r);
170e66f31c5Sopenharmony_ci
171e66f31c5Sopenharmony_ci  write_cb_called++;
172e66f31c5Sopenharmony_ci}
173e66f31c5Sopenharmony_ci
174e66f31c5Sopenharmony_ci
175e66f31c5Sopenharmony_cistatic void timer_cb(uv_timer_t* handle) {
176e66f31c5Sopenharmony_ci  int r;
177e66f31c5Sopenharmony_ci
178e66f31c5Sopenharmony_ci  /* Shutdown on drain. */
179e66f31c5Sopenharmony_ci  r = uv_shutdown(&shutdown_req, (uv_stream_t*) &client, shutdown_cb);
180e66f31c5Sopenharmony_ci  ASSERT_OK(r);
181e66f31c5Sopenharmony_ci  shutdown_requested++;
182e66f31c5Sopenharmony_ci}
183e66f31c5Sopenharmony_ci
184e66f31c5Sopenharmony_ci
185e66f31c5Sopenharmony_cistatic void connect_cb(uv_connect_t* req, int status) {
186e66f31c5Sopenharmony_ci  uv_buf_t buf = uv_buf_init("PING", 4);
187e66f31c5Sopenharmony_ci  uv_stream_t* stream;
188e66f31c5Sopenharmony_ci  int r;
189e66f31c5Sopenharmony_ci
190e66f31c5Sopenharmony_ci  ASSERT_PTR_EQ(req, &connect_req);
191e66f31c5Sopenharmony_ci  ASSERT_OK(status);
192e66f31c5Sopenharmony_ci
193e66f31c5Sopenharmony_ci  stream = req->handle;
194e66f31c5Sopenharmony_ci  connect_cb_called++;
195e66f31c5Sopenharmony_ci
196e66f31c5Sopenharmony_ci  r = uv_write(&write_req, stream, &buf, 1, write_cb);
197e66f31c5Sopenharmony_ci  ASSERT_OK(r);
198e66f31c5Sopenharmony_ci
199e66f31c5Sopenharmony_ci  /* Shutdown on drain. */
200e66f31c5Sopenharmony_ci  r = uv_shutdown(&shutdown_req, stream, shutdown_cb);
201e66f31c5Sopenharmony_ci  ASSERT_OK(r);
202e66f31c5Sopenharmony_ci
203e66f31c5Sopenharmony_ci  /* Start reading */
204e66f31c5Sopenharmony_ci  r = uv_read_start(stream, alloc_cb, read_cb);
205e66f31c5Sopenharmony_ci  ASSERT_OK(r);
206e66f31c5Sopenharmony_ci}
207e66f31c5Sopenharmony_ci
208e66f31c5Sopenharmony_ci
209e66f31c5Sopenharmony_cistatic void connect1_cb(uv_connect_t* req, int status) {
210e66f31c5Sopenharmony_ci  uv_buf_t buf;
211e66f31c5Sopenharmony_ci  uv_stream_t* stream;
212e66f31c5Sopenharmony_ci  int r;
213e66f31c5Sopenharmony_ci
214e66f31c5Sopenharmony_ci  ASSERT_PTR_EQ(req, &connect_req);
215e66f31c5Sopenharmony_ci  ASSERT_OK(status);
216e66f31c5Sopenharmony_ci
217e66f31c5Sopenharmony_ci  stream = req->handle;
218e66f31c5Sopenharmony_ci  connect_cb_called++;
219e66f31c5Sopenharmony_ci
220e66f31c5Sopenharmony_ci  r = uv_timer_init(uv_default_loop(), &tm);
221e66f31c5Sopenharmony_ci  ASSERT_OK(r);
222e66f31c5Sopenharmony_ci
223e66f31c5Sopenharmony_ci  r = uv_timer_start(&tm, timer_cb, 2000, 0);
224e66f31c5Sopenharmony_ci  ASSERT_OK(r);
225e66f31c5Sopenharmony_ci
226e66f31c5Sopenharmony_ci  buf = uv_buf_init("P", 1);
227e66f31c5Sopenharmony_ci  r = uv_write(&write_req, stream, &buf, 1, write1_cb);
228e66f31c5Sopenharmony_ci  ASSERT_OK(r);
229e66f31c5Sopenharmony_ci
230e66f31c5Sopenharmony_ci  /* Start reading */
231e66f31c5Sopenharmony_ci  r = uv_read_start(stream, alloc_cb, read1_cb);
232e66f31c5Sopenharmony_ci  ASSERT_OK(r);
233e66f31c5Sopenharmony_ci}
234e66f31c5Sopenharmony_ci
235e66f31c5Sopenharmony_ci
236e66f31c5Sopenharmony_ciTEST_IMPL(tcp_open) {
237e66f31c5Sopenharmony_ci  struct sockaddr_in addr;
238e66f31c5Sopenharmony_ci  uv_os_sock_t sock;
239e66f31c5Sopenharmony_ci  int r;
240e66f31c5Sopenharmony_ci  uv_tcp_t client2;
241e66f31c5Sopenharmony_ci
242e66f31c5Sopenharmony_ci  ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
243e66f31c5Sopenharmony_ci
244e66f31c5Sopenharmony_ci  startup();
245e66f31c5Sopenharmony_ci  sock = create_tcp_socket();
246e66f31c5Sopenharmony_ci
247e66f31c5Sopenharmony_ci  r = uv_tcp_init(uv_default_loop(), &client);
248e66f31c5Sopenharmony_ci  ASSERT_OK(r);
249e66f31c5Sopenharmony_ci
250e66f31c5Sopenharmony_ci  r = uv_tcp_open(&client, sock);
251e66f31c5Sopenharmony_ci  ASSERT_OK(r);
252e66f31c5Sopenharmony_ci
253e66f31c5Sopenharmony_ci  r = uv_tcp_connect(&connect_req,
254e66f31c5Sopenharmony_ci                     &client,
255e66f31c5Sopenharmony_ci                     (const struct sockaddr*) &addr,
256e66f31c5Sopenharmony_ci                     connect_cb);
257e66f31c5Sopenharmony_ci  ASSERT_OK(r);
258e66f31c5Sopenharmony_ci
259e66f31c5Sopenharmony_ci#ifndef _WIN32
260e66f31c5Sopenharmony_ci  {
261e66f31c5Sopenharmony_ci    r = uv_tcp_init(uv_default_loop(), &client2);
262e66f31c5Sopenharmony_ci    ASSERT_OK(r);
263e66f31c5Sopenharmony_ci
264e66f31c5Sopenharmony_ci    r = uv_tcp_open(&client2, sock);
265e66f31c5Sopenharmony_ci    ASSERT_EQ(r, UV_EEXIST);
266e66f31c5Sopenharmony_ci
267e66f31c5Sopenharmony_ci    uv_close((uv_handle_t*) &client2, NULL);
268e66f31c5Sopenharmony_ci  }
269e66f31c5Sopenharmony_ci#else  /* _WIN32 */
270e66f31c5Sopenharmony_ci  (void)client2;
271e66f31c5Sopenharmony_ci#endif
272e66f31c5Sopenharmony_ci
273e66f31c5Sopenharmony_ci  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
274e66f31c5Sopenharmony_ci
275e66f31c5Sopenharmony_ci  ASSERT_EQ(1, shutdown_cb_called);
276e66f31c5Sopenharmony_ci  ASSERT_EQ(1, connect_cb_called);
277e66f31c5Sopenharmony_ci  ASSERT_EQ(1, write_cb_called);
278e66f31c5Sopenharmony_ci  ASSERT_EQ(1, close_cb_called);
279e66f31c5Sopenharmony_ci
280e66f31c5Sopenharmony_ci  MAKE_VALGRIND_HAPPY(uv_default_loop());
281e66f31c5Sopenharmony_ci  return 0;
282e66f31c5Sopenharmony_ci}
283e66f31c5Sopenharmony_ci
284e66f31c5Sopenharmony_ci
285e66f31c5Sopenharmony_ciTEST_IMPL(tcp_open_twice) {
286e66f31c5Sopenharmony_ci  uv_tcp_t client;
287e66f31c5Sopenharmony_ci  uv_os_sock_t sock1, sock2;
288e66f31c5Sopenharmony_ci  int r;
289e66f31c5Sopenharmony_ci
290e66f31c5Sopenharmony_ci  startup();
291e66f31c5Sopenharmony_ci  sock1 = create_tcp_socket();
292e66f31c5Sopenharmony_ci  sock2 = create_tcp_socket();
293e66f31c5Sopenharmony_ci
294e66f31c5Sopenharmony_ci  r = uv_tcp_init(uv_default_loop(), &client);
295e66f31c5Sopenharmony_ci  ASSERT_OK(r);
296e66f31c5Sopenharmony_ci
297e66f31c5Sopenharmony_ci  r = uv_tcp_open(&client, sock1);
298e66f31c5Sopenharmony_ci  ASSERT_OK(r);
299e66f31c5Sopenharmony_ci
300e66f31c5Sopenharmony_ci  r = uv_tcp_open(&client, sock2);
301e66f31c5Sopenharmony_ci  ASSERT_EQ(r, UV_EBUSY);
302e66f31c5Sopenharmony_ci  close_socket(sock2);
303e66f31c5Sopenharmony_ci
304e66f31c5Sopenharmony_ci  uv_close((uv_handle_t*) &client, NULL);
305e66f31c5Sopenharmony_ci  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
306e66f31c5Sopenharmony_ci
307e66f31c5Sopenharmony_ci  MAKE_VALGRIND_HAPPY(uv_default_loop());
308e66f31c5Sopenharmony_ci  return 0;
309e66f31c5Sopenharmony_ci}
310e66f31c5Sopenharmony_ci
311e66f31c5Sopenharmony_ci
312e66f31c5Sopenharmony_ciTEST_IMPL(tcp_open_bound) {
313e66f31c5Sopenharmony_ci  struct sockaddr_in addr;
314e66f31c5Sopenharmony_ci  uv_tcp_t server;
315e66f31c5Sopenharmony_ci  uv_os_sock_t sock;
316e66f31c5Sopenharmony_ci
317e66f31c5Sopenharmony_ci  startup();
318e66f31c5Sopenharmony_ci  sock = create_tcp_socket();
319e66f31c5Sopenharmony_ci
320e66f31c5Sopenharmony_ci  ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
321e66f31c5Sopenharmony_ci
322e66f31c5Sopenharmony_ci  ASSERT_OK(uv_tcp_init(uv_default_loop(), &server));
323e66f31c5Sopenharmony_ci
324e66f31c5Sopenharmony_ci  ASSERT_OK(bind(sock, (struct sockaddr*) &addr, sizeof(addr)));
325e66f31c5Sopenharmony_ci
326e66f31c5Sopenharmony_ci  ASSERT_OK(uv_tcp_open(&server, sock));
327e66f31c5Sopenharmony_ci
328e66f31c5Sopenharmony_ci  ASSERT_OK(uv_listen((uv_stream_t*) &server, 128, NULL));
329e66f31c5Sopenharmony_ci
330e66f31c5Sopenharmony_ci  MAKE_VALGRIND_HAPPY(uv_default_loop());
331e66f31c5Sopenharmony_ci  return 0;
332e66f31c5Sopenharmony_ci}
333e66f31c5Sopenharmony_ci
334e66f31c5Sopenharmony_ci
335e66f31c5Sopenharmony_ciTEST_IMPL(tcp_open_connected) {
336e66f31c5Sopenharmony_ci  struct sockaddr_in addr;
337e66f31c5Sopenharmony_ci  uv_tcp_t client;
338e66f31c5Sopenharmony_ci  uv_os_sock_t sock;
339e66f31c5Sopenharmony_ci  uv_buf_t buf = uv_buf_init("PING", 4);
340e66f31c5Sopenharmony_ci
341e66f31c5Sopenharmony_ci  ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
342e66f31c5Sopenharmony_ci
343e66f31c5Sopenharmony_ci  startup();
344e66f31c5Sopenharmony_ci  sock = create_tcp_socket();
345e66f31c5Sopenharmony_ci
346e66f31c5Sopenharmony_ci  ASSERT_OK(connect(sock, (struct sockaddr*) &addr,  sizeof(addr)));
347e66f31c5Sopenharmony_ci
348e66f31c5Sopenharmony_ci  ASSERT_OK(uv_tcp_init(uv_default_loop(), &client));
349e66f31c5Sopenharmony_ci
350e66f31c5Sopenharmony_ci  ASSERT_OK(uv_tcp_open(&client, sock));
351e66f31c5Sopenharmony_ci
352e66f31c5Sopenharmony_ci  ASSERT_OK(uv_write(&write_req,
353e66f31c5Sopenharmony_ci                     (uv_stream_t*) &client,
354e66f31c5Sopenharmony_ci                     &buf,
355e66f31c5Sopenharmony_ci                     1,
356e66f31c5Sopenharmony_ci                     write_cb));
357e66f31c5Sopenharmony_ci
358e66f31c5Sopenharmony_ci  ASSERT_OK(uv_shutdown(&shutdown_req,
359e66f31c5Sopenharmony_ci                        (uv_stream_t*) &client,
360e66f31c5Sopenharmony_ci                        shutdown_cb));
361e66f31c5Sopenharmony_ci
362e66f31c5Sopenharmony_ci  ASSERT_OK(uv_read_start((uv_stream_t*) &client, alloc_cb, read_cb));
363e66f31c5Sopenharmony_ci
364e66f31c5Sopenharmony_ci  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
365e66f31c5Sopenharmony_ci
366e66f31c5Sopenharmony_ci  ASSERT_EQ(1, shutdown_cb_called);
367e66f31c5Sopenharmony_ci  ASSERT_EQ(1, write_cb_called);
368e66f31c5Sopenharmony_ci  ASSERT_EQ(1, close_cb_called);
369e66f31c5Sopenharmony_ci
370e66f31c5Sopenharmony_ci  MAKE_VALGRIND_HAPPY(uv_default_loop());
371e66f31c5Sopenharmony_ci  return 0;
372e66f31c5Sopenharmony_ci}
373e66f31c5Sopenharmony_ci
374e66f31c5Sopenharmony_ci
375e66f31c5Sopenharmony_ciTEST_IMPL(tcp_write_ready) {
376e66f31c5Sopenharmony_ci  struct sockaddr_in addr;
377e66f31c5Sopenharmony_ci  uv_os_sock_t sock;
378e66f31c5Sopenharmony_ci  int r;
379e66f31c5Sopenharmony_ci
380e66f31c5Sopenharmony_ci  ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
381e66f31c5Sopenharmony_ci
382e66f31c5Sopenharmony_ci  startup();
383e66f31c5Sopenharmony_ci  sock = create_tcp_socket();
384e66f31c5Sopenharmony_ci
385e66f31c5Sopenharmony_ci  r = uv_tcp_init(uv_default_loop(), &client);
386e66f31c5Sopenharmony_ci  ASSERT_OK(r);
387e66f31c5Sopenharmony_ci
388e66f31c5Sopenharmony_ci  r = uv_tcp_open(&client, sock);
389e66f31c5Sopenharmony_ci  ASSERT_OK(r);
390e66f31c5Sopenharmony_ci
391e66f31c5Sopenharmony_ci  r = uv_tcp_connect(&connect_req,
392e66f31c5Sopenharmony_ci                     &client,
393e66f31c5Sopenharmony_ci                     (const struct sockaddr*) &addr,
394e66f31c5Sopenharmony_ci                     connect1_cb);
395e66f31c5Sopenharmony_ci  ASSERT_OK(r);
396e66f31c5Sopenharmony_ci
397e66f31c5Sopenharmony_ci  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
398e66f31c5Sopenharmony_ci
399e66f31c5Sopenharmony_ci  ASSERT_EQ(1, shutdown_cb_called);
400e66f31c5Sopenharmony_ci  ASSERT_EQ(1, shutdown_requested);
401e66f31c5Sopenharmony_ci  ASSERT_EQ(1, connect_cb_called);
402e66f31c5Sopenharmony_ci  ASSERT_GT(write_cb_called, 0);
403e66f31c5Sopenharmony_ci  ASSERT_EQ(1, close_cb_called);
404e66f31c5Sopenharmony_ci
405e66f31c5Sopenharmony_ci  MAKE_VALGRIND_HAPPY(uv_default_loop());
406e66f31c5Sopenharmony_ci  return 0;
407e66f31c5Sopenharmony_ci}
408