Annotate

spec/net_resolvers_service_spec.lua @ 13014:06453c564141

util.startup: Add prosody.started promise to easily execute code after startup To avoid a race where server-started fires before the promise function body is run (on next tick), I moved server-started to fire on the next tick, which seems sensible anyway. Errors are logged, I'm not sure if we ought to be doing something more here. I'm sure we'll find out.
author Matthew Wild <mwild1@gmail.com>
date Sat, 01 Apr 2023 11:56:38 +0100
parent 12401:c029ddcad258
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
12401
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 local set = require "util.set";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 insulate("net.resolvers.service", function ()
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4 local adns = {
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5 resolver = function ()
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6 return {
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 lookup = function (_, cb, qname, qtype, qclass)
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8 if qname == "_xmpp-server._tcp.example.com"
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9 and (qtype or "SRV") == "SRV"
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10 and (qclass or "IN") == "IN" then
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
11 cb({
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
12 { -- 60+35+60
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
13 srv = { target = "xmpp0-a.example.com", port = 5228, priority = 0, weight = 60 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
14 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15 {
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
16 srv = { target = "xmpp0-b.example.com", port = 5216, priority = 0, weight = 35 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
17 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18 {
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19 srv = { target = "xmpp0-c.example.com", port = 5200, priority = 0, weight = 0 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
21 {
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22 srv = { target = "xmpp0-d.example.com", port = 5256, priority = 0, weight = 120 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25 {
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26 srv = { target = "xmpp1-a.example.com", port = 5273, priority = 1, weight = 30 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28 {
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29 srv = { target = "xmpp1-b.example.com", port = 5274, priority = 1, weight = 30 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
30 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32 {
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33 srv = { target = "xmpp2.example.com", port = 5275, priority = 2, weight = 0 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
34 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35 });
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 elseif qname == "_xmpp-server._tcp.single.example.com"
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37 and (qtype or "SRV") == "SRV"
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38 and (qclass or "IN") == "IN" then
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39 cb({
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40 {
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41 srv = { target = "xmpp0-a.example.com", port = 5269, priority = 0, weight = 0 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 });
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44 elseif qname == "_xmpp-server._tcp.half.example.com"
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45 and (qtype or "SRV") == "SRV"
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 and (qclass or "IN") == "IN" then
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 cb({
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 {
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 srv = { target = "xmpp0-a.example.com", port = 5269, priority = 0, weight = 0 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 {
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52 srv = { target = "xmpp0-b.example.com", port = 5270, priority = 0, weight = 1 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 });
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 elseif qtype == "A" then
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56 local l = qname:match("%-(%a)%.example.com$") or "1";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 local d = ("%d"):format(l:byte())
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58 cb({
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 {
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 a = "127.0.0."..d;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62 });
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 elseif qtype == "AAAA" then
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64 local l = qname:match("%-(%a)%.example.com$") or "1";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 local d = ("%04d"):format(l:byte())
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66 cb({
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67 {
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 aaaa = "fdeb:9619:649e:c7d9::"..d;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70 });
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 else
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 cb(nil);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73 end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74 end;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76 end;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
77 };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78 package.loaded["net.adns"] = mock(adns);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79 local resolver = require "net.resolvers.service";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80 math.randomseed(os.time());
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81 it("works for 99% of deployments", function ()
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 -- Most deployments only have a single SRV record, let's make
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
83 -- sure that works okay
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
84
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
85 local expected_targets = set.new({
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
86 -- xmpp0-a
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
87 "tcp4 127.0.0.97 5269";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
88 "tcp6 fdeb:9619:649e:c7d9::0097 5269";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
89 });
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
90 local received_targets = set.new({});
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
91
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
92 local r = resolver.new("single.example.com", "xmpp-server");
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93 local done = false;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94 local function handle_target(...)
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95 if ... == nil then
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96 done = true;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97 -- No more targets
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
98 return;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
99 end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
100 received_targets:add(table.concat({ ... }, " ", 1, 3));
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
101 end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
102 r:next(handle_target);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
103 while not done do
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
104 r:next(handle_target);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
105 end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
106
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
107 -- We should have received all expected targets, and no unexpected
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
108 -- ones:
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 assert.truthy(set.xor(received_targets, expected_targets):empty());
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
110 end);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
111
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
112 it("supports A/AAAA fallback", function ()
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
113 -- Many deployments don't have any SRV records, so we should
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
114 -- fall back to A/AAAA records instead when that is the case
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
115
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
116 local expected_targets = set.new({
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
117 -- xmpp0-a
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
118 "tcp4 127.0.0.97 5269";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
119 "tcp6 fdeb:9619:649e:c7d9::0097 5269";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
120 });
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
121 local received_targets = set.new({});
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
122
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
123 local r = resolver.new("xmpp0-a.example.com", "xmpp-server", "tcp", { default_port = 5269 });
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
124 local done = false;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
125 local function handle_target(...)
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
126 if ... == nil then
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
127 done = true;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
128 -- No more targets
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
129 return;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
130 end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
131 received_targets:add(table.concat({ ... }, " ", 1, 3));
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
132 end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
133 r:next(handle_target);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
134 while not done do
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
135 r:next(handle_target);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
136 end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
137
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
138 -- We should have received all expected targets, and no unexpected
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
139 -- ones:
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
140 assert.truthy(set.xor(received_targets, expected_targets):empty());
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
141 end);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
142
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
143
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
144 it("works", function ()
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
145 local expected_targets = set.new({
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
146 -- xmpp0-a
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
147 "tcp4 127.0.0.97 5228";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
148 "tcp6 fdeb:9619:649e:c7d9::0097 5228";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
149 "tcp4 127.0.0.97 5273";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
150 "tcp6 fdeb:9619:649e:c7d9::0097 5273";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
151
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
152 -- xmpp0-b
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
153 "tcp4 127.0.0.98 5274";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
154 "tcp6 fdeb:9619:649e:c7d9::0098 5274";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
155 "tcp4 127.0.0.98 5216";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
156 "tcp6 fdeb:9619:649e:c7d9::0098 5216";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
157
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
158 -- xmpp0-c
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
159 "tcp4 127.0.0.99 5200";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
160 "tcp6 fdeb:9619:649e:c7d9::0099 5200";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
161
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
162 -- xmpp0-d
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
163 "tcp4 127.0.0.100 5256";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
164 "tcp6 fdeb:9619:649e:c7d9::0100 5256";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
165
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
166 -- xmpp2
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
167 "tcp4 127.0.0.49 5275";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
168 "tcp6 fdeb:9619:649e:c7d9::0049 5275";
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
169
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
170 });
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
171 local received_targets = set.new({});
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
172
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
173 local r = resolver.new("example.com", "xmpp-server");
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
174 local done = false;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
175 local function handle_target(...)
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
176 if ... == nil then
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
177 done = true;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
178 -- No more targets
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
179 return;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
180 end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
181 received_targets:add(table.concat({ ... }, " ", 1, 3));
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
182 end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
183 r:next(handle_target);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
184 while not done do
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
185 r:next(handle_target);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
186 end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
187
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
188 -- We should have received all expected targets, and no unexpected
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
189 -- ones:
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
190 assert.truthy(set.xor(received_targets, expected_targets):empty());
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
191 end);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
192
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
193 it("balances across weights correctly #slow", function ()
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
194 -- This mimics many repeated connections to 'example.com' (mock
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
195 -- records defined above), and records the port number of the
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
196 -- first target. Therefore it (should) only return priority
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
197 -- 0 records, and the input data is constructed such that the
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
198 -- last two digits of the port number represent the percentage
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
199 -- of times that record should (on average) be picked first.
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
200
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
201 -- To prevent random test failures, we test across a handful
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
202 -- of fixed (randomly selected) seeds.
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
203 for _, seed in ipairs({ 8401877, 3943829, 7830992 }) do
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
204 math.randomseed(seed);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
205
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
206 local results = {};
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
207 local function run()
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
208 local run_results = {};
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
209 local r = resolver.new("example.com", "xmpp-server");
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
210 local function record_target(...)
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
211 if ... == nil then
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
212 -- No more targets
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
213 return;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
214 end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
215 run_results = { ... };
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
216 end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
217 r:next(record_target);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
218 return run_results[3];
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
219 end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
220
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
221 for _ = 1, 1000 do
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
222 local port = run();
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
223 results[port] = (results[port] or 0) + 1;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
224 end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
225
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
226 local ports = {};
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
227 for port in pairs(results) do
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
228 table.insert(ports, port);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
229 end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
230 table.sort(ports);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
231 for _, port in ipairs(ports) do
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
232 --print("PORT", port, tostring((results[port]/1000) * 100).."% hits (expected "..tostring(port-5200).."%)");
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
233 local hit_pct = (results[port]/1000) * 100;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
234 local expected_pct = port - 5200;
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
235 --print(hit_pct, expected_pct, math.abs(hit_pct - expected_pct));
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
236 assert.is_true(math.abs(hit_pct - expected_pct) < 5);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
237 end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
238 --print("---");
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
239 end
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
240 end);
c029ddcad258 net.resolvers.service: Honour record 'weight' when picking SRV targets
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
241 end);