puppet 6.4.2 → 6.4.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +17 -17
  3. data/ext/solaris/smf/puppet.xml +2 -0
  4. data/lib/hiera/scope.rb +7 -0
  5. data/lib/puppet.rb +1 -1
  6. data/lib/puppet/application/agent.rb +16 -5
  7. data/lib/puppet/application/device.rb +12 -3
  8. data/lib/puppet/application/ssl.rb +2 -0
  9. data/lib/puppet/configurer.rb +1 -1
  10. data/lib/puppet/network/http/factory.rb +5 -0
  11. data/lib/puppet/pops/types/types.rb +5 -3
  12. data/lib/puppet/provider.rb +1 -2
  13. data/lib/puppet/provider/package.rb +2 -0
  14. data/lib/puppet/provider/package/dpkg.rb +15 -2
  15. data/lib/puppet/provider/package/gem.rb +65 -29
  16. data/lib/puppet/provider/package/pip.rb +135 -111
  17. data/lib/puppet/provider/package/pip3.rb +1 -1
  18. data/lib/puppet/provider/package/puppet_gem.rb +1 -1
  19. data/lib/puppet/provider/package/rpm.rb +27 -16
  20. data/lib/puppet/provider/package/yum.rb +1 -1
  21. data/lib/puppet/provider/package_targetable.rb +68 -0
  22. data/lib/puppet/provider/service/upstart.rb +5 -3
  23. data/lib/puppet/provider/user/useradd.rb +16 -13
  24. data/lib/puppet/settings/server_list_setting.rb +9 -0
  25. data/lib/puppet/ssl/host.rb +1 -1
  26. data/lib/puppet/ssl/state_machine.rb +99 -28
  27. data/lib/puppet/type/package.rb +46 -9
  28. data/lib/puppet/util/pidlock.rb +3 -2
  29. data/lib/puppet/util/windows/process.rb +8 -8
  30. data/lib/puppet/util/windows/registry.rb +7 -1
  31. data/lib/puppet/util/windows/user.rb +14 -4
  32. data/lib/puppet/version.rb +1 -1
  33. data/locales/puppet.pot +115 -103
  34. data/man/man5/puppet.conf.5 +2 -2
  35. data/man/man8/puppet-agent.8 +1 -1
  36. data/man/man8/puppet-apply.8 +1 -1
  37. data/man/man8/puppet-catalog.8 +1 -1
  38. data/man/man8/puppet-config.8 +1 -1
  39. data/man/man8/puppet-describe.8 +1 -1
  40. data/man/man8/puppet-device.8 +1 -1
  41. data/man/man8/puppet-doc.8 +1 -1
  42. data/man/man8/puppet-epp.8 +1 -1
  43. data/man/man8/puppet-facts.8 +1 -1
  44. data/man/man8/puppet-filebucket.8 +1 -1
  45. data/man/man8/puppet-generate.8 +1 -1
  46. data/man/man8/puppet-help.8 +1 -1
  47. data/man/man8/puppet-key.8 +1 -1
  48. data/man/man8/puppet-lookup.8 +1 -1
  49. data/man/man8/puppet-man.8 +1 -1
  50. data/man/man8/puppet-module.8 +1 -1
  51. data/man/man8/puppet-node.8 +1 -1
  52. data/man/man8/puppet-parser.8 +1 -1
  53. data/man/man8/puppet-plugin.8 +1 -1
  54. data/man/man8/puppet-report.8 +1 -1
  55. data/man/man8/puppet-resource.8 +1 -1
  56. data/man/man8/puppet-script.8 +1 -1
  57. data/man/man8/puppet-ssl.8 +1 -1
  58. data/man/man8/puppet-status.8 +1 -1
  59. data/man/man8/puppet.8 +2 -2
  60. data/spec/integration/type/package_spec.rb +1 -1
  61. data/spec/integration/util/windows/registry_spec.rb +52 -0
  62. data/spec/integration/util/windows/user_spec.rb +19 -0
  63. data/spec/unit/application/agent_spec.rb +53 -32
  64. data/spec/unit/application/ssl_spec.rb +13 -0
  65. data/spec/unit/configurer_spec.rb +1 -1
  66. data/spec/unit/functions/new_spec.rb +15 -0
  67. data/spec/unit/hiera/scope_spec.rb +7 -0
  68. data/spec/unit/network/http/factory_spec.rb +6 -0
  69. data/spec/unit/provider/package/dpkg_spec.rb +18 -1
  70. data/spec/unit/provider/package/gem_spec.rb +101 -48
  71. data/spec/unit/provider/package/pip3_spec.rb +17 -0
  72. data/spec/unit/provider/package/pip_spec.rb +57 -67
  73. data/spec/unit/provider/package/puppet_gem_spec.rb +22 -6
  74. data/spec/unit/provider/package/rpm_spec.rb +116 -27
  75. data/spec/unit/provider/service/upstart_spec.rb +3 -22
  76. data/spec/unit/settings/server_list_setting_spec.rb +21 -0
  77. data/spec/unit/ssl/state_machine_spec.rb +206 -83
  78. data/spec/unit/util/pidlock_spec.rb +26 -0
  79. metadata +5 -2
@@ -106,6 +106,11 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
106
106
 
107
107
  it_behaves_like 'an ssl action'
108
108
 
109
+ it 'registers OIDs' do
110
+ expect(Puppet::SSL::Oids).to receive(:register_puppet_oids)
111
+ expects_command_to_fail(%r{Failed to submit certificate request})
112
+ end
113
+
109
114
  it 'submits the CSR and saves it locally' do
110
115
  stub_request(:put, %r{puppet-ca/v1/certificate_request/#{name}}).to_return(status: 200)
111
116
  stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 404)
@@ -366,6 +371,14 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
366
371
  ssl.command_line.args << 'bootstrap'
367
372
  end
368
373
 
374
+ it 'registers the OIDs' do
375
+ expect_any_instance_of(Puppet::SSL::StateMachine).to receive(:ensure_client_certificate).and_return(
376
+ double('ssl_context')
377
+ )
378
+ expect(Puppet::SSL::Oids).to receive(:register_puppet_oids)
379
+ expects_command_to_pass
380
+ end
381
+
369
382
  it 'returns an SSLContext with the loaded CA certs, CRLs, private key and client cert' do
370
383
  expect_any_instance_of(Puppet::SSL::StateMachine).to receive(:ensure_client_certificate).and_return(
371
384
  double('ssl_context')
@@ -1005,7 +1005,7 @@ describe Puppet::Configurer do
1005
1005
  @agent.run :catalog => catalog
1006
1006
  end
1007
1007
 
1008
- it "should select a server when provided" do
1008
+ it "should select a server when it receives 200 OK response" do
1009
1009
  Puppet.settings[:server_list] = ["myserver:123"]
1010
1010
  response = Net::HTTPOK.new(nil, 200, 'OK')
1011
1011
  allow(Puppet::Network::HttpPool).to receive(:connection).with('myserver', 123, anything).and_return(double('request', get: response))
@@ -174,6 +174,19 @@ describe 'the new function' do
174
174
  )).to have_resource("Notify[Integer, #{result}]")
175
175
  end
176
176
  end
177
+
178
+ { '0x0G' => :error,
179
+ '08' => :error,
180
+ '10F' => :error,
181
+ '0B2' => :error,
182
+ }.each do |str, result|
183
+ it "errors when given a non Integer compliant string '#{str}'" do
184
+ expect{compile_to_catalog(<<-"MANIFEST"
185
+ $x = Integer.new("#{str}")
186
+ MANIFEST
187
+ )}.to raise_error(Puppet::Error, /invalid value|cannot be converted to Integer/)
188
+ end
189
+ end
177
190
  end
178
191
 
179
192
  context "when radix is explicitly set to 'default' it" do
@@ -307,6 +320,8 @@ describe 'the new function' do
307
320
  { "10" => 10,
308
321
  "010" => 10,
309
322
  "00010" => 10,
323
+ "08" => 8,
324
+ "0008" => 8,
310
325
  }.each do |str, result|
311
326
  it "produces #{result} from the string '#{str}'" do
312
327
  expect(compile_to_catalog(<<-"MANIFEST"
@@ -90,4 +90,11 @@ describe Hiera::Scope do
90
90
  expect(scope.include?("calling_module")).to eq(true)
91
91
  end
92
92
  end
93
+
94
+ describe "#call_function" do
95
+ it "should delegate a call to call_function to the real scope" do
96
+ expect(real).to receive(:call_function).once
97
+ scope.call_function('some_function', [1,2,3])
98
+ end
99
+ end
93
100
  end
@@ -102,6 +102,12 @@ describe Puppet::Network::HTTP::Factory do
102
102
  expect(conn.keep_alive_timeout).to eq(2147483647)
103
103
  end
104
104
 
105
+ it "disables ruby's max retry on 2.5 and up", if: RUBY_VERSION.to_f >= 2.5 do
106
+ conn = create_connection(site)
107
+
108
+ expect(conn.max_retries).to eq(0)
109
+ end
110
+
105
111
  context 'source address' do
106
112
  it 'defaults to system-defined' do
107
113
  conn = create_connection(site)
@@ -221,19 +221,30 @@ describe Puppet::Type.type(:package).provider(:dpkg) do
221
221
  allow(Tempfile).to receive(:open).and_yield(tempfile)
222
222
  end
223
223
 
224
- it "installs first if holding" do
224
+ it "installs first if package is not present and ensure holding" do
225
+
225
226
  allow(provider).to receive(:execute)
227
+ allow(provider).to receive(:package_not_installed?).and_return(true)
226
228
  expect(provider).to receive(:install).once
227
229
  provider.hold
228
230
  end
229
231
 
232
+ it "skips install new package if package is allready installed" do
233
+ allow(provider).to receive(:execute)
234
+ allow(provider).to receive(:package_not_installed?).and_return(false)
235
+ expect(provider).not_to receive(:install)
236
+ provider.hold
237
+ end
238
+
230
239
  it "executes dpkg --set-selections when holding" do
240
+ allow(provider).to receive(:package_not_installed?).and_return(false)
231
241
  allow(provider).to receive(:install)
232
242
  expect(provider).to receive(:execute).with([:dpkg, '--set-selections'], {:failonfail => false, :combine => false, :stdinfile => tempfile.path}).once
233
243
  provider.hold
234
244
  end
235
245
 
236
246
  it "executes dpkg --set-selections when unholding" do
247
+ allow(provider).to receive(:package_not_installed?).and_return(false)
237
248
  allow(provider).to receive(:install)
238
249
  expect(provider).to receive(:execute).with([:dpkg, '--set-selections'], {:failonfail => false, :combine => false, :stdinfile => tempfile.path}).once
239
250
  provider.hold
@@ -275,4 +286,10 @@ describe Puppet::Type.type(:package).provider(:dpkg) do
275
286
  expect(provider).to receive(:dpkg).with("--purge", resource_name)
276
287
  provider.purge
277
288
  end
289
+
290
+ it "raises error if package name is nil" do
291
+ expect {provider.package_not_installed?(nil)}.to raise_error(ArgumentError,"Package name is nil or empty")
292
+ expect {provider.package_not_installed?("")}.to raise_error(ArgumentError,"Package name is nil or empty")
293
+ end
278
294
  end
295
+
@@ -2,7 +2,15 @@ require 'spec_helper'
2
2
 
3
3
  context Puppet::Type.type(:package).provider(:gem) do
4
4
 
5
+ it { is_expected.to be_installable }
6
+ it { is_expected.to be_uninstallable }
7
+ it { is_expected.to be_upgradeable }
8
+ it { is_expected.to be_versionable }
9
+ it { is_expected.to be_install_options }
10
+ it { is_expected.to be_targetable }
11
+
5
12
  let(:provider_gem_cmd) { '/provider/gem' }
13
+ let(:execute_options) { {:failonfail => true, :combine => true, :custom_environment => {"HOME"=>ENV["HOME"]}} }
6
14
 
7
15
  context 'installing myresource' do
8
16
  let(:resource) do
@@ -18,8 +26,6 @@ context Puppet::Type.type(:package).provider(:gem) do
18
26
  provider
19
27
  end
20
28
 
21
- let(:execute_options) { {:failonfail => true, :combine => true, :custom_environment => {"HOME"=>ENV["HOME"]}} }
22
-
23
29
  before :each do
24
30
  resource.provider = provider
25
31
  allow(described_class).to receive(:command).with(:gemcmd).and_return(provider_gem_cmd)
@@ -31,45 +37,45 @@ context Puppet::Type.type(:package).provider(:gem) do
31
37
  end
32
38
 
33
39
  it "should use the path to the gem command" do
34
- allow(described_class).to receive(:which).with(provider_gem_cmd).and_return(provider_gem_cmd)
40
+ allow(described_class).to receive(:validate_command).with(provider_gem_cmd)
35
41
  expect(described_class).to receive(:execute).with(be_a(Array), execute_options) { |args| expect(args[0]).to eq(provider_gem_cmd) }.and_return("")
36
42
  provider.install
37
43
  end
38
44
 
39
45
  it "should specify that the gem is being installed" do
40
- expect(described_class).to receive(:execute_gem_command).with(be_a(Array)) { |args| expect(args[0]).to eq("install") }.and_return("")
46
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, be_a(Array)) { |cmd, args| expect(args[0]).to eq("install") }.and_return("")
41
47
  provider.install
42
48
  end
43
49
 
44
50
  it "should specify that --rdoc should not be included when gem version is < 2.0.0" do
45
- expect(described_class).to receive(:execute_gem_command).with(be_a(Array)) { |args| expect(args[1]).to eq("--no-rdoc") }.and_return("")
51
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, be_a(Array)) { |cmd, args| expect(args[1]).to eq("--no-rdoc") }.and_return("")
46
52
  provider.install
47
53
  end
48
54
 
49
55
  it "should specify that --ri should not be included when gem version is < 2.0.0" do
50
- expect(described_class).to receive(:execute_gem_command).with(be_a(Array)) { |args| expect(args[2]).to eq("--no-ri") }.and_return("")
56
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, be_a(Array)) { |cmd, args| expect(args[2]).to eq("--no-ri") }.and_return("")
51
57
  provider.install
52
58
  end
53
59
 
54
60
  it "should specify that --document should not be included when gem version is >= 2.0.0" do
55
61
  allow(provider).to receive(:rubygem_version).and_return('2.0.0')
56
- expect(described_class).to receive(:execute_gem_command).with(be_a(Array)) { |args| expect(args[1]).to eq("--no-document") }.and_return("")
62
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, be_a(Array)) { |cmd, args| expect(args[1]).to eq("--no-document") }.and_return("")
57
63
  provider.install
58
64
  end
59
65
 
60
66
  it "should specify the package name" do
61
- expect(described_class).to receive(:execute_gem_command).with(be_a(Array)) { |args| expect(args[3]).to eq("myresource") }.and_return("")
67
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, be_a(Array)) { |cmd, args| expect(args[3]).to eq("myresource") }.and_return("")
62
68
  provider.install
63
69
  end
64
70
 
65
71
  it "should not append install_options by default" do
66
- expect(described_class).to receive(:execute_gem_command).with(be_a(Array)) { |args| expect(args.length).to eq(4) }.and_return("")
72
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, be_a(Array)) { |cmd, args| expect(args.length).to eq(4) }.and_return("")
67
73
  provider.install
68
74
  end
69
75
 
70
76
  it "should allow setting an install_options parameter" do
71
77
  resource[:install_options] = [ '--force', {'--bindir' => '/usr/bin' } ]
72
- expect(described_class).to receive(:execute_gem_command).with(be_a(Array)) do |args|
78
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, be_a(Array)) do |cmd, args|
73
79
  expect(args[1]).to eq('--force')
74
80
  expect(args[2]).to eq('--bindir=/usr/bin')
75
81
  end.and_return("")
@@ -80,7 +86,7 @@ context Puppet::Type.type(:package).provider(:gem) do
80
86
  context "as a normal file" do
81
87
  it "should use the file name instead of the gem name" do
82
88
  resource[:source] = "/my/file"
83
- expect(described_class).to receive(:execute_gem_command).with(be_a(Array)) { |args| expect(args[3]).to eq("/my/file") }.and_return("")
89
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, array_including("/my/file")).and_return("")
84
90
  provider.install
85
91
  end
86
92
  end
@@ -88,7 +94,7 @@ context Puppet::Type.type(:package).provider(:gem) do
88
94
  context "as a file url" do
89
95
  it "should use the file name instead of the gem name" do
90
96
  resource[:source] = "file:///my/file"
91
- expect(described_class).to receive(:execute_gem_command).with(be_a(Array)) { |args| expect(args[3]).to eq("/my/file") }.and_return("")
97
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, array_including("/my/file")).and_return("")
92
98
  provider.install
93
99
  end
94
100
  end
@@ -103,7 +109,7 @@ context Puppet::Type.type(:package).provider(:gem) do
103
109
  context "as a non-file and non-puppet url" do
104
110
  it "should treat the source as a gem repository" do
105
111
  resource[:source] = "http://host/my/file"
106
- expect(described_class).to receive(:execute_gem_command).with(be_a(Array)) { |args| expect(args[3..5]).to eq(["--source", "http://host/my/file", "myresource"]) }.and_return("")
112
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, be_a(Array)) { |cmd, args| expect(args[3..5]).to eq(["--source", "http://host/my/file", "myresource"]) }.and_return("")
107
113
  provider.install
108
114
  end
109
115
  end
@@ -111,7 +117,7 @@ context Puppet::Type.type(:package).provider(:gem) do
111
117
  context "as a windows path on windows", :if => Puppet::Util::Platform.windows? do
112
118
  it "should treat the source as a local path" do
113
119
  resource[:source] = "c:/this/is/a/path/to/a/gem.gem"
114
- expect(described_class).to receive(:execute_gem_command).with(be_a(Array)) { |args| expect(args[3]).to eq("c:/this/is/a/path/to/a/gem.gem") }.and_return("")
120
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, array_including("c:/this/is/a/path/to/a/gem.gem")).and_return("")
115
121
  provider.install
116
122
  end
117
123
  end
@@ -131,7 +137,7 @@ context Puppet::Type.type(:package).provider(:gem) do
131
137
  #gemlist is used for retrieving both local and remote version numbers, and there are cases
132
138
  # (particularly local) where it makes sense for it to return an array. That doesn't make
133
139
  # sense for '#latest', though.
134
- expect(provider.class).to receive(:gemlist).with({:justme => 'myresource'}).and_return({
140
+ expect(provider.class).to receive(:gemlist).with({:command => provider_gem_cmd, :justme => 'myresource'}).and_return({
135
141
  :name => 'myresource',
136
142
  :ensure => ["3.0"],
137
143
  :provider => :gem,
@@ -142,7 +148,7 @@ context Puppet::Type.type(:package).provider(:gem) do
142
148
  it "should list from the specified source repository" do
143
149
  resource[:source] = "http://foo.bar.baz/gems"
144
150
  expect(provider.class).to receive(:gemlist).
145
- with({:justme => 'myresource', :source => "http://foo.bar.baz/gems"}).
151
+ with({:command => provider_gem_cmd, :justme => 'myresource', :source => "http://foo.bar.baz/gems"}).
146
152
  and_return({
147
153
  :name => 'myresource',
148
154
  :ensure => ["3.0"],
@@ -158,67 +164,67 @@ context Puppet::Type.type(:package).provider(:gem) do
158
164
  end
159
165
 
160
166
  it "should return an empty array when no gems installed" do
161
- expect(described_class).to receive(:execute_gem_command).with(%w{list --local}).and_return("\n")
167
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, %w{list --local}).and_return("\n")
162
168
  expect(described_class.instances).to eq([])
163
169
  end
164
170
 
165
171
  it "should return ensure values as an array of installed versions" do
166
- expect(described_class).to receive(:execute_gem_command).with(%w{list --local}).and_return(<<-HEREDOC.gsub(/ /, ''))
172
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, %w{list --local}).and_return(<<-HEREDOC.gsub(/ /, ''))
167
173
  systemu (1.2.0)
168
174
  vagrant (0.8.7, 0.6.9)
169
175
  HEREDOC
170
176
 
171
177
  expect(described_class.instances.map {|p| p.properties}).to eq([
172
- {:ensure => ["1.2.0"], :provider => :gem, :name => 'systemu'},
173
- {:ensure => ["0.8.7", "0.6.9"], :provider => :gem, :name => 'vagrant'}
178
+ {:name => "systemu", :provider => :gem, :command => provider_gem_cmd, :ensure => ["1.2.0"]},
179
+ {:name => "vagrant", :provider => :gem, :command => provider_gem_cmd, :ensure => ["0.8.7", "0.6.9"]}
174
180
  ])
175
181
  end
176
182
 
177
183
  it "should ignore platform specifications" do
178
- expect(described_class).to receive(:execute_gem_command).with(%w{list --local}).and_return(<<-HEREDOC.gsub(/ /, ''))
184
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, %w{list --local}).and_return(<<-HEREDOC.gsub(/ /, ''))
179
185
  systemu (1.2.0)
180
186
  nokogiri (1.6.1 ruby java x86-mingw32 x86-mswin32-60, 1.4.4.1 x86-mswin32)
181
187
  HEREDOC
182
188
 
183
189
  expect(described_class.instances.map {|p| p.properties}).to eq([
184
- {:ensure => ["1.2.0"], :provider => :gem, :name => 'systemu'},
185
- {:ensure => ["1.6.1", "1.4.4.1"], :provider => :gem, :name => 'nokogiri'}
190
+ {:name => "systemu", :provider => :gem, :command => provider_gem_cmd, :ensure => ["1.2.0"]},
191
+ {:name => "nokogiri", :provider => :gem, :command => provider_gem_cmd, :ensure => ["1.6.1", "1.4.4.1"]}
186
192
  ])
187
193
  end
188
194
 
189
195
  it "should not list 'default: ' text from rubygems''" do
190
- expect(described_class).to receive(:execute_gem_command).with(%w{list --local}).and_return(<<-HEREDOC.gsub(/ /, ''))
196
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, %w{list --local}).and_return(<<-HEREDOC.gsub(/ /, ''))
191
197
  bundler (1.16.1, default: 1.16.0, 1.15.1)
192
198
  HEREDOC
193
199
 
194
200
  expect(described_class.instances.map {|p| p.properties}).to eq([
195
- {:name => 'bundler', :ensure => ["1.16.1", "1.16.0", "1.15.1"], :provider => :gem}
201
+ {:name => "bundler", :provider => :gem, :command => provider_gem_cmd, :ensure => ["1.16.1", "1.16.0", "1.15.1"]}
196
202
  ])
197
203
  end
198
204
 
199
205
  it "should not fail when an unmatched line is returned" do
200
- expect(described_class).to receive(:execute_gem_command).with(%w{list --local}).and_return(File.read(my_fixture('line-with-1.8.5-warning')))
206
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, %w{list --local}).and_return(File.read(my_fixture('line-with-1.8.5-warning')))
201
207
 
202
208
  expect(described_class.instances.map {|p| p.properties}).
203
- to eq([{provider: :gem, ensure: ["0.3.2"], name: "columnize"},
204
- {provider: :gem, ensure: ["1.1.3"], name: "diff-lcs"},
205
- {provider: :gem, ensure: ["0.0.1"], name: "metaclass"},
206
- {provider: :gem, ensure: ["0.10.5"], name: "mocha"},
207
- {provider: :gem, ensure: ["0.8.7"], name: "rake"},
208
- {provider: :gem, ensure: ["2.9.0"], name: "rspec-core"},
209
- {provider: :gem, ensure: ["2.9.1"], name: "rspec-expectations"},
210
- {provider: :gem, ensure: ["2.9.0"], name: "rspec-mocks"},
211
- {provider: :gem, ensure: ["0.9.0"], name: "rubygems-bundler"},
212
- {provider: :gem, ensure: ["1.11.3.3"], name: "rvm"}])
209
+ to eq([{:name=>"columnize", :provider=>:gem, :command => provider_gem_cmd, :ensure=>["0.3.2"]},
210
+ {:name=>"diff-lcs", :provider=>:gem, :command => provider_gem_cmd, :ensure=>["1.1.3"]},
211
+ {:name=>"metaclass", :provider=>:gem, :command => provider_gem_cmd, :ensure=>["0.0.1"]},
212
+ {:name=>"mocha", :provider=>:gem, :command => provider_gem_cmd, :ensure=>["0.10.5"]},
213
+ {:name=>"rake", :provider=>:gem, :command => provider_gem_cmd, :ensure=>["0.8.7"]},
214
+ {:name=>"rspec-core", :provider=>:gem, :command => provider_gem_cmd, :ensure=>["2.9.0"]},
215
+ {:name=>"rspec-expectations", :provider=>:gem, :command => provider_gem_cmd, :ensure=>["2.9.1"]},
216
+ {:name=>"rspec-mocks", :provider=>:gem, :command => provider_gem_cmd, :ensure=>["2.9.0"]},
217
+ {:name=>"rubygems-bundler", :provider=>:gem, :command => provider_gem_cmd, :ensure=>["0.9.0"]},
218
+ {:name=>"rvm", :provider=>:gem, :command => provider_gem_cmd, :ensure=>["1.11.3.3"]}])
213
219
  end
214
220
  end
215
221
 
216
222
  context "listing gems" do
217
223
  context "searching for a single package" do
218
224
  it "searches for an exact match" do
219
- expect(described_class).to receive(:execute_gem_command).with(include('\Abundler\z')).and_return(File.read(my_fixture('gem-list-single-package')))
220
- expected = {:name => 'bundler', :ensure => %w[1.6.2], :provider => :gem}
221
- expect(described_class.gemlist({:justme => 'bundler'})).to eq(expected)
225
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, array_including('\Abundler\z')).and_return(File.read(my_fixture('gem-list-single-package')))
226
+ expected = {:name=>"bundler", :provider=>:gem, :ensure=>["1.6.2"]}
227
+ expect(described_class.gemlist({:command => provider_gem_cmd, :justme => 'bundler'})).to eq(expected)
222
228
  end
223
229
  end
224
230
  end
@@ -294,6 +300,39 @@ context Puppet::Type.type(:package).provider(:gem) do
294
300
  end
295
301
  end
296
302
 
303
+ context 'installing myresource with a target command' do
304
+ let(:resource_gem_cmd) { '/resource/gem' }
305
+
306
+ let(:resource) do
307
+ Puppet::Type.type(:package).new(
308
+ :name => "myresource",
309
+ :ensure => :installed,
310
+ )
311
+ end
312
+
313
+ let(:provider) do
314
+ provider = described_class.new
315
+ provider.resource = resource
316
+ provider
317
+ end
318
+
319
+ before :each do
320
+ resource.provider = provider
321
+ end
322
+
323
+ context "when installing with a target command" do
324
+ before :each do
325
+ allow(described_class).to receive(:which).with(resource_gem_cmd).and_return(resource_gem_cmd)
326
+ end
327
+
328
+ it "should use the path to the other gem" do
329
+ resource::original_parameters[:command] = resource_gem_cmd
330
+ expect(described_class).to receive(:execute_gem_command).with(resource_gem_cmd, be_a(Array)).twice.and_return("")
331
+ provider.install
332
+ end
333
+ end
334
+ end
335
+
297
336
  context 'uninstalling myresource' do
298
337
  let(:resource) do
299
338
  Puppet::Type.type(:package).new(
@@ -308,8 +347,6 @@ context Puppet::Type.type(:package).provider(:gem) do
308
347
  provider
309
348
  end
310
349
 
311
- let(:execute_options) { {:failonfail => true, :combine => true, :custom_environment => {"HOME"=>ENV["HOME"]}} }
312
-
313
350
  before :each do
314
351
  resource.provider = provider
315
352
  allow(described_class).to receive(:command).with(:gemcmd).and_return(provider_gem_cmd)
@@ -317,39 +354,39 @@ context Puppet::Type.type(:package).provider(:gem) do
317
354
 
318
355
  context "when uninstalling" do
319
356
  it "should use the path to the gem command" do
320
- allow(described_class).to receive(:which).with(provider_gem_cmd).and_return(provider_gem_cmd)
357
+ allow(described_class).to receive(:validate_command).with(provider_gem_cmd)
321
358
  expect(described_class).to receive(:execute).with(be_a(Array), execute_options) { |args| expect(args[0]).to eq(provider_gem_cmd) }.and_return("")
322
359
  provider.uninstall
323
360
  end
324
361
 
325
362
  it "should specify that the gem is being uninstalled" do
326
- expect(described_class).to receive(:execute_gem_command).with(be_a(Array)) { |args| expect(args[0]).to eq("uninstall") }.and_return("")
363
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, be_a(Array)) { |cmd, args| expect(args[0]).to eq("uninstall") }.and_return("")
327
364
  provider.uninstall
328
365
  end
329
366
 
330
367
  it "should specify that the relevant executables should be removed without confirmation" do
331
- expect(described_class).to receive(:execute_gem_command).with(be_a(Array)) { |args| expect(args[1]).to eq("--executables") }.and_return("")
368
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, be_a(Array)) { |cmd, args| expect(args[1]).to eq("--executables") }.and_return("")
332
369
  provider.uninstall
333
370
  end
334
371
 
335
372
  it "should specify that all the matching versions should be removed" do
336
- expect(described_class).to receive(:execute_gem_command).with(be_a(Array)) { |args| expect(args[2]).to eq("--all") }.and_return("")
373
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, be_a(Array)) { |cmd, args| expect(args[2]).to eq("--all") }.and_return("")
337
374
  provider.uninstall
338
375
  end
339
376
 
340
377
  it "should specify the package name" do
341
- expect(described_class).to receive(:execute_gem_command).with(be_a(Array)) { |args| expect(args[3]).to eq("myresource") }.and_return("")
378
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, be_a(Array)) { |cmd, args| expect(args[3]).to eq("myresource") }.and_return("")
342
379
  provider.uninstall
343
380
  end
344
381
 
345
382
  it "should not append uninstall_options by default" do
346
- expect(described_class).to receive(:execute_gem_command).with(be_a(Array)) { |args| expect(args.length).to eq(4) }.and_return("")
383
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, be_a(Array)) { |cmd, args| expect(args.length).to eq(4) }.and_return("")
347
384
  provider.uninstall
348
385
  end
349
386
 
350
387
  it "should allow setting an uninstall_options parameter" do
351
388
  resource[:uninstall_options] = [ '--ignore-dependencies', {'--version' => '0.1.1' } ]
352
- expect(described_class).to receive(:execute_gem_command).with(be_a(Array)) do |args|
389
+ expect(described_class).to receive(:execute_gem_command).with(provider_gem_cmd, be_a(Array)) do |cmd, args|
353
390
  expect(args[4]).to eq('--ignore-dependencies')
354
391
  expect(args[5]).to eq('--version=0.1.1')
355
392
  end.and_return('')
@@ -357,4 +394,20 @@ context Puppet::Type.type(:package).provider(:gem) do
357
394
  end
358
395
  end
359
396
  end
397
+
398
+ context 'calculated specificity' do
399
+ context 'when is not defaultfor' do
400
+ subject { described_class.specificity }
401
+ it { is_expected.to eql 1 }
402
+ end
403
+
404
+ context 'when is defaultfor' do
405
+ let(:os) { Facter.value(:operatingsystem) }
406
+ subject do
407
+ described_class.defaultfor(operatingsystem: os)
408
+ described_class.specificity
409
+ end
410
+ it { is_expected.to be > 100 }
411
+ end
412
+ end
360
413
  end