Snap for 4632767 from c1d8463aac0b2a3a8b684e702ddd29cf335aa5fb to pi-release
Change-Id: I0a35f7fabafbd7db5a1ba2ddb478358ac9072152
diff --git a/.style.yapf b/.style.yapf
new file mode 100644
index 0000000..e36cf68
--- /dev/null
+++ b/.style.yapf
@@ -0,0 +1,3 @@
+[style]
+based_on_style = pep8
+continuation_indent_width = 8
diff --git a/cli/server.py b/cli/server.py
index b318d73..eea5738 100644
--- a/cli/server.py
+++ b/cli/server.py
@@ -23,12 +23,19 @@
from autotest_lib.cli import action_common
from autotest_lib.cli import topic_common
from autotest_lib.client.common_lib import error
+from autotest_lib.client.common_lib import global_config
# The django setup is moved here as test_that uses sqlite setup. If this line
# is in server_manager, test_that unittest will fail.
from autotest_lib.frontend import setup_django_environment
from autotest_lib.site_utils import server_manager
from autotest_lib.site_utils import server_manager_utils
+RESPECT_SKYLAB_SERVERDB = global_config.global_config.get_config_value(
+ 'SKYLAB', 'respect_skylab_serverdb', type=bool, default=False)
+ATEST_DISABLE_MSG = ('Updating server_db via atest server command has been '
+ 'disabled. Please use use go/cros-infra-inventory-tool '
+ 'to update it in skylab inventory service.')
+
class server(topic_common.atest):
"""Server class
@@ -230,6 +237,11 @@
@return: A Server object if it is created successfully.
"""
+ if RESPECT_SKYLAB_SERVERDB:
+ self.failure(ATEST_DISABLE_MSG,
+ what_failed='Failed to create server',
+ item=self.hostname, fatal=True)
+
try:
return server_manager.create(hostname=self.hostname, role=self.role,
note=self.note)
@@ -258,6 +270,11 @@
@return: True if server is deleted successfully.
"""
+ if RESPECT_SKYLAB_SERVERDB:
+ self.failure(ATEST_DISABLE_MSG,
+ what_failed='Failed to delete server',
+ item=self.hostname, fatal=True)
+
try:
server_manager.delete(hostname=self.hostname)
return True
@@ -360,6 +377,11 @@
@return: The updated server object if it is modified successfully.
"""
+ if RESPECT_SKYLAB_SERVERDB:
+ self.failure(ATEST_DISABLE_MSG,
+ what_failed='Failed to modify server',
+ item=self.hostname, fatal=True)
+
try:
return server_manager.modify(hostname=self.hostname, role=self.role,
status=self.status, delete=self.delete,
diff --git a/client/common_lib/cros/chromedriver.py b/client/common_lib/cros/chromedriver.py
index 4ef3ed7..5ca011e 100644
--- a/client/common_lib/cros/chromedriver.py
+++ b/client/common_lib/cros/chromedriver.py
@@ -31,7 +31,8 @@
extension_paths=[], username=None, password=None,
server_port=None, skip_cleanup=False, url_base=None,
extra_chromedriver_args=None, gaia_login=False,
- disable_default_apps=True, *args, **kwargs):
+ disable_default_apps=True, dont_override_profile=False, *args,
+ **kwargs):
"""Initialize.
@param extra_chrome_flags: Extra chrome flags to pass to chrome, if any.
@@ -51,6 +52,9 @@
the chromedriver binary, if any.
@param gaia_login: Logs in to real gaia.
@param disable_default_apps: For tests that exercise default apps.
+ @param dont_override_profile: Don't delete cryptohome before login.
+ Telemetry will output a warning with this
+ option.
"""
self._cleanup = not skip_cleanup
assert os.geteuid() == 0, 'Need superuser privileges'
@@ -61,7 +65,9 @@
password=password,
extra_browser_args=extra_chrome_flags,
gaia_login=gaia_login,
- disable_default_apps=disable_default_apps)
+ disable_default_apps=disable_default_apps,
+ dont_override_profile=dont_override_profile
+ )
self._browser = self._chrome.browser
# Close all tabs owned and opened by Telemetry, as these cannot be
# transferred to ChromeDriver.
diff --git a/client/common_lib/error.py b/client/common_lib/error.py
index 822a4bb..a10c952 100644
--- a/client/common_lib/error.py
+++ b/client/common_lib/error.py
@@ -459,6 +459,10 @@
"""Raised when an RPC tries to modify static labels."""
+class UnmodifiableAttributeException(RPCException):
+ """Raised when an RPC tries to modify static attributes."""
+
+
class InvalidBgJobCall(Exception):
"""Raised when an invalid call is made to a BgJob object."""
diff --git a/client/common_lib/utils.py b/client/common_lib/utils.py
index 8b4d885..a2e1d41 100644
--- a/client/common_lib/utils.py
+++ b/client/common_lib/utils.py
@@ -1832,24 +1832,21 @@
WIRELESS_SSID_PATTERN = 'wireless_ssid_(.*)/(\d+)'
-def get_built_in_ethernet_nic_name():
+def get_moblab_serial_number():
"""Gets the moblab public network interface.
If the eth0 is an USB interface, try to use eth1 instead. Otherwise
use eth0 by default.
"""
try:
- cmd_result = run('readlink -f /sys/class/net/eth0')
- if cmd_result.exit_status == 0 and 'usb' in cmd_result.stdout:
- cmd_result = run('readlink -f /sys/class/net/eth1')
- if cmd_result.exit_status == 0 and not ('usb' in cmd_result.stdout):
- logging.info('Eth0 is a USB dongle, use eth1 as moblab nic.')
- return _MOBLAB_ETH_1
- except error.CmdError:
- # readlink is not supported.
- logging.info('No readlink available, use eth0 as moblab nic.')
+ cmd_result = run('sudo vpd -g serial_number')
+ if cmd_result.stdout:
+ return cmd_result.stdout
+ except error.CmdError as e:
+ logging.error(str(e))
+ logging.info('Serial number ')
pass
- return _MOBLAB_ETH_0
+ return 'NoSerialNumber'
def ping(host, deadline=None, tries=None, timeout=60, user=None):
@@ -1957,24 +1954,6 @@
return None
-def get_default_interface_mac_address():
- """Returns the default moblab MAC address."""
- return get_interface_mac_address(
- get_built_in_ethernet_nic_name())
-
-
-def get_interface_mac_address(interface):
- """Return the MAC address of a given interface.
-
- @param interface: Interface to look up the MAC address of.
- """
- interface_link = run(
- 'ip addr show %s | grep link/ether' % interface).stdout
- # The output will be in the format of:
- # 'link/ether <mac> brd ff:ff:ff:ff:ff:ff'
- return interface_link.split()[1]
-
-
def get_moblab_id():
"""Gets the moblab random id.
@@ -2024,9 +2003,7 @@
if not gsuri:
gsuri = "%sresults/" % CONFIG.get_config_value('CROS', 'image_storage_server')
- return '%s%s/%s/' % (
- gsuri, get_interface_mac_address(get_built_in_ethernet_nic_name()),
- get_moblab_id())
+ return '%s%s/%s/' % (gsuri, get_moblab_serial_number(), get_moblab_id())
# TODO(petermayo): crosbug.com/31826 Share this with _GsUpload in
diff --git a/client/common_lib/utils_unittest.py b/client/common_lib/utils_unittest.py
index 092d747..3e31508 100755
--- a/client/common_lib/utils_unittest.py
+++ b/client/common_lib/utils_unittest.py
@@ -1118,10 +1118,10 @@
'CROS', 'image_storage_server').and_return(
self._IMAGE_STORAGE_SERVER)
self.god.stub_function_to_return(utils,
- 'get_interface_mac_address', 'test_mac')
+ 'get_moblab_serial_number', 'test_serial_number')
self.god.stub_function_to_return(utils, 'get_moblab_id', 'test_id')
expected_gsuri = '%sresults/%s/%s/' % (
- self._IMAGE_STORAGE_SERVER, 'test_mac', 'test_id')
+ self._IMAGE_STORAGE_SERVER, 'test_serial_number', 'test_id')
cached_gsuri = utils.DEFAULT_OFFLOAD_GSURI
utils.DEFAULT_OFFLOAD_GSURI = None
gsuri = utils.get_offload_gsuri()
@@ -1135,66 +1135,15 @@
self.god.mock_up(utils.CONFIG, 'CONFIG')
self.god.stub_function_to_return(utils, 'is_moblab', True)
self.god.stub_function_to_return(utils,
- 'get_interface_mac_address', 'test_mac')
+ 'get_moblab_serial_number', 'test_serial_number')
self.god.stub_function_to_return(utils, 'get_moblab_id', 'test_id')
gsuri = '%s%s/%s/' % (
- utils.DEFAULT_OFFLOAD_GSURI, 'test_mac', 'test_id')
+ utils.DEFAULT_OFFLOAD_GSURI, 'test_serial_number', 'test_id')
self.assertEqual(gsuri, utils.get_offload_gsuri())
self.god.check_playback()
-class GetBuiltinEthernetNicNameTest(unittest.TestCase):
- """Test get moblab public network interface name."""
-
- def setUp(self):
- self.god = mock.mock_god()
-
- def tearDown(self):
- self.god.unstub_all()
-
- def test_is_eth0(self):
- """Test when public network interface is eth0."""
- run_func = self.god.create_mock_function('run_func')
- self.god.stub_with(utils, 'run', run_func)
- run_func.expect_call('readlink -f /sys/class/net/eth0').and_return(
- utils.CmdResult(exit_status=0, stdout='not_u_s_b'))
- eth = utils.get_built_in_ethernet_nic_name()
- self.assertEqual('eth0', eth)
- self.god.check_playback()
-
- def test_readlin_fails(self):
- """Test when readlink does not work."""
- run_func = self.god.create_mock_function('run_func')
- self.god.stub_with(utils, 'run', run_func)
- run_func.expect_call('readlink -f /sys/class/net/eth0').and_return(
- utils.CmdResult(exit_status=-1, stdout='blah'))
- eth = utils.get_built_in_ethernet_nic_name()
- self.assertEqual('eth0', eth)
- self.god.check_playback()
-
- def test_no_readlink(self):
- """Test when readlink does not exist."""
- run_func = self.god.create_mock_function('run_func')
- self.god.stub_with(utils, 'run', run_func)
- run_func.expect_call('readlink -f /sys/class/net/eth0').and_raises(
- error.CmdError('readlink', 'no such command'))
- eth = utils.get_built_in_ethernet_nic_name()
- self.assertEqual('eth0', eth)
- self.god.check_playback()
-
- def test_is_eth1(self):
- """Test when public network interface is eth1."""
- run_func = self.god.create_mock_function('run_func')
- self.god.stub_with(utils, 'run', run_func)
- run_func.expect_call('readlink -f /sys/class/net/eth0').and_return(
- utils.CmdResult(exit_status=0, stdout='is usb'))
- run_func.expect_call('readlink -f /sys/class/net/eth1').and_return(
- utils.CmdResult(exit_status=0, stdout='not_u_s_b'))
- eth = utils.get_built_in_ethernet_nic_name()
- self.assertEqual('eth1', eth)
- self.god.check_playback()
-
class MockMetricsTest(unittest.TestCase):
"""Test metrics mock class can handle various metrics calls."""
diff --git a/client/cros/enterprise/enterprise_policy_base.py b/client/cros/enterprise/enterprise_policy_base.py
index 6cf9371..0d701f8 100755
--- a/client/cros/enterprise/enterprise_policy_base.py
+++ b/client/cros/enterprise/enterprise_policy_base.py
@@ -162,7 +162,7 @@
def setup_case(self, user_policies={}, suggested_user_policies={},
device_policies={}, skip_policy_value_verification=False,
enroll=False, auto_login=True, auto_logout=True,
- extra_chrome_flags=[]):
+ extra_chrome_flags=[], init_network_controller=False):
"""Set up DMS, log in, and verify policy values.
If the AutoTest fake DM Server is used, make a JSON policy blob
@@ -183,6 +183,7 @@
@param auto_login: Sign in to chromeos.
@param auto_logout: Sign out of chromeos when test is complete.
@param extra_chrome_flags: list of flags to add to Chrome.
+ @param init_network_controller: whether to init network controller.
@raises error.TestError if cryptohome vault is not mounted for user.
@raises error.TestFail if |policy_name| and |policy_value| are not
@@ -195,7 +196,8 @@
user_policies, suggested_user_policies, device_policies))
self._create_chrome(enroll=enroll, auto_login=auto_login,
- extra_chrome_flags=extra_chrome_flags)
+ extra_chrome_flags=extra_chrome_flags,
+ init_network_controller=init_network_controller)
# Skip policy check upon request or if we enroll but don't log in.
skip_policy_value_verification = (
@@ -502,7 +504,7 @@
def _create_chrome(self, enroll=False, auto_login=True,
- extra_chrome_flags=[]):
+ extra_chrome_flags=[], init_network_controller=False):
"""
Create a Chrome object. Enroll and/or sign in.
@@ -511,6 +513,7 @@
@param enroll: enroll the device.
@param auto_login: sign in to chromeos.
@param extra_chrome_flags: list of flags to add.
+ @param init_network_controller: whether to init network controller.
"""
extra_flags = self._initialize_chrome_extra_flags() + extra_chrome_flags
@@ -540,6 +543,7 @@
gaia_login=not self.dms_is_fake,
disable_gaia_services=self.dms_is_fake,
autotest_ext=True,
+ init_network_controller=init_network_controller,
expect_policy_fetch=True)
else:
self.cr = chrome.Chrome(auto_login=False,
@@ -561,6 +565,7 @@
@param url: URL of web page to load.
@param tab: browser tab to load (if any).
@returns: browser tab loaded with web page.
+ @raises: telemetry TimeoutException if document ready state times out.
"""
logging.info('Navigating to URL: %r', url)
if not tab:
diff --git a/client/cros/faft/rpc_functions.py b/client/cros/faft/rpc_functions.py
index 134c21b..08cea57 100755
--- a/client/cros/faft/rpc_functions.py
+++ b/client/cros/faft/rpc_functions.py
@@ -28,16 +28,16 @@
@param image_operator: Method accepting one section as its argument.
"""
@functools.wraps(image_operator)
- def wrapper(self, section):
+ def wrapper(self, section, *args, **dargs):
"""Wrapper method to support multiple sections.
@param section: A list of sections of just a section.
"""
if type(section) in (tuple, list):
for sec in section:
- image_operator(self, sec)
+ image_operator(self, sec, *args, **dargs)
else:
- image_operator(self, section)
+ image_operator(self, section, *args, **dargs)
return wrapper
@@ -403,12 +403,12 @@
self._bios_handler.restore_firmware(section)
@allow_multiple_section_input
- def _bios_corrupt_body(self, section):
+ def _bios_corrupt_body(self, section, corrupt_all=False):
"""Corrupt the requested firmware section body.
@param section: A firmware section, either 'a' or 'b'.
"""
- self._bios_handler.corrupt_firmware_body(section)
+ self._bios_handler.corrupt_firmware_body(section, corrupt_all)
@allow_multiple_section_input
def _bios_restore_body(self, section):
diff --git a/client/cros/input_playback/keyboard_search+f2 b/client/cros/input_playback/keyboard_search+f2
new file mode 100644
index 0000000..2f79ca5
--- /dev/null
+++ b/client/cros/input_playback/keyboard_search+f2
@@ -0,0 +1,15 @@
+E: 1519163506.723783 0004 0004 28
+E: 1519163506.723783 0001 001c 0
+E: 1519163506.723783 0000 0000 0
+E: 1519163507.976769 0004 0004 219
+E: 1519163507.976769 0001 007d 1
+E: 1519163507.976769 0000 0000 0
+E: 1519163508.071699 0004 0004 60
+E: 1519163508.071699 0001 003c 1
+E: 1519163508.071699 0000 0000 0
+E: 1519163508.154624 0004 0004 60
+E: 1519163508.154624 0001 003c 0
+E: 1519163508.154624 0000 0000 0
+E: 1519163508.216392 0004 0004 219
+E: 1519163508.216392 0001 007d 0
+E: 1519163508.216392 0000 0000 0
diff --git a/client/cros/liststorage.py b/client/cros/liststorage.py
index 9aaeec8..f252abc 100644
--- a/client/cros/liststorage.py
+++ b/client/cros/liststorage.py
@@ -15,7 +15,7 @@
|get_all()| output is human readable (as oppposite to python's data structures)
"""
-import os, re
+import logging, os, re
# this script can be run at command line on DUT (ie /usr/local/autotest
# contains only the client/ subtree), on a normal autotest
@@ -24,7 +24,13 @@
from autotest_lib.client.common_lib import utils
INFO_PATH = "/sys/block"
-
+UDEV_CMD_FOR_SERIAL_NUMBER = "udevadm info -a -n %s | grep -iE 'ATTRS{" \
+ "serial}' | head -n 1"
+LSUSB_CMD = "lsusb -v | grep -iE '^Device Desc|bcdUSB|iSerial'"
+DESC_PATTERN = r'Device Descriptor:'
+BCDUSB_PATTERN = r'bcdUSB\s+(\d+\.\d+)'
+ISERIAL_PATTERN = r'iSerial\s+\d\s(\S*)'
+UDEV_SERIAL_PATTERN = r'=="(.*)"'
def get_udev_info(blockdev, method='udev'):
"""Get information about |blockdev|
@@ -64,6 +70,54 @@
return ret
+def get_usbdevice_type_and_serial(device):
+ """Get USB device type and Serial number
+
+ @param device: USB device mount point Example: /dev/sda or /dev/sdb
+ @return: Returns the information about USB type and the serial number
+ of the device
+ """
+ usb_info_list = []
+ # Getting the USB type and Serial number info using 'lsusb -v'. Sample
+ # output is shown in below
+ # Device Descriptor:
+ # bcdUSB 2.00
+ # iSerial 3 131BC7
+ # bcdUSB 2.00
+ # Device Descriptor:
+ # bcdUSB 2.10
+ # iSerial 3 001A4D5E8634B03169273995
+
+ lsusb_output = utils.system_output(LSUSB_CMD)
+ # we are parsing each line and getting the usb info
+ for line in lsusb_output.splitlines():
+ desc_matched = re.search(DESC_PATTERN, line)
+ bcdusb_matched = re.search(BCDUSB_PATTERN, line)
+ iserial_matched = re.search(ISERIAL_PATTERN, line)
+ if desc_matched:
+ usb_info = {}
+ elif bcdusb_matched:
+ # bcdUSB may appear multiple time. Drop the remaining.
+ usb_info['bcdUSB'] = bcdusb_matched.group(1)
+ elif iserial_matched:
+ usb_info['iSerial'] = iserial_matched.group(1)
+ usb_info_list.append(usb_info)
+ logging.debug('lsusb output is %s', usb_info_list)
+ # Comparing the lsusb serial number with udev output serial number
+ # Both serial numbers should be same. Sample udev command output is
+ # shown in below.
+ # ATTRS{serial}=="001A4D5E8634B03169273995"
+ udev_serial_output = utils.system_output(UDEV_CMD_FOR_SERIAL_NUMBER %
+ device)
+ udev_serial_matched = re.search(UDEV_SERIAL_PATTERN, udev_serial_output)
+ if udev_serial_matched:
+ udev_serial = udev_serial_matched.group(1)
+ logging.debug("udev serial number is %s", udev_serial)
+ for usb_details in usb_info_list:
+ if usb_details['iSerial'] == udev_serial:
+ return usb_details.get('bcdUSB'), udev_serial
+ return None, None
+
def get_partition_info(part_path, bus, model, partid=None, fstype=None,
label=None, block_size=0, is_removable=False):
"""Return information about a device as a list of dictionaries
@@ -130,6 +184,8 @@
dev['fstype'] = proc_fstype
dev['is_mounted'] = True
dev['mountpoint'] = mount
+ dev['usb_type'], dev['serial'] = \
+ get_usbdevice_type_and_serial(dev['device'])
ret.append(dev)
# If not among mounted devices, it's just attached, print about the
@@ -137,13 +193,13 @@
# device instead
if not seen:
# we consider it if it's removable and and a partition id
- # OR it's on the USB bus.
+ # OR it's on the USB bus or ATA bus.
# Some USB HD do not get announced as removable, but they should be
# showed.
# There are good changes that if it's on a USB bus it's removable
# and thus interesting for us, independently whether it's declared
# removable
- if (is_removable and partid) or bus == 'usb':
+ if (is_removable and partid) or bus in ['usb', 'ata']:
if not label:
info = get_udev_info(device, 'blkid')
label = info.get('ID_FS_LABEL', partid)
@@ -153,8 +209,9 @@
dev['fstype'] = fstype
dev['is_mounted'] = False
dev['mountpoint'] = "/media/removable/%s" % label
+ dev['usb_type'], dev['serial'] = \
+ get_usbdevice_type_and_serial(dev['device'])
ret.append(dev)
-
return ret
@@ -222,7 +279,8 @@
def main():
for device in get_all():
print ("%(device)s %(bus)s %(model)s %(size)d %(fs_uuid)s %(fstype)s "
- "%(is_mounted)d %(mountpoint)s" % device)
+ "%(is_mounted)d %(mountpoint)s %(usb_type)s %(serial)s" %
+ device)
if __name__ == "__main__":
diff --git a/client/cros/multimedia/input_facade_native.py b/client/cros/multimedia/input_facade_native.py
index 83d0494..8c36245 100644
--- a/client/cros/multimedia/input_facade_native.py
+++ b/client/cros/multimedia/input_facade_native.py
@@ -10,6 +10,7 @@
from autotest_lib.client.bin.input import input_event_recorder
from autotest_lib.client.common_lib import error
+from autotest_lib.client.cros.graphics import graphics_utils
class InputFacadeNativeError(Exception):
@@ -67,3 +68,11 @@
raise error.TestError('input facade: input device name not given')
events = self.recorder.get_events()
return json.dumps(events)
+
+
+ def press_keys(self, key_list):
+ """ Simulating key press
+
+ @param key_list: A list of key strings, e.g. ['LEFTCTRL', 'F4']
+ """
+ graphics_utils.press_keys(key_list)
diff --git a/client/cros/update_engine/nano_omaha_devserver.py b/client/cros/update_engine/nano_omaha_devserver.py
index dd030c6..dcb00c3 100644
--- a/client/cros/update_engine/nano_omaha_devserver.py
+++ b/client/cros/update_engine/nano_omaha_devserver.py
@@ -18,6 +18,16 @@
class NanoOmahaDevserver(object):
"""A simple Omaha instance that can be setup on a DUT in client tests."""
+ def __init__(self, eol=False):
+ """
+ Create a nano omaha devserver.
+
+ @param eol: True if we should return a response with _eol flag
+
+ """
+ self._eol = eol
+
+
class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
"""Inner class for handling HTTP requests."""
@@ -40,7 +50,7 @@
sha256=\"%s\"
needsadmin=\"false\"
IsDeltaPayload=\"%s\"
-"""
+ """
_OMAHA_RESPONSE_TEMPLATE_TAIL = """ />
</actions>
@@ -48,32 +58,46 @@
</updatecheck>
</app>
</response>
-"""
+ """
+
+ _OMAHA_RESPONSE_EOL = """
+ <response protocol=\"3.0\">
+ <daystart elapsed_seconds=\"44801\"/>
+ <app appid=\"{87efface-864d-49a5-9bb3-4b050a7c227a}\" status=\"ok\">
+ <ping status=\"ok\"/>
+ <updatecheck _eol=\"eol\" status=\"noupdate\"/>
+ </app>
+ </response>
+ """
def do_POST(self):
"""Handler for POST requests."""
if self.path == '/update':
- (base, name) = _split_url(self.server._devserver._image_url)
- response = self._OMAHA_RESPONSE_TEMPLATE_HEAD % (
- base + '/',
- name,
- self.server._devserver._image_size,
- self.server._devserver._sha256,
- str(self.server._devserver._is_delta).lower())
- if self.server._devserver._is_delta:
- response += ' IsDelta="true"\n'
- if self.server._devserver._critical:
- response += ' deadline="now"\n'
- if self.server._devserver._metadata_size:
- response += ' MetadataSize="%d"\n' % (
- self.server._devserver._metadata_size)
- if self.server._devserver._metadata_signature:
- response += ' MetadataSignatureRsa="%s"\n' % (
- self.server._devserver._metadata_signature)
- if self.server._devserver._public_key:
- response += ' PublicKeyRsa="%s"\n' % (
- self.server._devserver._public_key)
- response += self._OMAHA_RESPONSE_TEMPLATE_TAIL
+ if self.server._devserver._eol:
+ response = self._OMAHA_RESPONSE_EOL
+ else:
+ (base, name) = _split_url(self.server._devserver._image_url)
+ response = self._OMAHA_RESPONSE_TEMPLATE_HEAD % (
+ base + '/',
+ name,
+ self.server._devserver._image_size,
+ self.server._devserver._sha256,
+ str(self.server._devserver._is_delta).lower())
+ if self.server._devserver._is_delta:
+ response += ' IsDelta="true"\n'
+ if self.server._devserver._critical:
+ response += ' deadline="now"\n'
+ if self.server._devserver._metadata_size:
+ response += ' MetadataSize="%d"\n' % (
+ self.server._devserver._metadata_size)
+ if self.server._devserver._metadata_signature:
+ response += ' ' \
+ 'MetadataSignatureRsa="%s"\n' % (
+ self.server._devserver._metadata_signature)
+ if self.server._devserver._public_key:
+ response += ' PublicKeyRsa="%s"\n' % (
+ self.server._devserver._public_key)
+ response += self._OMAHA_RESPONSE_TEMPLATE_TAIL
self.send_response(200)
self.send_header('Content-Type', 'application/xml')
self.end_headers()
@@ -110,4 +134,4 @@
self._metadata_signature = metadata_signature
self._public_key = public_key
self._is_delta = is_delta
- self._critical = critical
\ No newline at end of file
+ self._critical = critical
diff --git a/client/cros/video/device_capability.py b/client/cros/video/device_capability.py
index ad9d090..de97026 100644
--- a/client/cros/video/device_capability.py
+++ b/client/cros/video/device_capability.py
@@ -119,7 +119,7 @@
try:
return self.capabilities[cap]
except KeyError:
- raise error.TestFail("Unexpected capability: %s" % capability)
+ raise error.TestFail("Unexpected capability: %s" % cap)
def ensure_capability(self, cap):
@@ -128,3 +128,10 @@
"""
if self.get_capability(cap) != 'yes':
raise error.TestNAError("Missing Capability: %s" % cap)
+
+
+ def have_capability(self, cap):
+ """
+ Return whether cap is available.
+ """
+ return self.get_capability(cap) == 'yes'
diff --git a/client/site_tests/autoupdate_EOL/autoupdate_EOL.py b/client/site_tests/autoupdate_EOL/autoupdate_EOL.py
new file mode 100644
index 0000000..55f9b6e
--- /dev/null
+++ b/client/site_tests/autoupdate_EOL/autoupdate_EOL.py
@@ -0,0 +1,64 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+import logging
+import shutil
+
+from autotest_lib.client.bin import test, utils
+from autotest_lib.client.common_lib import error
+from autotest_lib.client.common_lib.cros import chrome
+from autotest_lib.client.cros.update_engine import nano_omaha_devserver
+
+class autoupdate_EOL(test.test):
+ """Tests end of life (EOL) behaviour."""
+ version = 1
+
+ _EXPECTED_EOL_STATUS = 'EOL_STATUS=eol'
+ _EOL_NOTIFICATION_TITLE = 'This device is no longer supported'
+
+ def cleanup(self):
+ shutil.copy('/var/log/update_engine.log', self.resultsdir)
+ self._omaha.stop()
+
+
+ def _check_eol_status(self):
+ """Checks update_engines eol status."""
+ result = utils.run('update_engine_client --eol_status').stdout.strip()
+ if result != self._EXPECTED_EOL_STATUS:
+ raise error.TestFail('Expected status %s. Actual: %s' %
+ (self._EXPECTED_EOL_STATUS, result))
+
+
+ def _check_eol_notification(self):
+ """Checks that we are showing an EOL notification to the user."""
+ with chrome.Chrome(autotest_ext=True, logged_in=True) as cr:
+ def find_notification():
+ notifications = cr.get_visible_notifications()
+ if notifications is None:
+ return False
+ else:
+ logging.debug(notifications)
+ for n in notifications:
+ if n['title'] == self._EOL_NOTIFICATION_TITLE:
+ return True
+
+ utils.poll_for_condition(condition=lambda: find_notification(),
+ desc='Notification is found',
+ timeout=5,
+ sleep_interval=1)
+
+
+ def run_once(self):
+ utils.run('restart update-engine')
+
+ # Start a devserver to return a response with eol entry.
+ self._omaha = nano_omaha_devserver.NanoOmahaDevserver(eol=True)
+ self._omaha.start()
+
+ # Try to update using the omaha server. It will fail with noupdate.
+ utils.run('update_engine_client -update -omaha_url=' +
+ 'http://127.0.0.1:%d/update ' % self._omaha.get_port(),
+ ignore_status=True)
+
+ self._check_eol_status()
+ self._check_eol_notification()
diff --git a/client/site_tests/autoupdate_EOL/control b/client/site_tests/autoupdate_EOL/control
new file mode 100644
index 0000000..971c6f6
--- /dev/null
+++ b/client/site_tests/autoupdate_EOL/control
@@ -0,0 +1,19 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = "dhaddock, Chromium OS"
+NAME = "autoupdate_EOL"
+TEST_CATEGORY = "Functional"
+TEST_CLASS = "platform"
+TEST_TYPE = "client"
+ATTRIBUTES = "suite:bvt-perbuild"
+PURPOSE = "Tests End of Life (EOL) / Autoupdate Expiration (AUE)"
+TIME = "SHORT"
+
+DOC = """
+This test will check that the DUT behaves correctly in an end of life scenario.
+
+"""
+
+job.run_test('autoupdate_EOL')
diff --git a/client/site_tests/autoupdate_StartOOBEUpdate/autoupdate_StartOOBEUpdate.py b/client/site_tests/autoupdate_StartOOBEUpdate/autoupdate_StartOOBEUpdate.py
index de3099a..d3427bc 100644
--- a/client/site_tests/autoupdate_StartOOBEUpdate/autoupdate_StartOOBEUpdate.py
+++ b/client/site_tests/autoupdate_StartOOBEUpdate/autoupdate_StartOOBEUpdate.py
@@ -97,13 +97,17 @@
self._oobe = self._chrome.browser.oobe
self._skip_to_oobe_update_screen()
- utils.poll_for_condition(self._is_update_started,
- error.TestFail('Update did not start.'),
- timeout=30)
+ try:
+ utils.poll_for_condition(self._is_update_started,
+ error.TestFail('Update did not start.'),
+ timeout=30)
+ except error.TestFail as e:
+ if self._critical_update:
+ raise e
def run_once(self, image_url, cellular=False, payload_info=None,
- full_payload=True):
+ full_payload=True, critical_update=True):
"""
Test that will start a forced update at OOBE.
@@ -118,6 +122,7 @@
"""
utils.run('restart update-engine')
+ self._critical_update = critical_update
if cellular:
try:
diff --git a/client/site_tests/camera_HAL3/camera_HAL3.py b/client/site_tests/camera_HAL3/camera_HAL3.py
index efa8856..65c628c 100644
--- a/client/site_tests/camera_HAL3/camera_HAL3.py
+++ b/client/site_tests/camera_HAL3/camera_HAL3.py
@@ -21,6 +21,7 @@
adapter_service = 'camera-halv3-adapter'
timeout = 600
media_profiles_path = os.path.join('vendor', 'etc', 'media_profiles.xml')
+ tablet_board_list = ['scarlet']
def setup(self):
"""
@@ -51,5 +52,7 @@
video.get('height'), video.get('frameRate')))
if recording_params:
cmd.append('--recording_params=' + ','.join(recording_params))
+ if utils.get_current_board() in self.tablet_board_list:
+ cmd.append('--gtest_filter=-*SensorOrientationTest/*')
utils.system(' '.join(cmd), timeout=self.timeout)
diff --git a/client/site_tests/network_WlanDriver/control b/client/site_tests/network_WlanDriver/control
index 788f7db..73adfa3 100644
--- a/client/site_tests/network_WlanDriver/control
+++ b/client/site_tests/network_WlanDriver/control
@@ -11,9 +11,9 @@
TEST_TYPE = 'client'
DOC = """
-Ensure the detected wlan device has the correct associated kernel driver and
-that the driver is the expected revision. This test will fail if we find
-that mlan0/wlan0 has an odd driver release.
+Ensure we detected a wlan device and that it has the correct associated kernel
+driver and revision. This test will fail if we find that mlan0/wlan0 has an
+odd driver release, or if it is missing entirely.
"""
diff --git a/client/site_tests/network_WlanDriver/control.bvt b/client/site_tests/network_WlanDriver/control.bvt
new file mode 100644
index 0000000..69146f6
--- /dev/null
+++ b/client/site_tests/network_WlanDriver/control.bvt
@@ -0,0 +1,21 @@
+# Copyright (c) 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = 'pstew, quiche, wiley, briannorris'
+NAME = 'network_WlanDriver.bvt'
+ATTRIBUTES = 'suite:bvt-perbuild'
+TIME = 'SHORT'
+TEST_TYPE = 'client'
+
+DOC = """
+Ensure we detected a wlan device and that it has the correct associated kernel
+driver and revision. This test will fail if we find that mlan0/wlan0 has an
+odd driver release, or if it is missing entirely.
+
+This version may forgive certain devices that are known to be permanently
+flaky, for expediency.
+"""
+
+
+job.run_test('network_WlanDriver', forgive_flaky=True)
diff --git a/client/site_tests/network_WlanDriver/network_WlanDriver.py b/client/site_tests/network_WlanDriver/network_WlanDriver.py
index 6bbad81..7c91aee 100755
--- a/client/site_tests/network_WlanDriver/network_WlanDriver.py
+++ b/client/site_tests/network_WlanDriver/network_WlanDriver.py
@@ -85,9 +85,25 @@
'4.4': 'wireless/marvell/mwifiex/mwifiex_pcie.ko',
},
}
+ EXCEPTION_BOARDS = [
+ # Exhibits very similar symptoms to http://crbug.com/693724,
+ # b/65858242, b/36264732.
+ 'nyan_kitty',
+ ]
- def run_once(self):
+ def NoDeviceFailure(self, forgive_flaky, message):
+ """
+ No WiFi device found. Forgiveable in some suites, for some boards.
+ """
+ board = utils.get_board()
+ if forgive_flaky and board in self.EXCEPTION_BOARDS:
+ return error.TestWarn('Exception (%s): %s' % (board, message))
+ else:
+ return error.TestFail(message)
+
+
+ def run_once(self, forgive_flaky=False):
"""Test main loop"""
# full_revision looks like "3.4.0".
full_revision = utils.system_output('uname -r')
@@ -110,7 +126,8 @@
if wlan_ifs:
net_if = wlan_ifs[0]
else:
- raise error.TestFail('Found no recognized wireless device')
+ raise self.NoDeviceFailure(forgive_flaky,
+ 'Found no recognized wireless device')
# Some systems (e.g., moblab) might blacklist certain devices. We don't
# rely on shill for most of this test, but it can be a helpful clue if
diff --git a/client/site_tests/platform_ToolchainTests/src/Makefile b/client/site_tests/platform_ToolchainTests/src/Makefile
index 9baca82..e8f6871 100644
--- a/client/site_tests/platform_ToolchainTests/src/Makefile
+++ b/client/site_tests/platform_ToolchainTests/src/Makefile
@@ -2,17 +2,35 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-all: toolchain-tests
-clean:
- rm -f toolchain-tests
+fortify-test-src := clang-fortify-tests.cpp
+# -U_FORTIFY_SOURCE: Clang gets unhappy being passed `-D_FORTIFY_SOURCE=2
+# -D_FORTIFY_SOURCE=1` (the first of which comes from our wrapper).
+fortify-cxx := $(CXX) $(fortify-test-src) $(CPPFLAGS) $(CXXFLAGS) -std=c++11 \
+ -D_GNU_SOURCE -fno-exceptions -O2 -U_FORTIFY_SOURCE
+fortify-diag-flags := -o /dev/null -Xclang -verify -DCOMPILATION_TESTS -c
+fortify-runtime-flags := -Wno-user-defined-warnings -Wno-unused-result
-toolchain-tests:
- $(CC) toolchain-tests.c -o toolchain-tests
+all: fortify-runtime-tests
+
+fortify-runtime-tests: clang-fortify-driver.o clang-fortify-tests-1.o \
+ clang-fortify-tests-2.o
+ $(CXX) $(LDFLAGS) -o $@ $+
+
+clang-fortify-tests-1.o: $(fortify-test-src)
+ $(fortify-cxx) $(fortify-runtime-flags) -c -D_FORTIFY_SOURCE=1 -o $@
+
+clang-fortify-tests-2.o: $(fortify-test-src)
+ $(fortify-cxx) $(fortify-runtime-flags) -c -D_FORTIFY_SOURCE=2 -o $@
+
+clean:
+ rm -f clang-fortify-*.o fortify-runtime-tests
install:
install -m 0755 -d $(DESTDIR)/usr/local/bin
install -m 0755 toolchain-tests $(DESTDIR)/usr/local/bin
+ install -m 0755 fortify-runtime-tests $(DESTDIR)/usr/local/bin
+.PHONY: check
check:
- @echo "Checking compiler warnings ..."
- @echo "Checking compiler errors ..."
+ $(fortify-cxx) $(fortify-diag-flags) -D_FORTIFY_SOURCE=1
+ $(fortify-cxx) $(fortify-diag-flags) -D_FORTIFY_SOURCE=2
diff --git a/client/site_tests/platform_ToolchainTests/src/clang-fortify-common.h b/client/site_tests/platform_ToolchainTests/src/clang-fortify-common.h
new file mode 100644
index 0000000..7c32f8e
--- /dev/null
+++ b/client/site_tests/platform_ToolchainTests/src/clang-fortify-common.h
@@ -0,0 +1,16 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <vector>
+
+struct Failure {
+ int line;
+ const char *message;
+ bool expected_death;
+};
+
+// Tests FORTIFY with -D_FORTIFY_SOURCE=1
+std::vector<Failure> test_fortify_1();
+// Tests FORTIFY with -D_FORTIFY_SOURCE=2
+std::vector<Failure> test_fortify_2();
diff --git a/client/site_tests/platform_ToolchainTests/src/clang-fortify-driver.cpp b/client/site_tests/platform_ToolchainTests/src/clang-fortify-driver.cpp
new file mode 100644
index 0000000..522660c
--- /dev/null
+++ b/client/site_tests/platform_ToolchainTests/src/clang-fortify-driver.cpp
@@ -0,0 +1,72 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <err.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "clang-fortify-common.h"
+
+// It's potentially easy for us to get blocked if a FORTIFY'ed I/O call isn't
+// properly verified.
+static void SetTimeout(int secs) {
+ struct sigaction sigact;
+ bzero(&sigact, sizeof(sigact));
+
+ sigact.sa_flags = SA_RESETHAND;
+ sigact.sa_handler = [](int) {
+ const char complaint[] = "!!! Timeout reached; abort abort abort\n";
+ (void)write(STDOUT_FILENO, complaint, strlen(complaint));
+ _exit(1);
+ };
+
+ if (sigaction(SIGALRM, &sigact, nullptr))
+ err(1, "Failed to establish a SIGALRM handler");
+
+ alarm(secs);
+}
+
+static void PrintFailures(const std::vector<Failure> &failures) {
+ fprintf(stderr, "Failure(s): (%zu total)\n", failures.size());
+ for (const Failure &f : failures) {
+ const char *why = f.expected_death ? "didn't die" : "died";
+ fprintf(stderr, "\t`%s` at line %d %s\n", f.message, f.line, why);
+ }
+}
+
+int main() {
+ // On my dev machine, this test takes around 70ms to run to completion. On
+ // samus, it's more like 20 seconds.
+ SetTimeout(300);
+
+ // Some functions (e.g. gets()) try to read from stdin. Stop them from doing
+ // so, lest they block forever.
+ int dev_null = open("/dev/null", O_RDONLY);
+ if (dev_null < 0)
+ err(1, "Failed opening /dev/null");
+
+ if (dup2(dev_null, STDIN_FILENO) < 0)
+ err(1, "Failed making stdin == /dev/null");
+
+ bool failed = false;
+
+ fprintf(stderr, "::: Testing _FORTIFY_SOURCE=1 :::\n");
+ std::vector<Failure> failures = test_fortify_1();
+ if (!failures.empty()) {
+ PrintFailures(failures);
+ failed = true;
+ }
+
+ fprintf(stderr, "::: Testing _FORTIFY_SOURCE=2 :::\n");
+ failures = test_fortify_2();
+ if (!failures.empty()) {
+ PrintFailures(failures);
+ failed = true;
+ }
+
+ return failed ? 1 : 0;
+}
diff --git a/client/site_tests/platform_ToolchainTests/src/clang-fortify-tests.cpp b/client/site_tests/platform_ToolchainTests/src/clang-fortify-tests.cpp
new file mode 100644
index 0000000..fe30bcb
--- /dev/null
+++ b/client/site_tests/platform_ToolchainTests/src/clang-fortify-tests.cpp
@@ -0,0 +1,689 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#if !defined(__clang__)
+#error "Non-clang isn't supported"
+#endif
+
+// Clang compile-time and run-time tests for glibc FORTIFY.
+//
+// This file is compiled in two configurations ways to give us a sane set of
+// tests for clang's FORTIFY implementation.
+//
+// One configuration uses clang's diagnostic consumer
+// (https://clang.llvm.org/doxygen/classclang_1_1VerifyDiagnosticConsumer.html#details)
+// to check diagnostics (e.g. the expected-* comments everywhere).
+//
+// The other configuration builds this file such that the resultant object file
+// exports a function named test_fortify_1 or test_fortify_2, depending on the
+// FORTIFY level we're using. These are called by clang_fortify_driver.cpp.
+//
+// Please note that this test does things like leaking memory. That's WAI.
+
+// Silence all "from 'diagnose_if'" `note`s from anywhere, including headers;
+// they're uninteresting for this test case, and their line numbers may change
+// over time.
+// expected-note@* 0+{{from 'diagnose_if'}}
+//
+// Similarly, there are a few overload tricks we have to emit errors. Ignore any
+// notes from those.
+// expected-note@* 0+{{candidate function}}
+
+// Must come before stdlib.h
+#include <limits.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <mqueue.h>
+#include <poll.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <wchar.h>
+#include <vector>
+
+#include "clang-fortify-common.h"
+
+// We're going to use deprecated APIs here (e.g. getwd). That's OK.
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+#ifndef _FORTIFY_SOURCE
+#error "_FORTIFY_SOURCE must be defined"
+#endif
+
+/////////////////// Test infrastructure; nothing to see here ///////////////////
+
+// GTest doesn't seem to have an EXPECT_NO_DEATH equivalent, and this all seems
+// easy enough to hand-roll in a simple environment.
+
+// Failures get stored here.
+static std::vector<Failure> *failures;
+
+template <typename Fn>
+static void ForkAndExpect(int line, const char *message, Fn &&F,
+ bool expect_death) {
+ fprintf(stderr, "Running %s... (expected to %s)\n", message,
+ expect_death ? "die" : "not die");
+
+ int pid = fork();
+ if (pid == -1)
+ err(1, "Failed to fork() a subproc");
+
+ if (pid == 0) {
+ F();
+ exit(0);
+ }
+
+ int status;
+ if (waitpid(pid, &status, 0) == -1)
+ err(1, "Failed to wait on child (pid %d)", pid);
+
+ bool died = WIFSIGNALED(status) || WEXITSTATUS(status) != 0;
+ if (died != expect_death) {
+ fprintf(stderr, "Check `%s` (at line %d) %s\n", message, line,
+ expect_death ? "failed to die" : "died");
+ failures->push_back({line, message, expect_death});
+ }
+}
+
+#define FORK_AND_EXPECT(x, die) ForkAndExpect(__LINE__, #x, [&] { (x); }, die)
+
+// EXPECT_NO_DEATH forks so that the test remains alive on a bug, and so that
+// the environment doesn't get modified on no bug. (Environment modification is
+// especially tricky to deal with given the *_STRUCT variants below.)
+#define EXPECT_NO_DEATH(x) FORK_AND_EXPECT(x, false)
+#define EXPECT_DEATH(x) FORK_AND_EXPECT(x, true)
+
+// Expecting death, but only if we're doing a "strict" struct-checking mode.
+#if _FORTIFY_SOURCE > 1
+#define EXPECT_DEATH_STRUCT(x) EXPECT_DEATH(x)
+#else
+#define EXPECT_DEATH_STRUCT(x) EXPECT_NO_DEATH(x)
+#endif
+
+//////////////////////////////// FORTIFY tests! ////////////////////////////////
+
+// FIXME(gbiv): glibc shouldn't #define this with FORTIFY on.
+#undef mempcpy
+
+const static int kBogusFD = -1;
+
+static void TestString() {
+ char small_buffer[8] = {};
+
+ {
+ char large_buffer[sizeof(small_buffer) + 1] = {};
+ // expected-warning@+1{{called with bigger length than the destination}}
+ EXPECT_DEATH(memcpy(small_buffer, large_buffer, sizeof(large_buffer)));
+ // expected-warning@+1{{called with bigger length than the destination}}
+ EXPECT_DEATH(memmove(small_buffer, large_buffer, sizeof(large_buffer)));
+ // expected-warning@+1{{called with bigger length than the destination}}
+ EXPECT_DEATH(mempcpy(small_buffer, large_buffer, sizeof(large_buffer)));
+ // expected-warning@+1{{called with bigger length than the destination}}
+ EXPECT_DEATH(memset(small_buffer, 0, sizeof(large_buffer)));
+ // expected-warning@+1{{transposed parameters}}
+ memset(small_buffer, sizeof(small_buffer), 0);
+ // expected-warning@+1{{called with bigger length than the destination}}
+ EXPECT_DEATH(bcopy(large_buffer, small_buffer, sizeof(large_buffer)));
+ // expected-warning@+1{{called with bigger length than the destination}}
+ EXPECT_DEATH(bzero(small_buffer, sizeof(large_buffer)));
+ }
+
+ {
+ const char large_string[] = "Hello!!!";
+ _Static_assert(sizeof(large_string) > sizeof(small_buffer), "");
+
+ // expected-warning@+1{{destination buffer will always be overflown}}
+ EXPECT_DEATH(strcpy(small_buffer, large_string));
+ // expected-warning@+1{{destination buffer will always be overflown}}
+ EXPECT_DEATH(stpcpy(small_buffer, large_string));
+ // expected-warning@+1{{called with bigger length than the destination}}
+ EXPECT_DEATH(strncpy(small_buffer, large_string, sizeof(large_string)));
+ // FIXME(gbiv): Clang (and GCC, for that matter) should diagnose this.
+ EXPECT_DEATH(stpncpy(small_buffer, large_string, sizeof(large_string)));
+ // expected-warning@+1{{destination buffer will always be overflown}}
+ EXPECT_DEATH(strcat(small_buffer, large_string));
+ // expected-warning@+1{{called with bigger length than the destination}}
+ EXPECT_DEATH(strncat(small_buffer, large_string, sizeof(large_string)));
+ }
+
+ {
+ struct {
+ char tiny_buffer[4];
+ char tiny_buffer2[4];
+ } split = {};
+
+ EXPECT_NO_DEATH(memcpy(split.tiny_buffer, &split, sizeof(split)));
+ EXPECT_NO_DEATH(memcpy(split.tiny_buffer, &split, sizeof(split)));
+ EXPECT_NO_DEATH(memmove(split.tiny_buffer, &split, sizeof(split)));
+ EXPECT_NO_DEATH(mempcpy(split.tiny_buffer, &split, sizeof(split)));
+ EXPECT_NO_DEATH(memset(split.tiny_buffer, 0, sizeof(split)));
+
+ EXPECT_NO_DEATH(bcopy(&split, split.tiny_buffer, sizeof(split)));
+ EXPECT_NO_DEATH(bzero(split.tiny_buffer, sizeof(split)));
+
+ const char small_string[] = "Hi!!";
+ _Static_assert(sizeof(small_string) > sizeof(split.tiny_buffer), "");
+
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{destination buffer will always be overflown}}
+#endif
+ EXPECT_DEATH_STRUCT(strcpy(split.tiny_buffer, small_string));
+
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{destination buffer will always be overflown}}
+#endif
+ EXPECT_DEATH_STRUCT(stpcpy(split.tiny_buffer, small_string));
+
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{called with bigger length than the destination}}
+#endif
+ EXPECT_DEATH_STRUCT(
+ strncpy(split.tiny_buffer, small_string, sizeof(small_string)));
+
+ // FIXME(gbiv): Clang (and GCC, for that matter) should diagnose this.
+ EXPECT_DEATH_STRUCT(
+ stpncpy(split.tiny_buffer, small_string, sizeof(small_string)));
+
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{destination buffer will always be overflown}}
+#endif
+ EXPECT_DEATH_STRUCT(strcat(split.tiny_buffer, small_string));
+
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{called with bigger length than the destination}}
+#endif
+ EXPECT_DEATH_STRUCT(
+ strncat(split.tiny_buffer, small_string, sizeof(small_string)));
+ }
+}
+
+// Since these emit hard errors, it's sort of hard to run them...
+#ifdef COMPILATION_TESTS
+namespace compilation_tests {
+static void testFcntl() {
+ // FIXME(gbiv): Need to fix these; they got dropped.
+#if 0
+ // expected-error@+1{{either with 2 or 3 arguments, not more}}
+#endif
+ open("/", 0, 0, 0);
+#if 0
+ // expected-error@+1{{either with 2 or 3 arguments, not more}}
+#endif
+ open64("/", 0, 0, 0);
+ // expected-error@+1{{either with 3 or 4 arguments, not more}}
+ openat(0, "/", 0, 0, 0);
+ // expected-error@+1{{either with 3 or 4 arguments, not more}}
+ openat64(0, "/", 0, 0, 0);
+
+ // expected-error@+1{{needs 3 arguments}}
+ open("/", O_CREAT);
+ // expected-error@+1{{needs 3 arguments}}
+ open("/", O_TMPFILE);
+ // expected-error@+1{{needs 3 arguments}}
+ open64("/", O_CREAT);
+ // expected-error@+1{{needs 3 arguments}}
+ open64("/", O_TMPFILE);
+ // expected-error@+1{{needs 4 arguments}}
+ openat(0, "/", O_CREAT);
+ // expected-error@+1{{needs 4 arguments}}
+ openat(0, "/", O_TMPFILE);
+ // expected-error@+1{{needs 4 arguments}}
+ openat64(0, "/", O_CREAT);
+ // expected-error@+1{{needs 4 arguments}}
+ openat64(0, "/", O_TMPFILE);
+
+ // Superfluous modes are sometimes bugs, but not often enough to complain
+ // about, apparently.
+}
+
+static void testMqueue() {
+ // FIXME(gbiv): remove mq_open's FORTIFY'ed body from glibc...
+
+ // expected-error@+1{{with 2 or 4 arguments}}
+ mq_open("/", 0, 0);
+ // expected-error@+1{{with 2 or 4 arguments}}
+ mq_open("/", 0, 0, 0, 0);
+
+ // expected-error@+1{{needs 4 arguments}}
+ mq_open("/", O_CREAT);
+}
+} // namespace compilation_tests
+#endif
+
+static void TestPoll() {
+ struct pollfd invalid_poll_fd = {kBogusFD, 0, 0};
+ {
+ struct pollfd few_fds[] = {invalid_poll_fd, invalid_poll_fd};
+ // expected-warning@+1{{fds buffer too small}}
+ EXPECT_DEATH(poll(few_fds, 3, 0));
+ // expected-warning@+1{{fds buffer too small}}
+ EXPECT_DEATH(ppoll(few_fds, 3, 0, 0));
+ }
+
+ {
+ struct {
+ struct pollfd few[2];
+ struct pollfd extra[1];
+ } fds = {{invalid_poll_fd, invalid_poll_fd}, {invalid_poll_fd}};
+ _Static_assert(sizeof(fds) >= sizeof(struct pollfd) * 3, "");
+
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{fds buffer too small}}
+#endif
+ EXPECT_DEATH_STRUCT(poll(fds.few, 3, 0));
+
+ struct timespec timeout = {};
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{fds buffer too small}}
+#endif
+ EXPECT_DEATH_STRUCT(ppoll(fds.few, 3, &timeout, 0));
+ }
+}
+
+static void TestSocket() {
+ {
+ char small_buffer[8];
+ // expected-warning@+1{{bigger length than size of destination buffer}}
+ EXPECT_DEATH(recv(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
+ // expected-warning@+1{{bigger length than size of destination buffer}}
+ EXPECT_DEATH(
+ recvfrom(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0, 0, 0));
+ }
+
+ {
+ struct {
+ char tiny_buffer[4];
+ char tiny_buffer2;
+ } split = {};
+
+ EXPECT_NO_DEATH(recv(kBogusFD, split.tiny_buffer, sizeof(split), 0));
+ EXPECT_NO_DEATH(
+ recvfrom(kBogusFD, split.tiny_buffer, sizeof(split), 0, 0, 0));
+ }
+}
+
+static void TestStdio() {
+ char small_buffer[8] = {};
+ {
+ // expected-warning@+1{{may overflow the destination buffer}}
+ EXPECT_DEATH(snprintf(small_buffer, sizeof(small_buffer) + 1, ""));
+
+ va_list va;
+ // expected-warning@+1{{may overflow the destination buffer}}
+ EXPECT_DEATH(vsnprintf(small_buffer, sizeof(small_buffer) + 1, "", va));
+ }
+
+ // gets is safe here, since stdin is actually /dev/null
+ // expected-warning@+1{{ignoring return value}}
+ EXPECT_NO_DEATH(gets(small_buffer));
+
+ char *volatile unknown_size_buffer = small_buffer;
+ // FIXME(gbiv): This should issue a "don't use me" warning, besides just
+ // deprecation (which is suppressed)...
+ // Since stdin is /dev/null, gets on a tiny buffer is safe here.
+ // expected-warning@+1{{ignoring return value}}
+ EXPECT_NO_DEATH(gets(unknown_size_buffer));
+}
+
+static void TestUnistd() {
+ char small_buffer[8];
+
+ // Return value warnings are (sort of) a part of FORTIFY, so we don't ignore
+ // them.
+ // expected-warning@+2{{ignoring return value of function}}
+ // expected-warning@+1{{bigger length than size of the destination buffer}}
+ EXPECT_DEATH(read(kBogusFD, small_buffer, sizeof(small_buffer) + 1));
+ // expected-warning@+2{{ignoring return value of function}}
+ // expected-warning@+1{{bigger length than size of the destination buffer}}
+ EXPECT_DEATH(pread(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
+ // expected-warning@+2{{ignoring return value of function}}
+ // expected-warning@+1{{bigger length than size of the destination buffer}}
+ EXPECT_DEATH(pread64(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0));
+ // expected-warning@+2{{ignoring return value of function}}
+ // expected-warning@+1{{bigger length than size of destination buffer}}
+ EXPECT_DEATH(readlink("/", small_buffer, sizeof(small_buffer) + 1));
+ // expected-warning@+2{{ignoring return value of function}}
+ // expected-warning@+1{{bigger length than size of destination buffer}}
+ EXPECT_DEATH(getcwd(small_buffer, sizeof(small_buffer) + 1));
+
+ // glibc allocates and returns a buffer if you pass null to getcwd
+ // expected-warning@+1{{ignoring return value of function}}
+ EXPECT_NO_DEATH(getcwd(NULL, 0));
+ // expected-warning@+1{{ignoring return value of function}}
+ EXPECT_NO_DEATH(getcwd(NULL, 4096));
+
+ {
+ char large_buffer[PATH_MAX * 2];
+ // expected-warning@+1{{ignoring return value of function}}
+ EXPECT_NO_DEATH(getwd(large_buffer));
+
+ char *volatile unknown_size_buffer = large_buffer;
+ // expected-warning@+2{{ignoring return value of function}}
+ // FIXME(gbiv): We should emit a "use getcwd" complaint here.
+ EXPECT_NO_DEATH(getwd(unknown_size_buffer));
+ }
+
+ // expected-warning@+1{{bigger length than size of destination buffer}}
+ EXPECT_DEATH(confstr(0, small_buffer, sizeof(small_buffer) + 1));
+
+ {
+ gid_t gids[2];
+ // expected-warning@+1{{bigger group count than what can fit}}
+ EXPECT_DEATH(getgroups(3, gids));
+ }
+
+ // expected-warning@+1{{bigger buflen than size of destination buffer}}
+ EXPECT_DEATH(ttyname_r(kBogusFD, small_buffer, sizeof(small_buffer) + 1));
+ // expected-warning@+1{{bigger buflen than size of destination buffer}}
+ EXPECT_DEATH(getlogin_r(small_buffer, sizeof(small_buffer) + 1));
+ // expected-warning@+1{{bigger buflen than size of destination buffer}}
+ EXPECT_DEATH(gethostname(small_buffer, sizeof(small_buffer) + 1));
+ // expected-warning@+1{{bigger buflen than size of destination buffer}}
+ EXPECT_DEATH(getdomainname(small_buffer, sizeof(small_buffer) + 1));
+
+ // We've already checked the warn-unused-result warnings; no need to clutter
+ // the code with rechecks...
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-value"
+ struct {
+ char tiny_buffer[4];
+ char tiny_buffer2[4];
+ } split;
+
+ EXPECT_NO_DEATH(read(kBogusFD, split.tiny_buffer, sizeof(split)));
+ EXPECT_NO_DEATH(pread(kBogusFD, split.tiny_buffer, sizeof(split), 0));
+ EXPECT_NO_DEATH(pread64(kBogusFD, split.tiny_buffer, sizeof(split), 0));
+
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{bigger length than size of destination buffer}}
+#endif
+ EXPECT_DEATH_STRUCT(readlink("/", split.tiny_buffer, sizeof(split)));
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{bigger length than size of destination buffer}}
+#endif
+ EXPECT_DEATH_STRUCT(getcwd(split.tiny_buffer, sizeof(split)));
+
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{bigger length than size of destination buffer}}
+#endif
+ EXPECT_DEATH_STRUCT(confstr(kBogusFD, split.tiny_buffer, sizeof(split)));
+
+ {
+ struct {
+ gid_t tiny_buffer[2];
+ gid_t tiny_buffer2[1];
+ } split_gids;
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{bigger group count than what can fit}}
+#endif
+ EXPECT_DEATH_STRUCT(getgroups(3, split_gids.tiny_buffer));
+ }
+
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{bigger buflen than size of destination buffer}}
+#endif
+ EXPECT_DEATH_STRUCT(ttyname_r(kBogusFD, split.tiny_buffer, sizeof(split)));
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{bigger buflen than size of destination buffer}}
+#endif
+ EXPECT_DEATH_STRUCT(getlogin_r(split.tiny_buffer, sizeof(split)));
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{bigger buflen than size of destination buffer}}
+#endif
+ EXPECT_DEATH_STRUCT(gethostname(split.tiny_buffer, sizeof(split)));
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{bigger buflen than size of destination buffer}}
+#endif
+ EXPECT_DEATH_STRUCT(getdomainname(split.tiny_buffer, sizeof(split)));
+
+#pragma clang diagnostic pop // -Wunused-value
+}
+
+static void TestWchar() {
+ // Sizes here are all expressed in terms of sizeof(wchar_t).
+ const int small_buffer_size = 8;
+ wchar_t small_buffer[small_buffer_size] = {};
+ {
+ const int large_buffer_size = small_buffer_size + 1;
+ wchar_t large_buffer[large_buffer_size];
+
+ // expected-warning@+1{{length bigger than size of destination buffer}}
+ EXPECT_DEATH(wmemcpy(small_buffer, large_buffer, large_buffer_size));
+ // expected-warning@+1{{length bigger than size of destination buffer}}
+ EXPECT_DEATH(wmemmove(small_buffer, large_buffer, large_buffer_size));
+ // expected-warning@+1{{length bigger than size of destination buffer}}
+ EXPECT_DEATH(wmempcpy(small_buffer, large_buffer, large_buffer_size));
+ }
+
+ {
+ const wchar_t large_string[] = L"Hello!!!";
+ const int large_string_size = small_buffer_size + 1;
+ _Static_assert(sizeof(large_string) == large_string_size * sizeof(wchar_t),
+ "");
+
+ // expected-warning@+1{{length bigger than size of destination buffer}}
+ EXPECT_DEATH(wmemset(small_buffer, 0, small_buffer_size + 1));
+ // expected-warning@+1{{length bigger than size of destination buffer}}
+ EXPECT_DEATH(wcsncpy(small_buffer, large_string, small_buffer_size + 1));
+ // expected-warning@+1{{length bigger than size of destination buffer}}
+ EXPECT_DEATH(wcpncpy(small_buffer, large_string, small_buffer_size + 1));
+
+ // expected-warning@+2{{ignoring return value of function}}
+ // expected-warning@+1{{length bigger than size of destination buffer}}
+ EXPECT_DEATH(fgetws(small_buffer, sizeof(small_buffer) + 1, 0));
+ // expected-warning@+2{{ignoring return value of function}}
+ // expected-warning@+1{{bigger size than length of destination buffer}}
+ EXPECT_DEATH(fgetws_unlocked(small_buffer, sizeof(small_buffer) + 1, 0));
+
+ // No diagnostics emitted for either clang or gcc :(
+ EXPECT_DEATH(wcscpy(small_buffer, large_string));
+ EXPECT_DEATH(wcpcpy(small_buffer, large_string));
+ EXPECT_DEATH(wcscat(small_buffer, large_string));
+ EXPECT_DEATH(wcsncat(small_buffer, large_string, large_string_size));
+ }
+
+ mbstate_t mbs;
+ bzero(&mbs, sizeof(mbs));
+ {
+ const char *src[small_buffer_size * sizeof(wchar_t)];
+ // expected-warning@+1{{called with dst buffer smaller than}}
+ EXPECT_DEATH(mbsrtowcs(small_buffer, src, sizeof(small_buffer) + 1, &mbs));
+ }
+
+ {
+ const int array_len = 8;
+ char chars[array_len];
+ const char *chars_ptr = chars;
+ wchar_t wchars[array_len];
+ const wchar_t *wchars_ptr = wchars;
+ // expected-warning@+1{{called with dst buffer smaller than}}
+ EXPECT_DEATH(wcsrtombs(chars, &wchars_ptr, array_len + 1, &mbs));
+ // expected-warning@+1{{called with dst buffer smaller than}}
+ EXPECT_DEATH(mbsnrtowcs(wchars, &chars_ptr, 0, array_len + 1, &mbs));
+ // expected-warning@+1{{called with dst buffer smaller than}}
+ EXPECT_DEATH(wcsnrtombs(chars, &wchars_ptr, 0, array_len + 1, &mbs));
+ }
+
+
+ struct {
+ wchar_t buf[small_buffer_size - 1];
+ wchar_t extra;
+ } small_split;
+ _Static_assert(sizeof(small_split) == sizeof(small_buffer), "");
+ bzero(&small_split, sizeof(small_split));
+
+ EXPECT_NO_DEATH(wmemcpy(small_split.buf, small_buffer, small_buffer_size));
+ EXPECT_NO_DEATH(wmemmove(small_split.buf, small_buffer, small_buffer_size));
+ EXPECT_NO_DEATH(wmempcpy(small_split.buf, small_buffer, small_buffer_size));
+
+ {
+ const wchar_t small_string[] = L"Hello!!";
+ _Static_assert(sizeof(small_buffer) == sizeof(small_string), "");
+
+ EXPECT_NO_DEATH(wmemset(small_split.buf, 0, small_buffer_size));
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{length bigger than size of destination buffer}}
+#endif
+ EXPECT_DEATH_STRUCT(
+ wcsncpy(small_split.buf, small_string, small_buffer_size));
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{length bigger than size of destination buffer}}
+#endif
+ EXPECT_DEATH_STRUCT(
+ wcpncpy(small_split.buf, small_string, small_buffer_size));
+
+ // FIXME(gbiv): FORTIFY doesn't warn about this eagerly enough on
+ // _FORTIFY_SOURCE=1.
+ // expected-warning@+4{{ignoring return value of function}}
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{length bigger than size of destination buffer}}
+#endif
+ EXPECT_DEATH(fgetws(small_split.buf, small_buffer_size, 0));
+
+ // FIXME(gbiv): FORTIFY doesn't warn about this eagerly enough on
+ // _FORTIFY_SOURCE=1.
+ // expected-warning@+4{{ignoring return value of function}}
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{bigger size than length of destination buffer}}
+#endif
+ EXPECT_DEATH(fgetws_unlocked(small_split.buf, small_buffer_size, 0));
+
+ // No diagnostics emitted for either clang or gcc :(
+ EXPECT_DEATH_STRUCT(wcscpy(small_split.buf, small_string));
+ EXPECT_DEATH_STRUCT(wcpcpy(small_split.buf, small_string));
+ EXPECT_DEATH_STRUCT(wcscat(small_split.buf, small_string));
+ EXPECT_DEATH_STRUCT(
+ wcsncat(small_split.buf, small_string, small_buffer_size));
+ }
+
+ {
+ // NOREVIEW: STRUCT
+ const char *src[sizeof(small_buffer)] = {};
+ // FIXME(gbiv): _FORTIFY_SOURCE=1 should diagnose this more aggressively
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{called with dst buffer smaller than}}
+#endif
+ EXPECT_DEATH(mbsrtowcs(small_split.buf, src, small_buffer_size, &mbs));
+ }
+
+ {
+ // NOREVIEW: STRUCT
+ const int array_len = 8;
+ struct {
+ char buf[array_len - 1];
+ char extra;
+ } split_chars;
+ const char *chars_ptr = split_chars.buf;
+ struct {
+ wchar_t buf[array_len - 1];
+ wchar_t extra;
+ } split_wchars;
+ const wchar_t *wchars_ptr = split_wchars.buf;
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{called with dst buffer smaller than}}
+#endif
+ EXPECT_DEATH_STRUCT(
+ wcsrtombs(split_chars.buf, &wchars_ptr, array_len, &mbs));
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{called with dst buffer smaller than}}
+#endif
+ EXPECT_DEATH_STRUCT(
+ mbsnrtowcs(split_wchars.buf, &chars_ptr, 0, array_len, &mbs));
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{called with dst buffer smaller than}}
+#endif
+ EXPECT_DEATH_STRUCT(
+ wcsnrtombs(split_chars.buf, &wchars_ptr, 0, array_len, &mbs));
+ }
+}
+
+static void TestStdlib() {
+ {
+ char path_buffer[PATH_MAX - 1];
+ // expected-warning@+2{{ignoring return value of function}}
+ // expected-warning@+1{{must be either NULL or at least PATH_MAX bytes}}
+ EXPECT_DEATH(realpath("/", path_buffer));
+ // expected-warning@+1{{ignoring return value of function}}
+ realpath("/", NULL);
+ }
+
+ char small_buffer[8];
+ // expected-warning@+1{{called with buflen bigger than size of buf}}
+ EXPECT_DEATH(ptsname_r(kBogusFD, small_buffer, sizeof(small_buffer) + 1));
+
+ {
+ const int wchar_buffer_size = 8;
+ wchar_t wchar_buffer[wchar_buffer_size];
+ // expected-warning@+1{{called with dst buffer smaller than}}
+ EXPECT_DEATH(mbstowcs(wchar_buffer, small_buffer, wchar_buffer_size + 1));
+ // expected-warning@+1{{called with dst buffer smaller than}}
+ EXPECT_DEATH(
+ wcstombs(small_buffer, wchar_buffer, sizeof(small_buffer) + 1));
+ }
+
+ {
+ struct {
+ char path_buffer[PATH_MAX - 1];
+ char rest[1];
+ } split;
+ // expected-warning@+4{{ignoring return value of function}}
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{must be either NULL or at least PATH_MAX bytes}}
+#endif
+ EXPECT_DEATH_STRUCT(realpath("/", split.path_buffer));
+ }
+
+ struct {
+ char tiny_buffer[4];
+ char rest[1];
+ } split;
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{called with buflen bigger than size of buf}}
+#endif
+ EXPECT_DEATH_STRUCT(ptsname_r(kBogusFD, split.tiny_buffer, sizeof(split)));
+
+ {
+ const int tiny_buffer_size = 4;
+ struct {
+ wchar_t tiny_buffer[tiny_buffer_size];
+ wchar_t rest;
+ } wsplit;
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{called with dst buffer smaller than}}
+#endif
+ EXPECT_DEATH_STRUCT(
+ mbstowcs(wsplit.tiny_buffer, small_buffer, tiny_buffer_size + 1));
+#if _FORTIFY_SOURCE > 1
+ // expected-warning@+2{{called with dst buffer smaller than}}
+#endif
+ EXPECT_DEATH_STRUCT(
+ wcstombs(split.tiny_buffer, wsplit.tiny_buffer, sizeof(split)));
+ }
+}
+
+/////////////////// Test infrastructure; nothing to see here ///////////////////
+
+#define CONCAT2(x, y) x ## y
+#define CONCAT(x, y) CONCAT2(x, y)
+
+// Exported to the driver so we can run these tests.
+std::vector<Failure> CONCAT(test_fortify_, _FORTIFY_SOURCE)() {
+ std::vector<Failure> result;
+ failures = &result;
+
+ TestPoll();
+ TestSocket();
+ TestStdio();
+ TestStdlib();
+ TestString();
+ TestUnistd();
+ TestWchar();
+
+ failures = nullptr;
+ return result;
+}
diff --git a/client/site_tests/platform_ToolchainTests/src/toolchain-tests b/client/site_tests/platform_ToolchainTests/src/toolchain-tests
new file mode 100755
index 0000000..c305521
--- /dev/null
+++ b/client/site_tests/platform_ToolchainTests/src/toolchain-tests
@@ -0,0 +1,32 @@
+#!/bin/bash -e
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+base=$(dirname "$(readlink -m "$0")")
+log=$(mktemp)
+
+echo "FORTIFY..."
+# We run these tests under `script` because each FORTIFY failure, which these
+# cause *a lot* of, will complain directly to /dev/tty. For hosts, these
+# messages can easily drown out any other script output.
+if ! script -q -e -c "${base}/fortify-runtime-tests" "${log}" >/dev/null; then
+ echo "${test} failed; see logs in ${log}."
+ if grep -q '!!! Timeout reached' "${log}"; then
+ echo "Looks like the test program timed out."
+ else
+ # Try to find and pretty-print the failure message(s).
+ # The /Failures/ part of the script can't be a simple address range: if
+ # we're printing _FORTIFY_SOURCE=1 errors, we might pick up the ":::
+ # _FORTIFY_SOURCE=2 :::" header twice.
+ sed -ne '/^:::/p' \
+ -e '/^Failure(s): /{ p; :again; n; p; /^\s/b again; }' \
+ "${log}"
+ fi
+
+ echo "FAIL"
+ exit 1
+fi
+
+rm -f "${log}"
+echo "PASS"
diff --git a/client/site_tests/platform_ToolchainTests/src/toolchain-tests.c b/client/site_tests/platform_ToolchainTests/src/toolchain-tests.c
deleted file mode 100644
index d67e474..0000000
--- a/client/site_tests/platform_ToolchainTests/src/toolchain-tests.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2017 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-int main()
-{
- return 0;
-}
diff --git a/client/site_tests/policy_ImagesBlockedForUrls/control.2urls_allow b/client/site_tests/policy_ImagesBlockedForUrls/control.2urls_allow
index 77eeb17..0f0fe4d 100644
--- a/client/site_tests/policy_ImagesBlockedForUrls/control.2urls_allow
+++ b/client/site_tests/policy_ImagesBlockedForUrls/control.2urls_allow
@@ -4,7 +4,7 @@
AUTHOR = 'scunningham'
NAME = 'policy_ImagesBlockedForUrls.2urls_allow'
-ATTRIBUTES = 'suite:bvt-perbuild, suite:policy'
+ATTRIBUTES = 'suite:bvt-perbuild, suite:ent-perbuild, suite:policy'
TIME = 'SHORT'
TEST_CATEGORY = 'General'
TEST_CLASS = 'enterprise'
diff --git a/client/site_tests/policy_ImagesBlockedForUrls/control.3urls_block b/client/site_tests/policy_ImagesBlockedForUrls/control.3urls_block
index ffde6a6..f0f4fbc 100644
--- a/client/site_tests/policy_ImagesBlockedForUrls/control.3urls_block
+++ b/client/site_tests/policy_ImagesBlockedForUrls/control.3urls_block
@@ -4,7 +4,7 @@
AUTHOR = 'scunningham'
NAME = 'policy_ImagesBlockedForUrls.3urls_block'
-ATTRIBUTES = 'suite:bvt-perbuild, suite:policy'
+ATTRIBUTES = 'suite:bvt-perbuild, suite:ent-nightly, suite:policy'
TIME = 'SHORT'
TEST_CATEGORY = 'General'
TEST_CLASS = 'enterprise'
diff --git a/client/site_tests/policy_KeyboardDefaultToFunctionKeys/control b/client/site_tests/policy_KeyboardDefaultToFunctionKeys/control
new file mode 100644
index 0000000..dda28f0
--- /dev/null
+++ b/client/site_tests/policy_KeyboardDefaultToFunctionKeys/control
@@ -0,0 +1,24 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = 'timkovich'
+NAME = 'policy_KeyboardDefaultFunctionKeys'
+TIME = 'SHORT'
+TEST_CATEGORY = 'General'
+TEST_CLASS = 'enterprise'
+TEST_TYPE = 'client'
+
+DOC = '''
+Verify effect of 'KeyboardDefaultFunctionKeys' policy on Chrome OS behavior.
+
+This test verifies the effect of the KeyboardDefaultFunctionKeys user policy on
+Chrome OS client behavior. It exercises all valid policy values across 3
+test cases: 'true', 'false', and 'notset'. The behavior of 'false' and 'notset'
+should be equivalent.
+
+'''
+
+args_dict = utils.args_to_dict(args)
+
+job.run_test('policy_KeyboardDefaultFunctionKeys', **args_dict)
diff --git a/client/site_tests/policy_KeyboardDefaultToFunctionKeys/control.false b/client/site_tests/policy_KeyboardDefaultToFunctionKeys/control.false
new file mode 100644
index 0000000..693e0dc
--- /dev/null
+++ b/client/site_tests/policy_KeyboardDefaultToFunctionKeys/control.false
@@ -0,0 +1,18 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = 'timkovich'
+NAME = 'policy_KeyboardDefaultToFunctionKeys.false'
+ATTRIBUTES = 'suite:bvt-perbuild, suite:policy'
+TIME = 'SHORT'
+TEST_CATEGORY = 'General'
+TEST_CLASS = 'enterprise'
+TEST_TYPE = 'client'
+
+DOC = '''
+Verify effect of 'KeyboardDefaultFunctionKeys' policy on Chrome OS behavior.
+
+'''
+
+job.run_test('policy_KeyboardDefaultToFunctionKeys', case='False')
diff --git a/client/site_tests/policy_KeyboardDefaultToFunctionKeys/control.notset b/client/site_tests/policy_KeyboardDefaultToFunctionKeys/control.notset
new file mode 100644
index 0000000..fba12a2
--- /dev/null
+++ b/client/site_tests/policy_KeyboardDefaultToFunctionKeys/control.notset
@@ -0,0 +1,18 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = 'timkovich'
+NAME = 'policy_KeyboardDefaultToFunctionKeys.notset'
+ATTRIBUTES = 'suite:bvt-perbuild, suite:policy'
+TIME = 'SHORT'
+TEST_CATEGORY = 'General'
+TEST_CLASS = 'enterprise'
+TEST_TYPE = 'client'
+
+DOC = '''
+Verify effect of 'KeyboardDefaultFunctionKeys' policy on Chrome OS behavior.
+
+'''
+
+job.run_test('policy_KeyboardDefaultToFunctionKeys', case='NotSet')
diff --git a/client/site_tests/policy_KeyboardDefaultToFunctionKeys/control.true b/client/site_tests/policy_KeyboardDefaultToFunctionKeys/control.true
new file mode 100644
index 0000000..c89ac78
--- /dev/null
+++ b/client/site_tests/policy_KeyboardDefaultToFunctionKeys/control.true
@@ -0,0 +1,18 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = 'timkovich'
+NAME = 'policy_KeyboardDefaultToFunctionKeys.true'
+ATTRIBUTES = 'suite:bvt-perbuild, suite:policy'
+TIME = 'SHORT'
+TEST_CATEGORY = 'General'
+TEST_CLASS = 'enterprise'
+TEST_TYPE = 'client'
+
+DOC = '''
+Verify effect of 'KeyboardDefaultFunctionKeys' policy on Chrome OS behavior.
+
+'''
+
+job.run_test('policy_KeyboardDefaultToFunctionKeys', case='True')
diff --git a/client/site_tests/policy_KeyboardDefaultToFunctionKeys/policy_KeyboardDefaultToFunctionKeys.py b/client/site_tests/policy_KeyboardDefaultToFunctionKeys/policy_KeyboardDefaultToFunctionKeys.py
new file mode 100644
index 0000000..561f1f4
--- /dev/null
+++ b/client/site_tests/policy_KeyboardDefaultToFunctionKeys/policy_KeyboardDefaultToFunctionKeys.py
@@ -0,0 +1,93 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import logging
+import re
+
+from autotest_lib.client.common_lib import error
+from autotest_lib.client.common_lib.cros import chrome
+from autotest_lib.client.cros.enterprise import enterprise_policy_base
+from autotest_lib.client.cros.input_playback import input_playback
+from autotest_lib.client.cros.touch_playback_test_base import EventsPage
+
+
+class policy_KeyboardDefaultToFunctionKeys(
+ enterprise_policy_base.EnterprisePolicyTest):
+ version = 1
+
+ POLICY_NAME = 'KeyboardDefaultToFunctionKeys'
+ TEST_CASES = {
+ 'True': True,
+ 'False': False,
+ 'NotSet': None
+ }
+
+
+ def initialize(self, **kwargs):
+ """
+ Emulate a keyboard and initialize enterprise policy base.
+
+ """
+ super(policy_KeyboardDefaultToFunctionKeys, self).initialize(**kwargs)
+ self.player = input_playback.InputPlayback()
+ self.player.emulate(input_type='keyboard')
+ self.player.find_connected_inputs()
+
+
+ def cleanup(self):
+ """
+ Close playback and policy base class.
+
+ """
+ self.player.close()
+ super(policy_KeyboardDefaultToFunctionKeys, self).cleanup()
+
+
+ def _test_function_keys_default(self, policy_value):
+ """
+ Test default function keys action.
+
+ Search+function keys should perform the alternate action.
+
+ @param policy_value: policy value for this case.
+ @raises error.TestFail if keypress differs from expected value.
+
+ """
+ # Get focus of the page
+ self.player.blocking_playback_of_default_file(
+ input_type='keyboard', filename='keyboard_enter')
+
+ key_actions = ['BrowserForward', 'F2']
+
+ if policy_value:
+ key_actions = reversed(key_actions)
+
+ for action, keys in zip(key_actions, ['f2', 'search+f2']):
+ self._events.clear_previous_events()
+
+ self.player.blocking_playback_of_default_file(
+ input_type='keyboard', filename='keyboard_' + keys)
+
+ events_log = self._events.get_events_log()
+ logging.info('Events log: ' + events_log)
+
+ if not re.search('key=' + action, events_log):
+ raise error.TestFail(('policy_value: %s - typed: %s, '
+ 'expected: %s') %
+ (policy_value, keys, action))
+
+
+ def run_once(self, case):
+ """
+ Setup and run the test configured for the specified test case.
+
+ @param case: Name of the test case to run.
+
+ """
+ case_value = self.TEST_CASES[case]
+ self.setup_case(user_policies={self.POLICY_NAME: case_value},
+ init_network_controller=True)
+
+ self._events = EventsPage(self.cr, self.bindir)
+ self._test_function_keys_default(case_value)
diff --git a/client/site_tests/policy_KeyboardDefaultToFunctionKeys/src/Makefile b/client/site_tests/policy_KeyboardDefaultToFunctionKeys/src/Makefile
new file mode 100644
index 0000000..6c88991
--- /dev/null
+++ b/client/site_tests/policy_KeyboardDefaultToFunctionKeys/src/Makefile
@@ -0,0 +1,28 @@
+# Copyright 2015 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+ifndef SYSROOT
+ $(error Define SYSROOT)
+endif
+
+OUT_DIR ?= .
+PROTO_PATH = $(SYSROOT)/usr/share/protofiles
+PROTO_DEFS = $(PROTO_PATH)/chrome_device_policy.proto \
+ $(PROTO_PATH)/device_management_backend.proto \
+ $(PROTO_PATH)/chrome_extension_policy.proto \
+ $(PROTO_PATH)/cloud_policy.proto
+PROTO_BINDINGS = $(OUT_DIR)/chrome_device_policy_pb2.py \
+ $(OUT_DIR)/device_management_backend_pb2.py \
+ $(OUT_DIR)/chrome_extension_policy_pb2.py \
+ $(OUT_DIR)/cloud_policy_pb2.py
+
+all: $(PROTO_BINDINGS)
+
+$(PROTO_BINDINGS): $(PROTO_DEFS)
+ protoc --proto_path=$(PROTO_PATH) --python_out=$(OUT_DIR) $(PROTO_DEFS)
+
+clean:
+ rm -f $(PROTO_BINDINGS)
+
+
diff --git a/client/site_tests/policy_ProxySettings/policy_ProxySettings.py b/client/site_tests/policy_ProxySettings/policy_ProxySettings.py
index 4b964d4..b2c98ba 100644
--- a/client/site_tests/policy_ProxySettings/policy_ProxySettings.py
+++ b/client/site_tests/policy_ProxySettings/policy_ProxySettings.py
@@ -2,23 +2,27 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import logging, threading
+import logging
+import sys
+import threading
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros.enterprise import enterprise_policy_base
from SocketServer import ThreadingTCPServer, StreamRequestHandler
+from telemetry.core import exceptions as telemetry_exceptions
class ProxyHandler(StreamRequestHandler):
"""Provide request handler for the Threaded Proxy Listener."""
-
def handle(self):
- """Get URL of request from first line.
+ """
+ Get URL of request from first line.
Read the first line of the request, up to 40 characters, and look
for the URL of the request. If found, save it to the URL list.
Note: All requests are sent an HTTP 504 error.
+
"""
# Capture URL in first 40 chars of request.
data = self.rfile.readline(40).strip()
@@ -29,42 +33,50 @@
class ThreadedProxyServer(ThreadingTCPServer):
- """Provide a Threaded Proxy Server to service and save requests.
+ """
+ Provide a Threaded Proxy Server to service and save requests.
Define a Threaded Proxy Server which services requests, and allows the
handler to save all requests.
- """
+ """
def __init__(self, server_address, HandlerClass):
- """Constructor.
+ """
+ Constructor.
@param server_address: tuple of server IP and port to listen on.
@param HandlerClass: the RequestHandler class to instantiate per req.
+
"""
self.requests_received = []
ThreadingTCPServer.allow_reuse_address = True
ThreadingTCPServer.__init__(self, server_address, HandlerClass)
def store_requests_received(self, request):
- """Add receieved request to list.
+ """
+ Add receieved request to list.
@param request: request received by the proxy server.
+
"""
self.requests_received.append(request)
class ProxyListener(object):
- """Provide a Proxy Listener to detect connect requests.
+ """
+ Provide a Proxy Listener to detect connect requests.
Define a proxy listener to detect when a CONNECT request is seen at the
given |server_address|, and record all requests received. Requests
received are exposed to the caller.
- """
+ """
def __init__(self, server_address):
- """Constructor.
+ """
+ Constructor.
@param server_address: tuple of server IP and port to listen on.
+
"""
self._server = ThreadedProxyServer(server_address, ProxyHandler)
self._thread = threading.Thread(target=self._server.serve_forever)
@@ -88,7 +100,8 @@
class policy_ProxySettings(enterprise_policy_base.EnterprisePolicyTest):
- """Test effect of ProxySettings policy on Chrome OS behavior.
+ """
+ Test effect of ProxySettings policy on Chrome OS behavior.
This test verifies the behavior of Chrome OS for specific configurations
of the ProxySettings use policy: None (undefined), ProxyMode=direct,
@@ -100,6 +113,7 @@
server should be used. When ProxyMode=fixed_servers or pac_script, then
the proxy server address specified by the ProxyServer or ProxyPacUrl
entry should be used.
+
"""
version = 1
@@ -129,7 +143,7 @@
self.DIRECT_PROXY = {
'ProxyMode': 'direct'
}
- self.TEST_URL = 'http://www.wired.com/'
+ self.TEST_URL = 'http://www.cnn.com/'
self.TEST_CASES = {
'FixedProxy_UseFixedProxy': self.FIXED_PROXY,
'PacProxy_UsePacFile': self.PAC_PROXY,
@@ -144,20 +158,45 @@
super(policy_ProxySettings, self).cleanup()
+ def navigate_to_url_with_retry(self, url, total_tries=1):
+ """
+ Navigate to url, attempting retry_count times if it fails to load.
+
+ @param url: string of the url to load.
+ @param total_tries: number of attempts to load the page.
+
+ @raises: error.TestError if page load times out.
+
+ """
+ for i in xrange(total_tries):
+ try:
+ self.navigate_to_url(url)
+ except telemetry_exceptions.TimeoutError as e:
+ if i is total_tries - 1:
+ logging.error('Timeout error: %s [%s].', str(e),
+ sys.exc_info())
+ raise error.TestError('Could not load %s after '
+ '%s tries.' % (url, total_tries))
+ else:
+ logging.debug('Retrying page load of %s.', url)
+ logging.debug('Timeout error: %s.', str(e))
+ else:
+ break
+
+
def _test_proxy_configuration(self, policy_value):
- """Verify CrOS enforces the specified ProxySettings configuration.
+ """
+ Verify CrOS enforces the specified ProxySettings configuration.
@param policy_value: policy value expected.
+
+ @raises error.TestFail if behavior does not match expected.
+
"""
self._proxy_server.reset_requests_received()
- self.navigate_to_url(self.TEST_URL)
+ self.navigate_to_url_with_retry(url=self.TEST_URL, total_tries=2)
proxied_requests = self._proxy_server.get_requests_received()
- # Determine whether TEST_URL is in |proxied_requests|. Comprehension
- # is conceptually equivalent to `TEST_URL in proxied_requests`;
- # however, we must do partial matching since TEST_URL and the
- # elements inside |proxied_requests| are not necessarily equal, i.e.,
- # TEST_URL is a substring of the received request.
matching_requests = [request for request in proxied_requests
if self.TEST_URL in request]
logging.info('matching_requests: %s', matching_requests)
@@ -176,9 +215,11 @@
def run_once(self, case):
- """Setup and run the test configured for the specified test case.
+ """
+ Setup and run the test configured for the specified test case.
- @param case: Name of the test case to run.
+ @param case: Name of the test case to run: see TEST_CASES.
+
"""
case_value = self.TEST_CASES[case]
self.setup_case(user_policies={self.POLICY_NAME: case_value})
diff --git a/client/site_tests/policy_RestoreOnStartupURLs/control.multipleurls_3tabs b/client/site_tests/policy_RestoreOnStartupURLs/control.multipleurls_3tabs
index 2109d3b..f0736aa 100644
--- a/client/site_tests/policy_RestoreOnStartupURLs/control.multipleurls_3tabs
+++ b/client/site_tests/policy_RestoreOnStartupURLs/control.multipleurls_3tabs
@@ -4,8 +4,7 @@
AUTHOR = 'scunningham'
NAME = 'policy_RestoreOnStartupURLs.multipleurls_3tabs'
-#TODO: Enable this test once crbug.com/805999 is fixed.
-#ATTRIBUTES = 'suite:bvt-perbuild, suite:policy'
+ATTRIBUTES = 'suite:bvt-perbuild, suite:policy'
TIME = 'SHORT'
TEST_CATEGORY = 'General'
TEST_CLASS = 'enterprise'
diff --git a/client/site_tests/policy_RestoreOnStartupURLs/policy_RestoreOnStartupURLs.py b/client/site_tests/policy_RestoreOnStartupURLs/policy_RestoreOnStartupURLs.py
index 52a6d92..3fc24fb 100644
--- a/client/site_tests/policy_RestoreOnStartupURLs/policy_RestoreOnStartupURLs.py
+++ b/client/site_tests/policy_RestoreOnStartupURLs/policy_RestoreOnStartupURLs.py
@@ -51,19 +51,16 @@
# Get list of open tab urls from browser; Convert unicode to text;
# Strip any trailing '/' character reported by devtools.
tab_urls = [tab.url.encode('utf8').rstrip('/')
- for tab in reversed(self.cr.browser.tabs)]
+ for tab in self.cr.browser.tabs]
# Telemetry always opens a 'newtab' tab if no startup tabs are opened.
- # If the only open tab is 'newtab', or a tab with the termporary url
- # www.google.com/_/chrome/newtab..., then set tab URLs to None.
- if len(tab_urls) == 1:
- for newtab_url in self.NEWTAB_URLS:
- if newtab_url in tab_urls:
- tab_urls = None
- break
+ if policy_value is None:
+ if len(tab_urls) != 1 or tab_urls[0] not in self.NEWTAB_URLS:
+ raise error.TestFail('Unexpected tabs: %s (expected: NEWTAB)' %
+ tab_urls)
# Compare open tabs with expected tabs by |policy_value|.
- if tab_urls != policy_value:
+ elif set(tab_urls) != set(policy_value):
raise error.TestFail('Unexpected tabs: %s (expected: %s)' %
(tab_urls, policy_value))
diff --git a/client/site_tests/vm_CrosVmStart/control b/client/site_tests/vm_CrosVmStart/control
index 6fa3e80..98eddfd 100644
--- a/client/site_tests/vm_CrosVmStart/control
+++ b/client/site_tests/vm_CrosVmStart/control
@@ -12,7 +12,7 @@
CRITERIA = """
Fail the VM fails to start or run a command.
"""
-ATTRIBUTES = ""
+ATTRIBUTES = "suite:bvt-cq"
TEST_CLASS = "security"
TEST_CATEGORY = "Functional"
TEST_TYPE = "client"
diff --git a/contrib/summarize_loadtest.py b/contrib/summarize_loadtest.py
index eac9392..6dd8505 100755
--- a/contrib/summarize_loadtest.py
+++ b/contrib/summarize_loadtest.py
@@ -7,10 +7,8 @@
"""Load generator for devserver."""
import argparse
-import ast
import itertools
import json
-import operator
import pprint
import re
import sys
@@ -20,16 +18,6 @@
from chromite.lib import cros_logging as logging
-# Map ast to operator.
-OPERATORS = {
- ast.Add: operator.add, ast.Sub: operator.sub, ast.Mult: operator.mul,
- ast.Div: operator.truediv, ast.USub: operator.neg,
- ast.Not: operator.not_,
- ast.Eq: operator.eq, ast.NotEq: operator.ne,
- ast.Lt: operator.lt, ast.Gt: operator.gt,
- ast.LtE: operator.le, ast.GtE: operator.ge,
-}
-
# Default keys to skip displaying.
DEFAULT_SKIP = [
'build_name',
@@ -71,67 +59,11 @@
parser.add_argument('--%s' % arg, type=str, action='store',
help='Comma-separated list of %s to filter by.' %
arg)
+ parser.add_argument('--no-summary', action='store_false', dest='summary',
+ help='Disable summary.')
return parser
-def eval_entry(expr, entry):
- """Perform evaluation of an expression.
-
- Named variables are interpreted as key-values from entry.
- """
- return eval_node(ast.parse(expr, mode='eval').body, entry)
-
-def eval_node(node, entry):
- """Perform evaluation of a node."""
- if isinstance(node, ast.Num):
- return node.n
- elif isinstance(node, ast.Str):
- return node.s
- elif isinstance(node, ast.Name):
- if node.id == 'True':
- return True
- elif node.id == 'False':
- return False
- else:
- return entry[node.id]
- elif isinstance(node, ast.BinOp):
- return OPERATORS[type(node.op)](eval_node(node.left, entry),
- eval_node(node.right, entry))
- elif isinstance(node, ast.UnaryOp): # <operator> <operand> e.g., -1
- return OPERATORS[type(node.op)](eval_node(node.operand, entry))
- elif isinstance(node, ast.BoolOp): # <operator> <operand> e.g., -1
- if isinstance(node.op, ast.And):
- for value in node.values:
- if not eval_node(value, entry):
- return False
- return True
- elif isinstance(node.op, ast.Or):
- for value in node.values:
- if eval_node(value, entry):
- return True
- return False
- else:
- raise TypeError(node)
- elif isinstance(node, ast.Compare): # <operator> <operand> e.g., -1
- left = node.left
- for op, comparator in zip(node.ops, node.comparators):
- if not OPERATORS[type(op)](eval_node(left, entry),
- eval_node(comparator, entry)):
- return False
- left = comparator
- return True
- elif isinstance(node, ast.Call):
- if isinstance(node.func, ast.Name) and node.func.id == 'match':
- return re.match(eval_node(node.args[0], entry),
- eval_node(node.args[1], entry))
- elif isinstance(node.func, ast.Name) and node.func.id == 'search':
- return re.search(eval_node(node.args[0], entry),
- eval_node(node.args[1], entry))
- else:
- raise TypeError(node)
- else:
- raise TypeError(node)
-
def summarize_entries(entries, skip=set()):
"""Summarize a list of entries."""
TAG_KEYS = [
@@ -219,7 +151,7 @@
options.__dict__[arg].split(','),
entries)
if options.filter:
- entries = filter(lambda x: eval_entry(options.filter, x), entries)
+ entries = filter(lambda x: eval(options.filter, {'re': re}, x), entries)
# Group the entries based on specified keys.
groups = group_entries(options.group.split(',') if options.group else None,
@@ -232,7 +164,7 @@
parents = []
for entry in dump_entries:
print(json.dumps(entry))
- if entry['parent'] not in parents:
+ if 'parent' in entry and entry['parent'] not in parents:
parents.append(entry['parent'])
# Dump all parents.
for entry in all_entries:
@@ -240,9 +172,10 @@
print(json.dumps(entry))
# Summarize the entries, group by group.
- skip = options.skip.split(',') if options.skip else set()
- summaries = [summarize_entries(group, skip) for group in groups]
- print(json.dumps(summaries, indent=2))
+ if options.summary:
+ skip = options.skip.split(',') if options.skip else set()
+ summaries = [summarize_entries(group, skip) for group in groups]
+ print(json.dumps(summaries, indent=2))
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))
diff --git a/frontend/afe/frontend_test_utils.py b/frontend/afe/frontend_test_utils.py
index 8adcb4a..10599ed 100644
--- a/frontend/afe/frontend_test_utils.py
+++ b/frontend/afe/frontend_test_utils.py
@@ -69,6 +69,23 @@
self.god.unstub_all()
+ def _set_static_attribute(self, host, attribute, value):
+ """Set static attribute for a host.
+
+ It ensures that all static attributes have a corresponding
+ entry in afe_host_attributes.
+ """
+ # Get or create the reference object in afe_host_attributes.
+ model, args = host._get_attribute_model_and_args(attribute)
+ model.objects.get_or_create(**args)
+
+ attribute_model, get_args = host._get_static_attribute_model_and_args(
+ attribute)
+ attribute_object, _ = attribute_model.objects.get_or_create(**get_args)
+ attribute_object.value = value
+ attribute_object.save()
+
+
def _create_job(self, hosts=[], metahosts=[], priority=0, active=False,
synchronous=False, hostless=False,
drone_set=None, control_file='control',
diff --git a/frontend/afe/moblab_rpc_interface.py b/frontend/afe/moblab_rpc_interface.py
index d4c1315..92e44f7 100644
--- a/frontend/afe/moblab_rpc_interface.py
+++ b/frontend/afe/moblab_rpc_interface.py
@@ -467,8 +467,8 @@
version_response = {
x.split('=')[0]: x.split('=')[1] for x in lines if '=' in x}
version_response['MOBLAB_ID'] = utils.get_moblab_id();
- version_response['MOBLAB_MAC_ADDRESS'] = (
- utils.get_default_interface_mac_address())
+ version_response['MOBLAB_SERIAL_NUMBER'] = (
+ utils.get_moblab_serial_number())
_check_for_system_update()
update_status = _get_system_update_status()
version_response['MOBLAB_UPDATE_VERSION'] = update_status['NEW_VERSION']
diff --git a/frontend/afe/model_logic.py b/frontend/afe/model_logic.py
index 3bad06b..98dec4b 100644
--- a/frontend/afe/model_logic.py
+++ b/frontend/afe/model_logic.py
@@ -9,6 +9,8 @@
from django.db import transaction
from django.db.models.sql import query
import django.db.models.sql.where
+
+from autotest_lib.client.common_lib import error
from autotest_lib.frontend.afe import rdb_model_extensions
@@ -1307,7 +1309,21 @@
raise NotImplementedError
+ def _is_replaced_by_static_attribute(self, attribute):
+ """
+ Subclasses could override this to indicate whether it has static
+ attributes.
+ """
+ return False
+
+
def set_attribute(self, attribute, value):
+ if self._is_replaced_by_static_attribute(attribute):
+ raise error.UnmodifiableAttributeException(
+ 'Failed to set attribute "%s" for host "%s" since it '
+ 'is static. Use go/chromeos-skylab-inventory-tools to '
+ 'modify this attribute.' % (attribute, self.hostname))
+
attribute_model, get_args = self._get_attribute_model_and_args(
attribute)
attribute_object, _ = attribute_model.objects.get_or_create(**get_args)
@@ -1316,6 +1332,12 @@
def delete_attribute(self, attribute):
+ if self._is_replaced_by_static_attribute(attribute):
+ raise error.UnmodifiableAttributeException(
+ 'Failed to delete attribute "%s" for host "%s" since it '
+ 'is static. Use go/chromeos-skylab-inventory-tools to '
+ 'modify this attribute.' % (attribute, self.hostname))
+
attribute_model, get_args = self._get_attribute_model_and_args(
attribute)
try:
diff --git a/frontend/afe/models.py b/frontend/afe/models.py
index 9224c28..beb64c3 100644
--- a/frontend/afe/models.py
+++ b/frontend/afe/models.py
@@ -29,6 +29,9 @@
RESPECT_STATIC_LABELS = global_config.global_config.get_config_value(
'SKYLAB', 'respect_static_labels', type=bool, default=False)
+RESPECT_STATIC_ATTRIBUTES = global_config.global_config.get_config_value(
+ 'SKYLAB', 'respect_static_attributes', type=bool, default=False)
+
class AclAccessViolation(Exception):
"""\
@@ -880,6 +883,18 @@
return StaticHostAttribute, dict(host=self, attribute=attribute)
+ def _is_replaced_by_static_attribute(self, attribute):
+ if RESPECT_STATIC_ATTRIBUTES:
+ model, args = self._get_static_attribute_model_and_args(attribute)
+ try:
+ static_attr = model.objects.get(**args)
+ return True
+ except StaticHostAttribute.DoesNotExist:
+ return False
+
+ return False
+
+
@classmethod
def get_attribute_model(cls):
"""Return the attribute model.
@@ -1399,7 +1414,7 @@
# - a job whose hqe has a host
# - one of the host's labels matches the shard's label.
# Non-aborted known jobs, completed jobs, active jobs, jobs
- # without hqe are excluded as we do with SQL_SHARD_JOBS.
+ # without hqe are exluded as we do with SQL_SHARD_JOBS.
SQL_SHARD_JOBS_WITH_HOSTS = (
'SELECT DISTINCT(t1.id) FROM afe_jobs t1 '
'INNER JOIN afe_host_queue_entries t2 ON '
@@ -1645,18 +1660,10 @@
check_known_jobs_exclude = 'AND NOT ' + check_known_jobs
check_known_jobs_include = 'OR ' + check_known_jobs
- #TODO(jkop): Get rid of this kludge when we update Django to >=1.7
- #correct usage would be .raw(..., using='readonly')
- old_db = Job.objects._db
- Job.objects._db = 'readonly'
- raw_sql = cls.SQL_SHARD_JOBS % {
- 'check_known_jobs': check_known_jobs_exclude,
- 'shard_id': shard.id}
- job_ids |= set([j.id for j in Job.objects.raw(raw_sql)])
- Job.objects._db = old_db
- if not job_ids:
- #If the replica is down or we're in a test, fetch from master.
- job_ids |= set([j.id for j in Job.objects.raw(raw_sql)])
+ query = Job.objects.raw(cls.SQL_SHARD_JOBS % {
+ 'check_known_jobs': check_known_jobs_exclude,
+ 'shard_id': shard.id})
+ job_ids |= set([j.id for j in query])
static_labels, non_static_labels = Host.classify_label_objects(
shard.labels.all())
diff --git a/frontend/afe/models_test.py b/frontend/afe/models_test.py
index 62f2423..25ca5e5 100755
--- a/frontend/afe/models_test.py
+++ b/frontend/afe/models_test.py
@@ -4,6 +4,7 @@
import unittest
import common
+from autotest_lib.client.common_lib import error
from autotest_lib.frontend import setup_django_environment
from autotest_lib.frontend.afe import frontend_test_utils
from autotest_lib.frontend.afe import models, model_logic
@@ -50,6 +51,72 @@
self._frontend_common_teardown()
+ def _get_attributes(self, host):
+ models.Host.objects.populate_relationships(
+ [host], models.HostAttribute, 'attribute_list')
+ return dict((attribute.attribute, attribute.value)
+ for attribute in host.attribute_list)
+
+ def test_delete_attribute(self):
+ previous_config = models.RESPECT_STATIC_ATTRIBUTES
+ models.RESPECT_STATIC_ATTRIBUTES = False
+ host1 = models.Host.objects.create(hostname='test_host1')
+ host1.set_attribute('test_attribute1', 'test_value1')
+
+ attributes = self._get_attributes(host1)
+ self.assertEquals(attributes['test_attribute1'], 'test_value1')
+
+ host1.set_or_delete_attribute('test_attribute1', None)
+ attributes = self._get_attributes(host1)
+ self.assertNotIn('test_attribute1', attributes.keys())
+
+ models.RESPECT_STATIC_ATTRIBUTES = previous_config
+
+
+ def test_delete_static_attribute(self):
+ previous_config = models.RESPECT_STATIC_ATTRIBUTES
+ models.RESPECT_STATIC_ATTRIBUTES = True
+ host1 = models.Host.objects.create(hostname='test_host1')
+ host1.set_attribute('test_attribute1', 'test_value1')
+ self._set_static_attribute(host1, 'test_attribute1', 'test_value1')
+
+ self.assertRaises(
+ error.UnmodifiableAttributeException,
+ host1.set_or_delete_attribute,
+ 'test_attribute1', None)
+
+ models.RESPECT_STATIC_ATTRIBUTES = previous_config
+
+
+ def test_set_attribute(self):
+ previous_config = models.RESPECT_STATIC_ATTRIBUTES
+ models.RESPECT_STATIC_ATTRIBUTES = False
+ host1 = models.Host.objects.create(hostname='test_host1')
+ host1.set_attribute('test_attribute1', 'test_value1')
+
+ host1.set_or_delete_attribute('test_attribute1', 'test_new_value1')
+
+ attributes = self._get_attributes(host1)
+ self.assertEquals(attributes['test_attribute1'], 'test_new_value1')
+
+ models.RESPECT_STATIC_ATTRIBUTES = previous_config
+
+
+ def test_set_static_attribute(self):
+ previous_config = models.RESPECT_STATIC_ATTRIBUTES
+ models.RESPECT_STATIC_ATTRIBUTES = True
+ host1 = models.Host.objects.create(hostname='test_host1')
+ host1.set_attribute('test_attribute1', 'test_value1')
+ self._set_static_attribute(host1, 'test_attribute1', 'test_value1')
+
+ self.assertRaises(
+ error.UnmodifiableAttributeException,
+ host1.set_or_delete_attribute,
+ 'test_attribute1', 'test_value2')
+
+ models.RESPECT_STATIC_ATTRIBUTES = previous_config
+
+
def test_add_host_previous_one_time_host(self):
# ensure that when adding a host which was previously used as a one-time
# host, the status isn't reset, since this can interfere with the
diff --git a/frontend/afe/rpc_interface.py b/frontend/afe/rpc_interface.py
index b4e1733..846574b 100644
--- a/frontend/afe/rpc_interface.py
+++ b/frontend/afe/rpc_interface.py
@@ -566,10 +566,20 @@
models.Host.objects.populate_relationships(hosts, models.HostAttribute,
'attribute_list')
host_attr_dicts = []
+ host_objs = []
for host_obj in hosts:
for attr_obj in host_obj.attribute_list:
if attr_obj.attribute == attribute:
host_attr_dicts.append(attr_obj.get_object_dict())
+ host_objs.append(host_obj)
+
+ if RESPECT_STATIC_ATTRIBUTES:
+ for host_attr, host_obj in zip(host_attr_dicts, host_objs):
+ static_attrs = models.StaticHostAttribute.query_objects(
+ {'host_id': host_obj.id, 'attribute': attribute})
+ if len(static_attrs) > 0:
+ host_attr['value'] = static_attrs[0].value
+
return rpc_utils.prepare_for_serialization(host_attr_dicts)
diff --git a/frontend/afe/rpc_interface_unittest.py b/frontend/afe/rpc_interface_unittest.py
index bf31ccb..8e74d0b 100755
--- a/frontend/afe/rpc_interface_unittest.py
+++ b/frontend/afe/rpc_interface_unittest.py
@@ -267,23 +267,6 @@
models.RESPECT_STATIC_ATTRIBUTES = self.old_respect_static_config
- def _set_static_attribute(self, host, attribute, value):
- """Set static attribute for a host.
-
- It ensures that all static attributes have a corresponding
- entry in afe_host_attributes.
- """
- # Get or create the reference object in afe_host_attributes.
- model, args = host._get_attribute_model_and_args(attribute)
- model.objects.get_or_create(**args)
-
- attribute_model, get_args = host._get_static_attribute_model_and_args(
- attribute)
- attribute_object, _ = attribute_model.objects.get_or_create(**get_args)
- attribute_object.value = value
- attribute_object.save()
-
-
def _fake_host_with_static_attributes(self):
host1 = models.Host.objects.create(hostname='test_host')
host1.set_attribute('test_attribute1', 'test_value1')
@@ -307,6 +290,25 @@
'test_attribute2': 'test_value2',
'static_attribute1': 'static_value2'})
+ def test_get_host_attribute_with_static(self):
+ host1 = models.Host.objects.create(hostname='test_host1')
+ host1.set_attribute('test_attribute1', 'test_value1')
+ self._set_static_attribute(host1, 'test_attribute1', 'static_value1')
+ host2 = models.Host.objects.create(hostname='test_host2')
+ host2.set_attribute('test_attribute1', 'test_value1')
+ host2.set_attribute('test_attribute2', 'test_value2')
+
+ attributes = rpc_interface.get_host_attribute(
+ 'test_attribute1',
+ hostname__in=['test_host1', 'test_host2'])
+ hosts = [attr['host'] for attr in attributes]
+ values = [attr['value'] for attr in attributes]
+ self.assertEquals(set(hosts),
+ set(['test_host1', 'test_host2']))
+ self.assertEquals(set(values),
+ set(['test_value1', 'static_value1']))
+
+
def test_get_hosts_by_attribute_without_static(self):
host1 = models.Host.objects.create(hostname='test_host1')
host1.set_attribute('test_attribute1', 'test_value1')
@@ -744,6 +746,22 @@
set(['test_host1', 'test_host2']))
+ def test_get_host_attribute(self):
+ host1 = models.Host.objects.create(hostname='test_host1')
+ host1.set_attribute('test_attribute1', 'test_value1')
+ host2 = models.Host.objects.create(hostname='test_host2')
+ host2.set_attribute('test_attribute1', 'test_value1')
+
+ attributes = rpc_interface.get_host_attribute(
+ 'test_attribute1',
+ hostname__in=['test_host1', 'test_host2'])
+ hosts = [attr['host'] for attr in attributes]
+ values = [attr['value'] for attr in attributes]
+ self.assertEquals(set(hosts),
+ set(['test_host1', 'test_host2']))
+ self.assertEquals(set(values), set(['test_value1']))
+
+
def test_get_hosts(self):
hosts = rpc_interface.get_hosts()
self._check_hostnames(hosts, [host.hostname for host in self.hosts])
diff --git a/frontend/client/src/autotest/moblab/rpc/VersionInfo.java b/frontend/client/src/autotest/moblab/rpc/VersionInfo.java
index 06870cb..538941d 100644
--- a/frontend/client/src/autotest/moblab/rpc/VersionInfo.java
+++ b/frontend/client/src/autotest/moblab/rpc/VersionInfo.java
@@ -21,7 +21,7 @@
private static final String NO_TRACK_FOUND = "NO TRACK FOUND";
private static final String NO_DESCRIPTION_FOUND = "NO DESCRIPTION FOUND";
private static final String NO_ID_FOUND = "NO ID FOUND";
- private static final String NO_MAC_ADDRESS_FOUND = "NO MAC ADDRESS FOUND";
+ private static final String NO_SERIAL_NUMBER_FOUND = "NO SERIAL NUMBER FOUND";
private static final String NO_UPDATE_VERSION_FOUND =
"NO UPDATE VERSION FOUND";
@@ -30,7 +30,7 @@
private String releaseTrack;
private String releaseDescription;
private String moblabIdentification;
- private String moblabMacAddress;
+ private String moblabSerialNumber;
private String moblabUpdateVersion;
private double moblabUpdateProgress;
private UPDATE_STATUS moblabUpdateStatus;
@@ -43,7 +43,7 @@
public String getReleaseTrack() { return releaseTrack; }
public String getReleaseDescription() { return releaseDescription; }
public String getMoblabIdentification() { return moblabIdentification; }
- public String getMoblabMacAddress() { return moblabMacAddress; }
+ public String getMoblabSerialNumber() { return moblabSerialNumber; }
public String getMoblabUpdateVersion() { return moblabUpdateVersion; }
public double getMoblabUpdateProgress() { return moblabUpdateProgress; }
public UPDATE_STATUS getMoblabUpdateStatus() { return moblabUpdateStatus; }
@@ -54,7 +54,7 @@
releaseTrack = new String(NO_TRACK_FOUND);
releaseDescription = new String(NO_DESCRIPTION_FOUND);
moblabIdentification = new String(NO_ID_FOUND);
- moblabMacAddress = new String(NO_MAC_ADDRESS_FOUND);
+ moblabSerialNumber = new String(NO_SERIAL_NUMBER_FOUND);
moblabUpdateVersion = new String(NO_UPDATE_VERSION_FOUND);
moblabUpdateStatus = UPDATE_STATUS.UNKNOWN;
moblabUpdateProgress = 0.0;
@@ -72,9 +72,9 @@
releaseDescription = getStringFieldOrDefault(object, "CHROMEOS_RELEASE_DESCRIPTION",
NO_DESCRIPTION_FOUND).trim();
moblabIdentification = getStringFieldOrDefault(object, "MOBLAB_ID",
- NO_DESCRIPTION_FOUND).trim();
- moblabMacAddress = getStringFieldOrDefault(object, "MOBLAB_MAC_ADDRESS",
- NO_DESCRIPTION_FOUND).trim();
+ NO_ID_FOUND).trim();
+ moblabSerialNumber = getStringFieldOrDefault(object, "MOBLAB_SERIAL_NUMBER",
+ NO_SERIAL_NUMBER_FOUND).trim();
moblabUpdateVersion = getStringFieldOrDefault(
object, "MOBLAB_UPDATE_VERSION", NO_UPDATE_VERSION_FOUND).trim();
moblabUpdateStatus = getUpdateStatus(object);
diff --git a/frontend/client/src/autotest/moblab/wizard/ConfigWizard.java b/frontend/client/src/autotest/moblab/wizard/ConfigWizard.java
index 9e3437a..a47625b 100644
--- a/frontend/client/src/autotest/moblab/wizard/ConfigWizard.java
+++ b/frontend/client/src/autotest/moblab/wizard/ConfigWizard.java
@@ -159,8 +159,8 @@
layoutTable.setWidget(row, 1, new Label(
info.getMoblabIdentification()));
row++;
- layoutTable.setWidget(row, 0, new Label("Moblab Mac Address"));
- layoutTable.setWidget(row, 1, new Label(info.getMoblabMacAddress()));
+ layoutTable.setWidget(row, 0, new Label("Moblab Serial Number"));
+ layoutTable.setWidget(row, 1, new Label(info.getMoblabSerialNumber()));
}
});
return layoutTable;
diff --git a/frontend/tko/models_test.py b/frontend/tko/models_test.py
new file mode 100644
index 0000000..e7db614
--- /dev/null
+++ b/frontend/tko/models_test.py
@@ -0,0 +1,61 @@
+#!/usr/bin/python
+# pylint: disable=missing-docstring
+
+import unittest
+
+import common
+from autotest_lib.frontend import setup_django_environment
+from autotest_lib.frontend import setup_test_environment
+from autotest_lib.frontend.tko import models
+
+
+class TKOTestTest(unittest.TestCase):
+
+ def setUp(self):
+ setup_test_environment.set_up()
+ self.machine1 = models.Machine.objects.create(hostname='myhost')
+ self.good_status = models.Status.objects.create(word='GOOD')
+ kernel_name = 'mykernel1'
+ self.kernel1 = models.Kernel.objects.create(kernel_hash=kernel_name,
+ base=kernel_name,
+ printable=kernel_name)
+ self.job1 = models.Job.objects.create(
+ tag='1-myjobtag1', label='myjob1',
+ username='myuser', machine=self.machine1,
+ afe_job_id=1)
+ self.job1_test1 = models.Test.objects.create(
+ job=self.job1, test='mytest1',
+ kernel=self.kernel1,
+ status=self.good_status,
+ machine=self.machine1)
+
+
+ def tearDown(self):
+ setup_test_environment.tear_down()
+
+
+ def _get_attributes(self, test):
+ models.Test.objects.populate_relationships(
+ [test], models.TestAttribute, 'attribute_list')
+ return dict((attribute.attribute, attribute.value)
+ for attribute in test.attribute_list)
+
+ def test_delete_attribute(self):
+ test1 = self.job1_test1
+ test1.set_attribute('test_attribute1', 'test_value1')
+
+ attributes = self._get_attributes(test1)
+ self.assertEquals(attributes['test_attribute1'], 'test_value1')
+
+ test1.set_or_delete_attribute('test_attribute1', None)
+ attributes = self._get_attributes(test1)
+ self.assertNotIn('test_attribute1', attributes.keys())
+
+
+ def test_set_attribute(self):
+ # Verify adding static attribute in model_logic doesn't break TKO Test.
+ test1 = self.job1_test1
+ test1.set_attribute('test_attribute1', 'test_value1')
+ test1.set_or_delete_attribute('test_attribute1', 'test_value2')
+ attributes = self._get_attributes(test1)
+ self.assertEquals(attributes['test_attribute1'], 'test_value2')
diff --git a/global_config.ini b/global_config.ini
index a077da2..3166868 100644
--- a/global_config.ini
+++ b/global_config.ini
@@ -467,6 +467,7 @@
lucifer_level: GATHERING
binaries_path: /usr/bin
jobdir: /usr/local/autotest/leases
+gcp_creds:
[LXC_POOL]
use_lxc_pool: False
diff --git a/scheduler/luciferlib.py b/scheduler/luciferlib.py
index 89529d3..6cc107d 100644
--- a/scheduler/luciferlib.py
+++ b/scheduler/luciferlib.py
@@ -20,6 +20,7 @@
# TODO(crbug.com/748234): Move these to shadow_config.ini
# See also drones.AUTOTEST_INSTALL_DIR
+_ENV = '/usr/bin/env'
_AUTOTEST_DIR = '/usr/local/autotest'
_JOB_REPORTER_PATH = os.path.join(_AUTOTEST_DIR, 'bin', 'job_reporter')
@@ -104,6 +105,8 @@
results_dir = _results_dir(manager, job)
num_tests_failed = manager.get_num_tests_failed(pidfile_id)
args = [
+ _JOB_REPORTER_PATH,
+
# General configuration
'--jobdir', _get_jobdir(),
'--run-job-path', _get_run_job_path(),
@@ -117,8 +120,13 @@
'--num-tests-failed', str(num_tests_failed),
'--results-dir', results_dir,
]
+ if _get_gcp_creds():
+ args = [
+ 'GOOGLE_APPLICATION_CREDENTIALS=%s'
+ % pipes.quote(_get_gcp_creds()),
+ ] + args
output_file = os.path.join(results_dir, 'job_reporter_output.log')
- drone.spawn(_JOB_REPORTER_PATH, args, output_file=output_file)
+ drone.spawn(_ENV, args, output_file=output_file)
return drone
@@ -142,6 +150,8 @@
drone = manager.get_drone_for_pidfile(pidfile_id)
results_dir = _results_dir(manager, job)
args = [
+ _JOB_REPORTER_PATH,
+
# General configuration
'--jobdir', _get_jobdir(),
'--run-job-path', _get_run_job_path(),
@@ -153,13 +163,18 @@
'--autoserv-exit', str(autoserv_exit),
'--results-dir', results_dir,
]
+ if _get_gcp_creds():
+ args = [
+ 'GOOGLE_APPLICATION_CREDENTIALS=%s'
+ % pipes.quote(_get_gcp_creds()),
+ ] + args
output_file = os.path.join(results_dir, 'job_reporter_output.log')
- drone.spawn(_JOB_REPORTER_PATH, args, output_file=output_file)
+ drone.spawn(_ENV, args, output_file=output_file)
return drone
def _get_jobdir():
- return _config.get_config_value(_SECTION, 'jobdir', type=str)
+ return _config.get_config_value(_SECTION, 'jobdir')
def _get_run_job_path():
@@ -172,7 +187,15 @@
def _get_binaries_path():
"""Get binaries dir path from config.."""
- return _config.get_config_value(_SECTION, 'binaries_path', type=str)
+ return _config.get_config_value(_SECTION, 'binaries_path')
+
+
+def _get_gcp_creds():
+ """Return path to GCP service account credentials.
+
+ This is the empty string by default, if no credentials will be used.
+ """
+ return _config.get_config_value(_SECTION, 'gcp_creds', default='')
class _DroneManager(object):
diff --git a/server/control_segments/stage_server_side_package b/server/control_segments/stage_server_side_package
index 1e2b8c5..8313c0b 100644
--- a/server/control_segments/stage_server_side_package
+++ b/server/control_segments/stage_server_side_package
@@ -6,6 +6,8 @@
import logging
+from contextlib import closing
+
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import dev_server
from autotest_lib.server import hosts
@@ -17,9 +19,9 @@
# Only need to stage server side package once.
for machine in machines:
try:
- host = hosts.create_host(machine)
- ssp_url = host.stage_server_side_package(image)
+ with closing(hosts.create_host(machine)) as host:
+ ssp_url = host.stage_server_side_package(image)
break
except (error.AutoservError, dev_server.DevServerException) as e:
error_msg = str(e)
- logging.error('Stage server-side package failed. %s', e)
\ No newline at end of file
+ logging.error('Stage server-side package failed. %s', e)
diff --git a/server/cros/faft/utils/mode_switcher.py b/server/cros/faft/utils/mode_switcher.py
index 63dafe4..579e104 100644
--- a/server/cros/faft/utils/mode_switcher.py
+++ b/server/cros/faft/utils/mode_switcher.py
@@ -530,21 +530,28 @@
logging.info("-[ModeSwitcher]-[ start mode_aware_reboot(%r, %s, ..) ]-",
reboot_type, reboot_method.__name__)
- is_dev = False
+ is_dev = is_rec = is_devsw_boot = False
if sync_before_boot:
is_dev = self.checkers.mode_checker('dev')
+ is_rec = self.checkers.mode_checker('rec')
+ is_devsw_boot = self.checkers.crossystem_checker(
+ {'devsw_boot': '1'}, True)
boot_id = self.faft_framework.get_bootid()
self.faft_framework.blocking_sync()
- logging.info("-[mode_aware_reboot]-[ is_dev=%s ]-", is_dev);
+ if is_rec:
+ logging.info("-[mode_aware_reboot]-[ is_rec=%s is_dev_switch=%s ]-",
+ is_rec, is_devsw_boot)
+ else:
+ logging.info("-[mode_aware_reboot]-[ is_dev=%s ]-", is_dev)
reboot_method()
if sync_before_boot:
self.wait_for_client_offline(orig_boot_id=boot_id)
# Encapsulating the behavior of skipping dev firmware screen,
# hitting ctrl-D
- # Note that if booting from recovery mode, will not
- # call bypass_dev_mode because can't determine prior to
- # reboot if we're going to boot up in dev or normal mode.
- if is_dev:
+ # Note that if booting from recovery mode, we can predict the next
+ # boot based on the developer switch position at boot (devsw_boot).
+ # If devsw_boot is True, we will call bypass_dev_mode after reboot.
+ if is_dev or is_devsw_boot:
self.bypass_dev_mode()
if wait_for_dut_up:
self.wait_for_client()
diff --git a/server/cros/multimedia/input_facade_adapter.py b/server/cros/multimedia/input_facade_adapter.py
index 8e7f483..b687f89 100644
--- a/server/cros/multimedia/input_facade_adapter.py
+++ b/server/cros/multimedia/input_facade_adapter.py
@@ -64,3 +64,11 @@
"""
return json.loads(self._input_proxy.get_input_events())
+
+
+ def press_keys(self, key_list):
+ """ Simulating key press
+
+ @param key_list: A list of key strings, e.g. ['LEFTCTRL', 'F4']
+ """
+ self._input_proxy.press_keys(key_list)
diff --git a/server/cros/telemetry_runner.py b/server/cros/telemetry_runner.py
index 6ea24ee..4677788 100644
--- a/server/cros/telemetry_runner.py
+++ b/server/cros/telemetry_runner.py
@@ -23,7 +23,8 @@
FAILED_STATUS = 'FAILED'
# A list of benchmarks with that the telemetry test harness can run on dut.
-ON_DUT_WHITE_LIST = ['dromaeo.domcoreattr',
+ON_DUT_WHITE_LIST = ['cros_ui_smoothness',
+ 'dromaeo.domcoreattr',
'dromaeo.domcoremodify',
'dromaeo.domcorequery',
'dromaeo.domcoretraverse',
diff --git a/server/cros/update_engine/omaha_devserver.py b/server/cros/update_engine/omaha_devserver.py
index ea6410d..f274c31 100644
--- a/server/cros/update_engine/omaha_devserver.py
+++ b/server/cros/update_engine/omaha_devserver.py
@@ -46,19 +46,22 @@
_DEVSERVER_TIMELIMIT_SECONDS = 12 * 60 * 60
- def __init__(self, omaha_host, update_payload_staged_url, max_updates=1):
+ def __init__(self, omaha_host, update_payload_staged_url, max_updates=1,
+ critical_update=True):
"""Starts a private devserver instance, operating at Omaha capacity.
@param omaha_host: host address where the devserver is spawned.
@param update_payload_staged_url: URL to provision for update requests.
@param max_updates: int number of updates this devserver will handle.
This is passed to src/platform/dev/devserver.py.
+ @param critical_update: Whether to set a deadline in responses.
"""
self._devserver_dir = '/home/chromeos-test/chromiumos/src/platform/dev'
if not update_payload_staged_url:
raise error.TestError('Missing update payload url')
+ self._critical_update = critical_update
self._max_updates = max_updates
self._omaha_host = omaha_host
self._devserver_pid = 0
@@ -221,9 +224,12 @@
'--urlbase=%s' % update_payload_url_base,
'--max_updates=%s' % self._max_updates,
'--host_log',
- '--static_dir=%s' % self._devserver_static_dir,
- '--critical_update',
+ '--static_dir=%s' % self._devserver_static_dir
]
+
+ if self._critical_update:
+ cmdlist.append('--critical_update')
+
remote_cmd = '( %s ) </dev/null >%s 2>&1 &' % (
' '.join(cmdlist), self._devserver_stdoutfile)
diff --git a/server/cros/update_engine/update_engine_test.py b/server/cros/update_engine/update_engine_test.py
index f94cba7..9d5c267 100644
--- a/server/cros/update_engine/update_engine_test.py
+++ b/server/cros/update_engine/update_engine_test.py
@@ -538,7 +538,7 @@
# We need to start our own devserver for the rest of the cases.
self._omaha_devserver = omaha_devserver.OmahaDevserver(
self._autotest_devserver.hostname, staged_url,
- max_updates=max_updates)
+ max_updates=max_updates, critical_update=critical_update)
self._omaha_devserver.start_devserver()
return self._omaha_devserver.get_update_url()
diff --git a/server/site_tests/autoupdate_NonBlockingOOBEUpdate/autoupdate_NonBlockingOOBEUpdate.py b/server/site_tests/autoupdate_NonBlockingOOBEUpdate/autoupdate_NonBlockingOOBEUpdate.py
new file mode 100644
index 0000000..1595a84
--- /dev/null
+++ b/server/site_tests/autoupdate_NonBlockingOOBEUpdate/autoupdate_NonBlockingOOBEUpdate.py
@@ -0,0 +1,60 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+import logging
+
+from autotest_lib.client.common_lib import error
+from autotest_lib.server import autotest
+from autotest_lib.server.cros.update_engine import update_engine_test
+
+class autoupdate_NonBlockingOOBEUpdate(update_engine_test.UpdateEngineTest):
+ """Try a non-forced autoupdate during OOBE."""
+ version = 1
+
+ # We override the default lsb-release file.
+ _CUSTOM_LSB_RELEASE = '/mnt/stateful_partition/etc/lsb-release'
+
+
+ def cleanup(self):
+ self._host.run('rm %s' % self._CUSTOM_LSB_RELEASE, ignore_status=True)
+ self._host.get_file('/var/log/update_engine.log', self.resultsdir)
+ super(autoupdate_NonBlockingOOBEUpdate, self).cleanup()
+
+
+ def run_once(self, host, full_payload=True, job_repo_url=None):
+ """
+ Trys an autoupdate during ChromeOS OOBE without a deadline.
+
+ @param host: The DUT that we are running on.
+ @param full_payload: True for a full payload. False for delta.
+ @param job_repo_url: Used for debugging locally. This is used to figure
+ out the current build and the devserver to use.
+ The test will read this from a host argument
+ when run in the lab.
+
+ """
+ self._host = host
+
+ # veyron_rialto is a medical device with a different OOBE that auto
+ # completes so this test is not valid on that device.
+ if 'veyron_rialto' in self._host.get_board():
+ raise error.TestNAError('Rialto has a custom OOBE. Skipping test.')
+
+ update_url = self.get_update_url_for_test(job_repo_url,
+ full_payload=full_payload,
+ critical_update=False)
+ logging.info('Update url: %s', update_url)
+
+ # Call client test to start the OOBE update.
+ client_at = autotest.Autotest(self._host)
+ client_at.run_test('autoupdate_StartOOBEUpdate', image_url=update_url,
+ full_payload=full_payload, critical_update=False)
+
+ # Ensure that the update failed as expected.
+ err_msg = 'finished OmahaRequestAction with code ' \
+ 'ErrorCode::kNonCriticalUpdateInOOBE'
+ output = self._host.run('cat /var/log/update_engine.log | grep "%s"'
+ % err_msg, ignore_status=True).exit_status
+ if output != 0:
+ raise error.TestFail('Update did not fail with '
+ 'kNonCriticalUpdateInOOBE')
\ No newline at end of file
diff --git a/server/site_tests/autoupdate_NonBlockingOOBEUpdate/control.delta b/server/site_tests/autoupdate_NonBlockingOOBEUpdate/control.delta
new file mode 100644
index 0000000..14aaa60
--- /dev/null
+++ b/server/site_tests/autoupdate_NonBlockingOOBEUpdate/control.delta
@@ -0,0 +1,31 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = "dhaddock, Chromium OS"
+NAME = "autoupdate_NonBlockingOOBEUpdate.delta"
+PURPOSE = "Test non-forced update at OOBE."
+TIME = "MEDIUM"
+TEST_CATEGORY = "Functional"
+TEST_CLASS = "platform"
+TEST_TYPE = "server"
+ATTRIBUTES = "suite:bvt-perbuild"
+DOC = """
+This tests an update is available at OOBE but there is no deadline set.
+
+Kick it off locally using this command:
+
+test_that <hostname>.cros autoupdate_NonBlockingOOBEUpdate.delta --args="job_repo_url='http://<IP>:<port>/static/<board>-release/RXX-XXXX.X.X/autotest/packages'"
+
+"""
+
+from autotest_lib.client.common_lib import utils
+
+args_dict = utils.args_to_dict(args)
+
+def run(machine):
+ host = hosts.create_host(machine)
+ job.run_test('autoupdate_NonBlockingOOBEUpdate', host=host,
+ full_payload=False, **args_dict)
+
+job.parallel_simple(run, machines)
diff --git a/server/site_tests/autoupdate_P2P/autoupdate_P2P.py b/server/site_tests/autoupdate_P2P/autoupdate_P2P.py
index b4ac86f..c4bf838 100644
--- a/server/site_tests/autoupdate_P2P/autoupdate_P2P.py
+++ b/server/site_tests/autoupdate_P2P/autoupdate_P2P.py
@@ -18,6 +18,10 @@
version = 1
+ _P2P_ATTEMPTS_FILE = '/var/lib/update_engine/prefs/p2p-num-attempts'
+ _P2P_FIRST_ATTEMPT_FILE = '/var/lib/update_engine/prefs/p2p-first-attempt' \
+ '-timestamp'
+
def setup(self):
self._omaha_devserver = None
@@ -44,8 +48,17 @@
except Exception:
raise error.TestFail('Failed to enable p2p on %s' % host)
- host.run('rm /var/lib/update_engine/prefs/p2p-num-attempts',
- ignore_status=True)
+ if self._too_many_attempts:
+ host.run('echo 11 > %s' % self._P2P_ATTEMPTS_FILE)
+ else:
+ host.run('rm %s' % self._P2P_ATTEMPTS_FILE, ignore_status=True)
+
+ if self._deadline_expired:
+ host.run('echo 1 > %s' % self._P2P_FIRST_ATTEMPT_FILE)
+ else:
+ host.run('rm %s' % self._P2P_FIRST_ATTEMPT_FILE,
+ ignore_status=True)
+
host.reboot()
@@ -149,10 +162,20 @@
"since p2p is enabled." % self._hosts[0].ip
errline = "Forcibly disabling use of p2p for downloading because no " \
"suitable peer could be found."
+ too_many_attempts_err_str = "Forcibly disabling use of p2p for " \
+ "downloading because of previous " \
+ "failures when using p2p."
if re.compile(errline).search(update_engine_log) is not None:
raise error.TestFail('P2P update was disabled because no suitable '
'peer DUT was found.')
+ if self._too_many_attempts or self._deadline_expired:
+ ue = re.compile(too_many_attempts_err_str)
+ if ue.search(update_engine_log) is None:
+ raise error.TestFail('We expected update_engine to complain '
+ 'that there were too many p2p attempts '
+ 'but it did not. Check the logs.')
+ return
for line in [line1, line2, line3]:
ue = re.compile(line)
if ue.search(update_engine_log) is None:
@@ -207,10 +230,13 @@
build2))
- def run_once(self, hosts, job_repo_url=None):
+ def run_once(self, hosts, job_repo_url=None, too_many_attempts=False,
+ deadline_expired=False):
self._hosts = hosts
logging.info('Hosts for this test: %s', self._hosts)
+ self._too_many_attempts = too_many_attempts
+ self._deadline_expired = deadline_expired
self._verify_hosts(job_repo_url)
self._enable_p2p_update_on_hosts()
diff --git a/server/site_tests/autoupdate_P2P/control.deadline_expired.delta b/server/site_tests/autoupdate_P2P/control.deadline_expired.delta
new file mode 100644
index 0000000..87c37dc
--- /dev/null
+++ b/server/site_tests/autoupdate_P2P/control.deadline_expired.delta
@@ -0,0 +1,33 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = "dhaddock, Chromium OS"
+NAME = "autoupdate_P2P.deadline_expired.delta"
+PURPOSE = "Test autoupdate via peer to peer(P2P)."
+TIME = "MEDIUM"
+TEST_CATEGORY = "Functional"
+TEST_CLASS = "platform"
+TEST_TYPE = "server"
+ATTRIBUTES = "suite:bvt-perbuild"
+SYNC_COUNT = 2
+DOC = """
+This tests autoupdate between two devices via peer to peer is disabled when
+deadline has expired.
+
+"""
+
+from autotest_lib.server import utils as server_utils
+
+def run(ntuple):
+ host_list = []
+ for machine in ntuple:
+ host_list.append(hosts.create_host(machine))
+ job.run_test('autoupdate_P2P', hosts=host_list, deadline_expired=True)
+
+ntuples, failures = server_utils.form_ntuples_from_machines(machines,
+ SYNC_COUNT)
+
+# Use log=False in parallel_simple to avoid an exception in setting up
+# the incremental parser when SYNC_COUNT > 1.
+job.parallel_simple(run, ntuples, log=False)
diff --git a/server/site_tests/autoupdate_P2P/control.delta b/server/site_tests/autoupdate_P2P/control.delta
index 102b871..04edb20 100644
--- a/server/site_tests/autoupdate_P2P/control.delta
+++ b/server/site_tests/autoupdate_P2P/control.delta
@@ -1,3 +1,7 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
AUTHOR = "dhaddock, Chromium OS"
NAME = "autoupdate_P2P.delta"
PURPOSE = "Test autoupdate via peer to peer(P2P)."
@@ -25,8 +29,8 @@
host_list.append(hosts.create_host(machine))
job.run_test('autoupdate_P2P', hosts=host_list)
-ntuples, failures = server_utils.form_ntuples_from_machines(
- machines, SYNC_COUNT)
+ntuples, failures = server_utils.form_ntuples_from_machines(machines,
+ SYNC_COUNT)
# Use log=False in parallel_simple to avoid an exception in setting up
# the incremental parser when SYNC_COUNT > 1.
diff --git a/server/site_tests/autoupdate_P2P/control.local b/server/site_tests/autoupdate_P2P/control.local
index bf3871f..8d14d21 100644
--- a/server/site_tests/autoupdate_P2P/control.local
+++ b/server/site_tests/autoupdate_P2P/control.local
@@ -1,3 +1,7 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
AUTHOR = "dhaddock, Chromium OS"
NAME = "autoupdate_P2P.local"
PURPOSE = "Test autoupdate via peer to peer(P2P) locally."
diff --git a/server/site_tests/autoupdate_P2P/control.too_many_attempts.delta b/server/site_tests/autoupdate_P2P/control.too_many_attempts.delta
new file mode 100644
index 0000000..4454ed1
--- /dev/null
+++ b/server/site_tests/autoupdate_P2P/control.too_many_attempts.delta
@@ -0,0 +1,33 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = "dhaddock, Chromium OS"
+NAME = "autoupdate_P2P.too_many_attempts.delta"
+PURPOSE = "Test autoupdate via peer to peer(P2P)."
+TIME = "MEDIUM"
+TEST_CATEGORY = "Functional"
+TEST_CLASS = "platform"
+TEST_TYPE = "server"
+ATTRIBUTES = "suite:bvt-perbuild"
+SYNC_COUNT = 2
+DOC = """
+This tests autoupdate between two devices via peer to peer is disabled when
+they have tried more than 10 times.
+
+"""
+
+from autotest_lib.server import utils as server_utils
+
+def run(ntuple):
+ host_list = []
+ for machine in ntuple:
+ host_list.append(hosts.create_host(machine))
+ job.run_test('autoupdate_P2P', hosts=host_list, too_many_attempts=True)
+
+ntuples, failures = server_utils.form_ntuples_from_machines(machines,
+ SYNC_COUNT)
+
+# Use log=False in parallel_simple to avoid an exception in setting up
+# the incremental parser when SYNC_COUNT > 1.
+job.parallel_simple(run, ntuples, log=False)
diff --git a/server/site_tests/cheets_GTS/cheets_GTS.py b/server/site_tests/cheets_GTS/cheets_GTS.py
index faaa71c..60f2f92 100644
--- a/server/site_tests/cheets_GTS/cheets_GTS.py
+++ b/server/site_tests/cheets_GTS/cheets_GTS.py
@@ -18,7 +18,7 @@
from autotest_lib.server import utils
from autotest_lib.server.cros import tradefed_test
-_PARTNER_GTS_LOCATION = 'gs://chromeos-partner-gts/gts-5.1_r2-4507047.zip'
+_PARTNER_GTS_LOCATION = 'gs://chromeos-partner-gts/gts-5.1_r3-4604229.zip'
class cheets_GTS(tradefed_test.TradefedTest):
diff --git a/server/site_tests/cheets_GTS/control.GtsAccountsHostTestCases b/server/site_tests/cheets_GTS/control.GtsAccountsHostTestCases
index e876c9d..338ee0c 100644
--- a/server/site_tests/cheets_GTS/control.GtsAccountsHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsAccountsHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsAccountsHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsAdminTestCases b/server/site_tests/cheets_GTS/control.GtsAdminTestCases
index 5362434..2f83b47 100644
--- a/server/site_tests/cheets_GTS/control.GtsAdminTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsAdminTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsAdminTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsAfwTestCases b/server/site_tests/cheets_GTS/control.GtsAfwTestCases
index 062a96d..3c8a306 100644
--- a/server/site_tests/cheets_GTS/control.GtsAfwTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsAfwTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsAfwTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsAppBlacklistDeviceTestCases b/server/site_tests/cheets_GTS/control.GtsAppBlacklistDeviceTestCases
index d169ef4..3f7e6ad 100644
--- a/server/site_tests/cheets_GTS/control.GtsAppBlacklistDeviceTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsAppBlacklistDeviceTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsAppBlacklistDeviceTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsArTestCases b/server/site_tests/cheets_GTS/control.GtsArTestCases
index ad0c563..51f6ca6 100644
--- a/server/site_tests/cheets_GTS/control.GtsArTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsArTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsArTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsBackupHostTestCases b/server/site_tests/cheets_GTS/control.GtsBackupHostTestCases
index fc186c9..1e3d518 100644
--- a/server/site_tests/cheets_GTS/control.GtsBackupHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsBackupHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsBackupHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsBackupTestCases b/server/site_tests/cheets_GTS/control.GtsBackupTestCases
index bf1eeb5..598b5d0 100644
--- a/server/site_tests/cheets_GTS/control.GtsBackupTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsBackupTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsBackupTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsCallLogTestCases b/server/site_tests/cheets_GTS/control.GtsCallLogTestCases
index 7c4d936..3c76306 100644
--- a/server/site_tests/cheets_GTS/control.GtsCallLogTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsCallLogTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsCallLogTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsCastHostTestCases b/server/site_tests/cheets_GTS/control.GtsCastHostTestCases
index 3ded6ca..379c00e 100644
--- a/server/site_tests/cheets_GTS/control.GtsCastHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsCastHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsCastHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsDexModuleRegistrationTestCases b/server/site_tests/cheets_GTS/control.GtsDexModuleRegistrationTestCases
index aea13af..bf8e4d9 100644
--- a/server/site_tests/cheets_GTS/control.GtsDexModuleRegistrationTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsDexModuleRegistrationTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsDexModuleRegistrationTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsDozeDeviceTestCases b/server/site_tests/cheets_GTS/control.GtsDozeDeviceTestCases
index 2aca040..c760cd4 100644
--- a/server/site_tests/cheets_GTS/control.GtsDozeDeviceTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsDozeDeviceTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsDozeDeviceTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsEdiHostTestCases b/server/site_tests/cheets_GTS/control.GtsEdiHostTestCases
index 60db6ec..9b5ccc6 100644
--- a/server/site_tests/cheets_GTS/control.GtsEdiHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsEdiHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsEdiHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsExoPlayerTestCases b/server/site_tests/cheets_GTS/control.GtsExoPlayerTestCases
index 3b366c3..0c1a2f7 100644
--- a/server/site_tests/cheets_GTS/control.GtsExoPlayerTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsExoPlayerTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsExoPlayerTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsExternalSourcesNegativeTestCases b/server/site_tests/cheets_GTS/control.GtsExternalSourcesNegativeTestCases
index c3d0150..37e8e64 100644
--- a/server/site_tests/cheets_GTS/control.GtsExternalSourcesNegativeTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsExternalSourcesNegativeTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsExternalSourcesNegativeTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsExternalSourcesTestCases b/server/site_tests/cheets_GTS/control.GtsExternalSourcesTestCases
index f4b326b..05146f9 100644
--- a/server/site_tests/cheets_GTS/control.GtsExternalSourcesTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsExternalSourcesTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsExternalSourcesTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsFeaturesTestCases b/server/site_tests/cheets_GTS/control.GtsFeaturesTestCases
index 916589c..8988e14 100644
--- a/server/site_tests/cheets_GTS/control.GtsFeaturesTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsFeaturesTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsFeaturesTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsGmscoreHostTestCases b/server/site_tests/cheets_GTS/control.GtsGmscoreHostTestCases
index 4009310..711a318 100644
--- a/server/site_tests/cheets_GTS/control.GtsGmscoreHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsGmscoreHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsGmscoreHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsHomeHostTestCases b/server/site_tests/cheets_GTS/control.GtsHomeHostTestCases
index b83b0d1..5c7a333 100644
--- a/server/site_tests/cheets_GTS/control.GtsHomeHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsHomeHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsHomeHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsInstallPackagesWhitelistDeviceTestCases b/server/site_tests/cheets_GTS/control.GtsInstallPackagesWhitelistDeviceTestCases
index 0d21aea..b3eec85 100644
--- a/server/site_tests/cheets_GTS/control.GtsInstallPackagesWhitelistDeviceTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsInstallPackagesWhitelistDeviceTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsInstallPackagesWhitelistDeviceTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsInstantAppsHostTestCases b/server/site_tests/cheets_GTS/control.GtsInstantAppsHostTestCases
index 4203699..dcd1795 100644
--- a/server/site_tests/cheets_GTS/control.GtsInstantAppsHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsInstantAppsHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsInstantAppsHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsLargeApkHostTestCases b/server/site_tests/cheets_GTS/control.GtsLargeApkHostTestCases
index 528dc77..38d56ea 100644
--- a/server/site_tests/cheets_GTS/control.GtsLargeApkHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsLargeApkHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsLargeApkHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsLauncherHostTestCases b/server/site_tests/cheets_GTS/control.GtsLauncherHostTestCases
index e169dc3..1a4741c 100644
--- a/server/site_tests/cheets_GTS/control.GtsLauncherHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsLauncherHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsLauncherHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsLocationHostTestCases b/server/site_tests/cheets_GTS/control.GtsLocationHostTestCases
index dc7fb97..d8fae2a 100644
--- a/server/site_tests/cheets_GTS/control.GtsLocationHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsLocationHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsLocationHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsLocationTestCases b/server/site_tests/cheets_GTS/control.GtsLocationTestCases
index bcf8794..afcd5e1 100644
--- a/server/site_tests/cheets_GTS/control.GtsLocationTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsLocationTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsLocationTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsMediaTestCases b/server/site_tests/cheets_GTS/control.GtsMediaTestCases
index b642b49..98fbc3e 100644
--- a/server/site_tests/cheets_GTS/control.GtsMediaTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsMediaTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsMediaTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsMemoryHostTestCases b/server/site_tests/cheets_GTS/control.GtsMemoryHostTestCases
index 9400895..dded755 100644
--- a/server/site_tests/cheets_GTS/control.GtsMemoryHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsMemoryHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsMemoryHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsMemoryTestCases b/server/site_tests/cheets_GTS/control.GtsMemoryTestCases
index f7b8d40..a45fbda 100644
--- a/server/site_tests/cheets_GTS/control.GtsMemoryTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsMemoryTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsMemoryTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsNetTestCases b/server/site_tests/cheets_GTS/control.GtsNetTestCases
index b5d0b69..044eeb8 100644
--- a/server/site_tests/cheets_GTS/control.GtsNetTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsNetTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsNetTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsNmgiarcTestCases b/server/site_tests/cheets_GTS/control.GtsNmgiarcTestCases
index 45e6aed..07b59a9 100644
--- a/server/site_tests/cheets_GTS/control.GtsNmgiarcTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsNmgiarcTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsNmgiarcTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsNotificationTvExtenderTestCases b/server/site_tests/cheets_GTS/control.GtsNotificationTvExtenderTestCases
index df9e9b8..13c8965 100644
--- a/server/site_tests/cheets_GTS/control.GtsNotificationTvExtenderTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsNotificationTvExtenderTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsNotificationTvExtenderTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsOemLockServiceTestCases b/server/site_tests/cheets_GTS/control.GtsOemLockServiceTestCases
index 6334e49..9e7ae51 100644
--- a/server/site_tests/cheets_GTS/control.GtsOemLockServiceTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsOemLockServiceTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsOemLockServiceTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsOsTestCases b/server/site_tests/cheets_GTS/control.GtsOsTestCases
index 7d70d00..826d26b 100644
--- a/server/site_tests/cheets_GTS/control.GtsOsTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsOsTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsOsTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsPackageInstallSessionTestCases b/server/site_tests/cheets_GTS/control.GtsPackageInstallSessionTestCases
index 1725a7e..06bac0e 100644
--- a/server/site_tests/cheets_GTS/control.GtsPackageInstallSessionTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsPackageInstallSessionTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsPackageInstallSessionTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsPackageInstallerTapjackingTestCases b/server/site_tests/cheets_GTS/control.GtsPackageInstallerTapjackingTestCases
index a8db59a..f409e20 100644
--- a/server/site_tests/cheets_GTS/control.GtsPackageInstallerTapjackingTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsPackageInstallerTapjackingTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsPackageInstallerTapjackingTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsPackageManagerHostTestCases b/server/site_tests/cheets_GTS/control.GtsPackageManagerHostTestCases
index 16a627e..de804a2 100644
--- a/server/site_tests/cheets_GTS/control.GtsPackageManagerHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsPackageManagerHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsPackageManagerHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsPackageNameCertPairsDeviceTestCases b/server/site_tests/cheets_GTS/control.GtsPackageNameCertPairsDeviceTestCases
index 42bb996..21bd19e 100644
--- a/server/site_tests/cheets_GTS/control.GtsPackageNameCertPairsDeviceTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsPackageNameCertPairsDeviceTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsPackageNameCertPairsDeviceTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsPartnerBookmarksTestCases b/server/site_tests/cheets_GTS/control.GtsPartnerBookmarksTestCases
index e6a11805..b5df988 100644
--- a/server/site_tests/cheets_GTS/control.GtsPartnerBookmarksTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsPartnerBookmarksTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsPartnerBookmarksTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsPermissionTestCases b/server/site_tests/cheets_GTS/control.GtsPermissionTestCases
index af035ce..0913540 100644
--- a/server/site_tests/cheets_GTS/control.GtsPermissionTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsPermissionTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsPermissionTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsPlacementTestCases b/server/site_tests/cheets_GTS/control.GtsPlacementTestCases
index ff6d88c..71e66b8 100644
--- a/server/site_tests/cheets_GTS/control.GtsPlacementTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsPlacementTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsPlacementTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsPlayAutoInstallTestCases b/server/site_tests/cheets_GTS/control.GtsPlayAutoInstallTestCases
index bcd9d7a..8003a05 100644
--- a/server/site_tests/cheets_GTS/control.GtsPlayAutoInstallTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsPlayAutoInstallTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsPlayAutoInstallTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsPlayStoreHostTestCases b/server/site_tests/cheets_GTS/control.GtsPlayStoreHostTestCases
index 4a275c9..3073f9a 100644
--- a/server/site_tests/cheets_GTS/control.GtsPlayStoreHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsPlayStoreHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsPlayStoreHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsPrintTestCases b/server/site_tests/cheets_GTS/control.GtsPrintTestCases
index 5062161..8889e51 100644
--- a/server/site_tests/cheets_GTS/control.GtsPrintTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsPrintTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsPrintTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsPrivacyTestCases b/server/site_tests/cheets_GTS/control.GtsPrivacyTestCases
index 6f8d1e2..eb15a64 100644
--- a/server/site_tests/cheets_GTS/control.GtsPrivacyTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsPrivacyTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsPrivacyTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsPropertiesTestCases b/server/site_tests/cheets_GTS/control.GtsPropertiesTestCases
new file mode 100644
index 0000000..d6db0cf
--- /dev/null
+++ b/server/site_tests/cheets_GTS/control.GtsPropertiesTestCases
@@ -0,0 +1,29 @@
+# Copyright 2016 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# This file has been automatically generated. Do not edit!
+
+AUTHOR = 'ARC++ Team'
+NAME = 'cheets_GTS.GtsPropertiesTestCases'
+ATTRIBUTES = 'suite:gts'
+DEPENDENCIES = 'arc'
+JOB_RETRIES = 2
+TEST_TYPE = 'server'
+TIME = 'LENGTHY'
+
+DOC = ('Run package GtsPropertiesTestCases of the '
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
+
+def run_GTS(machine):
+ host = hosts.create_host(machine)
+ job.run_test(
+ 'cheets_GTS',
+ host=host,
+ iterations=1,
+ tag='GtsPropertiesTestCases',
+ target_package='GtsPropertiesTestCases',
+
+ timeout=3600)
+
+parallel_simple(run_GTS, machines)
\ No newline at end of file
diff --git a/server/site_tests/cheets_GTS/control.GtsRlzTestCases b/server/site_tests/cheets_GTS/control.GtsRlzTestCases
index 0dbb923..8fce145 100644
--- a/server/site_tests/cheets_GTS/control.GtsRlzTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsRlzTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsRlzTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsSampleDeviceTestCases b/server/site_tests/cheets_GTS/control.GtsSampleDeviceTestCases
index ef87ad4..987aa80 100644
--- a/server/site_tests/cheets_GTS/control.GtsSampleDeviceTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsSampleDeviceTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsSampleDeviceTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsSampleDynamicConfigTestCases b/server/site_tests/cheets_GTS/control.GtsSampleDynamicConfigTestCases
index ecdcc1b..c16379f 100644
--- a/server/site_tests/cheets_GTS/control.GtsSampleDynamicConfigTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsSampleDynamicConfigTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsSampleDynamicConfigTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsSampleHostTestCases b/server/site_tests/cheets_GTS/control.GtsSampleHostTestCases
index c135442..e395ac7 100644
--- a/server/site_tests/cheets_GTS/control.GtsSampleHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsSampleHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsSampleHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsScreenshotHostTestCases b/server/site_tests/cheets_GTS/control.GtsScreenshotHostTestCases
index 9f6f610..6265813 100644
--- a/server/site_tests/cheets_GTS/control.GtsScreenshotHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsScreenshotHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsScreenshotHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsSearchHostTestCases b/server/site_tests/cheets_GTS/control.GtsSearchHostTestCases
index a69f544..07e162e 100644
--- a/server/site_tests/cheets_GTS/control.GtsSearchHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsSearchHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsSearchHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsSecurityHostTestCases b/server/site_tests/cheets_GTS/control.GtsSecurityHostTestCases
index f2466d8..36221a3 100644
--- a/server/site_tests/cheets_GTS/control.GtsSecurityHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsSecurityHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsSecurityHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsSensorHostTestCases b/server/site_tests/cheets_GTS/control.GtsSensorHostTestCases
index 42ea835..8a8230a 100644
--- a/server/site_tests/cheets_GTS/control.GtsSensorHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsSensorHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsSensorHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsSetupWizardHostTestCases b/server/site_tests/cheets_GTS/control.GtsSetupWizardHostTestCases
index e5bcdc9..42532cd 100644
--- a/server/site_tests/cheets_GTS/control.GtsSetupWizardHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsSetupWizardHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsSetupWizardHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsSsaidHostTestCases b/server/site_tests/cheets_GTS/control.GtsSsaidHostTestCases
index 8eba262..d47e476 100644
--- a/server/site_tests/cheets_GTS/control.GtsSsaidHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsSsaidHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsSsaidHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsStorageTestCases b/server/site_tests/cheets_GTS/control.GtsStorageTestCases
index 6fe6fe7..bb73924 100644
--- a/server/site_tests/cheets_GTS/control.GtsStorageTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsStorageTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsStorageTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsTelecomManagerTests b/server/site_tests/cheets_GTS/control.GtsTelecomManagerTests
index 2dcf7a3..d6b08ca 100644
--- a/server/site_tests/cheets_GTS/control.GtsTelecomManagerTests
+++ b/server/site_tests/cheets_GTS/control.GtsTelecomManagerTests
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsTelecomManagerTests of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsTetheringTestCases b/server/site_tests/cheets_GTS/control.GtsTetheringTestCases
index 4cc9680..f62318d 100644
--- a/server/site_tests/cheets_GTS/control.GtsTetheringTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsTetheringTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsTetheringTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsTvBugReportTestCases b/server/site_tests/cheets_GTS/control.GtsTvBugReportTestCases
index 554e005..8eb4fdc 100644
--- a/server/site_tests/cheets_GTS/control.GtsTvBugReportTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsTvBugReportTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsTvBugReportTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsTvHostTestCases b/server/site_tests/cheets_GTS/control.GtsTvHostTestCases
index 4c5f1e1..d78f365 100644
--- a/server/site_tests/cheets_GTS/control.GtsTvHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsTvHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsTvHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsWebViewHostTestCases b/server/site_tests/cheets_GTS/control.GtsWebViewHostTestCases
index 750023d..30b5c40 100644
--- a/server/site_tests/cheets_GTS/control.GtsWebViewHostTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsWebViewHostTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsWebViewHostTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsWebViewTestCases b/server/site_tests/cheets_GTS/control.GtsWebViewTestCases
index 662a205..9763689 100644
--- a/server/site_tests/cheets_GTS/control.GtsWebViewTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsWebViewTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsWebViewTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.GtsYouTubeTestCases b/server/site_tests/cheets_GTS/control.GtsYouTubeTestCases
index f17b17a..bcfd713 100644
--- a/server/site_tests/cheets_GTS/control.GtsYouTubeTestCases
+++ b/server/site_tests/cheets_GTS/control.GtsYouTubeTestCases
@@ -13,8 +13,7 @@
TIME = 'LENGTHY'
DOC = ('Run package GtsYouTubeTestCases of the '
- 'Android 5.1_r2 Google Test Suite (GTS), build 4507047,'
- 'in the ARC++ container.')
+ 'Android Google Test Suite (GTS) in the ARC++ container.')
def run_GTS(machine):
host = hosts.create_host(machine)
diff --git a/server/site_tests/cheets_GTS/control.tradefed-run-collect-tests-only b/server/site_tests/cheets_GTS/control.tradefed-run-collect-tests-only
index 4c92e8e..8db9586 100644
--- a/server/site_tests/cheets_GTS/control.tradefed-run-collect-tests-only
+++ b/server/site_tests/cheets_GTS/control.tradefed-run-collect-tests-only
@@ -10,7 +10,7 @@
JOB_RETRIES = 2
TEST_TYPE = 'server'
TIME = 'LENGTHY'
-
+PRIORITY = 70
DOC = ('Run tradefed to collect all of the available GTS tests for this device.')
def run_GTS(machine):
diff --git a/server/site_tests/firmware_CorruptBothFwBodyAB/firmware_CorruptBothFwBodyAB.py b/server/site_tests/firmware_CorruptBothFwBodyAB/firmware_CorruptBothFwBodyAB.py
index 3d7cf43..f068ccc 100644
--- a/server/site_tests/firmware_CorruptBothFwBodyAB/firmware_CorruptBothFwBodyAB.py
+++ b/server/site_tests/firmware_CorruptBothFwBodyAB/firmware_CorruptBothFwBodyAB.py
@@ -65,9 +65,13 @@
'mainfw_type': 'developer' if dev_mode else 'normal',
}))
self.faft_client.bios.corrupt_body(('a', 'b'))
+
+ # Older devices (without BROKEN screen) didn't wait for removal in
+ # dev mode. Make sure the USB key is not plugged in so they won't
+ # start booting immediately and get interrupted by unplug/replug.
+ self.servo.switch_usbkey('host')
self.switcher.simple_reboot()
- if not dev_mode:
- self.switcher.bypass_rec_mode()
+ self.switcher.bypass_rec_mode()
self.switcher.wait_for_client()
logging.info("Expected recovery boot and restore firmware.")
diff --git a/server/site_tests/firmware_CorruptBothFwSigAB/firmware_CorruptBothFwSigAB.py b/server/site_tests/firmware_CorruptBothFwSigAB/firmware_CorruptBothFwSigAB.py
index b8cc581..c5a8bb5 100644
--- a/server/site_tests/firmware_CorruptBothFwSigAB/firmware_CorruptBothFwSigAB.py
+++ b/server/site_tests/firmware_CorruptBothFwSigAB/firmware_CorruptBothFwSigAB.py
@@ -39,9 +39,13 @@
'mainfw_type': 'developer' if dev_mode else 'normal',
}))
self.faft_client.bios.corrupt_sig(('a', 'b'),)
+
+ # Older devices (without BROKEN screen) didn't wait for removal in
+ # dev mode. Make sure the USB key is not plugged in so they won't
+ # start booting immediately and get interrupted by unplug/replug.
+ self.servo.switch_usbkey('host')
self.switcher.simple_reboot()
- if not dev_mode:
- self.switcher.bypass_rec_mode()
+ self.switcher.bypass_rec_mode()
self.switcher.wait_for_client()
logging.info("Expected recovery boot and set fwb_tries flag.")
@@ -52,9 +56,10 @@
vboot.RECOVERY_REASON['RW_VERIFY_KEYBLOCK']),
}))
self.faft_client.system.set_try_fw_b()
- self.switcher.simple_reboot()
- if not dev_mode:
- self.switcher.bypass_rec_mode()
+
+ self.servo.switch_usbkey('host')
+ self.switcher.simple_reboot(sync_before_boot=False)
+ self.switcher.bypass_rec_mode()
self.switcher.wait_for_client()
logging.info("Still expected recovery boot and restore firmware.")
diff --git a/server/site_tests/firmware_CorruptBothKernelAB/firmware_CorruptBothKernelAB.py b/server/site_tests/firmware_CorruptBothKernelAB/firmware_CorruptBothKernelAB.py
index 3f223cb..b9b3f44 100644
--- a/server/site_tests/firmware_CorruptBothKernelAB/firmware_CorruptBothKernelAB.py
+++ b/server/site_tests/firmware_CorruptBothKernelAB/firmware_CorruptBothKernelAB.py
@@ -64,9 +64,13 @@
logging.info("Corrupt kernel A and B.")
self.check_state((self.check_root_part_on_non_recovery, 'a'))
self.faft_client.kernel.corrupt_sig(('a', 'b'))
+
+ # Older devices (without BROKEN screen) didn't wait for removal in
+ # dev mode. Make sure the USB key is not plugged in so they won't
+ # start booting immediately and get interrupted by unplug/replug.
+ self.servo.switch_usbkey('host')
self.switcher.mode_aware_reboot(wait_for_dut_up=False)
- if not dev_mode:
- self.switcher.bypass_rec_mode()
+ self.switcher.bypass_rec_mode()
self.switcher.wait_for_client()
logging.info("Expected recovery boot and restore the OS image.")
diff --git a/server/site_tests/firmware_CorruptRecoveryCache/firmware_CorruptRecoveryCache.py b/server/site_tests/firmware_CorruptRecoveryCache/firmware_CorruptRecoveryCache.py
index 146f1c3..2215875 100644
--- a/server/site_tests/firmware_CorruptRecoveryCache/firmware_CorruptRecoveryCache.py
+++ b/server/site_tests/firmware_CorruptRecoveryCache/firmware_CorruptRecoveryCache.py
@@ -106,8 +106,11 @@
if not self.cache_exist():
raise error.TestNAError('No RECOVERY_MRC_CACHE was found on DUT.')
- self.faft_client.bios.corrupt_body('rec')
+ self.faft_client.bios.corrupt_body('rec', True)
self.boot_to_recovery()
if not self.check_cache_rebuilt():
raise error.TestFail('Recovery Cache was not rebuilt.')
+
+ logging.info('Reboot out of Recovery')
+ self.switcher.simple_reboot()
diff --git a/server/site_tests/firmware_RollbackFirmware/firmware_RollbackFirmware.py b/server/site_tests/firmware_RollbackFirmware/firmware_RollbackFirmware.py
index 10059d3..693ba01 100644
--- a/server/site_tests/firmware_RollbackFirmware/firmware_RollbackFirmware.py
+++ b/server/site_tests/firmware_RollbackFirmware/firmware_RollbackFirmware.py
@@ -41,9 +41,13 @@
logging.info("Expected firmware B boot and rollback firmware B.")
self.check_state((self.checkers.fw_tries_checker, ('B', False)))
self.faft_client.bios.move_version_backward('b')
+
+ # Older devices (without BROKEN screen) didn't wait for removal in
+ # dev mode. Make sure the USB key is not plugged in so they won't
+ # start booting immediately and get interrupted by unplug/replug.
+ self.servo.switch_usbkey('host')
self.switcher.simple_reboot()
- if not dev_mode:
- self.switcher.bypass_rec_mode()
+ self.switcher.bypass_rec_mode()
self.switcher.wait_for_client()
logging.info("Expected recovery boot and restores firmware A and B.")
diff --git a/server/site_tests/platform_BootDevice/control b/server/site_tests/platform_BootDevice/control
index 1b91545..7270094 100644
--- a/server/site_tests/platform_BootDevice/control
+++ b/server/site_tests/platform_BootDevice/control
@@ -17,6 +17,6 @@
def run_bootdevice(machine):
host = hosts.create_host(machine)
- job.run_test("platform_BootDevice", host=host, iterations=10)
+ job.run_test("platform_BootDevice", host=host, reboot_iterations=10)
parallel_simple(run_bootdevice, machines)
diff --git a/server/site_tests/platform_BootDevice/control.100 b/server/site_tests/platform_BootDevice/control.100
index 53b84fb..5d47181 100644
--- a/server/site_tests/platform_BootDevice/control.100
+++ b/server/site_tests/platform_BootDevice/control.100
@@ -17,6 +17,6 @@
def run_bootdevice(machine):
host = hosts.create_host(machine)
- job.run_test("platform_BootDevice", host=host, iterations=100)
+ job.run_test("platform_BootDevice", host=host, reboot_iterations=100)
parallel_simple(run_bootdevice, machines)
diff --git a/server/site_tests/platform_BootDevice/control.stress2 b/server/site_tests/platform_BootDevice/control.stress2
index 8418590..0f0bdb2 100644
--- a/server/site_tests/platform_BootDevice/control.stress2
+++ b/server/site_tests/platform_BootDevice/control.stress2
@@ -17,6 +17,6 @@
def run_bootdevice(machine):
host = hosts.create_host(machine)
- job.run_test("platform_BootDevice", host=host, iterations=100)
+ job.run_test("platform_BootDevice", host=host, reboot_iterations=100)
parallel_simple(run_bootdevice, machines)
diff --git a/server/site_tests/platform_BootDevice/control.stress3 b/server/site_tests/platform_BootDevice/control.stress3
index 1ac4ea9..f236b76 100644
--- a/server/site_tests/platform_BootDevice/control.stress3
+++ b/server/site_tests/platform_BootDevice/control.stress3
@@ -17,6 +17,6 @@
def run_bootdevice(machine):
host = hosts.create_host(machine)
- job.run_test("platform_BootDevice", host=host, iterations=100)
+ job.run_test("platform_BootDevice", host=host, reboot_iterations=100)
parallel_simple(run_bootdevice, machines)
diff --git a/server/site_tests/platform_BootDevice/platform_BootDevice.py b/server/site_tests/platform_BootDevice/platform_BootDevice.py
index eefe56c..dab4557 100644
--- a/server/site_tests/platform_BootDevice/platform_BootDevice.py
+++ b/server/site_tests/platform_BootDevice/platform_BootDevice.py
@@ -3,14 +3,15 @@
# found in the LICENSE file.
import logging
-from autotest_lib.server import test, autotest
+from autotest_lib.server import test
class platform_BootDevice(test.test):
- version = 1
+ version = 1
- def run_once(self, host=None):
- self.client = host
-
- # Reboot the client
- logging.info('BootDevice: reboot %s' % self.client.hostname)
- self.client.reboot()
+ def run_once(self, reboot_iterations=1, host=None):
+ for i in xrange(reboot_iterations):
+ logging.info('======== Running BOOTDEVICE REBOOT ITERATION %d/%d '
+ '========', i+1, reboot_iterations)
+ # Reboot the client
+ logging.info('BootDevice: reboot %s', host.hostname)
+ host.reboot()
diff --git a/server/site_tests/telemetry_Benchmarks/control.cros_ui_smoothness b/server/site_tests/telemetry_Benchmarks/control.cros_ui_smoothness
new file mode 100644
index 0000000..d1a8386
--- /dev/null
+++ b/server/site_tests/telemetry_Benchmarks/control.cros_ui_smoothness
@@ -0,0 +1,32 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Do not edit this file! It was created by generate_controlfiles.py.
+
+from autotest_lib.client.common_lib import utils
+
+AUTHOR = 'sbasi, achuith, rohitbm'
+NAME = 'telemetry_Benchmarks.cros_ui_smoothness'
+ATTRIBUTES = 'suite:crosbolt_perf_nightly'
+TIME = 'LONG'
+TEST_CATEGORY = 'Benchmark'
+TEST_CLASS = 'performance'
+TEST_TYPE = 'server'
+
+DOC = '''
+This server side test suite executes the Telemetry Benchmark:
+cros_ui_smoothness
+This is part of Chrome for Chrome OS performance testing.
+
+Pass local=True to run with local telemetry and no AFE server.
+'''
+
+def run_benchmark(machine):
+ host = hosts.create_host(machine)
+ job.run_test('telemetry_Benchmarks', host=host,
+ benchmark='cros_ui_smoothness',
+ tag='cros_ui_smoothness',
+ args=utils.args_to_dict(args))
+
+parallel_simple(run_benchmark, machines)
\ No newline at end of file
diff --git a/server/site_tests/telemetry_Benchmarks/generate_controlfiles.py b/server/site_tests/telemetry_Benchmarks/generate_controlfiles.py
index c794569..caaa5b2 100644
--- a/server/site_tests/telemetry_Benchmarks/generate_controlfiles.py
+++ b/server/site_tests/telemetry_Benchmarks/generate_controlfiles.py
@@ -29,6 +29,7 @@
)
PERF_DAILY_RUN_TESTS = (
+ 'cros_ui_smoothness',
'dromaeo.domcoreattr',
'dromaeo.domcoremodify',
'dromaeo.domcorequery',
@@ -61,7 +62,7 @@
PERF_NO_SUITE)
CONTROLFILE_TEMPLATE = (
-"""# Copyright 2017 The Chromium OS Authors. All rights reserved.
+"""# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
diff --git a/site_utils/attribute_whitelist.txt b/site_utils/attribute_whitelist.txt
index 2a6b2f4..5505e8d 100644
--- a/site_utils/attribute_whitelist.txt
+++ b/site_utils/attribute_whitelist.txt
@@ -88,6 +88,8 @@
suite:dummy_server_nossp
suite:dummyclientretries
suite:dummyflake
+suite:ent-nightly
+suite:ent-perbuild
suite:experimental
suite:factory
suite:faft
diff --git a/site_utils/cloud_console_client.py b/site_utils/cloud_console_client.py
index c3141f8..343abef 100644
--- a/site_utils/cloud_console_client.py
+++ b/site_utils/cloud_console_client.py
@@ -173,7 +173,7 @@
msg_attributes[_get_attribute_name(cpcon.ATTR_MESSAGE_VERSION)] = (
CURRENT_MESSAGE_VERSION)
msg_attributes[_get_attribute_name(cpcon.ATTR_MOBLAB_MAC_ADDRESS)] = (
- utils.get_default_interface_mac_address())
+ utils.get_moblab_serial_number())
msg_attributes[_get_attribute_name(cpcon.ATTR_MOBLAB_ID)] = (
utils.get_moblab_id())
return msg_attributes
@@ -190,7 +190,7 @@
msg_attributes = {}
msg_attributes[LEGACY_ATTR_VERSION] = CURRENT_MESSAGE_VERSION
msg_attributes[LEGACY_ATTR_MOBLAB_MAC] = (
- utils.get_default_interface_mac_address())
+ utils.get_moblab_serial_number())
msg_attributes[LEGACY_ATTR_MOBLAB_ID] = utils.get_moblab_id()
msg_attributes[LEGACY_ATTR_GCS_URI] = gcs_uri
diff --git a/site_utils/cloud_console_client_unittest.py b/site_utils/cloud_console_client_unittest.py
index 8f67883..c9332f1 100644
--- a/site_utils/cloud_console_client_unittest.py
+++ b/site_utils/cloud_console_client_unittest.py
@@ -33,9 +33,9 @@
"""Tests the test result notification message."""
self._console_client = cloud_console_client.PubSubBasedClient()
self.mox.StubOutWithMock(utils,
- 'get_default_interface_mac_address')
- utils.get_default_interface_mac_address().AndReturn(
- '1c:dc:d1:11:01:e1')
+ 'get_moblab_serial_number')
+ utils.get_moblab_serial_number().AndReturn(
+ 'PV120BB8JAC01E')
self.mox.StubOutWithMock(utils, 'get_moblab_id')
utils.get_moblab_id().AndReturn(
'c8386d92-9ad1-11e6-80f5-111111111111')
diff --git a/site_utils/lxc/utils.py b/site_utils/lxc/utils.py
index a5ea5ec..155c2ab 100644
--- a/site_utils/lxc/utils.py
+++ b/site_utils/lxc/utils.py
@@ -142,16 +142,13 @@
"""
spec = (dst, (rename if rename else src).lstrip(os.path.sep))
full_dst = os.path.join(*list(spec))
- commands = []
if not path_exists(full_dst):
- commands.append('mkdir -p %s' % full_dst)
+ utils.run('sudo mkdir -p %s' % full_dst)
- commands.append('mount --bind %s %s' % (src, full_dst))
+ utils.run('sudo mount --bind %s %s' % (src, full_dst))
if readonly:
- commands.append('mount -o remount,ro,bind %s' % full_dst)
-
- sudo_commands(commands)
+ utils.run('sudo mount -o remount,ro,bind %s' % full_dst)
return cls(spec)
@@ -174,16 +171,17 @@
def cleanup(self):
"""Cleans up the bind-mount.
- Unmounts the destination, and deletes it.
+ Unmounts the destination, and deletes it if possible. If it was mounted
+ alongside important files, it will not be deleted.
"""
- # Ignore errors in rmdir because bind mount locations are sometimes
- # nested alongside actual file content (e.g. SSPs install into
+ full_dst = os.path.join(*list(self.spec))
+ utils.run('sudo umount %s' % full_dst)
+ # Ignore errors because bind mount locations are sometimes nested
+ # alongside actual file content (e.g. SSPs install into
# /usr/local/autotest so rmdir -p will fail for any mounts located in
# /usr/local/autotest).
- full_dst = os.path.join(*list(self.spec))
- commands = ["umount '%s'" % full_dst,
- "cd '%s'; rmdir -p '%s' || true" % (self.spec, self.spec)]
- sudo_commands(commands)
+ utils.run('sudo bash -c "cd %s; rmdir -p --ignore-fail-on-non-empty %s"'
+ % self.spec)
MountInfo = collections.namedtuple('MountInfo', ['root', 'mount_point', 'tags'])
@@ -237,18 +235,3 @@
# performs a prefix string comparison.
parent = os.path.join(parent, '')
return os.path.commonprefix([parent, subdir]) == parent
-
-
-def sudo_commands(commands):
- """Takes a list of bash commands and executes them all with one invocation
- of sudo. Saves ~400 ms per command.
-
- @param commands: The bash commands, as strings.
-
- @return The return code of the sudo call.
- """
- prefix = 'sudo bash -c \''
- suffix = '\''
- command = prefix + (' && '.join(commands)) + suffix
- return utils.run(command)
-
diff --git a/test_suites/control.ent-nightly b/test_suites/control.ent-nightly
new file mode 100644
index 0000000..38e9529
--- /dev/null
+++ b/test_suites/control.ent-nightly
@@ -0,0 +1,28 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = "Katherine Threlkeld <[email protected]>"
+NAME = "ent-nightly"
+PURPOSE = "Lower priority Enterprise related tests."
+TIME = "SHORT"
+TEST_CATEGORY = "Functional"
+TEST_CLASS = "suite"
+TEST_TYPE = "Server"
+
+DOC = """
+This suite runs Enterprise tests which should run on nightly, across
+a subset of boards.
+"""
+
+import common
+from autotest_lib.server.cros import provision
+from autotest_lib.server.cros.dynamic_suite import dynamic_suite
+
+args_dict['name'] = 'ent-nightly'
+args_dict['add_experimental'] = True
+args_dict['max_runtime_mins'] = 60
+args_dict['version_prefix'] = provision.CROS_VERSION_PREFIX
+args_dict['job'] = job
+
+dynamic_suite.reimage_and_run(**args_dict)
diff --git a/test_suites/control.ent-perbuild b/test_suites/control.ent-perbuild
new file mode 100644
index 0000000..7147738
--- /dev/null
+++ b/test_suites/control.ent-perbuild
@@ -0,0 +1,28 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = "Katherine Threlkeld <[email protected]>"
+NAME = "ent-perbuild"
+PURPOSE = "High priority Enterprise related tests."
+TIME = "SHORT"
+TEST_CATEGORY = "Functional"
+TEST_CLASS = "suite"
+TEST_TYPE = "Server"
+
+DOC = """
+This suite runs Enterprise tests which should run on every build, across
+a subset of boards.
+"""
+
+import common
+from autotest_lib.server.cros import provision
+from autotest_lib.server.cros.dynamic_suite import dynamic_suite
+
+args_dict['name'] = 'ent-perbuild'
+args_dict['add_experimental'] = True
+args_dict['max_runtime_mins'] = 60
+args_dict['version_prefix'] = provision.CROS_VERSION_PREFIX
+args_dict['job'] = job
+
+dynamic_suite.reimage_and_run(**args_dict)
diff --git a/tko/perf_upload/perf_dashboard_config.json b/tko/perf_upload/perf_dashboard_config.json
index 84bbe58..cc93835 100644
--- a/tko/perf_upload/perf_dashboard_config.json
+++ b/tko/perf_upload/perf_dashboard_config.json
@@ -546,6 +546,11 @@
"master_name": "ChromeOSPower"
},
{
+ "autotest_name": "telemetry_Benchmarks.cros_ui_smoothness",
+ "master_name": "ChromeOSPerf",
+ "dashboard_test_name": "cros_ui_smoothness"
+ },
+ {
"autotest_name": "telemetry_Benchmarks.dromaeo.domcoreattr",
"master_name": "ChromeOSPerf",
"dashboard_test_name": "dromaeo.domcoreattr"