Skip to content

Commit

Permalink
Refactors the test_wbemserverclass and adds two new files:
Browse files Browse the repository at this point in the history
1. instance_from_class_method.py - Temporary localization of the
instance_from_class method until we get it accepted.  This keeps the
tests running until we get this added method accepted as a new method in
ICMInstance.

2. teststuite/wbemserver_mock.py which isolates all the code to generate
the mock for the wbem server.  Since the wbem server mock is required to
run the WbemServer class in other mocks this simplifies building this
component.

3. Modifications to test_wbemserverclass.py to work with the two new
files.

4. In addition we extended the cim_objects we create for the tests
to include attributes that were overlooked before such as propagated and
the description qualifier on some of the objects.
  • Loading branch information
KSchopmeyer committed Jun 3, 2018
1 parent 1158870 commit 5fb7281
Show file tree
Hide file tree
Showing 4 changed files with 496 additions and 315 deletions.
112 changes: 112 additions & 0 deletions testsuite/instance_from_class_method.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
"""
Define instance in class method to be integrated into CIMInstance.
This temporarily adds the method to the CIMInstance class until we
agree on PR to incorporate the method into the class
"""
from pywbem import CIMInstance, CIMInstanceName
from pywbem._nocasedict import NocaseDict


@staticmethod
def instance_from_class(klass, namespace=None,
property_values=None,
include_null_properties=True,
include_path=True, strict=False,
include_class_origin=False):
"""
Build a new CIMInstance from the input CIMClass using the
property_values dictionary to complete properties and the other
parameters to filter properties, validate the properties, and
optionally set the path component of the CIMInstance. If any of the
properties in the class have default values, those values are passed
to the instance unless overridden by the property_values dictionary.
No CIMProperty qualifiers are included in the created instance and the
`class_origin` attribute is transfered from the class only if the
`include_class_origin` parameter is True
Parameters:
klass (:class:`pywbem:CIMClass`)
CIMClass from which the instance will be constructed. This
class must include qualifiers and should include properties
from any superclasses to be sure it includes all properties
that are to be built into the instance. Properties may be
excluded from the instance by not including them in the `klass`
parameter.
namespace (:term:`string`):
Namespace in the WBEMConnection used to retrieve the class or
`None` if the default_namespace is to be used.
property_values (dictionary):
Dictionary containing name/value pairs where the names are the
names of properties in the class and the properties are the
property values to be set into the instance. If a property is in
the property_values dictionary but not in the class an ValueError
exception is raised.
include_null_properties (:class:`py:bool`):
Determines if properties with Null values are included in the
instance.
If `True` they are included in the instance returned.
If `False` they are not included in the instance returned
inclued_class_origin (:class:`py:bool`):
Determines if ClassOrigin information is included in the returned
instance.
If None or False, class origin information is not included.
If True, class origin information is included.
include_path (:class:`py:bool`:):
If `True` the CIMInstanceName path is build and inserted into
the new instance. If `strict` all key properties must be in the
instance.
strict (:class:`py:bool`:):
If `True` and `include_path` is set, all key properties must be in
the instance so that
If not `True` The path component is created even if not all
key properties are in the created instance.
Returns:
Returns an instance with the defined properties and optionally
the path set. No qualifiers are included in the returned instance
and the existence of ClassOrigin depends on the
`include_class_origin` parameter. The value of each property is
either the value from the `property_values` dictionary, the
default_value from the class or Null(unless
`include_null_properties` is False). All other attributes of each
property are the same as the corresponding class property.
Raises:
ValueError if there are conflicts between the class and
property_values dictionary or strict is set and the class is not
complete.
"""
class_name = klass.classname
inst = CIMInstance(class_name)
for p in property_values:
if p not in klass.properties:
raise ValueError('Property Name %s in property_values but '
'not in class %s' % (p, class_name))
for cp in klass.properties:
ip = klass.properties[cp].copy()
ip.qualifiers = NocaseDict()
if not include_class_origin:
ip.class_origin = None
if ip.name in property_values:
ip.value = property_values[ip.name]
if include_null_properties:
inst[ip.name] = ip
else:
if ip.value:
inst[ip.name] = ip

if include_path:
inst.path = CIMInstanceName.from_instance(klass, inst, namespace,
strict=strict)
return inst
78 changes: 52 additions & 26 deletions testsuite/test_wbemconnection_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,9 @@ def tst_class():
test class for the mock class tests.
"""
qkey = {'Key': CIMQualifier('Key', True, propagated=False)}
dkey = {'Description': CIMQualifier('Description', 'blah blah',
dkey = {'Description': CIMQualifier('Description', 'class description',
propagated=False)}
pkey = {'Description': CIMQualifier('Description', 'property',
propagated=False)}

c = CIMClass(
Expand All @@ -163,10 +165,10 @@ def tst_class():
CIMProperty('InstanceID', None, qualifiers=qkey,
type='string', class_origin='CIM_Foo',
propagated=False)},
methods={'Delete': CIMMethod('Delete', 'uint32', qualifiers=dkey,
methods={'Delete': CIMMethod('Delete', 'uint32', qualifiers=pkey,
class_origin='CIM_Foo',
propagated=False),
'Fuzzy': CIMMethod('Fuzzy', 'string', qualifiers=dkey,
'Fuzzy': CIMMethod('Fuzzy', 'string', qualifiers=pkey,
class_origin='CIM_Foo',
propagated=False)})
return c
Expand All @@ -185,25 +187,30 @@ def tst_classes(tst_class):
qkey = {'Key': CIMQualifier('Key', True, propagated=False)}
dkey = {'Description': CIMQualifier('Description', 'blah blah',
propagated=False)}
pkey = {'Description': CIMQualifier('Description', 'property',
propagated=False)}

c2 = CIMClass(
'CIM_Foo_sub', superclass='CIM_Foo', qualifiers=dkey,
properties={'cimfoo_sub':
CIMProperty('cimfoo_sub', None, type='string',
qualifiers=pkey,
class_origin='CIM_Foo_sub',
propagated=False)})

c3 = CIMClass(
'CIM_Foo_sub2', superclass='CIM_Foo', qualifiers=dkey,
properties={'cimfoo_sub2':
CIMProperty('cimfoo_sub2', None, type='string',
qualifiers=pkey,
class_origin='CIM_Foo_sub2',
propagated=False)})

c4 = CIMClass(
'CIM_Foo_sub_sub', superclass='CIM_Foo_sub', qualifiers=dkey,
properties={'cimfoo_sub_sub':
CIMProperty('cimfoo_sub_sub', None, type='string',
qualifiers=pkey,
class_origin='CIM_Foo_sub_sub',
propagated=False)})

Expand All @@ -213,7 +220,7 @@ def tst_classes(tst_class):
CIMProperty('InstanceID', None, qualifiers=qkey,
type='string', class_origin='CIM_Foo_nokey',
propagated=False),
CIMProperty('cimfoo', None, qualifiers=None,
CIMProperty('cimfoo', None, qualifiers=pkey,
type='string', class_origin='CIM_Foo_nokey',
propagated=False),
])
Expand Down Expand Up @@ -1506,28 +1513,41 @@ def test_getclass_iqico(self, conn, tst_classes, ns, cn, iq, ico):
cl = conn.GetClass(cn, namespace=ns, IncludeQualifiers=iq,
LocalOnly=True, IncludeClassOrigin=ico)

cl.path = None

c_tst = tst_class.copy()
# test with LocalOnly True to get just the local properties
cl = conn.GetClass(cn, namespace=ns, IncludeQualifiers=iq,
LocalOnly=True, IncludeClassOrigin=ico)
# TODO ks confirm whether following needed
# cl.path = None

# remove all qualifiers and class_origins and test for equality
if not iq:
c_tst.qualifiers = NocaseDict()

for prop in c_tst.properties:
c_tst.properties[prop].qualifiers = NocaseDict()
for method in c_tst.methods:
c_tst.methods[method].qualifiers = NocaseDict()
for param in c_tst.methods[method].parameters:
c_tst.methods[method].parameters[param].qualifiers = \
tst_class.qualifiers = NocaseDict()
for prop in cl.properties:
tst_class.properties[prop].qualifiers = NocaseDict()
for method in cl.methods:
tst_class.methods[method].qualifiers = NocaseDict()
for param in cl.methods[method].parameters:
tst_class.methods[method].parameters[param].qualifiers = \
NocaseDict()

# remove class origin if ico = None. Else test
if not ico:
for prop in c_tst.properties:
c_tst.properties[prop].class_origin = None
for method in c_tst.methods:
c_tst.methods[method].class_origin = None
for prop in tst_class.properties:
tst_class.properties[prop].class_origin = None
for method in tst_class.methods:
tst_class.methods[method].class_origin = None
else:
# The following is a test
for pname in tst_class.properties:
tst_class.properties[pname].class_origin == tst_class.classname
for mname in tst_class.methods:
tst_class.methods[mname].class_origin == tst_class.classname

# Test the modified tst_class against the returned class
tst_ns = ns if ns else conn.default_namespace
tst_class.path = CIMClassName(cn, host='FakedUrl', namespace=tst_ns)

assert cl == c_tst
assert(cl == tst_class)

@pytest.mark.parametrize(
"ns", [None, 'root/blah'])
Expand All @@ -1552,18 +1572,24 @@ def test_getclass_lo(self, conn, ns, tst_classes, cn, lo, pl_exp):
"""
conn.add_cimobjects(tst_classes, namespace=ns)

if not lo:
cl = conn.GetClass(cn, namespace=ns, LocalOnly=lo,
IncludeQualifiers=True)
else:
cl = conn.GetClass(cn, namespace=ns, LocalOnly=lo,
IncludeQualifiers=True)
cl = conn.GetClass(cn, namespace=ns, LocalOnly=lo,
IncludeQualifiers=True,
IncludeClassOrigin=True)

assert cl.classname == cn
assert len(cl.properties) == len(pl_exp)
rtn_props = cl.properties.keys()
assert set(rtn_props) == set(pl_exp)

tst_cls_dict = dict()
for cl in tst_classes:
tst_cls_dict[cl.classname] = cl
for pname, prop in cl.properties.items():
prop_class_origin = prop.class_origin
class_prop_qualifiers = \
tst_cls_dict[prop_class_origin].properties[pname].qualifiers
assert prop.qualifiers == class_prop_qualifiers

@pytest.mark.parametrize(
"ns", [None, 'root/blah'])
# property list, expected properties in response
Expand Down

0 comments on commit 5fb7281

Please sign in to comment.