From fc7c8e9cae89a4d4e1de45ffff3f6b4cf17421f8 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Wed, 12 Aug 2026 04:42:33 +1000 Subject: [PATCH] [client] render: test X11 display paths --- client/tests/CMakeLists.txt | 25 ++++++++++++++ client/tests/render_test.cpp | 64 +++++++++++++++++++++++++++++++----- 2 files changed, 81 insertions(+), 8 deletions(-) diff --git a/client/tests/CMakeLists.txt b/client/tests/CMakeLists.txt index 01309f99..4895581e 100644 --- a/client/tests/CMakeLists.txt +++ b/client/tests/CMakeLists.txt @@ -633,6 +633,12 @@ find_program(WESTON_EXECUTABLE NAMES weston) if(NOT WESTON_EXECUTABLE) message(FATAL_ERROR "weston is required to run framebuffer rendering tests") endif() +if(ENABLE_X11) + find_program(XVFB_RUN_EXECUTABLE NAMES xvfb-run) + if(NOT XVFB_RUN_EXECUTABLE) + message(FATAL_ERROR "xvfb-run is required to run X11 rendering tests") + endif() +endif() add_executable(render-tests render_test.cpp @@ -668,8 +674,27 @@ add_test(NAME render-tests "${CMAKE_CURRENT_SOURCE_DIR}/run-with-weston.sh" "${WESTON_EXECUTABLE}" "$" + "--gtest_filter=-X11*" ) set_tests_properties(render-tests PROPERTIES TIMEOUT 120 ) + +if(ENABLE_X11) + add_test(NAME render-x11-tests + COMMAND "${CMAKE_COMMAND}" -E env + --unset=WAYLAND_DISPLAY + LIBGL_ALWAYS_SOFTWARE=1 + "${XVFB_RUN_EXECUTABLE}" + -a + -e /dev/stderr + -s "-screen 0 1024x768x24 +extension GLX" + "$" + "--gtest_filter=X11*" + ) + + set_tests_properties(render-x11-tests PROPERTIES + TIMEOUT 120 + ) +endif() diff --git a/client/tests/render_test.cpp b/client/tests/render_test.cpp index d1600fee..35a48984 100644 --- a/client/tests/render_test.cpp +++ b/client/tests/render_test.cpp @@ -124,6 +124,11 @@ std::string readText(const std::filesystem::path & path) std::istreambuf_iterator()); } +void expectX11Log(const std::string & clientLog) +{ + EXPECT_NE(clientLog.find("X11 XInput"), std::string::npos) << clientLog; +} + std::filesystem::path makeTempDirectory() { std::array value {}; @@ -753,25 +758,31 @@ class GeometryRenderPipelineTest : { }; -TEST_P(GeometryRenderPipelineTest, MatchesReference) +void runGeometryCase(const GeometryCase & geometry, bool x11) { - const GeometryCase & geometry = GetParam(); - const FormatCase format = + const FormatCase format = { "bgra", FRAME_TYPE_BGRA, false, false }; - const LaunchCase launch = + const LaunchCase launch = { "EGL", geometry.width, geometry.height, geometry.rotate, true }; Capture capture = produceCapture(format, "moving", 0, launch); ASSERT_FALSE(capture.data.empty()) << "artifacts: " << capture.directory; + if (x11) + expectX11Log(readText(capture.log)); compareGeometry(format, geometry, capture); if (!testing::Test::HasFailure()) std::filesystem::remove_all(capture.directory); } +TEST_P(GeometryRenderPipelineTest, MatchesReference) +{ + runGeometryCase(GetParam(), false); +} + std::string geometryRenderCaseName( const testing::TestParamInfo & info) { @@ -792,22 +803,24 @@ class OpenGLRenderPipelineTest : { }; -TEST_P(OpenGLRenderPipelineTest, RendersFrames) +void runOpenGLCase(const FormatCase & format, bool x11) { - const FormatCase & format = GetParam(); - const LaunchCase launch = + const LaunchCase launch = { "OpenGL", 254, 254, 90, false }; const std::filesystem::path directory = makeTempDirectory(); ASSERT_FALSE(directory.empty()); const std::filesystem::path log = - directory / (std::string("opengl-") + format.name + ".log"); + directory / (std::string(x11 ? "x11-opengl-" : "opengl-") + + format.name + ".log"); const int status = runClient( format, "moving", directory / "unused", log, 0, launch); const std::string clientLog = readText(log); EXPECT_EQ(status, 0) << clientLog; + if (x11) + expectX11Log(clientLog); EXPECT_NE(clientLog.find("Using Renderer: OpenGL"), std::string::npos) << clientLog; EXPECT_NE(clientLog.find("Vendor :"), std::string::npos) << clientLog; @@ -819,6 +832,11 @@ TEST_P(OpenGLRenderPipelineTest, RendersFrames) std::filesystem::remove_all(directory); } +TEST_P(OpenGLRenderPipelineTest, Runs) +{ + runOpenGLCase(GetParam(), false); +} + std::string openGLRenderCaseName( const testing::TestParamInfo & info) { @@ -836,4 +854,34 @@ INSTANTIATE_TEST_SUITE_P(Formats, OpenGLRenderPipelineTest, ), openGLRenderCaseName); +class X11EGLRenderPipelineTest : + public testing::TestWithParam +{ +}; + +TEST_P(X11EGLRenderPipelineTest, MatchesReference) +{ + ASSERT_FALSE(std::getenv("WAYLAND_DISPLAY")); + ASSERT_TRUE(std::getenv("DISPLAY")); + runGeometryCase(GetParam(), true); +} + +INSTANTIATE_TEST_SUITE_P(X11Geometry, X11EGLRenderPipelineTest, + testing::Values( + GeometryCase {"letterbox", 254, 254, 0, 0, 32, 254, 190}, + GeometryCase {"rotate90Scale2", 190, 254, 90, 0, 0, 190, 254} + ), + geometryRenderCaseName); + +TEST(X11OpenGLRenderPipelineTest, Runs) +{ + const FormatCase format = + { + "bgra", FRAME_TYPE_BGRA, false, false + }; + ASSERT_FALSE(std::getenv("WAYLAND_DISPLAY")); + ASSERT_TRUE(std::getenv("DISPLAY")); + runOpenGLCase(format, true); +} + } // namespace