Add missing translation support
Update a number of files to add missing translation support. The patch adds a new hacking check - N321. This ensures that all log messages, except debug ones, have translations. A '# noqa' indicates that the validation will not be done on the specific log message. This should be used in cases where the translations do not need to be done, for example, the log message is logging raw data. Closes-bug: #1290261 Change-Id: Ib2ca0bfaaf432e15448c96619682c2cfd073fbbc
This commit is contained in:
parent
5d7ac6a928
commit
b4ef81d6a0
@ -33,6 +33,7 @@ Nova Specific Commandments
|
||||
- [N319] Validate that debug level logs are not translated.
|
||||
- [N320] Setting CONF.* attributes directly in tests is forbidden. Use
|
||||
self.flags(option=value) instead.
|
||||
- [N321] Validate that LOG messages, except debug ones, have translations
|
||||
|
||||
Creating Unit Tests
|
||||
-------------------
|
||||
|
@ -123,7 +123,7 @@ class RequestLogging(wsgi.Middleware):
|
||||
request.user_agent,
|
||||
request.content_type,
|
||||
response.content_type,
|
||||
context=ctxt)
|
||||
context=ctxt) # noqa
|
||||
|
||||
|
||||
class Lockout(wsgi.Middleware):
|
||||
|
@ -292,7 +292,7 @@ class APIRouterV3(base_wsgi.Router):
|
||||
return False
|
||||
|
||||
if not CONF.osapi_v3.enabled:
|
||||
LOG.info("V3 API has been disabled by configuration")
|
||||
LOG.info(_("V3 API has been disabled by configuration"))
|
||||
return
|
||||
|
||||
self.init_only = init_only
|
||||
|
@ -2024,7 +2024,8 @@ class ComputeManager(manager.Manager):
|
||||
except Exception:
|
||||
# Because this allocation is async any failures are likely to occur
|
||||
# when the driver accesses network_info during spawn().
|
||||
LOG.exception('Failed to allocate network(s)', instance=instance)
|
||||
LOG.exception(_('Failed to allocate network(s)'),
|
||||
instance=instance)
|
||||
msg = _('Failed to allocate the network(s), not rescheduling.')
|
||||
raise exception.BuildAbortException(instance_uuid=instance.uuid,
|
||||
reason=msg)
|
||||
|
@ -52,7 +52,7 @@ class NovaWebSocketProxy(websockify.WebSocketProxy):
|
||||
connect_info = rpcapi.check_token(ctxt, token=token)
|
||||
|
||||
if not connect_info:
|
||||
LOG.audit("Invalid Token: %s", token)
|
||||
LOG.audit(_("Invalid Token: %s"), token)
|
||||
raise Exception(_("Invalid Token"))
|
||||
|
||||
host = connect_info['host']
|
||||
@ -60,7 +60,8 @@ class NovaWebSocketProxy(websockify.WebSocketProxy):
|
||||
|
||||
# Connect to the target
|
||||
self.msg("connecting to: %s:%s" % (host, port))
|
||||
LOG.audit("connecting to: %s:%s" % (host, port))
|
||||
LOG.audit(_("connecting to: %(host)s:%(port)s"),
|
||||
{'host': host, 'port': port})
|
||||
tsock = self.socket(host, port, connect=True)
|
||||
|
||||
# Handshake as necessary
|
||||
@ -71,7 +72,7 @@ class NovaWebSocketProxy(websockify.WebSocketProxy):
|
||||
data = tsock.recv(4096, socket.MSG_PEEK)
|
||||
if data.find("\r\n\r\n") != -1:
|
||||
if not data.split("\r\n")[0].find("200"):
|
||||
LOG.audit("Invalid Connection Info %s", token)
|
||||
LOG.audit(_("Invalid Connection Info %s"), token)
|
||||
raise Exception(_("Invalid Connection Info"))
|
||||
tsock.recv(len(data))
|
||||
break
|
||||
@ -87,5 +88,6 @@ class NovaWebSocketProxy(websockify.WebSocketProxy):
|
||||
tsock.shutdown(socket.SHUT_RDWR)
|
||||
tsock.close()
|
||||
self.vmsg("%s:%s: Target closed" % (host, port))
|
||||
LOG.audit("%s:%s: Target closed" % (host, port))
|
||||
LOG.audit(_("%(host)s:%(port)s: Target closed"),
|
||||
{'host': host, 'port': port})
|
||||
raise
|
||||
|
@ -123,7 +123,7 @@ class NovaException(Exception):
|
||||
# log the issue and the kwargs
|
||||
LOG.exception(_('Exception in string format operation'))
|
||||
for name, value in kwargs.iteritems():
|
||||
LOG.error("%s: %s" % (name, value))
|
||||
LOG.error("%s: %s" % (name, value)) # noqa
|
||||
|
||||
if CONF.fatal_exception_format_errors:
|
||||
raise exc_info[0], exc_info[1], exc_info[2]
|
||||
|
@ -15,6 +15,8 @@
|
||||
|
||||
import re
|
||||
|
||||
import pep8
|
||||
|
||||
"""
|
||||
Guidelines for writing new hacking checks
|
||||
|
||||
@ -50,6 +52,8 @@ asse_equal_end_with_none_re = re.compile(
|
||||
asse_equal_start_with_none_re = re.compile(
|
||||
r"(.)*assertEqual\(None, (\w|\.|\'|\"|\[|\])+\)")
|
||||
conf_attribute_set_re = re.compile(r"CONF\.[a-z0-9_.]+\s*=\s*\w")
|
||||
log_translation = re.compile(
|
||||
r"(.)*LOG\.(audit|error|info|warn|warning|critical|exception)\(\s*('|\")")
|
||||
|
||||
|
||||
def import_no_db_in_virt(logical_line, filename):
|
||||
@ -260,6 +264,19 @@ def no_setting_conf_directly_in_tests(logical_line, filename):
|
||||
"forbidden. Use self.flags(option=value) instead")
|
||||
|
||||
|
||||
def validate_log_translations(logical_line, physical_line, filename):
|
||||
# Translations are not required in the test directory
|
||||
# and the Xen utilities
|
||||
if ("nova/tests" in filename or
|
||||
"plugins/xenserver/xenapi/etc/xapi.d" in filename):
|
||||
return
|
||||
if pep8.noqa(physical_line):
|
||||
return
|
||||
msg = "N321: Log messages require translations!"
|
||||
if log_translation.match(logical_line):
|
||||
yield (0, msg)
|
||||
|
||||
|
||||
def factory(register):
|
||||
register(import_no_db_in_virt)
|
||||
register(no_db_session_in_public_api)
|
||||
@ -274,3 +291,4 @@ def factory(register):
|
||||
register(assert_equal_none)
|
||||
register(no_translate_debug_logs)
|
||||
register(no_setting_conf_directly_in_tests)
|
||||
register(validate_log_translations)
|
||||
|
@ -144,3 +144,34 @@ class HackingTestCase(test.NoDBTestCase):
|
||||
# Shouldn't fail since not in nova/tests/
|
||||
self.assertEqual(len(list(checks.no_setting_conf_directly_in_tests(
|
||||
"CONF.option = 1", "nova/compute/foo.py"))), 0)
|
||||
|
||||
def test_log_translations(self):
|
||||
logs = ['audit', 'error', 'info', 'warn', 'warning', 'critical',
|
||||
'exception']
|
||||
levels = ['_LI', '_LW', '_LE', '_LC']
|
||||
debug = "LOG.debug('OK')"
|
||||
self.assertEqual(0,
|
||||
len(list(
|
||||
checks.validate_log_translations(debug, debug, 'f'))))
|
||||
for log in logs:
|
||||
bad = 'LOG.%s("Bad")' % log
|
||||
self.assertEqual(1,
|
||||
len(list(
|
||||
checks.validate_log_translations(bad, bad, 'f'))))
|
||||
ok = "LOG.%s(_('OK'))" % log
|
||||
self.assertEqual(0,
|
||||
len(list(
|
||||
checks.validate_log_translations(ok, ok, 'f'))))
|
||||
ok = "LOG.%s('OK') # noqa" % log
|
||||
self.assertEqual(0,
|
||||
len(list(
|
||||
checks.validate_log_translations(ok, ok, 'f'))))
|
||||
ok = "LOG.%s(variable)" % log
|
||||
self.assertEqual(0,
|
||||
len(list(
|
||||
checks.validate_log_translations(ok, ok, 'f'))))
|
||||
for level in levels:
|
||||
ok = "LOG.%s(%s('OK'))" % (log, level)
|
||||
self.assertEqual(0,
|
||||
len(list(
|
||||
checks.validate_log_translations(ok, ok, 'f'))))
|
||||
|
@ -817,8 +817,8 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver):
|
||||
|
||||
class _LibvirtDeprecatedDriver(LibvirtGenericVIFDriver):
|
||||
def __init__(self, *args, **kwargs):
|
||||
LOG.warn('VIF driver \"%s\" is marked as deprecated and will be '
|
||||
'removed in the Juno release.',
|
||||
LOG.warn(_('VIF driver \"%s\" is marked as deprecated and will be '
|
||||
'removed in the Juno release.'),
|
||||
self.__class__.__name__)
|
||||
super(_LibvirtDeprecatedDriver, self).__init__(*args, **kwargs)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user