roby 0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (240) hide show
  1. data/.gitignore +29 -0
  2. data/History.txt +4 -0
  3. data/License-fr.txt +519 -0
  4. data/License.txt +515 -0
  5. data/Manifest.txt +245 -0
  6. data/NOTES +4 -0
  7. data/README.txt +163 -0
  8. data/Rakefile +161 -0
  9. data/TODO.txt +146 -0
  10. data/app/README.txt +24 -0
  11. data/app/Rakefile +8 -0
  12. data/app/config/ROBOT.rb +5 -0
  13. data/app/config/app.yml +91 -0
  14. data/app/config/init.rb +7 -0
  15. data/app/config/roby.yml +3 -0
  16. data/app/controllers/.gitattributes +0 -0
  17. data/app/controllers/ROBOT.rb +2 -0
  18. data/app/data/.gitattributes +0 -0
  19. data/app/planners/ROBOT/main.rb +6 -0
  20. data/app/planners/main.rb +5 -0
  21. data/app/scripts/distributed +3 -0
  22. data/app/scripts/generate/bookmarks +3 -0
  23. data/app/scripts/replay +3 -0
  24. data/app/scripts/results +3 -0
  25. data/app/scripts/run +3 -0
  26. data/app/scripts/server +3 -0
  27. data/app/scripts/shell +3 -0
  28. data/app/scripts/test +3 -0
  29. data/app/tasks/.gitattributes +0 -0
  30. data/app/tasks/ROBOT/.gitattributes +0 -0
  31. data/bin/roby +210 -0
  32. data/bin/roby-log +168 -0
  33. data/bin/roby-shell +25 -0
  34. data/doc/images/event_generalization.png +0 -0
  35. data/doc/images/exception_propagation_1.png +0 -0
  36. data/doc/images/exception_propagation_2.png +0 -0
  37. data/doc/images/exception_propagation_3.png +0 -0
  38. data/doc/images/exception_propagation_4.png +0 -0
  39. data/doc/images/exception_propagation_5.png +0 -0
  40. data/doc/images/replay_handler_error.png +0 -0
  41. data/doc/images/replay_handler_error_0.png +0 -0
  42. data/doc/images/replay_handler_error_1.png +0 -0
  43. data/doc/images/roby_cycle_overview.png +0 -0
  44. data/doc/images/roby_replay_02.png +0 -0
  45. data/doc/images/roby_replay_03.png +0 -0
  46. data/doc/images/roby_replay_04.png +0 -0
  47. data/doc/images/roby_replay_event_representation.png +0 -0
  48. data/doc/images/roby_replay_first_state.png +0 -0
  49. data/doc/images/roby_replay_relations.png +0 -0
  50. data/doc/images/roby_replay_startup.png +0 -0
  51. data/doc/images/task_event_generalization.png +0 -0
  52. data/doc/papers.rdoc +11 -0
  53. data/doc/styles/allison.css +314 -0
  54. data/doc/styles/allison.js +316 -0
  55. data/doc/styles/allison.rb +276 -0
  56. data/doc/styles/jamis.rb +593 -0
  57. data/doc/tutorials/01-GettingStarted.rdoc +86 -0
  58. data/doc/tutorials/02-GoForward.rdoc +220 -0
  59. data/doc/tutorials/03-PlannedPath.rdoc +268 -0
  60. data/doc/tutorials/04-EventPropagation.rdoc +236 -0
  61. data/doc/tutorials/05-ErrorHandling.rdoc +319 -0
  62. data/doc/tutorials/06-Overview.rdoc +40 -0
  63. data/doc/videos.rdoc +69 -0
  64. data/ext/droby/dump.cc +175 -0
  65. data/ext/droby/extconf.rb +3 -0
  66. data/ext/graph/algorithm.cc +746 -0
  67. data/ext/graph/extconf.rb +7 -0
  68. data/ext/graph/graph.cc +529 -0
  69. data/ext/graph/graph.hh +183 -0
  70. data/ext/graph/iterator_sequence.hh +102 -0
  71. data/ext/graph/undirected_dfs.hh +226 -0
  72. data/ext/graph/undirected_graph.hh +421 -0
  73. data/lib/roby.rb +41 -0
  74. data/lib/roby/app.rb +870 -0
  75. data/lib/roby/app/rake.rb +56 -0
  76. data/lib/roby/app/run.rb +14 -0
  77. data/lib/roby/app/scripts/distributed.rb +13 -0
  78. data/lib/roby/app/scripts/generate/bookmarks.rb +162 -0
  79. data/lib/roby/app/scripts/replay.rb +31 -0
  80. data/lib/roby/app/scripts/results.rb +15 -0
  81. data/lib/roby/app/scripts/run.rb +26 -0
  82. data/lib/roby/app/scripts/server.rb +18 -0
  83. data/lib/roby/app/scripts/shell.rb +88 -0
  84. data/lib/roby/app/scripts/test.rb +40 -0
  85. data/lib/roby/basic_object.rb +151 -0
  86. data/lib/roby/config.rb +5 -0
  87. data/lib/roby/control.rb +747 -0
  88. data/lib/roby/decision_control.rb +17 -0
  89. data/lib/roby/distributed.rb +32 -0
  90. data/lib/roby/distributed/base.rb +440 -0
  91. data/lib/roby/distributed/communication.rb +871 -0
  92. data/lib/roby/distributed/connection_space.rb +592 -0
  93. data/lib/roby/distributed/distributed_object.rb +206 -0
  94. data/lib/roby/distributed/drb.rb +62 -0
  95. data/lib/roby/distributed/notifications.rb +539 -0
  96. data/lib/roby/distributed/peer.rb +550 -0
  97. data/lib/roby/distributed/protocol.rb +529 -0
  98. data/lib/roby/distributed/proxy.rb +343 -0
  99. data/lib/roby/distributed/subscription.rb +311 -0
  100. data/lib/roby/distributed/transaction.rb +498 -0
  101. data/lib/roby/event.rb +897 -0
  102. data/lib/roby/exceptions.rb +234 -0
  103. data/lib/roby/executives/simple.rb +30 -0
  104. data/lib/roby/graph.rb +166 -0
  105. data/lib/roby/interface.rb +390 -0
  106. data/lib/roby/log.rb +3 -0
  107. data/lib/roby/log/chronicle.rb +303 -0
  108. data/lib/roby/log/console.rb +72 -0
  109. data/lib/roby/log/data_stream.rb +197 -0
  110. data/lib/roby/log/dot.rb +279 -0
  111. data/lib/roby/log/event_stream.rb +151 -0
  112. data/lib/roby/log/file.rb +340 -0
  113. data/lib/roby/log/gui/basic_display.ui +83 -0
  114. data/lib/roby/log/gui/chronicle.rb +26 -0
  115. data/lib/roby/log/gui/chronicle_view.rb +40 -0
  116. data/lib/roby/log/gui/chronicle_view.ui +70 -0
  117. data/lib/roby/log/gui/data_displays.rb +172 -0
  118. data/lib/roby/log/gui/data_displays.ui +155 -0
  119. data/lib/roby/log/gui/notifications.rb +26 -0
  120. data/lib/roby/log/gui/relations.rb +248 -0
  121. data/lib/roby/log/gui/relations.ui +123 -0
  122. data/lib/roby/log/gui/relations_view.rb +185 -0
  123. data/lib/roby/log/gui/relations_view.ui +149 -0
  124. data/lib/roby/log/gui/replay.rb +327 -0
  125. data/lib/roby/log/gui/replay_controls.rb +200 -0
  126. data/lib/roby/log/gui/replay_controls.ui +259 -0
  127. data/lib/roby/log/gui/runtime.rb +130 -0
  128. data/lib/roby/log/hooks.rb +185 -0
  129. data/lib/roby/log/logger.rb +202 -0
  130. data/lib/roby/log/notifications.rb +244 -0
  131. data/lib/roby/log/plan_rebuilder.rb +470 -0
  132. data/lib/roby/log/relations.rb +1056 -0
  133. data/lib/roby/log/server.rb +550 -0
  134. data/lib/roby/log/sqlite.rb +47 -0
  135. data/lib/roby/log/timings.rb +164 -0
  136. data/lib/roby/plan-object.rb +247 -0
  137. data/lib/roby/plan.rb +762 -0
  138. data/lib/roby/planning.rb +13 -0
  139. data/lib/roby/planning/loops.rb +302 -0
  140. data/lib/roby/planning/model.rb +906 -0
  141. data/lib/roby/planning/task.rb +151 -0
  142. data/lib/roby/propagation.rb +562 -0
  143. data/lib/roby/query.rb +619 -0
  144. data/lib/roby/relations.rb +583 -0
  145. data/lib/roby/relations/conflicts.rb +70 -0
  146. data/lib/roby/relations/ensured.rb +20 -0
  147. data/lib/roby/relations/error_handling.rb +23 -0
  148. data/lib/roby/relations/events.rb +9 -0
  149. data/lib/roby/relations/executed_by.rb +193 -0
  150. data/lib/roby/relations/hierarchy.rb +239 -0
  151. data/lib/roby/relations/influence.rb +10 -0
  152. data/lib/roby/relations/planned_by.rb +63 -0
  153. data/lib/roby/robot.rb +7 -0
  154. data/lib/roby/standard_errors.rb +218 -0
  155. data/lib/roby/state.rb +5 -0
  156. data/lib/roby/state/events.rb +221 -0
  157. data/lib/roby/state/information.rb +55 -0
  158. data/lib/roby/state/pos.rb +110 -0
  159. data/lib/roby/state/shapes.rb +32 -0
  160. data/lib/roby/state/state.rb +353 -0
  161. data/lib/roby/support.rb +92 -0
  162. data/lib/roby/task-operations.rb +182 -0
  163. data/lib/roby/task.rb +1618 -0
  164. data/lib/roby/test/common.rb +399 -0
  165. data/lib/roby/test/distributed.rb +214 -0
  166. data/lib/roby/test/tasks/empty_task.rb +9 -0
  167. data/lib/roby/test/tasks/goto.rb +36 -0
  168. data/lib/roby/test/tasks/simple_task.rb +23 -0
  169. data/lib/roby/test/testcase.rb +519 -0
  170. data/lib/roby/test/tools.rb +160 -0
  171. data/lib/roby/thread_task.rb +87 -0
  172. data/lib/roby/transactions.rb +462 -0
  173. data/lib/roby/transactions/proxy.rb +292 -0
  174. data/lib/roby/transactions/updates.rb +139 -0
  175. data/plugins/fault_injection/History.txt +4 -0
  176. data/plugins/fault_injection/README.txt +37 -0
  177. data/plugins/fault_injection/Rakefile +18 -0
  178. data/plugins/fault_injection/TODO.txt +0 -0
  179. data/plugins/fault_injection/app.rb +52 -0
  180. data/plugins/fault_injection/fault_injection.rb +89 -0
  181. data/plugins/fault_injection/test/test_fault_injection.rb +84 -0
  182. data/plugins/subsystems/README.txt +40 -0
  183. data/plugins/subsystems/Rakefile +18 -0
  184. data/plugins/subsystems/app.rb +171 -0
  185. data/plugins/subsystems/test/app/README +24 -0
  186. data/plugins/subsystems/test/app/Rakefile +8 -0
  187. data/plugins/subsystems/test/app/config/app.yml +71 -0
  188. data/plugins/subsystems/test/app/config/init.rb +9 -0
  189. data/plugins/subsystems/test/app/config/roby.yml +3 -0
  190. data/plugins/subsystems/test/app/planners/main.rb +20 -0
  191. data/plugins/subsystems/test/app/scripts/distributed +3 -0
  192. data/plugins/subsystems/test/app/scripts/replay +3 -0
  193. data/plugins/subsystems/test/app/scripts/results +3 -0
  194. data/plugins/subsystems/test/app/scripts/run +3 -0
  195. data/plugins/subsystems/test/app/scripts/server +3 -0
  196. data/plugins/subsystems/test/app/scripts/shell +3 -0
  197. data/plugins/subsystems/test/app/scripts/test +3 -0
  198. data/plugins/subsystems/test/app/tasks/services.rb +15 -0
  199. data/plugins/subsystems/test/test_subsystems.rb +71 -0
  200. data/test/distributed/test_communication.rb +178 -0
  201. data/test/distributed/test_connection.rb +282 -0
  202. data/test/distributed/test_execution.rb +373 -0
  203. data/test/distributed/test_mixed_plan.rb +341 -0
  204. data/test/distributed/test_plan_notifications.rb +238 -0
  205. data/test/distributed/test_protocol.rb +516 -0
  206. data/test/distributed/test_query.rb +102 -0
  207. data/test/distributed/test_remote_plan.rb +491 -0
  208. data/test/distributed/test_transaction.rb +463 -0
  209. data/test/mockups/tasks.rb +27 -0
  210. data/test/planning/test_loops.rb +380 -0
  211. data/test/planning/test_model.rb +427 -0
  212. data/test/planning/test_task.rb +106 -0
  213. data/test/relations/test_conflicts.rb +42 -0
  214. data/test/relations/test_ensured.rb +38 -0
  215. data/test/relations/test_executed_by.rb +149 -0
  216. data/test/relations/test_hierarchy.rb +158 -0
  217. data/test/relations/test_planned_by.rb +54 -0
  218. data/test/suite_core.rb +24 -0
  219. data/test/suite_distributed.rb +9 -0
  220. data/test/suite_planning.rb +3 -0
  221. data/test/suite_relations.rb +8 -0
  222. data/test/test_bgl.rb +508 -0
  223. data/test/test_control.rb +399 -0
  224. data/test/test_event.rb +894 -0
  225. data/test/test_exceptions.rb +592 -0
  226. data/test/test_interface.rb +37 -0
  227. data/test/test_log.rb +114 -0
  228. data/test/test_log_server.rb +132 -0
  229. data/test/test_plan.rb +584 -0
  230. data/test/test_propagation.rb +210 -0
  231. data/test/test_query.rb +266 -0
  232. data/test/test_relations.rb +180 -0
  233. data/test/test_state.rb +414 -0
  234. data/test/test_support.rb +16 -0
  235. data/test/test_task.rb +938 -0
  236. data/test/test_testcase.rb +122 -0
  237. data/test/test_thread_task.rb +73 -0
  238. data/test/test_transactions.rb +569 -0
  239. data/test/test_transactions_proxy.rb +198 -0
  240. metadata +570 -0
@@ -0,0 +1,463 @@
1
+ $LOAD_PATH.unshift File.expand_path('../..', File.dirname(__FILE__))
2
+ require 'roby/test/distributed'
3
+ require 'roby/test/tasks/simple_task'
4
+
5
+ class TC_DistributedTransaction < Test::Unit::TestCase
6
+ include Roby::Distributed::Test
7
+
8
+ def test_marshal_transactions
9
+ peer2peer(true) do |remote|
10
+ PeerServer.class_eval do
11
+ attr_reader :plan
12
+ def transaction
13
+ @plan ||= Plan.new
14
+ Roby::Transaction.new(plan)
15
+ end
16
+ def d_transaction
17
+ @plan ||= Plan.new
18
+ Roby::Distributed::Transaction.new(plan)
19
+ end
20
+ end
21
+ end
22
+
23
+ trsc = remote_peer.call(:transaction)
24
+ assert_kind_of(Plan::DRoby, trsc)
25
+ assert_equal(local.plan, remote_peer.local_object(trsc))
26
+
27
+ dtrsc = remote_peer.call(:d_transaction)
28
+ assert_kind_of(Distributed::Transaction::DRoby, dtrsc)
29
+ assert_raises(InvalidRemoteOperation) { remote_peer.local_object(dtrsc) }
30
+ end
31
+
32
+ def test_transaction_create
33
+ peer2peer(true) do |remote|
34
+ PeerServer.class_eval do
35
+ include Test::Unit::Assertions
36
+ def check_transaction(marshalled_trsc, trsc_drbobject)
37
+ assert(trsc = peer.local_object(marshalled_trsc))
38
+ assert_equal(trsc_drbobject, trsc.remote_siblings[peer])
39
+ assert_equal([peer, Roby::Distributed], trsc.owners)
40
+ assert(!trsc.first_editor?)
41
+ assert(!trsc.editor?)
42
+ assert(trsc.conflict_solver.kind_of?(Roby::SolverIgnoreUpdate))
43
+
44
+ assert(trsc.subscribed?)
45
+ assert(trsc.update_on?(peer))
46
+ assert(trsc.updated_by?(peer))
47
+ trsc
48
+ end
49
+ end
50
+ end
51
+ trsc = Distributed::Transaction.new(plan, :conflict_solver => SolverIgnoreUpdate.new)
52
+ assert(trsc.self_owned?)
53
+ assert(trsc.first_editor?)
54
+ assert(trsc.editor?)
55
+
56
+ remote_peer.create_sibling(trsc)
57
+ trsc.add_owner remote_peer
58
+ assert_equal([Distributed, remote_peer], trsc.owners)
59
+ remote_peer.call(:check_transaction, trsc, trsc.remote_id)
60
+ assert(trsc.subscribed?)
61
+ assert(trsc.update_on?(remote_peer))
62
+ assert(trsc.updated_by?(remote_peer))
63
+
64
+ assert(trsc.editor?)
65
+ end
66
+
67
+ def test_transaction_proxies
68
+ peer2peer(true) do |remote|
69
+ PeerServer.class_eval do
70
+ include Test::Unit::Assertions
71
+ def marshalled_transaction_proxy(trsc, task)
72
+ task = peer.local_object(task)
73
+ trsc = peer.local_object(trsc)
74
+ proxy = trsc[task]
75
+
76
+ assert(proxy.update_on?(peer))
77
+ assert(proxy.updated_by?(peer))
78
+ proxy
79
+ end
80
+ end
81
+ end
82
+ trsc = Distributed::Transaction.new(plan)
83
+ remote_peer.create_sibling(trsc)
84
+
85
+ # Check that marshalling the remote view of a local transaction proxy
86
+ # returns the local proxy itself
87
+ plan.insert(task = Task.new)
88
+ assert(!plan.update_on?(remote_peer))
89
+ assert(trsc.update_on?(remote_peer))
90
+ assert(!task.update_on?(remote_peer))
91
+
92
+ proxy = trsc[task]
93
+ assert(task.update_on?(remote_peer))
94
+ assert(proxy.update_on?(remote_peer))
95
+ assert(proxy.updated_by?(remote_peer))
96
+ process_events
97
+
98
+ assert(marshalled_remote = remote_peer.call(:marshalled_transaction_proxy, trsc, task))
99
+ assert_equal(proxy, remote_peer.local_object(marshalled_remote))
100
+ end
101
+
102
+ # Checks that if we discover a set of tasks, then their relations are updated as well
103
+ def test_discover
104
+ peer2peer(true) do |remote|
105
+ def remote.add_tasks(trsc)
106
+ trsc = local_peer.local_object(trsc)
107
+
108
+ trsc.edit do
109
+ t1 = SimpleTask.new :id => 'root'
110
+ t1.realized_by(t2 = SimpleTask.new(:id => 'child'))
111
+ t1.on(:start, t2, :start)
112
+ t2.realized_by(t3 = SimpleTask.new(:id => 'grandchild'))
113
+ t3.on(:failed, t2, :failed)
114
+
115
+ trsc.insert(t1)
116
+ end
117
+ end
118
+ end
119
+
120
+ trsc = Distributed::Transaction.new(plan)
121
+ trsc.add_owner remote_peer
122
+ trsc.propose(remote_peer)
123
+
124
+ trsc.release(false)
125
+ remote.add_tasks(Distributed.format(trsc))
126
+ trsc.edit
127
+ assert(t1 = trsc.find_tasks.with_arguments(:id => 'root').to_a.first)
128
+ assert(t2 = trsc.find_tasks.with_arguments(:id => 'child').to_a.first)
129
+ assert(t3 = trsc.find_tasks.with_arguments(:id => 'grandchild').to_a.first)
130
+
131
+ assert(t1.child_object?(t2, TaskStructure::Hierarchy))
132
+ assert(t2.child_object?(t3, TaskStructure::Hierarchy))
133
+ end
134
+
135
+ def test_edition
136
+ peer2peer(true) do |remote|
137
+ class << remote
138
+ include Test::Unit::Assertions
139
+ def edit_transaction(trsc)
140
+ trsc = local_peer.local_object(trsc)
141
+ trsc.edit
142
+ assert_equal(local_peer, trsc.next_editor)
143
+ assert(trsc.editor?)
144
+ end
145
+ def give_back(trsc)
146
+ trsc = local_peer.local_object(trsc)
147
+ assert(trsc.editor?)
148
+ trsc.release(false)
149
+ end
150
+ end
151
+ end
152
+
153
+ trsc = Distributed::Transaction.new(plan)
154
+ remote_trsc = remote_peer.create_sibling(trsc)
155
+ trsc.edit
156
+
157
+ assert(trsc.editor?)
158
+ assert(!trsc.release(false))
159
+
160
+ trsc.add_owner remote_peer
161
+ assert_equal(remote_peer, trsc.next_editor)
162
+ assert(trsc.release(true))
163
+
164
+ assert_doesnt_timeout(5) do
165
+ remote.edit_transaction(Distributed.format(trsc))
166
+ end
167
+ assert_raises(NotEditor) { trsc.commit_transaction }
168
+ remote.give_back(Distributed.format(trsc))
169
+
170
+ assert_doesnt_timeout(5) do
171
+ trsc.edit
172
+ end
173
+ assert(trsc.edition_reloop)
174
+ assert_raises(NotReady) { trsc.commit_transaction }
175
+ end
176
+
177
+ def test_ownership
178
+ peer2peer(true) do |remote|
179
+ remote.plan.insert(Task.new(:id => 1))
180
+ def remote.add_owner_local(trsc)
181
+ trsc = local_peer.local_object(trsc)
182
+ trsc.add_owner local_peer
183
+ nil
184
+ end
185
+ end
186
+
187
+ # Create a transaction for the plan
188
+ trsc = Roby::Distributed::Transaction.new(plan)
189
+ remote_peer.create_sibling(trsc)
190
+ assert(Distributed.owns?(trsc))
191
+ assert(!remote_peer.owns?(trsc))
192
+
193
+ trsc.add_owner remote_peer
194
+ assert(remote_peer.owns?(trsc))
195
+ trsc.remove_owner remote_peer
196
+ assert(!remote_peer.owns?(trsc))
197
+
198
+ r_task = subscribe_task(:id => 1)
199
+ assert(!Distributed.owns?(r_task))
200
+ assert(remote_peer.owns?(r_task))
201
+ assert_raises(OwnershipError) { t_task = trsc[r_task] }
202
+ # Check we still can remove the peer from the transaction owners
203
+ trsc.add_owner(remote_peer)
204
+ t_task = trsc[r_task]
205
+
206
+ assert_raises(OwnershipError) { trsc.remove_owner(remote_peer) }
207
+ trsc.self_owned = false
208
+
209
+ task = Task.new
210
+ assert_raises(OwnershipError) { t_task.realized_by task }
211
+ assert_raises(OwnershipError) { task.realized_by t_task }
212
+ assert_raises(OwnershipError) { task.event(:start).on t_task.event(:start) }
213
+ assert_raises(OwnershipError) { trsc.discard_transaction }
214
+ assert_raises(OwnershipError) { trsc.commit_transaction }
215
+ assert(! task.plan)
216
+ assert_nothing_raised { t_task.event(:start).on task.event(:start) }
217
+
218
+ remote.add_owner_local(Distributed.format(trsc))
219
+
220
+ assert_nothing_raised { t_task.realized_by task }
221
+ assert_nothing_raised { t_task.remove_child task }
222
+ assert_nothing_raised { t_task.event(:start).remove_signal task.event(:start) }
223
+ assert_nothing_raised { task.realized_by t_task }
224
+ assert_nothing_raised { task.event(:start).on t_task.event(:start) }
225
+ assert_raises(OwnershipError) { trsc.remove_owner remote_peer }
226
+ assert_raises(OwnershipError) { trsc.self_owned = false }
227
+ assert_nothing_raised { trsc.discard_transaction }
228
+ end
229
+
230
+ def test_executed_by
231
+ peer2peer(true) do |remote|
232
+ task = Task.new(:id => 1)
233
+ exec = Class.new(Task) do
234
+ event :ready, :command => true
235
+ end.new(:id => 'exec')
236
+ task.executed_by exec
237
+ remote.plan.insert(task)
238
+
239
+ remote.singleton_class.class_eval do
240
+ include Test::Unit::Assertions
241
+ define_method(:check_execution_agent) do
242
+ remote_connection_tasks = plan.find_tasks.
243
+ with_model(ConnectionTask).
244
+ with_arguments(:peer => Roby::Distributed).
245
+ to_a
246
+ assert(remote_connection_tasks.empty?)
247
+ assert_equal(exec, task.execution_agent)
248
+ end
249
+ end
250
+ end
251
+ r_task = remote_task(:id => 1)
252
+ assert_equal(remote_peer.task, r_task.execution_agent)
253
+
254
+ trsc = Roby::Distributed::Transaction.new(plan)
255
+ trsc.add_owner remote_peer
256
+ trsc.self_owned
257
+ r_task = subscribe_task(:id => 1)
258
+ assert(!trsc[remote_peer.task].distribute?)
259
+ assert_equal(trsc[remote_peer.task], trsc[r_task].execution_agent)
260
+ trsc.propose(remote_peer)
261
+ trsc.commit_transaction
262
+
263
+ assert_equal(remote_peer.task, r_task.execution_agent)
264
+ remote.check_execution_agent
265
+ end
266
+
267
+ class ArgumentUpdateTest < Roby::Task
268
+ arguments :foo
269
+ end
270
+
271
+ def test_argument_updates
272
+ peer2peer(true) do |remote|
273
+ remote.plan.insert(ArgumentUpdateTest.new(:id => 2))
274
+ def remote.set_argument(task)
275
+ task = local_peer.local_object(task)
276
+ task.plan.edit
277
+ task.arguments[:foo] = :bar
278
+ task.plan.release(false)
279
+ nil
280
+ end
281
+ end
282
+ r_task = remote_task(:id => 2, :permanent => true)
283
+ assert_raises(OwnershipError, r_task.owners) { r_task.arguments[:foo] = :bar }
284
+
285
+ trsc = Roby::Distributed::Transaction.new(plan)
286
+ trsc.add_owner remote_peer
287
+ trsc.self_owned
288
+ trsc.propose(remote_peer)
289
+
290
+ t_task = trsc[r_task]
291
+ trsc.release(false)
292
+ assert_nothing_raised { remote.set_argument(Distributed.format(t_task)) }
293
+
294
+ trsc.edit
295
+ assert_equal(:bar, t_task.arguments[:foo], t_task.name)
296
+ assert(!t_task.arguments.writable?(:foo))
297
+ assert_raises(ArgumentError) { t_task.arguments[:foo] = :blo }
298
+ trsc.commit_transaction
299
+ assert_equal(:bar, r_task.arguments[:foo])
300
+ end
301
+
302
+ def build_transaction(trsc)
303
+
304
+ # Now, add a task of our own and link the remote and the local
305
+ task = SimpleTask.new :id => 'local'
306
+ trsc.discover(task)
307
+
308
+ parent = subscribe_task(:id => 'remote-1')
309
+ child = subscribe_task(:id => 'remote-2')
310
+
311
+ # Check some properties
312
+ assert((trsc[parent].owners - trsc.owners).empty?)
313
+ assert(trsc[parent].read_write?)
314
+ assert(task.read_write?)
315
+ assert(trsc[parent].event(:start).read_write?)
316
+ assert(trsc[parent].event(:stop).read_write?)
317
+ assert(task.event(:start).read_write?)
318
+ assert(task.event(:stop).read_write?)
319
+
320
+ # Add relations
321
+ trsc[parent].realized_by task
322
+ task.realized_by trsc[child]
323
+ trsc[parent].event(:start).on task.event(:start)
324
+ task.event(:stop).on trsc[child].event(:stop)
325
+
326
+ [task, parent]
327
+ end
328
+
329
+ # Checks that +plan+ looks like the result of #build_transaction
330
+ def check_resulting_plan(plan)
331
+ #assert_equal(4, plan.known_tasks.size)
332
+ r_task = plan.known_tasks.find { |t| t.arguments[:id] == 'remote-1' }
333
+ task = plan.known_tasks.find { |t| t.arguments[:id] == 'local' }
334
+ c_task = plan.known_tasks.find { |t| t.arguments[:id] == 'remote-2' }
335
+
336
+ assert_equal(2, r_task.children.to_a.size, r_task.children)
337
+ assert(r_task.child_object?(task, Roby::TaskStructure::Hierarchy))
338
+ assert_equal([task.event(:start)], r_task.event(:start).child_objects(Roby::EventStructure::Signal).to_a)
339
+ assert_equal([c_task], task.children.to_a)
340
+ assert_equal([c_task.event(:stop)], task.event(:stop).child_objects(Roby::EventStructure::Signal).to_a)
341
+ assert(r_task.child_object?(c_task, Roby::TaskStructure::Hierarchy))
342
+ end
343
+
344
+ # Commit the transaction and checks the result
345
+ def check_transaction_commit(trsc)
346
+ # Commit the transaction
347
+ assert(trsc.commit_transaction)
348
+ remote_peer.call(:check_plan)
349
+ check_resulting_plan(local.plan)
350
+ end
351
+
352
+ def test_propose_commit
353
+ peer2peer(true) do |remote|
354
+ testcase = self
355
+ remote.plan.insert(root = SimpleTask.new(:id => 'remote-1'))
356
+ root.realized_by(child = SimpleTask.new(:id => 'remote-2'))
357
+
358
+ PeerServer.class_eval do
359
+ include Test::Unit::Assertions
360
+ define_method(:check_transaction) do |trsc|
361
+ trsc = peer.local_object(trsc)
362
+ testcase.check_resulting_plan(trsc)
363
+ end
364
+ define_method(:check_plan) do
365
+ testcase.check_resulting_plan(plan)
366
+ end
367
+ end
368
+ end
369
+ trsc = Roby::Distributed::Transaction.new(plan)
370
+ trsc.add_owner remote_peer
371
+ trsc.self_owned
372
+
373
+ task, r_task = build_transaction(trsc)
374
+
375
+ # Send the transaction to remote_peer and commit it
376
+ trsc.propose(remote_peer)
377
+
378
+ remote_peer.call(:check_transaction, trsc)
379
+ check_resulting_plan(trsc)
380
+
381
+ check_transaction_commit(trsc)
382
+ end
383
+
384
+ def test_synchronization
385
+ peer2peer(true) do |remote|
386
+ testcase = self
387
+ remote.plan.insert(root = SimpleTask.new(:id => 'remote-1'))
388
+ root.realized_by SimpleTask.new(:id => 'remote-2')
389
+
390
+ PeerServer.class_eval do
391
+ define_method(:check_transaction) do |trsc|
392
+ testcase.check_resulting_plan(peer.local_object(trsc))
393
+ end
394
+ define_method(:check_plan) { testcase.check_resulting_plan(remote.plan) }
395
+ end
396
+ end
397
+
398
+ # Create a transaction for the plan and send it right away
399
+ trsc = Roby::Distributed::Transaction.new(plan)
400
+ trsc.self_owned
401
+ trsc.add_owner remote_peer
402
+ trsc.propose(remote_peer)
403
+
404
+ task, r_task = build_transaction(trsc)
405
+
406
+ check_resulting_plan(trsc)
407
+ process_events
408
+ remote_peer.call(:check_transaction, trsc)
409
+
410
+ # Commit the transaction
411
+ check_transaction_commit(trsc)
412
+ end
413
+
414
+ def test_create_remote_tasks
415
+ peer2peer(true) do |remote|
416
+ def remote.arguments_of(t)
417
+ t = local_peer.local_object(t)
418
+ t.arguments
419
+ end
420
+
421
+ def remote.check_ownership(t)
422
+ t = local_peer.local_object(t)
423
+ t.self_owned?
424
+ end
425
+
426
+ def remote.check_mission(t)
427
+ t = local_peer.local_object(t)
428
+ plan.mission?(t)
429
+ end
430
+ end
431
+
432
+ trsc = Roby::Distributed::Transaction.new(plan)
433
+ trsc.add_owner remote_peer
434
+ trsc.propose(remote_peer)
435
+
436
+ local_task = SimpleTask.new(:id => 'local')
437
+ trsc.insert(local_task)
438
+
439
+ t = SimpleTask.new(:arg => 10, :id => 0)
440
+ t.extend DistributedObject
441
+ local_task.realized_by t
442
+ trsc.insert(t)
443
+ t.owner = remote_peer
444
+
445
+ assert(trsc.task_index.by_owner[remote_peer].include?(t))
446
+ assert(!trsc.task_index.by_owner[Roby::Distributed].include?(t))
447
+
448
+ assert(!t.self_owned?)
449
+ assert(remote.check_ownership(Distributed.format(t)))
450
+
451
+ trsc.commit_transaction
452
+ assert(plan.include?(t))
453
+ assert(!plan.mission?(t))
454
+ assert(!t.self_owned?)
455
+ assert(plan.task_index.by_owner[remote_peer].include?(t), plan.task_index.by_owner)
456
+ assert(!plan.task_index.by_owner[Roby::Distributed].include?(t))
457
+ assert(remote.check_mission(Distributed.format(t)))
458
+ assert(remote.check_ownership(Distributed.format(t)))
459
+ assert(local_task.children.include?(t))
460
+ assert_equal({ :arg => 10, :id => 0 }, remote.arguments_of(Distributed.format(t)))
461
+ end
462
+ end
463
+