• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#  Copyright (C) 2025 The Android Open Source Project
2#
3#  Licensed under the Apache License, Version 2.0 (the "License");
4#  you may not use this file except in compliance with the License.
5#  You may obtain a copy of the License at
6#
7#       http://www.apache.org/licenses/LICENSE-2.0
8#
9#  Unless required by applicable law or agreed to in writing, software
10#  distributed under the License is distributed on an "AS IS" BASIS,
11#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12#  See the License for the specific language governing permissions and
13#  limitations under the License.
14
15import logging
16import os
17import subprocess
18from mobly import base_test
19from mobly import test_runner
20from mobly import config_parser
21from mobly.controllers import android_device
22from devices import DeviceFactory
23from pathlib import Path
24from utilities.main_utils import common_main
25
26class AndroidFlashTest(base_test.BaseTestClass):
27
28    def setup_class(self):
29        # Setup required for the entire test class.
30        logging.info('Setting up test class.')
31        # Registers the android devices controllers with Mobly.
32        self.android_devices = self.register_controller(android_device)
33        # Retrieves the build path from the test configuration.
34        self.device = self.user_params['device']
35        self.serial = self.user_params['serial']
36        self.image_dir = Path(self.user_params['image_dir'])
37        self.wipe = self.user_params['wipe']
38        self.hw_variant = self.user_params['hw_variant']
39        self.b = self.user_params['b']
40        self.diag = self.user_params['diag']
41        self.preserve_keys = self.user_params['preserve_keys']
42        self.total_flashes = self.user_params['total_flashes']
43
44    def test_flash_device_stability(self):
45        # Check that there is at least one device available.
46        if not self.android_devices:
47            raise AssertionError('No Android devices are registered. Please make '
48                                 'sure at least one device is connected and '
49                                 'configured properly.')
50        ad = self.android_devices[0]  # Get the first device object.
51
52        total_flashes = self.total_flashes
53        successful_flashes = 0
54
55        for i in range(total_flashes):
56            logging.info('Flash attempt #%d', i + 1)
57
58            # Get the build fingerprint before flashing.
59            before_flash_fingerprint = ad.adb.getprop('ro.build.fingerprint')
60
61            try:
62
63                Device = DeviceFactory.get_device(self.device)
64                flash_result = Device.flash(self.serial, self.image_dir, self.wipe, self.hw_variant, self.b, self.diag, self.preserve_keys)
65                # Reboot the device and wait for it to come back online.
66                ad.reboot()
67                ad.wait_for_boot_completion()
68
69                # Get the build fingerprint after flashing.
70                after_flash_fingerprint = ad.adb.getprop('ro.build.fingerprint')
71
72                # Check if the flash was successful by comparing fingerprints.
73                if before_flash_fingerprint == after_flash_fingerprint:
74                    successful_flashes += 1
75                else:
76                    logging.error('Flash attempt #%d failed: fingerprint did not change.', i + 1)
77
78            except subprocess.CalledProcessError as e:
79                logging.error('Flash attempt #%d failed with return code %s', i + 1, e.returncode)
80
81            # It's a good idea to have some delay between flashes to avoid overloading the device.
82            # You can add sleep here if needed.
83
84        # After the loop, log the results of the stability test.
85        logging.info('Completed %d flash attempts with %d successes.', total_flashes, successful_flashes)
86
87        # Optionally, assert that all flashes were successful to mark the test as passed.
88        assert successful_flashes == total_flashes, 'Not all flash attempts were successful.'
89
90if __name__ == '__main__':
91    common_main()
92
93