Skip to content

Commit

Permalink
Added value-mapped value to instance table output (scalar elements only)
Browse files Browse the repository at this point in the history
Details:

* This change adds the value of the Values qualifier corresponding
  to the value of integer-typed value-mapped properties when displaying
  instances in table format.

  Becaue pywbem.ValueMapping supports only scalar elements at the
  moment, this support is limited to scalar elements. Array elements
  are output as normal, i.e. without the value-mapped value.

Signed-off-by: Andreas Maier <andreas.r.maier@gmx.de>
  • Loading branch information
andy-maier committed Jun 25, 2020
1 parent d7e6339 commit c90ae8a
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 19 deletions.
74 changes: 59 additions & 15 deletions pywbemtools/pywbemcli/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

from pywbem import CIMInstanceName, CIMInstance, CIMClass, \
CIMQualifierDeclaration, CIMProperty, CIMClassName, \
cimvalue
cimvalue, ValueMapping, CIMInt

from .config import USE_TERMINAL_WIDTH, DEFAULT_TABLE_WIDTH

Expand Down Expand Up @@ -1057,19 +1057,18 @@ def display_cim_objects(context, cim_objects, output_format, summary=False,
if isinstance(cim_objects, (list, tuple)):
# Table format output is processed as a group
if output_format_is_table(output_format):
_print_objects_as_table(cim_objects, output_format)
_print_objects_as_table(cim_objects, output_format, context=context)
else:
# Call to display each object
for obj in cim_objects:
display_cim_objects(context, obj,
output_format=output_format)
display_cim_objects(context, obj, output_format=output_format)
return

# Display a single item.
object_ = cim_objects
# This allows passing single objects to the table formatter (i.e. not lists)
if output_format_is_table(output_format):
_print_objects_as_table([object_], output_format)
_print_objects_as_table([object_], output_format, context=context)
elif output_format == 'mof':
try:
click.echo(object_.tomof())
Expand Down Expand Up @@ -1403,7 +1402,7 @@ def _print_qual_decls_as_table(qual_decls, table_width, table_format):


def _format_instances_as_rows(insts, max_cell_width=DEFAULT_MAX_CELL_WIDTH,
include_classes=False):
include_classes=False, context=None):
"""
Format the list of instances properties into as a list of the property
values for each instance( a row of the table) gathered into a list of
Expand All @@ -1415,7 +1414,10 @@ def _format_instances_as_rows(insts, max_cell_width=DEFAULT_MAX_CELL_WIDTH,
max_width if not None folds col entries longer than the defined
max_cell_width. If max_width is None, the data length is ignored.
Formatting is consistent with mof output for each value.
The property values are formatted similar to MOF output. Properties that
have a ValueMap qualifier (effectively, in the creation class of the
instance) are shown with both the actual property value and the mapped
value in parenthesis.
NOTE: This is a separate function to allow testing of the table formatting
independently of print output.
Expand All @@ -1431,11 +1433,18 @@ def _format_instances_as_rows(insts, max_cell_width=DEFAULT_MAX_CELL_WIDTH,
prop_names = []

# find instance with max number of properties
# TODO: This misses properties if there are instances of different derived
# classes that added different extension properties.
for inst in insts:
pn = inst.keys()
if len(pn) > len(prop_names):
prop_names = pn

# Cache of ValueMapping objects for integer-typed properties.
# Key: classname.propertyname, both in lower case.
# A value of None indicates the property does not have a value mapping.
valuemappings = {}

for inst in insts:
if not isinstance(inst, CIMInstance):
raise ValueError('Only accepts CIMInstance; not type {}'
Expand All @@ -1446,6 +1455,7 @@ def _format_instances_as_rows(insts, max_cell_width=DEFAULT_MAX_CELL_WIDTH,

# get value for each property in this object
for name in prop_names:

# Account for possible instances without all properties
# Outputs empty string. Note that instance with no value
# results in same output as not instance name.
Expand All @@ -1454,27 +1464,59 @@ def _format_instances_as_rows(insts, max_cell_width=DEFAULT_MAX_CELL_WIDTH,
else:
value = inst.get(name)
p = inst.properties[name]

# Cache value mappings for integer-typed properties
if not isinstance(p.value, CIMInt) or not context:
valuemapping = None
else:
vm_key = '{}.{}'.format(
inst.classname.lower(), name.lower())
try:
valuemapping = valuemappings[vm_key]
except KeyError:
try:
valuemapping = ValueMapping.for_property(
context.conn,
context.conn.default_namespace,
inst.classname,
name)
except ValueError:
# Property does not have a value mapping.
valuemapping = None
valuemappings[vm_key] = valuemapping

if value is None:
val_str = u''
else:
val_str, _ = cimvalue_to_fmtd_string(
p.value, p.type, indent=0, maxline=max_cell_width,
line_pos=0, end_space=0, avoid_splits=False)

# Add the value mapping in parenthesis
if valuemapping:
val_str = '{} ({})'.format(
val_str, valuemapping.tovalues(p.value))

line.append(val_str)
lines.append(line)

return lines


def _print_instances_as_table(insts, table_width, table_format,
include_classes=False):
include_classes=False, context=None):
"""
Print the properties of the instances defined in insts as a table where
each row is an instance and each column is a property value. The properties
are formatted similar to mof output. All properties in the instance are
included.
each row is an instance and each column is a property value.
All properties in the instance are included.
The header line consists of the property names.
The header line consists of property names.
The property values are formatted similar to MOF output. Properties that
have a ValueMap qualifier (effectively, in the creation class of the
instance) are shown with both the actual property value and the mapped
value in parenthesis.
"""

if table_width is None:
Expand Down Expand Up @@ -1517,14 +1559,15 @@ def _print_instances_as_table(insts, table_width, table_format,
raise ValueError('Only CIMInstance display allows table output')

rows = _format_instances_as_rows(insts, max_cell_width=max_cell_width,
include_classes=include_classes)
include_classes=include_classes,
context=context)

title = 'Instances: {}'.format(insts[0].classname)
click.echo(format_table(rows, new_header_line, title=title,
table_format=table_format))


def _print_objects_as_table(objects, output_format):
def _print_objects_as_table(objects, output_format, context=None):
"""
Call the method for each type of object to print that object type
information as a table.
Expand All @@ -1538,7 +1581,8 @@ def _print_objects_as_table(objects, output_format):

if objects:
if isinstance(objects[0], CIMInstance):
_print_instances_as_table(objects, table_width, output_format)
_print_instances_as_table(objects, table_width, output_format,
context=context)
elif isinstance(objects[0], CIMClass):
_print_classes_as_table(objects, table_width, output_format)
elif isinstance(objects[0], CIMQualifierDeclaration):
Expand Down
21 changes: 17 additions & 4 deletions tests/unit/simple_assoc_mock_model.mof
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,19 @@ Qualifier Out : boolean = false,
Scope(parameter),
Flavor(DisableOverride, ToSubclass);

Qualifier ValueMap : string[],
Scope(property, method, parameter);

Qualifier Values : string[],
Scope(property, method, parameter),
Flavor(EnableOverride, ToSubclass, Translatable);

class TST_Person{
[Key, Description ("This is key prop")]
string name;
string extraProperty = "defaultvalue";
[ValueMap {"1", "2"}, Values {"female", "male"}]
uint16 gender;
};

// NOTE: classname uses lower case s in sub. Instance names use upper case
Expand Down Expand Up @@ -57,25 +66,29 @@ class TST_FamilyCollection {

// Define instances of TST_Person

instance of TST_Person as $Mike { name = "Mike"; };
instance of TST_Person as $Saara { name = "Saara"; };
instance of TST_Person as $Sofi { name = "Sofi"; };
instance of TST_Person as $Gabi{ name = "Gabi"; };
instance of TST_Person as $Mike { name = "Mike"; gender = 2; };
instance of TST_Person as $Saara { name = "Saara"; gender = 1; };
instance of TST_Person as $Sofi { name = "Sofi"; gender = 1; };
instance of TST_Person as $Gabi{ name = "Gabi"; gender = 1; };

// Define instances of the TST_PersonSub
instance of TST_PersonSub as $Mikesub{ name = "Mikesub";
gender = 2;
secondProperty = "one" ;
counter = 1; };

instance of TST_PersonSub as $Saarasub { name = "Saarasub";
gender = 1;
secondProperty = "two" ;
counter = 2; };

instance of TST_PersonSub as $Sofisub{ name = "Sofisub";
gender = 1;
secondProperty = "three" ;
counter = 3; };

instance of TST_PersonSub as $Gabisub{ name = "Gabisub";
gender = 1;
secondProperty = "four" ;
counter = 4; };

Expand Down
16 changes: 16 additions & 0 deletions tests/unit/test_class_cmds.py
Original file line number Diff line number Diff line change
Expand Up @@ -1181,6 +1181,10 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
'',
' string extraProperty = "defaultvalue";',
'',
' [ValueMap { "1", "2" },',
' Values { "female", "male" }]',
' uint16 gender;',
'',
'};',
''],
'test': 'lines'},
Expand All @@ -1203,6 +1207,10 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
'',
' string extraProperty = "defaultvalue";',
'',
' [ValueMap { "1", "2" },',
' Values { "female", "male" }]',
' uint16 gender;',
'',
'};',
''],
'test': 'lines'},
Expand All @@ -1223,6 +1231,10 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
'',
' string extraProperty = "defaultvalue";',
'',
' [ValueMap { "1", "2" },',
' Values { "female", "male" }]',
' uint16 gender;',
'',
'};',
''],
'test': 'lines'},
Expand All @@ -1243,6 +1255,10 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
'',
' string extraProperty = "defaultvalue";',
'',
' [ValueMap { "1", "2" },',
' Values { "female", "male" }]',
' uint16 gender;',
'',
'};',
''],
'test': 'lines'},
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/test_instance_cmds.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,10 +380,12 @@
instance of TST_Person {
name = "Gabi";
gender = 1;
};
instance of TST_Person {
name = "Sofi";
gender = 1;
};
"""
Expand Down

0 comments on commit c90ae8a

Please sign in to comment.