test(persistence): remove bundled migration fixtures

This commit is contained in:
Kaede Akino committed 2026-10-16 20:15:25 +08:00
1 parent 9da4b350cf
commit 672b68d2da
8 files changed
-237

No files matched your search

-11
View File
@@ -1,11 +0,0 @@
# Original-module SwiftData stores
V1.store and V14.store were generated from the original `Termind` app module
before extracting `TermindPersistence`. They contain only synthetic data: a
fixed-ID host group and, in V1, a legacy provider. SQLite's backup API copied
committed contents from the WAL into these self-contained fixtures.
Do not regenerate these fixtures using the extracted models: that would stop
checking compatibility across the original and framework module identities.
The source revision is recorded below.
726a2eb909adba3ced6a507c4704886f787e5f66
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -4,8 +4,6 @@ import TermindDomain
import TermindPersistence
import Testing
private final class FixtureBundle: NSObject {}
@Suite @MainActor
struct PersistenceCompatibilityTests {
@Test func version35DropsRetiredImporterTableAndPreservesNativeHistoryOnReopen() throws {
@@ -111,27 +109,6 @@ struct PersistenceCompatibilityTests {
#expect(SSHKeyRef(label: "").storage == .iCloud)
}
@Test(arguments: [1, 14])
func originalAppModuleStoresOpenWithoutLosingData(version: Int) throws {
let source = try #require(
Bundle(for: FixtureBundle.self).url(forResource: "V\(version)", withExtension: "store"))
let directory = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
defer { try? FileManager.default.removeItem(at: directory) }
let url = directory.appendingPathComponent("Termind.store")
try FileManager.default.copyItem(at: source, to: url)
let container = try TermindPersistence.makeContainer(url: url)
let groups = try container.mainContext.fetch(FetchDescriptor<PersistentHostGroup>())
#expect(groups.map(\.name) == ["Legacy fixture group"])
#expect(groups.first?.id == UUID(uuidString: "11111111-1111-1111-1111-111111111111"))
if version == 1 {
let providers = try container.mainContext.fetch(FetchDescriptor<PersistentModelProvider>())
#expect(providers.map(\.name) == ["Legacy fixture provider"])
}
#expect(try container.mainContext.fetchCount(FetchDescriptor<PersistentTerminalPreferences>()) == 0)
#expect(try container.mainContext.fetchCount(FetchDescriptor<PersistentMetricsSyncEntry>()) == 0)
}
@Test
func fileStoreReopensWithSharedModels() throws {
let directory = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
@@ -149,93 +126,6 @@ struct PersistenceCompatibilityTests {
try container.mainContext.save()
}
@Test
func version28FixtureMigratesAndReopensWithoutLosingData() throws {
let source = try #require(Bundle(for: FixtureBundle.self).url(forResource: "V28", withExtension: "store"))
let directory = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
defer { try? FileManager.default.removeItem(at: directory) }
let url = directory.appendingPathComponent("Termind.store")
try FileManager.default.copyItem(at: source, to: url)
try verifyVersion28Store(at: url)
try verifyVersion28Store(at: url)
}
private func verifyVersion28Store(at url: URL) throws {
let container = try TermindPersistence.makeContainer(url: url)
let context = container.mainContext
let snapshot = try HostPersistence(context: context).load()
let host = try #require(snapshot.hosts.first)
let identity = try #require(snapshot.identities.first)
let key = try #require(snapshot.keys.first)
let snippet = try #require(snapshot.snippets.first)
let installationID = UUID(uuidString: "66666666-6666-6666-6666-666666666666")!
#expect(snapshot.hosts.count == 1)
#expect(host.id == UUID(uuidString: "22222222-2222-2222-2222-222222222222"))
#expect(host.name == "V28 fixture host")
#expect(host.host == "legacy.example.invalid")
#expect(host.sshEnabled)
#expect(host.sshPort == 2222)
#expect(host.sshCharset == .gb18030)
#expect(!host.telnetEnabled)
#expect(host.telnetPort == 23)
#expect(host.telnetCharset == .utf8)
#expect(host.telnetIdentityID == nil)
#expect(host.sshIdentityID == identity.id)
#expect(host.groupID == snapshot.groups.first?.id)
#expect(snapshot.groups.map(\.name) == ["V28 fixture group"])
#expect(host.tags == ["legacy", "ssh"])
#expect(host.colorTag == .teal)
#expect(host.sortIndex == 2.5)
#expect(host.shellIntegrationMode == .disabled)
#expect(host.portForwardingMaxConnections == 3)
#expect(host.sftpChannelInitialPath == "/srv/legacy")
#expect(
host.environmentVariables == [
HostEnvironmentVariable(variable: "LANG", value: "zh_CN.GB18030"),
HostEnvironmentVariable(variable: "TERM", value: "xterm-256color"),
])
#expect(host.startupSnippetID == snippet.id)
#expect(snippet.body == "pwd")
#expect(snippet.targetHostIDs == [host.id])
#expect(identity.id == UUID(uuidString: "33333333-3333-3333-3333-333333333333"))
#expect(identity.username == "deploy")
#expect(identity.credentialRef == "termind.fixture.password")
#expect(identity.passwordStorage == .thisDevice)
#expect(identity.keyID == key.id)
#expect(identity.notes == "Synthetic fixture")
#expect(identity.colorTag == .purple)
#expect(key.id == UUID(uuidString: "44444444-4444-4444-4444-444444444444"))
#expect(key.label == "V28 fixture key")
#expect(
snapshot.knownHosts == [
KnownHostEntry(
id: UUID(uuidString: "77777777-7777-7777-7777-777777777777")!,
hostname: "legacy.example.invalid", port: 2222,
fingerprint: "SHA256:fixture", addedAt: Date(timeIntervalSince1970: 50))
])
try HistorySyncPersistence(context: context).prepare()
let history = try context.fetch(FetchDescriptor<PersistentConnectionHistoryEntry>()).map(\.value)
#expect(
history == [
ConnectionHistoryEntry(
id: UUID(uuidString: "55555555-5555-5555-5555-555555555555")!,
hostID: host.id, kind: .ssh, connectedAt: Date(timeIntervalSince1970: 90),
sourceDeviceID: installationID)
])
#expect(try context.fetch(FetchDescriptor<PersistentVaultSyncState>()).first?.installationID == installationID)
#expect(try context.fetch(FetchDescriptor<PersistentDeviceRecord>()).map(\.id) == [installationID])
let suite = "PersistenceV28.\(UUID())"
let defaults = try #require(UserDefaults(suiteName: suite))
defer { defaults.removePersistentDomain(forName: suite) }
let settings = SettingsSyncPersistence(context: context, defaults: defaults)
try settings.prepare()
#expect(try settings.loadWorkspacePreferences() == WorkspacePreferences())
}
@Test
func memoryContainersUseTheFullSchemaAndRemainIndependent() throws {
let first = try TermindPersistence.makeContainer(inMemory: true)
-71
View File
@@ -1,71 +0,0 @@
import Foundation
import SwiftData
import TermindDomain
import TermindPersistence
// V28.store source: 0dc173d4b1d190071d35bc66f80ebb767d8b950c (the parent of b0d35d24).
// Build that checkout's TermindPersistence scheme for macOS with -onlyUsePackageVersionsFromResolvedFile.
// Compile this generator with -parse-as-library, using that build's -F/-I products, GRDBSQLite module path,
// TermindPersistence/TermindDomain/TermindApplication frameworks, and AgentKit.o/Logging.o.
// Pass a new temporary store path, then use SQLite's backup API to produce the standalone fixture after exit.
// Never regenerate against current models. All data is synthetic; no password or private key is stored.
// Expected schema checksum: hh/HY7td7OFShC/UhxiuwAlJuf8IZOWsZm7U7VqLaSs=
@main
struct GenerateV28Fixture {
@MainActor
static func main() throws {
let url = URL(fileURLWithPath: CommandLine.arguments[1])
let schema = Schema(versionedSchema: TermindSchemaV28.self)
let container = try ModelContainer(
for: schema,
configurations: [ModelConfiguration("Termind", schema: schema, url: url, cloudKitDatabase: .none)])
let context = container.mainContext
let groupID = UUID(uuidString: "11111111-1111-1111-1111-111111111111")!
let hostID = UUID(uuidString: "22222222-2222-2222-2222-222222222222")!
let identityID = UUID(uuidString: "33333333-3333-3333-3333-333333333333")!
let keyID = UUID(uuidString: "44444444-4444-4444-4444-444444444444")!
let historyID = UUID(uuidString: "55555555-5555-5555-5555-555555555555")!
let installationID = UUID(uuidString: "66666666-6666-6666-6666-666666666666")!
let knownHostID = UUID(uuidString: "77777777-7777-7777-7777-777777777777")!
let snippetID = UUID(uuidString: "88888888-8888-8888-8888-888888888888")!
let host = TermindSchemaV28HostModels.PersistentHost(
Host(
id: hostID, name: "V28 fixture host", host: "legacy.example.invalid", port: 2222,
identityID: identityID, charset: .gb18030, groupID: groupID,
tags: ["legacy", "ssh"], colorTag: .teal, sortIndex: 2.5,
shellIntegrationMode: .disabled, startupSnippetID: snippetID,
environmentVariables: [
HostEnvironmentVariable(variable: "LANG", value: "zh_CN.GB18030"),
HostEnvironmentVariable(variable: "TERM", value: "xterm-256color"),
], portForwardingMaxConnections: 3))
host.sftpSessionInitialPath = "/srv/legacy"
host.lastUsedAt = Date(timeIntervalSince1970: 100)
context.insert(host)
context.insert(PersistentHostGroup(HostGroup(id: groupID, name: "V28 fixture group")))
context.insert(
PersistentIdentity(
Identity(
id: identityID, name: "V28 fixture identity", username: "deploy",
credentialRef: "termind.fixture.password", passwordStorage: .thisDevice,
keyID: keyID, notes: "Synthetic fixture", colorTag: .purple)))
context.insert(PersistentSSHKey(SSHKeyRef(id: keyID, label: "V28 fixture key")))
let knownHost = TermindSchemaV29KnownHostModels.PersistentKnownHost(
KnownHostEntry(
id: knownHostID, hostname: "legacy.example.invalid", port: 2222,
fingerprint: "SHA256:fixture", addedAt: Date(timeIntervalSince1970: 50)))
knownHost.isMismatched = true
context.insert(knownHost)
context.insert(
PersistentSnippet(
Snippet(id: snippetID, title: "V28 fixture snippet", body: "pwd", targetHostIDs: [hostID])))
context.insert(
PersistentConnectionHistoryEntry(
ConnectionHistoryEntry(
id: historyID, hostID: hostID, kind: .ssh, connectedAt: Date(timeIntervalSince1970: 90))))
let state = PersistentVaultSyncState()
state.installationID = installationID
state.bootstrapCompleted = true
context.insert(state)
try context.save()
}
}
-33
View File
@@ -13,8 +13,6 @@ import UIKit
@testable import TermindIOS
private final class MobileMigrationFixtureBundle: NSObject {}
@Suite @MainActor
struct MobileAppTests {
private final class MetricsPreferences: MetricsConfigurationStoring {
@@ -52,37 +50,6 @@ struct MobileAppTests {
await app.tailscale.shutdown()
}
@Test func startupLoadsVersion28DataAfterMigrationAndRelaunch() throws {
let source = try #require(
Bundle(for: MobileMigrationFixtureBundle.self).url(forResource: "V28", withExtension: "store"))
let directory = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
defer { try? FileManager.default.removeItem(at: directory) }
let url = directory.appendingPathComponent("Termind.store")
try FileManager.default.copyItem(at: source, to: url)
let suite = "MobileMigrationV28.\(UUID())"
let defaults = try #require(UserDefaults(suiteName: suite))
defer { defaults.removePersistentDomain(forName: suite) }
for _ in 0..<2 {
var dependencies = MobileAppDependencies.testing(defaults: defaults)
dependencies.container = try TermindPersistence.makeContainer(url: url)
let app = try MobileAppModel(dependencies: dependencies)
defer { app.outbox.stop() }
let host = try #require(app.library.hosts.first)
#expect(host.name == "V28 fixture host")
#expect(host.sshCharset == .gb18030)
#expect(host.sshPort == 2222)
#expect(host.sshIdentityID == app.library.identities.first?.id)
#expect(app.library.identities.first?.credentialRef == "termind.fixture.password")
let history = app.connectionHistory.entries(for: host.id)
#expect(history.count == 1)
#expect(history.first?.sourceDeviceID == UUID(uuidString: "66666666-6666-6666-6666-666666666666"))
#expect(history.first?.endedAt == nil)
#expect(try app.hosts.snapshot().value.hosts == [host])
}
}
@Test func scenesCanUseTheSameAppRepository() throws {
let repository = InMemoryHostRepository()
let app = try MobileAppModel(hosts: repository)
-12
View File
@@ -85,7 +85,6 @@
D7D1BBB65020F61F7EFDDFD7 /* GhosttyTerminal in Frameworks */ = {isa = PBXBuildFile; productRef = TRMD00000000000000100012 /* GhosttyTerminal */; };
DEVK00000000000000000003 /* DeviceKit in Frameworks */ = {isa = PBXBuildFile; productRef = DEVK00000000000000000002 /* DeviceKit */; };
DEVK00000000000000000004 /* DeviceKit in Frameworks */ = {isa = PBXBuildFile; productRef = DEVK00000000000000000002 /* DeviceKit */; };
E28A00000000000000000002 /* V28.store in Resources */ = {isa = PBXBuildFile; fileRef = E28A00000000000000000001 /* V28.store */; };
E635C54CA9F1A63D909CFCE6 /* TermindPersistence.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 244632CCDB1CA43F45C0EB54 /* TermindPersistence.framework */; };
E9A6C576AF3870A1958F9C5A /* ETSession in Frameworks */ = {isa = PBXBuildFile; productRef = 6335BE33C2C5F92BE0568DF6 /* ETSession */; };
EF2F88E4809C845C3F1BBF63 /* TermindDomain.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A62058825D6607920F1E2A1 /* TermindDomain.framework */; };
@@ -492,7 +491,6 @@
BENC00000000000000000011 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
BENC00000000000000000012 /* termind-port-forwarding-benchmark */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "termind-port-forwarding-benchmark"; sourceTree = BUILT_PRODUCTS_DIR; };
DBE378B130478CFB00B16AA1 /* Termind.storekit */ = {isa = PBXFileReference; lastKnownFileType = text; name = Termind.storekit; path = StoreKit/Termind.storekit; sourceTree = "<group>"; };
E28A00000000000000000001 /* V28.store */ = {isa = PBXFileReference; lastKnownFileType = file; name = V28.store; path = FrameworkTests/Fixtures/V28.store; sourceTree = SOURCE_ROOT; };
F04700000000000000000011 /* TFMTests/SSHForwardingPumpTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TFMTests/SSHForwardingPumpTests.swift; sourceTree = SOURCE_ROOT; };
F04700000000000000000012 /* TFMTests/SSHForwardingWireTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TFMTests/SSHForwardingWireTests.swift; sourceTree = SOURCE_ROOT; };
F1BA00000000000000000020 /* Configuration/Firebase/GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Configuration/Firebase/GoogleService-Info.plist"; sourceTree = SOURCE_ROOT; };
@@ -847,14 +845,6 @@
path = Frameworks;
sourceTree = "<group>";
};
DB9666953064BA9A005FB585 /* Persistence Test Fixtures */ = {
isa = PBXGroup;
children = (
E28A00000000000000000001 /* V28.store */,
);
name = "Persistence Test Fixtures";
sourceTree = "<group>";
};
F04700000000000000000010 /* Forwarding Test Support */ = {
isa = PBXGroup;
children = (
@@ -881,7 +871,6 @@
BA4A4EAD7B8B3A380C9ED1C2 /* FrameworkTests */,
A102A7EA2C3532D7FA88B0A4 /* TFITests */,
F04700000000000000000010 /* Forwarding Test Support */,
DB9666953064BA9A005FB585 /* Persistence Test Fixtures */,
);
sourceTree = "<group>";
};
@@ -1449,7 +1438,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E28A00000000000000000002 /* V28.store in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};