|
20 | 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
21 | 21 | # SOFTWARE. |
22 | 22 |
|
23 | | -from xcube.core.store import new_data_store |
24 | | -from xcube.util.jsonschema import JsonObjectSchema,JsonNumberSchema |
| 23 | +import unittest |
| 24 | +from unittest.mock import MagicMock |
| 25 | + |
25 | 26 | import xarray as xr |
26 | | -from unittest.mock import patch |
| 27 | +from xcube.core.store import DataStoreError |
27 | 28 |
|
28 | 29 | from xcube_multistore.accessors.cds import CdsAccessor |
29 | | -from ..sample_data import get_sample_data_3d |
30 | 30 |
|
31 | | -import unittest |
| 31 | +from ..sample_data import get_sample_data_3d |
32 | 32 |
|
33 | 33 |
|
34 | 34 | class CdsAccessorTest(unittest.TestCase): |
35 | 35 |
|
36 | 36 | def setUp(self): |
37 | | - ds_3d = get_sample_data_3d() |
38 | | - memory_store = new_data_store("memory", root="datasource") |
39 | | - memory_store.write_data(ds_3d, "era5_dataset3.zarr", replace=True) |
40 | | - self.accesor = CdsAccessor(memory_store) |
| 37 | + self.ds_3d = get_sample_data_3d() |
| 38 | + self.accessor = CdsAccessor(MagicMock(), MagicMock(), "era5-land", MagicMock()) |
41 | 39 |
|
42 | 40 | def test_open_data(self): |
43 | | - ds = self.accesor.open_data("era5_dataset3.zarr") |
44 | | - self.assertIsInstance(ds, xr.Dataset) |
45 | | - self.assertCountEqual(["band_1"], ds.data_vars) |
46 | | - self.assertEqual([10, 3, 3], [ds.sizes["time"], ds.sizes["lat"], ds.sizes["lon"]]) |
| 41 | + self.accessor.store.open_data.return_value = self.ds_3d |
| 42 | + ds = self.accessor.open_data( |
| 43 | + "era5-land", time_range=("2025-01-01", "2025-01-10") |
| 44 | + ) |
| 45 | + xr.testing.assert_equal(self.ds_3d, ds) |
| 46 | + self.accessor.store.open_data.assert_called_once() |
47 | 47 |
|
48 | | - @patch("xcube.core.store.fs.store.BaseFsDataStore.open_data") |
49 | | - @patch("xcube.core.store.fs.store.BaseFsDataStore.get_open_data_params_schema") |
50 | | - def test_open_data_spatial_res(self, mock_open_params_schema, mock_open_data): |
51 | | - mock_open_params_schema.return_value = JsonObjectSchema( |
52 | | - properties=dict(spatial_res=JsonNumberSchema(minimum=0.1 )) |
| 48 | + def test_open_data_spatial_res(self): |
| 49 | + self.accessor.store.open_data.return_value = self.ds_3d |
| 50 | + ds = self.accessor.open_data( |
| 51 | + "era5-land", |
| 52 | + time_range=("2025-01-01", "2025-01-10"), |
| 53 | + point=(5.0, 40.0), |
53 | 54 | ) |
54 | | - mock_open_data.return_value = get_sample_data_3d() |
55 | | - ds = self.accesor.open_data("era5_dataset3.zarr", point=(5.0, 40.0)) |
56 | 55 | self.assertIsInstance(ds, xr.Dataset) |
57 | 56 | self.assertCountEqual(["band_1"], ds.data_vars) |
58 | 57 | self.assertCountEqual(("time",), ds.dims) |
59 | 58 | self.assertEqual([10], [ds.sizes["time"]]) |
| 59 | + |
| 60 | + def test_open_data_splits(self): |
| 61 | + # Fail first call, succeed sequentially on split halves |
| 62 | + def side_effect(*args, **kwargs): |
| 63 | + time_range = kwargs.get("time_range") |
| 64 | + if time_range == ("2025-01-01", "2025-01-10"): |
| 65 | + raise Exception("Too large request") |
| 66 | + if time_range == ("2025-01-01", "2025-01-05"): |
| 67 | + return self.ds_3d.isel(time=slice(0, 5)) |
| 68 | + if time_range == ("2025-01-06", "2025-01-10"): |
| 69 | + return self.ds_3d.isel(time=slice(5, 10)) |
| 70 | + raise AssertionError("Unexpected time_range") |
| 71 | + |
| 72 | + self.accessor.store.open_data.side_effect = side_effect |
| 73 | + ds = self.accessor.open_data( |
| 74 | + "era5-land", time_range=("2025-01-01", "2025-01-10") |
| 75 | + ) |
| 76 | + xr.testing.assert_equal(self.ds_3d, ds) |
| 77 | + |
| 78 | + def test_open_with_split_base_case_error(self): |
| 79 | + self.accessor.store.open_data.side_effect = Exception("fail always") |
| 80 | + |
| 81 | + with self.assertRaises(DataStoreError) as cm: |
| 82 | + _ = self.accessor.open_data( |
| 83 | + "era5-land", time_range=("2025-01-01", "2025-01-10") |
| 84 | + ) |
| 85 | + self.assertIn("Cannot further split time range", str(cm.exception)) |
0 commit comments