From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtpng1.m.smailru.net (smtpng1.m.smailru.net [94.100.181.251]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 02D4945C306 for ; Tue, 1 Dec 2020 02:56:22 +0300 (MSK) From: Vladislav Shpilevoy Date: Tue, 1 Dec 2020 00:56:11 +0100 Message-Id: <8ad36099679285cd0133507fad939cef93c57c87.1606780408.git.v.shpilevoy@tarantool.org> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Tarantool-patches] [PATCH 02/10] test: factor out swim from libc emulation funcs List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: tarantool-patches@dev.tarantool.org, sergepetrenko@tarantool.org SWIM unit tests contain special libraries for emulating event loop and network: swim_test_ev and swim_test_transport. They provide API similar to libev and to network part of libc, which internally is implemented entirely in user-space and allows to simulate all kinds of errors, any time durations, etc. These test libraries are going to be re-used for Raft unit tests. But for that it is necessary to detach them from all SWIM dependencies. -- This commit extracts libc-like functions from the fake implementation of swim_transport.h functions. That allows to move swim functions out of the fake network library to their own file, and build the fake network as an independent library not related to swim. It is worth mentioning that the bind() emulator (swim_test_bind()) is not a true bind(). Its behaviour is more like socket() + bind() + close(). Such API was designed for swim_transport, and it seems too hard to split it into separate methods, especially socket() and bind(). Because in the fake network library there is a relation between IPv4 address and file descriptor number. It means, you can't create a file descriptor without occupying an address. So socket() + bind() and rebind (= close() + socket() + bind()) must be atomic. swim_test_bind() does that. This will also work fine for Raft, so it was left as is for now. Part of #5303 --- test/unit/swim_test_transport.c | 72 +++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 21 deletions(-) diff --git a/test/unit/swim_test_transport.c b/test/unit/swim_test_transport.c index 9fad351b5..855fb2d8e 100644 --- a/test/unit/swim_test_transport.c +++ b/test/unit/swim_test_transport.c @@ -294,14 +294,20 @@ swim_test_transport_free(void) swim_fd_close(&swim_fd[i]); } +static void +swim_test_close(int fd) +{ + assert(fd >= FAKE_FD_BASE); + swim_fd_close(&swim_fd[fd - FAKE_FD_BASE]); +} + /** * Wrap a packet and put into send queue. Packets are popped from * it on EV_WRITE event. */ -ssize_t -swim_transport_send(struct swim_transport *transport, const void *data, - size_t size, const struct sockaddr *addr, - socklen_t addr_size) +static ssize_t +swim_test_sendto(int fd, const void *data, size_t size, + const struct sockaddr *addr, socklen_t addr_size) { /* * Create packet. Put into sending queue. @@ -309,11 +315,11 @@ swim_transport_send(struct swim_transport *transport, const void *data, (void) addr_size; assert(addr->sa_family == AF_INET); struct sockaddr_in src_addr; - swim_test_fd_to_sockaddr_in(transport->fd, &src_addr); + swim_test_fd_to_sockaddr_in(fd, &src_addr); struct swim_test_packet *p = swim_test_packet_new(data, size, &src_addr, (const struct sockaddr_in *) addr); - struct swim_fd *src = &swim_fd[transport->fd - FAKE_FD_BASE]; + struct swim_fd *src = &swim_fd[fd - FAKE_FD_BASE]; assert(src->is_opened); rlist_add_tail_entry(&src->send_queue, p, in_queue); return size; @@ -323,14 +329,14 @@ swim_transport_send(struct swim_transport *transport, const void *data, * Move a packet from send to recv queue. The packet is popped and * processed on EV_READ event. */ -ssize_t -swim_transport_recv(struct swim_transport *transport, void *buffer, size_t size, - struct sockaddr *addr, socklen_t *addr_size) +static ssize_t +swim_test_recvfrom(int fd, void *buffer, size_t size, struct sockaddr *addr, + socklen_t *addr_size) { /* * Pop a packet from a receiving queue. */ - struct swim_fd *dst = &swim_fd[transport->fd - FAKE_FD_BASE]; + struct swim_fd *dst = &swim_fd[fd - FAKE_FD_BASE]; assert(dst->is_opened); struct swim_test_packet *p = rlist_shift_entry(&dst->recv_queue, struct swim_test_packet, @@ -343,24 +349,48 @@ swim_transport_recv(struct swim_transport *transport, void *buffer, size_t size, return result; } -int -swim_transport_bind(struct swim_transport *transport, - const struct sockaddr *addr, socklen_t addr_len) +static int +swim_test_bind(int *fd, const struct sockaddr *addr, socklen_t addr_len) { assert(addr->sa_family == AF_INET); const struct sockaddr_in *new_addr = (const struct sockaddr_in *) addr; + assert(addr_len >= sizeof(*new_addr)); + (void)addr_len; int new_fd = swim_test_sockaddr_in_to_fd(new_addr); - int old_fd = transport->fd; - if (old_fd == new_fd) { - transport->addr = *new_addr; + int old_fd = *fd; + if (old_fd == new_fd) return 0; - } if (swim_fd_open(&swim_fd[new_fd - FAKE_FD_BASE]) != 0) return -1; - transport->fd = new_fd; - transport->addr = *new_addr; if (old_fd != -1) - swim_fd_close(&swim_fd[old_fd - FAKE_FD_BASE]); + swim_test_close(old_fd); + *fd = new_fd; + return 0; +} + +ssize_t +swim_transport_send(struct swim_transport *transport, const void *data, + size_t size, const struct sockaddr *addr, + socklen_t addr_size) +{ + return swim_test_sendto(transport->fd, data, size, addr, addr_size); +} + +ssize_t +swim_transport_recv(struct swim_transport *transport, void *buffer, size_t size, + struct sockaddr *addr, socklen_t *addr_size) +{ + return swim_test_recvfrom(transport->fd, buffer, size, addr, addr_size); +} + +int +swim_transport_bind(struct swim_transport *transport, + const struct sockaddr *addr, socklen_t addr_len) +{ + assert(addr->sa_family == AF_INET); + if (swim_test_bind(&transport->fd, addr, addr_len) != 0) + return -1; + transport->addr = *(struct sockaddr_in *)addr; return 0; } @@ -368,7 +398,7 @@ void swim_transport_destroy(struct swim_transport *transport) { if (transport->fd != -1) - swim_fd_close(&swim_fd[transport->fd - FAKE_FD_BASE]); + swim_test_close(transport->fd); } void -- 2.24.3 (Apple Git-128)