| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 2 # Copyright 2013 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 import hashlib | |
| 7 import json | |
| 8 import logging | |
| 9 import os | |
| 10 import StringIO | |
| 11 import sys | |
| 12 import threading | |
| 13 import unittest | |
| 14 | |
| 15 import auto_stub | |
| 16 | |
| 17 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
| 18 sys.path.insert(0, ROOT_DIR) | |
| 19 | |
| 20 import swarming | |
| 21 from utils import net | |
| 22 | |
| 23 | |
| 24 ALGO = hashlib.sha1 | |
| 25 FILE_NAME = u'test.isolated' | |
| 26 FILE_HASH = u'1' * 40 | |
| 27 TEST_NAME = u'unit_tests' | |
| 28 STDOUT_FOR_TRIGGER_LEN = 180 | |
| 29 | |
| 30 | |
| 31 TEST_CASE_SUCCESS = ( | |
| 32 '[----------] 2 tests from StaticCookiePolicyTest\n' | |
| 33 '[ RUN ] StaticCookiePolicyTest.AllowAllCookiesTest\n' | |
| 34 '[ OK ] StaticCookiePolicyTest.AllowAllCookiesTest (0 ms)\n' | |
| 35 '[ RUN ] StaticCookiePolicyTest.BlockAllCookiesTest\n' | |
| 36 '[ OK ] StaticCookiePolicyTest.BlockAllCookiesTest (0 ms)\n' | |
| 37 '[----------] 2 tests from StaticCookiePolicyTest (0 ms total)\n' | |
| 38 '\n' | |
| 39 '[----------] 1 test from TCPListenSocketTest\n' | |
| 40 '[ RUN ] TCPListenSocketTest.ServerSend\n' | |
| 41 '[ OK ] TCPListenSocketTest.ServerSend (1 ms)\n' | |
| 42 '[----------] 1 test from TCPListenSocketTest (1 ms total)\n') | |
| 43 | |
| 44 | |
| 45 TEST_CASE_FAILURE = ( | |
| 46 '[----------] 2 tests from StaticCookiePolicyTest\n' | |
| 47 '[ RUN ] StaticCookiePolicyTest.AllowAllCookiesTest\n' | |
| 48 '[ OK ] StaticCookiePolicyTest.AllowAllCookiesTest (0 ms)\n' | |
| 49 '[ RUN ] StaticCookiePolicyTest.BlockAllCookiesTest\n' | |
| 50 'C:\\win\\build\\src\\chrome\\test.cc: error: Value of: result()\n' | |
| 51 ' Actual: false\n' | |
| 52 'Expected: true\n' | |
| 53 '[ FAILED ] StaticCookiePolicyTest.BlockAllCookiesTest (0 ms)\n' | |
| 54 '[----------] 2 tests from StaticCookiePolicyTest (0 ms total)\n' | |
| 55 '\n' | |
| 56 '[----------] 1 test from TCPListenSocketTest\n' | |
| 57 '[ RUN ] TCPListenSocketTest.ServerSend\n' | |
| 58 '[ OK ] TCPListenSocketTest.ServerSend (1 ms)\n' | |
| 59 '[----------] 1 test from TCPListenSocketTest (1 ms total)\n') | |
| 60 | |
| 61 | |
| 62 SWARM_OUTPUT_SUCCESS = ( | |
| 63 '[ RUN ] unittests.Run Test\n' + | |
| 64 TEST_CASE_SUCCESS + | |
| 65 '[ OK ] unittests.Run Test (2549 ms)\n' | |
| 66 '[ RUN ] unittests.Clean Up\n' | |
| 67 'No output!\n' | |
| 68 '[ OK ] unittests.Clean Up (6 ms)\n' | |
| 69 '\n' | |
| 70 '[----------] unittests summary\n' | |
| 71 '[==========] 2 tests ran. (2556 ms total)\n') | |
| 72 | |
| 73 | |
| 74 SWARM_OUTPUT_FAILURE = ( | |
| 75 '[ RUN ] unittests.Run Test\n' + | |
| 76 TEST_CASE_FAILURE + | |
| 77 '[ OK ] unittests.Run Test (2549 ms)\n' | |
| 78 '[ RUN ] unittests.Clean Up\n' | |
| 79 'No output!\n' | |
| 80 '[ OK ] unittests.Clean Up (6 ms)\n' | |
| 81 '\n' | |
| 82 '[----------] unittests summary\n' | |
| 83 '[==========] 2 tests ran. (2556 ms total)\n') | |
| 84 | |
| 85 | |
| 86 SWARM_OUTPUT_WITH_NO_TEST_OUTPUT = ( | |
| 87 '\n' | |
| 88 'Unable to connection to swarm machine.\n') | |
| 89 | |
| 90 | |
| 91 TEST_SHARD_1 = 'Note: This is test shard 1 of 3.' | |
| 92 TEST_SHARD_2 = 'Note: This is test shard 2 of 3.' | |
| 93 TEST_SHARD_3 = 'Note: This is test shard 3 of 3.' | |
| 94 | |
| 95 | |
| 96 SWARM_SHARD_OUTPUT = ( | |
| 97 '[ RUN ] unittests.Run Test\n' | |
| 98 '%s\n' | |
| 99 '[ OK ] unittests.Run Test (2549 ms)\n' | |
| 100 '[ RUN ] unittests.Clean Up\n' | |
| 101 'No output!\n' | |
| 102 '[ OK ] unittests.Clean Up (6 ms)\n' | |
| 103 '\n' | |
| 104 '[----------] unittests summary\n' | |
| 105 '[==========] 2 tests ran. (2556 ms total)\n') | |
| 106 | |
| 107 | |
| 108 TEST_SHARD_OUTPUT_1 = SWARM_SHARD_OUTPUT % TEST_SHARD_1 | |
| 109 TEST_SHARD_OUTPUT_2 = SWARM_SHARD_OUTPUT % TEST_SHARD_2 | |
| 110 TEST_SHARD_OUTPUT_3 = SWARM_SHARD_OUTPUT % TEST_SHARD_3 | |
| 111 | |
| 112 | |
| 113 def gen_data(index, shard_output, exit_codes): | |
| 114 return { | |
| 115 u'config_instance_index': index, | |
| 116 u'exit_codes': unicode(exit_codes), | |
| 117 u'machine_id': u'host', | |
| 118 u'machine_tag': u'localhost', | |
| 119 u'output': unicode(shard_output), | |
| 120 } | |
| 121 | |
| 122 | |
| 123 def gen_yielded_data(index, shard_output, exit_codes): | |
| 124 """Returns an entry as it would be yielded by yield_results().""" | |
| 125 return index, gen_data(index, shard_output, exit_codes) | |
| 126 | |
| 127 | |
| 128 def generate_url_response(index, shard_output, exit_codes): | |
| 129 return net.HttpResponse.get_fake_response( | |
| 130 json.dumps(gen_data(index, shard_output, exit_codes)), 'mocked_url') | |
| 131 | |
| 132 | |
| 133 def get_swarm_results(keys): | |
| 134 """Simplifies the call to yield_results(). | |
| 135 | |
| 136 The timeout is hard-coded to 10 seconds. | |
| 137 """ | |
| 138 return list(swarming.yield_results('http://host:9001', keys, 10., None)) | |
| 139 | |
| 140 | |
| 141 class TestCase(auto_stub.TestCase): | |
| 142 """Base class that defines the url_open mock.""" | |
| 143 def setUp(self): | |
| 144 super(TestCase, self).setUp() | |
| 145 self._lock = threading.Lock() | |
| 146 self.requests = [] | |
| 147 self.mock(swarming.net, 'url_open', self._url_open) | |
| 148 | |
| 149 def tearDown(self): | |
| 150 try: | |
| 151 if not self.has_failed(): | |
| 152 self.assertEqual([], self.requests) | |
| 153 finally: | |
| 154 super(TestCase, self).tearDown() | |
| 155 | |
| 156 def _url_open(self, url, **kwargs): | |
| 157 logging.info('url_open(%s)', url) | |
| 158 with self._lock: | |
| 159 # Ignore 'stream' argument, it's not important for these tests. | |
| 160 kwargs.pop('stream') | |
| 161 # Since the client is multi-threaded, requests can be processed out of | |
| 162 # order. | |
| 163 for index, r in enumerate(self.requests): | |
| 164 if r[0] == url and r[1] == kwargs: | |
| 165 _, _, returned = self.requests.pop(index) | |
| 166 break | |
| 167 else: | |
| 168 self.fail('Failed to find url %s' % url) | |
| 169 return returned | |
| 170 | |
| 171 | |
| 172 class TestGetTestKeys(TestCase): | |
| 173 def test_no_keys(self): | |
| 174 self.mock(swarming.time, 'sleep', lambda x: x) | |
| 175 self.requests = [ | |
| 176 ( | |
| 177 'http://host:9001/get_matching_test_cases?name=my_test', | |
| 178 {'retry_404': True}, | |
| 179 StringIO.StringIO('No matching Test Cases'), | |
| 180 ) for _ in range(net.URL_OPEN_MAX_ATTEMPTS) | |
| 181 ] | |
| 182 try: | |
| 183 swarming.get_test_keys('http://host:9001', 'my_test') | |
| 184 self.fail() | |
| 185 except swarming.Failure as e: | |
| 186 msg = ( | |
| 187 'Error: Unable to find any tests with the name, my_test, on swarm ' | |
| 188 'server') | |
| 189 self.assertEqual(msg, e.args[0]) | |
| 190 | |
| 191 def test_no_keys_on_first_attempt(self): | |
| 192 self.mock(swarming.time, 'sleep', lambda x: x) | |
| 193 keys = ['key_1', 'key_2'] | |
| 194 self.requests = [ | |
| 195 ( | |
| 196 'http://host:9001/get_matching_test_cases?name=my_test', | |
| 197 {'retry_404': True}, | |
| 198 StringIO.StringIO('No matching Test Cases'), | |
| 199 ), | |
| 200 ( | |
| 201 'http://host:9001/get_matching_test_cases?name=my_test', | |
| 202 {'retry_404': True}, | |
| 203 StringIO.StringIO(json.dumps(keys)), | |
| 204 ), | |
| 205 ] | |
| 206 actual = swarming.get_test_keys('http://host:9001', 'my_test') | |
| 207 self.assertEqual(keys, actual) | |
| 208 | |
| 209 def test_find_keys(self): | |
| 210 keys = ['key_1', 'key_2'] | |
| 211 self.requests = [ | |
| 212 ( | |
| 213 'http://host:9001/get_matching_test_cases?name=my_test', | |
| 214 {'retry_404': True}, | |
| 215 StringIO.StringIO(json.dumps(keys)), | |
| 216 ), | |
| 217 ] | |
| 218 actual = swarming.get_test_keys('http://host:9001', 'my_test') | |
| 219 self.assertEqual(keys, actual) | |
| 220 | |
| 221 | |
| 222 class TestGetSwarmResults(TestCase): | |
| 223 def test_success(self): | |
| 224 self.requests = [ | |
| 225 ( | |
| 226 'http://host:9001/get_result?r=key1', | |
| 227 {'retry_404': False, 'retry_50x': False}, | |
| 228 generate_url_response(0, SWARM_OUTPUT_SUCCESS, '0, 0'), | |
| 229 ), | |
| 230 ] | |
| 231 expected = [gen_yielded_data(0, SWARM_OUTPUT_SUCCESS, '0, 0')] | |
| 232 actual = get_swarm_results(['key1']) | |
| 233 self.assertEqual(expected, actual) | |
| 234 | |
| 235 def test_failure(self): | |
| 236 self.requests = [ | |
| 237 ( | |
| 238 'http://host:9001/get_result?r=key1', | |
| 239 {'retry_404': False, 'retry_50x': False}, | |
| 240 generate_url_response(0, SWARM_OUTPUT_FAILURE, '0, 1'), | |
| 241 ), | |
| 242 ] | |
| 243 expected = [gen_yielded_data(0, SWARM_OUTPUT_FAILURE, '0, 1')] | |
| 244 actual = get_swarm_results(['key1']) | |
| 245 self.assertEqual(expected, actual) | |
| 246 | |
| 247 def test_no_test_output(self): | |
| 248 self.requests = [ | |
| 249 ( | |
| 250 'http://host:9001/get_result?r=key1', | |
| 251 {'retry_404': False, 'retry_50x': False}, | |
| 252 generate_url_response(0, SWARM_OUTPUT_WITH_NO_TEST_OUTPUT, '0, 0'), | |
| 253 ), | |
| 254 ] | |
| 255 expected = [gen_yielded_data(0, SWARM_OUTPUT_WITH_NO_TEST_OUTPUT, '0, 0')] | |
| 256 actual = get_swarm_results(['key1']) | |
| 257 self.assertEqual(expected, actual) | |
| 258 | |
| 259 def test_no_keys(self): | |
| 260 actual = get_swarm_results([]) | |
| 261 self.assertEqual([], actual) | |
| 262 | |
| 263 def test_url_errors(self): | |
| 264 self.mock(logging, 'error', lambda *_: None) | |
| 265 # NOTE: get_swarm_results() hardcodes timeout=10. range(12) is because of an | |
| 266 # additional time.time() call deep in net.url_open(). | |
| 267 now = {} | |
| 268 lock = threading.Lock() | |
| 269 def get_now(): | |
| 270 t = threading.current_thread() | |
| 271 with lock: | |
| 272 return now.setdefault(t, range(12)).pop(0) | |
| 273 self.mock(swarming.net, 'sleep_before_retry', lambda _x, _y: None) | |
| 274 self.mock(swarming, 'now', get_now) | |
| 275 # The actual number of requests here depends on 'now' progressing to 10 | |
| 276 # seconds. It's called twice per loop. | |
| 277 self.requests = [ | |
| 278 ( | |
| 279 'http://host:9001/get_result?r=key1', | |
| 280 {'retry_404': False, 'retry_50x': False}, | |
| 281 None, | |
| 282 ), | |
| 283 ( | |
| 284 'http://host:9001/get_result?r=key1', | |
| 285 {'retry_404': False, 'retry_50x': False}, | |
| 286 None, | |
| 287 ), | |
| 288 ( | |
| 289 'http://host:9001/get_result?r=key1', | |
| 290 {'retry_404': False, 'retry_50x': False}, | |
| 291 None, | |
| 292 ), | |
| 293 ( | |
| 294 'http://host:9001/get_result?r=key1', | |
| 295 {'retry_404': False, 'retry_50x': False}, | |
| 296 None, | |
| 297 ), | |
| 298 ( | |
| 299 'http://host:9001/get_result?r=key1', | |
| 300 {'retry_404': False, 'retry_50x': False}, | |
| 301 None, | |
| 302 ), | |
| 303 ] | |
| 304 actual = get_swarm_results(['key1']) | |
| 305 self.assertEqual([], actual) | |
| 306 self.assertTrue(all(not v for v in now.itervalues()), now) | |
| 307 | |
| 308 def test_shard_repeated(self): | |
| 309 self.requests = [ | |
| 310 ( | |
| 311 'http://host:9001/get_result?r=key1', | |
| 312 {'retry_404': False, 'retry_50x': False}, | |
| 313 generate_url_response(0, SWARM_OUTPUT_SUCCESS, '0, 0'), | |
| 314 ), | |
| 315 ( | |
| 316 'http://host:9001/get_result?r=key1-repeat', | |
| 317 {'retry_404': False, 'retry_50x': False}, | |
| 318 generate_url_response(0, SWARM_OUTPUT_SUCCESS, '0, 0'), | |
| 319 ), | |
| 320 ] | |
| 321 expected = [gen_yielded_data(0, SWARM_OUTPUT_SUCCESS, '0, 0')] | |
| 322 actual = get_swarm_results(['key1', 'key1-repeat']) | |
| 323 self.assertEqual(expected, actual) | |
| 324 | |
| 325 def test_one_shard_repeated(self): | |
| 326 """Have shard 1 repeated twice, then shard 2 and 3.""" | |
| 327 self.requests = [ | |
| 328 ( | |
| 329 'http://host:9001/get_result?r=key1', | |
| 330 {'retry_404': False, 'retry_50x': False}, | |
| 331 generate_url_response(0, TEST_SHARD_OUTPUT_1, '0, 0'), | |
| 332 ), | |
| 333 ( | |
| 334 'http://host:9001/get_result?r=key1-repeat', | |
| 335 {'retry_404': False, 'retry_50x': False}, | |
| 336 generate_url_response(0, TEST_SHARD_OUTPUT_1, '0, 0'), | |
| 337 ), | |
| 338 ( | |
| 339 'http://host:9001/get_result?r=key2', | |
| 340 {'retry_404': False, 'retry_50x': False}, | |
| 341 generate_url_response(1, TEST_SHARD_OUTPUT_2, '0, 0'), | |
| 342 ), | |
| 343 ( | |
| 344 'http://host:9001/get_result?r=key3', | |
| 345 {'retry_404': False, 'retry_50x': False}, | |
| 346 generate_url_response(2, TEST_SHARD_OUTPUT_3, '0, 0'), | |
| 347 ), | |
| 348 ] | |
| 349 expected = [ | |
| 350 gen_yielded_data(0, TEST_SHARD_OUTPUT_1, '0, 0'), | |
| 351 gen_yielded_data(1, TEST_SHARD_OUTPUT_2, '0, 0'), | |
| 352 gen_yielded_data(2, TEST_SHARD_OUTPUT_3, '0, 0'), | |
| 353 ] | |
| 354 actual = get_swarm_results(['key1', 'key1-repeat', 'key2', 'key3']) | |
| 355 self.assertEqual(expected, sorted(actual)) | |
| 356 | |
| 357 def test_collect_nothing(self): | |
| 358 self.mock(swarming, 'get_test_keys', lambda *_: [1, 2]) | |
| 359 self.mock(swarming, 'yield_results', lambda *_: []) | |
| 360 self.assertEquals( | |
| 361 1, swarming.collect('url', 'test_name', 'timeout', 'decorate')) | |
| 362 | |
| 363 def test_collect_success(self): | |
| 364 self.mock(swarming, 'get_test_keys', lambda *_: [1, 2]) | |
| 365 self.mock(sys, 'stdout', StringIO.StringIO()) | |
| 366 data = { | |
| 367 'config_instance_index': 0, | |
| 368 'exit_codes': '0', | |
| 369 'machine_id': 0, | |
| 370 'output': 'Foo', | |
| 371 } | |
| 372 self.mock(swarming, 'yield_results', lambda *_: [(0, data)]) | |
| 373 self.assertEquals( | |
| 374 0, swarming.collect('url', 'test_name', 'timeout', 'decorate')) | |
| 375 | |
| 376 def test_collect_fail(self): | |
| 377 self.mock(swarming, 'get_test_keys', lambda *_: [1, 2]) | |
| 378 self.mock(sys, 'stdout', StringIO.StringIO()) | |
| 379 data = { | |
| 380 'config_instance_index': 0, | |
| 381 'exit_codes': '0,8', | |
| 382 'machine_id': 0, | |
| 383 'output': 'Foo', | |
| 384 } | |
| 385 self.mock(swarming, 'yield_results', lambda *_: [(0, data)]) | |
| 386 self.assertEquals( | |
| 387 8, swarming.collect('url', 'test_name', 'timeout', 'decorate')) | |
| 388 | |
| 389 | |
| 390 def chromium_tasks(retrieval_url): | |
| 391 return [ | |
| 392 { | |
| 393 u'action': [ | |
| 394 u'python', u'run_isolated.zip', | |
| 395 u'--hash', FILE_HASH, | |
| 396 u'--isolate-server', retrieval_url, | |
| 397 ], | |
| 398 u'decorate_output': False, | |
| 399 u'test_name': u'Run Test', | |
| 400 u'time_out': 600, | |
| 401 }, | |
| 402 { | |
| 403 u'action' : [ | |
| 404 u'python', u'swarm_cleanup.py', | |
| 405 ], | |
| 406 u'decorate_output': False, | |
| 407 u'test_name': u'Clean Up', | |
| 408 u'time_out': 600, | |
| 409 } | |
| 410 ] | |
| 411 | |
| 412 | |
| 413 def generate_expected_json( | |
| 414 shards, | |
| 415 slave_os, | |
| 416 working_dir, | |
| 417 isolate_server, | |
| 418 profile): | |
| 419 os_value = unicode(swarming.PLATFORM_MAPPING_SWARMING[slave_os]) | |
| 420 expected = { | |
| 421 u'cleanup': u'root', | |
| 422 u'configurations': [ | |
| 423 { | |
| 424 u'config_name': os_value, | |
| 425 u'dimensions': { | |
| 426 u'os': os_value, | |
| 427 }, | |
| 428 u'min_instances': shards, | |
| 429 u'priority': 101, | |
| 430 }, | |
| 431 ], | |
| 432 u'data': [], | |
| 433 u'encoding': 'UTF-8', | |
| 434 u'env_vars': {}, | |
| 435 u'restart_on_failure': True, | |
| 436 u'test_case_name': TEST_NAME, | |
| 437 u'tests': chromium_tasks(isolate_server), | |
| 438 u'working_dir': unicode(working_dir), | |
| 439 } | |
| 440 if shards > 1: | |
| 441 expected[u'env_vars'][u'GTEST_SHARD_INDEX'] = u'%(instance_index)s' | |
| 442 expected[u'env_vars'][u'GTEST_TOTAL_SHARDS'] = u'%(num_instances)s' | |
| 443 if profile: | |
| 444 expected[u'tests'][0][u'action'].append(u'--verbose') | |
| 445 return expected | |
| 446 | |
| 447 | |
| 448 class MockedStorage(object): | |
| 449 def __init__(self, warm_cache): | |
| 450 self._warm_cache = warm_cache | |
| 451 | |
| 452 def upload_items(self, items): | |
| 453 return [] if self._warm_cache else items | |
| 454 | |
| 455 def get_fetch_url(self, _digest): # pylint: disable=R0201 | |
| 456 return 'http://localhost:8081/fetch_url' | |
| 457 | |
| 458 | |
| 459 class ManifestTest(auto_stub.TestCase): | |
| 460 def setUp(self): | |
| 461 self.mock(swarming.time, 'sleep', lambda x: None) | |
| 462 self.mock(sys, 'stdout', StringIO.StringIO()) | |
| 463 self.mock(sys, 'stderr', StringIO.StringIO()) | |
| 464 | |
| 465 def tearDown(self): | |
| 466 if not self.has_failed(): | |
| 467 self._check_output('', '') | |
| 468 super(ManifestTest, self).tearDown() | |
| 469 | |
| 470 def _check_output(self, out, err): | |
| 471 self.assertEqual(out, sys.stdout.getvalue()) | |
| 472 self.assertEqual(err, sys.stderr.getvalue()) | |
| 473 | |
| 474 # Flush their content by mocking them again. | |
| 475 self.mock(sys, 'stdout', StringIO.StringIO()) | |
| 476 self.mock(sys, 'stderr', StringIO.StringIO()) | |
| 477 | |
| 478 def test_basic_manifest(self): | |
| 479 manifest = swarming.Manifest( | |
| 480 isolated_hash=FILE_HASH, | |
| 481 test_name=TEST_NAME, | |
| 482 shards=2, | |
| 483 test_filter='*', | |
| 484 slave_os='Windows', | |
| 485 working_dir='swarm_tests', | |
| 486 isolate_server='http://localhost:8081', | |
| 487 verbose=False, | |
| 488 profile=False, | |
| 489 priority=101, | |
| 490 algo=ALGO) | |
| 491 | |
| 492 swarming.chromium_setup(manifest) | |
| 493 manifest_json = json.loads(manifest.to_json()) | |
| 494 | |
| 495 expected = generate_expected_json( | |
| 496 shards=2, | |
| 497 slave_os='win32', | |
| 498 working_dir='swarm_tests', | |
| 499 isolate_server=u'http://localhost:8081', | |
| 500 profile=False) | |
| 501 self.assertEqual(expected, manifest_json) | |
| 502 | |
| 503 def test_basic_linux(self): | |
| 504 """A basic linux manifest test to ensure that windows specific values | |
| 505 aren't used. | |
| 506 """ | |
| 507 manifest = swarming.Manifest( | |
| 508 isolated_hash=FILE_HASH, | |
| 509 test_name=TEST_NAME, | |
| 510 shards=1, | |
| 511 test_filter='*', | |
| 512 slave_os='Linux', | |
| 513 working_dir='swarm_tests', | |
| 514 isolate_server='http://localhost:8081', | |
| 515 verbose=False, | |
| 516 profile=False, | |
| 517 priority=101, | |
| 518 algo=ALGO) | |
| 519 | |
| 520 swarming.chromium_setup(manifest) | |
| 521 manifest_json = json.loads(manifest.to_json()) | |
| 522 | |
| 523 expected = generate_expected_json( | |
| 524 shards=1, | |
| 525 slave_os='linux2', | |
| 526 working_dir='swarm_tests', | |
| 527 isolate_server=u'http://localhost:8081', | |
| 528 profile=False) | |
| 529 self.assertEqual(expected, manifest_json) | |
| 530 | |
| 531 def test_basic_linux_profile(self): | |
| 532 manifest = swarming.Manifest( | |
| 533 isolated_hash=FILE_HASH, | |
| 534 test_name=TEST_NAME, | |
| 535 shards=1, | |
| 536 test_filter='*', | |
| 537 slave_os='Linux', | |
| 538 working_dir='swarm_tests', | |
| 539 isolate_server='http://localhost:8081', | |
| 540 verbose=False, | |
| 541 profile=True, | |
| 542 priority=101, | |
| 543 algo=ALGO) | |
| 544 | |
| 545 swarming.chromium_setup(manifest) | |
| 546 manifest_json = json.loads(manifest.to_json()) | |
| 547 | |
| 548 expected = generate_expected_json( | |
| 549 shards=1, | |
| 550 slave_os='linux2', | |
| 551 working_dir='swarm_tests', | |
| 552 isolate_server=u'http://localhost:8081', | |
| 553 profile=True) | |
| 554 self.assertEqual(expected, manifest_json) | |
| 555 | |
| 556 def test_process_manifest_success(self): | |
| 557 self.mock(swarming.net, 'url_read', lambda url, data=None: '{}') | |
| 558 self.mock(swarming.isolateserver, 'get_storage', | |
| 559 lambda *_: MockedStorage(warm_cache=False)) | |
| 560 | |
| 561 result = swarming.process_manifest( | |
| 562 file_hash_or_isolated=FILE_HASH, | |
| 563 test_name=TEST_NAME, | |
| 564 shards=1, | |
| 565 test_filter='*', | |
| 566 slave_os='linux2', | |
| 567 working_dir='swarm_tests', | |
| 568 isolate_server='http://localhost:8081', | |
| 569 swarming='http://localhost:8082', | |
| 570 verbose=False, | |
| 571 profile=False, | |
| 572 priority=101, | |
| 573 algo=ALGO) | |
| 574 self.assertEqual(0, result) | |
| 575 | |
| 576 # Just assert it printed enough, since it contains variable output. | |
| 577 out = sys.stdout.getvalue() | |
| 578 self.assertTrue( | |
| 579 len(out) > STDOUT_FOR_TRIGGER_LEN, | |
| 580 (out, sys.stderr.getvalue())) | |
| 581 self.assertTrue('Upload complete' in out) | |
| 582 self.mock(sys, 'stdout', StringIO.StringIO()) | |
| 583 | |
| 584 def test_process_manifest_success_zip_already_uploaded(self): | |
| 585 self.mock(swarming.net, 'url_read', lambda url, data=None: '{}') | |
| 586 self.mock(swarming.isolateserver, 'get_storage', | |
| 587 lambda *_: MockedStorage(warm_cache=True)) | |
| 588 | |
| 589 result = swarming.process_manifest( | |
| 590 file_hash_or_isolated=FILE_HASH, | |
| 591 test_name=TEST_NAME, | |
| 592 shards=1, | |
| 593 test_filter='*', | |
| 594 slave_os='linux2', | |
| 595 working_dir='swarm_tests', | |
| 596 isolate_server='http://localhost:8081', | |
| 597 swarming='http://localhost:8082', | |
| 598 verbose=False, | |
| 599 profile=False, | |
| 600 priority=101, | |
| 601 algo=ALGO) | |
| 602 self.assertEqual(0, result) | |
| 603 | |
| 604 # Just assert it printed enough, since it contains variable output. | |
| 605 out = sys.stdout.getvalue() | |
| 606 self.assertTrue(len(out) > STDOUT_FOR_TRIGGER_LEN) | |
| 607 self.assertTrue('Zip file already on server' in out) | |
| 608 self.mock(sys, 'stdout', StringIO.StringIO()) | |
| 609 | |
| 610 def test_no_request(self): | |
| 611 try: | |
| 612 swarming.main([ | |
| 613 'trigger', '--swarming', 'https://example.com', | |
| 614 '--isolate-server', 'https://example.com']) | |
| 615 self.fail() | |
| 616 except SystemExit as e: | |
| 617 self.assertEqual(2, e.code) | |
| 618 self._check_output( | |
| 619 '', | |
| 620 'Usage: swarming.py trigger [options]\n\n' | |
| 621 'swarming.py: error: At least one --task is required.\n') | |
| 622 | |
| 623 | |
| 624 if __name__ == '__main__': | |
| 625 logging.basicConfig( | |
| 626 level=logging.DEBUG if '-v' in sys.argv else logging.ERROR) | |
| 627 if '-v' in sys.argv: | |
| 628 unittest.TestCase.maxDiff = None | |
| 629 unittest.main() | |
| OLD | NEW |