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
data/test/test_gui.rb
CHANGED
data/test/test_interface.rb
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('..', File.dirname(__FILE__))
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.join('..', 'lib'), File.dirname(__FILE__))
|
|
2
2
|
require 'roby/test/common'
|
|
3
|
+
require 'roby/interface'
|
|
3
4
|
require 'flexmock'
|
|
4
5
|
|
|
5
6
|
class TC_Interface < Test::Unit::TestCase
|
|
6
7
|
include Roby::Test
|
|
7
8
|
|
|
9
|
+
def setup
|
|
10
|
+
super
|
|
11
|
+
Roby.app.filter_backtraces = false
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
|
|
8
15
|
include Roby::Planning
|
|
9
16
|
def test_method_missing
|
|
10
|
-
|
|
11
|
-
iface = Interface.new(control)
|
|
17
|
+
iface = Interface.new(engine)
|
|
12
18
|
|
|
13
19
|
task_model = Class.new(Task)
|
|
14
20
|
|
|
@@ -16,9 +22,9 @@ class TC_Interface < Test::Unit::TestCase
|
|
|
16
22
|
planner = Class.new(Planner) do
|
|
17
23
|
method(:null_task) { result_task = task_model.new }
|
|
18
24
|
end
|
|
19
|
-
|
|
25
|
+
Roby.app.planners << planner
|
|
20
26
|
|
|
21
|
-
|
|
27
|
+
engine.run
|
|
22
28
|
returned_task = iface.null_task! do |_, planner|
|
|
23
29
|
planner.start!
|
|
24
30
|
end
|
data/test/test_log.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('..', File.dirname(__FILE__))
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.join('..', 'lib'), File.dirname(__FILE__))
|
|
2
2
|
require 'roby/test/common'
|
|
3
3
|
require 'roby/test/distributed'
|
|
4
4
|
require 'roby/test/tasks/simple_task'
|
|
@@ -17,6 +17,7 @@ class TC_Log < Test::Unit::TestCase
|
|
|
17
17
|
|
|
18
18
|
def test_start_stop_logger
|
|
19
19
|
FlexMock.use do |mock|
|
|
20
|
+
mock.should_receive(:close).once
|
|
20
21
|
Log.add_logger mock
|
|
21
22
|
assert(Log.logging?)
|
|
22
23
|
assert_nothing_raised { Log.start_logging }
|
|
@@ -29,40 +30,48 @@ class TC_Log < Test::Unit::TestCase
|
|
|
29
30
|
|
|
30
31
|
def test_misc
|
|
31
32
|
FlexMock.use do |mock|
|
|
33
|
+
mock.should_receive(:logs_message?).with(:flush).and_return(false)
|
|
34
|
+
mock.should_receive(:logs_message?).with(:event).and_return(true)
|
|
32
35
|
mock.should_receive(:splat?).and_return(true)
|
|
33
36
|
mock.should_receive(:event).with(1, 2)
|
|
34
37
|
mock.should_receive(:flush)
|
|
38
|
+
mock.should_receive(:close).once
|
|
35
39
|
Log.add_logger mock
|
|
36
40
|
|
|
37
|
-
assert(Log.has_logger?(:flush))
|
|
41
|
+
assert(!Log.has_logger?(:flush))
|
|
38
42
|
assert(Log.has_logger?(:event))
|
|
39
43
|
|
|
40
44
|
assert_equal([mock], Log.enum_for(:each_logger, :event).to_a)
|
|
41
45
|
assert_equal([], Log.enum_for(:each_logger, :bla).to_a)
|
|
46
|
+
Log.remove_logger mock
|
|
42
47
|
end
|
|
43
48
|
end
|
|
44
49
|
|
|
45
50
|
def test_message_splat
|
|
46
51
|
FlexMock.use do |mock|
|
|
52
|
+
mock.should_receive(:logs_message?).and_return(true)
|
|
47
53
|
mock.should_receive(:splat?).and_return(true).twice
|
|
48
54
|
mock.should_receive(:splat_event).with(FlexMock.any, 1, 2).once
|
|
49
55
|
mock.should_receive(:flush).once
|
|
56
|
+
mock.should_receive(:close).once
|
|
50
57
|
Log.add_logger mock
|
|
51
58
|
|
|
52
59
|
Log.log(:splat_event) { [1, 2] }
|
|
53
|
-
|
|
60
|
+
Log.remove_logger mock
|
|
54
61
|
end
|
|
55
62
|
end
|
|
56
63
|
|
|
57
64
|
def test_message_nonsplat
|
|
58
65
|
FlexMock.use do |mock|
|
|
66
|
+
mock.should_receive(:logs_message?).and_return(true)
|
|
59
67
|
mock.should_receive(:splat?).and_return(false).twice
|
|
60
68
|
mock.should_receive(:nonsplat_event).with(FlexMock.any, [1, 2]).once
|
|
61
69
|
mock.should_receive(:flush).once
|
|
70
|
+
mock.should_receive(:close).once
|
|
62
71
|
Log.add_logger mock
|
|
63
72
|
|
|
64
73
|
Log.log(:nonsplat_event) { [1, 2] }
|
|
65
|
-
|
|
74
|
+
Log.remove_logger mock
|
|
66
75
|
end
|
|
67
76
|
end
|
|
68
77
|
|
|
@@ -74,6 +83,7 @@ class TC_Log < Test::Unit::TestCase
|
|
|
74
83
|
def test_known_objects_management
|
|
75
84
|
t1, t2 = SimpleTask.new, SimpleTask.new
|
|
76
85
|
FlexMock.use do |mock|
|
|
86
|
+
mock.should_receive(:logs_message?).and_return(true)
|
|
77
87
|
mock.should_receive(:splat?).and_return(true)
|
|
78
88
|
mock.should_receive(:added_task_child).
|
|
79
89
|
with(FlexMock.any, on_marshalled_task(t1), [TaskStructure::Hierarchy].droby_dump(nil),
|
|
@@ -83,7 +93,7 @@ class TC_Log < Test::Unit::TestCase
|
|
|
83
93
|
task_set.map { |obj| obj.remote_siblings[Roby::Distributed.droby_dump(nil)] }.to_set == [t1.remote_id, t2.remote_id].to_set
|
|
84
94
|
end
|
|
85
95
|
|
|
86
|
-
mock.should_receive(:
|
|
96
|
+
mock.should_receive(:added_tasks).
|
|
87
97
|
with(FlexMock.any, FlexMock.any, match_discovered_set).
|
|
88
98
|
once
|
|
89
99
|
mock.should_receive(:removed_task_child).
|
|
@@ -92,12 +102,13 @@ class TC_Log < Test::Unit::TestCase
|
|
|
92
102
|
mock.should_receive(:finalized_task).
|
|
93
103
|
with(FlexMock.any, FlexMock.any, t1.remote_id).
|
|
94
104
|
once
|
|
105
|
+
mock.should_receive(:close).once
|
|
95
106
|
|
|
96
107
|
Log.add_logger mock
|
|
97
108
|
begin
|
|
98
|
-
t1.
|
|
109
|
+
t1.depends_on t2
|
|
99
110
|
assert(Log.known_objects.empty?)
|
|
100
|
-
plan.
|
|
111
|
+
plan.add(t1)
|
|
101
112
|
assert_equal([t1, t2].to_value_set, Log.known_objects)
|
|
102
113
|
t1.remove_child t2
|
|
103
114
|
assert_equal([t1, t2].to_value_set, Log.known_objects)
|
data/test/test_log_server.rb
CHANGED
data/test/test_plan.rb
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('..', File.dirname(__FILE__))
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.join('..', 'lib'), File.dirname(__FILE__))
|
|
2
2
|
require 'roby/test/common'
|
|
3
|
-
require 'roby/log'
|
|
4
|
-
require 'roby/state/information'
|
|
5
3
|
require 'roby/test/tasks/simple_task'
|
|
6
4
|
|
|
7
5
|
require 'flexmock'
|
|
@@ -9,169 +7,225 @@ require 'flexmock'
|
|
|
9
7
|
|
|
10
8
|
module TC_PlanStatic
|
|
11
9
|
include Roby
|
|
10
|
+
include Roby::Test
|
|
12
11
|
|
|
13
|
-
def
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
plan.remove_task(t1)
|
|
46
|
-
|
|
47
|
-
plan.permanent(t1 = Task.new)
|
|
48
|
-
assert(plan.include?(t1))
|
|
49
|
-
assert(!plan.mission?(t1))
|
|
50
|
-
assert(!t1.mission?)
|
|
51
|
-
assert(plan.permanent?(t1))
|
|
52
|
-
plan.auto(t1)
|
|
53
|
-
assert(plan.include?(t1))
|
|
54
|
-
assert(!plan.mission?(t1))
|
|
55
|
-
assert(!t1.mission?)
|
|
56
|
-
assert(!plan.permanent?(t1))
|
|
57
|
-
|
|
58
|
-
plan.permanent(t1)
|
|
59
|
-
plan.remove_task(t1)
|
|
60
|
-
assert(!plan.include?(t1))
|
|
61
|
-
assert(!plan.mission?(t1))
|
|
62
|
-
assert(!t1.mission?)
|
|
63
|
-
assert(!plan.permanent?(t1))
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def test_plan_remove_object
|
|
67
|
-
t1, t2 = prepare_plan :tasks => 2
|
|
68
|
-
plan.discover(e = EventGenerator.new(true))
|
|
69
|
-
|
|
70
|
-
t1.realized_by(t2)
|
|
71
|
-
t1.on(:start, e)
|
|
72
|
-
|
|
73
|
-
plan.remove_object(e)
|
|
74
|
-
assert(!plan.free_events.include?(e))
|
|
75
|
-
assert(t1.event(:start).leaf?(EventStructure::Signal))
|
|
76
|
-
assert(!e.plan)
|
|
77
|
-
assert_raises(ArgumentError) { e.plan = plan }
|
|
78
|
-
|
|
79
|
-
plan.remove_object(t2)
|
|
80
|
-
assert(!plan.include?(e))
|
|
81
|
-
assert(!t1.realized_by?(t2))
|
|
82
|
-
assert(!t2.plan)
|
|
83
|
-
assert_raises(ArgumentError) { t2.plan = plan }
|
|
12
|
+
def assert_task_state(task, state)
|
|
13
|
+
assert_planobject_state(task, state)
|
|
14
|
+
if state == :removed
|
|
15
|
+
assert(!plan.mission?(task))
|
|
16
|
+
assert(!task.mission?)
|
|
17
|
+
else
|
|
18
|
+
if state == :mission
|
|
19
|
+
assert(plan.mission?(task))
|
|
20
|
+
assert(task.mission?)
|
|
21
|
+
elsif state == :permanent
|
|
22
|
+
assert(!plan.mission?(task))
|
|
23
|
+
assert(!task.mission?)
|
|
24
|
+
elsif state == :normal
|
|
25
|
+
assert(!plan.mission?(task))
|
|
26
|
+
assert(!task.mission?)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
def assert_planobject_state(obj, state)
|
|
31
|
+
if state == :removed
|
|
32
|
+
assert(!plan.include?(obj))
|
|
33
|
+
assert(!plan.permanent?(obj))
|
|
34
|
+
assert_equal(nil, obj.plan)
|
|
35
|
+
else
|
|
36
|
+
assert_equal(plan, obj.plan)
|
|
37
|
+
assert(plan.include?(obj))
|
|
38
|
+
if state == :permanent
|
|
39
|
+
assert(plan.permanent?(obj))
|
|
40
|
+
else
|
|
41
|
+
assert(!plan.permanent?(obj))
|
|
42
|
+
end
|
|
43
|
+
end
|
|
84
44
|
end
|
|
85
45
|
|
|
86
|
-
def
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
or_ev = OrGenerator.new
|
|
90
|
-
t2.event(:start).on or_ev
|
|
91
|
-
or_ev.on t3.event(:stop)
|
|
92
|
-
t2.planned_by t4
|
|
93
|
-
|
|
94
|
-
result = plan.discover(t1)
|
|
95
|
-
assert_equal(plan, result)
|
|
96
|
-
assert( plan.include?(t1) )
|
|
97
|
-
assert( plan.include?(t2) )
|
|
98
|
-
assert( plan.free_events.include?(or_ev))
|
|
99
|
-
assert( !plan.include?(t3) ) # t3 not related because of task structure
|
|
100
|
-
assert( plan.include?(t4) )
|
|
46
|
+
def test_add_task
|
|
47
|
+
plan.add(t = Task.new)
|
|
48
|
+
assert_task_state(t, :normal)
|
|
101
49
|
|
|
102
|
-
|
|
103
|
-
|
|
50
|
+
other_plan = Plan.new
|
|
51
|
+
assert_raises(ModelViolation) { other_plan.add(t) }
|
|
52
|
+
end
|
|
53
|
+
def test_add_task_deprecated_discover
|
|
54
|
+
t = Task.new
|
|
55
|
+
deprecated_feature { plan.discover(t) }
|
|
56
|
+
assert_task_state(t, :normal)
|
|
57
|
+
end
|
|
58
|
+
def test_remove_task
|
|
59
|
+
plan.remove_object(t)
|
|
60
|
+
assert_task_state(t, :removed)
|
|
61
|
+
end
|
|
104
62
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
63
|
+
def test_add_mission
|
|
64
|
+
plan.add_mission(t = Task.new)
|
|
65
|
+
assert_task_state(t, :mission)
|
|
66
|
+
end
|
|
67
|
+
def test_add_mission_deprecated_insert
|
|
68
|
+
plan.insert(t = Task.new)
|
|
69
|
+
assert_task_state(t, :mission)
|
|
70
|
+
end
|
|
71
|
+
def test_unmark_mission
|
|
72
|
+
plan.add_mission(t = Task.new)
|
|
73
|
+
plan.unmark_mission(t)
|
|
74
|
+
assert_task_state(t, :normal)
|
|
75
|
+
end
|
|
76
|
+
def test_removed_mission
|
|
77
|
+
plan.add_mission(t = Task.new)
|
|
78
|
+
plan.remove_object(t)
|
|
79
|
+
assert_task_state(t, :removed)
|
|
111
80
|
end
|
|
112
81
|
|
|
113
|
-
def
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
82
|
+
def test_add_mission_deprecated_insert
|
|
83
|
+
t = Task.new
|
|
84
|
+
deprecated_feature { plan.insert(t) }
|
|
85
|
+
assert_task_state(t, :mission)
|
|
86
|
+
end
|
|
87
|
+
def test_unmark_mission_deprecated_discard
|
|
88
|
+
plan.add_mission(t = Task.new)
|
|
89
|
+
deprecated_feature { plan.discard(t) }
|
|
90
|
+
assert_task_state(t, :normal)
|
|
91
|
+
end
|
|
92
|
+
def test_unmark_mission_deprecated_remove_mission
|
|
93
|
+
plan.add_mission(t = Task.new)
|
|
94
|
+
deprecated_feature { plan.remove_mission(t) }
|
|
95
|
+
assert_task_state(t, :normal)
|
|
96
|
+
end
|
|
118
97
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
98
|
+
def test_add_permanent
|
|
99
|
+
plan.add_permanent(t = Task.new)
|
|
100
|
+
assert_task_state(t, :permanent)
|
|
101
|
+
end
|
|
102
|
+
def test_unmark_permanent
|
|
103
|
+
plan.add_permanent(t = Task.new)
|
|
104
|
+
plan.unmark_permanent(t)
|
|
105
|
+
assert_task_state(t, :normal)
|
|
106
|
+
end
|
|
107
|
+
def test_remove_permanent
|
|
108
|
+
plan.add_permanent(t = Task.new)
|
|
109
|
+
plan.remove_object(t)
|
|
110
|
+
assert_task_state(t, :removed)
|
|
111
|
+
end
|
|
125
112
|
|
|
126
|
-
|
|
127
|
-
|
|
113
|
+
def test_add_permanent_deprecated_permanent
|
|
114
|
+
t = Task.new
|
|
115
|
+
deprecated_feature { plan.permanent(t) }
|
|
116
|
+
assert_task_state(t, :permanent)
|
|
117
|
+
end
|
|
118
|
+
def test_unmark_permanent_deprecated_auto
|
|
119
|
+
plan.add_permanent(t = Task.new)
|
|
120
|
+
deprecated_feature { plan.auto(t) }
|
|
121
|
+
assert_task_state(t, :normal)
|
|
122
|
+
end
|
|
128
123
|
|
|
129
|
-
|
|
130
|
-
plan.
|
|
124
|
+
def test_add_event
|
|
125
|
+
plan.add(ev = EventGenerator.new)
|
|
126
|
+
assert_planobject_state(ev, :normal)
|
|
127
|
+
end
|
|
128
|
+
def test_remove_event
|
|
129
|
+
plan.add(ev = EventGenerator.new)
|
|
130
|
+
plan.remove_object(ev)
|
|
131
|
+
assert_planobject_state(ev, :removed)
|
|
132
|
+
end
|
|
133
|
+
def test_add_permanent_event
|
|
134
|
+
plan.add_permanent(ev = EventGenerator.new)
|
|
135
|
+
assert_planobject_state(ev, :permanent)
|
|
136
|
+
end
|
|
137
|
+
def test_unmark_permanent_event
|
|
138
|
+
plan.add_permanent(ev = EventGenerator.new)
|
|
139
|
+
plan.unmark_permanent(ev)
|
|
140
|
+
assert_planobject_state(ev, :normal)
|
|
141
|
+
end
|
|
142
|
+
def test_permanent_event_deprecated_permanent
|
|
143
|
+
ev = EventGenerator.new
|
|
144
|
+
deprecated_feature { plan.permanent(ev) }
|
|
145
|
+
assert_planobject_state(ev, :permanent)
|
|
146
|
+
end
|
|
147
|
+
def test_unmark_permanent_event_deprecated_auto
|
|
148
|
+
plan.add_permanent(ev = EventGenerator.new)
|
|
149
|
+
deprecated_feature { plan.unmark_permanent(ev) }
|
|
150
|
+
assert_planobject_state(ev, :normal)
|
|
131
151
|
end
|
|
132
152
|
|
|
153
|
+
# TODO: test that #remove_object removes the object from its relations
|
|
154
|
+
# TODO: test that #add adds related objects
|
|
155
|
+
|
|
156
|
+
#def test_discover
|
|
157
|
+
# t1, t2, t3, t4 = prepare_plan :tasks => 4, :model => Roby::Test::SimpleTask
|
|
158
|
+
# t1.depends_on t2
|
|
159
|
+
# or_ev = OrGenerator.new
|
|
160
|
+
# t2.event(:start).signals or_ev
|
|
161
|
+
# or_ev.signals t3.event(:stop)
|
|
162
|
+
# t2.planned_by t4
|
|
163
|
+
|
|
164
|
+
# result = plan.discover(t1)
|
|
165
|
+
# assert_equal(plan, result)
|
|
166
|
+
# assert( plan.include?(t1) )
|
|
167
|
+
# assert( plan.include?(t2) )
|
|
168
|
+
# assert( plan.free_events.include?(or_ev))
|
|
169
|
+
# assert( !plan.include?(t3) ) # t3 not related because of task structure
|
|
170
|
+
# assert( plan.include?(t4) )
|
|
171
|
+
|
|
172
|
+
# # Discover t3 to help plan cleanup
|
|
173
|
+
# plan.discover(t3)
|
|
174
|
+
|
|
175
|
+
# # Discover an AndGenerator and not its sources. The sources
|
|
176
|
+
# # must be discovered automatically
|
|
177
|
+
# a, b = (1..2).map { EventGenerator.new(true) }
|
|
178
|
+
# and_event = a & b
|
|
179
|
+
# plan.discover(and_event)
|
|
180
|
+
# assert_equal(plan, a.plan)
|
|
181
|
+
#end
|
|
182
|
+
|
|
133
183
|
def test_useful_task_components
|
|
134
184
|
t1, t2, t3, t4 = prepare_plan :tasks => 4, :model => Roby::Test::SimpleTask
|
|
135
|
-
t1.
|
|
136
|
-
t2.
|
|
185
|
+
t1.depends_on t2
|
|
186
|
+
t2.signals(:start, t3, :stop)
|
|
137
187
|
t2.planned_by t4
|
|
138
188
|
|
|
139
|
-
plan.
|
|
189
|
+
plan.add_mission(t1)
|
|
140
190
|
|
|
141
191
|
assert_equal([t1, t2, t4].to_value_set, plan.locally_useful_tasks)
|
|
142
|
-
plan.
|
|
192
|
+
plan.add_mission(t3)
|
|
143
193
|
assert_equal([t1, t2, t3, t4].to_value_set, plan.locally_useful_tasks)
|
|
144
|
-
plan.
|
|
194
|
+
plan.unmark_mission(t1)
|
|
145
195
|
assert_equal([t3].to_value_set, plan.locally_useful_tasks)
|
|
146
196
|
assert_equal([t1, t2, t4].to_value_set, plan.unneeded_tasks)
|
|
147
197
|
end
|
|
148
198
|
|
|
149
199
|
def test_replace_task
|
|
150
200
|
(p, c1), (c11, c12, c2, c3) = prepare_plan :missions => 2, :tasks => 4, :model => Roby::Test::SimpleTask
|
|
151
|
-
p.
|
|
152
|
-
c1.
|
|
153
|
-
c1.
|
|
154
|
-
p.
|
|
155
|
-
c1.
|
|
156
|
-
c1.
|
|
157
|
-
c11.
|
|
201
|
+
p.depends_on c1, :model => [Roby::Test::SimpleTask, {}]
|
|
202
|
+
c1.depends_on c11
|
|
203
|
+
c1.depends_on c12
|
|
204
|
+
p.depends_on c2
|
|
205
|
+
c1.signals(:stop, c2, :start)
|
|
206
|
+
c1.forward_to :start, c1, :stop
|
|
207
|
+
c11.forward_to :success, c1, :success
|
|
158
208
|
|
|
159
209
|
# Replace c1 by c3 and check that the hooks are properly called
|
|
160
210
|
FlexMock.use do |mock|
|
|
161
211
|
p.singleton_class.class_eval do
|
|
162
212
|
define_method('removed_child_object') do |child, relations|
|
|
163
|
-
mock.removed_hook(
|
|
213
|
+
mock.removed_hook(self, child, relations)
|
|
164
214
|
end
|
|
165
215
|
end
|
|
166
216
|
c1.singleton_class.class_eval do
|
|
167
217
|
define_method('removed_parent_object') do |parent, relations|
|
|
168
|
-
mock.removed_hook(
|
|
218
|
+
mock.removed_hook(self, parent, relations)
|
|
169
219
|
end
|
|
170
220
|
end
|
|
171
221
|
|
|
172
222
|
mock.should_receive(:removed_hook).with(p, c1, [TaskStructure::Hierarchy]).once
|
|
173
223
|
mock.should_receive(:removed_hook).with(c1, p, [TaskStructure::Hierarchy]).once
|
|
174
|
-
|
|
224
|
+
mock.should_receive(:removed_hook).with(p, c2, [TaskStructure::Hierarchy])
|
|
225
|
+
mock.should_receive(:removed_hook).with(c2, p, [TaskStructure::Hierarchy])
|
|
226
|
+
mock.should_receive(:removed_hook).with(p, c3, [TaskStructure::Hierarchy])
|
|
227
|
+
mock.should_receive(:removed_hook).with(c3, p, [TaskStructure::Hierarchy])
|
|
228
|
+
plan.replace_task(c1, c3)
|
|
175
229
|
end
|
|
176
230
|
|
|
177
231
|
# Check that the external task and event structures have been
|
|
@@ -196,8 +250,10 @@ module TC_PlanStatic
|
|
|
196
250
|
assert( plan.include?(c1) )
|
|
197
251
|
|
|
198
252
|
# Check that #replace_task keeps the permanent flag too
|
|
199
|
-
p, t = prepare_plan :permanent =>
|
|
200
|
-
|
|
253
|
+
(root, p), t = prepare_plan :permanent => 2, :tasks => 1, :model => Roby::Test::SimpleTask
|
|
254
|
+
root.depends_on p, :model => Roby::Test::SimpleTask
|
|
255
|
+
|
|
256
|
+
plan.add_permanent(p)
|
|
201
257
|
plan.replace_task(p, t)
|
|
202
258
|
assert(!plan.permanent?(p))
|
|
203
259
|
assert(plan.permanent?(t))
|
|
@@ -205,30 +261,34 @@ module TC_PlanStatic
|
|
|
205
261
|
|
|
206
262
|
def test_replace
|
|
207
263
|
(p, c1), (c11, c12, c2, c3) = prepare_plan :missions => 2, :tasks => 4, :model => Roby::Test::SimpleTask
|
|
208
|
-
p.
|
|
209
|
-
c1.
|
|
210
|
-
c1.
|
|
211
|
-
p.
|
|
212
|
-
c1.
|
|
213
|
-
c1.
|
|
214
|
-
c11.
|
|
264
|
+
p.depends_on c1, :model => Roby::Test::SimpleTask
|
|
265
|
+
c1.depends_on c11
|
|
266
|
+
c1.depends_on c12
|
|
267
|
+
p.depends_on c2
|
|
268
|
+
c1.signals(:stop, c2, :start)
|
|
269
|
+
c1.forward_to :start, c1, :stop
|
|
270
|
+
c11.forward_to :success, c1, :success
|
|
215
271
|
|
|
216
272
|
# Replace c1 by c3 and check that the hooks are properly called
|
|
217
273
|
FlexMock.use do |mock|
|
|
218
274
|
p.singleton_class.class_eval do
|
|
219
275
|
define_method('removed_child_object') do |child, relations|
|
|
220
|
-
mock.removed_hook(
|
|
276
|
+
mock.removed_hook(self, child, relations)
|
|
221
277
|
end
|
|
222
278
|
end
|
|
223
279
|
c1.singleton_class.class_eval do
|
|
224
280
|
define_method('removed_parent_object') do |parent, relations|
|
|
225
|
-
mock.removed_hook(
|
|
281
|
+
mock.removed_hook(self, parent, relations)
|
|
226
282
|
end
|
|
227
283
|
end
|
|
228
284
|
|
|
229
285
|
mock.should_receive(:removed_hook).with(p, c1, [TaskStructure::Hierarchy]).once
|
|
230
286
|
mock.should_receive(:removed_hook).with(c1, p, [TaskStructure::Hierarchy]).once
|
|
231
|
-
|
|
287
|
+
mock.should_receive(:removed_hook).with(p, c2, [TaskStructure::Hierarchy])
|
|
288
|
+
mock.should_receive(:removed_hook).with(c2, p, [TaskStructure::Hierarchy])
|
|
289
|
+
mock.should_receive(:removed_hook).with(p, c3, [TaskStructure::Hierarchy])
|
|
290
|
+
mock.should_receive(:removed_hook).with(c3, p, [TaskStructure::Hierarchy])
|
|
291
|
+
plan.replace(c1, c3)
|
|
232
292
|
end
|
|
233
293
|
|
|
234
294
|
# Check that the external task and event structures have been
|
|
@@ -255,34 +315,34 @@ module TC_PlanStatic
|
|
|
255
315
|
|
|
256
316
|
def test_remove_task
|
|
257
317
|
t1, t2, t3 = (1..3).map { Roby::Task.new }
|
|
258
|
-
t1.
|
|
259
|
-
t1.
|
|
318
|
+
t1.depends_on t2
|
|
319
|
+
t1.signals(:stop, t3, :start)
|
|
260
320
|
|
|
261
|
-
plan.
|
|
262
|
-
plan.
|
|
321
|
+
plan.add_mission(t1)
|
|
322
|
+
plan.add_mission(t3)
|
|
263
323
|
|
|
264
324
|
assert(!t1.leaf?)
|
|
265
|
-
plan.
|
|
325
|
+
plan.remove_object(t2)
|
|
266
326
|
assert(t1.leaf?)
|
|
267
327
|
assert(!plan.include?(t2))
|
|
268
328
|
|
|
269
329
|
assert(!t1.event(:stop).leaf?(EventStructure::Signal))
|
|
270
|
-
plan.
|
|
330
|
+
plan.remove_object(t3)
|
|
271
331
|
assert(t1.event(:stop).leaf?(EventStructure::Signal))
|
|
272
332
|
assert(!plan.include?(t3))
|
|
273
333
|
end
|
|
274
334
|
|
|
275
335
|
def test_free_events
|
|
276
336
|
t1, t2, t3 = (1..3).map { Roby::Task.new }
|
|
277
|
-
plan.
|
|
278
|
-
t1.
|
|
337
|
+
plan.add_mission(t1)
|
|
338
|
+
t1.depends_on t2
|
|
279
339
|
assert_equal(plan, t2.plan)
|
|
280
340
|
assert_equal(plan, t1.event(:start).plan)
|
|
281
341
|
|
|
282
342
|
or_generator = (t1.event(:stop) | t2.event(:stop))
|
|
283
343
|
assert_equal(plan, or_generator.plan)
|
|
284
344
|
assert(plan.free_events.include?(or_generator))
|
|
285
|
-
or_generator.
|
|
345
|
+
or_generator.signals t3.event(:start)
|
|
286
346
|
assert_equal(plan, t3.plan)
|
|
287
347
|
|
|
288
348
|
and_generator = (t1.event(:stop) & t2.event(:stop))
|
|
@@ -292,17 +352,17 @@ module TC_PlanStatic
|
|
|
292
352
|
|
|
293
353
|
def test_plan_synchronization
|
|
294
354
|
t1, t2 = prepare_plan :tasks => 2
|
|
295
|
-
plan.
|
|
355
|
+
plan.add_mission(t1)
|
|
296
356
|
assert_equal(plan, t1.plan)
|
|
297
357
|
assert_equal(nil, t2.plan)
|
|
298
|
-
t1.
|
|
358
|
+
t1.depends_on t2
|
|
299
359
|
assert_equal(plan, t1.plan)
|
|
300
360
|
assert_equal(plan, t2.plan)
|
|
301
361
|
assert(plan.include?(t2))
|
|
302
362
|
|
|
303
363
|
e = EventGenerator.new(true)
|
|
304
364
|
assert_equal(nil, e.plan)
|
|
305
|
-
t1.
|
|
365
|
+
t1.signals(:start, e, :start)
|
|
306
366
|
assert_equal(plan, e.plan)
|
|
307
367
|
assert(plan.free_events.include?(e))
|
|
308
368
|
|
|
@@ -317,268 +377,42 @@ module TC_PlanStatic
|
|
|
317
377
|
include adding_child_failure
|
|
318
378
|
end
|
|
319
379
|
t1, t2 = model.new, model.new
|
|
320
|
-
plan.
|
|
380
|
+
plan.add_mission(t1)
|
|
321
381
|
assert_equal(plan, t1.plan)
|
|
322
382
|
assert_equal(nil, t2.plan)
|
|
323
|
-
assert_raises(RuntimeError) { t1.
|
|
383
|
+
assert_raises(RuntimeError) { t1.depends_on t2 }
|
|
324
384
|
assert_equal(plan, t1.plan)
|
|
325
385
|
assert_equal(plan, t2.plan)
|
|
326
386
|
assert(plan.include?(t2))
|
|
327
387
|
end
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
class TC_Plan < Test::Unit::TestCase
|
|
331
|
-
include TC_PlanStatic
|
|
332
|
-
include Roby::Test
|
|
333
|
-
|
|
334
|
-
def clear_finalized
|
|
335
|
-
Roby::Log.flush
|
|
336
|
-
@finalized_tasks_recorder.clear
|
|
337
|
-
end
|
|
338
|
-
def finalized_tasks; @finalized_tasks_recorder.tasks end
|
|
339
|
-
def finalized_events; @finalized_tasks_recorder.events end
|
|
340
|
-
class FinalizedTaskRecorder
|
|
341
|
-
attribute(:tasks) { Array.new }
|
|
342
|
-
attribute(:events) { Array.new }
|
|
343
|
-
def finalized_task(time, plan, task)
|
|
344
|
-
tasks << task
|
|
345
|
-
end
|
|
346
|
-
def finalized_event(time, plan, event)
|
|
347
|
-
events << event unless event.respond_to?(:task)
|
|
348
|
-
end
|
|
349
|
-
def clear
|
|
350
|
-
tasks.clear
|
|
351
|
-
events.clear
|
|
352
|
-
end
|
|
353
|
-
def splat?; true end
|
|
354
|
-
end
|
|
355
|
-
|
|
356
|
-
def setup
|
|
357
|
-
super
|
|
358
|
-
Roby::Log.add_logger(@finalized_tasks_recorder = FinalizedTaskRecorder.new)
|
|
359
|
-
end
|
|
360
|
-
def teardown
|
|
361
|
-
Roby::Log.remove_logger @finalized_tasks_recorder
|
|
362
|
-
super
|
|
363
|
-
end
|
|
364
|
-
|
|
365
|
-
def assert_finalizes(plan, unneeded, finalized = nil)
|
|
366
|
-
finalized ||= unneeded
|
|
367
|
-
finalized = finalized.map { |obj| obj.remote_id }
|
|
368
|
-
clear_finalized
|
|
369
|
-
|
|
370
|
-
yield if block_given?
|
|
371
|
-
|
|
372
|
-
assert_equal(unneeded.to_set, plan.unneeded_tasks.to_set)
|
|
373
|
-
plan.garbage_collect
|
|
374
|
-
process_events
|
|
375
|
-
plan.garbage_collect
|
|
376
|
-
|
|
377
|
-
# !!! We are actually relying on the logging queue for this to work.
|
|
378
|
-
# make sure it is empty before testing anything
|
|
379
|
-
Roby::Log.flush
|
|
380
|
-
|
|
381
|
-
assert_equal(finalized.to_set, (finalized_tasks.to_set | finalized_events.to_set))
|
|
382
|
-
assert(! finalized.any? { |t| plan.include?(t) })
|
|
383
|
-
end
|
|
384
|
-
|
|
385
|
-
def test_garbage_collect_tasks
|
|
386
|
-
klass = Class.new(Task) do
|
|
387
|
-
attr_accessor :delays
|
|
388
|
-
|
|
389
|
-
event(:start, :command => true)
|
|
390
|
-
event(:stop) do |context|
|
|
391
|
-
if delays
|
|
392
|
-
return
|
|
393
|
-
else
|
|
394
|
-
emit(:stop)
|
|
395
|
-
end
|
|
396
|
-
end
|
|
397
|
-
end
|
|
398
|
-
|
|
399
|
-
t1, t2, t3, t4, t5, t6, t7, t8, p1 = (1..9).map { |i| klass.new(:id => i) }
|
|
400
|
-
t1.realized_by t3
|
|
401
|
-
t2.realized_by t3
|
|
402
|
-
t3.realized_by t4
|
|
403
|
-
t5.realized_by t4
|
|
404
|
-
t5.planned_by p1
|
|
405
|
-
p1.realized_by t6
|
|
406
|
-
|
|
407
|
-
t7.realized_by t8
|
|
408
|
-
|
|
409
|
-
[t1, t2, t5].each { |t| plan.insert(t) }
|
|
410
|
-
plan.permanent(t7)
|
|
411
|
-
|
|
412
|
-
assert_finalizes(plan, [])
|
|
413
|
-
assert_finalizes(plan, [t1]) { plan.discard(t1) }
|
|
414
|
-
assert_finalizes(plan, [t2, t3]) do
|
|
415
|
-
t2.start!(nil)
|
|
416
|
-
plan.discard(t2)
|
|
417
|
-
end
|
|
418
|
-
assert_finalizes(plan, [t5, t4, p1, t6], []) do
|
|
419
|
-
t5.delays = true
|
|
420
|
-
t5.start!(nil)
|
|
421
|
-
plan.discard(t5)
|
|
422
|
-
end
|
|
423
|
-
assert(t5.event(:stop).pending?)
|
|
424
|
-
assert_finalizes(plan, [t5, t4, p1, t6]) do
|
|
425
|
-
t5.event(:stop).emit(nil)
|
|
426
|
-
end
|
|
427
|
-
end
|
|
428
|
-
|
|
429
|
-
def test_force_garbage_collect_tasks
|
|
430
|
-
t1 = Class.new(Task) do
|
|
431
|
-
event(:stop) { |context| }
|
|
432
|
-
end.new
|
|
433
|
-
t2 = Task.new
|
|
434
|
-
t1.realized_by t2
|
|
435
|
-
|
|
436
|
-
plan.insert(t1)
|
|
437
|
-
t1.start!
|
|
438
|
-
assert_finalizes(plan, []) do
|
|
439
|
-
plan.garbage_collect([t1])
|
|
440
|
-
end
|
|
441
|
-
assert(t1.event(:stop).pending?)
|
|
442
|
-
|
|
443
|
-
assert_finalizes(plan, [t1, t2], [t1, t2]) do
|
|
444
|
-
# This stops the mission, which will be automatically discarded
|
|
445
|
-
t1.event(:stop).emit(nil)
|
|
446
|
-
end
|
|
447
|
-
end
|
|
448
|
-
|
|
449
|
-
def test_gc_ignores_incoming_events
|
|
450
|
-
Roby::Plan.logger.level = Logger::WARN
|
|
451
|
-
a, b = prepare_plan :discover => 2, :model => SimpleTask
|
|
452
|
-
a.on(:stop, b, :start)
|
|
453
|
-
a.start!
|
|
454
|
-
|
|
455
|
-
process_events
|
|
456
|
-
process_events
|
|
457
|
-
assert(!a.plan)
|
|
458
|
-
assert(!b.plan)
|
|
459
|
-
assert(!b.event(:start).happened?)
|
|
460
|
-
end
|
|
461
|
-
|
|
462
|
-
# Test a setup where there is both pending tasks and running tasks. This
|
|
463
|
-
# checks that #stop! is called on all the involved tasks. This tracks
|
|
464
|
-
# problems related to bindings in the implementation of #garbage_collect:
|
|
465
|
-
# the killed task bound to the Control.once block must remain the same.
|
|
466
|
-
def test_gc_stopping
|
|
467
|
-
Roby::Plan.logger.level = Logger::WARN
|
|
468
|
-
running_task = nil
|
|
469
|
-
FlexMock.use do |mock|
|
|
470
|
-
task_model = Class.new(Task) do
|
|
471
|
-
event :start, :command => true
|
|
472
|
-
event :stop do
|
|
473
|
-
mock.stop(self)
|
|
474
|
-
end
|
|
475
|
-
end
|
|
476
|
-
|
|
477
|
-
running_tasks = (1..5).map do
|
|
478
|
-
task_model.new
|
|
479
|
-
end
|
|
480
|
-
|
|
481
|
-
plan.discover(running_tasks)
|
|
482
|
-
t1, t2 = Roby::Task.new, Roby::Task.new
|
|
483
|
-
t1.realized_by t2
|
|
484
|
-
plan.discover(t1)
|
|
485
|
-
|
|
486
|
-
running_tasks.each do |t|
|
|
487
|
-
t.start!
|
|
488
|
-
mock.should_receive(:stop).with(t).once
|
|
489
|
-
end
|
|
490
|
-
|
|
491
|
-
plan.garbage_collect
|
|
492
|
-
process_events
|
|
493
|
-
|
|
494
|
-
assert(!plan.include?(t1))
|
|
495
|
-
assert(!plan.include?(t2))
|
|
496
|
-
running_tasks.each do |t|
|
|
497
|
-
assert(t.finishing?)
|
|
498
|
-
t.emit(:stop)
|
|
499
|
-
end
|
|
500
|
-
|
|
501
|
-
plan.garbage_collect
|
|
502
|
-
running_tasks.each do |t|
|
|
503
|
-
assert(!plan.include?(t))
|
|
504
|
-
end
|
|
505
|
-
end
|
|
506
|
-
|
|
507
|
-
ensure
|
|
508
|
-
running_task.emit(:stop) if running_task && !running_task.finished?
|
|
509
|
-
end
|
|
510
|
-
|
|
511
|
-
def test_garbage_collect_events
|
|
512
|
-
t = SimpleTask.new
|
|
513
|
-
e1 = EventGenerator.new(true)
|
|
514
|
-
|
|
515
|
-
plan.insert(t)
|
|
516
|
-
plan.discover(e1)
|
|
517
|
-
assert_equal([e1], plan.unneeded_events.to_a)
|
|
518
|
-
t.event(:start).on e1
|
|
519
|
-
assert_equal([], plan.unneeded_events.to_a)
|
|
520
|
-
|
|
521
|
-
e2 = EventGenerator.new(true)
|
|
522
|
-
plan.discover(e2)
|
|
523
|
-
assert_equal([e2], plan.unneeded_events.to_a)
|
|
524
|
-
e1.forward e2
|
|
525
|
-
assert_equal([], plan.unneeded_events.to_a)
|
|
526
|
-
|
|
527
|
-
plan.remove_object(t)
|
|
528
|
-
assert_equal([e1, e2].to_value_set, plan.unneeded_events)
|
|
529
|
-
end
|
|
530
388
|
|
|
531
389
|
# Checks that a garbage collected object (event or task) cannot be added back into the plan
|
|
532
390
|
def test_garbage_collection_final
|
|
533
391
|
t = SimpleTask.new
|
|
534
392
|
e = EventGenerator.new(true)
|
|
535
|
-
plan.
|
|
536
|
-
|
|
537
|
-
assert_raises(ArgumentError) { plan.
|
|
538
|
-
assert_raises(ArgumentError) { plan.
|
|
393
|
+
plan.real_plan.add [t, e]
|
|
394
|
+
engine.garbage_collect
|
|
395
|
+
assert_raises(ArgumentError) { plan.add(t) }
|
|
396
|
+
assert_raises(ArgumentError) { plan.add(e) }
|
|
539
397
|
end
|
|
540
398
|
|
|
541
|
-
def
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
Roby.execute do
|
|
545
|
-
planning, planned, influencing = prepare_plan :discover => 3, :model => SimpleTask
|
|
546
|
-
|
|
547
|
-
planned.planned_by planning
|
|
548
|
-
influencing.realized_by planned
|
|
549
|
-
planning.influenced_by influencing
|
|
550
|
-
|
|
551
|
-
planned.start!
|
|
552
|
-
planning.start!
|
|
553
|
-
influencing.start!
|
|
554
|
-
end
|
|
399
|
+
def test_proxy_operator
|
|
400
|
+
t = SimpleTask.new
|
|
401
|
+
assert_same t, plan[t, false]
|
|
555
402
|
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
Roby.wait_one_cycle
|
|
403
|
+
assert plan.include?(t)
|
|
404
|
+
assert_same t, plan[t, true]
|
|
559
405
|
|
|
560
|
-
|
|
406
|
+
plan.remove_object(t)
|
|
407
|
+
assert_raises(ArgumentError) { plan[t] }
|
|
561
408
|
end
|
|
409
|
+
end
|
|
562
410
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
event :specialized_failure, :command => true
|
|
566
|
-
forward :specialized_failure => :failed
|
|
567
|
-
end
|
|
568
|
-
|
|
569
|
-
task = prepare_plan :missions => 1, :model => model
|
|
570
|
-
task.start!
|
|
571
|
-
task.specialized_failure!
|
|
572
|
-
|
|
573
|
-
error = Roby.check_failed_missions(plan).first.exception
|
|
574
|
-
assert_kind_of(Roby::MissionFailedError, error)
|
|
575
|
-
assert_equal(task.event(:specialized_failure).last, error.failure_point)
|
|
576
|
-
assert_nothing_raised do
|
|
577
|
-
Roby.format_exception error
|
|
578
|
-
end
|
|
411
|
+
class TC_Plan < Test::Unit::TestCase
|
|
412
|
+
include TC_PlanStatic
|
|
579
413
|
|
|
580
|
-
|
|
581
|
-
|
|
414
|
+
def test_transaction_stack
|
|
415
|
+
assert_equal [plan], plan.transaction_stack
|
|
582
416
|
end
|
|
583
417
|
end
|
|
584
418
|
|