#!/bin/sh
#
# Copyright (C) 2000-2023 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
# Test different cancel cases
# Can be quite long

#
TestName="cancel-test"
JobName=backup
. scripts/functions

scripts/cleanup
scripts/copy-confs

#
# Zap out any schedule in default conf file so that
#  it doesn't start during our test
#
outf="tmp/sed_tmp"
echo "s%  Schedule =%# Schedule =%g" >$outf
cp ${cwd}/bin/bacula-dir.conf ${cwd}/tmp/1
sed -f ${outf} ${cwd}/tmp/1 >${cwd}/bin/bacula-dir.conf

if [ "$FORCE_DEDUP" = yes ]; then
    MAXVOLBYTES=5KB
else
    MAXVOLBYTES=1MB
fi

touch tmp/log1.out

# Add some jobs and fileset for this test
cat <<EOF >>${cwd}/bin/bacula-dir.conf
FileSet {
  Name = FS_ERR
  Include {
    Options {
      signature = MD5
    }
    file = "\\</path/to/nowhere"
  }
}
Job {
  Name = RUN_ERR1
  ClientRunBeforeJob = "/bin/false"
  JobDefs = DefaultJob
}
Job {
  Name = RUN_ERR2
  RunScript {
    Command = "/bin/false"
    RunsWhen = Before
  }
  JobDefs = DefaultJob
}
Job {
  Name = RUN_ERR3
  ClientRunBeforeJob="/bin/sleep 10"
  RunScript {
    Command = "/bin/sleep 600"
    Command = "touch $tmp/RUN_ERR3.after.%i"
    RunsWhen = After
    RunsOnFailure = Yes
  }
  JobDefs = DefaultJob
}
Job {
  Name = RUN_ERR4
  ClientRunBeforeJob="/bin/sleep 10"
  RunScript {
    Command = "touch $tmp/RUN_ERR4.after"
    Command = "/bin/sleep 40"
    RunsWhen = After
    RunsOnFailure = Yes
  }
  JobDefs = DefaultJob
}
EOF

change_jobname BackupClient1 $JobName
start_test

when=`perl -MPOSIX -e "print strftime('%F %T', localtime(time+6000))"`

cat <<END_OF_DATA >${cwd}/tmp/bconcmds
@output /dev/null
messages
setbandwidth limit="500 kb/s" client
@$out ${cwd}/tmp/logfile1.out
@################################################################
@# run a first test without volume
@# Expect: duration < 60
@################################################################
run job=$JobName yes
@sleep 5
messages
cancel
yes
wait
messages
@$out ${cwd}/tmp/logfile2.out
@################################################################
@# run test with a small volume
@# Expect: duration < 60
@################################################################
label volume=TestVolume001 storage=File1 drive=0 slot=0 pool=Default
update volume=TestVolume001 MaxVolBytes=$MAXVOLBYTES
run job=$JobName yes
@sleep 5
messages
st dir
cancel
yes
wait
messages
@$out ${cwd}/tmp/logfile3.out
@################################################################
@# run test with 2 jobs in // (limit 1)
@# expect that the second job don't stay in the list
@# Expect: Job2 not present at the end
@################################################################
label volume=TestVolume002 storage=File1 drive=0 slot=0 pool=Default
run job=$JobName yes
@sleep 1
messages
run job=$JobName yes
@sleep 1
messages
st dir
cancel jobid=4
@sleep 1
st dir
cancel jobid=3
@sleep 1
st dir
wait
messages
@$out ${cwd}/tmp/logfile4.out
@################################################################
@# test with a broken fileset
@# Expect: duration < 20s
@################################################################
run job=$JobName fileset=FS_ERR yes
@sleep 3
messages
st dir
wait
messages
@$out ${cwd}/tmp/logfile5.out
@################################################################
@# test with a broken runscript
@# Expect: duration < 20s
@################################################################
run job=RUN_ERR1 yes
@sleep 3
messages
st dir
wait
messages
@$out ${cwd}/tmp/logfile6.out
@################################################################
@# test with a broken runscript
@# Expect: duration < 20s
@################################################################
run job=RUN_ERR2 yes
@sleep 3
messages
st dir
wait
messages
@$out ${cwd}/tmp/logfile7.out
@################################################################
@# test with a broken runscript and a very long AfterJob
@# we break the backup during the ClientRunBeforeJob
@# Expect: duration > 550
@################################################################
run job=RUN_ERR3 yes
@sleep 5
messages
st dir
cancel
yes
@sleep 5
messages
st dir
wait
messages
@$out ${cwd}/tmp/logfile8.out
@################################################################
@# test with a broken runscript and a very long AfterJob
@# we break the backup during the ClientRunAfterJob
@# Expect: duration > 550
@#         print sleep 600
@################################################################
run job=RUN_ERR3 yes
@sleep 20
messages
st dir
cancel
yes
@sleep 5
messages
st dir
wait
messages
@$out ${cwd}/tmp/logfile9.out
@################################################################
@# test with a broken runscript and a very long AfterJob
@# we break the backup during the backup
@# Expect: duration > 550
@#         print sleep 600
@################################################################
update volume=TestVolume002 volstatus=Used
label volume=TestVolume003 storage=File1 drive=0 slot=0 pool=Default
update volume=TestVolume003 MaxVolBytes=1MB
run job=RUN_ERR3 yes
@sleep 20
messages
st dir
cancel
yes
@sleep 5
messages
st dir
wait
messages
@$out ${cwd}/tmp/logfile10.out
@################################################################
@# test with a broken runscript and a short AfterJob
@# we break the backup during the backup
@# Expect: print sleep 40
@################################################################
update volume=TestVolume003 volstatus=Used
label volume=TestVolume004 storage=File1 drive=0 slot=0 pool=Default
update volume=TestVolume004 MaxVolBytes=1MB
run job=RUN_ERR4 yes
@sleep 20
messages
st dir
time
cancel
yes
@sleep 5
messages
st dir
wait
time
messages
@$out ${cwd}/tmp/logfile11.out
@################################################################
@# Test to cancel the job immediately
@# Expect: duration < 30
@################################################################
label volume=TestVolume005 storage=File1 drive=0 slot=0 pool=Default
run job=$JobName yes
time
cancel
yes
@sleep 5
messages
st dir
wait
time
messages
@$out ${cwd}/tmp/logfile12.out
@################################################################
@# Test to cancel the job before it starts
@# Expect: 
@################################################################
run job=$JobName when="$when" yes
@sleep 5
st dir
cancel
yes
time
@sleep 5
messages
st dir
wait
time
messages
@$out ${cwd}/tmp/logfile20.out
@################################################################
@# test with a broken connexion between DIR/FD
@# the test will run a job that will stop, and we send
@# the STOP signal to the FD process
@# Expect: duration < 400
@################################################################
update volume=TestVolume005 volstatus=Used
label volume=TestVolume006 storage=File1 drive=0 slot=0 pool=Default
update volume=TestVolume006 MaxVolBytes=1MB
run job=$JobName yes
@sleep 5
messages
quit
END_OF_DATA

run_bacula

print_debug "Stopping FD"
# stop the bacula-fd and cancel the job
pid=`cat $working/bacula-fd.*.pid`
kill -STOP $pid

cat <<END_OF_DATA >${cwd}/tmp/bconcmds
@$out ${cwd}/tmp/logfile20.out
@sleep 3
messages
st dir
cancel
yes
st dir
wait
messages
quit
END_OF_DATA

run_bconsole

kill -CONT $pid

check_for_zombie_jobs storage=File1
stop_bacula

# A fileset or runscript error goes fast
check_duration $tmp/logfile1.out 30
check_duration $tmp/logfile3.out 30
check_duration $tmp/logfile4.out 30
check_duration $tmp/logfile5.out 30
check_duration $tmp/logfile6.out 30

check_duration $tmp/logfile8.out 550 lt
grep 'ClientAfterJob "/bin/sleep 600"' $tmp/logfile8.out >/dev/null
if [ $? -ne 0 ]; then
    print_debug "Can't find ClientAfterJob in $tmp/logfile8.out"
    if [ -f $tmp/RUN_ERR3.after.9 ]; then
        print_debug "No log found, but the $tmp/RUN_ERR3.after.9 was created"
    else
        print_debug "ERROR: No log found, AND the $tmp/RUN_ERR3.after.9 was not created"
    fi
    estat=2
fi

check_duration $tmp/logfile9.out 550 lt
grep 'ClientAfterJob "/bin/sleep 600"' $tmp/logfile9.out >/dev/null
if [ $? -ne 0 ]; then
    print_debug "Can't find ClientAfterJob in $tmp/logfile9.out"
    if [ -f $tmp/RUN_ERR3.after.10 ]; then
        print_debug "No log found, but the $tmp/RUN_ERR3.after.10 was created"
    else
        print_debug "ERROR: No log found, AND the $tmp/RUN_ERR3.after.10 was not created"
    fi
    estat=2
fi

grep 'ClientAfterJob "/bin/sleep 40"' $tmp/logfile10.out >/dev/null
if [ $? -ne 0 ]; then
    print_debug "Can't find ClientAfterJob in $tmp/logfile10.out"
    if [ -f $tmp/RUN_ERR4.after ]; then
        print_debug "No log found, but the $tmp/RUN_ERR4.after was created"
    else
        print_debug "ERROR: No log found, AND the $tmp/RUN_ERR4.after was not created..."
    fi
    estat=2
fi

# Verify the broken connection
check_duration $tmp/logfile20.out 400 lt

end_test
