Port suite from mkumatag personal repo w/o history

All these files came from https://github.com/mkumatag/openbmc-automation
The decision to remove the commit history was because most of the 122
commits did not follow commit comment AND content best practices.
The ability to remove the commit history was possible because all
contributors where from the same company (IBM) making the coordination /
notification/acceptence easy.  See all the gory details about the
first try to commit with history here...
https://github.com/openbmc/openbmc-test-automation/pull/1

This suite of tests will run against an OpenBMC based server.  It will
run good/bad path testing against the REST interface.  There are tests
that will also run ipmitool on the victim BMC too.

If you want to support a new system in to the suite you should only
have to edit two files...
    data/<system>.py
    tox.ini

The README.md contains details on how to setup for the first time along
with how to execute the test suite

NOTE: some test cases require tools that do not exist on the system.
Currently the ipmitool is needed and if you do not manually copy / link
it in to the tools directory some suites will fail.
diff --git a/lib/disable_warning_urllib.py b/lib/disable_warning_urllib.py
new file mode 100644
index 0000000..1082f24
--- /dev/null
+++ b/lib/disable_warning_urllib.py
@@ -0,0 +1,16 @@
+#!/usr/bin/python
+import logging
+import warnings
+import httplib
+
+warnings.filterwarnings("ignore")
+
+# Hijack the HTTP lib logger message and Log only once
+requests_log = logging.getLogger("requests.packages.urllib3")
+requests_log.setLevel(logging.CRITICAL)
+requests_log.propagate = False
+
+class disable_warning_urllib():
+    def do_nothing():
+        return
+
diff --git a/lib/ipmi_client.robot b/lib/ipmi_client.robot
new file mode 100755
index 0000000..e7d96b4
--- /dev/null
+++ b/lib/ipmi_client.robot
@@ -0,0 +1,36 @@
+*** Settings ***
+Documentation           This module is for IPMI client for copying ipmitool to
+...                     openbmc box and execute ipmitool commands.
+
+Resource        ../lib/resource.txt
+
+Library                SSHLibrary
+Library                OperatingSystem
+
+*** Keywords ***
+Open Connection And Log In
+    Open connection     ${OPENBMC_HOST}
+    Login   ${OPENBMC_USERNAME}    ${OPENBMC_PASSWORD}
+    Copy ipmitool
+
+Run IPMI Command
+    [arguments]    ${args}
+    ${output}   ${stderr}=  Execute Command    /tmp/ipmitool -I dbus raw ${args}  return_stderr=True
+    Should Be Empty 	${stderr}
+    set test variable    ${OUTPUT}     "${output}"
+
+Run IPMI Standard Command
+    [arguments]    ${args}
+    ${stdout}    ${stderr}    ${output}=  Execute Command    /tmp/ipmitool -I dbus ${args}    return_stdout=True    return_stderr= True    return_rc=True
+    Should Be Equal    ${output}    ${0}    msg=${stderr}
+    [return]    ${stdout}
+
+Copy ipmitool
+    OperatingSystem.File Should Exist   tools/ipmitool      msg=The ipmitool program could not be found in the tools directory. It is not part of the automation code by default. You must manually copy or link the correct openbmc version of the tool in to the tools directory in order to run this test suite.
+
+    Import Library      SCPLibrary      WITH NAME       scp
+    scp.Open connection     ${OPENBMC_HOST}     username=${OPENBMC_USERNAME}      password=${OPENBMC_PASSWORD}
+    scp.Put File    tools/ipmitool   /tmp
+    SSHLibrary.Open Connection     ${OPENBMC_HOST}
+    Login   ${OPENBMC_USERNAME}    ${OPENBMC_PASSWORD}
+    Execute Command     chmod +x /tmp/ipmitool
diff --git a/lib/pdu/pdu.robot b/lib/pdu/pdu.robot
new file mode 100644
index 0000000..111952e
--- /dev/null
+++ b/lib/pdu/pdu.robot
@@ -0,0 +1,15 @@
+*** Settings ***
+Documentation           Generic PDU library
+
+Resource        ../../lib/resource.txt
+
+*** Keywords ***
+Validate Prereq
+    ${PDU_VAR_LIST} =    Create List    PDU_TYPE    PDU_IP  PDU_USERNAME    PDU_PASSWORD    PDU_SLOT_NO
+    : FOR    ${PDU_VAR}    IN    @{PDU_VAR_LIST}
+    \    Should Not Be Empty    ${${PDU_VAR}}   msg=Unable to find variable ${PDU_VAR}
+
+PDU Power Cycle
+    Validate Prereq
+    Import Resource  ${CURDIR}/../../lib/pdu/${PDU_TYPE}.robot
+    Power Cycle
diff --git a/lib/pdu/synaccess.robot b/lib/pdu/synaccess.robot
new file mode 100644
index 0000000..0810ec3
--- /dev/null
+++ b/lib/pdu/synaccess.robot
@@ -0,0 +1,16 @@
+*** Settings ***
+Documentation           synaccess PDU library
+
+Resource        ../../lib/pdu/pdu.robot
+Library         RequestsLibrary.RequestsKeywords
+
+*** Keywords ***
+Connect and Login
+    Validate Prereq
+    Open Connection     ${PDU_IP}
+    ${auth}=    Create List     ${PDU_USERNAME}    ${PDU_PASSWORD}
+    Create Session    pdu    http://${PDU_IP}   auth=${auth}
+
+Power Cycle
+    Connect and Login
+    ${ret}=    Get Request    pdu    /cmd.cgi?$A4 ${PDU_SLOT_NO}
diff --git a/lib/pythonutil.py b/lib/pythonutil.py
new file mode 100644
index 0000000..29efb78
--- /dev/null
+++ b/lib/pythonutil.py
@@ -0,0 +1,11 @@
+from socket import inet_ntoa
+from struct import pack
+
+
+def calcDottedNetmask(mask):
+    bits = 0
+    for i in xrange(32-mask,32):
+        bits |= (1 << i)
+    packed_value = pack('!I', bits)
+    addr = inet_ntoa(packed_value)
+    return addr
diff --git a/lib/resource.txt b/lib/resource.txt
new file mode 100755
index 0000000..2800581
--- /dev/null
+++ b/lib/resource.txt
@@ -0,0 +1,37 @@
+*** Settings ***
+Library           Collections
+Library           String
+Library           RequestsLibrary.RequestsKeywords
+Library           OperatingSystem
+Variables         ../data/variables.py
+
+*** Variables ***
+${OPENBMC_HOST}    9.3.164.161
+${DBUS_PREFIX}    ${EMPTY}
+${PORT}           ${EMPTY}
+${AUTH_URI}       https://${OPENBMC_HOST}
+${OPENBMC_USERNAME}    root
+${OPENBMC_PASSWORD}    0penBmc
+${MACHINE_TYPE}    palmetto
+${DBUS_POLL_INTERVAL}      15s
+${OPENBMC_REBOOT_TIMEOUT}   ${10}
+
+# PDU related parameters
+${PDU_TYPE}         ${EMPTY}
+${PDU_IP}           ${EMPTY}
+${PDU_USERNAME}     ${EMPTY}
+${PDU_PASSWORD}     ${EMPTY}
+${PDU_SLOT_NO}      ${EMPTY}
+
+*** Keywords ***
+Get Inventory Schema
+    [Arguments]    ${machine}
+    [Return]    &{INVENTORY}[${machine}]
+
+Get Inventory Items Schema
+    [Arguments]    ${machine}
+    [Return]    &{INVENTORY_ITEMS}[${machine}]
+
+Get Sensor Schema
+    [Arguments]    ${machine}
+    [Return]    &{SENSORS}[${machine}]
diff --git a/lib/rest_client.robot b/lib/rest_client.robot
new file mode 100644
index 0000000..bd2db37
--- /dev/null
+++ b/lib/rest_client.robot
@@ -0,0 +1,149 @@
+*** Settings ***
+Library           Collections
+Library           String
+Library           RequestsLibrary.RequestsKeywords
+Library           OperatingSystem
+Resource          ../lib/resource.txt
+Library           ../lib/disable_warning_urllib.py
+
+*** 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
+
+*** Keywords ***
+OpenBMC Get Request
+    [Arguments]    ${uri}    &{kwargs}
+    ${base_uri}=    Catenate    SEPARATOR=    ${DBUS_PREFIX}    ${uri}
+    Log Request    method=Get    base_uri=${base_uri}    args=&{kwargs}
+    Initialize OpenBMC
+    ${ret}=    Get Request    openbmc    ${base_uri}    &{kwargs}
+    Log Response    ${ret}
+    [Return]    ${ret}
+
+OpenBMC Post Request
+    [Arguments]    ${uri}    &{kwargs}
+    ${base_uri}=    Catenate    SEPARATOR=    ${DBUS_PREFIX}    ${uri}
+    ${headers}=     Create Dictionary   Content-Type=application/json
+    set to dictionary   ${kwargs}       headers     ${headers}
+    Log Request    method=Post    base_uri=${base_uri}    args=&{kwargs}
+    Initialize OpenBMC
+    ${ret}=    Post Request    openbmc    ${base_uri}    &{kwargs}
+    Log Response    ${ret}
+    [Return]    ${ret}
+
+OpenBMC Put Request
+    [Arguments]    ${uri}    &{kwargs}
+    ${base_uri}=    Catenate    SEPARATOR=    ${DBUS_PREFIX}    ${uri}
+    ${headers}=     Create Dictionary   Content-Type=application/json
+    set to dictionary   ${kwargs}       headers     ${headers}
+    Log Request    method=Put    base_uri=${base_uri}    args=&{kwargs}
+    Initialize OpenBMC
+    ${ret}=    Put Request    openbmc    ${base_uri}    &{kwargs}
+    Log Response    ${ret}
+    [Return]    ${ret}
+
+OpenBMC Delete Request
+    [Arguments]    ${uri}    &{kwargs}
+    ${base_uri}=    Catenate    SEPARATOR=    ${DBUS_PREFIX}    ${uri}
+    Log Request    method=Delete    base_uri=${base_uri}    args=&{kwargs}
+    Initialize OpenBMC
+    ${ret}=    Put Request    openbmc    ${base_uri}    &{kwargs}
+    Log Response    ${ret}
+    [Return]    ${ret}
+
+Initialize OpenBMC
+    Create Session    openbmc    ${AUTH_URI}  timeout=5   max_retries=1
+    ${headers}=     Create Dictionary   Content-Type=application/json
+    @{credentials} =   Create List     ${OPENBMC_USERNAME}      ${OPENBMC_PASSWORD}
+    ${data} =   create dictionary   data=@{credentials}
+    ${resp} =   Post Request    openbmc    /login    data=${data}   headers=${headers}
+    should be equal as strings      ${resp.status_code}     ${HTTP_OK}
+
+Log Request
+    [Arguments]    &{kwargs}
+    ${msg}=    Catenate    SEPARATOR=    URI:    ${AUTH_URI}    ${kwargs["base_uri"]}    , method:
+    ...    ${kwargs["method"]}    , args:    ${kwargs["args"]}
+    Logging    ${msg}    console=True
+
+Log Response
+    [Arguments]    ${resp}
+    ${msg}=    Catenate    SEPARATOR=    Response code:    ${resp.status_code}    , Content:    ${resp.content}
+    Logging    ${msg}    console=True
+
+Logging
+    [Arguments]    ${msg}    ${console}=default False
+    Log    ${msg}    console=True
+
+Read Attribute
+    [arguments]    ${uri}    ${attr}
+    ${resp} =   OpenBMC Get Request    ${uri}/attr/${attr}
+    ${content}=     To Json    ${resp.content}
+    [return]    ${content["data"]}
+
+Write Attribute
+    [Arguments]    ${uri}      ${attr}    &{kwargs}
+    ${base_uri}=    Catenate    SEPARATOR=    ${DBUS_PREFIX}    ${uri}
+    ${resp} =       openbmc put request    ${base_uri}/attr/${attr}     &{kwargs}
+    should be equal as strings      ${resp.status_code}     ${HTTP_OK}  
+    ${json} =   to json         ${resp.content}
+
+Read Properties
+    [arguments]    ${uri}
+    ${resp} =   OpenBMC Get Request    ${uri}   timeout=10
+    Should Be Equal As Strings    ${resp.status_code}    ${HTTP_OK}
+    ${content}=     To Json    ${resp.content}
+    [return]    ${content["data"]}
+
+Call Method
+    [arguments]    ${uri}    ${method}    &{kwargs}
+    ${base_uri}=    Catenate    SEPARATOR=    ${DBUS_PREFIX}    ${uri}
+    ${resp} =       openbmc post request    ${base_uri}/action/${method}     &{kwargs}
+    [return]     ${resp}
diff --git a/lib/utilities.py b/lib/utilities.py
new file mode 100755
index 0000000..95201dc
--- /dev/null
+++ b/lib/utilities.py
@@ -0,0 +1,105 @@
+#!/usr/bin/python -u
+import sys
+from robot.libraries.BuiltIn import BuiltIn
+import imp
+import string
+
+
+def get_sensor(module_name, value):
+	m = imp.load_source('module.name', module_name)
+
+	for i in m.ID_LOOKUP['SENSOR']:
+
+		if m.ID_LOOKUP['SENSOR'][i] == value:
+			return i
+
+	return 0xFF
+	
+
+def get_inventory_sensor (module_name, value):
+	m = imp.load_source('module.name', module_name)
+
+	value = string.replace(value, m.INVENTORY_ROOT, '<inventory_root>')
+
+	for i in m.ID_LOOKUP['SENSOR']:
+
+		if m.ID_LOOKUP['SENSOR'][i] == value:
+			return i
+
+	return 0xFF
+
+
+################################################################
+#  This will return the URI's of the FRU type 
+#
+#  i.e.  get_inventory_list('../data/Palmetto.py')
+#
+#  [/org/openbmc/inventory//system/chassis/motherboard/cpu0/core0,
+#   /org/openbmc/inventory/system/chassis/motherboard/dimm0]
+################################################################
+def get_inventory_list(module_name):
+
+	l = []
+	m = imp.load_source('module.name', module_name)
+
+	
+	for i in m.ID_LOOKUP['FRU']:
+		s = m.ID_LOOKUP['FRU'][i]
+		s = s.replace('<inventory_root>',m.INVENTORY_ROOT)
+		l.append(s)
+	
+	return l
+
+
+################################################################
+#  This will return the URI's of the FRU type 
+#
+#  i.e.  get_inventory_fru_type_list('../data/Barreleye.py', 'CPU')
+#
+#  [/org/openbmc/inventory//system/chassis/motherboard/cpu0,
+#   /org/openbmc/inventory//system/chassis/motherboard/cpu1]
+################################################################
+def  get_inventory_fru_type_list(module_name, fru):
+	l = []
+	m = imp.load_source('module.name', module_name)
+
+	for i in m.FRU_INSTANCES.keys():
+		if m.FRU_INSTANCES[i]['fru_type'] == fru:
+			s = i.replace('<inventory_root>',m.INVENTORY_ROOT)
+			l.append(s)
+	
+	return l
+
+
+################################################################
+#  This will return the URI's of the FRU type that contain VPD
+#
+#  i.e.  get_vpd_inventory_list('../data/Palmetto.py', 'DIMM')
+#
+#  [/org/openbmc/inventory/system/chassis/motherboard/dimm0,
+#   /org/openbmc/inventory/system/chassis/motherboard/dimm1]
+################################################################
+def  get_vpd_inventory_list(module_name, fru):
+	l = []
+	m = imp.load_source('module.name', module_name)
+
+	for i in m.ID_LOOKUP['FRU_STR']:
+		x = m.ID_LOOKUP['FRU_STR'][i]
+
+		if m.FRU_INSTANCES[x]['fru_type'] == fru:
+			s = x.replace('<inventory_root>',m.INVENTORY_ROOT)
+			l.append(s)
+	
+	return l
+
+
+def call_keyword(keyword):
+    return BuiltIn().run_keyword(keyword)
+
+
+def main():
+	print get_vpd_inventory_list('../data/Palmetto.py', 'DIMM')
+
+
+if __name__ == "__main__":
+   main()
\ No newline at end of file
diff --git a/lib/utils.robot b/lib/utils.robot
new file mode 100644
index 0000000..2d45f49
--- /dev/null
+++ b/lib/utils.robot
@@ -0,0 +1,54 @@
+*** Settings ***
+Resource                ../lib/resource.txt
+Resource                ../lib/rest_client.robot
+
+Library                 OperatingSystem
+
+*** Variables ***
+${SYSTEM_SHUTDOWN_TIME}       ${5}
+
+*** Keywords ***
+
+Wait For Host To Ping
+    [Arguments]     ${host}
+    Wait Until Keyword Succeeds     ${OPENBMC_REBOOT_TIMEOUT}min    5 sec   Ping Host   ${host}
+
+Ping Host
+    [Arguments]     ${host}
+    ${RC}   ${output} =     Run and return RC and Output    ping -c 4 ${host}
+    Log     RC: ${RC}\nOutput:\n${output}
+    Should be equal     ${RC}   ${0}
+
+Get Boot Progress
+    ${state} =     Read Attribute    /org/openbmc/sensors/host/BootProgress    value
+    [return]  ${state}
+
+Is Power On
+    ${state} =    Get Boot Progress
+    Should be equal   ${state}     FW Progress, Starting OS
+
+Is Power Off
+    ${state} =    Get Boot Progress
+    Should be equal   ${state}     Off
+
+Power On Host
+    @{arglist}=   Create List
+    ${args}=     Create Dictionary    data=@{arglist}
+    ${resp}=   Call Method    /org/openbmc/control/chassis0/    powerOn    data=${args}
+    should be equal as strings      ${resp.status_code}     ${HTTP_OK}
+    Wait Until Keyword Succeeds	  3 min    	10 sec    Is Power On
+
+Power Off Host
+    @{arglist}=   Create List
+    ${args}=     Create Dictionary    data=@{arglist}
+    ${resp}=   Call Method    /org/openbmc/control/chassis0/    powerOff   data=${args}
+    should be equal as strings      ${resp.status_code}     ${HTTP_OK}
+    Wait Until Keyword Succeeds	  1 min    	10 sec    Is Power Off
+
+Trigger Warm Reset
+    log to console    "Triggering warm reset"
+    ${data} =   create dictionary   data=@{EMPTY}
+    ${resp} =   openbmc post request    /org/openbmc/control/bmc0/action/warmReset     data=${data}
+    Should Be Equal As Strings      ${resp.status_code}     ${HTTP_OK}
+    Sleep   ${SYSTEM_SHUTDOWN_TIME}min
+    Wait For Host To Ping   ${OPENBMC_HOST}