How to access files when running XCTests in Ventura. Currently I receive "unauthorised access" errors.

Hi, I have an extensive macOS test suite that accesses a lot of files located on an external volume (several Tbytes of databases, images,...). After moving to Ventura this test suite is broken. More specifically, when trying to access .sqlite databases I receive a SQL error 23: unauthorised access. This is just the symptom of the fact that I do not seem to have the access rights on those files from the test suite. I verified that by moving such a .sqlite file to /tmp, it opens fine and the corresponding test succeeds. I tried fixing those rights by giving Full Disk Access (FDA) to Xcode, to xctest...but the problem persists.

Anyone out there having the same issue that found a fix ?

I should add that this test suite is associated with a framework (Swift package) and I have no Xcode project associated with it...just a plain Package.swift file. So I can't really fiddle with project level settings.

They surely must exist a way to access any file from a test suite even if it is located on an external disk, etc...

Thanks

Matthieu

Replies

Before we start, read On File System Permissions for some important background.

My preferred solution for this is to put your unit test data in a place that’s not protected by MAC. In this case, however, that’s unavoidable.

My next preferred option is to run your unit tests within your app. You can then grant the required TCC privileges to your app and away you go. Sadly, that doesn’t look like an option here either.

Finally, you need to locate the process doing the access and grant it the necessary TCC privilege. For the first step, I usually do that by adding a dummy test that simple logs the main executable of the process running it.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hello Thanks a lot for the quick answer and for the document.

The last option is my preferred one, as you'd imagine. However I am a bit confused by the result. I created a dummy test and printed out the Bundle.main.executablePath only to find out that it was /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/Agents/xctest. Isn't that the expected outcome? I had added xctest to the Full Disk Access list in System Preferences already but I am still not able to access those files. Am I missing something from your instructions ? Regards Matthieu

Isn’t that the expected outcome?

Oooo, negative questions are hard to answer in English (-:

I ran a quick test of a regular app on macOS 13. Granting Full Disk Access to the app avoids the need for Files and Folders > Removable Volume. So this problem is somehow related to xctest.

I then retried using a Swift package. Specifically, I created a simple package:

% swift package init

and modified the test like so:

% cat Tests/TestTests/TestTests.swift 
import XCTest
@testable import Test

final class TestTests: XCTestCase {

    func testExample() throws {
        let url = URL(fileURLWithPath: "/Volumes/TCCTestRemovable/test.txt")
        let d = try Data(contentsOf: url)
        print("count:", d.count)
    }
}

where TCCTestRemovable is a removable volume. Running this test from Terminal works:

% swift test
…
count: 14

That’s because Terminal on my Mac has the Files and Folders > Removable Volumes privilege. In TCC parlance, Terminal in the responsible code for any programs you run from the shell. If I remove that privilege, the test fails:

% swift test
…
/Users/quinn/Test/Tests/TestTests/TestTests.swift:8: error: -[TestTests.TestTests testExample] : failed: caught error: "Error Domain=NSCocoaErrorDomain Code=257 "The file “test.txt” couldn’t be opened because you don’t have permission to view it." UserInfo={NSFilePath=/Volumes/TCCTestRemovable/test.txt, NSUnderlyingError=0x600002491e00 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}"
Test Case '-[TestTests.TestTests testExample]' failed (0.324 seconds).
…

Are you running your tests from Terminal? Or Xcode?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

hello again, Thanks for your experiment and answer. Sorry for my negative question ;-)

I did run my tests in Xcode. I tried in Terminal and it works...although in my case, the ability to review the test outputs in Xcode is invaluable because I have about 1800 tests in this package.

So I tried your second option:

  • I created a macOS app project next to my package. I call it <Package>Tester
  • I added the package to test as a local package by dragging the package folder in the Xcode sidebar (see below)
  • I added my tests to the app test node by dragging the folder containing all my test classes in the sidebar. I had to choose to add that folder as a Group. I would have preferred to add it as a Reference but Xcode does not find the test classes when using Reference. It's a shame, but I can live with that. I simply have to make sure that I add new test classes from the new <Package>Tester app and not from the package. (The package will sync when new classes are added)
  • I made my project compile by tweaking a few things but not much
  • When launching the tests for the first time, I get the prompt for the "Tester" app to access Removable volumes. From there it works fine.

I suspect that something has changed in Ventura, maybe Monterey because I could run this test suite from Xcode, while working in the package. Maybe the xctest is the culprit. Adding TCC privileges to xctest does not work anymore

Thanks for your great assistance with this.

I add the layout of my Xcode project for reference below:

Sorry for my negative question ;-)

Sorry for using a language where there’s no way to answer negative questions reliably (-:

When launching the tests for the first time, I get the prompt for the "Tester" app to access Removable volumes.

Right, because in that case you’re running your unit test within the Tester app. This is controlled by the Host Application popup in the General tab of your test target. If it’s set to None, the tests run in the Xcode test runner (in this caes, xctest).


I did run my tests in Xcode.

OK. To continue the story from yesterday, I opened my Package.swift file in Xcode and ran my tests. The test failed with:

…/Tests/TestTests/TestTests.swift:8: error: -[TestTests.TestTests testExample] : failed: caught error: "Error Domain=NSCocoaErrorDomain Code=257 "The file “test.txt” couldn’t be opened because you don’t have permission to view it." UserInfo={NSFilePath=/Volumes/TCCTestRemovable/test.txt, NSUnderlyingError=0x600000c09f80 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}"

That makes some degree of sense:

  • Xcode has not been granted Files and Folders > Removable Volumes.

  • The test runner is executing in the background, so it doesn’t trigger the GUI prompt.

Anyway, to resolve this I added Xcode itself to Full Disk Access.

Coming back to the terms I defined in On File System Permissions, it seems that macOS 13 is smart enough to work out that Xcode is the responsible code for xctest.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

@eskimo Unfortunately, on MacOS 13, this problem still exists for my team. Any other suggestions? Full Disk Access is granted for gitlab-runner, Xcode and xctest.

You’ll have to be more specific about what “this problem” is. There’s a bunch of context up thread, and it’s not clear which of it applies to your specific situation.

My general advice is that you try to create a small test project (or package) that replicates the problem you’re seeing. That’ll yield one of two different results:

  • You are able to replicate the problem, in which case you can post the details here and I’ll take a look.

  • You’re not, in which case there’s something specific about your main project that’s causing the issue.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

No issues with official Xcode ie: 14.3.1, but FDA issues when running Xcode 15 Beta 5

...

As I'm falling in love with SPMs, I tend to write tests right in the SPM package.

These tests will run inprocess of /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/Agents/xctest. Just put a break point in your testXXX() and po Bundle.main.executablePath to verify.

Adding Xcode 15 Beta 5 to FDA did nothing, where Xcode 14.3.1 is not even on the FDA list.

Went back to 14.3.1 and my tests do work again. Peace.