summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Wrock <matt@mattwrock.com>2016-01-14 16:09:52 -0800
committerMatt Wrock <matt@mattwrock.com>2016-01-14 16:09:52 -0800
commitc0e4c98ed9630edda0d2285897a7dc6af57e26b7 (patch)
tree5e90a045a265a456e57aacae654b0d4d1d92cda4
parentbaa5901edd8d5530bba29046a8b68d5225232a7c (diff)
parentdd42bd9e51aab845e3be980a3a130382adeee1e4 (diff)
downloadchef-c0e4c98ed9630edda0d2285897a7dc6af57e26b7.tar.gz
Merge pull request #4377 from chef/choco_func_tests
fixing candidate filtering and adding functional tests for chocolatey_package
-rw-r--r--lib/chef/provider/package/chocolatey.rb33
-rw-r--r--spec/functional/assets/chocolatey_feed/test-A.1.0.nupkgbin0 -> 2667 bytes
-rw-r--r--spec/functional/assets/chocolatey_feed/test-A.1.5.nupkgbin0 -> 2669 bytes
-rw-r--r--spec/functional/assets/chocolatey_feed/test-A.2.0.nupkgbin0 -> 2667 bytes
-rw-r--r--spec/functional/assets/chocolatey_feed/test-B.1.0.nupkgbin0 -> 2667 bytes
-rw-r--r--spec/functional/resource/chocolatey_package_spec.rb121
-rw-r--r--spec/unit/provider/package/chocolatey_spec.rb25
7 files changed, 162 insertions, 17 deletions
diff --git a/lib/chef/provider/package/chocolatey.rb b/lib/chef/provider/package/chocolatey.rb
index 55ac304a79..3bf2ced297 100644
--- a/lib/chef/provider/package/chocolatey.rb
+++ b/lib/chef/provider/package/chocolatey.rb
@@ -66,7 +66,7 @@ class Chef
# @param names [Array<String>] array of package names to install
# @param versions [Array<String>] array of versions to install
def install_package(names, versions)
- name_versions_to_install = desired_name_versions.select { |n, v| names.include?(n) }
+ name_versions_to_install = desired_name_versions.select { |n, v| lowercase_names(names).include?(n) }
name_nil_versions = name_versions_to_install.select { |n,v| v.nil? }
name_has_versions = name_versions_to_install.reject { |n,v| v.nil? }
@@ -88,7 +88,7 @@ class Chef
# @param names [Array<String>] array of package names to install
# @param versions [Array<String>] array of versions to install
def upgrade_package(names, versions)
- name_versions_to_install = desired_name_versions.select { |n, v| names.include?(n) }
+ name_versions_to_install = desired_name_versions.select { |n, v| lowercase_names(names).include?(n) }
name_nil_versions = name_versions_to_install.select { |n,v| v.nil? }
name_has_versions = name_versions_to_install.reject { |n,v| v.nil? }
@@ -181,7 +181,7 @@ class Chef
# @return [Hash] Mapping of requested names to versions
def desired_name_versions
desired_versions = new_resource.version || new_resource.package_name.map { nil }
- Hash[*new_resource.package_name.zip(desired_versions).flatten]
+ Hash[*lowercase_names(new_resource.package_name).zip(desired_versions).flatten]
end
# Helper to construct optional args out of new_resource
@@ -213,8 +213,11 @@ class Chef
begin
cmd = [ "list -ar #{package_name_array.join ' '}" ]
cmd.push( "-source #{new_resource.source}" ) if new_resource.source
- parse_list_output(*cmd).reject do |name,version|
- desired_name_versions[name] && desired_name_versions[name] != version
+ parse_list_output(*cmd).each_with_object({}) do |name_version, available|
+ name, version = name_version
+ if desired_name_versions[name].nil? || desired_name_versions[name] == version
+ available[name] = version
+ end
end
end
end
@@ -224,21 +227,29 @@ class Chef
#
# @return [Hash] name-to-version mapping of installed packages
def installed_packages
- @installed_packages ||= parse_list_output("list -l -r")
+ @installed_packages ||= Hash[*parse_list_output("list -l -r").flatten]
end
# Helper to convert choco.exe list output to a Hash
# (names are downcased for case-insenstive matching)
#
# @param cmd [String] command to run
- # @return [String] list output converted to ruby Hash
+ # @return [Array] list output converted to ruby Hash
def parse_list_output(*args)
- hash = {}
+ list = []
choco_command(*args).stdout.each_line do |line|
- name, version = line.split("|")
- hash[name.downcase] = version.chomp
+ name, version = line.split('|')
+ list << [ name.downcase, version.chomp ]
end
- hash
+ list
+ end
+
+ # Helper to downcase all names in an array
+ #
+ # @param names [Array] original mixed case names
+ # @return [Array] same names in lower case
+ def lowercase_names(names)
+ names.map { |name| name.downcase }
end
end
end
diff --git a/spec/functional/assets/chocolatey_feed/test-A.1.0.nupkg b/spec/functional/assets/chocolatey_feed/test-A.1.0.nupkg
new file mode 100644
index 0000000000..a2d3e7bb4e
--- /dev/null
+++ b/spec/functional/assets/chocolatey_feed/test-A.1.0.nupkg
Binary files differ
diff --git a/spec/functional/assets/chocolatey_feed/test-A.1.5.nupkg b/spec/functional/assets/chocolatey_feed/test-A.1.5.nupkg
new file mode 100644
index 0000000000..9ce9445689
--- /dev/null
+++ b/spec/functional/assets/chocolatey_feed/test-A.1.5.nupkg
Binary files differ
diff --git a/spec/functional/assets/chocolatey_feed/test-A.2.0.nupkg b/spec/functional/assets/chocolatey_feed/test-A.2.0.nupkg
new file mode 100644
index 0000000000..250084d3ce
--- /dev/null
+++ b/spec/functional/assets/chocolatey_feed/test-A.2.0.nupkg
Binary files differ
diff --git a/spec/functional/assets/chocolatey_feed/test-B.1.0.nupkg b/spec/functional/assets/chocolatey_feed/test-B.1.0.nupkg
new file mode 100644
index 0000000000..f275c78dc6
--- /dev/null
+++ b/spec/functional/assets/chocolatey_feed/test-B.1.0.nupkg
Binary files differ
diff --git a/spec/functional/resource/chocolatey_package_spec.rb b/spec/functional/resource/chocolatey_package_spec.rb
new file mode 100644
index 0000000000..ad9025420b
--- /dev/null
+++ b/spec/functional/resource/chocolatey_package_spec.rb
@@ -0,0 +1,121 @@
+#
+# Author:: Matt Wrock (<matt@mattwrock.com>)
+# Copyright:: Copyright (c) 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::ChocolateyPackage, :windows_only do
+ include Chef::Mixin::PowershellOut
+
+ before(:all) do
+ powershell_out("iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))")
+ end
+
+ let(:package_name) { 'test-A' }
+ let(:package_list) { proc { powershell_out("choco list -lo -r #{Array(package_name).join(' ')}").stdout.chomp } }
+ let(:package_source) { File.join(CHEF_SPEC_ASSETS, 'chocolatey_feed') }
+
+ subject do
+ new_resource = Chef::Resource::ChocolateyPackage.new('test choco package', run_context)
+ new_resource.package_name package_name
+ new_resource.source package_source if package_source
+ new_resource
+ end
+
+ context 'installing a package' do
+ after { Chef::Resource::ChocolateyPackage.new(package_name, run_context).run_action(:remove) }
+
+ it 'installs the latest version' do
+ subject.run_action(:install)
+ expect(package_list.call).to eq("#{package_name}|2.0")
+ end
+
+ it 'does not install if already installed' do
+ subject.run_action(:install)
+ subject.run_action(:install)
+ expect(subject).not_to be_updated_by_last_action
+ end
+
+ it 'installs version given' do
+ subject.version '1.0'
+ subject.run_action(:install)
+ expect(package_list.call).to eq("#{package_name}|1.0")
+ end
+
+ it 'installs new version if one is already installed' do
+ subject.version '1.0'
+ subject.run_action(:install)
+ expect(package_list.call).to eq("#{package_name}|1.0")
+
+ subject.version '2.0'
+ subject.run_action(:install)
+ expect(package_list.call).to eq("#{package_name}|2.0")
+ end
+
+ context 'installing multiple packages' do
+ let(:package_name) { [ 'test-A', 'test-B' ] }
+
+ it 'installs both packages' do
+ subject.run_action(:install)
+ expect(package_list.call).to eq("test-A|2.0\r\ntest-B|1.0")
+ end
+ end
+
+ it 'raises if package is not found' do
+ subject.package_name 'blah'
+ expect{ subject.run_action(:install) }.to raise_error Chef::Exceptions::Package
+ end
+
+ it 'raises if package version is not found' do
+ subject.version '3.0'
+ expect{ subject.run_action(:install) }.to raise_error Chef::Exceptions::Package
+ end
+ end
+
+ context 'upgrading a package' do
+ after { Chef::Resource::ChocolateyPackage.new(package_name, run_context).run_action(:remove) }
+
+ it 'upgrades to a specific version' do
+ subject.version '1.0'
+ subject.run_action(:install)
+ expect(package_list.call).to eq("#{package_name}|1.0")
+
+ subject.version '1.5'
+ subject.run_action(:upgrade)
+ expect(package_list.call).to eq("#{package_name}|1.5")
+ end
+
+ it 'upgrades to the latest version if no version given' do
+ subject.version '1.0'
+ subject.run_action(:install)
+ expect(package_list.call).to eq("#{package_name}|1.0")
+
+ subject2 = Chef::Resource::ChocolateyPackage.new('test-A', run_context)
+ subject2.source package_source
+ subject2.run_action(:upgrade)
+ expect(package_list.call).to eq("#{package_name}|2.0")
+ end
+ end
+
+ context 'removing a package' do
+ it 'removes an installed package' do
+ subject.run_action(:install)
+ Chef::Resource::ChocolateyPackage.new(package_name, run_context).run_action(:remove)
+ expect(package_list.call).to eq('')
+ end
+ end
+end \ No newline at end of file
diff --git a/spec/unit/provider/package/chocolatey_spec.rb b/spec/unit/provider/package/chocolatey_spec.rb
index 406ebcd184..f8df129c6e 100644
--- a/spec/unit/provider/package/chocolatey_spec.rb
+++ b/spec/unit/provider/package/chocolatey_spec.rb
@@ -50,7 +50,8 @@ ConEmu|15.10.25.0
remote_list_stdout = <<-EOF
chocolatey|0.9.9.11
ConEmu|15.10.25.1
-git|2.6.2
+Git|2.6.1
+Git|2.6.2
munin-node|1.6.1.20130823
EOF
remote_list_obj = double(stdout: remote_list_stdout)
@@ -68,11 +69,23 @@ munin-node|1.6.1.20130823
end
describe "#candidate_version" do
- it "should set the candidate_version correctly" do
+ it "should set the candidate_version to the latest version when not pinning" do
allow_remote_list(["git"])
expect(provider.candidate_version).to eql(["2.6.2"])
end
+ it "should set the candidate_version to pinned version if available" do
+ allow_remote_list(["git"])
+ new_resource.version('2.6.1')
+ expect(provider.candidate_version).to eql(["2.6.1"])
+ end
+
+ it "should set the candidate_version to nill if pinning to bogus version" do
+ allow_remote_list(["git"])
+ new_resource.version('2.5.0')
+ expect(provider.candidate_version).to eql([nil])
+ end
+
it "should set the candidate_version to nil if there is no candidate" do
allow_remote_list(["vim"])
new_resource.package_name("vim")
@@ -209,7 +222,7 @@ munin-node|1.6.1.20130823
new_resource.package_name("ConEmu")
new_resource.version("15.10.25.1")
provider.load_current_resource
- expect(provider).to receive(:shell_out!).with("#{choco_exe} install -y -version 15.10.25.1 ConEmu", {:timeout=>timeout}).and_return(double)
+ expect(provider).to receive(:shell_out!).with("#{choco_exe} install -y -version 15.10.25.1 conemu", {:timeout=>timeout}).and_return(double)
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
end
@@ -222,7 +235,7 @@ munin-node|1.6.1.20130823
new_resource.package_name(["chocolatey", "ConEmu"])
new_resource.version([nil, "15.10.25.1"])
provider.load_current_resource
- expect(provider).to receive(:shell_out!).with("#{choco_exe} install -y -version 15.10.25.1 ConEmu", {:timeout=>timeout}).and_return(double)
+ expect(provider).to receive(:shell_out!).with("#{choco_exe} install -y -version 15.10.25.1 conemu", {:timeout=>timeout}).and_return(double)
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
end
@@ -242,7 +255,7 @@ munin-node|1.6.1.20130823
new_resource.package_name(["ConEmu", "git"])
new_resource.version(["15.10.25.1", nil])
provider.load_current_resource
- expect(provider).to receive(:shell_out!).with("#{choco_exe} install -y -version 15.10.25.1 ConEmu", {:timeout=>timeout}).and_return(double)
+ expect(provider).to receive(:shell_out!).with("#{choco_exe} install -y -version 15.10.25.1 conemu", {:timeout=>timeout}).and_return(double)
expect(provider).to receive(:shell_out!).with("#{choco_exe} install -y git", {:timeout=>timeout}).and_return(double)
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
@@ -323,7 +336,7 @@ munin-node|1.6.1.20130823
allow_remote_list(["ConEmu"])
new_resource.package_name("ConEmu")
provider.load_current_resource
- expect(provider).to receive(:shell_out!).with("#{choco_exe} upgrade -y ConEmu", {:timeout=>timeout}).and_return(double)
+ expect(provider).to receive(:shell_out!).with("#{choco_exe} upgrade -y conemu", {:timeout=>timeout}).and_return(double)
provider.run_action(:upgrade)
expect(new_resource).to be_updated_by_last_action
end