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 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 424 self._test_data.step_data.keys(), | 424 self._test_data.step_data.keys(), |
| 425 self._test_data.expected_exception)) | 425 self._test_data.expected_exception)) |
| 426 | 426 |
| 427 @property | 427 @property |
| 428 def steps_ran(self): | 428 def steps_ran(self): |
| 429 return self._step_history.values() | 429 return self._step_history.values() |
| 430 | 430 |
| 431 | 431 |
| 432 # Result of 'render_step'. | 432 # Result of 'render_step'. |
| 433 Placeholders = collections.namedtuple( | 433 Placeholders = collections.namedtuple( |
| 434 'Placeholders', ['cmd', 'stdout', 'stderr', 'stdin']) | 434 'Placeholders', ['inputs_cmd', 'outputs_cmd', 'stdout', 'stderr', 'stdin']) |
| 435 | 435 |
| 436 | 436 |
| 437 def render_step(step, step_test): | 437 def render_step(step, step_test): |
| 438 """Renders a step so that it can be fed to annotator.py. | 438 """Renders a step so that it can be fed to annotator.py. |
| 439 | 439 |
| 440 Args: | 440 Args: |
| 441 step: The step to render. | 441 step: The step to render. |
| 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 placeholders = 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 new_cmd = [] | 453 new_cmd = [] |
| 453 for item in step.get('cmd', []): | 454 for item in step.get('cmd', []): |
| 454 if isinstance(item, util.Placeholder): | 455 if isinstance(item, util.Placeholder): |
| 455 module_name, placeholder_name = item.name_pieces | 456 module_name, placeholder_name = item.name_pieces |
| 456 tdata = step_test.pop_placeholder(item.name_pieces) | 457 if isinstance(item, util.InputPlaceholder): |
| 458 tdata = step_test.pop_input_placeholder(item.name_pieces) | |
|
iannucci
2016/03/12 03:36:12
not needed: inputs are never mocked
stgao
2016/03/22 05:56:43
Reverted to the old approach.
We still need a def
| |
| 459 input_phs[module_name][placeholder_name].append((item, tdata)) | |
| 460 else: | |
| 461 assert isinstance(item, util.OutputPlaceholder), ( | |
| 462 'Not an OutputPlaceholder: %r' % item) | |
| 463 tdata = step_test.pop_output_placeholder(item.name_pieces) | |
| 464 output_phs[module_name][placeholder_name].append((item, tdata)) | |
| 457 new_cmd.extend(item.render(tdata)) | 465 new_cmd.extend(item.render(tdata)) |
| 458 placeholders[module_name][placeholder_name].append((item, tdata)) | |
| 459 else: | 466 else: |
| 460 new_cmd.append(item) | 467 new_cmd.append(item) |
| 461 rendered_step['cmd'] = new_cmd | 468 rendered_step['cmd'] = new_cmd |
| 462 | 469 |
| 463 # Process 'stdout', 'stderr' and 'stdin' placeholders, if given. | 470 # Process 'stdout', 'stderr' and 'stdin' placeholders, if given. |
| 464 stdio_placeholders = {} | 471 stdio_placeholders = {} |
| 465 for key in ('stdout', 'stderr', 'stdin'): | 472 for key in ('stdout', 'stderr', 'stdin'): |
| 466 placeholder = step.get(key) | 473 placeholder = step.get(key) |
| 467 tdata = None | 474 tdata = None |
| 468 if placeholder: | 475 if placeholder: |
| 469 assert isinstance(placeholder, util.Placeholder), key | 476 if key == 'stdin': |
| 477 assert isinstance(placeholder, util.InputPlaceholder), key | |
| 478 else: | |
| 479 assert isinstance(placeholder, util.OutputPlaceholder), key | |
| 470 tdata = getattr(step_test, key) | 480 tdata = getattr(step_test, key) |
| 471 placeholder.render(tdata) | 481 placeholder.render(tdata) |
| 472 assert placeholder.backing_file | 482 assert placeholder.backing_file |
| 473 rendered_step[key] = placeholder.backing_file | 483 rendered_step[key] = placeholder.backing_file |
| 474 stdio_placeholders[key] = (placeholder, tdata) | 484 stdio_placeholders[key] = (placeholder, tdata) |
| 475 | 485 |
| 476 return rendered_step, Placeholders(cmd=placeholders, **stdio_placeholders) | 486 return rendered_step, Placeholders( |
| 487 inputs_cmd=input_phs, outputs_cmd=output_phs, **stdio_placeholders) | |
| 477 | 488 |
| 478 | 489 |
| 479 def construct_step_result(step, retcode, placeholders): | 490 def construct_step_result(step, retcode, placeholders): |
| 480 """Constructs a StepData step result from step return data. | 491 """Constructs a StepData step result from step return data. |
| 481 | 492 |
| 482 The main purpose of this function is to add placeholder results into the | 493 The main purpose of this function is to add output placeholder results into |
| 483 step result where placeholders appeared in the input step. | 494 the step result where output placeholders appeared in the input step. |
| 495 Also give input placeholders the chance to do the clean-up if needed. | |
| 484 """ | 496 """ |
| 485 | 497 |
| 486 step_result = types.StepData(step, retcode) | 498 step_result = types.StepData(step, retcode) |
| 487 | 499 |
| 488 class BlankObject(object): | 500 class BlankObject(object): |
| 489 pass | 501 pass |
| 490 | 502 |
| 491 # Placeholders inside step |cmd|. | 503 # Input placeholders inside step |cmd|. |
| 492 for module_name, pholders in placeholders.cmd.iteritems(): | 504 for _, pholders in placeholders.inputs_cmd.iteritems(): |
| 505 for _, items in pholders.iteritems(): | |
| 506 for ph, td in items: | |
| 507 ph.result(step_result.presentation, td) | |
| 508 | |
| 509 # Output placeholders inside step |cmd|. | |
| 510 for module_name, pholders in placeholders.outputs_cmd.iteritems(): | |
| 493 assert not hasattr(step_result, module_name) | 511 assert not hasattr(step_result, module_name) |
| 494 o = BlankObject() | 512 o = BlankObject() |
| 495 setattr(step_result, module_name, o) | 513 setattr(step_result, module_name, o) |
| 496 | 514 |
| 497 for placeholder_name, items in pholders.iteritems(): | 515 for placeholder_name, items in pholders.iteritems(): |
| 498 lst = [ph.result(step_result.presentation, td) for ph, td in items] | 516 lst = [ph.result(step_result.presentation, td) for ph, td in items] |
| 499 setattr(o, placeholder_name+"_all", lst) | 517 setattr(o, placeholder_name+"_all", lst) |
| 500 setattr(o, placeholder_name, lst[0]) | 518 setattr(o, placeholder_name, lst[0]) |
| 501 | 519 |
| 502 # Placeholders that are used with IO redirection. | 520 # Placeholders that are used with IO redirection. |
| 503 for key in ('stdout', 'stderr', 'stdin'): | 521 for key in ('stdout', 'stderr', 'stdin'): |
| 504 assert not hasattr(step_result, key) | 522 assert not hasattr(step_result, key) |
| 505 ph, td = getattr(placeholders, key) | 523 ph, td = getattr(placeholders, key) |
| 506 result = ph.result(step_result.presentation, td) if ph else None | 524 result = ph.result(step_result.presentation, td) if ph else None |
| 507 setattr(step_result, key, result) | 525 if key != 'stdin': |
|
iannucci
2016/03/12 03:36:12
this looks wrong to me...? Not sure what this is s
stgao
2016/03/22 05:56:43
Reverted.
However, I thought we don't want to inc
| |
| 526 setattr(step_result, key, result) | |
| 508 | 527 |
| 509 return step_result | 528 return step_result |
| 510 | 529 |
| 511 | 530 |
| 512 def _merge_envs(original, override): | 531 def _merge_envs(original, override): |
| 513 """Merges two environments. | 532 """Merges two environments. |
| 514 | 533 |
| 515 Returns a new environment dict with entries from |override| overwriting | 534 Returns a new environment dict with entries from |override| overwriting |
| 516 corresponding entries in |original|. Keys whose value is None will completely | 535 corresponding entries in |original|. Keys whose value is None will completely |
| 517 remove the environment variable. Values can contain %(KEY)s strings, which | 536 remove the environment variable. Values can contain %(KEY)s strings, which |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 558 supplied command, and only uses the |env| kwarg for modifying the environment | 577 supplied command, and only uses the |env| kwarg for modifying the environment |
| 559 of the child process. | 578 of the child process. |
| 560 """ | 579 """ |
| 561 saved_path = os.environ['PATH'] | 580 saved_path = os.environ['PATH'] |
| 562 try: | 581 try: |
| 563 if path is not None: | 582 if path is not None: |
| 564 os.environ['PATH'] = path | 583 os.environ['PATH'] = path |
| 565 yield | 584 yield |
| 566 finally: | 585 finally: |
| 567 os.environ['PATH'] = saved_path | 586 os.environ['PATH'] = saved_path |
| OLD | NEW |