roby 0.7.3 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. data/History.txt +7 -5
  2. data/Manifest.txt +91 -16
  3. data/README.txt +24 -24
  4. data/Rakefile +92 -64
  5. data/app/config/app.yml +42 -43
  6. data/app/config/init.rb +26 -0
  7. data/benchmark/alloc_misc.rb +123 -0
  8. data/benchmark/discovery_latency.rb +67 -0
  9. data/benchmark/garbage_collection.rb +48 -0
  10. data/benchmark/genom.rb +31 -0
  11. data/benchmark/transactions.rb +62 -0
  12. data/bin/roby +1 -1
  13. data/bin/roby-log +16 -6
  14. data/doc/guide/.gitignore +2 -0
  15. data/doc/guide/config.yaml +34 -0
  16. data/doc/guide/ext/init.rb +14 -0
  17. data/doc/guide/ext/previous_next.rb +40 -0
  18. data/doc/guide/ext/rdoc_links.rb +33 -0
  19. data/doc/guide/index.rdoc +16 -0
  20. data/doc/guide/overview.rdoc +62 -0
  21. data/doc/guide/plan_modifications.rdoc +67 -0
  22. data/doc/guide/src/abstraction/achieve_with.page +8 -0
  23. data/doc/guide/src/abstraction/forwarding.page +8 -0
  24. data/doc/guide/src/abstraction/hierarchy.page +19 -0
  25. data/doc/guide/src/abstraction/index.page +28 -0
  26. data/doc/guide/src/abstraction/task_models.page +13 -0
  27. data/doc/guide/src/basics.template +6 -0
  28. data/doc/guide/src/basics/app.page +139 -0
  29. data/doc/guide/src/basics/code_examples.page +33 -0
  30. data/doc/guide/src/basics/dry.page +69 -0
  31. data/doc/guide/src/basics/errors.page +443 -0
  32. data/doc/guide/src/basics/events.page +179 -0
  33. data/doc/guide/src/basics/hierarchy.page +275 -0
  34. data/doc/guide/src/basics/index.page +11 -0
  35. data/doc/guide/src/basics/log_replay/goForward_1.png +0 -0
  36. data/doc/guide/src/basics/log_replay/goForward_2.png +0 -0
  37. data/doc/guide/src/basics/log_replay/goForward_3.png +0 -0
  38. data/doc/guide/src/basics/log_replay/goForward_4.png +0 -0
  39. data/doc/guide/src/basics/log_replay/goForward_5.png +0 -0
  40. data/doc/guide/src/basics/log_replay/hierarchy_error_1.png +0 -0
  41. data/doc/guide/src/basics/log_replay/hierarchy_error_2.png +0 -0
  42. data/doc/guide/src/basics/log_replay/hierarchy_error_3.png +0 -0
  43. data/doc/guide/src/basics/log_replay/plan_repair_1.png +0 -0
  44. data/doc/guide/src/basics/log_replay/plan_repair_2.png +0 -0
  45. data/doc/guide/src/basics/log_replay/plan_repair_3.png +0 -0
  46. data/doc/guide/src/basics/log_replay/plan_repair_4.png +0 -0
  47. data/doc/guide/src/basics/log_replay/roby_log_main_window.png +0 -0
  48. data/doc/guide/src/basics/log_replay/roby_log_relation_window.png +0 -0
  49. data/doc/guide/src/basics/log_replay/roby_replay_event_representation.png +0 -0
  50. data/doc/guide/src/basics/plan_objects.page +71 -0
  51. data/doc/guide/src/basics/relations_display.page +203 -0
  52. data/doc/guide/src/basics/roby_cycle_overview.png +0 -0
  53. data/doc/guide/src/basics/shell.page +102 -0
  54. data/doc/guide/src/basics/summary.page +32 -0
  55. data/doc/guide/src/basics/tasks.page +357 -0
  56. data/doc/guide/src/basics_shell_header.txt +16 -0
  57. data/doc/guide/src/cycle/cycle-overview.png +0 -0
  58. data/doc/guide/src/cycle/cycle-overview.svg +208 -0
  59. data/doc/guide/src/cycle/error_handling.page +168 -0
  60. data/doc/guide/src/cycle/error_instantaneous_repair.png +0 -0
  61. data/doc/guide/src/cycle/error_instantaneous_repair.svg +1224 -0
  62. data/doc/guide/src/cycle/garbage_collection.page +10 -0
  63. data/doc/guide/src/cycle/index.page +23 -0
  64. data/doc/guide/src/cycle/propagation.page +154 -0
  65. data/doc/guide/src/cycle/propagation_diamond.png +0 -0
  66. data/doc/guide/src/cycle/propagation_diamond.svg +1279 -0
  67. data/doc/guide/src/default.css +319 -0
  68. data/doc/guide/src/default.template +74 -0
  69. data/doc/guide/src/htmldoc.metainfo +20 -0
  70. data/doc/guide/src/htmldoc.virtual +18 -0
  71. data/doc/guide/src/images/bodybg.png +0 -0
  72. data/doc/guide/src/images/contbg.png +0 -0
  73. data/doc/guide/src/images/footerbg.png +0 -0
  74. data/doc/guide/src/images/gradient1.png +0 -0
  75. data/doc/guide/src/images/gradient2.png +0 -0
  76. data/doc/guide/src/index.page +7 -0
  77. data/doc/guide/src/introduction/index.page +29 -0
  78. data/doc/guide/src/introduction/install.page +133 -0
  79. data/doc/{papers.rdoc → guide/src/introduction/publications.page} +5 -2
  80. data/doc/{videos.rdoc → guide/src/introduction/videos.page} +4 -2
  81. data/doc/guide/src/plugins/fault_tolerance.page +44 -0
  82. data/doc/guide/src/plugins/index.page +11 -0
  83. data/doc/guide/src/plugins/subsystems.page +45 -0
  84. data/doc/guide/src/relations/dependency.page +89 -0
  85. data/doc/guide/src/relations/index.page +12 -0
  86. data/doc/misc/update_github +24 -0
  87. data/doc/tutorials/02-GoForward.rdoc +3 -3
  88. data/ext/graph/graph.cc +46 -0
  89. data/lib/roby.rb +57 -22
  90. data/lib/roby/app.rb +132 -112
  91. data/lib/roby/app/plugins/rake.rb +21 -0
  92. data/lib/roby/app/rake.rb +0 -7
  93. data/lib/roby/app/run.rb +1 -1
  94. data/lib/roby/app/scripts/distributed.rb +1 -2
  95. data/lib/roby/app/scripts/generate/bookmarks.rb +1 -1
  96. data/lib/roby/app/scripts/results.rb +2 -1
  97. data/lib/roby/app/scripts/run.rb +6 -2
  98. data/lib/roby/app/scripts/shell.rb +11 -11
  99. data/lib/roby/config.rb +1 -1
  100. data/lib/roby/decision_control.rb +62 -3
  101. data/lib/roby/distributed.rb +4 -0
  102. data/lib/roby/distributed/base.rb +8 -0
  103. data/lib/roby/distributed/communication.rb +12 -8
  104. data/lib/roby/distributed/connection_space.rb +61 -44
  105. data/lib/roby/distributed/distributed_object.rb +1 -1
  106. data/lib/roby/distributed/notifications.rb +22 -30
  107. data/lib/roby/distributed/peer.rb +13 -8
  108. data/lib/roby/distributed/proxy.rb +5 -5
  109. data/lib/roby/distributed/subscription.rb +4 -4
  110. data/lib/roby/distributed/transaction.rb +3 -3
  111. data/lib/roby/event.rb +176 -110
  112. data/lib/roby/exceptions.rb +12 -4
  113. data/lib/roby/execution_engine.rb +1604 -0
  114. data/lib/roby/external_process_task.rb +225 -0
  115. data/lib/roby/graph.rb +0 -6
  116. data/lib/roby/interface.rb +221 -137
  117. data/lib/roby/log/console.rb +5 -3
  118. data/lib/roby/log/data_stream.rb +94 -16
  119. data/lib/roby/log/dot.rb +8 -8
  120. data/lib/roby/log/event_stream.rb +13 -3
  121. data/lib/roby/log/file.rb +43 -18
  122. data/lib/roby/log/gui/basic_display_ui.rb +89 -0
  123. data/lib/roby/log/gui/chronicle_view_ui.rb +90 -0
  124. data/lib/roby/log/gui/data_displays.rb +4 -5
  125. data/lib/roby/log/gui/data_displays_ui.rb +146 -0
  126. data/lib/roby/log/gui/relations.rb +18 -18
  127. data/lib/roby/log/gui/relations_ui.rb +120 -0
  128. data/lib/roby/log/gui/relations_view_ui.rb +144 -0
  129. data/lib/roby/log/gui/replay.rb +41 -13
  130. data/lib/roby/log/gui/replay_controls.rb +3 -0
  131. data/lib/roby/log/gui/replay_controls.ui +133 -110
  132. data/lib/roby/log/gui/replay_controls_ui.rb +249 -0
  133. data/lib/roby/log/hooks.rb +19 -18
  134. data/lib/roby/log/logger.rb +7 -6
  135. data/lib/roby/log/notifications.rb +4 -4
  136. data/lib/roby/log/plan_rebuilder.rb +20 -22
  137. data/lib/roby/log/relations.rb +44 -16
  138. data/lib/roby/log/server.rb +1 -4
  139. data/lib/roby/log/timings.rb +88 -19
  140. data/lib/roby/plan-object.rb +135 -11
  141. data/lib/roby/plan.rb +408 -224
  142. data/lib/roby/planning/loops.rb +32 -25
  143. data/lib/roby/planning/model.rb +157 -51
  144. data/lib/roby/planning/task.rb +47 -20
  145. data/lib/roby/query.rb +128 -92
  146. data/lib/roby/relations.rb +254 -136
  147. data/lib/roby/relations/conflicts.rb +6 -9
  148. data/lib/roby/relations/dependency.rb +358 -0
  149. data/lib/roby/relations/ensured.rb +0 -1
  150. data/lib/roby/relations/error_handling.rb +0 -1
  151. data/lib/roby/relations/events.rb +0 -2
  152. data/lib/roby/relations/executed_by.rb +26 -11
  153. data/lib/roby/relations/planned_by.rb +14 -14
  154. data/lib/roby/robot.rb +46 -0
  155. data/lib/roby/schedulers/basic.rb +34 -0
  156. data/lib/roby/standalone.rb +4 -0
  157. data/lib/roby/standard_errors.rb +21 -15
  158. data/lib/roby/state/events.rb +5 -4
  159. data/lib/roby/support.rb +107 -6
  160. data/lib/roby/task-operations.rb +23 -19
  161. data/lib/roby/task.rb +522 -148
  162. data/lib/roby/task_index.rb +80 -0
  163. data/lib/roby/test/common.rb +283 -44
  164. data/lib/roby/test/distributed.rb +53 -37
  165. data/lib/roby/test/testcase.rb +9 -204
  166. data/lib/roby/test/tools.rb +3 -3
  167. data/lib/roby/transactions.rb +154 -111
  168. data/lib/roby/transactions/proxy.rb +40 -7
  169. data/manifest.xml +20 -0
  170. data/plugins/fault_injection/README.txt +0 -3
  171. data/plugins/fault_injection/Rakefile +2 -8
  172. data/plugins/fault_injection/app.rb +1 -1
  173. data/plugins/fault_injection/fault_injection.rb +3 -3
  174. data/plugins/fault_injection/test/test_fault_injection.rb +19 -25
  175. data/plugins/subsystems/README.txt +0 -3
  176. data/plugins/subsystems/Rakefile +2 -7
  177. data/plugins/subsystems/app.rb +27 -16
  178. data/plugins/subsystems/test/app/config/init.rb +3 -0
  179. data/plugins/subsystems/test/app/planners/main.rb +1 -1
  180. data/plugins/subsystems/test/app/tasks/services.rb +1 -1
  181. data/plugins/subsystems/test/test_subsystems.rb +23 -16
  182. data/test/distributed/test_communication.rb +32 -15
  183. data/test/distributed/test_connection.rb +28 -26
  184. data/test/distributed/test_execution.rb +59 -54
  185. data/test/distributed/test_mixed_plan.rb +34 -34
  186. data/test/distributed/test_plan_notifications.rb +26 -26
  187. data/test/distributed/test_protocol.rb +57 -48
  188. data/test/distributed/test_query.rb +11 -7
  189. data/test/distributed/test_remote_plan.rb +71 -71
  190. data/test/distributed/test_transaction.rb +50 -47
  191. data/test/mockups/external_process +28 -0
  192. data/test/planning/test_loops.rb +163 -119
  193. data/test/planning/test_model.rb +3 -3
  194. data/test/planning/test_task.rb +27 -7
  195. data/test/relations/test_conflicts.rb +3 -3
  196. data/test/relations/test_dependency.rb +324 -0
  197. data/test/relations/test_ensured.rb +2 -2
  198. data/test/relations/test_executed_by.rb +94 -19
  199. data/test/relations/test_planned_by.rb +11 -9
  200. data/test/suite_core.rb +6 -3
  201. data/test/suite_distributed.rb +1 -0
  202. data/test/suite_planning.rb +1 -0
  203. data/test/suite_relations.rb +2 -2
  204. data/test/tasks/test_external_process.rb +126 -0
  205. data/test/{test_thread_task.rb → tasks/test_thread_task.rb} +17 -20
  206. data/test/test_bgl.rb +21 -1
  207. data/test/test_event.rb +229 -155
  208. data/test/test_exceptions.rb +79 -80
  209. data/test/test_execution_engine.rb +987 -0
  210. data/test/test_gui.rb +1 -1
  211. data/test/test_interface.rb +11 -5
  212. data/test/test_log.rb +18 -7
  213. data/test/test_log_server.rb +1 -0
  214. data/test/test_plan.rb +229 -395
  215. data/test/test_query.rb +193 -35
  216. data/test/test_relations.rb +88 -8
  217. data/test/test_state.rb +55 -37
  218. data/test/test_support.rb +1 -1
  219. data/test/test_task.rb +371 -218
  220. data/test/test_testcase.rb +32 -16
  221. data/test/test_transactions.rb +211 -170
  222. data/test/test_transactions_proxy.rb +37 -19
  223. metadata +169 -71
  224. data/.gitignore +0 -29
  225. data/doc/styles/allison.css +0 -314
  226. data/doc/styles/allison.js +0 -316
  227. data/doc/styles/allison.rb +0 -276
  228. data/doc/styles/jamis.rb +0 -593
  229. data/lib/roby/control.rb +0 -746
  230. data/lib/roby/executives/simple.rb +0 -30
  231. data/lib/roby/propagation.rb +0 -562
  232. data/lib/roby/relations/hierarchy.rb +0 -239
  233. data/lib/roby/transactions/updates.rb +0 -139
  234. data/test/relations/test_hierarchy.rb +0 -158
  235. data/test/test_control.rb +0 -399
  236. data/test/test_propagation.rb +0 -210
@@ -1,239 +0,0 @@
1
- require 'roby/task'
2
- require 'roby/control'
3
- require 'set'
4
-
5
- module Roby::TaskStructure
6
- # Document-module: Hierarchy
7
- relation :Hierarchy, :child_name => :child, :parent_name => :parent_task do
8
- # True if +obj+ is a parent of this object in the hierarchy relation
9
- # (+obj+ is realized by +self+)
10
- def realizes?(obj); parent_object?(obj, Hierarchy) end
11
- # True if +obj+ is a child of this object in the hierarchy relation
12
- def realized_by?(obj); child_object?(obj, Hierarchy) end
13
- # True if +obj+ can be reached through the Hierarchy relation by
14
- # starting from this object
15
- def depends_on?(obj)
16
- generated_subgraph(Hierarchy).include?(obj)
17
- end
18
- # The set of parent objects in the Hierarchy relation
19
- def parents; parent_objects(Hierarchy) end
20
- # The set of child objects in the Hierarchy relation
21
- def children; child_objects(Hierarchy) end
22
-
23
-
24
- # Adds +task+ as a child of +self+ in the Hierarchy relation. The
25
- # following options are allowed:
26
- #
27
- # success:: the list of success events. The default is [:success]
28
- # failure:: the list of failing events. The default is [:failed]
29
- # model:: a <tt>[task_model, arguments]</tt> pair which defines the task model the parent is expecting.
30
- # The default value is to get these parameters from +task+
31
- #
32
- # The +success+ set describes the events of the child task that are
33
- # _required_ by the parent task. More specifically, the child task
34
- # remains useful for the parent task as long as none of these events are
35
- # emitted. By default, it is the +success+ event. Of course, an error
36
- # condition is encountered when all events of +success+ become
37
- # unreachable. In addition, the relation is removed if the
38
- # +remove_when_done+ flag is set to true (false by default).
39
- #
40
- # The +failure+ set describes the events of the child task which are an
41
- # error condition from the parent task point of view.
42
- #
43
- # In both error cases, a +ChildFailedError+ exception is raised.
44
- def realized_by(task, options = {})
45
- options = validate_options options,
46
- :model => [task.model, task.meaningful_arguments],
47
- :success => [:success],
48
- :failure => [:failed],
49
- :remove_when_done => false
50
-
51
- options[:success] = Array[*options[:success]]
52
- options[:failure] = Array[*options[:failure]]
53
-
54
- # Validate failure and success event names
55
- options[:success].each { |ev| task.event(ev) }
56
- options[:failure].each { |ev| task.event(ev) }
57
-
58
- options[:model] = [options[:model], {}] unless Array === options[:model]
59
- required_model, required_args = *options[:model]
60
- if !task.fullfills?(required_model, required_args)
61
- raise ArgumentError, "task #{task} does not fullfills the provided model #{options[:model]}"
62
- end
63
-
64
- add_child(task, options)
65
- self
66
- end
67
-
68
- # Set up the event gathering needed by Hierarchy.check_structure
69
- def added_child_object(child, relations, info) # :nodoc:
70
- super if defined? super
71
- if relations.include?(Hierarchy) && !respond_to?(:__getobj__) && !child.respond_to?(:__getobj__)
72
- events = info[:success].map { |ev| child.event(ev) }
73
- events.concat info[:failure].map { |ev| child.event(ev) }
74
- Roby::EventGenerator.gather_events(Hierarchy.interesting_events, events)
75
- end
76
- end
77
-
78
- # Return the set of this task children for which the :start event has
79
- # no parent in CausalLinks
80
- def first_children
81
- result = ValueSet.new
82
-
83
- generated_subgraph(Hierarchy).each do |task|
84
- next if task == self
85
- if task.event(:start).root?(Roby::EventStructure::CausalLink)
86
- result << task
87
- end
88
- end
89
- result
90
- end
91
-
92
- # The set of events that are needed by the parent tasks
93
- def fullfilled_events
94
- needed = ValueSet.new
95
- each_parent_task do |parent|
96
- needed.merge(parent[self, Hierarchy][:success])
97
- end
98
- needed
99
- end
100
-
101
- # Return [tags, arguments] where +tags+ is a list of task models which
102
- # are required by the parent tasks of this task, and arguments the
103
- # required arguments
104
- #
105
- # If there is a task class in the required models, it is always the
106
- # first element of +tags+
107
- def fullfilled_model
108
- model, tags, arguments = Roby::Task, [], {}
109
-
110
- each_parent_task do |parent|
111
- m, a = parent[self, Hierarchy][:model]
112
- if m.instance_of?(Roby::TaskModelTag)
113
- tags << m
114
- elsif m.has_ancestor?(model)
115
- model = m
116
- elsif !model.has_ancestor?(m)
117
- raise "inconsistency in fullfilled models: #{model} and #{m} are incompatible"
118
- end
119
- a.merge!(arguments) do |old, new|
120
- if old != new
121
- raise "inconsistency in fullfilled models: #{old} and #{new}"
122
- end
123
- end
124
- end
125
-
126
- tags.unshift(model)
127
- [tags, arguments]
128
- end
129
-
130
- # Remove all children that have successfully finished
131
- def remove_finished_children
132
- # We call #to_a to get a copy of children, since we will remove
133
- # children in the block. Note that we can't use #delete_if here
134
- # since #children is a relation enumerator (not the relation list
135
- # itself)
136
- children.to_a.each do |child|
137
- success_events = self[child, Hierarchy][:success]
138
- if success_events.any? { |ev| child.event(ev).happened? }
139
- remove_child(child)
140
- end
141
- end
142
- end
143
- end
144
-
145
- # Checks the structure of +plan+ w.r.t. the constraints of the hierarchy
146
- # relations. It returns an array of ChildFailedError for all failed
147
- # hierarchy relations
148
- def Hierarchy.check_structure(plan)
149
- result = []
150
-
151
- events = Hierarchy.interesting_events
152
- return result if events.empty? && failing_tasks.empty?
153
-
154
- # Get the set of tasks for which a possible failure has been
155
- # registered The tasks that are failing the hierarchy requirements
156
- # are registered in Hierarchy.failing_tasks. The interesting_events
157
- # set is cleared at cycle end (see below)
158
- tasks = events.inject(failing_tasks) { |set, event| set << event.generator.task }
159
- @failing_tasks = ValueSet.new
160
- tasks.each do |child|
161
- # Check if the task has been removed from the plan
162
- next unless child.plan
163
-
164
- has_error = false
165
- child.each_parent_task do |parent|
166
- next unless parent.self_owned?
167
- next if parent.finished? || parent.finishing?
168
-
169
- options = parent[child, Hierarchy]
170
- success = options[:success]
171
- failure = options[:failure]
172
-
173
- if success.any? { |e| child.event(e).happened? }
174
- if options[:remove_when_done]
175
- parent.remove_child child
176
- end
177
- elsif failing_event = failure.find { |e| child.event(e).happened? }
178
- result << Roby::ChildFailedError.new(parent, child.event(failing_event).last)
179
- failing_tasks << child
180
- end
181
- end
182
- end
183
-
184
- events.clear
185
- result
186
- end
187
-
188
- class << Hierarchy
189
- # The set of events that have been fired in this cycle and are involved in a Hierarchy relation
190
- attribute(:interesting_events) { Array.new }
191
-
192
- # The set of tasks that are currently failing
193
- attribute(:failing_tasks) { ValueSet.new }
194
- end
195
- end
196
-
197
- module Roby
198
- # This exception is raised when a {hierarchy relation}[classes/Roby/TaskStructure/Hierarchy.html] fails
199
- class ChildFailedError < LocalizedError
200
- # The parent in the relation
201
- attr_reader :parent
202
- # The child in the relation
203
- def child; failed_task end
204
- # The relation parameters (i.e. the hash given to #realized_by)
205
- attr_reader :relation
206
-
207
- # The event which is the cause of this error. This is either the task
208
- # source of a failure event, or the reason why a positive event has
209
- # become unreachable (if there is one)
210
- def initialize(parent, event)
211
- super(event.task_sources.find { true })
212
- @parent = parent
213
- @relation = parent[child, TaskStructure::Hierarchy]
214
- end
215
-
216
- def pretty_print(pp) # :nodoc:
217
- super
218
- pp.breakable
219
- pp.breakable
220
- pp.text "The failed relation is"
221
- pp.breakable
222
- pp.nest(2) do
223
- pp.text " "
224
- parent.pretty_print pp
225
- pp.breakable
226
- pp.text "realized_by "
227
- child.pretty_print pp
228
- end
229
- end
230
- def backtrace; [] end
231
-
232
- # True if +obj+ is involved in this exception
233
- def involved_plan_object?(obj)
234
- super || obj == parent
235
- end
236
- end
237
- Control.structure_checks << TaskStructure::Hierarchy.method(:check_structure)
238
- end
239
-
@@ -1,139 +0,0 @@
1
- module Roby
2
- class SolverInvalidateTransaction
3
- def self.finalized_plan_task(trsc, task); end
4
- def self.finalized_plan_event(trsc, task); end
5
-
6
- def self.adding_plan_relation(trsc, parent, child, relations, info)
7
- end
8
- def self.removing_plan_relation(trsc, parent, child, relations)
9
- end
10
- end
11
-
12
- class SolverUpdateRelations
13
- def self.finalized_plan_task(trsc, task)
14
- end
15
- def self.finalized_plan_event(trsc, task)
16
- end
17
-
18
- def self.adding_plan_relation(trsc, parent, child, relations, info)
19
- parent_proxy = trsc.wrap(parent)
20
- child_proxy = trsc.wrap(child)
21
- for rel in relations
22
- rel.link(parent_proxy, child_proxy, info)
23
- end
24
- trsc.invalid = false
25
- end
26
- def self.removing_plan_relation(trsc, parent, child, relations)
27
- parent_proxy = trsc.wrap(parent)
28
- child_proxy = trsc.wrap(child)
29
- for rel in relations
30
- rel.unlink(parent_proxy, child_proxy)
31
- end
32
- trsc.invalid = false
33
- end
34
- end
35
-
36
- class SolverIgnoreUpdate
37
- def finalized_plan_task(trsc, task)
38
- Roby.debug "#{trsc} is valid again"
39
- trsc.invalid = false
40
- end
41
- def finalized_plan_event(trsc, task)
42
- Roby.debug "#{trsc} is valid again"
43
- trsc.invalid = false
44
- end
45
-
46
- def adding_plan_relation(trsc, parent, child, relations, info)
47
- Roby.debug "#{trsc} is valid again"
48
- trsc.invalid = false
49
- end
50
- def removing_plan_relation(trsc, parent, child, relations)
51
- Roby.debug "#{trsc} is valid again"
52
- trsc.invalid = false
53
- end
54
- end
55
- class Transaction
56
- def finalized_plan_task(task)
57
- invalidate("task #{task} has been removed from the plan")
58
- discard_modifications(task)
59
- conflict_solver.finalized_plan_task(self, task)
60
- end
61
-
62
- def finalized_plan_event(event)
63
- invalidate("event #{event} has been removed from the plan")
64
- discard_modifications(event)
65
- conflict_solver.finalized_plan_event(self, event)
66
- end
67
-
68
- def adding_plan_relation(parent, child, relations, info)
69
- missing_relations = relations.find_all do |rel|
70
- !parent.child_object?(child, rel)
71
- end
72
- unless missing_relations.empty?
73
- invalidate("plan added a relation #{parent} -> #{child} in #{relations} with info #{info}")
74
- conflict_solver.adding_plan_relation(self, parent, child, relations, info)
75
- end
76
- end
77
-
78
- def removing_plan_relation(parent, child, relations)
79
- present_relations = relations.find_all do |rel|
80
- parent.child_object?(child, rel)
81
- end
82
- unless present_relations.empty?
83
- invalidate("plan removed the #{parent} -> #{child} relation in #{relations}")
84
- conflict_solver.removing_plan_relation(self, parent, child, relations)
85
- end
86
- end
87
- end
88
-
89
- module Transactions
90
- module PlanUpdates
91
- def self.finalized_object(plan, object)
92
- return unless object.root_object?
93
- plan.transactions.each do |trsc|
94
- next unless trsc.proxying?
95
-
96
- if proxy = trsc.wrap(object, false)
97
- yield(trsc, proxy)
98
- end
99
- end
100
- end
101
- def finalized_event(event)
102
- super if defined? super
103
- PlanUpdates.finalized_object(self, event) { |trsc, proxy| trsc.finalized_plan_event(proxy) }
104
- end
105
- def finalized_task(task)
106
- super if defined? super
107
- PlanUpdates.finalized_object(self, task) { |trsc, proxy| trsc.finalized_plan_task(proxy) }
108
- end
109
- end
110
- Roby::Plan.include PlanUpdates
111
-
112
- module PlanObjectUpdates
113
- def adding_child_object(child, relations, info)
114
- super if defined? super
115
- return if !plan
116
-
117
- for trsc in plan.transactions
118
- next unless trsc.proxying?
119
- if (parent_proxy = trsc[self, false]) && (child_proxy = trsc[child, false])
120
- trsc.adding_plan_relation(parent_proxy, child_proxy, relations, info)
121
- end
122
- end
123
- end
124
- def removing_child_object(child, relations)
125
- super if defined? super
126
- return if !plan
127
-
128
- plan.transactions.each do |trsc|
129
- next unless trsc.proxying?
130
- if (parent_proxy = trsc[self, false]) && (child_proxy = trsc[child, false])
131
- trsc.removing_plan_relation(parent_proxy, child_proxy, relations)
132
- end
133
- end
134
- end
135
- end
136
- Roby::PlanObject.include PlanObjectUpdates
137
- end
138
- end
139
-
@@ -1,158 +0,0 @@
1
- $LOAD_PATH.unshift File.expand_path('..', File.dirname(__FILE__))
2
- require 'roby/test/common'
3
- require 'roby/test/tasks/simple_task'
4
-
5
- class TC_RealizedBy < Test::Unit::TestCase
6
- include Roby::Test
7
-
8
- def test_definition
9
- tag = TaskModelTag.new
10
- klass = Class.new(SimpleTask) do
11
- argument :id
12
- include tag
13
- end
14
- plan.discover(t1 = SimpleTask.new)
15
-
16
- # Check validation of the model
17
- child = nil
18
- assert_nothing_raised { t1.realized_by((child = klass.new), :model => SimpleTask) }
19
-
20
- assert_same(Hierarchy.interesting_events, EventGenerator.event_gathering[child.event(:success)].find { true })
21
- assert_same(Hierarchy.interesting_events, EventGenerator.event_gathering[child.event(:failed)].find { true })
22
- assert_equal([SimpleTask, {}], t1[child, Hierarchy][:model])
23
-
24
- assert_nothing_raised { t1.realized_by klass.new, :model => [Roby::Task, {}] }
25
- assert_nothing_raised { t1.realized_by klass.new, :model => tag }
26
-
27
- plan.discover(simple_task = SimpleTask.new)
28
- assert_raises(ArgumentError) { t1.realized_by simple_task, :model => [Class.new(Roby::Task), {}] }
29
- assert_raises(ArgumentError) { t1.realized_by simple_task, :model => TaskModelTag.new }
30
-
31
- # Check validation of the arguments
32
- plan.discover(model_task = klass.new)
33
- assert_raises(ArgumentError) { t1.realized_by model_task, :model => [SimpleTask, {:id => 'bad'}] }
34
-
35
- plan.discover(child = klass.new(:id => 'good'))
36
- assert_raises(ArgumentError) { t1.realized_by child, :model => [klass, {:id => 'bad'}] }
37
- assert_nothing_raised { t1.realized_by child, :model => [klass, {:id => 'good'}] }
38
- assert_equal([klass, { :id => 'good' }], t1[child, TaskStructure::Hierarchy][:model])
39
-
40
- # Check edge annotation
41
- t2 = SimpleTask.new
42
- t1.realized_by t2, :model => SimpleTask
43
- assert_equal([SimpleTask, {}], t1[t2, TaskStructure::Hierarchy][:model])
44
- t2 = klass.new(:id => 10)
45
- t1.realized_by t2, :model => [klass, { :id => 10 }]
46
- end
47
-
48
- Hierarchy = TaskStructure::Hierarchy
49
-
50
- def assert_children_failed(children, plan)
51
- result = Hierarchy.check_structure(plan)
52
- assert_equal(children.to_set, result.map { |e| e.failed_task }.to_set)
53
- end
54
-
55
- def test_failure_point
56
- model = Class.new(SimpleTask) do
57
- event :specialized_failure, :command => true
58
- forward :specialized_failure => :failed
59
- end
60
- parent, child = prepare_plan :discover => 1, :tasks => 1, :model => model
61
- parent.realized_by child
62
-
63
- parent.start!
64
- child.start!
65
- child.specialized_failure!
66
-
67
- error = Hierarchy.check_structure(plan).first.exception
68
- assert_kind_of(ChildFailedError, error)
69
- assert_equal(child.event(:specialized_failure).last, error.failure_point)
70
- assert_equal(child.event(:specialized_failure).last, error.failed_event)
71
-
72
- parent.stop!
73
- end
74
-
75
- def test_exception_printing
76
- parent, child = prepare_plan :discover => 2, :model => SimpleTask
77
- parent.realized_by child
78
- parent.start!
79
- child.start!
80
- child.failed!
81
-
82
- error = Hierarchy.check_structure(plan).first.exception
83
- assert_kind_of(ChildFailedError, error)
84
- assert_nothing_raised do
85
- Roby.format_exception(error)
86
- end
87
-
88
- parent.stop!
89
- end
90
-
91
- def test_structure_checking
92
- child_model = Class.new(SimpleTask) do
93
- event :first, :command => true
94
- event :second, :command => true
95
- end
96
-
97
- p1 = SimpleTask.new
98
- child = child_model.new
99
- plan.discover([p1, child])
100
- p1.realized_by child
101
- plan.insert(p1)
102
-
103
- child.start!; p1.start!
104
- assert_equal([], Hierarchy.check_structure(plan))
105
- child.stop!
106
- assert_equal([child.event(:failed).last], Hierarchy.interesting_events)
107
- assert_children_failed([child], plan)
108
-
109
- plan.clear
110
- p1 = SimpleTask.new
111
- child = child_model.new
112
- plan.discover([p1, child])
113
- p1.realized_by child, :success => [:second], :failure => [:first]
114
- plan.insert(p1)
115
- child.start! ; p1.start!
116
- child.event(:first).emit(nil)
117
- assert_children_failed([child], plan)
118
-
119
- plan.clear
120
- p1 = SimpleTask.new
121
- child = child_model.new
122
- plan.discover([p1, child])
123
- p1.realized_by child, :success => [:first], :failure => [:second]
124
- plan.insert(p1)
125
- child.start! ; p1.start!
126
- child.event(:first).emit(nil)
127
- assert_children_failed([], plan)
128
- child.event(:second).emit(nil)
129
- assert_children_failed([], plan)
130
- end
131
-
132
- def test_fullfilled_model
133
- tag = TaskModelTag.new
134
- klass = Class.new(SimpleTask) do
135
- include tag
136
- end
137
-
138
- p1, p2, child = prepare_plan :discover => 3, :model => klass
139
-
140
- p1.realized_by child, :model => SimpleTask
141
- p2.realized_by child, :model => Roby::Task
142
- assert_equal([[SimpleTask], {}], child.fullfilled_model)
143
- p1.remove_child(child)
144
- assert_equal([[Roby::Task], {}], child.fullfilled_model)
145
- p1.realized_by child, :model => tag
146
- assert_equal([[Roby::Task, tag], {}], child.fullfilled_model)
147
- end
148
-
149
- def test_first_children
150
- p, c1, c2 = prepare_plan :discover => 3, :model => SimpleTask
151
- p.realized_by c1
152
- p.realized_by c2
153
- assert_equal([c1, c2].to_value_set, p.first_children)
154
-
155
- c1.on(:start, c2, :start)
156
- assert_equal([c1].to_value_set, p.first_children)
157
- end
158
- end