Merge lp:~jaypipes/nova/nova-virt-connection into lp:~hudson-openstack/nova/trunk
- nova-virt-connection
- Merge into trunk
Proposed by
Jay Pipes
Status: | Merged |
---|---|
Approved by: | Eric Day |
Approved revision: | 219 |
Merged at revision: | 261 |
Proposed branch: | lp:~jaypipes/nova/nova-virt-connection |
Merge into: | lp:~hudson-openstack/nova/trunk |
Prerequisite: | lp:~jaypipes/nova/pylint |
Diff against target: |
230 lines (+63/-26) 2 files modified
nova/tests/api_unittest.py (+58/-25) nova/virt/connection.py (+5/-1) |
To merge this branch: | bzr merge lp:~jaypipes/nova/nova-virt-connection |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Vish Ishaya (community) | Approve | ||
Review via email: mp+32208@code.launchpad.net |
Commit message
Description of the change
pylint fixes for /nova/virt/
To post a comment you must log in.
Revision history for this message
Vish Ishaya (vishvananda) wrote : | # |
Revision history for this message
Vish Ishaya (vishvananda) wrote : | # |
lgtm, regardless
review:
Approve
Revision history for this message
Jay Pipes (jaypipes) wrote : | # |
Must be a pylint version thing...I don't see the deprecation warning. Do you get it only on the block-level disable-msg at the top of the file? or all the disable-msg locations?
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : | # |
Attempt to merge lp:~jaypipes/nova/nova-virt-connection into lp:nova failed due to merge conflicts:
text conflict in nova/virt/
Revision history for this message
Jay Pipes (jaypipes) wrote : | # |
Conflicts resolved...
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'nova/tests/api_unittest.py' | |||
2 | --- nova/tests/api_unittest.py 2010-07-27 04:07:28 +0000 | |||
3 | +++ nova/tests/api_unittest.py 2010-08-30 13:27:43 +0000 | |||
4 | @@ -16,6 +16,8 @@ | |||
5 | 16 | # License for the specific language governing permissions and limitations | 16 | # License for the specific language governing permissions and limitations |
6 | 17 | # under the License. | 17 | # under the License. |
7 | 18 | 18 | ||
8 | 19 | """Unit tests for the API endpoint""" | ||
9 | 20 | |||
10 | 19 | import boto | 21 | import boto |
11 | 20 | from boto.ec2 import regioninfo | 22 | from boto.ec2 import regioninfo |
12 | 21 | import httplib | 23 | import httplib |
13 | @@ -38,7 +40,15 @@ | |||
14 | 38 | # circuit boto calls and feed them into our tornado handlers, | 40 | # circuit boto calls and feed them into our tornado handlers, |
15 | 39 | # it's pretty damn circuitous so apologies if you have to fix | 41 | # it's pretty damn circuitous so apologies if you have to fix |
16 | 40 | # a bug in it | 42 | # a bug in it |
18 | 41 | def boto_to_tornado(method, path, headers, data, host, connection=None): | 43 | # NOTE(jaypipes) The pylint disables here are for R0913 (too many args) which |
19 | 44 | # isn't controllable since boto's HTTPRequest needs that many | ||
20 | 45 | # args, and for the version-differentiated import of tornado's | ||
21 | 46 | # httputil. | ||
22 | 47 | # NOTE(jaypipes): The disable-msg=E1101 and E1103 below is because pylint is | ||
23 | 48 | # unable to introspect the deferred's return value properly | ||
24 | 49 | |||
25 | 50 | def boto_to_tornado(method, path, headers, data, # pylint: disable-msg=R0913 | ||
26 | 51 | host, connection=None): | ||
27 | 42 | """ translate boto requests into tornado requests | 52 | """ translate boto requests into tornado requests |
28 | 43 | 53 | ||
29 | 44 | connection should be a FakeTornadoHttpConnection instance | 54 | connection should be a FakeTornadoHttpConnection instance |
30 | @@ -46,7 +56,7 @@ | |||
31 | 46 | try: | 56 | try: |
32 | 47 | headers = httpserver.HTTPHeaders() | 57 | headers = httpserver.HTTPHeaders() |
33 | 48 | except AttributeError: | 58 | except AttributeError: |
35 | 49 | from tornado import httputil | 59 | from tornado import httputil # pylint: disable-msg=E0611 |
36 | 50 | headers = httputil.HTTPHeaders() | 60 | headers = httputil.HTTPHeaders() |
37 | 51 | for k, v in headers.iteritems(): | 61 | for k, v in headers.iteritems(): |
38 | 52 | headers[k] = v | 62 | headers[k] = v |
39 | @@ -61,57 +71,64 @@ | |||
40 | 61 | return req | 71 | return req |
41 | 62 | 72 | ||
42 | 63 | 73 | ||
46 | 64 | def raw_to_httpresponse(s): | 74 | def raw_to_httpresponse(response_string): |
47 | 65 | """ translate a raw tornado http response into an httplib.HTTPResponse """ | 75 | """translate a raw tornado http response into an httplib.HTTPResponse""" |
48 | 66 | sock = FakeHttplibSocket(s) | 76 | sock = FakeHttplibSocket(response_string) |
49 | 67 | resp = httplib.HTTPResponse(sock) | 77 | resp = httplib.HTTPResponse(sock) |
50 | 68 | resp.begin() | 78 | resp.begin() |
51 | 69 | return resp | 79 | return resp |
52 | 70 | 80 | ||
53 | 71 | 81 | ||
54 | 72 | class FakeHttplibSocket(object): | 82 | class FakeHttplibSocket(object): |
58 | 73 | """ a fake socket implementation for httplib.HTTPResponse, trivial """ | 83 | """a fake socket implementation for httplib.HTTPResponse, trivial""" |
59 | 74 | def __init__(self, s): | 84 | def __init__(self, response_string): |
60 | 75 | self.fp = StringIO.StringIO(s) | 85 | self._buffer = StringIO.StringIO(response_string) |
61 | 76 | 86 | ||
64 | 77 | def makefile(self, mode, other): | 87 | def makefile(self, _mode, _other): |
65 | 78 | return self.fp | 88 | """Returns the socket's internal buffer""" |
66 | 89 | return self._buffer | ||
67 | 79 | 90 | ||
68 | 80 | 91 | ||
69 | 81 | class FakeTornadoStream(object): | 92 | class FakeTornadoStream(object): |
72 | 82 | """ a fake stream to satisfy tornado's assumptions, trivial """ | 93 | """a fake stream to satisfy tornado's assumptions, trivial""" |
73 | 83 | def set_close_callback(self, f): | 94 | def set_close_callback(self, _func): |
74 | 95 | """Dummy callback for stream""" | ||
75 | 84 | pass | 96 | pass |
76 | 85 | 97 | ||
77 | 86 | 98 | ||
78 | 87 | class FakeTornadoConnection(object): | 99 | class FakeTornadoConnection(object): |
80 | 88 | """ a fake connection object for tornado to pass to its handlers | 100 | """A fake connection object for tornado to pass to its handlers |
81 | 89 | 101 | ||
82 | 90 | web requests are expected to write to this as they get data and call | 102 | web requests are expected to write to this as they get data and call |
83 | 91 | finish when they are done with the request, we buffer the writes and | 103 | finish when they are done with the request, we buffer the writes and |
84 | 92 | kick off a callback when it is done so that we can feed the result back | 104 | kick off a callback when it is done so that we can feed the result back |
85 | 93 | into boto. | 105 | into boto. |
86 | 94 | """ | 106 | """ |
89 | 95 | def __init__(self, d): | 107 | def __init__(self, deferred): |
90 | 96 | self.d = d | 108 | self._deferred = deferred |
91 | 97 | self._buffer = StringIO.StringIO() | 109 | self._buffer = StringIO.StringIO() |
92 | 98 | 110 | ||
93 | 99 | def write(self, chunk): | 111 | def write(self, chunk): |
94 | 112 | """Writes a chunk of data to the internal buffer""" | ||
95 | 100 | self._buffer.write(chunk) | 113 | self._buffer.write(chunk) |
96 | 101 | 114 | ||
97 | 102 | def finish(self): | 115 | def finish(self): |
100 | 103 | s = self._buffer.getvalue() | 116 | """Finalizes the connection and returns the buffered data via the |
101 | 104 | self.d.callback(s) | 117 | deferred callback. |
102 | 118 | """ | ||
103 | 119 | data = self._buffer.getvalue() | ||
104 | 120 | self._deferred.callback(data) | ||
105 | 105 | 121 | ||
106 | 106 | xheaders = None | 122 | xheaders = None |
107 | 107 | 123 | ||
108 | 108 | @property | 124 | @property |
110 | 109 | def stream(self): | 125 | def stream(self): # pylint: disable-msg=R0201 |
111 | 126 | """Required property for interfacing with tornado""" | ||
112 | 110 | return FakeTornadoStream() | 127 | return FakeTornadoStream() |
113 | 111 | 128 | ||
114 | 112 | 129 | ||
115 | 113 | class FakeHttplibConnection(object): | 130 | class FakeHttplibConnection(object): |
117 | 114 | """ a fake httplib.HTTPConnection for boto to use | 131 | """A fake httplib.HTTPConnection for boto to use |
118 | 115 | 132 | ||
119 | 116 | requests made via this connection actually get translated and routed into | 133 | requests made via this connection actually get translated and routed into |
120 | 117 | our tornado app, we then wait for the response and turn it back into | 134 | our tornado app, we then wait for the response and turn it back into |
121 | @@ -123,7 +140,9 @@ | |||
122 | 123 | self.deferred = defer.Deferred() | 140 | self.deferred = defer.Deferred() |
123 | 124 | 141 | ||
124 | 125 | def request(self, method, path, data, headers): | 142 | def request(self, method, path, data, headers): |
126 | 126 | req = boto_to_tornado | 143 | """Creates a connection to a fake tornado and sets |
127 | 144 | up a deferred request with the supplied data and | ||
128 | 145 | headers""" | ||
129 | 127 | conn = FakeTornadoConnection(self.deferred) | 146 | conn = FakeTornadoConnection(self.deferred) |
130 | 128 | request = boto_to_tornado(connection=conn, | 147 | request = boto_to_tornado(connection=conn, |
131 | 129 | method=method, | 148 | method=method, |
132 | @@ -131,12 +150,16 @@ | |||
133 | 131 | headers=headers, | 150 | headers=headers, |
134 | 132 | data=data, | 151 | data=data, |
135 | 133 | host=self.host) | 152 | host=self.host) |
137 | 134 | handler = self.app(request) | 153 | self.app(request) |
138 | 135 | self.deferred.addCallback(raw_to_httpresponse) | 154 | self.deferred.addCallback(raw_to_httpresponse) |
139 | 136 | 155 | ||
140 | 137 | def getresponse(self): | 156 | def getresponse(self): |
141 | 157 | """A bit of deferred magic for catching the response | ||
142 | 158 | from the previously deferred request""" | ||
143 | 138 | @defer.inlineCallbacks | 159 | @defer.inlineCallbacks |
144 | 139 | def _waiter(): | 160 | def _waiter(): |
145 | 161 | """Callback that simply yields the deferred's | ||
146 | 162 | return value.""" | ||
147 | 140 | result = yield self.deferred | 163 | result = yield self.deferred |
148 | 141 | defer.returnValue(result) | 164 | defer.returnValue(result) |
149 | 142 | d = _waiter() | 165 | d = _waiter() |
150 | @@ -144,14 +167,16 @@ | |||
151 | 144 | # this deferred has already been called by the time | 167 | # this deferred has already been called by the time |
152 | 145 | # we get here, we are going to cheat and return | 168 | # we get here, we are going to cheat and return |
153 | 146 | # the result of the callback | 169 | # the result of the callback |
155 | 147 | return d.result | 170 | return d.result # pylint: disable-msg=E1101 |
156 | 148 | 171 | ||
157 | 149 | def close(self): | 172 | def close(self): |
158 | 173 | """Required for compatibility with boto/tornado""" | ||
159 | 150 | pass | 174 | pass |
160 | 151 | 175 | ||
161 | 152 | 176 | ||
162 | 153 | class ApiEc2TestCase(test.BaseTestCase): | 177 | class ApiEc2TestCase(test.BaseTestCase): |
164 | 154 | def setUp(self): | 178 | """Unit test for the cloud controller on an EC2 API""" |
165 | 179 | def setUp(self): # pylint: disable-msg=C0103,C0111 | ||
166 | 155 | super(ApiEc2TestCase, self).setUp() | 180 | super(ApiEc2TestCase, self).setUp() |
167 | 156 | 181 | ||
168 | 157 | self.manager = manager.AuthManager() | 182 | self.manager = manager.AuthManager() |
169 | @@ -171,12 +196,16 @@ | |||
170 | 171 | self.mox.StubOutWithMock(self.ec2, 'new_http_connection') | 196 | self.mox.StubOutWithMock(self.ec2, 'new_http_connection') |
171 | 172 | 197 | ||
172 | 173 | def expect_http(self, host=None, is_secure=False): | 198 | def expect_http(self, host=None, is_secure=False): |
173 | 199 | """Returns a new EC2 connection""" | ||
174 | 174 | http = FakeHttplibConnection( | 200 | http = FakeHttplibConnection( |
175 | 175 | self.app, '%s:%d' % (self.host, FLAGS.cc_port), False) | 201 | self.app, '%s:%d' % (self.host, FLAGS.cc_port), False) |
176 | 202 | # pylint: disable-msg=E1103 | ||
177 | 176 | self.ec2.new_http_connection(host, is_secure).AndReturn(http) | 203 | self.ec2.new_http_connection(host, is_secure).AndReturn(http) |
178 | 177 | return http | 204 | return http |
179 | 178 | 205 | ||
180 | 179 | def test_describe_instances(self): | 206 | def test_describe_instances(self): |
181 | 207 | """Test that, after creating a user and a project, the describe | ||
182 | 208 | instances call to the API works properly""" | ||
183 | 180 | self.expect_http() | 209 | self.expect_http() |
184 | 181 | self.mox.ReplayAll() | 210 | self.mox.ReplayAll() |
185 | 182 | user = self.manager.create_user('fake', 'fake', 'fake') | 211 | user = self.manager.create_user('fake', 'fake', 'fake') |
186 | @@ -187,14 +216,18 @@ | |||
187 | 187 | 216 | ||
188 | 188 | 217 | ||
189 | 189 | def test_get_all_key_pairs(self): | 218 | def test_get_all_key_pairs(self): |
190 | 219 | """Test that, after creating a user and project and generating | ||
191 | 220 | a key pair, that the API call to list key pairs works properly""" | ||
192 | 190 | self.expect_http() | 221 | self.expect_http() |
193 | 191 | self.mox.ReplayAll() | 222 | self.mox.ReplayAll() |
195 | 192 | keyname = "".join(random.choice("sdiuisudfsdcnpaqwertasd") for x in range(random.randint(4, 8))) | 223 | keyname = "".join(random.choice("sdiuisudfsdcnpaqwertasd") \ |
196 | 224 | for x in range(random.randint(4, 8))) | ||
197 | 193 | user = self.manager.create_user('fake', 'fake', 'fake') | 225 | user = self.manager.create_user('fake', 'fake', 'fake') |
198 | 194 | project = self.manager.create_project('fake', 'fake', 'fake') | 226 | project = self.manager.create_project('fake', 'fake', 'fake') |
199 | 195 | self.manager.generate_key_pair(user.id, keyname) | 227 | self.manager.generate_key_pair(user.id, keyname) |
200 | 196 | 228 | ||
201 | 197 | rv = self.ec2.get_all_key_pairs() | 229 | rv = self.ec2.get_all_key_pairs() |
203 | 198 | self.assertTrue(filter(lambda k: k.name == keyname, rv)) | 230 | results = [k for k in rv if k.name == keyname] |
204 | 231 | self.assertEquals(len(results), 1) | ||
205 | 199 | self.manager.delete_project(project) | 232 | self.manager.delete_project(project) |
206 | 200 | self.manager.delete_user(user) | 233 | self.manager.delete_user(user) |
207 | 201 | 234 | ||
208 | === modified file 'nova/virt/connection.py' | |||
209 | --- nova/virt/connection.py 2010-08-13 10:51:33 +0000 | |||
210 | +++ nova/virt/connection.py 2010-08-30 13:27:43 +0000 | |||
211 | @@ -17,6 +17,11 @@ | |||
212 | 17 | # License for the specific language governing permissions and limitations | 17 | # License for the specific language governing permissions and limitations |
213 | 18 | # under the License. | 18 | # under the License. |
214 | 19 | 19 | ||
215 | 20 | """Abstraction of the underlying virtualization API""" | ||
216 | 21 | |||
217 | 22 | import logging | ||
218 | 23 | import sys | ||
219 | 24 | |||
220 | 20 | from nova import flags | 25 | from nova import flags |
221 | 21 | from nova.virt import fake | 26 | from nova.virt import fake |
222 | 22 | from nova.virt import libvirt_conn | 27 | from nova.virt import libvirt_conn |
223 | @@ -35,7 +40,6 @@ | |||
224 | 35 | Any object returned here must conform to the interface documented by | 40 | Any object returned here must conform to the interface documented by |
225 | 36 | FakeConnection. | 41 | FakeConnection. |
226 | 37 | """ | 42 | """ |
227 | 38 | |||
228 | 39 | # TODO(termie): maybe lazy load after initial check for permissions | 43 | # TODO(termie): maybe lazy load after initial check for permissions |
229 | 40 | # TODO(termie): check whether we can be disconnected | 44 | # TODO(termie): check whether we can be disconnected |
230 | 41 | t = FLAGS.connection_type | 45 | t = FLAGS.connection_type |
Not a huge deal, but pylint gives me a deprecation warning on disable-msg,
and says to use disable instead.
Vish
On Tue, Aug 10, 2010 at 7:26 AM, Jay Pipes <email address hidden> wrote:
> Jay Pipes has proposed merging lp:~jaypipes/nova/nova-virt-connection into connection. py /code.launchpad .net/~jaypipes/ nova/nova- virt-connection /+merge/ 32208 api_unittest. py' api_unittest. py 2010-07-27 04:07:28 +0000 api_unittest. py 2010-08-10 14:25:59 +0000 tornado( method, path, headers, data, host, connection=None): differentiated import of tornado( method, path, headers, data, # pylint: Connection instance HTTPHeaders( ) HTTPHeaders( ) iteritems( ): httpresponse( s): HTTPResponse et(s) httpresponse( response_ string) : HTTPResponse" "" et(response_ string) HTTPResponse( sock) et(object) : HTTPResponse, trivial """ StringIO( s) HTTPResponse, trivial""" StringIO( response_ string)
> lp:nova with lp:~jaypipes/nova/pylint as a prerequisite.
>
> Requested reviews:
> Nova Core (nova-core)
>
>
> pylint fixes for /nova/virt/
> --
> https:/
> Your team Nova Core is requested to review the proposed merge of
> lp:~jaypipes/nova/nova-virt-connection into lp:nova.
>
> === modified file 'nova/tests/
> --- nova/tests/
> +++ nova/tests/
> @@ -16,6 +16,8 @@
> # License for the specific language governing permissions and
> limitations
> # under the License.
>
> +"""Unit tests for the API endpoint"""
> +
> import boto
> from boto.ec2 import regioninfo
> import httplib
> @@ -38,7 +40,15 @@
> # circuit boto calls and feed them into our tornado
> handlers,
> # it's pretty damn circuitous so apologies if you have to
> fix
> # a bug in it
> -def boto_to_
> +# NOTE(jaypipes) The pylint disables here are for R0913 (too many args)
> which
> +# isn't controllable since boto's HTTPRequest needs that
> many
> +# args, and for the version-
> tornado's
> +# httputil.
> +# NOTE(jaypipes): The disable-msg=E1101 and E1103 below is because pylint
> is
> +# unable to introspect the deferred's return value
> properly
> +
> +def boto_to_
> disable-msg=R0913
> + host, connection=None):
> """ translate boto requests into tornado requests
>
> connection should be a FakeTornadoHttp
> @@ -46,7 +56,7 @@
> try:
> headers = httpserver.
> except AttributeError:
> - from tornado import httputil
> + from tornado import httputil # pylint: disable-msg=E0611
> headers = httputil.
> for k, v in headers.
> headers[k] = v
> @@ -61,57 +71,64 @@
> return req
>
>
> -def raw_to_
> - """ translate a raw tornado http response into an httplib.
> """
> - sock = FakeHttplibSock
> +def raw_to_
> + """translate a raw tornado http response into an
> httplib.
> + sock = FakeHttplibSock
> resp = httplib.
> resp.begin()
> return resp
>
>
> class FakeHttplibSock
> - """ a fake socket implementation for httplib.
> - def __init__(self, s):
> - self.fp = StringIO.
> + """a fake socket implementation for httplib.
> + def __init__(self, response_string):
> + self._buffer = StringIO.
>
> - def makefile(self, mode, othe...