vaguerent/test/unit/vagrant/batch_action_test.rb
Chris Roberts 88c675694a Update trigger abort behavior when running parallel actions
When the provider supports parallel actions and actions are being
run in parallel, do not immediately kill the process on failure.
Instead terminate the action thread and log the exit code. Once
all running actions have completed, the process will then exit
with the stored exit code.
2019-06-04 16:40:59 -07:00

87 lines
2.4 KiB
Ruby

require 'thread'
require 'timeout'
require File.expand_path("../../base", __FILE__)
describe Vagrant::BatchAction do
let(:called_actions) { [] }
let!(:lock) { Mutex.new }
let(:provider_name) { "test" }
let(:provider_options) { {} }
def new_machine(options)
double("machine").tap do |m|
allow(m).to receive(:provider_name).and_return(provider_name)
allow(m).to receive(:provider_options).and_return(options)
allow(m).to receive(:action) do |action, opts|
lock.synchronize do
called_actions << [m, action, opts]
end
end
end
end
describe "#run" do
let(:machine) { new_machine(provider_options) }
let(:machine2) { new_machine(provider_options) }
it "should run the actions on the machines in order" do
subject.action(machine, "up")
subject.action(machine2, "destroy")
subject.run
expect(called_actions.include?([machine, "up", nil])).to be
expect(called_actions.include?([machine2, "destroy", nil])).to be
end
it "should run the arbitrary methods in order" do
called = []
subject.custom(machine) { |m| called << m }
subject.custom(machine2) { |m| called << m }
subject.run
expect(called[0]).to equal(machine)
expect(called[1]).to equal(machine2)
end
it "should handle forks gracefully", :skip_windows do
# Doesn't need to be tested on Windows since Windows doesn't
# support fork(1)
allow(machine).to receive(:action) do |action, opts|
pid = fork
if !pid
# Child process
exit
end
# Parent process, wait for the child to exit
Timeout.timeout(1) do
Process.waitpid(pid)
end
end
subject.action(machine, "up")
subject.run
end
context "with provider supporting parallel actions" do
let(:provider_options) { {parallel: true} }
it "should flag threads as being parallel actions" do
parallel = nil
subject.custom(machine) { |m| parallel = Thread.current[:batch_parallel_action] }
subject.custom(machine) { |*_| }
subject.run
expect(parallel).to eq(true)
end
it "should exit the process if exit_code has been set" do
subject.custom(machine) { |m| Thread.current[:exit_code] = 1}
subject.custom(machine) { |*_| }
expect(Process).to receive(:exit!).with(1)
subject.run
end
end
end
end