#!/usr/bin/env ruby

$:.unshift("../../lib") if __FILE__ =~ /\.rb$/

require 'puppettest'

$skipsvcs = false
case Facter["operatingsystem"].value
when "Darwin", "OpenBSD": $skipsvcs = true
end

if $skipsvcs
    puts "Skipping service testing on %s" % Facter["operatingsystem"].value
else
class TestLocalService < Test::Unit::TestCase
	include PuppetTest

    def teardown
        Puppet.type(:service).clear
        super
    end

    def mktestsvcs
        list = tstsvcs.collect { |svc,svcargs|
            args = svcargs.dup
            args[:name] = svc
            Puppet.type(:service).create(args)
        }
    end

    def tstsvcs
        case Facter["operatingsystem"].value.downcase
        when "solaris":
            case Facter["operatingsystemrelease"].value
            when "5.10":
                return {"smtp" => {}, "xfs" => {}}
            end
        when "debian":
            return {"hddtemp" => {:hasrestart => true}}
        when "centos":
            return {"cups" => {:hasstatus => true}}
        when "redhat":
            return {"saslauthd" => {:hasstatus => true}}
        end

        Puppet.notice "No test services for %s-%s" %
            [Facter["operatingsystem"].value,
                Facter["operatingsystemrelease"].value]
        return []
    end

    def cycleservice(service)
        assert_nothing_raised() {
            service.retrieve
        }

        comp = newcomp("servicetst", service)
        service[:ensure] = true

        Puppet.info "Starting %s" % service.name
        assert_apply(service)

        # Some package systems background the work, so we need to give them
        # time to do their work.
        sleep(1.5)
        assert_nothing_raised() {
            service.retrieve
        }
        assert(service.insync?, "Service %s is not running" % service.name)

        # test refreshing it
        assert_nothing_raised() {
            service.refresh
        }

        # now stop it
        assert_nothing_raised() {
            service[:ensure] = :stopped
        }
        assert_nothing_raised() {
            service.retrieve
        }
        assert(!service.insync?(), "Service %s is not running" % service.name)
        Puppet.info "stopping %s" % service.name
        assert_events([:service_stopped], comp)
        sleep(1.5)
        assert_nothing_raised() {
            service.retrieve
        }
        assert(service.insync?, "Service %s has not stopped" % service.name)
    end

    def cycleenable(service)
        assert_nothing_raised() {
            service.retrieve
        }

        comp = newcomp("servicetst", service)
        service[:enable] = true

        Puppet.info "Enabling %s" % service.name
        assert_apply(service)

        # Some package systems background the work, so we need to give them
        # time to do their work.
        sleep(1.5)
        assert_nothing_raised() {
            service.retrieve
        }
        assert(service.insync?, "Service %s is not enabled" % service.name)

        # now stop it
        assert_nothing_raised() {
            service[:enable] = false
        }
        assert_nothing_raised() {
            service.retrieve
        }
        assert(!service.insync?(), "Service %s is not enabled" % service.name)
        Puppet.info "disabling %s" % service.name
        assert_events([:service_disabled], comp)
        sleep(1.5)
        assert_nothing_raised() {
            service.retrieve
        }
        assert(service.insync?, "Service %s has not been disabled" % service.name)
    end

    def test_status
        mktestsvcs.each { |svc|
            val = nil
            assert_nothing_raised("Could not get status") {
                val = svc.provider.status
            }
            assert_instance_of(Symbol, val)
        }
    end

    unless Puppet::Util::SUIDManager.uid == 0
        puts "run as root to test service start/stop"
    else
        def test_servicestartstop
            mktestsvcs.each { |svc|
                startproperty = nil
                assert_nothing_raised("Could not get status") {
                    startproperty = svc.provider.status
                }
                cycleservice(svc)

                svc[:ensure] = startproperty
                assert_apply(svc)
                Puppet.type(:component).clear
            }
        end

        def test_serviceenabledisable
            mktestsvcs.each { |svc|
                assert(svc[:name], "Service has no name")
                startproperty = nil
                svc[:check] = :enable
                assert_nothing_raised("Could not get status") {
                    startproperty = svc.provider.enabled?
                }
                cycleenable(svc)

                svc[:enable] = startproperty
                assert_apply(svc)
                Puppet.type(:component).clear
            }
        end

        def test_serviceenableandrun
            mktestsvcs.each do |svc|
                startenable = nil
                startensure = nil
                svc[:check] = [:ensure, :enable]
                svc.retrieve
                assert_nothing_raised("Could not get status") {
                    startenable = svc.property(:enable).is
                    startensure = svc.property(:ensure).is
                }

                svc[:enable] = false
                svc[:ensure] = :stopped
                assert_apply(svc)

                sleep 1
                svc.retrieve
                assert(svc.insync?, "Service did not sync both properties")

                svc[:enable] = true
                svc[:ensure] = :running
                assert_apply(svc)

                sleep 1
                svc.retrieve
                assert(svc.insync?, "Service did not sync both properties")

                svc[:enable] = startenable
                svc[:ensure] = startensure
                assert_apply(svc)
                Puppet.type(:component).clear
            end
        end
    end
end
end

# $Id: service.rb 2236 2007-02-27 23:57:55Z luke $


syntax highlighted by Code2HTML, v. 0.9.1