Skip to content

Commit 3f741ef

Browse files
dfa1claude
andcommitted
test(cli): force class init in terminal smoke tests
A class literal (PosixTerminal.class / WindowsTerminal.class) loads but does not run <clinit>, so the FFM downcall handles in static fields were never resolved — the tests asserted nothing and the classes showed 0% coverage. Switch to Class.forName(name, true, loader) to actually trigger static initialization, so a missing/renamed libc or kernel32 symbol fails the smoke test as intended and the init path is covered. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 2235499 commit 3f741ef

2 files changed

Lines changed: 21 additions & 11 deletions

File tree

cli/src/test/java/io/github/dfa1/vortex/cli/tui/term/PosixTerminalSmokeTest.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,24 @@
1414
///
1515
/// `open()` and `size()` are deliberately not exercised — they need a real
1616
/// console, and a stray successful `open()` would switch the developer's terminal
17-
/// into the alternate screen / raw mode. Class load alone is the safe, meaningful
18-
/// assertion: it forces every `Linker.downcallHandle` in the static initializer
19-
/// (tcgetattr, tcsetattr, cfmakeraw, ioctl) to resolve its libc symbol, throwing
17+
/// into the alternate screen / raw mode. Forcing class *initialization* is the
18+
/// safe, meaningful assertion: it runs every `Linker.downcallHandle` in the
19+
/// static initializer (tcgetattr, tcsetattr, cfmakeraw, ioctl), throwing
2020
/// [UnsatisfiedLinkError] during `<clinit>` if an entry point is missing.
2121
class PosixTerminalSmokeTest {
2222

2323
@Test
2424
@EnabledOnOs({OS.LINUX, OS.MAC})
25-
void classLoad_resolvesEveryLibcSymbol() {
26-
// Given / When — touching the class triggers <clinit>, which calls
27-
// Linker.downcallHandle for tcgetattr / tcsetattr / cfmakeraw / ioctl.
28-
Class<?> sut = PosixTerminal.class;
25+
void classLoad_resolvesEveryLibcSymbol() throws ClassNotFoundException {
26+
// Given / When — a class *literal* (PosixTerminal.class) only loads the
27+
// class; it does NOT run <clinit>, so the downcall handles in static
28+
// fields would never resolve and this would assert nothing. Force
29+
// initialization explicitly so the Linker.downcallHandle calls for
30+
// tcgetattr / tcsetattr / cfmakeraw / ioctl actually fire.
31+
Class<?> sut = Class.forName(
32+
"io.github.dfa1.vortex.cli.tui.term.PosixTerminal",
33+
true,
34+
getClass().getClassLoader());
2935

3036
// Then
3137
assertThat(sut).isNotNull();

cli/src/test/java/io/github/dfa1/vortex/cli/tui/term/WindowsTerminalSmokeTest.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,17 @@ class WindowsTerminalSmokeTest {
2121

2222
@Test
2323
@EnabledOnOs(OS.WINDOWS)
24-
void classLoad_resolvesEveryKernel32Symbol() {
25-
// Given / When — touching the class triggers <clinit>, which calls
26-
// Linker.downcallHandle for every imported kernel32 function.
24+
void classLoad_resolvesEveryKernel32Symbol() throws ClassNotFoundException {
25+
// Given / When — a class *literal* (WindowsTerminal.class) only loads the
26+
// class; it does NOT run <clinit>. Force initialization so the
27+
// Linker.downcallHandle calls for every imported kernel32 function fire.
2728
// Symbols covered: GetStdHandle, GetConsoleMode, SetConsoleMode,
2829
// GetConsoleScreenBufferInfo, GetFileType, ReadFile,
2930
// GetNumberOfConsoleInputEvents.
30-
Class<?> sut = WindowsTerminal.class;
31+
Class<?> sut = Class.forName(
32+
"io.github.dfa1.vortex.cli.tui.term.WindowsTerminal",
33+
true,
34+
getClass().getClassLoader());
3135

3236
// Then
3337
assertThat(sut).isNotNull();

0 commit comments

Comments
 (0)