10516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 20516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller# Use of this source code is governed by a BSD-style license that can be 30516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller# found in the LICENSE file. 40516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 50516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 61968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Millerimport abc 70516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 80516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Millerimport common 9af30e7c634ccbcf14976e397ed372b1ddacee8d7Fang Dengfrom autotest_lib.server.cros import provision_actionables as actionables 100516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 110516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 120516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller### Constants for label prefixes 130516e4cdc45476e625fd105c43d1fd19f7b395eaAlex MillerCROS_VERSION_PREFIX = 'cros-version' 145ace6f2e17f808efbee863a7d7dbe1bc52527a19Simran BasiANDROID_BUILD_VERSION_PREFIX = 'ab-version' 150723bf5ed7ff506e15fea180547cb6a8ae9102ebDan ShiFW_RW_VERSION_PREFIX = 'fwrw-version' 1636cfd831af781eed114337efa5b90c103a49b502Dan ShiFW_RO_VERSION_PREFIX = 'fwro-version' 170516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 18e92399e32d4e83d7eb01b5c56e53c301a2a6dbc7Chris Sosa# Default number of provisions attempts to try if we believe the devserver is 19e92399e32d4e83d7eb01b5c56e53c301a2a6dbc7Chris Sosa# flaky. 20e92399e32d4e83d7eb01b5c56e53c301a2a6dbc7Chris SosaFLAKY_DEVSERVER_ATTEMPTS = 2 21e92399e32d4e83d7eb01b5c56e53c301a2a6dbc7Chris Sosa 220516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 230516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller### Helpers to convert value to label 240516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Millerdef cros_version_to_label(image): 250516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller """ 260516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller Returns the proper label name for a ChromeOS build of |image|. 270516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 280516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller @param image: A string of the form 'lumpy-release/R28-3993.0.0' 290516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller @returns: A string that is the appropriate label name. 300516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 310516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller """ 320516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller return CROS_VERSION_PREFIX + ':' + image 330516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 340516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 352d00cb2e9ac077edb0d268016653ac2d2e8ead80Tom Wai-Hong Tamdef fwro_version_to_label(image): 369cb0eec5538e2e1e6ca0b7d66daffb7701557cd6Dan Shi """ 372d00cb2e9ac077edb0d268016653ac2d2e8ead80Tom Wai-Hong Tam Returns the proper label name for a RO firmware build of |image|. 382d00cb2e9ac077edb0d268016653ac2d2e8ead80Tom Wai-Hong Tam 392d00cb2e9ac077edb0d268016653ac2d2e8ead80Tom Wai-Hong Tam @param image: A string of the form 'lumpy-release/R28-3993.0.0' 402d00cb2e9ac077edb0d268016653ac2d2e8ead80Tom Wai-Hong Tam @returns: A string that is the appropriate label name. 412d00cb2e9ac077edb0d268016653ac2d2e8ead80Tom Wai-Hong Tam 422d00cb2e9ac077edb0d268016653ac2d2e8ead80Tom Wai-Hong Tam """ 432d00cb2e9ac077edb0d268016653ac2d2e8ead80Tom Wai-Hong Tam return FW_RO_VERSION_PREFIX + ':' + image 442d00cb2e9ac077edb0d268016653ac2d2e8ead80Tom Wai-Hong Tam 452d00cb2e9ac077edb0d268016653ac2d2e8ead80Tom Wai-Hong Tam 462d00cb2e9ac077edb0d268016653ac2d2e8ead80Tom Wai-Hong Tamdef fwrw_version_to_label(image): 472d00cb2e9ac077edb0d268016653ac2d2e8ead80Tom Wai-Hong Tam """ 482d00cb2e9ac077edb0d268016653ac2d2e8ead80Tom Wai-Hong Tam Returns the proper label name for a RW firmware build of |image|. 499cb0eec5538e2e1e6ca0b7d66daffb7701557cd6Dan Shi 509cb0eec5538e2e1e6ca0b7d66daffb7701557cd6Dan Shi @param image: A string of the form 'lumpy-release/R28-3993.0.0' 519cb0eec5538e2e1e6ca0b7d66daffb7701557cd6Dan Shi @returns: A string that is the appropriate label name. 529cb0eec5538e2e1e6ca0b7d66daffb7701557cd6Dan Shi 539cb0eec5538e2e1e6ca0b7d66daffb7701557cd6Dan Shi """ 540723bf5ed7ff506e15fea180547cb6a8ae9102ebDan Shi return FW_RW_VERSION_PREFIX + ':' + image 559cb0eec5538e2e1e6ca0b7d66daffb7701557cd6Dan Shi 569cb0eec5538e2e1e6ca0b7d66daffb7701557cd6Dan Shi 571968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Millerclass _SpecialTaskAction(object): 581968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller """ 591968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller Base class to give a template for mapping labels to tests. 601968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller """ 611968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 621968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller __metaclass__ = abc.ABCMeta 631968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 641968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 651968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller # One cannot do 661968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller # @abc.abstractproperty 671968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller # _actions = {} 681968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller # so this is the next best thing 691968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller @abc.abstractproperty 701968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller def _actions(self): 711968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller """A dictionary mapping labels to test names.""" 721968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller pass 731968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 741968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 751968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller @abc.abstractproperty 761968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller def name(self): 771968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller """The name of this special task to be used in output.""" 781968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller pass 791968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 801968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 811968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller @classmethod 821968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller def acts_on(cls, label): 831968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller """ 841968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller Returns True if the label is a label that we recognize as something we 851968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller know how to act on, given our _actions. 861968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 871968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller @param label: The label as a string. 881968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller @returns: True if there exists a test to run for this label. 891968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 901968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller """ 911968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller return label.split(':')[0] in cls._actions 921968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 931968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 941968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller @classmethod 951968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller def test_for(cls, label): 961968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller """ 971968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller Returns the test associated with the given (string) label name. 981968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 991968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller @param label: The label for which the action is being requested. 1001968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller @returns: The string name of the test that should be run. 1011968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller @raises KeyError: If the name was not recognized as one we care about. 1021968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 1031968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller """ 1041968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller return cls._actions[label] 1050516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 1060516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 107aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller @classmethod 108aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller def partition(cls, labels): 109aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller """ 110aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller Filter a list of labels into two sets: those labels that we know how to 111aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller act on and those that we don't know how to act on. 112aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller 113aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller @param labels: A list of strings of labels. 114aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller @returns: A tuple where the first element is a set of unactionable 115aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller labels, and the second element is a set of the actionable 116aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller labels. 117aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller """ 118aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller capabilities = set() 119aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller configurations = set() 120aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller 121aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller for label in labels: 122aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller if cls.acts_on(label): 123aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller configurations.add(label) 124aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller else: 125aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller capabilities.add(label) 126aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller 127aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller return capabilities, configurations 128aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller 129aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller 1301968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Millerclass Verify(_SpecialTaskAction): 1310516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller """ 1321968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller Tests to verify that the DUT is in a sane, known good state that we can run 1331968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller tests on. Failure to verify leads to running Repair. 1341968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller """ 1351968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 1361968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller _actions = { 137af30e7c634ccbcf14976e397ed372b1ddacee8d7Fang Deng 'modem_repair': actionables.TestActionable('cellular_StaleModemReboot'), 1386f7e8005d5f6c4ce6a1d1256013c1e8d0c543c80Don Garrett # TODO(crbug.com/404421): set rpm action to power_RPMTest after the RPM 1396f7e8005d5f6c4ce6a1d1256013c1e8d0c543c80Don Garrett # is stable in lab (destiny). The power_RPMTest failure led to reset job 1406f7e8005d5f6c4ce6a1d1256013c1e8d0c543c80Don Garrett # failure and that left dut in Repair Failed. Since the test will fail 1416f7e8005d5f6c4ce6a1d1256013c1e8d0c543c80Don Garrett # anyway due to the destiny lab issue, and test retry will retry the 1426f7e8005d5f6c4ce6a1d1256013c1e8d0c543c80Don Garrett # test in another DUT. 1436f7e8005d5f6c4ce6a1d1256013c1e8d0c543c80Don Garrett # This change temporarily disable the RPM check in reset job. 1446f7e8005d5f6c4ce6a1d1256013c1e8d0c543c80Don Garrett # Another way to do this is to remove rpm dependency from tests' control 1456f7e8005d5f6c4ce6a1d1256013c1e8d0c543c80Don Garrett # file. That will involve changes on multiple control files. This one 1466f7e8005d5f6c4ce6a1d1256013c1e8d0c543c80Don Garrett # line change here is a simple temporary fix. 1476f7e8005d5f6c4ce6a1d1256013c1e8d0c543c80Don Garrett 'rpm': actionables.TestActionable('dummy_PassServer'), 1481968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller } 1490516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 1501968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller name = 'verify' 1510516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 1521968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 1531968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Millerclass Provision(_SpecialTaskAction): 1541968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller """ 1551968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller Provisioning runs to change the configuration of the DUT from one state to 1561968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller another. It will only be run on verified DUTs. 1570516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller """ 1580516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 1591968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller # TODO(milleral): http://crbug.com/249555 1601968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller # Create some way to discover and register provisioning tests so that we 1611968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller # don't need to hand-maintain a list of all of them. 1621968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller _actions = { 1639d548744ea61718c246bd30dffff06f46381981bFang Deng CROS_VERSION_PREFIX: actionables.TestActionable( 1649d548744ea61718c246bd30dffff06f46381981bFang Deng 'provision_AutoUpdate', 1659d548744ea61718c246bd30dffff06f46381981bFang Deng extra_kwargs={'disable_sysinfo': False, 1669d548744ea61718c246bd30dffff06f46381981bFang Deng 'disable_before_test_sysinfo': False, 1679d548744ea61718c246bd30dffff06f46381981bFang Deng 'disable_before_iteration_sysinfo': True, 1689d548744ea61718c246bd30dffff06f46381981bFang Deng 'disable_after_test_sysinfo': True, 1699d548744ea61718c246bd30dffff06f46381981bFang Deng 'disable_after_iteration_sysinfo': True}), 1709a2376144709693922273d777ff7f802055209c5Tom Wai-Hong Tam FW_RO_VERSION_PREFIX: actionables.TestActionable( 171af30e7c634ccbcf14976e397ed372b1ddacee8d7Fang Deng 'provision_FirmwareUpdate'), 1729a2376144709693922273d777ff7f802055209c5Tom Wai-Hong Tam FW_RW_VERSION_PREFIX: actionables.TestActionable( 1739a2376144709693922273d777ff7f802055209c5Tom Wai-Hong Tam 'provision_FirmwareUpdate', 1749a2376144709693922273d777ff7f802055209c5Tom Wai-Hong Tam extra_kwargs={'rw_only': True}), 1755ace6f2e17f808efbee863a7d7dbe1bc52527a19Simran Basi ANDROID_BUILD_VERSION_PREFIX : actionables.TestActionable( 1765ace6f2e17f808efbee863a7d7dbe1bc52527a19Simran Basi 'provision_AndroidUpdate'), 1771968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller } 1780516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 1791968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller name = 'provision' 1801968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 1811968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 1821968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Millerclass Cleanup(_SpecialTaskAction): 1830516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller """ 1841968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller Cleanup runs after a test fails to try and remove artifacts of tests and 1851968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller ensure the DUT will be in a sane state for the next test run. 1861968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller """ 1871968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 1881968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller _actions = { 189af30e7c634ccbcf14976e397ed372b1ddacee8d7Fang Deng 'cleanup-reboot': actionables.RebootActionable(), 1901968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller } 1910516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 1921968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller name = 'cleanup' 1930516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 1941968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 1951968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Millerclass Repair(_SpecialTaskAction): 1961968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller """ 1971968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller Repair runs when one of the other special tasks fails. It should be able 1981968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller to take a component of the DUT that's in an unknown state and restore it to 1991968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller a good state. 2000516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller """ 2011968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 2021968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller _actions = { 2031968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller } 2041968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 2051968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller name = 'repair' 2061968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 2071968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 2081968edf2c148ea01f0332613d9eeab383e7d2dd3Alex Miller 209aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller# TODO(milleral): crbug.com/364273 210aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller# Label doesn't really mean label in this context. We're putting things into 211aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller# DEPENDENCIES that really aren't DEPENDENCIES, and we should probably stop 212aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller# doing that. 213aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Millerdef is_for_special_action(label): 214aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller """ 215aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller If any special task handles the label specially, then we're using the label 216aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller to communicate that we want an action, and not as an actual dependency that 217aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller the test has. 218aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller 219aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller @param label: A string label name. 220aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller @return True if any special task handles this label specially, 221aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller False if no special task handles this label. 222aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller """ 223aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller return (Verify.acts_on(label) or 224aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller Provision.acts_on(label) or 225aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller Cleanup.acts_on(label) or 226aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller Repair.acts_on(label)) 2270516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 2280516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 2290516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Millerdef filter_labels(labels): 2300516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller """ 2310516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller Filter a list of labels into two sets: those labels that we know how to 2320516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller change and those that we don't. For the ones we know how to change, split 2330516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller them apart into the name of configuration type and its value. 2340516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 2350516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller @param labels: A list of strings of labels. 2360516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller @returns: A tuple where the first element is a set of unprovisionable 2370516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller labels, and the second element is a set of the provisionable 2380516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller labels. 2390516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 2400516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller >>> filter_labels(['bluetooth', 'cros-version:lumpy-release/R28-3993.0.0']) 2410516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller (set(['bluetooth']), set(['cros-version:lumpy-release/R28-3993.0.0'])) 2420516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 2430516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller """ 244aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller return Provision.partition(labels) 2450516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 2460516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 2470516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Millerdef split_labels(labels): 2480516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller """ 2490516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller Split a list of labels into a dict mapping name to value. All labels must 2500516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller be provisionable labels, or else a ValueError 2510516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 2520516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller @param labels: list of strings of label names 2530516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller @returns: A dict of where the key is the configuration name, and the value 2540516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller is the configuration value. 2550516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller @raises: ValueError if a label is not a provisionable label. 2560516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 2570516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller >>> split_labels(['cros-version:lumpy-release/R28-3993.0.0']) 2580516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller {'cros-version': 'lumpy-release/R28-3993.0.0'} 2590516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller >>> split_labels(['bluetooth']) 2600516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller Traceback (most recent call last): 2610516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller ... 2620516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller ValueError: Unprovisionable label bluetooth 2630516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 2640516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller """ 2650516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller configurations = dict() 2660516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 2670516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller for label in labels: 268aa77200876b530a3b37e6be3ed1e2c0b7098c9dcAlex Miller if Provision.acts_on(label): 2690516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller name, value = label.split(':', 1) 2700516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller configurations[name] = value 2710516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller else: 2720516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller raise ValueError('Unprovisionable label %s' % label) 2730516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 2740516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller return configurations 2750516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 2760516e4cdc45476e625fd105c43d1fd19f7b395eaAlex Miller 2772229c9c1c5553f781d595d508dcb715050940368Alex Millerdef join(provision_type, provision_value): 2782229c9c1c5553f781d595d508dcb715050940368Alex Miller """ 2792229c9c1c5553f781d595d508dcb715050940368Alex Miller Combine the provision type and value into the label name. 2802229c9c1c5553f781d595d508dcb715050940368Alex Miller 2812229c9c1c5553f781d595d508dcb715050940368Alex Miller @param provision_type: One of the constants that are the label prefixes. 2822229c9c1c5553f781d595d508dcb715050940368Alex Miller @param provision_value: A string of the value for this provision type. 2832229c9c1c5553f781d595d508dcb715050940368Alex Miller @returns: A string that is the label name for this (type, value) pair. 2842229c9c1c5553f781d595d508dcb715050940368Alex Miller 2852229c9c1c5553f781d595d508dcb715050940368Alex Miller >>> join(CROS_VERSION_PREFIX, 'lumpy-release/R27-3773.0.0') 2862229c9c1c5553f781d595d508dcb715050940368Alex Miller 'cros-version:lumpy-release/R27-3773.0.0' 2872229c9c1c5553f781d595d508dcb715050940368Alex Miller 2882229c9c1c5553f781d595d508dcb715050940368Alex Miller """ 2892229c9c1c5553f781d595d508dcb715050940368Alex Miller return '%s:%s' % (provision_type, provision_value) 2902229c9c1c5553f781d595d508dcb715050940368Alex Miller 2912229c9c1c5553f781d595d508dcb715050940368Alex Miller 292667b5f2b48c6096f944a34ca53e769c1031be45fAlex Millerclass SpecialTaskActionException(Exception): 293667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller """ 294667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller Exception raised when a special task fails to successfully run a test that 295667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller is required. 296667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller 297667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller This is also a literally meaningless exception. It's always just discarded. 298667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller """ 299667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller 300667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller 301667b5f2b48c6096f944a34ca53e769c1031be45fAlex Millerdef run_special_task_actions(job, host, labels, task): 302667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller """ 303667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller Iterate through all `label`s and run any tests on `host` that `task` has 304667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller corresponding to the passed in labels. 305667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller 306667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller Emits status lines for each run test, and INFO lines for each skipped label. 307667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller 308667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller @param job: A job object from a control file. 309667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller @param host: The host to run actions on. 310667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller @param labels: The list of job labels to work on. 311667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller @param task: An instance of _SpecialTaskAction. 312667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller @returns: None 313667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller @raises: SpecialTaskActionException if a test fails. 314667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller 315667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller """ 316667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller capabilities, configuration = filter_labels(labels) 317667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller 318667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller for label in capabilities: 319667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller if task.acts_on(label): 320af30e7c634ccbcf14976e397ed372b1ddacee8d7Fang Deng action_item = task.test_for(label) 321af30e7c634ccbcf14976e397ed372b1ddacee8d7Fang Deng success = action_item.execute(job=job, host=host) 322667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller if not success: 323667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller raise SpecialTaskActionException() 324667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller else: 325667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller job.record('INFO', None, task.name, 326667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller "Can't %s label '%s'." % (task.name, label)) 327667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller 328667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller for name, value in split_labels(configuration).items(): 329667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller if task.acts_on(name): 330af30e7c634ccbcf14976e397ed372b1ddacee8d7Fang Deng action_item = task.test_for(name) 331af30e7c634ccbcf14976e397ed372b1ddacee8d7Fang Deng success = action_item.execute(job=job, host=host, value=value) 332667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller if not success: 333667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller raise SpecialTaskActionException() 334667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller else: 335667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller job.record('INFO', None, task.name, 336667b5f2b48c6096f944a34ca53e769c1031be45fAlex Miller "Can't %s label '%s:%s'." % (task.name, name, value)) 337