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