chef-config 14.10.9 → 14.11.21

Sign up to get free protection for your applications and to get access to all the features.
data/spec/spec_helper.rb CHANGED
@@ -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,1212 +1,1235 @@
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 "parsing arbitrary config from the CLI" do
72
-
73
- def apply_config
74
- described_class.apply_extra_config_options(extra_config_options)
75
- end
76
-
77
- context "when no arbitrary config is given" do
78
-
79
- let(:extra_config_options) { nil }
80
-
81
- it "succeeds" do
82
- expect { apply_config }.to_not raise_error
83
- end
84
-
85
- end
86
-
87
- context "when given a simple string option" do
88
-
89
- let(:extra_config_options) { [ "node_name=bobotclown" ] }
90
-
91
- it "applies the string option" do
92
- apply_config
93
- expect(described_class[:node_name]).to eq("bobotclown")
94
- end
95
-
96
- end
97
-
98
- context "when given a blank value" do
99
-
100
- let(:extra_config_options) { [ "http_retries=" ] }
101
-
102
- it "sets the value to nil" do
103
- # ensure the value is actually changed in the test
104
- described_class[:http_retries] = 55
105
- apply_config
106
- expect(described_class[:http_retries]).to eq(nil)
107
- end
108
- end
109
-
110
- context "when given spaces between `key = value`" do
111
-
112
- let(:extra_config_options) { [ "node_name = bobo" ] }
113
-
114
- it "handles the extra spaces and applies the config option" do
115
- apply_config
116
- expect(described_class[:node_name]).to eq("bobo")
117
- end
118
-
119
- end
120
-
121
- context "when given an integer value" do
122
-
123
- let(:extra_config_options) { [ "http_retries=9000" ] }
124
-
125
- it "converts to a numeric type and applies the config option" do
126
- apply_config
127
- expect(described_class[:http_retries]).to eq(9000)
128
- end
129
-
130
- end
131
-
132
- context "when given a boolean" do
133
-
134
- let(:extra_config_options) { [ "boolean_thing=true" ] }
135
-
136
- it "converts to a boolean type and applies the config option" do
137
- apply_config
138
- expect(described_class[:boolean_thing]).to eq(true)
139
- end
140
-
141
- end
142
-
143
- context "when given input that is not in key=value form" do
144
-
145
- let(:extra_config_options) { [ "http_retries:9000" ] }
146
-
147
- it "raises UnparsableConfigOption" do
148
- message = 'Unparsable config option "http_retries:9000"'
149
- expect { apply_config }.to raise_error(ChefConfig::UnparsableConfigOption, message)
150
- end
151
-
152
- end
153
-
154
- end
155
-
156
- describe "when configuring formatters" do
157
- # if TTY and not(force-logger)
158
- # formatter = configured formatter or default formatter
159
- # formatter goes to STDOUT/ERR
160
- # if log file is writeable
161
- # log level is configured level or info
162
- # log location is file
163
- # else
164
- # log level is warn
165
- # log location is STDERR
166
- # end
167
- # elsif not(TTY) and force formatter
168
- # formatter = configured formatter or default formatter
169
- # if log_location specified
170
- # formatter goes to log_location
171
- # else
172
- # formatter goes to STDOUT/ERR
173
- # end
174
- # else
175
- # formatter = "null"
176
- # log_location = configured-value or defualt
177
- # log_level = info or defualt
178
- # end
179
- #
180
- it "has an empty list of formatters by default" do
181
- expect(ChefConfig::Config.formatters).to eq([])
182
- end
183
-
184
- it "configures a formatter with a short name" do
185
- ChefConfig::Config.add_formatter(:doc)
186
- expect(ChefConfig::Config.formatters).to eq([[:doc, nil]])
187
- end
188
-
189
- it "configures a formatter with a file output" do
190
- ChefConfig::Config.add_formatter(:doc, "/var/log/formatter.log")
191
- expect(ChefConfig::Config.formatters).to eq([[:doc, "/var/log/formatter.log"]])
192
- end
193
-
194
- end
195
-
196
- [ false, true ].each do |is_windows|
197
-
198
- context "On #{is_windows ? 'Windows' : 'Unix'}" do
199
- def to_platform(*args)
200
- ChefConfig::Config.platform_specific_path(*args)
201
- end
202
-
203
- before :each do
204
- allow(ChefConfig).to receive(:windows?).and_return(is_windows)
205
- end
206
- describe "class method: windows_installation_drive" do
207
- before do
208
- allow(File).to receive(:expand_path).and_return("D:/Path/To/Executable")
209
- end
210
- if is_windows
211
- it "should return D: on a windows system" do
212
- expect(ChefConfig::Config.windows_installation_drive).to eq("D:")
213
- end
214
- else
215
- it "should return nil on a non-windows system" do
216
- expect(ChefConfig::Config.windows_installation_drive).to eq(nil)
217
- end
218
- end
219
- end
220
- describe "class method: platform_specific_path" do
221
- before do
222
- allow(ChefConfig::Config).to receive(:env).and_return({ "SYSTEMDRIVE" => "C:" })
223
- end
224
- if is_windows
225
- path = "/etc/chef/cookbooks"
226
- context "a windows system with chef installed on C: drive" do
227
- before do
228
- allow(ChefConfig::Config).to receive(:windows_installation_drive).and_return("C:")
229
- end
230
- it "should return a windows path rooted in C:" do
231
- expect(ChefConfig::Config.platform_specific_path(path)).to eq("C:\\chef\\cookbooks")
232
- end
233
- end
234
- context "a windows system with chef installed on D: drive" do
235
- before do
236
- allow(ChefConfig::Config).to receive(:windows_installation_drive).and_return("D:")
237
- end
238
- it "should return a windows path rooted in D:" do
239
- expect(ChefConfig::Config.platform_specific_path(path)).to eq("D:\\chef\\cookbooks")
240
- end
241
- end
242
- else
243
- it "should return given path on non-windows systems" do
244
- path = "/etc/chef/cookbooks"
245
- expect(ChefConfig::Config.platform_specific_path(path)).to eq("/etc/chef/cookbooks")
246
- end
247
- end
248
- end
249
-
250
- describe "default values" do
251
- let :primary_cache_path do
252
- if is_windows
253
- "#{ChefConfig::Config.env['SYSTEMDRIVE']}\\chef"
254
- else
255
- "/var/chef"
256
- end
257
- end
258
-
259
- let :secondary_cache_path do
260
- if is_windows
261
- "#{ChefConfig::Config[:user_home]}\\.chef"
262
- else
263
- "#{ChefConfig::Config[:user_home]}/.chef"
264
- end
265
- end
266
-
267
- before do
268
- if is_windows
269
- allow(ChefConfig::Config).to receive(:env).and_return({ "SYSTEMDRIVE" => "C:" })
270
- ChefConfig::Config[:user_home] = 'C:\Users\charlie'
271
- else
272
- ChefConfig::Config[:user_home] = "/Users/charlie"
273
- end
274
-
275
- allow(ChefConfig::Config).to receive(:path_accessible?).and_return(false)
276
- end
277
-
278
- describe "ChefConfig::Config[:fips]" do
279
- let(:fips_enabled) { false }
280
-
281
- before(:all) do
282
- @original_env = ENV.to_hash
283
- end
284
-
285
- after(:all) do
286
- ENV.clear
287
- ENV.update(@original_env)
288
- end
289
-
290
- before(:each) do
291
- ENV["CHEF_FIPS"] = nil
292
- allow(ChefConfig).to receive(:fips?).and_return(fips_enabled)
293
- end
294
-
295
- it "returns false when no environment is set and not enabled on system" do
296
- expect(ChefConfig::Config[:fips]).to eq(false)
297
- end
298
-
299
- context "when ENV['CHEF_FIPS'] is empty" do
300
- before do
301
- ENV["CHEF_FIPS"] = ""
302
- end
303
-
304
- it "returns false" do
305
- expect(ChefConfig::Config[:fips]).to eq(false)
306
- end
307
- end
308
-
309
- context "when ENV['CHEF_FIPS'] is set" do
310
- before do
311
- ENV["CHEF_FIPS"] = "1"
312
- end
313
-
314
- it "returns true" do
315
- expect(ChefConfig::Config[:fips]).to eq(true)
316
- end
317
- end
318
-
319
- context "when fips is enabled on system" do
320
- let(:fips_enabled) { true }
321
-
322
- it "returns true" do
323
- expect(ChefConfig::Config[:fips]).to eq(true)
324
- end
325
- end
326
- end
327
-
328
- describe "ChefConfig::Config[:chef_server_root]" do
329
- context "when chef_server_url isn't set manually" do
330
- it "returns the default of 'https://localhost:443'" do
331
- expect(ChefConfig::Config[:chef_server_root]).to eq("https://localhost:443")
332
- end
333
- end
334
-
335
- context "when chef_server_url matches '../organizations/*' without a trailing slash" do
336
- before do
337
- ChefConfig::Config[:chef_server_url] = "https://example.com/organizations/myorg"
338
- end
339
- it "returns the full URL without /organizations/*" do
340
- expect(ChefConfig::Config[:chef_server_root]).to eq("https://example.com")
341
- end
342
- end
343
-
344
- context "when chef_server_url matches '../organizations/*' with a trailing slash" do
345
- before do
346
- ChefConfig::Config[:chef_server_url] = "https://example.com/organizations/myorg/"
347
- end
348
- it "returns the full URL without /organizations/*" do
349
- expect(ChefConfig::Config[:chef_server_root]).to eq("https://example.com")
350
- end
351
- end
352
-
353
- context "when chef_server_url matches '..organizations..' but not '../organizations/*'" do
354
- before do
355
- ChefConfig::Config[:chef_server_url] = "https://organizations.com/organizations"
356
- end
357
- it "returns the full URL without any modifications" do
358
- expect(ChefConfig::Config[:chef_server_root]).to eq(ChefConfig::Config[:chef_server_url])
359
- end
360
- end
361
-
362
- context "when chef_server_url is a standard URL without the string organization(s)" do
363
- before do
364
- ChefConfig::Config[:chef_server_url] = "https://example.com/some_other_string"
365
- end
366
- it "returns the full URL without any modifications" do
367
- expect(ChefConfig::Config[:chef_server_root]).to eq(ChefConfig::Config[:chef_server_url])
368
- end
369
- end
370
- end
371
-
372
- describe "ChefConfig::Config[:cache_path]" do
373
- before do
374
- if is_windows
375
- allow(File).to receive(:expand_path).and_return("#{ChefConfig::Config.env["SYSTEMDRIVE"]}/Path/To/Executable")
376
- end
377
- end
378
- context "when /var/chef exists and is accessible" do
379
- it "defaults to /var/chef" do
380
- allow(ChefConfig::Config).to receive(:path_accessible?).with(to_platform("/var/chef")).and_return(true)
381
- expect(ChefConfig::Config[:cache_path]).to eq(primary_cache_path)
382
- end
383
- end
384
-
385
- context "when /var/chef does not exist and /var is accessible" do
386
- it "defaults to /var/chef" do
387
- allow(File).to receive(:exists?).with(to_platform("/var/chef")).and_return(false)
388
- allow(ChefConfig::Config).to receive(:path_accessible?).with(to_platform("/var")).and_return(true)
389
- expect(ChefConfig::Config[:cache_path]).to eq(primary_cache_path)
390
- end
391
- end
392
-
393
- context "when /var/chef does not exist and /var is not accessible" do
394
- it "defaults to $HOME/.chef" do
395
- allow(File).to receive(:exists?).with(to_platform("/var/chef")).and_return(false)
396
- allow(ChefConfig::Config).to receive(:path_accessible?).with(to_platform("/var")).and_return(false)
397
- expect(ChefConfig::Config[:cache_path]).to eq(secondary_cache_path)
398
- end
399
- end
400
-
401
- context "when /var/chef exists and is not accessible" do
402
- it "defaults to $HOME/.chef" do
403
- allow(File).to receive(:exists?).with(to_platform("/var/chef")).and_return(true)
404
- allow(File).to receive(:readable?).with(to_platform("/var/chef")).and_return(true)
405
- allow(File).to receive(:writable?).with(to_platform("/var/chef")).and_return(false)
406
-
407
- expect(ChefConfig::Config[:cache_path]).to eq(secondary_cache_path)
408
- end
409
- end
410
-
411
- context "when chef is running in local mode" do
412
- before do
413
- ChefConfig::Config.local_mode = true
414
- end
415
-
416
- context "and config_dir is /a/b/c" do
417
- before do
418
- ChefConfig::Config.config_dir to_platform("/a/b/c")
419
- end
420
-
421
- it "cache_path is /a/b/c/local-mode-cache" do
422
- expect(ChefConfig::Config.cache_path).to eq(to_platform("/a/b/c/local-mode-cache"))
423
- end
424
- end
425
-
426
- context "and config_dir is /a/b/c/" do
427
- before do
428
- ChefConfig::Config.config_dir to_platform("/a/b/c/")
429
- end
430
-
431
- it "cache_path is /a/b/c/local-mode-cache" do
432
- expect(ChefConfig::Config.cache_path).to eq(to_platform("/a/b/c/local-mode-cache"))
433
- end
434
- end
435
- end
436
- end
437
-
438
- it "ChefConfig::Config[:stream_execute_output] defaults to false" do
439
- expect(ChefConfig::Config[:stream_execute_output]).to eq(false)
440
- end
441
-
442
- it "ChefConfig::Config[:show_download_progress] defaults to false" do
443
- expect(ChefConfig::Config[:show_download_progress]).to eq(false)
444
- end
445
-
446
- it "ChefConfig::Config[:download_progress_interval] defaults to every 10%" do
447
- expect(ChefConfig::Config[:download_progress_interval]).to eq(10)
448
- end
449
-
450
- it "ChefConfig::Config[:file_backup_path] defaults to /var/chef/backup" do
451
- allow(ChefConfig::Config).to receive(:cache_path).and_return(primary_cache_path)
452
- backup_path = is_windows ? "#{primary_cache_path}\\backup" : "#{primary_cache_path}/backup"
453
- expect(ChefConfig::Config[:file_backup_path]).to eq(backup_path)
454
- end
455
-
456
- it "ChefConfig::Config[:ssl_verify_mode] defaults to :verify_peer" do
457
- expect(ChefConfig::Config[:ssl_verify_mode]).to eq(:verify_peer)
458
- end
459
-
460
- it "ChefConfig::Config[:ssl_ca_path] defaults to nil" do
461
- expect(ChefConfig::Config[:ssl_ca_path]).to be_nil
462
- end
463
-
464
- describe "ChefConfig::Config[:repo_mode]" do
465
-
466
- context "when local mode is enabled" do
467
-
468
- before { ChefConfig::Config[:local_mode] = true }
469
-
470
- it "defaults to 'hosted_everything'" do
471
- expect(ChefConfig::Config[:repo_mode]).to eq("hosted_everything")
472
- end
473
-
474
- context "and osc_compat is enabled" do
475
-
476
- before { ChefConfig::Config.chef_zero.osc_compat = true }
477
-
478
- it "defaults to 'everything'" do
479
- expect(ChefConfig::Config[:repo_mode]).to eq("everything")
480
- end
481
- end
482
- end
483
-
484
- context "when local mode is not enabled" do
485
-
486
- context "and the chef_server_url is multi-tenant" do
487
-
488
- before { ChefConfig::Config[:chef_server_url] = "https://chef.example/organizations/example" }
489
-
490
- it "defaults to 'hosted_everything'" do
491
- expect(ChefConfig::Config[:repo_mode]).to eq("hosted_everything")
492
- end
493
-
494
- end
495
-
496
- context "and the chef_server_url is not multi-tenant" do
497
-
498
- before { ChefConfig::Config[:chef_server_url] = "https://chef.example/" }
499
-
500
- it "defaults to 'everything'" do
501
- expect(ChefConfig::Config[:repo_mode]).to eq("everything")
502
- end
503
- end
504
- end
505
- end
506
-
507
- describe "ChefConfig::Config[:chef_repo_path]" do
508
-
509
- context "when cookbook_path is set to a single path" do
510
-
511
- before { ChefConfig::Config[:cookbook_path] = "/home/anne/repo/cookbooks" }
512
-
513
- it "is set to a path one directory up from the cookbook_path" do
514
- expected = File.expand_path("/home/anne/repo")
515
- expect(ChefConfig::Config[:chef_repo_path]).to eq(expected)
516
- end
517
-
518
- end
519
-
520
- context "when cookbook_path is set to multiple paths" do
521
-
522
- before do
523
- ChefConfig::Config[:cookbook_path] = [
524
- "/home/anne/repo/cookbooks",
525
- "/home/anne/other_repo/cookbooks",
526
- ]
527
- end
528
-
529
- it "is set to an Array of paths one directory up from the cookbook_paths" do
530
- expected = [ "/home/anne/repo", "/home/anne/other_repo"].map { |p| File.expand_path(p) }
531
- expect(ChefConfig::Config[:chef_repo_path]).to eq(expected)
532
- end
533
-
534
- end
535
-
536
- context "when cookbook_path is not set but cookbook_artifact_path is set" do
537
-
538
- before do
539
- ChefConfig::Config[:cookbook_path] = nil
540
- ChefConfig::Config[:cookbook_artifact_path] = "/home/roxie/repo/cookbook_artifacts"
541
- end
542
-
543
- it "is set to a path one directory up from the cookbook_artifact_path" do
544
- expected = File.expand_path("/home/roxie/repo")
545
- expect(ChefConfig::Config[:chef_repo_path]).to eq(expected)
546
- end
547
-
548
- end
549
-
550
- context "when cookbook_path is not set" do
551
-
552
- before { ChefConfig::Config[:cookbook_path] = nil }
553
-
554
- it "is set to the cache_path" do
555
- expect(ChefConfig::Config[:chef_repo_path]).to eq(ChefConfig::Config[:cache_path])
556
- end
557
-
558
- end
559
-
560
- end
561
-
562
- # On Windows, we'll detect an omnibus build and set this to the
563
- # cacert.pem included in the package, but it's nil if you're on Windows
564
- # w/o omnibus (e.g., doing development on Windows, custom build, etc.)
565
- if !is_windows
566
- it "ChefConfig::Config[:ssl_ca_file] defaults to nil" do
567
- expect(ChefConfig::Config[:ssl_ca_file]).to be_nil
568
- end
569
- end
570
-
571
- it "ChefConfig::Config[:data_bag_path] defaults to /var/chef/data_bags" do
572
- allow(ChefConfig::Config).to receive(:cache_path).and_return(primary_cache_path)
573
- data_bag_path = is_windows ? "#{primary_cache_path}\\data_bags" : "#{primary_cache_path}/data_bags"
574
- expect(ChefConfig::Config[:data_bag_path]).to eq(data_bag_path)
575
- end
576
-
577
- it "ChefConfig::Config[:environment_path] defaults to /var/chef/environments" do
578
- allow(ChefConfig::Config).to receive(:cache_path).and_return(primary_cache_path)
579
- environment_path = is_windows ? "#{primary_cache_path}\\environments" : "#{primary_cache_path}/environments"
580
- expect(ChefConfig::Config[:environment_path]).to eq(environment_path)
581
- end
582
-
583
- it "ChefConfig::Config[:cookbook_artifact_path] defaults to /var/chef/cookbook_artifacts" do
584
- allow(ChefConfig::Config).to receive(:cache_path).and_return(primary_cache_path)
585
- environment_path = is_windows ? "#{primary_cache_path}\\cookbook_artifacts" : "#{primary_cache_path}/cookbook_artifacts"
586
- expect(ChefConfig::Config[:cookbook_artifact_path]).to eq(environment_path)
587
- end
588
-
589
- describe "setting the config dir" do
590
-
591
- context "when the config file is given with a relative path" do
592
-
593
- before do
594
- ChefConfig::Config.config_file = "client.rb"
595
- end
596
-
597
- it "expands the path when determining config_dir" do
598
- # config_dir goes through PathHelper.canonical_path, which
599
- # downcases on windows because the FS is case insensitive, so we
600
- # have to downcase expected and actual to make the tests work.
601
- expect(ChefConfig::Config.config_dir.downcase).to eq(to_platform(Dir.pwd).downcase)
602
- end
603
-
604
- it "does not set derived paths at FS root" do
605
- ChefConfig::Config.local_mode = true
606
- expect(ChefConfig::Config.cache_path.downcase).to eq(to_platform(File.join(Dir.pwd, "local-mode-cache")).downcase)
607
- end
608
-
609
- end
610
-
611
- context "when the config file is /etc/chef/client.rb" do
612
-
613
- before do
614
- config_location = to_platform("/etc/chef/client.rb").downcase
615
- allow(File).to receive(:absolute_path).with(config_location).and_return(config_location)
616
- ChefConfig::Config.config_file = config_location
617
- end
618
-
619
- it "config_dir is /etc/chef" do
620
- expect(ChefConfig::Config.config_dir).to eq(to_platform("/etc/chef").downcase)
621
- end
622
-
623
- context "and chef is running in local mode" do
624
- before do
625
- ChefConfig::Config.local_mode = true
626
- end
627
-
628
- it "config_dir is /etc/chef" do
629
- expect(ChefConfig::Config.config_dir).to eq(to_platform("/etc/chef").downcase)
630
- end
631
- end
632
-
633
- context "when config_dir is set to /other/config/dir/" do
634
- before do
635
- ChefConfig::Config.config_dir = to_platform("/other/config/dir/")
636
- end
637
-
638
- it "yields the explicit value" do
639
- expect(ChefConfig::Config.config_dir).to eq(to_platform("/other/config/dir/"))
640
- end
641
- end
642
-
643
- end
644
-
645
- context "when the user's home dir is /home/charlie/" do
646
- before do
647
- ChefConfig::Config.user_home = to_platform("/home/charlie")
648
- end
649
-
650
- it "config_dir is /home/charlie/.chef/" do
651
- expect(ChefConfig::Config.config_dir).to eq(ChefConfig::PathHelper.join(to_platform("/home/charlie/.chef"), ""))
652
- end
653
-
654
- context "and chef is running in local mode" do
655
- before do
656
- ChefConfig::Config.local_mode = true
657
- end
658
-
659
- it "config_dir is /home/charlie/.chef/" do
660
- expect(ChefConfig::Config.config_dir).to eq(ChefConfig::PathHelper.join(to_platform("/home/charlie/.chef"), ""))
661
- end
662
- end
663
- end
664
-
665
- end
666
-
667
- if is_windows
668
- describe "finding the windows embedded dir" do
669
- let(:default_config_location) { "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.0/lib/chef/config.rb" }
670
- 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" }
671
- let(:non_omnibus_location) { "c:/my/dev/stuff/lib/ruby/gems/1.9.1/gems/chef-11.6.0/lib/chef/config.rb" }
672
-
673
- let(:default_ca_file) { "c:/opscode/chef/embedded/ssl/certs/cacert.pem" }
674
-
675
- it "finds the embedded dir in the default location" do
676
- allow(ChefConfig::Config).to receive(:_this_file).and_return(default_config_location)
677
- expect(ChefConfig::Config.embedded_dir).to eq("c:/opscode/chef/embedded")
678
- end
679
-
680
- it "finds the embedded dir in a custom install location" do
681
- allow(ChefConfig::Config).to receive(:_this_file).and_return(alternate_install_location)
682
- expect(ChefConfig::Config.embedded_dir).to eq("c:/my/alternate/install/place/chef/embedded")
683
- end
684
-
685
- it "doesn't error when not in an omnibus install" do
686
- allow(ChefConfig::Config).to receive(:_this_file).and_return(non_omnibus_location)
687
- expect(ChefConfig::Config.embedded_dir).to be_nil
688
- end
689
-
690
- it "sets the ssl_ca_cert path if the cert file is available" do
691
- allow(ChefConfig::Config).to receive(:_this_file).and_return(default_config_location)
692
- allow(File).to receive(:exist?).with(default_ca_file).and_return(true)
693
- expect(ChefConfig::Config.ssl_ca_file).to eq(default_ca_file)
694
- end
695
- end
696
- end
697
- end
698
-
699
- describe "ChefConfig::Config[:user_home]" do
700
- it "should set when HOME is provided" do
701
- expected = to_platform("/home/kitten")
702
- allow(ChefConfig::PathHelper).to receive(:home).and_return(expected)
703
- expect(ChefConfig::Config[:user_home]).to eq(expected)
704
- end
705
-
706
- it "falls back to the current working directory when HOME and USERPROFILE is not set" do
707
- allow(ChefConfig::PathHelper).to receive(:home).and_return(nil)
708
- expect(ChefConfig::Config[:user_home]).to eq(Dir.pwd)
709
- end
710
- end
711
-
712
- describe "ChefConfig::Config[:encrypted_data_bag_secret]" do
713
- let(:db_secret_default_path) { to_platform("/etc/chef/encrypted_data_bag_secret") }
714
-
715
- before do
716
- allow(File).to receive(:exist?).with(db_secret_default_path).and_return(secret_exists)
717
- end
718
-
719
- context "/etc/chef/encrypted_data_bag_secret exists" do
720
- let(:secret_exists) { true }
721
- it "sets the value to /etc/chef/encrypted_data_bag_secret" do
722
- expect(ChefConfig::Config[:encrypted_data_bag_secret]).to eq db_secret_default_path
723
- end
724
- end
725
-
726
- context "/etc/chef/encrypted_data_bag_secret does not exist" do
727
- let(:secret_exists) { false }
728
- it "sets the value to nil" do
729
- expect(ChefConfig::Config[:encrypted_data_bag_secret]).to be_nil
730
- end
731
- end
732
- end
733
-
734
- describe "ChefConfig::Config[:event_handlers]" do
735
- it "sets a event_handlers to an empty array by default" do
736
- expect(ChefConfig::Config[:event_handlers]).to eq([])
737
- end
738
- it "should be able to add custom handlers" do
739
- o = Object.new
740
- ChefConfig::Config[:event_handlers] << o
741
- expect(ChefConfig::Config[:event_handlers]).to be_include(o)
742
- end
743
- end
744
-
745
- describe "ChefConfig::Config[:user_valid_regex]" do
746
- context "on a platform that is not Windows" do
747
- it "allows one letter usernames" do
748
- any_match = ChefConfig::Config[:user_valid_regex].any? { |regex| regex.match("a") }
749
- expect(any_match).to be_truthy
750
- end
751
- end
752
- end
753
-
754
- describe "ChefConfig::Config[:internal_locale]" do
755
- let(:shell_out) do
756
- cmd = instance_double("Mixlib::ShellOut", exitstatus: 0, stdout: locales, error!: nil)
757
- allow(cmd).to receive(:run_command).and_return(cmd)
758
- cmd
759
- end
760
-
761
- let(:locales) { locale_array.join("\n") }
762
-
763
- before do
764
- allow(Mixlib::ShellOut).to receive(:new).with("locale -a").and_return(shell_out)
765
- end
766
-
767
- shared_examples_for "a suitable locale" do
768
- it "returns an English UTF-8 locale" do
769
- expect(ChefConfig.logger).to_not receive(:warn).with(/Please install an English UTF-8 locale for Chef to use/)
770
- expect(ChefConfig.logger).to_not receive(:trace).with(/Defaulting to locale en_US.UTF-8 on Windows/)
771
- expect(ChefConfig.logger).to_not receive(:trace).with(/No usable locale -a command found/)
772
- expect(ChefConfig::Config.guess_internal_locale).to eq expected_locale
773
- end
774
- end
775
-
776
- context "when the result includes 'C.UTF-8'" do
777
- include_examples "a suitable locale" do
778
- let(:locale_array) { [expected_locale, "en_US.UTF-8"] }
779
- let(:expected_locale) { "C.UTF-8" }
780
- end
781
- end
782
-
783
- context "when the result includes 'en_US.UTF-8'" do
784
- include_examples "a suitable locale" do
785
- let(:locale_array) { ["en_CA.UTF-8", expected_locale, "en_NZ.UTF-8"] }
786
- let(:expected_locale) { "en_US.UTF-8" }
787
- end
788
- end
789
-
790
- context "when the result includes 'en_US.utf8'" do
791
- include_examples "a suitable locale" do
792
- let(:locale_array) { ["en_CA.utf8", "en_US.utf8", "en_NZ.utf8"] }
793
- let(:expected_locale) { "en_US.UTF-8" }
794
- end
795
- end
796
-
797
- context "when the result includes 'en.UTF-8'" do
798
- include_examples "a suitable locale" do
799
- let(:locale_array) { ["en.ISO8859-1", expected_locale] }
800
- let(:expected_locale) { "en.UTF-8" }
801
- end
802
- end
803
-
804
- context "when the result includes 'en_*.UTF-8'" do
805
- include_examples "a suitable locale" do
806
- let(:locale_array) { [expected_locale, "en_CA.UTF-8", "en_GB.UTF-8"] }
807
- let(:expected_locale) { "en_AU.UTF-8" }
808
- end
809
- end
810
-
811
- context "when the result includes 'en_*.utf8'" do
812
- include_examples "a suitable locale" do
813
- let(:locale_array) { ["en_AU.utf8", "en_CA.utf8", "en_GB.utf8"] }
814
- let(:expected_locale) { "en_AU.UTF-8" }
815
- end
816
- end
817
-
818
- context "when the result does not include 'en_*.UTF-8'" do
819
- let(:locale_array) { ["af_ZA", "af_ZA.ISO8859-1", "af_ZA.ISO8859-15", "af_ZA.UTF-8"] }
820
-
821
- it "should fall back to C locale" do
822
- 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.")
823
- expect(ChefConfig::Config.guess_internal_locale).to eq "C"
824
- end
825
- end
826
-
827
- context "on error" do
828
- let(:locale_array) { [] }
829
-
830
- let(:shell_out_cmd) { instance_double("Mixlib::ShellOut") }
831
-
832
- before do
833
- allow(Mixlib::ShellOut).to receive(:new).and_return(shell_out_cmd)
834
- allow(shell_out_cmd).to receive(:run_command)
835
- allow(shell_out_cmd).to receive(:error!).and_raise(Mixlib::ShellOut::ShellCommandFailed, "this is an error")
836
- end
837
-
838
- it "should default to 'en_US.UTF-8'" do
839
- if is_windows
840
- expect(ChefConfig.logger).to receive(:trace).with("Defaulting to locale en_US.UTF-8 on Windows, until it matters that we do something else.")
841
- else
842
- expect(ChefConfig.logger).to receive(:trace).with("No usable locale -a command found, assuming you have en_US.UTF-8 installed.")
843
- end
844
- expect(ChefConfig::Config.guess_internal_locale).to eq "en_US.UTF-8"
845
- end
846
- end
847
- end
848
- end
849
- end
850
-
851
- describe "export_proxies" do
852
- before(:all) do
853
- @original_env = ENV.to_hash
854
- ENV["http_proxy"] = nil
855
- ENV["HTTP_PROXY"] = nil
856
- ENV["https_proxy"] = nil
857
- ENV["HTTPS_PROXY"] = nil
858
- ENV["ftp_proxy"] = nil
859
- ENV["FTP_PROXY"] = nil
860
- ENV["no_proxy"] = nil
861
- ENV["NO_PROXY"] = nil
862
- end
863
-
864
- after(:all) do
865
- ENV.clear
866
- ENV.update(@original_env)
867
- end
868
-
869
- let(:http_proxy) { "http://localhost:7979" }
870
- let(:https_proxy) { "https://localhost:7979" }
871
- let(:ftp_proxy) { "ftp://localhost:7979" }
872
- let(:proxy_user) { "http_user" }
873
- let(:proxy_pass) { "http_pass" }
874
-
875
- context "when http_proxy, proxy_pass and proxy_user are set" do
876
- before do
877
- ChefConfig::Config.http_proxy = http_proxy
878
- ChefConfig::Config.http_proxy_user = proxy_user
879
- ChefConfig::Config.http_proxy_pass = proxy_pass
880
- end
881
- it "exports ENV['http_proxy']" do
882
- expect(ENV).to receive(:[]=).with("http_proxy", "http://http_user:http_pass@localhost:7979")
883
- expect(ENV).to receive(:[]=).with("HTTP_PROXY", "http://http_user:http_pass@localhost:7979")
884
- ChefConfig::Config.export_proxies
885
- end
886
- end
887
-
888
- context "when https_proxy, proxy_pass and proxy_user are set" do
889
- before do
890
- ChefConfig::Config.https_proxy = https_proxy
891
- ChefConfig::Config.https_proxy_user = proxy_user
892
- ChefConfig::Config.https_proxy_pass = proxy_pass
893
- end
894
- it "exports ENV['https_proxy']" do
895
- expect(ENV).to receive(:[]=).with("https_proxy", "https://http_user:http_pass@localhost:7979")
896
- expect(ENV).to receive(:[]=).with("HTTPS_PROXY", "https://http_user:http_pass@localhost:7979")
897
- ChefConfig::Config.export_proxies
898
- end
899
- end
900
-
901
- context "when ftp_proxy, proxy_pass and proxy_user are set" do
902
- before do
903
- ChefConfig::Config.ftp_proxy = ftp_proxy
904
- ChefConfig::Config.ftp_proxy_user = proxy_user
905
- ChefConfig::Config.ftp_proxy_pass = proxy_pass
906
- end
907
- it "exports ENV['ftp_proxy']" do
908
- expect(ENV).to receive(:[]=).with("ftp_proxy", "ftp://http_user:http_pass@localhost:7979")
909
- expect(ENV).to receive(:[]=).with("FTP_PROXY", "ftp://http_user:http_pass@localhost:7979")
910
- ChefConfig::Config.export_proxies
911
- end
912
- end
913
-
914
- shared_examples "no user pass" do
915
- it "does not populate the user or password" do
916
- expect(ENV).to receive(:[]=).with("http_proxy", "http://localhost:7979")
917
- expect(ENV).to receive(:[]=).with("HTTP_PROXY", "http://localhost:7979")
918
- ChefConfig::Config.export_proxies
919
- end
920
- end
921
-
922
- context "when proxy_pass and proxy_user are passed as empty strings" do
923
- before do
924
- ChefConfig::Config.http_proxy = http_proxy
925
- ChefConfig::Config.http_proxy_user = ""
926
- ChefConfig::Config.http_proxy_pass = proxy_pass
927
- end
928
- include_examples "no user pass"
929
- end
930
-
931
- context "when proxy_pass and proxy_user are not provided" do
932
- before do
933
- ChefConfig::Config.http_proxy = http_proxy
934
- end
935
- include_examples "no user pass"
936
- end
937
-
938
- context "when the proxy is provided without a scheme" do
939
- before do
940
- ChefConfig::Config.http_proxy = "localhost:1111"
941
- end
942
- it "automatically adds the scheme to the proxy url" do
943
- expect(ENV).to receive(:[]=).with("http_proxy", "http://localhost:1111")
944
- expect(ENV).to receive(:[]=).with("HTTP_PROXY", "http://localhost:1111")
945
- ChefConfig::Config.export_proxies
946
- end
947
- end
948
-
949
- shared_examples "no export" do
950
- it "does not export any proxy settings" do
951
- ChefConfig::Config.export_proxies
952
- expect(ENV["http_proxy"]).to eq(nil)
953
- expect(ENV["https_proxy"]).to eq(nil)
954
- expect(ENV["ftp_proxy"]).to eq(nil)
955
- expect(ENV["no_proxy"]).to eq(nil)
956
- end
957
- end
958
-
959
- context "when nothing is set" do
960
- include_examples "no export"
961
- end
962
-
963
- context "when all the users and passwords are set but no proxies are set" do
964
- before do
965
- ChefConfig::Config.http_proxy_user = proxy_user
966
- ChefConfig::Config.http_proxy_pass = proxy_pass
967
- ChefConfig::Config.https_proxy_user = proxy_user
968
- ChefConfig::Config.https_proxy_pass = proxy_pass
969
- ChefConfig::Config.ftp_proxy_user = proxy_user
970
- ChefConfig::Config.ftp_proxy_pass = proxy_pass
971
- end
972
- include_examples "no export"
973
- end
974
-
975
- context "no_proxy is set" do
976
- before do
977
- ChefConfig::Config.no_proxy = "localhost"
978
- end
979
- it "exports ENV['no_proxy']" do
980
- expect(ENV).to receive(:[]=).with("no_proxy", "localhost")
981
- expect(ENV).to receive(:[]=).with("NO_PROXY", "localhost")
982
- ChefConfig::Config.export_proxies
983
- end
984
- end
985
- end
986
-
987
- describe "proxy_uri" do
988
- subject(:proxy_uri) { described_class.proxy_uri(scheme, host, port) }
989
- let(:env) { {} }
990
- let(:scheme) { "http" }
991
- let(:host) { "test.example.com" }
992
- let(:port) { 8080 }
993
- let(:proxy) { "#{proxy_prefix}#{proxy_host}:#{proxy_port}" }
994
- let(:proxy_prefix) { "http://" }
995
- let(:proxy_host) { "proxy.mycorp.com" }
996
- let(:proxy_port) { 8080 }
997
-
998
- before do
999
- stub_const("ENV", env)
1000
- end
1001
-
1002
- shared_examples_for "a proxy uri" do
1003
- it "contains the host" do
1004
- expect(proxy_uri.host).to eq(proxy_host)
1005
- end
1006
-
1007
- it "contains the port" do
1008
- expect(proxy_uri.port).to eq(proxy_port)
1009
- end
1010
- end
1011
-
1012
- context "when the config setting is normalized (does not contain the scheme)" do
1013
- include_examples "a proxy uri" do
1014
-
1015
- let(:proxy_prefix) { "" }
1016
-
1017
- let(:env) do
1018
- {
1019
- "#{scheme}_proxy" => proxy,
1020
- "no_proxy" => nil,
1021
- }
1022
- end
1023
- end
1024
- end
1025
-
1026
- context "when the proxy is set by the environment" do
1027
- include_examples "a proxy uri" do
1028
- let(:scheme) { "https" }
1029
- let(:env) do
1030
- {
1031
- "https_proxy" => "https://jane_username:opensesame@proxy.mycorp.com:8080",
1032
- }
1033
- end
1034
- end
1035
- end
1036
-
1037
- context "when an empty proxy is set by the environment" do
1038
- let(:env) do
1039
- {
1040
- "https_proxy" => "",
1041
- }
1042
- end
1043
-
1044
- it "does not fail with URI parse exception" do
1045
- expect { proxy_uri }.to_not raise_error
1046
- end
1047
- end
1048
-
1049
- context "when no_proxy is set" do
1050
- context "when no_proxy is the exact host" do
1051
- let(:env) do
1052
- {
1053
- "http_proxy" => proxy,
1054
- "no_proxy" => host,
1055
- }
1056
- end
1057
-
1058
- it { is_expected.to eq nil }
1059
- end
1060
-
1061
- context "when no_proxy includes the same domain with a wildcard" do
1062
- let(:env) do
1063
- {
1064
- "http_proxy" => proxy,
1065
- "no_proxy" => "*.example.com",
1066
- }
1067
- end
1068
-
1069
- it { is_expected.to eq nil }
1070
- end
1071
-
1072
- context "when no_proxy is included on a list" do
1073
- let(:env) do
1074
- {
1075
- "http_proxy" => proxy,
1076
- "no_proxy" => "chef.io,getchef.com,opscode.com,test.example.com",
1077
- }
1078
- end
1079
-
1080
- it { is_expected.to eq nil }
1081
- end
1082
-
1083
- context "when no_proxy is included on a list with wildcards" do
1084
- let(:env) do
1085
- {
1086
- "http_proxy" => proxy,
1087
- "no_proxy" => "10.*,*.example.com",
1088
- }
1089
- end
1090
-
1091
- it { is_expected.to eq nil }
1092
- end
1093
-
1094
- context "when no_proxy is a domain with a dot prefix" do
1095
- let(:env) do
1096
- {
1097
- "http_proxy" => proxy,
1098
- "no_proxy" => ".example.com",
1099
- }
1100
- end
1101
-
1102
- it { is_expected.to eq nil }
1103
- end
1104
-
1105
- context "when no_proxy is a domain with no wildcard" do
1106
- let(:env) do
1107
- {
1108
- "http_proxy" => proxy,
1109
- "no_proxy" => "example.com",
1110
- }
1111
- end
1112
-
1113
- it { is_expected.to eq nil }
1114
- end
1115
- end
1116
- end
1117
-
1118
- describe "allowing chefdk configuration outside of chefdk" do
1119
-
1120
- it "allows arbitrary settings in the chefdk config context" do
1121
- expect { ChefConfig::Config.chefdk.generator_cookbook("/path") }.to_not raise_error
1122
- end
1123
-
1124
- end
1125
-
1126
- describe "Treating deprecation warnings as errors" do
1127
-
1128
- context "when using our default RSpec configuration" do
1129
-
1130
- it "defaults to treating deprecation warnings as errors" do
1131
- expect(ChefConfig::Config[:treat_deprecation_warnings_as_errors]).to be(true)
1132
- end
1133
-
1134
- it "sets CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS environment variable" do
1135
- expect(ENV["CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS"]).to eq("1")
1136
- end
1137
-
1138
- it "treats deprecation warnings as errors in child processes when testing" do
1139
- # Doing a full integration test where we launch a child process is slow
1140
- # and liable to break for weird reasons (bundler env stuff, etc.), so
1141
- # we're just checking that the presence of the environment variable
1142
- # causes treat_deprecation_warnings_as_errors to be set to true after a
1143
- # config reset.
1144
- ChefConfig::Config.reset
1145
- expect(ChefConfig::Config[:treat_deprecation_warnings_as_errors]).to be(true)
1146
- end
1147
-
1148
- end
1149
-
1150
- context "outside of our test environment" do
1151
-
1152
- before do
1153
- ENV.delete("CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS")
1154
- ChefConfig::Config.reset
1155
- end
1156
-
1157
- it "defaults to NOT treating deprecation warnings as errors" do
1158
- expect(ChefConfig::Config[:treat_deprecation_warnings_as_errors]).to be(false)
1159
- end
1160
- end
1161
-
1162
- end
1163
-
1164
- describe "data collector URL" do
1165
-
1166
- context "when using default settings" do
1167
-
1168
- context "for Chef Client" do
1169
-
1170
- it "configures the data collector URL as a relative path to the Chef Server URL" do
1171
- ChefConfig::Config[:chef_server_url] = "https://chef.example/organizations/myorg"
1172
- expect(ChefConfig::Config[:data_collector][:server_url]).to eq("https://chef.example/organizations/myorg/data-collector")
1173
- end
1174
-
1175
- end
1176
-
1177
- context "for Chef Solo" do
1178
-
1179
- before do
1180
- ChefConfig::Config[:solo] = true
1181
- end
1182
-
1183
- it "sets the data collector server URL to nil" do
1184
- ChefConfig::Config[:chef_server_url] = "https://chef.example/organizations/myorg"
1185
- expect(ChefConfig::Config[:data_collector][:server_url]).to be_nil
1186
- end
1187
-
1188
- end
1189
-
1190
- end
1191
-
1192
- end
1193
-
1194
- describe "validation_client_name" do
1195
- context "with a normal server URL" do
1196
- before { ChefConfig::Config[:chef_server_url] = "https://chef.example/organizations/myorg" }
1197
-
1198
- it "sets the validation client to myorg-validator" do
1199
- expect(ChefConfig::Config[:validation_client_name]).to eq "myorg-validator"
1200
- end
1201
- end
1202
-
1203
- context "with an unusual server URL" do
1204
- before { ChefConfig::Config[:chef_server_url] = "https://chef.example/myorg" }
1205
-
1206
- it "sets the validation client to chef-validator" do
1207
- expect(ChefConfig::Config[:validation_client_name]).to eq "chef-validator"
1208
- end
1209
- end
1210
- end
1211
-
1212
- 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 "parsing arbitrary config from the CLI" do
72
+
73
+ def apply_config
74
+ described_class.apply_extra_config_options(extra_config_options)
75
+ end
76
+
77
+ context "when no arbitrary config is given" do
78
+
79
+ let(:extra_config_options) { nil }
80
+
81
+ it "succeeds" do
82
+ expect { apply_config }.to_not raise_error
83
+ end
84
+
85
+ end
86
+
87
+ context "when given a simple string option" do
88
+
89
+ let(:extra_config_options) { [ "node_name=bobotclown" ] }
90
+
91
+ it "applies the string option" do
92
+ apply_config
93
+ expect(described_class[:node_name]).to eq("bobotclown")
94
+ end
95
+
96
+ end
97
+
98
+ context "when given a blank value" do
99
+
100
+ let(:extra_config_options) { [ "http_retries=" ] }
101
+
102
+ it "sets the value to nil" do
103
+ # ensure the value is actually changed in the test
104
+ described_class[:http_retries] = 55
105
+ apply_config
106
+ expect(described_class[:http_retries]).to eq(nil)
107
+ end
108
+ end
109
+
110
+ context "when given spaces between `key = value`" do
111
+
112
+ let(:extra_config_options) { [ "node_name = bobo" ] }
113
+
114
+ it "handles the extra spaces and applies the config option" do
115
+ apply_config
116
+ expect(described_class[:node_name]).to eq("bobo")
117
+ end
118
+
119
+ end
120
+
121
+ context "when given an integer value" do
122
+
123
+ let(:extra_config_options) { [ "http_retries=9000" ] }
124
+
125
+ it "converts to a numeric type and applies the config option" do
126
+ apply_config
127
+ expect(described_class[:http_retries]).to eq(9000)
128
+ end
129
+
130
+ end
131
+
132
+ context "when given a boolean" do
133
+
134
+ let(:extra_config_options) { [ "boolean_thing=true" ] }
135
+
136
+ it "converts to a boolean type and applies the config option" do
137
+ apply_config
138
+ expect(described_class[:boolean_thing]).to eq(true)
139
+ end
140
+
141
+ end
142
+
143
+ context "when given input that is not in key=value form" do
144
+
145
+ let(:extra_config_options) { [ "http_retries:9000" ] }
146
+
147
+ it "raises UnparsableConfigOption" do
148
+ message = 'Unparsable config option "http_retries:9000"'
149
+ expect { apply_config }.to raise_error(ChefConfig::UnparsableConfigOption, message)
150
+ end
151
+
152
+ end
153
+
154
+ end
155
+
156
+ describe "when configuring formatters" do
157
+ # if TTY and not(force-logger)
158
+ # formatter = configured formatter or default formatter
159
+ # formatter goes to STDOUT/ERR
160
+ # if log file is writeable
161
+ # log level is configured level or info
162
+ # log location is file
163
+ # else
164
+ # log level is warn
165
+ # log location is STDERR
166
+ # end
167
+ # elsif not(TTY) and force formatter
168
+ # formatter = configured formatter or default formatter
169
+ # if log_location specified
170
+ # formatter goes to log_location
171
+ # else
172
+ # formatter goes to STDOUT/ERR
173
+ # end
174
+ # else
175
+ # formatter = "null"
176
+ # log_location = configured-value or defualt
177
+ # log_level = info or defualt
178
+ # end
179
+ #
180
+ it "has an empty list of formatters by default" do
181
+ expect(ChefConfig::Config.formatters).to eq([])
182
+ end
183
+
184
+ it "configures a formatter with a short name" do
185
+ ChefConfig::Config.add_formatter(:doc)
186
+ expect(ChefConfig::Config.formatters).to eq([[:doc, nil]])
187
+ end
188
+
189
+ it "configures a formatter with a file output" do
190
+ ChefConfig::Config.add_formatter(:doc, "/var/log/formatter.log")
191
+ expect(ChefConfig::Config.formatters).to eq([[:doc, "/var/log/formatter.log"]])
192
+ end
193
+
194
+ end
195
+
196
+ [ false, true ].each do |is_windows|
197
+
198
+ context "On #{is_windows ? 'Windows' : 'Unix'}" do
199
+ def to_platform(*args)
200
+ ChefConfig::Config.platform_specific_path(*args)
201
+ end
202
+
203
+ before :each do
204
+ allow(ChefConfig).to receive(:windows?).and_return(is_windows)
205
+ end
206
+ describe "class method: windows_installation_drive" do
207
+ before do
208
+ allow(File).to receive(:expand_path).and_return("D:/Path/To/Executable")
209
+ end
210
+ if is_windows
211
+ it "should return D: on a windows system" do
212
+ expect(ChefConfig::Config.windows_installation_drive).to eq("D:")
213
+ end
214
+ else
215
+ it "should return nil on a non-windows system" do
216
+ expect(ChefConfig::Config.windows_installation_drive).to eq(nil)
217
+ end
218
+ end
219
+ end
220
+ describe "class method: platform_specific_path" do
221
+ before do
222
+ allow(ChefConfig::Config).to receive(:env).and_return({ "SYSTEMDRIVE" => "C:" })
223
+ end
224
+ if is_windows
225
+ path = "/etc/chef/cookbooks"
226
+ context "a windows system with chef installed on C: drive" do
227
+ before do
228
+ allow(ChefConfig::Config).to receive(:windows_installation_drive).and_return("C:")
229
+ end
230
+ it "should return a windows path rooted in C:" do
231
+ expect(ChefConfig::Config.platform_specific_path(path)).to eq("C:\\chef\\cookbooks")
232
+ end
233
+ end
234
+ context "a windows system with chef installed on D: drive" do
235
+ before do
236
+ allow(ChefConfig::Config).to receive(:windows_installation_drive).and_return("D:")
237
+ end
238
+ it "should return a windows path rooted in D:" do
239
+ expect(ChefConfig::Config.platform_specific_path(path)).to eq("D:\\chef\\cookbooks")
240
+ end
241
+ end
242
+ else
243
+ it "should return given path on non-windows systems" do
244
+ path = "/etc/chef/cookbooks"
245
+ expect(ChefConfig::Config.platform_specific_path(path)).to eq("/etc/chef/cookbooks")
246
+ end
247
+ end
248
+ end
249
+
250
+ describe "default values" do
251
+ let :primary_cache_path do
252
+ if is_windows
253
+ "#{ChefConfig::Config.env['SYSTEMDRIVE']}\\chef"
254
+ else
255
+ "/var/chef"
256
+ end
257
+ end
258
+
259
+ let :secondary_cache_path do
260
+ if is_windows
261
+ "#{ChefConfig::Config[:user_home]}\\.chef"
262
+ else
263
+ "#{ChefConfig::Config[:user_home]}/.chef"
264
+ end
265
+ end
266
+
267
+ before do
268
+ if is_windows
269
+ allow(ChefConfig::Config).to receive(:env).and_return({ "SYSTEMDRIVE" => "C:" })
270
+ ChefConfig::Config[:user_home] = 'C:\Users\charlie'
271
+ else
272
+ ChefConfig::Config[:user_home] = "/Users/charlie"
273
+ end
274
+
275
+ allow(ChefConfig::Config).to receive(:path_accessible?).and_return(false)
276
+ end
277
+
278
+ describe "ChefConfig::Config[:fips]" do
279
+ let(:fips_enabled) { false }
280
+
281
+ before(:all) do
282
+ @original_env = ENV.to_hash
283
+ end
284
+
285
+ after(:all) do
286
+ ENV.clear
287
+ ENV.update(@original_env)
288
+ end
289
+
290
+ before(:each) do
291
+ ENV["CHEF_FIPS"] = nil
292
+ allow(ChefConfig).to receive(:fips?).and_return(fips_enabled)
293
+ end
294
+
295
+ it "returns false when no environment is set and not enabled on system" do
296
+ expect(ChefConfig::Config[:fips]).to eq(false)
297
+ end
298
+
299
+ context "when ENV['CHEF_FIPS'] is empty" do
300
+ before do
301
+ ENV["CHEF_FIPS"] = ""
302
+ end
303
+
304
+ it "returns false" do
305
+ expect(ChefConfig::Config[:fips]).to eq(false)
306
+ end
307
+ end
308
+
309
+ context "when ENV['CHEF_FIPS'] is set" do
310
+ before do
311
+ ENV["CHEF_FIPS"] = "1"
312
+ end
313
+
314
+ it "returns true" do
315
+ expect(ChefConfig::Config[:fips]).to eq(true)
316
+ end
317
+ end
318
+
319
+ context "when fips is enabled on system" do
320
+ let(:fips_enabled) { true }
321
+
322
+ it "returns true" do
323
+ expect(ChefConfig::Config[:fips]).to eq(true)
324
+ end
325
+ end
326
+ end
327
+
328
+ describe "ChefConfig::Config[:chef_server_root]" do
329
+ context "when chef_server_url isn't set manually" do
330
+ it "returns the default of 'https://localhost:443'" do
331
+ expect(ChefConfig::Config[:chef_server_root]).to eq("https://localhost:443")
332
+ end
333
+ end
334
+
335
+ context "when chef_server_url matches '../organizations/*' without a trailing slash" do
336
+ before do
337
+ ChefConfig::Config[:chef_server_url] = "https://example.com/organizations/myorg"
338
+ end
339
+ it "returns the full URL without /organizations/*" do
340
+ expect(ChefConfig::Config[:chef_server_root]).to eq("https://example.com")
341
+ end
342
+ end
343
+
344
+ context "when chef_server_url matches '../organizations/*' with a trailing slash" do
345
+ before do
346
+ ChefConfig::Config[:chef_server_url] = "https://example.com/organizations/myorg/"
347
+ end
348
+ it "returns the full URL without /organizations/*" do
349
+ expect(ChefConfig::Config[:chef_server_root]).to eq("https://example.com")
350
+ end
351
+ end
352
+
353
+ context "when chef_server_url matches '..organizations..' but not '../organizations/*'" do
354
+ before do
355
+ ChefConfig::Config[:chef_server_url] = "https://organizations.com/organizations"
356
+ end
357
+ it "returns the full URL without any modifications" do
358
+ expect(ChefConfig::Config[:chef_server_root]).to eq(ChefConfig::Config[:chef_server_url])
359
+ end
360
+ end
361
+
362
+ context "when chef_server_url is a standard URL without the string organization(s)" do
363
+ before do
364
+ ChefConfig::Config[:chef_server_url] = "https://example.com/some_other_string"
365
+ end
366
+ it "returns the full URL without any modifications" do
367
+ expect(ChefConfig::Config[:chef_server_root]).to eq(ChefConfig::Config[:chef_server_url])
368
+ end
369
+ end
370
+ end
371
+
372
+ describe "ChefConfig::Config[:cache_path]" do
373
+ before do
374
+ if is_windows
375
+ allow(File).to receive(:expand_path).and_return("#{ChefConfig::Config.env["SYSTEMDRIVE"]}/Path/To/Executable")
376
+ end
377
+ end
378
+ context "when /var/chef exists and is accessible" do
379
+ it "defaults to /var/chef" do
380
+ allow(ChefConfig::Config).to receive(:path_accessible?).with(to_platform("/var/chef")).and_return(true)
381
+ expect(ChefConfig::Config[:cache_path]).to eq(primary_cache_path)
382
+ end
383
+ end
384
+
385
+ context "when /var/chef does not exist and /var is accessible" do
386
+ it "defaults to /var/chef" do
387
+ allow(File).to receive(:exists?).with(to_platform("/var/chef")).and_return(false)
388
+ allow(ChefConfig::Config).to receive(:path_accessible?).with(to_platform("/var")).and_return(true)
389
+ expect(ChefConfig::Config[:cache_path]).to eq(primary_cache_path)
390
+ end
391
+ end
392
+
393
+ context "when /var/chef does not exist and /var is not accessible" do
394
+ it "defaults to $HOME/.chef" do
395
+ allow(File).to receive(:exists?).with(to_platform("/var/chef")).and_return(false)
396
+ allow(ChefConfig::Config).to receive(:path_accessible?).with(to_platform("/var")).and_return(false)
397
+ expect(ChefConfig::Config[:cache_path]).to eq(secondary_cache_path)
398
+ end
399
+ end
400
+
401
+ context "when /var/chef exists and is not accessible" do
402
+ it "defaults to $HOME/.chef" do
403
+ allow(File).to receive(:exists?).with(to_platform("/var/chef")).and_return(true)
404
+ allow(File).to receive(:readable?).with(to_platform("/var/chef")).and_return(true)
405
+ allow(File).to receive(:writable?).with(to_platform("/var/chef")).and_return(false)
406
+
407
+ expect(ChefConfig::Config[:cache_path]).to eq(secondary_cache_path)
408
+ end
409
+ end
410
+
411
+ context "when chef is running in local mode" do
412
+ before do
413
+ ChefConfig::Config.local_mode = true
414
+ end
415
+
416
+ context "and config_dir is /a/b/c" do
417
+ before do
418
+ ChefConfig::Config.config_dir to_platform("/a/b/c")
419
+ end
420
+
421
+ it "cache_path is /a/b/c/local-mode-cache" do
422
+ expect(ChefConfig::Config.cache_path).to eq(to_platform("/a/b/c/local-mode-cache"))
423
+ end
424
+ end
425
+
426
+ context "and config_dir is /a/b/c/" do
427
+ before do
428
+ ChefConfig::Config.config_dir to_platform("/a/b/c/")
429
+ end
430
+
431
+ it "cache_path is /a/b/c/local-mode-cache" do
432
+ expect(ChefConfig::Config.cache_path).to eq(to_platform("/a/b/c/local-mode-cache"))
433
+ end
434
+ end
435
+ end
436
+ end
437
+
438
+ it "ChefConfig::Config[:stream_execute_output] defaults to false" do
439
+ expect(ChefConfig::Config[:stream_execute_output]).to eq(false)
440
+ end
441
+
442
+ it "ChefConfig::Config[:show_download_progress] defaults to false" do
443
+ expect(ChefConfig::Config[:show_download_progress]).to eq(false)
444
+ end
445
+
446
+ it "ChefConfig::Config[:download_progress_interval] defaults to every 10%" do
447
+ expect(ChefConfig::Config[:download_progress_interval]).to eq(10)
448
+ end
449
+
450
+ it "ChefConfig::Config[:file_backup_path] defaults to /var/chef/backup" do
451
+ allow(ChefConfig::Config).to receive(:cache_path).and_return(primary_cache_path)
452
+ backup_path = is_windows ? "#{primary_cache_path}\\backup" : "#{primary_cache_path}/backup"
453
+ expect(ChefConfig::Config[:file_backup_path]).to eq(backup_path)
454
+ end
455
+
456
+ it "ChefConfig::Config[:ssl_verify_mode] defaults to :verify_peer" do
457
+ expect(ChefConfig::Config[:ssl_verify_mode]).to eq(:verify_peer)
458
+ end
459
+
460
+ it "ChefConfig::Config[:ssl_ca_path] defaults to nil" do
461
+ expect(ChefConfig::Config[:ssl_ca_path]).to be_nil
462
+ end
463
+
464
+ describe "ChefConfig::Config[:repo_mode]" do
465
+
466
+ context "when local mode is enabled" do
467
+
468
+ before { ChefConfig::Config[:local_mode] = true }
469
+
470
+ it "defaults to 'hosted_everything'" do
471
+ expect(ChefConfig::Config[:repo_mode]).to eq("hosted_everything")
472
+ end
473
+
474
+ context "and osc_compat is enabled" do
475
+
476
+ before { ChefConfig::Config.chef_zero.osc_compat = true }
477
+
478
+ it "defaults to 'everything'" do
479
+ expect(ChefConfig::Config[:repo_mode]).to eq("everything")
480
+ end
481
+ end
482
+ end
483
+
484
+ context "when local mode is not enabled" do
485
+
486
+ context "and the chef_server_url is multi-tenant" do
487
+
488
+ before { ChefConfig::Config[:chef_server_url] = "https://chef.example/organizations/example" }
489
+
490
+ it "defaults to 'hosted_everything'" do
491
+ expect(ChefConfig::Config[:repo_mode]).to eq("hosted_everything")
492
+ end
493
+
494
+ end
495
+
496
+ context "and the chef_server_url is not multi-tenant" do
497
+
498
+ before { ChefConfig::Config[:chef_server_url] = "https://chef.example/" }
499
+
500
+ it "defaults to 'everything'" do
501
+ expect(ChefConfig::Config[:repo_mode]).to eq("everything")
502
+ end
503
+ end
504
+ end
505
+ end
506
+
507
+ describe "ChefConfig::Config[:chef_repo_path]" do
508
+
509
+ context "when cookbook_path is set to a single path" do
510
+
511
+ before { ChefConfig::Config[:cookbook_path] = "/home/anne/repo/cookbooks" }
512
+
513
+ it "is set to a path one directory up from the cookbook_path" do
514
+ expected = File.expand_path("/home/anne/repo")
515
+ expect(ChefConfig::Config[:chef_repo_path]).to eq(expected)
516
+ end
517
+
518
+ end
519
+
520
+ context "when cookbook_path is set to multiple paths" do
521
+
522
+ before do
523
+ ChefConfig::Config[:cookbook_path] = [
524
+ "/home/anne/repo/cookbooks",
525
+ "/home/anne/other_repo/cookbooks",
526
+ ]
527
+ end
528
+
529
+ it "is set to an Array of paths one directory up from the cookbook_paths" do
530
+ expected = [ "/home/anne/repo", "/home/anne/other_repo"].map { |p| File.expand_path(p) }
531
+ expect(ChefConfig::Config[:chef_repo_path]).to eq(expected)
532
+ end
533
+
534
+ end
535
+
536
+ context "when cookbook_path is not set but cookbook_artifact_path is set" do
537
+
538
+ before do
539
+ ChefConfig::Config[:cookbook_path] = nil
540
+ ChefConfig::Config[:cookbook_artifact_path] = "/home/roxie/repo/cookbook_artifacts"
541
+ end
542
+
543
+ it "is set to a path one directory up from the cookbook_artifact_path" do
544
+ expected = File.expand_path("/home/roxie/repo")
545
+ expect(ChefConfig::Config[:chef_repo_path]).to eq(expected)
546
+ end
547
+
548
+ end
549
+
550
+ context "when cookbook_path is not set" do
551
+
552
+ before { ChefConfig::Config[:cookbook_path] = nil }
553
+
554
+ it "is set to the cache_path" do
555
+ expect(ChefConfig::Config[:chef_repo_path]).to eq(ChefConfig::Config[:cache_path])
556
+ end
557
+
558
+ end
559
+
560
+ end
561
+
562
+ # On Windows, we'll detect an omnibus build and set this to the
563
+ # cacert.pem included in the package, but it's nil if you're on Windows
564
+ # w/o omnibus (e.g., doing development on Windows, custom build, etc.)
565
+ if !is_windows
566
+ it "ChefConfig::Config[:ssl_ca_file] defaults to nil" do
567
+ expect(ChefConfig::Config[:ssl_ca_file]).to be_nil
568
+ end
569
+ end
570
+
571
+ it "ChefConfig::Config[:data_bag_path] defaults to /var/chef/data_bags" do
572
+ allow(ChefConfig::Config).to receive(:cache_path).and_return(primary_cache_path)
573
+ data_bag_path = is_windows ? "#{primary_cache_path}\\data_bags" : "#{primary_cache_path}/data_bags"
574
+ expect(ChefConfig::Config[:data_bag_path]).to eq(data_bag_path)
575
+ end
576
+
577
+ it "ChefConfig::Config[:environment_path] defaults to /var/chef/environments" do
578
+ allow(ChefConfig::Config).to receive(:cache_path).and_return(primary_cache_path)
579
+ environment_path = is_windows ? "#{primary_cache_path}\\environments" : "#{primary_cache_path}/environments"
580
+ expect(ChefConfig::Config[:environment_path]).to eq(environment_path)
581
+ end
582
+
583
+ it "ChefConfig::Config[:cookbook_artifact_path] defaults to /var/chef/cookbook_artifacts" do
584
+ allow(ChefConfig::Config).to receive(:cache_path).and_return(primary_cache_path)
585
+ environment_path = is_windows ? "#{primary_cache_path}\\cookbook_artifacts" : "#{primary_cache_path}/cookbook_artifacts"
586
+ expect(ChefConfig::Config[:cookbook_artifact_path]).to eq(environment_path)
587
+ end
588
+
589
+ describe "setting the config dir" do
590
+
591
+ context "when the config file is given with a relative path" do
592
+
593
+ before do
594
+ ChefConfig::Config.config_file = "client.rb"
595
+ end
596
+
597
+ it "expands the path when determining config_dir" do
598
+ # config_dir goes through PathHelper.canonical_path, which
599
+ # downcases on windows because the FS is case insensitive, so we
600
+ # have to downcase expected and actual to make the tests work.
601
+ expect(ChefConfig::Config.config_dir.downcase).to eq(to_platform(Dir.pwd).downcase)
602
+ end
603
+
604
+ it "does not set derived paths at FS root" do
605
+ ChefConfig::Config.local_mode = true
606
+ expect(ChefConfig::Config.cache_path.downcase).to eq(to_platform(File.join(Dir.pwd, "local-mode-cache")).downcase)
607
+ end
608
+
609
+ end
610
+
611
+ context "when the config file is /etc/chef/client.rb" do
612
+
613
+ before do
614
+ config_location = to_platform("/etc/chef/client.rb").downcase
615
+ allow(File).to receive(:absolute_path).with(config_location).and_return(config_location)
616
+ ChefConfig::Config.config_file = config_location
617
+ end
618
+
619
+ it "config_dir is /etc/chef" do
620
+ expect(ChefConfig::Config.config_dir).to eq(to_platform("/etc/chef").downcase)
621
+ end
622
+
623
+ context "and chef is running in local mode" do
624
+ before do
625
+ ChefConfig::Config.local_mode = true
626
+ end
627
+
628
+ it "config_dir is /etc/chef" do
629
+ expect(ChefConfig::Config.config_dir).to eq(to_platform("/etc/chef").downcase)
630
+ end
631
+ end
632
+
633
+ context "when config_dir is set to /other/config/dir/" do
634
+ before do
635
+ ChefConfig::Config.config_dir = to_platform("/other/config/dir/")
636
+ end
637
+
638
+ it "yields the explicit value" do
639
+ expect(ChefConfig::Config.config_dir).to eq(to_platform("/other/config/dir/"))
640
+ end
641
+ end
642
+
643
+ end
644
+
645
+ context "when the user's home dir is /home/charlie/" do
646
+ before do
647
+ ChefConfig::Config.user_home = "/home/charlie/"
648
+ end
649
+
650
+ it "config_dir is /home/charlie/.chef/" do
651
+ expect(ChefConfig::Config.config_dir).to eq(ChefConfig::PathHelper.join(ChefConfig::PathHelper.cleanpath("/home/charlie/"), ".chef", ""))
652
+ end
653
+
654
+ context "and chef is running in local mode" do
655
+ before do
656
+ ChefConfig::Config.local_mode = true
657
+ end
658
+
659
+ it "config_dir is /home/charlie/.chef/" do
660
+ expect(ChefConfig::Config.config_dir).to eq(ChefConfig::PathHelper.join(ChefConfig::PathHelper.cleanpath("/home/charlie/"), ".chef", ""))
661
+ end
662
+ end
663
+ end
664
+
665
+ if is_windows
666
+ context "when the user's home dir is windows specific" do
667
+ before do
668
+ ChefConfig::Config.user_home = to_platform("/home/charlie/")
669
+ end
670
+
671
+ it "config_dir is with backslashes" do
672
+ expect(ChefConfig::Config.config_dir).to eq(ChefConfig::PathHelper.join(ChefConfig::PathHelper.cleanpath("/home/charlie/"), ".chef", ""))
673
+ end
674
+
675
+ context "and chef is running in local mode" do
676
+ before do
677
+ ChefConfig::Config.local_mode = true
678
+ end
679
+
680
+ it "config_dir is with backslashes" do
681
+ expect(ChefConfig::Config.config_dir).to eq(ChefConfig::PathHelper.join(ChefConfig::PathHelper.cleanpath("/home/charlie/"), ".chef", ""))
682
+ end
683
+ end
684
+ end
685
+
686
+ end
687
+
688
+ end
689
+
690
+ if is_windows
691
+ describe "finding the windows embedded dir" do
692
+ let(:default_config_location) { "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.0/lib/chef/config.rb" }
693
+ 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" }
694
+ let(:non_omnibus_location) { "c:/my/dev/stuff/lib/ruby/gems/1.9.1/gems/chef-11.6.0/lib/chef/config.rb" }
695
+
696
+ let(:default_ca_file) { "c:/opscode/chef/embedded/ssl/certs/cacert.pem" }
697
+
698
+ it "finds the embedded dir in the default location" do
699
+ allow(ChefConfig::Config).to receive(:_this_file).and_return(default_config_location)
700
+ expect(ChefConfig::Config.embedded_dir).to eq("c:/opscode/chef/embedded")
701
+ end
702
+
703
+ it "finds the embedded dir in a custom install location" do
704
+ allow(ChefConfig::Config).to receive(:_this_file).and_return(alternate_install_location)
705
+ expect(ChefConfig::Config.embedded_dir).to eq("c:/my/alternate/install/place/chef/embedded")
706
+ end
707
+
708
+ it "doesn't error when not in an omnibus install" do
709
+ allow(ChefConfig::Config).to receive(:_this_file).and_return(non_omnibus_location)
710
+ expect(ChefConfig::Config.embedded_dir).to be_nil
711
+ end
712
+
713
+ it "sets the ssl_ca_cert path if the cert file is available" do
714
+ allow(ChefConfig::Config).to receive(:_this_file).and_return(default_config_location)
715
+ allow(File).to receive(:exist?).with(default_ca_file).and_return(true)
716
+ expect(ChefConfig::Config.ssl_ca_file).to eq(default_ca_file)
717
+ end
718
+ end
719
+ end
720
+ end
721
+
722
+ describe "ChefConfig::Config[:user_home]" do
723
+ it "should set when HOME is provided" do
724
+ expected = to_platform("/home/kitten")
725
+ allow(ChefConfig::PathHelper).to receive(:home).and_return(expected)
726
+ expect(ChefConfig::Config[:user_home]).to eq(expected)
727
+ end
728
+
729
+ it "falls back to the current working directory when HOME and USERPROFILE is not set" do
730
+ allow(ChefConfig::PathHelper).to receive(:home).and_return(nil)
731
+ expect(ChefConfig::Config[:user_home]).to eq(Dir.pwd)
732
+ end
733
+ end
734
+
735
+ describe "ChefConfig::Config[:encrypted_data_bag_secret]" do
736
+ let(:db_secret_default_path) { to_platform("/etc/chef/encrypted_data_bag_secret") }
737
+
738
+ before do
739
+ allow(File).to receive(:exist?).with(db_secret_default_path).and_return(secret_exists)
740
+ end
741
+
742
+ context "/etc/chef/encrypted_data_bag_secret exists" do
743
+ let(:secret_exists) { true }
744
+ it "sets the value to /etc/chef/encrypted_data_bag_secret" do
745
+ expect(ChefConfig::Config[:encrypted_data_bag_secret]).to eq db_secret_default_path
746
+ end
747
+ end
748
+
749
+ context "/etc/chef/encrypted_data_bag_secret does not exist" do
750
+ let(:secret_exists) { false }
751
+ it "sets the value to nil" do
752
+ expect(ChefConfig::Config[:encrypted_data_bag_secret]).to be_nil
753
+ end
754
+ end
755
+ end
756
+
757
+ describe "ChefConfig::Config[:event_handlers]" do
758
+ it "sets a event_handlers to an empty array by default" do
759
+ expect(ChefConfig::Config[:event_handlers]).to eq([])
760
+ end
761
+ it "should be able to add custom handlers" do
762
+ o = Object.new
763
+ ChefConfig::Config[:event_handlers] << o
764
+ expect(ChefConfig::Config[:event_handlers]).to be_include(o)
765
+ end
766
+ end
767
+
768
+ describe "ChefConfig::Config[:user_valid_regex]" do
769
+ context "on a platform that is not Windows" do
770
+ it "allows one letter usernames" do
771
+ any_match = ChefConfig::Config[:user_valid_regex].any? { |regex| regex.match("a") }
772
+ expect(any_match).to be_truthy
773
+ end
774
+ end
775
+ end
776
+
777
+ describe "ChefConfig::Config[:internal_locale]" do
778
+ let(:shell_out) do
779
+ cmd = instance_double("Mixlib::ShellOut", exitstatus: 0, stdout: locales, error!: nil)
780
+ allow(cmd).to receive(:run_command).and_return(cmd)
781
+ cmd
782
+ end
783
+
784
+ let(:locales) { locale_array.join("\n") }
785
+
786
+ before do
787
+ allow(Mixlib::ShellOut).to receive(:new).with("locale -a").and_return(shell_out)
788
+ end
789
+
790
+ shared_examples_for "a suitable locale" do
791
+ it "returns an English UTF-8 locale" do
792
+ expect(ChefConfig.logger).to_not receive(:warn).with(/Please install an English UTF-8 locale for Chef to use/)
793
+ expect(ChefConfig.logger).to_not receive(:trace).with(/Defaulting to locale en_US.UTF-8 on Windows/)
794
+ expect(ChefConfig.logger).to_not receive(:trace).with(/No usable locale -a command found/)
795
+ expect(ChefConfig::Config.guess_internal_locale).to eq expected_locale
796
+ end
797
+ end
798
+
799
+ context "when the result includes 'C.UTF-8'" do
800
+ include_examples "a suitable locale" do
801
+ let(:locale_array) { [expected_locale, "en_US.UTF-8"] }
802
+ let(:expected_locale) { "C.UTF-8" }
803
+ end
804
+ end
805
+
806
+ context "when the result includes 'en_US.UTF-8'" do
807
+ include_examples "a suitable locale" do
808
+ let(:locale_array) { ["en_CA.UTF-8", expected_locale, "en_NZ.UTF-8"] }
809
+ let(:expected_locale) { "en_US.UTF-8" }
810
+ end
811
+ end
812
+
813
+ context "when the result includes 'en_US.utf8'" do
814
+ include_examples "a suitable locale" do
815
+ let(:locale_array) { ["en_CA.utf8", "en_US.utf8", "en_NZ.utf8"] }
816
+ let(:expected_locale) { "en_US.UTF-8" }
817
+ end
818
+ end
819
+
820
+ context "when the result includes 'en.UTF-8'" do
821
+ include_examples "a suitable locale" do
822
+ let(:locale_array) { ["en.ISO8859-1", expected_locale] }
823
+ let(:expected_locale) { "en.UTF-8" }
824
+ end
825
+ end
826
+
827
+ context "when the result includes 'en_*.UTF-8'" do
828
+ include_examples "a suitable locale" do
829
+ let(:locale_array) { [expected_locale, "en_CA.UTF-8", "en_GB.UTF-8"] }
830
+ let(:expected_locale) { "en_AU.UTF-8" }
831
+ end
832
+ end
833
+
834
+ context "when the result includes 'en_*.utf8'" do
835
+ include_examples "a suitable locale" do
836
+ let(:locale_array) { ["en_AU.utf8", "en_CA.utf8", "en_GB.utf8"] }
837
+ let(:expected_locale) { "en_AU.UTF-8" }
838
+ end
839
+ end
840
+
841
+ context "when the result does not include 'en_*.UTF-8'" do
842
+ let(:locale_array) { ["af_ZA", "af_ZA.ISO8859-1", "af_ZA.ISO8859-15", "af_ZA.UTF-8"] }
843
+
844
+ it "should fall back to C locale" do
845
+ 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.")
846
+ expect(ChefConfig::Config.guess_internal_locale).to eq "C"
847
+ end
848
+ end
849
+
850
+ context "on error" do
851
+ let(:locale_array) { [] }
852
+
853
+ let(:shell_out_cmd) { instance_double("Mixlib::ShellOut") }
854
+
855
+ before do
856
+ allow(Mixlib::ShellOut).to receive(:new).and_return(shell_out_cmd)
857
+ allow(shell_out_cmd).to receive(:run_command)
858
+ allow(shell_out_cmd).to receive(:error!).and_raise(Mixlib::ShellOut::ShellCommandFailed, "this is an error")
859
+ end
860
+
861
+ it "should default to 'en_US.UTF-8'" do
862
+ if is_windows
863
+ expect(ChefConfig.logger).to receive(:trace).with("Defaulting to locale en_US.UTF-8 on Windows, until it matters that we do something else.")
864
+ else
865
+ expect(ChefConfig.logger).to receive(:trace).with("No usable locale -a command found, assuming you have en_US.UTF-8 installed.")
866
+ end
867
+ expect(ChefConfig::Config.guess_internal_locale).to eq "en_US.UTF-8"
868
+ end
869
+ end
870
+ end
871
+ end
872
+ end
873
+
874
+ describe "export_proxies" do
875
+ before(:all) do
876
+ @original_env = ENV.to_hash
877
+ ENV["http_proxy"] = nil
878
+ ENV["HTTP_PROXY"] = nil
879
+ ENV["https_proxy"] = nil
880
+ ENV["HTTPS_PROXY"] = nil
881
+ ENV["ftp_proxy"] = nil
882
+ ENV["FTP_PROXY"] = nil
883
+ ENV["no_proxy"] = nil
884
+ ENV["NO_PROXY"] = nil
885
+ end
886
+
887
+ after(:all) do
888
+ ENV.clear
889
+ ENV.update(@original_env)
890
+ end
891
+
892
+ let(:http_proxy) { "http://localhost:7979" }
893
+ let(:https_proxy) { "https://localhost:7979" }
894
+ let(:ftp_proxy) { "ftp://localhost:7979" }
895
+ let(:proxy_user) { "http_user" }
896
+ let(:proxy_pass) { "http_pass" }
897
+
898
+ context "when http_proxy, proxy_pass and proxy_user are set" do
899
+ before do
900
+ ChefConfig::Config.http_proxy = http_proxy
901
+ ChefConfig::Config.http_proxy_user = proxy_user
902
+ ChefConfig::Config.http_proxy_pass = proxy_pass
903
+ end
904
+ it "exports ENV['http_proxy']" do
905
+ expect(ENV).to receive(:[]=).with("http_proxy", "http://http_user:http_pass@localhost:7979")
906
+ expect(ENV).to receive(:[]=).with("HTTP_PROXY", "http://http_user:http_pass@localhost:7979")
907
+ ChefConfig::Config.export_proxies
908
+ end
909
+ end
910
+
911
+ context "when https_proxy, proxy_pass and proxy_user are set" do
912
+ before do
913
+ ChefConfig::Config.https_proxy = https_proxy
914
+ ChefConfig::Config.https_proxy_user = proxy_user
915
+ ChefConfig::Config.https_proxy_pass = proxy_pass
916
+ end
917
+ it "exports ENV['https_proxy']" do
918
+ expect(ENV).to receive(:[]=).with("https_proxy", "https://http_user:http_pass@localhost:7979")
919
+ expect(ENV).to receive(:[]=).with("HTTPS_PROXY", "https://http_user:http_pass@localhost:7979")
920
+ ChefConfig::Config.export_proxies
921
+ end
922
+ end
923
+
924
+ context "when ftp_proxy, proxy_pass and proxy_user are set" do
925
+ before do
926
+ ChefConfig::Config.ftp_proxy = ftp_proxy
927
+ ChefConfig::Config.ftp_proxy_user = proxy_user
928
+ ChefConfig::Config.ftp_proxy_pass = proxy_pass
929
+ end
930
+ it "exports ENV['ftp_proxy']" do
931
+ expect(ENV).to receive(:[]=).with("ftp_proxy", "ftp://http_user:http_pass@localhost:7979")
932
+ expect(ENV).to receive(:[]=).with("FTP_PROXY", "ftp://http_user:http_pass@localhost:7979")
933
+ ChefConfig::Config.export_proxies
934
+ end
935
+ end
936
+
937
+ shared_examples "no user pass" do
938
+ it "does not populate the user or password" do
939
+ expect(ENV).to receive(:[]=).with("http_proxy", "http://localhost:7979")
940
+ expect(ENV).to receive(:[]=).with("HTTP_PROXY", "http://localhost:7979")
941
+ ChefConfig::Config.export_proxies
942
+ end
943
+ end
944
+
945
+ context "when proxy_pass and proxy_user are passed as empty strings" do
946
+ before do
947
+ ChefConfig::Config.http_proxy = http_proxy
948
+ ChefConfig::Config.http_proxy_user = ""
949
+ ChefConfig::Config.http_proxy_pass = proxy_pass
950
+ end
951
+ include_examples "no user pass"
952
+ end
953
+
954
+ context "when proxy_pass and proxy_user are not provided" do
955
+ before do
956
+ ChefConfig::Config.http_proxy = http_proxy
957
+ end
958
+ include_examples "no user pass"
959
+ end
960
+
961
+ context "when the proxy is provided without a scheme" do
962
+ before do
963
+ ChefConfig::Config.http_proxy = "localhost:1111"
964
+ end
965
+ it "automatically adds the scheme to the proxy url" do
966
+ expect(ENV).to receive(:[]=).with("http_proxy", "http://localhost:1111")
967
+ expect(ENV).to receive(:[]=).with("HTTP_PROXY", "http://localhost:1111")
968
+ ChefConfig::Config.export_proxies
969
+ end
970
+ end
971
+
972
+ shared_examples "no export" do
973
+ it "does not export any proxy settings" do
974
+ ChefConfig::Config.export_proxies
975
+ expect(ENV["http_proxy"]).to eq(nil)
976
+ expect(ENV["https_proxy"]).to eq(nil)
977
+ expect(ENV["ftp_proxy"]).to eq(nil)
978
+ expect(ENV["no_proxy"]).to eq(nil)
979
+ end
980
+ end
981
+
982
+ context "when nothing is set" do
983
+ include_examples "no export"
984
+ end
985
+
986
+ context "when all the users and passwords are set but no proxies are set" do
987
+ before do
988
+ ChefConfig::Config.http_proxy_user = proxy_user
989
+ ChefConfig::Config.http_proxy_pass = proxy_pass
990
+ ChefConfig::Config.https_proxy_user = proxy_user
991
+ ChefConfig::Config.https_proxy_pass = proxy_pass
992
+ ChefConfig::Config.ftp_proxy_user = proxy_user
993
+ ChefConfig::Config.ftp_proxy_pass = proxy_pass
994
+ end
995
+ include_examples "no export"
996
+ end
997
+
998
+ context "no_proxy is set" do
999
+ before do
1000
+ ChefConfig::Config.no_proxy = "localhost"
1001
+ end
1002
+ it "exports ENV['no_proxy']" do
1003
+ expect(ENV).to receive(:[]=).with("no_proxy", "localhost")
1004
+ expect(ENV).to receive(:[]=).with("NO_PROXY", "localhost")
1005
+ ChefConfig::Config.export_proxies
1006
+ end
1007
+ end
1008
+ end
1009
+
1010
+ describe "proxy_uri" do
1011
+ subject(:proxy_uri) { described_class.proxy_uri(scheme, host, port) }
1012
+ let(:env) { {} }
1013
+ let(:scheme) { "http" }
1014
+ let(:host) { "test.example.com" }
1015
+ let(:port) { 8080 }
1016
+ let(:proxy) { "#{proxy_prefix}#{proxy_host}:#{proxy_port}" }
1017
+ let(:proxy_prefix) { "http://" }
1018
+ let(:proxy_host) { "proxy.mycorp.com" }
1019
+ let(:proxy_port) { 8080 }
1020
+
1021
+ before do
1022
+ stub_const("ENV", env)
1023
+ end
1024
+
1025
+ shared_examples_for "a proxy uri" do
1026
+ it "contains the host" do
1027
+ expect(proxy_uri.host).to eq(proxy_host)
1028
+ end
1029
+
1030
+ it "contains the port" do
1031
+ expect(proxy_uri.port).to eq(proxy_port)
1032
+ end
1033
+ end
1034
+
1035
+ context "when the config setting is normalized (does not contain the scheme)" do
1036
+ include_examples "a proxy uri" do
1037
+
1038
+ let(:proxy_prefix) { "" }
1039
+
1040
+ let(:env) do
1041
+ {
1042
+ "#{scheme}_proxy" => proxy,
1043
+ "no_proxy" => nil,
1044
+ }
1045
+ end
1046
+ end
1047
+ end
1048
+
1049
+ context "when the proxy is set by the environment" do
1050
+ include_examples "a proxy uri" do
1051
+ let(:scheme) { "https" }
1052
+ let(:env) do
1053
+ {
1054
+ "https_proxy" => "https://jane_username:opensesame@proxy.mycorp.com:8080",
1055
+ }
1056
+ end
1057
+ end
1058
+ end
1059
+
1060
+ context "when an empty proxy is set by the environment" do
1061
+ let(:env) do
1062
+ {
1063
+ "https_proxy" => "",
1064
+ }
1065
+ end
1066
+
1067
+ it "does not fail with URI parse exception" do
1068
+ expect { proxy_uri }.to_not raise_error
1069
+ end
1070
+ end
1071
+
1072
+ context "when no_proxy is set" do
1073
+ context "when no_proxy is the exact host" do
1074
+ let(:env) do
1075
+ {
1076
+ "http_proxy" => proxy,
1077
+ "no_proxy" => host,
1078
+ }
1079
+ end
1080
+
1081
+ it { is_expected.to eq nil }
1082
+ end
1083
+
1084
+ context "when no_proxy includes the same domain with a wildcard" do
1085
+ let(:env) do
1086
+ {
1087
+ "http_proxy" => proxy,
1088
+ "no_proxy" => "*.example.com",
1089
+ }
1090
+ end
1091
+
1092
+ it { is_expected.to eq nil }
1093
+ end
1094
+
1095
+ context "when no_proxy is included on a list" do
1096
+ let(:env) do
1097
+ {
1098
+ "http_proxy" => proxy,
1099
+ "no_proxy" => "chef.io,getchef.com,opscode.com,test.example.com",
1100
+ }
1101
+ end
1102
+
1103
+ it { is_expected.to eq nil }
1104
+ end
1105
+
1106
+ context "when no_proxy is included on a list with wildcards" do
1107
+ let(:env) do
1108
+ {
1109
+ "http_proxy" => proxy,
1110
+ "no_proxy" => "10.*,*.example.com",
1111
+ }
1112
+ end
1113
+
1114
+ it { is_expected.to eq nil }
1115
+ end
1116
+
1117
+ context "when no_proxy is a domain with a dot prefix" do
1118
+ let(:env) do
1119
+ {
1120
+ "http_proxy" => proxy,
1121
+ "no_proxy" => ".example.com",
1122
+ }
1123
+ end
1124
+
1125
+ it { is_expected.to eq nil }
1126
+ end
1127
+
1128
+ context "when no_proxy is a domain with no wildcard" do
1129
+ let(:env) do
1130
+ {
1131
+ "http_proxy" => proxy,
1132
+ "no_proxy" => "example.com",
1133
+ }
1134
+ end
1135
+
1136
+ it { is_expected.to eq nil }
1137
+ end
1138
+ end
1139
+ end
1140
+
1141
+ describe "allowing chefdk configuration outside of chefdk" do
1142
+
1143
+ it "allows arbitrary settings in the chefdk config context" do
1144
+ expect { ChefConfig::Config.chefdk.generator_cookbook("/path") }.to_not raise_error
1145
+ end
1146
+
1147
+ end
1148
+
1149
+ describe "Treating deprecation warnings as errors" do
1150
+
1151
+ context "when using our default RSpec configuration" do
1152
+
1153
+ it "defaults to treating deprecation warnings as errors" do
1154
+ expect(ChefConfig::Config[:treat_deprecation_warnings_as_errors]).to be(true)
1155
+ end
1156
+
1157
+ it "sets CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS environment variable" do
1158
+ expect(ENV["CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS"]).to eq("1")
1159
+ end
1160
+
1161
+ it "treats deprecation warnings as errors in child processes when testing" do
1162
+ # Doing a full integration test where we launch a child process is slow
1163
+ # and liable to break for weird reasons (bundler env stuff, etc.), so
1164
+ # we're just checking that the presence of the environment variable
1165
+ # causes treat_deprecation_warnings_as_errors to be set to true after a
1166
+ # config reset.
1167
+ ChefConfig::Config.reset
1168
+ expect(ChefConfig::Config[:treat_deprecation_warnings_as_errors]).to be(true)
1169
+ end
1170
+
1171
+ end
1172
+
1173
+ context "outside of our test environment" do
1174
+
1175
+ before do
1176
+ ENV.delete("CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS")
1177
+ ChefConfig::Config.reset
1178
+ end
1179
+
1180
+ it "defaults to NOT treating deprecation warnings as errors" do
1181
+ expect(ChefConfig::Config[:treat_deprecation_warnings_as_errors]).to be(false)
1182
+ end
1183
+ end
1184
+
1185
+ end
1186
+
1187
+ describe "data collector URL" do
1188
+
1189
+ context "when using default settings" do
1190
+
1191
+ context "for Chef Client" do
1192
+
1193
+ it "configures the data collector URL as a relative path to the Chef Server URL" do
1194
+ ChefConfig::Config[:chef_server_url] = "https://chef.example/organizations/myorg"
1195
+ expect(ChefConfig::Config[:data_collector][:server_url]).to eq("https://chef.example/organizations/myorg/data-collector")
1196
+ end
1197
+
1198
+ end
1199
+
1200
+ context "for Chef Solo" do
1201
+
1202
+ before do
1203
+ ChefConfig::Config[:solo] = true
1204
+ end
1205
+
1206
+ it "sets the data collector server URL to nil" do
1207
+ ChefConfig::Config[:chef_server_url] = "https://chef.example/organizations/myorg"
1208
+ expect(ChefConfig::Config[:data_collector][:server_url]).to be_nil
1209
+ end
1210
+
1211
+ end
1212
+
1213
+ end
1214
+
1215
+ end
1216
+
1217
+ describe "validation_client_name" do
1218
+ context "with a normal server URL" do
1219
+ before { ChefConfig::Config[:chef_server_url] = "https://chef.example/organizations/myorg" }
1220
+
1221
+ it "sets the validation client to myorg-validator" do
1222
+ expect(ChefConfig::Config[:validation_client_name]).to eq "myorg-validator"
1223
+ end
1224
+ end
1225
+
1226
+ context "with an unusual server URL" do
1227
+ before { ChefConfig::Config[:chef_server_url] = "https://chef.example/myorg" }
1228
+
1229
+ it "sets the validation client to chef-validator" do
1230
+ expect(ChefConfig::Config[:validation_client_name]).to eq "chef-validator"
1231
+ end
1232
+ end
1233
+ end
1234
+
1235
+ end