NWListener fails with “Operation not permitted” in UI Testing Bundle

Hello,


I am currently struggling with a strange behaviour in an attempt of creating a NWListener.


Given I use some simple code like:

var listener: NWListener = try NWListener(using: .tcp, on: 12345)
listener.newConnectionHandler = connectionHandler
listener.stateUpdateHandler = stateUpdateHandler
listener.start(queue: .main)
dispatchMain()

(with declared connectionHandler as well as stateUpdateHandler), I successfully can open a listener when running the code in a "Command Line Tool" target.

Yet, when I attempt to run it in a "macOS U Testing Bundle", I receive a "nw_listener_socket_inbox_create_socket bind failed [1: Operation not permitted]" error.
The sandbox is not enabled on the project; adding com.apple.security.network.server to the entitlements did not help though.

Does anybody know if this has to do with restrictions of the UI testing bundle / XCUITest or -better- how to solve this?

Best,
Chris

Accepted Reply

Does anybody know if this has to do with restrictions of the UI testing bundle … ?

It does. UI test bundles are, as the name suggests, bundles, not standalone apps. These bundles are actually executed by a test runner app, currently called ***-Runner.app, where *** is the test target name. When you run a test, Xcode copies an internal template it has for this runner, embeds your test bundle into that, and then runs it.

The problem here is that this runner does not have any entitlements, and specifically it does not have the

com.apple.security.network.server
entitlement, and thus can’t listen for incoming connections [1].

The solution is to add that entitlement to your UI test bundle [2]. Normally you add entitlements via Xcode’s shiny Capabilities editor, but this is not enabled for a UI test bundle [3]. Rather, you must manually create a

.entitlements
file and then reference it in the Code Signing Entitlements (
CODE_SIGN_ENTITLEMENTS
) build setting of the UI test bundle target. Xcode will then merge those entitlements in to the test runner as part of the build process.

I tried this out here in my office (using Xcode 10.1) and it seems to work a treat.

Two final things to note:

  • Feel free to file an enhancement request against Xcode for a better way to set this up. Manually editing

    .entitlements
    file is not fun.

    Please post your bug number, just for the record.

  • The above is all about UI test bundles. Unit test bundles are a different *****. I’ve talked about this elsewhere on DevForums [4], but I’m calling it out here to head off any confusion between the two cases.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

[1] Curiously, the default test runner setup does include the

com.apple.security.network.client
entitlement.

[2] Strictly speaking, entitlements can only be applied to apps and app extensions. Bundles do not have entitlements, but rather inherit their entitlements from the process which loads them. What’s actually going on here is that Xcode has a special case where it applies the UI test bundle’s entitlements to the test runner as part of the build process.

[3] This is understandable given the previous footnote, but it’s still bugworthy (-:

[4] For example, this post. Be aware that the specific issue covered in that thread was resolved a while back, but the general suggestions in that post still apply.

Replies

Does anybody know if this has to do with restrictions of the UI testing bundle … ?

It does. UI test bundles are, as the name suggests, bundles, not standalone apps. These bundles are actually executed by a test runner app, currently called ***-Runner.app, where *** is the test target name. When you run a test, Xcode copies an internal template it has for this runner, embeds your test bundle into that, and then runs it.

The problem here is that this runner does not have any entitlements, and specifically it does not have the

com.apple.security.network.server
entitlement, and thus can’t listen for incoming connections [1].

The solution is to add that entitlement to your UI test bundle [2]. Normally you add entitlements via Xcode’s shiny Capabilities editor, but this is not enabled for a UI test bundle [3]. Rather, you must manually create a

.entitlements
file and then reference it in the Code Signing Entitlements (
CODE_SIGN_ENTITLEMENTS
) build setting of the UI test bundle target. Xcode will then merge those entitlements in to the test runner as part of the build process.

I tried this out here in my office (using Xcode 10.1) and it seems to work a treat.

Two final things to note:

  • Feel free to file an enhancement request against Xcode for a better way to set this up. Manually editing

    .entitlements
    file is not fun.

    Please post your bug number, just for the record.

  • The above is all about UI test bundles. Unit test bundles are a different *****. I’ve talked about this elsewhere on DevForums [4], but I’m calling it out here to head off any confusion between the two cases.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

[1] Curiously, the default test runner setup does include the

com.apple.security.network.client
entitlement.

[2] Strictly speaking, entitlements can only be applied to apps and app extensions. Bundles do not have entitlements, but rather inherit their entitlements from the process which loads them. What’s actually going on here is that Xcode has a special case where it applies the UI test bundle’s entitlements to the test runner as part of the build process.

[3] This is understandable given the previous footnote, but it’s still bugworthy (-:

[4] For example, this post. Be aware that the specific issue covered in that thread was resolved a while back, but the general suggestions in that post still apply.

Dear eskimo,
thank you very much for the fast and comprehensive answer!
Indeed, what puzzled me was that the client worked without problems. So I was not all wrong about the entitlements, just did try it at the wrong end - so let's check out if I can manage to achieve this... :-) I'm currently still all-new to XCode (so it's not only XCode's "fault"), but depending on how easy it goes, I'll file the mentioned enhancement request.
Edit: Tried it out and now works fine - many thanks again! And indeed, I would like to remove this impediment for everybody else. Just thinking about what the best solution could be - add the .server entitlement to the defaults as currently the .client one is? Reveal the capabilities editor also to the UI testing bundle, though it's precisely not valid?
Best,
Chris

I’m glad to hear that you got this working.

Reveal the capabilities editor also to the UI testing bundle … ?

That’s what makes most sense to me, because it’d cover this case and many others. Still, when filing an ER it’s not necessary to give a concrete design. It’s fine to file an ER that says “This is painful, please make it less so”, and then offer some vague suggestions.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

> Please post your bug number, just for the record.

I opened a bug, its problem iD is 49329954. Thanks again!