/work/auto_tests/scenarios/scenario_overflow_recvq_test.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include "framework/framework.h" |
2 | | #include <stdio.h> |
3 | | #include <string.h> |
4 | | |
5 | 80.0k | #define NUM_MSGS 40000 |
6 | | |
7 | | typedef struct { |
8 | | uint32_t recv_count; |
9 | | } State; |
10 | | |
11 | | static void on_friend_message(const Tox_Event_Friend_Message *event, void *user_data) |
12 | 80.0k | { |
13 | 80.0k | ToxNode *self = (ToxNode *)user_data; |
14 | 80.0k | State *state = (State *)tox_node_get_script_ctx(self); |
15 | 80.0k | state->recv_count++; |
16 | 80.0k | } |
17 | | |
18 | | static void receiver_script(ToxNode *self, void *ctx) |
19 | 1 | { |
20 | 1 | State *state = (State *)ctx; |
21 | 1 | Tox_Dispatch *dispatch = tox_node_get_dispatch(self); |
22 | 1 | tox_events_callback_friend_message(dispatch, on_friend_message); |
23 | | |
24 | 1 | tox_node_wait_for_self_connected(self); |
25 | 1 | tox_node_wait_for_friend_connected(self, 0); |
26 | 1 | tox_node_wait_for_friend_connected(self, 1); |
27 | | |
28 | 1 | tox_node_log(self, "Ready to receive..."); |
29 | 1 | tox_scenario_barrier_wait(self); // Barrier 1: Connected |
30 | | |
31 | | // Wait until we get many messages or scenario timeout. |
32 | | // We don't expect ALL 80k messages to arrive in a short time, |
33 | | // but we want to see if it survives the flood. |
34 | 1 | uint32_t last_count = 0; |
35 | 1 | uint32_t stable_ticks = 0; |
36 | 81 | while (tox_scenario_is_running(self)) { |
37 | 81 | tox_scenario_yield(self); |
38 | 81 | if (state->recv_count == last_count && state->recv_count > 0) { |
39 | 11 | stable_ticks++; |
40 | 11 | if (stable_ticks > 100) { |
41 | 0 | break; // No new messages for 5 seconds |
42 | 0 | } |
43 | 70 | } else { |
44 | 70 | stable_ticks = 0; |
45 | 70 | } |
46 | 81 | last_count = state->recv_count; |
47 | | |
48 | 81 | if (state->recv_count >= NUM_MSGS * 2) { |
49 | 1 | break; |
50 | 1 | } |
51 | 81 | } |
52 | 1 | tox_node_log(self, "Received %u messages.", state->recv_count); |
53 | 1 | } |
54 | | |
55 | | static void sender_script(ToxNode *self, void *ctx) |
56 | 2 | { |
57 | 2 | tox_node_wait_for_self_connected(self); |
58 | 2 | tox_node_wait_for_friend_connected(self, 0); |
59 | | |
60 | 2 | tox_scenario_barrier_wait(self); // Barrier 1: Connected |
61 | | |
62 | 2 | tox_node_log(self, "Sending messages..."); |
63 | 2 | Tox *tox = tox_node_get_tox(self); |
64 | 79.9k | for (uint32_t i = 0; i < NUM_MSGS; i++) { |
65 | 79.9k | uint8_t message[128] = {0}; |
66 | 79.9k | snprintf((char *)message, sizeof(message), "%u-%u", tox_node_get_index(self), i); |
67 | | |
68 | 79.9k | Tox_Err_Friend_Send_Message err; |
69 | 79.9k | tox_friend_send_message(tox, 0, TOX_MESSAGE_TYPE_NORMAL, message, sizeof(message), &err); |
70 | | |
71 | 79.9k | if (err == TOX_ERR_FRIEND_SEND_MESSAGE_SENDQ) { |
72 | | // This is expected when flooding |
73 | 0 | if (i % 1000 == 0) { |
74 | 0 | tox_node_log(self, "Send queue full at message %u, yielding...", i); |
75 | 0 | } |
76 | 0 | tox_scenario_yield(self); |
77 | 0 | i--; // Retry this message |
78 | 0 | continue; |
79 | 0 | } |
80 | | |
81 | 79.9k | if (err == TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_CONNECTED) { |
82 | 0 | if (i % 1000 == 0) { |
83 | 0 | tox_node_log(self, "Friend not connected at message %u, waiting...", i); |
84 | 0 | } |
85 | 0 | tox_node_wait_for_friend_connected(self, 0); |
86 | 0 | i--; // Retry this message |
87 | 0 | continue; |
88 | 0 | } |
89 | | |
90 | 79.9k | ck_assert_msg(err == TOX_ERR_FRIEND_SEND_MESSAGE_OK, "send_message failed with %s", |
91 | 79.9k | tox_err_friend_send_message_to_string(err)); |
92 | | |
93 | 79.9k | if (i % 500 == 0) { |
94 | 160 | tox_scenario_yield(self); |
95 | 160 | } |
96 | 79.9k | } |
97 | 2 | tox_node_log(self, "Finished sending."); |
98 | 2 | } |
99 | | |
100 | | int main(int argc, char *argv[]) |
101 | 1 | { |
102 | 1 | ToxScenario *s = tox_scenario_new(argc, argv, 120000); |
103 | 1 | State receiver_state = {0}; |
104 | | |
105 | 1 | ToxNode *receiver = tox_scenario_add_node(s, "Receiver", receiver_script, &receiver_state, sizeof(State)); |
106 | 1 | ToxNode *sender1 = tox_scenario_add_node(s, "Sender1", sender_script, nullptr, 0); |
107 | 1 | ToxNode *sender2 = tox_scenario_add_node(s, "Sender2", sender_script, nullptr, 0); |
108 | | |
109 | 1 | tox_node_bootstrap(sender1, receiver); |
110 | 1 | tox_node_bootstrap(sender2, receiver); |
111 | 1 | tox_node_friend_add(receiver, sender1); |
112 | 1 | tox_node_friend_add(sender1, receiver); |
113 | 1 | tox_node_friend_add(receiver, sender2); |
114 | 1 | tox_node_friend_add(sender2, receiver); |
115 | | |
116 | 1 | ToxScenarioStatus res = tox_scenario_run(s); |
117 | 1 | if (res != TOX_SCENARIO_DONE && res != TOX_SCENARIO_TIMEOUT) { |
118 | 0 | return 1; |
119 | 0 | } |
120 | | |
121 | 1 | tox_scenario_free(s); |
122 | 1 | return 0; |
123 | 1 | } |
124 | | |
125 | | #undef NUM_MSGS |