AlmaLinux changes: Enable vc4 and v3d for Raspberry Pi graphics in AlmaLinux (Resolves: https://github.com/AlmaLinux/raspberry-pi/issues/32)
Add LLVM 21 support for gallivm (riscv64)
This commit is contained in:
commit
2faec6499e
1
.fmf/version
Normal file
1
.fmf/version
Normal file
@ -0,0 +1 @@
|
||||
1
|
||||
@ -4,3 +4,4 @@ product_versions:
|
||||
decision_context: osci_compose_gate
|
||||
rules:
|
||||
- !PassingTestCaseRule {test_case_name: desktop-qe.desktop-ci.tier1-gating.functional}
|
||||
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}
|
||||
|
||||
108
plan.fmf
Normal file
108
plan.fmf
Normal file
@ -0,0 +1,108 @@
|
||||
/plan-graphics-sanity-test:
|
||||
summary: Graphics stack smoke test plan
|
||||
discover:
|
||||
how: fmf
|
||||
provision:
|
||||
how: local
|
||||
prepare:
|
||||
how: shell
|
||||
script: |
|
||||
set -x # Enable verbose logging
|
||||
echo "========================================"
|
||||
echo "Installing desktop environment and graphics dependencies"
|
||||
echo "Architecture: $(uname -m)"
|
||||
echo "OS: $(cat /etc/redhat-release)"
|
||||
echo "========================================"
|
||||
|
||||
# Install full GNOME desktop environment (minimal)
|
||||
echo "Step 1: Installing GNOME desktop environment..."
|
||||
dnf groupinstall -y "Server with GUI" || \
|
||||
dnf groupinstall -y "GNOME Desktop" || \
|
||||
dnf install -y @gnome-desktop
|
||||
|
||||
# Install Wayland session specifically
|
||||
echo "Step 2: Installing Wayland session components..."
|
||||
dnf install -y \
|
||||
gnome-session-wayland-session \
|
||||
gnome-shell \
|
||||
mutter \
|
||||
xorg-x11-server-Xwayland
|
||||
|
||||
# Install graphics stack dependencies
|
||||
echo "Step 3: Installing graphics stack dependencies..."
|
||||
dnf install -y \
|
||||
mesa-dri-drivers \
|
||||
mesa-libGL \
|
||||
mesa-libEGL \
|
||||
mesa-libGLES \
|
||||
mesa-vulkan-drivers \
|
||||
gtk3 \
|
||||
gtk4 \
|
||||
xwayland-run \
|
||||
mesa-demos \
|
||||
python3-gobject \
|
||||
glx-utils
|
||||
|
||||
# Install optional packages
|
||||
echo "Step 4: Installing optional packages..."
|
||||
dnf install -y gtk3-devel gtk4-devel xterm glxgears || true
|
||||
|
||||
# Verify key components
|
||||
echo "Step 5: Verifying installation..."
|
||||
echo " mutter: $(which mutter || echo 'NOT FOUND')"
|
||||
echo " xwfb-run: $(which xwfb-run || echo 'NOT FOUND')"
|
||||
echo " glxinfo: $(which glxinfo || echo 'NOT FOUND')"
|
||||
echo " Software renderer: $(ls /usr/lib64/dri/swrast_dri.so 2>/dev/null || echo 'NOT FOUND')"
|
||||
|
||||
echo "========================================"
|
||||
echo "Installation complete"
|
||||
echo "========================================"
|
||||
execute:
|
||||
how: tmt
|
||||
|
||||
/tests:
|
||||
/infrastructure-test:
|
||||
summary: Graphics infrastructure test (Phases 1-3)
|
||||
description: |
|
||||
Validates graphics stack infrastructure:
|
||||
- Phase 1: System info and prerequisites
|
||||
- Phase 2: Library initialization (Mesa, GTK)
|
||||
- Phase 3: Headless compositor and GL context
|
||||
|
||||
This test verifies that the graphics stack is properly set up
|
||||
before running actual rendering tests.
|
||||
test: SKIP_INSTALL=1 ./tests/graphics-smoke-test-tmt.sh --phase=1-3
|
||||
tty: true
|
||||
order: 10
|
||||
duration: 4m
|
||||
contact:
|
||||
- Peter Kopec <pekopec@redhat.com>
|
||||
component:
|
||||
- mesa
|
||||
- gtk3
|
||||
- mutter
|
||||
- xwayland
|
||||
|
||||
/rendering-test:
|
||||
summary: Graphics rendering verification (Phase 4)
|
||||
description: |
|
||||
Validates actual graphics rendering with visual verification:
|
||||
- GTK3/GTK4 application startup
|
||||
- GTK4 rendering test with default renderer
|
||||
- GTK4 rendering test with NGL renderer
|
||||
- Visual verification via PNG color analysis
|
||||
- glxgears FPS test
|
||||
|
||||
Detects the s390x Mesa 25.2.7-3 black screen bug where
|
||||
GTK4 apps show black windows with default renderer but
|
||||
work correctly with GSK_RENDERER=ngl.
|
||||
test: SKIP_INSTALL=1 ./tests/graphics-smoke-test-tmt.sh --phase=4
|
||||
tty: true
|
||||
order: 20
|
||||
duration: 8m
|
||||
contact:
|
||||
- Peter Kopec <pekopec@redhat.com>
|
||||
component:
|
||||
- mesa
|
||||
- gtk4
|
||||
- mutter
|
||||
321
tests/README.md
Normal file
321
tests/README.md
Normal file
@ -0,0 +1,321 @@
|
||||
# Universal Mesa Graphics Smoke Test
|
||||
|
||||
Multi-architecture headless graphics stack testing for Mesa, GTK3/GTK4, and the GNOME compositor.
|
||||
|
||||
## Overview
|
||||
|
||||
This test suite validates the graphics stack functionality across **4 CPU architectures**:
|
||||
- **x86_64** (Intel/AMD)
|
||||
- **aarch64** (ARM 64-bit)
|
||||
- **ppc64le** (PowerPC Little-Endian)
|
||||
- **s390x** (IBM Z System)
|
||||
|
||||
The tests run entirely **headless** (no physical display required) using `xwfb-run` (Xwayland framebuffer) for testing on bare metal, VMs, or CI infrastructure.
|
||||
|
||||
## What It Tests
|
||||
|
||||
### Phase 1: System Information & Prerequisites
|
||||
- Architecture and kernel information
|
||||
- CPU, memory, and hardware details
|
||||
- Required package installation verification:
|
||||
- `mesa-dri-drivers`
|
||||
- `gtk3`, `gtk4`
|
||||
- `mutter` (Wayland compositor)
|
||||
- `xwayland-run` (headless testing framework)
|
||||
- Mesa GL/EGL/Vulkan drivers
|
||||
|
||||
### Phase 2: Graphics Library Initialization
|
||||
- Mesa GL library loading (`libGL.so.1`)
|
||||
- GTK3/GTK4 Python bindings import test
|
||||
- Software renderer availability check (llvmpipe/swrast)
|
||||
|
||||
### Phase 3: Headless Graphics Stack
|
||||
- Wayland compositor startup (`xwfb-run`)
|
||||
- X11/Xwayland compatibility layer
|
||||
- OpenGL context creation
|
||||
- Renderer detection (`glxinfo`)
|
||||
- Reports vendor, renderer, and GL version
|
||||
|
||||
### Phase 4: Application Rendering Tests
|
||||
- **GTK3 Demo**: Application startup and rendering
|
||||
- `gtk3-demo --list` (enumerate demos)
|
||||
- `gtk3-demo --run=textscroll --autoquit` (actual demo execution)
|
||||
|
||||
- **GTK4 Demo**: Application startup and rendering
|
||||
- `gtk4-demo --list` (enumerate demos)
|
||||
- `gtk4-demo --run=textscroll --autoquit` (actual demo execution)
|
||||
|
||||
- **GTK4 Visual Verification** (detects rendering bugs):
|
||||
- Renders colored shapes (red, green, blue rectangles + yellow circle)
|
||||
- Saves PNG screenshot
|
||||
- Analyzes color diversity to detect black screen bug
|
||||
- Tests **both** default renderer and NGL renderer
|
||||
|
||||
- **glxgears**: OpenGL performance test
|
||||
- Runs for 25 seconds
|
||||
- Verifies FPS output and GL rendering
|
||||
|
||||
## Known Issues Detected
|
||||
|
||||
### s390x Mesa 25.2.7-3 Black Screen Bug
|
||||
**Symptom**: GTK4 applications display black windows with the default renderer.
|
||||
|
||||
**Detection**: The visual verification test counts unique colors in the rendered PNG. A properly rendered image has 50+ unique color values; a black screen has <10.
|
||||
|
||||
**Workaround**: Setting `GSK_RENDERER=ngl` forces the NGL (new GL) renderer and fixes the issue.
|
||||
|
||||
This test suite automatically detects this failure and tests the NGL workaround.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
universal_sanity_test/
|
||||
├── main.fmf # TMT test definition (Testing Farm)
|
||||
├── graphics-smoke-test-rhts.sh # Main test script with RHTS reporting
|
||||
├── gtk4_render_test.py # GTK4 visual verification app
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
### Test Framework: TMT (Test Management Tool)
|
||||
|
||||
The `main.fmf` file defines:
|
||||
- **Plan**: `plan-graphics-sanity-test`
|
||||
- Provisioning: `local` (runs on current system)
|
||||
- Preparation: Installs GNOME desktop and graphics dependencies
|
||||
- Execution: TMT test runner
|
||||
|
||||
- **Test 1**: `infrastructure-test` (Phases 1-3)
|
||||
- Duration: 4 minutes
|
||||
- Order: 10 (runs first)
|
||||
- Tags: `CI-Tier-1`, `graphics`, `infrastructure`, `multiarch`
|
||||
|
||||
- **Test 2**: `rendering-test` (Phase 4)
|
||||
- Duration: 8 minutes
|
||||
- Order: 20 (runs second)
|
||||
- Tags: `CI-Tier-1`, `graphics`, `rendering`, `visual-verification`, `multiarch`
|
||||
|
||||
### RHTS Reporting
|
||||
|
||||
All test results are reported via `tmt-report-result` for integration with:
|
||||
- Testing Farm
|
||||
- RHEL Testing Infrastructure
|
||||
- CI/CD pipelines
|
||||
|
||||
Each test reports one of:
|
||||
- **PASS**: Test succeeded
|
||||
- **FAIL**: Critical test failed
|
||||
- **WARN**: Optional test failed (doesn't affect overall result)
|
||||
- **SKIP**: Test was skipped (dependency not available)
|
||||
|
||||
## Usage
|
||||
|
||||
### Run All Tests (Recommended)
|
||||
```bash
|
||||
./graphics-smoke-test-rhts.sh
|
||||
```
|
||||
|
||||
### Run Only Infrastructure Tests (Phases 1-3)
|
||||
```bash
|
||||
./graphics-smoke-test-rhts.sh --phase=1-3
|
||||
```
|
||||
|
||||
### Run Only Rendering Tests (Phase 4)
|
||||
```bash
|
||||
./graphics-smoke-test-rhts.sh --phase=4
|
||||
```
|
||||
|
||||
### Run with TMT (Testing Farm)
|
||||
```bash
|
||||
tmt run --all
|
||||
```
|
||||
|
||||
### Run Specific TMT Test
|
||||
```bash
|
||||
# Infrastructure only
|
||||
tmt run test --name /tests/infrastructure-test
|
||||
|
||||
# Rendering only
|
||||
tmt run test --name /tests/rendering-test
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
### System Requirements
|
||||
- RHEL 9+, Fedora 35+, or CentOS Stream 9+
|
||||
- Supported architectures: x86_64, aarch64, ppc64le, s390x
|
||||
- No physical display required (fully headless)
|
||||
|
||||
### Required Packages
|
||||
The test automatically installs these if missing:
|
||||
- `mesa-dri-drivers` - Mesa DRI drivers (required)
|
||||
- `mesa-libGL`, `mesa-libEGL`, `mesa-libGLES` - Mesa GL libraries
|
||||
- `mesa-vulkan-drivers` - Mesa Vulkan support
|
||||
- `gtk3`, `gtk4` - GTK widget toolkit
|
||||
- `xwayland-run` - Headless X server wrapper
|
||||
- `mutter` - GNOME Wayland compositor
|
||||
- `gnome-session-wayland-session` - Wayland session components
|
||||
- `mesa-demos` - GL utilities (glxinfo, glxgears)
|
||||
- `python3-gobject` - Python GTK bindings
|
||||
|
||||
### Optional Packages
|
||||
- `gtk3-devel`, `gtk4-devel` - Development tools
|
||||
- `glx-utils` - GLX utilities
|
||||
- `xterm` - Terminal emulator
|
||||
|
||||
## Output
|
||||
|
||||
### Logs Directory
|
||||
All logs are saved to: `/tmp/graphics-test-logs/`
|
||||
|
||||
Key files:
|
||||
- `00-master-test.log` - Complete test output
|
||||
- `prereq_system-check.log` - System information and prerequisites
|
||||
- `app_gtk4-render-test-default.log` - GTK4 default renderer test
|
||||
- `gtk4_render_test_default.png` - Visual verification screenshot
|
||||
- `gtk4_render_test_ngl.png` - NGL renderer screenshot
|
||||
|
||||
### Test Results Summary
|
||||
The script outputs:
|
||||
- Individual test results (PASS/FAIL/WARN/SKIP)
|
||||
- OpenGL renderer information
|
||||
- List of generated logs and screenshots
|
||||
- Overall result: PASS or FAIL
|
||||
|
||||
### RHTS Artifacts
|
||||
The following artifacts are submitted to Testing Farm:
|
||||
- Master log file
|
||||
- All PNG screenshots (visual evidence)
|
||||
- Failed test logs (for debugging)
|
||||
|
||||
## Customization
|
||||
|
||||
### Environment Variables
|
||||
```bash
|
||||
# Set custom log directory
|
||||
LOGDIR=/var/log/graphics-test ./graphics-smoke-test-rhts.sh
|
||||
|
||||
# Disable verbose logging
|
||||
VERBOSE=0 ./graphics-smoke-test-rhts.sh
|
||||
|
||||
# Force specific GTK renderer
|
||||
GSK_RENDERER=ngl ./graphics-smoke-test-rhts.sh --phase=4
|
||||
```
|
||||
|
||||
### Manual GTK4 Render Test
|
||||
```bash
|
||||
# Test with default renderer
|
||||
xwfb-run -w 2 -- python3 gtk4_render_test.py output.png
|
||||
|
||||
# Test with NGL renderer
|
||||
xwfb-run -w 2 -- python3 gtk4_render_test.py output_ngl.png --renderer=ngl
|
||||
|
||||
# Test with other renderers
|
||||
xwfb-run -w 2 -- python3 gtk4_render_test.py output_cairo.png --renderer=cairo
|
||||
xwfb-run -w 2 -- python3 gtk4_render_test.py output_vulkan.png --renderer=vulkan
|
||||
```
|
||||
|
||||
## Exit Codes
|
||||
|
||||
- `0` - All critical tests passed
|
||||
- `1` - One or more critical tests failed
|
||||
|
||||
## Integration Examples
|
||||
|
||||
### CI/CD Pipeline (.gitlab-ci.yml)
|
||||
```yaml
|
||||
graphics-test:
|
||||
stage: test
|
||||
script:
|
||||
- cd universal_sanity_test
|
||||
- ./graphics-smoke-test-rhts.sh
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- /tmp/graphics-test-logs/
|
||||
expire_in: 7 days
|
||||
tags:
|
||||
- multiarch
|
||||
```
|
||||
|
||||
### Testing Farm
|
||||
```yaml
|
||||
plans:
|
||||
- name: graphics-smoke-test
|
||||
discover:
|
||||
how: fmf
|
||||
execute:
|
||||
how: tmt
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Tests Fail to Start
|
||||
**Problem**: Missing dependencies
|
||||
|
||||
**Solution**: The script auto-installs packages, but you can pre-install:
|
||||
```bash
|
||||
dnf install -y mesa-dri-drivers gtk4 mutter xwayland-run
|
||||
```
|
||||
|
||||
### Black Screen Detected (s390x)
|
||||
**Problem**: GTK4 apps show black windows
|
||||
|
||||
**Solution**: This is a known Mesa bug on s390x. Use NGL renderer:
|
||||
```bash
|
||||
GSK_RENDERER=ngl gtk4-app
|
||||
```
|
||||
|
||||
### glxgears Timeout
|
||||
**Problem**: `glxgears` test times out or shows no FPS
|
||||
|
||||
**Solution**: Check renderer:
|
||||
```bash
|
||||
xwfb-run -w 2 -- glxinfo | grep -i renderer
|
||||
```
|
||||
Ensure software renderer (llvmpipe/swrast) is available.
|
||||
|
||||
### xwfb-run Not Found
|
||||
**Problem**: `xwayland-run` package not installed
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
dnf install -y xwayland-run
|
||||
```
|
||||
|
||||
## Development & Contributions
|
||||
|
||||
### Test Structure
|
||||
Each test uses the `run_test()` wrapper:
|
||||
```bash
|
||||
run_test "test-name" \
|
||||
"command to execute" \
|
||||
"yes|no (critical)"
|
||||
```
|
||||
|
||||
### Adding New Tests
|
||||
1. Add test to appropriate phase function in `graphics-smoke-test-rhts.sh`
|
||||
2. Use `run_test()` for automatic RHTS reporting
|
||||
3. Update this README with test description
|
||||
|
||||
### Color Coding
|
||||
- Blue: Section headers
|
||||
- Green: Pass
|
||||
- Yellow: Warning (non-critical failure)
|
||||
- Red: Fail (critical failure)
|
||||
|
||||
## License
|
||||
|
||||
Testing infrastructure for Mesa and GNOME graphics stack.
|
||||
|
||||
## Contact
|
||||
|
||||
- **Maintainer**: Peter Kopec pekopec@redhat.com
|
||||
- **Components Tested**: mesa, gtk3, gtk4, mutter, xwayland
|
||||
- **Tags**: CI-Tier-1, graphics, multiarch, infrastructure, rendering
|
||||
|
||||
## See Also
|
||||
|
||||
- [TMT Documentation](https://tmt.readthedocs.io/)
|
||||
- [Mesa Project](https://www.mesa3d.org/)
|
||||
- [GTK Documentation](https://www.gtk.org/)
|
||||
- [GNOME Mutter](https://gitlab.gnome.org/GNOME/mutter)
|
||||
794
tests/graphics-smoke-test-tmt.sh
Executable file
794
tests/graphics-smoke-test-tmt.sh
Executable file
@ -0,0 +1,794 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Cross-Architecture Graphics Smoke Test with TMT Reporting
|
||||
# Works on: x86_64, aarch64, ppc64le, s390x
|
||||
# OS: RHEL 9+, Fedora 35+
|
||||
#
|
||||
# Designed for Testing Farm / TMT environment
|
||||
# Reports each test result using tmt-report-result
|
||||
#
|
||||
|
||||
#set -e
|
||||
set -x # Enable verbose mode - show all commands
|
||||
|
||||
# =============================================================================
|
||||
# Configuration
|
||||
# =============================================================================
|
||||
TEST_TIMEOUT=30
|
||||
LOGDIR=${LOGDIR:-/tmp/graphics-test-logs}
|
||||
OVERALL_RESULT="PASS"
|
||||
VERBOSE=${VERBOSE:-1} # Verbose logging enabled by default
|
||||
|
||||
# Create log directory
|
||||
mkdir -p "$LOGDIR"
|
||||
|
||||
# Log everything to a master log file
|
||||
exec > >(tee -a "$LOGDIR/00-master-test.log") 2>&1
|
||||
|
||||
# Color output (disabled if not a terminal)
|
||||
if [ -t 1 ]; then
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
else
|
||||
RED=''
|
||||
GREEN=''
|
||||
YELLOW=''
|
||||
BLUE=''
|
||||
NC=''
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# Helper Functions
|
||||
# =============================================================================
|
||||
|
||||
# TMT reporting helper
|
||||
tmt_report() {
|
||||
local test_name="$1"
|
||||
local result="$2" # PASS/FAIL/WARN/SKIP
|
||||
local logfile="$3"
|
||||
|
||||
echo -e "${BLUE}[TMT]${NC} Reporting: $test_name = $result"
|
||||
|
||||
if command -v tmt-report-result >/dev/null 2>&1; then
|
||||
tmt-report-result -o "$logfile" "$test_name" "$result"
|
||||
else
|
||||
# Fallback when not in TMT environment
|
||||
echo "TMT_REPORT: $test_name $result $logfile"
|
||||
fi
|
||||
|
||||
# Track overall failure (SKIP doesn't affect overall result)
|
||||
if [ "$result" == "FAIL" ]; then
|
||||
OVERALL_RESULT="FAIL"
|
||||
fi
|
||||
}
|
||||
|
||||
# TMT log submission helper (for screenshots, images, etc.)
|
||||
tmt_submit() {
|
||||
local file="$1"
|
||||
local description="${2:-$(basename $file)}"
|
||||
|
||||
if [ ! -f "$file" ]; then
|
||||
echo -e "${YELLOW}[TMT]${NC} Skip submit: $file (not found)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}[TMT]${NC} Submitting: $description"
|
||||
|
||||
if command -v tmt-file-submit >/dev/null 2>&1; then
|
||||
tmt-file-submit -l "$file"
|
||||
else
|
||||
# Fallback when not in TMT environment
|
||||
echo "TMT_SUBMIT: $file ($description)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Test execution wrapper
|
||||
run_test() {
|
||||
local test_name="$1"
|
||||
local test_cmd="$2"
|
||||
local critical="${3:-yes}" # yes/no
|
||||
local logfile="$LOGDIR/${test_name//\//_}" # Replace / with _
|
||||
logfile="${logfile//[: ]/_}.log" # Replace : and space with _
|
||||
|
||||
echo "========================================"
|
||||
echo "Running: $test_name"
|
||||
echo "Command: $test_cmd"
|
||||
echo "Log: $logfile"
|
||||
echo -n "Result: "
|
||||
|
||||
if eval "$test_cmd" >"$logfile" 2>&1; then
|
||||
echo -e "${GREEN}PASS${NC}"
|
||||
|
||||
# Show last few lines of output if verbose
|
||||
if [ "$VERBOSE" == "1" ] && [ -s "$logfile" ]; then
|
||||
echo " Last output lines:"
|
||||
tail -5 "$logfile" | sed 's/^/ /'
|
||||
fi
|
||||
tmt_report "$test_name" "PASS" "$logfile"
|
||||
return 0
|
||||
else
|
||||
local exit_code=$?
|
||||
echo $exit_code >> "$logfile"
|
||||
if [ "$critical" == "yes" ]; then
|
||||
echo -e "${RED}FAIL${NC} (exit code: $exit_code)"
|
||||
|
||||
# Always show failure details
|
||||
echo " Error details:"
|
||||
tail -20 "$logfile" | sed 's/^/ /'
|
||||
|
||||
tmt_report "$test_name" "FAIL" "$logfile"
|
||||
return 1
|
||||
else
|
||||
echo -e "${YELLOW}WARN${NC} (optional, exit code: $exit_code)"
|
||||
|
||||
# Show warning details if verbose
|
||||
if [ "$VERBOSE" == "1" ] && [ -s "$logfile" ]; then
|
||||
echo " Warning details:"
|
||||
tail -10 "$logfile" | sed 's/^/ /'
|
||||
fi
|
||||
|
||||
tmt_report "$test_name" "WARN" "$logfile"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# Dependency Installation
|
||||
# =============================================================================
|
||||
|
||||
install_dependencies() {
|
||||
local logfile="$LOGDIR/00-install-dependencies.log"
|
||||
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE} Installing Dependencies${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
|
||||
# Required packages
|
||||
local required_packages=(
|
||||
mesa-dri-drivers
|
||||
mesa-libGL
|
||||
mesa-libEGL
|
||||
gtk3
|
||||
gtk4
|
||||
xwayland-run
|
||||
mutter
|
||||
mesa-demos
|
||||
python3-gobject
|
||||
)
|
||||
|
||||
# Optional packages
|
||||
local optional_packages=(
|
||||
gtk3-devel
|
||||
gtk4-devel
|
||||
gtk4-devel-tools
|
||||
xterm
|
||||
)
|
||||
|
||||
echo "Installing required packages..." | tee "$logfile"
|
||||
|
||||
if command -v dnf &>/dev/null; then
|
||||
# Install required packages
|
||||
if dnf install -y "${required_packages[@]}" >>"$logfile" 2>&1; then
|
||||
echo -e "${GREEN}✓${NC} Required packages installed"
|
||||
tmt_report "install-dependencies" "PASS" "$logfile"
|
||||
else
|
||||
echo -e "${RED}✗${NC} Failed to install required packages"
|
||||
tmt_report "install-dependencies" "FAIL" "$logfile"
|
||||
echo "Check log: $logfile"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install optional packages (non-fatal)
|
||||
echo "Installing optional packages..." | tee -a "$logfile"
|
||||
for pkg in "${optional_packages[@]}"; do
|
||||
dnf install -y "$pkg" >>"$logfile" 2>&1 || echo " Skipped: $pkg"
|
||||
done
|
||||
tmt_submit "$logfile" "Optional extra dependencies"
|
||||
else
|
||||
echo -e "${RED}✗${NC} dnf package manager not found"
|
||||
tmt_report "install-dependencies" "FAIL" "$logfile"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# Phase Functions
|
||||
# =============================================================================
|
||||
|
||||
run_phases_1_to_3() {
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE} Phases 1-3: Infrastructure Tests${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo "Architecture: $(uname -m)"
|
||||
echo "Kernel: $(uname -r)"
|
||||
echo "OS: $(cat /etc/redhat-release 2>/dev/null || cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2)"
|
||||
echo "Log directory: $LOGDIR"
|
||||
echo "Date: $(date)"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo
|
||||
|
||||
# Environment debugging
|
||||
echo -e "${BLUE}Environment Check:${NC}"
|
||||
echo "Display: ${DISPLAY:-not set}"
|
||||
echo "Wayland: ${WAYLAND_DISPLAY:-not set}"
|
||||
echo "XDG Runtime: ${XDG_RUNTIME_DIR:-not set}"
|
||||
echo "Session type: ${XDG_SESSION_TYPE:-not set}"
|
||||
echo
|
||||
|
||||
# Check what's already available
|
||||
echo -e "${BLUE}Pre-flight Check:${NC}"
|
||||
echo " mutter: $(which mutter 2>/dev/null || echo 'NOT FOUND')"
|
||||
echo " xwfb-run: $(which xwfb-run 2>/dev/null || echo 'NOT FOUND')"
|
||||
echo " glxinfo: $(which glxinfo 2>/dev/null || echo 'NOT FOUND')"
|
||||
echo " gtk3-demo: $(which gtk3-demo 2>/dev/null || echo 'NOT FOUND')"
|
||||
echo
|
||||
|
||||
# Check DRI drivers
|
||||
echo " DRI drivers:"
|
||||
if [ -d /usr/lib64/dri ]; then
|
||||
ls /usr/lib64/dri/*_dri.so 2>/dev/null | head -5 | sed 's/^/ /' || echo " NONE FOUND"
|
||||
else
|
||||
echo " /usr/lib64/dri NOT FOUND"
|
||||
fi
|
||||
echo
|
||||
|
||||
# Install dependencies first
|
||||
install_dependencies
|
||||
|
||||
# =========================================================================
|
||||
# PHASE 1: System Info & Prerequisites Check
|
||||
# =========================================================================
|
||||
echo -e "${BLUE}Phase 1: System Information & Prerequisites${NC}"
|
||||
echo "========================================"
|
||||
echo "Running: prereq/system-check"
|
||||
|
||||
local prereq_log="$LOGDIR/prereq_system-check.log"
|
||||
echo "Log: $prereq_log"
|
||||
echo -n "Result: "
|
||||
|
||||
# All checks go into one log file (use subshell so exit doesn't kill parent)
|
||||
(
|
||||
echo "========================================="
|
||||
echo "SYSTEM INFORMATION & PREREQUISITES CHECK"
|
||||
echo "========================================="
|
||||
echo "Date: $(date)"
|
||||
echo
|
||||
|
||||
# Hardware & System Info
|
||||
echo "--- Architecture & Kernel ---"
|
||||
uname -a
|
||||
echo "Architecture: $(uname -m)"
|
||||
echo
|
||||
|
||||
echo "--- CPU Information ---"
|
||||
if [ -f /proc/cpuinfo ]; then
|
||||
head -30 /proc/cpuinfo
|
||||
fi
|
||||
echo
|
||||
|
||||
echo "--- Memory Information ---"
|
||||
free -h
|
||||
echo
|
||||
|
||||
echo "--- PCI Devices ---"
|
||||
if command -v lspci >/dev/null 2>&1; then
|
||||
lspci -v
|
||||
echo
|
||||
echo "VGA Devices:"
|
||||
lspci | grep -i vga || echo "No VGA devices found"
|
||||
else
|
||||
echo "lspci not available (expected on s390x)"
|
||||
fi
|
||||
echo
|
||||
|
||||
echo "--- Hardware Details ---"
|
||||
if command -v lshw >/dev/null 2>&1; then
|
||||
lshw -short 2>&1 || echo "lshw failed"
|
||||
else
|
||||
echo "lshw not available"
|
||||
fi
|
||||
echo
|
||||
|
||||
echo "========================================="
|
||||
echo "PREREQUISITE CHECKS"
|
||||
echo "========================================="
|
||||
echo
|
||||
|
||||
# Check critical packages
|
||||
prereq_failed=0
|
||||
|
||||
echo "--- Mesa DRI Drivers ---"
|
||||
if rpm -q mesa-dri-drivers; then
|
||||
echo "✓ PASS"
|
||||
else
|
||||
echo "✗ FAIL - mesa-dri-drivers not installed"
|
||||
prereq_failed=1
|
||||
fi
|
||||
echo
|
||||
|
||||
echo "--- GTK3 ---"
|
||||
if rpm -q gtk3; then
|
||||
echo "✓ PASS"
|
||||
else
|
||||
echo "✗ WARN - gtk3 not installed (optional)"
|
||||
fi
|
||||
echo
|
||||
|
||||
echo "--- GTK4 ---"
|
||||
if rpm -q gtk4; then
|
||||
echo "✓ PASS"
|
||||
else
|
||||
echo "✗ FAIL - gtk4 not installed"
|
||||
prereq_failed=1
|
||||
fi
|
||||
echo
|
||||
|
||||
echo "--- xwfb-run (headless testing) ---"
|
||||
if which xwfb-run; then
|
||||
echo "✓ PASS"
|
||||
else
|
||||
echo "✗ FAIL - xwfb-run not found"
|
||||
prereq_failed=1
|
||||
fi
|
||||
echo
|
||||
|
||||
echo "--- Wayland Compositor ---"
|
||||
if rpm -q mutter >/dev/null 2>&1; then
|
||||
rpm -q mutter
|
||||
echo "✓ PASS - mutter (GNOME) found"
|
||||
elif rpm -q kwin >/dev/null 2>&1; then
|
||||
rpm -q kwin
|
||||
echo "✓ PASS - kwin (KDE) found"
|
||||
elif rpm -q weston >/dev/null 2>&1; then
|
||||
rpm -q weston
|
||||
echo "✓ PASS - weston found"
|
||||
else
|
||||
echo "✗ FAIL - No compositor found (mutter/kwin/weston)"
|
||||
prereq_failed=1
|
||||
fi
|
||||
echo
|
||||
|
||||
echo "--- Mesa/GL/EGL Packages ---"
|
||||
rpm -qa | grep -E 'mesa|libGL|libEGL' | sort || echo "No Mesa packages found"
|
||||
echo
|
||||
|
||||
echo "--- DRI Drivers ---"
|
||||
if [ -d /usr/lib64/dri ]; then
|
||||
ls -lh /usr/lib64/dri/ | grep '_dri.so$' || echo "No DRI drivers found"
|
||||
else
|
||||
echo "/usr/lib64/dri directory not found"
|
||||
fi
|
||||
echo
|
||||
|
||||
echo "========================================="
|
||||
if [ $prereq_failed -eq 0 ]; then
|
||||
echo "RESULT: All prerequisites satisfied"
|
||||
exit 0
|
||||
else
|
||||
echo "RESULT: Missing critical prerequisites"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
) > "$prereq_log" 2>&1
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN}PASS${NC}"
|
||||
tmt_report "prereq/system-check" "PASS" "$prereq_log"
|
||||
else
|
||||
echo -e "${RED}FAIL${NC}"
|
||||
echo " Missing prerequisites - check log for details"
|
||||
tail -20 "$prereq_log" | sed 's/^/ /'
|
||||
tmt_report "prereq/system-check" "FAIL" "$prereq_log"
|
||||
OVERALL_RESULT="FAIL"
|
||||
fi
|
||||
|
||||
# Submit the comprehensive log
|
||||
tmt_submit "$prereq_log" "system-check-full.log"
|
||||
echo
|
||||
|
||||
# =========================================================================
|
||||
# PHASE 2: Library Initialization Tests
|
||||
# =========================================================================
|
||||
echo -e "${BLUE}Phase 2: Graphics Library Initialization${NC}"
|
||||
|
||||
run_test "libinit/mesa-gl" \
|
||||
"timeout 5 bash -c 'LD_PRELOAD=/usr/lib64/libGL.so.1 /bin/true 2>&1'"
|
||||
|
||||
run_test "libinit/gtk3" \
|
||||
"timeout 5 python3 -c 'import gi; gi.require_version(\"Gtk\", \"3.0\"); from gi.repository import Gtk' 2>&1"
|
||||
|
||||
run_test "libinit/gtk4" \
|
||||
"timeout 5 python3 -c 'import gi; gi.require_version(\"Gtk\", \"4.0\"); from gi.repository import Gtk' 2>&1" \
|
||||
"no"
|
||||
|
||||
# Check software rendering
|
||||
ls -l /usr/lib64/ > /tmp/mesa_drivers.txt
|
||||
if [ -f /usr/lib64/dri/swrast_dri.so ] || [ -f /usr/lib64/dri/kms_swrast_dri.so ]; then
|
||||
echo -e " Software renderer: ${GREEN}available${NC} (llvmpipe/swrast)"
|
||||
tmt_report "libinit/swrast-available" "PASS" "/tmp/mesa_drivers.txt"
|
||||
else
|
||||
echo -e " Software renderer: ${YELLOW}not found${NC}"
|
||||
tmt_report "libinit/swrast-available" "WARN" "/tmp/mesa_drivers.txt"
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
# =========================================================================
|
||||
# PHASE 3: Headless Graphics Stack Tests
|
||||
# =========================================================================
|
||||
echo -e "${BLUE}Phase 3: Headless Graphics Stack Tests${NC}"
|
||||
|
||||
run_test "headless/compositor-start" \
|
||||
"timeout $TEST_TIMEOUT xwfb-run -w 2 -- true"
|
||||
|
||||
run_test "headless/ptyxis-help" \
|
||||
"timeout $TEST_TIMEOUT xwfb-run -w 2 -- ptyxis --help"
|
||||
|
||||
# Get and report renderer info
|
||||
local renderer_log="$LOGDIR/headless-renderer-info.log"
|
||||
if timeout $TEST_TIMEOUT xwfb-run -w 2 -- glxinfo >"$renderer_log" 2>&1; then
|
||||
RENDERER=$(grep "OpenGL renderer" "$renderer_log" | cut -d: -f2 | xargs)
|
||||
VENDOR=$(grep "OpenGL vendor" "$renderer_log" | cut -d: -f2 | xargs)
|
||||
VERSION=$(grep "OpenGL version" "$renderer_log" | cut -d: -f2 | xargs)
|
||||
|
||||
echo -e " OpenGL vendor: ${GREEN}${VENDOR}${NC}"
|
||||
echo -e " OpenGL renderer: ${GREEN}${RENDERER}${NC}"
|
||||
echo -e " OpenGL version: ${GREEN}${VERSION}${NC}"
|
||||
|
||||
tmt_report "headless/renderer-info" "PASS" "$renderer_log"
|
||||
else
|
||||
tmt_report "headless/renderer-info" "FAIL" "$renderer_log"
|
||||
fi
|
||||
|
||||
echo
|
||||
}
|
||||
|
||||
run_phase_4() {
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE} Phase 4: Application Rendering Tests${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo "Architecture: $(uname -m)"
|
||||
echo "Log directory: $LOGDIR"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo
|
||||
|
||||
# =========================================================================
|
||||
# PHASE 4: Application Startup Tests
|
||||
# =========================================================================
|
||||
echo -e "${BLUE}Phase 4: Application Startup Tests${NC}"
|
||||
|
||||
# Check GTK renderer being used
|
||||
echo "GTK Renderer Detection:"
|
||||
echo " GTK_RENDERER env: ${GTK_RENDERER:-not set (will use default)}"
|
||||
echo " GSK_RENDERER env: ${GSK_RENDERER:-not set}"
|
||||
echo " GTK_DEBUG env: ${GTK_DEBUG:-not set}"
|
||||
echo " Expected: GTK4 uses 'ngl' (new GL) or 'gl' renderer"
|
||||
|
||||
# Test GTK3 app (may not be installed on RHEL 10)
|
||||
if which gtk3-demo >/dev/null 2>&1; then
|
||||
run_test "app/gtk3-demo-list" \
|
||||
"timeout $TEST_TIMEOUT xwfb-run -w 2 -- gtk3-demo --list"
|
||||
#test some actual demo
|
||||
run_test "app/gtk3-demo-textscroll" \
|
||||
"timeout $TEST_TIMEOUT xwfb-run -w 2 -- gtk3-demo --run=textscroll --autoquit"
|
||||
else
|
||||
echo "========================================"
|
||||
echo "Running: app/gtk3-demo"
|
||||
echo "Command: gtk3-demo --list"
|
||||
echo -n "Result: "
|
||||
echo -e "${YELLOW}SKIP${NC} (gtk3-demo not installed)"
|
||||
tmt_report "app/gtk3-demo" "SKIP" "/dev/null"
|
||||
fi
|
||||
|
||||
|
||||
# Test GTK4
|
||||
run_test "app/gtk4-demo-list" \
|
||||
"timeout $TEST_TIMEOUT xwfb-run -w 2 -- gtk4-demo --list"
|
||||
|
||||
#Test some actual demo
|
||||
run_test "app/gtk4-demo-textscroll" \
|
||||
"timeout $TEST_TIMEOUT xwfb-run -w 2 -- gtk4-demo --run=textscroll --autoquit"
|
||||
|
||||
# Test GTK4 rendering with actual visual verification
|
||||
local gtk4_test_script="$(dirname "$0")/gtk4_render_test.py"
|
||||
if [ ! -f "$gtk4_test_script" ]; then
|
||||
gtk4_test_script="./gtk4_render_test.py"
|
||||
fi
|
||||
|
||||
if [ -f "$gtk4_test_script" ] && python3 -c "import gi; gi.require_version('Gtk', '4.0')" 2>/dev/null; then
|
||||
# =====================================================================
|
||||
# Test 1: GTK4 with default renderer
|
||||
# =====================================================================
|
||||
echo "========================================"
|
||||
echo "Running: app/gtk4-render-test-default (visual verification)"
|
||||
local gtk4_render_log="$LOGDIR/app_gtk4-render-test-default.log"
|
||||
local gtk4_render_png="$LOGDIR/gtk4_render_test_default.png"
|
||||
echo "Log: $gtk4_render_log"
|
||||
echo "Output: $gtk4_render_png"
|
||||
echo -n "Result: "
|
||||
|
||||
# Test with default renderer
|
||||
if timeout $TEST_TIMEOUT xwfb-run -w 2 -- python3 "$gtk4_test_script" "$gtk4_render_png" >"$gtk4_render_log" 2>&1; then
|
||||
# Check if PNG has good color diversity
|
||||
if [ -f "$gtk4_render_png" ]; then
|
||||
local colors=$(python3 -c "
|
||||
import sys
|
||||
with open('$gtk4_render_png', 'rb') as f:
|
||||
data = f.read()
|
||||
samples = set()
|
||||
for i in range(100, min(len(data)-4, 2000), 10):
|
||||
samples.add(data[i:i+4])
|
||||
print(len(samples))
|
||||
" 2>/dev/null || echo 0)
|
||||
|
||||
if [ "$colors" -gt 50 ]; then
|
||||
echo -e "${GREEN}PASS${NC} (${colors} unique colors - rendering OK)"
|
||||
tmt_report "app/gtk4-render-test-default" "PASS" "$gtk4_render_log"
|
||||
tmt_submit "$gtk4_render_png" "gtk4-render-test-default.png"
|
||||
else
|
||||
echo -e "${RED}FAIL${NC} (only ${colors} unique colors - black screen detected)"
|
||||
tmt_report "app/gtk4-render-test-default" "FAIL" "$gtk4_render_log"
|
||||
tmt_submit "$gtk4_render_png" "gtk4-render-FAILED-default.png"
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}FAIL${NC} (no PNG generated)"
|
||||
tmt_report "app/gtk4-render-test-default" "FAIL" "$gtk4_render_log"
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}FAIL${NC} (app crashed or timed out)"
|
||||
tmt_report "app/gtk4-render-test-default" "FAIL" "$gtk4_render_log"
|
||||
fi
|
||||
|
||||
# =====================================================================
|
||||
# Test 2: GTK4 with NGL renderer (optional/informational test)
|
||||
# =====================================================================
|
||||
echo "========================================"
|
||||
echo "Running: app/gtk4-render-test-ngl (visual verification with GSK_RENDERER=ngl)"
|
||||
echo "Note: NGL renderer test is OPTIONAL - verifies if workaround is available"
|
||||
local gtk4_ngl_log="$LOGDIR/app_gtk4-render-test-ngl.log"
|
||||
local gtk4_ngl_png="$LOGDIR/gtk4_render_test_ngl.png"
|
||||
echo "Log: $gtk4_ngl_log"
|
||||
echo "Output: $gtk4_ngl_png"
|
||||
echo -n "Result: "
|
||||
|
||||
# Test with NGL renderer (non-critical - NGL may not be fully supported yet)
|
||||
if timeout $TEST_TIMEOUT xwfb-run -w 2 -- python3 "$gtk4_test_script" "$gtk4_ngl_png" --renderer=ngl >"$gtk4_ngl_log" 2>&1; then
|
||||
# Check if PNG has good color diversity
|
||||
if [ -f "$gtk4_ngl_png" ]; then
|
||||
local ngl_colors=$(python3 -c "
|
||||
import sys
|
||||
with open('$gtk4_ngl_png', 'rb') as f:
|
||||
data = f.read()
|
||||
samples = set()
|
||||
for i in range(100, min(len(data)-4, 2000), 10):
|
||||
samples.add(data[i:i+4])
|
||||
print(len(samples))
|
||||
" 2>/dev/null || echo 0)
|
||||
|
||||
if [ "$ngl_colors" -gt 50 ]; then
|
||||
echo -e "${GREEN}PASS${NC} (${ngl_colors} unique colors - NGL renderer works!)"
|
||||
tmt_report "app/gtk4-render-test-ngl" "PASS" "$gtk4_ngl_log"
|
||||
tmt_submit "$gtk4_ngl_png" "gtk4-render-test-ngl.png"
|
||||
else
|
||||
echo -e "${YELLOW}WARN${NC} (only ${ngl_colors} unique colors - NGL renderer also has issues)"
|
||||
tmt_report "app/gtk4-render-test-ngl" "WARN" "$gtk4_ngl_log"
|
||||
tmt_submit "$gtk4_ngl_png" "gtk4-render-ngl-warn.png"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}WARN${NC} (no PNG generated - NGL renderer failed)"
|
||||
tmt_report "app/gtk4-render-test-ngl" "WARN" "$gtk4_ngl_log"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}WARN${NC} (app crashed or timed out - NGL renderer not supported/broken)"
|
||||
tmt_report "app/gtk4-render-test-ngl" "WARN" "$gtk4_ngl_log"
|
||||
fi
|
||||
else
|
||||
echo "========================================"
|
||||
echo "Running: app/gtk4-render-test"
|
||||
echo -n "Result: "
|
||||
echo -e "${YELLOW}SKIP${NC} (gtk4_render_test.py or GTK4 not available)"
|
||||
tmt_report "app/gtk4-render-test-default" "SKIP" "/dev/null"
|
||||
tmt_report "app/gtk4-render-test-ngl" "SKIP" "/dev/null"
|
||||
fi
|
||||
|
||||
if which xterm >/dev/null 2>&1; then
|
||||
run_test "app/xterm" \
|
||||
"timeout $TEST_TIMEOUT xwfb-run -w 2 -- xterm -e true" \
|
||||
"no"
|
||||
fi
|
||||
|
||||
if which glxgears >/dev/null 2>&1; then
|
||||
# glxgears runs forever, so we test differently:
|
||||
# Run for 5 seconds, check if it produces FPS output
|
||||
echo "========================================"
|
||||
echo "Running: app/glxgears"
|
||||
echo "Command: xwfb-run -w 2 -- glxgears -info & sleep 25 ; killall glxgears"
|
||||
local gears_log="$LOGDIR/app_glxgears.log"
|
||||
echo "Log: $gears_log"
|
||||
echo -n "Result: "
|
||||
|
||||
# Run glxgears for 5 seconds with kill timeout
|
||||
xwfb-run -w 2 -- glxgears -info >"$gears_log" 2>&1 &
|
||||
sleep 25
|
||||
killall glxgears
|
||||
local exit_code=$?
|
||||
|
||||
# Wait a moment for cleanup
|
||||
sleep 1
|
||||
|
||||
# Check if we got FPS output (means it rendered successfully)
|
||||
if grep -q "frames in.*seconds.*FPS" "$gears_log"; then
|
||||
echo -e "${GREEN}PASS${NC} (rendered frames successfully)"
|
||||
if [ "$VERBOSE" == "1" ]; then
|
||||
echo " GL Renderer:"
|
||||
grep "GL_RENDERER" "$gears_log" | sed 's/^/ /'
|
||||
echo " Performance:"
|
||||
grep "frames in.*seconds.*FPS" "$gears_log" | head -3 | sed 's/^/ /'
|
||||
fi
|
||||
tmt_report "app/glxgears" "PASS" "$gears_log"
|
||||
else
|
||||
echo -e "${YELLOW}WARN${NC} (no FPS output, exit code: $exit_code)"
|
||||
if [ "$VERBOSE" == "1" ]; then
|
||||
echo " Log output:"
|
||||
tail -10 "$gears_log" | sed 's/^/ /'
|
||||
fi
|
||||
tmt_report "app/glxgears" "WARN" "$gears_log"
|
||||
fi
|
||||
|
||||
# Cleanup any remaining processes
|
||||
killall -9 glxgears mutter dbus-run-session 2>/dev/null || true
|
||||
fi
|
||||
|
||||
echo
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# Main Test Execution
|
||||
# =============================================================================
|
||||
|
||||
main() {
|
||||
# Parse command-line arguments
|
||||
local RUN_PHASES="all" # Default: run all phases
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--phase=*)
|
||||
RUN_PHASES="${1#*=}"
|
||||
shift
|
||||
;;
|
||||
--help)
|
||||
echo "Usage: $0 [--phase=1-3|4|all]"
|
||||
echo " --phase=1-3 Run only infrastructure tests (Phases 1-3)"
|
||||
echo " --phase=4 Run only application rendering tests (Phase 4)"
|
||||
echo " --phase=all Run all phases (default)"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
echo "Use --help for usage information"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE} Graphics Stack Smoke Test${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo "Run mode: $RUN_PHASES"
|
||||
echo "Architecture: $(uname -m)"
|
||||
echo
|
||||
|
||||
# Run requested phases
|
||||
case "$RUN_PHASES" in
|
||||
"1-3")
|
||||
run_phases_1_to_3
|
||||
;;
|
||||
"4")
|
||||
run_phase_4
|
||||
;;
|
||||
"all")
|
||||
run_phases_1_to_3
|
||||
run_phase_4
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: Invalid phase specification: $RUN_PHASES"
|
||||
echo "Valid options: 1-3, 4, all"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# =========================================================================
|
||||
# Results Summary
|
||||
# =========================================================================
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE} Test Results Summary${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
|
||||
# Show all logs
|
||||
echo "Generated logs:"
|
||||
ls -lh "$LOGDIR" | tail -n +2 | awk '{printf " %s %s\n", $9, $5}'
|
||||
echo
|
||||
|
||||
if [ "$OVERALL_RESULT" == "PASS" ]; then
|
||||
echo -e "${GREEN}✓ ALL CRITICAL TESTS PASSED${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo "Graphics stack is functional on $(uname -m)"
|
||||
echo "Logs saved to: $LOGDIR"
|
||||
echo "Master log: $LOGDIR/00-master-test.log"
|
||||
|
||||
# Submit master log and any screenshots
|
||||
echo
|
||||
echo "Submitting artifacts to TMT..."
|
||||
tmt_submit "$LOGDIR/00-master-test.log" "master-test.log"
|
||||
|
||||
# Submit any PNG screenshots as visual evidence
|
||||
for png in "$LOGDIR"/*.png; do
|
||||
if [ -f "$png" ]; then
|
||||
tmt_submit "$png" "$(basename $png)"
|
||||
fi
|
||||
done
|
||||
|
||||
# Final overall report
|
||||
tmt_report "graphics-smoke-test" "PASS" "$LOGDIR/00-master-test.log"
|
||||
exit 0
|
||||
else
|
||||
echo -e "${RED}✗ ONE OR MORE CRITICAL TESTS FAILED${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo "Graphics stack validation failed"
|
||||
echo "Logs saved to: $LOGDIR"
|
||||
echo "Master log: $LOGDIR/00-master-test.log"
|
||||
echo
|
||||
|
||||
# Show detailed failure information
|
||||
echo -e "${RED}Failed Tests:${NC}"
|
||||
if ls "$LOGDIR"/*.log >/dev/null 2>&1; then
|
||||
for logfile in "$LOGDIR"/*.log; do
|
||||
testname=$(basename "$logfile" .log)
|
||||
# Check if it's a failed test (non-zero exit or error keywords)
|
||||
if grep -qi "error\|fail\|cannot\|unable" "$logfile" 2>/dev/null; then
|
||||
echo -e " ${RED}✗${NC} $testname"
|
||||
echo " Log: $logfile"
|
||||
echo " Last 10 lines:"
|
||||
tail -10 "$logfile" | sed 's/^/ /'
|
||||
echo
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Submit master log and all artifacts for debugging
|
||||
echo
|
||||
echo "Submitting artifacts to TMT..."
|
||||
tmt_submit "$LOGDIR/00-master-test.log" "master-test.log"
|
||||
|
||||
# Submit all PNG screenshots as evidence of failure
|
||||
for png in "$LOGDIR"/*.png; do
|
||||
if [ -f "$png" ]; then
|
||||
tmt_submit "$png" "$(basename $png)"
|
||||
fi
|
||||
done
|
||||
|
||||
# Submit failed test logs
|
||||
for log in "$LOGDIR"/*.log; do
|
||||
if [ -f "$log" ] && grep -qi "error\|fail" "$log" 2>/dev/null; then
|
||||
tmt_submit "$log" "$(basename $log)"
|
||||
fi
|
||||
done
|
||||
|
||||
# Final overall report
|
||||
tmt_report "graphics-smoke-test" "FAIL" "$LOGDIR/00-master-test.log"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# Script Entry Point
|
||||
# =============================================================================
|
||||
|
||||
# Pass all command-line arguments to main
|
||||
main "$@"
|
||||
146
tests/gtk4_render_test.py
Executable file
146
tests/gtk4_render_test.py
Executable file
@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
GTK4 Rendering Test - Verifies actual rendering by drawing and saving
|
||||
Tests the s390x Mesa bug where GTK apps show black screens
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Parse renderer argument BEFORE importing GTK
|
||||
# GSK_RENDERER must be set before GTK initializes
|
||||
renderer = None
|
||||
output_file = None
|
||||
|
||||
for i, arg in enumerate(sys.argv[1:], 1):
|
||||
if arg.startswith('--renderer='):
|
||||
renderer = arg.split('=', 1)[1]
|
||||
elif not arg.startswith('--'):
|
||||
output_file = arg
|
||||
|
||||
if renderer:
|
||||
os.environ['GSK_RENDERER'] = renderer
|
||||
print(f"Setting GSK_RENDERER={renderer} before GTK import")
|
||||
|
||||
#Set debug to print rear renderer of app
|
||||
os.environ['GSK_DEBUG'] = "renderer"
|
||||
|
||||
# Now import GTK (after setting environment)
|
||||
import gi
|
||||
gi.require_version('Gtk', '4.0')
|
||||
from gi.repository import Gtk, GLib
|
||||
import cairo
|
||||
|
||||
class RenderTestApp(Gtk.Application):
|
||||
def __init__(self, output_file):
|
||||
super().__init__(application_id='org.test.gtk4render')
|
||||
self.output_file = output_file
|
||||
self.rendered = False
|
||||
self.drawing_area = None
|
||||
|
||||
def do_activate(self):
|
||||
window = Gtk.ApplicationWindow(application=self)
|
||||
window.set_title("GTK4 Rendering Test")
|
||||
window.set_default_size(400, 300)
|
||||
|
||||
self.drawing_area = Gtk.DrawingArea()
|
||||
self.drawing_area.set_draw_func(self.draw_callback)
|
||||
|
||||
window.set_child(self.drawing_area)
|
||||
window.present()
|
||||
|
||||
# Wait for rendering, then save and quit
|
||||
GLib.timeout_add(2000, self.save_and_quit)
|
||||
|
||||
def draw_callback(self, area, cr, width, height):
|
||||
"""Draw colorful pattern to prove rendering works"""
|
||||
# Red rectangle
|
||||
cr.set_source_rgb(1.0, 0.0, 0.0)
|
||||
cr.rectangle(10, 10, 100, 100)
|
||||
cr.fill()
|
||||
|
||||
# Green rectangle
|
||||
cr.set_source_rgb(0.0, 1.0, 0.0)
|
||||
cr.rectangle(130, 10, 100, 100)
|
||||
cr.fill()
|
||||
|
||||
# Blue rectangle
|
||||
cr.set_source_rgb(0.0, 0.0, 1.0)
|
||||
cr.rectangle(250, 10, 100, 100)
|
||||
cr.fill()
|
||||
|
||||
# Yellow circle
|
||||
cr.set_source_rgb(1.0, 1.0, 0.0)
|
||||
cr.arc(200, 200, 50, 0, 2 * 3.14159)
|
||||
cr.fill()
|
||||
|
||||
print(f"Draw callback called - rendering {width}x{height} surface")
|
||||
self.rendered = True
|
||||
|
||||
def save_and_quit(self):
|
||||
"""Save the rendered surface to PNG and exit"""
|
||||
if not self.rendered:
|
||||
print("WARNING: Draw function not called yet")
|
||||
print("RESULT: WARN - Rendering may not have occurred")
|
||||
self.quit()
|
||||
return False
|
||||
|
||||
try:
|
||||
# Get the window and widget dimensions
|
||||
width = self.drawing_area.get_width()
|
||||
height = self.drawing_area.get_height()
|
||||
|
||||
print(f"Creating Cairo surface {width}x{height}")
|
||||
|
||||
# Create a Cairo image surface
|
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
|
||||
cr = cairo.Context(surface)
|
||||
|
||||
# Re-render to this surface
|
||||
self.draw_callback(None, cr, width, height)
|
||||
|
||||
# Save to PNG
|
||||
surface.write_to_png(self.output_file)
|
||||
|
||||
# Check file was created and has reasonable size
|
||||
if os.path.exists(self.output_file):
|
||||
file_size = os.path.getsize(self.output_file)
|
||||
print(f"SUCCESS: Saved rendering to {self.output_file} ({file_size} bytes)")
|
||||
|
||||
if file_size > 1000:
|
||||
print("RESULT: PASS - Rendering verified")
|
||||
else:
|
||||
print(f"RESULT: FAIL - PNG file too small ({file_size} bytes)")
|
||||
else:
|
||||
print(f"RESULT: FAIL - Failed to create {self.output_file}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"ERROR: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
print("RESULT: FAIL - Exception during rendering")
|
||||
|
||||
self.quit()
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
global output_file
|
||||
|
||||
if not output_file:
|
||||
print(f"Usage: {sys.argv[0]} <output.png> [--renderer=ngl|gl|cairo|vulkan]")
|
||||
print(f" --renderer: GSK renderer to use (default: auto-detect)")
|
||||
sys.exit(1)
|
||||
|
||||
print(f"GTK4 Rendering Test - will save to {output_file}")
|
||||
print(f"GSK_RENDERER: {os.environ.get('GSK_RENDERER', 'not set (auto-detect)')}")
|
||||
print(f"GTK_RENDERER: {os.environ.get('GTK_RENDERER', 'not set')}")
|
||||
|
||||
app = RenderTestApp(output_file)
|
||||
exit_status = app.run(None)
|
||||
|
||||
sys.exit(exit_status)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Loading…
Reference in New Issue
Block a user