diff --git a/test/mock_results/test_client_url_and_key_environment_variables/request.json b/test/mock_results/test_client_url_and_key_environment_variables/request.json new file mode 100644 index 0000000..67c2f29 --- /dev/null +++ b/test/mock_results/test_client_url_and_key_environment_variables/request.json @@ -0,0 +1 @@ +{"_dataset_name": "reanalysis-era5-single-levels-monthly-means", "variable": "2m_temperature", "area": [89.875, -179.875, -89.875, 179.875], "grid": [0.25, 0.25], "format": "netcdf", "product_type": "monthly_averaged_reanalysis", "time": "00:00", "day": "15", "month": "10", "year": "2015"} \ No newline at end of file diff --git a/test/mock_results/test_client_url_and_key_environment_variables/result b/test/mock_results/test_client_url_and_key_environment_variables/result new file mode 100644 index 0000000..f86f2f4 Binary files /dev/null and b/test/mock_results/test_client_url_and_key_environment_variables/result differ diff --git a/test/mock_results/test_client_url_and_key_parameters/request.json b/test/mock_results/test_client_url_and_key_parameters/request.json new file mode 100644 index 0000000..67c2f29 --- /dev/null +++ b/test/mock_results/test_client_url_and_key_parameters/request.json @@ -0,0 +1 @@ +{"_dataset_name": "reanalysis-era5-single-levels-monthly-means", "variable": "2m_temperature", "area": [89.875, -179.875, -89.875, 179.875], "grid": [0.25, 0.25], "format": "netcdf", "product_type": "monthly_averaged_reanalysis", "time": "00:00", "day": "15", "month": "10", "year": "2015"} \ No newline at end of file diff --git a/test/mock_results/test_client_url_and_key_parameters/result b/test/mock_results/test_client_url_and_key_parameters/result new file mode 100644 index 0000000..f86f2f4 Binary files /dev/null and b/test/mock_results/test_client_url_and_key_parameters/result differ diff --git a/test/mock_results/test_client_url_and_key_rc_file/request.json b/test/mock_results/test_client_url_and_key_rc_file/request.json new file mode 100644 index 0000000..67c2f29 --- /dev/null +++ b/test/mock_results/test_client_url_and_key_rc_file/request.json @@ -0,0 +1 @@ +{"_dataset_name": "reanalysis-era5-single-levels-monthly-means", "variable": "2m_temperature", "area": [89.875, -179.875, -89.875, 179.875], "grid": [0.25, 0.25], "format": "netcdf", "product_type": "monthly_averaged_reanalysis", "time": "00:00", "day": "15", "month": "10", "year": "2015"} \ No newline at end of file diff --git a/test/mock_results/test_client_url_and_key_rc_file/result b/test/mock_results/test_client_url_and_key_rc_file/result new file mode 100644 index 0000000..f86f2f4 Binary files /dev/null and b/test/mock_results/test_client_url_and_key_rc_file/result differ diff --git a/test/mock_results/test_copy_on_open/request.json b/test/mock_results/test_copy_on_open/request.json new file mode 100644 index 0000000..7eaf1a3 --- /dev/null +++ b/test/mock_results/test_copy_on_open/request.json @@ -0,0 +1 @@ +{"_dataset_name": "satellite-soil-moisture", "variable": "volumetric_surface_soil_moisture", "type_of_sensor": "combined_passive_and_active", "time_aggregation": "month_average", "type_of_record": "cdr", "version": "v202012", "format": "tgz", "day": "01", "month": ["01", "02"], "year": "2015"} \ No newline at end of file diff --git a/test/mock_results/test_copy_on_open/result b/test/mock_results/test_copy_on_open/result new file mode 100644 index 0000000..f2f0615 Binary files /dev/null and b/test/mock_results/test_copy_on_open/result differ diff --git a/test/mock_results/test_era5_bounds/result b/test/mock_results/test_era5_bounds/result index 5d02e25..f86f2f4 100644 Binary files a/test/mock_results/test_era5_bounds/result and b/test/mock_results/test_era5_bounds/result differ diff --git a/test/mock_results/test_era5_land_hourly/result b/test/mock_results/test_era5_land_hourly/result index 5ba8b5f..dc62089 100644 Binary files a/test/mock_results/test_era5_land_hourly/result and b/test/mock_results/test_era5_land_hourly/result differ diff --git a/test/mock_results/test_era5_land_monthly/result b/test/mock_results/test_era5_land_monthly/result index 24abda3..f0f7a87 100644 Binary files a/test/mock_results/test_era5_land_monthly/result and b/test/mock_results/test_era5_land_monthly/result differ diff --git a/test/mock_results/test_era5_single_levels_hourly/result b/test/mock_results/test_era5_single_levels_hourly/result index d454941..824ac4e 100644 Binary files a/test/mock_results/test_era5_single_levels_hourly/result and b/test/mock_results/test_era5_single_levels_hourly/result differ diff --git a/test/mock_results/test_normalize_variable_names/result b/test/mock_results/test_normalize_variable_names/result index 969d2b1..f4bb225 100644 Binary files a/test/mock_results/test_normalize_variable_names/result and b/test/mock_results/test_normalize_variable_names/result differ diff --git a/test/mock_results/test_open/result b/test/mock_results/test_open/result index 035253f..f3c5113 100644 Binary files a/test/mock_results/test_open/result and b/test/mock_results/test_open/result differ diff --git a/test/mock_results/test_sea_ice_cryosat-2/request.json b/test/mock_results/test_open_cryosat_2/request.json similarity index 65% rename from test/mock_results/test_sea_ice_cryosat-2/request.json rename to test/mock_results/test_open_cryosat_2/request.json index 6da142a..cbc7fe8 100644 --- a/test/mock_results/test_sea_ice_cryosat-2/request.json +++ b/test/mock_results/test_open_cryosat_2/request.json @@ -1 +1 @@ -{"_dataset_name": "satellite-sea-ice-thickness", "satellite": "cryosat-2", "cdr_type": "cdr", "version": "2_0", "variable": "all", "format": "tgz", "month": ["03", "04"], "year": "2016"} \ No newline at end of file +{"_dataset_name": "satellite-sea-ice-thickness", "satellite": "cryosat_2", "cdr_type": "cdr", "version": "2_0", "variable": "all", "format": "tgz", "month": ["03", "04"], "year": "2016"} \ No newline at end of file diff --git a/test/mock_results/test_sea_ice_cryosat-2/result b/test/mock_results/test_open_cryosat_2/result similarity index 87% rename from test/mock_results/test_sea_ice_cryosat-2/result rename to test/mock_results/test_open_cryosat_2/result index b71abae..295f54b 100644 Binary files a/test/mock_results/test_sea_ice_cryosat-2/result and b/test/mock_results/test_open_cryosat_2/result differ diff --git a/test/mock_results/test_open_data_null_variables_list/request.json b/test/mock_results/test_open_data_null_variables_list/request.json index 70d9e7f..0d5c301 100644 --- a/test/mock_results/test_open_data_null_variables_list/request.json +++ b/test/mock_results/test_open_data_null_variables_list/request.json @@ -1 +1 @@ -{"_dataset_name": "reanalysis-era5-single-levels-monthly-means", "variable": ["100m_u_component_of_wind", "100m_v_component_of_wind", "10m_u_component_of_neutral_wind", "10m_u_component_of_wind", "10m_v_component_of_neutral_wind", "10m_v_component_of_wind", "10m_wind_speed", "2m_dewpoint_temperature", "2m_temperature", "air_density_over_the_oceans", "angle_of_sub_gridscale_orography", "anisotropy_of_sub_gridscale_orography", "benjamin_feir_index", "boundary_layer_dissipation", "boundary_layer_height", "charnock", "clear_sky_direct_solar_radiation_at_surface", "cloud_base_height", "coefficient_of_drag_with_waves", "convective_available_potential_energy", "convective_inhibition", "convective_precipitation", "convective_rain_rate", "convective_snowfall", "convective_snowfall_rate_water_equivalent", "downward_uv_radiation_at_the_surface", "duct_base_height", "eastward_gravity_wave_surface_stress", "eastward_turbulent_surface_stress", "evaporation", "forecast_albedo", "forecast_logarithm_of_surface_roughness_for_heat", "forecast_surface_roughness", "free_convective_velocity_over_the_oceans", "friction_velocity", "gravity_wave_dissipation", "high_cloud_cover", "high_vegetation_cover", "ice_temperature_layer_1", "ice_temperature_layer_2", "ice_temperature_layer_3", "ice_temperature_layer_4", "instantaneous_10m_wind_gust", "instantaneous_eastward_turbulent_surface_stress", "instantaneous_large_scale_surface_precipitation_fraction", "instantaneous_moisture_flux", "instantaneous_northward_turbulent_surface_stress", "instantaneous_surface_sensible_heat_flux", "k_index", "lake_bottom_temperature", "lake_cover", "lake_depth", "lake_ice_depth", "lake_ice_temperature", "lake_mix_layer_depth", "lake_mix_layer_temperature", "lake_shape_factor", "lake_total_layer_temperature", "land_sea_mask", "large_scale_precipitation", "large_scale_precipitation_fraction", "large_scale_rain_rate", "large_scale_snowfall", "large_scale_snowfall_rate_water_equivalent", "leaf_area_index_high_vegetation", "leaf_area_index_low_vegetation", "low_cloud_cover", "low_vegetation_cover", "magnitude_of_turbulent_surface_stress", "maximum_individual_wave_height", "mean_boundary_layer_dissipation", "mean_convective_precipitation_rate", "mean_convective_snowfall_rate", "mean_direction_of_total_swell", "mean_direction_of_wind_waves", "mean_eastward_gravity_wave_surface_stress", "mean_eastward_turbulent_surface_stress", "mean_evaporation_rate", "mean_gravity_wave_dissipation", "mean_large_scale_precipitation_fraction", "mean_large_scale_precipitation_rate", "mean_large_scale_snowfall_rate", "mean_magnitude_of_turbulent_surface_stress", "mean_northward_gravity_wave_surface_stress", "mean_northward_turbulent_surface_stress", "mean_period_of_total_swell", "mean_period_of_wind_waves", "mean_potential_evaporation_rate", "mean_runoff_rate", "mean_sea_level_pressure", "mean_snow_evaporation_rate", "mean_snowfall_rate", "mean_snowmelt_rate", "mean_square_slope_of_waves", "mean_sub_surface_runoff_rate", "mean_surface_direct_short_wave_radiation_flux", "mean_surface_direct_short_wave_radiation_flux_clear_sky", "mean_surface_downward_long_wave_radiation_flux", "mean_surface_downward_long_wave_radiation_flux_clear_sky", "mean_surface_downward_short_wave_radiation_flux", "mean_surface_downward_short_wave_radiation_flux_clear_sky", "mean_surface_downward_uv_radiation_flux", "mean_surface_latent_heat_flux", "mean_surface_net_long_wave_radiation_flux", "mean_surface_net_long_wave_radiation_flux_clear_sky", "mean_surface_net_short_wave_radiation_flux", "mean_surface_net_short_wave_radiation_flux_clear_sky", "mean_surface_runoff_rate", "mean_surface_sensible_heat_flux", "mean_top_downward_short_wave_radiation_flux", "mean_top_net_long_wave_radiation_flux", "mean_top_net_long_wave_radiation_flux_clear_sky", "mean_top_net_short_wave_radiation_flux", "mean_top_net_short_wave_radiation_flux_clear_sky", "mean_total_precipitation_rate", "mean_vertical_gradient_of_refractivity_inside_trapping_layer", "mean_vertically_integrated_moisture_divergence", "mean_wave_direction", "mean_wave_direction_of_first_swell_partition", "mean_wave_direction_of_second_swell_partition", "mean_wave_direction_of_third_swell_partition", "mean_wave_period", "mean_wave_period_based_on_first_moment", "mean_wave_period_based_on_first_moment_for_swell", "mean_wave_period_based_on_first_moment_for_wind_waves", "mean_wave_period_based_on_second_moment_for_swell", "mean_wave_period_based_on_second_moment_for_wind_waves", "mean_wave_period_of_first_swell_partition", "mean_wave_period_of_second_swell_partition", "mean_wave_period_of_third_swell_partition", "mean_zero_crossing_wave_period", "medium_cloud_cover", "minimum_vertical_gradient_of_refractivity_inside_trapping_layer", "model_bathymetry", "near_ir_albedo_for_diffuse_radiation", "near_ir_albedo_for_direct_radiation", "normalized_energy_flux_into_ocean", "normalized_energy_flux_into_waves", "normalized_stress_into_ocean", "northward_gravity_wave_surface_stress", "northward_turbulent_surface_stress", "ocean_surface_stress_equivalent_10m_neutral_wind_direction", "ocean_surface_stress_equivalent_10m_neutral_wind_speed", "orography", "peak_wave_period", "period_corresponding_to_maximum_individual_wave_height", "potential_evaporation", "precipitation_type", "runoff", "sea_ice_cover", "sea_surface_temperature", "significant_height_of_combined_wind_waves_and_swell", "significant_height_of_total_swell", "significant_height_of_wind_waves", "significant_wave_height_of_first_swell_partition", "significant_wave_height_of_second_swell_partition", "significant_wave_height_of_third_swell_partition", "skin_reservoir_content", "skin_temperature", "slope_of_sub_gridscale_orography", "snow_albedo", "snow_density", "snow_depth", "snow_evaporation", "snowfall", "snowmelt", "soil_temperature_level_1", "soil_temperature_level_2", "soil_temperature_level_3", "soil_temperature_level_4", "soil_type", "standard_deviation_of_filtered_subgrid_orography", "standard_deviation_of_orography", "sub_surface_runoff", "surface_latent_heat_flux", "surface_net_solar_radiation", "surface_net_solar_radiation_clear_sky", "surface_net_thermal_radiation", "surface_net_thermal_radiation_clear_sky", "surface_pressure", "surface_runoff", "surface_sensible_heat_flux", "surface_solar_radiation_downward_clear_sky", "surface_solar_radiation_downwards", "surface_thermal_radiation_downward_clear_sky", "surface_thermal_radiation_downwards", "temperature_of_snow_layer", "toa_incident_solar_radiation", "top_net_solar_radiation", "top_net_solar_radiation_clear_sky", "top_net_thermal_radiation", "top_net_thermal_radiation_clear_sky", "total_cloud_cover", "total_column_cloud_ice_water", "total_column_cloud_liquid_water", "total_column_ozone", "total_column_rain_water", "total_column_snow_water", "total_column_supercooled_liquid_water", "total_column_water", "total_column_water_vapour", "total_precipitation", "total_sky_direct_solar_radiation_at_surface", "total_totals_index", "trapping_layer_base_height", "trapping_layer_top_height", "type_of_high_vegetation", "type_of_low_vegetation", "u_component_stokes_drift", "uv_visible_albedo_for_diffuse_radiation", "uv_visible_albedo_for_direct_radiation", "v_component_stokes_drift", "vertical_integral_of_divergence_of_cloud_frozen_water_flux", "vertical_integral_of_divergence_of_cloud_liquid_water_flux", "vertical_integral_of_divergence_of_geopotential_flux", "vertical_integral_of_divergence_of_kinetic_energy_flux", "vertical_integral_of_divergence_of_mass_flux", "vertical_integral_of_divergence_of_moisture_flux", "vertical_integral_of_divergence_of_ozone_flux", "vertical_integral_of_divergence_of_thermal_energy_flux", "vertical_integral_of_divergence_of_total_energy_flux", "vertical_integral_of_eastward_cloud_frozen_water_flux", "vertical_integral_of_eastward_cloud_liquid_water_flux", "vertical_integral_of_eastward_geopotential_flux", "vertical_integral_of_eastward_heat_flux", "vertical_integral_of_eastward_kinetic_energy_flux", "vertical_integral_of_eastward_mass_flux", "vertical_integral_of_eastward_ozone_flux", "vertical_integral_of_eastward_total_energy_flux", "vertical_integral_of_eastward_water_vapour_flux", "vertical_integral_of_energy_conversion", "vertical_integral_of_kinetic_energy", "vertical_integral_of_mass_of_atmosphere", "vertical_integral_of_mass_tendency", "vertical_integral_of_northward_cloud_frozen_water_flux", "vertical_integral_of_northward_cloud_liquid_water_flux", "vertical_integral_of_northward_geopotential_flux", "vertical_integral_of_northward_heat_flux", "vertical_integral_of_northward_kinetic_energy_flux", "vertical_integral_of_northward_mass_flux", "vertical_integral_of_northward_ozone_flux", "vertical_integral_of_northward_total_energy_flux", "vertical_integral_of_northward_water_vapour_flux", "vertical_integral_of_potential_and_internal_energy", "vertical_integral_of_potential_internal_and_latent_energy", "vertical_integral_of_temperature", "vertical_integral_of_thermal_energy", "vertical_integral_of_total_energy", "vertically_integrated_moisture_divergence", "volumetric_soil_water_layer_1", "volumetric_soil_water_layer_2", "volumetric_soil_water_layer_3", "volumetric_soil_water_layer_4", "wave_spectral_directional_width", "wave_spectral_directional_width_for_swell", "wave_spectral_directional_width_for_wind_waves", "wave_spectral_kurtosis", "wave_spectral_peakedness", "wave_spectral_skewness", "zero_degree_level"], "area": [0.875, -0.875, -0.875, 0.875], "grid": [0.25, 0.25], "format": "netcdf", "product_type": "monthly_averaged_reanalysis", "time": "00:00", "day": "15", "month": "10", "year": "2015"} \ No newline at end of file +{"_dataset_name": "reanalysis-era5-single-levels-monthly-means", "variable": ["100m_u_component_of_wind", "100m_v_component_of_wind", "10m_u_component_of_neutral_wind", "10m_u_component_of_wind", "10m_v_component_of_neutral_wind", "10m_v_component_of_wind", "10m_wind_speed", "2m_dewpoint_temperature", "2m_temperature", "air_density_over_the_oceans", "angle_of_sub_gridscale_orography", "anisotropy_of_sub_gridscale_orography", "benjamin_feir_index", "boundary_layer_dissipation", "boundary_layer_height", "charnock", "clear_sky_direct_solar_radiation_at_surface", "cloud_base_height", "coefficient_of_drag_with_waves", "convective_available_potential_energy", "convective_inhibition", "convective_precipitation", "convective_rain_rate", "convective_snowfall", "convective_snowfall_rate_water_equivalent", "downward_uv_radiation_at_the_surface", "duct_base_height", "eastward_gravity_wave_surface_stress", "eastward_turbulent_surface_stress", "evaporation", "forecast_albedo", "forecast_logarithm_of_surface_roughness_for_heat", "forecast_surface_roughness", "free_convective_velocity_over_the_oceans", "friction_velocity", "geopotential", "gravity_wave_dissipation", "high_cloud_cover", "high_vegetation_cover", "ice_temperature_layer_1", "ice_temperature_layer_2", "ice_temperature_layer_3", "ice_temperature_layer_4", "instantaneous_10m_wind_gust", "instantaneous_eastward_turbulent_surface_stress", "instantaneous_large_scale_surface_precipitation_fraction", "instantaneous_moisture_flux", "instantaneous_northward_turbulent_surface_stress", "instantaneous_surface_sensible_heat_flux", "k_index", "lake_bottom_temperature", "lake_cover", "lake_depth", "lake_ice_depth", "lake_ice_temperature", "lake_mix_layer_depth", "lake_mix_layer_temperature", "lake_shape_factor", "lake_total_layer_temperature", "land_sea_mask", "large_scale_precipitation", "large_scale_precipitation_fraction", "large_scale_rain_rate", "large_scale_snowfall", "large_scale_snowfall_rate_water_equivalent", "leaf_area_index_high_vegetation", "leaf_area_index_low_vegetation", "low_cloud_cover", "low_vegetation_cover", "magnitude_of_turbulent_surface_stress", "maximum_individual_wave_height", "mean_boundary_layer_dissipation", "mean_convective_precipitation_rate", "mean_convective_snowfall_rate", "mean_direction_of_total_swell", "mean_direction_of_wind_waves", "mean_eastward_gravity_wave_surface_stress", "mean_eastward_turbulent_surface_stress", "mean_evaporation_rate", "mean_gravity_wave_dissipation", "mean_large_scale_precipitation_fraction", "mean_large_scale_precipitation_rate", "mean_large_scale_snowfall_rate", "mean_magnitude_of_turbulent_surface_stress", "mean_northward_gravity_wave_surface_stress", "mean_northward_turbulent_surface_stress", "mean_period_of_total_swell", "mean_period_of_wind_waves", "mean_potential_evaporation_rate", "mean_runoff_rate", "mean_sea_level_pressure", "mean_snow_evaporation_rate", "mean_snowfall_rate", "mean_snowmelt_rate", "mean_square_slope_of_waves", "mean_sub_surface_runoff_rate", "mean_surface_direct_short_wave_radiation_flux", "mean_surface_direct_short_wave_radiation_flux_clear_sky", "mean_surface_downward_long_wave_radiation_flux", "mean_surface_downward_long_wave_radiation_flux_clear_sky", "mean_surface_downward_short_wave_radiation_flux", "mean_surface_downward_short_wave_radiation_flux_clear_sky", "mean_surface_downward_uv_radiation_flux", "mean_surface_latent_heat_flux", "mean_surface_net_long_wave_radiation_flux", "mean_surface_net_long_wave_radiation_flux_clear_sky", "mean_surface_net_short_wave_radiation_flux", "mean_surface_net_short_wave_radiation_flux_clear_sky", "mean_surface_runoff_rate", "mean_surface_sensible_heat_flux", "mean_top_downward_short_wave_radiation_flux", "mean_top_net_long_wave_radiation_flux", "mean_top_net_long_wave_radiation_flux_clear_sky", "mean_top_net_short_wave_radiation_flux", "mean_top_net_short_wave_radiation_flux_clear_sky", "mean_total_precipitation_rate", "mean_vertical_gradient_of_refractivity_inside_trapping_layer", "mean_vertically_integrated_moisture_divergence", "mean_wave_direction", "mean_wave_direction_of_first_swell_partition", "mean_wave_direction_of_second_swell_partition", "mean_wave_direction_of_third_swell_partition", "mean_wave_period", "mean_wave_period_based_on_first_moment", "mean_wave_period_based_on_first_moment_for_swell", "mean_wave_period_based_on_first_moment_for_wind_waves", "mean_wave_period_based_on_second_moment_for_swell", "mean_wave_period_based_on_second_moment_for_wind_waves", "mean_wave_period_of_first_swell_partition", "mean_wave_period_of_second_swell_partition", "mean_wave_period_of_third_swell_partition", "mean_zero_crossing_wave_period", "medium_cloud_cover", "minimum_vertical_gradient_of_refractivity_inside_trapping_layer", "model_bathymetry", "near_ir_albedo_for_diffuse_radiation", "near_ir_albedo_for_direct_radiation", "normalized_energy_flux_into_ocean", "normalized_energy_flux_into_waves", "normalized_stress_into_ocean", "northward_gravity_wave_surface_stress", "northward_turbulent_surface_stress", "ocean_surface_stress_equivalent_10m_neutral_wind_direction", "ocean_surface_stress_equivalent_10m_neutral_wind_speed", "peak_wave_period", "period_corresponding_to_maximum_individual_wave_height", "potential_evaporation", "precipitation_type", "runoff", "sea_ice_cover", "sea_surface_temperature", "significant_height_of_combined_wind_waves_and_swell", "significant_height_of_total_swell", "significant_height_of_wind_waves", "significant_wave_height_of_first_swell_partition", "significant_wave_height_of_second_swell_partition", "significant_wave_height_of_third_swell_partition", "skin_reservoir_content", "skin_temperature", "slope_of_sub_gridscale_orography", "snow_albedo", "snow_density", "snow_depth", "snow_evaporation", "snowfall", "snowmelt", "soil_temperature_level_1", "soil_temperature_level_2", "soil_temperature_level_3", "soil_temperature_level_4", "soil_type", "standard_deviation_of_filtered_subgrid_orography", "standard_deviation_of_orography", "sub_surface_runoff", "surface_latent_heat_flux", "surface_net_solar_radiation", "surface_net_solar_radiation_clear_sky", "surface_net_thermal_radiation", "surface_net_thermal_radiation_clear_sky", "surface_pressure", "surface_runoff", "surface_sensible_heat_flux", "surface_solar_radiation_downward_clear_sky", "surface_solar_radiation_downwards", "surface_thermal_radiation_downward_clear_sky", "surface_thermal_radiation_downwards", "temperature_of_snow_layer", "toa_incident_solar_radiation", "top_net_solar_radiation", "top_net_solar_radiation_clear_sky", "top_net_thermal_radiation", "top_net_thermal_radiation_clear_sky", "total_cloud_cover", "total_column_cloud_ice_water", "total_column_cloud_liquid_water", "total_column_ozone", "total_column_rain_water", "total_column_snow_water", "total_column_supercooled_liquid_water", "total_column_water", "total_column_water_vapour", "total_precipitation", "total_sky_direct_solar_radiation_at_surface", "total_totals_index", "trapping_layer_base_height", "trapping_layer_top_height", "type_of_high_vegetation", "type_of_low_vegetation", "u_component_stokes_drift", "uv_visible_albedo_for_diffuse_radiation", "uv_visible_albedo_for_direct_radiation", "v_component_stokes_drift", "vertical_integral_of_divergence_of_cloud_frozen_water_flux", "vertical_integral_of_divergence_of_cloud_liquid_water_flux", "vertical_integral_of_divergence_of_geopotential_flux", "vertical_integral_of_divergence_of_kinetic_energy_flux", "vertical_integral_of_divergence_of_mass_flux", "vertical_integral_of_divergence_of_moisture_flux", "vertical_integral_of_divergence_of_ozone_flux", "vertical_integral_of_divergence_of_thermal_energy_flux", "vertical_integral_of_divergence_of_total_energy_flux", "vertical_integral_of_eastward_cloud_frozen_water_flux", "vertical_integral_of_eastward_cloud_liquid_water_flux", "vertical_integral_of_eastward_geopotential_flux", "vertical_integral_of_eastward_heat_flux", "vertical_integral_of_eastward_kinetic_energy_flux", "vertical_integral_of_eastward_mass_flux", "vertical_integral_of_eastward_ozone_flux", "vertical_integral_of_eastward_total_energy_flux", "vertical_integral_of_eastward_water_vapour_flux", "vertical_integral_of_energy_conversion", "vertical_integral_of_kinetic_energy", "vertical_integral_of_mass_of_atmosphere", "vertical_integral_of_mass_tendency", "vertical_integral_of_northward_cloud_frozen_water_flux", "vertical_integral_of_northward_cloud_liquid_water_flux", "vertical_integral_of_northward_geopotential_flux", "vertical_integral_of_northward_heat_flux", "vertical_integral_of_northward_kinetic_energy_flux", "vertical_integral_of_northward_mass_flux", "vertical_integral_of_northward_ozone_flux", "vertical_integral_of_northward_total_energy_flux", "vertical_integral_of_northward_water_vapour_flux", "vertical_integral_of_potential_and_internal_energy", "vertical_integral_of_potential_internal_and_latent_energy", "vertical_integral_of_temperature", "vertical_integral_of_thermal_energy", "vertical_integral_of_total_energy", "vertically_integrated_moisture_divergence", "volumetric_soil_water_layer_1", "volumetric_soil_water_layer_2", "volumetric_soil_water_layer_3", "volumetric_soil_water_layer_4", "wave_spectral_directional_width", "wave_spectral_directional_width_for_swell", "wave_spectral_directional_width_for_wind_waves", "wave_spectral_kurtosis", "wave_spectral_peakedness", "wave_spectral_skewness", "zero_degree_level"], "area": [0.875, -0.875, -0.875, 0.875], "grid": [0.25, 0.25], "format": "netcdf", "product_type": "monthly_averaged_reanalysis", "time": "00:00", "day": "15", "month": "10", "year": "2015"} \ No newline at end of file diff --git a/test/mock_results/test_open_data_null_variables_list/result b/test/mock_results/test_open_data_null_variables_list/result index 25442b1..9aa51d6 100644 Binary files a/test/mock_results/test_open_data_null_variables_list/result and b/test/mock_results/test_open_data_null_variables_list/result differ diff --git a/test/mock_results/test_sea_ice_envisat/request.json b/test/mock_results/test_open_envisat/request.json similarity index 100% rename from test/mock_results/test_sea_ice_envisat/request.json rename to test/mock_results/test_open_envisat/request.json diff --git a/test/mock_results/test_sea_ice_envisat/result b/test/mock_results/test_open_envisat/result similarity index 88% rename from test/mock_results/test_sea_ice_envisat/result rename to test/mock_results/test_open_envisat/result index 69a7685..529cb9a 100644 Binary files a/test/mock_results/test_sea_ice_envisat/result and b/test/mock_results/test_open_envisat/result differ diff --git a/test/mock_results/test_soil_moisture_saturation_10_day/request.json b/test/mock_results/test_soil_moisture_saturation_10_day/request.json index 2cfde43..22f0036 100644 --- a/test/mock_results/test_soil_moisture_saturation_10_day/request.json +++ b/test/mock_results/test_soil_moisture_saturation_10_day/request.json @@ -1 +1 @@ -{"_dataset_name": "satellite-soil-moisture", "variable": "soil_moisture_saturation", "type_of_sensor": "active", "time_aggregation": "10_day_average", "type_of_record": "cdr", "version": "v201912.0.0", "format": "tgz", "day": ["01", "11"], "month": "04", "year": "2015"} \ No newline at end of file +{"_dataset_name": "satellite-soil-moisture", "variable": "surface_soil_moisture", "type_of_sensor": "active", "time_aggregation": "10_day_average", "type_of_record": "cdr", "version": "v202012", "format": "tgz", "day": ["01", "11"], "month": "04", "year": "2015"} \ No newline at end of file diff --git a/test/mock_results/test_soil_moisture_saturation_10_day/result b/test/mock_results/test_soil_moisture_saturation_10_day/result index 11b610c..ea2954e 100644 Binary files a/test/mock_results/test_soil_moisture_saturation_10_day/result and b/test/mock_results/test_soil_moisture_saturation_10_day/result differ diff --git a/test/mock_results/test_soil_moisture_saturation_daily/request.json b/test/mock_results/test_soil_moisture_saturation_daily/request.json index 50d12b5..5e59fc6 100644 --- a/test/mock_results/test_soil_moisture_saturation_daily/request.json +++ b/test/mock_results/test_soil_moisture_saturation_daily/request.json @@ -1 +1 @@ -{"_dataset_name": "satellite-soil-moisture", "variable": "soil_moisture_saturation", "type_of_sensor": "active", "time_aggregation": "day_average", "type_of_record": "cdr", "version": "v201912.0.0", "format": "tgz", "day": ["01", "02", "03", "04"], "month": "03", "year": "2016"} \ No newline at end of file +{"_dataset_name": "satellite-soil-moisture", "variable": "surface_soil_moisture", "type_of_sensor": "active", "time_aggregation": "day_average", "type_of_record": "cdr", "version": "v202012", "format": "tgz", "day": ["01", "02", "03", "04"], "month": "03", "year": "2016"} \ No newline at end of file diff --git a/test/mock_results/test_soil_moisture_saturation_daily/result b/test/mock_results/test_soil_moisture_saturation_daily/result index 9f2a157..a89fec9 100644 Binary files a/test/mock_results/test_soil_moisture_saturation_daily/result and b/test/mock_results/test_soil_moisture_saturation_daily/result differ diff --git a/test/mock_results/test_soil_moisture_volumetric_minimal_params/request.json b/test/mock_results/test_soil_moisture_volumetric_minimal_params/request.json index 177c830..7eaf1a3 100644 --- a/test/mock_results/test_soil_moisture_volumetric_minimal_params/request.json +++ b/test/mock_results/test_soil_moisture_volumetric_minimal_params/request.json @@ -1 +1 @@ -{"_dataset_name": "satellite-soil-moisture", "variable": "volumetric_surface_soil_moisture", "type_of_sensor": "combined_passive_and_active", "time_aggregation": "month_average", "type_of_record": "cdr", "version": "v201912.0.0", "format": "tgz", "day": "01", "month": ["01", "02"], "year": "2015"} \ No newline at end of file +{"_dataset_name": "satellite-soil-moisture", "variable": "volumetric_surface_soil_moisture", "type_of_sensor": "combined_passive_and_active", "time_aggregation": "month_average", "type_of_record": "cdr", "version": "v202012", "format": "tgz", "day": "01", "month": ["01", "02"], "year": "2015"} \ No newline at end of file diff --git a/test/mock_results/test_soil_moisture_volumetric_minimal_params/result b/test/mock_results/test_soil_moisture_volumetric_minimal_params/result index d90ace4..f2f0615 100644 Binary files a/test/mock_results/test_soil_moisture_volumetric_minimal_params/result and b/test/mock_results/test_soil_moisture_volumetric_minimal_params/result differ diff --git a/test/mock_results/test_soil_moisture_volumetric_monthly_2_years/request.json b/test/mock_results/test_soil_moisture_volumetric_monthly_2_years/request.json index 9074dce..a856d4b 100644 --- a/test/mock_results/test_soil_moisture_volumetric_monthly_2_years/request.json +++ b/test/mock_results/test_soil_moisture_volumetric_monthly_2_years/request.json @@ -1 +1 @@ -{"_dataset_name": "satellite-soil-moisture", "variable": "volumetric_surface_soil_moisture", "type_of_sensor": "combined_passive_and_active", "time_aggregation": "month_average", "type_of_record": "cdr", "version": "v201912.0.0", "format": "tgz", "day": "01", "month": ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"], "year": ["2015", "2016"]} \ No newline at end of file +{"_dataset_name": "satellite-soil-moisture", "variable": "volumetric_surface_soil_moisture", "type_of_sensor": "combined_passive_and_active", "time_aggregation": "month_average", "type_of_record": "cdr", "version": "v202012", "format": "tgz", "day": "01", "month": ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"], "year": ["2015", "2016"]} \ No newline at end of file diff --git a/test/mock_results/test_soil_moisture_volumetric_monthly_2_years/result b/test/mock_results/test_soil_moisture_volumetric_monthly_2_years/result index 8a61f50..cbfe476 100644 Binary files a/test/mock_results/test_soil_moisture_volumetric_monthly_2_years/result and b/test/mock_results/test_soil_moisture_volumetric_monthly_2_years/result differ diff --git a/test/mock_results/test_soil_moisture_volumetric_optional_params/request.json b/test/mock_results/test_soil_moisture_volumetric_optional_params/request.json new file mode 100644 index 0000000..7eaf1a3 --- /dev/null +++ b/test/mock_results/test_soil_moisture_volumetric_optional_params/request.json @@ -0,0 +1 @@ +{"_dataset_name": "satellite-soil-moisture", "variable": "volumetric_surface_soil_moisture", "type_of_sensor": "combined_passive_and_active", "time_aggregation": "month_average", "type_of_record": "cdr", "version": "v202012", "format": "tgz", "day": "01", "month": ["01", "02"], "year": "2015"} \ No newline at end of file diff --git a/test/mock_results/test_soil_moisture_volumetric_optional_params/result b/test/mock_results/test_soil_moisture_volumetric_optional_params/result new file mode 100644 index 0000000..f2f0615 Binary files /dev/null and b/test/mock_results/test_soil_moisture_volumetric_optional_params/result differ diff --git a/test/mocks.py b/test/mocks.py index 4b76c0b..ab4e1e5 100644 --- a/test/mocks.py +++ b/test/mocks.py @@ -1,12 +1,49 @@ import json +import pathlib import shutil import os +import inspect +import enum import cdsapi -class CDSClientMock: +class _Behaviour(enum.Enum): + MOCK = enum.auto() + REAL_CLIENT = enum.auto() + SAVE_RESULTS = enum.auto() + +# MOCK uses a mock CDS API client returning pre-generated, saved results +# REAL_CLIENT uses the real CDS client +# SAVE_RESULTS uses the real CDS client and saves results for future mocking +# REAL_CLIENT and SAVE_results require the credentials to be set +_BEHAVIOUR = _Behaviour.MOCK + + +class _SessionMock: + def close(self): + pass + +def _get_url_and_key(url, key): + if url is None: + url = os.environ.get('CDSAPI_URL') + if key is None: + key = os.environ.get('CDSAPI_KEY') + dotrc = os.environ.get('CDSAPI_RC', os.path.expanduser('~/.cdsapirc')) + if url is None or key is None: + if os.path.exists(dotrc): + config = cdsapi.api.read_config(dotrc) + if key is None: + key = config.get('key') + if url is None: + url = config.get('url') + if url is None or key is None: + raise Exception(f'Missing/incomplete configuration file: {dotrc}') + return url, key + + +class CDSClientMock: """A simple mock of the cdsapi.Client class This mock class uses predefined requests from on-disk JSON files. When @@ -26,31 +63,10 @@ class CDSClientMock: """ def __init__(self, url=None, key=None): - class Session: - def close(self): - pass - self.session = Session() - - if url is None: - url = os.environ.get('CDSAPI_URL') - if key is None: - key = os.environ.get('CDSAPI_KEY') - dotrc = os.environ.get('CDSAPI_RC', os.path.expanduser('~/.cdsapirc')) - if url is None or key is None: - if os.path.exists(dotrc): - config = cdsapi.api.read_config(dotrc) - if key is None: - key = config.get('key') - if url is None: - url = config.get('url') - if url is None or key is None: - raise Exception(f'Missing/incomplete configuration file: {dotrc}') - - self.url = url - self.key = key - - resource_path = os.path.join(os.path.dirname(__file__), - 'mock_results') + self.session = _SessionMock() + self.url, self.key = _get_url_and_key(url, key) + + resource_path = os.path.join(os.path.dirname(__file__), 'mock_results') # request_map is a list because dicts can't be hashed in Python, and # it's not worth introducing a dependency on frozendict just for this. self.request_map = [] @@ -58,7 +74,9 @@ def close(self): dir_path = os.path.join(resource_path, d) with open(os.path.join(dir_path, 'request.json'), 'r') as fh: request = json.load(fh) - self.request_map.append((request, os.path.join(dir_path, 'result'))) + self.request_map.append( + (request, os.path.join(dir_path, 'result')) + ) def _get_result(self, request): for canned_request, canned_result in self.request_map: @@ -67,6 +85,52 @@ def _get_result(self, request): raise KeyError('Request not recognized') def retrieve(self, dataset_name, params, file_path): - params_with_name = {**dict(_dataset_name=dataset_name), - **params} + params_with_name = {**dict(_dataset_name=dataset_name), **params} shutil.copy2(self._get_result(params_with_name), file_path) + + +class CDSClientWrapper: + def __init__(self, url=None, key=None): + self.session = _SessionMock() + self.real_client = cdsapi.Client() + self.url, self.key = _get_url_and_key(url, key) + + def retrieve(self, dataset_name, params, file_path): + self.real_client.retrieve(dataset_name, params, file_path) + + +def get_cds_client(dirname=None): + if _BEHAVIOUR is _Behaviour.MOCK: + # Use pre-generated response data for known requests. + return CDSClientMock + + elif _BEHAVIOUR is _Behaviour.REAL_CLIENT: + # Use the real cdsapi client, but wrap it to ignore the passed-in + # credentials (which will probably be dummy values) and fall back + # to environment variables. + return CDSClientWrapper + + elif _BEHAVIOUR is _Behaviour.SAVE_RESULTS: + # Wrap the real client and save the requests and responses + # for future mocking. As above, ignore passed-in credentials. + if dirname is None: + # Default directory name is name of calling function. + dirname = inspect.currentframe().f_back.f_code.co_name + resource_path = os.path.join(os.path.dirname(__file__), 'mock_results') + path = os.path.join(resource_path, dirname) + + class ResultSavingClientWrapper(CDSClientWrapper): + def retrieve(self, dataset_name, params, file_path): + params_with_name = { + **dict(_dataset_name=dataset_name), + **params, + } + pathlib.Path(path).mkdir(parents=True, exist_ok=True) + with open(os.path.join(path, 'request.json'), 'w') as fh: + json.dump(params_with_name, fh) + self.real_client.retrieve(dataset_name, params, file_path) + shutil.copy2(file_path, os.path.join(path, 'result')) + + return ResultSavingClientWrapper + else: + raise Exception(f'Unknown behaviour {_BEHAVIOUR}') diff --git a/test/test_era5.py b/test/test_era5.py index a9c27ce..e8fdf68 100644 --- a/test/test_era5.py +++ b/test/test_era5.py @@ -31,7 +31,7 @@ import xcube import xcube.core -from test.mocks import CDSClientMock +from test.mocks import get_cds_client from xcube.core.store import DATASET_TYPE from xcube.core.store import VariableDescriptor from xcube_cds.store import CDSDataOpener @@ -44,7 +44,7 @@ class CDSEra5Test(unittest.TestCase): def test_open(self): - opener = CDSDataOpener(client_class=CDSClientMock, + opener = CDSDataOpener(client_class=get_cds_client(), endpoint_url=_CDS_API_URL, cds_api_key=_CDS_API_KEY) dataset = opener.open_data( @@ -62,7 +62,7 @@ def test_open(self): self.assertEqual(10, len(dataset.variables['time'])) def test_normalize_variable_names(self): - store = CDSDataStore(client_class=CDSClientMock, normalize_names=True, + store = CDSDataStore(client_class=get_cds_client(), normalize_names=True, endpoint_url=_CDS_API_URL, cds_api_key=_CDS_API_KEY) dataset = store.open_data( @@ -90,7 +90,7 @@ def test_request_parameter_out_of_range(self): ) def test_era5_land_monthly(self): - store = CDSDataStore(client_class=CDSClientMock, + store = CDSDataStore(client_class=get_cds_client(), endpoint_url=_CDS_API_URL, cds_api_key=_CDS_API_KEY) dataset = store.open_data( @@ -106,7 +106,7 @@ def test_era5_land_monthly(self): self.assertTrue('u10' in dataset.variables) def test_era5_single_levels_hourly(self): - store = CDSDataStore(client_class=CDSClientMock, + store = CDSDataStore(client_class=get_cds_client(), endpoint_url=_CDS_API_URL, cds_api_key=_CDS_API_KEY) dataset = store.open_data( @@ -123,7 +123,7 @@ def test_era5_single_levels_hourly(self): self.assertEqual(48, len(dataset.variables['time'])) def test_era5_land_hourly(self): - store = CDSDataStore(client_class=CDSClientMock, + store = CDSDataStore(client_class=get_cds_client(), endpoint_url=_CDS_API_URL, cds_api_key=_CDS_API_KEY) dataset = store.open_data( @@ -139,7 +139,7 @@ def test_era5_land_hourly(self): self.assertEqual(48, len(dataset.variables['time'])) def test_era5_bounds(self): - opener = CDSDataOpener(client_class=CDSClientMock, + opener = CDSDataOpener(client_class=get_cds_client(), endpoint_url=_CDS_API_URL, cds_api_key=_CDS_API_KEY) dataset = opener.open_data( @@ -176,7 +176,7 @@ def test_era5_open_data_empty_variables_list(self): self.assertEqual(361, len(dataset.variables['lon'])) def test_open_data_null_variables_list(self): - store = CDSDataStore(client_class=CDSClientMock, + store = CDSDataStore(client_class=get_cds_client(), endpoint_url=_CDS_API_URL, cds_api_key=_CDS_API_KEY) data_id = 'reanalysis-era5-single-levels-monthly-means:' \ diff --git a/test/test_sea_ice_thickness.py b/test/test_sea_ice_thickness.py index a1c0271..3a618aa 100644 --- a/test/test_sea_ice_thickness.py +++ b/test/test_sea_ice_thickness.py @@ -29,7 +29,7 @@ from typing import Optional import unittest -from test.mocks import CDSClientMock +from test.mocks import get_cds_client from xcube_cds.store import CDSDataStore from xcube_cds.datasets.satellite_sea_ice_thickness import SeaIceThicknessHandler @@ -174,7 +174,7 @@ class CdsSeaIceThicknessStoreTest(unittest.TestCase): def setUp(self) -> None: self.store = CDSDataStore( - client_class=CDSClientMock, + client_class=get_cds_client(dirname=self._testMethodName), endpoint_url=_CDS_API_URL, cds_api_key=_CDS_API_KEY ) diff --git a/test/test_soil_moisture.py b/test/test_soil_moisture.py index 5f4fe4c..aa31ca0 100644 --- a/test/test_soil_moisture.py +++ b/test/test_soil_moisture.py @@ -29,7 +29,7 @@ import tempfile import unittest -from test.mocks import CDSClientMock +from test.mocks import get_cds_client from xcube_cds.store import CDSDataStore _CDS_API_URL = 'dummy' @@ -40,7 +40,7 @@ class CDSSoilMoistureTest(unittest.TestCase): def test_soil_moisture_volumetric_minimal_params(self): store = CDSDataStore( - client_class=CDSClientMock, + client_class=get_cds_client(), endpoint_url=_CDS_API_URL, cds_api_key=_CDS_API_KEY ) @@ -61,7 +61,7 @@ def test_soil_moisture_volumetric_minimal_params(self): def test_soil_moisture_volumetric_monthly_2_years(self): store = CDSDataStore( - client_class=CDSClientMock, + client_class=get_cds_client(), endpoint_url=_CDS_API_URL, cds_api_key=_CDS_API_KEY ) @@ -83,7 +83,7 @@ def test_soil_moisture_volumetric_monthly_2_years(self): def test_soil_moisture_saturation_daily(self): store = CDSDataStore( - client_class=CDSClientMock, + client_class=get_cds_client(), endpoint_url=_CDS_API_URL, cds_api_key=_CDS_API_KEY ) @@ -97,7 +97,7 @@ def test_soil_moisture_saturation_daily(self): self.assertEqual(4, len(dataset.variables['time'])) self.assertEqual('19910805T000000Z', dataset.attrs['time_coverage_start']) - self.assertEqual('20191231T235959Z', + self.assertEqual('20201231T235959Z', dataset.attrs['time_coverage_end']) description = store.describe_data(data_id) self.assertCountEqual(description.data_vars.keys(), @@ -105,7 +105,7 @@ def test_soil_moisture_saturation_daily(self): def test_soil_moisture_saturation_10_day(self): store = CDSDataStore( - client_class=CDSClientMock, + client_class=get_cds_client(), endpoint_url=_CDS_API_URL, cds_api_key=_CDS_API_KEY ) @@ -127,7 +127,7 @@ def test_soil_moisture_saturation_10_day(self): def test_soil_moisture_volumetric_optional_params(self): store = CDSDataStore( - client_class=CDSClientMock, + client_class=get_cds_client(), endpoint_url=_CDS_API_URL, cds_api_key=_CDS_API_KEY ) @@ -161,7 +161,7 @@ def test_soil_moisture_empty_variables_list(self): self.assertEqual(1441, len(dataset.variables['lon'])) def test_copy_on_open(self): - store = CDSDataStore(client_class=CDSClientMock, + store = CDSDataStore(client_class=get_cds_client(), endpoint_url=_CDS_API_URL, cds_api_key=_CDS_API_KEY) data_id = 'satellite-soil-moisture:volumetric:monthly' @@ -182,7 +182,7 @@ def test_copy_on_open(self): self.assertTrue(os.path.isdir(zarr_path)) def test_soil_moisture_get_open_params_schema(self): - store = CDSDataStore(client_class=CDSClientMock, + store = CDSDataStore(client_class=get_cds_client(), endpoint_url=_CDS_API_URL, cds_api_key=_CDS_API_KEY) data_id = 'satellite-soil-moisture:volumetric:monthly' diff --git a/test/test_store.py b/test/test_store.py index c62be86..cde96df 100644 --- a/test/test_store.py +++ b/test/test_store.py @@ -38,7 +38,7 @@ of the subdirectory is arbitrary, but it is useful to give it the same name as the unit test method. 4. Remove the _save_request_to and _save_file_to arguments from the open_data - call, and add a 'client_class=CDSClientMock' argument to the CDSDataOpener + call, and add a 'client_class=get_cds_client()' argument to the CDSDataOpener constructor. """ @@ -51,7 +51,7 @@ import xcube import xcube.core -from test.mocks import CDSClientMock +from test.mocks import get_cds_client, CDSClientMock from xcube.core.store import DATASET_TYPE from xcube.core.store import DataDescriptor from xcube_cds.constants import CDS_DATA_OPENER_ID @@ -226,7 +226,7 @@ def test_get_store_open_params_schema_without_data_id(self): ) def test_get_data_ids(self): - store = CDSDataStore(client_class=CDSClientMock, + store = CDSDataStore(client_class=get_cds_client(), endpoint_url=_CDS_API_URL, cds_api_key=_CDS_API_KEY) with self.assertRaises(ValueError): @@ -287,6 +287,9 @@ def test_client_url_and_key_parameters(self): 'wrong URL 2', 'wrong key 2') endpoint_url = 'https://example.com/' cds_api_key = 'xyzzy' + + # We always use a mock here regardless of the behaviour setting, + # since the real client would complain about the invalid parameters. opener = CDSDataOpener(client_class=CDSClientMock, endpoint_url=endpoint_url, cds_api_key=cds_api_key) @@ -314,7 +317,13 @@ def test_client_url_and_key_environment_variables(self): cds_api_key = 'xyzzy' self._set_up_api_configuration('wrong URL 1', 'wrong key 1', endpoint_url, cds_api_key) - client = self._get_client() + + # We always use a mock here regardless of the behaviour setting, + # since the real client would complain about the invalid parameters. + client = self._get_client( + name='test_client_url_and_key_environment_variables', + client_class=CDSClientMock + ) self.assertEqual(endpoint_url, client.url) self.assertEqual(cds_api_key, client.key) @@ -328,6 +337,9 @@ def test_client_url_and_key_rc_file(self): endpoint_url = 'https://example.com/' cds_api_key = 'xyzzy' self._set_up_api_configuration(endpoint_url, cds_api_key) + + # We always use a mock here regardless of the behaviour setting, + # since the real client would complain about the invalid parameters. opener = CDSDataOpener(client_class=CDSClientMock) opener.open_data( 'reanalysis-era5-single-levels-monthly-means:' @@ -354,13 +366,20 @@ def test_new_datastore_with_credential_parameters(self): self.assertEqual(cds_api_key, store.cds_api_key) @staticmethod - def _get_client(**opener_args): + def _get_client(opener_args=None, name=None, client_class=None): """Return the client instantiated to open a dataset Open a dataset and return the client that was instantiated to execute the CDS API query. """ - opener = CDSDataOpener(client_class=CDSClientMock, **opener_args) + + if opener_args is None: + opener_args = {} + if client_class is None: + client_class = get_cds_client(name) + opener = CDSDataOpener( + client_class=client_class, + **opener_args) opener.open_data( 'reanalysis-era5-single-levels-monthly-means:' 'monthly_averaged_reanalysis', diff --git a/xcube_cds/datasets/reanalysis-era5-single-levels-monthly-means.json b/xcube_cds/datasets/reanalysis-era5-single-levels-monthly-means.json index e29ba5b..df80361 100644 --- a/xcube_cds/datasets/reanalysis-era5-single-levels-monthly-means.json +++ b/xcube_cds/datasets/reanalysis-era5-single-levels-monthly-means.json @@ -243,6 +243,12 @@ "m s**-1", "Friction velocity" ], + [ + "geopotential", + "z", + "m**2 s**-2", + "Geopotential" + ], [ "gravity_wave_dissipation", "gwd", @@ -891,12 +897,6 @@ "m s**-1", "10 metre wind speed" ], - [ - "orography", - "z", - "m**2 s**-2", - "Geopotential" - ], [ "peak_wave_period", "pp1d", diff --git a/xcube_cds/datasets/reanalysis-era5-single-levels.json b/xcube_cds/datasets/reanalysis-era5-single-levels.json index 626ef3d..b25ddea 100644 --- a/xcube_cds/datasets/reanalysis-era5-single-levels.json +++ b/xcube_cds/datasets/reanalysis-era5-single-levels.json @@ -261,6 +261,12 @@ "m s**-1", "Friction velocity" ], + [ + "geopotential", + "z", + "m**2 s**-2", + "Geopotential" + ], [ "gravity_wave_dissipation", "gwd", @@ -921,12 +927,6 @@ "m s**-1", "10 metre wind speed" ], - [ - "orography", - "z", - "m**2 s**-2", - "Geopotential" - ], [ "peak_wave_period", "pp1d", diff --git a/xcube_cds/datasets/satellite_sea_ice_thickness.py b/xcube_cds/datasets/satellite_sea_ice_thickness.py index 6385d6a..88b8ff4 100644 --- a/xcube_cds/datasets/satellite_sea_ice_thickness.py +++ b/xcube_cds/datasets/satellite_sea_ice_thickness.py @@ -137,8 +137,13 @@ def transform_params(self, opener_params: Dict, data_id: str) -> \ variable_properties.cdr_types[0] ) + satellites = { + 'cryosat-2': 'cryosat_2', + 'envisat': 'envisat' + } + cds_params = dict( - satellite=mission, + satellite=satellites[mission], cdr_type=cdr_type, version=version, variable='all', diff --git a/xcube_cds/datasets/satellite_soil_moisture.py b/xcube_cds/datasets/satellite_soil_moisture.py index d55c0a7..d4cbdc7 100644 --- a/xcube_cds/datasets/satellite_soil_moisture.py +++ b/xcube_cds/datasets/satellite_soil_moisture.py @@ -64,7 +64,7 @@ class SoilMoistureHandler(CDSDatasetHandler): # Map second component of data ID to variable and sensor type information _var_map = { 'saturation': - VariableProperties(['soil_moisture_saturation'], ['active']), + VariableProperties(['surface_soil_moisture'], ['active']), 'volumetric': VariableProperties( ['volumetric_surface_soil_moisture'], @@ -202,19 +202,13 @@ def get_open_data_params_schema(self, data_id: str) -> JsonObjectSchema: 'checked.'), default='cdr'), version=JsonStringSchema( - enum=['v201706.0.0', 'v201812.0.0', 'v201812.0.1', - 'v201912.0.0'], + enum=['v201706', 'v201812', 'v201912', 'v202012'], title='Data version', description=( - 'Format: vMajor.Minor.Run, e.g. "v201706.0.0". The Major ' - 'number usually represents the year (YYYY) and month (MM) ' - 'of date. The initial value for Minor is zero, and will ' - 'increment when updating the file. If there is a need – ' - 'e.g. because of technical issues – to replace a file ' - 'which has already been made public, the Run number of ' - 'the replacement file shifts to the next increment. The ' - 'initial Run number is zero.'), - default='v201912.0.0') + 'Product version, in the format vYYYYMM, where YYYY' + 'represents a year number and MM a two-digit month number' + '(with leading zero if required).'), + default='v202012') ) if len(variable_properties.sensor_types) > 1: