16 static struct sync_flag bar_reachable;
18 static void status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
21 if(reachable && !strcmp(node->name, "bar")) {
22 set_sync_flag(&bar_reachable, true);
27 init_sync_flag(&bar_reachable);
29 struct meshlink_node **nodes = NULL;
32 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
34 // Open new meshlink instances.
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"));
40 meshlink_handle_t *mesh[3];
41 mesh[0] = meshlink_open("get_all_nodes_conf.1", "foo", "get-all-nodes", DEV_CLASS_BACKBONE);
44 mesh[1] = meshlink_open("get_all_nodes_conf.2", "bar", "get-all-nodes", DEV_CLASS_STATIONARY);
47 mesh[2] = meshlink_open("get_all_nodes_conf.3", "baz", "get-all-nodes", DEV_CLASS_STATIONARY);
50 // Check that we only know about ourself.
52 nodes = meshlink_get_all_nodes(mesh[0], nodes, &nnodes);
54 assert(nodes[0] == meshlink_get_self(mesh[0]));
56 // We should never have been online.
58 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
61 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
63 assert(nodes[0] == meshlink_get_self(mesh[0]));
65 // Let nodes know about each other.
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]);
73 for(int j = 0; j < 3; j++) {
78 assert(meshlink_import(mesh[j], data));
84 // We should know about all nodes now, and their device class.
86 nodes = meshlink_get_all_nodes(mesh[0], nodes, &nnodes);
89 nodes = meshlink_get_all_nodes_by_dev_class(mesh[0], DEV_CLASS_BACKBONE, nodes, &nnodes);
91 assert(nodes[0] == meshlink_get_self(mesh[0]));
93 nodes = meshlink_get_all_nodes_by_dev_class(mesh[0], DEV_CLASS_STATIONARY, nodes, &nnodes);
96 // But no node should have been online.
98 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
101 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
106 time_t foo_started = time(NULL);
107 assert(meshlink_start(mesh[0]));
109 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
111 assert(nodes[0] == meshlink_get_self(mesh[0]));
113 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
116 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], foo_started - 1, -1, nodes, &nnodes);
118 assert(nodes[0] == meshlink_get_self(mesh[0]));
120 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started - 1, nodes, &nnodes);
123 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started + 1, nodes, &nnodes);
125 assert(nodes[0] == meshlink_get_self(mesh[0]));
127 // Start bar and wait for it to connect.
129 meshlink_set_node_status_cb(mesh[0], status_cb);
132 assert(meshlink_start(mesh[1]));
133 assert(wait_sync_flag(&bar_reachable, 20));
134 time_t bar_started = time(NULL);
136 // Validate time ranges.
138 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
141 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
143 assert(nodes[0] == meshlink_get_node(mesh[0], "baz"));
145 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started + 1, nodes, &nnodes);
147 assert(nodes[0] == meshlink_get_self(mesh[0]));
149 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_started, bar_started, nodes, &nnodes);
151 assert(nodes[0] == meshlink_get_node(mesh[0], "bar"));
152 assert(nodes[1] == meshlink_get_self(mesh[0]));
156 meshlink_stop(mesh[1]);
158 time_t bar_stopped = time(NULL);
160 // Validate we can see when bar was reachable.
162 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_stopped, bar_stopped, nodes, &nnodes);
164 assert(nodes[0] == meshlink_get_self(mesh[0]));
166 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_started, bar_started, nodes, &nnodes);
168 assert(nodes[0] == meshlink_get_node(mesh[0], "bar"));
169 assert(nodes[1] == meshlink_get_self(mesh[0]));
171 // Close and restart foo, check that it remembers correctly.
173 meshlink_close(mesh[0]);
175 time_t foo_stopped = time(NULL);
176 mesh[0] = meshlink_open("get_all_nodes_conf.1", "foo", "get-all_nodes", DEV_CLASS_BACKBONE);
179 nodes = meshlink_get_all_nodes(mesh[0], nodes, &nnodes);
182 nodes = meshlink_get_all_nodes_by_dev_class(mesh[0], DEV_CLASS_BACKBONE, nodes, &nnodes);
184 assert(nodes[0] == meshlink_get_self(mesh[0]));
186 nodes = meshlink_get_all_nodes_by_dev_class(mesh[0], DEV_CLASS_STATIONARY, nodes, &nnodes);
189 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
191 assert(nodes[0] == meshlink_get_node(mesh[0], "baz"));
193 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
196 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started - 1, nodes, &nnodes);
199 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started + 1, nodes, &nnodes);
201 assert(nodes[0] == meshlink_get_self(mesh[0]));
203 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_started, bar_started, nodes, &nnodes);
205 assert(nodes[0] == meshlink_get_node(mesh[0], "bar"));
206 assert(nodes[1] == meshlink_get_self(mesh[0]));
208 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_stopped, bar_stopped, nodes, &nnodes);
210 assert(nodes[0] == meshlink_get_self(mesh[0]));
212 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], foo_stopped, -1, nodes, &nnodes);
217 for(int i = 0; i < 3; i++) {
218 meshlink_close(mesh[i]);