blob: 47614f9e3d152cc4a2f5c82c5d8314d9b0dd1fb4 [file] [log] [blame]
#!/bin/sh
# Copyright (c) International Business Machines Corp., 2001
# Copyright (c) 2017 Petr Vorel <pvorel@suse.cz>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it would be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# Author: Manoj Iyer <manjo@mail.utexas.edu>
TST_CNT=3
TST_TESTFUNC=do_test
TST_NEEDS_TMPDIR=1
TST_SETUP=setup
TST_CLEANUP=cleanup
. tst_test.sh
. daemonlib.sh
SYSLOG_STARTED=
CROND_STARTED=
LOGS=
grep_logs()
{
local pattern="$1"
local fail_msg="$2"
local pass_msg="${3:-}"
local n="${4:-10}"
local lines=10
local out=out.$$
local err=err.$$
local i ret
for i in $(seq 1 $n); do
if [ "$LOGS" ]; then
tail -n $lines $LOGS | grep "$pattern" > $out 2> $err
else
journalctl -n $lines | grep "$pattern" > $out 2> $err
fi
ret=$?
[ $ret -eq 0 ] && break
sleep 1
done
if [ $ret -ne 0 ]; then
tst_res TFAIL "$fail_msg: `cat $err`"
else
[ "$pass_msg" ] && tst_res TPASS "$pass_msg"
fi
}
create_crontab()
{
local crontab=cronjob.cron
local script=$1
local out=out.$$
tst_res TINFO "creating crontab: $script"
cat > $crontab <<EOF
* * * * * $script
EOF
tst_res TINFO "installing crontab file"
crontab $crontab > $out 2>&1
if [ $? -ne 0 ]; then
tst_brk TBROK "crontab: error while installing crontab file: `cat $out`"
return 1
fi
return 0
}
remove_crontab()
{
local out=out.$$
tst_res TINFO "removing crontab file"
crontab -r > $out 2>&1
if [ $? -ne 0 ]; then
tst_brk TBROK "crontab: error while removing crontab file `cat $out`"
return 1
fi
return 0
}
create_hello_script()
{
local script=$1
cat > $script <<EOF
#!/bin/sh
echo "Hello Hell"
exit 0
EOF
chmod +x $script
}
install_cron_test()
{
local script=$PWD/cronprg.sh
local cron_out=$PWD/tst1_cron.out
local err=err.log
local sleep_sec
local ts_min1 ts_min2 fail
tst_res TINFO "test install cron job"
cat > $script <<EOF
#! /bin/sh
DATE=\`LC_ALL=C date\`
echo "Hello Hell today is \$DATE" > $cron_out 2>&1
exit 0
EOF
chmod +x $script
create_crontab $script 2> $err
if [ $? -ne 0 ]; then
tst_brk TBROK "crontab: error while creating cron job: `cat $err`"
else
tst_res TINFO "cron job installed successfully"
fi
grep_logs 'crontab.*REPLACE' \
"cron activity not recorded" \
"cron activity logged"
# Sleep 3s after next minute since the loop below sleeps for 62 seconds, we
# should start this 5-iteration loop closely following the start of a
# minute.
sleep_sec=$((123-`date +%-S`))
tst_res TINFO "sleep for ${sleep_sec}s"
sleep $sleep_sec
# $script executed by the cron job will record the date and time into file
# $cron_out. Get the minute recorded by the program, sleep to allow the cron
# job to update file after 1m, and check if the value is advanced by 1.
for i in $(seq 1 5); do
tst_res TINFO "loop: $i: start"
if [ ! -f "$cron_out" ]; then
tst_res TFAIL "loop $i: file $cron_out doesn't exist"
fail=1
break
fi
ts_min1=$(awk '{print $8}' $cron_out | awk -F: '{printf("%d", $2);}')
# wait for the cron job to update output file
sleep 62
# Check the time recorded in output file, this should be 1 minute ahead of
# what was recored earlier.
ts_min2=$(awk '{print $8}' $cron_out | awk -F: '{printf("%d", $2);}')
if [ "x${ts_min1}" = "x" ] || [ "x${ts_min2}" = "x" ]; then
tst_res TFAIL "loop $i: failed to get time: ts_min1: $ts_min1, ts_min2: $ts_min2"
fail=1
break
fi
[ $ts_min1 -eq 59 ] && ts_min1=0 || ts_min1=$(( $ts_min1+1 ))
if [ $ts_min2 -ne $ts_min1 ]; then
tst_res TFAIL "loop $i: failed to update every minute: expected: $ts_min1, received: $ts_min2"
fail=1
break
fi
done
if [ ! "$fail" ]; then
grep_logs "CMD ($script)" \
"failed to install cron job installed and execute it" \
"cron job installed and executed" 1
fi
remove_crontab
}
remove_cron_job_test()
{
local script=$PWD/cronprg.sh
tst_res TINFO "test remove cron job"
create_hello_script $script
create_crontab $script
grep_logs 'crontab.*REPLACE' \
"crontab activity not recorded"
remove_crontab && grep_logs DELETE \
"crontab activity not recorded" \
"crontab removed the cron job" 1
}
list_cron_jobs_test()
{
local script=$PWD/cronprg.sh
local out=cron.out
tst_res TINFO "test list installed cron jobs"
create_hello_script $script
create_crontab $script
tst_res TINFO "crontab: listing cron jobs"
crontab -l | grep "$script" > $out 2>&1 || \
tst_brk TBROK "crontab failed while listing installed cron jobs: `cat $out`"
remove_crontab
crontab -l > $out 2>&1
if [ $? -ne 0 ]; then
grep -q "no crontab for" $out
if [ $? -ne 0 ]; then
tst_res TFAIL "crontab failed removing cron job: `cat $out`"
else
tst_res TPASS "crontab did not list any cron jobs"
fi
else
tst_res TFAIL "crontab failed removing cron job: `cat $out`"
fi
}
setup()
{
if [ "$SYSLOG_DAEMON" ]; then
status_daemon $SYSLOG_DAEMON
if [ $? -ne 0 ]; then
restart_daemon $SYSLOG_DAEMON
SYSLOG_STARTED=1
fi
fi
if [ "$CROND_DAEMON" ]; then
status_daemon $CROND_DAEMON
if [ $? -ne 0 ]; then
restart_daemon $CROND_DAEMON
CROND_STARTED=1
fi
fi
for f in /var/log/syslog /var/log/messages /var/log/cron /var/log/cron.log; do
[ -f "$f" ] && LOGS="$f $LOGS"
done
}
cleanup()
{
[ "$SYSLOG_STARTED" = "1" ] && stop_daemon $SYSLOG_DAEMON
[ "$CROND_STARTED" = "1" ] && stop_daemon $CROND_DAEMON
}
do_test()
{
case $1 in
1) install_cron_test;;
2) remove_cron_job_test;;
3) list_cron_jobs_test;;
esac
}
tst_run