diff options
Diffstat (limited to 'spec/unit')
-rw-r--r-- | spec/unit/application/apply_spec.rb | 10 | ||||
-rw-r--r-- | spec/unit/application/exit_code_spec.rb | 231 | ||||
-rw-r--r-- | spec/unit/application/solo_spec.rb | 210 | ||||
-rw-r--r-- | spec/unit/client_spec.rb | 2 | ||||
-rw-r--r-- | spec/unit/config_fetcher_spec.rb | 4 | ||||
-rw-r--r-- | spec/unit/cookbook/synchronizer_spec.rb | 2 | ||||
-rw-r--r-- | spec/unit/data_bag_item_spec.rb | 4 | ||||
-rw-r--r-- | spec/unit/data_bag_spec.rb | 4 | ||||
-rw-r--r-- | spec/unit/environment_spec.rb | 8 | ||||
-rw-r--r-- | spec/unit/handler_spec.rb | 87 | ||||
-rw-r--r-- | spec/unit/knife/cookbook_show_spec.rb | 179 | ||||
-rw-r--r-- | spec/unit/policy_builder/dynamic_spec.rb | 2 | ||||
-rw-r--r-- | spec/unit/policy_builder/policyfile_spec.rb | 2 | ||||
-rw-r--r-- | spec/unit/provider/git_spec.rb | 36 | ||||
-rw-r--r-- | spec/unit/provider/package/chocolatey_spec.rb | 16 | ||||
-rw-r--r-- | spec/unit/provider/package/portage_spec.rb | 6 | ||||
-rw-r--r-- | spec/unit/provider/package/yum/yum_cache_spec.rb | 27 | ||||
-rw-r--r-- | spec/unit/provider/systemd_unit_spec.rb | 27 |
18 files changed, 643 insertions, 214 deletions
diff --git a/spec/unit/application/apply_spec.rb b/spec/unit/application/apply_spec.rb index d223d55d2b..0af3916134 100644 --- a/spec/unit/application/apply_spec.rb +++ b/spec/unit/application/apply_spec.rb @@ -24,13 +24,13 @@ describe Chef::Application::Apply do allow(@app).to receive(:configure_logging).and_return(true) allow(Chef::Log).to receive(:debug).with("FIPS mode is enabled.") @recipe_text = "package 'nyancat'" - Chef::Config[:solo] = true + Chef::Config[:solo_legacy_mode] = true end describe "configuring the application" do it "should set solo mode to true" do @app.reconfigure - expect(Chef::Config[:solo]).to be_truthy + expect(Chef::Config[:solo_legacy_mode]).to be_truthy end end describe "read_recipe_file" do @@ -52,7 +52,8 @@ describe Chef::Application::Apply do describe "when recipe is nil" do it "should raise a fatal with the missing filename message" do - expect(Chef::Application).to receive(:fatal!).with("No recipe file was provided", 1) + expect(Chef::Application).to receive(:fatal!).with("No recipe file was provided", + Chef::Exceptions::RecipeNotFound.new) @app.read_recipe_file(nil) end end @@ -61,7 +62,8 @@ describe Chef::Application::Apply do allow(File).to receive(:exist?).with(@recipe_path).and_return(false) end it "should raise a fatal with the file doesn't exist message" do - expect(Chef::Application).to receive(:fatal!).with(/^No file exists at/, 1) + expect(Chef::Application).to receive(:fatal!).with(/^No file exists at/, + Chef::Exceptions::RecipeNotFound.new) @app.read_recipe_file(@recipe_file_name) end end diff --git a/spec/unit/application/exit_code_spec.rb b/spec/unit/application/exit_code_spec.rb new file mode 100644 index 0000000000..73a113e554 --- /dev/null +++ b/spec/unit/application/exit_code_spec.rb @@ -0,0 +1,231 @@ +# +# Author:: Steven Murawski (<smurawski@chef.io>) +# Copyright:: Copyright 2016, 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 "chef" +require "spec_helper" + +require "chef/application/exit_code" + +describe Chef::Application::ExitCode do + + let(:exit_codes) { Chef::Application::ExitCode } + + let(:valid_rfc_exit_codes) { Chef::Application::ExitCode::VALID_RFC_062_EXIT_CODES.values } + + context "Validates the return codes from RFC 062" do + + before do + allow(Chef::Config).to receive(:[]).with(:exit_status).and_return(:enabled) + end + + it "validates a SUCCESS return code of 0" do + expect(valid_rfc_exit_codes.include?(0)).to eq(true) + end + + it "validates a GENERIC_FAILURE return code of 1" do + expect(valid_rfc_exit_codes.include?(1)).to eq(true) + end + + it "validates a SIGINT_RECEIVED return code of 2" do + expect(valid_rfc_exit_codes.include?(2)).to eq(true) + end + + it "validates a SIGTERM_RECEIVED return code of 3" do + expect(valid_rfc_exit_codes.include?(3)).to eq(true) + end + + it "validates a AUDIT_MODE_FAILURE return code of 42" do + expect(valid_rfc_exit_codes.include?(42)).to eq(true) + end + + it "validates a REBOOT_SCHEDULED return code of 35" do + expect(valid_rfc_exit_codes.include?(35)).to eq(true) + end + + it "validates a REBOOT_NEEDED return code of 37" do + expect(valid_rfc_exit_codes.include?(37)).to eq(true) + end + + it "validates a REBOOT_FAILED return code of 41" do + expect(valid_rfc_exit_codes.include?(41)).to eq(true) + end + end + + context "when Chef::Config :exit_status is not configured" do + before do + allow(Chef::Config).to receive(:[]).with(:exit_status).and_return(nil) + allow(Chef::Config).to receive(:[]).with(:treat_deprecation_warnings_as_errors).and_return(false) + end + + it "writes a deprecation warning" do + warn = "Chef RFC 062 (https://github.com/chef/chef-rfc/master/rfc062-exit-status.md) defines the" \ + " exit codes that should be used with Chef. Chef::Application::ExitCode defines valid exit codes" \ + " In a future release, non-standard exit codes will be redefined as" \ + " GENERIC_FAILURE unless `exit_status` is set to `:disabled` in your client.rb." + expect(Chef).to receive(:log_deprecation).with(warn) + expect(exit_codes.normalize_exit_code(151)).to eq(151) + end + + it "does not modify non-RFC exit codes" do + expect(exit_codes.normalize_exit_code(151)).to eq(151) + end + + it "returns DEPRECATED_FAILURE when no exit code is specified" do + expect(exit_codes.normalize_exit_code()).to eq(-1) + end + + it "returns SIGINT_RECEIVED when a SIGINT is received" do + expect(exit_codes.normalize_exit_code(Chef::Exceptions::SigInt.new("BOOM"))).to eq(2) + end + + it "returns SIGTERM_RECEIVED when a SIGTERM is received" do + expect(exit_codes.normalize_exit_code(Chef::Exceptions::SigTerm.new("BOOM"))).to eq(3) + end + + it "returns SIGINT_RECEIVED when a deprecated exit code error is received" do + expect(exit_codes.normalize_exit_code(Chef::Exceptions::DeprecatedExitCode.new("BOOM"))).to eq(2) + end + + it "returns GENERIC_FAILURE when an exception is specified" do + expect(exit_codes.normalize_exit_code(Exception.new("BOOM"))).to eq(1) + end + + end + + context "when Chef::Config :exit_status is configured to not validate exit codes" do + before do + allow(Chef::Config).to receive(:[]).with(:exit_status).and_return(:disabled) + allow(Chef::Config).to receive(:[]).with(:treat_deprecation_warnings_as_errors).and_return(false) + end + + it "does not write a deprecation warning" do + warn = "Chef RFC 062 (https://github.com/chef/chef-rfc/master/rfc062-exit-status.md) defines the" \ + " exit codes that should be used with Chef. Chef::Application::ExitCode defines valid exit codes" \ + " In a future release, non-standard exit codes will be redefined as" \ + " GENERIC_FAILURE unless `exit_status` is set to `:disabled` in your client.rb." + expect(Chef).not_to receive(:log_deprecation).with(warn) + expect(exit_codes.normalize_exit_code(151)).to eq(151) + end + + it "does not modify non-RFC exit codes" do + expect(exit_codes.normalize_exit_code(151)).to eq(151) + end + + it "returns DEPRECATED_FAILURE when no exit code is specified" do + expect(exit_codes.normalize_exit_code()).to eq(-1) + end + + it "returns GENERIC_FAILURE when an exception is specified" do + expect(exit_codes.normalize_exit_code(Exception.new("BOOM"))).to eq(1) + end + + it "returns SUCCESS when a reboot is pending" do + allow(Chef::DSL::RebootPending).to receive(:reboot_pending?).and_return(true) + expect(exit_codes.normalize_exit_code(0)).to eq(0) + end + + it "returns SIGINT_RECEIVED when a SIGINT is received" do + expect(exit_codes.normalize_exit_code(Chef::Exceptions::SigInt.new("BOOM"))).to eq(2) + end + + it "returns SIGTERM_RECEIVED when a SIGTERM is received" do + expect(exit_codes.normalize_exit_code(Chef::Exceptions::SigTerm.new("BOOM"))).to eq(3) + end + + it "returns SIGINT_RECEIVED when a deprecated exit code error is received" do + expect(exit_codes.normalize_exit_code(Chef::Exceptions::DeprecatedExitCode.new("BOOM"))).to eq(2) + end + end + + context "when Chef::Config :exit_status is configured to validate exit codes" do + before do + allow(Chef::Config).to receive(:[]).with(:exit_status).and_return(:enabled) + allow(Chef::Config).to receive(:[]).with(:treat_deprecation_warnings_as_errors).and_return(false) + end + + it "does write a deprecation warning" do + warn = "Chef RFC 062 (https://github.com/chef/chef-rfc/master/rfc062-exit-status.md) defines the" \ + " exit codes that should be used with Chef. Chef::Application::ExitCode defines valid exit codes" \ + " In a future release, non-standard exit codes will be redefined as" \ + " GENERIC_FAILURE unless `exit_status` is set to `:disabled` in your client.rb." + expect(Chef).to receive(:log_deprecation).with(warn) + expect(exit_codes.normalize_exit_code(151)).to eq(1) + end + + it "returns a GENERIC_FAILURE for non-RFC exit codes" do + expect(exit_codes.normalize_exit_code(151)).to eq(1) + end + + it "returns GENERIC_FAILURE when no exit code is specified" do + expect(exit_codes.normalize_exit_code()).to eq(1) + end + + it "returns SIGINT_RECEIVED when a SIGINT is received" do + expect(exit_codes.normalize_exit_code(Chef::Exceptions::SigInt.new("BOOM"))).to eq(2) + end + + it "returns SIGTERM_RECEIVED when a SIGTERM is received" do + expect(exit_codes.normalize_exit_code(Chef::Exceptions::SigTerm.new("BOOM"))).to eq(3) + end + + it "returns GENERIC_FAILURE when a deprecated exit code error is received" do + expect(exit_codes.normalize_exit_code(Chef::Exceptions::DeprecatedExitCode.new("BOOM"))).to eq(1) + end + + it "returns GENERIC_FAILURE when an exception is specified" do + expect(exit_codes.normalize_exit_code(Exception.new("BOOM"))).to eq(1) + end + + it "returns AUDIT_MODE_FAILURE when there is an audit error" do + audit_error = Chef::Exceptions::AuditError.new("BOOM") + runtime_error = Chef::Exceptions::RunFailedWrappingError.new(audit_error) + expect(exit_codes.normalize_exit_code(runtime_error)).to eq(42) + end + + it "returns REBOOT_SCHEDULED when there is an reboot requested" do + reboot_error = Chef::Exceptions::Reboot.new("BOOM") + runtime_error = Chef::Exceptions::RunFailedWrappingError.new(reboot_error) + expect(exit_codes.normalize_exit_code(runtime_error)).to eq(35) + end + + it "returns REBOOT_FAILED when the reboot command fails" do + reboot_error = Chef::Exceptions::RebootFailed.new("BOOM") + runtime_error = Chef::Exceptions::RunFailedWrappingError.new(reboot_error) + expect(exit_codes.normalize_exit_code(runtime_error)).to eq(41) + end + + it "returns REBOOT_NEEDED when a reboot is pending" do + reboot_error = Chef::Exceptions::RebootPending.new("BOOM") + runtime_error = Chef::Exceptions::RunFailedWrappingError.new(reboot_error) + expect(exit_codes.normalize_exit_code(runtime_error)).to eq(37) + end + + it "returns SIGINT_RECEIVED when a SIGINT is received." do + sigint_error = Chef::Exceptions::SigInt.new("BOOM") + runtime_error = Chef::Exceptions::RunFailedWrappingError.new(sigint_error) + expect(exit_codes.normalize_exit_code(runtime_error)).to eq(2) + end + + it "returns SIGTERM_RECEIVED when a SIGTERM is received." do + sigterm_error = Chef::Exceptions::SigTerm.new("BOOM") + runtime_error = Chef::Exceptions::RunFailedWrappingError.new(sigterm_error) + expect(exit_codes.normalize_exit_code(runtime_error)).to eq(3) + end + end + +end diff --git a/spec/unit/application/solo_spec.rb b/spec/unit/application/solo_spec.rb index 85799d73db..1c8ec2e11c 100644 --- a/spec/unit/application/solo_spec.rb +++ b/spec/unit/application/solo_spec.rb @@ -30,141 +30,171 @@ describe Chef::Application::Solo do Chef::Config[:json_attribs] = false Chef::Config[:solo] = true + Chef::Config[:solo_legacy_mode] = true # protect the unit tests against accidental --delete-entire-chef-repo from firing # for real during tests. DO NOT delete this line. expect(FileUtils).not_to receive(:rm_rf) end - describe "configuring the application" do - it "should call set_specific_recipes" do - expect(app).to receive(:set_specific_recipes) - app.reconfigure - end - - it "should set solo mode to true" do - app.reconfigure - expect(Chef::Config[:solo]).to be_truthy - end + context "in legacy mode" do + describe "configuring the application" do + it "should call set_specific_recipes" do + expect(app).to receive(:set_specific_recipes) + app.reconfigure + end - it "should set audit-mode to :disabled" do - app.reconfigure - expect(Chef::Config[:audit_mode]).to be :disabled - end + it "should set solo mode to true" do + app.reconfigure + expect(Chef::Config[:solo]).to be_truthy + end - describe "when configured to not fork the client process" do - before do - Chef::Config[:client_fork] = false - Chef::Config[:daemonize] = false - Chef::Config[:interval] = nil - Chef::Config[:splay] = nil + it "should set audit-mode to :disabled" do + app.reconfigure + expect(Chef::Config[:audit_mode]).to be :disabled end - context "when interval is given" do + describe "when configured to not fork the client process" do before do - Chef::Config[:interval] = 600 + Chef::Config[:client_fork] = false + Chef::Config[:daemonize] = false + Chef::Config[:interval] = nil + Chef::Config[:splay] = nil end - it "should terminate with message" do - expect(Chef::Application).to receive(:fatal!).with( -"Unforked chef-client interval runs are disabled in Chef 12. + context "when interval is given" do + before do + Chef::Config[:interval] = 600 + end + + it "should terminate with message" do + expect(Chef::Application).to receive(:fatal!).with( + "Unforked chef-client interval runs are disabled in Chef 12. Configuration settings: interval = 600 seconds Enable chef-client interval runs by setting `:client_fork = true` in your config file or adding `--fork` to your command line options." - ) - app.reconfigure + ) + app.reconfigure + end end end - end - describe "when in daemonized mode and no interval has been set" do - before do - Chef::Config[:daemonize] = true - end + describe "when in daemonized mode and no interval has been set" do + before do + Chef::Config[:daemonize] = true + end - it "should set the interval to 1800" do - Chef::Config[:interval] = nil - app.reconfigure - expect(Chef::Config[:interval]).to eq(1800) + it "should set the interval to 1800" do + Chef::Config[:interval] = nil + app.reconfigure + expect(Chef::Config[:interval]).to eq(1800) + end end - end - describe "when the json_attribs configuration option is specified" do - let(:json_attribs) { { "a" => "b" } } - let(:config_fetcher) { double(Chef::ConfigFetcher, :fetch_json => json_attribs) } - let(:json_source) { "https://foo.com/foo.json" } + describe "when the json_attribs configuration option is specified" do + let(:json_attribs) { { "a" => "b" } } + let(:config_fetcher) { double(Chef::ConfigFetcher, :fetch_json => json_attribs) } + let(:json_source) { "https://foo.com/foo.json" } - before do - Chef::Config[:json_attribs] = json_source - expect(Chef::ConfigFetcher).to receive(:new).with(json_source). - and_return(config_fetcher) + before do + Chef::Config[:json_attribs] = json_source + expect(Chef::ConfigFetcher).to receive(:new).with(json_source). + and_return(config_fetcher) + end + + it "reads the JSON attributes from the specified source" do + app.reconfigure + expect(app.chef_client_json).to eq(json_attribs) + end end - it "reads the JSON attributes from the specified source" do + it "downloads a tarball when the recipe_url configuration option is specified" do + Chef::Config[:cookbook_path] = "#{Dir.tmpdir}/chef-solo/cookbooks" + Chef::Config[:recipe_url] = "http://junglist.gen.nz/recipes.tgz" + + expect(FileUtils).to receive(:mkdir_p).with("#{Dir.tmpdir}/chef-solo").and_return(true) + + tarfile = StringIO.new("remote_tarball_content") + target_file = StringIO.new + + expect(app).to receive(:open).with("http://junglist.gen.nz/recipes.tgz").and_yield(tarfile) + expect(File).to receive(:open).with("#{Dir.tmpdir}/chef-solo/recipes.tgz", "wb").and_yield(target_file) + + shellout = instance_double("Mixlib::ShellOut", run_command: nil, error!: nil, stdout: "") + + expect(app).to receive(:shell_out!).with("tar zxvf #{Dir.tmpdir}/chef-solo/recipes.tgz -C #{Dir.tmpdir}/chef-solo").and_return(shellout) app.reconfigure - expect(app.chef_client_json).to eq(json_attribs) + expect(target_file.string).to eq("remote_tarball_content") end - end - - it "downloads a tarball when the recipe_url configuration option is specified" do - Chef::Config[:cookbook_path] = "#{Dir.tmpdir}/chef-solo/cookbooks" - Chef::Config[:recipe_url] = "http://junglist.gen.nz/recipes.tgz" - expect(FileUtils).to receive(:mkdir_p).with("#{Dir.tmpdir}/chef-solo").and_return(true) + it "fetches the recipe_url first when both json_attribs and recipe_url are specified" do + json_attribs = { "a" => "b" } + config_fetcher = instance_double("Chef::ConfigFetcher", :fetch_json => json_attribs) - tarfile = StringIO.new("remote_tarball_content") - target_file = StringIO.new + Chef::Config[:json_attribs] = "https://foo.com/foo.json" + Chef::Config[:recipe_url] = "http://icanhas.cheezburger.com/lolcats" + Chef::Config[:cookbook_path] = "#{Dir.tmpdir}/chef-solo/cookbooks" + expect(FileUtils).to receive(:mkdir_p).with("#{Dir.tmpdir}/chef-solo").and_return(true) - expect(app).to receive(:open).with("http://junglist.gen.nz/recipes.tgz").and_yield(tarfile) - expect(File).to receive(:open).with("#{Dir.tmpdir}/chef-solo/recipes.tgz", "wb").and_yield(target_file) + allow(Chef::Mixin::Command).to receive(:run_command).and_return(true) - shellout = instance_double("Mixlib::ShellOut", run_command: nil, error!: nil, stdout: "") + shellout = instance_double("Mixlib::ShellOut", run_command: nil, error!: nil, stdout: "") - expect(app).to receive(:shell_out!).with("tar zxvf #{Dir.tmpdir}/chef-solo/recipes.tgz -C #{Dir.tmpdir}/chef-solo").and_return(shellout) - app.reconfigure - expect(target_file.string).to eq("remote_tarball_content") + expect(app).to receive(:shell_out!).with("tar zxvf #{Dir.tmpdir}/chef-solo/recipes.tgz -C #{Dir.tmpdir}/chef-solo").and_return(shellout) + expect(app).to receive(:fetch_recipe_tarball).ordered + expect(Chef::ConfigFetcher).to receive(:new).ordered.and_return(config_fetcher) + app.reconfigure + end end - it "fetches the recipe_url first when both json_attribs and recipe_url are specified" do - json_attribs = { "a" => "b" } - config_fetcher = instance_double("Chef::ConfigFetcher", :fetch_json => json_attribs) + describe "after the application has been configured" do + before do + Chef::Config[:solo] = true + Chef::Config[:solo_legacy_mode] = true + + allow(Chef::Daemon).to receive(:change_privilege) + chef_client = double("Chef::Client") + allow(Chef::Client).to receive(:new).and_return(chef_client) + # this is all stuff the reconfigure method needs + allow(app).to receive(:configure_opt_parser).and_return(true) + allow(app).to receive(:configure_chef).and_return(true) + allow(app).to receive(:configure_logging).and_return(true) + end - Chef::Config[:json_attribs] = "https://foo.com/foo.json" - Chef::Config[:recipe_url] = "http://icanhas.cheezburger.com/lolcats" - Chef::Config[:cookbook_path] = "#{Dir.tmpdir}/chef-solo/cookbooks" - expect(FileUtils).to receive(:mkdir_p).with("#{Dir.tmpdir}/chef-solo").and_return(true) + it "should change privileges" do + expect(Chef::Daemon).to receive(:change_privilege).and_return(true) + app.setup_application + end + end - allow(Chef::Mixin::Command).to receive(:run_command).and_return(true) + it_behaves_like "an application that loads a dot d" do + let(:dot_d_config_name) { :solo_d_dir } + end + end - shellout = instance_double("Mixlib::ShellOut", run_command: nil, error!: nil, stdout: "") + context "in local mode" do + before do + Chef::Config[:solo_legacy_mode] = false + end - expect(app).to receive(:shell_out!).with("tar zxvf #{Dir.tmpdir}/chef-solo/recipes.tgz -C #{Dir.tmpdir}/chef-solo").and_return(shellout) - expect(app).to receive(:fetch_recipe_tarball).ordered - expect(Chef::ConfigFetcher).to receive(:new).ordered.and_return(config_fetcher) + it "sets solo mode to true" do app.reconfigure + expect(Chef::Config[:solo]).to be_truthy end - end - describe "after the application has been configured" do - before do - Chef::Config[:solo] = true + it "sets local mode to true" do + app.reconfigure + expect(Chef::Config[:local_mode]).to be_truthy + end - allow(Chef::Daemon).to receive(:change_privilege) - chef_client = double("Chef::Client") - allow(Chef::Client).to receive(:new).and_return(chef_client) - # this is all stuff the reconfigure method needs - allow(app).to receive(:configure_opt_parser).and_return(true) + it "runs chef-client in local mode" do + allow(app).to receive(:setup_application).and_return(true) + allow(app).to receive(:run_application).and_return(true) allow(app).to receive(:configure_chef).and_return(true) allow(app).to receive(:configure_logging).and_return(true) + expect(Chef::Application::Client).to receive_message_chain(:new, :run) + app.run end - it "should change privileges" do - expect(Chef::Daemon).to receive(:change_privilege).and_return(true) - app.setup_application - end - end - - it_behaves_like "an application that loads a dot d" do - let(:dot_d_config_name) { :solo_d_dir } end end diff --git a/spec/unit/client_spec.rb b/spec/unit/client_spec.rb index fe9b1afe01..ec3f70b9b0 100644 --- a/spec/unit/client_spec.rb +++ b/spec/unit/client_spec.rb @@ -462,7 +462,7 @@ describe Chef::Client do describe "assert_cookbook_path_not_empty" do before do - Chef::Config[:solo] = true + Chef::Config[:solo_legacy_mode] = true Chef::Config[:cookbook_path] = ["/path/to/invalid/cookbook_path"] end diff --git a/spec/unit/config_fetcher_spec.rb b/spec/unit/config_fetcher_spec.rb index 35cf27f2af..6847ee5fd3 100644 --- a/spec/unit/config_fetcher_spec.rb +++ b/spec/unit/config_fetcher_spec.rb @@ -58,7 +58,7 @@ describe Chef::ConfigFetcher do and_return(invalid_json) expect(Chef::Application).to receive(:fatal!). - with(invalid_json_error_regex, 2) + with(invalid_json_error_regex, Chef::Exceptions::DeprecatedExitCode.new) fetcher.fetch_json end end @@ -104,7 +104,7 @@ describe Chef::ConfigFetcher do with("").and_return(invalid_json) expect(Chef::Application).to receive(:fatal!). - with(invalid_json_error_regex, 2) + with(invalid_json_error_regex, Chef::Exceptions::DeprecatedExitCode.new) fetcher.fetch_json end end diff --git a/spec/unit/cookbook/synchronizer_spec.rb b/spec/unit/cookbook/synchronizer_spec.rb index 97e7569cf4..3f5624f3b0 100644 --- a/spec/unit/cookbook/synchronizer_spec.rb +++ b/spec/unit/cookbook/synchronizer_spec.rb @@ -50,7 +50,7 @@ describe Chef::CookbookCacheCleaner do end it "does not remove anything on chef-solo" do - Chef::Config[:solo] = true + Chef::Config[:solo_legacy_mode] = true allow(cleaner.cache).to receive(:find).and_return(%w{cookbooks/valid1/recipes/default.rb cookbooks/valid2/recipes/default.rb}) expect(cleaner.cache).not_to receive(:delete) cleaner.cleanup_file_cache diff --git a/spec/unit/data_bag_item_spec.rb b/spec/unit/data_bag_item_spec.rb index 99bf89e583..2711fcae03 100644 --- a/spec/unit/data_bag_item_spec.rb +++ b/spec/unit/data_bag_item_spec.rb @@ -365,11 +365,11 @@ describe Chef::DataBagItem do describe "in solo mode" do before do - Chef::Config[:solo] = true + Chef::Config[:solo_legacy_mode] = true end after do - Chef::Config[:solo] = false + Chef::Config[:solo_legacy_mode] = false end it "converts the raw data to a data bag item" do diff --git a/spec/unit/data_bag_spec.rb b/spec/unit/data_bag_spec.rb index 92da4cade1..84aa724927 100644 --- a/spec/unit/data_bag_spec.rb +++ b/spec/unit/data_bag_spec.rb @@ -143,13 +143,13 @@ describe Chef::DataBag do shared_examples_for "data bag in solo mode" do |data_bag_path| before do - Chef::Config[:solo] = true + Chef::Config[:solo_legacy_mode] = true Chef::Config[:data_bag_path] = data_bag_path @paths = Array(data_bag_path) end after do - Chef::Config[:solo] = false + Chef::Config[:solo_legacy_mode] = false end it "should get the data bag from the data_bag_path" do diff --git a/spec/unit/environment_spec.rb b/spec/unit/environment_spec.rb index 4689c60b39..5557b5dc11 100644 --- a/spec/unit/environment_spec.rb +++ b/spec/unit/environment_spec.rb @@ -288,11 +288,11 @@ describe Chef::Environment do describe "in solo mode" do before do - Chef::Config[:solo] = true + Chef::Config[:solo_legacy_mode] = true end after do - Chef::Config[:solo] = false + Chef::Config[:solo_legacy_mode] = false end it "should raise and exception" do @@ -392,12 +392,12 @@ describe Chef::Environment do describe "when loading" do describe "in solo mode" do before do - Chef::Config[:solo] = true + Chef::Config[:solo_legacy_mode] = true Chef::Config[:environment_path] = "/var/chef/environments" end after do - Chef::Config[:solo] = false + Chef::Config[:solo_legacy_mode] = false end it "should get the environment from the environment_path" do diff --git a/spec/unit/handler_spec.rb b/spec/unit/handler_spec.rb index 65c3ddc4cb..a56645fa78 100644 --- a/spec/unit/handler_spec.rb +++ b/spec/unit/handler_spec.rb @@ -212,4 +212,91 @@ describe Chef::Handler do end end + describe "library report handler" do + before do + # we need to lazily declare this after we have reset Chef::Config in the default rspec before handler + class MyTestHandler < Chef::Handler + handler_for :report, :exception, :start + + class << self + attr_accessor :ran_report + end + + def report + self.class.ran_report = true + end + end + end + + it "gets added to Chef::Config[:report_handlers]" do + expect(Chef::Config[:report_handlers].include?(MyTestHandler)).to be true + end + + it "gets added to Chef::Config[:exception_handlers]" do + expect(Chef::Config[:exception_handlers].include?(MyTestHandler)).to be true + end + + it "gets added to Chef::Config[:start_handlers]" do + expect(Chef::Config[:start_handlers].include?(MyTestHandler)).to be true + end + + it "runs the report handler" do + Chef::Handler.run_report_handlers(@run_status) + expect(MyTestHandler.ran_report).to be true + end + + it "runs the exception handler" do + Chef::Handler.run_exception_handlers(@run_status) + expect(MyTestHandler.ran_report).to be true + end + + it "runs the start handler" do + Chef::Handler.run_start_handlers(@run_status) + expect(MyTestHandler.ran_report).to be true + end + end + + describe "library singleton report handler" do + before do + # we need to lazily declare this after we have reset Chef::Config in the default rspec before handler + class MyTestHandler < Chef::Handler + handler_for :report, :exception, :start + + include Singleton + + attr_accessor :ran_report + + def report + self.ran_report = true + end + end + end + + it "gets added to Chef::Config[:report_handlers]" do + expect(Chef::Config[:report_handlers].include?(MyTestHandler)).to be true + end + + it "gets added to Chef::Config[:exception_handlers]" do + expect(Chef::Config[:exception_handlers].include?(MyTestHandler)).to be true + end + + it "gets added to Chef::Config[:start_handlers]" do + expect(Chef::Config[:start_handlers].include?(MyTestHandler)).to be true + end + + it "runs the report handler" do + Chef::Handler.run_report_handlers(@run_status) + expect(MyTestHandler.instance.ran_report).to be true + end + + it "runs the exception handler" do + Chef::Handler.run_exception_handlers(@run_status) + expect(MyTestHandler.instance.ran_report).to be true + end + + it "runs the start handler" do + Chef::Handler.run_start_handlers(@run_status) + expect(MyTestHandler.instance.ran_report).to be true + end + end end diff --git a/spec/unit/knife/cookbook_show_spec.rb b/spec/unit/knife/cookbook_show_spec.rb index eeb7fef272..749e50c647 100644 --- a/spec/unit/knife/cookbook_show_spec.rb +++ b/spec/unit/knife/cookbook_show_spec.rb @@ -20,30 +20,57 @@ require "spec_helper" describe Chef::Knife::CookbookShow do - before(:each) do + before do Chef::Config[:node_name] = "webmonkey.example.com" - @knife = Chef::Knife::CookbookShow.new - @knife.config = {} - @knife.name_args = [ "cookbook_name" ] - @rest = double(Chef::ServerAPI) - allow(@knife).to receive(:rest).and_return(@rest) - allow(@knife).to receive(:pretty_print).and_return(true) - allow(@knife).to receive(:output).and_return(true) + allow(knife).to receive(:rest).and_return(rest) + allow(knife).to receive(:pretty_print).and_return(true) + allow(knife).to receive(:output).and_return(true) + allow(Chef::CookbookVersion).to receive(:load).and_return(cb) + end + + let (:knife) do + knife = Chef::Knife::CookbookShow.new + knife.config = {} + knife.name_args = [ "cookbook_name" ] + knife + end + + let (:cb) do + cb = Chef::CookbookVersion.new("cookbook_name") + cb.manifest = manifest + cb + end + + let (:rest) { double(Chef::ServerAPI) } + + let (:content) { "Example recipe text" } + + let (:manifest) do + { + "recipes" => [ + { + :name => "default.rb", + :path => "recipes/default.rb", + :checksum => "1234", + :url => "http://example.org/files/default.rb", + }, + ], + } end describe "run" do describe "with 0 arguments: help" do it "should should print usage and exit when given no arguments" do - @knife.name_args = [] - expect(@knife).to receive(:show_usage) - expect(@knife.ui).to receive(:fatal) - expect { @knife.run }.to raise_error(SystemExit) + knife.name_args = [] + expect(knife).to receive(:show_usage) + expect(knife.ui).to receive(:fatal) + expect { knife.run }.to raise_error(SystemExit) end end describe "with 1 argument: versions" do - before(:each) do - @response = { + let (:response) do + { "cookbook_name" => { "url" => "http://url/cookbooks/cookbook_name", "versions" => [ @@ -56,87 +83,60 @@ describe Chef::Knife::CookbookShow do end it "should show the raw cookbook data" do - expect(@rest).to receive(:get).with("cookbooks/cookbook_name").and_return(@response) - expect(@knife).to receive(:format_cookbook_list_for_display).with(@response) - @knife.run + expect(rest).to receive(:get).with("cookbooks/cookbook_name").and_return(response) + expect(knife).to receive(:format_cookbook_list_for_display).with(response) + knife.run end it "should respect the user-supplied environment" do - @knife.config[:environment] = "foo" - expect(@rest).to receive(:get).with("environments/foo/cookbooks/cookbook_name").and_return(@response) - expect(@knife).to receive(:format_cookbook_list_for_display).with(@response) - @knife.run + knife.config[:environment] = "foo" + expect(rest).to receive(:get).with("environments/foo/cookbooks/cookbook_name").and_return(response) + expect(knife).to receive(:format_cookbook_list_for_display).with(response) + knife.run end end describe "with 2 arguments: name and version" do - before(:each) do - @knife.name_args << "0.1.0" - @response = { "0.1.0" => { "recipes" => { "default.rb" => "" } } } + before do + knife.name_args << "0.1.0" end it "should show the specific part of a cookbook" do - expect(@rest).to receive(:get).with("cookbooks/cookbook_name/0.1.0").and_return(@response) - expect(@knife).to receive(:output).with(@response) - @knife.run + expect(Chef::CookbookVersion).to receive(:load).with("cookbook_name", "0.1.0").and_return(cb) + expect(knife).to receive(:output).with(cb) + knife.run end end describe "with 3 arguments: name, version, and segment" do before(:each) do - @knife.name_args = [ "cookbook_name", "0.1.0", "recipes" ] - @cookbook_response = Chef::CookbookVersion.new("cookbook_name") - @manifest = { - "recipes" => [ - { - :name => "default.rb", - :path => "recipes/default.rb", - :checksum => "1234", - :url => "http://example.org/files/default.rb", - }, - ], - } - @cookbook_response.manifest = @manifest - @response = { "name" => "default.rb", "url" => "http://example.org/files/default.rb", "checksum" => "1234", "path" => "recipes/default.rb" } + knife.name_args = [ "cookbook_name", "0.1.0", "recipes" ] end it "should print the json of the part" do - expect(@rest).to receive(:get).with("cookbooks/cookbook_name/0.1.0").and_return(@cookbook_response) - expect(@knife).to receive(:output).with(@cookbook_response.manifest["recipes"]) - @knife.run + expect(Chef::CookbookVersion).to receive(:load).with("cookbook_name", "0.1.0").and_return(cb) + expect(knife).to receive(:output).with(cb.manifest["recipes"]) + knife.run end end describe "with 4 arguments: name, version, segment and filename" do before(:each) do - @knife.name_args = [ "cookbook_name", "0.1.0", "recipes", "default.rb" ] - @cookbook_response = Chef::CookbookVersion.new("cookbook_name") - @cookbook_response.manifest = { - "recipes" => [ - { - :name => "default.rb", - :path => "recipes/default.rb", - :checksum => "1234", - :url => "http://example.org/files/default.rb", - }, - ], - } - @response = "Example recipe text" + knife.name_args = [ "cookbook_name", "0.1.0", "recipes", "default.rb" ] end it "should print the raw result of the request (likely a file!)" do - expect(@rest).to receive(:get).with("cookbooks/cookbook_name/0.1.0").and_return(@cookbook_response) - expect(@rest).to receive(:streaming_request).with("http://example.org/files/default.rb").and_return(StringIO.new(@response)) - expect(@knife).to receive(:pretty_print).with(@response) - @knife.run + expect(Chef::CookbookVersion).to receive(:load).with("cookbook_name", "0.1.0").and_return(cb) + expect(rest).to receive(:streaming_request).with("http://example.org/files/default.rb").and_return(StringIO.new(content)) + expect(knife).to receive(:pretty_print).with(content) + knife.run end end describe "with 4 arguments: name, version, segment and filename -- with specificity" do before(:each) do - @knife.name_args = [ "cookbook_name", "0.1.0", "files", "afile.rb" ] - @cookbook_response = Chef::CookbookVersion.new("cookbook_name") - @cookbook_response.manifest = { + knife.name_args = [ "cookbook_name", "0.1.0", "files", "afile.rb" ] + cb.manifest = { "files" => [ { :name => "afile.rb", @@ -169,51 +169,50 @@ describe Chef::Knife::CookbookShow do ], } - @response = "Example recipe text" end describe "with --fqdn" do it "should pass the fqdn" do - @knife.config[:platform] = "example_platform" - @knife.config[:platform_version] = "1.0" - @knife.config[:fqdn] = "examplehost.example.org" - expect(@rest).to receive(:get).with("cookbooks/cookbook_name/0.1.0").and_return(@cookbook_response) - expect(@rest).to receive(:streaming_request).with("http://example.org/files/1111").and_return(StringIO.new(@response)) - expect(@knife).to receive(:pretty_print).with(@response) - @knife.run + knife.config[:platform] = "example_platform" + knife.config[:platform_version] = "1.0" + knife.config[:fqdn] = "examplehost.example.org" + expect(Chef::CookbookVersion).to receive(:load).with("cookbook_name", "0.1.0").and_return(cb) + expect(rest).to receive(:streaming_request).with("http://example.org/files/1111").and_return(StringIO.new(content)) + expect(knife).to receive(:pretty_print).with(content) + knife.run end end describe "and --platform" do it "should pass the platform" do - @knife.config[:platform] = "ubuntu" - @knife.config[:platform_version] = "1.0" - @knife.config[:fqdn] = "differenthost.example.org" - expect(@rest).to receive(:get).with("cookbooks/cookbook_name/0.1.0").and_return(@cookbook_response) - expect(@rest).to receive(:streaming_request).with("http://example.org/files/3333").and_return(StringIO.new(@response)) - expect(@knife).to receive(:pretty_print).with(@response) - @knife.run + knife.config[:platform] = "ubuntu" + knife.config[:platform_version] = "1.0" + knife.config[:fqdn] = "differenthost.example.org" + expect(Chef::CookbookVersion).to receive(:load).with("cookbook_name", "0.1.0").and_return(cb) + expect(rest).to receive(:streaming_request).with("http://example.org/files/3333").and_return(StringIO.new(content)) + expect(knife).to receive(:pretty_print).with(content) + knife.run end end describe "and --platform-version" do it "should pass the platform" do - @knife.config[:platform] = "ubuntu" - @knife.config[:platform_version] = "9.10" - @knife.config[:fqdn] = "differenthost.example.org" - expect(@rest).to receive(:get).with("cookbooks/cookbook_name/0.1.0").and_return(@cookbook_response) - expect(@rest).to receive(:streaming_request).with("http://example.org/files/2222").and_return(StringIO.new(@response)) - expect(@knife).to receive(:pretty_print).with(@response) - @knife.run + knife.config[:platform] = "ubuntu" + knife.config[:platform_version] = "9.10" + knife.config[:fqdn] = "differenthost.example.org" + expect(Chef::CookbookVersion).to receive(:load).with("cookbook_name", "0.1.0").and_return(cb) + expect(rest).to receive(:streaming_request).with("http://example.org/files/2222").and_return(StringIO.new(content)) + expect(knife).to receive(:pretty_print).with(content) + knife.run end end describe "with none of the arguments, it should use the default" do it "should pass them all" do - expect(@rest).to receive(:get).with("cookbooks/cookbook_name/0.1.0").and_return(@cookbook_response) - expect(@rest).to receive(:streaming_request).with("http://example.org/files/4444").and_return(StringIO.new(@response)) - expect(@knife).to receive(:pretty_print).with(@response) - @knife.run + expect(Chef::CookbookVersion).to receive(:load).with("cookbook_name", "0.1.0").and_return(cb) + expect(rest).to receive(:streaming_request).with("http://example.org/files/4444").and_return(StringIO.new(content)) + expect(knife).to receive(:pretty_print).with(content) + knife.run end end diff --git a/spec/unit/policy_builder/dynamic_spec.rb b/spec/unit/policy_builder/dynamic_spec.rb index f91b0ba7d2..d94b2a69a2 100644 --- a/spec/unit/policy_builder/dynamic_spec.rb +++ b/spec/unit/policy_builder/dynamic_spec.rb @@ -254,7 +254,7 @@ describe Chef::PolicyBuilder::Dynamic do context "when running chef solo" do before do - Chef::Config[:solo] = true + Chef::Config[:solo_legacy_mode] = true expect(Chef::Node).to receive(:build).with(node_name).and_return(node) expect(policy_builder).to receive(:select_implementation).with(node) expect(implementation).to receive(:finish_load_node).with(node) diff --git a/spec/unit/policy_builder/policyfile_spec.rb b/spec/unit/policy_builder/policyfile_spec.rb index 0f345ee344..307bd45c18 100644 --- a/spec/unit/policy_builder/policyfile_spec.rb +++ b/spec/unit/policy_builder/policyfile_spec.rb @@ -115,7 +115,7 @@ describe Chef::PolicyBuilder::Policyfile do end context "chef-solo" do - before { Chef::Config[:solo] = true } + before { Chef::Config[:solo_legacy_mode] = true } it "errors on create" do expect { initialize_pb }.to raise_error(err_namespace::UnsupportedFeature) diff --git a/spec/unit/provider/git_spec.rb b/spec/unit/provider/git_spec.rb index 36c33d313c..a60c1b44c3 100644 --- a/spec/unit/provider/git_spec.rb +++ b/spec/unit/provider/git_spec.rb @@ -267,6 +267,42 @@ SHAS end end + context "with a user id" do + let(:deploy_user) { 123 } + let(:expected_cmd) { 'git clone "git://github.com/opscode/chef.git" "/my/deploy/dir"' } + let(:default_options) do + { + :user => 123, + :environment => { "HOME" => "/home/deployNinja" }, + :log_tag => "git[web2.0 app]", + } + end + before do + @resource.user deploy_user + allow(Etc).to receive(:getpwuid).and_return(double("Struct::Passwd", :name => @resource.user, :dir => "/home/deployNinja")) + end + context "with a specific home" do + let (:override_home) do + { "HOME" => "/home/masterNinja" } + end + let(:overrided_options) do + { + :user => 123, + :environment => { "HOME" => "/home/masterNinja" }, + :log_tag => "git[web2.0 app]", + } + end + before do + @resource.environment(override_home) + end + before { @resource.environment(override_home) } + it "clones a repo with amended git options with specific home" do + expect(@provider).to receive(:shell_out!).with(expected_cmd, hash_including(overrided_options)) + @provider.clone + end + end + end + it "runs a clone command with escaped destination" do @resource.user "deployNinja" allow(Etc).to receive(:getpwnam).and_return(double("Struct::Passwd", :name => @resource.user, :dir => "/home/deployNinja")) diff --git a/spec/unit/provider/package/chocolatey_spec.rb b/spec/unit/provider/package/chocolatey_spec.rb index 8eaa69b598..8344c3d0ec 100644 --- a/spec/unit/provider/package/chocolatey_spec.rb +++ b/spec/unit/provider/package/chocolatey_spec.rb @@ -59,7 +59,7 @@ Git|2.6.2 munin-node|1.6.1.20130823 EOF remote_list_obj = double(stdout: remote_list_stdout) - allow(provider).to receive(:shell_out!).with("#{choco_exe} list -ar #{package_names.join ' '}#{args}", { timeout: timeout }).and_return(remote_list_obj) + allow(provider).to receive(:shell_out!).with("#{choco_exe} list -r #{package_names.join ' '}#{args}", { timeout: timeout }).and_return(remote_list_obj) end describe "#initialize" do @@ -84,12 +84,6 @@ munin-node|1.6.1.20130823 expect(provider.candidate_version).to eql(["2.6.1"]) end - it "should set the candidate_version to nill if pinning to bogus version" do - allow_remote_list(["git"]) - new_resource.version("2.5.0") - expect(provider.candidate_version).to eql([nil]) - end - it "should set the candidate_version to nil if there is no candidate" do allow_remote_list(["vim"]) new_resource.package_name("vim") @@ -301,14 +295,6 @@ munin-node|1.6.1.20130823 expect { provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package) end - it "installing a package version that does not exist throws an error" do - allow_remote_list(["git"]) - new_resource.package_name("git") - new_resource.version("2.7.0") - provider.load_current_resource - expect { provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package) - end - it "installing multiple packages with a package that does not exist throws an error" do allow_remote_list(["git", "package-does-not-exist"]) new_resource.package_name(["git", "package-does-not-exist"]) diff --git a/spec/unit/provider/package/portage_spec.rb b/spec/unit/provider/package/portage_spec.rb index c2ff1cc952..ebb5b3139f 100644 --- a/spec/unit/provider/package/portage_spec.rb +++ b/spec/unit/provider/package/portage_spec.rb @@ -56,6 +56,12 @@ describe Chef::Provider::Package::Portage, "load_current_resource" do expect(@provider.current_resource.version).to eq("1.0.0-r1") end + it "should return a current resource with the correct version if the package is found with version with character" do + allow(::Dir).to receive(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0d"]) + @provider.load_current_resource + expect(@provider.current_resource.version).to eq("1.0.0d") + end + it "should return a current resource with a nil version if the package is not found" do allow(::Dir).to receive(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/notgit-1.0.0"]) @provider.load_current_resource diff --git a/spec/unit/provider/package/yum/yum_cache_spec.rb b/spec/unit/provider/package/yum/yum_cache_spec.rb new file mode 100644 index 0000000000..e9d615d734 --- /dev/null +++ b/spec/unit/provider/package/yum/yum_cache_spec.rb @@ -0,0 +1,27 @@ +# +# Author:: Adam Jacob (<adam@chef.io>) +# Copyright:: Copyright 2008-2016, 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" + +describe Chef::Provider::Package::Yum::YumCache do + + it "can find yum-dump.py" do + expect(File.exist?(Chef::Provider::Package::Yum::YumCache.instance.yum_dump_path)).to be true + end + +end diff --git a/spec/unit/provider/systemd_unit_spec.rb b/spec/unit/provider/systemd_unit_spec.rb index a76f9e433a..42604c22eb 100644 --- a/spec/unit/provider/systemd_unit_spec.rb +++ b/spec/unit/provider/systemd_unit_spec.rb @@ -39,7 +39,8 @@ describe Chef::Provider::SystemdUnit do let(:provider) { Chef::Provider::SystemdUnit.new(new_resource, run_context) } let(:unit_path_system) { "/etc/systemd/system/sysstat-collect.timer" } let(:unit_path_user) { "/etc/systemd/user/sysstat-collect.timer" } - let(:unit_content_string) { "[Unit]\nDescription=Run system activity accounting tool every 10 minutes\n\n[Timer]\nOnCalendar=*:00/10\n\n[Install]\nWantedBy=sysstat.service" } + let(:unit_content_string) { "[Unit]\nDescription = Run system activity accounting tool every 10 minutes\n\n[Timer]\nOnCalendar = *:00/10\n\n[Install]\nWantedBy = sysstat.service\n" } + let(:malformed_content_string) { "derp" } let(:unit_content_hash) do { @@ -86,6 +87,30 @@ describe Chef::Provider::SystemdUnit do .and_return(current_resource) end + describe "define_resource_requirements" do + before(:each) do + provider.action = :create + allow(provider).to receive(:active?).and_return(false) + allow(provider).to receive(:enabled?).and_return(false) + allow(provider).to receive(:masked?).and_return(false) + allow(provider).to receive(:static?).and_return(false) + end + + it "accepts valid resource requirements" do + new_resource.content(unit_content_string) + provider.load_current_resource + provider.define_resource_requirements + expect { provider.process_resource_requirements }.to_not raise_error + end + + it "rejects failed resource requirements" do + new_resource.content(malformed_content_string) + provider.load_current_resource + provider.define_resource_requirements + expect { provider.process_resource_requirements }.to raise_error(IniParse::ParseError) + end + end + describe "load_current_resource" do before(:each) do allow(provider).to receive(:active?).and_return(false) |