Class: Roby::Test::ExecutionExpectations
- Defined in:
- lib/roby/test/execution_expectations.rb
Overview
Underlying implementation for Roby's when do end.expect ... feature
The expectation's documented return value are NOT the values returned by the method itself, but the value that the user can expect out of the expectation run.
expect_execution.to do
achieve { plan.num_tasks }
end # => the number of tasks from the plan
expect_execution.to do
event = emit task.start_event
error = have_error_matching CodeError
[error, event]
end # => the pair (raised error, emitted event)
Defined Under Namespace
Classes: Achieve, BecomeUnreachable, EmitGenerator, EmitGeneratorModel, ErrorExpectation, Expectation, FailsToStart, Finalize, HaveErrorMatching, HaveFrameworkError, HaveHandledErrorMatching, IgnoreErrorsFrom, Maintain, NotBecomeUnreachable, NotEmitGenerator, NotEmitGeneratorModel, NotFinalize, PromiseFinishes, Quarantine, UnexpectedErrors, Unmet
Expectations collapse
-
#achieve(description: nil, backtrace: caller(1)) {|all_propagation_info| ... } ⇒ Object
Expect that the given block returns true.
-
#become_unreachable(*generators, backtrace: caller(1)) ⇒ Object+
Expect that the generator(s) become unreachable.
-
#emit(*generators, backtrace: caller(1)) ⇒ Event, [Event]
Expect that an event is emitted after the expect_execution block.
-
#fail_to_start(task, reason: nil, backtrace: caller(1)) ⇒ nil
Expect that the given task fails to start.
-
#finalize(*plan_objects, backtrace: caller(1)) ⇒ nil
Expect that plan objects (task or event) are finalized.
-
#finish(task, backtrace: caller(1)) ⇒ Event
Expect that the given task finishes.
-
#finish_promise(promise, backtrace: caller(1)) ⇒ nil
Expect that the given promise finishes.
-
#have_error_matching(matcher, backtrace: caller(1)) ⇒ ExecutionException
Expect that an error is raised and not caught.
-
#have_framework_error_matching(error, backtrace: caller(1)) ⇒ Object
Expect that a framework error is added.
-
#have_handled_error_matching(matcher, backtrace: caller(1)) ⇒ ExecutionException
Expect that an error is raised and caught.
-
#have_internal_error(task, original_exception) ⇒ Event
Expect that the given task emits its internal_error event.
-
#have_running(task, backtrace: caller(1)) ⇒ nil
Expect that the given task either starts or is running, and does not stop.
-
#ignore_errors_from(expectations, backtrace: caller(1)) ⇒ Object
Given another predicate, ignore all errors related to this predicate but do not expect the predicate itself to be fullfilled.
-
#maintain(at_least_during: 0, description: nil, backtrace: caller(1)) {|all_propagation_info| ... } ⇒ Object
Expect that the given block is true during a certain amount of time.
-
#not_become_unreachable(*generators, backtrace: caller(1)) ⇒ Object
Expect that the generator(s) do not become unreachable.
-
#not_emit(*generators, within: 0, backtrace: caller(1)) ⇒ nil
Expect that an event is not emitted after the expect_execution block.
-
#not_finalize(*plan_objects, backtrace: caller(1)) ⇒ nil
Expect that plan objects (task or event) are not finalized.
-
#quarantine(task, backtrace: caller(1)) ⇒ nil
Expect that the given task is put in quarantine.
-
#start(task, backtrace: caller(1)) ⇒ Event
Expect that the given task starts.
Setup collapse
-
.each_exit_allowed_condition(&block) ⇒ Object
Enumerates the blocks registered by #after.
-
.each_poll_block {|test, test| ... } ⇒ Object
Iterate over globally registered poll blocks.
-
.exit_allowed_condition(&block) ⇒ Object
Sets up a block that will be used by the harness to decide whether it can exit the execution loop or not when all expectations have been met.
-
.poll(&block) ⇒ Object
Sets up a block that will be called at each execution cycle and for all expectations.
-
#display_exceptions(enable) ⇒ Object
Whether exceptions should be displayed by the execution engine.
-
#filter_out_related_errors(enable) ⇒ Object
When enabled, errors that are caused by something that has a matcher will not be reported as unexpected.
-
#garbage_collect(enable) ⇒ Object
Whether a garbage collection pass should be run.
-
#join_all_waiting_work(join) ⇒ Object
Whether the expectation test should wait for asynchronous work to finish between event propagations.
-
#meets_exit_allowed_conditions? ⇒ Boolean
Whether the conditions registered with exit_allowed_condition are met.
-
#poll(&block) ⇒ Object
Setups a block that should be called at each execution cycle.
-
#scheduler(enabled_or_scheduler) ⇒ Object
Controls the scheduler.
-
#timeout(timeout) ⇒ Object
How long will the test wait either for asynchronous jobs (if #wait_until_timeout is false and #join_all_waiting_work is true) or until it succeeds (if #wait_until_timeout is true).
-
#validate_unexpected_errors(enable) ⇒ Object
Whether the expectations will pass if exceptions are propagated that are not explicitely expected.
-
#wait_until_timeout(wait) ⇒ Object
Whether the execution will run until the timeout if the expectations have not been met yet.
Class Method Summary collapse
- .format_propagation_info(propagation_info, indent: 0) ⇒ Object
-
.parse(test, plan, &block) ⇒ Expectation
Parse a expect { } block into an Expectation object.
Instance Method Summary collapse
-
#add_expectation(expectation) ⇒ Object
Add a new expectation to be run during #verify.
-
#compute_returned_objects(return_objects) ⇒ Object
Process the value returned by the
.to { }block to convert it to the actual result of the expectations. -
#execute(&block) ⇒ Object
Queue a block for execution.
- #find_all_unmet_expectations(all_propagation_info) ⇒ Object
- #find_tasks(*args) ⇒ Object
-
#has_pending_execute_blocks? ⇒ Boolean
Whether some blocks have been queued for execution with #execute.
-
#initialize(test, plan) ⇒ ExecutionExpectations
constructor
A new instance of ExecutionExpectations.
- #method_missing(m, *args, &block) ⇒ Object
- #parse(ret: true, &block) ⇒ Object
- #respond_to_missing?(m, include_private) ⇒ Boolean
-
#unexpected_error?(error) ⇒ Boolean
Checks whether the given error is unexpected, given the predicates.
- #validate_has_no_unexpected_error(propagation_info) ⇒ Object
-
#verify(&block) ⇒ Object
Verify that executing the given block in event propagation context will cause the expectations to be met.
- #verify_execute_one_cycle ⇒ Object
- #verify_validate_final(all_propagation_info) ⇒ Object
- #with_execution_engine_setup ⇒ Object
Constructor Details
#initialize(test, plan) ⇒ ExecutionExpectations
Returns a new instance of ExecutionExpectations.
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
# File 'lib/roby/test/execution_expectations.rb', line 318 def initialize(test, plan) @test = test @plan = plan @expectations = [] @execute_blocks = [] @poll_blocks = [] @scheduler = false @timeout = 5 @join_all_waiting_work = true @wait_until_timeout = true @garbage_collect = false @validate_unexpected_errors = true @display_exceptions = false @filter_out_related_errors = true end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(m, *args, &block) ⇒ Object
344 345 346 347 348 349 350 |
# File 'lib/roby/test/execution_expectations.rb', line 344 def method_missing(m, *args, &block) if @test.respond_to?(m) @test.public_send(m, *args, &block) else super end end |
Class Method Details
.each_exit_allowed_condition(&block) ⇒ Object
Enumerates the blocks registered by #after
This is meant to be used to integrate runtime services that are critical to the functioning of the expect_execution harness
574 575 576 |
# File 'lib/roby/test/execution_expectations.rb', line 574 def self.each_exit_allowed_condition(&block) @exit_allowed_conditions.each(&block) end |
.each_poll_block {|test, test| ... } ⇒ Object
Iterate over globally registered poll blocks
603 604 605 |
# File 'lib/roby/test/execution_expectations.rb', line 603 def self.each_poll_block(&block) @poll_blocks.each(&block) end |
.exit_allowed_condition(&block) ⇒ Object
Sets up a block that will be used by the harness to decide whether it can exit the execution loop or not when all expectations have been met.
This is meant to be used to integrate runtime services that are critical to the functioning of the expect_execution harness. Note that these conditions will be overriden when reaching the timeout.
563 564 565 566 |
# File 'lib/roby/test/execution_expectations.rb', line 563 def self.exit_allowed_condition(&block) @exit_allowed_conditions << block Roby.disposable { @exit_allowed_conditions.delete(block) } end |
.format_propagation_info(propagation_info, indent: 0) ⇒ Object
352 353 354 |
# File 'lib/roby/test/execution_expectations.rb', line 352 def self.format_propagation_info(propagation_info, indent: 0) PP.pp(propagation_info, "".dup).split("\n").join("\n#{' ' * indent}") end |
.parse(test, plan, &block) ⇒ Expectation
Parse a expect { } block into an Expectation object
308 309 310 |
# File 'lib/roby/test/execution_expectations.rb', line 308 def self.parse(test, plan, &block) new(test, plan).parse(&block) end |
.poll(&block) ⇒ Object
Sets up a block that will be called at each execution cycle and for all expectations
This is meant to be used to integrate runtime services that are critical to the functioning of the expect_execution harness
592 593 594 595 |
# File 'lib/roby/test/execution_expectations.rb', line 592 def self.poll(&block) @poll_blocks << block Roby.disposable { @poll_blocks.delete(block) } end |
Instance Method Details
#achieve(description: nil, backtrace: caller(1)) {|all_propagation_info| ... } ⇒ Object
Expect that the given block returns true
143 144 145 |
# File 'lib/roby/test/execution_expectations.rb', line 143 def achieve(description: nil, backtrace: caller(1), &block) add_expectation(Achieve.new(block, description, backtrace)) end |
#add_expectation(expectation) ⇒ Object
Add a new expectation to be run during #verify
616 617 618 619 |
# File 'lib/roby/test/execution_expectations.rb', line 616 def add_expectation(expectation) @expectations << expectation expectation end |
#become_unreachable(*generators, backtrace: caller(1)) ⇒ Object+
Expect that the generator(s) become unreachable
96 97 98 99 100 101 102 103 104 105 |
# File 'lib/roby/test/execution_expectations.rb', line 96 def become_unreachable(*generators, backtrace: caller(1)) return_values = generators.map do |generator| add_expectation(BecomeUnreachable.new(generator, backtrace)) end if return_values.size == 1 return_values.first else return_values end end |
#compute_returned_objects(return_objects) ⇒ Object
Process the value returned by the .to { } block to convert it to
the actual result of the expectations
766 767 768 769 770 771 772 |
# File 'lib/roby/test/execution_expectations.rb', line 766 def compute_returned_objects(return_objects) return_objects.map do |ret| obj = ret.respond_to?(:return_object) ? ret.return_object : ret obj = ret.filter_result(obj) if ret.respond_to?(:filter_result) obj end end |
#display_exceptions(enable) ⇒ Object
Whether exceptions should be displayed by the execution engine
The default is false
549 |
# File 'lib/roby/test/execution_expectations.rb', line 549 dsl_attribute :display_exceptions |
#emit(generator) ⇒ Event #emit(generator_query) ⇒ [Event]
Expect that an event is emitted after the expect_execution block
74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/roby/test/execution_expectations.rb', line 74 def emit(*generators, backtrace: caller(1)) return_values = generators.map do |generator| if generator.kind_of?(EventGenerator) add_expectation(EmitGenerator.new(generator, backtrace)) else add_expectation(EmitGeneratorModel.new(generator, backtrace)) end end if return_values.size == 1 return_values.first else return_values end end |
#execute(&block) ⇒ Object
Queue a block for execution
This is meant to be used by expectation objects which require to perform some actions in execution context.
625 626 627 628 |
# File 'lib/roby/test/execution_expectations.rb', line 625 def execute(&block) @execute_blocks << block nil end |
#fail_to_start(task, reason: nil, backtrace: caller(1)) ⇒ nil
Expect that the given task fails to start
151 152 153 |
# File 'lib/roby/test/execution_expectations.rb', line 151 def fail_to_start(task, reason: nil, backtrace: caller(1)) add_expectation(FailsToStart.new(task, reason, backtrace)) end |
#filter_out_related_errors(enable) ⇒ Object
When enabled, errors that are caused by something that has a matcher
will not be reported as unexpected. For instance, a DependencyFailedError
caused by an event, when there is the corresponding emit predicate.
The default is true
530 |
# File 'lib/roby/test/execution_expectations.rb', line 530 dsl_attribute :filter_out_related_errors |
#finalize(*plan_objects, backtrace: caller(1)) ⇒ nil
Expect that plan objects (task or event) are finalized
201 202 203 204 205 |
# File 'lib/roby/test/execution_expectations.rb', line 201 def finalize(*plan_objects, backtrace: caller(1)) plan_objects.map do |plan_object| add_expectation(Finalize.new(plan_object, backtrace)) end end |
#find_all_unmet_expectations(all_propagation_info) ⇒ Object
819 820 821 822 823 |
# File 'lib/roby/test/execution_expectations.rb', line 819 def find_all_unmet_expectations(all_propagation_info) @expectations.find_all do |exp| !exp.update_match(all_propagation_info) end end |
#find_tasks(*args) ⇒ Object
336 337 338 |
# File 'lib/roby/test/execution_expectations.rb', line 336 def find_tasks(*args) @test.plan.find_tasks(*args) end |
#finish(task, backtrace: caller(1)) ⇒ Event
Expect that the given task finishes
189 190 191 192 193 194 195 |
# File 'lib/roby/test/execution_expectations.rb', line 189 def finish(task, backtrace: caller(1)) unless task.running? start_emitted = emit(task.start_event, backtrace: backtrace) end [start_emitted, emit(task.stop_event, backtrace: backtrace)].compact end |
#finish_promise(promise, backtrace: caller(1)) ⇒ nil
Expect that the given promise finishes
238 239 240 |
# File 'lib/roby/test/execution_expectations.rb', line 238 def finish_promise(promise, backtrace: caller(1)) add_expectation(PromiseFinishes.new(promise, backtrace)) end |
#garbage_collect(enable) ⇒ Object
Whether a garbage collection pass should be run
The default is false
519 |
# File 'lib/roby/test/execution_expectations.rb', line 519 dsl_attribute :garbage_collect |
#has_pending_execute_blocks? ⇒ Boolean
Whether some blocks have been queued for execution with #execute
632 633 634 |
# File 'lib/roby/test/execution_expectations.rb', line 632 def has_pending_execute_blocks? # rubocop:disable Naming/PredicateName !@execute_blocks.empty? end |
#have_error_matching(matcher, backtrace: caller(1)) ⇒ ExecutionException
Expect that an error is raised and not caught
255 256 257 |
# File 'lib/roby/test/execution_expectations.rb', line 255 def have_error_matching(matcher, backtrace: caller(1)) # rubocop:disable Naming/PredicateName add_expectation(HaveErrorMatching.new(matcher, backtrace)) end |
#have_framework_error_matching(error, backtrace: caller(1)) ⇒ Object
Expect that a framework error is added
Framework errors are errors that are raised outside of user code. They are fatal inconsistencies, and cause the whole Roby instance to quit forcefully
Unlike with #have_error_matching and #have_handled_error_matching, the error is rarely a LocalizedError. For simple exceptions, one can simply use the exception class to match.
286 287 288 |
# File 'lib/roby/test/execution_expectations.rb', line 286 def have_framework_error_matching(error, backtrace: caller(1)) # rubocop:disable Naming/PredicateName add_expectation(HaveFrameworkError.new(error, backtrace)) end |
#have_handled_error_matching(matcher, backtrace: caller(1)) ⇒ ExecutionException
Expect that an error is raised and caught
272 273 274 |
# File 'lib/roby/test/execution_expectations.rb', line 272 def have_handled_error_matching(matcher, backtrace: caller(1)) # rubocop:disable Naming/PredicateName add_expectation(HaveHandledErrorMatching.new(matcher, backtrace)) end |
#have_internal_error(task, original_exception) ⇒ Event
Expect that the given task emits its internal_error event
221 222 223 224 |
# File 'lib/roby/test/execution_expectations.rb', line 221 def have_internal_error(task, original_exception) # rubocop:disable Naming/PredicateName [have_handled_error_matching(original_exception.match.with_origin(task)), emit(task.internal_error_event)] end |
#have_running(task, backtrace: caller(1)) ⇒ nil
Expect that the given task either starts or is running, and does not stop
The caveats of #not_emit apply to the "does not stop" part of the expectation. This should usually be used in conjunction with a synchronization point.
177 178 179 180 181 182 183 |
# File 'lib/roby/test/execution_expectations.rb', line 177 def have_running(task, backtrace: caller(1)) # rubocop:disable Naming/PredicateName unless task.running? start_emitted = emit(task.start_event, backtrace: backtrace) end [start_emitted, not_emit(task.stop_event)].compact end |
#ignore_errors_from(expectations, backtrace: caller(1)) ⇒ Object
Given another predicate, ignore all errors related to this predicate but do not expect the predicate itself to be fullfilled.
295 296 297 298 299 300 301 |
# File 'lib/roby/test/execution_expectations.rb', line 295 def ignore_errors_from(expectations, backtrace: caller(1)) expectations = Array(expectations) expectations.each do |e| @expectations.delete(e) end add_expectation(IgnoreErrorsFrom.new(expectations, backtrace)) end |
#join_all_waiting_work(join) ⇒ Object
Whether the expectation test should wait for asynchronous work to finish between event propagations
The default is true
496 |
# File 'lib/roby/test/execution_expectations.rb', line 496 dsl_attribute :join_all_waiting_work |
#maintain(at_least_during: 0, description: nil, backtrace: caller(1)) {|all_propagation_info| ... } ⇒ Object
Expect that the given block is true during a certain amount of time
128 129 130 131 132 133 134 |
# File 'lib/roby/test/execution_expectations.rb', line 128 def maintain( at_least_during: 0, description: nil, backtrace: caller(1), &block ) add_expectation( Maintain.new(at_least_during, block, description, backtrace) ) end |
#meets_exit_allowed_conditions? ⇒ Boolean
Whether the conditions registered with exit_allowed_condition are met
The test harness' loop will not exit until that is the case
581 582 583 |
# File 'lib/roby/test/execution_expectations.rb', line 581 def meets_exit_allowed_conditions? self.class.each_exit_allowed_condition.all? { _1.call(@test, @plan) } end |
#not_become_unreachable(*generators, backtrace: caller(1)) ⇒ Object
Expect that the generator(s) do not become unreachable
111 112 113 114 115 |
# File 'lib/roby/test/execution_expectations.rb', line 111 def not_become_unreachable(*generators, backtrace: caller(1)) generators.map do |generator| add_expectation(NotBecomeUnreachable.new(generator, backtrace)) end end |
#not_emit(*generators, within: 0, backtrace: caller(1)) ⇒ nil
Expect that an event is not emitted after the expect_execution block
Note that only one event propagation pass is guaranteed to happen before the "no emission" expectation is validated. I.e. this cannot test for the non-existence of a delayed emission
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/roby/test/execution_expectations.rb', line 35 def not_emit(*generators, within: 0, backtrace: caller(1)) generators.map do |generator| if generator.kind_of?(EventGenerator) add_expectation( NotEmitGenerator.new(generator, backtrace, within: within) ) else add_expectation( NotEmitGeneratorModel.new( generator, backtrace, within: within ) ) end end end |
#not_finalize(*plan_objects, backtrace: caller(1)) ⇒ nil
Expect that plan objects (task or event) are not finalized
211 212 213 214 215 |
# File 'lib/roby/test/execution_expectations.rb', line 211 def not_finalize(*plan_objects, backtrace: caller(1)) plan_objects.map do |plan_object| add_expectation(NotFinalize.new(plan_object, backtrace)) end end |
#parse(ret: true, &block) ⇒ Object
312 313 314 315 316 |
# File 'lib/roby/test/execution_expectations.rb', line 312 def parse(ret: true, &block) block_ret = instance_eval(&block) @return_objects = block_ret if ret self end |
#poll(&block) ⇒ Object
Setups a block that should be called at each execution cycle
608 609 610 611 |
# File 'lib/roby/test/execution_expectations.rb', line 608 def poll(&block) @poll_blocks << block self end |
#quarantine(task, backtrace: caller(1)) ⇒ nil
Expect that the given task is put in quarantine
230 231 232 |
# File 'lib/roby/test/execution_expectations.rb', line 230 def quarantine(task, backtrace: caller(1)) add_expectation(Quarantine.new(task, backtrace)) end |
#respond_to_missing?(m, include_private) ⇒ Boolean
340 341 342 |
# File 'lib/roby/test/execution_expectations.rb', line 340 def respond_to_missing?(m, include_private) @test.respond_to?(m) || super end |
#scheduler(enabled) ⇒ Object #scheduler(scheduler) ⇒ Object
Controls the scheduler
The default is false
510 |
# File 'lib/roby/test/execution_expectations.rb', line 510 dsl_attribute :scheduler |
#start(task, backtrace: caller(1)) ⇒ Event
Expect that the given task starts
159 160 161 |
# File 'lib/roby/test/execution_expectations.rb', line 159 def start(task, backtrace: caller(1)) emit task.start_event, backtrace: backtrace end |
#timeout(timeout) ⇒ Object
How long will the test wait either for asynchronous jobs (if #wait_until_timeout is false and #join_all_waiting_work is true) or until it succeeds (if #wait_until_timeout is true)
The default is 5s
476 |
# File 'lib/roby/test/execution_expectations.rb', line 476 dsl_attribute :timeout |
#unexpected_error?(error) ⇒ Boolean
Checks whether the given error is unexpected, given the predicates
It filters out errors that are related to certain predicates, as tested with the Roby::Test::ExecutionExpectations::Expectation#relates_to_error? test
809 810 811 812 813 814 815 816 817 |
# File 'lib/roby/test/execution_expectations.rb', line 809 def unexpected_error?(error) return true unless @filter_out_related_errors all_errors = Roby.flatten_exception(error) = @expectations.any? do |expectation| all_errors.any? { |orig_e| expectation.relates_to_error?(orig_e) } end ! end |
#validate_has_no_unexpected_error(propagation_info) ⇒ Object
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 |
# File 'lib/roby/test/execution_expectations.rb', line 774 def validate_has_no_unexpected_error(propagation_info) unexpected_errors = propagation_info.exceptions.find_all do |e| unexpected_error?(e) end unexpected_errors.concat( propagation_info.each_framework_error .map(&:first) .find_all { |e| unexpected_error?(e) } ) # Look for internal_error_event, which is how the tasks report # on their internal errors internal_errors = propagation_info.emitted_events.find_all do |ev| is_internal_error = ev.generator.respond_to?(:symbol) && ev.generator.symbol == :internal_error next unless is_internal_error ev.context.any? do |obj| unexpected_error?(obj) if obj.kind_of?(Exception) end end unexpected_errors += internal_errors.flat_map(&:context) return if unexpected_errors.empty? raise UnexpectedErrors.new(unexpected_errors) end |
#validate_unexpected_errors(enable) ⇒ Object
Whether the expectations will pass if exceptions are propagated that are not explicitely expected
The default is true
540 |
# File 'lib/roby/test/execution_expectations.rb', line 540 dsl_attribute :validate_unexpected_errors |
#verify(&block) ⇒ Object
Verify that executing the given block in event propagation context will cause the expectations to be met
668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 |
# File 'lib/roby/test/execution_expectations.rb', line 668 def verify(&block) all_propagation_info = ExecutionEngine::PropagationInfo.new timeout_deadline = Time.now_without_mock_time + @timeout @execute_blocks << block if block engine = @plan.execution_engine loop do engine.start_new_cycle propagation_info = verify_execute_one_cycle all_propagation_info.merge(propagation_info) unmet = find_all_unmet_expectations(all_propagation_info) unachievable = unmet.find_all do |expectation| expectation.unachievable?(all_propagation_info) end unless unachievable.empty? unachievable = unachievable.map do |expectation| explanation = expectation .explain_unachievable(all_propagation_info) [expectation, explanation] end raise Unmet.new(unachievable, all_propagation_info) end if @validate_unexpected_errors validate_has_no_unexpected_error(all_propagation_info) end remaining_timeout = timeout_deadline - Time.now_without_mock_time break if remaining_timeout < 0 if @join_all_waiting_work && engine.has_waiting_work? next elsif has_pending_execute_blocks? next elsif unmet.empty? break if meets_exit_allowed_conditions? elsif !@wait_until_timeout break end end verify_validate_final(all_propagation_info) if @return_objects.respond_to?(:to_ary) compute_returned_objects(@return_objects) else compute_returned_objects([@return_objects]).first end end |
#verify_execute_one_cycle ⇒ Object
720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 |
# File 'lib/roby/test/execution_expectations.rb', line 720 def verify_execute_one_cycle engine = @plan.execution_engine with_execution_engine_setup do propagation_info = engine.process_events( raise_framework_errors: false, garbage_collect_pass: @garbage_collect ) do @execute_blocks.delete_if do |b| b.call true end @poll_blocks.each(&:call) self.class.each_poll_block { _1.call(@test, @plan) } if engine.has_waiting_work? engine.process_waiting_work Thread.pass end end exceptions = engine.cycle_end({}, raise_framework_errors: false) propagation_info.framework_errors.concat(exceptions) propagation_info end end |
#verify_validate_final(all_propagation_info) ⇒ Object
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 |
# File 'lib/roby/test/execution_expectations.rb', line 745 def verify_validate_final(all_propagation_info) engine = @plan.execution_engine if @join_all_waiting_work && engine.has_waiting_work? e = ExecutionEngine::JoinAllWaitingWorkTimeout.new( engine.waiting_work ) raise UnexpectedErrors.new([e]), "some asynchronous work did not finish" end unmet = find_all_unmet_expectations(all_propagation_info) raise Unmet.new(unmet, all_propagation_info) unless unmet.empty? return unless @validate_unexpected_errors validate_has_no_unexpected_error(all_propagation_info) end |
#wait_until_timeout(wait) ⇒ Object
Whether the execution will run until the timeout if the expectations have not been met yet.
The default is true
486 |
# File 'lib/roby/test/execution_expectations.rb', line 486 dsl_attribute :wait_until_timeout |
#with_execution_engine_setup ⇒ Object
636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 |
# File 'lib/roby/test/execution_expectations.rb', line 636 def with_execution_engine_setup engine = @plan.execution_engine current_scheduler = engine.scheduler current_scheduler_state = engine.scheduler.enabled? current_display_exceptions = engine.display_exceptions? unless display_exceptions.nil? engine.display_exceptions = @display_exceptions end unless scheduler.nil? if @scheduler != true && @scheduler != false engine.scheduler = @scheduler else engine.scheduler.enabled = @scheduler end end yield ensure engine.scheduler = current_scheduler engine.scheduler.enabled = current_scheduler_state engine.display_exceptions = current_display_exceptions end |