10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch# Copyright 2014 The Chromium Authors. All rights reserved.
20529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch# Use of this source code is governed by a BSD-style license that can be
30529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch# found in the LICENSE file.
40529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport os
66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import stat
70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
80529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochfrom telemetry import decorators
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdochfrom telemetry.util import cloud_storage
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from telemetry.util import path
110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochdef _GetBinPath(binary_name, platform_name):
140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  # TODO(tonyg): Add another nesting level for architecture_name.
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return os.path.join(path.GetTelemetryDir(), 'bin', platform_name, binary_name)
160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochdef _IsInCloudStorage(binary_name, platform_name):
190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return os.path.exists(_GetBinPath(binary_name, platform_name) + '.sha1')
200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch@decorators.Cache
230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochdef FindLocallyBuiltPath(binary_name):
240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  """Finds the most recently built |binary_name|."""
250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  command = None
260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  command_mtime = 0
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  chrome_root = path.GetChromiumSrcDir()
280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  required_mode = os.X_OK
290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if binary_name.endswith('.apk'):
300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    required_mode = os.R_OK
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for build_dir, build_type in path.GetBuildDirectories():
320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    candidate = os.path.join(chrome_root, build_dir, build_type, binary_name)
330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if os.path.isfile(candidate) and os.access(candidate, required_mode):
340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      candidate_mtime = os.stat(candidate).st_mtime
350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if candidate_mtime > command_mtime:
360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        command = candidate
370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        command_mtime = candidate_mtime
380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return command
390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch@decorators.Cache
420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochdef FindPath(binary_name, platform_name):
430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  """Returns the path to the given binary name, pulling from the cloud if
440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  necessary."""
450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if platform_name == 'win':
460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    binary_name += '.exe'
470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  command = FindLocallyBuiltPath(binary_name)
480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if not command and _IsInCloudStorage(binary_name, platform_name):
490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    cloud_storage.GetIfChanged(_GetBinPath(binary_name, platform_name))
500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    command = _GetBinPath(binary_name, platform_name)
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    # Ensure the downloaded file is actually executable.
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if command and os.path.exists(command):
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      os.chmod(command,
556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)               stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP)
566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  # Return an absolute path consistently.
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if command:
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    command = os.path.abspath(command)
600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return command
61