diff --git a/spec/unit/provider/service/launchd_spec.rb b/spec/unit/provider/service/launchd_spec.rb index ddbd54c55..beb7ed607 100755 --- a/spec/unit/provider/service/launchd_spec.rb +++ b/spec/unit/provider/service/launchd_spec.rb @@ -1,213 +1,207 @@ -#!/usr/bin/env rspec -# -# Unit testing for the launchd service provider +# Spec Tests for the Launchd provider # require 'spec_helper' -require 'puppet' -require 'facter' - -provider_class = Puppet::Type.type(:service).provider(:launchd) - -describe provider_class do - - before :each do - # Create a mock resource - @resource = stub 'resource' - - @provider = provider_class.new - @joblabel = "com.foo.food" - @jobplist = {} - @services = {} - @args = {} - @class = Puppet::Type.type(:service).provider(:launchd) - - # A catch all; no parameters set - @resource.stubs(:[]).returns(nil) - - # But set name, ensure and enable - @resource.stubs(:[]).with(:name).returns @joblabel - @resource.stubs(:[]).with(:ensure).returns :enabled - @resource.stubs(:[]).with(:enable).returns :true - @resource.stubs(:ref).returns "Service[#{@joblabel}]" - - # stub out the provider methods that actually touch the filesystem - # or execute commands - @provider.stubs(:plist_from_label).returns([@joblabel, @jobplist]) - @provider.stubs(:execute).returns("") - @provider.stubs(:resource).returns @resource - - # We stub this out for the normal case as 10.6 is "special". - provider_class.stubs(:get_macosx_version_major).returns("10.5") - - end - - it "should have a start method for #{@provider.object_id}" do - @provider.should respond_to(:start) - end - it "should have a stop method" do - @provider.should respond_to(:stop) - end - - it "should have an enabled? method" do - @provider.should respond_to(:enabled?) - end - - it "should have an enable method" do - @provider.should respond_to(:enable) - end - - it "should have a disable method" do - @provider.should respond_to(:disable) - end +describe Puppet::Type.type(:service).provider(:launchd) do + let (:joblabel) { "com.foo.food" } + let (:provider) { subject.class } + let (:launchd_overrides) { '/var/db/launchd.db/com.apple.launchd/overrides.plist' } - it "should have a status method" do - @provider.should respond_to(:status) + describe "the type interface" do + %w{ start stop enabled? enable disable status}.each do |method| + it { should respond_to method.to_sym } + end end - - describe "when checking status" do + describe 'the status of the services' do it "should call the external command 'launchctl list' once" do - @class.expects(:launchctl).with(:list).returns(@joblabel) - @class.stubs(:jobsearch).with(nil).returns({@joblabel => "/Library/LaunchDaemons/#{@joblabel}"}) - @services = @class.prefetch(@args) + provider.expects(:launchctl).with(:list).returns(joblabel) + provider.expects(:jobsearch).with(nil).returns({joblabel => "/Library/LaunchDaemons/#{joblabel}"}) + provider.prefetch({}) end it "should return stopped if not listed in launchctl list output" do - #@class.expects(:launchctl).with(:list).returns(@joblabel) - @class.stubs(:launchctl).with(:list).returns('com.bar.barred') - @class.stubs(:jobsearch).with(nil).returns({'com.bar.barred' => ""}) - @services = @class.prefetch(@args) - @services.last.status.should == :stopped + provider.expects(:launchctl).with(:list).returns('com.bar.is_running') + provider.expects(:jobsearch).with(nil).returns({'com.bar.is_not_running' => ""}) + provider.prefetch({}).last.status.should eq :stopped end it "should return running if listed in launchctl list output" do - @class.stubs(:launchctl).with(:list).returns(@joblabel) - @class.stubs(:jobsearch).with(nil).returns({@joblabel => "/Library/LaunchDaemons/#{@joblabel}"}) - @services = @class.prefetch(@args) - @services.last.status.should == :running + provider.expects(:launchctl).with(:list).returns('com.bar.is_running') + provider.expects(:jobsearch).with(nil).returns({'com.bar.is_running' => ""}) + provider.prefetch({}).last.status.should eq :running end end - describe "when checking whether the service is enabled" do - it "should return true if the job plist says disabled is false" do - @provider.stubs(:plist_from_label).returns(["foo", {"Disabled" => false}]) - @provider.enabled?.should == :true + describe "when checking whether the service is enabled on OS X 10.5" do + it "should return true in if the job plist says disabled is false" do + Facter.expects(:value).times(2).with(:macosx_productversion_major).returns('10.5') + Facter.expects(:value).times(11).with(:kernel).returns('Darwin') + subject.expects(:plist_from_label).with(joblabel).returns(["foo", {"Disabled" => false}]) + subject.expects(:resource).returns({:name => joblabel}) + subject.enabled?.should == :true end - it "should return true if the job plist has no disabled key" do - @provider.stubs(:plist_from_label).returns(["foo", {}]) - @provider.enabled?.should == :true + it "should return true in if the job plist has no disabled key" do + subject.expects(:resource).returns({:name => joblabel}) + subject.stubs(:plist_from_label).returns(["foo", {}]) + subject.enabled?.should == :true end - it "should return false if the job plist says disabled is true" do - @provider.stubs(:plist_from_label).returns(["foo", {"Disabled" => true}]) - Facter.stubs(:value).with(:macosx_productversion_major).returns('10.5') - @provider.enabled?.should == :false + it "should return false in if the job plist says disabled is true" do + subject.expects(:resource).returns({:name => joblabel}) + subject.stubs(:plist_from_label).returns(["foo", {"Disabled" => true}]) + subject.enabled?.should == :false end end describe "when checking whether the service is enabled on OS X 10.6" do it "should return true if the job plist says disabled is true and the global overrides says disabled is false" do - provider_class.stubs(:get_macosx_version_major).returns("10.6") - @provider.stubs(:plist_from_label).returns(["foo", {"Disabled" => true}]) - @provider.class.stubs(:read_plist).returns({@resource[:name] => {"Disabled" => false}}) - FileTest.expects(:file?).with(Launchd_Overrides).returns(true) - @provider.enabled?.should == :true + provider.expects(:get_macosx_version_major).returns("10.6") + subject.expects(:plist_from_label).returns([joblabel, {"Disabled" => true}]) + provider.stubs(:read_plist).returns({joblabel => {"Disabled" => false}}) + FileTest.expects(:file?).with(launchd_overrides).returns(true) + subject.expects(:resource).times(4).returns({:name => joblabel}) + subject.enabled?.should == :true end it "should return false if the job plist says disabled is false and the global overrides says disabled is true" do - provider_class.stubs(:get_macosx_version_major).returns("10.6") - @provider.stubs(:plist_from_label).returns(["foo", {"Disabled" => false}]) - @provider.class.stubs(:read_plist).returns({@resource[:name] => {"Disabled" => true}}) - FileTest.expects(:file?).with(Launchd_Overrides).returns(true) - @provider.enabled?.should == :false + provider.expects(:get_macosx_version_major).returns("10.6") + subject.expects(:plist_from_label).returns([joblabel, {"Disabled" => false}]) + provider.stubs(:read_plist).returns({joblabel => {"Disabled" => true}}) + FileTest.expects(:file?).with(launchd_overrides).returns(true) + subject.expects(:resource).times(4).returns({:name => joblabel}) + subject.enabled?.should == :false end it "should return true if the job plist and the global overrides have no disabled keys" do - provider_class.stubs(:get_macosx_version_major).returns("10.6") - @provider.stubs(:plist_from_label).returns(["foo", {}]) - @provider.class.stubs(:read_plist).returns({}) - FileTest.expects(:file?).with(Launchd_Overrides).returns(true) - @provider.enabled?.should == :true + provider.expects(:get_macosx_version_major).returns("10.6") + subject.expects(:plist_from_label).returns([joblabel, {}]) + provider.stubs(:read_plist).returns({}) + FileTest.expects(:file?).with(launchd_overrides).returns(true) + subject.expects(:resource).times(2).returns({:name => joblabel}) + subject.enabled?.should == :true end end describe "when starting the service" do it "should look for the relevant plist once" do - @provider.expects(:plist_from_label).once - @provider.start - end - it "should execute 'launchctl load' once without writing to the plist if the job is enabled" do - @provider.stubs(:enabled?).returns :true - @provider.expects(:execute).with([:launchctl, :load, @resource[:name]]).once - @provider.start + subject.expects(:plist_from_label).returns([joblabel, {}]).once + subject.stubs(:enabled?).returns :true + subject.stubs(:execute).with([:launchctl, :load, joblabel]) + subject.stubs(:resource).returns({:name => joblabel}) + subject.start + end + it "should execute 'launchctl load' once without writing to the plist if the job is enabled" do + subject.stubs(:plist_from_label).returns([joblabel, {}]) + subject.stubs(:enabled?).returns :true + subject.expects(:execute).with([:launchctl, :load, joblabel]).once + subject.stubs(:resource).returns({:name => joblabel}) + subject.start end it "should execute 'launchctl load' with writing to the plist once if the job is disabled" do - @provider.stubs(:enabled?).returns :false - @provider.expects(:execute).with([:launchctl, :load, "-w", @resource[:name]]).once - @provider.start + subject.stubs(:plist_from_label).returns([joblabel, {}]) + subject.stubs(:enabled?).returns(:false) + subject.stubs(:resource).returns({:name => joblabel}) + subject.expects(:execute).with([:launchctl, :load, "-w", joblabel]).once + subject.start end it "should disable the job once if the job is disabled and should be disabled at boot" do - @provider.stubs(:enabled?).returns :false - @resource.stubs(:[]).with(:enable).returns :false - @provider.expects(:disable).once - @provider.start + subject.stubs(:plist_from_label).returns([joblabel, {"Disabled" => true}]) + subject.stubs(:enabled?).returns :false + subject.stubs(:execute).with([:launchctl, :load, "-w", joblabel]) + subject.stubs(:resource).returns({:name => joblabel, :enable => :false}) + subject.expects(:disable).once + subject.start end end describe "when stopping the service" do it "should look for the relevant plist once" do - @provider.expects(:plist_from_label).once - @provider.stop + subject.expects(:plist_from_label).returns([joblabel, {}]).once + subject.stubs(:enabled?).returns :true + subject.stubs(:execute).with([:launchctl, :unload, '-w', joblabel]) + subject.stubs(:resource).returns({:name => joblabel}) + subject.stop end it "should execute 'launchctl unload' once without writing to the plist if the job is disabled" do - @provider.stubs(:enabled?).returns :false - @provider.expects(:execute).with([:launchctl, :unload, @resource[:name]]).once - @provider.stop + subject.stubs(:plist_from_label).returns([joblabel, {}]) + subject.stubs(:enabled?).returns :false + subject.expects(:execute).with([:launchctl, :unload, joblabel]).once + subject.stubs(:resource).returns({:name => joblabel}) + subject.stop end it "should execute 'launchctl unload' with writing to the plist once if the job is enabled" do - @provider.stubs(:enabled?).returns :true - @provider.expects(:execute).with([:launchctl, :unload, "-w", @resource[:name]]).once - @provider.stop + subject.stubs(:plist_from_label).returns([joblabel, {}]) + subject.stubs(:enabled?).returns :true + subject.expects(:execute).with([:launchctl, :unload, '-w', joblabel]).once + subject.stubs(:resource).returns({:name => joblabel}) + subject.stop end it "should enable the job once if the job is enabled and should be enabled at boot" do - @provider.stubs(:enabled?).returns :true - @resource.stubs(:[]).with(:enable).returns :true - @provider.expects(:enable).once - @provider.stop + subject.stubs(:plist_from_label).returns([joblabel, {"Disabled" => false}]) + subject.stubs(:enabled?).returns :true + subject.stubs(:execute).with([:launchctl, :unload, "-w", joblabel]) + subject.stubs(:resource).returns({:name => joblabel, :enable => :true}) + subject.expects(:enable).once + subject.stop end end describe "when enabling the service" do - it "should look for the relevant plist once" do - @provider.expects(:plist_from_label).once - @provider.stop + it "should look for the relevant plist once" do ### Do we need this test? Differentiating it? + subject.expects(:plist_from_label).returns([joblabel, {}]).once + subject.stubs(:enabled?).returns :false + subject.stubs(:execute).with([:launchctl, :unload, joblabel]) + subject.stubs(:resource).returns({:name => joblabel, :enable => :true}) + subject.stop end it "should check if the job is enabled once" do - @provider.expects(:enabled?).once - @provider.stop + subject.stubs(:plist_from_label).returns([joblabel, {}]).once + subject.expects(:enabled?).once + subject.stubs(:execute).with([:launchctl, :unload, joblabel]) + subject.stubs(:resource).returns({:name => joblabel, :enable => :true}) + subject.stop end end describe "when disabling the service" do it "should look for the relevant plist once" do - @provider.expects(:plist_from_label).once - @provider.stop + subject.expects(:plist_from_label).returns([joblabel, {}]).once + subject.stubs(:enabled?).returns :true + subject.stubs(:execute).with([:launchctl, :unload, '-w', joblabel]) + subject.stubs(:resource).returns({:name => joblabel, :enable => :false}) + subject.stop end end describe "when enabling the service on OS X 10.6" do it "should write to the global launchd overrides file once" do - provider_class.stubs(:get_macosx_version_major).returns("10.6") - @provider.class.stubs(:read_plist).returns({}) + provider.stubs(:get_macosx_version_major).returns("10.6") + provider.stubs(:read_plist).returns({}) Plist::Emit.expects(:save_plist).once - @provider.enable + subject.stubs(:resource).returns({:name => joblabel, :enable => :true}) + subject.enable end end describe "when disabling the service on OS X 10.6" do it "should write to the global launchd overrides file once" do - provider_class.stubs(:get_macosx_version_major).returns("10.6") - @provider.class.stubs(:read_plist).returns({}) + provider.stubs(:get_macosx_version_major).returns("10.6") + provider.stubs(:read_plist).returns({}) Plist::Emit.expects(:save_plist).once - @provider.enable + subject.stubs(:resource).returns({:name => joblabel, :enable => :false}) + subject.enable end end -end + describe "when using an incompatible version of Facter" do + it "should display a deprecation warning" do + Facter.stubs(:value).with(:macosx_productversion_major).returns(nil) + Facter.stubs(:value).with(:kernel).returns('Darwin') + Facter.stubs(:value).with(:macosx_productversion).returns('10.5.8') + Puppet::Util::Warnings.expects(:maybe_log) + provider.stubs(:read_plist).returns({joblabel => {"Disabled" => false}}) + subject.stubs(:plist_from_label).returns([joblabel, {"Disabled" => false}]) + subject.stubs(:enabled?).returns :false + subject.stubs(:execute).with([:launchctl, :load, '-w', joblabel]) + subject.stubs(:resource).returns({:name => joblabel, :enable => :true}) + subject.enable + end + end +end \ No newline at end of file