Summary
Running the full CTest suite on macOS ARM64 with Qt 6.10.2 and VTK 9.5.2 produces 14 test failures out of 255 tests. These failures are reproducible on a clean build of the master branch at commit 8bc88e2a.
Computational Environment
| Component |
Version |
| OS |
macOS 26.3.1 (Darwin 25.3.0) |
| Architecture |
arm64 (Apple Silicon) |
| System Compiler |
Apple Clang 17.0.0 (clang-1700.6.3.2) |
| Build Compiler |
Homebrew LLVM/Clang 22.1.1 |
| Qt |
6.10.2 (Homebrew) |
| VTK |
9.5.2 (built via CTK superbuild) |
| DCMTK |
3.6.8 (built via CTK superbuild) |
| CMake |
3.26.6 |
| Ninja |
1.13.2 |
| Python |
3.12.10 |
Build configuration: CTK superbuild with CTK_ENABLE_Widgets=ON, CTK_LIB_DICOM/Core=ON, CTK_LIB_DICOM/Widgets=ON, CTK_LIB_Visualization/VTK/Widgets=ON, CTK_QT_VERSION=6, BUILD_TESTING=ON.
Test invocation: ctest --test-dir CTK-build --timeout 30 --output-on-failure
Test Failures
1. Qt6 QStateMachine Async Transition Failures (2 tests)
| Test |
Error |
ctkWorkflowWidgetTest1 |
"Incorrect widget visibility - the current step's widgets are invisible" |
ctkWorkflowWidgetTest2 |
"Incorrect widget visibility - the current step's widgets are invisible" |
Suspected cause: Qt6 changed QStateMachine state transitions to be fully asynchronous. The test checks widget visibility immediately after a transition, but the transition hasn't completed yet. The test also logs "addStep - step [Step 1] already associated with a different workflow !" which suggests the workflow setup has a race condition.
Possible fix: Insert QCoreApplication::processEvents() calls or use QSignalSpy to wait for the state machine transition to complete before checking widget visibility.
2. Qt6 QLocale Format Change (1 test)
| Test |
Error |
ctkLanguageComboBoxTest |
Test assertions fail on locale string format |
Suspected cause: Qt6 changed QLocale::name() return format. For example, some locales may return different territory codes or use different formatting conventions than Qt5. The test's expected strings don't match the Qt6 locale format.
Possible fix: Update both the ctkLanguageComboBox implementation and test expectations to handle Qt6's locale naming conventions, potentially using QLocale::languageToString() / QLocale::territoryToString() with version guards.
3. QRunnable GUI Thread Access (1 test)
| Test |
Error |
ctkPathListWidgetWithButtonsTest |
pathList.count() == 0 (expected non-zero) |
Suspected cause: The test uses a QRunnable that adds file paths from a worker thread, but Qt GUI objects (including the path list widget) must only be accessed from the main thread. The pathList.count() check runs before the worker thread's changes propagate to the GUI.
Possible fix: Use QMetaObject::invokeMethod with Qt::QueuedConnection to marshal GUI updates back to the main thread, or use signals/slots across threads.
4. OpenGL/Display-Dependent Failures (1 test)
| Test |
Error |
ctkWidgetsUtilsTestGrabWidget |
Grabbed QGLWidget pixel at (100,100) is ffffffff instead of expected ff000000 |
Suspected cause: QGLWidget grab returns all-white pixels because the OpenGL context is not rendering properly in the test environment (no physical display or GPU compositing). This is a known limitation of headless/CI environments.
Possible fix: Skip this test in environments without a display, or use QOffscreenSurface with a proper OpenGL context for pixel comparison tests.
5. Widget Logic Bug (1 test)
| Test |
Error |
ctkVTKThresholdWidgetTest1 |
setThresholdValues() failed: output is "19 19" instead of expected range (e.g., "11 19") |
Suspected cause: The threshold widget's setThresholdValues() method appears to have a bug where the lower threshold value is not being set correctly — both min and max end up as 19. This may be a pre-existing logic error in the widget implementation unrelated to Qt version.
Possible fix: Debug ctkVTKThresholdWidget::setThresholdValues() to determine why the lower bound is being overwritten.
6. Crosshair Rendering Baseline Mismatch (1 test)
| Test |
Error |
ctkCrosshairLabelTest2 |
"baseline comparison failed when using bulls-eye crosshair (odd size, bullsEye 15, width 1)" |
Suspected cause: The test compares rendered crosshair pixels against a hardcoded baseline. Platform-specific differences in anti-aliasing, subpixel rendering, or QPainter behavior on macOS ARM64 with Qt 6.10.2 cause the rendered output to differ from the expected baseline by enough to fail the comparison.
Possible fix: Either update the baseline images for this platform, increase the comparison tolerance, or make the crosshair rendering more deterministic (e.g., disable anti-aliasing during the test).
7. VTK OpenGL SEGFAULT / SIGTRAP (7 tests)
| Test |
Signal |
Error |
vtkLightBoxRendererManagerTest1 |
SIGTRAP |
"vtkLightBoxRendererManager is NOT initialized" — all operations (ResetCamera, SetActiveCamera, SetImageDataConnection, SetHighlightedById) fail |
ctkVTKVolumePropertyWidgetTest1 |
SEGFAULT |
vtkOpenGLState.cxx:867 WARN: Error glBlendFuncSeparate1 OpenGL errors detected — (1280) Invalid enum |
ctkVTKDiscretizableColorTransferWidgetTest1 |
SEGFAULT |
VTK OpenGL state initialization failure |
ctkVTKMagnifyViewTest2OddOdd |
SEGFAULT |
VTK OpenGL rendering crash |
ctkVTKMagnifyViewTest2EvenEven |
SEGFAULT |
VTK OpenGL rendering crash |
ctkVTKMagnifyViewTest2OddEven |
SEGFAULT |
VTK OpenGL rendering crash |
ctkVTKMagnifyViewTest2EvenOdd |
SEGFAULT |
VTK OpenGL rendering crash |
Suspected cause: All 7 tests require a functional OpenGL context with GPU access. On macOS ARM64, the Metal-backed OpenGL translation layer may not properly initialize in non-interactive (headless) test environments. VTK 9.5.2's OpenGL state management encounters invalid enums or uninitialized renderers, leading to crashes.
The vtkLightBoxRendererManager explicitly reports it is "NOT initialized" before all operations fail, suggesting the VTK render window cannot obtain a valid OpenGL context.
Possible fix:
- Mark these tests as requiring a display (
PROPERTIES LABELS "RequiresDisplay") and skip them in CI/headless environments
- Or use VTK's offscreen rendering (
vtkRenderWindow::SetOffScreenRendering(true)) if supported on the platform
- The
glBlendFuncSeparate "Invalid enum" error specifically suggests a Metal/OpenGL translation issue on macOS — may require VTK upstream fixes
Summary Table
| Category |
Tests |
Root Cause |
| Qt6 QStateMachine |
2 |
Async transitions; test doesn't wait |
| Qt6 QLocale |
1 |
Locale string format change |
| Thread safety |
1 |
GUI access from worker thread |
| OpenGL grab |
1 |
No display context for pixel readback |
| Widget logic |
1 |
Threshold min/max assignment bug |
| Crosshair baseline |
1 |
Platform rendering differences |
| VTK OpenGL |
7 |
No GPU/display; Metal translation issues |
Reproduction
cmake \
-DCTK_QT_VERSION:STRING=6 \
-DCTK_ENABLE_Widgets:BOOL=ON \
-DCTK_LIB_DICOM/Core:BOOL=ON \
-DCTK_LIB_DICOM/Widgets:BOOL=ON \
-DCTK_LIB_Visualization/VTK/Widgets:BOOL=ON \
-B CTK-build -S .
cmake --build CTK-build -j8
ctest --test-dir CTK-build --timeout 30 --output-on-failure
🤖 Generated with Claude Code
Summary
Running the full CTest suite on macOS ARM64 with Qt 6.10.2 and VTK 9.5.2 produces 14 test failures out of 255 tests. These failures are reproducible on a clean build of the
masterbranch at commit8bc88e2a.Computational Environment
Build configuration: CTK superbuild with
CTK_ENABLE_Widgets=ON,CTK_LIB_DICOM/Core=ON,CTK_LIB_DICOM/Widgets=ON,CTK_LIB_Visualization/VTK/Widgets=ON,CTK_QT_VERSION=6,BUILD_TESTING=ON.Test invocation:
ctest --test-dir CTK-build --timeout 30 --output-on-failureTest Failures
1. Qt6 QStateMachine Async Transition Failures (2 tests)
ctkWorkflowWidgetTest1ctkWorkflowWidgetTest2Suspected cause: Qt6 changed
QStateMachinestate transitions to be fully asynchronous. The test checks widget visibility immediately after a transition, but the transition hasn't completed yet. The test also logs"addStep - step [Step 1] already associated with a different workflow !"which suggests the workflow setup has a race condition.Possible fix: Insert
QCoreApplication::processEvents()calls or useQSignalSpyto wait for the state machine transition to complete before checking widget visibility.2. Qt6 QLocale Format Change (1 test)
ctkLanguageComboBoxTestSuspected cause: Qt6 changed
QLocale::name()return format. For example, some locales may return different territory codes or use different formatting conventions than Qt5. The test's expected strings don't match the Qt6 locale format.Possible fix: Update both the
ctkLanguageComboBoximplementation and test expectations to handle Qt6's locale naming conventions, potentially usingQLocale::languageToString()/QLocale::territoryToString()with version guards.3. QRunnable GUI Thread Access (1 test)
ctkPathListWidgetWithButtonsTestpathList.count() == 0(expected non-zero)Suspected cause: The test uses a
QRunnablethat adds file paths from a worker thread, but Qt GUI objects (including the path list widget) must only be accessed from the main thread. ThepathList.count()check runs before the worker thread's changes propagate to the GUI.Possible fix: Use
QMetaObject::invokeMethodwithQt::QueuedConnectionto marshal GUI updates back to the main thread, or use signals/slots across threads.4. OpenGL/Display-Dependent Failures (1 test)
ctkWidgetsUtilsTestGrabWidgetQGLWidgetpixel at (100,100) isffffffffinstead of expectedff000000Suspected cause:
QGLWidgetgrab returns all-white pixels because the OpenGL context is not rendering properly in the test environment (no physical display or GPU compositing). This is a known limitation of headless/CI environments.Possible fix: Skip this test in environments without a display, or use
QOffscreenSurfacewith a proper OpenGL context for pixel comparison tests.5. Widget Logic Bug (1 test)
ctkVTKThresholdWidgetTest1setThresholdValues()failed: output is"19 19"instead of expected range (e.g.,"11 19")Suspected cause: The threshold widget's
setThresholdValues()method appears to have a bug where the lower threshold value is not being set correctly — both min and max end up as 19. This may be a pre-existing logic error in the widget implementation unrelated to Qt version.Possible fix: Debug
ctkVTKThresholdWidget::setThresholdValues()to determine why the lower bound is being overwritten.6. Crosshair Rendering Baseline Mismatch (1 test)
ctkCrosshairLabelTest2Suspected cause: The test compares rendered crosshair pixels against a hardcoded baseline. Platform-specific differences in anti-aliasing, subpixel rendering, or QPainter behavior on macOS ARM64 with Qt 6.10.2 cause the rendered output to differ from the expected baseline by enough to fail the comparison.
Possible fix: Either update the baseline images for this platform, increase the comparison tolerance, or make the crosshair rendering more deterministic (e.g., disable anti-aliasing during the test).
7. VTK OpenGL SEGFAULT / SIGTRAP (7 tests)
vtkLightBoxRendererManagerTest1ctkVTKVolumePropertyWidgetTest1vtkOpenGLState.cxx:867 WARN: Error glBlendFuncSeparate1 OpenGL errors detected — (1280) Invalid enumctkVTKDiscretizableColorTransferWidgetTest1ctkVTKMagnifyViewTest2OddOddctkVTKMagnifyViewTest2EvenEvenctkVTKMagnifyViewTest2OddEvenctkVTKMagnifyViewTest2EvenOddSuspected cause: All 7 tests require a functional OpenGL context with GPU access. On macOS ARM64, the Metal-backed OpenGL translation layer may not properly initialize in non-interactive (headless) test environments. VTK 9.5.2's OpenGL state management encounters invalid enums or uninitialized renderers, leading to crashes.
The
vtkLightBoxRendererManagerexplicitly reports it is "NOT initialized" before all operations fail, suggesting the VTK render window cannot obtain a valid OpenGL context.Possible fix:
PROPERTIES LABELS "RequiresDisplay") and skip them in CI/headless environmentsvtkRenderWindow::SetOffScreenRendering(true)) if supported on the platformglBlendFuncSeparate"Invalid enum" error specifically suggests a Metal/OpenGL translation issue on macOS — may require VTK upstream fixesSummary Table
Reproduction
cmake \ -DCTK_QT_VERSION:STRING=6 \ -DCTK_ENABLE_Widgets:BOOL=ON \ -DCTK_LIB_DICOM/Core:BOOL=ON \ -DCTK_LIB_DICOM/Widgets:BOOL=ON \ -DCTK_LIB_Visualization/VTK/Widgets:BOOL=ON \ -B CTK-build -S . cmake --build CTK-build -j8 ctest --test-dir CTK-build --timeout 30 --output-on-failure🤖 Generated with Claude Code