1 # Copyright (c) Twisted Matrix Laboratories.
2 # See LICENSE for details.
5 Test cases for L{twisted.names.srvconnect}.
8 from twisted.internet import defer, protocol
9 from twisted.names import client, dns, srvconnect
10 from twisted.names.common import ResolverBase
11 from twisted.names.error import DNSNameError
12 from twisted.internet.error import DNSLookupError
13 from twisted.trial import unittest
14 from twisted.test.proto_helpers import MemoryReactor
17 class FakeResolver(ResolverBase):
19 Resolver that only gives out one given result.
21 Either L{results} or L{failure} must be set and will be used for
22 the return value of L{_lookup}
24 @ivar results: List of L{dns.RRHeader} for the desired result.
25 @type results: C{list}
26 @ivar failure: Failure with an exception from L{twisted.names.error}.
27 @type failure: L{Failure<twisted.python.failure.Failure>}
30 def __init__(self, results=None, failure=None):
31 self.results = results
32 self.failure = failure
34 def _lookup(self, name, cls, qtype, timeout):
36 Return the result or failure on lookup.
38 if self.results is not None:
39 return defer.succeed((self.results, [], []))
41 return defer.fail(self.failure)
45 class DummyFactory(protocol.ClientFactory):
47 Dummy client factory that stores the reason of connection failure.
52 def clientConnectionFailed(self, connector, reason):
55 class SRVConnectorTest(unittest.TestCase):
58 self.patch(client, 'theResolver', FakeResolver())
59 self.reactor = MemoryReactor()
60 self.factory = DummyFactory()
61 self.connector = srvconnect.SRVConnector(self.reactor, 'xmpp-server',
62 'example.org', self.factory)
65 def test_SRVPresent(self):
67 Test connectTCP gets called with the address from the SRV record.
69 payload = dns.Record_SRV(port=6269, target='host.example.org', ttl=60)
70 client.theResolver.results = [dns.RRHeader(name='example.org',
74 self.connector.connect()
76 self.assertIdentical(None, self.factory.reason)
78 self.reactor.tcpClients.pop()[:2], ('host.example.org', 6269))
81 def test_SRVNotPresent(self):
83 Test connectTCP gets called with fallback parameters on NXDOMAIN.
85 client.theResolver.failure = DNSNameError('example.org')
86 self.connector.connect()
88 self.assertIdentical(None, self.factory.reason)
90 self.reactor.tcpClients.pop()[:2], ('example.org', 'xmpp-server'))
93 def test_SRVNoResult(self):
95 Test connectTCP gets called with fallback parameters on empty result.
97 client.theResolver.results = []
98 self.connector.connect()
100 self.assertIdentical(None, self.factory.reason)
102 self.reactor.tcpClients.pop()[:2], ('example.org', 'xmpp-server'))
105 def test_SRVBadResult(self):
107 Test connectTCP gets called with fallback parameters on bad result.
109 client.theResolver.results = [dns.RRHeader(name='example.org',
113 self.connector.connect()
115 self.assertIdentical(None, self.factory.reason)
117 self.reactor.tcpClients.pop()[:2], ('example.org', 'xmpp-server'))
120 def test_SRVNoService(self):
122 Test that connecting fails when no service is present.
124 payload = dns.Record_SRV(port=5269, target='.', ttl=60)
125 client.theResolver.results = [dns.RRHeader(name='example.org',
129 self.connector.connect()
131 self.assertNotIdentical(None, self.factory.reason)
132 self.factory.reason.trap(DNSLookupError)
133 self.assertEqual(self.reactor.tcpClients, [])