cea9e39dd7
There are several common fixtures that every test case wants. Following the pattern in Nova, add a common base test case class to hold these things. Change-Id: I2d2cd91e5051d9cbf230e6f48985d6eddcb7b58a
225 lines
6.2 KiB
ReStructuredText
225 lines
6.2 KiB
ReStructuredText
Quantum Style Commandments
|
|
==========================
|
|
|
|
- Step 1: Read http://www.python.org/dev/peps/pep-0008/
|
|
- Step 2: Read http://www.python.org/dev/peps/pep-0008/ again
|
|
- Step 3: Read on
|
|
|
|
|
|
General
|
|
-------
|
|
- Put two newlines between top-level code (funcs, classes, etc)
|
|
- Put one newline between methods in classes and anywhere else
|
|
- Do not write "except:", use "except Exception:" at the very least
|
|
- Include your name with TODOs as in "#TODO(termie)"
|
|
- Do not shadow a built-in or reserved word. Example::
|
|
|
|
def list():
|
|
return [1, 2, 3]
|
|
|
|
mylist = list() # BAD, shadows `list` built-in
|
|
|
|
class Foo(object):
|
|
def list(self):
|
|
return [1, 2, 3]
|
|
|
|
mylist = Foo().list() # OKAY, does not shadow built-in
|
|
|
|
|
|
Imports
|
|
-------
|
|
- Do not make relative imports
|
|
- Order your imports by the full module path
|
|
|
|
Example::
|
|
|
|
The following imports,
|
|
|
|
from quantum.api import networks
|
|
from quantum import wsgi
|
|
|
|
are considered equivalent for ordering purposes to
|
|
|
|
import quantum.api.networks
|
|
import quantum.wsgi
|
|
|
|
- Organize your imports according to the following template
|
|
|
|
Example::
|
|
|
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
{{stdlib imports in human alphabetical order}}
|
|
\n
|
|
{{third-party lib imports in human alphabetical order}}
|
|
\n
|
|
{{quantum imports in human alphabetical order}}
|
|
\n
|
|
\n
|
|
{{begin your code}}
|
|
|
|
|
|
Human Alphabetical Order Examples
|
|
---------------------------------
|
|
Example::
|
|
|
|
import httplib
|
|
import random
|
|
import StringIO
|
|
import time
|
|
|
|
import eventlet
|
|
import testtools
|
|
import webob.exc
|
|
|
|
import quantum.api.networks
|
|
from quantum.api import ports
|
|
from quantum.db import models
|
|
from quantum.extensions import multiport
|
|
from quantum.openstack.common import log as logging
|
|
import quantum.manager
|
|
from quantum import service
|
|
|
|
|
|
Docstrings
|
|
----------
|
|
Example::
|
|
|
|
"""A one line docstring looks like this and ends in a period."""
|
|
|
|
|
|
"""A multiline docstring has a one-line summary, less than 80 characters.
|
|
|
|
Then a new paragraph after a newline that explains in more detail any
|
|
general information about the function, class or method. Example usages
|
|
are also great to have here if it is a complex class for function.
|
|
|
|
When writing the docstring for a class, an extra line should be placed
|
|
after the closing quotations. For more in-depth explanations for these
|
|
decisions see http://www.python.org/dev/peps/pep-0257/
|
|
|
|
If you are going to describe parameters and return values, use Sphinx, the
|
|
appropriate syntax is as follows.
|
|
|
|
:param foo: the foo parameter
|
|
:param bar: the bar parameter
|
|
:returns: return_type -- description of the return value
|
|
:returns: description of the return value
|
|
:raises: AttributeError, KeyError
|
|
"""
|
|
|
|
|
|
Dictionaries/Lists
|
|
------------------
|
|
If a dictionary (dict) or list object is longer than 80 characters, its items
|
|
should be split with newlines. Embedded iterables should have their items
|
|
indented. Additionally, the last item in the dictionary should have a trailing
|
|
comma. This increases readability and simplifies future diffs.
|
|
|
|
Example::
|
|
|
|
my_dictionary = {
|
|
"image": {
|
|
"name": "Just a Snapshot",
|
|
"size": 2749573,
|
|
"properties": {
|
|
"user_id": 12,
|
|
"arch": "x86_64",
|
|
},
|
|
"things": [
|
|
"thing_one",
|
|
"thing_two",
|
|
],
|
|
"status": "ACTIVE",
|
|
},
|
|
}
|
|
|
|
|
|
Calling Methods
|
|
---------------
|
|
Calls to methods 80 characters or longer should format each argument with
|
|
newlines. This is not a requirement, but a guideline::
|
|
|
|
unnecessarily_long_function_name('string one',
|
|
'string two',
|
|
kwarg1=constants.ACTIVE,
|
|
kwarg2=['a', 'b', 'c'])
|
|
|
|
|
|
Rather than constructing parameters inline, it is better to break things up::
|
|
|
|
list_of_strings = [
|
|
'what_a_long_string',
|
|
'not as long',
|
|
]
|
|
|
|
dict_of_numbers = {
|
|
'one': 1,
|
|
'two': 2,
|
|
'twenty four': 24,
|
|
}
|
|
|
|
object_one.call_a_method('string three',
|
|
'string four',
|
|
kwarg1=list_of_strings,
|
|
kwarg2=dict_of_numbers)
|
|
|
|
|
|
Internationalization (i18n) Strings
|
|
-----------------------------------
|
|
In order to support multiple languages, we have a mechanism to support
|
|
automatic translations of exception and log strings.
|
|
|
|
Example::
|
|
|
|
msg = _("An error occurred")
|
|
raise HTTPBadRequest(explanation=msg)
|
|
|
|
If you have a variable to place within the string, first internationalize the
|
|
template string then do the replacement.
|
|
|
|
Example::
|
|
|
|
msg = _("Missing parameter: %s") % ("flavor",)
|
|
LOG.error(msg)
|
|
|
|
If you have multiple variables to place in the string, use keyword parameters.
|
|
This helps our translators reorder parameters when needed.
|
|
|
|
Example::
|
|
|
|
msg = _("The server with id %(s_id)s has no key %(m_key)s")
|
|
LOG.error(msg % {"s_id": "1234", "m_key": "imageId"})
|
|
|
|
|
|
Creating Unit Tests
|
|
-------------------
|
|
For every new feature, unit tests should be created that both test and
|
|
(implicitly) document the usage of said feature. If submitting a patch for a
|
|
bug that had no unit test, a new passing unit test should be added. If a
|
|
submitted bug fix does have a unit test, be sure to add a new one that fails
|
|
without the patch and passes with the patch.
|
|
|
|
All unittest classes must ultimately inherit from testtools.TestCase. In the
|
|
Quantum test suite, this should be done by inheriting from
|
|
quantum.tests.base.BaseTestCase.
|
|
|
|
All setUp and tearDown methods must upcall using the super() method.
|
|
tearDown methods should be avoided and addCleanup calls should be preferred.
|
|
Never manually create tempfiles. Always use the tempfile fixtures from
|
|
the fixture library to ensure that they are cleaned up.
|
|
|
|
|
|
openstack-common
|
|
----------------
|
|
|
|
A number of modules from openstack-common are imported into the project.
|
|
|
|
These modules are "incubating" in openstack-common and are kept in sync
|
|
with the help of openstack-common's update.py script. See:
|
|
|
|
http://wiki.openstack.org/CommonLibrary#Incubation
|
|
|
|
The copy of the code should never be directly modified here. Please
|
|
always update openstack-common first and then run the script to copy
|
|
the changes across.
|