chef 15.6.10-universal-mingw32 → 15.7.30-universal-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/README.md +2 -2
  4. data/lib/chef/chef_fs/file_system/chef_server/cookbooks_dir.rb +22 -5
  5. data/lib/chef/cookbook/cookbook_version_loader.rb +12 -6
  6. data/lib/chef/cookbook_loader.rb +55 -2
  7. data/lib/chef/cookbook_uploader.rb +2 -0
  8. data/lib/chef/cookbook_version.rb +17 -0
  9. data/lib/chef/dist.rb +3 -3
  10. data/lib/chef/event_loggers/windows_eventlog.rb +1 -1
  11. data/lib/chef/knife/bootstrap.rb +5 -0
  12. data/lib/chef/knife/bootstrap/templates/chef-full.erb +11 -11
  13. data/lib/chef/knife/cookbook_upload.rb +75 -45
  14. data/lib/chef/knife/core/bootstrap_context.rb +5 -5
  15. data/lib/chef/knife/core/windows_bootstrap_context.rb +1 -1
  16. data/lib/chef/knife/supermarket_install.rb +1 -1
  17. data/lib/chef/log/winevt.rb +1 -1
  18. data/lib/chef/mixin/openssl_helper.rb +21 -0
  19. data/lib/chef/monkey_patches/net_http.rb +0 -38
  20. data/lib/chef/provider/cron.rb +54 -9
  21. data/lib/chef/provider/cron/aix.rb +9 -2
  22. data/lib/chef/provider/launchd.rb +1 -1
  23. data/lib/chef/provider/user/aix.rb +1 -1
  24. data/lib/chef/provider/user/mac.rb +17 -22
  25. data/lib/chef/provider/windows_task.rb +2 -2
  26. data/lib/chef/resource/archive_file.rb +5 -2
  27. data/lib/chef/resource/cron.rb +29 -0
  28. data/lib/chef/resource/cron_d.rb +29 -0
  29. data/lib/chef/resource/openssl_x509_certificate.rb +32 -21
  30. data/lib/chef/resource/sudo.rb +13 -4
  31. data/lib/chef/version.rb +2 -2
  32. data/lib/chef/version_string.rb +3 -126
  33. data/spec/data/cookbooks/apache2/metadata.json +33 -0
  34. data/spec/data/cookbooks/java/metadata.json +33 -0
  35. data/spec/functional/event_loggers/windows_eventlog_spec.rb +5 -5
  36. data/spec/integration/knife/chef_fs_data_store_spec.rb +7 -2
  37. data/spec/integration/knife/cookbook_upload_spec.rb +10 -0
  38. data/spec/integration/knife/deps_spec.rb +11 -0
  39. data/spec/integration/knife/upload_spec.rb +115 -14
  40. data/spec/unit/cookbook/cookbook_version_loader_spec.rb +7 -4
  41. data/spec/unit/knife/cookbook_upload_spec.rb +79 -18
  42. data/spec/unit/mixin/openssl_helper_spec.rb +42 -0
  43. data/spec/unit/provider/cron_spec.rb +127 -0
  44. data/spec/unit/provider/user/aix_spec.rb +2 -2
  45. metadata +8 -6
@@ -109,30 +109,41 @@ class Chef
109
109
  property :ca_key_pass, String,
110
110
  description: "The passphrase for CA private key's passphrase."
111
111
 
112
+ property :renew_before_expiry, Integer,
113
+ description: "The number of days before the expiry. The certificate will be automaticaly renewed when the value is reached.",
114
+ introduced: "15.7"
115
+
112
116
  action :create do
113
117
  description "Generate a certificate"
114
118
 
115
- unless ::File.exist? new_resource.path
116
- converge_by("Create #{@new_resource}") do
117
- file new_resource.path do
118
- action :create_if_missing
119
- owner new_resource.owner unless new_resource.owner.nil?
120
- group new_resource.group unless new_resource.group.nil?
121
- mode new_resource.mode unless new_resource.mode.nil?
122
- sensitive true
123
- content cert.to_pem
124
- end
125
-
126
- if new_resource.csr_file.nil?
127
- file new_resource.key_file do
128
- action :create_if_missing
129
- owner new_resource.owner unless new_resource.owner.nil?
130
- group new_resource.group unless new_resource.group.nil?
131
- mode new_resource.mode unless new_resource.mode.nil?
132
- sensitive true
133
- content key.to_pem
134
- end
135
- end
119
+ file new_resource.path do
120
+ action :create_if_missing
121
+ owner new_resource.owner unless new_resource.owner.nil?
122
+ group new_resource.group unless new_resource.group.nil?
123
+ mode new_resource.mode unless new_resource.mode.nil?
124
+ sensitive true
125
+ content cert.to_pem
126
+ end
127
+
128
+ if !new_resource.renew_before_expiry.nil? && cert_need_renewall?(new_resource.path, new_resource.renew_before_expiry)
129
+ file new_resource.path do
130
+ action :create
131
+ owner new_resource.owner unless new_resource.owner.nil?
132
+ group new_resource.group unless new_resource.group.nil?
133
+ mode new_resource.mode unless new_resource.mode.nil?
134
+ sensitive true
135
+ content cert.to_pem
136
+ end
137
+ end
138
+
139
+ if new_resource.csr_file.nil?
140
+ file new_resource.key_file do
141
+ action :create_if_missing
142
+ owner new_resource.owner unless new_resource.owner.nil?
143
+ group new_resource.group unless new_resource.group.nil?
144
+ mode new_resource.mode unless new_resource.mode.nil?
145
+ sensitive true
146
+ content key.to_pem
136
147
  end
137
148
  end
138
149
  end
@@ -158,19 +158,20 @@ class Chef
158
158
  declare_resource(:directory, target) unless ::File.exist?(target)
159
159
 
160
160
  Chef::Log.warn("#{new_resource.filename} will be rendered, but will not take effect because the #{new_resource.config_prefix}/sudoers config lacks the includedir directive that loads configs from #{new_resource.config_prefix}/sudoers.d/!") if ::File.readlines("#{new_resource.config_prefix}/sudoers").grep(/includedir/).empty?
161
+ file_path = "#{target}#{new_resource.filename}"
161
162
 
162
163
  if new_resource.template
163
164
  logger.trace("Template property provided, all other properties ignored.")
164
165
 
165
- declare_resource(:template, "#{target}#{new_resource.filename}") do
166
+ declare_resource(:template, file_path) do
166
167
  source new_resource.template
167
168
  mode "0440"
168
169
  variables new_resource.variables
169
- verify "cat #{new_resource.config_prefix}/sudoers %{path} | #{new_resource.visudo_binary} -cf -" if visudo_present?
170
+ verify visudo_content(file_path) if visudo_present?
170
171
  action :create
171
172
  end
172
173
  else
173
- declare_resource(:template, "#{target}#{new_resource.filename}") do
174
+ declare_resource(:template, file_path) do
174
175
  source ::File.expand_path("../support/sudoer.erb", __FILE__)
175
176
  local true
176
177
  mode "0440"
@@ -185,7 +186,7 @@ class Chef
185
186
  setenv: new_resource.setenv,
186
187
  env_keep_add: new_resource.env_keep_add,
187
188
  env_keep_subtract: new_resource.env_keep_subtract
188
- verify "cat #{new_resource.config_prefix}/sudoers %{path} | #{new_resource.visudo_binary} -cf -" if visudo_present?
189
+ verify visudo_content(file_path) if visudo_present?
189
190
  action :create
190
191
  end
191
192
  end
@@ -225,6 +226,14 @@ class Chef
225
226
 
226
227
  Chef::Log.warn("The visudo binary cannot be found at '#{new_resource.visudo_binary}'. Skipping sudoer file validation. If visudo is on this system you can specify the path using the 'visudo_binary' property.")
227
228
  end
229
+
230
+ def visudo_content(path)
231
+ if ::File.exists?(path)
232
+ "cat #{new_resource.config_prefix}/sudoers | #{new_resource.visudo_binary} -cf - && #{new_resource.visudo_binary} -cf %{path}"
233
+ else
234
+ "cat #{new_resource.config_prefix}/sudoers %{path} | #{new_resource.visudo_binary} -cf -"
235
+ end
236
+ end
228
237
  end
229
238
  end
230
239
  end
@@ -1,4 +1,4 @@
1
- # Copyright:: Copyright 2010-2018, Chef Software, Inc.
1
+ # Copyright:: Copyright 2010-2020, Chef Software Inc.
2
2
  # License:: Apache License, Version 2.0
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +23,7 @@ require_relative "version_string"
23
23
 
24
24
  class Chef
25
25
  CHEF_ROOT = File.expand_path("../..", __FILE__)
26
- VERSION = Chef::VersionString.new("15.6.10")
26
+ VERSION = Chef::VersionString.new("15.7.30")
27
27
  end
28
28
 
29
29
  #
@@ -13,131 +13,8 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- class Chef
17
- # String-like object for version strings.
18
- #
19
- # @since 13.2
20
- # @api internal
21
- class VersionString < String
22
- # Parsed version object for the string.
23
- # @return [Gem::Version]
24
- attr_reader :parsed_version
25
-
26
- # Create a new VersionString from an input String.
27
- #
28
- # @param val [String] Version string to parse.
29
- def initialize(val)
30
- super
31
- @parsed_version = ::Gem::Version.create(self)
32
- end
33
-
34
- # @!group Compat wrappers for String
35
-
36
- # Compat wrapper for + to behave like a normal String.
37
- #
38
- # @param other [String]
39
- # @return [String]
40
- def +(other)
41
- to_s + other
42
- end
43
-
44
- # Compat wrapper for * to behave like a normal String.
45
- #
46
- # @param other [Integer]
47
- # @return [String]
48
- def *(other)
49
- to_s * other
50
- end
51
-
52
- # @!group Comparison operators
53
-
54
- # Compare a VersionString to an object. If compared to another VersionString
55
- # then sort like `Gem::Version`, otherwise try to treat the other object as
56
- # a version but fall back to normal string comparison.
57
- #
58
- # @param other [Object]
59
- # @return [Integer]
60
- def <=>(other)
61
- other_ver = case other
62
- when VersionString
63
- other.parsed_version
64
- else
65
- begin
66
- Gem::Version.create(other.to_s)
67
- rescue ArgumentError
68
- # Comparing to a string that isn't a version.
69
- return super
70
- end
71
- end
72
- parsed_version <=> other_ver
73
- end
74
-
75
- # Compat wrapper for == based on <=>.
76
- #
77
- # @param other [Object]
78
- # @return [Boolean]
79
- def ==(other)
80
- (self <=> other) == 0
81
- end
16
+ require "chef-utils/version_string"
82
17
 
83
- # Compat wrapper for != based on <=>.
84
- #
85
- # @param other [Object]
86
- # @return [Boolean]
87
- def !=(other)
88
- (self <=> other) != 0
89
- end
90
-
91
- # Compat wrapper for < based on <=>.
92
- #
93
- # @param other [Object]
94
- # @return [Boolean]
95
- def <(other)
96
- (self <=> other) < 0
97
- end
98
-
99
- # Compat wrapper for <= based on <=>.
100
- #
101
- # @param other [Object]
102
- # @return [Boolean]
103
- def <=(other)
104
- (self <=> other) < 1
105
- end
106
-
107
- # Compat wrapper for > based on <=>.
108
- #
109
- # @param other [Object]
110
- # @return [Boolean]
111
- def >(other)
112
- (self <=> other) > 0
113
- end
114
-
115
- # Compat wrapper for >= based on <=>.
116
- #
117
- # @param other [Object]
118
- # @return [Boolean]
119
- def >=(other)
120
- (self <=> other) > -1
121
- end
122
-
123
- # @!group Matching operators
124
-
125
- # Matching operator to support checking against a requirement string.
126
- #
127
- # @param other [Regexp, String]
128
- # @return [Boolean]
129
- # @example Match against a Regexp
130
- # Chef::VersionString.new('1.0.0') =~ /^1/
131
- # @example Match against a requirement
132
- # Chef::VersionString.new('1.0.0') =~ '~> 1.0'
133
- def =~(other)
134
- case other
135
- when Regexp
136
- super
137
- else
138
- Gem::Requirement.create(other) =~ parsed_version
139
- end
140
- end
141
-
142
- end
18
+ class Chef
19
+ VersionString = ChefUtils::VersionString
143
20
  end
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "apache2",
3
+ "description": "",
4
+ "long_description": "",
5
+ "maintainer": "",
6
+ "maintainer_email": "",
7
+ "license": "All rights reserved",
8
+ "platforms": {
9
+
10
+ },
11
+ "dependencies": {
12
+
13
+ },
14
+ "providing": {
15
+
16
+ },
17
+ "recipes": {
18
+
19
+ },
20
+ "version": "0.0.1",
21
+ "source_url": "",
22
+ "issues_url": "",
23
+ "privacy": false,
24
+ "chef_versions": [
25
+
26
+ ],
27
+ "ohai_versions": [
28
+
29
+ ],
30
+ "gems": [
31
+
32
+ ]
33
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "java",
3
+ "description": "",
4
+ "long_description": "",
5
+ "maintainer": "",
6
+ "maintainer_email": "",
7
+ "license": "All rights reserved",
8
+ "platforms": {
9
+
10
+ },
11
+ "dependencies": {
12
+
13
+ },
14
+ "providing": {
15
+
16
+ },
17
+ "recipes": {
18
+
19
+ },
20
+ "version": "0.0.1",
21
+ "source_url": "",
22
+ "issues_url": "",
23
+ "privacy": false,
24
+ "chef_versions": [
25
+
26
+ ],
27
+ "ohai_versions": [
28
+
29
+ ],
30
+ "gems": [
31
+
32
+ ]
33
+ }
@@ -49,7 +49,7 @@ describe Chef::EventLoggers::WindowsEventLogger, :windows_only do
49
49
  logger.run_start(version, run_status)
50
50
 
51
51
  expect(event_log.read(flags, offset).any? do |e|
52
- e.source == Chef::Dist::PRODUCT && e.event_id == 10000 &&
52
+ e.source == Chef::Dist::SHORT && e.event_id == 10000 &&
53
53
  e.string_inserts[0].include?(version)
54
54
  end ).to be_truthy
55
55
  end
@@ -58,7 +58,7 @@ describe Chef::EventLoggers::WindowsEventLogger, :windows_only do
58
58
  logger.run_started(run_status)
59
59
 
60
60
  expect(event_log.read(flags, offset).any? do |e|
61
- e.source == Chef::Dist::PRODUCT && e.event_id == 10001 &&
61
+ e.source == Chef::Dist::SHORT && e.event_id == 10001 &&
62
62
  e.string_inserts[0].include?(run_id)
63
63
  end ).to be_truthy
64
64
  end
@@ -68,7 +68,7 @@ describe Chef::EventLoggers::WindowsEventLogger, :windows_only do
68
68
  logger.run_completed(node)
69
69
 
70
70
  expect(event_log.read(flags, offset).any? do |e|
71
- e.source == Chef::Dist::PRODUCT && e.event_id == 10002 &&
71
+ e.source == Chef::Dist::SHORT && e.event_id == 10002 &&
72
72
  e.string_inserts[0].include?(run_id) &&
73
73
  e.string_inserts[1].include?(elapsed_time.to_s)
74
74
  end).to be_truthy
@@ -79,7 +79,7 @@ describe Chef::EventLoggers::WindowsEventLogger, :windows_only do
79
79
  logger.run_failed(mock_exception)
80
80
 
81
81
  expect(event_log.read(flags, offset).any? do |e|
82
- e.source == Chef::Dist::PRODUCT && e.event_id == 10003 &&
82
+ e.source == Chef::Dist::SHORT && e.event_id == 10003 &&
83
83
  e.string_inserts[0].include?(run_id) &&
84
84
  e.string_inserts[1].include?(elapsed_time.to_s) &&
85
85
  e.string_inserts[2].include?(mock_exception.class.name) &&
@@ -93,7 +93,7 @@ describe Chef::EventLoggers::WindowsEventLogger, :windows_only do
93
93
  logger.run_failed(mock_exception)
94
94
 
95
95
  expect(event_log.read(flags, offset).any? do |e|
96
- e.source == Chef::Dist::PRODUCT && e.event_id == 10003 &&
96
+ e.source == Chef::Dist::SHORT && e.event_id == 10003 &&
97
97
  e.string_inserts[0].include?("UNKNOWN") &&
98
98
  e.string_inserts[1].include?("UNKNOWN") &&
99
99
  e.string_inserts[2].include?(mock_exception.class.name) &&
@@ -54,6 +54,7 @@ describe "ChefFSDataStore tests", :workstation do
54
54
 
55
55
  context "GET /TYPE" do
56
56
  it "knife list -z -R returns everything" do
57
+ expect(Chef::Log).to receive(:warn).with(/load method is deprecated. Use load! instead/).twice
57
58
  knife("list -z -Rfp /").should_succeed <<~EOM
58
59
  /acls/
59
60
  /acls/clients/
@@ -118,6 +119,7 @@ describe "ChefFSDataStore tests", :workstation do
118
119
  end
119
120
 
120
121
  it "knife delete -z -r /cookbooks/x works" do
122
+ expect(Chef::Log).to receive(:warn).with(/load method is deprecated. Use load! instead/).at_least(3).times
121
123
  knife("delete -z -r /cookbooks/x").should_succeed "Deleted /cookbooks/x\n"
122
124
  knife("list -z -Rfp /cookbooks").should_succeed ""
123
125
  end
@@ -155,6 +157,7 @@ describe "ChefFSDataStore tests", :workstation do
155
157
  end
156
158
 
157
159
  it "knife show -z /cookbooks/x/metadata.rb works" do
160
+ expect(Chef::Log).to receive(:warn).with(/load method is deprecated. Use load! instead/).once
158
161
  knife("show -z /cookbooks/x/metadata.rb").should_succeed "/cookbooks/x/metadata.rb:\n#{cookbook_x_100_metadata_rb}\n"
159
162
  end
160
163
 
@@ -190,11 +193,12 @@ describe "ChefFSDataStore tests", :workstation do
190
193
  end
191
194
 
192
195
  it "knife cookbook upload works" do
196
+ expect(Chef::Log).to receive(:warn).with(/load method is deprecated. Use load! instead/).once
193
197
  knife("cookbook upload -z --cookbook-path #{path_to("cookbooks_to_upload")} x").should_succeed stderr: <<~EOM
194
198
  Uploading x [1.0.0]
195
199
  Uploaded 1 cookbook.
196
200
  EOM
197
- knife("list --local -Rfp /cookbooks").should_succeed "/cookbooks/x/\n/cookbooks/x/metadata.rb\n"
201
+ knife("list --local -Rfp /cookbooks").should_succeed "/cookbooks/x/\n/cookbooks/x/metadata.json\n/cookbooks/x/metadata.rb\n"
198
202
  end
199
203
 
200
204
  it "knife raw -z -i empty.json -m PUT /data/x/y" do
@@ -251,7 +255,7 @@ describe "ChefFSDataStore tests", :workstation do
251
255
  Uploading z [1.0.0]
252
256
  Uploaded 1 cookbook.
253
257
  EOM
254
- knife("list --local -Rfp /cookbooks").should_succeed "/cookbooks/z/\n/cookbooks/z/metadata.rb\n"
258
+ knife("list --local -Rfp /cookbooks").should_succeed "/cookbooks/z/\n/cookbooks/z/metadata.json\n/cookbooks/z/metadata.rb\n"
255
259
  end
256
260
 
257
261
  it "knife raw -z -i empty.json -m POST /data" do
@@ -442,6 +446,7 @@ describe "ChefFSDataStore tests", :workstation do
442
446
 
443
447
  context "GET /TYPE" do
444
448
  it "knife list -z -R returns everything" do
449
+ expect(Chef::Log).to receive(:warn).with(/load method is deprecated. Use load! instead/).once
445
450
  knife("list -z -Rfp /").should_succeed <<~EOM
446
451
  /clients/
447
452
  /clients/x.json
@@ -86,5 +86,15 @@ describe "knife cookbook upload", :workstation do
86
86
  EOM
87
87
  end
88
88
  end
89
+
90
+ when_the_repository "has cookbook metadata without name attribute in metadata file" do
91
+ before do
92
+ file "cookbooks/x/metadata.rb", cb_metadata(nil, "1.0.0")
93
+ end
94
+
95
+ it "knife cookbook upload x " do
96
+ expect { knife("cookbook upload x -o #{cb_dir}") }.to raise_error(Chef::Exceptions::MetadataNotValid)
97
+ end
98
+ end
89
99
  end
90
100
  end
@@ -41,6 +41,7 @@ describe "knife deps", :workstation do
41
41
  file "cookbooks/soup/recipes/chicken.rb", ""
42
42
  end
43
43
  it "knife deps reports all dependencies" do
44
+ expect(Chef::Log).to receive(:warn).with(/load method is deprecated. Use load! instead/).twice
44
45
  knife("deps /roles/starring.json").should_succeed <<~EOM
45
46
  /roles/minor.json
46
47
  /cookbooks/quiche
@@ -60,6 +61,7 @@ describe "knife deps", :workstation do
60
61
  file "cookbooks/soup/recipes/chicken.rb", ""
61
62
  end
62
63
  it "knife deps reports all dependencies" do
64
+ expect(Chef::Log).to receive(:warn).with(/load method is deprecated. Use load! instead/).twice
63
65
  knife("deps /roles/starring.json").should_succeed <<~EOM
64
66
  /roles/minor.json
65
67
  /cookbooks/quiche
@@ -94,6 +96,7 @@ describe "knife deps", :workstation do
94
96
  file "nodes/mort.json", { "run_list" => %w{role[minor] recipe[quiche] recipe[soup::chicken]} }
95
97
  end
96
98
  it "knife deps reports just the node" do
99
+ expect(Chef::Log).to receive(:warn).with(/load method is deprecated. Use load! instead/).twice
97
100
  knife("deps /nodes/mort.json").should_succeed <<~EOM
98
101
  /roles/minor.json
99
102
  /cookbooks/quiche
@@ -108,6 +111,7 @@ describe "knife deps", :workstation do
108
111
  file "cookbooks/quiche/recipes/default.rb", ""
109
112
  end
110
113
  it "knife deps reports just the cookbook" do
114
+ expect(Chef::Log).to receive(:warn).with(/load method is deprecated. Use load! instead/).once
111
115
  knife("deps /cookbooks/quiche").should_succeed "/cookbooks/quiche\n"
112
116
  end
113
117
  end
@@ -119,6 +123,7 @@ depends "kettle"'
119
123
  file "cookbooks/quiche/recipes/default.rb", ""
120
124
  end
121
125
  it "knife deps reports just the cookbook" do
126
+ expect(Chef::Log).to receive(:warn).with(/load method is deprecated. Use load! instead/).twice
122
127
  knife("deps /cookbooks/quiche").should_succeed "/cookbooks/kettle\n/cookbooks/quiche\n"
123
128
  end
124
129
  end
@@ -148,6 +153,7 @@ depends "kettle"'
148
153
  end
149
154
 
150
155
  it "knife deps reports all dependencies" do
156
+ expect(Chef::Log).to receive(:warn).with(/load method is deprecated. Use load! instead/).twice
151
157
  knife("deps /nodes/mort.json").should_succeed <<~EOM
152
158
  /environments/desert.json
153
159
  /roles/minor.json
@@ -158,6 +164,7 @@ depends "kettle"'
158
164
  EOM
159
165
  end
160
166
  it "knife deps * reports all dependencies of all things" do
167
+ expect(Chef::Log).to receive(:warn).with(/load method is deprecated. Use load! instead/).twice
161
168
  knife("deps /nodes/*").should_succeed <<~EOM
162
169
  /roles/minor.json
163
170
  /nodes/bart.json
@@ -169,6 +176,7 @@ depends "kettle"'
169
176
  EOM
170
177
  end
171
178
  it "knife deps a b reports all dependencies of a and b" do
179
+ expect(Chef::Log).to receive(:warn).with(/load method is deprecated. Use load! instead/).twice
172
180
  knife("deps /nodes/bart.json /nodes/mort.json").should_succeed <<~EOM
173
181
  /roles/minor.json
174
182
  /nodes/bart.json
@@ -180,6 +188,7 @@ depends "kettle"'
180
188
  EOM
181
189
  end
182
190
  it "knife deps --tree /* shows dependencies in a tree" do
191
+ expect(Chef::Log).to receive(:warn).with(/load method is deprecated. Use load! instead/).twice
183
192
  knife("deps --tree /nodes/*").should_succeed <<~EOM
184
193
  /nodes/bart.json
185
194
  /roles/minor.json
@@ -214,11 +223,13 @@ depends "foo"'
214
223
  end
215
224
 
216
225
  it "knife deps prints each once" do
226
+ expect(Chef::Log).to receive(:warn).with(/load method is deprecated. Use load! instead/).at_least(3).times
217
227
  knife("deps /cookbooks/foo").should_succeed(
218
228
  stdout: "/cookbooks/baz\n/cookbooks/bar\n/cookbooks/foo\n"
219
229
  )
220
230
  end
221
231
  it "knife deps --tree prints each once" do
232
+ expect(Chef::Log).to receive(:warn).with(/load method is deprecated. Use load! instead/).at_least(3).times
222
233
  knife("deps --tree /cookbooks/foo").should_succeed(
223
234
  stdout: "/cookbooks/foo\n /cookbooks/bar\n /cookbooks/baz\n /cookbooks/foo\n"
224
235
  )