From da463f8e42f49d57fa3e88278e55d7c75a61846f Mon Sep 17 00:00:00 2001 From: Oana Tanasoiu Date: Wed, 29 Apr 2020 15:15:53 +0300 Subject: [PATCH] (FACT-2235) Add Aix processors fact --- lib/facts/aix/processors/count.rb | 17 ++++ lib/facts/aix/processors/isa.rb | 18 ++++ lib/facts/aix/processors/models.rb | 16 ++++ lib/facts/aix/processors/speed.rb | 17 ++++ lib/resolvers/aix/processors.rb | 80 +++++++++++++++++ .../facter/facts/aix/processors/count_spec.rb | 25 ++++++ spec/facter/facts/aix/processors/isa_spec.rb | 25 ++++++ .../facts/aix/processors/models_spec.rb | 24 ++++++ .../facter/facts/aix/processors/speed_spec.rb | 25 ++++++ spec/facter/resolvers/aix/processors_spec.rb | 86 +++++++++++++++++++ spec/fixtures/processors_cuat | 35 ++++++++ spec/fixtures/processors_cudv | 4 + spec/fixtures/processors_pddv | 6 ++ 13 files changed, 378 insertions(+) create mode 100644 lib/facts/aix/processors/count.rb create mode 100644 lib/facts/aix/processors/isa.rb create mode 100644 lib/facts/aix/processors/models.rb create mode 100644 lib/facts/aix/processors/speed.rb create mode 100644 lib/resolvers/aix/processors.rb create mode 100644 spec/facter/facts/aix/processors/count_spec.rb create mode 100644 spec/facter/facts/aix/processors/isa_spec.rb create mode 100644 spec/facter/facts/aix/processors/models_spec.rb create mode 100644 spec/facter/facts/aix/processors/speed_spec.rb create mode 100644 spec/facter/resolvers/aix/processors_spec.rb create mode 100644 spec/fixtures/processors_cuat create mode 100644 spec/fixtures/processors_cudv create mode 100644 spec/fixtures/processors_pddv diff --git a/lib/facts/aix/processors/count.rb b/lib/facts/aix/processors/count.rb new file mode 100644 index 000000000..a0b668671 --- /dev/null +++ b/lib/facts/aix/processors/count.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Facts + module Aix + module Processors + class Count + FACT_NAME = 'processors.count' + ALIASES = 'processorcount' + + def call_the_resolver + fact_value = Facter::Resolvers::Aix::Processors.resolve(:logical_count) + [Facter::ResolvedFact.new(FACT_NAME, fact_value), Facter::ResolvedFact.new(ALIASES, fact_value, :legacy)] + end + end + end + end +end diff --git a/lib/facts/aix/processors/isa.rb b/lib/facts/aix/processors/isa.rb new file mode 100644 index 000000000..c37cd9a74 --- /dev/null +++ b/lib/facts/aix/processors/isa.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Facts + module Aix + module Processors + class Isa + FACT_NAME = 'processors.isa' + ALIASES = 'hardwareisa' + + def call_the_resolver + fact_value = Facter::Resolvers::Uname.resolve(:processor) + + [Facter::ResolvedFact.new(FACT_NAME, fact_value), Facter::ResolvedFact.new(ALIASES, fact_value, :legacy)] + end + end + end + end +end diff --git a/lib/facts/aix/processors/models.rb b/lib/facts/aix/processors/models.rb new file mode 100644 index 000000000..527959643 --- /dev/null +++ b/lib/facts/aix/processors/models.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Facts + module Aix + module Processors + class Models + FACT_NAME = 'processors.models' + + def call_the_resolver + fact_value = Facter::Resolvers::Aix::Processors.resolve(:models) + Facter::ResolvedFact.new(FACT_NAME, fact_value) + end + end + end + end +end diff --git a/lib/facts/aix/processors/speed.rb b/lib/facts/aix/processors/speed.rb new file mode 100644 index 000000000..06b00e4e6 --- /dev/null +++ b/lib/facts/aix/processors/speed.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Facts + module Aix + module Processors + class Speed + FACT_NAME = 'processors.speed' + + def call_the_resolver + fact_value = Facter::Resolvers::Aix::Processors.resolve(:speed) + speed = Facter::FactsUtils::UnitConverter.hertz_to_human_readable(fact_value) + Facter::ResolvedFact.new(FACT_NAME, speed) + end + end + end + end +end diff --git a/lib/resolvers/aix/processors.rb b/lib/resolvers/aix/processors.rb new file mode 100644 index 000000000..94fa72c2c --- /dev/null +++ b/lib/resolvers/aix/processors.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true + +module Facter + module Resolvers + module Aix + class Processors < BaseResolver + @semaphore = Mutex.new + @fact_list ||= {} + class << self + private + + def post_resolve(fact_name) + @fact_list.fetch(fact_name) { query_pddv(fact_name) } + end + + def query_pddv(fact_name) + @fact_list[:models] = [] + @fact_list[:logical_count] = 0 + + odmquery = Facter::ODMQuery.new + odmquery.equals('class', 'processor') + + result = odmquery.execute + + return unless result + + proc_names = retrieve_from_array(result.scan(/uniquetype\s=\s.*/), 1) + + proc_names.each { |name| populate_from_cudv(name) } + + @fact_list[fact_name] + end + + def populate_from_cudv(name) + odmquery = Facter::ODMQuery.new + odmquery.equals('PdDvLn', name) + + result = odmquery.execute + + return unless result + + names = retrieve_from_array(result.scan(/name\s=\s.*/), 1) + + names.each { |elem| query_cuat(elem) } + end + + def query_cuat(name) + odmquery = Facter::ODMQuery.new + odmquery.equals('name', name) + + result = odmquery.execute + + return unless result + + type, frequency, smt_threads, smt_enabled = process(result) + + @fact_list[:speed] ||= frequency if frequency + + threads = smt_enabled ? smt_threads : 1 + + @fact_list[:logical_count] += threads + @fact_list[:models].concat([type] * threads) + end + + def process(stdout) + type = retrieve_from_array(stdout.scan(/attribute\s=\s"type"\n\s+value\s=\s.*/), 2).first + frequency = retrieve_from_array(stdout.scan(/attribute\s=\s"frequency"\n\s+value\s=\s.*/), 2).first + smt_threads = retrieve_from_array(stdout.scan(/attribute\s=\s"smt_threads"\n\s+value\s=\s.*/), 2).first + smt_enabled = retrieve_from_array(stdout.scan(/attribute\s=\s"smt_enabled"\n\s+value\s=\s.*/), 2).first + [type, frequency.to_i, smt_threads.to_i, smt_enabled] + end + + def retrieve_from_array(array, pos) + array.map { |elem| elem.split('=')[pos].strip.delete('"') } + end + end + end + end + end +end diff --git a/spec/facter/facts/aix/processors/count_spec.rb b/spec/facter/facts/aix/processors/count_spec.rb new file mode 100644 index 000000000..13df78bed --- /dev/null +++ b/spec/facter/facts/aix/processors/count_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +describe Facts::Aix::Processors::Count do + describe '#call_the_resolver' do + subject(:fact) { Facts::Aix::Processors::Count.new } + + let(:processors_count) { '32' } + + before do + allow(Facter::Resolvers::Aix::Processors).to \ + receive(:resolve).with(:logical_count).and_return(processors_count) + end + + it 'calls Facter::Resolvers::Aix::Processors' do + fact.call_the_resolver + expect(Facter::Resolvers::Aix::Processors).to have_received(:resolve).with(:logical_count) + end + + it 'returns processors count fact' do + expect(fact.call_the_resolver).to be_an_instance_of(Array).and \ + contain_exactly(an_object_having_attributes(name: 'processors.count', value: processors_count), + an_object_having_attributes(name: 'processorcount', value: processors_count, type: :legacy)) + end + end +end diff --git a/spec/facter/facts/aix/processors/isa_spec.rb b/spec/facter/facts/aix/processors/isa_spec.rb new file mode 100644 index 000000000..7f52b847b --- /dev/null +++ b/spec/facter/facts/aix/processors/isa_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +describe Facts::Aix::Processors::Isa do + describe '#call_the_resolver' do + subject(:fact) { Facts::Aix::Processors::Isa.new } + + let(:processors_arch) { 'powerpc' } + + before do + allow(Facter::Resolvers::Uname).to \ + receive(:resolve).with(:processor).and_return(processors_arch) + end + + it 'calls Facter::Resolvers::Uname' do + fact.call_the_resolver + expect(Facter::Resolvers::Uname).to have_received(:resolve).with(:processor) + end + + it 'returns processors isa fact' do + expect(fact.call_the_resolver).to be_an_instance_of(Array).and \ + contain_exactly(an_object_having_attributes(name: 'processors.isa', value: processors_arch), + an_object_having_attributes(name: 'hardwareisa', value: processors_arch, type: :legacy)) + end + end +end diff --git a/spec/facter/facts/aix/processors/models_spec.rb b/spec/facter/facts/aix/processors/models_spec.rb new file mode 100644 index 000000000..ee05d4d15 --- /dev/null +++ b/spec/facter/facts/aix/processors/models_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +describe Facts::Aix::Processors::Models do + describe '#call_the_resolver' do + subject(:fact) { Facts::Aix::Processors::Models.new } + + let(:models) { %w[PowerPC_POWER8 PowerPC_POWER8 PowerPC_POWER8 PowerPC_POWER8] } + + before do + allow(Facter::Resolvers::Aix::Processors).to \ + receive(:resolve).with(:models).and_return(models) + end + + it 'calls Facter::Resolvers::Aix::Processors' do + fact.call_the_resolver + expect(Facter::Resolvers::Aix::Processors).to have_received(:resolve).with(:models) + end + + it 'returns processors models fact' do + expect(fact.call_the_resolver).to be_an_instance_of(Facter::ResolvedFact).and \ + have_attributes(name: 'processors.models', value: models) + end + end +end diff --git a/spec/facter/facts/aix/processors/speed_spec.rb b/spec/facter/facts/aix/processors/speed_spec.rb new file mode 100644 index 000000000..2f9feccee --- /dev/null +++ b/spec/facter/facts/aix/processors/speed_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +describe Facts::Aix::Processors::Speed do + describe '#call_the_resolver' do + subject(:fact) { Facts::Aix::Processors::Speed.new } + + let(:speed) { 1_800_000_000 } + let(:converted_speed) { '1.80 GHz' } + + before do + allow(Facter::Resolvers::Aix::Processors).to \ + receive(:resolve).with(:speed).and_return(speed) + end + + it 'calls Facter::Resolvers::Aix::Processors' do + fact.call_the_resolver + expect(Facter::Resolvers::Aix::Processors).to have_received(:resolve).with(:speed) + end + + it 'returns a resolved fact' do + expect(fact.call_the_resolver).to be_an_instance_of(Facter::ResolvedFact).and \ + have_attributes(name: 'processors.speed', value: converted_speed) + end + end +end diff --git a/spec/facter/resolvers/aix/processors_spec.rb b/spec/facter/resolvers/aix/processors_spec.rb new file mode 100644 index 000000000..384a7415a --- /dev/null +++ b/spec/facter/resolvers/aix/processors_spec.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +describe Facter::Resolvers::Aix::Processors do + subject(:resolver) { Facter::Resolvers::Aix::Processors } + + let(:odm_query_spy) { instance_spy(Facter::ODMQuery) } + let(:odm_query_spy2) { instance_spy(Facter::ODMQuery) } + let(:odm_query_spy3) { instance_spy(Facter::ODMQuery) } + let(:logger_spy) { instance_spy(Facter::Log) } + + before do + resolver.instance_variable_set(:@log, logger_spy) + allow(Facter::ODMQuery).to receive(:new).ordered.and_return(odm_query_spy, odm_query_spy2, odm_query_spy3) + allow(odm_query_spy).to receive(:equals).with('class', 'processor').ordered + allow(odm_query_spy).to receive(:execute).ordered.and_return(result) + end + + after do + resolver.invalidate_cache + end + + context 'when PdDv query fails' do + let(:result) { nil } + + it 'returns nil' do + expect(resolver.resolve(:speed)).to be_nil + end + end + + context 'when PdDv query succesful but CuDv fails' do + let(:result) { load_fixture('processors_pddv').read } + + before do + allow(odm_query_spy2).to receive(:equals).with('PdDvLn', 'processor/sys/proc_rspc').ordered + allow(odm_query_spy2).to receive(:execute).ordered.and_return(nil) + end + + it 'returns nil' do + expect(resolver.resolve(:speed)).to be_nil + end + end + + context 'when CuAt query fails' do + let(:result) { load_fixture('processors_pddv').read } + + before do + allow(odm_query_spy2).to receive(:equals).with('PdDvLn', 'processor/sys/proc_rspc').ordered + allow(odm_query_spy2).to receive(:execute).ordered.and_return(load_fixture('processors_cudv').read) + + allow(odm_query_spy3).to receive(:equals).with('name', 'proc0').ordered + allow(odm_query_spy3).to receive(:execute).ordered.and_return(nil) + end + + it 'returns nil' do + expect(resolver.resolve(:speed)).to be_nil + end + end + + context 'when all queries returns an output' do + let(:result) { load_fixture('processors_pddv').read } + let(:models) do + %w[PowerPC_POWER8 PowerPC_POWER8 PowerPC_POWER8 + PowerPC_POWER8 PowerPC_POWER8 PowerPC_POWER8 PowerPC_POWER8 PowerPC_POWER8] + end + + before do + allow(odm_query_spy2).to receive(:equals).with('PdDvLn', 'processor/sys/proc_rspc').ordered + allow(odm_query_spy2).to receive(:execute).and_return(load_fixture('processors_cudv').read) + + allow(odm_query_spy3).to receive(:equals).with('name', 'proc0').ordered + allow(odm_query_spy3).to receive(:execute).ordered.and_return(load_fixture('processors_cuat').read) + end + + it 'returns speed fact' do + expect(resolver.resolve(:speed)).to eq(3_425_000_000) + end + + it 'returns models fact' do + expect(resolver.resolve(:models)).to eq(models) + end + + it 'returns logical_count fact' do + expect(resolver.resolve(:logical_count)).to eq(8) + end + end +end diff --git a/spec/fixtures/processors_cuat b/spec/fixtures/processors_cuat new file mode 100644 index 000000000..f40c9633d --- /dev/null +++ b/spec/fixtures/processors_cuat @@ -0,0 +1,35 @@ +uAt: + name = "proc0" + attribute = "type" + value = "PowerPC_POWER8" + type = "R" + generic = "D" + rep = "sl" + nls_index = 49 + +CuAt: + name = "proc0" + attribute = "frequency" + value = "3425000000" + type = "R" + generic = "D" + rep = "s" + nls_index = 69 + +CuAt: + name = "proc0" + attribute = "smt_threads" + value = "8" + type = "R" + generic = "D" + rep = "" + nls_index = 82 + +CuAt: + name = "proc0" + attribute = "smt_enabled" + value = "true" + type = "R" + generic = "D" + rep = "" + nls_index = 83 \ No newline at end of file diff --git a/spec/fixtures/processors_cudv b/spec/fixtures/processors_cudv new file mode 100644 index 000000000..b5693cf61 --- /dev/null +++ b/spec/fixtures/processors_cudv @@ -0,0 +1,4 @@ +CuDv: + name = "proc0" + status = 1 + PdDvLn = "processor/sys/proc_rspc" \ No newline at end of file diff --git a/spec/fixtures/processors_pddv b/spec/fixtures/processors_pddv new file mode 100644 index 000000000..87992d7b9 --- /dev/null +++ b/spec/fixtures/processors_pddv @@ -0,0 +1,6 @@ +PdDv: + type = "proc_rspc" + class = "processor" + Stop = "" + inventory_only = 0 + uniquetype = "processor/sys/proc_rspc" \ No newline at end of file