test: add interface_gui.py to test bitcoin-gui startup via RPC

Adds a functional test that starts bitcoin-gui (via the bitcoin wrapper
with "gui" subcommand) using QT_QPA_PLATFORM=minimal for headless
operation, then verifies it responds to a stop RPC call. This catches
startup regressions in the GUI that have no CI coverage today.

Extends the test framework to support use_gui=True in TestNode, which
invokes "bitcoin gui" instead of "bitcoin node" and automatically sets
QT_QPA_PLATFORM=minimal. Adds BUILD_GUI to test/config.ini.in and
is_gui_compiled()/skip_if_no_gui() helpers to BitcoinTestFramework.

Co-Authored-By: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ryan Ofsky
2026-06-17 14:42:44 -04:00
parent 93012d7ff9
commit aa01721c89
8 changed files with 79 additions and 8 deletions

View File

@@ -112,6 +112,7 @@ class TestNode():
v2transport=False,
uses_wallet=False,
ipcbind=False,
use_gui=False,
):
self.index = i
self.datadir_path = datadir_path
@@ -125,6 +126,7 @@ class TestNode():
self.binaries = binaries
self.coverage_dir = coverage_dir
self.cwd = cwd
self.use_gui = use_gui
self.has_explicit_bind = False
if extra_conf is not None:
append_config(self.datadir_path, extra_conf)
@@ -138,7 +140,7 @@ class TestNode():
# Configuration for logging is set as command-line args rather than in the bitcoin.conf file.
# This means that starting a bitcoind using the temp dir to debug a failed test won't
# spam debug.log.
self.args = self.binaries.node_argv(need_ipc=ipcbind) + [
self.args = self.binaries.node_argv(need_ipc=ipcbind, use_gui=use_gui) + [
f"-datadir={self.datadir_path}",
"-logtimemicros",
"-debug",
@@ -278,6 +280,20 @@ class TestNode():
# add environment variable LIBC_FATAL_STDERR_=1 so that libc errors are written to stderr and not the terminal
subp_env = dict(os.environ, LIBC_FATAL_STDERR_="1")
if self.use_gui:
subp_env.setdefault("QT_QPA_PLATFORM", "minimal")
subp_env.setdefault("LC_ALL", "nl_NL.UTF-8") # Set language to try to trigger translation bugs
if sys.platform.startswith("linux") and "XDG_RUNTIME_DIR" not in subp_env:
# Qt prints warnings to stderr when XDG_RUNTIME_DIR is unset or has wrong
# permissions (e.g. in CI environments without a desktop session), which
# would cause tests to fail due to unexpected stderr output. The two
# warnings are:
# "QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'"
# "QStandardPaths: wrong permissions on runtime directory /path, 0755 instead of 0700"
# Use a dedicated subdirectory with the required 0700 permissions.
xdg_runtime_dir = self.datadir_path / "xdg_runtime"
xdg_runtime_dir.mkdir(mode=0o700, exist_ok=True)
subp_env["XDG_RUNTIME_DIR"] = str(xdg_runtime_dir)
if env is not None:
subp_env.update(env)