\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7 \8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh \00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€ \00 $\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95 59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9 C/// File Manager

File Manager

Path: /opt/chef/embedded/lib/ruby/gems/2.7.0/gems/chef-16.3.45/spec/unit/provider/

Viewing File: launchd_spec.rb

#
# Author:: Mike Dodge (<mikedodge04@gmail.com>)
# Copyright:: Copyright (c) 2015 Facebook, 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::Launchd do

  context "When launchd manages call.mom.weekly" do
    let(:node) { Chef::Node.new }
    let(:events) { Chef::EventDispatch::Dispatcher.new }
    let(:run_context) { Chef::RunContext.new(node, {}, events) }
    let(:provider) { Chef::Provider::Launchd.new(new_resource, run_context) }

    let(:label) { "call.mom.weekly" }
    let(:new_resource) { Chef::Resource::Launchd.new(label) }
    let!(:current_resource) { Chef::Resource::Launchd.new(label) }
    let(:test_plist) { String.new <<~XML }
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
      <plist version="1.0">
      <dict>
      \t<key>Label</key>
      \t<string>call.mom.weekly</string>
      \t<key>Program</key>
      \t<string>/Library/scripts/call_mom.sh</string>
      \t<key>StartCalendarInterval</key>
      \t<dict>
      \t\t<key>Hour</key>
      \t\t<integer>10</integer>
      \t\t<key>Weekday</key>
      \t\t<integer>7</integer>
      \t</dict>
      \t<key>TimeOut</key>
      \t<integer>300</integer>
      </dict>
      </plist>
    XML
    let(:test_plist_multiple_intervals) { String.new <<~XML }
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
      <plist version="1.0">
      <dict>
      \t<key>Label</key>
      \t<string>call.mom.weekly</string>
      \t<key>Program</key>
      \t<string>/Library/scripts/call_mom.sh</string>
      \t<key>StartCalendarInterval</key>
      \t<array>
      \t\t<dict>
      \t\t\t<key>Hour</key>
      \t\t\t<integer>11</integer>
      \t\t\t<key>Weekday</key>
      \t\t\t<integer>1</integer>
      \t\t</dict>
      \t\t<dict>
      \t\t\t<key>Hour</key>
      \t\t\t<integer>12</integer>
      \t\t\t<key>Weekday</key>
      \t\t\t<integer>2</integer>
      \t\t</dict>
      \t</array>
      \t<key>TimeOut</key>
      \t<integer>300</integer>
      </dict>
      </plist>
    XML

    let(:test_hash) do
      {
      "Label" => "call.mom.weekly",
      "Program" => "/Library/scripts/call_mom.sh",
      "StartCalendarInterval" => {
        "Hour" => 10,
        "Weekday" => 7,
      },
      "TimeOut" => 300,
    }
    end

    before(:each) do
      provider.load_current_resource
    end

    it "resource name and label should be call.mom.weekly" do
      expect(new_resource.name).to eql(label)
      expect(new_resource.label).to eql(label)
    end

    def run_resource_setup_for_action(action)
      new_resource.action(action)
      provider.action = action
      provider.load_current_resource
      provider.define_resource_requirements
      provider.process_resource_requirements
    end

    describe "with type is set to" do
      describe "agent" do
        it "path should be /Library/LaunchAgents/call.mom.weekly.plist" do
          new_resource.type "agent"
          expect(provider.gen_path_from_type)
            .to eq("/Library/LaunchAgents/call.mom.weekly.plist")
        end
      end
      describe "daemon" do
        it "path should be /Library/LaunchDaemons/call.mom.weekly.plist" do
          expect(provider.gen_path_from_type)
            .to eq("/Library/LaunchDaemons/call.mom.weekly.plist")
        end
      end
    end

    describe "with a :create action and" do
      describe "program is passed" do
        it "should produce the test_plist from properties" do
          new_resource.program "/Library/scripts/call_mom.sh"
          new_resource.time_out 300
          new_resource.start_calendar_interval "Hour" => 10, "Weekday" => 7
          expect(provider.file_content?).to be_truthy
          expect(provider.file_content).to eql(test_plist)
        end
      end

      describe "start_calendar_interval is passed" do
        it "should allow array of Hashes" do
          allowed = (1..2).collect do |num|
            {
              "Hour" => 10 + num,
              "Weekday" => num,
            }
          end
          new_resource.program "/Library/scripts/call_mom.sh"
          new_resource.time_out 300
          new_resource.start_calendar_interval allowed
          expect(provider.file_content?).to be_truthy
          expect(provider.file_content).to eql(test_plist_multiple_intervals)
        end

        it "should allow all StartCalendarInterval keys" do
          allowed = {
            "Minute" => 1,
            "Hour" => 1,
            "Day" => 1,
            "Weekday" => 1,
            "Month" => 1,
          }
          new_resource.program "/Library/scripts/call_mom.sh"
          new_resource.time_out 300
          new_resource.start_calendar_interval allowed
          expect(provider.file_content?).to be_truthy
          %w{Minute Hour Day Weekday Month}.each do |key|
            expect(provider.file_content).to include("<key>#{key}</key>")
          end
        end

        it "should not allow invalid ShowCalendarInterval keys" do
          new_resource.program "/Library/scripts/call_mom.sh"
          new_resource.time_out 300
          expect do
            new_resource.start_calendar_interval "Hourly" => 1
          end.to raise_error(/Hourly are invalid/)
        end

        it "should not allow non-integer values" do
          new_resource.program "/Library/scripts/call_mom.sh"
          new_resource.time_out 300
          expect do
            new_resource.start_calendar_interval "Weekday" => "1-2"
          end.to raise_error(/Invalid value.*\(1-2\)/)
        end
      end

      describe "hash is passed" do
        it "should produce the test_plist content from the plist_hash property" do
          new_resource.plist_hash test_hash
          expect(provider.file_content?).to be_truthy
          expect(provider.file_content).to eql(test_plist)
        end
      end
    end

    describe "with an :delete action" do
      describe "and the ld file is present" do
        before(:each) do
          allow(File).to receive(:exists?).and_return(true)
          allow(provider).to receive(
            :manage_service
          ).with(:disable).and_return(true)
          allow(provider).to receive(
            :manage_plist
          ).with(:delete).and_return(true)
        end

        it "should call manage_service with a :disable action" do
          expect(provider.manage_service(:disable)).to be_truthy
        end

        it "works with action :delete" do
          expect(run_resource_setup_for_action(:delete)).to be_truthy
          provider.action_delete
        end
      end

      describe "and the ld file is not present" do
        before(:each) do
          allow(File).to receive(:exists?).and_return(false)
          allow(provider).to receive(
            :manage_plist
          ).with(:delete).and_return(true)
        end

        it "works with action :delete" do
          expect(run_resource_setup_for_action(:delete)).to be_truthy
          provider.action_delete
        end
      end
    end
  end
end