Files
Termind/TermindTests/ShellIntegrationBootstrapTests.swift
T
Kaede Akino ba46e90e30 Format with swift-format
`swift-format lint --strict --recursive Termind TermindTests
TermindMCPBridge` is in the contribution instructions but had never been
run to completion: 4133 violations across 141 files, most of them
indentation and line breaking the pretty-printer would have settled on
its own.

`swift-format format -i` accounts for all but five. The rest are
lint-only rules it will not rewrite for you:

- `SSHKeyMaterial` declared its libssh2 entry point in the C symbol's
  own spelling. `@_silgen_name` already carries the linkage name, so the
  Swift side is free to be `libssh2PublicKeyFromPrivateMemory`.
- Four `.forEach { ... }` calls become for-in loops, two in
  `PortForwardingController` and two in tests.

Formatting only, and checked as such rather than assumed: all 5409
string literals under `Termind` are byte-identical across the change, so
no localization key moved. Comparing whitespace-stripped token streams
leaves 43 files with any real change, and each is one of the rules
above, a dropped semicolon, a `case a, b` split onto separate lines with
its raw values kept explicit, or a file-scope `private` respelled
`fileprivate` — which is the same access level in that position.

Builds, and the suite stays at 975 of 975.
2026-09-02 18:09:30 +08:00

435 lines
18 KiB
Swift

import Foundation
import Testing
@testable import Termind
@Suite
struct ShellIntegrationBootstrapTests {
@Test
func bashBootstrapIsHiddenAndEmitsStandardOSC7() throws {
var bootstrap = RemoteShellIntegrationBootstrap(token: "ABC123")
let probe = String(decoding: bootstrap.startCommand, as: UTF8.self)
let probeOutput = Data(
("Welcome\r\nuser@host$ " + probe.dropLast()
+ "\r\n__TRMD_ABC123_SYSTEM__\"ubuntu\"|\"24.04\"|Linux|6.8.0-40-generic|x86_64__\r\n"
+ "__TRMD_ABC123_SHELL__/bin/bash__\r\nuser@host$ ").utf8
)
let probeUpdate = bootstrap.receive(probeOutput)
let command = try #require(probeUpdate.command)
let commandText = String(decoding: command, as: UTF8.self)
#expect(commandText.contains("file://localhost%s"))
#expect(commandText.contains("TermindCommand=ABC123"))
#expect(commandText.contains("TermindCommandFinished=ABC123"))
#expect(commandText.contains("TermindPrompt=ABC123"))
#expect(commandText.contains("TermindDraft=ABC123"))
#expect(commandText.contains("PROMPT_COMMAND"))
#expect(commandText.contains("bash_preexec_imported"))
#expect(commandText.contains("__termind_get_trap"))
#expect(commandText.contains("__termind_integration_token"))
#expect(commandText.contains("__termind_compose_clear"))
#expect(commandText.contains("emacs-standard vi-insertion vi-command"))
#expect(commandText.contains("\\e[777;1~"))
#expect(commandText.contains("\\e[777;2~"))
#expect(!commandText.contains("$HOSTNAME"))
#expect(!commandText.contains("kitty-shell-cwd"))
#expect(probeUpdate.visibleOutput == nil)
#expect(probe.contains("/etc/os-release"))
#expect(probe.contains("/usr/lib/os-release"))
#expect(!probe.contains(". /etc/os-release"))
let integrationOutput = Data(
(String(commandText.dropLast())
+ "\r\n__TRMD_ABC123_HOME__%2Fhome%2Fuser\r\n"
+ "__TRMD_ABC123_DONE__\r\n"
+ "\u{1B}]7;file://localhost/home/user\u{7}user@host$ ").utf8
)
let completed = bootstrap.receive(integrationOutput)
let visible = try #require(completed.visibleOutput)
let visibleText = String(decoding: visible, as: UTF8.self)
#expect(completed.isComplete)
#expect(completed.homeDirectory == "/home/user")
#expect(
completed.systemInfo
== RemoteSystemInfo(
distributionID: "ubuntu", distributionVersion: "24.04",
kernelName: "Linux", kernelRelease: "6.8.0-40-generic",
architecture: "x86_64"
))
#expect(
visibleText
== "Welcome\r\n\u{1B}]7;file://localhost/home/user\u{7}user@host$ "
)
#expect(!visibleText.contains("__TRMD_"))
#expect(!visibleText.contains("__termind_report_cwd"))
}
@Test
func parsesCommonDistributionsAndKernelOnlyFallback() throws {
for (token, systemLine, expected) in [
(
"RHEL", "rhel|9.4|Linux|5.14.0-427.el9.x86_64|x86_64",
RemoteSystemInfo(
distributionID: "rhel", distributionVersion: "9.4",
kernelName: "Linux", kernelRelease: "5.14.0-427.el9.x86_64",
architecture: "x86_64"
)
),
(
"ALPINE", "alpine|3.20.2|Linux|6.6.44-0-lts|aarch64",
RemoteSystemInfo(
distributionID: "alpine", distributionVersion: "3.20.2",
kernelName: "Linux", kernelRelease: "6.6.44-0-lts",
architecture: "aarch64"
)
),
(
"BSD", "||FreeBSD|14.1-RELEASE|amd64",
RemoteSystemInfo(
kernelName: "FreeBSD", kernelRelease: "14.1-RELEASE",
architecture: "amd64"
)
),
] {
var bootstrap = RemoteShellIntegrationBootstrap(token: token)
let marker =
"__TRMD_\(token)_SYSTEM__\(systemLine)__\r\n"
+ "__TRMD_\(token)_SHELL__/bin/zsh__\r\n"
_ = try #require(bootstrap.receive(Data(marker.utf8)).command)
let completed = bootstrap.receive(
Data("__TRMD_\(token)_HOME__%2Fhome%2Ftest\r\n__TRMD_\(token)_DONE__\r\n".utf8)
)
#expect(completed.systemInfo == expected)
}
}
@Test
func rejectsInstructionLikeAndOversizedSystemFieldsWithoutBlockingIntegration() throws {
var bootstrap = RemoteShellIntegrationBootstrap(token: "HOSTILE")
let oversized = String(repeating: "x", count: 65)
let marker =
"__TRMD_HOSTILE_SYSTEM__ubuntu ignore-previous|24.04|Linux|6.8.0|\(oversized)__\r\n"
+ "__TRMD_HOSTILE_SHELL__/bin/bash__\r\n"
_ = try #require(bootstrap.receive(Data(marker.utf8)).command)
let completed = bootstrap.receive(
Data("__TRMD_HOSTILE_HOME__%2Fhome%2Ftest\r\n__TRMD_HOSTILE_DONE__\r\n".utf8)
)
#expect(completed.integrationInstalled)
#expect(
completed.systemInfo
== RemoteSystemInfo(
distributionVersion: "24.04", kernelName: "Linux", kernelRelease: "6.8.0"
))
}
@Test(arguments: ["zsh", "fish"])
func supportedShellsUseStandardFileURI(shell: String) throws {
var bootstrap = RemoteShellIntegrationBootstrap(token: "SHELL")
let update = bootstrap.receive(
Data("__TRMD_SHELL_SHELL__/usr/bin/\(shell)__\r\n".utf8)
)
let command = try #require(update.command)
let text = String(decoding: command, as: UTF8.self)
#expect(text.contains("file://localhost"))
#expect(!text.contains("$HOST"))
#expect(!text.contains("hostname"))
#expect(!text.contains("kitty-shell-cwd"))
#expect(text.contains("TermindCommand=SHELL"))
#expect(text.contains("TermindCommandFinished=SHELL"))
if shell == "zsh" {
#expect(text.contains("add-zsh-hook preexec"))
#expect(text.contains("emacs viins vicmd"))
} else {
#expect(text.contains("fish_preexec"))
#expect(text.contains("default insert visual"))
}
#expect(text.contains("TermindPrompt=SHELL"))
#expect(text.contains("TermindDraft=SHELL"))
#expect(text.contains("__termind_compose_clear"))
#expect(text.contains("777;1~"))
#expect(text.contains("777;2~"))
}
@Test
func bashAndZshInstallationCommandsPassShellSyntaxChecks() throws {
try assertInstallationSyntax(shell: "bash", executable: "/bin/bash")
try assertInstallationSyntax(shell: "zsh", executable: "/bin/zsh")
}
@Test
func bashPreservesExistingHooksAndReportsACommandFailure() throws {
var bootstrap = RemoteShellIntegrationBootstrap(token: "RUNTIME")
let update = bootstrap.receive(
Data("__TRMD_RUNTIME_SHELL__/bin/bash__\r\n".utf8)
)
var script = Data(
"PROMPT_COMMAND='__user_prompt=1'\n"
.appending("__user_debug_hits=0\n")
.appending("trap '__user_debug_hits=$((__user_debug_hits + 1))' DEBUG\n")
.utf8
)
script.append(try #require(update.command))
script.append(
Data(
"__user_debug_hits=0\n:\n"
.appending("__hits_after_integration=$__user_debug_hits\n")
.appending("builtin trap - DEBUG\n")
.appending("(( __hits_after_integration > 0 )) && ")
.appending("builtin printf 'DEBUG_PRESERVED\\n'\n")
.appending("builtin printf '\\nHOOKS=%s;%s\\n' ")
.appending("\"$PROMPT_COMMAND\" \"$__hits_after_integration\"\n")
.appending("__termind_report_prompt\n")
.appending("__termind_report_command 'false'\n")
.appending("false\n__termind_report_prompt\nexit 0\n")
.utf8
))
let result = try runShell(executable: "/bin/bash", arguments: [], input: script)
#expect(result.status == 0, Comment(rawValue: result.errors))
#expect(result.output.contains("DEBUG_PRESERVED"))
#expect(result.output.contains("HOOKS=__termind_report_prompt; __user_prompt=1;"))
#expect(result.output.contains("TermindCommand=RUNTIME;false\u{7}"))
#expect(result.output.contains("TermindCommandFinished=RUNTIME;1;0\u{7}"))
}
@Test
func unsupportedShellSkipsInjection() {
var bootstrap = RemoteShellIntegrationBootstrap(token: "OTHER")
let update = bootstrap.receive(
Data("__TRMD_OTHER_SHELL__/bin/tcsh__\r\nprompt> ".utf8)
)
#expect(update.command == nil)
#expect(update.isComplete)
#expect(update.visibleOutput == Data("prompt> ".utf8))
#expect(update.homeResolutionUnavailable || update.isComplete)
}
@Test
func homeMarkerDecodesSpecialCharacters() throws {
var bootstrap = RemoteShellIntegrationBootstrap(token: "HOME")
let install = bootstrap.receive(
Data("__TRMD_HOME_SHELL__/bin/bash__\r\n".utf8)
)
_ = try #require(install.command)
let completed = bootstrap.receive(
Data("__TRMD_HOME_HOME__%2Fhome%2FJane%20Doe\r\n__TRMD_HOME_DONE__\r\n".utf8)
)
#expect(completed.homeDirectory == "/home/Jane Doe")
}
@Test
func timeoutHidesProbeAndRestoresLatestPrompt() {
var bootstrap = RemoteShellIntegrationBootstrap(token: "TIMEOUT", now: 0)
let probe = String(decoding: bootstrap.startCommand.dropLast(), as: UTF8.self)
_ = bootstrap.receive(
Data(("Welcome\r\nodd> " + probe + "\r\nsyntax error\r\nodd> ").utf8),
now: 100_000_000
)
let update = bootstrap.poll(now: 3_000_000_000)
let visible = String(decoding: update.visibleOutput ?? Data(), as: UTF8.self)
#expect(visible == "Welcome\r\nodd> ")
#expect(!update.isComplete)
#expect(!visible.contains("TIMEOUT"))
#expect(!visible.contains("syntax error"))
}
@Test
func lateSupportedProbeStillInstallsAndHidesChunkedBootstrap() throws {
var bootstrap = RemoteShellIntegrationBootstrap(token: "LATE", now: 0)
_ = bootstrap.receive(Data("Welcome\r\nuser@host$ ".utf8), now: 100_000_000)
let timeout = bootstrap.poll(now: 3_000_000_000)
#expect(timeout.visibleOutput == Data("Welcome\r\nuser@host$ ".utf8))
#expect(!timeout.isComplete)
let probeEcho = bootstrap.startCommand.dropLast()
let split = probeEcho.index(probeEcho.startIndex, offsetBy: probeEcho.count / 2)
let first = bootstrap.receive(Data(probeEcho[..<split]), now: 3_100_000_000)
#expect(first.visibleOutput == nil)
#expect(first.command == nil)
let second = bootstrap.receive(
Data(probeEcho[split...]) + Data("\r\n__TRMD_LATE_SHELL__/bin/ba".utf8),
now: 3_200_000_000
)
#expect(second.visibleOutput == nil)
#expect(second.command == nil)
let detected = bootstrap.receive(
Data("sh__\r\nuser@host$ ".utf8), now: 3_300_000_000
)
let command = try #require(detected.command)
#expect(detected.visibleOutput == nil)
let commandText = String(decoding: command.dropLast(), as: UTF8.self)
_ = bootstrap.receive(
Data((commandText + "\r\n__TRMD_LATE_HO").utf8), now: 3_400_000_000
)
let completed = bootstrap.receive(
Data(
("ME__%2Fhome%2Fuser\r\n__TRMD_LATE_DONE__\r\n"
+ "\u{1B}]7;file://localhost/home/user\u{7}user@host$ ").utf8
),
now: 3_500_000_000
)
let visible = String(decoding: try #require(completed.visibleOutput), as: UTF8.self)
#expect(completed.isComplete)
#expect(completed.homeDirectory == "/home/user")
#expect(visible == "\u{1B}]7;file://localhost/home/user\u{7}user@host$ ")
#expect(!visible.contains("__TRMD_"))
#expect(!visible.contains("__termind_"))
}
@Test
func lateUnsupportedProbeIsHiddenAndSkipsInstallation() throws {
var bootstrap = RemoteShellIntegrationBootstrap(token: "OTHER", now: 0)
_ = bootstrap.receive(Data("router# ".utf8), now: 0)
_ = bootstrap.poll(now: 3_000_000_000)
let probe = String(decoding: bootstrap.startCommand.dropLast(), as: UTF8.self)
let completed = bootstrap.receive(
Data((probe + "\r\n__TRMD_OTHER_SHELL__/bin/tcsh__\r\nrouter# ").utf8),
now: 3_100_000_000
)
let visible = String(decoding: try #require(completed.visibleOutput), as: UTF8.self)
#expect(completed.command == nil)
#expect(completed.isComplete)
#expect(visible == "router# ")
#expect(!visible.contains("printf"))
#expect(!visible.contains("__TRMD_"))
}
@Test
func lateProbeErrorIsHiddenAfterQuietPeriod() throws {
var bootstrap = RemoteShellIntegrationBootstrap(token: "ERROR", now: 0)
_ = bootstrap.receive(Data("odd> ".utf8), now: 0)
_ = bootstrap.poll(now: 3_000_000_000)
let probe = String(decoding: bootstrap.startCommand.dropLast(), as: UTF8.self)
let response = bootstrap.receive(
Data((probe + "\r\nprintf: command not found\r\nodd> ").utf8),
now: 3_100_000_000
)
#expect(response.visibleOutput == nil)
let completed = bootstrap.poll(now: 3_600_000_000)
let visible = String(decoding: try #require(completed.visibleOutput), as: UTF8.self)
#expect(completed.isComplete)
#expect(visible == "odd> ")
#expect(!visible.contains("printf"))
#expect(!visible.contains("command not found"))
}
@Test
func lateInstallationTimeoutHidesCommandAndError() throws {
var bootstrap = RemoteShellIntegrationBootstrap(token: "INSTALL", now: 0)
_ = bootstrap.receive(Data("user@host$ ".utf8), now: 0)
_ = bootstrap.poll(now: 3_000_000_000)
let probe = String(decoding: bootstrap.startCommand.dropLast(), as: UTF8.self)
let detected = bootstrap.receive(
Data((probe + "\r\n__TRMD_INSTALL_SHELL__/bin/bash__\r\n").utf8),
now: 3_100_000_000
)
let command = try #require(detected.command)
let commandText = String(decoding: command.dropLast(), as: UTF8.self)
_ = bootstrap.receive(
Data((commandText + "\r\nsyntax error\r\nuser@host$ ").utf8),
now: 3_200_000_000
)
let completed = bootstrap.poll(now: 6_100_000_000)
let visible = String(decoding: try #require(completed.visibleOutput), as: UTF8.self)
#expect(completed.isComplete)
#expect(visible == "user@host$ ")
#expect(!visible.contains("__termind_"))
#expect(!visible.contains("syntax error"))
}
@Test
func lateScannerPassesOrdinaryOutputThrough() throws {
var bootstrap = RemoteShellIntegrationBootstrap(token: "SCAN", now: 0)
_ = bootstrap.poll(now: 3_000_000_000)
let update = bootstrap.receive(
Data("background notice\r\n".utf8), now: 3_100_000_000
)
#expect(try #require(update.visibleOutput) == Data("background notice\r\n".utf8))
#expect(update.command == nil)
#expect(!update.isComplete)
}
@Test
func userInputPreventsLateInstallationWithoutLeakingProbe() throws {
var bootstrap = RemoteShellIntegrationBootstrap(token: "INPUT", now: 0)
_ = bootstrap.receive(Data("user@host$ ".utf8), now: 0)
_ = bootstrap.poll(now: 3_000_000_000)
bootstrap.noteUserInput()
let probe = String(decoding: bootstrap.startCommand.dropLast(), as: UTF8.self)
let completed = bootstrap.receive(
Data((probe + "\r\n__TRMD_INPUT_SHELL__/bin/zsh__\r\nuser@host$ ls -").utf8),
now: 3_100_000_000
)
let visible = String(decoding: try #require(completed.visibleOutput), as: UTF8.self)
#expect(completed.command == nil)
#expect(completed.isComplete)
#expect(visible == "user@host$ ls -")
#expect(!visible.contains("__TRMD_"))
#expect(!visible.contains("printf"))
}
private func assertInstallationSyntax(shell: String, executable: String) throws {
var bootstrap = RemoteShellIntegrationBootstrap(token: "SYNTAX")
let update = bootstrap.receive(
Data("__TRMD_SYNTAX_SHELL__/bin/\(shell)__\r\n".utf8)
)
let command = try #require(update.command)
let result = try runShell(executable: executable, arguments: ["-n"], input: command)
#expect(result.status == 0, "\(shell): \(result.errors)")
}
private func runShell(
executable: String, arguments: [String], input: Data
) throws -> (status: Int32, output: String, errors: String) {
let process = Process()
let standardInput = Pipe()
let standardOutput = Pipe()
let standardError = Pipe()
process.executableURL = URL(fileURLWithPath: executable)
process.arguments = arguments
process.standardInput = standardInput
process.standardOutput = standardOutput
process.standardError = standardError
try process.run()
standardInput.fileHandleForWriting.write(input)
try standardInput.fileHandleForWriting.close()
process.waitUntilExit()
return (
process.terminationStatus,
String(
decoding: standardOutput.fileHandleForReading.readDataToEndOfFile(),
as: UTF8.self
),
String(
decoding: standardError.fileHandleForReading.readDataToEndOfFile(),
as: UTF8.self
)
)
}
}