chef 11.14.2-x86-mingw32 → 11.14.6-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/lib/chef/application.rb +16 -8
  3. data/lib/chef/dsl/recipe.rb +14 -0
  4. data/lib/chef/exceptions.rb +1 -0
  5. data/lib/chef/provider/env/windows.rb +5 -9
  6. data/lib/chef/provider/group/dscl.rb +27 -9
  7. data/lib/chef/provider/package/rpm.rb +2 -2
  8. data/lib/chef/provider/user/dscl.rb +544 -157
  9. data/lib/chef/resource.rb +3 -0
  10. data/lib/chef/resource/freebsd_package.rb +10 -2
  11. data/lib/chef/resource/user.rb +18 -0
  12. data/lib/chef/resource_reporter.rb +7 -7
  13. data/lib/chef/role.rb +2 -2
  14. data/lib/chef/version.rb +1 -1
  15. data/spec/data/mac_users/10.7-8.plist.xml +559 -0
  16. data/spec/data/mac_users/10.7-8.shadow.xml +11 -0
  17. data/spec/data/mac_users/10.7.plist.xml +559 -0
  18. data/spec/data/mac_users/10.7.shadow.xml +11 -0
  19. data/spec/data/mac_users/10.8.plist.xml +559 -0
  20. data/spec/data/mac_users/10.8.shadow.xml +21 -0
  21. data/spec/data/mac_users/10.9.plist.xml +560 -0
  22. data/spec/data/mac_users/10.9.shadow.xml +21 -0
  23. data/spec/functional/resource/env_spec.rb +137 -0
  24. data/spec/functional/resource/user/dscl_spec.rb +198 -0
  25. data/spec/functional/resource/{user_spec.rb → user/useradd_spec.rb} +1 -1
  26. data/spec/support/lib/chef/resource/zen_follower.rb +46 -0
  27. data/spec/unit/application_spec.rb +32 -9
  28. data/spec/unit/provider/group/dscl_spec.rb +38 -1
  29. data/spec/unit/provider/package/rpm_spec.rb +12 -0
  30. data/spec/unit/provider/user/dscl_spec.rb +659 -264
  31. data/spec/unit/provider/user/useradd_spec.rb +1 -0
  32. data/spec/unit/recipe_spec.rb +41 -0
  33. data/spec/unit/resource_reporter_spec.rb +48 -0
  34. data/spec/unit/resource_spec.rb +9 -2
  35. data/spec/unit/role_spec.rb +6 -0
  36. metadata +28 -3
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>SALTED-SHA512-PBKDF2</key>
6
+ <dict>
7
+ <key>entropy</key>
8
+ <data>
9
+ EmAakNsXy/i6SAjmOC+w07nYpsGhkEd79oCrIa+2BlRnE25VzCCKb3QVbj2v
10
+ IPsTNp70t7r6BH2ANZ+0akikrczVSOuzOFGwk0fMqENBp/k6JxRzQ/ifuEP7
11
+ RsABfSZK+kl2uqz5QbkVvR7ByiTDCz51ngJAPgL1n+f/WTinY2w=
12
+ </data>
13
+ <key>iterations</key>
14
+ <integer>34482</integer>
15
+ <key>salt</key>
16
+ <data>
17
+ 7pVL5HL9xg3fiUhHgUM5k2JfAGr27IEMCPSafkE5RqE=
18
+ </data>
19
+ </dict>
20
+ </dict>
21
+ </plist>
@@ -0,0 +1,137 @@
1
+ #
2
+ # Author:: Adam Edwards (<adamed@getchef.com>)
3
+ # Copyright:: Copyright (c) 2014 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'spec_helper'
20
+
21
+ describe Chef::Resource::Env, :windows_only do
22
+ context 'when running on Windows' do
23
+ let(:chef_env_test_lower_case) { 'chefenvtest' }
24
+ let(:chef_env_test_mixed_case) { 'chefENVtest' }
25
+ let(:env_value1) { 'value1' }
26
+ let(:env_value2) { 'value2' }
27
+ let(:test_run_context) {
28
+ node = Chef::Node.new
29
+ node.default['platform'] = 'windows'
30
+ node.default['platform_version'] = '6.1'
31
+ empty_events = Chef::EventDispatch::Dispatcher.new
32
+ Chef::RunContext.new(node, {}, empty_events)
33
+ }
34
+ let(:test_resource) {
35
+ Chef::Resource::Env.new('unknown', test_run_context)
36
+ }
37
+
38
+ before(:each) do
39
+ resource_lower = Chef::Resource::Env.new(chef_env_test_lower_case, test_run_context)
40
+ resource_lower.run_action(:delete)
41
+ resource_mixed = Chef::Resource::Env.new(chef_env_test_mixed_case, test_run_context)
42
+ resource_mixed.run_action(:delete)
43
+ end
44
+
45
+ context "when the create action is invoked" do
46
+ it 'should create an environment variable for action create' do
47
+ expect(ENV[chef_env_test_lower_case]).to eq(nil)
48
+ test_resource.key_name(chef_env_test_lower_case)
49
+ test_resource.value(env_value1)
50
+ test_resource.run_action(:create)
51
+ expect(ENV[chef_env_test_lower_case]).to eq(env_value1)
52
+ end
53
+
54
+ it "should modify an existing variable's value to a new value and preserve the original name and preseve the original variable's name" do
55
+ test_resource.key_name(chef_env_test_lower_case)
56
+ test_resource.value(env_value1)
57
+ test_resource.run_action(:create)
58
+ expect(ENV[chef_env_test_lower_case]).to eq(env_value1)
59
+ test_resource.value(env_value2)
60
+ test_resource.run_action(:create)
61
+ expect(ENV[chef_env_test_lower_case]).to eq(env_value2)
62
+ end
63
+
64
+ it "should modify an existing variable's value to a new value if the variable name case differs from the existing variable" do
65
+ test_resource.key_name(chef_env_test_lower_case)
66
+ test_resource.value(env_value1)
67
+ test_resource.run_action(:create)
68
+ expect(ENV[chef_env_test_lower_case]).to eq(env_value1)
69
+ test_resource.key_name(chef_env_test_mixed_case)
70
+ test_resource.value(env_value2)
71
+ test_resource.run_action(:create)
72
+ expect(ENV[chef_env_test_lower_case]).to eq(env_value2)
73
+ end
74
+ end
75
+
76
+ context "when the modify action is invoked" do
77
+ it "should raise an exception for modify if the variable doesn't exist" do
78
+ expect(ENV[chef_env_test_lower_case]).to eq(nil)
79
+ test_resource.key_name(chef_env_test_lower_case)
80
+ test_resource.value(env_value1)
81
+ expect {test_resource.run_action(:modify) }.to raise_error(Chef::Exceptions::Env)
82
+ end
83
+
84
+ it "should modify an existing variable's value to a new value" do
85
+ test_resource.key_name(chef_env_test_lower_case)
86
+ test_resource.value(env_value1)
87
+ test_resource.run_action(:create)
88
+ expect(ENV[chef_env_test_lower_case]).to eq(env_value1)
89
+ test_resource.value(env_value2)
90
+ test_resource.run_action(:modify)
91
+ expect(ENV[chef_env_test_lower_case]).to eq(env_value2)
92
+ end
93
+
94
+ # This examlpe covers Chef Issue #1754
95
+ it "should modify an existing variable's value to a new value if the variable name case differs from the existing variable" do
96
+ test_resource.key_name(chef_env_test_lower_case)
97
+ test_resource.value(env_value1)
98
+ test_resource.run_action(:create)
99
+ expect(ENV[chef_env_test_lower_case]).to eq(env_value1)
100
+ test_resource.key_name(chef_env_test_mixed_case)
101
+ test_resource.value(env_value2)
102
+ test_resource.run_action(:modify)
103
+ expect(ENV[chef_env_test_lower_case]).to eq(env_value2)
104
+ end
105
+ end
106
+
107
+ context "when the delete action is invoked" do
108
+ it "should delete an environment variable" do
109
+ test_resource.key_name(chef_env_test_lower_case)
110
+ test_resource.value(env_value1)
111
+ test_resource.run_action(:create)
112
+ expect(ENV[chef_env_test_lower_case]).to eq(env_value1)
113
+ test_resource.run_action(:delete)
114
+ expect(ENV[chef_env_test_lower_case]).to eq(nil)
115
+ end
116
+
117
+ it "should not raise an exception when a non-existent environment variable is deleted" do
118
+ expect(ENV[chef_env_test_lower_case]).to eq(nil)
119
+ test_resource.key_name(chef_env_test_lower_case)
120
+ test_resource.value(env_value1)
121
+ expect{test_resource.run_action(:delete)}.not_to raise_error
122
+ expect(ENV[chef_env_test_lower_case]).to eq(nil)
123
+ end
124
+
125
+ it "should delete an existing variable's value to a new value if the specified variable name case differs from the existing variable" do
126
+ test_resource.key_name(chef_env_test_lower_case)
127
+ test_resource.value(env_value1)
128
+ test_resource.run_action(:create)
129
+ expect(ENV[chef_env_test_lower_case]).to eq(env_value1)
130
+ test_resource.key_name(chef_env_test_mixed_case)
131
+ test_resource.run_action(:delete)
132
+ expect(ENV[chef_env_test_lower_case]).to eq(nil)
133
+ expect(ENV[chef_env_test_mixed_case]).to eq(nil)
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,198 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2014 Chef Software, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'spec_helper'
19
+ require 'chef/mixin/shell_out'
20
+
21
+ metadata = {
22
+ :unix_only => true,
23
+ :requires_root => true,
24
+ :provider => {:user => Chef::Provider::User::Dscl}
25
+ }
26
+
27
+ describe "Chef::Resource::User with Chef::Provider::User::Dscl provider", metadata do
28
+ include Chef::Mixin::ShellOut
29
+
30
+ def clean_user
31
+ begin
32
+ shell_out!("/usr/bin/dscl . -delete '/Users/#{username}'")
33
+ rescue Mixlib::ShellOut::ShellCommandFailed
34
+ # Raised when the user is already cleaned
35
+ end
36
+ end
37
+
38
+ def user_should_exist
39
+ shell_out("/usr/bin/dscl . -ls /Users").stdout.should include username
40
+ end
41
+
42
+ def check_password(pass)
43
+ # In order to test the password we use dscl passwd command since
44
+ # that's the only command that gets the user password from CLI.
45
+ shell_out("dscl . -passwd /Users/greatchef #{pass} new_password").exitstatus.should == 0
46
+ # Now reset the password back
47
+ shell_out("dscl . -passwd /Users/greatchef new_password #{pass}").exitstatus.should == 0
48
+ end
49
+
50
+ let(:node) do
51
+ n = Chef::Node.new
52
+ n.consume_external_attrs(OHAI_SYSTEM.data.dup, {})
53
+ n
54
+ end
55
+
56
+ let(:events) do
57
+ Chef::EventDispatch::Dispatcher.new
58
+ end
59
+
60
+ let(:run_context) do
61
+ Chef::RunContext.new(node, {}, events)
62
+ end
63
+
64
+ let(:username) do
65
+ "greatchef"
66
+ end
67
+
68
+ let(:uid) { nil }
69
+ let(:gid) { 20 }
70
+ let(:home) { nil }
71
+ let(:manage_home) { false }
72
+ let(:password) { "XXXYYYZZZ" }
73
+ let(:comment) { "Great Chef" }
74
+ let(:shell) { "/bin/bash" }
75
+ let(:salt) { nil }
76
+ let(:iterations) { nil }
77
+
78
+ let(:user_resource) do
79
+ r = Chef::Resource::User.new("TEST USER RESOURCE", run_context)
80
+ r.username(username)
81
+ r.uid(uid)
82
+ r.gid(gid)
83
+ r.home(home)
84
+ r.shell(shell)
85
+ r.comment(comment)
86
+ r.manage_home(manage_home)
87
+ r.password(password)
88
+ r.salt(salt)
89
+ r.iterations(iterations)
90
+ r
91
+ end
92
+
93
+ before do
94
+ clean_user
95
+ end
96
+
97
+ after(:each) do
98
+ clean_user
99
+ end
100
+
101
+ describe "action :create" do
102
+ it "should create the user" do
103
+ user_resource.run_action(:create)
104
+ user_should_exist
105
+ check_password(password)
106
+ end
107
+ end
108
+
109
+ describe "when user exists" do
110
+ before do
111
+ existing_resource = user_resource.dup
112
+ existing_resource.run_action(:create)
113
+ user_should_exist
114
+ end
115
+
116
+ describe "when password is updated" do
117
+ it "should update the password of the user" do
118
+ user_resource.password("mykitchen")
119
+ user_resource.run_action(:create)
120
+ check_password("mykitchen")
121
+ end
122
+ end
123
+ end
124
+
125
+ describe "when password is being set via shadow hash" do
126
+ let(:password) {
127
+ if node[:platform_version].start_with?("10.7.")
128
+ # On Mac 10.7 we only need to set the password
129
+ "c9b3bd1a0cde797eef0eff16c580dab996ba3a21961cccc\
130
+ d0f5e65c61558243e50b1a490088bd4824e3b35562d383ca02260398\
131
+ ef1979b302212ec1c5383d1d05fc8d843"
132
+ else
133
+ "c734b6e4787c3727bb35e29fdd92b97c\
134
+ 1de12df509577a045728255ec7c6c5f5\
135
+ c18efa05ed02b682ffa7ebc05119900e\
136
+ b1d4880833aa7a190afc13e2bf0936b8\
137
+ 20123e8c98f0f9bcac2a629d9163caac\
138
+ 9464a8c234f3919082400b4f939bb77b\
139
+ c5adbbac718b7eb99463a7b679571e0f\
140
+ 1c9fef2ef08d0b9e9c2bcf644eed2ffc"
141
+ end
142
+ }
143
+
144
+ let(:iterations) { 25000 }
145
+ let(:salt) { "9e2e7d5ee473b496fd24cf0bbfcaedfcb291ee21740e570d1e917e874f8788ca" }
146
+
147
+ it "action :create should create the user" do
148
+ user_resource.run_action(:create)
149
+ user_should_exist
150
+ check_password("soawesome")
151
+ end
152
+
153
+ describe "when user exists" do
154
+ before do
155
+ existing_resource = user_resource.dup
156
+ existing_resource.run_action(:create)
157
+ user_should_exist
158
+ end
159
+
160
+ describe "when password is updated" do
161
+ it "should update the password of the user" do
162
+ user_resource.password("mykitchen")
163
+ user_resource.run_action(:create)
164
+ check_password("mykitchen")
165
+ end
166
+ end
167
+ end
168
+ end
169
+
170
+ describe "when a user is member of some groups" do
171
+ let(:groups) { ["staff", "operator"] }
172
+
173
+ before do
174
+ existing_resource = user_resource.dup
175
+ existing_resource.run_action(:create)
176
+
177
+ groups.each do |group|
178
+ shell_out!("/usr/bin/dscl . -append '/Groups/#{group}' GroupMembership #{username}")
179
+ end
180
+ end
181
+
182
+ after do
183
+ groups.each do |group|
184
+ # Do not raise an error when user is correctly removed
185
+ shell_out("/usr/bin/dscl . -delete '/Groups/#{group}' GroupMembership #{username}")
186
+ end
187
+ end
188
+
189
+ it ":remove action removes the user from the groups and deletes the user"do
190
+ user_resource.run_action(:remove)
191
+ groups.each do |group|
192
+ # Do not raise an error when group is empty
193
+ shell_out("dscl . read /Groups/staff GroupMembership").stdout.should_not include(group)
194
+ end
195
+ end
196
+ end
197
+
198
+ end
@@ -25,7 +25,7 @@ metadata = { :unix_only => true,
25
25
  :provider => {:user => Chef::Provider::User::Useradd}
26
26
  }
27
27
 
28
- describe Chef::Resource::User, metadata do
28
+ describe Chef::Provider::User::Useradd, metadata do
29
29
 
30
30
  include Chef::Mixin::ShellOut
31
31
 
@@ -0,0 +1,46 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2014 Chef Software, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'chef/knife'
19
+ require 'chef/json_compat'
20
+
21
+ class Chef
22
+ class Resource
23
+ class ZenFollower < Chef::Resource
24
+ attr_accessor :created_as_type
25
+
26
+ provides :follower, :on_platforms => ["zen"]
27
+
28
+ def initialize(name, run_context=nil)
29
+ @resource_name = :zen_follower
30
+ @created_as_type = "zen_follower"
31
+ super
32
+ end
33
+
34
+ def to_s
35
+ "#{created_as_type}[#{name}]"
36
+ end
37
+
38
+ def master(arg=nil)
39
+ if !arg.nil?
40
+ @master = arg
41
+ end
42
+ @master
43
+ end
44
+ end
45
+ end
46
+ end
@@ -255,7 +255,12 @@ describe Chef::Application do
255
255
 
256
256
  it "should set ENV['http_proxy']" do
257
257
  @app.configure_proxy_environment_variables
258
- @env['http_proxy'].should == "http://#{address}:#{port}"
258
+ @env['http_proxy'].should == "#{scheme}://#{address}:#{port}"
259
+ end
260
+
261
+ it "should set ENV['HTTP_PROXY']" do
262
+ @app.configure_proxy_environment_variables
263
+ @env['HTTP_PROXY'].should == "#{scheme}://#{address}:#{port}"
259
264
  end
260
265
 
261
266
  describe "when Chef::Config[:http_proxy_user] is set" do
@@ -265,7 +270,8 @@ describe Chef::Application do
265
270
 
266
271
  it "should set ENV['http_proxy'] with the username" do
267
272
  @app.configure_proxy_environment_variables
268
- @env['http_proxy'].should == "http://username@#{address}:#{port}"
273
+ @env['http_proxy'].should == "#{scheme}://username@#{address}:#{port}"
274
+ @env['HTTP_PROXY'].should == "#{scheme}://username@#{address}:#{port}"
269
275
  end
270
276
 
271
277
  context "when :http_proxy_user contains '@' and/or ':'" do
@@ -275,7 +281,8 @@ describe Chef::Application do
275
281
 
276
282
  it "should set ENV['http_proxy'] with the escaped username" do
277
283
  @app.configure_proxy_environment_variables
278
- @env['http_proxy'].should == "http://my%3Ausern%40me@#{address}:#{port}"
284
+ @env['http_proxy'].should == "#{scheme}://my%3Ausern%40me@#{address}:#{port}"
285
+ @env['HTTP_PROXY'].should == "#{scheme}://my%3Ausern%40me@#{address}:#{port}"
279
286
  end
280
287
  end
281
288
 
@@ -286,7 +293,8 @@ describe Chef::Application do
286
293
 
287
294
  it "should set ENV['http_proxy'] with the password" do
288
295
  @app.configure_proxy_environment_variables
289
- @env['http_proxy'].should == "http://username:password@#{address}:#{port}"
296
+ @env['http_proxy'].should == "#{scheme}://username:password@#{address}:#{port}"
297
+ @env['HTTP_PROXY'].should == "#{scheme}://username:password@#{address}:#{port}"
290
298
  end
291
299
 
292
300
  context "when :http_proxy_pass contains '@' and/or ':'" do
@@ -296,7 +304,8 @@ describe Chef::Application do
296
304
 
297
305
  it "should set ENV['http_proxy'] with the escaped password" do
298
306
  @app.configure_proxy_environment_variables
299
- @env['http_proxy'].should == "http://username:%3AP%40ssword101@#{address}:#{port}"
307
+ @env['http_proxy'].should == "#{scheme}://username:%3AP%40ssword101@#{address}:#{port}"
308
+ @env['HTTP_PROXY'].should == "#{scheme}://username:%3AP%40ssword101@#{address}:#{port}"
300
309
  end
301
310
  end
302
311
  end
@@ -310,7 +319,8 @@ describe Chef::Application do
310
319
 
311
320
  it "should set ENV['http_proxy']" do
312
321
  @app.configure_proxy_environment_variables
313
- @env['http_proxy'].should == "http://#{address}:#{port}"
322
+ @env['http_proxy'].should == "#{scheme}://#{address}:#{port}"
323
+ @env['HTTP_PROXY'].should == "#{scheme}://#{address}:#{port}"
314
324
  end
315
325
  end
316
326
  end
@@ -338,30 +348,43 @@ describe Chef::Application do
338
348
 
339
349
  describe "when Chef::Config[:http_proxy] is set" do
340
350
  context "when given an FQDN" do
351
+ let(:scheme) { "http" }
352
+ let(:address) { "proxy.example.org" }
353
+ let(:port) { 8080 }
354
+ let(:http_proxy) { "#{scheme}://#{address}:#{port}" }
355
+
356
+ it_should_behave_like "setting ENV['http_proxy']"
357
+ end
358
+
359
+ context "when given an HTTPS URL" do
360
+ let(:scheme) { "https" }
341
361
  let(:address) { "proxy.example.org" }
342
362
  let(:port) { 8080 }
343
- let(:http_proxy) { "http://#{address}:#{port}" }
363
+ let(:http_proxy) { "#{scheme}://#{address}:#{port}" }
344
364
 
345
365
  it_should_behave_like "setting ENV['http_proxy']"
346
366
  end
347
367
 
348
368
  context "when given an IP" do
369
+ let(:scheme) { "http" }
349
370
  let(:address) { "127.0.0.1" }
350
371
  let(:port) { 22 }
351
- let(:http_proxy) { "http://#{address}:#{port}" }
372
+ let(:http_proxy) { "#{scheme}://#{address}:#{port}" }
352
373
 
353
374
  it_should_behave_like "setting ENV['http_proxy']"
354
375
  end
355
376
 
356
377
  context "when given an IPv6" do
378
+ let(:scheme) { "http" }
357
379
  let(:address) { "[2001:db8::1]" }
358
380
  let(:port) { 80 }
359
- let(:http_proxy) { "http://#{address}:#{port}" }
381
+ let(:http_proxy) { "#{scheme}://#{address}:#{port}" }
360
382
 
361
383
  it_should_behave_like "setting ENV['http_proxy']"
362
384
  end
363
385
 
364
386
  context "when given without including http://" do
387
+ let(:scheme) { "http" }
365
388
  let(:address) { "proxy.example.org" }
366
389
  let(:port) { 8181 }
367
390
  let(:http_proxy) { "#{address}:#{port}" }