module Syskit::Test::NetworkManipulation

Network manipulation functionality (stubs, …) useful in tests

Public Instance Methods

__syskit_root_components() click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 862
def __syskit_root_components
    plan.find_tasks(Syskit::Component).not_abstract.roots(Roby::TaskStructure::Dependency)
end
normalize_instanciation_models(to_instanciate) click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 46
def normalize_instanciation_models(to_instanciate)
    # Instanciate all actions until we have a syskit instance
    # requirement pattern
    while true
        action_tasks, to_instanciate = to_instanciate.partition do |t|
            t.respond_to?(:planning_task) &&
                t.planning_task.pending? &&
                !t.planning_task.respond_to?(:requirements)
        end
        if action_tasks.empty?
            break
        else
            action_tasks.each do |t|
                tracker = t.as_service
                expect_execution { t.planning_task.start! }.
                    to { emit t.planning_task.start_event }
                to_instanciate << tracker.task
            end
        end
    end
    to_instanciate
end
setup() click to toggle source
Calls superclass method
# File lib/syskit/test/network_manipulation.rb, line 14
def setup
    @__test_created_deployments = Array.new
    @__test_overriden_configurations = Array.new
    super
end
syskit_configure(components = __syskit_root_components, recursive: true, except: Set.new) click to toggle source

Set this component instance up

# File lib/syskit/test/network_manipulation.rb, line 742
def syskit_configure(components = __syskit_root_components, recursive: true, except: Set.new)
    # We need all execution agents to be started to connect (and
    # therefore configur) the tasks
    syskit_start_all_execution_agents

    components = Array(components)
    return if components.empty?

    tasks = Set.new
    except  = except.to_set
    components.each do |component|
        next if tasks.include?(component)
        syskit_prepare_configure(component, tasks, recursive: recursive, except: except)
    end
    plan = components.first.plan
    guard = syskit_guard_against_start_and_configure(tasks)

    pending = tasks.dup.to_set
    while !pending.empty?
        execute do
            Syskit::Runtime::ConnectionManagement.update(plan)
        end
        current_state = pending.size
        pending.delete_if do |t|
            t.freeze_delayed_arguments
            should_setup = Orocos.allow_blocking_calls do
                !t.setup? && t.ready_for_setup?
            end
            if should_setup
                messages = capture_log(t, :info) do
                    t.setup.execute
                    execution_engine.join_all_waiting_work
                end
                if t.failed_to_start?
                    raise t.failure_reason
                else
                    assert t.setup?, "ran the setup for #{t}, but t.setup? does not return true"
                end
                true
            else
                t.setup?
            end
        end
        if current_state == pending.size
            missing_starts = pending.flat_map do |pending_task|
                pending_task.start_event.parent_objects(Roby::EventStructure::SyskitConfigurationPrecedence).
                    find_all { |e| e.symbol == :start && !e.emitted? }
            end
            missing_starts = missing_starts.map(&:task) - pending.to_a
            if missing_starts.empty?
                raise NoConfigureFixedPoint.new(pending), "cannot configure #{pending.map(&:to_s).join(", ")}"
            else
                syskit_start(missing_starts, recursive: false)
            end
        end
    end

ensure
    if guard
        expect_execution do
            plan.remove_free_event(guard)
        end.to_run
    end
end
syskit_configure_and_start(component = __syskit_root_components, recursive: true, except: Set.new) click to toggle source

Configure and start a task

Unlike {#syskit_stub_deploy_configure_and_start}, it does not stub the model, so model has to be deploy-able as-is.

@param (see #syskit_stub) @return [Syskit::Component]

# File lib/syskit/test/network_manipulation.rb, line 1050
def syskit_configure_and_start(component = __syskit_root_components, recursive: true, except: Set.new)
    syskit_configure(component, recursive: recursive, except: except)
    syskit_start(component, recursive: recursive, except: except)
    component
end
syskit_default_stub_name(model) click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 420
def syskit_default_stub_name(model)
    model_name =
        if model.respond_to?(:name) then model.name
        else model.to_str
        end
    "stub#{syskit_stub_model_id}"
end
syskit_deploy(*to_instanciate, add_mission: true, syskit_engine: nil, **resolve_options, &block) click to toggle source

Run Syskit's deployer (i.e. engine) on the current plan

# File lib/syskit/test/network_manipulation.rb, line 102
def syskit_deploy(*to_instanciate, add_mission: true, syskit_engine: nil, **resolve_options, &block)
    to_instanciate = to_instanciate.flatten # For backward-compatibility
    to_instanciate = normalize_instanciation_models(to_instanciate)

    emit_calls = Set.new
    placeholder_tasks = to_instanciate.map do |act|
        if act.respond_to?(:to_action)
            act = act.to_action
        end
        plan.add(task = act.as_plan)
        if add_mission
            plan.add_mission_task(task)
        end
        task
    end.compact
    root_tasks = placeholder_tasks.map(&:as_service)
    requirement_tasks = placeholder_tasks.map(&:planning_task)

    not_running = requirement_tasks.find_all { |t| !t.running? }
    expect_execution { not_running.each(&:start!) }.
        to { emit *not_running.map(&:start_event) }

    begin
        syskit_engine ||= Syskit::NetworkGeneration::Engine.new(plan)
        syskit_engine.resolve(**(Hash[on_error: :commit].merge(resolve_options)))
    rescue Exception => e
        expect_execution do
            requirement_tasks.each { |t| t.failed_event.emit(e) }
        end.to do
            requirement_tasks.each do |t|
                have_error_matching Roby::PlanningFailedError.match.
                    with_origin(t)
            end
        end
        raise
    end

    execute do
        placeholder_tasks.each do |task|
            plan.remove_task(task)
        end
        requirement_tasks.each { |t| t.success_event.emit if !t.finished? }
    end

    if Roby.app.public_logs?
        filename = name.gsub("/", "_")
        dataflow_base, hierarchy_base = filename + "-dataflow", filename + "-hierarchy"
        dataflow = File.join(Roby.app.log_dir, "#{dataflow_base}.svg")
        hierarchy = File.join(Roby.app.log_dir, "#{hierarchy_base}.svg")
        while File.file?(dataflow) || File.file?(hierarchy)
            i ||= 1
            dataflow = File.join(Roby.app.log_dir, "#{dataflow_base}.#{i}.svg")
            hierarchy = File.join(Roby.app.log_dir, "#{hierarchy_base}.#{i}.svg")
            i = i + 1
        end

        Graphviz.new(plan).to_file('dataflow', 'svg', dataflow)
        Graphviz.new(plan).to_file('hierarchy', 'svg', hierarchy)
    end

    root_tasks = root_tasks.map(&:task)
    if root_tasks.size == 1
        return root_tasks.first
    elsif root_tasks.size > 1
        return root_tasks
    end
end
syskit_deploy_and_configure(model = subject_syskit_model, recursive: true) click to toggle source

Deploy and configure a model

Unlike {#syskit_stub_deploy_and_configure}, it does not stub the model, so model has to be deploy-able as-is.

@param [#to_instance_requirements] model the requirements to

deploy and configure

@param [Boolean] recursive if true, children of the provided model

will be configured as well. Otherwise, only the toplevel task
will

@return [Syskit::Component]

# File lib/syskit/test/network_manipulation.rb, line 1025
def syskit_deploy_and_configure(model = subject_syskit_model, recursive: true)
    root = syskit_deploy(model)
    syskit_configure(root, recursive: recursive)
    root
end
syskit_deploy_configure_and_start(model = subject_syskit_model, recursive: true) click to toggle source

Deploy, configure and start a model

Unlike {#syskit_stub_deploy_configure_and_start}, it does not stub the model, so model has to be deploy-able as-is.

@param (see #syskit_stub) @return [Syskit::Component]

# File lib/syskit/test/network_manipulation.rb, line 1038
def syskit_deploy_configure_and_start(model = subject_syskit_model, recursive: true)
    root = syskit_deploy(model)
    syskit_configure_and_start(root, recursive: recursive)
end
syskit_export_to_svg(plan = self.plan, suffix: '', dataflow_options: Hash.new, hierarchy_options: Hash.new) click to toggle source

Export the dataflow and hierarchy to SVG

# File lib/syskit/test/network_manipulation.rb, line 1057
def syskit_export_to_svg(plan = self.plan, suffix: '', dataflow_options: Hash.new, hierarchy_options: Hash.new)
    basename = 'syskit-export-%i%s.%s.svg'

    counter = 0
    Dir.glob('syskit-export-*') do |file|
        if file =~ /syskit-export-(\d+)/
            counter = [counter, Integer($1)].max
        end
    end

    dataflow = basename % [counter + 1, suffix, 'dataflow']
    hierarchy = basename % [counter + 1, suffix, 'hierarchy']
    Syskit::Graphviz.new(plan).to_file('dataflow', 'svg', dataflow, **dataflow_options)
    Syskit::Graphviz.new(plan).to_file('hierarchy', 'svg', hierarchy, **hierarchy_options)
    puts "exported plan to #{dataflow} and #{hierarchy}"
    return dataflow, hierarchy
end
syskit_generate_network(*to_instanciate, add_missions: true) click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 69
def syskit_generate_network(*to_instanciate, add_missions: true)
    to_instanciate = normalize_instanciation_models(to_instanciate)
    placeholders = to_instanciate.map(&:as_plan)
    if add_missions
        execute do
            placeholders.each do |t|
                plan.add_mission_task(t)
                if t.planning_task.pending?
                    t.planning_task.start_event.call
                end
            end
        end
    end
    task_mapping = plan.in_transaction do |trsc|
        engine = NetworkGeneration::Engine.new(plan, work_plan: trsc)
        mapping = engine.compute_system_network(
            placeholders.map(&:planning_task),
            validate_generated_network: false)
        trsc.commit_transaction
        mapping
    end
    execute do
        placeholders.map do |task|
            replacement = task_mapping[task.planning_task]
            plan.replace_task(task, replacement)
            plan.remove_task(task)
            replacement.planning_task.success_event.emit
            replacement
        end
    end
end
syskit_guard_against_configure(tasks = Array.new, guard = Roby::EventGenerator.new) click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 839
def syskit_guard_against_configure(tasks = Array.new, guard = Roby::EventGenerator.new)
    tasks = Array(tasks)
    plan.add_permanent_event(guard)
    plan.find_tasks(Syskit::Component).each do |t|
        if !t.setup? && !tasks.include?(t)
            t.should_configure_after(guard)
        end
    end
    guard
end
syskit_guard_against_start_and_configure(tasks = Array.new, guard = Roby::EventGenerator.new) click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 850
def syskit_guard_against_start_and_configure(tasks = Array.new, guard = Roby::EventGenerator.new)
    plan.add_permanent_event(guard)
    syskit_guard_against_configure(tasks, guard)

    plan.find_tasks(Syskit::Component).each do |t|
        if t.pending? && !tasks.include?(t)
            t.should_start_after(guard)
        end
    end
    guard
end
syskit_prepare_configure(component, tasks, recursive: true, except: Set.new) click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 672
def syskit_prepare_configure(component, tasks, recursive: true, except: Set.new)
    component.freeze_delayed_arguments

    if component.respond_to?(:setup?)
        tasks << component
    end

    if recursive
        component.each_child do |child_task|
            if except.include?(child_task)
                next
            elsif child_task.respond_to?(:setup?)
                syskit_prepare_configure(child_task, tasks, recursive: true, except: except)
            end
        end
    end
end
syskit_prepare_start(component, tasks, recursive: true, except: Set.new) click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 823
def syskit_prepare_start(component, tasks, recursive: true, except: Set.new)
    if component.respond_to?(:setup?)
        tasks << component
    end

    if recursive
        component.each_child do |child_task|
            if except.include?(child_task)
                next
            elsif child_task.respond_to?(:setup?)
                syskit_prepare_start(child_task, tasks, recursive: true, except: except)
            end
        end
    end
end
syskit_protect_configuration_manager(model) click to toggle source

Ensure that any modification made to a model's configuration manager are undone at teardown

# File lib/syskit/test/network_manipulation.rb, line 32
def syskit_protect_configuration_manager(model)
    manager = model.configuration_manager
    model.configuration_manager = manager.dup
    @__test_overriden_configurations << [model, manager]
end
syskit_start(components = __syskit_root_components, recursive: true, except: Set.new) click to toggle source

Start this component

# File lib/syskit/test/network_manipulation.rb, line 867
def syskit_start(components = __syskit_root_components, recursive: true, except: Set.new)
    components = Array(components)
    return if components.empty?

    tasks = Set.new
    except = except.to_set
    components.each do |component|
        next if tasks.include?(component)
        syskit_prepare_start(component, tasks, recursive: recursive, except: except)
    end
    plan = components.first.plan
    guard = syskit_guard_against_start_and_configure(tasks)

    messages = Hash.new { |h, k| h[k] = Array.new }
    tasks.each do |t|
        flexmock(t).should_receive(:info).
            and_return { |msg| messages[t] << msg }
    end

    pending = tasks.dup
    while !pending.empty?
        current_state = pending.size

        to_start = Array.new
        pending.delete_if do |t|
            if t.running?
                true
            elsif t.executable?
                if !t.setup?
                    raise "#{t} is not set up, call #syskit_configure first"
                end
                to_start << t
                true
            end
        end

        if !to_start.empty?
            expect_execution { to_start.each(&:start!) }.
                to { emit(*to_start.map(&:start_event)) }
        end

        if current_state == pending.size
            raise NoStartFixedPoint.new(pending), "cannot start #{pending.map(&:to_s).join(", ")}"
        end
    end

    messages.each do |t, messages|
        assert messages.include?("starting #{t}")
    end

    if t = tasks.find { |t| !t.running? }
        raise RuntimeError, "failed to start #{t}: starting=#{t.starting?} running=#{t.running?} finished=#{t.finished?}"
    end

ensure
    if guard
        expect_execution do
            plan.remove_free_event(guard)
        end.to_run
    end
end
syskit_start_all_execution_agents() click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 620
def syskit_start_all_execution_agents
    guard = syskit_guard_against_configure

    agents = plan.each_task.map do |t|
        if t.execution_agent && !t.execution_agent.ready?
            t.execution_agent
        end
    end.compact

    not_running = agents.find_all { |t| !t.running? }
    not_ready   = agents.find_all { |t| !t.ready? }
    expect_execution { not_running.each(&:start!) }.
        to { emit(*not_ready.map(&:ready_event)) }

ensure
    if guard
        expect_execution do
            plan.remove_free_event(guard)
        end.to_run
    end
end
syskit_start_execution_agents(component, recursive: true) click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 642
def syskit_start_execution_agents(component, recursive: true)
    guard = syskit_guard_against_start_and_configure

    not_ready = []

    queue = [component]
    while !queue.empty?
        task = queue.shift
        if (agent = task.execution_agent) && !agent.ready?
            not_ready << agent
        end
        if recursive
            queue.concat task.each_child.map { |t, _| t }
        end
    end


    if !not_ready.empty?
        expect_execution do
            not_ready.each { |agent| agent.start! if !agent.running? }
        end.to { emit(*not_ready.map(&:ready_event)) }
    end
ensure
    if guard
        expect_execution do
            plan.remove_free_event(guard)
        end.to_run
    end
end
syskit_stub(*args, **options, &block) click to toggle source

@deprecated use #syskit_stub_requirements instead

# File lib/syskit/test/network_manipulation.rb, line 429
def syskit_stub(*args, **options, &block)
    Roby.warn_deprecated "syskit_stub has been renamed to syskit_stub_requirements to make the difference with syskit_stub_network more obvious"
    syskit_stub_requirements(*args, **options, &block)
end
syskit_stub_and_deploy( model = subject_syskit_model, recursive: true, remote_task: self.syskit_stub_resolves_remote_tasks?, &block) click to toggle source

Deploy the given composition, replacing every single data service and task context by a ruby task context, allowing to then test.

@param [Boolean] recursive (false) if true, the method will stub

the children of compositions that are used by the root
composition. Otherwise, you have to refer to them in the original
instance requirements

@example reuse toplevel tasks in children-of-children

class Cmp < Syskit::Composition
   add PoseSrv, :as => 'pose'
end
class RootCmp < Syskit::Composition
   add PoseSrv, :as => 'pose'
   add Cmp, :as => 'processor'
end
model = RootCmp.use(
   'processor' => Cmp.use('pose' => RootCmp.pose_child))
syskit_stub_deploy_and_start_composition(model)
# File lib/syskit/test/network_manipulation.rb, line 963
def syskit_stub_and_deploy(
    model = subject_syskit_model, recursive: true,
        remote_task: self.syskit_stub_resolves_remote_tasks?, &block)

    if model.respond_to?(:to_str)
        model = syskit_stub_task_context_model(model, &block)
    end
    tasks = syskit_generate_network(*model, &block)
    tasks = syskit_stub_network(tasks, remote_task: remote_task)
    if model.respond_to?(:to_ary)
        tasks
    else
        tasks.first
    end
end
syskit_stub_attached_device(bus, as: syskit_default_stub_name(bus)) click to toggle source

Create a stub device attached on the given bus

If the bus is a device object, the new device is attached to the same robot model. Otherwise, a new robot model is created for both the bus and the device

@param [Model<ComBus>,MasterDeviceInstance] bus either a bus model

or a bus object

@param [String] as a name for the new device @param [Model<TaskContext>] driver the driver that should be used

for the device. If not given, syskit will look for a suitable
driver or stub one
# File lib/syskit/test/network_manipulation.rb, line 387
def syskit_stub_attached_device(bus, as: syskit_default_stub_name(bus))
    if !bus.kind_of?(Robot::DeviceInstance)
        bus = syskit_stub_com_bus(bus, as: "#{as}_bus")
    end
    bus_m = bus.model
    dev_m = Syskit::Device.new_submodel(name: "#{bus}-stub") do
        provides bus_m::ClientSrv
    end
    dev = syskit_stub_device(dev_m, as: as)
    dev.attach_to(bus)
    dev
end
syskit_stub_com_bus(model, as: syskit_default_stub_name(model), driver: nil, robot: nil, **device_options) click to toggle source

Create a stub combus of the given model

It is created on a new robot instance so that to avoid clashes

@param [Model<ComBus>] model the device model @param [String] as the combus name @param [Model<TaskContext>] driver the driver that should be used.

If not given, a new driver is stubbed
# File lib/syskit/test/network_manipulation.rb, line 369
def syskit_stub_com_bus(model, as: syskit_default_stub_name(model), driver: nil, robot: nil, **device_options)
    robot ||= Syskit::Robot::RobotDefinition.new
    driver ||= syskit_stub_driver_model_for(model)
    robot.com_bus(model, as: as, using: driver, **device_options)
end
syskit_stub_component(model, devices: true) click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 244
def syskit_stub_component(model, devices: true)
    if devices
        syskit_stub_required_devices(model)
    else
        model
    end
end
syskit_stub_composition_requirements(model, recursive: true, as: syskit_default_stub_name(model), devices: true) click to toggle source

@api private

Helper for {#syskit_stub_model}

@param [InstanceRequirements] model

# File lib/syskit/test/network_manipulation.rb, line 310
def syskit_stub_composition_requirements(model, recursive: true, as: syskit_default_stub_name(model), devices: true)
    model = syskit_stub_component(model, devices: devices)

    if recursive
        model.each_child do |child_name, selected_child|
            if selected_task = selected_child.component
                deployed_child = selected_task
            else
                child_model = selected_child.selected
                selected_service = child_model.service
                child_model = child_model.to_component_model
                if child_model.composition_model?
                    deployed_child = syskit_stub_composition_requirements(
                        child_model, recursive: true, as: "#{as}_#{child_name}", devices: devices)
                else
                    deployed_child = syskit_stub_task_context_requirements(
                        child_model, as: "#{as}_#{child_name}", devices: devices)
                end
                if selected_service
                    deployed_child.select_service(selected_service)
                end
            end
            model.use(child_name => deployed_child)
        end
    end

    model
end
syskit_stub_conf(task_m, *conf, data: Hash.new) click to toggle source

Create empty configuration sections for the given task model

# File lib/syskit/test/network_manipulation.rb, line 297
def syskit_stub_conf(task_m, *conf, data: Hash.new)
    concrete_task_m = task_m.concrete_model
    syskit_protect_configuration_manager(concrete_task_m)
    conf.each do |conf_name|
        concrete_task_m.configuration_manager.add(conf_name, data, merge: true)
    end
end
syskit_stub_configured_deployment( task_model = nil, name = nil, remote_task: self.syskit_stub_resolves_remote_tasks?, &block) click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 180
def syskit_stub_configured_deployment(
        task_model = nil, name = nil,
        remote_task: self.syskit_stub_resolves_remote_tasks?, &block)

    if task_model
        task_model = task_model.to_component_model
    end

    process_server = Syskit.conf.process_server_for('stubs')

    task_context_class =
        if remote_task
            Orocos::RubyTasks::RemoteTaskContext
        else
            process_server.task_context_class
        end

    name ||= syskit_default_stub_name(task_model)
    deployment_model = Deployment.new_submodel(name: name) do
        if task_model
            task(name, task_model.orogen_model)
        end
        if block_given?
            instance_eval(&block)
        end
    end

    process_server.register_deployment_model(deployment_model.orogen_model)
    configured_deployment = Models::ConfiguredDeployment.
        new('stubs', deployment_model, Hash[name => name],
            name, Hash[task_context_class: task_context_class])
    Syskit.conf.register_configured_deployment(configured_deployment)
    configured_deployment
end
syskit_stub_deploy_and_configure( model = subject_syskit_model, recursive: true, as: syskit_default_stub_name(model), remote_task: self.syskit_stub_resolves_remote_tasks?, &block) click to toggle source

Stub a task, deploy it and configure it

This starts the underlying (stubbed) deployment process

@param (see #syskit_stub) @return [Syskit::Component] @see #syskit_stub

# File lib/syskit/test/network_manipulation.rb, line 986
def syskit_stub_deploy_and_configure(
        model = subject_syskit_model, recursive: true,
        as: syskit_default_stub_name(model),
        remote_task: self.syskit_stub_resolves_remote_tasks?, &block)

    root = syskit_stub_and_deploy(model, recursive: recursive, remote_task: remote_task, &block)
    syskit_configure(root, recursive: recursive)
    root
end
syskit_stub_deploy_configure_and_start( model = subject_syskit_model, recursive: true, as: syskit_default_stub_name(model), remote_task: self.syskit_stub_resolves_remote_tasks?, &block) click to toggle source

Stub a task, deploy it, configure it and start the task and the underlying stub deployment

This starts the underlying (stubbed) deployment process

@param (see #syskit_stub) @return [Syskit::Component] @see #syskit_stub

# File lib/syskit/test/network_manipulation.rb, line 1004
def syskit_stub_deploy_configure_and_start(
        model = subject_syskit_model, recursive: true,
        as: syskit_default_stub_name(model),
        remote_task: self.syskit_stub_resolves_remote_tasks?, &block)

    root = syskit_stub_and_deploy(model, recursive: recursive, remote_task: remote_task, &block)
    syskit_configure_and_start(root, recursive: recursive)
    root
end
syskit_stub_deployment( name = "deployment", deployment_model = nil, remote_task: self.syskit_stub_resolves_remote_tasks?, &block) click to toggle source

Create a new stub deployment instance, optionally stubbing the model as well

# File lib/syskit/test/network_manipulation.rb, line 236
def syskit_stub_deployment(
        name = "deployment", deployment_model = nil,
        remote_task: self.syskit_stub_resolves_remote_tasks?, &block)
    deployment_model ||= syskit_stub_deployment_model(nil, name, &block)
    plan.add_permanent_task(task = deployment_model.new(process_name: name, on: 'stubs'))
    task
end
syskit_stub_deployment_model( task_model = nil, name = nil, remote_task: self.syskit_stub_resolves_remote_tasks?, &block) click to toggle source

Create a new stub deployment model that can deploy a given task context model

@param [Model<Syskit::TaskContext>,nil] task_model if given, a

task model that should be deployed by this deployment model

@param [String] name the name of the deployed task as well as

of the deployment. If not given, and if task_model is provided,
task_model.name is used as default

@yield the deployment model context, i.e. a context in which the

same declarations than in oroGen's #deployment statement are
available

@return [Models::ConfiguredDeployment] the configured deployment

# File lib/syskit/test/network_manipulation.rb, line 227
def syskit_stub_deployment_model(
        task_model = nil, name = nil,
        remote_task: self.syskit_stub_resolves_remote_tasks?, &block)
    configured_deployment = syskit_stub_configured_deployment(task_model, name, remote_task: remote_task, &block)
    configured_deployment.model
end
syskit_stub_device(model, as: syskit_default_stub_name(model), driver: nil, robot: nil, **device_options) click to toggle source

Create a stub device of the given model

It is created on a new robot instance so that to avoid clashes

@param [Model<Device>] model the device model @param [String] as the device name @param [Model<TaskContext>] driver the driver that should be used.

If not given, a new driver is stubbed
# File lib/syskit/test/network_manipulation.rb, line 355
def syskit_stub_device(model, as: syskit_default_stub_name(model), driver: nil, robot: nil, **device_options)
    robot ||= Syskit::Robot::RobotDefinition.new
    driver ||= syskit_stub_driver_model_for(model)
    robot.device(model, as: as, using: driver, **device_options)
end
syskit_stub_driver_model_for(model) click to toggle source

@api private

Finds a driver model for a given device model, or create one if there is none

# File lib/syskit/test/network_manipulation.rb, line 343
def syskit_stub_driver_model_for(model)
    syskit_stub_requirements(model.find_all_drivers.first || model, devices: false)
end
syskit_stub_model_id() click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 413
def syskit_stub_model_id
    id = (@@syskit_stub_model_id += 1)
    if id != 0
        id
    end
end
syskit_stub_network(root_tasks, remote_task: self.syskit_stub_resolves_remote_tasks?) click to toggle source

Stub an already existing network

# File lib/syskit/test/network_manipulation.rb, line 450
def syskit_stub_network(root_tasks, remote_task: self.syskit_stub_resolves_remote_tasks?)
    tasks = Set.new
    dependency_graph = plan.task_relation_graph_for(Roby::TaskStructure::Dependency)
    root_tasks = Array(root_tasks).map do |t|
        tasks << t
        dependency_graph.depth_first_visit(t) do |child_t|
            tasks << child_t
        end

        if plan.mission_task?(t)
            [t, :mission_task]
        elsif plan.permanent_task?(t)
            [t, :permanent_task]
        else
            [t]
        end
    end

    mapped_tasks = Hash.new
    # NOTE: must NOT call #apply_merge_group with merge_mappings
    # directly. #apply_merge_group "replaces" the subnet represented
    # by the keys with the subnet represented by the values. In
    # other words, the connections present between two keys would
    # NOT be copied between the corresponding values
    plan.in_transaction do |trsc|
        trsc_tasks = tasks.map { |t| trsc[t] }

        merge_solver = NetworkGeneration::MergeSolver.new(trsc)
        tasks.each do |plan_t|
            merge_solver.register_replacement(plan_t, trsc[plan_t])
        end
        merge_mappings = Hash.new
        stubbed_tags = Hash.new
        trsc_tasks.each do |task|
            task.model.each_master_driver_service do |srv|
                task.arguments[:"#{srv.name}_dev"] ||=
                    syskit_stub_device(srv.model, driver: srv)
            end
        end

        trsc_tasks.find_all(&:abstract?).each do |abstract_task|
            # The task is required as being abstract (usually a
            # if_already_present tag). Do not stub that
            next if abstract_task.requirements.abstract?

            concrete_task =
                if abstract_task.kind_of?(Syskit::Actions::Profile::Tag)
                    tag_id = [abstract_task.model.tag_name, abstract_task.model.profile.name]
                    stubbed_tags[tag_id] ||= syskit_stub_network_abstract_component(abstract_task)
                else
                    syskit_stub_network_abstract_component(abstract_task)
                end

            if abstract_task.placeholder_task? && !abstract_task.kind_of?(Syskit::TaskContext) # 'pure' proxied data services
                trsc.replace_task(abstract_task, concrete_task)
                merge_solver.register_replacement(abstract_task, concrete_task)
            else
                merge_mappings[abstract_task] = concrete_task
            end
        end
        merge_mappings.each do |original, replacement|
            merge_solver.apply_merge_group(original => replacement)
        end
        merge_solver.merge_identical_tasks

        merge_mappings = Hash.new
        trsc_tasks.each do |original_task|
            concrete_task = merge_solver.replacement_for(original_task)
            if concrete_task.kind_of?(TaskContext) && !concrete_task.execution_agent
                merge_mappings[concrete_task] = syskit_stub_network_deployment(concrete_task, remote_task: remote_task)
            end
        end
        merge_mappings.each do |original, replacement|
            merge_solver.apply_merge_group(original => replacement)
        end

        mapped_tasks = Hash.new
        tasks.each do |plan_t|
            replacement_t = merge_solver.replacement_for(plan_t)
            mapped_tasks[plan_t] = trsc.may_unwrap(replacement_t)
        end

        root_tasks.each do |root_t, status|
            replacement_t = mapped_tasks[root_t]
            if replacement_t != root_t
                unless replacement_t.planning_task
                    replacement_t.planned_by trsc[root_t.planning_task]
                end
                trsc.send("add_#{status}", replacement_t)
            end
        end

        NetworkGeneration::SystemNetworkGenerator.remove_abstract_composition_optional_children(trsc)
        trsc.static_garbage_collect
        NetworkGeneration::SystemNetworkGenerator.verify_task_allocation(trsc)
        trsc.commit_transaction
    end


    execute do
        mapped_tasks.each do |old, new|
            if old != new
                plan.remove_task(old)
            end
        end
    end
    root_tasks.map { |t, _| mapped_tasks[t] }
end
syskit_stub_network_abstract_component(task) click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 583
def syskit_stub_network_abstract_component(task)
    task_m = task.concrete_model
    if task_m.respond_to?(:proxied_data_services)
        task_m = syskit_stub_proxied_data_service(task_m)
    elsif task_m.abstract?
        task_m = task_m.new_submodel(name: "#{task_m.name}-stub")
    end

    arguments = task.arguments.dup
    task_m.each_master_driver_service do |srv|
        arguments[:"#{srv.name}_dev"] ||=
            syskit_stub_device(srv.model, driver: task_m)
    end
    task_m.new(**arguments)
end
syskit_stub_network_deployment( task, as: task.orocos_name || syskit_default_stub_name(task.model), remote_task: self.syskit_stub_resolves_remote_tasks?) click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 599
def syskit_stub_network_deployment(
        task, as: task.orocos_name || syskit_default_stub_name(task.model),
        remote_task: self.syskit_stub_resolves_remote_tasks?)

    task_m = task.concrete_model
    deployment_model = syskit_stub_configured_deployment(
        task_m, as, remote_task: remote_task)
    syskit_stub_conf(task_m, *task.arguments[:conf])
    task.plan.add(deployer = deployment_model.new)
    deployed_task = deployer.instanciate_all_tasks.first

    new_args = Hash.new
    task.arguments.find_all do |key, arg|
        if deployed_task.arguments.writable?(key, arg)
            new_args[key] = arg
        end
    end
    deployed_task.assign_arguments(**new_args)
    deployed_task
end
syskit_stub_proxied_data_service(model) click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 559
def syskit_stub_proxied_data_service(model)
    superclass = if model.superclass <= Syskit::TaskContext
                     model.superclass
                 else Syskit::TaskContext
                 end

    services = model.proxied_data_services
    task_m = superclass.new_submodel(name: "#{model.to_s}-stub")
    services.each_with_index do |srv, idx|
        srv.each_input_port do |p|
            task_m.orogen_model.input_port p.name, Orocos.find_orocos_type_name_by_type(p.type)
        end
        srv.each_output_port do |p|
            task_m.orogen_model.output_port p.name, Orocos.find_orocos_type_name_by_type(p.type)
        end
        if srv <= Syskit::Device
            task_m.driver_for srv, as: "dev#{idx}"
        else
            task_m.provides srv, as: "srv#{idx}"
        end
    end
    task_m
end
syskit_stub_required_devices(model) click to toggle source

Stubs the devices required by the given model

# File lib/syskit/test/network_manipulation.rb, line 401
def syskit_stub_required_devices(model)
    model = model.to_instance_requirements
    model.model.to_component_model.each_master_driver_service do |srv|
        if !model.arguments[:"#{srv.name}_dev"]
            model.with_arguments(:"#{srv.name}_dev" => syskit_stub_device(srv.model, driver: model.model))
        end
    end
    model
end
syskit_stub_requirements(model = subject_syskit_model, recursive: true, as: syskit_default_stub_name(model), devices: true, &block) click to toggle source

Create an InstanceRequirement instance that would allow to deploy the given model

# File lib/syskit/test/network_manipulation.rb, line 436
def syskit_stub_requirements(model = subject_syskit_model, recursive: true, as: syskit_default_stub_name(model), devices: true, &block)
    if model.respond_to?(:to_str)
        model = syskit_stub_task_context_model(model, &block)
    end
    model = model.to_instance_requirements.dup

    if model.composition_model?
        syskit_stub_composition_requirements(model, recursive: recursive, as: as, devices: devices)
    else
        syskit_stub_task_context_requirements(model, as: as, devices: devices)
    end
end
syskit_stub_task_context_model(name, &block) click to toggle source

Create a new task context model with the given name

@yield a block in which the task context interface can be

defined
# File lib/syskit/test/network_manipulation.rb, line 174
def syskit_stub_task_context_model(name, &block)
    model = TaskContext.new_submodel(name: name, &block)
    model.orogen_model.extended_state_support
    model
end
syskit_stub_task_context_requirements(model, as: syskit_default_stub_name(model), devices: true) click to toggle source

@api private

Helper for {#syskit_stub_and_deploy}

@param [InstanceRequirements] task_m the task context model @param [String] as the deployment name

# File lib/syskit/test/network_manipulation.rb, line 258
def syskit_stub_task_context_requirements(model, as: syskit_default_stub_name(model), devices: true)
    model = model.to_instance_requirements

    task_m = model.model.to_component_model.concrete_model
    if task_m.respond_to?(:proxied_data_services)
        superclass = if task_m.superclass <= Syskit::TaskContext
                         task_m.superclass
                     else Syskit::TaskContext
                     end

        services = task_m.proxied_data_services
        task_m = superclass.new_submodel(name: "#{task_m.to_s}-stub")
        services.each_with_index do |srv, idx|
            srv.each_input_port do |p|
                task_m.orogen_model.input_port p.name, Orocos.find_orocos_type_name_by_type(p.type)
            end
            srv.each_output_port do |p|
                task_m.orogen_model.output_port p.name, Orocos.find_orocos_type_name_by_type(p.type)
            end
            if srv <= Syskit::Device
                task_m.driver_for srv, as: "dev#{idx}"
            else
                task_m.provides srv, as: "srv#{idx}"
            end
        end
    elsif task_m.abstract?
        task_m = task_m.new_submodel(name: "#{task_m.name}-stub")
    end
    model.add_models([task_m])
    model = syskit_stub_component(model, devices: devices)

    syskit_stub_conf(task_m, *model.arguments[:conf])

    syskit_stub_deployment_model(task_m, as)
    model.deployment_hints.clear
    model.prefer_deployed_tasks(as)
end
syskit_wait_ready(writer_or_reader, component: writer_or_reader.port.to_actual_port.component) click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 929
def syskit_wait_ready(writer_or_reader, component: writer_or_reader.port.to_actual_port.component)
    return if writer_or_reader.ready?

    if !component.setup?
        syskit_configure(component)
    end
    if !component.running?
        syskit_start(component)
    end

    expect_execution.to do
        achieve { writer_or_reader.ready? }
    end
end
teardown() click to toggle source
Calls superclass method
# File lib/syskit/test/network_manipulation.rb, line 20
def teardown
    super
    @__test_overriden_configurations.each do |model, manager|
        model.configuration_manager = manager
    end
    @__test_created_deployments.each do |d|
        Syskit.conf.deregister_configured_deployment(d)
    end
end
use_deployment(*args) click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 38
def use_deployment(*args)
    @__test_created_deployments.concat(Syskit.conf.use_deployment(*args).to_a)
end
use_ruby_tasks(*args) click to toggle source
# File lib/syskit/test/network_manipulation.rb, line 42
def use_ruby_tasks(*args)
    @__test_created_deployments.concat(Syskit.conf.use_ruby_tasks(*args).to_a)
end