chef-config 12.8.1 → 12.9.38

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,75 +1,75 @@
1
- require "chef-config/windows"
2
-
3
- # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
4
- RSpec.configure do |config|
5
- # rspec-expectations config goes here. You can use an alternate
6
- # assertion/expectation library such as wrong or the stdlib/minitest
7
- # assertions if you prefer.
8
- config.expect_with :rspec do |expectations|
9
- # This option will default to `true` in RSpec 4. It makes the `description`
10
- # and `failure_message` of custom matchers include text for helper methods
11
- # defined using `chain`, e.g.:
12
- # be_bigger_than(2).and_smaller_than(4).description
13
- # # => "be bigger than 2 and smaller than 4"
14
- # ...rather than:
15
- # # => "be bigger than 2"
16
- expectations.include_chain_clauses_in_custom_matcher_descriptions = true
17
- end
18
-
19
- # rspec-mocks config goes here. You can use an alternate test double
20
- # library (such as bogus or mocha) by changing the `mock_with` option here.
21
- config.mock_with :rspec do |mocks|
22
- # Prevents you from mocking or stubbing a method that does not exist on
23
- # a real object. This is generally recommended, and will default to
24
- # `true` in RSpec 4.
25
- mocks.verify_partial_doubles = true
26
- end
27
-
28
- # These two settings work together to allow you to limit a spec run
29
- # to individual examples or groups you care about by tagging them with
30
- # `:focus` metadata. When nothing is tagged with `:focus`, all examples
31
- # get run.
32
- config.filter_run :focus
33
- config.run_all_when_everything_filtered = true
34
-
35
- config.filter_run_excluding :windows_only => true unless ChefConfig.windows?
36
- config.filter_run_excluding :unix_only => true if ChefConfig.windows?
37
-
38
- # Limits the available syntax to the non-monkey patched syntax that is
39
- # recommended. For more details, see:
40
- # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
41
- # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
42
- # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
43
- config.disable_monkey_patching!
44
-
45
- # This setting enables warnings. It's recommended, but in some cases may
46
- # be too noisy due to issues in dependencies.
47
- config.warnings = true
48
-
49
- # Many RSpec users commonly either run the entire suite or an individual
50
- # file, and it's useful to allow more verbose output when running an
51
- # individual spec file.
52
- if config.files_to_run.one?
53
- # Use the documentation formatter for detailed output,
54
- # unless a formatter has already been configured
55
- # (e.g. via a command-line flag).
56
- config.default_formatter = "doc"
57
- end
58
-
59
- # Print the 10 slowest examples and example groups at the
60
- # end of the spec run, to help surface which specs are running
61
- # particularly slow.
62
- # config.profile_examples = 10
63
-
64
- # Run specs in random order to surface order dependencies. If you find an
65
- # order dependency and want to debug it, you can fix the order by providing
66
- # the seed, which is printed after each run.
67
- # --seed 1234
68
- config.order = :random
69
-
70
- # Seed global randomization in this process using the `--seed` CLI option.
71
- # Setting this allows you to use `--seed` to deterministically reproduce
72
- # test failures related to randomization by passing the same `--seed` value
73
- # as the one that triggered the failure.
74
- Kernel.srand config.seed
75
- end
1
+ require "chef-config/windows"
2
+
3
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
4
+ RSpec.configure do |config|
5
+ # rspec-expectations config goes here. You can use an alternate
6
+ # assertion/expectation library such as wrong or the stdlib/minitest
7
+ # assertions if you prefer.
8
+ config.expect_with :rspec do |expectations|
9
+ # This option will default to `true` in RSpec 4. It makes the `description`
10
+ # and `failure_message` of custom matchers include text for helper methods
11
+ # defined using `chain`, e.g.:
12
+ # be_bigger_than(2).and_smaller_than(4).description
13
+ # # => "be bigger than 2 and smaller than 4"
14
+ # ...rather than:
15
+ # # => "be bigger than 2"
16
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
17
+ end
18
+
19
+ # rspec-mocks config goes here. You can use an alternate test double
20
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
21
+ config.mock_with :rspec do |mocks|
22
+ # Prevents you from mocking or stubbing a method that does not exist on
23
+ # a real object. This is generally recommended, and will default to
24
+ # `true` in RSpec 4.
25
+ mocks.verify_partial_doubles = true
26
+ end
27
+
28
+ # These two settings work together to allow you to limit a spec run
29
+ # to individual examples or groups you care about by tagging them with
30
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
31
+ # get run.
32
+ config.filter_run :focus
33
+ config.run_all_when_everything_filtered = true
34
+
35
+ config.filter_run_excluding :windows_only => true unless ChefConfig.windows?
36
+ config.filter_run_excluding :unix_only => true if ChefConfig.windows?
37
+
38
+ # Limits the available syntax to the non-monkey patched syntax that is
39
+ # recommended. For more details, see:
40
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
41
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
42
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
43
+ config.disable_monkey_patching!
44
+
45
+ # This setting enables warnings. It's recommended, but in some cases may
46
+ # be too noisy due to issues in dependencies.
47
+ config.warnings = true
48
+
49
+ # Many RSpec users commonly either run the entire suite or an individual
50
+ # file, and it's useful to allow more verbose output when running an
51
+ # individual spec file.
52
+ if config.files_to_run.one?
53
+ # Use the documentation formatter for detailed output,
54
+ # unless a formatter has already been configured
55
+ # (e.g. via a command-line flag).
56
+ config.default_formatter = "doc"
57
+ end
58
+
59
+ # Print the 10 slowest examples and example groups at the
60
+ # end of the spec run, to help surface which specs are running
61
+ # particularly slow.
62
+ # config.profile_examples = 10
63
+
64
+ # Run specs in random order to surface order dependencies. If you find an
65
+ # order dependency and want to debug it, you can fix the order by providing
66
+ # the seed, which is printed after each run.
67
+ # --seed 1234
68
+ config.order = :random
69
+
70
+ # Seed global randomization in this process using the `--seed` CLI option.
71
+ # Setting this allows you to use `--seed` to deterministically reproduce
72
+ # test failures related to randomization by passing the same `--seed` value
73
+ # as the one that triggered the failure.
74
+ Kernel.srand config.seed
75
+ end
@@ -1,843 +1,995 @@
1
- #
2
- # Author:: Adam Jacob (<adam@chef.io>)
3
- # Author:: Kyle Goodwin (<kgoodwin@primerevenue.com>)
4
- # Copyright:: Copyright 2008-2016, Chef Software Inc.
5
- # License:: Apache License, Version 2.0
6
- #
7
- # Licensed under the Apache License, Version 2.0 (the "License");
8
- # you may not use this file except in compliance with the License.
9
- # You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing, software
14
- # distributed under the License is distributed on an "AS IS" BASIS,
15
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- # See the License for the specific language governing permissions and
17
- # limitations under the License.
18
- #
19
-
20
- require "spec_helper"
21
- require "chef-config/config"
22
-
23
- RSpec.describe ChefConfig::Config do
24
- before(:each) do
25
- ChefConfig::Config.reset
26
-
27
- # By default, treat deprecation warnings as errors in tests.
28
- ChefConfig::Config.treat_deprecation_warnings_as_errors(true)
29
-
30
- # Set environment variable so the setting persists in child processes
31
- ENV["CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS"] = "1"
32
- end
33
-
34
- describe "config attribute writer: chef_server_url" do
35
- before do
36
- ChefConfig::Config.chef_server_url = "https://junglist.gen.nz"
37
- end
38
-
39
- it "sets the server url" do
40
- expect(ChefConfig::Config.chef_server_url).to eq("https://junglist.gen.nz")
41
- end
42
-
43
- context "when the url has a leading space" do
44
- before do
45
- ChefConfig::Config.chef_server_url = " https://junglist.gen.nz"
46
- end
47
-
48
- it "strips the space from the url when setting" do
49
- expect(ChefConfig::Config.chef_server_url).to eq("https://junglist.gen.nz")
50
- end
51
-
52
- end
53
-
54
- context "when the url is a frozen string" do
55
- before do
56
- ChefConfig::Config.chef_server_url = " https://junglist.gen.nz".freeze
57
- end
58
-
59
- it "strips the space from the url when setting without raising an error" do
60
- expect(ChefConfig::Config.chef_server_url).to eq("https://junglist.gen.nz")
61
- end
62
- end
63
-
64
- context "when the url is invalid" do
65
- it "raises an exception" do
66
- expect { ChefConfig::Config.chef_server_url = "127.0.0.1" }.to raise_error(ChefConfig::ConfigurationError)
67
- end
68
- end
69
- end
70
-
71
- describe "when configuring formatters" do
72
- # if TTY and not(force-logger)
73
- # formatter = configured formatter or default formatter
74
- # formatter goes to STDOUT/ERR
75
- # if log file is writeable
76
- # log level is configured level or info
77
- # log location is file
78
- # else
79
- # log level is warn
80
- # log location is STDERR
81
- # end
82
- # elsif not(TTY) and force formatter
83
- # formatter = configured formatter or default formatter
84
- # if log_location specified
85
- # formatter goes to log_location
86
- # else
87
- # formatter goes to STDOUT/ERR
88
- # end
89
- # else
90
- # formatter = "null"
91
- # log_location = configured-value or defualt
92
- # log_level = info or defualt
93
- # end
94
- #
95
- it "has an empty list of formatters by default" do
96
- expect(ChefConfig::Config.formatters).to eq([])
97
- end
98
-
99
- it "configures a formatter with a short name" do
100
- ChefConfig::Config.add_formatter(:doc)
101
- expect(ChefConfig::Config.formatters).to eq([[:doc, nil]])
102
- end
103
-
104
- it "configures a formatter with a file output" do
105
- ChefConfig::Config.add_formatter(:doc, "/var/log/formatter.log")
106
- expect(ChefConfig::Config.formatters).to eq([[:doc, "/var/log/formatter.log"]])
107
- end
108
-
109
- end
110
-
111
- [ false, true ].each do |is_windows|
112
-
113
- context "On #{is_windows ? 'Windows' : 'Unix'}" do
114
- def to_platform(*args)
115
- ChefConfig::Config.platform_specific_path(*args)
116
- end
117
-
118
- before :each do
119
- allow(ChefConfig).to receive(:windows?).and_return(is_windows)
120
- end
121
-
122
- describe "class method: platform_specific_path" do
123
- if is_windows
124
- it "should return a windows path on windows systems" do
125
- path = "/etc/chef/cookbooks"
126
- allow(ChefConfig::Config).to receive(:env).and_return({ "SYSTEMDRIVE" => "C:" })
127
- # match on a regex that looks for the base path with an optional
128
- # system drive at the beginning (c:)
129
- # system drive is not hardcoded b/c it can change and b/c it is not present on linux systems
130
- expect(ChefConfig::Config.platform_specific_path(path)).to eq("C:\\chef\\cookbooks")
131
- end
132
- else
133
- it "should return given path on non-windows systems" do
134
- path = "/etc/chef/cookbooks"
135
- expect(ChefConfig::Config.platform_specific_path(path)).to eq("/etc/chef/cookbooks")
136
- end
137
- end
138
- end
139
-
140
- describe "default values" do
141
- let :primary_cache_path do
142
- if is_windows
143
- "#{ChefConfig::Config.env['SYSTEMDRIVE']}\\chef"
144
- else
145
- "/var/chef"
146
- end
147
- end
148
-
149
- let :secondary_cache_path do
150
- if is_windows
151
- "#{ChefConfig::Config[:user_home]}\\.chef"
152
- else
153
- "#{ChefConfig::Config[:user_home]}/.chef"
154
- end
155
- end
156
-
157
- before do
158
- if is_windows
159
- allow(ChefConfig::Config).to receive(:env).and_return({ "SYSTEMDRIVE" => "C:" })
160
- ChefConfig::Config[:user_home] = 'C:\Users\charlie'
161
- else
162
- ChefConfig::Config[:user_home] = "/Users/charlie"
163
- end
164
-
165
- allow(ChefConfig::Config).to receive(:path_accessible?).and_return(false)
166
- end
167
-
168
- describe "ChefConfig::Config[:chef_server_root]" do
169
- context "when chef_server_url isn't set manually" do
170
- it "returns the default of 'https://localhost:443'" do
171
- expect(ChefConfig::Config[:chef_server_root]).to eq("https://localhost:443")
172
- end
173
- end
174
-
175
- context "when chef_server_url matches '../organizations/*' without a trailing slash" do
176
- before do
177
- ChefConfig::Config[:chef_server_url] = "https://example.com/organizations/myorg"
178
- end
179
- it "returns the full URL without /organizations/*" do
180
- expect(ChefConfig::Config[:chef_server_root]).to eq("https://example.com")
181
- end
182
- end
183
-
184
- context "when chef_server_url matches '../organizations/*' with a trailing slash" do
185
- before do
186
- ChefConfig::Config[:chef_server_url] = "https://example.com/organizations/myorg/"
187
- end
188
- it "returns the full URL without /organizations/*" do
189
- expect(ChefConfig::Config[:chef_server_root]).to eq("https://example.com")
190
- end
191
- end
192
-
193
- context "when chef_server_url matches '..organizations..' but not '../organizations/*'" do
194
- before do
195
- ChefConfig::Config[:chef_server_url] = "https://organizations.com/organizations"
196
- end
197
- it "returns the full URL without any modifications" do
198
- expect(ChefConfig::Config[:chef_server_root]).to eq(ChefConfig::Config[:chef_server_url])
199
- end
200
- end
201
-
202
- context "when chef_server_url is a standard URL without the string organization(s)" do
203
- before do
204
- ChefConfig::Config[:chef_server_url] = "https://example.com/some_other_string"
205
- end
206
- it "returns the full URL without any modifications" do
207
- expect(ChefConfig::Config[:chef_server_root]).to eq(ChefConfig::Config[:chef_server_url])
208
- end
209
- end
210
- end
211
-
212
- describe "ChefConfig::Config[:cache_path]" do
213
- context "when /var/chef exists and is accessible" do
214
- it "defaults to /var/chef" do
215
- allow(ChefConfig::Config).to receive(:path_accessible?).with(to_platform("/var/chef")).and_return(true)
216
- expect(ChefConfig::Config[:cache_path]).to eq(primary_cache_path)
217
- end
218
- end
219
-
220
- context "when /var/chef does not exist and /var is accessible" do
221
- it "defaults to /var/chef" do
222
- allow(File).to receive(:exists?).with(to_platform("/var/chef")).and_return(false)
223
- allow(ChefConfig::Config).to receive(:path_accessible?).with(to_platform("/var")).and_return(true)
224
- expect(ChefConfig::Config[:cache_path]).to eq(primary_cache_path)
225
- end
226
- end
227
-
228
- context "when /var/chef does not exist and /var is not accessible" do
229
- it "defaults to $HOME/.chef" do
230
- allow(File).to receive(:exists?).with(to_platform("/var/chef")).and_return(false)
231
- allow(ChefConfig::Config).to receive(:path_accessible?).with(to_platform("/var")).and_return(false)
232
- expect(ChefConfig::Config[:cache_path]).to eq(secondary_cache_path)
233
- end
234
- end
235
-
236
- context "when /var/chef exists and is not accessible" do
237
- it "defaults to $HOME/.chef" do
238
- allow(File).to receive(:exists?).with(to_platform("/var/chef")).and_return(true)
239
- allow(File).to receive(:readable?).with(to_platform("/var/chef")).and_return(true)
240
- allow(File).to receive(:writable?).with(to_platform("/var/chef")).and_return(false)
241
-
242
- expect(ChefConfig::Config[:cache_path]).to eq(secondary_cache_path)
243
- end
244
- end
245
-
246
- context "when chef is running in local mode" do
247
- before do
248
- ChefConfig::Config.local_mode = true
249
- end
250
-
251
- context "and config_dir is /a/b/c" do
252
- before do
253
- ChefConfig::Config.config_dir to_platform("/a/b/c")
254
- end
255
-
256
- it "cache_path is /a/b/c/local-mode-cache" do
257
- expect(ChefConfig::Config.cache_path).to eq(to_platform("/a/b/c/local-mode-cache"))
258
- end
259
- end
260
-
261
- context "and config_dir is /a/b/c/" do
262
- before do
263
- ChefConfig::Config.config_dir to_platform("/a/b/c/")
264
- end
265
-
266
- it "cache_path is /a/b/c/local-mode-cache" do
267
- expect(ChefConfig::Config.cache_path).to eq(to_platform("/a/b/c/local-mode-cache"))
268
- end
269
- end
270
- end
271
- end
272
-
273
- it "ChefConfig::Config[:stream_execute_output] defaults to false" do
274
- expect(ChefConfig::Config[:stream_execute_output]).to eq(false)
275
- end
276
-
277
- it "ChefConfig::Config[:file_backup_path] defaults to /var/chef/backup" do
278
- allow(ChefConfig::Config).to receive(:cache_path).and_return(primary_cache_path)
279
- backup_path = is_windows ? "#{primary_cache_path}\\backup" : "#{primary_cache_path}/backup"
280
- expect(ChefConfig::Config[:file_backup_path]).to eq(backup_path)
281
- end
282
-
283
- it "ChefConfig::Config[:ssl_verify_mode] defaults to :verify_peer" do
284
- expect(ChefConfig::Config[:ssl_verify_mode]).to eq(:verify_peer)
285
- end
286
-
287
- it "ChefConfig::Config[:ssl_ca_path] defaults to nil" do
288
- expect(ChefConfig::Config[:ssl_ca_path]).to be_nil
289
- end
290
-
291
- describe "ChefConfig::Config[:repo_mode]" do
292
-
293
- context "when local mode is enabled" do
294
-
295
- before { ChefConfig::Config[:local_mode] = true }
296
-
297
- it "defaults to 'hosted_everything'" do
298
- expect(ChefConfig::Config[:repo_mode]).to eq("hosted_everything")
299
- end
300
-
301
- context "and osc_compat is enabled" do
302
-
303
- before { ChefConfig::Config.chef_zero.osc_compat = true }
304
-
305
- it "defaults to 'everything'" do
306
- expect(ChefConfig::Config[:repo_mode]).to eq("everything")
307
- end
308
- end
309
- end
310
-
311
- context "when local mode is not enabled" do
312
-
313
- context "and the chef_server_url is multi-tenant" do
314
-
315
- before { ChefConfig::Config[:chef_server_url] = "https://chef.example/organizations/example" }
316
-
317
- it "defaults to 'hosted_everything'" do
318
- expect(ChefConfig::Config[:repo_mode]).to eq("hosted_everything")
319
- end
320
-
321
- end
322
-
323
- context "and the chef_server_url is not multi-tenant" do
324
-
325
- before { ChefConfig::Config[:chef_server_url] = "https://chef.example/" }
326
-
327
- it "defaults to 'everything'" do
328
- expect(ChefConfig::Config[:repo_mode]).to eq("everything")
329
- end
330
- end
331
- end
332
- end
333
-
334
- describe "ChefConfig::Config[:chef_repo_path]" do
335
-
336
- context "when cookbook_path is set to a single path" do
337
-
338
- before { ChefConfig::Config[:cookbook_path] = "/home/anne/repo/cookbooks" }
339
-
340
- it "is set to a path one directory up from the cookbook_path" do
341
- expected = File.expand_path("/home/anne/repo")
342
- expect(ChefConfig::Config[:chef_repo_path]).to eq(expected)
343
- end
344
-
345
- end
346
-
347
- context "when cookbook_path is set to multiple paths" do
348
-
349
- before do
350
- ChefConfig::Config[:cookbook_path] = [
351
- "/home/anne/repo/cookbooks",
352
- "/home/anne/other_repo/cookbooks",
353
- ]
354
- end
355
-
356
- it "is set to an Array of paths one directory up from the cookbook_paths" do
357
- expected = [ "/home/anne/repo", "/home/anne/other_repo"].map { |p| File.expand_path(p) }
358
- expect(ChefConfig::Config[:chef_repo_path]).to eq(expected)
359
- end
360
-
361
- end
362
-
363
- context "when cookbook_path is not set but cookbook_artifact_path is set" do
364
-
365
- before do
366
- ChefConfig::Config[:cookbook_path] = nil
367
- ChefConfig::Config[:cookbook_artifact_path] = "/home/roxie/repo/cookbook_artifacts"
368
- end
369
-
370
- it "is set to a path one directory up from the cookbook_artifact_path" do
371
- expected = File.expand_path("/home/roxie/repo")
372
- expect(ChefConfig::Config[:chef_repo_path]).to eq(expected)
373
- end
374
-
375
- end
376
-
377
- context "when cookbook_path is not set" do
378
-
379
- before { ChefConfig::Config[:cookbook_path] = nil }
380
-
381
- it "is set to the cache_path" do
382
- expect(ChefConfig::Config[:chef_repo_path]).to eq(ChefConfig::Config[:cache_path])
383
- end
384
-
385
- end
386
-
387
- end
388
-
389
- # On Windows, we'll detect an omnibus build and set this to the
390
- # cacert.pem included in the package, but it's nil if you're on Windows
391
- # w/o omnibus (e.g., doing development on Windows, custom build, etc.)
392
- if !is_windows
393
- it "ChefConfig::Config[:ssl_ca_file] defaults to nil" do
394
- expect(ChefConfig::Config[:ssl_ca_file]).to be_nil
395
- end
396
- end
397
-
398
- it "ChefConfig::Config[:data_bag_path] defaults to /var/chef/data_bags" do
399
- allow(ChefConfig::Config).to receive(:cache_path).and_return(primary_cache_path)
400
- data_bag_path = is_windows ? "#{primary_cache_path}\\data_bags" : "#{primary_cache_path}/data_bags"
401
- expect(ChefConfig::Config[:data_bag_path]).to eq(data_bag_path)
402
- end
403
-
404
- it "ChefConfig::Config[:environment_path] defaults to /var/chef/environments" do
405
- allow(ChefConfig::Config).to receive(:cache_path).and_return(primary_cache_path)
406
- environment_path = is_windows ? "#{primary_cache_path}\\environments" : "#{primary_cache_path}/environments"
407
- expect(ChefConfig::Config[:environment_path]).to eq(environment_path)
408
- end
409
-
410
- it "ChefConfig::Config[:cookbook_artifact_path] defaults to /var/chef/cookbook_artifacts" do
411
- allow(ChefConfig::Config).to receive(:cache_path).and_return(primary_cache_path)
412
- environment_path = is_windows ? "#{primary_cache_path}\\cookbook_artifacts" : "#{primary_cache_path}/cookbook_artifacts"
413
- expect(ChefConfig::Config[:cookbook_artifact_path]).to eq(environment_path)
414
- end
415
-
416
- describe "setting the config dir" do
417
-
418
- context "when the config file is given with a relative path" do
419
-
420
- before do
421
- ChefConfig::Config.config_file = "client.rb"
422
- end
423
-
424
- it "expands the path when determining config_dir" do
425
- # config_dir goes through PathHelper.canonical_path, which
426
- # downcases on windows because the FS is case insensitive, so we
427
- # have to downcase expected and actual to make the tests work.
428
- expect(ChefConfig::Config.config_dir.downcase).to eq(to_platform(Dir.pwd).downcase)
429
- end
430
-
431
- it "does not set derived paths at FS root" do
432
- ChefConfig::Config.local_mode = true
433
- expect(ChefConfig::Config.cache_path.downcase).to eq(to_platform(File.join(Dir.pwd, "local-mode-cache")).downcase)
434
- end
435
-
436
- end
437
-
438
- context "when the config file is /etc/chef/client.rb" do
439
-
440
- before do
441
- config_location = to_platform("/etc/chef/client.rb").downcase
442
- allow(File).to receive(:absolute_path).with(config_location).and_return(config_location)
443
- ChefConfig::Config.config_file = config_location
444
- end
445
-
446
- it "config_dir is /etc/chef" do
447
- expect(ChefConfig::Config.config_dir).to eq(to_platform("/etc/chef").downcase)
448
- end
449
-
450
- context "and chef is running in local mode" do
451
- before do
452
- ChefConfig::Config.local_mode = true
453
- end
454
-
455
- it "config_dir is /etc/chef" do
456
- expect(ChefConfig::Config.config_dir).to eq(to_platform("/etc/chef").downcase)
457
- end
458
- end
459
-
460
- context "when config_dir is set to /other/config/dir/" do
461
- before do
462
- ChefConfig::Config.config_dir = to_platform("/other/config/dir/")
463
- end
464
-
465
- it "yields the explicit value" do
466
- expect(ChefConfig::Config.config_dir).to eq(to_platform("/other/config/dir/"))
467
- end
468
- end
469
-
470
- end
471
-
472
- context "when the user's home dir is /home/charlie/" do
473
- before do
474
- ChefConfig::Config.user_home = to_platform("/home/charlie")
475
- end
476
-
477
- it "config_dir is /home/charlie/.chef/" do
478
- expect(ChefConfig::Config.config_dir).to eq(ChefConfig::PathHelper.join(to_platform("/home/charlie/.chef"), ""))
479
- end
480
-
481
- context "and chef is running in local mode" do
482
- before do
483
- ChefConfig::Config.local_mode = true
484
- end
485
-
486
- it "config_dir is /home/charlie/.chef/" do
487
- expect(ChefConfig::Config.config_dir).to eq(ChefConfig::PathHelper.join(to_platform("/home/charlie/.chef"), ""))
488
- end
489
- end
490
- end
491
-
492
- end
493
-
494
- if is_windows
495
- describe "finding the windows embedded dir" do
496
- let(:default_config_location) { "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.0/lib/chef/config.rb" }
497
- let(:alternate_install_location) { "c:/my/alternate/install/place/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.0/lib/chef/config.rb" }
498
- let(:non_omnibus_location) { "c:/my/dev/stuff/lib/ruby/gems/1.9.1/gems/chef-11.6.0/lib/chef/config.rb" }
499
-
500
- let(:default_ca_file) { "c:/opscode/chef/embedded/ssl/certs/cacert.pem" }
501
-
502
- it "finds the embedded dir in the default location" do
503
- allow(ChefConfig::Config).to receive(:_this_file).and_return(default_config_location)
504
- expect(ChefConfig::Config.embedded_dir).to eq("c:/opscode/chef/embedded")
505
- end
506
-
507
- it "finds the embedded dir in a custom install location" do
508
- allow(ChefConfig::Config).to receive(:_this_file).and_return(alternate_install_location)
509
- expect(ChefConfig::Config.embedded_dir).to eq("c:/my/alternate/install/place/chef/embedded")
510
- end
511
-
512
- it "doesn't error when not in an omnibus install" do
513
- allow(ChefConfig::Config).to receive(:_this_file).and_return(non_omnibus_location)
514
- expect(ChefConfig::Config.embedded_dir).to be_nil
515
- end
516
-
517
- it "sets the ssl_ca_cert path if the cert file is available" do
518
- allow(ChefConfig::Config).to receive(:_this_file).and_return(default_config_location)
519
- allow(File).to receive(:exist?).with(default_ca_file).and_return(true)
520
- expect(ChefConfig::Config.ssl_ca_file).to eq(default_ca_file)
521
- end
522
- end
523
- end
524
- end
525
-
526
- describe "ChefConfig::Config[:user_home]" do
527
- it "should set when HOME is provided" do
528
- expected = to_platform("/home/kitten")
529
- allow(ChefConfig::PathHelper).to receive(:home).and_return(expected)
530
- expect(ChefConfig::Config[:user_home]).to eq(expected)
531
- end
532
-
533
- it "falls back to the current working directory when HOME and USERPROFILE is not set" do
534
- allow(ChefConfig::PathHelper).to receive(:home).and_return(nil)
535
- expect(ChefConfig::Config[:user_home]).to eq(Dir.pwd)
536
- end
537
- end
538
-
539
- describe "ChefConfig::Config[:encrypted_data_bag_secret]" do
540
- let(:db_secret_default_path) { to_platform("/etc/chef/encrypted_data_bag_secret") }
541
-
542
- before do
543
- allow(File).to receive(:exist?).with(db_secret_default_path).and_return(secret_exists)
544
- end
545
-
546
- context "/etc/chef/encrypted_data_bag_secret exists" do
547
- let(:secret_exists) { true }
548
- it "sets the value to /etc/chef/encrypted_data_bag_secret" do
549
- expect(ChefConfig::Config[:encrypted_data_bag_secret]).to eq db_secret_default_path
550
- end
551
- end
552
-
553
- context "/etc/chef/encrypted_data_bag_secret does not exist" do
554
- let(:secret_exists) { false }
555
- it "sets the value to nil" do
556
- expect(ChefConfig::Config[:encrypted_data_bag_secret]).to be_nil
557
- end
558
- end
559
- end
560
-
561
- describe "ChefConfig::Config[:event_handlers]" do
562
- it "sets a event_handlers to an empty array by default" do
563
- expect(ChefConfig::Config[:event_handlers]).to eq([])
564
- end
565
- it "should be able to add custom handlers" do
566
- o = Object.new
567
- ChefConfig::Config[:event_handlers] << o
568
- expect(ChefConfig::Config[:event_handlers]).to be_include(o)
569
- end
570
- end
571
-
572
- describe "ChefConfig::Config[:user_valid_regex]" do
573
- context "on a platform that is not Windows" do
574
- it "allows one letter usernames" do
575
- any_match = ChefConfig::Config[:user_valid_regex].any? { |regex| regex.match("a") }
576
- expect(any_match).to be_truthy
577
- end
578
- end
579
- end
580
-
581
- describe "ChefConfig::Config[:internal_locale]" do
582
- let(:shell_out) do
583
- cmd = instance_double("Mixlib::ShellOut", exitstatus: 0, stdout: locales, error!: nil)
584
- allow(cmd).to receive(:run_command).and_return(cmd)
585
- cmd
586
- end
587
-
588
- let(:locales) { locale_array.join("\n") }
589
-
590
- before do
591
- allow(Mixlib::ShellOut).to receive(:new).with("locale -a").and_return(shell_out)
592
- end
593
-
594
- shared_examples_for "a suitable locale" do
595
- it "returns an English UTF-8 locale" do
596
- expect(ChefConfig.logger).to_not receive(:warn).with(/Please install an English UTF-8 locale for Chef to use/)
597
- expect(ChefConfig.logger).to_not receive(:debug).with(/Defaulting to locale en_US.UTF-8 on Windows/)
598
- expect(ChefConfig.logger).to_not receive(:debug).with(/No usable locale -a command found/)
599
- expect(ChefConfig::Config.guess_internal_locale).to eq expected_locale
600
- end
601
- end
602
-
603
- context "when the result includes 'C.UTF-8'" do
604
- include_examples "a suitable locale" do
605
- let(:locale_array) { [expected_locale, "en_US.UTF-8"] }
606
- let(:expected_locale) { "C.UTF-8" }
607
- end
608
- end
609
-
610
- context "when the result includes 'en_US.UTF-8'" do
611
- include_examples "a suitable locale" do
612
- let(:locale_array) { ["en_CA.UTF-8", expected_locale, "en_NZ.UTF-8"] }
613
- let(:expected_locale) { "en_US.UTF-8" }
614
- end
615
- end
616
-
617
- context "when the result includes 'en_US.utf8'" do
618
- include_examples "a suitable locale" do
619
- let(:locale_array) { ["en_CA.utf8", "en_US.utf8", "en_NZ.utf8"] }
620
- let(:expected_locale) { "en_US.UTF-8" }
621
- end
622
- end
623
-
624
- context "when the result includes 'en.UTF-8'" do
625
- include_examples "a suitable locale" do
626
- let(:locale_array) { ["en.ISO8859-1", expected_locale] }
627
- let(:expected_locale) { "en.UTF-8" }
628
- end
629
- end
630
-
631
- context "when the result includes 'en_*.UTF-8'" do
632
- include_examples "a suitable locale" do
633
- let(:locale_array) { [expected_locale, "en_CA.UTF-8", "en_GB.UTF-8"] }
634
- let(:expected_locale) { "en_AU.UTF-8" }
635
- end
636
- end
637
-
638
- context "when the result includes 'en_*.utf8'" do
639
- include_examples "a suitable locale" do
640
- let(:locale_array) { ["en_AU.utf8", "en_CA.utf8", "en_GB.utf8"] }
641
- let(:expected_locale) { "en_AU.UTF-8" }
642
- end
643
- end
644
-
645
- context "when the result does not include 'en_*.UTF-8'" do
646
- let(:locale_array) { ["af_ZA", "af_ZA.ISO8859-1", "af_ZA.ISO8859-15", "af_ZA.UTF-8"] }
647
-
648
- it "should fall back to C locale" do
649
- expect(ChefConfig.logger).to receive(:warn).with("Please install an English UTF-8 locale for Chef to use, falling back to C locale and disabling UTF-8 support.")
650
- expect(ChefConfig::Config.guess_internal_locale).to eq "C"
651
- end
652
- end
653
-
654
- context "on error" do
655
- let(:locale_array) { [] }
656
-
657
- let(:shell_out_cmd) { instance_double("Mixlib::ShellOut") }
658
-
659
- before do
660
- allow(Mixlib::ShellOut).to receive(:new).and_return(shell_out_cmd)
661
- allow(shell_out_cmd).to receive(:run_command)
662
- allow(shell_out_cmd).to receive(:error!).and_raise(Mixlib::ShellOut::ShellCommandFailed, "this is an error")
663
- end
664
-
665
- it "should default to 'en_US.UTF-8'" do
666
- if is_windows
667
- expect(ChefConfig.logger).to receive(:debug).with("Defaulting to locale en_US.UTF-8 on Windows, until it matters that we do something else.")
668
- else
669
- expect(ChefConfig.logger).to receive(:debug).with("No usable locale -a command found, assuming you have en_US.UTF-8 installed.")
670
- end
671
- expect(ChefConfig::Config.guess_internal_locale).to eq "en_US.UTF-8"
672
- end
673
- end
674
- end
675
- end
676
- end
677
-
678
- describe "export_proxies" do
679
- let(:http_proxy) { "http://localhost:7979" }
680
- let(:https_proxy) { "https://localhost:7979" }
681
- let(:ftp_proxy) { "ftp://localhost:7979" }
682
- let(:proxy_user) { "http_user" }
683
- let(:proxy_pass) { "http_pass" }
684
-
685
- context "when http_proxy, proxy_pass and proxy_user are set" do
686
- before do
687
- ChefConfig::Config.http_proxy = http_proxy
688
- ChefConfig::Config.http_proxy_user = proxy_user
689
- ChefConfig::Config.http_proxy_pass = proxy_pass
690
- end
691
- it "exports ENV['http_proxy']" do
692
- expect(ENV).to receive(:[]=).with("http_proxy", "http://http_user:http_pass@localhost:7979")
693
- expect(ENV).to receive(:[]=).with("HTTP_PROXY", "http://http_user:http_pass@localhost:7979")
694
- ChefConfig::Config.export_proxies
695
- end
696
- end
697
-
698
- context "when https_proxy, proxy_pass and proxy_user are set" do
699
- before do
700
- ChefConfig::Config.https_proxy = https_proxy
701
- ChefConfig::Config.https_proxy_user = proxy_user
702
- ChefConfig::Config.https_proxy_pass = proxy_pass
703
- end
704
- it "exports ENV['https_proxy']" do
705
- expect(ENV).to receive(:[]=).with("https_proxy", "https://http_user:http_pass@localhost:7979")
706
- expect(ENV).to receive(:[]=).with("HTTPS_PROXY", "https://http_user:http_pass@localhost:7979")
707
- ChefConfig::Config.export_proxies
708
- end
709
- end
710
-
711
- context "when ftp_proxy, proxy_pass and proxy_user are set" do
712
- before do
713
- ChefConfig::Config.ftp_proxy = ftp_proxy
714
- ChefConfig::Config.ftp_proxy_user = proxy_user
715
- ChefConfig::Config.ftp_proxy_pass = proxy_pass
716
- end
717
- it "exports ENV['ftp_proxy']" do
718
- expect(ENV).to receive(:[]=).with("ftp_proxy", "ftp://http_user:http_pass@localhost:7979")
719
- expect(ENV).to receive(:[]=).with("FTP_PROXY", "ftp://http_user:http_pass@localhost:7979")
720
- ChefConfig::Config.export_proxies
721
- end
722
- end
723
-
724
- shared_examples "no user pass" do
725
- it "does not populate the user or password" do
726
- expect(ENV).to receive(:[]=).with("http_proxy", "http://localhost:7979")
727
- expect(ENV).to receive(:[]=).with("HTTP_PROXY", "http://localhost:7979")
728
- ChefConfig::Config.export_proxies
729
- end
730
- end
731
-
732
- context "when proxy_pass and proxy_user are passed as empty strings" do
733
- before do
734
- ChefConfig::Config.http_proxy = http_proxy
735
- ChefConfig::Config.http_proxy_user = ""
736
- ChefConfig::Config.http_proxy_pass = proxy_pass
737
- end
738
- include_examples "no user pass"
739
- end
740
-
741
- context "when proxy_pass and proxy_user are not provided" do
742
- before do
743
- ChefConfig::Config.http_proxy = http_proxy
744
- end
745
- include_examples "no user pass"
746
- end
747
-
748
- context "when the proxy is provided without a scheme" do
749
- before do
750
- ChefConfig::Config.http_proxy = "localhost:1111"
751
- end
752
- it "automatically adds the scheme to the proxy url" do
753
- expect(ENV).to receive(:[]=).with("http_proxy", "http://localhost:1111")
754
- expect(ENV).to receive(:[]=).with("HTTP_PROXY", "http://localhost:1111")
755
- ChefConfig::Config.export_proxies
756
- end
757
- end
758
-
759
- shared_examples "no export" do
760
- it "does not export any proxy settings" do
761
- ChefConfig::Config.export_proxies
762
- expect(ENV["http_proxy"]).to eq(nil)
763
- expect(ENV["https_proxy"]).to eq(nil)
764
- expect(ENV["ftp_proxy"]).to eq(nil)
765
- expect(ENV["no_proxy"]).to eq(nil)
766
- end
767
- end
768
-
769
- context "when nothing is set" do
770
- include_examples "no export"
771
- end
772
-
773
- context "when all the users and passwords are set but no proxies are set" do
774
- before do
775
- ChefConfig::Config.http_proxy_user = proxy_user
776
- ChefConfig::Config.http_proxy_pass = proxy_pass
777
- ChefConfig::Config.https_proxy_user = proxy_user
778
- ChefConfig::Config.https_proxy_pass = proxy_pass
779
- ChefConfig::Config.ftp_proxy_user = proxy_user
780
- ChefConfig::Config.ftp_proxy_pass = proxy_pass
781
- end
782
- include_examples "no export"
783
- end
784
-
785
- context "no_proxy is set" do
786
- before do
787
- ChefConfig::Config.no_proxy = "localhost"
788
- end
789
- it "exports ENV['no_proxy']" do
790
- expect(ENV).to receive(:[]=).with("no_proxy", "localhost")
791
- expect(ENV).to receive(:[]=).with("NO_PROXY", "localhost")
792
- ChefConfig::Config.export_proxies
793
- end
794
- end
795
- end
796
-
797
- describe "allowing chefdk configuration outside of chefdk" do
798
-
799
- it "allows arbitrary settings in the chefdk config context" do
800
- expect { ChefConfig::Config.chefdk.generator_cookbook("/path") }.to_not raise_error
801
- end
802
-
803
- end
804
-
805
- describe "Treating deprecation warnings as errors" do
806
-
807
- context "when using our default RSpec configuration" do
808
-
809
- it "defaults to treating deprecation warnings as errors" do
810
- expect(ChefConfig::Config[:treat_deprecation_warnings_as_errors]).to be(true)
811
- end
812
-
813
- it "sets CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS environment variable" do
814
- expect(ENV["CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS"]).to eq("1")
815
- end
816
-
817
- it "treats deprecation warnings as errors in child processes when testing" do
818
- # Doing a full integration test where we launch a child process is slow
819
- # and liable to break for weird reasons (bundler env stuff, etc.), so
820
- # we're just checking that the presence of the environment variable
821
- # causes treat_deprecation_warnings_as_errors to be set to true after a
822
- # config reset.
823
- ChefConfig::Config.reset
824
- expect(ChefConfig::Config[:treat_deprecation_warnings_as_errors]).to be(true)
825
- end
826
-
827
- end
828
-
829
- context "outside of our test environment" do
830
-
831
- before do
832
- ENV.delete("CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS")
833
- ChefConfig::Config.reset
834
- end
835
-
836
- it "defaults to NOT treating deprecation warnings as errors" do
837
- expect(ChefConfig::Config[:treat_deprecation_warnings_as_errors]).to be(false)
838
- end
839
- end
840
-
841
- end
842
-
843
- end
1
+ #
2
+ # Author:: Adam Jacob (<adam@chef.io>)
3
+ # Author:: Kyle Goodwin (<kgoodwin@primerevenue.com>)
4
+ # Copyright:: Copyright 2008-2016, Chef Software Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require "spec_helper"
21
+ require "chef-config/config"
22
+
23
+ RSpec.describe ChefConfig::Config do
24
+ before(:each) do
25
+ ChefConfig::Config.reset
26
+
27
+ # By default, treat deprecation warnings as errors in tests.
28
+ ChefConfig::Config.treat_deprecation_warnings_as_errors(true)
29
+
30
+ # Set environment variable so the setting persists in child processes
31
+ ENV["CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS"] = "1"
32
+ end
33
+
34
+ describe "config attribute writer: chef_server_url" do
35
+ before do
36
+ ChefConfig::Config.chef_server_url = "https://junglist.gen.nz"
37
+ end
38
+
39
+ it "sets the server url" do
40
+ expect(ChefConfig::Config.chef_server_url).to eq("https://junglist.gen.nz")
41
+ end
42
+
43
+ context "when the url has a leading space" do
44
+ before do
45
+ ChefConfig::Config.chef_server_url = " https://junglist.gen.nz"
46
+ end
47
+
48
+ it "strips the space from the url when setting" do
49
+ expect(ChefConfig::Config.chef_server_url).to eq("https://junglist.gen.nz")
50
+ end
51
+
52
+ end
53
+
54
+ context "when the url is a frozen string" do
55
+ before do
56
+ ChefConfig::Config.chef_server_url = " https://junglist.gen.nz".freeze
57
+ end
58
+
59
+ it "strips the space from the url when setting without raising an error" do
60
+ expect(ChefConfig::Config.chef_server_url).to eq("https://junglist.gen.nz")
61
+ end
62
+ end
63
+
64
+ context "when the url is invalid" do
65
+ it "raises an exception" do
66
+ expect { ChefConfig::Config.chef_server_url = "127.0.0.1" }.to raise_error(ChefConfig::ConfigurationError)
67
+ end
68
+ end
69
+ end
70
+
71
+ describe "when configuring formatters" do
72
+ # if TTY and not(force-logger)
73
+ # formatter = configured formatter or default formatter
74
+ # formatter goes to STDOUT/ERR
75
+ # if log file is writeable
76
+ # log level is configured level or info
77
+ # log location is file
78
+ # else
79
+ # log level is warn
80
+ # log location is STDERR
81
+ # end
82
+ # elsif not(TTY) and force formatter
83
+ # formatter = configured formatter or default formatter
84
+ # if log_location specified
85
+ # formatter goes to log_location
86
+ # else
87
+ # formatter goes to STDOUT/ERR
88
+ # end
89
+ # else
90
+ # formatter = "null"
91
+ # log_location = configured-value or defualt
92
+ # log_level = info or defualt
93
+ # end
94
+ #
95
+ it "has an empty list of formatters by default" do
96
+ expect(ChefConfig::Config.formatters).to eq([])
97
+ end
98
+
99
+ it "configures a formatter with a short name" do
100
+ ChefConfig::Config.add_formatter(:doc)
101
+ expect(ChefConfig::Config.formatters).to eq([[:doc, nil]])
102
+ end
103
+
104
+ it "configures a formatter with a file output" do
105
+ ChefConfig::Config.add_formatter(:doc, "/var/log/formatter.log")
106
+ expect(ChefConfig::Config.formatters).to eq([[:doc, "/var/log/formatter.log"]])
107
+ end
108
+
109
+ end
110
+
111
+ [ false, true ].each do |is_windows|
112
+
113
+ context "On #{is_windows ? 'Windows' : 'Unix'}" do
114
+ def to_platform(*args)
115
+ ChefConfig::Config.platform_specific_path(*args)
116
+ end
117
+
118
+ before :each do
119
+ allow(ChefConfig).to receive(:windows?).and_return(is_windows)
120
+ end
121
+
122
+ describe "class method: platform_specific_path" do
123
+ if is_windows
124
+ it "should return a windows path on windows systems" do
125
+ path = "/etc/chef/cookbooks"
126
+ allow(ChefConfig::Config).to receive(:env).and_return({ "SYSTEMDRIVE" => "C:" })
127
+ # match on a regex that looks for the base path with an optional
128
+ # system drive at the beginning (c:)
129
+ # system drive is not hardcoded b/c it can change and b/c it is not present on linux systems
130
+ expect(ChefConfig::Config.platform_specific_path(path)).to eq("C:\\chef\\cookbooks")
131
+ end
132
+ else
133
+ it "should return given path on non-windows systems" do
134
+ path = "/etc/chef/cookbooks"
135
+ expect(ChefConfig::Config.platform_specific_path(path)).to eq("/etc/chef/cookbooks")
136
+ end
137
+ end
138
+ end
139
+
140
+ describe "default values" do
141
+ let :primary_cache_path do
142
+ if is_windows
143
+ "#{ChefConfig::Config.env['SYSTEMDRIVE']}\\chef"
144
+ else
145
+ "/var/chef"
146
+ end
147
+ end
148
+
149
+ let :secondary_cache_path do
150
+ if is_windows
151
+ "#{ChefConfig::Config[:user_home]}\\.chef"
152
+ else
153
+ "#{ChefConfig::Config[:user_home]}/.chef"
154
+ end
155
+ end
156
+
157
+ before do
158
+ if is_windows
159
+ allow(ChefConfig::Config).to receive(:env).and_return({ "SYSTEMDRIVE" => "C:" })
160
+ ChefConfig::Config[:user_home] = 'C:\Users\charlie'
161
+ else
162
+ ChefConfig::Config[:user_home] = "/Users/charlie"
163
+ end
164
+
165
+ allow(ChefConfig::Config).to receive(:path_accessible?).and_return(false)
166
+ end
167
+
168
+ describe "ChefConfig::Config[:chef_server_root]" do
169
+ context "when chef_server_url isn't set manually" do
170
+ it "returns the default of 'https://localhost:443'" do
171
+ expect(ChefConfig::Config[:chef_server_root]).to eq("https://localhost:443")
172
+ end
173
+ end
174
+
175
+ context "when chef_server_url matches '../organizations/*' without a trailing slash" do
176
+ before do
177
+ ChefConfig::Config[:chef_server_url] = "https://example.com/organizations/myorg"
178
+ end
179
+ it "returns the full URL without /organizations/*" do
180
+ expect(ChefConfig::Config[:chef_server_root]).to eq("https://example.com")
181
+ end
182
+ end
183
+
184
+ context "when chef_server_url matches '../organizations/*' with a trailing slash" do
185
+ before do
186
+ ChefConfig::Config[:chef_server_url] = "https://example.com/organizations/myorg/"
187
+ end
188
+ it "returns the full URL without /organizations/*" do
189
+ expect(ChefConfig::Config[:chef_server_root]).to eq("https://example.com")
190
+ end
191
+ end
192
+
193
+ context "when chef_server_url matches '..organizations..' but not '../organizations/*'" do
194
+ before do
195
+ ChefConfig::Config[:chef_server_url] = "https://organizations.com/organizations"
196
+ end
197
+ it "returns the full URL without any modifications" do
198
+ expect(ChefConfig::Config[:chef_server_root]).to eq(ChefConfig::Config[:chef_server_url])
199
+ end
200
+ end
201
+
202
+ context "when chef_server_url is a standard URL without the string organization(s)" do
203
+ before do
204
+ ChefConfig::Config[:chef_server_url] = "https://example.com/some_other_string"
205
+ end
206
+ it "returns the full URL without any modifications" do
207
+ expect(ChefConfig::Config[:chef_server_root]).to eq(ChefConfig::Config[:chef_server_url])
208
+ end
209
+ end
210
+ end
211
+
212
+ describe "ChefConfig::Config[:cache_path]" do
213
+ context "when /var/chef exists and is accessible" do
214
+ it "defaults to /var/chef" do
215
+ allow(ChefConfig::Config).to receive(:path_accessible?).with(to_platform("/var/chef")).and_return(true)
216
+ expect(ChefConfig::Config[:cache_path]).to eq(primary_cache_path)
217
+ end
218
+ end
219
+
220
+ context "when /var/chef does not exist and /var is accessible" do
221
+ it "defaults to /var/chef" do
222
+ allow(File).to receive(:exists?).with(to_platform("/var/chef")).and_return(false)
223
+ allow(ChefConfig::Config).to receive(:path_accessible?).with(to_platform("/var")).and_return(true)
224
+ expect(ChefConfig::Config[:cache_path]).to eq(primary_cache_path)
225
+ end
226
+ end
227
+
228
+ context "when /var/chef does not exist and /var is not accessible" do
229
+ it "defaults to $HOME/.chef" do
230
+ allow(File).to receive(:exists?).with(to_platform("/var/chef")).and_return(false)
231
+ allow(ChefConfig::Config).to receive(:path_accessible?).with(to_platform("/var")).and_return(false)
232
+ expect(ChefConfig::Config[:cache_path]).to eq(secondary_cache_path)
233
+ end
234
+ end
235
+
236
+ context "when /var/chef exists and is not accessible" do
237
+ it "defaults to $HOME/.chef" do
238
+ allow(File).to receive(:exists?).with(to_platform("/var/chef")).and_return(true)
239
+ allow(File).to receive(:readable?).with(to_platform("/var/chef")).and_return(true)
240
+ allow(File).to receive(:writable?).with(to_platform("/var/chef")).and_return(false)
241
+
242
+ expect(ChefConfig::Config[:cache_path]).to eq(secondary_cache_path)
243
+ end
244
+ end
245
+
246
+ context "when chef is running in local mode" do
247
+ before do
248
+ ChefConfig::Config.local_mode = true
249
+ end
250
+
251
+ context "and config_dir is /a/b/c" do
252
+ before do
253
+ ChefConfig::Config.config_dir to_platform("/a/b/c")
254
+ end
255
+
256
+ it "cache_path is /a/b/c/local-mode-cache" do
257
+ expect(ChefConfig::Config.cache_path).to eq(to_platform("/a/b/c/local-mode-cache"))
258
+ end
259
+ end
260
+
261
+ context "and config_dir is /a/b/c/" do
262
+ before do
263
+ ChefConfig::Config.config_dir to_platform("/a/b/c/")
264
+ end
265
+
266
+ it "cache_path is /a/b/c/local-mode-cache" do
267
+ expect(ChefConfig::Config.cache_path).to eq(to_platform("/a/b/c/local-mode-cache"))
268
+ end
269
+ end
270
+ end
271
+ end
272
+
273
+ it "ChefConfig::Config[:stream_execute_output] defaults to false" do
274
+ expect(ChefConfig::Config[:stream_execute_output]).to eq(false)
275
+ end
276
+
277
+ it "ChefConfig::Config[:show_download_progress] defaults to false" do
278
+ expect(ChefConfig::Config[:show_download_progress]).to eq(false)
279
+ end
280
+
281
+ it "ChefConfig::Config[:download_progress_interval] defaults to every 10%" do
282
+ expect(ChefConfig::Config[:download_progress_interval]).to eq(10)
283
+ end
284
+
285
+ it "ChefConfig::Config[:file_backup_path] defaults to /var/chef/backup" do
286
+ allow(ChefConfig::Config).to receive(:cache_path).and_return(primary_cache_path)
287
+ backup_path = is_windows ? "#{primary_cache_path}\\backup" : "#{primary_cache_path}/backup"
288
+ expect(ChefConfig::Config[:file_backup_path]).to eq(backup_path)
289
+ end
290
+
291
+ it "ChefConfig::Config[:ssl_verify_mode] defaults to :verify_peer" do
292
+ expect(ChefConfig::Config[:ssl_verify_mode]).to eq(:verify_peer)
293
+ end
294
+
295
+ it "ChefConfig::Config[:ssl_ca_path] defaults to nil" do
296
+ expect(ChefConfig::Config[:ssl_ca_path]).to be_nil
297
+ end
298
+
299
+ describe "ChefConfig::Config[:repo_mode]" do
300
+
301
+ context "when local mode is enabled" do
302
+
303
+ before { ChefConfig::Config[:local_mode] = true }
304
+
305
+ it "defaults to 'hosted_everything'" do
306
+ expect(ChefConfig::Config[:repo_mode]).to eq("hosted_everything")
307
+ end
308
+
309
+ context "and osc_compat is enabled" do
310
+
311
+ before { ChefConfig::Config.chef_zero.osc_compat = true }
312
+
313
+ it "defaults to 'everything'" do
314
+ expect(ChefConfig::Config[:repo_mode]).to eq("everything")
315
+ end
316
+ end
317
+ end
318
+
319
+ context "when local mode is not enabled" do
320
+
321
+ context "and the chef_server_url is multi-tenant" do
322
+
323
+ before { ChefConfig::Config[:chef_server_url] = "https://chef.example/organizations/example" }
324
+
325
+ it "defaults to 'hosted_everything'" do
326
+ expect(ChefConfig::Config[:repo_mode]).to eq("hosted_everything")
327
+ end
328
+
329
+ end
330
+
331
+ context "and the chef_server_url is not multi-tenant" do
332
+
333
+ before { ChefConfig::Config[:chef_server_url] = "https://chef.example/" }
334
+
335
+ it "defaults to 'everything'" do
336
+ expect(ChefConfig::Config[:repo_mode]).to eq("everything")
337
+ end
338
+ end
339
+ end
340
+ end
341
+
342
+ describe "ChefConfig::Config[:chef_repo_path]" do
343
+
344
+ context "when cookbook_path is set to a single path" do
345
+
346
+ before { ChefConfig::Config[:cookbook_path] = "/home/anne/repo/cookbooks" }
347
+
348
+ it "is set to a path one directory up from the cookbook_path" do
349
+ expected = File.expand_path("/home/anne/repo")
350
+ expect(ChefConfig::Config[:chef_repo_path]).to eq(expected)
351
+ end
352
+
353
+ end
354
+
355
+ context "when cookbook_path is set to multiple paths" do
356
+
357
+ before do
358
+ ChefConfig::Config[:cookbook_path] = [
359
+ "/home/anne/repo/cookbooks",
360
+ "/home/anne/other_repo/cookbooks",
361
+ ]
362
+ end
363
+
364
+ it "is set to an Array of paths one directory up from the cookbook_paths" do
365
+ expected = [ "/home/anne/repo", "/home/anne/other_repo"].map { |p| File.expand_path(p) }
366
+ expect(ChefConfig::Config[:chef_repo_path]).to eq(expected)
367
+ end
368
+
369
+ end
370
+
371
+ context "when cookbook_path is not set but cookbook_artifact_path is set" do
372
+
373
+ before do
374
+ ChefConfig::Config[:cookbook_path] = nil
375
+ ChefConfig::Config[:cookbook_artifact_path] = "/home/roxie/repo/cookbook_artifacts"
376
+ end
377
+
378
+ it "is set to a path one directory up from the cookbook_artifact_path" do
379
+ expected = File.expand_path("/home/roxie/repo")
380
+ expect(ChefConfig::Config[:chef_repo_path]).to eq(expected)
381
+ end
382
+
383
+ end
384
+
385
+ context "when cookbook_path is not set" do
386
+
387
+ before { ChefConfig::Config[:cookbook_path] = nil }
388
+
389
+ it "is set to the cache_path" do
390
+ expect(ChefConfig::Config[:chef_repo_path]).to eq(ChefConfig::Config[:cache_path])
391
+ end
392
+
393
+ end
394
+
395
+ end
396
+
397
+ # On Windows, we'll detect an omnibus build and set this to the
398
+ # cacert.pem included in the package, but it's nil if you're on Windows
399
+ # w/o omnibus (e.g., doing development on Windows, custom build, etc.)
400
+ if !is_windows
401
+ it "ChefConfig::Config[:ssl_ca_file] defaults to nil" do
402
+ expect(ChefConfig::Config[:ssl_ca_file]).to be_nil
403
+ end
404
+ end
405
+
406
+ it "ChefConfig::Config[:data_bag_path] defaults to /var/chef/data_bags" do
407
+ allow(ChefConfig::Config).to receive(:cache_path).and_return(primary_cache_path)
408
+ data_bag_path = is_windows ? "#{primary_cache_path}\\data_bags" : "#{primary_cache_path}/data_bags"
409
+ expect(ChefConfig::Config[:data_bag_path]).to eq(data_bag_path)
410
+ end
411
+
412
+ it "ChefConfig::Config[:environment_path] defaults to /var/chef/environments" do
413
+ allow(ChefConfig::Config).to receive(:cache_path).and_return(primary_cache_path)
414
+ environment_path = is_windows ? "#{primary_cache_path}\\environments" : "#{primary_cache_path}/environments"
415
+ expect(ChefConfig::Config[:environment_path]).to eq(environment_path)
416
+ end
417
+
418
+ it "ChefConfig::Config[:cookbook_artifact_path] defaults to /var/chef/cookbook_artifacts" do
419
+ allow(ChefConfig::Config).to receive(:cache_path).and_return(primary_cache_path)
420
+ environment_path = is_windows ? "#{primary_cache_path}\\cookbook_artifacts" : "#{primary_cache_path}/cookbook_artifacts"
421
+ expect(ChefConfig::Config[:cookbook_artifact_path]).to eq(environment_path)
422
+ end
423
+
424
+ describe "setting the config dir" do
425
+
426
+ context "when the config file is given with a relative path" do
427
+
428
+ before do
429
+ ChefConfig::Config.config_file = "client.rb"
430
+ end
431
+
432
+ it "expands the path when determining config_dir" do
433
+ # config_dir goes through PathHelper.canonical_path, which
434
+ # downcases on windows because the FS is case insensitive, so we
435
+ # have to downcase expected and actual to make the tests work.
436
+ expect(ChefConfig::Config.config_dir.downcase).to eq(to_platform(Dir.pwd).downcase)
437
+ end
438
+
439
+ it "does not set derived paths at FS root" do
440
+ ChefConfig::Config.local_mode = true
441
+ expect(ChefConfig::Config.cache_path.downcase).to eq(to_platform(File.join(Dir.pwd, "local-mode-cache")).downcase)
442
+ end
443
+
444
+ end
445
+
446
+ context "when the config file is /etc/chef/client.rb" do
447
+
448
+ before do
449
+ config_location = to_platform("/etc/chef/client.rb").downcase
450
+ allow(File).to receive(:absolute_path).with(config_location).and_return(config_location)
451
+ ChefConfig::Config.config_file = config_location
452
+ end
453
+
454
+ it "config_dir is /etc/chef" do
455
+ expect(ChefConfig::Config.config_dir).to eq(to_platform("/etc/chef").downcase)
456
+ end
457
+
458
+ context "and chef is running in local mode" do
459
+ before do
460
+ ChefConfig::Config.local_mode = true
461
+ end
462
+
463
+ it "config_dir is /etc/chef" do
464
+ expect(ChefConfig::Config.config_dir).to eq(to_platform("/etc/chef").downcase)
465
+ end
466
+ end
467
+
468
+ context "when config_dir is set to /other/config/dir/" do
469
+ before do
470
+ ChefConfig::Config.config_dir = to_platform("/other/config/dir/")
471
+ end
472
+
473
+ it "yields the explicit value" do
474
+ expect(ChefConfig::Config.config_dir).to eq(to_platform("/other/config/dir/"))
475
+ end
476
+ end
477
+
478
+ end
479
+
480
+ context "when the user's home dir is /home/charlie/" do
481
+ before do
482
+ ChefConfig::Config.user_home = to_platform("/home/charlie")
483
+ end
484
+
485
+ it "config_dir is /home/charlie/.chef/" do
486
+ expect(ChefConfig::Config.config_dir).to eq(ChefConfig::PathHelper.join(to_platform("/home/charlie/.chef"), ""))
487
+ end
488
+
489
+ context "and chef is running in local mode" do
490
+ before do
491
+ ChefConfig::Config.local_mode = true
492
+ end
493
+
494
+ it "config_dir is /home/charlie/.chef/" do
495
+ expect(ChefConfig::Config.config_dir).to eq(ChefConfig::PathHelper.join(to_platform("/home/charlie/.chef"), ""))
496
+ end
497
+ end
498
+ end
499
+
500
+ end
501
+
502
+ if is_windows
503
+ describe "finding the windows embedded dir" do
504
+ let(:default_config_location) { "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.0/lib/chef/config.rb" }
505
+ let(:alternate_install_location) { "c:/my/alternate/install/place/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.0/lib/chef/config.rb" }
506
+ let(:non_omnibus_location) { "c:/my/dev/stuff/lib/ruby/gems/1.9.1/gems/chef-11.6.0/lib/chef/config.rb" }
507
+
508
+ let(:default_ca_file) { "c:/opscode/chef/embedded/ssl/certs/cacert.pem" }
509
+
510
+ it "finds the embedded dir in the default location" do
511
+ allow(ChefConfig::Config).to receive(:_this_file).and_return(default_config_location)
512
+ expect(ChefConfig::Config.embedded_dir).to eq("c:/opscode/chef/embedded")
513
+ end
514
+
515
+ it "finds the embedded dir in a custom install location" do
516
+ allow(ChefConfig::Config).to receive(:_this_file).and_return(alternate_install_location)
517
+ expect(ChefConfig::Config.embedded_dir).to eq("c:/my/alternate/install/place/chef/embedded")
518
+ end
519
+
520
+ it "doesn't error when not in an omnibus install" do
521
+ allow(ChefConfig::Config).to receive(:_this_file).and_return(non_omnibus_location)
522
+ expect(ChefConfig::Config.embedded_dir).to be_nil
523
+ end
524
+
525
+ it "sets the ssl_ca_cert path if the cert file is available" do
526
+ allow(ChefConfig::Config).to receive(:_this_file).and_return(default_config_location)
527
+ allow(File).to receive(:exist?).with(default_ca_file).and_return(true)
528
+ expect(ChefConfig::Config.ssl_ca_file).to eq(default_ca_file)
529
+ end
530
+ end
531
+ end
532
+ end
533
+
534
+ describe "ChefConfig::Config[:user_home]" do
535
+ it "should set when HOME is provided" do
536
+ expected = to_platform("/home/kitten")
537
+ allow(ChefConfig::PathHelper).to receive(:home).and_return(expected)
538
+ expect(ChefConfig::Config[:user_home]).to eq(expected)
539
+ end
540
+
541
+ it "falls back to the current working directory when HOME and USERPROFILE is not set" do
542
+ allow(ChefConfig::PathHelper).to receive(:home).and_return(nil)
543
+ expect(ChefConfig::Config[:user_home]).to eq(Dir.pwd)
544
+ end
545
+ end
546
+
547
+ describe "ChefConfig::Config[:encrypted_data_bag_secret]" do
548
+ let(:db_secret_default_path) { to_platform("/etc/chef/encrypted_data_bag_secret") }
549
+
550
+ before do
551
+ allow(File).to receive(:exist?).with(db_secret_default_path).and_return(secret_exists)
552
+ end
553
+
554
+ context "/etc/chef/encrypted_data_bag_secret exists" do
555
+ let(:secret_exists) { true }
556
+ it "sets the value to /etc/chef/encrypted_data_bag_secret" do
557
+ expect(ChefConfig::Config[:encrypted_data_bag_secret]).to eq db_secret_default_path
558
+ end
559
+ end
560
+
561
+ context "/etc/chef/encrypted_data_bag_secret does not exist" do
562
+ let(:secret_exists) { false }
563
+ it "sets the value to nil" do
564
+ expect(ChefConfig::Config[:encrypted_data_bag_secret]).to be_nil
565
+ end
566
+ end
567
+ end
568
+
569
+ describe "ChefConfig::Config[:event_handlers]" do
570
+ it "sets a event_handlers to an empty array by default" do
571
+ expect(ChefConfig::Config[:event_handlers]).to eq([])
572
+ end
573
+ it "should be able to add custom handlers" do
574
+ o = Object.new
575
+ ChefConfig::Config[:event_handlers] << o
576
+ expect(ChefConfig::Config[:event_handlers]).to be_include(o)
577
+ end
578
+ end
579
+
580
+ describe "ChefConfig::Config[:user_valid_regex]" do
581
+ context "on a platform that is not Windows" do
582
+ it "allows one letter usernames" do
583
+ any_match = ChefConfig::Config[:user_valid_regex].any? { |regex| regex.match("a") }
584
+ expect(any_match).to be_truthy
585
+ end
586
+ end
587
+ end
588
+
589
+ describe "ChefConfig::Config[:internal_locale]" do
590
+ let(:shell_out) do
591
+ cmd = instance_double("Mixlib::ShellOut", exitstatus: 0, stdout: locales, error!: nil)
592
+ allow(cmd).to receive(:run_command).and_return(cmd)
593
+ cmd
594
+ end
595
+
596
+ let(:locales) { locale_array.join("\n") }
597
+
598
+ before do
599
+ allow(Mixlib::ShellOut).to receive(:new).with("locale -a").and_return(shell_out)
600
+ end
601
+
602
+ shared_examples_for "a suitable locale" do
603
+ it "returns an English UTF-8 locale" do
604
+ expect(ChefConfig.logger).to_not receive(:warn).with(/Please install an English UTF-8 locale for Chef to use/)
605
+ expect(ChefConfig.logger).to_not receive(:debug).with(/Defaulting to locale en_US.UTF-8 on Windows/)
606
+ expect(ChefConfig.logger).to_not receive(:debug).with(/No usable locale -a command found/)
607
+ expect(ChefConfig::Config.guess_internal_locale).to eq expected_locale
608
+ end
609
+ end
610
+
611
+ context "when the result includes 'C.UTF-8'" do
612
+ include_examples "a suitable locale" do
613
+ let(:locale_array) { [expected_locale, "en_US.UTF-8"] }
614
+ let(:expected_locale) { "C.UTF-8" }
615
+ end
616
+ end
617
+
618
+ context "when the result includes 'en_US.UTF-8'" do
619
+ include_examples "a suitable locale" do
620
+ let(:locale_array) { ["en_CA.UTF-8", expected_locale, "en_NZ.UTF-8"] }
621
+ let(:expected_locale) { "en_US.UTF-8" }
622
+ end
623
+ end
624
+
625
+ context "when the result includes 'en_US.utf8'" do
626
+ include_examples "a suitable locale" do
627
+ let(:locale_array) { ["en_CA.utf8", "en_US.utf8", "en_NZ.utf8"] }
628
+ let(:expected_locale) { "en_US.UTF-8" }
629
+ end
630
+ end
631
+
632
+ context "when the result includes 'en.UTF-8'" do
633
+ include_examples "a suitable locale" do
634
+ let(:locale_array) { ["en.ISO8859-1", expected_locale] }
635
+ let(:expected_locale) { "en.UTF-8" }
636
+ end
637
+ end
638
+
639
+ context "when the result includes 'en_*.UTF-8'" do
640
+ include_examples "a suitable locale" do
641
+ let(:locale_array) { [expected_locale, "en_CA.UTF-8", "en_GB.UTF-8"] }
642
+ let(:expected_locale) { "en_AU.UTF-8" }
643
+ end
644
+ end
645
+
646
+ context "when the result includes 'en_*.utf8'" do
647
+ include_examples "a suitable locale" do
648
+ let(:locale_array) { ["en_AU.utf8", "en_CA.utf8", "en_GB.utf8"] }
649
+ let(:expected_locale) { "en_AU.UTF-8" }
650
+ end
651
+ end
652
+
653
+ context "when the result does not include 'en_*.UTF-8'" do
654
+ let(:locale_array) { ["af_ZA", "af_ZA.ISO8859-1", "af_ZA.ISO8859-15", "af_ZA.UTF-8"] }
655
+
656
+ it "should fall back to C locale" do
657
+ expect(ChefConfig.logger).to receive(:warn).with("Please install an English UTF-8 locale for Chef to use, falling back to C locale and disabling UTF-8 support.")
658
+ expect(ChefConfig::Config.guess_internal_locale).to eq "C"
659
+ end
660
+ end
661
+
662
+ context "on error" do
663
+ let(:locale_array) { [] }
664
+
665
+ let(:shell_out_cmd) { instance_double("Mixlib::ShellOut") }
666
+
667
+ before do
668
+ allow(Mixlib::ShellOut).to receive(:new).and_return(shell_out_cmd)
669
+ allow(shell_out_cmd).to receive(:run_command)
670
+ allow(shell_out_cmd).to receive(:error!).and_raise(Mixlib::ShellOut::ShellCommandFailed, "this is an error")
671
+ end
672
+
673
+ it "should default to 'en_US.UTF-8'" do
674
+ if is_windows
675
+ expect(ChefConfig.logger).to receive(:debug).with("Defaulting to locale en_US.UTF-8 on Windows, until it matters that we do something else.")
676
+ else
677
+ expect(ChefConfig.logger).to receive(:debug).with("No usable locale -a command found, assuming you have en_US.UTF-8 installed.")
678
+ end
679
+ expect(ChefConfig::Config.guess_internal_locale).to eq "en_US.UTF-8"
680
+ end
681
+ end
682
+ end
683
+ end
684
+ end
685
+
686
+ describe "export_proxies" do
687
+ before(:all) do
688
+ @original_env = ENV.to_hash
689
+ ENV["http_proxy"] = nil
690
+ ENV["https_proxy"] = nil
691
+ ENV["ftp_proxy"] = nil
692
+ ENV["no_proxy"] = nil
693
+ end
694
+
695
+ after(:all) do
696
+ ENV.clear
697
+ ENV.update(@original_env)
698
+ end
699
+
700
+ let(:http_proxy) { "http://localhost:7979" }
701
+ let(:https_proxy) { "https://localhost:7979" }
702
+ let(:ftp_proxy) { "ftp://localhost:7979" }
703
+ let(:proxy_user) { "http_user" }
704
+ let(:proxy_pass) { "http_pass" }
705
+
706
+ context "when http_proxy, proxy_pass and proxy_user are set" do
707
+ before do
708
+ ChefConfig::Config.http_proxy = http_proxy
709
+ ChefConfig::Config.http_proxy_user = proxy_user
710
+ ChefConfig::Config.http_proxy_pass = proxy_pass
711
+ end
712
+ it "exports ENV['http_proxy']" do
713
+ expect(ENV).to receive(:[]=).with("http_proxy", "http://http_user:http_pass@localhost:7979")
714
+ expect(ENV).to receive(:[]=).with("HTTP_PROXY", "http://http_user:http_pass@localhost:7979")
715
+ ChefConfig::Config.export_proxies
716
+ end
717
+ end
718
+
719
+ context "when https_proxy, proxy_pass and proxy_user are set" do
720
+ before do
721
+ ChefConfig::Config.https_proxy = https_proxy
722
+ ChefConfig::Config.https_proxy_user = proxy_user
723
+ ChefConfig::Config.https_proxy_pass = proxy_pass
724
+ end
725
+ it "exports ENV['https_proxy']" do
726
+ expect(ENV).to receive(:[]=).with("https_proxy", "https://http_user:http_pass@localhost:7979")
727
+ expect(ENV).to receive(:[]=).with("HTTPS_PROXY", "https://http_user:http_pass@localhost:7979")
728
+ ChefConfig::Config.export_proxies
729
+ end
730
+ end
731
+
732
+ context "when ftp_proxy, proxy_pass and proxy_user are set" do
733
+ before do
734
+ ChefConfig::Config.ftp_proxy = ftp_proxy
735
+ ChefConfig::Config.ftp_proxy_user = proxy_user
736
+ ChefConfig::Config.ftp_proxy_pass = proxy_pass
737
+ end
738
+ it "exports ENV['ftp_proxy']" do
739
+ expect(ENV).to receive(:[]=).with("ftp_proxy", "ftp://http_user:http_pass@localhost:7979")
740
+ expect(ENV).to receive(:[]=).with("FTP_PROXY", "ftp://http_user:http_pass@localhost:7979")
741
+ ChefConfig::Config.export_proxies
742
+ end
743
+ end
744
+
745
+ shared_examples "no user pass" do
746
+ it "does not populate the user or password" do
747
+ expect(ENV).to receive(:[]=).with("http_proxy", "http://localhost:7979")
748
+ expect(ENV).to receive(:[]=).with("HTTP_PROXY", "http://localhost:7979")
749
+ ChefConfig::Config.export_proxies
750
+ end
751
+ end
752
+
753
+ context "when proxy_pass and proxy_user are passed as empty strings" do
754
+ before do
755
+ ChefConfig::Config.http_proxy = http_proxy
756
+ ChefConfig::Config.http_proxy_user = ""
757
+ ChefConfig::Config.http_proxy_pass = proxy_pass
758
+ end
759
+ include_examples "no user pass"
760
+ end
761
+
762
+ context "when proxy_pass and proxy_user are not provided" do
763
+ before do
764
+ ChefConfig::Config.http_proxy = http_proxy
765
+ end
766
+ include_examples "no user pass"
767
+ end
768
+
769
+ context "when the proxy is provided without a scheme" do
770
+ before do
771
+ ChefConfig::Config.http_proxy = "localhost:1111"
772
+ end
773
+ it "automatically adds the scheme to the proxy url" do
774
+ expect(ENV).to receive(:[]=).with("http_proxy", "http://localhost:1111")
775
+ expect(ENV).to receive(:[]=).with("HTTP_PROXY", "http://localhost:1111")
776
+ ChefConfig::Config.export_proxies
777
+ end
778
+ end
779
+
780
+ shared_examples "no export" do
781
+ it "does not export any proxy settings" do
782
+ ChefConfig::Config.export_proxies
783
+ expect(ENV["http_proxy"]).to eq(nil)
784
+ expect(ENV["https_proxy"]).to eq(nil)
785
+ expect(ENV["ftp_proxy"]).to eq(nil)
786
+ expect(ENV["no_proxy"]).to eq(nil)
787
+ end
788
+ end
789
+
790
+ context "when nothing is set" do
791
+ include_examples "no export"
792
+ end
793
+
794
+ context "when all the users and passwords are set but no proxies are set" do
795
+ before do
796
+ ChefConfig::Config.http_proxy_user = proxy_user
797
+ ChefConfig::Config.http_proxy_pass = proxy_pass
798
+ ChefConfig::Config.https_proxy_user = proxy_user
799
+ ChefConfig::Config.https_proxy_pass = proxy_pass
800
+ ChefConfig::Config.ftp_proxy_user = proxy_user
801
+ ChefConfig::Config.ftp_proxy_pass = proxy_pass
802
+ end
803
+ include_examples "no export"
804
+ end
805
+
806
+ context "no_proxy is set" do
807
+ before do
808
+ ChefConfig::Config.no_proxy = "localhost"
809
+ end
810
+ it "exports ENV['no_proxy']" do
811
+ expect(ENV).to receive(:[]=).with("no_proxy", "localhost")
812
+ expect(ENV).to receive(:[]=).with("NO_PROXY", "localhost")
813
+ ChefConfig::Config.export_proxies
814
+ end
815
+ end
816
+ end
817
+
818
+ describe "proxy_uri" do
819
+ subject(:proxy_uri) { described_class.proxy_uri(scheme, host, port) }
820
+ let(:env) { {} }
821
+ let(:scheme) { "http" }
822
+ let(:host) { "test.example.com" }
823
+ let(:port) { 8080 }
824
+ let(:proxy) { "#{proxy_prefix}#{proxy_host}:#{proxy_port}" }
825
+ let(:proxy_prefix) { "http://" }
826
+ let(:proxy_host) { "proxy.mycorp.com" }
827
+ let(:proxy_port) { 8080 }
828
+
829
+ before do
830
+ stub_const("ENV", env)
831
+ end
832
+
833
+ shared_examples_for "a proxy uri" do
834
+ it "contains the host" do
835
+ expect(proxy_uri.host).to eq(proxy_host)
836
+ end
837
+
838
+ it "contains the port" do
839
+ expect(proxy_uri.port).to eq(proxy_port)
840
+ end
841
+ end
842
+
843
+ context "when the config setting is normalized (does not contain the scheme)" do
844
+ include_examples "a proxy uri" do
845
+
846
+ let(:proxy_prefix) { "" }
847
+
848
+ let(:env) do
849
+ {
850
+ "#{scheme}_proxy" => proxy,
851
+ "no_proxy" => nil,
852
+ }
853
+ end
854
+ end
855
+ end
856
+
857
+ context "when the proxy is set by the environment" do
858
+ include_examples "a proxy uri" do
859
+ let(:scheme) { "https" }
860
+ let(:env) do
861
+ {
862
+ "https_proxy" => "https://jane_username:opensesame@proxy.mycorp.com:8080",
863
+ }
864
+ end
865
+ end
866
+ end
867
+
868
+ context "when an empty proxy is set by the environment" do
869
+ let(:env) do
870
+ {
871
+ "https_proxy" => "",
872
+ }
873
+ end
874
+
875
+ it "does not fail with URI parse exception" do
876
+ expect { proxy_uri }.to_not raise_error
877
+ end
878
+ end
879
+
880
+ context "when no_proxy is set" do
881
+ context "when no_proxy is the exact host" do
882
+ let(:env) do
883
+ {
884
+ "http_proxy" => proxy,
885
+ "no_proxy" => host,
886
+ }
887
+ end
888
+
889
+ it { is_expected.to eq nil }
890
+ end
891
+
892
+ context "when no_proxy includes the same domain with a wildcard" do
893
+ let(:env) do
894
+ {
895
+ "http_proxy" => proxy,
896
+ "no_proxy" => "*.example.com",
897
+ }
898
+ end
899
+
900
+ it { is_expected.to eq nil }
901
+ end
902
+
903
+ context "when no_proxy is included on a list" do
904
+ let(:env) do
905
+ {
906
+ "http_proxy" => proxy,
907
+ "no_proxy" => "chef.io,getchef.com,opscode.com,test.example.com",
908
+ }
909
+ end
910
+
911
+ it { is_expected.to eq nil }
912
+ end
913
+
914
+ context "when no_proxy is included on a list with wildcards" do
915
+ let(:env) do
916
+ {
917
+ "http_proxy" => proxy,
918
+ "no_proxy" => "10.*,*.example.com",
919
+ }
920
+ end
921
+
922
+ it { is_expected.to eq nil }
923
+ end
924
+
925
+ context "when no_proxy is a domain with a dot prefix" do
926
+ let(:env) do
927
+ {
928
+ "http_proxy" => proxy,
929
+ "no_proxy" => ".example.com",
930
+ }
931
+ end
932
+
933
+ it { is_expected.to eq nil }
934
+ end
935
+
936
+ context "when no_proxy is a domain with no wildcard" do
937
+ let(:env) do
938
+ {
939
+ "http_proxy" => proxy,
940
+ "no_proxy" => "example.com",
941
+ }
942
+ end
943
+
944
+ it { is_expected.to eq nil }
945
+ end
946
+ end
947
+ end
948
+
949
+ describe "allowing chefdk configuration outside of chefdk" do
950
+
951
+ it "allows arbitrary settings in the chefdk config context" do
952
+ expect { ChefConfig::Config.chefdk.generator_cookbook("/path") }.to_not raise_error
953
+ end
954
+
955
+ end
956
+
957
+ describe "Treating deprecation warnings as errors" do
958
+
959
+ context "when using our default RSpec configuration" do
960
+
961
+ it "defaults to treating deprecation warnings as errors" do
962
+ expect(ChefConfig::Config[:treat_deprecation_warnings_as_errors]).to be(true)
963
+ end
964
+
965
+ it "sets CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS environment variable" do
966
+ expect(ENV["CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS"]).to eq("1")
967
+ end
968
+
969
+ it "treats deprecation warnings as errors in child processes when testing" do
970
+ # Doing a full integration test where we launch a child process is slow
971
+ # and liable to break for weird reasons (bundler env stuff, etc.), so
972
+ # we're just checking that the presence of the environment variable
973
+ # causes treat_deprecation_warnings_as_errors to be set to true after a
974
+ # config reset.
975
+ ChefConfig::Config.reset
976
+ expect(ChefConfig::Config[:treat_deprecation_warnings_as_errors]).to be(true)
977
+ end
978
+
979
+ end
980
+
981
+ context "outside of our test environment" do
982
+
983
+ before do
984
+ ENV.delete("CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS")
985
+ ChefConfig::Config.reset
986
+ end
987
+
988
+ it "defaults to NOT treating deprecation warnings as errors" do
989
+ expect(ChefConfig::Config[:treat_deprecation_warnings_as_errors]).to be(false)
990
+ end
991
+ end
992
+
993
+ end
994
+
995
+ end