From 1b0f94f20580a55bea52ba468bdeeca3dd4552bd Mon Sep 17 00:00:00 2001 From: fujioka yuuichi Date: Mon, 28 Oct 2013 09:05:57 +0900 Subject: [PATCH] Fix order of sample list Samples of "ceilometer sample-list" are sorted by Resource ID and Volume. Expected order is Timestamp. This pache fixes this problem. Change-Id: I338014e5868b2176a3afd549e13d0dd6118b3ac1 Closes-Bug: #1227495 --- ceilometerclient/common/utils.py | 28 +++++----- ceilometerclient/tests/test_utils.py | 58 ++++++++++++++++++++ ceilometerclient/tests/v2/test_shell.py | 73 +++++++++++++++++++++++++ ceilometerclient/v2/shell.py | 2 +- 4 files changed, 147 insertions(+), 14 deletions(-) diff --git a/ceilometerclient/common/utils.py b/ceilometerclient/common/utils.py index fe213781..82f5b08d 100644 --- a/ceilometerclient/common/utils.py +++ b/ceilometerclient/common/utils.py @@ -14,6 +14,7 @@ # under the License. from __future__ import print_function +import itertools import os import six import sys @@ -23,6 +24,7 @@ import uuid import prettytable from ceilometerclient import exc +from ceilometerclient.openstack.common import cliutils from ceilometerclient.openstack.common import importutils @@ -48,20 +50,20 @@ def pretty_choice_list(l): def print_list(objs, fields, field_labels, formatters={}, sortby=0): - pt = prettytable.PrettyTable([f for f in field_labels], - caching=False, print_empty=False) - pt.align = 'l' - for o in objs: - row = [] - for field in fields: - if field in formatters: - row.append(formatters[field](o)) - else: - data = getattr(o, field, '') - row.append(data) - pt.add_row(row) - print(pt.get_string(sortby=field_labels[sortby])) + def _make_default_formatter(field): + return lambda o: getattr(o, field, '') + + new_formatters = {} + for field, field_label in itertools.izip(fields, field_labels): + if field in formatters: + new_formatters[field_label] = formatters[field] + else: + new_formatters[field_label] = _make_default_formatter(field) + + cliutils.print_list(objs, field_labels, + formatters=new_formatters, + sortby_index=sortby) def print_dict(d, dict_property="Property", wrap=0): diff --git a/ceilometerclient/tests/test_utils.py b/ceilometerclient/tests/test_utils.py index 30ba31cf..51663432 100644 --- a/ceilometerclient/tests/test_utils.py +++ b/ceilometerclient/tests/test_utils.py @@ -44,6 +44,64 @@ class UtilsTest(test_utils.BaseTestCase): | K | k | | Key | Value | +----------+-------+ +''') + + def test_print_list(self): + class Foo: + def __init__(self, one, two, three): + self.one = one + self.two = two + self.three = three + + foo_list = [ + Foo(10, 'a', 'B'), + Foo(8, 'c', 'c'), + Foo(12, '0', 'Z')] + + def do_print_list(sortby): + saved_stdout = sys.stdout + try: + sys.stdout = output = six.StringIO() + utils.print_list(foo_list, + ['one', 'two', 'three'], + ['1st', '2nd', '3rd'], + {'one': lambda o: o.one * 10}, + sortby) + finally: + sys.stdout = saved_stdout + return output.getvalue() + + printed = do_print_list(None) + self.assertEqual(printed, '''\ ++-----+-----+-----+ +| 1st | 2nd | 3rd | ++-----+-----+-----+ +| 100 | a | B | +| 80 | c | c | +| 120 | 0 | Z | ++-----+-----+-----+ +''') + + printed = do_print_list(0) + self.assertEqual(printed, '''\ ++-----+-----+-----+ +| 1st | 2nd | 3rd | ++-----+-----+-----+ +| 80 | c | c | +| 100 | a | B | +| 120 | 0 | Z | ++-----+-----+-----+ +''') + + printed = do_print_list(1) + self.assertEqual(printed, '''\ ++-----+-----+-----+ +| 1st | 2nd | 3rd | ++-----+-----+-----+ +| 120 | 0 | Z | +| 100 | a | B | +| 80 | c | c | ++-----+-----+-----+ ''') def test_args_array_to_dict(self): diff --git a/ceilometerclient/tests/v2/test_shell.py b/ceilometerclient/tests/v2/test_shell.py index 6392e449..1c5a0dc4 100644 --- a/ceilometerclient/tests/v2/test_shell.py +++ b/ceilometerclient/tests/v2/test_shell.py @@ -19,6 +19,7 @@ from testtools import matchers from ceilometerclient.tests import utils from ceilometerclient.v2 import alarms +from ceilometerclient.v2 import samples from ceilometerclient.v2 import shell as ceilometer_shell @@ -135,3 +136,75 @@ class ShellAlarmHistoryCommandTest(utils.BaseTestCase): op='gt')] self._do_test_alarm_history(raw_query='timestamp>2013-10-03T08:59:28', parsed_query=parsed_query) + + +class ShellSampleListCommandTest(utils.BaseTestCase): + + METER = 'cpu_util' + SAMPLES = [{"counter_name": "cpu_util", + "resource_id": "5dcf5537-3161-4e25-9235-407e1385bd35", + "timestamp": "2013-10-15T05:50:30", + "counter_unit": "%", + "counter_volume": 0.261666666666667, + "counter_type": "gauge"}, + {"counter_name": "cpu_util", + "resource_id": "87d197e9-9cf6-4c25-bc66-1b1f4cedb52f", + "timestamp": "2013-10-15T05:50:29", + "counter_unit": "%", + "counter_volume": 0.261666666666667, + "counter_type": "gauge"}, + {"counter_name": "cpu_util", + "resource_id": "5dcf5537-3161-4e25-9235-407e1385bd35", + "timestamp": "2013-10-15T05:40:30", + "counter_unit": "%", + "counter_volume": 0.251247920133111, + "counter_type": "gauge"}, + {"counter_name": "cpu_util", + "resource_id": "87d197e9-9cf6-4c25-bc66-1b1f4cedb52f", + "timestamp": "2013-10-15T05:40:29", + "counter_unit": "%", + "counter_volume": 0.26, + "counter_type": "gauge"}] + + def setUp(self): + super(ShellSampleListCommandTest, self).setUp() + self.cc = mock.Mock() + self.cc.alarms = mock.Mock() + self.args = mock.Mock() + self.args.meter = self.METER + self.args.query = None + + def test_sample_list(self): + + sample_list = [samples.Sample(mock.Mock(), sample) + for sample in self.SAMPLES] + self.cc.samples.list.return_value = sample_list + + org_stdout = sys.stdout + try: + sys.stdout = output = six.StringIO() + ceilometer_shell.do_sample_list(self.cc, self.args) + self.cc.samples.list.assert_called_once_with( + meter_name=self.METER, + q=None) + finally: + sys.stdout = org_stdout + + self.assertEqual(output.getvalue(), '''\ ++--------------------------------------+----------+-------+----------------\ ++------+---------------------+ +| Resource ID | Name | Type | Volume \ +| Unit | Timestamp | ++--------------------------------------+----------+-------+----------------\ ++------+---------------------+ +| 5dcf5537-3161-4e25-9235-407e1385bd35 | cpu_util | gauge | 0.261666666667 \ +| % | 2013-10-15T05:50:30 | +| 87d197e9-9cf6-4c25-bc66-1b1f4cedb52f | cpu_util | gauge | 0.261666666667 \ +| % | 2013-10-15T05:50:29 | +| 5dcf5537-3161-4e25-9235-407e1385bd35 | cpu_util | gauge | 0.251247920133 \ +| % | 2013-10-15T05:40:30 | +| 87d197e9-9cf6-4c25-bc66-1b1f4cedb52f | cpu_util | gauge | 0.26 \ +| % | 2013-10-15T05:40:29 | ++--------------------------------------+----------+-------+----------------\ ++------+---------------------+ +''') diff --git a/ceilometerclient/v2/shell.py b/ceilometerclient/v2/shell.py index 69a585fd..c5b3f072 100644 --- a/ceilometerclient/v2/shell.py +++ b/ceilometerclient/v2/shell.py @@ -77,7 +77,7 @@ def do_sample_list(cc, args): fields = ['resource_id', 'counter_name', 'counter_type', 'counter_volume', 'counter_unit', 'timestamp'] utils.print_list(samples, fields, field_labels, - sortby=0) + sortby=None) @utils.arg('--project-id', metavar='',