Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2016 The LUCI Authors. All rights reserved. | 1 # Copyright 2016 The LUCI Authors. All rights reserved. |
| 2 # Use of this source code is governed under the Apache License, Version 2.0 | 2 # Use of this source code is governed under the Apache License, Version 2.0 |
| 3 # that can be found in the LICENSE file. | 3 # that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import calendar | 5 import calendar |
| 6 import collections | 6 import collections |
| 7 import contextlib | 7 import contextlib |
| 8 import datetime | 8 import datetime |
| 9 import itertools | 9 import itertools |
| 10 import json | 10 import json |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 399 | 399 |
| 400 # Convert when_timestamp to UNIX timestamp. | 400 # Convert when_timestamp to UNIX timestamp. |
| 401 when = change.get('when_timestamp') | 401 when = change.get('when_timestamp') |
| 402 if isinstance(when, datetime.datetime): | 402 if isinstance(when, datetime.datetime): |
| 403 when = calendar.timegm(when.utctimetuple()) | 403 when = calendar.timegm(when.utctimetuple()) |
| 404 change['when_timestamp'] = when | 404 change['when_timestamp'] = when |
| 405 | 405 |
| 406 return change | 406 return change |
| 407 | 407 |
| 408 | 408 |
| 409 class fakeEnviron(object): | |
|
nodir
2017/05/31 21:49:03
when reading this without context, it is hard to u
| |
| 410 def __init__(self): | |
| 411 self.data = {} | |
| 412 | |
| 413 def __getitem__(self, key): | |
| 414 return '<%s>' % key | |
| 415 | |
| 416 def __delitem__(self, key): | |
| 417 self.data[key] = None | |
| 418 | |
| 419 def __contains__(self, key): | |
| 420 return True | |
| 421 | |
| 422 def __setitem__(self, key, value): | |
| 423 self.data[key] = value | |
| 424 | |
| 425 def copy(self): | |
| 426 return self | |
| 427 | |
| 428 | |
| 409 class SimulationStepRunner(StepRunner): | 429 class SimulationStepRunner(StepRunner): |
| 410 """Pretends to run steps, instead recording what would have been run. | 430 """Pretends to run steps, instead recording what would have been run. |
| 411 | 431 |
| 412 This is the main workhorse of recipes.py simulation_test. Returns the log of | 432 This is the main workhorse of recipes.py simulation_test. Returns the log of |
| 413 steps that would have been run in steps_ran. Uses test_data to mock return | 433 steps that would have been run in steps_ran. Uses test_data to mock return |
| 414 values. | 434 values. |
| 415 """ | 435 """ |
| 416 | 436 |
| 417 def __init__(self, stream_engine, test_data, annotator): | 437 def __init__(self, stream_engine, test_data, annotator): |
| 418 self._test_data = test_data | 438 self._test_data = test_data |
| 419 self._stream_engine = stream_engine | 439 self._stream_engine = stream_engine |
| 420 self._annotator = annotator | 440 self._annotator = annotator |
| 421 self._step_history = collections.OrderedDict() | 441 self._step_history = collections.OrderedDict() |
| 422 | 442 |
| 423 @property | 443 @property |
| 424 def stream_engine(self): | 444 def stream_engine(self): |
| 425 return self._stream_engine | 445 return self._stream_engine |
| 426 | 446 |
| 427 def open_step(self, step_config): | 447 def open_step(self, step_config): |
| 428 try: | 448 try: |
| 429 test_data_fn = step_config.step_test_data or recipe_test_api.StepTestData | 449 test_data_fn = step_config.step_test_data or recipe_test_api.StepTestData |
| 430 step_test = self._test_data.pop_step_test_data(step_config.name, | 450 step_test = self._test_data.pop_step_test_data(step_config.name, |
| 431 test_data_fn) | 451 test_data_fn) |
| 432 rendered_step = render_step(step_config, step_test) | 452 rendered_step = render_step(step_config, step_test) |
| 453 step_env = _merge_envs(fakeEnviron(), (rendered_step.config.env or {})) | |
| 454 rendered_step = rendered_step._replace( | |
| 455 config=rendered_step.config._replace(env=step_env.data)) | |
| 433 step_config = None # Make sure we use rendered step config. | 456 step_config = None # Make sure we use rendered step config. |
| 434 | 457 |
| 435 # Layer the simulation step on top of the given stream engine. | 458 # Layer the simulation step on top of the given stream engine. |
| 436 step_stream = self._stream_engine.new_step_stream(rendered_step.config) | 459 step_stream = self._stream_engine.new_step_stream(rendered_step.config) |
| 437 except: | 460 except: |
| 438 with self.stream_engine.make_step_stream('Step Preparation Exception') as s: | 461 with self.stream_engine.make_step_stream('Step Preparation Exception') as s: |
| 439 s.set_step_status('EXCEPTION') | 462 s.set_step_status('EXCEPTION') |
| 440 with s.new_log_stream('exception') as l: | 463 with s.new_log_stream('exception') as l: |
| 441 l.write_split(traceback.format_exc()) | 464 l.write_split(traceback.format_exc()) |
| 442 raise | 465 raise |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 748 supplied command, and only uses the |env| kwarg for modifying the environment | 771 supplied command, and only uses the |env| kwarg for modifying the environment |
| 749 of the child process. | 772 of the child process. |
| 750 """ | 773 """ |
| 751 saved_path = os.environ['PATH'] | 774 saved_path = os.environ['PATH'] |
| 752 try: | 775 try: |
| 753 if path is not None: | 776 if path is not None: |
| 754 os.environ['PATH'] = path | 777 os.environ['PATH'] = path |
| 755 yield | 778 yield |
| 756 finally: | 779 finally: |
| 757 os.environ['PATH'] = saved_path | 780 os.environ['PATH'] = saved_path |
| OLD | NEW |