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
|
|
|
3
3
|
require 'roby/test/common'
|
|
4
4
|
require 'roby/test/tasks/simple_task'
|
|
@@ -19,8 +19,8 @@ class TC_Conflicts < Test::Unit::TestCase
|
|
|
19
19
|
assert(m2.conflicts_with?(m1))
|
|
20
20
|
|
|
21
21
|
# Create two tasks ...
|
|
22
|
-
plan.
|
|
23
|
-
plan.
|
|
22
|
+
plan.add(t1 = m1.new)
|
|
23
|
+
plan.add(t2 = m2.new)
|
|
24
24
|
assert !t1.child_object?(t2, Roby::TaskStructure::Conflicts)
|
|
25
25
|
assert !t2.child_object?(t1, Roby::TaskStructure::Conflicts)
|
|
26
26
|
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), File.dirname(__FILE__))
|
|
2
|
+
require 'roby/test/common'
|
|
3
|
+
require 'roby/test/tasks/simple_task'
|
|
4
|
+
|
|
5
|
+
class TC_RealizedBy < Test::Unit::TestCase
|
|
6
|
+
include Roby::Test
|
|
7
|
+
|
|
8
|
+
def test_check_structure_registration
|
|
9
|
+
assert plan.structure_checks.include?(Dependency.method(:check_structure))
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_definition
|
|
13
|
+
tag = TaskModelTag.new
|
|
14
|
+
klass = Class.new(SimpleTask) do
|
|
15
|
+
argument :id
|
|
16
|
+
include tag
|
|
17
|
+
end
|
|
18
|
+
plan.add(t1 = SimpleTask.new)
|
|
19
|
+
|
|
20
|
+
# Check validation of the model
|
|
21
|
+
child = nil
|
|
22
|
+
assert_nothing_raised { t1.depends_on((child = klass.new), :model => SimpleTask) }
|
|
23
|
+
assert_equal([SimpleTask, {}], t1[child, Dependency][:model])
|
|
24
|
+
|
|
25
|
+
assert_nothing_raised { t1.depends_on klass.new, :model => [Roby::Task, {}] }
|
|
26
|
+
assert_nothing_raised { t1.depends_on klass.new, :model => tag }
|
|
27
|
+
|
|
28
|
+
plan.add(simple_task = SimpleTask.new)
|
|
29
|
+
assert_raises(ArgumentError) { t1.depends_on simple_task, :model => [Class.new(Roby::Task), {}] }
|
|
30
|
+
assert_raises(ArgumentError) { t1.depends_on simple_task, :model => TaskModelTag.new }
|
|
31
|
+
|
|
32
|
+
# Check validation of the arguments
|
|
33
|
+
plan.add(model_task = klass.new)
|
|
34
|
+
assert_raises(ArgumentError) { t1.depends_on model_task, :model => [SimpleTask, {:id => 'bad'}] }
|
|
35
|
+
|
|
36
|
+
plan.add(child = klass.new(:id => 'good'))
|
|
37
|
+
assert_raises(ArgumentError) { t1.depends_on child, :model => [klass, {:id => 'bad'}] }
|
|
38
|
+
assert_nothing_raised { t1.depends_on child, :model => [klass, {:id => 'good'}] }
|
|
39
|
+
assert_equal([klass, { :id => 'good' }], t1[child, TaskStructure::Dependency][:model])
|
|
40
|
+
|
|
41
|
+
# Check edge annotation
|
|
42
|
+
t2 = SimpleTask.new
|
|
43
|
+
t1.depends_on t2, :model => SimpleTask
|
|
44
|
+
assert_equal([SimpleTask, {}], t1[t2, TaskStructure::Dependency][:model])
|
|
45
|
+
t2 = klass.new(:id => 10)
|
|
46
|
+
t1.depends_on t2, :model => [klass, { :id => 10 }]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
Dependency = TaskStructure::Dependency
|
|
50
|
+
|
|
51
|
+
def test_exception_printing
|
|
52
|
+
parent, child = prepare_plan :add => 2, :model => SimpleTask
|
|
53
|
+
parent.depends_on child
|
|
54
|
+
parent.start!
|
|
55
|
+
child.start!
|
|
56
|
+
child.failed!
|
|
57
|
+
|
|
58
|
+
error = plan.check_structure.find { true }[0].exception
|
|
59
|
+
assert_kind_of(ChildFailedError, error)
|
|
60
|
+
assert_nothing_raised do
|
|
61
|
+
Roby.format_exception(error)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
parent.stop!
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# This method is a common method used in the various error/nominal tests
|
|
68
|
+
# below. It creates two tasks:
|
|
69
|
+
# p1 which is an instance of SimpleTask
|
|
70
|
+
# child which is an instance of a task model with two controllable events
|
|
71
|
+
# 'first' and 'second'
|
|
72
|
+
#
|
|
73
|
+
# p1 is a parent of child. Both tasks are started and returned.
|
|
74
|
+
def create_pair(options)
|
|
75
|
+
child_model = Class.new(SimpleTask) do
|
|
76
|
+
event :first, :command => true
|
|
77
|
+
event :second, :command => true
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
p1 = SimpleTask.new
|
|
81
|
+
child = child_model.new
|
|
82
|
+
plan.add([p1, child])
|
|
83
|
+
p1.depends_on child, options
|
|
84
|
+
plan.add_mission(p1)
|
|
85
|
+
|
|
86
|
+
child.start!; p1.start!
|
|
87
|
+
return p1, child
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def assert_child_failed(child, reason, plan)
|
|
91
|
+
result = plan.check_structure
|
|
92
|
+
assert_equal([child].to_set, result.map { |e, _| e.exception.failed_task }.to_set)
|
|
93
|
+
assert_equal([reason].to_set, result.map { |e, _| e.exception.failed_event }.to_set)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def test_success
|
|
98
|
+
parent, child = create_pair :success => [:first],
|
|
99
|
+
:failure => [:stop],
|
|
100
|
+
:remove_when_done => false
|
|
101
|
+
|
|
102
|
+
assert_equal({}, plan.check_structure)
|
|
103
|
+
child.first!
|
|
104
|
+
assert_equal({}, plan.check_structure)
|
|
105
|
+
assert(parent.depends_on?(child))
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def test_success_removal
|
|
109
|
+
parent, child = create_pair :success => [:first],
|
|
110
|
+
:failure => [:stop],
|
|
111
|
+
:remove_when_done => true
|
|
112
|
+
|
|
113
|
+
child.first!
|
|
114
|
+
assert_equal({}, plan.check_structure)
|
|
115
|
+
assert(!parent.depends_on?(child))
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def test_success_preempts_explicit_failed
|
|
119
|
+
parent, child = create_pair :success => [:first],
|
|
120
|
+
:failure => [:stop]
|
|
121
|
+
|
|
122
|
+
child.first!
|
|
123
|
+
child.stop!
|
|
124
|
+
assert_equal({}, plan.check_structure)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def test_success_preempts_failure_on_unreachable
|
|
128
|
+
parent, child = create_pair :success => [:first]
|
|
129
|
+
|
|
130
|
+
child.first!
|
|
131
|
+
child.stop!
|
|
132
|
+
assert_equal({}, plan.check_structure)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def test_failure_explicit
|
|
136
|
+
parent, child = create_pair :success => [:first],
|
|
137
|
+
:failure => [:stop]
|
|
138
|
+
|
|
139
|
+
child.stop!
|
|
140
|
+
assert_child_failed(child, child.event(:stop).last, plan)
|
|
141
|
+
plan.clear
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def test_failure_on_unreachable
|
|
145
|
+
parent, child = create_pair :success => [:first]
|
|
146
|
+
|
|
147
|
+
child.stop!
|
|
148
|
+
assert_child_failed(child, child.event(:failed).last, plan)
|
|
149
|
+
plan.clear
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def test_fullfilled_model_validation
|
|
153
|
+
tag = TaskModelTag.new
|
|
154
|
+
klass = Class.new(Roby::Task)
|
|
155
|
+
|
|
156
|
+
p1, p2, child = prepare_plan :add => 3, :model => SimpleTask
|
|
157
|
+
p1.depends_on child, :model => [SimpleTask, { :id => "discover-3" }]
|
|
158
|
+
p2.depends_on child, :model => [SimpleTask, { :id => 'discover-3' }]
|
|
159
|
+
|
|
160
|
+
# Mess with the relation definition
|
|
161
|
+
p1[child, Dependency][:model].last[:id] = 'discover-10'
|
|
162
|
+
assert_raises(ModelViolation) { child.fullfilled_model }
|
|
163
|
+
p1[child, Dependency][:model] = [klass, {}]
|
|
164
|
+
assert_raises(ModelViolation) { child.fullfilled_model }
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def test_fullfilled_model
|
|
168
|
+
tag = TaskModelTag.new
|
|
169
|
+
klass = Class.new(SimpleTask) do
|
|
170
|
+
include tag
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
p1, p2, child = prepare_plan :add => 3, :model => klass
|
|
174
|
+
|
|
175
|
+
p1.depends_on child, :model => [SimpleTask, { :id => "discover-3" }]
|
|
176
|
+
p2.depends_on child, :model => Roby::Task
|
|
177
|
+
assert_equal([[SimpleTask], {:id => 'discover-3'}], child.fullfilled_model)
|
|
178
|
+
p1.remove_child(child)
|
|
179
|
+
assert_equal([[Roby::Task], {}], child.fullfilled_model)
|
|
180
|
+
p1.depends_on child, :model => tag
|
|
181
|
+
assert_equal([[Roby::Task, tag], {}], child.fullfilled_model)
|
|
182
|
+
p2.remove_child(child)
|
|
183
|
+
p2.depends_on child, :model => [klass, { :id => 'discover-3' }]
|
|
184
|
+
assert_equal([[klass, tag], {:id => 'discover-3'}], child.fullfilled_model)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def test_fullfilled_model_transaction
|
|
188
|
+
tag = TaskModelTag.new
|
|
189
|
+
klass = Class.new(SimpleTask) do
|
|
190
|
+
include tag
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
p1, p2, child = prepare_plan :add => 3, :model => Class.new(klass)
|
|
194
|
+
trsc = Transaction.new(plan)
|
|
195
|
+
|
|
196
|
+
p1.depends_on child, :model => [SimpleTask, { :id => "discover-3" }]
|
|
197
|
+
p2.depends_on child, :model => klass
|
|
198
|
+
|
|
199
|
+
t_child = trsc[child]
|
|
200
|
+
assert_equal([[klass], {:id => "discover-3"}], t_child.fullfilled_model)
|
|
201
|
+
t_p2 = trsc[p2]
|
|
202
|
+
assert_equal([[klass], {:id => "discover-3"}], t_child.fullfilled_model)
|
|
203
|
+
t_p2.remove_child(t_child)
|
|
204
|
+
assert_equal([[SimpleTask], { :id => 'discover-3' }], t_child.fullfilled_model)
|
|
205
|
+
t_p2.depends_on t_child, :model => klass
|
|
206
|
+
assert_equal([[klass], { :id => 'discover-3' }], t_child.fullfilled_model)
|
|
207
|
+
trsc.remove_object(t_p2)
|
|
208
|
+
assert_equal([[SimpleTask], { :id => 'discover-3' }], t_child.fullfilled_model)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def test_first_children
|
|
212
|
+
p, c1, c2 = prepare_plan :add => 3, :model => SimpleTask
|
|
213
|
+
p.depends_on c1
|
|
214
|
+
p.depends_on c2
|
|
215
|
+
assert_equal([c1, c2].to_value_set, p.first_children)
|
|
216
|
+
|
|
217
|
+
c1.signals(:start, c2, :start)
|
|
218
|
+
assert_equal([c1].to_value_set, p.first_children)
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def test_remove_finished_children
|
|
222
|
+
p, c1, c2 = prepare_plan :add => 3, :model => SimpleTask
|
|
223
|
+
plan.add_permanent(p)
|
|
224
|
+
p.depends_on c1
|
|
225
|
+
p.depends_on c2
|
|
226
|
+
|
|
227
|
+
p.start!
|
|
228
|
+
c1.start!
|
|
229
|
+
c1.success!
|
|
230
|
+
p.remove_finished_children
|
|
231
|
+
process_events
|
|
232
|
+
assert(!plan.include?(c1))
|
|
233
|
+
assert(plan.include?(c2))
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def test_role_definition
|
|
237
|
+
plan.add(parent = SimpleTask.new)
|
|
238
|
+
|
|
239
|
+
child = SimpleTask.new
|
|
240
|
+
parent.depends_on child, :role => 'child1'
|
|
241
|
+
assert_equal(['child1'].to_set, parent.roles_of(child))
|
|
242
|
+
|
|
243
|
+
child = SimpleTask.new
|
|
244
|
+
parent.depends_on child, :roles => ['child1', 'child2']
|
|
245
|
+
assert_equal(['child1', 'child2'].to_set, parent.roles_of(child))
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def setup_merging_test
|
|
249
|
+
plan.add(parent = SimpleTask.new)
|
|
250
|
+
tag = TaskModelTag.new
|
|
251
|
+
intermediate = Class.new(SimpleTask)
|
|
252
|
+
intermediate.include tag
|
|
253
|
+
child_model = Class.new(intermediate)
|
|
254
|
+
child = child_model.new(:id => 'child')
|
|
255
|
+
parent.depends_on child, :role => 'child1', :model => Task, :success => [], :failure => []
|
|
256
|
+
|
|
257
|
+
expected_info = { :remove_when_done=>true,
|
|
258
|
+
:model => [Roby::Task, {}],
|
|
259
|
+
:roles => ['child1'].to_set,
|
|
260
|
+
:success=>[],
|
|
261
|
+
:failure=>[] }
|
|
262
|
+
assert_equal expected_info, parent[child, Dependency]
|
|
263
|
+
|
|
264
|
+
return parent, child, expected_info, child_model, tag
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def test_merging_events
|
|
268
|
+
parent, child, info, child_model, _ = setup_merging_test
|
|
269
|
+
parent.depends_on child, :success => []
|
|
270
|
+
info[:model] = [child_model, {:id => 'child'}]
|
|
271
|
+
assert_equal info, parent[child, Dependency]
|
|
272
|
+
|
|
273
|
+
parent.depends_on child, :success => [:success]
|
|
274
|
+
info[:success] = [:success]
|
|
275
|
+
assert_equal info, parent[child, Dependency]
|
|
276
|
+
|
|
277
|
+
assert_raises(ModelViolation) { parent.depends_on child, :failure => [:success] }
|
|
278
|
+
assert_equal info, parent[child, Dependency]
|
|
279
|
+
|
|
280
|
+
parent.depends_on child, :failure => [:stop]
|
|
281
|
+
info[:failure] = [:stop]
|
|
282
|
+
assert_equal info, parent[child, Dependency]
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def test_merging_remove_when_done_cannot_change
|
|
286
|
+
parent, child, info, _ = setup_merging_test
|
|
287
|
+
assert_raises(ModelViolation) { parent.depends_on child, :remove_when_done => false }
|
|
288
|
+
parent.depends_on child, :model => info[:model], :remove_when_done => true, :success => []
|
|
289
|
+
assert_equal info, parent[child, Dependency]
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def test_merging_models
|
|
293
|
+
parent, child, info, child_model, tag = setup_merging_test
|
|
294
|
+
|
|
295
|
+
# Test that models are "upgraded"
|
|
296
|
+
parent.depends_on child, :model => SimpleTask, :success => []
|
|
297
|
+
info[:model][0] = SimpleTask
|
|
298
|
+
assert_equal info, parent[child, Dependency]
|
|
299
|
+
parent.depends_on child, :model => Roby::Task, :remove_when_done => true, :success => []
|
|
300
|
+
assert_equal info, parent[child, Dependency]
|
|
301
|
+
|
|
302
|
+
# Test that arguments are merged
|
|
303
|
+
parent.depends_on child, :model => [SimpleTask, {:id => 'child'}], :success => []
|
|
304
|
+
info[:model][1] = {:id => 'child'}
|
|
305
|
+
assert_equal info, parent[child, Dependency]
|
|
306
|
+
# note: arguments can't be changed on the task *and* #depends_on
|
|
307
|
+
# validates them, so we don't need to test that.
|
|
308
|
+
|
|
309
|
+
# Test model/tag handling: #depends_on should find the most generic
|
|
310
|
+
# model matching +task+ that includes all required models
|
|
311
|
+
parent.depends_on child, :model => tag, :success => []
|
|
312
|
+
info[:model][0] = child_model.superclass
|
|
313
|
+
assert_equal info, parent[child, Dependency]
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
def test_merging_roles
|
|
317
|
+
parent, child, info, _ = setup_merging_test
|
|
318
|
+
|
|
319
|
+
parent.depends_on child, :model => Roby::Task, :role => 'child2', :success => []
|
|
320
|
+
info[:roles] << 'child2'
|
|
321
|
+
assert_equal info, parent[child, Dependency]
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
|
|
@@ -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/common'
|
|
3
3
|
require 'flexmock'
|
|
4
4
|
|
|
@@ -8,7 +8,7 @@ class TC_EnsuredEvent < Test::Unit::TestCase
|
|
|
8
8
|
def test_ensure
|
|
9
9
|
setup = lambda do |mock|
|
|
10
10
|
e1, e2 = EventGenerator.new(true), Roby::EventGenerator.new(true)
|
|
11
|
-
plan.
|
|
11
|
+
plan.add [e1, e2]
|
|
12
12
|
e1.ensure e2
|
|
13
13
|
e1.on { mock.e1 }
|
|
14
14
|
e2.on { mock.e2 }
|
|
@@ -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/common'
|
|
3
3
|
require 'roby/test/tasks/simple_task'
|
|
4
4
|
require 'flexmock'
|
|
@@ -10,9 +10,13 @@ class TC_ExecutedBy < Test::Unit::TestCase
|
|
|
10
10
|
event :ready
|
|
11
11
|
forward :start => :ready
|
|
12
12
|
end
|
|
13
|
+
class SecondExecutionModel < SimpleTask
|
|
14
|
+
event :ready
|
|
15
|
+
forward :start => :ready
|
|
16
|
+
end
|
|
13
17
|
|
|
14
18
|
def test_relationships
|
|
15
|
-
plan.
|
|
19
|
+
plan.add(task = SimpleTask.new)
|
|
16
20
|
exec_task = ExecutionAgentModel.new
|
|
17
21
|
|
|
18
22
|
task.executed_by exec_task
|
|
@@ -21,15 +25,15 @@ class TC_ExecutedBy < Test::Unit::TestCase
|
|
|
21
25
|
|
|
22
26
|
def test_inherits_execution_model
|
|
23
27
|
model = Class.new(Roby::Task) do
|
|
24
|
-
executed_by ExecutionAgentModel
|
|
28
|
+
executed_by ExecutionAgentModel, :id => 20
|
|
25
29
|
end
|
|
26
30
|
submodel = Class.new(model)
|
|
27
31
|
|
|
28
|
-
assert_equal(ExecutionAgentModel, submodel.execution_agent)
|
|
32
|
+
assert_equal([ExecutionAgentModel, {:id => 20}], submodel.execution_agent)
|
|
29
33
|
end
|
|
30
34
|
|
|
31
35
|
def test_nominal
|
|
32
|
-
plan.
|
|
36
|
+
plan.add(task = SimpleTask.new)
|
|
33
37
|
task.executed_by(ExecutionAgentModel.new)
|
|
34
38
|
task.executed_by(exec = ExecutionAgentModel.new)
|
|
35
39
|
|
|
@@ -49,7 +53,7 @@ class TC_ExecutedBy < Test::Unit::TestCase
|
|
|
49
53
|
end
|
|
50
54
|
|
|
51
55
|
def test_agent_fails
|
|
52
|
-
plan.
|
|
56
|
+
plan.add(task = SimpleTask.new)
|
|
53
57
|
exec = ExecutionAgentModel.new
|
|
54
58
|
task.executed_by exec
|
|
55
59
|
task.start!
|
|
@@ -63,10 +67,10 @@ class TC_ExecutedBy < Test::Unit::TestCase
|
|
|
63
67
|
end
|
|
64
68
|
|
|
65
69
|
def test_agent_start_failed
|
|
66
|
-
plan.
|
|
70
|
+
plan.add_mission(task = SimpleTask.new)
|
|
67
71
|
exec = Class.new(SimpleTask) do
|
|
68
72
|
event :ready
|
|
69
|
-
|
|
73
|
+
signal :start => :failed
|
|
70
74
|
end.new
|
|
71
75
|
task.executed_by exec
|
|
72
76
|
|
|
@@ -76,23 +80,94 @@ class TC_ExecutedBy < Test::Unit::TestCase
|
|
|
76
80
|
assert(exec.finished?)
|
|
77
81
|
end
|
|
78
82
|
|
|
79
|
-
def
|
|
83
|
+
def test_agent_model_spawns
|
|
80
84
|
task_model = Class.new(SimpleTask)
|
|
81
85
|
|
|
82
|
-
task_model.executed_by ExecutionAgentModel
|
|
83
|
-
plan.
|
|
86
|
+
task_model.executed_by ExecutionAgentModel, :id => 10
|
|
87
|
+
plan.add_mission(task = task_model.new)
|
|
84
88
|
assert(task.execution_agent)
|
|
85
|
-
|
|
89
|
+
assert_equal(10, task.execution_agent.arguments[:id])
|
|
90
|
+
assert_kind_of(ExecutionAgentModel, task.execution_agent)
|
|
91
|
+
|
|
92
|
+
task.start!
|
|
93
|
+
assert(task.running?)
|
|
94
|
+
assert(task.execution_agent.running?)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def test_agent_model_reuses
|
|
98
|
+
plan.add_permanent(agent = ExecutionAgentModel.new)
|
|
99
|
+
|
|
100
|
+
task_model = Class.new(SimpleTask)
|
|
101
|
+
task_model.executed_by ExecutionAgentModel
|
|
102
|
+
|
|
103
|
+
plan.add_mission(task = task_model.new)
|
|
104
|
+
assert_same(agent, task.execution_agent)
|
|
86
105
|
|
|
87
106
|
task.start!
|
|
88
107
|
assert(task.running?)
|
|
89
108
|
assert(task.execution_agent.running?)
|
|
90
109
|
end
|
|
91
110
|
|
|
111
|
+
def test_agent_model_reuses_running_agent
|
|
112
|
+
plan.add_permanent(agent = ExecutionAgentModel.new)
|
|
113
|
+
agent.start!
|
|
114
|
+
|
|
115
|
+
task_model = Class.new(SimpleTask)
|
|
116
|
+
task_model.executed_by ExecutionAgentModel
|
|
117
|
+
|
|
118
|
+
plan.add_mission(task = task_model.new)
|
|
119
|
+
assert_same(agent, task.execution_agent)
|
|
120
|
+
|
|
121
|
+
task.start!
|
|
122
|
+
assert(task.running?)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def test_agent_model_arguments
|
|
126
|
+
plan.add_permanent(agent1 = ExecutionAgentModel.new(:id => 1))
|
|
127
|
+
plan.add_permanent(agent2 = ExecutionAgentModel.new(:id => 2))
|
|
128
|
+
|
|
129
|
+
task_model = Class.new(SimpleTask)
|
|
130
|
+
task_model.executed_by ExecutionAgentModel, :id => 2
|
|
131
|
+
|
|
132
|
+
plan.add_mission(task = task_model.new)
|
|
133
|
+
assert_same(agent2, task.execution_agent)
|
|
134
|
+
|
|
135
|
+
task.start!
|
|
136
|
+
assert(task.running?)
|
|
137
|
+
assert(task.execution_agent.running?)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def test_task_has_wrong_agent
|
|
141
|
+
task_model = Class.new(SimpleTask)
|
|
142
|
+
task_model.executed_by ExecutionAgentModel, :id => 2
|
|
143
|
+
|
|
144
|
+
plan.add_mission(task = task_model.new)
|
|
145
|
+
|
|
146
|
+
# Wrong agent type
|
|
147
|
+
plan.remove_object(task.execution_agent)
|
|
148
|
+
task.executed_by SecondExecutionModel.new(:id => 2)
|
|
149
|
+
assert_raises(Roby::CommandFailed) { task.start! }
|
|
150
|
+
|
|
151
|
+
# Wrong agent arguments
|
|
152
|
+
plan.remove_object(task.execution_agent)
|
|
153
|
+
task.executed_by ExecutionAgentModel.new(:id => 3)
|
|
154
|
+
assert_raises(Roby::CommandFailed) { task.start! }
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def test_model_requires_agent_but_none_exists
|
|
158
|
+
task_model = Class.new(SimpleTask)
|
|
159
|
+
task_model.executed_by ExecutionAgentModel, :id => 2
|
|
160
|
+
|
|
161
|
+
plan.add_mission(task = task_model.new)
|
|
162
|
+
plan.remove_object(task.execution_agent)
|
|
163
|
+
|
|
164
|
+
assert_raises(Roby::CommandFailed) { task.start! }
|
|
165
|
+
end
|
|
166
|
+
|
|
92
167
|
def test_respawn
|
|
93
168
|
task_model = Class.new(SimpleTask)
|
|
94
169
|
task_model.executed_by ExecutionAgentModel
|
|
95
|
-
first, second = prepare_plan :
|
|
170
|
+
first, second = prepare_plan :add => 2, :model => task_model
|
|
96
171
|
assert(first.execution_agent)
|
|
97
172
|
assert(ExecutionAgentModel, first.execution_agent.class)
|
|
98
173
|
assert(second.execution_agent)
|
|
@@ -104,7 +179,7 @@ class TC_ExecutedBy < Test::Unit::TestCase
|
|
|
104
179
|
first_agent = first.execution_agent
|
|
105
180
|
assert(first_agent.running?)
|
|
106
181
|
|
|
107
|
-
plan.
|
|
182
|
+
plan.add(third = task_model.new)
|
|
108
183
|
assert_equal(first.execution_agent, third.execution_agent)
|
|
109
184
|
|
|
110
185
|
first.execution_agent.stop!
|
|
@@ -115,7 +190,7 @@ class TC_ExecutedBy < Test::Unit::TestCase
|
|
|
115
190
|
end
|
|
116
191
|
|
|
117
192
|
def test_cannot_respawn
|
|
118
|
-
plan.
|
|
193
|
+
plan.add_mission(task = Class.new(SimpleTask).new)
|
|
119
194
|
task.executed_by(agent = ExecutionAgentModel.new)
|
|
120
195
|
|
|
121
196
|
agent.start!
|
|
@@ -127,14 +202,14 @@ class TC_ExecutedBy < Test::Unit::TestCase
|
|
|
127
202
|
agent = Class.new(SimpleTask) do
|
|
128
203
|
event :ready, :command => true
|
|
129
204
|
end.new
|
|
130
|
-
task, (init1, init2) = prepare_plan :missions => 1, :
|
|
205
|
+
task, (init1, init2) = prepare_plan :missions => 1, :add => 2, :model => SimpleTask
|
|
131
206
|
task.executed_by agent
|
|
132
207
|
init1.executed_by agent
|
|
133
208
|
init2.executed_by agent
|
|
134
209
|
|
|
135
|
-
agent.
|
|
136
|
-
agent.
|
|
137
|
-
init.
|
|
210
|
+
agent.depends_on(init = (init1 + init2))
|
|
211
|
+
agent.signals(:start, init, :start)
|
|
212
|
+
init.forward_to(:success, agent, :ready)
|
|
138
213
|
|
|
139
214
|
task.start!
|
|
140
215
|
assert(!task.running?)
|