diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/functional/assets/inittest | 36 | ||||
-rw-r--r-- | spec/functional/mixin/from_file_spec.rb | 11 | ||||
-rw-r--r-- | spec/functional/resource/insserv_spec.rb | 205 | ||||
-rw-r--r-- | spec/spec_helper.rb | 1 | ||||
-rw-r--r-- | spec/support/platform_helpers.rb | 4 | ||||
-rw-r--r-- | spec/unit/application/solo_spec.rb | 1 | ||||
-rw-r--r-- | spec/unit/application_spec.rb | 88 | ||||
-rw-r--r-- | spec/unit/environment_spec.rb | 6 | ||||
-rw-r--r-- | spec/unit/knife/bootstrap_spec.rb | 2 | ||||
-rw-r--r-- | spec/unit/provider/service/insserv_service_spec.rb | 4 | ||||
-rw-r--r-- | spec/unit/resource_collection_spec.rb | 8 | ||||
-rw-r--r-- | spec/unit/role_spec.rb | 9 |
12 files changed, 367 insertions, 8 deletions
diff --git a/spec/functional/assets/inittest b/spec/functional/assets/inittest new file mode 100644 index 0000000000..dc542a965a --- /dev/null +++ b/spec/functional/assets/inittest @@ -0,0 +1,36 @@ +#!/bin/sh + +TMPDIR="${TMPDIR:-/tmp}" + +function create_chef_txt { + touch $TMPDIR/inittest.txt +} + +function delete_chef_txt { + rm $TMPDIR/inittest.txt +} + +function rename_chef_txt { + mv $TMPDIR/inittest.txt $TMPDIR/$1 +} + +case "$1" in +start ) + create_chef_txt + ;; +stop ) + delete_chef_txt + ;; +status ) + [ -f $TMPDIR/inittest.txt ] || [ -f $TMPDIR/inittest_reload.txt ] || [ -f $TMPDIR/inittest_restart.txt ] + ;; +reload ) + rename_chef_txt "inittest_reload.txt" + ;; +restart ) + rename_chef_txt "inittest_restart.txt" + ;; +* ) + echo "Usage: $0 (start | stop | restart | reload)" + exit 1 +esac diff --git a/spec/functional/mixin/from_file_spec.rb b/spec/functional/mixin/from_file_spec.rb index a279f48790..d8519b4185 100644 --- a/spec/functional/mixin/from_file_spec.rb +++ b/spec/functional/mixin/from_file_spec.rb @@ -21,6 +21,7 @@ describe Chef::Mixin::FromFile do REAL_DATA = File.join(CHEF_SPEC_DATA, "mixin", "real_data.rb") INVALID_DATA = File.join(CHEF_SPEC_DATA, "mixin", "invalid_data.rb") NO_DATA = File.join(CHEF_SPEC_DATA, "mixin", "non_existant_data.rb") + DIRECTORY = File.expand_path("") class TestData include Chef::Mixin::FromFile @@ -78,5 +79,15 @@ describe Chef::Mixin::FromFile do datum = TestData.new expect { datum.from_file(NO_DATA) }.to raise_error(IOError) end + + it "should fail if it's a directory not a file" do + datum = TestData.new + expect { datum.from_file(DIRECTORY) }.to raise_error(IOError) + end + + it "should fail class if it's a directory not a file" do + datum = ClassTestData + expect { datum.from_file(DIRECTORY) }.to raise_error(IOError) + end end end diff --git a/spec/functional/resource/insserv_spec.rb b/spec/functional/resource/insserv_spec.rb new file mode 100644 index 0000000000..a923753019 --- /dev/null +++ b/spec/functional/resource/insserv_spec.rb @@ -0,0 +1,205 @@ +# encoding: UTF-8 +# +# Author:: Dheeraj Dubey (<dheeraj.dubey@msystechnologies.com>) +# Copyright:: Copyright 2009-2019, Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "spec_helper" +require "functional/resource/base" +require "chef/mixin/shell_out" +require "fileutils" + +describe Chef::Resource::Service, :requires_root, :sles11 do + + include Chef::Mixin::ShellOut + + def service_should_be_enabled + expect(shell_out!("/sbin/insserv -r -f #{new_resource.service_name}").exitstatus).to eq(0) + expect(shell_out!("/sbin/insserv -d -f #{new_resource.service_name}").exitstatus).to eq(0) + !Dir.glob("/etc/rc*/**/S*#{service_name}").empty? + end + + def service_should_be_disabled + expect(shell_out!("/sbin/insserv -r -f #{new_resource.service_name}").exitstatus).to eq(0) + Dir.glob("/etc/rc*/**/S*#{service_name}").empty? + end + + # Platform specific validation routines. + def service_should_be_started(file_name) + # The existence of this file indicates that the service was started. + expect(File.exists?("#{Dir.tmpdir}/#{file_name}")).to be_truthy + end + + def service_should_be_stopped(file_name) + expect(File.exists?("#{Dir.tmpdir}/#{file_name}")).to be_falsey + end + + def delete_test_files + files = Dir.glob("#{Dir.tmpdir}/init[a-z_]*.txt") + File.delete(*files) + end + + # Actual tests + let(:new_resource) do + new_resource = Chef::Resource::Service.new("inittest", run_context) + new_resource.provider Chef::Provider::Service::Insserv + new_resource.supports({ status: true, restart: true, reload: true }) + new_resource + end + + let(:provider) do + provider = new_resource.provider_for_action(new_resource.action) + provider + end + + let (:service_name) { "Chef::Util::PathHelper.escape_glob_dir(current_resource.service_name)" } + + let(:current_resource) do + provider.load_current_resource + provider.current_resource + end + + before(:all) do + File.delete("/etc/init.d/inittest") if File.exists?("/etc/init.d/inittest") + FileUtils.cp((File.join(File.dirname(__FILE__), "/../assets/inittest")).to_s, "/etc/init.d/inittest") + end + + after(:all) do + File.delete("/etc/init.d/inittest") if File.exists?("/etc/init.d/inittest") + end + + before(:each) do + delete_test_files + end + + after(:each) do + delete_test_files + end + + describe "start service" do + it "should start the service" do + new_resource.run_action(:start) + service_should_be_started("inittest.txt") + expect(new_resource).to be_updated_by_last_action + end + + it "should be idempotent" do + new_resource.run_action(:start) + service_should_be_started("inittest.txt") + expect(new_resource).to be_updated_by_last_action + new_resource.run_action(:start) + service_should_be_started("inittest.txt") + expect(new_resource).not_to be_updated_by_last_action + end + end + + describe "stop service" do + before do + new_resource.run_action(:start) + end + + it "should stop the service" do + new_resource.run_action(:stop) + service_should_be_stopped("inittest.txt") + expect(new_resource).to be_updated_by_last_action + end + + it "should be idempotent" do + new_resource.run_action(:stop) + service_should_be_stopped("inittest.txt") + expect(new_resource).to be_updated_by_last_action + new_resource.run_action(:stop) + service_should_be_stopped("inittest.txt") + expect(new_resource).not_to be_updated_by_last_action + end + end + + describe "restart service" do + before do + new_resource.run_action(:start) + end + + it "should restart the service" do + new_resource.run_action(:restart) + service_should_be_started("inittest_restart.txt") + expect(new_resource).to be_updated_by_last_action + end + + it "should be idempotent" do + skip "FIXME: restart is not idempotent" + new_resource.run_action(:restart) + service_should_be_disabled + expect(new_resource).to be_updated_by_last_action + new_resource.run_action(:restart) + service_should_be_disabled + expect(new_resource).not_to be_updated_by_last_action + end + end + + describe "reload service" do + before do + new_resource.run_action(:start) + end + + it "should reload the service" do + new_resource.run_action(:reload) + service_should_be_started("inittest_reload.txt") + expect(new_resource).to be_updated_by_last_action + end + + it "should be idempotent" do + skip "FIXME: reload is not idempotent" + new_resource.run_action(:reload) + service_should_be_disabled + expect(new_resource).to be_updated_by_last_action + new_resource.run_action(:reload) + service_should_be_disabled + expect(new_resource).not_to be_updated_by_last_action + end + end + + describe "enable service" do + it "should enable the service" do + new_resource.run_action(:enable) + service_should_be_enabled + expect(new_resource).to be_updated_by_last_action + end + + it "should be idempotent" do + new_resource.run_action(:enable) + service_should_be_enabled + new_resource.run_action(:enable) + service_should_be_enabled + expect(new_resource).not_to be_updated_by_last_action + end + end + + describe "disable_service" do + it "should disable the service" do + new_resource.run_action(:disable) + service_should_be_disabled + expect(new_resource).to be_updated_by_last_action + end + + it "should be idempotent" do + new_resource.run_action(:disable) + service_should_be_disabled + new_resource.run_action(:disable) + service_should_be_disabled + expect(new_resource).not_to be_updated_by_last_action + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 027be2e619..adfb262637 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -172,6 +172,7 @@ RSpec.configure do |config| config.filter_run_excluding linux_only: true unless linux? config.filter_run_excluding aix_only: true unless aix? config.filter_run_excluding suse_only: true unless suse? + config.filter_run_excluding sles11: true unless sles11? config.filter_run_excluding debian_family_only: true unless debian_family? config.filter_run_excluding supports_cloexec: true unless supports_cloexec? config.filter_run_excluding selinux_only: true unless selinux_enabled? diff --git a/spec/support/platform_helpers.rb b/spec/support/platform_helpers.rb index c4ab1db265..02f8c28345 100644 --- a/spec/support/platform_helpers.rb +++ b/spec/support/platform_helpers.rb @@ -162,6 +162,10 @@ def rhel6? rhel? && !!(ohai[:platform_version].to_i == 6) end +def sles11? + suse? && !!(ohai[:platform_version].to_i == 11) +end + def rhel7? rhel? && !!(ohai[:platform_version].to_i == 7) end diff --git a/spec/unit/application/solo_spec.rb b/spec/unit/application/solo_spec.rb index 74f71a9115..3f540d24e2 100644 --- a/spec/unit/application/solo_spec.rb +++ b/spec/unit/application/solo_spec.rb @@ -27,6 +27,7 @@ describe Chef::Application::Solo do allow(app).to receive(:configure_chef).and_return(true) allow(app).to receive(:configure_logging).and_return(true) allow(app).to receive(:trap) + allow(app).to receive(:cli_arguments).and_return([]) Chef::Config[:json_attribs] = false Chef::Config[:solo] = true diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb index 10dff0e250..e94f9b74ae 100644 --- a/spec/unit/application_spec.rb +++ b/spec/unit/application_spec.rb @@ -393,6 +393,94 @@ describe Chef::Application do end + describe "#set_specific_recipes" do + let(:app) { Chef::Application.new } + context "when cli arguments does not contain any values" do + before do + allow(app).to receive(:cli_arguments).and_return([]) + end + + it "returns an empty array" do + app.set_specific_recipes + expect(Chef::Config[:specific_recipes]).to eq([]) + end + end + + context "when cli arguments contain valid recipe file path" do + let(:tempfile) { Tempfile.new("default.rb").path } + before do + allow(app).to receive(:cli_arguments).and_return([tempfile]) + end + + it "sets the specific recipes to config" do + app.set_specific_recipes + expect(Chef::Config[:specific_recipes]).to eq([tempfile]) + end + end + + context "when cli arguments contain invalid recipe file path" do + let(:fatal) { false } + before do + tempfile = "/root/default.rb" + allow(app).to receive(:cli_arguments).and_return([tempfile]) + allow(Chef::Application).to receive(:fatal!).and_return(fatal) + end + + it "raises an error with application exit" do + expect(app.set_specific_recipes).to eq(fatal) + end + end + + context "when cli arguments contain empty string" do + let(:fatal) { false } + before do + allow(app).to receive(:cli_arguments).and_return([""]) + allow(Chef::Application).to receive(:fatal!).and_return(fatal) + end + + it "raises an arguments error" do + expect(app.set_specific_recipes).to eq(fatal) + end + end + + context "when cli arguments contain any string" do + let(:fatal) { false } + before do + allow(app).to receive(:cli_arguments).and_return(["test"]) + allow(Chef::Application).to receive(:fatal!).and_return(fatal) + end + + it "raises an arguments error" do + expect(app.set_specific_recipes).to eq(fatal) + end + end + + context "when cli arguments contain multiple invalid strings" do + let(:fatal) { false } + before do + allow(app).to receive(:cli_arguments).and_return(["", "test"]) + allow(Chef::Application).to receive(:fatal!).and_return(fatal) + end + + it "raises an arguments error" do + expect(app.set_specific_recipes).to eq(fatal) + end + end + + context "when cli arguments contain valid recipe file path and invalid string" do + let(:fatal) { false } + before do + tempfile = Tempfile.new("default.rb").path + allow(app).to receive(:cli_arguments).and_return([tempfile, "test"]) + allow(Chef::Application).to receive(:fatal!).and_return(fatal) + end + + it "raises an arguments error" do + expect(app.set_specific_recipes).to eq(fatal) + end + end + end + describe "configuration errors" do before do expect(Process).to receive(:exit) diff --git a/spec/unit/environment_spec.rb b/spec/unit/environment_spec.rb index 467b719bb7..aa4c105c3a 100644 --- a/spec/unit/environment_spec.rb +++ b/spec/unit/environment_spec.rb @@ -403,8 +403,9 @@ describe Chef::Environment do it "should get the environment from the environment_path" do expect(File).to receive(:directory?).with(Chef::Config[:environment_path]).and_return(true) expect(File).to receive(:exists?).with(File.join(Chef::Config[:environment_path], "foo.json")).and_return(false) - expect(File).to receive(:exists?).with(File.join(Chef::Config[:environment_path], "foo.rb")).exactly(2).times.and_return(true) + expect(File).to receive(:exists?).with(File.join(Chef::Config[:environment_path], "foo.rb")).exactly(1).times.and_return(true) expect(File).to receive(:readable?).with(File.join(Chef::Config[:environment_path], "foo.rb")).and_return(true) + expect(File).to receive(:file?).with(File.join(Chef::Config[:environment_path], "foo.rb")).and_return(true) role_dsl = "name \"foo\"\ndescription \"desc\"\n" expect(IO).to receive(:read).with(File.join(Chef::Config[:environment_path], "foo.rb")).and_return(role_dsl) Chef::Environment.load("foo") @@ -436,8 +437,9 @@ describe Chef::Environment do it "should return a Chef::Environment object from Ruby DSL" do expect(File).to receive(:directory?).with(Chef::Config[:environment_path]).and_return(true) expect(File).to receive(:exists?).with(File.join(Chef::Config[:environment_path], "foo.json")).and_return(false) - expect(File).to receive(:exists?).with(File.join(Chef::Config[:environment_path], "foo.rb")).exactly(2).times.and_return(true) + expect(File).to receive(:exists?).with(File.join(Chef::Config[:environment_path], "foo.rb")).exactly(1).times.and_return(true) expect(File).to receive(:readable?).with(File.join(Chef::Config[:environment_path], "foo.rb")).and_return(true) + expect(File).to receive(:file?).with(File.join(Chef::Config[:environment_path], "foo.rb")).and_return(true) role_dsl = "name \"foo\"\ndescription \"desc\"\n" expect(IO).to receive(:read).with(File.join(Chef::Config[:environment_path], "foo.rb")).and_return(role_dsl) environment = Chef::Environment.load("foo") diff --git a/spec/unit/knife/bootstrap_spec.rb b/spec/unit/knife/bootstrap_spec.rb index 4a7286bd6f..13e7906de8 100644 --- a/spec/unit/knife/bootstrap_spec.rb +++ b/spec/unit/knife/bootstrap_spec.rb @@ -1664,8 +1664,8 @@ describe Chef::Knife::Bootstrap do expect(knife).to receive(:validate_policy_options!).ordered expect(knife).to receive(:winrm_warn_no_ssl_verification).ordered expect(knife).to receive(:warn_on_short_session_timeout).ordered - expect(knife).to receive(:register_client).ordered expect(knife).to receive(:connect!).ordered + expect(knife).to receive(:register_client).ordered expect(knife).to receive(:render_template).and_return "content" expect(knife).to receive(:upload_bootstrap).with("content").and_return "/remote/path.sh" expect(knife).to receive(:perform_bootstrap).with("/remote/path.sh") diff --git a/spec/unit/provider/service/insserv_service_spec.rb b/spec/unit/provider/service/insserv_service_spec.rb index f2fe19db59..bd8a155bde 100644 --- a/spec/unit/provider/service/insserv_service_spec.rb +++ b/spec/unit/provider/service/insserv_service_spec.rb @@ -36,7 +36,7 @@ describe Chef::Provider::Service::Insserv do describe "load_current_resource" do describe "when startup links exist" do before do - allow(Dir).to receive(:glob).with("/etc/rc**/S*initgrediant").and_return(["/etc/rc5.d/S18initgrediant", "/etc/rc2.d/S18initgrediant", "/etc/rc4.d/S18initgrediant", "/etc/rc3.d/S18initgrediant"]) + allow(Dir).to receive(:glob).with("/etc/rc*/**/S*initgrediant").and_return(["/etc/rc.d/rc5.d/S18initgrediant", "/etc/rc.d/rc2.d/S18initgrediant", "/etc/rc.d/rc4.d/S18initgrediant", "/etc/rc.d/rc3.d/S18initgrediant"]) end it "sets the current enabled status to true" do @@ -47,7 +47,7 @@ describe Chef::Provider::Service::Insserv do describe "when startup links do not exist" do before do - allow(Dir).to receive(:glob).with("/etc/rc**/S*initgrediant").and_return([]) + allow(Dir).to receive(:glob).with("/etc/rc*/**/S*initgrediant").and_return([]) end it "sets the current enabled status to false" do diff --git a/spec/unit/resource_collection_spec.rb b/spec/unit/resource_collection_spec.rb index c12a005cfc..7f59246a88 100644 --- a/spec/unit/resource_collection_spec.rb +++ b/spec/unit/resource_collection_spec.rb @@ -183,6 +183,14 @@ describe Chef::ResourceCollection do expect(rc).to be_empty end + it "should allow to delete resources with different providers" do + pkg = Chef::Resource::YumPackage.new("monkey") + rc.insert(pkg, instance_name: "monkey", resource_type: "package") + expect(rc).not_to be_empty + expect(rc.delete("package[monkey]")).to eql(pkg) + expect(rc).to be_empty + end + it "should raise an exception if you send something strange to delete" do expect { rc.delete(:symbol) }.to raise_error(ArgumentError) end diff --git a/spec/unit/role_spec.rb b/spec/unit/role_spec.rb index 0e12f65e58..46ee71bb1c 100644 --- a/spec/unit/role_spec.rb +++ b/spec/unit/role_spec.rb @@ -268,8 +268,9 @@ describe Chef::Role do it "should return a Chef::Role object from a Ruby DSL" do expect(Dir).to receive(:glob).and_return(["#{Chef::Config[:role_path]}/memes", "#{Chef::Config[:role_path]}/memes/lolcat.rb"]) rb_path = File.join(Chef::Config[:role_path], "memes/lolcat.rb") - expect(File).to receive(:exists?).with(rb_path).exactly(2).times.and_return(true) + expect(File).to receive(:exists?).with(rb_path).exactly(1).times.and_return(true) expect(File).to receive(:readable?).with(rb_path).exactly(1).times.and_return(true) + expect(File).to receive(:file?).with(rb_path).exactly(1).times.and_return(true) expect(IO).to receive(:read).with(rb_path).and_return(ROLE_DSL) expect(@role).to be_a_kind_of(Chef::Role) @role.class.from_disk("lolcat") @@ -331,8 +332,9 @@ describe Chef::Role do it "should return a Chef::Role object from a Ruby DSL" do expect(Dir).to receive(:glob).with(File.join("/path1", "**", "**")).exactly(1).times.and_return(["/path1/lolcat.rb"]) - expect(File).to receive(:exists?).with("/path1/lolcat.rb").exactly(2).times.and_return(true) + expect(File).to receive(:exists?).with("/path1/lolcat.rb").exactly(1).times.and_return(true) expect(File).to receive(:readable?).with("/path1/lolcat.rb").and_return(true) + expect(File).to receive(:file?).with("/path1/lolcat.rb").and_return(true) expect(IO).to receive(:read).with("/path1/lolcat.rb").exactly(1).times.and_return(ROLE_DSL) expect(@role).to be_a_kind_of(Chef::Role) @role.class.from_disk("lolcat") @@ -341,8 +343,9 @@ describe Chef::Role do it "should return a Chef::Role object from a Ruby DSL when role is in the second path" do expect(Dir).to receive(:glob).with(File.join("/path1", "**", "**")).exactly(1).times.and_return([]) expect(Dir).to receive(:glob).with(File.join("/path/path2", "**", "**")).exactly(1).times.and_return(["/path/path2/lolcat.rb"]) - expect(File).to receive(:exists?).with("/path/path2/lolcat.rb").exactly(2).times.and_return(true) + expect(File).to receive(:exists?).with("/path/path2/lolcat.rb").exactly(1).times.and_return(true) expect(File).to receive(:readable?).with("/path/path2/lolcat.rb").and_return(true) + expect(File).to receive(:file?).with("/path/path2/lolcat.rb").and_return(true) expect(IO).to receive(:read).with("/path/path2/lolcat.rb").exactly(1).times.and_return(ROLE_DSL) expect(@role).to be_a_kind_of(Chef::Role) @role.class.from_disk("lolcat") |