110 lines
2.6 KiB
Ruby
110 lines
2.6 KiB
Ruby
# Copyright (c) HashiCorp, Inc.
|
|
# SPDX-License-Identifier: BUSL-1.1
|
|
|
|
require File.expand_path("../../../base", __FILE__)
|
|
|
|
describe Vagrant::Action::Warden do
|
|
class ActionOne
|
|
def initialize(app, env)
|
|
@app = app
|
|
end
|
|
|
|
def call(env)
|
|
env[:data] << 1 if env[:data]
|
|
@app.call(env)
|
|
end
|
|
|
|
def recover(env)
|
|
env[:recover] << 1
|
|
end
|
|
end
|
|
|
|
class ActionTwo
|
|
def initialize(app, env)
|
|
@app = app
|
|
end
|
|
|
|
def call(env)
|
|
env[:data] << 2 if env[:data]
|
|
@app.call(env)
|
|
end
|
|
|
|
def recover(env)
|
|
env[:recover] << 2
|
|
end
|
|
end
|
|
|
|
class ExitAction
|
|
def initialize(app, env)
|
|
@app = app
|
|
end
|
|
|
|
def call(env)
|
|
@app.call(env)
|
|
end
|
|
|
|
def recover(env)
|
|
env[:recover] = true
|
|
end
|
|
end
|
|
|
|
let(:data) { { data: [] } }
|
|
let(:instance) { described_class.new }
|
|
|
|
# This returns a proc that can be used with the builder
|
|
# that simply appends data to an array in the env.
|
|
def appender_proc(data)
|
|
Proc.new { |env| env[:data] << data }
|
|
end
|
|
|
|
it "calls the actions like normal" do
|
|
instance = described_class.new([appender_proc(1), appender_proc(2)], data)
|
|
instance.call(data)
|
|
|
|
expect(data[:data]).to eq([1, 2])
|
|
end
|
|
|
|
it "starts a recovery sequence when an exception is raised" do
|
|
error_proc = Proc.new { raise "ERROR!" }
|
|
|
|
data = { recover: [] }
|
|
instance = described_class.new([ActionOne, ActionTwo, error_proc], data)
|
|
|
|
# The error should be raised back up
|
|
expect { instance.call(data) }.
|
|
to raise_error(RuntimeError)
|
|
|
|
# Verify the recovery process goes in reverse order
|
|
expect(data[:recover]).to eq([2, 1])
|
|
|
|
# Verify that the error is available in the data
|
|
expect(data["vagrant.error"]).to be_kind_of(RuntimeError)
|
|
end
|
|
|
|
it "does not do a recovery sequence if SystemExit is raised" do
|
|
# Make a proc that just calls "abort" which raises a
|
|
# SystemExit exception.
|
|
error_proc = Proc.new { abort }
|
|
|
|
instance = described_class.new([ExitAction, error_proc], data)
|
|
|
|
# The SystemExit should come through
|
|
expect { instance.call(data) }.to raise_error(SystemExit)
|
|
|
|
# The recover should not have been called
|
|
expect(data.key?(:recover)).not_to be
|
|
end
|
|
|
|
it "does not do a recovery sequence if NoMemoryError is raised" do
|
|
error_proc = Proc.new { raise NoMemoryError }
|
|
|
|
instance = described_class.new([ExitAction, error_proc], data)
|
|
|
|
# The SystemExit should come through
|
|
expect { instance.call(data) }.to raise_error(NoMemoryError)
|
|
|
|
# The recover should not have been called
|
|
expect(data.key?(:recover)).not_to be
|
|
end
|
|
end
|