Tarantool development patches archive
 help / color / mirror / Atom feed
From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
To: tarantool-patches@freelists.org
Cc: kostja@tarantool.org
Subject: [tarantool-patches] [PATCH 5/6] test: differentiate blocked and closed swim fake fds
Date: Wed, 20 Mar 2019 13:49:18 +0300	[thread overview]
Message-ID: <aaafcbb19c32bd4358a55c4249fd37d098a606d6.1553078631.git.v.shpilevoy@tarantool.org> (raw)
In-Reply-To: <cover.1553078631.git.v.shpilevoy@tarantool.org>
In-Reply-To: <cover.1553078631.git.v.shpilevoy@tarantool.org>

SWIM's fake file descriptors were implemented to test SWIM with
virtual time and fully controlled network with immediate packet
delivery. One of their features - API to block a file descriptor
and test various failures about it.

But blocked fake fd looks the same as closed fd, and it can
confuse new test's author. Now if an fd is not unblocked at the
end of a test, it leads to a crash. This commit fixes that via
adding explicit difference between blocked and closed fd.

Part of #3234
---
 test/unit/swim_test_transport.c | 53 +++++++++++++++++++++------------
 1 file changed, 34 insertions(+), 19 deletions(-)

diff --git a/test/unit/swim_test_transport.c b/test/unit/swim_test_transport.c
index d6591e969..d1c3e97d7 100644
--- a/test/unit/swim_test_transport.c
+++ b/test/unit/swim_test_transport.c
@@ -90,10 +90,17 @@ struct swim_fd {
 	/** File descriptor number visible to libev. */
 	int evfd;
 	/**
-	 * Link in the list of opened descriptors. Used to feed
-	 * them all EV_WRITE.
+	 * True, if the descriptor is opened and can receive new
+	 * messages. Regardless of blocked or not. In case of
+	 * blocked, new messages are queued, but not delivered.
 	 */
-	struct rlist in_opened;
+	bool is_opened;
+
+	/**
+	 * Link in the list of opened and non-blocked descriptors.
+	 * Used to feed them all EV_WRITE.
+	 */
+	struct rlist in_active;
 	/** Queue of received, but not processed packets. */
 	struct rlist recv_queue;
 	/** Queue of sent, but not received packets. */
@@ -103,23 +110,22 @@ struct swim_fd {
 /** Table of fake file descriptors. */
 static struct swim_fd swim_fd[FAKE_FD_NUMBER];
 /**
- * List of opened file descriptors. Used to avoid fullscan of the
+ * List of active file descriptors. Used to avoid fullscan of the
  * table.
  */
-static RLIST_HEAD(swim_fd_opened);
+static RLIST_HEAD(swim_fd_active);
 
 /** Open a fake file descriptor. */
 static inline int
 swim_fd_open(struct swim_fd *fd)
 {
-	if (! rlist_empty(&fd->in_opened)) {
+	if (fd->is_opened) {
 		errno = EADDRINUSE;
 		diag_set(SocketError, "test_socket:1", "bind");
 		return -1;
 	}
-	rlist_add_tail_entry(&swim_fd_opened, fd, in_opened);
-	rlist_create(&fd->recv_queue);
-	rlist_create(&fd->send_queue);
+	fd->is_opened = true;
+	rlist_add_tail_entry(&swim_fd_active, fd, in_active);
 	return 0;
 }
 
@@ -127,12 +133,15 @@ swim_fd_open(struct swim_fd *fd)
 static inline void
 swim_fd_close(struct swim_fd *fd)
 {
+	if (! fd->is_opened)
+		return;
 	struct swim_test_packet *i, *tmp;
 	rlist_foreach_entry_safe(i, &fd->recv_queue, in_queue, tmp)
 		swim_test_packet_delete(i);
 	rlist_foreach_entry_safe(i, &fd->send_queue, in_queue, tmp)
 		swim_test_packet_delete(i);
-	rlist_del_entry(fd, in_opened);
+	rlist_del_entry(fd, in_active);
+	fd->is_opened = false;
 }
 
 void
@@ -140,7 +149,8 @@ swim_test_transport_init(void)
 {
 	for (int i = 0, evfd = FAKE_FD_BASE; i < FAKE_FD_NUMBER; ++i, ++evfd) {
 		swim_fd[i].evfd = evfd;
-		rlist_create(&swim_fd[i].in_opened);
+		swim_fd[i].is_opened = false;
+		rlist_create(&swim_fd[i].in_active);
 		rlist_create(&swim_fd[i].recv_queue);
 		rlist_create(&swim_fd[i].send_queue);
 	}
@@ -172,6 +182,7 @@ swim_transport_send(struct swim_transport *transport, const void *data,
 		swim_test_packet_new(data, size, &transport->addr,
 				     (const struct sockaddr_in *) addr);
 	struct swim_fd *src = &swim_fd[transport->fd - FAKE_FD_BASE];
+	assert(src->is_opened);
 	rlist_add_tail_entry(&src->send_queue, p, in_queue);
 	return size;
 }
@@ -188,6 +199,7 @@ swim_transport_recv(struct swim_transport *transport, void *buffer, size_t size,
 	 * Pop a packet from a receving queue.
 	 */
 	struct swim_fd *dst = &swim_fd[transport->fd - FAKE_FD_BASE];
+	assert(dst->is_opened);
 	struct swim_test_packet *p =
 		rlist_shift_entry(&dst->recv_queue, struct swim_test_packet,
 				  in_queue);
@@ -236,16 +248,16 @@ void
 swim_test_transport_block_fd(int fd)
 {
 	struct swim_fd *sfd = &swim_fd[fd - FAKE_FD_BASE];
-	assert(! rlist_empty(&sfd->in_opened));
-	rlist_del_entry(sfd, in_opened);
+	assert(! rlist_empty(&sfd->in_active));
+	rlist_del_entry(sfd, in_active);
 }
 
 void
 swim_test_transport_unblock_fd(int fd)
 {
 	struct swim_fd *sfd = &swim_fd[fd - FAKE_FD_BASE];
-	assert(rlist_empty(&sfd->in_opened));
-	rlist_add_tail_entry(&swim_fd_opened, sfd, in_opened);
+	if (sfd->is_opened && rlist_empty(&sfd->in_active))
+		rlist_add_tail_entry(&swim_fd_active, sfd, in_active);
 }
 
 /** Send one packet to destination's recv queue. */
@@ -257,8 +269,11 @@ swim_fd_send_packet(struct swim_fd *fd)
 	struct swim_test_packet *p =
 		rlist_shift_entry(&fd->send_queue, struct swim_test_packet,
 				  in_queue);
-	int dst_i = ntohs(p->dst.sin_port);
-	rlist_add_tail_entry(&swim_fd[dst_i].recv_queue, p, in_queue);
+	struct swim_fd *dst = &swim_fd[ntohs(p->dst.sin_port)];
+	if (dst->is_opened)
+		rlist_add_tail_entry(&dst->recv_queue, p, in_queue);
+	else
+		swim_test_packet_delete(p);
 }
 
 void
@@ -269,11 +284,11 @@ swim_transport_do_loop_step(struct ev_loop *loop)
 	 * Reversed because libev invokes events in reversed
 	 * order. So this reverse + libev reverse = normal order.
 	 */
-	rlist_foreach_entry_reverse(fd, &swim_fd_opened, in_opened) {
+	rlist_foreach_entry_reverse(fd, &swim_fd_active, in_active) {
 		swim_fd_send_packet(fd);
 		ev_feed_fd_event(loop, fd->evfd, EV_WRITE);
 	}
-	rlist_foreach_entry_reverse(fd, &swim_fd_opened, in_opened) {
+	rlist_foreach_entry_reverse(fd, &swim_fd_active, in_active) {
 		if (!rlist_empty(&fd->recv_queue))
 			ev_feed_fd_event(loop, fd->evfd, EV_READ);
 	}
-- 
2.17.2 (Apple Git-113)

  parent reply	other threads:[~2019-03-20 10:49 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-20 10:49 [tarantool-patches] [PATCH 0/6] SWIM failure detection draft Vladislav Shpilevoy
2019-03-20 10:49 ` [tarantool-patches] [PATCH 1/6] swim: follow-ups for SWIM anti-entropy Vladislav Shpilevoy
2019-03-29  8:27   ` [tarantool-patches] " Konstantin Osipov
2019-03-29 10:19     ` Vladislav Shpilevoy
2019-03-20 10:49 ` [tarantool-patches] [PATCH 2/6] test: introduce breakpoints for swim's event loop Vladislav Shpilevoy
2019-03-29 18:20   ` [tarantool-patches] " Konstantin Osipov
2019-04-02 12:25     ` Vladislav Shpilevoy
2019-04-02 19:16       ` Vladislav Shpilevoy
2019-04-02 20:40         ` Konstantin Osipov
2019-04-02 21:26           ` Vladislav Shpilevoy
2019-03-20 10:49 ` [tarantool-patches] [PATCH 3/6] test: remove swim_unblock_fd event from swim test harness Vladislav Shpilevoy
2019-03-29 18:22   ` [tarantool-patches] " Konstantin Osipov
2019-04-02 21:26     ` Vladislav Shpilevoy
2019-03-20 10:49 ` [tarantool-patches] [PATCH 4/6] swim: expose enum swim_member_status to public API Vladislav Shpilevoy
2019-03-29 18:24   ` [tarantool-patches] " Konstantin Osipov
2019-04-02 12:25     ` Vladislav Shpilevoy
2019-04-02 13:17       ` Konstantin Osipov
2019-04-02 21:26         ` Vladislav Shpilevoy
2019-03-20 10:49 ` Vladislav Shpilevoy [this message]
2019-03-29 18:25   ` [tarantool-patches] Re: [PATCH 5/6] test: differentiate blocked and closed swim fake fds Konstantin Osipov
2019-04-02 21:26     ` Vladislav Shpilevoy
2019-03-20 10:49 ` [tarantool-patches] [PATCH 6/6] [RAW] swim: introduce failure detection component Vladislav Shpilevoy
2019-03-29 18:59   ` [tarantool-patches] " Konstantin Osipov
2019-04-02 12:25     ` Vladislav Shpilevoy
2019-04-04 10:20       ` Vladislav Shpilevoy
2019-04-04 12:45       ` Konstantin Osipov
2019-04-04 13:57         ` Vladislav Shpilevoy
2019-04-04 16:14           ` Vladimir Davydov
2019-04-04 16:47             ` Vladislav Shpilevoy
2019-03-27 19:28 ` [tarantool-patches] [PATCH 7/6] swim: make swim_upsert_member returning two values Vladislav Shpilevoy
2019-03-28  8:52   ` [tarantool-patches] " Konstantin Osipov
2019-03-28 11:52     ` 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=aaafcbb19c32bd4358a55c4249fd37d098a606d6.1553078631.git.v.shpilevoy@tarantool.org \
    --to=v.shpilevoy@tarantool.org \
    --cc=kostja@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --subject='Re: [tarantool-patches] [PATCH 5/6] test: differentiate blocked and closed swim fake fds' \
    /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