1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372
|
# This is the checker for for a simple 16 node test with opensm and osmtest
proc parseNodePortGroup {simDir} {
set f [open [file join $simDir "port_pkey_groups.txt"] r]
set res {}
while {[gets $f sLine] >= 0} {
lappend res $sLine
}
close $f
puts "-I- Defined [llength $res] ports"
return $res
}
# given the node port group defined by the sim flow
# setup the partitions policy file for the SM
proc setupPartitionPolicyFile {fileName} {
global nodePortGroupList
for {set g 1} {$g <= 3} {incr g} {
set GROUP_PKEYS($g) ""
}
set f [open $fileName w]
# no need for default partition
# puts $f "Default=0x7fff ,ipoib : ALL, SELF=full ;"
# loop on the tree groups collecting their member guids and printing them out
foreach p {1 2 3} {
set guids {}
foreach png $nodePortGroupList {
# png = { name num grp guid pkey }
set grp [lindex $png 2]
if {$grp == $p} {
lappend guids [lindex $png 3]
set GROUP_PKEYS($grp) [lindex $png 4]
} elseif {$grp == 3} {
# group 3 ports are members of both other groups
lappend guids [lindex $png 3]
}
}
puts $f "G$p=$GROUP_PKEYS($p) :"
set lastGuid [lindex $guids end]
foreach g $guids {
if {$p != 3} {
puts -nonewline $f " $g=full"
} else {
puts -nonewline $f " $g"
}
if {$lastGuid == $g} {
puts $f ";"
} else {
puts $f ","
}
}
puts $f " "
}
close $f
}
# validate osmtest.dat versus the list of node port group
# group 1 must only have info regarding nodes of group1
# group 2 is similar
# group 3 see all others
#
# HACK: we currently only count the number of nodes/ports/path records
# and not use the full GUID based check.
proc validateInventoryVsGroup {simDir group nodePortGroupList} {
# count the number of ports we have in each group:
set GUIDS(1) {}
set GUIDS(2) {}
set GUIDS(3) {}
foreach npg $nodePortGroupList {
set g [lindex $npg 2]
set guid [lindex $npg 3]
lappend GUIDS($g) $guid
set GUID_GRP($guid) $g
}
set cnt1 [llength $GUIDS(1)]
set cnt2 [llength $GUIDS(2)]
set cnt3 [llength $GUIDS(3)]
switch $group {
1 {
foreach g $GUIDS(1) {set REQUIRED($g) 0}
foreach g $GUIDS(3) {set REQUIRED($g) 0}
foreach g $GUIDS(2) {set DISALLOWED($g) 2}
set expected [expr ($cnt1 + $cnt3)*($cnt1 + $cnt3)]
}
2 {
foreach g $GUIDS(2) {set REQUIRED($g) 0}
foreach g $GUIDS(3) {set REQUIRED($g) 0}
foreach g $GUIDS(1) {set DISALLOWED($g) 1}
set expected [expr ($cnt2 + $cnt3)*($cnt2 + $cnt3)]
}
3 {
foreach g $GUIDS(1) {set REQUIRED($g) 0}
foreach g $GUIDS(2) {set REQUIRED($g) 0}
foreach g $GUIDS(3) {set REQUIRED($g) 0}
set expected [expr \
$cnt3*($cnt1 + $cnt2 + $cnt3) + \
$cnt1*($cnt1 + $cnt3) + \
$cnt2*($cnt2 + $cnt3) ]
}
}
puts "-I- Expecting:$expected paths (membership is: 1=$cnt1 2=$cnt2 3=$cnt3 )"
# parse the inventory:
set fn [file join $simDir osmtest.dat]
set f [open $fn r]
set lineNum 0
set errCnt 0
set state none
while {[gets $f sLine] >= 0} {
incr lineNum
if {$state == "none"} {
if {[lindex $sLine 0] == "DEFINE_NODE"} {
set state node
} elseif {[lindex $sLine 0] == "DEFINE_PORT"} {
set state port
} elseif {[lindex $sLine 0] == "DEFINE_PATH"} {
set state path
}
} elseif {$state == "node"} {
set field [lindex $sLine 0]
# we only care about guid line and lid
if {$field == "port_guid"} {
set guid [lindex $sLine 1]
set GUID_BY_LID($lid) $guid
# now we can check if the guid is expected or not
if {[info exist DISALLOWED($guid)]} {
puts "-E- Got disallowed guid:$guid of group $DISALLOWED($guid)"
incr errCnt
} else {
# we might require it so mark ...
if {[info exist REQUIRED($guid)]} {
incr REQUIRED($guid)
}
}
} elseif {$field == "lid"} {
set lid [lindex $sLine 1]
} elseif {$field == "END"} {
set state none
}
} elseif {$state == "port"} {
# we only care about lid line
set field [lindex $sLine 0]
if {$field == "base_lid"} {
set lid [lindex $sLine 1]
# ignore lid 0x0 on physp of switches...
if {$lid != "0x0"} {
set guid $GUID_BY_LID($lid)
# now we can check if the guid is expected or not
if {[info exist DISALLOWED($guid)]} {
puts "-E- Got disallowed guid:$guid of group $DISALLOWED($guid)"
incr errCnt
} else {
# we might require it so mark ...
if {[info exist REQUIRED($guid)]} {
incr REQUIRED($guid)
}
}
}
} elseif {$field == "END"} {
set state none
}
} elseif {$state == "path"} {
# we need to check both sides of the path
set field [lindex $sLine 0]
if {$field == "sgid"} {
set sguid [lindex $sLine 2]
if {[info exist DISALLOWED($sguid)]} {
puts "-E- Got disallowed path from guid:$sguid of group $DISALLOWED($sguid)"
incr errCnt
} else {
# the path is allowed only if the ends are allowed to
# see wach other - catch cases where they are not:
if {[info exist GUID_GRP($sguid)] &&
[info exist GUID_GRP($dguid)] &&
((($GUID_GRP($sguid) == 1) && ($GUID_GRP($dguid) == 2)) ||
(($GUID_GRP($sguid) == 2) && ($GUID_GRP($dguid) == 1)))} {
incr errCnt
puts "-E- Got path from guid:$sguid to guid:$dguid"
incr errCnt
} else {
# track paths:
set k "$sguid $dguid"
set PATHS($k) 1
}
}
} elseif {$field == "dgid"} {
set dguid [lindex $sLine 2]
if {[info exist DISALLOWED($dguid)]} {
puts "-E- Got disallowed path to guid:$dguid of group $DISALLOWED($dguid)"
incr errCnt
}
} elseif {$field == "END"} {
set state none
}
}
}
close $f
foreach sguid [array names REQUIRED] {
if {$REQUIRED($sguid) != 2} {
puts "-E- Missing port or node for guid $sguid"
incr errCnt
}
foreach dguid [array names REQUIRED] {
# it is not enough for the ports to be visible - they need
# to see each other so can not be one from 1 and other from 2...
if {($GUID_GRP($sguid) == 1) && ($GUID_GRP($dguid) == 2)} continue
if {($GUID_GRP($sguid) == 2) && ($GUID_GRP($dguid) == 1)} continue
set k "$sguid $dguid"
if {![info exist PATHS($k)]} {
puts "-E- Missing path $k"
incr errCnt
}
}
}
puts "-I- Obtained: [llength [array names PATHS]] paths for group:$group"
return $errCnt
}
##############################################################################
#
# Start up the test applications
# This is the default flow that will start OpenSM only in 0x43 verbosity
# Return a list of process ids it started (to be killed on exit)
#
proc runner {simDir osmPath osmPortGuid} {
global simCtrlSock
global env
global nodePortGroupList
set osmStdOutLog [file join $simDir osm.stdout.log]
set osmLog [file join $simDir osm.log]
fconfigure $simCtrlSock -blocking 1 -buffering line
# randomize pkey tables
puts $simCtrlSock "setAllHcaPortsPKeyTable \$fabric"
puts "SIM: [gets $simCtrlSock]"
puts $simCtrlSock "dumpHcaPKeyGroupFile $simDir"
puts "SIM: [gets $simCtrlSock]"
# parse the node/port/pkey_group file from the sim dir:
set nodePortGroupList [parseNodePortGroup $simDir]
# Prepare the nodes partitions data
set partitionPolicyFile [file join $simDir partitions.policy]
setupPartitionPolicyFile $partitionPolicyFile
# start the SM
set valgrind "/usr/bin/valgrind --tool=memcheck"
set osmCmd "$osmPath -P$partitionPolicyFile -D 0x3 -d2 -t 8000 -f $osmLog -g $osmPortGuid"
puts "-I- Starting: $osmCmd"
set osmPid [eval "exec $osmCmd > $osmStdOutLog &"]
# start a tracker on the log file and process:
startOsmLogAnalyzer $osmLog
return $osmPid
}
##############################################################################
#
# Check for the test results
# Return the exit code
proc checker {simDir osmPath osmPortGuid} {
global env
global simCtrlSock osmPid
global nodePortGroupList
set osmTestPath [file join [file dirname $osmPath] osmtest]
set osmTestLog [file join $simDir osmtest.log]
set osmTestStdOutLog [file join $simDir osmtest.stdout.log]
set osmTestInventory [file join $simDir osmtest.dat]
# wait for the SM up or dead
set osmLog [file join $simDir osm.log]
if {[osmWaitForUpOrDead $osmLog]} {
return 1
}
# randomly sellect several nodes and create inventory by running osmtest
# on them - then check only valid entries were reported
for {set i 0 } {$i < 5} {incr i} {
# decide which will be the node name we will use
set r [expr int([rmRand]*[llength $nodePortGroupList])]
set nodeNPortNGroup [lindex $nodePortGroupList $r]
set nodeName [lindex $nodeNPortNGroup 0]
set portNum [lindex $nodeNPortNGroup 1]
set group [lindex $nodeNPortNGroup 2]
set portGuid [makeProcFSForNode $simDir $nodeName $portNum 1]
set env(IBMGTSIM_NODE) $nodeName
puts "-I- Invoking osmtest from node:$nodeName port:$portNum"
set osmTestCmd1 "$osmTestPath -t 8000 -g $portGuid -l $osmTestLog -f c -i $osmTestInventory"
puts "-I- Invoking: $osmTestCmd1 ..."
# HACK: we currently ignore osmtest craches on exit flow:
catch {set res [eval "exec $osmTestCmd1 >& $osmTestStdOutLog"]}
if {[catch {exec grep "OSMTEST: TEST \"Create Inventory\" PASS" $osmTestStdOutLog}]} {
puts "-E- osmtest Create Inventory failed"
return 1
}
if {[validateInventoryVsGroup $simDir $group $nodePortGroupList]} {
puts $simCtrlSock "dumpPKeyTables \$fabric"
puts "SIM: [gets $simCtrlSock]"
return 1
}
}
###### Verifing the pkey manager behaviour ################
# Remove the default pkey from the HCA ports (except the SM)
# HACK: for now the SM does not refresh PKey tables no matter what...
if {0} {
puts $simCtrlSock "removeDefaultPKeyFromTableForHcaPorts \$fabric"
puts "SIM: [gets $simCtrlSock]"
}
# Verify all pkeys are in correct place:
puts "-I- Calling simulator to verify all defined indexie are correct"
puts $simCtrlSock "verifyCorrectPKeyIndexForAllHcaPorts \$fabric"
set res [gets $simCtrlSock]
puts "SIM: $res"
if {$res != 0} {
puts "-E- $res ports have miss-placed pkeys"
return 1
}
#Inject a changebit - to force heavy sweep
puts $simCtrlSock "setOneSwitchChangeBit \$fabric"
puts "SIM: [gets $simCtrlSock]"
# wait for sweep to end or exit
if {[osmWaitForUpOrDead $osmLog 1]} {
return 1
}
# wait 3 seconds
after 1000
#Verify that the default port is in the PKey table of all ports
puts "-I- Calling simulator to verify all HCA ports have either 0x7fff or 0xffff"
puts $simCtrlSock "verifyDefaultPKeyForAllHcaPorts \$fabric"
set res [gets $simCtrlSock]
puts "SIM: $res"
if {$res == 0} {
puts "-I- Pkey check flow completed successfuly"
} else {
puts "-E- Pkey check flow failed"
}
return $res
}
|