123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557 |
- # -*- coding: utf-8 -*-
- from __future__ import absolute_import, print_function, unicode_literals
- import re
- import sys
- import textwrap
- # Import Salt libs
- from tests.support.mock import patch
- from tests.support.unit import TestCase, LOREM_IPSUM
- import salt.utils.stringutils
- # Import 3rd-party libs
- from salt.ext import six
- from salt.ext.six.moves import builtins, range # pylint: disable=redefined-builtin
- UNICODE = '中国語 (繁体)'
- STR = BYTES = UNICODE.encode('utf-8')
- # This is an example of a unicode string with й constructed using two separate
- # code points. Do not modify it.
- EGGS = '\u044f\u0438\u0306\u0446\u0430'
- LATIN1_UNICODE = 'räksmörgås'
- LATIN1_BYTES = LATIN1_UNICODE.encode('latin-1')
- DOUBLE_TXT = '''\
- # set variable identifying the chroot you work in (used in the prompt below)
- if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then
- debian_chroot=$(cat /etc/debian_chroot)
- fi
- '''
- SINGLE_TXT = '''\
- # set variable identifying the chroot you work in (used in the prompt below)
- if [ -z '$debian_chroot' ] && [ -r /etc/debian_chroot ]; then
- debian_chroot=$(cat /etc/debian_chroot)
- fi
- '''
- SINGLE_DOUBLE_TXT = '''\
- # set variable identifying the chroot you work in (used in the prompt below)
- if [ -z '$debian_chroot' ] && [ -r /etc/debian_chroot ]; then
- debian_chroot=$(cat /etc/debian_chroot)
- fi
- # set variable identifying the chroot you work in (used in the prompt below)
- if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then
- debian_chroot=$(cat /etc/debian_chroot)
- fi
- '''
- SINGLE_DOUBLE_SAME_LINE_TXT = '''\
- # set variable identifying the chroot you work in (used in the prompt below)
- if [ -z '$debian_chroot' ] && [ -r "/etc/debian_chroot" ]; then
- debian_chroot=$(cat /etc/debian_chroot)
- fi
- '''
- MATCH = '''\
- # set variable identifying the chroot you work in (used in the prompt below)
- if [ -z '$debian_chroot' ] && [ -r /etc/debian_chroot ]; then
- debian_chroot=$(cat /etc/debian_chroot)
- fi
- # set variable identifying the chroot you work in (used in the prompt below)
- if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then
- debian_chroot=$(cat /etc/debian_chroot)
- fi
- # set variable identifying the chroot you work in (used in the prompt below)
- if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then
- debian_chroot=$(cat /etc/debian_chroot)
- fi
- # set variable identifying the chroot you work in (used in the prompt below)
- if [ -z '$debian_chroot' ] && [ -r /etc/debian_chroot ]; then
- debian_chroot=$(cat /etc/debian_chroot)
- fi
- # set variable identifying the chroot you work in (used in the prompt below)
- if [ -z '$debian_chroot' ] && [ -r "/etc/debian_chroot" ]; then
- debian_chroot=$(cat /etc/debian_chroot)
- fi
- '''
- class TestBuildWhitespaceRegex(TestCase):
- def test_single_quotes(self):
- regex = salt.utils.stringutils.build_whitespace_split_regex(SINGLE_TXT)
- self.assertTrue(re.search(regex, MATCH))
- def test_double_quotes(self):
- regex = salt.utils.stringutils.build_whitespace_split_regex(DOUBLE_TXT)
- self.assertTrue(re.search(regex, MATCH))
- def test_single_and_double_quotes(self):
- regex = salt.utils.stringutils.build_whitespace_split_regex(SINGLE_DOUBLE_TXT)
- self.assertTrue(re.search(regex, MATCH))
- def test_issue_2227(self):
- regex = salt.utils.stringutils.build_whitespace_split_regex(SINGLE_DOUBLE_SAME_LINE_TXT)
- self.assertTrue(re.search(regex, MATCH))
- class StringutilsTestCase(TestCase):
- def test_contains_whitespace(self):
- does_contain_whitespace = 'A brown fox jumped over the red hen.'
- does_not_contain_whitespace = 'Abrownfoxjumpedovertheredhen.'
- self.assertTrue(salt.utils.stringutils.contains_whitespace(does_contain_whitespace))
- self.assertFalse(salt.utils.stringutils.contains_whitespace(does_not_contain_whitespace))
- def test_to_num(self):
- self.assertEqual(7, salt.utils.stringutils.to_num('7'))
- self.assertIsInstance(salt.utils.stringutils.to_num('7'), int)
- self.assertEqual(7, salt.utils.stringutils.to_num('7.0'))
- self.assertIsInstance(salt.utils.stringutils.to_num('7.0'), float)
- self.assertEqual(salt.utils.stringutils.to_num('Seven'), 'Seven')
- self.assertIsInstance(salt.utils.stringutils.to_num('Seven'), six.text_type)
- def test_to_none(self):
- self.assertIsNone(salt.utils.stringutils.to_none(''))
- self.assertIsNone(salt.utils.stringutils.to_none(' '))
- # Ensure that we do not inadvertently convert certain strings or 0 to None
- self.assertIsNotNone(salt.utils.stringutils.to_none('None'))
- self.assertIsNotNone(salt.utils.stringutils.to_none(0))
- def test_is_binary(self):
- self.assertFalse(salt.utils.stringutils.is_binary(LOREM_IPSUM))
- # Also test bytestring
- self.assertFalse(
- salt.utils.stringutils.is_binary(
- salt.utils.stringutils.is_binary(LOREM_IPSUM)
- )
- )
- zero_str = '{0}{1}'.format(LOREM_IPSUM, '\0')
- self.assertTrue(salt.utils.stringutils.is_binary(zero_str))
- # Also test bytestring
- self.assertTrue(
- salt.utils.stringutils.is_binary(
- salt.utils.stringutils.to_bytes(zero_str)
- )
- )
- # To to ensure safe exit if str passed doesn't evaluate to True
- self.assertFalse(salt.utils.stringutils.is_binary(''))
- self.assertFalse(salt.utils.stringutils.is_binary(b''))
- nontext = 3 * (''.join([chr(x) for x in range(1, 32) if x not in (8, 9, 10, 12, 13)]))
- almost_bin_str = '{0}{1}'.format(LOREM_IPSUM[:100], nontext[:42])
- self.assertFalse(salt.utils.stringutils.is_binary(almost_bin_str))
- # Also test bytestring
- self.assertFalse(
- salt.utils.stringutils.is_binary(
- salt.utils.stringutils.to_bytes(almost_bin_str)
- )
- )
- bin_str = almost_bin_str + '\x01'
- self.assertTrue(salt.utils.stringutils.is_binary(bin_str))
- # Also test bytestring
- self.assertTrue(
- salt.utils.stringutils.is_binary(
- salt.utils.stringutils.to_bytes(bin_str)
- )
- )
- def test_to_str(self):
- for x in (123, (1, 2, 3), [1, 2, 3], {1: 23}, None):
- self.assertRaises(TypeError, salt.utils.stringutils.to_str, x)
- if six.PY3:
- self.assertEqual(salt.utils.stringutils.to_str('plugh'), 'plugh')
- self.assertEqual(salt.utils.stringutils.to_str('áéíóúý', 'utf-8'), 'áéíóúý')
- self.assertEqual(salt.utils.stringutils.to_str(BYTES, 'utf-8'), UNICODE)
- self.assertEqual(salt.utils.stringutils.to_str(bytearray(BYTES), 'utf-8'), UNICODE)
- # Test situation when a minion returns incorrect utf-8 string because of... million reasons
- ut2 = b'\x9c'
- self.assertRaises(UnicodeDecodeError, salt.utils.stringutils.to_str, ut2, 'utf-8')
- self.assertEqual(salt.utils.stringutils.to_str(ut2, 'utf-8', 'replace'), u'\ufffd')
- self.assertRaises(UnicodeDecodeError, salt.utils.stringutils.to_str, bytearray(ut2), 'utf-8')
- self.assertEqual(salt.utils.stringutils.to_str(bytearray(ut2), 'utf-8', 'replace'), u'\ufffd')
- else:
- self.assertEqual(salt.utils.stringutils.to_str('plugh'), str('plugh')) # future lint: disable=blacklisted-function
- self.assertEqual(salt.utils.stringutils.to_str('áéíóúý', 'utf-8'), 'áéíóúý'.encode('utf-8'))
- self.assertEqual(salt.utils.stringutils.to_str(UNICODE, 'utf-8'), STR)
- self.assertEqual(salt.utils.stringutils.to_str(bytearray(STR), 'utf-8'), STR)
- # Test utf-8 fallback with Windows default codepage
- with patch.object(builtins, '__salt_system_encoding__', 'CP1252'):
- self.assertEqual(salt.utils.stringutils.to_str('Ψ'), 'Ψ'.encode('utf-8'))
- def test_to_bytes(self):
- for x in (123, (1, 2, 3), [1, 2, 3], {1: 23}, None):
- self.assertRaises(TypeError, salt.utils.stringutils.to_bytes, x)
- if six.PY3:
- self.assertEqual(salt.utils.stringutils.to_bytes('xyzzy'), b'xyzzy')
- self.assertEqual(salt.utils.stringutils.to_bytes(BYTES), BYTES)
- self.assertEqual(salt.utils.stringutils.to_bytes(bytearray(BYTES)), BYTES)
- self.assertEqual(salt.utils.stringutils.to_bytes(UNICODE, 'utf-8'), BYTES)
- # Test utf-8 fallback with ascii default encoding
- with patch.object(builtins, '__salt_system_encoding__', 'ascii'):
- self.assertEqual(salt.utils.stringutils.to_bytes('Ψ'), b'\xce\xa8')
- else:
- self.assertEqual(salt.utils.stringutils.to_bytes('xyzzy'), 'xyzzy')
- self.assertEqual(salt.utils.stringutils.to_bytes(BYTES), BYTES)
- self.assertEqual(salt.utils.stringutils.to_bytes(bytearray(BYTES)), BYTES)
- self.assertEqual(salt.utils.stringutils.to_bytes(UNICODE, 'utf-8'), BYTES)
- def test_to_unicode(self):
- self.assertEqual(
- salt.utils.stringutils.to_unicode(
- EGGS,
- normalize=True
- ),
- 'яйца'
- )
- self.assertNotEqual(
- salt.utils.stringutils.to_unicode(
- EGGS,
- normalize=False
- ),
- 'яйца'
- )
- self.assertEqual(
- salt.utils.stringutils.to_unicode(
- LATIN1_BYTES, encoding='latin-1'
- ),
- LATIN1_UNICODE
- )
- if six.PY3:
- self.assertEqual(salt.utils.stringutils.to_unicode('plugh'), 'plugh')
- self.assertEqual(salt.utils.stringutils.to_unicode('áéíóúý'), 'áéíóúý')
- self.assertEqual(salt.utils.stringutils.to_unicode(BYTES, 'utf-8'), UNICODE)
- self.assertEqual(salt.utils.stringutils.to_unicode(bytearray(BYTES), 'utf-8'), UNICODE)
- else:
- self.assertEqual(salt.utils.stringutils.to_unicode(str('xyzzy'), 'utf-8'), 'xyzzy') # future lint: disable=blacklisted-function
- self.assertEqual(salt.utils.stringutils.to_unicode(BYTES, 'utf-8'), UNICODE)
- # Test that unicode chars are decoded properly even when using
- # locales which are not UTF-8 compatible
- with patch.object(builtins, '__salt_system_encoding__', 'ascii'):
- self.assertEqual(salt.utils.stringutils.to_unicode('Ψ'.encode('utf-8')), 'Ψ')
- with patch.object(builtins, '__salt_system_encoding__', 'CP1252'):
- self.assertEqual(salt.utils.stringutils.to_unicode('Ψ'.encode('utf-8')), 'Ψ')
- def test_to_unicode_multi_encoding(self):
- result = salt.utils.stringutils.to_unicode(LATIN1_BYTES, encoding=('utf-8', 'latin1'))
- assert result == LATIN1_UNICODE
- def test_build_whitespace_split_regex(self):
- # With 3.7+, re.escape only escapes special characters, no longer
- # escaping all characters other than ASCII letters, numbers and
- # underscores. This includes commas.
- if sys.version_info >= (3, 7):
- expected_regex = '(?m)^(?:[\\s]+)?Lorem(?:[\\s]+)?ipsum(?:[\\s]+)?dolor(?:[\\s]+)?sit(?:[\\s]+)?amet,' \
- '(?:[\\s]+)?$'
- else:
- expected_regex = '(?m)^(?:[\\s]+)?Lorem(?:[\\s]+)?ipsum(?:[\\s]+)?dolor(?:[\\s]+)?sit(?:[\\s]+)?amet\\,' \
- '(?:[\\s]+)?$'
- ret = salt.utils.stringutils.build_whitespace_split_regex(' '.join(LOREM_IPSUM.split()[:5]))
- self.assertEqual(ret, expected_regex)
- def test_get_context(self):
- expected_context = textwrap.dedent('''\
- ---
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque eget urna a arcu lacinia sagittis.
- Sed scelerisque, lacus eget malesuada vestibulum, justo diam facilisis tortor, in sodales dolor
- [...]
- ---''')
- ret = salt.utils.stringutils.get_context(LOREM_IPSUM, 1, num_lines=1)
- self.assertEqual(ret, expected_context)
- def test_get_context_has_enough_context(self):
- template = '1\n2\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\ne\nf'
- context = salt.utils.stringutils.get_context(template, 8)
- expected = '---\n[...]\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\n[...]\n---'
- self.assertEqual(expected, context)
- def test_get_context_at_top_of_file(self):
- template = '1\n2\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\ne\nf'
- context = salt.utils.stringutils.get_context(template, 1)
- expected = '---\n1\n2\n3\n4\n5\n6\n[...]\n---'
- self.assertEqual(expected, context)
- def test_get_context_at_bottom_of_file(self):
- template = '1\n2\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\ne\nf'
- context = salt.utils.stringutils.get_context(template, 15)
- expected = '---\n[...]\na\nb\nc\nd\ne\nf\n---'
- self.assertEqual(expected, context)
- def test_get_context_2_context_lines(self):
- template = '1\n2\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\ne\nf'
- context = salt.utils.stringutils.get_context(template, 8, num_lines=2)
- expected = '---\n[...]\n6\n7\n8\n9\na\n[...]\n---'
- self.assertEqual(expected, context)
- def test_get_context_with_marker(self):
- template = '1\n2\n3\n4\n5\n6\n7\n8\n9\na\nb\nc\nd\ne\nf'
- context = salt.utils.stringutils.get_context(template, 8, num_lines=2, marker=' <---')
- expected = '---\n[...]\n6\n7\n8 <---\n9\na\n[...]\n---'
- self.assertEqual(expected, context)
- def test_expr_match(self):
- val = 'foo/bar/baz'
- # Exact match
- self.assertTrue(salt.utils.stringutils.expr_match(val, val))
- # Glob match
- self.assertTrue(salt.utils.stringutils.expr_match(val, 'foo/*/baz'))
- # Glob non-match
- self.assertFalse(salt.utils.stringutils.expr_match(val, 'foo/*/bar'))
- # Regex match
- self.assertTrue(salt.utils.stringutils.expr_match(val, r'foo/\w+/baz'))
- # Regex non-match
- self.assertFalse(salt.utils.stringutils.expr_match(val, r'foo/\w/baz'))
- def test_check_whitelist_blacklist(self):
- '''
- Ensure that whitelist matching works on both PY2 and PY3
- '''
- whitelist = ['one/two/three', r'web[0-9]']
- blacklist = ['four/five/six', r'web[5-9]']
- # Tests with string whitelist/blacklist
- self.assertFalse(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web_one',
- whitelist=whitelist[1],
- blacklist=None,
- )
- )
- self.assertFalse(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web_one',
- whitelist=whitelist[1],
- blacklist=[],
- )
- )
- self.assertTrue(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web1',
- whitelist=whitelist[1],
- blacklist=None,
- )
- )
- self.assertTrue(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web1',
- whitelist=whitelist[1],
- blacklist=[],
- )
- )
- self.assertFalse(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web5',
- whitelist=None,
- blacklist=blacklist[1],
- )
- )
- self.assertFalse(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web5',
- whitelist=[],
- blacklist=blacklist[1],
- )
- )
- self.assertTrue(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web_five',
- whitelist=None,
- blacklist=blacklist[1],
- )
- )
- self.assertTrue(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web_five',
- whitelist=[],
- blacklist=blacklist[1],
- )
- )
- self.assertFalse(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web5',
- whitelist=whitelist[1],
- blacklist=blacklist[1],
- )
- )
- self.assertTrue(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web4',
- whitelist=whitelist[1],
- blacklist=blacklist[1],
- )
- )
- # Tests with list whitelist/blacklist
- self.assertFalse(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web_one',
- whitelist=whitelist,
- blacklist=None,
- )
- )
- self.assertFalse(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web_one',
- whitelist=whitelist,
- blacklist=[],
- )
- )
- self.assertTrue(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web1',
- whitelist=whitelist,
- blacklist=None,
- )
- )
- self.assertTrue(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web1',
- whitelist=whitelist,
- blacklist=[],
- )
- )
- self.assertFalse(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web5',
- whitelist=None,
- blacklist=blacklist,
- )
- )
- self.assertFalse(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web5',
- whitelist=[],
- blacklist=blacklist,
- )
- )
- self.assertTrue(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web_five',
- whitelist=None,
- blacklist=blacklist,
- )
- )
- self.assertTrue(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web_five',
- whitelist=[],
- blacklist=blacklist,
- )
- )
- self.assertFalse(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web5',
- whitelist=whitelist,
- blacklist=blacklist,
- )
- )
- self.assertTrue(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web4',
- whitelist=whitelist,
- blacklist=blacklist,
- )
- )
- # Tests with set whitelist/blacklist
- self.assertFalse(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web_one',
- whitelist=set(whitelist),
- blacklist=None,
- )
- )
- self.assertFalse(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web_one',
- whitelist=set(whitelist),
- blacklist=set(),
- )
- )
- self.assertTrue(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web1',
- whitelist=set(whitelist),
- blacklist=None,
- )
- )
- self.assertTrue(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web1',
- whitelist=set(whitelist),
- blacklist=set(),
- )
- )
- self.assertFalse(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web5',
- whitelist=None,
- blacklist=set(blacklist),
- )
- )
- self.assertFalse(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web5',
- whitelist=set(),
- blacklist=set(blacklist),
- )
- )
- self.assertTrue(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web_five',
- whitelist=None,
- blacklist=set(blacklist),
- )
- )
- self.assertTrue(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web_five',
- whitelist=set(),
- blacklist=set(blacklist),
- )
- )
- self.assertFalse(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web5',
- whitelist=set(whitelist),
- blacklist=set(blacklist),
- )
- )
- self.assertTrue(
- salt.utils.stringutils.check_whitelist_blacklist(
- 'web4',
- whitelist=set(whitelist),
- blacklist=set(blacklist),
- )
- )
- # Test with invalid type for whitelist/blacklist
- self.assertRaises(
- TypeError,
- salt.utils.stringutils.check_whitelist_blacklist,
- 'foo', whitelist=123
- )
- self.assertRaises(
- TypeError,
- salt.utils.stringutils.check_whitelist_blacklist,
- 'foo', blacklist=123
- )
|