# Copyright 2012 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Verifies the integrity of the root partition.

Description
-----------

The root partition may be modified during the factory process. If the disk is
damaged or the flash process is broken, the root partition may also be wrong.

Test Procedure
--------------
This is an automatic test that doesn't need any user interaction.

Dependency
----------
- Device API ``cros.factory.device.partitions``.
- Device API ``cros.factory.device.toybox``.

Examples
--------
An example:

.. test_list::

  generic_storage_examples:VerifyRootPartition

"""

import logging
import os
import re
import tempfile

from cros.factory.device import device_utils
from cros.factory.test import test_case
from cros.factory.test import test_tags
from cros.factory.utils.arg_utils import Arg


DM_DEVICE_NAME = 'verifyroot'
DM_DEVICE_PATH = os.path.join('/dev/mapper', DM_DEVICE_NAME)
BLOCK_SIZE = 8 * 1024 * 1024


class VerifyRootPartitionTest(test_case.TestCase):
  """Verifies the integrity of the root partition."""
  related_components = (test_tags.TestCategory.STORAGE, )


  ARGS = [
      Arg('kern_a_device', str,
          'Path to the device containing KERN-A partition', default=None),
      Arg('root_device', str,
          'Path to the device containing rootfs partition', default=None),
      Arg('max_bytes', int, 'Maximum number of bytes to read', default=None),
  ]

  def setUp(self):
    self.dut = device_utils.CreateDUTInterface()

  def runTest(self):
    # yapf: disable
    if not self.args.kern_a_device:  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
      # yapf: enable
      # yapf: disable
      self.args.kern_a_device = self.dut.partitions.RELEASE_KERNEL.path  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
      # yapf: enable
    # yapf: disable
    if not self.args.root_device:  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
      # yapf: enable
      # yapf: disable
      self.args.root_device = self.dut.partitions.RELEASE_ROOTFS.path  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
      # yapf: enable

    # Prepend '/dev/' if the device path is not absolute. This is mainly for
    # backward-compatibility as many existing test list specifies only 'sda4' or
    # 'mmcblk0p4' in dargs.
    # yapf: disable
    if not self.args.kern_a_device.startswith('/'):  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
      # yapf: enable
      # yapf: disable
      self.args.kern_a_device = os.path.join('/dev', self.args.kern_a_device)  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
      # yapf: enable
    # yapf: disable
    if not self.args.root_device.startswith('/'):  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
      # yapf: enable
      # yapf: disable
      self.args.root_device = os.path.join('/dev', self.args.root_device)  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
      # yapf: enable

    # Copy out the KERN-A partition to a file, since vbutil_kernel
    # won't operate on a device, only a file
    # (http://crosbug.com/34176)
    # yapf: disable
    self.ui.SetState(f'Verifying KERN-A ({self.args.kern_a_device})...')  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
    # yapf: enable
    with self.dut.temp.TempFile() as kern_a_bin:
      # yapf: disable
      self.dut.toybox.dd(if_=self.args.kern_a_device, of=kern_a_bin,  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
      # yapf: enable
                         conv='fsync')
      try:
        vbutil_kernel_output = self.dut.CheckOutput(
            ['futility', 'vbutil_kernel', '--verify', kern_a_bin, '--verbose'],
            log=True)
      except Exception:
        logging.exception(
            'Unable to verify kernel in KERN-A; perhaps this device was imaged '
            'with chromeos-install instead of factory server?')
        raise

    logging.info('vbutil_kernel output is:\n%s', vbutil_kernel_output)

    DM_REGEXP = re.compile(r'dm="(?:1 )?vroot none ro(?: 1)?,(0 (\d+) .+)"')
    match = DM_REGEXP.search(vbutil_kernel_output)
    assert match, (f'Cannot find regexp {DM_REGEXP.pattern!r} in vbutil_kernel '
                   f'output')

    table = match.group(1)
    partition_size = int(match.group(2)) * 512

    DEV_REGEXP = re.compile(r'payload=\S* hashtree=\S*')
    (table_new, nsubs) = DEV_REGEXP.subn(
        # yapf: disable
        f'payload={self.args.root_device} hashtree={self.args.root_device}',  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
        # yapf: enable
        table)
    assert nsubs == 1, (
        f'Expected to find {DEV_REGEXP.pattern!r} in {table!r} once, but found'
        f' {int(nsubs)} matches.')
    table = table_new
    del table_new
    # Cause I/O error on invalid bytes
    table += ' error_behavior=eio'

    # Remove device in case a previous test left it hanging
    self._RemoveDMDevice()
    assert not self.dut.path.exists(DM_DEVICE_PATH)
    # Map the device
    self.dut.CheckCall(
        ['dmsetup', 'create', '-r', DM_DEVICE_NAME, '--table', table], log=True)

    # Read data from the partition; there will be an I/O error on failure
    # yapf: disable
    if self.args.max_bytes is None:  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
      # yapf: enable
      bytes_to_read = partition_size
    else:
      # yapf: disable
      bytes_to_read = min(partition_size, self.args.max_bytes)  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
      # yapf: enable

    if self.dut.link.IsLocal():
      # yapf: disable
      self.ui.DrawProgressBar(bytes_to_read)  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
      # yapf: enable
      # For local link, let's show progress bar for better UX
      with open(DM_DEVICE_PATH, 'rb') as dm_device:
        bytes_read = 0
        while True:
          bytes_left = bytes_to_read - bytes_read
          if not bytes_left:
            break
          count = len(dm_device.read(min(BLOCK_SIZE, bytes_left)))
          if not count:
            break
          bytes_read += count
          pct_done = bytes_read / bytes_to_read
          # yapf: disable
          message = (f'Read {bytes_read / 1024 / 1024:.1f} MiB ({pct_done:.1%})'  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
          # yapf: enable
                     f'of {self.args.root_device}')
          logging.info(message)
          # yapf: disable
          self.ui.SetState(message)  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
          # yapf: enable
          # yapf: disable
          self.ui.SetProgress(bytes_read)  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
          # yapf: enable
    else:
      # for remote link, read out everything at once to save time.
      with tempfile.TemporaryFile('w+') as stderr:
        try:
          # since we need the output of stderr, use CheckCall rather than
          # toybox.dd
          self.dut.CheckCall([
              'dd', 'if=' + DM_DEVICE_PATH, 'of=/dev/null',
              f'bs={int(BLOCK_SIZE)}', f'count={int(bytes_to_read)}',
              'iflag=count_bytes'
          ], log=True, stderr=stderr)
          stderr.flush()
          stderr.seek(0)
          dd_output = stderr.read()
        except Exception:
          stderr.flush()
          stderr.seek(0)
          logging.error('verify rootfs failed: %s', stderr.read())
          raise

      DD_REGEXP = re.compile(r'^(\d+) bytes \(.*\) copied', re.MULTILINE)
      match = DD_REGEXP.search(dd_output)
      assert match, f'unexpected dd output: {dd_output}'
      bytes_read = int(match.group(1))

    self.assertEqual(bytes_to_read, bytes_read)

  def tearDown(self):
    self._RemoveDMDevice()

  def _RemoveDMDevice(self):
    self.dut.Call(['dmsetup', 'remove', DM_DEVICE_NAME], log=True)
