#!/bin/sh
#
# Copyright (C) 2000-2026 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
# This script will test next vol algo with
# vtape
#
# TODO: Test Pool with RecyclePool
#       Test Pool without RecyclePool
#       Test with enabled=false
#       Test with recycle=no
#       Track scratch usage
#
# Please do not write any more tests with so many Jobs and combinations,
#  because when something goes wrong it is very hard and time consuming
#  to know what caused the failure.
#
. scripts/functions

# Dedup does not work with "tapes"
if test x$FORCE_DEDUP = xyes ; then
  echo "\n=== Test next-vol-test skipped not compatible with dedup  ==="
  exit 0
fi
if test x$FORCE_CLOUD = xyes ; then
  echo "\n=== Test next-vol-test skipped not compatible with Cloud  ==="
  exit 0
fi


TestName="next-vol-test"
JobName=backup

require_linux
scripts/cleanup
scripts/copy-tape-confs
cp scripts/bacula-dir-vtape.conf bin/bacula-dir.conf
cp scripts/bacula-sd-vtape.conf bin/bacula-sd.conf
scripts/prepare-fake-autochanger


start_test

cat <<EOF > ${cwd}/tmp/bconcmds
@$out ${cwd}/tmp/log.out
label barcodes storage=LTO3 slots=46-59 drive=0 pool=Scratch
yes
sql
update Media SET FirstWritten='2006-01-01 01:00:00', LastWritten='2006-01-01 01:00:00';

update volume=vol47 pool=Test inchanger=no RecyclePool=Test
update volume=vol59 pool=Test enabled=no
update volume=vol58 pool=Test volstatus=Recycle
purge  volume=vol57
update volume=vol56 pool=Test
update volume=vol55 pool=Test volstatus=Full
update volume=vol46 volstatus=Full volretention=15 
purge volume=vol46
update volume=vol46 pool=Test
update volume=vol54 volstatus=Recycle
purge  volume=vol53
update volume=vol52 MaxVolJobs=1 volretention=15
update volume=vol51 inchanger=no volstatus=Recycle
purge  volume=vol50
update volume=vol50 inchanger=no
update volume=vol49 inchanger=no
update volume=vol48 inchanger=no pool=Test
update volume  AllFromPool=Test
sql
update Media SET VolJobs=1 WHERE VolumeName='vol52';
update Media SET LastWritten='2006-01-01 01:00:01' WHERE VolumeName='vol57';
update Media SET LastWritten='2006-01-01 01:00:02' WHERE VolumeName='vol53';

list volumes
wait
quit
EOF

run_bacula

echo $PWD/build/po > tmp/file-list

cat <<EOF > ${cwd}/tmp/bconcmds
@$out ${cwd}/tmp/log2.out
@# Must choose vol56
@# Pool + Append + Enabled + InChanger
@# JobId=1
run level=full pool=Test NightlySave yes
wait
message
list volumes
@# Must choose vol58
@# Pool + Recycled + Enabled + InChanger
@# JobId=2
run level=full pool=Test NightlySave yes
wait
message
list volume
@# Must choose vol46
@# Pool + Purged + Enabled + InChanger
@# JobId=3
run level=full pool=Test NightlySave yes
wait
message
list volumes
@# Must choose vol55
@# Pool + Full + Recycle + Enabled + InChanger
@# JobId=4
run level=full pool=Test NightlySave yes
wait
message
list volumes
@# Must choose vol54
@# No more in Test pool, get from scratch
@# vol52 is Append, but have 1 job and MaxJob
@# Scratch + Recycle + Enabled + InChanger
@# JobId=5
run level=full pool=Test NightlySave yes
wait
message
list volume
@# Must choose vol52
@# Scratch + Purged + Enabled + InChanger + LastW
@# JobId=6
run level=Full pool=Test NightlySave yes
wait
message
list volume
@# Must choose vol57
@# Scratch + Purged + Enabled + InChanger + LastW
@# JobId=7
run level=full pool=Test NightlySave yes
wait
message
list volumes
@# Must choose vol53
@# Scratch + Purged + Enabled + InChanger + LastW
@# JobId=8
run level=full pool=Test NightlySave yes
wait
messages
list volumes
@# JobId=9
restore fileset="Full Set" pool=Test where=${cwd}/tmp/bacula-restores select all done
1
yes
wait
messages
wait
messages
@# Must Wait
@#run level=full pool=Test NightlySave yes
@#wait
@#message
@#list volume
quit
EOF

run_bconsole

awk '/Must choose/ { print $4 } '    tmp/log2.out > tmp/normal
awk '/Volume name.+:/ { print $3 } ' tmp/log2.out > tmp/real
if [ "$debug" -eq 1 ]; then
   diff -ur tmp/normal tmp/real
else
   diff tmp/normal tmp/real > /dev/null
fi
dstat=$?


# so some tests with File media
cat <<EOF > ${cwd}/tmp/bconcmds
@$out ${cwd}/tmp/log3.out
label volume=file1 storage=File pool=Test
label volume=file2 storage=File pool=Test
label volume=file3 storage=File pool=Test
label volume=file4 storage=File pool=Scratch
label volume=file5 storage=File pool=Test
label volume=file6 storage=File pool=Test
label volume=file7 storage=File pool=Scratch
label volume=file8 storage=File pool=Test
label volume=file9 storage=File pool=Scratch
label volume=file10 storage=File pool=Scratch
label volume=file11 storage=File pool=Test
sql
update Media SET FirstWritten='2006-01-01 01:00:00', LastWritten='2006-01-01 01:00:00';

update volume=file2 enabled=no
update volume=file3 volstatus=Recycle
@# volstatus=Purged
purge  volume=file4
update volume=file5 recycle=no volretention=1
update volume=file6 volstatus=Full volretention=15 
update volume=file7 volstatus=Full volretention=15 
purge volume=file7
update volume=file8 pool=Test VolRetention=1
update volume=file9 volstatus=Recycle
purge volume=file11
sql
update Media SET VolJobs=1 WHERE VolumeName='file9';
update Media SET LastWritten='2006-01-01 01:00:01' WHERE VolumeName='file4';
update Media SET LastWritten='2006-01-01 01:00:02' WHERE VolumeName='file7';

messages
@$out ${cwd}/tmp/log4.out
list volume
messages
@# Must choose file1
@# Pool + Append + Lowest MediaId
@# JobId=10
run level=full pool=Test storage=File NightlySave yes
wait
message
list volume
@# Must choose file5
@# Pool + Append + Lowest MediaId (only once)
@# JobId=11
run level=full pool=Test storage=File NightlySave yes
wait
message
list volume
@# Must choose file8
@# Pool + Append + Lowest MediaId
@# JobId=12
run level=full pool=Test storage=File NightlySave yes
wait
message
list volume
@# Must choose file3
@# Pool + Recycle
@# JobId=13
run level=full pool=Test storage=File NightlySave yes
wait
message
list volume
@# Must choose file11
@# Pool + Purged
@# JobId=14
run level=full pool=Test storage=File NightlySave yes
wait
message
list volume
@# Must choose file6
@# Pool + Full (prunable)
setdebug level=50 director
@# JobId=15
run level=full pool=Test storage=File NightlySave yes
wait
message
setdebug level=0 director
list volume
@sleep 5
@# Must choose file8
@# Pool + Full (prunable)
@# JobId=16
run level=full pool=Test storage=File NightlySave yes
wait
message
update volume=file8 enabled=no
list volume
@# Must choose file10
@# (no more Pool) Scratch + Append
@# JobId=17
run level=full pool=Test storage=File NightlySave yes
wait
message
list volume
@# Must choose file9
@# (no more Pool) Scratch + Recycle
@# JobId=18
run level=full pool=Test storage=File NightlySave yes
wait
message
list volume
@sleep 10
@# Must choose file6
@# Used (prunable) + Pool
@# JobId=19
run level=full pool=Test storage=File NightlySave yes
wait
message
list volume
@# Must choose file4
@# Used (prunable) + oldest + Scratch
run level=full pool=Test storage=File NightlySave yes
wait
message
list volume
@# Must choose file7
@# Used (prunable) + oldest + Scratch
@# JobId=20
run level=full pool=Test storage=File NightlySave yes
wait
message
list volume
wait
quit
EOF

run_bconsole

awk '/Must choose/ { print $4 } '    tmp/log4.out > tmp/normal4
awk '/Volume name.+:/ { print $3 } ' tmp/log4.out > tmp/real4
if [ "$debug" -eq 1 ]; then
   diff -ur tmp/normal4 tmp/real4
else
   diff tmp/normal4 tmp/real4 > /dev/null
fi
if [ $dstat -eq 0 ] ; then
   dstat=$?
   if [ $dstat -ne 0 ] ; then
      echo "normal4 and real4 differ!!!!!"
      echo "normal4 and real4 differ!!!!!"  >>test.out
   fi
fi

# try to break the old code 
# in this situation, we have 1 available volume (vol50) and bacula will try to use
# vol47, vol48 and vol49 and will stop without using vol50.

cat <<EOF > ${cwd}/tmp/bconcmds
@$out ${cwd}/tmp/log1.out
update volume=vol47 pool=Test VolStatus=Used VolRetention=10s inchanger=no RecyclePool=Test
update volume=vol48 pool=Test VolStatus=Used VolRetention=10s inchanger=no RecyclePool=Test
update volume=vol49 pool=Test VolStatus=Used VolRetention=10s inchanger=no RecyclePool=Test
update volume=vol50 pool=Test VolStatus=Used VolRetention=10s inchanger=yes RecyclePool=Test
sql
update Media SET FirstWritten='2005-01-01 01:00:00', LastWritten='2005-01-01 01:00:00' 
WHERE VolumeName IN ('vol47', 'vol48', 'vol49');

list volume
@# JobId=21
run level=full pool=Test NightlySave yes
wait
messages
quit
EOF

run_bconsole
grep "Invalid slot=0 defined in catalog for Volume" tmp/log1.out > /dev/null
if [ $? -ne 0 ]; then
   bstat=$?
fi

check_for_zombie_jobs storage=LTO3 client=${HOST}-fd
stop_bacula

check_two_logs

end_test
