# # Author:: Caleb Tennis () # Copyright:: Copyright (c) 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::Portage, "load_current_resource" do before(:each) do @node = Chef::Node.new @events = Chef::EventDispatch::Dispatcher.new @run_context = Chef::RunContext.new(@node, {}, @events) @new_resource = Chef::Resource::PortagePackage.new("dev-util/git") @new_resource_without_category = Chef::Resource::PortagePackage.new("git") @current_resource = Chef::Resource::PortagePackage.new("dev-util/git") @provider = Chef::Provider::Package::Portage.new(@new_resource, @run_context) allow(Chef::Resource::PortagePackage).to receive(:new).and_return(@current_resource) end describe "when determining the current state of the package" do it "should create a current resource with the name of new_resource" do allow(::Dir).to receive(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0"]) expect(Chef::Resource::PortagePackage).to receive(:new).and_return(@current_resource) @provider.load_current_resource end it "should set the current resource package name to the new resource package name" do allow(::Dir).to receive(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0"]) expect(@current_resource).to receive(:package_name).with(@new_resource.package_name) @provider.load_current_resource end it "should return a current resource with the correct version if the package is found" do allow(::Dir).to receive(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-foobar-0.9", "/var/db/pkg/dev-util/git-1.0.0"]) @provider.load_current_resource expect(@provider.current_resource.version).to eq("1.0.0") end it "should return a current resource with the correct version if the package is found with revision" do allow(::Dir).to receive(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0-r1"]) @provider.load_current_resource expect(@provider.current_resource.version).to eq("1.0.0-r1") end it "should return a current resource with the correct version if the package is found with version with character" do allow(::Dir).to receive(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0d"]) @provider.load_current_resource expect(@provider.current_resource.version).to eq("1.0.0d") end it "should return a current resource with a nil version if the package is not found" do allow(::Dir).to receive(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/notgit-1.0.0"]) @provider.load_current_resource expect(@provider.current_resource.version).to be_nil end it "should return a package name match from /var/db/pkg/* if a category isn't specified and a match is found" do allow(::Dir).to receive(:[]).with("/var/db/pkg/*/git-*").and_return(["/var/db/pkg/dev-util/git-foobar-0.9", "/var/db/pkg/dev-util/git-1.0.0"]) @provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context) @provider.load_current_resource expect(@provider.current_resource.version).to eq("1.0.0") end it "should return a current resource with a nil version if a category isn't specified and a name match from /var/db/pkg/* is not found" do allow(::Dir).to receive(:[]).with("/var/db/pkg/*/git-*").and_return(["/var/db/pkg/dev-util/notgit-1.0.0"]) @provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context) @provider.load_current_resource expect(@provider.current_resource.version).to be_nil end it "should throw an exception if a category isn't specified and multiple packages are found" do allow(::Dir).to receive(:[]).with("/var/db/pkg/*/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0", "/var/db/pkg/funny-words/git-1.0.0"]) @provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context) expect { @provider.load_current_resource }.to raise_error(Chef::Exceptions::Package) end it "should return a current resource with a nil version if a category is specified and multiple packages are found" do allow(::Dir).to receive(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0", "/var/db/pkg/funny-words/git-1.0.0"]) @provider = Chef::Provider::Package::Portage.new(@new_resource, @run_context) @provider.load_current_resource expect(@provider.current_resource.version).to be_nil end it "should return a current resource with a nil version if a category is not specified and multiple packages from the same category are found" do allow(::Dir).to receive(:[]).with("/var/db/pkg/*/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0", "/var/db/pkg/dev-util/git-1.0.1"]) @provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context) @provider.load_current_resource expect(@provider.current_resource.version).to be_nil end end describe "once the state of the package is known" do describe Chef::Provider::Package::Portage, "candidate_version" do it "should return the candidate_version variable if already set" do @provider.candidate_version = "1.0.0" expect(@provider).not_to receive(:shell_out_compacted) @provider.candidate_version end it "should throw an exception if the exitstatus is not 0" do status = double(stdout: "", stderr: "", exitstatus: 1) allow(@provider).to receive(:shell_out_compacted).and_return(status) expect { @provider.candidate_version }.to raise_error(Chef::Exceptions::Package) end it "should find the candidate_version if a category is specified and there are no duplicates" do status = double(stdout: "dev-vcs/git-2.16.2", exitstatus: 0) expect(@provider).to receive(:shell_out_compacted).and_return(status) expect(@provider.candidate_version).to eq("2.16.2") end it "should find the candidate_version if a category is not specified and there are no duplicates" do status = double(stdout: "dev-vcs/git-2.16.2", exitstatus: 0) @provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context) expect(@provider).to receive(:shell_out_compacted).and_return(status) expect(@provider.candidate_version).to eq("2.16.2") end it "should throw an exception if a category is not specified and there are duplicates" do stderr_output = <<~EOF You specified an unqualified atom that matched multiple packages: * app-misc/sphinx * dev-python/sphinx Please use a more specific atom. EOF status = double(stdout: "", stderr: stderr_output, exitstatus: 1) @provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context) expect(@provider).to receive(:shell_out_compacted).and_return(status) expect { @provider.candidate_version }.to raise_error(Chef::Exceptions::Package) end end describe Chef::Provider::Package::Portage, "install_package" do it "should install a normally versioned package using portage" do expect(@provider).to receive(:shell_out_compacted!).with("emerge", "-g", "--color", "n", "--nospinner", "--quiet", "=dev-util/git-1.0.0", timeout: 3600) @provider.install_package("dev-util/git", "1.0.0") end it "should install a tilde versioned package using portage" do expect(@provider).to receive(:shell_out_compacted!).with("emerge", "-g", "--color", "n", "--nospinner", "--quiet", "~dev-util/git-1.0.0", timeout: 3600) @provider.install_package("dev-util/git", "~1.0.0") end it "should add options to the emerge command when specified" do expect(@provider).to receive(:shell_out_compacted!).with("emerge", "-g", "--color", "n", "--nospinner", "--quiet", "--oneshot", "=dev-util/git-1.0.0", timeout: 3600) @new_resource.options "--oneshot" @provider.install_package("dev-util/git", "1.0.0") end end describe Chef::Provider::Package::Portage, "remove_package" do it "should un-emerge the package with no version specified" do expect(@provider).to receive(:shell_out_compacted!).with("emerge", "--unmerge", "--color", "n", "--nospinner", "--quiet", "dev-util/git", timeout: 3600) @provider.remove_package("dev-util/git", nil) end it "should un-emerge the package with a version specified" do expect(@provider).to receive(:shell_out_compacted!).with("emerge", "--unmerge", "--color", "n", "--nospinner", "--quiet", "=dev-util/git-1.0.0", timeout: 3600) @provider.remove_package("dev-util/git", "1.0.0") end end end end