Пример #1
0
    def test_read(self):
        '''
        Test to make sure we interact with etcd correctly
        '''
        with patch('etcd.Client', autospec=True) as mock:
            etcd_client = mock.return_value
            etcd_return = MagicMock(value='salt')
            etcd_client.read.return_value = etcd_return
            client = etcd_util.EtcdClient({})

            self.assertEqual(client.read('/salt'), etcd_return)
            etcd_client.read.assert_called_with('/salt',
                                                recursive=False,
                                                wait=False,
                                                timeout=None)

            client.read('salt', True, True, 10, 5)
            etcd_client.read.assert_called_with('salt',
                                                recursive=True,
                                                wait=True,
                                                timeout=10,
                                                waitIndex=5)

            etcd_client.read.side_effect = etcd.EtcdKeyNotFound
            self.assertRaises(etcd.EtcdKeyNotFound, client.read, 'salt')

            etcd_client.read.side_effect = etcd.EtcdConnectionFailed
            self.assertRaises(etcd.EtcdConnectionFailed, client.read, 'salt')

            etcd_client.read.side_effect = etcd.EtcdValueError
            self.assertRaises(etcd.EtcdValueError, client.read, 'salt')

            etcd_client.read.side_effect = ValueError
            self.assertRaises(ValueError, client.read, 'salt')

            etcd_client.read.side_effect = ReadTimeoutError(None, None, None)
            self.assertRaises(etcd.EtcdConnectionFailed, client.read, 'salt')

            etcd_client.read.side_effect = MaxRetryError(None, None)
            self.assertRaises(etcd.EtcdConnectionFailed, client.read, 'salt')
Пример #2
0
    def test_update(self):
        with patch("etcd.Client", autospec=True) as mock:
            client = etcd_util.EtcdClient({})
            some_data = {
                "/x/y/a": "1",
                "x": {"y": {"b": "3"}},
                "m/j/": "3",
                "z": "4",
                "d": {},
            }

            result = {
                "/test/x/y/a": "1",
                "/test/x/y/b": "2",
                "/test/m/j": "3",
                "/test/z": "4",
                "/test/d": True,
            }

            flatten_result = {
                "/test/x/y/a": "1",
                "/test/x/y/b": "2",
                "/test/m/j": "3",
                "/test/z": "4",
                "/test/d": {},
            }
            client._flatten = MagicMock(return_value=flatten_result)

            self.assertEqual(client.update("/some/key", path="/blah"), None)

            with patch.object(client, "write", autospec=True) as write_mock:

                def write_return(key, val, ttl=None, directory=None):
                    return result.get(key, None)

                write_mock.side_effect = write_return
                self.assertDictEqual(client.update(some_data, path="/test"), result)
                client._flatten.assert_called_with(some_data, "/test")
                self.assertEqual(write_mock.call_count, 5)
Пример #3
0
def test_ls():
    with patch("etcd.Client") as mock:
        client = etcd_util.EtcdClient({})

        with patch.object(client, "read", autospec=True) as mock:
            c1 = MagicMock()
            c1.__iter__.return_value = [
                MagicMock(key="/x/a", value="1"),
                MagicMock(key="/x/b", value="2"),
                MagicMock(key="/x/c", dir=True),
            ]
            mock.return_value = MagicMock(children=c1)
            assert client.ls("/x") == {"/x": {"/x/a": "1", "/x/b": "2", "/x/c/": {}}}
            mock.assert_called_with("/x")

            # iter(list(Exception)) works correctly with both mock<1.1 and mock>=1.1
            mock.side_effect = iter([etcd.EtcdKeyNotFound()])
            assert client.ls("/not-found") == {}

            mock.side_effect = Exception
            with pytest.raises(Exception):
                client.tree("some-error")
Пример #4
0
    def test_tree(self):
        '''
        Test recursive gets
        '''
        with patch('etcd.Client') as mock:
            client = etcd_util.EtcdClient({})

            with patch.object(client, 'read', autospec=True) as mock:

                c1, c2 = MagicMock(), MagicMock()
                c1.__iter__.return_value = [
                    MagicMock(key='/x/a', value='1'),
                    MagicMock(key='/x/b', value='2'),
                    MagicMock(key='/x/c', dir=True)
                ]
                c2.__iter__.return_value = [MagicMock(key='/x/c/d', value='3')]
                mock.side_effect = iter(
                    [MagicMock(children=c1),
                     MagicMock(children=c2)])
                self.assertDictEqual(client.tree('/x'), {
                    'a': '1',
                    'b': '2',
                    'c': {
                        'd': '3'
                    }
                })
                mock.assert_any_call('/x')
                mock.assert_any_call('/x/c')

                # iter(list(Exception)) works correctly with both mock<1.1 and mock>=1.1
                mock.side_effect = iter([etcd.EtcdKeyNotFound()])
                self.assertEqual(client.tree('not-found'), None)

                mock.side_effect = ValueError
                self.assertEqual(client.tree('/x'), None)

                mock.side_effect = Exception
                self.assertRaises(Exception, client.tree, 'some-error')
Пример #5
0
    def test_flatten(self):
        with patch("etcd.Client", autospec=True) as mock:
            client = etcd_util.EtcdClient({})
            some_data = {
                "/x/y/a": "1",
                "x": {"y": {"b": "2"}},
                "m/j/": "3",
                "z": "4",
                "d": {},
            }

            result_path = {
                "/test/x/y/a": "1",
                "/test/x/y/b": "2",
                "/test/m/j": "3",
                "/test/z": "4",
                "/test/d": {},
            }

            result_nopath = {
                "/x/y/a": "1",
                "/x/y/b": "2",
                "/m/j": "3",
                "/z": "4",
                "/d": {},
            }

            result_root = {
                "/x/y/a": "1",
                "/x/y/b": "2",
                "/m/j": "3",
                "/z": "4",
                "/d": {},
            }

            self.assertEqual(client._flatten(some_data, path="/test"), result_path)
            self.assertEqual(client._flatten(some_data, path="/"), result_root)
            self.assertEqual(client._flatten(some_data), result_nopath)
Пример #6
0
    def test_tree(self):
        """
        Test recursive gets
        """
        with patch("etcd.Client") as mock:
            client = etcd_util.EtcdClient({})

            with patch.object(client, "read", autospec=True) as mock:

                c1, c2 = MagicMock(), MagicMock()
                c1.__iter__.return_value = [
                    MagicMock(key="/x/a", value="1"),
                    MagicMock(key="/x/b", value="2"),
                    MagicMock(key="/x/c", dir=True),
                ]
                c2.__iter__.return_value = [MagicMock(key="/x/c/d", value="3")]
                mock.side_effect = iter(
                    [MagicMock(children=c1),
                     MagicMock(children=c2)])
                self.assertDictEqual(client.tree("/x"), {
                    "a": "1",
                    "b": "2",
                    "c": {
                        "d": "3"
                    }
                })
                mock.assert_any_call("/x")
                mock.assert_any_call("/x/c")

                # iter(list(Exception)) works correctly with both mock<1.1 and mock>=1.1
                mock.side_effect = iter([etcd.EtcdKeyNotFound()])
                self.assertEqual(client.tree("not-found"), None)

                mock.side_effect = ValueError
                self.assertEqual(client.tree("/x"), None)

                mock.side_effect = Exception
                self.assertRaises(Exception, client.tree, "some-error")
Пример #7
0
    def test_watch(self):
        with patch('etcd.Client', autospec=True) as client_mock:
            client = etcd_util.EtcdClient({})

            with patch.object(client, 'read', autospec=True) as mock:
                mock.return_value = MagicMock(value='stack', key='/some-key', modifiedIndex=1, dir=False)
                self.assertDictEqual(client.watch('/some-key'),
                                     {'value': 'stack', 'key': '/some-key', 'mIndex': 1, 'changed': True, 'dir': False})
                mock.assert_called_with('/some-key', wait=True, recursive=False, timeout=0, waitIndex=None)

                mock.side_effect = iter([etcd_util.EtcdUtilWatchTimeout, mock.return_value])
                self.assertDictEqual(client.watch('/some-key'),
                                     {'value': 'stack', 'changed': False, 'mIndex': 1, 'key': '/some-key', 'dir': False})

                mock.side_effect = iter([etcd_util.EtcdUtilWatchTimeout, etcd.EtcdKeyNotFound])
                self.assertEqual(client.watch('/some-key'),
                                 {'value': None, 'changed': False, 'mIndex': 0, 'key': '/some-key', 'dir': False})

                mock.side_effect = iter([etcd_util.EtcdUtilWatchTimeout, ValueError])
                self.assertEqual(client.watch('/some-key'), {})

                mock.side_effect = None
                mock.return_value = MagicMock(value='stack', key='/some-key', modifiedIndex=1, dir=True)
                self.assertDictEqual(client.watch('/some-dir', recurse=True, timeout=5, index=10),
                                     {'value': 'stack', 'key': '/some-key', 'mIndex': 1, 'changed': True, 'dir': True})
                mock.assert_called_with('/some-dir', wait=True, recursive=True, timeout=5, waitIndex=10)

                # iter(list(Exception)) works correctly with both mock<1.1 and mock>=1.1
                mock.side_effect = iter([MaxRetryError(None, None)])
                self.assertEqual(client.watch('/some-key'), {})

                mock.side_effect = iter([etcd.EtcdConnectionFailed()])
                self.assertEqual(client.watch('/some-key'), {})

                mock.side_effect = None
                mock.return_value = None
                self.assertEqual(client.watch('/some-key'), {})
Пример #8
0
    def test_rm(self, mock):
        etcd_client = mock.return_value
        client = etcd_util.EtcdClient({})

        etcd_client.delete.return_value = True
        self.assertEqual(client.rm('/some-key'), True)
        etcd_client.delete.assert_called_with('/some-key', recursive=False)
        self.assertEqual(client.rm('/some-dir', recurse=True), True)
        etcd_client.delete.assert_called_with('/some-dir', recursive=True)

        etcd_client.delete.side_effect = etcd.EtcdNotFile()
        self.assertEqual(client.rm('/some-dir'), None)

        etcd_client.delete.side_effect = etcd.EtcdDirNotEmpty()
        self.assertEqual(client.rm('/some-key'), None)

        etcd_client.delete.side_effect = etcd.EtcdRootReadOnly()
        self.assertEqual(client.rm('/'), None)

        etcd_client.delete.side_effect = ValueError
        self.assertEqual(client.rm('/some-dir'), None)

        etcd_client.delete.side_effect = Exception
        self.assertRaises(Exception, client.rm, 'some-dir')
Пример #9
0
    def test_ls(self, mock):
        client = etcd_util.EtcdClient({})

        with patch.object(client, 'read', autospec=True) as mock:
            c1 = MagicMock()
            c1.__iter__.return_value = [
                MagicMock(key='/x/a', value='1'),
                MagicMock(key='/x/b', value='2'),
                MagicMock(key='/x/c', dir=True)
            ]
            mock.return_value = MagicMock(children=c1)
            self.assertEqual(client.ls('/x'),
                             {'/x': {
                                 '/x/a': '1',
                                 '/x/b': '2',
                                 '/x/c/': {}
                             }})
            mock.assert_called_with('/x')

            mock.side_effect = etcd.EtcdKeyNotFound()
            self.assertEqual(client.ls('/not-found'), {})

            mock.side_effect = Exception
            self.assertRaises(Exception, client.tree, 'some-error')
Пример #10
0
    def test_write(self):
        with patch('etcd.Client', autospec=True) as mock:
            client = etcd_util.EtcdClient({})
            etcd_client = mock.return_value

            etcd_client.write.return_value = MagicMock(value='salt')
            self.assertEqual(client.write('/some-key', 'salt'), 'salt')
            etcd_client.write.assert_called_with('/some-key',
                                                 'salt',
                                                 ttl=None,
                                                 dir=False)

            self.assertEqual(client.write('/some-key', 'salt', ttl=5), 'salt')
            etcd_client.write.assert_called_with('/some-key',
                                                 'salt',
                                                 ttl=5,
                                                 dir=False)

            etcd_client.write.return_value = MagicMock(dir=True)
            self.assertEqual(
                client.write('/some-dir', 'salt', ttl=0, directory=True), True)
            etcd_client.write.assert_called_with('/some-dir',
                                                 None,
                                                 ttl=0,
                                                 dir=True)

            # Check when a file is attempted to be written to a read-only root
            etcd_client.write.side_effect = etcd.EtcdRootReadOnly()
            self.assertEqual(client.write('/', 'some-val', directory=False),
                             None)

            # Check when a directory is attempted to be written to a read-only root
            etcd_client.write.side_effect = etcd.EtcdRootReadOnly()
            self.assertEqual(client.write('/', None, directory=True), None)

            # Check when a file is attempted to be written when unable to connect to the service
            etcd_client.write.side_effect = MaxRetryError(None, None)
            self.assertEqual(
                client.write('/some-key', 'some-val', directory=False), None)

            # Check when a directory is attempted to be written when unable to connect to the service
            etcd_client.write.side_effect = MaxRetryError(None, None)
            self.assertEqual(client.write('/some-dir', None, directory=True),
                             None)

            # Check when a file is attempted to be written to a directory that already exists (name-collision)
            etcd_client.write.side_effect = etcd.EtcdNotFile()
            self.assertEqual(
                client.write('/some-dir', 'some-val', directory=False), None)

            # Check when a directory is attempted to be written to a file that already exists (name-collision)
            etcd_client.write.side_effect = etcd.EtcdNotDir()
            self.assertEqual(client.write('/some-key', None, directory=True),
                             None)

            # Check when a directory is attempted to be written to a directory that already exists (update-ttl)
            etcd_client.write.side_effect = etcd.EtcdNotFile()
            self.assertEqual(client.write('/some-dir', None, directory=True),
                             True)

            etcd_client.write.side_effect = ValueError
            self.assertEqual(client.write('/some-key', 'some-val'), None)

            etcd_client.write.side_effect = Exception
            self.assertRaises(Exception, client.set, 'some-key', 'some-val')
Пример #11
0
    def test_watch(self):
        with patch("etcd.Client", autospec=True) as client_mock:
            client = etcd_util.EtcdClient({})

            with patch.object(client, "read", autospec=True) as mock:
                mock.return_value = MagicMock(
                    value="stack", key="/some-key", modifiedIndex=1, dir=False
                )
                self.assertDictEqual(
                    client.watch("/some-key"),
                    {
                        "value": "stack",
                        "key": "/some-key",
                        "mIndex": 1,
                        "changed": True,
                        "dir": False,
                    },
                )
                mock.assert_called_with(
                    "/some-key", wait=True, recursive=False, timeout=0, waitIndex=None
                )

                mock.side_effect = iter(
                    [etcd_util.EtcdUtilWatchTimeout, mock.return_value]
                )
                self.assertDictEqual(
                    client.watch("/some-key"),
                    {
                        "value": "stack",
                        "changed": False,
                        "mIndex": 1,
                        "key": "/some-key",
                        "dir": False,
                    },
                )

                mock.side_effect = iter(
                    [etcd_util.EtcdUtilWatchTimeout, etcd.EtcdKeyNotFound]
                )
                self.assertEqual(
                    client.watch("/some-key"),
                    {
                        "value": None,
                        "changed": False,
                        "mIndex": 0,
                        "key": "/some-key",
                        "dir": False,
                    },
                )

                mock.side_effect = iter([etcd_util.EtcdUtilWatchTimeout, ValueError])
                self.assertEqual(client.watch("/some-key"), {})

                mock.side_effect = None
                mock.return_value = MagicMock(
                    value="stack", key="/some-key", modifiedIndex=1, dir=True
                )
                self.assertDictEqual(
                    client.watch("/some-dir", recurse=True, timeout=5, index=10),
                    {
                        "value": "stack",
                        "key": "/some-key",
                        "mIndex": 1,
                        "changed": True,
                        "dir": True,
                    },
                )
                mock.assert_called_with(
                    "/some-dir", wait=True, recursive=True, timeout=5, waitIndex=10
                )

                # iter(list(Exception)) works correctly with both mock<1.1 and mock>=1.1
                mock.side_effect = iter([MaxRetryError(None, None)])
                self.assertEqual(client.watch("/some-key"), {})

                mock.side_effect = iter([etcd.EtcdConnectionFailed()])
                self.assertEqual(client.watch("/some-key"), {})

                mock.side_effect = None
                mock.return_value = None
                self.assertEqual(client.watch("/some-key"), {})