Class: Roby::Test::ExecutionExpectations

Inherits:
Object
  • Object
show all
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)

Examples:

execute until a block returns true. The call returns the

block's return value

execute until an event was emitted and an error raised. The

call will in this case return the error object and the 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

Instance Attribute Summary collapse

Expectations collapse

Setup collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(test, plan) ⇒ ExecutionExpectations

Returns a new instance of ExecutionExpectations.



323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
# File 'lib/roby/test/execution_expectations.rb', line 323

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



349
350
351
352
353
354
355
# File 'lib/roby/test/execution_expectations.rb', line 349

def method_missing(m, *args, &block)
    if @test.respond_to?(m)
        @test.public_send(m, *args, &block)
    else
        super
    end
end

Instance Attribute Details

#testMinitest::Test (readonly)

The test case this object works on

Returns:



321
322
323
# File 'lib/roby/test/execution_expectations.rb', line 321

def test
  @test
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



579
580
581
# File 'lib/roby/test/execution_expectations.rb', line 579

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

Yield Parameters:

See Also:



608
609
610
# File 'lib/roby/test/execution_expectations.rb', line 608

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.



568
569
570
571
# File 'lib/roby/test/execution_expectations.rb', line 568

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



357
358
359
# File 'lib/roby/test/execution_expectations.rb', line 357

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

Returns:



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

See Also:

  • each_poll


597
598
599
600
# File 'lib/roby/test/execution_expectations.rb', line 597

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

Yield Parameters:

  • all_propagation_info (ExecutionEngine::PropagationInfo)

    all that happened during the propagations since the beginning of expect_execution block. It contains event emissions and raised/caught errors.

Yield Returns:

  • the value that should be returned by the expectation



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



621
622
623
624
# File 'lib/roby/test/execution_expectations.rb', line 621

def add_expectation(expectation)
    @expectations << expectation
    expectation
end

#become_unreachable(*generators, backtrace: caller(1)) ⇒ Object+

Expect that the generator(s) become unreachable

Parameters:

  • generators (Array<EventGenerator>)

    the generators that are expected to become unreachable

Returns:

  • (Object, Array<Object>)

    if only one generator is provided, its unreachability reason. Otherwise, the unreachability reasons of all the generators, in the same order than the argument



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



771
772
773
774
775
776
777
# File 'lib/roby/test/execution_expectations.rb', line 771

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

Parameters:

  • enable (Boolean)


554
# File 'lib/roby/test/execution_expectations.rb', line 554

dsl_attribute :display_exceptions

#emit(generator) ⇒ Event #emit(generator_query) ⇒ [Event]

Expect that an event is emitted after the expect_execution block

Overloads:

  • #emit(generator) ⇒ Event

    Returns the emitted event.

    Parameters:

    • generator (EventGenerator)

      the generator we're waiting the emission of

    Returns:

    • (Event)

      the emitted event

  • #emit(generator_query) ⇒ [Event]

    expect_execution.to do emit find_tasks(MyTask).start_event end

    Examples:

    wait for the emission of the start event of any task of

    model MyTask. The call will return the emitted events that match
    this.

    Parameters:

    Returns:

    • ([Event])

      all the events whose generator match the query

Parameters:

Returns:



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.



630
631
632
633
# File 'lib/roby/test/execution_expectations.rb', line 630

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

Parameters:

Returns:

  • (nil)


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

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

Parameters:

  • enable (Boolean)


535
# File 'lib/roby/test/execution_expectations.rb', line 535

dsl_attribute :filter_out_related_errors

#finalize(*plan_objects, backtrace: caller(1)) ⇒ nil

Expect that plan objects (task or event) are finalized

Parameters:

Returns:

  • (nil)


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



824
825
826
827
828
# File 'lib/roby/test/execution_expectations.rb', line 824

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



341
342
343
# File 'lib/roby/test/execution_expectations.rb', line 341

def find_tasks(*args)
    @test.plan.find_tasks(*args)
end

#finish(task, backtrace: caller(1)) ⇒ Event

Expect that the given task finishes

Parameters:

Returns:

  • (Event)

    the task's stop event



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

Parameters:

Returns:

  • (nil)


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

Parameters:

  • enable (Boolean)


524
# File 'lib/roby/test/execution_expectations.rb', line 524

dsl_attribute :garbage_collect

#has_pending_execute_blocks?Boolean

Whether some blocks have been queued for execution with #execute

Returns:

  • (Boolean)


637
638
639
# File 'lib/roby/test/execution_expectations.rb', line 637

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

Examples:

expect that a ChildFailedError is raised from 'task'

expect_execution.to do
  have_error_matching Roby::ChildFailedError.match.
    with_origin(task)
end

Parameters:

Returns:



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

Examples:

expect that a ChildFailedError is raised from 'task' and handled

expect_execution.to do
  have_handled_error_matching Roby::ChildFailedError.match.
    with_origin(task)
end

Parameters:

Returns:



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

Parameters:

Returns:

  • (Event)

    the emitted 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.

Examples:

task keeps running until action_task stops

expect_execution.to do
  keep_running task
  finish action_task
end

Parameters:

Returns:

  • (nil)


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.

Examples:

ignore all errors originating from this event emission

ignore_errors_from emit(task.stop_event)


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

Parameters:

  • join (Boolean)


501
# File 'lib/roby/test/execution_expectations.rb', line 501

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

Parameters:

  • at_least_during (Float) (defaults to: 0)

    the minimum duration in seconds. If zero, the expectations will run at least one execution cycle. The exact duration depends on the other expectations.

Yield Parameters:

  • all_propagation_info (ExecutionEngine::PropagationInfo)

    all that happened during the propagations since the beginning of expect_execution block. It contains event emissions and raised/caught errors.

Yield Returns:

  • (Boolean)

    expected to be true over duration seconds



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

Returns:

  • (Boolean)


586
587
588
# File 'lib/roby/test/execution_expectations.rb', line 586

def meets_exit_allowed_conditions?
    self.class.each_exit_allowed_condition.all? { _1.call(self, @plan) }
end

#not_become_unreachable(*generators, backtrace: caller(1)) ⇒ Object

Expect that the generator(s) do not become unreachable

Parameters:

  • generators (Array<EventGenerator>)

    the generators that are expected to 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

Returns:

  • (nil)


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

Parameters:

Returns:

  • (nil)


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



613
614
615
616
# File 'lib/roby/test/execution_expectations.rb', line 613

def poll(&block)
    @poll_blocks << block
    self
end

#quarantine(task, backtrace: caller(1)) ⇒ nil

Expect that the given task is put in quarantine

Parameters:

Returns:

  • (nil)


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

Returns:

  • (Boolean)


345
346
347
# File 'lib/roby/test/execution_expectations.rb', line 345

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

Overloads:

  • #scheduler(enabled) ⇒ Object

    Parameters:

    • enabled (Boolean)

      controls whether the scheduler is enabled or not

  • #scheduler(scheduler) ⇒ Object

    Parameters:



515
# File 'lib/roby/test/execution_expectations.rb', line 515

dsl_attribute :scheduler

#start(task, backtrace: caller(1)) ⇒ Event

Expect that the given task starts

Parameters:

Returns:

  • (Event)

    the task's start event



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

Parameters:

  • timeout (Float)


481
# File 'lib/roby/test/execution_expectations.rb', line 481

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

Parameters:

Returns:

  • (Boolean)


814
815
816
817
818
819
820
821
822
# File 'lib/roby/test/execution_expectations.rb', line 814

def unexpected_error?(error)
    return true unless @filter_out_related_errors

    all_errors = Roby.flatten_exception(error)
    has_related_predicate = @expectations.any? do |expectation|
        all_errors.any? { |orig_e| expectation.relates_to_error?(orig_e) }
    end
    !has_related_predicate
end

#validate_has_no_unexpected_error(propagation_info) ⇒ Object

Raises:



779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
# File 'lib/roby/test/execution_expectations.rb', line 779

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

Parameters:

  • enable (Boolean)


545
# File 'lib/roby/test/execution_expectations.rb', line 545

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

Returns:

  • (Object)

    a value or array of value as returned by the parsed block. If the block returns expectations, they are converted to a user-visible object by calling their #return_object method. Each expectation documents this as their return value (for instance, #achieve returns the block's "trueish" value)



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
719
720
721
722
723
# File 'lib/roby/test/execution_expectations.rb', line 673

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_cycleObject



725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
# File 'lib/roby/test/execution_expectations.rb', line 725

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(self, @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

Raises:



750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
# File 'lib/roby/test/execution_expectations.rb', line 750

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

Parameters:

  • wait (Boolean)


491
# File 'lib/roby/test/execution_expectations.rb', line 491

dsl_attribute :wait_until_timeout

#with_execution_engine_setupObject



641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
# File 'lib/roby/test/execution_expectations.rb', line 641

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