Skip to content

Commit

Permalink
Merge branch 'master' into issue#656-pullops-maxobjcount
Browse files Browse the repository at this point in the history
  • Loading branch information
andy-maier committed Jan 18, 2017
2 parents 322229c + 3457d21 commit d7c2bd7
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 71 deletions.
21 changes: 19 additions & 2 deletions pywbem/_recorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from ordereddict import OrderedDict
from datetime import datetime, timedelta
import yaml
from yaml.representer import RepresenterError
import six

from .cim_obj import CIMInstance, CIMInstanceName, CIMClass, CIMClassName, \
Expand Down Expand Up @@ -83,6 +84,18 @@ def _represent_ordereddict(dump, tag, mapping, flow_style=None):
_represent_ordereddict(dumper, u'tag:yaml.org,2002:map', value))


# Some monkey-patching for better diagnostics:
def _represent_undefined(self, data):
raise RepresenterError("cannot represent an object: %s of type: %s; "
"yaml_representers: %r, "
"yaml_multi_representers: %r" %
(data, type(data), self.yaml_representers.keys(),
self.yaml_multi_representers.keys()))


yaml.SafeDumper.represent_undefined = _represent_undefined


class OpArgs(OpArgs_tuple):
"""
A named tuple representing the name and input arguments of the invocation
Expand Down Expand Up @@ -250,7 +263,7 @@ def enabled(self):
"""Indicate whether the recorder is enabled."""
return self._enabled

def reset(self):
def reset(self, pull_op=None):
"""Reset all the attributes in the class"""
self._pywbem_method = None
self._pywbem_args = None
Expand All @@ -270,6 +283,7 @@ def reset(self):
self._http_response_reason = None
self._http_response_headers = None
self._http_response_payload = None
self._pull_op = pull_op

def stage_pywbem_args(self, method, **kwargs):
self._pywbem_method = method
Expand Down Expand Up @@ -418,7 +432,9 @@ def record(self, pywbem_args, pywbem_result, http_request, http_response):

tc_pywbem_response = OrderedDict()
if pywbem_result.ret is not None:
tc_pywbem_response['result'] = self.toyaml(pywbem_result.ret)
yaml_txt = 'pullresult' if self._pull_op else 'result'
tc_pywbem_response[yaml_txt] = self.toyaml(pywbem_result.ret)

if pywbem_result.exc is not None:
exc = pywbem_result.exc
if isinstance(exc, CIMError):
Expand Down Expand Up @@ -492,6 +508,7 @@ def toyaml(self, obj):
"""
if isinstance(obj, (list, tuple)):
ret = []
# This does not handle namedtuple
for item in obj:
ret.append(self.toyaml(item))
return ret
Expand Down
20 changes: 10 additions & 10 deletions pywbem/cim_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -3740,7 +3740,7 @@ def OpenEnumerateInstancePaths(self, ClassName, namespace=None,
"""

if self.operation_recorder:
self.operation_recorder.reset()
self.operation_recorder.reset(pull_op=True)
self.operation_recorder.stage_pywbem_args(
method='OpenEnumerateInstancePaths',
ClassName=ClassName,
Expand Down Expand Up @@ -4002,7 +4002,7 @@ class are to be included in the returned instances, as follows:
""" # noqa: E501

if self.operation_recorder:
self.operation_recorder.reset()
self.operation_recorder.reset(pull_op=True)
self.operation_recorder.stage_pywbem_args(
method='OpenEnumerateInstances',
ClassName=ClassName,
Expand Down Expand Up @@ -4225,7 +4225,7 @@ class (or subclasses).
"""

if self.operation_recorder:
self.operation_recorder.reset()
self.operation_recorder.reset(pull_op=True)
self.operation_recorder.stage_pywbem_args(
method='OpenReferenceInstancePaths',
InstanceName=InstanceName,
Expand Down Expand Up @@ -4473,7 +4473,7 @@ class (or subclasses).
""" # noqa: E501

if self.operation_recorder:
self.operation_recorder.reset()
self.operation_recorder.reset(pull_op=True)
self.operation_recorder.stage_pywbem_args(
method='OpenReferenceInstances',
InstanceName=InstanceName,
Expand Down Expand Up @@ -4705,7 +4705,7 @@ class (or subclasses).
"""

if self.operation_recorder:
self.operation_recorder.reset()
self.operation_recorder.reset(pull_op=True)
self.operation_recorder.stage_pywbem_args(
method='OpenAssociatorInstancePaths',
InstanceName=InstanceName,
Expand Down Expand Up @@ -4971,7 +4971,7 @@ class (or subclasses).
""" # noqa: E501

if self.operation_recorder:
self.operation_recorder.reset()
self.operation_recorder.reset(pull_op=True)
self.operation_recorder.stage_pywbem_args(
method='OpenAssociatorInstances',
InstanceName=InstanceName,
Expand Down Expand Up @@ -5188,7 +5188,7 @@ def _GetQueryRsltClass(result):
"ReturnQueryResultClass invalid or missing.")

if self.operation_recorder:
self.operation_recorder.reset()
self.operation_recorder.reset(pull_op=True)
self.operation_recorder.stage_pywbem_args(
method='OpenQueryInstances',
FilterQueryLanguage=FilterQueryLanguage,
Expand Down Expand Up @@ -5339,7 +5339,7 @@ def PullInstancesWithPath(self, context, MaxObjectCount,
"""

if self.operation_recorder:
self.operation_recorder.reset()
self.operation_recorder.reset(pull_op=True)
self.operation_recorder.stage_pywbem_args(
method='PullInstancesWithPath',
context=context,
Expand Down Expand Up @@ -5472,7 +5472,7 @@ def PullInstancePaths(self, context, MaxObjectCount, **extra):
"""

if self.operation_recorder:
self.operation_recorder.reset()
self.operation_recorder.reset(pull_op=True)
self.operation_recorder.stage_pywbem_args(
method='PullInstancePaths',
context=context,
Expand Down Expand Up @@ -5601,7 +5601,7 @@ def PullInstances(self, context, MaxObjectCount, **extra):
"""

if self.operation_recorder:
self.operation_recorder.reset()
self.operation_recorder.reset(pull_op=True)
self.operation_recorder.stage_pywbem_args(
method='PullInstances',
context=context,
Expand Down
97 changes: 38 additions & 59 deletions testsuite/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@
RUN_ONE_TESTCASE = None


def show_diff(conn, expected, actual, display_text):
"""Display the actual and expected data"""
print("Details for the following assertion error:")
print("- Expected result %s: %s" % (display_text, expected))
print("- Actual result %s: %s" % (display_text, actual))
if conn is not None and conn.debug:
print("- HTTP response data: %r" % conn.last_raw_reply)


def str_tuple(tuple_):
"""
Prepare a tuple or NonType for output.
Expand Down Expand Up @@ -706,6 +715,7 @@ def runtestcase(self, testcase):
self.assertEqual(cim_status, exp_cim_status,
"WBEMConnection operation CIM status code")

# Returns either exp_result or exp_pull_result
if exp_result is not None:
exp_result_obj = obj(exp_result, tc_name)

Expand All @@ -717,9 +727,7 @@ def runtestcase(self, testcase):
exp_type = type(exp_result_obj)
# pylint: disable=unidiomatic-typecheck
if act_type != exp_type:
print("Details for the following assertion error:")
print("- Expected result type: %s" % type(exp_result_obj))
print("- Actual result type: %s" % type(result))
show_diff(None, type(exp_result_obj), type(result), 'type')
raise AssertionError("PyWBEM CIM result type is not"
" as expected.")

Expand Down Expand Up @@ -749,89 +757,60 @@ def runtestcase(self, testcase):
else:
# pylint: disable=redefined-variable-type
_result = result

if _result != _exp_result_obj:
# TODO 2016/07 AM: Improve the presentation of the difference
print("Details for the following assertion error:")
print("- Expected result: %s" % repr(exp_result_obj))
print("- Actual result: %s" % repr(_result))
if conn.debug:
print("- HTTP response data: %r" % conn.last_raw_reply)
show_diff(conn, repr(exp_result_obj), repr(_result), 'data')
raise AssertionError("WBEMConnection operation method result "
"is not as expected.")

# if this is a pull result, compare the components of expected
# and actual results.
# and actual results. Pull results return a tuple
elif exp_pull_result is not None:
exp_pull_result_obj = result_tuple(exp_pull_result, tc_name)

# Length should be the same
# Result length should be the same as expected result
if len(result) != len(exp_pull_result_obj):
print("Details for the following assertion error:")
print("- Expected pull_result tuple size: %s" %
len(exp_pull_result_obj))
print("- Actual result len: %s" % len(result))
# print('result %s exp %s' % ((result, ),
# (exp_pull_result_obj, )))
show_diff(conn, len(conn, exp_pull_result_obj), len(result),
'tuple size')
raise AssertionError("PyWBEM CIM result type is not"
" as expected.")
# eos is required result
if result.eos != exp_pull_result_obj.eos:
print("Details for the following assertion error:")
print("- Expected pull result.eos: %r" %
exp_pull_result_obj.eos)
print("- Actual pull result.eos: %r" % result.eos)
if conn.debug:
print("- HTTP response data: %r" % conn.last_raw_reply)
show_diff(conn, exp_pull_result_obj.eos, result.eos,
'result.eos')
raise AssertionError("WBEMConnection operation method result "
"is not as expected.")

# Context is required result
# NOTE: pyaml does not natively support tuples
# It supports very simple tuples but only with single objects and
# in block mode.
# NOTE: pyaml does not natively support tuples. It supports very
# simple tuples but only with single objects and in block mode.
exp_context = tuple(exp_pull_result_obj.context) \
if exp_pull_result_obj.context \
else None
if result.context != exp_context:
print("Details for the following assertion error:")
print("- Expected pull result.context: %r" %
str_tuple(exp_context))
print("- Actual pull result.context: %r" %
str_tuple(result.context))
if conn.debug:
print("- HTTP response data: %r" % conn.last_raw_reply)
show_diff(conn, repr(str_tuple(exp_context)),
repr(str_tuple(result.context)), 'result.context')
raise AssertionError("WBEMConnection operation method result "
"is not as expected.")

if "instances" in exp_pull_result:
if result.instances != exp_pull_result_obj.instances:
# TODO 2016/07 AM: Improve the presentation of the diff.
print("Details for the following assertion error:")
print("- Expected pull result: %r" %
exp_pull_result_obj.instances)
print("- Actual pull result: %r" % result.instances)
if conn.debug:
print("- HTTP response data: %r" % conn.last_raw_reply)
raise AssertionError("WBEMConnection operation method "
"result is not as expected.")
_result = result.instances
_exp_result = exp_pull_result_obj.instances
elif "paths" in exp_pull_result:
if result.paths != exp_pull_result_obj.paths:
# TODO 2016/07 AM: Improve the presentation of the diff.
print("Details for the following assertion error:")
print("- Expected pull result: %r" %
exp_pull_result_obj.paths)
print("- Actual pull result: %r" % result.paths)
if conn.debug:
print("- HTTP response data: %r" % conn.last_raw_reply)
raise AssertionError("WBEMConnection operation method "
"result is not as expected.")
_result = result.paths
_exp_result = exp_pull_result_obj.paths
else:
# If there are no instances or paths in response, use
# instances: []
raise AssertionError("WBEMConnection operation method result "
"is not as expected. No 'instances' "
"or 'paths' component.")

if _result != _exp_result:
# TODO 2016/07 AM: Improve the presentation of the diff.
show_diff(conn, repr(_exp_result), repr(_result), 'result data')
raise AssertionError("WBEMConnection operation method "
"result is not as expected.")

# TODO redo as indexed loop to compare all items.

else:
Expand Down Expand Up @@ -860,15 +839,15 @@ def result_tuple(value, tc_name):

# either path or instances should be in value
if "instances" in value:
instances = value["instances"]
objs = obj(instances, tc_name)
# instances = value["instances"]
objs = obj(value["instances"], tc_name)
if 'paths' in value:
raise AssertionError("WBEMConnection operation method "
"result is not as expected. Both "
"'instances' and 'paths' component.")
elif "paths" in value:
paths = value["paths"]
objs = obj(paths, tc_name)
# paths = value["paths"]
objs = obj(value["paths"], tc_name)
result = namedtuple("result", ["paths", "eos", "context"])
else:
raise AssertionError("WBEMConnection operation method result "
Expand All @@ -888,7 +867,7 @@ def result_tuple(value, tc_name):


if __name__ == '__main__':
"""Main function of test_client. Calls unittest"""

# NonDocumented option to run a single testcase if that testcase name
# is listed on the cmd line.
if len(sys.argv) > 1:
Expand Down

0 comments on commit d7c2bd7

Please sign in to comment.