Source code for satpy.tests.test_config

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2019 Satpy developers
#
# This file is part of satpy.
#
# satpy is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# satpy is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# satpy.  If not, see <http://www.gnu.org/licenses/>.
"""Test objects and functions in the satpy.config module."""

import os
import sys
import unittest
from unittest import mock

import pytest


[docs]class TestBuiltinAreas(unittest.TestCase): """Test that the builtin areas are all valid."""
[docs] def test_areas_pyproj(self): """Test all areas have valid projections with pyproj.""" import numpy as np import pyproj import xarray as xr from pyresample import parse_area_file from pyresample.geometry import SwathDefinition from satpy.resample import get_area_file lons = np.array([[0, 0.1, 0.2], [0.05, 0.15, 0.25]]) lats = np.array([[0, 0.1, 0.2], [0.05, 0.15, 0.25]]) lons = xr.DataArray(lons) lats = xr.DataArray(lats) swath_def = SwathDefinition(lons, lats) all_areas = parse_area_file(get_area_file()) for area_obj in all_areas: if hasattr(area_obj, 'freeze'): try: area_obj = area_obj.freeze(lonslats=swath_def) except RuntimeError: # we didn't provide enough info to freeze, hard to guess # in a generic test so just skip this area continue proj_dict = area_obj.proj_dict _ = pyproj.Proj(proj_dict)
[docs] def test_areas_rasterio(self): """Test all areas have valid projections with rasterio.""" try: from rasterio.crs import CRS except ImportError: return unittest.skip("Missing rasterio dependency") if not hasattr(CRS, 'from_dict'): return unittest.skip("RasterIO 1.0+ required") import numpy as np import xarray as xr from pyresample import parse_area_file from pyresample.geometry import SwathDefinition from satpy.resample import get_area_file lons = np.array([[0, 0.1, 0.2], [0.05, 0.15, 0.25]]) lats = np.array([[0, 0.1, 0.2], [0.05, 0.15, 0.25]]) lons = xr.DataArray(lons) lats = xr.DataArray(lats) swath_def = SwathDefinition(lons, lats) all_areas = parse_area_file(get_area_file()) for area_obj in all_areas: if hasattr(area_obj, 'freeze'): try: area_obj = area_obj.freeze(lonslats=swath_def) except RuntimeError: # we didn't provide enough info to freeze, hard to guess # in a generic test so just skip this area continue proj_dict = area_obj.proj_dict if proj_dict.get('proj') in ('ob_tran', 'nsper') and \ 'wktext' not in proj_dict: # FIXME: rasterio doesn't understand ob_tran unless +wktext # See: https://github.com/pyproj4/pyproj/issues/357 # pyproj 2.0+ seems to drop wktext from PROJ dict continue _ = CRS.from_dict(proj_dict)
[docs]class TestPluginsConfigs(unittest.TestCase): """Test that plugins are working."""
[docs] @mock.patch('satpy._config.pkg_resources.iter_entry_points') def test_get_plugin_configs(self, iter_entry_points): """Check that the plugin configs are looked for.""" import pkg_resources ep = pkg_resources.EntryPoint.parse('example_composites = satpy_cpe') ep.dist = pkg_resources.Distribution.from_filename('satpy_cpe-0.0.0-py3.8.egg') ep.dist.module_path = os.path.join(os.path.sep + 'bla', 'bla') iter_entry_points.return_value = [ep] import satpy from satpy._config import get_entry_points_config_dirs # don't let user env vars affect results with satpy.config.set(config_path=[]): dirs = get_entry_points_config_dirs('satpy.composites') self.assertListEqual(dirs, [os.path.join(ep.dist.module_path, 'satpy_cpe', 'etc')])
[docs]class TestConfigObject: """Test basic functionality of the central config object."""
[docs] def test_custom_config_file(self): """Test adding a custom configuration file using SATPY_CONFIG.""" import tempfile from importlib import reload import yaml import satpy my_config_dict = { 'cache_dir': "/path/to/cache", } try: with tempfile.NamedTemporaryFile(mode='w+t', suffix='.yaml', delete=False) as tfile: yaml.dump(my_config_dict, tfile) tfile.close() with mock.patch.dict('os.environ', {'SATPY_CONFIG': tfile.name}): reload(satpy._config) reload(satpy) assert satpy.config.get('cache_dir') == '/path/to/cache' finally: os.remove(tfile.name)
[docs] def test_deprecated_env_vars(self): """Test that deprecated variables are mapped to new config.""" from importlib import reload import satpy old_vars = { 'PPP_CONFIG_DIR': '/my/ppp/config/dir', 'SATPY_ANCPATH': '/my/ancpath', } with mock.patch.dict('os.environ', old_vars): reload(satpy._config) reload(satpy) assert satpy.config.get('data_dir') == '/my/ancpath' assert satpy.config.get('config_path') == ['/my/ppp/config/dir']
[docs] def test_config_path_multiple(self): """Test that multiple config paths are accepted.""" from importlib import reload import satpy exp_paths, env_paths = _os_specific_multipaths() old_vars = { 'SATPY_CONFIG_PATH': env_paths, } with mock.patch.dict('os.environ', old_vars): reload(satpy._config) reload(satpy) assert satpy.config.get('config_path') == exp_paths
[docs] def test_config_path_multiple_load(self): """Test that config paths from subprocesses load properly. Satpy modifies the config path environment variable when it is imported. If Satpy is imported again from a subprocess then it should be able to parse this modified variable. """ from importlib import reload import satpy exp_paths, env_paths = _os_specific_multipaths() old_vars = { 'SATPY_CONFIG_PATH': env_paths, } with mock.patch.dict('os.environ', old_vars): # these reloads will update env variable "SATPY_CONFIG_PATH" reload(satpy._config) reload(satpy) # load the updated env variable and parse it again. reload(satpy._config) reload(satpy) assert satpy.config.get('config_path') == exp_paths
[docs] def test_bad_str_config_path(self): """Test that a str config path isn't allowed.""" from importlib import reload import satpy old_vars = { 'SATPY_CONFIG_PATH': '/my/configs1', } # single path from env var still works with mock.patch.dict('os.environ', old_vars): reload(satpy._config) reload(satpy) assert satpy.config.get('config_path') == ['/my/configs1'] # strings are not allowed, lists are with satpy.config.set(config_path='/single/string/paths/are/bad'): pytest.raises(ValueError, satpy._config.get_config_path_safe)
def _os_specific_multipaths(): exp_paths = ['/my/configs1', '/my/configs2', '/my/configs3'] if sys.platform.startswith("win"): exp_paths = ["C:" + p for p in exp_paths] path_str = os.pathsep.join(exp_paths) return exp_paths, path_str