Пример #1
0
 def test_get_unordered(self):
     with patch.dict(
             grainsmod.__grains__,
             OrderedDict([
                 ("a", "aval"),
                 (
                     "b",
                     OrderedDict([
                         ("z", "zval"),
                         (
                             "l1",
                             [
                                 "l21", "l22",
                                 OrderedDict([("l23", "l23val")])
                             ],
                         ),
                     ]),
                 ),
                 ("c", 8),
             ]),
     ):
         res = grainsmod.get("b", ordered=False)
         self.assertEqual(type(res), dict)
         # Check that order doesn't matter
         self.assertTrue(res == OrderedDict([
             ("l1",
              ["l21", "l22", OrderedDict([("l23", "l23val")])]),
             ("z", "zval"),
         ]))
Пример #2
0
 def test_equals(self):
     with patch.dict(
             grainsmod.__grains__,
             OrderedDict([
                 ("a", "aval"),
                 (
                     "b",
                     OrderedDict([
                         ("z", "zval"),
                         (
                             "l1",
                             [
                                 "l21", "l22",
                                 OrderedDict([("l23", "l23val")])
                             ],
                         ),
                     ]),
                 ),
                 ("c", 8),
             ]),
     ):
         res = grainsmod.equals("a", "aval")
         self.assertEqual(type(res), bool)
         self.assertTrue(res)
         res = grainsmod.equals("b:z", "zval")
         self.assertTrue(res)
         res = grainsmod.equals("b:z", "aval")
         self.assertFalse(res)
Пример #3
0
 def __init__(self, init=None, **kwargs):
     """
     Force internal dict to be ordered to ensure a consistent iteration
     order, irrespective of case.
     """
     self._data = OrderedDict()
     self.update(init or {}, **kwargs)
Пример #4
0
def parse_command_result(res, label=None):
    '''
    Parse the result of a zpool/zfs command

    .. note::

        Output on failure is rather predicatable.
        - retcode > 0
        - each 'error' is a line on stderr
        - optional 'Usage:' block under those with hits

        We simple check those and return a OrderedDict were
        we set label = True|False and error = error_messages

    '''
    ret = OrderedDict()

    if label:
        ret[label] = res['retcode'] == 0

    if res['retcode'] != 0:
        ret['error'] = []
        for error in res['stderr'].splitlines():
            if error.lower().startswith('usage:'):
                break
            if error.lower().startswith("use '-f'"):
                error = error.replace('-f', 'force=True')
            if error.lower().startswith("use '-r'"):
                error = error.replace('-r', 'recursive=True')
            ret['error'].append(error)

        if ret['error']:
            ret['error'] = "\n".join(ret['error'])
        else:
            del ret['error']

    return ret
Пример #5
0
    def test_decode(self):
        '''
        Companion to test_decode_to_str, they should both be kept up-to-date
        with one another.

        NOTE: This uses the lambda "_b" defined above in the global scope,
        which encodes a string to a bytestring, assuming utf-8.
        '''
        expected = [
            'unicode_str', 'питон', 123, 456.789, True, False, None, 'яйца',
            BYTES, [123, 456.789, 'спам', True, False, None, 'яйца', BYTES],
            (987, 654.321, 'яйца', 'яйца', None, (True, 'яйца', BYTES)), {
                'str_key': 'str_val',
                None: True,
                123: 456.789,
                'яйца': BYTES,
                'subdict': {
                    'unicode_key': 'яйца',
                    'tuple': (123, 'hello', 'world', True, 'яйца', BYTES),
                    'list': [456, 'спам', False, 'яйца', BYTES]
                }
            },
            OrderedDict([('foo', 'bar'), (123, 456), ('яйца', BYTES)])
        ]

        ret = hubblestack.utils.data.decode(self.test_data,
                                            keep=True,
                                            normalize=True,
                                            preserve_dict_class=True,
                                            preserve_tuples=True)
        self.assertEqual(ret, expected)

        # The binary data in the data structure should fail to decode, even
        # using the fallback, and raise an exception.
        self.assertRaises(UnicodeDecodeError,
                          hubblestack.utils.data.decode,
                          self.test_data,
                          keep=False,
                          normalize=True,
                          preserve_dict_class=True,
                          preserve_tuples=True)

        # Now munge the expected data so that we get what we would expect if we
        # disable preservation of dict class and tuples
        expected[10] = [
            987, 654.321, 'яйца', 'яйца', None, [True, 'яйца', BYTES]
        ]
        expected[11]['subdict']['tuple'] = [
            123, 'hello', 'world', True, 'яйца', BYTES
        ]
        expected[12] = {'foo': 'bar', 123: 456, 'яйца': BYTES}

        ret = hubblestack.utils.data.decode(self.test_data,
                                            keep=True,
                                            normalize=True,
                                            preserve_dict_class=False,
                                            preserve_tuples=False)
        self.assertEqual(ret, expected)

        # Now test single non-string, non-data-structure items, these should
        # return the same value when passed to this function
        for item in (123, 4.56, True, False, None):
            log.debug('Testing decode of %s', item)
            self.assertEqual(hubblestack.utils.data.decode(item), item)

        # Test single strings (not in a data structure)
        self.assertEqual(hubblestack.utils.data.decode('foo'), 'foo')
        self.assertEqual(hubblestack.utils.data.decode(_b('bar')), 'bar')
        self.assertEqual(hubblestack.utils.data.decode(EGGS, normalize=True),
                         'яйца')
        self.assertEqual(hubblestack.utils.data.decode(EGGS, normalize=False),
                         EGGS)

        # Test binary blob
        self.assertEqual(hubblestack.utils.data.decode(BYTES, keep=True),
                         BYTES)
        self.assertRaises(UnicodeDecodeError,
                          hubblestack.utils.data.decode,
                          BYTES,
                          keep=False)
Пример #6
0
    def test_encode(self):
        '''
        NOTE: This uses the lambda "_b" defined above in the global scope,
        which encodes a string to a bytestring, assuming utf-8.
        '''
        expected = [
            _b('unicode_str'),
            _b('питон'), 123, 456.789, True, False, None,
            _b(EGGS), BYTES,
            [123, 456.789,
             _b('спам'), True, False, None,
             _b(EGGS), BYTES],
            (987, 654.321, _b('яйца'), _b(EGGS), None,
             (True, _b(EGGS), BYTES)), {
                 _b('str_key'): _b('str_val'),
                 None: True,
                 123: 456.789,
                 _b(EGGS): BYTES,
                 _b('subdict'): {
                     _b('unicode_key'):
                     _b(EGGS),
                     _b('tuple'):
                     (123, _b('hello'), _b('world'), True, _b(EGGS), BYTES),
                     _b('list'): [456, _b('спам'), False,
                                  _b(EGGS), BYTES]
                 }
             },
            OrderedDict([(_b('foo'), _b('bar')), (123, 456),
                         (_b(EGGS), BYTES)])
        ]

        # Both keep=True and keep=False should work because the BYTES data is
        # already bytes.
        ret = hubblestack.utils.data.encode(self.test_data,
                                            keep=True,
                                            preserve_dict_class=True,
                                            preserve_tuples=True)
        self.assertEqual(ret, expected)
        ret = hubblestack.utils.data.encode(self.test_data,
                                            keep=False,
                                            preserve_dict_class=True,
                                            preserve_tuples=True)
        self.assertEqual(ret, expected)

        # Now munge the expected data so that we get what we would expect if we
        # disable preservation of dict class and tuples
        expected[10] = [
            987, 654.321,
            _b('яйца'),
            _b(EGGS), None, [True, _b(EGGS), BYTES]
        ]
        expected[11][_b('subdict')][_b('tuple')] = [
            123, _b('hello'),
            _b('world'), True,
            _b(EGGS), BYTES
        ]
        expected[12] = {_b('foo'): _b('bar'), 123: 456, _b(EGGS): BYTES}

        ret = hubblestack.utils.data.encode(self.test_data,
                                            keep=True,
                                            preserve_dict_class=False,
                                            preserve_tuples=False)
        self.assertEqual(ret, expected)
        ret = hubblestack.utils.data.encode(self.test_data,
                                            keep=False,
                                            preserve_dict_class=False,
                                            preserve_tuples=False)
        self.assertEqual(ret, expected)

        # Now test single non-string, non-data-structure items, these should
        # return the same value when passed to this function
        for item in (123, 4.56, True, False, None):
            log.debug('Testing encode of %s', item)
            self.assertEqual(hubblestack.utils.data.encode(item), item)

        # Test single strings (not in a data structure)
        self.assertEqual(hubblestack.utils.data.encode('foo'), _b('foo'))
        self.assertEqual(hubblestack.utils.data.encode(_b('bar')), _b('bar'))

        # Test binary blob, nothing should happen even when keep=False since
        # the data is already bytes
        self.assertEqual(hubblestack.utils.data.encode(BYTES, keep=True),
                         BYTES)
        self.assertEqual(hubblestack.utils.data.encode(BYTES, keep=False),
                         BYTES)
Пример #7
0
class DataTestCase(TestCase):
    test_data = [
        'unicode_str',
        _b('питон'), 123, 456.789, True, False, None, EGGS, BYTES,
        [123, 456.789,
         _b('спам'), True, False, None, EGGS, BYTES],
        (987, 654.321, _b('яйца'), EGGS, None, (True, EGGS, BYTES)), {
            _b('str_key'): _b('str_val'),
            None: True,
            123: 456.789,
            EGGS: BYTES,
            _b('subdict'): {
                'unicode_key': EGGS,
                _b('tuple'): (123, 'hello', _b('world'), True, EGGS, BYTES),
                _b('list'): [456, _b('спам'), False, EGGS, BYTES]
            }
        },
        OrderedDict([(_b('foo'), 'bar'), (123, 456), (EGGS, BYTES)])
    ]

    def test_traverse_dict_and_list(self):
        test_two_level_dict = {'foo': {'bar': 'baz'}}
        test_two_level_dict_and_list = {
            'foo': ['bar', 'baz', {
                'lorem': {
                    'ipsum': [{
                        'dolor': 'sit'
                    }]
                }
            }]
        }

        # Check traversing too far: hubblestack.utils.data.traverse_dict_and_list() returns
        # the value corresponding to a given key path, and baz is a value
        # corresponding to the key path foo:bar.
        self.assertDictEqual({'not_found': 'nope'},
                             hubblestack.utils.data.traverse_dict_and_list(
                                 test_two_level_dict, 'foo:bar:baz',
                                 {'not_found': 'nope'}))
        # Now check to ensure that foo:bar corresponds to baz
        self.assertEqual(
            'baz',
            hubblestack.utils.data.traverse_dict_and_list(
                test_two_level_dict, 'foo:bar', {'not_found': 'not_found'}))
        # Check traversing too far
        self.assertDictEqual({'not_found': 'nope'},
                             hubblestack.utils.data.traverse_dict_and_list(
                                 test_two_level_dict_and_list, 'foo:bar',
                                 {'not_found': 'nope'}))
        # Check index 1 (2nd element) of list corresponding to path 'foo'
        self.assertEqual(
            'baz',
            hubblestack.utils.data.traverse_dict_and_list(
                test_two_level_dict_and_list, 'foo:1',
                {'not_found': 'not_found'}))
        # Traverse a couple times into dicts embedded in lists
        self.assertEqual(
            'sit',
            hubblestack.utils.data.traverse_dict_and_list(
                test_two_level_dict_and_list, 'foo:lorem:ipsum:dolor',
                {'not_found': 'not_found'}))

    def test_compare_dicts(self):
        ret = hubblestack.utils.data.compare_dicts(old={'foo': 'bar'},
                                                   new={'foo': 'bar'})
        self.assertEqual(ret, {})

        ret = hubblestack.utils.data.compare_dicts(old={'foo': 'bar'},
                                                   new={'foo': 'woz'})
        expected_ret = {'foo': {'new': 'woz', 'old': 'bar'}}
        self.assertDictEqual(ret, expected_ret)

    def test_decode(self):
        '''
        Companion to test_decode_to_str, they should both be kept up-to-date
        with one another.

        NOTE: This uses the lambda "_b" defined above in the global scope,
        which encodes a string to a bytestring, assuming utf-8.
        '''
        expected = [
            'unicode_str', 'питон', 123, 456.789, True, False, None, 'яйца',
            BYTES, [123, 456.789, 'спам', True, False, None, 'яйца', BYTES],
            (987, 654.321, 'яйца', 'яйца', None, (True, 'яйца', BYTES)), {
                'str_key': 'str_val',
                None: True,
                123: 456.789,
                'яйца': BYTES,
                'subdict': {
                    'unicode_key': 'яйца',
                    'tuple': (123, 'hello', 'world', True, 'яйца', BYTES),
                    'list': [456, 'спам', False, 'яйца', BYTES]
                }
            },
            OrderedDict([('foo', 'bar'), (123, 456), ('яйца', BYTES)])
        ]

        ret = hubblestack.utils.data.decode(self.test_data,
                                            keep=True,
                                            normalize=True,
                                            preserve_dict_class=True,
                                            preserve_tuples=True)
        self.assertEqual(ret, expected)

        # The binary data in the data structure should fail to decode, even
        # using the fallback, and raise an exception.
        self.assertRaises(UnicodeDecodeError,
                          hubblestack.utils.data.decode,
                          self.test_data,
                          keep=False,
                          normalize=True,
                          preserve_dict_class=True,
                          preserve_tuples=True)

        # Now munge the expected data so that we get what we would expect if we
        # disable preservation of dict class and tuples
        expected[10] = [
            987, 654.321, 'яйца', 'яйца', None, [True, 'яйца', BYTES]
        ]
        expected[11]['subdict']['tuple'] = [
            123, 'hello', 'world', True, 'яйца', BYTES
        ]
        expected[12] = {'foo': 'bar', 123: 456, 'яйца': BYTES}

        ret = hubblestack.utils.data.decode(self.test_data,
                                            keep=True,
                                            normalize=True,
                                            preserve_dict_class=False,
                                            preserve_tuples=False)
        self.assertEqual(ret, expected)

        # Now test single non-string, non-data-structure items, these should
        # return the same value when passed to this function
        for item in (123, 4.56, True, False, None):
            log.debug('Testing decode of %s', item)
            self.assertEqual(hubblestack.utils.data.decode(item), item)

        # Test single strings (not in a data structure)
        self.assertEqual(hubblestack.utils.data.decode('foo'), 'foo')
        self.assertEqual(hubblestack.utils.data.decode(_b('bar')), 'bar')
        self.assertEqual(hubblestack.utils.data.decode(EGGS, normalize=True),
                         'яйца')
        self.assertEqual(hubblestack.utils.data.decode(EGGS, normalize=False),
                         EGGS)

        # Test binary blob
        self.assertEqual(hubblestack.utils.data.decode(BYTES, keep=True),
                         BYTES)
        self.assertRaises(UnicodeDecodeError,
                          hubblestack.utils.data.decode,
                          BYTES,
                          keep=False)

    def test_decode_to_str(self):
        '''
        Companion to test_decode, they should both be kept up-to-date with one
        another.

        NOTE: This uses the lambda "_s" defined above in the global scope,
        which converts the string/bytestring to a str type.
        '''
        expected = [
            _s('unicode_str'),
            _s('питон'), 123, 456.789, True, False, None,
            _s('яйца'), BYTES,
            [123, 456.789,
             _s('спам'), True, False, None,
             _s('яйца'), BYTES],
            (987, 654.321, _s('яйца'), _s('яйца'), None,
             (True, _s('яйца'), BYTES)), {
                 _s('str_key'): _s('str_val'),
                 None: True,
                 123: 456.789,
                 _s('яйца'): BYTES,
                 _s('subdict'): {
                     _s('unicode_key'):
                     _s('яйца'),
                     _s('tuple'):
                     (123, _s('hello'), _s('world'), True, _s('яйца'), BYTES),
                     _s('list'): [456,
                                  _s('спам'), False,
                                  _s('яйца'), BYTES]
                 }
             },
            OrderedDict([(_s('foo'), _s('bar')), (123, 456),
                         (_s('яйца'), BYTES)])
        ]

        ret = hubblestack.utils.data.decode(self.test_data,
                                            keep=True,
                                            normalize=True,
                                            preserve_dict_class=True,
                                            preserve_tuples=True,
                                            to_str=True)
        self.assertEqual(ret, expected)

        # The binary data in the data structure should fail to decode, even
        # using the fallback, and raise an exception.
        self.assertRaises(UnicodeDecodeError,
                          hubblestack.utils.data.decode,
                          self.test_data,
                          keep=False,
                          normalize=True,
                          preserve_dict_class=True,
                          preserve_tuples=True,
                          to_str=True)

        # Now munge the expected data so that we get what we would expect if we
        # disable preservation of dict class and tuples
        expected[10] = [
            987, 654.321,
            _s('яйца'),
            _s('яйца'), None, [True, _s('яйца'), BYTES]
        ]
        expected[11][_s('subdict')][_s('tuple')] = [
            123, _s('hello'),
            _s('world'), True,
            _s('яйца'), BYTES
        ]
        expected[12] = {_s('foo'): _s('bar'), 123: 456, _s('яйца'): BYTES}

        ret = hubblestack.utils.data.decode(self.test_data,
                                            keep=True,
                                            normalize=True,
                                            preserve_dict_class=False,
                                            preserve_tuples=False,
                                            to_str=True)
        self.assertEqual(ret, expected)

        # Now test single non-string, non-data-structure items, these should
        # return the same value when passed to this function
        for item in (123, 4.56, True, False, None):
            log.debug('Testing decode of %s', item)
            self.assertEqual(hubblestack.utils.data.decode(item, to_str=True),
                             item)

        # Test single strings (not in a data structure)
        self.assertEqual(hubblestack.utils.data.decode('foo', to_str=True),
                         _s('foo'))
        self.assertEqual(hubblestack.utils.data.decode(_b('bar'), to_str=True),
                         _s('bar'))

        # Test binary blob
        self.assertEqual(
            hubblestack.utils.data.decode(BYTES, keep=True, to_str=True),
            BYTES)
        self.assertRaises(UnicodeDecodeError,
                          hubblestack.utils.data.decode,
                          BYTES,
                          keep=False,
                          to_str=True)

    @skipIf(NO_MOCK, NO_MOCK_REASON)
    def test_decode_fallback(self):
        '''
        Test fallback to utf-8
        '''
        with patch.object(builtins, '__salt_system_encoding__', 'ascii'):
            self.assertEqual(hubblestack.utils.data.decode(_b('яйца')), 'яйца')

    def test_encode(self):
        '''
        NOTE: This uses the lambda "_b" defined above in the global scope,
        which encodes a string to a bytestring, assuming utf-8.
        '''
        expected = [
            _b('unicode_str'),
            _b('питон'), 123, 456.789, True, False, None,
            _b(EGGS), BYTES,
            [123, 456.789,
             _b('спам'), True, False, None,
             _b(EGGS), BYTES],
            (987, 654.321, _b('яйца'), _b(EGGS), None,
             (True, _b(EGGS), BYTES)), {
                 _b('str_key'): _b('str_val'),
                 None: True,
                 123: 456.789,
                 _b(EGGS): BYTES,
                 _b('subdict'): {
                     _b('unicode_key'):
                     _b(EGGS),
                     _b('tuple'):
                     (123, _b('hello'), _b('world'), True, _b(EGGS), BYTES),
                     _b('list'): [456, _b('спам'), False,
                                  _b(EGGS), BYTES]
                 }
             },
            OrderedDict([(_b('foo'), _b('bar')), (123, 456),
                         (_b(EGGS), BYTES)])
        ]

        # Both keep=True and keep=False should work because the BYTES data is
        # already bytes.
        ret = hubblestack.utils.data.encode(self.test_data,
                                            keep=True,
                                            preserve_dict_class=True,
                                            preserve_tuples=True)
        self.assertEqual(ret, expected)
        ret = hubblestack.utils.data.encode(self.test_data,
                                            keep=False,
                                            preserve_dict_class=True,
                                            preserve_tuples=True)
        self.assertEqual(ret, expected)

        # Now munge the expected data so that we get what we would expect if we
        # disable preservation of dict class and tuples
        expected[10] = [
            987, 654.321,
            _b('яйца'),
            _b(EGGS), None, [True, _b(EGGS), BYTES]
        ]
        expected[11][_b('subdict')][_b('tuple')] = [
            123, _b('hello'),
            _b('world'), True,
            _b(EGGS), BYTES
        ]
        expected[12] = {_b('foo'): _b('bar'), 123: 456, _b(EGGS): BYTES}

        ret = hubblestack.utils.data.encode(self.test_data,
                                            keep=True,
                                            preserve_dict_class=False,
                                            preserve_tuples=False)
        self.assertEqual(ret, expected)
        ret = hubblestack.utils.data.encode(self.test_data,
                                            keep=False,
                                            preserve_dict_class=False,
                                            preserve_tuples=False)
        self.assertEqual(ret, expected)

        # Now test single non-string, non-data-structure items, these should
        # return the same value when passed to this function
        for item in (123, 4.56, True, False, None):
            log.debug('Testing encode of %s', item)
            self.assertEqual(hubblestack.utils.data.encode(item), item)

        # Test single strings (not in a data structure)
        self.assertEqual(hubblestack.utils.data.encode('foo'), _b('foo'))
        self.assertEqual(hubblestack.utils.data.encode(_b('bar')), _b('bar'))

        # Test binary blob, nothing should happen even when keep=False since
        # the data is already bytes
        self.assertEqual(hubblestack.utils.data.encode(BYTES, keep=True),
                         BYTES)
        self.assertEqual(hubblestack.utils.data.encode(BYTES, keep=False),
                         BYTES)

    def test_encode_keep(self):
        '''
        Whereas we tested the keep argument in test_decode, it is much easier
        to do a more comprehensive test of keep in its own function where we
        can force the encoding.
        '''
        unicode_str = 'питон'
        encoding = 'ascii'

        # Test single string
        self.assertEqual(
            hubblestack.utils.data.encode(unicode_str, encoding, keep=True),
            unicode_str)
        self.assertRaises(UnicodeEncodeError,
                          hubblestack.utils.data.encode,
                          unicode_str,
                          encoding,
                          keep=False)

        data = [
            unicode_str,
            [b'foo', [unicode_str], {
                b'key': unicode_str
            }, (unicode_str, )], {
                b'list': [b'foo', unicode_str],
                b'dict': {
                    b'key': unicode_str
                },
                b'tuple': (b'foo', unicode_str)
            }, ([b'foo', unicode_str], {
                b'key': unicode_str
            }, (unicode_str, ))
        ]

        # Since everything was a bytestring aside from the bogus data, the
        # return data should be identical. We don't need to test recursive
        # decoding, that has already been tested in test_encode.
        self.assertEqual(
            hubblestack.utils.data.encode(data,
                                          encoding,
                                          keep=True,
                                          preserve_tuples=True), data)
        self.assertRaises(UnicodeEncodeError,
                          hubblestack.utils.data.encode,
                          data,
                          encoding,
                          keep=False,
                          preserve_tuples=True)

        for index, item in enumerate(data):
            self.assertEqual(
                hubblestack.utils.data.encode(data[index],
                                              encoding,
                                              keep=True,
                                              preserve_tuples=True),
                data[index])
            self.assertRaises(UnicodeEncodeError,
                              hubblestack.utils.data.encode,
                              data[index],
                              encoding,
                              keep=False,
                              preserve_tuples=True)

    @skipIf(NO_MOCK, NO_MOCK_REASON)
    def test_encode_fallback(self):
        '''
        Test fallback to utf-8
        '''
        with patch.object(builtins, '__salt_system_encoding__', 'ascii'):
            self.assertEqual(hubblestack.utils.data.encode('яйца'), _b('яйца'))
        with patch.object(builtins, '__salt_system_encoding__', 'CP1252'):
            self.assertEqual(hubblestack.utils.data.encode('Ψ'), _b('Ψ'))

    def test_repack_dict(self):
        list_of_one_element_dicts = [{
            'dict_key_1': 'dict_val_1'
        }, {
            'dict_key_2': 'dict_val_2'
        }, {
            'dict_key_3': 'dict_val_3'
        }]
        expected_ret = {
            'dict_key_1': 'dict_val_1',
            'dict_key_2': 'dict_val_2',
            'dict_key_3': 'dict_val_3'
        }
        ret = hubblestack.utils.data.repack_dictlist(list_of_one_element_dicts)
        self.assertDictEqual(ret, expected_ret)

        # Try with yaml
        yaml_key_val_pair = '- key1: val1'
        ret = hubblestack.utils.data.repack_dictlist(yaml_key_val_pair)
        self.assertDictEqual(ret, {'key1': 'val1'})

        # Make sure we handle non-yaml junk data
        ret = hubblestack.utils.data.repack_dictlist(LOREM_IPSUM)
        self.assertDictEqual(ret, {})

    def test_stringify(self):
        self.assertRaises(TypeError, hubblestack.utils.data.stringify, 9)
        self.assertEqual(
            hubblestack.utils.data.stringify(
                ['one', 'two', str('three'), 4,
                 5]),  # future lint: disable=blacklisted-function
            ['one', 'two', 'three', '4', '5'])

    def test_subdict_match(self):
        test_two_level_dict = {"foo": {"bar": "baz"}}
        test_two_level_comb_dict = {"foo": {"bar": "baz:woz"}}
        test_two_level_dict_and_list = {
            "abc": ["def", "ghi", {
                "lorem": {
                    "ipsum": [{
                        "dolor": "sit"
                    }]
                }
            }],
        }
        test_three_level_dict = {"a": {"b": {"c": "v"}}}

        self.assertTrue(
            hubblestack.utils.data.subdict_match(test_two_level_dict,
                                                 "foo:bar:baz"))
        # In test_two_level_comb_dict, 'foo:bar' corresponds to 'baz:woz', not
        # 'baz'. This match should return False.
        self.assertFalse(
            hubblestack.utils.data.subdict_match(test_two_level_comb_dict,
                                                 "foo:bar:baz"))
        # This tests matching with the delimiter in the value part (in other
        # words, that the path 'foo:bar' corresponds to the string 'baz:woz').
        self.assertTrue(
            hubblestack.utils.data.subdict_match(test_two_level_comb_dict,
                                                 "foo:bar:baz:woz"))
        # This would match if test_two_level_comb_dict['foo']['bar'] was equal
        # to 'baz:woz:wiz', or if there was more deep nesting. But it does not,
        # so this should return False.
        self.assertFalse(
            hubblestack.utils.data.subdict_match(test_two_level_comb_dict,
                                                 "foo:bar:baz:woz:wiz"))
        # This tests for cases when a key path corresponds to a list. The
        # value part 'ghi' should be successfully matched as it is a member of
        # the list corresponding to key path 'abc'. It is somewhat a
        # duplication of a test within test_traverse_dict_and_list, but
        # hubblestack.utils.data.subdict_match() does more than just invoke
        # hubblestack.utils.traverse_list_and_dict() so this particular assertion is a
        # sanity check.
        self.assertTrue(
            hubblestack.utils.data.subdict_match(test_two_level_dict_and_list,
                                                 "abc:ghi"))
        # This tests the use case of a dict embedded in a list, embedded in a
        # list, embedded in a dict. This is a rather absurd case, but it
        # confirms that match recursion works properly.
        self.assertTrue(
            hubblestack.utils.data.subdict_match(test_two_level_dict_and_list,
                                                 "abc:lorem:ipsum:dolor:sit"))
        # Test four level dict match for reference
        self.assertTrue(
            hubblestack.utils.data.subdict_match(test_three_level_dict,
                                                 "a:b:c:v"))
        # Test regression in 2015.8 where 'a:c:v' would match 'a:b:c:v'
        self.assertFalse(
            hubblestack.utils.data.subdict_match(test_three_level_dict,
                                                 "a:c:v"))
        # Test wildcard match
        self.assertTrue(
            hubblestack.utils.data.subdict_match(test_three_level_dict,
                                                 "a:*:c:v"))

    def test_subdict_match_with_wildcards(self):
        """
        Tests subdict matching when wildcards are used in the expression
        """
        data = {
            "a": {
                "b": {
                    "ç": "d",
                    "é": ["eff", "gee", "8ch"],
                    "ĩ": {
                        "j": "k"
                    }
                }
            }
        }
        assert hubblestack.utils.data.subdict_match(data, "*:*:*:*")
        assert hubblestack.utils.data.subdict_match(data, "a:*:*:*")
        assert hubblestack.utils.data.subdict_match(data, "a:b:*:*")
        assert hubblestack.utils.data.subdict_match(data, "a:b:ç:*")
        assert hubblestack.utils.data.subdict_match(data, "a:b:*:d")
        assert hubblestack.utils.data.subdict_match(data, "a:*:ç:d")
        assert hubblestack.utils.data.subdict_match(data, "*:b:ç:d")
        assert hubblestack.utils.data.subdict_match(data, "*:*:ç:d")
        assert hubblestack.utils.data.subdict_match(data, "*:*:*:d")
        assert hubblestack.utils.data.subdict_match(data, "a:*:*:d")
        assert hubblestack.utils.data.subdict_match(data, "a:b:*:ef*")
        assert hubblestack.utils.data.subdict_match(data, "a:b:*:g*")
        assert hubblestack.utils.data.subdict_match(data, "a:b:*:j:*")
        assert hubblestack.utils.data.subdict_match(data, "a:b:*:j:k")
        assert hubblestack.utils.data.subdict_match(data, "a:b:*:*:k")
        assert hubblestack.utils.data.subdict_match(data, "a:b:*:*:*")
Пример #8
0
    def test_decode_to_str(self):
        '''
        Companion to test_decode, they should both be kept up-to-date with one
        another.

        NOTE: This uses the lambda "_s" defined above in the global scope,
        which converts the string/bytestring to a str type.
        '''
        expected = [
            _s('unicode_str'),
            _s('питон'), 123, 456.789, True, False, None,
            _s('яйца'), BYTES,
            [123, 456.789,
             _s('спам'), True, False, None,
             _s('яйца'), BYTES],
            (987, 654.321, _s('яйца'), _s('яйца'), None,
             (True, _s('яйца'), BYTES)), {
                 _s('str_key'): _s('str_val'),
                 None: True,
                 123: 456.789,
                 _s('яйца'): BYTES,
                 _s('subdict'): {
                     _s('unicode_key'):
                     _s('яйца'),
                     _s('tuple'):
                     (123, _s('hello'), _s('world'), True, _s('яйца'), BYTES),
                     _s('list'): [456,
                                  _s('спам'), False,
                                  _s('яйца'), BYTES]
                 }
             },
            OrderedDict([(_s('foo'), _s('bar')), (123, 456),
                         (_s('яйца'), BYTES)])
        ]

        ret = hubblestack.utils.data.decode(self.test_data,
                                            keep=True,
                                            normalize=True,
                                            preserve_dict_class=True,
                                            preserve_tuples=True,
                                            to_str=True)
        self.assertEqual(ret, expected)

        # The binary data in the data structure should fail to decode, even
        # using the fallback, and raise an exception.
        self.assertRaises(UnicodeDecodeError,
                          hubblestack.utils.data.decode,
                          self.test_data,
                          keep=False,
                          normalize=True,
                          preserve_dict_class=True,
                          preserve_tuples=True,
                          to_str=True)

        # Now munge the expected data so that we get what we would expect if we
        # disable preservation of dict class and tuples
        expected[10] = [
            987, 654.321,
            _s('яйца'),
            _s('яйца'), None, [True, _s('яйца'), BYTES]
        ]
        expected[11][_s('subdict')][_s('tuple')] = [
            123, _s('hello'),
            _s('world'), True,
            _s('яйца'), BYTES
        ]
        expected[12] = {_s('foo'): _s('bar'), 123: 456, _s('яйца'): BYTES}

        ret = hubblestack.utils.data.decode(self.test_data,
                                            keep=True,
                                            normalize=True,
                                            preserve_dict_class=False,
                                            preserve_tuples=False,
                                            to_str=True)
        self.assertEqual(ret, expected)

        # Now test single non-string, non-data-structure items, these should
        # return the same value when passed to this function
        for item in (123, 4.56, True, False, None):
            log.debug('Testing decode of %s', item)
            self.assertEqual(hubblestack.utils.data.decode(item, to_str=True),
                             item)

        # Test single strings (not in a data structure)
        self.assertEqual(hubblestack.utils.data.decode('foo', to_str=True),
                         _s('foo'))
        self.assertEqual(hubblestack.utils.data.decode(_b('bar'), to_str=True),
                         _s('bar'))

        # Test binary blob
        self.assertEqual(
            hubblestack.utils.data.decode(BYTES, keep=True, to_str=True),
            BYTES)
        self.assertRaises(UnicodeDecodeError,
                          hubblestack.utils.data.decode,
                          BYTES,
                          keep=False,
                          to_str=True)
Пример #9
0
# -*- coding: utf-8 -*-
'''
Application Kinds of Hubble.
These are used to indicate what kind of Application is using RAET
'''
from collections import namedtuple
from hubblestack.utils.odict import OrderedDict

# Python equivalent of an enum
APPL_KINDS = OrderedDict([('master', 0),
                          ('minion', 1),
                          ('syndic', 2),
                          ('caller', 3)])
APPL_KIND_NAMES = OrderedDict((v, k) for k, v in list(APPL_KINDS.items()))  # inverse map
ApplKind = namedtuple('ApplKind', list(APPL_KINDS.keys()))
applKinds = ApplKind(**APPL_KINDS)