| Index: infra/bots/recipes/swarm_test.expected/missing_SK_IMAGE_VERSION_device.json
 | 
| diff --git a/infra/bots/recipes/swarm_test.expected/missing_SK_IMAGE_VERSION_device.json b/infra/bots/recipes/swarm_test.expected/missing_SK_IMAGE_VERSION_device.json
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..901c90d276b99b04652ac66cbd261c8cd596d700
 | 
| --- /dev/null
 | 
| +++ b/infra/bots/recipes/swarm_test.expected/missing_SK_IMAGE_VERSION_device.json
 | 
| @@ -0,0 +1,791 @@
 | 
| +[
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "python",
 | 
| +      "-u",
 | 
| +      "[SLAVE_BUILD]/skia/tools/buildbot_spec.py",
 | 
| +      "/path/to/tmp/json",
 | 
| +      "Test-Android-GCC-Nexus7-GPU-Tegra3-Arm7-Debug"
 | 
| +    ],
 | 
| +    "cwd": "[SLAVE_BUILD]/skia",
 | 
| +    "name": "exec buildbot_spec.py",
 | 
| +    "~followup_annotations": [
 | 
| +      "@@@STEP_LOG_LINE@json.output@{@@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@  \"build_targets\": [@@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@    \"dm\", @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@    \"nanobench\"@@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@  ], @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@  \"builder_cfg\": {@@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@    \"arch\": \"Arm7\", @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@    \"compiler\": \"GCC\", @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@    \"configuration\": \"Debug\", @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@    \"cpu_or_gpu\": \"GPU\", @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@    \"cpu_or_gpu_value\": \"Tegra3\", @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@    \"is_trybot\": false, @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@    \"model\": \"Nexus7\", @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@    \"os\": \"Android\", @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@    \"role\": \"Test\"@@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@  }, @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@  \"configuration\": \"Debug\", @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@  \"device_cfg\": \"arm_v7_neon\", @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@  \"dm_flags\": [@@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@    \"--dummy-flags\"@@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@  ], @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@  \"do_perf_steps\": true, @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@  \"do_test_steps\": true, @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@  \"env\": {@@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@    \"GYP_DEFINES\": \"skia_arch_type=arm skia_warnings_as_errors=0\"@@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@  }, @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@  \"nanobench_flags\": [@@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@    \"--dummy-flags\"@@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@  ], @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@  \"product.board\": \"grouper\", @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@  \"upload_dm_results\": true, @@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@  \"upload_perf_results\": false@@@",
 | 
| +      "@@@STEP_LOG_LINE@json.output@}@@@",
 | 
| +      "@@@STEP_LOG_END@json.output@@@"
 | 
| +    ]
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "which",
 | 
| +      "adb"
 | 
| +    ],
 | 
| +    "name": "which adb",
 | 
| +    "stdout": "/path/to/tmp/",
 | 
| +    "~followup_annotations": [
 | 
| +      "step returned non-zero exit code: 1",
 | 
| +      "@@@STEP_EXCEPTION@@@"
 | 
| +    ]
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/skia/platform_tools/android/bin/adb_wait_for_device"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "ANDROID_HOME": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "ANDROID_SDK_ROOT": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_ANDROID_VERBOSE_SETUP": "1",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "wait for device (1)"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/skia/platform_tools/android/bin/adb_wait_for_charge"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "ANDROID_HOME": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "ANDROID_SDK_ROOT": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_ANDROID_VERBOSE_SETUP": "1",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "wait for charge (1)"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "shell",
 | 
| +      "echo",
 | 
| +      "$EXTERNAL_STORAGE"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "get EXTERNAL_STORAGE dir",
 | 
| +    "stdout": "/path/to/tmp/"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "root"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "adb root",
 | 
| +    "stdout": "/path/to/tmp/"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "sleep",
 | 
| +      "10"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "wait"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/skia/platform_tools/android/bin/adb_wait_for_device"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "ANDROID_HOME": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "ANDROID_SDK_ROOT": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_ANDROID_VERBOSE_SETUP": "1",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "wait for device (2)"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/skia/platform_tools/android/bin/adb_wait_for_charge"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "ANDROID_HOME": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "ANDROID_SDK_ROOT": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_ANDROID_VERBOSE_SETUP": "1",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "wait for charge (2)"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/skia/platform_tools/android/bin/android_kill_skia",
 | 
| +      "--verbose"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "ANDROID_HOME": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "ANDROID_SDK_ROOT": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_ANDROID_VERBOSE_SETUP": "1",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "kill skia"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "shell",
 | 
| +      "stop"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "stop shell"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "shell",
 | 
| +      "dumpsys",
 | 
| +      "batteryproperties"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "starting battery stats"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "shell",
 | 
| +      "cat",
 | 
| +      "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "cat scaling_governor"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "shell",
 | 
| +      "cat",
 | 
| +      "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "cat cpu_freq"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/skia/platform_tools/android/bin/adb_push_if_needed",
 | 
| +      "--verbose",
 | 
| +      "[SLAVE_BUILD]/skia/resources",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_resources"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "ANDROID_HOME": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "ANDROID_SDK_ROOT": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_ANDROID_VERBOSE_SETUP": "1",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "push resources"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "python",
 | 
| +      "-u",
 | 
| +      "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
 | 
| +      "[SLAVE_BUILD]/skia/infra/bots/assets/skp/VERSION",
 | 
| +      "/path/to/tmp/"
 | 
| +    ],
 | 
| +    "name": "Get downloaded SKP VERSION"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "python",
 | 
| +      "-u",
 | 
| +      "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
 | 
| +      "42",
 | 
| +      "[SLAVE_BUILD]/tmp/SKP_VERSION"
 | 
| +    ],
 | 
| +    "name": "write SKP_VERSION"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "shell",
 | 
| +      "cat",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_tmp_dir/SKP_VERSION"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "read SKP_VERSION",
 | 
| +    "stdout": "/path/to/tmp/"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "python",
 | 
| +      "-u",
 | 
| +      "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
 | 
| +      "[SLAVE_BUILD]/skia/infra/bots/assets/skimage/VERSION",
 | 
| +      "/path/to/tmp/"
 | 
| +    ],
 | 
| +    "name": "Get downloaded skimage VERSION"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "python",
 | 
| +      "-u",
 | 
| +      "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
 | 
| +      "42",
 | 
| +      "[SLAVE_BUILD]/tmp/SK_IMAGE_VERSION"
 | 
| +    ],
 | 
| +    "name": "write SK_IMAGE_VERSION"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "shell",
 | 
| +      "cat",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_tmp_dir/SK_IMAGE_VERSION"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "read SK_IMAGE_VERSION",
 | 
| +    "stdout": "/path/to/tmp/",
 | 
| +    "~followup_annotations": [
 | 
| +      "step returned non-zero exit code: 1",
 | 
| +      "@@@STEP_EXCEPTION@@@"
 | 
| +    ]
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "shell",
 | 
| +      "rm",
 | 
| +      "-f",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_tmp_dir/SK_IMAGE_VERSION"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "rm SK_IMAGE_VERSION"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "shell",
 | 
| +      "rm",
 | 
| +      "-r",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_images"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "rmdir skia_images"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "shell",
 | 
| +      "if",
 | 
| +      "[",
 | 
| +      "-e",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_images",
 | 
| +      "];",
 | 
| +      "then",
 | 
| +      "echo",
 | 
| +      "FILE_EXISTS;",
 | 
| +      "fi"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "exists skia_images",
 | 
| +    "stdout": "/path/to/tmp/"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "shell",
 | 
| +      "mkdir",
 | 
| +      "-p",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_images"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "mkdir skia_images"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/skia/platform_tools/android/bin/adb_push_if_needed",
 | 
| +      "--verbose",
 | 
| +      "[SLAVE_BUILD]/skimage",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_images"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "ANDROID_HOME": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "ANDROID_SDK_ROOT": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_ANDROID_VERBOSE_SETUP": "1",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "push skimage"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "push",
 | 
| +      "[SLAVE_BUILD]/tmp/SK_IMAGE_VERSION",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_tmp_dir/SK_IMAGE_VERSION"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "push SK_IMAGE_VERSION"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "python",
 | 
| +      "-u",
 | 
| +      "\nimport os, sys\nfrom common import chromium_utils # Error? See https://crbug.com/584783.\n\n\nif os.path.exists(sys.argv[1]):\n  chromium_utils.RemoveDirectory(sys.argv[1])\n",
 | 
| +      "[CUSTOM_[SWARM_OUT_DIR]]/dm"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "PYTHONPATH": "[SLAVE_BUILD]/skia/infra/bots/.recipe_deps/build/scripts"
 | 
| +    },
 | 
| +    "name": "rmtree dm",
 | 
| +    "~followup_annotations": [
 | 
| +      "@@@STEP_LOG_LINE@python.inline@@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@import os, sys@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@from common import chromium_utils # Error? See https://crbug.com/584783.@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@if os.path.exists(sys.argv[1]):@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@  chromium_utils.RemoveDirectory(sys.argv[1])@@@",
 | 
| +      "@@@STEP_LOG_END@python.inline@@@"
 | 
| +    ]
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "python",
 | 
| +      "-u",
 | 
| +      "\nimport sys, os\npath = sys.argv[1]\nmode = int(sys.argv[2])\nif not os.path.isdir(path):\n  if os.path.exists(path):\n    print \"%s exists but is not a dir\" % path\n    sys.exit(1)\n  os.makedirs(path, mode)\n",
 | 
| +      "[CUSTOM_[SWARM_OUT_DIR]]/dm",
 | 
| +      "511"
 | 
| +    ],
 | 
| +    "name": "makedirs dm",
 | 
| +    "~followup_annotations": [
 | 
| +      "@@@STEP_LOG_LINE@python.inline@@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@import sys, os@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@path = sys.argv[1]@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@mode = int(sys.argv[2])@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@if not os.path.isdir(path):@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@  if os.path.exists(path):@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@    print \"%s exists but is not a dir\" % path@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@    sys.exit(1)@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@  os.makedirs(path, mode)@@@",
 | 
| +      "@@@STEP_LOG_END@python.inline@@@"
 | 
| +    ]
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "shell",
 | 
| +      "rm",
 | 
| +      "-r",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_dm"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "rmdir skia_dm"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "shell",
 | 
| +      "if",
 | 
| +      "[",
 | 
| +      "-e",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_dm",
 | 
| +      "];",
 | 
| +      "then",
 | 
| +      "echo",
 | 
| +      "FILE_EXISTS;",
 | 
| +      "fi"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "exists skia_dm",
 | 
| +    "stdout": "/path/to/tmp/"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "shell",
 | 
| +      "mkdir",
 | 
| +      "-p",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_dm"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "mkdir skia_dm"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "python",
 | 
| +      "-u",
 | 
| +      "\nimport sys, os\npath = sys.argv[1]\nmode = int(sys.argv[2])\nif not os.path.isdir(path):\n  if os.path.exists(path):\n    print \"%s exists but is not a dir\" % path\n    sys.exit(1)\n  os.makedirs(path, mode)\n",
 | 
| +      "[SLAVE_BUILD]/tmp",
 | 
| +      "511"
 | 
| +    ],
 | 
| +    "name": "makedirs tmp_dir",
 | 
| +    "~followup_annotations": [
 | 
| +      "@@@STEP_LOG_LINE@python.inline@@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@import sys, os@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@path = sys.argv[1]@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@mode = int(sys.argv[2])@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@if not os.path.isdir(path):@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@  if os.path.exists(path):@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@    print \"%s exists but is not a dir\" % path@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@    sys.exit(1)@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@  os.makedirs(path, mode)@@@",
 | 
| +      "@@@STEP_LOG_END@python.inline@@@"
 | 
| +    ]
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "python",
 | 
| +      "-u",
 | 
| +      "\nimport contextlib\nimport math\nimport socket\nimport sys\nimport time\nimport urllib2\n\nHASHES_URL = 'https://gold.skia.org/_/hashes'\nRETRIES = 5\nTIMEOUT = 60\nWAIT_BASE = 15\n\nsocket.setdefaulttimeout(TIMEOUT)\nfor retry in range(RETRIES):\n  try:\n    with contextlib.closing(\n        urllib2.urlopen(HASHES_URL, timeout=TIMEOUT)) as w:\n      hashes = w.read()\n      with open(sys.argv[1], 'w') as f:\n        f.write(hashes)\n        break\n  except Exception as e:\n    print 'Failed to get uninteresting hashes from %s:' % HASHES_URL\n    print e\n    if retry == RETRIES:\n      raise\n    waittime = WAIT_BASE * math.pow(2, retry)\n    print 'Retry in %d seconds.' % waittime\n    time.sleep(waittime)\n",
 | 
| +      "[SLAVE_BUILD]/tmp/uninteresting_hashes.txt"
 | 
| +    ],
 | 
| +    "cwd": "[SLAVE_BUILD]/skia",
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "get uninteresting hashes",
 | 
| +    "~followup_annotations": [
 | 
| +      "@@@STEP_LOG_LINE@python.inline@@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@import contextlib@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@import math@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@import socket@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@import time@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@import urllib2@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@HASHES_URL = 'https://gold.skia.org/_/hashes'@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@RETRIES = 5@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@TIMEOUT = 60@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@WAIT_BASE = 15@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@socket.setdefaulttimeout(TIMEOUT)@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@for retry in range(RETRIES):@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@  try:@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@    with contextlib.closing(@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@        urllib2.urlopen(HASHES_URL, timeout=TIMEOUT)) as w:@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@      hashes = w.read()@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@      with open(sys.argv[1], 'w') as f:@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@        f.write(hashes)@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@        break@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@  except Exception as e:@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@    print 'Failed to get uninteresting hashes from %s:' % HASHES_URL@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@    print e@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@    if retry == RETRIES:@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@      raise@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@    waittime = WAIT_BASE * math.pow(2, retry)@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@    print 'Retry in %d seconds.' % waittime@@@",
 | 
| +      "@@@STEP_LOG_LINE@python.inline@    time.sleep(waittime)@@@",
 | 
| +      "@@@STEP_LOG_END@python.inline@@@"
 | 
| +    ]
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "push",
 | 
| +      "[SLAVE_BUILD]/tmp/uninteresting_hashes.txt",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_tmp_dir/uninteresting_hashes.txt"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "push uninteresting_hashes.txt"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/skia/platform_tools/android/bin/android_run_skia",
 | 
| +      "--verbose",
 | 
| +      "--logcat",
 | 
| +      "-d",
 | 
| +      "arm_v7_neon",
 | 
| +      "-t",
 | 
| +      "Debug",
 | 
| +      "dm",
 | 
| +      "--undefok",
 | 
| +      "--resourcePath",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_resources",
 | 
| +      "--skps",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_skp/skps",
 | 
| +      "--images",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_images/dm",
 | 
| +      "--colorImages",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_images/colorspace",
 | 
| +      "--nameByHash",
 | 
| +      "--properties",
 | 
| +      "gitHash",
 | 
| +      "abc123",
 | 
| +      "master",
 | 
| +      "client.skia",
 | 
| +      "builder",
 | 
| +      "Test-Android-GCC-Nexus7-GPU-Tegra3-Arm7-Debug",
 | 
| +      "build_number",
 | 
| +      "6",
 | 
| +      "--key",
 | 
| +      "arch",
 | 
| +      "Arm7",
 | 
| +      "compiler",
 | 
| +      "GCC",
 | 
| +      "configuration",
 | 
| +      "Debug",
 | 
| +      "cpu_or_gpu",
 | 
| +      "GPU",
 | 
| +      "cpu_or_gpu_value",
 | 
| +      "Tegra3",
 | 
| +      "model",
 | 
| +      "Nexus7",
 | 
| +      "os",
 | 
| +      "Android",
 | 
| +      "--uninterestingHashesFile",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_tmp_dir/uninteresting_hashes.txt",
 | 
| +      "--writePath",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_dm",
 | 
| +      "--nocpu",
 | 
| +      "--dummy-flags"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "ANDROID_HOME": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "ANDROID_SDK_ROOT": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_ANDROID_VERBOSE_SETUP": "1",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "dm"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/skia/platform_tools/android/bin/adb_pull_if_needed",
 | 
| +      "--verbose",
 | 
| +      "/storage/emulated/legacy/skiabot/skia_dm",
 | 
| +      "[CUSTOM_[SWARM_OUT_DIR]]/dm"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "ANDROID_HOME": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "ANDROID_SDK_ROOT": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_ANDROID_VERBOSE_SETUP": "1",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "pull skia_dm"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "shell",
 | 
| +      "dumpsys",
 | 
| +      "batteryproperties"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "final battery stats"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "reboot"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "reboot"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "sleep",
 | 
| +      "10"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "wait for reboot"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/skia/platform_tools/android/bin/adb_wait_for_device"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "ANDROID_HOME": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "ANDROID_SDK_ROOT": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_ANDROID_VERBOSE_SETUP": "1",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "wait for device (3)"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/skia/platform_tools/android/bin/adb_wait_for_charge"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "ANDROID_HOME": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "ANDROID_SDK_ROOT": "[SLAVE_BUILD]/android_sdk/android-sdk",
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_ANDROID_VERBOSE_SETUP": "1",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "wait for charge (3)"
 | 
| +  },
 | 
| +  {
 | 
| +    "cmd": [
 | 
| +      "[SLAVE_BUILD]/android_sdk/android-sdk/platform-tools/adb",
 | 
| +      "kill-server"
 | 
| +    ],
 | 
| +    "env": {
 | 
| +      "BUILDTYPE": "Debug",
 | 
| +      "CHROME_HEADLESS": "1",
 | 
| +      "GYP_DEFINES": "skia_arch_type=arm skia_warnings_as_errors=0",
 | 
| +      "SKIA_OUT": "[SLAVE_BUILD]/out"
 | 
| +    },
 | 
| +    "name": "kill-server"
 | 
| +  },
 | 
| +  {
 | 
| +    "name": "$result",
 | 
| +    "recipe_result": null,
 | 
| +    "status_code": 0
 | 
| +  }
 | 
| +]
 | 
| 
 |