2016-07-13 03:32:35 +08:00
|
|
|
/* Auto Tests
|
|
|
|
*
|
|
|
|
* Tox Tests
|
|
|
|
*
|
|
|
|
* The following tests were written with a small Tox network in mind. Therefore,
|
|
|
|
* each test timeout was set to one for a small Tox Network. If connected to the
|
|
|
|
* 'Global' Tox Network, traversing the DHT would take MUCH longer than the
|
|
|
|
* timeouts allow. Because of this running these tests require NO other Tox
|
|
|
|
* clients running or accessible on/to localhost.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2018-01-29 05:30:39 +08:00
|
|
|
#ifndef _XOPEN_SOURCE
|
2017-01-06 20:19:12 +08:00
|
|
|
#define _XOPEN_SOURCE 600
|
2018-01-29 05:30:39 +08:00
|
|
|
#endif
|
2017-01-06 20:19:12 +08:00
|
|
|
|
2013-12-18 07:55:28 +08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2017-06-05 04:58:28 +08:00
|
|
|
#include "check_compat.h"
|
|
|
|
|
2013-12-18 07:55:28 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2016-11-02 22:34:33 +08:00
|
|
|
#include <time.h>
|
2013-12-18 07:55:28 +08:00
|
|
|
|
2017-01-21 05:16:55 +08:00
|
|
|
#include "../toxcore/ccompat.h"
|
2013-12-18 07:55:28 +08:00
|
|
|
#include "../toxcore/tox.h"
|
2016-09-17 20:48:11 +08:00
|
|
|
#include "../toxcore/util.h"
|
2013-12-18 07:55:28 +08:00
|
|
|
|
2014-08-08 04:59:47 +08:00
|
|
|
#include "helpers.h"
|
|
|
|
|
2016-07-13 03:32:35 +08:00
|
|
|
/* The Travis-CI container responds poorly to ::1 as a localhost address
|
|
|
|
* You're encouraged to -D FORCE_TESTS_IPV6 on a local test */
|
|
|
|
#ifdef FORCE_TESTS_IPV6
|
|
|
|
#define TOX_LOCALHOST "::1"
|
|
|
|
#else
|
|
|
|
#define TOX_LOCALHOST "127.0.0.1"
|
|
|
|
#endif
|
2015-03-11 05:31:50 +08:00
|
|
|
|
2016-09-05 23:10:48 +08:00
|
|
|
static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
|
2013-12-18 07:55:28 +08:00
|
|
|
{
|
2016-09-01 02:12:19 +08:00
|
|
|
if (*((uint32_t *)userdata) != 974536) {
|
2014-03-17 01:24:39 +08:00
|
|
|
return;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2013-12-18 07:55:28 +08:00
|
|
|
|
2014-01-18 02:35:40 +08:00
|
|
|
if (length == 7 && memcmp("Gentoo", data, 7) == 0) {
|
2018-01-29 05:30:39 +08:00
|
|
|
tox_friend_add_norequest(m, public_key, nullptr);
|
2014-01-18 02:35:40 +08:00
|
|
|
}
|
2013-12-18 07:55:28 +08:00
|
|
|
}
|
2016-09-05 23:10:48 +08:00
|
|
|
static uint32_t messages_received;
|
2013-12-23 11:30:14 +08:00
|
|
|
|
2016-09-05 23:10:48 +08:00
|
|
|
static void print_message(Tox *m, uint32_t friendnumber, TOX_MESSAGE_TYPE type, const uint8_t *string, size_t length,
|
|
|
|
void *userdata)
|
2013-12-23 11:30:14 +08:00
|
|
|
{
|
2016-09-01 02:12:19 +08:00
|
|
|
if (*((uint32_t *)userdata) != 974536) {
|
2013-12-23 11:30:14 +08:00
|
|
|
return;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2013-12-23 11:30:14 +08:00
|
|
|
|
2015-03-19 05:14:57 +08:00
|
|
|
if (type != TOX_MESSAGE_TYPE_NORMAL) {
|
2015-03-19 03:32:53 +08:00
|
|
|
ck_abort_msg("Bad type");
|
|
|
|
}
|
|
|
|
|
2014-06-02 08:48:02 +08:00
|
|
|
uint8_t cmp_msg[TOX_MAX_MESSAGE_LENGTH];
|
|
|
|
memset(cmp_msg, 'G', sizeof(cmp_msg));
|
|
|
|
|
2016-09-01 02:12:19 +08:00
|
|
|
if (length == TOX_MAX_MESSAGE_LENGTH && memcmp(string, cmp_msg, sizeof(cmp_msg)) == 0) {
|
2013-12-23 11:30:14 +08:00
|
|
|
++messages_received;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2013-12-23 11:30:14 +08:00
|
|
|
}
|
|
|
|
|
2016-09-05 23:10:48 +08:00
|
|
|
static uint32_t name_changes;
|
2013-12-23 11:30:14 +08:00
|
|
|
|
2016-09-05 23:10:48 +08:00
|
|
|
static void print_nickchange(Tox *m, uint32_t friendnumber, const uint8_t *string, size_t length, void *userdata)
|
2013-12-23 11:30:14 +08:00
|
|
|
{
|
2016-09-01 02:12:19 +08:00
|
|
|
if (*((uint32_t *)userdata) != 974536) {
|
2013-12-23 11:30:14 +08:00
|
|
|
return;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2013-12-23 11:30:14 +08:00
|
|
|
|
2016-09-01 02:12:19 +08:00
|
|
|
if (length == sizeof("Gentoo") && memcmp(string, "Gentoo", sizeof("Gentoo")) == 0) {
|
2013-12-23 11:30:14 +08:00
|
|
|
++name_changes;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2013-12-23 11:30:14 +08:00
|
|
|
}
|
2013-12-18 07:55:28 +08:00
|
|
|
|
2016-09-05 23:10:48 +08:00
|
|
|
static uint32_t status_m_changes;
|
|
|
|
static void print_status_m_change(Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length,
|
|
|
|
void *user_data)
|
2015-03-13 00:18:52 +08:00
|
|
|
{
|
2016-09-01 02:12:19 +08:00
|
|
|
if (*((uint32_t *)user_data) != 974536) {
|
2015-03-13 00:18:52 +08:00
|
|
|
return;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2015-03-13 00:18:52 +08:00
|
|
|
|
2016-09-13 04:37:58 +08:00
|
|
|
if (length == sizeof("Installing Gentoo") &&
|
|
|
|
memcmp(message, "Installing Gentoo", sizeof("Installing Gentoo")) == 0) {
|
2015-03-13 00:18:52 +08:00
|
|
|
++status_m_changes;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2015-03-13 00:18:52 +08:00
|
|
|
}
|
|
|
|
|
2016-09-05 23:10:48 +08:00
|
|
|
static uint32_t typing_changes;
|
2014-02-19 02:49:17 +08:00
|
|
|
|
2016-09-05 23:10:48 +08:00
|
|
|
static void print_typingchange(Tox *m, uint32_t friendnumber, bool typing, void *userdata)
|
2014-02-19 02:49:17 +08:00
|
|
|
{
|
2016-09-01 02:12:19 +08:00
|
|
|
if (*((uint32_t *)userdata) != 974536) {
|
2014-02-19 02:49:17 +08:00
|
|
|
return;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2014-02-19 02:49:17 +08:00
|
|
|
|
2016-09-01 02:12:19 +08:00
|
|
|
if (!typing) {
|
2014-02-19 02:49:17 +08:00
|
|
|
typing_changes = 1;
|
2016-09-01 02:12:19 +08:00
|
|
|
} else {
|
2014-02-19 02:49:17 +08:00
|
|
|
typing_changes = 2;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2014-02-19 02:49:17 +08:00
|
|
|
}
|
|
|
|
|
2016-09-05 23:10:48 +08:00
|
|
|
static uint32_t custom_packet;
|
2014-09-09 00:20:44 +08:00
|
|
|
|
2016-09-05 23:10:48 +08:00
|
|
|
static void handle_custom_packet(Tox *m, uint32_t friend_num, const uint8_t *data, size_t len, void *object)
|
2014-09-09 00:20:44 +08:00
|
|
|
{
|
|
|
|
uint8_t number = *((uint32_t *)object);
|
|
|
|
|
2016-09-01 02:12:19 +08:00
|
|
|
if (len != TOX_MAX_CUSTOM_PACKET_SIZE) {
|
2015-02-26 21:24:19 +08:00
|
|
|
return;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2014-09-09 00:20:44 +08:00
|
|
|
|
2017-01-21 05:16:55 +08:00
|
|
|
VLA(uint8_t, f_data, len);
|
2014-09-09 00:20:44 +08:00
|
|
|
memset(f_data, number, len);
|
2014-11-26 04:31:46 +08:00
|
|
|
|
2014-09-09 00:20:44 +08:00
|
|
|
if (memcmp(f_data, data, len) == 0) {
|
|
|
|
++custom_packet;
|
|
|
|
} else {
|
2015-03-11 05:31:50 +08:00
|
|
|
ck_abort_msg("Custom packet fail. %u", number);
|
2014-09-09 00:20:44 +08:00
|
|
|
}
|
2014-09-22 02:55:23 +08:00
|
|
|
|
2015-02-26 21:24:19 +08:00
|
|
|
return;
|
2014-09-09 00:20:44 +08:00
|
|
|
}
|
|
|
|
|
2016-09-05 23:10:48 +08:00
|
|
|
static unsigned int connected_t1;
|
|
|
|
static void tox_connection_status(Tox *tox, TOX_CONNECTION connection_status, void *user_data)
|
2015-03-12 03:37:25 +08:00
|
|
|
{
|
2016-09-01 02:12:19 +08:00
|
|
|
if (*((uint32_t *)user_data) != 974536) {
|
2015-03-12 03:37:25 +08:00
|
|
|
return;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2015-03-12 03:37:25 +08:00
|
|
|
|
2016-09-01 02:12:19 +08:00
|
|
|
if (connected_t1 && !connection_status) {
|
2015-03-12 03:37:25 +08:00
|
|
|
ck_abort_msg("Tox went offline");
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2015-03-12 03:37:25 +08:00
|
|
|
|
2015-07-04 09:52:53 +08:00
|
|
|
ck_assert_msg(connection_status == TOX_CONNECTION_UDP, "wrong status %u", connection_status);
|
|
|
|
|
2015-03-12 03:37:25 +08:00
|
|
|
connected_t1 = connection_status;
|
|
|
|
}
|
|
|
|
|
2013-12-18 07:55:28 +08:00
|
|
|
START_TEST(test_few_clients)
|
|
|
|
{
|
2016-11-06 00:52:41 +08:00
|
|
|
uint32_t index[] = { 1, 2, 3 };
|
2018-01-29 05:30:39 +08:00
|
|
|
long long unsigned int con_time = 0, cur_time = time(nullptr);
|
2015-03-13 03:17:34 +08:00
|
|
|
TOX_ERR_NEW t_n_error;
|
2018-01-29 05:30:39 +08:00
|
|
|
Tox *tox1 = tox_new_log(nullptr, &t_n_error, &index[0]);
|
2015-03-13 03:17:34 +08:00
|
|
|
ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "wrong error");
|
2018-01-29 05:30:39 +08:00
|
|
|
Tox *tox2 = tox_new_log(nullptr, &t_n_error, &index[1]);
|
2015-03-13 03:17:34 +08:00
|
|
|
ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "wrong error");
|
2018-01-29 05:30:39 +08:00
|
|
|
Tox *tox3 = tox_new_log(nullptr, &t_n_error, &index[2]);
|
2015-03-13 03:17:34 +08:00
|
|
|
ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "wrong error");
|
|
|
|
|
2016-09-11 15:02:44 +08:00
|
|
|
ck_assert_msg(tox1 && tox2 && tox3, "Failed to create 3 tox instances");
|
2015-03-11 20:09:45 +08:00
|
|
|
|
|
|
|
{
|
|
|
|
TOX_ERR_GET_PORT error;
|
2017-08-25 14:30:40 +08:00
|
|
|
uint16_t first_port = tox_self_get_udp_port(tox1, &error);
|
|
|
|
ck_assert_msg(33445 <= first_port && first_port <= 33545 - 2,
|
|
|
|
"First Tox instance did not bind to udp port inside [33445, 33543].\n");
|
2015-03-11 20:09:45 +08:00
|
|
|
ck_assert_msg(error == TOX_ERR_GET_PORT_OK, "wrong error");
|
|
|
|
|
2017-08-25 14:30:40 +08:00
|
|
|
ck_assert_msg(tox_self_get_udp_port(tox2, &error) == first_port + 1,
|
|
|
|
"Second Tox instance did not bind to udp port %d.\n", first_port + 1);
|
2015-03-13 07:04:49 +08:00
|
|
|
ck_assert_msg(error == TOX_ERR_GET_PORT_OK, "wrong error");
|
|
|
|
|
2017-08-25 14:30:40 +08:00
|
|
|
ck_assert_msg(tox_self_get_udp_port(tox3, &error) == first_port + 2,
|
|
|
|
"Third Tox instance did not bind to udp port %d.\n", first_port + 2);
|
2015-03-13 07:04:49 +08:00
|
|
|
ck_assert_msg(error == TOX_ERR_GET_PORT_OK, "wrong error");
|
|
|
|
}
|
|
|
|
|
2014-03-17 01:24:39 +08:00
|
|
|
uint32_t to_compare = 974536;
|
2015-03-12 03:37:25 +08:00
|
|
|
connected_t1 = 0;
|
Make self_connection_status callback stateless.
**What are we doing?**
We are moving towards stateless callbacks. This means that when registering a
callback, you no longer pass a user data pointer. Instead, you pass a user data
pointer to tox_iterate. This pointer is threaded through the code, passed to
each callback. The callback can modify the data pointed at. An extra indirection
will be needed if the pointer itself can change.
**Why?**
Currently, callbacks are registered with a user data pointer. This means the
library has N pointers for N different callbacks. These pointers need to be
managed by the client code. Managing the lifetime of the pointee can be
difficult. In C++, it takes special effort to ensure that the lifetime of user
data extends at least beyond the lifetime of the Tox instance. For other
languages, the situation is much worse. Java and other garbage collected
languages may move objects in memory, so the pointers are not stable. Tox4j goes
through a lot of effort to make the Java/Scala user experience a pleasant one by
keeping a global array of Tox+userdata on the C++ side, and communicating via
protobufs. A Haskell FFI would have to do similarly complex tricks.
Stateless callbacks ensure that a user data pointer only needs to live during a
single function call. This means that the user code (or language runtime) can
move the data around at will, as long as it sets the new location in the
callback.
**How?**
We are doing this change one callback at a time. After each callback, we ensure
that everything still works as expected. This means the toxcore change will
require 15 Pull Requests.
2016-08-10 20:46:04 +08:00
|
|
|
tox_callback_self_connection_status(tox1, tox_connection_status);
|
2016-08-23 05:44:58 +08:00
|
|
|
tox_callback_friend_request(tox2, accept_friend_request);
|
2015-02-26 21:24:19 +08:00
|
|
|
uint8_t address[TOX_ADDRESS_SIZE];
|
|
|
|
tox_self_get_address(tox2, address);
|
2018-01-29 05:30:39 +08:00
|
|
|
uint32_t test = tox_friend_add(tox3, address, (const uint8_t *)"Gentoo", 7, nullptr);
|
2013-12-18 07:55:28 +08:00
|
|
|
ck_assert_msg(test == 0, "Failed to add friend error code: %i", test);
|
|
|
|
|
2014-01-18 02:35:40 +08:00
|
|
|
uint8_t off = 1;
|
|
|
|
|
2013-12-18 07:55:28 +08:00
|
|
|
while (1) {
|
Make self_connection_status callback stateless.
**What are we doing?**
We are moving towards stateless callbacks. This means that when registering a
callback, you no longer pass a user data pointer. Instead, you pass a user data
pointer to tox_iterate. This pointer is threaded through the code, passed to
each callback. The callback can modify the data pointed at. An extra indirection
will be needed if the pointer itself can change.
**Why?**
Currently, callbacks are registered with a user data pointer. This means the
library has N pointers for N different callbacks. These pointers need to be
managed by the client code. Managing the lifetime of the pointee can be
difficult. In C++, it takes special effort to ensure that the lifetime of user
data extends at least beyond the lifetime of the Tox instance. For other
languages, the situation is much worse. Java and other garbage collected
languages may move objects in memory, so the pointers are not stable. Tox4j goes
through a lot of effort to make the Java/Scala user experience a pleasant one by
keeping a global array of Tox+userdata on the C++ side, and communicating via
protobufs. A Haskell FFI would have to do similarly complex tricks.
Stateless callbacks ensure that a user data pointer only needs to live during a
single function call. This means that the user code (or language runtime) can
move the data around at will, as long as it sets the new location in the
callback.
**How?**
We are doing this change one callback at a time. After each callback, we ensure
that everything still works as expected. This means the toxcore change will
require 15 Pull Requests.
2016-08-10 20:46:04 +08:00
|
|
|
tox_iterate(tox1, &to_compare);
|
|
|
|
tox_iterate(tox2, &to_compare);
|
|
|
|
tox_iterate(tox3, &to_compare);
|
2013-12-18 07:55:28 +08:00
|
|
|
|
2015-03-19 04:15:36 +08:00
|
|
|
if (tox_self_get_connection_status(tox1) && tox_self_get_connection_status(tox2)
|
|
|
|
&& tox_self_get_connection_status(tox3)) {
|
2015-03-12 03:37:25 +08:00
|
|
|
if (off) {
|
2018-01-29 05:30:39 +08:00
|
|
|
printf("Toxes are online, took %llu seconds\n", time(nullptr) - cur_time);
|
|
|
|
con_time = time(nullptr);
|
2015-03-12 03:37:25 +08:00
|
|
|
off = 0;
|
|
|
|
}
|
2014-01-18 02:35:40 +08:00
|
|
|
|
2018-01-29 05:30:39 +08:00
|
|
|
if (tox_friend_get_connection_status(tox2, 0, nullptr) == TOX_CONNECTION_UDP
|
|
|
|
&& tox_friend_get_connection_status(tox3, 0, nullptr) == TOX_CONNECTION_UDP) {
|
2015-03-12 03:37:25 +08:00
|
|
|
break;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2015-03-12 03:37:25 +08:00
|
|
|
}
|
2013-12-18 07:55:28 +08:00
|
|
|
|
|
|
|
c_sleep(50);
|
|
|
|
}
|
|
|
|
|
2015-03-12 03:37:25 +08:00
|
|
|
ck_assert_msg(connected_t1, "Tox1 isn't connected. %u", connected_t1);
|
2018-01-29 05:30:39 +08:00
|
|
|
printf("tox clients connected took %llu seconds\n", time(nullptr) - con_time);
|
2014-03-17 01:24:39 +08:00
|
|
|
to_compare = 974536;
|
2016-08-20 02:01:58 +08:00
|
|
|
tox_callback_friend_message(tox3, print_message);
|
2014-06-02 08:48:02 +08:00
|
|
|
uint8_t msgs[TOX_MAX_MESSAGE_LENGTH + 1];
|
|
|
|
memset(msgs, 'G', sizeof(msgs));
|
2015-03-12 06:26:25 +08:00
|
|
|
TOX_ERR_FRIEND_SEND_MESSAGE errm;
|
2015-03-19 05:14:57 +08:00
|
|
|
tox_friend_send_message(tox2, 0, TOX_MESSAGE_TYPE_NORMAL, msgs, TOX_MAX_MESSAGE_LENGTH + 1, &errm);
|
2015-03-12 06:26:25 +08:00
|
|
|
ck_assert_msg(errm == TOX_ERR_FRIEND_SEND_MESSAGE_TOO_LONG, "TOX_MAX_MESSAGE_LENGTH is too small\n");
|
2015-03-19 05:14:57 +08:00
|
|
|
tox_friend_send_message(tox2, 0, TOX_MESSAGE_TYPE_NORMAL, msgs, TOX_MAX_MESSAGE_LENGTH, &errm);
|
2015-03-12 06:26:25 +08:00
|
|
|
ck_assert_msg(errm == TOX_ERR_FRIEND_SEND_MESSAGE_OK, "TOX_MAX_MESSAGE_LENGTH is too big\n");
|
2013-12-23 11:30:14 +08:00
|
|
|
|
|
|
|
while (1) {
|
|
|
|
messages_received = 0;
|
Make self_connection_status callback stateless.
**What are we doing?**
We are moving towards stateless callbacks. This means that when registering a
callback, you no longer pass a user data pointer. Instead, you pass a user data
pointer to tox_iterate. This pointer is threaded through the code, passed to
each callback. The callback can modify the data pointed at. An extra indirection
will be needed if the pointer itself can change.
**Why?**
Currently, callbacks are registered with a user data pointer. This means the
library has N pointers for N different callbacks. These pointers need to be
managed by the client code. Managing the lifetime of the pointee can be
difficult. In C++, it takes special effort to ensure that the lifetime of user
data extends at least beyond the lifetime of the Tox instance. For other
languages, the situation is much worse. Java and other garbage collected
languages may move objects in memory, so the pointers are not stable. Tox4j goes
through a lot of effort to make the Java/Scala user experience a pleasant one by
keeping a global array of Tox+userdata on the C++ side, and communicating via
protobufs. A Haskell FFI would have to do similarly complex tricks.
Stateless callbacks ensure that a user data pointer only needs to live during a
single function call. This means that the user code (or language runtime) can
move the data around at will, as long as it sets the new location in the
callback.
**How?**
We are doing this change one callback at a time. After each callback, we ensure
that everything still works as expected. This means the toxcore change will
require 15 Pull Requests.
2016-08-10 20:46:04 +08:00
|
|
|
tox_iterate(tox1, &to_compare);
|
|
|
|
tox_iterate(tox2, &to_compare);
|
|
|
|
tox_iterate(tox3, &to_compare);
|
2013-12-23 11:30:14 +08:00
|
|
|
|
2016-09-01 02:12:19 +08:00
|
|
|
if (messages_received) {
|
2013-12-23 11:30:14 +08:00
|
|
|
break;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2013-12-23 11:30:14 +08:00
|
|
|
|
|
|
|
c_sleep(50);
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("tox clients messaging succeeded\n");
|
|
|
|
|
2015-06-07 10:13:43 +08:00
|
|
|
unsigned int save_size1 = tox_get_savedata_size(tox2);
|
2017-08-25 14:48:04 +08:00
|
|
|
ck_assert_msg(save_size1 != 0, "save is invalid size %u", save_size1);
|
2015-06-07 10:13:43 +08:00
|
|
|
printf("%u\n", save_size1);
|
2017-01-21 05:16:55 +08:00
|
|
|
VLA(uint8_t, save1, save_size1);
|
2015-06-07 10:13:43 +08:00
|
|
|
tox_get_savedata(tox2, save1);
|
2015-06-13 11:05:37 +08:00
|
|
|
tox_kill(tox2);
|
|
|
|
|
2018-01-29 05:30:39 +08:00
|
|
|
struct Tox_Options *options = tox_options_new(nullptr);
|
2016-12-16 01:35:54 +08:00
|
|
|
tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE);
|
|
|
|
tox_options_set_savedata_data(options, save1, save_size1);
|
2018-01-29 05:30:39 +08:00
|
|
|
tox2 = tox_new_log(options, nullptr, &index[1]);
|
|
|
|
cur_time = time(nullptr);
|
2015-06-13 11:05:37 +08:00
|
|
|
off = 1;
|
|
|
|
|
|
|
|
while (1) {
|
Make self_connection_status callback stateless.
**What are we doing?**
We are moving towards stateless callbacks. This means that when registering a
callback, you no longer pass a user data pointer. Instead, you pass a user data
pointer to tox_iterate. This pointer is threaded through the code, passed to
each callback. The callback can modify the data pointed at. An extra indirection
will be needed if the pointer itself can change.
**Why?**
Currently, callbacks are registered with a user data pointer. This means the
library has N pointers for N different callbacks. These pointers need to be
managed by the client code. Managing the lifetime of the pointee can be
difficult. In C++, it takes special effort to ensure that the lifetime of user
data extends at least beyond the lifetime of the Tox instance. For other
languages, the situation is much worse. Java and other garbage collected
languages may move objects in memory, so the pointers are not stable. Tox4j goes
through a lot of effort to make the Java/Scala user experience a pleasant one by
keeping a global array of Tox+userdata on the C++ side, and communicating via
protobufs. A Haskell FFI would have to do similarly complex tricks.
Stateless callbacks ensure that a user data pointer only needs to live during a
single function call. This means that the user code (or language runtime) can
move the data around at will, as long as it sets the new location in the
callback.
**How?**
We are doing this change one callback at a time. After each callback, we ensure
that everything still works as expected. This means the toxcore change will
require 15 Pull Requests.
2016-08-10 20:46:04 +08:00
|
|
|
tox_iterate(tox1, &to_compare);
|
|
|
|
tox_iterate(tox2, &to_compare);
|
|
|
|
tox_iterate(tox3, &to_compare);
|
2015-06-13 11:05:37 +08:00
|
|
|
|
|
|
|
if (tox_self_get_connection_status(tox1) && tox_self_get_connection_status(tox2)
|
|
|
|
&& tox_self_get_connection_status(tox3)) {
|
|
|
|
if (off) {
|
2018-01-29 05:30:39 +08:00
|
|
|
printf("Toxes are online again after reloading, took %llu seconds\n", time(nullptr) - cur_time);
|
|
|
|
con_time = time(nullptr);
|
2015-06-13 11:05:37 +08:00
|
|
|
off = 0;
|
|
|
|
}
|
2015-06-07 10:13:43 +08:00
|
|
|
|
2018-01-29 05:30:39 +08:00
|
|
|
if (tox_friend_get_connection_status(tox2, 0, nullptr) == TOX_CONNECTION_UDP
|
|
|
|
&& tox_friend_get_connection_status(tox3, 0, nullptr) == TOX_CONNECTION_UDP) {
|
2015-06-13 11:05:37 +08:00
|
|
|
break;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2015-06-13 11:05:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
c_sleep(50);
|
|
|
|
}
|
|
|
|
|
2018-01-29 05:30:39 +08:00
|
|
|
printf("tox clients connected took %llu seconds\n", time(nullptr) - con_time);
|
2016-08-17 17:52:04 +08:00
|
|
|
tox_callback_friend_name(tox3, print_nickchange);
|
2015-02-26 21:24:19 +08:00
|
|
|
TOX_ERR_SET_INFO err_n;
|
2016-09-05 23:10:48 +08:00
|
|
|
bool succ = tox_self_set_name(tox2, (const uint8_t *)"Gentoo", sizeof("Gentoo"), &err_n);
|
2015-02-26 21:24:19 +08:00
|
|
|
ck_assert_msg(succ && err_n == TOX_ERR_SET_INFO_OK, "tox_self_set_name failed because %u\n", err_n);
|
2013-12-23 11:30:14 +08:00
|
|
|
|
|
|
|
while (1) {
|
|
|
|
name_changes = 0;
|
Make self_connection_status callback stateless.
**What are we doing?**
We are moving towards stateless callbacks. This means that when registering a
callback, you no longer pass a user data pointer. Instead, you pass a user data
pointer to tox_iterate. This pointer is threaded through the code, passed to
each callback. The callback can modify the data pointed at. An extra indirection
will be needed if the pointer itself can change.
**Why?**
Currently, callbacks are registered with a user data pointer. This means the
library has N pointers for N different callbacks. These pointers need to be
managed by the client code. Managing the lifetime of the pointee can be
difficult. In C++, it takes special effort to ensure that the lifetime of user
data extends at least beyond the lifetime of the Tox instance. For other
languages, the situation is much worse. Java and other garbage collected
languages may move objects in memory, so the pointers are not stable. Tox4j goes
through a lot of effort to make the Java/Scala user experience a pleasant one by
keeping a global array of Tox+userdata on the C++ side, and communicating via
protobufs. A Haskell FFI would have to do similarly complex tricks.
Stateless callbacks ensure that a user data pointer only needs to live during a
single function call. This means that the user code (or language runtime) can
move the data around at will, as long as it sets the new location in the
callback.
**How?**
We are doing this change one callback at a time. After each callback, we ensure
that everything still works as expected. This means the toxcore change will
require 15 Pull Requests.
2016-08-10 20:46:04 +08:00
|
|
|
tox_iterate(tox1, &to_compare);
|
|
|
|
tox_iterate(tox2, &to_compare);
|
|
|
|
tox_iterate(tox3, &to_compare);
|
2013-12-23 11:30:14 +08:00
|
|
|
|
2016-09-01 02:12:19 +08:00
|
|
|
if (name_changes) {
|
2013-12-23 11:30:14 +08:00
|
|
|
break;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2013-12-23 11:30:14 +08:00
|
|
|
|
|
|
|
c_sleep(50);
|
|
|
|
}
|
|
|
|
|
2018-01-29 05:30:39 +08:00
|
|
|
ck_assert_msg(tox_friend_get_name_size(tox3, 0, nullptr) == sizeof("Gentoo"), "Name length not correct");
|
2013-12-23 11:30:14 +08:00
|
|
|
uint8_t temp_name[sizeof("Gentoo")];
|
2018-01-29 05:30:39 +08:00
|
|
|
tox_friend_get_name(tox3, 0, temp_name, nullptr);
|
2013-12-23 11:30:14 +08:00
|
|
|
ck_assert_msg(memcmp(temp_name, "Gentoo", sizeof("Gentoo")) == 0, "Name not correct");
|
2014-02-19 02:49:17 +08:00
|
|
|
|
2016-08-18 07:37:45 +08:00
|
|
|
tox_callback_friend_status_message(tox3, print_status_m_change);
|
2016-09-05 23:10:48 +08:00
|
|
|
succ = tox_self_set_status_message(tox2, (const uint8_t *)"Installing Gentoo", sizeof("Installing Gentoo"), &err_n);
|
2015-03-13 00:18:52 +08:00
|
|
|
ck_assert_msg(succ && err_n == TOX_ERR_SET_INFO_OK, "tox_self_set_status_message failed because %u\n", err_n);
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
status_m_changes = 0;
|
Make self_connection_status callback stateless.
**What are we doing?**
We are moving towards stateless callbacks. This means that when registering a
callback, you no longer pass a user data pointer. Instead, you pass a user data
pointer to tox_iterate. This pointer is threaded through the code, passed to
each callback. The callback can modify the data pointed at. An extra indirection
will be needed if the pointer itself can change.
**Why?**
Currently, callbacks are registered with a user data pointer. This means the
library has N pointers for N different callbacks. These pointers need to be
managed by the client code. Managing the lifetime of the pointee can be
difficult. In C++, it takes special effort to ensure that the lifetime of user
data extends at least beyond the lifetime of the Tox instance. For other
languages, the situation is much worse. Java and other garbage collected
languages may move objects in memory, so the pointers are not stable. Tox4j goes
through a lot of effort to make the Java/Scala user experience a pleasant one by
keeping a global array of Tox+userdata on the C++ side, and communicating via
protobufs. A Haskell FFI would have to do similarly complex tricks.
Stateless callbacks ensure that a user data pointer only needs to live during a
single function call. This means that the user code (or language runtime) can
move the data around at will, as long as it sets the new location in the
callback.
**How?**
We are doing this change one callback at a time. After each callback, we ensure
that everything still works as expected. This means the toxcore change will
require 15 Pull Requests.
2016-08-10 20:46:04 +08:00
|
|
|
tox_iterate(tox1, &to_compare);
|
|
|
|
tox_iterate(tox2, &to_compare);
|
|
|
|
tox_iterate(tox3, &to_compare);
|
2015-03-13 00:18:52 +08:00
|
|
|
|
2016-09-01 02:12:19 +08:00
|
|
|
if (status_m_changes) {
|
2015-03-13 00:18:52 +08:00
|
|
|
break;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2015-03-13 00:18:52 +08:00
|
|
|
|
|
|
|
c_sleep(50);
|
|
|
|
}
|
|
|
|
|
2018-01-29 05:30:39 +08:00
|
|
|
ck_assert_msg(tox_friend_get_status_message_size(tox3, 0, nullptr) == sizeof("Installing Gentoo"),
|
2015-03-13 00:18:52 +08:00
|
|
|
"status message length not correct");
|
|
|
|
uint8_t temp_status_m[sizeof("Installing Gentoo")];
|
2018-01-29 05:30:39 +08:00
|
|
|
tox_friend_get_status_message(tox3, 0, temp_status_m, nullptr);
|
2015-03-13 00:18:52 +08:00
|
|
|
ck_assert_msg(memcmp(temp_status_m, "Installing Gentoo", sizeof("Installing Gentoo")) == 0,
|
|
|
|
"status message not correct");
|
|
|
|
|
2016-08-20 07:13:23 +08:00
|
|
|
tox_callback_friend_typing(tox2, &print_typingchange);
|
2018-01-29 05:30:39 +08:00
|
|
|
tox_self_set_typing(tox3, 0, 1, nullptr);
|
2014-02-19 02:49:17 +08:00
|
|
|
|
|
|
|
while (1) {
|
|
|
|
typing_changes = 0;
|
Make self_connection_status callback stateless.
**What are we doing?**
We are moving towards stateless callbacks. This means that when registering a
callback, you no longer pass a user data pointer. Instead, you pass a user data
pointer to tox_iterate. This pointer is threaded through the code, passed to
each callback. The callback can modify the data pointed at. An extra indirection
will be needed if the pointer itself can change.
**Why?**
Currently, callbacks are registered with a user data pointer. This means the
library has N pointers for N different callbacks. These pointers need to be
managed by the client code. Managing the lifetime of the pointee can be
difficult. In C++, it takes special effort to ensure that the lifetime of user
data extends at least beyond the lifetime of the Tox instance. For other
languages, the situation is much worse. Java and other garbage collected
languages may move objects in memory, so the pointers are not stable. Tox4j goes
through a lot of effort to make the Java/Scala user experience a pleasant one by
keeping a global array of Tox+userdata on the C++ side, and communicating via
protobufs. A Haskell FFI would have to do similarly complex tricks.
Stateless callbacks ensure that a user data pointer only needs to live during a
single function call. This means that the user code (or language runtime) can
move the data around at will, as long as it sets the new location in the
callback.
**How?**
We are doing this change one callback at a time. After each callback, we ensure
that everything still works as expected. This means the toxcore change will
require 15 Pull Requests.
2016-08-10 20:46:04 +08:00
|
|
|
tox_iterate(tox1, &to_compare);
|
|
|
|
tox_iterate(tox2, &to_compare);
|
|
|
|
tox_iterate(tox3, &to_compare);
|
2014-02-19 02:49:17 +08:00
|
|
|
|
2016-09-01 02:12:19 +08:00
|
|
|
if (typing_changes == 2) {
|
2014-02-19 02:49:17 +08:00
|
|
|
break;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2014-02-19 02:49:17 +08:00
|
|
|
|
2016-09-01 03:40:20 +08:00
|
|
|
ck_assert_msg(typing_changes == 0, "Typing fail");
|
|
|
|
|
2014-02-19 02:49:17 +08:00
|
|
|
c_sleep(50);
|
|
|
|
}
|
|
|
|
|
2018-01-29 05:30:39 +08:00
|
|
|
ck_assert_msg(tox_friend_get_typing(tox2, 0, nullptr) == 1, "Typing fail");
|
|
|
|
tox_self_set_typing(tox3, 0, 0, nullptr);
|
2014-02-19 02:49:17 +08:00
|
|
|
|
|
|
|
while (1) {
|
|
|
|
typing_changes = 0;
|
Make self_connection_status callback stateless.
**What are we doing?**
We are moving towards stateless callbacks. This means that when registering a
callback, you no longer pass a user data pointer. Instead, you pass a user data
pointer to tox_iterate. This pointer is threaded through the code, passed to
each callback. The callback can modify the data pointed at. An extra indirection
will be needed if the pointer itself can change.
**Why?**
Currently, callbacks are registered with a user data pointer. This means the
library has N pointers for N different callbacks. These pointers need to be
managed by the client code. Managing the lifetime of the pointee can be
difficult. In C++, it takes special effort to ensure that the lifetime of user
data extends at least beyond the lifetime of the Tox instance. For other
languages, the situation is much worse. Java and other garbage collected
languages may move objects in memory, so the pointers are not stable. Tox4j goes
through a lot of effort to make the Java/Scala user experience a pleasant one by
keeping a global array of Tox+userdata on the C++ side, and communicating via
protobufs. A Haskell FFI would have to do similarly complex tricks.
Stateless callbacks ensure that a user data pointer only needs to live during a
single function call. This means that the user code (or language runtime) can
move the data around at will, as long as it sets the new location in the
callback.
**How?**
We are doing this change one callback at a time. After each callback, we ensure
that everything still works as expected. This means the toxcore change will
require 15 Pull Requests.
2016-08-10 20:46:04 +08:00
|
|
|
tox_iterate(tox1, &to_compare);
|
|
|
|
tox_iterate(tox2, &to_compare);
|
|
|
|
tox_iterate(tox3, &to_compare);
|
2014-02-19 02:49:17 +08:00
|
|
|
|
2016-09-01 02:12:19 +08:00
|
|
|
if (typing_changes == 1) {
|
2014-02-19 02:49:17 +08:00
|
|
|
break;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2014-02-19 02:49:17 +08:00
|
|
|
|
2016-09-01 03:40:20 +08:00
|
|
|
ck_assert_msg(typing_changes == 0, "Typing fail");
|
|
|
|
|
2014-02-19 02:49:17 +08:00
|
|
|
c_sleep(50);
|
|
|
|
}
|
|
|
|
|
2015-02-26 21:24:19 +08:00
|
|
|
TOX_ERR_FRIEND_QUERY err_t;
|
|
|
|
ck_assert_msg(tox_friend_get_typing(tox2, 0, &err_t) == 0, "Typing fail");
|
|
|
|
ck_assert_msg(err_t == TOX_ERR_FRIEND_QUERY_OK, "Typing fail");
|
2014-02-20 06:16:47 +08:00
|
|
|
|
2014-09-09 00:20:44 +08:00
|
|
|
uint32_t packet_number = 160;
|
2016-09-09 21:30:35 +08:00
|
|
|
tox_callback_friend_lossless_packet(tox3, &handle_custom_packet);
|
2014-09-09 00:20:44 +08:00
|
|
|
uint8_t data_c[TOX_MAX_CUSTOM_PACKET_SIZE + 1];
|
|
|
|
memset(data_c, ((uint8_t)packet_number), sizeof(data_c));
|
2018-01-29 05:30:39 +08:00
|
|
|
int ret = tox_friend_send_lossless_packet(tox2, 0, data_c, sizeof(data_c), nullptr);
|
2015-03-12 06:26:25 +08:00
|
|
|
ck_assert_msg(ret == 0, "tox_friend_send_lossless_packet bigger fail %i", ret);
|
2018-01-29 05:30:39 +08:00
|
|
|
ret = tox_friend_send_lossless_packet(tox2, 0, data_c, TOX_MAX_CUSTOM_PACKET_SIZE, nullptr);
|
2015-03-12 06:26:25 +08:00
|
|
|
ck_assert_msg(ret == 1, "tox_friend_send_lossless_packet fail %i", ret);
|
2014-09-09 00:20:44 +08:00
|
|
|
|
|
|
|
while (1) {
|
|
|
|
custom_packet = 0;
|
Make self_connection_status callback stateless.
**What are we doing?**
We are moving towards stateless callbacks. This means that when registering a
callback, you no longer pass a user data pointer. Instead, you pass a user data
pointer to tox_iterate. This pointer is threaded through the code, passed to
each callback. The callback can modify the data pointed at. An extra indirection
will be needed if the pointer itself can change.
**Why?**
Currently, callbacks are registered with a user data pointer. This means the
library has N pointers for N different callbacks. These pointers need to be
managed by the client code. Managing the lifetime of the pointee can be
difficult. In C++, it takes special effort to ensure that the lifetime of user
data extends at least beyond the lifetime of the Tox instance. For other
languages, the situation is much worse. Java and other garbage collected
languages may move objects in memory, so the pointers are not stable. Tox4j goes
through a lot of effort to make the Java/Scala user experience a pleasant one by
keeping a global array of Tox+userdata on the C++ side, and communicating via
protobufs. A Haskell FFI would have to do similarly complex tricks.
Stateless callbacks ensure that a user data pointer only needs to live during a
single function call. This means that the user code (or language runtime) can
move the data around at will, as long as it sets the new location in the
callback.
**How?**
We are doing this change one callback at a time. After each callback, we ensure
that everything still works as expected. This means the toxcore change will
require 15 Pull Requests.
2016-08-10 20:46:04 +08:00
|
|
|
tox_iterate(tox1, &to_compare);
|
|
|
|
tox_iterate(tox2, &to_compare);
|
2016-09-09 21:30:35 +08:00
|
|
|
tox_iterate(tox3, &packet_number);
|
2014-09-09 00:20:44 +08:00
|
|
|
|
2016-09-01 02:12:19 +08:00
|
|
|
if (custom_packet == 1) {
|
2014-09-09 00:20:44 +08:00
|
|
|
break;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2014-09-09 00:20:44 +08:00
|
|
|
|
2016-09-01 03:40:20 +08:00
|
|
|
ck_assert_msg(custom_packet == 0, "Lossless packet fail");
|
|
|
|
|
2014-09-09 00:20:44 +08:00
|
|
|
c_sleep(50);
|
|
|
|
}
|
2014-11-26 04:31:46 +08:00
|
|
|
|
2014-09-09 00:20:44 +08:00
|
|
|
packet_number = 200;
|
2016-09-09 21:30:35 +08:00
|
|
|
tox_callback_friend_lossy_packet(tox3, &handle_custom_packet);
|
2014-09-09 00:20:44 +08:00
|
|
|
memset(data_c, ((uint8_t)packet_number), sizeof(data_c));
|
2018-01-29 05:30:39 +08:00
|
|
|
ret = tox_friend_send_lossy_packet(tox2, 0, data_c, sizeof(data_c), nullptr);
|
2015-03-12 06:26:25 +08:00
|
|
|
ck_assert_msg(ret == 0, "tox_friend_send_lossy_packet bigger fail %i", ret);
|
2018-01-29 05:30:39 +08:00
|
|
|
ret = tox_friend_send_lossy_packet(tox2, 0, data_c, TOX_MAX_CUSTOM_PACKET_SIZE, nullptr);
|
2015-03-12 06:26:25 +08:00
|
|
|
ck_assert_msg(ret == 1, "tox_friend_send_lossy_packet fail %i", ret);
|
2014-09-09 00:20:44 +08:00
|
|
|
|
|
|
|
while (1) {
|
|
|
|
custom_packet = 0;
|
Make self_connection_status callback stateless.
**What are we doing?**
We are moving towards stateless callbacks. This means that when registering a
callback, you no longer pass a user data pointer. Instead, you pass a user data
pointer to tox_iterate. This pointer is threaded through the code, passed to
each callback. The callback can modify the data pointed at. An extra indirection
will be needed if the pointer itself can change.
**Why?**
Currently, callbacks are registered with a user data pointer. This means the
library has N pointers for N different callbacks. These pointers need to be
managed by the client code. Managing the lifetime of the pointee can be
difficult. In C++, it takes special effort to ensure that the lifetime of user
data extends at least beyond the lifetime of the Tox instance. For other
languages, the situation is much worse. Java and other garbage collected
languages may move objects in memory, so the pointers are not stable. Tox4j goes
through a lot of effort to make the Java/Scala user experience a pleasant one by
keeping a global array of Tox+userdata on the C++ side, and communicating via
protobufs. A Haskell FFI would have to do similarly complex tricks.
Stateless callbacks ensure that a user data pointer only needs to live during a
single function call. This means that the user code (or language runtime) can
move the data around at will, as long as it sets the new location in the
callback.
**How?**
We are doing this change one callback at a time. After each callback, we ensure
that everything still works as expected. This means the toxcore change will
require 15 Pull Requests.
2016-08-10 20:46:04 +08:00
|
|
|
tox_iterate(tox1, &to_compare);
|
|
|
|
tox_iterate(tox2, &to_compare);
|
2016-09-09 21:30:35 +08:00
|
|
|
tox_iterate(tox3, &packet_number);
|
2014-09-09 00:20:44 +08:00
|
|
|
|
2016-09-01 02:12:19 +08:00
|
|
|
if (custom_packet == 1) {
|
2014-09-09 00:20:44 +08:00
|
|
|
break;
|
2016-09-01 02:12:19 +08:00
|
|
|
}
|
2014-09-09 00:20:44 +08:00
|
|
|
|
2016-09-01 03:40:20 +08:00
|
|
|
ck_assert_msg(custom_packet == 0, "lossy packet fail");
|
|
|
|
|
2014-09-09 00:20:44 +08:00
|
|
|
c_sleep(50);
|
|
|
|
}
|
|
|
|
|
2018-01-29 05:30:39 +08:00
|
|
|
printf("test_few_clients succeeded, took %llu seconds\n", time(nullptr) - cur_time);
|
2014-06-06 21:50:19 +08:00
|
|
|
|
2016-12-16 01:35:54 +08:00
|
|
|
tox_options_free(options);
|
2014-06-06 21:50:19 +08:00
|
|
|
tox_kill(tox1);
|
|
|
|
tox_kill(tox2);
|
|
|
|
tox_kill(tox3);
|
2013-12-18 07:55:28 +08:00
|
|
|
}
|
|
|
|
END_TEST
|
|
|
|
|
2016-09-05 23:10:48 +08:00
|
|
|
static Suite *tox_suite(void)
|
2013-12-18 07:55:28 +08:00
|
|
|
{
|
2016-10-11 19:52:06 +08:00
|
|
|
Suite *s = suite_create("Tox few clients");
|
2013-12-18 07:55:28 +08:00
|
|
|
|
2018-02-06 05:38:58 +08:00
|
|
|
DEFTESTCASE(few_clients);
|
2016-07-13 03:32:35 +08:00
|
|
|
|
2013-12-18 07:55:28 +08:00
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
2018-01-29 05:30:39 +08:00
|
|
|
srand((unsigned int) time(nullptr));
|
2013-12-18 07:55:28 +08:00
|
|
|
|
|
|
|
Suite *tox = tox_suite();
|
|
|
|
SRunner *test_runner = srunner_create(tox);
|
|
|
|
|
|
|
|
int number_failed = 0;
|
|
|
|
srunner_run_all(test_runner, CK_NORMAL);
|
|
|
|
number_failed = srunner_ntests_failed(test_runner);
|
|
|
|
|
|
|
|
srunner_free(test_runner);
|
|
|
|
|
|
|
|
return number_failed;
|
|
|
|
}
|