2
votes

I have a local version of Jenkins installed on my machine, a Macbook Pro with El Capitan, which I use for development and debugging purposes, before pushing configurations to our CI builds.

Recently, I think since the upgrade to Xcode 8, we started getting this timeout error

iOSSimulator: Timed out waiting 120 seconds for simulator to boot, current state is 1.

The command to test is a simple enough xcodebuild,

xcodebuild clean test -scheme UnitTests -destination OS=9.3,name='iPhone 6' -sdk iphonesimulator -configuration Release ONLY_ACTIVE_ARCH=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES -enableCodeCoverage=YES

But for some reason recently, this error has started to pop up that's really affected being able to run a local version of this environment.

1
There are many potential causes for that particular error message. At the core, Xcode is launching Simulator.app, waiting for a distributed notification, then sending a distributed notification, then waiting for an XPC message from CoreSimulator.framework. This error message means that it either never got that distnote or never got the message from CoreSimulatorService. If you can take a sysdiagnose (sudo sysdiagnose -q) and file a radar with it and ~seaders/Library/Logs/CoreSimulator, I'd love to take a look.Jeremy Huddleston Sequoia
Note that Xcode 8.2 has some fixes to make CI much smoother for problems like these. We spent a bit of time triaging and fixing some of the causes for unreliable results in CI testing in the simulator (both genuine fixes for bugs as well as adding workarounds for other issues). Note that there is one issue in particular (ibtool hanging during a build) that is a kernel bug in El Cap and requires an upgrade of the host OS to Sierra to address.Jeremy Huddleston Sequoia
Hi @JeremyHuddlestonSequoia, thanks a lot for the replies, we're currently reworking our CI process to a more distributed approach and if we get this again, I'll definitely get a sysdiagnose and file a radar with the logs.seaders

1 Answers

2
votes

In my situation, it was nearly all to do with how I had Jenkins installed.

I initially installed Jenkins as a root process, in /Library/LaunchDaemons/org.jenkins.plist. In that config, it had my username under the UserName key, and running whoami showed that to be correct, but with how OSX runs Daemons vs. LaunchAgents was key here.

In that plist, I also had SessionCreate set to true, which is known to cause problems in situations like this.

This needs to be edited / explicitly set to "false" to be sure, <key>SessionCreate</key><false/>, also the user and group name keys should be checked to be the correct logged in user, in my situation all together, the start of my plist looks like,

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>UserName</key>
    <string>seaders</string>
    <key>GroupName</key>
    <string>staff</string>
    <key>SessionCreate</key>
    <false/>
    <key>EnvironmentVariables</key>
    <dict>
      <key>JENKINS_HOME</key>
      <string>/Users/Shared/Jenkins/Home</string>
    </dict>
    ...

For my situation, I needed to move that Jenkins configuration plist from root's LaunchDaemons into my own user's LaunchAgent directory,

$ # If jenkins is currently loaded from root, it needs unloading
$ sudo launchctl unload /Library/LaunchDaemons/org.jenkins.plist
$ sudo mv /Library/LaunchDaemons/org.jenkins.plist ~/Library/LaunchAgents/
$ # If jenkins had run under root, and used the regular log paths, we need to change the ownerships of a few places, my full command is
$ sudo chown -R seaders:staff ~/Library/LaunchAgents/org.jenkins.plist /var/log/jenkins/ /Users/Shared/Jenkins/Home
$ launchctl load ~/Library/LaunchAgents/org.jenkins.plist

The overall effect of this is Jenkins is truly run as your currently logged in user, the process is yours, the user and group names are yours, and you're explicitly telling it not to create a new session at all.

On top of that, when signing things with iOS, running things this way, you should no longer need to unlock the keychain, but if you do, this is the overly paranoid script we use with Jenkins,

$ security unlock-keychain -p ${USERPASS} ${HOME}/Library/Keychains/login.keychain
$ security list-keychains -s ${HOME}/Library/Keychains/login.keychain
$ security -v list-keychains -s ${HOME}/Library/Keychains/login.keychain
$ security list-keychains # so we can verify that it was added if it fails again
$ security -v unlock-keychain -p ${USERPASS} ${HOME}/Library/Keychains/login.keychain

But again, if you're running into keysign errors after setting up the machine as a development box correctly, which is allowed to sign apps, and Jenkins is truly running as your user, you shouldn't actually need to unlock the keychain any more.

Hope this helps others who've been going through this mobile CI hell.