Files
photocraft/scripts/test-ci-gpu-lavapipe.py
2ff8f419cb ci: run the GPU tests on lavapipe on Linux and fail if they skip (#7975)
The Linux runner has no GPU, so the GPU tests ran on Mesa llvmpipe over
GL, which can't render Rgba32Float: 57 GPU checks (50 GPU parity, 3
canvas, 2 adjustment preview parity, 2 effect-map recovery) returned
early and passed without comparing anything. A new step after Test
installs mesa-vulkan-drivers and runs the nextest `gpu` group on
lavapipe (Vulkan), reusing Test's build, and fails unless the parity
tests report the Vulkan backend and no test printed a skip.

No code change: photocraft's tests take whatever adapter wgpu returns,
software adapters included. Follows the CI half of lightcraft#1148.

Co-authored-by: FredApps <FredApps@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:44:13 +01:00

45 lines
2.1 KiB
Python

import importlib.util
from pathlib import Path
import unittest
spec = importlib.util.spec_from_file_location('gpu_check', Path(__file__).with_name('ci-gpu-lavapipe.py'))
check = importlib.util.module_from_spec(spec)
spec.loader.exec_module(check)
class LogChecks(unittest.TestCase):
def test_requires_vulkan_evidence(self):
self.assertTrue(check.validate_log(['GPU parity backend: Gl']))
self.assertTrue(check.validate_log([]))
def test_success_and_nextest_summary(self):
self.assertFalse(check.validate_log(['GPU parity backend: Vulkan (llvmpipe, Cpu)',
'Summary 100 tests run: 100 passed, 3 skipped']))
def test_rejects_missing_comparisons(self):
for message in ['skipping GPU parity tests: no device', 'skipping: unsupported format',
'no GPU adapter', 'SKIP gpu timing: no adapter',
'SKIP gpu timing: no device with timestamp queries', 'SKIP unknown test']:
with self.subTest(message=message):
self.assertTrue(check.validate_log(['GPU parity backend: Vulkan', message]))
def test_allows_only_known_timing_exceptions(self):
self.assertFalse(check.validate_log(['GPU parity backend: Vulkan',
'SKIP gpu timing: llvmpipe is a software adapter, which cannot show a GPU/CPU split',
'SKIP the comparison: this GPU finishes a 6 MP composite in 1 ms against 2 ms of encoding',
'SKIP the sum: this refresh still fit one command buffer']))
def test_selects_all_gpu_filters_from_config(self):
config = {'profile': {'default': {'overrides': [
{'filter': 'package(a)', 'test-group': 'gpu'},
{'filter': 'package(b)', 'test-group': 'cpu'},
{'filter': 'test(c)', 'test-group': 'gpu'}]}}}
self.assertEqual(check.gpu_filter(config), '(package(a)) | (test(c))')
config['profile']['default']['overrides'] = []
with self.assertRaises(ValueError):
check.gpu_filter(config)
if __name__ == '__main__':
unittest.main()