#!/usr/bin/env expect
############################################################################
# Purpose: Test of Slurm functionality
#          Validate that mod QoS modifies the preempt QoS when using =,+=,
#          -=
############################################################################
# Copyright (C) 2014 SchedMD LLC
# Written by Nathan Yee <nyee32@schedmd.com>
#
# This file is part of Slurm, a resource management program.
# For details, see <https://slurm.schedmd.com/>.
# Please also read the included file: DISCLAIMER.
#
# Slurm 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.
#
# Slurm is distributed in the hope that it will 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 Slurm; if not, write to the Free Software Foundation, Inc.
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
############################################################################
source ./globals
source ./globals_accounting

set exit_code    0
set qos_test(0)  "test$test_id\_qos_0"
set qos_test(1)  "test$test_id\_qos_1"
set qos_test(2)  "test$test_id\_qos_2"
set qos_test(3)  "test$test_id\_qos_3"
set qos_test(4)  "test$test_id\_qos_4"
set access_err  0

set qos_names_str 0
foreach inx [array names qos_test] {
	if { $qos_names_str != 0 } {
		set qos_names_str "$qos_names_str,$qos_test($inx)"
	} else {
		set qos_names_str "$qos_test($inx)"
	}
}

proc reset_qos { } {
	global sacctmgr qos_main exit_code qos_test

	set removed 0
	spawn $sacctmgr -i mod qos $qos_test(0) set preempt=''
	expect {
		"Modified qos" {
			set removed 1
			exp_continue
		}
		timeout {
			fail "sacctmgr is not responding"
		}
		eof {
			wait
		}
	}

	if {$removed != 1} {
		log_error "qos $qos_test(0)\'s preempt qos were not removed"
		set exit_code 1
	}

}

proc _local_mod_qos { preempt_qos } {
	global sacctmgr exit_code qos_test

	set mod 0
	spawn $sacctmgr -i mod qos $qos_test(0) set preempt$preempt_qos
	expect {
		-re "Modified qos" {
			set mod 1
			exp_continue
		}
		timeout {
			fail "sacctmgr is not responding"
		}
		eof {
			wait
		}
	}

	if {$mod != 1} {
		log_error "QoS $qos_test(0) was not modified"
		set exit_code 1
	}
}

proc check_pre { preempt_qos } {
	global sacctmgr exit_code re_word_str qos_test

	set match 0
	spawn $sacctmgr show qos $qos_test(0) format=preempt%-80 --noheader
	expect {
		-re "$preempt_qos" {
			set match 1
			exp_continue
		}
		timeout {
			fail "sacctmgr is not responding"
		}
		eof {
			wait
		}
	}

	if {$match != 1} {
		log_error "preempted QoS do not match what is expected"
		set exit_code 1
	}
}

######################### Test Begins #########################

#
# Check that current user is root or SlurmUser
#
if {![is_super_user]} {
	skip "Test can only be ran as SlurmUser"
}

if {[get_config_param "AccountingStorageType"] ne "accounting_storage/slurmdbd"} {
	skip "Not using accounting_storage/slurmdbd"
}

# clean it up (and check to make sure we can do this test
remove_qos $qos_names_str
if {$access_err != 0} {
	skip "Not authorized to perform this test"
}

# Add a few QoS
add_qos $qos_names_str ""
if { $exit_code } {
	remove_qos $qos_names_str
	fail "Unable to add QOS ($qos_names_str)"
}

# Add a preempt qos with =
log_info "Add a preempt qos with ="
_local_mod_qos "=$qos_test(1)"
check_pre $qos_test(1)

# Now clear the preempt qos
reset_qos
check_pre " "

# Add multiple QoSs with =
log_info "Add multiple QoSs with ="
_local_mod_qos "=$qos_test(1),$qos_test(2)"
check_pre "$qos_test(1),$qos_test(2)"
reset_qos
check_pre " "

# Add multiple QoSs with +=
log_info "Add multiple QoSs with +="
_local_mod_qos "=$qos_test(1)"
_local_mod_qos "+=$qos_test(2)"
check_pre "$qos_test(1),$qos_test(2)"
_local_mod_qos "+=$qos_test(3),$qos_test(4)"
check_pre "$qos_test(1),$qos_test(2),$qos_test(3),$qos_test(4)"
reset_qos
check_pre " "

# Remove some of the QoS with -=
log_info "Add multiple QoSs with -="
_local_mod_qos "=$qos_test(1),$qos_test(2),$qos_test(3),$qos_test(4)"
check_pre "$qos_test(1),$qos_test(2),$qos_test(3),$qos_test(4)"
_local_mod_qos "-=$qos_test(2)"
check_pre "$qos_test(1),$qos_test(3),$qos_test(4)"
_local_mod_qos "-=$qos_test(4)"
check_pre "$qos_test(1),$qos_test(3)"
_local_mod_qos "-=$qos_test(1),$qos_test(3)"
check_pre " "

remove_qos $qos_names_str

if {$exit_code != 0} {
	fail "Test failed due to previous errors"
}
