1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/third_party/libevent/test/regress_zlib.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,345 @@ 1.4 +/* 1.5 + * Copyright (c) 2008-2012 Niels Provos and Nick Mathewson 1.6 + * 1.7 + * Redistribution and use in source and binary forms, with or without 1.8 + * modification, are permitted provided that the following conditions 1.9 + * are met: 1.10 + * 1. Redistributions of source code must retain the above copyright 1.11 + * notice, this list of conditions and the following disclaimer. 1.12 + * 2. Redistributions in binary form must reproduce the above copyright 1.13 + * notice, this list of conditions and the following disclaimer in the 1.14 + * documentation and/or other materials provided with the distribution. 1.15 + * 3. The name of the author may not be used to endorse or promote products 1.16 + * derived from this software without specific prior written permission. 1.17 + * 1.18 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1.19 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1.20 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1.21 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1.22 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1.23 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.24 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.25 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.26 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 1.27 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.28 + */ 1.29 + 1.30 +/* The old tests here need assertions to work. */ 1.31 +#undef NDEBUG 1.32 + 1.33 +#ifdef WIN32 1.34 +#include <winsock2.h> 1.35 +#include <windows.h> 1.36 +#endif 1.37 + 1.38 +#include "event2/event-config.h" 1.39 + 1.40 +#include <sys/types.h> 1.41 +#ifndef WIN32 1.42 +#include <sys/socket.h> 1.43 +#include <sys/wait.h> 1.44 +#include <unistd.h> 1.45 +#include <netdb.h> 1.46 +#endif 1.47 +#include <signal.h> 1.48 +#include <stdio.h> 1.49 +#include <stdlib.h> 1.50 +#include <string.h> 1.51 + 1.52 +#include <assert.h> 1.53 +#include <errno.h> 1.54 + 1.55 +#include "event2/util.h" 1.56 +#include "event2/event.h" 1.57 +#include "event2/event_compat.h" 1.58 +#include "event2/buffer.h" 1.59 +#include "event2/bufferevent.h" 1.60 + 1.61 +#include "regress.h" 1.62 + 1.63 +/* zlib 1.2.4 and 1.2.5 do some "clever" things with macros. Instead of 1.64 + saying "(defined(FOO) ? FOO : 0)" they like to say "FOO-0", on the theory 1.65 + that nobody will care if the compile outputs a no-such-identifier warning. 1.66 + 1.67 + Sorry, but we like -Werror over here, so I guess we need to define these. 1.68 + I hope that zlib 1.2.6 doesn't break these too. 1.69 +*/ 1.70 +#ifndef _LARGEFILE64_SOURCE 1.71 +#define _LARGEFILE64_SOURCE 0 1.72 +#endif 1.73 +#ifndef _LFS64_LARGEFILE 1.74 +#define _LFS64_LARGEFILE 0 1.75 +#endif 1.76 +#ifndef _FILE_OFFSET_BITS 1.77 +#define _FILE_OFFSET_BITS 0 1.78 +#endif 1.79 +#ifndef off64_t 1.80 +#define off64_t ev_int64_t 1.81 +#endif 1.82 + 1.83 +#include <zlib.h> 1.84 + 1.85 +static int infilter_calls; 1.86 +static int outfilter_calls; 1.87 +static int readcb_finished; 1.88 +static int writecb_finished; 1.89 +static int errorcb_invoked; 1.90 + 1.91 +/* 1.92 + * Zlib filters 1.93 + */ 1.94 + 1.95 +static void 1.96 +zlib_deflate_free(void *ctx) 1.97 +{ 1.98 + z_streamp p = ctx; 1.99 + 1.100 + assert(deflateEnd(p) == Z_OK); 1.101 +} 1.102 + 1.103 +static void 1.104 +zlib_inflate_free(void *ctx) 1.105 +{ 1.106 + z_streamp p = ctx; 1.107 + 1.108 + assert(inflateEnd(p) == Z_OK); 1.109 +} 1.110 + 1.111 +static int 1.112 +getstate(enum bufferevent_flush_mode state) 1.113 +{ 1.114 + switch (state) { 1.115 + case BEV_FINISHED: 1.116 + return Z_FINISH; 1.117 + case BEV_FLUSH: 1.118 + return Z_SYNC_FLUSH; 1.119 + case BEV_NORMAL: 1.120 + default: 1.121 + return Z_NO_FLUSH; 1.122 + } 1.123 +} 1.124 + 1.125 +/* 1.126 + * The input filter is triggered only on new input read from the network. 1.127 + * That means all input data needs to be consumed or the filter needs to 1.128 + * initiate its own triggering via a timeout. 1.129 + */ 1.130 +static enum bufferevent_filter_result 1.131 +zlib_input_filter(struct evbuffer *src, struct evbuffer *dst, 1.132 + ev_ssize_t lim, enum bufferevent_flush_mode state, void *ctx) 1.133 +{ 1.134 + struct evbuffer_iovec v_in[1]; 1.135 + struct evbuffer_iovec v_out[1]; 1.136 + int nread, nwrite; 1.137 + int res, n; 1.138 + 1.139 + z_streamp p = ctx; 1.140 + 1.141 + do { 1.142 + /* let's do some decompression */ 1.143 + n = evbuffer_peek(src, -1, NULL, v_in, 1); 1.144 + if (n) { 1.145 + p->avail_in = v_in[0].iov_len; 1.146 + p->next_in = v_in[0].iov_base; 1.147 + } else { 1.148 + p->avail_in = 0; 1.149 + p->next_in = 0; 1.150 + } 1.151 + 1.152 + evbuffer_reserve_space(dst, 4096, v_out, 1); 1.153 + p->next_out = v_out[0].iov_base; 1.154 + p->avail_out = v_out[0].iov_len; 1.155 + 1.156 + /* we need to flush zlib if we got a flush */ 1.157 + res = inflate(p, getstate(state)); 1.158 + 1.159 + /* let's figure out how much was compressed */ 1.160 + nread = v_in[0].iov_len - p->avail_in; 1.161 + nwrite = v_out[0].iov_len - p->avail_out; 1.162 + 1.163 + evbuffer_drain(src, nread); 1.164 + v_out[0].iov_len = nwrite; 1.165 + evbuffer_commit_space(dst, v_out, 1); 1.166 + 1.167 + if (res==Z_BUF_ERROR) { 1.168 + /* We're out of space, or out of decodeable input. 1.169 + Only if nwrite == 0 assume the latter. 1.170 + */ 1.171 + if (nwrite == 0) 1.172 + return BEV_NEED_MORE; 1.173 + } else { 1.174 + assert(res == Z_OK || res == Z_STREAM_END); 1.175 + } 1.176 + 1.177 + } while (evbuffer_get_length(src) > 0); 1.178 + 1.179 + ++infilter_calls; 1.180 + 1.181 + return (BEV_OK); 1.182 +} 1.183 + 1.184 +static enum bufferevent_filter_result 1.185 +zlib_output_filter(struct evbuffer *src, struct evbuffer *dst, 1.186 + ev_ssize_t lim, enum bufferevent_flush_mode state, void *ctx) 1.187 +{ 1.188 + struct evbuffer_iovec v_in[1]; 1.189 + struct evbuffer_iovec v_out[1]; 1.190 + int nread, nwrite; 1.191 + int res, n; 1.192 + 1.193 + z_streamp p = ctx; 1.194 + 1.195 + do { 1.196 + /* let's do some compression */ 1.197 + n = evbuffer_peek(src, -1, NULL, v_in, 1); 1.198 + if (n) { 1.199 + p->avail_in = v_in[0].iov_len; 1.200 + p->next_in = v_in[0].iov_base; 1.201 + } else { 1.202 + p->avail_in = 0; 1.203 + p->next_in = 0; 1.204 + } 1.205 + 1.206 + evbuffer_reserve_space(dst, 4096, v_out, 1); 1.207 + p->next_out = v_out[0].iov_base; 1.208 + p->avail_out = v_out[0].iov_len; 1.209 + 1.210 + /* we need to flush zlib if we got a flush */ 1.211 + res = deflate(p, getstate(state)); 1.212 + 1.213 + /* let's figure out how much was decompressed */ 1.214 + nread = v_in[0].iov_len - p->avail_in; 1.215 + nwrite = v_out[0].iov_len - p->avail_out; 1.216 + 1.217 + evbuffer_drain(src, nread); 1.218 + v_out[0].iov_len = nwrite; 1.219 + evbuffer_commit_space(dst, v_out, 1); 1.220 + 1.221 + if (res==Z_BUF_ERROR) { 1.222 + /* We're out of space, or out of decodeable input. 1.223 + Only if nwrite == 0 assume the latter. 1.224 + */ 1.225 + if (nwrite == 0) 1.226 + return BEV_NEED_MORE; 1.227 + } else { 1.228 + assert(res == Z_OK || res == Z_STREAM_END); 1.229 + } 1.230 + 1.231 + } while (evbuffer_get_length(src) > 0); 1.232 + 1.233 + ++outfilter_calls; 1.234 + 1.235 + return (BEV_OK); 1.236 +} 1.237 + 1.238 +/* 1.239 + * simple bufferevent test (over transparent zlib treatment) 1.240 + */ 1.241 + 1.242 +static void 1.243 +readcb(struct bufferevent *bev, void *arg) 1.244 +{ 1.245 + if (evbuffer_get_length(bufferevent_get_input(bev)) == 8333) { 1.246 + struct evbuffer *evbuf = evbuffer_new(); 1.247 + assert(evbuf != NULL); 1.248 + 1.249 + /* gratuitous test of bufferevent_read_buffer */ 1.250 + bufferevent_read_buffer(bev, evbuf); 1.251 + 1.252 + bufferevent_disable(bev, EV_READ); 1.253 + 1.254 + if (evbuffer_get_length(evbuf) == 8333) { 1.255 + ++readcb_finished; 1.256 + } 1.257 + 1.258 + evbuffer_free(evbuf); 1.259 + } 1.260 +} 1.261 + 1.262 +static void 1.263 +writecb(struct bufferevent *bev, void *arg) 1.264 +{ 1.265 + if (evbuffer_get_length(bufferevent_get_output(bev)) == 0) { 1.266 + ++writecb_finished; 1.267 + } 1.268 +} 1.269 + 1.270 +static void 1.271 +errorcb(struct bufferevent *bev, short what, void *arg) 1.272 +{ 1.273 + errorcb_invoked = 1; 1.274 +} 1.275 + 1.276 +void 1.277 +test_bufferevent_zlib(void *arg) 1.278 +{ 1.279 + struct bufferevent *bev1=NULL, *bev2=NULL; 1.280 + char buffer[8333]; 1.281 + z_stream z_input, z_output; 1.282 + int i, r; 1.283 + evutil_socket_t pair[2] = {-1, -1}; 1.284 + (void)arg; 1.285 + 1.286 + infilter_calls = outfilter_calls = readcb_finished = writecb_finished 1.287 + = errorcb_invoked = 0; 1.288 + 1.289 + if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) { 1.290 + tt_abort_perror("socketpair"); 1.291 + } 1.292 + 1.293 + evutil_make_socket_nonblocking(pair[0]); 1.294 + evutil_make_socket_nonblocking(pair[1]); 1.295 + 1.296 + bev1 = bufferevent_socket_new(NULL, pair[0], 0); 1.297 + bev2 = bufferevent_socket_new(NULL, pair[1], 0); 1.298 + 1.299 + memset(&z_output, 0, sizeof(z_output)); 1.300 + r = deflateInit(&z_output, Z_DEFAULT_COMPRESSION); 1.301 + tt_int_op(r, ==, Z_OK); 1.302 + memset(&z_input, 0, sizeof(z_input)); 1.303 + r = inflateInit(&z_input); 1.304 + tt_int_op(r, ==, Z_OK); 1.305 + 1.306 + /* initialize filters */ 1.307 + bev1 = bufferevent_filter_new(bev1, NULL, zlib_output_filter, 1.308 + BEV_OPT_CLOSE_ON_FREE, zlib_deflate_free, &z_output); 1.309 + bev2 = bufferevent_filter_new(bev2, zlib_input_filter, 1.310 + NULL, BEV_OPT_CLOSE_ON_FREE, zlib_inflate_free, &z_input); 1.311 + bufferevent_setcb(bev1, readcb, writecb, errorcb, NULL); 1.312 + bufferevent_setcb(bev2, readcb, writecb, errorcb, NULL); 1.313 + 1.314 + bufferevent_disable(bev1, EV_READ); 1.315 + bufferevent_enable(bev1, EV_WRITE); 1.316 + 1.317 + bufferevent_enable(bev2, EV_READ); 1.318 + 1.319 + for (i = 0; i < (int)sizeof(buffer); i++) 1.320 + buffer[i] = i; 1.321 + 1.322 + /* break it up into multiple buffer chains */ 1.323 + bufferevent_write(bev1, buffer, 1800); 1.324 + bufferevent_write(bev1, buffer + 1800, sizeof(buffer) - 1800); 1.325 + 1.326 + /* we are done writing - we need to flush everything */ 1.327 + bufferevent_flush(bev1, EV_WRITE, BEV_FINISHED); 1.328 + 1.329 + event_dispatch(); 1.330 + 1.331 + tt_want(infilter_calls); 1.332 + tt_want(outfilter_calls); 1.333 + tt_want(readcb_finished); 1.334 + tt_want(writecb_finished); 1.335 + tt_want(!errorcb_invoked); 1.336 + 1.337 + test_ok = 1; 1.338 +end: 1.339 + if (bev1) 1.340 + bufferevent_free(bev1); 1.341 + if (bev2) 1.342 + bufferevent_free(bev2); 1.343 + 1.344 + if (pair[0] >= 0) 1.345 + evutil_closesocket(pair[0]); 1.346 + if (pair[1] >= 0) 1.347 + evutil_closesocket(pair[1]); 1.348 +}