[tarantool-patches] [PATCH 4/5] test: set packet drop rate instead of flag in swim tests
Vladislav Shpilevoy
v.shpilevoy at tarantool.org
Fri Apr 5 14:57:30 MSK 2019
Before dissemination component it was enough in the tests to
either drop all packets to/from a certain member, or do not drop
at all. But after dissemination it will be time to test more
granulated packet loss table: not 0/100, but 5/10/20/50/.../100
packet loss rate.
Part of #3234
---
test/unit/swim.c | 10 +++++-----
test/unit/swim_test_transport.c | 27 +++++++++++++++++++--------
test/unit/swim_test_transport.h | 9 +++++----
test/unit/swim_test_utils.c | 2 +-
test/unit/swim_test_utils.h | 2 +-
5 files changed, 31 insertions(+), 19 deletions(-)
diff --git a/test/unit/swim.c b/test/unit/swim.c
index d77225f6c..358230e15 100644
--- a/test/unit/swim.c
+++ b/test/unit/swim.c
@@ -293,7 +293,7 @@ swim_test_basic_gossip(void)
*/
swim_cluster_add_link(cluster, 0, 1);
swim_cluster_add_link(cluster, 1, 0);
- swim_cluster_set_drop(cluster, 1, true);
+ swim_cluster_set_drop(cluster, 1, 100);
/*
* Wait two no-ACKs on S1 from S2. +1 sec to send a first
* ping.
@@ -353,9 +353,9 @@ swim_test_refute(void)
swim_cluster_set_ack_timeout(cluster, 2);
swim_cluster_add_link(cluster, 0, 1);
- swim_cluster_set_drop(cluster, 1, true);
+ swim_cluster_set_drop(cluster, 1, 100);
fail_if(swim_cluster_wait_status(cluster, 0, 1, MEMBER_DEAD, 7) != 0);
- swim_cluster_set_drop(cluster, 1, false);
+ swim_cluster_set_drop(cluster, 1, 0);
is(swim_cluster_wait_incarnation(cluster, 1, 1, 1, 1), 0,
"S2 increments its own incarnation to refute its death");
is(swim_cluster_wait_incarnation(cluster, 0, 1, 1, 1), 0,
@@ -390,7 +390,7 @@ swim_test_too_big_packet(void)
"eventually reached", size);
swim_cluster_set_ack_timeout(cluster, ack_timeout);
- swim_cluster_set_drop(cluster, drop_id, true);
+ swim_cluster_set_drop(cluster, drop_id, 100);
is(swim_cluster_wait_status_anywhere(cluster, drop_id, MEMBER_DEAD,
first_dead_timeout), 0,
"a dead member is detected in time not depending on cluster size");
@@ -426,7 +426,7 @@ swim_test_undead(void)
swim_cluster_set_ack_timeout(cluster, 1);
swim_cluster_add_link(cluster, 0, 1);
swim_cluster_add_link(cluster, 1, 0);
- swim_cluster_set_drop(cluster, 1, true);
+ swim_cluster_set_drop(cluster, 1, 100);
is(swim_cluster_wait_status(cluster, 0, 1, MEMBER_DEAD, 4), 0,
"member S2 is dead");
swim_run_for(5);
diff --git a/test/unit/swim_test_transport.c b/test/unit/swim_test_transport.c
index 3b59eaf4d..e563185ee 100644
--- a/test/unit/swim_test_transport.c
+++ b/test/unit/swim_test_transport.c
@@ -97,10 +97,10 @@ struct swim_fd {
*/
bool is_opened;
/**
- * True if any message sent to that fd should be just
- * dropped, not queued.
+ * Probability of packet loss. For both sends and
+ * receipts.
*/
- bool is_dropping;
+ double drop_rate;
/**
* Link in the list of opened and non-blocked descriptors.
* Used to feed them all EV_WRITE.
@@ -130,7 +130,7 @@ swim_fd_open(struct swim_fd *fd)
return -1;
}
fd->is_opened = true;
- fd->is_dropping = false;
+ fd->drop_rate = 0;
rlist_add_tail_entry(&swim_fd_active, fd, in_active);
return 0;
}
@@ -156,7 +156,7 @@ swim_test_transport_init(void)
for (int i = 0, evfd = FAKE_FD_BASE; i < FAKE_FD_NUMBER; ++i, ++evfd) {
swim_fd[i].evfd = evfd;
swim_fd[i].is_opened = false;
- swim_fd[i].is_dropping = false;
+ swim_fd[i].drop_rate = 0;
rlist_create(&swim_fd[i].in_active);
rlist_create(&swim_fd[i].recv_queue);
rlist_create(&swim_fd[i].send_queue);
@@ -268,11 +268,21 @@ swim_test_transport_unblock_fd(int fd)
}
void
-swim_test_transport_set_drop(int fd, bool value)
+swim_test_transport_set_drop(int fd, double value)
{
struct swim_fd *sfd = &swim_fd[fd - FAKE_FD_BASE];
if (sfd->is_opened)
- sfd->is_dropping = value;
+ sfd->drop_rate = value;
+}
+
+/**
+ * Returns true with probability @a rate, and is used to decided
+ * wether to drop a packet or not.
+ */
+static inline bool
+swim_test_is_drop(double rate)
+{
+ return ((double) rand() / RAND_MAX) * 100 < rate;
}
/** Send one packet to destination's recv queue. */
@@ -285,7 +295,8 @@ swim_fd_send_packet(struct swim_fd *fd)
rlist_shift_entry(&fd->send_queue, struct swim_test_packet,
in_queue);
struct swim_fd *dst = &swim_fd[ntohs(p->dst.sin_port)];
- if (dst->is_opened && ! dst->is_dropping && ! fd->is_dropping)
+ if (dst->is_opened && !swim_test_is_drop(dst->drop_rate) &&
+ !swim_test_is_drop(fd->drop_rate))
rlist_add_tail_entry(&dst->recv_queue, p, in_queue);
else
swim_test_packet_delete(p);
diff --git a/test/unit/swim_test_transport.h b/test/unit/swim_test_transport.h
index 5a1a92271..d291abe91 100644
--- a/test/unit/swim_test_transport.h
+++ b/test/unit/swim_test_transport.h
@@ -60,12 +60,13 @@ void
swim_test_transport_unblock_fd(int fd);
/**
- * Set to true, if all incomming and outgoing packets should be
- * dropped. Note, that the node, owning @a fd, thinks, that its
- * packets are sent.
+ * Drop rate of incomming and outgoing packets. Note, that even if
+ * a packet is dropped on send, the node, owning @a fd, still
+ * thinks, that the packet is sent. It is not a sender-visible
+ * error.
*/
void
-swim_test_transport_set_drop(int fd, bool value);
+swim_test_transport_set_drop(int fd, double value);
/** Initialize test transport system. */
void
diff --git a/test/unit/swim_test_utils.c b/test/unit/swim_test_utils.c
index 277a73498..bada8ef43 100644
--- a/test/unit/swim_test_utils.c
+++ b/test/unit/swim_test_utils.c
@@ -177,7 +177,7 @@ swim_cluster_unblock_io(struct swim_cluster *cluster, int i)
}
void
-swim_cluster_set_drop(struct swim_cluster *cluster, int i, bool value)
+swim_cluster_set_drop(struct swim_cluster *cluster, int i, double value)
{
swim_test_transport_set_drop(swim_fd(cluster->node[i]), value);
}
diff --git a/test/unit/swim_test_utils.h b/test/unit/swim_test_utils.h
index 6e99b4879..f4397aff4 100644
--- a/test/unit/swim_test_utils.h
+++ b/test/unit/swim_test_utils.h
@@ -80,7 +80,7 @@ void
swim_cluster_unblock_io(struct swim_cluster *cluster, int i);
void
-swim_cluster_set_drop(struct swim_cluster *cluster, int i, bool value);
+swim_cluster_set_drop(struct swim_cluster *cluster, int i, double value);
/**
* Explicitly add a member of id @a from_id to a member of id
--
2.17.2 (Apple Git-113)
More information about the Tarantool-patches
mailing list