def check_cvs(self, ds): # get CV structure to check my_cv_structure = cv_structure(__cmip6_cv_struct_dict__) needed_cvs = my_cv_structure.get_cv_names_needed() # determine directory my_cv_directory_collection = data_directory_collection( self.__default_dir_env_vars__['cmip6_json'], self._cc_spec, 'cc') # update CVs if update necessary if my_cv_directory_collection.__do_update__: update_cmip6_json_cv(needed_cvs, my_cv_directory_collection) # get CVs cvs = read_cmip6_json_cv(needed_cvs, my_cv_directory_collection) # initialize further things results = [] # Usage of `results` in the called functions: # results.append([Result(BaseCheck.MEDIUM, check, 'blub', ['blab'])]) results = self.iterate_cv_structure(results, ds, my_cv_structure, cvs) return results
def test__cv_tools__check_cv(): """ """ ## prepare input data dummy_cv_struct_good_A = cv_structure(dummy_cv_struct_good_01) dummy_cv_struct_good_B = cv_structure(dummy_cv_struct_good_03) dummy_cv_struct_bad_cv_name = cv_structure(dummy_cv_struct_bad_07) # TODO: test: # ## check_cv(cv_struct, attribute, cvs, value) # check_cv(dummy_cv_struct_good_A, 'attr01', dummy_cv, 5) # TODO: define tests here! # TODO: check if value and cv are of different types ## take modified versions of non-error tests of `extract_cv` here # name of instance of cv_structure: `cv_struct` # try incorrect attribute # correct cv # => ValueError with pytest.raises(ValueError): tmp = dummy_cv_struct_good_A.check_cv('attr03', dummy_cv, 'DKRZ') # name of instance of cv_structure: `cv_struct` # try wrong type for attribute # correct cv # => TypeError with pytest.raises(TypeError): tmp = dummy_cv_struct_good_A.check_cv(77, dummy_cv, 'DKRZ') # name of instance of cv_structure: `cv_struct` # correct attribute # wrong type of cv # => TypeError with pytest.raises(TypeError): tmp = dummy_cv_struct_good_A.check_cv('attr01', 42, 'DKRZ') # name of instance of cv_structure: `cv_struct` # correct attribute; but the corresponding CV is not in dummy_cv # correct cv but it does not requested cv # => KeyError with pytest.raises(KeyError): tmp = dummy_cv_struct_bad_cv_name.check_cv('attr11', dummy_cv, 'DKRZ') # name of instance of cv_structure: `cv_struct` # try incorrect attribute # correct cv # => ValueError with pytest.raises(ValueError): tmp = dummy_cv_struct_good_B.check_cv('attr03', dummy_cv, 'a string to check') # name of instance of cv_structure: `cv_struct` # try wrong type for attribute # correct cv # => TypeError with pytest.raises(TypeError): tmp = dummy_cv_struct_good_B.check_cv(77, dummy_cv, 'a string to check') # name of instance of cv_structure: `cv_struct` # correct attribute # wrong type of cv # => TypeError with pytest.raises(TypeError): tmp = dummy_cv_struct_good_B.check_cv('attr01', 42, 'a string to check') # name of instance of cv_structure: `cv_struct` # correct attribute # wrong type of cv # guess = False (default) # => TypeError with pytest.raises(TypeError): tmp = dummy_cv_struct_good_B.check_cv('attr01', 42, 'a string to check', False) # name of instance of cv_structure: `cv_struct` # correct attribute; but the corresponding CV is not in dummy_cv # correct cv but it does not requested cv # => KeyError with pytest.raises(KeyError): tmp = dummy_cv_struct_bad_cv_name.check_cv('attr11', dummy_cv, 'a string to check') # name of instance of cv_structure: `cv_struct` # try correct attribute # correct cv # wrong type of guess # => TypeError with pytest.raises(TypeError): tmp = dummy_cv_struct_good_B.check_cv('attr01', dummy_cv, 'a string to check', 5) # name of instance of cv_structure: `cv_struct` # try correct attribute # list as cv # guess = True # but dummy_cv_struct_good['attr13'][2] contains a function that cannot # be applied to `example_list` # => TypeError example_list = ['abc', 'def'] with pytest.raises(TypeError): tmp = dummy_cv_struct_good_B.check_cv('attr13', example_list, 'a string to check', True) # name of instance of cv_structure: `cv_struct` # try correct attribute # dict as cv # guess = True # dummy_cv_struct_good['attr12'][1] not in example_dict example_dict = {'cv98': ['abc', 'def']} # 'cv99' is dummy_cv_struct_good['attr12'][1] but is not in `example_dict` with pytest.raises(KeyError): tmp = dummy_cv_struct_good_B.check_cv('attr12', example_dict, 'a string to check', True)
def test__cv_tools__extract_cv(): # TODO: extend test to check the output-cv when `list`[2] is not None # input data: # some basic cv_structure dummy_cv_struct_good = cv_structure(dummy_cv_struct_good_03) dummy_cv_struct_bad_cv_name = cv_structure(dummy_cv_struct_bad_07) ## some successful tests # name of instance of cv_structure: `cv_struct` # try correct attribute # correct cv # => no error assert dummy_cv[dummy_cv_struct_good['attr01'][1]].keys() == \ dummy_cv_struct_good.extract_cv('attr01', dummy_cv) # the `keys` is in `dummy_cv_struct_good['attr01'][2]` # name of instance of cv_structure: `cv_struct` # try another correct attribute # correct cv # => no error output_expected = set(dummy_cv[dummy_cv_struct_good['attr02'][1]].values()) output_present = set(dummy_cv_struct_good.extract_cv('attr02', dummy_cv)) # the `values` is in `dummy_cv_struct_good['attr02'][2]` assert 0 == len(output_present.symmetric_difference(output_expected)) # name of instance of cv_structure: `cv_struct` # try another correct attribute; the corresponding CV consists of sub-CVs # correct cv # => no error assert dummy_cv[dummy_cv_struct_good['attr09'][1]].keys() == \ dummy_cv_struct_good.extract_cv('attr09', dummy_cv) # the `keys` is in `dummy_cv_struct_good['attr09'][2]` # name of instance of cv_structure: `cv_struct` # try correct attribute # correct cv # guess = False # => no error assert dummy_cv[dummy_cv_struct_good['attr01'][1]].keys() == \ dummy_cv_struct_good.extract_cv('attr01', dummy_cv, False) # the `keys` is in `dummy_cv_struct_good['attr01'][2]` # name of instance of cv_structure: `cv_struct` # try correct attribute # correct cv # guess = True # => no error assert dummy_cv[dummy_cv_struct_good['attr01'][1]].keys() == \ dummy_cv_struct_good.extract_cv('attr01', dummy_cv, True) # the `keys` is in `dummy_cv_struct_good['attr01'][2]` # name of instance of cv_structure: `cv_struct` # try correct attribute # list as cv # guess = True # => no error example_list = ['abc', 'def'] assert example_list == dummy_cv_struct_good.extract_cv('attr11', example_list, True) # name of instance of cv_structure: `cv_struct` # try correct attribute # dict as cv # guess = True # => no error example_dict = {'cv99': ['abc', 'def']} # 'cv99' equals dummy_cv_struct_good['attr12'][1] assert example_dict['cv99'] == dummy_cv_struct_good.extract_cv('attr12', example_dict, True) # name of instance of cv_structure: `cv_struct` # try correct attribute # dict as cv # guess = True # => no error example_dict = {'': ['abc', 'def']} # '' equals dummy_cv_struct_good['attr11'][1] assert example_dict[''] == dummy_cv_struct_good.extract_cv('attr11', example_dict, True) # name of instance of cv_structure: `cv_struct` # try correct attribute # dict as cv # guess = True # => no error example_dict = {'cv99': ['abc', 'def']} # '' equals dummy_cv_struct_good['attr11'][1]; if '' is not a key in the # cv (as it is in this case; `example_dict` is the cv) then we get back the # original dict/cv/example_dict (except it an additional function was # applied; which was not the case here); output_expected = example_dict output_present = dummy_cv_struct_good.extract_cv('attr11', example_dict, True) assert output_expected.keys() == output_present.keys() assert 0 == len(set(output_present).symmetric_difference(set(output_expected))) # name of instance of cv_structure: `cv_struct` # try correct attribute # dict as cv # guess = True # => no error example_dict = {'cv99': ['abc', 'def']} # 'cv99' is just a dummy key # dummy_cv_struct_good['attr13'][1] is empty string but # dummy_cv_struct_good['attr13'][2] contains `keys` (function to apply) assert example_dict.keys() == dummy_cv_struct_good.extract_cv('attr13', example_dict, True) # name of instance of cv_structure: `cv_struct` # correct attribute # wrong type of cv # guess = True # => no error assert 42 == dummy_cv_struct_good.extract_cv('attr11', 42, True) # name of instance of cv_structure: `cv_struct` # try incorrect attribute # correct cv # => ValueError with pytest.raises(ValueError): tmp = dummy_cv_struct_good.extract_cv('attr03', dummy_cv) # name of instance of cv_structure: `cv_struct` # try wrong type for attribute # correct cv # => TypeError with pytest.raises(TypeError): tmp = dummy_cv_struct_good.extract_cv(77, dummy_cv) # name of instance of cv_structure: `cv_struct` # correct attribute # wrong type of cv # => TypeError with pytest.raises(TypeError): tmp = dummy_cv_struct_good.extract_cv('attr01', 42) # name of instance of cv_structure: `cv_struct` # correct attribute # wrong type of cv # guess = False (default) # => TypeError with pytest.raises(TypeError): tmp = dummy_cv_struct_good.extract_cv('attr01', 42, False) # name of instance of cv_structure: `cv_struct` # correct attribute; but the corresponding CV is not in dummy_cv # correct cv but it does not requested cv # => KeyError with pytest.raises(KeyError): tmp = dummy_cv_struct_bad_cv_name.extract_cv('attr11', dummy_cv) # name of instance of cv_structure: `cv_struct` # try correct attribute # correct cv # wrong type of guess # => TypeError with pytest.raises(TypeError): tmp = dummy_cv_struct_good.extract_cv('attr01', dummy_cv, 5) # name of instance of cv_structure: `cv_struct` # try correct attribute # list as cv # guess = True # but dummy_cv_struct_good['attr13'][2] contains a function that cannot # be applied to `example_list` # => TypeError example_list = ['abc', 'def'] with pytest.raises(TypeError): tmp = dummy_cv_struct_good.extract_cv('attr13', example_list, True) # name of instance of cv_structure: `cv_struct` # try correct attribute # dict as cv # guess = True # dummy_cv_struct_good['attr12'][1] not in example_dict example_dict = {'cv98': ['abc', 'def']} # 'cv99' is dummy_cv_struct_good['attr12'][1] but is not in `example_dict` with pytest.raises(KeyError): tmp = dummy_cv_struct_good.extract_cv('attr12', example_dict, True)
def test_cv_structure(): ### ~~~~~~~~~~~~~~~~~~~~~~ TEST __init__ ~~~~~~~~~~~~~~~~~~~~~~ ## test `__init__` call itself # call `__init__` successful and get back an instance of `cv_struture` for test_dict in list_cv_structs_NoError: assert isinstance(cv_structure(test_dict), cv_structure) # throw and catch `ValueError` for test_dict in list_cv_structs_ValueError: with pytest.raises(ValueError): dummy_cv_structure = cv_structure(test_dict) # throw and catch `TypeError` for test_dict in list_cv_structs_TypeError: with pytest.raises(TypeError): dummy_cv_structure = cv_structure(test_dict) ## test whether data is properly saved by __init__ dummy_cv_structure = cv_structure(dummy_cv_struct_good_01) # test keys assert dummy_cv_struct_good_01.keys() == dummy_cv_structure.keys() # test values assert not any([values not in dummy_cv_structure.values() for values in dummy_cv_struct_good_01.values()]) assert not any([values not in dummy_cv_struct_good_01.values() for values in dummy_cv_structure.values()]) ### ~~~~~~~~~~~~~~~~~~~~~~ TEST FUNCTIONS ~~~~~~~~~~~~~~~~~~~~~~ ## get_attributes_to_check dummy_cv_structure = cv_structure(dummy_cv_struct_good_01) assert dummy_cv_struct_good_01.keys() == dummy_cv_structure.get_attributes_to_check() ## get_cv_names_needed dummy_cv_structure = cv_structure(dummy_cv_struct_good_01) cvs_A = set([values[1] for values in dummy_cv_struct_good_01.values() if isinstance(values[1], str)]) cvs_B = set(dummy_cv_structure.get_cv_names_needed()) assert 0 == len(cvs_A.symmetric_difference(cvs_B)) ## get_cv_check_definition # initialize cf_structure dummy_cv_structure = cv_structure(dummy_cv_struct_good_01) keys = list(dummy_cv_structure) # do non-error tests # test 01, equal output input_good = keys[0] output_good = dummy_cv_struct_good_01[input_good] assert output_good == dummy_cv_structure.get_cv_check_definition(input_good) # test 02, inequal output input_good = keys[0] output_bad = dummy_cv_struct_good_01[keys[1]] assert output_bad != dummy_cv_structure.get_cv_check_definition(input_good) # throw errors # test 03, bad type input_bad = 1 with pytest.raises(TypeError): dummy_cv_structure.get_cv_check_definition(input_bad) # test 04, bad value input_bad = 'bad_attribute_value' with pytest.raises(ValueError): dummy_cv_structure.get_cv_check_definition(input_bad) ## has_children # initialize cf_structure dummy_cv_structure = cv_structure(dummy_cv_struct_good_03) keys = list(dummy_cv_structure) # do non-error tests # test 01, output: True output_true = True input_true = keys[2] assert output_true == dummy_cv_structure.has_children(input_true) # test 02, output: False output_false = False input_false = keys[0] assert output_false == dummy_cv_structure.has_children(input_false) # throw errors # test 03, bad type input_bad = 1 with pytest.raises(TypeError): dummy_cv_structure.has_children(input_bad) # test 04, bad value input_bad = 'bad_attribute_value' with pytest.raises(ValueError): dummy_cv_structure.has_children(input_bad) ## get_children # initialize cf_structure dummy_cv_structure = cv_structure(dummy_cv_struct_good_03) keys = list(dummy_cv_structure) # do non-error tests # test 01, output: some reasonable output input_exist = keys[2] output_exist = dummy_cv_struct_good_03[input_exist][4] assert output_exist == dummy_cv_structure.get_children(input_exist) # test 02, output: not None output_none = None assert output_none is not dummy_cv_structure.get_children(input_exist) # test 03, output: True input_exist = keys[3] output_exist = True assert output_exist == dummy_cv_structure.get_children(input_exist) # test 04, output: None input_notexists = keys[0] output_none = None assert output_none is dummy_cv_structure.get_children(input_notexists) # throw errors # test 05, bad type input_bad = 1 with pytest.raises(TypeError): dummy_cv_structure.get_children(input_bad) # test 06, bad value input_bad = 'bad_attribute_value' with pytest.raises(ValueError): dummy_cv_structure.get_children(input_bad)
def test__cv_tools__validate_argument_attribute(): # see: https://stackoverflow.com/questions/34648337/how-to-test-a-decorator-in-a-python-package/34648674 # input data: # some basic cv_structure dummy_cv_struct = cv_structure(dummy_cv_struct_good_01) # some successful tests # try correct attribute # name of instance of cv_structure: `cv_struct` # => no error @validate_argument_attribute(None) def dummy_fun(cv_struct, attribute): return cv_struct[attribute] assert dummy_cv_struct['attr01'] == dummy_fun(dummy_cv_struct, 'attr01') # try another correct attribute # name of instance of cv_structure: `cv_struct` # => no error @validate_argument_attribute(None) def dummy_fun(cv_struct, attribute): return cv_struct[attribute] assert dummy_cv_struct['attr02'] == dummy_fun(dummy_cv_struct, 'attr02') # try correct attribute # name of instance of cv_structure: `self` # => no error @validate_argument_attribute(None) def dummy_fun(self, attribute): return self[attribute] assert dummy_cv_struct['attr01'] == dummy_fun(dummy_cv_struct, 'attr01') # try correct attribute # name of instance of cv_structure: `self`, mention `self` in decorator # => no error @validate_argument_attribute('self') def dummy_fun(self, attribute): return self[attribute] assert dummy_cv_struct['attr01'] == dummy_fun(dummy_cv_struct, 'attr01') # try correct attribute # name of instance of cv_structure: `abc`; mention `abc` in decorator # => no error @validate_argument_attribute('abc') def dummy_fun(abc, attribute): return abc[attribute] assert dummy_cv_struct['attr01'] == dummy_fun(dummy_cv_struct, 'attr01') # test with errors # try correct attribute # name of instance of cv_structure: `blub` # => RuntimeError @validate_argument_attribute(None) def dummy_fun(blub, attribute): return blub[attribute] with pytest.raises(RuntimeError): dummy_fun(dummy_cv_struct, 'attr01') # try correct attribute # provide instance of `str` as argument `cv_struct` # => RuntimeError @validate_argument_attribute(None) def dummy_fun(cv_struct, attribute): return cv_struct[attribute] with pytest.raises(RuntimeError): dummy_fun('a bad value', 'attr01') # try incorrect attribute # name of instance of cv_structure: `cv_struct` # => ValueError @validate_argument_attribute(None) def dummy_fun(cv_struct, attribute): return cv_struct[attribute] with pytest.raises(ValueError): dummy_fun(dummy_cv_struct, 'attr03') # try wrong type for attribute # name of instance of cv_structure: `cv_struct` # => TypeError @validate_argument_attribute(None) def dummy_fun(cv_struct, attribute): return cv_struct[attribute] with pytest.raises(TypeError): dummy_fun(dummy_cv_struct, 77) # do not have the attribute # name of instance of cv_structure: `cv_struct` # => RuntimeError @validate_argument_attribute(None) def dummy_fun(cv_struct, attr): return cv_struct[attr] with pytest.raises(RuntimeError): dummy_fun(dummy_cv_struct, 'attr01')
'attr02': ['in', 'cv01', None, 'values', False]} # check allowed operations; no error dummy_cv_struct_good_02 = {'attr01': ['in', 'cv01', None, 'keys', False], 'attr02': ['in', 'cv01', None, 'values', False], 'attr03': ['in', 'cv02', None, '', False], 'attr04': ['not in', 'cv01', None, 'keys', False], 'attr05': ['regex', 'cv03', None, '', False], 'attr06': ['isinstance', 'blub', numpy.int32, '', False], 'attr07': ['contains any', 'cv04', None, '', False], 'attr08': ['contains all', 'cv05', None, '', False]} # check sub-cv_structure; no error dummy_cv_struct_good_03 = {'attr01': ['in', 'cv01', None, 'keys', False], 'attr02': ['in', 'cv01', None, 'values', False], 'attr09': ['in', 'cv06', None, 'keys', cv_structure({'attr03': dummy_cv_struct_good_02['attr03']})], 'attr10': ['in', 'cv07', None, 'keys', True], 'attr11': ['in', '', None, '', False], 'attr12': ['in', 'cv99', None, '', False], 'attr13': ['in', '', None, 'keys', False], 'attr14': None} # wrong value; ValueError dummy_cv_struct_bad_01 = {'attr01': ['in', 'cv01', None, 'keys', False], 'attr02': ['BAD VALUE', 'cv01', None, 'values', False]} # wrong type in list in value; TypeError dummy_cv_struct_bad_02 = {'attr01': ['in', 'cv01', None, 'keys', False], 'attr02': [5, 'cv01', None, 'values', False]} # too short list; ValueError dummy_cv_struct_bad_03 = {'attr01': ['in', 'cv01', None, 'keys', False], 'attr02': ['in', 'cv01', None, False]} # too long list; ValueError
def iterate_cv_all(self, results, dataset, cvs, parent_attribute_tree=[], ignore_cvs=[]): """ @param dataset: netCDF4 file, opened """ my_name = sys._getframe().f_code.co_name test_name_base_prefix = 'checking global attribute `' test_name_base_suffix = '` against CV' # The CVs have to be dictionaries. Otherwise, the automatic iteration # of the CVs does not work because one would not know which attribute # to check against each CV. if not isinstance(cvs, dict): raise TypeError(self._cc_spec + '.' + my_name + ': The CV(s) pro' + 'vided via argument `cvs` have to be of type `di' + 'ct`. Other types for CVs are not support by thi' + 's function.') # Generate a cv_struct from the keys of the dictionary autogen_cv_struct = cv_structure({ attr: ['in', attr, None, '', False] for attr in cvs.keys() if attr not in ignore_cvs }) # Iterate generated CV Structure; all `attributes` are in `cvs` # because we generated the cv_structure from the keys of `cvs`. for attribute in autogen_cv_struct.get_attributes_to_check(): test_name_base = (test_name_base_prefix + attribute + test_name_base_suffix) this_attribute_tree = parent_attribute_tree.copy() this_attribute_tree.append(attribute) # print(attribute) # check value of attribute for presence in Dataset if (hasattr(dataset, attribute)): attr_correct = autogen_cv_struct.check_cv(attribute, cvs, getattr( dataset, attribute), guess=True) results.append( Result(BaseCheck.HIGH, attr_correct, test_name_base, [ 'attribute `' + attribute + '` with ' + 'value "' + str(getattr(dataset, attribute)) + '" not present in CV; hierarchy of' + ' CVs checked: ' + ' -> '.join(this_attribute_tree) ])) # check if: # * cvs[attribute] is a dict => we can get the value of key # getattr(dataset, attribute) # * attr_correct is True => then we can extract child CVs if (isinstance(cvs[attribute], dict) and attr_correct): # print(' has children!') # get child CV cvs_child = cvs[attribute][getattr(dataset, attribute)] # If the child cv we got is not a dict, we cannot # proceed and skip checking this child. if not isinstance(cvs_child, dict): continue results = self.iterate_cv_all(results, dataset, cvs_child, this_attribute_tree, ignore_cvs) else: results.append( Result(BaseCheck.HIGH, False, test_name_base, [ 'attribute `' + attribute + '` not ' + 'present in netCDF file; hierarchy of' + ' CVs checked: ' + ' -> '.join(this_attribute_tree) ])) return results