puppet 6.0.9 → 6.0.10

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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +16 -16
  3. data/lib/hiera/scope.rb +7 -0
  4. data/lib/puppet.rb +1 -1
  5. data/lib/puppet/application/device.rb +13 -3
  6. data/lib/puppet/application/ssl.rb +2 -0
  7. data/lib/puppet/configurer.rb +1 -1
  8. data/lib/puppet/network/http/connection.rb +2 -0
  9. data/lib/puppet/network/http/factory.rb +5 -0
  10. data/lib/puppet/pops/types/types.rb +5 -3
  11. data/lib/puppet/provider.rb +1 -2
  12. data/lib/puppet/provider/package.rb +2 -0
  13. data/lib/puppet/provider/package/dpkg.rb +15 -2
  14. data/lib/puppet/provider/package/gem.rb +65 -29
  15. data/lib/puppet/provider/package/pip.rb +135 -111
  16. data/lib/puppet/provider/package/pip3.rb +1 -1
  17. data/lib/puppet/provider/package/puppet_gem.rb +1 -1
  18. data/lib/puppet/provider/package/rpm.rb +27 -16
  19. data/lib/puppet/provider/package/yum.rb +2 -1
  20. data/lib/puppet/provider/package_targetable.rb +68 -0
  21. data/lib/puppet/provider/service/upstart.rb +5 -3
  22. data/lib/puppet/provider/user/useradd.rb +16 -13
  23. data/lib/puppet/settings/server_list_setting.rb +9 -0
  24. data/lib/puppet/ssl/host.rb +0 -11
  25. data/lib/puppet/ssl/validator/default_validator.rb +31 -0
  26. data/lib/puppet/type/package.rb +46 -9
  27. data/lib/puppet/util/pidlock.rb +3 -2
  28. data/lib/puppet/util/windows/process.rb +8 -8
  29. data/lib/puppet/util/windows/registry.rb +7 -1
  30. data/lib/puppet/util/windows/user.rb +14 -4
  31. data/lib/puppet/version.rb +1 -1
  32. data/locales/puppet.pot +83 -79
  33. data/man/man5/puppet.conf.5 +2 -2
  34. data/man/man8/puppet-agent.8 +1 -1
  35. data/man/man8/puppet-apply.8 +1 -1
  36. data/man/man8/puppet-catalog.8 +1 -1
  37. data/man/man8/puppet-config.8 +1 -1
  38. data/man/man8/puppet-describe.8 +1 -1
  39. data/man/man8/puppet-device.8 +1 -1
  40. data/man/man8/puppet-doc.8 +1 -1
  41. data/man/man8/puppet-epp.8 +1 -1
  42. data/man/man8/puppet-facts.8 +1 -1
  43. data/man/man8/puppet-filebucket.8 +1 -1
  44. data/man/man8/puppet-generate.8 +1 -1
  45. data/man/man8/puppet-help.8 +1 -1
  46. data/man/man8/puppet-key.8 +1 -1
  47. data/man/man8/puppet-lookup.8 +1 -1
  48. data/man/man8/puppet-man.8 +1 -1
  49. data/man/man8/puppet-module.8 +1 -1
  50. data/man/man8/puppet-node.8 +1 -1
  51. data/man/man8/puppet-parser.8 +1 -1
  52. data/man/man8/puppet-plugin.8 +1 -1
  53. data/man/man8/puppet-report.8 +1 -1
  54. data/man/man8/puppet-resource.8 +1 -1
  55. data/man/man8/puppet-script.8 +1 -1
  56. data/man/man8/puppet-ssl.8 +1 -1
  57. data/man/man8/puppet-status.8 +1 -1
  58. data/man/man8/puppet.8 +2 -2
  59. data/spec/integration/network/http_pool_spec.rb +120 -0
  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/lib/puppet_spec/https.rb +166 -0
  64. data/spec/unit/application/ssl_spec.rb +5 -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/indirector/resource/ral_spec.rb +1 -0
  69. data/spec/unit/network/http/connection_spec.rb +0 -96
  70. data/spec/unit/network/http/factory_spec.rb +6 -0
  71. data/spec/unit/provider/package/dpkg_spec.rb +18 -1
  72. data/spec/unit/provider/package/gem_spec.rb +101 -48
  73. data/spec/unit/provider/package/pip3_spec.rb +17 -0
  74. data/spec/unit/provider/package/pip_spec.rb +57 -67
  75. data/spec/unit/provider/package/puppet_gem_spec.rb +22 -6
  76. data/spec/unit/provider/package/rpm_spec.rb +116 -27
  77. data/spec/unit/provider/service/upstart_spec.rb +3 -22
  78. data/spec/unit/settings/server_list_setting_spec.rb +21 -0
  79. data/spec/unit/ssl/validator_spec.rb +2 -0
  80. data/spec/unit/util/pidlock_spec.rb +26 -0
  81. metadata +9 -5
  82. data/lib/puppet/rest/client.rb +0 -83
  83. data/spec/unit/rest/client_spec.rb +0 -166
@@ -106,6 +106,12 @@ describe "Puppet::Util::Windows::User", :if => Puppet::Util::Platform.windows? d
106
106
  end
107
107
 
108
108
  describe "logon_user" do
109
+ let(:fLOGON32_PROVIDER_DEFAULT) {0}
110
+ let(:fLOGON32_LOGON_INTERACTIVE) {2}
111
+ let(:fLOGON32_LOGON_NETWORK) {3}
112
+ let(:token) {'test'}
113
+ let(:user) {'test'}
114
+ let(:passwd) {'test'}
109
115
  it "should raise an error when provided with an incorrect username and password" do
110
116
  expect_logon_failure_error {
111
117
  Puppet::Util::Windows::User.logon_user(username, bad_password)
@@ -117,8 +123,21 @@ describe "Puppet::Util::Windows::User", :if => Puppet::Util::Platform.windows? d
117
123
  Puppet::Util::Windows::User.logon_user(username, nil)
118
124
  }
119
125
  end
126
+
127
+ it 'should raise error given that logon returns false' do
128
+
129
+ allow(Puppet::Util::Windows::User).to receive(:logon_user_by_logon_type).with(
130
+ user, passwd, fLOGON32_LOGON_NETWORK, fLOGON32_PROVIDER_DEFAULT, anything).and_return (0)
131
+ allow(Puppet::Util::Windows::User).to receive(:logon_user_by_logon_type).with(
132
+ user, passwd, fLOGON32_LOGON_INTERACTIVE, fLOGON32_PROVIDER_DEFAULT, anything).and_return(0)
133
+
134
+ expect {Puppet::Util::Windows::User.logon_user(user, passwd) {}}
135
+ .to raise_error(Puppet::Util::Windows::Error, /Failed to logon user/)
136
+
137
+ end
120
138
  end
121
139
 
140
+
122
141
  describe "password_is?" do
123
142
  it "should return false given an incorrect username and password" do
124
143
  expect(Puppet::Util::Windows::User.password_is?(username, bad_password)).to be_falsey
@@ -0,0 +1,166 @@
1
+ require 'spec_helper'
2
+ require 'webrick'
3
+
4
+ class PuppetSpec::HTTPSServer
5
+ attr_reader :ca_cert, :ca_crl, :server_cert, :server_key
6
+
7
+ def initialize
8
+ @ca_cert = OpenSSL::X509::Certificate.new(CA_CERT)
9
+ @ca_crl = OpenSSL::X509::CRL.new(CRL)
10
+ @server_key = OpenSSL::PKey::RSA.new(SERVER_KEY)
11
+ @server_cert = OpenSSL::X509::Certificate.new(SERVER_CERT)
12
+ @config = WEBrick::Config::HTTP.dup
13
+ end
14
+
15
+ def handle_request(ctx, ssl)
16
+ req = WEBrick::HTTPRequest.new(@config)
17
+ req.parse(ssl)
18
+
19
+ res = WEBrick::HTTPResponse.new(@config)
20
+ res.status = 200
21
+ res.body = 'OK'
22
+ res.send_response(ssl)
23
+ end
24
+
25
+ def start_server(&block)
26
+ errors = []
27
+
28
+ IO.pipe {|stop_pipe_r, stop_pipe_w|
29
+ store = OpenSSL::X509::Store.new
30
+ store.add_cert(@ca_cert)
31
+ store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
32
+ ctx = OpenSSL::SSL::SSLContext.new
33
+ ctx.cert_store = store
34
+ ctx.cert = @server_cert
35
+ ctx.key = @server_key
36
+ ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
37
+
38
+ Socket.do_not_reverse_lookup = true
39
+ tcps = TCPServer.new("127.0.0.1", 0)
40
+ begin
41
+ port = tcps.connect_address.ip_port
42
+ begin
43
+ server_thread = Thread.new do
44
+ begin
45
+ ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)
46
+ ssls.start_immediately = true
47
+
48
+ loop do
49
+ readable, = IO.select([ssls, stop_pipe_r])
50
+ break if readable.include? stop_pipe_r
51
+
52
+ ssl = ssls.accept
53
+ begin
54
+ handle_request(ctx, ssl)
55
+ ensure
56
+ ssl.close
57
+ end
58
+ end
59
+ rescue => e
60
+ # uncomment this line if something goes wrong
61
+ # puts "SERVER #{e.message}"
62
+ errors << e
63
+ end
64
+ end
65
+
66
+ begin
67
+ yield port
68
+ ensure
69
+ stop_pipe_w.close
70
+ end
71
+ ensure
72
+ server_thread.join
73
+ end
74
+ ensure
75
+ tcps.close
76
+ end
77
+ }
78
+
79
+ errors
80
+ end
81
+
82
+ CA_CERT = <<END
83
+ -----BEGIN CERTIFICATE-----
84
+ MIICMjCCAZugAwIBAgIBADANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
85
+ IENBMB4XDTcwMDEwMTAwMDAwMFoXDTI5MDMwMTIxMzgxMVowEjEQMA4GA1UEAwwH
86
+ VGVzdCBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvPbXy4tgmUZsLx39
87
+ Q7/Fuo5cOVk9yNzwMN4000jZQjAC8DQKXSDkbJ/6MmaiRo+VgwWlEIRVttYjrXF/
88
+ YPKZowbEIaggc9uK96+HLiGiZ0H6rNM7DYsJiCX4OzJ91SOx9qsyJbyNxLbf+IP0
89
+ 961sTQhsRaqLn8vsn8Mv9I87eHsCAwEAAaOBlzCBlDAPBgNVHRMBAf8EBTADAQH/
90
+ MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUlJ+BUoL64NmMn+IAgiLokQqr0zcw
91
+ MQYJYIZIAYb4QgENBCQWIlB1cHBldCBTZXJ2ZXIgSW50ZXJuYWwgQ2VydGlmaWNh
92
+ dGUwHwYDVR0jBBgwFoAUlJ+BUoL64NmMn+IAgiLokQqr0zcwDQYJKoZIhvcNAQEL
93
+ BQADgYEAbIca4hMdGmQvLOnNIQJ+PaMsIQ9ZT6dr+NCvIf1Ass1dEr0qRy7tpyP0
94
+ scgYmnIrOHDoe+ecyvEuG1oDb/6wLCGzD4OJXRsOzqsSCZJ31HkmDircQGpd+XbR
95
+ BxqltBWaWmSBH+e64Himc1HbHRq5xb8JFRMK9dSqiF3DrREMN/A=
96
+ -----END CERTIFICATE-----
97
+ END
98
+
99
+ CRL = <<END
100
+ -----BEGIN X509 CRL-----
101
+ MIIBCjB1AgEBMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMMB1Rlc3QgQ0EXDTcw
102
+ MDEwMTAwMDAwMFoXDTI5MDMwMTIxMzgxMVqgLzAtMB8GA1UdIwQYMBaAFJSfgVKC
103
+ +uDZjJ/iAIIi6JEKq9M3MAoGA1UdFAQDAgEAMA0GCSqGSIb3DQEBCwUAA4GBAK/r
104
+ 2fz+PGgDzu85Od5Tp6jH+3Ons5WURxZzpfveGcG5fgRIG274E5Q1z+Aoj9KW/J5V
105
+ 6FPbuoVEpykTicKKQaALHfryOEaLqIbTPu+94AivOx9RxzHhYPrblvjuDkmVf+fp
106
+ O3/6YKoeOom3FP/ftKdcsx7tGXy8UxCMUaBGVb5J
107
+ -----END X509 CRL-----
108
+ END
109
+
110
+ SERVER_CERT = <<END
111
+ -----BEGIN CERTIFICATE-----
112
+ MIIBvzCCASigAwIBAgIBAzANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
113
+ IENBMB4XDTcwMDEwMTAwMDAwMFoXDTI5MDMwMTIxMzgxMVowFDESMBAGA1UEAwwJ
114
+ MTI3LjAuMC4xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRTWFUYiB9TnI/
115
+ ByjHHWnjnA02ieuczgAgI5CzrlrQCbCiogmsyvLmcKp4zJFVPTC6eG6Xy4sXANcn
116
+ g44l5gr3wcSzYctukk05HSbbdoBK5jjAzMT6al9l4mQdVXmv6dIkPFq27rIEaJTu
117
+ pOPaLn+mq64o2+lhTLLESOxygzOlWQIDAQABoyMwITAfBgNVHREEGDAWggkxMjcu
118
+ MC4wLjGCCTEyNy4wLjAuMjANBgkqhkiG9w0BAQsFAAOBgQCNdGVATsyhgfNHe4K8
119
+ 19Bi80kA6bvrNQ+6dOwNA3bfpOXog3MU+T5+Sv1tlHl7lL+fnTHZkfRzcQhA10Fw
120
+ YdAxLDyDcY4PzgQcWSw7Lu74TLucfzcR+s+MYHAy8XXP002kjCBrSoSMiQPtXF7P
121
+ f/MQaTCXjA8BP6Ldw4wdlODR5A==
122
+ -----END CERTIFICATE-----
123
+ END
124
+
125
+ SERVER_KEY = <<END
126
+ -----BEGIN RSA PRIVATE KEY-----
127
+ MIICXAIBAAKBgQDRTWFUYiB9TnI/ByjHHWnjnA02ieuczgAgI5CzrlrQCbCiogms
128
+ yvLmcKp4zJFVPTC6eG6Xy4sXANcng44l5gr3wcSzYctukk05HSbbdoBK5jjAzMT6
129
+ al9l4mQdVXmv6dIkPFq27rIEaJTupOPaLn+mq64o2+lhTLLESOxygzOlWQIDAQAB
130
+ AoGAYbM9O6aSg+uaaNFut4ODajvt7wdydD+0z0vKwBUjTvk2+rOo0H/r4qW07a6Q
131
+ KLnnhSOyfCkHRDWgOVGviQFZHHVptrxiMA6oiyWUL/CuKjGdDQi+Q1xnuEPh0qEz
132
+ Q5ELkY1amDFS0pQV0LkDOweF4rc57haJcgRFxOz2HQJKeAECQQD0csJ4/sTq7lsg
133
+ ebIFn0kKL/k99H53rUH3XlrnGo9CnVChLe6K9J/4smp98MCre0eSgc9ahNs2c4Fs
134
+ ZpcgT8mVAkEA2zFwDhSXkkcWGmfk2Q/pfj/0OqLcIGTYkvi3sc2uirHb93VOLlvj
135
+ ClM2XwRWeeeiEW+Ev5bLmHVGuK55+h/jtQJAfwTatJB9ti2gwGE79dvs0hRXiK/w
136
+ vzMSIf2vcoLEijLAYOBDIYU3Ur0yxLpDA1gNur0lB74dQlAGolM0mB+deQJBAKBf
137
+ RYsnydY+qI9dYHToTYAPrtOQANq6rjKqQ0yWHpRfmX8ulqsYk78kLu3KMLM0pMF5
138
+ BHlhDUlY1QuerKQy3NkCQENWVz2NfnrrcgXUMHBojONcP3mkkOUocO4Ezm4GAgXO
139
+ L55O+hAtuLYdxmuNPNhT2eyOsJ/pmPntS2k/rp39Hf4=
140
+ -----END RSA PRIVATE KEY-----
141
+ END
142
+
143
+ UNKNOWN_CA = <<END
144
+ -----BEGIN CERTIFICATE-----
145
+ MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G
146
+ A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610
147
+ dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB
148
+ cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx
149
+ MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO
150
+ ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv
151
+ biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6
152
+ c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu
153
+ 0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw
154
+ /HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk
155
+ H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw
156
+ fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1
157
+ neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB
158
+ BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW
159
+ qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta
160
+ YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
161
+ bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna
162
+ NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu
163
+ dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
164
+ -----END CERTIFICATE-----
165
+ END
166
+ end
@@ -105,6 +105,11 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
105
105
 
106
106
  it_behaves_like 'an ssl action'
107
107
 
108
+ it 'registers OIDs' do
109
+ expect(Puppet::SSL::Oids).to receive(:register_puppet_oids)
110
+ expects_command_to_fail(%r{Failed to submit certificate request})
111
+ end
112
+
108
113
  it 'submits the CSR and saves it locally' do
109
114
  stub_request(:get, %r{puppet-ca/v1/certificate_request/#{name}}).to_return(status: 404)
110
115
  stub_request(:put, %r{puppet-ca/v1/certificate_request/#{name}}).to_return(status: 200)
@@ -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(:http_ssl_instance).with('myserver', '123').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
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'puppet/type/user'
2
3
  require 'puppet/indirector/resource/ral'
3
4
 
4
5
  describe "Puppet::Resource::Ral" do
@@ -62,102 +62,6 @@ describe Puppet::Network::HTTP::Connection do
62
62
  end
63
63
  end
64
64
 
65
- shared_examples_for 'ssl verifier' do
66
- include PuppetSpec::Files
67
-
68
- let (:host) { "my_server" }
69
- let (:port) { 8140 }
70
-
71
- # This is terrible, and is doing things that should probably be in spec/lib/puppet_spec/validators.rb,
72
- # but we can't call allow from there.
73
- before(:each) do
74
- allow_any_instance_of(ConstantErrorValidator).to receive(:setup_connection) do |cev, connection|
75
- allow(connection).to receive(:start).and_raise(OpenSSL::SSL::SSLError.new(cev.instance_variable_get(:@fails_with)))
76
- end
77
- end
78
-
79
- before :all do
80
- WebMock.disable!
81
- end
82
-
83
- after :all do
84
- WebMock.enable!
85
- end
86
-
87
- it "should provide a useful error message when one is available and certificate validation fails", :unless => Puppet::Util::Platform.windows? do
88
- connection = Puppet::Network::HTTP::Connection.new(
89
- host, port,
90
- :verify => ConstantErrorValidator.new(:fails_with => 'certificate verify failed',
91
- :error_string => 'shady looking signature'))
92
-
93
- expect do
94
- connection.get('request')
95
- end.to raise_error(Puppet::Error, /certificate verify failed: \[shady looking signature\]/)
96
- end
97
-
98
- it "should provide a helpful error message when hostname was not match with server certificate", :unless => Puppet::Util::Platform.windows? || RUBY_PLATFORM == 'java' do
99
- Puppet[:confdir] = tmpdir('conf')
100
-
101
- connection = Puppet::Network::HTTP::Connection.new(
102
- host, port,
103
- :verify => ConstantErrorValidator.new(
104
- :fails_with => 'hostname was not match with server certificate',
105
- :peer_certs => [Puppet::TestCa.new.generate('not_my_server',
106
- :subject_alt_names => 'DNS:foo,DNS:bar,DNS:baz,DNS:not_my_server')[:cert]]))
107
-
108
- expect do
109
- connection.get('request')
110
- end.to raise_error(Puppet::Error) do |error|
111
- error.message =~ /\AServer hostname 'my_server' did not match server certificate; expected one of (.+)/
112
- expect($1.split(', ')).to match_array(%w[DNS:foo DNS:bar DNS:baz DNS:not_my_server not_my_server])
113
- end
114
- end
115
-
116
- it "should pass along the error message otherwise" do
117
- connection = Puppet::Network::HTTP::Connection.new(
118
- host, port,
119
- :verify => ConstantErrorValidator.new(:fails_with => 'some other message'))
120
-
121
- expect do
122
- connection.get('request')
123
- end.to raise_error(/some other message/)
124
- end
125
-
126
- it "should check all peer certificates for upcoming expiration", :unless => Puppet::Util::Platform.windows? || RUBY_PLATFORM == 'java' do
127
- Puppet[:confdir] = tmpdir('conf')
128
- cert = Puppet::TestCa.new.generate('server',
129
- :subject_alt_names => 'DNS:foo,DNS:bar,DNS:baz,DNS:server')[:cert]
130
-
131
- connection = Puppet::Network::HTTP::Connection.new(
132
- host, port,
133
- :verify => NoProblemsValidator.new(cert))
134
-
135
- allow_any_instance_of(Net::HTTP).to receive(:start)
136
- allow_any_instance_of(Net::HTTP).to receive(:request).and_return(httpok)
137
- allow_any_instance_of(Puppet::Network::HTTP::Pool).to receive(:setsockopts)
138
-
139
- connection.get('request')
140
- end
141
- end
142
-
143
- context "when using single use HTTPS connections", :unless => RUBY_PLATFORM == 'java' do
144
- it_behaves_like 'ssl verifier' do
145
- end
146
- end
147
-
148
- context "when using persistent HTTPS connections", :unless => RUBY_PLATFORM == 'java' do
149
- around :each do |example|
150
- pool = Puppet::Network::HTTP::Pool.new
151
- Puppet.override(:http_pool => pool) do
152
- example.run
153
- end
154
- pool.close
155
- end
156
-
157
- it_behaves_like 'ssl verifier' do
158
- end
159
- end
160
-
161
65
  context "when response is a redirect" do
162
66
  let (:site) { Puppet::Network::HTTP::Site.new('http', 'my_server', 8140) }
163
67
  let (:other_site) { Puppet::Network::HTTP::Site.new('http', 'redirected', 9292) }
@@ -101,6 +101,12 @@ describe Puppet::Network::HTTP::Factory do
101
101
  expect(conn.keep_alive_timeout).to eq(2147483647)
102
102
  end
103
103
 
104
+ it "disables ruby's max retry on 2.5 and up", if: RUBY_VERSION.to_f >= 2.5 do
105
+ conn = create_connection(site)
106
+
107
+ expect(conn.max_retries).to eq(0)
108
+ end
109
+
104
110
  context 'source address' do
105
111
  it 'defaults to system-defined' do
106
112
  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