]> git.meshlink.io Git - meshlink/blob - test/get-all-nodes.c
Never automatically try to bind to ports >= 32768.
[meshlink] / test / get-all-nodes.c
1 #ifdef NDEBUG
2 #undef NDEBUG
3 #endif
4
5 #include <stdio.h>
6 #include <unistd.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/time.h>
10 #include <time.h>
11 #include <assert.h>
12
13 #include "meshlink.h"
14 #include "utils.h"
15
16 static struct sync_flag bar_reachable;
17
18 static void status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
19         (void)mesh;
20
21         if(reachable && !strcmp(node->name, "bar")) {
22                 set_sync_flag(&bar_reachable, true);
23         }
24 }
25
26 int main(void) {
27         init_sync_flag(&bar_reachable);
28
29         struct meshlink_node **nodes = NULL;
30         size_t nnodes = 0;
31
32         meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
33
34         // Open new meshlink instances.
35
36         assert(meshlink_destroy("get_all_nodes_conf.1"));
37         assert(meshlink_destroy("get_all_nodes_conf.2"));
38         assert(meshlink_destroy("get_all_nodes_conf.3"));
39
40         meshlink_handle_t *mesh[3];
41         mesh[0] = meshlink_open("get_all_nodes_conf.1", "foo", "get-all-nodes", DEV_CLASS_BACKBONE);
42         assert(mesh[0]);
43
44         mesh[1] = meshlink_open("get_all_nodes_conf.2", "bar", "get-all-nodes", DEV_CLASS_STATIONARY);
45         assert(mesh[1]);
46
47         mesh[2] = meshlink_open("get_all_nodes_conf.3", "baz", "get-all-nodes", DEV_CLASS_STATIONARY);
48         assert(mesh[2]);
49
50         // Check that we only know about ourself.
51
52         nodes = meshlink_get_all_nodes(mesh[0], nodes, &nnodes);
53         assert(nnodes == 1);
54         assert(nodes[0] == meshlink_get_self(mesh[0]));
55
56         // We should never have been online.
57
58         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
59         assert(nnodes == 0);
60
61         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
62         assert(nnodes == 1);
63         assert(nodes[0] == meshlink_get_self(mesh[0]));
64
65         // Let nodes know about each other.
66
67         for(int i = 0; i < 3; i++) {
68                 meshlink_enable_discovery(mesh[i], false);
69                 assert(meshlink_set_canonical_address(mesh[i], meshlink_get_self(mesh[i]), "localhost", NULL));
70                 char *data = meshlink_export(mesh[i]);
71                 assert(data);
72
73                 for(int j = 0; j < 3; j++) {
74                         if(i == j) {
75                                 continue;
76                         }
77
78                         assert(meshlink_import(mesh[j], data));
79                 }
80
81                 free(data);
82         }
83
84         // We should know about all nodes now, and their device class.
85
86         nodes = meshlink_get_all_nodes(mesh[0], nodes, &nnodes);
87         assert(nnodes == 3);
88
89         nodes = meshlink_get_all_nodes_by_dev_class(mesh[0], DEV_CLASS_BACKBONE, nodes, &nnodes);
90         assert(nnodes == 1);
91         assert(nodes[0] == meshlink_get_self(mesh[0]));
92
93         nodes = meshlink_get_all_nodes_by_dev_class(mesh[0], DEV_CLASS_STATIONARY, nodes, &nnodes);
94         assert(nnodes == 2);
95
96         // But no node should have been online.
97
98         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
99         assert(nnodes == 0);
100
101         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
102         assert(nnodes == 3);
103
104         // Start foo.
105
106         time_t foo_started = time(NULL);
107         assert(meshlink_start(mesh[0]));
108
109         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
110         assert(nnodes == 1);
111         assert(nodes[0] == meshlink_get_self(mesh[0]));
112
113         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
114         assert(nnodes == 2);
115
116         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], foo_started - 1, -1, nodes, &nnodes);
117         assert(nnodes == 1);
118         assert(nodes[0] == meshlink_get_self(mesh[0]));
119
120         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started - 1, nodes, &nnodes);
121         assert(nnodes == 0);
122
123         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started + 1, nodes, &nnodes);
124         assert(nnodes == 1);
125         assert(nodes[0] == meshlink_get_self(mesh[0]));
126
127         // Start bar and wait for it to connect.
128
129         meshlink_set_node_status_cb(mesh[0], status_cb);
130
131         sleep(2);
132         assert(meshlink_start(mesh[1]));
133         assert(wait_sync_flag(&bar_reachable, 20));
134         time_t bar_started = time(NULL);
135
136         // Validate time ranges.
137
138         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
139         assert(nnodes == 2);
140
141         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
142         assert(nnodes == 1);
143         assert(nodes[0] == meshlink_get_node(mesh[0], "baz"));
144
145         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started + 1, nodes, &nnodes);
146         assert(nnodes == 1);
147         assert(nodes[0] == meshlink_get_self(mesh[0]));
148
149         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_started, bar_started, nodes, &nnodes);
150         assert(nnodes == 2);
151         assert(nodes[0] == meshlink_get_node(mesh[0], "bar"));
152         assert(nodes[1] == meshlink_get_self(mesh[0]));
153
154         // Stop bar.
155
156         meshlink_stop(mesh[1]);
157         sleep(2);
158         time_t bar_stopped = time(NULL);
159
160         // Validate we can see when bar was reachable.
161
162         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_stopped, bar_stopped, nodes, &nnodes);
163         assert(nnodes == 1);
164         assert(nodes[0] == meshlink_get_self(mesh[0]));
165
166         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_started, bar_started, nodes, &nnodes);
167         assert(nnodes == 2);
168         assert(nodes[0] == meshlink_get_node(mesh[0], "bar"));
169         assert(nodes[1] == meshlink_get_self(mesh[0]));
170
171         // Close and restart foo, check that it remembers correctly.
172
173         meshlink_close(mesh[0]);
174         sleep(2);
175         time_t foo_stopped = time(NULL);
176         mesh[0] = meshlink_open("get_all_nodes_conf.1", "foo", "get-all_nodes", DEV_CLASS_BACKBONE);
177         assert(mesh[0]);
178
179         nodes = meshlink_get_all_nodes(mesh[0], nodes, &nnodes);
180         assert(nnodes == 3);
181
182         nodes = meshlink_get_all_nodes_by_dev_class(mesh[0], DEV_CLASS_BACKBONE, nodes, &nnodes);
183         assert(nnodes == 1);
184         assert(nodes[0] == meshlink_get_self(mesh[0]));
185
186         nodes = meshlink_get_all_nodes_by_dev_class(mesh[0], DEV_CLASS_STATIONARY, nodes, &nnodes);
187         assert(nnodes == 2);
188
189         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
190         assert(nnodes == 1);
191         assert(nodes[0] == meshlink_get_node(mesh[0], "baz"));
192
193         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
194         assert(nnodes == 2);
195
196         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started - 1, nodes, &nnodes);
197         assert(nnodes == 0);
198
199         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started + 1, nodes, &nnodes);
200         assert(nnodes == 1);
201         assert(nodes[0] == meshlink_get_self(mesh[0]));
202
203         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_started, bar_started, nodes, &nnodes);
204         assert(nnodes == 2);
205         assert(nodes[0] == meshlink_get_node(mesh[0], "bar"));
206         assert(nodes[1] == meshlink_get_self(mesh[0]));
207
208         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_stopped, bar_stopped, nodes, &nnodes);
209         assert(nnodes == 1);
210         assert(nodes[0] == meshlink_get_self(mesh[0]));
211
212         nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], foo_stopped, -1, nodes, &nnodes);
213         assert(nnodes == 0);
214
215         // Clean up.
216
217         for(int i = 0; i < 3; i++) {
218                 meshlink_close(mesh[i]);
219         }
220 }