summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan McLellan <btm@loftninjas.org>2016-11-11 08:51:36 -0500
committerGitHub <noreply@github.com>2016-11-11 08:51:36 -0500
commit9ab43c91221f05cd0912c03e37eff153b6572403 (patch)
tree51d89c27e627b70309e81c0be34b469a0446b8c6
parent7e112b9542f3103c50990c3af337ce5575827e74 (diff)
parenta067259401905a42babd8ae083682b4e83185b7e (diff)
downloadchef-9ab43c91221f05cd0912c03e37eff153b6572403.tar.gz
Merge pull request #5315 from MsysTechnologiesllc/dh/adding_powershell_package_manager_support
Adding support for Powershell package manager to Chef package provider
-rw-r--r--lib/chef/provider/package/powershell.rb114
-rw-r--r--lib/chef/providers.rb1
-rw-r--r--lib/chef/resource/powershell_package.rb41
-rw-r--r--lib/chef/resources.rb1
-rw-r--r--spec/unit/provider/package/powershell_spec.rb337
-rw-r--r--spec/unit/resource/powershell_package_spec.rb68
6 files changed, 562 insertions, 0 deletions
diff --git a/lib/chef/provider/package/powershell.rb b/lib/chef/provider/package/powershell.rb
new file mode 100644
index 0000000000..5206b5b696
--- /dev/null
+++ b/lib/chef/provider/package/powershell.rb
@@ -0,0 +1,114 @@
+# Author:: Dheeraj Dubey(dheeraj.dubey@msystechnologies.com)
+# Copyright:: Copyright 2015-2016, Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require "chef/provider/package"
+require "chef/resource/powershell_package"
+require "chef/mixin/powershell_out"
+
+class Chef
+ class Provider
+ class Package
+ class Powershell < Chef::Provider::Package
+ include Chef::Mixin::PowershellOut
+
+ provides :powershell_package, os: "windows"
+
+ def load_current_resource
+ @current_resource = Chef::Resource::PowershellPackage.new(new_resource.name)
+ current_resource.package_name(new_resource.package_name)
+ current_resource.version(build_current_versions)
+ current_resource
+ end
+
+ def define_resource_requirements
+ super
+ if powershell_out("$PSVersionTable.PSVersion.Major").stdout.strip().to_i < 5
+ raise "Minimum installed Powershell Version required is 5"
+ end
+ requirements.assert(:install) do |a|
+ a.assertion { candidates_exist_for_all_uninstalled? }
+ a.failure_message(Chef::Exceptions::Package, "No candidate version available for #{packages_missing_candidates.join(", ")}")
+ a.whyrun("Assuming a repository that offers #{packages_missing_candidates.join(", ")} would have been configured")
+ end
+ end
+
+ def candidate_version
+ @candidate_version ||= build_candidate_versions
+ end
+
+ # Installs the package specified with the version passed else latest version will be installed
+ def install_package(names, versions)
+ names.each_with_index do |name, index|
+ powershell_out("Install-Package '#{name}' -Force -ForceBootstrap -RequiredVersion #{versions[index]}", { :timeout => @new_resource.timeout })
+ end
+ end
+
+ # Removes the package for the version passed and if no version is passed, then all installed versions of the package are removed
+ def remove_package(names, versions)
+ names.each_with_index do |name, index|
+ if versions && versions[index] != nil
+ powershell_out( "Uninstall-Package '#{name}' -Force -ForceBootstrap -RequiredVersion #{versions[index]}", { :timeout => @new_resource.timeout })
+ else
+ version = "0"
+ until version.empty?
+ version = powershell_out( "(Uninstall-Package '#{name}' -Force -ForceBootstrap | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => @new_resource.timeout }).stdout.strip()
+ if !version.empty?
+ Chef::Log.info("Removed package '#{name}' with version #{version}")
+ end
+ end
+ end
+ end
+ end
+
+ # Returns array of available available online
+ def build_candidate_versions
+ versions = []
+ new_resource.package_name.each_with_index do |name, index|
+ if new_resource.version && new_resource.version[index] != nil
+ version = powershell_out("(Find-Package '#{name}' -RequiredVersion #{new_resource.version[index]} -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => @new_resource.timeout }).stdout.strip()
+ else
+ version = powershell_out("(Find-Package '#{name}' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => @new_resource.timeout }).stdout.strip()
+ end
+ if version.empty?
+ version = nil
+ end
+ versions.push(version)
+ end
+ versions
+ end
+
+ # Returns version array of installed version on the system
+ def build_current_versions
+ version_list = []
+ new_resource.package_name.each_with_index do |name, index|
+ if new_resource.version && new_resource.version[index] != nil
+ version = powershell_out("(Get-Package -Name '#{name}' -RequiredVersion #{new_resource.version[index]} -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => @new_resource.timeout }).stdout.strip()
+ else
+ version = powershell_out("(Get-Package -Name '#{name}' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => @new_resource.timeout }).stdout.strip()
+ end
+ if version.empty?
+ version = nil
+ end
+ version_list.push(version)
+ end
+ version_list
+ end
+
+ end
+ end
+ end
+end
diff --git a/lib/chef/providers.rb b/lib/chef/providers.rb
index 596629290b..8067643bab 100644
--- a/lib/chef/providers.rb
+++ b/lib/chef/providers.rb
@@ -84,6 +84,7 @@ require "chef/provider/package/solaris"
require "chef/provider/package/smartos"
require "chef/provider/package/aix"
require "chef/provider/package/cab"
+require "chef/provider/package/powershell"
require "chef/provider/service/arch"
require "chef/provider/service/freebsd"
diff --git a/lib/chef/resource/powershell_package.rb b/lib/chef/resource/powershell_package.rb
new file mode 100644
index 0000000000..4d658d3cc5
--- /dev/null
+++ b/lib/chef/resource/powershell_package.rb
@@ -0,0 +1,41 @@
+# Author:: Dheeraj Dubey(dheeraj.dubey@msystechnologies.com)
+# Copyright:: Copyright 2008-2016, Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require "chef/resource/package"
+require "chef/mixin/uris"
+
+class Chef
+ class Resource
+ class PowershellPackage < Chef::Resource::Package
+ include Chef::Mixin::Uris
+
+ provides :powershell_package, os: "windows"
+
+ allowed_actions :install, :remove
+
+ def initialize(name, run_context = nil)
+ super
+ @resource_name = :powershell_package
+ end
+
+ property :package_name, [String, Array], coerce: proc { |x| [x].flatten }
+
+ property :version, [String, Array], coerce: proc { |x| [x].flatten }
+
+ end
+ end
+end
diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb
index 9ff772353b..6634a298d1 100644
--- a/lib/chef/resources.rb
+++ b/lib/chef/resources.rb
@@ -96,3 +96,4 @@ require "chef/resource/lwrp_base"
require "chef/resource/bff_package"
require "chef/resource/zypper_package"
require "chef/resource/cab_package"
+require "chef/resource/powershell_package"
diff --git a/spec/unit/provider/package/powershell_spec.rb b/spec/unit/provider/package/powershell_spec.rb
new file mode 100644
index 0000000000..4ab100f07f
--- /dev/null
+++ b/spec/unit/provider/package/powershell_spec.rb
@@ -0,0 +1,337 @@
+#
+# Author:: Dheeraj Dubey(<dheeraj.dubey@msystechnologies.com>)
+# Copyright:: Copyright 2008-2016, Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require "spec_helper"
+require "chef/mixin/powershell_out"
+
+describe Chef::Provider::Package::Powershell do
+ include Chef::Mixin::PowershellOut
+ let(:timeout) { 900 }
+
+ let(:new_resource) { Chef::Resource::PowershellPackage.new("windows_test_pkg") }
+
+ let(:provider) do
+ node = Chef::Node.new
+ events = Chef::EventDispatch::Dispatcher.new
+ run_context = Chef::RunContext.new(node, {}, events)
+ Chef::Provider::Package::Powershell.new(new_resource, run_context)
+ end
+
+ let(:package_xcertificate_installed) do
+ double("powershell_out", :stdout => "2.1.0.0\r\n")
+ end
+
+ let(:package_xcertificate_installed_2_0_0_0) do
+ double("powershell_out", :stdout => "2.0.0.0\r\n")
+ end
+
+ let(:package_xcertificate_available) do
+ double("powershell_out", :stdout => "2.1.0.0\r\n")
+ end
+
+ let(:package_xcertificate_available_2_0_0_0) do
+ double("powershell_out", :stdout => "2.0.0.0\r\n")
+ end
+
+ let(:package_xcertificate_not_installed) do
+ double("powershell_out", :stdout => "")
+ end
+
+ let(:package_xcertificate_not_available) do
+ double("powershell_out", :stdout => "")
+ end
+
+ let(:package_xnetworking_installed) do
+ double("powershell_out", :stdout => "2.12.0.0\r\n")
+ end
+
+ let(:package_xnetworking_installed_2_11_0_0) do
+ double("powershell_out", :stdout => "2.11.0.0\r\n")
+ end
+
+ let(:package_xnetworking_available) do
+ double("powershell_out", :stdout => "2.12.0.0\r\n")
+ end
+
+ let(:package_xnetworking_available_2_11_0_0) do
+ double("powershell_out", :stdout => "2.11.0.0\r\n")
+ end
+
+ let(:package_xnetworking_not_installed) do
+ double("powershell_out", :stdout => "")
+ end
+
+ let(:package_xnetworking_not_available) do
+ double("powershell_out", :stdout => "")
+ end
+
+ let(:package_7zip_available) do
+ double("powershell_out", :stdout => "16.02\r\n")
+ end
+
+ let(:package_7zip_not_installed) do
+ double("powershell_out", :stdout => "")
+ end
+
+ let(:powershell_installed_version) do
+ double("powershell_out", :stdout => "5")
+ end
+
+ describe "#initialize" do
+ it "should return the correct class" do
+ expect(provider).to be_kind_of(Chef::Provider::Package::Powershell)
+ end
+ end
+
+ describe "#candidate_version" do
+
+ it "should set the candidate_version to the latest version when not pinning" do
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xNetworking' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xnetworking_available)
+ new_resource.package_name(["xNetworking"])
+ new_resource.version(nil)
+ expect(provider.candidate_version).to eql(["2.12.0.0"])
+ end
+
+ it "should set the candidate_version to the latest version when not pinning and package name is space seperated" do
+ allow(provider).to receive(:powershell_out).with("(Find-Package '7-Zip 16.02 (x64)' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_7zip_available)
+ new_resource.package_name(["7-Zip 16.02 (x64)"])
+ new_resource.version(nil)
+ expect(provider.candidate_version).to eql(["16.02"])
+ end
+
+ it "should set the candidate_version to pinned version if available" do
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xCertificate' -RequiredVersion 2.0.0.0 -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_available_2_0_0_0)
+ new_resource.package_name(["xCertificate"])
+ new_resource.version(["2.0.0.0"])
+ expect(provider.candidate_version).to eql(["2.0.0.0"])
+ end
+
+ it "should set the candidate_version to nil if there is no candidate" do
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_not_available)
+ new_resource.package_name(["xCertificate"])
+ expect(provider.candidate_version).to eql([nil])
+ end
+
+ it "should set the candidate_version correctly when there are two packages to install" do
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_available)
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xNetworking' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xnetworking_available)
+ new_resource.package_name(%w{xCertificate xNetworking})
+ new_resource.version(nil)
+ expect(provider.candidate_version).to eql(["2.1.0.0", "2.12.0.0"])
+ end
+
+ it "should set the candidate_version correctly when only the first is installable" do
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_available)
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xNetworking' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xnetworking_not_available)
+ new_resource.package_name(%w{xCertificate xNetworking})
+ new_resource.version(nil)
+ expect(provider.candidate_version).to eql(["2.1.0.0", nil])
+ end
+
+ it "should set the candidate_version correctly when only the last is installable" do
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_not_available)
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xNetworking' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xnetworking_available)
+ new_resource.package_name(%w{xCertificate xNetworking})
+ new_resource.version(nil)
+ expect(provider.candidate_version).to eql([nil, "2.12.0.0"])
+ end
+
+ it "should set the candidate_version correctly when neither are is installable and version is passed as nil array" do
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_not_available)
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xNetworking' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xnetworking_not_available)
+ new_resource.package_name(%w{xNetworking xCertificate})
+ new_resource.version([nil, nil])
+ expect(provider.candidate_version).to eql([nil, nil])
+ end
+
+ it "should set the candidate_version correctly when neither are is installable and version is not passed" do
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_not_available)
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xNetworking' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xnetworking_not_available)
+ new_resource.package_name(%w{xNetworking xCertificate})
+ new_resource.version(nil)
+ expect(provider.candidate_version).to eql([nil, nil])
+ end
+
+ end
+
+ describe "#action_install" do
+ it "should install a single package" do
+ provider.load_current_resource
+ new_resource.package_name(["xCertificate"])
+ new_resource.version(nil)
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_available)
+ allow(provider).to receive(:powershell_out).with("(Get-Package -Name 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_not_available)
+ allow(provider).to receive(:powershell_out).with("$PSVersionTable.PSVersion.Major").and_return(powershell_installed_version)
+ expect(provider).to receive(:powershell_out).with("Install-Package 'xCertificate' -Force -ForceBootstrap -RequiredVersion 2.1.0.0", { :timeout => new_resource.timeout })
+ provider.run_action(:install)
+ expect(new_resource).to be_updated_by_last_action
+ end
+
+ it "should install a single package when package name has space in between" do
+ provider.load_current_resource
+ new_resource.package_name(["7-Zip 16.02 (x64)"])
+ new_resource.version(nil)
+ allow(provider).to receive(:powershell_out).with("(Find-Package '7-Zip 16.02 (x64)' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_7zip_available)
+ allow(provider).to receive(:powershell_out).with("(Get-Package -Name '7-Zip 16.02 (x64)' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_7zip_not_installed)
+ allow(provider).to receive(:powershell_out).with("$PSVersionTable.PSVersion.Major").and_return(powershell_installed_version)
+ expect(provider).to receive(:powershell_out).with("Install-Package '7-Zip 16.02 (x64)' -Force -ForceBootstrap -RequiredVersion 16.02", { :timeout => new_resource.timeout })
+ provider.run_action(:install)
+ expect(new_resource).to be_updated_by_last_action
+ end
+
+ context "when changing the timeout to 3600" do
+ let(:timeout) { 3600 }
+ it "sets the timeout on shell_out commands" do
+ new_resource.timeout(timeout)
+ provider.load_current_resource
+ new_resource.package_name(["xCertificate"])
+ new_resource.version(nil)
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_available)
+ allow(provider).to receive(:powershell_out).with("(Get-Package -Name 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_not_available)
+ allow(provider).to receive(:powershell_out).with("$PSVersionTable.PSVersion.Major").and_return(powershell_installed_version)
+ expect(provider).to receive(:powershell_out).with("Install-Package 'xCertificate' -Force -ForceBootstrap -RequiredVersion 2.1.0.0", { :timeout => new_resource.timeout })
+ provider.run_action(:install)
+ expect(new_resource).to be_updated_by_last_action
+ end
+ end
+
+ it "should not install packages that are up-to-date" do
+ new_resource.package_name(["xCertificate"])
+ new_resource.version(nil)
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_available)
+ allow(provider).to receive(:powershell_out).with("(Get-Package -Name 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_available)
+ allow(provider).to receive(:powershell_out).with("$PSVersionTable.PSVersion.Major").and_return(powershell_installed_version)
+ provider.load_current_resource
+ expect(provider).not_to receive(:install_package)
+ provider.run_action(:install)
+ expect(new_resource).not_to be_updated_by_last_action
+ end
+
+ it "should not install packages that are up-to-date" do
+ new_resource.package_name(["xNetworking"])
+ new_resource.version(["2.11.0.0"])
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xNetworking' -RequiredVersion 2.11.0.0 -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_available)
+ allow(provider).to receive(:powershell_out).with("(Get-Package -Name 'xNetworking' -RequiredVersion 2.11.0.0 -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xnetworking_available_2_11_0_0)
+ allow(provider).to receive(:powershell_out).with("$PSVersionTable.PSVersion.Major").and_return(powershell_installed_version)
+ provider.load_current_resource
+ expect(provider).not_to receive(:install_package)
+ provider.run_action(:install)
+ expect(new_resource).not_to be_updated_by_last_action
+ end
+
+ it "should handle complicated cases when the name/version array is pruned" do
+ # implicitly test that we correctly pick up new_resource.version[1] instead of
+ # new_version.resource[0]
+ new_resource.package_name(%w{xCertificate xNetworking})
+ new_resource.version([nil, "2.11.0.0"])
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_available)
+ allow(provider).to receive(:powershell_out).with("(Get-Package -Name 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_not_available)
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xNetworking' -RequiredVersion 2.11.0.0 -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xnetworking_available_2_11_0_0)
+ allow(provider).to receive(:powershell_out).with("(Get-Package -Name 'xNetworking' -RequiredVersion 2.11.0.0 -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xnetworking_not_available)
+ allow(provider).to receive(:powershell_out).with("$PSVersionTable.PSVersion.Major").and_return(powershell_installed_version)
+ expect(provider).to receive(:powershell_out).with("Install-Package 'xCertificate' -Force -ForceBootstrap -RequiredVersion 2.1.0.0", { :timeout => new_resource.timeout })
+ expect(provider).to receive(:powershell_out).with("Install-Package 'xNetworking' -Force -ForceBootstrap -RequiredVersion 2.11.0.0", { :timeout => new_resource.timeout })
+ provider.load_current_resource
+ provider.run_action(:install)
+ expect(new_resource).to be_updated_by_last_action
+ end
+
+ it "should split up commands when given two packages, one with a version pin" do
+ new_resource.package_name(%w{xCertificate xNetworking})
+ new_resource.version(["2.1.0.0", nil])
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xCertificate' -RequiredVersion 2.1.0.0 -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_available)
+ allow(provider).to receive(:powershell_out).with("(Get-Package -Name 'xCertificate' -RequiredVersion 2.1.0.0 -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_not_available)
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xNetworking' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xnetworking_available)
+ allow(provider).to receive(:powershell_out).with("(Get-Package -Name 'xNetworking' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xnetworking_not_available)
+ allow(provider).to receive(:powershell_out).with("$PSVersionTable.PSVersion.Major").and_return(powershell_installed_version)
+ expect(provider).to receive(:powershell_out).with("Install-Package 'xCertificate' -Force -ForceBootstrap -RequiredVersion 2.1.0.0", { :timeout => new_resource.timeout })
+ expect(provider).to receive(:powershell_out).with("Install-Package 'xNetworking' -Force -ForceBootstrap -RequiredVersion 2.12.0.0", { :timeout => new_resource.timeout })
+
+ provider.load_current_resource
+ provider.run_action(:install)
+ expect(new_resource).to be_updated_by_last_action
+ end
+
+ it "should do multipackage installs when given two packages without constraints" do
+ new_resource.package_name(%w{xCertificate xNetworking})
+ new_resource.version(nil)
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_available)
+ allow(provider).to receive(:powershell_out).with("(Get-Package -Name 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_not_available)
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xNetworking' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xnetworking_available)
+ allow(provider).to receive(:powershell_out).with("(Get-Package -Name 'xNetworking' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xnetworking_not_available)
+ allow(provider).to receive(:powershell_out).with("$PSVersionTable.PSVersion.Major").and_return(powershell_installed_version)
+ expect(provider).to receive(:powershell_out).with("Install-Package 'xCertificate' -Force -ForceBootstrap -RequiredVersion 2.1.0.0", { :timeout => new_resource.timeout })
+ expect(provider).to receive(:powershell_out).with("Install-Package 'xNetworking' -Force -ForceBootstrap -RequiredVersion 2.12.0.0", { :timeout => new_resource.timeout })
+ provider.load_current_resource
+ provider.run_action(:install)
+ expect(new_resource).to be_updated_by_last_action
+ end
+ end
+
+ describe "#action_remove" do
+ it "does nothing when the package is already removed" do
+ provider.load_current_resource
+ new_resource.package_name(["xCertificate"])
+ new_resource.version(["2.1.0.0"])
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xCertificate' -RequiredVersion 2.1.0.0 -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_available)
+ allow(provider).to receive(:powershell_out).with("(Get-Package -Name 'xCertificate' -RequiredVersion 2.1.0.0 -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_not_available)
+ allow(provider).to receive(:powershell_out).with("$PSVersionTable.PSVersion.Major").and_return(powershell_installed_version)
+ expect(provider).not_to receive(:remove_package)
+ provider.run_action(:remove)
+ expect(new_resource).not_to be_updated_by_last_action
+ end
+
+ it "does nothing when all the packages are already removed" do
+ new_resource.package_name(%w{xCertificate xNetworking})
+ new_resource.version(nil)
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_available)
+ allow(provider).to receive(:powershell_out).with("(Get-Package -Name 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_not_available)
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xNetworking' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xnetworking_available)
+ allow(provider).to receive(:powershell_out).with("(Get-Package -Name 'xNetworking' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xnetworking_not_available)
+ allow(provider).to receive(:powershell_out).with("$PSVersionTable.PSVersion.Major").and_return(powershell_installed_version)
+ provider.load_current_resource
+ expect(provider).not_to receive(:remove_package)
+ provider.run_action(:remove)
+ expect(new_resource).not_to be_updated_by_last_action
+ end
+
+ it "removes a package when version is specified" do
+ new_resource.package_name(["xCertificate"])
+ new_resource.version(["2.1.0.0"])
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xCertificate' -RequiredVersion 2.1.0.0 -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_available)
+ allow(provider).to receive(:powershell_out).with("(Get-Package -Name 'xCertificate' -RequiredVersion 2.1.0.0 -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_available)
+ allow(provider).to receive(:powershell_out).with("$PSVersionTable.PSVersion.Major").and_return(powershell_installed_version)
+ provider.load_current_resource
+ expect(provider).to receive(:powershell_out).with("Uninstall-Package 'xCertificate' -Force -ForceBootstrap -RequiredVersion 2.1.0.0", { :timeout => new_resource.timeout })
+ provider.run_action(:remove)
+ expect(new_resource).to be_updated_by_last_action
+ end
+
+ it "removes a package when version is not specified" do
+ new_resource.package_name(["xCertificate"])
+ new_resource.version(nil)
+ allow(provider).to receive(:powershell_out).with("(Find-Package 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_available)
+ allow(provider).to receive(:powershell_out).with("(Get-Package -Name 'xCertificate' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_available)
+ allow(provider).to receive(:powershell_out).with("$PSVersionTable.PSVersion.Major").and_return(powershell_installed_version)
+ provider.load_current_resource
+ expect(provider).to receive(:powershell_out).with("(Uninstall-Package 'xCertificate' -Force -ForceBootstrap | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => new_resource.timeout }).and_return(package_xcertificate_not_available)
+ provider.run_action(:remove)
+ expect(new_resource).to be_updated_by_last_action
+ end
+ end
+end
diff --git a/spec/unit/resource/powershell_package_spec.rb b/spec/unit/resource/powershell_package_spec.rb
new file mode 100644
index 0000000000..ff4aa991a7
--- /dev/null
+++ b/spec/unit/resource/powershell_package_spec.rb
@@ -0,0 +1,68 @@
+#
+# Author:: Dheeraj Dubey(<dheeraj.dubey@msystechnologies.com>)
+# Copyright:: Copyright 2008-2016, Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require "spec_helper"
+
+describe Chef::Resource::PowershellPackage do
+
+ let(:resource) { Chef::Resource::PowershellPackage.new("test_package") }
+
+ it "should create a new Chef::Resource::PowershellPackage" do
+ expect(resource).to be_a_kind_of(Chef::Resource)
+ expect(resource).to be_a_kind_of(Chef::Resource::Package)
+ expect(resource).to be_a_instance_of(Chef::Resource::PowershellPackage)
+ end
+
+ #to check the value of resource.resource_name
+ it "should have a resource name of :python" do
+ expect(resource.resource_name).to eql(:powershell_package)
+ end
+
+ it "should coerce its name to a package_name array" do
+ expect(resource.package_name).to eql(["test_package"])
+ end
+
+ it "the package_name setter should coerce to arrays" do
+ resource.package_name("git")
+ expect(resource.package_name).to eql(["git"])
+ end
+
+ it "the package_name setter should accept arrays" do
+ resource.package_name(%w{git unzip})
+ expect(resource.package_name).to eql(%w{git unzip})
+ end
+
+ it "the name should accept arrays" do
+ resource = Chef::Resource::PowershellPackage.new(%w{git unzip})
+ expect(resource.package_name).to eql(%w{git unzip})
+ end
+
+ it "the default version should be nil" do
+ expect(resource.version).to eql(nil)
+ end
+
+ it "the version setter should coerce to arrays" do
+ resource.version("1.2.3")
+ expect(resource.version).to eql(["1.2.3"])
+ end
+
+ it "the version setter should accept arrays" do
+ resource.version(["1.2.3", "4.5.6"])
+ expect(resource.version).to eql(["1.2.3", "4.5.6"])
+ end
+end