require "support/shared/integration/integration_helper" require "chef/mixin/shell_out" require "tiny_server" require "tmpdir" require "chef/platform" describe "chef-client" do include IntegrationSupport include Chef::Mixin::ShellOut let(:chef_dir) { File.join(File.dirname(__FILE__), "..", "..", "..", "bin") } # Invoke `chef-client` as `ruby PATH/TO/chef-client`. This ensures the # following constraints are satisfied: # * Windows: windows can only run batch scripts as bare executables. Rubygems # creates batch wrappers for installed gems, but we don't have batch wrappers # in the source tree. # * Other `chef-client` in PATH: A common case is running the tests on a # machine that has omnibus chef installed. In that case we need to ensure # we're running `chef-client` from the source tree and not the external one. # cf. CHEF-4914 let(:chef_client) { "ruby '#{chef_dir}/chef-client' --no-fork --minimal-ohai" } let(:critical_env_vars) { %w{PATH RUBYOPT BUNDLE_GEMFILE GEM_PATH}.map { |o| "#{o}=#{ENV[o]}" } .join(" ") } when_the_repository "uses RFC 062 defined exit codes" do def setup_client_rb file "config/client.rb", < chef_dir, :returns => [exit_code]) end context "has a cookbook" do context "with a library" do context "which cannot be loaded" do before do file "cookbooks/x/recipes/default.rb", "" file "cookbooks/x/libraries/error.rb", "require 'does/not/exist'" end it "exits with GENERIC_FAILURE, 1" do setup_client_rb run_chef_client_and_expect_exit_code 1 end end end context "with an audit recipe" do context "which fails" do before do file "cookbooks/x/recipes/default.rb", <<-RECIPE control_group "control group without top level control" do it "should fail" do expect(4 - 4).to eq(1) end end RECIPE end it "exits with AUDIT_MODE_FAILURE, 42" do setup_client_rb_with_audit_mode run_chef_client_and_expect_exit_code 42 end end end context "with a recipe" do context "which throws an error" do before { file "cookbooks/x/recipes/default.rb", "raise 'BOOM'" } it "exits with GENERIC_FAILURE, 1" do setup_client_rb run_chef_client_and_expect_exit_code 1 end end context "with a recipe which calls Chef::Application.fatal with a non-RFC exit code" do before { file "cookbooks/x/recipes/default.rb", "Chef::Application.fatal!('BOOM', 123)" } it "exits with the GENERIC_FAILURE exit code, 1" do setup_client_rb run_chef_client_and_expect_exit_code 1 end end context "with a recipe which calls Chef::Application.exit with a non-RFC exit code" do before { file "cookbooks/x/recipes/default.rb", "Chef::Application.exit!('BOOM', 231)" } it "exits with the GENERIC_FAILURE exit code, 1" do setup_client_rb run_chef_client_and_expect_exit_code 1 end end context "when a reboot exception is raised (like from the reboot resource)" do before do file "cookbooks/x/recipes/default.rb", <