summaryrefslogtreecommitdiff
path: root/spec/unit/provider
diff options
context:
space:
mode:
authorTim Smith <tsmith@chef.io>2020-06-05 10:04:30 -0700
committerGitHub <noreply@github.com>2020-06-05 10:04:30 -0700
commit6772c7c1f2c5e8e4814bef8b4a6e706e1cfad636 (patch)
treeccfb05599a1ce1594eca2a6a21c025679cd4a30f /spec/unit/provider
parentbf2d814febe70da55a7dbb487d762e3162eb04c0 (diff)
parent21f0369b506d96bea0dd6cfaecbcd95908d9ceaf (diff)
downloadchef-6772c7c1f2c5e8e4814bef8b4a6e706e1cfad636.tar.gz
Merge pull request #9932 from chef/script-resources-use-pipes
Change script resources to use pipes rather than writing to temp files
Diffstat (limited to 'spec/unit/provider')
-rw-r--r--spec/unit/provider/batch_spec.rb130
-rw-r--r--spec/unit/provider/powershell_script_spec.rb48
-rw-r--r--spec/unit/provider/script_spec.rb130
3 files changed, 153 insertions, 155 deletions
diff --git a/spec/unit/provider/batch_spec.rb b/spec/unit/provider/batch_spec.rb
new file mode 100644
index 0000000000..3ca1334489
--- /dev/null
+++ b/spec/unit/provider/batch_spec.rb
@@ -0,0 +1,130 @@
+#
+# Author:: Adam Jacob (adam@chef.io)
+# Copyright:: Copyright 2009-2016, Opscode
+# 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::Batch do
+ let(:node) do
+ node = Chef::Node.new
+ node.default["kernel"] = {}
+ node.default["kernel"][:machine] = :x86_64.to_s
+ node
+ end
+
+ let(:events) { Chef::EventDispatch::Dispatcher.new }
+
+ let(:run_context) { Chef::RunContext.new(node, {}, events) }
+
+ let(:new_resource) do
+ new_resource = Chef::Resource::Batch.new("cmd.exe and conquer")
+ new_resource.code %q{echo "hello"}
+ new_resource
+ end
+
+ let(:provider) { Chef::Provider::Batch.new(new_resource, run_context) }
+
+ context "#grant_alternate_user_read_access" do
+ before do
+ allow(ChefUtils).to receive(:windows?).and_return(true)
+ stub_const("Chef::ReservedNames::Win32::API::Security::GENERIC_READ", 1)
+ stub_const("Chef::ReservedNames::Win32::API::Security::GENERIC_EXECUTE", 4)
+ stub_const("Chef::ReservedNames::Win32::Security", Class.new)
+ stub_const("Chef::ReservedNames::Win32::Security::SecurableObject", Class.new)
+ stub_const("Chef::ReservedNames::Win32::Security::SID", Class.new)
+ stub_const("Chef::ReservedNames::Win32::Security::ACE", Class.new)
+ stub_const("Chef::ReservedNames::Win32::Security::ACL", Class.new)
+
+ provider.singleton_class.send(:public, :grant_alternate_user_read_access)
+ end
+
+ context "when an alternate user is not specified" do
+ it "does not attempt to set the script file's security descriptor" do
+ expect(provider).to receive(:grant_alternate_user_read_access)
+ expect(Chef::ReservedNames::Win32::Security::SecurableObject).not_to receive(:new)
+ provider.grant_alternate_user_read_access("a fake path")
+ end
+ end
+
+ context "when an alternate user is specified" do
+ let(:security_descriptor) { instance_double("Chef::ReservedNames::Win32::Security::SecurityDescriptor", dacl: []) }
+ let(:securable_object) { instance_double("Chef::ReservedNames::Win32::Security::SecurableObject", :security_descriptor => security_descriptor, :dacl= => nil) }
+
+ it "sets the script file's security descriptor" do
+ new_resource.user("toor")
+ expect(Chef::ReservedNames::Win32::Security::SecurableObject).to receive(:new).and_return(securable_object)
+ expect(Chef::ReservedNames::Win32::Security::SID).to receive(:from_account).and_return(nil)
+ expect(Chef::ReservedNames::Win32::Security::ACE).to receive(:access_allowed).and_return(nil)
+ expect(Chef::ReservedNames::Win32::Security::ACL).to receive(:create).and_return(nil)
+ expect(securable_object).to receive(:dacl=)
+ provider.grant_alternate_user_read_access("a fake path")
+ end
+ end
+ end
+
+ describe "#with_temp_script_file" do
+ before do
+ provider.singleton_class.send(:public, :with_temp_script_file)
+ provider.singleton_class.send(:public, :script_file_path)
+ end
+
+ it "should put the contents of the script in the temp file" do
+ temp_file_contents = nil
+
+ provider.with_temp_script_file do
+ temp_file_contents = File.read(provider.script_file_path)
+ end
+
+ expect(temp_file_contents.strip).to eq(%q{echo "hello"})
+ end
+ end
+
+ describe "#command" do
+ let(:basepath) { "C:\\Windows\\system32" }
+ let(:interpreter) { File.join(basepath, "cmd.exe") }
+
+ before do
+ allow(provider).to receive(:basepath).and_return(basepath)
+ provider.singleton_class.send(:public, :with_temp_script_file)
+ provider.singleton_class.send(:public, :script_file_path)
+ end
+
+ it 'should set the command to "interpreter" "tempfile"' do
+ command = nil
+ script_file_path = nil
+ provider.with_temp_script_file do
+ command = provider.command
+ script_file_path = provider.script_file_path
+ end
+
+ expect(command).to eq(%Q{"#{interpreter}" /c "#{script_file_path}"})
+ end
+
+ it "should set the command to 'interpreter flags tempfile'" do
+ new_resource.flags "/f"
+
+ command = nil
+ script_file_path = nil
+ provider.with_temp_script_file do
+ command = provider.command
+ script_file_path = provider.script_file_path
+ end
+
+ expect(command).to eq(%Q{"#{interpreter}" /f /c "#{script_file_path}"})
+ end
+ end
+end
diff --git a/spec/unit/provider/powershell_script_spec.rb b/spec/unit/provider/powershell_script_spec.rb
index 88aceda241..e0857a1ea4 100644
--- a/spec/unit/provider/powershell_script_spec.rb
+++ b/spec/unit/provider/powershell_script_spec.rb
@@ -18,34 +18,12 @@
require "spec_helper"
describe Chef::Provider::PowershellScript, "action_run" do
-
- let(:powershell_version) { nil }
- let(:node) do
- node = Chef::Node.new
- node.default["kernel"] = {}
- node.default["kernel"][:machine] = :x86_64.to_s
- unless powershell_version.nil?
- node.default[:languages] = { powershell: { version: powershell_version } }
- end
- node
- end
-
- # code block is mandatory for the powershell provider
- let(:code) { "" }
-
let(:events) { Chef::EventDispatch::Dispatcher.new }
- let(:run_context) { run_context = Chef::RunContext.new(node, {}, events) }
+ let(:run_context) { Chef::RunContext.new(Chef::Node.new, {}, events) }
let(:new_resource) do
- new_resource = Chef::Resource::PowershellScript.new("run some powershell code", run_context)
- new_resource.code code
- new_resource
- end
-
- def set_user_defined_flag
- new_resource.flags "-ExecutionPolicy RemoteSigned"
- provider
+ Chef::Resource::PowershellScript.new("run some powershell code", run_context)
end
let(:provider) do
@@ -54,32 +32,12 @@ describe Chef::Provider::PowershellScript, "action_run" do
context "when setting interpreter flags" do
before(:each) do
- allow(provider).to receive(:is_forced_32bit).and_return(false)
- os_info_double = double("os_info")
- allow(provider.run_context.node["kernel"]).to receive(:[]).with("os_info").and_return(os_info_double)
- allow(os_info_double).to receive(:[]).with("system_directory").and_return("C:\\Windows\\system32")
+ allow(provider).to receive(:basepath).and_return("C:\\Windows\\system32")
end
it "sets the -File flag as the last flag" do
flags = provider.command.split(" ").keep_if { |flag| flag =~ /^-/ }
expect(flags.pop).to eq("-File")
end
-
- let(:execution_policy_flag) do
- provider_flags = provider.flags.split(" ")
- # Last occurance of "executionpolicy"
- execution_policy_index = provider_flags.map(&:downcase).rindex("-executionpolicy")
-
- execution_policy_index ? provider_flags[execution_policy_index + 1] : nil
- end
-
- it "sets default -ExecutionPolicy flag to 'Bypass'" do
- expect(execution_policy_flag).to eq("Bypass")
- end
-
- it "sets user defined -ExecutionPolicy flag to 'RemoteSigned'" do
- set_user_defined_flag
- expect(execution_policy_flag).to eq("RemoteSigned")
- end
end
end
diff --git a/spec/unit/provider/script_spec.rb b/spec/unit/provider/script_spec.rb
index 68d6bdb697..18a8a3305b 100644
--- a/spec/unit/provider/script_spec.rb
+++ b/spec/unit/provider/script_spec.rb
@@ -34,124 +34,34 @@ describe Chef::Provider::Script, "action_run" do
let(:provider) { Chef::Provider::Script.new(new_resource, run_context) }
- let(:tempfile) { Tempfile.open("rspec-provider-script") }
-
- before(:each) do
- allow(provider).to receive(:shell_out!).and_return(true)
- allow(provider).to receive(:script_file).and_return(tempfile)
- end
-
- context "#script_file" do
- it "creates a temporary file to store the script" do
- allow(provider).to receive(:script_file).and_call_original
- expect(provider.script_file).to be_an_instance_of(Tempfile)
+ describe "#command" do
+ it "is only the intepreter in quotes by default" do
+ expect(provider.command.strip).to eq(%q{"perl"})
end
- end
- context "#unlink_script_file" do
- it "unlinks the tempfile" do
- tempfile_path = tempfile.path
- provider.unlink_script_file
- expect(File.exist?(tempfile_path)).to be false
+ it "is the interpreter in quotes with the flags when flags are used" do
+ new_resource.flags "-f"
+ expect(provider.command).to eq(%q{"perl" -f})
end
end
- context "when configuring the script file's security" do
- context "when not running on Windows" do
- before do
- allow(ChefUtils).to receive(:windows?).and_return(false)
- end
- context "#set_owner_and_group" do
- it "sets the owner and group for the script file" do
- new_resource.user "toor"
- new_resource.group "wheel"
- expect(FileUtils).to receive(:chown).with("toor", "wheel", tempfile.path)
- provider.set_owner_and_group
- end
- end
- end
-
- context "when running on Windows" do
- before do
- allow(ChefUtils).to receive(:windows?).and_return(true)
- expect(new_resource.user).to eq(nil)
- stub_const("Chef::ReservedNames::Win32::API::Security::GENERIC_READ", 1)
- stub_const("Chef::ReservedNames::Win32::API::Security::GENERIC_EXECUTE", 4)
- stub_const("Chef::ReservedNames::Win32::Security", Class.new)
- stub_const("Chef::ReservedNames::Win32::Security::SecurableObject", Class.new)
- stub_const("Chef::ReservedNames::Win32::Security::SID", Class.new)
- stub_const("Chef::ReservedNames::Win32::Security::ACE", Class.new)
- stub_const("Chef::ReservedNames::Win32::Security::ACL", Class.new)
- end
-
- context "when an alternate user is not specified" do
- it "does not attempt to set the script file's security descriptor" do
- expect(provider).to receive(:grant_alternate_user_read_access)
- expect(Chef::ReservedNames::Win32::Security::SecurableObject).not_to receive(:new)
- provider.set_owner_and_group
- end
- end
-
- context "when an alternate user is specified" do
- let(:security_descriptor) { instance_double("Chef::ReservedNames::Win32::Security::SecurityDescriptor", dacl: []) }
- let(:securable_object) { instance_double("Chef::ReservedNames::Win32::Security::SecurableObject", :security_descriptor => security_descriptor, :dacl= => nil) }
- it "sets the script file's security descriptor" do
- new_resource.user("toor")
- expect(Chef::ReservedNames::Win32::Security::SecurableObject).to receive(:new).and_return(securable_object)
- expect(Chef::ReservedNames::Win32::Security::SID).to receive(:from_account).and_return(nil)
- expect(Chef::ReservedNames::Win32::Security::ACE).to receive(:access_allowed).and_return(nil)
- expect(Chef::ReservedNames::Win32::Security::ACL).to receive(:create).and_return(nil)
- expect(securable_object).to receive(:dacl=)
- provider.set_owner_and_group
- end
- end
- end
- end
-
- context "with the script file set to the correct owner and group" do
+ describe "#action_run" do
before do
- allow(provider).to receive(:set_owner_and_group)
+ allow(provider).to receive(:stream_to_stdout?).and_return(false)
end
- describe "when writing the script to the file" do
- it "should put the contents of the script in the temp file" do
- allow(provider).to receive(:unlink_script_file) # stub to avoid remove
- provider.action_run
- expect(IO.read(tempfile.path)).to eq("$| = 1; print 'i like beans'\n")
- provider.unlink_script_file
- end
-
- it "closes before executing the script and unlinks it when finished" do
- tempfile_path = tempfile.path
- provider.action_run
- expect(tempfile).to be_closed
- expect(File.exist?(tempfile_path)).to be false
- end
- end
-
- describe "when running the script" do
- let (:default_opts) do
- { timeout: 3600, returns: 0, default_env: false, log_level: :info, log_tag: "script[run some perl code]" }
- end
-
- before do
- allow(STDOUT).to receive(:tty?).and_return(false)
- end
-
- it 'should set the command to "interpreter" "tempfile"' do
- expect(provider.command).to eq(%Q{"perl" "#{tempfile.path}"})
- end
-
- it "should call shell_out! with the command" do
- expect(provider).to receive(:shell_out!).with(provider.command, default_opts).and_return(true)
- provider.action_run
- end
-
- it "should set the command to 'interpreter flags tempfile'" do
- new_resource.flags "-f"
- expect(provider.command).to eq(%Q{"perl" -f "#{tempfile.path}"})
- end
+ it "should call shell_out! with the command and correct options" do
+ opts = {
+ timeout: 3600,
+ returns: 0,
+ default_env: false,
+ log_level: :info,
+ log_tag: "script[run some perl code]",
+ input: "$| = 1; print 'i like beans'",
+ }
+
+ expect(provider).to receive(:shell_out!).with(provider.command, opts).and_return(true)
+ provider.action_run
end
end
-
end