Skip to content

Commit

Permalink
Merge pull request #14383 from jameswnl/shared-tower-specs
Browse files Browse the repository at this point in the history
Add test coverage for Embedded Ansible and eliminate redundant spec code
  • Loading branch information
blomquisg authored Mar 17, 2017
2 parents 346382d + c2465a8 commit a143dcd
Show file tree
Hide file tree
Showing 34 changed files with 1,181 additions and 16,115 deletions.
Original file line number Diff line number Diff line change
@@ -1,120 +1,5 @@
require 'ansible_tower_client'
require 'support/ansible_shared/automation_manager/configuration_script_source'

describe ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScriptSource do
let(:finished_task) { FactoryGirl.create(:miq_task, :state => "Finished") }
let(:manager) { FactoryGirl.create(:provider_ansible_tower, :with_authentication).managers.first }
let(:atc) { double("AnsibleTowerClient::Connection", :api => api) }
let(:api) { double("AnsibleTowerClient::Api", :projects => projects) }

context "create through API" do
let(:projects) { double("AnsibleTowerClient::Collection", :create! => project) }
let(:project) { AnsibleTowerClient::Project.new(nil, project_json) }

let(:project_json) do
params.merge(
:id => 10,
"scm_type" => "git",
"scm_url" => "https://github.com/ansible/ansible-tower-samples"
).stringify_keys.to_json
end

let(:params) do
{
:description => "Description",
:name => "My Project",
:related => {}
}
end

it ".create_in_provider" do
expect(AnsibleTowerClient::Connection).to receive(:new).and_return(atc)
store_new_project(project, manager)
expect(EmsRefresh).to receive(:queue_refresh_task).and_return([finished_task])
expect(ExtManagementSystem).to receive(:find).with(manager.id).and_return(manager)

expect(described_class.create_in_provider(manager.id, params)).to be_a(described_class)
end

it "not found during refresh" do
expect(AnsibleTowerClient::Connection).to receive(:new).and_return(atc)
expect(EmsRefresh).to receive(:queue_refresh_task).and_return([finished_task])
expect(ExtManagementSystem).to receive(:find).with(manager.id).and_return(manager)

expect { described_class.create_in_provider(manager.id, params) }.to raise_error(ActiveRecord::RecordNotFound)
end

it ".create_in_provider_queue" do
EvmSpecHelper.local_miq_server
task_id = described_class.create_in_provider_queue(manager.id, params)
expect(MiqTask.find(task_id)).to have_attributes(:name => "Creating #{described_class.name} with name=#{params[:name]}")
expect(MiqQueue.first).to have_attributes(
:args => [manager.id, params],
:class_name => described_class.name,
:method_name => "create_in_provider",
:priority => MiqQueue::HIGH_PRIORITY,
:role => "ems_operations",
:zone => manager.my_zone
)
end

def store_new_project(project, manager)
described_class.create!(
:manager => manager,
:manager_ref => project.id.to_s,
:name => project.name,
)
end
end

context "Delete through API" do
let(:projects) { double("AnsibleTowerClient::Collection", :find => tower_project) }
let(:tower_project) { double("AnsibleTowerClient::Project", :destroy! => nil, :id => 1) }
let(:project) { described_class.create!(:manager => manager, :manager_ref => tower_project.id) }

it "#delete_in_provider" do
expect(AnsibleTowerClient::Connection).to receive(:new).and_return(atc)
expect(EmsRefresh).to receive(:queue_refresh_task).and_return([finished_task])
project.delete_in_provider
end

it "#delete_in_provider_queue" do
task_id = project.delete_in_provider_queue
expect(MiqTask.find(task_id)).to have_attributes(:name => "Deleting #{described_class.name} with manager_ref=#{project.manager_ref}")
expect(MiqQueue.first).to have_attributes(
:instance_id => project.id,
:args => [],
:class_name => described_class.name,
:method_name => "delete_in_provider",
:priority => MiqQueue::HIGH_PRIORITY,
:role => "ems_operations",
:zone => manager.my_zone
)
end
end

context "Update through API" do
let(:projects) { double("AnsibleTowerClient::Collection", :find => tower_project) }
let(:tower_project) { double("AnsibleTowerClient::Project", :update_attributes! => {}, :id => 1) }
let(:project) { described_class.create!(:manager => manager, :manager_ref => tower_project.id) }

it "#update_in_provider" do
expect(AnsibleTowerClient::Connection).to receive(:new).and_return(atc)
expect(EmsRefresh).to receive(:queue_refresh_task).and_return([finished_task])
expect(project.update_in_provider({})).to be_a(described_class)
end

it "#update_in_provider_queue" do
task_id = project.update_in_provider_queue({})
expect(MiqTask.find(task_id)).to have_attributes(:name => "Updating #{described_class.name} with manager_ref=#{project.manager_ref}")
expect(MiqQueue.first).to have_attributes(
:instance_id => project.id,
:args => [{:task_id => task_id}],
:class_name => described_class.name,
:method_name => "update_in_provider",
:priority => MiqQueue::HIGH_PRIORITY,
:role => "ems_operations",
:zone => manager.my_zone
)
end
end
it_behaves_like 'ansible configuration_script_source'
end
Original file line number Diff line number Diff line change
@@ -1,175 +1,5 @@
require 'ansible_tower_client'
require 'faraday'
describe ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript do
let(:api) { double(:api, :job_templates => double(:job_templates)) }
let(:connection) { double(:connection, :api => api) }
let(:job) { AnsibleTowerClient::Job.new(connection.api, "id" => 1) }
let(:job_template) { AnsibleTowerClient::JobTemplate.new(connection.api, "limit" => "", "id" => 1, "url" => "api/job_templates/1/", "name" => "template", "description" => "description", "extra_vars" => {:instance_ids => ['i-3434']}) }
let(:manager) { FactoryGirl.create(:automation_manager_ansible_tower, :provider, :configuration_script) }

it "belongs_to the Ansible Tower manager" do
expect(manager.configuration_scripts.size).to eq 1
expect(manager.configuration_scripts.first.variables).to eq :instance_ids => ['i-3434']
expect(manager.configuration_scripts.first).to be_a ConfigurationScript
end

context "relates to playbook" do
let(:configuration_script_source) { FactoryGirl.create(:configuration_script_source, :manager => manager) }
let!(:payload) { FactoryGirl.create(:configuration_script_payload) }
let(:configuration_scripts_without_payload) { FactoryGirl.create(:configuration_script) }
let(:configuration_scripts) do
[FactoryGirl.create(:configuration_script, :parent => payload),
FactoryGirl.create(:configuration_script, :parent => payload)]
end

it "can refer to a payload" do
expect(configuration_scripts[0].parent).to eq(payload)
expect(configuration_scripts[1].parent).to eq(payload)
expect(payload.children).to match_array(configuration_scripts)
end

it "can be without payload" do
expect(configuration_scripts_without_payload.parent).to be_nil
end
end

context "#run" do
before do
allow_any_instance_of(Provider).to receive_messages(:connect => connection)
allow(api.job_templates).to receive(:find) { job_template }
end

it "launches the referenced ansible job template" do
expect(job_template).to receive(:launch).with(:extra_vars => "{\"instance_ids\":[\"i-3434\"]}").and_return(job)
expect(manager.configuration_scripts.first.run).to be_a AnsibleTowerClient::Job
end

it "accepts different variables to launch a job template against" do
added_extras = {:extra_vars => {:some_key => :some_value}}
expect(job_template).to receive(:launch).with(:extra_vars=>"{\"instance_ids\":[\"i-3434\"],\"some_key\":\"some_value\"}").and_return(job)
expect(manager.configuration_scripts.first.run(added_extras)).to be_a AnsibleTowerClient::Job
end
end

context "#merge_extra_vars" do
it "merges internal and external hashes to send out to the tower gem" do
config_script = manager.configuration_scripts.first
external = {:some_key => :some_value}
internal = config_script.variables
expect(internal).to be_a Hash
expect(config_script.merge_extra_vars(external)).to eq(:extra_vars => "{\"instance_ids\":[\"i-3434\"],\"some_key\":\"some_value\"}")
end

it "merges an internal hash and an empty hash to send out to the tower gem" do
config_script = manager.configuration_scripts.first
external = nil
expect(config_script.merge_extra_vars(external)).to eq(:extra_vars => "{\"instance_ids\":[\"i-3434\"]}")
end

it "merges an empty internal hash and a hash to send out to the tower gem" do
external = {:some_key => :some_value}
internal = {}
config_script = manager.configuration_scripts.first
config_script.variables = internal
expect(config_script.merge_extra_vars(external)).to eq(:extra_vars => "{\"some_key\":\"some_value\"}")
end

it "merges all empty arguments to send out to the tower gem" do
external = nil
internal = {}
config_script = manager.configuration_scripts.first
config_script.variables = internal
expect(config_script.merge_extra_vars(external)).to eq(:extra_vars => "{}")
end
end

context "creates via the API" do
let(:provider) { FactoryGirl.create(:provider_ansible_tower, :with_authentication) }
let(:manager) { provider.managers.first }
let(:atc) { double("AnsibleTowerClient::Connection", :api => api) }
let(:api) { double("AnsibleTowerClient::Api", :job_templates => job_templates) }
let(:job_templates) { double("AnsibleTowerClient::Collection", :create! => job_template) }
let(:job_template) { AnsibleTowerClient::JobTemplate.new(nil, job_template_json) }
require 'support/ansible_shared/automation_manager/configuration_script'

let(:job_template_json) do
params.merge(
:id => 10,
:inventory => 1,
:related => {"inventory" => "blah/1"}
).except(:inventory_id).stringify_keys.to_json
end

let(:params) do
{
:description => "Description",
:extra_vars => {}.to_json,
:inventory_id => 1,
:name => "My Job Template",
:related => {}
}
end

context ".create_in_provider" do
let(:finished_task) { FactoryGirl.create(:miq_task, :state => "Finished") }

it "successfully created in provider" do
expect(AnsibleTowerClient::Connection).to receive(:new).and_return(atc)

store_new_job_template(job_template, manager)

expect(EmsRefresh).to receive(:queue_refresh_task).and_return([finished_task])
expect(ExtManagementSystem).to receive(:find).with(manager.id).and_return(manager)

expect(described_class.create_in_provider(manager.id, params)).to be_a(described_class)
end

it "not found during refresh" do
expect(AnsibleTowerClient::Connection).to receive(:new).and_return(atc)
expect(EmsRefresh).to receive(:queue_refresh_task).and_return([finished_task])
expect(ExtManagementSystem).to receive(:find).with(manager.id).and_return(manager)

expect { described_class.create_in_provider(manager.id, params) }.to raise_error(ActiveRecord::RecordNotFound)
end
end

it ".create_in_provider_queue" do
EvmSpecHelper.local_miq_server
task_id = described_class.create_in_provider_queue(manager.id, params)
expect(MiqTask.find(task_id)).to have_attributes(:name => "Creating Ansible Tower Job Template")
expect(MiqQueue.first).to have_attributes(
:args => [manager.id, params],
:class_name => "ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript",
:method_name => "create_in_provider",
:priority => MiqQueue::HIGH_PRIORITY,
:role => "ems_operations",
:zone => manager.zone.name
)
end

it ".update_in_provider_queue" do
EvmSpecHelper.local_miq_server
params[:manager_ref] = 10
task_id = described_class.update_in_provider_queue(manager.id, params)
expect(MiqTask.find(task_id)).to have_attributes(:name => "Updating Ansible Tower Job Template")
expect(MiqQueue.first).to have_attributes(
:args => [manager.id, params],
:class_name => "ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript",
:method_name => "update_in_provider",
:priority => MiqQueue::HIGH_PRIORITY,
:role => "ems_operations",
:zone => manager.zone.name
)
end

def store_new_job_template(job_template, manager)
described_class.create!(
:manager => manager,
:manager_ref => job_template.id.to_s,
:name => job_template.name,
:survey_spec => job_template.survey_spec_hash,
:variables => job_template.extra_vars_hash,
)
end

end
describe ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript do
it_behaves_like 'ansible configuration_script'
end
Loading

0 comments on commit a143dcd

Please sign in to comment.