/work/auto_tests/scenarios/scenario_group_general_test.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include "framework/framework.h" |
2 | | #include <stdio.h> |
3 | | #include <string.h> |
4 | | #include <stdlib.h> |
5 | | |
6 | 2 | #define GROUP_NAME "NASA Headquarters" |
7 | 1 | #define GROUP_NAME_LEN (sizeof(GROUP_NAME) - 1) |
8 | 2 | #define TOPIC "Funny topic here" |
9 | 1 | #define TOPIC_LEN (sizeof(TOPIC) - 1) |
10 | 4 | #define PEER0_NICK "Lois" |
11 | 2 | #define PEER0_NICK_LEN (sizeof(PEER0_NICK) - 1) |
12 | 4 | #define PEER0_NICK2 "Terry Davis" |
13 | 3 | #define PEER0_NICK2_LEN (sizeof(PEER0_NICK2) - 1) |
14 | 2 | #define PEER1_NICK "Bran" |
15 | 1 | #define PEER1_NICK_LEN (sizeof(PEER1_NICK) - 1) |
16 | 2 | #define EXIT_MESSAGE "Goodbye world" |
17 | 1 | #define EXIT_MESSAGE_LEN (sizeof(EXIT_MESSAGE) - 1) |
18 | 1 | #define PEER_LIMIT 20 |
19 | | |
20 | | typedef struct { |
21 | | uint32_t group_number; |
22 | | uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; |
23 | | uint32_t peer_joined_count; |
24 | | uint32_t self_joined_count; |
25 | | uint32_t peer_exit_count; |
26 | | bool peer_nick_updated; |
27 | | bool peer_status_updated; |
28 | | uint32_t last_peer_id; |
29 | | bool is_founder; |
30 | | bool synced; |
31 | | } GroupState; |
32 | | |
33 | | static void on_group_peer_join(const Tox_Event_Group_Peer_Join *event, void *user_data) |
34 | 25 | { |
35 | 25 | ToxNode *self = (ToxNode *)user_data; |
36 | 25 | GroupState *state = (GroupState *)tox_node_get_script_ctx(self); |
37 | 25 | state->peer_joined_count++; |
38 | 25 | state->last_peer_id = tox_event_group_peer_join_get_peer_id(event); |
39 | 25 | tox_node_log(self, "Peer joined: %u (total %u)", state->last_peer_id, state->peer_joined_count); |
40 | 25 | } |
41 | | |
42 | | static void on_group_self_join(const Tox_Event_Group_Self_Join *event, void *user_data) |
43 | 13 | { |
44 | 13 | ToxNode *self = (ToxNode *)user_data; |
45 | 13 | GroupState *state = (GroupState *)tox_node_get_script_ctx(self); |
46 | 13 | state->self_joined_count++; |
47 | 13 | tox_node_log(self, "Self joined (total %u)", state->self_joined_count); |
48 | 13 | } |
49 | | |
50 | | static void on_group_peer_exit(const Tox_Event_Group_Peer_Exit *event, void *user_data) |
51 | 2 | { |
52 | 2 | ToxNode *self = (ToxNode *)user_data; |
53 | 2 | GroupState *state = (GroupState *)tox_node_get_script_ctx(self); |
54 | 2 | state->peer_exit_count++; |
55 | 2 | tox_node_log(self, "Peer exited (total %u)", state->peer_exit_count); |
56 | | |
57 | 2 | if (state->peer_exit_count == 2) { |
58 | 1 | size_t len = tox_event_group_peer_exit_get_part_message_length(event); |
59 | 1 | const uint8_t *msg = tox_event_group_peer_exit_get_part_message(event); |
60 | 1 | ck_assert(len == EXIT_MESSAGE_LEN); |
61 | 1 | ck_assert(memcmp(msg, EXIT_MESSAGE, len) == 0); |
62 | 1 | } |
63 | 2 | } |
64 | | |
65 | | static void on_group_peer_name(const Tox_Event_Group_Peer_Name *event, void *user_data) |
66 | 1 | { |
67 | 1 | ToxNode *self = (ToxNode *)user_data; |
68 | 1 | GroupState *state = (GroupState *)tox_node_get_script_ctx(self); |
69 | 1 | size_t len = tox_event_group_peer_name_get_name_length(event); |
70 | 1 | const uint8_t *name = tox_event_group_peer_name_get_name(event); |
71 | 1 | if (len == PEER0_NICK2_LEN && memcmp(name, PEER0_NICK2, len) == 0) { |
72 | 1 | state->peer_nick_updated = true; |
73 | 1 | } |
74 | 1 | } |
75 | | |
76 | | static void on_group_peer_status(const Tox_Event_Group_Peer_Status *event, void *user_data) |
77 | 1 | { |
78 | 1 | ToxNode *self = (ToxNode *)user_data; |
79 | 1 | GroupState *state = (GroupState *)tox_node_get_script_ctx(self); |
80 | 1 | if (tox_event_group_peer_status_get_status(event) == TOX_USER_STATUS_BUSY) { |
81 | 1 | state->peer_status_updated = true; |
82 | 1 | } |
83 | 1 | } |
84 | | |
85 | | static void founder_script(ToxNode *self, void *ctx) |
86 | 1 | { |
87 | 1 | GroupState *state = (GroupState *)ctx; |
88 | 1 | Tox *tox = tox_node_get_tox(self); |
89 | 1 | Tox_Dispatch *dispatch = tox_node_get_dispatch(self); |
90 | | |
91 | 1 | tox_events_callback_group_peer_join(dispatch, on_group_peer_join); |
92 | 1 | tox_events_callback_group_self_join(dispatch, on_group_self_join); |
93 | | |
94 | 1 | tox_node_log(self, "Waiting for self connection..."); |
95 | 1 | WAIT_UNTIL(tox_node_is_self_connected(self)); |
96 | 1 | tox_node_log(self, "Connected!"); |
97 | | |
98 | 1 | Tox_Err_Group_New err_new; |
99 | 1 | state->group_number = tox_group_new(tox, TOX_GROUP_PRIVACY_STATE_PUBLIC, (const uint8_t *)GROUP_NAME, GROUP_NAME_LEN, (const uint8_t *)PEER0_NICK, PEER0_NICK_LEN, &err_new); |
100 | 1 | ck_assert(err_new == TOX_ERR_GROUP_NEW_OK); |
101 | 1 | tox_node_log(self, "Group created: %u", state->group_number); |
102 | | |
103 | 1 | tox_group_set_peer_limit(tox, state->group_number, PEER_LIMIT, nullptr); |
104 | 1 | tox_group_set_topic(tox, state->group_number, (const uint8_t *)TOPIC, TOPIC_LEN, nullptr); |
105 | | |
106 | 1 | tox_group_get_chat_id(tox, state->group_number, state->chat_id, nullptr); |
107 | | |
108 | | // Signal Peer 1 that group is created |
109 | 1 | tox_scenario_barrier_wait(self); |
110 | | |
111 | | // Wait for Peer 1 to join |
112 | 1 | tox_node_log(self, "Waiting for peer to join..."); |
113 | 1 | WAIT_UNTIL(state->peer_joined_count == 1); |
114 | 1 | tox_node_log(self, "Peer joined!"); |
115 | | |
116 | | // Sync check |
117 | 1 | WAIT_UNTIL(tox_group_is_connected(tox, state->group_number, nullptr)); |
118 | | |
119 | | // Change name |
120 | 1 | tox_group_self_set_name(tox, state->group_number, (const uint8_t *)PEER0_NICK2, PEER0_NICK2_LEN, nullptr); |
121 | | // Change status |
122 | 1 | tox_group_self_set_status(tox, state->group_number, TOX_USER_STATUS_BUSY, nullptr); |
123 | | |
124 | | // Disconnect |
125 | 1 | tox_node_log(self, "Disconnecting..."); |
126 | 1 | tox_group_disconnect(tox, state->group_number, nullptr); |
127 | | |
128 | | // Wait some time |
129 | 51 | for (int i = 0; i < 50; ++i) { |
130 | 50 | tox_scenario_yield(self); |
131 | 50 | } |
132 | | |
133 | | // Reconnect |
134 | 1 | tox_node_log(self, "Reconnecting..."); |
135 | 1 | tox_group_join(tox, state->chat_id, (const uint8_t *)PEER0_NICK, PEER0_NICK_LEN, nullptr, 0, nullptr); |
136 | | |
137 | 1 | WAIT_UNTIL(tox_group_is_connected(tox, state->group_number, nullptr)); |
138 | | |
139 | | // Wait for Peer 1 to see us |
140 | 101 | for (int i = 0; i < 100; ++i) { |
141 | 100 | tox_scenario_yield(self); |
142 | 100 | } |
143 | | |
144 | | // Leave |
145 | 1 | tox_node_log(self, "Leaving with message..."); |
146 | 1 | tox_group_leave(tox, state->group_number, (const uint8_t *)EXIT_MESSAGE, EXIT_MESSAGE_LEN, nullptr); |
147 | 1 | } |
148 | | |
149 | | static void peer1_script(ToxNode *self, void *ctx) |
150 | 1 | { |
151 | 1 | const GroupState *state = (const GroupState *)ctx; |
152 | 1 | Tox *tox = tox_node_get_tox(self); |
153 | 1 | Tox_Dispatch *dispatch = tox_node_get_dispatch(self); |
154 | | |
155 | 1 | tox_events_callback_group_peer_join(dispatch, on_group_peer_join); |
156 | 1 | tox_events_callback_group_self_join(dispatch, on_group_self_join); |
157 | 1 | tox_events_callback_group_peer_name(dispatch, on_group_peer_name); |
158 | 1 | tox_events_callback_group_peer_status(dispatch, on_group_peer_status); |
159 | 1 | tox_events_callback_group_peer_exit(dispatch, on_group_peer_exit); |
160 | | |
161 | 1 | tox_node_log(self, "Waiting for self connection..."); |
162 | 1 | WAIT_UNTIL(tox_node_is_self_connected(self)); |
163 | 1 | tox_node_log(self, "Connected!"); |
164 | | |
165 | | // Wait for Founder to create group and get chat_id |
166 | 1 | tox_node_log(self, "Waiting for founder to create group..."); |
167 | 1 | tox_scenario_barrier_wait(self); |
168 | | |
169 | 1 | const ToxNode *founder = tox_scenario_get_node(tox_node_get_scenario(self), 0); |
170 | 1 | const GroupState *founder_view = (const GroupState *)tox_node_get_peer_ctx(founder); |
171 | | |
172 | 1 | uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; |
173 | 1 | memcpy(chat_id, founder_view->chat_id, TOX_GROUP_CHAT_ID_SIZE); |
174 | 1 | tox_node_log(self, "Got chat ID from founder!"); |
175 | | |
176 | 1 | tox_node_log(self, "Joining group..."); |
177 | 1 | tox_group_join(tox, chat_id, (const uint8_t *)PEER1_NICK, PEER1_NICK_LEN, nullptr, 0, nullptr); |
178 | | |
179 | 1 | WAIT_UNTIL(state->self_joined_count == 1); |
180 | 1 | WAIT_UNTIL(state->peer_joined_count == 1); |
181 | 1 | WAIT_UNTIL(tox_group_is_connected(tox, 0, nullptr)); |
182 | | |
183 | 1 | WAIT_UNTIL(state->peer_nick_updated); |
184 | 1 | WAIT_UNTIL(state->peer_status_updated); |
185 | | |
186 | | // Founder will disconnect |
187 | 1 | WAIT_UNTIL(state->peer_exit_count == 1); |
188 | | |
189 | | // Change status while alone |
190 | 1 | tox_group_self_set_status(tox, 0, TOX_USER_STATUS_AWAY, nullptr); |
191 | | |
192 | | // Founder will reconnect |
193 | 1 | WAIT_UNTIL(state->peer_joined_count == 2); |
194 | | |
195 | | // Founder will leave with message |
196 | 1 | WAIT_UNTIL(state->peer_exit_count == 2); |
197 | | |
198 | 1 | tox_group_leave(tox, 0, nullptr, 0, nullptr); |
199 | 1 | } |
200 | | |
201 | | int main(int argc, char *argv[]) |
202 | 31 | { |
203 | 31 | ToxScenario *s = tox_scenario_new(argc, argv, 300000); |
204 | 31 | GroupState s0 = { .group_number = UINT32_MAX, .is_founder = true }; |
205 | 31 | GroupState s1 = { .group_number = UINT32_MAX, .is_founder = false }; |
206 | | |
207 | 31 | ToxNode *n0 = tox_scenario_add_node(s, "Founder", founder_script, &s0, sizeof(GroupState)); |
208 | 31 | ToxNode *n1 = tox_scenario_add_node(s, "Peer1", peer1_script, &s1, sizeof(GroupState)); |
209 | | |
210 | 31 | tox_node_bootstrap(n1, n0); |
211 | | // Note: No friend add needed for public groups, they find each other via DHT |
212 | | |
213 | 31 | ToxScenarioStatus res = tox_scenario_run(s); |
214 | 31 | if (res != TOX_SCENARIO_DONE) { |
215 | 0 | tox_scenario_log(s, "Test failed with status %u", res); |
216 | 0 | return 1; |
217 | 0 | } |
218 | | |
219 | 31 | tox_scenario_free(s); |
220 | 31 | return 0; |
221 | 31 | } |
222 | | |
223 | | #undef PEER_LIMIT |
224 | | #undef GROUP_NAME |
225 | | #undef GROUP_NAME_LEN |
226 | | #undef TOPIC |
227 | | #undef TOPIC_LEN |
228 | | #undef PEER0_NICK |
229 | | #undef PEER0_NICK_LEN |
230 | | #undef PEER1_NICK |
231 | | #undef PEER1_NICK_LEN |