[Tarantool-patches] [PATCH 05/10] test: factor out swim from fakenet.c/.h files

Vladislav Shpilevoy v.shpilevoy at tarantool.org
Tue Dec 1 02:56:14 MSK 2020


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 all swim code to swim_test_transport.c. Now
this file is nothing but an implementation of swim_transport.h on
top of fakenet API.

Fakenet, in turn, does not depend on SWIM anymore, and can be
moved to its own library.

Part of #5303
---
 test/unit/CMakeLists.txt        |  6 +--
 test/unit/fakenet.c             | 74 +++-------------------------
 test/unit/fakenet.h             | 46 ++++++++++++++++++
 test/unit/swim_test_transport.c | 86 +++++++++++++++++++++++++++++++++
 4 files changed, 141 insertions(+), 71 deletions(-)
 create mode 100644 test/unit/swim_test_transport.c

diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index 7c369740e..00f5e89a3 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -240,15 +240,15 @@ target_link_libraries(sio.test unit core)
 add_executable(crypto.test crypto.c core_test_utils.c)
 target_link_libraries(crypto.test crypto unit)
 
-add_executable(swim.test swim.c fakenet.c swim_test_ev.c
+add_executable(swim.test swim.c fakenet.c swim_test_transport.c swim_test_ev.c
                swim_test_utils.c ${PROJECT_SOURCE_DIR}/src/version.c core_test_utils.c)
 target_link_libraries(swim.test unit swim)
 
-add_executable(swim_proto.test swim_proto.c fakenet.c swim_test_ev.c
+add_executable(swim_proto.test swim_proto.c fakenet.c swim_test_transport.c swim_test_ev.c
                swim_test_utils.c ${PROJECT_SOURCE_DIR}/src/version.c core_test_utils.c)
 target_link_libraries(swim_proto.test unit swim)
 
-add_executable(swim_errinj.test swim_errinj.c fakenet.c
+add_executable(swim_errinj.test swim_errinj.c fakenet.c swim_test_transport.c
                swim_test_ev.c swim_test_utils.c
                ${PROJECT_SOURCE_DIR}/src/version.c core_test_utils.c)
 target_link_libraries(swim_errinj.test unit swim)
diff --git a/test/unit/fakenet.c b/test/unit/fakenet.c
index a8101194a..1c757ce89 100644
--- a/test/unit/fakenet.c
+++ b/test/unit/fakenet.c
@@ -29,8 +29,6 @@
  * SUCH DAMAGE.
  */
 #include "fakenet.h"
-#include "swim/swim_transport.h"
-#include "swim/swim_io.h"
 #include "fiber.h"
 #include <errno.h>
 #include <sys/socket.h>
@@ -291,18 +289,14 @@ fakenet_free(void)
 		fakenet_fd_close(&fakenet_fd[i]);
 }
 
-static void
+void
 fakenet_close(int fd)
 {
 	assert(fd >= FAKE_FD_BASE);
 	fakenet_fd_close(&fakenet_fd[fd - FAKE_FD_BASE]);
 }
 
-/**
- * Wrap a packet and put into send queue. Packets are popped from
- * it on EV_WRITE event.
- */
-static ssize_t
+ssize_t
 fakenet_sendto(int fd, const void *data, size_t size,
 	       const struct sockaddr *addr, socklen_t addr_size)
 {
@@ -322,11 +316,7 @@ fakenet_sendto(int fd, const void *data, size_t size,
 	return size;
 }
 
-/**
- * Move a packet from send to recv queue. The packet is popped and
- * processed on EV_READ event.
- */
-static ssize_t
+ssize_t
 fakenet_recvfrom(int fd, void *buffer, size_t size, struct sockaddr *addr,
 		 socklen_t *addr_size)
 {
@@ -346,7 +336,7 @@ fakenet_recvfrom(int fd, void *buffer, size_t size, struct sockaddr *addr,
 	return result;
 }
 
-static int
+int
 fakenet_bind(int *fd, const struct sockaddr *addr, socklen_t addr_len)
 {
 	assert(addr->sa_family == AF_INET);
@@ -365,46 +355,6 @@ fakenet_bind(int *fd, const struct sockaddr *addr, socklen_t addr_len)
 	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 fakenet_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 fakenet_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 (fakenet_bind(&transport->fd, addr, addr_len) != 0)
-		return -1;
-	transport->addr = *(struct sockaddr_in *)addr;
-	return 0;
-}
-
-void
-swim_transport_destroy(struct swim_transport *transport)
-{
-	if (transport->fd != -1)
-		fakenet_close(transport->fd);
-}
-
-void
-swim_transport_create(struct swim_transport *transport)
-{
-	transport->fd = -1;
-	memset(&transport->addr, 0, sizeof(transport->addr));
-}
-
 void
 fakenet_block(int fd)
 {
@@ -509,7 +459,7 @@ fakenet_loop_update(struct ev_loop *loop)
 	} while (ev_pending_count(loop) > 0);
 }
 
-static int
+int
 fakenet_getifaddrs(struct ifaddrs **ifaddrs)
 {
 	/*
@@ -541,13 +491,7 @@ fakenet_getifaddrs(struct ifaddrs **ifaddrs)
 	return 0;
 }
 
-int
-swim_getifaddrs(struct ifaddrs **ifaddrs)
-{
-	return fakenet_getifaddrs(ifaddrs);
-}
-
-static void
+void
 fakenet_freeifaddrs(struct ifaddrs *ifaddrs)
 {
 	/*
@@ -556,9 +500,3 @@ fakenet_freeifaddrs(struct ifaddrs *ifaddrs)
 	 */
 	free(ifaddrs);
 }
-
-void
-swim_freeifaddrs(struct ifaddrs *ifaddrs)
-{
-	fakenet_freeifaddrs(ifaddrs);
-}
diff --git a/test/unit/fakenet.h b/test/unit/fakenet.h
index 043c398ab..c2df31af2 100644
--- a/test/unit/fakenet.h
+++ b/test/unit/fakenet.h
@@ -30,7 +30,12 @@
  * SUCH DAMAGE.
  */
 #include <stdbool.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+
 struct ev_loop;
+struct ifaddrs;
 
 /**
  * Fakenet implements a 'fake' file descriptors table in user space in order to
@@ -38,6 +43,47 @@ struct ev_loop;
  * to set necessary loss level, delay, reorders, blocks.
  */
 
+/**
+ * Emulator of sendto().
+ * Save data to the socket output buffer. The buffer is flushed on the next loop
+ * update.
+ */
+ssize_t
+fakenet_sendto(int fd, const void *data, size_t size,
+	       const struct sockaddr *addr, socklen_t addr_size);
+
+/**
+ * Emulator of recvfrom().
+ * Try to read the input buffer of the socket.
+ */
+ssize_t
+fakenet_recvfrom(int fd, void *buffer, size_t size, struct sockaddr *addr,
+		 socklen_t *addr_size);
+
+/**
+ * Emulator of socket() + bind() + close().
+ * Fake bind will close the old descriptor, create a new one, and bind it to the
+ * given address atomically. So it either does all that successfully, or nothing
+ * of that. The created socket is connection-less and packet-oriented.
+ */
+int
+fakenet_bind(int *fd, const struct sockaddr *addr, socklen_t addr_len);
+
+/**
+ * Emulator of close().
+ * Should be called only on what was previously created via fakenet bind().
+ */
+void
+fakenet_close(int fd);
+
+/** Emulator of getifaddrs(). */
+int
+fakenet_getifaddrs(struct ifaddrs **ifaddrs);
+
+/** Emulator of freeifaddrs(). */
+void
+fakenet_freeifaddrs(struct ifaddrs *ifaddrs);
+
 /**
  * Signature of a packet filter function. It takes packet data,
  * arbitrary user data, and should return true, if the packet
diff --git a/test/unit/swim_test_transport.c b/test/unit/swim_test_transport.c
new file mode 100644
index 000000000..d2c39da5b
--- /dev/null
+++ b/test/unit/swim_test_transport.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2010-2020, Tarantool AUTHORS, please see AUTHORS file.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the
+ *    following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <assert.h>
+#include <string.h>
+#include "fakenet.h"
+#include "swim/swim_transport.h"
+
+ssize_t
+swim_transport_send(struct swim_transport *transport, const void *data,
+		    size_t size, const struct sockaddr *addr,
+		    socklen_t addr_size)
+{
+	return fakenet_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 fakenet_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 (fakenet_bind(&transport->fd, addr, addr_len) != 0)
+		return -1;
+	transport->addr = *(struct sockaddr_in *)addr;
+	return 0;
+}
+
+void
+swim_transport_destroy(struct swim_transport *transport)
+{
+	if (transport->fd != -1)
+		fakenet_close(transport->fd);
+}
+
+void
+swim_transport_create(struct swim_transport *transport)
+{
+	transport->fd = -1;
+	memset(&transport->addr, 0, sizeof(transport->addr));
+}
+
+int
+swim_getifaddrs(struct ifaddrs **ifaddrs)
+{
+	return fakenet_getifaddrs(ifaddrs);
+}
+
+void
+swim_freeifaddrs(struct ifaddrs *ifaddrs)
+{
+	fakenet_freeifaddrs(ifaddrs);
+}
-- 
2.24.3 (Apple Git-128)



More information about the Tarantool-patches mailing list