roby 0.7.3 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +7 -5
- data/Manifest.txt +91 -16
- data/README.txt +24 -24
- data/Rakefile +92 -64
- data/app/config/app.yml +42 -43
- data/app/config/init.rb +26 -0
- data/benchmark/alloc_misc.rb +123 -0
- data/benchmark/discovery_latency.rb +67 -0
- data/benchmark/garbage_collection.rb +48 -0
- data/benchmark/genom.rb +31 -0
- data/benchmark/transactions.rb +62 -0
- data/bin/roby +1 -1
- data/bin/roby-log +16 -6
- data/doc/guide/.gitignore +2 -0
- data/doc/guide/config.yaml +34 -0
- data/doc/guide/ext/init.rb +14 -0
- data/doc/guide/ext/previous_next.rb +40 -0
- data/doc/guide/ext/rdoc_links.rb +33 -0
- data/doc/guide/index.rdoc +16 -0
- data/doc/guide/overview.rdoc +62 -0
- data/doc/guide/plan_modifications.rdoc +67 -0
- data/doc/guide/src/abstraction/achieve_with.page +8 -0
- data/doc/guide/src/abstraction/forwarding.page +8 -0
- data/doc/guide/src/abstraction/hierarchy.page +19 -0
- data/doc/guide/src/abstraction/index.page +28 -0
- data/doc/guide/src/abstraction/task_models.page +13 -0
- data/doc/guide/src/basics.template +6 -0
- data/doc/guide/src/basics/app.page +139 -0
- data/doc/guide/src/basics/code_examples.page +33 -0
- data/doc/guide/src/basics/dry.page +69 -0
- data/doc/guide/src/basics/errors.page +443 -0
- data/doc/guide/src/basics/events.page +179 -0
- data/doc/guide/src/basics/hierarchy.page +275 -0
- data/doc/guide/src/basics/index.page +11 -0
- data/doc/guide/src/basics/log_replay/goForward_1.png +0 -0
- data/doc/guide/src/basics/log_replay/goForward_2.png +0 -0
- data/doc/guide/src/basics/log_replay/goForward_3.png +0 -0
- data/doc/guide/src/basics/log_replay/goForward_4.png +0 -0
- data/doc/guide/src/basics/log_replay/goForward_5.png +0 -0
- data/doc/guide/src/basics/log_replay/hierarchy_error_1.png +0 -0
- data/doc/guide/src/basics/log_replay/hierarchy_error_2.png +0 -0
- data/doc/guide/src/basics/log_replay/hierarchy_error_3.png +0 -0
- data/doc/guide/src/basics/log_replay/plan_repair_1.png +0 -0
- data/doc/guide/src/basics/log_replay/plan_repair_2.png +0 -0
- data/doc/guide/src/basics/log_replay/plan_repair_3.png +0 -0
- data/doc/guide/src/basics/log_replay/plan_repair_4.png +0 -0
- data/doc/guide/src/basics/log_replay/roby_log_main_window.png +0 -0
- data/doc/guide/src/basics/log_replay/roby_log_relation_window.png +0 -0
- data/doc/guide/src/basics/log_replay/roby_replay_event_representation.png +0 -0
- data/doc/guide/src/basics/plan_objects.page +71 -0
- data/doc/guide/src/basics/relations_display.page +203 -0
- data/doc/guide/src/basics/roby_cycle_overview.png +0 -0
- data/doc/guide/src/basics/shell.page +102 -0
- data/doc/guide/src/basics/summary.page +32 -0
- data/doc/guide/src/basics/tasks.page +357 -0
- data/doc/guide/src/basics_shell_header.txt +16 -0
- data/doc/guide/src/cycle/cycle-overview.png +0 -0
- data/doc/guide/src/cycle/cycle-overview.svg +208 -0
- data/doc/guide/src/cycle/error_handling.page +168 -0
- data/doc/guide/src/cycle/error_instantaneous_repair.png +0 -0
- data/doc/guide/src/cycle/error_instantaneous_repair.svg +1224 -0
- data/doc/guide/src/cycle/garbage_collection.page +10 -0
- data/doc/guide/src/cycle/index.page +23 -0
- data/doc/guide/src/cycle/propagation.page +154 -0
- data/doc/guide/src/cycle/propagation_diamond.png +0 -0
- data/doc/guide/src/cycle/propagation_diamond.svg +1279 -0
- data/doc/guide/src/default.css +319 -0
- data/doc/guide/src/default.template +74 -0
- data/doc/guide/src/htmldoc.metainfo +20 -0
- data/doc/guide/src/htmldoc.virtual +18 -0
- data/doc/guide/src/images/bodybg.png +0 -0
- data/doc/guide/src/images/contbg.png +0 -0
- data/doc/guide/src/images/footerbg.png +0 -0
- data/doc/guide/src/images/gradient1.png +0 -0
- data/doc/guide/src/images/gradient2.png +0 -0
- data/doc/guide/src/index.page +7 -0
- data/doc/guide/src/introduction/index.page +29 -0
- data/doc/guide/src/introduction/install.page +133 -0
- data/doc/{papers.rdoc → guide/src/introduction/publications.page} +5 -2
- data/doc/{videos.rdoc → guide/src/introduction/videos.page} +4 -2
- data/doc/guide/src/plugins/fault_tolerance.page +44 -0
- data/doc/guide/src/plugins/index.page +11 -0
- data/doc/guide/src/plugins/subsystems.page +45 -0
- data/doc/guide/src/relations/dependency.page +89 -0
- data/doc/guide/src/relations/index.page +12 -0
- data/doc/misc/update_github +24 -0
- data/doc/tutorials/02-GoForward.rdoc +3 -3
- data/ext/graph/graph.cc +46 -0
- data/lib/roby.rb +57 -22
- data/lib/roby/app.rb +132 -112
- data/lib/roby/app/plugins/rake.rb +21 -0
- data/lib/roby/app/rake.rb +0 -7
- data/lib/roby/app/run.rb +1 -1
- data/lib/roby/app/scripts/distributed.rb +1 -2
- data/lib/roby/app/scripts/generate/bookmarks.rb +1 -1
- data/lib/roby/app/scripts/results.rb +2 -1
- data/lib/roby/app/scripts/run.rb +6 -2
- data/lib/roby/app/scripts/shell.rb +11 -11
- data/lib/roby/config.rb +1 -1
- data/lib/roby/decision_control.rb +62 -3
- data/lib/roby/distributed.rb +4 -0
- data/lib/roby/distributed/base.rb +8 -0
- data/lib/roby/distributed/communication.rb +12 -8
- data/lib/roby/distributed/connection_space.rb +61 -44
- data/lib/roby/distributed/distributed_object.rb +1 -1
- data/lib/roby/distributed/notifications.rb +22 -30
- data/lib/roby/distributed/peer.rb +13 -8
- data/lib/roby/distributed/proxy.rb +5 -5
- data/lib/roby/distributed/subscription.rb +4 -4
- data/lib/roby/distributed/transaction.rb +3 -3
- data/lib/roby/event.rb +176 -110
- data/lib/roby/exceptions.rb +12 -4
- data/lib/roby/execution_engine.rb +1604 -0
- data/lib/roby/external_process_task.rb +225 -0
- data/lib/roby/graph.rb +0 -6
- data/lib/roby/interface.rb +221 -137
- data/lib/roby/log/console.rb +5 -3
- data/lib/roby/log/data_stream.rb +94 -16
- data/lib/roby/log/dot.rb +8 -8
- data/lib/roby/log/event_stream.rb +13 -3
- data/lib/roby/log/file.rb +43 -18
- data/lib/roby/log/gui/basic_display_ui.rb +89 -0
- data/lib/roby/log/gui/chronicle_view_ui.rb +90 -0
- data/lib/roby/log/gui/data_displays.rb +4 -5
- data/lib/roby/log/gui/data_displays_ui.rb +146 -0
- data/lib/roby/log/gui/relations.rb +18 -18
- data/lib/roby/log/gui/relations_ui.rb +120 -0
- data/lib/roby/log/gui/relations_view_ui.rb +144 -0
- data/lib/roby/log/gui/replay.rb +41 -13
- data/lib/roby/log/gui/replay_controls.rb +3 -0
- data/lib/roby/log/gui/replay_controls.ui +133 -110
- data/lib/roby/log/gui/replay_controls_ui.rb +249 -0
- data/lib/roby/log/hooks.rb +19 -18
- data/lib/roby/log/logger.rb +7 -6
- data/lib/roby/log/notifications.rb +4 -4
- data/lib/roby/log/plan_rebuilder.rb +20 -22
- data/lib/roby/log/relations.rb +44 -16
- data/lib/roby/log/server.rb +1 -4
- data/lib/roby/log/timings.rb +88 -19
- data/lib/roby/plan-object.rb +135 -11
- data/lib/roby/plan.rb +408 -224
- data/lib/roby/planning/loops.rb +32 -25
- data/lib/roby/planning/model.rb +157 -51
- data/lib/roby/planning/task.rb +47 -20
- data/lib/roby/query.rb +128 -92
- data/lib/roby/relations.rb +254 -136
- data/lib/roby/relations/conflicts.rb +6 -9
- data/lib/roby/relations/dependency.rb +358 -0
- data/lib/roby/relations/ensured.rb +0 -1
- data/lib/roby/relations/error_handling.rb +0 -1
- data/lib/roby/relations/events.rb +0 -2
- data/lib/roby/relations/executed_by.rb +26 -11
- data/lib/roby/relations/planned_by.rb +14 -14
- data/lib/roby/robot.rb +46 -0
- data/lib/roby/schedulers/basic.rb +34 -0
- data/lib/roby/standalone.rb +4 -0
- data/lib/roby/standard_errors.rb +21 -15
- data/lib/roby/state/events.rb +5 -4
- data/lib/roby/support.rb +107 -6
- data/lib/roby/task-operations.rb +23 -19
- data/lib/roby/task.rb +522 -148
- data/lib/roby/task_index.rb +80 -0
- data/lib/roby/test/common.rb +283 -44
- data/lib/roby/test/distributed.rb +53 -37
- data/lib/roby/test/testcase.rb +9 -204
- data/lib/roby/test/tools.rb +3 -3
- data/lib/roby/transactions.rb +154 -111
- data/lib/roby/transactions/proxy.rb +40 -7
- data/manifest.xml +20 -0
- data/plugins/fault_injection/README.txt +0 -3
- data/plugins/fault_injection/Rakefile +2 -8
- data/plugins/fault_injection/app.rb +1 -1
- data/plugins/fault_injection/fault_injection.rb +3 -3
- data/plugins/fault_injection/test/test_fault_injection.rb +19 -25
- data/plugins/subsystems/README.txt +0 -3
- data/plugins/subsystems/Rakefile +2 -7
- data/plugins/subsystems/app.rb +27 -16
- data/plugins/subsystems/test/app/config/init.rb +3 -0
- data/plugins/subsystems/test/app/planners/main.rb +1 -1
- data/plugins/subsystems/test/app/tasks/services.rb +1 -1
- data/plugins/subsystems/test/test_subsystems.rb +23 -16
- data/test/distributed/test_communication.rb +32 -15
- data/test/distributed/test_connection.rb +28 -26
- data/test/distributed/test_execution.rb +59 -54
- data/test/distributed/test_mixed_plan.rb +34 -34
- data/test/distributed/test_plan_notifications.rb +26 -26
- data/test/distributed/test_protocol.rb +57 -48
- data/test/distributed/test_query.rb +11 -7
- data/test/distributed/test_remote_plan.rb +71 -71
- data/test/distributed/test_transaction.rb +50 -47
- data/test/mockups/external_process +28 -0
- data/test/planning/test_loops.rb +163 -119
- data/test/planning/test_model.rb +3 -3
- data/test/planning/test_task.rb +27 -7
- data/test/relations/test_conflicts.rb +3 -3
- data/test/relations/test_dependency.rb +324 -0
- data/test/relations/test_ensured.rb +2 -2
- data/test/relations/test_executed_by.rb +94 -19
- data/test/relations/test_planned_by.rb +11 -9
- data/test/suite_core.rb +6 -3
- data/test/suite_distributed.rb +1 -0
- data/test/suite_planning.rb +1 -0
- data/test/suite_relations.rb +2 -2
- data/test/tasks/test_external_process.rb +126 -0
- data/test/{test_thread_task.rb → tasks/test_thread_task.rb} +17 -20
- data/test/test_bgl.rb +21 -1
- data/test/test_event.rb +229 -155
- data/test/test_exceptions.rb +79 -80
- data/test/test_execution_engine.rb +987 -0
- data/test/test_gui.rb +1 -1
- data/test/test_interface.rb +11 -5
- data/test/test_log.rb +18 -7
- data/test/test_log_server.rb +1 -0
- data/test/test_plan.rb +229 -395
- data/test/test_query.rb +193 -35
- data/test/test_relations.rb +88 -8
- data/test/test_state.rb +55 -37
- data/test/test_support.rb +1 -1
- data/test/test_task.rb +371 -218
- data/test/test_testcase.rb +32 -16
- data/test/test_transactions.rb +211 -170
- data/test/test_transactions_proxy.rb +37 -19
- metadata +169 -71
- data/.gitignore +0 -29
- data/doc/styles/allison.css +0 -314
- data/doc/styles/allison.js +0 -316
- data/doc/styles/allison.rb +0 -276
- data/doc/styles/jamis.rb +0 -593
- data/lib/roby/control.rb +0 -746
- data/lib/roby/executives/simple.rb +0 -30
- data/lib/roby/propagation.rb +0 -562
- data/lib/roby/relations/hierarchy.rb +0 -239
- data/lib/roby/transactions/updates.rb +0 -139
- data/test/relations/test_hierarchy.rb +0 -158
- data/test/test_control.rb +0 -399
- data/test/test_propagation.rb +0 -210
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), File.dirname(__FILE__))
|
|
2
2
|
require 'roby/test/distributed'
|
|
3
3
|
require 'roby/test/tasks/simple_task'
|
|
4
4
|
|
|
@@ -17,18 +17,18 @@ require 'roby/test/tasks/simple_task'
|
|
|
17
17
|
class TC_DistributedMixedPlan < Test::Unit::TestCase
|
|
18
18
|
include Roby::Distributed::Test
|
|
19
19
|
|
|
20
|
-
# Creates in +plan+ a task which is a child in a
|
|
20
|
+
# Creates in +plan+ a task which is a child in a depends_on relation and a parent
|
|
21
21
|
# in a planned_by relation. All tasks have an ID of "#{name}-#{number}", with
|
|
22
22
|
# 2 for the central task, 1 for its parent task and 3 for its planning task.
|
|
23
23
|
#
|
|
24
24
|
# Returns [-1, -2, -3]
|
|
25
25
|
def add_tasks(plan, name)
|
|
26
26
|
t1, t2, t3 = (1..3).map { |i| SimpleTask.new(:id => "#{name}-#{i}") }
|
|
27
|
-
t1.
|
|
27
|
+
t1.depends_on t2
|
|
28
28
|
t2.planned_by t3
|
|
29
|
-
plan.
|
|
30
|
-
plan.
|
|
31
|
-
plan.
|
|
29
|
+
plan.add_mission(t1)
|
|
30
|
+
plan.add(t2)
|
|
31
|
+
plan.add(t3)
|
|
32
32
|
|
|
33
33
|
[t1, t2, t3]
|
|
34
34
|
end
|
|
@@ -59,8 +59,8 @@ class TC_DistributedMixedPlan < Test::Unit::TestCase
|
|
|
59
59
|
#
|
|
60
60
|
# Tests are in two parts: first we build the transaction and check the
|
|
61
61
|
# relations of the resulting proxies. Then, we remove all relations of
|
|
62
|
-
# tasks *in the plan*. Since we have added a
|
|
63
|
-
# central tasks, the
|
|
62
|
+
# tasks *in the plan*. Since we have added a depends_on between the
|
|
63
|
+
# central tasks, the depends_on relations are kept inside the transaction.
|
|
64
64
|
# However, this is not the case for planning relations. Thus, the planning
|
|
65
65
|
# relation does not exist anymore in the transaction after they have been
|
|
66
66
|
# removed from the plan.
|
|
@@ -83,7 +83,7 @@ class TC_DistributedMixedPlan < Test::Unit::TestCase
|
|
|
83
83
|
|
|
84
84
|
# Common setup of the remote peer
|
|
85
85
|
def common_setup(propose_first)
|
|
86
|
-
peer2peer
|
|
86
|
+
peer2peer do |remote|
|
|
87
87
|
testcase = self
|
|
88
88
|
remote.singleton_class.class_eval do
|
|
89
89
|
define_method(:add_tasks) do |plan|
|
|
@@ -118,7 +118,7 @@ class TC_DistributedMixedPlan < Test::Unit::TestCase
|
|
|
118
118
|
end
|
|
119
119
|
|
|
120
120
|
# Create the transaction, and do the necessary modifications
|
|
121
|
-
trsc = Distributed::Transaction.new(plan
|
|
121
|
+
trsc = Distributed::Transaction.new(plan)
|
|
122
122
|
|
|
123
123
|
trsc.add_owner remote_peer
|
|
124
124
|
trsc.self_owned
|
|
@@ -147,11 +147,11 @@ class TC_DistributedMixedPlan < Test::Unit::TestCase
|
|
|
147
147
|
r_t2 = subscribe_task(:id => 'remote-2')
|
|
148
148
|
assert(1, r_t2.parents.to_a.size)
|
|
149
149
|
r_t1 = r_t2.parents.find { true }
|
|
150
|
-
t1, t2, t3 =
|
|
150
|
+
t1, t2, t3 = Roby.synchronize { add_tasks(plan, "local") }
|
|
151
151
|
|
|
152
152
|
assert(plan.useful_task?(r_t1))
|
|
153
|
-
trsc[r_t2].
|
|
154
|
-
trsc[r_t2].
|
|
153
|
+
trsc[r_t2].depends_on trsc[t2]
|
|
154
|
+
trsc[r_t2].signals(:start, trsc[t2], :start)
|
|
155
155
|
assert(plan.useful_task?(r_t1))
|
|
156
156
|
check_resulting_plan(trsc, false)
|
|
157
157
|
if propose_first
|
|
@@ -161,7 +161,7 @@ class TC_DistributedMixedPlan < Test::Unit::TestCase
|
|
|
161
161
|
end
|
|
162
162
|
|
|
163
163
|
# Remove the relations in the real tasks (not the proxies)
|
|
164
|
-
|
|
164
|
+
Roby.synchronize do
|
|
165
165
|
t2.remove_planning_task(t3)
|
|
166
166
|
end
|
|
167
167
|
remote.remove_relations(Distributed.format(r_t2))
|
|
@@ -185,10 +185,10 @@ class TC_DistributedMixedPlan < Test::Unit::TestCase
|
|
|
185
185
|
common_setup(propose_first) do |trsc|
|
|
186
186
|
remote.add_tasks(Distributed.format(plan))
|
|
187
187
|
r_t2 = subscribe_task(:id => 'remote-2')
|
|
188
|
-
t1, t2, t3 =
|
|
188
|
+
t1, t2, t3 = Roby.synchronize { add_tasks(trsc, "local") }
|
|
189
189
|
|
|
190
|
-
trsc[r_t2].
|
|
191
|
-
trsc[r_t2].
|
|
190
|
+
trsc[r_t2].depends_on t2
|
|
191
|
+
trsc[r_t2].signals(:start, t2, :start)
|
|
192
192
|
check_resulting_plan(trsc, false)
|
|
193
193
|
process_events
|
|
194
194
|
if propose_first
|
|
@@ -220,9 +220,9 @@ class TC_DistributedMixedPlan < Test::Unit::TestCase
|
|
|
220
220
|
trsc.edit
|
|
221
221
|
|
|
222
222
|
assert(r_t2.subscribed?)
|
|
223
|
-
t1, t2, t3 =
|
|
224
|
-
r_t2.
|
|
225
|
-
r_t2.
|
|
223
|
+
t1, t2, t3 = Roby.synchronize { add_tasks(plan, "local") }
|
|
224
|
+
r_t2.depends_on trsc[t2]
|
|
225
|
+
r_t2.signals(:start, trsc[t2], :start)
|
|
226
226
|
remote_peer.subscribe(r_t2)
|
|
227
227
|
remote_peer.push_subscription(t2)
|
|
228
228
|
|
|
@@ -239,15 +239,15 @@ class TC_DistributedMixedPlan < Test::Unit::TestCase
|
|
|
239
239
|
end
|
|
240
240
|
|
|
241
241
|
def test_garbage_collect
|
|
242
|
-
peer2peer
|
|
243
|
-
remote.plan.
|
|
242
|
+
peer2peer do |remote|
|
|
243
|
+
remote.plan.add_mission(SimpleTask.new(:id => 'remote-1'))
|
|
244
244
|
def remote.insert_children(trsc, root_task)
|
|
245
245
|
trsc = local_peer.local_object(trsc)
|
|
246
246
|
root_task = local_peer.local_object(root_task)
|
|
247
247
|
trsc.edit
|
|
248
248
|
|
|
249
|
-
root_task.
|
|
250
|
-
r2.
|
|
249
|
+
root_task.depends_on(r2 = SimpleTask.new(:id => 'remote-2'))
|
|
250
|
+
r2.depends_on(r3 = SimpleTask.new(:id => 'remote-3'))
|
|
251
251
|
trsc.release(false)
|
|
252
252
|
end
|
|
253
253
|
end
|
|
@@ -261,8 +261,8 @@ class TC_DistributedMixedPlan < Test::Unit::TestCase
|
|
|
261
261
|
# we are not subscribed to r1 anymore
|
|
262
262
|
trsc = Distributed::Transaction.new(plan)
|
|
263
263
|
trsc.add_owner(remote_peer)
|
|
264
|
-
trsc[r1].
|
|
265
|
-
Roby
|
|
264
|
+
trsc[r1].depends_on t1
|
|
265
|
+
Roby.synchronize do
|
|
266
266
|
remote_peer.unsubscribe(r1)
|
|
267
267
|
assert(!plan.unneeded_tasks.include?(r1))
|
|
268
268
|
end
|
|
@@ -275,10 +275,10 @@ class TC_DistributedMixedPlan < Test::Unit::TestCase
|
|
|
275
275
|
# Ok, we now create a r1 => t1 => t2 => t3 chain
|
|
276
276
|
# * t2 and t3 are kept because they are useful for r1
|
|
277
277
|
t2, t3 = nil
|
|
278
|
-
Roby
|
|
279
|
-
t1.
|
|
278
|
+
Roby.synchronize do
|
|
279
|
+
t1.depends_on(t2 = SimpleTask.new)
|
|
280
280
|
assert(!plan.unneeded_tasks.include?(t2))
|
|
281
|
-
t2.
|
|
281
|
+
t2.depends_on(t3 = SimpleTask.new)
|
|
282
282
|
assert(!plan.unneeded_tasks.include?(t3))
|
|
283
283
|
end
|
|
284
284
|
|
|
@@ -295,13 +295,13 @@ class TC_DistributedMixedPlan < Test::Unit::TestCase
|
|
|
295
295
|
process_events
|
|
296
296
|
|
|
297
297
|
r2 = remote_task(:id => 'remote-2')
|
|
298
|
-
Roby
|
|
298
|
+
Roby.synchronize do
|
|
299
299
|
assert(r2.plan && !plan.unneeded_tasks.include?(r2))
|
|
300
300
|
assert(t3.child_object?(r2, TaskStructure::Hierarchy))
|
|
301
301
|
end
|
|
302
302
|
|
|
303
303
|
r3 = remote_task(:id => 'remote-3')
|
|
304
|
-
Roby
|
|
304
|
+
Roby.synchronize do
|
|
305
305
|
assert(!r3.plan || plan.unneeded_tasks.include?(r3))
|
|
306
306
|
end
|
|
307
307
|
end
|
|
@@ -311,17 +311,17 @@ class TC_DistributedMixedPlan < Test::Unit::TestCase
|
|
|
311
311
|
# after the commit, there is a race condition possibility if the other
|
|
312
312
|
# peers do not have committed the transaction yet
|
|
313
313
|
def test_commit_race_condition
|
|
314
|
-
peer2peer
|
|
314
|
+
peer2peer do |remote|
|
|
315
315
|
def remote.add_task(trsc)
|
|
316
316
|
trsc = local_peer.local_object(trsc)
|
|
317
317
|
trsc.edit
|
|
318
|
-
trsc.
|
|
318
|
+
trsc.add(SimpleTask.new(:id => 'remote'))
|
|
319
319
|
trsc.release(false)
|
|
320
320
|
end
|
|
321
321
|
end
|
|
322
322
|
|
|
323
323
|
# Create an empty transaction and send it to our peer
|
|
324
|
-
# The peer will then
|
|
324
|
+
# The peer will then add a task, which
|
|
325
325
|
# will be GCed as soon as the transaction is committed
|
|
326
326
|
trsc = Distributed::Transaction.new(plan)
|
|
327
327
|
trsc.add_owner(remote_peer)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), File.dirname(__FILE__))
|
|
2
2
|
require 'roby/test/distributed'
|
|
3
3
|
require 'roby/test/tasks/simple_task'
|
|
4
4
|
require 'flexmock'
|
|
@@ -7,12 +7,12 @@ class TC_DistributedPlanNotifications < Test::Unit::TestCase
|
|
|
7
7
|
include Roby::Distributed::Test
|
|
8
8
|
|
|
9
9
|
def test_triggers
|
|
10
|
-
peer2peer
|
|
10
|
+
peer2peer do |remote|
|
|
11
11
|
def remote.new_task(kind, args)
|
|
12
|
-
|
|
12
|
+
engine.execute do
|
|
13
13
|
new_task = kind.proxy(local_peer).new(args)
|
|
14
14
|
yield(new_task.remote_id) if block_given?
|
|
15
|
-
plan.
|
|
15
|
+
plan.add_mission(new_task)
|
|
16
16
|
end
|
|
17
17
|
nil
|
|
18
18
|
end
|
|
@@ -52,9 +52,9 @@ class TC_DistributedPlanNotifications < Test::Unit::TestCase
|
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def test_trigger_subscribe
|
|
55
|
-
peer2peer
|
|
55
|
+
peer2peer do |remote|
|
|
56
56
|
def remote.new_task
|
|
57
|
-
plan.
|
|
57
|
+
plan.add_mission(SimpleTask.new(:id => 1))
|
|
58
58
|
nil
|
|
59
59
|
end
|
|
60
60
|
end
|
|
@@ -78,12 +78,12 @@ class TC_DistributedPlanNotifications < Test::Unit::TestCase
|
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
def test_subscribe_plan
|
|
81
|
-
peer2peer
|
|
82
|
-
plan.
|
|
83
|
-
subtask =
|
|
84
|
-
plan.
|
|
85
|
-
mission.
|
|
86
|
-
mission.
|
|
81
|
+
peer2peer do |remote|
|
|
82
|
+
plan.add_mission(mission = SimpleTask.new(:id => 'mission'))
|
|
83
|
+
subtask = SimpleTask.new :id => 'subtask'
|
|
84
|
+
plan.add_mission(next_mission = SimpleTask.new(:id => 'next_mission'))
|
|
85
|
+
mission.depends_on subtask
|
|
86
|
+
mission.signals(:start, next_mission, :start)
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
# Subscribe to the remote plan
|
|
@@ -103,27 +103,27 @@ class TC_DistributedPlanNotifications < Test::Unit::TestCase
|
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
def test_plan_updates
|
|
106
|
-
peer2peer
|
|
106
|
+
peer2peer do |remote|
|
|
107
107
|
class << remote
|
|
108
108
|
attr_reader :mission, :subtask, :next_mission, :free_event
|
|
109
109
|
def create_mission
|
|
110
110
|
@mission = Roby::Task.new :id => 'mission'
|
|
111
|
-
plan.
|
|
111
|
+
plan.add_mission(mission)
|
|
112
112
|
end
|
|
113
113
|
def create_subtask
|
|
114
|
-
plan.
|
|
115
|
-
mission.
|
|
114
|
+
plan.add_permanent(@subtask = Roby::Task.new(:id => 'subtask'))
|
|
115
|
+
mission.depends_on subtask
|
|
116
116
|
end
|
|
117
117
|
def create_next_mission
|
|
118
118
|
@next_mission = Roby::Task.new :id => 'next_mission'
|
|
119
|
-
mission.
|
|
120
|
-
plan.
|
|
119
|
+
mission.signals(:start, next_mission, :start)
|
|
120
|
+
plan.add_mission(next_mission)
|
|
121
121
|
end
|
|
122
122
|
def create_free_event
|
|
123
123
|
@free_event = Roby::EventGenerator.new(true)
|
|
124
124
|
# Link the event to a task to protect it from GC
|
|
125
|
-
@next_mission.
|
|
126
|
-
plan.
|
|
125
|
+
@next_mission.signals(:start, @free_event, :start)
|
|
126
|
+
plan.add(free_event)
|
|
127
127
|
end
|
|
128
128
|
def remove_free_event
|
|
129
129
|
plan.remove_object(free_event)
|
|
@@ -133,8 +133,8 @@ class TC_DistributedPlanNotifications < Test::Unit::TestCase
|
|
|
133
133
|
def unlink_subtask; mission.remove_child(subtask) end
|
|
134
134
|
def remove_subtask; plan.remove_object(subtask) end
|
|
135
135
|
def discard_mission
|
|
136
|
-
plan.
|
|
137
|
-
plan.
|
|
136
|
+
plan.add_permanent(mission)
|
|
137
|
+
plan.unmark_mission(mission)
|
|
138
138
|
end
|
|
139
139
|
def remove_mission; plan.remove_object(mission) end
|
|
140
140
|
end
|
|
@@ -206,12 +206,12 @@ class TC_DistributedPlanNotifications < Test::Unit::TestCase
|
|
|
206
206
|
end
|
|
207
207
|
|
|
208
208
|
def test_unsubscribe_plan
|
|
209
|
-
peer2peer
|
|
210
|
-
remote.plan.
|
|
211
|
-
remote.plan.
|
|
209
|
+
peer2peer do |remote|
|
|
210
|
+
remote.plan.add_mission(SimpleTask.new(:id => 'remote-1'))
|
|
211
|
+
remote.plan.add_mission(SimpleTask.new(:id => 'remote-2'))
|
|
212
212
|
|
|
213
213
|
def remote.new_task
|
|
214
|
-
plan.
|
|
214
|
+
plan.add_mission(SimpleTask.new(:id => 'remote-3'))
|
|
215
215
|
end
|
|
216
216
|
end
|
|
217
217
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), File.dirname(__FILE__))
|
|
2
2
|
require 'roby/test/distributed'
|
|
3
3
|
require 'roby/test/tasks/simple_task'
|
|
4
4
|
require 'flexmock'
|
|
@@ -30,13 +30,13 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
30
30
|
|
|
31
31
|
TEST_ARRAY_SIZE = 7
|
|
32
32
|
def dumpable_array
|
|
33
|
-
task =
|
|
33
|
+
task = SimpleTask.new(:id => 1)
|
|
34
34
|
[1, task,
|
|
35
35
|
Roby::EventGenerator.new {},
|
|
36
36
|
SimpleTask.new(:id => 2),
|
|
37
37
|
task.event(:start),
|
|
38
38
|
Roby::TaskStructure::Hierarchy,
|
|
39
|
-
Class.new(
|
|
39
|
+
Class.new(SimpleTask).new(:id => 3) ]
|
|
40
40
|
end
|
|
41
41
|
def dumpable_hash
|
|
42
42
|
Hash[*(0...TEST_ARRAY_SIZE).zip(dumpable_array).flatten]
|
|
@@ -47,7 +47,7 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
47
47
|
|
|
48
48
|
assert_kind_of(Task::DRoby, array[1])
|
|
49
49
|
assert_equal({:id => 1}, array[1].arguments)
|
|
50
|
-
assert_equal(
|
|
50
|
+
assert_equal(SimpleTask, array[1].model.proxy(remote_peer))
|
|
51
51
|
|
|
52
52
|
assert_kind_of(EventGenerator::DRoby, array[2])
|
|
53
53
|
assert(array[2].controlable)
|
|
@@ -117,7 +117,7 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
117
117
|
|
|
118
118
|
def test_enumerables
|
|
119
119
|
test_case = self
|
|
120
|
-
peer2peer
|
|
120
|
+
peer2peer do |remote|
|
|
121
121
|
PeerServer.class_eval do
|
|
122
122
|
define_method(:array) { test_case.dumpable_array }
|
|
123
123
|
define_method(:value_set) { test_case.dumpable_array.to_value_set }
|
|
@@ -148,7 +148,7 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
148
148
|
end
|
|
149
149
|
|
|
150
150
|
def test_marshal_peer
|
|
151
|
-
peer2peer
|
|
151
|
+
peer2peer do |remote|
|
|
152
152
|
def remote.remote_peer_id; Distributed.state.remote_id end
|
|
153
153
|
end
|
|
154
154
|
|
|
@@ -159,7 +159,7 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
159
159
|
end
|
|
160
160
|
|
|
161
161
|
def test_marshal_model
|
|
162
|
-
peer2peer
|
|
162
|
+
peer2peer do |remote|
|
|
163
163
|
PeerServer.class_eval do
|
|
164
164
|
def model; SimpleTask end
|
|
165
165
|
def anonymous_model; @anonymous ||= Class.new(model) end
|
|
@@ -178,10 +178,10 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
178
178
|
end
|
|
179
179
|
|
|
180
180
|
def test_marshal_task
|
|
181
|
-
peer2peer
|
|
181
|
+
peer2peer do |remote|
|
|
182
182
|
PeerServer.class_eval do
|
|
183
183
|
def task
|
|
184
|
-
plan.
|
|
184
|
+
plan.add_mission(@task = Class.new(SimpleTask).new(:id => 1))
|
|
185
185
|
@task.data = [42, @task.class]
|
|
186
186
|
[@task, @task.remote_id]
|
|
187
187
|
end
|
|
@@ -201,7 +201,7 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
201
201
|
assert_equal(remote_task_id, remote_task.remote_siblings[remote_peer.droby_dump(nil)], remote_task.remote_siblings)
|
|
202
202
|
assert(!remote_task.remote_siblings[Roby::Distributed.droby_dump(nil)])
|
|
203
203
|
|
|
204
|
-
plan.
|
|
204
|
+
plan.add_permanent(local_proxy = remote_peer.local_object(remote_task))
|
|
205
205
|
assert_kind_of(SimpleTask, local_proxy)
|
|
206
206
|
assert_not_same(SimpleTask, local_proxy.class)
|
|
207
207
|
assert_equal([42, local_proxy.class], local_proxy.data)
|
|
@@ -214,7 +214,9 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
214
214
|
remote_peer.synchro_point
|
|
215
215
|
assert(remote_peer.call(:check_sibling, local_proxy.remote_id))
|
|
216
216
|
assert(local_proxy.executable?)
|
|
217
|
-
|
|
217
|
+
Roby.execute do
|
|
218
|
+
assert_raises(OwnershipError) { local_proxy.start! }
|
|
219
|
+
end
|
|
218
220
|
end
|
|
219
221
|
|
|
220
222
|
class ErrorWithArguments < Exception
|
|
@@ -230,7 +232,7 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
230
232
|
assert_kind_of(Exception::DRoby, formatted)
|
|
231
233
|
assert_nothing_raised { Marshal.dump(formatted) }
|
|
232
234
|
|
|
233
|
-
peer2peer
|
|
235
|
+
peer2peer do |remote|
|
|
234
236
|
def remote.exception
|
|
235
237
|
model = Class.new(Exception)
|
|
236
238
|
e = model.exception("test")
|
|
@@ -264,17 +266,17 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
264
266
|
# See #test_local_task_back_forth_through_drb_race_condition
|
|
265
267
|
# This test checks the case where we received the added_sibling message
|
|
266
268
|
def test_local_task_back_forth_through_drb
|
|
267
|
-
peer2peer
|
|
269
|
+
peer2peer do |remote|
|
|
268
270
|
PeerServer.class_eval do
|
|
269
271
|
def proxy(object)
|
|
270
272
|
Marshal.dump(object)
|
|
271
|
-
plan.
|
|
273
|
+
plan.add_permanent(task = peer.local_object(object))
|
|
272
274
|
task
|
|
273
275
|
end
|
|
274
276
|
end
|
|
275
277
|
end
|
|
276
278
|
|
|
277
|
-
plan.
|
|
279
|
+
plan.add_permanent(local_task = SimpleTask.new(:id => 'local'))
|
|
278
280
|
remote_proxy = remote_peer.call(:proxy, local_task)
|
|
279
281
|
remote_peer.synchro_point
|
|
280
282
|
assert(remote_peer.proxies[remote_proxy], [remote_peer.proxies, remote_proxy])
|
|
@@ -291,17 +293,17 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
291
293
|
# #local_object while the local host does not know yet that the remote host
|
|
292
294
|
# has a sibling for the object
|
|
293
295
|
def test_local_task_back_forth_through_drb_race_condition
|
|
294
|
-
peer2peer
|
|
296
|
+
peer2peer do |remote|
|
|
295
297
|
def remote.proxy(object)
|
|
296
298
|
Marshal.dump(object)
|
|
297
|
-
plan.
|
|
299
|
+
plan.add_permanent(task = local_peer.local_object(object))
|
|
298
300
|
task
|
|
299
301
|
end
|
|
300
302
|
end
|
|
301
303
|
|
|
302
304
|
begin
|
|
303
305
|
remote.disable_communication
|
|
304
|
-
plan.
|
|
306
|
+
plan.add_permanent(local_task = SimpleTask.new(:id => 'local'))
|
|
305
307
|
remote_proxy = remote.proxy(Distributed.format(local_task))
|
|
306
308
|
assert_equal(remote_proxy, remote.proxy(Distributed.format(local_task)))
|
|
307
309
|
assert(!remote_peer.proxies[remote_proxy])
|
|
@@ -314,13 +316,17 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
314
316
|
assert_nothing_raised { remote_peer.synchro_point }
|
|
315
317
|
end
|
|
316
318
|
|
|
319
|
+
class FinalizedRemoteTaskRaceTask < SimpleTask
|
|
320
|
+
argument :newarg
|
|
321
|
+
end
|
|
322
|
+
|
|
317
323
|
# test a particular situations of GC/communication interaction
|
|
318
324
|
# - A finalizes a task T which is owned by B
|
|
319
325
|
# - A receives a message involving T which has been emitted while B was not knowing about the
|
|
320
326
|
# deletion (it has not yet received the removed_sibling message)
|
|
321
327
|
def test_finalized_remote_task_race_condition
|
|
322
|
-
peer2peer
|
|
323
|
-
remote.plan.
|
|
328
|
+
peer2peer do |remote|
|
|
329
|
+
remote.plan.add_mission(task = FinalizedRemoteTaskRaceTask.new(:id => 'remote'))
|
|
324
330
|
|
|
325
331
|
remote.singleton_class.class_eval do
|
|
326
332
|
define_method(:send_task_update) do
|
|
@@ -335,7 +341,7 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
335
341
|
task
|
|
336
342
|
end
|
|
337
343
|
|
|
338
|
-
|
|
344
|
+
engine.wait_one_cycle
|
|
339
345
|
assert(!task.plan)
|
|
340
346
|
|
|
341
347
|
new_task = remote_peer.local_object(remote.send_task_update)
|
|
@@ -347,14 +353,16 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
347
353
|
end
|
|
348
354
|
|
|
349
355
|
def test_marshal_task_arguments
|
|
350
|
-
peer2peer
|
|
356
|
+
peer2peer do |remote|
|
|
351
357
|
PeerServer.class_eval do
|
|
352
358
|
def task
|
|
353
|
-
plan.
|
|
359
|
+
plan.add_mission(@task = model.new(:id => 1, :model => model))
|
|
354
360
|
@task
|
|
355
361
|
end
|
|
356
362
|
def model
|
|
357
|
-
@model ||= Class.new(SimpleTask)
|
|
363
|
+
@model ||= Class.new(SimpleTask) do
|
|
364
|
+
argument :model
|
|
365
|
+
end
|
|
358
366
|
end
|
|
359
367
|
end
|
|
360
368
|
end
|
|
@@ -370,7 +378,7 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
370
378
|
end
|
|
371
379
|
|
|
372
380
|
def test_marshal_task_event
|
|
373
|
-
peer2peer
|
|
381
|
+
peer2peer do |remote|
|
|
374
382
|
PeerServer.class_eval do
|
|
375
383
|
attr_reader :task
|
|
376
384
|
def task_event
|
|
@@ -390,7 +398,7 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
390
398
|
|
|
391
399
|
CommonTaskModelTag = TaskModelTag.new
|
|
392
400
|
def test_marshal_task_model_tag
|
|
393
|
-
peer2peer
|
|
401
|
+
peer2peer do |remote|
|
|
394
402
|
PeerServer.class_eval do
|
|
395
403
|
def tag; CommonTaskModelTag end
|
|
396
404
|
def anonymous_tag
|
|
@@ -428,37 +436,38 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
428
436
|
end
|
|
429
437
|
|
|
430
438
|
def test_marshal_event
|
|
431
|
-
peer2peer
|
|
432
|
-
remote.plan.
|
|
433
|
-
t.
|
|
434
|
-
t.event(:start).
|
|
435
|
-
t.
|
|
439
|
+
peer2peer do |remote|
|
|
440
|
+
remote.plan.add_mission(t = Task.new)
|
|
441
|
+
t.signals(:start, (ev = EventGenerator.new(true)))
|
|
442
|
+
t.event(:start).forward_to(ev = EventGenerator.new(false))
|
|
443
|
+
t.signals(:start, (ev = EventGenerator.new { }))
|
|
436
444
|
PeerServer.class_eval do
|
|
437
445
|
include Test::Unit::Assertions
|
|
438
446
|
define_method(:events) { plan.free_events }
|
|
439
447
|
end
|
|
440
448
|
end
|
|
441
449
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
450
|
+
marshalled = remote_peer.call(:events)
|
|
451
|
+
marshalled.each { |ev| assert_kind_of(EventGenerator::DRoby, ev) }
|
|
452
|
+
Roby.execute do
|
|
453
|
+
all_events = marshalled.map { |ev| remote_peer.local_object(ev) }
|
|
454
|
+
assert_equal(1, all_events.find_all { |ev| !ev.controlable? }.size)
|
|
455
|
+
assert_equal(2, all_events.find_all { |ev| ev.controlable? }.size)
|
|
456
|
+
all_events.each do |ev|
|
|
457
|
+
if ev.controlable?
|
|
458
|
+
assert_raises(OwnershipError) { ev.call }
|
|
459
|
+
end
|
|
460
|
+
assert_raises(OwnershipError) { ev.emit }
|
|
461
|
+
end
|
|
462
|
+
end
|
|
454
463
|
end
|
|
455
464
|
|
|
456
465
|
def test_siblings
|
|
457
|
-
peer2peer
|
|
458
|
-
plan.
|
|
466
|
+
peer2peer do |remote|
|
|
467
|
+
plan.add_mission(Roby::Task.new(:id => 'remote'))
|
|
459
468
|
end
|
|
460
469
|
|
|
461
|
-
plan.
|
|
470
|
+
plan.add_mission(remote_task = remote_task(:id => 'remote'))
|
|
462
471
|
assert(remote_task.has_sibling_on?(remote_peer))
|
|
463
472
|
remote_object, _ = remote_peer.proxies.find { |_, task| task == remote_task }
|
|
464
473
|
assert(remote_object)
|
|
@@ -497,7 +506,7 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
497
506
|
|
|
498
507
|
def test_dump_sequence
|
|
499
508
|
DRb.start_service
|
|
500
|
-
t1, t2 = prepare_plan :
|
|
509
|
+
t1, t2 = prepare_plan :add => 2
|
|
501
510
|
p = t1+t2
|
|
502
511
|
|
|
503
512
|
formatted = Distributed.format(p)
|
|
@@ -506,7 +515,7 @@ class TC_DistributedRobyProtocol < Test::Unit::TestCase
|
|
|
506
515
|
|
|
507
516
|
def test_dump_parallel
|
|
508
517
|
DRb.start_service
|
|
509
|
-
t1, t2 = prepare_plan :
|
|
518
|
+
t1, t2 = prepare_plan :add => 2
|
|
510
519
|
p = t1|t2
|
|
511
520
|
|
|
512
521
|
formatted = Distributed.format(p)
|