\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/integration/recipes/

Viewing File: notifies_spec.rb

#
# Copyright:: Copyright (c) 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 "support/shared/integration/integration_helper"
require "chef/mixin/shell_out"

describe "notifications" do
  include IntegrationSupport
  include Chef::Mixin::ShellOut

  let(:chef_dir) { File.expand_path("../../../bin", __dir__) }
  let(:chef_client) { "bundle exec chef-client --minimal-ohai" }

  when_the_repository "notifies a nameless resource" do
    before do
      directory "cookbooks/x" do
        file "recipes/default.rb", <<-EOM
          apt_update do
            action :nothing
          end
          notify_group "foo" do
            notifies :nothing, 'apt_update', :delayed
            action :run
          end
          notify_group "bar" do
            notifies :nothing, 'apt_update[]', :delayed
            action :run
          end
        EOM
      end
    end

    it "should complete with success" do
      file "config/client.rb", <<~EOM
        local_mode true
        cookbook_path "#{path_to("cookbooks")}"
        log_level :warn
      EOM

      result = shell_out("#{chef_client} -c \"#{path_to("config/client.rb")}\" --no-color -F doc -o 'x::default'", cwd: chef_dir)
      # our delayed notification should run at the end of the parent run_context after the baz resource
      expect(result.stdout).to match(/\* apt_update\[\] action nothing \(skipped due to action :nothing\)\s+\* notify_group\[foo\] action run\s+\* notify_group\[bar\] action run\s+\* apt_update\[\] action nothing \(skipped due to action :nothing\)/)
      result.error!
    end
  end

  when_the_repository "notifies delayed one" do
    before do
      directory "cookbooks/x" do

        file "resources/notifying_test.rb", <<~EOM
          default_action :run
          provides :notifying_test
          resource_name :notifying_test

          action :run do
            notify_group "bar" do
              notifies :write, 'log[foo]', :delayed
              action :run
            end
          end
        EOM

        file "recipes/default.rb", <<~EOM
          log "foo" do
            action :nothing
          end
          notifying_test "whatever"
          log "baz"
        EOM

      end
    end

    it "should complete with success" do
      file "config/client.rb", <<~EOM
        local_mode true
        cookbook_path "#{path_to("cookbooks")}"
        log_level :warn
      EOM

      result = shell_out("#{chef_client} -c \"#{path_to("config/client.rb")}\" --no-color -F doc -o 'x::default'", cwd: chef_dir)
      # our delayed notification should run at the end of the parent run_context after the baz resource
      expect(result.stdout).to match(/\* notify_group\[bar\] action run\s+\* log\[baz\] action write\s+\* log\[foo\] action write/)
      result.error!
    end
  end

  when_the_repository "notifies delayed two" do
    before do
      directory "cookbooks/x" do

        file "resources/notifying_test.rb", <<~EOM
          default_action :run
          provides :notifying_test
          resource_name :notifying_test

          action :run do
            notify_group "bar" do
              notifies :write, 'log[foo]', :delayed
              action :run
            end
          end
        EOM

        file "recipes/default.rb", <<~EOM
          log "foo" do
            action :nothing
          end
          notifying_test "whatever"
          notify_group "baz" do
            notifies :write, 'log[foo]', :delayed
            action :run
          end
        EOM

      end
    end

    it "should complete with success" do
      file "config/client.rb", <<~EOM
        local_mode true
        cookbook_path "#{path_to("cookbooks")}"
        log_level :warn
      EOM

      result = shell_out("#{chef_client} -c \"#{path_to("config/client.rb")}\" --no-color -F doc -o 'x::default'", cwd: chef_dir)
      # our delayed notification should run at the end of the parent run_context after the baz resource
      expect(result.stdout).to match(/\* notify_group\[bar\] action run\s+\* notify_group\[baz\] action run\s+\* log\[foo\] action write/)
      # and only run once
      expect(result.stdout).not_to match(/\* log\[foo\] action write.*\* log\[foo\] action write/)
      result.error!
    end
  end

  when_the_repository "notifies delayed three" do
    before do
      directory "cookbooks/x" do

        file "resources/notifying_test.rb", <<~EOM
          default_action :run
          provides :notifying_test
          resource_name :notifying_test

          action :run do
            notify_group "bar" do
              notifies :write, 'log[foo]', :delayed
              action :run
            end
          end
        EOM

        file "recipes/default.rb", <<~EOM
          log "foo" do
            action :nothing
          end
          notify_group "quux" do
            notifies :write, 'log[foo]', :delayed
            notifies :write, 'log[baz]', :delayed
            action :run
          end
          notifying_test "whatever"
          log "baz"
        EOM

      end
    end

    it "should complete with success" do
      file "config/client.rb", <<~EOM
        local_mode true
        cookbook_path "#{path_to("cookbooks")}"
        log_level :warn
      EOM

      result = shell_out("#{chef_client} -c \"#{path_to("config/client.rb")}\" --no-color -F doc -o 'x::default'", cwd: chef_dir)
      # the delayed notification from the sub-resource is de-duplicated by the notification already in the parent run_context
      expect(result.stdout).to match(/\* notify_group\[quux\] action run\s+\* notifying_test\[whatever\] action run\s+\* notify_group\[bar\] action run\s+\* log\[baz\] action write\s+\* log\[foo\] action write\s+\* log\[baz\] action write/)
      # and only run once
      expect(result.stdout).not_to match(/\* log\[foo\] action write.*\* log\[foo\] action write/)
      result.error!
    end
  end

  when_the_repository "notifies delayed four" do
    before do
      directory "cookbooks/x" do
        file "recipes/default.rb", <<~EOM
          log "foo" do
            action :nothing
          end
          notify_group "bar" do
            notifies :write, 'log[foo]', :delayed
            action :run
          end
          notify_group "baz" do
            notifies :write, 'log[foo]', :delayed
            action :run
          end
        EOM

      end
    end

    it "should complete with success" do
      file "config/client.rb", <<~EOM
        local_mode true
        cookbook_path "#{path_to("cookbooks")}"
        log_level :warn
      EOM

      result = shell_out("#{chef_client} -c \"#{path_to("config/client.rb")}\" --no-color -F doc -o 'x::default'", cwd: chef_dir)
      # the delayed notification from the sub-resource is de-duplicated by the notification already in the parent run_context
      expect(result.stdout).to match(/\* notify_group\[bar\] action run\s+\* notify_group\[baz\] action run\s+\* log\[foo\] action write/)
      # and only run once
      expect(result.stdout).not_to match(/\* log\[foo\] action write.*\* log\[foo\] action write/)
      result.error!
    end
  end

  when_the_repository "notifies immediately" do
    before do
      directory "cookbooks/x" do

        file "resources/notifying_test.rb", <<~EOM
          default_action :run
          provides :notifying_test
          resource_name :notifying_test

          action :run do
            notify_group "bar" do
              notifies :write, 'log[foo]', :immediately
              action :run
            end
          end
        EOM

        file "recipes/default.rb", <<~EOM
          log "foo" do
            action :nothing
          end
          notifying_test "whatever"
          log "baz"
        EOM

      end
    end

    it "should complete with success" do
      file "config/client.rb", <<~EOM
        local_mode true
        cookbook_path "#{path_to("cookbooks")}"
        log_level :warn
      EOM

      result = shell_out("#{chef_client} -c \"#{path_to("config/client.rb")}\" --no-color -F doc -o 'x::default'", cwd: chef_dir)
      expect(result.stdout).to match(/\* notify_group\[bar\] action run\s+\* log\[foo\] action write\s+\* log\[baz\] action write/)
      result.error!
    end
  end

  when_the_repository "uses old notifies syntax" do
    before do
      directory "cookbooks/x" do

        file "resources/notifying_test.rb", <<~EOM
          default_action :run
          provides :notifying_test
          resource_name :notifying_test

          action :run do
            notify_group "bar" do
              notifies :write, resources(log: "foo"), :immediately
              action :run
            end
          end
        EOM

        file "recipes/default.rb", <<~EOM
          log "foo" do
            action :nothing
          end
          notifying_test "whatever"
          log "baz"
        EOM

      end
    end

    it "should complete with success" do
      file "config/client.rb", <<~EOM
        local_mode true
        cookbook_path "#{path_to("cookbooks")}"
        log_level :warn
      EOM

      result = shell_out("#{chef_client} -c \"#{path_to("config/client.rb")}\" --no-color -F doc -o 'x::default'", cwd: chef_dir)
      expect(result.stdout).to match(/\* notify_group\[bar\] action run\s+\* log\[foo\] action write\s+\* log\[baz\] action write/)
      result.error!
    end
  end

  when_the_repository "does not have a matching resource" do
    before do
      directory "cookbooks/x" do

        file "resources/notifying_test.rb", <<~EOM
          default_action :run
          provides :notifying_test
          resource_name :notifying_test

          action :run do
            notify_group "bar" do
              notifies :write, "log[foo]"
              action :run
            end
          end
        EOM

        file "recipes/default.rb", <<~EOM
          notifying_test "whatever"
          log "baz"
        EOM

      end
    end

    it "should complete with success" do
      file "config/client.rb", <<~EOM
        local_mode true
        cookbook_path "#{path_to("cookbooks")}"
        log_level :warn
      EOM

      result = shell_out("#{chef_client} -c \"#{path_to("config/client.rb")}\" --no-color -F doc -o 'x::default'", cwd: chef_dir)
      expect(result.stdout).to match(/Chef::Exceptions::ResourceNotFound/)
      expect(result.exitstatus).not_to eql(0)
    end
  end

  when_the_repository "encounters identical resources in parent and child resource collections" do
    before do
      directory "cookbooks/x" do

        file "resources/cloning_test.rb", <<~EOM
          default_action :run
          provides :cloning_test
          resource_name :cloning_test

          action :run do
            log "bar" do
              level :info
            end
          end
        EOM

        file "recipes/default.rb", <<~EOM
          log "bar" do
            level :warn
          end

          cloning_test "whatever"
        EOM

      end
    end

    it "should complete with success" do
      file "config/client.rb", <<~EOM
        local_mode true
        cookbook_path "#{path_to("cookbooks")}"
        log_level :warn
      EOM

      result = shell_out("#{chef_client} -c \"#{path_to("config/client.rb")}\" --no-color -F doc -o 'x::default'", cwd: chef_dir)
      expect(result.stdout).not_to match(/CHEF-3694/)
      result.error!
    end
  end

  when_the_repository "has resources that have arrays as the name" do
    before do
      directory "cookbooks/x" do
        file "recipes/default.rb", <<-EOM
          log [ "a", "b" ] do
            action :nothing
          end

          notify_group "doit" do
            notifies :write, "log[a, b]"
            action :run
          end
        EOM
      end
    end

    it "notifying the resource should work" do
      file "config/client.rb", <<~EOM
        local_mode true
        cookbook_path "#{path_to("cookbooks")}"
        log_level :warn
      EOM

      result = shell_out("#{chef_client} -c \"#{path_to("config/client.rb")}\" --no-color -F doc -o 'x::default'", cwd: chef_dir)
      expect(result.stdout).to match /\* log\[a, b\] action write/
      result.error!
    end

  end
end