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 logging |
| 8 import os |
| 9 import sys |
| 10 import tempfile |
| 11 import unittest |
| 12 |
| 13 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
| 14 sys.path.insert(0, ROOT_DIR) |
| 15 |
| 16 import isolate |
| 17 # Create shortcuts. |
| 18 from isolate import KEY_TOUCHED, KEY_TRACKED, KEY_UNTRACKED |
| 19 |
| 20 |
| 21 class Isolate(unittest.TestCase): |
| 22 def setUp(self): |
| 23 # Everything should work even from another directory. |
| 24 os.chdir(os.path.dirname(ROOT_DIR)) |
| 25 |
| 26 def test_load_isolate_for_flavor_empty(self): |
| 27 content = "{}" |
| 28 command, infiles, touched, read_only = isolate.load_isolate_for_flavor( |
| 29 content, isolate.get_flavor()) |
| 30 self.assertEquals([], command) |
| 31 self.assertEquals([], infiles) |
| 32 self.assertEquals([], touched) |
| 33 self.assertEquals(None, read_only) |
| 34 |
| 35 def test_result_load_empty(self): |
| 36 values = { |
| 37 } |
| 38 expected = { |
| 39 'command': [], |
| 40 'files': {}, |
| 41 'os': isolate.get_flavor(), |
| 42 } |
| 43 self.assertEquals(expected, isolate.Result.load(values).flatten()) |
| 44 |
| 45 def test_result_load(self): |
| 46 values = { |
| 47 'command': 'maybe', |
| 48 'files': {'foo': 42}, |
| 49 'read_only': 2, |
| 50 } |
| 51 expected = { |
| 52 'command': 'maybe', |
| 53 'files': {'foo': 42}, |
| 54 'os': isolate.get_flavor(), |
| 55 'read_only': 2, |
| 56 } |
| 57 self.assertEquals(expected, isolate.Result.load(values).flatten()) |
| 58 |
| 59 def test_result_load_unexpected(self): |
| 60 values = { |
| 61 'foo': 'bar', |
| 62 } |
| 63 expected = ( |
| 64 ("Found unexpected entry {'foo': 'bar'} while constructing an " |
| 65 "object Result"), |
| 66 {'foo': 'bar'}, |
| 67 'Result') |
| 68 try: |
| 69 isolate.Result.load(values) |
| 70 self.fail() |
| 71 except ValueError, e: |
| 72 self.assertEquals(expected, e.args) |
| 73 |
| 74 def test_savedstate_load_empty(self): |
| 75 values = { |
| 76 } |
| 77 expected = { |
| 78 'variables': {}, |
| 79 } |
| 80 self.assertEquals(expected, isolate.SavedState.load(values).flatten()) |
| 81 |
| 82 def test_savedstate_load(self): |
| 83 values = { |
| 84 'isolate_file': os.path.join(ROOT_DIR, 'maybe'), |
| 85 'variables': {'foo': 42}, |
| 86 } |
| 87 expected = { |
| 88 'isolate_file': os.path.join(ROOT_DIR, 'maybe'), |
| 89 'variables': {'foo': 42}, |
| 90 } |
| 91 self.assertEquals(expected, isolate.SavedState.load(values).flatten()) |
| 92 |
| 93 def test_load_stale_result(self): |
| 94 directory = tempfile.mkdtemp(prefix='isolate_') |
| 95 try: |
| 96 isolate_file = os.path.join( |
| 97 ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate') |
| 98 class Options(object): |
| 99 result = os.path.join(directory, 'result') |
| 100 outdir = os.path.join(directory, '0utdir') |
| 101 isolate = isolate_file |
| 102 variables = {'foo': 'bar'} |
| 103 |
| 104 # Data to be loaded in the .result file. Do not create a .state file. |
| 105 input_data = { |
| 106 'command': ['python'], |
| 107 'files': { |
| 108 'foo': { |
| 109 "mode": 416, |
| 110 "sha-1": "invalid", |
| 111 "size": 538, |
| 112 "timestamp": 1335146921, |
| 113 }, |
| 114 os.path.join('tests', 'isolate', 'touch_root.py'): { |
| 115 "mode": 488, |
| 116 "sha-1": "invalid", |
| 117 "size": 538, |
| 118 "timestamp": 1335146921, |
| 119 }, |
| 120 }, |
| 121 } |
| 122 isolate.trace_inputs.write_json(Options.result, input_data, False) |
| 123 |
| 124 # A CompleteState object contains two parts: |
| 125 # - Result instance stored in complete_state.result, corresponding to the |
| 126 # .result file, is what is read by run_test_from_archive.py. |
| 127 # - SavedState instance stored in compelte_state.saved_state, |
| 128 # corresponding to the .state file, which is simply to aid the developer |
| 129 # when re-running the same command multiple times and contain |
| 130 # discardable information. |
| 131 complete_state = isolate.load_complete_state(Options, isolate.STATS_ONLY) |
| 132 actual_result = complete_state.result.flatten() |
| 133 actual_saved_state = complete_state.saved_state.flatten() |
| 134 |
| 135 expected_result = { |
| 136 'command': ['python', 'touch_root.py'], |
| 137 'files': { |
| 138 os.path.join(u'tests', 'isolate', 'touch_root.py'): { |
| 139 'mode': 488, |
| 140 'size': self._size('tests', 'isolate', 'touch_root.py'), |
| 141 }, |
| 142 'isolate.py': { |
| 143 'mode': 488, |
| 144 'size': self._size('isolate.py'), |
| 145 }, |
| 146 }, |
| 147 'os': isolate.get_flavor(), |
| 148 'relative_cwd': os.path.join('tests', 'isolate'), |
| 149 } |
| 150 if sys.platform == 'win32': |
| 151 # 'mode' are not saved in windows. |
| 152 for values in expected_result['files'].itervalues(): |
| 153 del values['mode'] |
| 154 for item in actual_result['files'].itervalues(): |
| 155 self.assertTrue(item.pop('timestamp')) |
| 156 self.assertEquals(expected_result, actual_result) |
| 157 |
| 158 expected_saved_state = { |
| 159 'isolate_file': isolate_file, |
| 160 'variables': {'foo': 'bar'}, |
| 161 } |
| 162 self.assertEquals(expected_saved_state, actual_saved_state) |
| 163 finally: |
| 164 isolate.run_swarm_step.rmtree(directory) |
| 165 |
| 166 @staticmethod |
| 167 def _size(*args): |
| 168 return os.stat(os.path.join(ROOT_DIR, *args)).st_size |
| 169 |
| 170 def test_unknown_key(self): |
| 171 try: |
| 172 isolate.verify_variables({'foo': [],}) |
| 173 self.fail() |
| 174 except AssertionError: |
| 175 pass |
| 176 |
| 177 def test_unknown_var(self): |
| 178 try: |
| 179 isolate.verify_condition({'variables': {'foo': [],}}) |
| 180 self.fail() |
| 181 except AssertionError: |
| 182 pass |
| 183 |
| 184 def test_union(self): |
| 185 value1 = { |
| 186 'a': set(['A']), |
| 187 'b': ['B', 'C'], |
| 188 'c': 'C', |
| 189 } |
| 190 value2 = { |
| 191 'a': set(['B', 'C']), |
| 192 'b': [], |
| 193 'd': set(), |
| 194 } |
| 195 expected = { |
| 196 'a': set(['A', 'B', 'C']), |
| 197 'b': ['B', 'C'], |
| 198 'c': 'C', |
| 199 'd': set(), |
| 200 } |
| 201 self.assertEquals(expected, isolate.union(value1, value2)) |
| 202 |
| 203 def test_eval_content(self): |
| 204 try: |
| 205 # Intrinsics are not available. |
| 206 isolate.eval_content('map(str, [1, 2])') |
| 207 self.fail() |
| 208 except NameError: |
| 209 pass |
| 210 |
| 211 def test_load_isolate_as_config_empty(self): |
| 212 self.assertEquals({}, isolate.load_isolate_as_config( |
| 213 {}, None, []).flatten()) |
| 214 |
| 215 def test_load_isolate_as_config(self): |
| 216 value = { |
| 217 'variables': { |
| 218 KEY_TRACKED: ['a'], |
| 219 KEY_UNTRACKED: ['b'], |
| 220 KEY_TOUCHED: ['touched'], |
| 221 }, |
| 222 'conditions': [ |
| 223 ['OS=="atari"', { |
| 224 'variables': { |
| 225 KEY_TRACKED: ['c', 'x'], |
| 226 KEY_UNTRACKED: ['d'], |
| 227 KEY_TOUCHED: ['touched_a'], |
| 228 'command': ['echo', 'Hello World'], |
| 229 'read_only': True, |
| 230 }, |
| 231 }, { # else |
| 232 'variables': { |
| 233 KEY_TRACKED: ['e', 'x'], |
| 234 KEY_UNTRACKED: ['f'], |
| 235 KEY_TOUCHED: ['touched_e'], |
| 236 'command': ['echo', 'You should get an Atari'], |
| 237 }, |
| 238 }], |
| 239 ['OS=="amiga"', { |
| 240 'variables': { |
| 241 KEY_TRACKED: ['g'], |
| 242 'read_only': False, |
| 243 }, |
| 244 }], |
| 245 ['OS=="dendy"', { |
| 246 }], |
| 247 ['OS=="coleco"', { |
| 248 }, { # else |
| 249 'variables': { |
| 250 KEY_UNTRACKED: ['h'], |
| 251 'read_only': None, |
| 252 }, |
| 253 }], |
| 254 ], |
| 255 } |
| 256 expected = { |
| 257 'amiga': { |
| 258 'command': ['echo', 'You should get an Atari'], |
| 259 KEY_TOUCHED: ['touched', 'touched_e'], |
| 260 KEY_TRACKED: ['a', 'e', 'g', 'x'], |
| 261 KEY_UNTRACKED: ['b', 'f', 'h'], |
| 262 'read_only': False, |
| 263 }, |
| 264 'atari': { |
| 265 'command': ['echo', 'Hello World'], |
| 266 KEY_TOUCHED: ['touched', 'touched_a'], |
| 267 KEY_TRACKED: ['a', 'c', 'x'], |
| 268 KEY_UNTRACKED: ['b', 'd', 'h'], |
| 269 'read_only': True, |
| 270 }, |
| 271 'coleco': { |
| 272 'command': ['echo', 'You should get an Atari'], |
| 273 KEY_TOUCHED: ['touched', 'touched_e'], |
| 274 KEY_TRACKED: ['a', 'e', 'x'], |
| 275 KEY_UNTRACKED: ['b', 'f'], |
| 276 }, |
| 277 'dendy': { |
| 278 'command': ['echo', 'You should get an Atari'], |
| 279 KEY_TOUCHED: ['touched', 'touched_e'], |
| 280 KEY_TRACKED: ['a', 'e', 'x'], |
| 281 KEY_UNTRACKED: ['b', 'f', 'h'], |
| 282 }, |
| 283 } |
| 284 self.assertEquals( |
| 285 expected, isolate.load_isolate_as_config(value, None, []).flatten()) |
| 286 |
| 287 def test_load_isolate_as_config_duplicate_command(self): |
| 288 value = { |
| 289 'variables': { |
| 290 'command': ['rm', '-rf', '/'], |
| 291 }, |
| 292 'conditions': [ |
| 293 ['OS=="atari"', { |
| 294 'variables': { |
| 295 'command': ['echo', 'Hello World'], |
| 296 }, |
| 297 }], |
| 298 ], |
| 299 } |
| 300 try: |
| 301 isolate.load_isolate_as_config(value, None, []) |
| 302 self.fail() |
| 303 except AssertionError: |
| 304 pass |
| 305 |
| 306 def test_load_isolate_as_config_no_condition(self): |
| 307 value = { |
| 308 'variables': { |
| 309 KEY_TRACKED: ['a'], |
| 310 KEY_UNTRACKED: ['b'], |
| 311 }, |
| 312 } |
| 313 expected = { |
| 314 KEY_TRACKED: ['a'], |
| 315 KEY_UNTRACKED: ['b'], |
| 316 } |
| 317 actual = isolate.load_isolate_as_config(value, None, []) |
| 318 # Flattening the whole config will discard 'None'. |
| 319 self.assertEquals({}, actual.flatten()) |
| 320 self.assertEquals([None], actual.per_os.keys()) |
| 321 # But the 'None' value is still available as a backup. |
| 322 self.assertEquals(expected, actual.per_os[None].flatten()) |
| 323 |
| 324 def test_invert_map(self): |
| 325 value = { |
| 326 'amiga': { |
| 327 'command': ['echo', 'You should get an Atari'], |
| 328 KEY_TOUCHED: ['touched', 'touched_e'], |
| 329 KEY_TRACKED: ['a', 'e', 'g', 'x'], |
| 330 KEY_UNTRACKED: ['b', 'f', 'h'], |
| 331 'read_only': False, |
| 332 }, |
| 333 'atari': { |
| 334 'command': ['echo', 'Hello World'], |
| 335 KEY_TOUCHED: ['touched', 'touched_a'], |
| 336 KEY_TRACKED: ['a', 'c', 'x'], |
| 337 KEY_UNTRACKED: ['b', 'd', 'h'], |
| 338 'read_only': True, |
| 339 }, |
| 340 'coleco': { |
| 341 'command': ['echo', 'You should get an Atari'], |
| 342 KEY_TOUCHED: ['touched', 'touched_e'], |
| 343 KEY_TRACKED: ['a', 'e', 'x'], |
| 344 KEY_UNTRACKED: ['b', 'f'], |
| 345 }, |
| 346 'dendy': { |
| 347 'command': ['echo', 'You should get an Atari'], |
| 348 KEY_TOUCHED: ['touched', 'touched_e'], |
| 349 KEY_TRACKED: ['a', 'e', 'x'], |
| 350 KEY_UNTRACKED: ['b', 'f', 'h'], |
| 351 }, |
| 352 } |
| 353 expected_values = { |
| 354 'command': { |
| 355 ('echo', 'Hello World'): set(['atari']), |
| 356 ('echo', 'You should get an Atari'): set(['amiga', 'coleco', 'dendy']), |
| 357 }, |
| 358 KEY_TRACKED: { |
| 359 'a': set(['amiga', 'atari', 'coleco', 'dendy']), |
| 360 'c': set(['atari']), |
| 361 'e': set(['amiga', 'coleco', 'dendy']), |
| 362 'g': set(['amiga']), |
| 363 'x': set(['amiga', 'atari', 'coleco', 'dendy']), |
| 364 }, |
| 365 KEY_UNTRACKED: { |
| 366 'b': set(['amiga', 'atari', 'coleco', 'dendy']), |
| 367 'd': set(['atari']), |
| 368 'f': set(['amiga', 'coleco', 'dendy']), |
| 369 'h': set(['amiga', 'atari', 'dendy']), |
| 370 }, |
| 371 KEY_TOUCHED: { |
| 372 'touched': set(['amiga', 'atari', 'coleco', 'dendy']), |
| 373 'touched_a': set(['atari']), |
| 374 'touched_e': set(['amiga', 'coleco', 'dendy']), |
| 375 }, |
| 376 'read_only': { |
| 377 None: set(['coleco', 'dendy']), |
| 378 False: set(['amiga']), |
| 379 True: set(['atari']), |
| 380 }, |
| 381 } |
| 382 expected_oses = set(['amiga', 'atari', 'coleco', 'dendy']) |
| 383 actual_values, actual_oses = isolate.invert_map(value) |
| 384 self.assertEquals(expected_values, actual_values) |
| 385 self.assertEquals(expected_oses, actual_oses) |
| 386 |
| 387 def test_reduce_inputs(self): |
| 388 values = { |
| 389 'command': { |
| 390 ('echo', 'Hello World'): set(['atari']), |
| 391 ('echo', 'You should get an Atari'): set(['amiga', 'coleco', 'dendy']), |
| 392 }, |
| 393 KEY_TRACKED: { |
| 394 'a': set(['amiga', 'atari', 'coleco', 'dendy']), |
| 395 'c': set(['atari']), |
| 396 'e': set(['amiga', 'coleco', 'dendy']), |
| 397 'g': set(['amiga']), |
| 398 'x': set(['amiga', 'atari', 'coleco', 'dendy']), |
| 399 }, |
| 400 KEY_UNTRACKED: { |
| 401 'b': set(['amiga', 'atari', 'coleco', 'dendy']), |
| 402 'd': set(['atari']), |
| 403 'f': set(['amiga', 'coleco', 'dendy']), |
| 404 'h': set(['amiga', 'atari', 'dendy']), |
| 405 }, |
| 406 KEY_TOUCHED: { |
| 407 'touched': set(['amiga', 'atari', 'coleco', 'dendy']), |
| 408 'touched_a': set(['atari']), |
| 409 'touched_e': set(['amiga', 'coleco', 'dendy']), |
| 410 }, |
| 411 'read_only': { |
| 412 None: set(['coleco', 'dendy']), |
| 413 False: set(['amiga']), |
| 414 True: set(['atari']), |
| 415 }, |
| 416 } |
| 417 oses = set(['amiga', 'atari', 'coleco', 'dendy']) |
| 418 expected_values = { |
| 419 'command': { |
| 420 ('echo', 'Hello World'): set(['atari']), |
| 421 ('echo', 'You should get an Atari'): set(['!atari']), |
| 422 }, |
| 423 KEY_TRACKED: { |
| 424 'a': set([None]), |
| 425 'c': set(['atari']), |
| 426 'e': set(['!atari']), |
| 427 'g': set(['amiga']), |
| 428 'x': set([None]), |
| 429 }, |
| 430 KEY_UNTRACKED: { |
| 431 'b': set([None]), |
| 432 'd': set(['atari']), |
| 433 'f': set(['!atari']), |
| 434 'h': set(['!coleco']), |
| 435 }, |
| 436 KEY_TOUCHED: { |
| 437 'touched': set([None]), |
| 438 'touched_a': set(['atari']), |
| 439 'touched_e': set(['!atari']), |
| 440 }, |
| 441 'read_only': { |
| 442 None: set(['coleco', 'dendy']), |
| 443 False: set(['amiga']), |
| 444 True: set(['atari']), |
| 445 }, |
| 446 } |
| 447 actual_values, actual_oses = isolate.reduce_inputs(values, oses) |
| 448 self.assertEquals(expected_values, actual_values) |
| 449 self.assertEquals(oses, actual_oses) |
| 450 |
| 451 def test_reduce_inputs_take_strongest_dependency(self): |
| 452 values = { |
| 453 'command': { |
| 454 ('echo', 'Hello World'): set(['atari']), |
| 455 ('echo', 'You should get an Atari'): set(['amiga', 'coleco', 'dendy']), |
| 456 }, |
| 457 KEY_TRACKED: { |
| 458 'a': set(['amiga', 'atari', 'coleco', 'dendy']), |
| 459 'b': set(['amiga', 'atari', 'coleco']), |
| 460 }, |
| 461 KEY_UNTRACKED: { |
| 462 'c': set(['amiga', 'atari', 'coleco', 'dendy']), |
| 463 'd': set(['amiga', 'coleco', 'dendy']), |
| 464 }, |
| 465 KEY_TOUCHED: { |
| 466 'a': set(['amiga', 'atari', 'coleco', 'dendy']), |
| 467 'b': set(['atari', 'coleco', 'dendy']), |
| 468 'c': set(['amiga', 'atari', 'coleco', 'dendy']), |
| 469 'd': set(['atari', 'coleco', 'dendy']), |
| 470 }, |
| 471 } |
| 472 oses = set(['amiga', 'atari', 'coleco', 'dendy']) |
| 473 expected_values = { |
| 474 'command': { |
| 475 ('echo', 'Hello World'): set(['atari']), |
| 476 ('echo', 'You should get an Atari'): set(['!atari']), |
| 477 }, |
| 478 KEY_TRACKED: { |
| 479 'a': set([None]), |
| 480 'b': set(['!dendy']), |
| 481 }, |
| 482 KEY_UNTRACKED: { |
| 483 'c': set([None]), |
| 484 'd': set(['!atari']), |
| 485 }, |
| 486 KEY_TOUCHED: { |
| 487 'b': set(['dendy']), |
| 488 'd': set(['atari']), |
| 489 }, |
| 490 'read_only': {}, |
| 491 } |
| 492 actual_values, actual_oses = isolate.reduce_inputs(values, oses) |
| 493 self.assertEquals(expected_values, actual_values) |
| 494 self.assertEquals(oses, actual_oses) |
| 495 |
| 496 def test_convert_map_to_isolate_dict(self): |
| 497 values = { |
| 498 'command': { |
| 499 ('echo', 'Hello World'): set(['atari']), |
| 500 ('echo', 'You should get an Atari'): set(['!atari']), |
| 501 }, |
| 502 KEY_TRACKED: { |
| 503 'a': set([None]), |
| 504 'c': set(['atari']), |
| 505 'e': set(['!atari']), |
| 506 'g': set(['amiga']), |
| 507 'x': set([None]), |
| 508 }, |
| 509 KEY_UNTRACKED: { |
| 510 'b': set([None]), |
| 511 'd': set(['atari']), |
| 512 'f': set(['!atari']), |
| 513 'h': set(['!coleco']), |
| 514 }, |
| 515 KEY_TOUCHED: { |
| 516 'touched': set([None]), |
| 517 'touched_a': set(['atari']), |
| 518 'touched_e': set(['!atari']), |
| 519 }, |
| 520 'read_only': { |
| 521 None: set(['coleco', 'dendy']), |
| 522 False: set(['amiga']), |
| 523 True: set(['atari']), |
| 524 }, |
| 525 } |
| 526 oses = set(['amiga', 'atari', 'coleco', 'dendy']) |
| 527 expected = { |
| 528 'variables': { |
| 529 KEY_TRACKED: ['a', 'x'], |
| 530 KEY_UNTRACKED: ['b'], |
| 531 KEY_TOUCHED: ['touched'], |
| 532 }, |
| 533 'conditions': [ |
| 534 ['OS=="amiga"', { |
| 535 'variables': { |
| 536 KEY_TRACKED: ['g'], |
| 537 'read_only': False, |
| 538 }, |
| 539 }], |
| 540 ['OS=="atari"', { |
| 541 'variables': { |
| 542 'command': ['echo', 'Hello World'], |
| 543 KEY_TRACKED: ['c'], |
| 544 KEY_UNTRACKED: ['d'], |
| 545 KEY_TOUCHED: ['touched_a'], |
| 546 'read_only': True, |
| 547 }, |
| 548 }, { |
| 549 'variables': { |
| 550 'command': ['echo', 'You should get an Atari'], |
| 551 KEY_TRACKED: ['e'], |
| 552 KEY_UNTRACKED: ['f'], |
| 553 KEY_TOUCHED: ['touched_e'], |
| 554 }, |
| 555 }], |
| 556 ['OS=="coleco"', { |
| 557 }, { |
| 558 'variables': { |
| 559 KEY_UNTRACKED: ['h'], |
| 560 }, |
| 561 }], |
| 562 ], |
| 563 } |
| 564 self.assertEquals( |
| 565 expected, isolate.convert_map_to_isolate_dict(values, oses)) |
| 566 |
| 567 def test_merge_two_empty(self): |
| 568 # Flat stay flat. Pylint is confused about union() return type. |
| 569 # pylint: disable=E1103 |
| 570 actual = isolate.union( |
| 571 isolate.union( |
| 572 isolate.Configs([], None), |
| 573 isolate.load_isolate_as_config({}, None, [])), |
| 574 isolate.load_isolate_as_config({}, None, [])).flatten() |
| 575 self.assertEquals({}, actual) |
| 576 |
| 577 def test_merge_empty(self): |
| 578 actual = isolate.convert_map_to_isolate_dict( |
| 579 *isolate.reduce_inputs(*isolate.invert_map({}))) |
| 580 self.assertEquals({}, actual) |
| 581 |
| 582 def test_load_two_conditions(self): |
| 583 linux = { |
| 584 'conditions': [ |
| 585 ['OS=="linux"', { |
| 586 'variables': { |
| 587 'isolate_dependency_tracked': [ |
| 588 'file_linux', |
| 589 'file_common', |
| 590 ], |
| 591 }, |
| 592 }], |
| 593 ], |
| 594 } |
| 595 mac = { |
| 596 'conditions': [ |
| 597 ['OS=="mac"', { |
| 598 'variables': { |
| 599 'isolate_dependency_tracked': [ |
| 600 'file_mac', |
| 601 'file_common', |
| 602 ], |
| 603 }, |
| 604 }], |
| 605 ], |
| 606 } |
| 607 expected = { |
| 608 'linux': { |
| 609 'isolate_dependency_tracked': ['file_common', 'file_linux'], |
| 610 }, |
| 611 'mac': { |
| 612 'isolate_dependency_tracked': ['file_common', 'file_mac'], |
| 613 }, |
| 614 } |
| 615 # Pylint is confused about union() return type. |
| 616 # pylint: disable=E1103 |
| 617 configs = isolate.union( |
| 618 isolate.union( |
| 619 isolate.Configs([], None), |
| 620 isolate.load_isolate_as_config(linux, None, [])), |
| 621 isolate.load_isolate_as_config(mac, None, [])).flatten() |
| 622 self.assertEquals(expected, configs) |
| 623 |
| 624 def test_load_three_conditions(self): |
| 625 linux = { |
| 626 'conditions': [ |
| 627 ['OS=="linux"', { |
| 628 'variables': { |
| 629 'isolate_dependency_tracked': [ |
| 630 'file_linux', |
| 631 'file_common', |
| 632 ], |
| 633 }, |
| 634 }], |
| 635 ], |
| 636 } |
| 637 mac = { |
| 638 'conditions': [ |
| 639 ['OS=="mac"', { |
| 640 'variables': { |
| 641 'isolate_dependency_tracked': [ |
| 642 'file_mac', |
| 643 'file_common', |
| 644 ], |
| 645 }, |
| 646 }], |
| 647 ], |
| 648 } |
| 649 win = { |
| 650 'conditions': [ |
| 651 ['OS=="win"', { |
| 652 'variables': { |
| 653 'isolate_dependency_tracked': [ |
| 654 'file_win', |
| 655 'file_common', |
| 656 ], |
| 657 }, |
| 658 }], |
| 659 ], |
| 660 } |
| 661 expected = { |
| 662 'linux': { |
| 663 'isolate_dependency_tracked': ['file_common', 'file_linux'], |
| 664 }, |
| 665 'mac': { |
| 666 'isolate_dependency_tracked': ['file_common', 'file_mac'], |
| 667 }, |
| 668 'win': { |
| 669 'isolate_dependency_tracked': ['file_common', 'file_win'], |
| 670 }, |
| 671 } |
| 672 # Pylint is confused about union() return type. |
| 673 # pylint: disable=E1103 |
| 674 configs = isolate.union( |
| 675 isolate.union( |
| 676 isolate.union( |
| 677 isolate.Configs([], None), |
| 678 isolate.load_isolate_as_config(linux, None, [])), |
| 679 isolate.load_isolate_as_config(mac, None, [])), |
| 680 isolate.load_isolate_as_config(win, None, [])).flatten() |
| 681 self.assertEquals(expected, configs) |
| 682 |
| 683 def test_merge_three_conditions(self): |
| 684 values = { |
| 685 'linux': { |
| 686 'isolate_dependency_tracked': ['file_common', 'file_linux'], |
| 687 }, |
| 688 'mac': { |
| 689 'isolate_dependency_tracked': ['file_common', 'file_mac'], |
| 690 }, |
| 691 'win': { |
| 692 'isolate_dependency_tracked': ['file_common', 'file_win'], |
| 693 }, |
| 694 } |
| 695 expected = { |
| 696 'variables': { |
| 697 'isolate_dependency_tracked': [ |
| 698 'file_common', |
| 699 ], |
| 700 }, |
| 701 'conditions': [ |
| 702 ['OS=="linux"', { |
| 703 'variables': { |
| 704 'isolate_dependency_tracked': [ |
| 705 'file_linux', |
| 706 ], |
| 707 }, |
| 708 }], |
| 709 ['OS=="mac"', { |
| 710 'variables': { |
| 711 'isolate_dependency_tracked': [ |
| 712 'file_mac', |
| 713 ], |
| 714 }, |
| 715 }], |
| 716 ['OS=="win"', { |
| 717 'variables': { |
| 718 'isolate_dependency_tracked': [ |
| 719 'file_win', |
| 720 ], |
| 721 }, |
| 722 }], |
| 723 ], |
| 724 } |
| 725 actual = isolate.convert_map_to_isolate_dict( |
| 726 *isolate.reduce_inputs(*isolate.invert_map(values))) |
| 727 self.assertEquals(expected, actual) |
| 728 |
| 729 def test_configs_comment(self): |
| 730 # Pylint is confused with isolate.union() return type. |
| 731 # pylint: disable=E1103 |
| 732 configs = isolate.union( |
| 733 isolate.load_isolate_as_config({}, '# Yo dawg!\n# Chill out.\n', []), |
| 734 isolate.load_isolate_as_config({}, None, [])) |
| 735 self.assertEquals('# Yo dawg!\n# Chill out.\n', configs.file_comment) |
| 736 |
| 737 configs = isolate.union( |
| 738 isolate.load_isolate_as_config({}, None, []), |
| 739 isolate.load_isolate_as_config({}, '# Yo dawg!\n# Chill out.\n', [])) |
| 740 self.assertEquals('# Yo dawg!\n# Chill out.\n', configs.file_comment) |
| 741 |
| 742 # Only keep the first one. |
| 743 configs = isolate.union( |
| 744 isolate.load_isolate_as_config({}, '# Yo dawg!\n', []), |
| 745 isolate.load_isolate_as_config({}, '# Chill out.\n', [])) |
| 746 self.assertEquals('# Yo dawg!\n', configs.file_comment) |
| 747 |
| 748 def test_extract_comment(self): |
| 749 self.assertEquals( |
| 750 '# Foo\n# Bar\n', isolate.extract_comment('# Foo\n# Bar\n{}')) |
| 751 self.assertEquals('', isolate.extract_comment('{}')) |
| 752 |
| 753 def _test_pretty_print_impl(self, value, expected): |
| 754 actual = cStringIO.StringIO() |
| 755 isolate.pretty_print(value, actual) |
| 756 self.assertEquals(expected, actual.getvalue()) |
| 757 |
| 758 def test_pretty_print_empty(self): |
| 759 self._test_pretty_print_impl({}, '{\n}\n') |
| 760 |
| 761 def test_pretty_print_mid_size(self): |
| 762 value = { |
| 763 'variables': { |
| 764 'bar': [ |
| 765 'file1', |
| 766 'file2', |
| 767 ], |
| 768 }, |
| 769 'conditions': [ |
| 770 ['OS=\"foo\"', { |
| 771 'variables': { |
| 772 isolate.KEY_UNTRACKED: [ |
| 773 'dir1', |
| 774 'dir2', |
| 775 ], |
| 776 isolate.KEY_TRACKED: [ |
| 777 'file4', |
| 778 'file3', |
| 779 ], |
| 780 'command': ['python', '-c', 'print "H\\i\'"'], |
| 781 'read_only': True, |
| 782 'relative_cwd': 'isol\'at\\e', |
| 783 }, |
| 784 }], |
| 785 ['OS=\"bar\"', { |
| 786 'variables': {}, |
| 787 }, { |
| 788 'variables': {}, |
| 789 }], |
| 790 ], |
| 791 } |
| 792 expected = ( |
| 793 "{\n" |
| 794 " 'variables': {\n" |
| 795 " 'bar': [\n" |
| 796 " 'file1',\n" |
| 797 " 'file2',\n" |
| 798 " ],\n" |
| 799 " },\n" |
| 800 " 'conditions': [\n" |
| 801 " ['OS=\"foo\"', {\n" |
| 802 " 'variables': {\n" |
| 803 " 'command': [\n" |
| 804 " 'python',\n" |
| 805 " '-c',\n" |
| 806 " 'print \"H\\i\'\"',\n" |
| 807 " ],\n" |
| 808 " 'relative_cwd': 'isol\\'at\\\\e',\n" |
| 809 " 'read_only': True\n" |
| 810 " 'isolate_dependency_tracked': [\n" |
| 811 " 'file4',\n" |
| 812 " 'file3',\n" |
| 813 " ],\n" |
| 814 " 'isolate_dependency_untracked': [\n" |
| 815 " 'dir1',\n" |
| 816 " 'dir2',\n" |
| 817 " ],\n" |
| 818 " },\n" |
| 819 " }],\n" |
| 820 " ['OS=\"bar\"', {\n" |
| 821 " 'variables': {\n" |
| 822 " },\n" |
| 823 " }, {\n" |
| 824 " 'variables': {\n" |
| 825 " },\n" |
| 826 " }],\n" |
| 827 " ],\n" |
| 828 "}\n") |
| 829 self._test_pretty_print_impl(value, expected) |
| 830 |
| 831 |
| 832 if __name__ == '__main__': |
| 833 logging.basicConfig( |
| 834 level=logging.DEBUG if '-v' in sys.argv else logging.ERROR, |
| 835 format='%(levelname)5s %(filename)15s(%(lineno)3d): %(message)s') |
| 836 unittest.main() |
OLD | NEW |