diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/functional/resource/chocolatey_package_spec.rb | 20 | ||||
-rw-r--r-- | spec/integration/client/client_spec.rb | 22 | ||||
-rw-r--r-- | spec/integration/knife/raw_spec.rb | 58 | ||||
-rw-r--r-- | spec/integration/knife/redirection_spec.rb | 35 | ||||
-rw-r--r-- | spec/integration/knife/serve_spec.rb | 3 | ||||
-rw-r--r-- | spec/integration/recipes/unified_mode_spec.rb | 876 | ||||
-rw-r--r-- | spec/support/shared/integration/app_server_support.rb | 39 | ||||
-rw-r--r-- | spec/support/shared/integration/integration_helper.rb | 3 | ||||
-rw-r--r-- | spec/unit/application/client_spec.rb | 11 | ||||
-rw-r--r-- | spec/unit/application/solo_spec.rb | 11 | ||||
-rw-r--r-- | spec/unit/application_spec.rb | 2 | ||||
-rw-r--r-- | spec/unit/knife/bootstrap/train_connector_spec.rb | 27 | ||||
-rw-r--r-- | spec/unit/provider/ifconfig_spec.rb | 11 | ||||
-rw-r--r-- | spec/unit/provider/package/chocolatey_spec.rb | 64 |
14 files changed, 1054 insertions, 128 deletions
diff --git a/spec/functional/resource/chocolatey_package_spec.rb b/spec/functional/resource/chocolatey_package_spec.rb index c5590b2d88..a2728b3fa9 100644 --- a/spec/functional/resource/chocolatey_package_spec.rb +++ b/spec/functional/resource/chocolatey_package_spec.rb @@ -1,6 +1,6 @@ # # Author:: Matt Wrock (<matt@mattwrock.com>) -# Copyright:: Copyright (c) 2016 Chef Software, Inc. +# Copyright:: Copyright (c) 2016-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -75,6 +75,24 @@ describe Chef::Resource::ChocolateyPackage, :windows_only, :choco_installed do subject.package_name "blah" expect { subject.run_action(:install) }.to raise_error Chef::Exceptions::Package end + + it "installs with an option as a string" do + subject.options "--force --confirm" + subject.run_action(:install) + expect(package_list.call).to eq("#{package_name}|2.0") + end + + it "installs with multiple options as a string" do + subject.options "--force --confirm" + subject.run_action(:install) + expect(package_list.call).to eq("#{package_name}|2.0") + end + + it "installs with multiple options as an array" do + subject.options [ "--force", "--confirm" ] + subject.run_action(:install) + expect(package_list.call).to eq("#{package_name}|2.0") + end end context "upgrading a package" do diff --git a/spec/integration/client/client_spec.rb b/spec/integration/client/client_spec.rb index 68cfd015ab..b1763da1f0 100644 --- a/spec/integration/client/client_spec.rb +++ b/spec/integration/client/client_spec.rb @@ -369,6 +369,28 @@ describe "chef-client" do end end + when_the_repository "has a cookbook that outputs some node attributes" do + before do + file "cookbooks/x/recipes/default.rb", <<~'EOM' + puts "COOKBOOKS: #{node[:cookbooks]}" + EOM + file "cookbooks/x/metadata.rb", <<~EOM + name 'x' + version '0.0.1' + EOM + file "config/client.rb", <<~EOM + local_mode true + cookbook_path "#{path_to("cookbooks")}" + EOM + end + + it "should have a cookbook attribute" do + result = shell_out("#{chef_client} -c \"#{path_to("config/client.rb")}\" -o 'x::default' --no-fork", cwd: chef_dir) + result.error! + expect(result.stdout).to include('COOKBOOKS: {"x"=>{"version"=>"0.0.1"}}') + end + end + when_the_repository "has a cookbook that should fail chef_version checks" do before do file "cookbooks/x/recipes/default.rb", "" diff --git a/spec/integration/knife/raw_spec.rb b/spec/integration/knife/raw_spec.rb index 9fd7664ddd..99fb7b5787 100644 --- a/spec/integration/knife/raw_spec.rb +++ b/spec/integration/knife/raw_spec.rb @@ -19,11 +19,11 @@ require "support/shared/integration/integration_helper" require "support/shared/context/config" require "chef/knife/raw" require "chef/knife/show" +require "tiny_server" describe "knife raw", :workstation do include IntegrationSupport include KnifeSupport - include AppServerSupport include_context "default config options" @@ -185,19 +185,29 @@ describe "knife raw", :workstation do end context "When a server returns raw json" do - before :each do - Chef::Config.chef_server_url = "http://localhost:9018" - app = lambda do |env| - [200, { "Content-Type" => "application/json" }, ['{ "x": "y", "a": "b" }'] ] + def start_tiny_server(server_opts = {}) + @server = TinyServer::Manager.new(server_opts) + @server.start + @api = TinyServer::API.instance + @api.clear + + @api.get("/blah", 200, nil, { "Content-Type" => "application/json" }) do + '{ "x": "y", "a": "b" }' end - @raw_server_thread = start_app_server(app, 9018) + end + + def stop_tiny_server + @server.stop + @server = @api = nil + end + + before :each do + Chef::Config.chef_server_url = "http://localhost:9000" + start_tiny_server end after :each do - if @raw_server_thread - @raw_server_thread.kill - @raw_server_thread.join(30) - end + stop_tiny_server end it "knife raw /blah returns the prettified json" do @@ -217,19 +227,29 @@ describe "knife raw", :workstation do end context "When a server returns text" do - before :each do - Chef::Config.chef_server_url = "http://localhost:9018" - app = lambda do |env| - [200, { "Content-Type" => "text" }, ['{ "x": "y", "a": "b" }'] ] + def start_tiny_server(server_opts = {}) + @server = TinyServer::Manager.new(server_opts) + @server.start + @api = TinyServer::API.instance + @api.clear + + @api.get("/blah", 200, nil, { "Content-Type" => "text" }) do + '{ "x": "y", "a": "b" }' end - @raw_server_thread = start_app_server(app, 9018) + end + + def stop_tiny_server + @server.stop + @server = @api = nil + end + + before :each do + Chef::Config.chef_server_url = "http://localhost:9000" + start_tiny_server end after :each do - if @raw_server_thread - @raw_server_thread.kill - @raw_server_thread.join(30) - end + stop_tiny_server end it "knife raw /blah returns the raw text" do diff --git a/spec/integration/knife/redirection_spec.rb b/spec/integration/knife/redirection_spec.rb index 5e5ef27b9a..fe39315fe4 100644 --- a/spec/integration/knife/redirection_spec.rb +++ b/spec/integration/knife/redirection_spec.rb @@ -1,6 +1,6 @@ # # Author:: John Keiser (<jkeiser@chef.io>) -# Copyright:: Copyright 2013-2018, Chef Software Inc. +# Copyright:: Copyright 2013-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,6 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +require "tiny_server" require "support/shared/integration/integration_helper" require "support/shared/context/config" require "chef/knife/list" @@ -22,7 +23,21 @@ require "chef/knife/list" describe "redirection", :workstation do include IntegrationSupport include KnifeSupport - include AppServerSupport + + def start_tiny_server(real_chef_server_url, server_opts = {}) + @server = TinyServer::Manager.new(server_opts) + @server.start + @api = TinyServer::API.instance + @api.clear + + @api.get("/roles", 302, nil, { "Content-Type" => "text", "Location" => "#{real_chef_server_url}/roles" }) do + end + end + + def stop_tiny_server + @server.stop + @server = @api = nil + end include_context "default config options" @@ -30,20 +45,14 @@ describe "redirection", :workstation do before { role "x", {} } context "and another server redirects to it with 302" do - before :each do + before(:each) do real_chef_server_url = Chef::Config.chef_server_url - Chef::Config.chef_server_url = "http://localhost:9018" - app = lambda do |env| - [302, { "Content-Type" => "text", "Location" => "#{real_chef_server_url}#{env["PATH_INFO"]}" }, ["302 found"] ] - end - @redirector_server_thread = start_app_server(app, 9018) + Chef::Config.chef_server_url = "http://localhost:9000" + start_tiny_server(real_chef_server_url) end - after :each do - if @redirector_thread - @redirector_thread.kill - @redirector_thread.join(30) - end + after(:each) do + stop_tiny_server end it "knife list /roles returns the role" do diff --git a/spec/integration/knife/serve_spec.rb b/spec/integration/knife/serve_spec.rb index b0cdd8c070..ab293174d4 100644 --- a/spec/integration/knife/serve_spec.rb +++ b/spec/integration/knife/serve_spec.rb @@ -1,6 +1,6 @@ # # Author:: John Keiser (<jkeiser@chef.io>) -# Copyright:: Copyright 2013-2016, Chef Software Inc. +# Copyright:: Copyright 2013-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,7 +22,6 @@ require "chef/server_api" describe "knife serve", :workstation do include IntegrationSupport include KnifeSupport - include AppServerSupport def with_knife_serve exception = nil diff --git a/spec/integration/recipes/unified_mode_spec.rb b/spec/integration/recipes/unified_mode_spec.rb new file mode 100644 index 0000000000..944319f7bf --- /dev/null +++ b/spec/integration/recipes/unified_mode_spec.rb @@ -0,0 +1,876 @@ +require "support/shared/integration/integration_helper" +require "chef/mixin/shell_out" + +describe "Unified Mode" do + include IntegrationSupport + include Chef::Mixin::ShellOut + + let(:chef_dir) { File.expand_path("../../../../bin", __FILE__) } + + let(:chef_client) { "bundle exec chef-client --minimal-ohai" } + + when_the_repository "has a cookbook with a unified_mode resource with a delayed notification from the second block to the first block" do + before do + directory "cookbooks/x" do + + file "resources/unified_mode.rb", <<-EOM + unified_mode true + resource_name :unified_mode + provides :unified_mode + + action :doit do + klass = new_resource.class + var = "foo" + ruby_block "first block" do + block do + puts "\nfirst: \#\{var\}" + end + action :nothing + end + var = "bar" + ruby_block "second block" do + block do + puts "\nsecond: \#\{var\}" + end + notifies :run, "ruby_block[first block]", :delayed + end + var = "baz" + end + EOM + + file "recipes/default.rb", <<-EOM + unified_mode "whatever" + EOM + + end # directory 'cookbooks/x' + 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 "second block" runs first after "bar" is set + expect(result.stdout).to include("second: bar") + # then the "first block" runs after "baz" in the delayed phase + expect(result.stdout).to include("first: baz") + # nothing else should fire + expect(result.stdout).not_to include("first: foo") + expect(result.stdout).not_to include("first: bar") + expect(result.stdout).not_to include("second: foo") + expect(result.stdout).not_to include("second: baz") + result.error! + end + end + + when_the_repository "has a cookbook with a unified_mode resource with a delayed notification from the first block to the second block" do + before do + directory "cookbooks/x" do + + file "resources/unified_mode.rb", <<-EOM + unified_mode true + resource_name :unified_mode + provides :unified_mode + + action :doit do + klass = new_resource.class + var = "foo" + ruby_block "first block" do + block do + puts "\nfirst: \#\{var\}" + end + notifies :run, "ruby_block[second block]", :delayed + end + var = "bar" + ruby_block "second block" do + block do + puts "\nsecond: \#\{var\}" + end + action :nothing + end + var = "baz" + end + EOM + + file "recipes/default.rb", <<-EOM + unified_mode "whatever" + EOM + + end # directory 'cookbooks/x' + 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' -l debug", cwd: chef_dir) + # the first block should fire first + expect(result.stdout).to include("first: foo") + # the second block should fire in delayed phase + expect(result.stdout).to include("second: baz") + # nothing else should fire + expect(result.stdout).not_to include("first: bar") + expect(result.stdout).not_to include("first: baz") + expect(result.stdout).not_to include("second: foo") + expect(result.stdout).not_to include("second: bar") + result.error! + end + end + + when_the_repository "has a cookbook with a unified_mode resource with an immediate notification from the second block to the first block" do + before do + directory "cookbooks/x" do + + file "resources/unified_mode.rb", <<-EOM + unified_mode true + resource_name :unified_mode + provides :unified_mode + action :doit do + klass = new_resource.class + var = "foo" + ruby_block "first block" do + block do + puts "\nfirst: \#\{var\}" + end + action :nothing + end + var = "bar" + ruby_block "second block" do + block do + puts "\nsecond: \#\{var\}" + end + notifies :run, "ruby_block[first block]", :immediate + end + var = "baz" + end + EOM + + file "recipes/default.rb", <<-EOM + unified_mode "whatever" + EOM + + end # directory 'cookbooks/x' + 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 second resource should fire first when it is parsed + expect(result.stdout).to include("second: bar") + # the first resource should then immediately fire + expect(result.stdout).to include("first: bar") + # no other resources should fire + expect(result.stdout).not_to include("second: baz") + expect(result.stdout).not_to include("second: foo") + expect(result.stdout).not_to include("first: foo") + expect(result.stdout).not_to include("first: baz") + result.error! + end + end + + when_the_repository "has a cookbook with a unified_mode resource with an immediate notification from the first block to the second block" do + before do + directory "cookbooks/x" do + + file "resources/unified_mode.rb", <<-EOM + unified_mode true + resource_name :unified_mode + provides :unified_mode + action :doit do + klass = new_resource.class + var = "foo" + ruby_block "first block" do + block do + puts "\nfirst: \#\{var\}" + end + notifies :run, "ruby_block[second block]", :immediate + end + var = "bar" + ruby_block "second block" do + block do + puts "\nsecond: \#\{var\}" + end + action :nothing + end + var = "baz" + end + EOM + + file "recipes/default.rb", <<-EOM + unified_mode "whatever" + EOM + + end # directory 'cookbooks/x' + 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' -l debug", cwd: chef_dir) + # both blocks should run when they're declared + expect(result.stdout).to include("first: foo") + expect(result.stdout).to include("second: bar") + # nothing else should run + expect(result.stdout).not_to include("first: bar") + expect(result.stdout).not_to include("first: baz") + expect(result.stdout).not_to include("second: foo") + expect(result.stdout).not_to include("second: baz") + result.error! + end + end + + when_the_repository "has a cookbook with a unified_mode resource with an immediate notification from the first block to a block that does not exist" do + before do + directory "cookbooks/x" do + + file "resources/unified_mode.rb", <<-EOM + unified_mode true + resource_name :unified_mode + provides :unified_mode + action :doit do + klass = new_resource.class + var = "foo" + ruby_block "first block" do + block do + puts "\nfirst: \#\{var\}" + end + notifies :run, "ruby_block[second block]", :immediate + end + var = "bar" + var = "baz" + end + EOM + + file "recipes/default.rb", <<-EOM + unified_mode "whatever" + EOM + + end # directory 'cookbooks/x' + end + + it "should fail the run" 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) + # both blocks should run when they're declared + expect(result.stdout).to include("first: foo") + # nothing else should run + expect(result.stdout).not_to include("second: bar") + expect(result.stdout).not_to include("first: bar") + expect(result.stdout).not_to include("first: baz") + expect(result.stdout).not_to include("second: foo") + expect(result.stdout).not_to include("second: baz") + expect(result.stdout).to include("Chef::Exceptions::ResourceNotFound") + expect(result.error?).to be true + end + end + + when_the_repository "has a cookbook with a normal resource with an delayed notification with global resource unified mode on" do + before do + directory "cookbooks/x" do + + file "resources/unified_mode.rb", <<-EOM + resource_name :unified_mode + provides :unified_mode + + action :doit do + klass = new_resource.class + var = "foo" + ruby_block "second block" do + block do + puts "\nsecond: \#\{var\}" + end + action :nothing + end + var = "bar" + ruby_block "first block" do + block do + puts "\nfirst: \#\{var\}" + end + notifies :run, "ruby_block[second block]", :delayed + end + var = "baz" + end + EOM + + file "recipes/default.rb", <<-EOM + unified_mode "whatever" + EOM + + end # directory 'cookbooks/x' + end + + it "should complete with success" do + file "config/client.rb", <<~EOM + resource_unified_mode_default true + 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 "first block" resource runs before the assignment to baz in compile time + expect(result.stdout).to include("first: bar") + # we should not run the "first block" at compile time + expect(result.stdout).not_to include("first: baz") + # (and certainly should run it this early) + expect(result.stdout).not_to include("first: foo") + # the delayed notification should still fire and run after everything else + expect(result.stdout).to include("second: baz") + # the action :nothing should suppress any other running of the second block + expect(result.stdout).not_to include("second: foo") + expect(result.stdout).not_to include("second: bar") + result.error! + end + end + + when_the_repository "has a cookbook with a normal resource with an immediate notification with global resource unified mode on" do + before do + directory "cookbooks/x" do + + file "resources/unified_mode.rb", <<-EOM + resource_name :unified_mode + provides :unified_mode + action :doit do + klass = new_resource.class + var = "foo" + ruby_block "second block" do + block do + puts "\nsecond: \#\{var\}" + end + action :nothing + end + var = "bar" + ruby_block "first block" do + block do + puts "\nfirst: \#\{var\}" + end + notifies :run, "ruby_block[second block]", :immediate + end + var = "baz" + end + EOM + + file "recipes/default.rb", <<-EOM + unified_mode "whatever" + EOM + + end # directory 'cookbooks/x' + end + + it "should complete with success" do + file "config/client.rb", <<~EOM + resource_unified_mode_default true + 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 "first block" resource runs before the assignment to baz in compile time + expect(result.stdout).to include("first: bar") + # we should not run the "first block" at compile time + expect(result.stdout).not_to include("first: baz") + # (and certainly should run it this early) + expect(result.stdout).not_to include("first: foo") + # the immediate notifiation fires immediately + expect(result.stdout).to include("second: bar") + # the action :nothing should suppress any other running of the second block + expect(result.stdout).not_to include("second: foo") + expect(result.stdout).not_to include("second: baz") + result.error! + end + end + + when_the_repository "has a cookbook with a unified resource with an immediate subscribes from the second resource to the first" do + before do + directory "cookbooks/x" do + + file "resources/unified_mode.rb", <<-EOM + unified_mode true + resource_name :unified_mode + provides :unified_mode + action :doit do + klass = new_resource.class + var = "foo" + ruby_block "first block" do + block do + puts "\nfirst: \#\{var\}" + end + end + var = "bar" + ruby_block "second block" do + block do + puts "\nsecond: \#\{var\}" + end + subscribes :run, "ruby_block[first block]", :immediate + action :nothing + end + var = "baz" + end + EOM + + file "recipes/default.rb", <<-EOM + unified_mode "whatever" + EOM + + end # directory 'cookbooks/x' + 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 first resource fires + expect(result.stdout).to include("first: foo") + # the second resource fires when it is parsed + expect(result.stdout).to include("second: bar") + # no other actions should run + expect(result.stdout).not_to include("first: bar") + expect(result.stdout).not_to include("first: baz") + expect(result.stdout).not_to include("second: foo") + expect(result.stdout).not_to include("second: baz") + result.error! + end + end + + when_the_repository "has a cookbook with a unified resource with an immediate subscribes from the first resource to the second" do + before do + directory "cookbooks/x" do + + file "resources/unified_mode.rb", <<-EOM + unified_mode true + resource_name :unified_mode + provides :unified_mode + action :doit do + klass = new_resource.class + var = "foo" + ruby_block "first block" do + block do + puts "\nfirst: \#\{var\}" + end + subscribes :run, "ruby_block[second block]", :immediate + action :nothing + end + var = "bar" + ruby_block "second block" do + block do + puts "\nsecond: \#\{var\}" + end + end + var = "baz" + end + EOM + + file "recipes/default.rb", <<-EOM + unified_mode "whatever" + EOM + + end # directory 'cookbooks/x' + 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 second resource fires first after bar is set + expect(result.stdout).to include("second: bar") + # the first resource then has its immediate subscribes fire at that location + expect(result.stdout).to include("first: bar") + # no other actions should run + expect(result.stdout).not_to include("first: baz") + expect(result.stdout).not_to include("first: foo") + expect(result.stdout).not_to include("second: foo") + expect(result.stdout).not_to include("second: baz") + result.error! + end + end + + when_the_repository "has a cookbook with a unified resource with an delayed subscribes from the second resource to the first" do + before do + directory "cookbooks/x" do + + file "resources/unified_mode.rb", <<-EOM + unified_mode true + resource_name :unified_mode + provides :unified_mode + action :doit do + klass = new_resource.class + var = "foo" + ruby_block "first block" do + block do + puts "\nfirst: \#\{var\}" + end + end + var = "bar" + ruby_block "second block" do + block do + puts "\nsecond: \#\{var\}" + end + subscribes :run, "ruby_block[first block]", :delayed + action :nothing + end + var = "baz" + end + EOM + + file "recipes/default.rb", <<-EOM + unified_mode "whatever" + EOM + + end # directory 'cookbooks/x' + 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 first resource fires as it is parsed + expect(result.stdout).to include("first: foo") + # the second resource then fires in the delayed notifications phase + expect(result.stdout).to include("second: baz") + # no other actions should run + expect(result.stdout).not_to include("first: bar") + expect(result.stdout).not_to include("first: baz") + expect(result.stdout).not_to include("second: foo") + expect(result.stdout).not_to include("second: bar") + result.error! + end + end + + when_the_repository "has a cookbook with a unified resource with an delayed subscribes from the first resource to the second" do + before do + directory "cookbooks/x" do + + file "resources/unified_mode.rb", <<-EOM + unified_mode true + resource_name :unified_mode + provides :unified_mode + action :doit do + klass = new_resource.class + var = "foo" + ruby_block "first block" do + block do + puts "\nfirst: \#\{var\}" + end + subscribes :run, "ruby_block[second block]", :delayed + action :nothing + end + var = "bar" + ruby_block "second block" do + block do + puts "\nsecond: \#\{var\}" + end + end + var = "baz" + end + EOM + + file "recipes/default.rb", <<-EOM + unified_mode "whatever" + EOM + + end # directory 'cookbooks/x' + 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 second resource fires first after bar is set + expect(result.stdout).to include("second: bar") + # the first resource then fires in the delayed notifications phase + expect(result.stdout).to include("first: baz") + # no other actions should run + expect(result.stdout).not_to include("first: foo") + expect(result.stdout).not_to include("first: bar") + expect(result.stdout).not_to include("second: foo") + expect(result.stdout).not_to include("second: baz") + result.error! + end + end + + when_the_repository "has a cookbook with a unified resource with a correct before notification" do + before do + directory "cookbooks/x" do + + file "resources/unified_mode.rb", <<-EOM + unified_mode true + resource_name :unified_mode + provides :unified_mode + action :doit do + klass = new_resource.class + var = "foo" + ruby_block "notified block" do + block do + puts "\nnotified: \#\{var\}" + end + action :nothing + end + var = "bar" + whyrun_safe_ruby_block "notifying block" do + block do + puts "\nnotifying: \#\{var\}" + end + notifies :run, "ruby_block[notified block]", :before + end + var = "baz" + end + EOM + + file "recipes/default.rb", <<-EOM + unified_mode "whatever" + EOM + + end # directory 'cookbooks/x' + 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.scan(/notifying: bar/).length).to eql(2) + expect(result.stdout).to include("Would execute the whyrun_safe_ruby_block notifying block") + expect(result.stdout).to include("notified: bar") + # no other actions should run + expect(result.stdout).not_to include("notified: foo") + expect(result.stdout).not_to include("notified: baz") + expect(result.stdout).not_to include("notifying: foo") + expect(result.stdout).not_to include("notifying: baz") + result.error! + end + end + + when_the_repository "has a cookbook with a unified resource with a correct before subscribes" do + before do + directory "cookbooks/x" do + + file "resources/unified_mode.rb", <<-EOM + unified_mode true + resource_name :unified_mode + provides :unified_mode + action :doit do + klass = new_resource.class + var = "foo" + ruby_block "notified block" do + block do + puts "\nnotified: \#\{var\}" + end + subscribes :run, "whyrun_safe_ruby_block[notifying block]", :before + action :nothing + end + var = "bar" + whyrun_safe_ruby_block "notifying block" do + block do + puts "\nnotifying: \#\{var\}" + end + end + var = "baz" + end + EOM + + file "recipes/default.rb", <<-EOM + unified_mode "whatever" + EOM + + end # directory 'cookbooks/x' + 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.scan(/notifying: bar/).length).to eql(2) + expect(result.stdout).to include("Would execute the whyrun_safe_ruby_block notifying block") + expect(result.stdout).to include("notified: bar") + # no other actions should run + expect(result.stdout).not_to include("notified: foo") + expect(result.stdout).not_to include("notified: baz") + expect(result.stdout).not_to include("notifying: foo") + expect(result.stdout).not_to include("notifying: baz") + result.error! + end + end + + when_the_repository "has a cookbook with a unified resource with a broken/reversed before notification" do + before do + directory "cookbooks/x" do + + file "resources/unified_mode.rb", <<-EOM + unified_mode true + resource_name :unified_mode + provides :unified_mode + action :doit do + klass = new_resource.class + var = "foo" + whyrun_safe_ruby_block "notifying block" do + block do + puts "\nnotifying: \#\{var\}" + end + notifies :run, "ruby_block[notified block]", :before + end + var = "bar" + ruby_block "notified block" do + block do + puts "\nnotified: \#\{var\}" + end + action :nothing + end + var = "baz" + end + EOM + + file "recipes/default.rb", <<-EOM + unified_mode "whatever" + EOM + + end # directory 'cookbooks/x' + end + + it "should fail the run" 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' -l debug", cwd: chef_dir) + # this doesn't work and we can't tell the difference between it and if we were trying to do a correct :before notification but typo'd the name + # so Chef::Exceptions::ResourceNotFound is the best we can do + expect(result.stdout).to include("Chef::Exceptions::ResourceNotFound") + expect(result.error?).to be true + end + end + + when_the_repository "has a cookbook with a unified resource with a broken/reversed before subscribes" do + before do + directory "cookbooks/x" do + + file "resources/unified_mode.rb", <<-EOM + unified_mode true + resource_name :unified_mode + provides :unified_mode + action :doit do + klass = new_resource.class + var = "foo" + whyrun_safe_ruby_block "notifying block" do + block do + puts "\nnotifying: \#\{var\}" + end + end + var = "bar" + ruby_block "notified block" do + block do + puts "\nnotified: \#\{var\}" + end + subscribes :run, "whyrun_safe_ruby_block[notifying block]", :before + action :nothing + end + var = "baz" + end + EOM + + file "recipes/default.rb", <<-EOM + unified_mode "whatever" + EOM + + end # directory 'cookbooks/x' + end + + it "should fail the run" 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) + # this fires first normally before the error + expect(result.stdout).to include("notifying: foo") + # everything else does not run + expect(result.stdout).not_to include("notified: foo") + expect(result.stdout).not_to include("notified: bar") + expect(result.stdout).not_to include("notified: baz") + expect(result.stdout).not_to include("notifying: bar") + expect(result.stdout).not_to include("notifying: baz") + expect(result.stdout).to include("Chef::Exceptions::UnifiedModeBeforeSubscriptionEarlierResource") + expect(result.error?).to be true + end + end + + when_the_repository "has global resource unified mode on" do + before do + directory "cookbooks/x" do + + file "recipes/default.rb", <<-EOM + var = "foo" + ruby_block "first block" do + block do + puts "\nfirst: \#\{var\}" + end + end + var = "bar" + EOM + + end # directory 'cookbooks/x' + end + + it "recipes should still have a compile/converge mode" do + file "config/client.rb", <<~EOM + resource_unified_mode_default true + 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) + # in recipe mode we should still run normally with a compile/converge mode + expect(result.stdout).to include("first: bar") + expect(result.stdout).not_to include("first: foo") + result.error! + end + end +end diff --git a/spec/support/shared/integration/app_server_support.rb b/spec/support/shared/integration/app_server_support.rb deleted file mode 100644 index 317a5a2679..0000000000 --- a/spec/support/shared/integration/app_server_support.rb +++ /dev/null @@ -1,39 +0,0 @@ -# -# Author:: John Keiser (<jkeiser@chef.io>) -# Author:: Ho-Sheng Hsiao (<hosh@chef.io>) -# Copyright:: Copyright 2012-2018, 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 "rack" -require "stringio" - -module AppServerSupport - def start_app_server(app, port) - server = nil - thread = Thread.new do - Rack::Handler::WEBrick.run(app, - Port: 9018, - AccessLog: [], - Logger: WEBrick::Log.new(StringIO.new, 7)) do |found_server| - server = found_server - end - end - Timeout.timeout(30) do - sleep(0.01) until server && server.status == :Running - end - thread - end -end diff --git a/spec/support/shared/integration/integration_helper.rb b/spec/support/shared/integration/integration_helper.rb index 6c0eca98be..f0dfd1dc43 100644 --- a/spec/support/shared/integration/integration_helper.rb +++ b/spec/support/shared/integration/integration_helper.rb @@ -1,7 +1,7 @@ # # Author:: John Keiser (<jkeiser@chef.io>) # Author:: Ho-Sheng Hsiao (<hosh@chef.io>) -# Copyright:: Copyright 2012-2016, Chef Software Inc. +# Copyright:: Copyright 2012-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,7 +23,6 @@ require "chef/config" require "chef/json_compat" require "chef/server_api" require "support/shared/integration/knife_support" -require "support/shared/integration/app_server_support" require "cheffish/rspec/chef_run_support" require "spec_helper" diff --git a/spec/unit/application/client_spec.rb b/spec/unit/application/client_spec.rb index 0773fc70fd..d4ed403197 100644 --- a/spec/unit/application/client_spec.rb +++ b/spec/unit/application/client_spec.rb @@ -1,6 +1,6 @@ # Author:: AJ Christensen (<aj@junglist.gen.nz>) -# Copyright:: Copyright 2008-2018, Chef Software Inc. +# Copyright:: Copyright 2008-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -85,7 +85,6 @@ describe Chef::Application::Client, "reconfigure" do allow(app).to receive(:trap) allow(app).to receive(:configure_logging).and_return(true) - Chef::Config[:interval] = 10 Chef::Config[:once] = false @@ -162,7 +161,7 @@ describe Chef::Application::Client, "reconfigure" do it_behaves_like "sets the configuration", "--no-fork", client_fork: false end - context "with an interval" do + context "with an interval", :unix_only do it_behaves_like "sets the configuration", "--interval 1800", client_fork: true end @@ -322,7 +321,7 @@ describe Chef::Application::Client, "reconfigure" do Chef::Config[:splay] = nil end - it "should terminal with message when interval is given" do + it "should terminate with message when interval is given" do Chef::Config[:interval] = 600 allow(ChefConfig).to receive(:windows?).and_return(false) expect(Chef::Application).to receive(:fatal!).with( @@ -340,8 +339,8 @@ Enable .* interval runs by setting `:client_fork = true` in your config file or allow(ChefConfig).to receive(:windows?).and_return(true) end - it "should not terminate" do - expect(Chef::Application).not_to receive(:fatal!) + it "should terminate" do + expect(Chef::Application).to receive(:fatal!) app.reconfigure end end diff --git a/spec/unit/application/solo_spec.rb b/spec/unit/application/solo_spec.rb index 3f540d24e2..b70f959ab5 100644 --- a/spec/unit/application/solo_spec.rb +++ b/spec/unit/application/solo_spec.rb @@ -1,6 +1,6 @@ # # Author:: AJ Christensen (<aj@junglist.gen.nz>) -# Copyright:: Copyright 2008-2018, Chef Software Inc. +# Copyright:: Copyright 2008-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -64,18 +64,13 @@ describe Chef::Application::Solo do end it "should terminate with message" do - expect(Chef::Application).to receive(:fatal!).with( - /Unforked .* interval runs are disabled by default\. -Configuration settings: - interval = 600 seconds -Enable .* interval runs by setting `:client_fork = true` in your config file or adding `--fork` to your command line options\./ - ) + expect(Chef::Application).to receive(:fatal!).with(/interval runs are (disabled|not supported)/) app.reconfigure end end end - describe "when in daemonized mode and no interval has been set" do + describe "when in daemonized mode and no interval has been set", :unix_only do before do Chef::Config[:daemonize] = true end diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb index e94f9b74ae..7a787d1f3f 100644 --- a/spec/unit/application_spec.rb +++ b/spec/unit/application_spec.rb @@ -1,7 +1,7 @@ # # Author:: AJ Christensen (<aj@junglist.gen.nz>) # Author:: Mark Mzyk (mmzyk@chef.io) -# Copyright:: Copyright 2008-2018, Chef Software Inc. +# Copyright:: Copyright 2008-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/spec/unit/knife/bootstrap/train_connector_spec.rb b/spec/unit/knife/bootstrap/train_connector_spec.rb index a2b7a571b0..dd000f7300 100644 --- a/spec/unit/knife/bootstrap/train_connector_spec.rb +++ b/spec/unit/knife/bootstrap/train_connector_spec.rb @@ -162,16 +162,29 @@ describe Chef::Knife::Bootstrap::TrainConnector do allow(SecureRandom).to receive(:alphanumeric).with(6).and_return(random) end - it "uses the *nix command to create the temp dir and sets ownership to logged-in user" do - expected_command = "mkdir -p #{dir} && sudo chown user1 '#{dir}'" - expect(subject).to receive(:run_command!).with(expected_command) - .and_return double("result", stdout: "\r\n") - expect(subject.temp_dir).to eq(dir) + context "uses the *nix command to create the temp dir and sets ownership to logged-in" do + it "with sudo privilege" do + subject.config[:sudo] = true + expected_command1 = "mkdir -p '#{dir}'" + expected_command2 = "chown user1 '#{dir}'" + expect(subject).to receive(:run_command!).with(expected_command1) + .and_return double("result", stdout: "\r\n") + expect(subject).to receive(:run_command!).with(expected_command2) + .and_return double("result", stdout: "\r\n") + expect(subject.temp_dir).to eq(dir) + end + + it "without sudo privilege" do + expected_command = "mkdir -p '#{dir}'" + expect(subject).to receive(:run_command!).with(expected_command) + .and_return double("result", stdout: "\r\n") + expect(subject.temp_dir).to eq(dir) + end end context "with noise in stderr" do - it "uses the *nix command to create the temp dir and sets ownership to logged-in user" do - expected_command = "mkdir -p #{dir} && sudo chown user1 '#{dir}'" + it "uses the *nix command to create the temp dir" do + expected_command = "mkdir -p '#{dir}'" expect(subject).to receive(:run_command!).with(expected_command) .and_return double("result", stdout: "sudo: unable to resolve host hostname.localhost\r\n" + "#{dir}\r\n") expect(subject.temp_dir).to eq(dir) diff --git a/spec/unit/provider/ifconfig_spec.rb b/spec/unit/provider/ifconfig_spec.rb index 5b1256300e..38561d6e49 100644 --- a/spec/unit/provider/ifconfig_spec.rb +++ b/spec/unit/provider/ifconfig_spec.rb @@ -94,6 +94,17 @@ describe Chef::Provider::Ifconfig do expect(@new_resource).not_to be_updated end + it "should add a bridge interface" do + allow(@provider).to receive(:load_current_resource) + @new_resource.device "br-1234" + command = "ifconfig br-1234 10.0.0.1 netmask 255.255.254.0 metric 1 mtu 1500" + expect(@provider).to receive(:shell_out_compacted!).with(*command.split(" ")) + expect(@provider).to receive(:generate_config) + + @provider.run_action(:add) + expect(@new_resource).to be_updated + end + # We are not testing this case with the assumption that anyone writing the cookbook would not make a typo == lo # it "should add a blank command if the #{@new_resource.device} == lo" do # end diff --git a/spec/unit/provider/package/chocolatey_spec.rb b/spec/unit/provider/package/chocolatey_spec.rb index 9b0cef4ef3..c263b3aa0a 100644 --- a/spec/unit/provider/package/chocolatey_spec.rb +++ b/spec/unit/provider/package/chocolatey_spec.rb @@ -1,6 +1,6 @@ # # Author:: Adam Jacob (<adam@chef.io>) -# Copyright:: Copyright 2008-2016, Chef Software, Inc. +# Copyright:: Copyright 2008-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -46,7 +46,7 @@ describe Chef::Provider::Package::Chocolatey do allow(provider).to receive(:choco_install_path).and_return(choco_install_path) allow(provider).to receive(:choco_exe).and_return(choco_exe) local_list_obj = double(stdout: local_list_stdout) - allow(provider).to receive(:shell_out_compacted!).with("#{choco_exe} list -l -r", { returns: [0], timeout: timeout }).and_return(local_list_obj) + allow(provider).to receive(:shell_out_compacted!).with(choco_exe, "list", "-l", "-r", { returns: [0], timeout: timeout }).and_return(local_list_obj) end def allow_remote_list(package_names, args = nil) @@ -60,7 +60,11 @@ describe Chef::Provider::Package::Chocolatey do EOF remote_list_obj = double(stdout: remote_list_stdout) package_names.each do |pkg| - allow(provider).to receive(:shell_out_compacted!).with("#{choco_exe} list -r #{pkg}#{args}", { returns: [0], timeout: timeout }).and_return(remote_list_obj) + if args + allow(provider).to receive(:shell_out_compacted!).with(choco_exe, "list", "-r", pkg, *args, { returns: [0], timeout: timeout }).and_return(remote_list_obj) + else + allow(provider).to receive(:shell_out_compacted!).with(choco_exe, "list", "-r", pkg, { returns: [0], timeout: timeout }).and_return(remote_list_obj) + end end end @@ -182,7 +186,7 @@ describe Chef::Provider::Package::Chocolatey do it "should install a single package" do allow_remote_list(["git"]) provider.load_current_resource - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y git", { returns: [0], timeout: timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "install", "-y", "git", { returns: [0], timeout: timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -193,7 +197,7 @@ describe Chef::Provider::Package::Chocolatey do allow_remote_list(["git"]) new_resource.timeout(timeout) provider.load_current_resource - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y git", { returns: [0], timeout: timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "install", "-y", "git", { returns: [0], timeout: timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -222,7 +226,7 @@ describe Chef::Provider::Package::Chocolatey do new_resource.package_name("ConEmu") new_resource.version("15.10.25.1") provider.load_current_resource - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y --version 15.10.25.1 conemu", { returns: [0], timeout: timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "install", "-y", "--version", "15.10.25.1", "conemu", { returns: [0], timeout: timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -235,7 +239,7 @@ describe Chef::Provider::Package::Chocolatey do new_resource.package_name(%w{chocolatey ConEmu}) new_resource.version([nil, "15.10.25.1"]) provider.load_current_resource - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y --version 15.10.25.1 conemu", { returns: [0], timeout: timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "install", "-y", "--version", "15.10.25.1", "conemu", { returns: [0], timeout: timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -245,7 +249,7 @@ describe Chef::Provider::Package::Chocolatey do new_resource.package_name("conemu") new_resource.version("15.10.25.1") provider.load_current_resource - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y --version 15.10.25.1 conemu", { returns: [0], timeout: timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "install", "-y", "--version", "15.10.25.1", "conemu", { returns: [0], timeout: timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -255,8 +259,8 @@ describe Chef::Provider::Package::Chocolatey do new_resource.package_name(%w{ConEmu git}) new_resource.version(["15.10.25.1", nil]) provider.load_current_resource - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y --version 15.10.25.1 conemu", { returns: [0], timeout: timeout }).and_return(double) - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y git", { returns: [0], timeout: timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "install", "-y", "--version", "15.10.25.1", "conemu", { returns: [0], timeout: timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "install", "-y", "git", { returns: [0], timeout: timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -265,27 +269,27 @@ describe Chef::Provider::Package::Chocolatey do allow_remote_list(%w{git munin-node}) new_resource.package_name(%w{git munin-node}) provider.load_current_resource - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y git munin-node", { returns: [0], timeout: timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "install", "-y", "git", "munin-node", { returns: [0], timeout: timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end context "when passing a source argument" do it "should pass options into the install command" do - allow_remote_list(["git"], " -source localpackages") + allow_remote_list(["git"], ["-source", "localpackages"]) new_resource.source("localpackages") provider.load_current_resource - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y -source localpackages git", { returns: [0], timeout: timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "install", "-y", "-source", "localpackages", "git", { returns: [0], timeout: timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end end it "should pass options into the install command" do - allow_remote_list(["git"], " -force") + allow_remote_list(["git"], "-force") new_resource.options("-force") provider.load_current_resource - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y -force git", { returns: [0], timeout: timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "install", "-y", "-force", "git", { returns: [0], timeout: timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -306,7 +310,7 @@ describe Chef::Provider::Package::Chocolatey do context "alternate source" do it "installing a package that does not exist throws an error" do - allow_remote_list(["package-does-not-exist"], " -source alternate_source") + allow_remote_list(["package-does-not-exist"], ["-source", "alternate_source"]) new_resource.package_name("package-does-not-exist") new_resource.source("alternate_source") provider.load_current_resource @@ -316,7 +320,7 @@ describe Chef::Provider::Package::Chocolatey do context "private source" do it "installing a package without auth options throws an error" do - allow_remote_list(["package-without-auth"], " -source auth_source") + allow_remote_list(["package-without-auth"], ["-source", "auth_source"]) new_resource.package_name("package-without-auth") new_resource.source("auth_source") provider.load_current_resource @@ -324,7 +328,7 @@ describe Chef::Provider::Package::Chocolatey do end it "installing a package with invalid credentials throws an error" do - allow_remote_list(["package-invalid-auth"], " -source auth_source -u user -p password") + allow_remote_list(["package-invalid-auth"], [ "-source", "auth_source", "-u user -p password"]) new_resource.package_name("package-invalid-auth") new_resource.source("auth_source") new_resource.options("-u user -p password") @@ -333,11 +337,11 @@ describe Chef::Provider::Package::Chocolatey do end it "installing a package with valid credentials" do - allow_remote_list(["git"], " -source auth_source -u user -p password") + allow_remote_list(["git"], [ "-source", "auth_source", "-u user -p password" ]) new_resource.source("auth_source") new_resource.options("-u user -p password") provider.load_current_resource - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y -u user -p password -source auth_source git", { returns: [0], timeout: timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "install", "-y", "-u user -p password", "-source", "auth_source", "git", { returns: [0], timeout: timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -348,7 +352,7 @@ describe Chef::Provider::Package::Chocolatey do it "should install a package that is not installed" do allow_remote_list(["git"]) provider.load_current_resource - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} upgrade -y git", { returns: [0], timeout: timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "upgrade", "-y", "git", { returns: [0], timeout: timeout }).and_return(double) provider.run_action(:upgrade) expect(new_resource).to be_updated_by_last_action end @@ -357,7 +361,7 @@ describe Chef::Provider::Package::Chocolatey do allow_remote_list(["ConEmu"]) new_resource.package_name("ConEmu") provider.load_current_resource - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} upgrade -y conemu", { returns: [0], timeout: timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "upgrade", "-y", "conemu", { returns: [0], timeout: timeout }).and_return(double) provider.run_action(:upgrade) expect(new_resource).to be_updated_by_last_action end @@ -366,7 +370,7 @@ describe Chef::Provider::Package::Chocolatey do allow_remote_list(["conemu"]) new_resource.package_name("conemu") provider.load_current_resource - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} upgrade -y conemu", { returns: [0], timeout: timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "upgrade", "-y", "conemu", { returns: [0], timeout: timeout }).and_return(double) provider.run_action(:upgrade) expect(new_resource).to be_updated_by_last_action end @@ -375,7 +379,7 @@ describe Chef::Provider::Package::Chocolatey do allow_remote_list(["chocolatey"]) new_resource.package_name("chocolatey") provider.load_current_resource - expect(provider).not_to receive(:shell_out_compacted!).with("#{choco_exe} upgrade -y chocolatey", { returns: [0], timeout: timeout }) + expect(provider).not_to receive(:shell_out_compacted!).with(choco_exe, "upgrade", "-y", "chocolatey", { returns: [0], timeout: timeout }) provider.run_action(:upgrade) expect(new_resource).not_to be_updated_by_last_action end @@ -384,7 +388,7 @@ describe Chef::Provider::Package::Chocolatey do allow_remote_list(["git"]) new_resource.version("2.6.2") provider.load_current_resource - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} upgrade -y --version 2.6.2 git", { returns: [0], timeout: timeout }) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "upgrade", "-y", "--version", "2.6.2", "git", { returns: [0], timeout: timeout }) provider.run_action(:upgrade) expect(new_resource).to be_updated_by_last_action end @@ -392,7 +396,7 @@ describe Chef::Provider::Package::Chocolatey do it "upgrading multiple packages uses a single command" do allow_remote_list(%w{conemu git}) new_resource.package_name(%w{conemu git}) - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} upgrade -y conemu git", { returns: [0], timeout: timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "upgrade", "-y", "conemu", "git", { returns: [0], timeout: timeout }).and_return(double) provider.run_action(:upgrade) expect(new_resource).to be_updated_by_last_action end @@ -413,7 +417,7 @@ describe Chef::Provider::Package::Chocolatey do context "alternate source" do it "installing a package that does not exist throws an error" do - allow_remote_list(["package-does-not-exist"], " -source alternate_source") + allow_remote_list(["package-does-not-exist"], ["-source", "alternate_source"]) new_resource.package_name("package-does-not-exist") new_resource.source("alternate_source") provider.load_current_resource @@ -444,7 +448,7 @@ describe Chef::Provider::Package::Chocolatey do allow_remote_list(["ConEmu"]) new_resource.package_name("ConEmu") provider.load_current_resource - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} uninstall -y ConEmu", { returns: [0], timeout: timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "uninstall", "-y", "ConEmu", { returns: [0], timeout: timeout }).and_return(double) provider.run_action(:remove) expect(new_resource).to be_updated_by_last_action end @@ -453,7 +457,7 @@ describe Chef::Provider::Package::Chocolatey do allow_remote_list(["conemu"]) new_resource.package_name("conemu") provider.load_current_resource - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} uninstall -y conemu", { returns: [0], timeout: timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "uninstall", "-y", "conemu", { returns: [0], timeout: timeout }).and_return(double) provider.run_action(:remove) expect(new_resource).to be_updated_by_last_action end @@ -463,7 +467,7 @@ describe Chef::Provider::Package::Chocolatey do allow_remote_list(%w{git conemu}) new_resource.package_name(%w{git conemu}) provider.load_current_resource - expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} uninstall -y conemu", { returns: [0], timeout: timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with(choco_exe, "uninstall", "-y", "conemu", { returns: [0], timeout: timeout }).and_return(double) provider.run_action(:remove) expect(new_resource).to be_updated_by_last_action end |