summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasu1105 <vasundhara.jagdale@clogeny.com>2016-09-07 11:32:01 +0530
committerVasu1105 <vasundhara.jagdale@clogeny.com>2016-09-30 15:10:46 +0530
commit09b44d56bc3f9285360b6b93f7798e6de4dd8dfd (patch)
treef50f4ad4403c80f8bb3db301b6c5c1bab8610055
parent09886bad1411faa86b9e716712b4dad62b8330bd (diff)
downloadchef-09b44d56bc3f9285360b6b93f7798e6de4dd8dfd.tar.gz
Added resource and provider for cab package
Reverted changes Adding resource and provider for cab file support Added method identifying package version for installation and removal of package Updated code to idetitfy installed version refactored some code Refactored code for parsing dism get package output Fixed rubocop issue, working on specs created spec files Working on unit specs Added unit specs and working on functional specs Working on functional specs and fixed rubocop errors Fixed failing unit test cases Resolved rubucop style error Removed functional specs Fixed error and working on functional specs Added missing functional spec file
-rw-r--r--lib/chef/provider/package/cab.rb147
-rw-r--r--lib/chef/provider/package/windows.rb13
-rw-r--r--lib/chef/provider/package/windows/cab.rb152
-rw-r--r--lib/chef/providers.rb1
-rw-r--r--lib/chef/resource/cab_package.rb44
-rw-r--r--lib/chef/resources.rb1
-rw-r--r--spec/functional/assets/dummy-cab-23448.cabbin0 -> 1455340 bytes
-rw-r--r--spec/functional/resource/cab_package_spec.rb54
-rw-r--r--spec/unit/provider/package/cab_spec.rb191
-rw-r--r--spec/unit/resource/cab_package_spec.rb38
10 files changed, 477 insertions, 164 deletions
diff --git a/lib/chef/provider/package/cab.rb b/lib/chef/provider/package/cab.rb
new file mode 100644
index 0000000000..f5af1a86b4
--- /dev/null
+++ b/lib/chef/provider/package/cab.rb
@@ -0,0 +1,147 @@
+#
+# Author:: Vasundhara Jagdale (<vasundhara.jagdale@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/cab_package"
+require "chef/mixin/powershell_out"
+
+class Chef
+ class Provider
+ class Package
+ class Cab < Chef::Provider::Package
+ include Chef::Mixin::PowershellOut
+
+ provides :cab_package, os: "windows"
+
+ def load_current_resource
+ @current_resource = Chef::Resource::CabPackage.new(new_resource.name)
+ current_resource.source(new_resource.source)
+ new_resource.version(package_version)
+ current_resource.version(installed_version)
+ current_resource
+ end
+
+ def install_package(name, version)
+ dism_command("/Add-Package /PackagePath:\"#{@new_resource.source}\"")
+ end
+
+ def remove_package(name, version)
+ dism_command("/Remove-Package /PackagePath:\"#{@new_resource.source}\"")
+ end
+
+ def dism_command(command)
+ powershell_out("dism.exe /Online #{command} /NoRestart", { :timeout => @new_resource.timeout })
+ end
+
+ def installed_version
+ stdout = dism_command("/Get-PackageInfo /PackagePath:\"#{@new_resource.source}\"").stdout
+ package_info = parse_dism_get_package_info(stdout)
+ # e.g. Package_for_KB2975719~31bf3856ad364e35~amd64~~6.3.1.8
+ package = split_package_identity(package_info["package_information"]["package_identity"])
+ # Search for just the package name to catch a different version being installed
+ Chef::Log.debug("#{@new_resource} searching for installed package #{package['name']}")
+ found_packages = installed_packages.select { |p| p["package_identity"] =~ /^#{package['name']}~/ }
+ if found_packages.length == 0
+ nil
+ elsif found_packages.length == 1
+ stdout = dism_command("/Get-PackageInfo /PackageName:\"#{found_packages.first["package_identity"]}\"").stdout
+ find_version(stdout)
+ else
+ # Presuming this won't happen, otherwise we need to handle it
+ raise Chef::Exceptions::Package, "Found mutliple packages installed matching name #{package['name']}, found: #{found_packages.length} matches"
+ end
+ end
+
+ def package_version
+ Chef::Log.debug("#{@new_resource} getting product version for package at #{@new_resource.source}")
+ stdout = dism_command("/Get-PackageInfo /PackagePath:\"#{@new_resource.source}\"").stdout
+ find_version(stdout)
+ end
+
+ def find_version(stdout)
+ package_info = parse_dism_get_package_info(stdout)
+ package = split_package_identity(package_info["package_information"]["package_identity"])
+ package["version"]
+ end
+
+ # returns a hash of package state information given the output of dism /get-packages
+ # expected keys: package_identity
+ def parse_dism_get_packages(text)
+ packages = Array.new
+ text.each_line do |line|
+ key, value = line.split(":") if line.start_with?("Package Identity")
+ unless key.nil? || value.nil?
+ package = Hash.new
+ package[key.downcase.strip.tr(" ", "_")] = value.strip.chomp
+ packages << package
+ end
+ end
+ packages
+ end
+
+ # returns a hash of package information given the output of dism /get-packageinfo
+ def parse_dism_get_package_info(text)
+ package_data = Hash.new
+ errors = Array.new
+ in_section = false
+ section_headers = [ "Package information", "Custom Properties", "Features" ]
+ text.each_line do |line|
+ if line =~ /Error: (.*)/
+ errors << $1
+ elsif section_headers.any? { |header| line =~ /^(#{header})/ }
+ in_section = $1.downcase.tr(" ", "_")
+ elsif line =~ /(.*) ?: (.*)/
+ v = $2 # has to be first or the gsub below replaces this variable
+ k = $1.downcase.strip.tr(" ", "_")
+ if in_section
+ package_data[in_section] = Hash.new unless package_data[in_section]
+ package_data[in_section][k] = v
+ else
+ package_data[k] = v
+ end
+ end
+ end
+ unless errors.empty?
+ if !(errors & ["0x80070003\r", "0x80070002\r"]).empty?
+ raise Chef::Exceptions::Package, "DISM: The system cannot find the path or file specified."
+ elsif errors.include?("740\r")
+ raise Chef::Exceptions::Package, "DISM: Error 740: Elevated permissions are required to run DISM."
+ else
+ raise Chef::Exceptions::Package, "Unknown errors encountered parsing DISM output: #{errors}"
+ end
+ end
+ package_data
+ end
+
+ def split_package_identity(identity)
+ data = Hash.new
+ data["name"], data["publisher"], data["arch"], data["resource_id"], data["version"] = identity.split("~")
+ data
+ end
+
+ def installed_packages
+ @packages ||= begin
+ output = dism_command("/Get-Packages").stdout
+ packages = parse_dism_get_packages(output)
+ packages
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/package/windows.rb b/lib/chef/provider/package/windows.rb
index 0a655f5238..b11bcf5192 100644
--- a/lib/chef/provider/package/windows.rb
+++ b/lib/chef/provider/package/windows.rb
@@ -21,7 +21,6 @@ require "chef/resource/windows_package"
require "chef/provider/package"
require "chef/util/path_helper"
require "chef/mixin/checksum"
-require 'pry'
class Chef
class Provider
@@ -52,6 +51,7 @@ class Chef
current_resource.version(package_provider.installed_version)
new_resource.version(package_provider.package_version) if package_provider.package_version
end
+
current_resource
end
@@ -62,10 +62,6 @@ class Chef
Chef::Log.debug("#{new_resource} is MSI")
require "chef/provider/package/windows/msi"
Chef::Provider::Package::Windows::MSI.new(resource_for_provider, uninstall_registry_entries)
- when :cab
- Chef::Log.debug("#{new_resource} is CAB")
- require "chef/provider/package/windows/cab"
- Chef::Provider::Package::Windows::CAB.new(resource_for_provider)
else
Chef::Log.debug("#{new_resource} is EXE with type '#{installer_type}'")
require "chef/provider/package/windows/exe"
@@ -82,8 +78,6 @@ class Chef
@installer_type ||= begin
return :msi if msi?
- return :cab if cab?
-
if new_resource.installer_type
new_resource.installer_type
elsif source_location.nil?
@@ -271,11 +265,6 @@ class Chef
::File.extname(source_location).casecmp(".msi").zero?
end
end
-
- def cab?
- return true if new_resource.installer_type == :cab
- ::File.extname(source_location).casecmp(".cab").zero?
- end
end
end
end
diff --git a/lib/chef/provider/package/windows/cab.rb b/lib/chef/provider/package/windows/cab.rb
deleted file mode 100644
index 856460bfc9..0000000000
--- a/lib/chef/provider/package/windows/cab.rb
+++ /dev/null
@@ -1,152 +0,0 @@
-require 'chef/mixin/windows_architecture_helper'
-require "chef/mixin/shell_out"
-require 'chef/util/path_helper'
-
-class Chef
- class Provider
- class Package
- class Windows
- class CAB
- include Chef::Mixin::ShellOut
- include Chef::Mixin::WindowsArchitectureHelper
-
- def initialize(resource)
- @new_resource = resource
- end
-
- attr_reader :new_resource
-
- def installed_version
- Chef::Log.debug("#{@new_resource} getting product version for package at #{@new_resource.source}")
- stdout = dism_command("/Get-PackageInfo /PackagePath:\"#{@new_resource.source}\"").stdout
- package_info = parse_dism_get_package_info(stdout)
- # e.g. Package_for_KB2975719~31bf3856ad364e35~amd64~~6.3.1.8
- package = split_package_identity(package_info['package_information']['package_identity'])
- # Search for just the package name to catch a different version being installed
- Chef::Log.debug("#{@new_resource} searching for installed package #{package['name']}")
- found_packages = installed_packages.select { |p| p['package_identity'] =~ /^#{package['name']}~/ }
- if found_packages.length == 0
- nil
- elsif found_packages.length == 1
- package['version']
- else
- # Presuming this won't happen, otherwise we need to handle it
- raise Chef::Exceptions::Package, "Found mutliple packages installed matching name #{package['name']}, found: #{found_packages.length} matches"
- end
- end
-
- def package_version
- Chef::Log.debug("#{@new_resource} getting product version for package at #{@new_resource.source}")
- stdout = dism_command("/Get-PackageInfo /PackagePath:\"#{@new_resource.source}\"").stdout
- package_info = parse_dism_get_package_info(stdout)
- package = split_package_identity(package_info['package_information']['package_identity'])
- package['version']
- end
-
- def install_package
- Chef::Log.info("#{@new_resource} installing Windows CAB package '#{@new_resource.source}'")
- dism_command("/Add-Package /PackagePath:\"#{@new_resource.source}\"")
- end
-
- def remove_package
- Chef::Log.debug("#{@new_resource} removing Windows CAB package '#{@new_resource.source}'")
- dism_command("/Remove-Package /PackagePath:\"#{@new_resource.source}\"")
- end
-
- # Runs a command through DISM, and returns a Mixlib::ShellOut object
- # For example, output can be accessed like dism_command("/Get-CurrentEdition").stdout
- def dism_command(command)
- shellout = Mixlib::ShellOut.new("dism.exe /Online #{command} /NoRestart", {:timeout => @new_resource.timeout, :returns => @new_resource.returns})
- with_os_architecture(@node) do
- shellout.run_command
- end
- end
-
- # returns a hash of package state information given the output of dism /get-packages
- # expected keys: package_identity, state, release_type, install_time
- def parse_dism_get_packages(text)
- packages = Array.new
- package = Hash.new
- inside_package_listing = false
- text.each_line do |line|
- # Skip the headers
- if line =~ /^Packages listing:/
- inside_package_listing = true
- next
- end
-
- next unless inside_package_listing
-
- if line.chomp.empty?
- # Between packages so save it to the collection
- unless package.empty?
- packages << package
- package = Hash.new
- end
- end
-
- if line =~ /(.*) : (.*)/
- v = $2.chomp # has to be first or the gsub below replaces this variable
- k = $1.downcase.strip.gsub(/ /,"_")
- package[k] = v
- end
- end
- packages
- end
-
- # returns a hash of package information given the output of dism /get-packageinfo
- def parse_dism_get_package_info(text)
- package_data = Hash.new
- errors = Array.new
- in_section = false
- # Version/Image Version are Windows Versions
- # TODO: Verfiy we're parsing Features in a useful way
- section_headers = [ "Package information", "Custom Properties", "Features" ]
-
- text.each_line do |line|
- if line =~ /Error: (.*)/
- errors << $1
- elsif section_headers.any? { |header| line =~ /^(#{header})/ }
- in_section = $1.downcase.gsub(/ /,"_")
- elsif line =~ /(.*) ?: (.*)/
- v = $2 # has to be first or the gsub below replaces this variable
- k = $1.downcase.strip.gsub(/ /,"_")
- if in_section
- package_data[in_section] = Hash.new unless package_data[in_section]
- package_data[in_section][k] = v
- else
- package_data[k] = v
- end
- end
- end
-
- unless errors.empty?
- if errors.include?("87")
- Chef::Log.debug("DISM: Error 87: Package unknown (not installed)")
- return nil
- else
- raise Chef::Exceptions::Package, "Unknown errors encountered parsing DISM output: #{errors}"
- end
- end
- package_data
- end
-
- def split_package_identity(identity)
- data = Hash.new
- data['name'], data['publisher'], data['arch'], data['resource_id'], data['version'] = identity.split('~')
- data
- end
-
- def installed_packages
- @@package_cache ||= begin
- # TODO: A resource attribute to invalidate the cache
- output = dism_command("/Get-Packages").stdout
- packages = parse_dism_get_packages(output)
- packages
- end
- end
- end
- end
- end
- end
-end
diff --git a/lib/chef/providers.rb b/lib/chef/providers.rb
index affa5ca2c1..596629290b 100644
--- a/lib/chef/providers.rb
+++ b/lib/chef/providers.rb
@@ -83,6 +83,7 @@ require "chef/provider/package/zypper"
require "chef/provider/package/solaris"
require "chef/provider/package/smartos"
require "chef/provider/package/aix"
+require "chef/provider/package/cab"
require "chef/provider/service/arch"
require "chef/provider/service/freebsd"
diff --git a/lib/chef/resource/cab_package.rb b/lib/chef/resource/cab_package.rb
new file mode 100644
index 0000000000..b7acfb0ec9
--- /dev/null
+++ b/lib/chef/resource/cab_package.rb
@@ -0,0 +1,44 @@
+#
+# Author:: Vasundhara Jagdale (<vasundhara.jagdale@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 CabPackage < Chef::Resource::Package
+ include Chef::Mixin::Uris
+
+ provides :cab_package, os: "windows"
+
+ allowed_actions :install, :remove
+
+ def initialize(name, run_context = nil)
+ super
+ @resource_name = :cab_package
+ end
+
+ property :source, String,
+ coerce: (proc do |s|
+ unless s.nil?
+ uri_scheme?(s) ? s : Chef::Util::PathHelper.canonical_path(s, false)
+ end
+ end)
+ end
+ end
+end
diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb
index 2afd47a8f4..9ff772353b 100644
--- a/lib/chef/resources.rb
+++ b/lib/chef/resources.rb
@@ -95,3 +95,4 @@ require "chef/resource/yum_repository"
require "chef/resource/lwrp_base"
require "chef/resource/bff_package"
require "chef/resource/zypper_package"
+require "chef/resource/cab_package"
diff --git a/spec/functional/assets/dummy-cab-23448.cab b/spec/functional/assets/dummy-cab-23448.cab
new file mode 100644
index 0000000000..41eea0b77c
--- /dev/null
+++ b/spec/functional/assets/dummy-cab-23448.cab
Binary files differ
diff --git a/spec/functional/resource/cab_package_spec.rb b/spec/functional/resource/cab_package_spec.rb
new file mode 100644
index 0000000000..c0750ed480
--- /dev/null
+++ b/spec/functional/resource/cab_package_spec.rb
@@ -0,0 +1,54 @@
+#
+# Author:: Vasundhara Jagdale (<vasundhara.jagdale@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 "spec_helper"
+require "chef/mixin/powershell_out"
+
+describe Chef::Resource::CabPackage, :windows_only do
+ include Chef::Mixin::PowershellOut
+
+ let(:package_source) { File.join(CHEF_SPEC_ASSETS, "dummy-cab-23448.cab") }
+
+ let(:new_resource) do
+ new_resource = Chef::Resource::CabPackage.new("test-package", run_context)
+ new_resource.source = package_source
+ new_resource
+ end
+
+ let(:installed_version) { proc { stdout = powershell_out!("dism.exe /Online /Get-PackageInfo /PackagePath:\"#{new_resource.source}\" /NoRestart").stdout } }
+
+ context "installing package" do
+ after { remove_package }
+
+ it "installs the package" do
+ new_resource.run_action(:install)
+ expect(new_resource).to be_updated_by_last_action
+ end
+
+ it "raises error if package is not found" do
+ new_resource.source = File.join(CHEF_SPEC_ASSETS, "test.cab")
+ expect { new_resource.run_action(:install) }.to raise_error Chef::Exceptions::Package
+ end
+ end
+end
+
+def remove_package
+ pkg_to_remove = Chef::Resource::CabPackage.new("test-package", run_context)
+ pkg_to_remove.source = package_source
+ pkg_to_remove.run_action(:remove)
+end
diff --git a/spec/unit/provider/package/cab_spec.rb b/spec/unit/provider/package/cab_spec.rb
new file mode 100644
index 0000000000..9ce0c77485
--- /dev/null
+++ b/spec/unit/provider/package/cab_spec.rb
@@ -0,0 +1,191 @@
+#
+# Author:: Vasundhara Jagdale (<vasundhara.jagdale@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::Provider::Package::Cab do
+ let(:timeout) {}
+
+ let(:new_resource) { Chef::Resource::CabPackage.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::Cab.new(new_resource, run_context)
+ end
+
+ let(:installed_package_list_stdout) do
+ <<-EOF
+Packages listing:
+Package Identity : Package_for_KB2999486~31bf3856ad364e35~amd64~~6.1.9768.0
+Package Identity : Package_for_KB2994825~31bf3856ad364e35~amd64~~6.1.7601.0
+ EOF
+ end
+
+ let(:package_version_stdout) do
+ <<-EOF
+Package information:
+Package Identity : Package_for_KB2664825~31bf3856ad364e35~amd64~~6.1.3.0
+State : Installed
+Dependency : Language Pack
+The operation completed successfully
+ EOF
+ end
+
+ before do
+ new_resource.source = "C:\\Temp\\Test6.1-KB2664825-v3-x64.cab"
+ installed_package_list_obj = double(stdout: installed_package_list_stdout)
+ allow(provider).to receive(:powershell_out).with("dism.exe /Online /Get-Packages /NoRestart", { timeout: timeout }).and_return(installed_package_list_obj)
+ package_version_obj = double(stdout: package_version_stdout)
+ allow(provider).to receive(:powershell_out).with("dism.exe /Online /Get-PackageInfo /PackagePath:\"#{new_resource.source}\" /NoRestart", { timeout: timeout }).and_return(package_version_obj)
+ end
+
+ def allow_package_info(package_path = nil, package_name = nil)
+ get_pakage_info_stdout = <<-EOF
+Deployment Image Servicing and Management tool
+Version: 6.1.7600.16385
+
+Image Version: 6.1.7600.16385
+
+Package information:
+Package Identity : Package_for_KB2664825~31bf3856ad364e35~amd64~~6.1.3.0
+Applicable : Yes
+Copyright : Microsoft Corporation
+Company : Microsoft Corporation
+State : Installed
+Dependency : Language Pack
+The operation completed successfully
+ EOF
+ get_pakage_info_obj = double(stdout: get_pakage_info_stdout)
+ if package_path
+ allow(provider).to receive(:powershell_out).with("dism.exe /Online /Get-PackageInfo /PackagePath:\"#{package_path}\" /NoRestart", { timeout: timeout }).and_return(get_pakage_info_obj)
+ else
+ allow(provider).to receive(:powershell_out).with("dism.exe /Online /Get-PackageInfo /PackageName:\"#{package_name}\" /NoRestart", { timeout: timeout }).and_return(get_pakage_info_obj)
+ end
+ end
+
+ def allow_get_packags
+ get_packages_stdout = <<-EOF
+Deployment Image Servicing and Management tool
+Version: 6.1.7600.16385
+
+Image Version: 6.1.7600.16385
+
+Packages listing:
+
+Package Identity : Package_for_KB2999486~31bf3856ad364e35~amd64~~6.1.9768.0
+State : Installed
+Release Type : Language Pack
+Install Time : 2/11/2015 11:33 PM
+
+Package Identity : Package_for_KB2994825~31bf3856ad364e35~amd64~~6.1.7601.0
+State : Installed
+Release Type : Language Pack
+Install Time : 2/11/2015 11:33 PM
+
+Package Identity : Package_for_KB2664825~31bf3856ad364e35~amd64~~6.1.3.0
+State : Installed
+Release Type : Feature Pack
+Install Time : 11/21/2010 3:40 AM
+
+The operation completed successfully.
+ EOF
+ get_packages_obj = double(stdout: get_packages_stdout)
+ allow(provider).to receive(:powershell_out).with("dism.exe /Online /Get-Packages /NoRestart", { timeout: timeout }).and_return(get_packages_obj)
+ end
+
+ describe "#load_current_resource" do
+ it "returns a current_resource" do
+ expect(provider.load_current_resource).to be_kind_of(Chef::Resource::CabPackage)
+ end
+
+ it "sets the current_resource.version to nil when the package is not installed" do
+ provider.load_current_resource
+ expect(provider.current_resource.version).to eql(nil)
+ end
+
+ it "sets the new resource package version" do
+ provider.load_current_resource
+ expect(provider.new_resource.version).to eql("6.1.3.0")
+ end
+ end
+
+ describe "#initialize" do
+ it "returns the correct class" do
+ expect(provider).to be_kind_of(Chef::Provider::Package::Cab)
+ end
+ end
+
+ describe "#package_version" do
+ it "returns the new package version" do
+ allow_package_info(new_resource.source, nil)
+ expect(provider.package_version).to eql("6.1.3.0")
+ end
+ end
+
+ describe "#installed_version" do
+ it "returns the current installed version of package" do
+ allow_package_info(new_resource.source, nil)
+ allow_get_packags
+ allow_package_info(nil, "Package_for_KB2664825~31bf3856ad364e35~amd64~~6.1.3.0")
+ expect(provider.installed_version).to eql("6.1.3.0")
+ end
+ end
+
+ describe "#action_remove" do
+ it "does nothing when the package is already removed" do
+ 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 packages if package is installed" do
+ allow_package_info(new_resource.source, nil)
+ allow_get_packags
+ allow_package_info(nil, "Package_for_KB2664825~31bf3856ad364e35~amd64~~6.1.3.0")
+ provider.load_current_resource
+ expect(provider.installed_version).not_to eql(nil)
+ expect(provider).to receive(:remove_package)
+ provider.run_action(:remove)
+ expect(new_resource).to be_updated_by_last_action
+ end
+ end
+
+ describe "#action_install" do
+ it "installs package if already not installed" do
+ provider.load_current_resource
+ expect(provider.installed_version).to eql(nil)
+ expect(provider).to receive(:install_package)
+ provider.run_action(:install)
+ expect(new_resource).to be_updated_by_last_action
+ end
+
+ it "does not install package if already installed" do
+ allow_package_info(new_resource.source, nil)
+ allow_get_packags
+ allow_package_info(nil, "Package_for_KB2664825~31bf3856ad364e35~amd64~~6.1.3.0")
+ provider.load_current_resource
+ expect(provider.installed_version).not_to eql(nil)
+ expect(provider).not_to receive(:install_package)
+ provider.run_action(:install)
+ expect(new_resource).not_to be_updated_by_last_action
+ end
+ end
+end
diff --git a/spec/unit/resource/cab_package_spec.rb b/spec/unit/resource/cab_package_spec.rb
new file mode 100644
index 0000000000..aa4890f171
--- /dev/null
+++ b/spec/unit/resource/cab_package_spec.rb
@@ -0,0 +1,38 @@
+#
+# Author:: Vasundhara Jagdale (<vasundhara.jagdale@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::CabPackage do
+
+ let(:resource) { Chef::Resource::CabPackage.new("test_pkg") }
+
+ it "creates a new Chef::Resource::CabPackage" 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::CabPackage)
+ end
+
+ it "sets resource name as :cab_package" do
+ expect(resource.resource_name).to eql(:cab_package)
+ end
+
+ it "coerce its name to a package_name" do
+ expect(resource.package_name).to eql("test_pkg")
+ end
+end