]> git.meshlink.io Git - meshlink/blob - test/storage-callbacks.cpp
Use a key/value store with configurable storage callbacks.
[meshlink] / test / storage-callbacks.cpp
1 #ifdef NDEBUG
2 #undef NDEBUG
3 #endif
4
5 #include <algorithm>
6 #include <cassert>
7 #include <iostream>
8 #include <map>
9 #include <string>
10 #include <vector>
11
12 #include "meshlink++.h"
13 #include "utils.h"
14
15 #include "devtools.h"
16
17 std::map<std::string, std::map<std::string, std::vector<char>>> storage;
18
19 static bool load_cb(meshlink_handle_t *mesh, const char *name, void *buf, size_t *len) {
20         const auto& data = storage[mesh->name][name];
21         if (data.empty())
22                 return false;
23
24         char* begin = static_cast<char *>(buf);
25         auto todo = std::min(data.size(), *len);
26         *len = data.size();
27         std::copy_n(data.begin(), todo, begin);
28         return true;
29 }
30
31 static bool store_cb(meshlink_handle_t *mesh, const char *name, const void *buf, size_t len) {
32         auto& data = storage[mesh->name][name];
33         const char* begin = static_cast<const char *>(buf);
34         data.assign(begin, begin + len);
35         return true;
36 }
37
38 static bool ls_cb(meshlink_handle_t *mesh, meshlink_ls_entry_cb_t entry_cb) {
39         for (auto& it: storage[mesh->name]) {
40                 auto& name = it.first;
41                 auto& data = it.second;
42                 if (data.empty()) {
43                         continue;
44                 }
45                 if (!entry_cb(mesh, name.c_str(), data.size())) {
46                         return false;
47                 }
48         }
49
50         return true;
51 }
52
53 int main() {
54         meshlink::set_log_cb(MESHLINK_DEBUG, log_cb);
55
56         meshlink::open_params params1("storage-callbacks_conf.1", "foo", "storage-callbacks", DEV_CLASS_BACKBONE);
57         meshlink::open_params params2("storage-callbacks_conf.2", "bar", "storage-callbacks", DEV_CLASS_BACKBONE);
58         meshlink::open_params params3("storage-callbacks_conf.3", "baz", "storage-callbacks", DEV_CLASS_BACKBONE);
59
60         params1.set_storage_callbacks(load_cb, store_cb, ls_cb);
61         params1.set_storage_key("hunter42", 8);
62         params2.set_storage_callbacks(load_cb, store_cb, ls_cb);
63         params3.set_storage_callbacks(load_cb, store_cb, ls_cb);
64
65         // Start nodes and let foo invite bar
66         {
67                 meshlink::mesh mesh1(params1);
68                 meshlink::mesh mesh2(params2);
69
70                 mesh1.enable_discovery(false);
71                 mesh2.enable_discovery(false);
72
73                 char *invitation = mesh1.invite({}, "bar", 0);
74                 assert(invitation);
75                 assert(mesh1.start());
76
77                 assert(mesh2.join(invitation));
78                 free(invitation);
79         }
80
81
82         // Start the nodes again and check that they know each other
83         {
84                 meshlink::mesh mesh1(params1);
85                 meshlink::mesh mesh2(params2);
86
87                 mesh1.enable_discovery(false);
88                 mesh2.enable_discovery(false);
89
90                 assert(mesh1.start());
91                 assert(mesh2.start());
92
93                 assert(mesh1.get_node("bar"));
94                 assert(mesh2.get_node("foo"));
95         }
96
97         // Test key rotation
98         {
99                 meshlink::mesh mesh1(params1);
100                 meshlink::mesh mesh3(params3);
101
102                 mesh1.enable_discovery(false);
103                 mesh3.enable_discovery(false);
104
105                 char *invitation = mesh1.invite({}, "baz", 0);
106                 assert(invitation);
107
108                 devtool_keyrotate_probe = [](int stage){ return stage != 1; };
109                 assert(!mesh1.encrypted_key_rotate("newkey", 6));
110                 mesh1.close();
111
112                 params1.set_storage_key("newkey", 6);
113                 assert(!mesh1.open(params1));
114                 params1.set_storage_key("hunter42", 8);
115                 assert(mesh1.open(params1));
116
117                 devtool_keyrotate_probe = [](int stage){ return stage != 2; };
118                 assert(mesh1.encrypted_key_rotate("newkey", 6));
119                 mesh1.close();
120                 params1.set_storage_key("newkey", 6);
121                 assert(mesh1.open(params1));
122
123                 assert(mesh1.start());
124                 assert(mesh3.join(invitation));
125                 assert(mesh1.get_node("baz"));
126                 assert(mesh3.get_node("foo"));
127         }
128 }