chef 12.0.0.alpha.0 → 12.0.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (207) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +3 -5
  3. data/lib/chef/api_client.rb +1 -1
  4. data/lib/chef/application.rb +16 -8
  5. data/lib/chef/chef_fs/chef_fs_data_store.rb +1 -1
  6. data/lib/chef/chef_fs/command_line.rb +1 -1
  7. data/lib/chef/chef_fs/file_system.rb +1 -1
  8. data/lib/chef/chef_fs/file_system/acl_entry.rb +1 -1
  9. data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +3 -3
  10. data/lib/chef/chef_fs/file_system/cookbook_file.rb +2 -2
  11. data/lib/chef/chef_fs/file_system/rest_list_dir.rb +2 -2
  12. data/lib/chef/chef_fs/file_system/rest_list_entry.rb +4 -4
  13. data/lib/chef/config.rb +6 -5
  14. data/lib/chef/config_fetcher.rb +1 -1
  15. data/lib/chef/cookbook/cookbook_version_loader.rb +126 -43
  16. data/lib/chef/cookbook/metadata.rb +102 -53
  17. data/lib/chef/cookbook/syntax_check.rb +1 -1
  18. data/lib/chef/cookbook_loader.rb +62 -14
  19. data/lib/chef/cookbook_site_streaming_uploader.rb +12 -1
  20. data/lib/chef/cookbook_version.rb +13 -4
  21. data/lib/chef/data_bag.rb +28 -15
  22. data/lib/chef/data_bag_item.rb +5 -7
  23. data/lib/chef/digester.rb +5 -9
  24. data/lib/chef/dsl/recipe.rb +14 -0
  25. data/lib/chef/encrypted_data_bag_item.rb +1 -0
  26. data/lib/chef/encrypted_data_bag_item/assertions.rb +57 -0
  27. data/lib/chef/encrypted_data_bag_item/decryptor.rb +52 -28
  28. data/lib/chef/encrypted_data_bag_item/encrypted_data_bag_item_assertions.rb +37 -0
  29. data/lib/chef/encrypted_data_bag_item/encryption_failure.rb +22 -0
  30. data/lib/chef/encrypted_data_bag_item/encryptor.rb +79 -8
  31. data/lib/chef/environment.rb +1 -3
  32. data/lib/chef/exceptions.rb +18 -3
  33. data/lib/chef/formatters/base.rb +7 -0
  34. data/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb +1 -1
  35. data/lib/chef/handler/json_file.rb +0 -1
  36. data/lib/chef/http/json_output.rb +1 -1
  37. data/lib/chef/json_compat.rb +24 -6
  38. data/lib/chef/knife/bootstrap.rb +2 -2
  39. data/lib/chef/knife/client_delete.rb +1 -1
  40. data/lib/chef/knife/cookbook_site_download.rb +1 -1
  41. data/lib/chef/knife/cookbook_site_list.rb +1 -1
  42. data/lib/chef/knife/cookbook_site_search.rb +1 -1
  43. data/lib/chef/knife/cookbook_site_share.rb +2 -2
  44. data/lib/chef/knife/cookbook_site_show.rb +3 -3
  45. data/lib/chef/knife/cookbook_site_unshare.rb +1 -1
  46. data/lib/chef/knife/core/node_editor.rb +2 -3
  47. data/lib/chef/knife/core/ui.rb +2 -2
  48. data/lib/chef/knife/deps.rb +2 -3
  49. data/lib/chef/mixin/shell_out.rb +1 -1
  50. data/lib/chef/mixin/windows_architecture_helper.rb +1 -0
  51. data/lib/chef/node.rb +1 -2
  52. data/lib/chef/platform/provider_mapping.rb +33 -6
  53. data/lib/chef/provider.rb +0 -2
  54. data/lib/chef/provider/cookbook_file/content.rb +1 -1
  55. data/lib/chef/provider/cron.rb +11 -0
  56. data/lib/chef/provider/deploy.rb +3 -2
  57. data/lib/chef/provider/deploy/revision.rb +2 -2
  58. data/lib/chef/provider/env.rb +1 -1
  59. data/lib/chef/provider/env/windows.rb +5 -9
  60. data/lib/chef/provider/file.rb +84 -33
  61. data/lib/chef/provider/git.rb +2 -1
  62. data/lib/chef/provider/group/aix.rb +17 -2
  63. data/lib/chef/provider/group/dscl.rb +27 -9
  64. data/lib/chef/provider/group/pw.rb +8 -1
  65. data/lib/chef/provider/http_request.rb +4 -4
  66. data/lib/chef/provider/log.rb +4 -14
  67. data/lib/chef/provider/mount/mount.rb +2 -2
  68. data/lib/chef/provider/package/ips.rb +17 -23
  69. data/lib/chef/provider/package/paludis.rb +2 -2
  70. data/lib/chef/provider/package/rpm.rb +2 -2
  71. data/lib/chef/provider/package/rubygems.rb +2 -0
  72. data/lib/chef/provider/package/yum.rb +2 -0
  73. data/lib/chef/provider/package/zypper.rb +1 -1
  74. data/lib/chef/provider/remote_file/cache_control_data.rb +2 -2
  75. data/lib/chef/provider/service/windows.rb +87 -21
  76. data/lib/chef/provider/user/aix.rb +95 -0
  77. data/lib/chef/provider/user/dscl.rb +544 -156
  78. data/lib/chef/provider/user/useradd.rb +1 -0
  79. data/lib/chef/providers.rb +1 -0
  80. data/lib/chef/resource.rb +4 -3
  81. data/lib/chef/resource/freebsd_package.rb +10 -2
  82. data/lib/chef/resource/paludis_package.rb +1 -0
  83. data/lib/chef/resource/scm.rb +10 -0
  84. data/lib/chef/resource/user.rb +27 -0
  85. data/lib/chef/resource/windows_service.rb +53 -0
  86. data/lib/chef/resource_collection.rb +23 -12
  87. data/lib/chef/resource_reporter.rb +10 -10
  88. data/lib/chef/resources.rb +1 -0
  89. data/lib/chef/role.rb +3 -3
  90. data/lib/chef/run_list.rb +6 -3
  91. data/lib/chef/user.rb +1 -1
  92. data/lib/chef/util/diff.rb +1 -2
  93. data/lib/chef/version.rb +1 -1
  94. data/lib/chef/version_constraint.rb +4 -4
  95. data/spec/data/cookbooks/angrybash/metadata.rb +2 -0
  96. data/spec/data/cookbooks/apache2/metadata.rb +2 -0
  97. data/spec/data/cookbooks/borken/metadata.rb +2 -0
  98. data/spec/data/cookbooks/ignorken/metadata.rb +2 -0
  99. data/spec/data/cookbooks/java/metadata.rb +2 -0
  100. data/spec/data/cookbooks/name-mismatch-versionnumber/README.md +4 -0
  101. data/spec/data/cookbooks/name-mismatch-versionnumber/metadata.rb +8 -0
  102. data/spec/data/cookbooks/name-mismatch-versionnumber/recipes/default.rb +8 -0
  103. data/spec/data/cookbooks/openldap/files/default/remotedir/not_a_template.erb +2 -0
  104. data/spec/data/cookbooks/preseed/metadata.rb +2 -0
  105. data/spec/data/incomplete-metadata-chef-repo/incomplete-metadata/README.md +4 -0
  106. data/spec/data/incomplete-metadata-chef-repo/incomplete-metadata/metadata.rb +13 -0
  107. data/spec/data/incomplete-metadata-chef-repo/incomplete-metadata/recipes/default.rb +8 -0
  108. data/spec/data/invalid-metadata-chef-repo/invalid-metadata/README.md +4 -0
  109. data/spec/data/invalid-metadata-chef-repo/invalid-metadata/metadata.rb +10 -0
  110. data/spec/data/invalid-metadata-chef-repo/invalid-metadata/recipes/default.rb +8 -0
  111. data/spec/data/mac_users/10.7-8.plist.xml +559 -0
  112. data/spec/data/mac_users/10.7-8.shadow.xml +11 -0
  113. data/spec/data/mac_users/10.7.plist.xml +559 -0
  114. data/spec/data/mac_users/10.7.shadow.xml +11 -0
  115. data/spec/data/mac_users/10.8.plist.xml +559 -0
  116. data/spec/data/mac_users/10.8.shadow.xml +21 -0
  117. data/spec/data/mac_users/10.9.plist.xml +560 -0
  118. data/spec/data/mac_users/10.9.shadow.xml +21 -0
  119. data/spec/data/object_loader/environments/test.json +2 -0
  120. data/spec/data/object_loader/environments/test_json_class.json +2 -0
  121. data/spec/data/object_loader/nodes/test.json +2 -0
  122. data/spec/data/object_loader/nodes/test_json_class.json +2 -0
  123. data/spec/data/object_loader/roles/test.json +2 -0
  124. data/spec/data/object_loader/roles/test_json_class.json +2 -0
  125. data/spec/functional/resource/bff_spec.rb +1 -1
  126. data/spec/functional/resource/cron_spec.rb +20 -1
  127. data/spec/functional/resource/env_spec.rb +137 -0
  128. data/spec/functional/resource/group_spec.rb +7 -5
  129. data/spec/functional/resource/remote_file_spec.rb +12 -1
  130. data/spec/functional/resource/user/dscl_spec.rb +198 -0
  131. data/spec/functional/resource/{user_spec.rb → user/useradd_spec.rb} +175 -37
  132. data/spec/integration/client/client_spec.rb +6 -4
  133. data/spec/integration/client/ipv6_spec.rb +16 -14
  134. data/spec/integration/knife/chef_fs_data_store_spec.rb +57 -46
  135. data/spec/integration/knife/chef_repo_path_spec.rb +105 -78
  136. data/spec/integration/knife/chef_repository_file_system_spec.rb +100 -84
  137. data/spec/integration/knife/chefignore_spec.rb +76 -46
  138. data/spec/integration/knife/common_options_spec.rb +16 -21
  139. data/spec/integration/knife/cookbook_api_ipv6_spec.rb +3 -3
  140. data/spec/integration/knife/delete_spec.rb +66 -46
  141. data/spec/integration/knife/deps_spec.rb +145 -94
  142. data/spec/integration/knife/diff_spec.rb +176 -110
  143. data/spec/integration/knife/download_spec.rb +229 -133
  144. data/spec/integration/knife/list_spec.rb +62 -54
  145. data/spec/integration/knife/raw_spec.rb +24 -9
  146. data/spec/integration/knife/redirection_spec.rb +2 -2
  147. data/spec/integration/knife/serve_spec.rb +2 -2
  148. data/spec/integration/knife/show_spec.rb +32 -26
  149. data/spec/integration/knife/upload_spec.rb +308 -165
  150. data/spec/integration/recipes/lwrp_inline_resources_spec.rb +10 -8
  151. data/spec/integration/solo/solo_spec.rb +22 -11
  152. data/spec/spec_helper.rb +3 -0
  153. data/spec/support/lib/chef/resource/zen_follower.rb +46 -0
  154. data/spec/support/platform_helpers.rb +12 -0
  155. data/spec/support/shared/functional/file_resource.rb +10 -0
  156. data/spec/support/shared/integration/chef_zero_support.rb +130 -0
  157. data/spec/support/shared/integration/integration_helper.rb +100 -98
  158. data/spec/support/shared/integration/knife_support.rb +0 -1
  159. data/spec/support/shared/unit/provider/file.rb +6 -4
  160. data/spec/support/shared/unit/provider/useradd_based_user_provider.rb +10 -1
  161. data/spec/unit/api_client/registration_spec.rb +83 -74
  162. data/spec/unit/application_spec.rb +32 -9
  163. data/spec/unit/cookbook/cookbook_version_loader_spec.rb +179 -0
  164. data/spec/unit/cookbook/metadata_spec.rb +190 -150
  165. data/spec/unit/cookbook/syntax_check_spec.rb +3 -2
  166. data/spec/unit/cookbook_loader_spec.rb +114 -53
  167. data/spec/unit/{cookbook_site_streaming_uploader.rb → cookbook_site_streaming_uploader_spec.rb} +21 -1
  168. data/spec/unit/data_bag_spec.rb +88 -13
  169. data/spec/unit/deprecation_spec.rb +1 -2
  170. data/spec/unit/encrypted_data_bag_item_spec.rb +145 -9
  171. data/spec/unit/environment_spec.rb +1 -1
  172. data/spec/unit/formatters/base_spec.rb +48 -0
  173. data/spec/unit/json_compat_spec.rb +48 -17
  174. data/spec/unit/knife/client_delete_spec.rb +4 -4
  175. data/spec/unit/knife/client_show_spec.rb +15 -5
  176. data/spec/unit/knife/cookbook_site_download_spec.rb +1 -1
  177. data/spec/unit/knife/cookbook_site_share_spec.rb +3 -3
  178. data/spec/unit/knife/data_bag_from_file_spec.rb +0 -2
  179. data/spec/unit/knife/data_bag_show_spec.rb +23 -14
  180. data/spec/unit/knife/node_show_spec.rb +32 -15
  181. data/spec/unit/knife/role_show_spec.rb +59 -0
  182. data/spec/unit/platform_spec.rb +10 -0
  183. data/spec/unit/provider/deploy_spec.rb +4 -0
  184. data/spec/unit/provider/env_spec.rb +19 -0
  185. data/spec/unit/provider/git_spec.rb +22 -2
  186. data/spec/unit/provider/group/dscl_spec.rb +38 -1
  187. data/spec/unit/provider/group/pw_spec.rb +2 -2
  188. data/spec/unit/provider/http_request_spec.rb +8 -8
  189. data/spec/unit/provider/log_spec.rb +33 -53
  190. data/spec/unit/provider/mount/mount_spec.rb +12 -3
  191. data/spec/unit/provider/package/ips_spec.rb +96 -63
  192. data/spec/unit/provider/package/paludis_spec.rb +5 -5
  193. data/spec/unit/provider/package/rpm_spec.rb +12 -0
  194. data/spec/unit/provider/package/zypper_spec.rb +28 -16
  195. data/spec/unit/provider/service/windows_spec.rb +77 -17
  196. data/spec/unit/provider/user/dscl_spec.rb +659 -264
  197. data/spec/unit/provider/user/useradd_spec.rb +1 -0
  198. data/spec/unit/recipe_spec.rb +41 -0
  199. data/spec/unit/resource/scm_spec.rb +11 -0
  200. data/spec/unit/resource/user_spec.rb +4 -0
  201. data/spec/unit/resource/windows_service_spec.rb +46 -0
  202. data/spec/unit/resource_collection_spec.rb +33 -0
  203. data/spec/unit/resource_reporter_spec.rb +48 -0
  204. data/spec/unit/resource_spec.rb +9 -2
  205. data/spec/unit/role_spec.rb +6 -0
  206. data/spec/unit/version_constraint_spec.rb +28 -0
  207. metadata +61 -4
@@ -147,7 +147,8 @@ describe Chef::Cookbook::SyntaxCheck do
147
147
 
148
148
  it "does not remove the invalid file from the list of untested files" do
149
149
  syntax_check.untested_ruby_files.should include(File.join(cookbook_path, 'recipes', 'default.rb'))
150
- lambda { syntax_check.validate_ruby_files }.should_not change(syntax_check, :untested_ruby_files)
150
+ syntax_check.validate_ruby_files
151
+ syntax_check.untested_ruby_files.should include(File.join(cookbook_path, 'recipes', 'default.rb'))
151
152
  end
152
153
 
153
154
  it "indicates that a template file has a syntax error" do
@@ -166,7 +167,7 @@ describe Chef::Cookbook::SyntaxCheck do
166
167
  cookbook_path = File.join(CHEF_SPEC_DATA, 'cookbooks', 'ignorken')
167
168
  Chef::Config[:cookbook_path] = File.dirname(cookbook_path)
168
169
  syntax_check.cookbook_path.replace(cookbook_path)
169
- @ruby_files = [File.join(cookbook_path, 'recipes/default.rb')]
170
+ @ruby_files = [File.join(cookbook_path, 'metadata.rb'), File.join(cookbook_path, 'recipes/default.rb')]
170
171
  end
171
172
 
172
173
  it "shows that ignored ruby files do not require a syntax check" do
@@ -19,39 +19,61 @@
19
19
  require 'spec_helper'
20
20
 
21
21
  describe Chef::CookbookLoader do
22
- before(:each) do
23
- @repo_paths = [ File.expand_path(File.join(CHEF_SPEC_DATA, "kitchen")),
24
- File.expand_path(File.join(CHEF_SPEC_DATA, "cookbooks")) ]
25
- @cookbook_loader = Chef::CookbookLoader.new(@repo_paths)
22
+
23
+ let(:repo_paths) do
24
+ [
25
+ File.expand_path(File.join(CHEF_SPEC_DATA, "kitchen")),
26
+ File.expand_path(File.join(CHEF_SPEC_DATA, "cookbooks"))
27
+ ]
26
28
  end
27
29
 
28
- describe "loading all cookbooks" do
30
+ let(:cookbook_loader) { Chef::CookbookLoader.new(repo_paths) }
31
+
32
+ it "checks each directory only once when loading (CHEF-3487)" do
33
+ cookbook_paths = []
34
+ repo_paths.each do |repo_path|
35
+ cookbook_paths |= Dir[File.join(repo_path, "*")]
36
+ end
37
+
38
+ cookbook_paths.delete_if { |path| File.basename(path) == "chefignore" }
39
+
40
+ cookbook_paths.each do |cookbook_path|
41
+ Chef::Cookbook::CookbookVersionLoader.should_receive(:new).
42
+ with(cookbook_path, anything).
43
+ once.
44
+ and_call_original
45
+ end
46
+ cookbook_loader.load_cookbooks
47
+ end
48
+
49
+
50
+ context "after loading all cookbooks" do
29
51
  before(:each) do
30
- @cookbook_loader.load_cookbooks
52
+ cookbook_loader.load_cookbooks
31
53
  end
32
54
 
33
55
  describe "[]" do
34
56
  it "should return cookbook objects with []" do
35
- @cookbook_loader[:openldap].should be_a_kind_of(Chef::CookbookVersion)
57
+ cookbook_loader[:openldap].should be_a_kind_of(Chef::CookbookVersion)
36
58
  end
37
59
 
38
60
  it "should raise an exception if it cannot find a cookbook with []" do
39
- lambda { @cookbook_loader[:monkeypoop] }.should raise_error(Chef::Exceptions::CookbookNotFoundInRepo)
61
+ lambda { cookbook_loader[:monkeypoop] }.should raise_error(Chef::Exceptions::CookbookNotFoundInRepo)
40
62
  end
41
63
 
42
64
  it "should allow you to look up available cookbooks with [] and a symbol" do
43
- @cookbook_loader[:openldap].name.should eql(:openldap)
65
+ cookbook_loader[:openldap].name.should eql(:openldap)
44
66
  end
45
67
 
46
68
  it "should allow you to look up available cookbooks with [] and a string" do
47
- @cookbook_loader["openldap"].name.should eql(:openldap)
69
+ cookbook_loader["openldap"].name.should eql(:openldap)
48
70
  end
49
71
  end
50
72
 
51
73
  describe "each" do
52
74
  it "should allow you to iterate over cookbooks with each" do
53
75
  seen = Hash.new
54
- @cookbook_loader.each do |cookbook_name, cookbook|
76
+ cookbook_loader.each do |cookbook_name, cookbook|
55
77
  seen[cookbook_name] = true
56
78
  end
57
79
  seen.should have_key("openldap")
@@ -60,7 +82,7 @@ describe Chef::CookbookLoader do
60
82
 
61
83
  it "should iterate in alphabetical order" do
62
84
  seen = Array.new
63
- @cookbook_loader.each do |cookbook_name, cookbook|
85
+ cookbook_loader.each do |cookbook_name, cookbook|
64
86
  seen << cookbook_name
65
87
  end
66
88
  seen[0].should == "angrybash"
@@ -68,106 +90,111 @@ describe Chef::CookbookLoader do
68
90
  seen[2].should == "borken"
69
91
  seen[3].should == "ignorken"
70
92
  seen[4].should == "java"
71
- seen[5].should == "openldap"
93
+ seen[5].should == "name-mismatch"
94
+ seen[6].should == "openldap"
72
95
  end
73
96
  end
74
97
 
75
- describe "load_cookbooks" do
98
+ describe "referencing cookbook files" do
76
99
  it "should find all the cookbooks in the cookbook path" do
77
- Chef::Config.cookbook_path << File.expand_path(File.join(CHEF_SPEC_DATA, "hidden-cookbooks"))
78
- @cookbook_loader.load_cookbooks
79
- @cookbook_loader.should have_key(:openldap)
80
- @cookbook_loader.should have_key(:apache2)
100
+ cookbook_loader.load_cookbooks
101
+ cookbook_loader.should have_key(:openldap)
102
+ cookbook_loader.should have_key(:apache2)
81
103
  end
82
104
 
83
105
  it "should allow you to override an attribute file via cookbook_path" do
84
- @cookbook_loader[:openldap].attribute_filenames.detect { |f|
106
+ cookbook_loader[:openldap].attribute_filenames.detect { |f|
85
107
  f =~ /cookbooks\/openldap\/attributes\/default.rb/
86
108
  }.should_not eql(nil)
87
- @cookbook_loader[:openldap].attribute_filenames.detect { |f|
109
+ cookbook_loader[:openldap].attribute_filenames.detect { |f|
88
110
  f =~ /kitchen\/openldap\/attributes\/default.rb/
89
111
  }.should eql(nil)
90
112
  end
91
113
 
92
114
  it "should load different attribute files from deeper paths" do
93
- @cookbook_loader[:openldap].attribute_filenames.detect { |f|
115
+ cookbook_loader[:openldap].attribute_filenames.detect { |f|
94
116
  f =~ /kitchen\/openldap\/attributes\/robinson.rb/
95
117
  }.should_not eql(nil)
96
118
  end
97
119
 
98
120
  it "should allow you to override a definition file via cookbook_path" do
99
- @cookbook_loader[:openldap].definition_filenames.detect { |f|
121
+ cookbook_loader[:openldap].definition_filenames.detect { |f|
100
122
  f =~ /cookbooks\/openldap\/definitions\/client.rb/
101
123
  }.should_not eql(nil)
102
- @cookbook_loader[:openldap].definition_filenames.detect { |f|
124
+ cookbook_loader[:openldap].definition_filenames.detect { |f|
103
125
  f =~ /kitchen\/openldap\/definitions\/client.rb/
104
126
  }.should eql(nil)
105
127
  end
106
128
 
107
129
  it "should load definition files from deeper paths" do
108
- @cookbook_loader[:openldap].definition_filenames.detect { |f|
130
+ cookbook_loader[:openldap].definition_filenames.detect { |f|
109
131
  f =~ /kitchen\/openldap\/definitions\/drewbarrymore.rb/
110
132
  }.should_not eql(nil)
111
133
  end
112
134
 
113
135
  it "should allow you to override a recipe file via cookbook_path" do
114
- @cookbook_loader[:openldap].recipe_filenames.detect { |f|
136
+ cookbook_loader[:openldap].recipe_filenames.detect { |f|
115
137
  f =~ /cookbooks\/openldap\/recipes\/gigantor.rb/
116
138
  }.should_not eql(nil)
117
- @cookbook_loader[:openldap].recipe_filenames.detect { |f|
139
+ cookbook_loader[:openldap].recipe_filenames.detect { |f|
118
140
  f =~ /kitchen\/openldap\/recipes\/gigantor.rb/
119
141
  }.should eql(nil)
120
142
  end
121
143
 
122
144
  it "should load recipe files from deeper paths" do
123
- @cookbook_loader[:openldap].recipe_filenames.detect { |f|
145
+ cookbook_loader[:openldap].recipe_filenames.detect { |f|
124
146
  f =~ /kitchen\/openldap\/recipes\/woot.rb/
125
147
  }.should_not eql(nil)
126
148
  end
127
149
 
128
150
  it "should allow you to have an 'ignore' file, which skips loading files in later cookbooks" do
129
- @cookbook_loader[:openldap].recipe_filenames.detect { |f|
151
+ cookbook_loader[:openldap].recipe_filenames.detect { |f|
130
152
  f =~ /kitchen\/openldap\/recipes\/ignoreme.rb/
131
153
  }.should eql(nil)
132
154
  end
133
155
 
134
156
  it "should find files that start with a ." do
135
- @cookbook_loader[:openldap].file_filenames.detect { |f|
157
+ cookbook_loader[:openldap].file_filenames.detect { |f|
136
158
  f =~ /\.dotfile$/
137
159
  }.should =~ /\.dotfile$/
138
- @cookbook_loader[:openldap].file_filenames.detect { |f|
160
+ cookbook_loader[:openldap].file_filenames.detect { |f|
139
161
  f =~ /\.ssh\/id_rsa$/
140
162
  }.should =~ /\.ssh\/id_rsa$/
141
163
  end
142
164
 
143
165
  it "should load the metadata for the cookbook" do
144
- @cookbook_loader.metadata[:openldap].name.to_s.should == "openldap"
145
- @cookbook_loader.metadata[:openldap].should be_a_kind_of(Chef::Cookbook::Metadata)
166
+ cookbook_loader.metadata[:openldap].name.to_s.should == "openldap"
167
+ cookbook_loader.metadata[:openldap].should be_a_kind_of(Chef::Cookbook::Metadata)
146
168
  end
147
169
 
148
- it "should check each cookbook directory only once (CHEF-3487)" do
149
- cookbooks = []
150
- @repo_paths.each do |repo_path|
151
- cookbooks |= Dir[File.join(repo_path, "*")]
152
- end
153
- cookbooks.each do |cookbook|
154
- File.should_receive(:directory?).with(cookbook).once;
155
- end
156
- @cookbook_loader.load_cookbooks
157
- end
158
- end # load_cookbooks
170
+ end # referencing cookbook files
159
171
 
160
172
  end # loading all cookbooks
161
173
 
174
+ context "loading all cookbooks when one has invalid metadata" do
175
+
176
+ let(:repo_paths) do
177
+ [
178
+ File.join(CHEF_SPEC_DATA, "kitchen"),
179
+ File.join(CHEF_SPEC_DATA, "cookbooks"),
180
+ File.join(CHEF_SPEC_DATA, "invalid-metadata-chef-repo")
181
+ ]
182
+ end
183
+
184
+ it "does not squelch the exception" do
185
+ expect { cookbook_loader.load_cookbooks }.to raise_error("THIS METADATA HAS A BUG")
186
+ end
187
+
188
+ end
189
+
162
190
  describe "loading only one cookbook" do
163
191
  before(:each) do
164
- @cookbook_loader = Chef::CookbookLoader.new(@repo_paths)
165
- @cookbook_loader.load_cookbook("openldap")
192
+ cookbook_loader.load_cookbook("openldap")
166
193
  end
167
194
 
168
195
  it "should have loaded the correct cookbook" do
169
196
  seen = Hash.new
170
- @cookbook_loader.each do |cookbook_name, cookbook|
197
+ cookbook_loader.each do |cookbook_name, cookbook|
171
198
  seen[cookbook_name] = true
172
199
  end
173
200
  seen.should have_key("openldap")
@@ -176,7 +203,7 @@ describe Chef::CookbookLoader do
176
203
  it "should not duplicate keys when serialized to JSON" do
177
204
  # Chef JSON serialization will generate duplicate keys if given
178
205
  # a Hash containing matching string and symbol keys. See CHEF-4571.
179
- aa = @cookbook_loader["openldap"]
206
+ aa = cookbook_loader["openldap"]
180
207
  aa.to_hash["metadata"].recipes.keys.should_not include(:openldap)
181
208
  aa.to_hash["metadata"].recipes.keys.should include("openldap")
182
209
  expected_desc = "Main Open LDAP configuration"
@@ -190,30 +217,50 @@ describe Chef::CookbookLoader do
190
217
  end
191
218
 
192
219
  it "should not load the cookbook again when accessed" do
193
- @cookbook_loader.should_not_receive('load_cookbook')
194
- @cookbook_loader["openldap"]
220
+ cookbook_loader.should_not_receive('load_cookbook')
221
+ cookbook_loader["openldap"]
195
222
  end
196
223
 
197
224
  it "should not load the other cookbooks" do
198
225
  seen = Hash.new
199
- @cookbook_loader.each do |cookbook_name, cookbook|
226
+ cookbook_loader.each do |cookbook_name, cookbook|
200
227
  seen[cookbook_name] = true
201
228
  end
202
229
  seen.should_not have_key("apache2")
203
230
  end
204
231
 
205
232
  it "should load another cookbook lazily with []" do
206
- @cookbook_loader["apache2"].should be_a_kind_of(Chef::CookbookVersion)
233
+ cookbook_loader["apache2"].should be_a_kind_of(Chef::CookbookVersion)
234
+ end
235
+
236
+ context "when an unrelated cookbook has invalid metadata" do
237
+
238
+ let(:repo_paths) do
239
+ [
240
+ File.join(CHEF_SPEC_DATA, "kitchen"),
241
+ File.join(CHEF_SPEC_DATA, "cookbooks"),
242
+ File.join(CHEF_SPEC_DATA, "invalid-metadata-chef-repo")
243
+ ]
244
+ end
245
+
246
+ it "ignores the invalid cookbook" do
247
+ expect { cookbook_loader["openldap"] }.to_not raise_error
248
+ end
249
+
250
+ it "surfaces the exception if the cookbook is loaded later" do
251
+ expect { cookbook_loader["invalid-metadata"] }.to raise_error("THIS METADATA HAS A BUG")
252
+ end
253
+
207
254
  end
208
255
 
209
256
  describe "loading all cookbooks after loading only one cookbook" do
210
257
  before(:each) do
211
- @cookbook_loader.load_cookbooks
258
+ cookbook_loader.load_cookbooks
212
259
  end
213
260
 
214
261
  it "should load all cookbooks" do
215
262
  seen = Hash.new
216
- @cookbook_loader.each do |cookbook_name, cookbook|
263
+ cookbook_loader.each do |cookbook_name, cookbook|
217
264
  seen[cookbook_name] = true
218
265
  end
219
266
  seen.should have_key("openldap")
@@ -221,4 +268,18 @@ describe Chef::CookbookLoader do
221
268
  end
222
269
  end
223
270
  end # loading only one cookbook
271
+
272
+ describe "loading a single cookbook with a different name than basename" do
273
+
274
+ before(:each) do
275
+ cookbook_loader.load_cookbook("name-mismatch")
276
+ end
277
+
278
+ it "loads the correct cookbook" do
279
+ cookbook_version = cookbook_loader["name-mismatch"]
280
+ cookbook_version.should be_a_kind_of(Chef::CookbookVersion)
281
+ cookbook_version.name.should == :"name-mismatch"
282
+ end
283
+
284
+ end
224
285
  end
@@ -121,6 +121,27 @@ describe Chef::CookbookSiteStreamingUploader do
121
121
  })
122
122
  end
123
123
 
124
+ describe "http verify mode" do
125
+ before do
126
+ @uri = "https://cookbooks.dummy.com/api/v1/cookbooks"
127
+ uri_info = URI.parse(@uri)
128
+ @http = Net::HTTP.new(uri_info.host, uri_info.port)
129
+ Net::HTTP.should_receive(:new).with(uri_info.host, uri_info.port).and_return(@http)
130
+ end
131
+
132
+ it "should be VERIFY_NONE when ssl_verify_mode is :verify_none" do
133
+ Chef::Config[:ssl_verify_mode] = :verify_none
134
+ Chef::CookbookSiteStreamingUploader.make_request(:post, @uri, 'bill', @secret_filename)
135
+ @http.verify_mode.should == OpenSSL::SSL::VERIFY_NONE
136
+ end
137
+
138
+ it "should be VERIFY_PEER when ssl_verify_mode is :verify_peer" do
139
+ Chef::Config[:ssl_verify_mode] = :verify_peer
140
+ Chef::CookbookSiteStreamingUploader.make_request(:post, @uri, 'bill', @secret_filename)
141
+ @http.verify_mode.should == OpenSSL::SSL::VERIFY_PEER
142
+ end
143
+ end
144
+
124
145
  end # make_request
125
146
 
126
147
  describe "StreamPart" do
@@ -197,4 +218,3 @@ describe Chef::CookbookSiteStreamingUploader do
197
218
  end # MultipartStream
198
219
 
199
220
  end
200
-
@@ -128,10 +128,19 @@ describe Chef::DataBag do
128
128
  end
129
129
  end
130
130
 
131
- describe "in solo mode" do
131
+ def file_dir_stub(path, returns = true)
132
+ File.should_receive(:directory?).with(path).and_return(returns)
133
+ end
134
+
135
+ def dir_glob_stub(path, returns = [])
136
+ Dir.should_receive(:glob).with(File.join(path, 'foo/*.json')).and_return(returns)
137
+ end
138
+
139
+ shared_examples_for "data bag in solo mode" do |data_bag_path|
132
140
  before do
133
141
  Chef::Config[:solo] = true
134
- Chef::Config[:data_bag_path] = '/var/chef/data_bags'
142
+ Chef::Config[:data_bag_path] = data_bag_path
143
+ @paths = Array(data_bag_path)
135
144
  end
136
145
 
137
146
  after do
@@ -139,35 +148,93 @@ describe Chef::DataBag do
139
148
  end
140
149
 
141
150
  it "should get the data bag from the data_bag_path" do
142
- File.should_receive(:directory?).with('/var/chef/data_bags').and_return(true)
143
- Dir.should_receive(:glob).with('/var/chef/data_bags/foo/*.json').and_return([])
151
+ @paths.each do |path|
152
+ file_dir_stub(path)
153
+ dir_glob_stub(path)
154
+ end
144
155
  Chef::DataBag.load('foo')
145
156
  end
146
157
 
147
158
  it "should get the data bag from the data_bag_path by symbolic name" do
148
- File.should_receive(:directory?).with('/var/chef/data_bags').and_return(true)
149
- Dir.should_receive(:glob).with('/var/chef/data_bags/foo/*.json').and_return([])
159
+ @paths.each do |path|
160
+ file_dir_stub(path)
161
+ dir_glob_stub(path)
162
+ end
150
163
  Chef::DataBag.load(:foo)
151
164
  end
152
165
 
153
166
  it "should return the data bag" do
154
- File.should_receive(:directory?).with('/var/chef/data_bags').and_return(true)
155
- Dir.stub(:glob).and_return(["/var/chef/data_bags/foo/bar.json", "/var/chef/data_bags/foo/baz.json"])
156
- IO.should_receive(:read).with('/var/chef/data_bags/foo/bar.json').and_return('{"id": "bar", "name": "Bob Bar" }')
157
- IO.should_receive(:read).with('/var/chef/data_bags/foo/baz.json').and_return('{"id": "baz", "name": "John Baz" }')
167
+ @paths.each do |path|
168
+ file_dir_stub(path)
169
+ if path == @paths.first
170
+ dir_glob_stub(path, [File.join(path, 'foo/bar.json'), File.join(path, 'foo/baz.json')])
171
+ else
172
+ dir_glob_stub(path)
173
+ end
174
+ end
175
+ IO.should_receive(:read).with(File.join(@paths.first, 'foo/bar.json')).and_return('{"id": "bar", "name": "Bob Bar" }')
176
+ IO.should_receive(:read).with(File.join(@paths.first, 'foo/baz.json')).and_return('{"id": "baz", "name": "John Baz" }')
158
177
  data_bag = Chef::DataBag.load('foo')
159
178
  data_bag.should == { 'bar' => { 'id' => 'bar', 'name' => 'Bob Bar' }, 'baz' => { 'id' => 'baz', 'name' => 'John Baz' }}
160
179
  end
161
180
 
181
+ it "should raise if data bag has items with similar names but different content" do
182
+ @paths.each do |path|
183
+ file_dir_stub(path)
184
+ item_with_different_content = "{\"id\": \"bar\", \"name\": \"Bob Bar\", \"path\": \"#{path}\"}"
185
+ IO.should_receive(:read).with(File.join(path, 'foo/bar.json')).and_return(item_with_different_content)
186
+ if data_bag_path.is_a?(String)
187
+ dir_glob_stub(path, [File.join(path, 'foo/bar.json'), File.join(path, 'foo/baz.json')])
188
+ item_2_with_different_content = '{"id": "bar", "name": "John Baz"}'
189
+ IO.should_receive(:read).with(File.join(path, 'foo/baz.json')).and_return(item_2_with_different_content)
190
+ else
191
+ dir_glob_stub(path, [File.join(path, 'foo/bar.json')])
192
+ end
193
+ end
194
+ expect { Chef::DataBag.load('foo') }.to raise_error(Chef::Exceptions::DuplicateDataBagItem)
195
+ end
196
+
197
+ it "should return data bag if it has items with similar names and the same content" do
198
+ @paths.each do |path|
199
+ file_dir_stub(path)
200
+ dir_glob_stub(path, [File.join(path, 'foo/bar.json'), File.join(path, 'foo/baz.json')])
201
+ item_with_same_content = '{"id": "bar", "name": "Bob Bar"}'
202
+ IO.should_receive(:read).with(File.join(path, 'foo/bar.json')).and_return(item_with_same_content)
203
+ IO.should_receive(:read).with(File.join(path, 'foo/baz.json')).and_return(item_with_same_content)
204
+ end
205
+ data_bag = Chef::DataBag.load('foo')
206
+ test_data_bag = { 'bar' => { 'id' => 'bar', 'name' => 'Bob Bar'} }
207
+ data_bag.should == test_data_bag
208
+ end
209
+
210
+ it "should merge data bag items if there are no conflicts" do
211
+ @paths.each_with_index do |path, index|
212
+ file_dir_stub(path)
213
+ dir_glob_stub(path, [File.join(path, 'foo/bar.json'), File.join(path, 'foo/baz.json')])
214
+ test_item_with_same_content = '{"id": "bar", "name": "Bob Bar"}'
215
+ IO.should_receive(:read).with(File.join(path, 'foo/bar.json')).and_return(test_item_with_same_content)
216
+ test_uniq_item = "{\"id\": \"baz_#{index}\", \"name\": \"John Baz\", \"path\": \"#{path}\"}"
217
+ IO.should_receive(:read).with(File.join(path, 'foo/baz.json')).and_return(test_uniq_item)
218
+ end
219
+ data_bag = Chef::DataBag.load('foo')
220
+ test_data_bag = { 'bar' => { 'id' => 'bar', 'name' => 'Bob Bar'} }
221
+ @paths.each_with_index do |path, index|
222
+ test_data_bag["baz_#{index}"] = { "id" => "baz_#{index}", "name" => "John Baz", "path" => path }
223
+ end
224
+ data_bag.should == test_data_bag
225
+ end
226
+
162
227
  it "should return the data bag list" do
163
- File.should_receive(:directory?).with('/var/chef/data_bags').and_return(true)
164
- Dir.should_receive(:glob).and_return(["/var/chef/data_bags/foo", "/var/chef/data_bags/bar"])
228
+ @paths.each do |path|
229
+ file_dir_stub(path)
230
+ Dir.should_receive(:glob).and_return([File.join(path, 'foo'), File.join(path, 'bar')])
231
+ end
165
232
  data_bag_list = Chef::DataBag.list
166
233
  data_bag_list.should == { 'bar' => 'bar', 'foo' => 'foo' }
167
234
  end
168
235
 
169
236
  it 'should raise an error if the configured data_bag_path is invalid' do
170
- File.should_receive(:directory?).with('/var/chef/data_bags').and_return(false)
237
+ file_dir_stub(@paths.first, false)
171
238
 
172
239
  lambda {
173
240
  Chef::DataBag.load('foo')
@@ -175,6 +242,14 @@ describe Chef::DataBag do
175
242
  end
176
243
 
177
244
  end
245
+
246
+ describe "data bag with string path" do
247
+ it_should_behave_like "data bag in solo mode", "/var/chef/data_bags"
248
+ end
249
+
250
+ describe "data bag with array path" do
251
+ it_should_behave_like "data bag in solo mode", ["/var/chef/data_bags", "/var/chef/data_bags_2"]
252
+ end
178
253
  end
179
254
 
180
255
  end