diff options
author | Matt Wrock <matt@mattwrock.com> | 2016-01-14 16:09:52 -0800 |
---|---|---|
committer | Matt Wrock <matt@mattwrock.com> | 2016-01-14 16:09:52 -0800 |
commit | c0e4c98ed9630edda0d2285897a7dc6af57e26b7 (patch) | |
tree | 5e90a045a265a456e57aacae654b0d4d1d92cda4 | |
parent | baa5901edd8d5530bba29046a8b68d5225232a7c (diff) | |
parent | dd42bd9e51aab845e3be980a3a130382adeee1e4 (diff) | |
download | chef-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.rb | 33 | ||||
-rw-r--r-- | spec/functional/assets/chocolatey_feed/test-A.1.0.nupkg | bin | 0 -> 2667 bytes | |||
-rw-r--r-- | spec/functional/assets/chocolatey_feed/test-A.1.5.nupkg | bin | 0 -> 2669 bytes | |||
-rw-r--r-- | spec/functional/assets/chocolatey_feed/test-A.2.0.nupkg | bin | 0 -> 2667 bytes | |||
-rw-r--r-- | spec/functional/assets/chocolatey_feed/test-B.1.0.nupkg | bin | 0 -> 2667 bytes | |||
-rw-r--r-- | spec/functional/resource/chocolatey_package_spec.rb | 121 | ||||
-rw-r--r-- | spec/unit/provider/package/chocolatey_spec.rb | 25 |
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 Binary files differnew file mode 100644 index 0000000000..a2d3e7bb4e --- /dev/null +++ b/spec/functional/assets/chocolatey_feed/test-A.1.0.nupkg diff --git a/spec/functional/assets/chocolatey_feed/test-A.1.5.nupkg b/spec/functional/assets/chocolatey_feed/test-A.1.5.nupkg Binary files differnew file mode 100644 index 0000000000..9ce9445689 --- /dev/null +++ b/spec/functional/assets/chocolatey_feed/test-A.1.5.nupkg diff --git a/spec/functional/assets/chocolatey_feed/test-A.2.0.nupkg b/spec/functional/assets/chocolatey_feed/test-A.2.0.nupkg Binary files differnew file mode 100644 index 0000000000..250084d3ce --- /dev/null +++ b/spec/functional/assets/chocolatey_feed/test-A.2.0.nupkg diff --git a/spec/functional/assets/chocolatey_feed/test-B.1.0.nupkg b/spec/functional/assets/chocolatey_feed/test-B.1.0.nupkg Binary files differnew file mode 100644 index 0000000000..f275c78dc6 --- /dev/null +++ b/spec/functional/assets/chocolatey_feed/test-B.1.0.nupkg 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 |