From ae766987288d4cd13ee11605f390a60d6de139e7 Mon Sep 17 00:00:00 2001 From: Ewoud Kohl van Wijngaarden Date: Thu, 20 Jul 2023 17:43:09 +0200 Subject: [PATCH] Use a single FacterDB.get_facts call 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. --- lib/rspec-puppet-facts.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/rspec-puppet-facts.rb b/lib/rspec-puppet-facts.rb index 326827c..a26d5fb 100644 --- a/lib/rspec-puppet-facts.rb +++ b/lib/rspec-puppet-facts.rb @@ -118,11 +118,21 @@ def on_supported_os_implementation(opts = {}) loose_requirement = RspecPuppetFacts::facter_version_to_loose_requirement(facterversion) received_facts = [] + db = FacterDB.get_facts(filter) + 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. filter.each do |filter_spec| - versions = FacterDB.get_facts(filter_spec).to_h { |facts| [Gem::Version.new(facts[:facterversion]), facts] } + versions = JGrep.jgrep(db.to_json, FacterDB.generate_filter_str(filter_spec)) \ + .to_h do |facts| + result = facts.to_h { |k, v| [k.to_sym, v] } + [Gem::Version.new(result[:facterversion]), result] + end version, facts = versions.select { |v, _f| strict_requirement =~ v }.max_by { |v, _f| v }