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

import base64
import functools
import io
import json
import os
import re
import subprocess
import sys
import tempfile
import unittest
import urllib.request
from unittest.mock import (ANY, Mock, MagicMock, mock_open, patch, call,
                           PropertyMock)

bisect_builds = __import__('bisect-builds')

if 'NO_MOCK_SERVER' not in os.environ:
  maybe_patch = patch
else:
  # SetupEnvironment for gsutil to connect to real server.
  options = bisect_builds.ParseCommandLine(['-a', 'linux64', '-g', '1'])
  bisect_builds.SetupEnvironment(options)
  bisect_builds.SetupAndroidEnvironment()

  # Mock object that always wraps for the spec.
  # This will pass the call through and ignore the return_value and side_effect.
  class WrappedMock(MagicMock):

    def __init__(self,
                 spec=None,
                 return_value=None,
                 side_effect=None,
                 *args,
                 **kwargs):
      wraps = kwargs.pop('wraps', spec)
      super().__init__(spec, *args, **kwargs, wraps=wraps)

  maybe_patch = functools.partial(patch, spec=True, new_callable=WrappedMock)
  maybe_patch.object = functools.partial(patch.object,
                                         spec=True,
                                         new_callable=WrappedMock)


class BisectTestCase(unittest.TestCase):

  @classmethod
  def setUpClass(cls):
    # Patch the name pattern for pkgutil to accept "bisect-builds" as module
    # name.
    if sys.version_info[:2] > (3, 8):
      dotted_words = r'(?!\d)([\w-]+)(\.(?!\d)(\w+))*'
      name_pattern = re.compile(
          f'^(?P<pkg>{dotted_words})'
          f'(?P<cln>:(?P<obj>{dotted_words})?)?$', re.UNICODE)
      cls.name_pattern_patcher = patch('pkgutil._NAME_PATTERN', name_pattern)
      cls.name_pattern_patcher.start()

    # patch cache filename to prevent pollute working dir.
    fd, cls.tmp_cache_file = tempfile.mkstemp(suffix='.json')
    os.close(fd)
    cls.cache_filename_patcher = patch(
        'bisect-builds.ArchiveBuild._rev_list_cache_filename',
        new=PropertyMock(return_value=cls.tmp_cache_file))
    cls.cache_filename_patcher.start()

  @classmethod
  def tearDownClass(cls):
    if sys.version_info[:2] > (3, 8):
      cls.name_pattern_patcher.stop()
    cls.cache_filename_patcher.stop()
    os.unlink(cls.tmp_cache_file)


class BisectTest(BisectTestCase):

  max_rev = 10000

  def setUp(self):
    self.patchers = []
    self.patchers.append(patch('bisect-builds.DownloadJob._fetch'))
    self.patchers.append(
        patch('bisect-builds.ArchiveBuild.run_revision',
              return_value=(0, '', '')))
    self.patchers.append(
        patch('bisect-builds.SnapshotBuild._get_rev_list',
              return_value=range(self.max_rev)))
    for each in self.patchers:
      each.start()

  def tearDown(self):
    for each in self.patchers:
      each.stop()

  def bisect(self, good_rev, bad_rev, evaluate, num_runs=1):
    options = bisect_builds.ParseCommandLine([
        '-a', 'linux64', '-g',
        str(good_rev), '-b',
        str(bad_rev), '--times',
        str(num_runs), '--no-local-cache'
    ])
    archive_build = bisect_builds.create_archive_build(options)
    (minrev, maxrev) = bisect_builds.Bisect(archive_build=archive_build,
                                            evaluate=evaluate,
                                            try_args=options.args)
    return (minrev, maxrev)

  @patch('builtins.print')
  def testBisectConsistentAnswer(self, mock_print):

    def get_steps():
      steps = []
      for call in mock_print.call_args_list:
        if call.args and call.args[0].startswith('You have'):
          steps.append(int(re.search(r'(\d+) steps', call.args[0])[1]))
      return steps

    self.assertEqual(self.bisect(1000, 100, lambda *args: 'g'), (100, 101))
    self.assertSequenceEqual(get_steps(), range(10, 1, -1))

    mock_print.reset_mock()
    self.assertEqual(self.bisect(100, 1000, lambda *args: 'b'), (100, 101))
    self.assertSequenceEqual(get_steps(), range(10, 0, -1))

    mock_print.reset_mock()
    self.assertEqual(self.bisect(2000, 200, lambda *args: 'b'), (1999, 2000))
    self.assertSequenceEqual(get_steps(), range(11, 0, -1))

    mock_print.reset_mock()
    self.assertEqual(self.bisect(200, 2000, lambda *args: 'g'), (1999, 2000))
    self.assertSequenceEqual(get_steps(), range(11, 1, -1))

  @patch('bisect-builds.ArchiveBuild.run_revision', return_value=(0, '', ''))
  def test_bisect_should_retry(self, mock_run_revision):
    evaluator = Mock(side_effect='rgrgrbr')
    self.assertEqual(self.bisect(9, 1, evaluator), (2, 3))
    tested_revisions = [c.args[0] for c in evaluator.call_args_list]
    self.assertEqual(tested_revisions, [5, 5, 3, 3, 2, 2])
    self.assertEqual(mock_run_revision.call_count, 6)

    evaluator = Mock(side_effect='rgrrrgrbr')
    self.assertEqual(self.bisect(1, 10, evaluator), (8, 9))
    tested_revisions = [c.args[0] for c in evaluator.call_args_list]
    self.assertEqual(tested_revisions, [6, 6, 8, 8, 8, 8, 9, 9])

  def test_bisect_should_unknown(self):
    evaluator = Mock(side_effect='uuuggggg')
    self.assertEqual(self.bisect(9, 1, evaluator), (1, 2))
    tested_revisions = [c.args[0] for c in evaluator.call_args_list]
    self.assertEqual(tested_revisions, [5, 3, 6, 7, 2])

    evaluator = Mock(side_effect='uuugggggg')
    self.assertEqual(self.bisect(1, 9, evaluator), (8, 9))
    tested_revisions = [c.args[0] for c in evaluator.call_args_list]
    self.assertEqual(tested_revisions, [5, 7, 4, 3, 8])

  def test_bisect_should_quit(self):
    evaluator = Mock(side_effect=SystemExit())
    with self.assertRaises(SystemExit):
      self.assertEqual(self.bisect(9, 1, evaluator), (None, None))

  def test_edge_cases(self):
    with self.assertRaises(bisect_builds.BisectException):
      self.assertEqual(self.bisect(1, 1, Mock()), (1, 1))
    self.assertEqual(self.bisect(2, 1, Mock()), (1, 2))
    self.assertEqual(self.bisect(1, 2, Mock()), (1, 2))


class DownloadJobTest(BisectTestCase):

  @patch('bisect-builds.gsutil_download')
  def test_fetch_gsutil(self, mock_gsutil_download):
    fetch = bisect_builds.DownloadJob('gs://some-file.zip', 123)
    fetch.start()
    fetch.wait_for()
    mock_gsutil_download.assert_called_once()

  @patch('urllib.request.urlretrieve')
  def test_fetch_http(self, mock_urlretrieve):
    fetch = bisect_builds.DownloadJob('http://some-file.zip', 123)
    fetch.start()
    fetch.wait_for()
    mock_urlretrieve.assert_called_once()

  @patch('tempfile.mkstemp', return_value=(321, 'some-file.zip'))
  @patch('urllib.request.urlretrieve')
  @patch('os.close')
  @patch('os.unlink')
  def test_should_del(self, mock_unlink, mock_close, mock_urlretrieve,
                      mock_mkstemp):
    fetch = bisect_builds.DownloadJob('http://some-file.zip', 123)
    fetch.start().wait_for()
    fetch.stop()
    mock_mkstemp.assert_called_once()
    mock_close.assert_called_once()
    mock_urlretrieve.assert_called_once()
    mock_unlink.assert_called_with('some-file.zip')

  @patch('urllib.request.urlretrieve')
  def test_stop_wait_for_should_be_able_to_reenter(self, mock_urlretrieve):
    fetch = bisect_builds.DownloadJob('http://some-file.zip', 123)
    fetch.start()
    fetch.wait_for()
    fetch.wait_for()
    fetch.stop()
    fetch.stop()

  @patch('tempfile.mkstemp',
         side_effect=[(321, 'some-file.apks'), (123, 'file2.apk')])
  @patch('bisect-builds.gsutil_download')
  @patch('os.close')
  @patch('os.unlink')
  def test_should_support_multiple_files(self, mock_unlink, mock_close,
                                         mock_gsutil, mock_mkstemp):
    urls = {
        'trichrome':
        ('gs://chrome-unsigned/android-B0urB0N/129.0.6626.0/high-arm_64/'
         'TrichromeChromeGoogle6432Stable.apks'),
        'trichrome_library':
        ('gs://chrome-unsigned/android-B0urB0N/129.0.6626.0/high-arm_64/'
         'TrichromeLibraryGoogle6432Stable.apk'),
    }
    fetch = bisect_builds.DownloadJob(urls, 123)
    result = fetch.start().wait_for()
    fetch.stop()
    self.assertDictEqual(result, {
        'trichrome': 'some-file.apks',
        'trichrome_library': 'file2.apk',
    })
    self.assertEqual(mock_mkstemp.call_count, 2)
    self.assertEqual(mock_close.call_count, 2)
    mock_unlink.assert_has_calls([call('some-file.apks'), call('file2.apk')])
    self.assertEqual(mock_gsutil.call_count, 2)


  @patch(
      "urllib.request.urlopen",
      side_effect=urllib.request.HTTPError('url', 404, 'Not Found', None, None),
  )
  @patch('subprocess.Popen', spec=subprocess.Popen)
  @patch('bisect-builds.GSUTILS_PATH', new='/some/path')
  def test_download_failure_should_raised(self, mock_Popen, mock_urlopen):
    fetch = bisect_builds.DownloadJob('http://some-file.zip', 123)
    with self.assertRaises(urllib.request.HTTPError):
      fetch.start().wait_for()

    mock_Popen.return_value.communicate.return_value = (b'', b'status=403')
    mock_Popen.return_value.returncode = 1
    fetch = bisect_builds.DownloadJob('gs://some-file.zip', 123)
    with self.assertRaises(bisect_builds.BisectException):
      fetch.start().wait_for()


class ArchiveBuildTest(BisectTestCase):

  def setUp(self):
    self.patcher = patch.multiple(
        bisect_builds.ArchiveBuild,
        __abstractmethods__=set(),
        build_type='release',
        _get_rev_list=Mock(return_value=list(map(str, range(10)))),
        _rev_list_cache_key='abc')
    self.patcher.start()

  def tearDown(self):
    self.patcher.stop()

  def create_build(self, *args):
    args = ['-a', 'linux64', '-g', '0', '-b', '9', *args]
    options = bisect_builds.ParseCommandLine(args)
    return bisect_builds.ArchiveBuild(options)

  def test_cache_should_not_work_if_not_enabled(self):
    build = self.create_build('--no-local-cache')
    self.assertFalse(build.use_local_cache)
    with patch('builtins.open') as m:
      self.assertEqual(build.get_rev_list(), [str(x) for x in range(10)])
      bisect_builds.ArchiveBuild._get_rev_list.assert_called_once()
      m.assert_not_called()

  def test_cache_should_save_and_load(self):
    build = self.create_build()
    self.assertTrue(build.use_local_cache)
    # Load the non-existent cache and write to it.
    cached_data = []
    # The cache file would be opened 3 times:
    #   1. read by _load_rev_list_cache
    #   2. read by _save_rev_list_cache for existing cache
    #   3. write by _save_rev_list_cache
    write_mock = MagicMock()
    write_mock.__enter__().write.side_effect = lambda d: cached_data.append(d)
    with patch('builtins.open',
               side_effect=[FileNotFoundError, FileNotFoundError, write_mock]):
      self.assertEqual(build.get_rev_list(), [str(x) for x in range(10)])
      bisect_builds.ArchiveBuild._get_rev_list.assert_called_once()
    cached_json = json.loads(''.join(cached_data))
    self.assertDictEqual(cached_json, {'abc': [str(x) for x in range(10)]})
    # Load cache with cached data.
    build = self.create_build('--use-local-cache')
    bisect_builds.ArchiveBuild._get_rev_list.reset_mock()
    with patch('builtins.open', mock_open(read_data=''.join(cached_data))):
      self.assertEqual(build.get_rev_list(), [str(x) for x in range(10)])
      bisect_builds.ArchiveBuild._get_rev_list.assert_not_called()

  @patch.object(bisect_builds.ArchiveBuild, '_load_rev_list_cache')
  @patch.object(bisect_builds.ArchiveBuild, '_save_rev_list_cache')
  @patch.object(bisect_builds.ArchiveBuild,
                '_get_rev_list',
                return_value=[str(x) for x in range(10)])
  def test_should_request_partial_rev_list(self, mock_get_rev_list,
                                           mock_save_rev_list_cache,
                                           mock_load_rev_list_cache):
    build = self.create_build('--no-local-cache')
    # missing latest
    mock_load_rev_list_cache.return_value = [str(x) for x in range(5)]
    self.assertEqual(build.get_rev_list(), [str(x) for x in range(10)])
    mock_get_rev_list.assert_called_with('4', '9')
    # missing old and latest
    mock_load_rev_list_cache.return_value = [str(x) for x in range(1, 5)]
    self.assertEqual(build.get_rev_list(), [str(x) for x in range(10)])
    mock_get_rev_list.assert_called_with('0', '9')
    # missing old
    mock_load_rev_list_cache.return_value = [str(x) for x in range(3, 10)]
    self.assertEqual(build.get_rev_list(), [str(x) for x in range(10)])
    mock_get_rev_list.assert_called_with('0', '3')
    # no intersect
    mock_load_rev_list_cache.return_value = ['c', 'd', 'e']
    self.assertEqual(build.get_rev_list(), [str(x) for x in range(10)])
    mock_save_rev_list_cache.assert_called_with([str(x) for x in range(10)] +
                                                ['c', 'd', 'e'])
    mock_get_rev_list.assert_called_with('0', 'c')

  @patch.object(bisect_builds.ArchiveBuild, '_get_rev_list', return_value=[])
  def test_should_raise_error_when_no_rev_list(self, mock_get_rev_list):
    build = self.create_build('--no-local-cache')
    with self.assertRaises(bisect_builds.BisectException):
      build.get_rev_list()
    mock_get_rev_list.assert_any_call('0', '9')
    mock_get_rev_list.assert_any_call()

  @unittest.skipIf('NO_MOCK_SERVER' not in os.environ,
                   'The test is to ensure NO_MOCK_SERVER working correctly')
  @maybe_patch('bisect-builds.GetRevisionFromVersion', return_value=123)
  def test_no_mock(self, mock_GetRevisionFromVersion):
    self.assertEqual(bisect_builds.GetRevisionFromVersion('127.0.6533.74'),
                     1313161)
    mock_GetRevisionFromVersion.assert_called()

  @patch('bisect-builds.ArchiveBuild._install_revision')
  @patch('bisect-builds.ArchiveBuild._launch_revision',
         return_value=(1, '', ''))
  def test_run_revision_should_return_early(self, mock_launch_revision,
                                            mock_install_revision):
    build = self.create_build()
    build.run_revision('', '', [])
    mock_launch_revision.assert_called_once()

  @patch('bisect-builds.ArchiveBuild._install_revision')
  @patch('bisect-builds.ArchiveBuild._launch_revision',
         return_value=(0, '', ''))
  def test_run_revision_should_do_all_runs(self, mock_launch_revision,
                                           mock_install_revision):
    build = self.create_build('--time', '10')
    build.run_revision('', '', [])
    self.assertEqual(mock_launch_revision.call_count, 10)

  @patch('bisect-builds.UnzipFilenameToDir')
  @patch('glob.glob', return_value=['temp-dir/linux64/chrome'])
  @patch('os.path.abspath', return_value='/tmp/temp-dir/linux64/chrome')
  def test_install_revision_should_unzip_and_search_executable(
      self, mock_abspath, mock_glob, mock_UnzipFilenameToDir):
    build = self.create_build()
    self.assertEqual(build._install_revision('some-file.zip', 'temp-dir'),
                     {'chrome': '/tmp/temp-dir/linux64/chrome'})
    mock_UnzipFilenameToDir.assert_called_once_with('some-file.zip', 'temp-dir')
    mock_glob.assert_called_once_with('temp-dir/*/chrome')
    mock_abspath.assert_called_once_with('temp-dir/linux64/chrome')

  @patch('bisect-builds.UnzipFilenameToDir')
  @patch('glob.glob',
         side_effect=[['temp-dir/chrome-linux64/chrome'],
                      ['temp-dir/chromedriver_linux64/chromedriver']])
  @patch('os.path.abspath',
         side_effect=[
             '/tmp/temp-dir/chrome-linux64/chrome',
             '/tmp/temp-dir/chromedriver_linux64/chromedriver'
         ])
  def test_install_chromedriver(self, mock_abspath, mock_glob,
                                mock_UnzipFilenameToDir):
    build = self.create_build('--chromedriver')
    self.assertEqual(
        build._install_revision(
            {
                'chrome': 'some-file.zip',
                'chromedriver': 'some-other-file.zip',
            }, 'temp-dir'),
        {
            'chrome': '/tmp/temp-dir/chrome-linux64/chrome',
            'chromedriver': '/tmp/temp-dir/chromedriver_linux64/chromedriver',
        })
    mock_UnzipFilenameToDir.assert_has_calls([
        call('some-file.zip', 'temp-dir'),
        call('some-other-file.zip', 'temp-dir'),
    ])
    mock_glob.assert_has_calls([
        call('temp-dir/*/chrome'),
        call('temp-dir/*/chromedriver'),
    ])
    mock_abspath.assert_has_calls([
        call('temp-dir/chrome-linux64/chrome'),
        call('temp-dir/chromedriver_linux64/chromedriver')
    ])

  @patch('subprocess.Popen', spec=subprocess.Popen)
  def test_launch_revision_should_run_command(self, mock_Popen):
    mock_Popen.return_value.communicate.return_value = ('', '')
    mock_Popen.return_value.returncode = 0
    build = self.create_build()
    build._launch_revision('temp-dir', {'chrome': 'temp-dir/linux64/chrome'},
                           [])
    mock_Popen.assert_called_once_with(
        'temp-dir/linux64/chrome --user-data-dir=temp-dir/profile',
        cwd=None,
        shell=True,
        bufsize=-1,
        stdout=ANY,
        stderr=ANY)

  @unittest.skipIf(sys.platform.startswith('win'), 'This test is not for win')
  @patch('subprocess.Popen', spec=subprocess.Popen)
  def test_launch_revision_should_run_command_for_mac(self, mock_Popen):
    mock_Popen.return_value.communicate.return_value = ('', '')
    mock_Popen.return_value.returncode = 0
    build = self.create_build()
    build._launch_revision(
        'temp-dir', {
            'chrome':
            'temp-dir/full-build-mac/'
            'Google Chrome.app/Contents/MacOS/Google Chrome'
        }, [])
    mock_Popen.assert_called_once_with(
        "'temp-dir/full-build-mac/"
        "Google Chrome.app/Contents/MacOS/Google Chrome'"
        ' --user-data-dir=temp-dir/profile',
        cwd=None,
        shell=True,
        bufsize=-1,
        stdout=ANY,
        stderr=ANY)

  @unittest.skipUnless(sys.platform.startswith('win'),
                       'This test is for win only')
  @patch('subprocess.Popen', spec=subprocess.Popen)
  def test_launch_revision_should_run_command_for_win(self, mock_Popen):
    mock_Popen.return_value.communicate.return_value = ('', '')
    mock_Popen.return_value.returncode = 0
    build = self.create_build()
    build._launch_revision(
        'C:\\temp-dir', {
            'chrome': 'C:\\temp-dir\\full-build-win\\chrome.exe'
        }, [])
    mock_Popen.assert_called_once_with(
        "C:\\temp-dir\\full-build-win\\chrome.exe "
        '--user-data-dir=C:\\temp-dir/profile',
        cwd=None,
        shell=True,
        bufsize=-1,
        stdout=ANY,
        stderr=ANY)

  @patch('subprocess.Popen', spec=subprocess.Popen)
  def test_command_replacement(self, mock_Popen):
    mock_Popen.return_value.communicate.return_value = ('', '')
    mock_Popen.return_value.returncode = 0
    build = self.create_build(
        '--chromedriver', '-c',
        'CHROMEDRIVER=%d BROWSER_EXECUTABLE_PATH=%p pytest %a')
    build._launch_revision('/tmp', {
        'chrome': '/tmp/chrome',
        'chromedriver': '/tmp/chromedriver'
    }, ['--args', '--args2="word 1"', 'word 2'])
    if sys.platform.startswith('win'):
      mock_Popen.assert_called_once_with(
          'CHROMEDRIVER=/tmp/chromedriver BROWSER_EXECUTABLE_PATH=/tmp/chrome '
          'pytest --user-data-dir=/tmp/profile --args "--args2=\\"word 1\\"" '
          '"word 2"',
          cwd=None,
          shell=True,
          bufsize=-1,
          stdout=ANY,
          stderr=ANY)
    else:
      mock_Popen.assert_called_once_with(
          'CHROMEDRIVER=/tmp/chromedriver BROWSER_EXECUTABLE_PATH=/tmp/chrome '
          'pytest --user-data-dir=/tmp/profile --args \'--args2="word 1"\' '
          '\'word 2\'',
          cwd=None,
          shell=True,
          bufsize=-1,
          stdout=ANY,
          stderr=ANY)


class ReleaseBuildTest(BisectTestCase):

  def test_should_look_up_path_context(self):
    options = bisect_builds.ParseCommandLine(
        ['-r', '-a', 'linux64', '-g', '127.0.6533.74', '-b', '127.0.6533.88'])
    self.assertEqual(options.archive, 'linux64')
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.ReleaseBuild)
    self.assertEqual(build.binary_name, 'chrome')
    self.assertEqual(build.listing_platform_dir, 'linux64/')
    self.assertEqual(build.archive_name, 'chrome-linux64.zip')
    self.assertEqual(build.archive_extract_dir, 'chrome-linux64')

  @maybe_patch(
      'bisect-builds.GsutilList',
      return_value=[
          'gs://chrome-unsigned/desktop-5c0tCh/%s/linux64/chrome-linux64.zip' %
          x for x in ['127.0.6533.74', '127.0.6533.75', '127.0.6533.76']
      ])
  def test_get_rev_list(self, mock_GsutilList):
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'linux64', '-g', '127.0.6533.74', '-b', '127.0.6533.76',
        '--no-local-cache'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.ReleaseBuild)
    self.assertEqual(build.get_rev_list(),
                     ['127.0.6533.74', '127.0.6533.75', '127.0.6533.76'])
    mock_GsutilList.assert_any_call('gs://chrome-unsigned/desktop-5c0tCh')
    mock_GsutilList.assert_any_call(*[
        'gs://chrome-unsigned/desktop-5c0tCh/%s/linux64/chrome-linux64.zip' % x
        for x in ['127.0.6533.74', '127.0.6533.75', '127.0.6533.76']
    ],
                                    ignore_fail=True)
    self.assertEqual(mock_GsutilList.call_count, 2)

  @patch('bisect-builds.GsutilList',
         return_value=['127.0.6533.74', '127.0.6533.75', '127.0.6533.76'])
  def test_should_save_and_load_cache(self, mock_GsutilList):
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'linux64', '-g', '127.0.6533.74', '-b', '127.0.6533.77',
        '--use-local-cache'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.ReleaseBuild)
    # Load the non-existent cache and write to it.
    cached_data = []
    write_mock = MagicMock()
    write_mock.__enter__().write.side_effect = lambda d: cached_data.append(d)
    with patch('builtins.open',
               side_effect=[FileNotFoundError, FileNotFoundError, write_mock]):
      self.assertEqual(build.get_rev_list(),
                       ['127.0.6533.74', '127.0.6533.75', '127.0.6533.76'])
      mock_GsutilList.assert_called()
    cached_json = json.loads(''.join(cached_data))
    self.assertDictEqual(
        cached_json, {
            build._rev_list_cache_key:
            ['127.0.6533.74', '127.0.6533.75', '127.0.6533.76']
        })
    # Load cache with cached data and merge with new data
    mock_GsutilList.return_value = ['127.0.6533.76', '127.0.6533.77']
    build = bisect_builds.create_archive_build(options)
    with patch('builtins.open', mock_open(read_data=''.join(cached_data))):
      self.assertEqual(
          build.get_rev_list(),
          ['127.0.6533.74', '127.0.6533.75', '127.0.6533.76', '127.0.6533.77'])
    print(mock_GsutilList.call_args)
    mock_GsutilList.assert_any_call(
        'gs://chrome-unsigned/desktop-5c0tCh'
        '/127.0.6533.76/linux64/chrome-linux64.zip',
        'gs://chrome-unsigned/desktop-5c0tCh'
        '/127.0.6533.77/linux64/chrome-linux64.zip',
        ignore_fail=True)

  def test_get_download_url(self):
    options = bisect_builds.ParseCommandLine(
        ['-r', '-a', 'linux64', '-g', '127.0.6533.74', '-b', '127.0.6533.77'])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.ReleaseBuild)
    download_urls = build.get_download_url('127.0.6533.74')
    self.assertEqual(
        download_urls, 'gs://chrome-unsigned/desktop-5c0tCh'
        '/127.0.6533.74/linux64/chrome-linux64.zip')

    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'linux64', '-g', '127.0.6533.74', '-b', '127.0.6533.77',
        '--chromedriver'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.ReleaseBuild)
    download_urls = build.get_download_url('127.0.6533.74')
    self.assertEqual(
        download_urls, {
            'chrome':
            'gs://chrome-unsigned/desktop-5c0tCh'
            '/127.0.6533.74/linux64/chrome-linux64.zip',
            'chromedriver':
            'gs://chrome-unsigned/desktop-5c0tCh'
            '/127.0.6533.74/linux64/chromedriver_linux64.zip',
        })

  @unittest.skipUnless('NO_MOCK_SERVER' in os.environ,
                       'The test only valid when NO_MOCK_SERVER')
  @patch('bisect-builds.ArchiveBuild._run', return_value=(0, 'stdout', ''))
  def test_run_revision_with_real_zipfile(self, mock_run):
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'linux64', '-g', '127.0.6533.74', '-b', '127.0.6533.77',
        '--chromedriver', '-c', 'driver=%d prog=%p'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.ReleaseBuild)
    download_job = build.get_download_job('127.0.6533.74')
    zip_file = download_job.start().wait_for()
    with tempfile.TemporaryDirectory(prefix='bisect_tmp') as tempdir:
      build.run_revision(zip_file, tempdir, [])
    self.assertRegex(mock_run.call_args.args[0],
                     r'driver=.+/chromedriver prog=.+/chrome')


class ArchiveBuildWithCommitPositionTest(BisectTestCase):

  def setUp(self):
    patch.multiple(bisect_builds.ArchiveBuildWithCommitPosition,
                   __abstractmethods__=set(),
                   build_type='release').start()

  @maybe_patch('bisect-builds.GetRevisionFromVersion', return_value=1313161)
  @maybe_patch('bisect-builds.GetChromiumRevision', return_value=999999999)
  def test_should_convert_revision_as_commit_position(
      self, mock_GetChromiumRevision, mock_GetRevisionFromVersion):
    options = bisect_builds.ParseCommandLine(
        ['-a', 'linux64', '-g', '127.0.6533.74'])
    build = bisect_builds.ArchiveBuildWithCommitPosition(options)
    self.assertEqual(build.good_revision, 1313161)
    self.assertEqual(build.bad_revision, 999999999)
    mock_GetRevisionFromVersion.assert_called_once_with('127.0.6533.74')
    mock_GetChromiumRevision.assert_called()


class OfficialBuildTest(BisectTestCase):

  def test_should_lookup_path_context(self):
    options = bisect_builds.ParseCommandLine(
        ['-o', '-a', 'linux64', '-g', '0', '-b', '10'])
    self.assertEqual(options.archive, 'linux64')
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.OfficialBuild)
    self.assertEqual(build.binary_name, 'chrome')
    self.assertEqual(build.listing_platform_dir, 'linux-builder-perf/')
    self.assertEqual(build.archive_name, 'chrome-perf-linux.zip')
    self.assertEqual(build.archive_extract_dir, 'full-build-linux')

  @maybe_patch('bisect-builds.GsutilList',
               return_value=[
                   'full-build-linux_%d.zip' % x
                   for x in range(1313161, 1313164)
               ])
  def test_get_rev_list(self, mock_GsutilList):
    options = bisect_builds.ParseCommandLine([
        '-o', '-a', 'linux64', '-g', '1313161', '-b', '1313163',
        '--no-local-cache'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.OfficialBuild)
    self.assertEqual(build.get_rev_list(), list(range(1313161, 1313164)))
    mock_GsutilList.assert_called_once_with(
        'gs://chrome-test-builds/official-by-commit/linux-builder-perf/')

  @unittest.skipUnless('NO_MOCK_SERVER' in os.environ,
                       'The test only valid when NO_MOCK_SERVER')
  @patch('bisect-builds.ArchiveBuild._run', return_value=(0, 'stdout', ''))
  def test_run_revision_with_real_zipfile(self, mock_run):
    options = bisect_builds.ParseCommandLine([
        '-o', '-a', 'linux64', '-g', '1313161', '-b', '1313163',
        '--chromedriver', '-c', 'driver=%d prog=%p'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.OfficialBuild)
    download_job = build.get_download_job(1334339)
    zip_file = download_job.start().wait_for()
    with tempfile.TemporaryDirectory(prefix='bisect_tmp') as tempdir:
      build.run_revision(zip_file, tempdir, [])
    self.assertRegex(mock_run.call_args.args[0],
                     r'driver=.+/chromedriver prog=.+/chrome')

class SnapshotBuildTest(BisectTestCase):

  def test_should_lookup_path_context(self):
    options = bisect_builds.ParseCommandLine(
        ['-a', 'linux64', '-g', '0', '-b', '10'])
    self.assertEqual(options.archive, 'linux64')
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.SnapshotBuild)
    self.assertEqual(build.binary_name, 'chrome')
    self.assertEqual(build.listing_platform_dir, 'Linux_x64/')
    self.assertEqual(build.archive_name, 'chrome-linux.zip')
    self.assertEqual(build.archive_extract_dir, 'chrome-linux')

  CommonDataXMLContent = '''<?xml version='1.0' encoding='UTF-8'?>
    <ListBucketResult xmlns='http://doc.s3.amazonaws.com/2006-03-01'>
      <Name>chromium-browser-snapshots</Name>
      <Prefix>Linux_x64/</Prefix>
      <Marker></Marker>
      <NextMarker></NextMarker>
      <Delimiter>/</Delimiter>
      <IsTruncated>true</IsTruncated>
      <CommonPrefixes>
        <Prefix>Linux_x64/1313161/</Prefix>
      </CommonPrefixes>
      <CommonPrefixes>
        <Prefix>Linux_x64/1313163/</Prefix>
      </CommonPrefixes>
      <CommonPrefixes>
        <Prefix>Linux_x64/1313185/</Prefix>
      </CommonPrefixes>
    </ListBucketResult>
  '''

  @maybe_patch('urllib.request.urlopen',
               return_value=io.BytesIO(CommonDataXMLContent.encode('utf8')))
  @patch('bisect-builds.GetChromiumRevision', return_value=1313185)
  def test_get_rev_list(self, mock_GetChromiumRevision, mock_urlopen):
    options = bisect_builds.ParseCommandLine(
        ['-a', 'linux64', '-g', '1313161', '-b', '1313185', '--no-local-cache'])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.SnapshotBuild)
    rev_list = build.get_rev_list()
    mock_urlopen.assert_any_call(
        'http://commondatastorage.googleapis.com/chromium-browser-snapshots/'
        '?delimiter=/&prefix=Linux_x64/&marker=Linux_x64/1313161')
    self.assertEqual(mock_urlopen.call_count, 1)
    self.assertEqual(rev_list, [1313161, 1313163, 1313185])

  @patch('bisect-builds.SnapshotBuild._fetch_and_parse',
         return_value=([int(s)
                        for s in sorted([str(x) for x in range(1, 11)])], None))
  def test_get_rev_list_should_start_from_a_marker(self, mock_fetch_and_parse):
    options = bisect_builds.ParseCommandLine(
        ['-a', 'linux64', '-g', '0', '-b', '9', '--no-local-cache'])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.SnapshotBuild)
    rev_list = build._get_rev_list(0, 9)
    self.assertEqual(rev_list, list(range(1, 10)))
    mock_fetch_and_parse.assert_called_once_with(
        'http://commondatastorage.googleapis.com/chromium-browser-snapshots/'
        '?delimiter=/&prefix=Linux_x64/&marker=Linux_x64/0')
    mock_fetch_and_parse.reset_mock()
    rev_list = build._get_rev_list(1, 9)
    self.assertEqual(rev_list, list(range(1, 10)))
    mock_fetch_and_parse.assert_called_once_with(
        'http://commondatastorage.googleapis.com/chromium-browser-snapshots/'
        '?delimiter=/&prefix=Linux_x64/&marker=Linux_x64/1')

  @patch('bisect-builds.SnapshotBuild._fetch_and_parse',
         return_value=([int(s)
                        for s in sorted([str(x) for x in range(1, 11)])], None))
  def test_get_rev_list_should_scan_all_pages(self, mock_fetch_and_parse):
    options = bisect_builds.ParseCommandLine(
        ['-a', 'linux64', '-g', '3', '-b', '11', '--no-local-cache'])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.SnapshotBuild)
    rev_list = build._get_rev_list(0, 11)
    self.assertEqual(sorted(rev_list), list(range(1, 11)))
    mock_fetch_and_parse.assert_called_once_with(
        'http://commondatastorage.googleapis.com/chromium-browser-snapshots/'
        '?delimiter=/&prefix=Linux_x64/')

  def test_get_download_url(self):
    options = bisect_builds.ParseCommandLine(
        ['-a', 'linux64', '-g', '3', '-b', '11'])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.SnapshotBuild)
    download_urls = build.get_download_url(123)
    self.assertEqual(
        download_urls,
        'http://commondatastorage.googleapis.com/chromium-browser-snapshots'
        '/Linux_x64/123/chrome-linux.zip',
    )

    options = bisect_builds.ParseCommandLine(
        ['-a', 'linux64', '-g', '3', '-b', '11', '--chromedriver'])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.SnapshotBuild)
    download_urls = build.get_download_url(123)
    self.assertDictEqual(
        download_urls, {
            'chrome':
            'http://commondatastorage.googleapis.com/chromium-browser-snapshots'
            '/Linux_x64/123/chrome-linux.zip',
            'chromedriver':
            'http://commondatastorage.googleapis.com/chromium-browser-snapshots'
            '/Linux_x64/123/chromedriver_linux64.zip'
        })

  @unittest.skipUnless('NO_MOCK_SERVER' in os.environ,
                       'The test only valid when NO_MOCK_SERVER')
  @patch('bisect-builds.ArchiveBuild._run', return_value=(0, 'stdout', ''))
  def test_run_revision_with_real_zipfile(self, mock_run):
    options = bisect_builds.ParseCommandLine([
        '-a', 'linux64', '-g', '1313161', '-b', '1313185', '--chromedriver',
        '-c', 'driver=%d prog=%p'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.SnapshotBuild)
    download_job = build.get_download_job(1313161)
    zip_file = download_job.start().wait_for()
    with tempfile.TemporaryDirectory(prefix='bisect_tmp') as tempdir:
      build.run_revision(zip_file, tempdir, [])
    self.assertRegex(mock_run.call_args.args[0],
                     r'driver=.+/chromedriver prog=.+/chrome')

  @patch('bisect-builds.GetChromiumRevision', return_value=1313185)
  def test_get_bad_revision(self, mock_GetChromiumRevision):
    options = bisect_builds.ParseCommandLine(['-a', 'linux64', '-g', '1313161'])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.SnapshotBuild)
    mock_GetChromiumRevision.assert_called_once_with(
        'http://commondatastorage.googleapis.com/chromium-browser-snapshots'
        '/Linux_x64/LAST_CHANGE')
    self.assertEqual(build.bad_revision, 1313185)


class ChromeForTestingBuild(BisectTestCase):

  def test_should_lookup_path_context(self):
    options = bisect_builds.ParseCommandLine(
        ['-cft', '-a', 'linux64', '-g', '0', '-b', '10'])
    self.assertEqual(options.archive, 'linux64')
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.ChromeForTestingBuild)
    self.assertEqual(build.binary_name, 'chrome')
    self.assertEqual(build.listing_platform_dir, 'linux64/')
    self.assertEqual(build.archive_name, 'chrome-linux64.zip')
    self.assertEqual(build.chromedriver_binary_name, 'chromedriver')
    self.assertEqual(build.chromedriver_archive_name,
                     'chromedriver-linux64.zip')

  CommonDataXMLContent = '''<?xml version='1.0' encoding='UTF-8'?>
  <ListBucketResult xmlns="http://doc.s3.amazonaws.com/2006-03-01">
    <Name>chrome-for-testing-per-commit-public</Name>
    <Prefix>linux64/</Prefix>
    <Marker/>
    <Delimiter>/</Delimiter>
    <IsTruncated>false</IsTruncated>
    <Contents>
      <Key>linux64/LAST_CHANGE</Key>
      <Generation>1733959087133532</Generation>
      <MetaGeneration>1</MetaGeneration>
      <LastModified>2024-12-11T23:18:07.235Z</LastModified>
      <ETag>"dd60cb93e225ab33d7254beca56b507a"</ETag>
      <Size>7</Size>
    </Contents>
    <CommonPrefixes>
      <Prefix>linux64/r1390729/</Prefix>
    </CommonPrefixes>
    <CommonPrefixes>
      <Prefix>linux64/r1390746/</Prefix>
    </CommonPrefixes>
    <CommonPrefixes>
      <Prefix>linux64/r1390757/</Prefix>
    </CommonPrefixes>
  </ListBucketResult>
  '''

  @maybe_patch('urllib.request.urlopen',
               return_value=io.BytesIO(CommonDataXMLContent.encode('utf8')))
  @patch('bisect-builds.GetChromiumRevision', return_value=1390757)
  def test_get_rev_list(self, mock_GetChromiumRevision, mock_urlopen):
    options = bisect_builds.ParseCommandLine([
        '-cft', '-a', 'linux64', '-g', '1390729', '-b', '1390757',
        '--no-local-cache'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.ChromeForTestingBuild)
    rev_list = build.get_rev_list()
    mock_urlopen.assert_any_call(
        'https://storage.googleapis.com/chrome-for-testing-per-commit-public/'
        '?delimiter=/&prefix=linux64/&marker=linux64/r1390729')
    self.assertEqual(mock_urlopen.call_count, 1)
    self.assertEqual(rev_list, [1390729, 1390746, 1390757])

  def test_get_marker(self):
    options = bisect_builds.ParseCommandLine(
        ['-cft', '-a', 'linux64', '-g', '1', '-b', '3'])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.ChromeForTestingBuild)
    self.assertEqual('linux64/r1390729',
                     build._get_marker_for_revision(1390729))

  def test_get_download_url(self):
    options = bisect_builds.ParseCommandLine(
        ['-cft', '-a', 'linux64', '-g', '3', '-b', '11'])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.ChromeForTestingBuild)
    download_urls = build.get_download_url(123)
    self.assertEqual(
        download_urls,
        'https://storage.googleapis.com/chrome-for-testing-per-commit-public'
        '/linux64/r123/chrome-linux64.zip',
    )

    options = bisect_builds.ParseCommandLine(
        ['-cft', '-a', 'linux64', '-g', '3', '-b', '11', '--chromedriver'])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.ChromeForTestingBuild)
    download_urls = build.get_download_url(123)
    download_urls = build.get_download_url(123)
    self.assertEqual(
        download_urls, {
            'chrome':
            'https://storage.googleapis.com/chrome-for-testing-per-commit-public'
            '/linux64/r123/chrome-linux64.zip',
            'chromedriver':
            'https://storage.googleapis.com/chrome-for-testing-per-commit-public'
            '/linux64/r123/chromedriver-linux64.zip',
        })

  @patch('bisect-builds.GetChromiumRevision', return_value=1390757)
  def test_get_bad_revision(self, mock_GetChromiumRevision):
    options = bisect_builds.ParseCommandLine(
        ['-cft', '-a', 'linux64', '-g', '3'])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.ChromeForTestingBuild)
    mock_GetChromiumRevision.assert_called_once_with(
        'https://storage.googleapis.com/chrome-for-testing-per-commit-public'
        '/linux64/LAST_CHANGE')
    self.assertEqual(build.bad_revision, 1390757)

  @unittest.skipUnless('NO_MOCK_SERVER' in os.environ,
                       'The test only valid when NO_MOCK_SERVER')
  @patch('bisect-builds.ArchiveBuild._run', return_value=(0, 'stdout', ''))
  def test_run_revision_with_real_zipfile(self, mock_run):
    options = bisect_builds.ParseCommandLine([
        '--cft', '-a', 'linux64', '-g', '1', '--chromedriver', '-c',
        'driver=%d prog=%p'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.SnapshotBuild)
    download_job = build.get_download_job(build.bad_revision)
    zip_file = download_job.start().wait_for()
    with tempfile.TemporaryDirectory(prefix='bisect_tmp') as tempdir:
      build.run_revision(zip_file, tempdir, [])
    self.assertRegex(mock_run.call_args.args[0],
                     r'driver=.+/chromedriver prog=.+/chrome')


class ASANBuildTest(BisectTestCase):

  CommonDataXMLContent = '''<?xml version='1.0' encoding='UTF-8'?>
    <ListBucketResult xmlns='http://doc.s3.amazonaws.com/2006-03-01'>
      <Name>chromium-browser-asan</Name>
      <Prefix>mac-release/asan-mac-release</Prefix>
      <Marker></Marker>
      <NextMarker></NextMarker>
      <Delimiter>.zip</Delimiter>
      <IsTruncated>true</IsTruncated>
      <CommonPrefixes>
        <Prefix>mac-release/asan-mac-release-1313186.zip</Prefix>
      </CommonPrefixes>
      <CommonPrefixes>
        <Prefix>mac-release/asan-mac-release-1313195.zip</Prefix>
      </CommonPrefixes>
      <CommonPrefixes>
        <Prefix>mac-release/asan-mac-release-1313210.zip</Prefix>
      </CommonPrefixes>
    </ListBucketResult>
  '''

  @maybe_patch('urllib.request.urlopen',
               return_value=io.BytesIO(CommonDataXMLContent.encode('utf8')))
  def test_get_rev_list(self, mock_urlopen):
    options = bisect_builds.ParseCommandLine([
        '--asan', '-a', 'mac', '-g', '1313161', '-b', '1313210',
        '--no-local-cache'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.ASANBuild)
    rev_list = build.get_rev_list()
    # print(mock_urlopen.call_args_list)
    mock_urlopen.assert_any_call(
        'http://commondatastorage.googleapis.com/chromium-browser-asan/'
        '?delimiter=.zip&prefix=mac-release/asan-mac-release'
        '&marker=mac-release/asan-mac-release-1313161.zip')
    self.assertEqual(mock_urlopen.call_count, 1)
    self.assertEqual(rev_list, [1313186, 1313195, 1313210])


class AndroidBuildTest(BisectTestCase):

  def setUp(self):
    # patch for devil_imports
    self.patchers = []
    flag_changer_patcher = maybe_patch('bisect-builds.flag_changer',
                                       create=True)
    self.patchers.append(flag_changer_patcher)
    self.mock_flag_changer = flag_changer_patcher.start()
    chrome_patcher = maybe_patch('bisect-builds.chrome', create=True)
    self.patchers.append(chrome_patcher)
    self.mock_chrome = chrome_patcher.start()
    version_codes_patcher = maybe_patch('bisect-builds.version_codes',
                                        create=True)
    self.patchers.append(version_codes_patcher)
    self.mock_version_codes = version_codes_patcher.start()
    self.mock_version_codes.LOLLIPOP = 21
    self.mock_version_codes.NOUGAT = 24
    self.mock_version_codes.PIE = 28
    self.mock_version_codes.Q = 29
    initial_android_device_patcher = patch(
        'bisect-builds.InitializeAndroidDevice')
    self.patchers.append(initial_android_device_patcher)
    self.mock_initial_android_device = initial_android_device_patcher.start()
    self.device = self.mock_initial_android_device.return_value
    self.set_sdk_level(bisect_builds.version_codes.Q)

  def set_sdk_level(self, level):
    self.device.build_version_sdk = level

  def tearDown(self):
    for patcher in self.patchers:
      patcher.stop()


class AndroidReleaseBuildTest(AndroidBuildTest):

  def setUp(self):
    super().setUp()
    self.set_sdk_level(bisect_builds.version_codes.PIE)

  @maybe_patch(
      'bisect-builds.GsutilList',
      return_value=[
          'gs://chrome-signed/android-B0urB0N/%s/arm_64/MonochromeStable.apk' %
          x for x in ['127.0.6533.76', '127.0.6533.78', '127.0.6533.79']
      ])
  def test_get_android_rev_list(self, mock_GsutilList):
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'android-arm64', '--apk', 'chrome_stable', '-g',
        '127.0.6533.76', '-b', '127.0.6533.79', '--signed', '--no-local-cache'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.AndroidReleaseBuild)
    self.assertEqual(build.get_rev_list(),
                     ['127.0.6533.76', '127.0.6533.78', '127.0.6533.79'])
    mock_GsutilList.assert_any_call('gs://chrome-signed/android-B0urB0N')
    mock_GsutilList.assert_any_call(*[
        'gs://chrome-signed/android-B0urB0N/%s/arm_64/MonochromeStable.apk' % x
        for x in ['127.0.6533.76', '127.0.6533.78', '127.0.6533.79']
    ],
                                    ignore_fail=True)
    self.assertEqual(mock_GsutilList.call_count, 2)

  @patch('bisect-builds.InstallOnAndroid')
  def test_install_revision(self, mock_InstallOnAndroid):
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'android-arm64', '-g', '127.0.6533.76', '-b',
        '127.0.6533.79', '--apk', 'chrome'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.AndroidReleaseBuild)
    build._install_revision('chrome.apk', 'temp-dir')
    mock_InstallOnAndroid.assert_called_once_with(self.device, 'chrome.apk')

  @patch('bisect-builds.LaunchOnAndroid')
  def test_launch_revision(self, mock_LaunchOnAndroid):
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'android-arm64', '-g', '127.0.6533.76', '-b',
        '127.0.6533.79', '--apk', 'chrome'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.AndroidReleaseBuild)
    build._launch_revision('temp-dir', None)
    mock_LaunchOnAndroid.assert_called_once_with(self.device, 'chrome')

  @patch('bisect-builds.LaunchOnAndroid')
  def test_webview_launch_revision(self, mock_LaunchOnAndroid):
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'android-arm64', '-g', '127.0.6533.76', '-b',
        '127.0.6533.79', '--apk', 'system_webview'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.AndroidReleaseBuild)
    build._launch_revision('temp-dir', None)
    mock_LaunchOnAndroid.assert_called_once_with(self.device, 'system_webview')
    with self.assertRaises(bisect_builds.BisectException):
      build._launch_revision('temp-dir', None, ['args'])


class AndroidSnapshotBuildTest(AndroidBuildTest):

  def setUp(self):
    super().setUp()
    self.set_sdk_level(bisect_builds.version_codes.PIE)

  @patch('bisect-builds.UnzipFilenameToDir')
  @patch('bisect-builds.InstallOnAndroid')
  @patch('glob.glob', return_value=['Monochrome.apk'])
  def test_install_revision(self, mock_glob, mock_InstallOnAndroid, mock_unzip):
    options = bisect_builds.ParseCommandLine([
        '-a', 'android-arm64', '-g', '1313161', '-b', '1313210', '--apk',
        'chrome'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.AndroidSnapshotBuild)
    build._install_revision('chrome.zip', 'temp-dir')
    mock_glob.assert_called_once_with('temp-dir/*/apks/Monochrome.apk')
    mock_InstallOnAndroid.assert_called_once_with(self.device, 'Monochrome.apk')

  @patch('bisect-builds.UnzipFilenameToDir')
  @patch('sys.stdout', new_callable=io.StringIO)
  @patch('glob.glob',
         side_effect=[[],
                      [
                          "temp-dir/full-build-linux/apks/MonochromeBeta.apk",
                          "temp-dir/full-build-linux/apks/ChromePublic.apk"
                      ]])
  def test_install_revision_with_show_available_apks(self, mock_glob,
                                                     mock_stdout, mock_unzip):
    options = bisect_builds.ParseCommandLine([
        '-a', 'android-arm64', '-g', '1313161', '-b', '1313210', '--apk',
        'chrome'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.AndroidSnapshotBuild)
    with self.assertRaises(bisect_builds.BisectException):
      build._install_revision('chrome.zip', 'temp-dir')
    self.assertIn("The list of available --apk:", mock_stdout.getvalue())
    self.assertIn("chrome_beta", mock_stdout.getvalue())
    self.assertIn("chromium", mock_stdout.getvalue())

  @patch('bisect-builds.UnzipFilenameToDir')
  @patch('sys.stdout', new_callable=io.StringIO)
  @patch('glob.glob',
         side_effect=[[], ["temp-dir/full-build-linux/apks/unknown.apks"]])
  def test_install_revision_with_show_unknown_apks(self, mock_glob, mock_stdout,
                                                   mock_unzip):
    options = bisect_builds.ParseCommandLine([
        '-a', 'android-arm64', '-g', '1313161', '-b', '1313210', '--apk',
        'chrome'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.AndroidSnapshotBuild)
    with self.assertRaises(bisect_builds.BisectException):
      build._install_revision('chrome.zip', 'temp-dir')
    self.assertIn("No supported apk found. But found following",
                  mock_stdout.getvalue())
    self.assertIn("unknown.apks", mock_stdout.getvalue())

class AndroidTrichromeReleaseBuildTest(AndroidBuildTest):

  def setUp(self):
    super().setUp()
    self.set_sdk_level(bisect_builds.version_codes.Q)

  @maybe_patch(
      'bisect-builds.GsutilList',
      side_effect=[[
          'gs://chrome-unsigned/android-B0urB0N/%s/' % x for x in [
              '129.0.6626.0', '129.0.6626.1', '129.0.6627.0', '129.0.6627.1',
              '129.0.6628.0', '129.0.6628.1'
          ]
      ],
                   [('gs://chrome-unsigned/android-B0urB0N/%s/'
                     'high-arm_64/TrichromeChromeGoogle6432Stable.apks') % x
                    for x in ['129.0.6626.0', '129.0.6627.0', '129.0.6628.0']]])
  def test_get_rev_list(self, mock_GsutilList):
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'android-arm64-high', '--apk', 'chrome_stable', '-g',
        '129.0.6626.0', '-b', '129.0.6628.0', '--no-local-cache'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.AndroidTrichromeReleaseBuild)
    self.assertEqual(build.get_rev_list(),
                     ['129.0.6626.0', '129.0.6627.0', '129.0.6628.0'])
    print(mock_GsutilList.call_args_list)
    mock_GsutilList.assert_any_call('gs://chrome-unsigned/android-B0urB0N')
    mock_GsutilList.assert_any_call(*[
        ('gs://chrome-unsigned/android-B0urB0N/%s/'
         'high-arm_64/TrichromeChromeGoogle6432Stable.apks') % x for x in [
             '129.0.6626.0', '129.0.6626.1', '129.0.6627.0', '129.0.6627.1',
             '129.0.6628.0'
         ]
    ],
                                    ignore_fail=True)
    self.assertEqual(mock_GsutilList.call_count, 2)

  def test_should_raise_exception_for_PIE(self):
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'android-arm64-high', '--apk', 'chrome_stable', '-g',
        '129.0.6626.0', '-b', '129.0.6667.0'
    ])
    self.set_sdk_level(bisect_builds.version_codes.PIE)
    with self.assertRaises(bisect_builds.BisectException):
      bisect_builds.create_archive_build(options)

  def test_get_download_url(self):
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'android-arm64-high', '--apk', 'chrome_stable', '-g',
        '129.0.6626.0', '-b', '129.0.6628.0'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.AndroidTrichromeReleaseBuild)
    download_urls = build.get_download_url('129.0.6626.0')
    self.maxDiff = 1000
    self.assertDictEqual(
        download_urls, {
            'trichrome':
            ('gs://chrome-unsigned/android-B0urB0N/129.0.6626.0/high-arm_64/'
             'TrichromeChromeGoogle6432Stable.apks'),
            'trichrome_library':
            ('gs://chrome-unsigned/android-B0urB0N/129.0.6626.0/high-arm_64/'
             'TrichromeLibraryGoogle6432Stable.apk'),
        })

  @patch('bisect-builds.InstallOnAndroid')
  def test_install_revision(self, mock_InstallOnAndroid):
    downloads = {
        'trichrome': 'some-file.apks',
        'trichrome_library': 'file2.apk',
    }
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'android-arm64-high', '--apk', 'chrome_stable', '-g',
        '129.0.6626.0', '-b', '129.0.6628.0'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.AndroidTrichromeReleaseBuild)
    build._install_revision(downloads, 'tmp-dir')
    mock_InstallOnAndroid.assert_any_call(self.device, 'some-file.apks')
    mock_InstallOnAndroid.assert_any_call(self.device, 'file2.apk')


class AndroidTrichromeOfficialBuildTest(AndroidBuildTest):

  @maybe_patch('bisect-builds.GsutilList',
               return_value=[
                   'full-build-linux_%d.zip' % x
                   for x in [1334339, 1334342, 1334344, 1334345, 1334356]
               ])
  def test_get_rev_list(self, mock_GsutilList):
    options = bisect_builds.ParseCommandLine([
        '-o', '-a', 'android-arm64-high', '--apk', 'chrome', '-g', '1334338',
        '-b', '1334380', '--no-local-cache'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.AndroidTrichromeOfficialBuild)
    self.assertEqual(build.get_rev_list(),
                     [1334339, 1334342, 1334344, 1334345, 1334356])
    mock_GsutilList.assert_called_once_with(
        'gs://chrome-test-builds/official-by-commit/'
        'android_arm64_high_end-builder-perf/')

  def test_get_download_url(self):
    options = bisect_builds.ParseCommandLine([
        '-o', '-a', 'android-arm64-high', '--apk', 'chrome', '-g', '1334338',
        '-b', '1334380'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.AndroidTrichromeOfficialBuild)
    self.assertEqual(
        build.get_download_url(1334338),
        'gs://chrome-test-builds/official-by-commit'
        '/android_arm64_high_end-builder-perf/full-build-linux_1334338.zip')

  @patch('glob.glob',
         side_effect=[[
             'temp-dir/full-build-linux/apks/TrichromeChromeGoogle6432.apks'
         ], ['temp-dir/full-build-linux/apks/TrichromeLibraryGoogle6432.apk']])
  @patch('bisect-builds.UnzipFilenameToDir')
  @patch('bisect-builds.InstallOnAndroid')
  def test_install_revision(self, mock_InstallOnAndroid,
                            mock_UnzipFilenameToDir, mock_glob):
    options = bisect_builds.ParseCommandLine([
        '-o', '-a', 'android-arm64-high', '--apk', 'chrome', '-g', '1334338',
        '-b', '1334380'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.AndroidTrichromeOfficialBuild)
    build._install_revision('download.zip', 'tmp-dir')
    mock_UnzipFilenameToDir.assert_called_once_with('download.zip', 'tmp-dir')
    mock_InstallOnAndroid.assert_any_call(
        self.device,
        'temp-dir/full-build-linux/apks/TrichromeLibraryGoogle6432.apk')
    mock_InstallOnAndroid.assert_any_call(
        self.device,
        'temp-dir/full-build-linux/apks/TrichromeChromeGoogle6432.apks')

  @patch('sys.stdout', new_callable=io.StringIO)
  @patch('glob.glob',
         side_effect=[[],
                      ['temp-dir/TrichromeChromeGoogle6432Canary.minimal.apks']
                      ])
  @patch('bisect-builds.UnzipFilenameToDir')
  def test_install_revision_with_show_available_apks(self,
                                                     mock_UnzipFilenameToDir,
                                                     mock_glob, mock_stdout):
    options = bisect_builds.ParseCommandLine([
        '-o', '-a', 'android-arm64-high', '--apk', 'chrome', '-g', '1334338',
        '-b', '1334380'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.AndroidTrichromeOfficialBuild)
    with self.assertRaises(bisect_builds.BisectException):
      build._install_revision('download.zip', 'tmp-dir')
    self.assertIn("The list of available --apk:", mock_stdout.getvalue())
    self.assertIn("chrome_canary", mock_stdout.getvalue())

  @unittest.skipUnless('NO_MOCK_SERVER' in os.environ,
                       'The test only valid when NO_MOCK_SERVER')
  @patch('bisect-builds.InstallOnAndroid')
  @patch('bisect-builds.LaunchOnAndroid')
  def test_run_revision_with_real_zipfile(self, mock_LaunchOnAndroid,
                                          mock_InstallOnAndroid):
    options = bisect_builds.ParseCommandLine([
        '-o', '-a', 'android-arm64-high', '--apk', 'chrome', '-g', '1334338',
        '-b', '1334380'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.AndroidTrichromeOfficialBuild)
    download_job = build.get_download_job(1334339)
    zip_file = download_job.start().wait_for()
    with tempfile.TemporaryDirectory(prefix='bisect_tmp') as tempdir:
      build.run_revision(zip_file, tempdir, [])
    print(mock_InstallOnAndroid.call_args_list)
    self.assertRegex(mock_InstallOnAndroid.mock_calls[0].args[1],
                     'full-build-linux/apks/TrichromeLibraryGoogle6432.apk$')
    self.assertRegex(
        mock_InstallOnAndroid.mock_calls[1].args[1],
        'full-build-linux/apks/TrichromeChromeGoogle6432.minimal.apks$')
    mock_LaunchOnAndroid.assert_called_once_with(self.device, 'chrome')


class LinuxReleaseBuildTest(BisectTestCase):

  @patch('subprocess.Popen', spec=subprocess.Popen)
  def test_launch_revision_should_has_no_sandbox(self, mock_Popen):
    mock_Popen.return_value.communicate.return_value = ('', '')
    mock_Popen.return_value.returncode = 0
    options = bisect_builds.ParseCommandLine(
        ['-r', '-a', 'linux64', '-g', '127.0.6533.74', '-b', '127.0.6533.88'])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.LinuxReleaseBuild)
    build._launch_revision('temp-dir', {'chrome': 'temp-dir/linux64/chrome'},
                           [])
    mock_Popen.assert_called_once_with(
        'temp-dir/linux64/chrome --user-data-dir=temp-dir/profile --no-sandbox',
        cwd=None,
        shell=True,
        bufsize=-1,
        stdout=ANY,
        stderr=ANY)


class IOSReleaseBuildTest(BisectTestCase):

  @maybe_patch(
      'bisect-builds.GsutilList',
      side_effect=[[
          'gs://chrome-unsigned/ios-G1N/127.0.6533.76/',
          'gs://chrome-unsigned/ios-G1N/127.0.6533.77/',
          'gs://chrome-unsigned/ios-G1N/127.0.6533.78/'
      ],
                   [
                       'gs://chrome-unsigned/ios-G1N'
                       '/127.0.6533.76/iphoneos17.5/ios/10863/canary.ipa',
                       'gs://chrome-unsigned/ios-G1N'
                       '/127.0.6533.77/iphoneos17.5/ios/10866/canary.ipa',
                       'gs://chrome-unsigned/ios-G1N'
                       '/127.0.6533.78/iphoneos17.5/ios/10868/canary.ipa'
                   ]])
  def test_list_rev(self, mock_GsutilList):
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'ios', '--ipa=canary.ipa', '--device-id', '321', '-g',
        '127.0.6533.74', '-b', '127.0.6533.78', '--no-local-cache'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.IOSReleaseBuild)
    self.assertEqual(build.get_rev_list(),
                     ['127.0.6533.76', '127.0.6533.77', '127.0.6533.78'])
    mock_GsutilList.assert_any_call('gs://chrome-unsigned/ios-G1N')
    mock_GsutilList.assert_any_call(*[
        'gs://chrome-unsigned/ios-G1N/%s/*/ios/*/canary.ipa' % x
        for x in ['127.0.6533.76', '127.0.6533.77', '127.0.6533.78']
    ],
                                    ignore_fail=True)

  @patch('bisect-builds.UnzipFilenameToDir')
  @patch('glob.glob', return_value=['Payload/canary.app/Info.plist'])
  @patch('subprocess.Popen', spec=subprocess.Popen)
  def test_install_revision(self, mock_Popen, mock_glob,
                            mock_UnzipFilenameToDir):
    mock_Popen.return_value.communicate.return_value = ('', '')
    mock_Popen.return_value.returncode = 0
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'ios', '--ipa=canary.ipa', '--device-id', '321', '-g',
        '127.0.6533.74', '-b', '127.0.6533.78'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.IOSReleaseBuild)
    build._install_revision('canary.ipa', 'tempdir')
    mock_glob.assert_called_once_with('tempdir/Payload/*/Info.plist')
    mock_Popen.assert_has_calls([
        call([
            'xcrun', 'devicectl', 'device', 'install', 'app', '--device', '321',
            'canary.ipa'
        ],
             cwd=None,
             shell=False,
             bufsize=-1,
             stdout=-1,
             stderr=-1),
        call([
            'plutil', '-extract', 'CFBundleIdentifier', 'raw',
            'Payload/canary.app/Info.plist'
        ],
             cwd=None,
             shell=False,
             bufsize=-1,
             stdout=-1,
             stderr=-1)
    ],
                                any_order=True)

  @patch('subprocess.Popen', spec=subprocess.Popen)
  def test_launch_revision(self, mock_Popen):
    mock_Popen.return_value.communicate.return_value = ('', '')
    mock_Popen.return_value.returncode = 0
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'ios', '--ipa=canary.ipa', '--device-id', '321', '-g',
        '127.0.6533.74', '-b', '127.0.6533.78', '--', 'args1', 'args2'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.IOSReleaseBuild)
    build._launch_revision('tempdir', 'com.google.chrome.ios', options.args)
    mock_Popen.assert_any_call([
        'xcrun', 'devicectl', 'device', 'process', 'launch', '--device', '321',
        'com.google.chrome.ios', 'args1', 'args2'
    ],
                               cwd=None,
                               shell=False,
                               bufsize=-1,
                               stdout=-1,
                               stderr=-1)

  @unittest.skipUnless('NO_MOCK_SERVER' in os.environ,
                       'The test only valid when NO_MOCK_SERVER')
  @patch('bisect-builds.ArchiveBuild._run', return_value=(0, 'stdout', ''))
  def test_run_revision(self, mock_run):
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'ios', '--ipa=canary.ipa', '--device-id', '321', '-g',
        '127.0.6533.74', '-b', '127.0.6533.78'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.IOSReleaseBuild)
    job = build.get_download_job('127.0.6533.76')
    ipa = job.start().wait_for()
    with tempfile.TemporaryDirectory(prefix='bisect_tmp') as tempdir:
      build.run_revision(ipa, tempdir, options.args)
    mock_run.assert_has_calls([
        call([
            'xcrun', 'devicectl', 'device', 'install', 'app', '--device', '321',
            ANY
        ]),
        call(['plutil', '-extract', 'CFBundleIdentifier', 'raw', ANY]),
        call([
            'xcrun', 'devicectl', 'device', 'process', 'launch', '--device',
            '321', 'stdout'
        ])
    ])


class IOSSimulatorReleaseBuildTest(BisectTestCase):

  @maybe_patch(
      'bisect-builds.GsutilList',
      side_effect=[
          [
              'gs://bling-archive/128.0.6534.0/',
              'gs://bling-archive/128.0.6534.1/',
              'gs://bling-archive/128.0.6535.0/',
              'gs://bling-archive/128.0.6535.1/',
              'gs://bling-archive/128.0.6536.0/',
          ],
          [
              'gs://bling-archive/128.0.6534.0/20240612011643/Chromium.tar.gz',
              'gs://bling-archive/128.0.6536.0/20240613011356/Chromium.tar.gz',
          ]
      ])
  @patch('bisect-builds.ArchiveBuild._run', return_value=(0, '', ''))
  def test_list_rev(self, mock_run, mock_GsutilList):
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'ios-simulator', '--device-id', '321', '-g', '128.0.6534.0',
        '-b', '128.0.6536.0', '--no-local-cache'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.IOSSimulatorReleaseBuild)
    self.assertEqual(build.get_rev_list(), ['128.0.6534.0', '128.0.6536.0'])
    mock_run.assert_called_once_with(['xcrun', 'simctl', 'boot', '321'])
    mock_GsutilList.assert_any_call('gs://bling-archive')
    mock_GsutilList.assert_any_call(*[
        'gs://bling-archive/%s/*/Chromium.tar.gz' % x for x in [
            '128.0.6534.0', '128.0.6534.1', '128.0.6535.0', '128.0.6535.1',
            '128.0.6536.0'
        ]
    ],
                                    ignore_fail=True)

  @patch('bisect-builds.UnzipFilenameToDir')
  @patch('glob.glob', return_value=['Info.plist'])
  @patch('bisect-builds.ArchiveBuild._run', return_value=(0, '', ''))
  def test_install_revision(self, mock_run, mock_glob, mock_UnzipFilenameToDir):
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'ios-simulator', '--device-id', '321', '-g', '128.0.6534.0',
        '-b', '128.0.6539.0'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.IOSSimulatorReleaseBuild)
    build._install_revision('Chromium.tar.gz', 'tempdir')
    mock_UnzipFilenameToDir.assert_called_once_with('Chromium.tar.gz',
                                                    'tempdir')
    self.assertEqual(mock_glob.call_count, 2)
    mock_run.assert_has_calls([
        call(['xcrun', 'simctl', 'boot', '321']),
        call(['xcrun', 'simctl', 'install', '321', ANY]),
        call(['plutil', '-extract', 'CFBundleIdentifier', 'raw', 'Info.plist']),
    ])

  @patch('bisect-builds.ArchiveBuild._run', return_value=(0, '', ''))
  def test_launch_revision(self, mock_run):
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'ios-simulator', '--device-id', '321', '-g', '128.0.6534.0',
        '-b', '128.0.6539.0'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.IOSSimulatorReleaseBuild)
    build._launch_revision('tempdir', 'com.google.chrome.ios.dev',
                           ['args1', 'args2'])
    mock_run.assert_any_call([
        'xcrun', 'simctl', 'launch', '321', 'com.google.chrome.ios.dev',
        'args1', 'args2'
    ])

  @unittest.skipUnless('NO_MOCK_SERVER' in os.environ,
                       'The test only valid when NO_MOCK_SERVER')
  @patch('bisect-builds.ArchiveBuild._run', return_value=(0, 'stdout', ''))
  def test_run_revision(self, mock_run):
    options = bisect_builds.ParseCommandLine([
        '-r', '-a', 'ios-simulator', '--device-id', '321', '-g', '128.0.6534.0',
        '-b', '128.0.6539.0'
    ])
    build = bisect_builds.create_archive_build(options)
    self.assertIsInstance(build, bisect_builds.IOSSimulatorReleaseBuild)
    job = build.get_download_job('128.0.6534.0')
    download = job.start().wait_for()
    with tempfile.TemporaryDirectory(prefix='bisect_tmp') as tempdir:
      build.run_revision(download, tempdir, options.args)
    mock_run.assert_has_calls([
        call(['xcrun', 'simctl', 'boot', '321']),
        call(['xcrun', 'simctl', 'install', '321', ANY]),
        call(['plutil', '-extract', 'CFBundleIdentifier', 'raw', ANY]),
        call(['xcrun', 'simctl', 'launch', '321', 'stdout'])
    ])


class MaybeSwitchBuildTypeTest(BisectTestCase):

  def test_generate_new_command_without_cache(self):
    command_line = [
        '-r', '-a', 'linux64', '-g', '127.0.6533.74', '-b', '127.0.6533.88',
        '--no-local-cache'
    ]
    options = bisect_builds.ParseCommandLine(command_line)
    with patch('sys.argv', ['bisect-builds.py', *command_line]):
      new_cmd = bisect_builds.MaybeSwitchBuildType(
          options, bisect_builds.ChromiumVersion('127.0.6533.74'),
          bisect_builds.ChromiumVersion('127.0.6533.88'))
      self.assertEqual(new_cmd[1:], [
          '-o', '-a', 'linux64', '-g', '127.0.6533.74', '-b', '127.0.6533.88',
          '--verify-range', '--no-local-cache'
      ])

  def test_android_signed_with_args(self):
    command_line = [
        '-r', '--archive=android-arm64-high', '--good=127.0.6533.74', '-b',
        '127.0.6533.88', '--apk=chrome', '--signed', '--no-local-cache', '--',
        'args1', '--args2'
    ]
    options = bisect_builds.ParseCommandLine(command_line)
    with patch('sys.argv', ['bisect-builds.py', *command_line]):
      new_cmd = bisect_builds.MaybeSwitchBuildType(options, '127.0.6533.74',
                                                   '127.0.6533.88')
      self.assertEqual(new_cmd[1:], [
          '-o', '-a', 'android-arm64-high', '-g', '127.0.6533.74', '-b',
          '127.0.6533.88', '--verify-range', '--apk=chrome', '--no-local-cache',
          '--', 'args1', '--args2'
      ])

  def test_no_official_build(self):
    command_line = [
        '-r', '-a', 'ios', '--ipa=canary.ipa', '--device-id', '321', '-g',
        '127.0.6533.74', '-b', '127.0.6533.78', '--no-local-cache'
    ]
    options = bisect_builds.ParseCommandLine(command_line)
    with patch('sys.argv', ['bisect-builds.py', *command_line]):
      new_cmd = bisect_builds.MaybeSwitchBuildType(options, '127.0.6533.74',
                                                   '127.0.6533.88')
      self.assertEqual(new_cmd, None)

  @patch('bisect-builds.ArchiveBuild.get_rev_list', return_value=list(range(3)))
  def test_generate_suggestion_with_cache(self, mock_get_rev_list):
    command_line = [
        '-r', '-a', 'linux64', '-g', '127.0.6533.74', '-b', '127.0.6533.88',
        '--use-local-cache'
    ]
    options = bisect_builds.ParseCommandLine(command_line)
    with patch('sys.argv', ['bisect-builds.py', *command_line]):
      new_cmd = bisect_builds.MaybeSwitchBuildType(options, '127.0.6533.74',
                                                   '127.0.6533.88')
      self.assertEqual(new_cmd[1:], [
          '-o', '-a', 'linux64', '-g', '127.0.6533.74', '-b', '127.0.6533.88',
          '--verify-range', '--use-local-cache'
      ])
      mock_get_rev_list.assert_called()


class MethodTest(BisectTestCase):

  @patch('sys.stderr', new_callable=io.StringIO)
  def test_ParseCommandLine(self, mock_stderr):
    opts = bisect_builds.ParseCommandLine(
        ['-a', 'linux64', '-g', '1', 'args1', 'args2 3', '-b', '2'])
    self.assertEqual(opts.build_type, 'snapshot')
    self.assertEqual(opts.args, ['args1', 'args2 3'])

    opts = bisect_builds.ParseCommandLine(
        ['-a', 'linux64', '-g', '1', 'args1', 'args2 3'])
    self.assertEqual(opts.args, ['args1', 'args2 3'])

    opts = bisect_builds.ParseCommandLine(
        ['-a', 'linux64', '-g', '1', '--', 'args1', 'args2 3', '-b', '2'])
    self.assertEqual(opts.args, ['args1', 'args2 3', '-b', '2'])

    with self.assertRaises(SystemExit):
      bisect_builds.ParseCommandLine(['-a', 'mac64', '-o', '-g', '1'])
      self.assertRegexpMatches(
          mock_stderr.getvalue(), r'To bisect for mac64, please choose from '
          r'release(-r), snapshot(-s)')

  @patch('bisect-builds._DetectArchive', return_value='linux64')
  def test_ParseCommandLine_DetectArchive(self, mock_detect_archive):
    opts = bisect_builds.ParseCommandLine(['-o', '-g', '1'])
    self.assertEqual(opts.archive, 'linux64')

  def test_ParseCommandLine_default_apk(self):
    opts = bisect_builds.ParseCommandLine(
        ['-o', '-a', 'android-arm', '-g', '1'])
    self.assertEqual(opts.apk, 'chrome')

    opts = bisect_builds.ParseCommandLine(['-a', 'android-arm64', '-g', '1'])
    self.assertEqual(opts.apk, 'chromium')

  def test_ParseCommandLine_default_ipa(self):
    opts = bisect_builds.ParseCommandLine(
        ['-r', '-a', 'ios', '-g', '127.0.6533.74', '-b', '127.0.6533.88'])
    self.assertEqual(opts.ipa, 'canary')

  def test_ParseCommandLine_DetectArchive_with_apk(self):
    opts = bisect_builds.ParseCommandLine(['-o', '--apk', 'chrome', '-g', '1'])
    self.assertEqual(opts.archive, 'android-arm64')

  def test_ParseCommandLine_DetectArchive_with_ipa(self):
    opts = bisect_builds.ParseCommandLine(
        ['-r', '--ipa', 'stable', '-g', '127.0.6533.74', '-b', '127.0.6533.88'])
    self.assertEqual(opts.archive, 'ios-simulator')

  @patch('sys.stderr', new_callable=io.StringIO)
  def test_ParseCommandLine_apk_error(self, mock_stderr):
    with self.assertRaises(SystemExit):
      bisect_builds.ParseCommandLine(
          ['-a', 'linux64', '--apk', 'chrome', '-g', '1'])
    self.assertIn('--apk is only supported', mock_stderr.getvalue())

  @patch('sys.stderr', new_callable=io.StringIO)
  def test_ParseCommandLine_ipa_error(self, mock_stderr):
    with self.assertRaises(SystemExit):
      bisect_builds.ParseCommandLine(
          ['-a', 'linux64', '--ipa', 'stable', '-g', '1'])
    self.assertIn('--ipa is only supported', mock_stderr.getvalue())

  @patch('sys.stderr', new_callable=io.StringIO)
  def test_ParseCommandLine_signed_error(self, mock_stderr):
    with self.assertRaises(SystemExit):
      bisect_builds.ParseCommandLine(['-a', 'linux64', '--signed', '-g', '1'])
    self.assertIn('--signed is only supported', mock_stderr.getvalue())

  @patch('urllib.request.urlopen')
  @patch('builtins.open')
  @patch('sys.stdout', new_callable=io.StringIO)
  def test_update_script(self, mock_stdout, mock_open, mock_urlopen):
    mock_urlopen.return_value = io.BytesIO(
        base64.b64encode('content'.encode('utf-8')))
    with self.assertRaises(SystemExit):
      bisect_builds.ParseCommandLine(['--update-script'])
    mock_urlopen.assert_called_once_with(
        'https://chromium.googlesource.com/chromium/src/+/HEAD/'
        'tools/bisect-builds.py?format=TEXT')
    mock_open.assert_called_once()
    mock_open.return_value.__enter__().write.assert_called_once_with('content')
    self.assertEqual(mock_stdout.getvalue(), 'Update successful!\n')

  @patch("urllib.request.urlopen",
         side_effect=[
             urllib.request.HTTPError('url', 404, 'Not Found', None, None),
             urllib.request.HTTPError('url', 404, 'Not Found', None, None),
             io.BytesIO(b"NOT_A_JSON"),
             io.BytesIO(b'{"chromium_main_branch_position": 123}'),
         ])
  def test_GetRevisionFromVersion(self, mock_urlopen):
    self.assertEqual(123,
                     bisect_builds.GetRevisionFromVersion('127.0.6533.134'))
    mock_urlopen.assert_has_calls([
        call('https://chromiumdash.appspot.com/fetch_version'
             '?version=127.0.6533.134'),
        call('https://chromiumdash.appspot.com/fetch_version'
             '?version=127.0.6533.0'),
    ])

  @maybe_patch("urllib.request.urlopen",
               side_effect=[
                   io.BytesIO(b'{"chromium_main_branch_position": null}'),
                   io.BytesIO(b'{"message": "DEP\\n"}'),
                   io.BytesIO(b')]}\'\n{"message": "Cr-Branched-From: '
                              b'3d60439cfb36485e76a1c5bb7f513d3721b20da1-'
                              b'refs/heads/master@{#870763}\\n"}'),
               ])
  def test_GetRevisionFromSourceTag(self, mock_urlopen):
    self.assertEqual(870763,
                     bisect_builds.GetRevisionFromVersion('91.0.4472.38'))
    mock_urlopen.assert_has_calls([
        call('https://chromiumdash.appspot.com/fetch_version'
             '?version=91.0.4472.38'),
        call('https://chromium.googlesource.com/chromium/src/'
             '+/refs/tags/91.0.4472.38?format=JSON'),
        call('https://chromium.googlesource.com/chromium/src/'
             '+/refs/tags/91.0.4472.38^?format=JSON'),
    ])

  def test_join_args(self):
    test_data = ['a', 'b c', 'C:\\a b\\c', '/a b/c', '"a"', "'a'"]
    quoted_command = bisect_builds.join_args(
        [sys.executable, '-c', 'import sys, json; print(json.dumps(sys.argv))']
        + test_data)

    subproc = subprocess.Popen(
        quoted_command, shell=True, stdout=subprocess.PIPE)
    stdout, _ = subproc.communicate()
    dumped_argv = json.loads(stdout.decode('utf-8'))

    self.assertListEqual(dumped_argv, ['-c'] + test_data)


class ChromiumVersionTest(BisectTestCase):
  def test_cmpare_version_numbers(self):
    v127_0_6533_74 = bisect_builds.ChromiumVersion('127.0.6533.74')
    v127_0_6533_75 = bisect_builds.ChromiumVersion('127.0.6533.75')
    v127_0_6533_75_with_space = bisect_builds.ChromiumVersion('127.0.6533.75 ')
    v127 = bisect_builds.ChromiumVersion('127')

    self.assertLess(v127_0_6533_74, v127_0_6533_75)
    self.assertLessEqual(v127_0_6533_74, v127_0_6533_75)
    self.assertGreater(v127_0_6533_75, v127_0_6533_74)
    self.assertGreaterEqual(v127_0_6533_75, v127_0_6533_74)
    self.assertEqual(v127_0_6533_75, v127_0_6533_75_with_space)
    self.assertLess(v127, v127_0_6533_74)

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