Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2013-2015 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2013-2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import cStringIO | 5 import cStringIO |
| 6 import collections | 6 import collections |
| 7 import contextlib | 7 import contextlib |
| 8 import datetime | 8 import datetime |
| 9 import json | 9 import json |
| 10 import os | 10 import os |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 442 step_test: The test data json dictionary for this step, if any. | 442 step_test: The test data json dictionary for this step, if any. |
| 443 Passed through unaltered to each placeholder. | 443 Passed through unaltered to each placeholder. |
| 444 | 444 |
| 445 Returns the rendered step and a Placeholders object representing any | 445 Returns the rendered step and a Placeholders object representing any |
| 446 placeholder instances that were found while rendering. | 446 placeholder instances that were found while rendering. |
| 447 """ | 447 """ |
| 448 rendered_step = dict(step) | 448 rendered_step = dict(step) |
| 449 | 449 |
| 450 # Process 'cmd', rendering placeholders there. | 450 # Process 'cmd', rendering placeholders there. |
| 451 input_phs = collections.defaultdict(lambda: collections.defaultdict(list)) | 451 input_phs = collections.defaultdict(lambda: collections.defaultdict(list)) |
| 452 output_phs = collections.defaultdict(lambda: collections.defaultdict(list)) | 452 output_phs = collections.defaultdict( |
| 453 lambda: collections.defaultdict(collections.OrderedDict)) | |
| 453 new_cmd = [] | 454 new_cmd = [] |
| 454 for item in step.get('cmd', []): | 455 for item in step.get('cmd', []): |
| 455 if isinstance(item, util.Placeholder): | 456 if isinstance(item, util.Placeholder): |
| 456 module_name, placeholder_name = item.name_pieces | 457 module_name, placeholder_name = item.namespaces |
| 457 tdata = step_test.pop_placeholder(item.name_pieces) | 458 tdata = step_test.pop_placeholder( |
| 459 module_name, placeholder_name, item.name) | |
| 458 new_cmd.extend(item.render(tdata)) | 460 new_cmd.extend(item.render(tdata)) |
| 459 if isinstance(item, util.InputPlaceholder): | 461 if isinstance(item, util.InputPlaceholder): |
| 460 input_phs[module_name][placeholder_name].append((item, tdata)) | 462 input_phs[module_name][placeholder_name].append((item, tdata)) |
| 461 else: | 463 else: |
| 462 assert isinstance(item, util.OutputPlaceholder), ( | 464 assert isinstance(item, util.OutputPlaceholder), ( |
| 463 'Not an OutputPlaceholder: %r' % item) | 465 'Not an OutputPlaceholder: %r' % item) |
| 464 output_phs[module_name][placeholder_name].append((item, tdata)) | 466 # This assert also ensures at most one placeholder has the default name. |
|
iannucci
2016/03/22 22:54:24
well, it also asserts (correctly) that you don't h
stgao
2016/03/22 23:40:25
Yes. Updated.
| |
| 467 assert item.name not in output_phs[module_name][placeholder_name], ( | |
| 468 'Step "%s" has multiple output placeholders of %s.%s. Please ' | |
| 469 'specify explicit and different names for them.' % ( | |
| 470 step['name'], module_name, placeholder_name)) | |
| 471 output_phs[module_name][placeholder_name][item.name] = (item, tdata) | |
| 465 else: | 472 else: |
| 466 new_cmd.append(item) | 473 new_cmd.append(item) |
| 467 rendered_step['cmd'] = new_cmd | 474 rendered_step['cmd'] = new_cmd |
| 468 | 475 |
| 469 # Process 'stdout', 'stderr' and 'stdin' placeholders, if given. | 476 # Process 'stdout', 'stderr' and 'stdin' placeholders, if given. |
| 470 stdio_placeholders = {} | 477 stdio_placeholders = {} |
| 471 for key in ('stdout', 'stderr', 'stdin'): | 478 for key in ('stdout', 'stderr', 'stdin'): |
| 472 placeholder = step.get(key) | 479 placeholder = step.get(key) |
| 473 tdata = None | 480 tdata = None |
| 474 if placeholder: | 481 if placeholder: |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 504 for _, items in pholders.iteritems(): | 511 for _, items in pholders.iteritems(): |
| 505 for ph, td in items: | 512 for ph, td in items: |
| 506 ph.result(step_result.presentation, td) | 513 ph.result(step_result.presentation, td) |
| 507 | 514 |
| 508 # Output placeholders inside step |cmd|. | 515 # Output placeholders inside step |cmd|. |
| 509 for module_name, pholders in placeholders.outputs_cmd.iteritems(): | 516 for module_name, pholders in placeholders.outputs_cmd.iteritems(): |
| 510 assert not hasattr(step_result, module_name) | 517 assert not hasattr(step_result, module_name) |
| 511 o = BlankObject() | 518 o = BlankObject() |
| 512 setattr(step_result, module_name, o) | 519 setattr(step_result, module_name, o) |
| 513 | 520 |
| 514 for placeholder_name, items in pholders.iteritems(): | 521 for placeholder_name, instances in pholders.iteritems(): |
| 515 lst = [ph.result(step_result.presentation, td) for ph, td in items] | 522 named_results = {} |
| 516 setattr(o, placeholder_name+"_all", lst) | 523 default_result = None |
| 517 setattr(o, placeholder_name, lst[0]) | 524 for _, (ph, td) in instances.iteritems(): |
| 525 result = ph.result(step_result.presentation, td) | |
| 526 if ph.name is None: | |
| 527 default_result = result | |
| 528 else: | |
| 529 named_results[ph.name] = result | |
| 530 setattr(o, placeholder_name + "s", named_results) | |
| 531 | |
| 532 if default_result is None and len(named_results) == 1: | |
| 533 # Only 1 output placeholder with an explicit name. | |
| 534 default_result = named_results.values()[0] | |
| 535 setattr(o, placeholder_name, default_result) | |
|
iannucci
2016/03/22 22:54:24
what if there's two placeholders with names, and n
stgao
2016/03/22 23:40:25
Then the default output is set to None, per our di
| |
| 518 | 536 |
| 519 # Placeholders that are used with IO redirection. | 537 # Placeholders that are used with IO redirection. |
| 520 for key in ('stdout', 'stderr', 'stdin'): | 538 for key in ('stdout', 'stderr', 'stdin'): |
| 521 assert not hasattr(step_result, key) | 539 assert not hasattr(step_result, key) |
| 522 ph, td = getattr(placeholders, key) | 540 ph, td = getattr(placeholders, key) |
| 523 result = ph.result(step_result.presentation, td) if ph else None | 541 result = ph.result(step_result.presentation, td) if ph else None |
| 524 setattr(step_result, key, result) | 542 if key != 'stdin': |
| 543 setattr(step_result, key, result) | |
| 525 | 544 |
| 526 return step_result | 545 return step_result |
| 527 | 546 |
| 528 | 547 |
| 529 def _merge_envs(original, override): | 548 def _merge_envs(original, override): |
| 530 """Merges two environments. | 549 """Merges two environments. |
| 531 | 550 |
| 532 Returns a new environment dict with entries from |override| overwriting | 551 Returns a new environment dict with entries from |override| overwriting |
| 533 corresponding entries in |original|. Keys whose value is None will completely | 552 corresponding entries in |original|. Keys whose value is None will completely |
| 534 remove the environment variable. Values can contain %(KEY)s strings, which | 553 remove the environment variable. Values can contain %(KEY)s strings, which |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 575 supplied command, and only uses the |env| kwarg for modifying the environment | 594 supplied command, and only uses the |env| kwarg for modifying the environment |
| 576 of the child process. | 595 of the child process. |
| 577 """ | 596 """ |
| 578 saved_path = os.environ['PATH'] | 597 saved_path = os.environ['PATH'] |
| 579 try: | 598 try: |
| 580 if path is not None: | 599 if path is not None: |
| 581 os.environ['PATH'] = path | 600 os.environ['PATH'] = path |
| 582 yield | 601 yield |
| 583 finally: | 602 finally: |
| 584 os.environ['PATH'] = saved_path | 603 os.environ['PATH'] = saved_path |
| OLD | NEW |