puppet 4.1.0 → 4.2.0
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.
- data/ext/osx/puppet.plist +32 -0
- data/ext/redhat/client.init +3 -6
- data/ext/redhat/client.sysconfig +1 -10
- data/ext/suse/client.init +3 -6
- data/ext/systemd/puppet.service +2 -1
- data/lib/puppet.rb +1 -1
- data/lib/puppet/agent.rb +4 -19
- data/lib/puppet/application/apply.rb +22 -6
- data/lib/puppet/configurer.rb +3 -2
- data/lib/puppet/configurer/plugin_handler.rb +6 -2
- data/lib/puppet/face/plugin.rb +7 -14
- data/lib/puppet/forge/repository.rb +1 -2
- data/lib/puppet/indirector/catalog/compiler.rb +4 -3
- data/lib/puppet/indirector/facts/facter.rb +8 -0
- data/lib/puppet/module.rb +17 -12
- data/lib/puppet/network/http/factory.rb +8 -4
- data/lib/puppet/node/environment.rb +11 -7
- data/lib/puppet/parser/ast/pops_bridge.rb +5 -0
- data/lib/puppet/parser/functions/fqdn_rand.rb +2 -2
- data/lib/puppet/parser/scope.rb +39 -13
- data/lib/puppet/pops.rb +1 -0
- data/lib/puppet/pops/evaluator/runtime3_converter.rb +1 -1
- data/lib/puppet/pops/evaluator/runtime3_support.rb +31 -0
- data/lib/puppet/pops/parser/epp_support.rb +4 -2
- data/lib/puppet/property/ensure.rb +1 -1
- data/lib/puppet/provider.rb +5 -0
- data/lib/puppet/provider/augeas/augeas.rb +5 -0
- data/lib/puppet/provider/group/pw.rb +1 -0
- data/lib/puppet/provider/group/windows_adsi.rb +9 -0
- data/lib/puppet/provider/mount/parsed.rb +15 -1
- data/lib/puppet/provider/package.rb +6 -2
- data/lib/puppet/provider/package/gem.rb +16 -0
- data/lib/puppet/provider/package/openbsd.rb +7 -7
- data/lib/puppet/provider/package/pacman.rb +9 -8
- data/lib/puppet/provider/package/pip.rb +1 -1
- data/lib/puppet/provider/package/pip3.rb +18 -0
- data/lib/puppet/provider/package/pkgdmg.rb +4 -2
- data/lib/puppet/provider/package/pkgin.rb +3 -3
- data/lib/puppet/provider/package/rpm.rb +8 -14
- data/lib/puppet/provider/package/yum.rb +5 -4
- data/lib/puppet/provider/service/base.rb +3 -2
- data/lib/puppet/provider/service/bsd.rb +7 -7
- data/lib/puppet/provider/service/debian.rb +2 -1
- data/lib/puppet/provider/service/freebsd.rb +1 -1
- data/lib/puppet/provider/service/systemd.rb +75 -6
- data/lib/puppet/provider/service/upstart.rb +1 -1
- data/lib/puppet/provider/user/pw.rb +1 -0
- data/lib/puppet/resource/catalog.rb +1 -1
- data/lib/puppet/resource/status.rb +9 -0
- data/lib/puppet/resource/type.rb +4 -2
- data/lib/puppet/settings.rb +43 -16
- data/lib/puppet/transaction.rb +27 -13
- data/lib/puppet/type/augeas.rb +1 -0
- data/lib/puppet/type/exec.rb +11 -2
- data/lib/puppet/type/group.rb +9 -1
- data/lib/puppet/type/mount.rb +2 -0
- data/lib/puppet/type/package.rb +13 -2
- data/lib/puppet/type/service.rb +9 -0
- data/lib/puppet/util.rb +8 -3
- data/lib/puppet/util/execution.rb +2 -2
- data/lib/puppet/util/http_proxy.rb +60 -0
- data/lib/puppet/util/log.rb +1 -1
- data/lib/puppet/util/splayer.rb +18 -0
- data/lib/puppet/version.rb +1 -1
- data/spec/fixtures/unit/provider/package/yum/yum-check-update-obsoletes.txt +195 -0
- data/spec/integration/application/apply_spec.rb +72 -30
- data/spec/integration/indirector/facts/facter_spec.rb +38 -0
- data/spec/integration/parser/scope_spec.rb +20 -2
- data/spec/integration/provider/mount_spec.rb +23 -36
- data/spec/integration/transaction_spec.rb +40 -1
- data/spec/integration/type/file_spec.rb +36 -0
- data/spec/integration/type/package_spec.rb +65 -0
- data/spec/lib/matchers/include_in_order.rb +0 -1
- data/spec/lib/puppet_spec/files.rb +14 -0
- data/spec/unit/agent_spec.rb +0 -38
- data/spec/unit/application/apply_spec.rb +13 -0
- data/spec/unit/configurer/plugin_handler_spec.rb +42 -13
- data/spec/unit/configurer_spec.rb +5 -0
- data/spec/unit/face/plugin_spec.rb +33 -4
- data/spec/unit/file_serving/configuration/parser_spec.rb +25 -30
- data/spec/unit/indirector/catalog/compiler_spec.rb +16 -0
- data/spec/unit/indirector/facts/facter_spec.rb +2 -1
- data/spec/unit/module_spec.rb +0 -23
- data/spec/unit/network/http/factory_spec.rb +14 -0
- data/spec/unit/parser/functions/fqdn_rand_spec.rb +6 -2
- data/spec/unit/parser/functions/generate_spec.rb +3 -12
- data/spec/unit/parser/scope_spec.rb +9 -0
- data/spec/unit/pops/evaluator/runtime3_converter_spec.rb +19 -0
- data/spec/unit/pops/evaluator/variables_spec.rb +1 -1
- data/spec/unit/pops/parser/lexer2_spec.rb +35 -3
- data/spec/unit/provider/augeas/augeas_spec.rb +9 -0
- data/spec/unit/provider/group/windows_adsi_spec.rb +5 -0
- data/spec/unit/provider/package/aptrpm_spec.rb +2 -2
- data/spec/unit/provider/package/base_spec.rb +18 -0
- data/spec/unit/provider/package/gem_spec.rb +70 -0
- data/spec/unit/provider/package/pacman_spec.rb +55 -0
- data/spec/unit/provider/package/pip3_spec.rb +257 -0
- data/spec/unit/provider/package/pip_spec.rb +1 -1
- data/spec/unit/provider/package/pkgdmg_spec.rb +18 -0
- data/spec/unit/provider/package/pkgin_spec.rb +23 -13
- data/spec/unit/provider/package/yum_spec.rb +11 -0
- data/spec/unit/provider/service/bsd_spec.rb +130 -0
- data/spec/unit/provider/service/debian_spec.rb +12 -1
- data/spec/unit/provider/service/freebsd_spec.rb +16 -0
- data/spec/unit/provider/service/systemd_spec.rb +84 -7
- data/spec/unit/provider/service/upstart_spec.rb +1 -0
- data/spec/unit/provider/zone/solaris_spec.rb +45 -12
- data/spec/unit/puppet_spec.rb +1 -1
- data/spec/unit/resource/catalog_spec.rb +5 -0
- data/spec/unit/type/mount_spec.rb +8 -0
- data/spec/unit/type/service_spec.rb +5 -0
- data/spec/unit/util/http_proxy_spec.rb +87 -0
- data/spec/unit/util/log_spec.rb +12 -1
- data/spec/unit/util/splayer_spec.rb +45 -0
- metadata +3057 -3035
- checksums.yaml +0 -7
- data/ext/systemd/puppetmaster.service +0 -11
@@ -33,6 +33,15 @@ describe Puppet::Parser::Scope do
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
it "should generate a simple string when inspecting a scope" do
|
37
|
+
expect(@scope.inspect).to eq("Scope()")
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should generate a simple string when inspecting a scope with a resource" do
|
41
|
+
@scope.resource="foo::bar"
|
42
|
+
expect(@scope.inspect).to eq("Scope(foo::bar)")
|
43
|
+
end
|
44
|
+
|
36
45
|
it "should return a scope for use in a test harness" do
|
37
46
|
expect(create_test_scope_for_node("node_name_foo")).to be_a_kind_of(Puppet::Parser::Scope)
|
38
47
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
require 'puppet/pops'
|
5
|
+
require 'puppet/pops/types/type_factory'
|
6
|
+
|
7
|
+
describe 'when converting to 3.x' do
|
8
|
+
it "converts a resource type starting with Class without confusing it with exact match on 'class'" do
|
9
|
+
t = Puppet::Pops::Types::TypeFactory.resource('classroom', 'kermit')
|
10
|
+
converted = Puppet::Pops::Evaluator::Runtime3Converter.instance.catalog_type_to_split_type_title(t)
|
11
|
+
expect(converted).to eql(['classroom', 'kermit'])
|
12
|
+
end
|
13
|
+
|
14
|
+
it "converts a resource type of exactly 'Class'" do
|
15
|
+
t = Puppet::Pops::Types::TypeFactory.resource('class', 'kermit')
|
16
|
+
converted = Puppet::Pops::Evaluator::Runtime3Converter.instance.catalog_type_to_split_type_title(t)
|
17
|
+
expect(converted).to eql(['class', 'kermit'])
|
18
|
+
end
|
19
|
+
end
|
@@ -41,7 +41,7 @@ describe 'Puppet::Pops::Impl::EvaluatorImpl' do
|
|
41
41
|
|
42
42
|
it "access to global names works in local scope" do
|
43
43
|
top_scope_block = block( var('a').set(literal(2)+literal(2)))
|
44
|
-
local_scope_block = block( var('a').set(var('::a')+literal(2)), var('
|
44
|
+
local_scope_block = block( var('a').set(literal(100)), var('b').set(var('::a')+literal(2)), var('b'))
|
45
45
|
expect(evaluate_l(top_scope_block, local_scope_block)).to eq(6)
|
46
46
|
end
|
47
47
|
|
@@ -524,7 +524,7 @@ describe 'Lexer2' do
|
|
524
524
|
[:VARIABLE, "x"],
|
525
525
|
:EQUALS,
|
526
526
|
[:NUMBER, "10"],
|
527
|
-
[:RENDER_STRING, "just text\n"]
|
527
|
+
[:RENDER_STRING, " just text\n"]
|
528
528
|
)
|
529
529
|
end
|
530
530
|
|
@@ -540,7 +540,39 @@ describe 'Lexer2' do
|
|
540
540
|
[:VARIABLE, "x"],
|
541
541
|
:EQUALS,
|
542
542
|
[:NUMBER, "10"],
|
543
|
-
[:RENDER_STRING, "just text\n"]
|
543
|
+
[:RENDER_STRING, " just text\n"]
|
544
|
+
)
|
545
|
+
end
|
546
|
+
|
547
|
+
it 'epp comments strips left whitespace when preceding is right trim' do
|
548
|
+
code = <<-CODE
|
549
|
+
This is <% $x=10 -%>
|
550
|
+
space-before-me-but-not-after <%# This is an epp comment %>
|
551
|
+
just text
|
552
|
+
CODE
|
553
|
+
expect(epp_tokens_scanned_from(code)).to match_tokens2(
|
554
|
+
:EPP_START,
|
555
|
+
[:RENDER_STRING, " This is "],
|
556
|
+
[:VARIABLE, "x"],
|
557
|
+
:EQUALS,
|
558
|
+
[:NUMBER, "10"],
|
559
|
+
[:RENDER_STRING, " space-before-me-but-not-after\n just text\n"]
|
560
|
+
)
|
561
|
+
end
|
562
|
+
|
563
|
+
it 'epp comments strips left whitespace on same line when preceding is not right trim' do
|
564
|
+
code = <<-CODE
|
565
|
+
This is <% $x=10 %>
|
566
|
+
<%# This is an epp comment -%>
|
567
|
+
just text
|
568
|
+
CODE
|
569
|
+
expect(epp_tokens_scanned_from(code)).to match_tokens2(
|
570
|
+
:EPP_START,
|
571
|
+
[:RENDER_STRING, " This is "],
|
572
|
+
[:VARIABLE, "x"],
|
573
|
+
:EQUALS,
|
574
|
+
[:NUMBER, "10"],
|
575
|
+
[:RENDER_STRING, "\n just text\n"]
|
544
576
|
)
|
545
577
|
end
|
546
578
|
|
@@ -555,7 +587,7 @@ describe 'Lexer2' do
|
|
555
587
|
[:VARIABLE, "x"],
|
556
588
|
:EQUALS,
|
557
589
|
[:NUMBER, "10"],
|
558
|
-
[:RENDER_STRING, "<% this is escaped epp %>\n"]
|
590
|
+
[:RENDER_STRING, " <% this is escaped epp %>\n"]
|
559
591
|
)
|
560
592
|
end
|
561
593
|
|
@@ -692,6 +692,15 @@ describe provider_class do
|
|
692
692
|
expect(@provider.execute_changes).to eq(:executed)
|
693
693
|
end
|
694
694
|
|
695
|
+
it "should handle rename commands" do
|
696
|
+
@resource[:changes] = "rename Jar/Jar Binks"
|
697
|
+
@resource[:context] = "/foo/"
|
698
|
+
@augeas.expects(:rename).with("/foo/Jar/Jar", "Binks").returns(true)
|
699
|
+
@augeas.expects(:save).returns(true)
|
700
|
+
@augeas.expects(:close)
|
701
|
+
expect(@provider.execute_changes).to eq(:executed)
|
702
|
+
end
|
703
|
+
|
695
704
|
it "should handle setm commands" do
|
696
705
|
@resource[:changes] = ["set test[1]/Jar/Jar Foo","set test[2]/Jar/Jar Bar","setm test Jar/Jar Binks"]
|
697
706
|
@resource[:context] = "/foo/"
|
@@ -35,11 +35,13 @@ describe Puppet::Type.type(:group).provider(:windows_adsi), :if => Puppet.featur
|
|
35
35
|
let(:user1) { stub(:account => 'user1', :domain => '.', :to_s => 'user1sid') }
|
36
36
|
let(:user2) { stub(:account => 'user2', :domain => '.', :to_s => 'user2sid') }
|
37
37
|
let(:user3) { stub(:account => 'user3', :domain => '.', :to_s => 'user3sid') }
|
38
|
+
let(:invalid_user) { SecureRandom.uuid }
|
38
39
|
|
39
40
|
before :each do
|
40
41
|
Puppet::Util::Windows::SID.stubs(:name_to_sid_object).with('user1').returns(user1)
|
41
42
|
Puppet::Util::Windows::SID.stubs(:name_to_sid_object).with('user2').returns(user2)
|
42
43
|
Puppet::Util::Windows::SID.stubs(:name_to_sid_object).with('user3').returns(user3)
|
44
|
+
Puppet::Util::Windows::SID.stubs(:name_to_sid_object).with(invalid_user).returns(nil)
|
43
45
|
end
|
44
46
|
|
45
47
|
describe "#members_insync?" do
|
@@ -157,6 +159,9 @@ describe Puppet::Type.type(:group).provider(:windows_adsi), :if => Puppet.featur
|
|
157
159
|
it "should return a user string like DOMAIN\\USER,DOMAIN2\\USER2" do
|
158
160
|
expect(provider.members_to_s(['user1', 'user2'])).to eq('.\user1,.\user2')
|
159
161
|
end
|
162
|
+
it "should return the username when it cannot be resolved to a SID (for the sake of resource_harness error messages)" do
|
163
|
+
expect(provider.members_to_s([invalid_user])).to eq("#{invalid_user}")
|
164
|
+
end
|
160
165
|
end
|
161
166
|
end
|
162
167
|
|
@@ -24,9 +24,9 @@ describe Puppet::Type.type(:package).provider(:aptrpm) do
|
|
24
24
|
pkg.provider.expects(:rpm).with(*args)
|
25
25
|
end
|
26
26
|
|
27
|
-
it "should report
|
27
|
+
it "should report purged packages" do
|
28
28
|
rpm.raises(Puppet::ExecutionFailure, "couldn't find rpm")
|
29
|
-
expect(pkg.property(:ensure).retrieve).to eq(:
|
29
|
+
expect(pkg.property(:ensure).retrieve).to eq(:purged)
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should report present packages correctly" do
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'puppet/provider/package'
|
3
|
+
|
4
|
+
describe Puppet::Provider::Package do
|
5
|
+
it 'returns absent for uninstalled packages when not purgeable' do
|
6
|
+
provider = Puppet::Provider::Package.new
|
7
|
+
provider.expects(:query).returns nil
|
8
|
+
provider.class.expects(:feature?).with(:purgeable).returns false
|
9
|
+
expect(provider.properties[:ensure]).to eq(:absent)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'returns purged for uninstalled packages when purgeable' do
|
13
|
+
provider = Puppet::Provider::Package.new
|
14
|
+
provider.expects(:query).returns nil
|
15
|
+
provider.class.expects(:feature?).with(:purgeable).returns true
|
16
|
+
expect(provider.properties[:ensure]).to eq(:purged)
|
17
|
+
end
|
18
|
+
end
|
@@ -185,6 +185,76 @@ context 'installing myresource' do
|
|
185
185
|
end
|
186
186
|
end
|
187
187
|
end
|
188
|
+
|
189
|
+
describe 'insync?' do
|
190
|
+
describe 'for array of versions' do
|
191
|
+
let(:is) { ['1.3.4', '3.6.1', '5.1.2'] }
|
192
|
+
|
193
|
+
it 'returns true for ~> 1.3' do
|
194
|
+
resource[:ensure] = '~> 1.3'
|
195
|
+
expect(provider).to be_insync(is)
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'returns false for ~> 2' do
|
199
|
+
resource[:ensure] = '~> 2'
|
200
|
+
expect(provider).to_not be_insync(is)
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'returns true for > 4' do
|
204
|
+
resource[:ensure] = '> 4'
|
205
|
+
expect(provider).to be_insync(is)
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'returns true for 3.6.1' do
|
209
|
+
resource[:ensure] = '3.6.1'
|
210
|
+
expect(provider).to be_insync(is)
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'returns false for 3.6.2' do
|
214
|
+
resource[:ensure] = '3.6.2'
|
215
|
+
expect(provider).to_not be_insync(is)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe 'for string version' do
|
220
|
+
let(:is) { '1.3.4' }
|
221
|
+
|
222
|
+
it 'returns true for ~> 1.3' do
|
223
|
+
resource[:ensure] = '~> 1.3'
|
224
|
+
expect(provider).to be_insync(is)
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'returns false for ~> 2' do
|
228
|
+
resource[:ensure] = '~> 2'
|
229
|
+
expect(provider).to_not be_insync(is)
|
230
|
+
end
|
231
|
+
|
232
|
+
it 'returns false for > 4' do
|
233
|
+
resource[:ensure] = '> 4'
|
234
|
+
expect(provider).to_not be_insync(is)
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'returns true for 1.3.4' do
|
238
|
+
resource[:ensure] = '1.3.4'
|
239
|
+
expect(provider).to be_insync(is)
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'returns false for 3.6.1' do
|
243
|
+
resource[:ensure] = '3.6.1'
|
244
|
+
expect(provider).to_not be_insync(is)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'should return false for bad version specifiers' do
|
249
|
+
resource[:ensure] = 'not a valid gem specifier'
|
250
|
+
expect(provider).to_not be_insync('1.0')
|
251
|
+
end
|
252
|
+
|
253
|
+
it 'should return false for :absent' do
|
254
|
+
resource[:ensure] = '~> 1.0'
|
255
|
+
expect(provider).to_not be_insync(:absent)
|
256
|
+
end
|
257
|
+
end
|
188
258
|
end
|
189
259
|
end
|
190
260
|
|
@@ -410,4 +410,59 @@ EOF
|
|
410
410
|
expect(provider.latest).to eq('package1 1.0.0, package2 1.0.1')
|
411
411
|
end
|
412
412
|
end
|
413
|
+
|
414
|
+
describe 'when determining if a resource is a group' do
|
415
|
+
before do
|
416
|
+
described_class.unstub(:group?)
|
417
|
+
end
|
418
|
+
|
419
|
+
it 'should return false on non-zero pacman exit' do
|
420
|
+
executor.stubs(:execute).with(['/usr/bin/pacman', '-Sg', 'git'], {:failonfail => true, :combine => true, :custom_environment => {}}).raises(Puppet::ExecutionFailure, 'error')
|
421
|
+
expect(described_class.group?('git')).to eq(false)
|
422
|
+
end
|
423
|
+
|
424
|
+
it 'should return false on empty pacman output' do
|
425
|
+
executor.stubs(:execute).with(['/usr/bin/pacman', '-Sg', 'git'], {:failonfail => true, :combine => true, :custom_environment => {}}).returns ''
|
426
|
+
expect(described_class.group?('git')).to eq(false)
|
427
|
+
end
|
428
|
+
|
429
|
+
it 'should return true on non-empty pacman output' do
|
430
|
+
executor.stubs(:execute).with(['/usr/bin/pacman', '-Sg', 'vim-plugins'], {:failonfail => true, :combine => true, :custom_environment => {}}).returns 'vim-plugins vim-a'
|
431
|
+
expect(described_class.group?('vim-plugins')).to eq(true)
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
describe 'when querying installed groups' do
|
436
|
+
let(:installed_packages) { {'package1' => '1.0', 'package2' => '2.0', 'package3' => '3.0'} }
|
437
|
+
let(:groups) { [['foo package1'], ['foo package2'], ['bar package3'], ['bar package4'], ['baz package5']] }
|
438
|
+
|
439
|
+
it 'should raise an error on non-zero pacman exit without a filter' do
|
440
|
+
executor.expects(:open).with('| /usr/bin/pacman -Sgg 2>&1').returns 'error!'
|
441
|
+
$CHILD_STATUS.stubs(:exitstatus).returns 1
|
442
|
+
expect { described_class.get_installed_groups(installed_packages) }.to raise_error(Puppet::ExecutionFailure, 'error!')
|
443
|
+
end
|
444
|
+
|
445
|
+
it 'should return empty groups on non-zero pacman exit with a filter' do
|
446
|
+
executor.expects(:open).with('| /usr/bin/pacman -Sgg git 2>&1').returns ''
|
447
|
+
$CHILD_STATUS.stubs(:exitstatus).returns 1
|
448
|
+
expect(described_class.get_installed_groups(installed_packages, 'git')).to eq({})
|
449
|
+
end
|
450
|
+
|
451
|
+
it 'should return empty groups on empty pacman output' do
|
452
|
+
pipe = stub()
|
453
|
+
pipe.expects(:each_line)
|
454
|
+
executor.expects(:open).with('| /usr/bin/pacman -Sgg 2>&1').yields(pipe).returns ''
|
455
|
+
$CHILD_STATUS.stubs(:exitstatus).returns 0
|
456
|
+
expect(described_class.get_installed_groups(installed_packages)).to eq({})
|
457
|
+
end
|
458
|
+
|
459
|
+
it 'should return groups on non-empty pacman output' do
|
460
|
+
pipe = stub()
|
461
|
+
pipe.expects(:each_line).multiple_yields(*groups)
|
462
|
+
executor.expects(:open).with('| /usr/bin/pacman -Sgg 2>&1').yields(pipe).returns ''
|
463
|
+
$CHILD_STATUS.stubs(:exitstatus).returns 0
|
464
|
+
expect(described_class.get_installed_groups(installed_packages)).to eq({'foo' => 'package1 1.0, package2 2.0'})
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
413
468
|
end
|
@@ -0,0 +1,257 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
provider_class = Puppet::Type.type(:package).provider(:pip3)
|
5
|
+
osfamilies = { ['All', nil] => 'pip3' }
|
6
|
+
|
7
|
+
describe provider_class do
|
8
|
+
|
9
|
+
before do
|
10
|
+
@resource = Puppet::Resource.new(:package, "fake_package")
|
11
|
+
@provider = provider_class.new(@resource)
|
12
|
+
@client = stub_everything('client')
|
13
|
+
@client.stubs(:call).with('package_releases', 'real_package').returns(["1.3", "1.2.5", "1.2.4"])
|
14
|
+
@client.stubs(:call).with('package_releases', 'fake_package').returns([])
|
15
|
+
XMLRPC::Client.stubs(:new2).returns(@client)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "parse" do
|
19
|
+
|
20
|
+
it "should return a hash on valid input" do
|
21
|
+
expect(provider_class.parse("real_package==1.2.5")).to eq({
|
22
|
+
:ensure => "1.2.5",
|
23
|
+
:name => "real_package",
|
24
|
+
:provider => :pip3,
|
25
|
+
})
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should return nil on invalid input" do
|
29
|
+
expect(provider_class.parse("foo")).to eq(nil)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "cmd" do
|
35
|
+
|
36
|
+
it "should return pip3 by default" do
|
37
|
+
Facter.stubs(:value).with(:osfamily).returns("Not RedHat")
|
38
|
+
expect(provider_class.cmd).to eq('pip3')
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "instances" do
|
44
|
+
|
45
|
+
osfamilies.each do |osfamily, pip_cmd|
|
46
|
+
it "should return an array on #{osfamily} when #{pip_cmd} is present" do
|
47
|
+
Facter.stubs(:value).with(:osfamily).returns(osfamily.first)
|
48
|
+
Facter.stubs(:value).with(:operatingsystemmajrelease).returns(osfamily.last)
|
49
|
+
provider_class.expects(:which).with(pip_cmd).returns("/fake/bin/pip3")
|
50
|
+
p = stub("process")
|
51
|
+
p.expects(:collect).yields("real_package==1.2.5")
|
52
|
+
provider_class.expects(:execpipe).with("/fake/bin/pip3 freeze").yields(p)
|
53
|
+
provider_class.instances
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should return an empty array on #{osfamily} when #{pip_cmd} is missing" do
|
57
|
+
Facter.stubs(:value).with(:osfamily).returns(osfamily.first)
|
58
|
+
Facter.stubs(:value).with(:operatingsystemmajrelease).returns(osfamily.last)
|
59
|
+
provider_class.expects(:which).with(pip_cmd).returns nil
|
60
|
+
expect(provider_class.instances).to eq([])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "query" do
|
67
|
+
|
68
|
+
before do
|
69
|
+
@resource[:name] = "real_package"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should return a hash when pip3 and the package are present" do
|
73
|
+
provider_class.expects(:instances).returns [provider_class.new({
|
74
|
+
:ensure => "1.2.5",
|
75
|
+
:name => "real_package",
|
76
|
+
:provider => :pip3,
|
77
|
+
})]
|
78
|
+
|
79
|
+
expect(@provider.query).to eq({
|
80
|
+
:ensure => "1.2.5",
|
81
|
+
:name => "real_package",
|
82
|
+
:provider => :pip3,
|
83
|
+
})
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should return nil when the package is missing" do
|
87
|
+
provider_class.expects(:instances).returns []
|
88
|
+
expect(@provider.query).to eq(nil)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should be case insensitive" do
|
92
|
+
@resource[:name] = "Real_Package"
|
93
|
+
|
94
|
+
provider_class.expects(:instances).returns [provider_class.new({
|
95
|
+
:ensure => "1.2.5",
|
96
|
+
:name => "real_package",
|
97
|
+
:provider => :pip3,
|
98
|
+
})]
|
99
|
+
|
100
|
+
expect(@provider.query).to eq({
|
101
|
+
:ensure => "1.2.5",
|
102
|
+
:name => "real_package",
|
103
|
+
:provider => :pip3,
|
104
|
+
})
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "latest" do
|
110
|
+
|
111
|
+
it "should find a version number for real_package" do
|
112
|
+
@resource[:name] = "real_package"
|
113
|
+
expect(@provider.latest).not_to eq(nil)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should not find a version number for fake_package" do
|
117
|
+
@resource[:name] = "fake_package"
|
118
|
+
expect(@provider.latest).to eq(nil)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should handle a timeout gracefully" do
|
122
|
+
@resource[:name] = "fake_package"
|
123
|
+
@client.stubs(:call).raises(Timeout::Error)
|
124
|
+
expect { @provider.latest }.to raise_error(Puppet::Error)
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "install" do
|
130
|
+
|
131
|
+
before do
|
132
|
+
@resource[:name] = "fake_package"
|
133
|
+
@url = "git+https://example.com/fake_package.git"
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should install" do
|
137
|
+
@resource[:ensure] = :installed
|
138
|
+
@resource[:source] = nil
|
139
|
+
@provider.expects(:lazy_pip).
|
140
|
+
with("install", '-q', "fake_package")
|
141
|
+
@provider.install
|
142
|
+
end
|
143
|
+
|
144
|
+
it "omits the -e flag (GH-1256)" do
|
145
|
+
# The -e flag makes the provider non-idempotent
|
146
|
+
@resource[:ensure] = :installed
|
147
|
+
@resource[:source] = @url
|
148
|
+
@provider.expects(:lazy_pip).with() do |*args|
|
149
|
+
not args.include?("-e")
|
150
|
+
end
|
151
|
+
@provider.install
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should install from SCM" do
|
155
|
+
@resource[:ensure] = :installed
|
156
|
+
@resource[:source] = @url
|
157
|
+
@provider.expects(:lazy_pip).
|
158
|
+
with("install", '-q', "#{@url}#egg=fake_package")
|
159
|
+
@provider.install
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should install a particular SCM revision" do
|
163
|
+
@resource[:ensure] = "0123456"
|
164
|
+
@resource[:source] = @url
|
165
|
+
@provider.expects(:lazy_pip).
|
166
|
+
with("install", "-q", "#{@url}@0123456#egg=fake_package")
|
167
|
+
@provider.install
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should install a particular version" do
|
171
|
+
@resource[:ensure] = "0.0.0"
|
172
|
+
@resource[:source] = nil
|
173
|
+
@provider.expects(:lazy_pip).with("install", "-q", "fake_package==0.0.0")
|
174
|
+
@provider.install
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should upgrade" do
|
178
|
+
@resource[:ensure] = :latest
|
179
|
+
@resource[:source] = nil
|
180
|
+
@provider.expects(:lazy_pip).
|
181
|
+
with("install", "-q", "--upgrade", "fake_package")
|
182
|
+
@provider.install
|
183
|
+
end
|
184
|
+
|
185
|
+
it "should handle install options" do
|
186
|
+
@resource[:ensure] = :installed
|
187
|
+
@resource[:source] = nil
|
188
|
+
@resource[:install_options] = [{"--timeout" => "10"}, "--no-index"]
|
189
|
+
@provider.expects(:lazy_pip).
|
190
|
+
with("install", "-q", "--timeout=10", "--no-index", "fake_package")
|
191
|
+
@provider.install
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
describe "uninstall" do
|
197
|
+
|
198
|
+
it "should uninstall" do
|
199
|
+
@resource[:name] = "fake_package"
|
200
|
+
@provider.expects(:lazy_pip).
|
201
|
+
with('uninstall', '-y', '-q', 'fake_package')
|
202
|
+
@provider.uninstall
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
describe "update" do
|
208
|
+
|
209
|
+
it "should just call install" do
|
210
|
+
@provider.expects(:install).returns(nil)
|
211
|
+
@provider.update
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
|
216
|
+
describe "lazy_pip" do
|
217
|
+
|
218
|
+
after(:each) do
|
219
|
+
Puppet::Type::Package::ProviderPip.instance_variable_set(:@confine_collection, nil)
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should succeed if pip3 is present" do
|
223
|
+
@provider.stubs(:pip).returns(nil)
|
224
|
+
@provider.method(:lazy_pip).call "freeze"
|
225
|
+
end
|
226
|
+
|
227
|
+
osfamilies.each do |osfamily, pip_cmd|
|
228
|
+
it "should retry on #{osfamily} if #{pip_cmd} has not yet been found" do
|
229
|
+
Facter.stubs(:value).with(:osfamily).returns(osfamily.first)
|
230
|
+
Facter.stubs(:value).with(:operatingsystemmajrelease).returns(osfamily.last)
|
231
|
+
@provider.expects(:pip).twice.with('freeze').raises(NoMethodError).then.returns(nil)
|
232
|
+
@provider.expects(:which).with(pip_cmd).returns("/fake/bin/pip3")
|
233
|
+
@provider.method(:lazy_pip).call "freeze"
|
234
|
+
end
|
235
|
+
|
236
|
+
it "should fail on #{osfamily} if #{pip_cmd} is missing" do
|
237
|
+
Facter.stubs(:value).with(:osfamily).returns(osfamily.first)
|
238
|
+
Facter.stubs(:value).with(:operatingsystemmajrelease).returns(osfamily.last)
|
239
|
+
@provider.expects(:pip).with('freeze').raises(NoMethodError)
|
240
|
+
@provider.expects(:which).with(pip_cmd).returns(nil)
|
241
|
+
expect { @provider.method(:lazy_pip).call("freeze") }.to raise_error(NoMethodError)
|
242
|
+
end
|
243
|
+
|
244
|
+
it "should output a useful error message on #{osfamily} if #{pip_cmd} is missing" do
|
245
|
+
Facter.stubs(:value).with(:osfamily).returns(osfamily.first)
|
246
|
+
Facter.stubs(:value).with(:operatingsystemmajrelease).returns(osfamily.last)
|
247
|
+
@provider.expects(:pip).with('freeze').raises(NoMethodError)
|
248
|
+
@provider.expects(:which).with(pip_cmd).returns(nil)
|
249
|
+
expect { @provider.method(:lazy_pip).call("freeze") }.
|
250
|
+
to raise_error(NoMethodError, "Could not locate the #{pip_cmd} command.")
|
251
|
+
end
|
252
|
+
|
253
|
+
end
|
254
|
+
|
255
|
+
end
|
256
|
+
|
257
|
+
end
|