1# Copyright 2015 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.common_lib import error
8from autotest_lib.client.cros import enterprise_policy_base
9
10
11class policy_RestoreOnStartupURLs(enterprise_policy_base.EnterprisePolicyTest):
12    """Test effect of RestoreOnStartupURLs policy on Chrome OS behavior.
13
14    This test verifies the behavior of Chrome OS for a range of valid values
15    in the RestoreOnStartupURLs user policy. The values are covered by three
16    test cases named: NotSet_NoTabs, SingleUrl_1Tab, and MultipleUrls_3Tabs.
17    - Case NotSet_NoTabs opens no tabs. This is the default behavior for
18      un-managed user and guest user sessions.
19    - Case SingleUrl_1Tab opens a single tab to chrome://settings.
20    - Case MultipleUrls_3Tabs opens 3 tabs, in order, to the following pages:
21      'chrome://policy', 'chrome://settings', and 'chrome://histograms'
22
23    """
24    version = 1
25
26    POLICY_NAME = 'RestoreOnStartupURLs'
27    URLS1_DATA = ['chrome://settings']
28    URLS3_DATA = ['chrome://policy', 'chrome://settings',
29                  'chrome://histograms']
30    NEWTAB_URLS = ['chrome://newtab',
31                   'https://www.google.com/_/chrome/newtab?espv=2&ie=UTF-8']
32
33    # Dictionary of named test cases and policy data.
34    TEST_CASES = {
35        'NotSet_NoTabs': None,
36        'SingleUrl_1Tab': URLS1_DATA,
37        'MultipleUrls_3Tabs': URLS3_DATA
38    }
39
40    def _test_startup_urls(self, policy_value, policies_json):
41        """Verify CrOS enforces RestoreOnStartupURLs policy value.
42
43        When RestoreOnStartupURLs policy is set to one or more URLs, check
44        that a tab is opened to each URL. When set to None, check that no tab
45        is opened.
46
47        @param policy_value: policy value expected on chrome://policy page.
48        @param policies_json: policy JSON data to send to the fake DM server.
49
50        """
51        self.setup_case(self.POLICY_NAME, policy_value, policies_json)
52        logging.info('Running _test_StartupURLs(%s, %s)',
53                     policy_value, policies_json)
54
55        # Get list of open tab urls from browser; Convert unicode to text;
56        # Strip any trailing '/' character reported by devtools.
57        tab_urls = [tab.url.encode('utf8').rstrip('/')
58                    for tab in reversed(self.cr.browser.tabs)]
59        tab_urls_value = ','.join(tab_urls)
60
61        # Telemetry always opens a 'newtab' tab if no startup tabs are opened.
62        # If the only open tab is 'newtab', or a tab with the termporary url
63        # www.google.com/_/chrome/newtab..., then set tab URLs to None.
64        if tab_urls_value in self.NEWTAB_URLS:
65            tab_urls_value = None
66
67        # Compare open tabs with expected tabs by |policy_value|.
68        if tab_urls_value != policy_value:
69            raise error.TestFail('Unexpected tabs: %s '
70                                 '(expected: %s)' %
71                                 (tab_urls_value, policy_value))
72
73    def _run_test_case(self, case):
74        """Setup and run the test configured for the specified test case.
75
76        Set the expected |policy_value| string and |policies_json| data based
77        on the test |case|. If the user specified an expected |value| in the
78        command line args, then use it to set the |policy_value| and blank out
79        the |policies_json|.
80
81        @param case: Name of the test case to run.
82
83        """
84        if self.is_value_given:
85            # If |value| was given by user, then set expected |policy_value|
86            # to the given value, and setup |policies_json| to None.
87            policy_value = self.value
88            policies_json = None
89        else:
90            if self.TEST_CASES[case] is None:
91                policy_value = None
92                policies_json = {'RestoreOnStartup': None}
93            else:
94                policy_value = ','.join(self.TEST_CASES[case])
95                policies_json = {'RestoreOnStartup': 4}
96            policy_json = {self.POLICY_NAME: self.TEST_CASES[case]}
97            policies_json.update(policy_json)
98
99        # Run test using values configured for the test case.
100        self._test_startup_urls(policy_value, policies_json)
101
102    def run_once(self):
103        self.run_once_impl(self._run_test_case)
104