Avi Drissman | dfd88085 | 2022-09-15 20:11:09 | [diff] [blame] | 1 | # Copyright 2012 The Chromium Authors |
enne@chromium.org | eadd95d | 2012-11-02 22:42:09 | [diff] [blame] | 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
| 4 | |
Kuan Huang | 342fec5 | 2024-10-31 18:00:44 | [diff] [blame] | 5 | import base64 |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 6 | import functools |
Kuan Huang | c8dd77a | 2024-08-12 22:13:42 | [diff] [blame] | 7 | import io |
| 8 | import json |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 9 | import os |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 10 | import re |
cjamcl@google.com | fb61fc3 | 2019-04-18 19:47:20 | [diff] [blame] | 11 | import subprocess |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 12 | import sys |
Kuan Huang | c2fec79 | 2024-09-03 21:57:38 | [diff] [blame] | 13 | import tempfile |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 14 | import unittest |
Kuan Huang | c93ac26 | 2024-09-19 18:53:17 | [diff] [blame] | 15 | import urllib.request |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 16 | from unittest.mockimport(ANY,Mock,MagicMock, mock_open, patch, call, |
| 17 | PropertyMock) |
enne@chromium.org | eadd95d | 2012-11-02 22:42:09 | [diff] [blame] | 18 | |
| 19 | bisect_builds= __import__('bisect-builds') |
| 20 | |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 21 | if'NO_MOCK_SERVER'notin os.environ: |
| 22 | maybe_patch= patch |
| 23 | else: |
| 24 | # SetupEnvironment for gsutil to connect to real server. |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 25 | options= bisect_builds.ParseCommandLine(['-a','linux64','-g','1']) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 26 | bisect_builds.SetupEnvironment(options) |
Kuan Huang | c63de40 | 2024-08-12 22:15:27 | [diff] [blame] | 27 | bisect_builds.SetupAndroidEnvironment() |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 28 | |
| 29 | # Mock object that always wraps for the spec. |
| 30 | # This will pass the call through and ignore the return_value and side_effect. |
| 31 | classWrappedMock(MagicMock): |
| 32 | |
| 33 | def __init__(self, |
| 34 | spec=None, |
| 35 | return_value=None, |
| 36 | side_effect=None, |
| 37 | *args, |
| 38 | **kwargs): |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 39 | wraps= kwargs.pop('wraps', spec) |
| 40 | super().__init__(spec,*args,**kwargs, wraps=wraps) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 41 | |
| 42 | maybe_patch= functools.partial(patch, spec=True, new_callable=WrappedMock) |
Kuan Huang | c8dd77a | 2024-08-12 22:13:42 | [diff] [blame] | 43 | maybe_patch.object= functools.partial(patch.object, |
| 44 | spec=True, |
| 45 | new_callable=WrappedMock) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 46 | |
enne@chromium.org | eadd95d | 2012-11-02 22:42:09 | [diff] [blame] | 47 | |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 48 | classBisectTestCase(unittest.TestCase): |
| 49 | |
| 50 | @classmethod |
| 51 | def setUpClass(cls): |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 52 | # Patch the name pattern for pkgutil to accept "bisect-builds" as module |
| 53 | # name. |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 54 | if sys.version_info[:2]>(3,8): |
| 55 | dotted_words= r'(?!\d)([\w-]+)(\.(?!\d)(\w+))*' |
| 56 | name_pattern= re.compile( |
| 57 | f'^(?P<pkg>{dotted_words})' |
| 58 | f'(?P<cln>:(?P<obj>{dotted_words})?)?$', re.UNICODE) |
| 59 | cls.name_pattern_patcher= patch('pkgutil._NAME_PATTERN', name_pattern) |
| 60 | cls.name_pattern_patcher.start() |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 61 | |
Ben Joyce | c634f81 | 2024-09-19 20:13:07 | [diff] [blame] | 62 | # patch cache filename to prevent pollute working dir. |
| 63 | fd, cls.tmp_cache_file= tempfile.mkstemp(suffix='.json') |
| 64 | os.close(fd) |
| 65 | cls.cache_filename_patcher= patch( |
| 66 | 'bisect-builds.ArchiveBuild._rev_list_cache_filename', |
| 67 | new=PropertyMock(return_value=cls.tmp_cache_file)) |
| 68 | cls.cache_filename_patcher.start() |
| 69 | |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 70 | @classmethod |
| 71 | def tearDownClass(cls): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 72 | if sys.version_info[:2]>(3,8): |
| 73 | cls.name_pattern_patcher.stop() |
| 74 | cls.cache_filename_patcher.stop() |
| 75 | os.unlink(cls.tmp_cache_file) |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 76 | |
| 77 | |
| 78 | classBisectTest(BisectTestCase): |
enne@chromium.org | eadd95d | 2012-11-02 22:42:09 | [diff] [blame] | 79 | |
enne@chromium.org | eadd95d | 2012-11-02 22:42:09 | [diff] [blame] | 80 | max_rev=10000 |
enne@chromium.org | eadd95d | 2012-11-02 22:42:09 | [diff] [blame] | 81 | |
Kuan Huang | c2fec79 | 2024-09-03 21:57:38 | [diff] [blame] | 82 | def setUp(self): |
| 83 | self.patchers=[] |
| 84 | self.patchers.append(patch('bisect-builds.DownloadJob._fetch')) |
| 85 | self.patchers.append( |
| 86 | patch('bisect-builds.ArchiveBuild.run_revision', |
| 87 | return_value=(0,'',''))) |
| 88 | self.patchers.append( |
| 89 | patch('bisect-builds.SnapshotBuild._get_rev_list', |
| 90 | return_value=range(self.max_rev))) |
| 91 | for eachin self.patchers: |
| 92 | each.start() |
| 93 | |
| 94 | def tearDown(self): |
| 95 | for eachin self.patchers: |
| 96 | each.stop() |
| 97 | |
cjamcl@google.com | fb61fc3 | 2019-04-18 19:47:20 | [diff] [blame] | 98 | def bisect(self, good_rev, bad_rev, evaluate, num_runs=1): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 99 | options= bisect_builds.ParseCommandLine([ |
| 100 | '-a','linux64','-g', |
| 101 | str(good_rev),'-b', |
| 102 | str(bad_rev),'--times', |
| 103 | str(num_runs),'--no-local-cache' |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 104 | ]) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 105 | archive_build= bisect_builds.create_archive_build(options) |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 106 | (minrev, maxrev)= bisect_builds.Bisect(archive_build=archive_build, |
| 107 | evaluate=evaluate, |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 108 | try_args=options.args) |
cjamcl@google.com | fb61fc3 | 2019-04-18 19:47:20 | [diff] [blame] | 109 | return(minrev, maxrev) |
enne@chromium.org | eadd95d | 2012-11-02 22:42:09 | [diff] [blame] | 110 | |
Kuan Huang | 008965f9 | 2024-10-08 21:53:15 | [diff] [blame] | 111 | @patch('builtins.print') |
| 112 | def testBisectConsistentAnswer(self, mock_print): |
| 113 | |
| 114 | def get_steps(): |
| 115 | steps=[] |
| 116 | for callin mock_print.call_args_list: |
| 117 | if call.argsand call.args[0].startswith('You have'): |
| 118 | steps.append(int(re.search(r'(\d+) steps', call.args[0])[1])) |
| 119 | return steps |
| 120 | |
enne@chromium.org | eadd95d | 2012-11-02 22:42:09 | [diff] [blame] | 121 | self.assertEqual(self.bisect(1000,100,lambda*args:'g'),(100,101)) |
Kuan Huang | 008965f9 | 2024-10-08 21:53:15 | [diff] [blame] | 122 | self.assertSequenceEqual(get_steps(), range(10,1,-1)) |
| 123 | |
| 124 | mock_print.reset_mock() |
enne@chromium.org | eadd95d | 2012-11-02 22:42:09 | [diff] [blame] | 125 | self.assertEqual(self.bisect(100,1000,lambda*args:'b'),(100,101)) |
Kuan Huang | 008965f9 | 2024-10-08 21:53:15 | [diff] [blame] | 126 | self.assertSequenceEqual(get_steps(), range(10,0,-1)) |
| 127 | |
| 128 | mock_print.reset_mock() |
enne@chromium.org | eadd95d | 2012-11-02 22:42:09 | [diff] [blame] | 129 | self.assertEqual(self.bisect(2000,200,lambda*args:'b'),(1999,2000)) |
Kuan Huang | 008965f9 | 2024-10-08 21:53:15 | [diff] [blame] | 130 | self.assertSequenceEqual(get_steps(), range(11,0,-1)) |
| 131 | |
| 132 | mock_print.reset_mock() |
enne@chromium.org | eadd95d | 2012-11-02 22:42:09 | [diff] [blame] | 133 | self.assertEqual(self.bisect(200,2000,lambda*args:'g'),(1999,2000)) |
Kuan Huang | 008965f9 | 2024-10-08 21:53:15 | [diff] [blame] | 134 | self.assertSequenceEqual(get_steps(), range(11,1,-1)) |
enne@chromium.org | eadd95d | 2012-11-02 22:42:09 | [diff] [blame] | 135 | |
Kuan Huang | c2fec79 | 2024-09-03 21:57:38 | [diff] [blame] | 136 | @patch('bisect-builds.ArchiveBuild.run_revision', return_value=(0,'','')) |
| 137 | def test_bisect_should_retry(self, mock_run_revision): |
| 138 | evaluator=Mock(side_effect='rgrgrbr') |
| 139 | self.assertEqual(self.bisect(9,1, evaluator),(2,3)) |
| 140 | tested_revisions=[c.args[0]for cin evaluator.call_args_list] |
| 141 | self.assertEqual(tested_revisions,[5,5,3,3,2,2]) |
| 142 | self.assertEqual(mock_run_revision.call_count,6) |
| 143 | |
| 144 | evaluator=Mock(side_effect='rgrrrgrbr') |
| 145 | self.assertEqual(self.bisect(1,10, evaluator),(8,9)) |
| 146 | tested_revisions=[c.args[0]for cin evaluator.call_args_list] |
| 147 | self.assertEqual(tested_revisions,[6,6,8,8,8,8,9,9]) |
| 148 | |
| 149 | def test_bisect_should_unknown(self): |
| 150 | evaluator=Mock(side_effect='uuuggggg') |
| 151 | self.assertEqual(self.bisect(9,1, evaluator),(1,2)) |
| 152 | tested_revisions=[c.args[0]for cin evaluator.call_args_list] |
| 153 | self.assertEqual(tested_revisions,[5,3,6,7,2]) |
| 154 | |
| 155 | evaluator=Mock(side_effect='uuugggggg') |
| 156 | self.assertEqual(self.bisect(1,9, evaluator),(8,9)) |
| 157 | tested_revisions=[c.args[0]for cin evaluator.call_args_list] |
| 158 | self.assertEqual(tested_revisions,[5,7,4,3,8]) |
| 159 | |
| 160 | def test_bisect_should_quit(self): |
| 161 | evaluator=Mock(side_effect=SystemExit()) |
| 162 | with self.assertRaises(SystemExit): |
| 163 | self.assertEqual(self.bisect(9,1, evaluator),(None,None)) |
| 164 | |
| 165 | def test_edge_cases(self): |
| 166 | with self.assertRaises(bisect_builds.BisectException): |
| 167 | self.assertEqual(self.bisect(1,1,Mock()),(1,1)) |
| 168 | self.assertEqual(self.bisect(2,1,Mock()),(1,2)) |
| 169 | self.assertEqual(self.bisect(1,2,Mock()),(1,2)) |
| 170 | |
Kuan Huang | 8b5e33dc | 2024-08-15 17:51:24 | [diff] [blame] | 171 | |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 172 | classDownloadJobTest(BisectTestCase): |
Kuan Huang | 8b5e33dc | 2024-08-15 17:51:24 | [diff] [blame] | 173 | |
| 174 | @patch('bisect-builds.gsutil_download') |
| 175 | def test_fetch_gsutil(self, mock_gsutil_download): |
| 176 | fetch= bisect_builds.DownloadJob('gs://some-file.zip',123) |
| 177 | fetch.start() |
| 178 | fetch.wait_for() |
| 179 | mock_gsutil_download.assert_called_once() |
| 180 | |
| 181 | @patch('urllib.request.urlretrieve') |
| 182 | def test_fetch_http(self, mock_urlretrieve): |
| 183 | fetch= bisect_builds.DownloadJob('http://some-file.zip',123) |
| 184 | fetch.start() |
| 185 | fetch.wait_for() |
| 186 | mock_urlretrieve.assert_called_once() |
| 187 | |
| 188 | @patch('tempfile.mkstemp', return_value=(321,'some-file.zip')) |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 189 | @patch('urllib.request.urlretrieve') |
Kuan Huang | 8b5e33dc | 2024-08-15 17:51:24 | [diff] [blame] | 190 | @patch('os.close') |
| 191 | @patch('os.unlink') |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 192 | def test_should_del(self, mock_unlink, mock_close, mock_urlretrieve, |
| 193 | mock_mkstemp): |
Kuan Huang | 8b5e33dc | 2024-08-15 17:51:24 | [diff] [blame] | 194 | fetch= bisect_builds.DownloadJob('http://some-file.zip',123) |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 195 | fetch.start().wait_for() |
| 196 | fetch.stop() |
Kuan Huang | 8b5e33dc | 2024-08-15 17:51:24 | [diff] [blame] | 197 | mock_mkstemp.assert_called_once() |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 198 | mock_close.assert_called_once() |
| 199 | mock_urlretrieve.assert_called_once() |
| 200 | mock_unlink.assert_called_with('some-file.zip') |
Kuan Huang | 8b5e33dc | 2024-08-15 17:51:24 | [diff] [blame] | 201 | |
| 202 | @patch('urllib.request.urlretrieve') |
| 203 | def test_stop_wait_for_should_be_able_to_reenter(self, mock_urlretrieve): |
| 204 | fetch= bisect_builds.DownloadJob('http://some-file.zip',123) |
| 205 | fetch.start() |
| 206 | fetch.wait_for() |
| 207 | fetch.wait_for() |
| 208 | fetch.stop() |
| 209 | fetch.stop() |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 210 | |
| 211 | @patch('tempfile.mkstemp', |
| 212 | side_effect=[(321,'some-file.apks'),(123,'file2.apk')]) |
| 213 | @patch('bisect-builds.gsutil_download') |
| 214 | @patch('os.close') |
| 215 | @patch('os.unlink') |
| 216 | def test_should_support_multiple_files(self, mock_unlink, mock_close, |
| 217 | mock_gsutil, mock_mkstemp): |
| 218 | urls={ |
| 219 | 'trichrome': |
| 220 | ('gs://chrome-unsigned/android-B0urB0N/129.0.6626.0/high-arm_64/' |
| 221 | 'TrichromeChromeGoogle6432Stable.apks'), |
| 222 | 'trichrome_library': |
| 223 | ('gs://chrome-unsigned/android-B0urB0N/129.0.6626.0/high-arm_64/' |
| 224 | 'TrichromeLibraryGoogle6432Stable.apk'), |
| 225 | } |
| 226 | fetch= bisect_builds.DownloadJob(urls,123) |
| 227 | result= fetch.start().wait_for() |
Kuan Huang | 8b5e33dc | 2024-08-15 17:51:24 | [diff] [blame] | 228 | fetch.stop() |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 229 | self.assertDictEqual(result,{ |
| 230 | 'trichrome':'some-file.apks', |
| 231 | 'trichrome_library':'file2.apk', |
| 232 | }) |
| 233 | self.assertEqual(mock_mkstemp.call_count,2) |
| 234 | self.assertEqual(mock_close.call_count,2) |
Ben Joyce | 3c940d3 | 2025-02-12 19:31:52 | [diff] [blame] | 235 | mock_unlink.assert_has_calls( |
| 236 | [call('some-file.apks'), call('file2.apk')], any_order=True) |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 237 | self.assertEqual(mock_gsutil.call_count,2) |
cjamcl@google.com | fb61fc3 | 2019-04-18 19:47:20 | [diff] [blame] | 238 | |
enne@chromium.org | eadd95d | 2012-11-02 22:42:09 | [diff] [blame] | 239 | |
Kuan Huang | c3a4cd1e | 2024-10-03 21:17:31 | [diff] [blame] | 240 | @patch( |
| 241 | "urllib.request.urlopen", |
| 242 | side_effect=urllib.request.HTTPError('url',404,'Not Found',None,None), |
| 243 | ) |
| 244 | @patch('subprocess.Popen', spec=subprocess.Popen) |
| 245 | @patch('bisect-builds.GSUTILS_PATH', new='/some/path') |
| 246 | def test_download_failure_should_raised(self, mock_Popen, mock_urlopen): |
| 247 | fetch= bisect_builds.DownloadJob('http://some-file.zip',123) |
| 248 | with self.assertRaises(urllib.request.HTTPError): |
| 249 | fetch.start().wait_for() |
| 250 | |
| 251 | mock_Popen.return_value.communicate.return_value=(b'', b'status=403') |
| 252 | mock_Popen.return_value.returncode=1 |
| 253 | fetch= bisect_builds.DownloadJob('gs://some-file.zip',123) |
| 254 | with self.assertRaises(bisect_builds.BisectException): |
| 255 | fetch.start().wait_for() |
| 256 | |
| 257 | |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 258 | classArchiveBuildTest(BisectTestCase): |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 259 | |
| 260 | def setUp(self): |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 261 | self.patcher= patch.multiple( |
| 262 | bisect_builds.ArchiveBuild, |
| 263 | __abstractmethods__=set(), |
| 264 | build_type='release', |
| 265 | _get_rev_list=Mock(return_value=list(map(str, range(10)))), |
| 266 | _rev_list_cache_key='abc') |
| 267 | self.patcher.start() |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 268 | |
| 269 | def tearDown(self): |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 270 | self.patcher.stop() |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 271 | |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 272 | def create_build(self,*args): |
| 273 | args=['-a','linux64','-g','0','-b','9',*args] |
| 274 | options= bisect_builds.ParseCommandLine(args) |
Kuan Huang | c8dd77a | 2024-08-12 22:13:42 | [diff] [blame] | 275 | return bisect_builds.ArchiveBuild(options) |
| 276 | |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 277 | def test_cache_should_not_work_if_not_enabled(self): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 278 | build= self.create_build('--no-local-cache') |
Kuan Huang | c8dd77a | 2024-08-12 22:13:42 | [diff] [blame] | 279 | self.assertFalse(build.use_local_cache) |
| 280 | with patch('builtins.open')as m: |
| 281 | self.assertEqual(build.get_rev_list(),[str(x)for xin range(10)]) |
| 282 | bisect_builds.ArchiveBuild._get_rev_list.assert_called_once() |
| 283 | m.assert_not_called() |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 284 | |
| 285 | def test_cache_should_save_and_load(self): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 286 | build= self.create_build() |
Kuan Huang | c8dd77a | 2024-08-12 22:13:42 | [diff] [blame] | 287 | self.assertTrue(build.use_local_cache) |
| 288 | # Load the non-existent cache and write to it. |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 289 | cached_data=[] |
Kuan Huang | c8dd77a | 2024-08-12 22:13:42 | [diff] [blame] | 290 | # The cache file would be opened 3 times: |
| 291 | # 1. read by _load_rev_list_cache |
| 292 | # 2. read by _save_rev_list_cache for existing cache |
| 293 | # 3. write by _save_rev_list_cache |
| 294 | write_mock=MagicMock() |
| 295 | write_mock.__enter__().write.side_effect=lambda d: cached_data.append(d) |
| 296 | with patch('builtins.open', |
| 297 | side_effect=[FileNotFoundError,FileNotFoundError, write_mock]): |
| 298 | self.assertEqual(build.get_rev_list(),[str(x)for xin range(10)]) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 299 | bisect_builds.ArchiveBuild._get_rev_list.assert_called_once() |
Kuan Huang | c8dd77a | 2024-08-12 22:13:42 | [diff] [blame] | 300 | cached_json= json.loads(''.join(cached_data)) |
| 301 | self.assertDictEqual(cached_json,{'abc':[str(x)for xin range(10)]}) |
| 302 | # Load cache with cached data. |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 303 | build= self.create_build('--use-local-cache') |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 304 | bisect_builds.ArchiveBuild._get_rev_list.reset_mock() |
Kuan Huang | c8dd77a | 2024-08-12 22:13:42 | [diff] [blame] | 305 | with patch('builtins.open', mock_open(read_data=''.join(cached_data))): |
| 306 | self.assertEqual(build.get_rev_list(),[str(x)for xin range(10)]) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 307 | bisect_builds.ArchiveBuild._get_rev_list.assert_not_called() |
Kuan Huang | c8dd77a | 2024-08-12 22:13:42 | [diff] [blame] | 308 | |
| 309 | @patch.object(bisect_builds.ArchiveBuild,'_load_rev_list_cache') |
| 310 | @patch.object(bisect_builds.ArchiveBuild,'_save_rev_list_cache') |
| 311 | @patch.object(bisect_builds.ArchiveBuild, |
| 312 | '_get_rev_list', |
| 313 | return_value=[str(x)for xin range(10)]) |
| 314 | def test_should_request_partial_rev_list(self, mock_get_rev_list, |
| 315 | mock_save_rev_list_cache, |
| 316 | mock_load_rev_list_cache): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 317 | build= self.create_build('--no-local-cache') |
Kuan Huang | c8dd77a | 2024-08-12 22:13:42 | [diff] [blame] | 318 | # missing latest |
| 319 | mock_load_rev_list_cache.return_value=[str(x)for xin range(5)] |
| 320 | self.assertEqual(build.get_rev_list(),[str(x)for xin range(10)]) |
| 321 | mock_get_rev_list.assert_called_with('4','9') |
| 322 | # missing old and latest |
| 323 | mock_load_rev_list_cache.return_value=[str(x)for xin range(1,5)] |
| 324 | self.assertEqual(build.get_rev_list(),[str(x)for xin range(10)]) |
| 325 | mock_get_rev_list.assert_called_with('0','9') |
| 326 | # missing old |
| 327 | mock_load_rev_list_cache.return_value=[str(x)for xin range(3,10)] |
| 328 | self.assertEqual(build.get_rev_list(),[str(x)for xin range(10)]) |
| 329 | mock_get_rev_list.assert_called_with('0','3') |
| 330 | # no intersect |
| 331 | mock_load_rev_list_cache.return_value=['c','d','e'] |
| 332 | self.assertEqual(build.get_rev_list(),[str(x)for xin range(10)]) |
| 333 | mock_save_rev_list_cache.assert_called_with([str(x)for xin range(10)]+ |
| 334 | ['c','d','e']) |
| 335 | mock_get_rev_list.assert_called_with('0','c') |
| 336 | |
| 337 | @patch.object(bisect_builds.ArchiveBuild,'_get_rev_list', return_value=[]) |
| 338 | def test_should_raise_error_when_no_rev_list(self, mock_get_rev_list): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 339 | build= self.create_build('--no-local-cache') |
Kuan Huang | c8dd77a | 2024-08-12 22:13:42 | [diff] [blame] | 340 | with self.assertRaises(bisect_builds.BisectException): |
| 341 | build.get_rev_list() |
| 342 | mock_get_rev_list.assert_any_call('0','9') |
| 343 | mock_get_rev_list.assert_any_call() |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 344 | |
| 345 | @unittest.skipIf('NO_MOCK_SERVER'notin os.environ, |
| 346 | 'The test is to ensure NO_MOCK_SERVER working correctly') |
Kuan Huang | c63de40 | 2024-08-12 22:15:27 | [diff] [blame] | 347 | @maybe_patch('bisect-builds.GetRevisionFromVersion', return_value=123) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 348 | def test_no_mock(self, mock_GetRevisionFromVersion): |
| 349 | self.assertEqual(bisect_builds.GetRevisionFromVersion('127.0.6533.74'), |
| 350 | 1313161) |
| 351 | mock_GetRevisionFromVersion.assert_called() |
| 352 | |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 353 | @patch('bisect-builds.ArchiveBuild._install_revision') |
| 354 | @patch('bisect-builds.ArchiveBuild._launch_revision', |
| 355 | return_value=(1,'','')) |
| 356 | def test_run_revision_should_return_early(self, mock_launch_revision, |
| 357 | mock_install_revision): |
| 358 | build= self.create_build() |
Kuan Huang | c2fec79 | 2024-09-03 21:57:38 | [diff] [blame] | 359 | build.run_revision('','',[]) |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 360 | mock_launch_revision.assert_called_once() |
| 361 | |
| 362 | @patch('bisect-builds.ArchiveBuild._install_revision') |
| 363 | @patch('bisect-builds.ArchiveBuild._launch_revision', |
| 364 | return_value=(0,'','')) |
| 365 | def test_run_revision_should_do_all_runs(self, mock_launch_revision, |
| 366 | mock_install_revision): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 367 | build= self.create_build('--time','10') |
Kuan Huang | c2fec79 | 2024-09-03 21:57:38 | [diff] [blame] | 368 | build.run_revision('','',[]) |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 369 | self.assertEqual(mock_launch_revision.call_count,10) |
| 370 | |
| 371 | @patch('bisect-builds.UnzipFilenameToDir') |
| 372 | @patch('glob.glob', return_value=['temp-dir/linux64/chrome']) |
| 373 | @patch('os.path.abspath', return_value='/tmp/temp-dir/linux64/chrome') |
| 374 | def test_install_revision_should_unzip_and_search_executable( |
| 375 | self, mock_abspath, mock_glob, mock_UnzipFilenameToDir): |
| 376 | build= self.create_build() |
| 377 | self.assertEqual(build._install_revision('some-file.zip','temp-dir'), |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 378 | {'chrome':'/tmp/temp-dir/linux64/chrome'}) |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 379 | mock_UnzipFilenameToDir.assert_called_once_with('some-file.zip','temp-dir') |
| 380 | mock_glob.assert_called_once_with('temp-dir/*/chrome') |
| 381 | mock_abspath.assert_called_once_with('temp-dir/linux64/chrome') |
| 382 | |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 383 | @patch('bisect-builds.UnzipFilenameToDir') |
| 384 | @patch('glob.glob', |
| 385 | side_effect=[['temp-dir/chrome-linux64/chrome'], |
| 386 | ['temp-dir/chromedriver_linux64/chromedriver']]) |
| 387 | @patch('os.path.abspath', |
| 388 | side_effect=[ |
| 389 | '/tmp/temp-dir/chrome-linux64/chrome', |
| 390 | '/tmp/temp-dir/chromedriver_linux64/chromedriver' |
| 391 | ]) |
| 392 | def test_install_chromedriver(self, mock_abspath, mock_glob, |
| 393 | mock_UnzipFilenameToDir): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 394 | build= self.create_build('--chromedriver') |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 395 | self.assertEqual( |
| 396 | build._install_revision( |
| 397 | { |
| 398 | 'chrome':'some-file.zip', |
| 399 | 'chromedriver':'some-other-file.zip', |
| 400 | },'temp-dir'), |
| 401 | { |
| 402 | 'chrome':'/tmp/temp-dir/chrome-linux64/chrome', |
| 403 | 'chromedriver':'/tmp/temp-dir/chromedriver_linux64/chromedriver', |
| 404 | }) |
| 405 | mock_UnzipFilenameToDir.assert_has_calls([ |
| 406 | call('some-file.zip','temp-dir'), |
| 407 | call('some-other-file.zip','temp-dir'), |
| 408 | ]) |
| 409 | mock_glob.assert_has_calls([ |
| 410 | call('temp-dir/*/chrome'), |
| 411 | call('temp-dir/*/chromedriver'), |
| 412 | ]) |
| 413 | mock_abspath.assert_has_calls([ |
| 414 | call('temp-dir/chrome-linux64/chrome'), |
| 415 | call('temp-dir/chromedriver_linux64/chromedriver') |
| 416 | ]) |
| 417 | |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 418 | @patch('subprocess.Popen', spec=subprocess.Popen) |
| 419 | def test_launch_revision_should_run_command(self, mock_Popen): |
| 420 | mock_Popen.return_value.communicate.return_value=('','') |
| 421 | mock_Popen.return_value.returncode=0 |
| 422 | build= self.create_build() |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 423 | build._launch_revision('temp-dir',{'chrome':'temp-dir/linux64/chrome'}, |
| 424 | []) |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 425 | mock_Popen.assert_called_once_with( |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 426 | 'temp-dir/linux64/chrome --user-data-dir=temp-dir/profile', |
| 427 | cwd=None, |
| 428 | shell=True, |
| 429 | bufsize=-1, |
| 430 | stdout=ANY, |
| 431 | stderr=ANY) |
| 432 | |
Kuan Huang | 94c4a2d1 | 2024-11-21 21:46:09 | [diff] [blame] | 433 | @unittest.skipIf(sys.platform.startswith('win'),'This test is not for win') |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 434 | @patch('subprocess.Popen', spec=subprocess.Popen) |
Kuan Huang | d3c862c0 | 2024-10-31 04:02:14 | [diff] [blame] | 435 | def test_launch_revision_should_run_command_for_mac(self, mock_Popen): |
| 436 | mock_Popen.return_value.communicate.return_value=('','') |
| 437 | mock_Popen.return_value.returncode=0 |
| 438 | build= self.create_build() |
| 439 | build._launch_revision( |
| 440 | 'temp-dir',{ |
| 441 | 'chrome': |
| 442 | 'temp-dir/full-build-mac/' |
| 443 | 'Google Chrome.app/Contents/MacOS/Google Chrome' |
| 444 | },[]) |
| 445 | mock_Popen.assert_called_once_with( |
| 446 | "'temp-dir/full-build-mac/" |
| 447 | "Google Chrome.app/Contents/MacOS/Google Chrome'" |
| 448 | ' --user-data-dir=temp-dir/profile', |
| 449 | cwd=None, |
| 450 | shell=True, |
| 451 | bufsize=-1, |
| 452 | stdout=ANY, |
| 453 | stderr=ANY) |
| 454 | |
Kuan Huang | 94c4a2d1 | 2024-11-21 21:46:09 | [diff] [blame] | 455 | @unittest.skipUnless(sys.platform.startswith('win'), |
| 456 | 'This test is for win only') |
Kuan Huang | d3c862c0 | 2024-10-31 04:02:14 | [diff] [blame] | 457 | @patch('subprocess.Popen', spec=subprocess.Popen) |
| 458 | def test_launch_revision_should_run_command_for_win(self, mock_Popen): |
| 459 | mock_Popen.return_value.communicate.return_value=('','') |
| 460 | mock_Popen.return_value.returncode=0 |
| 461 | build= self.create_build() |
| 462 | build._launch_revision( |
| 463 | 'C:\\temp-dir',{ |
| 464 | 'chrome':'C:\\temp-dir\\full-build-win\\chrome.exe' |
| 465 | },[]) |
| 466 | mock_Popen.assert_called_once_with( |
Kuan Huang | 94c4a2d1 | 2024-11-21 21:46:09 | [diff] [blame] | 467 | "C:\\temp-dir\\full-build-win\\chrome.exe " |
Kuan Huang | d3c862c0 | 2024-10-31 04:02:14 | [diff] [blame] | 468 | '--user-data-dir=C:\\temp-dir/profile', |
| 469 | cwd=None, |
| 470 | shell=True, |
| 471 | bufsize=-1, |
| 472 | stdout=ANY, |
| 473 | stderr=ANY) |
| 474 | |
| 475 | @patch('subprocess.Popen', spec=subprocess.Popen) |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 476 | def test_command_replacement(self, mock_Popen): |
| 477 | mock_Popen.return_value.communicate.return_value=('','') |
| 478 | mock_Popen.return_value.returncode=0 |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 479 | build= self.create_build( |
| 480 | '--chromedriver','-c', |
| 481 | 'CHROMEDRIVER=%d BROWSER_EXECUTABLE_PATH=%p pytest %a') |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 482 | build._launch_revision('/tmp',{ |
| 483 | 'chrome':'/tmp/chrome', |
| 484 | 'chromedriver':'/tmp/chromedriver' |
| 485 | },['--args','--args2="word 1"','word 2']) |
Kuan Huang | 94c4a2d1 | 2024-11-21 21:46:09 | [diff] [blame] | 486 | if sys.platform.startswith('win'): |
| 487 | mock_Popen.assert_called_once_with( |
| 488 | 'CHROMEDRIVER=/tmp/chromedriver BROWSER_EXECUTABLE_PATH=/tmp/chrome ' |
| 489 | 'pytest --user-data-dir=/tmp/profile --args "--args2=\\"word 1\\"" ' |
| 490 | '"word 2"', |
| 491 | cwd=None, |
| 492 | shell=True, |
| 493 | bufsize=-1, |
| 494 | stdout=ANY, |
| 495 | stderr=ANY) |
| 496 | else: |
| 497 | mock_Popen.assert_called_once_with( |
| 498 | 'CHROMEDRIVER=/tmp/chromedriver BROWSER_EXECUTABLE_PATH=/tmp/chrome ' |
| 499 | 'pytest --user-data-dir=/tmp/profile --args \'--args2="word 1"\' ' |
| 500 | '\'word 2\'', |
| 501 | cwd=None, |
| 502 | shell=True, |
| 503 | bufsize=-1, |
| 504 | stdout=ANY, |
| 505 | stderr=ANY) |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 506 | |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 507 | |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 508 | classReleaseBuildTest(BisectTestCase): |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 509 | |
| 510 | def test_should_look_up_path_context(self): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 511 | options= bisect_builds.ParseCommandLine( |
Kuan Huang | c63de40 | 2024-08-12 22:15:27 | [diff] [blame] | 512 | ['-r','-a','linux64','-g','127.0.6533.74','-b','127.0.6533.88']) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 513 | self.assertEqual(options.archive,'linux64') |
Kuan Huang | c63de40 | 2024-08-12 22:15:27 | [diff] [blame] | 514 | build= bisect_builds.create_archive_build(options) |
| 515 | self.assertIsInstance(build, bisect_builds.ReleaseBuild) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 516 | self.assertEqual(build.binary_name,'chrome') |
| 517 | self.assertEqual(build.listing_platform_dir,'linux64/') |
| 518 | self.assertEqual(build.archive_name,'chrome-linux64.zip') |
| 519 | self.assertEqual(build.archive_extract_dir,'chrome-linux64') |
| 520 | |
Kuan Huang | c63de40 | 2024-08-12 22:15:27 | [diff] [blame] | 521 | @maybe_patch( |
| 522 | 'bisect-builds.GsutilList', |
| 523 | return_value=[ |
| 524 | 'gs://chrome-unsigned/desktop-5c0tCh/%s/linux64/chrome-linux64.zip'% |
| 525 | xfor xin['127.0.6533.74','127.0.6533.75','127.0.6533.76'] |
| 526 | ]) |
| 527 | def test_get_rev_list(self, mock_GsutilList): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 528 | options= bisect_builds.ParseCommandLine([ |
| 529 | '-r','-a','linux64','-g','127.0.6533.74','-b','127.0.6533.76', |
| 530 | '--no-local-cache' |
| 531 | ]) |
Kuan Huang | c63de40 | 2024-08-12 22:15:27 | [diff] [blame] | 532 | build= bisect_builds.create_archive_build(options) |
| 533 | self.assertIsInstance(build, bisect_builds.ReleaseBuild) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 534 | self.assertEqual(build.get_rev_list(), |
| 535 | ['127.0.6533.74','127.0.6533.75','127.0.6533.76']) |
Kuan Huang | c63de40 | 2024-08-12 22:15:27 | [diff] [blame] | 536 | mock_GsutilList.assert_any_call('gs://chrome-unsigned/desktop-5c0tCh') |
| 537 | mock_GsutilList.assert_any_call(*[ |
| 538 | 'gs://chrome-unsigned/desktop-5c0tCh/%s/linux64/chrome-linux64.zip'% x |
| 539 | for xin['127.0.6533.74','127.0.6533.75','127.0.6533.76'] |
| 540 | ], |
| 541 | ignore_fail=True) |
| 542 | self.assertEqual(mock_GsutilList.call_count,2) |
| 543 | |
| 544 | @patch('bisect-builds.GsutilList', |
| 545 | return_value=['127.0.6533.74','127.0.6533.75','127.0.6533.76']) |
| 546 | def test_should_save_and_load_cache(self, mock_GsutilList): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 547 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 548 | '-r','-a','linux64','-g','127.0.6533.74','-b','127.0.6533.77', |
Kuan Huang | c63de40 | 2024-08-12 22:15:27 | [diff] [blame] | 549 | '--use-local-cache' |
| 550 | ]) |
| 551 | build= bisect_builds.create_archive_build(options) |
| 552 | self.assertIsInstance(build, bisect_builds.ReleaseBuild) |
| 553 | # Load the non-existent cache and write to it. |
| 554 | cached_data=[] |
| 555 | write_mock=MagicMock() |
| 556 | write_mock.__enter__().write.side_effect=lambda d: cached_data.append(d) |
| 557 | with patch('builtins.open', |
| 558 | side_effect=[FileNotFoundError,FileNotFoundError, write_mock]): |
| 559 | self.assertEqual(build.get_rev_list(), |
| 560 | ['127.0.6533.74','127.0.6533.75','127.0.6533.76']) |
| 561 | mock_GsutilList.assert_called() |
| 562 | cached_json= json.loads(''.join(cached_data)) |
| 563 | self.assertDictEqual( |
| 564 | cached_json,{ |
| 565 | build._rev_list_cache_key: |
| 566 | ['127.0.6533.74','127.0.6533.75','127.0.6533.76'] |
| 567 | }) |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 568 | # Load cache with cached data and merge with new data |
| 569 | mock_GsutilList.return_value=['127.0.6533.76','127.0.6533.77'] |
| 570 | build= bisect_builds.create_archive_build(options) |
Kuan Huang | c63de40 | 2024-08-12 22:15:27 | [diff] [blame] | 571 | with patch('builtins.open', mock_open(read_data=''.join(cached_data))): |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 572 | self.assertEqual( |
| 573 | build.get_rev_list(), |
| 574 | ['127.0.6533.74','127.0.6533.75','127.0.6533.76','127.0.6533.77']) |
| 575 | print(mock_GsutilList.call_args) |
| 576 | mock_GsutilList.assert_any_call( |
| 577 | 'gs://chrome-unsigned/desktop-5c0tCh' |
| 578 | '/127.0.6533.76/linux64/chrome-linux64.zip', |
| 579 | 'gs://chrome-unsigned/desktop-5c0tCh' |
| 580 | '/127.0.6533.77/linux64/chrome-linux64.zip', |
| 581 | ignore_fail=True) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 582 | |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 583 | def test_get_download_url(self): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 584 | options= bisect_builds.ParseCommandLine( |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 585 | ['-r','-a','linux64','-g','127.0.6533.74','-b','127.0.6533.77']) |
| 586 | build= bisect_builds.create_archive_build(options) |
| 587 | self.assertIsInstance(build, bisect_builds.ReleaseBuild) |
| 588 | download_urls= build.get_download_url('127.0.6533.74') |
| 589 | self.assertEqual( |
| 590 | download_urls,'gs://chrome-unsigned/desktop-5c0tCh' |
| 591 | '/127.0.6533.74/linux64/chrome-linux64.zip') |
| 592 | |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 593 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 594 | '-r','-a','linux64','-g','127.0.6533.74','-b','127.0.6533.77', |
| 595 | '--chromedriver' |
| 596 | ]) |
| 597 | build= bisect_builds.create_archive_build(options) |
| 598 | self.assertIsInstance(build, bisect_builds.ReleaseBuild) |
| 599 | download_urls= build.get_download_url('127.0.6533.74') |
| 600 | self.assertEqual( |
| 601 | download_urls,{ |
| 602 | 'chrome': |
| 603 | 'gs://chrome-unsigned/desktop-5c0tCh' |
| 604 | '/127.0.6533.74/linux64/chrome-linux64.zip', |
| 605 | 'chromedriver': |
| 606 | 'gs://chrome-unsigned/desktop-5c0tCh' |
| 607 | '/127.0.6533.74/linux64/chromedriver_linux64.zip', |
| 608 | }) |
| 609 | |
| 610 | @unittest.skipUnless('NO_MOCK_SERVER'in os.environ, |
| 611 | 'The test only valid when NO_MOCK_SERVER') |
| 612 | @patch('bisect-builds.ArchiveBuild._run', return_value=(0,'stdout','')) |
| 613 | def test_run_revision_with_real_zipfile(self, mock_run): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 614 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 615 | '-r','-a','linux64','-g','127.0.6533.74','-b','127.0.6533.77', |
| 616 | '--chromedriver','-c','driver=%d prog=%p' |
| 617 | ]) |
| 618 | build= bisect_builds.create_archive_build(options) |
| 619 | self.assertIsInstance(build, bisect_builds.ReleaseBuild) |
| 620 | download_job= build.get_download_job('127.0.6533.74') |
| 621 | zip_file= download_job.start().wait_for() |
| 622 | with tempfile.TemporaryDirectory(prefix='bisect_tmp')as tempdir: |
| 623 | build.run_revision(zip_file, tempdir,[]) |
| 624 | self.assertRegex(mock_run.call_args.args[0], |
| 625 | r'driver=.+/chromedriver prog=.+/chrome') |
| 626 | |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 627 | |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 628 | classArchiveBuildWithCommitPositionTest(BisectTestCase): |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 629 | |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 630 | def setUp(self): |
| 631 | patch.multiple(bisect_builds.ArchiveBuildWithCommitPosition, |
| 632 | __abstractmethods__=set(), |
| 633 | build_type='release').start() |
| 634 | |
| 635 | @maybe_patch('bisect-builds.GetRevisionFromVersion', return_value=1313161) |
| 636 | @maybe_patch('bisect-builds.GetChromiumRevision', return_value=999999999) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 637 | def test_should_convert_revision_as_commit_position( |
| 638 | self, mock_GetChromiumRevision, mock_GetRevisionFromVersion): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 639 | options= bisect_builds.ParseCommandLine( |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 640 | ['-a','linux64','-g','127.0.6533.74']) |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 641 | build= bisect_builds.ArchiveBuildWithCommitPosition(options) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 642 | self.assertEqual(build.good_revision,1313161) |
| 643 | self.assertEqual(build.bad_revision,999999999) |
| 644 | mock_GetRevisionFromVersion.assert_called_once_with('127.0.6533.74') |
| 645 | mock_GetChromiumRevision.assert_called() |
| 646 | |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 647 | |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 648 | classOfficialBuildTest(BisectTestCase): |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 649 | |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 650 | def test_should_lookup_path_context(self): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 651 | options= bisect_builds.ParseCommandLine( |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 652 | ['-o','-a','linux64','-g','0','-b','10']) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 653 | self.assertEqual(options.archive,'linux64') |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 654 | build= bisect_builds.create_archive_build(options) |
| 655 | self.assertIsInstance(build, bisect_builds.OfficialBuild) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 656 | self.assertEqual(build.binary_name,'chrome') |
| 657 | self.assertEqual(build.listing_platform_dir,'linux-builder-perf/') |
| 658 | self.assertEqual(build.archive_name,'chrome-perf-linux.zip') |
| 659 | self.assertEqual(build.archive_extract_dir,'full-build-linux') |
| 660 | |
Kuan Huang | c63de40 | 2024-08-12 22:15:27 | [diff] [blame] | 661 | @maybe_patch('bisect-builds.GsutilList', |
| 662 | return_value=[ |
| 663 | 'full-build-linux_%d.zip'% x |
| 664 | for xin range(1313161,1313164) |
| 665 | ]) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 666 | def test_get_rev_list(self, mock_GsutilList): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 667 | options= bisect_builds.ParseCommandLine([ |
| 668 | '-o','-a','linux64','-g','1313161','-b','1313163', |
| 669 | '--no-local-cache' |
| 670 | ]) |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 671 | build= bisect_builds.create_archive_build(options) |
| 672 | self.assertIsInstance(build, bisect_builds.OfficialBuild) |
| 673 | self.assertEqual(build.get_rev_list(), list(range(1313161,1313164))) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 674 | mock_GsutilList.assert_called_once_with( |
| 675 | 'gs://chrome-test-builds/official-by-commit/linux-builder-perf/') |
| 676 | |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 677 | @unittest.skipUnless('NO_MOCK_SERVER'in os.environ, |
| 678 | 'The test only valid when NO_MOCK_SERVER') |
| 679 | @patch('bisect-builds.ArchiveBuild._run', return_value=(0,'stdout','')) |
| 680 | def test_run_revision_with_real_zipfile(self, mock_run): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 681 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 682 | '-o','-a','linux64','-g','1313161','-b','1313163', |
| 683 | '--chromedriver','-c','driver=%d prog=%p' |
| 684 | ]) |
| 685 | build= bisect_builds.create_archive_build(options) |
| 686 | self.assertIsInstance(build, bisect_builds.OfficialBuild) |
| 687 | download_job= build.get_download_job(1334339) |
| 688 | zip_file= download_job.start().wait_for() |
| 689 | with tempfile.TemporaryDirectory(prefix='bisect_tmp')as tempdir: |
| 690 | build.run_revision(zip_file, tempdir,[]) |
| 691 | self.assertRegex(mock_run.call_args.args[0], |
| 692 | r'driver=.+/chromedriver prog=.+/chrome') |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 693 | |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 694 | classSnapshotBuildTest(BisectTestCase): |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 695 | |
| 696 | def test_should_lookup_path_context(self): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 697 | options= bisect_builds.ParseCommandLine( |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 698 | ['-a','linux64','-g','0','-b','10']) |
| 699 | self.assertEqual(options.archive,'linux64') |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 700 | build= bisect_builds.create_archive_build(options) |
| 701 | self.assertIsInstance(build, bisect_builds.SnapshotBuild) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 702 | self.assertEqual(build.binary_name,'chrome') |
| 703 | self.assertEqual(build.listing_platform_dir,'Linux_x64/') |
| 704 | self.assertEqual(build.archive_name,'chrome-linux.zip') |
| 705 | self.assertEqual(build.archive_extract_dir,'chrome-linux') |
| 706 | |
| 707 | CommonDataXMLContent='''<?xml version='1.0' encoding='UTF-8'?> |
| 708 | <ListBucketResult xmlns='http://doc.s3.amazonaws.com/2006-03-01'> |
| 709 | <Name>chromium-browser-snapshots</Name> |
| 710 | <Prefix>Linux_x64/</Prefix> |
| 711 | <Marker></Marker> |
| 712 | <NextMarker></NextMarker> |
| 713 | <Delimiter>/</Delimiter> |
| 714 | <IsTruncated>true</IsTruncated> |
| 715 | <CommonPrefixes> |
| 716 | <Prefix>Linux_x64/1313161/</Prefix> |
| 717 | </CommonPrefixes> |
| 718 | <CommonPrefixes> |
| 719 | <Prefix>Linux_x64/1313163/</Prefix> |
| 720 | </CommonPrefixes> |
| 721 | <CommonPrefixes> |
| 722 | <Prefix>Linux_x64/1313185/</Prefix> |
| 723 | </CommonPrefixes> |
| 724 | </ListBucketResult> |
| 725 | ''' |
| 726 | |
| 727 | @maybe_patch('urllib.request.urlopen', |
Kuan Huang | 0505884 | 2024-10-24 21:22:26 | [diff] [blame] | 728 | return_value=io.BytesIO(CommonDataXMLContent.encode('utf8'))) |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 729 | @patch('bisect-builds.GetChromiumRevision', return_value=1313185) |
Kuan Huang | c8dd77a | 2024-08-12 22:13:42 | [diff] [blame] | 730 | def test_get_rev_list(self, mock_GetChromiumRevision, mock_urlopen): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 731 | options= bisect_builds.ParseCommandLine( |
| 732 | ['-a','linux64','-g','1313161','-b','1313185','--no-local-cache']) |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 733 | build= bisect_builds.create_archive_build(options) |
| 734 | self.assertIsInstance(build, bisect_builds.SnapshotBuild) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 735 | rev_list= build.get_rev_list() |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 736 | mock_urlopen.assert_any_call( |
Kuan Huang | c8dd77a | 2024-08-12 22:13:42 | [diff] [blame] | 737 | 'http://commondatastorage.googleapis.com/chromium-browser-snapshots/' |
| 738 | '?delimiter=/&prefix=Linux_x64/&marker=Linux_x64/1313161') |
| 739 | self.assertEqual(mock_urlopen.call_count,1) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 740 | self.assertEqual(rev_list,[1313161,1313163,1313185]) |
| 741 | |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 742 | @patch('bisect-builds.SnapshotBuild._fetch_and_parse', |
| 743 | return_value=([int(s) |
| 744 | for sin sorted([str(x)for xin range(1,11)])],None)) |
| 745 | def test_get_rev_list_should_start_from_a_marker(self, mock_fetch_and_parse): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 746 | options= bisect_builds.ParseCommandLine( |
| 747 | ['-a','linux64','-g','0','-b','9','--no-local-cache']) |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 748 | build= bisect_builds.create_archive_build(options) |
| 749 | self.assertIsInstance(build, bisect_builds.SnapshotBuild) |
| 750 | rev_list= build._get_rev_list(0,9) |
| 751 | self.assertEqual(rev_list, list(range(1,10))) |
| 752 | mock_fetch_and_parse.assert_called_once_with( |
| 753 | 'http://commondatastorage.googleapis.com/chromium-browser-snapshots/' |
| 754 | '?delimiter=/&prefix=Linux_x64/&marker=Linux_x64/0') |
| 755 | mock_fetch_and_parse.reset_mock() |
| 756 | rev_list= build._get_rev_list(1,9) |
| 757 | self.assertEqual(rev_list, list(range(1,10))) |
| 758 | mock_fetch_and_parse.assert_called_once_with( |
| 759 | 'http://commondatastorage.googleapis.com/chromium-browser-snapshots/' |
| 760 | '?delimiter=/&prefix=Linux_x64/&marker=Linux_x64/1') |
| 761 | |
| 762 | @patch('bisect-builds.SnapshotBuild._fetch_and_parse', |
| 763 | return_value=([int(s) |
| 764 | for sin sorted([str(x)for xin range(1,11)])],None)) |
| 765 | def test_get_rev_list_should_scan_all_pages(self, mock_fetch_and_parse): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 766 | options= bisect_builds.ParseCommandLine( |
| 767 | ['-a','linux64','-g','3','-b','11','--no-local-cache']) |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 768 | build= bisect_builds.create_archive_build(options) |
| 769 | self.assertIsInstance(build, bisect_builds.SnapshotBuild) |
| 770 | rev_list= build._get_rev_list(0,11) |
| 771 | self.assertEqual(sorted(rev_list), list(range(1,11))) |
| 772 | mock_fetch_and_parse.assert_called_once_with( |
| 773 | 'http://commondatastorage.googleapis.com/chromium-browser-snapshots/' |
| 774 | '?delimiter=/&prefix=Linux_x64/') |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 775 | |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 776 | def test_get_download_url(self): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 777 | options= bisect_builds.ParseCommandLine( |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 778 | ['-a','linux64','-g','3','-b','11']) |
| 779 | build= bisect_builds.create_archive_build(options) |
| 780 | self.assertIsInstance(build, bisect_builds.SnapshotBuild) |
| 781 | download_urls= build.get_download_url(123) |
| 782 | self.assertEqual( |
| 783 | download_urls, |
| 784 | 'http://commondatastorage.googleapis.com/chromium-browser-snapshots' |
| 785 | '/Linux_x64/123/chrome-linux.zip', |
| 786 | ) |
| 787 | |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 788 | options= bisect_builds.ParseCommandLine( |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 789 | ['-a','linux64','-g','3','-b','11','--chromedriver']) |
| 790 | build= bisect_builds.create_archive_build(options) |
| 791 | self.assertIsInstance(build, bisect_builds.SnapshotBuild) |
| 792 | download_urls= build.get_download_url(123) |
| 793 | self.assertDictEqual( |
| 794 | download_urls,{ |
| 795 | 'chrome': |
| 796 | 'http://commondatastorage.googleapis.com/chromium-browser-snapshots' |
| 797 | '/Linux_x64/123/chrome-linux.zip', |
| 798 | 'chromedriver': |
| 799 | 'http://commondatastorage.googleapis.com/chromium-browser-snapshots' |
| 800 | '/Linux_x64/123/chromedriver_linux64.zip' |
| 801 | }) |
| 802 | |
| 803 | @unittest.skipUnless('NO_MOCK_SERVER'in os.environ, |
| 804 | 'The test only valid when NO_MOCK_SERVER') |
| 805 | @patch('bisect-builds.ArchiveBuild._run', return_value=(0,'stdout','')) |
| 806 | def test_run_revision_with_real_zipfile(self, mock_run): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 807 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 808 | '-a','linux64','-g','1313161','-b','1313185','--chromedriver', |
| 809 | '-c','driver=%d prog=%p' |
| 810 | ]) |
| 811 | build= bisect_builds.create_archive_build(options) |
| 812 | self.assertIsInstance(build, bisect_builds.SnapshotBuild) |
| 813 | download_job= build.get_download_job(1313161) |
| 814 | zip_file= download_job.start().wait_for() |
| 815 | with tempfile.TemporaryDirectory(prefix='bisect_tmp')as tempdir: |
| 816 | build.run_revision(zip_file, tempdir,[]) |
| 817 | self.assertRegex(mock_run.call_args.args[0], |
| 818 | r'driver=.+/chromedriver prog=.+/chrome') |
| 819 | |
Kuan Huang | e844375 | 2024-09-16 19:05:20 | [diff] [blame] | 820 | @patch('bisect-builds.GetChromiumRevision', return_value=1313185) |
| 821 | def test_get_bad_revision(self, mock_GetChromiumRevision): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 822 | options= bisect_builds.ParseCommandLine(['-a','linux64','-g','1313161']) |
Kuan Huang | e844375 | 2024-09-16 19:05:20 | [diff] [blame] | 823 | build= bisect_builds.create_archive_build(options) |
| 824 | self.assertIsInstance(build, bisect_builds.SnapshotBuild) |
| 825 | mock_GetChromiumRevision.assert_called_once_with( |
| 826 | 'http://commondatastorage.googleapis.com/chromium-browser-snapshots' |
| 827 | '/Linux_x64/LAST_CHANGE') |
| 828 | self.assertEqual(build.bad_revision,1313185) |
| 829 | |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 830 | |
Kuan Huang | 2dd3a33f | 2024-12-13 17:52:52 | [diff] [blame] | 831 | classChromeForTestingBuild(BisectTestCase): |
| 832 | |
| 833 | def test_should_lookup_path_context(self): |
| 834 | options= bisect_builds.ParseCommandLine( |
| 835 | ['-cft','-a','linux64','-g','0','-b','10']) |
| 836 | self.assertEqual(options.archive,'linux64') |
| 837 | build= bisect_builds.create_archive_build(options) |
| 838 | self.assertIsInstance(build, bisect_builds.ChromeForTestingBuild) |
| 839 | self.assertEqual(build.binary_name,'chrome') |
| 840 | self.assertEqual(build.listing_platform_dir,'linux64/') |
| 841 | self.assertEqual(build.archive_name,'chrome-linux64.zip') |
| 842 | self.assertEqual(build.chromedriver_binary_name,'chromedriver') |
| 843 | self.assertEqual(build.chromedriver_archive_name, |
| 844 | 'chromedriver-linux64.zip') |
| 845 | |
| 846 | CommonDataXMLContent='''<?xml version='1.0' encoding='UTF-8'?> |
| 847 | <ListBucketResult xmlns="http://doc.s3.amazonaws.com/2006-03-01"> |
| 848 | <Name>chrome-for-testing-per-commit-public</Name> |
| 849 | <Prefix>linux64/</Prefix> |
| 850 | <Marker/> |
| 851 | <Delimiter>/</Delimiter> |
| 852 | <IsTruncated>false</IsTruncated> |
| 853 | <Contents> |
| 854 | <Key>linux64/LAST_CHANGE</Key> |
| 855 | <Generation>1733959087133532</Generation> |
| 856 | <MetaGeneration>1</MetaGeneration> |
| 857 | <LastModified>2024-12-11T23:18:07.235Z</LastModified> |
| 858 | <ETag>"dd60cb93e225ab33d7254beca56b507a"</ETag> |
| 859 | <Size>7</Size> |
| 860 | </Contents> |
| 861 | <CommonPrefixes> |
| 862 | <Prefix>linux64/r1390729/</Prefix> |
| 863 | </CommonPrefixes> |
| 864 | <CommonPrefixes> |
| 865 | <Prefix>linux64/r1390746/</Prefix> |
| 866 | </CommonPrefixes> |
| 867 | <CommonPrefixes> |
| 868 | <Prefix>linux64/r1390757/</Prefix> |
| 869 | </CommonPrefixes> |
| 870 | </ListBucketResult> |
| 871 | ''' |
| 872 | |
| 873 | @maybe_patch('urllib.request.urlopen', |
| 874 | return_value=io.BytesIO(CommonDataXMLContent.encode('utf8'))) |
| 875 | @patch('bisect-builds.GetChromiumRevision', return_value=1390757) |
| 876 | def test_get_rev_list(self, mock_GetChromiumRevision, mock_urlopen): |
| 877 | options= bisect_builds.ParseCommandLine([ |
| 878 | '-cft','-a','linux64','-g','1390729','-b','1390757', |
| 879 | '--no-local-cache' |
| 880 | ]) |
| 881 | build= bisect_builds.create_archive_build(options) |
| 882 | self.assertIsInstance(build, bisect_builds.ChromeForTestingBuild) |
| 883 | rev_list= build.get_rev_list() |
| 884 | mock_urlopen.assert_any_call( |
| 885 | 'https://storage.googleapis.com/chrome-for-testing-per-commit-public/' |
| 886 | '?delimiter=/&prefix=linux64/&marker=linux64/r1390729') |
| 887 | self.assertEqual(mock_urlopen.call_count,1) |
| 888 | self.assertEqual(rev_list,[1390729,1390746,1390757]) |
| 889 | |
| 890 | def test_get_marker(self): |
| 891 | options= bisect_builds.ParseCommandLine( |
| 892 | ['-cft','-a','linux64','-g','1','-b','3']) |
| 893 | build= bisect_builds.create_archive_build(options) |
| 894 | self.assertIsInstance(build, bisect_builds.ChromeForTestingBuild) |
| 895 | self.assertEqual('linux64/r1390729', |
| 896 | build._get_marker_for_revision(1390729)) |
| 897 | |
| 898 | def test_get_download_url(self): |
| 899 | options= bisect_builds.ParseCommandLine( |
| 900 | ['-cft','-a','linux64','-g','3','-b','11']) |
| 901 | build= bisect_builds.create_archive_build(options) |
| 902 | self.assertIsInstance(build, bisect_builds.ChromeForTestingBuild) |
| 903 | download_urls= build.get_download_url(123) |
| 904 | self.assertEqual( |
| 905 | download_urls, |
| 906 | 'https://storage.googleapis.com/chrome-for-testing-per-commit-public' |
| 907 | '/linux64/r123/chrome-linux64.zip', |
| 908 | ) |
| 909 | |
| 910 | options= bisect_builds.ParseCommandLine( |
| 911 | ['-cft','-a','linux64','-g','3','-b','11','--chromedriver']) |
| 912 | build= bisect_builds.create_archive_build(options) |
| 913 | self.assertIsInstance(build, bisect_builds.ChromeForTestingBuild) |
| 914 | download_urls= build.get_download_url(123) |
| 915 | download_urls= build.get_download_url(123) |
| 916 | self.assertEqual( |
| 917 | download_urls,{ |
| 918 | 'chrome': |
| 919 | 'https://storage.googleapis.com/chrome-for-testing-per-commit-public' |
| 920 | '/linux64/r123/chrome-linux64.zip', |
| 921 | 'chromedriver': |
| 922 | 'https://storage.googleapis.com/chrome-for-testing-per-commit-public' |
| 923 | '/linux64/r123/chromedriver-linux64.zip', |
| 924 | }) |
| 925 | |
| 926 | @patch('bisect-builds.GetChromiumRevision', return_value=1390757) |
| 927 | def test_get_bad_revision(self, mock_GetChromiumRevision): |
| 928 | options= bisect_builds.ParseCommandLine( |
| 929 | ['-cft','-a','linux64','-g','3']) |
| 930 | build= bisect_builds.create_archive_build(options) |
| 931 | self.assertIsInstance(build, bisect_builds.ChromeForTestingBuild) |
| 932 | mock_GetChromiumRevision.assert_called_once_with( |
| 933 | 'https://storage.googleapis.com/chrome-for-testing-per-commit-public' |
| 934 | '/linux64/LAST_CHANGE') |
| 935 | self.assertEqual(build.bad_revision,1390757) |
| 936 | |
| 937 | @unittest.skipUnless('NO_MOCK_SERVER'in os.environ, |
| 938 | 'The test only valid when NO_MOCK_SERVER') |
| 939 | @patch('bisect-builds.ArchiveBuild._run', return_value=(0,'stdout','')) |
| 940 | def test_run_revision_with_real_zipfile(self, mock_run): |
| 941 | options= bisect_builds.ParseCommandLine([ |
| 942 | '--cft','-a','linux64','-g','1','--chromedriver','-c', |
| 943 | 'driver=%d prog=%p' |
| 944 | ]) |
| 945 | build= bisect_builds.create_archive_build(options) |
| 946 | self.assertIsInstance(build, bisect_builds.SnapshotBuild) |
| 947 | download_job= build.get_download_job(build.bad_revision) |
| 948 | zip_file= download_job.start().wait_for() |
| 949 | with tempfile.TemporaryDirectory(prefix='bisect_tmp')as tempdir: |
| 950 | build.run_revision(zip_file, tempdir,[]) |
| 951 | self.assertRegex(mock_run.call_args.args[0], |
| 952 | r'driver=.+/chromedriver prog=.+/chrome') |
| 953 | |
| 954 | |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 955 | classASANBuildTest(BisectTestCase): |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 956 | |
| 957 | CommonDataXMLContent='''<?xml version='1.0' encoding='UTF-8'?> |
| 958 | <ListBucketResult xmlns='http://doc.s3.amazonaws.com/2006-03-01'> |
| 959 | <Name>chromium-browser-asan</Name> |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 960 | <Prefix>mac-release/asan-mac-release</Prefix> |
| 961 | <Marker></Marker> |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 962 | <NextMarker></NextMarker> |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 963 | <Delimiter>.zip</Delimiter> |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 964 | <IsTruncated>true</IsTruncated> |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 965 | <CommonPrefixes> |
| 966 | <Prefix>mac-release/asan-mac-release-1313186.zip</Prefix> |
| 967 | </CommonPrefixes> |
| 968 | <CommonPrefixes> |
| 969 | <Prefix>mac-release/asan-mac-release-1313195.zip</Prefix> |
| 970 | </CommonPrefixes> |
| 971 | <CommonPrefixes> |
| 972 | <Prefix>mac-release/asan-mac-release-1313210.zip</Prefix> |
| 973 | </CommonPrefixes> |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 974 | </ListBucketResult> |
| 975 | ''' |
| 976 | |
| 977 | @maybe_patch('urllib.request.urlopen', |
Kuan Huang | 0505884 | 2024-10-24 21:22:26 | [diff] [blame] | 978 | return_value=io.BytesIO(CommonDataXMLContent.encode('utf8'))) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 979 | def test_get_rev_list(self, mock_urlopen): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 980 | options= bisect_builds.ParseCommandLine([ |
| 981 | '--asan','-a','mac','-g','1313161','-b','1313210', |
| 982 | '--no-local-cache' |
| 983 | ]) |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 984 | build= bisect_builds.create_archive_build(options) |
| 985 | self.assertIsInstance(build, bisect_builds.ASANBuild) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 986 | rev_list= build.get_rev_list() |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 987 | # print(mock_urlopen.call_args_list) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 988 | mock_urlopen.assert_any_call( |
Kuan Huang | c8dd77a | 2024-08-12 22:13:42 | [diff] [blame] | 989 | 'http://commondatastorage.googleapis.com/chromium-browser-asan/' |
Kuan Huang | a716032a | 2024-08-14 22:15:46 | [diff] [blame] | 990 | '?delimiter=.zip&prefix=mac-release/asan-mac-release' |
| 991 | '&marker=mac-release/asan-mac-release-1313161.zip') |
| 992 | self.assertEqual(mock_urlopen.call_count,1) |
| 993 | self.assertEqual(rev_list,[1313186,1313195,1313210]) |
Kuan Huang | 49a2c641 | 2024-08-12 22:12:33 | [diff] [blame] | 994 | |
| 995 | |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 996 | classAndroidBuildTest(BisectTestCase): |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 997 | |
| 998 | def setUp(self): |
| 999 | # patch for devil_imports |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 1000 | self.patchers=[] |
| 1001 | flag_changer_patcher= maybe_patch('bisect-builds.flag_changer', |
| 1002 | create=True) |
| 1003 | self.patchers.append(flag_changer_patcher) |
| 1004 | self.mock_flag_changer= flag_changer_patcher.start() |
| 1005 | chrome_patcher= maybe_patch('bisect-builds.chrome', create=True) |
| 1006 | self.patchers.append(chrome_patcher) |
| 1007 | self.mock_chrome= chrome_patcher.start() |
| 1008 | version_codes_patcher= maybe_patch('bisect-builds.version_codes', |
| 1009 | create=True) |
| 1010 | self.patchers.append(version_codes_patcher) |
| 1011 | self.mock_version_codes= version_codes_patcher.start() |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1012 | self.mock_version_codes.LOLLIPOP=21 |
| 1013 | self.mock_version_codes.NOUGAT=24 |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1014 | self.mock_version_codes.PIE=28 |
| 1015 | self.mock_version_codes.Q=29 |
| 1016 | initial_android_device_patcher= patch( |
| 1017 | 'bisect-builds.InitializeAndroidDevice') |
| 1018 | self.patchers.append(initial_android_device_patcher) |
| 1019 | self.mock_initial_android_device= initial_android_device_patcher.start() |
| 1020 | self.device= self.mock_initial_android_device.return_value |
| 1021 | self.set_sdk_level(bisect_builds.version_codes.Q) |
| 1022 | |
| 1023 | def set_sdk_level(self, level): |
| 1024 | self.device.build_version_sdk= level |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1025 | |
| 1026 | def tearDown(self): |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 1027 | for patcherin self.patchers: |
| 1028 | patcher.stop() |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1029 | |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1030 | |
| 1031 | classAndroidReleaseBuildTest(AndroidBuildTest): |
| 1032 | |
| 1033 | def setUp(self): |
| 1034 | super().setUp() |
| 1035 | self.set_sdk_level(bisect_builds.version_codes.PIE) |
| 1036 | |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1037 | @maybe_patch( |
| 1038 | 'bisect-builds.GsutilList', |
| 1039 | return_value=[ |
| 1040 | 'gs://chrome-signed/android-B0urB0N/%s/arm_64/MonochromeStable.apk'% |
| 1041 | xfor xin['127.0.6533.76','127.0.6533.78','127.0.6533.79'] |
| 1042 | ]) |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1043 | def test_get_android_rev_list(self, mock_GsutilList): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1044 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1045 | '-r','-a','android-arm64','--apk','chrome_stable','-g', |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1046 | '127.0.6533.76','-b','127.0.6533.79','--signed','--no-local-cache' |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1047 | ]) |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1048 | build= bisect_builds.create_archive_build(options) |
| 1049 | self.assertIsInstance(build, bisect_builds.AndroidReleaseBuild) |
| 1050 | self.assertEqual(build.get_rev_list(), |
| 1051 | ['127.0.6533.76','127.0.6533.78','127.0.6533.79']) |
| 1052 | mock_GsutilList.assert_any_call('gs://chrome-signed/android-B0urB0N') |
| 1053 | mock_GsutilList.assert_any_call(*[ |
| 1054 | 'gs://chrome-signed/android-B0urB0N/%s/arm_64/MonochromeStable.apk'% x |
| 1055 | for xin['127.0.6533.76','127.0.6533.78','127.0.6533.79'] |
| 1056 | ], |
| 1057 | ignore_fail=True) |
| 1058 | self.assertEqual(mock_GsutilList.call_count,2) |
| 1059 | |
| 1060 | @patch('bisect-builds.InstallOnAndroid') |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1061 | def test_install_revision(self, mock_InstallOnAndroid): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1062 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | 95f6df07 | 2024-09-12 20:56:42 | [diff] [blame] | 1063 | '-r','-a','android-arm64','-g','127.0.6533.76','-b', |
| 1064 | '127.0.6533.79','--apk','chrome' |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1065 | ]) |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1066 | build= bisect_builds.create_archive_build(options) |
| 1067 | self.assertIsInstance(build, bisect_builds.AndroidReleaseBuild) |
| 1068 | build._install_revision('chrome.apk','temp-dir') |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1069 | mock_InstallOnAndroid.assert_called_once_with(self.device,'chrome.apk') |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1070 | |
| 1071 | @patch('bisect-builds.LaunchOnAndroid') |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1072 | def test_launch_revision(self, mock_LaunchOnAndroid): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1073 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | 95f6df07 | 2024-09-12 20:56:42 | [diff] [blame] | 1074 | '-r','-a','android-arm64','-g','127.0.6533.76','-b', |
| 1075 | '127.0.6533.79','--apk','chrome' |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1076 | ]) |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1077 | build= bisect_builds.create_archive_build(options) |
| 1078 | self.assertIsInstance(build, bisect_builds.AndroidReleaseBuild) |
| 1079 | build._launch_revision('temp-dir',None) |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1080 | mock_LaunchOnAndroid.assert_called_once_with(self.device,'chrome') |
| 1081 | |
Kuan Huang | fb55c27 | 2024-09-16 20:56:42 | [diff] [blame] | 1082 | @patch('bisect-builds.LaunchOnAndroid') |
| 1083 | def test_webview_launch_revision(self, mock_LaunchOnAndroid): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1084 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | fb55c27 | 2024-09-16 20:56:42 | [diff] [blame] | 1085 | '-r','-a','android-arm64','-g','127.0.6533.76','-b', |
| 1086 | '127.0.6533.79','--apk','system_webview' |
| 1087 | ]) |
| 1088 | build= bisect_builds.create_archive_build(options) |
| 1089 | self.assertIsInstance(build, bisect_builds.AndroidReleaseBuild) |
| 1090 | build._launch_revision('temp-dir',None) |
| 1091 | mock_LaunchOnAndroid.assert_called_once_with(self.device,'system_webview') |
| 1092 | with self.assertRaises(bisect_builds.BisectException): |
| 1093 | build._launch_revision('temp-dir',None,['args']) |
| 1094 | |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1095 | |
| 1096 | classAndroidSnapshotBuildTest(AndroidBuildTest): |
| 1097 | |
| 1098 | def setUp(self): |
| 1099 | super().setUp() |
| 1100 | self.set_sdk_level(bisect_builds.version_codes.PIE) |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1101 | |
Kuan Huang | beba95a5 | 2025-01-06 23:10:10 | [diff] [blame] | 1102 | @patch('bisect-builds.UnzipFilenameToDir') |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1103 | @patch('bisect-builds.InstallOnAndroid') |
Kuan Huang | beba95a5 | 2025-01-06 23:10:10 | [diff] [blame] | 1104 | @patch('glob.glob', return_value=['Monochrome.apk']) |
| 1105 | def test_install_revision(self, mock_glob, mock_InstallOnAndroid, mock_unzip): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1106 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1107 | '-a','android-arm64','-g','1313161','-b','1313210','--apk', |
| 1108 | 'chrome' |
| 1109 | ]) |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1110 | build= bisect_builds.create_archive_build(options) |
| 1111 | self.assertIsInstance(build, bisect_builds.AndroidSnapshotBuild) |
| 1112 | build._install_revision('chrome.zip','temp-dir') |
Kuan Huang | beba95a5 | 2025-01-06 23:10:10 | [diff] [blame] | 1113 | mock_glob.assert_called_once_with('temp-dir/*/apks/Monochrome.apk') |
| 1114 | mock_InstallOnAndroid.assert_called_once_with(self.device,'Monochrome.apk') |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1115 | |
Kuan Huang | beba95a5 | 2025-01-06 23:10:10 | [diff] [blame] | 1116 | @patch('bisect-builds.UnzipFilenameToDir') |
| 1117 | @patch('sys.stdout', new_callable=io.StringIO) |
| 1118 | @patch('glob.glob', |
| 1119 | side_effect=[[], |
| 1120 | [ |
| 1121 | "temp-dir/full-build-linux/apks/MonochromeBeta.apk", |
| 1122 | "temp-dir/full-build-linux/apks/ChromePublic.apk" |
| 1123 | ]]) |
| 1124 | def test_install_revision_with_show_available_apks(self, mock_glob, |
| 1125 | mock_stdout, mock_unzip): |
| 1126 | options= bisect_builds.ParseCommandLine([ |
| 1127 | '-a','android-arm64','-g','1313161','-b','1313210','--apk', |
| 1128 | 'chrome' |
| 1129 | ]) |
| 1130 | build= bisect_builds.create_archive_build(options) |
| 1131 | self.assertIsInstance(build, bisect_builds.AndroidSnapshotBuild) |
| 1132 | with self.assertRaises(bisect_builds.BisectException): |
| 1133 | build._install_revision('chrome.zip','temp-dir') |
| 1134 | self.assertIn("The list of available --apk:", mock_stdout.getvalue()) |
| 1135 | self.assertIn("chrome_beta", mock_stdout.getvalue()) |
| 1136 | self.assertIn("chromium", mock_stdout.getvalue()) |
| 1137 | |
| 1138 | @patch('bisect-builds.UnzipFilenameToDir') |
| 1139 | @patch('sys.stdout', new_callable=io.StringIO) |
| 1140 | @patch('glob.glob', |
| 1141 | side_effect=[[],["temp-dir/full-build-linux/apks/unknown.apks"]]) |
| 1142 | def test_install_revision_with_show_unknown_apks(self, mock_glob, mock_stdout, |
| 1143 | mock_unzip): |
| 1144 | options= bisect_builds.ParseCommandLine([ |
| 1145 | '-a','android-arm64','-g','1313161','-b','1313210','--apk', |
| 1146 | 'chrome' |
| 1147 | ]) |
| 1148 | build= bisect_builds.create_archive_build(options) |
| 1149 | self.assertIsInstance(build, bisect_builds.AndroidSnapshotBuild) |
| 1150 | with self.assertRaises(bisect_builds.BisectException): |
| 1151 | build._install_revision('chrome.zip','temp-dir') |
| 1152 | self.assertIn("No supported apk found. But found following", |
| 1153 | mock_stdout.getvalue()) |
| 1154 | self.assertIn("unknown.apks", mock_stdout.getvalue()) |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1155 | |
| 1156 | classAndroidTrichromeReleaseBuildTest(AndroidBuildTest): |
| 1157 | |
| 1158 | def setUp(self): |
| 1159 | super().setUp() |
| 1160 | self.set_sdk_level(bisect_builds.version_codes.Q) |
| 1161 | |
| 1162 | @maybe_patch( |
| 1163 | 'bisect-builds.GsutilList', |
| 1164 | side_effect=[[ |
| 1165 | 'gs://chrome-unsigned/android-B0urB0N/%s/'% xfor xin[ |
| 1166 | '129.0.6626.0','129.0.6626.1','129.0.6627.0','129.0.6627.1', |
| 1167 | '129.0.6628.0','129.0.6628.1' |
| 1168 | ] |
| 1169 | ], |
| 1170 | [('gs://chrome-unsigned/android-B0urB0N/%s/' |
| 1171 | 'high-arm_64/TrichromeChromeGoogle6432Stable.apks')% x |
| 1172 | for xin['129.0.6626.0','129.0.6627.0','129.0.6628.0']]]) |
| 1173 | def test_get_rev_list(self, mock_GsutilList): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1174 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1175 | '-r','-a','android-arm64-high','--apk','chrome_stable','-g', |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1176 | '129.0.6626.0','-b','129.0.6628.0','--no-local-cache' |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1177 | ]) |
| 1178 | build= bisect_builds.create_archive_build(options) |
| 1179 | self.assertIsInstance(build, bisect_builds.AndroidTrichromeReleaseBuild) |
| 1180 | self.assertEqual(build.get_rev_list(), |
| 1181 | ['129.0.6626.0','129.0.6627.0','129.0.6628.0']) |
| 1182 | print(mock_GsutilList.call_args_list) |
| 1183 | mock_GsutilList.assert_any_call('gs://chrome-unsigned/android-B0urB0N') |
| 1184 | mock_GsutilList.assert_any_call(*[ |
| 1185 | ('gs://chrome-unsigned/android-B0urB0N/%s/' |
| 1186 | 'high-arm_64/TrichromeChromeGoogle6432Stable.apks')% xfor xin[ |
| 1187 | '129.0.6626.0','129.0.6626.1','129.0.6627.0','129.0.6627.1', |
| 1188 | '129.0.6628.0' |
| 1189 | ] |
| 1190 | ], |
| 1191 | ignore_fail=True) |
| 1192 | self.assertEqual(mock_GsutilList.call_count,2) |
| 1193 | |
| 1194 | def test_should_raise_exception_for_PIE(self): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1195 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1196 | '-r','-a','android-arm64-high','--apk','chrome_stable','-g', |
| 1197 | '129.0.6626.0','-b','129.0.6667.0' |
| 1198 | ]) |
| 1199 | self.set_sdk_level(bisect_builds.version_codes.PIE) |
| 1200 | with self.assertRaises(bisect_builds.BisectException): |
| 1201 | bisect_builds.create_archive_build(options) |
| 1202 | |
| 1203 | def test_get_download_url(self): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1204 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1205 | '-r','-a','android-arm64-high','--apk','chrome_stable','-g', |
| 1206 | '129.0.6626.0','-b','129.0.6628.0' |
| 1207 | ]) |
| 1208 | build= bisect_builds.create_archive_build(options) |
| 1209 | self.assertIsInstance(build, bisect_builds.AndroidTrichromeReleaseBuild) |
| 1210 | download_urls= build.get_download_url('129.0.6626.0') |
| 1211 | self.maxDiff=1000 |
| 1212 | self.assertDictEqual( |
| 1213 | download_urls,{ |
| 1214 | 'trichrome': |
| 1215 | ('gs://chrome-unsigned/android-B0urB0N/129.0.6626.0/high-arm_64/' |
| 1216 | 'TrichromeChromeGoogle6432Stable.apks'), |
| 1217 | 'trichrome_library': |
| 1218 | ('gs://chrome-unsigned/android-B0urB0N/129.0.6626.0/high-arm_64/' |
| 1219 | 'TrichromeLibraryGoogle6432Stable.apk'), |
| 1220 | }) |
| 1221 | |
| 1222 | @patch('bisect-builds.InstallOnAndroid') |
| 1223 | def test_install_revision(self, mock_InstallOnAndroid): |
| 1224 | downloads={ |
| 1225 | 'trichrome':'some-file.apks', |
| 1226 | 'trichrome_library':'file2.apk', |
| 1227 | } |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1228 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1229 | '-r','-a','android-arm64-high','--apk','chrome_stable','-g', |
| 1230 | '129.0.6626.0','-b','129.0.6628.0' |
| 1231 | ]) |
| 1232 | build= bisect_builds.create_archive_build(options) |
| 1233 | self.assertIsInstance(build, bisect_builds.AndroidTrichromeReleaseBuild) |
| 1234 | build._install_revision(downloads,'tmp-dir') |
| 1235 | mock_InstallOnAndroid.assert_any_call(self.device,'some-file.apks') |
| 1236 | mock_InstallOnAndroid.assert_any_call(self.device,'file2.apk') |
| 1237 | |
| 1238 | |
| 1239 | classAndroidTrichromeOfficialBuildTest(AndroidBuildTest): |
| 1240 | |
| 1241 | @maybe_patch('bisect-builds.GsutilList', |
| 1242 | return_value=[ |
| 1243 | 'full-build-linux_%d.zip'% x |
| 1244 | for xin[1334339,1334342,1334344,1334345,1334356] |
| 1245 | ]) |
| 1246 | def test_get_rev_list(self, mock_GsutilList): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1247 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1248 | '-o','-a','android-arm64-high','--apk','chrome','-g','1334338', |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1249 | '-b','1334380','--no-local-cache' |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1250 | ]) |
| 1251 | build= bisect_builds.create_archive_build(options) |
| 1252 | self.assertIsInstance(build, bisect_builds.AndroidTrichromeOfficialBuild) |
| 1253 | self.assertEqual(build.get_rev_list(), |
| 1254 | [1334339,1334342,1334344,1334345,1334356]) |
| 1255 | mock_GsutilList.assert_called_once_with( |
| 1256 | 'gs://chrome-test-builds/official-by-commit/' |
| 1257 | 'android_arm64_high_end-builder-perf/') |
| 1258 | |
| 1259 | def test_get_download_url(self): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1260 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1261 | '-o','-a','android-arm64-high','--apk','chrome','-g','1334338', |
| 1262 | '-b','1334380' |
| 1263 | ]) |
| 1264 | build= bisect_builds.create_archive_build(options) |
| 1265 | self.assertIsInstance(build, bisect_builds.AndroidTrichromeOfficialBuild) |
| 1266 | self.assertEqual( |
| 1267 | build.get_download_url(1334338), |
| 1268 | 'gs://chrome-test-builds/official-by-commit' |
| 1269 | '/android_arm64_high_end-builder-perf/full-build-linux_1334338.zip') |
| 1270 | |
| 1271 | @patch('glob.glob', |
| 1272 | side_effect=[[ |
| 1273 | 'temp-dir/full-build-linux/apks/TrichromeChromeGoogle6432.apks' |
| 1274 | ],['temp-dir/full-build-linux/apks/TrichromeLibraryGoogle6432.apk']]) |
| 1275 | @patch('bisect-builds.UnzipFilenameToDir') |
| 1276 | @patch('bisect-builds.InstallOnAndroid') |
| 1277 | def test_install_revision(self, mock_InstallOnAndroid, |
| 1278 | mock_UnzipFilenameToDir, mock_glob): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1279 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1280 | '-o','-a','android-arm64-high','--apk','chrome','-g','1334338', |
| 1281 | '-b','1334380' |
| 1282 | ]) |
| 1283 | build= bisect_builds.create_archive_build(options) |
| 1284 | self.assertIsInstance(build, bisect_builds.AndroidTrichromeOfficialBuild) |
| 1285 | build._install_revision('download.zip','tmp-dir') |
| 1286 | mock_UnzipFilenameToDir.assert_called_once_with('download.zip','tmp-dir') |
| 1287 | mock_InstallOnAndroid.assert_any_call( |
| 1288 | self.device, |
| 1289 | 'temp-dir/full-build-linux/apks/TrichromeLibraryGoogle6432.apk') |
| 1290 | mock_InstallOnAndroid.assert_any_call( |
| 1291 | self.device, |
| 1292 | 'temp-dir/full-build-linux/apks/TrichromeChromeGoogle6432.apks') |
| 1293 | |
Kuan Huang | beba95a5 | 2025-01-06 23:10:10 | [diff] [blame] | 1294 | @patch('sys.stdout', new_callable=io.StringIO) |
| 1295 | @patch('glob.glob', |
| 1296 | side_effect=[[], |
| 1297 | ['temp-dir/TrichromeChromeGoogle6432Canary.minimal.apks'] |
| 1298 | ]) |
| 1299 | @patch('bisect-builds.UnzipFilenameToDir') |
| 1300 | def test_install_revision_with_show_available_apks(self, |
| 1301 | mock_UnzipFilenameToDir, |
| 1302 | mock_glob, mock_stdout): |
| 1303 | options= bisect_builds.ParseCommandLine([ |
| 1304 | '-o','-a','android-arm64-high','--apk','chrome','-g','1334338', |
| 1305 | '-b','1334380' |
| 1306 | ]) |
| 1307 | build= bisect_builds.create_archive_build(options) |
| 1308 | self.assertIsInstance(build, bisect_builds.AndroidTrichromeOfficialBuild) |
| 1309 | with self.assertRaises(bisect_builds.BisectException): |
| 1310 | build._install_revision('download.zip','tmp-dir') |
| 1311 | self.assertIn("The list of available --apk:", mock_stdout.getvalue()) |
| 1312 | self.assertIn("chrome_canary", mock_stdout.getvalue()) |
| 1313 | |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1314 | @unittest.skipUnless('NO_MOCK_SERVER'in os.environ, |
| 1315 | 'The test only valid when NO_MOCK_SERVER') |
| 1316 | @patch('bisect-builds.InstallOnAndroid') |
| 1317 | @patch('bisect-builds.LaunchOnAndroid') |
| 1318 | def test_run_revision_with_real_zipfile(self, mock_LaunchOnAndroid, |
| 1319 | mock_InstallOnAndroid): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1320 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1321 | '-o','-a','android-arm64-high','--apk','chrome','-g','1334338', |
| 1322 | '-b','1334380' |
| 1323 | ]) |
| 1324 | build= bisect_builds.create_archive_build(options) |
| 1325 | self.assertIsInstance(build, bisect_builds.AndroidTrichromeOfficialBuild) |
| 1326 | download_job= build.get_download_job(1334339) |
| 1327 | zip_file= download_job.start().wait_for() |
Kuan Huang | c2fec79 | 2024-09-03 21:57:38 | [diff] [blame] | 1328 | with tempfile.TemporaryDirectory(prefix='bisect_tmp')as tempdir: |
| 1329 | build.run_revision(zip_file, tempdir,[]) |
Kuan Huang | feb4fa55 | 2024-08-21 20:40:28 | [diff] [blame] | 1330 | print(mock_InstallOnAndroid.call_args_list) |
| 1331 | self.assertRegex(mock_InstallOnAndroid.mock_calls[0].args[1], |
| 1332 | 'full-build-linux/apks/TrichromeLibraryGoogle6432.apk$') |
| 1333 | self.assertRegex( |
| 1334 | mock_InstallOnAndroid.mock_calls[1].args[1], |
| 1335 | 'full-build-linux/apks/TrichromeChromeGoogle6432.minimal.apks$') |
| 1336 | mock_LaunchOnAndroid.assert_called_once_with(self.device,'chrome') |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1337 | |
Trung Nguyen | d391d05 | 2025-06-04 09:35:09 | [diff] [blame] | 1338 | @unittest.skipUnless('NO_MOCK_SERVER'in os.environ, |
| 1339 | 'The test only valid when NO_MOCK_SERVER') |
| 1340 | @patch('bisect-builds.InstallOnAndroid') |
| 1341 | @patch('bisect-builds.LaunchOnAndroid') |
| 1342 | def test_run_revision_with_webview_apk_with_unsupported_versions( |
| 1343 | self, mock_LaunchOnAndroid, mock_InstallOnAndroid): |
| 1344 | options= bisect_builds.ParseCommandLine([ |
| 1345 | '-o','-a','android-arm64-high','--apk','system_webview','-g', |
| 1346 | '100000','-b','100010' |
| 1347 | ]) |
| 1348 | |
| 1349 | with self.assertRaises(bisect_builds.BisectException): |
| 1350 | _= bisect_builds.create_archive_build(options) |
| 1351 | |
| 1352 | @unittest.skipUnless('NO_MOCK_SERVER'in os.environ, |
| 1353 | 'The test only valid when NO_MOCK_SERVER') |
| 1354 | @patch('bisect-builds.InstallOnAndroid') |
| 1355 | @patch('bisect-builds.LaunchOnAndroid') |
| 1356 | def test_webview_launch_revision(self, mock_LaunchOnAndroid, |
| 1357 | mock_InstallOnAndroid): |
| 1358 | options= bisect_builds.ParseCommandLine([ |
| 1359 | '-o','-a','android-arm64-high','--apk','system_webview','-g', |
| 1360 | '1350000','-b','1350010' |
| 1361 | ]) |
| 1362 | |
| 1363 | build= bisect_builds.create_archive_build(options) |
| 1364 | |
| 1365 | self.assertIsInstance(build, bisect_builds.AndroidTrichromeOfficialBuild) |
| 1366 | download_job= build.get_download_job(1334339) |
| 1367 | zip_file= download_job.start().wait_for() |
| 1368 | with tempfile.TemporaryDirectory(prefix='bisect_tmp')as tempdir: |
| 1369 | build.run_revision(zip_file, tempdir,[]) |
| 1370 | print(mock_InstallOnAndroid.call_args_list) |
| 1371 | self.assertRegex(mock_InstallOnAndroid.mock_calls[0].args[1], |
| 1372 | 'full-build-linux/apks/TrichromeLibraryGoogle6432.apk$') |
| 1373 | self.assertRegex( |
| 1374 | mock_InstallOnAndroid.mock_calls[1].args[1], |
| 1375 | 'full-build-linux/apks/TrichromeWebViewGoogle6432.minimal.apks$') |
| 1376 | mock_LaunchOnAndroid.assert_called_once_with(self.device,'system_webview') |
| 1377 | |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1378 | |
Kuan Huang | dc7d212b | 2024-08-19 20:53:30 | [diff] [blame] | 1379 | classLinuxReleaseBuildTest(BisectTestCase): |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1380 | |
| 1381 | @patch('subprocess.Popen', spec=subprocess.Popen) |
| 1382 | def test_launch_revision_should_has_no_sandbox(self, mock_Popen): |
| 1383 | mock_Popen.return_value.communicate.return_value=('','') |
| 1384 | mock_Popen.return_value.returncode=0 |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1385 | options= bisect_builds.ParseCommandLine( |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1386 | ['-r','-a','linux64','-g','127.0.6533.74','-b','127.0.6533.88']) |
| 1387 | build= bisect_builds.create_archive_build(options) |
| 1388 | self.assertIsInstance(build, bisect_builds.LinuxReleaseBuild) |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 1389 | build._launch_revision('temp-dir',{'chrome':'temp-dir/linux64/chrome'}, |
| 1390 | []) |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1391 | mock_Popen.assert_called_once_with( |
Kuan Huang | 89fe2eef | 2024-09-13 23:04:02 | [diff] [blame] | 1392 | 'temp-dir/linux64/chrome --user-data-dir=temp-dir/profile --no-sandbox', |
Kuan Huang | abd69f2 | 2024-09-13 23:03:48 | [diff] [blame] | 1393 | cwd=None, |
| 1394 | shell=True, |
Kuan Huang | d608f159 | 2024-08-15 23:31:35 | [diff] [blame] | 1395 | bufsize=-1, |
| 1396 | stdout=ANY, |
| 1397 | stderr=ANY) |
| 1398 | |
| 1399 | |
Kuan Huang | 2277007 | 2024-08-27 20:06:53 | [diff] [blame] | 1400 | classIOSReleaseBuildTest(BisectTestCase): |
| 1401 | |
| 1402 | @maybe_patch( |
| 1403 | 'bisect-builds.GsutilList', |
| 1404 | side_effect=[[ |
| 1405 | 'gs://chrome-unsigned/ios-G1N/127.0.6533.76/', |
| 1406 | 'gs://chrome-unsigned/ios-G1N/127.0.6533.77/', |
| 1407 | 'gs://chrome-unsigned/ios-G1N/127.0.6533.78/' |
| 1408 | ], |
| 1409 | [ |
| 1410 | 'gs://chrome-unsigned/ios-G1N' |
| 1411 | '/127.0.6533.76/iphoneos17.5/ios/10863/canary.ipa', |
| 1412 | 'gs://chrome-unsigned/ios-G1N' |
| 1413 | '/127.0.6533.77/iphoneos17.5/ios/10866/canary.ipa', |
| 1414 | 'gs://chrome-unsigned/ios-G1N' |
| 1415 | '/127.0.6533.78/iphoneos17.5/ios/10868/canary.ipa' |
| 1416 | ]]) |
| 1417 | def test_list_rev(self, mock_GsutilList): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1418 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | 2277007 | 2024-08-27 20:06:53 | [diff] [blame] | 1419 | '-r','-a','ios','--ipa=canary.ipa','--device-id','321','-g', |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1420 | '127.0.6533.74','-b','127.0.6533.78','--no-local-cache' |
Kuan Huang | 2277007 | 2024-08-27 20:06:53 | [diff] [blame] | 1421 | ]) |
| 1422 | build= bisect_builds.create_archive_build(options) |
| 1423 | self.assertIsInstance(build, bisect_builds.IOSReleaseBuild) |
| 1424 | self.assertEqual(build.get_rev_list(), |
| 1425 | ['127.0.6533.76','127.0.6533.77','127.0.6533.78']) |
| 1426 | mock_GsutilList.assert_any_call('gs://chrome-unsigned/ios-G1N') |
| 1427 | mock_GsutilList.assert_any_call(*[ |
| 1428 | 'gs://chrome-unsigned/ios-G1N/%s/*/ios/*/canary.ipa'% x |
| 1429 | for xin['127.0.6533.76','127.0.6533.77','127.0.6533.78'] |
| 1430 | ], |
| 1431 | ignore_fail=True) |
| 1432 | |
| 1433 | @patch('bisect-builds.UnzipFilenameToDir') |
| 1434 | @patch('glob.glob', return_value=['Payload/canary.app/Info.plist']) |
| 1435 | @patch('subprocess.Popen', spec=subprocess.Popen) |
| 1436 | def test_install_revision(self, mock_Popen, mock_glob, |
| 1437 | mock_UnzipFilenameToDir): |
| 1438 | mock_Popen.return_value.communicate.return_value=('','') |
| 1439 | mock_Popen.return_value.returncode=0 |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1440 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | 2277007 | 2024-08-27 20:06:53 | [diff] [blame] | 1441 | '-r','-a','ios','--ipa=canary.ipa','--device-id','321','-g', |
| 1442 | '127.0.6533.74','-b','127.0.6533.78' |
| 1443 | ]) |
| 1444 | build= bisect_builds.create_archive_build(options) |
| 1445 | self.assertIsInstance(build, bisect_builds.IOSReleaseBuild) |
| 1446 | build._install_revision('canary.ipa','tempdir') |
| 1447 | mock_glob.assert_called_once_with('tempdir/Payload/*/Info.plist') |
| 1448 | mock_Popen.assert_has_calls([ |
| 1449 | call([ |
| 1450 | 'xcrun','devicectl','device','install','app','--device','321', |
| 1451 | 'canary.ipa' |
| 1452 | ], |
| 1453 | cwd=None, |
Kuan Huang | abd69f2 | 2024-09-13 23:03:48 | [diff] [blame] | 1454 | shell=False, |
Kuan Huang | 2277007 | 2024-08-27 20:06:53 | [diff] [blame] | 1455 | bufsize=-1, |
| 1456 | stdout=-1, |
| 1457 | stderr=-1), |
| 1458 | call([ |
| 1459 | 'plutil','-extract','CFBundleIdentifier','raw', |
| 1460 | 'Payload/canary.app/Info.plist' |
| 1461 | ], |
| 1462 | cwd=None, |
Kuan Huang | abd69f2 | 2024-09-13 23:03:48 | [diff] [blame] | 1463 | shell=False, |
Kuan Huang | 2277007 | 2024-08-27 20:06:53 | [diff] [blame] | 1464 | bufsize=-1, |
| 1465 | stdout=-1, |
| 1466 | stderr=-1) |
| 1467 | ], |
| 1468 | any_order=True) |
| 1469 | |
| 1470 | @patch('subprocess.Popen', spec=subprocess.Popen) |
| 1471 | def test_launch_revision(self, mock_Popen): |
| 1472 | mock_Popen.return_value.communicate.return_value=('','') |
| 1473 | mock_Popen.return_value.returncode=0 |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1474 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | 2277007 | 2024-08-27 20:06:53 | [diff] [blame] | 1475 | '-r','-a','ios','--ipa=canary.ipa','--device-id','321','-g', |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1476 | '127.0.6533.74','-b','127.0.6533.78','--','args1','args2' |
Kuan Huang | 2277007 | 2024-08-27 20:06:53 | [diff] [blame] | 1477 | ]) |
| 1478 | build= bisect_builds.create_archive_build(options) |
| 1479 | self.assertIsInstance(build, bisect_builds.IOSReleaseBuild) |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1480 | build._launch_revision('tempdir','com.google.chrome.ios', options.args) |
Kuan Huang | 2277007 | 2024-08-27 20:06:53 | [diff] [blame] | 1481 | mock_Popen.assert_any_call([ |
| 1482 | 'xcrun','devicectl','device','process','launch','--device','321', |
| 1483 | 'com.google.chrome.ios','args1','args2' |
| 1484 | ], |
| 1485 | cwd=None, |
Kuan Huang | abd69f2 | 2024-09-13 23:03:48 | [diff] [blame] | 1486 | shell=False, |
Kuan Huang | 2277007 | 2024-08-27 20:06:53 | [diff] [blame] | 1487 | bufsize=-1, |
| 1488 | stdout=-1, |
| 1489 | stderr=-1) |
| 1490 | |
| 1491 | @unittest.skipUnless('NO_MOCK_SERVER'in os.environ, |
| 1492 | 'The test only valid when NO_MOCK_SERVER') |
Kuan Huang | b4c8df5 | 2024-09-05 17:59:18 | [diff] [blame] | 1493 | @patch('bisect-builds.ArchiveBuild._run', return_value=(0,'stdout','')) |
Kuan Huang | 2277007 | 2024-08-27 20:06:53 | [diff] [blame] | 1494 | def test_run_revision(self, mock_run): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1495 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | 2277007 | 2024-08-27 20:06:53 | [diff] [blame] | 1496 | '-r','-a','ios','--ipa=canary.ipa','--device-id','321','-g', |
| 1497 | '127.0.6533.74','-b','127.0.6533.78' |
| 1498 | ]) |
| 1499 | build= bisect_builds.create_archive_build(options) |
| 1500 | self.assertIsInstance(build, bisect_builds.IOSReleaseBuild) |
| 1501 | job= build.get_download_job('127.0.6533.76') |
| 1502 | ipa= job.start().wait_for() |
Kuan Huang | c2fec79 | 2024-09-03 21:57:38 | [diff] [blame] | 1503 | with tempfile.TemporaryDirectory(prefix='bisect_tmp')as tempdir: |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1504 | build.run_revision(ipa, tempdir, options.args) |
Kuan Huang | 2277007 | 2024-08-27 20:06:53 | [diff] [blame] | 1505 | mock_run.assert_has_calls([ |
| 1506 | call([ |
| 1507 | 'xcrun','devicectl','device','install','app','--device','321', |
| 1508 | ANY |
| 1509 | ]), |
| 1510 | call(['plutil','-extract','CFBundleIdentifier','raw', ANY]), |
| 1511 | call([ |
| 1512 | 'xcrun','devicectl','device','process','launch','--device', |
| 1513 | '321','stdout' |
| 1514 | ]) |
| 1515 | ]) |
| 1516 | |
| 1517 | |
Kuan Huang | b4c8df5 | 2024-09-05 17:59:18 | [diff] [blame] | 1518 | classIOSSimulatorReleaseBuildTest(BisectTestCase): |
| 1519 | |
| 1520 | @maybe_patch( |
| 1521 | 'bisect-builds.GsutilList', |
| 1522 | side_effect=[ |
| 1523 | [ |
| 1524 | 'gs://bling-archive/128.0.6534.0/', |
| 1525 | 'gs://bling-archive/128.0.6534.1/', |
| 1526 | 'gs://bling-archive/128.0.6535.0/', |
| 1527 | 'gs://bling-archive/128.0.6535.1/', |
| 1528 | 'gs://bling-archive/128.0.6536.0/', |
| 1529 | ], |
| 1530 | [ |
| 1531 | 'gs://bling-archive/128.0.6534.0/20240612011643/Chromium.tar.gz', |
| 1532 | 'gs://bling-archive/128.0.6536.0/20240613011356/Chromium.tar.gz', |
| 1533 | ] |
| 1534 | ]) |
Kuan Huang | 725c9305 | 2024-10-10 19:33:10 | [diff] [blame] | 1535 | @patch('bisect-builds.ArchiveBuild._run', return_value=(0,'','')) |
| 1536 | def test_list_rev(self, mock_run, mock_GsutilList): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1537 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | b4c8df5 | 2024-09-05 17:59:18 | [diff] [blame] | 1538 | '-r','-a','ios-simulator','--device-id','321','-g','128.0.6534.0', |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1539 | '-b','128.0.6536.0','--no-local-cache' |
Kuan Huang | b4c8df5 | 2024-09-05 17:59:18 | [diff] [blame] | 1540 | ]) |
| 1541 | build= bisect_builds.create_archive_build(options) |
| 1542 | self.assertIsInstance(build, bisect_builds.IOSSimulatorReleaseBuild) |
| 1543 | self.assertEqual(build.get_rev_list(),['128.0.6534.0','128.0.6536.0']) |
Kuan Huang | 725c9305 | 2024-10-10 19:33:10 | [diff] [blame] | 1544 | mock_run.assert_called_once_with(['xcrun','simctl','boot','321']) |
Kuan Huang | b4c8df5 | 2024-09-05 17:59:18 | [diff] [blame] | 1545 | mock_GsutilList.assert_any_call('gs://bling-archive') |
| 1546 | mock_GsutilList.assert_any_call(*[ |
| 1547 | 'gs://bling-archive/%s/*/Chromium.tar.gz'% xfor xin[ |
| 1548 | '128.0.6534.0','128.0.6534.1','128.0.6535.0','128.0.6535.1', |
| 1549 | '128.0.6536.0' |
| 1550 | ] |
| 1551 | ], |
| 1552 | ignore_fail=True) |
| 1553 | |
| 1554 | @patch('bisect-builds.UnzipFilenameToDir') |
| 1555 | @patch('glob.glob', return_value=['Info.plist']) |
| 1556 | @patch('bisect-builds.ArchiveBuild._run', return_value=(0,'','')) |
| 1557 | def test_install_revision(self, mock_run, mock_glob, mock_UnzipFilenameToDir): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1558 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | b4c8df5 | 2024-09-05 17:59:18 | [diff] [blame] | 1559 | '-r','-a','ios-simulator','--device-id','321','-g','128.0.6534.0', |
| 1560 | '-b','128.0.6539.0' |
| 1561 | ]) |
| 1562 | build= bisect_builds.create_archive_build(options) |
| 1563 | self.assertIsInstance(build, bisect_builds.IOSSimulatorReleaseBuild) |
| 1564 | build._install_revision('Chromium.tar.gz','tempdir') |
| 1565 | mock_UnzipFilenameToDir.assert_called_once_with('Chromium.tar.gz', |
| 1566 | 'tempdir') |
| 1567 | self.assertEqual(mock_glob.call_count,2) |
| 1568 | mock_run.assert_has_calls([ |
Kuan Huang | 725c9305 | 2024-10-10 19:33:10 | [diff] [blame] | 1569 | call(['xcrun','simctl','boot','321']), |
Kuan Huang | b4c8df5 | 2024-09-05 17:59:18 | [diff] [blame] | 1570 | call(['xcrun','simctl','install','321', ANY]), |
| 1571 | call(['plutil','-extract','CFBundleIdentifier','raw','Info.plist']), |
| 1572 | ]) |
| 1573 | |
| 1574 | @patch('bisect-builds.ArchiveBuild._run', return_value=(0,'','')) |
| 1575 | def test_launch_revision(self, mock_run): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1576 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | b4c8df5 | 2024-09-05 17:59:18 | [diff] [blame] | 1577 | '-r','-a','ios-simulator','--device-id','321','-g','128.0.6534.0', |
| 1578 | '-b','128.0.6539.0' |
| 1579 | ]) |
| 1580 | build= bisect_builds.create_archive_build(options) |
| 1581 | self.assertIsInstance(build, bisect_builds.IOSSimulatorReleaseBuild) |
| 1582 | build._launch_revision('tempdir','com.google.chrome.ios.dev', |
| 1583 | ['args1','args2']) |
| 1584 | mock_run.assert_any_call([ |
| 1585 | 'xcrun','simctl','launch','321','com.google.chrome.ios.dev', |
| 1586 | 'args1','args2' |
| 1587 | ]) |
| 1588 | |
| 1589 | @unittest.skipUnless('NO_MOCK_SERVER'in os.environ, |
| 1590 | 'The test only valid when NO_MOCK_SERVER') |
| 1591 | @patch('bisect-builds.ArchiveBuild._run', return_value=(0,'stdout','')) |
| 1592 | def test_run_revision(self, mock_run): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1593 | options= bisect_builds.ParseCommandLine([ |
Kuan Huang | b4c8df5 | 2024-09-05 17:59:18 | [diff] [blame] | 1594 | '-r','-a','ios-simulator','--device-id','321','-g','128.0.6534.0', |
| 1595 | '-b','128.0.6539.0' |
| 1596 | ]) |
| 1597 | build= bisect_builds.create_archive_build(options) |
| 1598 | self.assertIsInstance(build, bisect_builds.IOSSimulatorReleaseBuild) |
| 1599 | job= build.get_download_job('128.0.6534.0') |
| 1600 | download= job.start().wait_for() |
| 1601 | with tempfile.TemporaryDirectory(prefix='bisect_tmp')as tempdir: |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1602 | build.run_revision(download, tempdir, options.args) |
Kuan Huang | b4c8df5 | 2024-09-05 17:59:18 | [diff] [blame] | 1603 | mock_run.assert_has_calls([ |
Kuan Huang | 725c9305 | 2024-10-10 19:33:10 | [diff] [blame] | 1604 | call(['xcrun','simctl','boot','321']), |
Kuan Huang | b4c8df5 | 2024-09-05 17:59:18 | [diff] [blame] | 1605 | call(['xcrun','simctl','install','321', ANY]), |
| 1606 | call(['plutil','-extract','CFBundleIdentifier','raw', ANY]), |
| 1607 | call(['xcrun','simctl','launch','321','stdout']) |
| 1608 | ]) |
| 1609 | |
| 1610 | |
Kuan Huang | 95f6df07 | 2024-09-12 20:56:42 | [diff] [blame] | 1611 | classMaybeSwitchBuildTypeTest(BisectTestCase): |
| 1612 | |
| 1613 | def test_generate_new_command_without_cache(self): |
| 1614 | command_line=[ |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1615 | '-r','-a','linux64','-g','127.0.6533.74','-b','127.0.6533.88', |
| 1616 | '--no-local-cache' |
Kuan Huang | 95f6df07 | 2024-09-12 20:56:42 | [diff] [blame] | 1617 | ] |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1618 | options= bisect_builds.ParseCommandLine(command_line) |
Kuan Huang | 95f6df07 | 2024-09-12 20:56:42 | [diff] [blame] | 1619 | with patch('sys.argv',['bisect-builds.py',*command_line]): |
| 1620 | new_cmd= bisect_builds.MaybeSwitchBuildType( |
Kuan Huang | 6f7f5794 | 2024-12-05 19:26:30 | [diff] [blame] | 1621 | options, bisect_builds.ChromiumVersion('127.0.6533.74'), |
| 1622 | bisect_builds.ChromiumVersion('127.0.6533.88')) |
Kuan Huang | 95f6df07 | 2024-09-12 20:56:42 | [diff] [blame] | 1623 | self.assertEqual(new_cmd[1:],[ |
| 1624 | '-o','-a','linux64','-g','127.0.6533.74','-b','127.0.6533.88', |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1625 | '--verify-range','--no-local-cache' |
Kuan Huang | 95f6df07 | 2024-09-12 20:56:42 | [diff] [blame] | 1626 | ]) |
| 1627 | |
| 1628 | def test_android_signed_with_args(self): |
| 1629 | command_line=[ |
| 1630 | '-r','--archive=android-arm64-high','--good=127.0.6533.74','-b', |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1631 | '127.0.6533.88','--apk=chrome','--signed','--no-local-cache','--', |
| 1632 | 'args1','--args2' |
Kuan Huang | 95f6df07 | 2024-09-12 20:56:42 | [diff] [blame] | 1633 | ] |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1634 | options= bisect_builds.ParseCommandLine(command_line) |
Kuan Huang | 95f6df07 | 2024-09-12 20:56:42 | [diff] [blame] | 1635 | with patch('sys.argv',['bisect-builds.py',*command_line]): |
| 1636 | new_cmd= bisect_builds.MaybeSwitchBuildType(options,'127.0.6533.74', |
| 1637 | '127.0.6533.88') |
| 1638 | self.assertEqual(new_cmd[1:],[ |
| 1639 | '-o','-a','android-arm64-high','-g','127.0.6533.74','-b', |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1640 | '127.0.6533.88','--verify-range','--apk=chrome','--no-local-cache', |
| 1641 | '--','args1','--args2' |
Kuan Huang | 95f6df07 | 2024-09-12 20:56:42 | [diff] [blame] | 1642 | ]) |
| 1643 | |
| 1644 | def test_no_official_build(self): |
| 1645 | command_line=[ |
| 1646 | '-r','-a','ios','--ipa=canary.ipa','--device-id','321','-g', |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1647 | '127.0.6533.74','-b','127.0.6533.78','--no-local-cache' |
Kuan Huang | 95f6df07 | 2024-09-12 20:56:42 | [diff] [blame] | 1648 | ] |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1649 | options= bisect_builds.ParseCommandLine(command_line) |
Kuan Huang | 95f6df07 | 2024-09-12 20:56:42 | [diff] [blame] | 1650 | with patch('sys.argv',['bisect-builds.py',*command_line]): |
| 1651 | new_cmd= bisect_builds.MaybeSwitchBuildType(options,'127.0.6533.74', |
| 1652 | '127.0.6533.88') |
| 1653 | self.assertEqual(new_cmd,None) |
| 1654 | |
| 1655 | @patch('bisect-builds.ArchiveBuild.get_rev_list', return_value=list(range(3))) |
| 1656 | def test_generate_suggestion_with_cache(self, mock_get_rev_list): |
| 1657 | command_line=[ |
| 1658 | '-r','-a','linux64','-g','127.0.6533.74','-b','127.0.6533.88', |
| 1659 | '--use-local-cache' |
| 1660 | ] |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1661 | options= bisect_builds.ParseCommandLine(command_line) |
Kuan Huang | 95f6df07 | 2024-09-12 20:56:42 | [diff] [blame] | 1662 | with patch('sys.argv',['bisect-builds.py',*command_line]): |
| 1663 | new_cmd= bisect_builds.MaybeSwitchBuildType(options,'127.0.6533.74', |
| 1664 | '127.0.6533.88') |
| 1665 | self.assertEqual(new_cmd[1:],[ |
| 1666 | '-o','-a','linux64','-g','127.0.6533.74','-b','127.0.6533.88', |
| 1667 | '--verify-range','--use-local-cache' |
| 1668 | ]) |
| 1669 | mock_get_rev_list.assert_called() |
| 1670 | |
| 1671 | |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1672 | classMethodTest(BisectTestCase): |
| 1673 | |
Kuan Huang | 9a1ad2b | 2024-09-30 23:16:31 | [diff] [blame] | 1674 | @patch('sys.stderr', new_callable=io.StringIO) |
| 1675 | def test_ParseCommandLine(self, mock_stderr): |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1676 | opts= bisect_builds.ParseCommandLine( |
| 1677 | ['-a','linux64','-g','1','args1','args2 3','-b','2']) |
| 1678 | self.assertEqual(opts.build_type,'snapshot') |
| 1679 | self.assertEqual(opts.args,['args1','args2 3']) |
| 1680 | |
| 1681 | opts= bisect_builds.ParseCommandLine( |
| 1682 | ['-a','linux64','-g','1','args1','args2 3']) |
| 1683 | self.assertEqual(opts.args,['args1','args2 3']) |
| 1684 | |
| 1685 | opts= bisect_builds.ParseCommandLine( |
| 1686 | ['-a','linux64','-g','1','--','args1','args2 3','-b','2']) |
| 1687 | self.assertEqual(opts.args,['args1','args2 3','-b','2']) |
| 1688 | |
Kuan Huang | 9a1ad2b | 2024-09-30 23:16:31 | [diff] [blame] | 1689 | with self.assertRaises(SystemExit): |
| 1690 | bisect_builds.ParseCommandLine(['-a','mac64','-o','-g','1']) |
| 1691 | self.assertRegexpMatches( |
| 1692 | mock_stderr.getvalue(), r'To bisect for mac64, please choose from ' |
| 1693 | r'release(-r), snapshot(-s)') |
| 1694 | |
Kuan Huang | b790d5d | 2024-11-07 21:53:00 | [diff] [blame] | 1695 | @patch('bisect-builds._DetectArchive', return_value='linux64') |
| 1696 | def test_ParseCommandLine_DetectArchive(self, mock_detect_archive): |
| 1697 | opts= bisect_builds.ParseCommandLine(['-o','-g','1']) |
| 1698 | self.assertEqual(opts.archive,'linux64') |
| 1699 | |
Kuan Huang | 908c5521 | 2025-01-06 23:09:01 | [diff] [blame] | 1700 | def test_ParseCommandLine_default_apk(self): |
| 1701 | opts= bisect_builds.ParseCommandLine( |
| 1702 | ['-o','-a','android-arm','-g','1']) |
| 1703 | self.assertEqual(opts.apk,'chrome') |
| 1704 | |
| 1705 | opts= bisect_builds.ParseCommandLine(['-a','android-arm64','-g','1']) |
| 1706 | self.assertEqual(opts.apk,'chromium') |
| 1707 | |
| 1708 | def test_ParseCommandLine_default_ipa(self): |
| 1709 | opts= bisect_builds.ParseCommandLine( |
| 1710 | ['-r','-a','ios','-g','127.0.6533.74','-b','127.0.6533.88']) |
| 1711 | self.assertEqual(opts.ipa,'canary') |
| 1712 | |
| 1713 | def test_ParseCommandLine_DetectArchive_with_apk(self): |
| 1714 | opts= bisect_builds.ParseCommandLine(['-o','--apk','chrome','-g','1']) |
| 1715 | self.assertEqual(opts.archive,'android-arm64') |
| 1716 | |
| 1717 | def test_ParseCommandLine_DetectArchive_with_ipa(self): |
| 1718 | opts= bisect_builds.ParseCommandLine( |
| 1719 | ['-r','--ipa','stable','-g','127.0.6533.74','-b','127.0.6533.88']) |
| 1720 | self.assertEqual(opts.archive,'ios-simulator') |
| 1721 | |
| 1722 | @patch('sys.stderr', new_callable=io.StringIO) |
| 1723 | def test_ParseCommandLine_apk_error(self, mock_stderr): |
| 1724 | with self.assertRaises(SystemExit): |
| 1725 | bisect_builds.ParseCommandLine( |
| 1726 | ['-a','linux64','--apk','chrome','-g','1']) |
| 1727 | self.assertIn('--apk is only supported', mock_stderr.getvalue()) |
| 1728 | |
| 1729 | @patch('sys.stderr', new_callable=io.StringIO) |
| 1730 | def test_ParseCommandLine_ipa_error(self, mock_stderr): |
| 1731 | with self.assertRaises(SystemExit): |
| 1732 | bisect_builds.ParseCommandLine( |
| 1733 | ['-a','linux64','--ipa','stable','-g','1']) |
| 1734 | self.assertIn('--ipa is only supported', mock_stderr.getvalue()) |
| 1735 | |
| 1736 | @patch('sys.stderr', new_callable=io.StringIO) |
| 1737 | def test_ParseCommandLine_signed_error(self, mock_stderr): |
| 1738 | with self.assertRaises(SystemExit): |
| 1739 | bisect_builds.ParseCommandLine(['-a','linux64','--signed','-g','1']) |
| 1740 | self.assertIn('--signed is only supported', mock_stderr.getvalue()) |
| 1741 | |
Trung Nguyen | d391d05 | 2025-06-04 09:35:09 | [diff] [blame] | 1742 | @patch('sys.stderr', new_callable=io.StringIO) |
| 1743 | def test_ParseCommandLine_webview_incompatibility_error(self, mock_stderr): |
| 1744 | with self.assertRaises(SystemExit): |
| 1745 | _= bisect_builds.ParseCommandLine([ |
| 1746 | '-r','-a','android-arm64-high','-g','127.0.6533.76','-b', |
| 1747 | '127.0.6533.79','--apk','system_webview' |
| 1748 | ]) |
| 1749 | self.assertIn( |
| 1750 | 'Bisecting WebView for android-arm64-high, please choose official ' |
| 1751 | 'builds (-o)', mock_stderr.getvalue()) |
| 1752 | |
| 1753 | opts= bisect_builds.ParseCommandLine([ |
| 1754 | '-o','-a','android-arm64-high','-g','1334017','-b','1335078', |
| 1755 | '--apk','system_webview' |
| 1756 | ]) |
| 1757 | self.assertEqual(opts.apk,'system_webview') |
| 1758 | self.assertEqual(opts.archive,'android-arm64-high') |
| 1759 | self.assertEqual(opts.build_type,'official') |
| 1760 | |
| 1761 | |
Kuan Huang | 342fec5 | 2024-10-31 18:00:44 | [diff] [blame] | 1762 | @patch('urllib.request.urlopen') |
| 1763 | @patch('builtins.open') |
| 1764 | @patch('sys.stdout', new_callable=io.StringIO) |
| 1765 | def test_update_script(self, mock_stdout, mock_open, mock_urlopen): |
| 1766 | mock_urlopen.return_value= io.BytesIO( |
| 1767 | base64.b64encode('content'.encode('utf-8'))) |
| 1768 | with self.assertRaises(SystemExit): |
| 1769 | bisect_builds.ParseCommandLine(['--update-script']) |
| 1770 | mock_urlopen.assert_called_once_with( |
| 1771 | 'https://chromium.googlesource.com/chromium/src/+/HEAD/' |
| 1772 | 'tools/bisect-builds.py?format=TEXT') |
| 1773 | mock_open.assert_called_once() |
| 1774 | mock_open.return_value.__enter__().write.assert_called_once_with('content') |
| 1775 | self.assertEqual(mock_stdout.getvalue(),'Update successful!\n') |
| 1776 | |
Kuan Huang | c93ac26 | 2024-09-19 18:53:17 | [diff] [blame] | 1777 | @patch("urllib.request.urlopen", |
| 1778 | side_effect=[ |
| 1779 | urllib.request.HTTPError('url',404,'Not Found',None,None), |
| 1780 | urllib.request.HTTPError('url',404,'Not Found',None,None), |
Kuan Huang | 0505884 | 2024-10-24 21:22:26 | [diff] [blame] | 1781 | io.BytesIO(b"NOT_A_JSON"), |
| 1782 | io.BytesIO(b'{"chromium_main_branch_position": 123}'), |
Kuan Huang | c93ac26 | 2024-09-19 18:53:17 | [diff] [blame] | 1783 | ]) |
| 1784 | def test_GetRevisionFromVersion(self, mock_urlopen): |
| 1785 | self.assertEqual(123, |
| 1786 | bisect_builds.GetRevisionFromVersion('127.0.6533.134')) |
| 1787 | mock_urlopen.assert_has_calls([ |
| 1788 | call('https://chromiumdash.appspot.com/fetch_version' |
| 1789 | '?version=127.0.6533.134'), |
| 1790 | call('https://chromiumdash.appspot.com/fetch_version' |
| 1791 | '?version=127.0.6533.0'), |
| 1792 | ]) |
| 1793 | |
Kuan Huang | 0505884 | 2024-10-24 21:22:26 | [diff] [blame] | 1794 | @maybe_patch("urllib.request.urlopen", |
| 1795 | side_effect=[ |
| 1796 | io.BytesIO(b'{"chromium_main_branch_position": null}'), |
| 1797 | io.BytesIO(b'{"message": "DEP\\n"}'), |
| 1798 | io.BytesIO(b')]}\'\n{"message": "Cr-Branched-From: ' |
| 1799 | b'3d60439cfb36485e76a1c5bb7f513d3721b20da1-' |
| 1800 | b'refs/heads/master@{#870763}\\n"}'), |
| 1801 | ]) |
Kuan Huang | 008965f9 | 2024-10-08 21:53:15 | [diff] [blame] | 1802 | def test_GetRevisionFromSourceTag(self, mock_urlopen): |
Kuan Huang | 0505884 | 2024-10-24 21:22:26 | [diff] [blame] | 1803 | self.assertEqual(870763, |
| 1804 | bisect_builds.GetRevisionFromVersion('91.0.4472.38')) |
| 1805 | mock_urlopen.assert_has_calls([ |
| 1806 | call('https://chromiumdash.appspot.com/fetch_version' |
| 1807 | '?version=91.0.4472.38'), |
| 1808 | call('https://chromium.googlesource.com/chromium/src/' |
| 1809 | '+/refs/tags/91.0.4472.38?format=JSON'), |
| 1810 | call('https://chromium.googlesource.com/chromium/src/' |
| 1811 | '+/refs/tags/91.0.4472.38^?format=JSON'), |
| 1812 | ]) |
Kuan Huang | 008965f9 | 2024-10-08 21:53:15 | [diff] [blame] | 1813 | |
Kuan Huang | 94c4a2d1 | 2024-11-21 21:46:09 | [diff] [blame] | 1814 | def test_join_args(self): |
| 1815 | test_data=['a','b c','C:\\a b\\c','/a b/c','"a"',"'a'"] |
| 1816 | quoted_command= bisect_builds.join_args( |
| 1817 | [sys.executable,'-c','import sys, json; print(json.dumps(sys.argv))'] |
| 1818 | + test_data) |
| 1819 | |
| 1820 | subproc= subprocess.Popen( |
| 1821 | quoted_command, shell=True, stdout=subprocess.PIPE) |
| 1822 | stdout, _= subproc.communicate() |
| 1823 | dumped_argv= json.loads(stdout.decode('utf-8')) |
| 1824 | |
| 1825 | self.assertListEqual(dumped_argv,['-c']+ test_data) |
| 1826 | |
Kuan Huang | 37d0daa | 2024-09-19 18:03:08 | [diff] [blame] | 1827 | |
Kuan Huang | 6f7f5794 | 2024-12-05 19:26:30 | [diff] [blame] | 1828 | classChromiumVersionTest(BisectTestCase): |
| 1829 | def test_cmpare_version_numbers(self): |
| 1830 | v127_0_6533_74= bisect_builds.ChromiumVersion('127.0.6533.74') |
| 1831 | v127_0_6533_75= bisect_builds.ChromiumVersion('127.0.6533.75') |
| 1832 | v127_0_6533_75_with_space= bisect_builds.ChromiumVersion('127.0.6533.75 ') |
| 1833 | v127= bisect_builds.ChromiumVersion('127') |
| 1834 | |
| 1835 | self.assertLess(v127_0_6533_74, v127_0_6533_75) |
| 1836 | self.assertLessEqual(v127_0_6533_74, v127_0_6533_75) |
| 1837 | self.assertGreater(v127_0_6533_75, v127_0_6533_74) |
| 1838 | self.assertGreaterEqual(v127_0_6533_75, v127_0_6533_74) |
| 1839 | self.assertEqual(v127_0_6533_75, v127_0_6533_75_with_space) |
| 1840 | self.assertLess(v127, v127_0_6533_74) |
| 1841 | |
enne@chromium.org | eadd95d | 2012-11-02 22:42:09 | [diff] [blame] | 1842 | if __name__=='__main__': |
| 1843 | unittest.main() |