1# Lint as: python2, python3 2# Copyright 2014 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import os 7 8from autotest_lib.client.bin import utils 9from autotest_lib.client.common_lib import error 10 11 12def get_install_path(filename, host=None): 13 """ 14 Checks if a file exists on a remote machine in one of several paths. 15 16 @param filename String name of the file to check for existence. 17 @param host Host object representing the remote machine. 18 @return String full path of installed file, or None if not found. 19 20 """ 21 run = utils.run 22 if host is not None: 23 run = host.run 24 PATHS = ['/bin', 25 '/sbin', 26 '/system/bin', 27 '/system/xbin', 28 '/usr/bin', 29 '/usr/sbin', 30 '/usr/local/bin', 31 '/usr/local/sbin'] 32 glob_list = [os.path.join(path, filename) for path in PATHS] 33 # Some hosts have poor support for which. Sometimes none. 34 # Others have shells that can't perform advanced globbing. 35 result = host.run('ls %s 2> /dev/null' % ' '.join(glob_list), 36 ignore_status=True) 37 found_path = result.stdout.split('\n')[0].strip() 38 return found_path or None 39 40 41def must_be_installed(cmd, host=None): 42 """ 43 Asserts that cmd is installed on a remote machine at some path and raises 44 an exception if this is not the case. 45 46 @param cmd String name of the command to check for existence. 47 @param host Host object representing the remote machine. 48 @return String full path of cmd on success. Error raised on failure. 49 50 """ 51 run = utils.run 52 if host is not None: 53 run = host.run 54 if run('ls %s >/dev/null 2>&1' % cmd, 55 ignore_status=True).exit_status == 0: 56 return cmd 57 58 # Hunt for the equivalent file in a bunch of places. 59 cmd_base = os.path.basename(cmd) 60 alternate_path = get_install_path(cmd_base, host=host) 61 if alternate_path: 62 return alternate_path 63 64 error_msg = 'Unable to find %s' % cmd 65 if host is not None: 66 error_msg += ' on %s' % host.hostname 67 raise error.TestError(error_msg) 68