chef 18.2.7 → 18.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/chef-universal-mingw-ucrt.gemspec +1 -1
- data/chef.gemspec +3 -3
- data/lib/chef/application/base.rb +2 -0
- data/lib/chef/chef_fs/file_pattern.rb +1 -1
- data/lib/chef/chef_fs/path_utils.rb +7 -9
- data/lib/chef/client.rb +2 -2
- data/lib/chef/cookbook/synchronizer.rb +19 -2
- data/lib/chef/cookbook_version.rb +1 -1
- data/lib/chef/delayed_evaluator.rb +4 -0
- data/lib/chef/file_access_control/windows.rb +4 -1
- data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +2 -0
- data/lib/chef/http/ssl_policies.rb +2 -2
- data/lib/chef/mixin/homebrew_user.rb +15 -5
- data/lib/chef/monkey_patches/net-http.rb +127 -0
- data/lib/chef/node/attribute_collections.rb +10 -1
- data/lib/chef/node/immutable_collections.rb +7 -3
- data/lib/chef/node/mixin/state_tracking.rb +1 -1
- data/lib/chef/node/mixin/state_tracking_array.rb +41 -0
- data/lib/chef/node.rb +22 -0
- data/lib/chef/provider/launchd.rb +1 -1
- data/lib/chef/provider/mount/linux.rb +1 -1
- data/lib/chef/provider/mount/mount.rb +5 -5
- data/lib/chef/provider/package/apt.rb +11 -2
- data/lib/chef/provider/package/chocolatey.rb +239 -18
- data/lib/chef/provider/package/zypper.rb +6 -0
- data/lib/chef/provider/powershell_script.rb +96 -6
- data/lib/chef/provider/remote_file/http.rb +1 -1
- data/lib/chef/provider/service/systemd.rb +23 -8
- data/lib/chef/provider/service/windows.rb +1 -0
- data/lib/chef/provider/service.rb +14 -0
- data/lib/chef/provider/user.rb +5 -1
- data/lib/chef/provider/yum_repository.rb +1 -1
- data/lib/chef/recipe.rb +3 -11
- data/lib/chef/resource/_rest_resource.rb +1 -1
- data/lib/chef/resource/apt_package.rb +19 -0
- data/lib/chef/resource/apt_repository.rb +26 -6
- data/lib/chef/resource/chef_client_systemd_timer.rb +1 -1
- data/lib/chef/resource/chocolatey_installer.rb +207 -0
- data/lib/chef/resource/chocolatey_package.rb +8 -0
- data/lib/chef/resource/homebrew_cask.rb +6 -7
- data/lib/chef/resource/homebrew_package.rb +1 -1
- data/lib/chef/resource/homebrew_tap.rb +5 -5
- data/lib/chef/resource/launchd.rb +5 -1
- data/lib/chef/resource/locale.rb +5 -2
- data/lib/chef/resource/macos_pkg.rb +111 -0
- data/lib/chef/resource/powershell_script.rb +5 -1
- data/lib/chef/resource/service.rb +3 -0
- data/lib/chef/resource/sudo.rb +37 -2
- data/lib/chef/resource/support/ulimit.erb +40 -0
- data/lib/chef/resource/user_ulimit.rb +38 -0
- data/lib/chef/resource/windows_certificate.rb +1 -1
- data/lib/chef/resource/windows_security_policy.rb +2 -2
- data/lib/chef/resource.rb +11 -1
- data/lib/chef/resources.rb +2 -0
- data/lib/chef/version.rb +1 -1
- data/lib/chef/win32/security.rb +7 -1
- data/spec/data/trusted_certs/example.crt +29 -20
- data/spec/data/trusted_certs/example_no_cn.crt +30 -34
- data/spec/functional/resource/chocolatey_package_spec.rb +32 -20
- data/spec/functional/resource/execute_spec.rb +1 -1
- data/spec/functional/resource/windows_certificate_spec.rb +25 -0
- data/spec/functional/resource/zypper_package_spec.rb +10 -0
- data/spec/unit/client_spec.rb +2 -2
- data/spec/unit/compliance/reporter/chef_server_automate_spec.rb +1 -1
- data/spec/unit/delayed_evaluator_spec.rb +35 -0
- data/spec/unit/mixin/homebrew_user_spec.rb +30 -7
- data/spec/unit/node/vivid_mash_spec.rb +42 -0
- data/spec/unit/node_spec.rb +6 -0
- data/spec/unit/provider/apt_repository_spec.rb +17 -7
- data/spec/unit/provider/launchd_spec.rb +2 -2
- data/spec/unit/provider/mount/aix_spec.rb +2 -2
- data/spec/unit/provider/mount/linux_spec.rb +6 -5
- data/spec/unit/provider/mount/mount_spec.rb +8 -8
- data/spec/unit/provider/package/apt_spec.rb +18 -13
- data/spec/unit/provider/package/chocolatey_spec.rb +53 -9
- data/spec/unit/provider/package/rpm_spec.rb +2 -2
- data/spec/unit/provider/package/zypper_spec.rb +10 -0
- data/spec/unit/provider/powershell_script_spec.rb +100 -4
- data/spec/unit/provider/remote_file/http_spec.rb +4 -4
- data/spec/unit/provider/service/systemd_service_spec.rb +1 -0
- data/spec/unit/provider/user/linux_spec.rb +10 -0
- data/spec/unit/resource/apt_repository_spec.rb +5 -0
- data/spec/unit/resource/chef_client_systemd_timer_spec.rb +1 -1
- data/spec/unit/resource/chocolatey_installer_spec.rb +151 -0
- data/spec/unit/resource/macos_pkg_spec.rb +38 -0
- data/spec/unit/resource/powershell_script_spec.rb +2 -2
- data/spec/unit/resource_spec.rb +86 -0
- metadata +29 -16
- /data/spec/functional/assets/chocolatey_feed/{test-A.1.0.nupkg → test-A.1.0.0.nupkg} +0 -0
- /data/spec/functional/assets/chocolatey_feed/{test-A.1.5.nupkg → test-A.1.5.0.nupkg} +0 -0
- /data/spec/functional/assets/chocolatey_feed/{test-A.2.0.nupkg → test-A.2.0.0.nupkg} +0 -0
- /data/spec/functional/assets/chocolatey_feed/{test-B.1.0.nupkg → test-B.1.0.0.nupkg} +0 -0
@@ -41,7 +41,7 @@ describe Chef::Provider::Package::Rpm do
|
|
41
41
|
let(:rpm_q_status) { instance_double("Mixlib::ShellOut", exitstatus: rpm_q_exitstatus, stdout: rpm_q_stdout) }
|
42
42
|
|
43
43
|
before(:each) do
|
44
|
-
allow(::File).to receive(:exist?).with("PLEASE STUB File.
|
44
|
+
allow(::File).to receive(:exist?).with("PLEASE STUB File.exist? EXACTLY").and_return(true)
|
45
45
|
|
46
46
|
# Ensure all shell out usage is stubbed with exact arguments
|
47
47
|
allow(provider).to receive(:shell_out_compacted!).with("PLEASE STUB YOUR SHELLOUT CALLS").and_return(nil)
|
@@ -412,7 +412,7 @@ describe Chef::Provider::Package::Rpm do
|
|
412
412
|
|
413
413
|
let(:new_resource) do
|
414
414
|
# When we pass a source in as the name, then #initialize in the
|
415
|
-
# provider will call File.
|
415
|
+
# provider will call File.exist?. Because of the ordering in our
|
416
416
|
# let() bindings and such, we have to set the stub here and not in a
|
417
417
|
# before block.
|
418
418
|
allow(::File).to receive(:exist?).with(package_source).and_return(true)
|
@@ -491,4 +491,14 @@ describe Chef::Provider::Package::Zypper do
|
|
491
491
|
provider.remove_package(%w{emacs vim}, ["1.0", "2.0"])
|
492
492
|
end
|
493
493
|
end
|
494
|
+
|
495
|
+
describe "resolve_available_version" do
|
496
|
+
it "should return correct version if multiple packages are shown" do
|
497
|
+
status = double(stdout: "S | Name | Type | Version | Arch | Repository\n---+--------------------------+---------+---------------------+--------+-------------------------------------------------------------\n | apache2-mod_wsgi | package | 4.7.1-150400.3.3.1 | x86_64 | Update repository with updates from SUSE Linux Enterprise 15\n | apache2-mod_wsgi | package | 4.7.1-150400.1.52 | x86_64 | Main Repository\ni+ | apache2-mod_wsgi-python3 | package | 4.5.18-150000.4.6.1 | x86_64 | Update repository with updates from SUSE Linux Enterprise 15\nv | apache2-mod_wsgi-python3 | package | 4.5.18-4.3.1 | x86_64 | Main Repository\n", exitstatus: 0)
|
498
|
+
|
499
|
+
allow(provider).to receive(:shell_out_compacted!).and_return(status)
|
500
|
+
result = provider.send(:resolve_available_version, "apache2-mod_wsgi-python3", nil)
|
501
|
+
expect(result).to eq("4.5.18-150000.4.6.1")
|
502
|
+
end
|
503
|
+
end
|
494
504
|
end
|
@@ -17,10 +17,14 @@
|
|
17
17
|
#
|
18
18
|
|
19
19
|
require "spec_helper"
|
20
|
-
describe Chef::Provider::PowershellScript, "action_run" do
|
20
|
+
describe Chef::Provider::PowershellScript, "action_run", windows_only: true do
|
21
21
|
let(:events) { Chef::EventDispatch::Dispatcher.new }
|
22
22
|
|
23
|
-
let(:run_context) {
|
23
|
+
let(:run_context) {
|
24
|
+
@node = Chef::Node.new
|
25
|
+
@node.consume_external_attrs(OHAI_SYSTEM.data.dup, {})
|
26
|
+
Chef::RunContext.new(@node, {}, events)
|
27
|
+
}
|
24
28
|
|
25
29
|
let(:new_resource) do
|
26
30
|
Chef::Resource::PowershellScript.new("run some powershell code", run_context)
|
@@ -44,7 +48,7 @@ describe Chef::Provider::PowershellScript, "action_run" do
|
|
44
48
|
"C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe" -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Bypass -InputFormat None -InputFormat Fabulous -File "C:\\Temp\\Script.ps1"
|
45
49
|
CMD
|
46
50
|
|
47
|
-
expect(provider.command).to eq(expected)
|
51
|
+
expect(provider.send(:command)).to eq(expected)
|
48
52
|
end
|
49
53
|
|
50
54
|
it "uses pwsh when given the pwsh interpreter" do
|
@@ -55,7 +59,99 @@ describe Chef::Provider::PowershellScript, "action_run" do
|
|
55
59
|
"pwsh" -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Bypass -InputFormat None -File "C:\\Temp\\Script.ps1"
|
56
60
|
CMD
|
57
61
|
|
58
|
-
expect(provider.command).to eq(expected)
|
62
|
+
expect(provider.send(:command)).to eq(expected)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "returns the script specific to the inline interpreter when using use_inline_interpreter" do
|
66
|
+
new_resource.code = "test script"
|
67
|
+
new_resource.use_inline_powershell = true
|
68
|
+
# This is a string that is ONLY in the use_inline_interpreter version of this
|
69
|
+
expect(provider.send(:powershell_wrapper_script)).to include("$interpolatedexitcode = $")
|
70
|
+
end
|
71
|
+
|
72
|
+
it "returns the script specific to the normal interpreter when not using use_inline_interpreter" do
|
73
|
+
new_resource.code = "test script"
|
74
|
+
new_resource.use_inline_powershell = false
|
75
|
+
# This is a string that is ONLY in the non use_inline_interpreter version of this
|
76
|
+
expect(provider.send(:powershell_wrapper_script)).to include("new-variable -name interpolatedexitcode -visibility private")
|
77
|
+
end
|
78
|
+
|
79
|
+
it "Correctly returns for $True for regular powershell" do
|
80
|
+
new_resource.code = "$True"
|
81
|
+
new_resource.use_inline_powershell = false
|
82
|
+
new_resource.convert_boolean_return = true
|
83
|
+
expect(provider.run_action(:run)).to eq(nil)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "Correctly returns for $True for inline powershell with convert_boolean_return" do
|
87
|
+
new_resource.code = "$True"
|
88
|
+
new_resource.use_inline_powershell = true
|
89
|
+
new_resource.convert_boolean_return = true
|
90
|
+
expect(provider.run_action(:run)).to eq(nil)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "Correctly throws exception for $False for regular powershell" do
|
94
|
+
new_resource.code = "$False"
|
95
|
+
new_resource.use_inline_powershell = false
|
96
|
+
new_resource.convert_boolean_return = true
|
97
|
+
expect { provider.run_action(:run) }.to raise_error(an_instance_of(Mixlib::ShellOut::ShellCommandFailed))
|
98
|
+
end
|
99
|
+
|
100
|
+
it "Correctly throws exception for $False for inline powershell" do
|
101
|
+
new_resource.code = "$False"
|
102
|
+
new_resource.use_inline_powershell = true
|
103
|
+
new_resource.convert_boolean_return = true
|
104
|
+
expect { provider.run_action(:run) }.to raise_error(an_instance_of(ChefPowerShell::PowerShellExceptions::PowerShellCommandFailed))
|
105
|
+
end
|
106
|
+
|
107
|
+
it "return 1 fails correctly for non-inline" do
|
108
|
+
new_resource.code = "return 1"
|
109
|
+
new_resource.use_inline_powershell = false
|
110
|
+
expect { provider.run_action(:run) }.to raise_error(an_instance_of(Mixlib::ShellOut::ShellCommandFailed))
|
111
|
+
end
|
112
|
+
|
113
|
+
it "return 1 fails correctly for inline" do
|
114
|
+
new_resource.code = "return 1"
|
115
|
+
new_resource.use_inline_powershell = true
|
116
|
+
expect { provider.run_action(:run) }.to raise_error(an_instance_of(ChefPowerShell::PowerShellExceptions::PowerShellCommandFailed))
|
117
|
+
end
|
118
|
+
|
119
|
+
it "return 1 is valid when returns includes 1 for non-inline" do
|
120
|
+
new_resource.code = "return 1"
|
121
|
+
new_resource.use_inline_powershell = false
|
122
|
+
new_resource.returns = [1]
|
123
|
+
expect(provider.run_action(:run)).to eq(nil)
|
124
|
+
end
|
125
|
+
it "return 1 is valid when returns includes 1 for inline" do
|
126
|
+
new_resource.code = "return 1"
|
127
|
+
new_resource.use_inline_powershell = true
|
128
|
+
new_resource.returns = [1]
|
129
|
+
expect(provider.run_action(:run)).to eq(nil)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "bad powershell exceptions for non-inline" do
|
133
|
+
new_resource.code = "xyzzy"
|
134
|
+
new_resource.use_inline_powershell = false
|
135
|
+
expect { provider.run_action(:run) }.to raise_error(an_instance_of(Mixlib::ShellOut::ShellCommandFailed))
|
136
|
+
end
|
137
|
+
|
138
|
+
it "bad powershell exceptions for inline" do
|
139
|
+
new_resource.code = "xyzzy"
|
140
|
+
new_resource.use_inline_powershell = true
|
141
|
+
expect { provider.run_action(:run) }.to raise_error(an_instance_of(ChefPowerShell::PowerShellExceptions::PowerShellCommandFailed))
|
142
|
+
end
|
143
|
+
|
144
|
+
it "uses powershell for inline by default" do
|
145
|
+
new_resource.code = "$host.version.major -lt 7"
|
146
|
+
new_resource.use_inline_powershell = true
|
147
|
+
expect(provider.run_action(:run)).to eq(nil)
|
148
|
+
end
|
149
|
+
|
150
|
+
it "uses pwsh for inline when asked" do
|
151
|
+
new_resource.code = "$host.version.major -ge 7"
|
152
|
+
new_resource.use_inline_powershell = true
|
153
|
+
new_resource.interpreter = "pwsh"
|
154
|
+
expect(provider.run_action(:run)).to eq(nil)
|
59
155
|
end
|
60
156
|
end
|
61
157
|
end
|
@@ -251,7 +251,7 @@ describe Chef::Provider::RemoteFile::HTTP do
|
|
251
251
|
end
|
252
252
|
|
253
253
|
context "and the response has no Date or Last-Modified header" do
|
254
|
-
let(:last_response) { { "date" => nil, "
|
254
|
+
let(:last_response) { { "date" => nil, "last-modified" => nil } }
|
255
255
|
it "does not set an mtime in the result" do
|
256
256
|
# RFC 2616 suggests that servers that do not set a Date header do not
|
257
257
|
# have a reliable clock, so no use in making them deal with dates.
|
@@ -265,19 +265,19 @@ describe Chef::Provider::RemoteFile::HTTP do
|
|
265
265
|
context "and the response has a Last-Modified header" do
|
266
266
|
let(:last_response) do
|
267
267
|
# Last-Modified should be preferred to Date if both are set
|
268
|
-
{ "date" => "Fri, 17 May 2013 23:23:23 GMT", "
|
268
|
+
{ "date" => "Fri, 17 May 2013 23:23:23 GMT", "last-modified" => "Fri, 17 May 2013 11:11:11 GMT" }
|
269
269
|
end
|
270
270
|
|
271
271
|
it "sets the mtime to the Last-Modified time in the response" do
|
272
272
|
fetcher.fetch
|
273
273
|
expect(cache_control_data.etag).to be_nil
|
274
|
-
expect(cache_control_data.mtime).to eq(last_response["
|
274
|
+
expect(cache_control_data.mtime).to eq(last_response["last-modified"])
|
275
275
|
end
|
276
276
|
end
|
277
277
|
|
278
278
|
context "and the response has a Date header but no Last-Modified header" do
|
279
279
|
let(:last_response) do
|
280
|
-
{ "date" => "Fri, 17 May 2013 23:23:23 GMT", "
|
280
|
+
{ "date" => "Fri, 17 May 2013 23:23:23 GMT", "last-modified" => nil }
|
281
281
|
end
|
282
282
|
|
283
283
|
it "sets the mtime to the Date in the response" do
|
@@ -56,6 +56,7 @@ describe Chef::Provider::Service::Systemd do
|
|
56
56
|
allow(provider).to receive(:is_active?).and_return(false)
|
57
57
|
allow(provider).to receive(:is_enabled?).and_return(false)
|
58
58
|
allow(provider).to receive(:is_masked?).and_return(false)
|
59
|
+
allow(provider).to receive(:is_static?).and_return(false)
|
59
60
|
allow(provider).to receive(:is_indirect?).and_return(false)
|
60
61
|
end
|
61
62
|
|
@@ -136,6 +136,7 @@ describe Chef::Provider::User::Linux, linux_only: true do
|
|
136
136
|
"home" => ["/home/notarealuser", "/Users/notarealuser"],
|
137
137
|
"shell" => ["/usr/bin/zsh", "/bin/bash"],
|
138
138
|
"password" => %w{abcd 12345},
|
139
|
+
"sensitive" => [true],
|
139
140
|
}
|
140
141
|
end
|
141
142
|
|
@@ -147,6 +148,15 @@ describe Chef::Provider::User::Linux, linux_only: true do
|
|
147
148
|
end
|
148
149
|
end
|
149
150
|
|
151
|
+
it "should show a blank for password if sensitive set to true" do
|
152
|
+
@new_resource.password mapping["password"][0]
|
153
|
+
@current_resource.password mapping["password"][1]
|
154
|
+
@new_resource.sensitive true
|
155
|
+
@current_resource.sensitive true
|
156
|
+
provider.compare_user
|
157
|
+
expect(provider.change_desc).to eql(["change password from ******** to ********"])
|
158
|
+
end
|
159
|
+
|
150
160
|
%w{uid gid}.each do |property|
|
151
161
|
it "should return false if string #{property} matches fixnum" do
|
152
162
|
@new_resource.send(property, "100")
|
@@ -68,6 +68,11 @@ describe Chef::Resource::AptRepository do
|
|
68
68
|
expect(resource.key).to eql(["key1"])
|
69
69
|
end
|
70
70
|
|
71
|
+
it "allows setting options to a String and coerces it to an Array" do
|
72
|
+
resource.options = "by-hash=no"
|
73
|
+
expect(resource.options).to eql(["by-hash=no"])
|
74
|
+
end
|
75
|
+
|
71
76
|
it "fails if the user provides a repo_name with a forward slash" do
|
72
77
|
expect { resource.repo_name "foo/bar" }.to raise_error(ArgumentError)
|
73
78
|
end
|
@@ -102,7 +102,7 @@ describe Chef::Resource::ChefClientSystemdTimer do
|
|
102
102
|
|
103
103
|
it "sets CPUQuota if cpu_quota property is set" do
|
104
104
|
resource.cpu_quota 50
|
105
|
-
expect(provider.service_content["Service"]["CPUQuota"]).to eq(50)
|
105
|
+
expect(provider.service_content["Service"]["CPUQuota"]).to eq("50%")
|
106
106
|
end
|
107
107
|
end
|
108
108
|
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 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
|
+
|
20
|
+
describe Chef::Resource::ChocolateyInstaller do
|
21
|
+
include RecipeDSLHelper
|
22
|
+
|
23
|
+
let(:resource) { Chef::Resource::ChocolateyInstaller.new("fakey_fakerton") }
|
24
|
+
let(:config) do
|
25
|
+
<<-CONFIG
|
26
|
+
<?xml version="1.0" encoding="utf-8"?>
|
27
|
+
<chocolatey xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
28
|
+
<config>
|
29
|
+
<add key="containsLegacyPackageInstalls" value="true" description="Install has packages installed prior to 0.9.9 series." />
|
30
|
+
</config>
|
31
|
+
<sources>
|
32
|
+
<source id="chocolatey" value="https://chocolatey.org/api/v2/" disabled="false" bypassProxy="false" selfService="false" adminOnly="false" priority="0" />
|
33
|
+
</sources>
|
34
|
+
<features>
|
35
|
+
<feature name="checksumFiles" enabled="true" setExplicitly="false" description="Checksum files when pulled in from internet (based on package)." />
|
36
|
+
</features>
|
37
|
+
<apiKeys />
|
38
|
+
</chocolatey>
|
39
|
+
CONFIG
|
40
|
+
end
|
41
|
+
|
42
|
+
# we save off the ENV and set ALLUSERSPROFILE so these specs will work on *nix and non-C drive Windows installs
|
43
|
+
before(:each) do
|
44
|
+
@original_env = ENV.to_hash
|
45
|
+
ENV["ALLUSERSPROFILE"] = "C:\\ProgramData"
|
46
|
+
end
|
47
|
+
|
48
|
+
after(:each) do
|
49
|
+
ENV.clear
|
50
|
+
ENV.update(@original_env)
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "Basic Resource Settings" do
|
54
|
+
context "on windows", :windows_only do
|
55
|
+
it "supports :install, :uninstall, :upgrade actions" do
|
56
|
+
expect { resource.action :install }.not_to raise_error
|
57
|
+
expect { resource.action :uninstall }.not_to raise_error
|
58
|
+
expect { resource.action :upgrade }.not_to raise_error
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "Basic chocolatey settings" do
|
64
|
+
context "on windows", :windows_only do
|
65
|
+
it "has a resource name of :chocolatey_installer" do
|
66
|
+
expect(resource.resource_name).to eql(:chocolatey_installer)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "sets the default action as :install" do
|
70
|
+
expect(resource.action).to eql([:install])
|
71
|
+
end
|
72
|
+
|
73
|
+
it "supports :install and :uninstall actions" do
|
74
|
+
expect { resource.action :install }.not_to raise_error
|
75
|
+
expect { resource.action :uninstall }.not_to raise_error
|
76
|
+
end
|
77
|
+
|
78
|
+
it "does not support bologna install options" do
|
79
|
+
expect { resource.action :foo }.to raise_error(Chef::Exceptions::ValidationFailed)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "Installing chocolatey" do
|
85
|
+
context "on windows", :windows_only do
|
86
|
+
it "can install Chocolatey with parameters" do
|
87
|
+
resource.chocolatey_version = "1.4.0"
|
88
|
+
expect { resource.action :install }.not_to raise_error
|
89
|
+
end
|
90
|
+
|
91
|
+
it "logs a warning if a chocolatey install cannot be found" do
|
92
|
+
allow(::File).to receive(:exist?).with('C:\ProgramData\chocolatey\bin\choco.exe').and_return(false)
|
93
|
+
expect { Chef::Log.warn("Chocolatey is already uninstalled.") }.not_to output.to_stderr
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "Chocolatey is idempotent because" do
|
99
|
+
context "on windows", :windows_only do
|
100
|
+
it "it does not install choco again if it is already installed" do
|
101
|
+
install_choco
|
102
|
+
chocolatey_installer "install" do
|
103
|
+
action :install
|
104
|
+
end.should_not_be_updated
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "upgrading choco versions" do
|
110
|
+
|
111
|
+
context "on windows", :windows_only do
|
112
|
+
describe "when the versions do not match" do
|
113
|
+
it "upgrades if the proposed version is newer" do
|
114
|
+
allow(resource).to receive(:get_choco_version).and_return(Gem::Version.new("1.2.2"))
|
115
|
+
allow(resource).to receive(:chocolatey_version).and_return(Gem::Version.new("4.2.2"))
|
116
|
+
expect { resource.action :upgrade }.not_to raise_error
|
117
|
+
allow(resource).to receive(:get_choco_version).and_return(Gem::Version.new("4.2.2"))
|
118
|
+
expect(resource.get_choco_version).to eql(Gem::Version.new("4.2.2"))
|
119
|
+
end
|
120
|
+
end
|
121
|
+
describe "when the versions match" do
|
122
|
+
it "does not upgrade if the old version is identical" do
|
123
|
+
allow(resource).to receive(:get_choco_version).and_return(Gem::Version.new("2.2.2"))
|
124
|
+
allow(resource).to receive(:chocolatey_version).and_return(Gem::Version.new("2.2.2"))
|
125
|
+
expect { resource.action :upgrade }.not_to raise_error
|
126
|
+
expect(resource).not_to be_updated
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "Uninstalling chocolatey" do
|
133
|
+
context "on windows", :windows_only do
|
134
|
+
it "doesn't error out uninstalling chocolatey if chocolatey is not installed" do
|
135
|
+
allow(::File).to receive(:exist?).with('C:\ProgramData\chocolatey\bin\choco.exe').and_return(false)
|
136
|
+
expect { resource.action :uninstall }.not_to raise_error
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def install_choco
|
142
|
+
require "chef-powershell"
|
143
|
+
include ChefPowerShell::ChefPowerShellModule::PowerShellExec
|
144
|
+
powershell_code = <<-CODE
|
145
|
+
Set-ExecutionPolicy Bypass -Scope Process -Force;
|
146
|
+
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
|
147
|
+
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
|
148
|
+
CODE
|
149
|
+
powershell_exec(powershell_code)
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 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
|
+
|
20
|
+
describe Chef::Resource::MacosPkg do
|
21
|
+
let(:resource) { Chef::Resource::MacosPkg.new("fakey_fakerton") }
|
22
|
+
|
23
|
+
it "has a resource name of :macos_pkg" do
|
24
|
+
expect(resource.resource_name).to eql(:macos_pkg)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "sets the default action as :install" do
|
28
|
+
expect(resource.action).to eql([:install])
|
29
|
+
end
|
30
|
+
|
31
|
+
it "supports :install action" do
|
32
|
+
expect { resource.action :install }.not_to raise_error
|
33
|
+
end
|
34
|
+
|
35
|
+
it "target property defaults to /" do
|
36
|
+
expect(resource.target).to eql("/")
|
37
|
+
end
|
38
|
+
end
|
@@ -47,9 +47,9 @@ describe Chef::Resource::PowershellScript do
|
|
47
47
|
expect(resource.convert_boolean_return).to eq(false)
|
48
48
|
end
|
49
49
|
|
50
|
-
it "inherits exactly the :cwd, :domain, :environment, :group, :password, :path, :user, :umask, :architecture, :elevated, :interpreter, :login properties from a parent resource class" do
|
50
|
+
it "inherits exactly the :cwd, :domain, :environment, :group, :password, :path, :user, :umask, :architecture, :elevated, :interpreter, :login, :use_inline_powershell properties from a parent resource class" do
|
51
51
|
inherited_difference = Chef::Resource::PowershellScript.guard_inherited_attributes -
|
52
|
-
%i{cwd domain environment group password path user umask architecture elevated interpreter login}
|
52
|
+
%i{cwd domain environment group password path user umask architecture elevated interpreter login use_inline_powershell}
|
53
53
|
|
54
54
|
expect(inherited_difference).to eq([])
|
55
55
|
end
|
data/spec/unit/resource_spec.rb
CHANGED
@@ -803,6 +803,92 @@ describe Chef::Resource do
|
|
803
803
|
end
|
804
804
|
end
|
805
805
|
|
806
|
+
describe "when using resource partials" do
|
807
|
+
let(:resource_using_core_partial) do
|
808
|
+
Class.new(Chef::Resource) do
|
809
|
+
use "core::core_partial"
|
810
|
+
end
|
811
|
+
end
|
812
|
+
|
813
|
+
let(:resource_using_cookbook_partial) do
|
814
|
+
Class.new(Chef::Resource) do
|
815
|
+
use "my_local_partial"
|
816
|
+
end
|
817
|
+
end
|
818
|
+
|
819
|
+
let(:resource_using_nested_partials) do
|
820
|
+
FakeCaller = Struct.new(:label, :path, keyword_init: true)
|
821
|
+
NonDynamicResource = Chef::Resource.dup
|
822
|
+
|
823
|
+
# Fake a caller_locations array, as RSpec uses a different execution path
|
824
|
+
NonDynamicResource.define_singleton_method(:caller_locations) do
|
825
|
+
[
|
826
|
+
FakeCaller.new(label: "use", path: File.join(__dir__, "resource.rb")),
|
827
|
+
FakeCaller.new(label: "noise", path: File.join(__dir__, "no_file")),
|
828
|
+
FakeCaller.new(label: "class_from_file", path: File.join(__dir__, "_level3_partial.rb")),
|
829
|
+
FakeCaller.new(label: "noise", path: File.join(__dir__, "no_file")),
|
830
|
+
FakeCaller.new(label: "class_from_file", path: File.join(__dir__, "_level2_partial.rb")),
|
831
|
+
FakeCaller.new(label: "noise", path: File.join(__dir__, "no_file")),
|
832
|
+
FakeCaller.new(label: "class_from_file", path: File.join(__dir__, "_level1_partial.rb")),
|
833
|
+
FakeCaller.new(label: "noise", path: File.join(__dir__, "no_file")),
|
834
|
+
FakeCaller.new(label: "class_from_file", path: File.join(__dir__, "_level0_partial.rb")),
|
835
|
+
]
|
836
|
+
end
|
837
|
+
|
838
|
+
Class.new(NonDynamicResource) do
|
839
|
+
use "level3_partial"
|
840
|
+
end
|
841
|
+
end
|
842
|
+
|
843
|
+
it "correcly includes a core partial" do
|
844
|
+
expected_path = File.expand_path(File.join(__dir__, "../..", "lib/chef", "resource/_core_partial.rb"))
|
845
|
+
partial = "property :addon_property, default: true"
|
846
|
+
|
847
|
+
expect(IO).to receive(:read).with(expected_path).and_return(partial)
|
848
|
+
expect(resource_using_core_partial.properties.keys).to include(:addon_property)
|
849
|
+
end
|
850
|
+
|
851
|
+
it "correctly includes a cookbook partial" do
|
852
|
+
expected_path = File.expand_path(File.join(__dir__, "_my_local_partial.rb"))
|
853
|
+
partial = "property :addon_property, default: true"
|
854
|
+
|
855
|
+
expect(IO).to receive(:read).with(expected_path).and_return(partial)
|
856
|
+
expect(resource_using_cookbook_partial.properties.keys).to include(:addon_property)
|
857
|
+
end
|
858
|
+
|
859
|
+
it "correctly includes nested partials" do
|
860
|
+
level0_path = File.expand_path(File.join(__dir__, "_level0_partial.rb"))
|
861
|
+
level0_partial = "property :level0_property, default: true"
|
862
|
+
expect(IO).to receive(:read).with(level0_path).and_return(level0_partial)
|
863
|
+
|
864
|
+
level1_path = File.expand_path(File.join(__dir__, "_level1_partial.rb"))
|
865
|
+
level1_partial = <<-EOF
|
866
|
+
use 'level0_partial'
|
867
|
+
property :level1_property, default: true
|
868
|
+
EOF
|
869
|
+
expect(IO).to receive(:read).with(level1_path).and_return(level1_partial)
|
870
|
+
|
871
|
+
level2_path = File.expand_path(File.join(__dir__, "_level2_partial.rb"))
|
872
|
+
level2_partial = <<-EOF
|
873
|
+
use 'level1_partial'
|
874
|
+
property :level2_property, default: true
|
875
|
+
EOF
|
876
|
+
expect(IO).to receive(:read).with(level2_path).and_return(level2_partial)
|
877
|
+
|
878
|
+
level3_path = File.expand_path(File.join(__dir__, "_level3_partial.rb"))
|
879
|
+
level3_partial = <<-EOF
|
880
|
+
use 'level2_partial'
|
881
|
+
property :level3_property, default: true
|
882
|
+
EOF
|
883
|
+
expect(IO).to receive(:read).with(level3_path).and_return(level3_partial)
|
884
|
+
|
885
|
+
expect(resource_using_nested_partials.properties.keys).to include(:level0_property)
|
886
|
+
expect(resource_using_nested_partials.properties.keys).to include(:level1_property)
|
887
|
+
expect(resource_using_nested_partials.properties.keys).to include(:level2_property)
|
888
|
+
expect(resource_using_nested_partials.properties.keys).to include(:level3_property)
|
889
|
+
end
|
890
|
+
end
|
891
|
+
|
806
892
|
describe "should_skip?" do
|
807
893
|
before do
|
808
894
|
resource = Chef::Resource::Cat.new("sugar", run_context)
|