Merge lp:~termie/nova/remove_ioloop into lp:~hudson-openstack/nova/trunk

Proposed by termie
Status: Merged
Merged at revision: 300
Proposed branch: lp:~termie/nova/remove_ioloop
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 265 lines (+64/-34)
7 files modified
nova/rpc.py (+2/-17)
nova/test.py (+49/-5)
nova/tests/access_unittest.py (+1/-1)
nova/tests/auth_unittest.py (+1/-1)
nova/tests/cloud_unittest.py (+8/-6)
nova/tests/objectstore_unittest.py (+1/-1)
nova/tests/rpc_unittest.py (+2/-3)
To merge this branch: bzr merge lp:~termie/nova/remove_ioloop
Reviewer Review Type Date Requested Status
Joshua McKenty (community) Approve
Review via email: mp+34913@code.launchpad.net

Description of the change

Removes most traces of tornado from the codebase, leaving only the things that gundlach's branch will remove later.

The tests were passing even while the code was wrong during part of this process so I updated the TrialTestCase tests to emulate the behavior that BaseTestCase was providing of automatically turning test cases that return generators into defer.inlineCallbacks.

To post a comment you must log in.
Revision history for this message
Joshua McKenty (joshua-mckenty) wrote :

lgtm, with a bit of either hesitation or confusion about how you're storing originalAttach as an instance property (in _monkeyPatchAttach). Isn't there some risk that rpc.Consumer.attach_to_twisted will be called independently from some of the code during the test runs? (I suppose it's very unlikely...)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'nova/rpc.py'
2--- nova/rpc.py 2010-08-18 15:44:24 +0000
3+++ nova/rpc.py 2010-09-08 20:59:25 +0000
4@@ -81,21 +81,6 @@
5 self.failed_connection = False
6 super(Consumer, self).__init__(*args, **kwargs)
7
8- # TODO(termie): it would be nice to give these some way of automatically
9- # cleaning up after themselves
10- def attach_to_tornado(self, io_inst=None):
11- """Attach a callback to tornado that fires 10 times a second"""
12- from tornado import ioloop
13- if io_inst is None:
14- io_inst = ioloop.IOLoop.instance()
15-
16- injected = ioloop.PeriodicCallback(
17- lambda: self.fetch(enable_callbacks=True), 100, io_loop=io_inst)
18- injected.start()
19- return injected
20-
21- attachToTornado = attach_to_tornado
22-
23 def fetch(self, no_ack=None, auto_ack=None, enable_callbacks=False):
24 """Wraps the parent fetch with some logic for failed connections"""
25 # TODO(vish): the logic for failed connections and logging should be
26@@ -123,6 +108,7 @@
27 """Attach a callback to twisted that fires 10 times a second"""
28 loop = task.LoopingCall(self.fetch, enable_callbacks=True)
29 loop.start(interval=0.1)
30+ return loop
31
32
33 class Publisher(messaging.Publisher):
34@@ -264,7 +250,6 @@
35 msg_id = uuid.uuid4().hex
36 msg.update({'_msg_id': msg_id})
37 LOG.debug("MSG_ID is %s" % (msg_id))
38-
39 conn = Connection.instance()
40 d = defer.Deferred()
41 consumer = DirectConsumer(connection=conn, msg_id=msg_id)
42@@ -278,7 +263,7 @@
43 return d.callback(data['result'])
44
45 consumer.register_callback(deferred_receive)
46- injected = consumer.attach_to_tornado()
47+ injected = consumer.attach_to_twisted()
48
49 # clean up after the injected listened and return x
50 d.addCallback(lambda x: injected.stop() and x or x)
51
52=== modified file 'nova/test.py'
53--- nova/test.py 2010-08-18 15:44:24 +0000
54+++ nova/test.py 2010-09-08 20:59:25 +0000
55@@ -33,6 +33,7 @@
56
57 from nova import fakerabbit
58 from nova import flags
59+from nova import rpc
60
61
62 FLAGS = flags.FLAGS
63@@ -62,19 +63,29 @@
64 self.mox = mox.Mox()
65 self.stubs = stubout.StubOutForTesting()
66 self.flag_overrides = {}
67+ self.injected = []
68+ self._monkeyPatchAttach()
69
70 def tearDown(self): # pylint: disable-msg=C0103
71 """Runs after each test method to finalize/tear down test environment"""
72- super(TrialTestCase, self).tearDown()
73 self.reset_flags()
74 self.mox.UnsetStubs()
75 self.stubs.UnsetAll()
76 self.stubs.SmartUnsetAll()
77 self.mox.VerifyAll()
78+
79+ rpc.Consumer.attach_to_twisted = self.originalAttach
80+ for x in self.injected:
81+ try:
82+ x.stop()
83+ except AssertionError:
84+ pass
85
86 if FLAGS.fake_rabbit:
87 fakerabbit.reset_all()
88
89+ super(TrialTestCase, self).tearDown()
90+
91 def flags(self, **kw):
92 """Override flag variables for a test"""
93 for k, v in kw.iteritems():
94@@ -90,16 +101,51 @@
95 for k, v in self.flag_overrides.iteritems():
96 setattr(FLAGS, k, v)
97
98+ def run(self, result=None):
99+ test_method = getattr(self, self._testMethodName)
100+ setattr(self,
101+ self._testMethodName,
102+ self._maybeInlineCallbacks(test_method, result))
103+ rv = super(TrialTestCase, self).run(result)
104+ setattr(self, self._testMethodName, test_method)
105+ return rv
106+
107+ def _maybeInlineCallbacks(self, func, result):
108+ def _wrapped():
109+ g = func()
110+ if isinstance(g, defer.Deferred):
111+ return g
112+ if not hasattr(g, 'send'):
113+ return defer.succeed(g)
114+
115+ inlined = defer.inlineCallbacks(func)
116+ d = inlined()
117+ return d
118+ _wrapped.func_name = func.func_name
119+ return _wrapped
120+
121+ def _monkeyPatchAttach(self):
122+ self.originalAttach = rpc.Consumer.attach_to_twisted
123+ def _wrapped(innerSelf):
124+ rv = self.originalAttach(innerSelf)
125+ self.injected.append(rv)
126+ return rv
127+
128+ _wrapped.func_name = self.originalAttach.func_name
129+ rpc.Consumer.attach_to_twisted = _wrapped
130+
131
132 class BaseTestCase(TrialTestCase):
133 # TODO(jaypipes): Can this be moved into the TrialTestCase class?
134- """Base test case class for all unit tests."""
135+ """Base test case class for all unit tests.
136+
137+ DEPRECATED: This is being removed once Tornado is gone, use TrialTestCase.
138+ """
139 def setUp(self): # pylint: disable-msg=C0103
140 """Run before each test method to initialize test environment"""
141 super(BaseTestCase, self).setUp()
142 # TODO(termie): we could possibly keep a more global registry of
143 # the injected listeners... this is fine for now though
144- self.injected = []
145 self.ioloop = ioloop.IOLoop.instance()
146
147 self._waiting = None
148@@ -109,8 +155,6 @@
149 def tearDown(self):# pylint: disable-msg=C0103
150 """Runs after each test method to finalize/tear down test environment"""
151 super(BaseTestCase, self).tearDown()
152- for x in self.injected:
153- x.stop()
154 if FLAGS.fake_rabbit:
155 fakerabbit.reset_all()
156
157
158=== modified file 'nova/tests/access_unittest.py'
159--- nova/tests/access_unittest.py 2010-07-28 23:11:02 +0000
160+++ nova/tests/access_unittest.py 2010-09-08 20:59:25 +0000
161@@ -30,7 +30,7 @@
162 class Context(object):
163 pass
164
165-class AccessTestCase(test.BaseTestCase):
166+class AccessTestCase(test.TrialTestCase):
167 def setUp(self):
168 super(AccessTestCase, self).setUp()
169 FLAGS.connection_type = 'fake'
170
171=== modified file 'nova/tests/auth_unittest.py'
172--- nova/tests/auth_unittest.py 2010-08-11 01:04:23 +0000
173+++ nova/tests/auth_unittest.py 2010-09-08 20:59:25 +0000
174@@ -31,7 +31,7 @@
175 FLAGS = flags.FLAGS
176
177
178-class AuthTestCase(test.BaseTestCase):
179+class AuthTestCase(test.TrialTestCase):
180 flush_db = False
181 def setUp(self):
182 super(AuthTestCase, self).setUp()
183
184=== modified file 'nova/tests/cloud_unittest.py'
185--- nova/tests/cloud_unittest.py 2010-08-19 01:25:16 +0000
186+++ nova/tests/cloud_unittest.py 2010-09-08 20:59:25 +0000
187@@ -19,7 +19,6 @@
188 import logging
189 import StringIO
190 import time
191-from tornado import ioloop
192 from twisted.internet import defer
193 import unittest
194 from xml.etree import ElementTree
195@@ -36,7 +35,7 @@
196 FLAGS = flags.FLAGS
197
198
199-class CloudTestCase(test.BaseTestCase):
200+class CloudTestCase(test.TrialTestCase):
201 def setUp(self):
202 super(CloudTestCase, self).setUp()
203 self.flags(connection_type='fake',
204@@ -51,18 +50,21 @@
205 # set up a service
206 self.compute = service.ComputeService()
207 self.compute_consumer = rpc.AdapterConsumer(connection=self.conn,
208- topic=FLAGS.compute_topic,
209- proxy=self.compute)
210- self.injected.append(self.compute_consumer.attach_to_tornado(self.ioloop))
211+ topic=FLAGS.compute_topic,
212+ proxy=self.compute)
213+ self.compute_consumer.attach_to_twisted()
214
215 try:
216 manager.AuthManager().create_user('admin', 'admin', 'admin')
217 except: pass
218 admin = manager.AuthManager().get_user('admin')
219 project = manager.AuthManager().create_project('proj', 'admin', 'proj')
220- self.context = api.APIRequestContext(handler=None,project=project,user=admin)
221+ self.context = api.APIRequestContext(handler=None,
222+ project=project,
223+ user=admin)
224
225 def tearDown(self):
226+ super(CloudTestCase, self).tearDown()
227 manager.AuthManager().delete_project('proj')
228 manager.AuthManager().delete_user('admin')
229
230
231=== modified file 'nova/tests/objectstore_unittest.py'
232--- nova/tests/objectstore_unittest.py 2010-08-18 15:44:24 +0000
233+++ nova/tests/objectstore_unittest.py 2010-09-08 20:59:25 +0000
234@@ -53,7 +53,7 @@
235 os.makedirs(os.path.join(OSS_TEMPDIR, 'buckets'))
236
237
238-class ObjectStoreTestCase(test.BaseTestCase):
239+class ObjectStoreTestCase(test.TrialTestCase):
240 """Test objectstore API directly."""
241
242 def setUp(self): # pylint: disable-msg=C0103
243
244=== modified file 'nova/tests/rpc_unittest.py'
245--- nova/tests/rpc_unittest.py 2010-08-18 15:44:24 +0000
246+++ nova/tests/rpc_unittest.py 2010-09-08 20:59:25 +0000
247@@ -30,7 +30,7 @@
248 FLAGS = flags.FLAGS
249
250
251-class RpcTestCase(test.BaseTestCase):
252+class RpcTestCase(test.TrialTestCase):
253 """Test cases for rpc"""
254 def setUp(self): # pylint: disable-msg=C0103
255 super(RpcTestCase, self).setUp()
256@@ -39,8 +39,7 @@
257 self.consumer = rpc.AdapterConsumer(connection=self.conn,
258 topic='test',
259 proxy=self.receiver)
260-
261- self.injected.append(self.consumer.attach_to_tornado(self.ioloop))
262+ self.consumer.attach_to_twisted()
263
264 def test_call_succeed(self):
265 """Get a value through rpc call"""