Improve hacking and remove useless unit tests

* Remove tests/unit/aas and test/unit/fixture
  fixtures are not used so just remove them
  aas - didn't have __init__.py files so these
  tests were not executed at all. By the way
  code related to this tests was removed earlier
  in this patch:
  https://review.openstack.org/#/c/152847/

* Remove all old py3 related hacking rules
  Now we have unit & functional jobs that checks them

* Add new hacking rule that protect us from usage of '

* Unified signature of all hacking methods
  (otherwise we are not able to make decorator)

* Add hacking rules decorator for skiping 3 types of lines:
  empty, commented, and with # noqa comment

Change-Id: I6bf2cc123325a4980edeb066a6c31aa685858f5b
This commit is contained in:
Boris Pavlovic 2015-03-14 04:39:59 +03:00
parent 55e850a76e
commit b87fd91156
3 changed files with 204 additions and 402 deletions

View File

@ -21,15 +21,6 @@ Rally Specific Commandments
* [N322] - Ensure that ``assertEqual(A, None)`` and ``assertEqual(None, A)`` are not used
* [N323] - Ensure that ``assertTrue/assertFalse(A in/not in B)`` are not used with collection contents
* [N324] - Ensure that ``assertEqual(A in/not in B, True/False)`` and ``assertEqual(True/False, A in/not in B)`` are not used with collection contents
* [N33x] - Reserved for rules related to Python 3 compatibility
* [N330] - Ensure that ``dict.iterkeys()``, ``dict.itervalues()``, ``dict.iteritems()`` and ``dict.iterlist()`` are not used
* [N331] - Ensure that ``basestring`` is not used
* [N332] - Ensure that ``StringIO.StringIO`` is not used
* [N333] - Ensure that ``urlparse`` is not used
* [N334] - Ensure that ``itertools.imap`` is not used
* [N335] - Ensure that ``xrange`` is not used
* [N336] - Ensure that ``string.lowercase`` and ``string.uppercase`` are not used
* [N337] - Ensure that ``next()`` method on iterator objects is not used
* [N338] - Ensure that ``+`` operand is not used to concatenate dict.items()
* [N340] - Ensure that we are importing always ``from rally import objects``
* [N341] - Ensure that we are importing oslo_xyz packages instead of deprecated oslo.xyz ones
* [N341] - Ensure that we are importing oslo_xyz packages instead of deprecated oslo.xyz ones
* [N350] - Ensure that single quotes are not used

View File

@ -24,6 +24,7 @@ Guidelines for writing new hacking checks
"""
import functools
import re
@ -45,16 +46,18 @@ re_assert_equal_in_end_with_true_or_false = re.compile(
r"assertEqual\((\w|[][.'\"])+( not)? in (\w|[][.'\", ])+, (True|False)\)")
re_assert_equal_in_start_with_true_or_false = re.compile(
r"assertEqual\((True|False), (\w|[][.'\"])+( not)? in (\w|[][.'\", ])+\)")
re_basestring_method = re.compile(r"(^|[\s,(\[=])basestring([\s,)\]]|$)")
re_StringIO_method = re.compile(r"StringIO\.StringIO\(")
re_urlparse_method = re.compile(r"(^|[\s=])urlparse\.")
re_itertools_imap_method = re.compile(r"(^|[\s=])itertools\.imap\(")
re_xrange_method = re.compile(r"(^|[\s=])xrange\(")
re_string_lower_upper_case_method = re.compile(
r"(^|[(,\s=])string\.(lower|upper)case([)\[,\s]|$)")
re_next_on_iterator_method = re.compile(r"\.next\(\)")
re_concatenate_dict = re.compile(
r".*\.items\(\)(\s*\+\s*.*\.items\(\))+.*")
def skip_ignored_lines(func):
@functools.wraps(func)
def wrapper(logical_line, filename):
line = logical_line.strip()
if not line or line.startswith("#") or line.endswith("# noqa"):
return
yield next(func(logical_line, filename))
return wrapper
def _parse_assert_mock_str(line):
@ -67,6 +70,7 @@ def _parse_assert_mock_str(line):
return None, None, None
@skip_ignored_lines
def check_assert_methods_from_mock(logical_line, filename):
"""Ensure that ``assert_*`` methods from ``mock`` library is used correctly
@ -112,6 +116,7 @@ def check_assert_methods_from_mock(logical_line, filename):
"custom_msg": custom_msg})
@skip_ignored_lines
def check_import_of_logging(logical_line, filename):
"""Check correctness import of logging module
@ -131,7 +136,8 @@ def check_import_of_logging(logical_line, filename):
"use `rally.common.log` instead.")
def no_translate_debug_logs(logical_line):
@skip_ignored_lines
def no_translate_debug_logs(logical_line, filename):
"""Check for "LOG.debug(_("
As per our translation policy,
@ -148,6 +154,7 @@ def no_translate_debug_logs(logical_line):
yield(0, "N311 Don't translate debug level logs")
@skip_ignored_lines
def no_use_conf_debug_check(logical_line, filename):
"""Check for "cfg.CONF.debug"
@ -167,7 +174,8 @@ def no_use_conf_debug_check(logical_line, filename):
"should be used instead.")
def assert_true_instance(logical_line):
@skip_ignored_lines
def assert_true_instance(logical_line, filename):
"""Check for assertTrue(isinstance(a, b)) sentences
N320
@ -177,7 +185,8 @@ def assert_true_instance(logical_line):
"you should use assertIsInstance(a, b) instead.")
def assert_equal_type(logical_line):
@skip_ignored_lines
def assert_equal_type(logical_line, filename):
"""Check for assertEqual(type(A), B) sentences
N321
@ -187,7 +196,8 @@ def assert_equal_type(logical_line):
"you should use assertIsInstance(a, b) instead.")
def assert_equal_none(logical_line):
@skip_ignored_lines
def assert_equal_none(logical_line, filename):
"""Check for assertEqual(A, None) or assertEqual(None, A) sentences
N322
@ -200,7 +210,8 @@ def assert_equal_none(logical_line):
"instead.")
def assert_true_or_false_with_in(logical_line):
@skip_ignored_lines
def assert_true_or_false_with_in(logical_line, filename):
"""Check assertTrue/False(A in/not in B) with collection contents
Check for assertTrue/False(A in B), assertTrue/False(A not in B),
@ -217,7 +228,8 @@ def assert_true_or_false_with_in(logical_line):
" instead.")
def assert_equal_in(logical_line):
@skip_ignored_lines
def assert_equal_in(logical_line, filename):
"""Check assertEqual(A in/not in B, True/False) with collection contents
Check for assertEqual(A in B, True/False), assertEqual(True/False, A in B),
@ -234,134 +246,7 @@ def assert_equal_in(logical_line):
"collection contents.")
def check_iteritems_method(logical_line):
"""Check that collections are iterated in Python 3 compatible way
The correct forms:
six.iterkeys(collection)
six.itervalues(collection)
six.iteritems(collection)
six.iterlist(collection)
N330
"""
iter_functions = ["iterkeys()", "itervalues()",
"iteritems()", "iterlist()"]
for func in iter_functions:
pos = logical_line.find(func)
if pos != -1:
yield (pos, "N330: Use six.%(func)s(dict) rather than "
"dict.%(func)s() to iterate a collection." %
{"func": func[:-2]})
def check_basestring_method(logical_line):
"""Check if basestring is properly called for compatibility with Python 3
There is no global variable "basestring" in Python 3.The correct form
is six.string_types, instead of basestring.
N331
"""
res = re_basestring_method.search(logical_line)
if res:
yield (0, "N331: Use six.string_types rather than basestring.")
def check_StringIO_method(logical_line):
"""Check if StringIO is properly called for compatibility with Python 3
In Python 3, StringIO module is gone. The correct form is
six.moves.StringIO instead of StringIO.StringIO.
N332
"""
res = re_StringIO_method.search(logical_line)
if res:
yield (0, "N332: Use six.moves.StringIO "
"rather than StringIO.StringIO.")
def check_urlparse_method(logical_line):
"""Check if urlparse is properly called for compatibility with Python 3
The correct form is six.moves.urllib.parse instead of "urlparse".
N333
"""
res = re_urlparse_method.search(logical_line)
if res:
yield (0, "N333: Use six.moves.urllib.parse rather than urlparse.")
def check_itertools_imap_method(logical_line):
"""Check if itertools.imap is properly called for compatibility with Python 3
The correct form is six.moves.map instead of itertools.imap.
N334
"""
res = re_itertools_imap_method.search(logical_line)
if res:
yield (0, "N334: Use six.moves.map rather than itertools.imap.")
def check_xrange_method(logical_line):
"""Check if xrange is properly called for compatibility with Python 3
The correct form is six.moves.range instead of xrange.
N335
"""
res = re_xrange_method.search(logical_line)
if res:
yield (0, "N335: Use six.moves.range rather than xrange.")
def check_string_lower_upper_case_method(logical_line):
"""Check if string.lowercase and string.uppercase are properly called
In Python 3, string.lowercase and string.uppercase are gone.
The correct form is "string.ascii_lowercase" and "string.ascii_uppercase".
N336
"""
res = re_string_lower_upper_case_method.search(logical_line)
if res:
yield (0, "N336: Use string.ascii_lowercase or string.ascii_uppercase "
"rather than string.lowercase or string.uppercase.")
def check_next_on_iterator_method(logical_line):
"""Check if next() method on iterator objects are properly called
Python 3 introduced a next() function to replace the next() method on
iterator objects. Rather than calling the method on the iterator,
the next() function is called with the iterable object as it's sole
parameter, which calls the underlying __next__() method.
N337
"""
res = re_next_on_iterator_method.search(logical_line)
if res:
yield (0, "N337: Use next(iterator) rather than iterator.next().")
def check_concatenate_dict_with_plus_operand(logical_line):
"""Check if a dict is being sum with + operator
Python 3 dict.items() return a dict_items object instead of a list, and
this object, doesn't support + operator. Need to use the update method
instead in order to concatenate two dictionaries.
N338
"""
res = re_concatenate_dict.search(logical_line)
if res:
yield (0, "N338: Use update() method instead of '+'' operand to "
"concatenate dictionaries")
@skip_ignored_lines
def check_no_direct_rally_objects_import(logical_line, filename):
"""Check if rally.objects are properly imported.
@ -379,6 +264,7 @@ def check_no_direct_rally_objects_import(logical_line, filename):
"After that you can use directly objects e.g. objects.Task")
@skip_ignored_lines
def check_no_oslo_deprecated_import(logical_line, filename):
"""Check if oslo.foo packages are not imported instead of oslo_foo ones.
@ -394,6 +280,59 @@ def check_no_oslo_deprecated_import(logical_line, filename):
"instead")
@skip_ignored_lines
def check_quotes(logical_line, filename):
"""Check that single quotation marks are not used
N350
"""
in_string = False
in_multiline_string = False
single_quotas_are_used = False
check_tripple = (
lambda line, i, char: (
i + 2 < len(line) and
(char == line[i] == line[i + 1] == line[i + 2])
)
)
i = 0
while i < len(logical_line):
char = logical_line[i]
if in_string:
if char == "\"":
in_string = False
if char == "\\":
i += 1 # ignore next char
elif in_multiline_string:
if check_tripple(logical_line, i, "\""):
i += 2 # skip next 2 chars
in_multiline_string = False
elif char == "#":
break
elif char == "'":
single_quotas_are_used = True
break
elif char == "\"":
if check_tripple(logical_line, i, "\""):
in_multiline_string = True
i += 3
continue
in_string = True
i += 1
if single_quotas_are_used:
yield (i, "N350 Remove Single quotes")
def factory(register):
register(check_assert_methods_from_mock)
register(check_import_of_logging)
@ -404,14 +343,6 @@ def factory(register):
register(assert_equal_none)
register(assert_true_or_false_with_in)
register(assert_equal_in)
register(check_iteritems_method)
register(check_basestring_method)
register(check_StringIO_method)
register(check_urlparse_method)
register(check_itertools_imap_method)
register(check_xrange_method)
register(check_string_lower_upper_case_method)
register(check_next_on_iterator_method)
register(check_no_direct_rally_objects_import)
register(check_concatenate_dict_with_plus_operand)
register(check_no_oslo_deprecated_import)
register(check_quotes)

View File

@ -29,6 +29,17 @@ class HackingTestCase(test.TestCase):
self.assertIsNone(method)
self.assertIsNone(obj)
def test_skip_ignored_lines(self):
@checks.skip_ignored_lines
def any_gen(logical_line, file_name):
yield 42
self.assertEqual([], list(any_gen("fdafadfdas # noqa", "f")))
self.assertEqual([], list(any_gen(" # fdafadfdas", "f")))
self.assertEqual([], list(any_gen(" ", "f")))
self.assertEqual(42, next(any_gen("otherstuff", "f")))
def test_correct_usage_of_assert_from_mock(self):
correct_method_names = ["assert_any_call", "assert_called_once_with",
"assert_called_with", "assert_has_calls"]
@ -61,6 +72,14 @@ class HackingTestCase(test.TestCase):
self.assertEqual(4, actual_number)
self.assertTrue(actual_msg.startswith("N303"))
def _assert_good_samples(self, checker, samples, module_file="f"):
for s in samples:
self.assertEqual([], list(checker(s, module_file)), s)
def _assert_bad_samples(self, checker, samples, module_file="f"):
for s in samples:
self.assertEqual(1, len(list(checker(s, module_file))), s)
def test_check_wrong_logging_import(self):
bad_imports = ["from oslo_log import log",
"import oslo_log",
@ -84,284 +103,145 @@ class HackingTestCase(test.TestCase):
self.assertEqual([], list(checkres))
def test_no_translate_debug_logs(self):
self.assertEqual(len(list(checks.no_translate_debug_logs(
"LOG.debug(_('foo'))"))), 1)
self.assertEqual(len(list(checks.no_translate_debug_logs(
"LOG.debug('foo')"))), 0)
self.assertEqual(len(list(checks.no_translate_debug_logs(
"LOG.info(_('foo'))"))), 0)
bad_samples = ["LOG.debug(_('foo'))"]
self._assert_bad_samples(checks.no_translate_debug_logs, bad_samples)
good_samples = ["LOG.debug('foo')", "LOG.info(_('foo'))"]
self._assert_good_samples(checks.no_translate_debug_logs, good_samples)
def test_no_use_conf_debug_check(self):
self.assertEqual(len(list(checks.no_use_conf_debug_check(
"if CONF.debug:", "fakefile"))), 1)
bad_samples = [
"if CONF.debug:",
"if cfg.CONF.debug"
]
self._assert_bad_samples(checks.no_use_conf_debug_check, bad_samples)
self.assertEqual(len(list(checks.no_use_conf_debug_check(
"if cfg.CONF.debug", "fakefile"))), 1)
self.assertEqual(len(list(checks.no_use_conf_debug_check(
"if logging.is_debug()", "fakefile"))), 0)
good_samples = ["if logging.is_debug()"]
self._assert_good_samples(checks.no_use_conf_debug_check, good_samples)
def test_assert_true_instance(self):
self.assertEqual(len(list(checks.assert_true_instance(
"self.assertTrue(isinstance(e, "
"exception.BuildAbortException))"))), 1)
"exception.BuildAbortException))", "f"))), 1)
self.assertEqual(
len(list(checks.assert_true_instance("self.assertTrue()"))), 0)
0,
len(list(checks.assert_true_instance("self.assertTrue()", "f"))))
def test_assert_equal_type(self):
self.assertEqual(len(list(checks.assert_equal_type(
"self.assertEqual(type(als['QuicAssist']), list)"))), 1)
"self.assertEqual(type(als['QuicAssist']), list)", "f"))), 1)
self.assertEqual(
len(list(checks.assert_equal_type("self.assertTrue()"))), 0)
def test_check_iteritems_method(self):
self.assertEqual(len(list(checks.check_iteritems_method(
"dict.iteritems()"))), 1)
self.assertEqual(len(list(checks.check_iteritems_method(
"iteritems(dict)"))), 0)
self.assertEqual(len(list(checks.check_iteritems_method(
"dict.items()"))), 0)
def test_check_concatenate_dict_with_plus_operand(self):
self.assertEqual(len(list(
checks.check_concatenate_dict_with_plus_operand(
"dict1.items() + dict2.items()"))), 1)
self.assertEqual(len(list(
checks.check_concatenate_dict_with_plus_operand(
"dict(self.endpoint.to_dict().items() + "
"endpoint.items())"))), 1)
self.assertEqual(len(list(
checks.check_concatenate_dict_with_plus_operand(
"dict(self.endpoint.to_dict().items() + "
"endpoint.items() + something.items())"))), 1)
self.assertEqual(len(list(
checks.check_concatenate_dict_with_plus_operand(
"dict1.item() + dict2.item()"))), 0)
self.assertEqual(len(list(
checks.check_concatenate_dict_with_plus_operand(
"obj.getitems() + obj.getitems()"))), 0)
self.assertEqual(len(list(
checks.check_concatenate_dict_with_plus_operand(
"obj.getitems() + dict2.items()"))), 0)
def test_check_basestring_method(self):
self.assertEqual(len(list(checks.check_basestring_method(
"basestring"))), 1)
self.assertEqual(len(list(checks.check_basestring_method(
"six.string_types"))), 0)
def test_check_StringIO_method(self):
self.assertEqual(len(list(checks.check_StringIO_method(
"StringIO.StringIO()"))), 1)
self.assertEqual(len(list(checks.check_StringIO_method(
"six.moves.StringIO()"))), 0)
def test_check_urlparse_method(self):
self.assertEqual(len(list(checks.check_urlparse_method(
"urlparse.urlparse(url)"))), 1)
self.assertEqual(len(list(checks.check_urlparse_method(
"six.moves.urllib.parse.urlparse(url)"))), 0)
def test_check_itertools_imap_method(self):
self.assertEqual(len(list(checks.check_itertools_imap_method(
"itertools.imap()"))), 1)
self.assertEqual(len(list(checks.check_itertools_imap_method(
"six.moves.map()"))), 0)
def test_check_xrange_imap_method(self):
self.assertEqual(len(list(checks.check_xrange_method(
"xrange()"))), 1)
self.assertEqual(len(list(checks.check_xrange_method(
"six.moves.range()"))), 0)
def test_check_string_lower_upper_case_method(self):
self.assertEqual(len(list(checks.check_string_lower_upper_case_method(
"string.lowercase[:16]"))), 1)
self.assertEqual(len(list(checks.check_string_lower_upper_case_method(
"string.uppercase[:16]"))), 1)
self.assertEqual(len(list(checks.check_string_lower_upper_case_method(
"string.ascii_lowercase[:16]"))), 0)
self.assertEqual(len(list(checks.check_string_lower_upper_case_method(
"string.ascii_uppercase[:16]"))), 0)
def test_check_next_on_iterator_method(self):
self.assertEqual(len(list(checks.check_next_on_iterator_method(
"iterator.next()"))), 1)
self.assertEqual(len(list(checks.check_next_on_iterator_method(
"next(iterator)"))), 0)
len(list(checks.assert_equal_type("self.assertTrue()", "f"))), 0)
def test_assert_equal_none(self):
self.assertEqual(len(list(checks.assert_equal_none(
"self.assertEqual(A, None)"))), 1)
"self.assertEqual(A, None)", "f"))), 1)
self.assertEqual(len(list(checks.assert_equal_none(
"self.assertEqual(None, A)"))), 1)
"self.assertEqual(None, A)", "f"))), 1)
self.assertEqual(
len(list(checks.assert_equal_none("self.assertIsNone()"))), 0)
len(list(checks.assert_equal_none("self.assertIsNone()", "f"))), 0)
def test_assert_true_or_false_with_in_or_not_in(self):
self.assertEqual(len(list(checks.assert_true_or_false_with_in(
"self.assertTrue(A in B)"))), 1)
good_lines = [
"self.assertTrue(any(A > 5 for A in B))",
"self.assertTrue(any(A > 5 for A in B), 'some message')",
"self.assertFalse(some in list1 and some2 in list2)"
]
self._assert_good_samples(checks.assert_true_or_false_with_in,
good_lines)
self.assertEqual(len(list(checks.assert_true_or_false_with_in(
"self.assertFalse(A in B)"))), 1)
self.assertEqual(len(list(checks.assert_true_or_false_with_in(
"self.assertTrue(A not in B)"))), 1)
self.assertEqual(len(list(checks.assert_true_or_false_with_in(
"self.assertFalse(A not in B)"))), 1)
self.assertEqual(len(list(checks.assert_true_or_false_with_in(
"self.assertTrue(A in B, 'some message')"))), 1)
self.assertEqual(len(list(checks.assert_true_or_false_with_in(
"self.assertFalse(A in B, 'some message')"))), 1)
self.assertEqual(len(list(checks.assert_true_or_false_with_in(
"self.assertTrue(A not in B, 'some message')"))), 1)
self.assertEqual(len(list(checks.assert_true_or_false_with_in(
"self.assertFalse(A not in B, 'some message')"))), 1)
self.assertEqual(len(list(checks.assert_true_or_false_with_in(
"self.assertTrue(A in 'some string with spaces')"))), 1)
self.assertEqual(len(list(checks.assert_true_or_false_with_in(
"self.assertTrue(A in 'some string with spaces')"))), 1)
self.assertEqual(len(list(checks.assert_true_or_false_with_in(
"self.assertTrue(A in ['1', '2', '3'])"))), 1)
self.assertEqual(len(list(checks.assert_true_or_false_with_in(
"self.assertTrue(A in [1, 2, 3])"))), 1)
self.assertEqual(len(list(checks.assert_true_or_false_with_in(
"self.assertTrue(any(A > 5 for A in B))"))), 0)
self.assertEqual(len(list(checks.assert_true_or_false_with_in(
"self.assertTrue(any(A > 5 for A in B), 'some message')"))), 0)
self.assertEqual(len(list(checks.assert_true_or_false_with_in(
"self.assertFalse(some in list1 and some2 in list2)"))), 0)
bad_lines = [
"self.assertTrue(A in B)",
"self.assertFalse(A in B)",
"self.assertTrue(A not in B)",
"self.assertFalse(A not in B)",
"self.assertTrue(A in B, 'some message')",
"self.assertFalse(A in B, 'some message')",
"self.assertTrue(A not in B, 'some message')",
"self.assertFalse(A not in B, 'some message')",
"self.assertTrue(A in 'some string with spaces')",
"self.assertTrue(A in 'some string with spaces')",
"self.assertTrue(A in ['1', '2', '3'])",
"self.assertTrue(A in [1, 2, 3])"
]
self._assert_bad_samples(checks.assert_true_or_false_with_in,
bad_lines)
def test_assert_equal_in(self):
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual(a in b, True)"))), 1)
good_lines = [
"self.assertEqual(any(a==1 for a in b), True)",
"self.assertEqual(True, any(a==1 for a in b))",
"self.assertEqual(any(a==1 for a in b), False)",
"self.assertEqual(False, any(a==1 for a in b))"
]
self._assert_good_samples(checks.assert_equal_in, good_lines)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual(a not in b, True)"))), 1)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual('str' in 'string', True)"))), 1)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual('str' not in 'string', True)"))), 1)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual(any(a==1 for a in b), True)"))), 0)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual(True, a in b)"))), 1)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual(True, a not in b)"))), 1)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual(True, 'str' in 'string')"))), 1)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual(True, 'str' not in 'string')"))), 1)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual(True, any(a==1 for a in b))"))), 0)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual(a in b, False)"))), 1)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual(a not in b, False)"))), 1)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual('str' in 'string', False)"))), 1)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual('str' not in 'string', False)"))), 1)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual(any(a==1 for a in b), False)"))), 0)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual(False, a in b)"))), 1)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual(False, a not in b)"))), 1)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual(False, 'str' in 'string')"))), 1)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual(False, 'str' not in 'string')"))), 1)
self.assertEqual(len(list(checks.assert_equal_in(
"self.assertEqual(False, any(a==1 for a in b))"))), 0)
bad_lines = [
"self.assertEqual(a in b, True)",
"self.assertEqual(a not in b, True)",
"self.assertEqual('str' in 'string', True)",
"self.assertEqual('str' not in 'string', True)",
"self.assertEqual(True, a in b)",
"self.assertEqual(True, a not in b)",
"self.assertEqual(True, 'str' in 'string')",
"self.assertEqual(True, 'str' not in 'string')",
"self.assertEqual(a in b, False)",
"self.assertEqual(a not in b, False)",
"self.assertEqual('str' in 'string', False)",
"self.assertEqual('str' not in 'string', False)",
"self.assertEqual(False, a in b)",
"self.assertEqual(False, a not in b)",
"self.assertEqual(False, 'str' in 'string')",
"self.assertEqual(False, 'str' not in 'string')",
]
self._assert_bad_samples(checks.assert_equal_in, bad_lines)
def test_check_no_direct_rally_objects_import(self):
bad_imports = ["from rally.objects import task",
"import rally.objects.task"]
good_import = "from rally import objects"
self._assert_bad_samples(checks.check_no_direct_rally_objects_import,
bad_imports)
for bad_import in bad_imports:
checkres = checks.check_no_direct_rally_objects_import(bad_import,
"fakefile")
self.assertIsNotNone(next(checkres))
self._assert_good_samples(checks.check_no_direct_rally_objects_import,
bad_imports,
module_file="./rally/objects/__init__.py")
for bad_import in bad_imports:
checkres = checks.check_no_direct_rally_objects_import(
bad_import, "./rally/objects/__init__.py")
self.assertEqual([], list(checkres))
checkres = checks.check_no_direct_rally_objects_import(good_import,
"fakefile")
self.assertEqual([], list(checkres))
good_imports = ["from rally import objects"]
self._assert_good_samples(checks.check_no_direct_rally_objects_import,
good_imports)
def test_check_no_oslo_deprecated_import(self):
bad_imports = ["from oslo.config",
"import oslo.config,"
"import oslo.config",
"from oslo.db",
"import oslo.db,"
"import oslo.db",
"from oslo.i18n",
"import oslo.i18n,"
"import oslo.i18n",
"from oslo.serialization",
"import oslo.serialization,"
"import oslo.serialization",
"from oslo.utils",
"import oslo.utils,"]
"import oslo.utils"]
for bad_import in bad_imports:
checkres = checks.check_no_oslo_deprecated_import(bad_import,
"fakefile")
self.assertIsNotNone(next(checkres))
self._assert_bad_samples(checks.check_no_oslo_deprecated_import,
bad_imports)
def test_check_quotas(self):
bad_lines = [
"a = '1'",
"a = \"a\" + 'a'",
"'",
"\"\"\"\"\"\" + ''''''"
]
self._assert_bad_samples(checks.check_quotes, bad_lines)
good_lines = [
"\"'a'\" + \"\"\"a'''fdfd'''\"\"\"",
"\"fdfdfd\" + \"''''''\"",
"a = '' # noqa "
]
self._assert_good_samples(checks.check_quotes, good_lines)