summaryrefslogtreecommitdiff
path: root/auto_tests/run_auto_test.h
blob: 4f2dc27895a2198799308b348de02df50a91290f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <stdlib.h>  // calloc, free

#include "check_compat.h"
#include "../testing/misc_tools.h"
#include "../toxcore/Messenger.h"
#include "../toxcore/mono_time.h"

static bool all_connected(uint32_t tox_count, Tox **toxes)
{
    for (uint32_t i = 0; i < tox_count; i++) {
        if (tox_self_get_connection_status(toxes[i]) == TOX_CONNECTION_NONE) {
            return false;
        }
    }

    return true;
}

static bool all_friends_connected(uint32_t tox_count, Tox **toxes)
{
    for (uint32_t i = 0; i < tox_count; i++) {
        const size_t friend_count = tox_self_get_friend_list_size(toxes[i]);

        for (size_t j = 0; j < friend_count; j++) {
            if (tox_friend_get_connection_status(toxes[i], j, nullptr) == TOX_CONNECTION_NONE) {
                return false;
            }
        }
    }

    return true;
}

static void iterate_all_wait(uint32_t tox_count, Tox **toxes, State *state, uint32_t wait)
{
    for (uint32_t i = 0; i < tox_count; i++) {
        tox_iterate(toxes[i], &state[i]);
        state[i].clock += wait;
    }

    /* Also actually sleep a little, to allow for local network processing */
    c_sleep(20);
}

static uint64_t get_state_clock_callback(Mono_Time *mono_time, void *user_data)
{
    const State *state = (const State *)user_data;
    return state->clock;
}

static void run_auto_test(uint32_t tox_count, void test(Tox **toxes, State *state), bool chain)
{
    printf("initialising %u toxes\n", tox_count);
    Tox **toxes = (Tox **)calloc(tox_count, sizeof(Tox *));
    State *state = (State *)calloc(tox_count, sizeof(State));

    for (uint32_t i = 0; i < tox_count; i++) {
        state[i].index = i;
        toxes[i] = tox_new_log(nullptr, nullptr, &state[i].index);
        ck_assert_msg(toxes[i], "failed to create %u tox instances", i + 1);

        // TODO(iphydf): Don't rely on toxcore internals.
        Mono_Time *mono_time = (*(Messenger **)toxes[i])->mono_time;

        state[i].clock = current_time_monotonic(mono_time);
        mono_time_set_current_time_callback(mono_time, get_state_clock_callback, &state[i]);
    }

    if (chain) {
        printf("each tox adds adjacent toxes as friends\n");

        for (uint32_t i = 0; i < tox_count; i++) {
            for (uint32_t j = i - 1; j != i + 3; j += 2) {
                if (j >= tox_count) {
                    continue;
                }

                uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
                tox_self_get_public_key(toxes[j], public_key);
                tox_friend_add_norequest(toxes[i], public_key, nullptr);
            }
        }
    } else {
        printf("toxes all add each other as friends\n");

        for (uint32_t i = 0; i < tox_count; i++) {
            for (uint32_t j = 0; j < tox_count; j++) {
                if (i != j) {
                    uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
                    tox_self_get_public_key(toxes[j], public_key);
                    tox_friend_add_norequest(toxes[i], public_key, nullptr);
                }
            }
        }
    }

    printf("bootstrapping all toxes off toxes[0]\n");
    uint8_t dht_key[TOX_PUBLIC_KEY_SIZE];
    tox_self_get_dht_id(toxes[0], dht_key);
    const uint16_t dht_port = tox_self_get_udp_port(toxes[0], nullptr);

    for (uint32_t i = 1; i < tox_count; i++) {
        tox_bootstrap(toxes[i], "localhost", dht_port, dht_key, nullptr);
    }

    do {
        iterate_all_wait(tox_count, toxes, state, ITERATION_INTERVAL);
    } while (!all_connected(tox_count, toxes));

    printf("toxes are online\n");

    do {
        iterate_all_wait(tox_count, toxes, state, ITERATION_INTERVAL);
    } while (!all_friends_connected(tox_count, toxes));

    printf("tox clients connected\n");

    test(toxes, state);

    for (uint32_t i = 0; i < tox_count; i++) {
        tox_kill(toxes[i]);
    }

    free(state);
    free(toxes);
}