* [Tarantool-patches] [PATCH 00/10] Raft module, part 3 - fake network and libev for Raft and SWIM
@ 2020-11-30 23:56 Vladislav Shpilevoy
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 01/10] test: stop using swim_transport.addr as in-param Vladislav Shpilevoy
` (12 more replies)
0 siblings, 13 replies; 15+ messages in thread
From: Vladislav Shpilevoy @ 2020-11-30 23:56 UTC (permalink / raw)
To: tarantool-patches, sergepetrenko
The patchset is a third part of Raft relocation to a new module for the sake of
unit testing. This part extracts fake network and libev libraries from SWIM unit
tests to a new library fakesys, which will be used by Raft.
The patchset only moves the existing code. For the actual Raft tests it is
likely I will add some new Raft-specific code, and probably will generalize
something from swim_test_utils.h/.c.
Branch: http://github.com/tarantool/tarantool/tree/gerold103/gh-5303-p3-fakesys
Issue: https://github.com/tarantool/tarantool/issues/5303
Vladislav Shpilevoy (10):
test: stop using swim_transport.addr as in-param
test: factor out swim from libc emulation funcs
test: rename fake libc network methods to fakenet
test: move fake network code to fakenet.c/.h files
test: factor out swim from fakenet.c/.h files
fakesys: introduce fake system library
test: rename fake libev methods to fakeev
test: move fake libev code to fakeev.c/.h files
test: factor out swim from fakeev.h/.c files
fakesys: move fakeev to fakesys library
src/lib/CMakeLists.txt | 1 +
src/lib/fakesys/CMakeLists.txt | 8 +
src/lib/fakesys/fakeev.c | 350 ++++++++++++
.../lib/fakesys/fakeev.h | 45 +-
src/lib/fakesys/fakenet.c | 502 ++++++++++++++++++
.../lib/fakesys/fakenet.h | 81 ++-
test/unit/CMakeLists.txt | 6 +-
test/unit/swim.c | 8 +-
test/unit/swim_errinj.c | 8 +-
test/unit/swim_test_ev.c | 319 +----------
test/unit/swim_test_transport.c | 438 +--------------
test/unit/swim_test_utils.c | 30 +-
test/unit/swim_test_utils.h | 6 +-
13 files changed, 1003 insertions(+), 799 deletions(-)
create mode 100644 src/lib/fakesys/CMakeLists.txt
create mode 100644 src/lib/fakesys/fakeev.c
rename test/unit/swim_test_ev.h => src/lib/fakesys/fakeev.h (77%)
create mode 100644 src/lib/fakesys/fakenet.c
rename test/unit/swim_test_transport.h => src/lib/fakesys/fakenet.h (59%)
--
2.24.3 (Apple Git-128)
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Tarantool-patches] [PATCH 01/10] test: stop using swim_transport.addr as in-param
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 ` Vladislav Shpilevoy
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 10/10] fakesys: move fakeev to fakesys library Vladislav Shpilevoy
` (11 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: Vladislav Shpilevoy @ 2020-11-30 23:56 UTC (permalink / raw)
To: tarantool-patches, sergepetrenko
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.
--
One of the dependencies - swim_transport.addr, which was used in
swim_transport_send() as an input parameter. swim_transport_send()
simulates sendto(), and it can't be generalized while it depends
on source address being passed explicitly.
This patch makes swim_transport_send() deduct the source address
by the file descriptor number.
There is a couple of new functions for that:
swim_test_sockaddr_in_to_fd and swim_test_fd_to_sockaddr_in.
They were inlined earlier, but it seems the fd <-> source address
translation is used often enough to extract these functions.
Part of #5303
---
test/unit/swim_test_transport.c | 28 +++++++++++++++++++++++++---
1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/test/unit/swim_test_transport.c b/test/unit/swim_test_transport.c
index 334ac926e..9fad351b5 100644
--- a/test/unit/swim_test_transport.c
+++ b/test/unit/swim_test_transport.c
@@ -51,6 +51,25 @@ enum {
FAKE_FD_NUMBER = 1000,
};
+static inline int
+swim_test_sockaddr_in_to_fd(const struct sockaddr_in *addr)
+{
+ assert(addr->sin_family == AF_INET);
+ return ntohs(addr->sin_port) + FAKE_FD_BASE;
+}
+
+static inline void
+swim_test_fd_to_sockaddr_in(int fd, struct sockaddr_in *addr)
+{
+ *addr = (struct sockaddr_in){
+ .sin_family = AF_INET,
+ .sin_port = htons(fd) - FAKE_FD_BASE,
+ .sin_addr = {
+ .s_addr = htonl(INADDR_LOOPBACK),
+ },
+ };
+}
+
/** UDP packet wrapper. It is stored in send/recv queues. */
struct swim_test_packet {
/** Source address. */
@@ -289,8 +308,10 @@ 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);
struct swim_test_packet *p =
- swim_test_packet_new(data, size, &transport->addr,
+ swim_test_packet_new(data, size, &src_addr,
(const struct sockaddr_in *) addr);
struct swim_fd *src = &swim_fd[transport->fd - FAKE_FD_BASE];
assert(src->is_opened);
@@ -328,7 +349,7 @@ swim_transport_bind(struct swim_transport *transport,
{
assert(addr->sa_family == AF_INET);
const struct sockaddr_in *new_addr = (const struct sockaddr_in *) addr;
- int new_fd = ntohs(new_addr->sin_port) + FAKE_FD_BASE;
+ 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;
@@ -406,7 +427,8 @@ swim_fd_send_packet(struct swim_fd *fd)
}
swim_test_packet_delete(p);
} else {
- dst = &swim_fd[ntohs(p->dst.sin_port)];
+ int fdnum = swim_test_sockaddr_in_to_fd(&p->dst);
+ dst = &swim_fd[fdnum - FAKE_FD_BASE];
swim_move_packet(fd, dst, p);
}
}
--
2.24.3 (Apple Git-128)
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Tarantool-patches] [PATCH 10/10] fakesys: move fakeev to fakesys library
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 ` Vladislav Shpilevoy
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 02/10] test: factor out swim from libc emulation funcs Vladislav Shpilevoy
` (10 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: Vladislav Shpilevoy @ 2020-11-30 23:56 UTC (permalink / raw)
To: tarantool-patches, sergepetrenko
Fakesys is a collection of fake implementations of deep system
things such as libev and libc.
The fake subsystems will provide API just like their original
counterparts (except for function names), but with full control of
their behaviour in user-space for the sake of unit testing.
Fakeev is a bogus version of libev, whose main feature is virtual
time. Fakeev has internal clock, which is fully controllable in
user-space. That allows to roll hours of tests in milliseconds of
real time.
Fakeev is used in SWIM tests, and will be used in Raft tests.
Part of #5303
---
src/lib/fakesys/CMakeLists.txt | 1 +
{test/unit => src/lib/fakesys}/fakeev.c | 0
{test/unit => src/lib/fakesys}/fakeev.h | 0
test/unit/CMakeLists.txt | 6 +++---
test/unit/swim_test_ev.c | 2 +-
test/unit/swim_test_utils.h | 2 +-
6 files changed, 6 insertions(+), 5 deletions(-)
rename {test/unit => src/lib/fakesys}/fakeev.c (100%)
rename {test/unit => src/lib/fakesys}/fakeev.h (100%)
diff --git a/src/lib/fakesys/CMakeLists.txt b/src/lib/fakesys/CMakeLists.txt
index b4d6af817..71e6a558e 100644
--- a/src/lib/fakesys/CMakeLists.txt
+++ b/src/lib/fakesys/CMakeLists.txt
@@ -1,5 +1,6 @@
set(lib_sources
fakenet.c
+ fakeev.c
)
set_source_files_compile_flags(${lib_sources})
diff --git a/test/unit/fakeev.c b/src/lib/fakesys/fakeev.c
similarity index 100%
rename from test/unit/fakeev.c
rename to src/lib/fakesys/fakeev.c
diff --git a/test/unit/fakeev.h b/src/lib/fakesys/fakeev.h
similarity index 100%
rename from test/unit/fakeev.h
rename to src/lib/fakesys/fakeev.h
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index 7f64f9685..e6a79e911 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -240,16 +240,16 @@ 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 swim_test_transport.c fakeev.c swim_test_ev.c
+add_executable(swim.test swim.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 fakesys swim)
-add_executable(swim_proto.test swim_proto.c swim_test_transport.c fakeev.c swim_test_ev.c
+add_executable(swim_proto.test swim_proto.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 fakesys swim)
add_executable(swim_errinj.test swim_errinj.c swim_test_transport.c
- fakeev.c swim_test_ev.c swim_test_utils.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 fakesys swim)
diff --git a/test/unit/swim_test_ev.c b/test/unit/swim_test_ev.c
index 876aa4eea..e075194e8 100644
--- a/test/unit/swim_test_ev.c
+++ b/test/unit/swim_test_ev.c
@@ -29,7 +29,7 @@
* SUCH DAMAGE.
*/
#include "swim/swim_ev.h"
-#include "fakeev.h"
+#include "fakesys/fakeev.h"
double
swim_time(void)
diff --git a/test/unit/swim_test_utils.h b/test/unit/swim_test_utils.h
index 665423a03..61a6787d9 100644
--- a/test/unit/swim_test_utils.h
+++ b/test/unit/swim_test_utils.h
@@ -39,7 +39,7 @@
#include "swim/swim_ev.h"
#include "swim/swim_proto.h"
#include "fakesys/fakenet.h"
-#include "fakeev.h"
+#include "fakesys/fakeev.h"
struct swim_cluster;
--
2.24.3 (Apple Git-128)
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Tarantool-patches] [PATCH 02/10] test: factor out swim from libc emulation funcs
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
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 03/10] test: rename fake libc network methods to fakenet Vladislav Shpilevoy
` (9 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: Vladislav Shpilevoy @ 2020-11-30 23:56 UTC (permalink / raw)
To: tarantool-patches, sergepetrenko
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)
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Tarantool-patches] [PATCH 03/10] test: rename fake libc network methods to fakenet
2020-11-30 23:56 [Tarantool-patches] [PATCH 00/10] Raft module, part 3 - fake network and libev for Raft and SWIM Vladislav Shpilevoy
` (2 preceding siblings ...)
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 02/10] test: factor out swim from libc emulation funcs Vladislav Shpilevoy
@ 2020-11-30 23:56 ` Vladislav Shpilevoy
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 04/10] test: move fake network code to fakenet.c/.h files Vladislav Shpilevoy
` (8 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: Vladislav Shpilevoy @ 2020-11-30 23:56 UTC (permalink / raw)
To: tarantool-patches, sergepetrenko
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.
--
The only dependency left in fake network functions is the 'swim'
prefix. This commit replaces it with 'fakenet' before they are
going to be moved to their own library.
Part of #5303
---
test/unit/swim.c | 4 +-
test/unit/swim_errinj.c | 4 +-
test/unit/swim_test_transport.c | 234 +++++++++++++++++---------------
test/unit/swim_test_transport.h | 30 ++--
test/unit/swim_test_utils.c | 18 ++-
5 files changed, 148 insertions(+), 142 deletions(-)
diff --git a/test/unit/swim.c b/test/unit/swim.c
index 4e9dce8ce..1787745bc 100644
--- a/test/unit/swim.c
+++ b/test/unit/swim.c
@@ -1078,7 +1078,7 @@ main_f(va_list ap)
(void) ap;
swim_test_ev_init();
- swim_test_transport_init();
+ fakenet_init();
swim_test_one_link();
swim_test_sequence();
@@ -1103,7 +1103,7 @@ main_f(va_list ap)
swim_test_dissemination_speed();
swim_test_suspect_new_members();
- swim_test_transport_free();
+ fakenet_free();
swim_test_ev_free();
test_result = check_plan();
diff --git a/test/unit/swim_errinj.c b/test/unit/swim_errinj.c
index 0f8718a33..005be380d 100644
--- a/test/unit/swim_errinj.c
+++ b/test/unit/swim_errinj.c
@@ -217,12 +217,12 @@ main_f(va_list ap)
(void) ap;
swim_test_ev_init();
- swim_test_transport_init();
+ fakenet_init();
swim_test_payload_refutation();
swim_test_indirect_ping();
- swim_test_transport_free();
+ fakenet_free();
swim_test_ev_free();
test_result = check_plan();
diff --git a/test/unit/swim_test_transport.c b/test/unit/swim_test_transport.c
index 855fb2d8e..a259addc9 100644
--- a/test/unit/swim_test_transport.c
+++ b/test/unit/swim_test_transport.c
@@ -52,14 +52,14 @@ enum {
};
static inline int
-swim_test_sockaddr_in_to_fd(const struct sockaddr_in *addr)
+fakenet_sockaddr_in_to_fd(const struct sockaddr_in *addr)
{
assert(addr->sin_family == AF_INET);
return ntohs(addr->sin_port) + FAKE_FD_BASE;
}
static inline void
-swim_test_fd_to_sockaddr_in(int fd, struct sockaddr_in *addr)
+fakenet_fd_to_sockaddr_in(int fd, struct sockaddr_in *addr)
{
*addr = (struct sockaddr_in){
.sin_family = AF_INET,
@@ -71,7 +71,7 @@ swim_test_fd_to_sockaddr_in(int fd, struct sockaddr_in *addr)
}
/** UDP packet wrapper. It is stored in send/recv queues. */
-struct swim_test_packet {
+struct fakenet_packet {
/** Source address. */
struct sockaddr_in src;
/** Destination address. */
@@ -85,12 +85,11 @@ struct swim_test_packet {
};
/** Wrap @a data into a new packet. */
-static inline struct swim_test_packet *
-swim_test_packet_new(const char *data, int size, const struct sockaddr_in *src,
- const struct sockaddr_in *dst)
+static inline struct fakenet_packet *
+fakenet_packet_new(const char *data, int size, const struct sockaddr_in *src,
+ const struct sockaddr_in *dst)
{
- struct swim_test_packet *p =
- (struct swim_test_packet *) malloc(sizeof(*p) + size);
+ struct fakenet_packet *p = malloc(sizeof(*p) + size);
assert(p != NULL);
rlist_create(&p->in_queue);
p->src = *src;
@@ -102,18 +101,18 @@ swim_test_packet_new(const char *data, int size, const struct sockaddr_in *src,
/** Free packet memory. */
static inline void
-swim_test_packet_delete(struct swim_test_packet *p)
+fakenet_packet_delete(struct fakenet_packet *p)
{
rlist_del_entry(p, in_queue);
free(p);
}
/** Fully duplicate a packet on new memory. */
-static inline struct swim_test_packet *
-swim_test_packet_dup(struct swim_test_packet *p)
+static inline struct fakenet_packet *
+fakenet_packet_dup(struct fakenet_packet *p)
{
- int size = sizeof(struct swim_test_packet) + p->size;
- struct swim_test_packet *res = (struct swim_test_packet *) malloc(size);
+ int size = sizeof(struct fakenet_packet) + p->size;
+ struct fakenet_packet *res = malloc(size);
assert(res != NULL);
memcpy(res, p, size);
rlist_create(&res->in_queue);
@@ -126,9 +125,9 @@ swim_test_packet_dup(struct swim_test_packet *p)
* filters in the list. If anyone wants to filter the packet out,
* then the packet is dropped.
*/
-struct swim_fd_filter {
+struct fakenet_filter {
/** A function to decide whether to drop a packet. */
- swim_test_filter_check_f check;
+ fakenet_filter_check_f check;
/**
* Arbitrary user data. Passed to each call of @a check.
*/
@@ -138,10 +137,10 @@ struct swim_fd_filter {
};
/** Create a new filter. */
-static inline struct swim_fd_filter *
-swim_fd_filter_new(swim_test_filter_check_f check, void *udata)
+static inline struct fakenet_filter *
+fakenet_filter_new(fakenet_filter_check_f check, void *udata)
{
- struct swim_fd_filter *f = (struct swim_fd_filter *) malloc(sizeof(*f));
+ struct fakenet_filter *f = malloc(sizeof(*f));
assert(f != NULL);
f->udata = udata;
f->check = check;
@@ -151,14 +150,14 @@ swim_fd_filter_new(swim_test_filter_check_f check, void *udata)
/** Delete @a filter and its data. */
static inline void
-swim_fd_filter_delete(struct swim_fd_filter *filter)
+fakenet_filter_delete(struct fakenet_filter *filter)
{
rlist_del_entry(filter, in_filters);
free(filter);
}
/** Fake file descriptor. */
-struct swim_fd {
+struct fakenet_fd {
/** File descriptor number visible to libev. */
int evfd;
/**
@@ -185,71 +184,70 @@ struct swim_fd {
};
/** Table of fake file descriptors. */
-static struct swim_fd swim_fd[FAKE_FD_NUMBER];
+static struct fakenet_fd fakenet_fd[FAKE_FD_NUMBER];
/**
* List of active file descriptors. Used to avoid fullscan of the
* table.
*/
-static RLIST_HEAD(swim_fd_active);
+static RLIST_HEAD(fakenet_fd_active);
/** Open a fake file descriptor. */
static inline int
-swim_fd_open(struct swim_fd *fd)
+fakenet_fd_open(struct fakenet_fd *fd)
{
if (fd->is_opened) {
errno = EADDRINUSE;
- diag_set(SocketError, "test_socket:1", "bind");
+ diag_set(SocketError, "fake_socket:1", "bind");
return -1;
}
assert(rlist_empty(&fd->filters));
fd->is_opened = true;
- rlist_add_tail_entry(&swim_fd_active, fd, in_active);
+ rlist_add_tail_entry(&fakenet_fd_active, fd, in_active);
return 0;
}
void
-swim_test_transport_remove_filter(int fd, swim_test_filter_check_f check)
+fakenet_remove_filter(int fd, fakenet_filter_check_f check)
{
- struct swim_fd *sfd = &swim_fd[fd - FAKE_FD_BASE];
+ struct fakenet_fd *sfd = &fakenet_fd[fd - FAKE_FD_BASE];
assert(sfd->is_opened);
- struct swim_fd_filter *f;
+ struct fakenet_filter *f;
rlist_foreach_entry(f, &sfd->filters, in_filters) {
if (check == f->check) {
- swim_fd_filter_delete(f);
+ fakenet_filter_delete(f);
return;
}
}
}
void
-swim_test_transport_add_filter(int fd, swim_test_filter_check_f check,
- void *udata)
+fakenet_add_filter(int fd, fakenet_filter_check_f check, void *udata)
{
- struct swim_fd *sfd = &swim_fd[fd - FAKE_FD_BASE];
+ struct fakenet_fd *sfd = &fakenet_fd[fd - FAKE_FD_BASE];
assert(sfd->is_opened);
- struct swim_fd_filter *f = swim_fd_filter_new(check, udata);
- swim_test_transport_remove_filter(fd, check);
+ struct fakenet_filter *f = fakenet_filter_new(check, udata);
+ fakenet_remove_filter(fd, check);
rlist_add_tail_entry(&sfd->filters, f, in_filters);
}
/** Send one packet to destination's recv queue. */
static inline void
-swim_fd_send_packet(struct swim_fd *fd);
+fakenet_fd_send_packet(struct fakenet_fd *fd);
/** Close a fake file descriptor. */
static inline void
-swim_fd_close(struct swim_fd *fd)
+fakenet_fd_close(struct fakenet_fd *fd)
{
if (! fd->is_opened)
return;
- struct swim_fd_filter *f, *f_tmp;
+ struct fakenet_filter *f, *f_tmp;
rlist_foreach_entry_safe(f, &fd->filters, in_filters, f_tmp)
- swim_fd_filter_delete(f);
- struct swim_test_packet *i, *tmp;
+ fakenet_filter_delete(f);
+ struct fakenet_packet *i, *tmp;
rlist_foreach_entry_safe(i, &fd->recv_queue, in_queue, tmp)
- swim_test_packet_delete(i);
+ fakenet_packet_delete(i);
while (! rlist_empty(&fd->send_queue))
- swim_fd_send_packet(fd);
+ fakenet_fd_send_packet(fd);
rlist_del_entry(fd, in_active);
fd->is_opened = false;
}
@@ -262,10 +260,10 @@ swim_fd_close(struct swim_fd *fd)
* @a dir.
*/
static inline bool
-swim_fd_test_if_drop(struct swim_fd *fd, const struct swim_test_packet *p,
+fakenet_test_if_drop(struct fakenet_fd *fd, const struct fakenet_packet *p,
int dir, int peer_fd)
{
- struct swim_fd_filter *f;
+ struct fakenet_filter *f;
rlist_foreach_entry(f, &fd->filters, in_filters) {
if (f->check(p->data, p->size, f->udata, dir, peer_fd))
return true;
@@ -274,31 +272,30 @@ swim_fd_test_if_drop(struct swim_fd *fd, const struct swim_test_packet *p,
}
void
-swim_test_transport_init(void)
+fakenet_init(void)
{
for (int i = 0, evfd = FAKE_FD_BASE; i < FAKE_FD_NUMBER; ++i, ++evfd) {
- rlist_create(&swim_fd[i].filters);
- swim_fd[i].evfd = evfd;
- 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);
+ rlist_create(&fakenet_fd[i].filters);
+ fakenet_fd[i].evfd = evfd;
+ fakenet_fd[i].is_opened = false;
+ rlist_create(&fakenet_fd[i].in_active);
+ rlist_create(&fakenet_fd[i].recv_queue);
+ rlist_create(&fakenet_fd[i].send_queue);
}
}
void
-swim_test_transport_free(void)
+fakenet_free(void)
{
- struct swim_test_packet *p, *tmp;
- for (int i = 0; i < (int)lengthof(swim_fd); ++i)
- swim_fd_close(&swim_fd[i]);
+ for (int i = 0; i < (int)lengthof(fakenet_fd); ++i)
+ fakenet_fd_close(&fakenet_fd[i]);
}
static void
-swim_test_close(int fd)
+fakenet_close(int fd)
{
assert(fd >= FAKE_FD_BASE);
- swim_fd_close(&swim_fd[fd - FAKE_FD_BASE]);
+ fakenet_fd_close(&fakenet_fd[fd - FAKE_FD_BASE]);
}
/**
@@ -306,8 +303,8 @@ swim_test_close(int fd)
* it on EV_WRITE event.
*/
static ssize_t
-swim_test_sendto(int fd, const void *data, size_t size,
- const struct sockaddr *addr, socklen_t addr_size)
+fakenet_sendto(int fd, const void *data, size_t size,
+ const struct sockaddr *addr, socklen_t addr_size)
{
/*
* Create packet. Put into sending queue.
@@ -315,11 +312,11 @@ swim_test_sendto(int fd, const void *data, size_t size,
(void) addr_size;
assert(addr->sa_family == AF_INET);
struct sockaddr_in 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[fd - FAKE_FD_BASE];
+ fakenet_fd_to_sockaddr_in(fd, &src_addr);
+ struct fakenet_packet *p =
+ fakenet_packet_new(data, size, &src_addr,
+ (const struct sockaddr_in *)addr);
+ struct fakenet_fd *src = &fakenet_fd[fd - FAKE_FD_BASE];
assert(src->is_opened);
rlist_add_tail_entry(&src->send_queue, p, in_queue);
return size;
@@ -330,40 +327,40 @@ swim_test_sendto(int fd, const void *data, size_t size,
* processed on EV_READ event.
*/
static ssize_t
-swim_test_recvfrom(int fd, void *buffer, size_t size, struct sockaddr *addr,
- socklen_t *addr_size)
+fakenet_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[fd - FAKE_FD_BASE];
+ struct fakenet_fd *dst = &fakenet_fd[fd - FAKE_FD_BASE];
assert(dst->is_opened);
- struct swim_test_packet *p =
- rlist_shift_entry(&dst->recv_queue, struct swim_test_packet,
+ struct fakenet_packet *p =
+ rlist_shift_entry(&dst->recv_queue, struct fakenet_packet,
in_queue);
*(struct sockaddr_in *) addr = p->src;
*addr_size = sizeof(p->src);
ssize_t result = MIN((size_t) p->size, size);
memcpy(buffer, p->data, result);
- swim_test_packet_delete(p);
+ fakenet_packet_delete(p);
return result;
}
static int
-swim_test_bind(int *fd, const struct sockaddr *addr, socklen_t addr_len)
+fakenet_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 new_fd = fakenet_sockaddr_in_to_fd(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)
+ if (fakenet_fd_open(&fakenet_fd[new_fd - FAKE_FD_BASE]) != 0)
return -1;
if (old_fd != -1)
- swim_test_close(old_fd);
+ fakenet_close(old_fd);
*fd = new_fd;
return 0;
}
@@ -373,14 +370,14 @@ 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);
+ 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 swim_test_recvfrom(transport->fd, buffer, size, addr, addr_size);
+ return fakenet_recvfrom(transport->fd, buffer, size, addr, addr_size);
}
int
@@ -388,7 +385,7 @@ 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)
+ if (fakenet_bind(&transport->fd, addr, addr_len) != 0)
return -1;
transport->addr = *(struct sockaddr_in *)addr;
return 0;
@@ -398,7 +395,7 @@ void
swim_transport_destroy(struct swim_transport *transport)
{
if (transport->fd != -1)
- swim_test_close(transport->fd);
+ fakenet_close(transport->fd);
}
void
@@ -409,19 +406,21 @@ swim_transport_create(struct swim_transport *transport)
}
void
-swim_test_transport_block_fd(int fd)
+fakenet_block(int fd)
{
- struct swim_fd *sfd = &swim_fd[fd - FAKE_FD_BASE];
- assert(! rlist_empty(&sfd->in_active));
+ assert(fd >= FAKE_FD_BASE);
+ struct fakenet_fd *sfd = &fakenet_fd[fd - FAKE_FD_BASE];
+ assert(!rlist_empty(&sfd->in_active));
rlist_del_entry(sfd, in_active);
}
void
-swim_test_transport_unblock_fd(int fd)
+fakenet_unblock(int fd)
{
- struct swim_fd *sfd = &swim_fd[fd - FAKE_FD_BASE];
+ assert(fd >= FAKE_FD_BASE);
+ struct fakenet_fd *sfd = &fakenet_fd[fd - FAKE_FD_BASE];
if (sfd->is_opened && rlist_empty(&sfd->in_active))
- rlist_add_tail_entry(&swim_fd_active, sfd, in_active);
+ rlist_add_tail_entry(&fakenet_fd_active, sfd, in_active);
}
/**
@@ -431,35 +430,35 @@ swim_test_transport_unblock_fd(int fd)
* drop rate is not 0.
*/
static inline void
-swim_move_packet(struct swim_fd *src, struct swim_fd *dst,
- struct swim_test_packet *p)
+fakenet_move_packet(struct fakenet_fd *src, struct fakenet_fd *dst,
+ struct fakenet_packet *p)
{
- if (dst->is_opened && !swim_fd_test_if_drop(dst, p, 0, src->evfd) &&
- !swim_fd_test_if_drop(src, p, 1, dst->evfd))
+ if (dst->is_opened && !fakenet_test_if_drop(dst, p, 0, src->evfd) &&
+ !fakenet_test_if_drop(src, p, 1, dst->evfd))
rlist_add_tail_entry(&dst->recv_queue, p, in_queue);
else
- swim_test_packet_delete(p);
+ fakenet_packet_delete(p);
}
static inline void
-swim_fd_send_packet(struct swim_fd *fd)
+fakenet_fd_send_packet(struct fakenet_fd *fd)
{
assert(! rlist_empty(&fd->send_queue));
- struct swim_fd *dst;
- struct swim_test_packet *dup, *p =
- rlist_shift_entry(&fd->send_queue, struct swim_test_packet,
+ struct fakenet_fd *dst;
+ struct fakenet_packet *dup, *p =
+ rlist_shift_entry(&fd->send_queue, struct fakenet_packet,
in_queue);
if (p->dst.sin_addr.s_addr == INADDR_BROADCAST &&
p->dst.sin_port == 0) {
- rlist_foreach_entry(dst, &swim_fd_active, in_active) {
- dup = swim_test_packet_dup(p);
- swim_move_packet(fd, dst, dup);
+ rlist_foreach_entry(dst, &fakenet_fd_active, in_active) {
+ dup = fakenet_packet_dup(p);
+ fakenet_move_packet(fd, dst, dup);
}
- swim_test_packet_delete(p);
+ fakenet_packet_delete(p);
} else {
- int fdnum = swim_test_sockaddr_in_to_fd(&p->dst);
- dst = &swim_fd[fdnum - FAKE_FD_BASE];
- swim_move_packet(fd, dst, p);
+ int fdnum = fakenet_sockaddr_in_to_fd(&p->dst);
+ dst = &fakenet_fd[fdnum - FAKE_FD_BASE];
+ fakenet_move_packet(fd, dst, p);
}
}
@@ -468,30 +467,30 @@ swim_fd_send_packet(struct swim_fd *fd)
* to send/recv.
*/
static inline void
-swim_test_transport_feed_events(struct ev_loop *loop)
+fakenet_feed_events(struct ev_loop *loop)
{
- struct swim_fd *fd;
+ struct fakenet_fd *fd;
/*
* Reversed because libev invokes events in reversed
* order. So this reverse + libev reverse = normal order.
*/
- rlist_foreach_entry_reverse(fd, &swim_fd_active, in_active) {
+ rlist_foreach_entry_reverse(fd, &fakenet_fd_active, in_active) {
if (! rlist_empty(&fd->send_queue))
- swim_fd_send_packet(fd);
+ fakenet_fd_send_packet(fd);
ev_feed_fd_event(loop, fd->evfd, EV_WRITE);
}
- rlist_foreach_entry_reverse(fd, &swim_fd_active, in_active) {
+ rlist_foreach_entry_reverse(fd, &fakenet_fd_active, in_active) {
if (!rlist_empty(&fd->recv_queue))
ev_feed_fd_event(loop, fd->evfd, EV_READ);
}
}
void
-swim_test_transport_do_loop_step(struct ev_loop *loop)
+fakenet_loop_update(struct ev_loop *loop)
{
do {
ev_invoke_pending(loop);
- swim_test_transport_feed_events(loop);
+ fakenet_feed_events(loop);
/*
* Just a single loop + invoke is not enough. At
* least two are necessary.
@@ -510,8 +509,8 @@ swim_test_transport_do_loop_step(struct ev_loop *loop)
} while (ev_pending_count(loop) > 0);
}
-int
-swim_getifaddrs(struct ifaddrs **ifaddrs)
+static int
+fakenet_getifaddrs(struct ifaddrs **ifaddrs)
{
/*
* This is a fake implementation of getifaddrs. It always
@@ -519,8 +518,7 @@ swim_getifaddrs(struct ifaddrs **ifaddrs)
* which is later used to send a packet to all the opened
* descriptors. Second is a dummy interface leading to
* nowhere. The latter is used just for testing that the
- * real SWIM code correctly iterates through the
- * interface list.
+ * real code correctly iterates through the interface list.
*/
int size = (sizeof(struct ifaddrs) + sizeof(struct sockaddr_in)) * 2;
struct ifaddrs *iface = (struct ifaddrs *) calloc(1, size);
@@ -543,8 +541,14 @@ swim_getifaddrs(struct ifaddrs **ifaddrs)
return 0;
}
-void
-swim_freeifaddrs(struct ifaddrs *ifaddrs)
+int
+swim_getifaddrs(struct ifaddrs **ifaddrs)
+{
+ return fakenet_getifaddrs(ifaddrs);
+}
+
+static void
+fakenet_freeifaddrs(struct ifaddrs *ifaddrs)
{
/*
* The whole list is packed into a single allocation
@@ -552,3 +556,9 @@ swim_freeifaddrs(struct ifaddrs *ifaddrs)
*/
free(ifaddrs);
}
+
+void
+swim_freeifaddrs(struct ifaddrs *ifaddrs)
+{
+ fakenet_freeifaddrs(ifaddrs);
+}
diff --git a/test/unit/swim_test_transport.h b/test/unit/swim_test_transport.h
index 6235278d0..1f754de00 100644
--- a/test/unit/swim_test_transport.h
+++ b/test/unit/swim_test_transport.h
@@ -34,10 +34,9 @@
struct ev_loop;
/**
- * SWIM test_transport implements a 'fake' file descriptors table
- * in user space in order to get the full control over UDP
- * sockets, used in core SWIM code. Fake fds are used to provide a
- * capability to set necessary loss level, delay, reorders.
+ * Fakenet implements a 'fake' file descriptors table in user space in order to
+ * get the full control over UDP sockets. Fake fds are used to provide means
+ * to set necessary loss level, delay, reorders, blocks.
*/
/**
@@ -49,8 +48,8 @@ struct ev_loop;
* parameter a sender/receiver descriptor number is passed
* depending on @a dir.
*/
-typedef bool (*swim_test_filter_check_f)(const char *data, int size,
- void *udata, int dir, int peer_fd);
+typedef bool (*fakenet_filter_check_f)(const char *data, int size, void *udata,
+ int dir, int peer_fd);
/**
* Until there are no new IO events, feed EV_WRITE event to all
@@ -59,18 +58,18 @@ typedef bool (*swim_test_filter_check_f)(const char *data, int size,
* from send to recv queues.
*/
void
-swim_test_transport_do_loop_step(struct ev_loop *loop);
+fakenet_loop_update(struct ev_loop *loop);
/**
* Block a file descriptor so as it can not receive nor send any
* packets.
*/
void
-swim_test_transport_block_fd(int fd);
+fakenet_block(int fd);
/** Unblock a file descriptor. */
void
-swim_test_transport_unblock_fd(int fd);
+fakenet_unblock(int fd);
/**
* Add a filter to the file descriptor @a fd. If a filter with
@@ -83,8 +82,7 @@ swim_test_transport_unblock_fd(int fd);
* invocation.
*/
void
-swim_test_transport_add_filter(int fd, swim_test_filter_check_f check,
- void *udata);
+fakenet_add_filter(int fd, fakenet_filter_check_f check, void *udata);
/**
* Remove a filter having @a check function. Works just like the
@@ -92,14 +90,14 @@ swim_test_transport_add_filter(int fd, swim_test_filter_check_f check,
* is found, then it is not an error.
*/
void
-swim_test_transport_remove_filter(int fd, swim_test_filter_check_f check);
+fakenet_remove_filter(int fd, fakenet_filter_check_f check);
-/** Initialize test transport system. */
+/** Initialize fake network system. */
void
-swim_test_transport_init(void);
+fakenet_init(void);
-/** Destroy test transport system, free resources. */
+/** Destroy fake network system, free resources. */
void
-swim_test_transport_free(void);
+fakenet_free(void);
#endif /* TARANTOOL_SWIM_TEST_TRANSPORT_H_INCLUDED */
diff --git a/test/unit/swim_test_utils.c b/test/unit/swim_test_utils.c
index 9dbd28a9f..ef35f2134 100644
--- a/test/unit/swim_test_utils.c
+++ b/test/unit/swim_test_utils.c
@@ -398,14 +398,14 @@ swim_cluster_restart_node(struct swim_cluster *cluster, int i)
void
swim_cluster_block_io(struct swim_cluster *cluster, int i)
{
- swim_test_transport_block_fd(swim_fd(cluster->node[i].swim));
+ fakenet_block(swim_fd(cluster->node[i].swim));
}
void
swim_cluster_unblock_io(struct swim_cluster *cluster, int i)
{
struct swim *s = swim_cluster_member(cluster, i);
- swim_test_transport_unblock_fd(swim_fd(s));
+ fakenet_unblock(swim_fd(s));
}
/** Create a new drop rate filter helper. */
@@ -447,12 +447,11 @@ swim_cluster_set_drop_generic(struct swim_cluster *cluster, int i,
struct swim_node *n = swim_cluster_node(cluster, i);
int fd = swim_fd(n->swim);
if (value == 0) {
- swim_test_transport_remove_filter(fd, swim_filter_drop_rate);
+ fakenet_remove_filter(fd, swim_filter_drop_rate);
return;
}
swim_drop_rate_create(&n->drop_rate, value, is_for_in, is_for_out);
- swim_test_transport_add_filter(fd, swim_filter_drop_rate,
- &n->drop_rate);
+ fakenet_add_filter(fd, swim_filter_drop_rate, &n->drop_rate);
}
void
@@ -509,9 +508,8 @@ swim_cluster_set_drop_channel(struct swim_cluster *cluster, int from_id,
return;
}
swim_drop_channel_add_fd(dc, to_fd);
- swim_test_transport_add_filter(swim_fd(from_node->swim),
- swim_filter_drop_channel,
- &from_node->drop_channel);
+ fakenet_add_filter(swim_fd(from_node->swim), swim_filter_drop_channel,
+ &from_node->drop_channel);
}
/** Check if @a s1 knows every member of @a s2's table. */
@@ -577,7 +575,7 @@ swim_wait_timeout(double timeout, struct swim_cluster *cluster,
* send immediately without preliminary timeouts or
* whatsoever.
*/
- swim_test_transport_do_loop_step(loop);
+ fakenet_loop_update(loop);
if (cluster != NULL)
swim_cluster_run_triggers(cluster);
while (! check(cluster, data)) {
@@ -589,7 +587,7 @@ swim_wait_timeout(double timeout, struct swim_cluster *cluster,
* some of them generated IO events. Process them
* too.
*/
- swim_test_transport_do_loop_step(loop);
+ fakenet_loop_update(loop);
if (cluster != NULL)
swim_cluster_run_triggers(cluster);
}
--
2.24.3 (Apple Git-128)
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Tarantool-patches] [PATCH 04/10] test: move fake network code to fakenet.c/.h files
2020-11-30 23:56 [Tarantool-patches] [PATCH 00/10] Raft module, part 3 - fake network and libev for Raft and SWIM Vladislav Shpilevoy
` (3 preceding siblings ...)
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 ` Vladislav Shpilevoy
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 05/10] test: factor out swim from " Vladislav Shpilevoy
` (7 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: Vladislav Shpilevoy @ 2020-11-30 23:56 UTC (permalink / raw)
To: tarantool-patches, sergepetrenko
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 moves all fake network code to separate files -
fakenet.c/.h, which are now easy to relocate to a new library.
These files still contain some swim methods, which are moved to
their own file in a separate commit. Because their file will be
swim_test_transport.c. But if they would be moved there in the
same commit, git would treat it like everything *except* the swim
methods was moved to fakenet.c/.h because of names clash. That
would destroy git history. So the swim code movement is split in 2
commits.
Part of #5303
---
test/unit/CMakeLists.txt | 6 +++---
test/unit/{swim_test_transport.c => fakenet.c} | 2 +-
test/unit/{swim_test_transport.h => fakenet.h} | 5 +----
test/unit/swim_test_ev.c | 1 -
test/unit/swim_test_utils.c | 1 -
test/unit/swim_test_utils.h | 2 +-
6 files changed, 6 insertions(+), 11 deletions(-)
rename test/unit/{swim_test_transport.c => fakenet.c} (99%)
rename test/unit/{swim_test_transport.h => fakenet.h} (95%)
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index e05466473..7c369740e 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 swim_test_transport.c swim_test_ev.c
+add_executable(swim.test swim.c fakenet.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 swim_test_transport.c swim_test_ev.c
+add_executable(swim_proto.test swim_proto.c fakenet.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 swim_test_transport.c
+add_executable(swim_errinj.test swim_errinj.c fakenet.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/swim_test_transport.c b/test/unit/fakenet.c
similarity index 99%
rename from test/unit/swim_test_transport.c
rename to test/unit/fakenet.c
index a259addc9..a8101194a 100644
--- a/test/unit/swim_test_transport.c
+++ b/test/unit/fakenet.c
@@ -28,7 +28,7 @@
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#include "swim_test_transport.h"
+#include "fakenet.h"
#include "swim/swim_transport.h"
#include "swim/swim_io.h"
#include "fiber.h"
diff --git a/test/unit/swim_test_transport.h b/test/unit/fakenet.h
similarity index 95%
rename from test/unit/swim_test_transport.h
rename to test/unit/fakenet.h
index 1f754de00..043c398ab 100644
--- a/test/unit/swim_test_transport.h
+++ b/test/unit/fakenet.h
@@ -1,5 +1,4 @@
-#ifndef TARANTOOL_SWIM_TEST_TRANSPORT_H_INCLUDED
-#define TARANTOOL_SWIM_TEST_TRANSPORT_H_INCLUDED
+#pragma once
/*
* Copyright 2010-2019, Tarantool AUTHORS, please see AUTHORS file.
*
@@ -99,5 +98,3 @@ fakenet_init(void);
/** Destroy fake network system, free resources. */
void
fakenet_free(void);
-
-#endif /* TARANTOOL_SWIM_TEST_TRANSPORT_H_INCLUDED */
diff --git a/test/unit/swim_test_ev.c b/test/unit/swim_test_ev.c
index 23d909b05..625b697d9 100644
--- a/test/unit/swim_test_ev.c
+++ b/test/unit/swim_test_ev.c
@@ -29,7 +29,6 @@
* SUCH DAMAGE.
*/
#include "swim_test_ev.h"
-#include "swim_test_transport.h"
#include "trivia/util.h"
#include "swim/swim_ev.h"
#include "tarantool_ev.h"
diff --git a/test/unit/swim_test_utils.c b/test/unit/swim_test_utils.c
index ef35f2134..6a3b6a685 100644
--- a/test/unit/swim_test_utils.c
+++ b/test/unit/swim_test_utils.c
@@ -30,7 +30,6 @@
*/
#include "swim_test_utils.h"
#include "swim_test_ev.h"
-#include "swim_test_transport.h"
#include "swim/swim_ev.h"
#include "uuid/tt_uuid.h"
#include "trivia/util.h"
diff --git a/test/unit/swim_test_utils.h b/test/unit/swim_test_utils.h
index ac86b6f72..ba1749a7e 100644
--- a/test/unit/swim_test_utils.h
+++ b/test/unit/swim_test_utils.h
@@ -38,7 +38,7 @@
#include "swim/swim.h"
#include "swim/swim_ev.h"
#include "swim/swim_proto.h"
-#include "swim_test_transport.h"
+#include "fakenet.h"
#include "swim_test_ev.h"
struct swim_cluster;
--
2.24.3 (Apple Git-128)
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Tarantool-patches] [PATCH 05/10] test: factor out swim from fakenet.c/.h files
2020-11-30 23:56 [Tarantool-patches] [PATCH 00/10] Raft module, part 3 - fake network and libev for Raft and SWIM Vladislav Shpilevoy
` (4 preceding siblings ...)
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 ` Vladislav Shpilevoy
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 06/10] fakesys: introduce fake system library Vladislav Shpilevoy
` (6 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: Vladislav Shpilevoy @ 2020-11-30 23:56 UTC (permalink / raw)
To: tarantool-patches, sergepetrenko
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)
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Tarantool-patches] [PATCH 06/10] fakesys: introduce fake system library
2020-11-30 23:56 [Tarantool-patches] [PATCH 00/10] Raft module, part 3 - fake network and libev for Raft and SWIM Vladislav Shpilevoy
` (5 preceding siblings ...)
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 05/10] test: factor out swim from " Vladislav Shpilevoy
@ 2020-11-30 23:56 ` Vladislav Shpilevoy
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 07/10] test: rename fake libev methods to fakeev Vladislav Shpilevoy
` (5 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: Vladislav Shpilevoy @ 2020-11-30 23:56 UTC (permalink / raw)
To: tarantool-patches, sergepetrenko
Fakesys is going to be a collection of fake implementations of
deep system things such as libev and libc.
The fake subsystems will provide API just like their original
counterparts (except for function names), but with full control of
their behaviour in user-space for the sake of unit testing.
This commit introduces first part of fakesys - a subset of libc
network API: sendto(), recvfrom(), bind(), close(), getifaddrs().
Main features of fakenet are:
- Integration with event loop via fakenet_loop_update(). Although
this could be also considered an issue if it will be ever
necessary to implement fake epoll, or sockets not bound to any
event loop;
- Filters to decide which packets to drop depending on their src,
dst, and content;
- Socket block to suspend packets delivery until the socket is
unblocked.
Fakenet implements connection-less API, for UDP sockets. This is
exactly what is needed in SWIM.
Raft fake transport will need reliable sockets with broadcast API.
Reliability can be ensured by setting drop rate to 0 (which is
default). Broadcast functionality is already present - there is a
broadcast interface in fakenet_getifaddrs() result.
Part of #5303
---
src/lib/CMakeLists.txt | 1 +
src/lib/fakesys/CMakeLists.txt | 7 +++++++
{test/unit => src/lib/fakesys}/fakenet.c | 0
{test/unit => src/lib/fakesys}/fakenet.h | 0
test/unit/CMakeLists.txt | 12 ++++++------
test/unit/swim_test_transport.c | 2 +-
test/unit/swim_test_utils.h | 2 +-
7 files changed, 16 insertions(+), 8 deletions(-)
create mode 100644 src/lib/fakesys/CMakeLists.txt
rename {test/unit => src/lib/fakesys}/fakenet.c (100%)
rename {test/unit => src/lib/fakesys}/fakenet.h (100%)
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index cabbe3d89..06f935f3e 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -15,6 +15,7 @@ add_subdirectory(swim)
add_subdirectory(mpstream)
add_subdirectory(vclock)
add_subdirectory(raft)
+add_subdirectory(fakesys)
if(ENABLE_BUNDLED_MSGPUCK)
add_subdirectory(msgpuck EXCLUDE_FROM_ALL)
endif()
diff --git a/src/lib/fakesys/CMakeLists.txt b/src/lib/fakesys/CMakeLists.txt
new file mode 100644
index 000000000..b4d6af817
--- /dev/null
+++ b/src/lib/fakesys/CMakeLists.txt
@@ -0,0 +1,7 @@
+set(lib_sources
+ fakenet.c
+)
+
+set_source_files_compile_flags(${lib_sources})
+add_library(fakesys STATIC ${lib_sources})
+target_link_libraries(fakesys core)
diff --git a/test/unit/fakenet.c b/src/lib/fakesys/fakenet.c
similarity index 100%
rename from test/unit/fakenet.c
rename to src/lib/fakesys/fakenet.c
diff --git a/test/unit/fakenet.h b/src/lib/fakesys/fakenet.h
similarity index 100%
rename from test/unit/fakenet.h
rename to src/lib/fakesys/fakenet.h
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index 00f5e89a3..e6a79e911 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -240,18 +240,18 @@ 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_transport.c swim_test_ev.c
+add_executable(swim.test swim.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)
+target_link_libraries(swim.test unit fakesys swim)
-add_executable(swim_proto.test swim_proto.c fakenet.c swim_test_transport.c swim_test_ev.c
+add_executable(swim_proto.test swim_proto.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)
+target_link_libraries(swim_proto.test unit fakesys swim)
-add_executable(swim_errinj.test swim_errinj.c fakenet.c swim_test_transport.c
+add_executable(swim_errinj.test swim_errinj.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)
+target_link_libraries(swim_errinj.test unit fakesys swim)
add_executable(merger.test merger.test.c)
target_link_libraries(merger.test unit core box)
diff --git a/test/unit/swim_test_transport.c b/test/unit/swim_test_transport.c
index d2c39da5b..c27603709 100644
--- a/test/unit/swim_test_transport.c
+++ b/test/unit/swim_test_transport.c
@@ -30,7 +30,7 @@
*/
#include <assert.h>
#include <string.h>
-#include "fakenet.h"
+#include "fakesys/fakenet.h"
#include "swim/swim_transport.h"
ssize_t
diff --git a/test/unit/swim_test_utils.h b/test/unit/swim_test_utils.h
index ba1749a7e..7a3a88c0b 100644
--- a/test/unit/swim_test_utils.h
+++ b/test/unit/swim_test_utils.h
@@ -38,7 +38,7 @@
#include "swim/swim.h"
#include "swim/swim_ev.h"
#include "swim/swim_proto.h"
-#include "fakenet.h"
+#include "fakesys/fakenet.h"
#include "swim_test_ev.h"
struct swim_cluster;
--
2.24.3 (Apple Git-128)
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Tarantool-patches] [PATCH 07/10] test: rename fake libev methods to fakeev
2020-11-30 23:56 [Tarantool-patches] [PATCH 00/10] Raft module, part 3 - fake network and libev for Raft and SWIM Vladislav Shpilevoy
` (6 preceding siblings ...)
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 06/10] fakesys: introduce fake system library Vladislav Shpilevoy
@ 2020-11-30 23:56 ` Vladislav Shpilevoy
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 08/10] test: move fake libev code to fakeev.c/.h files Vladislav Shpilevoy
` (4 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: Vladislav Shpilevoy @ 2020-11-30 23:56 UTC (permalink / raw)
To: tarantool-patches, sergepetrenko
SWIM unit tests contain a special library for emulating the event
loop: swim_test_ev. It provides API similar to libev, but
implemented entirely in user-space, including clock functions.
The latter is the most important point, as the original libev
does not allow to define your own timing functions - internally it
relies on select/kqueue/epoll/poll/select/... with true clock.
Because of that it is impossible to perform long tests with the
original libev, which could last for minutes or even tens of
seconds if their count is big. swim_test_ev uses virtual time,
where hours can be played in milliseconds.
The fake libev is going to be re-used for Raft unit tests. But for
that it is necessary to detach it from all SWIM dependencies.
--
This commit makes all swim_test_ev functions have 'fakeev' prefix
instead of 'swim'. The functions, implementing swim_ev.h API, are
kept as one-line proxies to the fakeev functions.
Part of #5303
---
test/unit/swim.c | 4 +-
test/unit/swim_errinj.c | 4 +-
test/unit/swim_test_ev.c | 185 +++++++++++++++++++++---------------
test/unit/swim_test_ev.h | 27 ++++--
test/unit/swim_test_utils.c | 10 +-
test/unit/swim_test_utils.h | 2 +-
6 files changed, 134 insertions(+), 98 deletions(-)
diff --git a/test/unit/swim.c b/test/unit/swim.c
index 1787745bc..a506d04e9 100644
--- a/test/unit/swim.c
+++ b/test/unit/swim.c
@@ -1077,7 +1077,7 @@ main_f(va_list ap)
swim_start_test(22);
(void) ap;
- swim_test_ev_init();
+ fakeev_init();
fakenet_init();
swim_test_one_link();
@@ -1104,7 +1104,7 @@ main_f(va_list ap)
swim_test_suspect_new_members();
fakenet_free();
- swim_test_ev_free();
+ fakeev_free();
test_result = check_plan();
footer();
diff --git a/test/unit/swim_errinj.c b/test/unit/swim_errinj.c
index 005be380d..00b59f63c 100644
--- a/test/unit/swim_errinj.c
+++ b/test/unit/swim_errinj.c
@@ -216,14 +216,14 @@ main_f(va_list ap)
swim_start_test(2);
(void) ap;
- swim_test_ev_init();
+ fakeev_init();
fakenet_init();
swim_test_payload_refutation();
swim_test_indirect_ping();
fakenet_free();
- swim_test_ev_free();
+ fakeev_free();
test_result = check_plan();
footer();
diff --git a/test/unit/swim_test_ev.c b/test/unit/swim_test_ev.c
index 625b697d9..6847836e3 100644
--- a/test/unit/swim_test_ev.c
+++ b/test/unit/swim_test_ev.c
@@ -48,18 +48,18 @@ static double watch = 0;
static int event_id = 0;
/**
- * SWIM testing event loop has two event types - natural libev
- * events like timer, and artificial like fake socket blocking.
+ * Fake event loop has two event types - natural libev events like timer, and
+ * artificial like fake socket blocking.
*/
-enum swim_event_type {
- SWIM_EVENT_TIMER,
- SWIM_EVENT_BRK,
+enum fakeev_event_type {
+ FAKEEV_EVENT_TIMER,
+ FAKEEV_EVENT_BRK,
};
-struct swim_event;
+struct fakeev_event;
-typedef void (*swim_event_process_f)(struct swim_event *, struct ev_loop *);
-typedef void (*swim_event_delete_f)(struct swim_event *);
+typedef void (*fakeev_event_process_f)(struct fakeev_event *, struct ev_loop *);
+typedef void (*fakeev_event_delete_f)(struct fakeev_event *);
/**
* An isolated event loop not visible to the fiber scheduler,
@@ -69,7 +69,7 @@ typedef void (*swim_event_delete_f)(struct swim_event *);
static struct ev_loop *test_loop;
struct ev_loop *
-swim_loop(void)
+fakeev_loop(void)
{
return test_loop;
}
@@ -78,9 +78,9 @@ swim_loop(void)
* Base event. It is stored in the event heap and virtualizes
* other events.
*/
-struct swim_event {
+struct fakeev_event {
/** Type, for assertions only. */
- enum swim_event_type type;
+ enum fakeev_event_type type;
/**
* When that event should be invoked according to the fake
* watch.
@@ -94,9 +94,9 @@ struct swim_event {
* Process the event. Usually the event is deleted right
* after that.
*/
- swim_event_process_f process;
+ fakeev_event_process_f process;
/** Just delete the event. Called on event heap reset. */
- swim_event_delete_f delete;
+ fakeev_event_delete_f delete;
};
/**
@@ -104,7 +104,7 @@ struct swim_event {
* deadline and the smallest ID in that deadline.
*/
static inline bool
-swim_event_less(const struct swim_event *e1, const struct swim_event *e2)
+fakeev_event_less(const struct fakeev_event *e1, const struct fakeev_event *e2)
{
if (e1->deadline == e2->deadline)
return e1->id < e2->id;
@@ -112,8 +112,8 @@ swim_event_less(const struct swim_event *e1, const struct swim_event *e2)
}
#define HEAP_NAME event_heap
-#define HEAP_LESS(h, e1, e2) swim_event_less(e1, e2)
-#define heap_value_t struct swim_event
+#define HEAP_LESS(h, e1, e2) fakeev_event_less(e1, e2)
+#define heap_value_t struct fakeev_event
#define heap_value_attr in_event_heap
#include "salad/heap.h"
@@ -125,15 +125,15 @@ static struct mh_i64ptr_t *events_hash;
/**
* Create a new event which should call @a process after @a delay
- * fake seconds. @A delete is called explicitly when the event
- * is deleted by SWIM explicitly, and when the event heap is
- * reset.
+ * fake seconds. @A delete is called to free the event when it is
+ * done, and when the event heap is reset.
*/
static void
-swim_event_create(struct swim_event *e, enum swim_event_type type, double delay,
- swim_event_process_f process, swim_event_delete_f delete)
+fakeev_event_create(struct fakeev_event *e, enum fakeev_event_type type,
+ double delay, fakeev_event_process_f process,
+ fakeev_event_delete_f delete)
{
- e->deadline = swim_time() + delay;
+ e->deadline = fakeev_time() + delay;
e->id = event_id++;
e->process = process;
e->delete = delete;
@@ -143,34 +143,34 @@ swim_event_create(struct swim_event *e, enum swim_event_type type, double delay,
/** Destroy a basic event. */
static inline void
-swim_event_destroy(struct swim_event *e)
+fakeev_event_destroy(struct fakeev_event *e)
{
event_heap_delete(&event_heap, e);
}
/** Destroy a event and free its resources. */
static inline void
-swim_event_delete(struct swim_event *e)
+fakeev_event_delete(struct fakeev_event *e)
{
e->delete(e);
}
/** Find an event by @a watcher. */
-static struct swim_event *
-swim_event_by_ev(struct ev_watcher *watcher)
+static struct fakeev_event *
+fakeev_event_by_ev(struct ev_watcher *watcher)
{
mh_int_t rc = mh_i64ptr_find(events_hash, (uint64_t) watcher, NULL);
if (rc == mh_end(events_hash))
return NULL;
- return (struct swim_event *) mh_i64ptr_node(events_hash, rc)->val;
+ return mh_i64ptr_node(events_hash, rc)->val;
}
/** Timer event generated by libev. */
-struct swim_timer_event {
- struct swim_event base;
+struct fakeev_timer_event {
+ struct fakeev_event base;
/**
* Libev watcher. Used to store callback and to find the
- * event by watcher pointer. It is necessary because SWIM
+ * event by watcher pointer. It is necessary because real code
* operates by libev watchers.
*/
struct ev_watcher *watcher;
@@ -178,45 +178,45 @@ struct swim_timer_event {
/** Destroy a timer event and free its resources. */
static void
-swim_timer_event_delete(struct swim_event *e)
+fakeev_timer_event_delete(struct fakeev_event *e)
{
- assert(e->type == SWIM_EVENT_TIMER);
- struct swim_timer_event *te = (struct swim_timer_event *) e;
+ assert(e->type == FAKEEV_EVENT_TIMER);
+ struct fakeev_timer_event *te = (struct fakeev_timer_event *)e;
mh_int_t rc = mh_i64ptr_find(events_hash, (uint64_t) te->watcher, NULL);
assert(rc != mh_end(events_hash));
mh_i64ptr_del(events_hash, rc, NULL);
- swim_event_destroy(e);
+ fakeev_event_destroy(e);
free(te);
}
/** Create a new timer event. */
static void
-swim_timer_event_new(struct ev_watcher *watcher, double delay);
+fakeev_timer_event_new(struct ev_watcher *watcher, double delay);
/** Process a timer event and delete it. */
static void
-swim_timer_event_process(struct swim_event *e, struct ev_loop *loop)
+fakeev_timer_event_process(struct fakeev_event *e, struct ev_loop *loop)
{
- assert(e->type == SWIM_EVENT_TIMER);
- struct ev_watcher *w = ((struct swim_timer_event *) e)->watcher;
+ assert(e->type == FAKEEV_EVENT_TIMER);
+ struct ev_watcher *w = ((struct fakeev_timer_event *)e)->watcher;
struct ev_timer *t = (struct ev_timer *) w;
- swim_timer_event_delete(e);
+ fakeev_timer_event_delete(e);
t->at = 0;
if (t->repeat > 0)
- swim_timer_event_new(w, t->repeat);
+ fakeev_timer_event_new(w, t->repeat);
ev_invoke(loop, w, EV_TIMER);
}
static void
-swim_timer_event_new(struct ev_watcher *watcher, double delay)
+fakeev_timer_event_new(struct ev_watcher *watcher, double delay)
{
- struct swim_timer_event *e =
- (struct swim_timer_event *) malloc(sizeof(*e));
+ struct fakeev_timer_event *e = malloc(sizeof(*e));
assert(e != NULL);
- swim_event_create(&e->base, SWIM_EVENT_TIMER, delay,
- swim_timer_event_process, swim_timer_event_delete);
+ fakeev_event_create(&e->base, FAKEEV_EVENT_TIMER, delay,
+ fakeev_timer_event_process,
+ fakeev_timer_event_delete);
e->watcher = watcher;
- assert(swim_event_by_ev(watcher) == NULL);
+ assert(fakeev_event_by_ev(watcher) == NULL);
struct mh_i64ptr_node_t node = {(uint64_t) watcher, e};
mh_int_t rc = mh_i64ptr_put(events_hash, &node, NULL, NULL);
(void) rc;
@@ -227,19 +227,19 @@ swim_timer_event_new(struct ev_watcher *watcher, double delay)
* Breakpoint event for debug. It does nothing but stops the event
* loop after a timeout to allow highlevel API to check some
* cases. The main feature is that a test can choose that timeout,
- * while natural SWIM events usually are out of control. That
+ * while natural events usually are out of control. That
* events allows to check conditions between natural events.
*/
-struct swim_brk_event {
- struct swim_event base;
+struct fakeev_brk_event {
+ struct fakeev_event base;
};
/** Delete a breakpoint event. */
static void
-swim_brk_event_delete(struct swim_event *e)
+fakeev_brk_event_delete(struct fakeev_event *e)
{
- assert(e->type == SWIM_EVENT_BRK);
- swim_event_destroy(e);
+ assert(e->type == FAKEEV_EVENT_BRK);
+ fakeev_event_destroy(e);
free(e);
}
@@ -247,25 +247,24 @@ swim_brk_event_delete(struct swim_event *e)
* Breakpoint event processing is nothing but the event deletion.
*/
static void
-swim_brk_event_process(struct swim_event *e, struct ev_loop *loop)
+fakeev_brk_event_process(struct fakeev_event *e, struct ev_loop *loop)
{
(void) loop;
- assert(e->type == SWIM_EVENT_BRK);
- swim_brk_event_delete(e);
+ assert(e->type == FAKEEV_EVENT_BRK);
+ fakeev_brk_event_delete(e);
}
void
-swim_ev_set_brk(double delay)
+fakeev_set_brk(double delay)
{
- struct swim_brk_event *e = (struct swim_brk_event *) malloc(sizeof(*e));
+ struct fakeev_brk_event *e = malloc(sizeof(*e));
assert(e != NULL);
- swim_event_create(&e->base, SWIM_EVENT_BRK, delay,
- swim_brk_event_process, swim_brk_event_delete);
+ fakeev_event_create(&e->base, FAKEEV_EVENT_BRK, delay,
+ fakeev_brk_event_process, fakeev_brk_event_delete);
}
-/** Implementation of global time visible in SWIM. */
double
-swim_time(void)
+fakeev_time(void)
{
return watch;
}
@@ -275,44 +274,44 @@ swim_time(void)
* already started - nothing happens.
*/
void
-swim_ev_timer_start(struct ev_loop *loop, struct ev_timer *base)
+fakeev_timer_start(struct ev_loop *loop, struct ev_timer *base)
{
(void) loop;
- if (swim_event_by_ev((struct ev_watcher *) base) != NULL)
+ if (fakeev_event_by_ev((struct ev_watcher *)base) != NULL)
return;
/* Create the periodic watcher and one event. */
- swim_timer_event_new((struct ev_watcher *) base, base->at);
+ fakeev_timer_event_new((struct ev_watcher *)base, base->at);
}
void
-swim_ev_timer_again(struct ev_loop *loop, struct ev_timer *base)
+fakeev_timer_again(struct ev_loop *loop, struct ev_timer *base)
{
(void) loop;
- if (swim_event_by_ev((struct ev_watcher *) base) != NULL)
+ if (fakeev_event_by_ev((struct ev_watcher *)base) != NULL)
return;
/* Create the periodic watcher and one event. */
- swim_timer_event_new((struct ev_watcher *) base, base->repeat);
+ fakeev_timer_event_new((struct ev_watcher *)base, base->repeat);
}
/** Time stop cancels the event if the timer is active. */
void
-swim_ev_timer_stop(struct ev_loop *loop, struct ev_timer *base)
+fakeev_timer_stop(struct ev_loop *loop, struct ev_timer *base)
{
(void) loop;
/*
* Delete the watcher and its events. Should be only one.
*/
- struct swim_event *e = swim_event_by_ev((struct ev_watcher *) base);
+ struct fakeev_event *e = fakeev_event_by_ev((struct ev_watcher *)base);
if (e == NULL)
return;
- swim_event_delete(e);
+ fakeev_event_delete(e);
}
/** Process all the events with the next nearest deadline. */
void
-swim_test_ev_do_loop_step(struct ev_loop *loop)
+fakeev_loop_update(struct ev_loop *loop)
{
- struct swim_event *e = event_heap_top(&event_heap);
+ struct fakeev_event *e = event_heap_top(&event_heap);
if (e != NULL) {
assert(e->deadline >= watch);
/* Multiple events can have the same deadline. */
@@ -326,18 +325,18 @@ swim_test_ev_do_loop_step(struct ev_loop *loop)
}
void
-swim_test_ev_reset(void)
+fakeev_reset(void)
{
- struct swim_event *e;
+ struct fakeev_event *e;
while ((e = event_heap_top(&event_heap)) != NULL)
- swim_event_delete(e);
+ fakeev_event_delete(e);
assert(mh_size(events_hash) == 0);
event_id = 0;
watch = 0;
}
void
-swim_test_ev_init(void)
+fakeev_init(void)
{
events_hash = mh_i64ptr_new();
assert(events_hash != NULL);
@@ -347,10 +346,40 @@ swim_test_ev_init(void)
}
void
-swim_test_ev_free(void)
+fakeev_free(void)
{
- swim_test_ev_reset();
+ fakeev_reset();
event_heap_destroy(&event_heap);
mh_i64ptr_delete(events_hash);
ev_loop_destroy(test_loop);
}
+
+double
+swim_time(void)
+{
+ return fakeev_time();
+}
+
+void
+swim_ev_timer_start(struct ev_loop *loop, struct ev_timer *watcher)
+{
+ return fakeev_timer_start(loop, watcher);
+}
+
+void
+swim_ev_timer_again(struct ev_loop *loop, struct ev_timer *watcher)
+{
+ return fakeev_timer_again(loop, watcher);
+}
+
+void
+swim_ev_timer_stop(struct ev_loop *loop, struct ev_timer *watcher)
+{
+ return fakeev_timer_stop(loop, watcher);
+}
+
+struct ev_loop *
+swim_loop(void)
+{
+ return fakeev_loop();
+}
diff --git a/test/unit/swim_test_ev.h b/test/unit/swim_test_ev.h
index bc925a859..d93b149de 100644
--- a/test/unit/swim_test_ev.h
+++ b/test/unit/swim_test_ev.h
@@ -33,10 +33,9 @@
struct ev_loop;
/**
- * SWIM test_ev implements a 'fake' event loop with bogus clock to
- * speed up events processing while keeping SWIM unaware that it
- * works in a simulation. Libev is used a little, just to store
- * some IO events.
+ * Fakeev implements a 'fake' event loop with bogus clock to speed up events
+ * processing while keeping the real code unaware that it works in a simulation.
+ * Libev is used a little, just to store some IO events.
*
* The test event loop works as follows. It has a global watch and
* a heap of events sorted by deadlines. An event is either a
@@ -46,7 +45,7 @@ struct ev_loop;
* and equal deadline, and sets the global watch with the deadline
* value. It simulates time flow. All the events with that
* deadline are processed. An event processing usually means
- * calling a libev callback set by a SWIM instance beforehand.
+ * calling a libev callback set by real code beforehand.
*
* For example, if event deadlines and the watch are:
*
@@ -82,11 +81,19 @@ struct ev_loop;
/** Initialize test event processing system. */
void
-swim_test_ev_init(void);
+fakeev_init(void);
/** Destroy test event processing system, free resources. */
void
-swim_test_ev_free(void);
+fakeev_free(void);
+
+/** Implementation of global time visible as real time in the tested code. */
+double
+fakeev_time(void);
+
+/** Global loop used by the fake events. */
+struct ev_loop *
+fakeev_loop(void);
/**
* Stop the event loop after @a delay fake seconds. It does not
@@ -94,14 +101,14 @@ swim_test_ev_free(void);
* times.
*/
void
-swim_ev_set_brk(double delay);
+fakeev_set_brk(double delay);
/** Play one step of event loop, process generated events. */
void
-swim_test_ev_do_loop_step(struct ev_loop *loop);
+fakeev_loop_update(struct ev_loop *loop);
/** Destroy pending events, reset global watch. */
void
-swim_test_ev_reset(void);
+fakeev_reset(void);
#endif /* TARANTOOL_SWIM_TEST_EV_H_INCLUDED */
diff --git a/test/unit/swim_test_utils.c b/test/unit/swim_test_utils.c
index 6a3b6a685..c9d92a704 100644
--- a/test/unit/swim_test_utils.c
+++ b/test/unit/swim_test_utils.c
@@ -565,9 +565,9 @@ static int
swim_wait_timeout(double timeout, struct swim_cluster *cluster,
swim_loop_check_f check, void *data)
{
- swim_ev_set_brk(timeout);
- double deadline = swim_time() + timeout;
- struct ev_loop *loop = swim_loop();
+ fakeev_set_brk(timeout);
+ double deadline = fakeev_time() + timeout;
+ struct ev_loop *loop = fakeev_loop();
/*
* There can be pending out of bound IO events, affecting
* the result. For example, 'quit' messages, which are
@@ -578,9 +578,9 @@ swim_wait_timeout(double timeout, struct swim_cluster *cluster,
if (cluster != NULL)
swim_cluster_run_triggers(cluster);
while (! check(cluster, data)) {
- if (swim_time() >= deadline)
+ if (fakeev_time() >= deadline)
return -1;
- swim_test_ev_do_loop_step(loop);
+ fakeev_loop_update(loop);
/*
* After events are processed, it is possible that
* some of them generated IO events. Process them
diff --git a/test/unit/swim_test_utils.h b/test/unit/swim_test_utils.h
index 7a3a88c0b..0f0051edd 100644
--- a/test/unit/swim_test_utils.h
+++ b/test/unit/swim_test_utils.h
@@ -259,7 +259,7 @@ swim_run_test(const char *log_file, fiber_func test);
#define swim_finish_test() { \
say_verbose("-------- SWIM end test %s --------", __func__); \
- swim_test_ev_reset(); \
+ fakeev_reset(); \
check_plan(); \
footer(); \
}
--
2.24.3 (Apple Git-128)
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Tarantool-patches] [PATCH 08/10] test: move fake libev code to fakeev.c/.h files
2020-11-30 23:56 [Tarantool-patches] [PATCH 00/10] Raft module, part 3 - fake network and libev for Raft and SWIM Vladislav Shpilevoy
` (7 preceding siblings ...)
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 07/10] test: rename fake libev methods to fakeev Vladislav Shpilevoy
@ 2020-11-30 23:56 ` Vladislav Shpilevoy
2020-11-30 23:56 ` [Tarantool-patches] [PATCH 09/10] test: factor out swim from fakeev.h/.c files Vladislav Shpilevoy
` (3 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: Vladislav Shpilevoy @ 2020-11-30 23:56 UTC (permalink / raw)
To: tarantool-patches, sergepetrenko
SWIM unit tests contain a special library for emulating the event
loop: swim_test_ev. It provides API similar to libev, but
implemented entirely in user-space, including clock functions.
The latter is the most important point, as the original libev
does not allow to define your own timing functions - internally it
relies on select/kqueue/epoll/poll/select/... with true clock.
Because of that it is impossible to perform long tests with the
original libev, which could last for minutes or even tens of
seconds if their count is big. swim_test_ev uses virtual time,
where hours can be played in milliseconds.
The fake libev is going to be re-used for Raft unit tests. But for
that it is necessary to detach it from all SWIM dependencies.
--
The patch renames swim_test_ev.c/.h to fakeev.c/.h because they
will contain only fakeev functions soon.
The swim methods, implementing swim_ev.h via fakeev, are moved to
their own file in a separate commit. Because their file will be
swim_test_ev.c. If they would be moved here, git would treat it
like everything *except* swim functions was moved to fakeev.h/.c.
It would ruin git history, and is split in 2 commits to avoid
this.
Part of #5303
---
test/unit/CMakeLists.txt | 6 +++---
test/unit/{swim_test_ev.c => fakeev.c} | 2 +-
test/unit/{swim_test_ev.h => fakeev.h} | 5 +----
test/unit/swim_test_utils.c | 1 -
test/unit/swim_test_utils.h | 2 +-
5 files changed, 6 insertions(+), 10 deletions(-)
rename test/unit/{swim_test_ev.c => fakeev.c} (99%)
rename test/unit/{swim_test_ev.h => fakeev.h} (96%)
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index e6a79e911..436178280 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -240,16 +240,16 @@ 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 swim_test_transport.c swim_test_ev.c
+add_executable(swim.test swim.c swim_test_transport.c fakeev.c
swim_test_utils.c ${PROJECT_SOURCE_DIR}/src/version.c core_test_utils.c)
target_link_libraries(swim.test unit fakesys swim)
-add_executable(swim_proto.test swim_proto.c swim_test_transport.c swim_test_ev.c
+add_executable(swim_proto.test swim_proto.c swim_test_transport.c fakeev.c
swim_test_utils.c ${PROJECT_SOURCE_DIR}/src/version.c core_test_utils.c)
target_link_libraries(swim_proto.test unit fakesys swim)
add_executable(swim_errinj.test swim_errinj.c swim_test_transport.c
- swim_test_ev.c swim_test_utils.c
+ fakeev.c swim_test_utils.c
${PROJECT_SOURCE_DIR}/src/version.c core_test_utils.c)
target_link_libraries(swim_errinj.test unit fakesys swim)
diff --git a/test/unit/swim_test_ev.c b/test/unit/fakeev.c
similarity index 99%
rename from test/unit/swim_test_ev.c
rename to test/unit/fakeev.c
index 6847836e3..20de35d7f 100644
--- a/test/unit/swim_test_ev.c
+++ b/test/unit/fakeev.c
@@ -28,7 +28,7 @@
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#include "swim_test_ev.h"
+#include "fakeev.h"
#include "trivia/util.h"
#include "swim/swim_ev.h"
#include "tarantool_ev.h"
diff --git a/test/unit/swim_test_ev.h b/test/unit/fakeev.h
similarity index 96%
rename from test/unit/swim_test_ev.h
rename to test/unit/fakeev.h
index d93b149de..b50fe5b3d 100644
--- a/test/unit/swim_test_ev.h
+++ b/test/unit/fakeev.h
@@ -1,5 +1,4 @@
-#ifndef TARANTOOL_SWIM_TEST_EV_H_INCLUDED
-#define TARANTOOL_SWIM_TEST_EV_H_INCLUDED
+#pragma once
/*
* Copyright 2010-2019, Tarantool AUTHORS, please see AUTHORS file.
*
@@ -110,5 +109,3 @@ fakeev_loop_update(struct ev_loop *loop);
/** Destroy pending events, reset global watch. */
void
fakeev_reset(void);
-
-#endif /* TARANTOOL_SWIM_TEST_EV_H_INCLUDED */
diff --git a/test/unit/swim_test_utils.c b/test/unit/swim_test_utils.c
index c9d92a704..708889460 100644
--- a/test/unit/swim_test_utils.c
+++ b/test/unit/swim_test_utils.c
@@ -29,7 +29,6 @@
* SUCH DAMAGE.
*/
#include "swim_test_utils.h"
-#include "swim_test_ev.h"
#include "swim/swim_ev.h"
#include "uuid/tt_uuid.h"
#include "trivia/util.h"
diff --git a/test/unit/swim_test_utils.h b/test/unit/swim_test_utils.h
index 0f0051edd..665423a03 100644
--- a/test/unit/swim_test_utils.h
+++ b/test/unit/swim_test_utils.h
@@ -39,7 +39,7 @@
#include "swim/swim_ev.h"
#include "swim/swim_proto.h"
#include "fakesys/fakenet.h"
-#include "swim_test_ev.h"
+#include "fakeev.h"
struct swim_cluster;
--
2.24.3 (Apple Git-128)
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Tarantool-patches] [PATCH 09/10] test: factor out swim from fakeev.h/.c files
2020-11-30 23:56 [Tarantool-patches] [PATCH 00/10] Raft module, part 3 - fake network and libev for Raft and SWIM Vladislav Shpilevoy
` (8 preceding siblings ...)
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 ` 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
` (2 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: Vladislav Shpilevoy @ 2020-11-30 23:56 UTC (permalink / raw)
To: tarantool-patches, sergepetrenko
SWIM unit tests contain a special library for emulating the event
loop: swim_test_ev. It provides API similar to libev, but
implemented entirely in user-space, including clock functions.
The latter is the most important point, as the original libev
does not allow to define your own timing functions - internally it
relies on select/kqueue/epoll/poll/select/... with true clock.
Because of that it is impossible to perform long tests with the
original libev, which could last for minutes or even tens of
seconds if their count is big. swim_test_ev uses virtual time,
where hours can be played in milliseconds.
--
This commit extracts all swim code to swim_test_ev.c. Now this
file is nothing but an implementation of swim_ev.h on top of
fakeev API.
Fakeev, in turn, does not depend on SWIM anymore, and can be moved
to fakesys library.
Part of #5303
---
test/unit/CMakeLists.txt | 6 ++--
test/unit/fakeev.c | 35 -----------------------
test/unit/fakeev.h | 13 +++++++++
test/unit/swim_test_ev.c | 62 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 78 insertions(+), 38 deletions(-)
create mode 100644 test/unit/swim_test_ev.c
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index 436178280..7f64f9685 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -240,16 +240,16 @@ 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 swim_test_transport.c fakeev.c
+add_executable(swim.test swim.c swim_test_transport.c fakeev.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 fakesys swim)
-add_executable(swim_proto.test swim_proto.c swim_test_transport.c fakeev.c
+add_executable(swim_proto.test swim_proto.c swim_test_transport.c fakeev.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 fakesys swim)
add_executable(swim_errinj.test swim_errinj.c swim_test_transport.c
- fakeev.c swim_test_utils.c
+ fakeev.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 fakesys swim)
diff --git a/test/unit/fakeev.c b/test/unit/fakeev.c
index 20de35d7f..20fab916b 100644
--- a/test/unit/fakeev.c
+++ b/test/unit/fakeev.c
@@ -30,7 +30,6 @@
*/
#include "fakeev.h"
#include "trivia/util.h"
-#include "swim/swim_ev.h"
#include "tarantool_ev.h"
#define HEAP_FORWARD_DECLARATION
#include "salad/heap.h"
@@ -269,10 +268,6 @@ fakeev_time(void)
return watch;
}
-/**
- * Start of a timer generates a delayed event. If a timer is
- * already started - nothing happens.
- */
void
fakeev_timer_start(struct ev_loop *loop, struct ev_timer *base)
{
@@ -353,33 +348,3 @@ fakeev_free(void)
mh_i64ptr_delete(events_hash);
ev_loop_destroy(test_loop);
}
-
-double
-swim_time(void)
-{
- return fakeev_time();
-}
-
-void
-swim_ev_timer_start(struct ev_loop *loop, struct ev_timer *watcher)
-{
- return fakeev_timer_start(loop, watcher);
-}
-
-void
-swim_ev_timer_again(struct ev_loop *loop, struct ev_timer *watcher)
-{
- return fakeev_timer_again(loop, watcher);
-}
-
-void
-swim_ev_timer_stop(struct ev_loop *loop, struct ev_timer *watcher)
-{
- return fakeev_timer_stop(loop, watcher);
-}
-
-struct ev_loop *
-swim_loop(void)
-{
- return fakeev_loop();
-}
diff --git a/test/unit/fakeev.h b/test/unit/fakeev.h
index b50fe5b3d..89954b2e1 100644
--- a/test/unit/fakeev.h
+++ b/test/unit/fakeev.h
@@ -30,6 +30,7 @@
* SUCH DAMAGE.
*/
struct ev_loop;
+struct ev_timer;
/**
* Fakeev implements a 'fake' event loop with bogus clock to speed up events
@@ -94,6 +95,18 @@ fakeev_time(void);
struct ev_loop *
fakeev_loop(void);
+/** Emulator of ev_timer_start(). */
+void
+fakeev_timer_start(struct ev_loop *loop, struct ev_timer *base);
+
+/** Emulator of ev_timer_again(). */
+void
+fakeev_timer_again(struct ev_loop *loop, struct ev_timer *base);
+
+/** Emulator of ev_timer_stop(). */
+void
+fakeev_timer_stop(struct ev_loop *loop, struct ev_timer *base);
+
/**
* Stop the event loop after @a delay fake seconds. It does not
* affect other events, so the loop can stop earlier multiple
diff --git a/test/unit/swim_test_ev.c b/test/unit/swim_test_ev.c
new file mode 100644
index 000000000..876aa4eea
--- /dev/null
+++ b/test/unit/swim_test_ev.c
@@ -0,0 +1,62 @@
+/*
+ * 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 "swim/swim_ev.h"
+#include "fakeev.h"
+
+double
+swim_time(void)
+{
+ return fakeev_time();
+}
+
+void
+swim_ev_timer_start(struct ev_loop *loop, struct ev_timer *watcher)
+{
+ return fakeev_timer_start(loop, watcher);
+}
+
+void
+swim_ev_timer_again(struct ev_loop *loop, struct ev_timer *watcher)
+{
+ return fakeev_timer_again(loop, watcher);
+}
+
+void
+swim_ev_timer_stop(struct ev_loop *loop, struct ev_timer *watcher)
+{
+ return fakeev_timer_stop(loop, watcher);
+}
+
+struct ev_loop *
+swim_loop(void)
+{
+ return fakeev_loop();
+}
--
2.24.3 (Apple Git-128)
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Tarantool-patches] [PATCH 00/10] Raft module, part 3 - fake network and libev for Raft and SWIM
2020-11-30 23:56 [Tarantool-patches] [PATCH 00/10] Raft module, part 3 - fake network and libev for Raft and SWIM Vladislav Shpilevoy
` (9 preceding siblings ...)
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 ` Serge Petrenko
2020-12-01 22:33 ` Vladislav Shpilevoy
2020-12-04 0:35 ` Alexander V. Tikhonov
12 siblings, 0 replies; 15+ messages in thread
From: Serge Petrenko @ 2020-12-01 13:42 UTC (permalink / raw)
To: Vladislav Shpilevoy, tarantool-patches
01.12.2020 02:56, Vladislav Shpilevoy пишет:
> The patchset is a third part of Raft relocation to a new module for the sake of
> unit testing. This part extracts fake network and libev libraries from SWIM unit
> tests to a new library fakesys, which will be used by Raft.
>
> The patchset only moves the existing code. For the actual Raft tests it is
> likely I will add some new Raft-specific code, and probably will generalize
> something from swim_test_utils.h/.c.
>
> Branch: http://github.com/tarantool/tarantool/tree/gerold103/gh-5303-p3-fakesys
> Issue: https://github.com/tarantool/tarantool/issues/5303
Hi! Thanks for the patchset!
LGTM.
> Vladislav Shpilevoy (10):
> test: stop using swim_transport.addr as in-param
> test: factor out swim from libc emulation funcs
> test: rename fake libc network methods to fakenet
> test: move fake network code to fakenet.c/.h files
> test: factor out swim from fakenet.c/.h files
> fakesys: introduce fake system library
> test: rename fake libev methods to fakeev
> test: move fake libev code to fakeev.c/.h files
> test: factor out swim from fakeev.h/.c files
> fakesys: move fakeev to fakesys library
>
> src/lib/CMakeLists.txt | 1 +
> src/lib/fakesys/CMakeLists.txt | 8 +
> src/lib/fakesys/fakeev.c | 350 ++++++++++++
> .../lib/fakesys/fakeev.h | 45 +-
> src/lib/fakesys/fakenet.c | 502 ++++++++++++++++++
> .../lib/fakesys/fakenet.h | 81 ++-
> test/unit/CMakeLists.txt | 6 +-
> test/unit/swim.c | 8 +-
> test/unit/swim_errinj.c | 8 +-
> test/unit/swim_test_ev.c | 319 +----------
> test/unit/swim_test_transport.c | 438 +--------------
> test/unit/swim_test_utils.c | 30 +-
> test/unit/swim_test_utils.h | 6 +-
> 13 files changed, 1003 insertions(+), 799 deletions(-)
> create mode 100644 src/lib/fakesys/CMakeLists.txt
> create mode 100644 src/lib/fakesys/fakeev.c
> rename test/unit/swim_test_ev.h => src/lib/fakesys/fakeev.h (77%)
> create mode 100644 src/lib/fakesys/fakenet.c
> rename test/unit/swim_test_transport.h => src/lib/fakesys/fakenet.h (59%)
>
--
Serge Petrenko
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Tarantool-patches] [PATCH 00/10] Raft module, part 3 - fake network and libev for Raft and SWIM
2020-11-30 23:56 [Tarantool-patches] [PATCH 00/10] Raft module, part 3 - fake network and libev for Raft and SWIM Vladislav Shpilevoy
` (10 preceding siblings ...)
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
12 siblings, 0 replies; 15+ messages in thread
From: Vladislav Shpilevoy @ 2020-12-01 22:33 UTC (permalink / raw)
To: tarantool-patches, sergepetrenko, Alexander V. Tikhonov
Sash (Tikh.), could you please validate the branch is ok to push?
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Tarantool-patches] [PATCH 00/10] Raft module, part 3 - fake network and libev for Raft and SWIM
2020-11-30 23:56 [Tarantool-patches] [PATCH 00/10] Raft module, part 3 - fake network and libev for Raft and SWIM Vladislav Shpilevoy
` (11 preceding siblings ...)
2020-12-01 22:33 ` Vladislav Shpilevoy
@ 2020-12-04 0:35 ` Alexander V. Tikhonov
2020-12-04 22:53 ` Vladislav Shpilevoy
12 siblings, 1 reply; 15+ messages in thread
From: Alexander V. Tikhonov @ 2020-12-04 0:35 UTC (permalink / raw)
To: Vladislav Shpilevoy; +Cc: tarantool-patches
Hi Vlad, thanks for the patchset. I've checked that all commit
criteria tests passed [1], patchset LGTM.
[1] - https://gitlab.com/tarantool/tarantool/-/pipelines/223423665
On Tue, Dec 01, 2020 at 12:56:08AM +0100, Vladislav Shpilevoy via Tarantool-patches wrote:
> The patchset is a third part of Raft relocation to a new module for the sake of
> unit testing. This part extracts fake network and libev libraries from SWIM unit
> tests to a new library fakesys, which will be used by Raft.
>
> The patchset only moves the existing code. For the actual Raft tests it is
> likely I will add some new Raft-specific code, and probably will generalize
> something from swim_test_utils.h/.c.
>
> Branch: http://github.com/tarantool/tarantool/tree/gerold103/gh-5303-p3-fakesys
> Issue: https://github.com/tarantool/tarantool/issues/5303
>
> Vladislav Shpilevoy (10):
> test: stop using swim_transport.addr as in-param
> test: factor out swim from libc emulation funcs
> test: rename fake libc network methods to fakenet
> test: move fake network code to fakenet.c/.h files
> test: factor out swim from fakenet.c/.h files
> fakesys: introduce fake system library
> test: rename fake libev methods to fakeev
> test: move fake libev code to fakeev.c/.h files
> test: factor out swim from fakeev.h/.c files
> fakesys: move fakeev to fakesys library
>
> src/lib/CMakeLists.txt | 1 +
> src/lib/fakesys/CMakeLists.txt | 8 +
> src/lib/fakesys/fakeev.c | 350 ++++++++++++
> .../lib/fakesys/fakeev.h | 45 +-
> src/lib/fakesys/fakenet.c | 502 ++++++++++++++++++
> .../lib/fakesys/fakenet.h | 81 ++-
> test/unit/CMakeLists.txt | 6 +-
> test/unit/swim.c | 8 +-
> test/unit/swim_errinj.c | 8 +-
> test/unit/swim_test_ev.c | 319 +----------
> test/unit/swim_test_transport.c | 438 +--------------
> test/unit/swim_test_utils.c | 30 +-
> test/unit/swim_test_utils.h | 6 +-
> 13 files changed, 1003 insertions(+), 799 deletions(-)
> create mode 100644 src/lib/fakesys/CMakeLists.txt
> create mode 100644 src/lib/fakesys/fakeev.c
> rename test/unit/swim_test_ev.h => src/lib/fakesys/fakeev.h (77%)
> create mode 100644 src/lib/fakesys/fakenet.c
> rename test/unit/swim_test_transport.h => src/lib/fakesys/fakenet.h (59%)
>
> --
> 2.24.3 (Apple Git-128)
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Tarantool-patches] [PATCH 00/10] Raft module, part 3 - fake network and libev for Raft and SWIM
2020-12-04 0:35 ` Alexander V. Tikhonov
@ 2020-12-04 22:53 ` Vladislav Shpilevoy
0 siblings, 0 replies; 15+ messages in thread
From: Vladislav Shpilevoy @ 2020-12-04 22:53 UTC (permalink / raw)
To: Alexander V. Tikhonov; +Cc: tarantool-patches
Pushed to master and 2.6.
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2020-12-04 22:53 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [Tarantool-patches] [PATCH 02/10] test: factor out swim from libc emulation funcs Vladislav Shpilevoy
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox