test(persistence): remove bundled migration fixtures
This commit is contained in:
1 parent
9da4b350cf
commit
672b68d2da
8 files changed
-237
No files matched your search
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user