#!/usr/bin/env expect
############################################################################
# Purpose: Test of Slurm functionality
#          sacctmgr add a coordinator
############################################################################
# Copyright (C) 2008-2010 Lawrence Livermore National Security.
# Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
# Written by Joseph Donaghy <donaghy1@llnl.gov>
# CODE-OCEC-09-009. All rights reserved.
#
# 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_accounting

set test_nu     "test21-19"
set exit_code   0
set clu		cluster
set tc1		[format "%s%s" $test_nu "clus1"]
set tc2		[format "%s%s" $test_nu "clus2"]
set tc3		[format "%s%s" $test_nu "clus3"]
set fs1		2500
set fs2		1700
set fs3		1
set mc1		1000000
set mc2		700000
set mc3		1
set mj1		50
set mj2		70
set mj3		1
set mn1		300
set mn2		700
set mn3		1
set mw1		01:00:00
set mw2		00:07:00
set mw3		00:01:00
set acc		account
set nams	names
set nm1		[format "%s%s" $test_nu "acct1"]
set nm2		[format "%s%s" $test_nu "acct2"]
set nm3		[format "%s%s" $test_nu "acct3"]
set des		Description
set ds1		testaccounta1
set ds2		testacct
set org		Organization
set or1		accountorga1
set or2		acttrg
set qs		QosLevel
set qs1		normal
set par		parent
set usr		user
set us1         [format "%s%s" $test_nu "user1"]
set us2         [format "%s%s" $test_nu "user2"]
set us3         [format "%s%s" $test_nu "user3"]
set al		AdminLevel
set aln		None
set ala		Administrator
set alo		Operator
set dac		DefaultAccount
set pts		Partitions
set fs		fairshare
set mc		maxcpu
set mj		maxjob
set mn		maxnode
set mw		maxwall
set dbu		debug
set access_err  0

# Cluster
array set clus_req {}

# Accounts
array set acct_req {}
set acct_req(cluster) [format "%s%s" $test_nu "clus1"],[format "%s%s" $test_nu "clus2"],[format "%s%s" $test_nu "clus3"]

# User
array set user_req {}
set user_req(cluster) [format "%s%s" $test_nu "clus1"],[format "%s%s" $test_nu "clus2"],[format "%s%s" $test_nu "clus3"]
set user_req(account) [format "%s%s" $test_nu "acct1"],[format "%s%s" $test_nu "acct2"],[format "%s%s" $test_nu "acct3"]

set timeout 60

#
# Check accounting config and bail if not found.
#
if {[get_config_param "AccountingStorageType"] ne "accounting_storage/slurmdbd"} {
	skip "This test can't be run without a usable AccountStorageType"
}

if {[string compare [get_admin_level] "Administrator"]} {
	skip "This test can't be run without being an Accounting administrator.\nUse: sacctmgr mod user \$USER set admin=admin"
}

#make sure we have a clean system and permission to do this work
remove_user "" "" "$us1,$us2,$us3"
remove_acct "" "$nm1,$nm2,$nm3"
remove_cluster "$tc1,$tc2,$tc3"
if {$access_err != 0} {
	skip "Not authorized to perform this test"
}

#add cluster
incr exit_code [add_cluster "$tc1,$tc2,$tc3" [array get clus_req]]
if { $exit_code } {
	remove_user "" "" "$us1,$us2,$us3"
	remove_acct "" "$nm1,$nm2,$nm3"
	remove_cluster "$tc1,$tc2,$tc3"
	fail "Unable to add cluster ($tc1,$tc2,$tc3)"
}

#add accounts
incr exit_code [add_acct "$nm1,$nm2,$nm3" [array get acct_req]]
if { $exit_code } {
	remove_user "" "" "$us1,$us2,$us3"
	remove_acct "" "$nm1,$nm2,$nm3"
	remove_cluster "$tc1,$tc2,$tc3"
	fail "Unable to add account ($nm1,$nm2,$nm3)"
}

#add users
incr exit_code [add_user "$us1,$us2,$us3" [array get user_req]]
if { $exit_code } {
	remove_user "" "" "$us1,$us2,$us3"
	remove_acct "" "$nm1,$nm2,$nm3"
	remove_cluster "$tc1,$tc2,$tc3"
	fail "Unable to add user ($us1,$us2,$us3)"
}

# Add a coordinator
# accounts names
incr exit_code [add_coor $nm1 $us1]
if { $exit_code } {
	remove_user "" "" "$us1,$us2,$us3"
	remove_acct "" "$nm1,$nm2,$nm3"
	remove_cluster "$tc1,$tc2,$tc3"
	fail "Unable to add coordinator ($nm1 $us1)"
}

#
# Use sacctmgr to list the test user modification
#
set matches 0
set my_pid [spawn $sacctmgr -n -p list user names=$us1,$us2,$us3 withcoor format=user,DefaultAccount,Admin,Coord cluster=$tc1]
expect {
	-re "There was a problem" {
	        log_error "There was a problem with the sacctmgr command"
	    	incr exit_code 1
	}
	-re "($us1.$nm1.$aln.$nm1.|($us2|$us3).$nm1.$aln..)" {
		incr matches
		exp_continue
	}
	timeout {
		log_error "sacctmgr list associations not responding"
		slow_kill $my_pid
		incr exit_code 1
	}
	eof {
		wait
	}
}

if {$matches != 3} {
	log_error "Coordinator add 3 incorrect with only $matches"
	incr exit_code 1
}

# Next, add coordinator to two users
incr exit_code [add_coor "$nm1,$nm3" "$us2,$us3"]
if { $exit_code } {
	remove_user "" "" "$us1,$us2,$us3"
	remove_acct "" "$nm1,$nm2,$nm3"
	remove_cluster "$tc1,$tc2,$tc3"
	fail "Unable to add coordinator ($nm1,$nm3 $us2,$us3)"
}

#
# Use sacctmgr to list the test coordinator additions
#
set matches 0
set my_pid [spawn $sacctmgr -n -p list user names=$us1,$us2,$us3 withcoor format=user,DefaultAccount,Admin,Coord cluster=$tc1]
expect {
	-re "There was a problem" {
	    log_error "There was a problem with the sacctmgr command"
	   	incr exit_code 1
	}
	-re "($us1.$nm1.$aln.$nm1.|($us2|$us3).$nm1.$aln.$nm1,$nm3)" {
		incr matches
		exp_continue
	}
	timeout {
		log_error "sacctmgr list associations not responding"
		slow_kill $my_pid
		incr exit_code 1
	}
	eof {
		wait
	}
}

if {$matches != 3} {
	log_error "User modification 3 incorrect with only $matches"
	incr exit_code 1
}

# This is the end below here

incr exit_code [remove_user "" "" "$us1,$us2,$us3"]
incr exit_code [remove_acct "" "$nm1,$nm2,$nm3"]
incr exit_code [remove_cluster "$tc1,$tc2,$tc3"]

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