Skip to content

Scenario Failure: sentinel1_soil_moisture #385

@github-actions

Description

@github-actions

Benchmark scenario ID: sentinel1_soil_moisture
Benchmark scenario definition: https://github.com/ESA-APEx/apex_algorithms/blob/a4d58a18b69cf4c81512047b01e3f3e7581b54dc/algorithm_catalog/vito/surfacesoilmoisture/benchmark_scenarios/sentinel1_soil_moisture.json
openEO backend: openeofed.dataspace.copernicus.eu

GitHub Actions workflow run: https://github.com/ESA-APEx/apex_algorithms/actions/runs/22812845706
Workflow artifacts: https://github.com/ESA-APEx/apex_algorithms/actions/runs/22812845706#artifacts

Test start: 2026-03-08 03:17:47.612808+00:00
Test duration: 0:07:11.716538
Test outcome: ❌ failed

Last successful test phase: download-actual
Failure in test phase: download-reference

Contact Information

Name Organization Contact
Hans Vanrompay VITO Contact via VITO (VITO Website, GitHub)

Process Graph

{
  "soil_moisture1": {
    "arguments": {
      "spatial_extent": {
        "coordinates": [
          [
            [
              139.194,
              -35.516
            ],
            [
              139.535,
              -35.516
            ],
            [
              139.535,
              -35.284
            ],
            [
              139.194,
              -35.284
            ],
            [
              139.194,
              -35.516
            ]
          ]
        ],
        "type": "Polygon"
      },
      "reference_temporal_extent": [
        "2017-02-02",
        "2020-02-02"
      ],
      "current_temporal_extent": [
        "2020-02-02",
        "2020-02-28"
      ]
    },
    "namespace": "https://raw.githubusercontent.com/ESA-APEx/apex_algorithms/8ad2bccf3d7534f0743a9cf73911080abc32f74c/algorithm_catalog/vito/surfacesoilmoisture/openeo_udp/sentinel1_soil_moisture.json",
    "process_id": "sentinel1_soil_moisture"
  },
  "saveresult1": {
    "arguments": {
      "data": {
        "from_node": "soil_moisture1"
      },
      "format": "GTiff",
      "options": {}
    },
    "process_id": "save_result",
    "result": true
  }
}

Error Logs

scenario = BenchmarkScenario(id='sentinel1_soil_moisture', description='Estimates surface soil moisture from Sentinel-1 GRD data ...gorithms/apex_algorithms/algorithm_catalog/vito/surfacesoilmoisture/benchmark_scenarios/sentinel1_soil_moisture.json'))
connection_factory = <function connection_factory.<locals>.get_connection at 0x7fc3bc09dda0>
tmp_path = PosixPath('/home/runner/work/apex_algorithms/apex_algorithms/qa/benchmarks/tmp_path_root/test_run_benchmark_sentinel1_s0')
track_metric = <function track_metric.<locals>.track at 0x7fc3bc09dee0>
track_phase = <function track_phase.<locals>.track at 0x7fc3bc09e020>
upload_assets_on_fail = <function upload_assets_on_fail.<locals>.collect at 0x7fc3bc09e0c0>
request = <FixtureRequest for <Function test_run_benchmark[sentinel1_soil_moisture]>>

    @pytest.mark.parametrize(
        "scenario",
        [
            # Use scenario id as parameterization id to give nicer test names.
            pytest.param(uc, id=uc.id)
            for uc in get_benchmark_scenarios()
        ],
    )
    def test_run_benchmark(
        scenario: BenchmarkScenario,
        connection_factory,
        tmp_path: Path,
        track_metric,
        track_phase,
        upload_assets_on_fail,
        request,
    ):
        track_metric("scenario_id", scenario.id)

        with track_phase(phase="connect"):
            # Check if a backend override has been provided via cli options.
            override_backend = request.config.getoption("--override-backend")
            backend_filter = request.config.getoption("--backend-filter")
            if backend_filter and not re.match(backend_filter, scenario.backend):
                # TODO apply filter during scenario retrieval, but seems to be hard to retrieve cli param
                pytest.skip(
                    f"skipping scenario {scenario.id} because backend {scenario.backend} does not match filter {backend_filter!r}"
                )
            backend = scenario.backend
            if override_backend:
                _log.info(f"Overriding backend URL with {override_backend!r}")
                backend = override_backend

            connection: openeo.Connection = connection_factory(url=backend)

        report_path = None

        with track_phase(phase="create-job"):
            # TODO #14 scenario option to use synchronous instead of batch job mode?
            job = connection.create_job(
                process_graph=scenario.process_graph,
                title=f"APEx benchmark {scenario.id}",
                additional=scenario.job_options,
            )
            track_metric("job_id", job.job_id)

            if request.config.getoption("--upload-benchmark-report"):
                report_path = tmp_path / "benchmark_report.json"
                report_path.write_text(json.dumps({
                    "job_id": job.job_id,
                    "scenario_id": scenario.id,
                    "scenario_description": scenario.description,
                    "scenario_backend": scenario.backend,
                    "scenario_source": str(scenario.source) if scenario.source else None,
                    "reference_data": scenario.reference_data,
                    "reference_options": scenario.reference_options,
                }, indent=2))
                upload_assets_on_fail(report_path)

        with track_phase(phase="run-job"):
            # TODO: monitor timing and progress
            # TODO: separate "job started" and run phases?
            max_minutes = request.config.getoption("--maximum-job-time-in-minutes")
            if max_minutes:
                def _timeout_handler(signum, frame):
                    raise TimeoutError(
                        f"Batch job {job.job_id} exceeded maximum allowed time of {max_minutes} minutes"
                    )

                old_handler = signal.signal(signal.SIGALRM, _timeout_handler)
                signal.alarm(max_minutes * 60)
            try:
                job.start_and_wait()
            finally:
                if max_minutes:
                    signal.alarm(0)
                    signal.signal(signal.SIGALRM, old_handler)

        with track_phase(phase="collect-metadata"):
            collect_metrics_from_job_metadata(job, track_metric=track_metric)

            results = job.get_results()
            collect_metrics_from_results_metadata(results, track_metric=track_metric)

        with track_phase(phase="download-actual"):
            # Download actual results
            actual_dir = tmp_path / "actual"
            paths = results.download_files(target=actual_dir, include_stac_metadata=True)

            # Upload assets on failure
            upload_assets_on_fail(*paths)

        with track_phase(phase="download-reference"):
>           reference_dir = download_reference_data(
                scenario=scenario, reference_dir=tmp_path / "reference"
            )

tests/test_benchmarks.py:117:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/apex_algorithm_qa_tools/scenarios.py:151: in download_reference_data
    resp = requests.get(source, stream=True)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/requests/api.py:73: in get
    return request("get", url, params=params, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/requests/api.py:59: in request
    return session.request(method=method, url=url, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/requests/sessions.py:575: in request
    prep = self.prepare_request(req)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
/opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/requests/sessions.py:484: in prepare_request
    p.prepare(
/opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/requests/models.py:367: in prepare
    self.prepare_url(url, params)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <PreparedRequest [GET]>, url = '', params = OrderedDict()

    def prepare_url(self, url, params):
        """Prepares the given HTTP URL."""
        #: Accept objects that have string representations.
        #: We're unable to blindly call unicode/str functions
        #: as this will include the bytestring indicator (b'')
        #: on python 3.x.
        #: https://github.com/psf/requests/pull/2238
        if isinstance(url, bytes):
            url = url.decode("utf8")
        else:
            url = str(url)

        # Remove leading whitespaces from url
        url = url.lstrip()

        # Don't do any URL preparation for non-HTTP schemes like `mailto`,
        # `data` etc to work around exceptions from `url_parse`, which
        # handles RFC 3986 only.
        if ":" in url and not url.lower().startswith("http"):
            self.url = url
            return

        # Support for unicode domain names and paths.
        try:
            scheme, auth, host, port, path, query, fragment = parse_url(url)
        except LocationParseError as e:
            raise InvalidURL(*e.args)

        if not scheme:
>           raise MissingSchema(
                f"Invalid URL {url!r}: No scheme supplied. "
                f"Perhaps you meant https://{url}?"
            )
E           requests.exceptions.MissingSchema: Invalid URL '': No scheme supplied. Perhaps you meant https://?

/opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/site-packages/requests/models.py:438: MissingSchema
----------------------------- Captured stdout call -----------------------------
0:00:00 Job 'cdse-j-2603080317524b69940764d35be5dfce': send 'start'
0:00:23 Job 'cdse-j-2603080317524b69940764d35be5dfce': created (progress 0%)
0:00:28 Job 'cdse-j-2603080317524b69940764d35be5dfce': running (progress N/A)
0:00:37 Job 'cdse-j-2603080317524b69940764d35be5dfce': running (progress N/A)
0:00:45 Job 'cdse-j-2603080317524b69940764d35be5dfce': running (progress N/A)
0:00:55 Job 'cdse-j-2603080317524b69940764d35be5dfce': running (progress N/A)
0:01:07 Job 'cdse-j-2603080317524b69940764d35be5dfce': running (progress N/A)
0:01:23 Job 'cdse-j-2603080317524b69940764d35be5dfce': running (progress N/A)
0:01:42 Job 'cdse-j-2603080317524b69940764d35be5dfce': running (progress N/A)
0:02:06 Job 'cdse-j-2603080317524b69940764d35be5dfce': running (progress N/A)
0:02:37 Job 'cdse-j-2603080317524b69940764d35be5dfce': running (progress N/A)
0:03:14 Job 'cdse-j-2603080317524b69940764d35be5dfce': running (progress N/A)
0:04:01 Job 'cdse-j-2603080317524b69940764d35be5dfce': running (progress N/A)
0:04:59 Job 'cdse-j-2603080317524b69940764d35be5dfce': running (progress N/A)
0:06:00 Job 'cdse-j-2603080317524b69940764d35be5dfce': running (progress N/A)
0:07:00 Job 'cdse-j-2603080317524b69940764d35be5dfce': finished (progress 100%)
------------------------------ Captured log call -------------------------------
INFO     conftest:conftest.py:145 Connecting to 'openeofed.dataspace.copernicus.eu'
INFO     openeo.config:config.py:193 Loaded openEO client config from sources: []
INFO     conftest:conftest.py:158 Checking for auth_env_var='OPENEO_AUTH_CLIENT_CREDENTIALS_CDSEFED' to drive auth against url='openeofed.dataspace.copernicus.eu'.
INFO     conftest:conftest.py:162 Extracted provider_id='CDSE' client_id='openeo-apex-benchmarks-service-account' from auth_env_var='OPENEO_AUTH_CLIENT_CREDENTIALS_CDSEFED'
INFO     openeo.rest.connection:connection.py:302 Found OIDC providers: ['CDSE']
INFO     openeo.rest.auth.oidc:oidc.py:404 Doing 'client_credentials' token request 'https://identity.dataspace.copernicus.eu/auth/realms/CDSE/protocol/openid-connect/token' with post data fields ['grant_type', 'client_id', 'client_secret', 'scope'] (client_id 'openeo-apex-benchmarks-service-account')
INFO     openeo.rest.connection:connection.py:401 Obtained tokens: ['access_token', 'id_token']
INFO     openeo.rest.job:job.py:436 Downloading Job result asset 'openEO.tif' from https://s3.waw3-1.openeo.v1.dataspace.copernicus.eu/openeo-data-prod-waw4-1/batch_jobs/j-2603080317524b69940764d35be5dfce/openEO.tif?X-Proxy-Head-As-Get=true&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=e61b97beed494374b0cb630a679d0ac5%2F20260308%2Fwaw4-1%2Fs3%2Faws4_request&X-Amz-Date=20260308T032454Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Security-Token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlX2FybiI6ImFybjpvcGVuZW93czppYW06Ojpyb2xlL29wZW5lby1kYXRhLXByb2Qtd2F3NC0xLXdvcmtzcGFjZSIsImluaXRpYWxfaXNzdWVyIjoib3BlbmVvLnByb2Qud2F3My0xLm9wZW5lby1pbnQudjEuZGF0YXNwYWNlLmNvcGVybmljdXMuZXUiLCJodHRwczovL2F3cy5hbWF6b24uY29tL3RhZ3MiOnsicHJpbmNpcGFsX3RhZ3MiOnsiam9iX2lkIjpbImotMjYwMzA4MDMxNzUyNGI2OTk0MDc2NGQzNWJlNWRmY2UiXSwidXNlcl9pZCI6WyI2YTc3ZmNkMS05YzA4LTQ2ZTktYjg3NS01NGZiOTk5YWIyMDAiXX0sInRyYW5zaXRpdmVfdGFnX2tleXMiOlsidXNlcl9pZCIsImpvYl9pZCJdfSwiaXNzIjoic3RzLndhdzMtMS5vcGVuZW8udjEuZGF0YXNwYWNlLmNvcGVybmljdXMuZXUiLCJzdWIiOiJvcGVuZW8tZHJpdmVyIiwiZXhwIjoxNzcyOTgzNDk0LCJuYmYiOjE3NzI5NDAyOTQsImlhdCI6MTc3Mjk0MDI5NCwianRpIjoiYTc2ZWIxNmUtMzViYy00NWRmLWJiNzktMjRhMjkzMDZjMjgxIiwiYWNjZXNzX2tleV9pZCI6ImU2MWI5N2JlZWQ0OTQzNzRiMGNiNjMwYTY3OWQwYWM1In0.jlW-cwjtvw5zzeH8doSH1XkCJq81UWV3g1OUfk0KZ4KtqmoMhTNblZ0q9yevDOYGIZace0BuFpKNbYltNEopdtLxaxMfEgf1n6uZo3-xNFiJ_Vtaq-VIGQwCcGBAi5iHA_5v6EW5JtAS262NrQGg3NyMdQTcQPDJXI4-TrN2Eiy0-v-jgpZNXI-Y-SmgP4oLMA61MsIriw2nX6EiRLm_R1NznVWWfiD_kFchqVtP8UdbvBGJaovR7CECbDKay6eig0mVk5tCqUWiu_Or1Mip5AQBuokO9hKqCtx8_cdIcv3wUzX-6iTJPvK2Wi47fikjCdkBlI6boy15SAu7TX-m5A&X-Amz-Signature=7f50ea86ad9fd875fe4c7d2e3746b7f0e36de70eac257d8854a8aa07578d0291 to /home/runner/work/apex_algorithms/apex_algorithms/qa/benchmarks/tmp_path_root/test_run_benchmark_sentinel1_s0/actual/openEO.tif
INFO     apex_algorithm_qa_tools.scenarios:util.py:345 Downloading reference data for scenario.id='sentinel1_soil_moisture' to reference_dir=PosixPath('/home/runner/work/apex_algorithms/apex_algorithms/qa/benchmarks/tmp_path_root/test_run_benchmark_sentinel1_s0/reference'): start 2026-03-08 03:24:59.327980
INFO     apex_algorithm_qa_tools.scenarios:util.py:345 Downloading source='' to path=PosixPath('/home/runner/work/apex_algorithms/apex_algorithms/qa/benchmarks/tmp_path_root/test_run_benchmark_sentinel1_s0/reference/openEO.tif'): start 2026-03-08 03:24:59.328346
INFO     apex_algorithm_qa_tools.scenarios:util.py:351 Downloading source='' to path=PosixPath('/home/runner/work/apex_algorithms/apex_algorithms/qa/benchmarks/tmp_path_root/test_run_benchmark_sentinel1_s0/reference/openEO.tif'): fail 2026-03-08 03:24:59.328731, elapsed 0:00:00.000385
INFO     apex_algorithm_qa_tools.scenarios:util.py:351 Downloading reference data for scenario.id='sentinel1_soil_moisture' to reference_dir=PosixPath('/home/runner/work/apex_algorithms/apex_algorithms/qa/benchmarks/tmp_path_root/test_run_benchmark_sentinel1_s0/reference'): fail 2026-03-08 03:24:59.328858, elapsed 0:00:00.000878

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions