1#!/usr/bin/env python3
2#
3# Copyright (C) 2021 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may not
6# use this file except in compliance with the License. You may obtain a copy of
7# the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations under
15# the License.
16"""
17Script for to flash Fuchsia devices and reports the DUT's version of Fuchsia in
18the Sponge test result properties. Uses the built in flashing tool for
19fuchsia_devices.
20"""
21from acts import asserts
22from acts import signals
23from acts.base_test import BaseTestClass
24from acts.utils import get_device
25
26MAX_FLASH_ATTEMPTS = 3
27
28
29class FlashTest(BaseTestClass):
30
31    def setup_class(self):
32        super().setup_class()
33        self.failed_to_get_version = False
34
35    def teardown_class(self):
36        # Verify that FlashTest successfully reported the DUT version. This is
37        # working around a flaw in ACTS where signals.TestAbortAll does not
38        # report any errors.
39        #
40        # TODO(http://b/253515812): This has been fixed in Mobly already. Remove
41        # teardown_class and change "TestError" to "abort_all" in
42        # test_flash_devices once we move to Mobly.
43        if self.failed_to_get_version:
44            asserts.abort_all('Failed to get DUT version')
45
46        return super().teardown_class()
47
48    def test_flash_devices(self):
49        for device in self.fuchsia_devices:
50            flash_counter = 0
51            while True:
52                try:
53                    device.reboot(reboot_type='flash',
54                                  use_ssh=True,
55                                  unreachable_timeout=120,
56                                  ping_timeout=120)
57                    self.log.info(f'{device.orig_ip} has been flashed.')
58                    break
59                except Exception as err:
60                    self.log.error(
61                        f'Failed to flash {device.orig_ip} with error:\n{err}')
62
63                    if not device.device_pdu_config:
64                        asserts.abort_all(
65                            f'Failed to flash {device.orig_ip} and no PDU available for hard reboot'
66                        )
67
68                    flash_counter = flash_counter + 1
69                    if flash_counter == MAX_FLASH_ATTEMPTS:
70                        asserts.abort_all(
71                            f'Failed to flash {device.orig_ip} after {MAX_FLASH_ATTEMPTS} attempts'
72                        )
73
74                    self.log.info(
75                        f'Hard rebooting {device.orig_ip} and retrying flash.')
76                    device.reboot(reboot_type='hard',
77                                  testbed_pdus=self.pdu_devices)
78
79        # Report the new Fuchsia version
80        try:
81            dut = get_device(self.fuchsia_devices, 'DUT')
82            version = dut.version()
83            self.record_data({'sponge_properties': {
84                'DUT_VERSION': version,
85            }})
86            self.log.info("DUT version found: {}".format(version))
87        except Exception as e:
88            self.failed_to_get_version = True
89            raise signals.TestError(f'Failed to get DUT version: {e}') from e
90