#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (c) 2013 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.

"""Integration test to test the basic functionality of dev-install.

This module contains a test that runs some sanity integration tests against
a VM. First it starts a VM test image and turns it into a base image by wiping
all of the stateful partition. Once done, runs dev_install to restore the
stateful partition.
"""

from __future__ import print_function

import argparse
import logging
import os
import shutil
import sys
import tempfile

import constants
sys.path.append(constants.SOURCE_ROOT)
sys.path.append(constants.CROS_PLATFORM_ROOT)

# pylint: disable=wrong-import-position
from chromite.lib import constants as chromite_constants
from chromite.lib import cros_build_lib
from chromite.lib import dev_server_wrapper
from chromite.lib import image_lib
from chromite.lib import osutils
from chromite.lib import remote_access

from crostestutils.lib import test_helper


class TestError(Exception):
  """Raised on any error during testing. It being raised is a test failure."""


class DevModeTest(object):
  """Wrapper for dev mode tests."""

  # qemu hardcodes 10.0.2.2 as the host from the guest's point of view
  # https://wiki.qemu.org/Documentation/Networking#User_Networking_.28SLIRP.29
  # When the host's eth0 IP address is also 10.0.2.*, and the guest tries to
  # access it, the requests will be handled by qemu and never be seen by the
  # host. Instead, let the guest always connect to 10.0.2.2.
  HOST_IP_ADDRESS = '10.0.2.2'

  def __init__(self, image_path, board, binhost):
    """Initializes DevModeTest.

    Args:
      image_path: Filesystem path to the image to test.
      board: Board of the image under test.
      binhost: Binhost override. Binhost as defined here is where dev-install
               go to search for binary packages. By default this will
               be set to the devserver url of the host running this script.
               If no override i.e. the default is ok, set to None.
    """
    self.image_path = image_path
    self.board = board
    self.binhost = binhost
    self.tmpdir = tempfile.mkdtemp('DevModeTest')
    self.working_image_path = None
    self.devserver = None
    self.device = None
    self.port = None

  def Cleanup(self):
    """Cleans up any state at the end of the test."""
    try:
      if self.devserver:
        self.devserver.Stop()
      self.devserver = None
      if self.device:
        self.device.Cleanup()
      self.device = None
      if self.port:
        cros_build_lib.run(['./cros_vm', '--stop', '--ssh-port=%d' % self.port],
                           cwd=chromite_constants.CHROMITE_BIN_DIR,
                           check=False)
      self.port = None
      osutils.RmDir(self.tmpdir, ignore_missing=True)
      self.tmpdir = None
    except Exception:
      logging.exception('Received error during cleanup')

  def _WipeDevInstall(self):
    """Wipes the devinstall state."""
    logging.info('Wiping /usr/local/bin from the image.')
    with image_lib.LoopbackPartitions(
        self.working_image_path, destination=self.tmpdir) as image:
      image.Mount(('STATE',), mount_opts=())
      dev_image_path = os.path.join(self.tmpdir, 'dir-STATE', 'dev_image')
      osutils.RmDir(dev_image_path, sudo=True)

  def PrepareTest(self):
    """Pre-test modification to the image and env to setup test."""
    logging.info('Making copy of the image %s to manipulate.', self.image_path)
    self.working_image_path = os.path.join(self.tmpdir,
                                           os.path.basename(self.image_path))
    shutil.copyfile(self.image_path, self.working_image_path)
    logging.debug('Copy of vm image stored at %s.', self.working_image_path)

    self._WipeDevInstall()

    self.port = remote_access.GetUnusedPort()
    logging.info('Starting the vm on port %d.', self.port)
    vm_cmd = ['./cros_vm', '--ssh-port=%d' % self.port,
              '--board=%s' % self.board,
              '--image-path=%s' % self.working_image_path, '--start']
    cros_build_lib.run(vm_cmd, cwd=chromite_constants.CHROMITE_BIN_DIR)

    # After the vm is requested ssh can initially take a while.
    connect_settings = remote_access.CompileSSHConnectSettings(
        ConnectTimeout=300)

    self.device = remote_access.ChromiumOSDevice(
        remote_access.LOCALHOST, port=self.port, base_dir=self.tmpdir,
        connect_settings=connect_settings)

    if not self.device.MountRootfsReadWrite():
      raise TestError('Failed to make rootfs writeable')

    if not self.binhost:
      logging.info('Starting the devserver.')
      self.devserver = dev_server_wrapper.DevServerWrapper()
      self.devserver.Start()
      self.binhost = self.devserver.GetDevServerURL(
          ip=self.HOST_IP_ADDRESS, port=self.devserver.port,
          sub_dir='static/pkgroot/%s/packages' % self.board)

    logging.info('Using binhost %s', self.binhost)

  def TestDevInstall(self):
    """Tests that we can run dev-install and have python work afterwards."""
    try:
      logging.info('Running dev install in the vm.')
      self.device.run(
          ['bash', '-l', '-c',
           '"/usr/bin/dev_install --yes --binhost=%s"' % self.binhost])

      logging.info('Verifying that all python versions work on the image.')
      # Symlinks can be tricky, and running python from one place might work
      # while it fails from another.  Test all the prefixes (and $PATH).
      for prefix in ('/usr/bin', '/usr/local/bin', '/usr/local/usr/bin', ''):
        for prog in ('python', 'python3'):
          self.device.run(['sudo', '-u', 'chronos', '--',
                           os.path.join(prefix, prog),
                           '-c', '"print(\'hello world\')"'])

      # We need emerge to work so we can install more binpkgs.
      self.device.run(['emerge', '--info'])
    except (cros_build_lib.RunCommandError,
            remote_access.SSHConnectionError) as e:
      self.devserver.PrintLog()
      logging.error('dev-install test failed. See devserver log above for more '
                    'details.')
      raise TestError('dev-install test failed with: %s' % str(e))

  def Run(self):
    try:
      self.PrepareTest()
      self.TestDevInstall()
      logging.info('All tests passed.')
    finally:
      self.Cleanup()


def main():
  parser = argparse.ArgumentParser(description=__doc__)
  parser.add_argument('--binhost', metavar='URL',
                      help='binhost override. By default, starts up a devserver'
                      ' and uses it as the binhost.')
  parser.add_argument('board', nargs=1, help='board to use.')
  parser.add_argument('image_path', nargs=1, help='path to test image.')
  parser.add_argument('-v', '--verbose', default=False, action='store_true',
                      help='Print out added debugging information')
  options = parser.parse_args()

  test_helper.SetupCommonLoggingFormat(verbose=options.verbose)
  DevModeTest(os.path.realpath(options.image_path[0]), options.board[0],
              options.binhost).Run()

if __name__ == '__main__':
  main()
