Initial Redfish test support for OpenBMC

Changes:
    - Add client library for redfish.
    - New response code file for legacy vs new redfish.
    - Basic test to check response code from client.

Resolves   openbmc/openbmc-test-automation#1424

Change-Id: I254f59d3548a83c2633eaa2a24c1945131c2825e
Signed-off-by: George Keishing <gkeishin@in.ibm.com>
diff --git a/data/variables.py b/data/variables.py
index 883dbba..58b0893 100644
--- a/data/variables.py
+++ b/data/variables.py
@@ -136,6 +136,10 @@
 # The path on the BMC where signed keys are stored.
 ACTIVATION_DIR_PATH = "/etc/activationdata/"
 
+# Redfish variables.
+REDFISH_BASE_URI = '/redfish/v1/'
+REDFISH_SESSION = REDFISH_BASE_URI + 'SessionService/Sessions'
+
 '''
   QEMU HTTPS variable:
 
diff --git a/lib/redfish_client.robot b/lib/redfish_client.robot
new file mode 100644
index 0000000..10bdb3d
--- /dev/null
+++ b/lib/redfish_client.robot
@@ -0,0 +1,78 @@
+*** Settings ***
+Library           Collections
+Library           String
+Library           RequestsLibrary.RequestsKeywords
+Library           OperatingSystem
+Resource          resource.txt
+Library           disable_warning_urllib.py
+Resource          rest_response_code.robot
+
+*** Variables ***
+
+# Assign default value to QUIET for programs which may not define it.
+${QUIET}          ${0}
+
+*** Keywords ***
+
+Redfish Login Request
+    [Documentation]  Do REST login and return authorization token.
+    [Arguments]  ${openbmc_username}=${OPENBMC_USERNAME}
+    ...          ${openbmc_password}=${OPENBMC_PASSWORD}
+    ...          ${alias_session}=openbmc
+    ...          ${timeout}=20
+
+    # Description of argument(s):
+    # openbmc_username  The username to be used to login to the BMC.
+    #                   This defaults to global ${OPENBMC_USERNAME}.
+    # openbmc_password  The password to be used to login to the BMC.
+    #                   This defaults to global ${OPENBMC_PASSWORD}.
+    # alias_session     Session object name.
+    #                   This defaults to "openbmc"
+    # timeout           REST login attempt time out.
+
+    Create Session  openbmc  ${AUTH_URI}  timeout=${timeout}
+    ${headers}=  Create Dictionary  Content-Type=application/json
+
+    ${data}=  Create Dictionary
+    ...  UserName=${openbmc_username}  Password=${openbmc_password}
+
+    ${resp}=  Post Request  openbmc
+    ...  ${REDFISH_SESSION}  data=${data}  headers=${headers}
+
+    Should Be Equal As Strings  ${resp.status_code}  ${HTTP_OK}
+    Log  ${resp.headers["X-Auth-Token"]}
+
+    [Return]  ${resp.headers["X-Auth-Token"]}
+
+
+Redfish Get Request
+    [Documentation]  Do REST GET request and return the result.
+    [Arguments]  ${uri_suffix}  ${xauth_token}=None
+    ...          ${response_format}=json  ${timeout}=30
+
+    # Description of argument(s):
+    # uri_suffix       The URI to establish connection with
+    #                  (e.g. 'Systems').
+    # xauth_token      Authentication token.
+    # response_format  The format desired for data returned by this keyword
+    #                  (json/HTTPS response).
+    # timeout          Timeout in seconds to establish connection with URI.
+
+    ${xauth_token} =  Run Keyword If  ${xauth_token} == ${None}
+    ...  Redfish Login Request
+
+    ${base_uri} =  Catenate  SEPARATOR=  ${REDFISH_BASE_URI}  ${uri_suffix}
+
+    # Example: "X-Auth-Token: 3la1JUf1vY4yN2dNOwun"
+    ${headers} =  Create Dictionary  Content-Type=application/json
+    ...  X-Auth-Token=${xauth_token}
+    ${resp}=  Get Request
+    ...  openbmc  ${base_uri}  headers=${headers}  timeout=${timeout}
+
+    Return From Keyword If  ${response_format} != "json"  ${resp}
+
+    Should Be Equal As Strings  ${resp.status_code}  ${HTTP_OK}
+
+    ${content} =  To JSON  ${resp.content}
+    [Return]  ${content}
+
diff --git a/lib/rest_client.robot b/lib/rest_client.robot
index d9ab79b..d471daf 100644
--- a/lib/rest_client.robot
+++ b/lib/rest_client.robot
@@ -3,60 +3,11 @@
 Library           String
 Library           RequestsLibrary.RequestsKeywords
 Library           OperatingSystem
-Resource          ../lib/resource.txt
-Library           ../lib/disable_warning_urllib.py
+Resource          resource.txt
+Library           disable_warning_urllib.py
+Resource          rest_response_code.robot
 
 *** Variables ***
-# Response codes
-${HTTP_CONTINUE}    100
-${HTTP_SWITCHING_PROTOCOLS}    101
-${HTTP_PROCESSING}    102
-${HTTP_OK}        200
-${HTTP_CREATED}    201
-${HTTP_ACCEPTED}    202
-${HTTP_NON_AUTHORITATIVE_INFORMATION}    203
-${HTTP_NO_CONTENT}    204
-${HTTP_RESET_CONTENT}    205
-${HTTP_PARTIAL_CONTENT}    206
-${HTTP_MULTI_STATUS}    207
-${HTTP_IM_USED}    226
-${HTTP_MULTIPLE_CHOICES}    300
-${HTTP_MOVED_PERMANENTLY}    301
-${HTTP_FOUND}     302
-${HTTP_SEE_OTHER}    303
-${HTTP_NOT_MODIFIED}    304
-${HTTP_USE_PROXY}    305
-${HTTP_TEMPORARY_REDIRECT}    307
-${HTTP_BAD_REQUEST}    400
-${HTTP_UNAUTHORIZED}    401
-${HTTP_PAYMENT_REQUIRED}    402
-${HTTP_FORBIDDEN}    403
-${HTTP_NOT_FOUND}    404
-${HTTP_METHOD_NOT_ALLOWED}    405
-${HTTP_NOT_ACCEPTABLE}    406
-${HTTP_PROXY_AUTHENTICATION_REQUIRED}    407
-${HTTP_REQUEST_TIMEOUT}    408
-${HTTP_CONFLICT}    409
-${HTTP_GONE}      410
-${HTTP_LENGTH_REQUIRED}    411
-${HTTP_PRECONDITION_FAILED}    412
-${HTTP_REQUEST_ENTITY_TOO_LARGE}    413
-${HTTP_REQUEST_URI_TOO_LONG}    414
-${HTTP_UNSUPPORTED_MEDIA_TYPE}    415
-${HTTP_REQUESTED_RANGE_NOT_SATISFIABLE}    416
-${HTTP_EXPECTATION_FAILED}    417
-${HTTP_UNPROCESSABLE_ENTITY}    422
-${HTTP_LOCKED}    423
-${HTTP_FAILED_DEPENDENCY}    424
-${HTTP_UPGRADE_REQUIRED}    426
-${HTTP_INTERNAL_SERVER_ERROR}    500
-${HTTP_NOT_IMPLEMENTED}    501
-${HTTP_BAD_GATEWAY}    502
-${HTTP_SERVICE_UNAVAILABLE}    503
-${HTTP_GATEWAY_TIMEOUT}    504
-${HTTP_HTTP_VERSION_NOT_SUPPORTED}    505
-${HTTP_INSUFFICIENT_STORAGE}    507
-${HTTP_NOT_EXTENDED}    510
 # Assign default value to QUIET for programs which may not define it.
 ${QUIET}  ${0}
 
diff --git a/lib/rest_response_code.robot b/lib/rest_response_code.robot
new file mode 100644
index 0000000..fbbadc8
--- /dev/null
+++ b/lib/rest_response_code.robot
@@ -0,0 +1,51 @@
+*** Variables ***
+# Response codes
+${HTTP_CONTINUE}                         100
+${HTTP_SWITCHING_PROTOCOLS}              101
+${HTTP_PROCESSING}                       102
+${HTTP_OK}                               200
+${HTTP_CREATED}                          201
+${HTTP_ACCEPTED}                         202
+${HTTP_NON_AUTHORITATIVE_INFORMATION}    203
+${HTTP_NO_CONTENT}                       204
+${HTTP_RESET_CONTENT}                    205
+${HTTP_PARTIAL_CONTENT}                  206
+${HTTP_MULTI_STATUS}                     207
+${HTTP_IM_USED}                          226
+${HTTP_MULTIPLE_CHOICES}                 300
+${HTTP_MOVED_PERMANENTLY}                301
+${HTTP_FOUND}                            302
+${HTTP_SEE_OTHER}                        303
+${HTTP_NOT_MODIFIED}                     304
+${HTTP_USE_PROXY}                        305
+${HTTP_TEMPORARY_REDIRECT}               307
+${HTTP_BAD_REQUEST}                      400
+${HTTP_UNAUTHORIZED}                     401
+${HTTP_PAYMENT_REQUIRED}                 402
+${HTTP_FORBIDDEN}                        403
+${HTTP_NOT_FOUND}                        404
+${HTTP_METHOD_NOT_ALLOWED}               405
+${HTTP_NOT_ACCEPTABLE}                   406
+${HTTP_PROXY_AUTHENTICATION_REQUIRED}    407
+${HTTP_REQUEST_TIMEOUT}                  408
+${HTTP_CONFLICT}                         409
+${HTTP_GONE}                             410
+${HTTP_LENGTH_REQUIRED}                  411
+${HTTP_PRECONDITION_FAILED}              412
+${HTTP_REQUEST_ENTITY_TOO_LARGE}         413
+${HTTP_REQUEST_URI_TOO_LONG}             414
+${HTTP_UNSUPPORTED_MEDIA_TYPE}           415
+${HTTP_REQUESTED_RANGE_NOT_SATISFIABLE}  416
+${HTTP_EXPECTATION_FAILED}               417
+${HTTP_UNPROCESSABLE_ENTITY}             422
+${HTTP_LOCKED}                           423
+${HTTP_FAILED_DEPENDENCY}                424
+${HTTP_UPGRADE_REQUIRED}                 426
+${HTTP_INTERNAL_SERVER_ERROR}            500
+${HTTP_NOT_IMPLEMENTED}                  501
+${HTTP_BAD_GATEWAY}                      502
+${HTTP_SERVICE_UNAVAILABLE}              503
+${HTTP_GATEWAY_TIMEOUT}                  504
+${HTTP_HTTP_VERSION_NOT_SUPPORTED}       505
+${HTTP_INSUFFICIENT_STORAGE}             507
+${HTTP_NOT_EXTENDED}                     510
diff --git a/redfish_test/test_redfish_interfaces.robot b/redfish_test/test_redfish_interfaces.robot
new file mode 100644
index 0000000..17324c7
--- /dev/null
+++ b/redfish_test/test_redfish_interfaces.robot
@@ -0,0 +1,30 @@
+*** Settings ***
+Documentation    Test Redfish interfaces supported.
+
+Resource    ../lib/redfish_client.robot
+
+** Test Cases **
+
+Get Redfish Response Codes
+    [Documentation]  Get Redfish response codes and validate them.
+    [Tags]  Get_Redfish_Response_Codes
+    [Template]  Execute Get And Check Response
+
+    # Expected status    URL Path
+    ${HTTP_OK}           Systems
+    ${HTTP_OK}           Systems/motherboard
+    ${HTTP_OK}           Chassis/system
+    ${HTTP_OK}           Managers/openbmc/EthernetInterfaces/eth0
+    ${HTTP_NOT_FOUND}    /i/dont/exist/
+
+*** Keywords ***
+
+Execute Get And Check Response
+    [Documentation]  Execute "GET" request and check for expected status.
+    [Arguments]  ${expected_response_code}  ${url_path}
+    # Description of argument(s):
+    # expected_response_code   Expected REST status codes.
+    # url_path                 URL path.
+
+    ${resp} =  Redfish Get Request  ${url_path}  response_format=${0}
+    Should Be Equal As Strings  ${resp.status_code}  ${expected_response_code}