vaguerent/test/unit/vagrant/action/builtin/cloud_init_setup_test.rb

156 lines
6.3 KiB
Ruby

# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: BUSL-1.1
require File.expand_path("../../../../base", __FILE__)
require "vagrant/util/mime"
describe Vagrant::Action::Builtin::CloudInitSetup do
let(:app) { lambda { |env| } }
let(:vm) { double("vm", disk: disk, disks: disks) }
let(:disk) { double("disk") }
let(:disks) { double("disk") }
let(:config) { double("config", vm: vm) }
let(:provider) { double("provider") }
let(:machine) { double("machine", config: config, provider: provider, name: "machine",
provider_name: "provider", data_dir: Pathname.new("/fake/dir"),
ui: ui, env: machine_env, id: "123-456-789") }
let(:host) { double("host") }
let(:machine_env) { double("machine_env", root_path: "root", host: host) }
let(:env) { { ui: ui, machine: machine, env: machine_env} }
let(:ui) { Vagrant::UI::Silent.new }
let(:cfg) { double("cfg", type: :user_data, content_type: "text/cloud-config",
content_disposition_filename: nil, path: "my/path",
inline: nil) }
let(:cfg_inline) { double("cfg", type: :user_data, content_type: "text/cloud-config",
content_disposition_filename: nil, inline: "data: true",
path: nil) }
let(:cfg_with_content_disposition_filename_inline) {
double("cfg", type: :user_data, content_type: "text/x-shellscript",
content_disposition_filename: "test.ps1",
inline: "#ps1_sysnative\n", path: nil) }
let(:cloud_init_configs) { [cfg, cfg_inline] }
let(:text_cfgs) { [Vagrant::Util::Mime::Entity.new("data: true", "text/cloud-config"),
Vagrant::Util::Mime::Entity.new("data: false", "text/cloud-config") ] }
let(:meta_data) { { "instance-id" => "i-123456789" } }
let(:subject) { described_class.new(app, env) }
describe "#call" do
it "calls setup_user_data if cloud_init config present" do
allow(vm).to receive(:cloud_init_configs).and_return(cloud_init_configs)
expect(app).to receive(:call).with(env).ordered
expect(subject).to receive(:setup_user_data).and_return(true)
expect(subject).to receive(:write_cfg_iso).and_return(true)
subject.call(env)
end
it "continues on if no cloud_init config present" do
allow(vm).to receive(:cloud_init_configs).and_return([])
expect(app).to receive(:call).with(env).ordered
expect(subject).not_to receive(:setup_user_data)
expect(subject).not_to receive(:write_cfg_iso)
expect(subject).not_to receive(:attack_disk_config)
subject.call(env)
end
end
describe "#setup_user_data" do
it "builds a MIME message and prepares a disc to be attached" do
expect(subject).to receive(:read_text_cfg).twice
expect(subject).to receive(:generate_cfg_msg)
subject.setup_user_data(machine, env, cloud_init_configs)
end
end
describe "#read_text_cfg" do
let(:cfg_text) { "config: true" }
it "takes a text cfg path and saves it as a MIME text message" do
mime_text_part = double("mime_text_part")
expect(mime_text_part).not_to receive(:disposition=)
allow(File).to receive(:read).and_return(cfg_text)
expect(Vagrant::Util::Mime::Entity).to receive(:new).with(cfg_text, "text/cloud-config").and_return(mime_text_part)
subject.read_text_cfg(machine, cfg)
end
it "takes a text cfg inline string and saves it as a MIME text message" do
mime_text_part = double("mime_text_part")
expect(mime_text_part).not_to receive(:disposition=)
expect(Vagrant::Util::Mime::Entity).to receive(:new).with("data: true", "text/cloud-config").and_return(mime_text_part)
subject.read_text_cfg(machine, cfg_inline)
end
it "takes a text cfg inline string with content_disposition_filename and saves it as a MIME text message" do
mime_text_part = double("mime_text_part")
expect(mime_text_part).to receive(:disposition=).with("attachment; filename=\"test.ps1\"")
expect(Vagrant::Util::Mime::Entity).to receive(:new).with("#ps1_sysnative\n", "text/x-shellscript").and_return(mime_text_part)
subject.read_text_cfg(machine, cfg_with_content_disposition_filename_inline)
end
end
describe "#generate_cfg_msg" do
it "creates a miltipart mixed message of combined configs" do
message = subject.generate_cfg_msg(machine, text_cfgs)
expect(message).to be_a(Vagrant::Util::Mime::Multipart)
end
it "sets a MIME-Version header" do
message = subject.generate_cfg_msg(machine, text_cfgs)
expect(message.headers["MIME-Version"]).to eq("1.0")
end
end
describe "#write_cfg_iso" do
let(:iso_path) { Pathname.new("fake/iso/path") }
let(:source_dir) { Pathname.new("fake/source/path") }
let(:meta_data_file) { double("meta_data_file") }
before do
allow(meta_data_file).to receive(:write).and_return(true)
end
it "raises an error if the host capability is not supported" do
message = subject.generate_cfg_msg(machine, text_cfgs)
allow(host).to receive(:capability?).with(:create_iso).and_return(false)
expect{subject.write_cfg_iso(machine, env, message, {})}.to raise_error(Vagrant::Errors::CreateIsoHostCapNotFound)
end
it "creates a temp dir with the cloud_init config and generates an iso" do
message = subject.generate_cfg_msg(machine, text_cfgs)
allow(host).to receive(:capability?).with(:create_iso).and_return(true)
allow(Dir).to receive(:mktmpdir).and_return(source_dir)
expect(File).to receive(:open).with("#{source_dir}/user-data", 'w').and_return(true)
expect(File).to receive(:open).with("#{source_dir}/meta-data", 'w').and_yield(meta_data_file)
expect(FileUtils).to receive(:remove_entry).with(source_dir).and_return(true)
allow(host).to receive(:capability).with(:create_iso, source_dir, volume_id: "cidata").and_return(iso_path)
expect(vm.disks).to receive(:each)
expect(meta_data).to receive(:to_yaml)
subject.write_cfg_iso(machine, env, message, meta_data)
end
end
describe "#attach_disk_config" do
let(:iso_path) { Pathname.new("fake/iso/path") }
it "creates a new disk config based on the iso_path" do
expect(vm.disks).to receive(:each)
subject.attach_disk_config(machine, env, iso_path)
end
end
end