# require "helper" require "rbconfig" require "inspec/shell_detector" module ShellDetectorTestHelpers def no_proc Dir.expects(:exist?).with("/proc").returns(false) end def with_proc(shell) Dir.expects(:exist?).with("/proc").returns(true) File.expects(:readlink).with("/proc/#{ppid}/exe").returns(shell) end def with_ps(output) subject.expects(:'`').with("ps -cp #{ppid} -o command=").returns(output) end def with_env(shell) ENV.expects(:[]).with("SHELL").returns(shell) end def with_pwuid(shell) Process.expects(:uid).returns(9999) @mock_user = Minitest::Mock.new @mock_user.expect :shell, shell Etc.expects(:getpwuid).with(9999).returns(@mock_user) end end describe Inspec::ShellDetector do include ShellDetectorTestHelpers let(:subject) { Inspec::ShellDetector.new } let(:ppid) { Process.ppid } # Small hack to ensure we can test on windows it "returns nil immediately if running on windows" do RbConfig::CONFIG.expects(:[]).with("host_os").returns("mswin") _(subject.shell!).must_be_nil end describe "not on windows" do before do RbConfig::CONFIG.expects(:[]).with("host_os").returns("beos") end it "detects the shell via /proc if it exists" do with_proc("/usr/bin/fish") _(subject.shell!).must_equal("fish") end it "detects via `ps` if /proc doesn't exist" do no_proc; with_ps("/usr/bin/ksh") _(subject.shell!).must_equal("ksh") end it "detects via ENV if parent process methods failed" do no_proc; with_ps(""); with_env("fish") _(subject.shell!).must_equal("fish") end it "detects via getpwuid if all else fails" do no_proc; with_ps(""); with_env(""); with_pwuid("/usr/bin/fish") _(subject.shell!).must_equal("fish") @mock_user.verify end it "returns nil if the shell isn't in the whitelist" do no_proc; with_ps(""); with_env("badshell"); with_pwuid("/usr/bin/badshell") _(subject.shell!).must_be_nil end end end