Docstrings should not start with a space

As per OpenStack Docstrings guide lines [1]:
[H401] Docstrings should not start with a space.
[H403] Multi line docstrings should end on a new line.
[H404] Multi line docstrings should start without a leading new line.
[H405] Multi line docstrings should start with a one line summary
followed by an empty line.

[1] http://docs.openstack.org/developer/hacking/#docstrings

trivialfix

Change-Id: I7683085edbd6b82c1efaa75ff507165ee51c16fd
This commit is contained in:
Duan Jiong
2017-03-25 12:41:58 +08:00
parent 702eb4ad5e
commit b07bc1a78b
14 changed files with 100 additions and 142 deletions

View File

@@ -40,7 +40,7 @@ class APIVersionRequest(object):
"""Create an API version request object. """Create an API version request object.
:param version_string: String representation of APIVersionRequest. :param version_string: String representation of APIVersionRequest.
Correct format is 'X.Y', where 'X' and 'Y' are int values. Correct format is 'X.Y', where 'X' and 'Y' are int values.
""" """
match = re.match(r"^([1-9]\d*)\.([1-9]\d*|0)$", version_string) match = re.match(r"^([1-9]\d*)\.([1-9]\d*|0)$", version_string)
if match: if match:

View File

@@ -133,7 +133,7 @@ class VersionedResource(object):
:returns: Returns the result of the method called :returns: Returns the result of the method called
:raises: VersionNotFoundForAPIMethod if there is no method which :raises: VersionNotFoundForAPIMethod if there is no method which
matches the name and version constraints matches the name and version constraints
""" """
# versioning is used in 3 classes: request deserializer and # versioning is used in 3 classes: request deserializer and
# controller have request as first argument # controller have request as first argument

View File

@@ -77,8 +77,7 @@ def parse_args(args=None, usage=None, default_config_files=None):
def _get_deployment_flavor(flavor=None): def _get_deployment_flavor(flavor=None):
""" """Retrieve the paste_deploy.flavor config item, formatted appropriately
Retrieve the paste_deploy.flavor config item, formatted appropriately
for appending to the application name. for appending to the application name.
:param flavor: if specified, use this setting rather than the :param flavor: if specified, use this setting rather than the
@@ -102,8 +101,7 @@ def _get_paste_config_path():
def _get_deployment_config_file(): def _get_deployment_config_file():
""" """Retrieve the deployment_config_file config item, formatted as an
Retrieve the deployment_config_file config item, formatted as an
absolute pathname. absolute pathname.
""" """
path = CONF.paste_deploy.config_file path = CONF.paste_deploy.config_file
@@ -116,8 +114,7 @@ def _get_deployment_config_file():
def load_paste_app(app_name, flavor=None, conf_file=None): def load_paste_app(app_name, flavor=None, conf_file=None):
""" """Builds and returns a WSGI app from a paste config file.
Builds and returns a WSGI app from a paste config file.
We assume the last config file specified in the supplied ConfigOpts We assume the last config file specified in the supplied ConfigOpts
object is the paste config file, if conf_file is None. object is the paste config file, if conf_file is None.

View File

@@ -23,8 +23,7 @@ LOG = logging.getLogger(__name__)
class GlareException(Exception): class GlareException(Exception):
""" """Base Glare Exception class.
Base Glare Exception class.
To correctly use this class, inherit from it and define To correctly use this class, inherit from it and define
a 'message' property. That message will get printf'd a 'message' property. That message will get printf'd

View File

@@ -27,15 +27,14 @@ MAX_NUMERIC_PRERELEASE_LENGTH = 6
class DBVersion(object): class DBVersion(object):
def __init__(self, components_long, prerelease, build): def __init__(self, components_long, prerelease, build):
""" """Creates a DBVersion object out of 3 component fields. This initializer
Creates a DBVersion object out of 3 component fields. This initializer
is supposed to be called from SQLAlchemy if 3 database columns are is supposed to be called from SQLAlchemy if 3 database columns are
mapped to this composite field. mapped to this composite field.
:param components_long: a 64-bit long value, containing numeric :param components_long: a 64-bit long value, containing numeric
components of the version components of the version
:param prerelease: a prerelease label of the version, optionally :param prerelease: a prerelease label of the version, optionally
preformatted with leading zeroes in numeric-only parts of the label preformatted with leading zeroes in numeric-only parts of the label
:param build: a build label of the version :param build: a build label of the version
""" """
version_string = '%s.%s.%s' % _long_to_components(components_long) version_string = '%s.%s.%s' % _long_to_components(components_long)
@@ -80,8 +79,7 @@ def _check_limit(value):
def _version_to_long(version): def _version_to_long(version):
""" """Converts the numeric part of the semver version into the 64-bit long value
Converts the numeric part of the semver version into the 64-bit long value
using the following logic: using the following logic:
* major version is stored in first 16 bits of the value * major version is stored in first 16 bits of the value

View File

@@ -56,8 +56,7 @@ GLARE_TEST_SOCKET_FD_STR = 'GLARE_TEST_SOCKET_FD'
def chunkreadable(iter, chunk_size=65536): def chunkreadable(iter, chunk_size=65536):
""" """Wrap a readable iterator with a reader yielding chunks of
Wrap a readable iterator with a reader yielding chunks of
a preferred size, otherwise leave iterator unchanged. a preferred size, otherwise leave iterator unchanged.
:param iter: an iter which may also be readable :param iter: an iter which may also be readable
@@ -67,8 +66,7 @@ def chunkreadable(iter, chunk_size=65536):
def chunkiter(fp, chunk_size=65536): def chunkiter(fp, chunk_size=65536):
""" """Return an iterator to a file-like obj which yields fixed size chunks.
Return an iterator to a file-like obj which yields fixed size chunks.
:param fp: a file-like object :param fp: a file-like object
:param chunk_size: maximum size of chunk :param chunk_size: maximum size of chunk
@@ -82,8 +80,7 @@ def chunkiter(fp, chunk_size=65536):
def cooperative_iter(iter): def cooperative_iter(iter):
""" """Return an iterator which schedules after each
Return an iterator which schedules after each
iteration. This can prevent eventlet thread starvation. iteration. This can prevent eventlet thread starvation.
:param iter: an iterator to wrap :param iter: an iterator to wrap
@@ -99,8 +96,7 @@ def cooperative_iter(iter):
def cooperative_read(fd): def cooperative_read(fd):
""" """Wrap a file descriptor's read with a partial function which schedules
Wrap a file descriptor's read with a partial function which schedules
after each read. This can prevent eventlet thread starvation. after each read. This can prevent eventlet thread starvation.
:param fd: a file descriptor to wrap :param fd: a file descriptor to wrap
@@ -116,8 +112,7 @@ MAX_COOP_READER_BUFFER_SIZE = 134217728 # 128M seems like a sane buffer limit
class CooperativeReader(object): class CooperativeReader(object):
""" """An eventlet thread friendly class for reading in blob data.
An eventlet thread friendly class for reading in blob data.
When accessing data either through the iterator or the read method When accessing data either through the iterator or the read method
we perform a sleep to allow a co-operative yield. When there is more than we perform a sleep to allow a co-operative yield. When there is more than
@@ -126,8 +121,7 @@ class CooperativeReader(object):
having the same thread be continuously active. having the same thread be continuously active.
""" """
def __init__(self, fd): def __init__(self, fd):
""" """:param fd: Underlying blob file object
:param fd: Underlying blob file object
""" """
self.fd = fd self.fd = fd
self.iterator = None self.iterator = None
@@ -204,8 +198,7 @@ class CooperativeReader(object):
class LimitingReader(object): class LimitingReader(object):
""" """Reader designed to fail when reading blob data past the configured
Reader designed to fail when reading blob data past the configured
allowable amount. allowable amount.
""" """
def __init__(self, data, limit): def __init__(self, data, limit):
@@ -361,8 +354,7 @@ except re.error:
def no_4byte_params(f): def no_4byte_params(f):
""" """Checks that no 4 byte unicode characters are allowed
Checks that no 4 byte unicode characters are allowed
in dicts' keys/values and string's parameters. in dicts' keys/values and string's parameters.
""" """
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
@@ -400,8 +392,7 @@ def no_4byte_params(f):
def stash_conf_values(): def stash_conf_values():
""" """Make a copy of some of the current global CONF's settings.
Make a copy of some of the current global CONF's settings.
Allows determining if any of these values have changed Allows determining if any of these values have changed
when the config is reloaded. when the config is reloaded.
""" """
@@ -608,8 +599,7 @@ def _get_element_type(element_type):
class DictDiffer(object): class DictDiffer(object):
""" """Calculate the difference between two dictionaries as:
Calculate the difference between two dictionaries as:
(1) items added (1) items added
(2) items removed (2) items removed
(3) keys same in both but changed values (3) keys same in both but changed values
@@ -647,8 +637,7 @@ class DictDiffer(object):
class BlobIterator(object): class BlobIterator(object):
""" """Reads data from a blob, one chunk at a time.
Reads data from a blob, one chunk at a time.
""" """
def __init__(self, data, chunk_size=65536): def __init__(self, data, chunk_size=65536):

View File

@@ -129,8 +129,7 @@ def get_bind_addr(default_port=None):
def ssl_wrap_socket(sock): def ssl_wrap_socket(sock):
""" """Wrap an existing socket in SSL
Wrap an existing socket in SSL
:param sock: non-SSL socket to wrap :param sock: non-SSL socket to wrap
@@ -153,8 +152,7 @@ def ssl_wrap_socket(sock):
def get_socket(default_port): def get_socket(default_port):
""" """Bind socket to bind ip:port in conf
Bind socket to bind ip:port in conf
:param default_port: port to bind to if none is specified in conf :param default_port: port to bind to if none is specified in conf
@@ -260,8 +258,7 @@ class Server(object):
self.pgid = 0 self.pgid = 0
def hup(self, *args): def hup(self, *args):
""" """Reloads configuration files with zero down time
Reloads configuration files with zero down time
""" """
signal.signal(signal.SIGHUP, signal.SIG_IGN) signal.signal(signal.SIGHUP, signal.SIG_IGN)
raise glare_exc.SIGHUPInterrupt raise glare_exc.SIGHUPInterrupt
@@ -274,8 +271,7 @@ class Server(object):
os.killpg(self.pgid, signal.SIGTERM) os.killpg(self.pgid, signal.SIGTERM)
def start(self, application, default_port): def start(self, application, default_port):
""" """Run a WSGI server with the given application.
Run a WSGI server with the given application.
:param application: The application to be run in the WSGI server :param application: The application to be run in the WSGI server
:param default_port: Port to bind to if none is specified in conf :param default_port: Port to bind to if none is specified in conf
@@ -348,8 +344,7 @@ class Server(object):
LOG.debug('Exited') LOG.debug('Exited')
def configure(self, old_conf=None, has_changed=None): def configure(self, old_conf=None, has_changed=None):
""" """Apply configuration settings
Apply configuration settings
:param old_conf: Cached old configuration settings (if any) :param old_conf: Cached old configuration settings (if any)
:param has_changed: callable to determine if a parameter has changed :param has_changed: callable to determine if a parameter has changed
@@ -370,8 +365,7 @@ class Server(object):
initialize_glance_store() initialize_glance_store()
def reload(self): def reload(self):
""" """Reload and re-apply configuration settings
Reload and re-apply configuration settings
Existing child processes are sent a SIGHUP signal Existing child processes are sent a SIGHUP signal
and will exit after completing existing requests. and will exit after completing existing requests.
@@ -466,8 +460,7 @@ class Server(object):
socket_timeout=self.client_socket_timeout) socket_timeout=self.client_socket_timeout)
def configure_socket(self, old_conf=None, has_changed=None): def configure_socket(self, old_conf=None, has_changed=None):
""" """Ensure a socket exists and is appropriately configured.
Ensure a socket exists and is appropriately configured.
This function is called on start up, and can also be This function is called on start up, and can also be
called in the event of a configuration reload. called in the event of a configuration reload.
@@ -536,8 +529,7 @@ class Server(object):
class APIMapper(routes.Mapper): class APIMapper(routes.Mapper):
""" """Handle route matching when url is '' because routes.Mapper returns
Handle route matching when url is '' because routes.Mapper returns
an error in this case. an error in this case.
""" """
@@ -557,13 +549,11 @@ class RejectMethodController(object):
class Router(object): class Router(object):
""" """WSGI middleware that maps incoming requests to WSGI apps.
WSGI middleware that maps incoming requests to WSGI apps.
""" """
def __init__(self, mapper): def __init__(self, mapper):
""" """Create a router for the given routes.Mapper.
Create a router for the given routes.Mapper.
Each route in `mapper` must specify a 'controller', which is a Each route in `mapper` must specify a 'controller', which is a
WSGI app to call. You'll probably want to specify an 'action' as WSGI app to call. You'll probably want to specify an 'action' as
@@ -596,8 +586,7 @@ class Router(object):
@webob.dec.wsgify @webob.dec.wsgify
def __call__(self, req): def __call__(self, req):
""" """Route the incoming request to a controller based on self.map.
Route the incoming request to a controller based on self.map.
If no match, return either a 404(Not Found) or 501(Not Implemented). If no match, return either a 404(Not Found) or 501(Not Implemented).
""" """
return self._router return self._router
@@ -605,8 +594,7 @@ class Router(object):
@staticmethod @staticmethod
@webob.dec.wsgify @webob.dec.wsgify
def _dispatch(req): def _dispatch(req):
""" """Called by self._router after matching the incoming request to a route
Called by self._router after matching the incoming request to a route
and putting the information into req.environ. Either returns 404, and putting the information into req.environ. Either returns 404,
501, or the routed WSGI app's response. 501, or the routed WSGI app's response.
""" """
@@ -658,8 +646,7 @@ class JSONRequestDeserializer(object):
'gzip', 'identity']) 'gzip', 'identity'])
def has_body(self, request): def has_body(self, request):
""" """Returns whether a Webob.Request object will possess an entity body.
Returns whether a Webob.Request object will possess an entity body.
:param request: Webob.Request object :param request: Webob.Request object
""" """
@@ -735,8 +722,7 @@ def translate_exception(req, e):
class Resource(object): class Resource(object):
""" """WSGI app that handles (de)serialization and controller dispatch.
WSGI app that handles (de)serialization and controller dispatch.
Reads routing information supplied by RoutesMiddleware and calls Reads routing information supplied by RoutesMiddleware and calls
the requested action method upon its deserializer, controller, the requested action method upon its deserializer, controller,

View File

@@ -38,6 +38,7 @@ def version(engine=None):
def upgrade(revision, config=None): def upgrade(revision, config=None):
"""Used for upgrading database. """Used for upgrading database.
:param revision: Desired database version :param revision: Desired database version
:type revision: string :type revision: string
""" """
@@ -49,6 +50,7 @@ def upgrade(revision, config=None):
def downgrade(revision, config=None): def downgrade(revision, config=None):
"""Used for downgrading database. """Used for downgrading database.
:param revision: Desired database version7 :param revision: Desired database version7
:type revision: string :type revision: string
""" """
@@ -59,7 +61,9 @@ def downgrade(revision, config=None):
def stamp(revision, config=None): def stamp(revision, config=None):
"""Stamps database with provided revision. """Stamps database with provided revision.
Don't run any migrations. Don't run any migrations.
:param revision: Should match one from repository or head - to stamp :param revision: Should match one from repository or head - to stamp
database with most recent revision database with most recent revision
:type revision: string :type revision: string
@@ -70,6 +74,7 @@ def stamp(revision, config=None):
def revision(message=None, autogenerate=False, config=None): def revision(message=None, autogenerate=False, config=None):
"""Creates template for migration. """Creates template for migration.
:param message: Text that will be used for migration title :param message: Text that will be used for migration title
:type message: string :type message: string
:param autogenerate: If True - generates diff based on current database :param autogenerate: If True - generates diff based on current database

View File

@@ -91,8 +91,7 @@ def get_session(autocommit=True, expire_on_commit=False):
def clear_db_env(): def clear_db_env():
""" """Unset global configuration variables for database.
Unset global configuration variables for database.
""" """
global _FACADE global _FACADE
_FACADE = None _FACADE = None
@@ -113,8 +112,7 @@ def delete(context, artifact_id, session):
def _drop_protected_attrs(model_class, values): def _drop_protected_attrs(model_class, values):
""" """Removed protected attributes from values dictionary using the models
Removed protected attributes from values dictionary using the models
__protected_attributes__ field. __protected_attributes__ field.
""" """
for attr in model_class.__protected_attributes__: for attr in model_class.__protected_attributes__:
@@ -193,15 +191,16 @@ def get(context, artifact_id, session):
def get_all(context, session, filters=None, marker=None, limit=None, def get_all(context, session, filters=None, marker=None, limit=None,
sort=None, latest=False): sort=None, latest=False):
"""List all visible artifacts """List all visible artifacts
:param filters: dict of filter keys and values. :param filters: dict of filter keys and values.
:param marker: artifact id after which to start page :param marker: artifact id after which to start page
:param limit: maximum number of artifacts to return :param limit: maximum number of artifacts to return
:param sort: a tuple (key, dir, type) where key is an attribute by :param sort: a tuple (key, dir, type) where key is an attribute by
which results should be sorted, dir is a direction: 'asc' or 'desc', which results should be sorted, dir is a direction: 'asc' or 'desc',
and type is type of the attribute: 'bool', 'string', 'numeric' or 'int' or and type is type of the attribute: 'bool', 'string', 'numeric' or 'int' or
None if attribute is base. None if attribute is base.
:param latest: flag that indicates, that only artifacts with highest :param latest: flag that indicates, that only artifacts with highest
versions should be returned in output versions should be returned in output
""" """
artifacts = _get_all( artifacts = _get_all(
context, session, filters, marker, limit, sort, latest) context, session, filters, marker, limit, sort, latest)

View File

@@ -37,14 +37,16 @@ LOG = logging.getLogger(__name__)
class Engine(object): class Engine(object):
"""Engine is responsible for executing different helper operations when """Engine is responsible for executing different helper operations when
processing incoming requests from Glare API. processing incoming requests from Glare API.
Engine receives incoming data and does the following: Engine receives incoming data and does the following:
- check basic policy permissions; - check basic policy permissions;
- requests artifact definition from artifact type registry; - requests artifact definition from artifact type registry;
- check access permission(ro, rw); - check access permission(ro, rw);
- lock artifact for update if needed; - lock artifact for update if needed;
- pass data to base artifact to execute all business logic operations - pass data to base artifact to execute all business logic operations
with database; with database;
- notify other users about finished operation. - notify other users about finished operation.
Engine should not include any business logic and validation related Engine should not include any business logic and validation related
to Artifacts. Engine should not know any internal details of artifact to Artifacts. Engine should not know any internal details of artifact
type, because this part of the work is done by Base artifact type. type, because this part of the work is done by Base artifact type.
@@ -63,13 +65,14 @@ class Engine(object):
@classmethod @classmethod
def _get_artifact(cls, ctx, type_name, artifact_id, read_only=False): def _get_artifact(cls, ctx, type_name, artifact_id, read_only=False):
"""Return artifact requested by user. """Return artifact requested by user.
Check access permissions and policies. Check access permissions and policies.
:param ctx: user context :param ctx: user context
:param type_name: artifact type name :param type_name: artifact type name
:param artifact_id: id of the artifact to be updated :param artifact_id: id of the artifact to be updated
:param read_only: flag, if set to True only read access is checked, :param read_only: flag, if set to True only read access is checked,
if False then engine checks if artifact can be modified by the user if False then engine checks if artifact can be modified by the user
""" """
artifact_type = registry.ArtifactRegistry.get_artifact_type(type_name) artifact_type = registry.ArtifactRegistry.get_artifact_type(type_name)
# only artifact is available for class users # only artifact is available for class users
@@ -196,12 +199,12 @@ class Engine(object):
:param type_name: Artifact type name :param type_name: Artifact type name
:param filters: filters that need to be applied to artifact :param filters: filters that need to be applied to artifact
:param marker: the artifact that considered as begin of the list :param marker: the artifact that considered as begin of the list
so all artifacts before marker (including marker itself) will not be so all artifacts before marker (including marker itself) will not be
added to artifact list added to artifact list
:param limit: maximum number of items in list :param limit: maximum number of items in list
:param sort: sorting options :param sort: sorting options
:param latest: flag that indicates, that only artifacts with highest :param latest: flag that indicates, that only artifacts with highest
versions should be returned in output versions should be returned in output
:return: list of artifact definitions :return: list of artifact definitions
""" """
policy.authorize("artifact:list", {}, context) policy.authorize("artifact:list", {}, context)

View File

@@ -57,13 +57,11 @@ eventlet.patcher.monkey_patch()
class Server(object): class Server(object):
""" """Class used to easily manage starting and stopping
Class used to easily manage starting and stopping
a server during functional test runs. a server during functional test runs.
""" """
def __init__(self, test_dir, port, sock=None): def __init__(self, test_dir, port, sock=None):
""" """Creates a new Server object.
Creates a new Server object.
:param test_dir: The directory where all test stuff is kept. This is :param test_dir: The directory where all test stuff is kept. This is
passed from the FunctionalTestCase. passed from the FunctionalTestCase.
@@ -87,8 +85,7 @@ class Server(object):
self.stop_kill = False self.stop_kill = False
def write_conf(self, **kwargs): def write_conf(self, **kwargs):
""" """Writes the configuration file for the server to its intended
Writes the configuration file for the server to its intended
destination. Returns the name of the configuration file and destination. Returns the name of the configuration file and
the over-ridden config content (may be useful for populating the over-ridden config content (may be useful for populating
error messages). error messages).
@@ -132,8 +129,7 @@ class Server(object):
return self.conf_file_name, overridden return self.conf_file_name, overridden
def start(self, expect_exit=True, expected_exitcode=0, **kwargs): def start(self, expect_exit=True, expected_exitcode=0, **kwargs):
""" """Starts the server.
Starts the server.
Any kwargs passed to this method will override the configuration Any kwargs passed to this method will override the configuration
value in the conf file used in starting the servers. value in the conf file used in starting the servers.
@@ -190,8 +186,7 @@ class Server(object):
return (rc, '', '') return (rc, '', '')
def reload(self, expect_exit=True, expected_exitcode=0, **kwargs): def reload(self, expect_exit=True, expected_exitcode=0, **kwargs):
""" """Start and stop the service to reload
Start and stop the service to reload
Any kwargs passed to this method will override the configuration Any kwargs passed to this method will override the configuration
value in the conf file used in starting the servers. value in the conf file used in starting the servers.
@@ -240,9 +235,7 @@ class Server(object):
atexit.register(_delete_cached_db) atexit.register(_delete_cached_db)
def stop(self): def stop(self):
""" """Spin down the server."""
Spin down the server.
"""
if not self.process_pid: if not self.process_pid:
raise Exception('why is this being called? %s' % self.server_name) raise Exception('why is this being called? %s' % self.server_name)
@@ -262,9 +255,7 @@ class Server(object):
class GlareServer(Server): class GlareServer(Server):
""" """Server object that starts/stops/manages Glare server"""
Server object that starts/stops/manages Glare server
"""
def __init__(self, test_dir, port, policy_file, delayed_delete=False, def __init__(self, test_dir, port, policy_file, delayed_delete=False,
pid_file=None, sock=None, **kwargs): pid_file=None, sock=None, **kwargs):
@@ -347,8 +338,7 @@ paste.filter_factory =
class FunctionalTest(test_utils.BaseTestCase): class FunctionalTest(test_utils.BaseTestCase):
""" """Base test class for any test that wants to test the actual
Base test class for any test that wants to test the actual
servers and clients and not just the stubbed out interfaces servers and clients and not just the stubbed out interfaces
""" """
@@ -424,8 +414,7 @@ class FunctionalTest(test_utils.BaseTestCase):
self.assertEqual(0, exitcode) self.assertEqual(0, exitcode)
def cleanup(self): def cleanup(self):
""" """Makes sure anything we created or started up in the
Makes sure anything we created or started up in the
tests are destroyed or spun down tests are destroyed or spun down
""" """
@@ -451,8 +440,7 @@ class FunctionalTest(test_utils.BaseTestCase):
expect_exit=True, expect_exit=True,
expected_exitcode=0, expected_exitcode=0,
**kwargs): **kwargs):
""" """Starts a server on an unused port.
Starts a server on an unused port.
Any kwargs passed to this method will override the configuration Any kwargs passed to this method will override the configuration
value in the conf file used in starting the server. value in the conf file used in starting the server.
@@ -483,8 +471,7 @@ class FunctionalTest(test_utils.BaseTestCase):
def start_with_retry(self, server, port_name, max_retries, def start_with_retry(self, server, port_name, max_retries,
expect_launch=True, expect_launch=True,
**kwargs): **kwargs):
""" """Starts a server, with retries if the server launches but
Starts a server, with retries if the server launches but
fails to start listening on the expected port. fails to start listening on the expected port.
:param server: the server to launch :param server: the server to launch
@@ -514,8 +501,7 @@ class FunctionalTest(test_utils.BaseTestCase):
self.assertTrue(launch_msg is None, launch_msg) self.assertTrue(launch_msg is None, launch_msg)
def start_servers(self, **kwargs): def start_servers(self, **kwargs):
""" """Starts the Glare server on unused port.
Starts the Glare server on unused port.
Any kwargs passed to this method will override the configuration Any kwargs passed to this method will override the configuration
value in the conf file used in starting the servers. value in the conf file used in starting the servers.
@@ -525,8 +511,7 @@ class FunctionalTest(test_utils.BaseTestCase):
self.start_with_retry(self.glare_server, 'glare_port', 3, **kwargs) self.start_with_retry(self.glare_server, 'glare_port', 3, **kwargs)
def ping_server(self, port): def ping_server(self, port):
""" """Simple ping on the port. If responsive, return True, else
Simple ping on the port. If responsive, return True, else
return False. return False.
:note We use raw sockets, not ping here, since ping uses ICMP and :note We use raw sockets, not ping here, since ping uses ICMP and
@@ -542,8 +527,7 @@ class FunctionalTest(test_utils.BaseTestCase):
s.close() s.close()
def wait_for_servers(self, servers, expect_launch=True, timeout=30): def wait_for_servers(self, servers, expect_launch=True, timeout=30):
""" """Tight loop, waiting for the given server port(s) to be available.
Tight loop, waiting for the given server port(s) to be available.
Returns when all are pingable. There is a timeout on waiting Returns when all are pingable. There is a timeout on waiting
for the servers to come up. for the servers to come up.
@@ -597,8 +581,7 @@ class FunctionalTest(test_utils.BaseTestCase):
return msg if expect_launch else None return msg if expect_launch else None
def stop_server(self, server, name): def stop_server(self, server, name):
""" """Called to stop a single server in a normal fashion.
Called to stop a single server in a normal fashion.
:param server: the server to stop :param server: the server to stop
""" """
@@ -611,9 +594,8 @@ class FunctionalTest(test_utils.BaseTestCase):
self._reset_database(self.glare_server.sql_connection) self._reset_database(self.glare_server.sql_connection)
def run_sql_cmd(self, sql): def run_sql_cmd(self, sql):
""" """Provides a crude mechanism to run manual SQL commands
Provides a crude mechanism to run manual SQL commands for backend for backend DB verification within the functional tests.
DB verification within the functional tests.
The raw result set is returned. The raw result set is returned.
""" """
engine = db_api.get_engine() engine = db_api.get_engine()

View File

@@ -103,8 +103,7 @@ class BaseTestCase(testtools.TestCase):
return dst_file_name return dst_file_name
def config(self, **kw): def config(self, **kw):
""" """Override some configuration values.
Override some configuration values.
The keyword arguments are the names of configuration options to The keyword arguments are the names of configuration options to
override and their values. override and their values.

View File

@@ -76,6 +76,7 @@ class WalkVersionsMixin(object):
def _migrate_up(self, engine, config, version, with_data=False): def _migrate_up(self, engine, config, version, with_data=False):
"""migrate up to a new version of the db. """migrate up to a new version of the db.
We allow for data insertion and post checks at every We allow for data insertion and post checks at every
migration version with special _pre_upgrade_### and migration version with special _pre_upgrade_### and
_check_### functions in the main test. _check_### functions in the main test.

View File

@@ -76,8 +76,8 @@ class BaseTestCase(testtools.TestCase):
return dst_file_name return dst_file_name
def config(self, **kw): def config(self, **kw):
""" """Override some configuration values.
Override some configuration values.
The keyword arguments are the names of configuration options to The keyword arguments are the names of configuration options to
override and their values. override and their values.
If a group argument is supplied, the overrides are applied to If a group argument is supplied, the overrides are applied to
@@ -142,8 +142,8 @@ def fork_exec(cmd,
exec_env=None, exec_env=None,
logfile=None, logfile=None,
pass_fds=None): pass_fds=None):
""" """Execute a command using fork/exec.
Execute a command using fork/exec.
This is needed for programs system executions that need path This is needed for programs system executions that need path
searching but cannot have a shell as their parent process, for searching but cannot have a shell as their parent process, for
example: glare. When glare starts it sets itself as example: glare. When glare starts it sets itself as
@@ -151,6 +151,7 @@ def fork_exec(cmd,
a Popen process would have is not the right pid to use for killing a Popen process would have is not the right pid to use for killing
the process group. This patch gives the test env direct access the process group. This patch gives the test env direct access
to the actual pid. to the actual pid.
:param cmd: Command to execute as an array of arguments. :param cmd: Command to execute as an array of arguments.
:param exec_env: A dictionary representing the environment with :param exec_env: A dictionary representing the environment with
which to run the command. which to run the command.
@@ -192,8 +193,8 @@ def fork_exec(cmd,
def wait_for_fork(pid, def wait_for_fork(pid,
raise_error=True, raise_error=True,
expected_exitcode=0): expected_exitcode=0):
""" """Wait for a process to complete
Wait for a process to complete
This function will wait for the given pid to complete. If the This function will wait for the given pid to complete. If the
exit code does not match that of the expected_exitcode an error exit code does not match that of the expected_exitcode an error
is raised. is raised.
@@ -220,11 +221,12 @@ def execute(cmd,
expect_exit=True, expect_exit=True,
expected_exitcode=0, expected_exitcode=0,
context=None): context=None):
""" """Executes a command in a subprocess.
Executes a command in a subprocess. Returns a tuple
of (exitcode, out, err), where out is the string output Returns a tuple of (exitcode, out, err), where out is the string
from stdout and err is the string output from stderr when output from stdout and err is the string output from stderr when
executing the command. executing the command.
:param cmd: Command string to execute :param cmd: Command string to execute
:param raise_error: If returncode is not 0 (success), then :param raise_error: If returncode is not 0 (success), then
raise a RuntimeError? Default: True) raise a RuntimeError? Default: True)
@@ -291,10 +293,11 @@ def execute(cmd,
def find_executable(cmdname): def find_executable(cmdname):
""" """Searches the path for a given cmdname.
Searches the path for a given cmdname. Returns an absolute
filename if an executable with the given name exists in the path, Returns an absolute filename if an executable with the given
or None if one does not. name exists in the path, or None if one does not.
:param cmdname: The bare name of the executable to search for :param cmdname: The bare name of the executable to search for
""" """
@@ -317,8 +320,7 @@ def find_executable(cmdname):
def get_unused_port(): def get_unused_port():
""" """Returns an unused port on localhost.
Returns an unused port on localhost.
""" """
port, s = get_unused_port_and_socket() port, s = get_unused_port_and_socket()
s.close() s.close()
@@ -326,8 +328,7 @@ def get_unused_port():
def get_unused_port_and_socket(): def get_unused_port_and_socket():
""" """Returns an unused port on localhost and the open socket
Returns an unused port on localhost and the open socket
from which it was created. from which it was created.
""" """
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -337,8 +338,7 @@ def get_unused_port_and_socket():
def xattr_writes_supported(path): def xattr_writes_supported(path):
""" """Returns True if the we can write a file to the supplied
Returns True if the we can write a file to the supplied
path and subsequently write a xattr to that file. path and subsequently write a xattr to that file.
""" """
try: try: