Project

General

Profile

Download (8.68 KB) Statistics
| Branch: | Tag: | Revision:
require 'test_helper'
require 'fact_importer_test_helper'

class FactImporterTest < ActiveSupport::TestCase
include FactImporterIsolation

attr_reader :importer
class CustomFactName < FactName; end
class CustomImporter < FactImporter
def fact_name_class
CustomFactName
end
end

let(:host) { FactoryBot.create(:host) }

test "default importers" do
assert_includes FactImporter.importers.keys, 'puppet'
assert_equal PuppetFactImporter, FactImporter.importer_for(:puppet)
assert_equal PuppetFactImporter, FactImporter.importer_for('puppet')
assert_equal PuppetFactImporter, FactImporter.importer_for(:whatever)
assert_equal PuppetFactImporter, FactImporter.importer_for('whatever')
end

test 'importer API defines background processing support' do
assert FactImporter.respond_to?(:support_background)
end

context 'when using a custom importer' do
setup do
FactImporter.register_fact_importer :custom_importer, CustomImporter
end

test ".register_custom_importer" do
assert_equal CustomImporter, FactImporter.importer_for(:custom_importer)
end

test 'importers without authorized_smart_proxy_features return empty set of features' do
assert_equal [], FactImporter.importer_for(:custom_importer).authorized_smart_proxy_features
end

context 'importing facts' do
test 'facts of other type do not collide even if they inherit from FactName' do
assert_nothing_raised do
custom_import '_timestamp' => '234'
puppet_import '_timestamp' => '345'
end
end

test 'facts created have the origin attribute set' do
custom_import('foo' => 'bar')
imported_fact = FactName.find_by_name('foo').fact_values.first
assert_equal 'N/A', imported_fact.origin
end
end
end

describe '#normalize' do
test 'filters regular facts' do
data = FactsData::FlatFacts.new
Setting.stubs(:[]).with(:excluded_facts).returns(data.filter)

facts = data.good_facts.merge(data.ignored_facts)

importer = FactImporter.new(nil, facts)
actual_facts = importer.send(:facts)

assert_equal data.good_facts, actual_facts
end

test 'filters a::b facts' do
data = FactsData::RhsmStyleFacts.new
Setting.stubs(:[]).with(:excluded_facts).returns(data.filter)

facts = data.good_facts.merge(data.ignored_facts)

importer = FactImporter.new(nil, facts)
actual_facts = importer.send(:facts)

assert_equal data.good_facts, actual_facts
end

test 'filters macaddress_virbr0 facts' do
data = FactsData::FlatPuppetStyleFacts.new
Setting.stubs(:[]).with(:excluded_facts).returns(data.filter)

facts = data.good_facts.merge(data.ignored_facts)

importer = FactImporter.new(nil, facts)
actual_facts = importer.send(:facts)

assert_equal data.good_facts, actual_facts
end

test 'filters default interface facts' do
data = FactsData::DefaultInterfacesFacts.new

facts = data.good_facts.merge(data.ignored_facts)

importer = FactImporter.new(nil, facts)
actual_facts = importer.send(:facts)

assert_equal data.good_facts, actual_facts
end
end

describe '#import!' do
setup do
FactoryBot.create(:fact_value, :value => '2.6.9', :host => host,
:fact_name => FactoryBot.create(:fact_name, :name => 'kernelversion'))
FactoryBot.create(:fact_value, :value => '10.0.19.33', :host => host,
:fact_name => FactoryBot.create(:fact_name, :name => 'ipaddress'))
end

test 'importer imports everything as strings' do
default_import 'kernelversion' => '2.6.9', 'vda_size' => 4242, 'structured' => {'key' => 'value'}
assert_equal '2.6.9', value('kernelversion')
assert_equal '4242', value('vda_size')
assert_equal '{"key"=>"value"}', value('structured')
refute FactName.find_by_name('structured').compose?
end

test 'importer adds new facts' do
assert_equal '2.6.9', value('kernelversion')
assert_equal '10.0.19.33', value('ipaddress')
default_import 'foo' => 'bar', 'kernelversion' => '2.6.9', 'ipaddress' => '10.0.19.33'
assert_equal 'bar', value('foo')
assert_equal '2.6.9', value('kernelversion')
assert_equal 0, importer.counters[:deleted]
assert_equal 0, importer.counters[:updated]
assert_equal 1, importer.counters[:added]
end

test 'importer removes deleted facts' do
default_import 'ipaddress' => '10.0.19.33'
assert_nil value('kernelversion')

assert_equal 1, importer.counters[:deleted]
assert_equal 0, importer.counters[:updated]
assert_equal 0, importer.counters[:added]
end

test 'importer updates fact values' do
assert_equal '2.6.9', value('kernelversion')
assert_equal '10.0.19.33', value('ipaddress')
default_import 'kernelversion' => '3.8.11', 'ipaddress' => '10.0.19.33'
assert_equal '3.8.11', value('kernelversion')

assert_equal 0, importer.counters[:deleted]
assert_equal 1, importer.counters[:updated]
assert_equal 0, importer.counters[:added]
end

test "importer shouldn't set nil values" do
assert_equal '2.6.9', value('kernelversion')
assert_equal '10.0.19.33', value('ipaddress')
default_import('kernelversion' => nil, 'ipaddress' => '10.0.19.33')
assert_nil value('kernelversion')
assert_equal '10.0.19.33', value('ipaddress')

assert_equal 1, importer.counters[:deleted]
assert_equal 0, importer.counters[:updated]
assert_equal 0, importer.counters[:added]
end

test "importer adds, removes and deletes facts" do
assert_equal '2.6.9', value('kernelversion')
assert_equal '10.0.19.33', value('ipaddress')
default_import('kernelversion' => nil, 'ipaddress' => '10.0.19.5', 'uptime' => '1 picosecond')
assert_nil value('kernelversion')
assert_equal '10.0.19.5', value('ipaddress')
assert_equal '1 picosecond', value('uptime')

assert_equal 1, importer.counters[:deleted]
assert_equal 1, importer.counters[:updated]
assert_equal 1, importer.counters[:added]
end

test "importer retains 'other' facts" do
assert_equal '2.6.9', value('kernelversion')
FactoryBot.create(:fact_value, :value => 'othervalue', :host => host,
:fact_name => FactoryBot.create(:fact_name_other, :name => 'otherfact'))
default_import('ipaddress' => '10.0.19.5', 'uptime' => '1 picosecond')
assert_equal 'othervalue', value('otherfact')
assert_nil value('kernelversion')
assert_equal '10.0.19.5', value('ipaddress')
assert_equal '1 picosecond', value('uptime')
assert_equal 1, importer.counters[:deleted]
assert_equal 1, importer.counters[:updated]
assert_equal 1, importer.counters[:added]
end

test "importer handles fact name additions" do
facts = { 'duplicate_name' => 'some_value' }
importer = FactImporter.new(host, facts)
importer.stubs(:fact_name_class).returns(FactName)
allow_transactions_for importer
importer.stubs(:save_name_record).raises(ActiveRecord::RecordNotUnique, 'Test message')

# redefine fact_name_attributes for this instance, so it will create
# the fact name before it's actually created by the importer
def importer.fact_name_attributes(fact_name)
ActiveRecord::Base.transaction(:requires_new => true) do
dup_record = FactoryBot.build(:fact_name, :name => fact_name)
# save duplicate record in isolated transaction
dup_record.save!
end

{
name: fact_name
}
end

importer.import!

name_record = FactName.find_by(name: 'duplicate_name')
assert_not_nil name_record
end

test 'importer cannot run in transaction' do
facts = { 'some_name' => 'some_value' }
importer = FactImporter.new(host, facts)
importer.stubs(:fact_name_class).returns(FactName)
exception = assert_raises(RuntimeError) do
importer.import!
end
assert_match(/outside of global transaction/, exception.message)
end
end

def default_import(facts)
@importer = FactImporter.new(host, facts)
allow_transactions_for @importer
@importer.stubs(:fact_name_class).returns(FactName)
@importer.import!
end

def custom_import(facts)
@importer = CustomImporter.new(host, facts)
allow_transactions_for @importer
@importer.import!
end

def puppet_import(facts)
@importer = PuppetFactImporter.new(host, facts)
allow_transactions_for @importer
@importer.import!
end

def value(fact)
FactValue.joins(:fact_name).where(:host_id => host.id, :fact_names => { :name => fact }).first.try(:value)
end
end
(26-26/67)