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
=== modified file 'nova/rpc.py'
--- nova/rpc.py 2010-08-18 15:44:24 +0000
+++ nova/rpc.py 2010-09-08 20:59:25 +0000
@@ -81,21 +81,6 @@
81 self.failed_connection = False81 self.failed_connection = False
82 super(Consumer, self).__init__(*args, **kwargs)82 super(Consumer, self).__init__(*args, **kwargs)
8383
84 # TODO(termie): it would be nice to give these some way of automatically
85 # cleaning up after themselves
86 def attach_to_tornado(self, io_inst=None):
87 """Attach a callback to tornado that fires 10 times a second"""
88 from tornado import ioloop
89 if io_inst is None:
90 io_inst = ioloop.IOLoop.instance()
91
92 injected = ioloop.PeriodicCallback(
93 lambda: self.fetch(enable_callbacks=True), 100, io_loop=io_inst)
94 injected.start()
95 return injected
96
97 attachToTornado = attach_to_tornado
98
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):
100 """Wraps the parent fetch with some logic for failed connections"""85 """Wraps the parent fetch with some logic for failed connections"""
101 # TODO(vish): the logic for failed connections and logging should be86 # TODO(vish): the logic for failed connections and logging should be
@@ -123,6 +108,7 @@
123 """Attach a callback to twisted that fires 10 times a second"""108 """Attach a callback to twisted that fires 10 times a second"""
124 loop = task.LoopingCall(self.fetch, enable_callbacks=True)109 loop = task.LoopingCall(self.fetch, enable_callbacks=True)
125 loop.start(interval=0.1)110 loop.start(interval=0.1)
111 return loop
126112
127113
128class Publisher(messaging.Publisher):114class Publisher(messaging.Publisher):
@@ -264,7 +250,6 @@
264 msg_id = uuid.uuid4().hex250 msg_id = uuid.uuid4().hex
265 msg.update({'_msg_id': msg_id})251 msg.update({'_msg_id': msg_id})
266 LOG.debug("MSG_ID is %s" % (msg_id))252 LOG.debug("MSG_ID is %s" % (msg_id))
267
268 conn = Connection.instance()253 conn = Connection.instance()
269 d = defer.Deferred()254 d = defer.Deferred()
270 consumer = DirectConsumer(connection=conn, msg_id=msg_id)255 consumer = DirectConsumer(connection=conn, msg_id=msg_id)
@@ -278,7 +263,7 @@
278 return d.callback(data['result'])263 return d.callback(data['result'])
279264
280 consumer.register_callback(deferred_receive)265 consumer.register_callback(deferred_receive)
281 injected = consumer.attach_to_tornado()266 injected = consumer.attach_to_twisted()
282267
283 # clean up after the injected listened and return x268 # clean up after the injected listened and return x
284 d.addCallback(lambda x: injected.stop() and x or x)269 d.addCallback(lambda x: injected.stop() and x or x)
285270
=== modified file 'nova/test.py'
--- nova/test.py 2010-08-18 15:44:24 +0000
+++ nova/test.py 2010-09-08 20:59:25 +0000
@@ -33,6 +33,7 @@
3333
34from nova import fakerabbit34from nova import fakerabbit
35from nova import flags35from nova import flags
36from nova import rpc
3637
3738
38FLAGS = flags.FLAGS39FLAGS = flags.FLAGS
@@ -62,19 +63,29 @@
62 self.mox = mox.Mox()63 self.mox = mox.Mox()
63 self.stubs = stubout.StubOutForTesting()64 self.stubs = stubout.StubOutForTesting()
64 self.flag_overrides = {}65 self.flag_overrides = {}
66 self.injected = []
67 self._monkeyPatchAttach()
6568
66 def tearDown(self): # pylint: disable-msg=C010369 def tearDown(self): # pylint: disable-msg=C0103
67 """Runs after each test method to finalize/tear down test environment"""70 """Runs after each test method to finalize/tear down test environment"""
68 super(TrialTestCase, self).tearDown()
69 self.reset_flags()71 self.reset_flags()
70 self.mox.UnsetStubs()72 self.mox.UnsetStubs()
71 self.stubs.UnsetAll()73 self.stubs.UnsetAll()
72 self.stubs.SmartUnsetAll()74 self.stubs.SmartUnsetAll()
73 self.mox.VerifyAll()75 self.mox.VerifyAll()
76
77 rpc.Consumer.attach_to_twisted = self.originalAttach
78 for x in self.injected:
79 try:
80 x.stop()
81 except AssertionError:
82 pass
7483
75 if FLAGS.fake_rabbit:84 if FLAGS.fake_rabbit:
76 fakerabbit.reset_all()85 fakerabbit.reset_all()
7786
87 super(TrialTestCase, self).tearDown()
88
78 def flags(self, **kw):89 def flags(self, **kw):
79 """Override flag variables for a test"""90 """Override flag variables for a test"""
80 for k, v in kw.iteritems():91 for k, v in kw.iteritems():
@@ -90,16 +101,51 @@
90 for k, v in self.flag_overrides.iteritems():101 for k, v in self.flag_overrides.iteritems():
91 setattr(FLAGS, k, v)102 setattr(FLAGS, k, v)
92103
104 def run(self, result=None):
105 test_method = getattr(self, self._testMethodName)
106 setattr(self,
107 self._testMethodName,
108 self._maybeInlineCallbacks(test_method, result))
109 rv = super(TrialTestCase, self).run(result)
110 setattr(self, self._testMethodName, test_method)
111 return rv
112
113 def _maybeInlineCallbacks(self, func, result):
114 def _wrapped():
115 g = func()
116 if isinstance(g, defer.Deferred):
117 return g
118 if not hasattr(g, 'send'):
119 return defer.succeed(g)
120
121 inlined = defer.inlineCallbacks(func)
122 d = inlined()
123 return d
124 _wrapped.func_name = func.func_name
125 return _wrapped
126
127 def _monkeyPatchAttach(self):
128 self.originalAttach = rpc.Consumer.attach_to_twisted
129 def _wrapped(innerSelf):
130 rv = self.originalAttach(innerSelf)
131 self.injected.append(rv)
132 return rv
133
134 _wrapped.func_name = self.originalAttach.func_name
135 rpc.Consumer.attach_to_twisted = _wrapped
136
93137
94class BaseTestCase(TrialTestCase):138class BaseTestCase(TrialTestCase):
95 # TODO(jaypipes): Can this be moved into the TrialTestCase class?139 # TODO(jaypipes): Can this be moved into the TrialTestCase class?
96 """Base test case class for all unit tests."""140 """Base test case class for all unit tests.
141
142 DEPRECATED: This is being removed once Tornado is gone, use TrialTestCase.
143 """
97 def setUp(self): # pylint: disable-msg=C0103144 def setUp(self): # pylint: disable-msg=C0103
98 """Run before each test method to initialize test environment"""145 """Run before each test method to initialize test environment"""
99 super(BaseTestCase, self).setUp()146 super(BaseTestCase, self).setUp()
100 # TODO(termie): we could possibly keep a more global registry of147 # TODO(termie): we could possibly keep a more global registry of
101 # the injected listeners... this is fine for now though148 # the injected listeners... this is fine for now though
102 self.injected = []
103 self.ioloop = ioloop.IOLoop.instance()149 self.ioloop = ioloop.IOLoop.instance()
104150
105 self._waiting = None151 self._waiting = None
@@ -109,8 +155,6 @@
109 def tearDown(self):# pylint: disable-msg=C0103155 def tearDown(self):# pylint: disable-msg=C0103
110 """Runs after each test method to finalize/tear down test environment"""156 """Runs after each test method to finalize/tear down test environment"""
111 super(BaseTestCase, self).tearDown()157 super(BaseTestCase, self).tearDown()
112 for x in self.injected:
113 x.stop()
114 if FLAGS.fake_rabbit:158 if FLAGS.fake_rabbit:
115 fakerabbit.reset_all()159 fakerabbit.reset_all()
116160
117161
=== modified file 'nova/tests/access_unittest.py'
--- nova/tests/access_unittest.py 2010-07-28 23:11:02 +0000
+++ nova/tests/access_unittest.py 2010-09-08 20:59:25 +0000
@@ -30,7 +30,7 @@
30class Context(object):30class Context(object):
31 pass31 pass
3232
33class AccessTestCase(test.BaseTestCase):33class AccessTestCase(test.TrialTestCase):
34 def setUp(self):34 def setUp(self):
35 super(AccessTestCase, self).setUp()35 super(AccessTestCase, self).setUp()
36 FLAGS.connection_type = 'fake'36 FLAGS.connection_type = 'fake'
3737
=== modified file 'nova/tests/auth_unittest.py'
--- nova/tests/auth_unittest.py 2010-08-11 01:04:23 +0000
+++ nova/tests/auth_unittest.py 2010-09-08 20:59:25 +0000
@@ -31,7 +31,7 @@
31FLAGS = flags.FLAGS31FLAGS = flags.FLAGS
3232
3333
34class AuthTestCase(test.BaseTestCase):34class AuthTestCase(test.TrialTestCase):
35 flush_db = False35 flush_db = False
36 def setUp(self):36 def setUp(self):
37 super(AuthTestCase, self).setUp()37 super(AuthTestCase, self).setUp()
3838
=== modified file 'nova/tests/cloud_unittest.py'
--- nova/tests/cloud_unittest.py 2010-08-19 01:25:16 +0000
+++ nova/tests/cloud_unittest.py 2010-09-08 20:59:25 +0000
@@ -19,7 +19,6 @@
19import logging19import logging
20import StringIO20import StringIO
21import time21import time
22from tornado import ioloop
23from twisted.internet import defer22from twisted.internet import defer
24import unittest23import unittest
25from xml.etree import ElementTree24from xml.etree import ElementTree
@@ -36,7 +35,7 @@
36FLAGS = flags.FLAGS35FLAGS = flags.FLAGS
3736
3837
39class CloudTestCase(test.BaseTestCase):38class CloudTestCase(test.TrialTestCase):
40 def setUp(self):39 def setUp(self):
41 super(CloudTestCase, self).setUp()40 super(CloudTestCase, self).setUp()
42 self.flags(connection_type='fake',41 self.flags(connection_type='fake',
@@ -51,18 +50,21 @@
51 # set up a service50 # set up a service
52 self.compute = service.ComputeService()51 self.compute = service.ComputeService()
53 self.compute_consumer = rpc.AdapterConsumer(connection=self.conn,52 self.compute_consumer = rpc.AdapterConsumer(connection=self.conn,
54 topic=FLAGS.compute_topic,53 topic=FLAGS.compute_topic,
55 proxy=self.compute)54 proxy=self.compute)
56 self.injected.append(self.compute_consumer.attach_to_tornado(self.ioloop))55 self.compute_consumer.attach_to_twisted()
5756
58 try:57 try:
59 manager.AuthManager().create_user('admin', 'admin', 'admin')58 manager.AuthManager().create_user('admin', 'admin', 'admin')
60 except: pass59 except: pass
61 admin = manager.AuthManager().get_user('admin')60 admin = manager.AuthManager().get_user('admin')
62 project = manager.AuthManager().create_project('proj', 'admin', 'proj')61 project = manager.AuthManager().create_project('proj', 'admin', 'proj')
63 self.context = api.APIRequestContext(handler=None,project=project,user=admin)62 self.context = api.APIRequestContext(handler=None,
63 project=project,
64 user=admin)
6465
65 def tearDown(self):66 def tearDown(self):
67 super(CloudTestCase, self).tearDown()
66 manager.AuthManager().delete_project('proj')68 manager.AuthManager().delete_project('proj')
67 manager.AuthManager().delete_user('admin')69 manager.AuthManager().delete_user('admin')
6870
6971
=== modified file 'nova/tests/objectstore_unittest.py'
--- nova/tests/objectstore_unittest.py 2010-08-18 15:44:24 +0000
+++ nova/tests/objectstore_unittest.py 2010-09-08 20:59:25 +0000
@@ -53,7 +53,7 @@
53os.makedirs(os.path.join(OSS_TEMPDIR, 'buckets'))53os.makedirs(os.path.join(OSS_TEMPDIR, 'buckets'))
5454
5555
56class ObjectStoreTestCase(test.BaseTestCase):56class ObjectStoreTestCase(test.TrialTestCase):
57 """Test objectstore API directly."""57 """Test objectstore API directly."""
5858
59 def setUp(self): # pylint: disable-msg=C010359 def setUp(self): # pylint: disable-msg=C0103
6060
=== modified file 'nova/tests/rpc_unittest.py'
--- nova/tests/rpc_unittest.py 2010-08-18 15:44:24 +0000
+++ nova/tests/rpc_unittest.py 2010-09-08 20:59:25 +0000
@@ -30,7 +30,7 @@
30FLAGS = flags.FLAGS30FLAGS = flags.FLAGS
3131
3232
33class RpcTestCase(test.BaseTestCase):33class RpcTestCase(test.TrialTestCase):
34 """Test cases for rpc"""34 """Test cases for rpc"""
35 def setUp(self): # pylint: disable-msg=C010335 def setUp(self): # pylint: disable-msg=C0103
36 super(RpcTestCase, self).setUp()36 super(RpcTestCase, self).setUp()
@@ -39,8 +39,7 @@
39 self.consumer = rpc.AdapterConsumer(connection=self.conn,39 self.consumer = rpc.AdapterConsumer(connection=self.conn,
40 topic='test',40 topic='test',
41 proxy=self.receiver)41 proxy=self.receiver)
4242 self.consumer.attach_to_twisted()
43 self.injected.append(self.consumer.attach_to_tornado(self.ioloop))
4443
45 def test_call_succeed(self):44 def test_call_succeed(self):
46 """Get a value through rpc call"""45 """Get a value through rpc call"""