Exemple #1
0
 def validate_args(cls, project_filename, **kw):
     expected_args = set(['sample_file'])
     for k, v in kw.items():
         expected_args.discard(k)
         if k == 'sample_file':
             if not isinstance(v, str):
                 raise ValidationError(
                     'sample_file should be a path string')
             if not os.path.exists(path_rel_to_file(project_filename, v)):
                 raise ValidationError(f'sample_file doesn\'t exist: {v}')
         else:
             raise ValidationError(f'Unknown argument for sampler: {k}')
     return True
 def validate_args(cls, project_filename, **kw):
     expected_args = set(['n_datapoints'])
     for k, v in kw.items():
         expected_args.discard(k)
         if k == 'n_datapoints':
             if not isinstance(v, int):
                 raise ValidationError(
                     'n_datapoints needs to be an integer')
             if v <= 0:
                 raise ValidationError('n_datapoints need to be >= 1')
         else:
             raise ValidationError(f'Unknown argument for sampler: {k}')
     if len(expected_args) > 0:
         raise ValidationError(
             'The following sampler arguments are required: ' +
             ', '.join(expected_args))
     return True
Exemple #3
0
 def validate_sampler(project_file):
     cfg = get_project_configuration(project_file)
     sampler_name = cfg['sampler']['type']
     try:
         Sampler = BuildStockBatchBase.get_sampler_class(sampler_name)
     except AttributeError:
         raise ValidationError(
             f'Sampler class `{sampler_name}` is not available.')
     args = cfg['sampler']['args']
     return Sampler.validate_args(project_file, **args)
Exemple #4
0
    def validate_xor_nor_schema_keys(project_file):
        cfg = get_project_configuration(project_file)
        major, minor = cfg.get('version', __schema_version__).split('.')
        if int(major) >= 0:
            if int(minor) >= 0:
                # xor
                if ('weather_files_url' in cfg.keys()) is \
                   ('weather_files_path' in cfg.keys()):
                    raise ValidationError(
                        'Both/neither weather_files_url and weather_files_path found in yaml root'
                    )

        return True
Exemple #5
0
 def validate_args(cls, project_filename, **kw):
     expected_args = set(['logic'])
     extra_kw = {}
     for k, v in kw.items():
         expected_args.discard(k)
         if k == 'logic':
             # TODO: do some validation of the logic here.
             pass
         elif k == 'resample':
             pass
         else:
             extra_kw[k] = v
     if len(expected_args) > 0:
         raise ValidationError('The following sampler arguments are required: ' + ', '.join(expected_args))
     cls.SUB_SAMPLER_CLASS.validate_args(project_filename, **extra_kw)
     return True
Exemple #6
0
    def validate_measures_and_arguments(cfg):

        buildstock_dir = cfg["buildstock_directory"]
        measures_dir = os.path.join(buildstock_dir, 'measures')
        type_map = {'Integer': int, 'Boolean': bool, 'String': str, 'Double': float}

        measure_names = {
            'BuildExistingModel': 'baseline',
            'SimulationOutputReport': 'workflow_generator.args.simulation_output',
            'ApplyUpgrade': 'upgrades',
            'TimeseriesCSVExport': 'workflow_generator.args.timeseries_csv_export'
        }

        def cfg_path_exists(cfg_path):
            if cfg_path is None:
                return False
            path_items = cfg_path.split('.')
            a = cfg
            for path_item in path_items:
                try:
                    a = a[path_item]  # noqa F841
                except KeyError:
                    return False
            return True

        def get_cfg_path(cfg_path):
            if cfg_path is None:
                return None
            path_items = cfg_path.split('.')
            a = cfg
            for path_item in path_items:
                try:
                    a = a[path_item]
                except KeyError:
                    return None
            return a

        workflow_args = cfg['workflow_generator'].get('args', {})
        if 'reporting_measures' in workflow_args.keys():
            for reporting_measure in workflow_args['reporting_measures']:
                measure_names[reporting_measure['measure_dir_name']] = 'workflow_generator.args.reporting_measures'

        error_msgs = ''
        warning_msgs = ''
        for measure_name, cfg_key in measure_names.items():
            measure_path = os.path.join(measures_dir, measure_name)

            if cfg_path_exists(cfg_key) or cfg_key == 'workflow_generator.args.residential_simulation_controls':
                # if they exist in the cfg, make sure they exist in the buildstock checkout
                if not os.path.exists(measure_path):
                    error_msgs += f"* {measure_name} does not exist in {buildstock_dir}. \n"

            # check the rest only if that measure exists in cfg
            if not cfg_path_exists(cfg_key):
                continue

            # check argument value types for simulation output report and timeseries csv export measures
            if measure_name in ['SimulationOutputReport', 'TimeseriesCSVExport']:
                root = get_measure_xml(os.path.join(measure_path, 'measure.xml'))
                expected_arguments = {}
                required_args_with_default = {}
                required_args_no_default = {}
                for argument in root.findall('./arguments/argument'):
                    name = argument.find('./name').text
                    expected_arguments[name] = []
                    required = argument.find('./required').text
                    default = argument.find('./default_value')
                    default = default.text if default is not None else None

                    if required == 'true' and not default:
                        required_args_no_default[name] = None
                    elif required == 'true':
                        required_args_with_default[name] = default

                    if argument.find('./type').text == 'Choice':
                        for choice in argument.findall('./choices/choice'):
                            for value in choice.findall('./value'):
                                expected_arguments[name].append(value.text)
                    else:
                        expected_arguments[name] = argument.find('./type').text

                for actual_argument_key in get_cfg_path(measure_names[measure_name]).keys():
                    if actual_argument_key not in expected_arguments.keys():
                        error_msgs += f"* Found unexpected argument key {actual_argument_key} for "\
                                      f"{measure_names[measure_name]} in yaml file. The available keys are: " \
                                      f"{list(expected_arguments.keys())}\n"
                        continue

                    required_args_no_default.pop(actual_argument_key, None)
                    required_args_with_default.pop(actual_argument_key, None)

                    actual_argument_value = get_cfg_path(measure_names[measure_name])[actual_argument_key]
                    expected_argument_type = expected_arguments[actual_argument_key]

                    if type(expected_argument_type) is not list:
                        try:
                            if type(actual_argument_value) is not list:
                                actual_argument_value = [actual_argument_value]

                            for val in actual_argument_value:
                                if not isinstance(val, type_map[expected_argument_type]):
                                    error_msgs += f"* Wrong argument value type for {actual_argument_key} for measure "\
                                                  f"{measure_names[measure_name]} in yaml file. Expected type:" \
                                                  f" {type_map[expected_argument_type]}, got: {val}" \
                                                  f" of type: {type(val)} \n"
                        except KeyError:
                            print(f"Found an unexpected argument value type: {expected_argument_type} for argument "
                                  f" {actual_argument_key} in measure {measure_name}.\n")
                    else:  # Choice
                        if actual_argument_value not in expected_argument_type:
                            error_msgs += f"* Found unexpected argument value {actual_argument_value} for "\
                                          f"{measure_names[measure_name]} in yaml file. Valid values are " \
                                           f"{expected_argument_type}.\n"

                for arg, default in required_args_no_default.items():
                    error_msgs += f"* Required argument {arg} for measure {measure_name} wasn't supplied. " \
                                    f"There is no default for this argument.\n"

                for arg, default in required_args_with_default.items():
                    warning_msgs += f"* Required argument {arg} for measure {measure_name} wasn't supplied. " \
                                    f"Using default value: {default}. \n"

        if warning_msgs:
            logger.warning(warning_msgs)

        if not error_msgs:
            return True
        else:
            logger.error(error_msgs)
            raise ValidationError(error_msgs)