xref: /aosp_15_r20/external/autotest/server/cros/bluetooth/bluetooth_test_version_control.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1# Lint as: python2, python3
2# Copyright 2021 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"""Provide version control for Bluetooth tests"""
6
7import logging
8import os
9
10from autotest_lib.server import utils
11
12CWD = os.getcwd()
13BLUETOOTH_DIR = os.path.dirname(__file__)
14REMOTE_NAME = 'cros'
15BRANCH_NAME = 'main'
16BRANCH_NAME_FULL = os.path.join(REMOTE_NAME, BRANCH_NAME)
17HTTP_MIRROR_URL =\
18        'http://commondatastorage.googleapis.com/chromeos-localmirror'
19BUNDLE_PATH = 'distfiles/bluetooth_peer_bundle'
20HTTP_BUNDLE_URL = os.path.join(HTTP_MIRROR_URL, BUNDLE_PATH)
21LATEST_STABLE_AUTOTEST_COMMIT = 'LATEST_STABLE_AUTOTEST_COMMIT'
22HTTP_LATEST_STABLE_AUTOTEST_COMMIT_URL = os.path.join(
23        HTTP_BUNDLE_URL, LATEST_STABLE_AUTOTEST_COMMIT)
24
25
26def check_git_tree_clean():
27    """ Check if local directory is clear from modification
28
29    @returns: True if success, False otherwise
30    """
31    output = utils.run('git status --porcelain')
32    if output.stdout != '':
33        logging.info(
34                'The Autotest directory is not clean! To perform the AVL\n'
35                'testing consistently, the AVL setup process will fetch\n'
36                'a specific commit hash from the server and check out\n'
37                'locally. To preserve your local changes, please commit\n'
38                'or stash your changes! Changes:')
39        logging.info(output.stdout)
40        return False
41
42    logging.info('Local git tree is clean.')
43    return True
44
45
46def fetch_target_commit():
47    """ Fetch from the cloud or git to retrieve latest ToT or latest stable
48    commit hash.
49
50    @returns: current and targeted commit hash
51    """
52    current_commit = utils.system_output('git rev-parse HEAD')
53    utils.run('git fetch ' + REMOTE_NAME)
54    target_commit = utils.system_output(
55            'git rev-parse {}'.format(BRANCH_NAME_FULL))
56
57    output = utils.run('wget -O {} {}'.format(
58            LATEST_STABLE_AUTOTEST_COMMIT,
59            HTTP_LATEST_STABLE_AUTOTEST_COMMIT_URL),
60                       ignore_status=True)
61
62    if output.exit_status != 0:
63        logging.info('Failed to fetch the latest commit from the server')
64        logging.info(output.stdout)
65        logging.info(output.stderr)
66    else:
67        with open(LATEST_STABLE_AUTOTEST_COMMIT) as commit_file:
68            target_commit = commit_file.readline().strip()
69
70    logging.info('The latest commit will be used is:\n%s', target_commit)
71    return current_commit, target_commit
72
73
74def checkout_commit(commit):
75    """ Checkout the autotest directory to the specified commit."""
76    output = utils.run('git checkout {}'.format(commit), ignore_status=True)
77    if output.exit_status != 0:
78        logging.info(output.stderr)
79        logging.info('Failed to checkout target commit, please retry '
80                     'after\nrepo sync')
81    else:
82        logging.info('Target (stable or ToT) autotest commit is checked out,\n'
83                     'please rerun the test!')
84
85
86def test_version_setup_exit_print():
87    """ Exit the setup and return to the previous CWD."""
88    logging.info('=======================================================\n')
89    os.chdir(CWD)
90
91
92def test_version_setup():
93    """This and above functions hope to sync the AVL test environments
94    among different vendors, partners, and developers by providing an
95    automatic process to fetch a commit hash of the "released"
96    (or "stabled") version of the autotest directory from the cloud and
97    checkout locally. No manual interaction should be expected.
98
99    @returns: True if current commit version satisfied requirement, the
100              test shall proceed. False otherwise.
101    """
102    logging.info('=======================================================\n'
103                 '                    AVL Test Setup\n')
104
105    os.chdir(BLUETOOTH_DIR)
106    if not check_git_tree_clean():
107        test_version_setup_exit_print()
108        return False
109
110    current_commit, target_commit = fetch_target_commit()
111    if current_commit == target_commit:
112        logging.info('Local tree is already at target autotest commit.')
113        test_version_setup_exit_print()
114        return True
115
116    checkout_commit(target_commit)
117    test_version_setup_exit_print()
118    return False
119