]> git.meshlink.io Git - meshlink/blob - test/trio.c
Refactor the non-blackbox test suite.
[meshlink] / test / trio.c
1 #define _GNU_SOURCE
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <errno.h>
8 #include <assert.h>
9 #include <sys/time.h>
10
11 #include "meshlink.h"
12 #include "devtools.h"
13 #include "utils.h"
14
15 static struct sync_flag received;
16 static struct sync_flag bar_learned_baz;
17 static struct sync_flag baz_learned_bar;
18
19 static void receive_cb(meshlink_handle_t *mesh, meshlink_node_t *source, const void *data, size_t len) {
20         (void)mesh;
21         (void)source;
22
23         if(len == 5 && !memcmp(data, "Hello", 5)) {
24                 set_sync_flag(&received, true);
25         }
26 }
27
28 static void bar_status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
29         (void)mesh;
30         (void)reachable;
31
32         if(!strcmp(node->name, "baz")) {
33                 set_sync_flag(&bar_learned_baz, true);
34         }
35 }
36
37 static void baz_status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
38         (void)mesh;
39         (void)reachable;
40
41         if(!strcmp(node->name, "bar")) {
42                 set_sync_flag(&baz_learned_bar, true);
43         }
44 }
45
46 int main() {
47         meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
48
49         // Create three instances.
50
51         const char *name[3] = {"foo", "bar", "baz"};
52         meshlink_handle_t *mesh[3];
53         char *data[3];
54
55         for(int i = 0; i < 3; i++) {
56                 char *path = NULL;
57                 assert(asprintf(&path, "trio_conf.%d", i) != -1 && path);
58
59                 assert(meshlink_destroy(path));
60                 mesh[i] = meshlink_open(path, name[i], "trio", DEV_CLASS_BACKBONE);
61                 assert(mesh[i]);
62                 free(path);
63
64                 meshlink_add_address(mesh[i], "localhost");
65
66                 data[i] = meshlink_export(mesh[i]);
67                 assert(data[i]);
68         }
69
70         // first node knows the two other nodes
71
72         for(int i = 1; i < 3; i++) {
73                 assert(meshlink_import(mesh[i], data[0]));
74                 assert(meshlink_import(mesh[0], data[i]));
75
76                 assert(meshlink_get_node(mesh[i], name[0]));
77                 assert(meshlink_get_node(mesh[0], name[i]));
78         }
79
80         // second and third node should not know each other yet
81
82         assert(!meshlink_get_node(mesh[1], name[2]));
83         assert(!meshlink_get_node(mesh[2], name[1]));
84
85         // start the nodes
86
87         meshlink_set_node_status_cb(mesh[1], bar_status_cb);
88         meshlink_set_node_status_cb(mesh[2], baz_status_cb);
89
90         for(int i = 0; i < 3; i++) {
91                 free(data[i]);
92                 assert(meshlink_start(mesh[i]));
93         }
94
95         // the nodes should now learn about each other
96
97         assert(wait_sync_flag(&bar_learned_baz, 5));
98         assert(wait_sync_flag(&baz_learned_bar, 5));
99
100         // Send a packet, expect it is received
101
102         meshlink_set_receive_cb(mesh[1], receive_cb);
103
104         for(int i = 0; i < 15; i++) {
105                 assert(meshlink_send(mesh[2], meshlink_get_node(mesh[2], name[1]), "Hello", 5));
106
107                 if(wait_sync_flag(&received, 1)) {
108                         break;
109                 }
110         }
111
112         assert(wait_sync_flag(&received, 15));
113
114         // Check that the second and third node have autoconnected to each other
115
116         devtool_edge_t *edges = NULL;
117         size_t nedges = 0;
118         assert_after((edges = devtool_get_all_edges(mesh[1], edges, &nedges), nedges == 3), 15);
119         free(edges);
120
121         // Stop the first node
122
123         meshlink_stop(mesh[0]);
124         sleep(1);
125
126         // Communication should still be possible
127
128         set_sync_flag(&received, false);
129
130         for(int i = 0; i < 15; i++) {
131                 assert(meshlink_send(mesh[2], meshlink_get_node(mesh[2], name[1]), "Hello", 5));
132
133                 if(wait_sync_flag(&received, 1)) {
134                         break;
135                 }
136         }
137
138         assert(wait_sync_flag(&received, 15));
139
140         // Stop the other nodes
141
142         for(int i = 1; i < 3; i++) {
143                 meshlink_stop(mesh[i]);
144         }
145
146         sleep(1);
147
148         // Start just the other two nodes
149
150         for(int i = 1; i < 3; i++) {
151                 assert(meshlink_start(mesh[i]));
152         }
153
154         assert(meshlink_get_node(mesh[1], name[2]));
155         assert(meshlink_get_node(mesh[2], name[1]));
156
157         // Communication should still be possible
158
159         set_sync_flag(&received, false);
160
161         for(int i = 0; i < 15; i++) {
162                 assert(meshlink_send(mesh[2], meshlink_get_node(mesh[2], name[1]), "Hello", 5));
163
164                 if(wait_sync_flag(&received, 1)) {
165                         break;
166                 }
167         }
168
169         assert(wait_sync_flag(&received, 1));
170
171         // Clean up.
172
173         for(int i = 0; i < 3; i++) {
174                 meshlink_close(mesh[i]);
175         }
176 }