@@ -25,6 +25,7 @@ import (
2525 "fmt"
2626 "testing"
2727 "time"
28+ "net"
2829
2930 "github.com/stretchr/testify/require"
3031 "github.com/stretchr/testify/suite"
@@ -93,6 +94,8 @@ func (s *RingpopSuite) TestCustomMode() {
9394
9495type mockResolver struct {
9596 Hosts map [string ][]string
97+ SRV map [string ][]net.SRV
98+ suite * RingpopSuite
9699}
97100
98101func (resolver * mockResolver ) LookupHost (ctx context.Context , host string ) ([]string , error ) {
@@ -103,6 +106,22 @@ func (resolver *mockResolver) LookupHost(ctx context.Context, host string) ([]st
103106 return addrs , nil
104107}
105108
109+ func (resolver * mockResolver ) LookupSRV (ctx context.Context , service string , proto string , name string ) (string , []* net.SRV , error ) {
110+ var records []* net.SRV
111+ srvs , ok := resolver .SRV [service ]
112+ if ! ok {
113+ return "" , nil , fmt .Errorf ("Host was not resolved: %s" , service )
114+ }
115+
116+ for _ , record := range srvs {
117+ var srvRecord net.SRV
118+ srvRecord = record
119+ records = append (records , & srvRecord )
120+ }
121+
122+ return "test" , records , nil
123+ }
124+
106125func (s * RingpopSuite ) TestDNSMode () {
107126 var cfg Ringpop
108127 err := yaml .Unmarshal ([]byte (getDNSConfig ()), & cfg )
@@ -165,6 +184,102 @@ func (s *RingpopSuite) TestDNSMode() {
165184 s .NotNil (err , "error should be returned when no hosts" )
166185}
167186
187+ func (s * RingpopSuite ) TestDNSSRVMode () {
188+ var cfg Ringpop
189+ err := yaml .Unmarshal ([]byte (getDNSSRVConfig ()), & cfg )
190+ s .Nil (err )
191+ s .Equal ("test" , cfg .Name )
192+ s .Equal (BootstrapModeDNSSRV , cfg .BootstrapMode )
193+ s .Nil (cfg .validate ())
194+ logger := loggerimpl .NewNopLogger ()
195+ f , err := cfg .NewFactory (nil , "test" , logger )
196+ s .Nil (err )
197+ s .NotNil (f )
198+
199+ s .ElementsMatch (
200+ []string {
201+ "service-a.example.net" ,
202+ "service-b.example.net" ,
203+ "unknown-duplicate.example.net" ,
204+ "unknown-duplicate.example.net" ,
205+ "badhostport" ,
206+ },
207+ cfg .BootstrapHosts ,
208+ )
209+
210+ provider := newDNSSRVProvider (
211+ cfg .BootstrapHosts ,
212+ & mockResolver {
213+ SRV : map [string ][]net.SRV {
214+ "service-a" : []net.SRV {{ Target :"az1-service-a.addr.example.net" , Port : 7755 }, {Target : "az2-service-a.addr.example.net" , Port : 7566 }},
215+ "service-b" : []net.SRV {{ Target :"az1-service-b.addr.example.net" , Port : 7788 }, {Target : "az2-service-b.addr.example.net" , Port : 7896 }},
216+ },
217+ Hosts : map [string ][]string {
218+ "az1-service-a.addr.example.net" : []string {"10.0.0.1" },
219+ "az2-service-a.addr.example.net" : []string {"10.0.2.0" , "10.0.2.3" },
220+ "az1-service-b.addr.example.net" : []string {"10.0.3.0" , "10.0.3.3" },
221+ "az2-service-b.addr.example.net" : []string {"10.0.3.1" },
222+ },
223+ suite : s ,
224+ },
225+ logger ,
226+ )
227+ cfg .DiscoveryProvider = provider
228+ s .ElementsMatch (
229+ []string {
230+ "service-a.example.net" ,
231+ "service-b.example.net" ,
232+ "unknown-duplicate.example.net" ,
233+ "badhostport" ,
234+ },
235+ provider .UnresolvedHosts ,
236+ "duplicate entries should be removed" ,
237+ )
238+
239+ //Expect unknown-duplicate.example.net to not resolve
240+ _ , err = cfg .DiscoveryProvider .Hosts ()
241+ s .NotNil (err )
242+
243+ //Remove known bad hosts from Unresolved list
244+ provider .UnresolvedHosts = []string {
245+ "service-a.example.net" ,
246+ "service-b.example.net" ,
247+ "badhostport" ,
248+ }
249+
250+ //Expect badhostport to not seperate service name
251+ _ , err = cfg .DiscoveryProvider .Hosts ()
252+ s .NotNil (err )
253+
254+
255+ //Remove known bad hosts from Unresolved list
256+ provider .UnresolvedHosts = []string {
257+ "service-a.example.net" ,
258+ "service-b.example.net" ,
259+ }
260+
261+ hostports , err := cfg .DiscoveryProvider .Hosts ()
262+ s .Nil (err )
263+ s .ElementsMatch (
264+ []string {
265+ "10.0.0.1:7755" ,
266+ "10.0.2.0:7566" , "10.0.2.3:7566" ,
267+ "10.0.3.0:7788" , "10.0.3.3:7788" ,
268+ "10.0.3.1:7896" ,
269+ },
270+ hostports ,
271+ )
272+
273+ cfg .DiscoveryProvider = newDNSProvider (
274+ cfg .BootstrapHosts ,
275+ & mockResolver {Hosts : map [string ][]string {}},
276+ logger ,
277+ )
278+ hostports , err = cfg .DiscoveryProvider .Hosts ()
279+ s .Nil (hostports )
280+ s .NotNil (err , "error should be returned when no hosts" )
281+ }
282+
168283func (s * RingpopSuite ) TestInvalidConfig () {
169284 var cfg Ringpop
170285 s .NotNil (cfg .validate ())
@@ -207,3 +322,15 @@ bootstrapHosts:
207322- badhostport
208323maxJoinDuration: 30s`
209324}
325+
326+ func getDNSSRVConfig () string {
327+ return `name: "test"
328+ bootstrapMode: "dns-srv"
329+ bootstrapHosts:
330+ - service-a.example.net
331+ - service-b.example.net
332+ - unknown-duplicate.example.net
333+ - unknown-duplicate.example.net
334+ - badhostport
335+ maxJoinDuration: 30s`
336+ }
0 commit comments