rename stale forkpty test tag to pty
test / unit + widget + golden + a11y (push) Failing after 32s
test / integration_test (xvfb) (push) Has been skipped
test / bundle smoke (xvfb 5s) (push) Has been skipped
test / daemon subprocess + web WASM smoke (push) Has been skipped
test / dart doc (lib API) (push) Failing after 36s

forkpty was replaced by posix_openpt + posix_spawn in T-96, but the
test tag, ci/test.sh segregation, and dart_test.yaml comment kept the
forkpty name. The segregation is still required — verified the PTY
tests fail under the flutter-test runner (the master fd doesn't
reliably deliver output there) but pass under dart test — only the
name was wrong. Rename to `pty` and correct the rationale comment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-23 08:49:13 +02:00
co-authored by Claude Opus 4.7
parent caf8fd95cf
commit b224502658
5 changed files with 20 additions and 18 deletions
+3 -3
View File
@@ -11,8 +11,8 @@ flutter analyze
echo "==> dart format (whole tree)"
dart format --set-exit-if-changed .
echo "==> dart test (forkpty — incompatible with flutter test runner)"
dart test --tags forkpty test/pty/session_test.dart test/panes/registry_test.dart
echo "==> dart test (pty — unreliable under the flutter test runner)"
dart test --tags pty test/pty/session_test.dart test/panes/registry_test.dart
echo "==> flutter test --coverage (unit + widget + golden)"
flutter test --coverage --exclude-tags forkpty
flutter test --coverage --exclude-tags pty
+7 -5
View File
@@ -3,8 +3,10 @@
# both honor them. Undeclared tags are ignored by the runners, which
# silently breaks selective excludes.
tags:
# Tests that call `forkpty()` via Dart FFI. Must run under `dart test`,
# not `flutter test` the latter's runner hosts a multi-threaded
# Flutter engine in which forkpty produces a master fd that never
# delivers output. See `test/pty/session_test.dart`.
forkpty:
# Native-PTY tests (posix_openpt + posix_spawn via Dart FFI). Must run
# under `dart test`, not `flutter test`: the flutter-test runner hosts a
# multi-threaded engine in which the PTY master fd doesn't reliably
# deliver output, so these flake there (verified). They are reliable
# under `dart test`. (Tag was historically named `forkpty`, before
# T-96 replaced forkpty with posix_spawn.) See `test/pty/session_test.dart`.
pty:
+2 -2
View File
@@ -1,7 +1,7 @@
/// Unit tests for [PaneRegistry].
///
/// Exercises spawn / list / write / resize / close against the real
/// NativePty (forkpty via FFI). Events are captured via
/// NativePty (posix_spawn via FFI). Events are captured via
/// [RecordingEventSink].
library;
@@ -41,7 +41,7 @@ void main() {
expect(evt.data['id'], pane.id);
});
test('output events base64-encode the child bytes', tags: ['forkpty'], retry: 2, () async {
test('output events base64-encode the child bytes', tags: ['pty'], retry: 2, () async {
// Subscribe to the sink stream BEFORE spawn so we don't miss
// any pane.output events that arrive between spawn and listen.
final buf = StringBuffer();
+2 -2
View File
@@ -11,8 +11,8 @@ import 'package:test/test.dart';
void main() {
group('PtyException', () {
test('toString includes the op + message', () {
const e = PtyException('forkpty', 'kaboom');
expect(e.toString(), contains('forkpty'));
const e = PtyException('posix_spawn', 'kaboom');
expect(e.toString(), contains('posix_spawn'));
expect(e.toString(), contains('kaboom'));
expect(e.toString(), isNot(contains('errno=')));
});
+6 -6
View File
@@ -3,7 +3,7 @@
/// Exercises posix_spawn() end-to-end: spawn → child output through the
/// reader isolate. Linux + macOS only; skipped elsewhere.
///
/// Per-test `tags: ['forkpty']` marks the tests that depend on the
/// Per-test `tags: ['pty']` marks the tests that depend on the
/// reader isolate delivering output from the master fd — reads from a
/// pty master under the flutter test runner are unstable when other
/// suites run in parallel (intermittently empty). Only the
@@ -24,7 +24,7 @@ void main() {
if (!Platform.isLinux && !Platform.isMacOS) return;
group('NativePty', () {
test('spawns shell -c echo and reads output', tags: ['forkpty'], retry: 2, () async {
test('spawns shell -c echo and reads output', tags: ['pty'], retry: 2, () async {
final s = NativePty.start(
executable: '/bin/sh',
arguments: ['-c', 'echo hello-pty'],
@@ -42,7 +42,7 @@ void main() {
expect(got, contains('hello-pty'));
});
test('write sends keystrokes to child', tags: ['forkpty'], retry: 2, () async {
test('write sends keystrokes to child', tags: ['pty'], retry: 2, () async {
final s = NativePty.start(
executable: '/bin/sh',
arguments: [],
@@ -77,7 +77,7 @@ void main() {
expect(result, contains('write-test-ok'));
});
test('close kills child and closes output', tags: ['forkpty'], retry: 2, () async {
test('close kills child and closes output', tags: ['pty'], retry: 2, () async {
final s = NativePty.start(
executable: '/bin/sh',
arguments: [],
@@ -101,7 +101,7 @@ void main() {
expect(s.isClosed, isTrue);
});
test('bare command name resolves via the PATH env var', tags: ['forkpty'], retry: 2, () async {
test('bare command name resolves via the PATH env var', tags: ['pty'], retry: 2, () async {
// 'sh' is a bare command; without resolution, execve would fail.
final s = NativePty.start(
executable: 'sh',
@@ -163,7 +163,7 @@ void main() {
test('start with a bare command name resolves it via PATH (no read)', () async {
// Resolves "cat" to /bin/cat (or wherever it lives on PATH).
// Doesn't read the master fd — that path is exercised by the
// forkpty-tagged version of this test under `dart test`.
// pty-tagged version of this test under `dart test`.
final s = NativePty.start(
executable: 'cat',
arguments: const [],