~vishvananda/nova/network-refactor

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/internet/test/test_base.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) 2009 Twisted Matrix Laboratories.
 
2
# See LICENSE for details.
 
3
 
 
4
"""
 
5
Tests for L{twisted.internet.base}.
 
6
"""
 
7
 
 
8
import socket
 
9
from Queue import Queue
 
10
 
 
11
from zope.interface import implements
 
12
 
 
13
from twisted.python.threadpool import ThreadPool
 
14
from twisted.python.util import setIDFunction
 
15
from twisted.internet.interfaces import IReactorTime, IReactorThreads
 
16
from twisted.internet.error import DNSLookupError
 
17
from twisted.internet.base import ThreadedResolver, DelayedCall
 
18
from twisted.internet.task import Clock
 
19
from twisted.trial.unittest import TestCase
 
20
 
 
21
 
 
22
class FakeReactor(object):
 
23
    """
 
24
    A fake reactor implementation which just supports enough reactor APIs for
 
25
    L{ThreadedResolver}.
 
26
    """
 
27
    implements(IReactorTime, IReactorThreads)
 
28
 
 
29
    def __init__(self):
 
30
        self._clock = Clock()
 
31
        self.callLater = self._clock.callLater
 
32
 
 
33
        self._threadpool = ThreadPool()
 
34
        self._threadpool.start()
 
35
        self.getThreadPool = lambda: self._threadpool
 
36
 
 
37
        self._threadCalls = Queue()
 
38
 
 
39
 
 
40
    def callFromThread(self, f, *args, **kwargs):
 
41
        self._threadCalls.put((f, args, kwargs))
 
42
 
 
43
 
 
44
    def _runThreadCalls(self):
 
45
        f, args, kwargs = self._threadCalls.get()
 
46
        f(*args, **kwargs)
 
47
 
 
48
 
 
49
    def _stop(self):
 
50
        self._threadpool.stop()
 
51
 
 
52
 
 
53
 
 
54
class ThreadedResolverTests(TestCase):
 
55
    """
 
56
    Tests for L{ThreadedResolver}.
 
57
    """
 
58
    def test_success(self):
 
59
        """
 
60
        L{ThreadedResolver.getHostByName} returns a L{Deferred} which fires
 
61
        with the value returned by the call to L{socket.gethostbyname} in the
 
62
        threadpool of the reactor passed to L{ThreadedResolver.__init__}.
 
63
        """
 
64
        ip = "10.0.0.17"
 
65
        name = "foo.bar.example.com"
 
66
        timeout = 30
 
67
 
 
68
        reactor = FakeReactor()
 
69
        self.addCleanup(reactor._stop)
 
70
 
 
71
        lookedUp = []
 
72
        resolvedTo = []
 
73
        def fakeGetHostByName(name):
 
74
            lookedUp.append(name)
 
75
            return ip
 
76
 
 
77
        self.patch(socket, 'gethostbyname', fakeGetHostByName)
 
78
 
 
79
        resolver = ThreadedResolver(reactor)
 
80
        d = resolver.getHostByName(name, (timeout,))
 
81
        d.addCallback(resolvedTo.append)
 
82
 
 
83
        reactor._runThreadCalls()
 
84
 
 
85
        self.assertEqual(lookedUp, [name])
 
86
        self.assertEqual(resolvedTo, [ip])
 
87
 
 
88
        # Make sure that any timeout-related stuff gets cleaned up.
 
89
        reactor._clock.advance(timeout + 1)
 
90
        self.assertEqual(reactor._clock.calls, [])
 
91
 
 
92
 
 
93
    def test_failure(self):
 
94
        """
 
95
        L{ThreadedResolver.getHostByName} returns a L{Deferred} which fires a
 
96
        L{Failure} if the call to L{socket.gethostbyname} raises an exception.
 
97
        """
 
98
        timeout = 30
 
99
 
 
100
        reactor = FakeReactor()
 
101
        self.addCleanup(reactor._stop)
 
102
 
 
103
        def fakeGetHostByName(name):
 
104
            raise IOError("ENOBUFS (this is a funny joke)")
 
105
 
 
106
        self.patch(socket, 'gethostbyname', fakeGetHostByName)
 
107
 
 
108
        failedWith = []
 
109
        resolver = ThreadedResolver(reactor)
 
110
        d = resolver.getHostByName("some.name", (timeout,))
 
111
        self.assertFailure(d, DNSLookupError)
 
112
        d.addCallback(failedWith.append)
 
113
 
 
114
        reactor._runThreadCalls()
 
115
 
 
116
        self.assertEqual(len(failedWith), 1)
 
117
 
 
118
        # Make sure that any timeout-related stuff gets cleaned up.
 
119
        reactor._clock.advance(timeout + 1)
 
120
        self.assertEqual(reactor._clock.calls, [])
 
121
 
 
122
 
 
123
    def test_timeout(self):
 
124
        """
 
125
        If L{socket.gethostbyname} does not complete before the specified
 
126
        timeout elapsed, the L{Deferred} returned by
 
127
        L{ThreadedResolver.getHostByBame} fails with L{DNSLookupError}.
 
128
        """
 
129
        timeout = 10
 
130
 
 
131
        reactor = FakeReactor()
 
132
        self.addCleanup(reactor._stop)
 
133
 
 
134
        result = Queue()
 
135
        def fakeGetHostByName(name):
 
136
            raise result.get()
 
137
 
 
138
        self.patch(socket, 'gethostbyname', fakeGetHostByName)
 
139
 
 
140
        failedWith = []
 
141
        resolver = ThreadedResolver(reactor)
 
142
        d = resolver.getHostByName("some.name", (timeout,))
 
143
        self.assertFailure(d, DNSLookupError)
 
144
        d.addCallback(failedWith.append)
 
145
 
 
146
        reactor._clock.advance(timeout - 1)
 
147
        self.assertEqual(failedWith, [])
 
148
        reactor._clock.advance(1)
 
149
        self.assertEqual(len(failedWith), 1)
 
150
 
 
151
        # Eventually the socket.gethostbyname does finish - in this case, with
 
152
        # an exception.  Nobody cares, though.
 
153
        result.put(IOError("The I/O was errorful"))
 
154
 
 
155
 
 
156
 
 
157
class DelayedCallTests(TestCase):
 
158
    """
 
159
    Tests for L{DelayedCall}.
 
160
    """
 
161
    def test_str(self):
 
162
        """
 
163
        The string representation of a L{DelayedCall} instance, as returned by
 
164
        C{str}, includes the unsigned id of the instance, as well as its state,
 
165
        the function to be called, and the function arguments.
 
166
        """
 
167
        def nothing():
 
168
            pass
 
169
        dc = DelayedCall(12, nothing, (3, ), {"A": 5}, None, None, lambda: 1.5)
 
170
        ids = {dc: 200}
 
171
        def fakeID(obj):
 
172
            try:
 
173
                return ids[obj]
 
174
            except (TypeError, KeyError):
 
175
                return id(obj)
 
176
        self.addCleanup(setIDFunction, setIDFunction(fakeID))
 
177
        self.assertEquals(
 
178
            str(dc),
 
179
            "<DelayedCall 0xc8 [10.5s] called=0 cancelled=0 nothing(3, A=5)>")