• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2020 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 logging
6
7from autotest_lib.client.bin import utils
8from autotest_lib.client.common_lib import error
9from autotest_lib.client.common_lib.cros import chrome
10from autotest_lib.client.cros.update_engine import nebraska_wrapper
11from autotest_lib.client.cros.update_engine import update_engine_test
12from telemetry.core import exceptions
13
14class autoupdate_UpdateFromUI(update_engine_test.UpdateEngineTest):
15    """Starts an update from the Chrome OS Settings app. """
16    version = 1
17
18    _NOTIFICATION_INTERVAL = 1
19    _NOTIFICATION_TIMEOUT = 10
20    _NOTIFICATION_TITLE = "Update available"
21
22
23    def initialize(self):
24        """Test setup."""
25        super(autoupdate_UpdateFromUI, self).initialize()
26        self._clear_custom_lsb_release()
27        self._cr = None
28
29
30    def cleanup(self):
31        """Test cleanup. Clears the custom lsb-release used by the test. """
32        self._clear_custom_lsb_release()
33        super(autoupdate_UpdateFromUI, self).cleanup()
34
35    def _wait_for_update_notification(self):
36        """Waits for the post-update notification to appear. """
37
38        def find_notification():
39            """Polls for visibility of the post-update notification. """
40            notifications = self._cr.get_visible_notifications()
41            if notifications is None:
42                return False
43            return any(n for n in notifications
44                       if self._NOTIFICATION_TITLE in n['title'])
45
46        utils.poll_for_condition(
47                condition=find_notification,
48                exception=error.TestFail('Post-update notification not found'),
49                timeout=self._NOTIFICATION_TIMEOUT,
50                sleep_interval=self._NOTIFICATION_INTERVAL)
51
52
53    def run_once(self, payload_url):
54        """
55        Tests that a Chrome OS software update can be completed from the UI,
56        and that the post-update notification appears when the update is
57        complete.
58
59        @param payload_url: The payload url to use.
60
61        """
62        with nebraska_wrapper.NebraskaWrapper(
63            log_dir=self.resultsdir, payload_url=payload_url) as nebraska:
64            # To check the post-update notification, we need to remain logged
65            # in after the update completes. However, the DUT will auto-reboot
66            # if we log out after completing an update. This will cause the
67            # server test to fail when returning from the client test. To avoid
68            # this, we stay logged in at the end of the client test by not
69            # using a context manager for the Chrome session.
70            try:
71                self._cr = chrome.Chrome(autotest_ext=True)
72
73                # Need to create a custom lsb-release file to point the UI
74                # update button to Nebraska instead of the default update
75                # server.
76                self._create_custom_lsb_release(
77                    nebraska.get_update_url(critical_update=True))
78
79                # Go to the OS settings page and check for an update.
80                tab = self._cr.browser.tabs[0]
81                tab.Navigate('chrome://os-settings/help')
82                tab.WaitForDocumentReadyStateToBeComplete()
83                self._take_screenshot('before_check_for_updates.png')
84                try:
85                    tab.EvaluateJavaScript('settings.AboutPageBrowserProxyImpl'
86                                           '.getInstance().requestUpdate()')
87                except exceptions.EvaluateException:
88                    raise error.TestFail(
89                        'Failed to find and click Check For Updates button.')
90                self._take_screenshot('after_check_for_updates.png')
91                self._wait_for_update_to_complete()
92
93            except Exception as e:
94                # The update didn't complete, so we can close the Chrome
95                # session without worrying about auto-reboot.
96                logging.exception("Failed to perform the update: %s", e)
97                if self._cr:
98                    self._cr.close()
99                raise error.TestFail("Failed to perform the update: %s" % e)
100
101            self._wait_for_update_notification()
102