#!/usr/bin/python
#
# Copyright 2016 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.

'''Sanity tests for Chrome on Chrome OS.

This script runs a number of sanity tests to ensure that Chrome browser on
Chrome OS is functional.
'''

from __future__ import print_function

import argparse
import datetime
import logging
import sys

# This sets up import paths for autotest.
import common
from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib.cros import arc, arc_common, chrome
from autotest_lib.client.common_lib.cros import session_manager
from autotest_lib.client.common_lib.error import TestFail
from autotest_lib.client.cros import cryptohome


class VMSanity(object):
  """Class for managing VM Sanity tests."""


  def __init__(self, count=1, run_cryptohome=True, run_incognito=True,
               run_screenlocker=True):
    self.count = count
    self.run_cryptohome = run_cryptohome
    self.run_incognito = run_incognito
    self.run_screenlocker = run_screenlocker


  def Run(self):
    start = datetime.datetime.now()

    for i in range(self.count):
      if self.count > 1:
        logging.info('Starting iteration %d.', i)
      if self.run_cryptohome:
        self.RunCryptohomeTest()
      if self.run_incognito:
        self.RunIncognitoTest()
      if self.run_screenlocker:
        self.RunScreenlockTest()

    elapsed = datetime.datetime.now() - start
    logging.info('Tests succeeded in %s seconds.', elapsed.seconds)


  def RunCryptohomeTest(self):
    """Test Cryptohome."""
    logging.info('RunCryptohomeTest: Starting chrome and logging in.')
    is_arc_available = utils.is_arc_available()
    arc_mode = arc_common.ARC_MODE_ENABLED if is_arc_available else None
    with chrome.Chrome(arc_mode=arc_mode, num_tries=1) as cr:
      # Check that the cryptohome is mounted.
      # is_vault_mounted throws an exception if it fails.
      logging.info('Checking mounted cryptohome.')
      cryptohome.is_vault_mounted(user=cr.username, allow_fail=False)
      # Navigate to about:blank.
      tab = cr.browser.tabs[0]
      tab.Navigate('about:blank')

      # Evaluate some javascript.
      logging.info('Evaluating JavaScript.')
      if tab.EvaluateJavaScript('2+2') != 4:
        raise TestFail('EvaluateJavaScript failed')

      # ARC test.
      if is_arc_available:
        arc.wait_for_android_process('org.chromium.arc.intent_helper')
        arc.wait_for_adb_ready()
        logging.info('Android booted successfully.')
        if not arc.is_package_installed('android'):
          raise TestFail('"android" system package was not listed by '
                         'Package Manager.')

    if is_arc_available:
      utils.poll_for_condition(lambda: not arc.is_adb_connected(),
                               timeout=15,
                               desc='Android container still running '
                               'after Chrome shutdown.')


  def RunIncognitoTest(self):
    """Test Incognito mode."""
    logging.info('RunIncognitoTest')
    with chrome.Chrome(logged_in=False):
      if not cryptohome.is_guest_vault_mounted():
        raise TestFail('Expected to find a guest vault mounted.')
    if cryptohome.is_guest_vault_mounted(allow_fail=True):
      raise TestFail('Expected to NOT find a guest vault mounted.')


  def RunScreenlockTest(self):
    """Run a test that locks the screen."""
    logging.info('RunScreenlockTest')
    with chrome.Chrome(autotest_ext=True) as cr:
      cr.autotest_ext.ExecuteJavaScript('chrome.autotestPrivate.lockScreen();')
      utils.poll_for_condition(
          lambda: cr.login_status['isScreenLocked'],
          timeout=15,
          exception=TestFail('Screen not locked'))


  @staticmethod
  def ParseArgs(argv):
    """Parse command line.

    Args:
      argv: List of command line arguments.

    Returns:
      List of parsed opts.
    """
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--count', type=int, default=1,
                        help='Number of iterations of the test to run.')
    parser.add_argument('--run-all', default=False, action='store_true',
                        help='Run all tests.')
    parser.add_argument('--run-cryptohome', default=False, action='store_true',
                        help='Run Cryptohome test.')
    parser.add_argument('--run-incognito', default=False, action='store_true',
                        help='Run Incognito test.')
    parser.add_argument('--run-screenlock', default=False, action='store_true',
                        help='Run Screenlock test.')
    return parser.parse_args(argv)


def main(argv):
    '''The main function.'''
    opts = VMSanity.ParseArgs(argv)

    # Run all tests if none are specified.
    if opts.run_all or not (opts.run_cryptohome or opts.run_incognito or
                            opts.run_screenlock):
      opts.run_cryptohome = opts.run_incognito = opts.run_screen_lock = True

    VMSanity(opts.count, opts.run_cryptohome, opts.run_incognito,
             opts.run_screenlock).Run()


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))
