1#!/usr/bin/python
2#
3# Copyright 2016 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7'''Sanity tests for Chrome on Chrome OS.
8
9This script runs a number of sanity tests to ensure that Chrome browser on
10Chrome OS is functional.
11'''
12
13from __future__ import print_function
14
15import argparse
16import datetime
17import logging
18import sys
19
20# This sets up import paths for autotest.
21import common
22from autotest_lib.client.bin import utils
23from autotest_lib.client.common_lib.cros import arc, arc_common, chrome
24from autotest_lib.client.common_lib.cros import session_manager
25from autotest_lib.client.common_lib.error import TestFail
26from autotest_lib.client.cros import cryptohome
27
28
29class VMSanity(object):
30  """Class for managing VM Sanity tests."""
31
32
33  def __init__(self, count=1, run_cryptohome=True, run_incognito=True,
34               run_screenlocker=True):
35    self.count = count
36    self.run_cryptohome = run_cryptohome
37    self.run_incognito = run_incognito
38    self.run_screenlocker = run_screenlocker
39
40
41  def Run(self):
42    start = datetime.datetime.now()
43
44    for i in range(self.count):
45      if self.count > 1:
46        logging.info('Starting iteration %d.', i)
47      if self.run_cryptohome:
48        self.RunCryptohomeTest()
49      if self.run_incognito:
50        self.RunIncognitoTest()
51      if self.run_screenlocker:
52        self.RunScreenlockTest()
53
54    elapsed = datetime.datetime.now() - start
55    logging.info('Tests succeeded in %s seconds.', elapsed.seconds)
56
57
58  def RunCryptohomeTest(self):
59    """Test Cryptohome."""
60    logging.info('RunCryptohomeTest: Starting chrome and logging in.')
61    is_arc_available = utils.is_arc_available()
62    arc_mode = arc_common.ARC_MODE_ENABLED if is_arc_available else None
63    with chrome.Chrome(arc_mode=arc_mode, num_tries=1) as cr:
64      # Check that the cryptohome is mounted.
65      # is_vault_mounted throws an exception if it fails.
66      logging.info('Checking mounted cryptohome.')
67      cryptohome.is_vault_mounted(user=cr.username, allow_fail=False)
68      # Navigate to about:blank.
69      tab = cr.browser.tabs[0]
70      tab.Navigate('about:blank')
71
72      # Evaluate some javascript.
73      logging.info('Evaluating JavaScript.')
74      if tab.EvaluateJavaScript('2+2') != 4:
75        raise TestFail('EvaluateJavaScript failed')
76
77      # ARC test.
78      if is_arc_available:
79        arc.wait_for_adb_ready()
80        logging.info('Android booted successfully.')
81        arc.wait_for_android_process('org.chromium.arc.intent_helper')
82        if not arc.is_package_installed('android'):
83          raise TestFail('"android" system package was not listed by '
84                         'Package Manager.')
85
86    if is_arc_available:
87      utils.poll_for_condition(lambda: not arc.is_android_container_alive(),
88                               timeout=15,
89                               desc='Android container still running '
90                               'after Chrome shutdown.')
91
92
93  def RunIncognitoTest(self):
94    """Test Incognito mode."""
95    logging.info('RunIncognitoTest')
96    with chrome.Chrome(logged_in=False):
97      if not cryptohome.is_guest_vault_mounted():
98        raise TestFail('Expected to find a guest vault mounted.')
99    if cryptohome.is_guest_vault_mounted(allow_fail=True):
100      raise TestFail('Expected to NOT find a guest vault mounted.')
101
102
103  def RunScreenlockTest(self):
104    """Run a test that locks the screen."""
105    logging.info('RunScreenlockTest')
106    with chrome.Chrome(autotest_ext=True) as cr:
107      cr.autotest_ext.ExecuteJavaScript('chrome.autotestPrivate.lockScreen();')
108      utils.poll_for_condition(
109          lambda: cr.login_status['isScreenLocked'],
110          timeout=15,
111          exception=TestFail('Screen not locked'))
112
113
114  @staticmethod
115  def ParseArgs(argv):
116    """Parse command line.
117
118    Args:
119      argv: List of command line arguments.
120
121    Returns:
122      List of parsed opts.
123    """
124    parser = argparse.ArgumentParser(description=__doc__)
125    parser.add_argument('--count', type=int, default=1,
126                        help='Number of iterations of the test to run.')
127    parser.add_argument('--run-all', default=False, action='store_true',
128                        help='Run all tests.')
129    parser.add_argument('--run-cryptohome', default=False, action='store_true',
130                        help='Run Cryptohome test.')
131    parser.add_argument('--run-incognito', default=False, action='store_true',
132                        help='Run Incognito test.')
133    parser.add_argument('--run-screenlock', default=False, action='store_true',
134                        help='Run Screenlock test.')
135    return parser.parse_args(argv)
136
137
138def main(argv):
139    '''The main function.'''
140    opts = VMSanity.ParseArgs(argv)
141
142    # Run all tests if none are specified.
143    if opts.run_all or not (opts.run_cryptohome or opts.run_incognito or
144                            opts.run_screenlock):
145      opts.run_cryptohome = opts.run_incognito = opts.run_screen_lock = True
146
147    VMSanity(opts.count, opts.run_cryptohome, opts.run_incognito,
148             opts.run_screenlock).Run()
149
150
151if __name__ == '__main__':
152    sys.exit(main(sys.argv[1:]))
153