puppet 5.5.10-x86-mingw32 → 5.5.12-x86-mingw32

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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +30 -0
  3. data/Gemfile.lock +13 -13
  4. data/lib/puppet.rb +4 -4
  5. data/lib/puppet/application.rb +1 -1
  6. data/lib/puppet/application/filebucket.rb +6 -1
  7. data/lib/puppet/configurer.rb +4 -7
  8. data/lib/puppet/confine/boolean.rb +45 -0
  9. data/lib/puppet/confine/false.rb +7 -1
  10. data/lib/puppet/confine/true.rb +7 -1
  11. data/lib/puppet/defaults.rb +0 -18
  12. data/lib/puppet/functions/call.rb +2 -1
  13. data/lib/puppet/network/http/connection.rb +15 -5
  14. data/lib/puppet/pops/issues.rb +4 -0
  15. data/lib/puppet/pops/model/factory.rb +38 -4
  16. data/lib/puppet/pops/parser/egrammar.ra +2 -2
  17. data/lib/puppet/pops/parser/eparser.rb +628 -627
  18. data/lib/puppet/pops/parser/heredoc_support.rb +17 -7
  19. data/lib/puppet/pops/parser/lexer2.rb +6 -1
  20. data/lib/puppet/pops/parser/locator.rb +106 -86
  21. data/lib/puppet/pops/parser/parser_support.rb +11 -2
  22. data/lib/puppet/pops/types/type_mismatch_describer.rb +1 -1
  23. data/lib/puppet/provider/file/windows.rb +49 -1
  24. data/lib/puppet/provider/group/windows_adsi.rb +4 -1
  25. data/lib/puppet/provider/mount/parsed.rb +3 -0
  26. data/lib/puppet/provider/package/windows.rb +5 -1
  27. data/lib/puppet/provider/service/systemd.rb +1 -1
  28. data/lib/puppet/provider/service/upstart.rb +8 -6
  29. data/lib/puppet/settings.rb +10 -5
  30. data/lib/puppet/transaction.rb +8 -6
  31. data/lib/puppet/transaction/resource_harness.rb +1 -0
  32. data/lib/puppet/type/exec.rb +27 -5
  33. data/lib/puppet/type/file/mode.rb +6 -1
  34. data/lib/puppet/type/filebucket.rb +12 -8
  35. data/lib/puppet/util/command_line.rb +5 -1
  36. data/lib/puppet/util/log.rb +7 -2
  37. data/lib/puppet/util/windows/security.rb +29 -8
  38. data/lib/puppet/version.rb +1 -1
  39. data/locales/puppet.pot +196 -151
  40. data/man/man5/puppet.conf.5 +2 -2
  41. data/man/man8/puppet-agent.8 +1 -1
  42. data/man/man8/puppet-apply.8 +1 -1
  43. data/man/man8/puppet-ca.8 +1 -1
  44. data/man/man8/puppet-catalog.8 +1 -1
  45. data/man/man8/puppet-cert.8 +1 -1
  46. data/man/man8/puppet-certificate.8 +1 -1
  47. data/man/man8/puppet-certificate_request.8 +1 -1
  48. data/man/man8/puppet-certificate_revocation_list.8 +1 -1
  49. data/man/man8/puppet-config.8 +1 -1
  50. data/man/man8/puppet-describe.8 +1 -1
  51. data/man/man8/puppet-device.8 +1 -1
  52. data/man/man8/puppet-doc.8 +1 -1
  53. data/man/man8/puppet-epp.8 +1 -1
  54. data/man/man8/puppet-facts.8 +1 -1
  55. data/man/man8/puppet-filebucket.8 +6 -2
  56. data/man/man8/puppet-generate.8 +1 -1
  57. data/man/man8/puppet-help.8 +1 -1
  58. data/man/man8/puppet-key.8 +1 -1
  59. data/man/man8/puppet-lookup.8 +1 -1
  60. data/man/man8/puppet-man.8 +1 -1
  61. data/man/man8/puppet-master.8 +1 -1
  62. data/man/man8/puppet-module.8 +1 -1
  63. data/man/man8/puppet-node.8 +1 -1
  64. data/man/man8/puppet-parser.8 +1 -1
  65. data/man/man8/puppet-plugin.8 +1 -1
  66. data/man/man8/puppet-report.8 +1 -1
  67. data/man/man8/puppet-resource.8 +1 -1
  68. data/man/man8/puppet-script.8 +1 -1
  69. data/man/man8/puppet-status.8 +1 -1
  70. data/man/man8/puppet.8 +2 -2
  71. data/spec/fixtures/unit/provider/mount/parsed/freebsd.fstab +1 -0
  72. data/spec/fixtures/unit/provider/mount/parsed/freebsd.mount +1 -0
  73. data/spec/fixtures/unit/provider/mount/parsed/linux.fstab +1 -0
  74. data/spec/fixtures/unit/provider/mount/parsed/linux.mount +1 -0
  75. data/spec/fixtures/unit/provider/mount/parsed/netbsd.fstab +1 -0
  76. data/spec/fixtures/unit/provider/mount/parsed/netbsd.mount +1 -0
  77. data/spec/fixtures/unit/provider/mount/parsed/openbsd.fstab +1 -0
  78. data/spec/fixtures/unit/provider/mount/parsed/openbsd.mount +1 -0
  79. data/spec/integration/provider/file/windows_spec.rb +162 -0
  80. data/spec/integration/type/file_spec.rb +0 -19
  81. data/spec/unit/application_spec.rb +8 -1
  82. data/spec/unit/configurer_spec.rb +2 -4
  83. data/spec/unit/confine/false_spec.rb +27 -0
  84. data/spec/unit/confine/true_spec.rb +27 -0
  85. data/spec/unit/defaults_spec.rb +0 -14
  86. data/spec/unit/network/http/connection_spec.rb +1 -1
  87. data/spec/unit/pops/loaders/loaders_spec.rb +5 -0
  88. data/spec/unit/pops/parser/locator_spec.rb +45 -0
  89. data/spec/unit/pops/parser/parse_heredoc_spec.rb +111 -15
  90. data/spec/unit/pops/types/type_mismatch_describer_spec.rb +9 -0
  91. data/spec/unit/provider/group/windows_adsi_spec.rb +7 -1
  92. data/spec/unit/provider/mount/parsed_spec.rb +8 -1
  93. data/spec/unit/provider/package/windows_spec.rb +12 -1
  94. data/spec/unit/provider/service/systemd_spec.rb +6 -4
  95. data/spec/unit/settings_spec.rb +36 -0
  96. data/spec/unit/transaction/resource_harness_spec.rb +26 -0
  97. data/spec/unit/transaction_spec.rb +29 -0
  98. data/spec/unit/type/exec_spec.rb +47 -0
  99. data/spec/unit/type/filebucket_spec.rb +8 -6
  100. data/spec/unit/util/command_line_spec.rb +23 -2
  101. data/spec/unit/util/log_spec.rb +15 -0
  102. data/spec/unit/util/storage_spec.rb +19 -19
  103. metadata +6 -3
  104. data/MAINTAINERS +0 -47
@@ -244,6 +244,15 @@ describe 'the type mismatch describer' do
244
244
  expect { eval_and_collect_notices(code) }.to(raise_error(Puppet::Error,
245
245
  /Class\[Test\]: parameter 'opts' expects size to be 1, got 0/))
246
246
  end
247
+
248
+ it "treats Optional as Optional[Any]" do
249
+ code = <<-PUPPET
250
+ class test(Optional $var=undef) {}
251
+ class { 'test': var => 'hello' }
252
+ PUPPET
253
+ expect { eval_and_collect_notices(code) }.not_to raise_error
254
+ end
255
+
247
256
  end
248
257
  end
249
258
  end
@@ -251,7 +251,13 @@ describe Puppet::Type.type(:group).provider(:windows_adsi), :if => Puppet.featur
251
251
  'user3',
252
252
  ]
253
253
 
254
- expect(provider.members).to match_array([user1.sid, user2.sid, user3.sid])
254
+ expected_member_sids = [user1.sid, user2.sid, user3.sid]
255
+ expected_members = ['user1', 'user2', 'user3']
256
+ provider.stubs(:members_to_s)
257
+ .with(expected_member_sids)
258
+ .returns(expected_members.join(','))
259
+
260
+ expect(provider.members).to match_array(expected_members)
255
261
  end
256
262
 
257
263
  it "should be able to set group members" do
@@ -172,6 +172,7 @@ FSTAB
172
172
  expect(mounts[2]).to eq({ :name => '/sys', :mounted => :yes })
173
173
  expect(mounts[3]).to eq({ :name => '/usr/portage', :mounted => :yes })
174
174
  expect(mounts[4]).to eq({ :name => '/ghost', :mounted => :yes })
175
+ expect(mounts[5]).to eq({ :name => '/run', :mounted => :yes})
175
176
  end
176
177
 
177
178
  it "should get name from mountoutput found on AIX" do
@@ -283,10 +284,11 @@ FSTAB
283
284
  @res_mounted = Puppet::Type::Mount.new(:name => '/') # in every fake fstab
284
285
  @res_unmounted = Puppet::Type::Mount.new(:name => '/boot') # in every fake fstab
285
286
  @res_absent = Puppet::Type::Mount.new(:name => '/absent') # in no fake fstab
287
+ @res_trailing_slash = Puppet::Type::Mount.new(:name => '/run/') # in every fake fstab
286
288
 
287
289
  # Simulate transaction.rb:prefetch
288
290
  @resource_hash = {}
289
- [@res_ghost, @res_mounted, @res_unmounted, @res_absent].each do |resource|
291
+ [@res_ghost, @res_mounted, @res_unmounted, @res_absent, @res_trailing_slash].each do |resource|
290
292
  @resource_hash[resource.name] = resource
291
293
  end
292
294
  end
@@ -306,6 +308,11 @@ FSTAB
306
308
  described_class.prefetch(@resource_hash)
307
309
  expect(@res_mounted.provider.get(:ensure)).to eq(:mounted)
308
310
  end
311
+
312
+ it 'strips trailing slashes from resource titles' do
313
+ described_class.prefetch(@resource_hash)
314
+ expect(@res_trailing_slash.provider.get(:ensure)).to eq(:mounted)
315
+ end
309
316
  end
310
317
 
311
318
  it "should set :ensure to :absent if not found in fstab and not mounted" do
@@ -86,7 +86,7 @@ describe Puppet::Type.type(:package).provider(:windows), :if => Puppet.features.
86
86
  context '#install' do
87
87
  let(:command) { 'blarg.exe /S' }
88
88
  let(:klass) { mock('installer', :install_command => ['blarg.exe', '/S'] ) }
89
- let(:execute_options) do {:failonfail => false, :combine => true, :cwd => 'E:\Rando\Directory', :suppress_window => true} end
89
+ let(:execute_options) do {:failonfail => false, :combine => true, :cwd => nil, :suppress_window => true} end
90
90
  before :each do
91
91
  Puppet::Provider::Package::Windows::Package.expects(:installer_class).returns(klass)
92
92
  end
@@ -136,6 +136,17 @@ describe Puppet::Type.type(:package).provider(:windows), :if => Puppet.features.
136
136
  expect(error.code).to eq(5) # ERROR_ACCESS_DENIED
137
137
  end
138
138
  end
139
+
140
+ context 'With a real working dir' do
141
+ let(:execute_options) do {:failonfail => false, :combine => true, :cwd => 'E:\Rando\Directory', :suppress_window => true} end
142
+
143
+ it 'should not try to set the working directory' do
144
+ Puppet::FileSystem.expects(:exist?).with('E:\Rando\Directory').returns(true)
145
+ expect_execute(command, 0)
146
+
147
+ provider.install
148
+ end
149
+ end
139
150
  end
140
151
 
141
152
  context '#uninstall' do
@@ -30,10 +30,12 @@ describe Puppet::Type.type(:service).provider(:systemd) do
30
30
  end
31
31
  end
32
32
 
33
- it "should be the default provider on rhel7" do
34
- Facter.stubs(:value).with(:osfamily).returns(:redhat)
35
- Facter.stubs(:value).with(:operatingsystemmajrelease).returns("7")
36
- expect(described_class).to be_default
33
+ [7, 8].each do |ver|
34
+ it "should be the default provider on rhel#{ver}" do
35
+ Facter.stubs(:value).with(:osfamily).returns(:redhat)
36
+ Facter.stubs(:value).with(:operatingsystemmajrelease).returns(ver.to_s)
37
+ expect(described_class).to be_default
38
+ end
37
39
  end
38
40
 
39
41
  [ 4, 5, 6 ].each do |ver|
@@ -702,6 +702,42 @@ describe Puppet::Settings do
702
702
  @settings.send(:parse_config_files)
703
703
  end
704
704
  end
705
+
706
+ describe "when the file exists" do
707
+ it "fails if the file is not readable" do
708
+ Puppet::FileSystem.expects(:exist?).with(user_config_file_default_location).returns(true)
709
+ @settings.expects(:read_file).raises('Permission denied')
710
+
711
+ expect{ @settings.send(:parse_config_files) }.to raise_error(RuntimeError, /Could not load #{user_config_file_default_location}: Permission denied/)
712
+ end
713
+
714
+ it "does not fail if the file is not readable and when `require_config` is false" do
715
+ Puppet::FileSystem.expects(:exist?).with(user_config_file_default_location).returns(true)
716
+ @settings.expects(:read_file).raises('Permission denied')
717
+
718
+ @settings.expects(:parse_config).never
719
+ Puppet.expects(:log_exception)
720
+
721
+ expect{ @settings.send(:parse_config_files, false) }.not_to raise_error
722
+ end
723
+
724
+ it "reads the file if it is readable" do
725
+ Puppet::FileSystem.expects(:exist?).with(user_config_file_default_location).returns(true)
726
+ @settings.expects(:read_file).returns('server = host.string')
727
+ @settings.expects(:parse_config)
728
+
729
+ @settings.send(:parse_config_files)
730
+ end
731
+ end
732
+
733
+ describe "when the file does not exist" do
734
+ it "does not attempt to parse the config file" do
735
+ Puppet::FileSystem.expects(:exist?).with(user_config_file_default_location).returns(false)
736
+ @settings.expects(:parse_config).never
737
+
738
+ @settings.send(:parse_config_files)
739
+ end
740
+ end
705
741
  end
706
742
 
707
743
  describe "when parsing its configuration" do
@@ -601,4 +601,30 @@ describe Puppet::Transaction::ResourceHarness do
601
601
  Puppet::Util::Storage.expects(:cache).with(@resource).returns data
602
602
  expect(@harness.cached(@resource, :foo)).to eq("other")
603
603
  end
604
+
605
+ describe "successful event message" do
606
+ let(:test_file) do
607
+ tmpfile('foo').tap do |path|
608
+ File.open(path, 'w') { |fh| fh.write("old contents") }
609
+ end
610
+ end
611
+
612
+ let(:resource) do
613
+ Puppet::Type.type(:file).new(:path => test_file, :backup => false, :content => "hello world")
614
+ end
615
+
616
+ it "contains (corrective) when corrective change" do
617
+ Puppet::Transaction::Event.any_instance.stubs(:corrective_change).returns(true)
618
+ status = @harness.evaluate(resource)
619
+ sync_event = status.events[0]
620
+ expect(sync_event.message).to match(/content changed '{md5}[0-9a-f]+' to '{md5}[0-9a-f]+' \(corrective\)/)
621
+ end
622
+
623
+ it "contains no modifier when intentional change" do
624
+ Puppet::Transaction::Event.any_instance.stubs(:corrective_change).returns(false)
625
+ status = @harness.evaluate(resource)
626
+ sync_event = status.events[0]
627
+ expect(sync_event.message).to match(/content changed '{md5}[0-9a-f]+' to '{md5}[0-9a-f]+'$/)
628
+ end
629
+ end
604
630
  end
@@ -600,6 +600,30 @@ describe Puppet::Transaction do
600
600
  transaction.prefetch_if_necessary(resource)
601
601
  end
602
602
 
603
+ it "should not rescue SystemExit without future_features flag" do
604
+ Puppet.settings[:future_features] = false
605
+ resource.provider.class.expects(:prefetch).raises(SystemExit, "SystemMessage")
606
+ expect { transaction.prefetch_if_necessary(resource) }.to raise_error(SystemExit, "SystemMessage")
607
+ end
608
+
609
+ it "should not rescue SystemExit with future_features flag" do
610
+ Puppet.settings[:future_features] = true
611
+ resource.provider.class.expects(:prefetch).raises(SystemExit, "SystemMessage")
612
+ expect { transaction.prefetch_if_necessary(resource) }.to raise_error(SystemExit, "SystemMessage")
613
+ end
614
+
615
+ it "should rescue LoadError without future_features flag" do
616
+ Puppet.settings[:future_features] = false
617
+ resource.provider.class.expects(:prefetch).raises(LoadError, "LoadMessage")
618
+ expect { transaction.prefetch_if_necessary(resource) }.not_to raise_error
619
+ end
620
+
621
+ it "should rescue LoadError with future_features flag" do
622
+ Puppet.settings[:future_features] = true
623
+ resource.provider.class.expects(:prefetch).raises(LoadError, "LoadMessage")
624
+ expect { transaction.prefetch_if_necessary(resource) }.not_to raise_error
625
+ end
626
+
603
627
  describe "and prefetching fails" do
604
628
  before :each do
605
629
  resource.provider.class.expects(:prefetch).raises(Puppet::Error, "message")
@@ -613,6 +637,11 @@ describe Puppet::Transaction do
613
637
  it "should not rescue prefetch executions" do
614
638
  expect { transaction.prefetch_if_necessary(resource) }.to raise_error(Puppet::Error)
615
639
  end
640
+
641
+ it "should log the exception during prefetch" do
642
+ Puppet.expects(:log_exception).with(anything, "Could not prefetch sshkey provider 'parsed': message")
643
+ expect { transaction.prefetch_if_necessary(resource) }.to raise_error(Puppet::Error, "message")
644
+ end
616
645
  end
617
646
 
618
647
  context "with future_features flag" do
@@ -31,6 +31,33 @@ describe Puppet::Type.type(:exec) do
31
31
  return exec
32
32
  end
33
33
 
34
+ def exec_stub(options = {})
35
+ command = options.delete(:command) || @command
36
+ #unless_val = options.delete(:unless) || :true
37
+ type_args = {
38
+ :name => command,
39
+ #:unless => unless_val,
40
+ }.merge(options)
41
+
42
+ # Chicken, meet egg:
43
+ # Provider methods have to be stubbed before resource init or checks fail
44
+ # We have to set 'unless' in resource init or it can not be marked sensitive correctly.
45
+ # So: we create a dummy ahead of time and use 'any_instance' to stub out provider methods.
46
+ dummy = Puppet::Type.type(:exec).new(:name => @command)
47
+ dummy.provider.class.any_instance.stubs(:validatecmd)
48
+ dummy.provider.class.any_instance.stubs(:checkexe).returns(true)
49
+ pass_status = stub('status', :exitstatus => 0, :split => ["pass output"])
50
+ fail_status = stub('status', :exitstatus => 1, :split => ["fail output"])
51
+ Puppet::Util::Execution.stubs(:execute).with(:true, anything).returns(pass_status)
52
+ Puppet::Util::Execution.stubs(:execute).with(:false, anything).returns(fail_status)
53
+
54
+ test = Puppet::Type.type(:exec).new(type_args)
55
+
56
+ Puppet::Util::Log.level = :debug
57
+
58
+ return test
59
+ end
60
+
34
61
  before do
35
62
  @command = make_absolute('/bin/true whatever')
36
63
  @executable = make_absolute('/bin/true')
@@ -176,6 +203,26 @@ describe Puppet::Type.type(:exec) do
176
203
  expect(@logs).to eq([])
177
204
  end
178
205
 
206
+ describe "when checks stop execution when debugging" do
207
+ [[:unless, :true], [:onlyif, :false]].each do |check, result|
208
+ it "should log a message with the command when #{check} is #{result}" do
209
+ output = "'#{@command}' won't be executed because of failed check '#{check}'"
210
+ test = exec_stub({:command => @command, check => result})
211
+ expect(test.check_all_attributes).to eq(false)
212
+ expect(@logs).to include(an_object_having_attributes(level: :debug, message: output))
213
+ end
214
+
215
+ it "should log a message with a redacted command and check if #{check} is sensitive" do
216
+ output1 = "Executing check '[redacted]'"
217
+ output2 = "'[command redacted]' won't be executed because of failed check '#{check}'"
218
+ test = exec_stub({:command => @command, check => result, :sensitive_parameters => [check]})
219
+ expect(test.check_all_attributes).to eq(false)
220
+ expect(@logs).to include(an_object_having_attributes(level: :debug, message: output1))
221
+ expect(@logs).to include(an_object_having_attributes(level: :debug, message: output2))
222
+ end
223
+ end
224
+ end
225
+
179
226
  describe " when multiple tries are set," do
180
227
  it "should repeat the command attempt 'tries' times on failure and produce an error" do
181
228
  tries = 5
@@ -21,14 +21,14 @@ describe Puppet::Type.type(:filebucket) do
21
21
  expect(Puppet::Type.type(:filebucket).new(:name => "main")[:path]).to eq(Puppet[:clientbucketdir])
22
22
  end
23
23
 
24
- it "should use the masterport as the path by default port" do
24
+ it "should not have a default port" do
25
25
  Puppet.settings[:masterport] = 50
26
- expect(Puppet::Type.type(:filebucket).new(:name => "main")[:port]).to eq(Puppet[:masterport])
26
+ expect(Puppet::Type.type(:filebucket).new(:name => "main")[:port]).to eq(nil)
27
27
  end
28
28
 
29
- it "should use the server as the path by default server" do
29
+ it "should not have a default server" do
30
30
  Puppet.settings[:server] = "myserver"
31
- expect(Puppet::Type.type(:filebucket).new(:name => "main")[:server]).to eq(Puppet[:server])
31
+ expect(Puppet::Type.type(:filebucket).new(:name => "main")[:server]).to eq(nil)
32
32
  end
33
33
 
34
34
  it "be local by default" do
@@ -93,10 +93,12 @@ describe Puppet::Type.type(:filebucket) do
93
93
  bucket.bucket
94
94
  end
95
95
 
96
- it "should use the default server if the path is unset and no server is provided" do
96
+ it "should not try to guess server or port if the path is unset and no server is provided" do
97
97
  Puppet.settings[:server] = "myserv"
98
+ Puppet.settings[:server_list] = ['server_list_0', 'server_list_1']
99
+ Puppet::FileBucket::Dipper.expects(:new).with(:Server => nil, :Port => nil).returns @bucket
100
+
98
101
  bucket = Puppet::Type.type(:filebucket).new :name => "main", :path => false
99
- Puppet::FileBucket::Dipper.expects(:new).with { |args| args[:Server] == "myserv" }.returns @bucket
100
102
  bucket.bucket
101
103
  end
102
104
  end
@@ -67,8 +67,8 @@ describe Puppet::Util::CommandLine do
67
67
  end
68
68
  end
69
69
 
70
- %w{--help -h}.each do|arg|
71
- it "should print help" do
70
+ %w{--help -h help}.each do|arg|
71
+ it "should print help and exit if #{arg} is given" do
72
72
  commandline = Puppet::Util::CommandLine.new("puppet", [arg])
73
73
  commandline.expects(:exec).never
74
74
 
@@ -77,6 +77,27 @@ describe Puppet::Util::CommandLine do
77
77
  }.to have_printed(/Usage: puppet <subcommand> \[options\] <action> \[options\]/).and_exit_with(0)
78
78
  end
79
79
  end
80
+
81
+ it "should fail if the config file isn't readable and we're running a subcommand that requires a readable config file" do
82
+ Puppet::FileSystem.stubs(:exist?).with(Puppet[:config]).returns(true)
83
+ Puppet::Settings.any_instance.stubs(:read_file).returns('')
84
+ Puppet::Settings.any_instance.expects(:read_file).with(Puppet[:config]).raises('Permission denied')
85
+
86
+ expect{ described_class.new("puppet", ['config']).execute }.to raise_error(SystemExit)
87
+ end
88
+
89
+ it "should not fail if the config file isn't readable and we're running a subcommand that does not require a readable config file" do
90
+ Puppet::FileSystem.stubs(:exist?)
91
+ Puppet::FileSystem.stubs(:exist?).with(Puppet[:config]).returns(true)
92
+ Puppet::Settings.any_instance.stubs(:read_file).returns('')
93
+ Puppet::Settings.any_instance.expects(:read_file).with(Puppet[:config]).raises('Permission denied')
94
+
95
+ commandline = described_class.new("puppet", ['help'])
96
+
97
+ expect {
98
+ commandline.execute
99
+ }.to have_printed(/Usage: puppet <subcommand> \[options\] <action> \[options\]/).and_exit_with(0)
100
+ end
80
101
  end
81
102
 
82
103
  describe "when dealing with puppet commands" do
@@ -88,6 +88,21 @@ describe Puppet::Util::Log do
88
88
  expect(logs.last.source).to eq(utf_8_msg)
89
89
  end
90
90
 
91
+ require 'puppet/util/log/destinations'
92
+
93
+ it "raises an error when it has no successful logging destinations" do
94
+ # spec_helper.rb redirects log output away from the console,
95
+ # so we have to stop that here, or else the logic we are testing
96
+ # will not be reached.
97
+ Puppet::Util::Log.stubs(:destinations).returns({})
98
+
99
+ our_exception = Puppet::DevError.new("test exception")
100
+ Puppet::FileSystem.expects(:dir).raises(our_exception)
101
+ bad_file = tmpfile("bad_file")
102
+
103
+ expect { Puppet::Util::Log.newdestination(bad_file) }.to raise_error(Puppet::DevError)
104
+ end
105
+
91
106
  describe ".setup_default" do
92
107
  it "should default to :syslog" do
93
108
  Puppet.features.stubs(:syslog?).returns(true)
@@ -169,6 +169,8 @@ describe Puppet::Util::Storage do
169
169
  end
170
170
 
171
171
  describe "when storing to the state file" do
172
+ A_SMALL_AMOUNT_OF_TIME = 0.001 #Seconds
173
+
172
174
  before(:each) do
173
175
  @state_file = tmpfile('storage_test')
174
176
  @saved_statefile = Puppet[:statefile]
@@ -220,13 +222,13 @@ describe Puppet::Util::Storage do
220
222
  stale_checked = Time.now - (Puppet[:statettl] + 1)
221
223
  Puppet::Util::Storage.cache(:yayness)[:checked] = recent_checked
222
224
  Puppet::Util::Storage.cache(:stale)[:checked] = stale_checked
223
- expect(Puppet::Util::Storage.state).to eq(
225
+ expect(Puppet::Util::Storage.state).to match(
224
226
  {
225
227
  :yayness => {
226
- :checked => recent_checked
228
+ :checked => a_value_within(A_SMALL_AMOUNT_OF_TIME).of(recent_checked)
227
229
  },
228
230
  :stale => {
229
- :checked => stale_checked
231
+ :checked => a_value_within(A_SMALL_AMOUNT_OF_TIME).of(stale_checked)
230
232
  }
231
233
  }
232
234
  )
@@ -238,29 +240,28 @@ describe Puppet::Util::Storage do
238
240
 
239
241
  Puppet::Util::Storage.load
240
242
 
241
- expect(Puppet::Util::Storage.state).to eq(
243
+ expect(Puppet::Util::Storage.state).to match(
242
244
  {
243
245
  :yayness => {
244
- :checked => recent_checked
246
+ :checked => a_value_within(A_SMALL_AMOUNT_OF_TIME).of(recent_checked)
245
247
  }
246
248
  }
247
249
  )
248
250
  end
249
251
 
250
-
251
252
  it "does not expire entries when statettl is 0" do
252
253
  Puppet[:statettl] = '0'
253
254
  recent_checked = Time.now
254
255
  older_checked = Time.now - 10_000_000
255
256
  Puppet::Util::Storage.cache(:yayness)[:checked] = recent_checked
256
257
  Puppet::Util::Storage.cache(:older)[:checked] = older_checked
257
- expect(Puppet::Util::Storage.state).to eq(
258
+ expect(Puppet::Util::Storage.state).to match(
258
259
  {
259
260
  :yayness => {
260
- :checked => recent_checked
261
+ :checked => a_value_within(A_SMALL_AMOUNT_OF_TIME).of(recent_checked)
261
262
  },
262
263
  :older => {
263
- :checked => older_checked
264
+ :checked => a_value_within(A_SMALL_AMOUNT_OF_TIME).of(older_checked)
264
265
  }
265
266
  }
266
267
  )
@@ -272,32 +273,31 @@ describe Puppet::Util::Storage do
272
273
 
273
274
  Puppet::Util::Storage.load
274
275
 
275
- expect(Puppet::Util::Storage.state).to eq(
276
+ expect(Puppet::Util::Storage.state).to match(
276
277
  {
277
278
  :yayness => {
278
- :checked => recent_checked
279
+ :checked => a_value_within(A_SMALL_AMOUNT_OF_TIME).of(recent_checked)
279
280
  },
280
281
  :older => {
281
- :checked => older_checked
282
+ :checked => a_value_within(A_SMALL_AMOUNT_OF_TIME).of(older_checked)
282
283
  }
283
284
  }
284
285
  )
285
286
  end
286
287
 
287
-
288
288
  it "does not expire entries when statettl is 'unlimited'" do
289
289
  Puppet[:statettl] = 'unlimited'
290
290
  recent_checked = Time.now
291
291
  older_checked = Time.now - 10_000_000
292
292
  Puppet::Util::Storage.cache(:yayness)[:checked] = recent_checked
293
293
  Puppet::Util::Storage.cache(:older)[:checked] = older_checked
294
- expect(Puppet::Util::Storage.state).to eq(
294
+ expect(Puppet::Util::Storage.state).to match(
295
295
  {
296
296
  :yayness => {
297
- :checked => recent_checked
297
+ :checked => a_value_within(A_SMALL_AMOUNT_OF_TIME).of(recent_checked)
298
298
  },
299
299
  :older => {
300
- :checked => older_checked
300
+ :checked => a_value_within(A_SMALL_AMOUNT_OF_TIME).of(older_checked)
301
301
  }
302
302
  }
303
303
  )
@@ -309,13 +309,13 @@ describe Puppet::Util::Storage do
309
309
 
310
310
  Puppet::Util::Storage.load
311
311
 
312
- expect(Puppet::Util::Storage.state).to eq(
312
+ expect(Puppet::Util::Storage.state).to match(
313
313
  {
314
314
  :yayness => {
315
- :checked => recent_checked
315
+ :checked => a_value_within(A_SMALL_AMOUNT_OF_TIME).of(recent_checked)
316
316
  },
317
317
  :older => {
318
- :checked => older_checked
318
+ :checked => a_value_within(A_SMALL_AMOUNT_OF_TIME).of(older_checked)
319
319
  }
320
320
  }
321
321
  )