def display_class_tree(classes, top_class=None): """ Display the list of classes as a left justified tree in ascii to the click.echo output Parameters: classes (list of :class:`~pywbem.CIMClass`) top_class (:term: `string`) The top level class to display or None if the display is from root. """ # build dictionary of classname : superclassname cn_supercn = {cl.classname: cl.superclass for cl in classes} # if top_class is none, create artifical root if top_class is None: for cn in cn_supercn: if not cn_supercn[cn]: cn_supercn[cn] = 'root' top_class = 'root' # Hack to build the class to subclass dictionary from the # superclass to class dictionary cn_subcn = NocaseDict() # pylint: disable=bad-continuation, expression-not-assigned [ cn_subcn.setdefault(v, []).append(k) for (k, v) in six.iteritems(cn_supercn) ] # noqa: F841 tree = build_tree(cn_subcn, top_class) tr = LeftAligned() click.echo(tr(tree))
def test_order_preservation(self): """Test order preservation of itervalues()""" dic = NocaseDict() for key, value in self.order_tuples: dic[key] = value i = 0 for value in dic.itervalues(): exp_value = self.order_tuples[i][1] self.assertEqual(value, exp_value) i += 1
def test_order_preservation(self): """Test order preservation of iteritems()""" dic = NocaseDict() for key, value in self.order_tuples: dic[key] = value i = 0 for item in dic.iteritems(): exp_item = self.order_tuples[i] self.assertEqual(item, exp_item) i += 1
def test_reliable_order(self): """Test that repr() has a reliable result despite different orders of insertion into the dictionary.""" dic1 = NocaseDict() dic1['Budgie'] = 'Fish' dic1['Dog'] = 'Cat' dic1['Foo'] = 'Bla' dic2 = NocaseDict() dic2['Foo'] = 'Bla' dic2['Dog'] = 'Cat' dic2['Budgie'] = 'Fish' self.assertEqual(repr(dic1), repr(dic2))
def test_reliable_order(self): """Test that repr() has a reliable result for two dicts with the same insertion order.""" dic1 = NocaseDict() dic1['Budgie'] = 'Fish' dic1['Foo'] = 'Bla' dic1['Dog'] = 'Cat' dic2 = NocaseDict() dic2['Budgie'] = 'Fish' dic2['Foo'] = 'Bla' dic2['Dog'] = 'Cat' self.assertEqual(repr(dic1), repr(dic2))
def test_unnamed_keys(self): """Test unnamed keys.""" dic = NocaseDict() dic.allow_unnamed_keys = True dic[None] = 'a' assert None in dic assert len(dic) == 1 a_val = dic[None] assert a_val == 'a' del dic[None] assert None not in dic assert not dic
def assertCIMProperty(self, obj, name, value, type_=None, class_origin=None, array_size=None, propagated=None, is_array=False, reference_class=None, qualifiers=None, embedded_object=None): """ Verify the attributes of the CIMProperty object in `obj` against expected values passed as the remaining arguments. """ self.assertEqual(obj.name, name, "name attribute") self.assertEqual(obj.value, value, "value attribute") self.assertEqual(obj.type, type_, "type attribute") self.assertEqual(obj.class_origin, class_origin, "class_origin attribute") self.assertEqual(obj.array_size, array_size, "array_size attribute") self.assertEqual(obj.propagated, propagated, "propagated attribute") self.assertEqual(obj.is_array, is_array, "is_array attribute") self.assertEqual(obj.reference_class, reference_class, "reference_class attribute") self.assertEqual(obj.qualifiers, NocaseDict(qualifiers), "qualifiers attribute") self.assertEqual(obj.embedded_object, embedded_object, "embedded_object attribute")
def test_order_preservation(self): """Test order preservation of for loop on dict""" dic = NocaseDict() for key, value in self.order_tuples: dic[key] = value i = 0 for key in dic: item = (key, dic[key]) exp_item = self.order_tuples[i] self.assertEqual(item, exp_item) i += 1
def _tree_node(class_subclass_dict, cn): """ Build dictionary of the class/subclass relationships for class cn in dictionary of class_subclass names. Returns dictionary of dictionaries in form suitable for asciitree """ node_dict = NocaseDict() # If there is no subclass, the class will not exist in this dictionary if cn in class_subclass_dict: cn_list = class_subclass_dict[cn] # This should not be necessary if end nodes are not in the dict. if cn_list: for key in cn_list: node_dict[key] = _tree_node(class_subclass_dict, key) else: node_dict = NocaseDict() else: return {} return node_dict
def setUp(self): """unittest setUp creates NoCaseDict""" self.dic = NocaseDict() self.dic['Dog'] = 'Cat' self.dic['Budgie'] = 'Fish' self.order_tuples = ( ('Dog', 'Cat'), ('Budgie', 'Fish'), ('Ham', 'Jam'), ('Sofi', 'Blue'), ('Gabi', 'Red'), )
def test_all(self): # Basic init dic = NocaseDict() self.assertTrue(len(dic) == 0) # Initialise from sequence object dic = NocaseDict([('Dog', 'Cat'), ('Budgie', 'Fish')]) self.assertTrue(len(dic) == 2) self.assertTrue(dic['Dog'] == 'Cat' and dic['Budgie'] == 'Fish') # Initialise from mapping object dic = NocaseDict({'Dog': 'Cat', 'Budgie': 'Fish'}) self.assertTrue(len(dic) == 2) self.assertTrue(dic['Dog'] == 'Cat' and dic['Budgie'] == 'Fish') # Initialise from kwargs dic = NocaseDict(Dog='Cat', Budgie='Fish') self.assertTrue(len(dic) == 2) self.assertTrue(dic['Dog'] == 'Cat' and dic['Budgie'] == 'Fish')
def assert_CIMProperty_attrs( self, obj, name, value, type_=None, class_origin=None, array_size=None, propagated=None, is_array=False, reference_class=None, qualifiers=None, embedded_object=None): """ Verify the attributes of the CIMProperty object in `obj` against expected values passed as the remaining arguments. """ self.assertEqual(obj.name, name) self.assertEqual(obj.value, value) self.assertEqual(obj.type, type_) self.assertEqual(obj.class_origin, class_origin) self.assertEqual(obj.array_size, array_size) self.assertEqual(obj.propagated, propagated) self.assertEqual(obj.is_array, is_array) self.assertEqual(obj.reference_class, reference_class) self.assertEqual(obj.qualifiers, NocaseDict(qualifiers)) self.assertEqual(obj.embedded_object, embedded_object)
def setUp(self): self.dic = NocaseDict() self.dic['Dog'] = 'Cat' self.dic['Budgie'] = 'Fish'
def test_all(self): # The base dictionary that is used for all comparisons base_dict = dict({'Budgie': 'Fish', 'Dog': 'Cat'}) # Test dictionaries to test against the base dict, as a list of # tuple(dict, relation, comment), with relation being the expected # comparison relation, and one of ('eq', 'ne'). test_dicts = [ (dict({ 'Budgie': 'Fish', 'Dog': 'Cat' }), 'eq', 'Same'), (dict({'Budgie': 'Fish'}), 'ne', 'Higher key missing, shorter size'), (dict({'Dog': 'Cat'}), 'ne', 'Lower key missing, shorter size'), (dict({ 'Budgie': 'Fish', 'Curly': 'Snake', 'Cozy': 'Dog' }), 'ne', 'First non-matching key is less. But longer size!'), (dict({ 'Alf': 'F', 'Anton': 'S', 'Aussie': 'D' }), 'ne', 'Only non-matching keys that are less. But longer size!'), (dict({'Budgio': 'Fish'}), 'ne', 'First non-matching key is greater. But shorter size!'), (dict({'Zoe': 'F'}), 'ne', 'Only non-matching keys that are greater. But shorter size!'), (dict({ 'Budgie': 'Fish', 'Curly': 'Snake' }), 'ne', 'Same size. First non-matching key is less'), (dict({ 'Alf': 'F', 'Anton': 'S' }), 'ne', 'Same size. Only non-matching keys that are less'), (dict({ 'Zoe': 'F', 'Zulu': 'S' }), 'ne', 'Same size. Only non-matching keys that are greater'), (dict({ 'Budgie': 'Fish', 'Dog': 'Car' }), 'ne', 'Same size, only matching keys. First non-matching value is less' ), (dict({ 'Budgie': 'Fish', 'Dog': 'Caz' }), 'ne', 'Same size, only matching keys. First non-matching value is grt.' ), ] # First, run these tests against a standard dictionary to verify # that the test case definitions conform to that self.run_test_dicts(base_dict, test_dicts) # Then, transform these tests to NocaseDict and run them again TEST_CASE_INSENSITIVITY = True base_ncdict = NocaseDict(base_dict) test_ncdicts = [] for test_dict, relation, comment in test_dicts: test_ncdict = NocaseDict() for key in test_dict: if TEST_CASE_INSENSITIVITY: nc_key = swapcase2(key) else: nc_key = key test_ncdict[nc_key] = test_dict[key] test_ncdicts.append((test_ncdict, relation, comment)) self.run_test_dicts(base_ncdict, test_ncdicts)
def runtestcase(self, testcase): """Run a single test case.""" tc_name = tc_getattr("", testcase, "name") tc_desc = tc_getattr(tc_name, testcase, "description", None) tc_ignore = tc_getattr(tc_name, testcase, "ignore_python_version", None) tc_ignore_test = tc_getattr(tc_name, testcase, "ignore_test", None) # Test to determine if execute this testcase # 1. If the RUN_ONE_TESTCASE option set and this is not the one # 2. if ingore_python_version set and version does not match if RUN_ONE_TESTCASE is not None: if tc_name != RUN_ONE_TESTCASE: return else: if tc_ignore_test is not None: print("IGNORE test case: %s: %s. Ignore_test: set" % (tc_name, tc_desc)) return if six.PY2 and tc_ignore == 2 or six.PY3 and tc_ignore == 3: print("IGNORE test case: %s: %s for python version %s" % (tc_name, tc_desc, tc_ignore)) return print("Process test case: %s: %s" % (tc_name, tc_desc)) httpretty.httpretty.allow_net_connect = False pywbem_request = tc_getattr(tc_name, testcase, "pywbem_request") exp_http_request = tc_getattr(tc_name, testcase, "http_request", None) http_response = tc_getattr(tc_name, testcase, "http_response", None) exp_pywbem_response = tc_getattr(tc_name, testcase, "pywbem_response") # Setup HTTPretty for one WBEM operation if exp_http_request is not None: exp_http_exception = tc_getattr(tc_name, http_response, "exception", None) if exp_http_exception is None: params = { "body": tc_getattr(tc_name, http_response, "data"), "adding_headers": tc_getattr(tc_name, http_response, "headers", None), "status": tc_getattr(tc_name, http_response, "status") } else: callback_name = exp_http_exception try: callback_func = getattr(Callback(), callback_name) except AttributeError: raise ClientTestError("Error in testcase %s: Unknown " "exception callback specified: %s" % (tc_name, callback_name)) params = {"body": callback_func} method = tc_getattr(tc_name, exp_http_request, "verb") uri = tc_getattr(tc_name, exp_http_request, "url") httpretty.register_uri(method=method, uri=uri, **params) conn = pywbem.WBEMConnection( url=tc_getattr(tc_name, pywbem_request, "url"), creds=tc_getattr(tc_name, pywbem_request, "creds"), default_namespace=tc_getattr(tc_name, pywbem_request, "namespace"), timeout=tc_getattr(tc_name, pywbem_request, "timeout"), enable_stats=tc_getattr(tc_name, pywbem_request, "enable-stats", False)) conn.debug = tc_getattr(tc_name, pywbem_request, "debug", False) op = tc_getattr(tc_name, pywbem_request, "operation") # Example: # "operation": { # "pywbem_method": "GetInstance", # "InstanceName": { # "pywbem_object": "CIMInstanceName", # "classname": "PyWBEM_Person", # "keybindings": { # "Name": "Fritz" # } # }, # "LocalOnly": False # } op_name = tc_getattr(tc_name, op, "pywbem_method") op_args = {} for arg_name in op: if arg_name == "pywbem_method": continue op_args[arg_name] = obj(op[arg_name], tc_name) try: op_call = getattr(conn, op_name) except AttributeError as exc: raise ClientTestError("Error in definition of testcase %s: " "Unknown operation name: %s" % (tc_name, op_name)) # Invoke the PyWBEM operation to be tested try: result = op_call(**op_args) raised_exception = None except Exception as exc: # pylint: disable=broad-except raised_exception = exc stringio = six.StringIO() traceback.print_exc(file=stringio) raised_traceback_str = stringio.getvalue() stringio.close() result = None # Validate PyWBEM result and exceptions. # We validate exceptions before validating the HTTP request, because # an exception might have been raised on the way down before the # request was actually made. exp_exception = tc_getattr(tc_name, exp_pywbem_response, "exception", None) exp_cim_status = tc_getattr(tc_name, exp_pywbem_response, "cim_status", 0) # get the optional expected request and reply sizes if specified. The # default is None if not specified exp_request_len = tc_getattr_list(tc_name, exp_pywbem_response, "request_len", None) exp_reply_len = tc_getattr_list(tc_name, exp_pywbem_response, "reply_len", None) # get the expected result. This may be either the the definition # of a value or cimobject or a list of values or cimobjects or # a named tuple of results. exp_result = tc_getattr_list(tc_name, exp_pywbem_response, "result", None) exp_pull_result = tc_getattr(tc_name, exp_pywbem_response, "pullresult", None) if exp_pull_result and exp_result: raise ClientTestError("Error in definition of testcase %s: " "result and pull result attributes " "are exclusive.") if exp_exception is not None and exp_result is not None: raise ClientTestError("Error in definition of testcase %s: " "'result' and 'exception' attributes in " "'pywbem_result' are not compatible." % tc_name) if exp_cim_status != 0 and exp_result is not None: raise ClientTestError("Error in definition of testcase %s: " "'result' and 'cim_status' attributes in " "'pywbem_result' are not compatible." % tc_name) if exp_cim_status != 0: exp_exception = 'CIMError' if exp_exception is not None: if raised_exception is None: raise AssertionError("Testcase %s: A %s exception was " "expected to be raised by PyWBEM " "operation %s, but no exception was " "actually raised." % (tc_name, exp_exception, op_name)) elif raised_exception.__class__.__name__ != exp_exception: raise AssertionError( "Testcase %s: A %s exception was " "expected to be raised by PyWBEM " "operation %s, but a different " "exception was actually raised:\n" "%s\n" % (tc_name, exp_exception, op_name, raised_traceback_str)) else: if raised_exception is not None: raise AssertionError("Testcase %s: No exception was " "expected to be raised by PyWBEM " "operation %s, but an exception was " "actually raised:\n" "%s\n" % (tc_name, op_name, raised_traceback_str)) # Validate HTTP request produced by PyWBEM if exp_http_request is not None: http_request = httpretty.last_request() self.assertTrue( not isinstance(http_request, HTTPrettyRequestEmpty), "HTTP request is empty") exp_verb = tc_getattr(tc_name, exp_http_request, "verb") self.assertEqual( http_request.method, exp_verb, "Verb in HTTP request is: %s (expected: %s)" % (http_request.method, exp_verb)) exp_headers = tc_getattr(tc_name, exp_http_request, "headers", {}) for header_name in exp_headers: self.assertEqual( http_request.headers[header_name], exp_headers[header_name], "Value of %s header in HTTP request is: %s " "(expected: %s)" % (header_name, http_request.headers[header_name], exp_headers[header_name])) exp_data = tc_getattr(tc_name, exp_http_request, "data", None) self.assertXMLEqual(http_request.body, exp_data, "Unexpected CIM-XML payload in HTTP request") if exp_request_len is not None: self.assertEqual( exp_request_len, conn.last_request_len, 'request lengths do not match. exp %s rcvd %s' % (exp_request_len, conn.last_request_len)) if conn.stats_enabled: snapshot = conn.statistics.snapshot() self.assertEqual(len(snapshot), 1) # one operation; one stat for name, stats in snapshot: # pylint: disable=unused-variable stat = stats self.assertEqual(stat.count, 1, "Expected a single statistic") self.assertEqual(stat.min_request_len, stat.max_request_len) self.assertEqual(stat.min_request_len, exp_request_len) if exp_reply_len is not None: self.assertEqual( exp_reply_len, conn.last_reply_len, 'Reply lengths do not match. exp %s rcvd %s' % (exp_reply_len, conn.last_reply_len)) if conn.stats_enabled: snapshot = conn.statistics.snapshot() self.assertEqual(len(snapshot), 1) # one operation; one stat for name, stats in snapshot: stat = stats self.assertEqual(stat.count, 1, "Expected a single statistic") self.assertEqual(stat.min_reply_len, stat.max_reply_len) self.assertEqual(stat.min_reply_len, exp_reply_len) # Continue with validating the result if isinstance(raised_exception, pywbem.CIMError): cim_status = raised_exception.args[0] else: cim_status = 0 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) # The testcase can only specify lists but not tuples, so we # tolerate tuple/list mismatches: act_type = type(result) if act_type == tuple: act_type = list exp_type = type(exp_result_obj) # pylint: disable=unidiomatic-typecheck if act_type != exp_type: show_diff(None, type(exp_result_obj), type(result), 'type') raise AssertionError("PyWBEM CIM result type is not" " as expected.") # The testcase can only specify dicts but not NocaseDicts, so we # tolerate such mismatches (in case of InvokeMethod): if isinstance(exp_result_obj, list) and \ len(exp_result_obj) == 2 and \ isinstance(exp_result_obj[1], dict): _exp_result_obj = (exp_result_obj[0], NocaseDict(exp_result_obj[1])) else: _exp_result_obj = exp_result_obj # If result items are tuple, convert to lists. This is for # class ref and assoc results. if isinstance(result, list) and \ result and isinstance(result[0], tuple): _result = [] for item in result: if isinstance(item, tuple): _result.append(list(item)) else: _result.append(item) else: _result = result if _result != _exp_result_obj: # TODO 2016/07 AM: Improve the presentation of the difference 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. Pull results return a tuple elif exp_pull_result is not None: exp_pull_result_obj = result_tuple(exp_pull_result, tc_name) # Result length should be the same as expected result if len(result) != len(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: 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. exp_context = tuple(exp_pull_result_obj.context) \ if exp_pull_result_obj.context \ else None if result.context != exp_context: 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: _result = result.instances _exp_result = exp_pull_result_obj.instances elif "paths" in exp_pull_result: _result = result.paths _exp_result = exp_pull_result_obj.paths else: 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: self.assertEqual( result, None, "PyWBEM CIM result is not None: %s" % repr(result))
def test_all(self): dic2 = NocaseDict({'dog': 'Cat', 'Budgie': 'Fish'}) self.assertTrue(self.dic == dic2) dic2['Budgie'] = 'fish' self.assertTrue(self.dic != dic2)
def test_all(self): """Test all init options""" # Empty dic = NocaseDict() self.assertTrue(len(dic) == 0) dic = NocaseDict(None) self.assertTrue(len(dic) == 0) dic = NocaseDict(list()) self.assertTrue(len(dic) == 0) dic = NocaseDict(tuple()) self.assertTrue(len(dic) == 0) dic = NocaseDict(dict()) self.assertTrue(len(dic) == 0) dic = NocaseDict(dic) self.assertTrue(len(dic) == 0) # Initialise from iterable dic = NocaseDict([('Dog', 'Cat'), ('Budgie', 'Fish')]) self.assertTrue(len(dic) == 2) self.assertTrue(dic['Dog'] == 'Cat' and dic['Budgie'] == 'Fish') dic = NocaseDict((('Dog', 'Cat'), ('Budgie', 'Fish'))) self.assertTrue(len(dic) == 2) self.assertTrue(dic['Dog'] == 'Cat' and dic['Budgie'] == 'Fish') # Initialise from dictionary with pytest.warns(UserWarning) as rec_warnings: dic = NocaseDict({'Dog': 'Cat', 'Budgie': 'Fish'}) assert len(rec_warnings) == 1 self.assertTrue(len(dic) == 2) self.assertTrue(dic['Dog'] == 'Cat' and dic['Budgie'] == 'Fish') # Initialise from kwargs with pytest.warns(UserWarning) as rec_warnings: dic = NocaseDict(Dog='Cat', Budgie='Fish') assert len(rec_warnings) == 1 self.assertTrue(len(dic) == 2) self.assertTrue(dic['Dog'] == 'Cat' and dic['Budgie'] == 'Fish') # Initialise from iterable and kwargs dic = NocaseDict([('Dog', 'Cat'), ], Budgie='Fish') self.assertTrue(len(dic) == 2) self.assertTrue(dic['Dog'] == 'Cat' and dic['Budgie'] == 'Fish') dic = NocaseDict((('Dog', 'Cat'),), Budgie='Fish') self.assertTrue(len(dic) == 2) self.assertTrue(dic['Dog'] == 'Cat' and dic['Budgie'] == 'Fish') # Initialise from dictionary and kwargs dic = NocaseDict({'Dog': 'Cat'}, Budgie='Fish') self.assertTrue(len(dic) == 2) self.assertTrue(dic['Dog'] == 'Cat' and dic['Budgie'] == 'Fish') # Initialise from unsupported object type try: dic = NocaseDict('illegal') except TypeError: pass else: self.fail("TypeError was unexpectedly not thrown.") # Initialise with too many positional arguments try: dic = NocaseDict(list(), list()) except TypeError: pass else: self.fail("TypeError was unexpectedly not thrown.")
TESTCASES_NOCASEDICT_EQUAL_HASH = [ # Each testcase tuple has these items: # * desc: Short testcase description. # * kwargs: Input arguments for test function, as a dict: # * obj1: CIMInstanceName object #1 to use. # * obj2: CIMInstanceName object #2 to use. # * exp_obj_equal: Expected equality of the objects. # * exp_exc_types: Expected exception type(s), or None. # * exp_warn_types: Expected warning type(s), or None. # * condition: Boolean condition for testcase to run, or 'pdb' for debugger ( "Empty dictionary", dict( obj1=NocaseDict([]), obj2=NocaseDict([]), exp_obj_equal=True, ), None, None, True ), ( "One item, keys and values equal", dict( obj1=NocaseDict([('k1', 'v1')]), obj2=NocaseDict([('k1', 'v1')]), exp_obj_equal=True, ), None, None, True ), (
exp_result="{'a': 1}", ), None, None, True ), ( "OrderedDict of strings", dict( value=OrderedDict([('a', 1), ('b', 2)]), exp_result="OrderedDict({'a': 1, 'b': 2})", ), None, None, True ), ( "NocaseDict of strings", dict( value=NocaseDict([('a', 1), ('b', 2)]), exp_result="NocaseDict({'a': 1, 'b': 2})", ), None, None, True ), ] @pytest.mark.parametrize( "desc, kwargs, exp_exc_types, exp_warn_types, condition", TESTCASES_ASCII2) @simplified_test_function def test_ascii2(testcase, value, exp_result): """ Test function for _ascii2(). """
def setUp(self): """unittest setUp creates NoCaseDict""" self.dic = NocaseDict() self.dic['Dog'] = 'Cat' self.dic['Budgie'] = 'Fish'