2 """Tests for the eventlet.support.greendns module"""
10 from tests import mock
13 import dns.rdtypes.IN.A
14 import dns.rdtypes.IN.AAAA
16 import dns.reversename
18 from eventlet.support import greendns
19 greendns_available = True
21 greendns_available = False
22 greendns = mock.Mock()
25 def greendns_requirement(_f):
26 """We want to skip tests if greendns is not installed.
28 return greendns_available
31 class TestHostsResolver(tests.LimitedTestCase):
33 def _make_host_resolver(self):
34 """Returns a HostResolver instance
36 The hosts file will be empty but accessible as a py.path.local
37 instance using the ``hosts`` attribute.
39 hosts = tempfile.NamedTemporaryFile()
40 hr = greendns.HostsResolver(fname=hosts.name)
45 @tests.skip_unless(greendns_requirement)
46 def test_default_fname(self):
47 hr = greendns.HostsResolver()
48 assert os.path.exists(hr.fname)
50 @tests.skip_unless(greendns_requirement)
51 def test_readlines_lines(self):
52 hr = self._make_host_resolver()
53 hr.hosts.write(b'line0\n')
55 assert hr._readlines() == ['line0']
57 hr.hosts.write(b'line1\n')
59 assert hr._readlines() == ['line0', 'line1']
61 hr.hosts.write(b'#comment0\nline0\n #comment1\nline1')
62 assert hr._readlines() == ['line0', 'line1']
64 @tests.skip_unless(greendns_requirement)
65 def test_readlines_missing_file(self):
66 hr = self._make_host_resolver()
69 assert hr._readlines() == []
71 @tests.skip_unless(greendns_requirement)
72 def test_load_no_contents(self):
73 hr = self._make_host_resolver()
77 assert not hr._aliases
79 @tests.skip_unless(greendns_requirement)
80 def test_load_v4_v6_cname_aliases(self):
81 hr = self._make_host_resolver()
82 hr.hosts.write(b'1.2.3.4 v4.example.com v4\n'
83 b'dead:beef::1 v6.example.com v6\n')
86 assert hr._v4 == {'v4.example.com': '1.2.3.4', 'v4': '1.2.3.4'}
87 assert hr._v6 == {'v6.example.com': 'dead:beef::1',
89 assert hr._aliases == {'v4': 'v4.example.com',
90 'v6': 'v6.example.com'}
92 @tests.skip_unless(greendns_requirement)
93 def test_load_v6_link_local(self):
94 hr = self._make_host_resolver()
95 hr.hosts.write(b'fe80:: foo\n'
96 b'fe80:dead:beef::1 bar\n')
102 @tests.skip_unless(greendns_requirement)
103 def test_query_A(self):
104 hr = self._make_host_resolver()
105 hr._v4 = {'v4.example.com': '1.2.3.4'}
106 ans = hr.query('v4.example.com')
107 assert ans[0].address == '1.2.3.4'
109 @tests.skip_unless(greendns_requirement)
110 def test_query_ans_types(self):
111 # This assumes test_query_A above succeeds
112 hr = self._make_host_resolver()
113 hr._v4 = {'v4.example.com': '1.2.3.4'}
114 hr._last_stat = time.time()
115 ans = hr.query('v4.example.com')
116 assert isinstance(ans, greendns.dns.resolver.Answer)
117 assert ans.response is None
118 assert ans.qname == dns.name.from_text('v4.example.com')
119 assert ans.rdtype == dns.rdatatype.A
120 assert ans.rdclass == dns.rdataclass.IN
121 assert ans.canonical_name == dns.name.from_text('v4.example.com')
122 assert ans.expiration
123 assert isinstance(ans.rrset, dns.rrset.RRset)
124 assert ans.rrset.rdtype == dns.rdatatype.A
125 assert ans.rrset.rdclass == dns.rdataclass.IN
126 ttl = greendns.HOSTS_TTL
127 assert ttl - 1 <= ans.rrset.ttl <= ttl + 1
129 assert isinstance(rr, greendns.dns.rdtypes.IN.A.A)
130 assert rr.rdtype == dns.rdatatype.A
131 assert rr.rdclass == dns.rdataclass.IN
132 assert rr.address == '1.2.3.4'
134 @tests.skip_unless(greendns_requirement)
135 def test_query_AAAA(self):
136 hr = self._make_host_resolver()
137 hr._v6 = {'v6.example.com': 'dead:beef::1'}
138 ans = hr.query('v6.example.com', dns.rdatatype.AAAA)
139 assert ans[0].address == 'dead:beef::1'
141 @tests.skip_unless(greendns_requirement)
142 def test_query_unknown_raises(self):
143 hr = self._make_host_resolver()
144 with tests.assert_raises(greendns.dns.resolver.NoAnswer):
145 hr.query('example.com')
147 @tests.skip_unless(greendns_requirement)
148 def test_query_unknown_no_raise(self):
149 hr = self._make_host_resolver()
150 ans = hr.query('example.com', raise_on_no_answer=False)
151 assert isinstance(ans, greendns.dns.resolver.Answer)
152 assert ans.response is None
153 assert ans.qname == dns.name.from_text('example.com')
154 assert ans.rdtype == dns.rdatatype.A
155 assert ans.rdclass == dns.rdataclass.IN
156 assert ans.canonical_name == dns.name.from_text('example.com')
157 assert ans.expiration
158 assert isinstance(ans.rrset, greendns.dns.rrset.RRset)
159 assert ans.rrset.rdtype == dns.rdatatype.A
160 assert ans.rrset.rdclass == dns.rdataclass.IN
161 assert len(ans.rrset) == 0
163 @tests.skip_unless(greendns_requirement)
164 def test_query_CNAME(self):
165 hr = self._make_host_resolver()
166 hr._aliases = {'host': 'host.example.com'}
167 ans = hr.query('host', dns.rdatatype.CNAME)
168 assert ans[0].target == dns.name.from_text('host.example.com')
169 assert str(ans[0].target) == 'host.example.com.'
171 @tests.skip_unless(greendns_requirement)
172 def test_query_unknown_type(self):
173 hr = self._make_host_resolver()
174 with tests.assert_raises(greendns.dns.resolver.NoAnswer):
175 hr.query('example.com', dns.rdatatype.MX)
177 @tests.skip_unless(greendns_requirement)
178 def test_getaliases(self):
179 hr = self._make_host_resolver()
180 hr._aliases = {'host': 'host.example.com',
181 'localhost': 'host.example.com'}
182 res = set(hr.getaliases('host'))
183 assert res == set(['host.example.com', 'localhost'])
185 @tests.skip_unless(greendns_requirement)
186 def test_getaliases_unknown(self):
187 hr = self._make_host_resolver()
188 assert hr.getaliases('host.example.com') == []
190 @tests.skip_unless(greendns_requirement)
191 def test_getaliases_fqdn(self):
192 hr = self._make_host_resolver()
193 hr._aliases = {'host': 'host.example.com'}
194 res = set(hr.getaliases('host.example.com'))
195 assert res == set(['host'])
198 def _make_mock_base_resolver():
199 """A mocked base resolver class"""
203 class Resolver(object):
204 aliases = ['cname.example.com']
208 def query(self, *args, **kwargs):
213 if hasattr(self, 'rrset'):
217 return greendns.HostsAnswer('foo', 1, 1, rrset, False)
219 def getaliases(self, *args, **kwargs):
225 class TestProxyResolver(tests.LimitedTestCase):
227 @tests.skip_unless(greendns_requirement)
228 def test_clear(self):
229 rp = greendns.ResolverProxy()
230 resolver = rp._resolver
232 assert rp._resolver != resolver
234 @tests.skip_unless(greendns_requirement)
235 def _make_mock_hostsresolver(self):
236 """A mocked HostsResolver"""
237 base_resolver = _make_mock_base_resolver()
238 base_resolver.rr.address = '1.2.3.4'
239 return base_resolver()
241 @tests.skip_unless(greendns_requirement)
242 def _make_mock_resolver(self):
243 """A mocked Resolver"""
244 base_resolver = _make_mock_base_resolver()
245 base_resolver.rr.address = '5.6.7.8'
246 return base_resolver()
248 @tests.skip_unless(greendns_requirement)
249 def test_hosts(self):
250 hostsres = self._make_mock_hostsresolver()
251 rp = greendns.ResolverProxy(hostsres)
252 ans = rp.query('host.example.com')
253 assert ans[0].address == '1.2.3.4'
255 @tests.skip_unless(greendns_requirement)
256 def test_hosts_noanswer(self):
257 hostsres = self._make_mock_hostsresolver()
258 res = self._make_mock_resolver()
259 rp = greendns.ResolverProxy(hostsres)
261 hostsres.raises = greendns.dns.resolver.NoAnswer
262 ans = rp.query('host.example.com')
263 assert ans[0].address == '5.6.7.8'
265 @tests.skip_unless(greendns_requirement)
266 def test_resolver(self):
267 res = self._make_mock_resolver()
268 rp = greendns.ResolverProxy()
270 ans = rp.query('host.example.com')
271 assert ans[0].address == '5.6.7.8'
273 @tests.skip_unless(greendns_requirement)
274 def test_noanswer(self):
275 res = self._make_mock_resolver()
276 rp = greendns.ResolverProxy()
278 res.raises = greendns.dns.resolver.NoAnswer
279 with tests.assert_raises(greendns.dns.resolver.NoAnswer):
280 rp.query('host.example.com')
282 @tests.skip_unless(greendns_requirement)
283 def test_nxdomain(self):
284 res = self._make_mock_resolver()
285 rp = greendns.ResolverProxy()
287 res.raises = greendns.dns.resolver.NXDOMAIN
288 with tests.assert_raises(greendns.dns.resolver.NXDOMAIN):
289 rp.query('host.example.com')
291 @tests.skip_unless(greendns_requirement)
292 def test_noanswer_hosts(self):
293 hostsres = self._make_mock_hostsresolver()
294 res = self._make_mock_resolver()
295 rp = greendns.ResolverProxy(hostsres)
297 hostsres.raises = greendns.dns.resolver.NoAnswer
298 res.raises = greendns.dns.resolver.NoAnswer
299 with tests.assert_raises(greendns.dns.resolver.NoAnswer):
300 rp.query('host.example.com')
302 def _make_mock_resolver_aliases(self):
305 target = 'host.example.com'
307 class Resolver(object):
309 exc_type = greendns.dns.resolver.NoAnswer
311 def query(self, *args, **kwargs):
315 if self.call_count < 2:
316 return greendns.HostsAnswer(args[0], 1, 5, [RR()], False)
318 raise self.exc_type()
322 @tests.skip_unless(greendns_requirement)
323 def test_getaliases(self):
324 aliases_res = self._make_mock_resolver_aliases()
325 rp = greendns.ResolverProxy()
326 rp._resolver = aliases_res
327 aliases = set(rp.getaliases('alias.example.com'))
328 assert aliases == set(['host.example.com'])
330 @tests.skip_unless(greendns_requirement)
331 def test_getaliases_fqdn(self):
332 aliases_res = self._make_mock_resolver_aliases()
333 rp = greendns.ResolverProxy()
334 rp._resolver = aliases_res
335 rp._resolver.call_count = 1
336 assert rp.getaliases('host.example.com') == []
338 @tests.skip_unless(greendns_requirement)
339 def test_getaliases_nxdomain(self):
340 aliases_res = self._make_mock_resolver_aliases()
341 rp = greendns.ResolverProxy()
342 rp._resolver = aliases_res
343 rp._resolver.call_count = 1
344 rp._resolver.exc_type = greendns.dns.resolver.NXDOMAIN
345 assert rp.getaliases('host.example.com') == []
348 class TestResolve(tests.LimitedTestCase):
351 base_resolver = _make_mock_base_resolver()
352 base_resolver.rr.address = '1.2.3.4'
353 self._old_resolver = greendns.resolver
354 greendns.resolver = base_resolver()
357 greendns.resolver = self._old_resolver
359 @tests.skip_unless(greendns_requirement)
361 ans = greendns.resolve('host.example.com', socket.AF_INET)
362 assert ans[0].address == '1.2.3.4'
363 assert greendns.resolver.args == ('host.example.com', dns.rdatatype.A)
365 @tests.skip_unless(greendns_requirement)
367 greendns.resolver.rr.address = 'dead:beef::1'
368 ans = greendns.resolve('host.example.com', socket.AF_INET6)
369 assert ans[0].address == 'dead:beef::1'
370 assert greendns.resolver.args == ('host.example.com', dns.rdatatype.AAAA)
372 @tests.skip_unless(greendns_requirement)
373 def test_unknown_rdtype(self):
374 with tests.assert_raises(socket.gaierror):
375 greendns.resolve('host.example.com', socket.AF_INET6 + 1)
377 @tests.skip_unless(greendns_requirement)
378 def test_timeout(self):
379 greendns.resolver.raises = greendns.dns.exception.Timeout
380 with tests.assert_raises(socket.gaierror):
381 greendns.resolve('host.example.com')
383 @tests.skip_unless(greendns_requirement)
385 greendns.resolver.raises = greendns.dns.exception.DNSException
386 with tests.assert_raises(socket.gaierror):
387 greendns.resolve('host.example.com')
389 @tests.skip_unless(greendns_requirement)
390 def test_noraise_noanswer(self):
391 greendns.resolver.rrset = None
392 ans = greendns.resolve('example.com', raises=False)
395 @tests.skip_unless(greendns_requirement)
396 def test_noraise_nxdomain(self):
397 greendns.resolver.raises = greendns.dns.resolver.NXDOMAIN
398 ans = greendns.resolve('example.com', raises=False)
402 class TestResolveCname(tests.LimitedTestCase):
405 base_resolver = _make_mock_base_resolver()
406 base_resolver.rr.target = 'cname.example.com'
407 self._old_resolver = greendns.resolver
408 greendns.resolver = base_resolver()
411 greendns.resolver = self._old_resolver
413 @tests.skip_unless(greendns_requirement)
414 def test_success(self):
415 cname = greendns.resolve_cname('alias.example.com')
416 assert cname == 'cname.example.com'
418 @tests.skip_unless(greendns_requirement)
419 def test_timeout(self):
420 greendns.resolver.raises = greendns.dns.exception.Timeout
421 with tests.assert_raises(socket.gaierror):
422 greendns.resolve_cname('alias.example.com')
424 @tests.skip_unless(greendns_requirement)
425 def test_nodata(self):
426 greendns.resolver.raises = greendns.dns.exception.DNSException
427 with tests.assert_raises(socket.gaierror):
428 greendns.resolve_cname('alias.example.com')
430 @tests.skip_unless(greendns_requirement)
431 def test_no_answer(self):
432 greendns.resolver.raises = greendns.dns.resolver.NoAnswer
433 assert greendns.resolve_cname('host.example.com') == 'host.example.com'
436 def _make_mock_resolve():
437 """A stubbed out resolve function
439 This monkeypatches the greendns.resolve() function with a mock.
440 You must give it answers by calling .add().
443 class MockAnswer(list):
446 class MockResolve(object):
451 def __call__(self, name, family=socket.AF_INET, raises=True):
452 qname = dns.name.from_text(name)
454 rrset = self.answers[name][family]
457 raise greendns.dns.resolver.NoAnswer()
458 rrset = dns.rrset.RRset(qname, 1, 1)
462 ans.extend(rrset.items)
465 def add(self, name, addr):
466 """Add an address to a name and family"""
468 rdata = dns.rdtypes.IN.A.A(dns.rdataclass.IN,
469 dns.rdatatype.A, addr)
470 family = socket.AF_INET
471 except (socket.error, dns.exception.SyntaxError):
472 rdata = dns.rdtypes.IN.AAAA.AAAA(dns.rdataclass.IN,
473 dns.rdatatype.AAAA, addr)
474 family = socket.AF_INET6
475 family_dict = self.answers.setdefault(name, {})
476 rrset = family_dict.get(family)
478 family_dict[family] = rrset = dns.rrset.RRset(
479 dns.name.from_text(name), rdata.rdclass, rdata.rdtype)
482 resolve = MockResolve()
486 class TestGetaddrinfo(tests.LimitedTestCase):
488 def _make_mock_resolve_cname(self):
489 """A stubbed out cname function"""
491 class ResolveCname(object):
493 cname = 'cname.example.com'
495 def __call__(self, host):
499 resolve_cname = ResolveCname()
503 self._old_resolve = greendns.resolve
504 self._old_resolve_cname = greendns.resolve_cname
505 self._old_orig_getaddrinfo = greendns.socket.getaddrinfo
508 greendns.resolve = self._old_resolve
509 greendns.resolve_cname = self._old_resolve_cname
510 greendns.socket.getaddrinfo = self._old_orig_getaddrinfo
512 @tests.skip_unless(greendns_requirement)
513 def test_getaddrinfo(self):
514 greendns.resolve = _make_mock_resolve()
515 greendns.resolve.add('example.com', '127.0.0.2')
516 greendns.resolve.add('example.com', '::1')
517 res = greendns.getaddrinfo('example.com', 'ssh')
518 addr = ('127.0.0.2', 22)
519 tcp = (socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP, addr)
520 udp = (socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP, addr)
521 addr = ('::1', 22, 0, 0)
522 tcp6 = (socket.AF_INET6, socket.SOCK_STREAM, socket.IPPROTO_TCP, addr)
523 udp6 = (socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP, addr)
524 filt_res = [ai[:3] + (ai[4],) for ai in res]
525 assert tcp in filt_res
526 assert udp in filt_res
527 assert tcp6 in filt_res
528 assert udp6 in filt_res
530 @tests.skip_unless(greendns_requirement)
531 def test_getaddrinfo_idn(self):
532 greendns.resolve = _make_mock_resolve()
533 idn_name = u'евентлет.com'
534 greendns.resolve.add(idn_name.encode('idna').decode('ascii'), '127.0.0.2')
535 res = greendns.getaddrinfo(idn_name, 'ssh')
536 addr = ('127.0.0.2', 22)
537 tcp = (socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP, addr)
538 udp = (socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP, addr)
539 filt_res = [ai[:3] + (ai[4],) for ai in res]
540 assert tcp in filt_res
541 assert udp in filt_res
543 @tests.skip_unless(greendns_requirement)
544 def test_getaddrinfo_inet(self):
545 greendns.resolve = _make_mock_resolve()
546 greendns.resolve.add('example.com', '127.0.0.2')
547 res = greendns.getaddrinfo('example.com', 'ssh', socket.AF_INET)
548 addr = ('127.0.0.2', 22)
549 tcp = (socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP, addr)
550 udp = (socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP, addr)
551 assert tcp in [ai[:3] + (ai[4],) for ai in res]
552 assert udp in [ai[:3] + (ai[4],) for ai in res]
554 @tests.skip_unless(greendns_requirement)
555 def test_getaddrinfo_inet6(self):
556 greendns.resolve = _make_mock_resolve()
557 greendns.resolve.add('example.com', '::1')
558 res = greendns.getaddrinfo('example.com', 'ssh', socket.AF_INET6)
559 addr = ('::1', 22, 0, 0)
560 tcp = (socket.AF_INET6, socket.SOCK_STREAM, socket.IPPROTO_TCP, addr)
561 udp = (socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP, addr)
562 assert tcp in [ai[:3] + (ai[4],) for ai in res]
563 assert udp in [ai[:3] + (ai[4],) for ai in res]
565 @tests.skip_unless(greendns_requirement)
566 def test_getaddrinfo_only_a_ans(self):
567 greendns.resolve = _make_mock_resolve()
568 greendns.resolve.add('example.com', '1.2.3.4')
569 res = greendns.getaddrinfo('example.com', 0)
570 addr = [('1.2.3.4', 0)] * len(res)
571 assert addr == [ai[-1] for ai in res]
573 @tests.skip_unless(greendns_requirement)
574 def test_getaddrinfo_only_aaaa_ans(self):
575 greendns.resolve = _make_mock_resolve()
576 greendns.resolve.add('example.com', 'dead:beef::1')
577 res = greendns.getaddrinfo('example.com', 0)
578 addr = [('dead:beef::1', 0, 0, 0)] * len(res)
579 assert addr == [ai[-1] for ai in res]
581 @tests.skip_unless(greendns_requirement)
582 def test_canonname(self):
583 greendns.resolve = _make_mock_resolve()
584 greendns.resolve.add('host.example.com', '1.2.3.4')
585 greendns.resolve_cname = self._make_mock_resolve_cname()
586 res = greendns.getaddrinfo('host.example.com', 0,
587 0, 0, 0, socket.AI_CANONNAME)
588 assert res[0][3] == 'cname.example.com'
590 @tests.skip_unless(greendns_requirement)
591 def test_host_none(self):
592 res = greendns.getaddrinfo(None, 80)
593 for addr in set(ai[-1] for ai in res):
594 assert addr in [('127.0.0.1', 80), ('::1', 80, 0, 0)]
596 @tests.skip_unless(greendns_requirement)
597 def test_host_none_passive(self):
598 res = greendns.getaddrinfo(None, 80, 0, 0, 0, socket.AI_PASSIVE)
599 for addr in set(ai[-1] for ai in res):
600 assert addr in [('0.0.0.0', 80), ('::', 80, 0, 0)]
602 @tests.skip_unless(greendns_requirement)
603 def test_v4mapped(self):
604 greendns.resolve = _make_mock_resolve()
605 greendns.resolve.add('example.com', '1.2.3.4')
606 res = greendns.getaddrinfo('example.com', 80,
607 socket.AF_INET6, 0, 0, socket.AI_V4MAPPED)
608 addrs = set(ai[-1] for ai in res)
609 assert addrs == set([('::ffff:1.2.3.4', 80, 0, 0)])
611 @tests.skip_unless(greendns_requirement)
612 def test_v4mapped_all(self):
613 greendns.resolve = _make_mock_resolve()
614 greendns.resolve.add('example.com', '1.2.3.4')
615 greendns.resolve.add('example.com', 'dead:beef::1')
616 res = greendns.getaddrinfo('example.com', 80, socket.AF_INET6, 0, 0,
617 socket.AI_V4MAPPED | socket.AI_ALL)
618 addrs = set(ai[-1] for ai in res)
620 assert addr in [('::ffff:1.2.3.4', 80, 0, 0),
621 ('dead:beef::1', 80, 0, 0)]
623 @tests.skip_unless(greendns_requirement)
624 def test_numericserv(self):
625 greendns.resolve = _make_mock_resolve()
626 greendns.resolve.add('example.com', '1.2.3.4')
627 with tests.assert_raises(socket.gaierror):
628 greendns.getaddrinfo('example.com', 'www', 0, 0, 0, socket.AI_NUMERICSERV)
630 @tests.skip_unless(greendns_requirement)
631 def test_numerichost(self):
632 greendns.resolve = _make_mock_resolve()
633 greendns.resolve.add('example.com', '1.2.3.4')
634 with tests.assert_raises(socket.gaierror):
635 greendns.getaddrinfo('example.com', 80, 0, 0, 0, socket.AI_NUMERICHOST)
637 @tests.skip_unless(greendns_requirement)
638 def test_noport(self):
639 greendns.resolve = _make_mock_resolve()
640 greendns.resolve.add('example.com', '1.2.3.4')
641 ai = greendns.getaddrinfo('example.com', None)
642 assert ai[0][-1][1] == 0
644 @tests.skip_unless(greendns_requirement)
645 def test_AI_ADDRCONFIG(self):
646 # When the users sets AI_ADDRCONFIG but only has an IPv4
647 # address configured we will iterate over the results, but the
648 # call for the IPv6 address will fail rather then return an
649 # empty list. In that case we should catch the exception and
650 # only return the ones which worked.
651 def getaddrinfo(addr, port, family, socktype, proto, aiflags):
652 if addr == '127.0.0.1':
653 return [(socket.AF_INET, 1, 0, '', ('127.0.0.1', 0))]
654 elif addr == '::1' and aiflags & socket.AI_ADDRCONFIG:
655 raise socket.error(socket.EAI_ADDRFAMILY,
656 'Address family for hostname not supported')
657 elif addr == '::1' and not aiflags & socket.AI_ADDRCONFIG:
658 return [(socket.AF_INET6, 1, 0, '', ('::1', 0, 0, 0))]
659 greendns.socket.getaddrinfo = getaddrinfo
660 greendns.resolve = _make_mock_resolve()
661 greendns.resolve.add('localhost', '127.0.0.1')
662 greendns.resolve.add('localhost', '::1')
663 res = greendns.getaddrinfo('localhost', None,
664 0, 0, 0, socket.AI_ADDRCONFIG)
665 assert res == [(socket.AF_INET, 1, 0, '', ('127.0.0.1', 0))]
667 @tests.skip_unless(greendns_requirement)
668 def test_AI_ADDRCONFIG_noaddr(self):
669 # If AI_ADDRCONFIG is used but there is no address we need to
670 # get an exception, not an empty list.
671 def getaddrinfo(addr, port, family, socktype, proto, aiflags):
672 raise socket.error(socket.EAI_ADDRFAMILY,
673 'Address family for hostname not supported')
674 greendns.socket.getaddrinfo = getaddrinfo
675 greendns.resolve = _make_mock_resolve()
677 greendns.getaddrinfo('::1', None, 0, 0, 0, socket.AI_ADDRCONFIG)
678 except socket.error as e:
679 assert e.errno == socket.EAI_ADDRFAMILY
682 class TestIsIpAddr(tests.LimitedTestCase):
684 @tests.skip_unless(greendns_requirement)
686 assert greendns.is_ipv4_addr('1.2.3.4')
688 @tests.skip_unless(greendns_requirement)
689 def test_isv4_false(self):
690 assert not greendns.is_ipv4_addr('260.0.0.0')
692 @tests.skip_unless(greendns_requirement)
694 assert greendns.is_ipv6_addr('dead:beef::1')
696 @tests.skip_unless(greendns_requirement)
697 def test_isv6_invalid(self):
698 assert not greendns.is_ipv6_addr('foobar::1')
700 @tests.skip_unless(greendns_requirement)
702 assert greendns.is_ip_addr('1.2.3.4')
704 @tests.skip_unless(greendns_requirement)
705 def test_v4_illegal(self):
706 assert not greendns.is_ip_addr('300.0.0.1')
708 @tests.skip_unless(greendns_requirement)
709 def test_v6_addr(self):
710 assert greendns.is_ip_addr('::1')
712 @tests.skip_unless(greendns_requirement)
713 def test_isv4_none(self):
714 assert not greendns.is_ipv4_addr(None)
716 @tests.skip_unless(greendns_requirement)
717 def test_isv6_none(self):
718 assert not greendns.is_ipv6_addr(None)
720 @tests.skip_unless(greendns_requirement)
722 assert not greendns.is_ip_addr(None)
725 class TestGethostbyname(tests.LimitedTestCase):
728 self._old_resolve = greendns.resolve
729 greendns.resolve = _make_mock_resolve()
732 greendns.resolve = self._old_resolve
734 @tests.skip_unless(greendns_requirement)
735 def test_ipaddr(self):
736 assert greendns.gethostbyname('1.2.3.4') == '1.2.3.4'
738 @tests.skip_unless(greendns_requirement)
740 greendns.resolve.add('host.example.com', '1.2.3.4')
741 assert greendns.gethostbyname('host.example.com') == '1.2.3.4'
744 class TestGetaliases(tests.LimitedTestCase):
746 def _make_mock_resolver(self):
747 base_resolver = _make_mock_base_resolver()
748 resolver = base_resolver()
749 resolver.aliases = ['cname.example.com']
753 self._old_resolver = greendns.resolver
754 greendns.resolver = self._make_mock_resolver()
757 greendns.resolver = self._old_resolver
759 @tests.skip_unless(greendns_requirement)
760 def test_getaliases(self):
761 assert greendns.getaliases('host.example.com') == ['cname.example.com']
764 class TestGethostbyname_ex(tests.LimitedTestCase):
766 def _make_mock_getaliases(self):
768 class GetAliases(object):
769 aliases = ['cname.example.com']
771 def __call__(self, *args, **kwargs):
774 getaliases = GetAliases()
778 self._old_resolve = greendns.resolve
779 greendns.resolve = _make_mock_resolve()
780 self._old_getaliases = greendns.getaliases
783 greendns.resolve = self._old_resolve
784 greendns.getaliases = self._old_getaliases
786 @tests.skip_unless(greendns_requirement)
787 def test_ipaddr(self):
788 res = greendns.gethostbyname_ex('1.2.3.4')
789 assert res == ('1.2.3.4', [], ['1.2.3.4'])
791 @tests.skip_unless(greendns_requirement)
793 greendns.resolve.add('host.example.com', '1.2.3.4')
794 greendns.getaliases = self._make_mock_getaliases()
795 greendns.getaliases.aliases = []
796 res = greendns.gethostbyname_ex('host.example.com')
797 assert res == ('host.example.com', [], ['1.2.3.4'])
799 @tests.skip_unless(greendns_requirement)
800 def test_multiple_addrs(self):
801 greendns.resolve.add('host.example.com', '1.2.3.4')
802 greendns.resolve.add('host.example.com', '1.2.3.5')
803 greendns.getaliases = self._make_mock_getaliases()
804 greendns.getaliases.aliases = []
805 res = greendns.gethostbyname_ex('host.example.com')
806 assert res == ('host.example.com', [], ['1.2.3.4', '1.2.3.5'])
809 def test_reverse_name():
810 tests.run_isolated('greendns_from_address_203.py')