Paul Hinze eacb798a71
Fix action hooks running twice in destroy_on_error scenarios
The "destroy_on_error" functionality for `vagrant up` is implemented in
the `recover()` action chain, and works by firing off a destroy action
from inside that chain.

This is all well and good, but it copies its existing `env` which has
had `action_name` set for the up action. This was causing action_hooks
for up actions to attach to this destroy action stack.

Setting the action_name explicitly in the env before firing the runner
should correct the behavior. I'm not sure if raw_action_name is used
anywhere but I figured it was better to be consistent vs conservative in
what we change.
2022-04-25 12:26:56 -05:00

69 lines
1.9 KiB
Ruby

require_relative '../base'
describe VagrantPlugins::ProviderVirtualBox::Action::Import do
let(:app) { double("app") }
let(:state) { :test_state }
let(:machine) { double("machine", state: double("state", id: state)) }
let(:action_runner) { double("action_runner") }
let(:env) {
{
machine: machine,
action_runner: action_runner,
destroy_on_error: destroy_on_error,
}
}
subject { described_class.new(app, {}) }
describe "#recover" do
context "when destroy_on_error is false" do
let(:destroy_on_error) { false }
it "does nothing" do
expect(action_runner).to_not receive(:run)
subject.recover(env)
end
end
context "when destroy_on_error is true" do
let(:destroy_on_error) { true }
context "and machine is not_created" do
let(:state) { Vagrant::MachineState::NOT_CREATED_ID }
it "does nothing" do
expect(action_runner).to_not receive(:run)
subject.recover(env)
end
end
context "and machine is created" do
let(:state) { :running }
it "runs the destroy action with the proper environment" do
destroy_stack = double("destroy_stack")
allow(VagrantPlugins::ProviderVirtualBox::Action).to receive(:action_destroy) { destroy_stack }
expect(action_runner).to receive(:run).with(destroy_stack, hash_including(
config_validate: false,
force_confirm_destroy: true,
raw_action_name: :destroy,
action_name: :machine_action_destroy,
))
subject.recover(env)
end
context "but a VagrantError was raised" do
before {
env["vagrant.error"] = Vagrant::Errors::VagrantError.new
}
it "does nothing" do
expect(action_runner).to_not receive(:run)
subject.recover(env)
end
end
end
end
end
end