summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--auto_tests/helpers.h2
-rw-r--r--auto_tests/monolith_test.cc260
-rw-r--r--auto_tests/monolith_test.cpp293
-rw-r--r--cmake/CompileGTest.cmake2
-rw-r--r--testing/random_testing.cc77
-rw-r--r--toxav/BUILD.bazel2
-rw-r--r--toxav/rtp_test.cc64
-rw-r--r--toxav/rtp_test.cpp80
-rw-r--r--toxcore/BUILD.bazel4
-rw-r--r--toxcore/crypto_core_test.cc91
-rw-r--r--toxcore/crypto_core_test.cpp96
-rw-r--r--toxcore/util_test.cc51
-rw-r--r--toxcore/util_test.cpp55
14 files changed, 512 insertions, 567 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 613297ed..7147d07b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -491,7 +491,7 @@ endfunction()
491if(BUILD_TOXAV) 491if(BUILD_TOXAV)
492 add_definitions(-D__STDC_LIMIT_MACROS=1) 492 add_definitions(-D__STDC_LIMIT_MACROS=1)
493 add_executable(auto_monolith_test ${CPUFEATURES} 493 add_executable(auto_monolith_test ${CPUFEATURES}
494 auto_tests/monolith_test.cpp) 494 auto_tests/monolith_test.cc)
495 target_link_libraries(auto_monolith_test ${toxcore_LINK_MODULES}) 495 target_link_libraries(auto_monolith_test ${toxcore_LINK_MODULES})
496 add_test(NAME monolith COMMAND ${CROSSCOMPILING_EMULATOR} auto_monolith_test) 496 add_test(NAME monolith COMMAND ${CROSSCOMPILING_EMULATOR} auto_monolith_test)
497endif() 497endif()
diff --git a/auto_tests/helpers.h b/auto_tests/helpers.h
index b953e29a..7af127f5 100644
--- a/auto_tests/helpers.h
+++ b/auto_tests/helpers.h
@@ -9,6 +9,7 @@
9#include <stdio.h> 9#include <stdio.h>
10#include <string.h> 10#include <string.h>
11 11
12#ifndef c_sleep
12#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) 13#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
13#include <windows.h> 14#include <windows.h>
14#define c_sleep(x) Sleep(x) 15#define c_sleep(x) Sleep(x)
@@ -16,6 +17,7 @@
16#include <unistd.h> 17#include <unistd.h>
17#define c_sleep(x) usleep(1000 * (x)) 18#define c_sleep(x) usleep(1000 * (x))
18#endif 19#endif
20#endif
19 21
20#define ITERATION_INTERVAL 200 22#define ITERATION_INTERVAL 200
21 23
diff --git a/auto_tests/monolith_test.cc b/auto_tests/monolith_test.cc
new file mode 100644
index 00000000..9fa7ee26
--- /dev/null
+++ b/auto_tests/monolith_test.cc
@@ -0,0 +1,260 @@
1/* Nop-test, just to make sure our code compiles as C++.
2 */
3
4#ifdef __FreeBSD__
5// Include this here, because _XOPEN_SOURCE hides symbols we need.
6//
7// https://lists.freebsd.org/pipermail/freebsd-standards/2004-March/000474.html.
8#include <net/if.h>
9#endif
10
11#ifdef __APPLE__
12#define _DARWIN_C_SOURCE
13#endif
14
15#ifdef HAVE_CONFIG_H
16#include "config.h"
17#endif
18
19#include "../other/monolith.h"
20#define DHT_C_INCLUDED
21
22#include "../testing/misc_tools.c"
23#include "check_compat.h"
24#include "helpers.h"
25
26#include <ctype.h>
27
28namespace TCP_test {
29int main(void);
30#include "TCP_test.c"
31} // namespace TCP_test
32namespace bootstrap_test {
33int main(void);
34#include "bootstrap_test.c"
35} // namespace bootstrap_test
36namespace conference_test {
37int main(void);
38#include "conference_test.c"
39} // namespace conference_test
40namespace crypto_test {
41int main(void);
42#include "crypto_test.c"
43} // namespace crypto_test
44namespace dht_test {
45int main(void);
46#include "dht_test.c"
47} // namespace dht_test
48namespace encryptsave_test {
49int main(void);
50#include "encryptsave_test.c"
51} // namespace encryptsave_test
52namespace file_saving_test {
53int main(void);
54#include "file_saving_test.c"
55} // namespace file_saving_test
56namespace friend_request_test {
57int main(void);
58#include "friend_request_test.c"
59} // namespace friend_request_test
60namespace lan_discovery_test {
61int main(void);
62#include "lan_discovery_test.c"
63} // namespace lan_discovery_test
64namespace lossless_packet_test {
65int main(void);
66#include "lossless_packet_test.c"
67} // namespace lossless_packet_test
68namespace lossy_packet_test {
69int main(void);
70#include "lossy_packet_test.c"
71} // namespace lossy_packet_test
72namespace messenger_test {
73int main(void);
74#include "messenger_test.c"
75} // namespace messenger_test
76namespace network_test {
77int main(void);
78#include "network_test.c"
79} // namespace network_test
80namespace onion_test {
81int main(void);
82#include "onion_test.c"
83} // namespace onion_test
84namespace save_friend_test {
85int main(void);
86#include "save_friend_test.c"
87} // namespace save_friend_test
88namespace save_load_test {
89int main(void);
90#include "save_load_test.c"
91} // namespace save_load_test
92namespace selfname_change_conference_test {
93int main(void);
94#include "selfname_change_conference_test.c"
95} // namespace selfname_change_conference_test
96namespace self_conference_title_change_test {
97int main(void);
98#include "self_conference_title_change_test.c"
99} // namespace self_conference_title_change_test
100namespace send_message_test {
101int main(void);
102#include "send_message_test.c"
103} // namespace send_message_test
104namespace set_name_test {
105int main(void);
106#include "set_name_test.c"
107} // namespace set_name_test
108namespace set_status_message_test {
109int main(void);
110#include "set_status_message_test.c"
111} // namespace set_status_message_test
112namespace simple_conference_test {
113int main(void);
114#include "simple_conference_test.c"
115} // namespace simple_conference_test
116namespace skeleton_test {
117int main(void);
118#include "skeleton_test.c"
119} // namespace skeleton_test
120namespace toxav_basic_test {
121int main(void);
122#include "toxav_basic_test.c"
123} // namespace toxav_basic_test
124namespace toxav_many_test {
125int main(void);
126#include "toxav_many_test.c"
127} // namespace toxav_many_test
128namespace tox_many_tcp_test {
129int main(void);
130#include "tox_many_tcp_test.c"
131} // namespace tox_many_tcp_test
132namespace tox_many_test {
133int main(void);
134#include "tox_many_test.c"
135} // namespace tox_many_test
136namespace tox_one_test {
137int main(void);
138#include "tox_one_test.c"
139} // namespace tox_one_test
140namespace tox_strncasecmp_test {
141int main(void);
142#include "tox_strncasecmp_test.c"
143} // namespace tox_strncasecmp_test
144namespace typing_test {
145int main(void);
146#include "typing_test.c"
147} // namespace typing_test
148namespace version_test {
149int main(void);
150#include "version_test.c"
151} // namespace version_test
152
153#define PRINT_SIZE 0
154
155template <typename T, size_t Expected, size_t Actual = sizeof(T)>
156void check_size(char const *type) {
157#if PRINT_SIZE
158 printf("CHECK_SIZE(%s, %zu);\n", type, Actual);
159#else
160 static_assert(Actual == Expected, "Bad sizeof - see template expansion errors for details");
161#endif
162}
163
164#define CHECK_SIZE(TYPE, SIZE) check_size<TYPE, SIZE>(#TYPE)
165
166/**
167 * The main function static-asserts that we are aware of all the sizes of all
168 * the structs it toxcore. If you find this failing after you make a change,
169 * switch on the PRINT_SIZE above and copy the number into this function.
170 */
171int main(int argc, char *argv[]) {
172#if defined(__x86_64__) && defined(__LP64__)
173 // toxcore/DHT
174 CHECK_SIZE(Client_data, 496);
175 CHECK_SIZE(Cryptopacket_Handles, 16);
176 CHECK_SIZE(DHT, 676528);
177 CHECK_SIZE(DHT_Friend, 5104);
178 CHECK_SIZE(Hardening, 144);
179 CHECK_SIZE(IPPTs, 40);
180 CHECK_SIZE(IPPTsPng, 232);
181 CHECK_SIZE(NAT, 48);
182 CHECK_SIZE(Node_format, 64);
183 CHECK_SIZE(Shared_Key, 80);
184 CHECK_SIZE(Shared_Keys, 81920);
185 // toxcore/friend_connection
186 CHECK_SIZE(Friend_Conn, 1784);
187 CHECK_SIZE(Friend_Connections, 72);
188 // toxcore/friend_requests
189 CHECK_SIZE(Friend_Requests, 1080);
190 // toxcore/group
191 CHECK_SIZE(Group_c, 728);
192 CHECK_SIZE(Group_Chats, 2120);
193 CHECK_SIZE(Group_Peer, 480);
194 // toxcore/list
195 CHECK_SIZE(BS_LIST, 32);
196 // toxcore/logger
197 CHECK_SIZE(Logger, 24);
198 // toxcore/Messenger
199 CHECK_SIZE(File_Transfers, 72);
200 CHECK_SIZE(Friend, 39264);
201 CHECK_SIZE(Messenger, 2008);
202 CHECK_SIZE(Messenger_Options, 72);
203 CHECK_SIZE(Receipts, 16);
204 // toxcore/net_crypto
205#ifdef __linux__
206 CHECK_SIZE(Crypto_Connection, 525392);
207 CHECK_SIZE(Net_Crypto, 272);
208#endif
209 CHECK_SIZE(New_Connection, 168);
210 CHECK_SIZE(Packet_Data, 1384);
211 CHECK_SIZE(Packets_Array, 262152);
212 // toxcore/network
213 CHECK_SIZE(IP, 24);
214 CHECK_SIZE(IP4, 4);
215#if USE_IPV6
216 CHECK_SIZE(IP6, 16);
217#endif
218 CHECK_SIZE(IP_Port, 32);
219 CHECK_SIZE(Networking_Core, 4112);
220 CHECK_SIZE(Packet_Handler, 16);
221 // toxcore/onion_announce
222 CHECK_SIZE(Cmp_data, 296);
223 CHECK_SIZE(Onion_Announce, 128048);
224 CHECK_SIZE(Onion_Announce_Entry, 288);
225 // toxcore/onion_client
226 CHECK_SIZE(Last_Pinged, 40);
227 CHECK_SIZE(Onion_Client, 15816);
228 CHECK_SIZE(Onion_Client_Cmp_data, 176);
229 CHECK_SIZE(Onion_Client_Paths, 2520);
230 CHECK_SIZE(Onion_Friend, 1936);
231 CHECK_SIZE(Onion_Friend, 1936);
232 CHECK_SIZE(Onion_Node, 168);
233 // toxcore/onion
234 CHECK_SIZE(Onion, 245832);
235 CHECK_SIZE(Onion_Path, 392);
236 // toxcore/ping_array
237 CHECK_SIZE(Ping_Array, 24);
238 CHECK_SIZE(Ping_Array_Entry, 32);
239 // toxcore/ping
240 CHECK_SIZE(Ping, 2072);
241 // toxcore/TCP_client
242 CHECK_SIZE(TCP_Client_Connection, 12064);
243 CHECK_SIZE(TCP_Proxy_Info, 40);
244 // toxcore/TCP_connection
245 CHECK_SIZE(TCP_con, 112);
246 CHECK_SIZE(TCP_Connections, 200);
247 CHECK_SIZE(TCP_Connection_to, 112);
248 // toxcore/TCP_server
249 CHECK_SIZE(TCP_Priority_List, 16);
250 CHECK_SIZE(TCP_Secure_Connection, 11816);
251#ifdef TCP_SERVER_USE_EPOLL
252 CHECK_SIZE(TCP_Server, 6049968); // 6MB!
253#else
254 CHECK_SIZE(TCP_Server, 6049952); // 6MB!
255#endif
256 // toxcore/tox
257 CHECK_SIZE(Tox_Options, 64);
258#endif
259 return 0;
260}
diff --git a/auto_tests/monolith_test.cpp b/auto_tests/monolith_test.cpp
deleted file mode 100644
index 44a5b16b..00000000
--- a/auto_tests/monolith_test.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
1/* Nop-test, just to make sure our code compiles as C++.
2 */
3
4#ifdef __FreeBSD__
5// Include this here, because _XOPEN_SOURCE hides symbols we need.
6//
7// https://lists.freebsd.org/pipermail/freebsd-standards/2004-March/000474.html.
8#include <net/if.h>
9#endif
10
11#ifdef __APPLE__
12#define _DARWIN_C_SOURCE
13#endif
14
15#ifdef HAVE_CONFIG_H
16#include "config.h"
17#endif
18
19#include "../other/monolith.h"
20#define DHT_C_INCLUDED
21
22#include "check_compat.h"
23#include "helpers.h"
24#include "../testing/misc_tools.c"
25
26#include <ctype.h>
27
28namespace TCP_test
29{
30int main(void);
31#include "TCP_test.c"
32}
33namespace bootstrap_test
34{
35int main(void);
36#include "bootstrap_test.c"
37}
38namespace conference_test
39{
40int main(void);
41#include "conference_test.c"
42}
43namespace crypto_test
44{
45int main(void);
46#include "crypto_test.c"
47}
48namespace dht_test
49{
50int main(void);
51#include "dht_test.c"
52}
53namespace encryptsave_test
54{
55int main(void);
56#include "encryptsave_test.c"
57}
58namespace file_saving_test
59{
60int main(void);
61#include "file_saving_test.c"
62}
63namespace friend_request_test
64{
65int main(void);
66#include "friend_request_test.c"
67}
68namespace lan_discovery_test
69{
70int main(void);
71#include "lan_discovery_test.c"
72}
73namespace lossless_packet_test
74{
75int main(void);
76#include "lossless_packet_test.c"
77}
78namespace lossy_packet_test
79{
80int main(void);
81#include "lossy_packet_test.c"
82}
83namespace messenger_test
84{
85int main(void);
86#include "messenger_test.c"
87}
88namespace network_test
89{
90int main(void);
91#include "network_test.c"
92}
93namespace onion_test
94{
95int main(void);
96#include "onion_test.c"
97}
98namespace save_friend_test
99{
100int main(void);
101#include "save_friend_test.c"
102}
103namespace save_load_test
104{
105int main(void);
106#include "save_load_test.c"
107}
108namespace selfname_change_conference_test
109{
110int main(void);
111#include "selfname_change_conference_test.c"
112}
113namespace self_conference_title_change_test
114{
115int main(void);
116#include "self_conference_title_change_test.c"
117}
118namespace send_message_test
119{
120int main(void);
121#include "send_message_test.c"
122}
123namespace set_name_test
124{
125int main(void);
126#include "set_name_test.c"
127}
128namespace set_status_message_test
129{
130int main(void);
131#include "set_status_message_test.c"
132}
133namespace simple_conference_test
134{
135int main(void);
136#include "simple_conference_test.c"
137}
138namespace skeleton_test
139{
140int main(void);
141#include "skeleton_test.c"
142}
143namespace toxav_basic_test
144{
145int main(void);
146#include "toxav_basic_test.c"
147}
148namespace toxav_many_test
149{
150int main(void);
151#include "toxav_many_test.c"
152}
153namespace tox_many_tcp_test
154{
155int main(void);
156#include "tox_many_tcp_test.c"
157}
158namespace tox_many_test
159{
160int main(void);
161#include "tox_many_test.c"
162}
163namespace tox_one_test
164{
165int main(void);
166#include "tox_one_test.c"
167}
168namespace tox_strncasecmp_test
169{
170int main(void);
171#include "tox_strncasecmp_test.c"
172}
173namespace typing_test
174{
175int main(void);
176#include "typing_test.c"
177}
178namespace version_test
179{
180int main(void);
181#include "version_test.c"
182}
183
184#define PRINT_SIZE 0
185
186template<typename T, size_t Expected, size_t Actual = sizeof(T)>
187void check_size(char const *type)
188{
189#if PRINT_SIZE
190 printf("CHECK_SIZE(%s, %zu);\n", type, Actual);
191#else
192 static_assert(Actual == Expected, "Bad sizeof - see template expansion errors for details");
193#endif
194}
195
196#define CHECK_SIZE(TYPE, SIZE) check_size<TYPE, SIZE>(#TYPE)
197
198/**
199 * The main function static-asserts that we are aware of all the sizes of all
200 * the structs it toxcore. If you find this failing after you make a change,
201 * switch on the PRINT_SIZE above and copy the number into this function.
202 */
203int main(int argc, char *argv[])
204{
205#if defined(__x86_64__) && defined(__LP64__)
206 // toxcore/DHT
207 CHECK_SIZE(Client_data, 496);
208 CHECK_SIZE(Cryptopacket_Handles, 16);
209 CHECK_SIZE(DHT, 676528);
210 CHECK_SIZE(DHT_Friend, 5104);
211 CHECK_SIZE(Hardening, 144);
212 CHECK_SIZE(IPPTs, 40);
213 CHECK_SIZE(IPPTsPng, 232);
214 CHECK_SIZE(NAT, 48);
215 CHECK_SIZE(Node_format, 64);
216 CHECK_SIZE(Shared_Key, 80);
217 CHECK_SIZE(Shared_Keys, 81920);
218 // toxcore/friend_connection
219 CHECK_SIZE(Friend_Conn, 1784);
220 CHECK_SIZE(Friend_Connections, 72);
221 // toxcore/friend_requests
222 CHECK_SIZE(Friend_Requests, 1080);
223 // toxcore/group
224 CHECK_SIZE(Group_c, 728);
225 CHECK_SIZE(Group_Chats, 2120);
226 CHECK_SIZE(Group_Peer, 480);
227 // toxcore/list
228 CHECK_SIZE(BS_LIST, 32);
229 // toxcore/logger
230 CHECK_SIZE(Logger, 24);
231 // toxcore/Messenger
232 CHECK_SIZE(File_Transfers, 72);
233 CHECK_SIZE(Friend, 39264);
234 CHECK_SIZE(Messenger, 2008);
235 CHECK_SIZE(Messenger_Options, 72);
236 CHECK_SIZE(Receipts, 16);
237 // toxcore/net_crypto
238#ifdef __linux__
239 CHECK_SIZE(Crypto_Connection, 525392);
240 CHECK_SIZE(Net_Crypto, 272);
241#endif
242 CHECK_SIZE(New_Connection, 168);
243 CHECK_SIZE(Packet_Data, 1384);
244 CHECK_SIZE(Packets_Array, 262152);
245 // toxcore/network
246 CHECK_SIZE(IP, 24);
247 CHECK_SIZE(IP4, 4);
248#if USE_IPV6
249 CHECK_SIZE(IP6, 16);
250#endif
251 CHECK_SIZE(IP_Port, 32);
252 CHECK_SIZE(Networking_Core, 4112);
253 CHECK_SIZE(Packet_Handler, 16);
254 // toxcore/onion_announce
255 CHECK_SIZE(Cmp_data, 296);
256 CHECK_SIZE(Onion_Announce, 128048);
257 CHECK_SIZE(Onion_Announce_Entry, 288);
258 // toxcore/onion_client
259 CHECK_SIZE(Last_Pinged, 40);
260 CHECK_SIZE(Onion_Client, 15816);
261 CHECK_SIZE(Onion_Client_Cmp_data, 176);
262 CHECK_SIZE(Onion_Client_Paths, 2520);
263 CHECK_SIZE(Onion_Friend, 1936);
264 CHECK_SIZE(Onion_Friend, 1936);
265 CHECK_SIZE(Onion_Node, 168);
266 // toxcore/onion
267 CHECK_SIZE(Onion, 245832);
268 CHECK_SIZE(Onion_Path, 392);
269 // toxcore/ping_array
270 CHECK_SIZE(Ping_Array, 24);
271 CHECK_SIZE(Ping_Array_Entry, 32);
272 // toxcore/ping
273 CHECK_SIZE(Ping, 2072);
274 // toxcore/TCP_client
275 CHECK_SIZE(TCP_Client_Connection, 12064);
276 CHECK_SIZE(TCP_Proxy_Info, 40);
277 // toxcore/TCP_connection
278 CHECK_SIZE(TCP_con, 112);
279 CHECK_SIZE(TCP_Connections, 200);
280 CHECK_SIZE(TCP_Connection_to, 112);
281 // toxcore/TCP_server
282 CHECK_SIZE(TCP_Priority_List, 16);
283 CHECK_SIZE(TCP_Secure_Connection, 11816);
284#ifdef TCP_SERVER_USE_EPOLL
285 CHECK_SIZE(TCP_Server, 6049968); // 6MB!
286#else
287 CHECK_SIZE(TCP_Server, 6049952); // 6MB!
288#endif
289 // toxcore/tox
290 CHECK_SIZE(Tox_Options, 64);
291#endif
292 return 0;
293}
diff --git a/cmake/CompileGTest.cmake b/cmake/CompileGTest.cmake
index b7e0175f..f9aa4506 100644
--- a/cmake/CompileGTest.cmake
+++ b/cmake/CompileGTest.cmake
@@ -50,7 +50,7 @@ endif()
50 50
51function(unit_test subdir target) 51function(unit_test subdir target)
52 if(HAVE_GTEST) 52 if(HAVE_GTEST)
53 add_executable(unit_${target}_test ${subdir}/${target}_test.cpp) 53 add_executable(unit_${target}_test ${subdir}/${target}_test.cc)
54 target_link_modules(unit_${target}_test toxcore gtest) 54 target_link_modules(unit_${target}_test toxcore gtest)
55 set_target_properties(unit_${target}_test PROPERTIES COMPILE_FLAGS "${TEST_CXX_FLAGS}") 55 set_target_properties(unit_${target}_test PROPERTIES COMPILE_FLAGS "${TEST_CXX_FLAGS}")
56 add_test(NAME ${target} COMMAND ${CROSSCOMPILING_EMULATOR} unit_${target}_test) 56 add_test(NAME ${target} COMMAND ${CROSSCOMPILING_EMULATOR} unit_${target}_test)
diff --git a/testing/random_testing.cc b/testing/random_testing.cc
index ecad07d3..b896e694 100644
--- a/testing/random_testing.cc
+++ b/testing/random_testing.cc
@@ -15,7 +15,7 @@
15namespace { 15namespace {
16 16
17// Whether to write log messages when handling callbacks. 17// Whether to write log messages when handling callbacks.
18constexpr bool LOG_CALLBACKS = 0; 18constexpr bool LOG_CALLBACKS = false;
19 19
20// Number of participants in the test run. 20// Number of participants in the test run.
21constexpr uint32_t NUM_TOXES = 10; 21constexpr uint32_t NUM_TOXES = 10;
@@ -79,7 +79,7 @@ struct Action {
79 uint32_t weight; 79 uint32_t weight;
80 char const *title; 80 char const *title;
81 bool (*can)(Local_State const &state); 81 bool (*can)(Local_State const &state);
82 void (*run)(Local_State &state, Random &rnd, std::mt19937 &rng); 82 void (*run)(Local_State *state, Random *rnd, std::mt19937 *rng);
83}; 83};
84 84
85std::vector<size_t> get_action_weights(std::vector<Action> const &actions) { 85std::vector<size_t> get_action_weights(std::vector<Action> const &actions) {
@@ -107,7 +107,7 @@ struct Global_State : std::vector<Local_State> {
107 : actions_(actions), rnd_(actions), action_counter_(actions.size()) {} 107 : actions_(actions), rnd_(actions), action_counter_(actions.size()) {}
108 108
109 Action const &action(size_t id) const { return actions_.at(id); } 109 Action const &action(size_t id) const { return actions_.at(id); }
110 Random &rnd() { return rnd_; } 110 Random *rnd() { return &rnd_; }
111 std::vector<unsigned> &action_counter() { return action_counter_; } 111 std::vector<unsigned> &action_counter() { return action_counter_; }
112 112
113 private: 113 private:
@@ -147,7 +147,8 @@ void handle_conference_message(Tox *tox, uint32_t conference_number, uint32_t pe
147 Local_State *state = static_cast<Local_State *>(user_data); 147 Local_State *state = static_cast<Local_State *>(user_data);
148 148
149 if (LOG_CALLBACKS) { 149 if (LOG_CALLBACKS) {
150 std::printf("Tox #%u received a message of length %u\n", state->id(), (unsigned)length); 150 std::printf("Tox #%u received a message of length %u\n", state->id(),
151 static_cast<unsigned>(length));
151 } 152 }
152} 153}
153 154
@@ -227,18 +228,18 @@ bool all_connected(Global_State const &toxes) {
227 }); 228 });
228} 229}
229 230
230bool bootstrap_toxes(Global_State &toxes) { 231bool bootstrap_toxes(Global_State *toxes) {
231 std::printf("Waiting for %u iterations for all friends to come online\n", 232 std::printf("Waiting for %u iterations for all friends to come online\n",
232 MAX_BOOTSTRAP_ITERATIONS); 233 MAX_BOOTSTRAP_ITERATIONS);
233 234
234 for (uint32_t i = 0; i < MAX_BOOTSTRAP_ITERATIONS; i++) { 235 for (uint32_t i = 0; i < MAX_BOOTSTRAP_ITERATIONS; i++) {
235 c_sleep(tox_iteration_interval(toxes.front().tox())); 236 c_sleep(tox_iteration_interval(toxes->front().tox()));
236 237
237 for (Local_State &state : toxes) { 238 for (Local_State &state : *toxes) {
238 tox_iterate(state.tox(), &state); 239 tox_iterate(state.tox(), &state);
239 } 240 }
240 241
241 if (all_connected(toxes)) { 242 if (all_connected(*toxes)) {
242 std::printf("Took %u iterations\n", i); 243 std::printf("Took %u iterations\n", i);
243 return true; 244 return true;
244 } 245 }
@@ -247,25 +248,25 @@ bool bootstrap_toxes(Global_State &toxes) {
247 return false; 248 return false;
248} 249}
249 250
250bool execute_random_action(Global_State &toxes, std::mt19937 &rng) { 251bool execute_random_action(Global_State *toxes, std::mt19937 *rng) {
251 // First, choose a random actor. 252 // First, choose a random actor.
252 Local_State &actor = toxes.at(toxes.rnd().tox_selector(rng)); 253 Local_State &actor = toxes->at(toxes->rnd()->tox_selector(*rng));
253 size_t const action_id = toxes.rnd().action_selector(rng); 254 size_t const action_id = toxes->rnd()->action_selector(*rng);
254 Action const &action = toxes.action(action_id); 255 Action const &action = toxes->action(action_id);
255 if (!action.can(actor)) { 256 if (!action.can(actor)) {
256 return false; 257 return false;
257 } 258 }
258 259
259 std::printf("Tox #%u %s", actor.id(), action.title); 260 std::printf("Tox #%u %s", actor.id(), action.title);
260 action.run(actor, toxes.rnd(), rng); 261 action.run(&actor, toxes->rnd(), rng);
261 std::printf("\n"); 262 std::printf("\n");
262 263
263 toxes.action_counter().at(action_id)++; 264 toxes->action_counter().at(action_id)++;
264 265
265 return true; 266 return true;
266} 267}
267 268
268bool attempt_action(Global_State &toxes, std::mt19937 &rng) { 269bool attempt_action(Global_State *toxes, std::mt19937 *rng) {
269 for (uint32_t i = 0; i < MAX_ACTION_ATTEMPTS; i++) { 270 for (uint32_t i = 0; i < MAX_ACTION_ATTEMPTS; i++) {
270 if (execute_random_action(toxes, rng)) { 271 if (execute_random_action(toxes, rng)) {
271 return true; 272 return true;
@@ -284,9 +285,9 @@ int main() {
284 [](Local_State const &state) { 285 [](Local_State const &state) {
285 return tox_conference_get_chatlist_size(state.tox()) < MAX_CONFERENCES_PER_USER; 286 return tox_conference_get_chatlist_size(state.tox()) < MAX_CONFERENCES_PER_USER;
286 }, 287 },
287 [](Local_State &state, Random &rnd, std::mt19937 &rng) { 288 [](Local_State *state, Random *rnd, std::mt19937 *rng) {
288 TOX_ERR_CONFERENCE_NEW err; 289 TOX_ERR_CONFERENCE_NEW err;
289 tox_conference_new(state.tox(), &err); 290 tox_conference_new(state->tox(), &err);
290 assert(err == TOX_ERR_CONFERENCE_NEW_OK); 291 assert(err == TOX_ERR_CONFERENCE_NEW_OK);
291 }, 292 },
292 }, 293 },
@@ -295,12 +296,12 @@ int main() {
295 [](Local_State const &state) { 296 [](Local_State const &state) {
296 return tox_conference_get_chatlist_size(state.tox()) != 0; 297 return tox_conference_get_chatlist_size(state.tox()) != 0;
297 }, 298 },
298 [](Local_State &state, Random &rnd, std::mt19937 &rng) { 299 [](Local_State *state, Random *rnd, std::mt19937 *rng) {
299 TOX_ERR_CONFERENCE_INVITE err; 300 TOX_ERR_CONFERENCE_INVITE err;
300 tox_conference_invite(state.tox(), rnd.friend_selector(rng), 301 tox_conference_invite(
301 state.next_invite % tox_conference_get_chatlist_size(state.tox()), 302 state->tox(), rnd->friend_selector(*rng),
302 &err); 303 state->next_invite % tox_conference_get_chatlist_size(state->tox()), &err);
303 state.next_invite++; 304 state->next_invite++;
304 assert(err == TOX_ERR_CONFERENCE_INVITE_OK); 305 assert(err == TOX_ERR_CONFERENCE_INVITE_OK);
305 }, 306 },
306 }, 307 },
@@ -309,9 +310,9 @@ int main() {
309 [](Local_State const &state) { 310 [](Local_State const &state) {
310 return tox_conference_get_chatlist_size(state.tox()) != 0; 311 return tox_conference_get_chatlist_size(state.tox()) != 0;
311 }, 312 },
312 [](Local_State &state, Random &rnd, std::mt19937 &rng) { 313 [](Local_State *state, Random *rnd, std::mt19937 *rng) {
313 TOX_ERR_CONFERENCE_DELETE err; 314 TOX_ERR_CONFERENCE_DELETE err;
314 tox_conference_delete(state.tox(), tox_conference_get_chatlist_size(state.tox()) - 1, 315 tox_conference_delete(state->tox(), tox_conference_get_chatlist_size(state->tox()) - 1,
315 &err); 316 &err);
316 assert(err == TOX_ERR_CONFERENCE_DELETE_OK); 317 assert(err == TOX_ERR_CONFERENCE_DELETE_OK);
317 }, 318 },
@@ -321,18 +322,18 @@ int main() {
321 [](Local_State const &state) { 322 [](Local_State const &state) {
322 return tox_conference_get_chatlist_size(state.tox()) != 0; 323 return tox_conference_get_chatlist_size(state.tox()) != 0;
323 }, 324 },
324 [](Local_State &state, Random &rnd, std::mt19937 &rng) { 325 [](Local_State *state, Random *rnd, std::mt19937 *rng) {
325 std::vector<uint8_t> message(rnd.message_length_selector(rng)); 326 std::vector<uint8_t> message(rnd->message_length_selector(*rng));
326 for (uint8_t &byte : message) { 327 for (uint8_t &byte : message) {
327 byte = rnd.byte_selector(rng); 328 byte = rnd->byte_selector(*rng);
328 } 329 }
329 330
330 TOX_ERR_CONFERENCE_SEND_MESSAGE err; 331 TOX_ERR_CONFERENCE_SEND_MESSAGE err;
331 tox_conference_send_message( 332 tox_conference_send_message(
332 state.tox(), tox_conference_get_chatlist_size(state.tox()) - 1, 333 state->tox(), tox_conference_get_chatlist_size(state->tox()) - 1,
333 TOX_MESSAGE_TYPE_NORMAL, message.data(), message.size(), &err); 334 TOX_MESSAGE_TYPE_NORMAL, message.data(), message.size(), &err);
334 if (err == TOX_ERR_CONFERENCE_SEND_MESSAGE_OK) { 335 if (err == TOX_ERR_CONFERENCE_SEND_MESSAGE_OK) {
335 printf(" (OK, length = %u)", (unsigned)message.size()); 336 printf(" (OK, length = %u)", static_cast<unsigned>(message.size()));
336 } else { 337 } else {
337 printf(" (FAILED: %u)", err); 338 printf(" (FAILED: %u)", err);
338 } 339 }
@@ -340,24 +341,24 @@ int main() {
340 }, 341 },
341 { 342 {
342 10, "changes their name", [](Local_State const &state) { return true; }, 343 10, "changes their name", [](Local_State const &state) { return true; },
343 [](Local_State &state, Random &rnd, std::mt19937 &rng) { 344 [](Local_State *state, Random *rnd, std::mt19937 *rng) {
344 std::vector<uint8_t> name(rnd.name_length_selector(rng)); 345 std::vector<uint8_t> name(rnd->name_length_selector(*rng));
345 for (uint8_t &byte : name) { 346 for (uint8_t &byte : name) {
346 byte = rnd.byte_selector(rng); 347 byte = rnd->byte_selector(*rng);
347 } 348 }
348 349
349 TOX_ERR_SET_INFO err; 350 TOX_ERR_SET_INFO err;
350 tox_self_set_name(state.tox(), name.data(), name.size(), &err); 351 tox_self_set_name(state->tox(), name.data(), name.size(), &err);
351 assert(err == TOX_ERR_SET_INFO_OK); 352 assert(err == TOX_ERR_SET_INFO_OK);
352 353
353 printf(" (length = %u)", (unsigned)name.size()); 354 printf(" (length = %u)", static_cast<unsigned>(name.size()));
354 }, 355 },
355 }, 356 },
356 { 357 {
357 10, "sets their name to empty", [](Local_State const &state) { return true; }, 358 10, "sets their name to empty", [](Local_State const &state) { return true; },
358 [](Local_State &state, Random &rnd, std::mt19937 &rng) { 359 [](Local_State *state, Random *rnd, std::mt19937 *rng) {
359 TOX_ERR_SET_INFO err; 360 TOX_ERR_SET_INFO err;
360 tox_self_set_name(state.tox(), nullptr, 0, &err); 361 tox_self_set_name(state->tox(), nullptr, 0, &err);
361 assert(err == TOX_ERR_SET_INFO_OK); 362 assert(err == TOX_ERR_SET_INFO_OK);
362 }, 363 },
363 }, 364 },
@@ -368,12 +369,12 @@ int main() {
368 std::mt19937 rng; 369 std::mt19937 rng;
369 uint32_t action_number; 370 uint32_t action_number;
370 for (action_number = 0; action_number < MAX_ACTIONS; action_number++) { 371 for (action_number = 0; action_number < MAX_ACTIONS; action_number++) {
371 if (!all_connected(toxes) && !bootstrap_toxes(toxes)) { 372 if (!all_connected(toxes) && !bootstrap_toxes(&toxes)) {
372 std::printf("Bootstrapping took too long; %u actions performed\n", action_number); 373 std::printf("Bootstrapping took too long; %u actions performed\n", action_number);
373 return EXIT_FAILURE; 374 return EXIT_FAILURE;
374 } 375 }
375 376
376 if (!attempt_action(toxes, rng)) { 377 if (!attempt_action(&toxes, &rng)) {
377 std::printf( 378 std::printf(
378 "System is stuck after %u actions: none of the toxes can perform an action anymore\n", 379 "System is stuck after %u actions: none of the toxes can perform an action anymore\n",
379 action_number); 380 action_number);
diff --git a/toxav/BUILD.bazel b/toxav/BUILD.bazel
index cf905910..a5d49e0d 100644
--- a/toxav/BUILD.bazel
+++ b/toxav/BUILD.bazel
@@ -37,7 +37,7 @@ cc_library(
37 37
38cc_test( 38cc_test(
39 name = "rtp_test", 39 name = "rtp_test",
40 srcs = ["rtp_test.cpp"], 40 srcs = ["rtp_test.cc"],
41 deps = [ 41 deps = [
42 ":rtp", 42 ":rtp",
43 "//c-toxcore/toxcore:crypto_core", 43 "//c-toxcore/toxcore:crypto_core",
diff --git a/toxav/rtp_test.cc b/toxav/rtp_test.cc
new file mode 100644
index 00000000..b41ff905
--- /dev/null
+++ b/toxav/rtp_test.cc
@@ -0,0 +1,64 @@
1#include "rtp.h"
2
3#include "../toxcore/crypto_core.h"
4
5#include <gtest/gtest.h>
6
7namespace {
8
9RTPHeader random_header() {
10 return {
11 random_u16(), random_u16(), random_u16(), random_u16(), random_u16(),
12 random_u16(), random_u16(), random_u32(), random_u32(), random_u64(),
13 random_u32(), random_u32(), random_u32(), random_u16(), random_u16(),
14 };
15}
16
17TEST(Rtp, Deserialisation) {
18 RTPHeader const header = random_header();
19
20 uint8_t rdata[RTP_HEADER_SIZE];
21 EXPECT_EQ(rtp_header_pack(rdata, &header), RTP_HEADER_SIZE);
22
23 RTPHeader unpacked = {0};
24 EXPECT_EQ(rtp_header_unpack(rdata, &unpacked), RTP_HEADER_SIZE);
25
26 EXPECT_EQ(header.ve, unpacked.ve);
27 EXPECT_EQ(header.pe, unpacked.pe);
28 EXPECT_EQ(header.xe, unpacked.xe);
29 EXPECT_EQ(header.cc, unpacked.cc);
30 EXPECT_EQ(header.ma, unpacked.ma);
31 EXPECT_EQ(header.pt, unpacked.pt);
32 EXPECT_EQ(header.sequnum, unpacked.sequnum);
33 EXPECT_EQ(header.timestamp, unpacked.timestamp);
34 EXPECT_EQ(header.ssrc, unpacked.ssrc);
35 EXPECT_EQ(header.flags, unpacked.flags);
36 EXPECT_EQ(header.offset_full, unpacked.offset_full);
37 EXPECT_EQ(header.data_length_full, unpacked.data_length_full);
38 EXPECT_EQ(header.received_length_full, unpacked.received_length_full);
39 EXPECT_EQ(header.offset_lower, unpacked.offset_lower);
40 EXPECT_EQ(header.data_length_lower, unpacked.data_length_lower);
41}
42
43TEST(Rtp, SerialisingAllOnes) {
44 RTPHeader header;
45 memset(&header, 0xff, sizeof header);
46
47 uint8_t rdata[RTP_HEADER_SIZE];
48 rtp_header_pack(rdata, &header);
49
50 EXPECT_EQ(std::string((char const *)rdata, sizeof rdata),
51 std::string("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
52 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
53 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
54 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
55 "\x00\x00\x00\x00\x00\x00\x00\x00"
56 "\x00\x00\x00\x00\x00\x00\x00\x00"
57 "\x00\x00\x00\x00\x00\x00\x00\x00"
58 "\x00\x00\x00\x00\x00\x00\x00\x00"
59 "\x00\x00\x00\x00\x00\x00\x00\x00"
60 "\x00\x00\x00\x00\xFF\xFF\xFF\xFF",
61 RTP_HEADER_SIZE));
62}
63
64} // namespace
diff --git a/toxav/rtp_test.cpp b/toxav/rtp_test.cpp
deleted file mode 100644
index d6717a28..00000000
--- a/toxav/rtp_test.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
1#include "rtp.h"
2
3#include "../toxcore/crypto_core.h"
4
5#include <gtest/gtest.h>
6
7namespace
8{
9
10RTPHeader random_header()
11{
12 return {
13 random_u16(),
14 random_u16(),
15 random_u16(),
16 random_u16(),
17 random_u16(),
18 random_u16(),
19 random_u16(),
20 random_u32(),
21 random_u32(),
22 random_u64(),
23 random_u32(),
24 random_u32(),
25 random_u32(),
26 random_u16(),
27 random_u16(),
28 };
29}
30
31TEST(Rtp, Deserialisation)
32{
33 RTPHeader const header = random_header();
34
35 uint8_t rdata[RTP_HEADER_SIZE];
36 EXPECT_EQ(rtp_header_pack(rdata, &header), RTP_HEADER_SIZE);
37
38 RTPHeader unpacked = {0};
39 EXPECT_EQ(rtp_header_unpack(rdata, &unpacked), RTP_HEADER_SIZE);
40
41 EXPECT_EQ(header.ve, unpacked.ve);
42 EXPECT_EQ(header.pe, unpacked.pe);
43 EXPECT_EQ(header.xe, unpacked.xe);
44 EXPECT_EQ(header.cc, unpacked.cc);
45 EXPECT_EQ(header.ma, unpacked.ma);
46 EXPECT_EQ(header.pt, unpacked.pt);
47 EXPECT_EQ(header.sequnum, unpacked.sequnum);
48 EXPECT_EQ(header.timestamp, unpacked.timestamp);
49 EXPECT_EQ(header.ssrc, unpacked.ssrc);
50 EXPECT_EQ(header.flags, unpacked.flags);
51 EXPECT_EQ(header.offset_full, unpacked.offset_full);
52 EXPECT_EQ(header.data_length_full, unpacked.data_length_full);
53 EXPECT_EQ(header.received_length_full, unpacked.received_length_full);
54 EXPECT_EQ(header.offset_lower, unpacked.offset_lower);
55 EXPECT_EQ(header.data_length_lower, unpacked.data_length_lower);
56}
57
58TEST(Rtp, SerialisingAllOnes)
59{
60 RTPHeader header;
61 memset(&header, 0xff, sizeof header);
62
63 uint8_t rdata[RTP_HEADER_SIZE];
64 rtp_header_pack(rdata, &header);
65
66 EXPECT_EQ(std::string((char const *)rdata, sizeof rdata),
67 std::string("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
68 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
69 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
70 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
71 "\x00\x00\x00\x00\x00\x00\x00\x00"
72 "\x00\x00\x00\x00\x00\x00\x00\x00"
73 "\x00\x00\x00\x00\x00\x00\x00\x00"
74 "\x00\x00\x00\x00\x00\x00\x00\x00"
75 "\x00\x00\x00\x00\x00\x00\x00\x00"
76 "\x00\x00\x00\x00\xFF\xFF\xFF\xFF",
77 RTP_HEADER_SIZE));
78}
79
80} // namespace
diff --git a/toxcore/BUILD.bazel b/toxcore/BUILD.bazel
index b22f9b9e..1d43d828 100644
--- a/toxcore/BUILD.bazel
+++ b/toxcore/BUILD.bazel
@@ -30,7 +30,7 @@ cc_library(
30 30
31cc_test( 31cc_test(
32 name = "crypto_core_test", 32 name = "crypto_core_test",
33 srcs = ["crypto_core_test.cpp"], 33 srcs = ["crypto_core_test.cc"],
34 deps = [ 34 deps = [
35 ":crypto_core", 35 ":crypto_core",
36 "@com_google_googletest//:gtest_main", 36 "@com_google_googletest//:gtest_main",
@@ -75,7 +75,7 @@ cc_library(
75 75
76cc_test( 76cc_test(
77 name = "util_test", 77 name = "util_test",
78 srcs = ["util_test.cpp"], 78 srcs = ["util_test.cc"],
79 deps = [ 79 deps = [
80 ":network", 80 ":network",
81 "@com_google_googletest//:gtest_main", 81 "@com_google_googletest//:gtest_main",
diff --git a/toxcore/crypto_core_test.cc b/toxcore/crypto_core_test.cc
new file mode 100644
index 00000000..1fbdd296
--- /dev/null
+++ b/toxcore/crypto_core_test.cc
@@ -0,0 +1,91 @@
1#include "crypto_core.h"
2
3#include <algorithm>
4
5#include <gtest/gtest.h>
6
7namespace {
8
9enum {
10 /**
11 * The size of the arrays to compare. This was chosen to take around 2000
12 * CPU clocks on x86_64.
13 */
14 CRYPTO_TEST_MEMCMP_SIZE = 1024 * 1024, // 1 MiB
15 /**
16 * The number of times we run memcmp in the test.
17 *
18 * We compute the median time taken to reduce error margins.
19 */
20 CRYPTO_TEST_MEMCMP_ITERATIONS = 500,
21 /**
22 * The margin of error (in clocks) we allow for this test.
23 *
24 * Should be within 0.5% of ~2000 CPU clocks. In reality, the code is much
25 * more precise and is usually within 1 CPU clock.
26 */
27 CRYPTO_TEST_MEMCMP_EPS = 10,
28};
29
30clock_t memcmp_time(void *a, void *b, size_t len) {
31 clock_t start = clock();
32 crypto_memcmp(a, b, len);
33 return clock() - start;
34}
35
36/**
37 * This function performs the actual timing. It interleaves comparison of
38 * equal and non-equal arrays to reduce the influence of external effects
39 * such as the machine being a little more busy 1 second later.
40 */
41void memcmp_median(void *src, void *same, void *not_same, size_t len, clock_t *same_median,
42 clock_t *not_same_median) {
43 clock_t same_results[CRYPTO_TEST_MEMCMP_ITERATIONS];
44 clock_t not_same_results[CRYPTO_TEST_MEMCMP_ITERATIONS];
45
46 for (size_t i = 0; i < CRYPTO_TEST_MEMCMP_ITERATIONS; i++) {
47 same_results[i] = memcmp_time(src, same, len);
48 not_same_results[i] = memcmp_time(src, not_same, len);
49 }
50
51 std::sort(same_results, same_results + CRYPTO_TEST_MEMCMP_ITERATIONS);
52 *same_median = same_results[CRYPTO_TEST_MEMCMP_ITERATIONS / 2];
53 std::sort(not_same_results, not_same_results + CRYPTO_TEST_MEMCMP_ITERATIONS);
54 *not_same_median = not_same_results[CRYPTO_TEST_MEMCMP_ITERATIONS / 2];
55}
56
57/**
58 * This test checks whether crypto_memcmp takes the same time for equal and
59 * non-equal chunks of memory.
60 */
61TEST(CryptoCore, MemcmpTimingIsDataIndependent) {
62 // A random piece of memory.
63 auto *src = new uint8_t[CRYPTO_TEST_MEMCMP_SIZE];
64 random_bytes(src, CRYPTO_TEST_MEMCMP_SIZE);
65
66 // A separate piece of memory containing the same data.
67 auto *same = new uint8_t[CRYPTO_TEST_MEMCMP_SIZE];
68 memcpy(same, src, CRYPTO_TEST_MEMCMP_SIZE);
69
70 // Another piece of memory containing different data.
71 auto *not_same = new uint8_t[CRYPTO_TEST_MEMCMP_SIZE];
72 random_bytes(not_same, CRYPTO_TEST_MEMCMP_SIZE);
73
74 clock_t same_median;
75 clock_t not_same_median;
76 memcmp_median(src, same, not_same, CRYPTO_TEST_MEMCMP_SIZE, &same_median, &not_same_median);
77
78 delete[] not_same;
79 delete[] same;
80 delete[] src;
81
82 clock_t const delta =
83 same_median > not_same_median ? same_median - not_same_median : not_same_median - same_median;
84
85 EXPECT_LT(delta, CRYPTO_TEST_MEMCMP_EPS)
86 << "Delta time is too long (" << delta << " >= " << CRYPTO_TEST_MEMCMP_EPS << ")\n"
87 << "Time of the same data comparation: " << same_median << " clocks\n"
88 << "Time of the different data comparation: " << not_same_median << " clocks";
89}
90
91} // namespace
diff --git a/toxcore/crypto_core_test.cpp b/toxcore/crypto_core_test.cpp
deleted file mode 100644
index 8f91dce8..00000000
--- a/toxcore/crypto_core_test.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
1#include "crypto_core.h"
2
3#include <algorithm>
4
5#include <gtest/gtest.h>
6
7namespace
8{
9
10enum {
11 /**
12 * The size of the arrays to compare. This was chosen to take around 2000
13 * CPU clocks on x86_64.
14 */
15 CRYPTO_TEST_MEMCMP_SIZE = 1024 * 1024, // 1 MiB
16 /**
17 * The number of times we run memcmp in the test.
18 *
19 * We compute the median time taken to reduce error margins.
20 */
21 CRYPTO_TEST_MEMCMP_ITERATIONS = 500,
22 /**
23 * The margin of error (in clocks) we allow for this test.
24 *
25 * Should be within 0.5% of ~2000 CPU clocks. In reality, the code is much
26 * more precise and is usually within 1 CPU clock.
27 */
28 CRYPTO_TEST_MEMCMP_EPS = 10,
29};
30
31clock_t memcmp_time(void *a, void *b, size_t len)
32{
33 clock_t start = clock();
34 crypto_memcmp(a, b, len);
35 return clock() - start;
36}
37
38/**
39 * This function performs the actual timing. It interleaves comparison of
40 * equal and non-equal arrays to reduce the influence of external effects
41 * such as the machine being a little more busy 1 second later.
42 */
43void memcmp_median(void *src, void *same, void *not_same, size_t len,
44 clock_t *same_median, clock_t *not_same_median)
45{
46 clock_t same_results[CRYPTO_TEST_MEMCMP_ITERATIONS];
47 clock_t not_same_results[CRYPTO_TEST_MEMCMP_ITERATIONS];
48
49 for (size_t i = 0; i < CRYPTO_TEST_MEMCMP_ITERATIONS; i++) {
50 same_results[i] = memcmp_time(src, same, len);
51 not_same_results[i] = memcmp_time(src, not_same, len);
52 }
53
54 std::sort(same_results, same_results + CRYPTO_TEST_MEMCMP_ITERATIONS);
55 *same_median = same_results[CRYPTO_TEST_MEMCMP_ITERATIONS / 2];
56 std::sort(not_same_results, not_same_results + CRYPTO_TEST_MEMCMP_ITERATIONS);
57 *not_same_median = not_same_results[CRYPTO_TEST_MEMCMP_ITERATIONS / 2];
58}
59
60/**
61 * This test checks whether crypto_memcmp takes the same time for equal and
62 * non-equal chunks of memory.
63 */
64TEST(CryptoCore, MemcmpTimingIsDataIndependent)
65{
66 // A random piece of memory.
67 uint8_t *src = new uint8_t[CRYPTO_TEST_MEMCMP_SIZE];
68 random_bytes(src, CRYPTO_TEST_MEMCMP_SIZE);
69
70 // A separate piece of memory containing the same data.
71 uint8_t *same = new uint8_t[CRYPTO_TEST_MEMCMP_SIZE];
72 memcpy(same, src, CRYPTO_TEST_MEMCMP_SIZE);
73
74 // Another piece of memory containing different data.
75 uint8_t *not_same = new uint8_t[CRYPTO_TEST_MEMCMP_SIZE];
76 random_bytes(not_same, CRYPTO_TEST_MEMCMP_SIZE);
77
78 clock_t same_median;
79 clock_t not_same_median;
80 memcmp_median(src, same, not_same, CRYPTO_TEST_MEMCMP_SIZE, &same_median, &not_same_median);
81
82 delete[] not_same;
83 delete[] same;
84 delete[] src;
85
86 clock_t const delta = same_median > not_same_median
87 ? same_median - not_same_median
88 : not_same_median - same_median;
89
90 EXPECT_LT(delta, CRYPTO_TEST_MEMCMP_EPS)
91 << "Delta time is too long (" << delta << " >= " << CRYPTO_TEST_MEMCMP_EPS << ")\n"
92 << "Time of the same data comparation: " << same_median << " clocks\n"
93 << "Time of the different data comparation: " << not_same_median << " clocks";
94}
95
96} // namespace
diff --git a/toxcore/util_test.cc b/toxcore/util_test.cc
new file mode 100644
index 00000000..541aa61f
--- /dev/null
+++ b/toxcore/util_test.cc
@@ -0,0 +1,51 @@
1#include "util.h"
2
3#include "crypto_core.h"
4
5#include <gtest/gtest.h>
6
7TEST(Util, UnixTimeIncreasesOverTime) {
8 unix_time_update();
9 uint64_t const start = unix_time();
10
11 while (start == unix_time()) {
12 unix_time_update();
13 }
14
15 uint64_t const end = unix_time();
16 EXPECT_GT(end, start);
17}
18
19TEST(Util, IsTimeout) {
20 uint64_t const start = unix_time();
21 EXPECT_FALSE(is_timeout(start, 1));
22
23 while (start == unix_time()) {
24 unix_time_update();
25 }
26
27 EXPECT_TRUE(is_timeout(start, 1));
28}
29
30TEST(Util, TwoRandomIdsAreNotEqual) {
31 uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
32 uint8_t sk1[CRYPTO_SECRET_KEY_SIZE];
33 uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE];
34 uint8_t sk2[CRYPTO_SECRET_KEY_SIZE];
35
36 crypto_new_keypair(pk1, sk1);
37 crypto_new_keypair(pk2, sk2);
38
39 EXPECT_FALSE(id_equal(pk1, pk2));
40}
41
42TEST(Util, IdCopyMakesKeysEqual) {
43 uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
44 uint8_t sk1[CRYPTO_SECRET_KEY_SIZE];
45 uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE] = {0};
46
47 crypto_new_keypair(pk1, sk1);
48 id_copy(pk2, pk1);
49
50 EXPECT_TRUE(id_equal(pk1, pk2));
51}
diff --git a/toxcore/util_test.cpp b/toxcore/util_test.cpp
deleted file mode 100644
index 8de63848..00000000
--- a/toxcore/util_test.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
1#include "util.h"
2
3#include "crypto_core.h"
4
5#include <gtest/gtest.h>
6
7TEST(Util, UnixTimeIncreasesOverTime)
8{
9 unix_time_update();
10 uint64_t const start = unix_time();
11
12 while (start == unix_time()) {
13 unix_time_update();
14 }
15
16 uint64_t const end = unix_time();
17 EXPECT_GT(end, start);
18}
19
20TEST(Util, IsTimeout)
21{
22 uint64_t const start = unix_time();
23 EXPECT_FALSE(is_timeout(start, 1));
24
25 while (start == unix_time()) {
26 unix_time_update();
27 }
28
29 EXPECT_TRUE(is_timeout(start, 1));
30}
31
32TEST(Util, TwoRandomIdsAreNotEqual)
33{
34 uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
35 uint8_t sk1[CRYPTO_SECRET_KEY_SIZE];
36 uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE];
37 uint8_t sk2[CRYPTO_SECRET_KEY_SIZE];
38
39 crypto_new_keypair(pk1, sk1);
40 crypto_new_keypair(pk2, sk2);
41
42 EXPECT_FALSE(id_equal(pk1, pk2));
43}
44
45TEST(Util, IdCopyMakesKeysEqual)
46{
47 uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
48 uint8_t sk1[CRYPTO_SECRET_KEY_SIZE];
49 uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE] = {0};
50
51 crypto_new_keypair(pk1, sk1);
52 id_copy(pk2, pk1);
53
54 EXPECT_TRUE(id_equal(pk1, pk2));
55}