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