From 11cf6c43f1f737be29a175d40eca4b714ef82548 Mon Sep 17 00:00:00 2001 From: Shaun Crampton Date: Tue, 10 Apr 2018 15:17:24 +0100 Subject: [PATCH] Fix sort_target parameter off-by-one. Fixes #18 --- etcd3gw/client.py | 9 +++--- etcd3gw/tests/test_etcd3gw.py | 53 +++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/etcd3gw/client.py b/etcd3gw/client.py index e7b355b..6bd7e3c 100644 --- a/etcd3gw/client.py +++ b/etcd3gw/client.py @@ -27,7 +27,7 @@ from etcd3gw.utils import DEFAULT_TIMEOUT from etcd3gw import watch -_SORT_ORDER = ['ascend', 'descend'] +_SORT_ORDER = ['none', 'ascend', 'descend'] _SORT_TARGET = ['key', 'version', 'create', 'mod', 'value'] _EXCEPTIONS_BY_CODE = { @@ -194,14 +194,14 @@ def get(self, key, metadata=False, sort_order=None, try: order = 0 if sort_order: - order = _SORT_ORDER.index(sort_order) + 1 + order = _SORT_ORDER.index(sort_order) except ValueError: raise ValueError('sort_order must be one of "ascend" or "descend"') try: target = 0 if sort_target: - target = _SORT_TARGET.index(sort_target) + 1 + target = _SORT_TARGET.index(sort_target) except ValueError: raise ValueError('sort_target must be one of "key", ' '"version", "create", "mod" or "value"') @@ -251,7 +251,8 @@ def get_prefix(self, key_prefix, sort_order=None, sort_target=None): return self.get(key_prefix, metadata=True, range_end=_encode(_increment_last_byte(key_prefix)), - sort_order=sort_order) + sort_order=sort_order, + sort_target=sort_target) def replace(self, key, initial_value, new_value): """Atomically replace the value of a key with a new value. diff --git a/etcd3gw/tests/test_etcd3gw.py b/etcd3gw/tests/test_etcd3gw.py index 31e7dd9..d69c85d 100644 --- a/etcd3gw/tests/test_etcd3gw.py +++ b/etcd3gw/tests/test_etcd3gw.py @@ -118,6 +118,59 @@ def remove_prefix(string, prefix): assert reverse_keys == ''.join(reversed(initial_keys)) + @unittest.skipUnless( + _is_etcd3_running(), "etcd3 is not available") + def test_get_prefix_sort_order_explicit_sort_target_key(self): + def remove_prefix(string, prefix): + return string[len(prefix):] + + initial_keys_ordered = 'abcde' + initial_keys = 'aebdc' + initial_values = 'qwert' + + for k, v in zip(initial_keys, initial_values): + self.client.put('/doot2/{}'.format(k), v) + + keys = '' + for value, meta in self.client.get_prefix( + '/doot2', sort_order='ascend', sort_target='key'): + keys += remove_prefix(meta['key'], '/doot2/') + + assert keys == initial_keys_ordered + + reverse_keys = '' + for value, meta in self.client.get_prefix( + '/doot2', sort_order='descend', sort_target='key'): + reverse_keys += remove_prefix(meta['key'], '/doot2/') + + assert reverse_keys == ''.join(reversed(initial_keys_ordered)) + + @unittest.skipUnless( + _is_etcd3_running(), "etcd3 is not available") + def test_get_prefix_sort_order_explicit_sort_target_rev(self): + def remove_prefix(string, prefix): + return string[len(prefix):] + + initial_keys = 'aebdc' + initial_values = 'qwert' + + for k, v in zip(initial_keys, initial_values): + self.client.put('/expsortmod/{}'.format(k), v) + + keys = '' + for value, meta in self.client.get_prefix( + '/expsortmod', sort_order='ascend', sort_target='mod'): + keys += remove_prefix(meta['key'], '/expsortmod/') + + assert keys == initial_keys + + reverse_keys = '' + for value, meta in self.client.get_prefix( + '/expsortmod', sort_order='descend', sort_target='mod'): + reverse_keys += remove_prefix(meta['key'], '/expsortmod/') + + assert reverse_keys == ''.join(reversed(initial_keys)) + @unittest.skipUnless( _is_etcd3_running(), "etcd3 is not available") def test_replace_success(self):