IPMI channel support test use case

Added:
   - Test case to verify supported IPMI channel of the system.
   - Test case to verify invalid IPMI channel response.
   - Keyword to get the MAC address.
   - Keyword to get the valid physical network count.
   - Added expect_error parameter to standard IPMI keyword args.

For reference: openbmc/openbmc#3036

Resolves  openbmc/openbmc-test-automation#1313

Change-Id: Ie94e87094056248c335822b1bdc41b8254bfa343
Signed-off-by: George Keishing <gkeishin@in.ibm.com>
diff --git a/lib/bmc_network_utils.robot b/lib/bmc_network_utils.robot
index 41b248c..8c0e2ef 100644
--- a/lib/bmc_network_utils.robot
+++ b/lib/bmc_network_utils.robot
@@ -85,6 +85,7 @@
 
     [Return]  ${cmd_output}
 
+# TODO: openbmc/openbmc-test-automation#1331
 Get BMC MAC Address
     [Documentation]  Get system MAC address.
 
@@ -103,6 +104,28 @@
 
     [Return]  ${words[1]}
 
+
+Get BMC MAC Address List
+    [Documentation]  Get system MAC address
+
+    # Sample output of "ip addr | grep ether":
+    # link/ether xx.xx.xx.xx.xx.xx brd ff:ff:ff:ff:ff:ff
+
+    ${cmd_output}=  BMC Execute Command  /sbin/ip addr | grep ether
+
+    # Split the line and return MAC address.
+    # Split list data:
+    # link/ether | xx:xx:xx:xx:xx:xx | brd | ff:ff:ff:ff:ff:ff
+    # link/ether | xx:xx:xx:xx:xx:xx | brd | ff:ff:ff:ff:ff:ff
+
+    ${mac_list}=  Create List
+    @{lines}=  Split To Lines  ${cmd_output[0]}
+    :FOR  ${line}  IN  @{lines}
+    \  @{words}=  Split String  ${line}
+    \   Append To List  ${mac_list}  ${words[1]}
+
+    [Return]  ${mac_list}
+
 Get BMC Hostname
     [Documentation]  Get BMC hostname.
 
diff --git a/lib/ipmi_client.robot b/lib/ipmi_client.robot
index 2a3b743..60c5a45 100755
--- a/lib/ipmi_client.robot
+++ b/lib/ipmi_client.robot
@@ -112,12 +112,17 @@
     [Return]    ${output}
 
 Run External IPMI Standard Command
-    [Arguments]    ${args}
+    [Arguments]  ${args}  ${fail_on_err}=${1}
+
+    # Description of argument(s):
+    # args         IPMI command to be executed.
+    # fail_on_err  Fail if keyword the IPMI command fails
 
     ${ipmi_cmd}=  Catenate  SEPARATOR=
     ...  ${IPMI_EXT_CMD} ${IPMI_USER_OPTIONS} -P${SPACE}${IPMI_PASSWORD}
     ...  ${SPACE}${HOST}${SPACE}${OPENBMC_HOST}${SPACE}${args}
     ${rc}  ${output}=  Run And Return RC and Output  ${ipmi_cmd}
+    Return From Keyword If  ${fail_on_err} == ${0}  ${output}
     Should Be Equal  ${rc}  ${0}  msg=${output}
     [Return]  ${output}
 
diff --git a/tests/ipmi/test_general_ipmi.robot b/tests/ipmi/test_general_ipmi.robot
index 1b38fce..ce640bd 100644
--- a/tests/ipmi/test_general_ipmi.robot
+++ b/tests/ipmi/test_general_ipmi.robot
@@ -515,6 +515,37 @@
     Should Be Equal  ${sdr_info['sdr_repository_alloc_info_supported']}  no
 
 
+Test Valid IPMI Channels Supported
+    [Documentation]  Verify IPMI channels supported on a given system.
+    [Tags]  Test_Valid_IPMI_Channels_Supported
+
+    ${channel_count}=  Get Physical Network Interface Count
+
+    # Note: IPMI network channel logically starts from 1.
+    :FOR  ${channel_number}  IN RANGE  1  ${channel_count}
+    \  Run External IPMI Standard Command  lan print ${channel_number}
+
+
+Test Invalid IPMI Channel Response
+    [Documentation]  Verify invalid IPMI channels supported response.
+    [Tags]  Test_Invalid_IPMI_Channel_Response
+
+    ${channel_count}=  Get Physical Network Interface Count
+
+    # To target invalid channel, increment count.
+    ${channel_number}=  Evaluate  ${channel_count} + 1
+
+    # Example of invalid channel:
+    # $ ipmitool -I lanplus -H xx.xx.xx.xx -P 0penBmc lan print 3
+    # Get Channel Info command failed: Parameter out of range
+    # Invalid channel: 3
+
+    ${stdout}=  Run External IPMI Standard Command
+    ...  lan print ${channel_number}  fail_on_err=${0}
+    Should Contain  ${stdout}  Invalid channel
+    ...  msg=IPMI channel ${channel_number} is invalid but seen working.
+
+
 *** Keywords ***
 
 Get Sensor Count
@@ -649,3 +680,17 @@
 
     Should Be True  ${ipmi_rest_power_diff} <= ${allowed_power_diff}
     ...  msg=Power reading above allowed threshold ${allowed_power_diff}.
+
+
+Get Physical Network Interface Count
+    [Documentation]  Return valid physical network interfaces count.
+
+    # Example:
+    # link/ether 22:3a:7f:70:92:cb brd ff:ff:ff:ff:ff:ff
+    # link/ether 0e:8e:0d:6b:e9:e4 brd ff:ff:ff:ff:ff:ff
+
+    ${mac_entry_list}=  Get BMC MAC Address List
+    ${mac_unique_list}=  Remove Duplicates  ${mac_entry_list}
+    ${physical_interface_count}=  Get Length  ${mac_unique_list}
+
+    [Return]  ${physical_interface_count}