| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 """Integration tests for project.py.""" | |
| 7 | |
| 8 import logging | |
| 9 import os | |
| 10 import random | |
| 11 import shutil | |
| 12 import string | |
| 13 import StringIO | |
| 14 import sys | |
| 15 import tempfile | |
| 16 import time | |
| 17 import unittest | |
| 18 import urllib2 | |
| 19 | |
| 20 ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) | |
| 21 sys.path.insert(0, os.path.join(ROOT_DIR, '..')) | |
| 22 | |
| 23 import projects | |
| 24 from verification import base | |
| 25 from verification import presubmit_check | |
| 26 from verification import try_job_on_rietveld | |
| 27 | |
| 28 # From /tests | |
| 29 import mocks | |
| 30 | |
| 31 | |
| 32 def _try_comment(pc, issue=31337): | |
| 33 return ( | |
| 34 "add_comment(%d, u'%shttp://localhost/user@example.com/%d/1\\n')" % | |
| 35 (issue, pc.TRYING_PATCH.replace('\n', '\\n'), | |
| 36 issue)) | |
| 37 | |
| 38 | |
| 39 class TestCase(mocks.TestCase): | |
| 40 def setUp(self): | |
| 41 super(TestCase, self).setUp() | |
| 42 self.mock(projects, '_read_lines', self._read_lines) | |
| 43 self.mock( | |
| 44 projects.async_push, | |
| 45 'AsyncPush', lambda _1, _2: mocks.AsyncPushMock(self)) | |
| 46 class Dummy(object): | |
| 47 @staticmethod | |
| 48 def get_list(): | |
| 49 return [] | |
| 50 if not projects.chromium_committers: | |
| 51 projects.chromium_committers = Dummy() | |
| 52 self.mock( | |
| 53 projects.chromium_committers, 'get_list', self._get_committers_list) | |
| 54 if not projects.nacl_committers: | |
| 55 projects.nacl_committers = Dummy() | |
| 56 self.mock(projects.nacl_committers, 'get_list', self._get_committers_list) | |
| 57 self.mock(presubmit_check.subprocess2, 'check_output', self._check_output) | |
| 58 self.mock(urllib2, 'urlopen', self._urlopen) | |
| 59 self.mock(time, 'time', self._time) | |
| 60 self.check_output = [] | |
| 61 self.read_lines = [] | |
| 62 self.urlrequests = [] | |
| 63 self.time = [] | |
| 64 | |
| 65 def tearDown(self): | |
| 66 try: | |
| 67 if not self.has_failed(): | |
| 68 self.assertEqual([], self.check_output) | |
| 69 self.assertEqual([], self.read_lines) | |
| 70 self.assertEqual([], self.urlrequests) | |
| 71 self.assertEqual([], self.time) | |
| 72 finally: | |
| 73 super(TestCase, self).tearDown() | |
| 74 | |
| 75 # Mocks | |
| 76 def _urlopen(self, url): | |
| 77 if not self.urlrequests: | |
| 78 self.fail(url) | |
| 79 expected_url, data = self.urlrequests.pop(0) | |
| 80 self.assertEqual(expected_url, url) | |
| 81 return StringIO.StringIO(data) | |
| 82 | |
| 83 @staticmethod | |
| 84 def _get_committers_list(): | |
| 85 return ['user@example.com', 'user@example.org'] | |
| 86 | |
| 87 def _read_lines(self, root, error): | |
| 88 if not self.read_lines: | |
| 89 self.fail(root) | |
| 90 a = self.read_lines.pop(0) | |
| 91 self.assertEqual(a[0], root) | |
| 92 self.assertEqual(a[1], error) | |
| 93 return a[2] | |
| 94 | |
| 95 def _check_output(self, *args, **kwargs): | |
| 96 # For now, ignore the arguments. Change if necessary. | |
| 97 if not self.check_output: | |
| 98 self.fail((args, kwargs)) | |
| 99 return self.check_output.pop(0) | |
| 100 | |
| 101 def _time(self): | |
| 102 self.assertTrue(self.time) | |
| 103 return self.time.pop(0) | |
| 104 | |
| 105 | |
| 106 class ProjectTest(TestCase): | |
| 107 def setUp(self): | |
| 108 super(ProjectTest, self).setUp() | |
| 109 | |
| 110 def test_loaded(self): | |
| 111 members = ( | |
| 112 'blink', 'chromium', 'chromium_deps', 'gyp', 'nacl', 'skia', 'tools') | |
| 113 self.assertEqual(sorted(members), sorted(projects.supported_projects())) | |
| 114 | |
| 115 def test_all(self): | |
| 116 # Make sure it's possible to load each project. | |
| 117 self.time = [1] * 2 | |
| 118 root_dir = os.path.join(os.getcwd(), 'root_dir') | |
| 119 chromium_status_pwd = os.path.join(root_dir, '.chromium_status_pwd') | |
| 120 skia_status_pwd = os.path.join(root_dir, '.skia_status_pwd') | |
| 121 mapping = { | |
| 122 'blink': { | |
| 123 'lines': [ | |
| 124 chromium_status_pwd, 'chromium-status password', ['foo'], | |
| 125 ], | |
| 126 'pre_patch_verifiers': ['project_bases', 'reviewer_lgtm'], | |
| 127 'verifiers': ['try job rietveld', 'tree status'], | |
| 128 }, | |
| 129 'chromium': { | |
| 130 'lines': [ | |
| 131 chromium_status_pwd, 'chromium-status password', ['foo'], | |
| 132 ], | |
| 133 'pre_patch_verifiers': ['project_bases', 'reviewer_lgtm'], | |
| 134 'verifiers': ['try job rietveld', 'tree status'], | |
| 135 }, | |
| 136 'chromium_deps': { | |
| 137 'lines': [ | |
| 138 chromium_status_pwd, 'chromium-status password', ['foo'], | |
| 139 ], | |
| 140 'pre_patch_verifiers': ['project_bases', 'reviewer_lgtm'], | |
| 141 'verifiers': ['presubmit'], | |
| 142 }, | |
| 143 'gyp': { | |
| 144 'lines': [ | |
| 145 chromium_status_pwd, 'chromium-status password', ['foo'], | |
| 146 ], | |
| 147 'pre_patch_verifiers': ['project_bases', 'reviewer_lgtm'], | |
| 148 'verifiers': ['tree status'], | |
| 149 }, | |
| 150 'nacl': { | |
| 151 'lines': [ | |
| 152 chromium_status_pwd, 'chromium-status password', ['foo'], | |
| 153 ], | |
| 154 'pre_patch_verifiers': ['project_bases', 'reviewer_lgtm'], | |
| 155 'verifiers': ['presubmit', 'tree status'], | |
| 156 }, | |
| 157 'skia': { | |
| 158 'lines': [ | |
| 159 skia_status_pwd, 'skia-status password', ['foo'], | |
| 160 ], | |
| 161 'pre_patch_verifiers': ['project_bases', 'reviewer_lgtm'], | |
| 162 'verifiers': ['presubmit', 'tree status'], | |
| 163 }, | |
| 164 'tools': { | |
| 165 'lines': [ | |
| 166 chromium_status_pwd, 'chromium-status password', ['foo'], | |
| 167 ], | |
| 168 'pre_patch_verifiers': ['project_bases', 'reviewer_lgtm'], | |
| 169 'verifiers': ['presubmit'], | |
| 170 }, | |
| 171 } | |
| 172 for project in sorted(projects.supported_projects()): | |
| 173 logging.debug(project) | |
| 174 self.assertEqual([], self.read_lines) | |
| 175 expected = mapping.pop(project) | |
| 176 self.read_lines = [expected['lines']] | |
| 177 p = projects.load_project( | |
| 178 project, 'user', root_dir, self.context.rietveld, True) | |
| 179 self.assertEqual( | |
| 180 expected['pre_patch_verifiers'], | |
| 181 [x.name for x in p.pre_patch_verifiers], | |
| 182 (expected['pre_patch_verifiers'], | |
| 183 [x.name for x in p.pre_patch_verifiers], | |
| 184 project)) | |
| 185 self.assertEqual( | |
| 186 expected['verifiers'], [x.name for x in p.verifiers], | |
| 187 (expected['verifiers'], | |
| 188 [x.name for x in p.verifiers], | |
| 189 project)) | |
| 190 if project == 'tools': | |
| 191 # Add special checks for it. | |
| 192 project_bases_verifier = p.pre_patch_verifiers[0] | |
| 193 branch = '\\@[a-zA-Z0-9\\-_\\.]+$' | |
| 194 self.assertEqual( | |
| 195 [ | |
| 196 # svn | |
| 197 '^svn\\:\\/\\/svn\\.chromium\\.org\\/chrome/trunk/tools(|/.*)$', | |
| 198 '^svn\\:\\/\\/chrome\\-svn\\/chrome/trunk/tools(|/.*)$', | |
| 199 '^svn\\:\\/\\/chrome\\-svn\\.corp\\/chrome/trunk/tools(|/.*)$', | |
| 200 '^svn\\:\\/\\/chrome\\-svn\\.corp\\.google\\.com\\/chrome/trunk/' | |
| 201 'tools(|/.*)$', | |
| 202 '^http\\:\\/\\/src\\.chromium\\.org\\/svn/trunk/tools(|/.*)$', | |
| 203 '^https\\:\\/\\/src\\.chromium\\.org\\/svn/trunk/tools(|/.*)$', | |
| 204 '^http\\:\\/\\/src\\.chromium\\.org\\/chrome/trunk/tools(|/.*)$', | |
| 205 '^https\\:\\/\\/src\\.chromium\\.org\\/chrome/trunk/tools(|/.*)$', | |
| 206 | |
| 207 # git | |
| 208 '^https?\\:\\/\\/git\\.chromium\\.org\\/git\\/chromium\\/tools\\/' | |
| 209 '([a-z0-9\\-_]+)(?:\\.git)?' + branch, | |
| 210 '^https?\\:\\/\\/git\\.chromium\\.org\\/chromium\\/tools\\/' | |
| 211 '([a-z0-9\\-_]+)(?:\\.git)?' + branch, | |
| 212 '^https?\\:\\/\\/chromium\\.googlesource\\.com\\/chromium\\/tools' | |
| 213 '\\/([a-z0-9\\-_]+)(?:\\.git)?' + branch, | |
| 214 '^https?\\:\\/\\/chromium\\.googlesource\\.com\\/a\\/chromium\\/' | |
| 215 'tools\\/([a-z0-9\\-_]+)(?:\\.git)?' + branch, | |
| 216 ], | |
| 217 project_bases_verifier.project_bases) | |
| 218 self.assertEqual({}, mapping) | |
| 219 | |
| 220 | |
| 221 class ChromiumStateLoad(TestCase): | |
| 222 # Load a complete state and ensure the code is reacting properly. | |
| 223 def setUp(self): | |
| 224 super(ChromiumStateLoad, self).setUp() | |
| 225 self.buildbot = mocks.BuildbotMock(self) | |
| 226 self.mock( | |
| 227 try_job_on_rietveld.buildbot_json, 'Buildbot', lambda _: self.buildbot) | |
| 228 self.tempdir = tempfile.mkdtemp(prefix='project_test') | |
| 229 self.now = None | |
| 230 | |
| 231 def tearDown(self): | |
| 232 try: | |
| 233 shutil.rmtree(self.tempdir) | |
| 234 finally: | |
| 235 super(ChromiumStateLoad, self).tearDown() | |
| 236 | |
| 237 def _add_build(self, builder, buildnumber, revision, steps, completed): | |
| 238 """Adds a build with a randomly generated key.""" | |
| 239 key = ''.join(random.choice(string.ascii_letters) for _ in xrange(8)) | |
| 240 build = self.buildbot.add_build( | |
| 241 builder, buildnumber, revision, key, completed, None) | |
| 242 build.steps.extend(steps) | |
| 243 return key | |
| 244 | |
| 245 def _LoadPendingManagerState(self, issue): | |
| 246 self.urlrequests = [ | |
| 247 ( 'http://chromium-status.appspot.com/allstatus?format=json&endTime=%d' % | |
| 248 (self.now - 300), | |
| 249 # In theory we should return something but nothing works fine. | |
| 250 '[]'), | |
| 251 ] | |
| 252 self.read_lines = [ | |
| 253 [ | |
| 254 os.path.join(self.tempdir, '.chromium_status_pwd'), | |
| 255 'chromium-status password', | |
| 256 ['foo'], | |
| 257 ], | |
| 258 ] | |
| 259 self.context.rietveld.patchsets_properties[(issue, 1)] = {} | |
| 260 | |
| 261 self.time = [self.now] * 1 | |
| 262 pc = projects.load_project( | |
| 263 'chromium', 'invalid', self.tempdir, self.context.rietveld, False) | |
| 264 self.assertEqual(0, len(self.time)) | |
| 265 pc.context = self.context | |
| 266 pc.load(os.path.join(ROOT_DIR, 'chromium.%d.json' % issue)) | |
| 267 | |
| 268 # Verify the content a bit. | |
| 269 self.assertEqual(1, len(pc.queue.iterate())) | |
| 270 self.assertEqual(issue, pc.queue.get(issue).issue) | |
| 271 expected = [ | |
| 272 u'presubmit', | |
| 273 u'project_bases', | |
| 274 u'reviewer_lgtm', | |
| 275 u'tree status', | |
| 276 u'try job rietveld', | |
| 277 ] | |
| 278 self.assertEqual(expected, sorted(pc.queue.get(issue).verifications)) | |
| 279 | |
| 280 return pc | |
| 281 | |
| 282 def _verify_final_state(self, verifications, why_not, rietveld_calls): | |
| 283 for name, obj in verifications.iteritems(): | |
| 284 if name == 'try job rietveld': | |
| 285 self.assertEqual(base.PROCESSING, obj.get_state(), name) | |
| 286 self.assertEqual(why_not, obj.why_not()) | |
| 287 else: | |
| 288 self.assertEqual(base.SUCCEEDED, obj.get_state(), name) | |
| 289 self.assertEqual(None, obj.why_not()) | |
| 290 | |
| 291 if name == 'tree status': | |
| 292 self.time = [self.now] * 1 | |
| 293 self.assertEqual(False, obj.postpone(), name) | |
| 294 self.assertEqual(0, len(self.time)) | |
| 295 else: | |
| 296 self.assertEqual(False, obj.postpone(), name) | |
| 297 self.context.rietveld.check_calls(rietveld_calls) | |
| 298 | |
| 299 def testLoadState(self): | |
| 300 self.now = 1354207000. | |
| 301 issue = 31337 | |
| 302 pending_manager = self._LoadPendingManagerState(issue) | |
| 303 | |
| 304 # Then fix the crap out of it. | |
| 305 self.time = [self.now] * 3 | |
| 306 pending_manager.update_status() | |
| 307 self.assertEqual(0, len(self.time)) | |
| 308 self.assertEqual(1, len(pending_manager.queue.iterate())) | |
| 309 | |
| 310 why_not = (u'Waiting for the following jobs:\n' | |
| 311 ' win_rel: sync_integration_tests\n') | |
| 312 rietveld_calls = [ | |
| 313 "trigger_try_jobs(%d, 1, 'CQ', False, 'HEAD', {u'win_rel': " | |
| 314 "[u'sync_integration_tests']})" % issue | |
| 315 ] | |
| 316 self._verify_final_state(pending_manager.queue.get(issue).verifications, | |
| 317 why_not, rietveld_calls) | |
| 318 | |
| 319 def testLoadState11299256(self): | |
| 320 # Loads a saved state and try to revive it. | |
| 321 self.now = 1354551606. | |
| 322 issue = 11299256 | |
| 323 pending_manager = self._LoadPendingManagerState(issue) | |
| 324 self._add_build('ios_rel_device', 1, 2, [], 4) | |
| 325 | |
| 326 # Then fix the crap out of it. | |
| 327 self.time = [self.now] * 3 | |
| 328 pending_manager.update_status() | |
| 329 self.assertEqual(1, len(self.time)) | |
| 330 self.assertEqual(1, len(pending_manager.queue.iterate())) | |
| 331 | |
| 332 why_not = (u'Waiting for the following jobs:\n' | |
| 333 ' ios_rel_device: compile\n') | |
| 334 rietveld_calls = [] | |
| 335 # ios_rel_device seems lost. CQ should not reissue it now to avoid | |
| 336 # overloading the tryserver. | |
| 337 self._verify_final_state(pending_manager.queue.get(issue).verifications, | |
| 338 why_not, rietveld_calls) | |
| 339 | |
| 340 def testLoadState12208028(self): | |
| 341 # Loads a saved state and try to revive it. | |
| 342 self.now = 1360256000. | |
| 343 issue = 12208028 | |
| 344 pending_manager = self._LoadPendingManagerState(issue) | |
| 345 | |
| 346 # Then fix the crap out of it. | |
| 347 self.time = [self.now] * 3 | |
| 348 pending_manager.update_status() | |
| 349 self.assertEqual(0, len(self.time)) | |
| 350 self.assertEqual(1, len(pending_manager.queue.iterate())) | |
| 351 | |
| 352 why_not = (u'Waiting for the following jobs:\n' | |
| 353 ' android_dbg_triggered_tests: build\n') | |
| 354 rietveld_calls = [ | |
| 355 "trigger_try_jobs(%d, 1, 'CQ', False, 'HEAD', {u'android_dbg': " | |
| 356 "[u'build']})" % issue | |
| 357 ] | |
| 358 self._verify_final_state(pending_manager.queue.get(issue).verifications, | |
| 359 why_not, rietveld_calls) | |
| 360 | |
| 361 def testLoadState12253015(self): | |
| 362 # Loads a saved state and try to revive it. | |
| 363 self.now = 1360256000. | |
| 364 issue = 12253015 | |
| 365 pending_manager = self._LoadPendingManagerState(issue) | |
| 366 | |
| 367 # Then fix the crap out of it. | |
| 368 self.time = [self.now] * 3 | |
| 369 pending_manager.update_status() | |
| 370 self.assertEqual(0, len(self.time)) | |
| 371 self.assertEqual(1, len(pending_manager.queue.iterate())) | |
| 372 | |
| 373 why_not = ( | |
| 374 u'Waiting for the following jobs:\n' | |
| 375 ' win7_aura: browser_tests\n' | |
| 376 ' win_rel: chrome_frame_tests,chrome_frame_net_tests,browser_tests,' | |
| 377 'nacl_integration,sync_integration_tests,installer_util_unittests,' | |
| 378 'content_browsertests,chrome_frame_unittests,mini_installer_test\n') | |
| 379 rietveld_calls = [ | |
| 380 "trigger_try_jobs(%d, 1, 'CQ', False, 'HEAD', {u'win7_aura': " | |
| 381 "[u'browser_tests']})" % issue, | |
| 382 ] | |
| 383 self._verify_final_state(pending_manager.queue.get(issue).verifications, | |
| 384 why_not, rietveld_calls) | |
| 385 | |
| 386 def testLoadState12633013(self): | |
| 387 # Loads a saved state and try to revive it. | |
| 388 self.now = 1363610000. | |
| 389 issue = 12633013 | |
| 390 pending_manager = self._LoadPendingManagerState(issue) | |
| 391 | |
| 392 # Then fix the crap out of it. | |
| 393 self.time = [self.now] * 3 | |
| 394 pending_manager.update_status() | |
| 395 self.assertEqual(0, len(self.time)) | |
| 396 self.assertEqual(1, len(pending_manager.queue.iterate())) | |
| 397 | |
| 398 why_not = ( | |
| 399 u'Waiting for the following jobs:\n' | |
| 400 ' android_dbg_triggered_tests: slave_steps\n') | |
| 401 rietveld_calls = [ | |
| 402 "trigger_try_jobs(%d, 1, 'CQ', False, 'HEAD', {u'android_dbg': " | |
| 403 "[u'slave_steps']})" % issue, | |
| 404 ] | |
| 405 self._verify_final_state(pending_manager.queue.get(issue).verifications, | |
| 406 why_not, rietveld_calls) | |
| 407 | |
| 408 def testLoadStateSwarm(self): | |
| 409 # Loads a saved state and try to revive it. | |
| 410 self.now = 1360256000. | |
| 411 issue = 666 | |
| 412 pending_manager = self._LoadPendingManagerState(issue) | |
| 413 | |
| 414 # Then fix the crap out of it. | |
| 415 self.time = [self.now] * 5 | |
| 416 pending_manager.update_status() | |
| 417 self.assertEqual(0, len(self.time)) | |
| 418 self.assertEqual(1, len(pending_manager.queue.iterate())) | |
| 419 | |
| 420 why_not = (u'Waiting for the following jobs:\n' | |
| 421 ' linux_rel: browser_tests\n' | |
| 422 ' mac_rel: browser_tests\n' | |
| 423 ' win_rel: browser_tests\n') | |
| 424 # TODO(csharp): These triggered events should be the swarm versions, | |
| 425 # change them once swarm tests are enabled by default. | |
| 426 rietveld_calls = [ | |
| 427 "trigger_try_jobs(%d, 1, 'CQ', False, 'HEAD', {u'linux_rel': " | |
| 428 "[u'browser_tests']})" % issue, | |
| 429 "trigger_try_jobs(%d, 1, 'CQ', False, 'HEAD', {u'mac_rel': " | |
| 430 "[u'browser_tests']})" % issue, | |
| 431 "trigger_try_jobs(%d, 1, 'CQ', False, 'HEAD', {u'win_rel': " | |
| 432 "[u'browser_tests']})" % issue, | |
| 433 ] | |
| 434 self._verify_final_state(pending_manager.queue.get(issue).verifications, | |
| 435 why_not, rietveld_calls) | |
| 436 | |
| 437 def test_tbr(self): | |
| 438 self.time = map(lambda x: float(x*35), range(15)) | |
| 439 self.urlrequests = [ | |
| 440 ('https://chromium-status.appspot.com/allstatus?format=json&endTime=85', | |
| 441 # Cheap hack here. | |
| 442 '[]'), | |
| 443 ] | |
| 444 root_dir = os.path.join(os.getcwd(), 'root_dir') | |
| 445 self.read_lines = [ | |
| 446 [ | |
| 447 os.path.join(root_dir, '.chromium_status_pwd'), | |
| 448 'chromium-status password', | |
| 449 ['foo'], | |
| 450 ], | |
| 451 ] | |
| 452 pc = projects.load_project( | |
| 453 'chromium', 'commit-bot-test', root_dir, self.context.rietveld, True) | |
| 454 pc.context = self.context | |
| 455 issue = self.context.rietveld.issues[31337] | |
| 456 self.context.rietveld.patchsets_properties[(31337, 1)] = {} | |
| 457 | |
| 458 # A TBR= patch without reviewer nor messages, like a webkit roll. | |
| 459 issue['description'] += '\nTBR=' | |
| 460 issue['reviewers'] = [] | |
| 461 issue['messages'] = [] | |
| 462 issue['owner_email'] = u'user@example.com' | |
| 463 issue['base_url'] = u'svn://svn.chromium.org/chrome/trunk/src' | |
| 464 pc.look_for_new_pending_commit() | |
| 465 pc.process_new_pending_commit() | |
| 466 pc.update_status() | |
| 467 pc.scan_results() | |
| 468 self.assertEqual(1, len(pc.queue.iterate())) | |
| 469 key = self._add_build('chromium_presubmit', 123456, 124, | |
| 470 [mocks.BuildbotBuildStep('presubmit', False)], True) | |
| 471 self.context.rietveld.patchsets_properties[(31337, 1)] = { | |
| 472 'try_job_results': [{ | |
| 473 'builder': "chromium_presubmit", | |
| 474 'key': key, | |
| 475 'buildnumber': "123456", | |
| 476 }]} | |
| 477 build = self.buildbot.builders['chromium_presubmit'].builds[123456] | |
| 478 build.steps[0].simplified_result = True | |
| 479 pc.update_status() | |
| 480 pc.scan_results() | |
| 481 self.assertEqual(0, len(pc.queue.iterate())) | |
| 482 # check_calls | |
| 483 self.context.rietveld.check_calls([ | |
| 484 _try_comment(pc), | |
| 485 "trigger_try_jobs(31337, 1, 'CQ', False, 'HEAD', " | |
| 486 "{u'chromium_presubmit': ['presubmit']})", | |
| 487 'close_issue(31337)', | |
| 488 "update_description(31337, u'foo\\nTBR=')", | |
| 489 "add_comment(31337, 'Change committed as 125')", | |
| 490 ]) | |
| 491 self.context.checkout.check_calls([ | |
| 492 'prepare(None)', | |
| 493 'apply_patch(%r)' % self.context.rietveld.patchsets[0], | |
| 494 'prepare(None)', | |
| 495 'apply_patch(%r)' % self.context.rietveld.patchsets[1], | |
| 496 "commit(u'foo\\nTBR=\\n\\nReview URL: http://nowhere/31337', " | |
| 497 "u'user@example.com')", | |
| 498 ]) | |
| 499 self.context.status.check_names(['initial', 'why not', 'why not', | |
| 500 'why not', 'commit']) | |
| 501 | |
| 502 | |
| 503 | |
| 504 if __name__ == '__main__': | |
| 505 logging.basicConfig( | |
| 506 level=logging.DEBUG if '-v' in sys.argv else logging.WARNING, | |
| 507 format='%(levelname)5s %(module)15s(%(lineno)3d): %(message)s') | |
| 508 unittest.main() | |
| OLD | NEW |