Class: Roby::Queries::ExecutionExceptionMatcher

Inherits:
Object
  • Object
show all
Includes:
DRoby::V5::Queries::ExecutionExceptionMatcherDumper
Defined in:
lib/roby/queries/execution_exception_matcher.rb,
lib/roby/droby/enable.rb

Overview

Object that allows to specify generalized matches on a Roby::ExecutionException object

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from DRoby::V5::Queries::ExecutionExceptionMatcherDumper

#droby_dump

Constructor Details

#initializeExecutionExceptionMatcher

Returns a new instance of ExecutionExceptionMatcher.



13
14
15
16
17
18
# File 'lib/roby/queries/execution_exception_matcher.rb', line 13

def initialize
    @exception_matcher = LocalizedErrorMatcher.new
    @involved_tasks_matchers = Array.new
    @expected_edges = nil
    @handled = nil
end

Instance Attribute Details

#exception_matcherLocalizedErrorMatcher (readonly)

An object that will be used to match the actual (Ruby) exception



8
9
10
# File 'lib/roby/queries/execution_exception_matcher.rb', line 8

def exception_matcher
  @exception_matcher
end

#involved_tasks_matchersArray<#===,TaskMatcher> (readonly)

An object that will be used to match the exception origin

Returns:



11
12
13
# File 'lib/roby/queries/execution_exception_matcher.rb', line 11

def involved_tasks_matchers
  @involved_tasks_matchers
end

Instance Method Details

#===(exception) ⇒ Boolean

Returns true if the given execution exception object matches self, false otherwise.

Returns:

  • (Boolean)

    true if the given execution exception object matches self, false otherwise



136
137
138
139
140
141
142
143
144
145
# File 'lib/roby/queries/execution_exception_matcher.rb', line 136

def ===(exception)
    if !exception.respond_to?(:to_execution_exception)
        return false
    end
    exception = exception.to_execution_exception
    exception_matcher === exception.exception &&
        involved_tasks_matchers.all? { |m| exception.trace.any? { |t| m === t } } &&
        (!@expected_edges || (@expected_edges == exception.trace.each_edge.to_set)) &&
        (@handled.nil? || !(@handled ^ exception.handled?))
end

#describe_failed_match(exception) ⇒ Object



147
148
149
150
151
152
153
# File 'lib/roby/queries/execution_exception_matcher.rb', line 147

def describe_failed_match(exception)
    if !(exception_matcher === exception.exception)
        return exception_matcher.describe_failed_match(exception.exception)
    elsif missing_involved_task = involved_tasks_matchers.find { |m| exception.trace.none? { |t| m === t } }
        return "#{missing_involved_task} cannot be found in the exception trace\n  #{exception.trace.map(&:to_s).join("\n  ")}"
    end
end

#fatalObject



48
49
50
51
# File 'lib/roby/queries/execution_exception_matcher.rb', line 48

def fatal
    exception_matcher.fatal
    self
end

#handled(flag = true) ⇒ Object



20
21
22
23
# File 'lib/roby/queries/execution_exception_matcher.rb', line 20

def handled(flag = true)
    @handled = flag
    self
end

#involving(task_matcher) ⇒ Object

Matched exceptions must have a task in their trace that matches the given task matcher

Parameters:



92
93
94
95
# File 'lib/roby/queries/execution_exception_matcher.rb', line 92

def involving(task_matcher)
    involved_tasks_matchers << origin_matcher
    self
end

#matches_task?(task) ⇒ Boolean

Returns:

  • (Boolean)


155
156
157
158
# File 'lib/roby/queries/execution_exception_matcher.rb', line 155

def matches_task?(task)
    involved_tasks_matchers.all? { |m| m === task } &&
        exception_matcher.matches_task?(task)
end

#not_handledObject



25
26
27
# File 'lib/roby/queries/execution_exception_matcher.rb', line 25

def not_handled
    handled(false)
end

#pretty_print(pp) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/roby/queries/execution_exception_matcher.rb', line 101

def pretty_print(pp)
    pp.text "ExecutionException("
    exception_matcher.pretty_print(pp)
    pp.text ")"
    if !involved_tasks_matchers.empty?
        pp.text ".involving("
        pp.nest(2) do
            involved_tasks_matchers.each do |m|
                pp.breakable
                m.pretty_print(pp)
            end
        end
        pp.text ")"
    end
    if @expected_edges
        pp.text ".with_trace("
        pp.nest(2) do
            @expected_edges.each do |a, b, _|
                pp.breakable
                pp.text "#{a} => #{b}"
            end
        end
        pp.text ")"
    end
    if !@handled.nil?
        if @handled
            pp.text ".handled"
        else
            pp.text ".not_handled"
        end
    end
end

#to_execution_exception_matcherObject



160
161
162
# File 'lib/roby/queries/execution_exception_matcher.rb', line 160

def to_execution_exception_matcher
    self
end

#to_sObject



97
98
99
# File 'lib/roby/queries/execution_exception_matcher.rb', line 97

def to_s
    PP.pp(self, "")
end

#with_empty_traceObject



53
54
55
56
# File 'lib/roby/queries/execution_exception_matcher.rb', line 53

def with_empty_trace
    @expected_edges = Set.new
    self
end

#with_exception(exception_matcher) ⇒ Object

Sets the exception matcher object



30
31
32
33
# File 'lib/roby/queries/execution_exception_matcher.rb', line 30

def with_exception(exception_matcher)
    @exception_matcher = exception_matcher
    self
end

#with_model(exception_model) ⇒ Object

Specifies which subclass of LocalizedError this matcher should look for

Returns:

  • self



36
37
38
39
# File 'lib/roby/queries/execution_exception_matcher.rb', line 36

def with_model(exception_model)
    exception_matcher.with_model(exception_model)
    self
end

#with_origin(plan_object_matcher) ⇒ Object

Specifies a match on the error origin

The resulting match is extended, i.e. a task matcher will match the origin’s task event if the origin itself is an event.

Returns:

  • self



42
43
44
45
# File 'lib/roby/queries/execution_exception_matcher.rb', line 42

def with_origin(plan_object_matcher)
    exception_matcher.with_origin(plan_object_matcher)
    self
end

#with_trace(*edges) ⇒ Object #with_trace(edges) ⇒ Object

Match the exception trace

The trace is a representation of the exception’s propagation during Roby’s exception propagation phase. This verifies that the graph contains the edges specified by its argument

Overloads:

  • #with_trace(*edges) ⇒ Object

    Parameters:

    • edges (Array<Task>)

      specify the edges of the propagation graph two-by-two, source then sink

      @example match a graph with (source0, sink0), (source0, sink1) edges

      with_trace(source0, sink0, source0, sink1)
      
  • #with_trace(edges) ⇒ Object

    Parameters:

    • edges (Hash)

      specify edges as a mapping. Edges that share the same source must be specified as source=>[sink0, sink1]

      @example match a graph with (source0, sink0), (source0, sink1) edges

      with_trace(source0 => [sink0, sink1])
      


78
79
80
81
82
83
84
85
86
# File 'lib/roby/queries/execution_exception_matcher.rb', line 78

def with_trace(*edges)
    if edges.first.kind_of?(Hash)
        edges = edges.first.to_a.flat_map do |source, targets|
            Array(targets).flat_map { |t| [source, t] }
        end
    end
    @expected_edges = edges.each_slice(2).map { |a, b| [a, b, nil] }.to_set
    self
end