blob: 18fef0a7261a3ac9b396e3f4b7dba761a4e9d260 [file] [log] [blame]
# 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 json
import logging
import time
from autotest_lib.client.bin import test
from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import chrome
from autotest_lib.client.cros import cryptohome
from autotest_lib.client.cros.input_playback import input_playback
class desktopui_CheckRlzPingSent(test.test):
"""Tests creating a new user, doing a google search, checking RLZ Data."""
version = 1
_RLZ_DATA_FILE = "/home/chronos/user/RLZ Data"
def _verify_rlz_data(self, expect_caf_ping=True, guest=False):
"""
Checks the RLZ data file for CAI and CAF ping events.
@param expect_caf_ping: True if expecting the CAF event to be in the
RLZ data file, False if not expecting it.
@param guest: True if checking in guest mode. The guest mode user
mount may not be in the root mount namespace, so the RLZ
data file path must be adjusted accordingly.
"""
rlz_data_cmd = []
if guest:
mounter_pid = utils.run(
['pgrep', '-f', '/usr/sbin/cryptohome-namespace-mount']).stdout
if mounter_pid is not None:
ns_path = '/proc/%s/ns/mnt' % mounter_pid.rstrip()
rlz_data_cmd.extend(['nsenter', '--mount=%s' % ns_path])
rlz_data_cmd.extend(['cat', self._RLZ_DATA_FILE])
def rlz_data_exists():
"""Check rlz data exists."""
rlz_data = json.loads(utils.run(rlz_data_cmd).stdout)
logging.debug('rlz data: %s', rlz_data)
if 'stateful_events' in rlz_data:
cai_present = 'CAI' in rlz_data['stateful_events']['C']['_']
caf_present = 'CAF' in rlz_data['stateful_events']['C']['_']
return cai_present and (caf_present == expect_caf_ping)
return False
utils.poll_for_condition(rlz_data_exists, timeout=120)
def _check_url_for_rlz(self, cr):
"""
Does a Google search and ensures there is an rlz parameter.
@param cr: Chrome instance.
"""
timeout_minutes = 2
timeout = time.time() + 60 * timeout_minutes
# Setup a keyboard emulator to open new tabs and type a search.
with input_playback.InputPlayback() as player:
player.emulate(input_type='keyboard')
player.find_connected_inputs()
while True:
# Open a new tab, search in the omnibox.
player.blocking_playback_of_default_file(
input_type='keyboard', filename='keyboard_ctrl+t')
player.blocking_playback_of_default_file(
input_type='keyboard', filename='keyboard_b+a+d+enter')
logging.info(cr.browser.tabs[-1].url)
if 'rlz=' in cr.browser.tabs[-1].url:
break
else:
if time.time() > timeout:
raise error.TestFail('RLZ ping did not send in %d '
'minutes.' % timeout_minutes)
time.sleep(10)
def _wait_for_rlz_lock(self):
"""Waits for the DUT to get into locked state after login."""
def get_install_lockbox_finalized_status():
status = cryptohome.get_install_attribute_status()
return status == 'VALID'
try:
utils.poll_for_condition(
lambda: get_install_lockbox_finalized_status(),
exception=utils.TimeoutError(),
timeout=120)
except utils.TimeoutError:
raise error.TestFail('Timed out trying to lock the device')
def run_once(self, ping_timeout=30, expect_caf_ping=True, username=None,
pre_login=None, pre_login_username=None):
"""
Tests whether or not the RLZ install event (CAI) and first-use event
(CAF) pings are sent. After the first user login, the CAI ping will
be sent after a certain delay. This delay is 24 hours by default, but
can be overridden by specifying the rlz-ping-delay flag in
/etc/chrome_dev.conf, or by using the --rlz-ping-delay argument to
Chrome. Then, if two RW_VPD settings have the correct values
(should_send_rlz_ping == 1, rlz_embargo_end_date has passed OR not
specified), the CAF ping will be sent as well. Ping status is checked
in the /home/chronos/user/'RLZ Data' file, which will contain entries
for CAI and CAF pings in the 'stateful_events' section.
@param ping_timeout: Delay time (seconds) before any RLZ pings are
sent.
@param expect_caf_ping: True if expecting the first-use event (CAF)
ping to be sent, False if not expecting it.
The ping would not be expected if the relevant
RW_VPD settings do not have the right
combination of values.
@param username: Username to log in with during the main RLZ check.
None to sign in with the default test user account.
Specifying a username will log in with a profile
distinct from the test user.
@param pre_login: Whether or not to login before the main RLZ ping
test, and for how long. Should be one of
['lock', 'no_lock', None]. 'lock' is meant for guest
mode testing, where a non-guest user must login to
'lock' the device for RLZ before the ping can be
sent in guest mode. 'no_lock' is to log and log out
immediately to ensure no ping is sent. Used to
verify that the ping can be sent from subsequent
user logins if it has not already been sent.
@param pre_login_username: The username to sign in with for the
pre-login step. None to use the default
test user account.
"""
# Browser arg to make DUT send rlz ping after a short delay.
browser_args = ['--rlz-ping-delay=%d' % ping_timeout]
# TODO(crbug/1103298): keyboard input doesn't work in guest mode
# without disabling this flag. Remove when bug is fixed.
if pre_login == 'lock':
browser_args.append('--disable-features=ImeInputLogicFst')
# If we are testing the ping is sent in guest mode (pre_login='lock'),
# we need to first do a real login and wait for the DUT to become
# 'locked' for rlz. Then logout and enter guest mode.
# If we are testing the ping can be sent by the second user to use the
# device, we will login and immediately logout (pre_login='no_lock').
if pre_login is not None:
logging.debug("Logging in before main RLZ test with username "
"flag: %s", pre_login_username)
with chrome.Chrome(logged_in=True, username=pre_login_username,
extra_browser_args=browser_args):
if pre_login is 'lock':
logging.debug("Waiting for device to be 'locked' for RLZ")
self._wait_for_rlz_lock()
logging.debug("Starting RLZ check with username flag: %s", username)
# Pass clear_enterprise_policy=False in guest mode to avoid deleting
# /home/chronos/'Local State' between logins. Deleting it will cause
# the guest mode test to fail on boards that do not have rlz_brand_code
# in the VPD (mainly unibuild models). This file is normally not
# deleted between logins anyways.
with chrome.Chrome(
logged_in=pre_login is not 'lock',
clear_enterprise_policy=pre_login is not 'lock',
extra_browser_args=browser_args,
username=username,
dont_override_profile=True) as cr:
self._check_url_for_rlz(cr)
self._verify_rlz_data(expect_caf_ping=expect_caf_ping,
guest=pre_login is 'lock')