1 # Copyright (c) Twisted Matrix Laboratories.
2 # See LICENSE for details.
6 from twisted.trial import unittest
8 from twisted.names import dns, cache
9 from twisted.internet import task
11 class Caching(unittest.TestCase):
13 Tests for L{cache.CacheResolver}.
16 def test_lookup(self):
17 c = cache.CacheResolver({
18 dns.Query(name='example.com', type=dns.MX, cls=dns.IN):
19 (time.time(), ([], [], []))})
20 return c.lookupMailExchange('example.com').addCallback(
21 self.assertEqual, ([], [], []))
24 def test_constructorExpires(self):
26 Cache entries passed into L{cache.CacheResolver.__init__} get
27 cancelled just like entries added with cacheResult
30 r = ([dns.RRHeader("example.com", dns.A, dns.IN, 60,
31 dns.Record_A("127.0.0.1", 60))],
32 [dns.RRHeader("example.com", dns.A, dns.IN, 50,
33 dns.Record_A("127.0.0.1", 50))],
34 [dns.RRHeader("example.com", dns.A, dns.IN, 40,
35 dns.Record_A("127.0.0.1", 40))])
38 query = dns.Query(name="example.com", type=dns.A, cls=dns.IN)
40 c = cache.CacheResolver({ query : (clock.seconds(), r)}, reactor=clock)
42 # 40 seconds is enough to expire the entry because expiration is based
46 self.assertNotIn(query, c.cache)
48 return self.assertFailure(
49 c.lookupAddress("example.com"), dns.DomainError)
52 def test_normalLookup(self):
54 When a cache lookup finds a cached entry from 1 second ago, it is
55 returned with a TTL of original TTL minus the elapsed 1 second.
57 r = ([dns.RRHeader("example.com", dns.A, dns.IN, 60,
58 dns.Record_A("127.0.0.1", 60))],
59 [dns.RRHeader("example.com", dns.A, dns.IN, 50,
60 dns.Record_A("127.0.0.1", 50))],
61 [dns.RRHeader("example.com", dns.A, dns.IN, 40,
62 dns.Record_A("127.0.0.1", 40))])
66 c = cache.CacheResolver(reactor=clock)
67 c.cacheResult(dns.Query(name="example.com", type=dns.A, cls=dns.IN), r)
72 self.assertEquals(result[0][0].ttl, 59)
73 self.assertEquals(result[1][0].ttl, 49)
74 self.assertEquals(result[2][0].ttl, 39)
75 self.assertEquals(result[0][0].name.name, "example.com")
77 return c.lookupAddress("example.com").addCallback(cbLookup)
80 def test_negativeTTLLookup(self):
82 When the cache is queried exactly as the cached entry should expire
83 but before it has actually been cleared, the TTL will be 0, not
86 r = ([dns.RRHeader("example.com", dns.A, dns.IN, 60,
87 dns.Record_A("127.0.0.1", 60))],
88 [dns.RRHeader("example.com", dns.A, dns.IN, 50,
89 dns.Record_A("127.0.0.1", 50))],
90 [dns.RRHeader("example.com", dns.A, dns.IN, 40,
91 dns.Record_A("127.0.0.1", 40))])
94 # Make sure timeouts never happen, so entries won't get cleared:
95 clock.callLater = lambda *args, **kwargs: None
97 c = cache.CacheResolver({
98 dns.Query(name="example.com", type=dns.A, cls=dns.IN) :
99 (clock.seconds(), r)}, reactor=clock)
103 def cbLookup(result):
104 self.assertEquals(result[0][0].ttl, 0)
105 self.assertEquals(result[0][0].ttl, 0)
106 self.assertEquals(result[0][0].ttl, 0)
107 self.assertEquals(result[0][0].name.name, "example.com")
109 return c.lookupAddress("example.com").addCallback(cbLookup)