#!/usr/bin/env vpython3
# Copyright 2020 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import json
import os
import shutil
import sys
import tempfile
from textwrap import dedent
import unittest

# The following non-std imports are fetched via vpython. See the list at
# //.vpython3
import mock  # pylint: disable=import-error
from parameterized import parameterized  # pylint: disable=import-error

import test_runner

_TAST_TEST_RESULTS_JSON = {
    "name": "login.Chrome",
    "errors": None,
    "start": "2020-01-01T15:41:30.799228462-08:00",
    "end": "2020-01-01T15:41:53.318914698-08:00",
    "skipReason": ""
}


class TestRunnerTest(unittest.TestCase):

  def setUp(self):
    self._tmp_dir = tempfile.mkdtemp()
    self.mock_rdb = mock.patch.object(
        test_runner.result_sink, 'TryInitClient', return_value=None)
    self.mock_rdb.start()
    self.mock_env = mock.patch.dict(
        os.environ, {'SWARMING_BOT_ID': 'cros-chrome-chromeos8-row29'})
    self.mock_env.start()

  def tearDown(self):
    shutil.rmtree(self._tmp_dir, ignore_errors=True)
    self.mock_rdb.stop()
    self.mock_env.stop()

  def safeAssertItemsEqual(self, list1, list2):
    """A Py3 safe version of assertItemsEqual.

    See https://bugs.python.org/issue17866.
    """
    self.assertSetEqual(set(list1), set(list2))


class TastTests(TestRunnerTest):

  def get_common_tast_args(self, use_vm, fetch_cros_hostname):
    return [
        'script_name',
        'tast',
        '--suite-name=chrome_all_tast_tests',
        '--board=eve',
        '--flash',
        '--path-to-outdir=out_eve/Release',
        '--logs-dir=%s' % self._tmp_dir,
        '--use-vm' if use_vm else
        ('--fetch-cros-hostname'
         if fetch_cros_hostname else '--device=localhost:2222'),
    ]

  def get_common_tast_expectations(self, use_vm, fetch_cros_hostname):
    expectation = [
        test_runner.CROS_RUN_TEST_PATH,
        '--board',
        'eve',
        '--cache-dir',
        test_runner.DEFAULT_CROS_CACHE,
        '--results-dest-dir',
        '%s/system_logs' % self._tmp_dir,
        '--flash',
        '--build-dir',
        'out_eve/Release',
        '--results-dir',
        self._tmp_dir,
        '--tast-total-shards=1',
        '--tast-shard-index=0',
    ]
    expectation.extend(['--start', '--copy-on-write'] if use_vm else (
        ['--device', 'chrome-chromeos8-row29']
        if fetch_cros_hostname else ['--device', 'localhost:2222']))
    for p in test_runner.SYSTEM_LOG_LOCATIONS:
      expectation.extend(['--results-src', p])

    expectation += [
        '--mount',
        '--deploy',
        '--nostrip',
    ]
    return expectation

  def test_tast_gtest_filter(self):
    """Tests running tast tests with a gtest-style filter."""
    with open(os.path.join(self._tmp_dir, 'streamed_results.jsonl'), 'w') as f:
      json.dump(_TAST_TEST_RESULTS_JSON, f)

    args = self.get_common_tast_args(False, False) + [
        '--attr-expr=( "group:mainline" && "dep:chrome" && !informational)',
        '--gtest_filter=login.Chrome:ui.WindowControl',
    ]
    with mock.patch.object(sys, 'argv', args),\
         mock.patch.object(test_runner.subprocess, 'Popen') as mock_popen:
      mock_popen.return_value.returncode = 0

      test_runner.main()
      # The gtest filter should cause the Tast expr to be replaced with a list
      # of the tests in the filter.
      expected_cmd = self.get_common_tast_expectations(False, False) + [
          '--tast=("name:login.Chrome" || "name:ui.WindowControl")'
      ]

      self.safeAssertItemsEqual(expected_cmd, mock_popen.call_args[0][0])

  @parameterized.expand([
      [True, False],
      [False, True],
      [False, False],
  ])
  def test_tast_attr_expr(self, use_vm, fetch_cros_hostname):
    """Tests running a tast tests specified by an attribute expression."""
    with open(os.path.join(self._tmp_dir, 'streamed_results.jsonl'), 'w') as f:
      json.dump(_TAST_TEST_RESULTS_JSON, f)

    args = self.get_common_tast_args(use_vm, fetch_cros_hostname) + [
        '--attr-expr=( "group:mainline" && "dep:chrome" && !informational)',
    ]
    with mock.patch.object(sys, 'argv', args),\
         mock.patch.object(test_runner.subprocess, 'Popen') as mock_popen:
      mock_popen.return_value.returncode = 0

      test_runner.main()
      expected_cmd = self.get_common_tast_expectations(
          use_vm, fetch_cros_hostname) + [
              '--tast=( "group:mainline" && "dep:chrome" && !informational)',
          ]

      self.safeAssertItemsEqual(expected_cmd, mock_popen.call_args[0][0])

  @parameterized.expand([
      [True, False],
      [False, True],
      [False, False],
  ])
  def test_tast_with_vars(self, use_vm, fetch_cros_hostname):
    """Tests running a tast tests with runtime variables."""
    with open(os.path.join(self._tmp_dir, 'streamed_results.jsonl'), 'w') as f:
      json.dump(_TAST_TEST_RESULTS_JSON, f)

    args = self.get_common_tast_args(use_vm, fetch_cros_hostname) + [
        '-t=login.Chrome',
        '--tast-var=key=value',
    ]
    with mock.patch.object(sys, 'argv', args),\
         mock.patch.object(test_runner.subprocess, 'Popen') as mock_popen:
      mock_popen.return_value.returncode = 0
      test_runner.main()
      expected_cmd = self.get_common_tast_expectations(
          use_vm, fetch_cros_hostname) + [
              '--tast', 'login.Chrome', '--tast-var', 'key=value'
          ]

      self.safeAssertItemsEqual(expected_cmd, mock_popen.call_args[0][0])

  @parameterized.expand([
      [True, False],
      [False, True],
      [False, False],
  ])
  def test_tast_retries(self, use_vm, fetch_cros_hostname):
    """Tests running a tast tests with retries."""
    with open(os.path.join(self._tmp_dir, 'streamed_results.jsonl'), 'w') as f:
      json.dump(_TAST_TEST_RESULTS_JSON, f)

    args = self.get_common_tast_args(use_vm, fetch_cros_hostname) + [
        '-t=login.Chrome',
        '--tast-retries=1',
    ]
    with mock.patch.object(sys, 'argv', args),\
         mock.patch.object(test_runner.subprocess, 'Popen') as mock_popen:
      mock_popen.return_value.returncode = 0
      test_runner.main()
      expected_cmd = self.get_common_tast_expectations(
          use_vm,
          fetch_cros_hostname) + ['--tast', 'login.Chrome', '--tast-retries=1']

      self.safeAssertItemsEqual(expected_cmd, mock_popen.call_args[0][0])

  @parameterized.expand([
      [True, False],
      [False, True],
      [False, False],
  ])
  def test_tast(self, use_vm, fetch_cros_hostname):
    """Tests running a tast tests."""
    with open(os.path.join(self._tmp_dir, 'streamed_results.jsonl'), 'w') as f:
      json.dump(_TAST_TEST_RESULTS_JSON, f)

    args = self.get_common_tast_args(use_vm, fetch_cros_hostname) + [
        '-t=login.Chrome',
    ]
    with mock.patch.object(sys, 'argv', args),\
         mock.patch.object(test_runner.subprocess, 'Popen') as mock_popen:
      mock_popen.return_value.returncode = 0

      test_runner.main()
      expected_cmd = self.get_common_tast_expectations(
          use_vm, fetch_cros_hostname) + ['--tast', 'login.Chrome']

      self.safeAssertItemsEqual(expected_cmd, mock_popen.call_args[0][0])


class GTestTest(TestRunnerTest):

  @parameterized.expand([
      [True, True, True, False, True],
      [True, False, False, False, False],
      [False, True, True, True, True],
      [False, False, False, True, False],
      [False, True, True, False, True],
      [False, False, False, False, False],
  ])
  def test_gtest(self, use_vm, stop_ui, use_test_sudo_helper,
                 fetch_cros_hostname, use_deployed_dbus_configs):
    """Tests running a gtest."""
    fd_mock = mock.mock_open()

    args = [
        'script_name',
        'gtest',
        '--test-exe=out_eve/Release/base_unittests',
        '--board=eve',
        '--path-to-outdir=out_eve/Release',
        '--use-vm' if use_vm else
        ('--fetch-cros-hostname'
         if fetch_cros_hostname else '--device=localhost:2222'),
    ]
    if stop_ui:
      args.append('--stop-ui')
    if use_test_sudo_helper:
      args.append('--run-test-sudo-helper')
    if use_deployed_dbus_configs:
      args.append('--use-deployed-dbus-configs')

    with mock.patch.object(sys, 'argv', args),\
         mock.patch.object(test_runner.subprocess, 'Popen') as mock_popen,\
         mock.patch.object(os, 'fdopen', fd_mock),\
         mock.patch.object(os, 'remove') as mock_remove,\
         mock.patch.object(tempfile, 'mkstemp',
            side_effect=[(3, 'out_eve/Release/device_script.sh'),\
                         (4, 'out_eve/Release/runtime_files.txt')]),\
         mock.patch.object(os, 'fchmod'):
      mock_popen.return_value.returncode = 0

      test_runner.main()
      self.assertEqual(1, mock_popen.call_count)
      expected_cmd = [
          'vpython3', test_runner.CROS_RUN_TEST_PATH, '--board', 'eve',
          '--cache-dir', test_runner.DEFAULT_CROS_CACHE, '--remote-cmd',
          '--cwd', 'out_eve/Release', '--files-from',
          'out_eve/Release/runtime_files.txt'
      ]
      if not stop_ui:
        expected_cmd.append('--as-chronos')
      expected_cmd.extend(['--start', '--copy-on-write'] if use_vm else (
          ['--device', 'chrome-chromeos8-row29']
          if fetch_cros_hostname else ['--device', 'localhost:2222']))
      expected_cmd.extend(['--', './device_script.sh'])
      self.safeAssertItemsEqual(expected_cmd, mock_popen.call_args[0][0])

      expected_device_script = dedent("""\
          #!/bin/sh
          export HOME=/usr/local/tmp
          export TMPDIR=/usr/local/tmp
          """)

      core_cmd = 'LD_LIBRARY_PATH=./ ./out_eve/Release/base_unittests'\
          ' --test-launcher-shard-index=0 --test-launcher-total-shards=1'

      if use_test_sudo_helper:
        expected_device_script += dedent("""\
            TEST_SUDO_HELPER_PATH=$(mktemp)
            ./test_sudo_helper.py --socket-path=${TEST_SUDO_HELPER_PATH} &
            TEST_SUDO_HELPER_PID=$!
          """)
        core_cmd += ' --test-sudo-helper-socket-path=${TEST_SUDO_HELPER_PATH}'

      if use_deployed_dbus_configs:
        expected_device_script += dedent("""\
            mount --bind ./dbus /opt/google/chrome/dbus
            kill -s HUP $(pgrep dbus)
          """)

      if stop_ui:
        dbus_cmd = 'dbus-send --system --type=method_call'\
          ' --dest=org.chromium.PowerManager'\
          ' /org/chromium/PowerManager'\
          ' org.chromium.PowerManager.HandleUserActivity int32:0'
        expected_device_script += dedent("""\
          stop ui
          {0}
          chown -R chronos: ../..
          sudo -E -u chronos -- /bin/bash -c \"{1}\"
          TEST_RETURN_CODE=$?
          start ui
          """).format(dbus_cmd, core_cmd)
      else:
        expected_device_script += dedent("""\
          {0}
          TEST_RETURN_CODE=$?
          """).format(core_cmd)

      if use_test_sudo_helper:
        expected_device_script += dedent("""\
            pkill -P $TEST_SUDO_HELPER_PID
            kill $TEST_SUDO_HELPER_PID
            unlink ${TEST_SUDO_HELPER_PATH}
          """)

      if use_deployed_dbus_configs:
        expected_device_script += dedent("""\
            umount /opt/google/chrome/dbus
            kill -s HUP $(pgrep dbus)
          """)

      expected_device_script += dedent("""\
          exit $TEST_RETURN_CODE
        """)

      self.assertEqual(2, fd_mock().write.call_count)
      write_calls = fd_mock().write.call_args_list

      # Split the strings to make failure messages easier to read.
      # Verify the first write of device script.
      self.assertListEqual(
          expected_device_script.split('\n'),
          str(write_calls[0][0][0]).split('\n'))

      # Verify the 2nd write of runtime files.
      expected_runtime_files = ['out_eve/Release/device_script.sh']
      self.assertListEqual(expected_runtime_files,
                           str(write_calls[1][0][0]).strip().split('\n'))

      mock_remove.assert_called_once_with('out_eve/Release/device_script.sh')

  def test_gtest_with_vpython(self):
    """Tests building a gtest with --vpython-dir."""
    args = mock.MagicMock()
    args.test_exe = 'base_unittests'
    args.test_launcher_summary_output = None
    args.trace_dir = None
    args.runtime_deps_path = None
    args.path_to_outdir = self._tmp_dir
    args.vpython_dir = self._tmp_dir
    args.logs_dir = self._tmp_dir

    # With vpython_dir initially empty, the test_runner should error out
    # due to missing vpython binaries.
    gtest = test_runner.GTestTest(args, None)
    with self.assertRaises(test_runner.TestFormatError):
      gtest.build_test_command()

    # Create the two expected tools, and the test should be ready to run.
    with open(os.path.join(args.vpython_dir, 'vpython3'), 'w'):
      pass  # Just touch the file.
    os.mkdir(os.path.join(args.vpython_dir, 'bin'))
    with open(os.path.join(args.vpython_dir, 'bin', 'python3'), 'w'):
      pass
    gtest = test_runner.GTestTest(args, None)
    gtest.build_test_command()


class HostCmdTests(TestRunnerTest):

  @parameterized.expand([
      [False, False],
      [False, True],
      [True, False],
      [True, True],
  ])
  def test_host_cmd(self, deploy_chrome, strip_chrome):
    args = [
        'script_name',
        'host-cmd',
        '--board=eve',
        '--flash',
        '--path-to-outdir=out/Release',
        '--device=localhost:2222',
    ]
    if deploy_chrome:
      args += ['--deploy-chrome']
    if strip_chrome:
      args += ['--strip-chrome']
    args += [
        '--',
        'fake_cmd',
    ]
    with mock.patch.object(sys, 'argv', args),\
         mock.patch.object(test_runner.subprocess, 'Popen') as mock_popen:
      mock_popen.return_value.returncode = 0

      test_runner.main()
      expected_cmd = [
          test_runner.CROS_RUN_TEST_PATH,
          '--board',
          'eve',
          '--cache-dir',
          test_runner.DEFAULT_CROS_CACHE,
          '--flash',
          '--device',
          'localhost:2222',
          '--host-cmd',
      ]
      if deploy_chrome:
        expected_cmd += [
            '--mount',
            '--deploy',
            '--build-dir',
            os.path.join(test_runner.CHROMIUM_SRC_PATH, 'out/Release'),
        ]
        if not strip_chrome:
          expected_cmd += ['--nostrip']

      expected_cmd += [
          '--',
          'fake_cmd',
      ]

      self.safeAssertItemsEqual(expected_cmd, mock_popen.call_args[0][0])


if __name__ == '__main__':
  unittest.main()
