22import threading
33import time
44from dataclasses import dataclass
5- from typing import Iterator
5+ from typing import Iterator , Dict , Any
6+ from pathlib import Path
7+ import json
68
79import pytest
810
@@ -290,65 +292,118 @@ def test_job_start_task_failure(self, worker_pool, dummy_backend, caplog):
290292 "Failed to start job 'job-000': OpenEoApiError('[500] Internal: No job starting for you, buddy')"
291293 ]
292294
293- def test_download_task_in_pool (self , worker_pool , tmp_path ):
294- # Test that download tasks can be submitted to the thread pool
295- # without needing actual backend functionality
296- task = _JobDownloadTask (
297- job_id = "pool-job-123" ,
298- df_idx = 42 ,
299- root_url = "https://example.com" ,
300- bearer_token = "test-token" ,
301- download_dir = tmp_path
302- )
295+
296+
297+ import tempfile
298+ from requests_mock import Mocker
299+ OPENEO_BACKEND = "https://openeo.dummy.test/"
300+
301+ class TestJobDownloadTask :
302+
303+ # Use a temporary directory for safe file handling
304+ @pytest .fixture
305+ def temp_dir (self ):
306+ with tempfile .TemporaryDirectory () as temp_dir :
307+ yield Path (temp_dir )
308+
309+ def test_job_download_success (self , requests_mock : Mocker , temp_dir : Path ):
310+ """
311+ Test a successful job download and verify file content and stats update.
312+ """
313+ job_id = "job-007"
314+ df_idx = 42
303315
304- worker_pool .submit_task (task )
305- results , remaining = worker_pool .process_futures (timeout = 1 )
316+ # Setup Dummy Backend
317+ backend = DummyBackend .at_url (OPENEO_BACKEND , requests_mock = requests_mock )
318+ backend .next_result = b"The downloaded file content."
306319
307- # We can't test the actual download result without a backend,
308- # but we can verify the task was processed
309- assert len (results ) == 1
310- result = results [0 ]
311- assert result .job_id == "pool-job-123"
312- assert result .df_idx == 42
313- assert remaining == 0
320+ # Pre-set job status to "finished" so the download link is available
321+ backend .batch_jobs [job_id ] = {"job_id" : job_id , "pg" : {}, "status" : "created" }
322+
323+ # Need to ensure job status is "finished" for download attempt to occur
324+ backend ._set_job_status (job_id = job_id , status = "finished" )
325+ backend .batch_jobs [job_id ]["status" ] = "finished"
314326
315- class TestJobDownloadTask :
316- def test_download_success (self , tmp_path , caplog ):
317- caplog .set_level (logging .INFO )
327+ download_dir = temp_dir / job_id / "results"
328+ download_dir .mkdir (parents = True )
318329
319- # Test the basic functionality without complex backend setup
320- download_dir = tmp_path / "downloads"
330+ # Create the task instance
321331 task = _JobDownloadTask (
322- job_id = "test-job-123" ,
323- df_idx = 0 ,
324- root_url = "https://example.com" ,
325- bearer_token = "test-token" ,
326- download_dir = download_dir
332+ root_url = OPENEO_BACKEND ,
333+ bearer_token = "dummy-token-7" ,
334+ job_id = job_id ,
335+ df_idx = df_idx ,
336+ download_dir = download_dir ,
327337 )
338+
339+ # Execute the task
340+ result = task .execute ()
341+
342+ # 4. Assertions
343+
344+ # A. Verify TaskResult structure
345+ assert isinstance (result , _TaskResult )
346+ assert result .job_id == job_id
347+ assert result .df_idx == df_idx
348+
349+ # B. Verify stats update for the MultiBackendJobManager
350+ assert result .stats_update == {"job download" : 1 }
351+
352+ # C. Verify download content (crucial part of the unit test)
353+ downloaded_file = download_dir / "result.data"
354+ assert downloaded_file .exists ()
355+ assert downloaded_file .read_bytes () == b"The downloaded file content."
356+
357+ # Verify backend interaction
358+ get_results_calls = [c for c in requests_mock .request_history if c .method == "GET" and f"/jobs/{ job_id } /results" in c .url ]
359+ assert len (get_results_calls ) >= 1
360+ get_asset_calls = [c for c in requests_mock .request_history if c .method == "GET" and f"/jobs/{ job_id } /results/result.data" in c .url ]
361+ assert len (get_asset_calls ) == 1
362+
363+ def test_job_download_failure (self , requests_mock : Mocker , temp_dir : Path ):
364+ """
365+ Test a failed download (e.g., bad connection) and verify error reporting.
366+ """
367+ job_id = "job-008"
368+ df_idx = 55
369+
370+ # Need to ensure job status is "finished" for download attempt to occur
371+ backend = DummyBackend .at_url (OPENEO_BACKEND , requests_mock = requests_mock )
372+
373+ requests_mock .get (
374+ f"{ OPENEO_BACKEND } jobs/{ job_id } /results" ,
375+ status_code = 500 ,
376+ json = {"code" : "InternalError" , "message" : "Failed to list results" })
377+
378+ backend .batch_jobs [job_id ] = {"job_id" : job_id , "pg" : {}, "status" : "created" }
328379
329- # Since we can't test actual downloads without a real backend,
330- # we'll test that the task is properly constructed and the directory is handled
331- assert task .job_id == "test-job-123"
332- assert task .df_idx == 0
333- assert task .root_url == "https://example.com"
334- assert task .download_dir == download_dir
335- # Token should be hidden in repr
336- assert "test-token" not in repr (task )
337-
338- def test_download_failure_handling (self , tmp_path , caplog ):
339- caplog .set_level (logging .ERROR )
380+ # Need to ensure job status is "finished" for download attempt to occur
381+ backend ._set_job_status (job_id = job_id , status = "finished" )
382+ backend .batch_jobs [job_id ]["status" ] = "finished"
340383
341- # Test that the task properly handles execution context
342- # We can't easily test actual download failures without complex setup,
343- # but we can verify the task structure and error handling approach
344- download_dir = tmp_path / "downloads"
384+ download_dir = temp_dir / job_id / "results"
385+ download_dir . mkdir ( parents = True )
386+
387+ # Create the task instance
345388 task = _JobDownloadTask (
346- job_id = "failing-job" ,
347- df_idx = 1 ,
348- root_url = "https://example.com" ,
349- bearer_token = "test-token" ,
350- download_dir = download_dir
389+ root_url = OPENEO_BACKEND ,
390+ bearer_token = "dummy-token-8" ,
391+ job_id = job_id ,
392+ df_idx = df_idx ,
393+ download_dir = download_dir ,
351394 )
395+
396+ # Execute the task
397+ result = task .execute ()
398+
399+ # Verify TaskResult structure
400+ assert isinstance (result , _TaskResult )
401+ assert result .job_id == job_id
402+ assert result .df_idx == df_idx
403+
404+ # Verify stats update for the MultiBackendJobManager
405+ assert result .stats_update == {"job download error" : 1 }
352406
353- # The task should be properly constructed for error handling
354- assert task .job_id == "failing-job"
407+ # Verify no file was created (or only empty/failed files)
408+ assert not any (p .is_file () for p in download_dir .glob ("*" ))
409+
0 commit comments