1# Copyright 2018 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import datetime
6
7from autotest_lib.client.common_lib import error
8from autotest_lib.client.common_lib.cros import tpm_utils
9from autotest_lib.client.common_lib.cros import vpd_utils
10from autotest_lib.server import autotest
11from autotest_lib.server import test
12
13
14class rlz_CheckPing(test.test):
15    """
16    Tests if we are sending RLZ install (CAI) and first-use (CAF) pings in a
17    variety of different circumstances. Refer to the TestTracker RLZ test plan
18    for more information:
19    https://testtracker.googleplex.com/testplans/details/25301
20
21    """
22    version = 1
23
24    _CLIENT_TEST = 'desktopui_CheckRlzPingSent'
25    _PING_VPD = 'should_send_rlz_ping'
26    _DATE_VPD = 'rlz_embargo_end_date'
27
28    def _check_rlz_brand_code(self):
29        """Checks that we have an rlz brand code."""
30        try:
31            self._host.run('cros_config / brand-code')
32        except error.AutoservRunError as e:
33            raise error.TestFail('DUT is missing brand_code: %s.' %
34                                 e.result_obj.stderr)
35
36
37    def _set_vpd_values(self, should_send_rlz_ping, rlz_embargo_end_date):
38        """
39        Sets the required vpd values for the test.
40
41        @param should_send_rlz_ping: Value to set should_send_rlz_ping. 1 to
42                                     send the ping, 0 to not send it, None to
43                                     clear it from the VPD.
44        @param embargo_date: Date for rlz_embargo_end_date value. This should
45                             be a datetime.date object with the desired date
46                             for rlz_embargo_end_date, or None to clear it and
47                             proceed with rlz_embargo_end_date not set.
48
49        """
50        to_set = {}
51        if should_send_rlz_ping is not None:
52            to_set[self._PING_VPD] = should_send_rlz_ping
53        else:
54            vpd_utils.vpd_delete(host=self._host, key=self._PING_VPD,
55                                 dump=True, force_dump=True)
56
57        if rlz_embargo_end_date:
58            to_set[self._DATE_VPD] = rlz_embargo_end_date.isoformat()
59        else:
60            vpd_utils.vpd_delete(host=self._host, key=self._DATE_VPD,
61                                 dump=True, force_dump=True)
62
63        if to_set:
64            vpd_utils.vpd_set(host=self._host, vpd_dict=to_set, dump=True,
65                              force_dump=True)
66
67
68    def _check_rlz_vpd_settings_post_ping(self, should_send_rlz_ping,
69                                          rlz_embargo_end_date):
70        """
71        Checks that rlz related vpd settings are correct after the test.
72        In the typical case where the first-use event (CAF) ping is sent
73        successfully, both should_send_rlz_ping and rlz_embargo_end_date VPD
74        values should be cleared. If the CAF ping is not sent, they will
75        remain unchanged.
76
77        @param should_send_rlz_ping: Expected value for the
78                                     should_send_rlz_ping VPD setting
79                                     (0 or 1). If None, we expect no setting
80                                     to be present.
81        @param rlz_embargo_end_date: Expected value of the
82                                     rlz_embargo_end_date VPD setting.
83                                     This argument should be None if expecting
84                                     the value to be cleared, and a
85                                     datetime.date object containing the
86                                     expected date otherwise.
87
88        """
89        check_should_send_ping = vpd_utils.vpd_get(host=self._host,
90                                                   key=self._PING_VPD)
91        if check_should_send_ping is not None:
92            check_should_send_ping = int(check_should_send_ping)
93
94        check_date = vpd_utils.vpd_get(host=self._host,
95                                       key=self._DATE_VPD)
96
97        if rlz_embargo_end_date:
98            rlz_embargo_end_date = rlz_embargo_end_date.isoformat()
99
100        if check_date != rlz_embargo_end_date:
101            raise error.TestFail('Unexpected value for rlz_embargo_end_date:'
102                                 ' %s' % check_date)
103
104        if check_should_send_ping != should_send_rlz_ping:
105            raise error.TestFail('Unexpected value for should_send_rlz_ping:'
106                                 ' %s' % check_should_send_ping)
107
108
109    def run_once(self, host, ping_timeout=30, pre_login=None,
110                 rlz_embargo_end_date=None, should_send_rlz_ping=1,
111                 check_ping_not_resent=False, reboot=False):
112        """
113        Configures the DUT to send RLZ pings. Checks for the RLZ client
114        install (CAI) and first-use (CAF) pings.
115
116        @param host: Host to run test on.
117        @param ping_timeout: Delay time (seconds) before both CAI and CAF
118                             pings are sent.
119        @param pre_login: Whether or not to login before the main RLZ ping
120                          test, and for how long. Should be one of
121                          ['lock', 'no_lock', None]. 'lock' is meant for guest
122                          mode testing, where a non-guest user must login to
123                          'lock' the device for RLZ before the ping can be
124                          sent in guest mode. 'no_lock' is to log in with a
125                          different user account and log out immediately to
126                          ensure no ping is sent. Used to verify that the ping
127                          can be sent from subsequent user logins if it has
128                          not already been sent.
129        @param rlz_embargo_end_date: Date for rlz_embargo_end_date VPD
130                                     setting. If None, no value will be set
131                                     for rlz_embargo_end_date, and any
132                                     existing value will be cleared. For a
133                                     specific rlz_embargo_end_date, this
134                                     argument should be a datetime.date
135                                     object containing the desired date.
136        @param should_send_rlz_ping: Value of the should_send_rlz_ping VPD
137                                     setting. 1 to send the first-use (CAF)
138                                     ping, 0 to not send it. The ping should
139                                     not be sent when the VPD value is 0,
140                                     which in the normal use-case occurs after
141                                     the CAF ping has been sent. It is set to
142                                     0 after the CAF ping to ensure it is not
143                                     sent again in the device's lifetime.
144                                     This argument can also be None, in which
145                                     case the should_send_rlz_ping VPD setting
146                                     will be cleared. No CAF ping should be
147                                     sent in this case, either.
148        @param check_ping_not_resent: True to perform a second RLZ check with
149                                      a different user account for tests that
150                                      confirm the first-use (CAF) ping is not
151                                      resent. The second check assumes the CAF
152                                      ping was sent successfully, so the
153                                      should_send_rlz_ping and
154                                      rlz_embargo_end_date parameters should
155                                      be a combination that ensures it was
156                                      sent.
157        @param reboot: True to reboot after the first RLZ check.
158
159        """
160        self._host = host
161        self._check_rlz_brand_code()
162
163        # Set VPD settings that control if the DUT will send a first-use ping.
164        self._set_vpd_values(should_send_rlz_ping=should_send_rlz_ping,
165                             rlz_embargo_end_date=rlz_embargo_end_date)
166        # Clear TPM owner so we have no users on DUT.
167        tpm_utils.ClearTPMOwnerRequest(self._host)
168
169        # We expect first-use (CAF) ping to be sent when:
170        # 1. should_send_rlz_ping exists and is 1
171        # 2. rlz_embargo_end_date is missing or in the past
172        expect_caf = bool(should_send_rlz_ping)
173        if rlz_embargo_end_date:
174            expect_caf = (expect_caf and
175                (datetime.date.today() - rlz_embargo_end_date).days > 0)
176
177        # Login, do a Google search, verify events in RLZ Data file.
178        client_at = autotest.Autotest(self._host)
179        client_at.run_test(self._CLIENT_TEST, ping_timeout=ping_timeout,
180                           expect_caf_ping=expect_caf, pre_login=pre_login,
181                           pre_login_username='rlz_user')
182        client_at._check_client_test_result(self._host, self._CLIENT_TEST)
183
184        if expect_caf:
185            self._check_rlz_vpd_settings_post_ping(
186                should_send_rlz_ping=0, rlz_embargo_end_date=None)
187        else:
188            self._check_rlz_vpd_settings_post_ping(
189                should_send_rlz_ping=should_send_rlz_ping,
190                rlz_embargo_end_date=rlz_embargo_end_date)
191
192        if reboot:
193            self._host.reboot()
194
195        # Log in with another user and verify CAF ping is not resent. This
196        # portion of the test assumes a successful run above where expect_caf
197        # was True.
198        if check_ping_not_resent:
199            client_at.run_test(self._CLIENT_TEST, ping_timeout=ping_timeout,
200                               expect_caf_ping=False, username='rlz_user',
201                               tag="check_ping_not_resent")
202
203            # Confirm VPD settings are also unchanged
204            self._check_rlz_vpd_settings_post_ping(
205                should_send_rlz_ping=0, rlz_embargo_end_date=None)