aboutsummaryrefslogtreecommitdiff
path: root/spec/unit/provider/cron/filetype_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/unit/provider/cron/filetype_spec.rb')
-rw-r--r--spec/unit/provider/cron/filetype_spec.rb144
1 files changed, 144 insertions, 0 deletions
diff --git a/spec/unit/provider/cron/filetype_spec.rb b/spec/unit/provider/cron/filetype_spec.rb
new file mode 100644
index 0000000..bf96f91
--- /dev/null
+++ b/spec/unit/provider/cron/filetype_spec.rb
@@ -0,0 +1,144 @@
+require 'spec_helper'
+require 'puppet/provider/cron/filetype'
+
+# rubocop:disable RSpec/FilePath
+describe Puppet::Provider::Cron::FileType do
+ shared_examples_for 'crontab provider' do
+ let(:cron) { type.new('no_such_user') }
+ let(:crontab) { File.read(my_fixture(crontab_output)) }
+ let(:options) { { failonfail: true, combine: true } }
+ let(:uid) { 'no_such_user' }
+ let(:user_options) { options.merge(uid: uid) }
+
+ it 'exists' do
+ expect(type).not_to be_nil
+ end
+
+ # make Puppet::Util::SUIDManager return something deterministic, not the
+ # uid of the user running the tests, except where overridden below.
+ before :each do
+ Puppet::Util::SUIDManager.stubs(:uid).returns 1234
+ end
+
+ describe '#read' do
+ before(:each) do
+ Puppet::Util.stubs(:uid).with(uid).returns 9000
+ end
+
+ it 'runs crontab -l as the target user' do
+ Puppet::Util::Execution
+ .expects(:execute)
+ .with(['crontab', '-l'], user_options)
+ .returns(Puppet::Util::Execution::ProcessOutput.new(crontab, 0))
+
+ expect(cron.read).to eq(crontab)
+ end
+
+ it 'does not switch user if current user is the target user' do
+ Puppet::Util.expects(:uid).with(uid).twice.returns 9000
+ Puppet::Util::SUIDManager.expects(:uid).returns 9000
+ Puppet::Util::Execution
+ .expects(:execute).with(['crontab', '-l'], options)
+ .returns(Puppet::Util::Execution::ProcessOutput.new(crontab, 0))
+ expect(cron.read).to eq(crontab)
+ end
+
+ it 'treats an absent crontab as empty' do
+ Puppet::Util::Execution.expects(:execute).with(['crontab', '-l'], user_options).raises(Puppet::ExecutionFailure, absent_crontab)
+ expect(cron.read).to eq('')
+ end
+
+ it "treats a nonexistent user's crontab as empty" do
+ Puppet::Util.expects(:uid).with(uid).returns nil
+
+ expect(cron.read).to eq('')
+ end
+
+ it 'returns empty if the user is not authorized to use cron' do
+ Puppet::Util::Execution.expects(:execute).with(['crontab', '-l'], user_options).raises(Puppet::ExecutionFailure, unauthorized_crontab)
+ expect(cron.read).to eq('')
+ end
+ end
+
+ describe '#remove' do
+ it 'runs crontab -r as the target user' do
+ Puppet::Util::Execution.expects(:execute).with(['crontab', '-r'], user_options)
+ cron.remove
+ end
+
+ it 'does not switch user if current user is the target user' do
+ Puppet::Util.expects(:uid).with(uid).returns 9000
+ Puppet::Util::SUIDManager.expects(:uid).returns 9000
+ Puppet::Util::Execution.expects(:execute).with(['crontab', '-r'], options)
+ cron.remove
+ end
+ end
+
+ describe '#write' do
+ let!(:tmp_cron) { Tempfile.new('puppet_crontab_spec') }
+ let!(:tmp_cron_path) { tmp_cron.path }
+
+ before :each do
+ Puppet::Util.stubs(:uid).with(uid).returns 9000
+ Tempfile.expects(:new).with("puppet_#{name}", encoding: Encoding.default_external).returns tmp_cron
+ end
+
+ after :each do
+ File.unstub(:chown)
+ end
+
+ it 'runs crontab as the target user on a temporary file' do
+ File.expects(:chown).with(9000, nil, tmp_cron_path)
+ Puppet::Util::Execution.expects(:execute).with(['crontab', tmp_cron_path], user_options)
+
+ tmp_cron.expects(:print).with("foo\n")
+ cron.write "foo\n"
+
+ expect(Puppet::FileSystem).not_to exist(tmp_cron_path)
+ end
+
+ it 'does not switch user if current user is the target user' do
+ Puppet::Util::SUIDManager.expects(:uid).returns 9000
+ File.expects(:chown).with(9000, nil, tmp_cron_path)
+ Puppet::Util::Execution.expects(:execute).with(['crontab', tmp_cron_path], options)
+
+ tmp_cron.expects(:print).with("foo\n")
+ cron.write "foo\n"
+
+ expect(Puppet::FileSystem).not_to exist(tmp_cron_path)
+ end
+ end
+ end
+
+ describe 'the suntab filetype', unless: Puppet::Util::Platform.windows? do
+ let(:type) { described_class.filetype(:suntab) }
+ let(:name) { type.name }
+ let(:crontab_output) { 'suntab_output' }
+
+ # possible crontab output was taken from here:
+ # https://docs.oracle.com/cd/E19082-01/819-2380/sysrescron-60/index.html
+ let(:absent_crontab) do
+ 'crontab: can\'t open your crontab file'
+ end
+ let(:unauthorized_crontab) do
+ 'crontab: you are not authorized to use cron. Sorry.'
+ end
+
+ it_behaves_like 'crontab provider'
+ end
+
+ describe 'the aixtab filetype', unless: Puppet::Util::Platform.windows? do
+ let(:type) { described_class.filetype(:aixtab) }
+ let(:name) { type.name }
+ let(:crontab_output) { 'aixtab_output' }
+
+ let(:absent_crontab) do
+ '0481-103 Cannot open a file in the /var/spool/cron/crontabs directory.'
+ end
+ let(:unauthorized_crontab) do
+ '0481-109 You are not authorized to use the cron command.'
+ end
+
+ it_behaves_like 'crontab provider'
+ end
+end