summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authortyler-ball <tyleraball@gmail.com>2014-11-13 11:05:10 -0800
committertyler-ball <tyleraball@gmail.com>2014-11-13 11:05:10 -0800
commit13fba4b26511382037efb9e36ce84eda1ba569e1 (patch)
tree5e3e2dd4094480815d174b08aaea510b3f5cf269 /spec
parentf5b36609eeb85d060e61293678488490cd382ea1 (diff)
parent2f8a0e92db2244b9404472b8ecae52c373d758ea (diff)
downloadchef-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.rb4
-rw-r--r--spec/support/pedant/pedant_config.rb7
-rw-r--r--spec/support/shared/unit/resource/static_provider_resolution.rb7
-rw-r--r--spec/unit/api_client/registration_spec.rb22
-rw-r--r--spec/unit/knife/bootstrap_spec.rb28
-rw-r--r--spec/unit/mixin/deep_merge_spec.rb14
-rw-r--r--spec/unit/node/attribute_spec.rb6
-rw-r--r--spec/unit/node_spec.rb346
-rw-r--r--spec/unit/provider/service/systemd_service_spec.rb337
-rw-r--r--spec/unit/provider_resolver_spec.rb185
-rw-r--r--spec/unit/resource/timestamped_deploy_spec.rb37
-rw-r--r--spec/unit/runner_spec.rb4
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