Skip to content

Accept search with ecmwf properties without "ecmwf:" prefix. #3264

Accept search with ecmwf properties without "ecmwf:" prefix.

Accept search with ecmwf properties without "ecmwf:" prefix. #3264

GitHub Actions / Test Results failed Dec 2, 2024 in 0s

3 fail, 3 skipped, 576 pass in 2m 56s

    2 files  ±0      2 suites  ±0   2m 56s ⏱️ -1s
  582 tests ±0    576 ✅  - 1  3 💤 ±0  3 ❌ +1 
1 164 runs  ±0  1 152 ✅  - 2  6 💤 ±0  6 ❌ +2 

Results for commit 44bc0fe. ± Comparison against earlier commit e013529.

Annotations

Check warning on line 0 in tests.units.test_search_plugins.TestSearchPluginQueryStringSearch

See this annotation in the file changed.

@github-actions github-actions / Test Results

All 2 runs failed: test_plugins_search_ecmwf_search_wekeo_discover_queryables (tests.units.test_search_plugins.TestSearchPluginQueryStringSearch)

artifacts/unit-test-results-python3.13-ubuntu-latest/junit-report.xml [took 0s]
artifacts/unit-test-results-python3.9-ubuntu-latest/junit-report.xml [took 0s]
Raw output
AssertionError: 'monthly_averaged_ensemble_members' != None
self = <tests.units.test_search_plugins.TestSearchPluginQueryStringSearch testMethod=test_plugins_search_ecmwf_search_wekeo_discover_queryables>
mock_requests_get = <function get at 0x7fe371ff7600>

    @mock.patch("eodag.utils.requests.requests.sessions.Session.get", autospec=True)
    def test_plugins_search_ecmwf_search_wekeo_discover_queryables(
        self, mock_requests_get
    ):
        # One of the providers that has discover_queryables() configured with QueryStringSearch
        search_plugin = self.get_search_plugin(provider="wekeo_ecmwf")
        self.assertEqual("WekeoECMWFSearch", search_plugin.__class__.__name__)
        self.assertEqual(
            "ECMWFSearch",
            search_plugin.discover_queryables.__func__.__qualname__.split(".")[0],
        )
    
        constraints_path = os.path.join(TEST_RESOURCES_PATH, "constraints.json")
        with open(constraints_path) as f:
            constraints = json.load(f)
        wekeo_ecmwf_constraints = {"constraints": constraints[0]}
        mock_requests_get.return_value = MockResponse(
            wekeo_ecmwf_constraints, status_code=200
        )
    
        provider_queryables_from_constraints_file = [
            "ecmwf:year",
            "ecmwf:month",
            "ecmwf:day",
            "ecmwf:time",
            "ecmwf:variable",
            "ecmwf:leadtime_hour",
            "ecmwf:type",
            "ecmwf:product_type",
        ]
    
        queryables = search_plugin.discover_queryables(productType="ERA5_SL_MONTHLY")
        self.assertIsNotNone(queryables)
    
        mock_requests_get.assert_called_once_with(
            mock.ANY,
            "https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/queryable/"
            "EO:ECMWF:DAT:REANALYSIS_ERA5_SINGLE_LEVELS_MONTHLY_MEANS",
            headers=USER_AGENT,
            auth=None,
            timeout=60,
        )
    
        # queryables from provider constraints file are added (here the ones of ERA5_SL_MONTHLY for wekeo_ecmwf)
        for provider_queryable in provider_queryables_from_constraints_file:
            provider_queryable = (
                get_queryable_from_provider(
                    provider_queryable,
                    search_plugin.get_metadata_mapping("ERA5_SL_MONTHLY"),
                )
                or provider_queryable
            )
            self.assertIn(provider_queryable, queryables)
    
        # default properties in provider config are added and must be default values of the queryables
        for property, default_value in search_plugin.config.products[
            "ERA5_SL_MONTHLY"
        ].items():
            queryable = queryables.get(property)
            if queryable is not None:
>               self.assertEqual(default_value, queryable.__metadata__[0].get_default())
E               AssertionError: 'monthly_averaged_ensemble_members' != None

tests/units/test_search_plugins.py:751: AssertionError

Check warning on line 0 in tests.units.test_search_plugins.TestSearchPluginPostJsonSearch

See this annotation in the file changed.

@github-actions github-actions / Test Results

All 2 runs failed: test_plugins_search_postjsonsearch_default_dates (tests.units.test_search_plugins.TestSearchPluginPostJsonSearch)

artifacts/unit-test-results-python3.13-ubuntu-latest/junit-report.xml [took 0s]
artifacts/unit-test-results-python3.9-ubuntu-latest/junit-report.xml [took 0s]
Raw output
AssertionError: expected call not found.
Expected: post('https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/search', json={'dataset_id': 'EO:ECMWF:DAT:REANALYSIS_ERA5_SINGLE_LEVELS', 'year': 2020, 'month': ['02'], 'day': ['20', '21'], 'time': ['01:00'], 'product_type': ['ensemble_mean'], 'variable': ['10m_u_component_of_wind'], 'data_format': 'grib', 'download_format': 'zip', 'itemsPerPage': 20, 'startIndex': 0}, headers={'User-Agent': 'eodag/3.0.2.dev23+g6b529e3c'}, timeout=60, verify=True)
  Actual: post('https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/search', json={'year': 2020, 'month': ['02'], 'day': ['20', '21'], 'time': ['01:00'], 'dataset_id': 'EO:ECMWF:DAT:REANALYSIS_ERA5_SINGLE_LEVELS', 'product_type': 'ensemble_mean', 'variable': '10m_u_component_of_wind', 'download_format': 'zip', 'data_format': 'grib', 'itemsPerPage': 20, 'startIndex': 0}, headers={'User-Agent': 'eodag/3.0.2.dev23+g6b529e3c'}, timeout=60, verify=True)
self = <tests.units.test_search_plugins.TestSearchPluginPostJsonSearch testMethod=test_plugins_search_postjsonsearch_default_dates>
mock_normalize = <function normalize_results at 0x7fcf68f5d080>
mock_request = <function post at 0x7fcf68605a80>

    @mock.patch("eodag.plugins.search.qssearch.requests.post", autospec=True)
    @mock.patch(
        "eodag.plugins.search.qssearch.PostJsonSearch.normalize_results", autospec=True
    )
    def test_plugins_search_postjsonsearch_default_dates(
        self, mock_normalize, mock_request
    ):
        provider = "wekeo_ecmwf"
        search_plugins = self.plugins_manager.get_search_plugins(provider=provider)
        search_plugin = next(search_plugins)
        mock_request.return_value = MockResponse({"features": []}, 200)
        # year, month, day, time given -> don't use default dates
        search_plugin.query(
            prep=PreparedSearch(),
            productType="ERA5_SL",
            year=2020,
            month=["02"],
            day=["20", "21"],
            time=["01:00"],
        )
>       mock_request.assert_called_with(
            "https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/search",
            json={
                "dataset_id": "EO:ECMWF:DAT:REANALYSIS_ERA5_SINGLE_LEVELS",
                "year": 2020,
                "month": ["02"],
                "day": ["20", "21"],
                "time": ["01:00"],
                "product_type": ["ensemble_mean"],
                "variable": ["10m_u_component_of_wind"],
                "data_format": "grib",
                "download_format": "zip",
                "itemsPerPage": 20,
                "startIndex": 0,
            },
            headers=USER_AGENT,
            timeout=60,
            verify=True,
        )

tests/units/test_search_plugins.py:1039: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../../.local/share/uv/python/cpython-3.13.0-linux-x86_64-gnu/lib/python3.13/unittest/mock.py:236: in assert_called_with
    return mock.assert_called_with(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <MagicMock name='post' spec='function' id='140528797692464'>
args = ('https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/search',)
kwargs = {'headers': {'User-Agent': 'eodag/3.0.2.dev23+g6b529e3c'}, 'json': {'data_format': 'grib', 'dataset_id': 'EO:ECMWF:DAT:REANALYSIS_ERA5_SINGLE_LEVELS', 'day': ['20', '21'], 'download_format': 'zip', ...}, 'timeout': 60, 'verify': True}
expected = call('', ('https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/search',), {'json': {'dataset_id': 'EO:ECMWF:DA...rPage': 20, 'startIndex': 0}, 'headers': {'User-Agent': 'eodag/3.0.2.dev23+g6b529e3c'}, 'timeout': 60, 'verify': True})
actual = call('', ('https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/search',), {'json': {'year': 2020, 'month': ['0...rPage': 20, 'startIndex': 0}, 'headers': {'User-Agent': 'eodag/3.0.2.dev23+g6b529e3c'}, 'timeout': 60, 'verify': True})
_error_message = <function NonCallableMock.assert_called_with.<locals>._error_message at 0x7fcf68f5cb80>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.
    
        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\n  Actual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)
    
        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: post('https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/search', json={'dataset_id': 'EO:ECMWF:DAT:REANALYSIS_ERA5_SINGLE_LEVELS', 'year': 2020, 'month': ['02'], 'day': ['20', '21'], 'time': ['01:00'], 'product_type': ['ensemble_mean'], 'variable': ['10m_u_component_of_wind'], 'data_format': 'grib', 'download_format': 'zip', 'itemsPerPage': 20, 'startIndex': 0}, headers={'User-Agent': 'eodag/3.0.2.dev23+g6b529e3c'}, timeout=60, verify=True)
E             Actual: post('https://gateway.prod.wekeo2.eu/hda-broker/api/v1/dataaccess/search', json={'year': 2020, 'month': ['02'], 'day': ['20', '21'], 'time': ['01:00'], 'dataset_id': 'EO:ECMWF:DAT:REANALYSIS_ERA5_SINGLE_LEVELS', 'product_type': 'ensemble_mean', 'variable': '10m_u_component_of_wind', 'download_format': 'zip', 'data_format': 'grib', 'itemsPerPage': 20, 'startIndex': 0}, headers={'User-Agent': 'eodag/3.0.2.dev23+g6b529e3c'}, timeout=60, verify=True)

../../../.local/share/uv/python/cpython-3.13.0-linux-x86_64-gnu/lib/python3.13/unittest/mock.py:977: AssertionError

Check warning on line 0 in tests.units.test_search_plugins.TestSearchPluginPostJsonSearch

See this annotation in the file changed.

@github-actions github-actions / Test Results

All 2 runs failed: test_plugins_search_postjsonsearch_query_params_wekeo (tests.units.test_search_plugins.TestSearchPluginPostJsonSearch)

artifacts/unit-test-results-python3.13-ubuntu-latest/junit-report.xml [took 0s]
artifacts/unit-test-results-python3.9-ubuntu-latest/junit-report.xml [took 0s]
Raw output
AssertionError: {'hydrological_year': ['1980_81'], 'dataset[194 chars]': 0} != {'dataset_id': 'EO:ECMWF:DAT:DERIVED_GRIDDE[185 chars]': 0}
  {'data_format': 'zip',
   'dataset_id': 'EO:ECMWF:DAT:DERIVED_GRIDDED_GLACIER_MASS_CHANGE',
-  'format': 'zip',
   'hydrological_year': ['1980_81'],
   'itemsPerPage': 10,
+  'product_version': 'wgms_fog_2022_09',
   'startIndex': 0,
-  'variable': 'glacier_mass_change',
?                                   ^

+  'variable': 'glacier_mass_change'}
?                                   ^

-  'version': 'wgms_fog_2022_09'}
self = <tests.units.test_search_plugins.TestSearchPluginPostJsonSearch testMethod=test_plugins_search_postjsonsearch_query_params_wekeo>
mock__request = <function _request at 0x7fcf6810bd80>

    @mock.patch("eodag.plugins.search.qssearch.PostJsonSearch._request", autospec=True)
    def test_plugins_search_postjsonsearch_query_params_wekeo(self, mock__request):
        """A query with PostJsonSearch (here wekeo) must generate query params corresponding to the
        search criteria"""
        provider = "wekeo_ecmwf"
        product_type = "GRIDDED_GLACIERS_MASS_CHANGE"
        search_plugin = self.get_search_plugin(product_type, provider)
        auth_plugin = self.get_auth_plugin(search_plugin)
    
        mock__request.return_value = mock.Mock()
    
        def _test_query_params(search_criteria, raw_result, expected_query_params):
            mock__request.reset_mock()
            mock__request.return_value.json.side_effect = [raw_result]
            results, _ = search_plugin.query(
                prep=PreparedSearch(
                    page=1,
                    items_per_page=10,
                    auth_plugin=auth_plugin,
                ),
                **search_criteria,
            )
            self.assertDictEqual(
                mock__request.call_args_list[0].args[1].query_params,
                expected_query_params,
            )
    
        raw_result = {
            "properties": {"itemsPerPage": 1, "startIndex": 0, "totalResults": 1},
            "features": [
                {
                    "type": "Feature",
                    "properties": {
                        "startdate": "1975-01-01T00:00:00Z",
                        "enddate": "2024-09-30T00:00:00Z",
                    },
                    "id": "derived-gridded-glacier-mass-change-576f8a153a25a83d9d3a5cfb03c4a759",
                }
            ],
        }
    
        # Test #1: using the datetime
        search_criteria = {
            "productType": product_type,
            "startTimeFromAscendingNode": "1980-01-01",
            "completionTimeFromAscendingNode": "1981-12-31",
            "variable": "glacier_mass_change",
            "format": "zip",
            "version": "wgms_fog_2022_09",
        }
        expected_query_params = {
            "dataset_id": "EO:ECMWF:DAT:DERIVED_GRIDDED_GLACIER_MASS_CHANGE",
            "hydrological_year": ["1980_81"],
            "variable": "glacier_mass_change",
            "data_format": "zip",
            "product_version": "wgms_fog_2022_09",
            "itemsPerPage": 10,
            "startIndex": 0,
        }
>       _test_query_params(search_criteria, raw_result, expected_query_params)

tests/units/test_search_plugins.py:1218: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/units/test_search_plugins.py:1181: in _test_query_params
    self.assertDictEqual(
E   AssertionError: {'hydrological_year': ['1980_81'], 'dataset[194 chars]': 0} != {'dataset_id': 'EO:ECMWF:DAT:DERIVED_GRIDDE[185 chars]': 0}
E     {'data_format': 'zip',
E      'dataset_id': 'EO:ECMWF:DAT:DERIVED_GRIDDED_GLACIER_MASS_CHANGE',
E   -  'format': 'zip',
E      'hydrological_year': ['1980_81'],
E      'itemsPerPage': 10,
E   +  'product_version': 'wgms_fog_2022_09',
E      'startIndex': 0,
E   -  'variable': 'glacier_mass_change',
E   ?                                   ^
E   
E   +  'variable': 'glacier_mass_change'}
E   ?                                   ^
E   
E   -  'version': 'wgms_fog_2022_09'}