| 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 import cStringIO | |
| 7 import hashlib | |
| 8 import json | |
| 9 import logging | |
| 10 import os | |
| 11 import sys | |
| 12 import tempfile | |
| 13 import unittest | |
| 14 | |
| 15 import auto_stub | |
| 16 | |
| 17 ROOT_DIR = unicode(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | |
| 18 sys.path.insert(0, ROOT_DIR) | |
| 19 | |
| 20 import isolate | |
| 21 from utils import file_path | |
| 22 # Create shortcuts. | |
| 23 from isolate import KEY_TOUCHED, KEY_TRACKED, KEY_UNTRACKED | |
| 24 | |
| 25 | |
| 26 ALGO = hashlib.sha1 | |
| 27 | |
| 28 | |
| 29 def _size(*args): | |
| 30 return os.stat(os.path.join(ROOT_DIR, *args)).st_size | |
| 31 | |
| 32 | |
| 33 def hash_file(*args): | |
| 34 return isolate.isolateserver.hash_file(os.path.join(ROOT_DIR, *args), ALGO) | |
| 35 | |
| 36 | |
| 37 class IsolateBase(auto_stub.TestCase): | |
| 38 def setUp(self): | |
| 39 super(IsolateBase, self).setUp() | |
| 40 self.old_cwd = os.getcwd() | |
| 41 self.cwd = tempfile.mkdtemp(prefix='isolate_') | |
| 42 # Everything should work even from another directory. | |
| 43 os.chdir(self.cwd) | |
| 44 | |
| 45 def tearDown(self): | |
| 46 try: | |
| 47 os.chdir(self.old_cwd) | |
| 48 isolate.run_isolated.rmtree(self.cwd) | |
| 49 finally: | |
| 50 super(IsolateBase, self).tearDown() | |
| 51 | |
| 52 | |
| 53 class IsolateTest(IsolateBase): | |
| 54 def test_savedstate_load_minimal(self): | |
| 55 # The file referenced by 'isolate_file' must exist even if its content is | |
| 56 # not read. | |
| 57 open(os.path.join(self.cwd, 'fake.isolate'), 'wb').close() | |
| 58 values = { | |
| 59 'isolate_file': 'fake.isolate', | |
| 60 } | |
| 61 expected = { | |
| 62 'algo': 'sha-1', | |
| 63 'child_isolated_files': [], | |
| 64 'command': [], | |
| 65 'files': {}, | |
| 66 'isolate_file': 'fake.isolate', | |
| 67 'variables': { | |
| 68 'OS': isolate.get_flavor(), | |
| 69 }, | |
| 70 'version': '1.0', | |
| 71 } | |
| 72 saved_state = isolate.SavedState.load(values, self.cwd) | |
| 73 self.assertEqual(expected, saved_state.flatten()) | |
| 74 | |
| 75 def test_savedstate_load(self): | |
| 76 # The file referenced by 'isolate_file' must exist even if its content is | |
| 77 # not read. | |
| 78 open(os.path.join(self.cwd, 'fake.isolate'), 'wb').close() | |
| 79 values = { | |
| 80 'isolate_file': 'fake.isolate', | |
| 81 'variables': { | |
| 82 'foo': 42, | |
| 83 'OS': isolate.get_flavor(), | |
| 84 }, | |
| 85 } | |
| 86 expected = { | |
| 87 'algo': 'sha-1', | |
| 88 'child_isolated_files': [], | |
| 89 'command': [], | |
| 90 'files': {}, | |
| 91 'isolate_file': 'fake.isolate', | |
| 92 'variables': { | |
| 93 'foo': 42, | |
| 94 'OS': isolate.get_flavor(), | |
| 95 }, | |
| 96 'version': '1.0', | |
| 97 } | |
| 98 saved_state = isolate.SavedState.load(values, self.cwd) | |
| 99 self.assertEqual(expected, saved_state.flatten()) | |
| 100 | |
| 101 def test_unknown_key(self): | |
| 102 try: | |
| 103 isolate.verify_variables({'foo': [],}) | |
| 104 self.fail() | |
| 105 except AssertionError: | |
| 106 pass | |
| 107 | |
| 108 def test_unknown_var(self): | |
| 109 try: | |
| 110 isolate.verify_condition({'variables': {'foo': [],}}, {}) | |
| 111 self.fail() | |
| 112 except AssertionError: | |
| 113 pass | |
| 114 | |
| 115 def test_union(self): | |
| 116 value1 = { | |
| 117 'a': set(['A']), | |
| 118 'b': ['B', 'C'], | |
| 119 'c': 'C', | |
| 120 } | |
| 121 value2 = { | |
| 122 'a': set(['B', 'C']), | |
| 123 'b': [], | |
| 124 'd': set(), | |
| 125 } | |
| 126 expected = { | |
| 127 'a': set(['A', 'B', 'C']), | |
| 128 'b': ['B', 'C'], | |
| 129 'c': 'C', | |
| 130 'd': set(), | |
| 131 } | |
| 132 self.assertEqual(expected, isolate.union(value1, value2)) | |
| 133 | |
| 134 def test_eval_content(self): | |
| 135 try: | |
| 136 # Intrinsics are not available. | |
| 137 isolate.eval_content('map(str, [1, 2])') | |
| 138 self.fail() | |
| 139 except NameError: | |
| 140 pass | |
| 141 | |
| 142 def test_load_isolate_as_config_empty(self): | |
| 143 self.assertEqual({}, isolate.load_isolate_as_config( | |
| 144 self.cwd, {}, None).flatten()) | |
| 145 | |
| 146 def test_load_isolate_as_config(self): | |
| 147 value = { | |
| 148 'conditions': [ | |
| 149 ['OS=="amiga" or OS=="atari" or OS=="coleco" or OS=="dendy"', { | |
| 150 'variables': { | |
| 151 KEY_TRACKED: ['a'], | |
| 152 KEY_UNTRACKED: ['b'], | |
| 153 KEY_TOUCHED: ['touched'], | |
| 154 }, | |
| 155 }], | |
| 156 ['OS=="atari"', { | |
| 157 'variables': { | |
| 158 KEY_TRACKED: ['c', 'x'], | |
| 159 KEY_UNTRACKED: ['d'], | |
| 160 KEY_TOUCHED: ['touched_a'], | |
| 161 'command': ['echo', 'Hello World'], | |
| 162 'read_only': True, | |
| 163 }, | |
| 164 }], | |
| 165 ['OS=="amiga" or OS=="coleco" or OS=="dendy"', { | |
| 166 'variables': { | |
| 167 KEY_TRACKED: ['e', 'x'], | |
| 168 KEY_UNTRACKED: ['f'], | |
| 169 KEY_TOUCHED: ['touched_e'], | |
| 170 'command': ['echo', 'You should get an Atari'], | |
| 171 }, | |
| 172 }], | |
| 173 ['OS=="amiga"', { | |
| 174 'variables': { | |
| 175 KEY_TRACKED: ['g'], | |
| 176 'read_only': False, | |
| 177 }, | |
| 178 }], | |
| 179 ['OS=="amiga" or OS=="atari" or OS=="dendy"', { | |
| 180 'variables': { | |
| 181 KEY_UNTRACKED: ['h'], | |
| 182 }, | |
| 183 }], | |
| 184 ], | |
| 185 } | |
| 186 expected = { | |
| 187 ('amiga',): { | |
| 188 'command': ['echo', 'You should get an Atari'], | |
| 189 KEY_TOUCHED: ['touched', 'touched_e'], | |
| 190 KEY_TRACKED: ['a', 'e', 'g', 'x'], | |
| 191 KEY_UNTRACKED: ['b', 'f', 'h'], | |
| 192 'read_only': False, | |
| 193 }, | |
| 194 ('atari',): { | |
| 195 'command': ['echo', 'Hello World'], | |
| 196 KEY_TOUCHED: ['touched', 'touched_a'], | |
| 197 KEY_TRACKED: ['a', 'c', 'x'], | |
| 198 KEY_UNTRACKED: ['b', 'd', 'h'], | |
| 199 'read_only': True, | |
| 200 }, | |
| 201 ('coleco',): { | |
| 202 'command': ['echo', 'You should get an Atari'], | |
| 203 KEY_TOUCHED: ['touched', 'touched_e'], | |
| 204 KEY_TRACKED: ['a', 'e', 'x'], | |
| 205 KEY_UNTRACKED: ['b', 'f'], | |
| 206 }, | |
| 207 ('dendy',): { | |
| 208 'command': ['echo', 'You should get an Atari'], | |
| 209 KEY_TOUCHED: ['touched', 'touched_e'], | |
| 210 KEY_TRACKED: ['a', 'e', 'x'], | |
| 211 KEY_UNTRACKED: ['b', 'f', 'h'], | |
| 212 }, | |
| 213 } | |
| 214 self.assertEqual( | |
| 215 expected, isolate.load_isolate_as_config( | |
| 216 self.cwd, value, None).flatten()) | |
| 217 | |
| 218 def test_load_isolate_as_config_duplicate_command(self): | |
| 219 value = { | |
| 220 'variables': { | |
| 221 'command': ['rm', '-rf', '/'], | |
| 222 }, | |
| 223 'conditions': [ | |
| 224 ['OS=="atari"', { | |
| 225 'variables': { | |
| 226 'command': ['echo', 'Hello World'], | |
| 227 }, | |
| 228 }], | |
| 229 ], | |
| 230 } | |
| 231 try: | |
| 232 isolate.load_isolate_as_config(self.cwd, value, None) | |
| 233 self.fail() | |
| 234 except AssertionError: | |
| 235 pass | |
| 236 | |
| 237 def test_invert_map(self): | |
| 238 value = { | |
| 239 ('amiga',): { | |
| 240 'command': ['echo', 'You should get an Atari'], | |
| 241 KEY_TOUCHED: ['touched', 'touched_e'], | |
| 242 KEY_TRACKED: ['a', 'e', 'g', 'x'], | |
| 243 KEY_UNTRACKED: ['b', 'f', 'h'], | |
| 244 'read_only': False, | |
| 245 }, | |
| 246 ('atari',): { | |
| 247 'command': ['echo', 'Hello World'], | |
| 248 KEY_TOUCHED: ['touched', 'touched_a'], | |
| 249 KEY_TRACKED: ['a', 'c', 'x'], | |
| 250 KEY_UNTRACKED: ['b', 'd', 'h'], | |
| 251 'read_only': True, | |
| 252 }, | |
| 253 ('coleco',): { | |
| 254 'command': ['echo', 'You should get an Atari'], | |
| 255 KEY_TOUCHED: ['touched', 'touched_e'], | |
| 256 KEY_TRACKED: ['a', 'e', 'x'], | |
| 257 KEY_UNTRACKED: ['b', 'f'], | |
| 258 }, | |
| 259 ('dendy',): { | |
| 260 'command': ['echo', 'You should get an Atari'], | |
| 261 KEY_TOUCHED: ['touched', 'touched_e'], | |
| 262 KEY_TRACKED: ['a', 'e', 'x'], | |
| 263 KEY_UNTRACKED: ['b', 'f', 'h'], | |
| 264 }, | |
| 265 } | |
| 266 amiga, atari, coleco, dendy = ( | |
| 267 set([(os,)]) for os in ('amiga', 'atari', 'coleco', 'dendy')) | |
| 268 expected_values = { | |
| 269 'command': { | |
| 270 ('echo', 'Hello World'): atari, | |
| 271 ('echo', 'You should get an Atari'): amiga | coleco | dendy, | |
| 272 }, | |
| 273 KEY_TRACKED: { | |
| 274 'a': amiga | atari | coleco | dendy, | |
| 275 'c': atari, | |
| 276 'e': amiga | coleco | dendy, | |
| 277 'g': amiga, | |
| 278 'x': amiga | atari | coleco | dendy, | |
| 279 }, | |
| 280 KEY_UNTRACKED: { | |
| 281 'b': amiga | atari | coleco | dendy, | |
| 282 'd': atari, | |
| 283 'f': amiga | coleco | dendy, | |
| 284 'h': amiga | atari | dendy, | |
| 285 }, | |
| 286 KEY_TOUCHED: { | |
| 287 'touched': amiga | atari | coleco | dendy, | |
| 288 'touched_a': atari, | |
| 289 'touched_e': amiga | coleco | dendy, | |
| 290 }, | |
| 291 'read_only': { | |
| 292 False: amiga, | |
| 293 True: atari, | |
| 294 }, | |
| 295 } | |
| 296 actual_values = isolate.invert_map(value) | |
| 297 self.assertEqual(expected_values, actual_values) | |
| 298 | |
| 299 def test_reduce_inputs(self): | |
| 300 amiga, atari, coleco, dendy = ( | |
| 301 set([(os,)]) for os in ('amiga', 'atari', 'coleco', 'dendy')) | |
| 302 values = { | |
| 303 'command': { | |
| 304 ('echo', 'Hello World'): atari, | |
| 305 ('echo', 'You should get an Atari'): amiga | coleco | dendy, | |
| 306 }, | |
| 307 KEY_TRACKED: { | |
| 308 'a': amiga | atari | coleco | dendy, | |
| 309 'c': atari, | |
| 310 'e': amiga | coleco | dendy, | |
| 311 'g': amiga, | |
| 312 'x': amiga | atari | coleco | dendy, | |
| 313 }, | |
| 314 KEY_UNTRACKED: { | |
| 315 'b': amiga | atari | coleco | dendy, | |
| 316 'd': atari, | |
| 317 'f': amiga | coleco | dendy, | |
| 318 'h': amiga | atari | dendy, | |
| 319 }, | |
| 320 KEY_TOUCHED: { | |
| 321 'touched': amiga | atari | coleco | dendy, | |
| 322 'touched_a': atari, | |
| 323 'touched_e': amiga | coleco | dendy, | |
| 324 }, | |
| 325 'read_only': { | |
| 326 False: amiga, | |
| 327 True: atari, | |
| 328 }, | |
| 329 } | |
| 330 expected_values = { | |
| 331 'command': { | |
| 332 ('echo', 'Hello World'): atari, | |
| 333 ('echo', 'You should get an Atari'): amiga | coleco | dendy, | |
| 334 }, | |
| 335 KEY_TRACKED: { | |
| 336 'a': amiga | atari | coleco | dendy, | |
| 337 'c': atari, | |
| 338 'e': amiga | coleco | dendy, | |
| 339 'g': amiga, | |
| 340 'x': amiga | atari | coleco | dendy, | |
| 341 }, | |
| 342 KEY_UNTRACKED: { | |
| 343 'b': amiga | atari | coleco | dendy, | |
| 344 'd': atari, | |
| 345 'f': amiga | coleco | dendy, | |
| 346 'h': amiga | atari | dendy, | |
| 347 }, | |
| 348 KEY_TOUCHED: { | |
| 349 'touched': amiga | atari | coleco | dendy, | |
| 350 'touched_a': atari, | |
| 351 'touched_e': amiga | coleco | dendy, | |
| 352 }, | |
| 353 'read_only': { | |
| 354 False: amiga, | |
| 355 True: atari, | |
| 356 }, | |
| 357 } | |
| 358 actual_values = isolate.reduce_inputs(values) | |
| 359 self.assertEqual(expected_values, actual_values) | |
| 360 | |
| 361 def test_reduce_inputs_merge_subfolders_and_files(self): | |
| 362 linux, mac, win = (set([(os,)]) for os in ('linux', 'mac', 'win')) | |
| 363 values = { | |
| 364 KEY_TRACKED: { | |
| 365 'folder/tracked_file': win, | |
| 366 'folder_helper/tracked_file': win, | |
| 367 }, | |
| 368 KEY_UNTRACKED: { | |
| 369 'folder/': linux | mac | win, | |
| 370 'folder/subfolder/': win, | |
| 371 'folder/untracked_file': linux | mac | win, | |
| 372 'folder_helper/': linux, | |
| 373 }, | |
| 374 KEY_TOUCHED: { | |
| 375 'folder/touched_file': win, | |
| 376 'folder/helper_folder/deep_file': win, | |
| 377 'folder_helper/touched_file1': mac | win, | |
| 378 'folder_helper/touched_file2': linux, | |
| 379 }, | |
| 380 } | |
| 381 expected_values = { | |
| 382 'command': {}, | |
| 383 KEY_TRACKED: { | |
| 384 'folder_helper/tracked_file': win, | |
| 385 }, | |
| 386 KEY_UNTRACKED: { | |
| 387 'folder/': linux | mac | win, | |
| 388 'folder_helper/': linux, | |
| 389 }, | |
| 390 KEY_TOUCHED: { | |
| 391 'folder_helper/touched_file1': mac | win, | |
| 392 }, | |
| 393 'read_only': {}, | |
| 394 } | |
| 395 actual_values = isolate.reduce_inputs(values) | |
| 396 self.assertEqual(expected_values, actual_values) | |
| 397 | |
| 398 def test_reduce_inputs_take_strongest_dependency(self): | |
| 399 amiga, atari, coleco, dendy = ( | |
| 400 set([(os,)]) for os in ('amiga', 'atari', 'coleco', 'dendy')) | |
| 401 values = { | |
| 402 'command': { | |
| 403 ('echo', 'Hello World'): atari, | |
| 404 ('echo', 'You should get an Atari'): amiga | coleco | dendy, | |
| 405 }, | |
| 406 KEY_TRACKED: { | |
| 407 'a': amiga | atari | coleco | dendy, | |
| 408 'b': amiga | atari | coleco, | |
| 409 }, | |
| 410 KEY_UNTRACKED: { | |
| 411 'c': amiga | atari | coleco | dendy, | |
| 412 'd': amiga | coleco | dendy, | |
| 413 }, | |
| 414 KEY_TOUCHED: { | |
| 415 'a': amiga | atari | coleco | dendy, | |
| 416 'b': atari | coleco | dendy, | |
| 417 'c': amiga | atari | coleco | dendy, | |
| 418 'd': atari | coleco | dendy, | |
| 419 }, | |
| 420 } | |
| 421 expected_values = { | |
| 422 'command': { | |
| 423 ('echo', 'Hello World'): atari, | |
| 424 ('echo', 'You should get an Atari'): amiga | coleco | dendy, | |
| 425 }, | |
| 426 KEY_TRACKED: { | |
| 427 'a': amiga | atari | coleco | dendy, | |
| 428 'b': amiga | atari | coleco, | |
| 429 }, | |
| 430 KEY_UNTRACKED: { | |
| 431 'c': amiga | atari | coleco | dendy, | |
| 432 'd': amiga | coleco | dendy, | |
| 433 }, | |
| 434 KEY_TOUCHED: { | |
| 435 'b': dendy, | |
| 436 'd': atari, | |
| 437 }, | |
| 438 'read_only': {}, | |
| 439 } | |
| 440 actual_values = isolate.reduce_inputs(values) | |
| 441 self.assertEqual(expected_values, actual_values) | |
| 442 | |
| 443 def test_convert_map_to_isolate_dict(self): | |
| 444 amiga = ('amiga',) | |
| 445 atari = ('atari',) | |
| 446 coleco = ('coleco',) | |
| 447 dendy = ('dendy',) | |
| 448 values = { | |
| 449 'command': { | |
| 450 ('echo', 'Hello World'): (atari,), | |
| 451 ('echo', 'You should get an Atari'): (amiga, coleco, dendy), | |
| 452 }, | |
| 453 KEY_TRACKED: { | |
| 454 'a': (amiga, atari, coleco, dendy), | |
| 455 'c': (atari,), | |
| 456 'e': (amiga, coleco, dendy), | |
| 457 'g': (amiga,), | |
| 458 'x': (amiga, atari, coleco, dendy), | |
| 459 }, | |
| 460 KEY_UNTRACKED: { | |
| 461 'b': (amiga, atari, coleco, dendy), | |
| 462 'd': (atari,), | |
| 463 'f': (amiga, coleco, dendy), | |
| 464 'h': (amiga, atari, dendy), | |
| 465 }, | |
| 466 KEY_TOUCHED: { | |
| 467 'touched': (amiga, atari, coleco, dendy), | |
| 468 'touched_a': (atari,), | |
| 469 'touched_e': (amiga, coleco, dendy), | |
| 470 }, | |
| 471 'read_only': { | |
| 472 False: (amiga,), | |
| 473 True: (atari,), | |
| 474 }, | |
| 475 } | |
| 476 expected_conditions = [ | |
| 477 ['OS=="amiga"', { | |
| 478 'variables': { | |
| 479 KEY_TRACKED: ['g'], | |
| 480 'read_only': False, | |
| 481 }, | |
| 482 }], | |
| 483 ['OS=="amiga" or OS=="atari" or OS=="coleco" or OS=="dendy"', { | |
| 484 'variables': { | |
| 485 KEY_TRACKED: ['a', 'x'], | |
| 486 KEY_UNTRACKED: ['b'], | |
| 487 KEY_TOUCHED: ['touched'], | |
| 488 }, | |
| 489 }], | |
| 490 ['OS=="amiga" or OS=="atari" or OS=="dendy"', { | |
| 491 'variables': { | |
| 492 KEY_UNTRACKED: ['h'], | |
| 493 }, | |
| 494 }], | |
| 495 ['OS=="amiga" or OS=="coleco" or OS=="dendy"', { | |
| 496 'variables': { | |
| 497 'command': ['echo', 'You should get an Atari'], | |
| 498 KEY_TRACKED: ['e'], | |
| 499 KEY_UNTRACKED: ['f'], | |
| 500 KEY_TOUCHED: ['touched_e'], | |
| 501 }, | |
| 502 }], | |
| 503 ['OS=="atari"', { | |
| 504 'variables': { | |
| 505 'command': ['echo', 'Hello World'], | |
| 506 KEY_TRACKED: ['c'], | |
| 507 KEY_UNTRACKED: ['d'], | |
| 508 KEY_TOUCHED: ['touched_a'], | |
| 509 'read_only': True, | |
| 510 }, | |
| 511 }], | |
| 512 ] | |
| 513 actual = isolate.convert_map_to_isolate_dict(values, ('OS',)) | |
| 514 self.assertEqual(expected_conditions, sorted(actual.pop('conditions'))) | |
| 515 self.assertFalse(actual) | |
| 516 | |
| 517 def test_merge_two_empty(self): | |
| 518 # Flat stay flat. Pylint is confused about union() return type. | |
| 519 # pylint: disable=E1103 | |
| 520 actual = isolate.union( | |
| 521 isolate.union( | |
| 522 isolate.Configs(None), | |
| 523 isolate.load_isolate_as_config(self.cwd, {}, None)), | |
| 524 isolate.load_isolate_as_config(self.cwd, {}, None)).flatten() | |
| 525 self.assertEqual({}, actual) | |
| 526 | |
| 527 def test_merge_empty(self): | |
| 528 actual = isolate.convert_map_to_isolate_dict( | |
| 529 isolate.reduce_inputs(isolate.invert_map({})), ('dummy1', 'dummy2')) | |
| 530 self.assertEqual({'conditions': []}, actual) | |
| 531 | |
| 532 def test_load_two_conditions(self): | |
| 533 linux = { | |
| 534 'conditions': [ | |
| 535 ['OS=="linux"', { | |
| 536 'variables': { | |
| 537 'isolate_dependency_tracked': [ | |
| 538 'file_linux', | |
| 539 'file_common', | |
| 540 ], | |
| 541 }, | |
| 542 }], | |
| 543 ], | |
| 544 } | |
| 545 mac = { | |
| 546 'conditions': [ | |
| 547 ['OS=="mac"', { | |
| 548 'variables': { | |
| 549 'isolate_dependency_tracked': [ | |
| 550 'file_mac', | |
| 551 'file_common', | |
| 552 ], | |
| 553 }, | |
| 554 }], | |
| 555 ], | |
| 556 } | |
| 557 expected = { | |
| 558 ('linux',): { | |
| 559 'isolate_dependency_tracked': ['file_common', 'file_linux'], | |
| 560 }, | |
| 561 ('mac',): { | |
| 562 'isolate_dependency_tracked': ['file_common', 'file_mac'], | |
| 563 }, | |
| 564 } | |
| 565 # Pylint is confused about union() return type. | |
| 566 # pylint: disable=E1103 | |
| 567 configs = isolate.union( | |
| 568 isolate.union( | |
| 569 isolate.Configs(None), | |
| 570 isolate.load_isolate_as_config(self.cwd, linux, None)), | |
| 571 isolate.load_isolate_as_config(self.cwd, mac, None)).flatten() | |
| 572 self.assertEqual(expected, configs) | |
| 573 | |
| 574 def test_load_three_conditions(self): | |
| 575 linux = { | |
| 576 'conditions': [ | |
| 577 ['OS=="linux" and chromeos==1', { | |
| 578 'variables': { | |
| 579 'isolate_dependency_tracked': [ | |
| 580 'file_linux', | |
| 581 'file_common', | |
| 582 ], | |
| 583 }, | |
| 584 }], | |
| 585 ], | |
| 586 } | |
| 587 mac = { | |
| 588 'conditions': [ | |
| 589 ['OS=="mac" and chromeos==0', { | |
| 590 'variables': { | |
| 591 'isolate_dependency_tracked': [ | |
| 592 'file_mac', | |
| 593 'file_common', | |
| 594 ], | |
| 595 }, | |
| 596 }], | |
| 597 ], | |
| 598 } | |
| 599 win = { | |
| 600 'conditions': [ | |
| 601 ['OS=="win" and chromeos==0', { | |
| 602 'variables': { | |
| 603 'isolate_dependency_tracked': [ | |
| 604 'file_win', | |
| 605 'file_common', | |
| 606 ], | |
| 607 }, | |
| 608 }], | |
| 609 ], | |
| 610 } | |
| 611 expected = { | |
| 612 ('linux', 1): { | |
| 613 'isolate_dependency_tracked': ['file_common', 'file_linux'], | |
| 614 }, | |
| 615 ('mac', 0): { | |
| 616 'isolate_dependency_tracked': ['file_common', 'file_mac'], | |
| 617 }, | |
| 618 ('win', 0): { | |
| 619 'isolate_dependency_tracked': ['file_common', 'file_win'], | |
| 620 }, | |
| 621 } | |
| 622 # Pylint is confused about union() return type. | |
| 623 # pylint: disable=E1103 | |
| 624 configs = isolate.union( | |
| 625 isolate.union( | |
| 626 isolate.union( | |
| 627 isolate.Configs(None), | |
| 628 isolate.load_isolate_as_config(self.cwd, linux, None)), | |
| 629 isolate.load_isolate_as_config(self.cwd, mac, None)), | |
| 630 isolate.load_isolate_as_config(self.cwd, win, None)).flatten() | |
| 631 self.assertEqual(expected, configs) | |
| 632 | |
| 633 def test_merge_three_conditions(self): | |
| 634 values = { | |
| 635 ('linux',): { | |
| 636 'isolate_dependency_tracked': ['file_common', 'file_linux'], | |
| 637 }, | |
| 638 ('mac',): { | |
| 639 'isolate_dependency_tracked': ['file_common', 'file_mac'], | |
| 640 }, | |
| 641 ('win',): { | |
| 642 'isolate_dependency_tracked': ['file_common', 'file_win'], | |
| 643 }, | |
| 644 } | |
| 645 expected = { | |
| 646 'conditions': [ | |
| 647 ['OS=="linux"', { | |
| 648 'variables': { | |
| 649 'isolate_dependency_tracked': [ | |
| 650 'file_linux', | |
| 651 ], | |
| 652 }, | |
| 653 }], | |
| 654 ['OS=="linux" or OS=="mac" or OS=="win"', { | |
| 655 'variables': { | |
| 656 'isolate_dependency_tracked': [ | |
| 657 'file_common', | |
| 658 ], | |
| 659 }, | |
| 660 }], | |
| 661 ['OS=="mac"', { | |
| 662 'variables': { | |
| 663 'isolate_dependency_tracked': [ | |
| 664 'file_mac', | |
| 665 ], | |
| 666 }, | |
| 667 }], | |
| 668 ['OS=="win"', { | |
| 669 'variables': { | |
| 670 'isolate_dependency_tracked': [ | |
| 671 'file_win', | |
| 672 ], | |
| 673 }, | |
| 674 }], | |
| 675 ], | |
| 676 } | |
| 677 actual = isolate.convert_map_to_isolate_dict( | |
| 678 isolate.reduce_inputs(isolate.invert_map(values)), ('OS',)) | |
| 679 self.assertEqual(expected, actual) | |
| 680 | |
| 681 def test_configs_comment(self): | |
| 682 # Pylint is confused with isolate.union() return type. | |
| 683 # pylint: disable=E1103 | |
| 684 configs = isolate.union( | |
| 685 isolate.load_isolate_as_config( | |
| 686 self.cwd, {}, '# Yo dawg!\n# Chill out.\n'), | |
| 687 isolate.load_isolate_as_config(self.cwd, {}, None)) | |
| 688 self.assertEqual('# Yo dawg!\n# Chill out.\n', configs.file_comment) | |
| 689 | |
| 690 configs = isolate.union( | |
| 691 isolate.load_isolate_as_config(self.cwd, {}, None), | |
| 692 isolate.load_isolate_as_config( | |
| 693 self.cwd, {}, '# Yo dawg!\n# Chill out.\n')) | |
| 694 self.assertEqual('# Yo dawg!\n# Chill out.\n', configs.file_comment) | |
| 695 | |
| 696 # Only keep the first one. | |
| 697 configs = isolate.union( | |
| 698 isolate.load_isolate_as_config(self.cwd, {}, '# Yo dawg!\n'), | |
| 699 isolate.load_isolate_as_config(self.cwd, {}, '# Chill out.\n')) | |
| 700 self.assertEqual('# Yo dawg!\n', configs.file_comment) | |
| 701 | |
| 702 def test_load_with_includes(self): | |
| 703 included_isolate = { | |
| 704 'variables': { | |
| 705 'isolate_dependency_tracked': [ | |
| 706 'file_common', | |
| 707 ], | |
| 708 }, | |
| 709 'conditions': [ | |
| 710 ['OS=="linux"', { | |
| 711 'variables': { | |
| 712 'isolate_dependency_tracked': [ | |
| 713 'file_linux', | |
| 714 ], | |
| 715 }, | |
| 716 }, { | |
| 717 'variables': { | |
| 718 'isolate_dependency_tracked': [ | |
| 719 'file_non_linux', | |
| 720 ], | |
| 721 }, | |
| 722 }], | |
| 723 ], | |
| 724 } | |
| 725 isolate.trace_inputs.write_json( | |
| 726 os.path.join(self.cwd, 'included.isolate'), included_isolate, True) | |
| 727 values = { | |
| 728 'includes': ['included.isolate'], | |
| 729 'variables': { | |
| 730 'isolate_dependency_tracked': [ | |
| 731 'file_less_common', | |
| 732 ], | |
| 733 }, | |
| 734 'conditions': [ | |
| 735 ['OS=="mac"', { | |
| 736 'variables': { | |
| 737 'isolate_dependency_tracked': [ | |
| 738 'file_mac', | |
| 739 ], | |
| 740 }, | |
| 741 }], | |
| 742 ], | |
| 743 } | |
| 744 actual = isolate.load_isolate_as_config(self.cwd, values, None) | |
| 745 | |
| 746 expected = { | |
| 747 ('linux',): { | |
| 748 'isolate_dependency_tracked': [ | |
| 749 'file_common', | |
| 750 'file_less_common', | |
| 751 'file_linux', | |
| 752 ], | |
| 753 }, | |
| 754 ('mac',): { | |
| 755 'isolate_dependency_tracked': [ | |
| 756 'file_common', | |
| 757 'file_less_common', | |
| 758 'file_mac', | |
| 759 'file_non_linux', | |
| 760 ], | |
| 761 }, | |
| 762 ('win',): { | |
| 763 'isolate_dependency_tracked': [ | |
| 764 'file_common', | |
| 765 'file_less_common', | |
| 766 'file_non_linux', | |
| 767 ], | |
| 768 }, | |
| 769 } | |
| 770 self.assertEqual(expected, actual.flatten()) | |
| 771 | |
| 772 def test_extract_comment(self): | |
| 773 self.assertEqual( | |
| 774 '# Foo\n# Bar\n', isolate.extract_comment('# Foo\n# Bar\n{}')) | |
| 775 self.assertEqual('', isolate.extract_comment('{}')) | |
| 776 | |
| 777 def _test_pretty_print_impl(self, value, expected): | |
| 778 actual = cStringIO.StringIO() | |
| 779 isolate.pretty_print(value, actual) | |
| 780 self.assertEqual(expected, actual.getvalue()) | |
| 781 | |
| 782 def test_pretty_print_empty(self): | |
| 783 self._test_pretty_print_impl({}, '{\n}\n') | |
| 784 | |
| 785 def test_pretty_print_mid_size(self): | |
| 786 value = { | |
| 787 'variables': { | |
| 788 'bar': [ | |
| 789 'file1', | |
| 790 'file2', | |
| 791 ], | |
| 792 }, | |
| 793 'conditions': [ | |
| 794 ['OS=\"foo\"', { | |
| 795 'variables': { | |
| 796 isolate.KEY_UNTRACKED: [ | |
| 797 'dir1', | |
| 798 'dir2', | |
| 799 ], | |
| 800 isolate.KEY_TRACKED: [ | |
| 801 'file4', | |
| 802 'file3', | |
| 803 ], | |
| 804 'command': ['python', '-c', 'print "H\\i\'"'], | |
| 805 'read_only': True, | |
| 806 'relative_cwd': 'isol\'at\\e', | |
| 807 }, | |
| 808 }], | |
| 809 ['OS=\"bar\"', { | |
| 810 'variables': {}, | |
| 811 }, { | |
| 812 'variables': {}, | |
| 813 }], | |
| 814 ], | |
| 815 } | |
| 816 expected = ( | |
| 817 "{\n" | |
| 818 " 'variables': {\n" | |
| 819 " 'bar': [\n" | |
| 820 " 'file1',\n" | |
| 821 " 'file2',\n" | |
| 822 " ],\n" | |
| 823 " },\n" | |
| 824 " 'conditions': [\n" | |
| 825 " ['OS=\"foo\"', {\n" | |
| 826 " 'variables': {\n" | |
| 827 " 'command': [\n" | |
| 828 " 'python',\n" | |
| 829 " '-c',\n" | |
| 830 " 'print \"H\\i\'\"',\n" | |
| 831 " ],\n" | |
| 832 " 'relative_cwd': 'isol\\'at\\\\e',\n" | |
| 833 " 'read_only': True\n" | |
| 834 " 'isolate_dependency_tracked': [\n" | |
| 835 " 'file4',\n" | |
| 836 " 'file3',\n" | |
| 837 " ],\n" | |
| 838 " 'isolate_dependency_untracked': [\n" | |
| 839 " 'dir1',\n" | |
| 840 " 'dir2',\n" | |
| 841 " ],\n" | |
| 842 " },\n" | |
| 843 " }],\n" | |
| 844 " ['OS=\"bar\"', {\n" | |
| 845 " 'variables': {\n" | |
| 846 " },\n" | |
| 847 " }, {\n" | |
| 848 " 'variables': {\n" | |
| 849 " },\n" | |
| 850 " }],\n" | |
| 851 " ],\n" | |
| 852 "}\n") | |
| 853 self._test_pretty_print_impl(value, expected) | |
| 854 | |
| 855 def test_convert_old_to_new_bypass(self): | |
| 856 isolate_not_needing_conversion = { | |
| 857 'conditions': [ | |
| 858 ['OS=="mac"', {'variables': {'foo': 'bar'}}], | |
| 859 ['condition shouldn\'t matter', {'variables': {'x': 'y'}}], | |
| 860 ], | |
| 861 } | |
| 862 self.assertEqual( | |
| 863 isolate_not_needing_conversion, | |
| 864 isolate.convert_old_to_new_format(isolate_not_needing_conversion)) | |
| 865 | |
| 866 def test_convert_old_to_new_else(self): | |
| 867 isolate_with_else_clauses = { | |
| 868 'conditions': [ | |
| 869 ['OS=="mac"', { | |
| 870 'variables': {'foo': 'bar'}, | |
| 871 }, { | |
| 872 'variables': {'x': 'y'}, | |
| 873 }], | |
| 874 ['OS=="foo"', { | |
| 875 }, { | |
| 876 'variables': {'p': 'q'}, | |
| 877 }], | |
| 878 ], | |
| 879 } | |
| 880 expected_output = { | |
| 881 'conditions': [ | |
| 882 ['OS=="foo" or OS=="linux" or OS=="win"', { | |
| 883 'variables': {'x': 'y'}, | |
| 884 }], | |
| 885 ['OS=="linux" or OS=="mac" or OS=="win"', { | |
| 886 'variables': {'p': 'q'}, | |
| 887 }], | |
| 888 ['OS=="mac"', { | |
| 889 'variables': {'foo': 'bar'}, | |
| 890 }], | |
| 891 ], | |
| 892 } | |
| 893 self.assertEqual( | |
| 894 expected_output, | |
| 895 isolate.convert_old_to_new_format(isolate_with_else_clauses)) | |
| 896 | |
| 897 def test_convert_old_to_new_default_variables(self): | |
| 898 isolate_with_default_variables = { | |
| 899 'conditions': [ | |
| 900 ['OS=="abc"', { | |
| 901 'variables': {'foo': 'bar'}, | |
| 902 }], | |
| 903 ], | |
| 904 'variables': {'p': 'q'}, | |
| 905 } | |
| 906 expected_output = { | |
| 907 'conditions': [ | |
| 908 ['OS=="abc"', { | |
| 909 'variables': {'foo': 'bar'}, | |
| 910 }], | |
| 911 ['OS=="abc" or OS=="linux" or OS=="mac" or OS=="win"', { | |
| 912 'variables': {'p': 'q'}, | |
| 913 }], | |
| 914 ], | |
| 915 } | |
| 916 self.assertEqual( | |
| 917 expected_output, | |
| 918 isolate.convert_old_to_new_format(isolate_with_default_variables)) | |
| 919 | |
| 920 def test_variable_arg(self): | |
| 921 parser = isolate.OptionParserIsolate() | |
| 922 parser.require_isolated = False | |
| 923 expected = { | |
| 924 'Baz': 'sub=string', | |
| 925 'EXECUTABLE_SUFFIX': '.exe' if isolate.get_flavor() == 'win' else '', | |
| 926 'Foo': 'bar', | |
| 927 'OS': isolate.get_flavor(), | |
| 928 } | |
| 929 | |
| 930 options, args = parser.parse_args( | |
| 931 ['-V', 'Foo', 'bar', '-V', 'Baz=sub=string']) | |
| 932 self.assertEqual(expected, options.variables) | |
| 933 self.assertEqual([], args) | |
| 934 | |
| 935 def test_variable_arg_fail(self): | |
| 936 parser = isolate.OptionParserIsolate() | |
| 937 self.mock(sys, 'stderr', cStringIO.StringIO()) | |
| 938 self.assertRaises(SystemExit, parser.parse_args, ['-V', 'Foo']) | |
| 939 | |
| 940 def test_blacklist(self): | |
| 941 ok = [ | |
| 942 '.git2', | |
| 943 '.pyc', | |
| 944 '.swp', | |
| 945 'allo.git', | |
| 946 'foo', | |
| 947 ] | |
| 948 blocked = [ | |
| 949 '.git', | |
| 950 os.path.join('foo', '.git'), | |
| 951 'foo.pyc', | |
| 952 'bar.swp', | |
| 953 ] | |
| 954 blacklist = isolate.trace_inputs.gen_blacklist(isolate.DEFAULT_BLACKLIST) | |
| 955 for i in ok: | |
| 956 self.assertFalse(blacklist(i), i) | |
| 957 for i in blocked: | |
| 958 self.assertTrue(blacklist(i), i) | |
| 959 | |
| 960 def test_blacklist_chromium(self): | |
| 961 ok = [ | |
| 962 '.run_test_cases', | |
| 963 'testserver.log2', | |
| 964 ] | |
| 965 blocked = [ | |
| 966 'foo.run_test_cases', | |
| 967 'testserver.log', | |
| 968 os.path.join('foo', 'testserver.log'), | |
| 969 ] | |
| 970 blacklist = isolate.trace_inputs.gen_blacklist(isolate.DEFAULT_BLACKLIST) | |
| 971 for i in ok: | |
| 972 self.assertFalse(blacklist(i), i) | |
| 973 for i in blocked: | |
| 974 self.assertTrue(blacklist(i), i) | |
| 975 | |
| 976 if sys.platform == 'darwin': | |
| 977 def test_expand_symlinks_path_case(self): | |
| 978 # Ensures that the resulting path case is fixed on case insensitive file | |
| 979 # system. | |
| 980 os.symlink('dest', os.path.join(self.cwd, 'link')) | |
| 981 os.mkdir(os.path.join(self.cwd, 'Dest')) | |
| 982 open(os.path.join(self.cwd, 'Dest', 'file.txt'), 'w').close() | |
| 983 | |
| 984 result = isolate.expand_symlinks(unicode(self.cwd), 'link') | |
| 985 self.assertEqual((u'Dest', [u'link']), result) | |
| 986 result = isolate.expand_symlinks(unicode(self.cwd), 'link/File.txt') | |
| 987 self.assertEqual((u'Dest/file.txt', [u'link']), result) | |
| 988 | |
| 989 def test_expand_directories_and_symlinks_path_case(self): | |
| 990 # Ensures that the resulting path case is fixed on case insensitive file | |
| 991 # system. A superset of test_expand_symlinks_path_case. | |
| 992 # Create *all* the paths with the wrong path case. | |
| 993 basedir = os.path.join(self.cwd, 'baseDir') | |
| 994 os.mkdir(basedir.lower()) | |
| 995 subdir = os.path.join(basedir, 'subDir') | |
| 996 os.mkdir(subdir.lower()) | |
| 997 open(os.path.join(subdir, 'Foo.txt'), 'w').close() | |
| 998 os.symlink('subDir', os.path.join(basedir, 'linkdir')) | |
| 999 actual = isolate.expand_directories_and_symlinks( | |
| 1000 unicode(self.cwd), [u'baseDir/'], lambda _: None, True, False) | |
| 1001 expected = [ | |
| 1002 u'basedir/linkdir', | |
| 1003 u'basedir/subdir/Foo.txt', | |
| 1004 u'basedir/subdir/Foo.txt', | |
| 1005 ] | |
| 1006 self.assertEqual(expected, actual) | |
| 1007 | |
| 1008 def test_process_input_path_case_simple(self): | |
| 1009 # Ensure the symlink dest is saved in the right path case. | |
| 1010 subdir = os.path.join(self.cwd, 'subdir') | |
| 1011 os.mkdir(subdir) | |
| 1012 linkdir = os.path.join(self.cwd, 'linkdir') | |
| 1013 os.symlink('subDir', linkdir) | |
| 1014 actual = isolate.process_input( | |
| 1015 unicode(linkdir.upper()), {}, True, 'mac', ALGO) | |
| 1016 expected = {'l': u'subdir', 'm': 360, 't': int(os.stat(linkdir).st_mtime)} | |
| 1017 self.assertEqual(expected, actual) | |
| 1018 | |
| 1019 def test_process_input_path_case_complex(self): | |
| 1020 # Ensure the symlink dest is saved in the right path case. This includes 2 | |
| 1021 # layers of symlinks. | |
| 1022 basedir = os.path.join(self.cwd, 'basebir') | |
| 1023 os.mkdir(basedir) | |
| 1024 | |
| 1025 linkeddir2 = os.path.join(self.cwd, 'linkeddir2') | |
| 1026 os.mkdir(linkeddir2) | |
| 1027 | |
| 1028 linkeddir1 = os.path.join(basedir, 'linkeddir1') | |
| 1029 os.symlink('../linkedDir2', linkeddir1) | |
| 1030 | |
| 1031 subsymlinkdir = os.path.join(basedir, 'symlinkdir') | |
| 1032 os.symlink('linkedDir1', subsymlinkdir) | |
| 1033 | |
| 1034 actual = isolate.process_input( | |
| 1035 unicode(subsymlinkdir.upper()), {}, True, 'mac', ALGO) | |
| 1036 expected = { | |
| 1037 'l': u'linkeddir1', 'm': 360, 't': int(os.stat(subsymlinkdir).st_mtime), | |
| 1038 } | |
| 1039 self.assertEqual(expected, actual) | |
| 1040 | |
| 1041 actual = isolate.process_input( | |
| 1042 unicode(linkeddir1.upper()), {}, True, 'mac', ALGO) | |
| 1043 expected = { | |
| 1044 'l': u'../linkeddir2', 'm': 360, 't': int(os.stat(linkeddir1).st_mtime), | |
| 1045 } | |
| 1046 self.assertEqual(expected, actual) | |
| 1047 | |
| 1048 if sys.platform != 'win32': | |
| 1049 def test_symlink_input_absolute_path(self): | |
| 1050 # A symlink is outside of the checkout, it should be treated as a normal | |
| 1051 # directory. | |
| 1052 # .../src | |
| 1053 # .../src/out -> .../tmp/foo | |
| 1054 # .../tmp | |
| 1055 # .../tmp/foo | |
| 1056 src = os.path.join(self.cwd, u'src') | |
| 1057 src_out = os.path.join(src, 'out') | |
| 1058 tmp = os.path.join(self.cwd, 'tmp') | |
| 1059 tmp_foo = os.path.join(tmp, 'foo') | |
| 1060 os.mkdir(src) | |
| 1061 os.mkdir(tmp) | |
| 1062 os.mkdir(tmp_foo) | |
| 1063 # The problem was that it's an absolute path, so it must be considered a | |
| 1064 # normal directory. | |
| 1065 os.symlink(tmp, src_out) | |
| 1066 open(os.path.join(tmp_foo, 'bar.txt'), 'w').close() | |
| 1067 actual = isolate.expand_symlinks(src, u'out/foo/bar.txt') | |
| 1068 self.assertEqual((u'out/foo/bar.txt', []), actual) | |
| 1069 | |
| 1070 | |
| 1071 class IsolateLoad(IsolateBase): | |
| 1072 def setUp(self): | |
| 1073 super(IsolateLoad, self).setUp() | |
| 1074 self.directory = tempfile.mkdtemp(prefix='isolate_') | |
| 1075 | |
| 1076 def tearDown(self): | |
| 1077 try: | |
| 1078 isolate.run_isolated.rmtree(self.directory) | |
| 1079 finally: | |
| 1080 super(IsolateLoad, self).tearDown() | |
| 1081 | |
| 1082 def _get_option(self, isolate_file): | |
| 1083 OS = isolate.get_flavor() | |
| 1084 chromeos_value = int(OS == 'linux') | |
| 1085 class Options(object): | |
| 1086 isolated = os.path.join(self.directory, 'foo.isolated') | |
| 1087 outdir = os.path.join(self.directory, 'outdir') | |
| 1088 isolate = isolate_file | |
| 1089 variables = {'foo': 'bar', 'OS': OS, 'chromeos': chromeos_value} | |
| 1090 ignore_broken_items = False | |
| 1091 return Options() | |
| 1092 | |
| 1093 def _cleanup_isolated(self, expected_isolated): | |
| 1094 """Modifies isolated to remove the non-deterministic parts.""" | |
| 1095 if sys.platform == 'win32': | |
| 1096 # 'm' are not saved in windows. | |
| 1097 for values in expected_isolated['files'].itervalues(): | |
| 1098 self.assertTrue(values.pop('m')) | |
| 1099 | |
| 1100 def _cleanup_saved_state(self, actual_saved_state): | |
| 1101 for item in actual_saved_state['files'].itervalues(): | |
| 1102 self.assertTrue(item.pop('t')) | |
| 1103 | |
| 1104 def test_load_stale_isolated(self): | |
| 1105 isolate_file = os.path.join( | |
| 1106 ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate') | |
| 1107 | |
| 1108 # Data to be loaded in the .isolated file. Do not create a .state file. | |
| 1109 input_data = { | |
| 1110 'command': ['python'], | |
| 1111 'files': { | |
| 1112 'foo': { | |
| 1113 "m": 416, | |
| 1114 "h": "invalid", | |
| 1115 "s": 538, | |
| 1116 "t": 1335146921, | |
| 1117 }, | |
| 1118 os.path.join('tests', 'isolate', 'touch_root.py'): { | |
| 1119 "m": 488, | |
| 1120 "h": "invalid", | |
| 1121 "s": 538, | |
| 1122 "t": 1335146921, | |
| 1123 }, | |
| 1124 }, | |
| 1125 } | |
| 1126 options = self._get_option(isolate_file) | |
| 1127 isolate.trace_inputs.write_json(options.isolated, input_data, False) | |
| 1128 | |
| 1129 # A CompleteState object contains two parts: | |
| 1130 # - Result instance stored in complete_state.isolated, corresponding to the | |
| 1131 # .isolated file, is what is read by run_test_from_archive.py. | |
| 1132 # - SavedState instance stored in compelte_state.saved_state, | |
| 1133 # corresponding to the .state file, which is simply to aid the developer | |
| 1134 # when re-running the same command multiple times and contain | |
| 1135 # discardable information. | |
| 1136 complete_state = isolate.load_complete_state(options, self.cwd, None, False) | |
| 1137 actual_isolated = complete_state.saved_state.to_isolated() | |
| 1138 actual_saved_state = complete_state.saved_state.flatten() | |
| 1139 | |
| 1140 expected_isolated = { | |
| 1141 'algo': 'sha-1', | |
| 1142 'command': ['python', 'touch_root.py'], | |
| 1143 'files': { | |
| 1144 os.path.join(u'tests', 'isolate', 'touch_root.py'): { | |
| 1145 'm': 488, | |
| 1146 'h': hash_file('tests', 'isolate', 'touch_root.py'), | |
| 1147 's': _size('tests', 'isolate', 'touch_root.py'), | |
| 1148 }, | |
| 1149 u'isolate.py': { | |
| 1150 'm': 488, | |
| 1151 'h': hash_file('isolate.py'), | |
| 1152 's': _size('isolate.py'), | |
| 1153 }, | |
| 1154 }, | |
| 1155 'os': isolate.get_flavor(), | |
| 1156 'relative_cwd': os.path.join(u'tests', 'isolate'), | |
| 1157 'version': '1.0', | |
| 1158 } | |
| 1159 self._cleanup_isolated(expected_isolated) | |
| 1160 self.assertEqual(expected_isolated, actual_isolated) | |
| 1161 | |
| 1162 expected_saved_state = { | |
| 1163 'algo': 'sha-1', | |
| 1164 'child_isolated_files': [], | |
| 1165 'command': ['python', 'touch_root.py'], | |
| 1166 'files': { | |
| 1167 os.path.join(u'tests', 'isolate', 'touch_root.py'): { | |
| 1168 'm': 488, | |
| 1169 'h': hash_file('tests', 'isolate', 'touch_root.py'), | |
| 1170 's': _size('tests', 'isolate', 'touch_root.py'), | |
| 1171 }, | |
| 1172 u'isolate.py': { | |
| 1173 'm': 488, | |
| 1174 'h': hash_file('isolate.py'), | |
| 1175 's': _size('isolate.py'), | |
| 1176 }, | |
| 1177 }, | |
| 1178 'isolate_file': isolate.safe_relpath( | |
| 1179 file_path.get_native_path_case(isolate_file), | |
| 1180 os.path.dirname(options.isolated)), | |
| 1181 'relative_cwd': os.path.join(u'tests', 'isolate'), | |
| 1182 'variables': { | |
| 1183 'foo': 'bar', | |
| 1184 'OS': isolate.get_flavor(), | |
| 1185 'chromeos': options.variables['chromeos'], | |
| 1186 }, | |
| 1187 'version': '1.0', | |
| 1188 } | |
| 1189 self._cleanup_isolated(expected_saved_state) | |
| 1190 self._cleanup_saved_state(actual_saved_state) | |
| 1191 self.assertEqual(expected_saved_state, actual_saved_state) | |
| 1192 | |
| 1193 def test_subdir(self): | |
| 1194 # The resulting .isolated file will be missing ../../isolate.py. It is | |
| 1195 # because this file is outside the --subdir parameter. | |
| 1196 isolate_file = os.path.join( | |
| 1197 ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate') | |
| 1198 options = self._get_option(isolate_file) | |
| 1199 chromeos_value = int(isolate.get_flavor() == 'linux') | |
| 1200 options.variables['chromeos'] = chromeos_value | |
| 1201 complete_state = isolate.load_complete_state( | |
| 1202 options, self.cwd, os.path.join('tests', 'isolate'), False) | |
| 1203 actual_isolated = complete_state.saved_state.to_isolated() | |
| 1204 actual_saved_state = complete_state.saved_state.flatten() | |
| 1205 | |
| 1206 expected_isolated = { | |
| 1207 'algo': 'sha-1', | |
| 1208 'command': ['python', 'touch_root.py'], | |
| 1209 'files': { | |
| 1210 os.path.join(u'tests', 'isolate', 'touch_root.py'): { | |
| 1211 'm': 488, | |
| 1212 'h': hash_file('tests', 'isolate', 'touch_root.py'), | |
| 1213 's': _size('tests', 'isolate', 'touch_root.py'), | |
| 1214 }, | |
| 1215 }, | |
| 1216 'os': isolate.get_flavor(), | |
| 1217 'relative_cwd': os.path.join(u'tests', 'isolate'), | |
| 1218 'version': '1.0', | |
| 1219 } | |
| 1220 self._cleanup_isolated(expected_isolated) | |
| 1221 self.assertEqual(expected_isolated, actual_isolated) | |
| 1222 | |
| 1223 expected_saved_state = { | |
| 1224 'algo': 'sha-1', | |
| 1225 'child_isolated_files': [], | |
| 1226 'command': ['python', 'touch_root.py'], | |
| 1227 'files': { | |
| 1228 os.path.join(u'tests', 'isolate', 'touch_root.py'): { | |
| 1229 'm': 488, | |
| 1230 'h': hash_file('tests', 'isolate', 'touch_root.py'), | |
| 1231 's': _size('tests', 'isolate', 'touch_root.py'), | |
| 1232 }, | |
| 1233 }, | |
| 1234 'isolate_file': isolate.safe_relpath( | |
| 1235 file_path.get_native_path_case(isolate_file), | |
| 1236 os.path.dirname(options.isolated)), | |
| 1237 'relative_cwd': os.path.join(u'tests', 'isolate'), | |
| 1238 'variables': { | |
| 1239 'foo': 'bar', | |
| 1240 'OS': isolate.get_flavor(), | |
| 1241 'chromeos': chromeos_value, | |
| 1242 }, | |
| 1243 'version': '1.0', | |
| 1244 } | |
| 1245 self._cleanup_isolated(expected_saved_state) | |
| 1246 self._cleanup_saved_state(actual_saved_state) | |
| 1247 self.assertEqual(expected_saved_state, actual_saved_state) | |
| 1248 | |
| 1249 def test_subdir_variable(self): | |
| 1250 # the resulting .isolated file will be missing ../../isolate.py. it is | |
| 1251 # because this file is outside the --subdir parameter. | |
| 1252 isolate_file = os.path.join( | |
| 1253 ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate') | |
| 1254 options = self._get_option(isolate_file) | |
| 1255 chromeos_value = int(isolate.get_flavor() == 'linux') | |
| 1256 options.variables['chromeos'] = chromeos_value | |
| 1257 options.variables['BAZ'] = os.path.join('tests', 'isolate') | |
| 1258 complete_state = isolate.load_complete_state( | |
| 1259 options, self.cwd, '<(BAZ)', False) | |
| 1260 actual_isolated = complete_state.saved_state.to_isolated() | |
| 1261 actual_saved_state = complete_state.saved_state.flatten() | |
| 1262 | |
| 1263 expected_isolated = { | |
| 1264 'algo': 'sha-1', | |
| 1265 'command': ['python', 'touch_root.py'], | |
| 1266 'files': { | |
| 1267 os.path.join('tests', 'isolate', 'touch_root.py'): { | |
| 1268 'm': 488, | |
| 1269 'h': hash_file('tests', 'isolate', 'touch_root.py'), | |
| 1270 's': _size('tests', 'isolate', 'touch_root.py'), | |
| 1271 }, | |
| 1272 }, | |
| 1273 'os': isolate.get_flavor(), | |
| 1274 'relative_cwd': os.path.join(u'tests', 'isolate'), | |
| 1275 'version': '1.0', | |
| 1276 } | |
| 1277 self._cleanup_isolated(expected_isolated) | |
| 1278 self.assertEqual(expected_isolated, actual_isolated) | |
| 1279 | |
| 1280 expected_saved_state = { | |
| 1281 'algo': 'sha-1', | |
| 1282 'child_isolated_files': [], | |
| 1283 'command': ['python', 'touch_root.py'], | |
| 1284 'files': { | |
| 1285 os.path.join(u'tests', 'isolate', 'touch_root.py'): { | |
| 1286 'm': 488, | |
| 1287 'h': hash_file('tests', 'isolate', 'touch_root.py'), | |
| 1288 's': _size('tests', 'isolate', 'touch_root.py'), | |
| 1289 }, | |
| 1290 }, | |
| 1291 'isolate_file': isolate.safe_relpath( | |
| 1292 file_path.get_native_path_case(isolate_file), | |
| 1293 os.path.dirname(options.isolated)), | |
| 1294 'relative_cwd': os.path.join(u'tests', 'isolate'), | |
| 1295 'variables': { | |
| 1296 'foo': 'bar', | |
| 1297 'BAZ': os.path.join('tests', 'isolate'), | |
| 1298 'OS': isolate.get_flavor(), | |
| 1299 'chromeos': chromeos_value, | |
| 1300 }, | |
| 1301 'version': '1.0', | |
| 1302 } | |
| 1303 self._cleanup_isolated(expected_saved_state) | |
| 1304 self._cleanup_saved_state(actual_saved_state) | |
| 1305 self.assertEqual(expected_saved_state, actual_saved_state) | |
| 1306 | |
| 1307 def test_variable_not_exist(self): | |
| 1308 isolate_file = os.path.join( | |
| 1309 ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate') | |
| 1310 options = self._get_option(isolate_file) | |
| 1311 options.variables['PRODUCT_DIR'] = os.path.join(u'tests', u'isolate') | |
| 1312 native_cwd = file_path.get_native_path_case(unicode(self.cwd)) | |
| 1313 try: | |
| 1314 isolate.load_complete_state(options, self.cwd, None, False) | |
| 1315 self.fail() | |
| 1316 except isolate.ExecutionError, e: | |
| 1317 self.assertEqual( | |
| 1318 'PRODUCT_DIR=%s is not a directory' % | |
| 1319 os.path.join(native_cwd, 'tests', 'isolate'), | |
| 1320 e.args[0]) | |
| 1321 | |
| 1322 def test_variable(self): | |
| 1323 isolate_file = os.path.join( | |
| 1324 ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate') | |
| 1325 options = self._get_option(isolate_file) | |
| 1326 chromeos_value = int(isolate.get_flavor() == 'linux') | |
| 1327 options.variables['chromeos'] = chromeos_value | |
| 1328 options.variables['PRODUCT_DIR'] = os.path.join('tests', 'isolate') | |
| 1329 complete_state = isolate.load_complete_state(options, ROOT_DIR, None, False) | |
| 1330 actual_isolated = complete_state.saved_state.to_isolated() | |
| 1331 actual_saved_state = complete_state.saved_state.flatten() | |
| 1332 | |
| 1333 expected_isolated = { | |
| 1334 'algo': 'sha-1', | |
| 1335 'command': ['python', 'touch_root.py'], | |
| 1336 'files': { | |
| 1337 u'isolate.py': { | |
| 1338 'm': 488, | |
| 1339 'h': hash_file('isolate.py'), | |
| 1340 's': _size('isolate.py'), | |
| 1341 }, | |
| 1342 os.path.join(u'tests', 'isolate', 'touch_root.py'): { | |
| 1343 'm': 488, | |
| 1344 'h': hash_file('tests', 'isolate', 'touch_root.py'), | |
| 1345 's': _size('tests', 'isolate', 'touch_root.py'), | |
| 1346 }, | |
| 1347 }, | |
| 1348 'os': isolate.get_flavor(), | |
| 1349 'relative_cwd': os.path.join(u'tests', 'isolate'), | |
| 1350 'version': '1.0', | |
| 1351 } | |
| 1352 self._cleanup_isolated(expected_isolated) | |
| 1353 self.assertEqual(expected_isolated, actual_isolated) | |
| 1354 | |
| 1355 expected_saved_state = { | |
| 1356 'algo': 'sha-1', | |
| 1357 'child_isolated_files': [], | |
| 1358 'command': ['python', 'touch_root.py'], | |
| 1359 'files': { | |
| 1360 u'isolate.py': { | |
| 1361 'm': 488, | |
| 1362 'h': hash_file('isolate.py'), | |
| 1363 's': _size('isolate.py'), | |
| 1364 }, | |
| 1365 os.path.join(u'tests', 'isolate', 'touch_root.py'): { | |
| 1366 'm': 488, | |
| 1367 'h': hash_file('tests', 'isolate', 'touch_root.py'), | |
| 1368 's': _size('tests', 'isolate', 'touch_root.py'), | |
| 1369 }, | |
| 1370 }, | |
| 1371 'isolate_file': isolate.safe_relpath( | |
| 1372 file_path.get_native_path_case(isolate_file), | |
| 1373 os.path.dirname(options.isolated)), | |
| 1374 'relative_cwd': os.path.join(u'tests', 'isolate'), | |
| 1375 'variables': { | |
| 1376 'foo': 'bar', | |
| 1377 'PRODUCT_DIR': '.', | |
| 1378 'OS': isolate.get_flavor(), | |
| 1379 'chromeos': chromeos_value, | |
| 1380 }, | |
| 1381 'version': '1.0', | |
| 1382 } | |
| 1383 self._cleanup_isolated(expected_saved_state) | |
| 1384 self._cleanup_saved_state(actual_saved_state) | |
| 1385 self.assertEqual(expected_saved_state, actual_saved_state) | |
| 1386 self.assertEqual([], os.listdir(self.directory)) | |
| 1387 | |
| 1388 def test_root_dir_because_of_variable(self): | |
| 1389 # Ensures that load_isolate() works even when path variables have deep root | |
| 1390 # dirs. The end result is similar to touch_root.isolate, except that | |
| 1391 # no_run.isolate doesn't reference '..' at all. | |
| 1392 # | |
| 1393 # A real world example would be PRODUCT_DIR=../../out/Release but nothing in | |
| 1394 # this directory is mapped. | |
| 1395 # | |
| 1396 # Imagine base/base_unittests.isolate would not map anything in | |
| 1397 # PRODUCT_DIR. In that case, the automatically determined root dir is | |
| 1398 # src/base, since nothing outside this directory is mapped. | |
| 1399 isolate_file = os.path.join( | |
| 1400 ROOT_DIR, 'tests', 'isolate', 'no_run.isolate') | |
| 1401 options = self._get_option(isolate_file) | |
| 1402 chromeos_value = int(isolate.get_flavor() == 'linux') | |
| 1403 # Any directory outside ROOT_DIR/tests/isolate. | |
| 1404 options.variables['PRODUCT_DIR'] = os.path.join('third_party') | |
| 1405 complete_state = isolate.load_complete_state(options, ROOT_DIR, None, False) | |
| 1406 actual_isolated = complete_state.saved_state.to_isolated() | |
| 1407 actual_saved_state = complete_state.saved_state.flatten() | |
| 1408 | |
| 1409 expected_isolated = { | |
| 1410 'algo': 'sha-1', | |
| 1411 'files': { | |
| 1412 os.path.join(u'tests', 'isolate', 'files1', 'subdir', '42.txt'): { | |
| 1413 'm': 416, | |
| 1414 'h': hash_file('tests', 'isolate', 'files1', 'subdir', '42.txt'), | |
| 1415 's': _size('tests', 'isolate', 'files1', 'subdir', '42.txt'), | |
| 1416 }, | |
| 1417 os.path.join(u'tests', 'isolate', 'files1', 'test_file1.txt'): { | |
| 1418 'm': 416, | |
| 1419 'h': hash_file('tests', 'isolate', 'files1', 'test_file1.txt'), | |
| 1420 's': _size('tests', 'isolate', 'files1', 'test_file1.txt'), | |
| 1421 }, | |
| 1422 os.path.join(u'tests', 'isolate', 'files1', 'test_file2.txt'): { | |
| 1423 'm': 416, | |
| 1424 'h': hash_file('tests', 'isolate', 'files1', 'test_file2.txt'), | |
| 1425 's': _size('tests', 'isolate', 'files1', 'test_file2.txt'), | |
| 1426 }, | |
| 1427 os.path.join(u'tests', 'isolate', 'no_run.isolate'): { | |
| 1428 'm': 416, | |
| 1429 'h': hash_file('tests', 'isolate', 'no_run.isolate'), | |
| 1430 's': _size('tests', 'isolate', 'no_run.isolate'), | |
| 1431 }, | |
| 1432 }, | |
| 1433 'os': isolate.get_flavor(), | |
| 1434 'relative_cwd': os.path.join(u'tests', 'isolate'), | |
| 1435 'version': '1.0', | |
| 1436 } | |
| 1437 self._cleanup_isolated(expected_isolated) | |
| 1438 self.assertEqual(expected_isolated, actual_isolated) | |
| 1439 | |
| 1440 expected_saved_state = { | |
| 1441 'algo': 'sha-1', | |
| 1442 'child_isolated_files': [], | |
| 1443 'command': [], | |
| 1444 'files': { | |
| 1445 os.path.join(u'tests', 'isolate', 'files1', 'subdir', '42.txt'): { | |
| 1446 'm': 416, | |
| 1447 'h': hash_file('tests', 'isolate', 'files1', 'subdir', '42.txt'), | |
| 1448 's': _size('tests', 'isolate', 'files1', 'subdir', '42.txt'), | |
| 1449 }, | |
| 1450 os.path.join(u'tests', 'isolate', 'files1', 'test_file1.txt'): { | |
| 1451 'm': 416, | |
| 1452 'h': hash_file('tests', 'isolate', 'files1', 'test_file1.txt'), | |
| 1453 's': _size('tests', 'isolate', 'files1', 'test_file1.txt'), | |
| 1454 }, | |
| 1455 os.path.join(u'tests', 'isolate', 'files1', 'test_file2.txt'): { | |
| 1456 'm': 416, | |
| 1457 'h': hash_file('tests', 'isolate', 'files1', 'test_file2.txt'), | |
| 1458 's': _size('tests', 'isolate', 'files1', 'test_file2.txt'), | |
| 1459 }, | |
| 1460 os.path.join(u'tests', 'isolate', 'no_run.isolate'): { | |
| 1461 'm': 416, | |
| 1462 'h': hash_file('tests', 'isolate', 'no_run.isolate'), | |
| 1463 's': _size('tests', 'isolate', 'no_run.isolate'), | |
| 1464 }, | |
| 1465 }, | |
| 1466 'isolate_file': isolate.safe_relpath( | |
| 1467 file_path.get_native_path_case(isolate_file), | |
| 1468 os.path.dirname(options.isolated)), | |
| 1469 'relative_cwd': os.path.join(u'tests', 'isolate'), | |
| 1470 'variables': { | |
| 1471 'foo': 'bar', | |
| 1472 'PRODUCT_DIR': os.path.join(u'..', '..', 'third_party'), | |
| 1473 'OS': isolate.get_flavor(), | |
| 1474 'chromeos': chromeos_value, | |
| 1475 }, | |
| 1476 'version': '1.0', | |
| 1477 } | |
| 1478 self._cleanup_isolated(expected_saved_state) | |
| 1479 self._cleanup_saved_state(actual_saved_state) | |
| 1480 self.assertEqual(expected_saved_state, actual_saved_state) | |
| 1481 self.assertEqual([], os.listdir(self.directory)) | |
| 1482 | |
| 1483 def test_chromium_split(self): | |
| 1484 # Create an .isolate file and a tree of random stuff. | |
| 1485 isolate_file = os.path.join( | |
| 1486 ROOT_DIR, 'tests', 'isolate', 'split.isolate') | |
| 1487 options = self._get_option(isolate_file) | |
| 1488 options.variables = { | |
| 1489 'OS': isolate.get_flavor(), | |
| 1490 'DEPTH': '.', | |
| 1491 'PRODUCT_DIR': os.path.join('files1'), | |
| 1492 } | |
| 1493 complete_state = isolate.load_complete_state( | |
| 1494 options, os.path.join(ROOT_DIR, 'tests', 'isolate'), None, False) | |
| 1495 # By saving the files, it forces splitting the data up. | |
| 1496 complete_state.save_files() | |
| 1497 | |
| 1498 actual_isolated_master = isolate.trace_inputs.read_json( | |
| 1499 os.path.join(self.directory, 'foo.isolated')) | |
| 1500 expected_isolated_master = { | |
| 1501 u'algo': u'sha-1', | |
| 1502 u'command': [u'python', u'split.py'], | |
| 1503 u'files': { | |
| 1504 u'split.py': { | |
| 1505 u'm': 488, | |
| 1506 u'h': unicode(hash_file('tests', 'isolate', 'split.py')), | |
| 1507 u's': _size('tests', 'isolate', 'split.py'), | |
| 1508 }, | |
| 1509 }, | |
| 1510 u'includes': [ | |
| 1511 unicode(hash_file(os.path.join(self.directory, 'foo.0.isolated'))), | |
| 1512 unicode(hash_file(os.path.join(self.directory, 'foo.1.isolated'))), | |
| 1513 ], | |
| 1514 u'os': unicode(isolate.get_flavor()), | |
| 1515 u'relative_cwd': u'.', | |
| 1516 u'version': u'1.0', | |
| 1517 } | |
| 1518 self._cleanup_isolated(expected_isolated_master) | |
| 1519 self.assertEqual(expected_isolated_master, actual_isolated_master) | |
| 1520 | |
| 1521 actual_isolated_0 = isolate.trace_inputs.read_json( | |
| 1522 os.path.join(self.directory, 'foo.0.isolated')) | |
| 1523 expected_isolated_0 = { | |
| 1524 u'algo': u'sha-1', | |
| 1525 u'files': { | |
| 1526 os.path.join(u'test', 'data', 'foo.txt'): { | |
| 1527 u'm': 416, | |
| 1528 u'h': unicode( | |
| 1529 hash_file('tests', 'isolate', 'test', 'data', 'foo.txt')), | |
| 1530 u's': _size('tests', 'isolate', 'test', 'data', 'foo.txt'), | |
| 1531 }, | |
| 1532 }, | |
| 1533 u'os': unicode(isolate.get_flavor()), | |
| 1534 u'version': u'1.0', | |
| 1535 } | |
| 1536 self._cleanup_isolated(expected_isolated_0) | |
| 1537 self.assertEqual(expected_isolated_0, actual_isolated_0) | |
| 1538 | |
| 1539 actual_isolated_1 = isolate.trace_inputs.read_json( | |
| 1540 os.path.join(self.directory, 'foo.1.isolated')) | |
| 1541 expected_isolated_1 = { | |
| 1542 u'algo': u'sha-1', | |
| 1543 u'files': { | |
| 1544 os.path.join(u'files1', 'subdir', '42.txt'): { | |
| 1545 u'm': 416, | |
| 1546 u'h': unicode( | |
| 1547 hash_file('tests', 'isolate', 'files1', 'subdir', '42.txt')), | |
| 1548 u's': _size('tests', 'isolate', 'files1', 'subdir', '42.txt'), | |
| 1549 }, | |
| 1550 }, | |
| 1551 u'os': unicode(isolate.get_flavor()), | |
| 1552 u'version': u'1.0', | |
| 1553 } | |
| 1554 self._cleanup_isolated(expected_isolated_1) | |
| 1555 self.assertEqual(expected_isolated_1, actual_isolated_1) | |
| 1556 | |
| 1557 actual_saved_state = isolate.trace_inputs.read_json( | |
| 1558 isolate.isolatedfile_to_state(options.isolated)) | |
| 1559 isolated_base = unicode(os.path.basename(options.isolated)) | |
| 1560 expected_saved_state = { | |
| 1561 u'algo': u'sha-1', | |
| 1562 u'child_isolated_files': [ | |
| 1563 isolated_base[:-len('.isolated')] + '.0.isolated', | |
| 1564 isolated_base[:-len('.isolated')] + '.1.isolated', | |
| 1565 ], | |
| 1566 u'command': [u'python', u'split.py'], | |
| 1567 u'files': { | |
| 1568 os.path.join(u'files1', 'subdir', '42.txt'): { | |
| 1569 u'm': 416, | |
| 1570 u'h': unicode( | |
| 1571 hash_file('tests', 'isolate', 'files1', 'subdir', '42.txt')), | |
| 1572 u's': _size('tests', 'isolate', 'files1', 'subdir', '42.txt'), | |
| 1573 }, | |
| 1574 u'split.py': { | |
| 1575 u'm': 488, | |
| 1576 u'h': unicode(hash_file('tests', 'isolate', 'split.py')), | |
| 1577 u's': _size('tests', 'isolate', 'split.py'), | |
| 1578 }, | |
| 1579 os.path.join(u'test', 'data', 'foo.txt'): { | |
| 1580 u'm': 416, | |
| 1581 u'h': unicode( | |
| 1582 hash_file('tests', 'isolate', 'test', 'data', 'foo.txt')), | |
| 1583 u's': _size('tests', 'isolate', 'test', 'data', 'foo.txt'), | |
| 1584 }, | |
| 1585 }, | |
| 1586 u'isolate_file': isolate.safe_relpath( | |
| 1587 file_path.get_native_path_case(isolate_file), | |
| 1588 unicode(os.path.dirname(options.isolated))), | |
| 1589 u'relative_cwd': u'.', | |
| 1590 u'variables': { | |
| 1591 u'OS': unicode(isolate.get_flavor()), | |
| 1592 u'DEPTH': u'.', | |
| 1593 u'PRODUCT_DIR': u'files1', | |
| 1594 }, | |
| 1595 u'version': u'1.0', | |
| 1596 } | |
| 1597 self._cleanup_isolated(expected_saved_state) | |
| 1598 self._cleanup_saved_state(actual_saved_state) | |
| 1599 self.assertEqual(expected_saved_state, actual_saved_state) | |
| 1600 self.assertEqual( | |
| 1601 [ | |
| 1602 'foo.0.isolated', 'foo.1.isolated', | |
| 1603 'foo.isolated', 'foo.isolated.state', | |
| 1604 ], | |
| 1605 sorted(os.listdir(self.directory))) | |
| 1606 | |
| 1607 | |
| 1608 class IsolateCommand(IsolateBase): | |
| 1609 def load_complete_state(self, *_): | |
| 1610 """Creates a minimalist CompleteState instance without an .isolated | |
| 1611 reference. | |
| 1612 """ | |
| 1613 out = isolate.CompleteState(None, isolate.SavedState(self.cwd)) | |
| 1614 out.saved_state.isolate_file = u'blah.isolate' | |
| 1615 out.saved_state.relative_cwd = u'' | |
| 1616 return out | |
| 1617 | |
| 1618 def test_CMDrewrite(self): | |
| 1619 isolate_file = os.path.join(self.cwd, 'x.isolate') | |
| 1620 data = ( | |
| 1621 '# Foo', | |
| 1622 '{', | |
| 1623 '}', | |
| 1624 ) | |
| 1625 with open(isolate_file, 'wb') as f: | |
| 1626 f.write('\n'.join(data)) | |
| 1627 | |
| 1628 self.mock(sys, 'stdout', cStringIO.StringIO()) | |
| 1629 cmd = ['-i', isolate_file] | |
| 1630 self.assertEqual(0, isolate.CMDrewrite(isolate.OptionParserIsolate(), cmd)) | |
| 1631 with open(isolate_file, 'rb') as f: | |
| 1632 actual = f.read() | |
| 1633 | |
| 1634 expected = "# Foo\n{\n 'conditions': [\n ],\n}\n" | |
| 1635 self.assertEqual(expected, actual) | |
| 1636 | |
| 1637 if sys.platform != 'win32': | |
| 1638 def test_CMDcheck_no_mode_on_windows(self): | |
| 1639 # Store for Windows, make sure file mode are not included. Hopefully, run | |
| 1640 # this test on another OS. | |
| 1641 isolate_file = os.path.join( | |
| 1642 ROOT_DIR, 'tests', 'isolate', 'symlink_full.isolate') | |
| 1643 isolated_file = os.path.join(self.cwd, 'foo.isolated') | |
| 1644 cmd = [ | |
| 1645 '-i', isolate_file, | |
| 1646 '-V', 'OS', 'win', | |
| 1647 '-V', 'chromeos', '0', | |
| 1648 '-s', isolated_file, | |
| 1649 ] | |
| 1650 self.assertEqual(0, isolate.CMDcheck(isolate.OptionParserIsolate(), cmd)) | |
| 1651 with open(isolated_file, 'rb') as f: | |
| 1652 actual = json.load(f) | |
| 1653 mapped = [ | |
| 1654 os.path.join(u'files2', 'subdir', '42.txt'), | |
| 1655 os.path.join(u'files2', 'test_file1.txt'), | |
| 1656 os.path.join(u'files2', 'test_file2.txt'), | |
| 1657 os.path.join(u'symlink_full.py'), | |
| 1658 ] | |
| 1659 files = dict( | |
| 1660 ( | |
| 1661 f, | |
| 1662 { | |
| 1663 u'h': unicode(hash_file('tests', 'isolate', f)), | |
| 1664 u's': _size('tests', 'isolate', f), | |
| 1665 } | |
| 1666 ) | |
| 1667 for f in mapped) | |
| 1668 expected = { | |
| 1669 u'algo': u'sha-1', | |
| 1670 u'command': [u'python', u'symlink_full.py'], | |
| 1671 u'files': files, | |
| 1672 u'os': u'win', | |
| 1673 u'relative_cwd': u'.', | |
| 1674 u'version': u'1.0', | |
| 1675 } | |
| 1676 self.assertEqual(expected, actual) | |
| 1677 | |
| 1678 def test_CMDrun_extra_args(self): | |
| 1679 cmd = [ | |
| 1680 'run', | |
| 1681 '--isolate', 'blah.isolate', | |
| 1682 '--outdir', os.path.join(self.cwd, 'jumbo'), | |
| 1683 '--', 'extra_args', | |
| 1684 ] | |
| 1685 self.mock(isolate, 'load_complete_state', self.load_complete_state) | |
| 1686 self.mock(isolate.subprocess, 'call', lambda *_, **_kwargs: 0) | |
| 1687 self.assertEqual(0, isolate.CMDrun(isolate.OptionParserIsolate(), cmd)) | |
| 1688 | |
| 1689 | |
| 1690 if __name__ == '__main__': | |
| 1691 logging.basicConfig( | |
| 1692 level=logging.DEBUG if '-v' in sys.argv else logging.ERROR, | |
| 1693 format='%(levelname)5s %(filename)15s(%(lineno)3d): %(message)s') | |
| 1694 if '-v' in sys.argv: | |
| 1695 unittest.TestCase.maxDiff = None | |
| 1696 unittest.main() | |
| OLD | NEW |