summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerdar Sutay <serdar@opscode.com>2014-10-21 11:14:19 -0700
committerSerdar Sutay <serdar@opscode.com>2014-10-21 11:14:19 -0700
commiteeb45770585a50d78e412682b0ae44524e29e727 (patch)
treec1d2e00403722fa111e6bd01d2f56bc0ccabe790
parentccb220a72ba07a9b2cbabba25f88edb7e7064d7b (diff)
parent09fbf4a6efacad4c635531b005dbc5832e8c03c8 (diff)
downloadchef-eeb45770585a50d78e412682b0ae44524e29e727.tar.gz
Merge pull request #2028 from ClogenyTechnologies/kd/aix-service
aix service provider
-rw-r--r--lib/chef/platform/provider_mapping.rb3
-rw-r--r--lib/chef/provider/service/aix.rb126
-rw-r--r--lib/chef/provider/service/aixinit.rb117
-rw-r--r--lib/chef/providers.rb2
-rwxr-xr-xspec/functional/assets/chefinittest34
-rwxr-xr-xspec/functional/assets/testchefsubsys11
-rwxr-xr-xspec/functional/resource/aix_service_spec.rb136
-rwxr-xr-xspec/functional/resource/aixinit_service_spec.rb211
-rw-r--r--spec/spec_helper.rb1
-rw-r--r--spec/unit/provider/service/aix_service_spec.rb181
-rw-r--r--spec/unit/provider/service/aixinit_service_spec.rb269
11 files changed, 1090 insertions, 1 deletions
diff --git a/lib/chef/platform/provider_mapping.rb b/lib/chef/platform/provider_mapping.rb
index 9e15ea5658..e6d948276c 100644
--- a/lib/chef/platform/provider_mapping.rb
+++ b/lib/chef/platform/provider_mapping.rb
@@ -394,7 +394,8 @@ class Chef
:ifconfig => Chef::Provider::Ifconfig::Aix,
:cron => Chef::Provider::Cron::Aix,
:package => Chef::Provider::Package::Aix,
- :user => Chef::Provider::User::Aix
+ :user => Chef::Provider::User::Aix,
+ :service => Chef::Provider::Service::Aix
}
},
:exherbo => {
diff --git a/lib/chef/provider/service/aix.rb b/lib/chef/provider/service/aix.rb
new file mode 100644
index 0000000000..6f70f797b9
--- /dev/null
+++ b/lib/chef/provider/service/aix.rb
@@ -0,0 +1,126 @@
+#
+# Author:: kaustubh (<kaustubh@clogeny.com>)
+# Copyright:: Copyright (c) 2014 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 'chef/provider/service'
+
+class Chef
+ class Provider
+ class Service
+ class Aix < Chef::Provider::Service
+ attr_reader :status_load_success
+
+ def initialize(new_resource, run_context)
+ super
+ end
+
+ def load_current_resource
+ @current_resource = Chef::Resource::Service.new(@new_resource.name)
+ @current_resource.service_name(@new_resource.service_name)
+
+ @status_load_success = true
+ @priority_success = true
+ @is_resource_group = false
+
+ determine_current_status!
+
+ @current_resource
+ end
+
+ def whyrun_supported?
+ true
+ end
+
+ def start_service
+ if @is_resource_group
+ shell_out!("startsrc -g #{@new_resource.service_name}")
+ else
+ shell_out!("startsrc -s #{@new_resource.service_name}")
+ end
+ end
+
+ def stop_service
+ if @is_resource_group
+ shell_out!("stopsrc -g #{@new_resource.service_name}")
+ else
+ shell_out!("stopsrc -s #{@new_resource.service_name}")
+ end
+ end
+
+ def restart_service
+ stop_service
+ start_service
+ end
+
+ def reload_service
+ if @is_resource_group
+ shell_out!("refresh -g #{@new_resource.service_name}")
+ else
+ shell_out!("refresh -s #{@new_resource.service_name}")
+ end
+ end
+
+ def shared_resource_requirements
+ super
+ requirements.assert(:all_actions) do |a|
+ a.assertion { @status_load_success }
+ a.whyrun ["Service status not available. Assuming a prior action would have installed the service.", "Assuming status of not running."]
+ end
+ end
+
+ def define_resource_requirements
+ # FIXME? need reload from service.rb
+ shared_resource_requirements
+ end
+
+ protected
+ def determine_current_status!
+ Chef::Log.debug "#{@new_resource} using lssrc to check the status "
+ begin
+ services = shell_out!("lssrc -a | grep -w #{@new_resource.service_name}").stdout.split("\n")
+ is_resource_group?(services)
+
+ if services.length == 1 && services[0].split(' ').last == "active"
+ @current_resource.running true
+ else
+ @current_resource.running false
+ end
+ Chef::Log.debug "#{@new_resource} running: #{@current_resource.running}"
+ # ShellOut sometimes throws different types of Exceptions than ShellCommandFailed.
+ # Temporarily catching different types of exceptions here until we get Shellout fixed.
+ # TODO: Remove the line before one we get the ShellOut fix.
+ rescue Mixlib::ShellOut::ShellCommandFailed, SystemCallError
+ @status_load_success = false
+ @current_resource.running false
+ nil
+ end
+ end
+
+ def is_resource_group? (services)
+ if services.length > 1
+ Chef::Log.debug("#{@new_resource.service_name} is a group")
+ @is_resource_group = true
+ elsif services[0].split(' ')[1] == @new_resource.service_name
+ Chef::Log.debug("#{@new_resource.service_name} is a group")
+ @is_resource_group = true
+ end
+ end
+ end
+ end
+ end
+end
+
diff --git a/lib/chef/provider/service/aixinit.rb b/lib/chef/provider/service/aixinit.rb
new file mode 100644
index 0000000000..ab4b8e5406
--- /dev/null
+++ b/lib/chef/provider/service/aixinit.rb
@@ -0,0 +1,117 @@
+#
+# Author:: kaustubh (<kaustubh@clogeny.com>)
+# Copyright:: Copyright (c) 2014 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 'chef/provider/service/init'
+
+class Chef
+ class Provider
+ class Service
+ class AixInit < Chef::Provider::Service::Init
+ RC_D_SCRIPT_NAME = /\/etc\/rc.d\/rc2.d\/([SK])(\d\d|)/i
+
+ def initialize(new_resource, run_context)
+ super
+ @init_command = "/etc/rc.d/init.d/#{@new_resource.service_name}"
+ end
+
+ def load_current_resource
+ super
+ @priority_success = true
+ @rcd_status = nil
+
+ set_current_resource_attributes
+ @current_resource
+ end
+
+ def action_enable
+ if @new_resource.priority.nil?
+ priority_ok = true
+ else
+ priority_ok = @current_resource.priority == @new_resource.priority
+ end
+ if @current_resource.enabled and priority_ok
+ Chef::Log.debug("#{@new_resource} already enabled - nothing to do")
+ else
+ converge_by("enable service #{@new_resource}") do
+ enable_service
+ Chef::Log.info("#{@new_resource} enabled")
+ end
+ end
+ load_new_resource_state
+ @new_resource.enabled(true)
+ end
+
+ def enable_service
+ Dir.glob(["/etc/rc.d/rc2.d/[SK][0-9][0-9]#{@new_resource.service_name}", "/etc/rc.d/rc2.d/[SK]#{@new_resource.service_name}"]).each { |f| ::File.delete(f)}
+
+ if @new_resource.priority.is_a? Integer
+ create_symlink(2, 'S', @new_resource.priority)
+
+ elsif @new_resource.priority.is_a? Hash
+ @new_resource.priority.each do |level,o|
+ create_symlink(level,(o[0] == :start ? 'S' : 'K'),o[1])
+ end
+ else
+ create_symlink(2, 'S', '')
+ end
+ end
+
+ def disable_service
+ Dir.glob(["/etc/rc.d/rc2.d/[SK][0-9][0-9]#{@new_resource.service_name}", "/etc/rc.d/rc2.d/[SK]#{@new_resource.service_name}"]).each { |f| ::File.delete(f) }
+
+ if @new_resource.priority.is_a? Integer
+ create_symlink(2, 'K',100 - @new_resource.priority)
+ elsif @new_resource.priority.is_a? Hash
+ @new_resource.priority.each do |level,o|
+ create_symlink(level, 'K', 100 - o[1]) if o[0] == :stop
+ end
+ else
+ create_symlink(2, 'K', '')
+ end
+ end
+
+ def create_symlink(run_level, status, priority)
+ ::File.symlink("/etc/rc.d/init.d/#{@new_resource.service_name}", "/etc/rc.d/rc#{run_level}.d/#{status}#{priority}#{@new_resource.service_name}")
+ end
+
+ def set_current_resource_attributes
+ # assuming run level 2 for aix
+ is_enabled = false
+ files = Dir.glob(["/etc/rc.d/rc2.d/[SK][0-9][0-9]#{@new_resource.service_name}", "/etc/rc.d/rc2.d/[SK]#{@new_resource.service_name}"])
+
+ priority = {}
+
+ files.each do |file|
+ if (RC_D_SCRIPT_NAME =~ file)
+ priority[2] = [($1 == "S" ? :start : :stop), ($2.empty? ? '' : $2.to_i)]
+ if $1 == "S"
+ is_enabled = true
+ end
+ end
+ end
+
+ if is_enabled && files.length == 1
+ priority = priority[2][1]
+ end
+ @current_resource.enabled(is_enabled)
+ @current_resource.priority(priority)
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/lib/chef/providers.rb b/lib/chef/providers.rb
index fec00d0e63..bceb1f7106 100644
--- a/lib/chef/providers.rb
+++ b/lib/chef/providers.rb
@@ -88,6 +88,8 @@ require 'chef/provider/service/upstart'
require 'chef/provider/service/windows'
require 'chef/provider/service/solaris'
require 'chef/provider/service/macosx'
+require 'chef/provider/service/aixinit'
+require 'chef/provider/service/aix'
require 'chef/provider/user/dscl'
require 'chef/provider/user/pw'
diff --git a/spec/functional/assets/chefinittest b/spec/functional/assets/chefinittest
new file mode 100755
index 0000000000..79e064cd5f
--- /dev/null
+++ b/spec/functional/assets/chefinittest
@@ -0,0 +1,34 @@
+#!/bin/ksh
+
+function create_chef_txt {
+ touch /tmp/chefinittest.txt
+}
+
+function delete_chef_txt {
+ rm /tmp/chefinittest.txt
+}
+
+function rename_chef_txt {
+ mv /tmp/chefinittest.txt /tmp/$1
+}
+
+case "$1" in
+start )
+ create_chef_txt
+ ;;
+stop )
+ delete_chef_txt
+ ;;
+status )
+ [ -f /tmp/chefinittest.txt ] || [ -f /tmp/chefinittest_reload.txt ] || [ -f /tmp/chefinittest_restart.txt ]
+ ;;
+reload )
+ rename_chef_txt "chefinittest_reload.txt"
+ ;;
+restart )
+ rename_chef_txt "chefinittest_restart.txt"
+ ;;
+* )
+ echo "Usage: $0 (start | stop | restart | reload)"
+ exit 1
+esac
diff --git a/spec/functional/assets/testchefsubsys b/spec/functional/assets/testchefsubsys
new file mode 100755
index 0000000000..e9ff30d4aa
--- /dev/null
+++ b/spec/functional/assets/testchefsubsys
@@ -0,0 +1,11 @@
+#!/bin/bash
+# trapchild
+
+sleep 120 &
+
+pid="$!"
+
+trap 'echo I am going down, so killing off my processes..; kill $pid; exit' SIGHUP SIGINT
+ SIGQUIT SIGTERM
+
+wait \ No newline at end of file
diff --git a/spec/functional/resource/aix_service_spec.rb b/spec/functional/resource/aix_service_spec.rb
new file mode 100755
index 0000000000..6008fdea8f
--- /dev/null
+++ b/spec/functional/resource/aix_service_spec.rb
@@ -0,0 +1,136 @@
+# encoding: UTF-8
+#
+# Author:: Kaustubh Deorukhkar (<kaustubh@clogeny.com>)
+# Copyright:: Copyright (c) 2014 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'
+
+shared_examples "src service" do
+
+ include Chef::Mixin::ShellOut
+
+ def service_should_be_started
+ expect(shell_out!("lssrc -a | grep #{new_resource.service_name}").stdout.split(' ').last).to eq("active")
+ end
+
+ def service_should_be_stopped
+ expect(shell_out!("lssrc -a | grep #{new_resource.service_name}").stdout.split(' ').last).to eq("inoperative")
+ end
+
+ def get_service_pid
+ args = shell_out!("lssrc -a | grep #{new_resource.service_name}").stdout.split(' ')
+ if args.length == 3
+ args[1]
+ else
+ args[2]
+ end
+ end
+
+ describe "start service" do
+ it "should start the service" do
+ new_resource.run_action(:start)
+ service_should_be_started
+ 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
+ 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
+ end
+ end
+end
+
+describe Chef::Resource::Service, :requires_root, :aix_only do
+ def get_user_id
+ shell_out("id -u #{ENV['USER']}").stdout.chomp
+ end
+
+ describe "When service is a subsystem" do
+ before(:all) do
+ script_dir = File.join(File.dirname(__FILE__), "/../assets/")
+ shell_out!("mkssys -s ctestsys -p #{script_dir}/testchefsubsys -u #{get_user_id} -S -n 15 -f 9 -R -Q")
+ end
+
+ after(:each) do
+ shell_out("stopsrc -s ctestsys")
+ end
+
+ after(:all) do
+ shell_out!("rmssys -s ctestsys")
+ end
+
+
+ let(:new_resource) do
+ new_resource = Chef::Resource::Service.new("ctestsys", run_context)
+ new_resource
+ end
+
+ let(:provider) do
+ provider = new_resource.provider_for_action(new_resource.action)
+ provider
+ end
+
+ it_behaves_like "src service"
+ end
+
+
+ describe "When service is a group" do
+ before(:all) do
+ script_dir = File.join(File.dirname(__FILE__), "/../assets/")
+ shell_out!("mkssys -s ctestsys -p #{script_dir}/testchefsubsys -u #{get_user_id} -S -n 15 -f 9 -R -Q -G ctestgrp")
+ end
+
+ after(:each) do
+ shell_out("stopsrc -g ctestgrp")
+ end
+
+ after(:all) do
+ # rmssys supports only -s option.
+ shell_out!("rmssys -s ctestsys")
+ end
+
+ let(:new_resource) do
+ new_resource = Chef::Resource::Service.new("ctestgrp", run_context)
+ new_resource
+ end
+
+ let(:provider) do
+ provider = new_resource.provider_for_action(new_resource.action)
+ provider
+ end
+
+ it_behaves_like "src service"
+ end
+end
diff --git a/spec/functional/resource/aixinit_service_spec.rb b/spec/functional/resource/aixinit_service_spec.rb
new file mode 100755
index 0000000000..a99309187c
--- /dev/null
+++ b/spec/functional/resource/aixinit_service_spec.rb
@@ -0,0 +1,211 @@
+# encoding: UTF-8
+#
+# Author:: Kaustubh Deorukhkar (<kaustubh@clogeny.com>)
+# Copyright:: Copyright (c) 2014 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, :aix_only do
+
+ include Chef::Mixin::ShellOut
+
+ # Platform specific validation routines.
+ def service_should_be_started(file_name)
+ # The existance of this file indicates that the service was started.
+ expect(File.exists?("/tmp/#{file_name}")).to be_true
+ end
+
+ def service_should_be_stopped(file_name)
+ expect(File.exists?("/tmp/#{file_name}")).to be_false
+ end
+
+ def valide_symlinks(expected_output, run_level = nil, status = nil, priority = nil)
+ directory = []
+ if priority.is_a?Hash
+ priority.each do |level,o|
+ directory << "/etc/rc.d/rc#{level}.d/#{(o[0] == :start ? 'S' : 'K')}#{o[1]}#{new_resource.service_name}"
+ end
+ directory
+ else
+ directory << "/etc/rc.d/rc#{run_level}.d/#{status}#{priority}#{new_resource.service_name}"
+ end
+ expect(Dir.glob(directory)).to eq(expected_output)
+ File.delete(*directory)
+ end
+
+ def delete_test_files
+ files = Dir.glob("/tmp/chefinit[a-z_]*.txt")
+ File.delete(*files)
+ end
+
+ # Actual tests
+ let(:new_resource) do
+ new_resource = Chef::Resource::Service.new("chefinittest", run_context)
+ new_resource.provider Chef::Provider::Service::AixInit
+ 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
+
+ before(:all) do
+ File.delete("/etc/rc.d/init.d/chefinittest") if File.exists?("/etc/rc.d/init.d/chefinittest")
+ FileUtils.cp("#{File.join(File.dirname(__FILE__), "/../assets/chefinittest")}", "/etc/rc.d/init.d/chefinittest")
+ end
+
+ after(:all) do
+ File.delete("/etc/rc.d/init.d/chefinittest") if File.exists?("/etc/rc.d/init.d/chefinittest")
+ 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("chefinittest.txt")
+ 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("chefinittest.txt")
+ 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("chefinittest_restart.txt")
+ 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("chefinittest_reload.txt")
+ end
+ end
+
+ describe "enable service" do
+
+ context "when the service doesn't set a priority" do
+ it "creates symlink with status S" do
+ new_resource.run_action(:enable)
+ valide_symlinks(["/etc/rc.d/rc2.d/Schefinittest"],2,'S')
+ end
+ end
+
+ context "when the service sets a simple priority (integer)" do
+ before do
+ new_resource.priority(75)
+ end
+
+ it "creates a symlink with status S and a priority" do
+ new_resource.run_action(:enable)
+ valide_symlinks(["/etc/rc.d/rc2.d/S75chefinittest"], 2,'S',75)
+ end
+ end
+
+ context "when the service sets complex priorities (hash)" do
+ before do
+ priority = {2 => [:start, 20], 3 => [:stop, 10]}
+ new_resource.priority(priority)
+ end
+
+ it "create symlink with status start (S) or stop (K) and a priority " do
+ new_resource.run_action(:enable)
+ valide_symlinks(["/etc/rc.d/rc2.d/S20chefinittest", "/etc/rc.d/rc3.d/K10chefinittest"], 2,'S',new_resource.priority)
+ end
+ end
+ end
+
+ describe "disable_service" do
+
+ context "when the service doesn't set a priority" do
+ before do
+ File.symlink("/etc/rc.d/init.d/chefinittest", "/etc/rc.d/rc2.d/Schefinittest")
+ end
+
+ after do
+ File.delete("/etc/rc.d/rc2.d/Schefinittest") if File.exists?("/etc/rc.d/rc2.d/chefinittest")
+ end
+
+ it "creates symlink with status K" do
+ new_resource.run_action(:disable)
+ valide_symlinks(["/etc/rc.d/rc2.d/Kchefinittest"], 2,'K')
+ end
+ end
+
+ context "when the service sets a simple priority (integer)" do
+ before do
+ new_resource.priority(75)
+ File.symlink("/etc/rc.d/init.d/chefinittest", "/etc/rc.d/rc2.d/Schefinittest")
+ end
+
+ after do
+ File.delete("/etc/rc.d/rc2.d/Schefinittest") if File.exists?("/etc/rc.d/rc2.d/chefinittest")
+ end
+
+ it "creates a symlink with status K and a priority" do
+ new_resource.run_action(:disable)
+ valide_symlinks(["/etc/rc.d/rc2.d/K25chefinittest"], 2,'K',25)
+ end
+ end
+
+ context "when the service sets complex priorities (hash)" do
+ before do
+ @priority = {2 => [:stop, 20], 3 => [:start, 10]}
+ new_resource.priority(@priority)
+ File.symlink("/etc/rc.d/init.d/chefinittest", "/etc/rc.d/rc2.d/Schefinittest")
+ end
+
+ after do
+ File.delete("/etc/rc.d/rc2.d/Schefinittest") if File.exists?("/etc/rc.d/rc2.d/chefinittest")
+ end
+
+ it "create symlink with status stop (K) and a priority " do
+ new_resource.run_action(:disable)
+ valide_symlinks(["/etc/rc.d/rc2.d/K80chefinittest"], 2,'K',80)
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index d29215f5fe..b1d7cdbd64 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -119,6 +119,7 @@ RSpec.configure do |config|
config.filter_run_excluding :solaris_only => true unless solaris?
config.filter_run_excluding :system_windows_service_gem_only => true unless system_windows_service_gem?
config.filter_run_excluding :unix_only => true unless unix?
+ config.filter_run_excluding :aix_only => true unless aix?
config.filter_run_excluding :supports_cloexec => true unless supports_cloexec?
config.filter_run_excluding :selinux_only => true unless selinux_enabled?
config.filter_run_excluding :ruby_18_only => true unless ruby_18?
diff --git a/spec/unit/provider/service/aix_service_spec.rb b/spec/unit/provider/service/aix_service_spec.rb
new file mode 100644
index 0000000000..070f618b99
--- /dev/null
+++ b/spec/unit/provider/service/aix_service_spec.rb
@@ -0,0 +1,181 @@
+#
+# Author:: Kaustubh <kaustubh@clogeny.com>
+# Copyright:: Copyright (c) 2014 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'
+
+describe Chef::Provider::Service::Aix do
+ 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("chef")
+ @current_resource = Chef::Resource::Service.new("chef")
+
+ @provider = Chef::Provider::Service::Aix.new(@new_resource, @run_context)
+ Chef::Resource::Service.stub(:new).and_return(@current_resource)
+ end
+
+ describe "load current resource" do
+ it "should create a current resource with the name of the new resource and determine the status" do
+ @status = double("Status", :exitstatus => 0, :stdout => @stdout)
+ @provider.stub(:shell_out!).and_return(@status)
+
+ Chef::Resource::Service.should_receive(:new).and_return(@current_resource)
+ @current_resource.should_receive(:service_name).with("chef")
+ @provider.should_receive(:determine_current_status!)
+
+ @provider.load_current_resource
+ end
+ end
+
+ describe "determine current status" do
+ context "when the service is active" do
+ before do
+ @status = double("Status", :exitstatus => 0, :stdout => "chef chef 12345 active\n")
+ end
+
+ it "current resource is running" do
+ @provider.should_receive(:shell_out!).with("lssrc -a | grep -w chef").and_return(@status)
+ @provider.should_receive(:is_resource_group?).with(["chef chef 12345 active"])
+
+ @provider.load_current_resource
+ @current_resource.running.should be_true
+ end
+ end
+
+ context "when the service is inoprative" do
+ before do
+ @status = double("Status", :exitstatus => 0, :stdout => "chef chef inoperative\n")
+ end
+
+ it "current resource is not running" do
+ @provider.should_receive(:shell_out!).with("lssrc -a | grep -w chef").and_return(@status)
+ @provider.should_receive(:is_resource_group?).with(["chef chef inoperative"])
+
+ @provider.load_current_resource
+ @current_resource.running.should be_false
+ end
+ end
+ end
+
+ describe "is resource group" do
+ context "when there are mutiple subsystems associated with group" do
+ before do
+ @status = double("Status", :exitstatus => 0, :stdout => "chef1 chef 12345 active\nchef2 chef 12334 active\nchef3 chef inoperative")
+ end
+
+ it "service is a group" do
+ @provider.should_receive(:shell_out!).with("lssrc -a | grep -w chef").and_return(@status)
+ @provider.load_current_resource
+ @provider.instance_eval("@is_resource_group").should be_true
+ end
+ end
+
+ context "when there is a single subsystem in the group" do
+ before do
+ @status = double("Status", :exitstatus => 0, :stdout => "chef1 chef inoperative\n")
+ end
+
+ it "service is a group" do
+ @provider.should_receive(:shell_out!).with("lssrc -a | grep -w chef").and_return(@status)
+ @provider.load_current_resource
+ @provider.instance_eval("@is_resource_group").should be_true
+ end
+ end
+
+ context "when there service is a subsytem" do
+ before do
+ @status = double("Status", :exitstatus => 0, :stdout => "chef chef123 inoperative\n")
+ end
+
+ it "service is a subsystem" do
+ @provider.should_receive(:shell_out!).with("lssrc -a | grep -w chef").and_return(@status)
+ @provider.load_current_resource
+ @provider.instance_eval("@is_resource_group").should be_false
+ end
+ end
+ end
+
+ describe "when starting the service" do
+ before do
+ @new_resource.service_name "apache"
+ end
+
+ it "should call the start command for groups" do
+ @provider.instance_eval('@is_resource_group = true')
+ @provider.should_receive(:shell_out!).with("startsrc -g #{@new_resource.service_name}")
+
+ @provider.start_service
+ end
+
+ it "should call the start command for subsystem" do
+ @provider.should_receive(:shell_out!).with("startsrc -s #{@new_resource.service_name}")
+
+ @provider.start_service
+ end
+ end
+
+ describe "when stopping a service" do
+ before do
+ @new_resource.service_name "apache"
+ end
+
+ it "should call the stop command for groups" do
+ @provider.instance_eval('@is_resource_group = true')
+ @provider.should_receive(:shell_out!).with("stopsrc -g #{@new_resource.service_name}")
+
+ @provider.stop_service
+ end
+
+ it "should call the stop command for subsystem" do
+ @provider.should_receive(:shell_out!).with("stopsrc -s #{@new_resource.service_name}")
+
+ @provider.stop_service
+ end
+ end
+
+ describe "when reloading a service" do
+ before do
+ @new_resource.service_name "apache"
+ end
+
+ it "should call the reload command for groups" do
+ @provider.instance_eval('@is_resource_group = true')
+ @provider.should_receive(:shell_out!).with("refresh -g #{@new_resource.service_name}")
+
+ @provider.reload_service
+ end
+
+ it "should call the reload command for subsystem" do
+ @provider.should_receive(:shell_out!).with("refresh -s #{@new_resource.service_name}")
+
+ @provider.reload_service
+ end
+ end
+
+ describe "when restarting the service" do
+ it "should call stop service followed by start service" do
+ @provider.should_receive(:stop_service)
+ @provider.should_receive(:start_service)
+
+ @provider.restart_service
+ end
+ end
+end
+
diff --git a/spec/unit/provider/service/aixinit_service_spec.rb b/spec/unit/provider/service/aixinit_service_spec.rb
new file mode 100644
index 0000000000..bb090b112c
--- /dev/null
+++ b/spec/unit/provider/service/aixinit_service_spec.rb
@@ -0,0 +1,269 @@
+#
+# Author:: kaustubh (<kaustubh@clogeny.com>)
+# Copyright:: Copyright (c) 2014 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'
+
+describe Chef::Provider::Service::AixInit do
+ before(:each) do
+ @node = Chef::Node.new
+ @node.automatic_attrs[:command] = {:ps => 'fuuuu'}
+ @events = Chef::EventDispatch::Dispatcher.new
+ @run_context = Chef::RunContext.new(@node, {}, @events)
+
+ @new_resource = Chef::Resource::Service.new("chef")
+ @provider = Chef::Provider::Service::AixInit.new(@new_resource, @run_context)
+
+ @current_resource = Chef::Resource::Service.new("chef")
+ @provider.current_resource = @current_resource
+
+ @pid, @stdin, @stdout, @stderr = nil, nil, nil, nil
+ end
+
+ describe "load_current_resource" do
+ it "sets current resource attributes" do
+ @provider.should_receive(:set_current_resource_attributes)
+
+ @provider.load_current_resource
+ end
+ end
+
+ describe "action_enable" do
+ shared_examples_for "the service is up to date" do
+ it "does not enable the service" do
+ @provider.should_not_receive(:enable_service)
+ @provider.action_enable
+ @provider.set_updated_status
+ @provider.new_resource.should_not be_updated
+ end
+ end
+
+ shared_examples_for "the service is not up to date" do
+ it "enables the service and sets the resource as updated" do
+ @provider.should_receive(:enable_service).and_return(true)
+ @provider.action_enable
+ @provider.set_updated_status
+ @provider.new_resource.should be_updated
+ end
+ end
+
+ context "when the service is disabled" do
+ before do
+ @current_resource.enabled(false)
+ end
+
+ it_behaves_like "the service is not up to date"
+ end
+
+ context "when the service is enabled" do
+ before do
+ @current_resource.enabled(true)
+ @current_resource.priority(80)
+ end
+
+ context "and the service sets no priority" do
+ it_behaves_like "the service is up to date"
+ end
+
+ context "and the service requests the same priority as is set" do
+ before do
+ @new_resource.priority(80)
+ end
+ it_behaves_like "the service is up to date"
+ end
+
+ context "and the service requests a different priority than is set" do
+ before do
+ @new_resource.priority(20)
+ end
+ it_behaves_like "the service is not up to date"
+ end
+ end
+ end
+
+ describe "enable_service" do
+ before do
+ Dir.stub(:glob).with(["/etc/rc.d/rc2.d/[SK][0-9][0-9]#{@new_resource.service_name}", "/etc/rc.d/rc2.d/[SK]#{@new_resource.service_name}"]).and_return([])
+ end
+
+ context "when the service doesn't set a priority" do
+ it "creates symlink with status S" do
+ @provider.should_receive(:create_symlink).with(2,'S','')
+
+ @provider.enable_service
+ end
+ end
+
+ context "when the service sets a simple priority (integer)" do
+ before do
+ @new_resource.priority(75)
+ end
+
+ it "creates a symlink with status S and a priority" do
+ @provider.should_receive(:create_symlink).with(2,'S',75)
+
+ @provider.enable_service
+ end
+ end
+
+ context "when the service sets complex priorities (hash)" do
+ before do
+ priority = {2 => [:start, 20], 3 => [:stop, 10]}
+ @new_resource.priority(priority)
+ end
+
+ it "create symlink with status start (S) or stop (K) and a priority " do
+ @provider.should_receive(:create_symlink).with(2,'S',20)
+ @provider.should_receive(:create_symlink).with(3,'K',10)
+
+ @provider.enable_service
+ end
+ end
+ end
+
+ describe "disable_service" do
+ before do
+ Dir.stub(:glob).with(["/etc/rc.d/rc2.d/[SK][0-9][0-9]#{@new_resource.service_name}", "/etc/rc.d/rc2.d/[SK]#{@new_resource.service_name}"]).and_return([])
+ end
+
+ context "when the service doesn't set a priority" do
+ it "creates symlinks with status stop (K)" do
+ @provider.should_receive(:create_symlink).with(2,'K','')
+
+ @provider.disable_service
+ end
+ end
+
+ context "when the service sets a simple priority (integer)" do
+ before do
+ @new_resource.priority(75)
+ end
+
+ it "create symlink with status stop (k) and a priority " do
+ @provider.should_receive(:create_symlink).with(2,'K',25)
+
+ @provider.disable_service
+ end
+ end
+
+ context "when the service sets complex priorities (hash)" do
+ before do
+ @priority = {2 => [:start, 20], 3 => [:stop, 10]}
+ @new_resource.priority(@priority)
+ end
+
+ it "create symlink with status stop (k) and a priority " do
+ @provider.should_receive(:create_symlink).with(3,'K',90)
+
+ @provider.disable_service
+ end
+ end
+ end
+
+ describe "set_current_resource_attributes" do
+ context "when rc2.d contains only start script" do
+ before do
+ files = ["/etc/rc.d/rc2.d/S20apache"]
+
+ Dir.stub(:glob).with(["/etc/rc.d/rc2.d/[SK][0-9][0-9]#{@new_resource.service_name}", "/etc/rc.d/rc2.d/[SK]chef"]).and_return(files)
+ end
+
+ it "the service is enabled" do
+ @provider.current_resource.should_receive(:enabled).with(true)
+ @provider.current_resource.should_receive(:priority).with(20)
+
+ @provider.set_current_resource_attributes
+ end
+ end
+
+ context "when rc2.d contains only stop script" do
+ before do
+ files = ["/etc/rc.d/rc2.d/K20apache"]
+ @priority = {2 => [:stop, 20]}
+
+ Dir.stub(:glob).with(["/etc/rc.d/rc2.d/[SK][0-9][0-9]#{@new_resource.service_name}", "/etc/rc.d/rc2.d/[SK]chef"]).and_return(files)
+ end
+ it "the service is not enabled" do
+ @provider.current_resource.should_receive(:enabled).with(false)
+ @provider.current_resource.should_receive(:priority).with(@priority)
+
+ @provider.set_current_resource_attributes
+ end
+ end
+
+ context "when rc2.d contains both start and stop scripts" do
+ before do
+ @files = ["/etc/rc.d/rc2.d/S20apache", "/etc/rc.d/rc2.d/K80apache"]
+ @priority = {2 => [:start, 20], 2 => [:stop, 80]}
+
+ Dir.stub(:glob).with(["/etc/rc.d/rc2.d/[SK][0-9][0-9]#{@new_resource.service_name}", "/etc/rc.d/rc2.d/[SK]chef"]).and_return(@files)
+ end
+ it "the service is enabled" do
+ @current_resource.should_receive(:enabled).with(true)
+ @current_resource.should_receive(:priority).with(@priority)
+
+ @provider.set_current_resource_attributes
+ end
+ end
+
+ context "when rc2.d contains only start script (without priority)" do
+ before do
+ files = ["/etc/rc.d/rc2.d/Sapache"]
+
+ Dir.stub(:glob).with(["/etc/rc.d/rc2.d/[SK][0-9][0-9]#{@new_resource.service_name}", "/etc/rc.d/rc2.d/[SK]#{@new_resource.service_name}"]).and_return(files)
+ end
+
+ it "the service is enabled" do
+ @provider.current_resource.should_receive(:enabled).with(true)
+ @provider.current_resource.should_receive(:priority).with('')
+
+ @provider.set_current_resource_attributes
+ end
+ end
+
+ context "when rc2.d contains only stop script (without priority)" do
+ before do
+ files = ["/etc/rc.d/rc2.d/Kapache"]
+ @priority = {2 => [:stop, '']}
+
+ Dir.stub(:glob).with(["/etc/rc.d/rc2.d/[SK][0-9][0-9]#{@new_resource.service_name}", "/etc/rc.d/rc2.d/[SK]#{@new_resource.service_name}"]).and_return(files)
+ end
+ it "the service is not enabled" do
+ @provider.current_resource.should_receive(:enabled).with(false)
+ @provider.current_resource.should_receive(:priority).with(@priority)
+
+ @provider.set_current_resource_attributes
+ end
+ end
+
+ context "when rc2.d contains both start and stop scripts" do
+ before do
+ files = ["/etc/rc.d/rc2.d/Sapache", "/etc/rc.d/rc2.d/Kapache"]
+ @priority = {2 => [:start, ''], 2 => [:stop, '']}
+
+ Dir.stub(:glob).with(["/etc/rc.d/rc2.d/[SK][0-9][0-9]#{@new_resource.service_name}", "/etc/rc.d/rc2.d/[SK]#{@new_resource.service_name}"]).and_return(files)
+ end
+ it "the service is enabled" do
+ @current_resource.should_receive(:enabled).with(true)
+ @current_resource.should_receive(:priority).with(@priority)
+
+ @provider.set_current_resource_attributes
+ end
+ end
+ end
+end
+