2

I'm trying to automate the functional testing I have in my project. For this, I use Jenkins and run the test tasks using the post-receive git hook. The job is properly invoked, but before the tests are run, I need to erase the simulators in order to tests first time startup of the app. I do the following:

#!/bin/bash --login

# simulator we want
sim="iPhone 6"

# close the iOS simulator if open
echo "Trying to close iOS Simulator"
osascript -e 'tell app "iOS Simulator" to quit'

# find all booted devices
booted=( $(xcrun simctl list | sed -n 's/.*(\(.*\)) (Booted)/\1/p') )
if [ ${#booted[@]} != 0 ]; then
    echo 'Found the following booted devices:'
    for device in ${booted[@]}
    do
        echo $device
    done
else
    echo 'There are no booted devices, skipping'
fi

# shutdown all of them to be able to erase them
for device in ${booted[@]}
do
    echo "Trying to shutdown $device"
    xcrun simctl shutdown $device
    echo "Done"
done

# sanity check, all devices should be shutdown
booted=( $(xcrun simctl list | sed -n 's/.*(\(.*\)) (Booted)/\1/p') )
if [ ${#booted[@]} != 0 ]; then
    echo 'Even though we shut down all the devices, some devices are still booted:'
    for device in ${booted[@]}
    do
        echo $device
    done
    exit 1
fi  

# erase the device so we can test index page and tutorial
allDevices=( $(xcrun simctl list | sed -En 's/.* \((.*)\) \((Shutdown)\)/\1/p') )
for device in ${allDevices[@]}
do
    echo "Erasing device $device"
    xcrun simctl erase $device
    echo
done

# sanity check, all devices should be shutdown
booted=( $(xcrun simctl list | sed -n 's/.*(\(.*\)) (Booted)/\1/p') )
if [ ${#booted[@]} != 0 ]; then
    echo 'Even though we shut down all the devices, some devices are still booted:'
    for device in ${booted[@]}
    do
        echo $device
    done
    exit 1
fi

echo device list:
echo $(xcrun simctl list)

dev=( $(xcrun simctl list | sed -En 's/'"$sim"' \((.*)\) \((Shutdown)\)/\1/p') )
echo Booting the device $dev
xcrun simctl boot $dev

# clean is not good enough, need to remove DerivedData contents manually
rm -rf ~/Library/Developer/Xcode/DerivedData

/usr/local/bin/xctool -workspace MyApp.xcworkspace -scheme MyApp_QA2 clean

xcodebuild -workspace MyApp.xcworkspace -scheme MyApp_QA2 -destination 'platform=iOS Simulator,name=iPhone 6,OS=8.1' test | xcpretty -c -r html

When I run this, I get:

Unable to boot booted device

These lines are responsible for booting:

dev=( $(xcrun simctl list | sed -En 's/'"$sim"' \((.*)\) \((Shutdown)\)/\1/p') )
echo Booting the device $dev
xcrun simctl boot $dev

So, I comment them, but then the build fails with:

2015-03-10 09:56:13.036 xcodebuild[84840:4008451] [MT] iPhoneSimulator: Unable to connect to "com.apple.instruments.deviceservice.lockdown" (Error Domain=com.apple.CoreSimulator.SimError Code=146 "Unable to lookup in current state: Shutdown" UserInfo=0x7fbcb2f00af0 {NSLocalizedDescription=Unable to lookup in current state: Shutdown})

Looks to me like Xcode and simctl can't agree which one should be responsible for booting the correct sim. Any ideas?

lawicko
  • 7,246
  • 3
  • 37
  • 49

2 Answers2

1

In Xcode 6 and Xcode 7, Simulator.app is responsible for booting the device it uses. If you use simctl to boot the device, it will not be usable by Simulator.app in that state because it will be booted to a headless state.

Jeremy Huddleston Sequoia
  • 22,938
  • 5
  • 78
  • 86
1

You can launch the simulator with xcrun instruments -w "iPhone 5 (8.4 Simulator)" and to shut down the simulator with killall "iOS Simulator"