#!/usr/bin/expect
############################################################################
# Purpose: Test of SLURM functionality
#          sacctmgr dump test
#
#
# 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) 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 <http://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_id     "21.24"
set file_in     "test$test_id.input"
set file_in2    "test$test_id.input2"
set file_in3    "test$test_id.input3"
set file_out    "test$test_id.output"
set file_out2   "test$test_id.output2"
set file_out3   "test$test_id.output3"
set file_out4   "test$test_id.output4"
set exit_code   0
set lis		list
set as		assoc
set fmt		format
set cln		clean
set tre		tree
set was		withassoc
set wco		withcoordinator
set par		Parent
set roo		root
set clu		Cluster
set tc1		slurm_test-cluster-1
set tc2		slurm_test-cluster-2
set tc3		slurm_test-cluster-3
set acc		Account
set nams	names
set ta1		slurm_test-account.1
set ta2		slurm_test-account.2
set ta3		slurm_test-account.3
set ta4		slurm_test-account.4
set dsc		Description
set org		Organization
set usr		User
set tu1         slurm_test-user.1
set tu2         slurm_test-user.2
set tu3         slurm_test-user.3
set tu4         slurm_test-user.4
set qs          QOS
set qs2         runfirst
set al		AdminLevel
set aln		None
set ala		Administrator
set alo		Operator
set coo         Coordinator
set col         CoordinatorList
set dac		DefaultAccount
set pts		Partitions
set pde		pdebug
set pba		pbatch
set dw		DefaultWCKey
set wk		WCKeys
set fs		Fairshare
set gm		GrpCPUMins
set gc		GrpCPUs
set gj		GrpJobs
set gs		GrpSubmitJobs
set gn		GrpNodes
set gw		GrpWall
set mm		MaxCPUMins
set mp		MaxCPUMinsPerJob
set mc		MaxCPUs
set mu		MaxCPUsPerJob
set mj		MaxJobs
set ms		MaxSubmitJobs
set mn		MaxNodes
set mnj		MaxNodesPerJob
set mw		MaxWall
set md		MaxWallDurationPerJob

set wckey_check hole,latch,stone,turn

# Accounts
array set acct_req {
	cluster        slurm_test-cluster-3
	parent         root
	description    appliedacct
	organization   organization
	fairshare      5678
	grpcpumins     5500
	grpcpus        50
	grpjobs        510
	grpsubmitjobs  520
	grpnodes       530
	grpwall        300
	maxcpus        540
	maxcpumins     550000
	maxjobs        550
	maxsubmitjobs  560
	maxnodes       570
	maxwall        350
}
set acct_req(qos) $qs2

array set acct_req2 {
	cluster        slurm_test-cluster-3
	parent         slurm_test-account.4
	description    theoryacct
	organization   theoryorg
	fairshare      4321
	grpcpumins     4000
	grpcpus        40
	grpjobs        410
	grpnodes       430
	grpsubmitjobs  420
	grpwall        240
	maxcpumins     420000
	maxcpus        440
	maxjobs        450
	maxnodes       470
	maxsubmitjobs  460
	maxwall        280
}
set acct_req2(qos) $qs2

array set acct_req3 {
	cluster        slurm_test-cluster-3
	parent         slurm_test-account.3
	description    physicsacct
	organization   physicsorg
	fairshare      3240
	grpcpumins     3300
	grpcpus        30
	grpjobs        310
	grpnodes       330
	grpsubmitjobs  320
	grpwall        180
	maxcpumins     330000
	maxcpus        340
	maxjobs        350
	maxnodes       370
	maxsubmitjobs  360
	maxwall        210
}
set acct_req3(qos) $qs2

# Users
array set user_req {

	cluster        slurm_test-cluster-3
	account        slurm_test-account.4
	adminlevel     Administrator
	defaultaccount slurm_test-account.3
	defaultwckey   hole
	wckey          latch,stone,turn
	fairshare      3240
	grpcpumins     3300
	grpcpus        30
	grpjobs        310
	grpnodes       330
	grpsubmitjobs  320
	grpwall        180
	maxcpumins     330000
	maxcpus        340
	maxjobs        350
	maxnodes       370
	maxsubmitjobs  360
	maxwall        210
}
set user_req(qos) $qs2

array set user_req2 {

	cluster        slurm_test-cluster-3
	account        slurm_test-account.3
	adminlevel     Operator
	defaultaccount slurm_test-account.2
	defaultwckey   stone
	wckey          latch,hole,turn
	fairshare      2375
	grpcpumins     2000
	grpcpus        20
	grpjobs        210
	grpnodes       230
	grpsubmitjobs  220
	grpwall        120
	maxcpumins     220000
	maxcpus        240
	maxjobs        250
	maxnodes       270
	maxsubmitjobs  260
	maxwall        140

}
set user_req2(qos) $qs2

array set user_req3 {

	cluster        slurm_test-cluster-3
	account        slurm_test-account.2
	adminlevel     None
	defaultaccount slurm_test-account.2
	defaultwckey   latch
	wckey          stone,hole,turn
	fairshare      1000
	grpcpumins     1100
	grpcpus        10
	grpjobs        120
	grpnodes       140
	grpsubmitjobs  130
	grpwall        60
	maxcpumins     110000
	maxcpus        150
	maxjobs        160
	maxnodes       180
	maxsubmitjobs  170
	maxwall        70

}
set user_req3(qos) $qs2

# Clusters
array set clus_req {
	fairshare 6789
	grpcpus	  60
	grpjob	  610
	grpsubmit 620
	grpnodes  630
	maxcpus   640
	maxcpumin 660000
	maxjobs   650
	maxsubmit 660
	maxnodes  670
	maxwall   2880
}
# I couldn't figure out how to make a variable in an array to = the value of
# another variable.  If you figure this out just move this into the above
# array definition.
set clus_req(qos) $qs2

set timeout     60
set access_err  0

print_header $test_id

set timeout 60

#
# Check accounting config and bail if not found.
#
if { [test_account_storage] == 0 } {
	send_user "\nWARNING: This test can't be run without a usable AccountStorageType\n"
	exit 0
}
set track_wckey [test_track_wckey]

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

#make sure we have a clean system and permission to do this work
remove_user "" "" "$tu1,$tu2,$tu3,$tu4"
remove_acct "" "$ta2,$ta3,$ta4"
remove_qos "$qs2"
remove_cluster "$tc1,$tc2,$tc3"
if {$access_err != 0} {
	send_user "\nWARNING: not authorized to perform this test\n"
	exit $exit_code
}

#add qos
incr exit_code [add_qos "$qs2"]
if { $exit_code } {
	remove_user "" "" "$tu1,$tu2,$tu3,$tu4"
	remove_acct "" "$ta2,$ta3,$ta4"
	remove_qos "$qs2"
	remove_cluster "$tc1,$tc2,$tc3"
	exit $exit_code
}

#
#add cluster
incr exit_code [add_cluster $tc3 [array get clus_req]]
if { $exit_code } {
	remove_user "" "" "$tu1,$tu2,$tu3,$tu4"
	remove_acct "" "$ta2,$ta3,$ta4"
	remove_qos "$qs2"
	remove_cluster "$tc1,$tc2,$tc3"
	exit $exit_code
}

#add accounts
incr exit_code [add_acct $ta4 [array get acct_req]]
if { $exit_code } {
	remove_user "" "" "$tu1,$tu2,$tu3,$tu4"
	remove_acct "" "$ta2,$ta3,$ta4"
	remove_qos "$qs2"
	remove_cluster "$tc1,$tc2,$tc3"
	exit $exit_code
}

incr exit_code [add_acct $ta3 [array get acct_req2]]
if { $exit_code } {
	remove_user "" "" "$tu1,$tu2,$tu3,$tu4"
	remove_acct "" "$ta2,$ta3,$ta4"
	remove_qos "$qs2"
	remove_cluster "$tc1,$tc2,$tc3"
	exit $exit_code
}

incr exit_code [add_acct $ta2 [array get acct_req3]]
if { $exit_code } {
	remove_user "" "" "$tu1,$tu2,$tu3,$tu4"
	remove_acct "" "$ta2,$ta3,$ta4"
	remove_qos "$qs2"
	remove_cluster "$tc1,$tc2,$tc3"
	exit $exit_code
}

#add users
incr exit_code [add_user $tu3 [array get user_req]]
if { $exit_code } {
	remove_user "" "" "$tu1,$tu2,$tu3,$tu4"
	remove_acct "" "$ta2,$ta3,$ta4"
	remove_qos "$qs2"
	remove_cluster "$tc1,$tc2,$tc3"
	exit $exit_code
}

incr exit_code [add_user $tu2 [array get user_req2]]
if { $exit_code } {
	remove_user "" "" "$tu1,$tu2,$tu3,$tu4"
	remove_acct "" "$ta2,$ta3,$ta4"
	remove_qos "$qs2"
	remove_cluster "$tc1,$tc2,$tc3"
	exit $exit_code
}

incr exit_code [add_user $tu1 [array get user_req3]]
if { $exit_code } {
	remove_user "" "" "$tu1,$tu2,$tu3,$tu4"
	remove_acct "" "$ta1,$ta2,$ta3,$ta4"
	remove_qos "$qs2"
	remove_cluster "$tc1,$tc2,$tc3"
	exit $exit_code
}

exec $bin_rm -f $file_out4

set matches 0
set my_pid [spawn $sacctmgr -i dump $clu=$tc3 file=$file_out4]
expect {
	-re "(Cluster .* returned nothing)" {
		send_user "FAILURE: there was a problem with the dump\n"
	    	incr exit_code 1
	}
	-re "(No filename given)" {
		send_user "FAILURE: there was a problem with the file name\n"
	    	incr exit_code 1
	}
	-re "(Can only do one cluster at a time)" {
		send_user "FAILURE: there was a problem with the dump\n"
	    	incr exit_code 1
	}
	-re "too few arguments for keyword" {
		send_user "FAILURE: there was a problem with the dump request\n"
	    	incr exit_code 1
	}
	-re "Unknown option" {
		send_user "FAILURE: there was a problem with the request\n"
	    	incr exit_code 1
	}
	-re "(sacctmgr: Cluster)" {
		incr matches
		exp_continue
	}
	timeout {
		send_user "\nFAILURE: sacctmgr list associations not responding\n"
		slow_kill $my_pid
		incr exit_code 1
	}
	eof {
		wait
	}
}

if {$matches != 1} {
	send_user "\nFAILURE:  File load 1 incorrect with only $matches.\n"
	incr exit_code 1
}

set matches 0
set tfile [open "$file_out4" r]
while {[gets $tfile line] != -1} {

	if {![string compare $line "No such file or directory"]} {
		send_user "FAILURE: there was a problem with the sacctmgr command\n"
		incr exit_code 1
	} elseif {![string compare $line "$clu - '$tc3':$fs=$clus_req(fairshare):$gc=$clus_req(grpcpus):$gj=$clus_req(grpjob):$gn=$clus_req(grpnodes):$gs=$clus_req(grpsubmit):$mp=$clus_req(maxcpumin):$mu=$clus_req(maxcpus):$mj=$clus_req(maxjobs):$mnj=$clus_req(maxnodes):$ms=$clus_req(maxsubmit):$md=$clus_req(maxwall):$qs='$clus_req(qos)'"]} {
		send_user "match 1\n"
		incr matches
	} elseif {![string compare $line "$par - '$roo'"]} {
		send_user "match 2\n"
		incr matches
	} elseif {![string compare $line "$usr - '$roo':$dac='$roo':$al='$ala':$fs=1"]} {
		send_user "match 3\n"
		incr matches
	} elseif {![string compare $line "$acc - '$ta4':$dsc='$acct_req(description)':$org='$acct_req(organization)':$fs=$acct_req(fairshare):$gm=$acct_req(grpcpumins):$gc=$acct_req(grpcpus):$gj=$acct_req(grpjobs):$gn=$acct_req(grpnodes):$gs=$acct_req(grpsubmitjobs):$gw=$acct_req(grpwall):$mp=$acct_req(maxcpumins):$mu=$acct_req(maxcpus):$mj=$acct_req(maxjobs):$mnj=$acct_req(maxnodes):$ms=$acct_req(maxsubmitjobs):$md=$acct_req(maxwall):$qs='$acct_req(qos)'"]} {
		send_user "match 4\n"
		incr matches
	} elseif {![string compare $line "$par - '$ta4'"]} {
		send_user "match 5\n"
		incr matches
	} elseif {![string compare $line "$usr - '$tu3':$dac='$user_req(defaultaccount)':$dw='$user_req(defaultwckey)':$al='$user_req(adminlevel)':$wk='$wckey_check':$fs=$user_req(fairshare):$gm=$user_req(grpcpumins):$gc=$user_req(grpcpus):$gj=$user_req(grpjobs):$gn=$user_req(grpnodes):$gs=$user_req(grpsubmitjobs):$gw=$user_req(grpwall):$mp=$user_req(maxcpumins):$mu=$user_req(maxcpus):$mj=$user_req(maxjobs):$mnj=$user_req(maxnodes):$ms=$user_req(maxsubmitjobs):$md=$user_req(maxwall):$qs='$user_req(qos)'"]} {
		# should come through 2 times
		send_user "match 6\n"
		incr matches
	} elseif {![string compare $line "$acc - '$ta3':$dsc='$acct_req2(description)':$org='$acct_req2(organization)':$fs=$acct_req2(fairshare):$gm=$acct_req2(grpcpumins):$gc=$acct_req2(grpcpus):$gj=$acct_req2(grpjobs):$gn=$acct_req2(grpnodes):$gs=$acct_req2(grpsubmitjobs):$gw=$acct_req2(grpwall):$mp=$acct_req2(maxcpumins):$mu=$acct_req2(maxcpus):$mj=$acct_req2(maxjobs):$mnj=$acct_req2(maxnodes):$ms=$acct_req2(maxsubmitjobs):$md=$acct_req2(maxwall):$qs='$acct_req2(qos)'"]} {
		send_user "match 7\n"
		incr matches
	} elseif {![string compare $line "$par - '$ta3'"]} {
		send_user "match 8\n"
		incr matches
	} elseif {![string compare $line "$acc - '$ta2':$dsc='$acct_req3(description)':$org='$acct_req3(organization)':$fs=$acct_req3(fairshare):$gm=$acct_req3(grpcpumins):$gc=$acct_req3(grpcpus):$gj=$acct_req3(grpjobs):$gn=$acct_req3(grpnodes):$gs=$acct_req3(grpsubmitjobs):$gw=$acct_req3(grpwall):$mp=$acct_req3(maxcpumins):$mu=$acct_req3(maxcpus):$mj=$acct_req3(maxjobs):$mnj=$acct_req3(maxnodes):$ms=$acct_req3(maxsubmitjobs):$md=$acct_req3(maxwall):$qs='$acct_req3(qos)'"]} {
		send_user "match 9\n"
		incr matches
	} elseif {![string compare $line "$par - '$ta2'"]} {
		send_user "match 10\n"
		incr matches
	} elseif {![string compare $line "$usr - '$tu1':$dac='$user_req3(defaultaccount)':$dw='$user_req3(defaultwckey)':$wk='$wckey_check':$fs=$user_req3(fairshare):$gm=$user_req3(grpcpumins):$gc=$user_req3(grpcpus):$gj=$user_req3(grpjobs):$gn=$user_req3(grpnodes):$gs=$user_req3(grpsubmitjobs):$gw=$user_req3(grpwall):$mp=$user_req3(maxcpumins):$mu=$user_req3(maxcpus):$mj=$user_req3(maxjobs):$mnj=$user_req3(maxnodes):$ms=$user_req3(maxsubmitjobs):$md=$user_req3(maxwall):$qs='$user_req3(qos)'"]} {
		send_user "match 11\n"
		incr matches
	} elseif {![string compare $line "$usr - '$tu2':$dac='$user_req2(defaultaccount)':$dw='$user_req2(defaultwckey)':$al='$user_req2(adminlevel)':$wk='$wckey_check':$fs=$user_req2(fairshare):$gm=$user_req2(grpcpumins):$gc=$user_req2(grpcpus):$gj=$user_req2(grpjobs):$gn=$user_req2(grpnodes):$gs=$user_req2(grpsubmitjobs):$gw=$user_req2(grpwall):$mp=$user_req2(maxcpumins):$mu=$user_req2(maxcpus):$mj=$user_req2(maxjobs):$mnj=$user_req2(maxnodes):$ms=$user_req2(maxsubmitjobs):$md=$user_req2(maxwall):$qs='$user_req2(qos)'"]} {
		# should come through 2 times
		send_user "match 12\n"
		incr matches
	}
}


if {$matches != 14} {
	send_user "\nFAILURE:  Parse of file for 14 entries incorrect with only $matches.\n"
	incr exit_code 1
}

#
# This is the end below here

incr exit_code [remove_user "" "" "$tu1,$tu2,$tu3,$tu4"]
incr exit_code [remove_acct "" "$ta2,$ta3,$ta4"]
incr exit_code [remove_qos "$qs2"]
incr exit_code [remove_cluster "$tc1,$tc2,$tc3"]

if {$exit_code == 0} {
   	exec $bin_rm -f $file_out4
	print_success $test_id
} else {
	send_user "\nFAILURE\n"
}
exit $exit_code
