#!/usr/bin/env expect
############################################################################
# Purpose: Test of Slurm functionality
#          Validate scontrol create, delete, and update for reservations.
############################################################################
# Copyright (C) 2009 Lawrence Livermore National Security
# Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
# Written by Dave Bremer <dbremer@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
source ./inc3.11.1
source ./inc3.11.2
source ./inc3.11.3
source ./inc3.11.4
source ./inc3.11.5
source ./inc3.11.6
source ./inc3.11.7
source ./inc3.11.8
source ./inc3.11.9
source ./inc3.11.10
source ./inc3.11.11

set file_in		"test$test_id.input"
set exit_code		0
set res_name		""
set res_name_save	""
set res_nodes		""
set res_nodecnt		0
set res_thread_cnt	0
set res_partition	""
set res_flags		""
set user_name		""
set def_oversubscribe_force 0
set def_partition	""
set def_node		""
set def_node_name	""
set def_node_inx_min	-1
set def_node_inx_max	-1
set ii			0
set log_cpu_cnt		0

proc cleanup {} {
	global bin_rm file_in

	exec $bin_rm -f $file_in
}

if {![is_super_user]} {
	skip "This test can't be run except as SlurmUser"
}
set select_type_parameters [get_config_param "SelectTypeParameters"]
if {[param_contains $select_type_parameters "CR_ONE_TASK_PER_CORE"]} {
	skip "This test is incompatible SelectTypeParameters=CR_ONE_TASK_PER_CORE"
}

set have_resv 0
spawn $scontrol show res $res_name
expect {
	-re "ReservationName=($re_word_str)" {
		incr have_resv
		exp_continue
	}
	eof {
		wait
	}
}
if {$have_resv != 0} {
	log_warn "$have_resv reservations exist at start of test which may interfere with the test"
}

#
# Identify usable nodes in default partition
#
set def_partition [default_partition]
if {[string compare $def_partition ""] == 0} {
	fail "Failed to find default partition"
}

spawn $scontrol show partition $def_partition
expect {
	-re " OverSubscribe=FORCE" {
		set def_oversubscribe_force 1
		exp_continue
	}
	eof {
		wait
	}
}
spawn $sinfo -h -o "=%N=" -tIDLE -p $def_partition
expect {
	-re "=(.+)=" {
		set def_node $expect_out(1,string)
		exp_continue
	}
	eof {
		wait
	}
}
if {[string compare $def_node ""] == 0} {
	fail "Default partition seems to have no nodes"
}

spawn $sinfo -h -o "=%N=" -tIDLE -p $def_partition
expect {
	-re "=($re_word_str).($number)-($number).=" {
		set def_node_name $expect_out(1,string)
		set def_node_inx_min $expect_out(2,string)
		set def_node_inx_max $expect_out(3,string)
		exp_continue
	}
	eof {
		wait
	}
}

# Some tests do not support names of this form "rack[0-3]_blade[0-63]"
set irregular_node_name 0
if {[string compare $def_node_name ""] == 0} {
	log_warn "Node name format not supported for all test"
	set irregular_node_name 1
}

#
# Determine system size
#
set core_spec 0
set cores_per_socket 0
set sockets_per_node 0
set heterogeneous 0
log_user 0
spawn $scontrol show node -o
expect {
	-re "CoresPerSocket=($number)" {
		if {$cores_per_socket == 0} {
			set cores_per_socket $expect_out(1,string)
		} elseif {$cores_per_socket != $expect_out(1,string)} {
			set heterogeneous 1
		}
		exp_continue
	}
	-re "Sockets=($number)" {
		if {$sockets_per_node == 0} {
			set sockets_per_node $expect_out(1,string)
		} elseif {$sockets_per_node != $expect_out(1,string)} {
			set heterogeneous 1
		}
		exp_continue
	}
	-re "CoreSpecCount=($number)" {
		if {$expect_out(1,string) > 0} {
			set core_spec 1
		}
		exp_continue
	}
	-re "CPUSpecList=($number)" {
		set core_spec 1
		exp_continue
	}
	eof {
		wait
	}
}
log_user 1
if {$heterogeneous != 0} {
	log_warn "Cluster is heterogeneous and some tests may fail"
}
set cores_per_node [expr $cores_per_socket * $sockets_per_node]
set node_count [llength [get_nodes_by_state idle,alloc,comp]]
set cluster_cpus [expr $cores_per_node * $node_count]

set cr_socket 0
if {[param_contains $select_type_parameters "CR_SOCKET*"]} {
	set cr_socket 1
}

# Retrieve a node from partition and total cores in partition
set states "idle"
set node_list [get_nodes_by_state $states $def_partition]
set part_node_cnt [llength $node_list]
if {$part_node_cnt == 0} {
	fail "Unable to get $states nodes in partition $def_partition"
}

set part_node [lindex $node_list 0]
set part_node_cores [get_node_cores $part_node]
if {$part_node_cores == -1} {
	fail "Unable to get cores from $part_node"
}
set part_cores [get_part_total_cores $def_partition $states]
if {$part_cores == 0} {
	fail "Unable to get cores from $states nodes in $def_partition"
}

#
# Get the user name
#
set user_name [get_my_user_name]

set cons_res_actived 0
if {$def_oversubscribe_force == 0} {
	if {[check_config_select "cons_res"] ||
	    [check_config_select "cons_tres"]} {
		set cons_res_actived 1
	}
}
set exclusive [default_part_exclusive]
if {$cons_res_actived == 1} {
	inc3_11_1
}
inc3_11_2
inc3_11_3
inc3_11_4
inc3_11_5
inc3_11_6
if {$cons_res_actived == 1 && $part_node_cores > 1 && $core_spec == 0 && $exclusive == 0 && $cr_socket == 0} {
	inc3_11_7
	inc3_11_8
}
if {$cons_res_actived == 1 && $part_node_cores > 1 && $core_spec == 0 && $exclusive == 0 && $cr_socket == 0 && $irregular_node_name == 0 && $heterogeneous == 0} {
	inc3_11_9
}
inc3_11_10
inc3_11_11

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