diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | CONTRIBUTING.md | 10 | ||||
-rw-r--r-- | RELEASE_NOTES.md | 7 | ||||
-rw-r--r-- | lib/chef/chef_class.rb | 5 | ||||
-rw-r--r-- | lib/chef/knife/bootstrap/templates/README.md | 7 | ||||
-rw-r--r-- | lib/chef/mixin/which.rb | 2 | ||||
-rw-r--r-- | lib/chef/platform/service_helpers.rb | 62 | ||||
-rw-r--r-- | lib/chef/provider/package/rpm.rb | 4 | ||||
-rw-r--r-- | lib/chef/provider/remote_directory.rb | 2 | ||||
-rw-r--r-- | lib/chef/run_context.rb | 8 | ||||
-rw-r--r-- | spec/integration/recipes/remote_directory.rb | 74 | ||||
-rw-r--r-- | spec/spec_helper.rb | 2 | ||||
-rw-r--r-- | spec/support/shared/unit/mock_shellout.rb | 46 | ||||
-rw-r--r-- | spec/unit/provider/package/rpm_spec.rb | 19 | ||||
-rw-r--r-- | spec/unit/provider_resolver_spec.rb | 1357 |
15 files changed, 901 insertions, 705 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c83dbed88..251b68e50e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ of partial templates. * [**Joel Handwell**](https://github.com/joelhandwell): [pr#3821](https://github.com/chef/chef/pull/3821) Human friendly elapsed time in log +* [pr#3985](https://github.com/chef/chef/pull/3985) Simplify the regex which determines the rpm version to resolve issue #3671 * [pr#3928](https://github.com/chef/chef/pull/3928) Add named run list support when using policyfiles * [pr#3913](https://github.com/chef/chef/pull/3913) Add `policy_name`and `policy_group` fields to the node object * [pr#3875](https://github.com/chef/chef/pull/3875) Patch Win32::Registry#delete_key, #delete_value to use wide (W) APIs diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cc416537ab..e7f2e05f06 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -70,7 +70,7 @@ Chef uses [the Apache 2.0 license](https://github.com/opscode/chef/blob/master/L The license tells you what rights you have that are provided by the copyright holder. It is important that the contributor fully understands what rights they are licensing and agrees to them. Sometimes the copyright holder isn't the contributor, - most often when the contributor is doing work for a company. + such as when the contributor is doing work for a company. To make a good faith effort to ensure these criteria are met, Chef requires an Individual CLA or a Corporate CLA for contributions. This agreement helps ensure you are aware of the @@ -134,8 +134,8 @@ There is also a listing of the various Chef products and where to file issues th Otherwise you can file your issue in the [Chef project](https://github.com/opscode/chef/issues) and we will make sure it gets filed against the appropriate project. -In order to decrease the back and forth an issues and help us get to the bottom of them quickly - we use below issue template. You can copy paste this code into the issue you are opening and +In order to decrease the back and forth in issues, and to help us get to the bottom of them quickly + we use the below issue template. You can copy/paste this template into the issue you are opening and edit it accordingly. <a name="issuetemplate"></a> @@ -148,16 +148,12 @@ In order to decrease the back and forth an issues and help us get to the bottom ### Scenario: [What you are trying to achieve and you can't?] - - ### Steps to Reproduce: [If you are filing an issue what are the things we need to do in order to repro your problem?] - ### Expected Result: [What are you expecting to happen as the consequence of above reproduction steps?] - ### Actual Result: [What actually happens after the reproduction steps?] ``` diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index cba5b9f415..d95c416a41 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,9 @@ # Chef Client Release Notes 12.5.0: * OSX 10.11 support (support for SIP and service changes) +* Windows cookbook <= 1.38.1 contains a library file which does not compile with +chef-client 12.5.0. This is resolved in version 1.38.2 of the Windows cookbook. +Cookbooks depending on the Windows cookbook should update the dependency version +to at least 1.38.2 to be compatible with chef-client 12.5.0. ## PSCredential support for the `dsc_script` resource @@ -59,7 +63,7 @@ In Fedora 22 yum has been deprecated in favor of DNF. Unfortunately, while DNF compatible with yum, the yum provider in Chef is not compatible with DNF. Until a proper `dnf_package` resource and associated provider is written and merged into core, 12.5.0 has been patched so that the `yum_package` resource takes a property named `yum_binary` which can be set to point at the yum binary -to run for all its commands. The `yum_binary` will also default to `yum-deprecated` if the +to run for all its commands. The `yum_binary` will also default to `yum-deprecated` if the `/usr/bin/yum-deprecated` command is found on the system. This means that Fedora 22 users can run something like this early in their chef-client run: @@ -73,4 +77,3 @@ end After which the yum-deprecated binary will exist, and the yum provider will find it and should operate normally and successfully. - diff --git a/lib/chef/chef_class.rb b/lib/chef/chef_class.rb index b18c3fbdde..6a0d09ec96 100644 --- a/lib/chef/chef_class.rb +++ b/lib/chef/chef_class.rb @@ -226,5 +226,10 @@ class Chef end end + # @api private Only for test dependency injection; not evenly implemented as yet. + def self.path_to(path) + path + end + reset! end diff --git a/lib/chef/knife/bootstrap/templates/README.md b/lib/chef/knife/bootstrap/templates/README.md index 13a0fe7ada..b5bca25d8e 100644 --- a/lib/chef/knife/bootstrap/templates/README.md +++ b/lib/chef/knife/bootstrap/templates/README.md @@ -1,12 +1,11 @@ This directory contains bootstrap templates which can be used with the -d flag to 'knife bootstrap' to install Chef in different ways. To simplify installation, and reduce the matrix of common installation patterns to support, we have -standardized on the [Omnibus](https://github.com/opscode/omnibus-ruby) built installation +standardized on the [Omnibus](https://github.com/chef/omnibus) built installation packages. The 'chef-full' template downloads a script which is used to determine the correct -Omnibus package for this system from the [Omnitruck](https://github.com/opscode/opscode-omnitruck) API. All other templates in this directory are deprecated and will be removed -in the future. +Omnibus package for this system from the [Omnitruck](https://docs.chef.io/api_omnitruck.html) API. You can still utilize custom bootstrap templates on your system if your installation -needs are unique. Additional information can be found on the [docs site](http://docs.opscode.com/knife_bootstrap.html#custom-templates).
\ No newline at end of file +needs are unique. Additional information can be found on the [docs site](https://docs.chef.io/knife_bootstrap.html#custom-templates). diff --git a/lib/chef/mixin/which.rb b/lib/chef/mixin/which.rb index 4179c97b62..4e1c516386 100644 --- a/lib/chef/mixin/which.rb +++ b/lib/chef/mixin/which.rb @@ -28,7 +28,7 @@ class Chef paths = ENV['PATH'].split(File::PATH_SEPARATOR) + extra_path paths.each do |path| filename = File.join(path, cmd) - return filename if File.executable?(filename) + return filename if File.executable?(Chef.path_to(filename)) end false end diff --git a/lib/chef/platform/service_helpers.rb b/lib/chef/platform/service_helpers.rb index d50812e687..8365141c6e 100644 --- a/lib/chef/platform/service_helpers.rb +++ b/lib/chef/platform/service_helpers.rb @@ -19,6 +19,7 @@ # XXX: mixing shellout into a mixin into classes has to be code smell require 'chef/mixin/shell_out' require 'chef/mixin/which' +require 'chef/chef_class' class Chef class Platform @@ -42,56 +43,56 @@ class Chef # different services is NOT a design concern of this module. # def service_resource_providers - @service_resource_providers ||= [].tap do |service_resource_providers| + providers = [] - if ::File.exist?("/usr/sbin/update-rc.d") - service_resource_providers << :debian - end - - if ::File.exist?("/usr/sbin/invoke-rc.d") - service_resource_providers << :invokercd - end + if ::File.exist?(Chef.path_to("/usr/sbin/update-rc.d")) + providers << :debian + end - if ::File.exist?("/sbin/insserv") - service_resource_providers << :insserv - end + if ::File.exist?(Chef.path_to("/usr/sbin/invoke-rc.d")) + providers << :invokercd + end - # debian >= 6.0 has /etc/init but does not have upstart - if ::File.exist?("/etc/init") && ::File.exist?("/sbin/start") - service_resource_providers << :upstart - end + if ::File.exist?(Chef.path_to("/sbin/insserv")) + providers << :insserv + end - if ::File.exist?("/sbin/chkconfig") - service_resource_providers << :redhat - end + # debian >= 6.0 has /etc/init but does not have upstart + if ::File.exist?(Chef.path_to("/etc/init")) && ::File.exist?(Chef.path_to("/sbin/start")) + providers << :upstart + end - if systemd_sanity_check? - service_resource_providers << :systemd - end + if ::File.exist?(Chef.path_to("/sbin/chkconfig")) + providers << :redhat + end + if systemd_sanity_check? + providers << :systemd end + + providers end def config_for_service(service_name) configs = [] - if ::File.exist?("/etc/init.d/#{service_name}") + if ::File.exist?(Chef.path_to("/etc/init.d/#{service_name}")) configs << :initd end - if ::File.exist?("/etc/init/#{service_name}.conf") + if ::File.exist?(Chef.path_to("/etc/init/#{service_name}.conf")) configs << :upstart end - if ::File.exist?("/etc/xinetd.d/#{service_name}") + if ::File.exist?(Chef.path_to("/etc/xinetd.d/#{service_name}")) configs << :xinetd end - if ::File.exist?("/etc/rc.d/#{service_name}") + if ::File.exist?(Chef.path_to("/etc/rc.d/#{service_name}")) configs << :etc_rcd end - if ::File.exist?("/usr/local/etc/rc.d/#{service_name}") + if ::File.exist?(Chef.path_to("/usr/local/etc/rc.d/#{service_name}")) configs << :usr_local_etc_rcd end @@ -105,14 +106,11 @@ class Chef private def systemctl_path - if @systemctl_path.nil? - @systemctl_path = which("systemctl") - end - @systemctl_path + which("systemctl") end def systemd_sanity_check? - systemctl_path && File.exist?("/proc/1/comm") && File.open("/proc/1/comm").gets.chomp == "systemd" + systemctl_path && File.exist?(Chef.path_to("/proc/1/comm")) && File.open(Chef.path_to("/proc/1/comm")).gets.chomp == "systemd" end def extract_systemd_services(command) @@ -126,7 +124,7 @@ class Chef # this splits off the suffix after the last dot to return "sshd" services += services.select {|s| s.match(/\.service$/) }.map { |s| s.sub(/(.*)\.service$/, '\1') } rescue Mixlib::ShellOut::ShellCommandFailed - false + [] end def platform_has_systemd_unit?(service_name) diff --git a/lib/chef/provider/package/rpm.rb b/lib/chef/provider/package/rpm.rb index c5d52a8384..6ce0dd689f 100644 --- a/lib/chef/provider/package/rpm.rb +++ b/lib/chef/provider/package/rpm.rb @@ -61,7 +61,7 @@ class Chef Chef::Log.debug("#{@new_resource} checking rpm status") shell_out_with_timeout!("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' #{@new_resource.source}").stdout.each_line do |line| case line - when /^([\w\d+_.-]+)\s([\w\d~_.-]+)$/ + when /^(\S+)\s(\S+)$/ @current_resource.package_name($1) @new_resource.version($2) @candidate_version = $2 @@ -78,7 +78,7 @@ class Chef @rpm_status = shell_out_with_timeout("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' #{@current_resource.package_name}") @rpm_status.stdout.each_line do |line| case line - when /^([\w\d+_.-]+)\s([\w\d~_.-]+)$/ + when /^(\S+)\s(\S+)$/ Chef::Log.debug("#{@new_resource} current version is #{$2}") @current_resource.version($2) end diff --git a/lib/chef/provider/remote_directory.rb b/lib/chef/provider/remote_directory.rb index 56c2ff0caf..3c1c50b963 100644 --- a/lib/chef/provider/remote_directory.rb +++ b/lib/chef/provider/remote_directory.rb @@ -161,7 +161,7 @@ class Chef def files_to_transfer cookbook = run_context.cookbook_collection[resource_cookbook] files = cookbook.relative_filenames_in_preferred_directory(node, :files, source) - files.sort!.reverse! + files.sort_by! { |x| x.count(::File::SEPARATOR) } end # Either the explicit cookbook that the user sets on the resource, or the implicit diff --git a/lib/chef/run_context.rb b/lib/chef/run_context.rb index 0c8d3d1a48..205bb47448 100644 --- a/lib/chef/run_context.rb +++ b/lib/chef/run_context.rb @@ -528,15 +528,13 @@ ERROR_MESSAGE attr_reader :loaded_attributes_hash attr_reader :loaded_recipes_hash + # @api private + attr_writer :resource_collection + module Deprecated ### # These need to be settable so deploy can run a resource_collection # independent of any cookbooks via +recipe_eval+ - def resource_collection=(value) - Chef.log_deprecation("Setting run_context.resource_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") - @resource_collection = value - end - def audits=(value) Chef.log_deprecation("Setting run_context.audits will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") @audits = value diff --git a/spec/integration/recipes/remote_directory.rb b/spec/integration/recipes/remote_directory.rb new file mode 100644 index 0000000000..a1988ccd52 --- /dev/null +++ b/spec/integration/recipes/remote_directory.rb @@ -0,0 +1,74 @@ +require 'support/shared/integration/integration_helper' + +describe Chef::Resource::RemoteDirectory do + include IntegrationSupport + include Chef::Mixin::ShellOut + + # Until Cheffish::RSpec has cookbook support, we have to run the whole client + let(:chef_dir) { File.join(File.dirname(__FILE__), "..", "..", "..", "bin") } + + # Invoke `chef-client` as `ruby PATH/TO/chef-client`. This ensures the + # following constraints are satisfied: + # * Windows: windows can only run batch scripts as bare executables. Rubygems + # creates batch wrappers for installed gems, but we don't have batch wrappers + # in the source tree. + # * Other `chef-client` in PATH: A common case is running the tests on a + # machine that has omnibus chef installed. In that case we need to ensure + # we're running `chef-client` from the source tree and not the external one. + # cf. CHEF-4914 + let(:chef_client) { "ruby '#{chef_dir}/chef-client' --minimal-ohai" } + + when_the_repository "has a cookbook with a source_dir with two subdirectories, each with one file and subdir in a different alphabetical order" do + before do + file 'config/client.rb', <<-EOM + local_mode true + cookbook_path "#{path_to('cookbooks')}" + EOM + directory "cookbooks/test" do + directory "files/default/source_dir" do + directory "sub1" do + file "aaa", "" + file "zzz/file", "" + end + directory "sub2" do + file "aaa/file", "" + file "zzz", "" + end + end + end + end + + context "and a recipe is run with a remote_directory that syncs source_dir with different mode and file_mode" do + let!(:dest_dir) { path_to("dest_dir") } + before do + directory "cookbooks/test" do + file "recipes/default.rb", <<-EOM + remote_directory #{dest_dir.inspect} do + source "source_dir" + mode "0754" + files_mode 0777 + end + EOM + end + shell_out!("#{chef_client} -c \"#{path_to('config/client.rb')}\" -o 'test::default'", :cwd => chef_dir) + end + + def mode_of(path) + path = path_to(path) + stat = File.stat(path) + (stat.mode & 0777).to_s(8) + end + + it "creates all directories and files with the correct permissions" do + expect(mode_of("dest_dir/sub1")).to eq "754" + expect(mode_of("dest_dir/sub1/aaa")).to eq "777" + expect(mode_of("dest_dir/sub1/zzz")).to eq "754" + expect(mode_of("dest_dir/sub1/zzz/file")).to eq "777" + expect(mode_of("dest_dir/sub2")).to eq "754" + expect(mode_of("dest_dir/sub2/aaa")).to eq "754" + expect(mode_of("dest_dir/sub2/aaa/file")).to eq "777" + expect(mode_of("dest_dir/sub2/zzz")).to eq "777" + end + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index aadf55f64b..92a4daf6d5 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -73,6 +73,7 @@ require 'spec/support/local_gems.rb' if File.exists?(File.join(File.dirname(__FI # Explicitly require spec helpers that need to load first require 'spec/support/platform_helpers' +require 'spec/support/shared/unit/mock_shellout' # Autoloads support files # Excludes support/platforms by default @@ -98,6 +99,7 @@ TEST_PLATFORM_VERSION = TEST_NODE['platform_version'] RSpec.configure do |config| config.include(Matchers) + config.include(MockShellout::RSpec) config.filter_run :focus => true config.filter_run_excluding :external => true diff --git a/spec/support/shared/unit/mock_shellout.rb b/spec/support/shared/unit/mock_shellout.rb new file mode 100644 index 0000000000..7c3e49ec82 --- /dev/null +++ b/spec/support/shared/unit/mock_shellout.rb @@ -0,0 +1,46 @@ +# +# Author:: John Keiser <jkeiser@chef.io> +# Copyright:: Copyright (c) 2015 John Keiser. +# 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. +# + +# +# Mocks shellout results. Examples: +# mock_shellout_command("systemctl --all", exitstatus: 1) +# +class MockShellout + module RSpec + def mock_shellout_command(command, **result) + allow(::Mixlib::ShellOut).to receive(:new).with(command, anything).and_return MockShellout.new(result) + end + end + + def initialize(**properties) + @properties = { + stdout: "", + stderr: "", + exitstatus: 0 + }.merge(properties) + end + def method_missing(name, *args) + @properties[name.to_sym] + end + def error? + exitstatus != 0 + end + def error! + raise Mixlib::ShellOut::ShellCommandFailed, "Expected process to exit with 0, but received #{exitstatus}" if error? + end +end diff --git a/spec/unit/provider/package/rpm_spec.rb b/spec/unit/provider/package/rpm_spec.rb index e0e45d0b4f..ad9d694e34 100644 --- a/spec/unit/provider/package/rpm_spec.rb +++ b/spec/unit/provider/package/rpm_spec.rb @@ -256,6 +256,24 @@ describe Chef::Provider::Package::Rpm do end end + context "when the package name contains a plus symbol (chef#3671)" do + + let(:package_name) { "chef-server-core" } + + let(:package_source) { "/tmp/chef-server-core-12.2.0+20150713220422-1.el6.x86_64.rpm" } + + let(:rpm_qp_stdout) { "chef-server-core 12.2.0+20150713220422-1.el6" } + let(:rpm_q_stdout) { "chef-server-core 12.2.0+20150713220422-1.el6" } + + let(:rpm_qp_exitstatus) { 0 } + let(:rpm_q_exitstatus) { 0 } + + it "should correctly determine the candidate version and installed version" do + expect(provider.current_resource.package_name).to eq("chef-server-core") + expect(provider.new_resource.version).to eq("12.2.0+20150713220422-1.el6") + end + end + end context "when the source is given as an URI" do @@ -413,4 +431,3 @@ describe Chef::Provider::Package::Rpm do end - diff --git a/spec/unit/provider_resolver_spec.rb b/spec/unit/provider_resolver_spec.rb index 88df4a20cc..2fb99f610c 100644 --- a/spec/unit/provider_resolver_spec.rb +++ b/spec/unit/provider_resolver_spec.rb @@ -20,6 +20,9 @@ require 'spec_helper' require 'chef/mixin/convert_to_class_name' require 'chef/provider_resolver' require 'chef/platform/service_helpers' +require 'support/shared/integration/integration_helper' +require 'tmpdir' +require 'fileutils' include Chef::Mixin::ConvertToClassName @@ -27,833 +30,887 @@ include Chef::Mixin::ConvertToClassName #module Chef::Provider describe Chef::ProviderResolver do + include IntegrationSupport - let(:resource_name) { :service } - let(:provider) { nil } - let(:action) { :start } - - let(:node) do - node = Chef::Node.new - node.automatic[:os] = os - node.automatic[:platform_family] = platform_family - node.automatic[:platform] = platform - node.automatic[:platform_version] = platform_version - node.automatic[:kernel] = { machine: 'i386' } - node - end - let(:run_context) { Chef::RunContext.new(node, nil, nil) } - - let(:provider_resolver) { Chef::ProviderResolver.new(node, resource, action) } - let(:resolved_provider) do - begin - resource ? resource.provider_for_action(action).class : nil - rescue Chef::Exceptions::ProviderNotFound - nil + # Root the filesystem under a temp directory so Chef.path_to will point at it + when_the_repository "is empty" do + before do + allow(Chef).to receive(:path_to) { |path| File.join(path_to(""), path) } end - end - let(:resource) do - resource_class = Chef::ResourceResolver.resolve(resource_name, node: node) - if resource_class - resource = resource_class.new('test', run_context) - resource.provider = provider if provider + let(:resource_name) { :service } + let(:provider) { nil } + let(:action) { :start } + + let(:node) do + node = Chef::Node.new + node.automatic[:os] = os + node.automatic[:platform_family] = platform_family + node.automatic[:platform] = platform + node.automatic[:platform_version] = platform_version + node.automatic[:kernel] = { machine: 'i386' } + node end - resource - end - - def self.on_platform(platform, *tags, - platform_version: '11.0.1', - platform_family: nil, - os: nil, - &block) - Array(platform).each do |platform| - Array(platform_version).each do |platform_version| - on_one_platform(platform, platform_version, platform_family || platform, os || platform_family || platform, *tags, &block) + let(:run_context) { Chef::RunContext.new(node, nil, nil) } + + let(:provider_resolver) { Chef::ProviderResolver.new(node, resource, action) } + let(:resolved_provider) do + begin + resource ? resource.provider_for_action(action).class : nil + rescue Chef::Exceptions::ProviderNotFound + nil end end - end - - def self.on_one_platform(platform, platform_version, platform_family, os, *tags, &block) - describe "on #{platform} #{platform_version}, platform_family: #{platform_family}, os: #{os}", *tags do - let(:os) { os } - let(:platform) { platform } - let(:platform_family) { platform_family } - let(:platform_version) { platform_version } - define_singleton_method(:os) { os } - define_singleton_method(:platform) { platform } - define_singleton_method(:platform_family) { platform_family } - define_singleton_method(:platform_version) { platform_version } - - instance_eval(&block) + let(:service_name) { "test" } + let(:resource) do + resource_class = Chef::ResourceResolver.resolve(resource_name, node: node) + if resource_class + resource = resource_class.new(service_name, run_context) + resource.provider = provider if provider + end + resource end - end - def self.expect_providers(**providers) - providers.each do |name, expected| - describe name.to_s do - let(:resource_name) { name } - - tags = [] - expected_provider = nil - expected_resource = nil - Array(expected).each do |p| - if p.is_a?(Class) && p <= Chef::Provider - expected_provider = p - elsif p.is_a?(Class) && p <= Chef::Resource - expected_resource = p - else - tags << p - end - end - - if expected_resource && expected_provider - it "'#{name}' resolves to resource #{expected_resource} and provider #{expected_provider}", *tags do - expect(resource.class).to eql(expected_resource) - provider = double(expected_provider, class: expected_provider) - expect(provider).to receive(:action=).with(action) - expect(expected_provider).to receive(:new).with(resource, run_context).and_return(provider) - expect(resolved_provider).to eql(expected_provider) - end - elsif expected_provider - it "'#{name}' resolves to provider #{expected_provider}", *tags do - provider = double(expected_provider) - expect(provider).to receive(:action=).with(action) - expect(expected_provider).to receive(:new).with(resource, run_context).and_return(provider) - expect(resolved_provider).to eql(expected_provider) - end - else - it "'#{name}' fails to resolve (since #{name.inspect} is unsupported on #{platform} #{platform_version})", *tags do - expect(resolved_provider).to be_nil - end + def self.on_platform(platform, *tags, + platform_version: '11.0.1', + platform_family: nil, + os: nil, + &block) + Array(platform).each do |platform| + Array(platform_version).each do |platform_version| + on_one_platform(platform, platform_version, platform_family || platform, os || platform_family || platform, *tags, &block) end end end - end - - describe "resolving service resource" do - def stub_service_providers(*services) - services ||= [] - allow(Chef::Platform::ServiceHelpers).to receive(:service_resource_providers) - .and_return(services) - end - - def stub_service_configs(*configs) - configs ||= [] - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return(configs) - end - - before do - allow(resource).to receive(:service_name).and_return("ntp") - end - - shared_examples_for "an ubuntu platform with upstart, update-rc.d and systemd" do - before do - stub_service_providers(:debian, :invokercd, :upstart, :systemd) - end - it "when only the SysV init script exists, it returns a Service::Debian provider" do - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return( [ :initd, :systemd ] ) - expect(resolved_provider).to eql(Chef::Provider::Service::Systemd) - end - - it "when both SysV and Upstart scripts exist, it returns a Service::Upstart provider" do - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return( [ :initd, :upstart, :systemd ] ) - expect(resolved_provider).to eql(Chef::Provider::Service::Systemd) - end + def self.on_one_platform(platform, platform_version, platform_family, os, *tags, &block) + describe "on #{platform} #{platform_version}, platform_family: #{platform_family}, os: #{os}", *tags do + let(:os) { os } + let(:platform) { platform } + let(:platform_family) { platform_family } + let(:platform_version) { platform_version } - it "when only the Upstart script exists, it returns a Service::Upstart provider" do - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return( [ :upstart, :systemd ] ) - expect(resolved_provider).to eql(Chef::Provider::Service::Systemd) - end + define_singleton_method(:os) { os } + define_singleton_method(:platform) { platform } + define_singleton_method(:platform_family) { platform_family } + define_singleton_method(:platform_version) { platform_version } - it "when both do not exist, it calls the old style provider resolver and returns a Debian Provider" do - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return( [ :systemd ] ) - expect(resolved_provider).to eql(Chef::Provider::Service::Systemd) - end - it "when only the SysV init script exists, it returns a Service::Debian provider" do - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return( [ :initd ] ) - expect(resolved_provider).to eql(Chef::Provider::Service::Debian) + instance_eval(&block) end + end - it "when both SysV and Upstart scripts exist, it returns a Service::Upstart provider" do - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return( [ :initd, :upstart ] ) - expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) - end + def self.expect_providers(**providers) + providers.each do |name, expected| + describe name.to_s do + let(:resource_name) { name } + + tags = [] + expected_provider = nil + expected_resource = nil + Array(expected).each do |p| + if p.is_a?(Class) && p <= Chef::Provider + expected_provider = p + elsif p.is_a?(Class) && p <= Chef::Resource + expected_resource = p + else + tags << p + end + end - it "when only the Upstart script exists, it returns a Service::Upstart provider" do - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return( [ :upstart ] ) - expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) + if expected_resource && expected_provider + it "'#{name}' resolves to resource #{expected_resource} and provider #{expected_provider}", *tags do + expect(resource.class).to eql(expected_resource) + provider = double(expected_provider, class: expected_provider) + expect(provider).to receive(:action=).with(action) + expect(expected_provider).to receive(:new).with(resource, run_context).and_return(provider) + expect(resolved_provider).to eql(expected_provider) + end + elsif expected_provider + it "'#{name}' resolves to provider #{expected_provider}", *tags do + provider = double(expected_provider) + expect(provider).to receive(:action=).with(action) + expect(expected_provider).to receive(:new).with(resource, run_context).and_return(provider) + expect(resolved_provider).to eql(expected_provider) + end + else + it "'#{name}' fails to resolve (since #{name.inspect} is unsupported on #{platform} #{platform_version})", *tags do + expect(resolved_provider).to be_nil + end + end + end end + end - it "when both do not exist, it calls the old style provider resolver and returns a Debian Provider" do - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return( [ ] ) - expect(resolved_provider).to eql(Chef::Provider::Service::Systemd) + describe "resolving service resource" do + def stub_service_providers(*services) + services.each do |service| + case service + when :debian + directory 'usr/sbin/update-rc.d' + when :invokercd + directory 'usr/sbin/invoke-rc.d' + when :insserv + directory 'sbin/insserv' + when :upstart + directory 'etc/init' + directory 'sbin/start' + when :redhat + directory 'sbin/chkconfig' + when :systemd + file 'bin/systemctl', '' + # Make systemctl executable + File.chmod(0755, path_to('bin/systemctl')) + # Windows doesn't respect executable bit, do this to let Windows users see if they've broken the resolver + allow(::File).to receive(:executable?) { |p| p == path_to('bin/systemctl') } if windows? + file 'proc/1/comm', "systemd\n" + mock_shellout_command("/bin/systemctl --all", stdout: "") + mock_shellout_command("/bin/systemctl list-unit-files", stdout: "") + else + raise ArgumentError, service + end + end end - end - shared_examples_for "an ubuntu platform with upstart and update-rc.d" do - before do - stub_service_providers(:debian, :invokercd, :upstart) + def stub_service_configs(*configs) + configs.each do |config| + case config + when :initd + file "etc/init.d/#{service_name}", "" + when :upstart + file "etc/init/#{service_name}.conf", "" + when :xinetd + file "etc/xinetd.d/#{service_name}", "" + when :etc_rcd + file "etc/rc.d/#{service_name}", "" + when :usr_local_etc_rcd + file "usr/local/etc/rc.d/#{service_name}", "" + when :systemd + file 'bin/systemctl', '' + # Make systemctl executable + File.chmod(0755, path_to("bin/systemctl")) + # Windows doesn't respect executable bit, do this to let Windows users see if they've broken the resolver + allow(::File).to receive(:executable?) { |p| p == path_to('bin/systemctl') } if windows? + file 'proc/1/comm', "systemd\n" + mock_shellout_command("/bin/systemctl --all", stdout: <<-EOM) + superv loaded + stinky something-else + #{service_name} loaded + blargh not-found + EOM + mock_shellout_command("/bin/systemctl list-unit-files", stdout: <<-EOM) + usuperv loaded + ustinky something-else + u#{service_name} loaded + ublargh not-found + EOM + else + raise ArgumentError, config + end + end end - # needs to be handled by the highest priority init.d handler - context "when only the SysV init script exists" do + shared_examples_for "an ubuntu platform with upstart, update-rc.d and systemd" do before do - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return( [ :initd ] ) + stub_service_providers(:debian, :invokercd, :upstart, :systemd) end - it "enables init, invokercd, debian and upstart providers" do - expect(provider_resolver.enabled_handlers).to include( - Chef::Provider::Service::Debian, - Chef::Provider::Service::Init, - Chef::Provider::Service::Invokercd, - Chef::Provider::Service::Upstart, - ) + it "when only the SysV init script exists, it returns a Service::Debian provider" do + stub_service_configs(:initd, :systemd) + expect(resolved_provider).to eql(Chef::Provider::Service::Systemd) end - it "supports all the enabled handlers except for upstart" do - expect(provider_resolver.supported_handlers).to include( - Chef::Provider::Service::Debian, - Chef::Provider::Service::Init, - Chef::Provider::Service::Invokercd, - ) - expect(provider_resolver.supported_handlers).to_not include( - Chef::Provider::Service::Upstart, - ) + it "when both SysV and Upstart scripts exist, it returns a Service::Upstart provider" do + stub_service_configs(:initd, :upstart, :systemd) + expect(resolved_provider).to eql(Chef::Provider::Service::Systemd) end - it "returns a Service::Debian provider" do - expect(resolved_provider).to eql(Chef::Provider::Service::Debian) + it "when only the Upstart script exists, it returns a Service::Upstart provider" do + stub_service_configs(:upstart, :systemd) + expect(resolved_provider).to eql(Chef::Provider::Service::Systemd) end - end - # on ubuntu this must be handled by upstart, the init script will exit 1 and fail - context "when both SysV and Upstart scripts exist" do - before do - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return( [ :initd, :upstart ] ) + it "when both do not exist, it calls the old style provider resolver and returns a Debian Provider" do + stub_service_configs(:systemd) + expect(resolved_provider).to eql(Chef::Provider::Service::Systemd) end - it "enables init, invokercd, debian and upstart providers" do - expect(provider_resolver.enabled_handlers).to include( - Chef::Provider::Service::Debian, - Chef::Provider::Service::Init, - Chef::Provider::Service::Invokercd, - Chef::Provider::Service::Upstart, - ) + it "when only the SysV init script exists, it returns a Service::Debian provider" do + stub_service_configs(:initd) + expect(resolved_provider).to eql(Chef::Provider::Service::Debian) end - it "supports all the enabled handlers" do - expect(provider_resolver.supported_handlers).to include( - Chef::Provider::Service::Debian, - Chef::Provider::Service::Init, - Chef::Provider::Service::Invokercd, - Chef::Provider::Service::Upstart, - ) + it "when both SysV and Upstart scripts exist, it returns a Service::Upstart provider" do + stub_service_configs(:initd, :upstart) + expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) end - it "returns a Service::Upstart provider" do + it "when only the Upstart script exists, it returns a Service::Upstart provider" do + stub_service_configs(:upstart) expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) end + + it "when both do not exist, it calls the old style provider resolver and returns a Debian Provider" do + stub_service_configs + expect(resolved_provider).to eql(Chef::Provider::Service::Systemd) + end end - # this case is a pure-upstart script which is easy - context "when only the Upstart script exists" do + shared_examples_for "an ubuntu platform with upstart and update-rc.d" do before do - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return( [ :upstart ] ) + stub_service_providers(:debian, :invokercd, :upstart) end - it "enables init, invokercd, debian and upstart providers" do - expect(provider_resolver.enabled_handlers).to include( - Chef::Provider::Service::Debian, - Chef::Provider::Service::Init, - Chef::Provider::Service::Invokercd, - Chef::Provider::Service::Upstart, - ) - end + # needs to be handled by the highest priority init.d handler + context "when only the SysV init script exists" do + before do + stub_service_configs(:initd) + end - it "supports only the upstart handler" do - expect(provider_resolver.supported_handlers).to include( - Chef::Provider::Service::Upstart, - ) - expect(provider_resolver.supported_handlers).to_not include( - Chef::Provider::Service::Debian, - Chef::Provider::Service::Init, - Chef::Provider::Service::Invokercd, - ) - end + it "enables init, invokercd, debian and upstart providers" do + expect(provider_resolver.enabled_handlers).to include( + Chef::Provider::Service::Debian, + Chef::Provider::Service::Init, + Chef::Provider::Service::Invokercd, + Chef::Provider::Service::Upstart, + ) + end - it "returns a Service::Upstart provider" do - expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) - end - end + it "supports all the enabled handlers except for upstart" do + expect(provider_resolver.supported_handlers).to include( + Chef::Provider::Service::Debian, + Chef::Provider::Service::Init, + Chef::Provider::Service::Invokercd, + ) + expect(provider_resolver.supported_handlers).to_not include( + Chef::Provider::Service::Upstart, + ) + end - # this case is important to get correct for why-run when no config is setup - context "when both do not exist" do - before do - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return( [ ] ) + it "returns a Service::Debian provider" do + expect(resolved_provider).to eql(Chef::Provider::Service::Debian) + end end - it "enables init, invokercd, debian and upstart providers" do - expect(provider_resolver.enabled_handlers).to include( - Chef::Provider::Service::Debian, - Chef::Provider::Service::Init, - Chef::Provider::Service::Invokercd, - Chef::Provider::Service::Upstart, - ) - end + # on ubuntu this must be handled by upstart, the init script will exit 1 and fail + context "when both SysV and Upstart scripts exist" do + before do + stub_service_configs(:initd, :upstart) + end - it "no providers claim to support the resource" do - expect(provider_resolver.supported_handlers).to_not include( - Chef::Provider::Service::Upstart, - Chef::Provider::Service::Debian, - Chef::Provider::Service::Init, - Chef::Provider::Service::Invokercd, - ) - end + it "enables init, invokercd, debian and upstart providers" do + expect(provider_resolver.enabled_handlers).to include( + Chef::Provider::Service::Debian, + Chef::Provider::Service::Init, + Chef::Provider::Service::Invokercd, + Chef::Provider::Service::Upstart, + ) + end - it "returns a Debian Provider" do - expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) - end - end - end + it "supports all the enabled handlers" do + expect(provider_resolver.supported_handlers).to include( + Chef::Provider::Service::Debian, + Chef::Provider::Service::Init, + Chef::Provider::Service::Invokercd, + Chef::Provider::Service::Upstart, + ) + end - shared_examples_for "a debian platform using the insserv provider" do - context "with a default install" do - before do - stub_service_providers(:debian, :invokercd, :insserv) + it "returns a Service::Upstart provider" do + expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) + end end - it "uses the Service::Insserv Provider to manage sysv init scripts" do - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return( [ :initd ] ) - expect(resolved_provider).to eql(Chef::Provider::Service::Insserv) - end + # this case is a pure-upstart script which is easy + context "when only the Upstart script exists" do + before do + stub_service_configs(:upstart) + end - it "uses the Service::Insserv Provider when there is no config" do - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return( [ ] ) - expect(resolved_provider).to eql(Chef::Provider::Service::Insserv) - end - end + it "enables init, invokercd, debian and upstart providers" do + expect(provider_resolver.enabled_handlers).to include( + Chef::Provider::Service::Debian, + Chef::Provider::Service::Init, + Chef::Provider::Service::Invokercd, + Chef::Provider::Service::Upstart, + ) + end - context "when the user has installed upstart" do - before do - stub_service_providers(:debian, :invokercd, :insserv, :upstart) - end + it "supports only the upstart handler" do + expect(provider_resolver.supported_handlers).to include( + Chef::Provider::Service::Upstart, + ) + expect(provider_resolver.supported_handlers).to_not include( + Chef::Provider::Service::Debian, + Chef::Provider::Service::Init, + Chef::Provider::Service::Invokercd, + ) + end - it "when only the SysV init script exists, it returns an Insserv provider" do - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return( [ :initd ] ) - expect(resolved_provider).to eql(Chef::Provider::Service::Insserv) + it "returns a Service::Upstart provider" do + expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) + end end - it "when both SysV and Upstart scripts exist, it returns a Service::Upstart provider" do - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return( [ :initd, :upstart ] ) - expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) - end + # this case is important to get correct for why-run when no config is setup + context "when both do not exist" do + before do + stub_service_configs + end - it "when only the Upstart script exists, it returns a Service::Upstart provider" do - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return( [ :upstart ] ) - expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) - end + it "enables init, invokercd, debian and upstart providers" do + expect(provider_resolver.enabled_handlers).to include( + Chef::Provider::Service::Debian, + Chef::Provider::Service::Init, + Chef::Provider::Service::Invokercd, + Chef::Provider::Service::Upstart, + ) + end - it "when both do not exist, it calls the old style provider resolver and returns a Debian Provider" do - allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") - .and_return( [ ] ) - expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) + it "no providers claim to support the resource" do + expect(provider_resolver.supported_handlers).to_not include( + Chef::Provider::Service::Upstart, + Chef::Provider::Service::Debian, + Chef::Provider::Service::Init, + Chef::Provider::Service::Invokercd, + ) + end + + it "returns a Debian Provider" do + expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) + end end end - end - on_platform "ubuntu", platform_version: "14.10", platform_family: "debian", os: "linux" do - it_behaves_like "an ubuntu platform with upstart, update-rc.d and systemd" - end + shared_examples_for "a debian platform using the insserv provider" do + context "with a default install" do + before do + stub_service_providers(:debian, :invokercd, :insserv) + end - on_platform "ubuntu", platform_version: "14.04", platform_family: "debian", os: "linux" do - it_behaves_like "an ubuntu platform with upstart and update-rc.d" - end + it "uses the Service::Insserv Provider to manage sysv init scripts" do + stub_service_configs(:initd) + expect(resolved_provider).to eql(Chef::Provider::Service::Insserv) + end - on_platform "ubuntu", platform_version: "10.04", platform_family: "debian", os: "linux" do - it_behaves_like "an ubuntu platform with upstart and update-rc.d" - end + it "uses the Service::Insserv Provider when there is no config" do + stub_service_configs + expect(resolved_provider).to eql(Chef::Provider::Service::Insserv) + end + end - # old debian uses the Debian provider (does not have insserv or upstart, or update-rc.d???) - on_platform "debian", platform_version: "4.0", os: "linux" do - #it_behaves_like "a debian platform using the debian provider" - end + context "when the user has installed upstart" do + before do + stub_service_providers(:debian, :invokercd, :insserv, :upstart) + end - # Debian replaced the debian provider with insserv in the FIXME:VERSION distro - on_platform "debian", platform_version: "7.0", os: "linux" do - it_behaves_like "a debian platform using the insserv provider" - end + it "when only the SysV init script exists, it returns an Insserv provider" do + stub_service_configs(:initd) + expect(resolved_provider).to eql(Chef::Provider::Service::Insserv) + end + + it "when both SysV and Upstart scripts exist, it returns a Service::Upstart provider" do + stub_service_configs(:initd, :upstart) + expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) + end + + it "when only the Upstart script exists, it returns a Service::Upstart provider" do + stub_service_configs(:upstart) + expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) + end - on_platform %w{solaris2 openindiana opensolaris nexentacore omnios smartos}, os: "solaris2", platform_version: "5.11" do - it "returns a Solaris provider" do - stub_service_providers - stub_service_configs - expect(resolved_provider).to eql(Chef::Provider::Service::Solaris) + it "when both do not exist, it calls the old style provider resolver and returns a Debian Provider" do + stub_service_configs + expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) + end + end end - it "always returns a Solaris provider" do - # no matter what we stub on the next two lines we should get a Solaris provider - stub_service_providers(:debian, :invokercd, :insserv, :upstart, :redhat, :systemd) - stub_service_configs(:initd, :upstart, :xinetd, :user_local_etc_rcd, :systemd) - expect(resolved_provider).to eql(Chef::Provider::Service::Solaris) + on_platform "ubuntu", platform_version: "15.10", platform_family: "debian", os: "linux" do + it_behaves_like "an ubuntu platform with upstart, update-rc.d and systemd" + + it "when the unit-files are missing and system-ctl list-unit-files returns an error" do + stub_service_providers(:debian, :invokercd, :upstart, :systemd) + stub_service_configs(:initd, :upstart) + mock_shellout_command("/bin/systemctl list-unit-files", exitstatus: 1) + expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) + end end - end - on_platform %w{mswin mingw32 windows}, platform_family: "windows", platform_version: "5.11" do - it "returns a Windows provider" do - stub_service_providers - stub_service_configs - expect(resolved_provider).to eql(Chef::Provider::Service::Windows) + on_platform "ubuntu", platform_version: "14.10", platform_family: "debian", os: "linux" do + it_behaves_like "an ubuntu platform with upstart, update-rc.d and systemd" end - it "always returns a Windows provider" do - # no matter what we stub on the next two lines we should get a Windows provider - stub_service_providers(:debian, :invokercd, :insserv, :upstart, :redhat, :systemd) - stub_service_configs(:initd, :upstart, :xinetd, :user_local_etc_rcd, :systemd) - expect(resolved_provider).to eql(Chef::Provider::Service::Windows) + on_platform "ubuntu", platform_version: "14.04", platform_family: "debian", os: "linux" do + it_behaves_like "an ubuntu platform with upstart and update-rc.d" end - end - on_platform %w{mac_os_x mac_os_x_server}, os: "darwin", platform_family: "mac_os_x", platform_version: "10.9.2" do - it "returns a Macosx provider" do - stub_service_providers - stub_service_configs - expect(resolved_provider).to eql(Chef::Provider::Service::Macosx) + on_platform "ubuntu", platform_version: "10.04", platform_family: "debian", os: "linux" do + it_behaves_like "an ubuntu platform with upstart and update-rc.d" end - it "always returns a Macosx provider" do - # no matter what we stub on the next two lines we should get a Macosx provider - stub_service_providers(:debian, :invokercd, :insserv, :upstart, :redhat, :systemd) - stub_service_configs(:initd, :upstart, :xinetd, :user_local_etc_rcd, :systemd) - expect(resolved_provider).to eql(Chef::Provider::Service::Macosx) + # old debian uses the Debian provider (does not have insserv or upstart, or update-rc.d???) + on_platform "debian", platform_version: "4.0", os: "linux" do + #it_behaves_like "a debian platform using the debian provider" end - end - on_platform %w(freebsd netbsd), platform_version: '3.1.4' do - it "returns a Freebsd provider if it finds the /usr/local/etc/rc.d initscript" do - stub_service_providers - stub_service_configs(:usr_local_etc_rcd) - expect(resolved_provider).to eql(Chef::Provider::Service::Freebsd) + # Debian replaced the debian provider with insserv in the FIXME:VERSION distro + on_platform "debian", platform_version: "7.0", os: "linux" do + it_behaves_like "a debian platform using the insserv provider" end - it "returns a Freebsd provider if it finds the /etc/rc.d initscript" do - stub_service_providers - stub_service_configs(:etc_rcd) - expect(resolved_provider).to eql(Chef::Provider::Service::Freebsd) + on_platform %w{solaris2 openindiana opensolaris nexentacore omnios smartos}, os: "solaris2", platform_version: "5.11" do + it "returns a Solaris provider" do + stub_service_providers + stub_service_configs + expect(resolved_provider).to eql(Chef::Provider::Service::Solaris) + end + + it "always returns a Solaris provider" do + # no matter what we stub on the next two lines we should get a Solaris provider + stub_service_providers(:debian, :invokercd, :insserv, :upstart, :redhat, :systemd) + stub_service_configs(:initd, :upstart, :xinetd, :usr_local_etc_rcd, :systemd) + expect(resolved_provider).to eql(Chef::Provider::Service::Solaris) + end end - it "always returns a Freebsd provider if it finds the /usr/local/etc/rc.d initscript" do - # should only care about :usr_local_etc_rcd stub in the service configs - stub_service_providers(:debian, :invokercd, :insserv, :upstart, :redhat, :systemd) - stub_service_configs(:usr_local_etc_rcd, :initd, :upstart, :xinetd, :systemd) - expect(resolved_provider).to eql(Chef::Provider::Service::Freebsd) + on_platform %w{mswin mingw32 windows}, platform_family: "windows", platform_version: "5.11" do + it "returns a Windows provider" do + stub_service_providers + stub_service_configs + expect(resolved_provider).to eql(Chef::Provider::Service::Windows) + end + + it "always returns a Windows provider" do + # no matter what we stub on the next two lines we should get a Windows provider + stub_service_providers(:debian, :invokercd, :insserv, :upstart, :redhat, :systemd) + stub_service_configs(:initd, :upstart, :xinetd, :usr_local_etc_rcd, :systemd) + expect(resolved_provider).to eql(Chef::Provider::Service::Windows) + end end - it "always returns a Freebsd provider if it finds the /usr/local/etc/rc.d initscript" do - # should only care about :etc_rcd stub in the service configs - stub_service_providers(:debian, :invokercd, :insserv, :upstart, :redhat, :systemd) - stub_service_configs(:etc_rcd, :initd, :upstart, :xinetd, :systemd) - expect(resolved_provider).to eql(Chef::Provider::Service::Freebsd) + on_platform %w{mac_os_x mac_os_x_server}, os: "darwin", platform_family: "mac_os_x", platform_version: "10.9.2" do + it "returns a Macosx provider" do + stub_service_providers + stub_service_configs + expect(resolved_provider).to eql(Chef::Provider::Service::Macosx) + end + + it "always returns a Macosx provider" do + # no matter what we stub on the next two lines we should get a Macosx provider + stub_service_providers(:debian, :invokercd, :insserv, :upstart, :redhat, :systemd) + stub_service_configs(:initd, :upstart, :xinetd, :usr_local_etc_rcd, :systemd) + expect(resolved_provider).to eql(Chef::Provider::Service::Macosx) + end end - it "foo" do - stub_service_providers - stub_service_configs - expect(resolved_provider).to eql(Chef::Provider::Service::Freebsd) + on_platform %w(freebsd netbsd), platform_version: '3.1.4' do + it "returns a Freebsd provider if it finds the /usr/local/etc/rc.d initscript" do + stub_service_providers + stub_service_configs(:usr_local_etc_rcd) + expect(resolved_provider).to eql(Chef::Provider::Service::Freebsd) + end + + it "returns a Freebsd provider if it finds the /etc/rc.d initscript" do + stub_service_providers + stub_service_configs(:etc_rcd) + expect(resolved_provider).to eql(Chef::Provider::Service::Freebsd) + end + + it "always returns a Freebsd provider if it finds the /usr/local/etc/rc.d initscript" do + # should only care about :usr_local_etc_rcd stub in the service configs + stub_service_providers(:debian, :invokercd, :insserv, :upstart, :redhat, :systemd) + stub_service_configs(:usr_local_etc_rcd, :initd, :upstart, :xinetd, :systemd) + expect(resolved_provider).to eql(Chef::Provider::Service::Freebsd) + end + + it "always returns a Freebsd provider if it finds the /usr/local/etc/rc.d initscript" do + # should only care about :etc_rcd stub in the service configs + stub_service_providers(:debian, :invokercd, :insserv, :upstart, :redhat, :systemd) + stub_service_configs(:etc_rcd, :initd, :upstart, :xinetd, :systemd) + expect(resolved_provider).to eql(Chef::Provider::Service::Freebsd) + end + + it "foo" do + stub_service_providers + stub_service_configs + expect(resolved_provider).to eql(Chef::Provider::Service::Freebsd) + end end - end - end + end - PROVIDERS = - { - bash: [ Chef::Resource::Bash, Chef::Provider::Script ], - breakpoint: [ Chef::Resource::Breakpoint, Chef::Provider::Breakpoint ], - chef_gem: [ Chef::Resource::ChefGem, Chef::Provider::Package::Rubygems ], - cookbook_file: [ Chef::Resource::CookbookFile, Chef::Provider::CookbookFile ], - csh: [ Chef::Resource::Csh, Chef::Provider::Script ], - deploy: [ Chef::Resource::Deploy, Chef::Provider::Deploy::Timestamped ], - deploy_revision: [ Chef::Resource::DeployRevision, Chef::Provider::Deploy::Revision ], - directory: [ Chef::Resource::Directory, Chef::Provider::Directory ], - easy_install_package: [ Chef::Resource::EasyInstallPackage, Chef::Provider::Package::EasyInstall ], - erl_call: [ Chef::Resource::ErlCall, Chef::Provider::ErlCall ], - execute: [ Chef::Resource::Execute, Chef::Provider::Execute ], - file: [ Chef::Resource::File, Chef::Provider::File ], - gem_package: [ Chef::Resource::GemPackage, Chef::Provider::Package::Rubygems ], - git: [ Chef::Resource::Git, Chef::Provider::Git ], - group: [ Chef::Resource::Group, Chef::Provider::Group::Gpasswd ], - homebrew_package: [ Chef::Resource::HomebrewPackage, Chef::Provider::Package::Homebrew ], - http_request: [ Chef::Resource::HttpRequest, Chef::Provider::HttpRequest ], - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], - link: [ Chef::Resource::Link, Chef::Provider::Link ], - log: [ Chef::Resource::Log, Chef::Provider::Log::ChefLog ], - macports_package: [ Chef::Resource::MacportsPackage, Chef::Provider::Package::Macports ], - mdadm: [ Chef::Resource::Mdadm, Chef::Provider::Mdadm ], - mount: [ Chef::Resource::Mount, Chef::Provider::Mount::Mount ], - perl: [ Chef::Resource::Perl, Chef::Provider::Script ], - portage_package: [ Chef::Resource::PortagePackage, Chef::Provider::Package::Portage ], - python: [ Chef::Resource::Python, Chef::Provider::Script ], - remote_directory: [ Chef::Resource::RemoteDirectory, Chef::Provider::RemoteDirectory ], - route: [ Chef::Resource::Route, Chef::Provider::Route ], - ruby: [ Chef::Resource::Ruby, Chef::Provider::Script ], - ruby_block: [ Chef::Resource::RubyBlock, Chef::Provider::RubyBlock ], - script: [ Chef::Resource::Script, Chef::Provider::Script ], - subversion: [ Chef::Resource::Subversion, Chef::Provider::Subversion ], - template: [ Chef::Resource::Template, Chef::Provider::Template ], - timestamped_deploy: [ Chef::Resource::TimestampedDeploy, Chef::Provider::Deploy::Timestamped ], - user: [ Chef::Resource::User, Chef::Provider::User::Useradd ], - whyrun_safe_ruby_block: [ Chef::Resource::WhyrunSafeRubyBlock, Chef::Provider::WhyrunSafeRubyBlock ], - - # We want to check that these are unsupported: - apt_package: nil, - bff_package: nil, - dpkg_package: nil, - dsc_script: nil, - ips_package: nil, - pacman_package: nil, - paludis_package: nil, - rpm_package: nil, - smartos_package: nil, - solaris_package: nil, - yum_package: nil, - windows_package: nil, - windows_service: nil, - - "linux" => { - apt_package: [ Chef::Resource::AptPackage, Chef::Provider::Package::Apt ], - dpkg_package: [ Chef::Resource::DpkgPackage, Chef::Provider::Package::Dpkg ], - pacman_package: [ Chef::Resource::PacmanPackage, Chef::Provider::Package::Pacman ], - paludis_package: [ Chef::Resource::PaludisPackage, Chef::Provider::Package::Paludis ], - rpm_package: [ Chef::Resource::RpmPackage, Chef::Provider::Package::Rpm ], - yum_package: [ Chef::Resource::YumPackage, Chef::Provider::Package::Yum ], - - "debian" => { - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig::Debian ], - package: [ Chef::Resource::AptPackage, Chef::Provider::Package::Apt ], -# service: [ Chef::Resource::DebianService, Chef::Provider::Service::Debian ], + PROVIDERS = + { + bash: [ Chef::Resource::Bash, Chef::Provider::Script ], + breakpoint: [ Chef::Resource::Breakpoint, Chef::Provider::Breakpoint ], + chef_gem: [ Chef::Resource::ChefGem, Chef::Provider::Package::Rubygems ], + cookbook_file: [ Chef::Resource::CookbookFile, Chef::Provider::CookbookFile ], + csh: [ Chef::Resource::Csh, Chef::Provider::Script ], + deploy: [ Chef::Resource::Deploy, Chef::Provider::Deploy::Timestamped ], + deploy_revision: [ Chef::Resource::DeployRevision, Chef::Provider::Deploy::Revision ], + directory: [ Chef::Resource::Directory, Chef::Provider::Directory ], + easy_install_package: [ Chef::Resource::EasyInstallPackage, Chef::Provider::Package::EasyInstall ], + erl_call: [ Chef::Resource::ErlCall, Chef::Provider::ErlCall ], + execute: [ Chef::Resource::Execute, Chef::Provider::Execute ], + file: [ Chef::Resource::File, Chef::Provider::File ], + gem_package: [ Chef::Resource::GemPackage, Chef::Provider::Package::Rubygems ], + git: [ Chef::Resource::Git, Chef::Provider::Git ], + group: [ Chef::Resource::Group, Chef::Provider::Group::Gpasswd ], + homebrew_package: [ Chef::Resource::HomebrewPackage, Chef::Provider::Package::Homebrew ], + http_request: [ Chef::Resource::HttpRequest, Chef::Provider::HttpRequest ], + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], + link: [ Chef::Resource::Link, Chef::Provider::Link ], + log: [ Chef::Resource::Log, Chef::Provider::Log::ChefLog ], + macports_package: [ Chef::Resource::MacportsPackage, Chef::Provider::Package::Macports ], + mdadm: [ Chef::Resource::Mdadm, Chef::Provider::Mdadm ], + mount: [ Chef::Resource::Mount, Chef::Provider::Mount::Mount ], + perl: [ Chef::Resource::Perl, Chef::Provider::Script ], + portage_package: [ Chef::Resource::PortagePackage, Chef::Provider::Package::Portage ], + python: [ Chef::Resource::Python, Chef::Provider::Script ], + remote_directory: [ Chef::Resource::RemoteDirectory, Chef::Provider::RemoteDirectory ], + route: [ Chef::Resource::Route, Chef::Provider::Route ], + ruby: [ Chef::Resource::Ruby, Chef::Provider::Script ], + ruby_block: [ Chef::Resource::RubyBlock, Chef::Provider::RubyBlock ], + script: [ Chef::Resource::Script, Chef::Provider::Script ], + subversion: [ Chef::Resource::Subversion, Chef::Provider::Subversion ], + template: [ Chef::Resource::Template, Chef::Provider::Template ], + timestamped_deploy: [ Chef::Resource::TimestampedDeploy, Chef::Provider::Deploy::Timestamped ], + user: [ Chef::Resource::User, Chef::Provider::User::Useradd ], + whyrun_safe_ruby_block: [ Chef::Resource::WhyrunSafeRubyBlock, Chef::Provider::WhyrunSafeRubyBlock ], + + # We want to check that these are unsupported: + apt_package: nil, + bff_package: nil, + dpkg_package: nil, + dsc_script: nil, + ips_package: nil, + pacman_package: nil, + paludis_package: nil, + rpm_package: nil, + smartos_package: nil, + solaris_package: nil, + yum_package: nil, + windows_package: nil, + windows_service: nil, + + "linux" => { + apt_package: [ Chef::Resource::AptPackage, Chef::Provider::Package::Apt ], + dpkg_package: [ Chef::Resource::DpkgPackage, Chef::Provider::Package::Dpkg ], + pacman_package: [ Chef::Resource::PacmanPackage, Chef::Provider::Package::Pacman ], + paludis_package: [ Chef::Resource::PaludisPackage, Chef::Provider::Package::Paludis ], + rpm_package: [ Chef::Resource::RpmPackage, Chef::Provider::Package::Rpm ], + yum_package: [ Chef::Resource::YumPackage, Chef::Provider::Package::Yum ], "debian" => { - "7.0" => { - }, - "6.0" => { - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], -# service: [ Chef::Resource::InsservService, Chef::Provider::Service::Insserv ], - }, - "5.0" => { - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig::Debian ], + package: [ Chef::Resource::AptPackage, Chef::Provider::Package::Apt ], + # service: [ Chef::Resource::DebianService, Chef::Provider::Service::Debian ], + + "debian" => { + "7.0" => { + }, + "6.0" => { + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], + # service: [ Chef::Resource::InsservService, Chef::Provider::Service::Insserv ], + }, + "5.0" => { + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], + }, + }, + "gcel" => { + "3.1.4" => { + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], + }, + }, + "linaro" => { + "3.1.4" => { + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], + }, + }, + "linuxmint" => { + "3.1.4" => { + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], + # service: [ Chef::Resource::UpstartService, Chef::Provider::Service::Upstart ], + }, + }, + "raspbian" => { + "3.1.4" => { + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], + }, + }, + "ubuntu" => { + "11.10" => { + }, + "10.04" => { + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], + }, }, }, - "gcel" => { - "3.1.4" => { - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], - }, - }, - "linaro" => { - "3.1.4" => { - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], - }, - }, - "linuxmint" => { - "3.1.4" => { - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], -# service: [ Chef::Resource::UpstartService, Chef::Provider::Service::Upstart ], - }, - }, - "raspbian" => { - "3.1.4" => { - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], - }, - }, - "ubuntu" => { - "11.10" => { - }, - "10.04" => { - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], - }, - }, - }, - - "arch" => { - # TODO should be Chef::Resource::PacmanPackage - package: [ Chef::Resource::Package, Chef::Provider::Package::Pacman ], "arch" => { - "3.1.4" => { - } - }, - }, + # TODO should be Chef::Resource::PacmanPackage + package: [ Chef::Resource::Package, Chef::Provider::Package::Pacman ], - "freebsd" => { - group: [ Chef::Resource::Group, Chef::Provider::Group::Pw ], - user: [ Chef::Resource::User, Chef::Provider::User::Pw ], + "arch" => { + "3.1.4" => { + } + }, + }, "freebsd" => { - "3.1.4" => { + group: [ Chef::Resource::Group, Chef::Provider::Group::Pw ], + user: [ Chef::Resource::User, Chef::Provider::User::Pw ], + + "freebsd" => { + "3.1.4" => { + }, }, }, - }, - "suse" => { - group: [ Chef::Resource::Group, Chef::Provider::Group::Gpasswd ], "suse" => { - "12.0" => { - }, - %w(11.1 11.2 11.3) => { - group: [ Chef::Resource::Group, Chef::Provider::Group::Suse ], - }, - }, - "opensuse" => { -# service: [ Chef::Resource::RedhatService, Chef::Provider::Service::Redhat ], - package: [ Chef::Resource::ZypperPackage, Chef::Provider::Package::Zypper ], - group: [ Chef::Resource::Group, Chef::Provider::Group::Usermod ], - "12.3" => { - }, - "12.2" => { - group: [ Chef::Resource::Group, Chef::Provider::Group::Suse ], + group: [ Chef::Resource::Group, Chef::Provider::Group::Gpasswd ], + "suse" => { + "12.0" => { + }, + %w(11.1 11.2 11.3) => { + group: [ Chef::Resource::Group, Chef::Provider::Group::Suse ], + }, + }, + "opensuse" => { + # service: [ Chef::Resource::RedhatService, Chef::Provider::Service::Redhat ], + package: [ Chef::Resource::ZypperPackage, Chef::Provider::Package::Zypper ], + group: [ Chef::Resource::Group, Chef::Provider::Group::Usermod ], + "12.3" => { + }, + "12.2" => { + group: [ Chef::Resource::Group, Chef::Provider::Group::Suse ], + }, }, }, - }, - - "gentoo" => { - # TODO should be Chef::Resource::PortagePackage - package: [ Chef::Resource::Package, Chef::Provider::Package::Portage ], - portage_package: [ Chef::Resource::PortagePackage, Chef::Provider::Package::Portage ], -# service: [ Chef::Resource::GentooService, Chef::Provider::Service::Gentoo ], "gentoo" => { - "3.1.4" => { - }, - }, - }, + # TODO should be Chef::Resource::PortagePackage + package: [ Chef::Resource::Package, Chef::Provider::Package::Portage ], + portage_package: [ Chef::Resource::PortagePackage, Chef::Provider::Package::Portage ], + # service: [ Chef::Resource::GentooService, Chef::Provider::Service::Gentoo ], - "rhel" => { -# service: [ Chef::Resource::SystemdService, Chef::Provider::Service::Systemd ], - package: [ Chef::Resource::YumPackage, Chef::Provider::Package::Yum ], - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig::Redhat ], - - %w(amazon xcp xenserver ibm_powerkvm cloudlinux parallels) => { - "3.1.4" => { -# service: [ Chef::Resource::RedhatService, Chef::Provider::Service::Redhat ], + "gentoo" => { + "3.1.4" => { + }, }, }, - %w(redhat centos scientific oracle) => { - "7.0" => { - }, - "6.0" => { -# service: [ Chef::Resource::RedhatService, Chef::Provider::Service::Redhat ], - }, - }, - "fedora" => { - "15.0" => { - }, - "14.0" => { -# service: [ Chef::Resource::RedhatService, Chef::Provider::Service::Redhat ], + + "rhel" => { + # service: [ Chef::Resource::SystemdService, Chef::Provider::Service::Systemd ], + package: [ Chef::Resource::YumPackage, Chef::Provider::Package::Yum ], + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig::Redhat ], + + %w(amazon xcp xenserver ibm_powerkvm cloudlinux parallels) => { + "3.1.4" => { + # service: [ Chef::Resource::RedhatService, Chef::Provider::Service::Redhat ], + }, + }, + %w(redhat centos scientific oracle) => { + "7.0" => { + }, + "6.0" => { + # service: [ Chef::Resource::RedhatService, Chef::Provider::Service::Redhat ], + }, + }, + "fedora" => { + "15.0" => { + }, + "14.0" => { + # service: [ Chef::Resource::RedhatService, Chef::Provider::Service::Redhat ], + }, }, }, - }, - }, + }, - "darwin" => { - %w(mac_os_x mac_os_x_server) => { - group: [ Chef::Resource::Group, Chef::Provider::Group::Dscl ], - package: [ Chef::Resource::HomebrewPackage, Chef::Provider::Package::Homebrew ], - user: [ Chef::Resource::User, Chef::Provider::User::Dscl ], + "darwin" => { + %w(mac_os_x mac_os_x_server) => { + group: [ Chef::Resource::Group, Chef::Provider::Group::Dscl ], + package: [ Chef::Resource::HomebrewPackage, Chef::Provider::Package::Homebrew ], + user: [ Chef::Resource::User, Chef::Provider::User::Dscl ], - "mac_os_x" => { - "10.9.2" => { + "mac_os_x" => { + "10.9.2" => { + }, }, }, }, - }, - - "windows" => { - batch: [ Chef::Resource::Batch, Chef::Provider::Batch ], - dsc_script: [ Chef::Resource::DscScript, Chef::Provider::DscScript ], - env: [ Chef::Resource::Env, Chef::Provider::Env::Windows ], - group: [ Chef::Resource::Group, Chef::Provider::Group::Windows ], - mount: [ Chef::Resource::Mount, Chef::Provider::Mount::Windows ], - package: [ Chef::Resource::WindowsPackage, Chef::Provider::Package::Windows ], - powershell_script: [ Chef::Resource::PowershellScript, Chef::Provider::PowershellScript ], - service: [ Chef::Resource::WindowsService, Chef::Provider::Service::Windows ], - user: [ Chef::Resource::User, Chef::Provider::User::Windows ], - windows_package: [ Chef::Resource::WindowsPackage, Chef::Provider::Package::Windows ], - windows_service: [ Chef::Resource::WindowsService, Chef::Provider::Service::Windows ], "windows" => { - %w(mswin mingw32 windows) => { - "10.9.2" => { + batch: [ Chef::Resource::Batch, Chef::Provider::Batch ], + dsc_script: [ Chef::Resource::DscScript, Chef::Provider::DscScript ], + env: [ Chef::Resource::Env, Chef::Provider::Env::Windows ], + group: [ Chef::Resource::Group, Chef::Provider::Group::Windows ], + mount: [ Chef::Resource::Mount, Chef::Provider::Mount::Windows ], + package: [ Chef::Resource::WindowsPackage, Chef::Provider::Package::Windows ], + powershell_script: [ Chef::Resource::PowershellScript, Chef::Provider::PowershellScript ], + service: [ Chef::Resource::WindowsService, Chef::Provider::Service::Windows ], + user: [ Chef::Resource::User, Chef::Provider::User::Windows ], + windows_package: [ Chef::Resource::WindowsPackage, Chef::Provider::Package::Windows ], + windows_service: [ Chef::Resource::WindowsService, Chef::Provider::Service::Windows ], + + "windows" => { + %w(mswin mingw32 windows) => { + "10.9.2" => { + }, }, }, }, - }, - - "aix" => { - bff_package: [ Chef::Resource::BffPackage, Chef::Provider::Package::Aix ], - cron: [ Chef::Resource::Cron, Chef::Provider::Cron::Aix ], - group: [ Chef::Resource::Group, Chef::Provider::Group::Aix ], - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig::Aix ], - mount: [ Chef::Resource::Mount, Chef::Provider::Mount::Aix ], - # TODO should be Chef::Resource::BffPackage - package: [ Chef::Resource::Package, Chef::Provider::Package::Aix ], - rpm_package: [ Chef::Resource::RpmPackage, Chef::Provider::Package::Rpm ], - user: [ Chef::Resource::User, Chef::Provider::User::Aix ], -# service: [ Chef::Resource::AixService, Chef::Provider::Service::Aix ], "aix" => { + bff_package: [ Chef::Resource::BffPackage, Chef::Provider::Package::Aix ], + cron: [ Chef::Resource::Cron, Chef::Provider::Cron::Aix ], + group: [ Chef::Resource::Group, Chef::Provider::Group::Aix ], + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig::Aix ], + mount: [ Chef::Resource::Mount, Chef::Provider::Mount::Aix ], + # TODO should be Chef::Resource::BffPackage + package: [ Chef::Resource::Package, Chef::Provider::Package::Aix ], + rpm_package: [ Chef::Resource::RpmPackage, Chef::Provider::Package::Rpm ], + user: [ Chef::Resource::User, Chef::Provider::User::Aix ], + # service: [ Chef::Resource::AixService, Chef::Provider::Service::Aix ], + "aix" => { - "5.6" => { + "aix" => { + "5.6" => { + }, }, }, }, - }, - "hpux" => { "hpux" => { "hpux" => { - "3.1.4" => { - group: [ Chef::Resource::Group, Chef::Provider::Group::Usermod ] + "hpux" => { + "3.1.4" => { + group: [ Chef::Resource::Group, Chef::Provider::Group::Usermod ] + } } } - } - }, + }, - "netbsd" => { "netbsd" => { "netbsd" => { - "3.1.4" => { - group: [ Chef::Resource::Group, Chef::Provider::Group::Groupmod ], + "netbsd" => { + "3.1.4" => { + group: [ Chef::Resource::Group, Chef::Provider::Group::Groupmod ], + }, }, }, }, - }, - - "openbsd" => { - group: [ Chef::Resource::Group, Chef::Provider::Group::Usermod ], - package: [ Chef::Resource::OpenbsdPackage, Chef::Provider::Package::Openbsd ], "openbsd" => { + group: [ Chef::Resource::Group, Chef::Provider::Group::Usermod ], + package: [ Chef::Resource::OpenbsdPackage, Chef::Provider::Package::Openbsd ], + "openbsd" => { - "3.1.4" => { + "openbsd" => { + "3.1.4" => { + }, }, }, }, - }, - "solaris2" => { - group: [ Chef::Resource::Group, Chef::Provider::Group::Usermod ], - ips_package: [ Chef::Resource::IpsPackage, Chef::Provider::Package::Ips ], - package: [ Chef::Resource::SolarisPackage, Chef::Provider::Package::Solaris ], - mount: [ Chef::Resource::Mount, Chef::Provider::Mount::Solaris ], - solaris_package: [ Chef::Resource::SolarisPackage, Chef::Provider::Package::Solaris ], - - "smartos" => { - smartos_package: [ Chef::Resource::SmartosPackage, Chef::Provider::Package::SmartOS ], - package: [ Chef::Resource::SmartosPackage, Chef::Provider::Package::SmartOS ], + "solaris2" => { + group: [ Chef::Resource::Group, Chef::Provider::Group::Usermod ], + ips_package: [ Chef::Resource::IpsPackage, Chef::Provider::Package::Ips ], + package: [ Chef::Resource::SolarisPackage, Chef::Provider::Package::Solaris ], + mount: [ Chef::Resource::Mount, Chef::Provider::Mount::Solaris ], + solaris_package: [ Chef::Resource::SolarisPackage, Chef::Provider::Package::Solaris ], "smartos" => { - "3.1.4" => { + smartos_package: [ Chef::Resource::SmartosPackage, Chef::Provider::Package::SmartOS ], + package: [ Chef::Resource::SmartosPackage, Chef::Provider::Package::SmartOS ], + + "smartos" => { + "3.1.4" => { + }, }, }, - }, - "solaris2" => { - "nexentacore" => { - "3.1.4" => { + "solaris2" => { + "nexentacore" => { + "3.1.4" => { + }, }, - }, - "omnios" => { - "3.1.4" => { - user: [ Chef::Resource::User, Chef::Provider::User::Solaris ], - } - }, - "openindiana" => { - "3.1.4" => { + "omnios" => { + "3.1.4" => { + user: [ Chef::Resource::User, Chef::Provider::User::Solaris ], + } }, - }, - "opensolaris" => { - "3.1.4" => { + "openindiana" => { + "3.1.4" => { + }, }, - }, - "solaris2" => { - user: [ Chef::Resource::User, Chef::Provider::User::Solaris ], - "5.11" => { - package: [ Chef::Resource::IpsPackage, Chef::Provider::Package::Ips ], + "opensolaris" => { + "3.1.4" => { + }, }, - "5.9" => { + "solaris2" => { + user: [ Chef::Resource::User, Chef::Provider::User::Solaris ], + "5.11" => { + package: [ Chef::Resource::IpsPackage, Chef::Provider::Package::Ips ], + }, + "5.9" => { + }, }, }, - }, - }, + }, - "solaris" => { "solaris" => { "solaris" => { - "3.1.4" => { + "solaris" => { + "3.1.4" => { + }, }, }, }, - }, - "exherbo" => { "exherbo" => { "exherbo" => { - "3.1.4" => { - # TODO should be Chef::Resource::PaludisPackage - package: [ Chef::Resource::Package, Chef::Provider::Package::Paludis ] + "exherbo" => { + "3.1.4" => { + # TODO should be Chef::Resource::PaludisPackage + package: [ Chef::Resource::Package, Chef::Provider::Package::Paludis ] + } } } } } - } - - def self.create_provider_tests(providers, test, expected, filter) - expected = expected.merge(providers.select { |key, value| key.is_a?(Symbol) }) - providers.each do |key, value| - if !key.is_a?(Symbol) - next_test = test.merge({ filter => key }) - next_filter = - case filter - when :os - :platform_family - when :platform_family - :platform - when :platform - :platform_version - when :platform_version - nil - else - raise "Hash too deep; only os, platform_family, platform and platform_version supported" - end - create_provider_tests(value, next_test, expected, next_filter) + + def self.create_provider_tests(providers, test, expected, filter) + expected = expected.merge(providers.select { |key, value| key.is_a?(Symbol) }) + providers.each do |key, value| + if !key.is_a?(Symbol) + next_test = test.merge({ filter => key }) + next_filter = + case filter + when :os + :platform_family + when :platform_family + :platform + when :platform + :platform_version + when :platform_version + nil + else + raise "Hash too deep; only os, platform_family, platform and platform_version supported" + end + create_provider_tests(value, next_test, expected, next_filter) + end end - end - # If there is no filter, we're as deep as we need to go - if !filter - on_platform test.delete(:platform), test do - expect_providers(expected) + # If there is no filter, we're as deep as we need to go + if !filter + on_platform test.delete(:platform), test do + expect_providers(expected) + end end end - end - create_provider_tests(PROVIDERS, {}, {}, :os) + create_provider_tests(PROVIDERS, {}, {}, :os) + end end |