diff options
author | tyler-ball <tyleraball@gmail.com> | 2014-11-13 11:05:10 -0800 |
---|---|---|
committer | tyler-ball <tyleraball@gmail.com> | 2014-11-13 11:05:10 -0800 |
commit | 13fba4b26511382037efb9e36ce84eda1ba569e1 (patch) | |
tree | 5e3e2dd4094480815d174b08aaea510b3f5cf269 /spec | |
parent | f5b36609eeb85d060e61293678488490cd382ea1 (diff) | |
parent | 2f8a0e92db2244b9404472b8ecae52c373d758ea (diff) | |
download | chef-13fba4b26511382037efb9e36ce84eda1ba569e1.tar.gz |
Merge branch 'audit-mode' into tball/audit-teststball/audit-tests
Diffstat (limited to 'spec')
-rw-r--r-- | spec/integration/knife/serve_spec.rb | 4 | ||||
-rw-r--r-- | spec/support/pedant/pedant_config.rb | 7 | ||||
-rw-r--r-- | spec/support/shared/unit/resource/static_provider_resolution.rb | 7 | ||||
-rw-r--r-- | spec/unit/api_client/registration_spec.rb | 22 | ||||
-rw-r--r-- | spec/unit/knife/bootstrap_spec.rb | 28 | ||||
-rw-r--r-- | spec/unit/mixin/deep_merge_spec.rb | 14 | ||||
-rw-r--r-- | spec/unit/node/attribute_spec.rb | 6 | ||||
-rw-r--r-- | spec/unit/node_spec.rb | 346 | ||||
-rw-r--r-- | spec/unit/provider/service/systemd_service_spec.rb | 337 | ||||
-rw-r--r-- | spec/unit/provider_resolver_spec.rb | 185 | ||||
-rw-r--r-- | spec/unit/resource/timestamped_deploy_spec.rb | 37 | ||||
-rw-r--r-- | spec/unit/runner_spec.rb | 4 |
12 files changed, 754 insertions, 243 deletions
diff --git a/spec/integration/knife/serve_spec.rb b/spec/integration/knife/serve_spec.rb index dd3fa5c0d1..7bf7d29b40 100644 --- a/spec/integration/knife/serve_spec.rb +++ b/spec/integration/knife/serve_spec.rb @@ -31,14 +31,14 @@ describe 'knife serve', :workstation do exception = nil t = Thread.new do begin - knife('serve --chef-zero-port=8889') + knife('serve --chef-zero-port=8890') rescue exception = $! end end begin Chef::Config.log_level = :debug - Chef::Config.chef_server_url = 'http://localhost:8889' + Chef::Config.chef_server_url = 'http://localhost:8890' Chef::Config.node_name = nil Chef::Config.client_key = nil api = Chef::ServerAPI.new diff --git a/spec/support/pedant/pedant_config.rb b/spec/support/pedant/pedant_config.rb index 6818d29d74..f7d14d8f17 100644 --- a/spec/support/pedant/pedant_config.rb +++ b/spec/support/pedant/pedant_config.rb @@ -72,6 +72,13 @@ superuser_name 'admin' superuser_key key webui_key key +# When we updated Chef to RSpec 3 there were gem conflicts with chef-pedant. +# We removed chef as a chef-pedant gem dependency in pedant.gemfile, but this +# caused chef-pedant to fail because it could not query for the chef version +# on the box pedant is running on. X-Chef-Version isn't needed in server +# requests for these tests, so we've disabled it. +ingore_x_chef_version true + # Set the platform_class platform_class Pedant::OpenSourcePlatform diff --git a/spec/support/shared/unit/resource/static_provider_resolution.rb b/spec/support/shared/unit/resource/static_provider_resolution.rb index 147852598a..2bc4c70d95 100644 --- a/spec/support/shared/unit/resource/static_provider_resolution.rb +++ b/spec/support/shared/unit/resource/static_provider_resolution.rb @@ -43,12 +43,7 @@ def static_provider_resolution(opts={}) node } let(:events) { Chef::EventDispatch::Dispatcher.new } - let(:provider_resolver) { Chef::ProviderResolver.new(node) } - let(:run_context) { - run_context = Chef::RunContext.new(node, {}, events) - run_context.provider_resolver = provider_resolver - run_context - } + let(:run_context) { Chef::RunContext.new(node, {}, events) } let(:resource) { resource_class.new("foo", run_context) } it "should return a #{resource_class}" do diff --git a/spec/unit/api_client/registration_spec.rb b/spec/unit/api_client/registration_spec.rb index 55348ec8ee..d6230afb6a 100644 --- a/spec/unit/api_client/registration_spec.rb +++ b/spec/unit/api_client/registration_spec.rb @@ -209,6 +209,28 @@ describe Chef::ApiClient::Registration do registration.write_key expect(IO.read(key_location)).to eq("--begin rsa key etc--") end + + context 'when the client key location is a symlink' do + it 'does not follow the symlink', :unix_only do + expected_flags = (File::CREAT|File::TRUNC|File::RDWR) + + if defined?(File::NOFOLLOW) + expected_flags |= File::NOFOLLOW + end + + expect(registration.file_flags).to eq(expected_flags) + end + + context 'with follow_client_key_symlink set to true' do + before do + Chef::Config[:follow_client_key_symlink] = true + end + + it 'follows the symlink', :unix_only do + expect(registration.file_flags).to eq(File::CREAT|File::TRUNC|File::RDWR) + end + end + end end describe "when registering a client" do diff --git a/spec/unit/knife/bootstrap_spec.rb b/spec/unit/knife/bootstrap_spec.rb index 4de2b4531d..27731ea9f6 100644 --- a/spec/unit/knife/bootstrap_spec.rb +++ b/spec/unit/knife/bootstrap_spec.rb @@ -29,7 +29,7 @@ describe Chef::Knife::Bootstrap do Chef::Log.logger = Logger.new(StringIO.new) Chef::Config[:knife][:bootstrap_template] = bootstrap_template unless bootstrap_template.nil? - k = Chef::Knife::Bootstrap.new + k = Chef::Knife::Bootstrap.new(bootstrap_cli_options) k.merge_configs allow(k.ui).to receive(:stderr).and_return(stderr) @@ -41,11 +41,37 @@ describe Chef::Knife::Bootstrap do let(:bootstrap_template) { nil } + let(:bootstrap_cli_options) { [ ] } + it "should use chef-full as default template" do expect(knife.bootstrap_template).to be_a_kind_of(String) expect(File.basename(knife.bootstrap_template)).to eq("chef-full") end + context "with :distro and :bootstrap_template cli options" do + let(:bootstrap_cli_options) { [ "--bootstrap-template", "my-template", "--distro", "other-template" ] } + + it "should select bootstrap template" do + expect(File.basename(knife.bootstrap_template)).to eq("my-template") + end + end + + context "with :distro and :template_file cli options" do + let(:bootstrap_cli_options) { [ "--distro", "my-template", "--template-file", "other-template" ] } + + it "should select bootstrap template" do + expect(File.basename(knife.bootstrap_template)).to eq("other-template") + end + end + + context "with :bootstrap_template and :template_file cli options" do + let(:bootstrap_cli_options) { [ "--bootstrap-template", "my-template", "--template-file", "other-template" ] } + + it "should select bootstrap template" do + expect(File.basename(knife.bootstrap_template)).to eq("my-template") + end + end + context "when finding templates" do context "when :bootstrap_template config is set to a file" do context "that doesn't exist" do diff --git a/spec/unit/mixin/deep_merge_spec.rb b/spec/unit/mixin/deep_merge_spec.rb index 40e749ecc0..779445e04e 100644 --- a/spec/unit/mixin/deep_merge_spec.rb +++ b/spec/unit/mixin/deep_merge_spec.rb @@ -236,20 +236,6 @@ describe Chef::Mixin::DeepMerge, "deep_merge!" do @dm.deep_merge!(hash_src, hash_dst) expect(hash_dst).to eq({"item" => "orange"}) end - - it 'should overwrite hashes with nil' do - hash_src = {"item" => { "1" => "2"}, "other" => true } - hash_dst = {"item" => nil } - @dm.deep_merge!(hash_src, hash_dst) - expect(hash_dst).to eq({"item" => nil, "other" => true }) - end - - it 'should overwrite strings with nil' do - hash_src = {"item" => "to_overwrite", "other" => false } - hash_dst = {"item" => nil } - @dm.deep_merge!(hash_src, hash_dst) - expect(hash_dst).to eq({"item" => nil, "other" => false }) - end end # deep_merge! # Chef specific diff --git a/spec/unit/node/attribute_spec.rb b/spec/unit/node/attribute_spec.rb index c5d0f2398e..6cdf60550f 100644 --- a/spec/unit/node/attribute_spec.rb +++ b/spec/unit/node/attribute_spec.rb @@ -285,7 +285,7 @@ describe Chef::Node::Attribute do end it "prefers 'forced default' over any other default" do - @attributes.default!["default"] = "force default" + @attributes.force_default["default"] = "force default" @attributes.role_default["default"] = "role default" @attributes.env_default["default"] = "environment default" expect(@attributes["default"]).to eq("force default") @@ -307,7 +307,7 @@ describe Chef::Node::Attribute do end it "prefers 'forced overrides' over role or cookbook overrides" do - @attributes.override!["override"] = "force override" + @attributes.force_override["override"] = "force override" @attributes.env_override["override"] = "environment override" @attributes.role_override["override"] = "role override" expect(@attributes["override"]).to eq("force override") @@ -939,7 +939,6 @@ describe Chef::Node::Attribute do end - describe "values" do before do @attributes = Chef::Node::Attribute.new( @@ -1185,4 +1184,3 @@ describe Chef::Node::Attribute do end end - diff --git a/spec/unit/node_spec.rb b/spec/unit/node_spec.rb index 24209d367f..1daaf9ec52 100644 --- a/spec/unit/node_spec.rb +++ b/spec/unit/node_spec.rb @@ -247,13 +247,6 @@ describe Chef::Node do node.default.fuu.bahrr.baz = "qux" expect(node.fuu.bahrr.baz).to eq("qux") end - - it "accesses force defaults via default!" do - node.default![:foo] = "wet bar" - node.default[:foo] = "bar" - expect(node[:foo]).to eq("wet bar") - end - end describe "override attributes" do @@ -292,13 +285,330 @@ describe Chef::Node do node.override.fuu.bahrr.baz = "qux" expect(node.fuu.bahrr.baz).to eq("qux") end + end + + describe "globally deleting attributes" do + context "with hash values" do + before do + node.role_default["mysql"]["server"]["port"] = 1234 + node.normal["mysql"]["server"]["port"] = 2345 + node.override["mysql"]["server"]["port"] = 3456 + end + + it "deletes all the values and returns the value with the highest precidence" do + expect( node.rm("mysql", "server", "port") ).to eql(3456) + expect( node["mysql"]["server"]["port"] ).to be_nil + expect( node["mysql"]["server"] ).to eql({}) + end + + it "deletes nested things correctly" do + node.default["mysql"]["client"]["client_setting"] = "foo" + expect( node.rm("mysql", "server") ).to eql( {"port" => 3456} ) + expect( node["mysql"] ).to eql( { "client" => { "client_setting" => "foo" } } ) + end + + it "returns nil if the node attribute does not exist" do + expect( node.rm("no", "such", "thing") ).to be_nil + end - it "sets force_overrides via override!" do - node.override![:foo] = "wet bar" - node.override[:foo] = "bar" - expect(node[:foo]).to eq("wet bar") + it "can delete the entire tree" do + expect( node.rm("mysql") ).to eql({"server"=>{"port"=>3456}}) + end end + context "when trying to delete through a thing that isn't an array-like or hash-like object" do + before do + node.default["mysql"] = true + end + + it "returns nil when you're two levels deeper" do + expect( node.rm("mysql", "server", "port") ).to eql(nil) + end + + it "returns nil when you're one level deeper" do + expect( node.rm("mysql", "server") ).to eql(nil) + end + + it "correctly deletes at the top level" do + expect( node.rm("mysql") ).to eql(true) + end + end + + context "with array indexes" do + before do + node.role_default["mysql"]["server"][0]["port"] = 1234 + node.normal["mysql"]["server"][0]["port"] = 2345 + node.override["mysql"]["server"][0]["port"] = 3456 + node.override["mysql"]["server"][1]["port"] = 3456 + end + + it "deletes the array element" do + expect( node.rm("mysql", "server", 0, "port") ).to eql(3456) + expect( node["mysql"]["server"][0]["port"] ).to be_nil + expect( node["mysql"]["server"][1]["port"] ).to eql(3456) + end + end + + context "with real arrays" do + before do + node.role_default["mysql"]["server"] = [ { + "port" => 1234, + } ] + node.normal["mysql"]["server"] = [ { + "port" => 2345, + } ] + node.override["mysql"]["server"] = [ { + "port" => 3456, + } ] + end + + it "deletes the array element" do + expect( node.rm("mysql", "server", 0, "port") ).to eql(3456) + expect( node["mysql"]["server"][0]["port"] ).to be_nil + end + + it "does not have a horrible error message when mistaking arrays for hashes" do + expect { node.rm("mysql", "server", "port") }.to raise_error(TypeError, "Wrong type in index of attribute (did you use a Hash index on an Array?)") + end + end + end + + describe "granular deleting attributes" do + context "when only defaults exist" do + before do + node.role_default["mysql"]["server"]["port"] = 1234 + node.default["mysql"]["server"]["port"] = 2345 + node.force_default["mysql"]["server"]["port"] = 3456 + end + + it "returns the deleted values" do + expect( node.rm_default("mysql", "server", "port") ).to eql(3456) + end + + it "returns nil for the combined attribues" do + expect( node.rm_default("mysql", "server", "port") ).to eql(3456) + expect( node["mysql"]["server"]["port"] ).to eql(nil) + end + + it "returns an empty hash for the default attrs" do + expect( node.rm_default("mysql", "server", "port") ).to eql(3456) + # this auto-vivifies, should it? + expect( node.default_attrs["mysql"]["server"]["port"] ).to eql({}) + end + + it "returns an empty hash after the last key is deleted" do + expect( node.rm_default("mysql", "server", "port") ).to eql(3456) + expect( node["mysql"]["server"] ).to eql({}) + end + end + + context "when trying to delete through a thing that isn't an array-like or hash-like object" do + before do + node.default["mysql"] = true + end + + it "returns nil when you're two levels deeper" do + expect( node.rm_default("mysql", "server", "port") ).to eql(nil) + end + + it "returns nil when you're one level deeper" do + expect( node.rm_default("mysql", "server") ).to eql(nil) + end + + it "correctly deletes at the top level" do + expect( node.rm_default("mysql") ).to eql(true) + end + end + + context "when a higher precedence exists" do + before do + node.role_default["mysql"]["server"]["port"] = 1234 + node.default["mysql"]["server"]["port"] = 2345 + node.force_default["mysql"]["server"]["port"] = 3456 + + node.override["mysql"]["server"]["port"] = 9999 + end + + it "returns the deleted values" do + expect( node.rm_default("mysql", "server", "port") ).to eql(3456) + end + + it "returns the higher precedence values after the delete" do + expect( node.rm_default("mysql", "server", "port") ).to eql(3456) + expect( node["mysql"]["server"]["port"] ).to eql(9999) + end + + it "returns an empty has for the default attrs" do + expect( node.rm_default("mysql", "server", "port") ).to eql(3456) + # this auto-vivifies, should it? + expect( node.default_attrs["mysql"]["server"]["port"] ).to eql({}) + end + end + + context "when a lower precedence exists" do + before do + node.default["mysql"]["server"]["port"] = 2345 + node.override["mysql"]["server"]["port"] = 9999 + node.role_override["mysql"]["server"]["port"] = 9876 + node.force_override["mysql"]["server"]["port"] = 6669 + end + + it "returns the deleted values" do + expect( node.rm_override("mysql", "server", "port") ).to eql(6669) + end + + it "returns the lower precedence levels after the delete" do + expect( node.rm_override("mysql", "server", "port") ).to eql(6669) + expect( node["mysql"]["server"]["port"] ).to eql(2345) + end + + it "returns an empty has for the override attrs" do + expect( node.rm_override("mysql", "server", "port") ).to eql(6669) + # this auto-vivifies, should it? + expect( node.override_attrs["mysql"]["server"]["port"] ).to eql({}) + end + end + + it "rm_default returns nil on deleting non-existent values" do + expect( node.rm_default("no", "such", "thing") ).to be_nil + end + + it "rm_normal returns nil on deleting non-existent values" do + expect( node.rm_normal("no", "such", "thing") ).to be_nil + end + + it "rm_override returns nil on deleting non-existent values" do + expect( node.rm_override("no", "such", "thing") ).to be_nil + end + end + + describe "granular replacing attributes" do + it "removes everything at the level of the last key" do + node.default["mysql"]["server"]["port"] = 2345 + + node.default!["mysql"]["server"] = { "data_dir" => "/my_raid_volume/lib/mysql" } + + expect( node["mysql"]["server"] ).to eql({ "data_dir" => "/my_raid_volume/lib/mysql" }) + end + + it "replaces a value at the cookbook sub-level of the atributes only" do + node.default["mysql"]["server"]["port"] = 2345 + node.default["mysql"]["server"]["service_name"] = "fancypants-sql" + node.role_default["mysql"]["server"]["port"] = 1234 + node.force_default["mysql"]["server"]["port"] = 3456 + + node.default!["mysql"]["server"] = { "data_dir" => "/my_raid_volume/lib/mysql" } + + expect( node["mysql"]["server"]["port"] ).to eql(3456) + expect( node["mysql"]["server"]["service_name"] ).to be_nil + expect( node["mysql"]["server"]["data_dir"] ).to eql("/my_raid_volume/lib/mysql") + expect( node["mysql"]["server"] ).to eql({ "port" => 3456, "data_dir" => "/my_raid_volume/lib/mysql" }) + end + + it "higher precedence values aren't removed" do + node.role_default["mysql"]["server"]["port"] = 1234 + node.default["mysql"]["server"]["port"] = 2345 + node.force_default["mysql"]["server"]["port"] = 3456 + node.override["mysql"]["server"]["service_name"] = "fancypants-sql" + + node.default!["mysql"]["server"] = { "data_dir" => "/my_raid_volume/lib/mysql" } + + expect( node["mysql"]["server"]["port"] ).to eql(3456) + expect( node["mysql"]["server"]["data_dir"] ).to eql("/my_raid_volume/lib/mysql") + expect( node["mysql"]["server"] ).to eql({ "service_name" => "fancypants-sql", "port" => 3456, "data_dir" => "/my_raid_volume/lib/mysql" }) + end + end + + describe "granular force replacing attributes" do + it "removes everything at the level of the last key" do + node.force_default["mysql"]["server"]["port"] = 2345 + + node.force_default!["mysql"]["server"] = { + "data_dir" => "/my_raid_volume/lib/mysql", + } + + expect( node["mysql"]["server"] ).to eql({ + "data_dir" => "/my_raid_volume/lib/mysql", + }) + end + + it "removes all values from the precedence level when setting" do + node.role_default["mysql"]["server"]["port"] = 1234 + node.default["mysql"]["server"]["port"] = 2345 + node.force_default["mysql"]["server"]["port"] = 3456 + + node.force_default!["mysql"]["server"] = { + "data_dir" => "/my_raid_volume/lib/mysql", + } + + expect( node["mysql"]["server"]["port"] ).to be_nil + expect( node["mysql"]["server"]["data_dir"] ).to eql("/my_raid_volume/lib/mysql") + expect( node["mysql"]["server"] ).to eql({ + "data_dir" => "/my_raid_volume/lib/mysql", + }) + end + + it "higher precedence levels are not removed" do + node.role_default["mysql"]["server"]["port"] = 1234 + node.default["mysql"]["server"]["port"] = 2345 + node.force_default["mysql"]["server"]["port"] = 3456 + node.override["mysql"]["server"]["service_name"] = "fancypants-sql" + + node.force_default!["mysql"]["server"] = { + "data_dir" => "/my_raid_volume/lib/mysql", + } + + expect( node["mysql"]["server"]["port"] ).to be_nil + expect( node["mysql"]["server"]["data_dir"] ).to eql("/my_raid_volume/lib/mysql") + expect( node["mysql"]["server"] ).to eql({ + "service_name" => "fancypants-sql", + "data_dir" => "/my_raid_volume/lib/mysql", + }) + end + + it "will autovivify" do + node.force_default!["mysql"]["server"] = { + "data_dir" => "/my_raid_volume/lib/mysql", + } + expect( node["mysql"]["server"]["data_dir"] ).to eql("/my_raid_volume/lib/mysql") + end + + it "lower precedence levels aren't removed" do + node.role_override["mysql"]["server"]["port"] = 1234 + node.override["mysql"]["server"]["port"] = 2345 + node.force_override["mysql"]["server"]["port"] = 3456 + node.default["mysql"]["server"]["service_name"] = "fancypants-sql" + + node.force_override!["mysql"]["server"] = { + "data_dir" => "/my_raid_volume/lib/mysql", + } + + expect( node["mysql"]["server"]["port"] ).to be_nil + expect( node["mysql"]["server"]["data_dir"] ).to eql("/my_raid_volume/lib/mysql") + expect( node["mysql"]["server"] ).to eql({ + "service_name" => "fancypants-sql", + "data_dir" => "/my_raid_volume/lib/mysql", + }) + end + + it "when overwriting a non-hash/array" do + node.override["mysql"] = false + node.force_override["mysql"] = true + node.force_override!["mysql"]["server"] = { + "data_dir" => "/my_raid_volume/lib/mysql", + } + expect( node["mysql"]["server"]["data_dir"] ).to eql("/my_raid_volume/lib/mysql") + end + + it "when overwriting an array with a hash" do + node.force_override["mysql"][0] = true + node.force_override!["mysql"]["server"] = { + "data_dir" => "/my_raid_volume/lib/mysql", + } + expect( node["mysql"]["server"] ).to eql({ + "data_dir" => "/my_raid_volume/lib/mysql", + }) + end end it "should raise an ArgumentError if you ask for an attribute that doesn't exist via method_missing" do @@ -472,8 +782,8 @@ describe Chef::Node do node.automatic_attrs[:recipes] = [ "nginx::other_module" ] node.loaded_recipe(:nginx, "module") expect(node.automatic_attrs[:recipes].length).to eq(2) - expect(node.recipe?("nginx::module")).to be_truthy - expect(node.recipe?("nginx::other_module")).to be_truthy + expect(node.recipe?("nginx::module")).to be true + expect(node.recipe?("nginx::other_module")).to be true end end @@ -484,11 +794,11 @@ describe Chef::Node do end it "finds the recipe" do - expect(node.recipe?("nginx::module")).to be_truthy + expect(node.recipe?("nginx::module")).to be true end it "does not find a recipe not in the run list" do - expect(node.recipe?("nginx::other_module")).to be_falsey + expect(node.recipe?("nginx::other_module")).to be false end end context "when a recipe is in the expanded run list only" do @@ -498,11 +808,11 @@ describe Chef::Node do end it "finds a recipe in the expanded run list" do - expect(node.recipe?("nginx::module")).to be_truthy + expect(node.recipe?("nginx::module")).to be true end it "does not find a recipe that's not in the run list" do - expect(node.recipe?("nginx::other_module")).to be_falsey + expect(node.recipe?("nginx::other_module")).to be false end end end @@ -536,7 +846,6 @@ describe Chef::Node do @expansion.default_attrs.replace({:default => "from role", :d_role => "role only"}) @expansion.override_attrs.replace({:override => "from role", :o_role => "role only"}) - @environment = Chef::Environment.new @environment.default_attributes = {:default => "from env", :d_env => "env only" } @environment.override_attributes = {:override => "from env", :o_env => "env only"} @@ -753,7 +1062,6 @@ describe Chef::Node do expect(node_for_json["default"]["env default"]).to eq("env default") end - it "should deserialize itself from json", :json => true do node.from_file(File.expand_path("nodes/test.example.com.rb", CHEF_SPEC_DATA)) json = Chef::JSONCompat.to_json(node) diff --git a/spec/unit/provider/service/systemd_service_spec.rb b/spec/unit/provider/service/systemd_service_spec.rb index 2bdbdaad05..90b669a459 100644 --- a/spec/unit/provider/service/systemd_service_spec.rb +++ b/spec/unit/provider/service/systemd_service_spec.rb @@ -19,238 +19,261 @@ require 'spec_helper' describe Chef::Provider::Service::Systemd do + + let(:node) { Chef::Node.new } + + let(:events) { Chef::EventDispatch::Dispatcher.new } + + let(:run_context) { Chef::RunContext.new(node, {}, events) } + + let(:service_name) { "rsyslog.service" } + + let(:new_resource) { Chef::Resource::Service.new(service_name) } + + let(:provider) { Chef::Provider::Service::Systemd.new(new_resource, run_context) } + + let(:shell_out_success) do + double('shell_out_with_systems_locale', :exitstatus => 0, :error? => false) + end + + let(:shell_out_failure) do + double('shell_out_with_systems_locale', :exitstatus => 1, :error? => true) + end + + let(:current_resource) { Chef::Resource::Service.new(service_name) } + before(:each) do - @node = Chef::Node.new - @events = Chef::EventDispatch::Dispatcher.new - @run_context = Chef::RunContext.new(@node, {}, @events) - @new_resource = Chef::Resource::Service.new('rsyslog.service') - @provider = Chef::Provider::Service::Systemd.new(@new_resource, @run_context) - - @shell_out_success = double('shell_out_with_systems_locale', - :exitstatus => 0, :error? => false) - @shell_out_failure = double('shell_out_with_systems_locale', - :exitstatus => 1, :error? => true) + allow(Chef::Resource::Service).to receive(:new).with(service_name).and_return(current_resource) end describe "load_current_resource" do - before(:each) do - @current_resource = Chef::Resource::Service.new('rsyslog.service') - allow(Chef::Resource::Service).to receive(:new).and_return(@current_resource) - allow(@provider).to receive(:is_active?).and_return(false) - allow(@provider).to receive(:is_enabled?).and_return(false) + before(:each) do + allow(provider).to receive(:is_active?).and_return(false) + allow(provider).to receive(:is_enabled?).and_return(false) end it "should create a current resource with the name of the new resource" do - expect(Chef::Resource::Service).to receive(:new).and_return(@current_resource) - @provider.load_current_resource + expect(Chef::Resource::Service).to receive(:new).with(new_resource.name).and_return(current_resource) + provider.load_current_resource end it "should set the current resources service name to the new resources service name" do - expect(@current_resource).to receive(:service_name).with(@new_resource.service_name) - @provider.load_current_resource + provider.load_current_resource + expect(current_resource.service_name).to eql(service_name) end it "should check if the service is running" do - expect(@provider).to receive(:is_active?) - @provider.load_current_resource + expect(provider).to receive(:is_active?) + provider.load_current_resource end it "should set running to true if the service is running" do - allow(@provider).to receive(:is_active?).and_return(true) - expect(@current_resource).to receive(:running).with(true) - @provider.load_current_resource + allow(provider).to receive(:is_active?).and_return(true) + provider.load_current_resource + expect(current_resource.running).to be true end it "should set running to false if the service is not running" do - allow(@provider).to receive(:is_active?).and_return(false) - expect(@current_resource).to receive(:running).with(false) - @provider.load_current_resource + allow(provider).to receive(:is_active?).and_return(false) + provider.load_current_resource + expect(current_resource.running).to be false end describe "when a status command has been specified" do before do - allow(@new_resource).to receive(:status_command).and_return("/bin/chefhasmonkeypants status") + allow(new_resource).to receive(:status_command).and_return("/bin/chefhasmonkeypants status") end it "should run the services status command if one has been specified" do - allow(@provider).to receive(:shell_out).and_return(@shell_out_success) - expect(@current_resource).to receive(:running).with(true) - @provider.load_current_resource + allow(provider).to receive(:shell_out).and_return(shell_out_success) + provider.load_current_resource + expect(current_resource.running).to be true end it "should run the services status command if one has been specified and properly set status check state" do - allow(@provider).to receive(:shell_out).with("/bin/chefhasmonkeypants status").and_return(@shell_out_success) - @provider.load_current_resource - expect(@provider.instance_variable_get("@status_check_success")).to be_truthy + allow(provider).to receive(:shell_out).with("/bin/chefhasmonkeypants status").and_return(shell_out_success) + provider.load_current_resource + expect(provider.status_check_success).to be true end it "should set running to false if a status command fails" do - allow(@provider).to receive(:shell_out).and_return(@shell_out_failure) - expect(@current_resource).to receive(:running).with(false) - @provider.load_current_resource + allow(provider).to receive(:shell_out).and_return(shell_out_failure) + provider.load_current_resource + expect(current_resource.running).to be false end it "should update state to indicate status check failed when a status command fails" do - allow(@provider).to receive(:shell_out).and_return(@shell_out_failure) - @provider.load_current_resource - expect(@provider.instance_variable_get("@status_check_success")).to be_falsey + allow(provider).to receive(:shell_out).and_return(shell_out_failure) + provider.load_current_resource + expect(provider.status_check_success).to be false end end it "should check if the service is enabled" do - expect(@provider).to receive(:is_enabled?) - @provider.load_current_resource + expect(provider).to receive(:is_enabled?) + provider.load_current_resource end it "should set enabled to true if the service is enabled" do - allow(@provider).to receive(:is_enabled?).and_return(true) - expect(@current_resource).to receive(:enabled).with(true) - @provider.load_current_resource + allow(provider).to receive(:is_enabled?).and_return(true) + provider.load_current_resource + expect(current_resource.enabled).to be true end it "should set enabled to false if the service is not enabled" do - allow(@provider).to receive(:is_enabled?).and_return(false) - expect(@current_resource).to receive(:enabled).with(false) - @provider.load_current_resource + allow(provider).to receive(:is_enabled?).and_return(false) + provider.load_current_resource + expect(current_resource.enabled).to be false end it "should return the current resource" do - expect(@provider.load_current_resource).to eql(@current_resource) + expect(provider.load_current_resource).to eql(current_resource) end end - describe "start and stop service" do - before(:each) do - @current_resource = Chef::Resource::Service.new('rsyslog.service') - allow(Chef::Resource::Service).to receive(:new).and_return(@current_resource) - @provider.current_resource = @current_resource - end + def setup_current_resource + provider.current_resource = current_resource + current_resource.service_name(service_name) + end - it "should call the start command if one is specified" do - allow(@new_resource).to receive(:start_command).and_return("/sbin/rsyslog startyousillysally") - expect(@provider).to receive(:shell_out_with_systems_locale!).with("/sbin/rsyslog startyousillysally") - @provider.start_service - end + %w{/usr/bin/systemctl /bin/systemctl}.each do |systemctl_path| + describe "when systemctl path is #{systemctl_path}" do + before(:each) do + setup_current_resource + allow(provider).to receive(:which).with("systemctl").and_return(systemctl_path) + end - it "should call '/bin/systemctl start service_name' if no start command is specified" do - expect(@provider).to receive(:shell_out_with_systems_locale!).with("/bin/systemctl start #{@new_resource.service_name}").and_return(@shell_out_success) - @provider.start_service - end + describe "start and stop service" do - it "should not call '/bin/systemctl start service_name' if it is already running" do - allow(@current_resource).to receive(:running).and_return(true) - expect(@provider).not_to receive(:shell_out_with_systems_locale!).with("/bin/systemctl start #{@new_resource.service_name}") - @provider.start_service - end + it "should call the start command if one is specified" do + allow(new_resource).to receive(:start_command).and_return("/sbin/rsyslog startyousillysally") + expect(provider).to receive(:shell_out_with_systems_locale!).with("/sbin/rsyslog startyousillysally") + provider.start_service + end - it "should call the restart command if one is specified" do - allow(@current_resource).to receive(:running).and_return(true) - allow(@new_resource).to receive(:restart_command).and_return("/sbin/rsyslog restartyousillysally") - expect(@provider).to receive(:shell_out_with_systems_locale!).with("/sbin/rsyslog restartyousillysally") - @provider.restart_service - end + it "should call '#{systemctl_path} start service_name' if no start command is specified" do + expect(provider).to receive(:shell_out_with_systems_locale!).with("#{systemctl_path} start #{service_name}").and_return(shell_out_success) + provider.start_service + end - it "should call '/bin/systemctl restart service_name' if no restart command is specified" do - allow(@current_resource).to receive(:running).and_return(true) - expect(@provider).to receive(:shell_out_with_systems_locale!).with("/bin/systemctl restart #{@new_resource.service_name}").and_return(@shell_out_success) - @provider.restart_service - end + it "should not call '#{systemctl_path} start service_name' if it is already running" do + current_resource.running(true) + expect(provider).not_to receive(:shell_out_with_systems_locale!).with("#{systemctl_path} start #{service_name}") + provider.start_service + end - describe "reload service" do - context "when a reload command is specified" do - it "should call the reload command" do - allow(@current_resource).to receive(:running).and_return(true) - allow(@new_resource).to receive(:reload_command).and_return("/sbin/rsyslog reloadyousillysally") - expect(@provider).to receive(:shell_out_with_systems_locale!).with("/sbin/rsyslog reloadyousillysally") - @provider.reload_service + it "should call the restart command if one is specified" do + current_resource.running(true) + allow(new_resource).to receive(:restart_command).and_return("/sbin/rsyslog restartyousillysally") + expect(provider).to receive(:shell_out_with_systems_locale!).with("/sbin/rsyslog restartyousillysally") + provider.restart_service end - end - context "when a reload command is not specified" do - it "should call '/bin/systemctl reload service_name' if the service is running" do - allow(@current_resource).to receive(:running).and_return(true) - expect(@provider).to receive(:shell_out_with_systems_locale!).with("/bin/systemctl reload #{@new_resource.service_name}").and_return(@shell_out_success) - @provider.reload_service + it "should call '#{systemctl_path} restart service_name' if no restart command is specified" do + current_resource.running(true) + expect(provider).to receive(:shell_out_with_systems_locale!).with("#{systemctl_path} restart #{service_name}").and_return(shell_out_success) + provider.restart_service end - it "should start the service if the service is not running" do - allow(@current_resource).to receive(:running).and_return(false) - expect(@provider).to receive(:start_service).and_return(true) - @provider.reload_service + describe "reload service" do + context "when a reload command is specified" do + it "should call the reload command" do + current_resource.running(true) + allow(new_resource).to receive(:reload_command).and_return("/sbin/rsyslog reloadyousillysally") + expect(provider).to receive(:shell_out_with_systems_locale!).with("/sbin/rsyslog reloadyousillysally") + provider.reload_service + end + end + + context "when a reload command is not specified" do + it "should call '#{systemctl_path} reload service_name' if the service is running" do + current_resource.running(true) + expect(provider).to receive(:shell_out_with_systems_locale!).with("#{systemctl_path} reload #{service_name}").and_return(shell_out_success) + provider.reload_service + end + + it "should start the service if the service is not running" do + current_resource.running(false) + expect(provider).to receive(:start_service).and_return(true) + provider.reload_service + end + end end - end - end - it "should call the stop command if one is specified" do - allow(@current_resource).to receive(:running).and_return(true) - allow(@new_resource).to receive(:stop_command).and_return("/sbin/rsyslog stopyousillysally") - expect(@provider).to receive(:shell_out_with_systems_locale!).with("/sbin/rsyslog stopyousillysally") - @provider.stop_service - end + it "should call the stop command if one is specified" do + current_resource.running(true) + allow(new_resource).to receive(:stop_command).and_return("/sbin/rsyslog stopyousillysally") + expect(provider).to receive(:shell_out_with_systems_locale!).with("/sbin/rsyslog stopyousillysally") + provider.stop_service + end - it "should call '/bin/systemctl stop service_name' if no stop command is specified" do - allow(@current_resource).to receive(:running).and_return(true) - expect(@provider).to receive(:shell_out_with_systems_locale!).with("/bin/systemctl stop #{@new_resource.service_name}").and_return(@shell_out_success) - @provider.stop_service - end + it "should call '#{systemctl_path} stop service_name' if no stop command is specified" do + current_resource.running(true) + expect(provider).to receive(:shell_out_with_systems_locale!).with("#{systemctl_path} stop #{service_name}").and_return(shell_out_success) + provider.stop_service + end - it "should not call '/bin/systemctl stop service_name' if it is already stopped" do - allow(@current_resource).to receive(:running).and_return(false) - expect(@provider).not_to receive(:shell_out_with_systems_locale!).with("/bin/systemctl stop #{@new_resource.service_name}") - @provider.stop_service - end - end + it "should not call '#{systemctl_path} stop service_name' if it is already stopped" do + current_resource.running(false) + expect(provider).not_to receive(:shell_out_with_systems_locale!).with("#{systemctl_path} stop #{service_name}") + provider.stop_service + end + end - describe "enable and disable service" do - before(:each) do - @current_resource = Chef::Resource::Service.new('rsyslog.service') - allow(Chef::Resource::Service).to receive(:new).and_return(@current_resource) - @provider.current_resource = @current_resource - end + describe "enable and disable service" do + before(:each) do + provider.current_resource = current_resource + current_resource.service_name(service_name) + allow(provider).to receive(:which).with("systemctl").and_return("#{systemctl_path}") + end - it "should call '/bin/systemctl enable service_name' to enable the service" do - expect(@provider).to receive(:shell_out!).with("/bin/systemctl enable #{@new_resource.service_name}").and_return(@shell_out_success) - @provider.enable_service - end + it "should call '#{systemctl_path} enable service_name' to enable the service" do + expect(provider).to receive(:shell_out!).with("#{systemctl_path} enable #{service_name}").and_return(shell_out_success) + provider.enable_service + end - it "should call '/bin/systemctl disable service_name' to disable the service" do - expect(@provider).to receive(:shell_out!).with("/bin/systemctl disable #{@new_resource.service_name}").and_return(@shell_out_success) - @provider.disable_service - end - end + it "should call '#{systemctl_path} disable service_name' to disable the service" do + expect(provider).to receive(:shell_out!).with("#{systemctl_path} disable #{service_name}").and_return(shell_out_success) + provider.disable_service + end + end - describe "is_active?" do - before(:each) do - @current_resource = Chef::Resource::Service.new('rsyslog.service') - allow(Chef::Resource::Service).to receive(:new).and_return(@current_resource) - end + describe "is_active?" do + before(:each) do + provider.current_resource = current_resource + current_resource.service_name(service_name) + allow(provider).to receive(:which).with("systemctl").and_return("#{systemctl_path}") + end - it "should return true if '/bin/systemctl is-active service_name' returns 0" do - expect(@provider).to receive(:shell_out).with('/bin/systemctl is-active rsyslog.service --quiet').and_return(@shell_out_success) - expect(@provider.is_active?).to be_truthy - end + it "should return true if '#{systemctl_path} is-active service_name' returns 0" do + expect(provider).to receive(:shell_out).with("#{systemctl_path} is-active #{service_name} --quiet").and_return(shell_out_success) + expect(provider.is_active?).to be true + end - it "should return false if '/bin/systemctl is-active service_name' returns anything except 0" do - expect(@provider).to receive(:shell_out).with('/bin/systemctl is-active rsyslog.service --quiet').and_return(@shell_out_failure) - expect(@provider.is_active?).to be_falsey - end - end + it "should return false if '#{systemctl_path} is-active service_name' returns anything except 0" do + expect(provider).to receive(:shell_out).with("#{systemctl_path} is-active #{service_name} --quiet").and_return(shell_out_failure) + expect(provider.is_active?).to be false + end + end - describe "is_enabled?" do - before(:each) do - @current_resource = Chef::Resource::Service.new('rsyslog.service') - allow(Chef::Resource::Service).to receive(:new).and_return(@current_resource) - end + describe "is_enabled?" do + before(:each) do + provider.current_resource = current_resource + current_resource.service_name(service_name) + allow(provider).to receive(:which).with("systemctl").and_return("#{systemctl_path}") + end - it "should return true if '/bin/systemctl is-enabled service_name' returns 0" do - expect(@provider).to receive(:shell_out).with('/bin/systemctl is-enabled rsyslog.service --quiet').and_return(@shell_out_success) - expect(@provider.is_enabled?).to be_truthy - end + it "should return true if '#{systemctl_path} is-enabled service_name' returns 0" do + expect(provider).to receive(:shell_out).with("#{systemctl_path} is-enabled #{service_name} --quiet").and_return(shell_out_success) + expect(provider.is_enabled?).to be true + end - it "should return false if '/bin/systemctl is-enabled service_name' returns anything except 0" do - expect(@provider).to receive(:shell_out).with('/bin/systemctl is-enabled rsyslog.service --quiet').and_return(@shell_out_failure) - expect(@provider.is_enabled?).to be_falsey + it "should return false if '#{systemctl_path} is-enabled service_name' returns anything except 0" do + expect(provider).to receive(:shell_out).with("#{systemctl_path} is-enabled #{service_name} --quiet").and_return(shell_out_failure) + expect(provider.is_enabled?).to be false + end + end end end end diff --git a/spec/unit/provider_resolver_spec.rb b/spec/unit/provider_resolver_spec.rb index 927cca4f58..c56207c554 100644 --- a/spec/unit/provider_resolver_spec.rb +++ b/spec/unit/provider_resolver_spec.rb @@ -33,11 +33,11 @@ describe Chef::ProviderResolver do node end - let(:provider_resolver) { Chef::ProviderResolver.new(node) } + let(:provider_resolver) { Chef::ProviderResolver.new(node, resource, action) } let(:action) { :start } - let(:resolved_provider) { provider_resolver.resolve(resource, action) } + let(:resolved_provider) { provider_resolver.resolve } let(:provider) { nil } @@ -63,11 +63,34 @@ describe Chef::ProviderResolver do allow(resource).to receive(:service_name).and_return("ntp") end - shared_examples_for "a debian platform with upstart and update-rc.d" do + shared_examples_for "an ubuntu platform with upstart, update-rc.d and systemd" do before do - stub_service_providers(:debian, :invokercd, :upstart) + 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 + + 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 + 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 ] ) @@ -89,7 +112,137 @@ describe Chef::ProviderResolver do 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::Debian) + expect(resolved_provider).to eql(Chef::Provider::Service::Systemd) + end + end + + shared_examples_for "an ubuntu platform with upstart and update-rc.d" do + before do + stub_service_providers(:debian, :invokercd, :upstart) + end + + # needs to be handled by the highest priority init.d handler + context "when only the SysV init script exists" do + before do + allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") + .and_return( [ :initd ] ) + 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 "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 + + it "returns a Service::Debian provider" do + expect(resolved_provider).to eql(Chef::Provider::Service::Debian) + 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 ] ) + 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 "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 + + it "returns a Service::Upstart provider" do + expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) + end + end + + # this case is a pure-upstart script which is easy + context "when only the Upstart script exists" do + before do + allow(Chef::Platform::ServiceHelpers).to receive(:config_for_service).with("ntp") + .and_return( [ :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 "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 "returns a Service::Upstart provider" do + expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) + end + 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( [ ] ) + 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 "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 @@ -104,6 +257,12 @@ describe Chef::ProviderResolver do .and_return( [ :initd ] ) expect(resolved_provider).to eql(Chef::Provider::Service::Insserv) 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 context "when the user has installed upstart" do @@ -111,7 +270,7 @@ describe Chef::ProviderResolver do stub_service_providers(:debian, :invokercd, :insserv, :upstart) end - it "when only the SysV init script exists, it returns a Service::Debian provider" do + 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) @@ -132,12 +291,18 @@ describe Chef::ProviderResolver do 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::Insserv) + expect(resolved_provider).to eql(Chef::Provider::Service::Upstart) end end end - describe "on Linux" do + describe "on Ubuntu 14.10" do + let(:os) { "linux" } + let(:platform) { "ubuntu" } + let(:platform_family) { "debian" } + let(:platform_version) { "14.04" } + + it_behaves_like "an ubuntu platform with upstart, update-rc.d and systemd" end describe "on Ubuntu 14.04" do @@ -146,7 +311,7 @@ describe Chef::ProviderResolver do let(:platform_family) { "debian" } let(:platform_version) { "14.04" } - it_behaves_like "a debian platform with upstart and update-rc.d" + it_behaves_like "an ubuntu platform with upstart and update-rc.d" end describe "on Ubuntu 10.04" do @@ -155,7 +320,7 @@ describe Chef::ProviderResolver do let(:platform_family) { "debian" } let(:platform_version) { "10.04" } - it_behaves_like "a debian platform with upstart and update-rc.d" + it_behaves_like "an ubuntu platform with upstart and update-rc.d" end # old debian uses the Debian provider (does not have insserv or upstart, or update-rc.d???) diff --git a/spec/unit/resource/timestamped_deploy_spec.rb b/spec/unit/resource/timestamped_deploy_spec.rb index 2af9d8bb0f..eca6c570d4 100644 --- a/spec/unit/resource/timestamped_deploy_spec.rb +++ b/spec/unit/resource/timestamped_deploy_spec.rb @@ -20,35 +20,14 @@ require 'spec_helper' describe Chef::Resource::TimestampedDeploy, "initialize" do - let(:node) { - node = Chef::Node.new - node.automatic_attrs[:os] = 'linux' - node.automatic_attrs[:platform_family] = 'rhel' - node - } - let(:events) { Chef::EventDispatch::Dispatcher.new } - let(:provider_resolver) { Chef::ProviderResolver.new(node) } - let(:run_context) { - run_context = Chef::RunContext.new(node, {}, events) - run_context.provider_resolver = provider_resolver - run_context - } - let(:resource) { Chef::Resource::TimestampedDeploy.new("stuff", run_context) } + static_provider_resolution( + resource: Chef::Resource::TimestampedDeploy, + provider: Chef::Provider::Deploy::Timestamped, + name: :deploy, + action: :deploy, + os: 'linux', + platform_family: 'rhel', + ) - it "should return a Chef::Resource::TimestampedDeploy" do - expect(resource).to be_a_kind_of(Chef::Resource::TimestampedDeploy) - end - - it "should set the resource_name to :timestamped_deploy" do - expect(resource.resource_name).to eql(:deploy) - end - - it "should leave the provider nil" do - expect(resource.provider).to eql(nil) - end - - it "should resolve to a Chef::Provider::Deploy::Timestamped" do - expect(resource.provider_for_action(:install)).to be_a(Chef::Provider::Deploy::Timestamped) - end end diff --git a/spec/unit/runner_spec.rb b/spec/unit/runner_spec.rb index 9bd4199418..b30f818da1 100644 --- a/spec/unit/runner_spec.rb +++ b/spec/unit/runner_spec.rb @@ -99,13 +99,15 @@ describe Chef::Runner do end context "when we fall through to old Chef::Platform resolution" do + let(:provider_resolver) { Chef::ProviderResolver.new(node, first_resource, nil) } before do # set up old Chef::Platform resolution instead of provider_resolver Chef::Platform.set( :resource => :cat, :provider => Chef::Provider::SnakeOil ) - allow(run_context.provider_resolver).to receive(:maybe_dynamic_provider_resolution).with(first_resource, anything()).and_return(nil) + allow(Chef::ProviderResolver).to receive(:new).and_return(provider_resolver) + allow(provider_resolver).to receive(:maybe_dynamic_provider_resolution).with(first_resource, anything()).and_return(nil) end it "should use the platform provider if it has one" do |