Merge lp:~shweta-ap05/neutron/shweta-l2network-plugin-persistence into lp:~cisco-openstack/neutron/l2network-plugin-persistence
- shweta-l2network-plugin-persistence
- Merge into l2network-plugin-persistence
Proposed by
Shweta P
Status: | Merged |
---|---|
Merged at revision: | 67 |
Proposed branch: | lp:~shweta-ap05/neutron/shweta-l2network-plugin-persistence |
Merge into: | lp:~cisco-openstack/neutron/l2network-plugin-persistence |
Diff against target: |
1487 lines (+435/-611) 10 files modified
quantum/common/test_lib.py (+278/-0) quantum/plugins/cisco/README (+29/-8) quantum/plugins/cisco/run_tests.py (+41/-252) quantum/plugins/cisco/tests/unit/test_l2networkApi.py (+20/-17) quantum/plugins/cisco/tests/unit/test_nexus_plugin.py (+3/-4) quantum/plugins/cisco/tests/unit/test_ucs_driver.py (+29/-26) quantum/plugins/cisco/tests/unit/test_ucs_plugin.py (+18/-18) run_tests.py (+2/-244) run_tests.sh (+12/-3) tests/unit/test_api.py (+3/-39) |
To merge this branch: | bzr merge lp:~shweta-ap05/neutron/shweta-l2network-plugin-persistence |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sumit Naiksatam (community) | code walk through | Approve | |
Review via email: mp+71643@code.launchpad.net |
Commit message
Description of the change
Added the changes for the test structure that Dan suggested.
Added pep8 and pylint changes.
To post a comment you must log in.
Revision history for this message
Sumit Naiksatam (snaiksat) wrote : | # |
review:
Approve
(code walk through)
- 67. By Sumit Naiksatam
-
Mergin Shweta's test changes, also README file.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'quantum/common/test_lib.py' |
2 | --- quantum/common/test_lib.py 1970-01-01 00:00:00 +0000 |
3 | +++ quantum/common/test_lib.py 2011-08-16 06:17:23 +0000 |
4 | @@ -0,0 +1,278 @@ |
5 | +# vim: tabstop=4 shiftwidth=4 softtabstop=4 |
6 | + |
7 | +# Copyright 2010 OpenStack, LLC |
8 | +# All Rights Reserved. |
9 | +# |
10 | +# Licensed under the Apache License, Version 2.0 (the "License"); |
11 | +# you may not use this file except in compliance with the License. |
12 | +# You may obtain a copy of the License at |
13 | +# |
14 | +# http://www.apache.org/licenses/LICENSE-2.0 |
15 | +# |
16 | +# Unless required by applicable law or agreed to in writing, software |
17 | +# distributed under the License is distributed on an "AS IS" BASIS, |
18 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
19 | +# See the License for the specific language governing permissions and |
20 | +# limitations under the License. |
21 | + |
22 | +# Colorizer Code is borrowed from Twisted: |
23 | +# Copyright (c) 2001-2010 Twisted Matrix Laboratories. |
24 | +# |
25 | +# Permission is hereby granted, free of charge, to any person obtaining |
26 | +# a copy of this software and associated documentation files (the |
27 | +# "Software"), to deal in the Software without restriction, including |
28 | +# without limitation the rights to use, copy, modify, merge, publish, |
29 | +# distribute, sublicense, and/or sell copies of the Software, and to |
30 | +# permit persons to whom the Software is furnished to do so, subject to |
31 | +# the following conditions: |
32 | +# |
33 | +# The above copyright notice and this permission notice shall be |
34 | +# included in all copies or substantial portions of the Software. |
35 | +# |
36 | +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
37 | +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
38 | +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
39 | +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
40 | +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
41 | +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
42 | +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
43 | + |
44 | +import gettext |
45 | +import os |
46 | +import unittest |
47 | +import sys |
48 | +import logging |
49 | + |
50 | +from nose import result |
51 | +from nose import core |
52 | +from nose import config |
53 | + |
54 | + |
55 | +class _AnsiColorizer(object): |
56 | + """ |
57 | + A colorizer is an object that loosely wraps around a stream, allowing |
58 | + callers to write text to the stream in a particular color. |
59 | + |
60 | + Colorizer classes must implement C{supported()} and C{write(text, color)}. |
61 | + """ |
62 | + _colors = dict(black=30, red=31, green=32, yellow=33, |
63 | + blue=34, magenta=35, cyan=36, white=37) |
64 | + |
65 | + def __init__(self, stream): |
66 | + self.stream = stream |
67 | + |
68 | + def supported(cls, stream=sys.stdout): |
69 | + """ |
70 | + A class method that returns True if the current platform supports |
71 | + coloring terminal output using this method. Returns False otherwise. |
72 | + """ |
73 | + if not stream.isatty(): |
74 | + return False # auto color only on TTYs |
75 | + try: |
76 | + import curses |
77 | + except ImportError: |
78 | + return False |
79 | + else: |
80 | + try: |
81 | + try: |
82 | + return curses.tigetnum("colors") > 2 |
83 | + except curses.error: |
84 | + curses.setupterm() |
85 | + return curses.tigetnum("colors") > 2 |
86 | + except: |
87 | + raise |
88 | + # guess false in case of error |
89 | + return False |
90 | + supported = classmethod(supported) |
91 | + |
92 | + def write(self, text, color): |
93 | + """ |
94 | + Write the given text to the stream in the given color. |
95 | + |
96 | + @param text: Text to be written to the stream. |
97 | + |
98 | + @param color: A string label for a color. e.g. 'red', 'white'. |
99 | + """ |
100 | + color = self._colors[color] |
101 | + self.stream.write('\x1b[%s;1m%s\x1b[0m' % (color, text)) |
102 | + |
103 | + |
104 | +class _Win32Colorizer(object): |
105 | + """ |
106 | + See _AnsiColorizer docstring. |
107 | + """ |
108 | + def __init__(self, stream): |
109 | + from win32console import GetStdHandle, STD_OUT_HANDLE, \ |
110 | + FOREGROUND_RED, FOREGROUND_BLUE, FOREGROUND_GREEN, \ |
111 | + FOREGROUND_INTENSITY |
112 | + red, green, blue, bold = (FOREGROUND_RED, FOREGROUND_GREEN, |
113 | + FOREGROUND_BLUE, FOREGROUND_INTENSITY) |
114 | + self.stream = stream |
115 | + self.screenBuffer = GetStdHandle(STD_OUT_HANDLE) |
116 | + self._colors = { |
117 | + 'normal': red | green | blue, |
118 | + 'red': red | bold, |
119 | + 'green': green | bold, |
120 | + 'blue': blue | bold, |
121 | + 'yellow': red | green | bold, |
122 | + 'magenta': red | blue | bold, |
123 | + 'cyan': green | blue | bold, |
124 | + 'white': red | green | blue | bold} |
125 | + |
126 | + def supported(cls, stream=sys.stdout): |
127 | + try: |
128 | + import win32console |
129 | + screenBuffer = win32console.GetStdHandle( |
130 | + win32console.STD_OUT_HANDLE) |
131 | + except ImportError: |
132 | + return False |
133 | + import pywintypes |
134 | + try: |
135 | + screenBuffer.SetConsoleTextAttribute( |
136 | + win32console.FOREGROUND_RED | |
137 | + win32console.FOREGROUND_GREEN | |
138 | + win32console.FOREGROUND_BLUE) |
139 | + except pywintypes.error: |
140 | + return False |
141 | + else: |
142 | + return True |
143 | + supported = classmethod(supported) |
144 | + |
145 | + def write(self, text, color): |
146 | + color = self._colors[color] |
147 | + self.screenBuffer.SetConsoleTextAttribute(color) |
148 | + self.stream.write(text) |
149 | + self.screenBuffer.SetConsoleTextAttribute(self._colors['normal']) |
150 | + |
151 | + |
152 | +class _NullColorizer(object): |
153 | + """ |
154 | + See _AnsiColorizer docstring. |
155 | + """ |
156 | + def __init__(self, stream): |
157 | + self.stream = stream |
158 | + |
159 | + def supported(cls, stream=sys.stdout): |
160 | + return True |
161 | + supported = classmethod(supported) |
162 | + |
163 | + def write(self, text, color): |
164 | + self.stream.write(text) |
165 | + |
166 | + |
167 | +class QuantumTestResult(result.TextTestResult): |
168 | + def __init__(self, *args, **kw): |
169 | + result.TextTestResult.__init__(self, *args, **kw) |
170 | + self._last_case = None |
171 | + self.colorizer = None |
172 | + # NOTE(vish, tfukushima): reset stdout for the terminal check |
173 | + stdout = sys.__stdout__ |
174 | + for colorizer in [_Win32Colorizer, _AnsiColorizer, _NullColorizer]: |
175 | + if colorizer.supported(): |
176 | + self.colorizer = colorizer(self.stream) |
177 | + break |
178 | + sys.stdout = stdout |
179 | + |
180 | + def getDescription(self, test): |
181 | + return str(test) |
182 | + |
183 | + # NOTE(vish, tfukushima): copied from unittest with edit to add color |
184 | + def addSuccess(self, test): |
185 | + unittest.TestResult.addSuccess(self, test) |
186 | + if self.showAll: |
187 | + self.colorizer.write("OK", 'green') |
188 | + self.stream.writeln() |
189 | + elif self.dots: |
190 | + self.stream.write('.') |
191 | + self.stream.flush() |
192 | + |
193 | + # NOTE(vish, tfukushima): copied from unittest with edit to add color |
194 | + def addFailure(self, test, err): |
195 | + unittest.TestResult.addFailure(self, test, err) |
196 | + if self.showAll: |
197 | + self.colorizer.write("FAIL", 'red') |
198 | + self.stream.writeln() |
199 | + elif self.dots: |
200 | + self.stream.write('F') |
201 | + self.stream.flush() |
202 | + |
203 | + # NOTE(vish, tfukushima): copied from unittest with edit to add color |
204 | + def addError(self, test, err): |
205 | + """Overrides normal addError to add support for errorClasses. |
206 | + If the exception is a registered class, the error will be added |
207 | + to the list for that class, not errors. |
208 | + """ |
209 | + stream = getattr(self, 'stream', None) |
210 | + ec, ev, tb = err |
211 | + try: |
212 | + exc_info = self._exc_info_to_string(err, test) |
213 | + except TypeError: |
214 | + # This is for compatibility with Python 2.3. |
215 | + exc_info = self._exc_info_to_string(err) |
216 | + for cls, (storage, label, isfail) in self.errorClasses.items(): |
217 | + if result.isclass(ec) and issubclass(ec, cls): |
218 | + if isfail: |
219 | + test.passwd = False |
220 | + storage.append((test, exc_info)) |
221 | + # Might get patched into a streamless result |
222 | + if stream is not None: |
223 | + if self.showAll: |
224 | + message = [label] |
225 | + detail = result._exception_details(err[1]) |
226 | + if detail: |
227 | + message.append(detail) |
228 | + stream.writeln(": ".join(message)) |
229 | + elif self.dots: |
230 | + stream.write(label[:1]) |
231 | + return |
232 | + self.errors.append((test, exc_info)) |
233 | + test.passed = False |
234 | + if stream is not None: |
235 | + if self.showAll: |
236 | + self.colorizer.write("ERROR", 'red') |
237 | + self.stream.writeln() |
238 | + elif self.dots: |
239 | + stream.write('E') |
240 | + |
241 | + def startTest(self, test): |
242 | + unittest.TestResult.startTest(self, test) |
243 | + current_case = test.test.__class__.__name__ |
244 | + |
245 | + if self.showAll: |
246 | + if current_case != self._last_case: |
247 | + self.stream.writeln(current_case) |
248 | + self._last_case = current_case |
249 | + |
250 | + self.stream.write( |
251 | + ' %s' % str(test.test._testMethodName).ljust(60)) |
252 | + self.stream.flush() |
253 | + |
254 | + |
255 | +class QuantumTestRunner(core.TextTestRunner): |
256 | + def _makeResult(self): |
257 | + return QuantumTestResult(self.stream, |
258 | + self.descriptions, |
259 | + self.verbosity, |
260 | + self.config) |
261 | + |
262 | + |
263 | +def run_tests(c): |
264 | + logger = logging.getLogger() |
265 | + hdlr = logging.StreamHandler() |
266 | + formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') |
267 | + hdlr.setFormatter(formatter) |
268 | + logger.addHandler(hdlr) |
269 | + logger.setLevel(logging.DEBUG) |
270 | + |
271 | + runner = QuantumTestRunner(stream=c.stream, |
272 | + verbosity=c.verbosity, |
273 | + config=c) |
274 | + return not core.run(config=c, testRunner=runner) |
275 | + |
276 | +# describes parameters used by different unit/functional tests |
277 | +# a plugin-specific testing mechanism should import this dictionary |
278 | +# and override the values in it if needed (e.g., run_tests.py in |
279 | +# quantum/plugins/openvswitch/ ) |
280 | +test_config = { |
281 | + "plugin_name": "quantum.plugins.SamplePlugin.FakePlugin", |
282 | +} |
283 | |
284 | === modified file 'quantum/plugins/cisco/README' |
285 | --- quantum/plugins/cisco/README 2011-08-15 21:50:55 +0000 |
286 | +++ quantum/plugins/cisco/README 2011-08-16 06:17:23 +0000 |
287 | @@ -2,7 +2,7 @@ |
288 | README: Quantum L2 Network Plugin Framework |
289 | ============================================ |
290 | |
291 | -:Author: Sumit Naiksatam, Ram Durairaj, Mark Voelker, Edgar Magana, Shweta Padubidri, Rohit Agarwalla, Ying Liu, Debo Dutta |
292 | +:Author: Sumit Naiksatam, Ram Durairaj, Mark Voelker, Edgar Magana, Shweta Padubidri, Rohit Agarwalla, Ying Liu |
293 | :Contact: netstack@lists.launchpad.net |
294 | :Web site: https://launchpad.net/~cisco-openstack |
295 | :Copyright: 2011 Cisco Systems, Inc. |
296 | @@ -125,8 +125,6 @@ |
297 | # Port number on the Nexus switch to which the UCSM 6120 is connected |
298 | # Use shortened interface syntax, e.g. "3/23" not "Ethernet3/23". |
299 | nexus_port=3/23 |
300 | -#Port number where the SSH will be running at Nexus Switch, e.g.: 22 (Default) |
301 | -nexus_ssh_port=22 |
302 | |
303 | [DRIVER] |
304 | name=quantum.plugins.cisco.nexus.cisco_nexus_network_driver.CiscoNEXUSDriver |
305 | @@ -168,7 +166,8 @@ |
306 | How to test the installation |
307 | ---------------------------- |
308 | The unit tests are located at quantum/plugins/cisco/tests/unit. They can be |
309 | -executed from quantum/plugins/cisco/ using the run_tests.py script. |
310 | +executed from the main folder using the run_tests.sh or to get a more detailed |
311 | +result the quantum/plugins/cisco/run_tests.py script. |
312 | |
313 | 1. Testing the core API (without UCS/Nexus/RHEL hardware, and can be run on |
314 | Ubuntu): |
315 | @@ -176,18 +175,40 @@ |
316 | quantum/plugins/cisco/conf/plugins.ini |
317 | Then run the test script: |
318 | |
319 | -python run_tests.py unit.test_l2networkApi |
320 | + Set the environment variable PLUGIN_DIR to the location of the plugin |
321 | + directory. This is manadatory if the run_tests.sh script is used. |
322 | + |
323 | + export PLUGIN_DIR=quantum/plugins/cisco |
324 | + ./run_tests.sh quantum.plugins.cisco.tests.unit.test_l2networkApi |
325 | + |
326 | + or |
327 | + |
328 | + python quantum/plugins/cisco/run_tests.py |
329 | + quantum.plugins.cisco.tests.unit.test_l2networkApi |
330 | |
331 | 2. Specific Plugin unit test (needs environment setup as indicated in the |
332 | pre-requisites): |
333 | - python run_tests.py unit.<name_of_the file> |
334 | + |
335 | + export PLUGIN_DIR=quantum/plugins/cisco |
336 | + ./run_tests.sh quantum.plugins.cisco.tests.unit.<name_of_the file> |
337 | + |
338 | + or |
339 | + |
340 | + python <path to the plugin directory>/run_tests.py |
341 | + quantum.plugins.cisco.tests.unit.<name_of_the file> |
342 | E.g.: |
343 | |
344 | -python run_tests.py unit.test_ucs_plugin.py |
345 | + python quantum/plugins/cisco/run_tests.py |
346 | + quantum.plugins.cisco.tests.unit.test_ucs_plugin.py |
347 | |
348 | 3. All unit tests (needs environment setup as indicated in the pre-requisites): |
349 | |
350 | -python run_tests.py unit |
351 | + export PLUGIN_DIR=quantum/plugins/cisco |
352 | + ./run_tests.sh quantum.plugins.cisco.tests.unit |
353 | + |
354 | + or |
355 | + |
356 | + python quantum/plugins/cisco/run_tests.py quantum.plugins.cisco.tests.unit |
357 | |
358 | |
359 | Additional installation required on Nova Compute |
360 | |
361 | === modified file 'quantum/plugins/cisco/run_tests.py' |
362 | --- quantum/plugins/cisco/run_tests.py 2011-08-08 07:23:44 +0000 |
363 | +++ quantum/plugins/cisco/run_tests.py 2011-08-16 06:17:23 +0000 |
364 | @@ -16,50 +16,34 @@ |
365 | # See the License for the specific language governing permissions and |
366 | # limitations under the License. |
367 | |
368 | -# Colorizer Code is borrowed from Twisted: |
369 | -# Copyright (c) 2001-2010 Twisted Matrix Laboratories. |
370 | -# |
371 | -# Permission is hereby granted, free of charge, to any person obtaining |
372 | -# a copy of this software and associated documentation files (the |
373 | -# "Software"), to deal in the Software without restriction, including |
374 | -# without limitation the rights to use, copy, modify, merge, publish, |
375 | -# distribute, sublicense, and/or sell copies of the Software, and to |
376 | -# permit persons to whom the Software is furnished to do so, subject to |
377 | -# the following conditions: |
378 | -# |
379 | -# The above copyright notice and this permission notice shall be |
380 | -# included in all copies or substantial portions of the Software. |
381 | -# |
382 | -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
383 | -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
384 | -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
385 | -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
386 | -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
387 | -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
388 | -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
389 | - |
390 | -"""Unittest runner for quantum |
391 | + |
392 | +"""Unittest runner for quantum OVS plugin |
393 | + |
394 | +This file should be run from the top dir in the quantum directory |
395 | |
396 | To run all test:: |
397 | - python run_tests.py |
398 | + python quantum/plugins/cisco/run_tests.py |
399 | |
400 | To run all unit tests:: |
401 | - python run_tests.py unit |
402 | + python quantum/plugins/cisco/run_tests.py quantum.plugins.cisco.tests.unit |
403 | |
404 | To run all functional tests:: |
405 | - python run_tests.py functional |
406 | + python quantum/plugins/openvswitch/run_tests.py functional |
407 | |
408 | To run a single unit test:: |
409 | - python run_tests.py unit.test_stores:TestSwiftBackend.test_get |
410 | + python quantum/plugins/openvswitch/run_tests.py \ |
411 | + quantum.plugins.cisco.tests.unit.test_stores:TestSwiftBackend.test_get |
412 | |
413 | To run a single functional test:: |
414 | - python run_tests.py functional.test_service:TestController.test_create |
415 | + python quantum/plugins/openvswitch/run_tests.py \ |
416 | + quantum.plugins.cisco.tests.functional.test_service \ |
417 | + :TestController.test_create |
418 | |
419 | To run a single unit test module:: |
420 | - python run_tests.py unit.test_stores |
421 | + python quantum/plugins/openvswitch/run_tests.py unit.test_stores |
422 | |
423 | To run a single functional test module:: |
424 | - python run_tests.py functional.test_stores |
425 | + python quantum/plugins/openvswitch/run_tests.py functional.test_stores |
426 | """ |
427 | |
428 | import gettext |
429 | @@ -69,233 +53,38 @@ |
430 | import sys |
431 | |
432 | from nose import config |
433 | -from nose import result |
434 | -from nose import core |
435 | - |
436 | - |
437 | -class _AnsiColorizer(object): |
438 | - """ |
439 | - A colorizer is an object that loosely wraps around a stream, allowing |
440 | - callers to write text to the stream in a particular color. |
441 | - |
442 | - Colorizer classes must implement C{supported()} and C{write(text, color)}. |
443 | - """ |
444 | - _colors = dict(black=30, red=31, green=32, yellow=33, |
445 | - blue=34, magenta=35, cyan=36, white=37) |
446 | - |
447 | - def __init__(self, stream): |
448 | - self.stream = stream |
449 | - |
450 | - def supported(cls, stream=sys.stdout): |
451 | - """ |
452 | - A class method that returns True if the current platform supports |
453 | - coloring terminal output using this method. Returns False otherwise. |
454 | - """ |
455 | - if not stream.isatty(): |
456 | - return False # auto color only on TTYs |
457 | - try: |
458 | - import curses |
459 | - except ImportError: |
460 | - return False |
461 | - else: |
462 | - try: |
463 | - try: |
464 | - return curses.tigetnum("colors") > 2 |
465 | - except curses.error: |
466 | - curses.setupterm() |
467 | - return curses.tigetnum("colors") > 2 |
468 | - except: |
469 | - raise |
470 | - # guess false in case of error |
471 | - return False |
472 | - supported = classmethod(supported) |
473 | - |
474 | - def write(self, text, color): |
475 | - """ |
476 | - Write the given text to the stream in the given color. |
477 | - |
478 | - @param text: Text to be written to the stream. |
479 | - |
480 | - @param color: A string label for a color. e.g. 'red', 'white'. |
481 | - """ |
482 | - color = self._colors[color] |
483 | - self.stream.write('\x1b[%s;1m%s\x1b[0m' % (color, text)) |
484 | - |
485 | - |
486 | -class _Win32Colorizer(object): |
487 | - """ |
488 | - See _AnsiColorizer docstring. |
489 | - """ |
490 | - def __init__(self, stream): |
491 | - from win32console import GetStdHandle, STD_OUT_HANDLE, \ |
492 | - FOREGROUND_RED, FOREGROUND_BLUE, FOREGROUND_GREEN, \ |
493 | - FOREGROUND_INTENSITY |
494 | - red, green, blue, bold = (FOREGROUND_RED, FOREGROUND_GREEN, |
495 | - FOREGROUND_BLUE, FOREGROUND_INTENSITY) |
496 | - self.stream = stream |
497 | - self.screenBuffer = GetStdHandle(STD_OUT_HANDLE) |
498 | - self._colors = { |
499 | - 'normal': red | green | blue, |
500 | - 'red': red | bold, |
501 | - 'green': green | bold, |
502 | - 'blue': blue | bold, |
503 | - 'yellow': red | green | bold, |
504 | - 'magenta': red | blue | bold, |
505 | - 'cyan': green | blue | bold, |
506 | - 'white': red | green | blue | bold} |
507 | - |
508 | - def supported(cls, stream=sys.stdout): |
509 | - try: |
510 | - import win32console |
511 | - screenBuffer = win32console.GetStdHandle( |
512 | - win32console.STD_OUT_HANDLE) |
513 | - except ImportError: |
514 | - return False |
515 | - import pywintypes |
516 | - try: |
517 | - screenBuffer.SetConsoleTextAttribute( |
518 | - win32console.FOREGROUND_RED | |
519 | - win32console.FOREGROUND_GREEN | |
520 | - win32console.FOREGROUND_BLUE) |
521 | - except pywintypes.error: |
522 | - return False |
523 | - else: |
524 | - return True |
525 | - supported = classmethod(supported) |
526 | - |
527 | - def write(self, text, color): |
528 | - color = self._colors[color] |
529 | - self.screenBuffer.SetConsoleTextAttribute(color) |
530 | - self.stream.write(text) |
531 | - self.screenBuffer.SetConsoleTextAttribute(self._colors['normal']) |
532 | - |
533 | - |
534 | -class _NullColorizer(object): |
535 | - """ |
536 | - See _AnsiColorizer docstring. |
537 | - """ |
538 | - def __init__(self, stream): |
539 | - self.stream = stream |
540 | - |
541 | - def supported(cls, stream=sys.stdout): |
542 | - return True |
543 | - supported = classmethod(supported) |
544 | - |
545 | - def write(self, text, color): |
546 | - self.stream.write(text) |
547 | - |
548 | - |
549 | -class QuantumTestResult(result.TextTestResult): |
550 | - def __init__(self, *args, **kw): |
551 | - result.TextTestResult.__init__(self, *args, **kw) |
552 | - self._last_case = None |
553 | - self.colorizer = None |
554 | - # NOTE(vish, tfukushima): reset stdout for the terminal check |
555 | - stdout = sys.__stdout__ |
556 | - for colorizer in [_Win32Colorizer, _AnsiColorizer, _NullColorizer]: |
557 | - if colorizer.supported(): |
558 | - self.colorizer = colorizer(self.stream) |
559 | - break |
560 | - sys.stdout = stdout |
561 | - |
562 | - def getDescription(self, test): |
563 | - return str(test) |
564 | - |
565 | - # NOTE(vish, tfukushima): copied from unittest with edit to add color |
566 | - def addSuccess(self, test): |
567 | - unittest.TestResult.addSuccess(self, test) |
568 | - if self.showAll: |
569 | - self.colorizer.write("OK", 'green') |
570 | - self.stream.writeln() |
571 | - elif self.dots: |
572 | - self.stream.write('.') |
573 | - self.stream.flush() |
574 | - |
575 | - # NOTE(vish, tfukushima): copied from unittest with edit to add color |
576 | - def addFailure(self, test, err): |
577 | - unittest.TestResult.addFailure(self, test, err) |
578 | - if self.showAll: |
579 | - self.colorizer.write("FAIL", 'red') |
580 | - self.stream.writeln() |
581 | - elif self.dots: |
582 | - self.stream.write('F') |
583 | - self.stream.flush() |
584 | - |
585 | - # NOTE(vish, tfukushima): copied from unittest with edit to add color |
586 | - def addError(self, test, err): |
587 | - """Overrides normal addError to add support for errorClasses. |
588 | - If the exception is a registered class, the error will be added |
589 | - to the list for that class, not errors. |
590 | - """ |
591 | - stream = getattr(self, 'stream', None) |
592 | - ec, ev, tb = err |
593 | - try: |
594 | - exc_info = self._exc_info_to_string(err, test) |
595 | - except TypeError: |
596 | - # This is for compatibility with Python 2.3. |
597 | - exc_info = self._exc_info_to_string(err) |
598 | - for cls, (storage, label, isfail) in self.errorClasses.items(): |
599 | - if result.isclass(ec) and issubclass(ec, cls): |
600 | - if isfail: |
601 | - test.passwd = False |
602 | - storage.append((test, exc_info)) |
603 | - # Might get patched into a streamless result |
604 | - if stream is not None: |
605 | - if self.showAll: |
606 | - message = [label] |
607 | - detail = result._exception_details(err[1]) |
608 | - if detail: |
609 | - message.append(detail) |
610 | - stream.writeln(": ".join(message)) |
611 | - elif self.dots: |
612 | - stream.write(label[:1]) |
613 | - return |
614 | - self.errors.append((test, exc_info)) |
615 | - test.passed = False |
616 | - if stream is not None: |
617 | - if self.showAll: |
618 | - self.colorizer.write("ERROR", 'red') |
619 | - self.stream.writeln() |
620 | - elif self.dots: |
621 | - stream.write('E') |
622 | - |
623 | - def startTest(self, test): |
624 | - unittest.TestResult.startTest(self, test) |
625 | - current_case = test.test.__class__.__name__ |
626 | - |
627 | - if self.showAll: |
628 | - if current_case != self._last_case: |
629 | - self.stream.writeln(current_case) |
630 | - self._last_case = current_case |
631 | - |
632 | - self.stream.write( |
633 | - ' %s' % str(test.test._testMethodName).ljust(60)) |
634 | - self.stream.flush() |
635 | - |
636 | - |
637 | -class QuantumTestRunner(core.TextTestRunner): |
638 | - def _makeResult(self): |
639 | - return QuantumTestResult(self.stream, |
640 | - self.descriptions, |
641 | - self.verbosity, |
642 | - self.config) |
643 | - |
644 | + |
645 | +sys.path.append(os.getcwd()) |
646 | + |
647 | +from quantum.common.test_lib import run_tests, test_config |
648 | +#from quantum.plugins.openvswitch.tests.test_vlan_map import VlanMapTest |
649 | |
650 | if __name__ == '__main__': |
651 | - # Set up test logger. |
652 | - logger = logging.getLogger() |
653 | - hdlr = logging.StreamHandler() |
654 | - formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') |
655 | - hdlr.setFormatter(formatter) |
656 | - logger.addHandler(hdlr) |
657 | - logger.setLevel(logging.DEBUG) |
658 | + exit_status = False |
659 | + |
660 | + # if a single test case was specified, |
661 | + # we should only invoked the tests once |
662 | + invoke_once = len(sys.argv) > 1 |
663 | + |
664 | + cwd = os.getcwd() |
665 | |
666 | working_dir = os.path.abspath("tests") |
667 | c = config.Config(stream=sys.stdout, |
668 | env=os.environ, |
669 | verbosity=3, |
670 | workingDir=working_dir) |
671 | - runner = QuantumTestRunner(stream=c.stream, |
672 | - verbosity=c.verbosity, |
673 | - config=c) |
674 | - sys.exit(not core.run(config=c, testRunner=runner)) |
675 | + exit_status = run_tests(c) |
676 | + |
677 | + if invoke_once: |
678 | + sys.exit(0) |
679 | + |
680 | + os.chdir(cwd) |
681 | + |
682 | + working_dir = os.path.abspath("quantum/plugins/cisco/tests") |
683 | + c = config.Config(stream=sys.stdout, |
684 | + env=os.environ, |
685 | + verbosity=3, |
686 | + workingDir=working_dir) |
687 | + exit_status = exit_status or run_tests(c) |
688 | + |
689 | + sys.exit(exit_status) |
690 | |
691 | === modified file 'quantum/plugins/cisco/tests/unit/test_l2networkApi.py' |
692 | --- quantum/plugins/cisco/tests/unit/test_l2networkApi.py 2011-08-14 19:33:44 +0000 |
693 | +++ quantum/plugins/cisco/tests/unit/test_l2networkApi.py 2011-08-16 06:17:23 +0000 |
694 | @@ -19,13 +19,13 @@ |
695 | |
696 | import logging |
697 | import unittest |
698 | -import time |
699 | +#import time |
700 | from quantum.common import exceptions as exc |
701 | from quantum.plugins.cisco.common import cisco_constants as const |
702 | from quantum.plugins.cisco.common import cisco_exceptions as cexc |
703 | from quantum.plugins.cisco import l2network_plugin |
704 | from quantum.plugins.cisco import l2network_plugin_configuration as conf |
705 | -from quantum.plugins.cisco.common import cisco_utils as utils |
706 | +#from quantum.plugins.cisco.common import cisco_utils as utils |
707 | from quantum.plugins.cisco.db import api as db |
708 | from quantum.plugins.cisco.db import l2network_db as cdb |
709 | |
710 | @@ -675,13 +675,16 @@ |
711 | port_dict = self._l2network_plugin.create_port( |
712 | tenant_id, new_net_dict[const.NET_ID], 'const.PORT_UP') |
713 | self._l2network_plugin.associate_portprofile( |
714 | - tenant_id, new_net_dict[const.NET_ID], port_dict[const.PORT_ID], port_profile_id) |
715 | + tenant_id, new_net_dict[const.NET_ID], |
716 | + port_dict[const.PORT_ID], port_profile_id) |
717 | self.assertRaises(cexc.PortProfileInvalidDelete, |
718 | self._l2network_plugin.delete_portprofile, |
719 | tenant_id, port_profile_id) |
720 | - self.tearDownAssociatePortProfile(tenant_id, new_net_dict[const.NET_ID], |
721 | - port_dict[const.PORT_ID], port_profile_id) |
722 | - self.tearDownNetworkPort(tenant_id, new_net_dict[const.NET_ID], port_dict[const.PORT_ID]) |
723 | + self.tearDownAssociatePortProfile( |
724 | + tenant_id, new_net_dict[const.NET_ID], |
725 | + port_dict[const.PORT_ID], port_profile_id) |
726 | + self.tearDownNetworkPort(tenant_id, new_net_dict[const.NET_ID], |
727 | + port_dict[const.PORT_ID]) |
728 | LOG.debug("test_delete_portprofileAssociated - END") |
729 | |
730 | def test_list_portprofile(self, tenant_id='test_tenant'): |
731 | @@ -793,8 +796,7 @@ |
732 | tenant_id, profile_id, new_profile_name) |
733 | LOG.debug("test_rename_portprofileDNE - END") |
734 | |
735 | - def test_associate_portprofile(self, tenant_id='test_tenant', |
736 | - net_id='0005', port_id='p00005'): |
737 | + def test_associate_portprofile(self, tenant_id='test_tenant'): |
738 | """ |
739 | Tests association of a port-profile |
740 | """ |
741 | @@ -809,18 +811,18 @@ |
742 | tenant_id, self.profile_name, self.qos) |
743 | port_profile_id = port_profile_dict['profile-id'] |
744 | self._l2network_plugin.associate_portprofile( |
745 | - tenant_id, net_id, port_dict[const.PORT_ID], |
746 | - port_profile_id) |
747 | + tenant_id, new_net_dict[const.NET_ID], |
748 | + port_dict[const.PORT_ID], port_profile_id) |
749 | port_profile_associate = cdb.get_pp_binding(tenant_id, port_profile_id) |
750 | self.assertEqual(port_profile_associate[const.PORTID], |
751 | port_dict[const.PORT_ID]) |
752 | #self.assertEqual( |
753 | # self._l2network_plugin._portprofiles[port_profile_id] |
754 | # [const.PROFILE_ASSOCIATIONS][0], port_id) |
755 | - self.tearDownAssociatePortProfile(tenant_id, net_id, |
756 | - port_dict[const.PORT_ID], |
757 | - port_profile_id) |
758 | - self.tearDownNetworkPortInterface( |
759 | + self.tearDownAssociatePortProfile( |
760 | + tenant_id, new_net_dict[const.NET_ID], |
761 | + port_dict[const.PORT_ID], port_profile_id) |
762 | + self.tearDownNetworkPort( |
763 | tenant_id, new_net_dict[const.NET_ID], |
764 | port_dict[const.PORT_ID]) |
765 | LOG.debug("test_associate_portprofile - END") |
766 | @@ -839,7 +841,7 @@ |
767 | LOG.debug("test_associate_portprofileDNE - END") |
768 | |
769 | def test_disassociate_portprofile(self, tenant_id='test_tenant', |
770 | - net_id='0005', port_id='p00005'): |
771 | + ): |
772 | """ |
773 | Tests disassociation of a port-profile |
774 | """ |
775 | @@ -864,7 +866,7 @@ |
776 | # self.assertEqual(self._l2network_plugin._portprofiles |
777 | # [port_profile_id][const.PROFILE_ASSOCIATIONS], []) |
778 | self.tearDownPortProfile(tenant_id, port_profile_id) |
779 | - self.tearDownNetworkPortInterface( |
780 | + self.tearDownNetworkPort( |
781 | tenant_id, new_net_dict[const.NET_ID], |
782 | port_dict[const.PORT_ID]) |
783 | LOG.debug("test_disassociate_portprofile - END") |
784 | @@ -988,7 +990,8 @@ |
785 | |
786 | def _make_portprofile_dict(self, tenant_id, profile_id, profile_name, |
787 | qos): |
788 | - profile_associations = self._make_portprofile_assc_list(tenant_id, profile_id) |
789 | + profile_associations = self._make_portprofile_assc_list( |
790 | + tenant_id, profile_id) |
791 | res = {const.PROFILE_ID: str(profile_id), |
792 | const.PROFILE_NAME: profile_name, |
793 | const.PROFILE_ASSOCIATIONS: profile_associations, |
794 | |
795 | === modified file 'quantum/plugins/cisco/tests/unit/test_nexus_plugin.py' |
796 | --- quantum/plugins/cisco/tests/unit/test_nexus_plugin.py 2011-08-08 07:23:44 +0000 |
797 | +++ quantum/plugins/cisco/tests/unit/test_nexus_plugin.py 2011-08-16 06:17:23 +0000 |
798 | @@ -259,11 +259,10 @@ |
799 | self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID]) |
800 | LOG.debug("test_get_vlan_id_for_network - END") |
801 | |
802 | - """ |
803 | + def tearDownNetwork(self, tenant_id, network_dict_id): |
804 | + """ |
805 | Clean up functions after the tests |
806 | - """ |
807 | - |
808 | - def tearDownNetwork(self, tenant_id, network_dict_id): |
809 | + """ |
810 | self._cisco_nexus_plugin.delete_network(tenant_id, network_dict_id) |
811 | |
812 | # def test_create_network(self): |
813 | |
814 | === modified file 'quantum/plugins/cisco/tests/unit/test_ucs_driver.py' |
815 | --- quantum/plugins/cisco/tests/unit/test_ucs_driver.py 2011-08-08 07:23:44 +0000 |
816 | +++ quantum/plugins/cisco/tests/unit/test_ucs_driver.py 2011-08-16 06:17:23 +0000 |
817 | @@ -24,13 +24,13 @@ |
818 | |
819 | LOG = logging.getLogger('quantum.tests.test_ucs_driver') |
820 | |
821 | -create_vlan_output = "<configConfMos cookie=\"cookie_placeholder\" "\ |
822 | +CREATE_VLAN_OUTPUT = "<configConfMos cookie=\"cookie_placeholder\" "\ |
823 | "inHierarchical=\"true\"> <inConfigs><pair key=\"fabric/lan/net-New Vlan\"> "\ |
824 | "<fabricVlan defaultNet=\"no\" dn=\"fabric/lan/net-New Vlan\" id=\"200\" "\ |
825 | "name=\"New Vlan\" status=\"created\"></fabricVlan> </pair> </inConfigs> "\ |
826 | "</configConfMos>" |
827 | |
828 | -create_profile_output = "<configConfMos cookie=\"cookie_placeholder\" "\ |
829 | +CREATE_PROFILE_OUTPUT = "<configConfMos cookie=\"cookie_placeholder\" "\ |
830 | "inHierarchical=\"true\"> <inConfigs><pair key=\"fabric/lan/profiles/vnic-"\ |
831 | "New Profile\"> <vnicProfile descr=\"Profile created by Cisco OpenStack "\ |
832 | "Quantum Plugin\" dn=\"fabric/lan/profiles/vnic-New Profile\" maxPorts="\ |
833 | @@ -39,7 +39,7 @@ |
834 | "name=\"New Vlan\" rn=\"if-New Vlan\" > </vnicEtherIf> </vnicProfile> "\ |
835 | "</pair> </inConfigs> </configConfMos>" |
836 | |
837 | -change_vlan_output = "<configConfMos cookie=\"cookie_placeholder\" "\ |
838 | +CHANGE_VLAN_OUTPUT = "<configConfMos cookie=\"cookie_placeholder\" "\ |
839 | "inHierarchical=\"true\"> <inConfigs><pair key=\""\ |
840 | "fabric/lan/profiles/vnic-New Profile\"> <vnicProfile descr=\"Profile "\ |
841 | "created by Cisco OpenStack Quantum Plugin\" "\ |
842 | @@ -50,18 +50,18 @@ |
843 | "<vnicEtherIf defaultNet=\"yes\" name=\"New Vlan\" rn=\"if-New Vlan\" > "\ |
844 | "</vnicEtherIf> </vnicProfile> </pair></inConfigs> </configConfMos>" |
845 | |
846 | -delete_vlan_output = "<configConfMos cookie=\"cookie_placeholder\" "\ |
847 | +DELETE_VLAN_OUTPUT = "<configConfMos cookie=\"cookie_placeholder\" "\ |
848 | "inHierarchical=\"true\"> <inConfigs><pair key=\"fabric/lan/net-New Vlan\"> "\ |
849 | "<fabricVlan dn=\"fabric/lan/net-New Vlan\" status=\"deleted\"> "\ |
850 | "</fabricVlan> </pair> </inConfigs></configConfMos>" |
851 | |
852 | -delete_profile_output = "<configConfMos cookie=\"cookie_placeholder\" "\ |
853 | +DELETE_PROFILE_OUTPUT = "<configConfMos cookie=\"cookie_placeholder\" "\ |
854 | "inHierarchical=\"false\"> <inConfigs><pair key=\""\ |
855 | "fabric/lan/profiles/vnic-New Profile\"> <vnicProfile "\ |
856 | "dn=\"fabric/lan/profiles/vnic-New Profile\" status=\"deleted\"> "\ |
857 | "</vnicProfile></pair> </inConfigs> </configConfMos>" |
858 | |
859 | -associate_profile_output = "<configConfMos cookie=\"cookie_placeholder\" "\ |
860 | +ASSOCIATE_PROFILE_OUTPUT = "<configConfMos cookie=\"cookie_placeholder\" "\ |
861 | "inHierarchical=\"true\"> <inConfigs> <pair key="\ |
862 | "\"fabric/lan/profiles/vnic-New Profile/cl-New Profile Client\">"\ |
863 | " <vmVnicProfCl dcName=\".*\" descr=\"\" dn=\"fabric/lan/profiles/vnic-"\ |
864 | @@ -73,83 +73,86 @@ |
865 | class TestUCSDriver(unittest.TestCase): |
866 | |
867 | def setUp(self): |
868 | - self._ucsmDriver = cisco_ucs_network_driver.CiscoUCSMDriver() |
869 | + self.ucsm_driver = cisco_ucs_network_driver.CiscoUCSMDriver() |
870 | self.vlan_name = 'New Vlan' |
871 | self.vlan_id = '200' |
872 | self.profile_name = 'New Profile' |
873 | self.old_vlan_name = 'Old Vlan' |
874 | self.profile_client_name = 'New Profile Client' |
875 | |
876 | - def test_create_vlan_post_data(self, expected_output=create_vlan_output): |
877 | + def test_create_vlan_post_data(self, expected_output=CREATE_VLAN_OUTPUT): |
878 | """ |
879 | Tests creation of vlan post Data |
880 | """ |
881 | |
882 | LOG.debug("test_create_vlan") |
883 | - vlan_details = self._ucsmDriver._create_vlan_post_data( |
884 | + vlan_details = self.ucsm_driver._create_vlan_post_data( |
885 | self.vlan_name, self.vlan_id) |
886 | self.assertEqual(vlan_details, expected_output) |
887 | LOG.debug("test_create_vlan - END") |
888 | |
889 | def test_create_profile_post_data( |
890 | - self, expected_output=create_profile_output): |
891 | + self, expected_output=CREATE_PROFILE_OUTPUT): |
892 | """ |
893 | Tests creation of profile post Data |
894 | """ |
895 | |
896 | LOG.debug("test_create_profile_post_data - START") |
897 | - profile_details = self._ucsmDriver._create_profile_post_data( |
898 | + profile_details = self.ucsm_driver._create_profile_post_data( |
899 | self.profile_name, self.vlan_name) |
900 | self.assertEqual(profile_details, expected_output) |
901 | LOG.debug("test_create_profile_post - END") |
902 | |
903 | - def test_change_vlan_in_profile_post_data( |
904 | - self, expected_output=change_vlan_output): |
905 | + def test_change_vlan_profile_data( |
906 | + self, expected_output=CHANGE_VLAN_OUTPUT): |
907 | """ |
908 | Tests creation of change vlan in profile post Data |
909 | """ |
910 | |
911 | LOG.debug("test_create_profile_post_data - START") |
912 | - profile_details = self._ucsmDriver._change_vlan_in_profile_post_data( |
913 | + profile_details = self.ucsm_driver._change_vlan_in_profile_post_data( |
914 | self.profile_name, self.old_vlan_name, self.vlan_name) |
915 | self.assertEqual(profile_details, expected_output) |
916 | LOG.debug("test_create_profile_post - END") |
917 | |
918 | - def test_delete_vlan_post_data(self, expected_output=delete_vlan_output): |
919 | - LOG.debug("test_create_profile_post_data - START") |
920 | + def test_delete_vlan_post_data(self, expected_output=DELETE_VLAN_OUTPUT): |
921 | """ |
922 | Tests deletion of vlan post Data |
923 | """ |
924 | |
925 | - vlan_details = self._ucsmDriver._create_vlan_post_data( |
926 | + LOG.debug("test_create_profile_post_data - START") |
927 | + |
928 | + self.ucsm_driver._create_vlan_post_data( |
929 | self.vlan_name, self.vlan_id) |
930 | - vlan_delete_details = self._ucsmDriver._delete_vlan_post_data( |
931 | + vlan_delete_details = self.ucsm_driver._delete_vlan_post_data( |
932 | self.vlan_name) |
933 | self.assertEqual(vlan_delete_details, expected_output) |
934 | LOG.debug("test_create_profile_post - END") |
935 | |
936 | def test_delete_profile_post_data( |
937 | - self, expected_output=delete_profile_output): |
938 | + self, expected_output=DELETE_PROFILE_OUTPUT): |
939 | """ |
940 | Tests deletion of profile post Data |
941 | """ |
942 | |
943 | LOG.debug("test_create_profile_post_data - START") |
944 | - profile_details = self._ucsmDriver._create_profile_post_data( |
945 | + #profile_details = self.ucsm_driver._create_profile_post_data( |
946 | + # self.profile_name, self.vlan_name) |
947 | + self.ucsm_driver._create_profile_post_data( |
948 | self.profile_name, self.vlan_name) |
949 | - profile_delete_details = self._ucsmDriver._delete_profile_post_data( |
950 | + profile_delete_details = self.ucsm_driver._delete_profile_post_data( |
951 | self.profile_name) |
952 | self.assertEqual(profile_delete_details, expected_output) |
953 | LOG.debug("test_create_profile_post - END") |
954 | |
955 | - def test_create_profile_client_post_data( |
956 | - self, expected_output=associate_profile_output): |
957 | + def test_create_profile_client_data( |
958 | + self, expected_output=ASSOCIATE_PROFILE_OUTPUT): |
959 | """ |
960 | Tests creation of profile client post Data |
961 | """ |
962 | |
963 | - LOG.debug("test_create_profile_client_post_data - START") |
964 | - profile_details = self._ucsmDriver._create_profile_client_post_data( |
965 | + LOG.debug("test_create_profile_client_data - START") |
966 | + profile_details = self.ucsm_driver._create_profile_client_post_data( |
967 | self.profile_name, self.profile_client_name) |
968 | self.assertEqual(profile_details, expected_output) |
969 | LOG.debug("test_create_profile_post - END") |
970 | @@ -160,6 +163,6 @@ |
971 | """ |
972 | |
973 | LOG.debug("test_get_next_dynamic_nic - START") |
974 | - dynamic_nic_id = self._ucsmDriver._get_next_dynamic_nic() |
975 | + dynamic_nic_id = self.ucsm_driver._get_next_dynamic_nic() |
976 | self.assertTrue(len(dynamic_nic_id) > 0) |
977 | LOG.debug("test_get_next_dynamic_nic - END") |
978 | |
979 | === modified file 'quantum/plugins/cisco/tests/unit/test_ucs_plugin.py' |
980 | --- quantum/plugins/cisco/tests/unit/test_ucs_plugin.py 2011-08-08 07:23:44 +0000 |
981 | +++ quantum/plugins/cisco/tests/unit/test_ucs_plugin.py 2011-08-16 06:17:23 +0000 |
982 | @@ -32,7 +32,7 @@ |
983 | |
984 | self.tenant_id = "test_tenant_cisco12" |
985 | self.net_name = "test_network_cisco12" |
986 | - self.net_id = 000007 |
987 | + self.net_id = 000011 |
988 | self.vlan_name = "q-" + str(self.net_id) + "vlan" |
989 | self.vlan_id = 266 |
990 | self.port_id = "4" |
991 | @@ -238,12 +238,12 @@ |
992 | self.assertEqual(new_port_profile[const.PROFILE_NAME], profile_name) |
993 | self.tearDownNetworkPort(self.tenant_id, self.net_id, self.port_id) |
994 | |
995 | - def _test_get_port_details_state_down(self, port_state): |
996 | + def _test_show_port_state_down(self, port_state): |
997 | """ |
998 | Tests whether user is able to retrieve a remote interface |
999 | that is attached to this particular port when port state is down. |
1000 | """ |
1001 | - LOG.debug("UCSVICTestPlugin:_test_get_port_details_state_down()" + |
1002 | + LOG.debug("UCSVICTestPlugin:_test_show_port_state_down()" + |
1003 | "called\n") |
1004 | self._cisco_ucs_plugin.create_network(self.tenant_id, self.net_name, |
1005 | self.net_id, self.vlan_name, |
1006 | @@ -268,8 +268,8 @@ |
1007 | def test_get_port_details_state_up(self): |
1008 | self._test_get_port_details_state_up(const.PORT_UP) |
1009 | |
1010 | - def test_get_port_details_state_down(self): |
1011 | - self._test_get_port_details_state_down(const.PORT_DOWN) |
1012 | + def test_show_port_state_down(self): |
1013 | + self._test_show_port_state_down(const.PORT_DOWN) |
1014 | |
1015 | def test_create_port_profile(self): |
1016 | LOG.debug("UCSVICTestPlugin:test_create_port_profile() called\n") |
1017 | @@ -313,7 +313,7 @@ |
1018 | self.tenant_id, self.net_id, self.port_id) |
1019 | self.assertEqual(port[const.ATTACHMENT], remote_interface_id) |
1020 | port_profile = port[const.PORT_PROFILE] |
1021 | - profile_name = port_profile[const.PROFILE_NAME] |
1022 | + #profile_name = port_profile[const.PROFILE_NAME] |
1023 | new_vlan_name = self._cisco_ucs_plugin._get_vlan_name_for_network( |
1024 | self.tenant_id, self.net_id) |
1025 | new_vlan_id = self._cisco_ucs_plugin._get_vlan_id_for_network( |
1026 | @@ -346,7 +346,7 @@ |
1027 | self.tenant_id, self.net_id, self.port_id) |
1028 | self.assertEqual(port[const.ATTACHMENT], None) |
1029 | port_profile = port[const.PORT_PROFILE] |
1030 | - profile_name = port_profile[const.PROFILE_NAME] |
1031 | + #profile_name = port_profile[const.PROFILE_NAME] |
1032 | self.assertEqual(port_profile[const.PROFILE_VLAN_NAME], |
1033 | conf.DEFAULT_VLAN_NAME) |
1034 | self.assertEqual(port_profile[const.PROFILE_VLAN_ID], |
1035 | @@ -394,12 +394,12 @@ |
1036 | def test_get_network_NetworkNotFound(self): |
1037 | self.assertRaises(exc.NetworkNotFound, |
1038 | self._cisco_ucs_plugin._get_network, |
1039 | - *(self.tenant_id, self.net_id)) |
1040 | + self.tenant_id, self.net_id) |
1041 | |
1042 | def test_delete_network_NetworkNotFound(self): |
1043 | self.assertRaises(exc.NetworkNotFound, |
1044 | self._cisco_ucs_plugin.delete_network, |
1045 | - *(self.tenant_id, self.net_id)) |
1046 | + self.tenant_id, self.net_id) |
1047 | |
1048 | def test_delete_port_PortInUse(self): |
1049 | self._test_delete_port_PortInUse("4") |
1050 | @@ -414,7 +414,7 @@ |
1051 | self.port_id, |
1052 | remote_interface_id) |
1053 | self.assertRaises(exc.PortInUse, self._cisco_ucs_plugin.delete_port, |
1054 | - *(self.tenant_id, self.net_id, self.port_id)) |
1055 | + self.tenant_id, self.net_id, self.port_id) |
1056 | self.tearDownNetworkPortInterface(self.tenant_id, self.net_id, |
1057 | self.port_id) |
1058 | |
1059 | @@ -423,7 +423,7 @@ |
1060 | self.net_id, self.vlan_name, |
1061 | self.vlan_id) |
1062 | self.assertRaises(exc.PortNotFound, self._cisco_ucs_plugin.delete_port, |
1063 | - *(self.tenant_id, self.net_id, self.port_id)) |
1064 | + self.tenant_id, self.net_id, self.port_id) |
1065 | self.tearDownNetwork(self.tenant_id, self.net_id) |
1066 | |
1067 | def test_plug_interface_PortInUse(self): |
1068 | @@ -441,16 +441,16 @@ |
1069 | self.port_id, |
1070 | remote_interface_id1) |
1071 | self.assertRaises(exc.PortInUse, self._cisco_ucs_plugin.plug_interface, |
1072 | - *(self.tenant_id, self.net_id, self.port_id, |
1073 | - remote_interface_id2)) |
1074 | + self.tenant_id, self.net_id, self.port_id, |
1075 | + remote_interface_id2) |
1076 | self.tearDownNetworkPortInterface(self.tenant_id, self.net_id, |
1077 | self.port_id) |
1078 | |
1079 | - def test_validate_attachment_AlreadyAttached(self): |
1080 | + def test_attachment_exists(self): |
1081 | LOG.debug("UCSVICTestPlugin:testValidateAttachmentAlreadyAttached") |
1082 | - self._test_validate_attachment_AlreadyAttached("4") |
1083 | + self._test_attachment_exists("4") |
1084 | |
1085 | - def _test_validate_attachment_AlreadyAttached(self, remote_interface_id): |
1086 | + def _test_attachment_exists(self, remote_interface_id): |
1087 | LOG.debug("UCSVICTestPlugin:_test_validate_attachmentAlreadyAttached") |
1088 | self._cisco_ucs_plugin.create_network(self.tenant_id, self.net_name, |
1089 | self.net_id, self.vlan_name, |
1090 | @@ -461,8 +461,8 @@ |
1091 | self.port_id, |
1092 | remote_interface_id) |
1093 | self.assertRaises( |
1094 | - exc.AlreadyAttached, self._cisco_ucs_plugin._validate_attachment, |
1095 | - *(self.tenant_id, self.net_id, self.port_id, remote_interface_id)) |
1096 | + exc.PortInUse, self._cisco_ucs_plugin._validate_attachment, |
1097 | + self.tenant_id, self.net_id, self.port_id, remote_interface_id) |
1098 | self.tearDownNetworkPortInterface(self.tenant_id, self.net_id, |
1099 | self.port_id) |
1100 | |
1101 | |
1102 | === modified file 'run_tests.py' |
1103 | --- run_tests.py 2011-07-29 23:39:45 +0000 |
1104 | +++ run_tests.py 2011-08-16 06:17:23 +0000 |
1105 | @@ -16,27 +16,6 @@ |
1106 | # See the License for the specific language governing permissions and |
1107 | # limitations under the License. |
1108 | |
1109 | -# Colorizer Code is borrowed from Twisted: |
1110 | -# Copyright (c) 2001-2010 Twisted Matrix Laboratories. |
1111 | -# |
1112 | -# Permission is hereby granted, free of charge, to any person obtaining |
1113 | -# a copy of this software and associated documentation files (the |
1114 | -# "Software"), to deal in the Software without restriction, including |
1115 | -# without limitation the rights to use, copy, modify, merge, publish, |
1116 | -# distribute, sublicense, and/or sell copies of the Software, and to |
1117 | -# permit persons to whom the Software is furnished to do so, subject to |
1118 | -# the following conditions: |
1119 | -# |
1120 | -# The above copyright notice and this permission notice shall be |
1121 | -# included in all copies or substantial portions of the Software. |
1122 | -# |
1123 | -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
1124 | -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
1125 | -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
1126 | -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
1127 | -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
1128 | -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
1129 | -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
1130 | |
1131 | """Unittest runner for quantum |
1132 | |
1133 | @@ -63,239 +42,18 @@ |
1134 | """ |
1135 | |
1136 | import gettext |
1137 | -import logging |
1138 | import os |
1139 | import unittest |
1140 | import sys |
1141 | |
1142 | +from quantum.common.test_lib import run_tests |
1143 | from nose import config |
1144 | -from nose import result |
1145 | -from nose import core |
1146 | - |
1147 | - |
1148 | -class _AnsiColorizer(object): |
1149 | - """ |
1150 | - A colorizer is an object that loosely wraps around a stream, allowing |
1151 | - callers to write text to the stream in a particular color. |
1152 | - |
1153 | - Colorizer classes must implement C{supported()} and C{write(text, color)}. |
1154 | - """ |
1155 | - _colors = dict(black=30, red=31, green=32, yellow=33, |
1156 | - blue=34, magenta=35, cyan=36, white=37) |
1157 | - |
1158 | - def __init__(self, stream): |
1159 | - self.stream = stream |
1160 | - |
1161 | - def supported(cls, stream=sys.stdout): |
1162 | - """ |
1163 | - A class method that returns True if the current platform supports |
1164 | - coloring terminal output using this method. Returns False otherwise. |
1165 | - """ |
1166 | - if not stream.isatty(): |
1167 | - return False # auto color only on TTYs |
1168 | - try: |
1169 | - import curses |
1170 | - except ImportError: |
1171 | - return False |
1172 | - else: |
1173 | - try: |
1174 | - try: |
1175 | - return curses.tigetnum("colors") > 2 |
1176 | - except curses.error: |
1177 | - curses.setupterm() |
1178 | - return curses.tigetnum("colors") > 2 |
1179 | - except: |
1180 | - raise |
1181 | - # guess false in case of error |
1182 | - return False |
1183 | - supported = classmethod(supported) |
1184 | - |
1185 | - def write(self, text, color): |
1186 | - """ |
1187 | - Write the given text to the stream in the given color. |
1188 | - |
1189 | - @param text: Text to be written to the stream. |
1190 | - |
1191 | - @param color: A string label for a color. e.g. 'red', 'white'. |
1192 | - """ |
1193 | - color = self._colors[color] |
1194 | - self.stream.write('\x1b[%s;1m%s\x1b[0m' % (color, text)) |
1195 | - |
1196 | - |
1197 | -class _Win32Colorizer(object): |
1198 | - """ |
1199 | - See _AnsiColorizer docstring. |
1200 | - """ |
1201 | - def __init__(self, stream): |
1202 | - from win32console import GetStdHandle, STD_OUT_HANDLE, \ |
1203 | - FOREGROUND_RED, FOREGROUND_BLUE, FOREGROUND_GREEN, \ |
1204 | - FOREGROUND_INTENSITY |
1205 | - red, green, blue, bold = (FOREGROUND_RED, FOREGROUND_GREEN, |
1206 | - FOREGROUND_BLUE, FOREGROUND_INTENSITY) |
1207 | - self.stream = stream |
1208 | - self.screenBuffer = GetStdHandle(STD_OUT_HANDLE) |
1209 | - self._colors = { |
1210 | - 'normal': red | green | blue, |
1211 | - 'red': red | bold, |
1212 | - 'green': green | bold, |
1213 | - 'blue': blue | bold, |
1214 | - 'yellow': red | green | bold, |
1215 | - 'magenta': red | blue | bold, |
1216 | - 'cyan': green | blue | bold, |
1217 | - 'white': red | green | blue | bold} |
1218 | - |
1219 | - def supported(cls, stream=sys.stdout): |
1220 | - try: |
1221 | - import win32console |
1222 | - screenBuffer = win32console.GetStdHandle( |
1223 | - win32console.STD_OUT_HANDLE) |
1224 | - except ImportError: |
1225 | - return False |
1226 | - import pywintypes |
1227 | - try: |
1228 | - screenBuffer.SetConsoleTextAttribute( |
1229 | - win32console.FOREGROUND_RED | |
1230 | - win32console.FOREGROUND_GREEN | |
1231 | - win32console.FOREGROUND_BLUE) |
1232 | - except pywintypes.error: |
1233 | - return False |
1234 | - else: |
1235 | - return True |
1236 | - supported = classmethod(supported) |
1237 | - |
1238 | - def write(self, text, color): |
1239 | - color = self._colors[color] |
1240 | - self.screenBuffer.SetConsoleTextAttribute(color) |
1241 | - self.stream.write(text) |
1242 | - self.screenBuffer.SetConsoleTextAttribute(self._colors['normal']) |
1243 | - |
1244 | - |
1245 | -class _NullColorizer(object): |
1246 | - """ |
1247 | - See _AnsiColorizer docstring. |
1248 | - """ |
1249 | - def __init__(self, stream): |
1250 | - self.stream = stream |
1251 | - |
1252 | - def supported(cls, stream=sys.stdout): |
1253 | - return True |
1254 | - supported = classmethod(supported) |
1255 | - |
1256 | - def write(self, text, color): |
1257 | - self.stream.write(text) |
1258 | - |
1259 | - |
1260 | -class QuantumTestResult(result.TextTestResult): |
1261 | - def __init__(self, *args, **kw): |
1262 | - result.TextTestResult.__init__(self, *args, **kw) |
1263 | - self._last_case = None |
1264 | - self.colorizer = None |
1265 | - # NOTE(vish, tfukushima): reset stdout for the terminal check |
1266 | - stdout = sys.__stdout__ |
1267 | - for colorizer in [_Win32Colorizer, _AnsiColorizer, _NullColorizer]: |
1268 | - if colorizer.supported(): |
1269 | - self.colorizer = colorizer(self.stream) |
1270 | - break |
1271 | - sys.stdout = stdout |
1272 | - |
1273 | - def getDescription(self, test): |
1274 | - return str(test) |
1275 | - |
1276 | - # NOTE(vish, tfukushima): copied from unittest with edit to add color |
1277 | - def addSuccess(self, test): |
1278 | - unittest.TestResult.addSuccess(self, test) |
1279 | - if self.showAll: |
1280 | - self.colorizer.write("OK", 'green') |
1281 | - self.stream.writeln() |
1282 | - elif self.dots: |
1283 | - self.stream.write('.') |
1284 | - self.stream.flush() |
1285 | - |
1286 | - # NOTE(vish, tfukushima): copied from unittest with edit to add color |
1287 | - def addFailure(self, test, err): |
1288 | - unittest.TestResult.addFailure(self, test, err) |
1289 | - if self.showAll: |
1290 | - self.colorizer.write("FAIL", 'red') |
1291 | - self.stream.writeln() |
1292 | - elif self.dots: |
1293 | - self.stream.write('F') |
1294 | - self.stream.flush() |
1295 | - |
1296 | - # NOTE(vish, tfukushima): copied from unittest with edit to add color |
1297 | - def addError(self, test, err): |
1298 | - """Overrides normal addError to add support for errorClasses. |
1299 | - If the exception is a registered class, the error will be added |
1300 | - to the list for that class, not errors. |
1301 | - """ |
1302 | - stream = getattr(self, 'stream', None) |
1303 | - ec, ev, tb = err |
1304 | - try: |
1305 | - exc_info = self._exc_info_to_string(err, test) |
1306 | - except TypeError: |
1307 | - # This is for compatibility with Python 2.3. |
1308 | - exc_info = self._exc_info_to_string(err) |
1309 | - for cls, (storage, label, isfail) in self.errorClasses.items(): |
1310 | - if result.isclass(ec) and issubclass(ec, cls): |
1311 | - if isfail: |
1312 | - test.passwd = False |
1313 | - storage.append((test, exc_info)) |
1314 | - # Might get patched into a streamless result |
1315 | - if stream is not None: |
1316 | - if self.showAll: |
1317 | - message = [label] |
1318 | - detail = result._exception_details(err[1]) |
1319 | - if detail: |
1320 | - message.append(detail) |
1321 | - stream.writeln(": ".join(message)) |
1322 | - elif self.dots: |
1323 | - stream.write(label[:1]) |
1324 | - return |
1325 | - self.errors.append((test, exc_info)) |
1326 | - test.passed = False |
1327 | - if stream is not None: |
1328 | - if self.showAll: |
1329 | - self.colorizer.write("ERROR", 'red') |
1330 | - self.stream.writeln() |
1331 | - elif self.dots: |
1332 | - stream.write('E') |
1333 | - |
1334 | - def startTest(self, test): |
1335 | - unittest.TestResult.startTest(self, test) |
1336 | - current_case = test.test.__class__.__name__ |
1337 | - |
1338 | - if self.showAll: |
1339 | - if current_case != self._last_case: |
1340 | - self.stream.writeln(current_case) |
1341 | - self._last_case = current_case |
1342 | - |
1343 | - self.stream.write( |
1344 | - ' %s' % str(test.test._testMethodName).ljust(60)) |
1345 | - self.stream.flush() |
1346 | - |
1347 | - |
1348 | -class QuantumTestRunner(core.TextTestRunner): |
1349 | - def _makeResult(self): |
1350 | - return QuantumTestResult(self.stream, |
1351 | - self.descriptions, |
1352 | - self.verbosity, |
1353 | - self.config) |
1354 | |
1355 | |
1356 | if __name__ == '__main__': |
1357 | - # Set up test logger. |
1358 | - logger = logging.getLogger() |
1359 | - hdlr = logging.StreamHandler() |
1360 | - formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') |
1361 | - hdlr.setFormatter(formatter) |
1362 | - logger.addHandler(hdlr) |
1363 | - logger.setLevel(logging.DEBUG) |
1364 | - |
1365 | working_dir = os.path.abspath("tests") |
1366 | c = config.Config(stream=sys.stdout, |
1367 | env=os.environ, |
1368 | verbosity=3, |
1369 | workingDir=working_dir) |
1370 | - runner = QuantumTestRunner(stream=c.stream, |
1371 | - verbosity=c.verbosity, |
1372 | - config=c) |
1373 | - sys.exit(not core.run(config=c, testRunner=runner)) |
1374 | + sys.exit(run_tests(c)) |
1375 | |
1376 | === modified file 'run_tests.sh' |
1377 | --- run_tests.sh 2011-07-29 23:39:45 +0000 |
1378 | +++ run_tests.sh 2011-08-16 06:17:23 +0000 |
1379 | @@ -39,11 +39,20 @@ |
1380 | |
1381 | function run_tests { |
1382 | # Just run the test suites in current environment |
1383 | - ${wrapper} rm -f tests.sqlite |
1384 | - ${wrapper} $NOSETESTS 2> run_tests.err.log |
1385 | + ${wrapper} rm -f ./$PLUGIN_DIR/tests.sqlite |
1386 | + ${wrapper} $NOSETESTS 2> ./$PLUGIN_DIR/run_tests.err.log |
1387 | } |
1388 | |
1389 | -NOSETESTS="python run_tests.py $noseargs" |
1390 | +NOSETESTS="python ./$PLUGIN_DIR/run_tests.py $noseargs" |
1391 | + |
1392 | +if [ -n "$PLUGIN_DIR" ] |
1393 | +then |
1394 | + if ! [ -f ./$PLUGIN_DIR/run_tests.py ] |
1395 | + then |
1396 | + echo "Could not find run_tests.py in plugin directory $PLUGIN_DIR" |
1397 | + exit 1 |
1398 | + fi |
1399 | +fi |
1400 | |
1401 | if [ $never_venv -eq 0 ] |
1402 | then |
1403 | |
1404 | === modified file 'tests/unit/test_api.py' |
1405 | --- tests/unit/test_api.py 2011-08-10 04:58:15 +0000 |
1406 | +++ tests/unit/test_api.py 2011-08-16 06:17:23 +0000 |
1407 | @@ -20,13 +20,13 @@ |
1408 | import logging |
1409 | import unittest |
1410 | |
1411 | - |
1412 | import tests.unit.testlib_api as testlib |
1413 | + |
1414 | from quantum import api as server |
1415 | from quantum.db import api as db |
1416 | +from quantum.common.test_lib import test_config |
1417 | from quantum.common.wsgi import Serializer |
1418 | |
1419 | - |
1420 | LOG = logging.getLogger('quantum.tests.test_api') |
1421 | |
1422 | |
1423 | @@ -150,19 +150,6 @@ |
1424 | network_data['network']) |
1425 | LOG.debug("_test_rename_network - format:%s - END", format) |
1426 | |
1427 | - def _test_rename_network_duplicate(self, format): |
1428 | - LOG.debug("_test_rename_network_duplicate - format:%s - START", format) |
1429 | - content_type = "application/%s" % format |
1430 | - network_id1 = self._create_network(format, name="net1") |
1431 | - network_id2 = self._create_network(format, name="net2") |
1432 | - update_network_req = testlib.update_network_request(self.tenant_id, |
1433 | - network_id2, |
1434 | - "net1", |
1435 | - format) |
1436 | - update_network_res = update_network_req.get_response(self.api) |
1437 | - self.assertEqual(update_network_res.status_int, 422) |
1438 | - LOG.debug("_test_rename_network_duplicate - format:%s - END", format) |
1439 | - |
1440 | def _test_rename_network_badrequest(self, format): |
1441 | LOG.debug("_test_rename_network_badrequest - format:%s - START", |
1442 | format) |
1443 | @@ -440,23 +427,6 @@ |
1444 | show_port_res.body, content_type) |
1445 | self.assertEqual({'id': port_id, 'state': new_port_state}, |
1446 | port_data['port']) |
1447 | - |
1448 | - # now set it back to the original value |
1449 | - update_port_req = testlib.update_port_request(self.tenant_id, |
1450 | - network_id, port_id, |
1451 | - port_state, |
1452 | - format) |
1453 | - update_port_res = update_port_req.get_response(self.api) |
1454 | - self.assertEqual(update_port_res.status_int, 200) |
1455 | - show_port_req = testlib.show_port_request(self.tenant_id, |
1456 | - network_id, port_id, |
1457 | - format) |
1458 | - show_port_res = show_port_req.get_response(self.api) |
1459 | - self.assertEqual(show_port_res.status_int, 200) |
1460 | - port_data = self._port_serializer.deserialize( |
1461 | - show_port_res.body, content_type) |
1462 | - self.assertEqual({'id': port_id, 'state': port_state}, |
1463 | - port_data['port']) |
1464 | LOG.debug("_test_set_port_state - format:%s - END", format) |
1465 | |
1466 | def _test_set_port_state_networknotfound(self, format): |
1467 | @@ -680,7 +650,7 @@ |
1468 | |
1469 | def setUp(self): |
1470 | options = {} |
1471 | - options['plugin_provider'] = 'quantum.plugins.SamplePlugin.FakePlugin' |
1472 | + options['plugin_provider'] = test_config['plugin_name'] |
1473 | self.api = server.APIRouterV01(options) |
1474 | self.tenant_id = "test_tenant" |
1475 | self.network_name = "test_network" |
1476 | @@ -736,12 +706,6 @@ |
1477 | def test_rename_network_xml(self): |
1478 | self._test_rename_network('xml') |
1479 | |
1480 | - def test_rename_network_duplicate_json(self): |
1481 | - self._test_rename_network_duplicate('json') |
1482 | - |
1483 | - def test_rename_network_duplicate_xml(self): |
1484 | - self._test_rename_network_duplicate('xml') |
1485 | - |
1486 | def test_rename_network_badrequest_json(self): |
1487 | self._test_rename_network_badrequest('json') |
1488 |
lgtm