Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fix heisenbug and simplify tests #12

Merged
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 52 additions & 76 deletions test/task_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -179,115 +179,91 @@
end

describe "using 'init' connection" do
attr_reader :controller, :state
attr_reader :task

before do
@gpio_root = Pathname(Dir.mktmpdir)
make_fake_gpio(42, true)

@controller = syskit_deploy(
OroGen.linux_gpios.Task
.deployed_as("controller_task_under_test")
.with_arguments(name: "controller")
)
@controller.properties.sysfs_gpio_path = @gpio_root.to_s
@controller.properties.edge_triggered_output = true

@state = syskit_deploy(
@task = syskit_deploy(
OroGen.linux_gpios.Task
.deployed_as("state_task_under_test")
.with_arguments(name: "state")
.deployed_as("task_under_test")
.with_arguments(name: "task")
)
@state.properties.sysfs_gpio_path = @gpio_root.to_s
@state.properties.edge_triggered_output = true
@task.properties.sysfs_gpio_path = @gpio_root.to_s
@task.properties.edge_triggered_output = true
end

after do
@gpio_root&.rmtree
end

it "does not keep last written value when a new connection is established " \
"without 'init: true'" do
configure_and_start_tasks
connect_tasks
command = { states: [{ data: 0 }] }
"with 'init: false'" do
configure_and_start_task
command = { states: [{ data: 0 }], time: Time.now }

data_reader = syskit_create_reader task.r_states_port, init: false
expect_execution do
syskit_write controller.w_commands_port, command
break_and_reestablish_connection(init: false)
syskit_write task.w_commands_port, command
end.to do # rubocop:disable Style/MultilineBlockChain
have_no_new_sample(state.r_states_port)
have_one_new_sample(data_reader)
end
end
refute read_fake_gpio(42)

it "keeps last written value when a new connection is established " \
"with 'init: true'" do
configure_and_start_tasks
connect_tasks
command = { states: [{ data: 0 }] }
sample = expect_execution do
syskit_write controller.w_commands_port, command
break_and_reestablish_connection
expect_execution do
data_reader.disconnect
data_reader = syskit_create_reader task.r_states_port, init: false
end.to do # rubocop:disable Style/MultilineBlockChain
have_one_new_sample(state.r_states_port)
have_no_new_sample(data_reader, at_least_during: 1)
end

assert_equal 0, sample.states[0].data
end

it "keeps last written value even after a delay when reconnected " \
it "keeps last written value when a new connection is established " \
"with 'init: true'" do
configure_and_start_tasks
connect_tasks
command = { states: [{ data: 0 }] }
sample = expect_execution do
syskit_write controller.w_commands_port, command
break_and_reestablish_connection(delay: 1)
configure_and_start_task
command = { states: [{ data: 0 }], time: Time.now }

data_reader = syskit_create_reader task.r_states_port, init: true
samples = expect_execution do
syskit_write task.w_commands_port, command
end.to do # rubocop:disable Style/MultilineBlockChain
have_one_new_sample(state.r_states_port)
have_new_samples(data_reader, 2)
end
assert_equal 1, samples[0].states[0].data
assert_equal 0, samples[1].states[0].data

assert_equal 0, sample.states[0].data
data_reader.disconnect
data_reader = syskit_create_reader task.r_states_port, init: true
expect_execution.to { have_one_new_sample(data_reader) }
refute read_fake_gpio(42)
end

it "keeps the last value even after multiple disconnections and reconnections" do
configure_and_start_tasks
connect_tasks
command = { states: [{ data: 0 }] }
sample = expect_execution do
syskit_write controller.w_commands_port, command
3.times do
break_and_reestablish_connection
end
configure_and_start_task
command = { states: [{ data: 0 }], time: Time.now }

data_reader = syskit_create_reader task.r_states_port, init: true
samples = expect_execution do
syskit_write task.w_commands_port, command
end.to do # rubocop:disable Style/MultilineBlockChain
have_one_new_sample(state.r_states_port)
have_new_samples(data_reader, 2)
end
assert_equal 1, samples[0].states[0].data
assert_equal 0, samples[1].states[0].data

assert_equal 0, sample.states[0].data
end

def configure_and_start_tasks
make_fake_gpio(42, true)
controller.properties.w_configuration = { ids: [42] }
syskit_configure_and_start(controller)
state.properties.r_configuration = { ids: [42] }
syskit_configure_and_start(state)
end

def break_and_reestablish_connection(init: true, delay: 0)
controller.disconnect_ports(state, [%w[r_states w_commands]])
sleep(delay) if delay > 0
controller.connect_to state, init: init
3.times do
data_reader.disconnect
data_reader = syskit_create_reader task.r_states_port, init: true
end
expect_execution.to { have_one_new_sample(data_reader) }
refute read_fake_gpio(42)
end

def connect_tasks
cmp_m = Syskit::Composition.new_submodel do
add OroGen.linux_gpios.Task, as: "controller"
add OroGen.linux_gpios.Task, as: "state"

controller_child.connect_to state_child, init: true
end
syskit_stub_deploy_configure_and_start(
cmp_m.use("controller" => controller, "state" => state)
)
def configure_and_start_task
task.properties.w_configuration = { ids: [42] }
task.properties.r_configuration = { ids: [42] }
syskit_configure_and_start(task)
end
end

Expand Down