Coverage Report

Created: 2026-10-24 08:16

/work/auto_tests/scenarios/scenario_file_seek_test.c
Line
Count
Source (jump to first uncovered line)
1
#include "framework/framework.h"
2
#include <stdio.h>
3
#include <stdlib.h>
4
#include <string.h>
5
6
1
#define FILE_SIZE (1024 * 1024)
7
385
#define SEEK_POS (512 * 1024)
8
9
typedef struct {
10
    bool seek_happened;
11
    bool finished;
12
} SenderState;
13
14
static void on_file_chunk_request(const Tox_Event_File_Chunk_Request *event, void *user_data)
15
384
{
16
384
    ToxNode *self = (ToxNode *)user_data;
17
384
    SenderState *state = (SenderState *)tox_node_get_script_ctx(self);
18
19
384
    uint32_t friend_number = tox_event_file_chunk_request_get_friend_number(event);
20
384
    uint32_t file_number = tox_event_file_chunk_request_get_file_number(event);
21
384
    uint64_t position = tox_event_file_chunk_request_get_position(event);
22
384
    size_t length = tox_event_file_chunk_request_get_length(event);
23
24
384
    if (length == 0) {
25
1
        state->finished = true;
26
1
        return;
27
1
    }
28
29
383
    if (position >= SEEK_POS) {
30
383
        state->seek_happened = true;
31
383
    }
32
33
383
    uint8_t data[TOX_MAX_CUSTOM_PACKET_SIZE];
34
383
    memset(data, (uint8_t)(position % 256), length);
35
383
    tox_file_send_chunk(tox_node_get_tox(self), friend_number, file_number, position, data, length, nullptr);
36
383
}
37
38
static void sender_script(ToxNode *self, void *ctx)
39
1
{
40
1
    SenderState *state = (SenderState *)ctx;
41
1
    tox_events_callback_file_chunk_request(tox_node_get_dispatch(self), on_file_chunk_request);
42
43
1
    tox_node_wait_for_self_connected(self);
44
1
    tox_node_wait_for_friend_connected(self, 0);
45
46
1
    Tox *tox = tox_node_get_tox(self);
47
1
    tox_file_send(tox, 0, TOX_FILE_KIND_DATA, FILE_SIZE, nullptr, (const uint8_t *)"seek_test.bin", 13, nullptr);
48
49
1
    WAIT_UNTIL(state->finished);
50
1
    tox_node_log(self, "Sender finished. Seek happened: %s", state->seek_happened ? "YES" : "NO");
51
1
    ck_assert(state->seek_happened);
52
1
}
53
54
typedef struct {
55
    uint32_t file_number;
56
    bool file_recv_called;
57
    bool finished;
58
} ReceiverState;
59
60
static void on_file_recv(const Tox_Event_File_Recv *event, void *user_data)
61
2
{
62
2
    ToxNode *self = (ToxNode *)user_data;
63
2
    ReceiverState *state = (ReceiverState *)tox_node_get_script_ctx(self);
64
2
    state->file_number = tox_event_file_recv_get_file_number(event);
65
2
    state->file_recv_called = true;
66
2
    tox_node_log(self, "Received file request, file_number = %u", state->file_number);
67
2
}
68
69
static void on_file_recv_chunk(const Tox_Event_File_Recv_Chunk *event, void *user_data)
70
384
{
71
384
    ToxNode *self = (ToxNode *)user_data;
72
384
    ReceiverState *state = (ReceiverState *)tox_node_get_script_ctx(self);
73
384
    size_t length = tox_event_file_recv_chunk_get_data_length(event);
74
384
    if (length == 0) {
75
1
        state->finished = true;
76
1
    }
77
384
}
78
79
static void receiver_script(ToxNode *self, void *ctx)
80
1
{
81
1
    ReceiverState *state = (ReceiverState *)ctx;
82
1
    tox_events_callback_file_recv(tox_node_get_dispatch(self), on_file_recv);
83
1
    tox_events_callback_file_recv_chunk(tox_node_get_dispatch(self), on_file_recv_chunk);
84
85
1
    tox_node_wait_for_self_connected(self);
86
1
    tox_node_wait_for_friend_connected(self, 0);
87
88
1
    WAIT_UNTIL(state->file_recv_called);
89
90
1
    tox_node_log(self, "Seeking to %d before resuming...", SEEK_POS);
91
1
    Tox_Err_File_Seek seek_err;
92
1
    bool seek_res = tox_file_seek(tox_node_get_tox(self), 0, state->file_number, SEEK_POS, &seek_err);
93
1
    if (!seek_res) {
94
0
        tox_node_log(self, "tox_file_seek failed: %s", tox_err_file_seek_to_string(seek_err));
95
0
    }
96
1
    ck_assert(seek_res);
97
98
1
    tox_node_log(self, "Resuming file %u...", state->file_number);
99
1
    Tox_Err_File_Control ctrl_err;
100
1
    bool resume_res = tox_file_control(tox_node_get_tox(self), 0, state->file_number, TOX_FILE_CONTROL_RESUME, &ctrl_err);
101
1
    ck_assert(resume_res);
102
103
1
    WAIT_UNTIL(state->finished);
104
1
    tox_node_log(self, "Receiver finished!");
105
1
}
106
107
int main(int argc, char *argv[])
108
31
{
109
31
    ToxScenario *s = tox_scenario_new(argc, argv, 60000);
110
111
31
    SenderState sender_state = {false, false};
112
31
    ReceiverState receiver_state = {0, false, false};
113
114
31
    tox_scenario_add_node(s, "Sender", sender_script, &sender_state, sizeof(SenderState));
115
31
    tox_scenario_add_node(s, "Receiver", receiver_script, &receiver_state, sizeof(ReceiverState));
116
117
31
    ToxNode *sender = tox_scenario_get_node(s, 0);
118
31
    ToxNode *receiver = tox_scenario_get_node(s, 1);
119
120
31
    tox_node_bootstrap(sender, receiver);
121
31
    tox_node_friend_add(sender, receiver);
122
31
    tox_node_friend_add(receiver, sender);
123
124
31
    ToxScenarioStatus res = tox_scenario_run(s);
125
31
    if (res != TOX_SCENARIO_DONE) {
126
0
        fprintf(stderr, "Scenario failed with status %u\n", res);
127
0
        return 1;
128
0
    }
129
130
31
    tox_scenario_free(s);
131
31
    return 0;
132
31
}
133
134
#undef FILE_SIZE