xref: /aosp_15_r20/tools/asuite/atest/device_update.py (revision c2e18aaa1096c836b086f94603d04f4eb9cf37f5)
1*c2e18aaaSAndroid Build Coastguard Worker# Copyright 2023, The Android Open Source Project
2*c2e18aaaSAndroid Build Coastguard Worker#
3*c2e18aaaSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*c2e18aaaSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*c2e18aaaSAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*c2e18aaaSAndroid Build Coastguard Worker#
7*c2e18aaaSAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
8*c2e18aaaSAndroid Build Coastguard Worker#
9*c2e18aaaSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*c2e18aaaSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*c2e18aaaSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*c2e18aaaSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*c2e18aaaSAndroid Build Coastguard Worker# limitations under the License.
14*c2e18aaaSAndroid Build Coastguard Worker
15*c2e18aaaSAndroid Build Coastguard Worker"""Device update methods used to prepare the device under test."""
16*c2e18aaaSAndroid Build Coastguard Worker
17*c2e18aaaSAndroid Build Coastguard Workerfrom abc import ABC, abstractmethod
18*c2e18aaaSAndroid Build Coastguard Workerfrom pathlib import Path
19*c2e18aaaSAndroid Build Coastguard Workerimport subprocess
20*c2e18aaaSAndroid Build Coastguard Workerfrom subprocess import CalledProcessError
21*c2e18aaaSAndroid Build Coastguard Workerimport time
22*c2e18aaaSAndroid Build Coastguard Workerfrom typing import List, Set
23*c2e18aaaSAndroid Build Coastguard Worker
24*c2e18aaaSAndroid Build Coastguard Workerfrom atest import atest_utils
25*c2e18aaaSAndroid Build Coastguard Workerfrom atest import constants
26*c2e18aaaSAndroid Build Coastguard Worker
27*c2e18aaaSAndroid Build Coastguard Worker
28*c2e18aaaSAndroid Build Coastguard Workerclass DeviceUpdateMethod(ABC):
29*c2e18aaaSAndroid Build Coastguard Worker  """A device update method used to update device."""
30*c2e18aaaSAndroid Build Coastguard Worker
31*c2e18aaaSAndroid Build Coastguard Worker  @abstractmethod
32*c2e18aaaSAndroid Build Coastguard Worker  def update(self, serials: List[str] = None):
33*c2e18aaaSAndroid Build Coastguard Worker    """Updates the device.
34*c2e18aaaSAndroid Build Coastguard Worker
35*c2e18aaaSAndroid Build Coastguard Worker    Args:
36*c2e18aaaSAndroid Build Coastguard Worker        serials: A list of serial numbers.
37*c2e18aaaSAndroid Build Coastguard Worker
38*c2e18aaaSAndroid Build Coastguard Worker    Raises:
39*c2e18aaaSAndroid Build Coastguard Worker        Error: If the device update fails.
40*c2e18aaaSAndroid Build Coastguard Worker    """
41*c2e18aaaSAndroid Build Coastguard Worker
42*c2e18aaaSAndroid Build Coastguard Worker  @abstractmethod
43*c2e18aaaSAndroid Build Coastguard Worker  def dependencies(self) -> Set[str]:
44*c2e18aaaSAndroid Build Coastguard Worker    """Returns the dependencies required by this device update method."""
45*c2e18aaaSAndroid Build Coastguard Worker
46*c2e18aaaSAndroid Build Coastguard Worker
47*c2e18aaaSAndroid Build Coastguard Workerclass NoopUpdateMethod(DeviceUpdateMethod):
48*c2e18aaaSAndroid Build Coastguard Worker
49*c2e18aaaSAndroid Build Coastguard Worker  def update(self, serials: List[str] = None) -> None:
50*c2e18aaaSAndroid Build Coastguard Worker    pass
51*c2e18aaaSAndroid Build Coastguard Worker
52*c2e18aaaSAndroid Build Coastguard Worker  def dependencies(self) -> Set[str]:
53*c2e18aaaSAndroid Build Coastguard Worker    return set()
54*c2e18aaaSAndroid Build Coastguard Worker
55*c2e18aaaSAndroid Build Coastguard Worker
56*c2e18aaaSAndroid Build Coastguard Workerclass AdeviceUpdateMethod(DeviceUpdateMethod):
57*c2e18aaaSAndroid Build Coastguard Worker  _TOOL = 'adevice'
58*c2e18aaaSAndroid Build Coastguard Worker
59*c2e18aaaSAndroid Build Coastguard Worker  def __init__(self, adevice_path: Path=_TOOL, targets: Set[str]=None):
60*c2e18aaaSAndroid Build Coastguard Worker    self._adevice_path = adevice_path
61*c2e18aaaSAndroid Build Coastguard Worker    self._targets = targets or set(['sync'])
62*c2e18aaaSAndroid Build Coastguard Worker
63*c2e18aaaSAndroid Build Coastguard Worker  def update(self, serials: List[str] = None) -> None:
64*c2e18aaaSAndroid Build Coastguard Worker    try:
65*c2e18aaaSAndroid Build Coastguard Worker      print(atest_utils.mark_cyan('\nUpdating device...'))
66*c2e18aaaSAndroid Build Coastguard Worker      update_start = time.time()
67*c2e18aaaSAndroid Build Coastguard Worker
68*c2e18aaaSAndroid Build Coastguard Worker      update_cmd = [self._adevice_path, 'update']
69*c2e18aaaSAndroid Build Coastguard Worker      if serials:
70*c2e18aaaSAndroid Build Coastguard Worker        if len(serials) > 1:
71*c2e18aaaSAndroid Build Coastguard Worker          atest_utils.colorful_print(
72*c2e18aaaSAndroid Build Coastguard Worker              'Warning: Device update feature can only update one '
73*c2e18aaaSAndroid Build Coastguard Worker              'device for now, but this invocation specifies more '
74*c2e18aaaSAndroid Build Coastguard Worker              'than one device. Atest will update the first device '
75*c2e18aaaSAndroid Build Coastguard Worker              'by default.',
76*c2e18aaaSAndroid Build Coastguard Worker              constants.YELLOW,
77*c2e18aaaSAndroid Build Coastguard Worker          )
78*c2e18aaaSAndroid Build Coastguard Worker
79*c2e18aaaSAndroid Build Coastguard Worker        update_cmd.extend(['--serial', serials[0]])
80*c2e18aaaSAndroid Build Coastguard Worker
81*c2e18aaaSAndroid Build Coastguard Worker      subprocess.check_call(update_cmd)
82*c2e18aaaSAndroid Build Coastguard Worker
83*c2e18aaaSAndroid Build Coastguard Worker      print(
84*c2e18aaaSAndroid Build Coastguard Worker          atest_utils.mark_cyan(
85*c2e18aaaSAndroid Build Coastguard Worker              '\nDevice update finished in '
86*c2e18aaaSAndroid Build Coastguard Worker              f'{str(round(time.time() - update_start, 2))}s.'
87*c2e18aaaSAndroid Build Coastguard Worker          )
88*c2e18aaaSAndroid Build Coastguard Worker      )
89*c2e18aaaSAndroid Build Coastguard Worker
90*c2e18aaaSAndroid Build Coastguard Worker    except CalledProcessError as e:
91*c2e18aaaSAndroid Build Coastguard Worker      raise Error('Failed to update the device with adevice') from e
92*c2e18aaaSAndroid Build Coastguard Worker
93*c2e18aaaSAndroid Build Coastguard Worker  def dependencies(self) -> Set[str]:
94*c2e18aaaSAndroid Build Coastguard Worker    return self._targets.union({self._TOOL})
95*c2e18aaaSAndroid Build Coastguard Worker
96*c2e18aaaSAndroid Build Coastguard Worker
97*c2e18aaaSAndroid Build Coastguard Workerclass Error(Exception):
98*c2e18aaaSAndroid Build Coastguard Worker  pass
99