chef 12.5.1-universal-mingw32 → 12.6.0-universal-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.
- checksums.yaml +4 -4
- data/Gemfile +6 -1
- data/README.md +6 -4
- data/Rakefile +1 -4
- data/chef-windows.gemspec +21 -0
- data/chef.gemspec +58 -0
- data/lib/chef/api_client/registration.rb +9 -4
- data/lib/chef/application.rb +3 -84
- data/lib/chef/application/apply.rb +9 -2
- data/lib/chef/application/client.rb +8 -3
- data/lib/chef/application/solo.rb +7 -1
- data/lib/chef/application/windows_service.rb +21 -6
- data/lib/chef/application/windows_service_manager.rb +2 -3
- data/lib/chef/audit/runner.rb +1 -0
- data/lib/chef/chef_class.rb +1 -11
- data/lib/chef/chef_fs/chef_fs_data_store.rb +181 -2
- data/lib/chef/chef_fs/file_system/cookbook_subdir.rb +5 -0
- data/lib/chef/chef_fs/file_system/file_system_entry.rb +11 -7
- data/lib/chef/client.rb +28 -1
- data/lib/chef/cookbook/cookbook_collection.rb +14 -1
- data/lib/chef/cookbook/cookbook_version_loader.rb +1 -1
- data/lib/chef/cookbook/metadata.rb +115 -9
- data/lib/chef/cookbook/remote_file_vendor.rb +1 -1
- data/lib/chef/cookbook_version.rb +6 -2
- data/lib/chef/data_bag.rb +1 -1
- data/lib/chef/data_bag_item.rb +1 -1
- data/lib/chef/digester.rb +5 -1
- data/lib/chef/dsl/chef_provisioning.rb +57 -0
- data/lib/chef/dsl/cheffish.rb +64 -0
- data/lib/chef/dsl/declare_resource.rb +108 -0
- data/lib/chef/dsl/platform_introspection.rb +3 -3
- data/lib/chef/dsl/recipe.rb +3 -73
- data/lib/chef/dsl/resources.rb +27 -1
- data/lib/chef/event_dispatch/base.rb +3 -0
- data/lib/chef/event_dispatch/dispatcher.rb +5 -0
- data/lib/chef/event_dispatch/events_output_stream.rb +8 -0
- data/lib/chef/exceptions.rb +21 -1
- data/lib/chef/file_access_control/unix.rb +12 -12
- data/lib/chef/file_content_management/deploy/cp.rb +2 -2
- data/lib/chef/file_content_management/deploy/mv_unix.rb +4 -4
- data/lib/chef/file_content_management/deploy/mv_windows.rb +1 -1
- data/lib/chef/formatters/base.rb +7 -0
- data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +2 -2
- data/lib/chef/formatters/indentable_output_stream.rb +5 -0
- data/lib/chef/http.rb +19 -3
- data/lib/chef/http/decompressor.rb +2 -2
- data/lib/chef/json_compat.rb +1 -0
- data/lib/chef/knife.rb +16 -2
- data/lib/chef/knife/bootstrap.rb +55 -10
- data/lib/chef/knife/cookbook_site_install.rb +5 -1
- data/lib/chef/knife/core/bootstrap_context.rb +2 -1
- data/lib/chef/knife/core/node_presenter.rb +1 -1
- data/lib/chef/knife/ssh.rb +30 -16
- data/lib/chef/knife/ssl_check.rb +4 -2
- data/lib/chef/knife/ssl_fetch.rb +3 -2
- data/lib/chef/knife/status.rb +14 -1
- data/lib/chef/log.rb +14 -0
- data/lib/chef/mixin/get_source_from_package.rb +7 -2
- data/lib/chef/mixin/properties.rb +302 -0
- data/lib/chef/mixin/proxified_socket.rb +38 -0
- data/lib/chef/mixin/subclass_directive.rb +37 -0
- data/lib/chef/node.rb +13 -5
- data/lib/chef/platform/query_helpers.rb +14 -3
- data/lib/chef/platform/service_helpers.rb +20 -38
- data/lib/chef/policy_builder/expand_node_object.rb +3 -0
- data/lib/chef/policy_builder/policyfile.rb +1 -0
- data/lib/chef/property.rb +51 -12
- data/lib/chef/provider.rb +40 -35
- data/lib/chef/provider/deploy.rb +1 -1
- data/lib/chef/provider/dsc_resource.rb +54 -20
- data/lib/chef/provider/execute.rb +25 -4
- data/lib/chef/provider/group.rb +1 -1
- data/lib/chef/provider/lwrp_base.rb +1 -0
- data/lib/chef/provider/package.rb +76 -30
- data/lib/chef/provider/package/dpkg.rb +152 -69
- data/lib/chef/provider/package/openbsd.rb +6 -8
- data/lib/chef/provider/package/solaris.rb +2 -0
- data/lib/chef/provider/package/windows.rb +95 -14
- data/lib/chef/provider/package/windows/exe.rb +129 -0
- data/lib/chef/provider/package/windows/msi.rb +37 -13
- data/lib/chef/provider/package/windows/registry_uninstall_entry.rb +89 -0
- data/lib/chef/provider/package/yum.rb +13 -3
- data/lib/chef/provider/powershell_script.rb +3 -0
- data/lib/chef/provider/remote_file/cache_control_data.rb +37 -4
- data/lib/chef/provider/remote_file/http.rb +1 -1
- data/lib/chef/provider/script.rb +1 -0
- data/lib/chef/provider/service.rb +13 -10
- data/lib/chef/provider/service/solaris.rb +43 -17
- data/lib/chef/provider/service/upstart.rb +3 -3
- data/lib/chef/provider/user.rb +1 -1
- data/lib/chef/provider/user/dscl.rb +111 -100
- data/lib/chef/provider/user/windows.rb +5 -3
- data/lib/chef/recipe.rb +3 -5
- data/lib/chef/resource.rb +77 -320
- data/lib/chef/resource/action_class.rb +4 -0
- data/lib/chef/resource/dpkg_package.rb +4 -3
- data/lib/chef/resource/dsc_resource.rb +40 -2
- data/lib/chef/resource/execute.rb +9 -1
- data/lib/chef/resource/ksh.rb +32 -0
- data/lib/chef/resource/lwrp_base.rb +6 -10
- data/lib/chef/resource/package.rb +8 -9
- data/lib/chef/resource/registry_key.rb +1 -1
- data/lib/chef/resource/resource_notification.rb +14 -1
- data/lib/chef/resource/script.rb +1 -1
- data/lib/chef/resource/windows_package.rb +1 -1
- data/lib/chef/resource_builder.rb +14 -7
- data/lib/chef/resource_reporter.rb +6 -0
- data/lib/chef/resources.rb +1 -7
- data/lib/chef/rest.rb +1 -1
- data/lib/chef/run_context.rb +45 -2
- data/lib/chef/run_list/run_list_expansion.rb +47 -0
- data/lib/chef/runner.rb +25 -0
- data/lib/chef/search/query.rb +16 -2
- data/lib/chef/util/diff.rb +2 -2
- data/lib/chef/util/powershell/ps_credential.rb +2 -3
- data/lib/chef/version.rb +1 -1
- data/lib/chef/win32/api/file.rb +51 -1
- data/lib/chef/win32/file.rb +5 -0
- data/lib/chef/win32/file/version_info.rb +93 -0
- data/lib/chef/win32/mutex.rb +1 -1
- data/spec/data/apt/chef-integration-test2-1.0/debian/changelog +5 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2.debhelper.log +45 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2.substvars +1 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2/DEBIAN/conffiles +1 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2/DEBIAN/control +10 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2/DEBIAN/md5sums +1 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/compat +1 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/conffiles +1 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/control +13 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/copyright +34 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/files +1 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/rules +13 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/source/format +1 -0
- data/spec/data/apt/chef-integration-test2_1.0-1.debian.tar.gz +0 -0
- data/spec/data/apt/chef-integration-test2_1.0-1.dsc +18 -0
- data/spec/data/apt/chef-integration-test2_1.0-1_amd64.build +91 -0
- data/spec/data/apt/chef-integration-test2_1.0-1_amd64.changes +31 -0
- data/spec/data/apt/chef-integration-test2_1.0-1_amd64.deb +0 -0
- data/spec/data/apt/chef-integration-test2_1.0.orig.tar.gz +0 -0
- data/spec/functional/application_spec.rb +1 -1
- data/spec/functional/audit/runner_spec.rb +4 -0
- data/spec/functional/knife/ssh_spec.rb +5 -5
- data/spec/functional/notifications_spec.rb +74 -4
- data/spec/functional/resource/aix_service_spec.rb +2 -2
- data/spec/functional/resource/dpkg_package_spec.rb +339 -0
- data/spec/functional/resource/ifconfig_spec.rb +3 -1
- data/spec/functional/resource/mount_spec.rb +5 -2
- data/spec/functional/resource/package_spec.rb +1 -1
- data/spec/functional/resource/user/windows_spec.rb +8 -0
- data/spec/functional/resource/windows_package_spec.rb +177 -0
- data/spec/functional/win32/version_info_spec.rb +50 -0
- data/spec/integration/client/client_spec.rb +80 -0
- data/spec/integration/knife/download_spec.rb +9 -0
- data/spec/integration/knife/upload_spec.rb +28 -1
- data/spec/integration/recipes/lwrp_inline_resources_spec.rb +93 -23
- data/spec/integration/recipes/resource_action_spec.rb +211 -116
- data/spec/integration/recipes/resource_converge_if_changed_spec.rb +72 -0
- data/spec/integration/solo/solo_spec.rb +34 -0
- data/spec/spec_helper.rb +11 -1
- data/spec/support/platform_helpers.rb +8 -0
- data/spec/support/shared/integration/integration_helper.rb +6 -0
- data/spec/support/shared/unit/execute_resource.rb +5 -0
- data/spec/support/shared/unit/platform_introspector.rb +7 -0
- data/spec/tiny_server.rb +6 -2
- data/spec/unit/api_client/registration_spec.rb +5 -4
- data/spec/unit/application_spec.rb +1 -181
- data/spec/unit/chef_fs/file_system/cookbook_subdir_spec.rb +34 -0
- data/spec/unit/cookbook/metadata_spec.rb +122 -2
- data/spec/unit/http_spec.rb +102 -0
- data/spec/unit/knife/bootstrap_spec.rb +55 -13
- data/spec/unit/knife/core/bootstrap_context_spec.rb +10 -3
- data/spec/unit/knife/ssl_check_spec.rb +7 -3
- data/spec/unit/knife/ssl_fetch_spec.rb +2 -2
- data/spec/unit/knife/status_spec.rb +13 -13
- data/spec/unit/knife_spec.rb +26 -2
- data/spec/unit/lwrp_spec.rb +1 -1
- data/spec/unit/mixin/properties_spec.rb +97 -0
- data/spec/unit/mixin/proxified_socket_spec.rb +94 -0
- data/spec/unit/mixin/subclass_directive_spec.rb +45 -0
- data/spec/unit/node_spec.rb +9 -1
- data/spec/unit/policy_builder/policyfile_spec.rb +2 -0
- data/spec/unit/property/validation_spec.rb +14 -12
- data/spec/unit/property_spec.rb +56 -0
- data/spec/unit/provider/deploy_spec.rb +1 -1
- data/spec/unit/provider/dsc_resource_spec.rb +63 -24
- data/spec/unit/provider/execute_spec.rb +95 -28
- data/spec/unit/provider/package/dpkg_spec.rb +185 -96
- data/spec/unit/provider/package/windows/exe_spec.rb +251 -0
- data/spec/unit/provider/package/windows/msi_spec.rb +94 -10
- data/spec/unit/provider/package/windows_spec.rb +227 -26
- data/spec/unit/provider/package/yum_spec.rb +6 -0
- data/spec/unit/provider/package_spec.rb +495 -366
- data/spec/unit/provider/remote_file/cache_control_data_spec.rb +62 -36
- data/spec/unit/provider/script_spec.rb +2 -2
- data/spec/unit/provider/service/solaris_smf_service_spec.rb +110 -39
- data/spec/unit/provider/service/upstart_service_spec.rb +19 -0
- data/spec/unit/provider/user/dscl_spec.rb +14 -0
- data/spec/unit/provider/user/windows_spec.rb +2 -2
- data/spec/unit/provider/user_spec.rb +9 -0
- data/spec/unit/provider_resolver_spec.rb +6 -30
- data/spec/unit/recipe_spec.rb +46 -20
- data/spec/unit/resource/chef_gem_spec.rb +1 -1
- data/spec/unit/resource/dsc_resource_spec.rb +14 -3
- data/spec/unit/resource/ksh_spec.rb +40 -0
- data/spec/unit/resource/registry_key_spec.rb +2 -2
- data/spec/unit/resource/resource_notification_spec.rb +44 -45
- data/spec/unit/resource_reporter_spec.rb +7 -0
- data/spec/unit/resource_spec.rb +268 -253
- data/spec/unit/rest_spec.rb +2 -2
- data/spec/unit/run_list/run_list_expansion_spec.rb +18 -3
- data/spec/unit/search/query_spec.rb +19 -1
- data/spec/unit/util/powershell/ps_credential_spec.rb +8 -1
- data/spec/unit/windows_service_spec.rb +83 -38
- data/tasks/external_tests.rb +19 -9
- data/tasks/rspec.rb +1 -1
- metadata +70 -21
- data/spec/support/pedant/Gemfile +0 -3
- data/spec/support/pedant/pedant_config.rb +0 -129
- data/spec/support/pedant/run_pedant.rb +0 -63
- data/spec/support/pedant/stickywicket.pem +0 -27
- data/spec/unit/provider/package_spec.rbe +0 -0
@@ -0,0 +1,251 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Matt Wrock <matt@mattwrock.com>
|
3
|
+
# Copyright:: Copyright (c) 2015 Chef Software, 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
|
+
require 'chef/provider/package/windows/exe'
|
21
|
+
|
22
|
+
unless Chef::Platform.windows?
|
23
|
+
class Chef
|
24
|
+
module ReservedNames::Win32
|
25
|
+
class File
|
26
|
+
def version_info
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe Chef::Provider::Package::Windows::Exe do
|
35
|
+
let(:package_name) { "calculator" }
|
36
|
+
let(:resource_source) { "calculator.exe" }
|
37
|
+
let(:new_resource) do
|
38
|
+
new_resource = Chef::Resource::WindowsPackage.new(package_name)
|
39
|
+
new_resource.source(resource_source)
|
40
|
+
new_resource
|
41
|
+
end
|
42
|
+
let(:uninstall_hash) do
|
43
|
+
[{
|
44
|
+
'DisplayVersion' => 'outdated',
|
45
|
+
'UninstallString' => File.join("uninst_dir", "uninst_file")
|
46
|
+
}]
|
47
|
+
end
|
48
|
+
let(:uninstall_entry) do
|
49
|
+
entries = []
|
50
|
+
uninstall_hash.each do |entry|
|
51
|
+
entries.push(Chef::Provider::Package::Windows::RegistryUninstallEntry.new('hive', 'key', entry))
|
52
|
+
end
|
53
|
+
entries
|
54
|
+
end
|
55
|
+
let(:provider) { Chef::Provider::Package::Windows::Exe.new(new_resource, :nsis, uninstall_entry) }
|
56
|
+
let(:file_version) { nil }
|
57
|
+
let(:product_version) { nil }
|
58
|
+
let(:version_info) { instance_double("Chef::ReservedNames::Win32::File::Version_info", FileVersion: file_version, ProductVersion: product_version) }
|
59
|
+
|
60
|
+
before(:each) do
|
61
|
+
allow(Chef::ReservedNames::Win32::File).to receive(:version_info).and_return(version_info)
|
62
|
+
allow(::File).to receive(:exist?).with(Chef::Util::PathHelper.canonical_path(resource_source, false)).and_return(true)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "responds to shell_out!" do
|
66
|
+
expect(provider).to respond_to(:shell_out!)
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "expand_options" do
|
70
|
+
it "returns an empty string if passed no options" do
|
71
|
+
expect(provider.expand_options(nil)).to eql ""
|
72
|
+
end
|
73
|
+
|
74
|
+
it "returns a string with a leading space if passed options" do
|
75
|
+
expect(provider.expand_options("--train nope --town no_way")).to eql(" --train nope --town no_way")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "installed_version" do
|
80
|
+
it "returns the installed version" do
|
81
|
+
expect(provider.installed_version).to eql(["outdated"])
|
82
|
+
end
|
83
|
+
|
84
|
+
context "no versions installed" do
|
85
|
+
let(:uninstall_hash) { [] }
|
86
|
+
|
87
|
+
it "returns the installed version" do
|
88
|
+
expect(provider.installed_version).to eql(nil)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "package_version" do
|
94
|
+
before { new_resource.version(nil) }
|
95
|
+
|
96
|
+
context "source file does not exist" do
|
97
|
+
before do
|
98
|
+
allow(::File).to receive(:exist?).with(Chef::Util::PathHelper.canonical_path(resource_source, false)).and_return(false)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "returns nil" do
|
102
|
+
expect(provider.package_version).to eql(nil)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "file version is empty" do
|
107
|
+
let(:file_version) { '' }
|
108
|
+
|
109
|
+
it "returns nil" do
|
110
|
+
expect(provider.package_version).to eql(nil)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "returns the version of a package if given" do
|
114
|
+
new_resource.version('v55555')
|
115
|
+
expect(provider.package_version).to eql('v55555')
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context "both file and product version are in installer" do
|
120
|
+
let(:file_version) { '1.1.1' }
|
121
|
+
let(:product_version) { '1.1' }
|
122
|
+
|
123
|
+
it "returns the file version" do
|
124
|
+
expect(provider.package_version).to eql('1.1.1')
|
125
|
+
end
|
126
|
+
|
127
|
+
it "returns the version of a package if given" do
|
128
|
+
new_resource.version('v55555')
|
129
|
+
expect(provider.package_version).to eql('v55555')
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context "only file version is in installer" do
|
134
|
+
let(:file_version) { '1.1.1' }
|
135
|
+
|
136
|
+
it "returns the file version" do
|
137
|
+
expect(provider.package_version).to eql('1.1.1')
|
138
|
+
end
|
139
|
+
|
140
|
+
it "returns the version of a package if given" do
|
141
|
+
new_resource.version('v55555')
|
142
|
+
expect(provider.package_version).to eql('v55555')
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context "only product version is in installer" do
|
147
|
+
let(:product_version) { '1.1' }
|
148
|
+
|
149
|
+
it "returns the product version" do
|
150
|
+
expect(provider.package_version).to eql('1.1')
|
151
|
+
end
|
152
|
+
|
153
|
+
it "returns the version of a package if given" do
|
154
|
+
new_resource.version('v55555')
|
155
|
+
expect(provider.package_version).to eql('v55555')
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context "no version info is in installer" do
|
160
|
+
let(:file_version) { nil }
|
161
|
+
let(:product_version) { nil }
|
162
|
+
|
163
|
+
it "returns the version of a package" do
|
164
|
+
new_resource.version('v55555')
|
165
|
+
expect(provider.package_version).to eql('v55555')
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context "no version info is in installer and none in attribute" do
|
170
|
+
it "returns the version of a package" do
|
171
|
+
expect(provider.package_version).to eql(nil)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe "remove_package" do
|
177
|
+
context "no version given and one package installed" do
|
178
|
+
it "removes installed package" do
|
179
|
+
expect(provider).to receive(:shell_out!).with(/start \"\" \/wait \/d\"uninst_dir\" uninst_file \/S \/NCRC & exit %%%%ERRORLEVEL%%%%/, kind_of(Hash))
|
180
|
+
provider.remove_package
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context "several packages installed" do
|
185
|
+
let(:uninstall_hash) do
|
186
|
+
[
|
187
|
+
{
|
188
|
+
'DisplayVersion' => 'v1',
|
189
|
+
'UninstallString' => File.join("uninst_dir1", "uninst_file1")
|
190
|
+
},
|
191
|
+
{
|
192
|
+
'DisplayVersion' => 'v2',
|
193
|
+
'UninstallString' => File.join("uninst_dir2", "uninst_file2")
|
194
|
+
}
|
195
|
+
]
|
196
|
+
end
|
197
|
+
|
198
|
+
context "version given and installed" do
|
199
|
+
it "removes given version" do
|
200
|
+
new_resource.version('v2')
|
201
|
+
expect(provider).to receive(:shell_out!).with(/start \"\" \/wait \/d\"uninst_dir2\" uninst_file2 \/S \/NCRC & exit %%%%ERRORLEVEL%%%%/, kind_of(Hash))
|
202
|
+
provider.remove_package
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context "no version given" do
|
207
|
+
it "removes both versions" do
|
208
|
+
expect(provider).to receive(:shell_out!).with(/start \"\" \/wait \/d\"uninst_dir1\" uninst_file1 \/S \/NCRC & exit %%%%ERRORLEVEL%%%%/, kind_of(Hash))
|
209
|
+
expect(provider).to receive(:shell_out!).with(/start \"\" \/wait \/d\"uninst_dir2\" uninst_file2 \/S \/NCRC & exit %%%%ERRORLEVEL%%%%/, kind_of(Hash))
|
210
|
+
provider.remove_package
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
context "installs nsis installer" do
|
217
|
+
let(:provider) { Chef::Provider::Package::Windows::Exe.new(new_resource, :nsis, uninstall_entry) }
|
218
|
+
|
219
|
+
it "calls installer with the correct flags" do
|
220
|
+
expect(provider).to receive(:shell_out!).with(/start \"\" \/wait \"#{Regexp.quote(new_resource.source)}\" \/S \/NCRC & exit %%%%ERRORLEVEL%%%%/, kind_of(Hash))
|
221
|
+
provider.install_package
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
context "installs installshield installer" do
|
226
|
+
let(:provider) { Chef::Provider::Package::Windows::Exe.new(new_resource, :installshield, uninstall_entry) }
|
227
|
+
|
228
|
+
it "calls installer with the correct flags" do
|
229
|
+
expect(provider).to receive(:shell_out!).with(/start \"\" \/wait \"#{Regexp.quote(new_resource.source)}\" \/s \/sms & exit %%%%ERRORLEVEL%%%%/, kind_of(Hash))
|
230
|
+
provider.install_package
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
context "installs inno installer" do
|
235
|
+
let(:provider) { Chef::Provider::Package::Windows::Exe.new(new_resource, :inno, uninstall_entry) }
|
236
|
+
|
237
|
+
it "calls installer with the correct flags" do
|
238
|
+
expect(provider).to receive(:shell_out!).with(/start \"\" \/wait \"#{Regexp.quote(new_resource.source)}\" \/VERYSILENT \/SUPPRESSMSGBOXES \/NORESTART & exit %%%%ERRORLEVEL%%%%/, kind_of(Hash))
|
239
|
+
provider.install_package
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
context "installs wise installer" do
|
244
|
+
let(:provider) { Chef::Provider::Package::Windows::Exe.new(new_resource, :wise, uninstall_entry) }
|
245
|
+
|
246
|
+
it "calls installer with the correct flags" do
|
247
|
+
expect(provider).to receive(:shell_out!).with(/start \"\" \/wait \"#{Regexp.quote(new_resource.source)}\" \/s & exit %%%%ERRORLEVEL%%%%/, kind_of(Hash))
|
248
|
+
provider.install_package
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
@@ -17,17 +17,37 @@
|
|
17
17
|
#
|
18
18
|
|
19
19
|
require 'spec_helper'
|
20
|
+
require 'chef/provider/package/windows/msi'
|
20
21
|
|
21
22
|
describe Chef::Provider::Package::Windows::MSI do
|
22
23
|
let(:node) { double('Chef::Node') }
|
23
24
|
let(:events) { double('Chef::Events').as_null_object } # mock all the methods
|
24
25
|
let(:run_context) { double('Chef::RunContext', :node => node, :events => events) }
|
25
|
-
let(:
|
26
|
-
let(:
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
let(:package_name) { "calculator" }
|
27
|
+
let(:resource_source) { "calculator.msi" }
|
28
|
+
let(:resource_version) { nil }
|
29
|
+
let(:new_resource) do
|
30
|
+
new_resource = Chef::Resource::WindowsPackage.new(package_name)
|
31
|
+
new_resource.source(resource_source)
|
32
|
+
new_resource.version(resource_version)
|
33
|
+
new_resource
|
34
|
+
end
|
35
|
+
let(:uninstall_hash) do
|
36
|
+
[{
|
37
|
+
'DisplayVersion' => 'outdated',
|
38
|
+
'UninstallString' => "MsiExec.exe /X{guid}"
|
39
|
+
}]
|
40
|
+
end
|
41
|
+
let(:uninstall_entry) do
|
42
|
+
entries = []
|
43
|
+
uninstall_hash.each do |entry|
|
44
|
+
entries.push(Chef::Provider::Package::Windows::RegistryUninstallEntry.new('hive', 'key', entry))
|
45
|
+
end
|
46
|
+
entries
|
47
|
+
end
|
48
|
+
let(:provider) { Chef::Provider::Package::Windows::MSI.new(new_resource, uninstall_entry) }
|
49
|
+
before do
|
50
|
+
allow(::File).to receive(:exist?).with(Chef::Util::PathHelper.canonical_path(resource_source, false)).and_return(true)
|
31
51
|
end
|
32
52
|
|
33
53
|
it "responds to shell_out!" do
|
@@ -50,6 +70,11 @@ describe Chef::Provider::Package::Windows::MSI do
|
|
50
70
|
allow(provider).to receive(:get_installed_version).with("{23170F69-40C1-2702-0920-000001000000}").and_return("3.14159.1337.42")
|
51
71
|
expect(provider.installed_version).to eql("3.14159.1337.42")
|
52
72
|
end
|
73
|
+
|
74
|
+
it "returns the installed version in the registry when install file not present" do
|
75
|
+
allow(::File).to receive(:exist?).with(Chef::Util::PathHelper.canonical_path(resource_source, false)).and_return(false)
|
76
|
+
expect(provider.installed_version).to eql(["outdated"])
|
77
|
+
end
|
53
78
|
end
|
54
79
|
|
55
80
|
describe "package_version" do
|
@@ -57,19 +82,78 @@ describe Chef::Provider::Package::Windows::MSI do
|
|
57
82
|
allow(provider).to receive(:get_product_property).with(/calculator.msi$/, "ProductVersion").and_return(42)
|
58
83
|
expect(provider.package_version).to eql(42)
|
59
84
|
end
|
85
|
+
|
86
|
+
context "version is explicitly provided" do
|
87
|
+
let(:resource_version) { "given_version" }
|
88
|
+
|
89
|
+
it "returns the given version" do
|
90
|
+
expect(provider.package_version).to eql("given_version")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "no source or version is given" do
|
95
|
+
before do
|
96
|
+
allow(::File).to receive(:exist?).with(Chef::Util::PathHelper.canonical_path(resource_source, false)).and_return(false)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "returns nil" do
|
100
|
+
expect(provider.package_version).to eql(nil)
|
101
|
+
end
|
102
|
+
end
|
60
103
|
end
|
61
104
|
|
62
105
|
describe "install_package" do
|
63
106
|
it "calls msiexec /qn /i" do
|
64
|
-
expect(provider).to receive(:shell_out!).with(/msiexec \/qn \/i \"
|
65
|
-
provider.install_package
|
107
|
+
expect(provider).to receive(:shell_out!).with(/msiexec \/qn \/i \"#{Regexp.quote(new_resource.source)}\"/, kind_of(Hash))
|
108
|
+
provider.install_package
|
66
109
|
end
|
67
110
|
end
|
68
111
|
|
69
112
|
describe "remove_package" do
|
70
113
|
it "calls msiexec /qn /x" do
|
71
|
-
expect(provider).to receive(:shell_out!).with(/msiexec \/qn \/x \"
|
72
|
-
provider.remove_package
|
114
|
+
expect(provider).to receive(:shell_out!).with(/msiexec \/qn \/x \"#{Regexp.quote(new_resource.source)}\"/, kind_of(Hash))
|
115
|
+
provider.remove_package
|
116
|
+
end
|
117
|
+
|
118
|
+
context "no source is provided" do
|
119
|
+
before do
|
120
|
+
allow(::File).to receive(:exist?).with(Chef::Util::PathHelper.canonical_path(resource_source, false)).and_return(false)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "removes installed package" do
|
124
|
+
expect(provider).to receive(:shell_out!).with(/MsiExec.exe \/X{guid} \/Q/, kind_of(Hash))
|
125
|
+
provider.remove_package
|
126
|
+
end
|
127
|
+
|
128
|
+
context "there are multiple installs" do
|
129
|
+
let(:uninstall_hash) do
|
130
|
+
[
|
131
|
+
{
|
132
|
+
'DisplayVersion' => 'outdated',
|
133
|
+
'UninstallString' => "MsiExec.exe /X{guid}"
|
134
|
+
},
|
135
|
+
{
|
136
|
+
'DisplayVersion' => 'really_outdated',
|
137
|
+
'UninstallString' => "MsiExec.exe /X{guid2}"
|
138
|
+
}
|
139
|
+
]
|
140
|
+
end
|
141
|
+
|
142
|
+
it "removes both installed package" do
|
143
|
+
expect(provider).to receive(:shell_out!).with(/MsiExec.exe \/X{guid} \/Q/, kind_of(Hash))
|
144
|
+
expect(provider).to receive(:shell_out!).with(/MsiExec.exe \/X{guid2} \/Q/, kind_of(Hash))
|
145
|
+
provider.remove_package
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "custom options includes /Q" do
|
150
|
+
before { new_resource.options("/Q") }
|
151
|
+
|
152
|
+
it "does not duplicate quiet switch" do
|
153
|
+
expect(provider).to receive(:shell_out!).with(/MsiExec.exe \/X{guid} \/Q/, kind_of(Hash))
|
154
|
+
provider.remove_package
|
155
|
+
end
|
156
|
+
end
|
73
157
|
end
|
74
158
|
end
|
75
159
|
end
|
@@ -17,6 +17,8 @@
|
|
17
17
|
#
|
18
18
|
|
19
19
|
require 'spec_helper'
|
20
|
+
require 'chef/provider/package/windows/exe'
|
21
|
+
require 'chef/provider/package/windows/msi'
|
20
22
|
|
21
23
|
describe Chef::Provider::Package::Windows, :windows_only do
|
22
24
|
before(:each) do
|
@@ -28,10 +30,19 @@ describe Chef::Provider::Package::Windows, :windows_only do
|
|
28
30
|
let(:events) { double('Chef::Events').as_null_object } # mock all the methods
|
29
31
|
let(:run_context) { double('Chef::RunContext', :node => node, :events => events) }
|
30
32
|
let(:resource_source) { 'calculator.msi' }
|
31
|
-
let(:
|
33
|
+
let(:resource_name) { 'calculator' }
|
34
|
+
let(:new_resource) do
|
35
|
+
new_resource = Chef::Resource::WindowsPackage.new(resource_name)
|
36
|
+
new_resource.source(resource_source)
|
37
|
+
new_resource
|
38
|
+
end
|
32
39
|
let(:provider) { Chef::Provider::Package::Windows.new(new_resource, run_context) }
|
33
40
|
let(:cache_path) { 'c:\\cache\\' }
|
34
41
|
|
42
|
+
before(:each) do
|
43
|
+
allow(::File).to receive(:exist?).with(provider.new_resource.source).and_return(true)
|
44
|
+
end
|
45
|
+
|
35
46
|
describe "load_current_resource" do
|
36
47
|
shared_examples "a local file" do
|
37
48
|
before(:each) do
|
@@ -43,7 +54,7 @@ describe Chef::Provider::Package::Windows, :windows_only do
|
|
43
54
|
it "creates a current resource with the name of the new resource" do
|
44
55
|
provider.load_current_resource
|
45
56
|
expect(provider.current_resource).to be_a(Chef::Resource::WindowsPackage)
|
46
|
-
expect(provider.current_resource.name).to eql(
|
57
|
+
expect(provider.current_resource.name).to eql(resource_name)
|
47
58
|
end
|
48
59
|
|
49
60
|
it "sets the current version if the package is installed" do
|
@@ -76,19 +87,6 @@ describe Chef::Provider::Package::Windows, :windows_only do
|
|
76
87
|
end
|
77
88
|
it_behaves_like "a local file"
|
78
89
|
end
|
79
|
-
|
80
|
-
context "when remote_file_attributes are provided" do
|
81
|
-
let (:remote_file_attributes) { {:path => 'C:\\foobar.msi'} }
|
82
|
-
before(:each) do
|
83
|
-
new_resource.remote_file_attributes(remote_file_attributes)
|
84
|
-
end
|
85
|
-
|
86
|
-
it 'should override the attributes of the remote file resource used' do
|
87
|
-
expect(::File).to receive(:exists?).with(remote_file_attributes[:path])
|
88
|
-
provider.load_current_resource
|
89
|
-
end
|
90
|
-
|
91
|
-
end
|
92
90
|
end
|
93
91
|
|
94
92
|
context "when source is a local file" do
|
@@ -98,6 +96,7 @@ describe Chef::Provider::Package::Windows, :windows_only do
|
|
98
96
|
|
99
97
|
describe "package_provider" do
|
100
98
|
shared_examples "a local file" do
|
99
|
+
|
101
100
|
it "checks that the source path is valid" do
|
102
101
|
expect(Chef::Util::PathHelper).to receive(:validate_path)
|
103
102
|
provider.package_provider
|
@@ -108,9 +107,29 @@ describe Chef::Provider::Package::Windows, :windows_only do
|
|
108
107
|
expect(provider.package_provider).to be_a(Chef::Provider::Package::Windows::MSI)
|
109
108
|
end
|
110
109
|
|
111
|
-
it "
|
112
|
-
allow(provider).to receive(:installer_type).and_return(:
|
113
|
-
expect
|
110
|
+
it "sets the package provider to Exe if the the installer type is :inno" do
|
111
|
+
allow(provider).to receive(:installer_type).and_return(:inno)
|
112
|
+
expect(provider.package_provider).to be_a(Chef::Provider::Package::Windows::Exe)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "sets the package provider to Exe if the the installer type is :nsis" do
|
116
|
+
allow(provider).to receive(:installer_type).and_return(:nsis)
|
117
|
+
expect(provider.package_provider).to be_a(Chef::Provider::Package::Windows::Exe)
|
118
|
+
end
|
119
|
+
|
120
|
+
it "sets the package provider to Exe if the the installer type is :wise" do
|
121
|
+
allow(provider).to receive(:installer_type).and_return(:wise)
|
122
|
+
expect(provider.package_provider).to be_a(Chef::Provider::Package::Windows::Exe)
|
123
|
+
end
|
124
|
+
|
125
|
+
it "sets the package provider to Exe if the the installer type is :installshield" do
|
126
|
+
allow(provider).to receive(:installer_type).and_return(:installshield)
|
127
|
+
expect(provider.package_provider).to be_a(Chef::Provider::Package::Windows::Exe)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "defaults to exe if the installer_type is unknown" do
|
131
|
+
allow(provider).to receive(:installer_type).and_return(nil)
|
132
|
+
expect(provider.package_provider).to be_a(Chef::Provider::Package::Windows::Exe)
|
114
133
|
end
|
115
134
|
end
|
116
135
|
|
@@ -146,20 +165,202 @@ describe Chef::Provider::Package::Windows, :windows_only do
|
|
146
165
|
end
|
147
166
|
|
148
167
|
describe "installer_type" do
|
149
|
-
|
168
|
+
let(:resource_source) { "microsoft_installer.exe" }
|
169
|
+
|
170
|
+
context "there is no source" do
|
171
|
+
let(:uninstall_hash) do
|
172
|
+
[{
|
173
|
+
'DisplayVersion' => 'outdated',
|
174
|
+
'UninstallString' => "blah blah"
|
175
|
+
}]
|
176
|
+
end
|
177
|
+
let(:uninstall_key) { "blah" }
|
178
|
+
let(:uninstall_entry) do
|
179
|
+
entries = []
|
180
|
+
uninstall_hash.each do |entry|
|
181
|
+
entries.push(Chef::Provider::Package::Windows::RegistryUninstallEntry.new('hive', uninstall_key, entry))
|
182
|
+
end
|
183
|
+
entries
|
184
|
+
end
|
185
|
+
|
186
|
+
before do
|
187
|
+
allow(Chef::Provider::Package::Windows::RegistryUninstallEntry).to receive(:find_entries).and_return(uninstall_entry)
|
188
|
+
allow(::File).to receive(:exist?).with(Chef::Util::PathHelper.canonical_path(resource_source, false)).and_return(false)
|
189
|
+
end
|
190
|
+
|
191
|
+
context "uninstall string contains MsiExec.exe" do
|
192
|
+
let(:uninstall_hash) do
|
193
|
+
[{
|
194
|
+
'DisplayVersion' => 'outdated',
|
195
|
+
'UninstallString' => "MsiExec.exe /X{guid}"
|
196
|
+
}]
|
197
|
+
end
|
198
|
+
|
199
|
+
it "sets installer_type to MSI" do
|
200
|
+
expect(provider.installer_type).to eql(:msi)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context "uninstall string ends with uninst.exe" do
|
205
|
+
let(:uninstall_hash) do
|
206
|
+
[{
|
207
|
+
'DisplayVersion' => 'outdated',
|
208
|
+
'UninstallString' => %q{"c:/hfhfheru/uninst.exe"}
|
209
|
+
}]
|
210
|
+
end
|
211
|
+
|
212
|
+
it "sets installer_type to NSIS" do
|
213
|
+
expect(provider.installer_type).to eql(:nsis)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
context "uninstall key ends in _is1" do
|
218
|
+
let(:uninstall_key) { "blah_is1" }
|
219
|
+
|
220
|
+
it "sets installer_type to inno" do
|
221
|
+
expect(provider.installer_type).to eql(:inno)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
context "eninstall entries is empty" do
|
226
|
+
before { allow(Chef::Provider::Package::Windows::RegistryUninstallEntry).to receive(:find_entries).and_return([]) }
|
227
|
+
|
228
|
+
it "returns nil" do
|
229
|
+
expect(provider.installer_type).to eql(nil)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
it "returns @installer_type if it is set" do
|
150
235
|
provider.new_resource.installer_type(:downeaster)
|
151
236
|
expect(provider.installer_type).to eql(:downeaster)
|
152
237
|
end
|
153
238
|
|
154
|
-
it "sets installer_type to
|
155
|
-
|
156
|
-
expect(provider.installer_type).to eql(:
|
239
|
+
it "sets installer_type to inno if the source contains inno" do
|
240
|
+
allow(::Kernel).to receive(:open).and_yield(StringIO.new('blah blah inno blah'))
|
241
|
+
expect(provider.installer_type).to eql(:inno)
|
157
242
|
end
|
158
243
|
|
159
|
-
it "
|
160
|
-
|
161
|
-
provider.
|
162
|
-
|
244
|
+
it "sets installer_type to wise if the source contains wise" do
|
245
|
+
allow(::Kernel).to receive(:open).and_yield(StringIO.new('blah blah wise blah'))
|
246
|
+
expect(provider.installer_type).to eql(:wise)
|
247
|
+
end
|
248
|
+
|
249
|
+
it "sets installer_type to nsis if the source contains nsis" do
|
250
|
+
allow(::Kernel).to receive(:open).and_yield(StringIO.new('blah blah nullsoft blah'))
|
251
|
+
expect(provider.installer_type).to eql(:nsis)
|
252
|
+
end
|
253
|
+
|
254
|
+
context "source ends in .msi" do
|
255
|
+
let(:resource_source) { "microsoft_installer.msi" }
|
256
|
+
|
257
|
+
it "sets installer_type to msi" do
|
258
|
+
expect(provider.installer_type).to eql(:msi)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
context "the source is setup.exe" do
|
263
|
+
let(:resource_source) { "setup.exe" }
|
264
|
+
|
265
|
+
it "sets installer_type to installshield" do
|
266
|
+
allow(::Kernel).to receive(:open).and_yield(StringIO.new(''))
|
267
|
+
expect(provider.installer_type).to eql(:installshield)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
context "cannot determine the installer type" do
|
272
|
+
let(:resource_source) { "tomfoolery.now" }
|
273
|
+
|
274
|
+
it "raises an error" do
|
275
|
+
allow(::Kernel).to receive(:open).and_yield(StringIO.new(''))
|
276
|
+
provider.new_resource.installer_type(nil)
|
277
|
+
expect { provider.installer_type }.to raise_error(Chef::Exceptions::CannotDetermineWindowsInstallerType)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
describe "action_install" do
|
283
|
+
let(:new_resource) { Chef::Resource::WindowsPackage.new("blah.exe") }
|
284
|
+
before do
|
285
|
+
new_resource.installer_type(:inno)
|
286
|
+
allow_any_instance_of(Chef::Provider::Package::Windows::Exe).to receive(:package_version).and_return(new_resource.version)
|
287
|
+
end
|
288
|
+
|
289
|
+
context "no version given, discovered or installed" do
|
290
|
+
it "installs latest" do
|
291
|
+
expect(provider).to receive(:install_package).with("blah.exe", "latest")
|
292
|
+
provider.run_action(:install)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
context "no version given or discovered but package is installed" do
|
297
|
+
before { allow(provider).to receive(:current_version_array).and_return(["5.5.5"]) }
|
298
|
+
|
299
|
+
it "does not install" do
|
300
|
+
expect(provider).not_to receive(:install_package)
|
301
|
+
provider.run_action(:install)
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
context "a version is given and none is installed" do
|
306
|
+
before { new_resource.version('5.5.5') }
|
307
|
+
|
308
|
+
it "installs given version" do
|
309
|
+
expect(provider).to receive(:install_package).with("blah.exe", "5.5.5")
|
310
|
+
provider.run_action(:install)
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
context "a version is given and several are installed" do
|
315
|
+
context "given version matches an installed version" do
|
316
|
+
before do
|
317
|
+
new_resource.version('5.5.5')
|
318
|
+
allow(provider).to receive(:current_version_array).and_return([ ["5.5.5", "4.3.0", "1.1.1"] ])
|
319
|
+
end
|
320
|
+
|
321
|
+
it "does not install" do
|
322
|
+
expect(provider).not_to receive(:install_package)
|
323
|
+
provider.run_action(:install)
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
context "given version does not match an installed version" do
|
328
|
+
before do
|
329
|
+
new_resource.version('5.5.5')
|
330
|
+
allow(provider).to receive(:current_version_array).and_return([ ["5.5.0", "4.3.0", "1.1.1"] ])
|
331
|
+
end
|
332
|
+
|
333
|
+
it "installs given version" do
|
334
|
+
expect(provider).to receive(:install_package).with("blah.exe", "5.5.5")
|
335
|
+
provider.run_action(:install)
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
context "a version is given and one is installed" do
|
341
|
+
context "given version matches installed version" do
|
342
|
+
before do
|
343
|
+
new_resource.version('5.5.5')
|
344
|
+
allow(provider).to receive(:current_version_array).and_return(["5.5.5"])
|
345
|
+
end
|
346
|
+
|
347
|
+
it "does not install" do
|
348
|
+
expect(provider).not_to receive(:install_package)
|
349
|
+
provider.run_action(:install)
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
context "given version does not match installed version" do
|
354
|
+
before do
|
355
|
+
new_resource.version('5.5.5')
|
356
|
+
allow(provider).to receive(:current_version_array).and_return(["5.5.0"])
|
357
|
+
end
|
358
|
+
|
359
|
+
it "installs given version" do
|
360
|
+
expect(provider).to receive(:install_package).with("blah.exe", "5.5.5")
|
361
|
+
provider.run_action(:install)
|
362
|
+
end
|
363
|
+
end
|
163
364
|
end
|
164
365
|
end
|
165
366
|
end
|