xref: /aosp_15_r20/external/autotest/client/common_lib/cros/path_utils.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
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