Skip to content

chore: Bump pip and pyjwt#668

Open
aig-hannes wants to merge 1 commit into
mainfrom
feature/fix-cve
Open

chore: Bump pip and pyjwt#668
aig-hannes wants to merge 1 commit into
mainfrom
feature/fix-cve

Conversation

@aig-hannes
Copy link
Copy Markdown
Contributor

No description provided.

@aig-hannes aig-hannes self-assigned this Jun 5, 2026
@aig-hannes aig-hannes requested a review from a team as a code owner June 5, 2026 14:02
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Jun 5, 2026

@aig-hannes aig-hannes enabled auto-merge (rebase) June 5, 2026 14:07
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 5, 2026

❌ 2 Tests Failed:

Tests completed Failed Passed Skipped
879 2 877 15
View the top 2 failed test(s) by shortest run time
tests.aignostics.application.gui_test::test_gui_run_download
Stack Traces | 46.7s run time
user = <nicegui.testing.user.User object at 0x7f0cc5f535c0>
runner = <typer.testing.CliRunner object at 0x7f0cc5f51e00>
tmp_path = PosixPath('.../pytest-of-runner/pytest-21/test_gui_run_download1')
silent_logging = None
record_property = <function record_property.<locals>.append_property at 0x7f0cf41ec040>

    @pytest.mark.e2e
    @pytest.mark.long_running
    @pytest.mark.flaky(retries=1, delay=5)
    @pytest.mark.timeout(timeout=60 * 10)
    @pytest.mark.sequential  # Helps on Linux with image analysis step otherwise timing out
    async def test_gui_run_download(  # noqa: PLR0914, PLR0915
        user: User, runner: CliRunner, tmp_path: Path, silent_logging: None, record_property
    ) -> None:
        """Test that the user can download a run result via the GUI."""
        record_property("tested-item-id", "SPEC-APPLICATION-SERVICE, SPEC-GUI-SERVICE")
        with patch(
            "aignostics.application._gui._page_application_run_describe.get_user_data_directory",
            return_value=tmp_path,
        ):
            # Find run
            runs = Service().application_runs(
                application_id=HETA_APPLICATION_ID,
                application_version=HETA_APPLICATION_VERSION,
                external_id=SPOT_0_GS_URL,
                tags=["scheduled"],
                has_output=True,
                limit=1,
            )
            if not runs:
                message = f"No matching runs found for application {HETA_APPLICATION_ID} ({HETA_APPLICATION_VERSION}). "
                message += "This test requires the scheduled test test_application_runs_heta_version passing first."
                pytest.skip(message)
    
            run_id = runs[0].run_id
    
            # Explore run
            run = Service().application_run(run_id).details()
            print(
                f"Found existing run: {run.run_id}\n"
                f"application: {run.application_id} ({run.version_number})\n"
                f"status: {run.state}, output: {run.output}\n"
                f"submitted at: {run.submitted_at}, terminated at: {run.terminated_at}\n"
                f"statistics: {run.statistics!r}\n",
                f"custom_metadata: {run.custom_metadata!r}\n",
            )
            # Step 1: Go to latest completed run
            await user.open(f"/application/run/{run.run_id}")
            await user.should_see(f"Run {run.run_id}", retries=100)
            await user.should_see(
                f"Run of {run.application_id} ({run.version_number})",
                retries=100,
            )
    
            # Step 2: Open Result Download dialog
            await user.should_see(marker="BUTTON_DOWNLOAD_RUN", retries=100)
            user.find(marker="BUTTON_DOWNLOAD_RUN").click()
    
            # Step 3: Check download button is initially disabled, then select Data folder
            download_run_button: ui.button = user.find(marker="DIALOG_BUTTON_DOWNLOAD_RUN").elements.pop()
            assert not download_run_button.enabled, "Download button should be disabled before selecting target"
            await user.should_see(marker="BUTTON_DOWNLOAD_DESTINATION_DATA", retries=100)
            user.find(marker="BUTTON_DOWNLOAD_DESTINATION_DATA").click()
            await assert_notified(user, "Using Launchpad results directory")
    
            # Step 4: Trigger Download - wait for button to be enabled
            download_run_button = user.find(marker="DIALOG_BUTTON_DOWNLOAD_RUN").elements.pop()
            assert download_run_button.enabled, "Download button should be enabled after selecting target"
            user.find(marker="DIALOG_BUTTON_DOWNLOAD_RUN").click()
            await assert_notified(user, "Downloading ...")
    
            # Check: Download completed
            await assert_notified(user, "Download completed.", 60 * 4)
            print_directory_structure(tmp_path, "downloaded_run")
    
            # Check for directory layout as expected
            run_dir = tmp_path / run.run_id
            assert run_dir.is_dir(), f"Expected run directory {run_dir} not found"
    
            subdirs = [d for d in run_dir.iterdir() if d.is_dir()]
            assert len(subdirs) == 2, f"Expected two subdirectories in {run_dir}, but found {len(subdirs)}"
    
            input_dir = run_dir / "input"
            assert input_dir.is_dir(), f"Expected input directory {input_dir} not found"
    
            results_dir = run_dir / SPOT_0_FILENAME.replace(".tiff", "")
            assert results_dir.is_dir(), f"Expected run results directory {results_dir} not found"
    
            # Check for input file having been downloaded
            input_file = input_dir / SPOT_0_FILENAME
            assert input_file.exists(), f"Expected input file {input_file} not found"
            assert input_file.stat().st_size == SPOT_0_FILESIZE, (
                f"Expected input file size {SPOT_0_FILESIZE}, but got {input_file.stat().st_size}"
            )
    
            # Check for files in the results directory
            files_in_results_dir = list(results_dir.glob("*"))
            expected_count = len(SPOT_0_EXPECTED_RESULT_FILES)
>           assert len(files_in_results_dir) == expected_count, (
                f"Expected {expected_count} files in {results_dir}, but found {len(files_in_results_dir)}: "
                f"{[f.name for f in files_in_results_dir]}"
            )
E           AssertionError: Expected 12 files in .../pytest-of-runner/pytest-21/test_gui_run_download1/b197ab65-0be1-488c-ad2e-68ab1b6b2603/8fafc17d-a5cc-4e9d-a982-030b1486ca88, but found 14: ['cell_classification_geojson_polygons.json', 'cell_classification_parquet_polygons.parquet', 'tissue_qc_csv_class_information.csv', 'readout_generation_slide_readouts.csv', 'tissue_segmentation_segmentation_map_image.tiff', 'tissue_segmentation_geojson_polygons.json', 'readout_generation_cell_readouts.csv', 'tissue_segmentation_csv_class_information.csv', 'tissue_qc_geojson_polygons.json', 'tissue_qc_parquet_polygons.parquet', 'tissue_segmentation_parquet_polygons.parquet', 'cell_detection_parquet_centers.parquet', 'cell_detection_parquet_polygons.parquet', 'tissue_qc_segmentation_map_image.tiff']
E           assert 14 == 12
E            +  where 14 = len([PosixPath('.../pytest-of-runner/pytest-21/test_gui_run_download1/b197ab65-0be1-488c-ad2e-68ab1b6b2603/8fafc17d-a5cc-4e9d-a982-030b1486ca88/cell_classification_geojson_polygons.json'), PosixPath('.../pytest-of-runner/pytest-21/test_gui_run_download1/b197ab65-0be1-488c-ad2e-68ab1b6b2603/8fafc17d-a5cc-4e9d-a982-030b1486ca88/cell_classification_parquet_polygons.parquet'), PosixPath('.../pytest-of-runner/pytest-21/test_gui_run_download1/b197ab65-0be1-488c-ad2e-68ab1b6b2603/8fafc17d-a5cc-4e9d-a982-030b1486ca88/tissue_qc_csv_class_information.csv'), PosixPath('.../pytest-of-runner/pytest-21/test_gui_run_download1/b197ab65-0be1-488c-ad2e-68ab1b6b2603/8fafc17d-a5cc-4e9d-a982-030b1486ca88/readout_generation_slide_readouts.csv'), PosixPath('.../pytest-of-runner/pytest-21/test_gui_run_download1/b197ab65-0be1-488c-ad2e-68ab1b6b2603/8fafc17d-a5cc-4e9d-a982-030b1486ca88/tissue_segmentation_segmentation_map_image.tiff'), PosixPath('.../pytest-of-runner/pytest-21/test_gui_run_download1/b197ab65-0be1-488c-ad2e-68ab1b6b2603/8fafc17d-a5cc-4e9d-a982-030b1486ca88/tissue_segmentation_geojson_polygons.json'), ...])

.../aignostics/application/gui_test.py:445: AssertionError
tests.aignostics.qupath.gui_test::test_gui_run_qupath_install_to_inspect
Stack Traces | 63.7s run time
user = <nicegui.testing.user.User object at 0x7f0cd6ce2140>
runner = <typer.testing.CliRunner object at 0x7f0cc4d0c670>
tmp_path = PosixPath('.../pytest-of-runner/pytest-21/test_gui_run_qupath_install_to0')
silent_logging = None, qupath_teardown = None, qupath_save_restore = None
record_property = <function record_property.<locals>.append_property at 0x7f0cd6ed5f30>

    @pytest.mark.e2e
    @pytest.mark.long_running
    @pytest.mark.skipif(
        (platform.system() == "Linux" and platform.machine() in {"aarch64", "arm64"}),
        reason="QuPath is not supported on ARM64 Linux",
    )
    @pytest.mark.timeout(timeout=60 * 15)
    @pytest.mark.sequential
    async def test_gui_run_qupath_install_to_inspect(  # noqa: C901, PLR0912, PLR0913, PLR0914, PLR0915, PLR0917
        user: User,
        runner: CliRunner,
        tmp_path: Path,
        silent_logging: None,
        qupath_teardown: None,
        qupath_save_restore: None,
        record_property,
    ) -> None:
        """Test installing QuPath, downloading run results, creating QuPath project from it, and inspecting results."""
        record_property("tested-item-id", "TC-QUPATH-01, SPEC-GUI-SERVICE")
    
        # Find run
        runs = Service().application_runs(
            application_id=HETA_APPLICATION_ID,
            application_version=HETA_APPLICATION_VERSION,
            external_id=SPOT_0_GS_URL,
            tags=["scheduled"],
            has_output=True,
            limit=1,
        )
        if not runs:
            message = f"No matching runs found for application {HETA_APPLICATION_ID} ({HETA_APPLICATION_VERSION}). "
            message += "This test requires the scheduled test test_application_runs_heta_version passing first."
            pytest.skip(message)
    
        run_id = runs[0].run_id
    
        # Explore run
        run = Service().application_run(run_id).details()
        print(
            f"Found existing run: {run.run_id}\n"
            f"application: {run.application_id} ({run.version_number})\n"
            f"status: {run.state}, output: {run.output}\n"
            f"submitted at: {run.submitted_at}, terminated at: {run.terminated_at}\n"
            f"statistics: {run.statistics!r}\n",
            f"custom_metadata: {run.custom_metadata!r}\n",
        )
    
        # Explore results
        results = list(Service().application_run(run_id).results())
        assert results, f"No results found for run {run_id}"
        for item in results:
            print(
                f"Found item: {item.item_id}, status: {item.state}, output: {item.output}, "
                f"external_id: {item.external_id}\n"
                f"custom_metadata: {item.custom_metadata!r}\n",
            )
    
        with patch(
            "aignostics.application._gui._page_application_run_describe.get_user_data_directory", return_value=tmp_path
        ):
            # Step 1: (Re)Install QuPath
            result = runner.invoke(cli, ["qupath", "install"])
            output = normalize_output(result.output, strip_ansi=True)
            assert f"QuPath v{QUPATH_VERSION} installed successfully" in output, (
                f"Expected 'QuPath v{QUPATH_VERSION} installed successfully' in output.\nOutput: {output}"
            )
            assert result.exit_code == 0
    
            # Step 2: Go to latest completed run via GUI
            await user.open(f"/application/run/{run.run_id}")
            await user.should_see(f"Run {run.run_id}")
            await user.should_see(f"Run of {HETA_APPLICATION_ID} ({HETA_APPLICATION_VERSION})")
    
            # Step 3: Open Result Download dialog
            await user.should_see(marker="BUTTON_OPEN_QUPATH", retries=100)
            user.find(marker="BUTTON_OPEN_QUPATH").click()
    
            # Step 4: Select Data destination
            await user.should_see(marker="BUTTON_DOWNLOAD_DESTINATION_DATA")
            download_destination_data_button: ui.button = user.find(
                marker="BUTTON_DOWNLOAD_DESTINATION_DATA"
            ).elements.pop()
            assert download_destination_data_button.enabled, "Download destination button should be enabled"
            user.find(marker="BUTTON_DOWNLOAD_DESTINATION_DATA").click()
            await assert_notified(user, "Using Launchpad results directory", 30)
    
            # Step 5: Trigger Download
            await user.should_see(marker="DIALOG_BUTTON_DOWNLOAD_RUN")
            download_run_button: ui.button = user.find(marker="DIALOG_BUTTON_DOWNLOAD_RUN").elements.pop()
            assert download_run_button.enabled, "Download button should be enabled before downloading"
            user.find(marker="DIALOG_BUTTON_DOWNLOAD_RUN").click()
            await assert_notified(user, "Downloading ...", 30)
    
            # Step 6: Check download completes, QuPath project created, and QuPath launched
            await assert_notified(user, "Download and QuPath project creation completed.", 60 * 5)
            print_directory_structure(tmp_path, "execute")
    
            # Check for directory layout as expected
            run_dir = tmp_path / run.run_id
            assert run_dir.is_dir(), f"Expected run directory {run_dir} not found"
    
            subdirs = [d for d in run_dir.iterdir() if d.is_dir()]
            assert len(subdirs) == 3, f"Expected three subdirectories in {run_dir}, but found {len(subdirs)}"
    
            input_dir = run_dir / "input"
            assert input_dir.is_dir(), f"Expected input directory {input_dir} not found"
    
            results_dir = run_dir / SPOT_0_FILENAME.replace(".tiff", "")
            assert results_dir.is_dir(), f"Expected run results directory {results_dir} not found"
    
            qupath_dir = run_dir / "qupath"
            assert qupath_dir.is_dir(), f"Expected QuPath directory {qupath_dir} not found"
    
            # Check for input file having been downloaded
            input_file = input_dir / SPOT_0_FILENAME
            assert input_file.exists(), f"Expected input file {input_file} not found"
            assert input_file.stat().st_size == SPOT_0_FILESIZE, (
                f"Expected input file size {SPOT_0_FILESIZE}, but got {input_file.stat().st_size}"
            )
    
            # Check for files in the results directory
            files_in_results_dir = list(results_dir.glob("*"))
            expected_count = len(SPOT_0_EXPECTED_RESULT_FILES)
>           assert len(files_in_results_dir) == expected_count, (
                f"Expected {expected_count} files in {results_dir}, but found {len(files_in_results_dir)}: "
                f"{[f.name for f in files_in_results_dir]}"
            )
E           AssertionError: Expected 12 files in .../pytest-of-runner/pytest-21/test_gui_run_qupath_install_to0/b197ab65-0be1-488c-ad2e-68ab1b6b2603/8fafc17d-a5cc-4e9d-a982-030b1486ca88, but found 14: ['cell_classification_geojson_polygons.json', 'cell_classification_parquet_polygons.parquet', 'tissue_qc_csv_class_information.csv', 'readout_generation_slide_readouts.csv', 'tissue_segmentation_segmentation_map_image.tiff', 'tissue_segmentation_geojson_polygons.json', 'readout_generation_cell_readouts.csv', 'tissue_segmentation_csv_class_information.csv', 'tissue_qc_geojson_polygons.json', 'tissue_qc_parquet_polygons.parquet', 'tissue_segmentation_parquet_polygons.parquet', 'cell_detection_parquet_centers.parquet', 'cell_detection_parquet_polygons.parquet', 'tissue_qc_segmentation_map_image.tiff']
E           assert 14 == 12
E            +  where 14 = len([PosixPath('.../pytest-of-runner/pytest-21/test_gui_run_qupath_install_to0/b197ab65-0be1-488c-ad2e-68ab1b6b2603/8fafc17d-a5cc-4e9d-a982-030b1486ca88/cell_classification_geojson_polygons.json'), PosixPath('.../pytest-of-runner/pytest-21/test_gui_run_qupath_install_to0/b197ab65-0be1-488c-ad2e-68ab1b6b2603/8fafc17d-a5cc-4e9d-a982-030b1486ca88/cell_classification_parquet_polygons.parquet'), PosixPath('.../pytest-of-runner/pytest-21/test_gui_run_qupath_install_to0/b197ab65-0be1-488c-ad2e-68ab1b6b2603/8fafc17d-a5cc-4e9d-a982-030b1486ca88/tissue_qc_csv_class_information.csv'), PosixPath('.../pytest-of-runner/pytest-21/test_gui_run_qupath_install_to0/b197ab65-0be1-488c-ad2e-68ab1b6b2603/8fafc17d-a5cc-4e9d-a982-030b1486ca88/readout_generation_slide_readouts.csv'), PosixPath('.../pytest-of-runner/pytest-21/test_gui_run_qupath_install_to0/b197ab65-0be1-488c-ad2e-68ab1b6b2603/8fafc17d-a5cc-4e9d-a982-030b1486ca88/tissue_segmentation_segmentation_map_image.tiff'), PosixPath('.../pytest-of-runner/pytest-21/test_gui_run_qupath_install_to0/b197ab65-0be1-488c-ad2e-68ab1b6b2603/8fafc17d-a5cc-4e9d-a982-030b1486ca88/tissue_segmentation_geojson_polygons.json'), ...])

.../aignostics/qupath/gui_test.py:261: AssertionError

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@aig-hannes
Copy link
Copy Markdown
Contributor Author

Failing tests are unrelated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants