Adds the ability to list atomic labels via 'atest label list --atomicgroup'
Adds ability to parse values from nested dicts to topic_common for the above.
Signed-off-by: Gregory Smith <[email protected]>
git-svn-id: http://test.kernel.org/svn/autotest/trunk@3350 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/cli/label.py b/cli/label.py
index 244f795..65ad468 100755
--- a/cli/label.py
+++ b/cli/label.py
@@ -55,7 +55,7 @@
class label_list(action_common.atest_list, label):
- """atest label list [--platform] [--all]
+ """atest label list [--platform] [--all] [--atomicgroup]
[--valid-only] [--machine <machine>]
[--blist <file>] [<labels>]"""
def __init__(self):
@@ -74,6 +74,11 @@
'platform labels'),
action='store_true')
+ self.parser.add_option('--atomicgroup',
+ help=('Display only atomic group labels '
+ 'along with the atomic group name.'),
+ action='store_true')
+
self.parser.add_option('-m', '--machine',
help='List LABELs of MACHINE',
type='string',
@@ -85,9 +90,10 @@
inline_option='machine')
(options, leftover) = super(label_list, self).parse([host_info])
- if options.all and options.platform_only:
+ exclusives = [options.all, options.platform_only, options.atomicgroup]
+ if exclusives.count(True) > 1:
self.invalid_syntax('Only specify one of --all,'
- '--platform')
+ '--platform, --atomicgroup')
if len(self.hosts) > 1:
self.invalid_syntax(('Only one machine name allowed. '
@@ -95,6 +101,7 @@
'instead.') %
(sys.argv[0], ','.join(self.hosts)))
self.all = options.all
+ self.atomicgroup = options.atomicgroup
self.platform_only = options.platform_only
self.valid_only = options.valid_only
return (options, leftover)
@@ -125,6 +132,10 @@
results = [label for label in results
if label['platform']]
keys = ['name', 'invalid']
+ elif self.atomicgroup:
+ results = [label for label in results
+ if label['atomic_group']]
+ keys = ['name', 'atomic_group.name', 'invalid']
elif not self.all:
results = [label for label in results
if not label['platform']]
diff --git a/cli/topic_common.py b/cli/topic_common.py
index ce4de41..0070349 100755
--- a/cli/topic_common.py
+++ b/cli/topic_common.py
@@ -100,6 +100,7 @@
'synch_count': 'Sync Count',
'max_number_of_machines': 'Max. hosts to use',
'parse_failed_repair': 'Include failed repair results',
+ 'atomic_group.name': 'Atomic Group Name',
}
# In the failure, tag that will replace the item.
@@ -132,6 +133,24 @@
'platform': __convert_platform,
'labels': lambda labels: ', '.join(labels)}
+
+def _get_item_key(item, key):
+ """Allow for lookups in nested dictionaries using '.'s within a key."""
+ if key in item:
+ return item[key]
+ nested_item = item
+ for subkey in key.split('.'):
+ if not subkey:
+ raise ValueError('empty subkey in %r' % key)
+ try:
+ nested_item = nested_item[subkey]
+ except KeyError, e:
+ raise KeyError('%r - looking up key %r in %r' %
+ (e, key, nested_item))
+ else:
+ return nested_item
+
+
class CliError(Exception):
pass
@@ -490,7 +509,7 @@
for key in keys:
print '%s: %s' % (KEYS_TO_NAMES_EN[key],
self.__conv_value(key,
- item[key]))
+ _get_item_key(item, key)))
def print_fields_parse(self, items, keys, title=None):
@@ -499,10 +518,10 @@
for item in items:
values = ['%s=%s' % (KEYS_TO_NAMES_EN[key],
self.__conv_value(key,
- item[key]))
+ _get_item_key(item, key)))
for key in keys
if self.__conv_value(key,
- item[key]) != '']
+ _get_item_key(item, key)) != '']
print self.parse_delim.join(values)
@@ -517,7 +536,7 @@
return
for key in keys[:-1]:
lens[key] = max(len(self.__conv_value(key,
- item[key]))
+ _get_item_key(item, key)))
for item in items)
lens[key] = max(lens[key], len(KEYS_TO_NAMES_EN[key]))
lens[keys[-1]] = 0
@@ -535,13 +554,14 @@
header = tuple(KEYS_TO_NAMES_EN[key] for key in keys_header)
print fmt % header
for item in items:
- values = tuple(self.__conv_value(key, item[key])
+ values = tuple(self.__conv_value(key,
+ _get_item_key(item, key))
for key in keys_header)
print fmt % values
if sublist_keys:
for key in sublist_keys:
self.print_wrapped(KEYS_TO_NAMES_EN[key],
- item[key])
+ _get_item_key(item, key))
print '\n'
@@ -550,16 +570,16 @@
format"""
for item in items:
values = ['%s=%s' % (KEYS_TO_NAMES_EN[key],
- self.__conv_value(key, item[key]))
+ self.__conv_value(key, _get_item_key(item, key)))
for key in keys_header
if self.__conv_value(key,
- item[key]) != '']
+ _get_item_key(item, key)) != '']
if sublist_keys:
[values.append('%s=%s'% (KEYS_TO_NAMES_EN[key],
- ','.join(item[key])))
+ ','.join(_get_item_key(item, key))))
for key in sublist_keys
- if len(item[key])]
+ if len(_get_item_key(item, key))]
print self.parse_delim.join(values)
@@ -585,10 +605,10 @@
for item in items:
values += ['%s=%s' % (KEYS_TO_NAMES_EN[key],
self.__conv_value(key,
- item[key]))
+ _get_item_key(item, key)))
for key in ['id', 'name']
if self.__conv_value(key,
- item[key]) != '']
+ _get_item_key(item, key)) != '']
print self.parse_delim.join(values)
@@ -596,7 +616,7 @@
"""Print a wrapped list of results"""
if not items:
return
- print ' '.join(item[key] for item in items)
+ print ' '.join(_get_item_key(item, key) for item in items)
def print_list_parse(self, items, key):
@@ -604,4 +624,4 @@
if not items:
return
print '%s=%s' % (KEYS_TO_NAMES_EN[key],
- ','.join(item[key] for item in items))
+ ','.join(_get_item_key(item, key) for item in items))
diff --git a/cli/topic_common_unittest.py b/cli/topic_common_unittest.py
index 75075db..7d79e7f 100755
--- a/cli/topic_common_unittest.py
+++ b/cli/topic_common_unittest.py
@@ -11,6 +11,22 @@
from autotest_lib.frontend.afe.json_rpc import proxy
+class topic_common_misc_tests(unittest.TestCase):
+ def test_get_item_key(self):
+ get_item_key = topic_common._get_item_key
+ self.assertRaises(ValueError, get_item_key, {}, '')
+ self.assertRaises(ValueError, get_item_key, {}, '.')
+ self.assertRaises(KeyError, get_item_key, {}, 'a')
+ self.assertRaises(KeyError, get_item_key, {}, 'a.')
+ self.assertRaises(ValueError, get_item_key, {'a': {}}, 'a.')
+ self.assertRaises(KeyError, get_item_key, {'a': {}}, 'a.b')
+ self.assertEquals(2, get_item_key({'a.b': 2, 'a': {}}, 'a.b'))
+ self.assertEquals(9, get_item_key({'a': {'b': 9}}, 'a.b'))
+ self.assertEquals(3, get_item_key({'a': {'b': {'c': 3}}}, 'a.b.c'))
+ self.assertEquals(5, get_item_key({'a': 5}, 'a'))
+ self.assertEquals({'b': 9}, get_item_key({'a': {'b': 9}}, 'a'))
+
+
class item_parse_info_unittest(cli_mock.cli_unittest):
def __test_parsing_flist_bad(self, options):
parse_info = topic_common.item_parse_info