]> git.meshlink.io Git - meshlink/blob - test/trio.c
Check that autoconnect works as expected.
[meshlink] / test / trio.c
1 #define _GNU_SOURCE
2
3 #include <stdio.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <errno.h>
7 #include <assert.h>
8 #include <sys/time.h>
9
10 #include "meshlink.h"
11 #include "devtools.h"
12 #include "utils.h"
13
14 static void log_cb(meshlink_handle_t *mesh, meshlink_log_level_t level, const char *text) {
15         static struct timeval tv0;
16         struct timeval tv;
17
18         if(tv0.tv_sec == 0)
19                 gettimeofday(&tv0, NULL);
20         gettimeofday(&tv, NULL);
21         fprintf(stderr, "%u.%.03u ", (unsigned int)(tv.tv_sec - tv0.tv_sec), (unsigned int)tv.tv_usec / 1000);
22
23         if(mesh)
24                 fprintf(stderr, "(%s) ", mesh->name);
25         fprintf(stderr, "[%d] %s\n", level, text);
26 }
27
28 static bool received = false;
29
30 static void receive_cb(meshlink_handle_t *mesh, meshlink_node_t *source, const void *data, size_t len) {
31         fprintf(stderr, "RECEIVED SOMETHING\n");
32         if(len == 5 && !memcmp(data, "Hello", 5))
33                 received = true;
34 }
35
36 int main(int argc, char *argv[]) {
37         // Create three instances.
38
39         const char *name[3] = {"foo", "bar", "baz"};
40         meshlink_handle_t *mesh[3];
41         char *data[3];
42
43         for(int i = 0; i < 3; i++) {
44                 char *path;
45                 asprintf(&path, "trio_conf.%d", i);
46                 assert(path);
47
48                 mesh[i] = meshlink_open(path, name[i], "trio", DEV_CLASS_BACKBONE);
49                 assert(mesh[i]);
50
51                 data[i] = meshlink_export(mesh[i]);
52                 assert(data[i]);
53         }
54
55         // first node knows the two other nodes
56
57         for(int i = 1; i < 3; i++) {
58                 assert(meshlink_import(mesh[i], data[0]));
59                 assert(meshlink_import(mesh[0], data[i]));
60
61                 assert(meshlink_get_node(mesh[i], name[0]));
62                 assert(meshlink_get_node(mesh[0], name[i]));
63         }
64
65         // second and third node should not know each other yet
66
67         assert(!meshlink_get_node(mesh[1], name[2]));
68         assert(!meshlink_get_node(mesh[2], name[1]));
69
70         // start the nodes
71
72         for(int i = 0; i < 3; i++)
73                 meshlink_start(mesh[i]);
74
75         // the nodes should now learn about each other
76
77         assert_after(meshlink_get_node(mesh[1], name[2]), 5);
78         assert_after(meshlink_get_node(mesh[2], name[1]), 5);
79
80         // Send a packet, expect it is received
81
82         meshlink_set_receive_cb(mesh[1], receive_cb);
83         assert_after((meshlink_send(mesh[2], meshlink_get_node(mesh[2], name[1]), "Hello", 5), received), 15);
84
85         // Check that the second and third node have autoconnected to each other
86
87         devtool_edge_t *edges = NULL;
88         size_t nedges = 0;
89         assert_after((edges = devtool_get_all_edges(mesh[1], edges, &nedges), nedges == 3), 15);
90
91         // Stop the first node
92
93         meshlink_stop(mesh[0]);
94         sleep(1);
95
96         // Communication should still be possible
97
98         assert_after((meshlink_send(mesh[2], meshlink_get_node(mesh[2], name[1]), "Hello", 5), received), 15);
99
100         // Stop the other nodes
101
102         for(int i = 1; i < 3; i++)
103                 meshlink_stop(mesh[i]);
104
105         sleep(1);
106
107         // Start just the other two nodes
108
109         meshlink_set_log_cb(mesh[1], MESHLINK_DEBUG, log_cb);
110
111         for(int i = 1; i < 3; i++)
112                 meshlink_start(mesh[i]);
113
114         assert(meshlink_get_node(mesh[1], name[2]));
115         assert(meshlink_get_node(mesh[2], name[1]));
116
117         // Communication should still be possible
118
119         received = false;
120         assert_after((meshlink_send(mesh[2], meshlink_get_node(mesh[2], name[1]), "Hello", 5), received), 25);
121
122         // Clean up.
123
124         for(int i = 0; i < 3; i++)
125                 meshlink_close(mesh[i]);
126 }