#!/usr/bin/env expect
############################################################################
# Purpose: Test federated job updates
#
# Reqs:    1. Using slurmdbd accounting storage type and is up
#          2. fed_slurm_base is defined in globals.local - set to directory that
#          has access to each federation configure (fedc1, fedc2, fedc3).
#          Eg.
#          fedr/slurm/ (src)
#          fedr/fed1/bin
#          fedr/fed1/sbin
#          fedr/fed1/etc
#          fedr/fed1/...
#          fedr/fed2/...
#          fedr/fed3/...
#          3. controllers are up and running.
#
# Output:  "TEST: #.#" followed by "SUCCESS" if test was successful, OR
#          "FAILURE: ..." otherwise with an explanation of the failure, OR
#          anything else indicates a failure mode that must be investigated.
############################################################################
# Copyright (C) 2017 SchedMD LLC.
# Written by Isaac Hartung <ihartung@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
source ./globals_federation

set test_id     "37.6"
set exit_code   0
set fed_name    "feda"
set file_in     "test$test_id.in"
set user_name   ""
set srun_job_cnt 0

set eol "\r\n"

print_header $test_id

#
# Check accounting config and bail if not found.
#
if { [test_account_storage] == 0 } {
	log_warn "This test can't be run without a usable AccountStorageType"
	exit 0
}

if { [string compare [check_accounting_admin_level] "Administrator"] } {
	log_warn "This test can't be run without being an Accounting administrator.\n \
	 	  Use: sacctmgr mod user \$USER set admin=admin."
	exit 0
}

proc modify {job_id constraint reg_ex error_message} {
	global fedc1 fed_slurm_base bin_sleep

	set my_scontrol "${fed_slurm_base}/$fedc1/bin/scontrol"
	set matches 0

	spawn $my_scontrol update jobid=$job_id clusterfeatures=$constraint
	expect {
		-re "$reg_ex" {
			incr matches
		}
		timeout {
			log_error "scontrol not responding"
			end_it 1
		}
		eof {
			wait
		}
	}
	if {![string match "" $reg_ex] && $matches != 1} {
		log_error "didn't match regex $reg_ex: $matches"
		end_it 1
	}

	$bin_sleep 3
}

proc modify_with_clusters {job_id constraint reg_ex error_message} {
	global fedc1 fed_slurm_base bin_sleep

	set my_scontrol "${fed_slurm_base}/$fedc1/bin/scontrol"
	set matches 0

	spawn $my_scontrol update jobid=$job_id clusters=$constraint
	expect {
		-re "$reg_ex" {
			incr matches
		}
		timeout {
			log_error "scontrol not responding"
			end_it 1
		}
		eof {
			wait
		}
	}
	if {![string match "" $reg_ex] && $matches != 1} {
		log_error "didn't match regex $reg_ex: $matches"
		end_it 1
	}

	$bin_sleep 3
}

proc sbatch {my_sbatch script constraint args} {

	global number bin_sleep node_count

	set job_id 0
	set command "$my_sbatch -N$node_count --exclusive --output=/dev/null \
		--error=/dev/null -t5 --wrap $script --cluster-constraint=$constraint"

	if {$args ne ""} {
		append command " $args"
	}
	spawn {*}$command
	expect {
		-re "Submitted batch job ($number)" {
			set job_id $expect_out(1,string)
		}
		timeout {
			log_error "sbatch not responding"
			end_it 1
		}
		eof {
			wait
		}
	}
	if {$job_id == 0} {
		log_error "batch submit failure"
		end_it 1
	}

	$bin_sleep 3
	return $job_id
}

proc verify {fed job_id pattern error_message} {
	global fed_slurm_base

	set matches 0
	set my_squeue "${fed_slurm_base}/$fed/bin/squeue"
	spawn $my_squeue -a --local -j $job_id --noheader \
		-Ostatecompact:.5,siblingsviable:.20,siblingsactive:.20
	expect {
		-re "\\s+$pattern" {
			incr matches
		}
		eof {
			wait
		}
	}
	if {$matches != 1} {
		log_error "$error_message"
		end_it 1
	}
}

proc cancel_all_jobs { } {
	global scancel user_name fedc1 fedc2 fedc3

	spawn $scancel -M$fedc1,$fedc2,$fedc3 --user $user_name
	expect {
		eof {
			wait
		}
	}
	sleep 5
}

proc cleanup { } {
	global scancel fed_name user_name bin_rm file_in fedc1 fedc2 fedc3
	global test_id bin_bash

	cancel_all_jobs
	exec $bin_rm -f $file_in
	exec $bin_bash -c "$bin_rm -f test$test_id*.out"

	return [delete_federations $fed_name];
}

proc end_it { exit_code } {
	global test_id
	cleanup
	if {$exit_code == 0} {
		print_success $test_id
	}
	exit $exit_code
}

#start test

if {[test_federation_setup]} {
	log_warn "WARNING: This test can't be run without fed_slurm_base,\
		fedc1, fedc2, fedc3 setup in globals.local."
	exit 0
}

if {[test_all_up]} {
	exit 0
}

set user_name [get_my_user_name]

# Remove existing setup
if {[cleanup] != 0} {
	log_error "failed to cleanup"
	end_it 1
}

# add clusters to federation
if {[setup_federation $fed_name]} {
	log_error "failed to setup federation"
	end_it 1
}

# get number of nodes per cluster
set node_count [available_nodes "" ""]

make_bash_script $file_in "env; $bin_sleep 300"


send_user "\n################################################################\n"
send_user "Setup cluster features"
send_user "\n################################################################\n"

set matches 0
set my_pid [spawn $sacctmgr -i modify cluster $fedc1 set features=fa]
expect {
	-re "Setting$eol" {
		incr matches
		exp_continue
	}
	-re "^\\s+Feature\\s+=\\s+fa" {
		incr matches
		exp_continue
	}
	-re "Modified cluster...$eol" {
		incr matches
		exp_continue
	}
	-re "^\\s+$fedc1$eol" {
		incr matches
		exp_continue
	}
	timeout {
		send_user "\nFAILURE: sacctmgr mod not responding\n"
		slow_kill $my_pid
		set exit_code 1
	}
	eof {
		wait
	}
}
if {$exit_code || $matches != 4} {
	send_user "$matches FAILURE: unexpected error.\n"
	end_it 1
}

set matches 0
set my_pid [spawn $sacctmgr -i modify cluster $fedc2 set features=fb]
expect {
	-re "Setting$eol" {
		incr matches
		exp_continue
	}
	-re "^\\s+Feature\\s+=\\s+fb" {
		incr matches
		exp_continue
	}
	-re "Modified cluster...$eol" {
		incr matches
		exp_continue
	}
	-re "^\\s+$fedc2$eol" {
		incr matches
		exp_continue
	}
	timeout {
		send_user "\nFAILURE: sacctmgr mod not responding\n"
		slow_kill $my_pid
		set exit_code 1
	}
	eof {
		wait
	}
}
if {$exit_code || $matches != 4} {
	send_user "$matches FAILURE: unexpected error.\n"
	end_it 1
}

set matches 0
set my_pid [spawn $sacctmgr -i modify cluster $fedc3 set features=fc]
expect {
	-re "Setting$eol" {
		incr matches
		exp_continue
	}
	-re "^\\s+Feature\\s+=\\s+fc" {
		incr matches
		exp_continue
	}
	-re "Modified cluster...$eol" {
		incr matches
		exp_continue
	}
	-re "^\\s+$fedc3$eol" {
		incr matches
		exp_continue
	}
	timeout {
		send_user "\nFAILURE: sacctmgr mod not responding\n"
		slow_kill $my_pid
		set exit_code 1
	}
	eof {
		wait
	}
}
if {$exit_code || $matches != 4} {
	send_user "$matches FAILURE: unexpected error.\n"
	end_it 1
}


set my_scontrol "${fed_slurm_base}/$fedc1/bin/scontrol"

set job_id 0
set script "\"sleep 300\""
set my_sbatch "${fed_slurm_base}/$fedc1/bin/sbatch"


send_user "\n################################################################\n"
send_user "Modify Feature of Running Job"
send_user "\n################################################################\n"
cancel_all_jobs

#first job

set job_id [sbatch $my_sbatch $script fa]

verify $fedc1 $job_id "R\\s+$fedc1\\s+$fedc1" "Job not running on designated cluster"

modify $job_id fb "Job is no longer pending execution for job $job_id" "allowed user to modify features of running job"

send_user "\n################################################################\n"
send_user "Test invalid feature"
send_user "\n################################################################\n"
#second job

set job_id [sbatch $my_sbatch $script fa]

verify $fedc1 $job_id "PD\\s+$fedc1\\s+$fedc1" "Job not running on designated cluster"

#invalid feature

modify $job_id invalid "Invalid cluster feature specification for job" "allowed invalid feature"

send_user "\n################################################################\n"
send_user "Move pending job to $fedc2 with feature fb"
send_user "\n################################################################\n"
modify $job_id fb "" "did not allow user to modify features of pending job"

set run_cluster [wait_for_fed_job $job_id RUNNING ""]
if {[string compare $run_cluster $fedc2]} {
	log_error "Job not running on $fedc2"
	end_it 1
}
verify $fedc1 $job_id "RV\\s+$fedc2\\s+$fedc2" "Job not revoked"
verify $fedc2 $job_id "R\\s+$fedc2\\s+$fedc2" "Job not running on designated cluster"

send_user "\n################################################################\n"
send_user "New job to fa, then move job to $fedc2,$fedc3. Runs on $fedc3"
send_user "\n################################################################\n"
#third job

set job_id [sbatch $my_sbatch $script fa]

modify $job_id "fb,fc" "" "did not allow user to modify features of pending job"

set run_cluster [wait_for_fed_job $job_id RUNNING ""]
if {[string compare $run_cluster $fedc3]} {
	log_error "Job not running on $fedc3"
	end_it 1
}
verify $fedc1 $job_id "RV\\s+$fedc2,$fedc3\\s+$fedc3" "Job not revoked"
verify $fedc3 $job_id "R\\s+$fedc2,$fedc3\\s+$fedc3" "Job not running on designated cluster"

send_user "\n################################################################\n"
send_user "New job to fa, then move job to $fedc3"
send_user "\n################################################################\n"
#fourth job

set job_id [sbatch $my_sbatch $script fa]

modify $job_id "fc" "" "did not allow user to modify features of pending job"

verify $fedc1 $job_id "RV\\s+$fedc3\\s+$fedc3" "Job not revoked"
verify $fedc3 $job_id "PD\\s+$fedc3\\s+NA" "Job not running on designated cluster"

send_user "\n################################################################\n"
send_user "Move job to $fedc1,$fedc3"
send_user "\n################################################################\n"
modify $job_id "fa,fc" "" "did not allow user to modify features of pending job"

verify $fedc1 $job_id "PD\\s+$fedc1,$fedc3\\s+$fedc1,$fedc3" "Job not running on designated cluster"
verify $fedc2 $job_id ".+Invalid.+" "Job found on wrong cluster"
verify $fedc3 $job_id "PD\\s+$fedc1,$fedc3\\s+NA" "Job found on wrong cluster"

send_user "\n################################################################\n"
send_user "Move job to $fedc1"
send_user "\n################################################################\n"
modify $job_id "fa" "" "did not allow user to modify features of pending job"

verify $fedc1 $job_id "PD\\s+$fedc1\\s+$fedc1" "Job not running on designated cluster"
verify $fedc2 $job_id ".+Invalid.+" "Job found on wrong cluster"
verify $fedc3 $job_id ".+Invalid.+" "Job found on wrong cluster"

send_user "\n################################################################\n"
send_user "Clear features. Should go to pending on $fedc1,$fedc2,$fedc3"
send_user "\n################################################################\n"
#Clear Features

modify $job_id "" "" "did not allow user to modify features of pending job"

verify $fedc1 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+$fedc1,$fedc2,$fedc3" "Job not running on designated cluster"
verify $fedc2 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+NA" "Job not running on designated cluster"
verify $fedc3 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+NA" "Job not running on designated cluster"

send_user "\n################################################################\n"
send_user "Modify Feature of Held Job"
send_user "\n################################################################\n"
cancel_all_jobs

set job_id [sbatch $my_sbatch $script fa -H]

verify $fedc1 $job_id "PD\\s+$fedc1\\s+$fedc1" "Job not running on designated cluster"
verify $fedc2 $job_id ".+Invalid.+" "Job found on wrong cluster"
verify $fedc3 $job_id ".+Invalid.+" "Job found on wrong cluster"

modify $job_id "fb,fc" "" "did not allow user to modify features of pending job"

verify $fedc1 $job_id "RV\\s+$fedc2,$fedc3\\s+NA" "Job not running on designated cluster"
verify $fedc2 $job_id ".+Invalid.+" "Job found on wrong cluster"
verify $fedc3 $job_id ".+Invalid.+" "Job found on wrong cluster"

modify $job_id "" "" "did not allow user to modify features of pending job"

verify $fedc1 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+NA" "Job not running on designated cluster"
verify $fedc2 $job_id ".+Invalid.+" "Job found on wrong cluster"
verify $fedc3 $job_id ".+Invalid.+" "Job found on wrong cluster"

modify $job_id "fc" "" "did not allow user to modify features of pending job"

verify $fedc1 $job_id "PD\\s+$fedc3\\s+NA" "Job not running on designated cluster"
verify $fedc2 $job_id ".+Invalid.+" "Job found on wrong cluster"
verify $fedc3 $job_id ".+Invalid.+" "Job found on wrong cluster"

set my_scontrol "${fed_slurm_base}/$fedc1/bin/scontrol"

send_user "releasing job\n"

exec $my_scontrol release $job_id

sleep 3

set run_cluster [wait_for_fed_job $job_id RUNNING ""]
if {[string compare $run_cluster $fedc3]} {
	log_error "Job not running on $fedc3"
	end_it 1
}
verify $fedc1 $job_id "RV\\s+$fedc3\\s+$fedc3" "Job not running on designated cluster"
verify $fedc2 $job_id ".+Invalid.+" "Job found on wrong cluster"
verify $fedc3 $job_id "R\\s+$fedc3\\s+$fedc3" "Job found on wrong cluster"

send_user "\n################################################################\n"
send_user "Test Clearing Features"
send_user "\n################################################################\n"

cancel_all_jobs

#fill up clusters with jobs

sbatch $my_sbatch $script fa
sbatch $my_sbatch $script fb
sbatch $my_sbatch $script fc

#add pending job

set job_id [sbatch $my_sbatch $script "" --requeue]

verify $fedc1 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+$fedc1,$fedc2,$fedc3" "Job not running on designated cluster"
verify $fedc2 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+NA" "Job not running on designated cluster"
verify $fedc3 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+NA" "Job not running on designated cluster"

modify $job_id "fa" "" "did not allow user to modify features of pending job"

verify $fedc1 $job_id "PD\\s+$fedc1\\s+$fedc1" "Job not running on designated cluster"
verify $fedc2 $job_id ".+Invalid.+" "Job found on wrong cluster"
verify $fedc3 $job_id ".+Invalid.+" "Job found on wrong cluster"

modify $job_id "" "" "did not allow user to modify features of pending job"

verify $fedc1 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+$fedc1,$fedc2,$fedc3" "Job not running on designated cluster"
verify $fedc2 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+NA" "Job not running on designated cluster"
verify $fedc3 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+NA" "Job not running on designated cluster"

send_user "\n################################################################\n"
send_user "Modify Federation Cluster Features"
send_user "\n################################################################\n"
cancel_all_jobs

sbatch $my_sbatch $script fa
sbatch $my_sbatch $script fb
sbatch $my_sbatch $script fc

set job_id [sbatch $my_sbatch $script ""]

verify $fedc1 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+$fedc1,$fedc2,$fedc3" "Job not running on designated cluster"
verify $fedc2 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+NA" "Job not running on designated cluster"
verify $fedc3 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+NA" "Job not running on designated cluster"

modify_with_clusters $job_id "$fedc1" "" "did not allow user to modify features of pending job"

verify $fedc1 $job_id "PD\\s+$fedc1\\s+$fedc1" "Job not running on designated cluster"
verify $fedc2 $job_id ".+Invalid.+" "Job found on wrong cluster"
verify $fedc3 $job_id ".+Invalid.+" "Job found on wrong cluster"

modify_with_clusters $job_id "$fedc1,$fedc2" "" "did not allow user to modify features of pending job"

verify $fedc1 $job_id "PD\\s+$fedc1,$fedc2\\s+$fedc1,$fedc2" "Job not running on designated cluster"
verify $fedc2 $job_id "PD\\s+$fedc1,$fedc2\\s+NA" "Job not running on designated cluster"
verify $fedc3 $job_id ".+Invalid.+" "Job found on wrong cluster"

modify_with_clusters $job_id "$fedc2" "" "did not allow user to modify features of pending job"

verify $fedc1 $job_id "RV\\s+$fedc2\\s+$fedc2" "Job not running on designated cluster"
verify $fedc2 $job_id "PD\\s+$fedc2\\s+NA" "Job not running on designated cluster"
verify $fedc3 $job_id ".+Invalid.+" "Job found on wrong cluster"

modify_with_clusters $job_id "" "" "did not allow user to modify features of pending job"

verify $fedc1 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+$fedc1,$fedc2,$fedc3" "Job not running on designated cluster"
verify $fedc2 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+NA" "Job not running on designated cluster"
verify $fedc3 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+NA" "Job not running on designated cluster"

#this one shows that the $fedc1 is routing the update from $fedc1 to $fedc2

send_user "\n################################################################\n"
send_user "$fedc1 routing the update from $fedc1 to $fedc2"
send_user "\n################################################################\n"

set job_id [sbatch $my_sbatch $script "" -M$fedc2]

verify $fedc2 $job_id "PD\\s+$fedc2\\s+$fedc2" "Job not running on designated cluster"
verify $fedc1 $job_id ".+Invalid.+" "Job found on wrong cluster"
verify $fedc3 $job_id ".+Invalid.+" "Job found on wrong cluster"

modify_with_clusters $job_id "$fedc1" "" "did not allow user to modify features of pending job"

verify $fedc2 $job_id "RV\\s+$fedc1\\s+$fedc1" "Job not running on designated cluster"
verify $fedc1 $job_id "PD\\s+$fedc1\\s+NA" "Job not running on designated cluster"
verify $fedc3 $job_id ".+Invalid.+" "Job found on wrong cluster"

modify_with_clusters $job_id "" "" "did not allow user to modify features of pending job"

verify $fedc2 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+$fedc1,$fedc2,$fedc3" "Job not running on designated cluster"
verify $fedc1 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+NA" "Job not running on designated cluster"
verify $fedc3 $job_id "PD\\s+$fedc1,$fedc2,$fedc3\\s+NA" "Job not running on designated cluster"

#Federations and clusterfeatures ($fedc1 and fb - so the job is not eligible
#				  anywhere beacause it can't have both)

send_user "\n################################################################\n"
send_user "Federations and ClusterFeatures"
send_user "\n################################################################\n"


modify_with_clusters $job_id "$fedc1" "" "did not allow user to modify features of pending job"

verify $fedc2 $job_id "RV\\s+$fedc1\\s+$fedc1" "Job not running on designated cluster"
verify $fedc1 $job_id "PD\\s+$fedc1\\s+NA" "Job not running on designated cluster"
verify $fedc3 $job_id ".+Invalid.+" "Job found on wrong cluster"

modify $job_id "fb" "" "did not allow user to modify features of pending job"

verify $fedc2 $job_id "RV\\s+NA\\s+NA" "Job not running on designated cluster"
verify $fedc1 $job_id ".+Invalid.+" "Job found on wrong cluster"
verify $fedc3 $job_id ".+Invalid.+" "Job found on wrong cluster"

modify $job_id "fa" "" "did not allow user to modify features of pending job"

verify $fedc2 $job_id "RV\\s+$fedc1\\s+$fedc1" "Job not running on designated cluster"
verify $fedc1 $job_id "PD\\s+$fedc1\\s+NA" "Job not running on designated cluster"
verify $fedc3 $job_id ".+Invalid.+" "Job found on wrong cluster"

send_user "\n################################################################\n"
send_user "Federations and Negative ClusterFeatures"
send_user "\n################################################################\n"

cancel_all_jobs

set jid(0) [sbatch $my_sbatch $script !fc,fb]
set jid(1) [sbatch $my_sbatch $script !fa,fc]
set jid(2) [sbatch $my_sbatch $script !fb,fa]

verify $fedc1 $jid(0) "R\\s+$fedc1\\s+$fedc1" "Job not running on designated cluster"
verify $fedc2 $jid(1) "R\\s+$fedc2\\s+$fedc2" "Job not running on designated cluster"
verify $fedc3 $jid(2) "R\\s+$fedc3\\s+$fedc3" "Job not running on designated cluster"

#submit pending job on all clusters then move around using negative constraints.

set jid(4) [sbatch $my_sbatch $script ""]

verify $fedc1 $jid(4) "PD\\s+$fedc1,$fedc2,$fedc3\\s+$fedc1,$fedc2,$fedc3" "Job not running on designated cluster"
verify $fedc2 $jid(4) "PD\\s+$fedc1,$fedc2,$fedc3\\s+NA" "Job not running on designated cluster"
verify $fedc3 $jid(4) "PD\\s+$fedc1,$fedc2,$fedc3\\s+NA" "Job not running on designated cluster"

modify $jid(4) "!fb" "" "did not allow user to modify features of pending job"

verify $fedc2 $jid(4) ".+Invalid.+" "Job found on wrong cluster"
verify $fedc1 $jid(4) "PD\\s+$fedc1,$fedc3\\s+" "Job not running on designated cluster"
verify $fedc3 $jid(4) "PD\\s+$fedc1,$fedc3\\s+" "Job not running on designated cluster"

modify $jid(4) "!fc" "" "did not allow user to modify features of pending job"

verify $fedc2 $jid(4) "PD\\s+$fedc1,$fedc2\\s+" "Job not running on designated cluster"
verify $fedc1 $jid(4) "PD\\s+$fedc1,$fedc2\\s+" "Job not running on designated cluster"
verify $fedc3 $jid(4) ".+Invalid.+" "Job found on wrong cluster"

modify $jid(4) "!fa" "" "did not allow user to modify features of pending job"

verify $fedc1 $jid(4) "RV\\s+$fedc2,$fedc3\\s+" "Job found on wrong cluster"
verify $fedc2 $jid(4) "PD\\s+$fedc2,$fedc3\\s+" "Job not running on designated cluster"
verify $fedc3 $jid(4) "PD\\s+$fedc2,$fedc3\\s+" "Job not running on designated cluster"

modify $jid(4) "!fb,fc" "" "did not allow user to modify features of pending job"

verify $fedc2 $jid(4) ".+Invalid.+" "Job found on wrong cluster"
verify $fedc1 $jid(4) "PD\\s+$fedc1\\s+" "Job not running on designated cluster"
verify $fedc3 $jid(4) ".+Invalid.+" "Job found on wrong cluster"

modify $jid(4) "!fa,fc" "" "did not allow user to modify features of pending job"

verify $fedc1 $jid(4) "RV\\s+$fedc2\\s+$fedc2" "Job found on wrong cluster"
verify $fedc2 $jid(4) "PD\\s+$fedc2\\s+" "Job not running on designated cluster"
verify $fedc3 $jid(4) ".+Invalid.+" "Job found on wrong cluster"

modify $jid(4) "!fb,fa" "" "did not allow user to modify features of pending job"

verify $fedc2 $jid(4) ".+Invalid.+" "Job found on wrong cluster"
verify $fedc3 $jid(4) "PD\\s+$fedc3\\s+" "Job not running on designated cluster"
verify $fedc1 $jid(4) "RV\\s+$fedc3\\s+$fedc3" "Job found on wrong cluster"

#clear features again

modify $jid(4) "" "" "did not allow user to modify features of pending job"

verify $fedc1 $jid(4) "PD\\s+$fedc1,$fedc2,$fedc3\\s+$fedc1,$fedc2,$fedc3" "Job not running on designated cluster"
verify $fedc2 $jid(4) "PD\\s+$fedc1,$fedc2,$fedc3\\s+NA" "Job not running on designated cluster"
verify $fedc3 $jid(4) "PD\\s+$fedc1,$fedc2,$fedc3\\s+NA" "Job not running on designated cluster"

#submit pending jobs to single cluster using negative constraints.

set jid(0) [sbatch $my_sbatch $script !fc,fb]

wait_for_fed_job $jid(0) PENDING $fedc1

verify $fedc2 $jid(0) ".+Invalid.+" "Job found on wrong cluster"
verify $fedc1 $jid(0) "PD\\s+$fedc1\\s+$fedc1" "Job not running on designated cluster"
verify $fedc3 $jid(0) ".+Invalid.+" "Job found on wrong cluster"

set jid(0) [sbatch $my_sbatch $script !fa,fb]

sleep 5

verify $fedc2 $jid(0) ".+Invalid.+" "Job found on wrong cluster"
verify $fedc3 $jid(0) "PD\\s+$fedc3\\s+NA" "Job not running on designated cluster"
verify $fedc1 $jid(0) "RV\\s+$fedc3\\s+$fedc3" "Job found on wrong cluster"

set jid(0) [sbatch $my_sbatch $script !fc,fa]

sleep 5

verify $fedc1 $jid(0) "RV\\s+$fedc2\\s+$fedc2" "Job found on wrong cluster"
verify $fedc2 $jid(0) "PD\\s+$fedc2\\s+NA" "Job not running on designated cluster"
verify $fedc3 $jid(0) ".+Invalid.+" "Job found on wrong cluster"

#error test--negate all clusters.

set matches 0

set command "$my_sbatch -N$node_count --exclusive --output=/dev/null \
	--error=/dev/null -t5 --wrap $script --cluster-constraint=!fa,fb,fc"
spawn {*}$command
expect {
	-re ".+Invalid cluster feature specification" {
		incr matches
	}
	timeout {
		log_error "sbatch not responding"
		end_it 1
	}
	eof {
		wait
	}
}

if {$matches != 1} {
	log_error "batch submit failure"
	end_it 1
}

# All Done
end_it 0
