# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import contextlib

DEPS = [
  'build',
  'depot_tools/bot_update',
  'depot_tools/gclient',
  'depot_tools/gsutil',
  'goma',
  'recipe_engine/context',
  'recipe_engine/file',
  'recipe_engine/json',
  'recipe_engine/path',
  'recipe_engine/platform',
  'recipe_engine/properties',
  'recipe_engine/step',
  'recipe_engine/python',
  'zip',
]

BUCKET_NAME = 'flutter_infra'
GOMA_JOBS = '200'

def GetCloudPath(api, path):
  # TODO(eseidel): api.bot_update.last_returned_properties is supposedly a known
  # api wart. iannucci says it will be improved at some point.
  git_hash = api.bot_update.last_returned_properties['got_engine_revision']
  return 'flutter/%s/%s' % (git_hash, path)


def Build(api, config, *targets):
  checkout = api.path['start_dir'].join('src')
  build_dir = checkout.join('out/%s' % config)
  ninja_args = ['ninja', '-j', GOMA_JOBS, '-C', build_dir]
  ninja_args.extend(targets)
  api.goma.build_with_goma(
    name='build %s' % ' '.join([config] + list(targets)),
    ninja_command=ninja_args)


def RunHostTests(api, out_dir, exe_extension=''):
  directory = api.path['start_dir'].join('src', out_dir)
  with api.context(cwd=directory):
    # Cross platform tests.
    api.step('Test FXL',
      [directory.join('fxl_unittests' + exe_extension)])
    api.step('Test Flow',
      [directory.join('flow_unittests' + exe_extension)])
    api.step('Test FML', [
      directory.join('fml_unittests' + exe_extension),
      '--gtest_filter="-*TimeSensitiveTest*"'
    ])
    api.step('Test Synchronization',
      [directory.join('synchronization_unittests' + exe_extension)])
    api.step('Test Runtime',
      [directory.join('runtime_unittests' + exe_extension)])
    api.step('Test Shell',
      [directory.join('shell_unittests' + exe_extension)])
    api.step('Test Embedder API',
      [directory.join('embedder_unittests' + exe_extension)])

    if api.platform.is_mac:
      api.step('Test Flutter Channels',
        [directory.join('flutter_channels_unittests' + exe_extension)])

def RunGN(api, *args):
  checkout = api.path['start_dir'].join('src')
  gn_cmd = ['python', checkout.join('flutter/tools/gn'), '--goma']
  gn_cmd.extend(args)
  api.step('gn %s' % ' '.join(args), gn_cmd)


def AddFiles(api, pkg, relative_paths):
  for path in relative_paths:
    pkg.add_file(pkg.root.join(path), archive_name=api.path.basename(path))


def UploadArtifacts(api, platform, file_paths, archive_name='artifacts.zip'):
  dir_label = '%s UploadArtifacts %s' % (platform, archive_name)
  with MakeTempDir(api, dir_label) as temp_dir:
    local_zip = temp_dir.join('artifacts.zip')
    remote_name = '%s/%s' % (platform, archive_name)
    remote_zip = GetCloudPath(api, remote_name)
    pkg = api.zip.make_package(api.path['start_dir'].join('src'), local_zip)
    AddFiles(api, pkg, file_paths)

    pkg.zip('Zip %s %s' % (platform, archive_name))
    api.gsutil.upload(local_zip, BUCKET_NAME, remote_zip,
        name='upload "%s"' % remote_name)


def UploadFolder(api, dir_label, parent_dir, folder_name, zip_name):
  with MakeTempDir(api, dir_label) as temp_dir:
    local_zip = temp_dir.join(zip_name)
    remote_name = zip_name
    remote_zip = GetCloudPath(api, remote_name)
    parent_dir = api.path['start_dir'].join(parent_dir)
    pkg = api.zip.make_package(parent_dir, local_zip)
    pkg.add_directory(parent_dir.join(folder_name))
    pkg.zip('Zip %s' % folder_name)
    api.gsutil.upload(local_zip, BUCKET_NAME, remote_zip,
        name='upload %s' % remote_name)


def UploadDartPackage(api, package_name):
  UploadFolder(api,
    'UploadDartPackage %s' % package_name, # dir_label
    'src/out/android_debug/dist/packages', # parent_dir
    package_name, # folder_name
    "%s.zip" % package_name) # zip_name


def UploadFlutterPatchedSdk(api):
  UploadFolder(api,
    'Upload Flutter patched sdk', # dir_label
    'src/out/host_debug', # parent_dir
    'flutter_patched_sdk', # folder_name
    'flutter_patched_sdk.zip') # zip_name

def UploadDartSdk(api, archive_name):
  UploadFolder(api,
    'Upload Dart SDK', # dir_label
    'src/out/host_debug', # parent_dir
    'dart-sdk', # folder_name
    archive_name)

# TODO(eseidel): Would be nice to have this on api.path or api.file.
@contextlib.contextmanager
def MakeTempDir(api, label):
  try:
    temp_dir = api.path.mkdtemp('tmp')
    yield temp_dir
  finally:
    api.file.rmtree('temp dir for %s' % label, temp_dir)


def AnalyzeDartUI(api):
  RunGN(api, '--unoptimized')
  Build(api, 'host_debug_unopt', 'generate_dart_ui')

  checkout = api.path['start_dir'].join('src')
  with api.context(cwd=checkout):
    api.step('analyze dart_ui', ['/bin/bash', 'flutter/travis/analyze.sh'])


def UploadTreeMap(api, upload_dir, lib_flutter_path):
  with MakeTempDir(api, 'treemap') as temp_dir:
    checkout = api.path['start_dir'].join('src')
    script_path = checkout.join('third_party/dart/runtime/third_party/binary_size/src/run_binary_size_analysis.py')
    library_path = checkout.join(lib_flutter_path)
    destionation_dir = temp_dir.join('sizes')
    args = ['--library', library_path, '--destdir', destionation_dir]

    api.python('generate treemap for %s' % lib_flutter_path, script_path, args)

    remote_name = GetCloudPath(api, upload_dir)
    result = api.gsutil.upload(destionation_dir, BUCKET_NAME, remote_name,
        args=['-r'], name='upload treemap for %s' % lib_flutter_path, link_name=None)
    result.presentation.links['Open Treemap'] = 'https://storage.googleapis.com/%s/%s/sizes/index.html' % (BUCKET_NAME, remote_name)


def BuildLinuxAndroid(api):
  debug_variants = [
    ('arm', 'android_debug', 'android-arm'),
    ('arm64', 'android_debug_arm64', 'android-arm64'),
    ('x86', 'android_debug_x86', 'android-x86'),
    ('x64', 'android_debug_x64', 'android-x64'),
  ]
  for android_cpu, out_dir, artifact_dir in debug_variants:
    RunGN(api, '--android', '--android-cpu=%s' % android_cpu)
    Build(api, out_dir)
    artifacts = ['out/%s/flutter.jar' % out_dir]
    if android_cpu in ['x86', 'x64']:
        artifacts.append('out/%s/lib.stripped/libflutter.so' % out_dir)
    UploadArtifacts(api, artifact_dir, artifacts)
    UploadArtifacts(api, artifact_dir, ['out/%s/libflutter.so' % out_dir],
                    archive_name='symbols.zip')

  jit_variants = [
    ('arm', 'android_dynamic_%s', 'android-arm-dynamic-%s', 'clang_x86'),
    ('arm64', 'android_dynamic_%s_arm64', 'android-arm64-dynamic-%s', 'clang_x64'),
  ]
  for android_cpu, out_dir, artifact_dir, clang_dir in jit_variants:
    for runtime_mode in ['profile', 'release']:
      build_output_dir = out_dir % runtime_mode
      upload_dir = artifact_dir % runtime_mode

      RunGN(api, '--android', '--dynamic', '--runtime-mode=' + runtime_mode,
            '--android-cpu=%s' % android_cpu)
      Build(api, build_output_dir)

      UploadArtifacts(api, upload_dir, [
        'out/%s/flutter.jar' % build_output_dir,
      ])
      UploadArtifacts(api, upload_dir, [
        'out/%s/%s/gen_snapshot' % (build_output_dir, clang_dir),
      ], archive_name='linux-x64.zip')
      UploadArtifacts(api, upload_dir, [
          'out/%s/libflutter.so' % build_output_dir
      ], archive_name='symbols.zip')

  # Build and upload engines for the runtime modes that use AOT compilation.
  aot_variants = [
    ('arm', 'android_%s', 'android-arm-%s', 'clang_x86'),
    ('arm64', 'android_%s_arm64', 'android-arm64-%s', 'clang_x64'),
  ]
  for android_cpu, out_dir, artifact_dir, clang_dir in aot_variants:
    for runtime_mode in ['profile', 'release']:
      build_output_dir = out_dir % runtime_mode
      upload_dir = artifact_dir % runtime_mode

      RunGN(api, '--android', '--runtime-mode=' + runtime_mode, '--android-cpu=%s' % android_cpu)
      Build(api, build_output_dir)

      UploadArtifacts(api, upload_dir, [
        'third_party/dart/runtime/bin/dart_io_entries.txt',
        'flutter/runtime/dart_vm_entry_points.txt',
        'out/%s/dart_entry_points/entry_points.json' % build_output_dir,
        'out/%s/dart_entry_points/entry_points_extra.json' % build_output_dir,
        'out/%s/flutter.jar' % build_output_dir,
      ])

      # Upload artifacts used for AOT compilation on Linux hosts.
      UploadArtifacts(api, upload_dir, [
        'out/%s/%s/gen_snapshot' % (build_output_dir, clang_dir),
      ], archive_name='linux-x64.zip')
      unstripped_lib_flutter_path = 'out/%s/libflutter.so' % build_output_dir
      UploadArtifacts(api, upload_dir, [
          unstripped_lib_flutter_path
      ], archive_name='symbols.zip')

      if runtime_mode == 'release':
        UploadTreeMap(api, upload_dir, unstripped_lib_flutter_path);

  Build(api, 'android_debug', ':dist')
  UploadDartPackage(api, 'sky_engine')


def BuildLinux(api):
  RunGN(api, '--runtime-mode', 'debug')
  RunGN(api, '--runtime-mode', 'debug', '--unoptimized')
  RunGN(api, '--runtime-mode', 'release', '--android', '--enable-vulkan')
  Build(api, 'host_debug_unopt')
  Build(api, 'host_debug')
  Build(api, 'android_release_vulkan')
  RunHostTests(api, 'out/host_debug_unopt')
  UploadArtifacts(api, 'linux-x64', [
    'out/host_debug_unopt/icudtl.dat',
    'out/host_debug_unopt/flutter_tester',
    'out/host_debug_unopt/gen/flutter/lib/snapshot/isolate_snapshot.bin',
    'out/host_debug_unopt/gen/flutter/lib/snapshot/vm_isolate_snapshot.bin',
    'out/host_debug_unopt/gen/frontend_server.dart.snapshot',
  ])
  UploadArtifacts(api, 'linux-x64', [
    'out/host_debug/flutter_embedder.h',
    'out/host_debug/libflutter_engine.so',
  ], archive_name='linux-x64-embedder')
  UploadFlutterPatchedSdk(api)
  UploadDartSdk(api, archive_name='dart-sdk-linux-x64.zip')


def TestObservatory(api):
  checkout = api.path['start_dir'].join('src')
  flutter_tester_path = checkout.join('out/host_debug_unopt/flutter_tester')
  empty_main_path = \
      checkout.join('flutter/shell/testing/observatory/empty_main.dart')
  test_path = checkout.join('flutter/shell/testing/observatory/test.dart')
  test_cmd = ['dart', test_path, flutter_tester_path, empty_main_path]
  with api.context(cwd=checkout):
    api.step('test observatory and service protocol', test_cmd)


#def TestEngine(api):
#  checkout = api.path['start_dir'].join('src')
#  test_cmd = [checkout.join('flutter/testing/run_tests.sh')]
#  with api.context(cwd=checkout):
#    api.step('engine unit tests', test_cmd)


def RunFindXcode(api, ios_tools_path, target_version):
  """Locates and switches to a version of Xcode matching target_version."""
  args = [
      '--json-file', api.json.output(),
      '--version', target_version,
  ]
  result = api.build.python(
      'set_xcode_version',
      ios_tools_path.join('build', 'bots', 'scripts', 'find_xcode.py'),
      args)
  return result.json.output


def SetupXcode(api):
  ios_tools_path = api.path['start_dir'].join('src', 'ios_tools')
  target_version = '9.0.1'
  xcode_json = RunFindXcode(api, ios_tools_path, target_version)
  if not xcode_json['matches']:
    raise api.step.StepFailure('Xcode %s not found' % target_version)


def BuildMac(api):
  RunGN(api, '--runtime-mode', 'debug', '--no-lto')
  RunGN(api, '--runtime-mode', 'debug', '--unoptimized', '--no-lto')
  RunGN(api, '--runtime-mode', 'profile', '--android')
  RunGN(api, '--runtime-mode', 'profile', '--android', '--android-cpu=arm64')
  RunGN(api, '--runtime-mode', 'release', '--android')
  RunGN(api, '--runtime-mode', 'release', '--android', '--android-cpu=arm64')
  RunGN(api, '--runtime-mode', 'release', '--android', '--enable-vulkan')

  Build(api, 'host_debug_unopt')
  Build(api, 'host_debug')
  RunHostTests(api, 'out/host_debug_unopt')

  Build(api, 'android_profile', 'flutter/lib/snapshot')
  Build(api, 'android_profile_arm64', 'flutter/lib/snapshot')
  Build(api, 'android_release', 'flutter/lib/snapshot')
  Build(api, 'android_release_arm64', 'flutter/lib/snapshot')
  Build(api, 'android_release_vulkan')

  host_debug_path = api.path['start_dir'].join('src', 'out', 'host_debug')

  api.zip.directory('Archive FlutterEmbedder.framework',
    host_debug_path.join('FlutterEmbedder.framework'),
    host_debug_path.join('FlutterEmbedder.framework.zip'))

  UploadArtifacts(api, 'darwin-x64', [
    'out/host_debug_unopt/icudtl.dat',
    'out/host_debug_unopt/flutter_tester',
    'out/host_debug_unopt/gen/flutter/lib/snapshot/isolate_snapshot.bin',
    'out/host_debug_unopt/gen/flutter/lib/snapshot/vm_isolate_snapshot.bin',
    'out/host_debug_unopt/gen/frontend_server.dart.snapshot',
  ])

  UploadArtifacts(api, 'darwin-x64', [
    'out/host_debug/FlutterEmbedder.framework.zip'
  ], archive_name='FlutterEmbedder.framework.zip')

  UploadArtifacts(api, "android-arm-profile" , [
    'out/android_profile/clang_x86/gen_snapshot',
  ], archive_name='darwin-x64.zip')

  UploadArtifacts(api, "android-arm64-profile" , [
    'out/android_profile_arm64/clang_x64/gen_snapshot',
  ], archive_name='darwin-x64.zip')

  UploadArtifacts(api, "android-arm-release" , [
    'out/android_release/clang_x86/gen_snapshot',
  ], archive_name='darwin-x64.zip')

  UploadArtifacts(api, "android-arm64-release" , [
    'out/android_release_arm64/clang_x64/gen_snapshot',
  ], archive_name='darwin-x64.zip')

  UploadDartSdk(api, archive_name='dart-sdk-darwin-x64.zip')


def PackageIOSVariant(api, label, arm64_out, armv7_out, sim_out, bucket_name):
  checkout = api.path['start_dir'].join('src')
  out_dir = checkout.join('out')

  # Package the multi-arch framework for iOS.
  label_dir = out_dir.join(label)
  create_ios_framework_cmd = [
    checkout.join('flutter/sky/tools/create_ios_framework.py'),
    '--dst',
    label_dir,
    '--arm64-out-dir',
    api.path.join(out_dir, arm64_out),
    '--armv7-out-dir',
    api.path.join(out_dir, armv7_out),
    '--simulator-out-dir',
    api.path.join(out_dir, sim_out),
  ]
  with api.context(cwd=checkout):
    api.step('Create iOS %s Flutter.framework' % label,
      create_ios_framework_cmd)

  # Zip Flutter.framework.
  api.zip.directory('Archive Flutter.framework for %s' % label,
    label_dir.join('Flutter.framework'),
    label_dir.join('Flutter.framework.zip'))

  # Package the multi-arch gen_snapshot for macOS.
  create_macos_gen_snapshot_cmd = [
    checkout.join('flutter/sky/tools/create_macos_gen_snapshot.py'),
    '--dst',
    label_dir,
    '--arm64-out-dir',
    api.path.join(out_dir, arm64_out),
    '--armv7-out-dir',
    api.path.join(out_dir, armv7_out),
  ]
  with api.context(cwd=checkout):
    api.step('Create macOS %s gen_snapshot' % label,
      create_macos_gen_snapshot_cmd)

  # Upload the artifacts to cloud storage.
  artifacts = [
    'third_party/dart/runtime/bin/dart_io_entries.txt',
    'flutter/runtime/dart_vm_entry_points.txt',
    'flutter/lib/snapshot/snapshot.dart',
    'flutter/shell/platform/darwin/ios/framework/Flutter.podspec',
    'out/%s/gen_snapshot' % label,
    'out/%s/Flutter.framework.zip' % label,
  ]
  if label in ['profile', 'release']:
    artifacts.append('out/%s/dart_entry_points/entry_points.json' % arm64_out)
    artifacts.append(
      'out/%s/dart_entry_points/entry_points_extra.json' % arm64_out)
  UploadArtifacts(api, bucket_name, artifacts)


def BuildIOS(api):
  # Generate Ninja files for all valid configurations.
  RunGN(api, '--ios', '--runtime-mode', 'debug', '--no-lto')
  RunGN(api, '--ios', '--runtime-mode', 'debug', '--ios-cpu=arm', '--no-lto')
  RunGN(api, '--ios', '--runtime-mode', 'debug', '--simulator', '--no-lto')
  RunGN(api, '--ios', '--runtime-mode', 'profile')
  RunGN(api, '--ios', '--runtime-mode', 'profile', '--ios-cpu=arm')
  RunGN(api, '--ios', '--runtime-mode', 'release')
  RunGN(api, '--ios', '--runtime-mode', 'release', '--ios-cpu=arm')

  # Build all configurations.
  Build(api, 'ios_debug')
  Build(api, 'ios_debug_arm')
  Build(api, 'ios_debug_sim')
  Build(api, 'ios_profile')
  Build(api, 'ios_profile_arm')
  Build(api, 'ios_release')
  Build(api, 'ios_release_arm')

  # Package all variants
  PackageIOSVariant(api,
      'debug',   'ios_debug',   'ios_debug_arm',   'ios_debug_sim', 'ios')
  PackageIOSVariant(api,
      'profile', 'ios_profile', 'ios_profile_arm', 'ios_debug_sim', 'ios-profile')
  PackageIOSVariant(api,
      'release', 'ios_release', 'ios_release_arm', 'ios_debug_sim', 'ios-release')


def BuildWindows(api):
  RunGN(api, '--runtime-mode', 'debug')
  RunGN(api, '--runtime-mode', 'debug', '--unoptimized')
  RunGN(api, '--runtime-mode', 'profile', '--android')
  RunGN(api, '--runtime-mode', 'profile', '--android', '--android-cpu=arm64')
  RunGN(api, '--runtime-mode', 'release', '--android')
  RunGN(api, '--runtime-mode', 'release', '--android', '--android-cpu=arm64')

  Build(api, 'host_debug_unopt')
  Build(api, 'host_debug')
  Build(api, 'android_profile', 'gen_snapshot')
  Build(api, 'android_profile_arm64', 'gen_snapshot')
  Build(api, 'android_release', 'gen_snapshot')
  Build(api, 'android_release_arm64', 'gen_snapshot')

  RunHostTests(api, 'out\\host_debug', '.exe')

  UploadArtifacts(api, 'windows-x64', [
    'out/host_debug/icudtl.dat',
    'out/host_debug/flutter_tester.exe',
    'out/host_debug/gen/flutter/lib/snapshot/isolate_snapshot.bin',
    'out/host_debug/gen/flutter/lib/snapshot/vm_isolate_snapshot.bin',
    'out/host_debug/gen/frontend_server.dart.snapshot',
  ])

  UploadArtifacts(api, 'windows-x64', [
    'out/host_debug/flutter_embedder.h',
    'out/host_debug/flutter_engine.dll',
    'out/host_debug/flutter_engine.dll.exp',
    'out/host_debug/flutter_engine.dll.lib',
    'out/host_debug/flutter_engine.dll.pdb',
  ], archive_name='windows-x64-embedder.zip')

  UploadArtifacts(api, "android-arm-profile" , [
    'out/android_profile/gen_snapshot.exe',
  ], archive_name='windows-x64.zip')

  UploadArtifacts(api, "android-arm64-profile" , [
    'out/android_profile_arm64/gen_snapshot.exe',
  ], archive_name='windows-x64.zip')

  UploadArtifacts(api, "android-arm-release" , [
    'out/android_release/gen_snapshot.exe',
  ], archive_name='windows-x64.zip')

  UploadArtifacts(api, "android-arm64-release" , [
    'out/android_release_arm64/gen_snapshot.exe',
  ], archive_name='windows-x64.zip')

  UploadDartSdk(api, archive_name='dart-sdk-windows-x64.zip')


def BuildJavadoc(api):
  checkout = api.path['start_dir'].join('src')
  with MakeTempDir(api, 'BuildJavadoc') as temp_dir:
    javadoc_cmd = [checkout.join('flutter/tools/gen_javadoc.py'),
                   '--out-dir', temp_dir]
    with api.context(cwd=checkout):
      api.step('build javadoc', javadoc_cmd)
    api.zip.directory('archive javadoc', temp_dir,
                      checkout.join('out/android_javadoc.zip'))

  api.gsutil.upload(checkout.join('out/android_javadoc.zip'),
                    BUCKET_NAME,
                    GetCloudPath(api, 'android-javadoc.zip'),
                    name='upload javadoc')


def BuildObjcDoc(api):
  """Builds documentation for the Objective-C variant of engine."""
  checkout = api.path['start_dir'].join('src')
  with MakeTempDir(api, 'BuildObjcDoc') as temp_dir:
    objcdoc_cmd = [checkout.join('flutter/tools/gen_objcdoc.sh'), temp_dir]
    with api.context(cwd=checkout.join('flutter')):
      api.step('build obj-c doc', objcdoc_cmd)
    api.zip.directory('archive obj-c doc', temp_dir,
                      checkout.join('out/ios-objcdoc.zip'))

  api.gsutil.upload(checkout.join('out/ios-objcdoc.zip'),
                    BUCKET_NAME,
                    GetCloudPath(api, 'ios-objcdoc.zip'),
                    name='upload obj-c doc')


def GetCheckout(api):
  src_cfg = api.gclient.make_config()
  soln = src_cfg.solutions.add()
  soln.name = 'src/flutter'
  soln.url = \
      'https://chromium.googlesource.com/external/github.com/flutter/engine'
  # TODO(eseidel): What does parent_got_revision_mapping do?  Do I care?
  src_cfg.parent_got_revision_mapping['parent_got_revision'] = 'got_revision'
  src_cfg.target_os = set(['android'])
  api.gclient.c = src_cfg
  api.gclient.c.got_revision_mapping['src/flutter'] = 'got_engine_revision'
  api.bot_update.ensure_checkout()
  api.gclient.runhooks()


def RunSteps(api):
  # buildbot sets 'clobber' to the empty string which is falsey, check with 'in'
  if 'clobber' in api.properties:
    api.file.rmcontents('everything', api.path['start_dir'])

  GetCheckout(api)

  checkout = api.path['start_dir'].join('src')
  dart_bin = checkout.join('third_party', 'dart', 'tools', 'sdks', 'dart-sdk', 'bin')

  api.goma.ensure_goma()

  env = {
    'PATH': api.path.pathsep.join((str(dart_bin), '%(PATH)s')),
    'GOMA_DIR': api.goma.goma_dir,
  }

  # The context adds dart to the path, only needed for the analyze step for now.
  with api.context(env=env):
    if api.platform.is_linux:
      AnalyzeDartUI(api)
      BuildLinux(api)
      TestObservatory(api)
      #TestEngine(api)
      BuildLinuxAndroid(api)
      BuildJavadoc(api)

    if api.platform.is_mac:
      SetupXcode(api)
      BuildMac(api)
      BuildIOS(api)
      BuildObjcDoc(api)

    if api.platform.is_win:
      BuildWindows(api)


def GenTests(api):
  # A valid commit to flutter/engine, to make the gsutil urls look real.
  for platform in ('mac', 'linux', 'win'):
    test = (api.test(platform) + api.platform(platform, 64)
        + api.properties(mastername='client.flutter',
              buildername='%s Engine' % platform.capitalize(),
              bot_id='fake-m1', clobber=''))
    if platform == 'mac':
      test += (
        api.step_data('set_xcode_version', api.json.output({
          'matches': {
            '/Applications/Xcode9.0.app': '9.0.1 (9A1004)'
          }
        }))
      )
    yield test

  yield (
    api.test('mac_cannot_find_xcode') +
    api.platform('mac', 64) +
    api.properties(revision='1234abcd') +
    api.properties(clobber='') +
    api.properties(buildername='Mac Engine') +
    api.step_data('set_xcode_version', api.json.output({
      'matches': {}
    }))
  )
