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,3 +1,4 @@
|
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), File.dirname(__FILE__))
|
|
1
2
|
require 'test/unit'
|
|
2
3
|
require 'roby/distributed'
|
|
3
4
|
require 'roby/test/distributed'
|
|
@@ -43,7 +44,7 @@ class TC_DistributedCommunication < Test::Unit::TestCase
|
|
|
43
44
|
def setup
|
|
44
45
|
super
|
|
45
46
|
|
|
46
|
-
peer2peer
|
|
47
|
+
peer2peer do |remote|
|
|
47
48
|
def remote.install_fake_methods
|
|
48
49
|
local_peer.local_server.extend FakePeerServerMethods
|
|
49
50
|
end
|
|
@@ -78,6 +79,17 @@ class TC_DistributedCommunication < Test::Unit::TestCase
|
|
|
78
79
|
end
|
|
79
80
|
end
|
|
80
81
|
|
|
82
|
+
def disable_logging
|
|
83
|
+
remote.disable_logging
|
|
84
|
+
logger = Roby::Distributed.logger
|
|
85
|
+
old_loglevel = logger.level
|
|
86
|
+
logger.level = Logger::UNKNOWN
|
|
87
|
+
yield
|
|
88
|
+
ensure
|
|
89
|
+
remote.enable_logging
|
|
90
|
+
logger.level = old_loglevel
|
|
91
|
+
end
|
|
92
|
+
|
|
81
93
|
def test_transmit_error
|
|
82
94
|
FlexMock.use do |mock|
|
|
83
95
|
remote_peer.disable_tx
|
|
@@ -85,8 +97,10 @@ class TC_DistributedCommunication < Test::Unit::TestCase
|
|
|
85
97
|
mock.block_called
|
|
86
98
|
end
|
|
87
99
|
mock.should_receive(:block_called).never
|
|
88
|
-
|
|
89
|
-
|
|
100
|
+
disable_logging do
|
|
101
|
+
remote_peer.enable_tx
|
|
102
|
+
assert_raises(Roby::Distributed::DisconnectedError) { remote_peer.synchro_point }
|
|
103
|
+
end
|
|
90
104
|
|
|
91
105
|
assert(!remote_peer.connected?)
|
|
92
106
|
end
|
|
@@ -117,24 +131,26 @@ class TC_DistributedCommunication < Test::Unit::TestCase
|
|
|
117
131
|
end
|
|
118
132
|
|
|
119
133
|
def test_call_raises
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
134
|
+
disable_logging do
|
|
135
|
+
assert_raises(RuntimeError) do
|
|
136
|
+
remote_peer.call(:reply_error, 2)
|
|
137
|
+
end
|
|
138
|
+
end
|
|
124
139
|
end
|
|
125
140
|
|
|
126
141
|
def test_call_disconnects
|
|
127
|
-
Roby.logger.level = Logger::FATAL
|
|
128
142
|
remote_peer.disable_tx
|
|
129
143
|
|
|
130
144
|
remote_peer.transmit(:reply_error, 2)
|
|
131
145
|
sleep(0.5)
|
|
132
146
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
147
|
+
disable_logging do
|
|
148
|
+
Thread.new do
|
|
149
|
+
sleep(0.5)
|
|
150
|
+
remote_peer.enable_tx
|
|
151
|
+
end
|
|
152
|
+
assert_raises(DisconnectedError) { remote_peer.call(:reply, nil, 42) }
|
|
153
|
+
end
|
|
138
154
|
end
|
|
139
155
|
|
|
140
156
|
def test_callback
|
|
@@ -149,8 +165,9 @@ class TC_DistributedCommunication < Test::Unit::TestCase
|
|
|
149
165
|
end
|
|
150
166
|
|
|
151
167
|
def test_recursive_callbacks
|
|
152
|
-
|
|
153
|
-
|
|
168
|
+
disable_logging do
|
|
169
|
+
assert_raises(DisconnectedError) { remote_peer.call(:recursive_callbacks) }
|
|
170
|
+
end
|
|
154
171
|
end
|
|
155
172
|
|
|
156
173
|
def test_synchro_point
|
|
@@ -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'
|
|
@@ -14,8 +14,8 @@ class TC_DistributedConnection < Test::Unit::TestCase
|
|
|
14
14
|
Distributed.state.wait_discovery
|
|
15
15
|
|
|
16
16
|
assert(!Distributed.state.discovering?)
|
|
17
|
-
assert(1,
|
|
18
|
-
assert(
|
|
17
|
+
assert(1, local.neighbours.size)
|
|
18
|
+
assert(local.neighbours.find(&check), local.neighbours.map { |n| [n.name, n.remote_id] }.to_s)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
# Test neighbour discovery using a remote central tuplespace as neighbour list
|
|
@@ -31,10 +31,11 @@ class TC_DistributedConnection < Test::Unit::TestCase
|
|
|
31
31
|
central_tuplespace = DRbObject.new_with_uri('druby://localhost:1245')
|
|
32
32
|
|
|
33
33
|
Distributed.state = ConnectionSpace.new :ring_discovery => false,
|
|
34
|
-
:discovery_tuplespace => central_tuplespace
|
|
34
|
+
:discovery_tuplespace => central_tuplespace, :plan => plan
|
|
35
35
|
end
|
|
36
|
-
|
|
37
|
-
:discovery_tuplespace => central_tuplespace
|
|
36
|
+
@local = ConnectionSpace.new :ring_discovery => false,
|
|
37
|
+
:discovery_tuplespace => central_tuplespace, :plan => plan
|
|
38
|
+
Distributed.state = local
|
|
38
39
|
assert_has_neighbour { |n| n.name == "#{Socket.gethostname}-#{remote_pid}" }
|
|
39
40
|
end
|
|
40
41
|
|
|
@@ -45,12 +46,13 @@ class TC_DistributedConnection < Test::Unit::TestCase
|
|
|
45
46
|
|
|
46
47
|
remote_pid = remote_process do
|
|
47
48
|
DRb.start_service
|
|
48
|
-
Distributed.state = ConnectionSpace.new :period => 0.5, :ring_discovery => true, :ring_broadcast => BROADCAST
|
|
49
|
+
Distributed.state = ConnectionSpace.new :period => 0.5, :ring_discovery => true, :ring_broadcast => BROADCAST, :plan => plan
|
|
49
50
|
Distributed.publish :bind => '127.0.0.2'
|
|
50
51
|
end
|
|
51
52
|
|
|
52
53
|
DRb.start_service
|
|
53
|
-
|
|
54
|
+
@local = ConnectionSpace.new :period => 0.5, :ring_discovery => true, :ring_broadcast => BROADCAST, :plan => plan
|
|
55
|
+
Distributed.state = local
|
|
54
56
|
Distributed.publish :bind => '127.0.0.1'
|
|
55
57
|
|
|
56
58
|
assert_has_neighbour { |n| n.name == "#{Socket.gethostname}-#{remote_pid}" }
|
|
@@ -60,10 +62,10 @@ class TC_DistributedConnection < Test::Unit::TestCase
|
|
|
60
62
|
# Note that #peer2peer is the exact same process
|
|
61
63
|
def test_connect(standalone = true)
|
|
62
64
|
if standalone
|
|
63
|
-
start_peers
|
|
65
|
+
start_peers
|
|
64
66
|
|
|
65
67
|
notified = []
|
|
66
|
-
|
|
68
|
+
local.on_neighbour do |n|
|
|
67
69
|
notified << n
|
|
68
70
|
end
|
|
69
71
|
end
|
|
@@ -71,24 +73,24 @@ class TC_DistributedConnection < Test::Unit::TestCase
|
|
|
71
73
|
assert(local.discovery_thread)
|
|
72
74
|
|
|
73
75
|
# Initiate the connection from +local+
|
|
74
|
-
remote_neighbour =
|
|
75
|
-
|
|
76
|
+
remote_neighbour = local.neighbours.find { true }
|
|
77
|
+
engine.execute do
|
|
76
78
|
did_yield = nil
|
|
77
79
|
Peer.initiate_connection(local, remote_neighbour) do |did_yield|
|
|
78
80
|
end
|
|
79
81
|
|
|
80
82
|
# Wait for the remote peer to take into account the fact that we
|
|
81
83
|
# try connecting
|
|
82
|
-
|
|
84
|
+
local.synchronize do
|
|
83
85
|
remote_id = remote_neighbour.remote_id
|
|
84
|
-
assert(
|
|
85
|
-
|
|
86
|
+
assert(local.pending_connections[remote_id] ||
|
|
87
|
+
local.peers[remote_id])
|
|
86
88
|
end
|
|
87
89
|
|
|
88
90
|
sleep(1)
|
|
89
|
-
|
|
91
|
+
local.synchronize do
|
|
90
92
|
remote_id = remote_neighbour.remote_id
|
|
91
|
-
assert(@remote_peer =
|
|
93
|
+
assert(@remote_peer = local.peers[remote_id], local.peers)
|
|
92
94
|
assert_equal(remote_peer, did_yield)
|
|
93
95
|
end
|
|
94
96
|
assert(remote_peer.connected?)
|
|
@@ -103,7 +105,7 @@ class TC_DistributedConnection < Test::Unit::TestCase
|
|
|
103
105
|
assert_equal(remote_peer, Peer.connect(remote_neighbour))
|
|
104
106
|
end
|
|
105
107
|
|
|
106
|
-
|
|
108
|
+
engine.wait_one_cycle
|
|
107
109
|
assert(remote_peer.task.running?)
|
|
108
110
|
#assert_raises(ArgumentError) { Peer.initiate_connection(local, remote_neighbour) }
|
|
109
111
|
assert(remote_peer.link_alive?)
|
|
@@ -123,7 +125,7 @@ class TC_DistributedConnection < Test::Unit::TestCase
|
|
|
123
125
|
end
|
|
124
126
|
|
|
125
127
|
def test_synchronous_connect
|
|
126
|
-
start_peers
|
|
128
|
+
start_peers do |remote|
|
|
127
129
|
def remote.connected?
|
|
128
130
|
local_peer.connected?
|
|
129
131
|
end
|
|
@@ -140,7 +142,7 @@ class TC_DistributedConnection < Test::Unit::TestCase
|
|
|
140
142
|
|
|
141
143
|
def test_concurrent_connection
|
|
142
144
|
GC.disable
|
|
143
|
-
start_peers
|
|
145
|
+
start_peers do |remote|
|
|
144
146
|
class << remote
|
|
145
147
|
def find_neighbour
|
|
146
148
|
@neighbour = Roby::Distributed.neighbours.find { true }
|
|
@@ -197,11 +199,11 @@ class TC_DistributedConnection < Test::Unit::TestCase
|
|
|
197
199
|
|
|
198
200
|
# Test the normal disconnection process
|
|
199
201
|
def test_disconnect
|
|
200
|
-
peer2peer
|
|
202
|
+
peer2peer do |remote|
|
|
201
203
|
def remote.peers_empty?; Distributed.peers.empty? end
|
|
202
204
|
end
|
|
203
205
|
|
|
204
|
-
|
|
206
|
+
engine.wait_one_cycle
|
|
205
207
|
assert(remote_peer.task.ready?)
|
|
206
208
|
|
|
207
209
|
remote_peer.disconnect
|
|
@@ -223,7 +225,7 @@ class TC_DistributedConnection < Test::Unit::TestCase
|
|
|
223
225
|
# Tests that the remote peer disconnects if #demux raises DisconnectedError
|
|
224
226
|
def test_disconnect_on_error
|
|
225
227
|
Roby.logger.level = Logger::FATAL
|
|
226
|
-
peer2peer
|
|
228
|
+
peer2peer do |remote|
|
|
227
229
|
class << remote
|
|
228
230
|
include Test::Unit::Assertions
|
|
229
231
|
def assert_demux_raises
|
|
@@ -246,7 +248,7 @@ class TC_DistributedConnection < Test::Unit::TestCase
|
|
|
246
248
|
end
|
|
247
249
|
|
|
248
250
|
def test_socket_reconnect
|
|
249
|
-
peer2peer
|
|
251
|
+
peer2peer
|
|
250
252
|
Distributed.state.synchronize do
|
|
251
253
|
remote_peer.socket.close
|
|
252
254
|
assert(!remote_peer.link_alive?)
|
|
@@ -261,7 +263,7 @@ class TC_DistributedConnection < Test::Unit::TestCase
|
|
|
261
263
|
end
|
|
262
264
|
|
|
263
265
|
def test_remote_dies
|
|
264
|
-
peer2peer
|
|
266
|
+
peer2peer
|
|
265
267
|
Process.kill('KILL', remote_processes[1][0])
|
|
266
268
|
|
|
267
269
|
sleep(1)
|
|
@@ -270,7 +272,7 @@ class TC_DistributedConnection < Test::Unit::TestCase
|
|
|
270
272
|
|
|
271
273
|
|
|
272
274
|
def test_abort_connection
|
|
273
|
-
peer2peer
|
|
275
|
+
peer2peer
|
|
274
276
|
remote_peer.disconnected!
|
|
275
277
|
|
|
276
278
|
sleep(1)
|
|
@@ -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,22 +7,27 @@ class TC_DistributedExecution < Test::Unit::TestCase
|
|
|
7
7
|
include Roby::Distributed::Test
|
|
8
8
|
SimpleTask = Roby::Test::SimpleTask
|
|
9
9
|
|
|
10
|
+
def setup
|
|
11
|
+
super
|
|
12
|
+
Roby.app.filter_backtraces = false
|
|
13
|
+
end
|
|
14
|
+
|
|
10
15
|
def test_event_status
|
|
11
|
-
peer2peer
|
|
16
|
+
peer2peer do |remote|
|
|
12
17
|
class << remote
|
|
13
18
|
attr_reader :controlable
|
|
14
19
|
attr_reader :contingent
|
|
15
20
|
def create
|
|
16
21
|
# Put the task to avoir having GC clearing the events
|
|
17
|
-
plan.
|
|
18
|
-
plan.
|
|
19
|
-
plan.
|
|
20
|
-
t.
|
|
21
|
-
t.
|
|
22
|
+
plan.add_mission(t = SimpleTask.new(:id => 'task'))
|
|
23
|
+
plan.add(@controlable = Roby::EventGenerator.new(true))
|
|
24
|
+
plan.add(@contingent = Roby::EventGenerator.new(false))
|
|
25
|
+
t.signals(:start, controlable, :start)
|
|
26
|
+
t.forward_to(:start, contingent, :start)
|
|
22
27
|
nil
|
|
23
28
|
end
|
|
24
29
|
def fire
|
|
25
|
-
|
|
30
|
+
engine.execute do
|
|
26
31
|
controlable.call(nil)
|
|
27
32
|
contingent.emit(nil)
|
|
28
33
|
end
|
|
@@ -38,10 +43,10 @@ class TC_DistributedExecution < Test::Unit::TestCase
|
|
|
38
43
|
|
|
39
44
|
FlexMock.use do |mock|
|
|
40
45
|
controlable.on do
|
|
41
|
-
mock.fired_controlable(
|
|
46
|
+
mock.fired_controlable(engine.gathering?)
|
|
42
47
|
end
|
|
43
48
|
contingent.on do
|
|
44
|
-
mock.fired_contingent(
|
|
49
|
+
mock.fired_contingent(engine.gathering?)
|
|
45
50
|
end
|
|
46
51
|
|
|
47
52
|
mock.should_receive(:fired_controlable).with(true).once
|
|
@@ -55,13 +60,13 @@ class TC_DistributedExecution < Test::Unit::TestCase
|
|
|
55
60
|
end
|
|
56
61
|
|
|
57
62
|
def test_signal_establishment
|
|
58
|
-
peer2peer
|
|
63
|
+
peer2peer do |remote|
|
|
59
64
|
Roby::Distributed.on_transaction do |trsc|
|
|
60
65
|
trsc.edit do
|
|
61
66
|
local_task = trsc.find_tasks.which_fullfills(Roby::Test::SimpleTask).to_a.first
|
|
62
67
|
t = trsc[SimpleTask.new(:id => 'remote_task')]
|
|
63
|
-
local_task.
|
|
64
|
-
local_task.
|
|
68
|
+
local_task.depends_on t
|
|
69
|
+
local_task.signals :start, t, :start
|
|
65
70
|
nil
|
|
66
71
|
end
|
|
67
72
|
end
|
|
@@ -71,42 +76,42 @@ class TC_DistributedExecution < Test::Unit::TestCase
|
|
|
71
76
|
trsc.add_owner remote_peer
|
|
72
77
|
trsc.propose(remote_peer)
|
|
73
78
|
|
|
74
|
-
plan.
|
|
79
|
+
plan.add_mission(local_task = Roby::Test::SimpleTask.new)
|
|
75
80
|
trsc[local_task]
|
|
76
81
|
trsc.release
|
|
77
82
|
trsc.edit
|
|
78
83
|
trsc.commit_transaction
|
|
79
84
|
|
|
80
|
-
|
|
81
|
-
|
|
85
|
+
engine.execute { local_task.start! }
|
|
86
|
+
engine.wait_one_cycle
|
|
82
87
|
remote_peer.synchro_point
|
|
83
88
|
remote_task = subscribe_task(:id => 'remote_task')
|
|
84
89
|
assert(remote_task.running?)
|
|
85
90
|
|
|
86
|
-
|
|
87
|
-
plan.
|
|
91
|
+
engine.execute do
|
|
92
|
+
plan.unmark_mission(local_task)
|
|
88
93
|
local_task.stop!
|
|
89
94
|
end
|
|
90
95
|
end
|
|
91
96
|
|
|
92
97
|
# This test that the event/plan modification order is kept on a remote host
|
|
93
98
|
def test_keeps_causality
|
|
94
|
-
peer2peer
|
|
99
|
+
peer2peer do |remote|
|
|
95
100
|
class << remote
|
|
96
101
|
attr_reader :event
|
|
97
102
|
attr_reader :task
|
|
98
103
|
def create
|
|
99
104
|
# Put the task to avoir having GC clearing the events
|
|
100
|
-
plan.
|
|
101
|
-
plan.
|
|
102
|
-
event.
|
|
105
|
+
plan.add_mission(@task = SimpleTask.new(:id => 'task'))
|
|
106
|
+
plan.add(@event = Roby::EventGenerator.new(true))
|
|
107
|
+
event.signals task.event(:start)
|
|
103
108
|
nil
|
|
104
109
|
end
|
|
105
110
|
def fire
|
|
106
|
-
|
|
111
|
+
engine.execute do
|
|
107
112
|
event.on do
|
|
108
|
-
plan.
|
|
109
|
-
task.event(:start).
|
|
113
|
+
plan.unmark_mission(task)
|
|
114
|
+
task.event(:start).signals task.event(:success)
|
|
110
115
|
end
|
|
111
116
|
|
|
112
117
|
event.call(nil)
|
|
@@ -135,20 +140,20 @@ class TC_DistributedExecution < Test::Unit::TestCase
|
|
|
135
140
|
end
|
|
136
141
|
|
|
137
142
|
def test_task_status
|
|
138
|
-
Roby.
|
|
139
|
-
peer2peer
|
|
143
|
+
Roby.app.abort_on_exception = false
|
|
144
|
+
peer2peer do |remote|
|
|
140
145
|
class << remote
|
|
141
146
|
include Test::Unit::Assertions
|
|
142
147
|
attr_reader :task
|
|
143
148
|
def create_task
|
|
144
149
|
plan.clear
|
|
145
|
-
plan.
|
|
150
|
+
plan.add_mission(@task = SimpleTask.new(:id => 1))
|
|
146
151
|
end
|
|
147
|
-
def start_task;
|
|
152
|
+
def start_task; engine.once { task.start! }; nil end
|
|
148
153
|
def stop_task
|
|
149
154
|
assert(task.executable?)
|
|
150
|
-
|
|
151
|
-
plan.
|
|
155
|
+
engine.once do
|
|
156
|
+
plan.unmark_mission(task)
|
|
152
157
|
task.stop!
|
|
153
158
|
end
|
|
154
159
|
nil
|
|
@@ -180,8 +185,8 @@ class TC_DistributedExecution < Test::Unit::TestCase
|
|
|
180
185
|
end
|
|
181
186
|
|
|
182
187
|
def test_signalling
|
|
183
|
-
peer2peer
|
|
184
|
-
remote.plan.
|
|
188
|
+
peer2peer do |remote|
|
|
189
|
+
remote.plan.add_mission(task = SimpleTask.new(:id => 1))
|
|
185
190
|
remote.class.class_eval do
|
|
186
191
|
include Test::Unit::Assertions
|
|
187
192
|
define_method(:start_task) do
|
|
@@ -191,7 +196,7 @@ class TC_DistributedExecution < Test::Unit::TestCase
|
|
|
191
196
|
assert(fev = events.find { |ev| !ev.controlable? })
|
|
192
197
|
assert(task.event(:start).child_object?(sev, Roby::EventStructure::Signal))
|
|
193
198
|
assert(task.event(:start).child_object?(fev, Roby::EventStructure::Forwarding))
|
|
194
|
-
|
|
199
|
+
engine.once { task.start! }
|
|
195
200
|
nil
|
|
196
201
|
end
|
|
197
202
|
end
|
|
@@ -210,8 +215,8 @@ class TC_DistributedExecution < Test::Unit::TestCase
|
|
|
210
215
|
forwarded_ev.on { |ev| mock.forward_emitted }
|
|
211
216
|
assert(!forwarded_ev.controlable?)
|
|
212
217
|
|
|
213
|
-
p_task.event(:start).
|
|
214
|
-
p_task.event(:start).
|
|
218
|
+
p_task.event(:start).signals signalled_ev
|
|
219
|
+
p_task.event(:start).forward_to forwarded_ev
|
|
215
220
|
|
|
216
221
|
mock.should_receive(:signal_command).once.ordered('signal')
|
|
217
222
|
mock.should_receive(:signal_emitted).once.ordered('signal')
|
|
@@ -226,11 +231,11 @@ class TC_DistributedExecution < Test::Unit::TestCase
|
|
|
226
231
|
end
|
|
227
232
|
|
|
228
233
|
def test_event_handlers
|
|
229
|
-
peer2peer
|
|
230
|
-
remote.plan.
|
|
234
|
+
peer2peer do |remote|
|
|
235
|
+
remote.plan.add_mission(task = SimpleTask.new(:id => 1))
|
|
231
236
|
def remote.start(task)
|
|
232
237
|
task = local_peer.local_object(task)
|
|
233
|
-
|
|
238
|
+
engine.once { task.start! }
|
|
234
239
|
nil
|
|
235
240
|
end
|
|
236
241
|
end
|
|
@@ -249,13 +254,13 @@ class TC_DistributedExecution < Test::Unit::TestCase
|
|
|
249
254
|
# Test that we can 'forget' running tasks that was known to us because they
|
|
250
255
|
# were related to subscribed tasks
|
|
251
256
|
def test_forgetting
|
|
252
|
-
peer2peer
|
|
257
|
+
peer2peer do |remote|
|
|
253
258
|
parent, child =
|
|
254
259
|
SimpleTask.new(:id => 'parent'),
|
|
255
260
|
SimpleTask.new(:id => 'child')
|
|
256
|
-
parent.
|
|
261
|
+
parent.depends_on child
|
|
257
262
|
|
|
258
|
-
remote.plan.
|
|
263
|
+
remote.plan.add_mission(parent)
|
|
259
264
|
child.start!
|
|
260
265
|
remote.singleton_class.class_eval do
|
|
261
266
|
define_method(:remove_link) do
|
|
@@ -277,11 +282,11 @@ class TC_DistributedExecution < Test::Unit::TestCase
|
|
|
277
282
|
# Tests that running remote tasks are aborted and pending tasks GCed if the
|
|
278
283
|
# connection is killed
|
|
279
284
|
def test_disconnect_kills_tasks
|
|
280
|
-
peer2peer
|
|
281
|
-
remote.plan.
|
|
285
|
+
peer2peer do |remote|
|
|
286
|
+
remote.plan.add_mission(task = SimpleTask.new(:id => 'remote-1'))
|
|
282
287
|
def remote.start(task)
|
|
283
288
|
task = local_peer.local_object(task)
|
|
284
|
-
|
|
289
|
+
engine.execute do
|
|
285
290
|
task.start!
|
|
286
291
|
end
|
|
287
292
|
nil
|
|
@@ -295,7 +300,7 @@ class TC_DistributedExecution < Test::Unit::TestCase
|
|
|
295
300
|
assert(task.child_object?(remote_peer.task, TaskStructure::ExecutionAgent))
|
|
296
301
|
assert(task.subscribed?)
|
|
297
302
|
|
|
298
|
-
|
|
303
|
+
engine.execute do
|
|
299
304
|
remote_peer.disconnected!
|
|
300
305
|
end
|
|
301
306
|
assert(!task.subscribed?)
|
|
@@ -321,12 +326,12 @@ class TC_DistributedExecution < Test::Unit::TestCase
|
|
|
321
326
|
end
|
|
322
327
|
|
|
323
328
|
def test_code_blocks_owners
|
|
324
|
-
peer2peer
|
|
325
|
-
remote.plan.
|
|
329
|
+
peer2peer do |remote|
|
|
330
|
+
remote.plan.add_mission(CodeBlocksOwnersMockup.new(:id => 'mockup'))
|
|
326
331
|
|
|
327
332
|
def remote.call
|
|
328
333
|
task = plan.find_tasks(CodeBlocksOwnersMockup).to_a.first
|
|
329
|
-
|
|
334
|
+
engine.execute { task.start! }
|
|
330
335
|
end
|
|
331
336
|
|
|
332
337
|
def remote.blocks_called
|
|
@@ -348,17 +353,17 @@ class TC_DistributedExecution < Test::Unit::TestCase
|
|
|
348
353
|
# Checks that we get the update fine if +fired+ and +signalled+ are
|
|
349
354
|
# received in the same cycle
|
|
350
355
|
def test_joint_fired_signalled
|
|
351
|
-
peer2peer
|
|
352
|
-
remote.plan.
|
|
353
|
-
|
|
356
|
+
peer2peer do |remote|
|
|
357
|
+
remote.plan.add_mission(task = SimpleTask.new(:id => 'remote-1'))
|
|
358
|
+
engine.once { task.start! }
|
|
354
359
|
end
|
|
355
360
|
|
|
356
361
|
event_time = Time.now
|
|
357
362
|
remote = subscribe_task(:id => 'remote-1')
|
|
358
|
-
plan.
|
|
363
|
+
plan.add_mission(local = SimpleTask.new(:id => 'local'))
|
|
359
364
|
remote_peer.synchro_point
|
|
360
365
|
|
|
361
|
-
|
|
366
|
+
engine.execute do
|
|
362
367
|
remote_peer.local_server.event_fired(remote.event(:success), 0, Time.now, [42])
|
|
363
368
|
remote_peer.local_server.event_add_propagation(true, remote.event(:success), local.event(:start), 0, event_time, [42])
|
|
364
369
|
end
|