roby 0.8.0 → 3.0.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 (644) hide show
  1. checksums.yaml +7 -0
  2. data/.deep-cover.rb +3 -0
  3. data/.gitattributes +1 -0
  4. data/.gitignore +24 -0
  5. data/.simplecov +10 -0
  6. data/.travis.yml +17 -0
  7. data/.yardopts +4 -0
  8. data/Gemfile +15 -0
  9. data/README.md +11 -0
  10. data/Rakefile +47 -177
  11. data/benchmark/{alloc_misc.rb → attic/alloc_misc.rb} +2 -2
  12. data/benchmark/{discovery_latency.rb → attic/discovery_latency.rb} +19 -19
  13. data/benchmark/{garbage_collection.rb → attic/garbage_collection.rb} +9 -9
  14. data/benchmark/{genom.rb → attic/genom.rb} +0 -0
  15. data/benchmark/attic/transactions.rb +62 -0
  16. data/benchmark/plan_basic_operations.rb +28 -0
  17. data/benchmark/relations/graph.rb +63 -0
  18. data/benchmark/ruby/identity.rb +18 -0
  19. data/benchmark/ruby/set_intersect_vs_hash_merge.rb +39 -0
  20. data/benchmark/ruby/yield_vs_block.rb +35 -0
  21. data/benchmark/run +5 -0
  22. data/benchmark/synthetic_plan_modifications_with_transactions.rb +79 -0
  23. data/benchmark/transactions.rb +99 -51
  24. data/bin/roby +38 -197
  25. data/bin/roby-display +14 -0
  26. data/bin/roby-log +3 -176
  27. data/doc/guide/{src → attic}/abstraction/achieve_with.page +1 -1
  28. data/doc/guide/{src → attic}/abstraction/forwarding.page +1 -1
  29. data/doc/guide/{src → attic}/abstraction/hierarchy.page +1 -1
  30. data/doc/guide/{src → attic}/abstraction/index.page +1 -1
  31. data/doc/guide/{src → attic}/abstraction/task_models.page +1 -1
  32. data/doc/guide/{overview.rdoc → attic/cycle/api_overview.rdoc} +6 -1
  33. data/doc/guide/{src → attic}/cycle/cycle-overview.png +0 -0
  34. data/doc/guide/{src → attic}/cycle/cycle-overview.svg +0 -0
  35. data/doc/guide/attic/cycle/error_handling.page +98 -0
  36. data/doc/guide/{src → attic}/cycle/error_instantaneous_repair.png +0 -0
  37. data/doc/guide/{src → attic}/cycle/error_instantaneous_repair.svg +0 -0
  38. data/doc/guide/{src/cycle/error_handling.page → attic/cycle/error_sources.page} +46 -89
  39. data/doc/guide/{src → attic}/cycle/garbage_collection.page +1 -1
  40. data/doc/guide/{src → attic}/cycle/index.page +1 -1
  41. data/doc/guide/{src → attic}/cycle/propagation.page +11 -1
  42. data/doc/guide/{src → attic}/cycle/propagation_diamond.png +0 -0
  43. data/doc/guide/{src → attic}/cycle/propagation_diamond.svg +0 -0
  44. data/doc/guide/attic/plans/building_plans.page +89 -0
  45. data/doc/guide/attic/plans/code.page +192 -0
  46. data/doc/guide/{src/basics → attic/plans}/events.page +3 -4
  47. data/doc/guide/attic/plans/index.page +7 -0
  48. data/doc/guide/{plan_modifications.rdoc → attic/plans/plan_modifications.rdoc} +5 -3
  49. data/doc/guide/{src/basics → attic/plans}/plan_objects.page +2 -1
  50. data/doc/guide/attic/plans/querying_plans.page +5 -0
  51. data/doc/guide/{src/basics → attic/plans}/tasks.page +20 -20
  52. data/doc/guide/config.yaml +7 -4
  53. data/doc/guide/ext/extended_menu.rb +29 -0
  54. data/doc/guide/ext/init.rb +6 -0
  55. data/doc/guide/ext/rdoc_links.rb +7 -6
  56. data/doc/guide/src/advanced_concepts/history.page +5 -0
  57. data/doc/guide/src/advanced_concepts/index.page +11 -0
  58. data/doc/guide/src/advanced_concepts/recognizing_patterns.page +83 -0
  59. data/doc/guide/src/advanced_concepts/scheduling.page +87 -0
  60. data/doc/guide/src/advanced_concepts/transactions.page +5 -0
  61. data/doc/guide/src/advanced_concepts/unreachability.page +42 -0
  62. data/doc/guide/src/base.template +96 -0
  63. data/doc/guide/src/basics_shell_header.txt +5 -7
  64. data/doc/guide/src/building/action_coordination.page +96 -0
  65. data/doc/guide/src/building/actions.page +124 -0
  66. data/doc/guide/src/building/file_layout.page +71 -0
  67. data/doc/guide/src/building/index.page +50 -0
  68. data/doc/guide/src/building/patterns.page +86 -0
  69. data/doc/guide/src/building/patterns_forwarding.png +0 -0
  70. data/doc/guide/src/building/patterns_forwarding.svg +277 -0
  71. data/doc/guide/src/building/runtime.page +95 -0
  72. data/doc/guide/src/building/task_models.page +94 -0
  73. data/doc/guide/src/building/tasks.page +284 -0
  74. data/doc/guide/src/concepts/error_handling.page +100 -0
  75. data/doc/guide/src/concepts/exception_propagation.png +0 -0
  76. data/doc/guide/src/concepts/exception_propagation.svg +445 -0
  77. data/doc/guide/src/concepts/execution.page +85 -0
  78. data/doc/guide/src/concepts/execution.png +0 -0
  79. data/doc/guide/src/concepts/execution.svg +573 -0
  80. data/doc/guide/src/concepts/execution_cycle.png +0 -0
  81. data/doc/guide/src/concepts/garbage_collection.page +57 -0
  82. data/doc/guide/src/concepts/index.page +27 -0
  83. data/doc/guide/src/concepts/plans.page +101 -0
  84. data/doc/guide/src/concepts/policy.page +31 -0
  85. data/doc/guide/src/concepts/reactor.page +61 -0
  86. data/doc/guide/src/concepts/simple_plan_example.png +0 -0
  87. data/doc/guide/src/concepts/simple_plan_example.svg +376 -0
  88. data/doc/guide/src/default.template +9 -74
  89. data/doc/guide/src/event_relations/forward.page +71 -0
  90. data/doc/guide/src/event_relations/index.page +12 -0
  91. data/doc/guide/src/event_relations/scheduling_constraints.page +43 -0
  92. data/doc/guide/src/event_relations/signal.page +55 -0
  93. data/doc/guide/src/event_relations/temporal_constraints.page +77 -0
  94. data/doc/guide/src/htmldoc.metainfo +21 -8
  95. data/doc/guide/src/index.page +8 -3
  96. data/doc/guide/src/{introduction/install.page → installation/index.page} +37 -25
  97. data/doc/guide/src/installation/publications.page +14 -0
  98. data/doc/guide/src/{introduction → installation}/videos.page +14 -7
  99. data/doc/guide/src/interacting/index.page +16 -0
  100. data/doc/guide/src/interacting/run.page +33 -0
  101. data/doc/guide/src/interacting/shell.page +95 -0
  102. data/doc/guide/src/plugins/creating_plugins.page +72 -0
  103. data/doc/guide/src/plugins/index.page +27 -5
  104. data/doc/guide/src/plugins/{fault_tolerance.page → standard_plugins/fault_tolerance.page} +2 -2
  105. data/doc/guide/src/plugins/standard_plugins/index.page +11 -0
  106. data/doc/guide/src/plugins/{subsystems.page → standard_plugins/subsystems.page} +2 -2
  107. data/doc/guide/src/style_screen.css +687 -0
  108. data/doc/guide/src/task_relations/dependency.page +107 -0
  109. data/doc/guide/src/task_relations/executed_by.page +77 -0
  110. data/doc/guide/src/task_relations/index.page +12 -0
  111. data/doc/guide/src/task_relations/new_relations.page +119 -0
  112. data/doc/guide/src/task_relations/planned_by.page +46 -0
  113. data/doc/guide/src/tutorial/app.page +117 -0
  114. data/doc/guide/src/{basics → tutorial}/code_examples.page +6 -5
  115. data/doc/guide/src/{basics → tutorial}/dry.page +15 -15
  116. data/doc/guide/src/{basics → tutorial}/errors.page +43 -68
  117. data/doc/guide/src/tutorial/events.page +195 -0
  118. data/doc/guide/src/{basics → tutorial}/hierarchy.page +53 -52
  119. data/doc/guide/src/tutorial/index.page +13 -0
  120. data/doc/guide/src/tutorial/log_replay/goForward_1.png +0 -0
  121. data/doc/guide/src/tutorial/log_replay/goForward_2.png +0 -0
  122. data/doc/guide/src/tutorial/log_replay/goForward_3.png +0 -0
  123. data/doc/guide/src/{basics → tutorial}/log_replay/goForward_4.png +0 -0
  124. data/doc/guide/src/tutorial/log_replay/goForward_5.png +0 -0
  125. data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_1.png +0 -0
  126. data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_2.png +0 -0
  127. data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_3.png +0 -0
  128. data/doc/guide/src/tutorial/log_replay/moveto_code_error.png +0 -0
  129. data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_1.png +0 -0
  130. data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_2.png +0 -0
  131. data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_3.png +0 -0
  132. data/doc/guide/src/tutorial/log_replay/plan_repair_4.png +0 -0
  133. data/doc/guide/src/tutorial/log_replay/roby_log_main_window.png +0 -0
  134. data/doc/guide/src/{basics → tutorial}/log_replay/roby_log_relation_window.png +0 -0
  135. data/doc/guide/src/{basics → tutorial}/log_replay/roby_replay_event_representation.png +0 -0
  136. data/doc/guide/src/tutorial/relations_display.page +153 -0
  137. data/doc/guide/src/{basics → tutorial}/roby_cycle_overview.png +0 -0
  138. data/doc/guide/src/tutorial/shell.page +121 -0
  139. data/doc/guide/src/{basics → tutorial}/summary.page +1 -1
  140. data/doc/guide/src/tutorial/tasks.page +374 -0
  141. data/lib/roby.rb +102 -47
  142. data/lib/roby/actions.rb +17 -0
  143. data/lib/roby/actions/action.rb +80 -0
  144. data/lib/roby/actions/interface.rb +45 -0
  145. data/lib/roby/actions/library.rb +23 -0
  146. data/lib/roby/actions/models/action.rb +224 -0
  147. data/lib/roby/actions/models/coordination_action.rb +58 -0
  148. data/lib/roby/actions/models/interface.rb +22 -0
  149. data/lib/roby/actions/models/interface_base.rb +294 -0
  150. data/lib/roby/actions/models/library.rb +12 -0
  151. data/lib/roby/actions/models/method_action.rb +90 -0
  152. data/lib/roby/actions/task.rb +114 -0
  153. data/lib/roby/and_generator.rb +125 -0
  154. data/lib/roby/app.rb +2795 -829
  155. data/lib/roby/app/autotest_console_reporter.rb +138 -0
  156. data/lib/roby/app/base.rb +21 -0
  157. data/lib/roby/app/cucumber.rb +2 -0
  158. data/lib/roby/app/cucumber/controller.rb +439 -0
  159. data/lib/roby/app/cucumber/helpers.rb +280 -0
  160. data/lib/roby/app/cucumber/world.rb +32 -0
  161. data/lib/roby/app/debug.rb +136 -0
  162. data/lib/roby/app/gen.rb +2 -0
  163. data/lib/roby/app/rake.rb +178 -38
  164. data/lib/roby/app/robot_config.rb +9 -0
  165. data/lib/roby/app/robot_names.rb +115 -0
  166. data/lib/roby/app/run.rb +3 -2
  167. data/lib/roby/app/scripts.rb +72 -0
  168. data/lib/roby/app/scripts/autotest.rb +173 -0
  169. data/lib/roby/app/scripts/display.rb +2 -0
  170. data/lib/roby/app/scripts/restart.rb +52 -0
  171. data/lib/roby/app/scripts/results.rb +17 -8
  172. data/lib/roby/app/scripts/run.rb +155 -24
  173. data/lib/roby/app/scripts/shell.rb +147 -62
  174. data/lib/roby/app/scripts/test.rb +107 -22
  175. data/lib/roby/app/test_reporter.rb +74 -0
  176. data/lib/roby/app/test_server.rb +159 -0
  177. data/lib/roby/app/vagrant.rb +47 -0
  178. data/lib/roby/backports.rb +16 -0
  179. data/lib/roby/cli/display.rb +190 -0
  180. data/lib/roby/cli/exceptions.rb +17 -0
  181. data/lib/roby/cli/gen/actions/class.rb +5 -0
  182. data/lib/roby/cli/gen/actions/test.rb +6 -0
  183. data/lib/roby/cli/gen/app/.yardopts +6 -0
  184. data/lib/roby/cli/gen/app/README.md +28 -0
  185. data/lib/roby/cli/gen/app/Rakefile +15 -0
  186. data/{app → lib/roby/cli/gen/app}/config/app.yml +29 -39
  187. data/lib/roby/cli/gen/app/models/.gitattributes +1 -0
  188. data/{app → lib/roby/cli/gen/app/scripts}/controllers/.gitattributes +0 -0
  189. data/{app/data/.gitattributes → lib/roby/cli/gen/app/test/.gitignore} +0 -0
  190. data/lib/roby/cli/gen/class/class.rb +6 -0
  191. data/lib/roby/cli/gen/class/test.rb +7 -0
  192. data/lib/roby/cli/gen/helpers.rb +203 -0
  193. data/lib/roby/cli/gen/module/module.rb +5 -0
  194. data/lib/roby/cli/gen/module/test.rb +6 -0
  195. data/lib/roby/cli/gen/roby_app/config/init.rb +17 -0
  196. data/lib/roby/cli/gen/roby_app/config/robots/robot.rb +40 -0
  197. data/lib/roby/cli/gen/task/class.rb +44 -0
  198. data/lib/roby/cli/gen/task/test.rb +6 -0
  199. data/lib/roby/cli/gen_main.rb +120 -0
  200. data/lib/roby/cli/log.rb +276 -0
  201. data/lib/roby/cli/log/flamegraph.html +499 -0
  202. data/lib/roby/cli/log/flamegraph_renderer.rb +88 -0
  203. data/lib/roby/cli/main.rb +153 -0
  204. data/lib/roby/coordination.rb +60 -0
  205. data/lib/roby/coordination/action_script.rb +25 -0
  206. data/lib/roby/coordination/action_state_machine.rb +125 -0
  207. data/lib/roby/coordination/actions.rb +106 -0
  208. data/lib/roby/coordination/base.rb +145 -0
  209. data/lib/roby/coordination/calculus.rb +40 -0
  210. data/lib/roby/coordination/child.rb +28 -0
  211. data/lib/roby/coordination/event.rb +29 -0
  212. data/lib/roby/coordination/fault_handler.rb +25 -0
  213. data/lib/roby/coordination/fault_handling_task.rb +13 -0
  214. data/lib/roby/coordination/fault_response_table.rb +110 -0
  215. data/lib/roby/coordination/models/action_script.rb +64 -0
  216. data/lib/roby/coordination/models/action_state_machine.rb +224 -0
  217. data/lib/roby/coordination/models/actions.rb +191 -0
  218. data/lib/roby/coordination/models/arguments.rb +55 -0
  219. data/lib/roby/coordination/models/base.rb +176 -0
  220. data/lib/roby/coordination/models/capture.rb +86 -0
  221. data/lib/roby/coordination/models/child.rb +35 -0
  222. data/lib/roby/coordination/models/event.rb +41 -0
  223. data/lib/roby/coordination/models/exceptions.rb +42 -0
  224. data/lib/roby/coordination/models/fault_handler.rb +219 -0
  225. data/lib/roby/coordination/models/fault_response_table.rb +77 -0
  226. data/lib/roby/coordination/models/root.rb +22 -0
  227. data/lib/roby/coordination/models/script.rb +283 -0
  228. data/lib/roby/coordination/models/task.rb +184 -0
  229. data/lib/roby/coordination/models/task_from_action.rb +50 -0
  230. data/lib/roby/coordination/models/task_from_as_plan.rb +33 -0
  231. data/lib/roby/coordination/models/task_from_instanciation_object.rb +31 -0
  232. data/lib/roby/coordination/models/task_from_variable.rb +27 -0
  233. data/lib/roby/coordination/models/task_with_dependencies.rb +48 -0
  234. data/lib/roby/coordination/models/variable.rb +32 -0
  235. data/lib/roby/coordination/script.rb +200 -0
  236. data/lib/roby/coordination/script_instruction.rb +12 -0
  237. data/lib/roby/coordination/task.rb +45 -0
  238. data/lib/roby/coordination/task_base.rb +69 -0
  239. data/lib/roby/coordination/task_script.rb +293 -0
  240. data/lib/roby/coordination/task_state_machine.rb +308 -0
  241. data/lib/roby/decision_control.rb +33 -21
  242. data/lib/roby/distributed_object.rb +76 -0
  243. data/lib/roby/droby.rb +17 -0
  244. data/lib/roby/droby/droby_id.rb +6 -0
  245. data/lib/roby/droby/enable.rb +153 -0
  246. data/lib/roby/droby/event_logger.rb +189 -0
  247. data/lib/roby/droby/event_logging.rb +57 -0
  248. data/lib/roby/droby/exceptions.rb +14 -0
  249. data/lib/roby/droby/identifiable.rb +22 -0
  250. data/lib/roby/droby/logfile.rb +141 -0
  251. data/lib/roby/droby/logfile/client.rb +176 -0
  252. data/lib/roby/droby/logfile/file_format.md +97 -0
  253. data/lib/roby/droby/logfile/index.rb +117 -0
  254. data/lib/roby/droby/logfile/reader.rb +139 -0
  255. data/lib/roby/droby/logfile/server.rb +199 -0
  256. data/lib/roby/droby/logfile/writer.rb +114 -0
  257. data/lib/roby/droby/marshal.rb +264 -0
  258. data/lib/roby/droby/marshallable.rb +12 -0
  259. data/lib/roby/droby/null_event_logger.rb +25 -0
  260. data/lib/roby/droby/object_manager.rb +205 -0
  261. data/lib/roby/droby/peer_id.rb +6 -0
  262. data/lib/roby/droby/plan_rebuilder.rb +373 -0
  263. data/lib/roby/droby/rebuilt_plan.rb +160 -0
  264. data/lib/roby/droby/remote_droby_id.rb +6 -0
  265. data/lib/roby/droby/timepoints.rb +205 -0
  266. data/lib/roby/droby/timepoints_ctf.metadata.erb +101 -0
  267. data/lib/roby/droby/timepoints_ctf.rb +125 -0
  268. data/lib/roby/droby/v5.rb +14 -0
  269. data/lib/roby/droby/v5/builtin.rb +120 -0
  270. data/lib/roby/droby/v5/droby_class.rb +45 -0
  271. data/lib/roby/droby/v5/droby_constant.rb +81 -0
  272. data/lib/roby/droby/v5/droby_dump.rb +1026 -0
  273. data/lib/roby/droby/v5/droby_id.rb +44 -0
  274. data/lib/roby/droby/v5/droby_model.rb +82 -0
  275. data/lib/roby/droby/v5/peer_id.rb +10 -0
  276. data/lib/roby/droby/v5/remote_droby_id.rb +42 -0
  277. data/lib/roby/event.rb +79 -957
  278. data/lib/roby/event_constraints.rb +835 -0
  279. data/lib/roby/event_generator.rb +1047 -0
  280. data/lib/roby/event_structure/causal_link.rb +6 -0
  281. data/lib/roby/event_structure/forwarding.rb +6 -0
  282. data/lib/roby/event_structure/precedence.rb +7 -0
  283. data/lib/roby/event_structure/signal.rb +8 -0
  284. data/lib/roby/event_structure/temporal_constraints.rb +640 -0
  285. data/lib/roby/exceptions.rb +446 -152
  286. data/lib/roby/executable_plan.rb +549 -0
  287. data/lib/roby/execution_engine.rb +1997 -950
  288. data/lib/roby/filter_generator.rb +26 -0
  289. data/lib/roby/gui/chronicle_view.rb +225 -0
  290. data/lib/roby/gui/chronicle_widget.rb +925 -0
  291. data/lib/roby/gui/dot_id.rb +11 -0
  292. data/lib/roby/gui/exception_view.rb +44 -0
  293. data/lib/roby/gui/log_display.rb +273 -0
  294. data/lib/roby/gui/model_views.rb +2 -0
  295. data/lib/roby/gui/model_views/action_interface.rb +53 -0
  296. data/lib/roby/gui/model_views/task.rb +47 -0
  297. data/lib/roby/gui/model_views/task.rhtml +41 -0
  298. data/lib/roby/gui/object_info_view.rb +89 -0
  299. data/lib/roby/gui/plan_dot_layout.rb +427 -0
  300. data/lib/roby/gui/plan_rebuilder_widget.rb +357 -0
  301. data/lib/roby/gui/qt4_toMSecsSinceEpoch.rb +8 -0
  302. data/lib/roby/gui/relations_view.rb +278 -0
  303. data/lib/roby/gui/relations_view/relations.ui +139 -0
  304. data/lib/roby/gui/relations_view/relations_canvas.rb +1088 -0
  305. data/lib/roby/gui/relations_view/relations_config.rb +292 -0
  306. data/lib/roby/gui/relations_view/relations_view.ui +53 -0
  307. data/lib/roby/gui/scheduler_view.css +24 -0
  308. data/lib/roby/gui/scheduler_view.rb +46 -0
  309. data/lib/roby/gui/scheduler_view.rhtml +53 -0
  310. data/lib/roby/gui/stepping.rb +93 -0
  311. data/lib/roby/gui/stepping.ui +181 -0
  312. data/lib/roby/gui/styles.rb +81 -0
  313. data/lib/roby/gui/task_display_configuration.rb +42 -0
  314. data/lib/roby/gui/task_state_at.rb +38 -0
  315. data/lib/roby/hooks.rb +26 -0
  316. data/lib/roby/interface.rb +136 -469
  317. data/lib/roby/interface/async.rb +20 -0
  318. data/lib/roby/interface/async/action_monitor.rb +188 -0
  319. data/lib/roby/interface/async/interface.rb +498 -0
  320. data/lib/roby/interface/async/job_monitor.rb +213 -0
  321. data/lib/roby/interface/async/log.rb +238 -0
  322. data/lib/roby/interface/async/new_job_listener.rb +79 -0
  323. data/lib/roby/interface/async/ui_connector.rb +183 -0
  324. data/lib/roby/interface/client.rb +553 -0
  325. data/lib/roby/interface/command.rb +24 -0
  326. data/lib/roby/interface/command_argument.rb +16 -0
  327. data/lib/roby/interface/command_library.rb +92 -0
  328. data/lib/roby/interface/droby_channel.rb +174 -0
  329. data/lib/roby/interface/exceptions.rb +22 -0
  330. data/lib/roby/interface/interface.rb +655 -0
  331. data/lib/roby/interface/job.rb +47 -0
  332. data/lib/roby/interface/rest.rb +10 -0
  333. data/lib/roby/interface/rest/api.rb +29 -0
  334. data/lib/roby/interface/rest/helpers.rb +24 -0
  335. data/lib/roby/interface/rest/server.rb +212 -0
  336. data/lib/roby/interface/server.rb +154 -0
  337. data/lib/roby/interface/shell_client.rb +468 -0
  338. data/lib/roby/interface/shell_subcommand.rb +24 -0
  339. data/lib/roby/interface/subcommand_client.rb +35 -0
  340. data/lib/roby/interface/tcp.rb +168 -0
  341. data/lib/roby/models/arguments.rb +112 -0
  342. data/lib/roby/models/plan_object.rb +83 -0
  343. data/lib/roby/models/task.rb +835 -0
  344. data/lib/roby/models/task_event.rb +62 -0
  345. data/lib/roby/models/task_service.rb +78 -0
  346. data/lib/roby/or_generator.rb +88 -0
  347. data/lib/roby/plan.rb +1751 -864
  348. data/lib/roby/plan_object.rb +611 -0
  349. data/lib/roby/plan_service.rb +200 -0
  350. data/lib/roby/promise.rb +332 -0
  351. data/lib/roby/queries.rb +23 -0
  352. data/lib/roby/queries/and_matcher.rb +32 -0
  353. data/lib/roby/queries/any.rb +27 -0
  354. data/lib/roby/queries/code_error_matcher.rb +58 -0
  355. data/lib/roby/queries/event_generator_matcher.rb +9 -0
  356. data/lib/roby/queries/execution_exception_matcher.rb +165 -0
  357. data/lib/roby/queries/index.rb +165 -0
  358. data/lib/roby/queries/localized_error_matcher.rb +149 -0
  359. data/lib/roby/queries/matcher_base.rb +107 -0
  360. data/lib/roby/queries/none.rb +27 -0
  361. data/lib/roby/queries/not_matcher.rb +30 -0
  362. data/lib/roby/queries/op_matcher.rb +8 -0
  363. data/lib/roby/queries/or_matcher.rb +30 -0
  364. data/lib/roby/queries/plan_object_matcher.rb +363 -0
  365. data/lib/roby/queries/query.rb +188 -0
  366. data/lib/roby/queries/task_event_generator_matcher.rb +86 -0
  367. data/lib/roby/queries/task_matcher.rb +344 -0
  368. data/lib/roby/relations.rb +42 -678
  369. data/lib/roby/relations/bidirectional_directed_adjacency_graph.rb +492 -0
  370. data/lib/roby/relations/directed_relation_support.rb +268 -0
  371. data/lib/roby/relations/event_relation_graph.rb +19 -0
  372. data/lib/roby/relations/fork_merge_visitor.rb +154 -0
  373. data/lib/roby/relations/graph.rb +533 -0
  374. data/lib/roby/relations/models/directed_relation_support.rb +11 -0
  375. data/lib/roby/relations/models/graph.rb +75 -0
  376. data/lib/roby/relations/models/task_relation_graph.rb +18 -0
  377. data/lib/roby/relations/space.rb +380 -0
  378. data/lib/roby/relations/task_relation_graph.rb +20 -0
  379. data/lib/roby/robot.rb +85 -38
  380. data/lib/roby/schedulers/basic.rb +155 -25
  381. data/lib/roby/schedulers/null.rb +20 -0
  382. data/lib/roby/schedulers/reporting.rb +31 -0
  383. data/lib/roby/schedulers/state.rb +129 -0
  384. data/lib/roby/schedulers/temporal.rb +91 -0
  385. data/lib/roby/singletons.rb +87 -0
  386. data/lib/roby/standalone.rb +4 -2
  387. data/lib/roby/standard_errors.rb +405 -82
  388. data/lib/roby/state.rb +6 -3
  389. data/lib/roby/state/conf_model.rb +5 -0
  390. data/lib/roby/state/events.rb +181 -95
  391. data/lib/roby/state/goal_model.rb +77 -0
  392. data/lib/roby/state/open_struct.rb +591 -0
  393. data/lib/roby/state/open_struct_model.rb +68 -0
  394. data/lib/roby/state/pos.rb +45 -45
  395. data/lib/roby/state/shapes.rb +11 -11
  396. data/lib/roby/state/state_model.rb +303 -0
  397. data/lib/roby/state/task.rb +43 -0
  398. data/lib/roby/support.rb +88 -148
  399. data/lib/roby/task.rb +1361 -1750
  400. data/lib/roby/task_arguments.rb +428 -0
  401. data/lib/roby/task_event.rb +127 -0
  402. data/lib/roby/task_event_generator.rb +337 -0
  403. data/lib/roby/task_service.rb +6 -0
  404. data/lib/roby/task_structure/conflicts.rb +104 -0
  405. data/lib/roby/task_structure/dependency.rb +932 -0
  406. data/lib/roby/task_structure/error_handling.rb +118 -0
  407. data/lib/roby/task_structure/executed_by.rb +234 -0
  408. data/lib/roby/task_structure/planned_by.rb +90 -0
  409. data/lib/roby/tasks/aggregator.rb +37 -0
  410. data/lib/roby/tasks/external_process.rb +275 -0
  411. data/lib/roby/tasks/group.rb +27 -0
  412. data/lib/roby/tasks/null.rb +19 -0
  413. data/lib/roby/tasks/parallel.rb +43 -0
  414. data/lib/roby/tasks/sequence.rb +88 -0
  415. data/lib/roby/tasks/simple.rb +21 -0
  416. data/lib/roby/{thread_task.rb → tasks/thread.rb} +50 -24
  417. data/lib/roby/tasks/timeout.rb +17 -0
  418. data/lib/roby/tasks/virtual.rb +55 -0
  419. data/lib/roby/template_plan.rb +7 -0
  420. data/lib/roby/test/aruba_minitest.rb +74 -0
  421. data/lib/roby/test/assertion.rb +16 -0
  422. data/lib/roby/test/assertions.rb +490 -0
  423. data/lib/roby/test/common.rb +368 -591
  424. data/lib/roby/test/dsl.rb +149 -0
  425. data/lib/roby/test/error.rb +18 -0
  426. data/lib/roby/test/event_reporter.rb +83 -0
  427. data/lib/roby/test/execution_expectations.rb +1134 -0
  428. data/lib/roby/test/expect_execution.rb +151 -0
  429. data/lib/roby/test/minitest_helpers.rb +166 -0
  430. data/lib/roby/test/roby_app_helpers.rb +200 -0
  431. data/lib/roby/test/run_planners.rb +155 -0
  432. data/lib/roby/test/self.rb +112 -0
  433. data/lib/roby/test/spec.rb +198 -0
  434. data/lib/roby/test/tasks/empty_task.rb +4 -4
  435. data/lib/roby/test/tasks/goto.rb +28 -27
  436. data/lib/roby/test/teardown_plans.rb +100 -0
  437. data/lib/roby/test/testcase.rb +239 -307
  438. data/lib/roby/test/tools.rb +159 -155
  439. data/lib/roby/test/validate_state_machine.rb +75 -0
  440. data/lib/roby/transaction.rb +1125 -0
  441. data/lib/roby/transaction/event_generator_proxy.rb +63 -0
  442. data/lib/roby/transaction/plan_object_proxy.rb +99 -0
  443. data/lib/roby/transaction/plan_service_proxy.rb +43 -0
  444. data/lib/roby/transaction/proxying.rb +120 -0
  445. data/lib/roby/transaction/task_event_generator_proxy.rb +19 -0
  446. data/lib/roby/transaction/task_proxy.rb +135 -0
  447. data/lib/roby/until_generator.rb +30 -0
  448. data/lib/roby/version.rb +5 -0
  449. data/lib/roby/yard.rb +169 -0
  450. data/lib/yard-roby.rb +1 -0
  451. data/manifest.xml +32 -6
  452. data/roby.gemspec +59 -0
  453. metadata +788 -587
  454. data/Manifest.txt +0 -321
  455. data/NOTES +0 -4
  456. data/README.txt +0 -166
  457. data/TODO.txt +0 -146
  458. data/app/README.txt +0 -24
  459. data/app/Rakefile +0 -8
  460. data/app/config/ROBOT.rb +0 -5
  461. data/app/config/init.rb +0 -33
  462. data/app/config/roby.yml +0 -3
  463. data/app/controllers/ROBOT.rb +0 -2
  464. data/app/planners/ROBOT/main.rb +0 -6
  465. data/app/planners/main.rb +0 -5
  466. data/app/scripts/distributed +0 -3
  467. data/app/scripts/generate/bookmarks +0 -3
  468. data/app/scripts/replay +0 -3
  469. data/app/scripts/results +0 -3
  470. data/app/scripts/run +0 -3
  471. data/app/scripts/server +0 -3
  472. data/app/scripts/shell +0 -3
  473. data/app/scripts/test +0 -3
  474. data/app/tasks/.gitattributes +0 -0
  475. data/app/tasks/ROBOT/.gitattributes +0 -0
  476. data/bin/roby-shell +0 -25
  477. data/doc/guide/src/basics/app.page +0 -139
  478. data/doc/guide/src/basics/index.page +0 -11
  479. data/doc/guide/src/basics/log_replay/goForward_1.png +0 -0
  480. data/doc/guide/src/basics/log_replay/goForward_2.png +0 -0
  481. data/doc/guide/src/basics/log_replay/goForward_3.png +0 -0
  482. data/doc/guide/src/basics/log_replay/goForward_5.png +0 -0
  483. data/doc/guide/src/basics/log_replay/plan_repair_4.png +0 -0
  484. data/doc/guide/src/basics/log_replay/roby_log_main_window.png +0 -0
  485. data/doc/guide/src/basics/relations_display.page +0 -203
  486. data/doc/guide/src/basics/shell.page +0 -102
  487. data/doc/guide/src/default.css +0 -319
  488. data/doc/guide/src/introduction/index.page +0 -29
  489. data/doc/guide/src/introduction/publications.page +0 -14
  490. data/doc/guide/src/relations/dependency.page +0 -89
  491. data/doc/guide/src/relations/index.page +0 -12
  492. data/ext/droby/dump.cc +0 -175
  493. data/ext/droby/extconf.rb +0 -3
  494. data/ext/graph/algorithm.cc +0 -746
  495. data/ext/graph/extconf.rb +0 -7
  496. data/ext/graph/graph.cc +0 -575
  497. data/ext/graph/graph.hh +0 -183
  498. data/ext/graph/iterator_sequence.hh +0 -102
  499. data/ext/graph/undirected_dfs.hh +0 -226
  500. data/ext/graph/undirected_graph.hh +0 -421
  501. data/lib/roby/app/scripts/generate/bookmarks.rb +0 -162
  502. data/lib/roby/app/scripts/replay.rb +0 -31
  503. data/lib/roby/app/scripts/server.rb +0 -18
  504. data/lib/roby/basic_object.rb +0 -151
  505. data/lib/roby/config.rb +0 -14
  506. data/lib/roby/distributed.rb +0 -36
  507. data/lib/roby/distributed/base.rb +0 -448
  508. data/lib/roby/distributed/communication.rb +0 -875
  509. data/lib/roby/distributed/connection_space.rb +0 -616
  510. data/lib/roby/distributed/distributed_object.rb +0 -206
  511. data/lib/roby/distributed/drb.rb +0 -62
  512. data/lib/roby/distributed/notifications.rb +0 -531
  513. data/lib/roby/distributed/peer.rb +0 -555
  514. data/lib/roby/distributed/protocol.rb +0 -529
  515. data/lib/roby/distributed/proxy.rb +0 -343
  516. data/lib/roby/distributed/subscription.rb +0 -311
  517. data/lib/roby/distributed/transaction.rb +0 -498
  518. data/lib/roby/external_process_task.rb +0 -225
  519. data/lib/roby/graph.rb +0 -160
  520. data/lib/roby/log.rb +0 -3
  521. data/lib/roby/log/chronicle.rb +0 -303
  522. data/lib/roby/log/console.rb +0 -74
  523. data/lib/roby/log/data_stream.rb +0 -275
  524. data/lib/roby/log/dot.rb +0 -279
  525. data/lib/roby/log/event_stream.rb +0 -161
  526. data/lib/roby/log/file.rb +0 -396
  527. data/lib/roby/log/gui/basic_display.ui +0 -83
  528. data/lib/roby/log/gui/basic_display_ui.rb +0 -89
  529. data/lib/roby/log/gui/chronicle.rb +0 -26
  530. data/lib/roby/log/gui/chronicle_view.rb +0 -40
  531. data/lib/roby/log/gui/chronicle_view.ui +0 -70
  532. data/lib/roby/log/gui/chronicle_view_ui.rb +0 -90
  533. data/lib/roby/log/gui/data_displays.rb +0 -171
  534. data/lib/roby/log/gui/data_displays.ui +0 -155
  535. data/lib/roby/log/gui/data_displays_ui.rb +0 -146
  536. data/lib/roby/log/gui/notifications.rb +0 -26
  537. data/lib/roby/log/gui/relations.rb +0 -269
  538. data/lib/roby/log/gui/relations.ui +0 -123
  539. data/lib/roby/log/gui/relations_ui.rb +0 -120
  540. data/lib/roby/log/gui/relations_view.rb +0 -185
  541. data/lib/roby/log/gui/relations_view.ui +0 -149
  542. data/lib/roby/log/gui/relations_view_ui.rb +0 -144
  543. data/lib/roby/log/gui/replay.rb +0 -366
  544. data/lib/roby/log/gui/replay_controls.rb +0 -206
  545. data/lib/roby/log/gui/replay_controls.ui +0 -282
  546. data/lib/roby/log/gui/replay_controls_ui.rb +0 -249
  547. data/lib/roby/log/gui/runtime.rb +0 -130
  548. data/lib/roby/log/hooks.rb +0 -186
  549. data/lib/roby/log/logger.rb +0 -203
  550. data/lib/roby/log/notifications.rb +0 -244
  551. data/lib/roby/log/plan_rebuilder.rb +0 -468
  552. data/lib/roby/log/relations.rb +0 -1084
  553. data/lib/roby/log/server.rb +0 -547
  554. data/lib/roby/log/sqlite.rb +0 -47
  555. data/lib/roby/log/timings.rb +0 -233
  556. data/lib/roby/plan-object.rb +0 -371
  557. data/lib/roby/planning.rb +0 -13
  558. data/lib/roby/planning/loops.rb +0 -309
  559. data/lib/roby/planning/model.rb +0 -1012
  560. data/lib/roby/planning/task.rb +0 -180
  561. data/lib/roby/query.rb +0 -655
  562. data/lib/roby/relations/conflicts.rb +0 -67
  563. data/lib/roby/relations/dependency.rb +0 -358
  564. data/lib/roby/relations/ensured.rb +0 -19
  565. data/lib/roby/relations/error_handling.rb +0 -22
  566. data/lib/roby/relations/events.rb +0 -7
  567. data/lib/roby/relations/executed_by.rb +0 -208
  568. data/lib/roby/relations/influence.rb +0 -10
  569. data/lib/roby/relations/planned_by.rb +0 -63
  570. data/lib/roby/state/information.rb +0 -55
  571. data/lib/roby/state/state.rb +0 -367
  572. data/lib/roby/task-operations.rb +0 -186
  573. data/lib/roby/task_index.rb +0 -80
  574. data/lib/roby/test/distributed.rb +0 -230
  575. data/lib/roby/test/tasks/simple_task.rb +0 -23
  576. data/lib/roby/transactions.rb +0 -507
  577. data/lib/roby/transactions/proxy.rb +0 -325
  578. data/plugins/fault_injection/History.txt +0 -4
  579. data/plugins/fault_injection/README.txt +0 -34
  580. data/plugins/fault_injection/Rakefile +0 -12
  581. data/plugins/fault_injection/TODO.txt +0 -0
  582. data/plugins/fault_injection/app.rb +0 -52
  583. data/plugins/fault_injection/fault_injection.rb +0 -89
  584. data/plugins/fault_injection/test/test_fault_injection.rb +0 -78
  585. data/plugins/subsystems/README.txt +0 -37
  586. data/plugins/subsystems/Rakefile +0 -13
  587. data/plugins/subsystems/app.rb +0 -182
  588. data/plugins/subsystems/test/app/README +0 -24
  589. data/plugins/subsystems/test/app/Rakefile +0 -8
  590. data/plugins/subsystems/test/app/config/app.yml +0 -71
  591. data/plugins/subsystems/test/app/config/init.rb +0 -12
  592. data/plugins/subsystems/test/app/config/roby.yml +0 -3
  593. data/plugins/subsystems/test/app/planners/main.rb +0 -20
  594. data/plugins/subsystems/test/app/scripts/distributed +0 -3
  595. data/plugins/subsystems/test/app/scripts/replay +0 -3
  596. data/plugins/subsystems/test/app/scripts/results +0 -3
  597. data/plugins/subsystems/test/app/scripts/run +0 -3
  598. data/plugins/subsystems/test/app/scripts/server +0 -3
  599. data/plugins/subsystems/test/app/scripts/shell +0 -3
  600. data/plugins/subsystems/test/app/scripts/test +0 -3
  601. data/plugins/subsystems/test/app/tasks/services.rb +0 -15
  602. data/plugins/subsystems/test/test_subsystems.rb +0 -78
  603. data/test/distributed/test_communication.rb +0 -195
  604. data/test/distributed/test_connection.rb +0 -284
  605. data/test/distributed/test_execution.rb +0 -378
  606. data/test/distributed/test_mixed_plan.rb +0 -341
  607. data/test/distributed/test_plan_notifications.rb +0 -238
  608. data/test/distributed/test_protocol.rb +0 -525
  609. data/test/distributed/test_query.rb +0 -106
  610. data/test/distributed/test_remote_plan.rb +0 -491
  611. data/test/distributed/test_transaction.rb +0 -466
  612. data/test/mockups/external_process +0 -28
  613. data/test/mockups/tasks.rb +0 -27
  614. data/test/planning/test_loops.rb +0 -432
  615. data/test/planning/test_model.rb +0 -427
  616. data/test/planning/test_task.rb +0 -126
  617. data/test/relations/test_conflicts.rb +0 -42
  618. data/test/relations/test_dependency.rb +0 -324
  619. data/test/relations/test_ensured.rb +0 -38
  620. data/test/relations/test_executed_by.rb +0 -224
  621. data/test/relations/test_planned_by.rb +0 -56
  622. data/test/suite_core.rb +0 -29
  623. data/test/suite_distributed.rb +0 -10
  624. data/test/suite_planning.rb +0 -4
  625. data/test/suite_relations.rb +0 -8
  626. data/test/tasks/test_external_process.rb +0 -126
  627. data/test/tasks/test_thread_task.rb +0 -70
  628. data/test/test_bgl.rb +0 -528
  629. data/test/test_event.rb +0 -969
  630. data/test/test_exceptions.rb +0 -591
  631. data/test/test_execution_engine.rb +0 -987
  632. data/test/test_gui.rb +0 -20
  633. data/test/test_interface.rb +0 -43
  634. data/test/test_log.rb +0 -125
  635. data/test/test_log_server.rb +0 -133
  636. data/test/test_plan.rb +0 -418
  637. data/test/test_query.rb +0 -424
  638. data/test/test_relations.rb +0 -260
  639. data/test/test_state.rb +0 -432
  640. data/test/test_support.rb +0 -16
  641. data/test/test_task.rb +0 -1181
  642. data/test/test_testcase.rb +0 -138
  643. data/test/test_transactions.rb +0 -610
  644. data/test/test_transactions_proxy.rb +0 -216
@@ -0,0 +1,21 @@
1
+ module Roby
2
+ module Tasks
3
+ # This task model is a simple task where +start+, +success+ and
4
+ # +failed+ are pass-through controlable events. They have an +id+
5
+ # argument which is automatically set to the object's #object_id if not
6
+ # explicitely given at initialization.
7
+ class Simple < Roby::Task
8
+ argument :id
9
+
10
+ def initialize(arguments = {}) # :nodoc:
11
+ arguments = { id: object_id.to_s }.merge(arguments)
12
+ super(arguments)
13
+ end
14
+
15
+ event :start, command: true
16
+ event :success, command: true, terminal: true
17
+ terminates
18
+ end
19
+ end
20
+ end
21
+
@@ -1,4 +1,6 @@
1
1
  module Roby
2
+ module Tasks
3
+
2
4
  # This task represents a separate thread in the plan. At definition, the
3
5
  # thread's implementation is defined using the +implementation+ statement:
4
6
  #
@@ -14,11 +16,10 @@ module Roby
14
16
  #
15
17
  # By default, the task is not interruptible (i.e. +stop+ is not
16
18
  # controllable). The +interruptible+ statement allows to change that, in
17
- # which case, the thread must call #interruption_point explicitely when the
18
- # interruption can be safely performed by raising an exception.
19
- class ThreadTask < Roby::Task
20
- # The thread object. Only valid when the task is running
21
- attr_reader :thread
19
+ # which case, the thread must either check for
20
+ # {#interruption_requested?}, or call #interruption_point explicitely,
21
+ # when the interruption can be safely performed by raising an exception.
22
+ class Thread < Roby::Task
22
23
  # The thread result if the execution was successful
23
24
  attr_reader :result
24
25
 
@@ -26,16 +27,32 @@ class << self
26
27
  # The implementation block for that task model
27
28
  attr_reader :implementation_block
28
29
 
29
- # Defines the block which should be executed in the separate
30
- # thread. The currently defined block can be accessed
31
- # through the implementation_block attribute.
30
+ # Defines the block which should be executed in the separate
31
+ # thread. The currently defined block can be accessed
32
+ # through the implementation_block attribute.
32
33
  def implementation(&block)
33
34
  @implementation_block = block
34
35
  end
35
36
  end
36
37
 
37
- # True if an interruption has been requested
38
- attr_predicate :interruption_requested?, true
38
+ # True if Roby requests that the thread quits
39
+ def interruption_requested?
40
+ @interruption_event.set?
41
+ end
42
+
43
+ def initialize(arguments = Hash.new, one_shot: true)
44
+ @one_shot = one_shot
45
+ super(arguments)
46
+ end
47
+
48
+ # True if the thread will quit by itself, or run until an interruption
49
+ # is requested
50
+ #
51
+ # In the one shot case, a thread quitting without the stop event pending
52
+ # is considered a success. In the latter case, a failure
53
+ #
54
+ # The default is one shot
55
+ attr_predicate :one_shot?, true
39
56
 
40
57
  # Call that method in the interruption thread at points where an
41
58
  # interruption is safe. It will raise Interrupt if an interruption has
@@ -46,42 +63,51 @@ def interruption_point
46
63
  end
47
64
  end
48
65
 
49
- event :start do |context|
50
- emit :start
51
- @thread = Thread.new do
52
- Thread.current.priority = 0
66
+ # @api private
67
+ #
68
+ # Start the underlying thread and the monitoring objects
69
+ def start_thread
70
+ @interruption_event = Concurrent::Event.new
71
+ @thread = ::Thread.new do
72
+ ::Thread.current.priority = 0
53
73
  instance_eval(&self.class.implementation_block)
54
74
  end
55
75
  end
56
76
 
57
- poll do
58
- if thread.alive?
59
- return
60
- end
77
+ event :start do |context|
78
+ start_thread
79
+ start_event.emit
80
+ end
81
+
82
+ poll do
83
+ if @thread.alive?
84
+ return
85
+ end
61
86
 
62
87
  begin
63
- result = thread.value
88
+ result = @thread.value
64
89
  rescue Exception => e
65
90
  error = e
66
91
  end
67
92
  @thread = nil
68
93
 
69
- if error
70
- emit :failed, error
94
+ if error || (!one_shot? && !stop_event.pending?)
95
+ failed_event.emit(error || result)
71
96
  else
72
97
  @result = result
73
- emit :success
98
+ success_event.emit(result)
74
99
  end
75
100
  end
76
101
 
77
102
  # Call this method in the model definition to declare that the thread
78
103
  # implementation will call #interruption_point regularly.
79
104
  def self.interruptible
80
- event :failed, :terminal => true do |context|
81
- self.interruption_requested = true
105
+ event :failed, terminal: true do |context|
106
+ @interruption_event.set
82
107
  end
83
108
  super
84
109
  end
85
110
  end
111
+ end
86
112
  end
87
113
 
@@ -0,0 +1,17 @@
1
+ module Roby
2
+ module Tasks
3
+ class Timeout < Roby::Task
4
+ argument :delay
5
+ terminates
6
+
7
+ event :timed_out
8
+ forward timed_out: :stop
9
+
10
+ event :start do |context|
11
+ start_event.forward_to timed_out_event, delay: delay
12
+ start_event.emit
13
+ end
14
+ end
15
+ end
16
+ end
17
+
@@ -0,0 +1,55 @@
1
+ module Roby
2
+ module Tasks
3
+ # A virtual task is a task representation for a combination of two events.
4
+ # This allows to combine two unrelated events, one being the +start+ event
5
+ # of the virtual task and the other its success event.
6
+ #
7
+ # The task fails if the success event becomes unreachable.
8
+ #
9
+ # See VirtualTask.create
10
+ class Virtual < Task
11
+ # The start event
12
+ attr_reader :actual_start_event
13
+ # The success event
14
+ attr_accessor :actual_success_event
15
+ # Set the start event
16
+ def actual_start_event=(ev)
17
+ if !ev.controlable?
18
+ raise ArgumentError, "the start event of a virtual task must be controlable"
19
+ end
20
+ @actual_start_event = ev
21
+ end
22
+
23
+ event :start do |context|
24
+ event(:start).achieve_with(actual_start_event)
25
+ actual_start_event.call
26
+ end
27
+ on :start do |context|
28
+ actual_success_event.forward_to_once success_event
29
+ actual_success_event.if_unreachable(cancel_at_emission: true) do
30
+ failed_event.emit if executable?
31
+ end
32
+ end
33
+
34
+ terminates
35
+
36
+ # Creates a new VirtualTask with the given start and success events
37
+ def self.create(start, success)
38
+ task = VirtualTask.new
39
+ task.actual_start_event = start
40
+ task.actual_success_event = success
41
+
42
+ if start.respond_to?(:task)
43
+ task.depends_on start.task
44
+ end
45
+ if success.respond_to?(:task)
46
+ task.depends_on success.task
47
+ end
48
+
49
+ task
50
+ end
51
+ end
52
+ end
53
+ # For backward-compatibility
54
+ VirtualTask = Tasks::Virtual
55
+ end
@@ -0,0 +1,7 @@
1
+ module Roby
2
+ # A plan that is used as a template to inject in other plans
3
+ class TemplatePlan < Plan
4
+ def template?; true end
5
+ def executable?; false end
6
+ end
7
+ end
@@ -0,0 +1,74 @@
1
+ require 'aruba/api'
2
+
3
+ module Roby
4
+ module Test
5
+ # Minitest-usable Aruba wrapper
6
+ #
7
+ # Aruba 0.14 is incompatible with Minitest because of their definition
8
+ # of the #run method This change hacks around the problem, by moving
9
+ # the Aruba API to a side stub object.
10
+ #
11
+ # The run methods are renamed as they have been renamed in Aruba 1.0
12
+ # alpha, run -> run_command and run_simple -> run_command_and_stop
13
+ module ArubaMinitest
14
+ class API
15
+ include ::Aruba::Api
16
+ end
17
+
18
+ attr_reader :roby_bin
19
+
20
+ def setup
21
+ super
22
+ @aruba_api = API.new
23
+ @aruba_api.setup_aruba
24
+ @roby_bin = File.join(Roby::BIN_DIR, "roby")
25
+ end
26
+
27
+ def teardown
28
+ stop_all_commands
29
+ super
30
+ end
31
+
32
+ def run_command_and_stop(*args, fail_on_error: true)
33
+ cmd = run_command(*args)
34
+ cmd.stop
35
+ if fail_on_error
36
+ assert_command_finished_successfully(cmd)
37
+ end
38
+ cmd
39
+ end
40
+
41
+ def run_command(*args)
42
+ @aruba_api.run(*args)
43
+ end
44
+
45
+ def run_roby_and_stop(cmd, *args, fail_on_error: true)
46
+ run_command_and_stop("#{Gem.ruby} #{roby_bin} #{cmd}", *args, fail_on_error: fail_on_error)
47
+ end
48
+
49
+ def run_roby(cmd, *args, fail_on_error: true)
50
+ run_command("#{Gem.ruby} #{roby_bin} #{cmd}", *args, fail_on_error: fail_on_error)
51
+ end
52
+
53
+ def method_missing(m, *args, &block)
54
+ if @aruba_api.respond_to?(m)
55
+ return @aruba_api.send(m, *args, &block)
56
+ else
57
+ super
58
+ end
59
+ end
60
+
61
+ def assert_command_stops(cmd, fail_on_error: true)
62
+ cmd.stop
63
+ if fail_on_error
64
+ assert_command_finished_successfully(cmd)
65
+ end
66
+ end
67
+
68
+ def assert_command_finished_successfully(cmd)
69
+ refute cmd.timed_out?, "#{cmd} timed out on stop"
70
+ assert_equal 0, cmd.exit_status, "#{cmd} finished with a non-zero exit status (#{cmd.exit_status})\n-- STDOUT\n#{cmd.stdout}\n-- STDERR\n#{cmd.stderr}"
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,16 @@
1
+ module Roby
2
+ module Test
3
+ class Assertion < MiniTest::Assertion
4
+ attr_reader :original_error
5
+
6
+ def initialize(original_error)
7
+ @original_error = original_error
8
+ end
9
+
10
+ def message
11
+ [super].concat(Roby.format_exception(original_error)).join("\n")
12
+ end
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,490 @@
1
+ module Roby
2
+ module Test
3
+ module Assertions
4
+ def setup
5
+ @expected_events = Array.new
6
+ super
7
+ end
8
+
9
+ def teardown
10
+ @expected_events.each do |m, args|
11
+ if !plan.event_logger.has_received_event?(m, *args)
12
+ flunk("expected to receive a log event #{m}(#{args.map(&:to_s).join(", ")}) but did not. Received:\n " +
13
+ plan.event_logger.received_events.
14
+ find_all { |m, _, args| m.to_s !~ /timegroup/ }.
15
+ map { |m, time, args| "#{m}(#{args.map(&:to_s).join(", ")})" }.
16
+ join("\n "))
17
+ end
18
+ end
19
+ super
20
+ end
21
+
22
+ def validate_state_machine(task_or_action, &block)
23
+ ValidateStateMachine.new(self, task_or_action).evaluate(&block)
24
+ end
25
+
26
+ # Checks that an exception's #pretty_print method passes without
27
+ # exceptions
28
+ def assert_exception_can_be_pretty_printed(e)
29
+ PP.pp(e, "") # verify that the exception can be pretty-printed, all Roby exceptions should
30
+ end
31
+
32
+ # Better equality test for sets
33
+ #
34
+ # It displays the difference between the two sets
35
+ def assert_sets_equal(expected, actual)
36
+ if !(diff = (expected - actual)).empty?
37
+ flunk("expects two sets to be equal, but #{expected} is missing #{diff.size} expected elements:\n #{diff.to_a.map(&:to_s).join(", ")}")
38
+ elsif !(diff = (actual - expected)).empty?
39
+ flunk("expects two sets to be equal, but #{actual} has #{diff.size} more elements than expected:\n #{diff.to_a.map(&:to_s).join(", ")}")
40
+ end
41
+ end
42
+
43
+ # Capture log output from one logger and returns it
44
+ #
45
+ # Note that it currently does not "de-shares" loggers
46
+ #
47
+ # @param [Logger,#logger] a logger object, or an object that holds
48
+ # one
49
+ # @param [Symbol] level the name of the logging method (e.g. :warn)
50
+ # @return [Array<String>]
51
+ def capture_log(object, level)
52
+ FlexMock.use(object) do |mock|
53
+ __capture_log(mock, level, &proc)
54
+ end
55
+ end
56
+
57
+ def __capture_log(mock, level)
58
+ Roby.disable_colors
59
+
60
+ if mock.respond_to?(:logger)
61
+ object_logger = mock.logger
62
+ else
63
+ object_logger = mock
64
+ end
65
+
66
+ capture = Array.new
67
+ original_level = object_logger.level
68
+ level_value = Logger.const_get(level.upcase)
69
+ if original_level > level_value
70
+ object_logger.level = level_value
71
+ end
72
+
73
+ mock.should_receive(level).
74
+ and_return do |msg|
75
+ if msg.respond_to?(:to_str)
76
+ capture << msg
77
+ else
78
+ mock.invoke_original(level) do
79
+ capture << msg.call
80
+ break
81
+ end
82
+ end
83
+ end
84
+
85
+ yield
86
+ capture
87
+ ensure
88
+ Roby.enable_colors_if_available
89
+ object_logger.level = original_level
90
+ end
91
+
92
+ # Verifies that the given exception object does not raise when
93
+ # pretty-printed
94
+ #
95
+ # When using minitest, this is called by
96
+ # {MinitestHelpers#assert_raises}
97
+ def assert_exception_can_be_pretty_printed(e)
98
+ PP.pp(e, "") # verify that the exception can be pretty-printed, all Roby exceptions should
99
+ end
100
+
101
+ # Verifies that a given event is unreachable, optionally checking
102
+ # its unreachability reason
103
+ #
104
+ # @return the unreachability reason
105
+ def assert_event_is_unreachable(event, reason: nil)
106
+ assert event.unreachable?, "#{event} was expected to be unreachable but is not"
107
+ if reason
108
+ assert(reason === event.unreachability_reason, "the unreachability of #{event} was expected to match #{reason} but it is #{event.unreachability_reason}")
109
+ end
110
+ event.unreachability_reason
111
+ end
112
+
113
+ # Asserts that two tasks are in a parent-child relationship in a
114
+ # specific relation
115
+ #
116
+ # @param [Roby::Task] parent the parent task
117
+ # @param [Roby::Task] child the child task
118
+ # @param [Relations::Models::Graph] relation the relation
119
+ # @param [#===] info optional object used to match the edge
120
+ # information. Leave empty if it should not be matched. Note that
121
+ # giving 'nil' will match against nil
122
+ def assert_child_of(parent, child, relation, *info)
123
+ assert_same parent.relation_graphs, child.relation_graphs, "#{parent} and #{child} cannot be related as they are not acting on the same relation graphs"
124
+ graph = parent.relation_graph_for(relation)
125
+ assert graph.has_vertex?(parent), "#{parent} and #{child} canot be related in #{relation} as the former is not in the graph"
126
+ assert graph.has_vertex?(child), "#{parent} and #{child} canot be related in #{relation} as the latter is not in the graph"
127
+ assert parent.child_object?(child, relation), "#{child} is not a child of #{parent} in #{relation}"
128
+ if !info.empty?
129
+ assert_equal info.first, parent[child, relation], "info differs"
130
+ end
131
+ end
132
+
133
+ # Asserts that two tasks are not a parent-child relationship in a
134
+ # specific relation
135
+ def refute_child_of(parent, child, relation)
136
+ assert_same parent.relation_graphs, child.relation_graphs, "#{parent} and #{child} cannot be related as they are not acting on the same relation graphs"
137
+ graph = parent.relation_graph_for(relation)
138
+ refute(graph.has_vertex?(parent) && graph.has_vertex?(child) && parent.child_object?(child, relation))
139
+ end
140
+
141
+ # This assertion fails if the relative error between +found+ and
142
+ # +expected+is more than +error+
143
+ def assert_relative_error(expected, found, error, msg = "")
144
+ if expected == 0
145
+ assert_in_delta(0, found, error, "comparing #{found} to #{expected} in #{msg}")
146
+ else
147
+ assert_in_delta(0, (found - expected) / expected, error, "comparing #{found} to #{expected} in #{msg}")
148
+ end
149
+ end
150
+
151
+ # This assertion fails if +found+ and +expected+ are more than +dl+
152
+ # meters apart in the x, y and z coordinates, or +dt+ radians apart
153
+ # in angles
154
+ def assert_same_position(expected, found, dl = 0.01, dt = 0.01, msg = "")
155
+ assert_relative_error(expected.x, found.x, dl, msg)
156
+ assert_relative_error(expected.y, found.y, dl, msg)
157
+ assert_relative_error(expected.z, found.z, dl, msg)
158
+ assert_relative_error(expected.yaw, found.yaw, dt, msg)
159
+ assert_relative_error(expected.pitch, found.pitch, dt, msg)
160
+ assert_relative_error(expected.roll, found.roll, dt, msg)
161
+ end
162
+
163
+ def droby_local_marshaller
164
+ @droby_local_marshaller ||= DRoby::Marshal.new
165
+ end
166
+
167
+ def droby_remote_marshaller
168
+ @droby_remote_marshaller ||= DRoby::Marshal.new
169
+ end
170
+
171
+ def droby_to_remote(object, local_marshaller: self.droby_local_marshaller)
172
+ droby = local_marshaller.dump(object)
173
+ dumped =
174
+ begin Marshal.dump(droby)
175
+ rescue Exception => e
176
+ require 'roby/droby/logfile/writer'
177
+ obj, exception = Roby::DRoby::Logfile::Writer.find_invalid_marshalling_object(droby)
178
+ raise e, "#{obj} cannot be marshalled: #{exception.message}", exception.backtrace
179
+ end
180
+ Marshal.load(dumped)
181
+ end
182
+
183
+ def droby_transfer(object, local_marshaller: self.droby_local_marshaller, remote_marshaller: self.droby_remote_marshaller)
184
+ loaded = droby_to_remote(object, local_marshaller: local_marshaller)
185
+ remote_marshaller.local_object(loaded)
186
+ end
187
+
188
+
189
+ # Asserts that an object can marshalled an unmarshalled by the DRoby
190
+ # protocol
191
+ #
192
+ # It does not verify that the resulting objects are equal as they
193
+ # usually are not
194
+ #
195
+ # @param [Object] object the object to test against
196
+ # @param [DRoby::Marshal] local_marshaller the local marshaller,
197
+ # which will be used to marshal 'object'
198
+ # @param [DRoby::Marshal] remote_marshaller the remote marshaller,
199
+ # which will be used to unmarshal the marshalled version of
200
+ # 'object'
201
+ # @return [Object] the 'remote' object created from the unmarshalled
202
+ # droby representation
203
+ def assert_droby_compatible(object, local_marshaller: self.droby_local_marshaller, remote_marshaller: self.droby_remote_marshaller, bidirectional: false)
204
+ remote_object = droby_transfer(object, local_marshaller: local_marshaller,
205
+ remote_marshaller: remote_marshaller)
206
+ if bidirectional
207
+ local_object = droby_transfer(remote_object, local_marshaller: remote_marshaller,
208
+ remote_marshaller: local_marshaller)
209
+ return remote_object, local_object
210
+ else
211
+ return remote_object
212
+ end
213
+ end
214
+
215
+ # Expects the event logger to receive the given message
216
+ #
217
+ # The assertion is validated on teardown
218
+ def assert_logs_event(event_name, *args)
219
+ @expected_events << [event_name, args]
220
+ end
221
+
222
+ # @!group Deprecated assertions replaced by expect_execution
223
+
224
+ # @api private
225
+ #
226
+ # Helper method that creates a matching object for localized errors
227
+ #
228
+ # @param [LocalizedError] localized_error_type the error model to
229
+ # match
230
+ # @param [Exception,nil] original_exception an original exception
231
+ # to match, for exceptions that transform exceptions into other
232
+ # (e.g. CodeError)
233
+ # @param [Task,EventGenerator] failure_point the exceptions' failure
234
+ # point
235
+ # @return [#===] an object that can match an execution exception
236
+ def create_exception_matcher(localized_error_type, original_exception: nil, failure_point: nil)
237
+ matcher = localized_error_type.match
238
+ if original_exception
239
+ matcher.with_original_exception(original_exception)
240
+ end
241
+ if matcher.respond_to?(:with_ruby_exception) && matcher.ruby_exception_class == Exception
242
+ if original_exception
243
+ matcher.with_ruby_exception(original_exception)
244
+ else
245
+ matcher.without_ruby_exception
246
+ end
247
+ end
248
+ if failure_point
249
+ matcher.with_origin(failure_point)
250
+ end
251
+ matcher
252
+ end
253
+
254
+ # @deprecated use #expect_execution { ... }.to { emit event } instead
255
+ def assert_event_emission(positive = [], negative = [], msg = nil, timeout = 5, enable_scheduler: nil, garbage_collect_pass: true)
256
+ Roby.warn_deprecated "#{__method__} is deprecated, use #expect_execution { ... }.to { emit event } instead"
257
+ expect_execution do
258
+ yield if block_given?
259
+ end.timeout(timeout).
260
+ scheduler(enable_scheduler).
261
+ garbage_collect(garbage_collect_pass).
262
+ to do
263
+ not_emit *Array(negative)
264
+ emit *Array(positive)
265
+ end
266
+ end
267
+
268
+ # @deprecated use #expect_execution { ... }.to { quarantine task }
269
+ def assert_task_quarantined(task, timeout: 5)
270
+ Roby.warn_deprecated "#{__method__} is deprecated, use #expect_execution { ... }.to { quarantine task } instead"
271
+ expect_execution { yield }.timeout(timeout).
272
+ to { quarantine task }
273
+ end
274
+
275
+ # @deprecated use #expect_execution { ... }.to { become_unreachable generator }
276
+ def assert_event_becomes_unreachable(generator, timeout: 5, &block)
277
+ Roby.warn_deprecated "#{__method__} is deprecated, use #expect_execution { ... }.to { become_unreachable generator } instead"
278
+ expect_execution { yield }.timeout(timeout).
279
+ to { become_unreachable generator }
280
+ end
281
+
282
+ # @deprecated use expect_execution { ... }.to { have_error_matching ... }
283
+ def assert_free_event_emission_failed(exception = EmissionFailed, original_exception: nil, failure_point: EventGenerator, &block)
284
+ Roby.warn_deprecated "#{__method__} is deprecated, use #expect_execution { ... }.to { have_error_matching ... } instead"
285
+ assert_event_emission_failed(exception, original_exception: original_exception, failure_point: failure_point, &block)
286
+ end
287
+
288
+ # @deprecated use expect_execution { ... }.to { have_error_matching EmissionFailed.match.... }
289
+ def assert_event_emission_failed(exception = EmissionFailed, original_exception: nil, failure_point: EventGenerator, execution_engine: nil, &block)
290
+ Roby.warn_deprecated "#{__method__} is deprecated, use #expect_execution { ... }.to { have_error_matching EmissionFailed.match... } instead"
291
+ assert_event_exception(
292
+ exception, original_exception: original_exception,
293
+ failure_point: failure_point,
294
+ execution_engine: execution_engine, &block)
295
+ end
296
+
297
+ # @deprecated use expect_execution { ... }.to { have_error_matching CommandFailed.match... }
298
+ def assert_free_event_command_failed(exception = CommandFailed, original_exception: nil, failure_point: EventGenerator, execution_engine: nil, &block)
299
+ Roby.warn_deprecated "#{__method__} is deprecated, use #expect_execution { ... }.to { have_error_matching CommandFailed.match... } instead"
300
+ assert_event_exception(
301
+ exception, original_exception: original_exception,
302
+ failure_point: failure_point,
303
+ execution_engine: execution_engine, &block)
304
+ end
305
+
306
+ # @deprecated use expect_execution { ... }.to { have_error_matching CommandFailed.match... }
307
+ def assert_event_command_failed(exception = CommandFailed, original_exception: nil, failure_point: EventGenerator, execution_engine: nil, &block)
308
+ Roby.warn_deprecated "#{__method__} is deprecated, use #expect_execution { ... }.to { have_error_matching CommandFailed.match... } instead"
309
+ assert_event_exception(
310
+ exception, original_exception: original_exception,
311
+ failure_point: failure_point,
312
+ execution_engine: execution_engine, &block)
313
+ end
314
+
315
+ # @deprecated use expect_execution { ... }.to { have_error_matching ... }
316
+ def assert_free_event_exception(matcher, original_exception: nil, failure_point: EventGenerator, execution_engine: nil, &block)
317
+ Roby.warn_deprecated "#{__method__} is deprecated, use #expect_execution { ... }.to { have_error_matching ... } instead"
318
+ assert_event_exception(
319
+ matcher, original_exception: original_exception,
320
+ failure_point: failure_point,
321
+ execution_engine: execution_engine, &block)
322
+ end
323
+
324
+ # @deprecated use expect_execution { ... }.to { have_error_matching ... }
325
+ def assert_event_exception(matcher, original_exception: nil, failure_point: EventGenerator, execution_engine: nil)
326
+ Roby.warn_deprecated "#{__method__} is deprecated, use #expect_execution { ... }.to { have_error_matching ... } instead"
327
+ matcher = create_exception_matcher(
328
+ matcher, original_exception: original_exception,
329
+ failure_point: failure_point)
330
+ expect_execution { yield if block_given? }.to { have_error_matching matcher }
331
+ end
332
+
333
+ # @deprecated use expect_execution { ... }.to { fail_to_start ... }
334
+ def assert_task_fails_to_start(task, matcher, failure_point: task.start_event, original_exception: nil, tasks: [])
335
+ Roby.warn_deprecated "#{__method__} is deprecated, use #expect_execution { ... }.to { fail_to_start ... } instead"
336
+ matcher = create_exception_matcher(
337
+ matcher, original_exception: original_exception,
338
+ failure_point: failure_point)
339
+ expect_execution { yield if block_given? }.to { fail_to_start task }
340
+ task.failure_reason
341
+ end
342
+
343
+ # @deprecated use expect_execution { ... }.to { have_error_matching ... }
344
+ def assert_fatal_exception(matcher, failure_point: Task, original_exception: nil, tasks: [], kill_tasks: tasks, garbage_collect: false)
345
+ Roby.warn_deprecated "#{__method__} is deprecated, use #expect_execution { ... }.to { have_error_matching ... } instead"
346
+ matcher = create_exception_matcher(
347
+ matcher, original_exception: original_exception,
348
+ failure_point: failure_point)
349
+ expect_execution { yield if block_given? }.garbage_collect(garbage_collect).to { have_error_matching matcher }.exception
350
+ end
351
+
352
+ # @deprecated use expect_execution { ... }.to { have_handled_error_matching ... }
353
+ def assert_handled_exception(matcher, failure_point: Task, original_exception: nil, tasks: [])
354
+ Roby.warn_deprecated "#{__method__} is deprecated, use #expect_execution { ... }.to { have_handled_error_matching ... } instead"
355
+ matcher = create_exception_matcher(
356
+ matcher, original_exception: original_exception,
357
+ failure_point: failure_point)
358
+ expect_execution { yield if block_given? }.to { have_handled_error_matching matcher }
359
+ end
360
+
361
+ # @deprecated use expect_execution { ... }.to { have_error_matching ... }
362
+ def assert_nonfatal_exception(matcher, failure_point: Task, original_exception: nil, tasks: [])
363
+ Roby.warn_deprecated "#{__method__} is deprecated, use #expect_execution { ... }.to { have_error_matching ... } instead"
364
+ matcher = create_exception_matcher(
365
+ matcher, original_exception: original_exception,
366
+ failure_point: failure_point)
367
+ expect_execution { yield }.to { have_error_matching matcher }
368
+ end
369
+
370
+ # @deprecated
371
+ def assert_logs_exception_with_backtrace(exception_m, logger, level)
372
+ flexmock(Roby).should_receive(:log_exception_with_backtrace).once.
373
+ with(exception_m, logger, level)
374
+ end
375
+
376
+ # @deprecated
377
+ def assert_free_event_exception_warning
378
+ Roby.warn_deprecated "#{__method__} is deprecated, and has no replacements. It is not needed when using the expect_execution harness"
379
+ messages = capture_log(execution_engine, :warn) do
380
+ yield
381
+ end
382
+ assert_equal ["1 free event exceptions"], messages
383
+ end
384
+
385
+ # @deprecated
386
+ def assert_notifies_free_event_exception(matcher, failure_point: nil)
387
+ Roby.warn_deprecated "#{__method__} is deprecated, and has no replacements. It is not needed when using the expect_execution harness"
388
+ flexmock(execution_engine).should_receive(:notify_exception).
389
+ with(ExecutionEngine::EXCEPTION_FREE_EVENT,
390
+ *roby_make_flexmock_exception_matcher(matcher, [failure_point])).
391
+ once
392
+ end
393
+
394
+ # @deprecated use #expect_execution { ... }.to { have_error_matching ... } instead
395
+ def assert_adds_error(matcher, original_exception: nil, failure_point: PlanObject)
396
+ Roby.warn_deprecated "#{__method__} is deprecated, use #expect_execution { ... }.to { have_error_matching ... } instead"
397
+ matcher = create_exception_matcher(
398
+ matcher, original_exception: original_exception,
399
+ failure_point: failure_point)
400
+ expect_execution { yield }.to { have_error_matching matcher }
401
+ end
402
+
403
+ # @deprecated use #expect_execution { ... }.to { have_framework_error_matching ... } instead
404
+ def assert_adds_framework_error(matcher)
405
+ Roby.warn_deprecated "#{__method__} is deprecated, use #expect_execution { ... }.to { have_framework_error_matching ... } instead"
406
+ expect_execution { yield }.to { have_framework_error_matching matcher }
407
+ end
408
+
409
+ # @api private
410
+ #
411
+ # Helper matcher used to provide a better error message in the
412
+ # various exception assertions
413
+ FlexmockExceptionMatcher = Struct.new :matcher do
414
+ def ===(exception)
415
+ return true if matcher === exception
416
+ if self.class.describe? && (description = matcher.describe_failed_match(exception))
417
+ Roby.warn "expected exception to match #{matcher}, but #{description}"
418
+ end
419
+ false
420
+ end
421
+ def inspect; to_s end
422
+ def to_s; matcher.to_s; end
423
+
424
+ @describe = false
425
+ def self.describe?
426
+ @describe
427
+ end
428
+ def self.describe=(flag)
429
+ @describe = flag
430
+ end
431
+ end
432
+
433
+ # @api private
434
+ #
435
+ # Helper matcher used to provide a better error message in the
436
+ # various exception assertions
437
+ FlexmockExceptionTasks = Struct.new :tasks do
438
+ def ===(tasks)
439
+ self.tasks.to_set == tasks
440
+ end
441
+ def inspect; to_s end
442
+ def to_s; "involved_tasks(#{tasks.to_a.map(&:to_s).join(", ")})" end
443
+ end
444
+
445
+ # @api private
446
+ #
447
+ # Helper method that creates exception matchers that provide better
448
+ # error messages, for the benefit of the exception assertions
449
+ def roby_make_flexmock_exception_matcher(matcher, tasks)
450
+ return FlexmockExceptionMatcher.new(matcher.to_execution_exception_matcher),
451
+ FlexmockExceptionTasks.new(tasks.to_set)
452
+ end
453
+
454
+ # @!endgroup Deprecated assertions replaced by expect_execution
455
+
456
+ # @deprecated use {#validate_state_machine} instead
457
+ def assert_state_machine_transition(state_machine_task, to_state: Regexp.new, timeout: 5, start: true)
458
+ Roby.warn_deprecated "#{__method__} is deprecated, use #validate_state_machine instead"
459
+ state_machines = state_machine_task.each_coordination_object.
460
+ find_all { |obj| obj.kind_of?(Coordination::ActionStateMachine) }
461
+ if state_machines.empty?
462
+ raise ArgumentError, "#{state_machine_task} has no state machines"
463
+ end
464
+
465
+ if to_state.respond_to?(:to_str) && !to_state.end_with?('_state')
466
+ to_state = "#{to_state}_state"
467
+ end
468
+
469
+ done = false
470
+ state_machines.each do |m|
471
+ m.on_transition do |_, new_state|
472
+ if to_state === new_state.name
473
+ done = true
474
+ end
475
+ end
476
+ end
477
+ yield if block_given?
478
+ process_events_until(timeout: timeout, garbage_collect_pass: false) do
479
+ done
480
+ end
481
+ roby_run_planner(state_machine_task)
482
+ if start
483
+ assert_event_emission state_machine_task.current_task_child.start_event
484
+ end
485
+ state_machine_task.current_task_child
486
+ end
487
+ end
488
+ end
489
+ end
490
+