def test_dependencies_sink_input_can_only_be_driven_once( self, get_sos_model, get_sector_model, energy_supply_sector_model, sample_scenarios): """Expect error when sink input is driven by multiple sources """ get_sos_model['model_dependencies'] = [ { "source": "energy_demand", "source_output": "output_a", "sink": "energy_supply", "sink_input": "input_a" }, { "source": "energy_demand", "source_output": "output_b", "sink": "energy_supply", "sink_input": "input_a" } ] get_sector_model['outputs'] = [ { "name": "output_a", "dims": [ "dim_a" ], "dtype": "dtype_a", "unit": "unit_a" }, { "name": "output_b", "dims": [ "dim_a" ], "dtype": "dtype_a", "unit": "unit_a" } ] energy_supply_sector_model['inputs'] = [ { "name": "input_a", "dims": [ "dim_a" ], "dtype": "dtype_a", "unit": "unit_a" } ] try: validate_sos_model_config( get_sos_model, [get_sector_model, energy_supply_sector_model], sample_scenarios) except SmifDataError as ex: assert len(ex.args[0]) == 2 assert ex.args[0][0].component == 'model_dependencies' assert 'Sink input `input_a` is driven by multiple sources' in ex.args[0][0].error assert ex.args[0][1].component == 'model_dependencies' assert 'Sink input `input_a` is driven by multiple sources' in ex.args[0][0].error
def test_dependencies_source_output_or_sink_input_not_exist( self, get_sos_model, get_sector_model, energy_supply_sector_model, sample_scenarios): """Expect error when source output or sink input do not exist """ get_sos_model['model_dependencies'] = [ { "source": "energy_demand", "source_output": "output_a", "sink": "energy_supply", "sink_input": "input_a" } ] get_sector_model['outputs'] = [] energy_supply_sector_model['inputs'] = [ { "name": "input_a", "dims": [ "dim_a" ], "dtype": "dtype_a", "unit": "unit_a" } ] try: validate_sos_model_config( get_sos_model, [get_sector_model, energy_supply_sector_model], sample_scenarios) assert False except SmifDataError as ex: assert ex.args[0] assert ex.args[0][0].component == 'model_dependencies' assert 'Source output `output_a` does not exist' in ex.args[0][0].error get_sector_model['outputs'] = [ { "name": "output_a", "dims": [ "dim_a" ], "dtype": "dtype_a", "unit": "unit_a" } ] energy_supply_sector_model['inputs'] = [] try: validate_sos_model_config( get_sos_model, [get_sector_model, energy_supply_sector_model], sample_scenarios) assert False except SmifDataError as ex: assert ex.args[0] assert ex.args[0][0].component == 'model_dependencies' assert 'Sink input `input_a` does not exist' in ex.args[0][0].error
def test_correct(self, get_sos_model, get_sector_model, energy_supply_sector_model, sample_scenarios): """Expect no error on the default configuration """ validate_sos_model_config( get_sos_model, [get_sector_model, energy_supply_sector_model], sample_scenarios)
def test_invalid_timesteps_file(get_sos_model_config): """Expect an error if timesteps is not a path to a file """ data = get_sos_model_config data['timesteps'] = 3 validate_sos_model_config(data) ex = VALIDATION_ERRORS.pop() msg = "Expected 'timesteps' in main config to specify a timesteps file, instead got 3" assert msg in str(ex)
def test_interval_sets_missing(self, get_sos_model_config): """Expect an error if no time interval sets are specified """ data = get_sos_model_config del data['interval_sets'] validate_sos_model_config(data) ex = VALIDATION_ERRORS.pop() msg = "No 'interval_sets' specified in main config file." assert msg == str(ex)
def test_missing_timestep(self, get_sos_model_config): """Expect an error if missing timesteps """ data = get_sos_model_config del data['timesteps'] validate_sos_model_config(data) ex = VALIDATION_ERRORS.pop() msg = "No 'timesteps' file specified in main config" assert msg in str(ex)
def test_used_planning_needs_files(get_sos_model_config): """Expect an error if a planning mode is to be used, but has no files """ data = get_sos_model_config del data["planning"]["pre_specified"]["files"] validate_sos_model_config(data) ex = VALIDATION_ERRORS.pop() msg = "No 'files' provided for the 'pre_specified' planning type in main config" assert msg in str(ex)
def test_missing_planning(get_sos_model_config): """Expect an error if missing planning """ data = get_sos_model_config del data['planning'] validate_sos_model_config(data) ex = VALIDATION_ERRORS.pop() msg = "No 'planning' mode specified in main config" assert msg in str(ex)
def test_sector_model_type(get_sos_model_config): """Expect an error if sector_model config is not a dict """ data = get_sos_model_config data['sector_models'] = [None] validate_sos_model_config(data) ex = VALIDATION_ERRORS.pop() msg = "Expected a sector model config block" assert msg in str(ex)
def test_sector_models_empty_list(get_sos_model_config): """Expect an error if sector_models is an empty list """ data = get_sos_model_config data['sector_models'] = [] validate_sos_model_config(data) ex = VALIDATION_ERRORS.pop() msg = "No 'sector_models' specified in main config" assert msg in str(ex)
def test_missing_sector_models(get_sos_model_config): """Expect an error if missing sector_models """ data = get_sos_model_config del data['sector_models'] validate_sos_model_config(data) ex = VALIDATION_ERRORS.pop() msg = "No 'sector_models' specified in main config" assert msg in str(ex)
def test_modelrun_config_invalid(): """Expect an error if not a dict """ invalid_possibilities = [0, [], "just a string", 3.1415] for invalid_data in invalid_possibilities: validate_sos_model_config(invalid_data) ex = VALIDATION_ERRORS.pop() msg = "Main config file should contain setup data" assert msg in str(ex)
def test_sector_models_not_list(get_sos_model_config): """Expect an error if sector_models is not a list """ data = get_sos_model_config data['sector_models'] = 42 validate_sos_model_config(data) ex = VALIDATION_ERRORS.pop() msg = "Expected 'sector_models' in main config to specify a list of sector " + \ "models to run, instead got 42." assert msg in str(ex)
def test_scenario_data_missing(self, get_sos_model_config): """Expect an error if no scenario data is specified, but referenced in input file """ data = get_sos_model_config del data['scenario_data'] validate_sos_model_config(data) ex = VALIDATION_ERRORS.pop() msg = "No 'scenario_data' specified in main config file." assert msg == str(ex)
def test_sector_model_missing_reference(self, get_sos_model, sample_scenarios): """Expect error when references sector model configuration does not exist """ try: validate_sos_model_config( get_sos_model, [], sample_scenarios) assert False except SmifDataError as ex: assert ex.args[0] assert ex.args[0][0].component == 'sector_models' assert 'valid sector_model configuration' in ex.args[0][0].error
def test_sector_models_none_configured(self, get_sos_model, get_sector_model, energy_supply_sector_model, sample_scenarios): """Expect exception when no sector_models are configured """ try: get_sos_model['sector_models'] = [] validate_sos_model_config( get_sos_model, [get_sector_model, energy_supply_sector_model], sample_scenarios) assert False except SmifDataError as ex: assert ex.args[0] assert ex.args[0][0].component == 'sector_models' assert 'one sector model must be selected' in ex.args[0][0].error
def test_dependencies_source_or_sink_not_enabled(self, get_sos_model, get_sector_model, energy_supply_sector_model, sample_scenarios): """Expect error when source or sink is not enabled in the sector_model configuration """ get_sos_model['model_dependencies'] = [ { "source": "energy_demand", "source_output": "output_a", "sink": "energy_supply", "sink_input": "input_a" } ] get_sos_model['sector_models'] = [ 'energy_supply' ] get_sector_model['outputs'] = [ { "name": "output_a", "dims": [ "dim_a" ], "dtype": "dtype_a", "unit": "unit_a" } ] energy_supply_sector_model['inputs'] = [ { "name": "input_a", "dims": [ "dim_a" ], "dtype": "dtype_a", "unit": "unit_a" } ] try: validate_sos_model_config( get_sos_model, [get_sector_model, energy_supply_sector_model], sample_scenarios) assert False except SmifDataError as ex: assert ex.args[0] assert ex.args[0][2].component == 'model_dependencies' assert '`energy_demand` is not enabled' in ex.args[0][2].error
def test_dependencies_circular(self, get_sos_model, get_sector_model, energy_supply_sector_model, sample_scenarios): """Expect error when circular dependency is in configuration """ get_sos_model['sector_models'] = [ 'energy_demand' ] get_sos_model['model_dependencies'] = [ { "source": "energy_demand", "source_output": "output_a", "sink": "energy_demand", "sink_input": "input_a" } ] get_sector_model['inputs'] = [ { "name": "input_a", "dims": [ "dim_a" ], "dtype": "dtype_a", "unit": "unit_a" } ] get_sector_model['outputs'] = [ { "name": "output_a", "dims": [ "dim_a" ], "dtype": "dtype_a", "unit": "unit_a" } ] try: validate_sos_model_config( get_sos_model, [get_sector_model, energy_supply_sector_model], sample_scenarios) assert False except SmifDataError as ex: assert ex.args[0] assert ex.args[0][0].component == 'model_dependencies' assert 'Circular dependencies' in ex.args[0][0].error
def test_scenario_missing_reference(self, get_sos_model, get_sector_model, energy_supply_sector_model, sample_scenarios): """Expect error when references scenario configuration does not exist """ try: get_sos_model['scenarios'] = ['scenario_a'] sample_scenarios = [] validate_sos_model_config( get_sos_model, [get_sector_model, energy_supply_sector_model], sample_scenarios) assert False except SmifDataError as ex: assert ex.args[0] assert ex.args[0][0].component == 'scenarios' assert 'valid scenario configuration' in ex.args[0][0].error
def test_dependencies_with_no_dims_spec( self, get_sos_model, get_sector_model, energy_supply_sector_model, sample_scenarios): """Expect error when sink input is driven by multiple sources """ get_sos_model['model_dependencies'] = [ { "source": "energy_demand", "source_output": "output_a", "sink": "energy_supply", "sink_input": "input_a" } ] get_sector_model['outputs'] = [ { "name": "output_a", "dims": [ "dim_a" ], "dtype": "dtype_a", "unit": "unit_a" } ] energy_supply_sector_model['inputs'] = [ { "name": "input_a", "dtype": "dtype_a", "unit": "unit_a" } ] try: validate_sos_model_config( get_sos_model, [get_sector_model, energy_supply_sector_model], sample_scenarios) except SmifDataError as ex: assert len(ex.args[0]) == 1 assert ex.args[0][0].component == 'model_dependencies' assert 'Source `output_a` has different dimensions than sink `input_a`' \ in ex.args[0][0].error
def test_description_too_long(self, get_sos_model, get_sector_model, energy_supply_sector_model, sample_scenarios): """Expect exception when description is too long """ get_sos_model['description'] = 255 * 'a' validate_sos_model_config( get_sos_model, [get_sector_model, energy_supply_sector_model], sample_scenarios) try: get_sos_model['description'] = 256 * 'a' validate_sos_model_config( get_sos_model, [get_sector_model, energy_supply_sector_model], sample_scenarios) except SmifDataError as ex: assert ex.args[0] assert ex.args[0][0].component == 'description' assert 'characters' in ex.args[0][0].error
def test_modelrun_config_validate(self, get_sos_model_config): """Expect no errors from a complete, valid config """ validate_sos_model_config(get_sos_model_config)
def test_dependencies_has_matching_specs(self, get_sos_model, get_sector_model, energy_supply_sector_model, sample_scenarios): """Expect error when source output or sink input have different specs """ get_sos_model['model_dependencies'] = [ { "source": "energy_demand", "source_output": "output_a", "sink": "energy_supply", "sink_input": "input_a" } ] get_sector_model['outputs'] = [ { "name": "output_a", "dims": [ "dim_a" ], "dtype": "dtype_a", "unit": "unit_a" } ] energy_supply_sector_model['inputs'] = [ { "name": "input_a", "dims": [ "dim_b" ], "dtype": "dtype_a", "unit": "unit_a" } ] try: validate_sos_model_config( get_sos_model, [get_sector_model, energy_supply_sector_model], sample_scenarios) assert False except SmifDataError as ex: assert ex.args[0] assert ex.args[0][0].component == 'model_dependencies' msg = '`output_a` has different dimensions than sink `input_a`' assert msg in ex.args[0][0].error get_sector_model['outputs'] = [ { "name": "output_a", "dims": [ "dim_a" ], "dtype": "dtype_a", "unit": "unit_a" } ] energy_supply_sector_model['inputs'] = [ { "name": "input_a", "dims": [ "dim_a" ], "dtype": "dtype_b", "unit": "unit_a" } ] try: validate_sos_model_config( get_sos_model, [get_sector_model, energy_supply_sector_model], sample_scenarios) assert False except SmifDataError as ex: assert ex.args[0] assert ex.args[0][0].component == 'model_dependencies' msg = '`output_a` has a different dtype than sink `input_a`' assert msg in ex.args[0][0].error