diff options
author | Yuan Zhou <yuan.zhou@intel.com> | 2014-07-31 19:51:50 +0800 |
---|---|---|
committer | Yuan Zhou <yuan.zhou@intel.com> | 2014-08-06 16:07:17 +0800 |
commit | 776133bd299adfb644f2274143b9fba72672428d (patch) | |
tree | 2d76f05f20192657353e2445fe1f082aedcb4d6c | |
parent | fd1594937d777c0047051ae470e2de5523522171 (diff) | |
download | python-swiftclient-776133bd299adfb644f2274143b9fba72672428d.tar.gz |
Clean up raw policy stats in account stat
Storage policy stats was not well parsed in account stat. This
patch parses the stats and print out the stats in a format like below:
$swift -A http://swift_cluster/auth/v1.0 -U test:tester -K testing stat
Account: AUTH_test
Containers: 5
Objects: 1
Bytes: 2097152
Objects in policy "golden": 1
Bytess in policy "golden": 2097152
Objects in policy "silver": 0
Bytes in policy "silver": 0
X-Timestamp: 1404697760.88809
X-Trans-Id: txec519e24b44a413abb705-0053da2dcb
Content-Type: text/plain; charset=utf-8
Accept-Ranges: bytes
Change-Id: I7ad0ee6d88f8393e3a93e90cd52b9b592da7072d
-rw-r--r-- | swiftclient/command_helpers.py | 41 | ||||
-rw-r--r-- | swiftclient/multithreading.py | 17 | ||||
-rw-r--r-- | tests/unit/test_command_helpers.py | 43 | ||||
-rw-r--r-- | tests/unit/test_shell.py | 10 |
4 files changed, 85 insertions, 26 deletions
diff --git a/swiftclient/command_helpers.py b/swiftclient/command_helpers.py index 0c81cb6..ef18636 100644 --- a/swiftclient/command_helpers.py +++ b/swiftclient/command_helpers.py @@ -15,9 +15,11 @@ from swiftclient.utils import prt_bytes def stat_account(conn, options, thread_manager): + items_to_print = [] + headers = conn.head_account() if options.verbose > 1: - thread_manager.print_items(( + items_to_print.extend(( ('StorageURL', conn.url), ('Auth Token', conn.token), )) @@ -26,19 +28,40 @@ def stat_account(conn, options, thread_manager): options.human).lstrip() bytes_used = prt_bytes(headers.get('x-account-bytes-used', 0), options.human).lstrip() - thread_manager.print_items(( + items_to_print.extend(( ('Account', conn.url.rsplit('/', 1)[-1]), ('Containers', container_count), ('Objects', object_count), ('Bytes', bytes_used), )) - thread_manager.print_headers(headers, - meta_prefix='x-account-meta-', - exclude_headers=( - 'content-length', 'date', - 'x-account-container-count', - 'x-account-object-count', - 'x-account-bytes-used')) + policies = set() + exclude_policy_headers = [] + ps_header_prefix = 'x-account-storage-policy-' + for header_key, header_value in headers.items(): + if header_key.lower().startswith(ps_header_prefix): + policy_name = header_key.rsplit('-', 2)[0].split('-', 4)[-1] + policies.add(policy_name) + exclude_policy_headers.append(header_key) + for policy in policies: + items_to_print.extend(( + ('Objects in policy "' + policy + '"', + prt_bytes(headers.get(ps_header_prefix + policy + '-object-count', + 0), options.human).lstrip()), + ('Bytes in policy "' + policy + '"', + prt_bytes(headers.get(ps_header_prefix + policy + '-bytes-used', + 0), options.human).lstrip()), + )) + + items_to_print.extend(thread_manager.headers_to_items( + headers, meta_prefix='x-account-meta-', + exclude_headers=([ + 'content-length', 'date', + 'x-account-container-count', + 'x-account-object-count', + 'x-account-bytes-used'] + exclude_policy_headers))) + # line up the items nicely + offset = max(len(item) for item, value in items_to_print) + thread_manager.print_items(items_to_print, offset=offset) def stat_container(conn, options, args, thread_manager): diff --git a/swiftclient/multithreading.py b/swiftclient/multithreading.py index 2f498c9..d187091 100644 --- a/swiftclient/multithreading.py +++ b/swiftclient/multithreading.py @@ -193,6 +193,7 @@ class MultiThreadingManager(object): The swift command-line tool uses this to exit non-zero if any error strings were printed. """ + DEFAULT_OFFSET = 14 def __init__(self, print_stream=sys.stdout, error_stream=sys.stderr): """ @@ -231,7 +232,7 @@ class MultiThreadingManager(object): msg = msg % fmt_args self.printer.queue.put(msg) - def print_items(self, items, offset=14, skip_missing=False): + def print_items(self, items, offset=DEFAULT_OFFSET, skip_missing=False): lines = [] template = '%%%ds: %%s' % offset for k, v in items: @@ -241,7 +242,7 @@ class MultiThreadingManager(object): self.print_msg('\n'.join(lines)) def print_headers(self, headers, meta_prefix='', exclude_headers=None, - offset=14): + offset=DEFAULT_OFFSET): exclude_headers = exclude_headers or [] meta_headers = [] other_headers = [] @@ -254,6 +255,18 @@ class MultiThreadingManager(object): other_headers.append(template % (key.title(), value)) self.print_msg('\n'.join(chain(meta_headers, other_headers))) + def headers_to_items(self, headers, meta_prefix='', exclude_headers=None): + exclude_headers = exclude_headers or [] + meta_items = [] + other_items = [] + for key, value in headers.items(): + if key.startswith(meta_prefix): + meta_key = 'Meta %s' % key[len(meta_prefix):].title() + meta_items.append((meta_key, value)) + elif key not in exclude_headers: + other_items.append((key.title(), value)) + return meta_items + other_items + def error(self, msg, *fmt_args): if fmt_args: msg = msg % fmt_args diff --git a/tests/unit/test_command_helpers.py b/tests/unit/test_command_helpers.py index af81601..8bb9dc1 100644 --- a/tests/unit/test_command_helpers.py +++ b/tests/unit/test_command_helpers.py @@ -69,10 +69,10 @@ class TestStatHelpers(testtools.TestCase): with self.thread_manager as thread_manager: h.stat_account(self.conn, self.options, thread_manager) expected = """ - Account: a - Containers: 42 - Objects: 976K - Bytes: 1.0G + Account: a +Containers: 42 + Objects: 976K + Bytes: 1.0G """ self.assertOut(expected) @@ -89,12 +89,35 @@ class TestStatHelpers(testtools.TestCase): with self.thread_manager as thread_manager: h.stat_account(self.conn, self.options, thread_manager) expected = """ - StorageURL: http://storage/v1/a - Auth Token: tk12345 - Account: a - Containers: 42 - Objects: 1000000 - Bytes: 1073741824 +StorageURL: http://storage/v1/a +Auth Token: tk12345 + Account: a +Containers: 42 + Objects: 1000000 + Bytes: 1073741824 +""" + self.assertOut(expected) + + def test_stat_account_policy_stat(self): + # stub head_account + stub_headers = { + 'x-account-container-count': 42, + 'x-account-object-count': 1000000, + 'x-account-bytes-used': 2 ** 30, + 'x-account-storage-policy-nada-object-count': 1000000, + 'x-account-storage-policy-nada-bytes-used': 2 ** 30, + } + self.conn.head_account.return_value = stub_headers + + with self.thread_manager as thread_manager: + h.stat_account(self.conn, self.options, thread_manager) + expected = """ + Account: a + Containers: 42 + Objects: 1000000 + Bytes: 1073741824 +Objects in policy "nada": 1000000 + Bytes in policy "nada": 1073741824 """ self.assertOut(expected) diff --git a/tests/unit/test_shell.py b/tests/unit/test_shell.py index daf4cd8..83113f0 100644 --- a/tests/unit/test_shell.py +++ b/tests/unit/test_shell.py @@ -63,11 +63,11 @@ class TestShell(unittest.TestCase): connection.return_value.head_account.return_value = return_headers connection.return_value.url = 'http://127.0.0.1/v1/AUTH_account' swiftclient.shell.main(argv) - calls = [mock.call(' Account: AUTH_account\n' + - ' Containers: 1\n' + - ' Objects: 2\n' + - ' Bytes: 3'), - mock.call('')] + calls = [mock.call(' Account: AUTH_account\n' + + 'Containers: 1\n' + + ' Objects: 2\n' + + ' Bytes: 3'), + ] mock_print.assert_has_calls(calls) @mock.patch('swiftclient.shell.MultiThreadingManager._print') |