Erik
Erik

Reputation: 5841

xcodebuild running tests headless?

As we all know by now, the only way to run tests on iOS is by using the simulator. My problem is that we are running jenkins and the iOS builds are running on a slave (via SSH), as a result running xcodebuild can't start the simulator (as it runs headless). I've read somewhere that it should be possible to get this to work with SimLauncher (gem sim_launcher). But I can't find any info on how to set this up with xcodebuild. Any pointers are welcome.

Upvotes: 3

Views: 3220

Answers (2)

Tad
Tad

Reputation: 151

Erik - I ended up doing the items documented here:

Essentially:

The first problem, is that you do have to have the user that runs the builds also logged in to the console on that Mac build machine. It needs to be able to pop up the simulator, and will fail if you don’t have a user logged in — as it can’t do this entirely headless without a display.

Secondly, the XCode Developer tools requires elevated privileges in order to execute all of the tasks on the Unit tests. Sometimes you may miss seeing it, but without these, the Simulator will give you an authentication prompt that never clears.

A first solution to this (on Mavericks) is to run:

sudo security authorizationdb write system.privilege.taskport allow

This will eliminate one class of these authentication popups. You’ll also need to run:

sudo DevToolsSecurity --enable

Per Apple’s man page on this tool:

On normal user systems, the first time in a given login session that any such Apple-code-signed debugger or performance analysis tools are used to examine one of the user’s processes, the user is queried for an administator password for authorization. DevToolsSecurity tool to change the authorization policies, such that a user who is a member of either the admin group or the _developer group does not need to enter an additional password to use the Apple-code-signed debugger or performance analysis tools.

Only issue is that these same things seem to be broken once I upgraded to Xcode 6. Back to the drawing board....

Upvotes: 2

Gardner Bickford
Gardner Bickford

Reputation: 1963

Headless and xcodebuild do not mix well. Please consider this alternative:

You can configure the slave node to launch via jnlp (webstart). I use a bash script with the .command extension as a login item (System Preferences -> Users -> Login Items) with the following contents:

#!/bin/bash

slave_url="https://gardner.company.com/jenkins/jnlpJars/slave.jar"

max_attempts=40 # ten minutes
echo "Waiting to try again. curl returneed $rc"
curl -fO "${slave_url}" >>slave.log
rc=$?
if [ $rc -ne 0 -a $max_attempts -gt 0 ]; then
  echo "Waiting to try again. curl returneed $rc"
  sleep 5
  curl -fO "${slave_url}" >>slave.log
  rc=$?
  if [ $rc -eq 0 ]; then
    zip -T slave.jar
    rc=$?
  fi
  let max_attempts-=1
fi

# Simulator
java -jar slave.jar -jnlpUrl https://gardner.company.com/jenkins/computer/buildmachine/slave-agent.jnlp -secret YOUR_SECRET_KEY

The build user is set to automatically login. You can see the arguments to the slave.jar app by executing:

gardner:~ buildmachine$ java -jar slave.jar --help
"--help" is not a valid option
java -jar slave.jar [options...]
 -auth user:pass                 : If your Jenkins is security-enabled, specify
                                   a valid user name and password.
 -connectTo HOST:PORT            : make a TCP connection to the given host and
                                   port, then start communication.
 -cp (-classpath) PATH           : add the given classpath elements to the
                                   system classloader.
 -jar-cache DIR                  : Cache directory that stores jar files sent
                                   from the master
 -jnlpCredentials USER:PASSWORD  : HTTP BASIC AUTH header to pass in for making
                                   HTTP requests.
 -jnlpUrl URL                    : instead of talking to the master via
                                   stdin/stdout, emulate a JNLP client by
                                   making a TCP connection to the master.
                                   Connection parameters are obtained by
                                   parsing the JNLP file.
 -noReconnect                    : Doesn't try to reconnect when a communication
                                   fail, and exit instead
 -proxyCredentials USER:PASSWORD : HTTP BASIC AUTH header to pass in for making
                                   HTTP authenticated proxy requests.
 -secret HEX_SECRET              : Slave connection secret to use instead of
                                   -jnlpCredentials.
 -slaveLog FILE                  : create local slave error log
 -tcp FILE                       : instead of talking to the master via
                                   stdin/stdout, listens to a random local
                                   port, write that port number to the given
                                   file, then wait for the master to connect to
                                   that port.
 -text                           : encode communication with the master with
                                   base64. Useful for running slave over 8-bit
                                   unsafe protocol like telnet

gardner:~ buildmachine$ 

For a discussion about OSX slaves and how the master is launched please see this Jenkins bug: https://issues.jenkins-ci.org/browse/JENKINS-21237

Upvotes: 2

Related Questions