Tarantool development patches archive
 help / color / mirror / Atom feed
From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
To: tarantool-patches@dev.tarantool.org, sergepetrenko@tarantool.org
Subject: [Tarantool-patches] [PATCH 02/10] test: factor out swim from libc emulation funcs
Date: Tue,  1 Dec 2020 00:56:11 +0100	[thread overview]
Message-ID: <8ad36099679285cd0133507fad939cef93c57c87.1606780408.git.v.shpilevoy@tarantool.org> (raw)
In-Reply-To: <cover.1606780408.git.v.shpilevoy@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)

  parent reply	other threads:[~2020-11-30 23:56 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-30 23:56 [Tarantool-patches] [PATCH 00/10] Raft module, part 3 - fake network and libev for Raft and SWIM Vladislav Shpilevoy
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 01/10] test: stop using swim_transport.addr as in-param Vladislav Shpilevoy
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 10/10] fakesys: move fakeev to fakesys library Vladislav Shpilevoy
2020-11-30 23:56 ` Vladislav Shpilevoy [this message]
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 03/10] test: rename fake libc network methods to fakenet Vladislav Shpilevoy
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 04/10] test: move fake network code to fakenet.c/.h files Vladislav Shpilevoy
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 05/10] test: factor out swim from " Vladislav Shpilevoy
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 06/10] fakesys: introduce fake system library Vladislav Shpilevoy
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 07/10] test: rename fake libev methods to fakeev Vladislav Shpilevoy
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 08/10] test: move fake libev code to fakeev.c/.h files Vladislav Shpilevoy
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 09/10] test: factor out swim from fakeev.h/.c files Vladislav Shpilevoy
2020-12-01 13:42 ` [Tarantool-patches] [PATCH 00/10] Raft module, part 3 - fake network and libev for Raft and SWIM Serge Petrenko
2020-12-01 22:33 ` Vladislav Shpilevoy
2020-12-04  0:35 ` Alexander V. Tikhonov
2020-12-04 22:53   ` Vladislav Shpilevoy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8ad36099679285cd0133507fad939cef93c57c87.1606780408.git.v.shpilevoy@tarantool.org \
    --to=v.shpilevoy@tarantool.org \
    --cc=sergepetrenko@tarantool.org \
    --cc=tarantool-patches@dev.tarantool.org \
    --subject='Re: [Tarantool-patches] [PATCH 02/10] test: factor out swim from libc emulation funcs' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox