Skip to content

Commit

Permalink
Merge pull request #111 from rodjek/1.10.0-release
Browse files Browse the repository at this point in the history
1.10.0 release
  • Loading branch information
rodjek committed Dec 11, 2019
2 parents 2efad50 + 1903185 commit ead1e88
Show file tree
Hide file tree
Showing 8 changed files with 325 additions and 45 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ sudo: false
cache: bundler
script:
- bundle exec rake spec
- bundle exec rake puppet_versions:test
- bundle exec rake build
rvm:
- 2.1
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 2019-12-11 - Release 1.10.0
- Automatically select the default Facter version based on the Puppet version.
The available Puppet version is matched against a mapping of Puppet and
Facter versions included in the `puppet-agent` all-in-one packages to find
the most suitable Facter version.

## 2019-07-31 - Release 1.9.6
- Suppress the warning message generated when the Augeas gem is not available.
- Searching through older Facter releases for a fact set that does not exist no
Expand Down
101 changes: 85 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,27 @@ describe 'myclass::debian' do
],
}

on_supported_os(test_on).each do |os, facts|
let (:facts) { facts }
on_supported_os(test_on).each do |os, os_facts|
let (:facts) { os_facts }
it { is_expected.to compile.with_all_deps }
end
end
```
Ruby 1.9 and later:
```ruby
require 'spec_helper'

describe 'myclass::raspbian' do
test_on = {
supported_os: [
{
'operatingsystem' => 'Debian',
'operatingsystemrelease' => ['10', '9', '8'],
},
],
}
on_supported_os(test_on).each do |os, os_facts|
let(:facts) { os_facts }
it { is_expected.to compile.with_all_deps }
end
end
Expand Down Expand Up @@ -139,17 +158,17 @@ require 'spec_helper'

describe 'myclass' do

on_supported_os.each do |os, facts|
on_supported_os.each do |os, os_facts|
context "on #{os}" do
let(:facts) do
facts
os_facts
end

it { is_expected.to compile.with_all_deps }
...

# If you need any to specify any operating system specific tests
case facts[:osfamily]
case os_facts[:osfamily]
when 'Debian'
...
else
Expand All @@ -160,6 +179,56 @@ describe 'myclass' do
end
```

When using roles and profiles to manage a heterogeneous IT estate, you can test a profile that supports several OSes with many `let(:facts)` as long as each is in its own context:
```ruby
require 'spec_helper'

describe 'profiles::packagerepos' do
context 'Raspbian tests' do # We manage hundreds of desk-mounted Pis
raspbian = {
hardwaremodels: ['armv7l'],
supported_os: [
{
'operatingsystem' => 'Debian',
'operatingsystemrelease' => ['10', '9', '8'],
},
],
}
on_supported_os(raspbian).each do |os, os_facts|
let(:facts) do
os_facts
end

context "#{os} with defaults" do
it { is_expected.to compile }
# more tests ...
end
end
end
context 'Ubuntu tests' do # And also a fleet of Ubuntu desktops
ubuntu = {
supported_os: [
{
'operatingsystem' => 'Ubuntu',
'operatingsystemrelease' => ['18.04', '16.04'],
},
],
}

on_supported_os(ubuntu).each do |os, os_facts|
let(:facts) do
os_facts
end

context "#{os} with defaults" do
it { is_expected.to compile }
# more tests ...
end
end
end
end
```

### Testing a type or provider

Use `on_supported_os` in the same way for your type and provider unit tests.
Expand Down Expand Up @@ -207,17 +276,17 @@ require 'spec_helper'

describe 'mytype' do

on_supported_os.each do |os, facts|
on_supported_os.each do |os, os_facts|
context "on #{os}" do
let(:facts) do
facts
os_facts
end

it { should be_valid_type }
...

# If you need to specify any operating system specific tests
case facts[:osfamily]
case os_facts[:osfamily]
when 'Debian'
...
else
Expand Down Expand Up @@ -275,10 +344,10 @@ require 'spec_helper'

describe 'myfunction' do

on_supported_os.each do |os, facts|
on_supported_os.each do |os, os_facts|
context "on #{os}" do
let(:facts) do
facts
os_facts
end

it { should run.with_params('something').and_return('a value') }
Expand Down Expand Up @@ -307,12 +376,12 @@ To override fact values and include additional facts in your tests, merge values
require 'spec_helper'

describe 'myclass' do
on_supported_os.each do |os, facts|
on_supported_os.each do |os, os_facts|
context "on #{os}" do

# Add the 'foo' fact with the value 'bar' to the tests
let(:facts) do
facts.merge({
os_facts.merge({
:foo => 'bar',
})
end
Expand Down Expand Up @@ -368,9 +437,9 @@ To do this, pass a lambda as the value for the custom fact. The lambda is passed
add_custom_fact :root_home, lambda { |os,facts| "/tmp/#{facts['hostname']}" }
```

### Suppling Custom External Facts through FacterDB
### Supplying Custom External Facts through FacterDB
Rspec-puppet-facts uses a gem called facterdb that contains many fact sets of various combinations that are pre generated. Rspec-puppet-facts queries
facterdb to pull out a specific fact set to use when testing.
facterdb to pull out a specific fact set to use when testing.

The default facts are great for many things but there will be times when you need to have custom
fact sets that only make sense in your environment or might contain sensitive information.
Expand All @@ -379,7 +448,7 @@ To supply external facts to facterdb just set the `FACTERDB_SEARCH_PATHS` enviro
paths to your facts.

When separating paths please use the default path separator character supported by your OS.
* Unix/Linux/OSX = `:`
* Unix/Linux/OSX = `:`
* Windows = `;`

This means you will need to supply your own fact sets in addition to the ones contained in facterdb.
Expand Down Expand Up @@ -435,7 +504,7 @@ ENV['FACTERDB_SEARCH_PATHS'] = custom_facts
```
## Running your tests

For most cases, there is no change to how you run your tests. Running `rake spec` will run all the tests against the facts for all the supported operating systems.
For most cases, there is no change to how you run your tests. Running `rake spec` will run all the tests against the facts for all the supported operating systems. If you are developing a module using the [Puppet Development Kit](https://puppet.com/docs/pdk/1.x/pdk_install.html), `pdk test unit` will run all your tests against the supported operating systems listed in `metadata.json`.

If you want to run the tests against the facts for specific operating systems, you can provide a filter in the `SPEC_FACTS_OS` environment variable and only the supported operating systems whose name starts with the specified filter will be used.

Expand Down
33 changes: 33 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
require 'bundler/gem_tasks'

PUPPET_VERSIONS_PATH = File.join(__dir__, 'ext', 'puppet_agent_components.json')

begin
require 'rspec/core/rake_task'
require 'yard'
Expand All @@ -14,3 +16,34 @@ task :dump_commit do
puts "############ Commits since #{last_tag} ######"
puts `git log --pretty=format:"- %s" #{last_tag}..HEAD`
end

namespace :puppet_versions do
task :update do
require 'net/http'
require 'net/https'
require 'uri'

uri = URI.parse('https://forgeapi.puppet.com/private/versions/puppet-agent')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == 'https'

request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
raise unless response.is_a?(Net::HTTPSuccess)

File.open(PUPPET_VERSIONS_PATH, 'wb:UTF-8') do |fd|
fd.write(response.body)
end
end

task :test do
Rake::Task['puppet_versions:update'].invoke

output = `git status --porcelain #{PUPPET_VERSIONS_PATH}`
unless output.strip.empty?
$stderr.puts "#{PUPPET_VERSIONS_PATH} is out of date."
$stderr.puts 'Run the puppet_versions:update task to update it and commit the changes.'
raise
end
end
end
1 change: 1 addition & 0 deletions ext/puppet_agent_components.json

Large diffs are not rendered by default.

46 changes: 41 additions & 5 deletions lib/rspec-puppet-facts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@
require 'facterdb'
require 'json'

RSpec.configure do |c|
c.add_setting :default_facter_version, :default => Facter.version
c.add_setting :facterdb_string_keys, :default => false
end

# The purpose of this module is to simplify the Puppet
# module's RSpec tests by looping through all supported
# OS'es and their facts data which is received from the FacterDB.
Expand Down Expand Up @@ -348,4 +343,45 @@ def self.down_facter_version(version, minor_subtractor = 1)
minor = (minor.to_i - minor_subtractor).to_s
"#{major}.#{minor}.#{z}"
end

def self.facter_version_for_puppet_version(puppet_version)
return Facter.version if puppet_version.nil?

json_path = File.expand_path(File.join(__dir__, '..', 'ext', 'puppet_agent_components.json'))
unless File.file?(json_path) && File.readable?(json_path)
warning "#{json_path} does not exist or is not readable, defaulting to Facter #{Facter.version}"
return Facter.version
end

fd = File.open(json_path, 'rb:UTF-8')
data = JSON.parse(fd.read)

version_map = data.map { |_, versions|
if versions['puppet'].nil? || versions['facter'].nil?
nil
else
[Gem::Version.new(versions['puppet']), versions['facter']]
end
}.compact

puppet_gem_version = Gem::Version.new(puppet_version)
applicable_versions = version_map.select { |p, _| puppet_gem_version >= p }
if applicable_versions.empty?
warning "Unable to find Puppet #{puppet_version} in #{json_path}, defaulting to Facter #{Facter.version}"
return Facter.version
end

applicable_versions.sort { |a, b| b.first <=> a.first }.first.last
rescue JSON::ParserError
warning "#{json_path} contains invalid JSON, defaulting to Facter #{Facter.version}"
Facter.version
ensure
fd.close if fd
end
end

RSpec.configure do |c|
c.add_setting :default_facter_version,
:default => RspecPuppetFacts.facter_version_for_puppet_version(Puppet.version)
c.add_setting :facterdb_string_keys, :default => false
end
2 changes: 1 addition & 1 deletion lib/rspec-puppet-facts/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ module RspecPuppetFacts
# This module contains the current version constant
module Version
# The current version of this gem
STRING = '1.9.6'
STRING = '1.10.0'
end
end

0 comments on commit ead1e88

Please sign in to comment.