From e32783312ba801ce72ea23b2f7e1019c14d71765 Mon Sep 17 00:00:00 2001 From: Gilles Cornu Date: Sat, 22 Mar 2014 17:18:00 +0100 Subject: [PATCH] provisioners/ansible: improve unit tests (wip) - Don't mock the config object, but use a true instance - When possible, take advantage of Rpsec before/after hooks to reduce code repetitions - Add an example ("with inventory_path option") - Use a global variable to store the path of the generated inventory - Miscellaneous changes in existing examples (style, fixes) --- .../provisioners/ansible/provisioner_test.rb | 95 +++++++++---------- 1 file changed, 47 insertions(+), 48 deletions(-) diff --git a/test/unit/plugins/provisioners/ansible/provisioner_test.rb b/test/unit/plugins/provisioners/ansible/provisioner_test.rb index 6ec3eba31..746efe709 100644 --- a/test/unit/plugins/provisioners/ansible/provisioner_test.rb +++ b/test/unit/plugins/provisioners/ansible/provisioner_test.rb @@ -1,5 +1,6 @@ require_relative "../../../base" +require Vagrant.source_root.join("plugins/provisioners/ansible/config") require Vagrant.source_root.join("plugins/provisioners/ansible/provisioner") describe VagrantPlugins::Ansible::Provisioner do @@ -15,7 +16,8 @@ describe VagrantPlugins::Ansible::Provisioner do end let(:machine) { iso_env.machine(iso_env.machine_names[0], :dummy) } - let(:config) { double("config") } + let(:config) { VagrantPlugins::Ansible::Config.new } + let(:file_that_exists) { File.expand_path(__FILE__) } let(:ssh_info) {{ private_key_path: ['/path/to/my/key'], @@ -25,41 +27,24 @@ describe VagrantPlugins::Ansible::Provisioner do before do machine.stub(ssh_info: ssh_info) - config.stub(playbook: 'playbook.yml') - config.stub(extra_vars: nil) - config.stub(inventory_path: nil) - config.stub(ask_sudo_pass: nil) - config.stub(limit: nil) - config.stub(sudo: nil) - config.stub(sudo_user: nil) - config.stub(verbose: nil) - config.stub(tags: nil) - config.stub(skip_tags: nil) - config.stub(start_at_task: nil) - config.stub(groups: {}) - config.stub(host_key_checking: 'false') - config.stub(raw_arguments: nil) - config.stub(raw_ssh_args: nil) + config.playbook = 'playbook.yml' + + $generated_inventory_file = File.join(machine.env.local_data_path, %w(provisioners ansible inventory vagrant_ansible_inventory)) end shared_examples_for "an ansible-playbook subprocess" do it "sets default arguments" do expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| - index = args.find_index("ansible-playbook") - expect(index).to eql(0) - index = args.find_index("--private-key=/path/to/my/key") - expect(index).to eql(1) - index = args.find_index("--user=testuser") - expect(index).to eql(2) + expect(args[0]).to eq("ansible-playbook") + expect(args[1]).to eq("--private-key=/path/to/my/key") + expect(args[2]).to eq("--user=testuser") - index = args.find_index("--limit=#{machine.name}") + index = args.index("--limit=#{machine.name}") expect(index).to be > 0 - index = args.find_index("playbook.yml") - expect(index).to eql(args.length-2) + expect(args[args.length-2]).to eq("playbook.yml") } - subject.provision end it "exports default environment variables" do @@ -69,7 +54,6 @@ describe VagrantPlugins::Ansible::Provisioner do expect(cmd_opts[:env]['ANSIBLE_HOST_KEY_CHECKING']).to eql("false") expect(cmd_opts[:env]['PYTHONUNBUFFERED']).to eql(1) } - subject.provision end end @@ -79,24 +63,21 @@ describe VagrantPlugins::Ansible::Provisioner do cmd_opts = args.last expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to be_nil } - subject.provision end it "does not force SSH transport mode" do expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| - index = args.find_index("--connection=ssh") + index = args.index("--connection=ssh") expect(index).to be_nil } - subject.provision end end shared_examples_for "SSH transport mode is forced" do it "sets --connection=ssh argument" do expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| - index = args.find_index("--connection=ssh") + index = args.index("--connection=ssh") expect(index).to be > 0 } - subject.provision end it "enables ControlPersist (like Ansible defaults) via ANSIBLE_SSH_ARGS" do expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| @@ -104,40 +85,60 @@ describe VagrantPlugins::Ansible::Provisioner do expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-o ControlMaster=auto") expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-o ControlPersist=60s") } - subject.provision end end describe "#provision" do - let(:result) { Vagrant::Util::Subprocess::Result.new(0, "", "") } - before do - Vagrant::Util::Subprocess.stub(execute: result) + unless example.metadata[:skip_before] + config.finalize! + Vagrant::Util::Subprocess.stub(execute: Vagrant::Util::Subprocess::Result.new(0, "", "")) + end + end + + after do + unless example.metadata[:skip_after] + subject.provision + end end it "doesn't raise an error if it succeeds" do - subject.provision end - it "raises an error if the exit code is non-zero" do - Vagrant::Util::Subprocess.stub( - execute: Vagrant::Util::Subprocess::Result.new(1, "", "")) + it "raises an error if the exit code is non-zero", skip_before: true, skip_after: true do + config.finalize! + Vagrant::Util::Subprocess.stub(execute: Vagrant::Util::Subprocess::Result.new(1, "", "")) - expect {subject.provision}. - to raise_error(Vagrant::Errors::AnsibleFailed) + expect {subject.provision}.to raise_error(Vagrant::Errors::AnsibleFailed) end describe "with default options" do + it_behaves_like 'an ansible-playbook subprocess' it_behaves_like 'SSH transport mode is not forced' - it "generates the inventory" do + it "generates an inventory file and uses it" do expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| - index = args.find_index("--inventory-file=#{File.join(machine.env.local_data_path, %w(provisioners ansible inventory vagrant_ansible_inventory))}") - expect(index).to be > 0 + expect(File.exists?($generated_inventory_file)).to be_true + expect(args.include?("--inventory-file=#{$generated_inventory_file}")).to be_true + } + end + end + + describe "with inventory_path option" do + before do + config.inventory_path = file_that_exists + end + + it_behaves_like 'an ansible-playbook subprocess' + it_behaves_like 'SSH transport mode is not forced' + + it "uses given inventory path" do + expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args| + expect(args.include?("--inventory-file=#{file_that_exists}")).to be_true + expect(args.include?("--inventory-file=#{$generated_inventory_file}")).to be_false } - subject.provision end end @@ -155,7 +156,6 @@ describe VagrantPlugins::Ansible::Provisioner do expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-o IdentityFile=/an/other/identity") expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-o IdentityFile=/yet/an/other/key") } - subject.provision end end @@ -172,7 +172,6 @@ describe VagrantPlugins::Ansible::Provisioner do cmd_opts = args.last expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-o ForwardAgent=yes") } - subject.provision end end