#!/usr/bin/expect --
################################################################################
#
# File:  readOaPower 
#
# Description: Read the power state of blades from the OA
#
# Notes:  If a bay/blade is specified on the command line the power state
#         of that system is printed out.
#         If an expected power state is also specified on the command line,
#         check that the reported power state matches that given on the command
#         line.  If the actual power state matches the expected state, print
#         "PASS" and return shell success (0). If the power state doesn't match
#         print "FAIL" and return 1.
#
#         Any errors in running the command, etc. will return 2
#
#      -*- OpenSAF  -*-
#
# (C) Copyright 2008 The OpenSAF Foundation
#
# This program 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. This file and program are licensed
# under the GNU Lesser General Public License Version 2.1, February 1999.
# The complete license can be accessed from the following location:
# http://opensource.org/licenses/lgpl-license.php
# See the Copying file included with the OpenSAF distribution for full
# licensing terms.
#
# Author(s):
#           Hewlett-Packard Company
#
#
################################################################################

# Get the name of this script.
set MyName [lindex [split $argv0 {/}] end]
set caller "$MyName"

################################################################################
#                                 Subroutines
################################################################################

#*******************************************************************************
# SetLibraryPath: Sets the library path for common libraries
# Input: none
# Output: exits with value 0
#*******************************************************************************
proc SetLibraryPath {argv0} {
   global basepath locpath
   global env
   global VERBOSE

   if {![info exists VERBOSE]} {
      set VERBOSE 0
   }
   set libDir "tests/hisv/lib"
    # Get the path to the our libraries
    if {$VERBOSE} {
       send_user "\n\[SM] SetLibraryPath:\n"
       send_user "\targv0 = $argv0\n"
    }
    set pathToMe $argv0
     # If the path to this tool is relative to this directory,
     #   substitute $PWD.
    regsub {^./[^/]+} $pathToMe $env(PWD) pathToMe
     # set locpath to this directory
    regsub {/[^/]+$} $pathToMe "" locpath

    if {$VERBOSE} {
       send_user "\tpathToMe = $pathToMe\n"
       send_user "\tlocpath  = $locpath\n"
    }
    if [info exists env(BASEPATH)] {
        # Use the environment variable BASEPATH if set:
       set basepath "$env(BASEPATH)"
    } \
    else {
           set pathDirs [split $locpath /]
           set pLen [expr [llength $pathDirs] - 1]

            # Work backwards through the path to try to
            #  find the path to the library directory
           for {set i $pLen} {$i > 0 } {incr i -1} {

               if {$i == $pLen} {
                  set dummyPath $pathToMe
               }
               regsub {/[^/]+$} $dummyPath "" dummyPath
               if {[file exists $dummyPath/libsm]} {
                  set basepath $dummyPath
                  break
               } \
               elseif {[file exists $dummyPath/lib/libsm]} {
                  set basepath $dummyPath/lib
                  break
               }
           }

           if {![info exists basepath]} {
               send_user "ERROR: Can't find common library directory $libDir\n"
               exit 2
           }
    }

    if {$VERBOSE} {send_user "\tFound library path $basepath\n"}
}

#*******************************************************************************
# Usage: Print usage message
# Input: none
# Output: exits with value 0
#*******************************************************************************
proc Usage {} {
   global MyName
   global domain
   global ilo_user ilo_passwd
   global user passwd

   puts "$MyName: Read the power state of blades from the OA"
   puts "\tIf a bay/blade is specified on the command line the power state of that"
   puts "\tof that system is printed."
   puts "\tIf an expected power state is also specified on the command line,"
   puts "\tcheck that the reported power state matches that given on the command"
   puts "\tline.  If the actual power state matches the expected state, print"
   puts "\t\"PASS\" and return shell success (0). If the power state doesn't match"
   puts "\tprint \"FAIL\" and return shell failure (1)."
   puts "\nUsage: $MyName -sut=<ilo_hostname> \[optional]"
   puts "    Required options:"
   puts "\t-sut=<ilo_hostname>"
   puts "\t    hostname is the hostname of the system under test."
   puts ""
   puts "    Test-related options:"
   puts ""
   puts "    Other options:"
   puts "\t-ilo_passwd=<ilo_admin_passwd>"
   puts "\t    ilo_admin_passwd is the administrator password on the system under test."
   puts "\t    (default: $passwd)."
   puts "\t-ilo_user=<administrator>"
   puts "\t    user_name to log into iLO virtual serial console as"
   puts "\t    (default: $user)."
   puts ""
   puts "    Login-related options:"
   puts "\t-user=<root_user>"
   puts "\t    root_user is the login name for a user with root privileges."
   puts "\t    default: $user."
   puts "\t-password=<root_user_password>"
   puts "\t    The password for the user specified above."
   puts ""
   exit 0
} ;# End Usage

#*******************************************************************************
#  ParseArgs: Customized command-line parsing for this test
#  Input: rargv - reference to the argv string
#  Output: sets variables in caller's scope
#  Note: This parses options that didn't match options in
#        libcmdline::ParseCanonicalCmdline, so if the option
#        is not set properly here, check libcmdline.
#*******************************************************************************
proc ParseArgs {rargv} {
   global VERBOSE
   global console
   upvar $rargv argv

   set unusedArgs ""

   if {$VERBOSE} {
       send_user "\n\[SM] ParseArgs:\n"
   }
   if [info exists argv] {
      if {$VERBOSE} { send_user "\targv = $argv\n"}
   } \
   else {
      return
   }
 
   set argv [split $argv { =}]

   while {[llength $argv] > 0} {
       set opt [shift argv]
       switch -- $opt {
           -h -
           -help -
           --help -
           -? {  Usage }
           -s -
           -slot -
           -b -
           -bay -
           -blade { uplevel #0 set bay [shift argv]; continue }
           -on    { uplevel #0 set powerState "ON"; continue}
           -off   { uplevel #0 set powerState "OFF"; continue}
           default {
              if { $opt != "" } {
                 if {![info exists console] || [info exists console] && [regexp {^[0-9]+$} $console]} {
                    if {$VERBOSE} {send_user "\tFlagless option, setting console to $opt\n" }
                    uplevel #0 set console $opt
                    SmartParse
                 } \
                 else {
                    push unusedArgs $opt
                 }
              }
           }
       }
    }  ;# End while
    set argv $unusedArgs
    upvar sut sut

    if {[info exists sut] && [regexp {^[0-9]+$} $sut]} {
       uplevel #0 set bay $sut
    }

}   ;# End ParseArgs


################################################################################
#                              End Subroutines
################################################################################
# Set verbose early to get verbose output from search for library
# path and command-line parsing
if {[regexp -- {-v} $argv]} { set VERBOSE 1 }

# Set library path
SetLibraryPath $argv0

#***************************** Global Variables ********************************
source $basepath/defaults
 # Connect to the firmware, not the console
set fwConnect 1

# Source libraries.
source "$basepath/libcmdline"
source "$basepath/stdlib"
source "$basepath/libilo"
source "$basepath/libsm"
source "$basepath/liblinux"
source "$basepath/libstate"

################################################################################
#                           Overloaded Subroutines
################################################################################
#  Add subroutines, e.g., Done, here to override the
#  default action as defined in the libraries above.

################################################################################
#                         End Overloaded Subroutines
################################################################################

# Set interrupt handlers
SetSigTraps


#************************** Configuration Loading ******************************

# Override default settings with command-line options
ParseCanonicalCmdline argv
if {[info exists argv] && [llength $argv]} { ParseArgs argv }
if {![info exists prompt]} { set prompt $root_prompt }

# Show the user what's going on...
if {$VERBOSE} {log_user 1}

# Set the Expect log file if we are in verbose mode.
set log "$MyName"
set log [split $log {.}]
set logfilename "[lindex $log 0].log.[pid]"

if {[info exists env(DRYRUN)] && $env(DRYRUN)} {
   set DRYRUN 1
   set VERBOSE 3
}

#**************************** Start Debug-Logfile ******************************
if { $VERBOSE || [info exists env(DEBUG)] && $env(DEBUG)} {
    exp_internal -f $logfilename 0
    send_user "\n\[SM] Logfile is $logfilename\n"
}

#*************************** Connect to the System *****************************
set timeout $timeout_setting

if {$VERBOSE} {
   send_user "\[SM] $MyName:\n"
   if {[info exists console]} {send_user "\tconsole is $console\n"}
   if {[info exists sut]} {send_user "\tsut is $sut\n"}
   if {[info exists type]} {send_user "\ttype is $type\n"}
   if {[info exists powerState]} {send_user "\tpowerState is $powerState\n"}
}
if {![info exists console]} {
	ErrorMessage "You must specify the hostname of the OA\n" 1
}

     # sut is the system number if connecting from the OA
if {!$fwConnect} {
    # Connect to the system console
   if {![ConnectConsole $type $console sut]} {
      ErrorMessage "Failed to connect to the system console $console" 2
   }
} \
else {
   if {$type == "ilo"} {
      ErrorMessage "To read the power on all systems in this enclosure, you must log into the OA\n" 1
   }
   if {![ConnectFW $console $oaUser $oaPasswd]} {
      ErrorMessage "Failed to connect to $type" 3
   }
}

# Clean out any chassis codes
expect *

#****************************** Start the Test *********************************
set failed 0
if {![OACheckPowerStatus serverList]} {
   ErrorMessage "Failed to get power status" 3
}
if {[info exists bay] && [info exists serverList($bay)]} {
   if [info exists powerState] {
      if {$serverList($bay) == $powerState} {
         send_user "\nPASS: system $bay is $powerState\n"
      } \
      else {
         send_user "\nFAIL: system $bay is $serverList($bay)\n"
         set failed 1
      }
   } \
   else {
      send_user "\nsystem $bay is $serverList($bay)\n"
   }
} \
elseif {[info exists bay]} {
   ErrorMessage "Couldn't read power state for $bay" 2
}

#******************************* End the Test **********************************
Done $failed
