1#!/bin/sh 2 3# Copyright (c) International Business Machines Corp., 2001 4# Copyright (c) 2017 Petr Vorel <pvorel@suse.cz> 5# 6# This program is free software; you can redistribute it and/or 7# modify it under the terms of the GNU General Public License as 8# published by the Free Software Foundation; either version 2 of 9# the License, or (at your option) any later version. 10# 11# This program is distributed in the hope that it would be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program; if not, write the Free Software Foundation, 18# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19# 20# Author: Manoj Iyer <manjo@mail.utexas.edu> 21 22TST_ID="cron_tests01" 23TST_CNT=3 24TST_TESTFUNC=do_test 25TST_NEEDS_TMPDIR=1 26TST_SETUP=setup 27TST_CLEANUP=cleanup 28. tst_test.sh 29 30. daemonlib.sh 31 32SYSLOG_STARTED= 33CROND_STARTED= 34LOGS= 35 36grep_logs() 37{ 38 local pattern="$1" 39 local fail_msg="$2" 40 local pass_msg="${3:-}" 41 local n="${4:-10}" 42 43 local lines=10 44 local out=out.$$ 45 local err=err.$$ 46 local i ret 47 48 for i in $(seq 1 $n); do 49 if [ "$LOGS" ]; then 50 tail -n $lines $LOGS | grep "$pattern" > $out 2> $err 51 else 52 journalctl -n $lines | grep "$pattern" > $out 2> $err 53 fi 54 ret=$? 55 [ $ret -eq 0 ] && break 56 sleep 1 57 done 58 59 if [ $ret -ne 0 ]; then 60 tst_res TFAIL "$fail_msg: `cat $err`" 61 else 62 [ "$pass_msg" ] && tst_res TPASS "$pass_msg" 63 fi 64} 65 66create_crontab() 67{ 68 local crontab=cronjob.cron 69 local script=$1 70 local out=out.$$ 71 72 tst_res TINFO "creating crontab: $script" 73 74 cat > $crontab <<EOF 75* * * * * $script 76EOF 77 78 tst_res TINFO "installing crontab file" 79 crontab $crontab > $out 2>&1 80 if [ $? -ne 0 ]; then 81 tst_brk TBROK "crontab: error while installing crontab file: `cat $out`" 82 return 1 83 fi 84 return 0 85} 86 87remove_crontab() 88{ 89 local out=out.$$ 90 tst_res TINFO "removing crontab file" 91 crontab -r > $out 2>&1 92 if [ $? -ne 0 ]; then 93 tst_brk TBROK "crontab: error while removing crontab file `cat $out`" 94 return 1 95 fi 96 return 0 97} 98 99create_hello_script() 100{ 101 local script=$1 102 103 cat > $script <<EOF 104#!/bin/sh 105echo "Hello Hell" 106exit 0 107EOF 108 chmod +x $script 109} 110 111install_cron_test() 112{ 113 local script=$PWD/cronprg.sh 114 local cron_out=$PWD/tst1_cron.out 115 local err=err.log 116 local sleep_sec 117 local ts_min1 ts_min2 fail 118 119 tst_res TINFO "test install cron job" 120 121 cat > $script <<EOF 122#! /bin/sh 123DATE=\`LC_ALL=C date\` 124echo "Hello Hell today is \$DATE" > $cron_out 2>&1 125exit 0 126EOF 127 chmod +x $script 128 129 create_crontab $script 2> $err 130 131 if [ $? -ne 0 ]; then 132 tst_brk TBROK "crontab: error while creating cron job: `cat $err`" 133 else 134 tst_res TINFO "cron job installed successfully" 135 fi 136 137 grep_logs 'crontab.*REPLACE' \ 138 "cron activity not recorded" \ 139 "cron activity logged" 140 141 # Sleep 3s after next minute since the loop below sleeps for 62 seconds, we 142 # should start this 5-iteration loop closely following the start of a 143 # minute. 144 sleep_sec=$((123-`date +%-S`)) 145 tst_res TINFO "sleep for ${sleep_sec}s" 146 sleep $sleep_sec 147 148 # $script executed by the cron job will record the date and time into file 149 # $cron_out. Get the minute recorded by the program, sleep to allow the cron 150 # job to update file after 1m, and check if the value is advanced by 1. 151 for i in $(seq 1 5); do 152 tst_res TINFO "loop: $i: start" 153 154 if [ ! -f "$cron_out" ]; then 155 tst_res TFAIL "loop $i: file $cron_out doesn't exist" 156 fail=1 157 break 158 fi 159 160 ts_min1=$(awk '{print $8}' $cron_out | awk -F: '{printf("%d", $2);}') 161 162 # wait for the cron job to update output file 163 sleep 62 164 165 # Check the time recorded in output file, this should be 1 minute ahead of 166 # what was recored earlier. 167 ts_min2=$(awk '{print $8}' $cron_out | awk -F: '{printf("%d", $2);}') 168 169 if [ "x${ts_min1}" = "x" ] || [ "x${ts_min2}" = "x" ]; then 170 tst_res TFAIL "loop $i: failed to get time: ts_min1: $ts_min1, ts_min2: $ts_min2" 171 fail=1 172 break 173 fi 174 175 [ $ts_min1 -eq 59 ] && ts_min1=0 || ts_min1=$(( $ts_min1+1 )) 176 177 if [ $ts_min2 -ne $ts_min1 ]; then 178 tst_res TFAIL "loop $i: failed to update every minute: expected: $ts_min1, received: $ts_min2" 179 fail=1 180 break 181 fi 182 done 183 184 if [ ! "$fail" ]; then 185 grep_logs "CMD ($script)" \ 186 "failed to install cron job installed and execute it" \ 187 "cron job installed and executed" 1 188 fi 189 190 remove_crontab 191} 192 193remove_cron_job_test() 194{ 195 local script=$PWD/cronprg.sh 196 197 tst_res TINFO "test remove cron job" 198 199 create_hello_script $script 200 create_crontab $script 201 202 grep_logs 'crontab.*REPLACE' \ 203 "crontab activity not recorded" 204 205 remove_crontab && grep_logs DELETE \ 206 "crontab activity not recorded" \ 207 "crontab removed the cron job" 1 208} 209 210list_cron_jobs_test() 211{ 212 local script=$PWD/cronprg.sh 213 local out=cron.out 214 215 tst_res TINFO "test list installed cron jobs" 216 217 create_hello_script $script 218 create_crontab $script 219 220 tst_res TINFO "crontab: listing cron jobs" 221 crontab -l | grep "$script" > $out 2>&1 || \ 222 tst_brk TBROK "crontab failed while listing installed cron jobs: `cat $out`" 223 224 remove_crontab 225 226 crontab -l > $out 2>&1 227 if [ $? -ne 0 ]; then 228 grep -q "no crontab for" $out 229 if [ $? -ne 0 ]; then 230 tst_res TFAIL "crontab failed removing cron job: `cat $out`" 231 else 232 tst_res TPASS "crontab did not list any cron jobs" 233 fi 234 else 235 tst_res TFAIL "crontab failed removing cron job: `cat $out`" 236 fi 237} 238 239setup() 240{ 241 if [ "$SYSLOG_DAEMON" ]; then 242 status_daemon $SYSLOG_DAEMON 243 if [ $? -ne 0 ]; then 244 restart_daemon $SYSLOG_DAEMON 245 SYSLOG_STARTED=1 246 fi 247 fi 248 249 if [ "$CROND_DAEMON" ]; then 250 status_daemon $CROND_DAEMON 251 if [ $? -ne 0 ]; then 252 restart_daemon $CROND_DAEMON 253 CROND_STARTED=1 254 fi 255 fi 256 257 for f in /var/log/syslog /var/log/messages /var/log/cron /var/log/cron.log; do 258 [ -f "$f" ] && LOGS="$f $LOGS" 259 done 260} 261 262cleanup() 263{ 264 [ "$SYSLOG_STARTED" = "1" ] && stop_daemon $SYSLOG_DAEMON 265 [ "$CROND_STARTED" = "1" ] && stop_daemon $CROND_DAEMON 266} 267 268do_test() 269{ 270 case $1 in 271 1) install_cron_test;; 272 2) remove_cron_job_test;; 273 3) list_cron_jobs_test;; 274 esac 275} 276 277tst_run 278