this repo has no description
1open Swim.Types
2module Cluster = Swim.Cluster
3
4external env_cast : 'a -> 'b = "%identity"
5
6let make_config ~port ~name =
7 {
8 default_config with
9 bind_addr = "\127\000\000\001";
10 bind_port = port;
11 node_name = Some name;
12 protocol_interval = 0.1;
13 probe_timeout = 0.05;
14 suspicion_mult = 2;
15 secret_key = String.make 16 'k';
16 cluster_name = "test-cluster";
17 }
18
19let test_cluster_create_start_shutdown sw env () =
20 let config = make_config ~port:17946 ~name:"test-node" in
21 let env_wrap = { stdenv = env; sw } in
22 match Cluster.create ~sw ~env:env_wrap ~config with
23 | Error `Invalid_key -> Alcotest.fail "invalid key"
24 | Ok cluster ->
25 Cluster.start cluster;
26 let local = Cluster.local_node cluster in
27 Alcotest.(check string)
28 "node name" "test-node"
29 (node_id_to_string local.id);
30 Eio.Time.sleep env#clock 0.05;
31 Cluster.shutdown cluster
32
33let test_cluster_stats sw env () =
34 let config = make_config ~port:17947 ~name:"stats-node" in
35 let env_wrap = { stdenv = env; sw } in
36 match Cluster.create ~sw ~env:env_wrap ~config with
37 | Error _ -> Alcotest.fail "create failed"
38 | Ok cluster ->
39 Cluster.start cluster;
40 Eio.Time.sleep env#clock 0.05;
41 let stats = Cluster.stats cluster in
42 Alcotest.(check int) "initial nodes_alive" 0 stats.nodes_alive;
43 Cluster.shutdown cluster
44
45let test_cluster_add_member sw env () =
46 let config = make_config ~port:17948 ~name:"add-member-node" in
47 let env_wrap = { stdenv = env; sw } in
48 match Cluster.create ~sw ~env:env_wrap ~config with
49 | Error _ -> Alcotest.fail "create failed"
50 | Ok cluster ->
51 Cluster.start cluster;
52 let fake_node =
53 make_node_info
54 ~id:(node_id_of_string "fake-node")
55 ~addr:(`Udp (Eio.Net.Ipaddr.of_raw "\127\000\000\002", 7946))
56 ~meta:"test-meta"
57 in
58 Cluster.add_member cluster fake_node;
59 Eio.Time.sleep env#clock 0.05;
60 Alcotest.(check int) "member count" 1 (Cluster.member_count cluster);
61 Cluster.shutdown cluster
62
63let test_cluster_remove_member sw env () =
64 let config = make_config ~port:17949 ~name:"remove-member-node" in
65 let env_wrap = { stdenv = env; sw } in
66 match Cluster.create ~sw ~env:env_wrap ~config with
67 | Error _ -> Alcotest.fail "create failed"
68 | Ok cluster ->
69 Cluster.start cluster;
70 let fake_node =
71 make_node_info
72 ~id:(node_id_of_string "fake-node")
73 ~addr:(`Udp (Eio.Net.Ipaddr.of_raw "\127\000\000\002", 7946))
74 ~meta:"test-meta"
75 in
76 Cluster.add_member cluster fake_node;
77 Eio.Time.sleep env#clock 0.02;
78 Alcotest.(check int) "before remove" 1 (Cluster.member_count cluster);
79 let removed =
80 Cluster.remove_member cluster (node_id_of_string "fake-node")
81 in
82 Alcotest.(check bool) "removed" true removed;
83 Alcotest.(check int) "after remove" 0 (Cluster.member_count cluster);
84 Cluster.shutdown cluster
85
86let test_cluster_members_list sw env () =
87 let config = make_config ~port:17950 ~name:"members-list-node" in
88 let env_wrap = { stdenv = env; sw } in
89 match Cluster.create ~sw ~env:env_wrap ~config with
90 | Error _ -> Alcotest.fail "create failed"
91 | Ok cluster ->
92 Cluster.start cluster;
93 for i = 1 to 3 do
94 let node =
95 make_node_info
96 ~id:(node_id_of_string (Printf.sprintf "node-%d" i))
97 ~addr:(`Udp (Eio.Net.Ipaddr.of_raw "\127\000\000\001", 7946 + i))
98 ~meta:""
99 in
100 Cluster.add_member cluster node
101 done;
102 Eio.Time.sleep env#clock 0.02;
103 let members = Cluster.members cluster in
104 Alcotest.(check int) "members count" 3 (List.length members);
105 Cluster.shutdown cluster
106
107let test_cluster_is_healthy sw env () =
108 let config = make_config ~port:17951 ~name:"health-node" in
109 let env_wrap = { stdenv = env; sw } in
110 match Cluster.create ~sw ~env:env_wrap ~config with
111 | Error _ -> Alcotest.fail "create failed"
112 | Ok cluster ->
113 Cluster.start cluster;
114 Alcotest.(check bool)
115 "unhealthy without members" false
116 (Cluster.is_healthy cluster);
117 Cluster.shutdown cluster
118
119let test_cluster_broadcast sw env () =
120 let config = make_config ~port:17952 ~name:"broadcast-node" in
121 let env_wrap = { stdenv = env; sw } in
122 match Cluster.create ~sw ~env:env_wrap ~config with
123 | Error _ -> Alcotest.fail "create failed"
124 | Ok cluster ->
125 Cluster.start cluster;
126 Cluster.broadcast cluster ~topic:"test-topic" ~payload:"hello world";
127 Eio.Time.sleep env#clock 0.02;
128 Cluster.shutdown cluster
129
130let test_cluster_on_message sw env () =
131 let config = make_config ~port:17953 ~name:"message-handler-node" in
132 let env_wrap = { stdenv = env; sw } in
133 match Cluster.create ~sw ~env:env_wrap ~config with
134 | Error _ -> Alcotest.fail "create failed"
135 | Ok cluster ->
136 Cluster.start cluster;
137 let received = ref false in
138 Cluster.on_message cluster (fun _topic _payload _origin ->
139 received := true);
140 Eio.Time.sleep env#clock 0.02;
141 Cluster.shutdown cluster
142
143let test_cluster_invalid_key sw env () =
144 let config =
145 { (make_config ~port:17954 ~name:"bad-key") with secret_key = "short" }
146 in
147 let env_wrap = { stdenv = env; sw } in
148 match Cluster.create ~sw ~env:env_wrap ~config with
149 | Error `Invalid_key -> ()
150 | Ok _ -> Alcotest.fail "expected invalid key error"
151
152let () =
153 Eio_main.run @@ fun env ->
154 let env = env_cast env in
155 Eio.Switch.run @@ fun sw ->
156 Alcotest.run "integration"
157 [
158 ( "cluster",
159 [
160 ( "create_start_shutdown",
161 `Quick,
162 test_cluster_create_start_shutdown sw env );
163 ("stats", `Quick, test_cluster_stats sw env);
164 ("add_member", `Quick, test_cluster_add_member sw env);
165 ("remove_member", `Quick, test_cluster_remove_member sw env);
166 ("members_list", `Quick, test_cluster_members_list sw env);
167 ("is_healthy", `Quick, test_cluster_is_healthy sw env);
168 ("broadcast", `Quick, test_cluster_broadcast sw env);
169 ("on_message", `Quick, test_cluster_on_message sw env);
170 ("invalid_key", `Quick, test_cluster_invalid_key sw env);
171 ] );
172 ]