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
@@ -1,9 +1,9 @@
1
1
  module Roby
2
2
  module Test
3
- class EmptyTask < Roby::Task
4
- terminates
5
- forward :start => :success
6
- end
3
+ class EmptyTask < Roby::Task
4
+ terminates
5
+ forward start: :success
6
+ end
7
7
  end
8
8
  end
9
9
 
@@ -1,36 +1,37 @@
1
1
 
2
2
  module Roby
3
3
  module Test
4
- class Goto2D < Roby::Task
5
- terminates
6
- argument :x, :y
4
+ class Goto2D < Roby::Task
5
+ terminates
6
+ argument :x
7
+ argument :y
7
8
 
8
- def speed; State.goto_speed end
9
- def x; arguments[:x] end
10
- def y; arguments[:y] end
9
+ def speed; State.goto_speed end
10
+ def x; arguments[:x] end
11
+ def y; arguments[:y] end
11
12
 
12
- poll do
13
- dx = x - State.pos.x
14
- dy = y - State.pos.y
15
- d = Math.sqrt(dx * dx + dy * dy)
16
- if d > speed
17
- State.pos.x += speed * dx / d
18
- State.pos.y += speed * dy / d
19
- else
20
- State.pos.x = x
21
- State.pos.y = y
22
- emit :success
23
- end
24
- STDERR.puts "#{x} #{y} #{speed} #{State.pos}"
25
- end
13
+ poll do
14
+ dx = x - State.pos.x
15
+ dy = y - State.pos.y
16
+ d = Math.sqrt(dx * dx + dy * dy)
17
+ if d > speed
18
+ State.pos.x += speed * dx / d
19
+ State.pos.y += speed * dy / d
20
+ else
21
+ State.pos.x = x
22
+ State.pos.y = y
23
+ emit :success
24
+ end
25
+ STDERR.puts "#{x} #{y} #{speed} #{State.pos}"
26
+ end
26
27
 
27
- module Planning
28
- planning_library
29
- method(:go_to) do
30
- Goto2D.new(arguments)
31
- end
32
- end
33
- end
28
+ module Planning
29
+ planning_library
30
+ method(:go_to) do
31
+ Goto2D.new(arguments)
32
+ end
33
+ end
34
+ end
34
35
  end
35
36
  end
36
37
 
@@ -0,0 +1,100 @@
1
+ module Roby
2
+ module Test
3
+ module TeardownPlans
4
+ attr_reader :registered_plans
5
+
6
+ def register_plan(plan)
7
+ if !plan
8
+ raise "registering nil plan"
9
+ end
10
+ (@registered_plans ||= Array.new) << plan
11
+ end
12
+
13
+ def clear_registered_plans
14
+ registered_plans.each do |p|
15
+ if p.respond_to?(:execution_engine)
16
+ p.execution_engine.killall
17
+ p.execution_engine.reset
18
+ execute(plan: p) { p.clear }
19
+ end
20
+ end
21
+ registered_plans.clear
22
+ end
23
+
24
+ def teardown_registered_plans
25
+ old_gc_roby_logger_level = Roby.logger.level
26
+ if self.registered_plans.all? { |p| p.empty? }
27
+ return
28
+ end
29
+
30
+ plans = self.registered_plans.map do |p|
31
+ if p.executable?
32
+ [p, p.execution_engine, Set.new, Set.new]
33
+ end
34
+ end.compact
35
+
36
+ counter = 0
37
+ while !plans.empty?
38
+ plans = plans.map do |plan, engine, last_tasks, last_quarantine|
39
+ plan_quarantine = plan.quarantined_tasks
40
+ if counter > 100
41
+ Roby.warn "more than #{counter} iterations while trying to shut down #{plan} after #{self.class.name}##{name}, quarantine=#{plan_quarantine.size} tasks, tasks=#{plan.tasks.size} tasks"
42
+ if last_tasks != plan.tasks
43
+ Roby.warn "Known tasks:"
44
+ plan.tasks.each do |t|
45
+ Roby.warn " #{t} running=#{t.running?} finishing=#{t.finishing?}"
46
+ end
47
+ last_tasks = plan.tasks.dup
48
+ end
49
+ if last_quarantine != plan_quarantine
50
+ Roby.warn "Quarantined tasks:"
51
+ plan_quarantine.each do |t|
52
+ Roby.warn " #{t}"
53
+ end
54
+ last_quarantine = plan_quarantine.dup
55
+ end
56
+ sleep 1
57
+ end
58
+ engine.killall
59
+
60
+ quarantine_and_dependencies = plan.compute_useful_tasks(plan.quarantined_tasks)
61
+
62
+ if quarantine_and_dependencies.size != plan.tasks.size
63
+ [plan, engine, last_tasks, last_quarantine]
64
+ end
65
+ end.compact
66
+ counter += 1
67
+ end
68
+
69
+ registered_plans.each do |plan|
70
+ if !plan.empty?
71
+ if plan.tasks.all? { |t| t.pending? }
72
+ plan.clear
73
+ else
74
+ Roby.warn "failed to teardown: #{plan} has #{plan.tasks.size} tasks and #{plan.free_events.size} events, #{plan.quarantined_tasks.size} of which are in quarantine"
75
+ if !plan.execution_engine
76
+ Roby.warn "this is most likely because this plan does not have an execution engine. Either add one or clear the plan in the tests"
77
+ end
78
+ end
79
+ end
80
+ plan.clear
81
+ if engine = plan.execution_engine
82
+ engine.clear
83
+ engine.emitted_events.clear
84
+ end
85
+
86
+ if !plan.transactions.empty?
87
+ Roby.warn " #{plan.transactions.size} transactions left attached to the plan"
88
+ plan.transactions.each do |trsc|
89
+ trsc.discard_transaction
90
+ end
91
+ end
92
+ end
93
+
94
+ ensure
95
+ Roby.logger.level = old_gc_roby_logger_level
96
+ end
97
+ end
98
+ end
99
+ end
100
+
@@ -6,318 +6,250 @@
6
6
 
7
7
  module Roby
8
8
  module Test
9
- extend Logger::Hierarchy
10
- extend Logger::Forward
11
-
12
- # This is the base class for running tests which uses a Roby control
13
- # loop (i.e. plan execution).
14
- #
15
- # Because configuration and planning can be robot-specific, parts of
16
- # the tests can also be splitted into generic parts and specific parts.
17
- # The TestCase.robot statement allows to specify that a given test case
18
- # is specific to a given robot, in which case it is ran only if the
19
- # call to <tt>scripts/test</tt> specified a robot which matches (i.e.
20
- # same name and type).
21
- #
22
- # Finally, two other mode of operation control the way tests are ran
23
- # [simulation]
24
- # if the <tt>--sim</tt> flag is given to <tt>scripts/test</tt>, the
25
- # tests are ran under simulation. Otherwise, they are run in live
26
- # mode (see Roby::Application for a description of simulation and
27
- # live modes). It is possible to constrain that a given test method
28
- # is run only in simulation or live mode with the TestCase.sim and
29
- # TestCase.nosim statements:
30
- #
31
- # sim :sim_only
32
- # def test_sim_only
33
- # end
34
- #
35
- # nosim :live_only
36
- # def test_live_only
37
- # end
38
- # [interactive]
39
- # Sometime, it is hard to actually assess the quality of processing
40
- # results automatically. In these cases, it is possible to show the
41
- # user the result of data processing, and then ask if the result is
42
- # valid by using the #user_validation method. Nonetheless, the tests
43
- # can be ran in automatic mode, in which the assertions which require
44
- # user validation are simply skipped. The <tt>--interactive</tt> or
45
- # <tt>-i</tt> flags of <tt>scripts/test</tt> specify that user
46
- # interaction is possible.
47
- class TestCase < Test::Unit::TestCase
48
- include Roby::Test
49
- include Assertions
50
- class << self
51
- attribute(:case_config) { Hash.new }
52
- attribute(:methods_config) { Hash.new }
53
- attr_reader :app_setup
54
- end
55
-
56
- # Sets the robot configuration for this test case. If a block is
57
- # given, it is called between the time the robot configuration is
58
- # loaded and the time the test methods are started. It can
59
- # therefore be used to change the robot configuration for the need
60
- # of this particular test case
61
- def self.robot(name, kind = name, &block)
62
- @app_setup = [name, kind, block]
63
- apply_robot_setup
64
- end
65
-
66
- @@first_time = true
67
- # Loads the configuration as specified by TestCase.robot
68
- def self.apply_robot_setup
69
- app = Roby.app
70
- if @@first_time
71
- # Make sure the log directory is empty
72
- if File.exists?(app.log_dir)
73
- if !Dir.new(app.log_dir).empty?
74
- if !STDIN.ask("#{app.log_dir} still exists and must be cleaned before starting. Proceed ? [N,y]", false)
75
- raise "user abort"
76
- end
77
- end
78
- FileUtils.rm_rf app.log_dir
79
- end
80
- @@first_time = false
81
- end
82
-
83
- name, kind, block = app_setup
84
- # Silently ignore the test suites which use a different robot
85
- if app.robot_name &&
86
- (app.robot_name != name || app.robot_type != kind)
87
- return
88
- end
89
- app.robot name, kind
90
- app.reset
91
- app.single
92
- app.setup
93
- if block
94
- block.call
95
- end
96
-
97
- yield if block_given?
98
- end
99
-
100
- # Returns a fresh MainPlanner object for the current plan
101
- def planner
102
- MainPlanner.new(plan)
103
- end
104
-
105
- def setup # :nodoc:
9
+ extend Logger::Hierarchy
10
+ extend Logger::Forward
11
+
12
+ # This is the base class for running tests which uses a Roby control
13
+ # loop (i.e. plan execution).
14
+ #
15
+ # Because configuration and planning can be robot-specific, parts of
16
+ # the tests can also be splitted into generic parts and specific parts.
17
+ # The TestCase.robot statement allows to specify that a given test case
18
+ # is specific to a given robot, in which case it is ran only if the
19
+ # call to <tt>scripts/test</tt> specified a robot which matches (i.e.
20
+ # same name and type).
21
+ #
22
+ # Finally, two other mode of operation control the way tests are ran
23
+ # [simulation]
24
+ # if the <tt>--sim</tt> flag is given to <tt>scripts/test</tt>, the
25
+ # tests are ran under simulation. Otherwise, they are run in live
26
+ # mode (see Roby::Application for a description of simulation and
27
+ # live modes). It is possible to constrain that a given test method
28
+ # is run only in simulation or live mode with the TestCase.sim and
29
+ # TestCase.nosim statements:
30
+ #
31
+ # sim :sim_only
32
+ # def test_sim_only
33
+ # end
34
+ #
35
+ # nosim :live_only
36
+ # def test_live_only
37
+ # end
38
+ # [interactive]
39
+ # Sometime, it is hard to actually assess the quality of processing
40
+ # results automatically. In these cases, it is possible to show the
41
+ # user the result of data processing, and then ask if the result is
42
+ # valid by using the #user_validation method. Nonetheless, the tests
43
+ # can be ran in automatic mode, in which the assertions which require
44
+ # user validation are simply skipped. The <tt>--interactive</tt> or
45
+ # <tt>-i</tt> flags of <tt>scripts/test</tt> specify that user
46
+ # interaction is possible.
47
+ class TestCase < Test::Unit::TestCase
48
+ include Roby::Test
49
+ include Assertions
50
+ class << self
51
+ attribute(:case_config) { Hash.new }
52
+ attribute(:methods_config) { Hash.new }
53
+ attr_reader :app_setup
54
+ end
55
+
56
+ # Sets the robot configuration for this test case. If a block is
57
+ # given, it is called between the time the robot configuration is
58
+ # loaded and the time the test methods are started. It can
59
+ # therefore be used to change the robot configuration for the need
60
+ # of this particular test case
61
+ def self.robot(name, kind = name, &block)
62
+ @app_setup = [name, kind, block]
63
+ end
64
+
65
+ # Loads the configuration as specified by TestCase.robot
66
+ def self.apply_robot_setup
67
+ app = Roby.app
68
+
69
+ name, kind, block = app_setup
70
+ # Ignore the test suites which use a different robot
71
+ if name || kind && (app.robot_name &&
72
+ (app.robot_name != name || app.robot_type != kind))
73
+ Test.info "ignoring #{self} as it is for robot #{name} and we are running for #{app.robot_name}:#{app.robot_type}"
74
+ return
75
+ end
76
+ if block
77
+ block.call
78
+ end
79
+
80
+ yield if block_given?
81
+ end
82
+
83
+ # Returns a fresh MainPlanner object for the current plan
84
+ def planner
85
+ MainPlanner.new(plan)
86
+ end
87
+
88
+ def setup # :nodoc:
106
89
  @plan = Roby.plan
107
- @engine = Roby.engine
108
- @control = Roby.control
109
-
110
- super
111
- end
112
-
113
- def method_config # :nodoc:
114
- self.class.case_config.merge(self.class.methods_config[method_name] || Hash.new)
115
- end
116
-
117
- # Returns true if user interaction is to be disabled during this test
118
- def automatic_testing?
119
- Roby.app.automatic_testing?
120
- end
121
-
122
- # Progress report for the curren test. If +max+ is given, then
123
- # +value+ is assumed to be between 0 and +max+. Otherwise, +value+
124
- # is a float value between 0 and 1 and is displayed as a percentage.
125
- def progress(value, max = nil)
126
- if max
127
- print "\r#{@method_name} progress: #{value}/#{max}"
128
- else
129
- print "\r#{@method_name} progress: #{"%.2f %%" % [value * 100]}"
130
- end
131
- STDOUT.flush
132
- end
133
-
134
- def user_interaction
135
- return unless automatic_testing?
136
-
137
- test_result = catch(:validation_result) do
138
- yield
139
- return
140
- end
141
- if test_result
142
- flunk(*test_result)
143
- end
144
- end
145
-
146
- # Ask for user validation. The method first yields, and then asks
147
- # the user if the showed dataset is nominal. If the tests are ran
148
- # in automated mode (#automatic_testing? returns true), it does
149
- # nothing.
150
- def user_validation(msg)
151
- return if automatic_testing?
152
-
153
- assert_block(msg) do
154
- STDOUT.puts "Now validating #{msg}"
155
- yield
156
-
157
- STDIN.ask("\rIs the result OK ? [N,y]", false)
158
- end
159
- end
160
-
161
- # Do not run +test_name+ inside a simulation environment
162
- # +test_name+ is the name of the method without +test_+. For
163
- # instance:
164
- # nosim :init
165
- # def test_init
166
- # end
167
- #
168
- # See also TestCase.sim
169
- def self.nosim(*names)
170
- names.each do |test_name|
171
- config = (methods_config[test_name.to_s] ||= Hash.new)
172
- config[:mode] = :nosim
173
- end
174
- end
175
-
176
- # Run +test_name+ only inside a simulation environment
177
- # +test_name+ is the name of the method without +test_+. For
178
- # instance:
179
- # sim :init
180
- # def test_init
181
- # end
182
- #
183
- # See also TestCase.nosim
184
- def self.sim(*names)
185
- names.each do |test_name|
186
- config = (methods_config[test_name.to_s] ||= Hash.new)
187
- config[:mode] = :sim
188
- end
189
- end
190
-
191
- def self.suite # :nodoc:
192
- method_names = public_instance_methods(true)
193
- tests = method_names.delete_if {|method_name| method_name !~ /^(dataset|test)./}
194
- suite = Test::Unit::TestSuite.new(name)
195
- tests.sort.each do |test|
196
- catch(:invalid_test) do
197
- suite << new(test)
198
- end
199
- end
200
- if (suite.empty?)
201
- catch(:invalid_test) do
202
- suite << new("default_test")
203
- end
204
- end
205
- return suite
206
- end
207
-
208
- def run(result) # :nodoc:
90
+ @engine = plan.engine
91
+ @control = plan.engine.control
92
+
93
+ super
94
+ end
95
+
96
+ # Returns true if user interaction is to be disabled during this test
97
+ def automatic_testing?
98
+ Roby.app.automatic_testing?
99
+ end
100
+
101
+ # Progress report for the curren test. If +max+ is given, then
102
+ # +value+ is assumed to be between 0 and +max+. Otherwise, +value+
103
+ # is a float value between 0 and 1 and is displayed as a percentage.
104
+ def progress(value, max = nil)
105
+ if max
106
+ print "\rprogress: #{value}/#{max}"
107
+ else
108
+ print "\rprogress: #{"%.2f %%" % [value * 100]}"
109
+ end
110
+ STDOUT.flush
111
+ end
112
+
113
+ def user_interaction
114
+ return unless automatic_testing?
115
+
116
+ test_result = catch(:validation_result) do
117
+ yield
118
+ return
119
+ end
120
+ if test_result
121
+ flunk(*test_result)
122
+ end
123
+ end
124
+
125
+ # Ask for user validation. The method first yields, and then asks
126
+ # the user if the showed dataset is nominal. If the tests are ran
127
+ # in automated mode (#automatic_testing? returns true), it does
128
+ # nothing.
129
+ def user_validation(msg)
130
+ return if automatic_testing?
131
+
132
+ assert_block(msg) do
133
+ STDOUT.puts "Now validating #{msg}"
134
+ yield
135
+
136
+ STDIN.ask("\rIs the result OK ? [N,y]", false)
137
+ end
138
+ end
139
+
140
+ # Do not run +test_name+ inside a simulation environment
141
+ # +test_name+ is the name of the method without +test_+. For
142
+ # instance:
143
+ # nosim :init
144
+ # def test_init
145
+ # end
146
+ #
147
+ # See also TestCase.sim
148
+ def self.nosim(*names)
149
+ names.each do |test_name|
150
+ config = (methods_config[test_name.to_s] ||= Hash.new)
151
+ config[:mode] = :nosim
152
+ end
153
+ end
154
+
155
+ # Run +test_name+ only inside a simulation environment
156
+ # +test_name+ is the name of the method without +test_+. For
157
+ # instance:
158
+ # sim :init
159
+ # def test_init
160
+ # end
161
+ #
162
+ # See also TestCase.nosim
163
+ def self.sim(*names)
164
+ names.each do |test_name|
165
+ config = (methods_config[test_name.to_s] ||= Hash.new)
166
+ config[:mode] = :sim
167
+ end
168
+ end
169
+
170
+ def run(result) # :nodoc:
209
171
  if self.class == TestCase
210
172
  return
211
173
  end
212
174
 
213
- self.class.apply_robot_setup do
214
- yield if block_given?
215
-
216
- case method_config[:mode]
217
- when :nosim
218
- return if Roby.app.simulation?
219
- when :sim
220
- return unless Roby.app.simulation?
221
- end
222
-
223
- @failed_test = false
224
- begin
225
- Roby.app.run do
226
- super
227
- end
228
- rescue Exception => e
229
- if @_result
230
- add_error(e)
231
- else
232
- raise
233
- end
234
- end
235
-
236
- keep_logdir = @failed_test || Roby.app.testing_keep_logs?
237
- save_logdir = (@failed_test && automatic_testing?) || Roby.app.testing_keep_logs?
238
- if save_logdir
239
- subdir = @failed_test ? 'failures' : 'results'
240
- basedir = File.join(APP_DIR, 'test', subdir)
241
- dirname = Roby::Application.unique_dirname(basedir, dataset_prefix)
242
-
243
- if Roby.app.testing_overwrites_logs?
244
- dirname.gsub! /\.\d+$/, ''
245
- FileUtils.rm_rf dirname
246
- end
247
-
248
- FileUtils.mv Roby.app.log_dir, dirname
249
- end
250
- if !keep_logdir
251
- FileUtils.rm_rf Roby.app.log_dir
252
- end
253
- end
254
-
255
- rescue Exception
256
- puts "testcase #{method_name} teardown failed with\n#{$!.full_message}"
257
- end
258
-
259
- def add_error(*args, &block) # :nodoc:
260
- @failed_test = true
261
- super
262
- end
263
- def add_failure(*args, &block) # :nodoc:
264
- @failed_test = true
265
- super
266
- end
267
-
268
- # The directory in which datasets are to be saved
269
- def datasets_dir
270
- "#{APP_DIR}/test/datasets"
271
- end
272
- # The directory into which the datasets generated by the current
273
- # testcase are to be saved.
274
- def dataset_prefix
275
- "#{Roby.app.robot_name}-#{self.class.name.gsub('TC_', '').underscore}-#{@method_name.gsub(/(?:test|dataset)_/, '')}"
276
- end
277
- # Returns the full path of the file name into which the log file +file+
278
- # should be saved to be referred to as the +dataset_name+ dataset
279
- def dataset_file_path(dataset_name, file)
280
- path = File.join(datasets_dir, dataset_name, file)
281
- if !File.file?(path)
282
- raise "#{path} does not exist"
283
- end
284
-
285
- path
286
- rescue
287
- flunk("dataset #{dataset_name} has not been generated: #{$!.message}")
288
- end
289
-
290
-
291
-
292
- # Saves +file+, which is taken in the log directory, in the
293
- # test/datasets directory. The data set is saved as
294
- # 'robot-testname-testmethod-suffix'
295
- def save_dataset(files = nil, suffix = '')
296
- destname = dataset_prefix
297
- destname << "-#{suffix}" unless suffix.empty?
298
-
299
- dir = File.join(datasets_dir, destname)
300
- if File.exists?(dir)
301
- relative_dir = dir.gsub(/^#{Regexp.quote(APP_DIR)}/, '')
302
- unless STDIN.ask("\r#{relative_dir} already exists. Delete ? [N,y]", false)
303
- raise "user abort"
304
- end
305
- FileUtils.rm_rf dir
306
- end
307
- FileUtils.mkdir_p(dir)
308
-
309
- files ||= Dir.entries(Roby.app.log_dir).find_all do |path|
310
- File.file? File.join(Roby.app.log_dir, path)
311
- end
312
-
313
- [*files].each do |path|
314
- FileUtils.mv "#{Roby.app.log_dir}/#{path}", dir
315
- end
316
- end
317
-
318
- def sampling(*args, &block); Test.sampling(*args, &block) end
319
- def stats(*args, &block); Test.stats(*args, &block) end
320
- end
175
+ self.class.apply_robot_setup do
176
+ yield if block_given?
177
+
178
+ @failed_test = false
179
+ begin
180
+ super
181
+ rescue Exception => e
182
+ if @_result
183
+ add_error(e)
184
+ else
185
+ raise
186
+ end
187
+ end
188
+ end
189
+ end
190
+
191
+ def add_error(*args, &block) # :nodoc:
192
+ @failed_test = true
193
+ super
194
+ end
195
+ def add_failure(*args, &block) # :nodoc:
196
+ @failed_test = true
197
+ super
198
+ end
199
+
200
+ # The directory in which datasets are to be saved
201
+ def datasets_dir
202
+ "#{Roby.app.app_dir}/test/datasets"
203
+ end
204
+ # The directory into which the datasets generated by the current
205
+ # testcase are to be saved.
206
+ def dataset_prefix
207
+ "#{Roby.app.robot_name}-#{self.class.name.gsub('TC_', '').underscore}-#{@method_name.gsub(/(?:test|dataset)_/, '')}"
208
+ end
209
+ # Returns the full path of the file name into which the log file +file+
210
+ # should be saved to be referred to as the +dataset_name+ dataset
211
+ def dataset_file_path(dataset_name, file)
212
+ path = File.join(datasets_dir, dataset_name, file)
213
+ if !File.file?(path)
214
+ raise "#{path} does not exist"
215
+ end
216
+
217
+ path
218
+ rescue
219
+ flunk("dataset #{dataset_name} has not been generated: #{$!.message}")
220
+ end
221
+
222
+
223
+
224
+ # Saves +file+, which is taken in the log directory, in the
225
+ # test/datasets directory. The data set is saved as
226
+ # 'robot-testname-testmethod-suffix'
227
+ def save_dataset(files = nil, suffix = '')
228
+ destname = dataset_prefix
229
+ destname << "-#{suffix}" unless suffix.empty?
230
+
231
+ dir = File.join(datasets_dir, destname)
232
+ if File.exists?(dir)
233
+ relative_dir = dir.gsub(/^#{Regexp.quote(Roby.app.app_dir)}/, '')
234
+ unless STDIN.ask("\r#{relative_dir} already exists. Delete ? [N,y]", false)
235
+ raise "user abort"
236
+ end
237
+ FileUtils.rm_rf dir
238
+ end
239
+ FileUtils.mkdir_p(dir)
240
+
241
+ files ||= Dir.entries(Roby.app.log_dir).find_all do |path|
242
+ File.file? File.join(Roby.app.log_dir, path)
243
+ end
244
+
245
+ [*files].each do |path|
246
+ FileUtils.mv "#{Roby.app.log_dir}/#{path}", dir
247
+ end
248
+ end
249
+
250
+ def sampling(*args, &block); Test.sampling(engine, *args, &block) end
251
+ def stats(*args, &block); Test.stats(*args, &block) end
252
+ end
321
253
  end
322
254
  end
323
255