From 347fe719f72e759dbd24db5935c6c5a8a4e8c893 Mon Sep 17 00:00:00 2001
From: Alejandro Sanchez <alex@schedmd.com>
Date: Thu, 28 Apr 2016 11:35:19 -0700
Subject: [PATCH] Update reservation test for heterogeneous nodes

bug 2597
---
 testsuite/expect/globals   | 158 +++++++++++++++++++++++++++++++++++++
 testsuite/expect/inc3.11.1 |  20 +++--
 testsuite/expect/inc3.11.7 |  18 ++---
 testsuite/expect/test3.11  |  27 ++++++-
 4 files changed, 199 insertions(+), 24 deletions(-)

diff --git a/testsuite/expect/globals b/testsuite/expect/globals
index bab069e794e..d17be916c28 100755
--- a/testsuite/expect/globals
+++ b/testsuite/expect/globals
@@ -3716,3 +3716,161 @@ proc get_curr_line_num {frame_info} {
 	# returned by 'info frame'
 	set result [dict get [info frame $frame_info] line]
 }
+
+#####################################################################
+#
+# Proc: get_partition_nodes
+#
+# Purpose: Get the list of node names in a given partition/states
+#
+# Input:	partition - partition to get nodes off
+#		states - states to filter on nodes
+#
+# Returns: node names list, -1 on sinfo error
+#
+#####################################################################
+
+proc get_partition_nodes {partition states} {
+
+	global sinfo alpha_numeric_under
+	log_user 0
+	set node_list ""
+
+	if {[string length $partition] == 0} {
+		set partition [default_partition]
+	}
+
+	if {[string length $states] == 0} {
+		set sinfo_pid [spawn -noecho $sinfo -h -N -p $partition -o %N -e]
+	} else {
+		set sinfo_pid [spawn -noecho $sinfo -h -N -p $partition -o %N -t $states -e]
+	}
+
+	expect {
+		-re "($alpha_numeric_under)" {
+			lappend node_list $expect_out(1,string)
+			exp_continue
+		}
+		timeout {
+			send_user "\nFAILURE: sinfo not responding\n"
+			slow_kill $sinfo_pid
+			set exit_code 1
+		}
+		eof {
+			wait
+		}
+	}
+
+	log_user 1
+	return $node_list
+}
+
+#####################################################################
+#
+# Proc: get_node_cores
+#
+# Purpose:	Given a node, return its total number of cores
+#		(not the CoresPerSocket, but the total cores)
+#
+# Input: node - node to get cores from
+#
+# Returns: node cores if retrieved, -1 otherwise
+#
+#####################################################################
+
+proc get_node_cores {node} {
+
+	global sinfo number
+	set cores -1
+	set sockets_per_node 0
+	set cores_per_socket 0
+
+	if {[string length $node] == 0} {
+		return $cores
+	}
+
+	log_user 0
+	set sinfo_pid [spawn -noecho $sinfo -o "%X %Y" -h -n $node]
+
+	expect {
+		-re "($number)" {
+			if {$sockets_per_node == 0} {
+				set sockets_per_node $expect_out(1,string)
+			} else {
+				set cores_per_socket $expect_out(1,string)
+			}
+			exp_continue
+		}
+		timeout {
+			send_user "\nFAILURE: sinfo not responding\n"
+			slow_kill $sinfo_pid
+			set exit_code 1
+		}
+		eof {
+			wait
+		}
+	}
+
+	log_user 1
+
+	set cores [expr $sockets_per_node * $cores_per_socket]
+
+	return $cores
+}
+
+#####################################################################
+#
+# Proc: get_part_total_cores
+#
+# Purpose: Given a partition and/or states, return its total cores
+#
+# Input part - partition to check cores
+#	states - states to filter on partition cores
+#
+# Returns: partition cores
+#
+#####################################################################
+
+proc get_part_total_cores {part states} {
+	global sinfo number
+	log_user 0
+	set cores 0
+	set tmp 0
+	set i 0
+
+	if {[string length $part] == 0} {
+		set part [default_partition]
+	}
+
+	if {[string length $states] == 0} {
+		set sinfo_pid [spawn -noecho $sinfo -h -N -p $part -o "%X %Y"]
+	} else {
+		set sinfo_pid [spawn -noecho $sinfo -h -N -p $part -t $states -o "%X %Y"]
+	}
+
+	expect {
+		-re "($number)" {
+			set is_even [expr {($i % 2) == 0}]
+			if {$is_even == 1} {
+				set tmp $expect_out(1,string)
+			} else {
+				set tmp [expr $tmp * $expect_out(1,string)]
+				set cores [expr $cores + $tmp]
+			}
+			incr i
+			exp_continue
+		}
+		timeout {
+			send_user "\nFAILURE: sinfo not responding\n"
+			slow_kill $sinfo_pid
+			set exit_code 1
+		}
+		eof {
+			wait
+		}
+	}
+
+	log_user 1
+	return $cores
+}
+
diff --git a/testsuite/expect/inc3.11.1 b/testsuite/expect/inc3.11.1
index 99f7087e64f..2388aea5fbc 100644
--- a/testsuite/expect/inc3.11.1
+++ b/testsuite/expect/inc3.11.1
@@ -32,13 +32,10 @@
 ############################################################################
 
 proc inc3_11_1 {} {
-	global def_node user_name def_partition exit_code cluster_cpus res_name
-	global cons_res_actived def_node_name
-
-	set num_nodes [available_nodes $def_partition ""]
-
-	# First setting core_res_num greater than cores per node (assuming symmetric nodes)
-	set core_res_num [ expr ($cluster_cpus / $num_nodes) + 1 ]
+	global cons_res_actived def_node def_node_name
+	global def_partition exit_code
+	global part_cores part_node part_node_cnt part_node_cores
+	global res_name user_name
 
 	# TEST 1
 	# Make a list of lists with a series of parameters to test.  All the tests
@@ -64,7 +61,8 @@ proc inc3_11_1 {} {
 "
 	#{StartTime=now   Duration=5   Nodes=$def_node   Account=badaccountname}
 	if {$cons_res_actived == 1} {
-		set more_badtests "StartTime=now   Duration=5   NodeCnt=1 CoreCnt=$core_res_num  User=$user_name"
+		set corecnt [ expr $part_node_cores + 1 ]
+		set more_badtests "StartTime=now Duration=5 Nodes=$part_node CoreCnt=$corecnt User=$user_name"
 		lappend badtests $more_badtests
 	}
 
@@ -75,7 +73,7 @@ proc inc3_11_1 {} {
 			delete_res $res_name
 			exit 1
 		} else {
-			send_user "\033\[32mExpected error.  You can turn that frown upside-down. (Within: inc3.11.1)\033\[m\n"
+			send_user "\033\[32mExpected error. You can turn that frown upside-down. (Within: inc3.11.1)\033\[m\n"
 		}
 	}
 
@@ -84,7 +82,7 @@ proc inc3_11_1 {} {
 		exit $exit_code
 	}
 
-	set core_res_num [ expr $cluster_cpus / 2 ]
+	set corecnt [ expr $part_cores / 2 ]
 	set goodtests "
 	{StartTime=now   Duration=5   Nodes=$def_node   User=$user_name Flags=ignore_jobs}
 	{StartTime=now+5minutes   EndTime=now+10minutes   Nodes=$def_node   User=$user_name Flags=ignore_jobs}
@@ -96,7 +94,7 @@ proc inc3_11_1 {} {
 "
 	#{StartTime=now   Duration=5   NodeCnt=10 CoreCnt=11  User=$user_name}
 	if {$cons_res_actived == 1} {
-		set more_goodtests "StartTime=now   Duration=5   NodeCnt=$num_nodes CoreCnt=$core_res_num  User=$user_name"
+		set more_goodtests "StartTime=now Duration=5 NodeCnt=$part_node_cnt CoreCnt=$corecnt User=$user_name"
 		lappend goodtests $more_goodtests
 	}
 
diff --git a/testsuite/expect/inc3.11.7 b/testsuite/expect/inc3.11.7
index 15783cb70fe..c5a7fef27c7 100644
--- a/testsuite/expect/inc3.11.7
+++ b/testsuite/expect/inc3.11.7
@@ -31,16 +31,15 @@
 ############################################################################
 
 proc inc3_11_7 {} {
-	global user_name exit_code res_name res_nodes
-	global bin_rm file_in bin_sleep sbatch number scontrol
-	global alpha_numeric_under scancel
-	global cluster_cpus cores_per_node def_partition
-	global res_name res_thread_cnt wait_for_job
+	global alpha_numeric_under bin_rm bin_sleep cluster_cpus cores_per_node
+	global def_partition exit_code file_in number part_cores part_node
+	global part_node_cnt part_node_cores res_name res_name res_nodes
+	global res_thread_cnt sbatch scancel scontrol user_name wait_for_job
 
 	send_user "\n+++++ STARTING TEST 7 (Within: inc3.11.7) +++++\n"
 
 	# Make a reservation, just to get node size infomation
-	set ret_code [create_res "StartTime=now Duration=1 NodeCnt=1 User=$user_name" 0]
+	set ret_code [create_res "StartTime=now Duration=1 Nodes=$part_node User=$user_name" 0]
 	if {$ret_code != 0} {
 		send_user "\n\033\[31mFAILURE: Unable to create a valid reservation (Within inc3.11.7)\033\[m\n"
 		exit $ret_code
@@ -54,14 +53,13 @@ proc inc3_11_7 {} {
 	# Now make a reservation using half the cores on that node
 	# There is no way to specify a the Nodes in a reservation with CoreCnt,
 	# so hope that we get a node with the same size
-	set core_res_num   [ expr ($cores_per_node / 2) ]
-	set ret_code [create_res "StartTime=now Duration=60 NodeCnt=1 CoreCnt=$core_res_num User=$user_name" 0]
+	set corecnt [ expr ($part_node_cores / 2) ]
+	set ret_code [create_res "StartTime=now Duration=60 Nodes=$part_node CoreCnt=$corecnt User=$user_name" 0]
 	if {$ret_code != 0} {
 		send_user "\n\033\[31mFAILURE: Unable to create a valid reservation (Within: inc3.11.7)\033\[m\n"
 		exit $ret_code
 	}
-	set core_res_num   [ expr ($cores_per_node / 2) ]
-	set thread_res_num [ expr $core_res_num * $res_thread_cnt ]
+	set thread_res_num [ expr $corecnt * $res_thread_cnt ]
 
 	# Make the job script
 	exec $bin_rm -f $file_in
diff --git a/testsuite/expect/test3.11 b/testsuite/expect/test3.11
index a238c42f825..cba2d4a0b7d 100755
--- a/testsuite/expect/test3.11
+++ b/testsuite/expect/test3.11
@@ -52,7 +52,7 @@ set res_nodecnt		0
 set res_thread_cnt	0
 set user_name		""
 set def_oversubscribe_force 0
-set def_partition 	""
+set def_partition	""
 set def_node		""
 set def_node_name	""
 set def_node_inx_min	-1
@@ -423,6 +423,27 @@ if {[test_select_type_params "CR_SOCKET"]} {
 	set cr_socket 1
 }
 
+# Retrieve a node from partition and total cores in partition
+set states "idle"
+set node_list [get_partition_nodes $def_partition $states]
+set part_node_cnt [llength $node_list]
+if {$part_node_cnt == 0} {
+	send_user "\n\033\[34mWARNING: unable to get $states nodes in partition $def_partition"
+	exit $exit_code
+}
+
+set part_node [lindex $node_list 0]
+set part_node_cores [get_node_cores $part_node]
+if {$part_node_cores == -1} {
+	send_user "\n\033\[34mWARNING: unable to get cores from $part_node"
+	exit $exit_code
+}
+set part_cores [get_part_total_cores $def_partition $states]
+if {$part_cores == 0} {
+	send_user "\n\033\[34mWARNING: unable to get cores from $states nodes in $def_partition"
+	exit $exit_code
+}
+
 #
 # Get the user name
 #
@@ -452,11 +473,11 @@ inc3_11_3
 inc3_11_4
 inc3_11_5
 inc3_11_6
-if {$cons_res_actived == 1 && $cores_per_node > 1 && $core_spec == 0 && $exclusive == 0 && $cr_socket == 0} {
+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 && $cores_per_node > 1 && $core_spec == 0 && $exclusive == 0 && $cr_socket == 0 && $irregular_node_name == 0} {
+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
 }
 
-- 
GitLab