Exemple #1
0
    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
Exemple #7
0
    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