chef 11.6.0.rc.0 → 11.6.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/distro/common/html/chef-client.8.html +4 -4
  2. data/distro/common/html/chef-expander.8.html +4 -4
  3. data/distro/common/html/chef-expanderctl.8.html +4 -4
  4. data/distro/common/html/chef-server-webui.8.html +4 -4
  5. data/distro/common/html/chef-server.8.html +4 -4
  6. data/distro/common/html/chef-shell.1.html +4 -4
  7. data/distro/common/html/chef-solo.8.html +4 -4
  8. data/distro/common/html/chef-solr.8.html +4 -4
  9. data/distro/common/html/knife-bootstrap.1.html +4 -4
  10. data/distro/common/html/knife-client.1.html +4 -4
  11. data/distro/common/html/knife-configure.1.html +4 -4
  12. data/distro/common/html/knife-cookbook-site.1.html +4 -4
  13. data/distro/common/html/knife-cookbook.1.html +4 -4
  14. data/distro/common/html/knife-data-bag.1.html +4 -4
  15. data/distro/common/html/knife-environment.1.html +4 -4
  16. data/distro/common/html/knife-exec.1.html +4 -4
  17. data/distro/common/html/knife-index.1.html +4 -4
  18. data/distro/common/html/knife-node.1.html +4 -4
  19. data/distro/common/html/knife-role.1.html +4 -4
  20. data/distro/common/html/knife-search.1.html +4 -4
  21. data/distro/common/html/knife-ssh.1.html +4 -4
  22. data/distro/common/html/knife-status.1.html +4 -4
  23. data/distro/common/html/knife-tag.1.html +4 -4
  24. data/distro/common/html/knife.1.html +4 -4
  25. data/distro/common/man/man1/chef-shell.1 +1 -1
  26. data/distro/common/man/man1/knife-bootstrap.1 +1 -1
  27. data/distro/common/man/man1/knife-client.1 +1 -1
  28. data/distro/common/man/man1/knife-configure.1 +1 -1
  29. data/distro/common/man/man1/knife-cookbook-site.1 +1 -1
  30. data/distro/common/man/man1/knife-cookbook.1 +1 -1
  31. data/distro/common/man/man1/knife-data-bag.1 +1 -1
  32. data/distro/common/man/man1/knife-environment.1 +1 -1
  33. data/distro/common/man/man1/knife-exec.1 +1 -1
  34. data/distro/common/man/man1/knife-index.1 +1 -1
  35. data/distro/common/man/man1/knife-node.1 +1 -1
  36. data/distro/common/man/man1/knife-role.1 +1 -1
  37. data/distro/common/man/man1/knife-search.1 +1 -1
  38. data/distro/common/man/man1/knife-ssh.1 +1 -1
  39. data/distro/common/man/man1/knife-status.1 +1 -1
  40. data/distro/common/man/man1/knife-tag.1 +1 -1
  41. data/distro/common/man/man1/knife.1 +1 -1
  42. data/distro/common/man/man8/chef-client.8 +1 -1
  43. data/distro/common/man/man8/chef-expander.8 +1 -1
  44. data/distro/common/man/man8/chef-expanderctl.8 +1 -1
  45. data/distro/common/man/man8/chef-server-webui.8 +1 -1
  46. data/distro/common/man/man8/chef-server.8 +1 -1
  47. data/distro/common/man/man8/chef-solo.8 +1 -1
  48. data/distro/common/man/man8/chef-solr.8 +1 -1
  49. data/lib/chef/cookbook/cookbook_version_loader.rb +10 -19
  50. data/lib/chef/cookbook/file_system_file_vendor.rb +4 -7
  51. data/lib/chef/cookbook/metadata.rb +1 -10
  52. data/lib/chef/cookbook/syntax_check.rb +4 -4
  53. data/lib/chef/cookbook_uploader.rb +1 -1
  54. data/lib/chef/cookbook_version.rb +6 -10
  55. data/lib/chef/provider/file.rb +2 -1
  56. data/lib/chef/provider/package/yum.rb +1 -1
  57. data/lib/chef/resource/file.rb +2 -0
  58. data/lib/chef/scan_access_control.rb +6 -1
  59. data/lib/chef/util/diff.rb +31 -5
  60. data/lib/chef/version.rb +1 -1
  61. data/spec/functional/knife/exec_spec.rb +2 -2
  62. data/spec/spec_helper.rb +3 -0
  63. data/spec/support/platform_helpers.rb +12 -0
  64. data/spec/support/shared/functional/file_resource.rb +50 -10
  65. data/spec/support/shared/unit/provider/file.rb +4 -2
  66. data/spec/unit/cookbook/metadata_spec.rb +50 -56
  67. data/spec/unit/cookbook_loader_spec.rb +1 -22
  68. data/spec/unit/provider/package/yum_spec.rb +17 -36
  69. data/spec/unit/scan_access_control_spec.rb +4 -2
  70. data/spec/unit/util/diff_spec.rb +351 -11
  71. metadata +53 -9
  72. checksums.yaml +0 -15
  73. data/spec/data/cookbooks/not-nginx/attributes/default.rb +0 -1
  74. data/spec/data/cookbooks/not-nginx/metadata.rb +0 -1
  75. data/spec/data/kitchen/no-really-not-nginx/attributes/default.rb +0 -1
  76. data/spec/data/kitchen/no-really-not-nginx/metadata.rb +0 -1
@@ -37,17 +37,14 @@ class Chef
37
37
  raise ArgumentError, "You must specify at least one repo path" if @repo_paths.empty?
38
38
  end
39
39
 
40
- def cookbooks
41
- @cookbooks ||= Chef::CookbookLoader.new(@repo_paths).load_cookbooks
42
- end
43
-
44
40
  # Implements abstract base's requirement. It looks in the
45
41
  # Chef::Config.cookbook_path file hierarchy for the requested
46
42
  # file.
47
43
  def get_filename(filename)
48
- if cookbooks.has_key?(@cookbook_name)
49
- location = File.join(cookbooks[@cookbook_name].root_dir, filename)
50
- location = nil unless File.exist?(location)
44
+ location = @repo_paths.inject(nil) do |memo, basepath|
45
+ candidate_location = File.join(basepath, @cookbook_name, filename)
46
+ memo = candidate_location if File.exist?(candidate_location)
47
+ memo
51
48
  end
52
49
  raise "File #{filename} does not exist for cookbook #{@cookbook_name}" unless location
53
50
 
@@ -91,7 +91,7 @@ class Chef
91
91
  # metadata<Chef::Cookbook::Metadata>
92
92
  def initialize(cookbook=nil, maintainer='YOUR_COMPANY_NAME', maintainer_email='YOUR_EMAIL', license='none')
93
93
  @cookbook = cookbook
94
- @name = cookbook ? cookbook.name : nil
94
+ @name = cookbook ? cookbook.name : ""
95
95
  @long_description = ""
96
96
  self.maintainer(maintainer)
97
97
  self.maintainer_email(maintainer_email)
@@ -468,15 +468,6 @@ class Chef
468
468
  @groupings = o[GROUPINGS] if o.has_key?(GROUPINGS)
469
469
  @recipes = o[RECIPES] if o.has_key?(RECIPES)
470
470
  @version = o[VERSION] if o.has_key?(VERSION)
471
- #
472
- # XXX: When a client (berkshelf in particular) uploads metadata without a name field, the hosted chef
473
- # ruby server will subsequently return empty string ("") for the metadata.name. In erchef uploading
474
- # metadata without a name field will simply not store or retrieve a name field so we get @name = nil.
475
- # During the migration from ruby to erchef, metadata.name of "" was migrated faithfully even though it
476
- # fails validation, and erchef will return this, so we still have to handle this case unless the
477
- # database is sanitized to remove metadata.name == "".
478
- #
479
- @name = nil if !@name.nil? && @name.empty?
480
471
  self
481
472
  end
482
473
 
@@ -85,14 +85,14 @@ class Chef
85
85
  # validated.
86
86
  attr_reader :validated_files
87
87
 
88
- # Creates a new SyntaxCheck given the +cookbook_pathname+ and a +cookbook_path+.
88
+ # Creates a new SyntaxCheck given the +cookbook_name+ and a +cookbook_path+.
89
89
  # If no +cookbook_path+ is given, +Chef::Config.cookbook_path+ is used.
90
- def self.for_cookbook(cookbook_pathname, cookbook_path=nil)
90
+ def self.for_cookbook(cookbook_name, cookbook_path=nil)
91
91
  cookbook_path ||= Chef::Config.cookbook_path
92
92
  unless cookbook_path
93
- raise ArgumentError, "Cannot find cookbook #{cookbook_pathname} unless Chef::Config.cookbook_path is set or an explicit cookbook path is given"
93
+ raise ArgumentError, "Cannot find cookbook #{cookbook_name} unless Chef::Config.cookbook_path is set or an explicit cookbook path is given"
94
94
  end
95
- new(File.join(cookbook_path, cookbook_pathname.to_s))
95
+ new(File.join(cookbook_path, cookbook_name.to_s))
96
96
  end
97
97
 
98
98
  # Create a new SyntaxCheck object
@@ -159,7 +159,7 @@ class Chef
159
159
 
160
160
  def validate_cookbooks
161
161
  cookbooks.each do |cb|
162
- syntax_checker = Chef::Cookbook::SyntaxCheck.for_cookbook(cb.pathname, @user_cookbook_path)
162
+ syntax_checker = Chef::Cookbook::SyntaxCheck.for_cookbook(cb.name, @user_cookbook_path)
163
163
  Chef::Log.info("Validating ruby files")
164
164
  exit(1) unless syntax_checker.validate_ruby_files
165
165
  Chef::Log.info("Validating templates")
@@ -50,7 +50,7 @@ class Chef
50
50
  attr_accessor :resource_filenames
51
51
  attr_accessor :provider_filenames
52
52
  attr_accessor :root_filenames
53
- attr_accessor :pathname
53
+ attr_accessor :name
54
54
  attr_accessor :metadata
55
55
  attr_accessor :metadata_filenames
56
56
  attr_accessor :status
@@ -83,8 +83,8 @@ class Chef
83
83
  #
84
84
  # === Returns
85
85
  # object<Chef::CookbookVersion>:: Duh. :)
86
- def initialize(pathname)
87
- @pathname = pathname
86
+ def initialize(name)
87
+ @name = name
88
88
  @frozen = false
89
89
  @attribute_filenames = Array.new
90
90
  @definition_filenames = Array.new
@@ -104,10 +104,6 @@ class Chef
104
104
  @metadata = Chef::Cookbook::Metadata.new
105
105
  end
106
106
 
107
- def name
108
- metadata.name || @pathname
109
- end
110
-
111
107
  def version
112
108
  metadata.version
113
109
  end
@@ -602,11 +598,11 @@ class Chef
602
598
  specificity = "default"
603
599
 
604
600
  if segment == :root_files
605
- matcher = segment_file.match(".+/#{Regexp.escape(pathname.to_s)}/(.+)")
601
+ matcher = segment_file.match(".+/#{Regexp.escape(name.to_s)}/(.+)")
606
602
  file_name = matcher[1]
607
603
  path = file_name
608
604
  elsif segment == :templates || segment == :files
609
- matcher = segment_file.match("/#{Regexp.escape(pathname.to_s)}/(#{Regexp.escape(segment.to_s)}/(.+?)/(.+))")
605
+ matcher = segment_file.match("/#{Regexp.escape(name.to_s)}/(#{Regexp.escape(segment.to_s)}/(.+?)/(.+))")
610
606
  unless matcher
611
607
  Chef::Log.debug("Skipping file #{segment_file}, as it isn't in any of the proper directories (platform-version, platform or default)")
612
608
  Chef::Log.debug("You probably need to move #{segment_file} into the 'default' sub-directory")
@@ -616,7 +612,7 @@ class Chef
616
612
  specificity = matcher[2]
617
613
  file_name = matcher[3]
618
614
  else
619
- matcher = segment_file.match("/#{Regexp.escape(pathname.to_s)}/(#{Regexp.escape(segment.to_s)}/(.+))")
615
+ matcher = segment_file.match("/#{Regexp.escape(name.to_s)}/(#{Regexp.escape(segment.to_s)}/(.+))")
620
616
  path = matcher[1]
621
617
  file_name = matcher[2]
622
618
  end
@@ -74,7 +74,7 @@ class Chef
74
74
  # Let children resources override constructing the @current_resource
75
75
  @current_resource ||= Chef::Resource::File.new(@new_resource.name)
76
76
  @current_resource.path(@new_resource.path)
77
- if real_file?(@current_resource.path) && ::File.exists?(@current_resource.path)
77
+ if ::File.exists?(@current_resource.path) && ::File.file?(::File.realpath(@current_resource.path))
78
78
  if @action != :create_if_missing && @current_resource.respond_to?(:checksum)
79
79
  @current_resource.checksum(checksum(@current_resource.path))
80
80
  end
@@ -292,6 +292,7 @@ class Chef
292
292
  converge_by(description) do
293
293
  unlink(@new_resource.path)
294
294
  end
295
+ @current_resource.checksum = nil
295
296
  @file_unlinked = true
296
297
  end
297
298
  end
@@ -759,7 +759,7 @@ class Chef
759
759
  @rpmdb << pkg
760
760
  end
761
761
 
762
- error = status.stderr.readlines
762
+ error = status.stderr
763
763
  rescue Mixlib::ShellOut::CommandTimeout => e
764
764
  Chef::Log.error("#{helper} exceeded timeout #{Chef::Config[:yum_timeout]}")
765
765
  raise(e)
@@ -36,6 +36,8 @@ class Chef
36
36
  state_attrs :checksum, :owner, :group, :mode
37
37
  end
38
38
 
39
+ attr_writer :checksum
40
+
39
41
  provides :file, :on_platforms => :all
40
42
 
41
43
  def initialize(name, run_context=nil)
@@ -127,7 +127,12 @@ class Chef
127
127
  end
128
128
 
129
129
  def stat
130
- @stat ||= @new_resource.instance_of?(Chef::Resource::Link) ? ::File.lstat(@new_resource.path) : ::File.stat(@new_resource.path)
130
+ @stat ||= if @new_resource.instance_of?(Chef::Resource::Link)
131
+ ::File.lstat(@new_resource.path)
132
+ else
133
+ realpath = ::File.realpath(@new_resource.path)
134
+ ::File.stat(realpath)
135
+ end
131
136
  end
132
137
  end
133
138
  end
@@ -22,6 +22,10 @@ class Chef
22
22
  class Diff
23
23
  include Chef::Mixin::ShellOut
24
24
 
25
+ # @todo: to_a, to_s, to_json, inspect defs, accessors for @diff and @error
26
+ # @todo: move coercion to UTF-8 into to_json
27
+ # @todo: replace shellout to diff -u with diff-lcs gem
28
+
25
29
  def for_output
26
30
  # formatted output to a terminal uses arrays of strings and returns error strings
27
31
  @diff.nil? ? [ @error ] : @diff
@@ -75,8 +79,13 @@ class Chef
75
79
 
76
80
  begin
77
81
  # -u: Unified diff format
82
+ # LC_ALL: in ruby 1.9 we want to set nil which is a magic option to mixlib-shellout to
83
+ # pass through the LC_ALL locale. in ruby 1.8 we force to 7-bit 'C' locale
84
+ # (which is the mixlib-shellout default for all rubies all the time).
78
85
  Chef::Log.debug("running: diff -u #{old_file} #{new_file}")
79
- result = shell_out("diff -u #{old_file} #{new_file}")
86
+ locale = ( Object.const_defined? :Encoding ) ? nil : 'C'
87
+ result = shell_out("diff -u #{old_file} #{new_file}", :env => {'LC_ALL' => locale})
88
+
80
89
  rescue Exception => e
81
90
  # Should *not* receive this, but in some circumstances it seems that
82
91
  # an exception can be thrown even using shell_out instead of shell_out!
@@ -94,7 +103,18 @@ class Chef
94
103
  if result.stdout.length > diff_output_threshold
95
104
  return "(long diff of over #{diff_output_threshold} characters, diff output suppressed)"
96
105
  else
97
- @diff = result.stdout.split("\n")
106
+ diff_str = result.stdout
107
+ if Object.const_defined? :Encoding # ruby >= 1.9
108
+ if ( diff_str.encoding == Encoding::ASCII_8BIT &&
109
+ diff_str.encoding != Encoding.default_external &&
110
+ RUBY_VERSION.to_f < 2.0 )
111
+ # @todo mixlib-shellout under ruby 1.9 hands back an ASCII-8BIT encoded string, which needs to
112
+ # be fixed to the default external encoding -- this should be moved into mixlib-shellout
113
+ diff_str = diff_str.force_encoding(Encoding.default_external)
114
+ end
115
+ diff_str.encode!('UTF-8', :invalid => :replace, :undef => :replace, :replace => '?')
116
+ end
117
+ @diff = diff_str.split("\n")
98
118
  @diff.delete("\")
99
119
  return "(diff available)"
100
120
  end
@@ -106,10 +126,16 @@ class Chef
106
126
  end
107
127
 
108
128
  def is_binary?(path)
109
- ::File.open(path) do |file|
110
- buff = file.read(Chef::Config[:diff_filesize_threshold])
129
+ File.open(path) do |file|
130
+ # XXX: this slurps into RAM, but we should have already checked our diff has a reasonable size
131
+ buff = file.read
111
132
  buff = "" if buff.nil?
112
- return buff !~ /^[\r[:print:]]*$/
133
+ begin
134
+ return buff !~ /\A[\s[:print:]]*\z/m
135
+ rescue ArgumentError => e
136
+ return true if e.message =~ /invalid byte sequence/
137
+ raise
138
+ end
113
139
  end
114
140
  end
115
141
 
@@ -17,7 +17,7 @@
17
17
 
18
18
  class Chef
19
19
  CHEF_ROOT = File.dirname(File.expand_path(File.dirname(__FILE__)))
20
- VERSION = '11.6.0.rc.0'
20
+ VERSION = '11.6.0.rc.1'
21
21
  end
22
22
 
23
23
  # NOTE: the Chef::Version class is defined in version_class.rb
@@ -46,12 +46,12 @@ describe Chef::Knife::Exec do
46
46
 
47
47
  pending "executes a script in the context of the chef-shell main context", :ruby_18_only
48
48
 
49
- it "executes a script in the context of the chef-shell main context", :ruby_19_only do
49
+ it "executes a script in the context of the chef-shell main context", :ruby_gte_19_only do
50
50
  @node = Chef::Node.new
51
51
  @node.name("ohai-world")
52
52
  response = {"rows" => [@node],"start" => 0,"total" => 1}
53
53
  @api.get(%r{^/search/node}, 200, response.to_json)
54
- code = "$output.puts nodes.all.inspect"
54
+ code = "$output.puts nodes.all"
55
55
  @knife.config[:exec] = code
56
56
  @knife.run
57
57
  $output.string.should match(%r{node\[ohai-world\]})
@@ -104,6 +104,9 @@ RSpec.configure do |config|
104
104
  config.filter_run_excluding :selinux_only => true unless selinux_enabled?
105
105
  config.filter_run_excluding :ruby_18_only => true unless ruby_18?
106
106
  config.filter_run_excluding :ruby_19_only => true unless ruby_19?
107
+ config.filter_run_excluding :ruby_gte_19_only => true unless ruby_gte_19?
108
+ config.filter_run_excluding :ruby_20_only => true unless ruby_20?
109
+ config.filter_run_excluding :ruby_gte_20_only => true unless ruby_gte_20?
107
110
  config.filter_run_excluding :requires_root => true unless ENV['USER'] == 'root'
108
111
  config.filter_run_excluding :requires_unprivileged_user => true if ENV['USER'] == 'root'
109
112
  config.filter_run_excluding :uses_diff => true unless has_diff?
@@ -1,5 +1,17 @@
1
1
  require 'fcntl'
2
2
 
3
+ def ruby_gte_20?
4
+ RUBY_VERSION.to_f >= 2.0
5
+ end
6
+
7
+ def ruby_gte_19?
8
+ RUBY_VERSION.to_f >= 1.9
9
+ end
10
+
11
+ def ruby_20?
12
+ !!(RUBY_VERSION =~ /^2.0/)
13
+ end
14
+
3
15
  def ruby_19?
4
16
  !!(RUBY_VERSION =~ /^1.9/)
5
17
  end
@@ -523,15 +523,8 @@ shared_examples_for "a configured file resource" do
523
523
  resource.path(link_path)
524
524
  # create symlinks for test context
525
525
  File.symlink(path, link_path)
526
-
527
- # Create source (real) file
528
- File.open(path, "wb") { |f| f.write(wrong_content) }
529
526
  end
530
527
 
531
- include_context "setup broken permissions"
532
-
533
- include_examples "a securable resource with existing target"
534
-
535
528
  after(:each) do
536
529
  # shared examples should not change our test setup of a file resource
537
530
  # pointing at a symlink:
@@ -539,9 +532,56 @@ shared_examples_for "a configured file resource" do
539
532
  FileUtils.rm_rf(link_path)
540
533
  end
541
534
 
542
- it "does not replace the symlink with a real file" do
543
- resource.run_action(:create)
544
- File.should be_symlink(link_path)
535
+ context "and the permissions are incorrect" do
536
+ before do
537
+ # Create source (real) file
538
+ File.open(path, "wb") { |f| f.write(expected_content) }
539
+ end
540
+
541
+
542
+ include_context "setup broken permissions"
543
+
544
+ include_examples "a securable resource with existing target"
545
+
546
+ it "does not replace the symlink with a real file" do
547
+ resource.run_action(:create)
548
+ File.should be_symlink(link_path)
549
+ end
550
+
551
+ end
552
+
553
+ context "and the content is incorrect" do
554
+ before do
555
+ # Create source (real) file
556
+ File.open(path, "wb") { |f| f.write(wrong_content) }
557
+ end
558
+
559
+ it "updates the source file content" do
560
+ pending
561
+ end
562
+
563
+ it "marks the resource as updated" do
564
+ resource.run_action(:create)
565
+ resource.should be_updated_by_last_action
566
+ end
567
+
568
+ it "does not replace the symlink with a real file" do
569
+ resource.run_action(:create)
570
+ File.should be_symlink(link_path)
571
+ end
572
+ end
573
+
574
+ context "and the content and permissions are correct" do
575
+ let(:expect_updated?) { false }
576
+
577
+ before do
578
+ # Create source (real) file
579
+ File.open(path, "wb") { |f| f.write(expected_content) }
580
+ end
581
+ include_context "setup correct permissions"
582
+
583
+ include_examples "a securable resource with existing target"
584
+
545
585
  end
546
586
 
547
587
  end
@@ -146,7 +146,8 @@ shared_examples_for Chef::Provider::File do
146
146
  # mock up the filesystem to behave like unix
147
147
  setup_normal_file
148
148
  stat_struct = mock("::File.stat", :mode => 0600, :uid => 0, :gid => 0, :mtime => 10000)
149
- File.should_receive(:stat).with(resource.path).at_least(:once).and_return(stat_struct)
149
+ resource_real_path = File.realpath(resource.path)
150
+ File.should_receive(:stat).with(resource_real_path).at_least(:once).and_return(stat_struct)
150
151
  Etc.stub!(:getgrgid).with(0).and_return(mock("Group Ent", :name => "wheel"))
151
152
  Etc.stub!(:getpwuid).with(0).and_return(mock("User Ent", :name => "root"))
152
153
  end
@@ -270,7 +271,8 @@ shared_examples_for Chef::Provider::File do
270
271
  # mock up the filesystem to behave like unix
271
272
  setup_normal_file
272
273
  stat_struct = mock("::File.stat", :mode => 0600, :uid => 0, :gid => 0, :mtime => 10000)
273
- File.stub!(:stat).with(resource.path).and_return(stat_struct)
274
+ resource_real_path = File.realpath(resource.path)
275
+ File.stub!(:stat).with(resource_real_path).and_return(stat_struct)
274
276
  Etc.stub!(:getgrgid).with(0).and_return(mock("Group Ent", :name => "wheel"))
275
277
  Etc.stub!(:getpwuid).with(0).and_return(mock("User Ent", :name => "root"))
276
278
  provider.send(:load_resource_attributes_from_file, resource)
@@ -7,9 +7,9 @@
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
9
9
  # You may obtain a copy of the License at
10
- #
10
+ #
11
11
  # http://www.apache.org/licenses/LICENSE-2.0
12
- #
12
+ #
13
13
  # Unless required by applicable law or agreed to in writing, software
14
14
  # distributed under the License is distributed on an "AS IS" BASIS,
15
15
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,7 +20,7 @@
20
20
  require 'spec_helper'
21
21
  require 'chef/cookbook/metadata'
22
22
 
23
- describe Chef::Cookbook::Metadata do
23
+ describe Chef::Cookbook::Metadata do
24
24
  before(:each) do
25
25
  @cookbook = Chef::CookbookVersion.new('test_cookbook')
26
26
  @meta = Chef::Cookbook::Metadata.new(@cookbook)
@@ -86,7 +86,7 @@ describe Chef::Cookbook::Metadata do
86
86
  it "should return a Chef::Cookbook::Metadata object" do
87
87
  @meta.should be_a_kind_of(Chef::Cookbook::Metadata)
88
88
  end
89
-
89
+
90
90
  it "should allow a cookbook as the first argument" do
91
91
  lambda { Chef::Cookbook::Metadata.new(@cookbook) }.should_not raise_error
92
92
  end
@@ -96,7 +96,7 @@ describe Chef::Cookbook::Metadata do
96
96
  end
97
97
 
98
98
  it "should set the maintainer name from the second argument" do
99
- md = Chef::Cookbook::Metadata.new(@cookbook, 'Bobo T. Clown')
99
+ md = Chef::Cookbook::Metadata.new(@cookbook, 'Bobo T. Clown')
100
100
  md.maintainer.should == 'Bobo T. Clown'
101
101
  end
102
102
 
@@ -105,7 +105,7 @@ describe Chef::Cookbook::Metadata do
105
105
  end
106
106
 
107
107
  it "should set the maintainer email from the third argument" do
108
- md = Chef::Cookbook::Metadata.new(@cookbook, 'Bobo T. Clown', 'bobo@clown.co')
108
+ md = Chef::Cookbook::Metadata.new(@cookbook, 'Bobo T. Clown', 'bobo@clown.co')
109
109
  md.maintainer_email.should == 'bobo@clown.co'
110
110
  end
111
111
 
@@ -114,10 +114,10 @@ describe Chef::Cookbook::Metadata do
114
114
  end
115
115
 
116
116
  it "should set the license from the fourth argument" do
117
- md = Chef::Cookbook::Metadata.new(@cookbook, 'Bobo T. Clown', 'bobo@clown.co', 'Clown License v1')
117
+ md = Chef::Cookbook::Metadata.new(@cookbook, 'Bobo T. Clown', 'bobo@clown.co', 'Clown License v1')
118
118
  md.license.should == 'Clown License v1'
119
119
  end
120
- end
120
+ end
121
121
 
122
122
  describe "cookbook" do
123
123
  it "should return the cookbook we were initialized with" do
@@ -133,7 +133,7 @@ describe Chef::Cookbook::Metadata do
133
133
 
134
134
  describe "platforms" do
135
135
  it "should return the current platform hash" do
136
- @meta.platforms.should be_a_kind_of(Hash)
136
+ @meta.platforms.should be_a_kind_of(Hash)
137
137
  end
138
138
  end
139
139
 
@@ -235,7 +235,7 @@ describe Chef::Cookbook::Metadata do
235
235
  end
236
236
  end
237
237
  end
238
-
238
+
239
239
  describe "attribute groupings" do
240
240
  it "should allow you set a grouping" do
241
241
  group = {
@@ -312,7 +312,7 @@ describe Chef::Cookbook::Metadata do
312
312
  @meta.attribute("db/mysql/databases", {})
313
313
  @meta.attributes["db/mysql/databases"][:choice].should == []
314
314
  end
315
-
315
+
316
316
  it "should let calculated be true or false" do
317
317
  lambda {
318
318
  @meta.attribute("db/mysql/databases", :calculated => true)
@@ -324,7 +324,7 @@ describe Chef::Cookbook::Metadata do
324
324
  @meta.attribute("db/mysql/databases", :calculated => Hash.new)
325
325
  }.should raise_error(ArgumentError)
326
326
  end
327
-
327
+
328
328
  it "should set calculated to false by default" do
329
329
  @meta.attribute("db/mysql/databases", {})
330
330
  @meta.attributes["db/mysql/databases"][:calculated].should == false
@@ -350,7 +350,7 @@ describe Chef::Cookbook::Metadata do
350
350
  @meta.attribute("db/mysql/databases", :type => "symbol")
351
351
  }.should_not raise_error(ArgumentError)
352
352
  end
353
-
353
+
354
354
  it "should let type be hash (backwards compatability only)" do
355
355
  lambda {
356
356
  @meta.attribute("db/mysql/databases", :type => "hash")
@@ -375,7 +375,7 @@ describe Chef::Cookbook::Metadata do
375
375
  }.should_not raise_error(ArgumentError)
376
376
  #attrib = @meta.attributes["db/mysql/databases"][:required].should == "required"
377
377
  end
378
-
378
+
379
379
  it "should convert required false to optional" do
380
380
  lambda {
381
381
  @meta.attribute("db/mysql/databases", :required => false)
@@ -387,7 +387,7 @@ describe Chef::Cookbook::Metadata do
387
387
  @meta.attribute("db/mysql/databases", {})
388
388
  @meta.attributes["db/mysql/databases"][:required].should == 'optional'
389
389
  end
390
-
390
+
391
391
  it "should make sure recipes is an array" do
392
392
  lambda {
393
393
  @meta.attribute("db/mysql/databases", :recipes => [])
@@ -399,7 +399,7 @@ describe Chef::Cookbook::Metadata do
399
399
 
400
400
  it "should set recipes to an empty array by default" do
401
401
  @meta.attribute("db/mysql/databases", {})
402
- @meta.attributes["db/mysql/databases"][:recipes].should == []
402
+ @meta.attributes["db/mysql/databases"][:recipes].should == []
403
403
  end
404
404
 
405
405
  it "should allow the default value to be a string, array, or hash" do
@@ -438,14 +438,14 @@ describe Chef::Cookbook::Metadata do
438
438
  lambda {
439
439
  attrs = {
440
440
  :choice => [ "a", "b", "c"],
441
- :default => "b"
441
+ :default => "b"
442
442
  }
443
443
  @meta.attribute("db/mysql/databases", attrs)
444
444
  }.should_not raise_error(ArgumentError)
445
445
  lambda {
446
446
  attrs = {
447
447
  :choice => [ "a", "b", "c", "d", "e"],
448
- :default => ["b", "d"]
448
+ :default => ["b", "d"]
449
449
  }
450
450
  @meta.attribute("db/mysql/databases", attrs)
451
451
  }.should_not raise_error(ArgumentError)
@@ -455,7 +455,7 @@ describe Chef::Cookbook::Metadata do
455
455
  lambda {
456
456
  attrs = {
457
457
  :choice => [ "a", "b", "c"],
458
- :default => "d"
458
+ :default => "d"
459
459
  }
460
460
  @meta.attribute("db/mysql/databases", attrs)
461
461
  }.should raise_error(ArgumentError)
@@ -470,11 +470,11 @@ describe Chef::Cookbook::Metadata do
470
470
  end
471
471
 
472
472
  describe "recipes" do
473
- before(:each) do
473
+ before(:each) do
474
474
  @cookbook.recipe_files = [ "default.rb", "enlighten.rb" ]
475
475
  @meta = Chef::Cookbook::Metadata.new(@cookbook)
476
476
  end
477
-
477
+
478
478
  it "should have the names of the recipes" do
479
479
  @meta.recipes["test_cookbook"].should == ""
480
480
  @meta.recipes["test_cookbook::enlighten"].should == ""
@@ -493,7 +493,7 @@ describe Chef::Cookbook::Metadata do
493
493
  end
494
494
 
495
495
  describe "json" do
496
- before(:each) do
496
+ before(:each) do
497
497
  @cookbook.recipe_files = [ "default.rb", "enlighten.rb" ]
498
498
  @meta = Chef::Cookbook::Metadata.new(@cookbook)
499
499
  @meta.version "1.0"
@@ -509,8 +509,8 @@ describe Chef::Cookbook::Metadata do
509
509
  @meta.provides "foo(:bar, :baz)"
510
510
  @meta.replaces "snarkitron"
511
511
  @meta.recipe "test_cookbook::enlighten", "is your buddy"
512
- @meta.attribute "bizspark/has_login",
513
- :display_name => "You have nothing"
512
+ @meta.attribute "bizspark/has_login",
513
+ :display_name => "You have nothing"
514
514
  @meta.version "1.2.3"
515
515
  end
516
516
 
@@ -524,23 +524,23 @@ describe Chef::Cookbook::Metadata do
524
524
  end
525
525
 
526
526
  %w{
527
- name
528
- description
529
- long_description
530
- maintainer
531
- maintainer_email
527
+ name
528
+ description
529
+ long_description
530
+ maintainer
531
+ maintainer_email
532
532
  license
533
- platforms
534
- dependencies
535
- suggestions
536
- recommendations
537
- conflicting
533
+ platforms
534
+ dependencies
535
+ suggestions
536
+ recommendations
537
+ conflicting
538
538
  providing
539
- replacing
540
- attributes
539
+ replacing
540
+ attributes
541
541
  recipes
542
542
  version
543
- }.each do |t|
543
+ }.each do |t|
544
544
  it "should include '#{t}'" do
545
545
  @serial[t].should == @meta.send(t.to_sym)
546
546
  end
@@ -557,23 +557,23 @@ describe Chef::Cookbook::Metadata do
557
557
  end
558
558
 
559
559
  %w{
560
- name
561
- description
562
- long_description
563
- maintainer
564
- maintainer_email
560
+ name
561
+ description
562
+ long_description
563
+ maintainer
564
+ maintainer_email
565
565
  license
566
- platforms
567
- dependencies
568
- suggestions
569
- recommendations
570
- conflicting
566
+ platforms
567
+ dependencies
568
+ suggestions
569
+ recommendations
570
+ conflicting
571
571
  providing
572
- replacing
573
- attributes
572
+ replacing
573
+ attributes
574
574
  recipes
575
575
  version
576
- }.each do |t|
576
+ }.each do |t|
577
577
  it "should match '#{t}'" do
578
578
  @deserial.send(t.to_sym).should == @meta.send(t.to_sym)
579
579
  end
@@ -585,12 +585,6 @@ describe Chef::Cookbook::Metadata do
585
585
  @hash = @meta.to_hash
586
586
  end
587
587
 
588
- it "should convert a name field containing the empty string to nil" do
589
- @hash['name'] = ""
590
- deserial = Chef::Cookbook::Metadata.from_hash(@hash)
591
- deserial.name.should be_nil
592
- end
593
-
594
588
  [:dependencies,
595
589
  :recommendations,
596
590
  :suggestions,