From b588297bf646d5070521f0a31041f20c0d3063f6 Mon Sep 17 00:00:00 2001 From: Vitor Barbosa Date: Thu, 3 Dec 2020 19:00:52 -0300 Subject: [PATCH] Run tests using previously created simulator if possible This only applies if there is no destination configured on '.batler.yml'. If the stored simulator does not exist, a new one is created. If there is no simulator stored in cache, a new one is created. --- simctl/simulator.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/simctl/simulator.go b/simctl/simulator.go index 710da7f..c91967f 100644 --- a/simctl/simulator.go +++ b/simctl/simulator.go @@ -2,14 +2,22 @@ package simctl import ( "fmt" + "io/ioutil" "os" "os/exec" "strings" ) +const simulatorCacheFilename = "/tmp/batler-simulator" + // CreateSimulator creates an arbitrary iOS simulator from existing runtimes and devicetypes. // This method returns the identifier for the newly created simulator or an error, otherwise. func CreateSimulator(xcodePath string) (string, error) { + cachedSimulatorID, err := getSimulatorFromCache(xcodePath) + if err == nil { + return cachedSimulatorID, nil + } + runtimes, err := ListRuntimes(xcodePath) if err != nil { return "", fmt.Errorf("could not get runtimes: %w", err) @@ -34,6 +42,12 @@ func CreateSimulator(xcodePath string) (string, error) { } simulatorID := strings.TrimRight(string(output), "\r\n") + + if err := saveSimulatorOnCache(simulatorID); err != nil { + // TODO (vitor.araujo): replace fmt by logging + fmt.Printf("failed to cache simulator id: %v\n", err) + } + return simulatorID, nil } } @@ -41,6 +55,37 @@ func CreateSimulator(xcodePath string) (string, error) { return "", fmt.Errorf("could not create simulator from device types and runtimes") } +func saveSimulatorOnCache(simulatorID string) error { + return ioutil.WriteFile(simulatorCacheFilename, []byte(simulatorID), 0600) +} + +func getSimulatorFromCache(xcodePath string) (string, error) { + output, err := ioutil.ReadFile(simulatorCacheFilename) + if err != nil { + return "", fmt.Errorf("could not read cache file: %w", err) + } + + simulatorID := strings.TrimRight(string(output), "\r\n") + if !simulatorExists(simulatorID, xcodePath) { + return "", fmt.Errorf("cached simulator with ID=%s does not exist", simulatorID) + } + + return simulatorID, nil +} + +func simulatorExists(deviceID, xcodePath string) bool { + cmd := exec.Command("xcrun", "simctl", "list", "devices", deviceID) + cmd.Env = os.Environ() + cmd.Env = append(cmd.Env, fmt.Sprintf("DEVELOPER_DIR=%s", xcodePath)) + + output, err := cmd.Output() + if err != nil { + return false + } + + return strings.Contains(string(output), deviceID) +} + func createDeviceName(runtimeID, deviceTypeID string) string { runtimeIDParts := strings.Split(runtimeID, ".") osVersion := runtimeIDParts[len(runtimeIDParts)-1]