libuv-svace-build
185 строк · 4.8 Кб
1/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2*
3* Permission is hereby granted, free of charge, to any person obtaining a copy
4* of this software and associated documentation files (the "Software"), to
5* deal in the Software without restriction, including without limitation the
6* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7* sell copies of the Software, and to permit persons to whom the Software is
8* furnished to do so, subject to the following conditions:
9*
10* The above copyright notice and this permission notice shall be included in
11* all copies or substantial portions of the Software.
12*
13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19* IN THE SOFTWARE.
20*/
21
22#include "uv.h"23#include "task.h"24#include <stdio.h>25#include <stdlib.h>26
27
28#define WRITES 329#if defined(__arm__) /* Decrease the chunks so the test passes on arm CI bots */30#define CHUNKS_PER_WRITE 204831#else32#define CHUNKS_PER_WRITE 409633#endif34#define CHUNK_SIZE 10024 /* 10 kb */35
36#define TOTAL_BYTES (WRITES * CHUNKS_PER_WRITE * CHUNK_SIZE)37
38static char* send_buffer;39
40static int shutdown_cb_called = 0;41static int connect_cb_called = 0;42static int write_cb_called = 0;43static int close_cb_called = 0;44static size_t bytes_sent = 0;45static size_t bytes_sent_done = 0;46static size_t bytes_received_done = 0;47
48static uv_connect_t connect_req;49static uv_shutdown_t shutdown_req;50static uv_write_t write_reqs[WRITES];51
52
53static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {54buf->base = malloc(size);55buf->len = size;56}
57
58
59static void close_cb(uv_handle_t* handle) {60ASSERT_NOT_NULL(handle);61close_cb_called++;62}
63
64
65static void shutdown_cb(uv_shutdown_t* req, int status) {66uv_tcp_t* tcp;67
68ASSERT_PTR_EQ(req, &shutdown_req);69ASSERT_OK(status);70
71tcp = (uv_tcp_t*)(req->handle);72
73/* The write buffer should be empty by now. */74ASSERT_OK(tcp->write_queue_size);75
76/* Now we wait for the EOF */77shutdown_cb_called++;78
79/* We should have had all the writes called already. */80ASSERT_EQ(write_cb_called, WRITES);81}
82
83
84static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {85ASSERT_NOT_NULL(tcp);86
87if (nread >= 0) {88bytes_received_done += nread;89}90else {91ASSERT_EQ(nread, UV_EOF);92printf("GOT EOF\n");93uv_close((uv_handle_t*)tcp, close_cb);94}95
96free(buf->base);97}
98
99
100static void write_cb(uv_write_t* req, int status) {101ASSERT_NOT_NULL(req);102
103if (status) {104fprintf(stderr, "uv_write error: %s\n", uv_strerror(status));105ASSERT(0);106}107
108bytes_sent_done += CHUNKS_PER_WRITE * CHUNK_SIZE;109write_cb_called++;110}
111
112
113static void connect_cb(uv_connect_t* req, int status) {114uv_buf_t send_bufs[CHUNKS_PER_WRITE];115uv_stream_t* stream;116int i, j, r;117
118ASSERT_PTR_EQ(req, &connect_req);119ASSERT_OK(status);120
121stream = req->handle;122connect_cb_called++;123
124/* Write a lot of data */125for (i = 0; i < WRITES; i++) {126uv_write_t* write_req = write_reqs + i;127
128for (j = 0; j < CHUNKS_PER_WRITE; j++) {129send_bufs[j] = uv_buf_init(send_buffer + bytes_sent, CHUNK_SIZE);130bytes_sent += CHUNK_SIZE;131}132
133r = uv_write(write_req, stream, send_bufs, CHUNKS_PER_WRITE, write_cb);134ASSERT_OK(r);135}136
137/* Shutdown on drain. */138r = uv_shutdown(&shutdown_req, stream, shutdown_cb);139ASSERT_OK(r);140
141/* Start reading */142r = uv_read_start(stream, alloc_cb, read_cb);143ASSERT_OK(r);144}
145
146
147TEST_IMPL(tcp_writealot) {148struct sockaddr_in addr;149uv_tcp_t client;150int r;151
152#if defined(__MSAN__) || defined(__TSAN__)153RETURN_SKIP("Test is too slow to run under "154"MemorySanitizer or ThreadSanitizer");155#endif156
157ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));158
159send_buffer = calloc(1, TOTAL_BYTES);160ASSERT_NOT_NULL(send_buffer);161
162r = uv_tcp_init(uv_default_loop(), &client);163ASSERT_OK(r);164
165r = uv_tcp_connect(&connect_req,166&client,167(const struct sockaddr*) &addr,168connect_cb);169ASSERT_OK(r);170
171uv_run(uv_default_loop(), UV_RUN_DEFAULT);172
173ASSERT_EQ(1, shutdown_cb_called);174ASSERT_EQ(1, connect_cb_called);175ASSERT_EQ(write_cb_called, WRITES);176ASSERT_EQ(1, close_cb_called);177ASSERT_EQ(bytes_sent, TOTAL_BYTES);178ASSERT_EQ(bytes_sent_done, TOTAL_BYTES);179ASSERT_EQ(bytes_received_done, TOTAL_BYTES);180
181free(send_buffer);182
183MAKE_VALGRIND_HAPPY(uv_default_loop());184return 0;185}
186