puppet 3.3.0.rc2 → 3.3.0.rc3

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.

@@ -9,7 +9,7 @@ gpg_name: 'info@puppetlabs.com'
9
9
  gpg_key: '4BD6EC30'
10
10
  sign_tar: FALSE
11
11
  # a space separated list of mock configs
12
- final_mocks: 'pl-el-5-i386 pl-el-6-i386 pl-fedora-17-i386 pl-fedora-18-i386 pl-fedora-19-i386'
12
+ final_mocks: 'pl-el-5-i386 pl-el-6-i386 pl-fedora-18-i386 pl-fedora-19-i386'
13
13
  yum_host: 'yum.puppetlabs.com'
14
14
  yum_repo_path: '/opt/repository/yum/'
15
15
  build_gem: TRUE
@@ -55,7 +55,7 @@ class WindowsDaemon < Win32::Daemon
55
55
  runinterval = 1800
56
56
  end
57
57
 
58
- pid = Process.create(:command_line => "\"#{puppet}\" agent --onetime #{args}").process_id
58
+ pid = Process.create(:command_line => "\"#{puppet}\" agent --onetime #{args}", :creation_flags => Process::CREATE_NEW_CONSOLE).process_id
59
59
  log_debug("Process created: #{pid}")
60
60
 
61
61
  log_debug("Service waiting for #{runinterval} seconds")
@@ -0,0 +1,29 @@
1
+ # Various methods used to coerce values into a canonical form.
2
+ #
3
+ # @api private
4
+ module Puppet::Coercion
5
+ # Try to coerce various input values into boolean true/false
6
+ #
7
+ # Only a very limited subset of values are allowed. This method does not try
8
+ # to provide a generic "truthiness" system.
9
+ #
10
+ # @param value [Boolean, Symbol, String]
11
+ # @return [Boolean]
12
+ # @raise
13
+ # @api private
14
+ def self.boolean(value)
15
+ # downcase strings
16
+ if value.respond_to? :downcase
17
+ value = value.downcase
18
+ end
19
+
20
+ case value
21
+ when true, :true, 'true', :yes, 'yes'
22
+ true
23
+ when false, :false, 'false', :no, 'no'
24
+ false
25
+ else
26
+ fail('expected a boolean value')
27
+ end
28
+ end
29
+ end
@@ -210,6 +210,13 @@ class Puppet::Configurer
210
210
  Puppet::Transaction::Report.indirection.save(report, nil, :environment => @environment) if Puppet[:report]
211
211
  rescue => detail
212
212
  Puppet.log_exception(detail, "Could not send report: #{detail}")
213
+ if detail.message =~ /Could not intern from pson.*Puppet::Transaction::Report/
214
+ Puppet.notice("There was an error sending the report.")
215
+ Puppet.notice("This error is possibly caused by sending the report in a format the master can not handle.")
216
+ Puppet.notice("A puppet master older than 3.2.2 can not handle pson reports.")
217
+ Puppet.notice("Set report_serialization_format=yaml on the agent to send reports to older masters.")
218
+ Puppet.notice("See http://links.puppetlabs.com/deprecate_yaml_on_network for more information.")
219
+ end
213
220
  end
214
221
 
215
222
  def save_last_run_summary(report)
@@ -1081,6 +1081,24 @@ EOT
1081
1081
  can be guaranteed to support this format, but it will be used for all
1082
1082
  classes that support it.",
1083
1083
  },
1084
+ :report_serialization_format => {
1085
+ :default => "pson",
1086
+ :type => :enum,
1087
+ :values => ["pson", "yaml"],
1088
+ :desc => "The serialization format to use when sending reports to the
1089
+ `report_server`. Possible values are `pson` and `yaml`. This setting
1090
+ affects puppet agent, but not puppet apply (which processes its own
1091
+ reports).
1092
+
1093
+ This should almost always be set to `pson`. It can be temporarily set to
1094
+ `yaml` to let agents using this Puppet version connect to a puppet master
1095
+ running Puppet 3.0.0 through 3.2.4.",
1096
+ :hook => proc do |value|
1097
+ if value == "yaml"
1098
+ Puppet.deprecation_warning("Sending reports in 'yaml' is deprecated; use 'pson' instead.")
1099
+ end
1100
+ end
1101
+ },
1084
1102
  :agent_catalog_run_lockfile => {
1085
1103
  :default => "$statedir/agent_catalog_run.lock",
1086
1104
  :type => :string, # (#2888) Ensure this file is not added to the settings catalog.
@@ -1234,13 +1252,21 @@ EOT
1234
1252
  :type => :enum,
1235
1253
  :values => ["manifest", "title-hash", "random"],
1236
1254
  :default => "title-hash",
1237
- :desc => "Controls the default ordering to use in the absence of any
1238
- dependency information. By default this is 'title-hash', which is an
1239
- opaque, stable, random order. The value of 'manifest' will use the order
1240
- in which the resources were added to the catalog, which matches the order
1241
- that the puppet language executes. The final value of 'random' causes
1242
- resources to be assigned a random order, while still obeying declared
1243
- dependencies."
1255
+ :desc => "How unrelated resources should be ordered when applying a catalog.
1256
+ Allowed values are `title-hash`, `manifest`, and `random`. This
1257
+ setting affects puppet agent and puppet apply, but not puppet master.
1258
+
1259
+ * `title-hash` (the default) will order resources randomly, but will use
1260
+ the same order across runs and across nodes.
1261
+ * `manifest` will use the order in which the resources were declared in
1262
+ their manifest files.
1263
+ * `random` will order resources randomly and change their order with each
1264
+ run. This can work like a fuzzer for shaking out undeclared dependencies.
1265
+
1266
+ Regardless of this setting's value, Puppet will always obey explicit
1267
+ dependencies set with the before/require/notify/subscribe metaparameters
1268
+ and the `->`/`~>` chaining arrows; this setting only affects the relative
1269
+ ordering of _unrelated_ resources."
1244
1270
  }
1245
1271
  )
1246
1272
 
@@ -13,6 +13,15 @@ class Puppet::FileBucket::File
13
13
  attr :contents
14
14
  attr :bucket_path
15
15
 
16
+ def self.supported_formats
17
+ # This should really be :raw, like is done for Puppet::FileServing::Content
18
+ # but this class hasn't historically supported `from_raw`, so switching
19
+ # would break compatibility between newer 3.x agents talking to older 3.x
20
+ # masters. However, to/from_s has been supported and achieves the desired
21
+ # result without breaking compatibility.
22
+ [:s]
23
+ end
24
+
16
25
  def initialize(contents, options = {})
17
26
  raise ArgumentError.new("contents must be a String, got a #{contents.class}") unless contents.is_a?(String)
18
27
  @contents = contents
@@ -45,11 +54,10 @@ class Puppet::FileBucket::File
45
54
  self.new(contents)
46
55
  end
47
56
 
48
- def to_pson
49
- { "contents" => contents }.to_pson
50
- end
51
-
57
+ # This method is deprecated, but cannot be removed for awhile, otherwise
58
+ # older agents sending pson couldn't backup to filebuckets on newer masters
52
59
  def self.from_pson(pson)
60
+ Puppet.deprecation_warning("Deserializing Puppet::FileBucket::File objects from pson is deprecated. Upgrade to a newer version.")
53
61
  self.new(pson["contents"])
54
62
  end
55
63
  end
@@ -44,7 +44,9 @@ module Puppet::FileBucketFile
44
44
  checksum, files_original_path = request_to_checksum_and_path(request)
45
45
 
46
46
  save_to_disk(instance, files_original_path)
47
- instance.to_s
47
+
48
+ # don't echo the request content back to the agent
49
+ model.new('')
48
50
  end
49
51
 
50
52
  def validate_key(request)
@@ -67,20 +67,28 @@ module Puppet::Network::FormatHandler
67
67
  # Determine which of the accepted formats should be used given what is supported.
68
68
  #
69
69
  # @param accepted [Array<String, Symbol>] the accepted formats in a form a
70
- # that can be understood by #format_to_canonical_name and is in order of
71
- # preference (most preferred is first)
70
+ # that generally conforms to an HTTP Accept header. Any quality specifiers
71
+ # are ignored and instead the formats are simply in strict preference order
72
+ # (most preferred is first)
72
73
  # @param supported [Array<Symbol>] the names of the supported formats (order
73
74
  # does not matter)
74
75
  # @return [Puppet::Network::Format, nil] the most suitable format
75
76
  # @api private
76
77
  def self.most_suitable_format_for(accepted, supported)
77
- format_name = accepted.find do |accepted|
78
+ format_name = accepted.collect do |accepted|
79
+ accepted.to_s.sub(/;q=.*$/, '')
80
+ end.collect do |accepted|
78
81
  begin
79
- format_name = format_to_canonical_name(accepted)
80
- supported.include?(format_name)
82
+ if accepted == '*/*'
83
+ formats
84
+ else
85
+ format_to_canonical_name(accepted)
86
+ end
81
87
  rescue ArgumentError
82
- false
88
+ nil
83
89
  end
90
+ end.flatten.find do |accepted|
91
+ supported.include?(accepted)
84
92
  end
85
93
 
86
94
  if format_name
@@ -1,20 +1,10 @@
1
+ require 'puppet/coercion'
2
+
1
3
  # This specialized {Puppet::Parameter} handles boolean options, accepting lots
2
4
  # of strings and symbols for both truthiness and falsehood.
3
5
  #
4
6
  class Puppet::Parameter::Boolean < Puppet::Parameter
5
7
  def unsafe_munge(value)
6
- # downcase strings
7
- if value.respond_to? :downcase
8
- value = value.downcase
9
- end
10
-
11
- case value
12
- when true, :true, 'true', :yes, 'yes'
13
- true
14
- when false, :false, 'false', :no, 'no'
15
- false
16
- else
17
- fail('expected a boolean value')
18
- end
8
+ Puppet::Coercion.boolean(value)
19
9
  end
20
10
  end
@@ -0,0 +1,7 @@
1
+ require 'puppet/coercion'
2
+
3
+ class Puppet::Property::Boolean < Puppet::Property
4
+ def unsafe_munge(value)
5
+ Puppet::Coercion.boolean(value)
6
+ end
7
+ end
@@ -214,6 +214,11 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
214
214
  expiry_date
215
215
  end
216
216
 
217
+ def open_security_passwd
218
+ # helper method for tests
219
+ File.open("/etc/security/passwd", 'r')
220
+ end
221
+
217
222
  #--------------------------------
218
223
  # Getter and Setter
219
224
  # When the provider is initialized, create getter/setter methods for each
@@ -229,15 +234,15 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
229
234
  def password
230
235
  password = :absent
231
236
  user = @resource[:name]
232
- f = File.open("/etc/security/passwd", 'r')
237
+ f = open_security_passwd
233
238
  # Skip to the user
234
239
  f.each_line { |l| break if l =~ /^#{user}:\s*$/ }
235
240
  if ! f.eof?
236
241
  f.each_line { |l|
237
242
  # If there is a new user stanza, stop
238
243
  break if l =~ /^\S*:\s*$/
239
- # If the password= entry is found, return it
240
- if l =~ /^\s*password\s*=\s*(.*)$/
244
+ # If the password= entry is found, return it, stripping trailing space
245
+ if l =~ /^\s*password\s*=\s*(\S*)\s*$/
241
246
  password = $1; break;
242
247
  end
243
248
  }
@@ -315,6 +315,10 @@ class Puppet::Transaction::Report
315
315
  instance_variables - [:@external_times]
316
316
  end
317
317
 
318
+ def self.supported_formats
319
+ [Puppet[:report_serialization_format].intern]
320
+ end
321
+
318
322
  private
319
323
 
320
324
  def calculate_change_metric
@@ -1,3 +1,5 @@
1
+ require 'puppet/property/boolean'
2
+
1
3
  module Puppet
2
4
  # We want the mount to refresh when it changes.
3
5
  newtype(:mount, :self_refresh => true) do
@@ -182,11 +184,18 @@ module Puppet
182
184
  }
183
185
  end
184
186
 
185
- newproperty(:atboot) do
187
+ newproperty(:atboot, :parent => Puppet::Property::Boolean) do
186
188
  desc "Whether to mount the mount at boot. Not all platforms
187
189
  support this."
188
190
 
189
- newvalues :yes, :no
191
+ def munge(value)
192
+ munged = super
193
+ if munged
194
+ :yes
195
+ else
196
+ :no
197
+ end
198
+ end
190
199
  end
191
200
 
192
201
  newproperty(:dump) do
@@ -7,7 +7,7 @@
7
7
 
8
8
 
9
9
  module Puppet
10
- PUPPETVERSION = '3.3.0-rc2'
10
+ PUPPETVERSION = '3.3.0-rc3'
11
11
 
12
12
  ##
13
13
  # version is a public API method intended to always provide a fast and
@@ -15,8 +15,18 @@ describe Puppet::FileBucket::File do
15
15
  let(:bucketdir) { Puppet[:bucketdir] = tmpdir('bucket') }
16
16
  let(:destdir) { File.join(bucketdir, "8/b/3/7/0/2/a/d/#{digest}") }
17
17
 
18
- it "should have a to_s method to return the contents" do
19
- Puppet::FileBucket::File.new(contents).to_s.should == contents
18
+ it "defines its supported format to be `:s`" do
19
+ expect(Puppet::FileBucket::File.supported_formats).to eq([:s])
20
+ end
21
+
22
+ it "serializes to `:s`" do
23
+ expect(Puppet::FileBucket::File.new(contents).to_s).to eq(contents)
24
+ end
25
+
26
+ it "deserializes from `:s`" do
27
+ file = Puppet::FileBucket::File.from_s(contents)
28
+
29
+ expect(file.contents).to eq(contents)
20
30
  end
21
31
 
22
32
  it "should raise an error if changing content" do
@@ -66,10 +76,16 @@ describe Puppet::FileBucket::File do
66
76
  end
67
77
 
68
78
  it "should convert the contents to PSON" do
69
- Puppet::FileBucket::File.new("file contents").to_pson.should == '{"contents":"file contents"}'
79
+ # The model class no longer defines to_pson and it is not a supported
80
+ # format, but pson monkey patches Object#to_pson to return
81
+ # Object#to_s.to_pson, and it monkey patches String#to_pson to wrap the
82
+ # returned string in quotes. So it works in a way that is completely
83
+ # unexpected, and it doesn't round-trip correctly, awesome.
84
+ Puppet::FileBucket::File.new("file contents").to_pson.should == '"file contents"'
70
85
  end
71
86
 
72
87
  it "should load from PSON" do
88
+ Puppet.expects(:deprecation_warning).with('Deserializing Puppet::FileBucket::File objects from pson is deprecated. Upgrade to a newer version.')
73
89
  Puppet::FileBucket::File.from_pson({"contents"=>"file contents"}).contents.should == "file contents"
74
90
  end
75
91
 
@@ -28,6 +28,12 @@ describe Puppet::FileBucketFile::File do
28
28
  end
29
29
 
30
30
  describe "when servicing a save request" do
31
+ it "should return a result whose content is empty" do
32
+ bucket_file = Puppet::FileBucket::File.new('stuff')
33
+ result = Puppet::FileBucket::File.indirection.save(bucket_file, "md5/c13d88cb4cb02003daedb8a84e5d272a")
34
+ result.contents.should be_empty
35
+ end
36
+
31
37
  describe "when supplying a path" do
32
38
  it "should store the path if not already stored" do
33
39
  checksum = save_bucket_file("stuff\r\n", "/foo/bar")
@@ -53,7 +53,7 @@ describe Puppet::Network::FormatHandler do
53
53
  describe "#most_suitable_format_for" do
54
54
  before :each do
55
55
  Puppet::Network::FormatHandler.create(:one, :extension => "foo", :mime => "text/one")
56
- Puppet::Network::FormatHandler.create(:two, :extension => "bar", :mime => "text/two")
56
+ Puppet::Network::FormatHandler.create(:two, :extension => "bar", :mime => "application/two")
57
57
  end
58
58
 
59
59
  let(:format_one) { Puppet::Network::FormatHandler.format(:one) }
@@ -63,6 +63,10 @@ describe Puppet::Network::FormatHandler do
63
63
  Puppet::Network::FormatHandler.most_suitable_format_for(accepted, [:one, :two])
64
64
  end
65
65
 
66
+ it "finds either format when anything is accepted" do
67
+ [format_one, format_two].should include(suitable_in_setup_formats(["*/*"]))
68
+ end
69
+
66
70
  it "finds no format when none are acceptable" do
67
71
  suitable_in_setup_formats(["three"]).should be_nil
68
72
  end
@@ -79,6 +83,10 @@ describe Puppet::Network::FormatHandler do
79
83
  suitable_in_setup_formats(["text/one"]).should == format_one
80
84
  end
81
85
 
86
+ it "ignores quality specifiers" do
87
+ suitable_in_setup_formats(["two;q=0.8", "text/one;q=0.9"]).should == format_two
88
+ end
89
+
82
90
  it "allows specifying acceptable formats by canonical name" do
83
91
  suitable_in_setup_formats([:one]).should == format_one
84
92
  end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ require 'puppet/property/boolean'
3
+
4
+ describe Puppet::Property::Boolean do
5
+ let (:resource) { mock('resource') }
6
+ subject { described_class.new(:resource => resource) }
7
+
8
+ [ true, :true, 'true', :yes, 'yes', 'TrUe', 'yEs' ].each do |arg|
9
+ it "should munge #{arg.inspect} as true" do
10
+ subject.munge(arg).should == true
11
+ end
12
+ end
13
+ [ false, :false, 'false', :no, 'no', 'FaLSE', 'nO' ].each do |arg|
14
+ it "should munge #{arg.inspect} as false" do
15
+ subject.munge(arg).should == false
16
+ end
17
+ end
18
+ [ nil, :undef, 'undef', '0', 0, '1', 1, 9284 ].each do |arg|
19
+ it "should fail to munge #{arg.inspect}" do
20
+ expect { subject.munge(arg) }.to raise_error Puppet::Error
21
+ end
22
+ end
23
+ end
24
+
@@ -128,4 +128,35 @@ guest id=100 pgrp=usr groups=usr home=/home/guest
128
128
  @provider.should_include?(:rlogin, managed_keys).should be_true
129
129
  end
130
130
  end
131
+ describe "when handling passwords" do
132
+ let(:passwd_without_spaces) do
133
+ # from http://pic.dhe.ibm.com/infocenter/aix/v7r1/index.jsp?topic=%2Fcom.ibm.aix.files%2Fdoc%2Faixfiles%2Fpasswd_security.htm
134
+ <<-OUTPUT
135
+ smith:
136
+ password = MGURSj.F056Dj
137
+ lastupdate = 623078865
138
+ flags = ADMIN,NOCHECK
139
+ OUTPUT
140
+ end
141
+
142
+ let(:passwd_with_spaces) do
143
+ # add trailing space to the password
144
+ passwd_without_spaces.gsub(/password = (.*)/, 'password = \1 ')
145
+ end
146
+
147
+
148
+ it "should be able to read the hashed password" do
149
+ @provider.stubs(:open_security_passwd).returns(StringIO.new(passwd_without_spaces))
150
+ @resource.stubs(:[]).returns('smith')
151
+
152
+ @provider.password.should == 'MGURSj.F056Dj'
153
+ end
154
+
155
+ it "should be able to read the hashed password, even with trailing spaces" do
156
+ @provider.stubs(:open_security_passwd).returns(StringIO.new(passwd_with_spaces))
157
+ @resource.stubs(:[]).returns('smith')
158
+
159
+ @provider.password.should == 'MGURSj.F056Dj'
160
+ end
161
+ end
131
162
  end
@@ -375,20 +375,33 @@ describe Puppet::Transaction::Report do
375
375
  end
376
376
  end
377
377
 
378
+ it "defaults to serializing to pson" do
379
+ expect(Puppet::Transaction::Report.supported_formats).to eq([:pson])
380
+ end
381
+
378
382
  it "can make a round trip through pson" do
379
- status = Puppet::Resource::Status.new(Puppet::Type.type(:notify).new(:title => "a resource"))
380
- status.changed = true
383
+ Puppet[:report_serialization_format] = "pson"
384
+ report = generate_report
381
385
 
382
- report = Puppet::Transaction::Report.new('testy', 1357986, 'test_environment', "df34516e-4050-402d-a166-05b03b940749")
383
- report << Puppet::Util::Log.new(:level => :warning, :message => "log message")
384
- report.add_times("timing", 4)
385
- report.add_resource_status(status)
386
- report.finalize_report
386
+ tripped = Puppet::Transaction::Report.convert_from(:pson, report.render)
387
+
388
+ expect_equivalent_reports(tripped, report)
389
+ end
387
390
 
388
- tripped = Puppet::Transaction::Report.convert_from(:pson, report.render(:pson))
391
+ it "can make a round trip through yaml" do
392
+ Puppet[:report_serialization_format] = "yaml"
393
+ report = generate_report
394
+
395
+ yaml_output = report.render
396
+ tripped = Puppet::Transaction::Report.convert_from(:yaml, yaml_output)
397
+
398
+ yaml_output.should =~ /^--- /
399
+ expect_equivalent_reports(tripped, report)
400
+ end
389
401
 
402
+ def expect_equivalent_reports(tripped, report)
390
403
  tripped.host.should == report.host
391
- tripped.time.should == report.time
404
+ tripped.time.to_i.should == report.time.to_i
392
405
  tripped.configuration_version.should == report.configuration_version
393
406
  tripped.transaction_uuid.should == report.transaction_uuid
394
407
  tripped.report_format.should == report.report_format
@@ -399,7 +412,7 @@ describe Puppet::Transaction::Report do
399
412
 
400
413
  logs_as_strings(tripped).should == logs_as_strings(report)
401
414
  metrics_as_hashes(tripped).should == metrics_as_hashes(report)
402
- resource_statuses_as_hashes(tripped).should == resource_statuses_as_hashes(report)
415
+ expect_equivalent_resource_statuses(tripped.resource_statuses, report.resource_statuses)
403
416
  end
404
417
 
405
418
  def logs_as_strings(report)
@@ -412,9 +425,41 @@ describe Puppet::Transaction::Report do
412
425
  end.flatten]
413
426
  end
414
427
 
415
- def resource_statuses_as_hashes(report)
416
- Hash[*report.resource_statuses.collect do |name, s|
417
- [name, PSON.parse(s.to_pson)]
418
- end.flatten]
428
+ def expect_equivalent_resource_statuses(tripped, report)
429
+ tripped.keys.sort.should == report.keys.sort
430
+
431
+ tripped.each_pair do |name, status|
432
+ expected = report[name]
433
+
434
+ status.title.should == expected.title
435
+ status.file.should == expected.file
436
+ status.line.should == expected.line
437
+ status.resource.should == expected.resource
438
+ status.resource_type.should == expected.resource_type
439
+ status.containment_path.should == expected.containment_path
440
+ status.evaluation_time.should == expected.evaluation_time
441
+ status.tags.should == expected.tags
442
+ status.time.to_i.should == expected.time.to_i
443
+ status.failed.should == expected.failed
444
+ status.changed.should == expected.changed
445
+ status.out_of_sync.should == expected.out_of_sync
446
+ status.skipped.should == expected.skipped
447
+ status.change_count.should == expected.change_count
448
+ status.out_of_sync_count.should == expected.out_of_sync_count
449
+ status.events.should == expected.events
450
+ end
419
451
  end
452
+
453
+ def generate_report
454
+ status = Puppet::Resource::Status.new(Puppet::Type.type(:notify).new(:title => "a resource"))
455
+ status.changed = true
456
+
457
+ report = Puppet::Transaction::Report.new('testy', 1357986, 'test_environment', "df34516e-4050-402d-a166-05b03b940749")
458
+ report << Puppet::Util::Log.new(:level => :warning, :message => "log message")
459
+ report.add_times("timing", 4)
460
+ report.add_resource_status(status)
461
+ report.finalize_report
462
+ report
463
+ end
464
+
420
465
  end
@@ -263,16 +263,32 @@ describe Puppet::Type.type(:mount), :unless => Puppet.features.microsoft_windows
263
263
  end
264
264
 
265
265
  describe "for atboot" do
266
- it "should support yes as a value for atboot" do
267
- expect { described_class.new(:name => "/foo", :ensure => :present, :atboot => :yes) }.to_not raise_error
266
+ it "does not allow non-boolean values" do
267
+ expect { described_class.new(:name => "/foo", :ensure => :present, :atboot => 'unknown') }.to raise_error Puppet::Error, /expected a boolean value/
268
268
  end
269
269
 
270
- it "should support no as a value for atboot" do
271
- expect { described_class.new(:name => "/foo", :ensure => :present, :atboot => :no) }.to_not raise_error
270
+ it "interprets yes as yes" do
271
+ resource = described_class.new(:name => "/foo", :ensure => :present, :atboot => :yes)
272
+
273
+ expect(resource[:atboot]).to eq(:yes)
274
+ end
275
+
276
+ it "interprets true as yes" do
277
+ resource = described_class.new(:name => "/foo", :ensure => :present, :atboot => :true)
278
+
279
+ expect(resource[:atboot]).to eq(:yes)
272
280
  end
273
281
 
274
- it "should not support other values for atboot" do
275
- expect { described_class.new(:name => "/foo", :ensure => :present, :atboot => :true) }.to raise_error Puppet::Error, /Invalid value/
282
+ it "interprets no as no" do
283
+ resource = described_class.new(:name => "/foo", :ensure => :present, :atboot => :no)
284
+
285
+ expect(resource[:atboot]).to eq(:no)
286
+ end
287
+
288
+ it "interprets false as no" do
289
+ resource = described_class.new(:name => "/foo", :ensure => :present, :atboot => false)
290
+
291
+ expect(resource[:atboot]).to eq(:no)
276
292
  end
277
293
  end
278
294
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppet
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0.rc2
4
+ version: 3.3.0.rc3
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-29 00:00:00.000000000 Z
12
+ date: 2013-09-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: facter
@@ -121,6 +121,7 @@ files:
121
121
  - lib/puppet/application/secret_agent.rb
122
122
  - lib/puppet/application/status.rb
123
123
  - lib/puppet/bindings.rb
124
+ - lib/puppet/coercion.rb
124
125
  - lib/puppet/configurer.rb
125
126
  - lib/puppet/configurer/downloader.rb
126
127
  - lib/puppet/configurer/fact_handler.rb
@@ -576,6 +577,7 @@ files:
576
577
  - lib/puppet/pops/visitable.rb
577
578
  - lib/puppet/pops/visitor.rb
578
579
  - lib/puppet/property.rb
580
+ - lib/puppet/property/boolean.rb
579
581
  - lib/puppet/property/ensure.rb
580
582
  - lib/puppet/property/keyvalue.rb
581
583
  - lib/puppet/property/list.rb
@@ -1860,6 +1862,7 @@ files:
1860
1862
  - spec/unit/pops/types/type_factory_spec.rb
1861
1863
  - spec/unit/pops/types/type_parser_spec.rb
1862
1864
  - spec/unit/pops/visitor_spec.rb
1865
+ - spec/unit/property/boolean_spec.rb
1863
1866
  - spec/unit/property/ensure_spec.rb
1864
1867
  - spec/unit/property/keyvalue_spec.rb
1865
1868
  - spec/unit/property/list_spec.rb
@@ -2838,6 +2841,7 @@ test_files:
2838
2841
  - spec/unit/pops/types/type_factory_spec.rb
2839
2842
  - spec/unit/pops/types/type_parser_spec.rb
2840
2843
  - spec/unit/pops/visitor_spec.rb
2844
+ - spec/unit/property/boolean_spec.rb
2841
2845
  - spec/unit/property/ensure_spec.rb
2842
2846
  - spec/unit/property/keyvalue_spec.rb
2843
2847
  - spec/unit/property/list_spec.rb