Re: Permission Denied trying to connect to localhost in unit test
Re: Permission Denied trying to connect to localhost in unit test
- Subject: Re: Permission Denied trying to connect to localhost in unit test
- From: Robert Walsh via Cocoa-dev <email@hidden>
- Date: Fri, 13 Dec 2019 19:40:10 +0000
- Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=envisionware.com; dmarc=pass action=none header.from=envisionware.com; dkim=pass header.d=envisionware.com; arc=none
- Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=0KI4PLEZ6xDLJPvMVYZ0wIZDLLiPYC1NhdDEgZscgp4=; b=cr82zML4aCgihJi0qOAialdf3zAcAElPhUyzYFi/D0gnywnK68w9vy5f5ZD3nbF/Zr1LtzYLUlG6vkLdnYSIADM/v/L6SxEOmtmMbusWlg8VUhd298ypOXpyFl9Mnx4fl59yP07Nu7VbHrSlhcmtwobyyRn2D2t7UJ45Qqvnl/xvI2Uh4bC5mMIg/P1fNx9RVPXLUULClEebYAuDyG1/yHMCCiDCOcJryCrRtGUR5oWB+IMvCeTPvSIVNr4647Pfki+N6RQXQ6C6ZlUKljlf3L3rvlTRJaREYWGZaDvyxOfEmtH+jhlG6zCArgxbAsDiFP4tx0BwCQfIFdM5OJGzGQ==
- Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=eOCfb3KJH0tDcA0/MU9cecKUR4WU/2bSvJ9ApjdVcwMYtIaw1wdW+Qlg0ipZ++yrJa0tuP06h2umr3xsh2ZbqOXn0/MUe363qQaMYWUf6u51GEnut0PNcHWbkOaUvJs8NBIbxGFcknmqnMndpPIrhWTmExA/aQaWymYbhGwy/A9IeOCyyC9iW824M4iPttii/PBjBL8SZE23CUFcO5Fa9w5jeOZMzsnQDg/9hTx/BXLoGp5gVCWxXMsboQqHsQQBpl1AEOFbVqAqx6op++kr//GwjRgiaZMpqKonZ+humcFvZI1XqrxeI2KRKJt91NQZi/hxPeuzdEq7+RmDRIwW3w==
- Thread-topic: Permission Denied trying to connect to localhost in unit test
>> Is it an https/http error?
No, this is a simple tcp socket intended to send and receive plain text.
>> Yes, you would create a new test target and add all the GUI stuff as a
>> member of the test target...
I have created a dummy GUI app, and I made the TcpClient a property of the
AppDelegate. In applicationDidFinishLaunching, I instantiate the property, and
in applicationWillTerminate, I set the property back to nil.
In the test case, I first start the tcp server thread (and wait until it is
ready to accept connections), then I get a reference to the property:
AppDelegate *appDelegate = (AppDelegate *)[[NSApplication sharedApplication]
delegate];
TcpClient *tcpClient = appDelegate.tcpClient;
I check to see that the tcpClient is initially not connected, then I try to
connect to the tcp server on local host and confirm that the client is
connected.
Initially, the server could not bind the listen socket because the dummy GUI
app's capabilities block did not include the entitlements for allowing incoming
and outgoing connections, so I enabled both and reran the tests. This time,
the client connection failed with Permission Denied just as it did with the
unit tests targeting the command line tool directly. I then removed the
capabilities block entirely from the dummy GUI app, and reran the tests; again,
the server started but the client failed to connect.
It is interesting to me that changing the entitlements on the dummy GUI app to
allow or disallow incoming connections _does_ impact whether the server is
allowed to bind the listening socket, but it does not seem to impact whether
the client is allowed to connect. (Further the error for failing to bind the
listen socket is Operation Not Permitted [errno 1], not Permission Denied.)
Also the results are the same whether I configure the dummy GUI app to link to
a static library containing the TcpClient class or remove the link and include
the TcpClient.m source as a compile target in the dummy GUI app.
As I said earlier, I will move forward without explicit unit tests for this
TcpClient. Thanks to all who offered suggestions. I also filed a report with
the Feedback Assistant (FB7492819).
Rob
________________________________
From: Keary Suska <email@hidden>
Sent: Friday, December 13, 2019 12:58 PM
To: Robert Walsh <email@hidden>
Cc: Cocoa-Dev (Apple) <email@hidden>
Subject: Re: Permission Denied trying to connect to localhost in unit test
Yes, you would create a new test target and add all the GUI stuff as a member
of the test target. Of course, you will want to exclude them from other
targets. You shouldn’t need to do any library linking since it is a common
codebase. Simply include the classes and put the glue code in the App Delegate.
Keary Suska
Esoteritech, Inc.
> On Dec 13, 2019, at 7:35 AM, Robert Walsh via Cocoa-dev
> <email@hidden> wrote:
>
> Thanks - I just finished doing that. I stubbed out a simple main that has
> enough smarts to use this TcpClient the way it will be used in the real app,
> and I was able to connect to an instance of the server to which the command
> line tool needs to connect. This server is running on another machine, not
> on localhost. I was able to make this connection without needing to grant
> any entitlements to the command line tool, so the problem occurs only when
> trying to run the unit test. In short, the unit test case is allowed to
> start a server and accept connections (from telnet, for example), and the
> class being tested is allowed to connect to an external server when not being
> run within the test case. So far, though, the class being tested cannot
> connect to the server when both are used inside the test case.
>
> I can probably move forward by testing this particular class the old
> fashioned way through manual inspection and then mocking it in other classes
> where it will be used.
>
> If, though, I want to go the dummy test app route, would I create another
> target that is a GUI app, either link to a static library containing the
> testable classes or include them as compile targets, and then create a unit
> test bundle that targets that GUI app?
>
> Rob
>
>
> ________________________________
> From: Keary Suska <email@hidden>
> Sent: Friday, December 13, 2019 12:18 PM
> To: Robert Walsh <email@hidden>
> Cc: Cocoa-Dev (Apple) <email@hidden>
> Subject: Re: Permission Denied trying to connect to localhost in unit test
>
> I would first test to see if you can access networking at all—i.e. connect to
> a public HTTP server and see if it works. If it doesn’t, then you are
> probably running against the entitlements issue. I suspect that the “dummy
> target” indicated is simply a GUI app wrapper built just for testing but not
> for deployment. Should be easy enough because it doesn’t have to do anything
> in the GUI.
>
> Keary Suska
> Esoteritech, Inc.
>
>
>> On Dec 13, 2019, at 4:42 AM, Robert Walsh via Cocoa-dev
>> <email@hidden> wrote:
>>
>> The errno is 13 (which I think is just a generic Permission Denied).
>>
>> I am connecting to localhost.
>>
>> I did find this post in the Apple Developer Forums
>> (https://forums.developer.apple.com/thread/52211):
>> How do I unittest a command line application? |Apple Developer
>> Forums<https://forums.developer.apple.com/thread/52211>
>> Yes, you can add the unit testing bundle, but it won't let you set Target to
>> be Tested.. Right. That’s because the machinery to load your test bundle
>> within a process only works if the process is based on a GUI framework (like
>> Cocoa or Cocoa Touch).
>> forums.developer.apple.com
>>
>>
>> A command line tool typically does not use a GUI framework and thus the test
>> machinery is unable to load your bundle into that tool.
>>
>> However, you can test without an app target. If you set the Target to be
>> Tested popup to None, Xcode will load your test bundle into its built-in
>> ‘test runner’ tool, xctest.
>>
>> This works well for most but there are some gotchas. Specifically, if the
>> code you’re using requires entitlements then you won’t be able to test it
>> like this because there’s no way to give those entitlements to xctest. The
>> standard workaround for that is to add a dummy test target app to your
>> project.
>>
>>
>> Assuming the problem is that I need to add the App Sandbox -> Outgoing
>> Connections (Client) entitlement to the command line target (since I can't
>> add any entitlements to the test target; clicking "+ Capabilities" brings up
>> a dialog saying that capabilities are not support for this target), how do I
>> create "a dummy test target app?" As I said before, I created the test
>> target by using the Unit Test Bundle template, and I don't see any other
>> relevant choices.
>>
>>
>> Rob
>>
>>
>> ________________________________
>> From: Jens Alfke <email@hidden>
>> Sent: Thursday, December 12, 2019 1:58 PM
>> To: Robert Walsh <email@hidden>
>> Cc: Cocoa-Dev (Apple) <email@hidden>
>> Subject: Re: Permission Denied trying to connect to localhost in unit test
>>
>>
>>
>> On Dec 12, 2019, at 7:42 AM, Robert Walsh via Cocoa-dev
>> <email@hidden<mailto:email@hidden>> wrote:
>>
>> I am writing a command line application in Objective-C that needs to make a
>> TCP connection to a server. In a unit test for the TcpClient class I am
>> writing, I have a simple TCP server that listens for connections in a
>> thread. When I try to connect to this socket from the client socket class,
>> connect() fails and perror reports Permission Denied.
>>
>> That's odd. I've written plenty of macOS networking code and not seen this
>> problem. What is the errno value?
>>
>> The only thing I can guess is that the Xcode test-runner process is being
>> sandboxed to prevent outgoing networking, but I've definitely run TCP
>> connections from XCTests without problems. Are you connecting to "localhost"
>> / 127.0.0.1, or using an explicit IP address?
>>
>> —Jens
>> _______________________________________________
>>
>> Cocoa-dev mailing list (email@hidden)
>>
>> Please do not post admin requests or moderator comments to the list.
>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>>
>> Help/Unsubscribe/Update your Subscription:
>>
>> This email sent to email@hidden
>
> _______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden