Add Designate hacking checks to the tempest plugin
This patch adds the Designate hacking checks to also run against the Designate tempest plugin code to maintain consistent style checking across the Designate repositories. Change-Id: I8f41bb8188ba8442dbf493dac39b8601f5208938
This commit is contained in:
parent
fe4672da25
commit
cc8f89b41c
@ -15,16 +15,16 @@ from tempest import clients
|
||||
from tempest import config
|
||||
from tempest.lib import auth
|
||||
|
||||
from designate_tempest_plugin.services.dns.v2.json.blacklists_client import \
|
||||
BlacklistsClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.pool_client import \
|
||||
PoolClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.recordset_client import \
|
||||
RecordsetClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.tld_client import \
|
||||
TldClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.zones_client import \
|
||||
ZonesClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.blacklists_client import (
|
||||
BlacklistsClient)
|
||||
from designate_tempest_plugin.services.dns.v2.json.pool_client import (
|
||||
PoolClient)
|
||||
from designate_tempest_plugin.services.dns.v2.json.recordset_client import (
|
||||
RecordsetClient)
|
||||
from designate_tempest_plugin.services.dns.v2.json.tld_client import (
|
||||
TldClient)
|
||||
from designate_tempest_plugin.services.dns.v2.json.zones_client import (
|
||||
ZonesClient)
|
||||
|
||||
|
||||
CONF = config.CONF
|
||||
|
@ -95,8 +95,8 @@ def rand_quotas(zones=None, zone_records=None, zone_recordsets=None,
|
||||
}
|
||||
|
||||
if CONF.dns_feature_enabled.bug_1573141_fixed:
|
||||
quotas_dict['api_export_size'] = \
|
||||
api_export_size or data_utils.rand_int_id(100, 999999)
|
||||
quotas_dict['api_export_size'] = (
|
||||
api_export_size or data_utils.rand_int_id(100, 999999))
|
||||
else:
|
||||
LOG.warning("Leaving `api_export_size` out of quota data due to: "
|
||||
"https://bugs.launchpad.net/designate/+bug/1573141")
|
||||
@ -190,8 +190,7 @@ def rand_sshfp_recordset(zone_name, algorithm_number=None,
|
||||
**kwargs):
|
||||
algorithm_number = algorithm_number or 2
|
||||
fingerprint_type = fingerprint_type or 1
|
||||
fingerprint = fingerprint or \
|
||||
"123456789abcdef67890123456789abcdef67890"
|
||||
fingerprint = fingerprint or "123456789abcdef67890123456789abcdef67890"
|
||||
|
||||
data = "%s %s %s" % (algorithm_number, fingerprint_type, fingerprint)
|
||||
return rand_recordset_data('SSHFP', zone_name, records=[data], **kwargs)
|
||||
|
0
designate_tempest_plugin/hacking/__init__.py
Normal file
0
designate_tempest_plugin/hacking/__init__.py
Normal file
187
designate_tempest_plugin/hacking/checks.py
Normal file
187
designate_tempest_plugin/hacking/checks.py
Normal file
@ -0,0 +1,187 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
# Copyright (c) 2012, Cloudscaling
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import re
|
||||
|
||||
from hacking import core
|
||||
import pycodestyle
|
||||
|
||||
# D701: Default parameter value is a mutable type
|
||||
# D702: Log messages require translation
|
||||
# D703: Found use of _() without explicit import of _!
|
||||
# D704: Found import of %s. This oslo library has been graduated!
|
||||
# D705: timeutils.utcnow() must be used instead of datetime.%s()
|
||||
# D706: Don't translate debug level logs
|
||||
# D707: basestring is not Python3-compatible, use str instead.
|
||||
# D708: Do not use xrange. Use range for large loops.
|
||||
# D709: LOG.audit is deprecated, please use LOG.info!
|
||||
# D710: LOG.warn() is not allowed. Use LOG.warning()
|
||||
# D711: Don't use backslashes for line continuation.
|
||||
|
||||
UNDERSCORE_IMPORT_FILES = []
|
||||
|
||||
|
||||
mutable_default_argument_check = re.compile(
|
||||
r"^\s*def .+\((.+=\{\}|.+=\[\])")
|
||||
string_translation = re.compile(r"[^_]*_\(\s*('|\")")
|
||||
translated_log = re.compile(
|
||||
r"(.)*LOG\.(audit|error|info|warn|warning|critical|exception)"
|
||||
r"\(\s*_\(\s*('|\")")
|
||||
underscore_import_check = re.compile(r"(.)*import _(.)*")
|
||||
# We need this for cases where they have created their own _ function.
|
||||
custom_underscore_check = re.compile(r"(.)*_\s*=\s*(.)*")
|
||||
graduated_oslo_libraries_import_re = re.compile(
|
||||
r"^\s*(?:import|from) designate\.openstack\.common\.?.*?"
|
||||
r"(gettextutils|rpc)"
|
||||
r".*?")
|
||||
no_line_continuation_backslash_re = re.compile(r'.*(\\)\n')
|
||||
|
||||
|
||||
@core.flake8ext
|
||||
def mutable_default_arguments(physical_line, logical_line, filename):
|
||||
if pycodestyle.noqa(physical_line):
|
||||
return
|
||||
|
||||
if mutable_default_argument_check.match(logical_line):
|
||||
yield (0, "D701: Default parameter value is a mutable type")
|
||||
|
||||
|
||||
@core.flake8ext
|
||||
def no_translate_debug_logs(logical_line, filename):
|
||||
"""Check for 'LOG.debug(_('
|
||||
As per our translation policy,
|
||||
https://wiki.openstack.org/wiki/LoggingStandards#Log_Translation
|
||||
we shouldn't translate debug level logs.
|
||||
* This check assumes that 'LOG' is a logger.
|
||||
* Use filename so we can start enforcing this in specific folders instead
|
||||
of needing to do so all at once.
|
||||
N319
|
||||
"""
|
||||
if logical_line.startswith("LOG.debug(_("):
|
||||
yield(0, "D706: Don't translate debug level logs")
|
||||
|
||||
|
||||
@core.flake8ext
|
||||
def check_explicit_underscore_import(logical_line, filename):
|
||||
"""Check for explicit import of the _ function
|
||||
|
||||
We need to ensure that any files that are using the _() function
|
||||
to translate logs are explicitly importing the _ function. We
|
||||
can't trust unit test to catch whether the import has been
|
||||
added so we need to check for it here.
|
||||
"""
|
||||
# Build a list of the files that have _ imported. No further
|
||||
# checking needed once it is found.
|
||||
if filename in UNDERSCORE_IMPORT_FILES:
|
||||
pass
|
||||
elif (underscore_import_check.match(logical_line) or
|
||||
custom_underscore_check.match(logical_line)):
|
||||
UNDERSCORE_IMPORT_FILES.append(filename)
|
||||
elif (translated_log.match(logical_line) or
|
||||
string_translation.match(logical_line)):
|
||||
yield(0, "D703: Found use of _() without explicit import of _!")
|
||||
|
||||
|
||||
@core.flake8ext
|
||||
def no_import_graduated_oslo_libraries(logical_line, filename):
|
||||
"""Check that we don't continue to use o.c. oslo libraries after graduation
|
||||
|
||||
After a library graduates from oslo-incubator, as we make the switch, we
|
||||
should ensure we don't continue to use the oslo-incubator versions.
|
||||
|
||||
In many cases, it's not possible to immediately remove the code from the
|
||||
openstack/common folder due to dependency issues.
|
||||
"""
|
||||
# We can't modify oslo-incubator code, so ignore it here.
|
||||
if "designate/openstack/common" in filename:
|
||||
return
|
||||
|
||||
matches = graduated_oslo_libraries_import_re.match(logical_line)
|
||||
if matches:
|
||||
yield(0, "D704: Found import of %s. This oslo library has been "
|
||||
"graduated!" % matches.group(1))
|
||||
|
||||
|
||||
@core.flake8ext
|
||||
def use_timeutils_utcnow(logical_line, filename):
|
||||
# tools are OK to use the standard datetime module
|
||||
if "/tools/" in filename:
|
||||
return
|
||||
|
||||
msg = "D705: timeutils.utcnow() must be used instead of datetime.%s()"
|
||||
|
||||
datetime_funcs = ['now', 'utcnow']
|
||||
for f in datetime_funcs:
|
||||
pos = logical_line.find('datetime.%s' % f)
|
||||
if pos != -1:
|
||||
yield (pos, msg % f)
|
||||
|
||||
|
||||
@core.flake8ext
|
||||
def check_no_basestring(logical_line):
|
||||
if re.search(r"\bbasestring\b", logical_line):
|
||||
msg = ("D707: basestring is not Python3-compatible, use "
|
||||
"str instead.")
|
||||
yield(0, msg)
|
||||
|
||||
|
||||
@core.flake8ext
|
||||
def check_python3_xrange(logical_line):
|
||||
if re.search(r"\bxrange\s*\(", logical_line):
|
||||
yield(0, "D708: Do not use xrange. Use range for "
|
||||
"large loops.")
|
||||
|
||||
|
||||
@core.flake8ext
|
||||
def check_no_log_audit(logical_line):
|
||||
"""Ensure that we are not using LOG.audit messages
|
||||
Plans are in place going forward as discussed in the following
|
||||
spec (https://review.opendev.org/#/c/132552/) to take out
|
||||
LOG.audit messages. Given that audit was a concept invented
|
||||
for OpenStack we can enforce not using it.
|
||||
"""
|
||||
if "LOG.audit(" in logical_line:
|
||||
yield(0, "D709: LOG.audit is deprecated, please use LOG.info!")
|
||||
|
||||
|
||||
@core.flake8ext
|
||||
def check_no_log_warn(logical_line):
|
||||
"""Disallow 'LOG.warn('
|
||||
|
||||
D710
|
||||
"""
|
||||
if logical_line.startswith('LOG.warn('):
|
||||
yield(0, "D710:Use LOG.warning() rather than LOG.warn()")
|
||||
|
||||
|
||||
@core.flake8ext
|
||||
def check_line_continuation_no_backslash(logical_line, tokens):
|
||||
"""D711 - Don't use backslashes for line continuation.
|
||||
|
||||
:param logical_line: The logical line to check. Not actually used.
|
||||
:param tokens: List of tokens to check.
|
||||
:returns: None if the tokens don't contain any issues, otherwise a tuple
|
||||
is yielded that contains the offending index in the logical
|
||||
line and a message describe the check validation failure.
|
||||
"""
|
||||
backslash = None
|
||||
for token_type, text, start, end, orig_line in tokens:
|
||||
m = no_line_continuation_backslash_re.match(orig_line)
|
||||
if m:
|
||||
backslash = (start[0], m.start(1))
|
||||
break
|
||||
|
||||
if backslash is not None:
|
||||
msg = 'D711 Backslash line continuations not allowed'
|
||||
yield backslash, msg
|
@ -12,7 +12,7 @@
|
||||
# License for the specific language governing permissions and limitations under
|
||||
# the License.
|
||||
|
||||
from designate_tempest_plugin.services.dns.admin.json.quotas_client import \
|
||||
QuotasClient
|
||||
from designate_tempest_plugin.services.dns.admin.json.quotas_client import (
|
||||
QuotasClient)
|
||||
|
||||
__all__ = ['QuotasClient']
|
||||
|
@ -12,35 +12,21 @@
|
||||
# License for the specific language governing permissions and limitations under
|
||||
# the License.
|
||||
|
||||
from designate_tempest_plugin.services.dns.v2.json.blacklists_client import \
|
||||
BlacklistsClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.designate_limit_client \
|
||||
import DesignateLimitClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.pool_client import \
|
||||
PoolClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.ptr_client \
|
||||
import PtrClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.quotas_client import \
|
||||
QuotasClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.recordset_client import \
|
||||
RecordsetClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.service_client import \
|
||||
ServiceClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.tld_client import TldClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.transfer_accepts_client \
|
||||
import TransferAcceptClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.transfer_request_client \
|
||||
import TransferRequestClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.tsigkey_client import \
|
||||
TsigkeyClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.zones_client import \
|
||||
ZonesClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.zone_exports_client import \
|
||||
ZoneExportsClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.zone_imports_client import \
|
||||
ZoneImportsClient
|
||||
from designate_tempest_plugin.services.dns.v2.json.api_version_client import \
|
||||
ApiVersionClient
|
||||
from .json.blacklists_client import BlacklistsClient
|
||||
from .json.designate_limit_client import DesignateLimitClient
|
||||
from .json.pool_client import PoolClient
|
||||
from .json.ptr_client import PtrClient
|
||||
from .json.quotas_client import QuotasClient
|
||||
from .json.recordset_client import RecordsetClient
|
||||
from .json.service_client import ServiceClient
|
||||
from .json.tld_client import TldClient
|
||||
from .json.transfer_accepts_client import TransferAcceptClient
|
||||
from .json.transfer_request_client import TransferRequestClient
|
||||
from .json.tsigkey_client import TsigkeyClient
|
||||
from .json.zones_client import ZonesClient
|
||||
from .json.zone_exports_client import ZoneExportsClient
|
||||
from .json.zone_imports_client import ZoneImportsClient
|
||||
from .json.api_version_client import ApiVersionClient
|
||||
|
||||
__all__ = ['BlacklistsClient', 'DesignateLimitClient', 'PoolClient',
|
||||
'PtrClient', 'QuotasClient', 'RecordsetClient', 'ServiceClient',
|
||||
|
@ -24,8 +24,8 @@ from designate_tempest_plugin.common import waiters
|
||||
from designate_tempest_plugin import data_utils as dns_data_utils
|
||||
from designate_tempest_plugin.tests import base
|
||||
|
||||
from designate_tempest_plugin.services.dns.query.query_client \
|
||||
import SingleQueryClient
|
||||
from designate_tempest_plugin.services.dns.query.query_client import (
|
||||
SingleQueryClient)
|
||||
|
||||
CONF = config.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
@ -15,8 +15,8 @@ from tempest import test
|
||||
from tempest import config
|
||||
from tempest.lib.common.utils import test_utils as utils
|
||||
|
||||
from designate_tempest_plugin.services.dns.query.query_client import \
|
||||
QueryClient
|
||||
from designate_tempest_plugin.services.dns.query.query_client import (
|
||||
QueryClient)
|
||||
from designate_tempest_plugin.tests import rbac_utils
|
||||
|
||||
|
||||
|
@ -92,8 +92,8 @@ class QuotasV2Test(base.BaseDnsV2Test):
|
||||
def _reach_quota_limit(
|
||||
self, limit_threshold, quota_type, zone=None):
|
||||
attempt_number = 0
|
||||
not_raised_msg = "Failed, expected '413 over_quota' response of " \
|
||||
"type:{} wasn't received.".format(quota_type)
|
||||
not_raised_msg = ("Failed, expected '413 over_quota' response of "
|
||||
"type:{} wasn't received.".format(quota_type))
|
||||
while attempt_number <= limit_threshold + 1:
|
||||
try:
|
||||
attempt_number += 1
|
||||
@ -136,8 +136,8 @@ class QuotasV2Test(base.BaseDnsV2Test):
|
||||
raised_err = str(e).replace(' ', '')
|
||||
if not_raised_msg in str(e):
|
||||
raise AssertionError(not_raised_msg)
|
||||
elif "'code':413" in raised_err and \
|
||||
"'type':'over_quota'" in raised_err:
|
||||
elif ("'code':413" in raised_err and
|
||||
"'type':'over_quota'" in raised_err):
|
||||
LOG.info("OK, type':'over_quota' was raised")
|
||||
break
|
||||
else:
|
||||
@ -309,10 +309,9 @@ class QuotasBoundary(base.BaseDnsV2Test, tempest.test.BaseTestCase):
|
||||
cls.quota_client = cls.os_system_admin.dns_v2.QuotasClient()
|
||||
cls.project_client = cls.os_system_admin.projects_client
|
||||
cls.zone_client = cls.os_system_admin.dns_v2.ZonesClient()
|
||||
cls.recordset_client = \
|
||||
cls.os_system_admin.dns_v2.RecordsetClient()
|
||||
cls.export_zone_client = \
|
||||
cls.os_system_admin.dns_v2.ZoneExportsClient()
|
||||
cls.recordset_client = cls.os_system_admin.dns_v2.RecordsetClient()
|
||||
cls.export_zone_client = (
|
||||
cls.os_system_admin.dns_v2.ZoneExportsClient())
|
||||
else:
|
||||
cls.quota_client = cls.os_admin.dns_v2.QuotasClient()
|
||||
cls.project_client = cls.os_admin.projects_client
|
||||
|
@ -23,8 +23,8 @@ from designate_tempest_plugin.tests import base
|
||||
from designate_tempest_plugin.common import constants as const
|
||||
from designate_tempest_plugin import data_utils as dns_data_utils
|
||||
from designate_tempest_plugin.common import waiters
|
||||
from designate_tempest_plugin.services.dns.query.query_client \
|
||||
import SingleQueryClient
|
||||
from designate_tempest_plugin.services.dns.query.query_client import (
|
||||
SingleQueryClient)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
@ -25,8 +25,8 @@ from designate_tempest_plugin import data_utils as dns_data_utils
|
||||
from designate_tempest_plugin.tests import base
|
||||
from designate_tempest_plugin.common import constants as const
|
||||
from designate_tempest_plugin.common import waiters
|
||||
from designate_tempest_plugin.services.dns.query.query_client \
|
||||
import SingleQueryClient
|
||||
from designate_tempest_plugin.services.dns.query.query_client import (
|
||||
SingleQueryClient)
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
@ -22,8 +22,8 @@ from tempest.lib import decorators
|
||||
from designate_tempest_plugin.common import constants as const
|
||||
from designate_tempest_plugin.common import waiters
|
||||
from designate_tempest_plugin import data_utils as dns_data_utils
|
||||
from designate_tempest_plugin.tests.api.v2.test_zones_exports import \
|
||||
BaseZoneExportsTest
|
||||
from designate_tempest_plugin.tests.api.v2.test_zones_exports import (
|
||||
BaseZoneExportsTest)
|
||||
|
||||
CONF = config.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
@ -17,8 +17,8 @@ from tempest.lib import decorators
|
||||
from designate_tempest_plugin.common import constants as const
|
||||
from designate_tempest_plugin.common import waiters
|
||||
from designate_tempest_plugin import data_utils as dns_data_utils
|
||||
from designate_tempest_plugin.tests.api.v2.test_zones_imports import \
|
||||
BaseZonesImportTest
|
||||
from designate_tempest_plugin.tests.api.v2.test_zones_imports import (
|
||||
BaseZonesImportTest)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
12
tox.ini
12
tox.ini
@ -105,3 +105,15 @@ extension =
|
||||
T112 = tempest.hacking.checks:dont_import_local_tempest_into_lib
|
||||
T113 = tempest.hacking.checks:dont_use_config_in_tempest_lib
|
||||
T114 = tempest.hacking.checks:use_rand_uuid_instead_of_uuid4
|
||||
D701 = checks:mutable_default_arguments
|
||||
D703 = checks:check_explicit_underscore_import
|
||||
D704 = checks:no_import_graduated_oslo_libraries
|
||||
D705 = checks:use_timeutils_utcnow
|
||||
D706 = checks:no_translate_debug_logs
|
||||
D707 = checks:check_no_basestring
|
||||
D708 = checks:check_python3_xrange
|
||||
D709 = checks:check_no_log_audit
|
||||
D710 = checks:check_no_log_warn
|
||||
D711 = checks:check_line_continuation_no_backslash
|
||||
paths = ./designate_tempest_plugin/hacking
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user