summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Schaumburg <pschaumburg@tecracer.de>2020-04-01 09:08:49 +0200
committerPatrick Schaumburg <pschaumburg@tecracer.de>2020-04-01 09:08:49 +0200
commitdc39395d4890fddb9996f10d9f05b743c38cf0b7 (patch)
tree7c4de5566ead30cc1f363a3b0773a1dbbe0cc4c2
parent750e035a20c17da7bb2bf473095e71e84c43d23e (diff)
parentc73fff159a28ea4df17ce76526a04733476bd88a (diff)
downloadchef-dc39395d4890fddb9996f10d9f05b743c38cf0b7.tar.gz
Merge branch 'master' into ps/windows_firewall_rule-rework
-rw-r--r--.expeditor/release.omnibus.yml2
-rw-r--r--CHANGELOG.md16
-rw-r--r--Gemfile.lock22
-rw-r--r--VERSION2
-rw-r--r--chef-bin/lib/chef-bin/version.rb2
-rw-r--r--chef-config/lib/chef-config/config.rb4
-rw-r--r--chef-config/lib/chef-config/version.rb2
-rw-r--r--chef-utils/lib/chef-utils/dsl/cloud.rb3
-rw-r--r--chef-utils/lib/chef-utils/version.rb2
-rw-r--r--chef-utils/spec/unit/dsl/cloud_spec.rb6
-rw-r--r--lib/chef/cookbook/gem_installer.rb2
-rw-r--r--lib/chef/provider/package/rubygems.rb31
-rw-r--r--lib/chef/resource/build_essential.rb87
-rw-r--r--lib/chef/resource/gem_package.rb10
-rw-r--r--lib/chef/resource/lwrp_base.rb5
-rw-r--r--lib/chef/resource/windows_share.rb2
-rw-r--r--lib/chef/version.rb2
-rw-r--r--spec/functional/resource/ifconfig_spec.rb4
-rw-r--r--spec/functional/win32/version_info_spec.rb8
-rw-r--r--spec/spec_helper.rb4
-rw-r--r--spec/support/platform_helpers.rb4
-rw-r--r--spec/unit/cookbook/gem_installer_spec.rb4
-rw-r--r--spec/unit/provider/package/rubygems_spec.rb237
-rw-r--r--spec/unit/resource/build_essential_spec.rb50
-rw-r--r--spec/unit/resource/data/InstallHistory_with_CLT.plist92
-rw-r--r--spec/unit/resource/data/InstallHistory_without_CLT.plist38
-rw-r--r--spec/unit/resource/gem_package_spec.rb6
-rw-r--r--spec/unit/resource/windows_share_spec.rb4
28 files changed, 555 insertions, 96 deletions
diff --git a/.expeditor/release.omnibus.yml b/.expeditor/release.omnibus.yml
index 5e09b706ae..0aaaa6eace 100644
--- a/.expeditor/release.omnibus.yml
+++ b/.expeditor/release.omnibus.yml
@@ -49,6 +49,7 @@ builder-to-testers-map:
ubuntu-16.04-x86_64:
- ubuntu-16.04-x86_64
- ubuntu-18.04-x86_64
+ - ubuntu-20.04-x86_64
windows-2012r2-i386:
- windows-2012r2-i386
windows-2012r2-x86_64:
@@ -56,3 +57,4 @@ builder-to-testers-map:
- windows-2012r2-x86_64
- windows-2016-x86_64
- windows-2019-x86_64
+ - windows-10-x86_64
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6516874b0c..836463ed8b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,15 +1,25 @@
<!-- usage documentation: http://expeditor-docs.es.chef.io/configuration/changelog/ -->
-<!-- latest_release 16.0.160 -->
-## [v16.0.160](https://github.com/chef/chef/tree/v16.0.160) (2020-03-26)
+<!-- latest_release 16.0.171 -->
+## [v16.0.171](https://github.com/chef/chef/tree/v16.0.171) (2020-04-01)
#### Merged Pull Requests
-- Improve chef_client_* resources [#9540](https://github.com/chef/chef/pull/9540) ([tas50](https://github.com/tas50))
+- Add Windows 10 Tester [#9564](https://github.com/chef/chef/pull/9564) ([tas50](https://github.com/tas50))
<!-- latest_release -->
<!-- release_rollup since=15.6.10 -->
### Changes not yet released to stable
#### Merged Pull Requests
+- Add Windows 10 Tester [#9564](https://github.com/chef/chef/pull/9564) ([tas50](https://github.com/tas50)) <!-- 16.0.171 -->
+- Fix functional tests on Windows 10 by matching less [#9563](https://github.com/chef/chef/pull/9563) ([btm](https://github.com/btm)) <!-- 16.0.170 -->
+- Fix cloud? helper to only report true on cloud instances [#9553](https://github.com/chef/chef/pull/9553) ([tas50](https://github.com/tas50)) <!-- 16.0.169 -->
+- Simplify the matching code per code review [#9552](https://github.com/chef/chef/pull/9552) ([tas50](https://github.com/tas50)) <!-- 16.0.168 -->
+- build_essential resource: fix macOS 10.15 and improve installation support with a new :upgrade action for macOS [#9550](https://github.com/chef/chef/pull/9550) ([tas50](https://github.com/tas50)) <!-- 16.0.167 -->
+- Remove SLES 11 support from build_essential [#9551](https://github.com/chef/chef/pull/9551) ([tas50](https://github.com/tas50)) <!-- 16.0.166 -->
+- Add Ubuntu 20.04 (x86_64) Tester [#9523](https://github.com/chef/chef/pull/9523) ([christopher-snapp](https://github.com/christopher-snapp)) <!-- 16.0.164 -->
+- Skip the ifconfig functional tests if we don&#39;t have ifconfig [#9549](https://github.com/chef/chef/pull/9549) ([tas50](https://github.com/tas50)) <!-- 16.0.163 -->
+- Fix unintuitive behavior of sources on gem resources [#9480](https://github.com/chef/chef/pull/9480) ([phiggins](https://github.com/phiggins)) <!-- 16.0.162 -->
+- Fixed windows share cannot modify frozen string bug [#9524](https://github.com/chef/chef/pull/9524) ([sanga1794](https://github.com/sanga1794)) <!-- 16.0.161 -->
- Improve chef_client_* resources [#9540](https://github.com/chef/chef/pull/9540) ([tas50](https://github.com/tas50)) <!-- 16.0.160 -->
- Add a `knife yaml convert` tool [#9508](https://github.com/chef/chef/pull/9508) ([btm](https://github.com/btm)) <!-- 16.0.159 -->
- Add missing introduced value to the new property in rhsm_register [#9534](https://github.com/chef/chef/pull/9534) ([tas50](https://github.com/tas50)) <!-- 16.0.158 -->
diff --git a/Gemfile.lock b/Gemfile.lock
index a466d33a4c..32a90151c7 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -27,12 +27,12 @@ GIT
PATH
remote: .
specs:
- chef (16.0.160)
+ chef (16.0.171)
addressable
bcrypt_pbkdf (~> 1.0)
bundler (>= 1.10)
- chef-config (= 16.0.160)
- chef-utils (= 16.0.160)
+ chef-config (= 16.0.171)
+ chef-utils (= 16.0.171)
chef-vault
chef-zero (>= 14.0.11)
diff-lcs (~> 1.2, >= 1.2.4)
@@ -61,12 +61,12 @@ PATH
train-winrm (>= 0.2.5)
tty-screen (~> 0.6)
uuidtools (~> 2.1.5)
- chef (16.0.160-universal-mingw32)
+ chef (16.0.171-universal-mingw32)
addressable
bcrypt_pbkdf (~> 1.0)
bundler (>= 1.10)
- chef-config (= 16.0.160)
- chef-utils (= 16.0.160)
+ chef-config (= 16.0.171)
+ chef-utils (= 16.0.171)
chef-vault
chef-zero (>= 14.0.11)
diff-lcs (~> 1.2, >= 1.2.4)
@@ -111,15 +111,15 @@ PATH
PATH
remote: chef-bin
specs:
- chef-bin (16.0.160)
- chef (= 16.0.160)
+ chef-bin (16.0.171)
+ chef (= 16.0.171)
PATH
remote: chef-config
specs:
- chef-config (16.0.160)
+ chef-config (16.0.171)
addressable
- chef-utils (= 16.0.160)
+ chef-utils (= 16.0.171)
fuzzyurl
mixlib-config (>= 2.2.12, < 4.0)
mixlib-shellout (>= 2.0, < 4.0)
@@ -128,7 +128,7 @@ PATH
PATH
remote: chef-utils
specs:
- chef-utils (16.0.160)
+ chef-utils (16.0.171)
GEM
remote: https://rubygems.org/
diff --git a/VERSION b/VERSION
index df75c601d4..abec1b0e1a 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-16.0.160 \ No newline at end of file
+16.0.171 \ No newline at end of file
diff --git a/chef-bin/lib/chef-bin/version.rb b/chef-bin/lib/chef-bin/version.rb
index 61f28298b1..fbf18110a4 100644
--- a/chef-bin/lib/chef-bin/version.rb
+++ b/chef-bin/lib/chef-bin/version.rb
@@ -21,7 +21,7 @@
module ChefBin
CHEFBIN_ROOT = File.expand_path("../..", __FILE__)
- VERSION = "16.0.160".freeze
+ VERSION = "16.0.171".freeze
end
#
diff --git a/chef-config/lib/chef-config/config.rb b/chef-config/lib/chef-config/config.rb
index 1ee27949bc..9c8614559d 100644
--- a/chef-config/lib/chef-config/config.rb
+++ b/chef-config/lib/chef-config/config.rb
@@ -1219,10 +1219,10 @@ module ChefConfig
default :ruby_encoding, Encoding::UTF_8
# can be set to a string or array of strings for URIs to set as rubygems sources
- default :rubygems_url, "https://www.rubygems.org"
+ default :rubygems_url, nil
# globally sets the default of the clear_sources property on the gem_package and chef_gem resources
- default :clear_gem_sources, false
+ default :clear_gem_sources, nil
# If installed via an omnibus installer, this gives the path to the
# "embedded" directory which contains all of the software packaged with
diff --git a/chef-config/lib/chef-config/version.rb b/chef-config/lib/chef-config/version.rb
index edc5a1b250..b3a2453cf4 100644
--- a/chef-config/lib/chef-config/version.rb
+++ b/chef-config/lib/chef-config/version.rb
@@ -15,5 +15,5 @@
module ChefConfig
CHEFCONFIG_ROOT = File.expand_path("../..", __FILE__)
- VERSION = "16.0.160".freeze
+ VERSION = "16.0.171".freeze
end
diff --git a/chef-utils/lib/chef-utils/dsl/cloud.rb b/chef-utils/lib/chef-utils/dsl/cloud.rb
index 734c7412aa..4b55fcdc29 100644
--- a/chef-utils/lib/chef-utils/dsl/cloud.rb
+++ b/chef-utils/lib/chef-utils/dsl/cloud.rb
@@ -30,7 +30,8 @@ module ChefUtils
# @return [Boolean]
#
def cloud?(node = __getnode)
- node.key?("cloud")
+ # cloud is always present, but nil if not on a cloud
+ !node["cloud"].nil?
end
# Return true if the current current node is in EC2.
diff --git a/chef-utils/lib/chef-utils/version.rb b/chef-utils/lib/chef-utils/version.rb
index b6567f9cdd..32ca448832 100644
--- a/chef-utils/lib/chef-utils/version.rb
+++ b/chef-utils/lib/chef-utils/version.rb
@@ -15,5 +15,5 @@
module ChefUtils
CHEFUTILS_ROOT = File.expand_path("../..", __FILE__)
- VERSION = "16.0.160".freeze
+ VERSION = "16.0.171".freeze
end
diff --git a/chef-utils/spec/unit/dsl/cloud_spec.rb b/chef-utils/spec/unit/dsl/cloud_spec.rb
index ebf24c7818..8fc6c18528 100644
--- a/chef-utils/spec/unit/dsl/cloud_spec.rb
+++ b/chef-utils/spec/unit/dsl/cloud_spec.rb
@@ -79,4 +79,10 @@ RSpec.describe ChefUtils::DSL::Cloud do
context "on softlayer" do
cloud_reports_true_for(:cloud?, :softlayer?, node: { "softlayer" => {}, "cloud" => {} })
end
+
+ context "on virtualbox" do
+ it "does not return true for cloud?" do
+ expect(described_class.cloud?({ "virtualbox" => {}, "cloud" => nil })).to be false
+ end
+ end
end
diff --git a/lib/chef/cookbook/gem_installer.rb b/lib/chef/cookbook/gem_installer.rb
index cf0177d1d5..172c1e6448 100644
--- a/lib/chef/cookbook/gem_installer.rb
+++ b/lib/chef/cookbook/gem_installer.rb
@@ -57,7 +57,7 @@ class Chef
begin
Dir.mktmpdir("chef-gem-bundle") do |dir|
File.open("#{dir}/Gemfile", "w+") do |tf|
- Array(Chef::Config[:rubygems_url] || "https://www.rubygems.org").each do |s|
+ Array(Chef::Config[:rubygems_url] || "https://rubygems.org").each do |s|
tf.puts "source '#{s}'"
end
cookbook_gems.each do |gem_name, args|
diff --git a/lib/chef/provider/package/rubygems.rb b/lib/chef/provider/package/rubygems.rb
index 60df50ddd3..fd93affd97 100644
--- a/lib/chef/provider/package/rubygems.rb
+++ b/lib/chef/provider/package/rubygems.rb
@@ -483,9 +483,23 @@ class Chef
end
end
+ ##
+ # If `include_default_source` is nil, return true if the global
+ # `rubygems_url` was set or if `clear_sources` and `source` on the
+ # resource are not set.
+ # If `include_default_source` is not nil, it has been set explicitly on
+ # the resource and that value should be used.
+ def include_default_source?
+ if new_resource.include_default_source.nil?
+ !!Chef::Config[:rubygems_url] || !(new_resource.source || new_resource.clear_sources)
+ else
+ new_resource.include_default_source
+ end
+ end
+
def gem_sources
srcs = [ new_resource.source ]
- srcs << Chef::Config[:rubygems_url] if new_resource.include_default_source
+ srcs << (Chef::Config[:rubygems_url] || "https://rubygems.org") if include_default_source?
srcs.flatten.compact
end
@@ -550,12 +564,25 @@ class Chef
new_resource.gem_binary || "gem"
end
+ ##
+ # If `clear_sources` is nil, clearing sources is implied if a `source`
+ # was added or if the global rubygems URL is set. If `clear_sources`
+ # is not nil, it has been set explicitly on the resource and its value
+ # should be used.
+ def clear_sources?
+ if new_resource.clear_sources.nil?
+ !!(new_resource.source || Chef::Config[:rubygems_url])
+ else
+ new_resource.clear_sources
+ end
+ end
+
def install_via_gem_command(name, version)
src = []
if new_resource.source.is_a?(String) && new_resource.source =~ /\.gem$/i
name = new_resource.source
else
- src << "--clear-sources" if new_resource.clear_sources
+ src << "--clear-sources" if clear_sources?
src += gem_sources.map { |s| "--source=#{s}" }
end
src_str = src.empty? ? "" : " #{src.join(" ")}"
diff --git a/lib/chef/resource/build_essential.rb b/lib/chef/resource/build_essential.rb
index a01449792d..5a41f3895b 100644
--- a/lib/chef/resource/build_essential.rb
+++ b/lib/chef/resource/build_essential.rb
@@ -15,6 +15,7 @@
#
require_relative "../resource"
+require "plist"
class Chef
class Resource
@@ -37,6 +38,13 @@ class Chef
compile_time true
end
```
+
+ Upgrade compilation packages on macOS systems
+ ```ruby
+ build_essential 'Install compilation tools' do
+ action :upgrade
+ end
+ ```
DOC
# this allows us to use build_essential without setting a name
@@ -61,23 +69,7 @@ class Chef
package "devel/m4"
package "devel/gettext"
when macos?
- unless xcode_cli_installed?
- # This script was graciously borrowed and modified from Tim Sutton's
- # osx-vm-templates at https://github.com/timsutton/osx-vm-templates/blob/b001475df54a9808d3d56d06e71b8fa3001fff42/scripts/xcode-cli-tools.sh
- execute "install XCode Command Line tools" do
- command <<-EOH.gsub(/^ {14}/, "")
- # create the placeholder file that's checked by CLI updates' .dist code
- # in Apple's SUS catalog
- touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
- # find the CLI Tools update. We tail here because sometimes there's 2 and newest is last
- PROD=$(softwareupdate -l | grep "\*.*Command Line" | tail -n 1 | awk -F"*" '{print $2}' | sed -e 's/^ *//' | tr -d '\n')
- # install it
- softwareupdate -i "$PROD" --verbose
- # Remove the placeholder to prevent perpetual appearance in the update utility
- rm -f /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
- EOH
- end
- end
+ install_xcode_cli_tools(xcode_cli_package_label) unless xcode_cli_installed?
when omnios?
package "developer/gcc48"
package "developer/object-file"
@@ -114,7 +106,6 @@ class Chef
package "pkg-config"
when suse?
package %w{ autoconf bison flex gcc gcc-c++ kernel-default-devel make m4 }
- package %w{ gcc48 gcc48-c++ } if node["platform_version"].to_i < 12
else
msg = <<-EOH
The build_essential resource does not currently support the '#{node["platform_family"]}'
@@ -128,16 +119,66 @@ class Chef
end
end
+ action :upgrade do
+ description "Upgrade build essential (Xcode Command Line) tools on macOS"
+
+ if macos?
+ pkg_label = xcode_cli_package_label
+
+ # With upgrade action we should install if it's not installed or if there's an available update.
+ # `xcode_cli_package_label` will be nil if there's no update.
+ install_xcode_cli_tools(pkg_label) if !xcode_cli_installed? || xcode_cli_package_label
+ else
+ Chef::Log.info "The build_essential resource :upgrade action is only supported on macOS systems. Skipping..."
+ end
+ end
+
action_class do
#
- # Determine if the XCode Command Line Tools are installed
+ # Install Xcode Command Line tools via softwareupdate CLI
+ #
+ # @param [String] label The label (package name) to install
+ #
+ def install_xcode_cli_tools(label)
+ # This script was graciously borrowed and modified from Tim Sutton's
+ # osx-vm-templates at https://github.com/timsutton/osx-vm-templates/blob/b001475df54a9808d3d56d06e71b8fa3001fff42/scripts/xcode-cli-tools.sh
+ execute "install Xcode Command Line tools" do
+ command <<-EOH
+ # create the placeholder file that's checked by CLI updates' .dist code
+ # in Apple's SUS catalog
+ touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
+ # install it
+ softwareupdate -i "#{label}" --verbose
+ # Remove the placeholder to prevent perpetual appearance in the update utility
+ rm -f /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
+ EOH
+ end
+ end
+
+ #
+ # Determine if the XCode Command Line Tools are installed by parsing the install history plist.
+ # We parse the plist data install of running pkgutil because we found that pkgutils doesn't always contain all the packages
#
# @return [true, false]
def xcode_cli_installed?
- cmd = Mixlib::ShellOut.new("pkgutil --pkgs=com.apple.pkg.CLTools_Executables")
- cmd.run_command
- # pkgutil returns an error if the package isn't found aka not installed
- cmd.error? ? false : true
+ packages = Plist.parse_xml(::File.open("/Library/Receipts/InstallHistory.plist", "r"))
+ packages.select! { |package| package["displayName"].match? "Command Line Tools" }
+ !packages.empty?
+ end
+
+ #
+ # Return to package label of the latest Xcode Command Line Tools update, if available
+ #
+ # @return [String, NilClass]
+ def xcode_cli_package_label
+ available_updates = shell_out("softwareupdate", "--list")
+
+ # raise if we fail to check
+ available_updates.error!
+
+ # https://rubular.com/r/UPEE5P7mZLvXNs
+ # this will return the match or nil
+ available_updates.stdout[/^\s*\* (?:Label: )?(Command Line Tools.*)/, 1]
end
end
end
diff --git a/lib/chef/resource/gem_package.rb b/lib/chef/resource/gem_package.rb
index a8e16841dc..5cd83d25fd 100644
--- a/lib/chef/resource/gem_package.rb
+++ b/lib/chef/resource/gem_package.rb
@@ -30,7 +30,7 @@ class Chef
# the source can either be a path to a package source like:
# source /var/tmp/mygem-1.2.3.4.gem
# or it can be a url rubygems source like:
- # https://www.rubygems.org
+ # https://rubygems.org
# the default has to be nil in order for the magical wiring up of the name property to
# the source pathname to work correctly.
#
@@ -41,16 +41,16 @@ class Chef
property :source, [ String, Array ],
description: "Optional. The URL, or list of URLs, at which the gem package is located. This list is added to the source configured in Chef::Config[:rubygems_url] (see also include_default_source) to construct the complete list of rubygems sources. Users in an 'airgapped' environment should set Chef::Config[:rubygems_url] to their local RubyGems mirror."
- property :clear_sources, [ TrueClass, FalseClass ],
+ property :clear_sources, [ TrueClass, FalseClass, nil ],
description: "Set to 'true' to download a gem from the path specified by the source property (and not from RubyGems).",
default: lazy { Chef::Config[:clear_gem_sources] }, desired_state: false
property :gem_binary, String, desired_state: false,
- description: "The path of a gem binary to use for the installation. By default, the same version of Ruby that is used by the #{Chef::Dist::CLIENT} will be installed."
+ description: "The path of a gem binary to use for the installation. By default, the same version of Ruby that is used by the #{Chef::Dist::CLIENT} will be installed."
- property :include_default_source, [ TrueClass, FalseClass ],
+ property :include_default_source, [ TrueClass, FalseClass, nil ],
description: "Set to 'false' to not include 'Chef::Config[:rubygems_url]'' in the sources.",
- default: true, introduced: "13.0"
+ default: nil, introduced: "13.0"
property :options, [ String, Hash, Array, nil ],
description: "Options for the gem install, either a Hash or a String. When a hash is given, the options are passed to Gem::DependencyInstaller.new, and the gem will be installed via the gems API. When a String is given, the gem will be installed by shelling out to the gem command. Using a Hash of options with an explicit gem_binary will result in undefined behavior.",
diff --git a/lib/chef/resource/lwrp_base.rb b/lib/chef/resource/lwrp_base.rb
index 152482434f..c5887e5104 100644
--- a/lib/chef/resource/lwrp_base.rb
+++ b/lib/chef/resource/lwrp_base.rb
@@ -51,7 +51,6 @@ class Chef
resource_class = Class.new(self)
resource_class.run_context = run_context
- resource_class.provides resource_name.to_sym
resource_class.class_from_file(filename)
# Make a useful string for the class (rather than <Class:312894723894>)
@@ -66,6 +65,10 @@ class Chef
LWRPBase.loaded_lwrps[filename] = true
+ # wire up the default resource name after the class is parsed only if we haven't declared one.
+ # (this ordering is important for MapCollision deprecation warnings)
+ resource_class.provides resource_name.to_sym unless Chef::ResourceResolver.includes_handler?(resource_name.to_sym, self)
+
resource_class
end
diff --git a/lib/chef/resource/windows_share.rb b/lib/chef/resource/windows_share.rb
index 1b81eaf55f..2c4d79522a 100644
--- a/lib/chef/resource/windows_share.rb
+++ b/lib/chef/resource/windows_share.rb
@@ -39,7 +39,7 @@ class Chef
# Specifies the path of the location of the folder to share. The path must be fully qualified. Relative paths or paths that contain wildcard characters are not permitted.
property :path, String,
description: "The path of the folder to share. Required when creating. If the share already exists on a different path then it is deleted and re-created.",
- coerce: proc { |p| p.gsub!(%r{/}, "\\") || p }
+ coerce: proc { |p| p.gsub(%r{/}, "\\") || p }
# Specifies an optional description of the SMB share. A description of the share is displayed by running the Get-SmbShare cmdlet. The description may not contain more than 256 characters.
property :description, String,
diff --git a/lib/chef/version.rb b/lib/chef/version.rb
index b4096d1462..6c028f7e25 100644
--- a/lib/chef/version.rb
+++ b/lib/chef/version.rb
@@ -23,7 +23,7 @@ require_relative "version_string"
class Chef
CHEF_ROOT = File.expand_path("../..", __FILE__)
- VERSION = Chef::VersionString.new("16.0.160")
+ VERSION = Chef::VersionString.new("16.0.171")
end
#
diff --git a/spec/functional/resource/ifconfig_spec.rb b/spec/functional/resource/ifconfig_spec.rb
index 23a5579311..6bb54d6276 100644
--- a/spec/functional/resource/ifconfig_spec.rb
+++ b/spec/functional/resource/ifconfig_spec.rb
@@ -1,6 +1,6 @@
#
# Author:: Kaustubh Deorukhkar (<kaustubh@clogeny.com>)
-# Copyright:: Copyright 2013-2018, Chef Software Inc.
+# Copyright:: Copyright 2013-2020, Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +23,7 @@ require "chef/mixin/shell_out"
# run this test only for following platforms.
include_flag = !(%w{amazon debian aix}.include?(ohai[:platform_family]) || (ohai[:platform_family] == "rhel" && ohai[:platform_version].to_i < 7))
-describe Chef::Resource::Ifconfig, :requires_root, external: include_flag do
+describe Chef::Resource::Ifconfig, :requires_root, :requires_ifconfig, external: include_flag do
include Chef::Mixin::ShellOut
let(:new_resource) do
diff --git a/spec/functional/win32/version_info_spec.rb b/spec/functional/win32/version_info_spec.rb
index 988339fd7a..2c5cd63357 100644
--- a/spec/functional/win32/version_info_spec.rb
+++ b/spec/functional/win32/version_info_spec.rb
@@ -32,12 +32,12 @@ describe "Chef::ReservedNames::Win32::File::VersionInfo", :windows_only do
subject { Chef::ReservedNames::Win32::File::VersionInfo.new(file_path) }
- it "file version has the same version as windows" do
- expect(subject.FileVersion).to start_with(os_version)
+ it "file version has the same major.minor version as windows" do
+ expect(subject.FileVersion).to start_with(os_version.rpartition(".").first)
end
- it "product version has the same version as windows" do
- expect(subject.ProductVersion).to start_with(os_version)
+ it "product version has the same major.minor version as windows" do
+ expect(subject.ProductVersion).to start_with(os_version.rpartition(".").first)
end
it "company is microsoft" do
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 54e0ef41b1..49e8d2f8f5 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -1,6 +1,6 @@
#
# Author:: Adam Jacob (<adam@chef.io>)
-# Copyright:: Copyright 2008-2019, Chef Software Inc.
+# Copyright:: Copyright 2008-2020, Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -198,7 +198,9 @@ RSpec.configure do |config|
config.filter_run_excluding chef: DependencyProc.with(Chef::VERSION)
config.filter_run_excluding ruby: DependencyProc.with(RUBY_VERSION)
+ # check for particular binaries we need
config.filter_run_excluding choco_installed: true unless choco_installed?
+ config.filter_run_excluding requires_ifconfig: true unless ifconfig?
running_platform_arch = `uname -m`.strip unless windows?
diff --git a/spec/support/platform_helpers.rb b/spec/support/platform_helpers.rb
index f9d8955f1e..e92da37043 100644
--- a/spec/support/platform_helpers.rb
+++ b/spec/support/platform_helpers.rb
@@ -270,6 +270,10 @@ rescue SocketError
false
end
+def ifconfig?
+ which("ifconfig")
+end
+
def choco_installed?
result = ShellHelpers.powershell_out("choco --version")
result.stderr.empty? ? true : false
diff --git a/spec/unit/cookbook/gem_installer_spec.rb b/spec/unit/cookbook/gem_installer_spec.rb
index 5cb995e33b..2733dfc862 100644
--- a/spec/unit/cookbook/gem_installer_spec.rb
+++ b/spec/unit/cookbook/gem_installer_spec.rb
@@ -78,7 +78,7 @@ describe Chef::Cookbook::GemInstaller do
it "generates a valid Gemfile when Chef::Config[:rubygems_url] is set to a String" do
expect(gem_installer).to receive(:shell_out!).and_return(shell_out)
- Chef::Config[:rubygems_url] = "https://www.rubygems.org"
+ Chef::Config[:rubygems_url] = "https://rubygems.org"
expect { gem_installer.install }.to_not raise_error
expect(bundler_dsl.dependencies.find { |d| d.name == "httpclient" }.requirements_list.length).to eql(2)
@@ -86,7 +86,7 @@ describe Chef::Cookbook::GemInstaller do
it "generates a valid Gemfile when Chef::Config[:rubygems_url] is set to an Array" do
expect(gem_installer).to receive(:shell_out!).and_return(shell_out)
- Chef::Config[:rubygems_url] = [ "https://www.rubygems.org" ]
+ Chef::Config[:rubygems_url] = [ "https://rubygems.org" ]
expect { gem_installer.install }.to_not raise_error
diff --git a/spec/unit/provider/package/rubygems_spec.rb b/spec/unit/provider/package/rubygems_spec.rb
index 1bafefe5e8..54b721ed40 100644
--- a/spec/unit/provider/package/rubygems_spec.rb
+++ b/spec/unit/provider/package/rubygems_spec.rb
@@ -363,7 +363,7 @@ describe Chef::Provider::Package::Rubygems do
let(:bindir) { "/usr/bin" }
let(:options) { nil }
let(:source) { nil }
- let(:include_default_source) { true }
+ let(:include_default_source) { nil }
let(:new_resource) do
new_resource = Chef::Resource::GemPackage.new(gem_name)
@@ -585,7 +585,7 @@ describe Chef::Provider::Package::Rubygems do
it "determines the candidate version by querying the remote gem servers" do
expect(provider.gem_env).to receive(:candidate_version_from_remote)
- .with(gem_dep, source, Chef::Config[:rubygems_url])
+ .with(gem_dep, source)
.and_return(Gem::Version.new(target_version))
expect(provider.candidate_version).to eq(target_version)
end
@@ -605,7 +605,7 @@ describe Chef::Provider::Package::Rubygems do
it "determines the candidate version by querying the remote gem servers" do
expect(provider.gem_env).to receive(:candidate_version_from_remote)
- .with(gem_dep, *[source, Chef::Config[:rubygems_url] ].flatten)
+ .with(gem_dep, *source)
.and_return(Gem::Version.new(target_version))
expect(provider.candidate_version).to eq(target_version)
end
@@ -645,13 +645,13 @@ describe Chef::Provider::Package::Rubygems do
before do
expected_source = [ source ]
- expected_source << Chef::Config[:rubygems_url] if include_default_source
+ expected_source << "https://rubygems.org" if provider.include_default_source?
allow(provider.gem_env).to receive(:candidate_version_from_remote).with(gem_dep, *expected_source.flatten.compact).and_return(version)
end
describe "in the current gem environment" do
it "installs the gem via the gems api when no explicit options are used" do
- expect(provider.gem_env).to receive(:install).with(gem_dep, sources: [ Chef::Config[:rubygems_url] ])
+ expect(provider.gem_env).to receive(:install).with(gem_dep, sources: [ "https://rubygems.org" ])
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
end
@@ -660,7 +660,7 @@ describe Chef::Provider::Package::Rubygems do
let(:source) { "http://gems.example.org" }
it "installs the gem via the gems api" do
- expect(provider.gem_env).to receive(:install).with(gem_dep, sources: [source, Chef::Config[:rubygems_url]])
+ expect(provider.gem_env).to receive(:install).with(gem_dep, sources: [source])
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
end
@@ -691,7 +691,7 @@ describe Chef::Provider::Package::Rubygems do
it "installs the gem via the gems api, when the package has no file separator characters in it, but a matching file exists in cwd" do
allow(::File).to receive(:exist?).and_return(true)
new_resource.package_name("rspec-core")
- expect(provider.gem_env).to receive(:install).with(gem_dep, sources: [ Chef::Config[:rubygems_url] ])
+ expect(provider.gem_env).to receive(:install).with(gem_dep, sources: [ "https://rubygems.org" ])
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
end
@@ -700,14 +700,14 @@ describe Chef::Provider::Package::Rubygems do
let(:options) { "-i /alt/install/location" }
it "installs the gem by shelling out when options are provided as a String" do
- expected = "gem install rspec-core -q --no-document -v \"#{target_version}\" --source=https://www.rubygems.org #{options}"
+ expected = "gem install rspec-core -q --no-document -v \"#{target_version}\" --source=https://rubygems.org #{options}"
expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900)
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
end
it "unmockening needs_nodocument?" do
- expected = "gem install rspec-core -q --no-document -v \"#{target_version}\" --source=https://www.rubygems.org #{options}"
+ expected = "gem install rspec-core -q --no-document -v \"#{target_version}\" --source=https://rubygems.org #{options}"
expect(provider).to receive(:needs_nodocument?).and_call_original
stub_const("Gem::VERSION", "3.0.0")
expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900)
@@ -716,7 +716,7 @@ describe Chef::Provider::Package::Rubygems do
end
it "when the rubygems_version is old it uses the old flags" do
- expected = "gem install rspec-core -q --no-rdoc --no-ri -v \"#{target_version}\" --source=https://www.rubygems.org #{options}"
+ expected = "gem install rspec-core -q --no-rdoc --no-ri -v \"#{target_version}\" --source=https://rubygems.org #{options}"
expect(provider).to receive(:needs_nodocument?).and_call_original
stub_const("Gem::VERSION", "2.8.0")
expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900)
@@ -728,10 +728,10 @@ describe Chef::Provider::Package::Rubygems do
context "when the Chef::Config[:rubygems_url] option is provided" do
let(:gem_binary) { "/foo/bar" }
- it "installs the gem with rubygems.org as an added source" do
+ it "installs the gem" do
Chef::Config[:rubygems_url] = "https://mirror1"
- expect(provider.gem_env).to receive(:candidate_version_from_remote).with(gem_dep, Chef::Config[:rubygems_url]).and_return(version)
- expected = "#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --source=https://mirror1"
+ expect(provider.gem_env).to receive(:candidate_version_from_remote).with(gem_dep, "https://mirror1").and_return(version)
+ expected = "#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --clear-sources --source=https://mirror1"
expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900)
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
@@ -742,19 +742,30 @@ describe Chef::Provider::Package::Rubygems do
let(:source) { "http://mirror.ops.rhcloud.com/mirror/ruby" }
let(:gem_binary) { "/foo/bar" }
- it "installs the gem with rubygems.org as an added source" do
- expected = "#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --source=#{source} --source=https://www.rubygems.org"
+ it "installs the gem" do
+ expected = "#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --clear-sources --source=#{source}"
expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900)
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
end
+ context "with include_default_source true" do
+ let(:include_default_source) { true }
+
+ it "ignores the Chef::Config setting" do
+ expected = "#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --clear-sources --source=#{source} --source=https://rubygems.org"
+ expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900)
+ provider.run_action(:install)
+ expect(new_resource).to be_updated_by_last_action
+ end
+ end
+
context "with include_default_source false" do
let(:include_default_source) { false }
it "ignores the Chef::Config setting" do
Chef::Config[:rubygems_url] = "https://ignored"
- expected = "#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --source=#{source}"
+ expected = "#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --clear-sources --source=#{source}"
expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900)
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
@@ -767,18 +778,29 @@ describe Chef::Provider::Package::Rubygems do
let(:gem_binary) { "/foo/bar" }
it "installs the gem with an array as an added source" do
- expected = "#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --source=https://mirror1 --source=https://mirror2 --source=https://www.rubygems.org"
+ expected = "#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --clear-sources --source=https://mirror1 --source=https://mirror2"
expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900)
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
end
+ context "with include_default_source true" do
+ let(:include_default_source) { true }
+
+ it "installs the gem with rubygems as a source" do
+ expected = "#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --clear-sources --source=https://mirror1 --source=https://mirror2 --source=https://rubygems.org"
+ expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900)
+ provider.run_action(:install)
+ expect(new_resource).to be_updated_by_last_action
+ end
+ end
+
context "with include_default_source false" do
let(:include_default_source) { false }
it "ignores the Chef::Config setting" do
Chef::Config[:rubygems_url] = "https://ignored"
- expected = "#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --source=https://mirror1 --source=https://mirror2"
+ expected = "#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --clear-sources --source=https://mirror1 --source=https://mirror2"
expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900)
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
@@ -786,13 +808,26 @@ describe Chef::Provider::Package::Rubygems do
end
end
- context "when we have cleared sources and an explict source is specified" do
+ context "when clear_sources is set true and an explict source is specified" do
let(:gem_binary) { "/foo/bar" }
let(:source) { "http://mirror.ops.rhcloud.com/mirror/ruby" }
it "installs the gem" do
new_resource.clear_sources(true)
- expected = "#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --clear-sources --source=#{source} --source=https://www.rubygems.org"
+ expected = "#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --clear-sources --source=#{source}"
+ expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900)
+ provider.run_action(:install)
+ expect(new_resource).to be_updated_by_last_action
+ end
+ end
+
+ context "when clear_sources is set false and an explict source is specified" do
+ let(:gem_binary) { "/foo/bar" }
+ let(:source) { "http://mirror.ops.rhcloud.com/mirror/ruby" }
+
+ it "installs the gem" do
+ new_resource.clear_sources(false)
+ expected = "#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --source=#{source}"
expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900)
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
@@ -804,7 +839,7 @@ describe Chef::Provider::Package::Rubygems do
let(:options) { "-i /alt/install/location" }
it "installs the gem by shelling out when options are provided but no version is given" do
- expected = "gem install rspec-core -q --no-document -v \"#{candidate_version}\" --source=https://www.rubygems.org #{options}"
+ expected = "gem install rspec-core -q --no-document -v \"#{candidate_version}\" --source=https://rubygems.org #{options}"
expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900)
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
@@ -815,7 +850,7 @@ describe Chef::Provider::Package::Rubygems do
let(:options) { { install_dir: "/alt/install/location" } }
it "installs the gem via the gems api when options are given as a Hash" do
- expect(provider.gem_env).to receive(:install).with(gem_dep, { sources: [ Chef::Config[:rubygems_url] ] }.merge(options))
+ expect(provider.gem_env).to receive(:install).with(gem_dep, { sources: [ "https://rubygems.org" ] }.merge(options))
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
end
@@ -825,7 +860,7 @@ describe Chef::Provider::Package::Rubygems do
let(:target_version) { "9000.0.2" }
it "installs the gem via the gems api" do
- expect(provider.gem_env).to receive(:install).with(gem_dep, sources: [ Chef::Config[:rubygems_url] ] )
+ expect(provider.gem_env).to receive(:install).with(gem_dep, sources: [ "https://rubygems.org" ] )
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
end
@@ -868,7 +903,7 @@ describe Chef::Provider::Package::Rubygems do
let(:gem_binary) { "/usr/weird/bin/gem" }
it "installs the gem by shelling out to gem install" do
- expect(provider).to receive(:shell_out_compacted!).with("#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --source=https://www.rubygems.org", env: nil, timeout: 900)
+ expect(provider).to receive(:shell_out_compacted!).with("#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --source=https://rubygems.org", env: nil, timeout: 900)
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
end
@@ -876,7 +911,7 @@ describe Chef::Provider::Package::Rubygems do
it "unmockening needs_nodocument?" do
expect(provider).to receive(:needs_nodocument?).and_call_original
expect(provider.gem_env).to receive(:shell_out!).with("#{gem_binary} --version").and_return(instance_double(Mixlib::ShellOut, stdout: "3.0.0\n"))
- expect(provider).to receive(:shell_out_compacted!).with("#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --source=https://www.rubygems.org", env: nil, timeout: 900)
+ expect(provider).to receive(:shell_out_compacted!).with("#{gem_binary} install rspec-core -q --no-document -v \"#{target_version}\" --source=https://rubygems.org", env: nil, timeout: 900)
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
end
@@ -884,7 +919,7 @@ describe Chef::Provider::Package::Rubygems do
it "when the rubygems_version is old it uses the old flags" do
expect(provider).to receive(:needs_nodocument?).and_call_original
expect(provider.gem_env).to receive(:shell_out!).with("#{gem_binary} --version").and_return(instance_double(Mixlib::ShellOut, stdout: "2.8.0\n"))
- expect(provider).to receive(:shell_out_compacted!).with("#{gem_binary} install rspec-core -q --no-rdoc --no-ri -v \"#{target_version}\" --source=https://www.rubygems.org", env: nil, timeout: 900)
+ expect(provider).to receive(:shell_out_compacted!).with("#{gem_binary} install rspec-core -q --no-rdoc --no-ri -v \"#{target_version}\" --source=https://rubygems.org", env: nil, timeout: 900)
provider.run_action(:install)
expect(new_resource).to be_updated_by_last_action
end
@@ -979,3 +1014,153 @@ describe Chef::Provider::Package::Rubygems do
end
end
end
+
+describe Chef::Provider::Package::Rubygems, "clear_sources?" do
+ let(:new_resource) do
+ Chef::Resource::GemPackage.new("foo")
+ end
+
+ let(:provider) do
+ run_context = Chef::RunContext.new(Chef::Node.new, {}, Chef::EventDispatch::Dispatcher.new)
+ Chef::Provider::Package::Rubygems.new(new_resource, run_context)
+ end
+
+ it "is false when clear_sources is unset" do
+ expect(provider.clear_sources?).to be false
+ end
+
+ it "is false when clear_sources is set false" do
+ new_resource.clear_sources(false)
+ expect(provider.clear_sources?).to be false
+ end
+
+ it "is true when clear_sources is set true" do
+ new_resource.clear_sources(true)
+ expect(provider.clear_sources?).to be true
+ end
+
+ context "when a source is set" do
+ before do
+ new_resource.source("http://mirror.ops.rhcloud.com/mirror/ruby")
+ end
+
+ it "is true when clear_sources is unset" do
+ expect(provider.clear_sources?).to be true
+ end
+
+ it "is false when clear_sources is set false" do
+ new_resource.clear_sources(false)
+ expect(provider.clear_sources?).to be false
+ end
+
+ it "is true when clear_sources is set true" do
+ new_resource.clear_sources(true)
+ expect(provider.clear_sources?).to be true
+ end
+ end
+
+ context "when Chef::Config[:rubygems_url] is set" do
+ before do
+ Chef::Config.rubygems_url = "https://example.com/"
+ end
+
+ it "is true when clear_sources is unset" do
+ expect(provider.clear_sources?).to be true
+ end
+
+ it "is false when clear_sources is set false" do
+ new_resource.clear_sources(false)
+ expect(provider.clear_sources?).to be false
+ end
+
+ it "is true when clear_sources is set true" do
+ new_resource.clear_sources(true)
+ expect(provider.clear_sources?).to be true
+ end
+ end
+end
+
+describe Chef::Provider::Package::Rubygems, "include_default_source?" do
+ let(:new_resource) do
+ Chef::Resource::GemPackage.new("foo")
+ end
+
+ let(:provider) do
+ run_context = Chef::RunContext.new(Chef::Node.new, {}, Chef::EventDispatch::Dispatcher.new)
+ Chef::Provider::Package::Rubygems.new(new_resource, run_context)
+ end
+
+ it "is true when include_default_source is unset" do
+ expect(provider.include_default_source?).to be true
+ end
+
+ it "is false when include_default_source is set false" do
+ new_resource.include_default_source(false)
+ expect(provider.include_default_source?).to be false
+ end
+
+ it "is true when include_default_source is set true" do
+ new_resource.include_default_source(true)
+ expect(provider.include_default_source?).to be true
+ end
+
+ context "when a source is set" do
+ before do
+ new_resource.source("http://mirror.ops.rhcloud.com/mirror/ruby")
+ end
+
+ it "is false when include_default_source is unset" do
+ expect(provider.include_default_source?).to be false
+ end
+
+ it "is false when include_default_source is set false" do
+ new_resource.include_default_source(false)
+ expect(provider.include_default_source?).to be false
+ end
+
+ it "is true when include_default_source is set true" do
+ new_resource.include_default_source(true)
+ expect(provider.include_default_source?).to be true
+ end
+ end
+
+ context "when Chef::Config[:rubygems_url] is set" do
+ before do
+ Chef::Config.rubygems_url = "https://example.com/"
+ end
+
+ it "is true when include_default_source is unset" do
+ expect(provider.include_default_source?).to be true
+ end
+
+ it "is false when include_default_source is set false" do
+ new_resource.include_default_source(false)
+ expect(provider.include_default_source?).to be false
+ end
+
+ it "is true when include_default_source is set true" do
+ new_resource.include_default_source(true)
+ expect(provider.include_default_source?).to be true
+ end
+ end
+
+ context "when clear_sources is set" do
+ before do
+ new_resource.clear_sources(true)
+ end
+
+ it "is false when include_default_source is unset" do
+ expect(provider.include_default_source?).to be false
+ end
+
+ it "is false when include_default_source is set false" do
+ new_resource.include_default_source(false)
+ expect(provider.include_default_source?).to be false
+ end
+
+ it "is true when include_default_source is set true" do
+ new_resource.include_default_source(true)
+ expect(provider.include_default_source?).to be true
+ end
+ end
+end
diff --git a/spec/unit/resource/build_essential_spec.rb b/spec/unit/resource/build_essential_spec.rb
index 0043b08a5c..e41256176f 100644
--- a/spec/unit/resource/build_essential_spec.rb
+++ b/spec/unit/resource/build_essential_spec.rb
@@ -1,5 +1,5 @@
#
-# Copyright:: Copyright 2018, Chef Software, Inc.
+# Copyright:: Copyright 2018-2020, Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,7 +19,23 @@ require "spec_helper"
describe Chef::Resource::BuildEssential do
- let(:resource) { Chef::Resource::BuildEssential.new("foo") }
+ let(:node) { Chef::Node.new }
+ let(:events) { Chef::EventDispatch::Dispatcher.new }
+ let(:run_context) { Chef::RunContext.new(node, {}, events) }
+ let(:resource) { Chef::Resource::BuildEssential.new("foo", run_context) }
+ let(:provider) { resource.provider_for_action(:install) }
+
+ let(:softwareupdate_catalina_and_later) do
+ double("shell_out", exitstatus: 0, error!: nil, stdout: "Software Update Tool\n\nFinding available software\nSoftware Update found the following new or updated software:\n* Label: Command Line Tools for Xcode-11.0\n\tTitle: Command Line Tools for Xcode, Version: 11.0, Size: 224868K, Recommended: YES, \n")
+ end
+
+ let(:softwareupdate_catalina_and_later_no_cli) do
+ double("shell_out", exitstatus: 0, error!: nil, stdout: "Software Update Tool\n\nFinding available software\nSoftware Update found the following new or updated software:\n* Label: Chef Infra Client\n\tTitle: Chef Infra Client, Version: 17.0.208, Size: 224868K, Recommended: YES, \n")
+ end
+
+ let(:softwareupdate_pre_catalina) do
+ double("shell_out", exitstatus: 0, error!: nil, stdout: "Software Update Tool\n\nFinding available software\nSoftware Update found the following new or updated software:\n * Command Line Tools (macOS High Sierra version 10.13) for Xcode-10.0\n")
+ end
it "has a resource name of :build_essential" do
expect(resource.resource_name).to eql(:build_essential)
@@ -40,4 +56,34 @@ describe Chef::Resource::BuildEssential do
expect(resource.name).to eql("")
end
end
+
+ describe "#xcode_cli_installed?" do
+ it "returns true if the CLI is in the InstallHistory plist" do
+ allow(::File).to receive(:open).with("/Library/Receipts/InstallHistory.plist", "r").and_return(::File.join(::File.dirname(__FILE__), "data/InstallHistory_with_CLT.plist"))
+ expect(provider.xcode_cli_installed?).to eql(true)
+ end
+
+ it "returns false if the pkgutil doesn't list the package" do
+ allow(::File).to receive(:open).with("/Library/Receipts/InstallHistory.plist", "r").and_return(::File.join(::File.dirname(__FILE__), "data/InstallHistory_without_CLT.plist"))
+ expect(provider.xcode_cli_installed?).to eql(false)
+ end
+ end
+
+ describe "#xcode_cli_package_label" do
+ it "returns a package name on macOS < 10.15" do
+ allow(provider).to receive(:shell_out).with("softwareupdate", "--list").and_return(softwareupdate_pre_catalina)
+ expect(provider.xcode_cli_package_label).to eql("Command Line Tools (macOS High Sierra version 10.13) for Xcode-10.0")
+ end
+
+ it "returns a package name on macOS 10.15+" do
+ allow(provider).to receive(:shell_out).with("softwareupdate", "--list").and_return(softwareupdate_catalina_and_later)
+ expect(provider.xcode_cli_package_label).to eql("Command Line Tools for Xcode-11.0")
+ end
+
+ it "returns nil if no update is listed" do
+ allow(provider).to receive(:shell_out).with("softwareupdate", "--list").and_return(softwareupdate_catalina_and_later_no_cli)
+ expect(provider.xcode_cli_package_label).to be_nil
+ end
+
+ end
end
diff --git a/spec/unit/resource/data/InstallHistory_with_CLT.plist b/spec/unit/resource/data/InstallHistory_with_CLT.plist
new file mode 100644
index 0000000000..402c8f344d
--- /dev/null
+++ b/spec/unit/resource/data/InstallHistory_with_CLT.plist
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <dict>
+ <key>contentType</key>
+ <string>config-data</string>
+ <key>date</key>
+ <date>2019-10-07T20:09:37Z</date>
+ <key>displayName</key>
+ <string>XProtectPlistConfigData</string>
+ <key>displayVersion</key>
+ <string>2106</string>
+ <key>packageIdentifiers</key>
+ <array>
+ <string>com.apple.pkg.XProtectPlistConfigData_10_15.16U4081</string>
+ </array>
+ <key>processName</key>
+ <string>softwareupdated</string>
+ </dict>
+ <dict>
+ <key>contentType</key>
+ <string>config-data</string>
+ <key>date</key>
+ <date>2019-10-07T20:09:37Z</date>
+ <key>displayName</key>
+ <string>Gatekeeper Configuration Data</string>
+ <key>displayVersion</key>
+ <string>181</string>
+ <key>packageIdentifiers</key>
+ <array>
+ <string>com.apple.pkg.GatekeeperConfigData.16U1873</string>
+ </array>
+ <key>processName</key>
+ <string>softwareupdated</string>
+ </dict>
+ <dict>
+ <key>contentType</key>
+ <string>config-data</string>
+ <key>date</key>
+ <date>2019-10-07T20:09:37Z</date>
+ <key>displayName</key>
+ <string>MRTConfigData</string>
+ <key>displayVersion</key>
+ <string>1.50</string>
+ <key>packageIdentifiers</key>
+ <array>
+ <string>com.apple.pkg.MRTConfigData_10_15.16U4082</string>
+ </array>
+ <key>processName</key>
+ <string>softwareupdated</string>
+ </dict>
+ <dict>
+ <key>date</key>
+ <date>2019-10-09T02:37:33Z</date>
+ <key>displayName</key>
+ <string>Chef Infra Client</string>
+ <key>displayVersion</key>
+ <string></string>
+ <key>packageIdentifiers</key>
+ <array>
+ <string>com.getchef.pkg.chef</string>
+ </array>
+ <key>processName</key>
+ <string>installer</string>
+ </dict>
+ <dict>
+ <key>date</key>
+ <date>2019-10-09T02:47:02Z</date>
+ <key>displayName</key>
+ <string>Command Line Tools for Xcode</string>
+ <key>displayVersion</key>
+ <string>11.0</string>
+ <key>packageIdentifiers</key>
+ <array>
+ <string>com.apple.pkg.CLTools_Executables</string>
+ <string>com.apple.pkg.CLTools_SDK_macOS1015</string>
+ <string>com.apple.pkg.CLTools_SDK_macOS1014</string>
+ <string>com.apple.pkg.CLTools_macOS_SDK</string>
+ <string>com.apple.pkg.DevSDK</string>
+ <string>com.apple.pkg.DevSDK_OSX109</string>
+ <string>com.apple.pkg.DevSDK_OSX1010</string>
+ <string>com.apple.pkg.DevSDK_OSX1011</string>
+ <string>com.apple.pkg.DevSDK_OSX1012</string>
+ <string>com.apple.pkg.DevSDK_macOS1013_Public</string>
+ <string>com.apple.pkg.macOS_SDK_headers_for_macOS_10.14</string>
+ </array>
+ <key>processName</key>
+ <string>softwareupdated</string>
+ </dict>
+</array>
+</plist>
diff --git a/spec/unit/resource/data/InstallHistory_without_CLT.plist b/spec/unit/resource/data/InstallHistory_without_CLT.plist
new file mode 100644
index 0000000000..2cc10d63ff
--- /dev/null
+++ b/spec/unit/resource/data/InstallHistory_without_CLT.plist
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <dict>
+ <key>contentType</key>
+ <string>config-data</string>
+ <key>date</key>
+ <date>2019-09-30T20:36:29Z</date>
+ <key>displayName</key>
+ <string>Gatekeeper Configuration Data</string>
+ <key>displayVersion</key>
+ <string>181</string>
+ <key>packageIdentifiers</key>
+ <array>
+ <string>com.apple.pkg.GatekeeperConfigData.16U1873</string>
+ </array>
+ <key>processName</key>
+ <string>softwareupdated</string>
+ </dict>
+ <dict>
+ <key>contentType</key>
+ <string>config-data</string>
+ <key>date</key>
+ <date>2019-09-30T20:36:29Z</date>
+ <key>displayName</key>
+ <string>MRTConfigData</string>
+ <key>displayVersion</key>
+ <string>1.49</string>
+ <key>packageIdentifiers</key>
+ <array>
+ <string>com.apple.pkg.MRTConfigData_10_15.16U4080</string>
+ </array>
+ <key>processName</key>
+ <string>softwareupdated</string>
+ </dict>
+</array>
+</plist>
diff --git a/spec/unit/resource/gem_package_spec.rb b/spec/unit/resource/gem_package_spec.rb
index aba6ab1032..b572fd0d40 100644
--- a/spec/unit/resource/gem_package_spec.rb
+++ b/spec/unit/resource/gem_package_spec.rb
@@ -53,11 +53,11 @@ describe Chef::Resource::GemPackage, "gem_binary" do
end
end
-describe Chef::Resource::GemPackage, "clear_gem_sources" do
+describe Chef::Resource::GemPackage, "clear_sources" do
let(:resource) { Chef::Resource::GemPackage.new("foo") }
- it "is false by default" do
- expect(resource.clear_sources).to be false
+ it "is nil by default" do
+ expect(resource.clear_sources).to be_nil
end
it "sets the default of clear_sources to the config value" do
diff --git a/spec/unit/resource/windows_share_spec.rb b/spec/unit/resource/windows_share_spec.rb
index 365d2c7b11..c86465e7c8 100644
--- a/spec/unit/resource/windows_share_spec.rb
+++ b/spec/unit/resource/windows_share_spec.rb
@@ -38,9 +38,11 @@ describe Chef::Resource::WindowsShare do
end
it "coerces path to a single path separator format" do
- resource.path("C:/chef")
+ resource.path("C:/chef".freeze)
expect(resource.path).to eql("C:\\chef")
resource.path("C:\\chef")
expect(resource.path).to eql("C:\\chef")
+ resource.path("C:/chef".dup)
+ expect(resource.path).to eql("C:\\chef")
end
end