Unit test SwiftData migrations

I'm trying to write a unit test for a SwiftData migration. In the teardown function I delete the SQLite container files, but then the underlying sqlite library complains.

There must be a way to gracefully terminate the SwiftData container before I delete the files, but I don't see how. Simplying nil-ifying the references doesn't work. I don't see any obvious close functions, so I hope someone knows a non-obvious function.

override func tearDownWithError() throws {
    // Cleanup resources
    // -- DOES NOT CLOSE UNDERLYING SQLITE ACCESS --
    self.container = nil
    self.context = nil
    
    // Delete database
    do {
        try FileManager.default.removeItem(at: self.url)
    }
    catch {
        // Ignore file not found, report everything else.
        let nserror = error as NSError
        if nserror.domain != "NSCocoaErrorDomain" && nserror.code == 4 {
            throw error
        }
    }
    try? FileManager.default.removeItem(at: self.url.deletingPathExtension().appendingPathExtension("store-shm"))
    try? FileManager.default.removeItem(at: self.url.deletingPathExtension().appendingPathExtension("store-wal"))
}

I get these errors for .store, store-shm, and .store-wal:

BUG IN CLIENT OF libsqlite3.dylib: database integrity compromised by API violation: vnode unlinked while in use: /Users/(ME)/Library/Developer/XCTestDevices/C52F4E12-EB4F-4639-9866-C3A7126155FA/data/Containers/Data/Application/B0EE90C6-B95D-4185-890D-6F20766B9B3B/tmp/test1.store
invalidated open fd: 11 (0x11)

If the worst comes to the worst, I'll work around it by using a differently-named container for each test, but as they're in tmp they'll get cleaned up for me eventually.

Replies

  • I'm not familiar with how one bridges CoreData with SwiftData, so I'm at a loss how to make use of it. It's an instance function, and the init requires a NSManagedObjectModel, not an @Model.

  • I missed it was swift data.

Add a Comment