Annotate

spec/net_resolvers_service_spec.lua @ 12401:c029ddcad258

net.resolvers.service: Honour record 'weight' when picking SRV targets #NotHappyEyeballs
author Matthew Wild <mwild1@gmail.com>
date Thu, 17 Mar 2022 18:20:26 +0000
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);