rspec-puppet-facts 1.9.2 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,6 +2,6 @@ module RspecPuppetFacts
2
2
  # This module contains the current version constant
3
3
  module Version
4
4
  # The current version of this gem
5
- STRING = '1.9.2'
5
+ STRING = '2.0.1'
6
6
  end
7
7
  end
@@ -1,33 +1,31 @@
1
- # -*- encoding: utf-8 -*-
2
- $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
3
- require "rspec-puppet-facts/version"
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path('lib', __dir__)
4
+ require 'rspec-puppet-facts/version'
4
5
 
5
6
  Gem::Specification.new do |s|
6
- s.name = "rspec-puppet-facts"
7
+ s.name = 'rspec-puppet-facts'
7
8
  s.version = RspecPuppetFacts::Version::STRING
8
- s.authors = ["Mickaël Canévet"]
9
- s.email = ["mickael.canevet@camptocamp.com"]
10
- s.homepage = "http://github.com/mcanevet/rspec-puppet-facts"
11
- s.summary = "Standard facts fixtures for Puppet"
12
- s.description = "Contains facts from many Facter version on many Operating Systems"
9
+ s.authors = ['Mickaël Canévet']
10
+ s.email = ['mickael.canevet@camptocamp.com']
11
+ s.homepage = 'http://github.com/mcanevet/rspec-puppet-facts'
12
+ s.summary = 'Standard facts fixtures for Puppet'
13
+ s.description = 'Contains facts from many Facter version on many Operating Systems'
13
14
  s.licenses = 'Apache-2.0'
14
15
 
16
+ # see .travis.yml for the supported ruby versions
17
+ s.required_ruby_version = '>= 2.4.0'
18
+
15
19
  s.files = `git ls-files`.split("\n")
16
20
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
18
22
 
19
- if RUBY_VERSION =~ /^1\./
20
- s.add_development_dependency 'mime-types', '< 3.0'
21
- else
22
- s.add_development_dependency 'mime-types'
23
- end
23
+ s.add_development_dependency 'mime-types'
24
24
  s.add_development_dependency 'coveralls'
25
25
  s.add_development_dependency 'rake'
26
26
  s.add_development_dependency 'rspec'
27
27
  s.add_development_dependency 'yard'
28
28
  s.add_runtime_dependency 'puppet'
29
- s.add_runtime_dependency 'json'
30
29
  s.add_runtime_dependency 'facter'
31
30
  s.add_runtime_dependency 'facterdb', '>= 0.5.0'
32
- s.add_runtime_dependency 'mcollective-client'
33
31
  end
@@ -1,12 +1,176 @@
1
1
  require 'spec_helper'
2
2
  require 'json'
3
+ require 'stringio'
3
4
 
4
5
  describe RspecPuppetFacts do
5
6
  let(:metadata_file) do
6
7
  'spec/fixtures/metadata.json'
7
8
  end
8
9
 
10
+ describe '.facter_version_for_puppet_version' do
11
+ subject(:facter_version) do
12
+ described_class.facter_version_for_puppet_version(puppet_version)
13
+ end
14
+
15
+ let(:component_json_path) do
16
+ File.expand_path(File.join(__dir__, '..', 'ext', 'puppet_agent_components.json'))
17
+ end
18
+
19
+ let(:puppet_version) { Puppet.version }
20
+
21
+ context 'when the component JSON file does not exist' do
22
+ before(:each) do
23
+ allow(File).to receive(:file?).with(component_json_path).and_return(false)
24
+ allow(described_class).to receive(:warning)
25
+ end
26
+
27
+ it 'defaults to the currently installed Facter version' do
28
+ expect(facter_version).to eq(Facter.version)
29
+ end
30
+
31
+ it 'warns the user' do
32
+ msg = /does not exist or is not readable, defaulting to/i
33
+ expect(described_class).to receive(:warning).with(a_string_matching(msg))
34
+ facter_version
35
+ end
36
+ end
37
+
38
+ context 'when the component JSON file is unreadable' do
39
+ before(:each) do
40
+ allow(File).to receive(:readable?).with(component_json_path).and_return(false)
41
+ allow(described_class).to receive(:warning)
42
+ end
43
+
44
+ it 'defaults to the currently installed Facter version' do
45
+ expect(facter_version).to eq(Facter.version)
46
+ end
47
+
48
+ it 'warns the user' do
49
+ msg = /does not exist or is not readable, defaulting to/i
50
+ expect(described_class).to receive(:warning).with(a_string_matching(msg))
51
+ facter_version
52
+ end
53
+ end
54
+
55
+ context 'when the component JSON file is unparseable' do
56
+ before(:each) do
57
+ io = StringIO.new('this is not JSON!')
58
+ allow(File).to receive(:open).with(component_json_path, anything).and_return(io)
59
+ allow(described_class).to receive(:warning)
60
+ end
61
+
62
+ it 'defaults to the currently installed Facter version' do
63
+ expect(facter_version).to eq(Facter.version)
64
+ end
65
+
66
+ it 'warns the user' do
67
+ msg = /contains invalid json, defaulting to/i
68
+ expect(described_class).to receive(:warning).with(a_string_matching(msg))
69
+ facter_version
70
+ end
71
+ end
72
+
73
+ context 'when the passed puppet_version is nil' do
74
+ let(:puppet_version) { nil }
75
+
76
+ it 'defaults to the currently installed Facter version' do
77
+ expect(facter_version).to eq(Facter.version)
78
+ end
79
+ end
80
+
81
+ context 'when passed a Puppet version greater than any known version' do
82
+ let(:puppet_version) { '999.0.0' }
83
+
84
+ it 'returns the Facter version for the highest known Puppet version' do
85
+ known_facter_versions = JSON.parse(File.read(component_json_path)).map do |_, r|
86
+ r['facter']
87
+ end
88
+ sorted_facter_versions = known_facter_versions.compact.sort do |a, b|
89
+ Gem::Version.new(b) <=> Gem::Version.new(a)
90
+ end
91
+
92
+ expect(facter_version).to eq(sorted_facter_versions.first)
93
+ end
94
+ end
95
+
96
+ context 'when passed a known Puppet version' do
97
+ let(:puppet_version) { '5.2.0' }
98
+
99
+ it 'returns the Facter version for that Puppet version' do
100
+ expect(facter_version).to eq('3.9.0')
101
+ end
102
+ end
103
+
104
+ context 'when passed a Puppet version between two known versions' do
105
+ let(:puppet_version) { '5.2.5' }
106
+
107
+ it 'returns the Facter version for the lower Puppet version' do
108
+ expect(facter_version).to eq('3.9.0')
109
+ end
110
+ end
111
+
112
+ context 'when passed a Puppet version lower than any known version' do
113
+ let(:puppet_version) { '1.0.0' }
114
+
115
+ before(:each) do
116
+ allow(described_class).to receive(:warning)
117
+ end
118
+
119
+ it 'returns the currently installed Facter version' do
120
+ expect(facter_version).to eq(Facter.version)
121
+ end
122
+
123
+ it 'warns the user' do
124
+ msg = /unable to find puppet #{Regexp.escape(puppet_version)}.+?, defaulting to/i
125
+ expect(described_class).to receive(:warning).with(a_string_matching(msg))
126
+ facter_version
127
+ end
128
+ end
129
+ end
130
+
9
131
  describe '#on_supported_os' do
132
+ context 'With RSpec.configuration.facterdb_string_keys' do
133
+ subject(:result) do
134
+ on_supported_os(
135
+ {
136
+ :supported_os => [
137
+ {
138
+ "operatingsystem" => "Debian",
139
+ "operatingsystemrelease" => ['7'],
140
+ },
141
+ ],
142
+ }
143
+ )
144
+ end
145
+
146
+ let(:get_keys) do
147
+ proc { |r| r.keys + r.select { |_,v| v.is_a?(Hash) }.map { |_,v| get_keys.call(v) }.flatten }
148
+ end
149
+
150
+ context 'set to true' do
151
+ before(:each) do
152
+ RSpec.configuration.facterdb_string_keys = true
153
+ end
154
+
155
+ after(:each) do
156
+ RSpec.configuration.facterdb_string_keys = false
157
+ end
158
+
159
+ it 'returns a fact set with all the keys as Strings' do
160
+ expect(get_keys.call(result['debian-7-x86_64'])).to all(be_a(String))
161
+ end
162
+ end
163
+
164
+ context 'set to false' do
165
+ before(:each) do
166
+ RSpec.configuration.facterdb_string_keys = false
167
+ end
168
+
169
+ it 'returns a fact set with all the keys as Symbols or Strings' do
170
+ expect(get_keys.call(result['debian-7-x86_64'])).to all(be_a(Symbol).or(be_a(String)))
171
+ end
172
+ end
173
+ end
10
174
 
11
175
  context 'Without specifying supported_os' do
12
176
  subject { on_supported_os }
@@ -142,6 +306,30 @@ describe RspecPuppetFacts do
142
306
  end
143
307
  end
144
308
 
309
+ context 'When specifying a supported_os with a single release as a String' do
310
+ subject(:factsets) do
311
+ on_supported_os(
312
+ {
313
+ :supported_os => [
314
+ { 'operatingsystem' => 'RedHat', 'operatingsystemrelease' => '7' },
315
+ ]
316
+ }
317
+ )
318
+ end
319
+
320
+ it 'returns a Hash' do
321
+ expect(factsets).to be_a(Hash)
322
+ end
323
+
324
+ it 'returns a single fact set' do
325
+ expect(factsets.size).to eq(1)
326
+ end
327
+
328
+ it 'returns a fact set for the specified release' do
329
+ expect(factsets).to include('redhat-7-x86_64' => include(:operatingsystemmajrelease => '7'))
330
+ end
331
+ end
332
+
145
333
  context 'When testing Ubuntu' do
146
334
  subject {
147
335
  on_supported_os(
@@ -161,17 +349,13 @@ describe RspecPuppetFacts do
161
349
  }
162
350
 
163
351
  let(:expected_fact_sets) do
164
- if Facter.version.to_f < 1.7
165
- ['ubuntu-12.04-x86_64', 'ubuntu-14.04-x86_64']
166
- else
167
- ['ubuntu-12.04-x86_64', 'ubuntu-14.04-x86_64', 'ubuntu-16.04-x86_64']
168
- end
352
+ ['ubuntu-12.04-x86_64', 'ubuntu-14.04-x86_64', 'ubuntu-16.04-x86_64']
169
353
  end
170
354
 
171
355
  it 'should return a hash' do
172
356
  expect(subject.class).to eq Hash
173
357
  end
174
- it 'should have 4 elements' do
358
+ it 'should have 3 elements' do
175
359
  expect(subject.size).to eq(expected_fact_sets.size)
176
360
  end
177
361
  it 'should return supported OS' do
@@ -306,16 +490,19 @@ describe RspecPuppetFacts do
306
490
  'operatingsystemrelease' => release,
307
491
  }
308
492
  ],
493
+ :facterversion => facterversion,
309
494
  }
310
495
  )
311
496
  end
312
497
 
498
+ let(:facterversion) { '3.8.0' }
499
+
313
500
  context 'with a standard release' do
314
501
  let(:release) { ['7'] }
315
502
 
316
503
  it { is_expected.to be_a(Hash) }
317
504
  it { is_expected.to have_attributes(:size => 1) }
318
- it { is_expected.to include('windows-7-x64' => an_instance_of(Hash)) }
505
+ it { is_expected.to include('windows-7-x86_64' => an_instance_of(Hash)) }
319
506
  end
320
507
 
321
508
  context 'with a revision release' do
@@ -323,7 +510,7 @@ describe RspecPuppetFacts do
323
510
 
324
511
  it { is_expected.to be_a(Hash) }
325
512
  it { is_expected.to have_attributes(:size => 1) }
326
- it { is_expected.to include('windows-2012 R2-x64' => an_instance_of(Hash)) }
513
+ it { is_expected.to include('windows-2012 R2-x86_64' => an_instance_of(Hash)) }
327
514
  end
328
515
 
329
516
  context 'with a Server prefixed release' do
@@ -331,7 +518,7 @@ describe RspecPuppetFacts do
331
518
 
332
519
  it { is_expected.to be_a(Hash) }
333
520
  it { is_expected.to have_attributes(:size => 1) }
334
- it { is_expected.to include('windows-2012-x64' => an_instance_of(Hash)) }
521
+ it { is_expected.to include('windows-2012-x86_64' => an_instance_of(Hash)) }
335
522
  end
336
523
 
337
524
  context 'with a 2016 release' do
@@ -339,7 +526,18 @@ describe RspecPuppetFacts do
339
526
 
340
527
  it { is_expected.to be_a(Hash) }
341
528
  it { is_expected.to have_attributes(:size => 1) }
342
- it { is_expected.to include('windows-2016-x64' => an_instance_of(Hash)) }
529
+ it { is_expected.to include('windows-2016-x86_64' => an_instance_of(Hash)) }
530
+ end
531
+
532
+ context 'with a 2016 release and Facter < 3.4' do
533
+ let(:release) { ['2016'] }
534
+ let(:facterversion) { '3.3.0' }
535
+
536
+ it { is_expected.to be_a(Hash) }
537
+ it { is_expected.to have_attributes(:size => 1) }
538
+ it 'munges the operatingsystemmajrelease to 2016' do
539
+ is_expected.to include('windows-2016-x86_64' => an_instance_of(Hash))
540
+ end
343
541
  end
344
542
  end
345
543
 
@@ -420,17 +618,56 @@ describe RspecPuppetFacts do
420
618
  expect(subject.size).to eq 2
421
619
  end
422
620
  it 'should return supported OS' do
423
- expect(subject.keys.sort).to eq %w(
424
- archlinux-3-x86_64
425
- debian-8-x86_64
621
+ expect(subject.keys.sort).to include(a_string_matching(/\Aarchlinux-\d+-x86_64/), 'debian-8-x86_64')
622
+ end
623
+ end
624
+
625
+ context 'When the operatingsystemrelease contains parens' do
626
+ subject do
627
+ on_supported_os(
628
+ {
629
+ :supported_os => [
630
+ {
631
+ 'operatingsystem' => 'IOS',
632
+ 'operatingsystemrelease' => ['12.2(25)EWA9'],
633
+ }
634
+ ],
635
+ }
426
636
  )
427
637
  end
638
+
639
+ before(:each) do
640
+ allow(RspecPuppetFacts).to receive(:warning).with(a_string_matching(/no facts were found/i))
641
+ allow(FacterDB).to receive(:get_facts).and_call_original
642
+ end
643
+
644
+ it 'escapes the parens in the filter' do
645
+ filter = [
646
+ include(
647
+ :operatingsystem => "IOS",
648
+ :operatingsystemrelease => "/^12\\.2\\(25\\)EWA9/",
649
+ :hardwaremodel => "x86_64",
650
+ ),
651
+ ]
652
+
653
+ expect(FacterDB).to receive(:get_facts).with(filter)
654
+ subject
655
+ end
656
+
657
+ it 'does not raise an error' do
658
+ expect { subject }.not_to raise_error
659
+ end
428
660
  end
429
661
 
430
- context 'Without a custom facterversion in the options hash' do
662
+ context 'With a default Facter version specified in the RSpec configuration' do
431
663
  before(:each) do
432
- allow(Facter).to receive(:version).and_return('2.4.5')
664
+ RSpec.configuration.default_facter_version = '3.1.0'
665
+ end
666
+
667
+ after(:each) do
668
+ RSpec.configuration.default_facter_version = Facter.version
433
669
  end
670
+
434
671
  subject do
435
672
  on_supported_os(
436
673
  supported_os: [
@@ -439,10 +676,10 @@ describe RspecPuppetFacts do
439
676
  )
440
677
  end
441
678
 
442
- it 'returns facts from the loaded facter version' do
679
+ it 'returns facts from the specified default Facter version' do
443
680
  is_expected.to match(
444
681
  'centos-7-x86_64' => include(
445
- facterversion: /\A2\.4\./
682
+ :facterversion => /\A3\.1\./
446
683
  )
447
684
  )
448
685
  end
@@ -466,7 +703,7 @@ describe RspecPuppetFacts do
466
703
  major, minor = Facter.version.split('.')
467
704
  is_expected.to match(
468
705
  'centos-7-x86_64' => include(
469
- facterversion: /\A#{major}\.[#{minor}#{minor.to_i + 1}]\./
706
+ :facterversion => /\A#{major}\.[#{minor}#{minor.to_i + 1}]\./
470
707
  )
471
708
  )
472
709
  end
@@ -493,7 +730,7 @@ describe RspecPuppetFacts do
493
730
 
494
731
  it 'returns facts from a facter version matching 3.1' do
495
732
  is_expected.to match(
496
- 'centos-7-x86_64' => include(facterversion: '3.1.6')
733
+ 'centos-7-x86_64' => include(:facterversion => '3.1.6')
497
734
  )
498
735
  end
499
736
  end
@@ -510,7 +747,7 @@ describe RspecPuppetFacts do
510
747
 
511
748
  it 'returns facts from a facter version matching 3.1' do
512
749
  is_expected.to match(
513
- 'centos-7-x86_64' => include(facterversion: '3.1.6')
750
+ 'centos-7-x86_64' => include(:facterversion => '3.1.6')
514
751
  )
515
752
  end
516
753
  end
@@ -527,7 +764,7 @@ describe RspecPuppetFacts do
527
764
 
528
765
  it 'returns facts from a facter version matching 3.3' do
529
766
  is_expected.to match(
530
- 'centos-7-x86_64' => include(facterversion: '3.3.0')
767
+ 'centos-7-x86_64' => include(:facterversion => '3.3.0')
531
768
  )
532
769
  end
533
770
  end
@@ -544,7 +781,24 @@ describe RspecPuppetFacts do
544
781
 
545
782
  it 'returns facts from a facter version matching 3.3' do
546
783
  is_expected.to match(
547
- 'centos-7-x86_64' => include(facterversion: '3.3.0')
784
+ 'centos-7-x86_64' => include(:facterversion => '3.3.0')
785
+ )
786
+ end
787
+ end
788
+
789
+ context 'When querying a fact set that does not have an operatingsystemmajrelease fact' do
790
+ subject do
791
+ on_supported_os(
792
+ supported_os: [
793
+ { 'operatingsystem' => 'SLES', 'operatingsystemrelease' => ['11'] }
794
+ ],
795
+ facterversion: '2.1.0'
796
+ )
797
+ end
798
+
799
+ it 'splits the operatingsystemrelease fact value to get the major release' do
800
+ is_expected.to match(
801
+ 'sles-11-x86_64' => include(:operatingsystemrelease => '11.3')
548
802
  )
549
803
  end
550
804
  end
@@ -564,6 +818,36 @@ describe RspecPuppetFacts do
564
818
  /:facterversion must be in the /)
565
819
  end
566
820
  end
821
+
822
+ context 'Downgrades to a facter version with facts per OS' do
823
+ subject do
824
+ on_supported_os(
825
+ supported_os: [
826
+ { 'operatingsystem' => 'CentOS', 'operatingsystemrelease' => %w[7] },
827
+ { 'operatingsystem' => 'OpenSuSE', 'operatingsystemrelease' => %w[42] }
828
+ ],
829
+ facterversion: '3.9.5'
830
+ )
831
+ end
832
+
833
+ before(:each) do
834
+ allow(FacterDB).to receive(:get_facts).and_call_original
835
+ allow(FacterDB).to receive(:get_facts).with(
836
+ a_hash_including(facterversion: "/\\A3\\.9\\./", operatingsystem: 'CentOS')
837
+ ).and_return([])
838
+ end
839
+
840
+ it 'returns CentOS facts from a facter version matching 3.8' do
841
+ is_expected.to include(
842
+ 'centos-7-x86_64' => include(:facterversion => '3.8.0')
843
+ )
844
+ end
845
+ it 'returns OpenSuSE facts from a facter version matching 3.9' do
846
+ is_expected.to include(
847
+ 'opensuse-42-x86_64' => include(:facterversion => '3.9.2')
848
+ )
849
+ end
850
+ end
567
851
  end
568
852
 
569
853
  context '#add_custom_fact' do
@@ -620,7 +904,7 @@ describe RspecPuppetFacts do
620
904
  it 'should not add "augeasversion" if Augeas is supported' do
621
905
  allow(described_class).to receive(:augeas?).and_return(false)
622
906
  RspecPuppetFacts.reset
623
- expect(subject.common_facts).not_to include :augeasversion
907
+ expect(subject.common_facts).not_to include(:augeasversion)
624
908
  end
625
909
 
626
910
  it 'should determine the Augeas version if Augeas is supported' do
@@ -640,8 +924,31 @@ describe RspecPuppetFacts do
640
924
  expect(subject.common_facts[:augeasversion]).to eq 'my_version'
641
925
  end
642
926
 
643
- it 'can output a warning message' do
644
- expect { RspecPuppetFacts.warning('test') }.to output(/test/).to_stderr_from_any_process
927
+ context 'when mcollective is available' do
928
+ module MCollective_stub
929
+ VERSION = 'my_version'
930
+ end
931
+
932
+ before(:each) do
933
+ allow(described_class).to receive(:mcollective?).and_return(true)
934
+ stub_const('MCollective', MCollective_stub)
935
+ described_class.reset
936
+ end
937
+
938
+ it 'includes an "mco_version" fact' do
939
+ expect(subject.common_facts).to include(:mco_version => 'my_version')
940
+ end
941
+ end
942
+
943
+ context 'when mcollective is not available' do
944
+ before(:each) do
945
+ allow(described_class).to receive(:mcollective?).and_return(false)
946
+ described_class.reset
947
+ end
948
+
949
+ it 'does not include an "mco_version" fact' do
950
+ expect(subject.common_facts).not_to include(:mco_version)
951
+ end
645
952
  end
646
953
  end
647
954