From 7d992bc339acb716a27c631cd18bde79086b3556 Mon Sep 17 00:00:00 2001 From: dheerajd-msys Date: Fri, 24 May 2019 05:29:43 +0530 Subject: Fix service enable idempotency in sles11 (#8256) * fix service enable idempotency in sles11 Signed-off-by: dheerajd-msys --- lib/chef/provider/service/insserv.rb | 4 +- spec/functional/assets/inittest | 36 ++++ spec/functional/resource/insserv_spec.rb | 205 +++++++++++++++++++++ spec/spec_helper.rb | 1 + spec/support/platform_helpers.rb | 4 + spec/unit/provider/service/insserv_service_spec.rb | 4 +- 6 files changed, 251 insertions(+), 3 deletions(-) create mode 100644 spec/functional/assets/inittest create mode 100644 spec/functional/resource/insserv_spec.rb diff --git a/lib/chef/provider/service/insserv.rb b/lib/chef/provider/service/insserv.rb index a8e841f8b3..770016bc59 100644 --- a/lib/chef/provider/service/insserv.rb +++ b/lib/chef/provider/service/insserv.rb @@ -36,7 +36,9 @@ class Chef super # Look for a /etc/rc.*/SnnSERVICE link to signify that the service would be started in a runlevel - if Dir.glob("/etc/rc**/S*#{Chef::Util::PathHelper.escape_glob_dir(current_resource.service_name)}").empty? + service_name = Chef::Util::PathHelper.escape_glob_dir(current_resource.service_name) + + if Dir.glob("/etc/rc*/**/S*#{service_name}").empty? current_resource.enabled false else current_resource.enabled true 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/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 () +# 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 e87308e9ed..5ed5e73506 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 5ae9c01722..f446a30862 100644 --- a/spec/support/platform_helpers.rb +++ b/spec/support/platform_helpers.rb @@ -175,6 +175,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/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 -- cgit v1.2.1