[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