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_state.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/state/pos'
|
|
4
4
|
require 'flexmock'
|
|
@@ -283,7 +283,7 @@ class TC_State < Test::Unit::TestCase
|
|
|
283
283
|
def test_pos_delta_event
|
|
284
284
|
State.pos = Pos::Euler3D.new
|
|
285
285
|
|
|
286
|
-
plan.
|
|
286
|
+
plan.add(d = State.on_delta(:d => 10))
|
|
287
287
|
assert_kind_of(PosDeltaEvent, d)
|
|
288
288
|
d.poll
|
|
289
289
|
assert_equal(State.pos, d.last_value)
|
|
@@ -308,7 +308,7 @@ class TC_State < Test::Unit::TestCase
|
|
|
308
308
|
def test_yaw_delta_event
|
|
309
309
|
State.pos = Pos::Euler3D.new
|
|
310
310
|
|
|
311
|
-
plan.
|
|
311
|
+
plan.add(y = State.on_delta(:yaw => 2))
|
|
312
312
|
assert_kind_of(YawDeltaEvent, y)
|
|
313
313
|
y.poll
|
|
314
314
|
assert_equal(0, y.last_value)
|
|
@@ -327,87 +327,105 @@ class TC_State < Test::Unit::TestCase
|
|
|
327
327
|
end
|
|
328
328
|
|
|
329
329
|
def test_time_delta_event
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
330
|
+
FlexMock.use(Time) do |time_proxy|
|
|
331
|
+
current_time = Time.now + 5
|
|
332
|
+
time_proxy.should_receive(:now).and_return { current_time }
|
|
333
|
+
|
|
334
|
+
plan.add(t = State.on_delta(:t => 1))
|
|
335
|
+
assert_kind_of(TimeDeltaEvent, t)
|
|
336
|
+
|
|
337
|
+
t.poll
|
|
338
|
+
assert(!t.happened?)
|
|
339
|
+
current_time += 0.5
|
|
340
|
+
t.poll
|
|
341
|
+
assert(!t.happened?)
|
|
342
|
+
|
|
343
|
+
current_time += 0.5
|
|
344
|
+
t.poll
|
|
345
|
+
assert(1, t.history.size)
|
|
346
|
+
|
|
347
|
+
current_time += 0.5
|
|
348
|
+
t.poll
|
|
349
|
+
assert(1, t.history.size)
|
|
350
|
+
|
|
351
|
+
current_time += 0.5
|
|
352
|
+
t.poll
|
|
353
|
+
assert(2, t.history.size)
|
|
354
|
+
end
|
|
342
355
|
end
|
|
343
356
|
|
|
344
357
|
def test_timepoint_event
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
358
|
+
FlexMock.use(Time) do |time_proxy|
|
|
359
|
+
current_time = Time.now + 5
|
|
360
|
+
time_proxy.should_receive(:now).and_return { current_time }
|
|
361
|
+
|
|
362
|
+
plan.add(ev = State.at(:t => current_time + 1))
|
|
363
|
+
ev.poll
|
|
364
|
+
assert(!ev.happened?)
|
|
365
|
+
current_time += 1
|
|
366
|
+
ev.poll
|
|
367
|
+
assert(ev.happened?)
|
|
368
|
+
current_time += 1
|
|
369
|
+
ev.poll
|
|
370
|
+
assert_equal(1, ev.history.size)
|
|
371
|
+
end
|
|
354
372
|
end
|
|
355
373
|
|
|
356
374
|
def test_and_state_events
|
|
357
375
|
State.pos = Pos::Euler3D.new
|
|
358
|
-
plan.
|
|
376
|
+
plan.add_permanent(ev = State.on_delta(:yaw => 2, :d => 10))
|
|
359
377
|
assert_kind_of(AndGenerator, ev)
|
|
360
378
|
|
|
361
|
-
|
|
379
|
+
engine.process_events
|
|
362
380
|
assert_equal(0, ev.history.size)
|
|
363
381
|
|
|
364
382
|
State.pos.yaw = 1
|
|
365
383
|
State.pos.x = 15
|
|
366
|
-
|
|
384
|
+
engine.process_events
|
|
367
385
|
assert_equal(0, ev.history.size)
|
|
368
386
|
|
|
369
387
|
State.pos.yaw = 2
|
|
370
|
-
|
|
388
|
+
engine.process_events
|
|
371
389
|
assert_equal(1, ev.history.size)
|
|
372
390
|
|
|
373
391
|
State.pos.yaw = 3
|
|
374
392
|
State.pos.x = 25
|
|
375
|
-
|
|
393
|
+
engine.process_events
|
|
376
394
|
assert_equal(1, ev.history.size)
|
|
377
395
|
|
|
378
396
|
State.pos.yaw = 4
|
|
379
|
-
|
|
397
|
+
engine.process_events
|
|
380
398
|
assert_equal(2, ev.history.size, ev.waiting.to_a)
|
|
381
399
|
end
|
|
382
400
|
|
|
383
401
|
def test_or_state_events
|
|
384
402
|
State.pos = Pos::Euler3D.new
|
|
385
|
-
plan.
|
|
403
|
+
plan.add_permanent(y = State.on_delta(:yaw => 2))
|
|
386
404
|
|
|
387
405
|
ev = y.or(:d => 10)
|
|
388
|
-
|
|
406
|
+
engine.process_events
|
|
389
407
|
assert_equal(0, ev.history.size)
|
|
390
408
|
|
|
391
409
|
State.pos.yaw = 1
|
|
392
410
|
State.pos.x = 15
|
|
393
|
-
|
|
411
|
+
engine.process_events
|
|
394
412
|
assert_equal(1, ev.history.size)
|
|
395
413
|
|
|
396
414
|
State.pos.yaw = 2
|
|
397
|
-
|
|
415
|
+
engine.process_events
|
|
398
416
|
assert_equal(1, ev.history.size)
|
|
399
417
|
|
|
400
418
|
State.pos.yaw = 3
|
|
401
|
-
|
|
419
|
+
engine.process_events
|
|
402
420
|
assert_equal(2, ev.history.size)
|
|
403
421
|
|
|
404
422
|
ev = ev.or(:t => 3600)
|
|
405
|
-
|
|
423
|
+
engine.process_events
|
|
406
424
|
assert_equal(0, ev.history.size)
|
|
407
425
|
|
|
408
426
|
time_event = plan.free_events.find { |t| t.kind_of?(TimeDeltaEvent) }
|
|
409
427
|
time_event.instance_variable_set(:@last_value, Time.now - 3600)
|
|
410
|
-
|
|
428
|
+
engine.process_events
|
|
411
429
|
assert_equal(1, ev.history.size)
|
|
412
430
|
end
|
|
413
431
|
end
|
data/test/test_support.rb
CHANGED
data/test/test_task.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/tasks/simple_task'
|
|
4
4
|
require 'roby/test/tasks/empty_task'
|
|
@@ -6,40 +6,100 @@ require 'flexmock'
|
|
|
6
6
|
|
|
7
7
|
class TC_Task < Test::Unit::TestCase
|
|
8
8
|
include Roby::Test
|
|
9
|
+
def setup
|
|
10
|
+
super
|
|
11
|
+
Roby.app.filter_backtraces = false
|
|
12
|
+
end
|
|
9
13
|
|
|
10
14
|
def test_model_tag
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
tag1 = TaskModelTag.new { argument :model_tag_1 }
|
|
16
|
+
assert(tag1.const_defined?(:ClassExtension))
|
|
17
|
+
assert(tag1::ClassExtension.method_defined?(:argument))
|
|
18
|
+
|
|
19
|
+
tag2 = TaskModelTag.new do
|
|
20
|
+
include tag1
|
|
21
|
+
argument :model_tag_2
|
|
22
|
+
end
|
|
23
|
+
assert(tag2 < tag1)
|
|
24
|
+
assert(tag2.const_defined?(:ClassExtension))
|
|
25
|
+
assert(tag2::ClassExtension.method_defined?(:argument))
|
|
26
|
+
|
|
16
27
|
task = Class.new(Task) do
|
|
17
|
-
include
|
|
28
|
+
include tag2
|
|
18
29
|
argument :task_tag
|
|
19
30
|
end
|
|
20
|
-
assert_equal([:task_tag, :
|
|
31
|
+
assert_equal([:task_tag, :model_tag_2, :model_tag_1].to_set, task.arguments.to_set)
|
|
21
32
|
end
|
|
22
33
|
|
|
23
|
-
def
|
|
24
|
-
model = Class.new(Task)
|
|
25
|
-
arguments :from, :to
|
|
26
|
-
end
|
|
27
|
-
plan.discover(task = model.new(:from => 'B', :useless => 'bla'))
|
|
34
|
+
def test_arguments_declaration
|
|
35
|
+
model = Class.new(Task) { arguments :from, :to }
|
|
28
36
|
assert_equal([], Task.arguments.to_a)
|
|
29
|
-
assert_equal([:from, :to].to_value_set,
|
|
30
|
-
|
|
31
|
-
assert_equal({:from => 'B'}, task.meaningful_arguments)
|
|
37
|
+
assert_equal([:from, :to].to_value_set, model.arguments.to_value_set)
|
|
38
|
+
end
|
|
32
39
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
def test_arguments_initialization
|
|
41
|
+
model = Class.new(Task) { arguments :arg, :to }
|
|
42
|
+
plan.add(task = model.new(:arg => 'B'))
|
|
43
|
+
assert_equal({:arg => 'B'}, task.arguments)
|
|
44
|
+
assert_equal('B', task.arg)
|
|
45
|
+
assert_equal(nil, task.to)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def test_arguments_initialization_uses_assignation_operator
|
|
49
|
+
model = Class.new(Task) do
|
|
50
|
+
arguments :arg, :to
|
|
51
|
+
|
|
52
|
+
def arg=(value)
|
|
53
|
+
arguments[:assigned] = true
|
|
54
|
+
arguments[:arg] = value
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
plan.add(task = model.new(:arg => 'B'))
|
|
59
|
+
assert_equal({:arg => 'B', :assigned => true}, task.arguments)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def test_arguments_assignation
|
|
63
|
+
model = Class.new(Task) { arguments :arg }
|
|
64
|
+
plan.add(task = model.new)
|
|
65
|
+
task.arguments[:arg] = 'A'
|
|
66
|
+
assert_equal('A', task.arg)
|
|
67
|
+
assert_equal({ :arg => 'A' }, task.arguments)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def test_arguments_assignation_operator
|
|
71
|
+
model = Class.new(Task) { arguments :arg }
|
|
72
|
+
plan.add(task = model.new)
|
|
73
|
+
task.arg = 'B'
|
|
74
|
+
assert_equal('B', task.arg)
|
|
75
|
+
assert_equal({ :arg => 'B' }, task.arguments)
|
|
76
|
+
end
|
|
38
77
|
|
|
78
|
+
def test_meaningful_arguments
|
|
79
|
+
model = Class.new(Task) { arguments :arg }
|
|
80
|
+
plan.add(task = model.new(:arg => 'B', :useless => 'bla'))
|
|
81
|
+
assert_equal({:arg => 'B', :useless => 'bla'}, task.arguments)
|
|
82
|
+
assert_equal({:arg => 'B'}, task.meaningful_arguments)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def test_arguments_cannot_override
|
|
86
|
+
model = Class.new(Task) { arguments :arg }
|
|
87
|
+
plan.add(task = model.new(:arg => 'B', :useless => 'bla'))
|
|
88
|
+
assert_raises(ArgumentError) { task.arg = 10 }
|
|
89
|
+
|
|
90
|
+
# But we can override non-meaningful arguments
|
|
39
91
|
task.arguments[:bar] = 42
|
|
40
92
|
assert_nothing_raised { task.arguments[:bar] = 43 }
|
|
41
93
|
end
|
|
42
94
|
|
|
95
|
+
def test_arguments_partially_instanciated
|
|
96
|
+
model = Class.new(Task) { arguments :arg0, :arg1 }
|
|
97
|
+
plan.add(task = model.new(:arg0 => 'B', :useless => 'bla'))
|
|
98
|
+
assert(task.partially_instanciated?)
|
|
99
|
+
task.arg1 = 'C'
|
|
100
|
+
assert(!task.partially_instanciated?)
|
|
101
|
+
end
|
|
102
|
+
|
|
43
103
|
def test_command_block
|
|
44
104
|
FlexMock.use do |mock|
|
|
45
105
|
model = Class.new(SimpleTask) do
|
|
@@ -48,7 +108,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
48
108
|
emit :start
|
|
49
109
|
end
|
|
50
110
|
end
|
|
51
|
-
plan.
|
|
111
|
+
plan.add_mission(task = model.new)
|
|
52
112
|
mock.should_receive(:start).once.with(task, [42])
|
|
53
113
|
task.start!(42)
|
|
54
114
|
end
|
|
@@ -70,53 +130,97 @@ class TC_Task < Test::Unit::TestCase
|
|
|
70
130
|
end
|
|
71
131
|
end
|
|
72
132
|
|
|
73
|
-
plan.
|
|
133
|
+
plan.add_mission(task = child_m.new)
|
|
74
134
|
mock.should_receive(:parent_started).once.with(task, 21)
|
|
75
135
|
mock.should_receive(:child_started).once.with(task, 42)
|
|
76
136
|
task.start!(42)
|
|
77
137
|
end
|
|
78
138
|
end
|
|
79
139
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
140
|
+
def assert_task_relation_set(task, relation, expected)
|
|
141
|
+
plan.add(task)
|
|
142
|
+
task.each_event do |from|
|
|
143
|
+
task.each_event do |to|
|
|
144
|
+
next if from == to
|
|
145
|
+
exp = expected[from.symbol]
|
|
146
|
+
if exp == to.symbol || (exp.respond_to?(:include?) && exp.include?(to.symbol))
|
|
147
|
+
assert from.child_object?(to, relation), "expected relation #{from} => #{to} in #{relation} is missing"
|
|
148
|
+
else
|
|
149
|
+
assert !from.child_object?(to, relation), "unexpected relation #{from} => #{to} found in #{relation}"
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
85
154
|
|
|
86
|
-
|
|
155
|
+
def do_test_instantiate_model_relations(method, relation, additional_links = Hash.new)
|
|
156
|
+
klass = Class.new(Roby::Test::SimpleTask) do
|
|
157
|
+
4.times { |i| event "e#{i + 1}", :command => true }
|
|
158
|
+
send(method, :e1 => [:e2, :e3], :e4 => :stop)
|
|
87
159
|
end
|
|
160
|
+
|
|
161
|
+
plan.add(task = klass.new)
|
|
162
|
+
expected_links = Hash[:e1 => [:e2, :e3], :e4 => :stop]
|
|
163
|
+
|
|
164
|
+
assert_task_relation_set task, relation, expected_links.merge(additional_links)
|
|
165
|
+
end
|
|
166
|
+
def test_instantiate_model_signals
|
|
167
|
+
do_test_instantiate_model_relations(:signal, EventStructure::Signal)
|
|
168
|
+
end
|
|
169
|
+
def test_instantiate_deprecated_model_on
|
|
170
|
+
deprecated_feature do
|
|
171
|
+
do_test_instantiate_model_relations(:on, EventStructure::Signal)
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
def test_instantiate_model_forward
|
|
175
|
+
do_test_instantiate_model_relations(:forward, EventStructure::Forwarding,
|
|
176
|
+
:success => :stop, :aborted => :failed, :failed => :stop)
|
|
177
|
+
end
|
|
178
|
+
def test_instantiate_model_causal_links
|
|
179
|
+
do_test_instantiate_model_relations(:causal_link, EventStructure::CausalLink,
|
|
180
|
+
:success => :stop, :aborted => :failed, :failed => :stop)
|
|
88
181
|
end
|
|
89
182
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
end.new
|
|
100
|
-
plan.discover(task)
|
|
183
|
+
|
|
184
|
+
def do_test_inherit_model_relations(method, relation, additional_links = Hash.new)
|
|
185
|
+
base = Class.new(Roby::Test::SimpleTask) do
|
|
186
|
+
4.times { |i| event "e#{i + 1}", :command => true }
|
|
187
|
+
send(method, :e1 => [:e2, :e3])
|
|
188
|
+
end
|
|
189
|
+
subclass = Class.new(base) do
|
|
190
|
+
send(method, :e4 => :stop)
|
|
191
|
+
end
|
|
101
192
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
:second => [:third],
|
|
106
|
-
:third => [:success, :aborted],
|
|
107
|
-
:aborted => [:failed],
|
|
108
|
-
:failed => [:stop],
|
|
109
|
-
:success => [:stop]
|
|
193
|
+
task = base.new
|
|
194
|
+
assert_task_relation_set task, relation,
|
|
195
|
+
Hash[:e1 => [:e2, :e3]].merge(additional_links)
|
|
110
196
|
|
|
197
|
+
task = subclass.new
|
|
198
|
+
assert_task_relation_set task, relation,
|
|
199
|
+
Hash[:e1 => [:e2, :e3], :e4 => :stop].merge(additional_links)
|
|
200
|
+
end
|
|
201
|
+
def test_inherit_model_signals
|
|
202
|
+
do_test_inherit_model_relations(:signal, EventStructure::Signal)
|
|
203
|
+
end
|
|
204
|
+
def test_inherit_deprecated_model_on
|
|
205
|
+
deprecated_feature do
|
|
206
|
+
do_test_inherit_model_relations(:on, EventStructure::Signal)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
def test_inherit_model_forward
|
|
210
|
+
do_test_inherit_model_relations(:forward, EventStructure::Forwarding,
|
|
211
|
+
:success => :stop, :aborted => :failed, :failed => :stop)
|
|
212
|
+
end
|
|
213
|
+
def test_inherit_model_causal_links
|
|
214
|
+
do_test_inherit_model_relations(:causal_link, EventStructure::CausalLink,
|
|
215
|
+
:success => :stop, :aborted => :failed, :failed => :stop)
|
|
111
216
|
end
|
|
112
217
|
|
|
113
218
|
# Test the behaviour of Task#on, and event propagation inside a task
|
|
114
|
-
def
|
|
115
|
-
plan.
|
|
219
|
+
def test_instance_event_handlers
|
|
220
|
+
plan.add(t1 = SimpleTask.new)
|
|
116
221
|
assert_raises(ArgumentError) { t1.on(:start) }
|
|
117
222
|
|
|
118
|
-
|
|
119
|
-
plan.discover(task = SimpleTask.new)
|
|
223
|
+
plan.add(task = SimpleTask.new)
|
|
120
224
|
FlexMock.use do |mock|
|
|
121
225
|
task.on(:start) { |event| mock.started(event.context) }
|
|
122
226
|
task.on(:start) { |event| task.emit(:success, *event.context) }
|
|
@@ -130,38 +234,64 @@ class TC_Task < Test::Unit::TestCase
|
|
|
130
234
|
assert(task.finished?)
|
|
131
235
|
event_history = task.history.map { |ev| ev.generator }
|
|
132
236
|
assert_equal([task.event(:start), task.event(:success), task.event(:stop)], event_history)
|
|
237
|
+
end
|
|
133
238
|
|
|
134
|
-
|
|
239
|
+
def test_instance_signals
|
|
135
240
|
FlexMock.use do |mock|
|
|
136
|
-
t1, t2 = prepare_plan :
|
|
137
|
-
|
|
138
|
-
t2.on(:start) { mock.start }
|
|
241
|
+
t1, t2 = prepare_plan :add => 3, :model => SimpleTask
|
|
242
|
+
t1.signals(:start, t2, :start)
|
|
139
243
|
|
|
140
|
-
|
|
244
|
+
t2.on(:start) { mock.start }
|
|
245
|
+
mock.should_receive(:start).once
|
|
141
246
|
t1.start!
|
|
142
247
|
end
|
|
248
|
+
end
|
|
143
249
|
|
|
250
|
+
def test_instance_signals_deprecated_default_event_name
|
|
144
251
|
FlexMock.use do |mock|
|
|
145
|
-
t1, t2 = prepare_plan :
|
|
146
|
-
|
|
252
|
+
t1, t2 = prepare_plan :add => 3, :model => SimpleTask
|
|
253
|
+
deprecated_feature do
|
|
254
|
+
t1.on(:start, t2)
|
|
255
|
+
end
|
|
147
256
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
257
|
+
t2.on(:start) { mock.start }
|
|
258
|
+
mock.should_receive(:start).once
|
|
259
|
+
t1.start!
|
|
260
|
+
end
|
|
261
|
+
end
|
|
151
262
|
|
|
152
|
-
|
|
153
|
-
|
|
263
|
+
def test_instance_signals_deprecated_on_usage
|
|
264
|
+
FlexMock.use do |mock|
|
|
265
|
+
t1, t2 = prepare_plan :add => 3, :model => SimpleTask
|
|
266
|
+
deprecated_feature do
|
|
267
|
+
t1.on(:start, t2, :start)
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
t2.on(:start) { mock.start }
|
|
271
|
+
mock.should_receive(:start).once
|
|
154
272
|
t1.start!
|
|
155
273
|
end
|
|
274
|
+
end
|
|
156
275
|
|
|
276
|
+
def test_instance_signals_plain_events
|
|
157
277
|
t = prepare_plan :missions => 1, :model => SimpleTask
|
|
158
278
|
e = EventGenerator.new(true)
|
|
159
|
-
t.
|
|
279
|
+
t.signals(:start, e)
|
|
160
280
|
t.start!
|
|
161
281
|
assert(e.happened?)
|
|
162
282
|
end
|
|
163
283
|
|
|
164
|
-
def
|
|
284
|
+
def test_instance_signals_plain_events_deprecated_on_usage
|
|
285
|
+
t = prepare_plan :missions => 1, :model => SimpleTask
|
|
286
|
+
e = EventGenerator.new(true)
|
|
287
|
+
deprecated_feature do
|
|
288
|
+
t.on(:start, e)
|
|
289
|
+
end
|
|
290
|
+
t.start!
|
|
291
|
+
assert(e.happened?)
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def test_model_forwardings
|
|
165
295
|
model = Class.new(SimpleTask) do
|
|
166
296
|
forward :start => :failed
|
|
167
297
|
end
|
|
@@ -169,10 +299,20 @@ class TC_Task < Test::Unit::TestCase
|
|
|
169
299
|
assert_equal({}, SimpleTask.signal_sets)
|
|
170
300
|
|
|
171
301
|
assert_equal([:failed, :stop].to_value_set, model.forwardings(:start))
|
|
172
|
-
assert_equal([:stop].to_value_set,
|
|
173
|
-
assert_equal(
|
|
302
|
+
assert_equal([:stop].to_value_set, model.forwardings(:failed))
|
|
303
|
+
assert_equal([:stop].to_value_set, model.enum_for(:each_forwarding, :failed).to_value_set)
|
|
304
|
+
|
|
305
|
+
plan.add(task = model.new)
|
|
306
|
+
task.start!
|
|
174
307
|
|
|
175
|
-
|
|
308
|
+
# Make sure the model-level relation is not applied to parent models
|
|
309
|
+
plan.add(task = SimpleTask.new)
|
|
310
|
+
task.start!
|
|
311
|
+
assert(!task.failed?)
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
def test_model_event_handlers
|
|
315
|
+
model = Class.new(SimpleTask)
|
|
176
316
|
assert_raises(ArgumentError) { model.on(:start) { || } }
|
|
177
317
|
assert_raises(ArgumentError) { model.on(:start) { |a, b| } }
|
|
178
318
|
|
|
@@ -180,42 +320,29 @@ class TC_Task < Test::Unit::TestCase
|
|
|
180
320
|
model.on :start do
|
|
181
321
|
mock.start_called(self)
|
|
182
322
|
end
|
|
183
|
-
plan.
|
|
323
|
+
plan.add(task = model.new)
|
|
184
324
|
mock.should_receive(:start_called).with(task).once
|
|
185
325
|
task.start!
|
|
186
|
-
assert(task.failed?)
|
|
187
|
-
end
|
|
188
326
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
327
|
+
# Make sure the model-level handler is not applied to parent models
|
|
328
|
+
plan.add(task = SimpleTask.new)
|
|
329
|
+
task.start!
|
|
330
|
+
assert(!task.failed?)
|
|
331
|
+
end
|
|
193
332
|
end
|
|
194
333
|
|
|
195
|
-
def
|
|
334
|
+
def test_instance_forward_to
|
|
196
335
|
FlexMock.use do |mock|
|
|
197
336
|
t1, t2 = prepare_plan :missions => 2, :model => SimpleTask
|
|
198
|
-
t1.
|
|
337
|
+
t1.forward_to(:start, t2, :start)
|
|
199
338
|
t2.on(:start) { mock.start }
|
|
200
339
|
|
|
201
340
|
mock.should_receive(:start).once
|
|
202
341
|
t1.start!
|
|
203
342
|
end
|
|
343
|
+
end
|
|
204
344
|
|
|
205
|
-
|
|
206
|
-
t1, t2 = prepare_plan :missions => 2, :model => SimpleTask
|
|
207
|
-
t2.start!
|
|
208
|
-
|
|
209
|
-
t1.forward(:start, t2, :stop)
|
|
210
|
-
t2.on(:start) { mock.start }
|
|
211
|
-
t2.on(:stop) { mock.stop }
|
|
212
|
-
|
|
213
|
-
mock.should_receive(:start).never
|
|
214
|
-
mock.should_receive(:stop).once
|
|
215
|
-
t1.start!
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
|
|
345
|
+
def test_instance_forward_to_plain_events
|
|
219
346
|
FlexMock.use do |mock|
|
|
220
347
|
t1 = prepare_plan :missions => 1, :model => SimpleTask
|
|
221
348
|
ev = EventGenerator.new do
|
|
@@ -223,7 +350,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
223
350
|
ev.emit
|
|
224
351
|
end
|
|
225
352
|
ev.on { mock.emitted }
|
|
226
|
-
t1.
|
|
353
|
+
t1.forward_to(:start, ev)
|
|
227
354
|
|
|
228
355
|
mock.should_receive(:called).never
|
|
229
356
|
mock.should_receive(:emitted).once
|
|
@@ -231,68 +358,78 @@ class TC_Task < Test::Unit::TestCase
|
|
|
231
358
|
end
|
|
232
359
|
end
|
|
233
360
|
|
|
234
|
-
def
|
|
361
|
+
def test_terminal_option
|
|
235
362
|
klass = Class.new(Task) do
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
event
|
|
247
|
-
forward :
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
363
|
+
event :terminal, :terminal => true
|
|
364
|
+
end
|
|
365
|
+
assert klass.event_model(:terminal).terminal?
|
|
366
|
+
plan.add(task = klass.new)
|
|
367
|
+
assert task.event(:terminal).terminal?
|
|
368
|
+
assert task.event(:terminal).child_object?(task.event(:stop), EventStructure::Forwarding)
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
def test_terminal_direct_forward_in_model
|
|
372
|
+
klass = Class.new(Task) do
|
|
373
|
+
event :terminal
|
|
374
|
+
forward :terminal => :stop
|
|
375
|
+
end
|
|
376
|
+
assert klass.event_model(:terminal).terminal?
|
|
377
|
+
plan.add(task = klass.new)
|
|
378
|
+
assert task.event(:terminal).terminal?
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
def test_terminal_indirect_forward_in_model
|
|
382
|
+
klass = Class.new(Task) do
|
|
383
|
+
event :terminal
|
|
384
|
+
event :intermediate
|
|
385
|
+
|
|
386
|
+
forward :intermediate => :failed
|
|
387
|
+
forward :terminal => :intermediate
|
|
252
388
|
end
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
389
|
+
assert klass.event_model(:terminal).terminal?
|
|
390
|
+
plan.add(task = klass.new)
|
|
391
|
+
assert task.event(:terminal).terminal?
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
def test_terminal_direct_signal_in_model
|
|
395
|
+
klass = Class.new(SimpleTask) do
|
|
396
|
+
event :terminal
|
|
397
|
+
signal :terminal => :stop
|
|
398
|
+
end
|
|
399
|
+
assert klass.event_model(:terminal).terminal?
|
|
400
|
+
plan.add(task = klass.new)
|
|
401
|
+
assert task.event(:terminal).terminal?
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
def test_terminal_indirect_signal_in_model
|
|
405
|
+
klass = Class.new(Task) do
|
|
406
|
+
event :terminal
|
|
407
|
+
event :intermediate, :command => true
|
|
408
|
+
|
|
409
|
+
signal :terminal => :intermediate
|
|
410
|
+
forward :intermediate => :failed
|
|
411
|
+
end
|
|
412
|
+
assert klass.event_model(:terminal).terminal?
|
|
413
|
+
plan.add(task = klass.new)
|
|
414
|
+
assert task.event(:terminal).terminal?
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
def test_should_not_establish_signal_from_terminal_to_non_terminal
|
|
418
|
+
klass = Class.new(Task) do
|
|
419
|
+
event :terminal, :terminal => true
|
|
420
|
+
event :intermediate
|
|
421
|
+
end
|
|
422
|
+
assert_raises(ArgumentError) { klass.forward :terminal => :intermediate }
|
|
423
|
+
klass.new
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
def test_should_not_establish_signal_from_terminal_to_non_terminal
|
|
427
|
+
klass = Class.new(Task) do
|
|
428
|
+
event :terminal, :terminal => true
|
|
429
|
+
event :intermediate, :command => true
|
|
430
|
+
end
|
|
431
|
+
assert_raises(ArgumentError) { klass.signal :terminal => :intermediate }
|
|
432
|
+
klass.new
|
|
296
433
|
end
|
|
297
434
|
|
|
298
435
|
# Tests Task::event
|
|
@@ -312,8 +449,9 @@ class TC_Task < Test::Unit::TestCase
|
|
|
312
449
|
|
|
313
450
|
klass.event :ev_terminal, :terminal => true, :command => true
|
|
314
451
|
|
|
315
|
-
plan.
|
|
452
|
+
plan.add(task = klass.new)
|
|
316
453
|
assert_respond_to(task, :start!)
|
|
454
|
+
assert_respond_to(task, :start?)
|
|
317
455
|
|
|
318
456
|
# Test modifications to the class hierarchy
|
|
319
457
|
my_event = nil
|
|
@@ -349,7 +487,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
349
487
|
# Check validation of options[:command]
|
|
350
488
|
assert_raise(ArgumentError) { klass.event :try_event, :command => "bla" }
|
|
351
489
|
|
|
352
|
-
plan.
|
|
490
|
+
plan.add(task = EmptyTask.new)
|
|
353
491
|
start_event = task.event(:start)
|
|
354
492
|
|
|
355
493
|
assert_equal(start_event, task.event(:start))
|
|
@@ -371,7 +509,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
371
509
|
failed!
|
|
372
510
|
end
|
|
373
511
|
end.new
|
|
374
|
-
plan.
|
|
512
|
+
plan.add(task)
|
|
375
513
|
|
|
376
514
|
assert(task.pending?)
|
|
377
515
|
assert(!task.starting?)
|
|
@@ -437,7 +575,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
437
575
|
|
|
438
576
|
on(:stop) { |event| mock.stopped(event.context) }
|
|
439
577
|
end
|
|
440
|
-
plan.
|
|
578
|
+
plan.add_mission(task = model.new)
|
|
441
579
|
|
|
442
580
|
mock.should_receive(:starting).with([42]).once
|
|
443
581
|
mock.should_receive(:started).with([42]).once
|
|
@@ -488,7 +626,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
488
626
|
ev_models = Hash[*model.enum_for(:each_event).to_a.flatten]
|
|
489
627
|
assert_equal([:start, :success, :aborted, :updated_data, :stop, :failed, :inter].to_set, ev_models.keys.to_set)
|
|
490
628
|
|
|
491
|
-
plan.
|
|
629
|
+
plan.add(task = model.new)
|
|
492
630
|
ev_models = Hash[*task.model.enum_for(:each_event).to_a.flatten]
|
|
493
631
|
assert_equal([:start, :success, :aborted, :updated_data, :stop, :failed, :inter].to_set, ev_models.keys.to_set)
|
|
494
632
|
assert( ev_models[:start].symbol )
|
|
@@ -499,7 +637,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
499
637
|
model = Class.new(SimpleTask) do
|
|
500
638
|
event(:inter, :command => true)
|
|
501
639
|
end
|
|
502
|
-
plan.
|
|
640
|
+
plan.add(task = model.new)
|
|
503
641
|
|
|
504
642
|
assert_raises(CommandFailed) { task.inter! }
|
|
505
643
|
assert_raises(EmissionFailed) { task.emit(:inter) }
|
|
@@ -523,7 +661,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
523
661
|
emit :inter
|
|
524
662
|
end
|
|
525
663
|
end
|
|
526
|
-
plan.
|
|
664
|
+
plan.add(task = model.new)
|
|
527
665
|
assert_nothing_raised { task.start! }
|
|
528
666
|
end
|
|
529
667
|
|
|
@@ -535,7 +673,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
535
673
|
event :stop, :command => true
|
|
536
674
|
end
|
|
537
675
|
|
|
538
|
-
plan.
|
|
676
|
+
plan.add(task = model.new)
|
|
539
677
|
task.start!
|
|
540
678
|
task.emit(:stop)
|
|
541
679
|
assert(!task.success?)
|
|
@@ -543,7 +681,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
543
681
|
assert(task.finished?)
|
|
544
682
|
assert_equal(task.event(:stop).last, task.terminal_event)
|
|
545
683
|
|
|
546
|
-
plan.
|
|
684
|
+
plan.add(task = model.new)
|
|
547
685
|
task.start!
|
|
548
686
|
task.emit(:success)
|
|
549
687
|
assert(task.success?)
|
|
@@ -551,7 +689,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
551
689
|
assert(task.finished?)
|
|
552
690
|
assert_equal(task.event(:success).last, task.terminal_event)
|
|
553
691
|
|
|
554
|
-
plan.
|
|
692
|
+
plan.add(task = model.new)
|
|
555
693
|
task.start!
|
|
556
694
|
task.emit(:failed)
|
|
557
695
|
assert(!task.success?)
|
|
@@ -565,7 +703,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
565
703
|
flunk 'no exception raised'
|
|
566
704
|
rescue klass => e
|
|
567
705
|
unless msg === e.message
|
|
568
|
-
flunk "exception message '#{e.message}' does not match the expected pattern"
|
|
706
|
+
flunk "exception message '#{e.message}' does not match the expected pattern #{msg}"
|
|
569
707
|
end
|
|
570
708
|
rescue Exception => e
|
|
571
709
|
flunk "expected an exception of class #{klass} but got #{e.full_message}"
|
|
@@ -581,9 +719,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
581
719
|
assert_raises(EventNotExecutable) { task.start! }
|
|
582
720
|
assert_raises(EventNotExecutable) { task.event(:start).call }
|
|
583
721
|
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
plan.discover(task)
|
|
722
|
+
plan.add(task)
|
|
587
723
|
assert(task.executable?)
|
|
588
724
|
assert_nothing_raised { task.event(:start).call(nil) }
|
|
589
725
|
|
|
@@ -591,7 +727,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
591
727
|
assert_raises(ModelViolation) { task.executable = false }
|
|
592
728
|
|
|
593
729
|
task = SimpleTask.new
|
|
594
|
-
plan.
|
|
730
|
+
plan.add_mission(task)
|
|
595
731
|
assert(task.executable?)
|
|
596
732
|
task.executable = false
|
|
597
733
|
assert(!task.executable?)
|
|
@@ -599,7 +735,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
599
735
|
assert(task.executable?)
|
|
600
736
|
|
|
601
737
|
task = SimpleTask.new
|
|
602
|
-
plan.
|
|
738
|
+
plan.add_permanent(task)
|
|
603
739
|
assert(task.executable?)
|
|
604
740
|
task.executable = false
|
|
605
741
|
assert(!task.executable?)
|
|
@@ -639,11 +775,11 @@ class TC_Task < Test::Unit::TestCase
|
|
|
639
775
|
if check_signaling then
|
|
640
776
|
error = yield
|
|
641
777
|
assert_exception_message(EventNotExecutable, substring) do
|
|
642
|
-
exception_propagator(error, :
|
|
778
|
+
exception_propagator(error, :signals)
|
|
643
779
|
end
|
|
644
780
|
error = yield
|
|
645
781
|
assert_exception_message(EventNotExecutable, substring) do
|
|
646
|
-
exception_propagator(error, :
|
|
782
|
+
exception_propagator(error, :forward_to)
|
|
647
783
|
end
|
|
648
784
|
end
|
|
649
785
|
end
|
|
@@ -651,7 +787,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
651
787
|
def test_exception_refinement
|
|
652
788
|
# test for partially instanciation
|
|
653
789
|
check_direct_start(/partially instanciated/,true) do
|
|
654
|
-
plan.
|
|
790
|
+
plan.add(task = ParameterizedTask.new)
|
|
655
791
|
task
|
|
656
792
|
end
|
|
657
793
|
|
|
@@ -662,21 +798,21 @@ class TC_Task < Test::Unit::TestCase
|
|
|
662
798
|
|
|
663
799
|
#test for an abstract task
|
|
664
800
|
check_direct_start(/abstract/,true) do
|
|
665
|
-
plan.
|
|
801
|
+
plan.add(task = AbstractTask.new)
|
|
666
802
|
task
|
|
667
803
|
end
|
|
668
804
|
|
|
669
805
|
#test for a not executable plan
|
|
670
806
|
erroneous_plan = NotExecutablePlan.new
|
|
671
807
|
check_direct_start(/plan is not executable/,false) do
|
|
672
|
-
erroneous_plan.
|
|
808
|
+
erroneous_plan.add(task = SimpleTask.new)
|
|
673
809
|
task
|
|
674
810
|
end
|
|
675
|
-
erroneous_plan.
|
|
811
|
+
erroneous_plan.clear
|
|
676
812
|
|
|
677
813
|
#test for a not executable task
|
|
678
814
|
check_direct_start(/is not executable/,true) do
|
|
679
|
-
plan.
|
|
815
|
+
plan.add(task = SimpleTask.new)
|
|
680
816
|
task.executable = false
|
|
681
817
|
task
|
|
682
818
|
end
|
|
@@ -686,7 +822,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
686
822
|
|
|
687
823
|
def test_task_success_failure
|
|
688
824
|
FlexMock.use do |mock|
|
|
689
|
-
plan.
|
|
825
|
+
plan.add_mission(t = EmptyTask.new)
|
|
690
826
|
[:start, :success, :stop].each do |name|
|
|
691
827
|
t.on(name) { mock.send(name) }
|
|
692
828
|
mock.should_receive(name).once.ordered
|
|
@@ -696,7 +832,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
696
832
|
end
|
|
697
833
|
|
|
698
834
|
def aggregator_test(a, *tasks)
|
|
699
|
-
plan.
|
|
835
|
+
plan.add_mission(a)
|
|
700
836
|
FlexMock.use do |mock|
|
|
701
837
|
[:start, :success, :stop].each do |name|
|
|
702
838
|
a.on(name) { mock.send(name) }
|
|
@@ -709,10 +845,10 @@ class TC_Task < Test::Unit::TestCase
|
|
|
709
845
|
|
|
710
846
|
def test_task_parallel_aggregator
|
|
711
847
|
t1, t2 = EmptyTask.new, EmptyTask.new
|
|
712
|
-
plan.
|
|
848
|
+
plan.add([t1, t2])
|
|
713
849
|
aggregator_test((t1 | t2), t1, t2)
|
|
714
850
|
t1, t2 = EmptyTask.new, EmptyTask.new
|
|
715
|
-
plan.
|
|
851
|
+
plan.add([t1, t2])
|
|
716
852
|
aggregator_test( (t1 | t2).to_task, t1, t2 )
|
|
717
853
|
end
|
|
718
854
|
|
|
@@ -755,7 +891,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
755
891
|
|
|
756
892
|
task = seq.to_task(model)
|
|
757
893
|
|
|
758
|
-
plan.
|
|
894
|
+
plan.add_mission(task)
|
|
759
895
|
|
|
760
896
|
assert(!seq.child_object?(t1, TaskStructure::Hierarchy))
|
|
761
897
|
assert(!seq.child_object?(t2, TaskStructure::Hierarchy))
|
|
@@ -769,13 +905,13 @@ class TC_Task < Test::Unit::TestCase
|
|
|
769
905
|
end
|
|
770
906
|
|
|
771
907
|
def test_compatible_state
|
|
772
|
-
t1, t2 = prepare_plan :
|
|
908
|
+
t1, t2 = prepare_plan :add => 2, :model => SimpleTask
|
|
773
909
|
|
|
774
910
|
assert(t1.compatible_state?(t2))
|
|
775
911
|
t1.start!; assert(! t1.compatible_state?(t2) && !t2.compatible_state?(t1))
|
|
776
912
|
t1.stop!; assert(t1.compatible_state?(t2) && t2.compatible_state?(t1))
|
|
777
913
|
|
|
778
|
-
plan.
|
|
914
|
+
plan.add(t1 = SimpleTask.new)
|
|
779
915
|
t1.start!
|
|
780
916
|
t2.start!; assert(t1.compatible_state?(t2) && t2.compatible_state?(t1))
|
|
781
917
|
t1.stop!; assert(t1.compatible_state?(t2) && !t2.compatible_state?(t1))
|
|
@@ -791,31 +927,33 @@ class TC_Task < Test::Unit::TestCase
|
|
|
791
927
|
end
|
|
792
928
|
|
|
793
929
|
t1, t2 = task_model.new, task_model.new
|
|
794
|
-
plan.
|
|
930
|
+
plan.add([t1, t2])
|
|
795
931
|
assert(t1.fullfills?(t1.model))
|
|
796
932
|
assert(t1.fullfills?(t2))
|
|
797
933
|
assert(t1.fullfills?(abstract_task_model))
|
|
798
934
|
|
|
799
|
-
plan.
|
|
935
|
+
plan.add(t2 = task_model.new(:index => 2))
|
|
800
936
|
assert(!t1.fullfills?(t2))
|
|
801
937
|
|
|
802
|
-
plan.
|
|
938
|
+
plan.add(t3 = task_model.new(:universe => 42))
|
|
803
939
|
assert(t3.fullfills?(t1))
|
|
804
940
|
assert(!t1.fullfills?(t3))
|
|
941
|
+
plan.add(t3 = task_model.new(:universe => 42, :index => 21))
|
|
942
|
+
assert(t3.fullfills?(task_model, :universe => 42))
|
|
805
943
|
|
|
806
|
-
plan.
|
|
944
|
+
plan.add(t3 = Class.new(Task).new)
|
|
807
945
|
assert(!t1.fullfills?(t3))
|
|
808
946
|
|
|
809
|
-
plan.
|
|
947
|
+
plan.add(t3 = Class.new(task_model).new)
|
|
810
948
|
assert(!t1.fullfills?(t3))
|
|
811
949
|
assert(t3.fullfills?(t1))
|
|
812
950
|
end
|
|
813
951
|
|
|
814
952
|
def test_related_tasks
|
|
815
953
|
t1, t2, t3 = (1..3).map { SimpleTask.new }.
|
|
816
|
-
each { |t| plan.
|
|
817
|
-
t1.
|
|
818
|
-
t1.event(:start).
|
|
954
|
+
each { |t| plan.add(t) }
|
|
955
|
+
t1.depends_on t2
|
|
956
|
+
t1.event(:start).signals t3.event(:start)
|
|
819
957
|
assert_equal([t3].to_value_set, t1.event(:start).related_tasks)
|
|
820
958
|
assert_equal([t2].to_value_set, t1.related_objects)
|
|
821
959
|
assert_equal([t2, t3].to_value_set, t1.related_tasks)
|
|
@@ -823,9 +961,9 @@ class TC_Task < Test::Unit::TestCase
|
|
|
823
961
|
|
|
824
962
|
def test_related_events
|
|
825
963
|
t1, t2, t3 = (1..3).map { SimpleTask.new }.
|
|
826
|
-
each { |t| plan.
|
|
827
|
-
t1.
|
|
828
|
-
t1.event(:start).
|
|
964
|
+
each { |t| plan.add(t) }
|
|
965
|
+
t1.depends_on t2
|
|
966
|
+
t1.event(:start).signals t3.event(:start)
|
|
829
967
|
assert_equal([t3.event(:start)].to_value_set, t1.related_events)
|
|
830
968
|
end
|
|
831
969
|
|
|
@@ -836,7 +974,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
836
974
|
|
|
837
975
|
# Test that the stop event will make the handler called on a running task
|
|
838
976
|
FlexMock.use do |mock|
|
|
839
|
-
plan.
|
|
977
|
+
plan.add(task = model.new)
|
|
840
978
|
ev = task.event(:success)
|
|
841
979
|
ev.if_unreachable(false) { mock.success_called }
|
|
842
980
|
ev.if_unreachable(true) { mock.success_cancel_called }
|
|
@@ -851,11 +989,11 @@ class TC_Task < Test::Unit::TestCase
|
|
|
851
989
|
task.start!
|
|
852
990
|
task.success!
|
|
853
991
|
end
|
|
854
|
-
|
|
992
|
+
engine.garbage_collect
|
|
855
993
|
|
|
856
994
|
# Test that it works on pending tasks too
|
|
857
995
|
FlexMock.use do |mock|
|
|
858
|
-
plan.
|
|
996
|
+
plan.add(task = model.new)
|
|
859
997
|
ev = task.event(:success)
|
|
860
998
|
ev.if_unreachable(false) { mock.success_called }
|
|
861
999
|
ev.if_unreachable(true) { mock.success_cancel_called }
|
|
@@ -868,7 +1006,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
868
1006
|
mock.should_receive(:ready_called).once
|
|
869
1007
|
mock.should_receive(:ready_cancel_called).once
|
|
870
1008
|
|
|
871
|
-
|
|
1009
|
+
engine.garbage_collect
|
|
872
1010
|
end
|
|
873
1011
|
|
|
874
1012
|
end
|
|
@@ -881,11 +1019,11 @@ class TC_Task < Test::Unit::TestCase
|
|
|
881
1019
|
event(:start).achieve_with slave
|
|
882
1020
|
end
|
|
883
1021
|
end.new
|
|
884
|
-
plan.
|
|
1022
|
+
plan.add([master, slave])
|
|
885
1023
|
|
|
886
1024
|
master.start!
|
|
887
1025
|
assert(master.starting?)
|
|
888
|
-
assert(master.
|
|
1026
|
+
assert(master.depends_on?(slave))
|
|
889
1027
|
slave.start!
|
|
890
1028
|
slave.success!
|
|
891
1029
|
assert(master.started?)
|
|
@@ -896,7 +1034,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
896
1034
|
event(:start).achieve_with slave.event(:start)
|
|
897
1035
|
end
|
|
898
1036
|
end.new
|
|
899
|
-
plan.
|
|
1037
|
+
plan.add([master, slave])
|
|
900
1038
|
|
|
901
1039
|
master.start!
|
|
902
1040
|
assert(master.starting?)
|
|
@@ -905,7 +1043,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
905
1043
|
|
|
906
1044
|
def test_task_group
|
|
907
1045
|
t1, t2 = SimpleTask.new, SimpleTask.new
|
|
908
|
-
plan.
|
|
1046
|
+
plan.add(g = Group.new(t1, t2))
|
|
909
1047
|
|
|
910
1048
|
g.start!
|
|
911
1049
|
assert(t1.running?)
|
|
@@ -918,7 +1056,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
918
1056
|
end
|
|
919
1057
|
|
|
920
1058
|
def test_task_poll
|
|
921
|
-
|
|
1059
|
+
engine.run
|
|
922
1060
|
|
|
923
1061
|
FlexMock.use do |mock|
|
|
924
1062
|
t = Class.new(SimpleTask) do
|
|
@@ -928,12 +1066,12 @@ class TC_Task < Test::Unit::TestCase
|
|
|
928
1066
|
end.new
|
|
929
1067
|
mock.should_receive(:polled).at_least.once.with(t)
|
|
930
1068
|
|
|
931
|
-
|
|
932
|
-
plan.
|
|
1069
|
+
engine.execute do
|
|
1070
|
+
plan.add_permanent(t)
|
|
933
1071
|
t.start!
|
|
934
1072
|
end
|
|
935
|
-
|
|
936
|
-
|
|
1073
|
+
engine.wait_one_cycle
|
|
1074
|
+
engine.execute do
|
|
937
1075
|
assert(t.running?, t.terminal_event.to_s)
|
|
938
1076
|
t.stop!
|
|
939
1077
|
end
|
|
@@ -948,11 +1086,11 @@ class TC_Task < Test::Unit::TestCase
|
|
|
948
1086
|
end
|
|
949
1087
|
end.new
|
|
950
1088
|
|
|
951
|
-
|
|
952
|
-
plan.
|
|
1089
|
+
engine.execute do
|
|
1090
|
+
plan.add_permanent(t)
|
|
953
1091
|
t.start!
|
|
954
1092
|
end
|
|
955
|
-
|
|
1093
|
+
engine.wait_one_cycle
|
|
956
1094
|
assert(t.failed?)
|
|
957
1095
|
end
|
|
958
1096
|
end
|
|
@@ -962,15 +1100,15 @@ class TC_Task < Test::Unit::TestCase
|
|
|
962
1100
|
event :specialized_failure, :command => true
|
|
963
1101
|
forward :specialized_failure => :failed
|
|
964
1102
|
end.new
|
|
965
|
-
plan.
|
|
1103
|
+
plan.add(task)
|
|
966
1104
|
|
|
967
1105
|
task.start!
|
|
968
1106
|
assert_equal([task.event(:start).last], task.event(:start).last.task_sources.to_a)
|
|
969
1107
|
|
|
970
1108
|
ev = EventGenerator.new(true)
|
|
971
|
-
ev.
|
|
1109
|
+
ev.forward_to task.event(:specialized_failure)
|
|
972
1110
|
ev.call
|
|
973
|
-
assert_equal([task.event(:specialized_failure).last], task.event(:
|
|
1111
|
+
assert_equal([task.event(:specialized_failure).last], task.event(:stop).last.task_sources.to_a)
|
|
974
1112
|
end
|
|
975
1113
|
|
|
976
1114
|
def test_virtual_task
|
|
@@ -978,7 +1116,7 @@ class TC_Task < Test::Unit::TestCase
|
|
|
978
1116
|
assert_raises(ArgumentError) { VirtualTask.create(success, start) }
|
|
979
1117
|
|
|
980
1118
|
assert_kind_of(VirtualTask, task = VirtualTask.create(start, success))
|
|
981
|
-
plan.
|
|
1119
|
+
plan.add(task)
|
|
982
1120
|
assert_equal(start, task.start_event)
|
|
983
1121
|
assert_equal(success, task.success_event)
|
|
984
1122
|
FlexMock.use do |mock|
|
|
@@ -993,19 +1131,19 @@ class TC_Task < Test::Unit::TestCase
|
|
|
993
1131
|
end
|
|
994
1132
|
|
|
995
1133
|
start, success = EventGenerator.new(true), EventGenerator.new
|
|
996
|
-
plan.
|
|
1134
|
+
plan.add(task = VirtualTask.create(start, success))
|
|
997
1135
|
task.start!
|
|
998
1136
|
plan.remove_object(success)
|
|
999
1137
|
assert(task.failed?)
|
|
1000
1138
|
|
|
1001
1139
|
start, success = EventGenerator.new(true), EventGenerator.new
|
|
1002
|
-
plan.
|
|
1003
|
-
plan.
|
|
1140
|
+
plan.add(success)
|
|
1141
|
+
plan.add(task = VirtualTask.create(start, success))
|
|
1004
1142
|
assert_nothing_raised { success.emit }
|
|
1005
1143
|
end
|
|
1006
1144
|
|
|
1007
1145
|
def test_dup
|
|
1008
|
-
plan.
|
|
1146
|
+
plan.add(task = Roby::Test::SimpleTask.new)
|
|
1009
1147
|
task.start!
|
|
1010
1148
|
|
|
1011
1149
|
new = task.dup
|
|
@@ -1024,5 +1162,20 @@ class TC_Task < Test::Unit::TestCase
|
|
|
1024
1162
|
new.event(:stop).call
|
|
1025
1163
|
assert(new.finished?, new.history)
|
|
1026
1164
|
end
|
|
1165
|
+
|
|
1166
|
+
def test_failed_to_start
|
|
1167
|
+
plan.add(task = Roby::Test::SimpleTask.new)
|
|
1168
|
+
begin
|
|
1169
|
+
task.event(:start).emit_failed
|
|
1170
|
+
rescue Exception
|
|
1171
|
+
end
|
|
1172
|
+
assert task.failed_to_start?
|
|
1173
|
+
assert task.failed?
|
|
1174
|
+
assert !task.pending?
|
|
1175
|
+
assert !task.running?
|
|
1176
|
+
assert [], plan.find_tasks.pending.to_a
|
|
1177
|
+
assert [], plan.find_tasks.running.to_a
|
|
1178
|
+
assert [task], plan.find_tasks.failed.to_a
|
|
1179
|
+
end
|
|
1027
1180
|
end
|
|
1028
1181
|
|