Coverage Report

Created: 2026-10-24 08:16

/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