Skip to content

Commit

Permalink
Use a single FacterDB.get_facts call
Browse files Browse the repository at this point in the history
The major cost is FacterDB.get_facts. Instead of calling it once for
every OS version this instead calls it once with a complex filter. It
then uses JGrep to simulate another smaller DB and futher query that.

In my non-scientific test this reduces the load time of puppet-example
from 3.5 to 2.5 seconds.
  • Loading branch information
ekohl committed Sep 13, 2024
1 parent f719a71 commit 5fcc51c
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 10 deletions.
13 changes: 10 additions & 3 deletions lib/rspec-puppet-facts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,20 @@ def on_supported_os_implementation(opts = {})
loose_requirement = RspecPuppetFacts.facter_version_to_loose_requirement(facterversion)
received_facts = []

db = FacterDB.get_facts(filter, symbolize_keys: false)
unless db.any?
RspecPuppetFacts.warning "No facts were found in the FacterDB for: #{filter.inspect}"
return {}
end

# FacterDB may have newer versions of facter data for which it contains a subset of all possible
# facter data (see FacterDB 0.5.2 for Facter releases 3.8 and 3.9). In this situation we need to
# cycle through and downgrade Facter versions per platform type until we find matching Facter data.
facterversion_key = RSpec.configuration.facterdb_string_keys ? 'facterversion' : :facterversion
json_db = db.to_json
filter.each do |filter_spec|
versions = FacterDB.get_facts(filter_spec, symbolize_keys: !RSpec.configuration.facterdb_string_keys).to_h do |facts|
[Gem::Version.new(facts[facterversion_key]), facts]
versions = JGrep.jgrep(json_db, FacterDB.generate_filter_str(filter_spec)).to_h do |facts|
result = RSpec.configuration.facterdb_string_keys ? facts : facts.transform_keys(&:to_sym)
[Gem::Version.new(facts['facterversion']), result]
end

version, facts = versions.select { |v, _f| strict_requirement =~ v }.max_by { |v, _f| v }
Expand Down
17 changes: 10 additions & 7 deletions spec/rspec_puppet_facts_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -610,13 +610,13 @@
end

it 'escapes the parens in the filter' do
filter = {
filter = [{
'os.name' => 'IOS',
'os.release.full' => '/^12\\.2\\(25\\)EWA9/',
'os.hardware' => 'x86_64',
}
}]

expect(FacterDB).to receive(:get_facts).with(filter, symbolize_keys: true).once
expect(FacterDB).to receive(:get_facts).with(filter, symbolize_keys: false).once.and_return([])
subject
end

Expand Down Expand Up @@ -742,11 +742,14 @@
end

before do
allow(FacterDB).to receive(:get_facts).and_call_original
allow(FacterDB).to receive(:get_facts).with(
{ 'os.name' => 'CentOS', 'os.release.full' => '/^9/', 'os.hardware' => 'x86_64' }, symbolize_keys: true
).and_wrap_original do |m, *args|
m.call(*args).reject { |facts| facts[:facterversion].start_with?('4.6.') }
[
{ 'os.name' => 'CentOS', 'os.release.full' => '/^9/', 'os.hardware' => 'x86_64' },
{ 'os.name' => 'Debian', 'os.release.full' => '/^12/', 'os.hardware' => 'x86_64' },
],
symbolize_keys: false,
).and_wrap_original do |m, *args, **kwargs|
m.call(*args, **kwargs).reject { |facts| facts.dig('os', 'name') == 'CentOS' && facts['facterversion'].start_with?('4.6.') }
end
end

Expand Down

0 comments on commit 5fcc51c

Please sign in to comment.