voxpupuli / rspec-puppet-facts Goto Github PK
View Code? Open in Web Editor NEWSimplify your unit tests by looping on every supported Operating System and populating facts.
License: Apache License 2.0
Simplify your unit tests by looping on every supported Operating System and populating facts.
License: Apache License 2.0
There is no normalization within rspec-puppet between legacy and the equivalent structured facts hash. e.g. $operatingsystemmajrelease
and $facts['os']['release']['major']
, thought they contain the same value. Are there any plans to provide those facts in rspec-puppet-facts
?
/cc @rodjek
There is no need to keep json as a dependency as ruby 1.9.3+ now includes the compiled gem.
Whilst trying to downgrade the facter version, rspec-puppet-facts will hang if it can't find a suitable version.
An example from puppet-ipset module.
with
RSpec.configure do |c|
c.default_facter_version = '3.9'
end
and metadata.json
operatingsystem_support: [
{
operatingsystem: Debian,
operatingsystemrelease: [
9,
8,
10
]
},
{
operatingsystem: Ubuntu,
operatingsystemrelease: [
16.04,
18.04
]
},
{
operatingsystem: RedHat,
operatingsystemrelease: [
7,
8
]
},
{
operatingsystem: CentOS,
operatingsystemrelease: [
7,
8
]
},
{
operatingsystem: OracleLinux,
operatingsystemrelease: [
7,
8
]
},
{
operatingsystem: Scientific,
operatingsystemrelease: [
7,
8
]
},
{
operatingsystem: Archlinux
}
],
Adding debug to https://github.com/mcanevet/rspec-puppet-facts/blob/4e07ec47787632ac3e3f8a8330ec074cc4b8905f/lib/rspec-puppet-facts.rb#L113 to print out version
...
"3.9"
"3.8."
"3.7."
"3.6."
"3.5."
"3.4."
"3.3."
"3.2."
"3.1."
"3.0."
"3.-1."
"3.-2."
"3.-3."
"3.-4."
"3.-5."
"3.-6."
^C
The down_facter_version
function is very simplistic. It only checks the minor version and doesn't check that it isn't already 0
.
RPF should error when there are no facts for a supported OS, otherwise people will assume test coverage when there is none.
I think we should have the following line raise an error vs. the default of warning. Warnings usually do not stop pipelines. This gives users a false sense of their code being tested on every OS and Version defined in the metadata.json for the puppet module.
https://github.com/voxpupuli/rspec-puppet-facts/blob/master/lib/rspec-puppet-facts.rb#L145
If you look at the latest builds, ruby 1.8.7 tests are in the allowed_failures group already and now 1.9.3 tests are failing (see #43). You could probably fix this for 1.9.3, somehow, but it's only a stop-gap solution as more and more gems start giving up 1.9 support. I would recommend removing both version entirely, as they provide no benefit due to failing during gem downloads, and only result in slower test completion.
The required_ruby_version should be set in the gemspec at this time as well.
When I try to perform a hiera.lookup
request in a spec, the hierarchy doesn't find the kernel
fact. Because of that, Hiera shows this message:
Ignoring bad definition in :hierarchy: 'kernel/'
And as a result, the data I need is not found.
require "puppetlabs_spec_helper/module_spec_helper"
require "rspec-puppet-facts"
include RspecPuppetFacts
# needed to perform lookups inside specs
require "hiera"
RSpec.configure do |c|
c.default_facts = {
"hostname" => `hostname -f`.strip,
"ipaddress" => `hostname -i`.strip,
"puppetversion" => "4.6.1",
}
c.fail_fast = true if ENV['FAIL_FAST'] == "true"
# needed to evaluate hiera lookups in the puppet code
c.hiera_config = "spec/fixtures/hiera/hiera.yaml"
if ENV['COVERAGE'] == "true"
c.after(:suite) do
RSpec::Puppet::Coverage.report!
end
end
end
# Default to "no" as our specs fail on default facts (i.e. "$::networking")
ENV['STRICT_VARIABLES'] = "no" unless ENV['STRICT_VARIABLES']
:backends:
- yaml
:yaml:
:datadir: spec/fixtures/hiera
:hierarchy:
- "fqdn/%{fqdn}"
- "environment/%{environment}"
- "hostgroup/%{hostgroup}"
- "os/%{operatingsystem}/%{operatingsystemrelease}"
- "os/%{operatingsystem}"
- "kernel/%{kernel}"
- "common"
cron_service: 'cron'
cron_service: 'crond'
class ta_base::linux() {
$cron_service = hiera('cron_service')
service { $cron_service:
enable => true,
ensure => true,
hasrestart => true,
hasstatus => true,
}
}
require "spec_helper"
hiera = Hiera.new(:config => "spec/fixtures/hiera/hiera.yaml")
describe "ta_base::linux" do
on_supported_os.each do |os, facts|
context "on #{os}" do
let(:facts) { facts }
cron_service = hiera.lookup("cron_service", nil, facts)
it { is_expected.to compile.with_all_deps }
it { is_expected.to contain_service(cron_service)
.with(
"enable" => true,
"ensure" => true
)
}
end
end
end
$ SPEC=spec/classes/linux_spec.rb FAIL_FAST=true rake spec_standalone
/home/dunk/.rvm/rubies/ruby-2.3.1/bin/ruby -I/home/dunk/.rvm/gems/ruby-2.3.1@puppet-testing/gems/rspec-core-3.6.0/lib:/home/dunk/.rvm/gems/ruby-2.3.1@puppet-testing/gems/rspec-support-3.6.0/lib/home/dunk/.rvm/gems/ruby-2.3.1@puppet-testing/gems/rspec-core-3.6.0/exe/rspec spec/classes/linux_spec.rb --color
DEBUG: 2017-08-23 17:38:05 -0600: Hiera YAML backend starting
DEBUG: 2017-08-23 17:38:05 -0600: Looking up cron_service in YAML backend
DEBUG: 2017-08-23 17:38:05 -0600: Ignoring bad definition in :hierarchy: 'fqdn/'
DEBUG: 2017-08-23 17:38:05 -0600: Ignoring bad definition in :hierarchy: 'environment/'
DEBUG: 2017-08-23 17:38:05 -0600: Ignoring bad definition in :hierarchy: 'hostgroup/'
DEBUG: 2017-08-23 17:38:05 -0600: Ignoring bad definition in :hierarchy: 'os//'
DEBUG: 2017-08-23 17:38:05 -0600: Ignoring bad definition in :hierarchy: 'os/'
DEBUG: 2017-08-23 17:38:05 -0600: Ignoring bad definition in :hierarchy: 'kernel/'
DEBUG: 2017-08-23 17:38:05 -0600: Looking for data source common
DEBUG: 2017-08-23 17:38:05 -0600: Looking up cron_service in YAML backend
DEBUG: 2017-08-23 17:38:05 -0600: Ignoring bad definition in :hierarchy: 'fqdn/'
DEBUG: 2017-08-23 17:38:05 -0600: Ignoring bad definition in :hierarchy: 'environment/'
DEBUG: 2017-08-23 17:38:05 -0600: Ignoring bad definition in :hierarchy: 'hostgroup/'
DEBUG: 2017-08-23 17:38:05 -0600: Ignoring bad definition in :hierarchy: 'os//'
DEBUG: 2017-08-23 17:38:05 -0600: Ignoring bad definition in :hierarchy: 'os/'
DEBUG: 2017-08-23 17:38:05 -0600: Ignoring bad definition in :hierarchy: 'kernel/'
DEBUG: 2017-08-23 17:38:05 -0600: Looking for data source common
DEBUG: 2017-08-23 17:38:05 -0600: Looking up cron_service in YAML backend
DEBUG: 2017-08-23 17:38:05 -0600: Ignoring bad definition in :hierarchy: 'fqdn/'
DEBUG: 2017-08-23 17:38:05 -0600: Ignoring bad definition in :hierarchy: 'environment/'
DEBUG: 2017-08-23 17:38:05 -0600: Ignoring bad definition in :hierarchy: 'hostgroup/'
DEBUG: 2017-08-23 17:38:05 -0600: Ignoring bad definition in :hierarchy: 'os//'
DEBUG: 2017-08-23 17:38:05 -0600: Ignoring bad definition in :hierarchy: 'os/'
DEBUG: 2017-08-23 17:38:05 -0600: Ignoring bad definition in :hierarchy: 'kernel/'
DEBUG: 2017-08-23 17:38:05 -0600: Looking for data source common
ta_base::linux
on centos-6-x86_64
should compile into a catalogue without dependency cycles
should contain Service[] with enable => true and ensure => true (FAILED - 1)
Failures:
1) ta_base::linux on centos-6-x86_64 should contain Service[] with enable => true and ensure => true
Failure/Error:
it { is_expected.to contain_service(cron_service)
.with(
"enable" => true,
"ensure" => true
)
}
ArgumentError:
No title provided and "Service" is not a valid resource reference
# /home/dunk/.rvm/gems/ruby-2.3.1@puppet-testing/gems/puppet-4.7.0/lib/puppet/resource.rb:572:in `extract_type_and_title'
# /home/dunk/.rvm/gems/ruby-2.3.1@puppet-testing/gems/puppet-4.7.0/lib/puppet/resource.rb:557:in `type_and_title'
# /home/dunk/.rvm/gems/ruby-2.3.1@puppet-testing/gems/puppet-4.7.0/lib/puppet/resource/catalog.rb:355:in `resource'
# /home/dunk/.rvm/gems/ruby-2.3.1@puppet-testing/gems/rspec-puppet-2.6.8/lib/rspec-puppet/matchers/create_generic.rb:85:in `matches?'
# ./spec/classes/linux_spec.rb:17:in `block (4 levels) in <top (required)>'
Finished in 3.93 seconds (files took 4.26 seconds to load)
2 examples, 1 failure
Failed examples:
rspec ./spec/classes/linux_spec.rb[1:1:2] # ta_base::linux on centos-6-x86_64 should contain Service[] with enable => true and ensure => true
/home/dunk/.rvm/rubies/ruby-2.3.1/bin/ruby -I/home/dunk/.rvm/gems/ruby-2.3.1@puppet-testing/gems/rspec-core-3.6.0/lib:/home/dunk/.rvm/gems/ruby-2.3.1@puppet-testing/gems/rspec-support-3.6.0/lib/home/dunk/.rvm/gems/ruby-2.3.1@puppet-testing/gems/rspec-core-3.6.0/exe/rspec spec/classes/linux_spec.rb --color failed
From what I can see, this comes down to the facts
hash having kernel
as a Symbol
instead of a String
, because it properly loads spec/fixtures/hiera/kernel/Linux.yaml
when I do this:
# manifest
facts['kernel'] = "Linux"
cron_service = hiera.lookup("cron_service", nil, facts)
# log output from running test
DEBUG: 2017-08-23 17:39:14 -0600: Looking up cron_service in YAML backend
DEBUG: 2017-08-23 17:39:14 -0600: Ignoring bad definition in :hierarchy: 'fqdn/'
DEBUG: 2017-08-23 17:39:14 -0600: Ignoring bad definition in :hierarchy: 'environment/'
DEBUG: 2017-08-23 17:39:14 -0600: Ignoring bad definition in :hierarchy: 'hostgroup/'
DEBUG: 2017-08-23 17:39:14 -0600: Ignoring bad definition in :hierarchy: 'os//'
DEBUG: 2017-08-23 17:39:14 -0600: Ignoring bad definition in :hierarchy: 'os/'
DEBUG: 2017-08-23 17:39:14 -0600: Looking for data source kernel/Linux
DEBUG: 2017-08-23 17:39:14 -0600: Found cron_service in kernel/Linux
The last 2 lines being the key difference:
Looking for data source kernel/Linux
Found cron_service in kernel/Linux
So....
it seems with 1.0.x e.g. freebsd-10-x86_64
is not showing up in on_supported_os anymore
Metadata.json supports minor OS releases of RedHat
https://docs.puppetlabs.com/puppet/latest/reference/modules_publishing.html#operating-system-compatibility-in-metadatajson
It'd be nice if rspec-puppet-facts could too. :)
If I try to use
"operatingsystem_support": [
{
"operatingsystem": "RedHat",
"operatingsystemrelease":[ "6.5", "6.6", "7.1" ]
}
]
I get
Can't find facts for 'redhat-6.5-x86_64' for facter 2.4, skipping...
Can't find facts for 'redhat-6.6-x86_64' for facter 2.4, skipping...
Can't find facts for 'redhat-7.1-x86_64' for facter 2.4, skipping...
I guess the only fact that would vary between minor releases is "operatingsystemrelease" and "os"
(which is currently set to 6.5 for redhat 6 facts).
See https://travis-ci.org/praekeltfoundation/puppet-gluster/jobs/106945015 for an example of this.
In doing some testing if you lookup %{::memory.system.total_bytes}
it returns null and I believe that is because puppet requires facter and the latest version if 2.5.1 and in that facts set there is no fact for that even though for example 4.10.1
ships with 3.6.4
and it is available in facterdb under 3.6
folder.
I think there either needs to be a facter gem published to support later than 2.5
or some way for rspec-puppet-facts to use the 3.x facts from facterdb
The change done in #72 breaks our CI using Puppet 6:
An error occurred while loading ./spec/classes/vhosts_spec.rb.
Failure/Error:
on_supported_os.each do |os, os_facts|
context "on #{os}" do
let(:facts) { os_facts }
let :pre_condition do
<<-EOF
# Fake assert_private function from stdlib to not fail within this test
function assert_private () { }
include apache
EOF
end
LoadError:
cannot load such file -- augeas
# /usr/local/bundle/gems/rspec-puppet-2.7.1/lib/rspec-puppet/monkey_patches.rb:350:in `require'
# /usr/local/bundle/gems/rspec-puppet-2.7.1/lib/rspec-puppet/monkey_patches.rb:350:in `require'
# /usr/local/bundle/gems/rspec-puppet-facts-1.9.1/lib/rspec-puppet-facts.rb:220:in `common_facts'
# /usr/local/bundle/gems/rspec-puppet-facts-1.9.1/lib/rspec-puppet-facts.rb:134:in `block in on_supported_os'
# /usr/local/bundle/gems/rspec-puppet-facts-1.9.1/lib/rspec-puppet-facts.rb:117:in `map'
# /usr/local/bundle/gems/rspec-puppet-facts-1.9.1/lib/rspec-puppet-facts.rb:117:in `on_supported_os'
# ./spec/classes/vhosts_spec.rb:4:in `block in <top (required)>'
# ./spec/classes/vhosts_spec.rb:3:in `<top (required)>'
That's probably because the rescue doesn't rescue a LoadError
. I will submit a PR for this.
It would be useful if the facts had consistent, known hostnames and domains. This would make it easier to construct tests for manifests using these facts, without having to override/merge these.
I'm trying to apply the following conditional rather than having to rewrite the supported block:
but for some reason this doesn't seem to be working as Ubuntu is still trying to run, I'm sure I'm doing something wrong:
metadata.json
"operatingsystem_support": [
{
"operatingsystem": "CentOS",
"operatingsystemrelease": [
"5",
"6",
"7"
]
},
{
"operatingsystem": "Ubuntu",
"operatingsystemrelease": [
"12.04",
"14.04",
"16.04"
]
}
],
require 'spec_helper'
describe 'profile_base::el' do
context 'supported operating systems' do
on_supported_os.each do |os, facts|
context "on #{os}" do
let(:facts) do
facts.merge({
puppetversion: Puppet.version,
sudoversion: '1.7.10p9'
})
end
if (:osfamily != "Debian") then
context "profile_base::el class without any parameters" do
%w(profile_base::el profile_base::linux
profile_base::nix).each do |puppet_class|
it { should contain_class(puppet_class) }
it { should compile.with_all_deps }
end
end
end
end
end
end
end
Will you accept a pull?
The git tag for https://rubygems.org/gems/rspec-puppet-facts/versions/2.0.1 is missing. @mcanevet can you take a look?
I am using rspec-puppet and it appears that not all supported operating systems are being tested. For example, here is the metadata for one of the modules I am currently testing.
"name": "mdct-dhcpd",
"version": "0.1.0",
"author": "Michael Watters",
"summary": "Installs and configures dhcpd",
"license": "Apache-2.0",
"source": "",
"project_page": null,
"issues_url": null,
"dependencies": [
{"name":"puppetlabs/firewall", "version_requirement": ">= 0.0.4 <= 1.8.1" }
],
"operatingsystem_support": [
{ "operatingsystem":"CentOS", "operatingsystemrelease":[ "7" ] },
{ "operatingsystem":"Fedora", "operatingsystemrelease":[ "20", "21", "22", "23", "24", "25", "26" ] }
],
"data_provider": null
}`
When rake spec is run only Fedora 23-26 are tested.
usr/bin/ruby -I/home/00/d861703/.gem/ruby/gems/rspec-support-3.6.0/lib:/usr/local/share/gems/gems/rspec-core-3.6.0/lib /usr/local/share/gems/gems/rspec-core-3.6.0/exe/rspec --pattern spec/{aliases,classes,defines,unit,functions,hosts,integration,type_aliases,types}/**/*_spec.rb --color
dhcpd
on fedora-23-x86_64
should contain Firewall[105 dhcpd] with dport => "68", proto => "udp" and action => "accept"
should contain Package[dhcp] that comes before File[/etc/dhcp/dhcpd.conf]
should contain File[/etc/dhcp/dhcpd.conf] that requires Package[dhcp]
should contain Service[dhcpd] with ensure => "running" and enable => true
on fedora-22-x86_64
should contain Firewall[105 dhcpd] with dport => "68", proto => "udp" and action => "accept"
should contain Package[dhcp] that comes before File[/etc/dhcp/dhcpd.conf]
should contain File[/etc/dhcp/dhcpd.conf] that requires Package[dhcp]
should contain Service[dhcpd] with ensure => "running" and enable => true
on fedora-25-x86_64
should contain Firewall[105 dhcpd] with dport => "68", proto => "udp" and action => "accept"
should contain Package[dhcp] that comes before File[/etc/dhcp/dhcpd.conf]
should contain File[/etc/dhcp/dhcpd.conf] that requires Package[dhcp]
should contain Service[dhcpd] with ensure => "running" and enable => true
on fedora-24-x86_64
should contain Firewall[105 dhcpd] with dport => "68", proto => "udp" and action => "accept"
should contain Package[dhcp] that comes before File[/etc/dhcp/dhcpd.conf]
should contain File[/etc/dhcp/dhcpd.conf] that requires Package[dhcp]
should contain Service[dhcpd] with ensure => "running" and enable => true
on centos-7-x86_64
should contain Firewall[105 dhcpd] with dport => "68", proto => "udp" and action => "accept"
should contain Package[dhcp] that comes before File[/etc/dhcp/dhcpd.conf]
should contain File[/etc/dhcp/dhcpd.conf] that requires Package[dhcp]
should contain Service[dhcpd] with ensure => "running" and enable => true
Finished in 1.43 seconds (files took 2.37 seconds to load)
20 examples, 0 failures
Is there a way to make tests run on all defined operating systems?
I'm not sure if this is intended or not, but this gem seems to be missing the puppetversion
fact, which has been around since at least Facter 1.6.
I'm currently using the following workaround:
let(:facts) do
facts.merge!({ :puppetversion => ENV['PUPPET_VERSION'] || '3.7.0' })
end
I have the following rspec tests for my functions based on the example in the README:
require 'spec_helper'
describe 'my_function' do
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
on_supported_os.each do |os, facts|
context "on #{os}" do
before :each do
facts.each do |k, v|
scope.stubs(:lookupvar).with("::#{k}").returns(v)
scope.stubs(:lookupvar).with(k.to_s).returns(v)
end
end
it { should run.with_params(...).and_return(...) }
...
end
end
end
This all works fine on Puppet ~> 3.0
but as soon as I try with ~> 4.0
I get errors like this:
x) my_function on centos-6-x86_64
Failure/Error: it { should run.with_params(...).and_return(...) }
NameError:
undefined method `function_my_function' for class `Puppet::Parser::Scope'
If I remove the let(:scope) ...
and associated bits then it works again but obviously lacks the per-OS facts, etc. Is there some additional setup needed for Puppet 4?
Is it possible to set structured facts in the test spec? For example if one needs AWS ec2 metadata as a fact in an rspec test how do you do that? This doesn't seem to work.
let(:facts) do
facts.merge({
:ec2_tag_name => 'vmName-dev-01',
:ec2_tag_env => 'dev',
:ec2_tag_company => 'flux',
:ec2_metadata['public-ipv4'] => '54.1.2.3',
})
end
I'm using the service_provider
fact from the stdlib module in my own modules. Because this fact won't be in facterdb I have to provide values for it. Now, I can do this using add_custom_fact :service_provider, ->(os, facts) { ... }
however at least for this fact, the logic can be quite cumbersome. I also have to duplicate this logic across every module that uses this same fact.
It would be handy if (somehow) a module that provides a custom fact also exports some example values for use in tests split by OS which could then be picked up by rspec-puppet-facts. I'm not sure how it would work, but given every module dependency is available under spec/fixtures/modules/*
during a test run some well-defined location in each module could be used. So stdlib would have example values that on for example, RHEL6, service_provider
is init
, on RHEL7 its systemd
, plus all of the other OS values, etc.
I found voxpupuli/facterdb#49 which is about the package_provider
fact, but it's the same problem.
Hello,
I am using rspec-puppet-facts 2.0.5
and facterdb 1.19.0
on ruby 2.7.6
and Puppet 7.19.0
.
When I try to add or override a Fact in my spec_helper.rb
like so…:
add_custom_fact :blubb, 'blobb'
… then it appears in the Facts-Hash as String "blubb" => "blobb"
instead of as a Symbol :blubb => "blobb"
.
This leads to the Problem, that I cannot override Facts from Facter-DB, because f.e. add_custom_fact :ipaddress => '1.2.3.4'
happens to create the String-Fact "ipaddress" => '1.2.3.4'
besides the previously existing :ipaddress => '10.0.2.15'
instead of overriding it. The same goes for the nested Hash :network
versus "network"
.
Actually it seems to be even worse:
My Rspec-Test throws…:
expected that the catalogue would contain Service_monitoring::Monitor::Host[foo.example.com]
with address set to "10.0.2.15" but it is set to "1.2.3.4"
… because the Rspec-Test picks up the Symbol-Fact…
it 'should export itself as monitoring::host' do
expect(exported_resources).to contain_service_monitoring__monitor__host(node)
.with_address(facts[:networking]['ip'])
end
… and the Puppet-Code picks up the String-Fact:
$agent_ip_address = $::facts['networking']['ip']
I tried to find the Source of this Misbehaviour (IMHO), but even in rspec-puppet-facts.rb
the Symbols stay untouched:
def add_custom_fact(name, value, options = {})
options[:confine] = [options[:confine]] if options[:confine].is_a?(String)
options[:exclude] = [options[:exclude]] if options[:exclude].is_a?(String)
RspecPuppetFacts.register_custom_fact(name, value, options)
end
def self.register_custom_fact(name, value, options)
@custom_facts ||= {}
@custom_facts[name] = {:options => options, :value => value}
end
So I guess either I need some Help about what I am doing wrong, or I spotted kind of a Bug.
Just curious why the mcollective client is required.
If I want to create a test block using on_supported_os
with only one os release, I still have to make the filter an array instead of a single string which I would expect to work, as other filters like operatingsystem
work with a string.
Example that doesn't work:
on_supported_os({
:supported_os => [ {
'operatingsystem' => 'RedHat',
'operatingsystemrelease' => '5',
} ]
}).each do ...
Example that actually works:
on_supported_os({
:supported_os => [ {
'operatingsystem' => 'RedHat',
'operatingsystemrelease' => ['5'],
} ]
}).each do ...
#103 greatly improves performance. It would be great if this could make it into a release.
The hardwaremodule fact changed between facter versions 2.x and 3.x. This is causing a failure to lookup windows systems in FacterDB when the facterversion is set to the 3.x version.
Facterversion 3.x (hardwaremodel => 'x86_64')
https://github.com/camptocamp/facterdb/blob/master/facts/3.5/windows-2012%20r2-x86_64.facts#L21
Facterversion 2.x (hardwaremodel => '64')
https://github.com/camptocamp/facterdb/blob/master/facts/2.5/windows-2012%20r2-x86_64.facts#L7
https://github.com/mcanevet/rspec-puppet-facts/blob/master/lib/rspec-puppet-facts.rb#L64
Because we hardcode x64 regardless of facter versions failures to lookup will fail.
Additionally
hardwaremodel = version =~ /^[12]\./ ? 'x64' : 'x86_64'
is not tied to a windows release and should be bound to the facterversion instead of the windows version. This causes another issue where windows 2012 systems with facterversion of 3.x would never be found either.
Supported OS entries in metadata.json which don't match any facts are simply silently not tested. This could happen when the user has a typo in the OS name or in any of the OS release names, or if FacterDB has not yet been populated with facts for the given OS name and release.
For example, given a semantically correct support matrix like so:
"operatingsystem_support": [
{
"operatingsystem": "CentOS",
"operatingsystemrelease": ["6", "7"]
}
]
on_supported_os
could have 0, 1 or 2 entries depending on Facter version and FacterDB parity. Thus with the recommended use pattern for on_supported_os
, it's possible that no testing occurs at all, or less testing is happening than intended, with at most a warning message in the test result output.
With typos in the support matrix, this problem could happen even with a fully populated FacterDB.
I think rspec-puppet-facts should throw an error if facts for a given OS name and release are not found. I'm guessing this precludes the use of FacterDB.get_facts
, the API of which seems to be the root cause of this issue (or maybe validating its return value is an acceptable solution).
When trying to use a case facts[:osfamily]
like described, I'm getting the following error trying to do a validation:
An error occurred while loading ./spec/classes/libvirt_spec.rb.
Failure/Error: case facts[:osfamily]
`facts` is not available on an example group (e.g. a `describe` or `context` block). It is only available from within individual examples (e.g. `it` blocks) or from constructs that run in the scope of an example (e.g. `before`, `let`, etc).
# ./spec/classes/libvirt_spec.rb:11:in `block (3 levels) in <top (required)>'
# ./spec/classes/libvirt_spec.rb:7:in `block (2 levels) in <top (required)>'
# ./spec/classes/libvirt_spec.rb:6:in `each'
# ./spec/classes/libvirt_spec.rb:6:in `block in <top (required)>'
# ./spec/classes/libvirt_spec.rb:5:in `<top (required)>'
Run options: exclude {:bolt=>true}
Where I'm literally just proceeding as exampled:
describe 'libvirt', type: :class do
on_supported_os.each do |os, os_facts|
context "on #{os}" do
let(:facts) do
os_facts
end
case facts[:osfamily]
when 'Debian'
let :params do
{
package_libvirtd: 'libvirtd',
package_libvirt_devel: 'libvirt-dev'
}
end
it {
is_expected.to contain_package('libvirtd').with(
'ensure' => 'present',
)
}
it {
is_expected.to contain_package('libvirt-dev').with(
'ensure' => 'present',
)
}
it {
is_expected.to contain_package('ruby-libvirt').with(
'ensure' => 'present',
'provider' => 'puppet_gem',
)
}
end
it { is_expected.to compile }
end
end
end
So the documentation would clearly need some form of update as to how to do a OS-specific distinction here.
It appears that the proper way to support Windows variants in metadata.json
, looking at a few puppetlabs examples, is with a string Server <version>[ <release>]
, e.g. Server 2012 R2
. However, this does not result in the OS being added to the on_supported_os
hash. Instead, the string 2012 R2
needs to be used.
Which is correct, and is there a way to normalize that so either string would pick up the windows-2012-r2
collections in facterdb?
It would be great if it was possible to cache the result of on_supported_os, so it runs only once. It is slows a lot of tests and this could greatly improve a lot of rspec tests speed.
#37 covered how to set custom structured facts but this doesn't seem to work when I want to override an existing nested structured fact.
For example, I want to force $facts['os']['selinux']['enabled']
to be true
regardless but it's always false
because that's what is now set in the shipped facts, (fairly sure it used to be true
or unset in previous facterdb releases so it was working by chance).
let(:facts) do
facts.merge({
os: {
selinux: {
enabled: true,
},
},
})
end
I found there is a deep_merge
gem pulled in via Puppet so I tried instead:
let(:facts) do
DeepMerge.deep_merge!(facts, {
os: {
selinux: {
enabled: true,
},
},
})
end
But this gem seems to have odd merge behaviour and won't overwrite existing values.
What's the easiest way to do this?
In the module voxpupuli/puppet-snmp. Tests that previously was passing (with rspec-puppet-facts version 1.9.2), without modification are now failing (with rspec-puppet-facts version 1.9.5).
You can find details about my debug work in issue voxpupuli/puppet-snmp#199.
A more explicit message would really be useful, or it is a bug introduced by 21442e7
With v1.9.0 having better Windows support, it has exposed a possible issue with loading providers.
In the puppet_agent module, running https://github.com/puppetlabs/puppetlabs-puppet_agent/blob/master/spec/classes/puppet_agent_spec.rb with v 1.8.0 of rspec-puppet-facts gem, they pass correctly.
When I run with v1.9.0 I get errrors such as;
8) puppet_agent supported operating systems on ubuntu-16.04-x86_64 puppet_agent class without any parameters should compile into a catalogue without dependency cycles
Failure/Error: it { is_expected.to compile.with_all_deps }
NoMethodError:
undefined method `supports_acl?' for File[sources.list](provider=windows):Puppet::Type::File::ProviderWindows
# /usr/local/bundle/gems/puppet-5.4.0/lib/puppet/provider/file/windows.rb:84:in `validate'
# /usr/local/bundle/gems/puppet-5.4.0/lib/puppet/type/file.rb:394:in `block (2 levels) in <top (required)>'
# /usr/local/bundle/gems/puppet-5.4.0/lib/puppet/type.rb:2402:in `initialize'
# /usr/local/bundle/gems/puppet-5.4.0/lib/puppet/type/file.rb:491:in `initialize'
# /usr/local/bundle/gems/puppet-5.4.0/lib/puppet/resource.rb:461:in `new'
# /usr/local/bundle/gems/puppet-5.4.0/lib/puppet/resource.rb:461:in `to_ral'
# /usr/local/bundle/gems/puppet-5.4.0/lib/puppet/resource/catalog.rb:640:in `block in to_catalog'
# /usr/local/bundle/gems/puppet-5.4.0/lib/puppet/resource/catalog.rb:632:in `each'
# /usr/local/bundle/gems/puppet-5.4.0/lib/puppet/resource/catalog.rb:632:in `to_catalog'
# /usr/local/bundle/gems/puppet-5.4.0/lib/puppet/resource/catalog.rb:513:in `to_ral'
# /usr/local/bundle/gems/rspec-puppet-2.6.9/lib/rspec-puppet/matchers/compile.rb:142:in `cycles_found?'
# /usr/local/bundle/gems/rspec-puppet-2.6.9/lib/rspec-puppet/matchers/compile.rb:25:in `matches?'
# ./spec/classes/puppet_agent_spec.rb:154:in `block (7 levels) in <top (required)>'
Note that it's trying to load the Windows File resource provider.
So what I did was run ONLY ubuntu-16.04-x86_64 tests and they pass. If the Windows tests run prior they fail with error above.
It appears that the first invocation is determining the default provider.
To test this I changed:
https://github.com/puppetlabs/puppetlabs-puppet_agent/blob/master/spec/classes/puppet_agent_spec.rb#L75
to (ubuntu only)
context "on #{os}", :if => (os == 'ubuntu-16.04-x86_64') do
to (windows -> windows -> ubuntu)
context "on #{os}", :if => (os == 'windows-2008 R2-x64' || os == 'windows-2012-x64' || os == 'ubuntu-16.04-x86_64') do
Environment:
Docker on Windows
Linux bdf55e700bbe 4.9.60-linuxkit-aufs #1 SMP Mon Nov 6 16:00:12 UTC 2017 x86_64 GNU/Linux
Puppet facts
root@bdf55e700bbe:/project# bundle exec puppet facts
{
"name": "bdf55e700bbe.gallifrey.local",
"values": {
"puppetversion": "5.4.0",
"kernel": "Linux",
"kernelrelease": "4.9.60-linuxkit-aufs",
"facterversion": "2.5.1",
"partitions": {
"sda1": {
"size": "125827072",
"mount": "/etc/resolv.conf"
}
},
"operatingsystem": "Debian",
"domain": "gallifrey.local",
"operatingsystemmajrelease": "8",
"timezone": "UTC",
"selinux": false,
"uptime_days": 0,
"physicalprocessorcount": 1,
"os": {
"name": "Debian",
"family": "Debian",
"release": {
"major": "8",
"minor": "8",
"full": "8.8"
}
},
"rubyplatform": "x86_64-linux",
"virtual": "docker",
"is_virtual": true,
"architecture": "amd64",
"hardwaremodel": "x86_64",
"uptime_hours": 3,
"processors": {
"models": [
"Intel(R) Core(TM) i7-7560U CPU @ 2.40GHz",
"Intel(R) Core(TM) i7-7560U CPU @ 2.40GHz"
],
"count": 2,
"physicalcount": 1
},
"processor0": "Intel(R) Core(TM) i7-7560U CPU @ 2.40GHz",
"processor1": "Intel(R) Core(TM) i7-7560U CPU @ 2.40GHz",
"processorcount": 2,
"interfaces": "",
"ipaddress": "172.17.0.2",
"osfamily": "Debian",
"operatingsystemrelease": "8.8",
"kernelmajversion": "4.9",
"rubysitedir": "/usr/local/lib/ruby/site_ruby/2.1.0",
"uptime_seconds": 11444,
"fqdn": "bdf55e700bbe.gallifrey.local",
"filesystems": "ext2,ext3,ext4,iso9660,msdos,squashfs,udf,vfat,xfs",
"uniqueid": "11ac0200",
"path": "/usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"blockdevice_sr0_size": 443424768,
"blockdevice_sr0_vendor": "Msft",
"blockdevice_sr0_model": "Virtual DVD-ROM",
"blockdevice_sda_size": 64424509440,
"blockdevice_sda_vendor": "Msft",
"blockdevice_sda_model": "Virtual Disk",
"blockdevice_sr1_size": 174080,
"blockdevice_sr1_vendor": "Msft",
"blockdevice_sr1_model": "Virtual DVD-ROM",
"blockdevices": "sda,sr0,sr1",
"gid": "root",
"system_uptime": {
"seconds": 11444,
"hours": 3,
"days": 0,
"uptime": "3:10 hours"
},
"hostname": "bdf55e700bbe",
"rubyversion": "2.1.10",
"kernelversion": "4.9.60",
"ps": "ps -ef",
"memorysize": "1.93 GB",
"memoryfree": "1.53 GB",
"swapsize": "1024.00 MB",
"swapfree": "1023.83 MB",
"swapsize_mb": "1024.00",
"swapfree_mb": "1023.83",
"memorysize_mb": "1980.77",
"memoryfree_mb": "1565.25",
"hardwareisa": "unknown",
"id": "root",
"uptime": "3:10 hours",
"clientcert": "bdf55e700bbe.gallifrey.local",
"clientversion": "5.4.0",
"clientnoop": false
},
"timestamp": "2018-02-26T06:52:36.884490600+00:00",
"expiration": "2018-02-26T07:22:36.884672700+00:00"
}
I've run into unexpected behavior with respect to Ubuntu operatingsystemreleases. Specifically, rspec-puppet-facts doesn't appear to process all specified minor releases.
Here's the relevant section of metadata.json:
"operatingsystem_support": [
{
"operatingsystem": "Ubuntu",
"operatingsystemrelease": [
"12.04",
"14.04",
"14.10",
"15.04",
"15.10"
]
}
]
I would expect rspec-puppet-facts to iterate through each operatingsystemrelease allowing me to test for run tests for 12.04, 14.04, 14.10, 15.04, 15.10. It's not. Instead I get iterations only on 12.04, 14.10, 15.10. No opportunity to test 14.04 or 15.04 is provided.
It kinda acts like rspec-puppet-facts is doing some kind of filtering on major version (12, 14, 15) such that only one minor version (the largest) is kept. Is this expected behavior?
symbolized facts deprecation
With the release of rspec-puppet-facts 4.0.0 we will remove support for symbolized facts. At the moment people typically use this in their unit files:
case facts[:os]['name']
when 'Archlinux'
context 'on Archlinux' do
it { is_expected.to contain_package('borg') }
end
when 'Ubuntu'
For history reasons the first level of facts were symbols. You will have to update it to strings with the 4.0.0 release:
case facts['os']['name']
when 'Archlinux'
context 'on Archlinux' do
it { is_expected.to contain_package('borg') }
end
when 'Ubuntu'
Currently on_supported_os
collects facts on every invocation. Typically it's called in every file with the same arguments (none). These calls can be slow and the result will be the same anyway. In voxpupuli/voxpupuli-test@5fb4475 I implemented memoization for voxpupuli-test.
Would this be a welcome addition to rspec-puppet-facts itself or should we keep it in voxpupuli-test?
Is lsbdistcodename supported already and I just don't know how to access it?
If lsbdistcodename isn't already supported, is there a way to do some kind of selector in facts.merge like below for RHEL?
let(:facts) do
facts.merge(
case $::operatingsystemmajrelease {
when '6'
:lsbdistcodename => 'Santiago'
when '7'
:lsbdistcodename => 'Maipo'
end
end
In the parlance of Facter 3.6 docs and as far as I can see, this gem only populates legacy facts, but not modern facts.
Are you planing to add support for modern facts? PR welcome?
With either "2012" or "2012 R2" as operatingsystemrelease in metadata.json, unit tests are always run for both entries:
david@davids:~/tmp/testmod$ grep -A3 windows metadata.json
"operatingsystem": "windows",
"operatingsystemrelease": [
"2012 R2"
]
david@davids:~/tmp/testmod$ bundle exec rspec -fd spec/classes/foo_spec.rb
testmod::foo
on debian-8-x86_64
should compile into a catalogue without dependency cycles (FAILED - 1)
on windows-2012-x64
should compile into a catalogue without dependency cycles (FAILED - 2)
on windows-2012 R2-x64
should compile into a catalogue without dependency cycles (FAILED - 3)
on ubuntu-16.04-x86_64
should compile into a catalogue without dependency cycles (FAILED - 4)
I'm attempting to use the add_custom_fact
functionality to add a 'systemd' fact for testing a module that uses 'camptocamp-systemd'.
It would appear that the fact is not being symbolised correctly when testing in rspec.
I've added the following to spec_helper.rb
:
add_custom_fact :systemd, ->(os,facts) {
case facts[:osfamily]
when 'RedHat'
case facts[:operatingsystemmajrelease]
when '5','6'
false
when '7'
true
end
when 'Debian'
case facts[:lsbdistcodename]
when 'jessie'
true
else
false
end
else
false
end
}
But when dumping the 'facts' value from within a rspec test, I get:
{:sshfp_ecdsa=>"SSHFP 3 1 5ac9d8a3d8d21350da19cd71d21b1cb4ddcd32e1\nSSHFP 3 2 31425eee47ed3ae3e968f6bc48ab5a645f899744848d81d768b2ad38b43c289b", :lsbdistrelease=>"12.04", :uptime=>"0:03 hours", :is_virtual=>true, :ipaddress=>"10.0.2.15", :serialnumber=>"0", :manufacturer=>"innotek GmbH", :rubyplatform=>"x86_64-linux", :boardmanufacturer=>"Oracle Corporation", :macaddress_eth0=>"08:00:27:0f:67:ea", :network_eth0=>"10.0.2.0", :blockdevice_sda_vendor=>"ATA", :timezone=>"UTC", :processorcount=>1, :sshfp_rsa=>"SSHFP 1 1 ff2e5147dbd06309221334e95182a2578376b99c\nSSHFP 1 2 a4fa733c8b80d653e1f7bde1a62aa32e7d3b011681ee59bfd014642d8900f744", :domain=>"example.com", :memoryfree_mb=>"432.00", :swapsize_mb=>"512.00", :bios_vendor=>"innotek GmbH", :sshdsakey=>"AAAAB3NzaC1kc3MAAACBAM7xkV/4Q+vcuK0a6af7qVEoc6eSM6GbvFuzoTBV5op14wl0ajkxUlrOdXG0gQDsA+2j+5TyyKkdhD2Wdkkji1cagA1mUJFDcVSVeXipFibBtd7wmGNdbEbCjByL8ZM71AS3y6JywygpoX3k9l+qhuJdc01wwNRV937Md1+zmNF/AAAAFQCPEqcFfYRS0J9qxTkotkDb0ObF8wAAAIEAjteqq8MGXAejpufCbR5BF7992wo/naz6WOi1e5hcE53rQ/3GEBQhN7qEu+79wA1jZs2433xOoK9aA76pXIZs682pf022wDIN/RRa/8pjoH603asbY30NookmyD7CdRKGu1NJW2XgEYHHvypa3d2TEf1/B/zZCEG0Sf0x+MTFwuMAAACBAI3VHzREuRjdt+Pjv2UrXVtbuQYlAuXTzL5k3LPoCJX6bZWxB8ZkBH5TUVY0dm8+Z5jT8uyfOlez8rx6dSb5yCU/xtCYv6od9qvn1bRQGqwME9uRSKUuobu8lDD0sAaeHEhBskPbYQTiFImG51uW5K9uutTR7+sqs1TqWB/czPsw", :bios_release_date=>"12/01/2006", :filesystems=>"ext2,ext3,ext4,vfat", :blockdevice_sr1_vendor=>"VBOX", :memoryfree=>"432.00 MB", :hardwareisa=>"x86_64", :blockdevice_sda_size=>10632560640, :blockdevice_sda_model=>"VBOX HARDDISK", :processor0=>"Intel(R) Core(TM)2 Quad CPU Q6700 @ 2.66GHz", :kernelmajversion=>"3.5", :partitions=>{"sda1"=>{"uuid"=>"0387e66f-2dec-40a0-ac75-d36281af965c", "filesystem"=>"ext2", "mount"=>"/boot", "size"=>"497664"}, "sda2"=>{"size"=>"2"}, "sda5"=>{"filesystem"=>"LVM2_member", "size"=>"20262912"}}, :path=>"/home/vagrant/vendor/bundler/ruby/1.8/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/var/lib/gems/1.8/bin/:/root/.gem/ruby/2.1.0/bin:/usr/lib64/ruby/gems/1.9.1/gems/bundler-1.7.12/bin:/usr/lib64/ruby/gems/2.0.0/gems/bundler-1.7.12/bin", :blockdevice_sr1_size=>1073741312, :productname=>"VirtualBox", :netmask=>"255.255.255.0", :hardwaremodel=>"x86_64", :uptime_days=>0, :virtual=>"virtualbox", :boardserialnumber=>"0", :rubysitedir=>"/Users/gavinw/.rvm/rubies/ruby-1.9.3-p551/lib/ruby/site_ruby/1.9.1", :system_uptime=>{"days"=>0, "seconds"=>197, "hours"=>0, "uptime"=>"0:03 hours"}, :selinux=>false, :sshecdsakey=>"AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLBtSpI6A01NXAodidU0F2aFYsKsZS/w3TQC79BSBiIX7jkr61Sk5U9ui98DJ75yI1cu40m0U1UYyx6ic8YrmCw=", :memorysize=>"491.21 MB", :operatingsystem=>"Ubuntu", :lsbdistid=>"Ubuntu", :gem_version=>"~> 2.4.0", :mtu_lo=>16436, :operatingsystemmajrelease=>"12.04", :os=>{"lsb"=>{"distcodename"=>"precise", "distdescription"=>"Ubuntu 12.04.2 LTS", "distrelease"=>"12.04", "majdistrelease"=>"12.04", "distid"=>"Ubuntu"}, "release"=>{"major"=>"12.04", "full"=>"12.04"}, "name"=>"Ubuntu", "family"=>"Debian"}, :bios_version=>"VirtualBox", :architecture=>"amd64", :lsbdistcodename=>"precise", :blockdevices=>"sda,sr0,sr1", :id=>"root", :kernelrelease=>"3.5.0-23-generic", :ps=>"ps -ef", :lsbmajdistrelease=>"12.04", :ipaddress_lo=>"127.0.0.1", :lsbdistdescription=>"Ubuntu 12.04.2 LTS", :macaddress=>"08:00:27:0f:67:ea", :osfamily=>"Debian", :processors=>{"models"=>["Intel(R) Core(TM)2 Quad CPU Q6700 @ 2.66GHz"], "physicalcount"=>1, "count"=>1}, :netmask_eth0=>"255.255.255.0", :netmask_lo=>"255.0.0.0", :blockdevice_sr0_model=>"CD-ROM", :uptime_hours=>0, :mtu_eth0=>1500, :physicalprocessorcount=>1, :sshfp_dsa=>"SSHFP 2 1 50660f826759a12fe1a9a798418936739b1e41cf\nSSHFP 2 2 d88a5eee3ca9e8c68f668ad7fd21f5feb8b324bd2efaa35b78fcdcf415496279", :facterversion=>"2.4.0", :sshrsakey=>"AAAAB3NzaC1yc2EAAAADAQABAAABAQCXu5RlDOqQ9yghl+U0dkglhOQD6maadTZ34t8KlEwjFnhOx1jpbKVRG2vIJCDusHcIxYPS+uN4owEFbz7l9MtEwCMkzf9fg1imlzRnItAkFtcDZx/jV/PDWcESnTXhc2DRW51IM3pzyHoYThj/cQF4rRDlif1S0H6uj9soJRQi/ftoB62Zkme4j6/GMhY6iJzH3KifTAd3gxaRdp/28/Ym+Q1YZNXAq/BpnNSTEhg9kyHX6M9aTOfZ1K4jqtQaJSiJxZvVZMcWP2lbwIy3NR2uX6D27LK0vd57XOj49R6RjhAnFEKq1Hxa1qOdQrYEeGLuFqMEVwVT6NNuRgFIpyyx", :uuid=>"3C88DC2E-F7DA-4254-9BA4-2E7B341FD7D9", :blockdevice_sr0_vendor=>"VBOX", :type=>"Other", :gid=>"root", :swapfree_mb=>"512.00", :uptime_seconds=>197, :blockdevice_sr0_size=>1073741312, :swapfree=>"512.00 MB", :hostname=>"foo", :kernel=>"Linux", :fqdn=>"foo.example.com", :interfaces=>"eth0,lo", :ipaddress_eth0=>"10.0.2.15", :boardproductname=>"VirtualBox", :memorysize_mb=>"491.21", :swapsize=>"512.00 MB", :uniqueid=>"007f0101", :operatingsystemrelease=>"12.04", :blockdevice_sr1_model=>"CD-ROM", :rubyversion=>"1.9.3", :kernelversion=>"3.5.0", :network_lo=>"127.0.0.0", :mco_version=>"2.9.0", :puppetversion=>"4.7.0", "systemd"=>false}
Note "systemd"=>false
at the end.
In case your module needs a fact to be present (say concat_basedir
), it would greatly simplify life if you could add in globally from spec_helper.rb
.
If I follow the directions at https://github.com/mcanevet/rspec-puppet-facts#specifying-the-supported-operating-systems about specifying a hash to on_supported_os
and use the documented hash format, Rubocop complains about using an obsolete hash format.
require 'spec_helper'
describe 'profiles::packagemanager' do
test_on = {
:supported_os => [
{
'operatingsystem' => 'Ubuntu',
'operatingsystemrelease' => ['18.04', '16.04'],
},
],
}
on_supported_os(test_on).each do |os, os_facts|
let(:facts) do
os_facts
end
context "on #{os} with local=true" do
let :params do
{
'local' => 'true',
'mirror' => 'ftpmirror.ncl.ac.uk',
}
end
# case os_facts[:operatingsystem]
# when 'Ubuntu'
it { is_expected.to compile }
it {
is_expected.to contain_class('apt').with(
'purge' => { 'sources.list' => 'true' },
'update' => { 'frequency' => 'always', 'loglevel' => 'debug' },
)
}
it { is_expected.to contain_exec('apt--f-install') }
it { is_expected.to contain_apt__source('puppetlabs') }
it { is_expected.to contain_apt__source('ubuntu') }
it { is_expected.to contain_apt__source('ubuntu-updates') }
it { is_expected.to contain_apt__source('ubuntu-partner') }
it { is_expected.to contain_apt__source('ubuntu-security') }
it { is_expected.to contain_apt__source('telred') }
it { is_expected.to contain_apt__key('puppetlabs') }
it { is_expected.to contain_apt__key('ubuntu-archive') }
it { is_expected.to contain_apt__key('ubuntu-cdimage') }
it { is_expected.to contain_apt__key('TEL.RED Release Signing Key') }
# end
end
end
end
gives
~/git/PUPPET/puppet5/site/profiles(50-rolesprofiles*) » pdk validate
pdk (INFO): Running all available validators...
pdk (INFO): Using Ruby 2.5.7
pdk (INFO): Using Puppet 6.10.1
[✔] Checking metadata syntax (metadata.json tasks/*.json).
[✔] Checking module metadata style (metadata.json).
[✔] Checking YAML syntax (["**/*.yaml", "*.yaml", "**/*.yml", "*.yml"]).
[✔] Checking Puppet manifest syntax (**/*.pp).
[✔] Checking Puppet manifest style (**/*.pp).
[✖] Checking Ruby code style (**/**.rb).
[✔] Checking task names (tasks/**/*).
info: puppet-epp: ./: Target does not contain any files to validate (**/*.epp).
convention: rubocop: spec/classes/packagemanager_spec.rb:5:5: Style/HashSyntax: Use the new Ruby 1.9 hash syntax.
info: task-metadata-lint: ./: Target does not contain any files to validate (tasks/*.json).
If I update to the newer hash style
test_on = {
supported_os: [
{
'operatingsystem' => 'Ubuntu',
'operatingsystemrelease' => ['18.04', '16.04'],
},
],
}
Then the validator is happy.
Not being particularly fluent in Ruby, I tried to misstate the newer hash style as follows:
test_on = {
supported_os: [
{
operatingsystem: 'Ubuntu',
operatingsystemrelease: ['18.04', '16.04'],
},
],
}
This gave NoMethodError: undefined method `downcase' for nil:NilClass
. Only when I was typing up an issue about the NoMethodError
did I stumble upon the correct hash syntax.
I'll make another merge/pull request later when I'm not in the middle of trying to make my profiles actually work.
Hi, I need to mock the ipaddress and macaddress fact for two tests, here is my a part of my spec file:
require 'spec_helper'
describe 'profiles::base', type: :class do
on_supported_os.each do |os, facts|
context "on #{os} " do
let :facts do
# mocked_facts(facts)
facts
end
context 'the default base profile on all systems' do
it { should compile.with_all_deps }
describe 'we create awesome facts' do
let :facts do
super().merge(
ipaddress: '10.16.254.253',
macaddress: 'AA:BB:CC:DD:EE:FF'
)
end
it do
should contain_file_line('set-ip').with(
path: '/etc/facter/facts.d/sach.txt',
line: 'primary_ip=10.16.254.253'
)
end
it do
should contain_file_line('set-mac').with(
path: '/etc/facter/facts.d/sach.txt',
line: 'primary_mac=AA:BB:CC:DD:EE:FF'
)
end
end
end
end
end
end
This results in:
1) profiles::base on debian-6-x86_64 the default base profile on all systems we create awesome facts should contain File_line[set-ip] with path => "/etc/facter/facts.d/sach.txt" and line => "primary_ip=10.16.254.253"
Failure/Error:
should contain_file_line('set-ip').with(
path: '/etc/facter/facts.d/sach.txt',
line: 'primary_ip=10.16.254.253'
)
expected that the catalogue would contain File_line[set-ip] with line set to "primary_ip=10.16.254.253" but it is set to "primary_ip=10.0.2.15"
# ./spec/classes/base_spec.rb:100:in `block (6 levels) in <top (required)>'
2) profiles::base on debian-6-x86_64 the default base profile on all systems we create awesome facts should contain File_line[set-mac] with path => "/etc/facter/facts.d/sach.txt" and line => "primary_mac=AA:BB:CC:DD:EE:FF"
Failure/Error:
should contain_file_line('set-mac').with(
path: '/etc/facter/facts.d/sach.txt',
line: 'primary_mac=AA:BB:CC:DD:EE:FF'
)
expected that the catalogue would contain File_line[set-mac] with line set to "primary_mac=AA:BB:CC:DD:EE:FF" but it is set to "primary_mac=08:00:27:d9:42:67"
# ./spec/classes/base_spec.rb:106:in `block (6 levels) in <top (required)>'
Instead of super().merge()
I also tried facts.merge()
, which resulted in the same error.
While #122 greatly reduces the expensive calls to on_supported_os
, there are still a lot of calls to FacterDB. Some hot code is here:
Effectively for every filter (which is a tuple of OS and release) it does a call to FacterDB to get facts. If there is not an exact match for the requested Facter version it does another. Then once is has collected all this information, it does one last call to FacterDB to get all the data. Note that this last call is effectively redundant because for every iteration the facts for that filter were already retrieved.
This gives us a worst case complexity of 2n+1
where n is the number of supported OS releases.
The most obvious workaround is to record new facts for every facter release. This would reduce it down to n+1
complexity. However, that means the FacterDB itself will grow which may result in other scaling problems.
Perhaps FacterDB could expose a richer API to allow more effective queries. For example, a lambda to filter a fact. This is not supported by jgrep, but something to think about.
Another consideration is to just query without a facterversion filter and then filter out any unwanted results. Then concat those results.
I have been chatting on Puppet Community slack, asking about why my AIX tests aren't working (aren't running for AIX), and someone pointed me to https://github.com/mcanevet/rspec-puppet-facts/blob/010538181409b159c93e265a4648dd966ae77dfb/lib/rspec-puppet-facts.rb#L58-L66
This should have a case for AIX, but I am not sure what hardwaremodel needs to be set to. I was thinking powerpc
(uname -p) or isa
fact based on what the other operating systems are using. However the "hardwaremodel" fact comes out as something like IBM,8284-22A
which is pretty non-useful. It makes me think that either the hardwaremodel is hopelessly generic on other platforms or its incorrectly populated for AIX. Maybe we could just set the hardware model filter to something like /^IBM/
?
I figured I would start here with a discussion before trying to throw code at it, cause I am soo green when it comes to rspec testing that I am not really sure how to even test this code. :)
NOTE: I recently submitted some facts for reference.
~tommy
AFAICT, the first example in the README is wrong, because at https://github.com/mcanevet/rspec-puppet-facts/blame/master/README.md#L68 it's missing a
let (:facts) { facts }
Thus, the test shouldn't work if the manifest under test is actually using facts. I think this should be fixed, because that's quiet confusing for people using rspec-puppet-facts for the first time.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.