179 lines
8.4 KiB
Python
179 lines
8.4 KiB
Python
# 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')
|