← Back to team overview

opencompute-developers team mailing list archive

[Merge] lp:~bladernr/opencompute/merge-github-junk into lp:opencompute/opencompute-testing

 

Jeff Lane has proposed merging lp:~bladernr/opencompute/merge-github-junk into lp:opencompute/opencompute-testing.

Requested reviews:
  Jeff Lane (bladernr)

For more details, see:
https://code.launchpad.net/~bladernr/opencompute/merge-github-junk/+merge/268148

Merges in all the stuff ITRI put into github.
-- 
Your team Open Compute Developers is subscribed to branch lp:opencompute/opencompute-testing.
=== added file 'README.tips'
--- README.tips	1970-01-01 00:00:00 +0000
+++ README.tips	2015-08-14 22:03:31 +0000
@@ -0,0 +1,121 @@
+############User manual and installation guide################
+Note: Please use Ubuntu 12.04 or lately.
+
+######[Run Checkbox]######
+$ opencompute-certification
+Note, sudo is not necessary, you should be prompted for a root password.
+
+######[Important directory]######
+Runtime Logs: $HOME/.cache/plainbox/
+Results: $HOME/.local/plainbox/
+
+##############################################################################################
+Before running ME/BMC test, please fill in related information in configuration file.
+Each section exists in configuration file has its own purpose.
+The following will explain how to fill in settings in each section.
+
+Note:
+1. Path of configuration file: /etc/xdg/bmc.cfg or /etc/xdg/me.cfg
+2. Without these settings pre-setting in configuration file, you won't start tests smoothly.
+
+##############################################################################################
+
+
+############User manual of each section################
+
+######[Targets]######
+For remotely access via IPMI/DCMI, you need to fill in ME/BMC IP address of SUT.
+For example, ME/BMC IP: 10.2.107.5
+[Targets]
+Target1: 10.2.107.5
+
+######[Account]######
+For remotely access via IPMI/DCMI, you need to fill in ME/BMC account here.
+For example, USER/PASSWORD: OCP/OCP. Then, the settings in this section must be
+[Account]
+USER: OCP
+PASSWORD: OCP
+
+######[Sensors] and [SensorsForCPUTemp]######
+For thermal tests of ME/BMC sensors, you need to check and set Sensor ID before starting tests.
+Refers to TC-001-0006-Hardware_Monitoring.txt.in,
+there are five kinds of sensors to monitor, so please write corresponding sensor ID to this field.
+For example, the sensor ID related to these five kinds of sensors on Winterfell
+are "outlet Temp", "inlet Temp", "PCH Temp", "P0 DIMM Temp", "P1 DIMM Temp", "P0 Therm Margin",
+"P1 Therm Margin", "CPU0 Tjmax", "CPU1 Tjmax"
+[Sensors]
+Outlet: Outlet Temp
+Inlet: Inlet Temp
+PCH: PCH Temp
+Px DIMM: P0 DIMM Temp
+Py DIMM: P1 DIMM Temp
+CPUx: CPU0 Temp
+CPUy: CPU1 Temp
+
+Note:
+        Case1. There are CPU sensors to monitor CPU temperature directly.
+               You just fill in sensor IDs behind key "CPUx" and "CPUy" and
+               don't care the section [SensorsForCPUTemp] at all.
+        Case2. There are no CPU sensors to monitor CPU temperature directly.
+               CPUx temperature is derived from Px Therm Margin and CPUx Tjmax.
+               ie,"CPU0 Temp" = "P0 Therm Margin" + "CPU0 Tjmax"
+               (It still requires "PU0 Temp" marked behind key "CPUx")
+               Besides, please also fill in "P0 Therm Margin", "PU0 Tjmax"
+               to corresponding section presented as below.
+               [SensorsForCPUTemp]
+               Px Therm Margin: P0 Therm Margin
+               Py Therm Margin: P1 Therm Margin
+               CPUx Tjmax: CPU0 Tjmax
+               CPUy Tjmax: CPU1 Tjmax
+
+
+######[SensorsForSampling]######
+Refers to test case TC-002-0008-001-Temp_Sampling_Increment, the description is to retrieve CPU and intake temperature 30 times.
+For example, the related sensor IDs on Winterfell are "Inlet Temp", "P0 Therm Margin", "P1 Therm Margin", "CPU0 Tjmax", "CPU1 Tjmax".
+[SensorsForSampling]
+Inlet: Inlet Temp
+CPUx: CPU0 Temp
+CPUy: CPU1 Temp
+Note: if the CPU0 temperature derives from "P0 therm Margin" and "CPU0 Tjmax",
+you have to give a string "CPU0 temp" behind key "CPUx". And also remember to fill in the sensor ID in section [SensorsForCPUTemp].
+Please refer to section [Sensors].
+
+
+##############################################################################################
+The following four sections [Admin Level], [Operator Level], [User Level] and [Add User Test] are for User level test.
+Please refer to TC-002-0009-User_Levels.txt.in. In these four sections, you don't need to modify settings here.
+
+######[Admin Level]######
+[Admin Level]
+ADMIN_NAME: ccma_admin
+ADMIN_PASSWD: ccma_admin
+priv_level: 4
+user_id: 3
+channel_num: 1
+Note: But please set the settings in the section using ipmitool/dcmitool manually on SUT before starting user level test.
+
+######[Operator Level]######
+[Operator Level]
+OPER_NAME: ccma_oper
+OPER_PASSWD: ccma_oper
+priv_level: 3
+user_id: 4
+channel_num: 1
+Note: But please set the settings in the section using ipmitool/dcmitool manually on SUT before starting user level test.
+
+######[User Level]######
+[User Level]
+USER_NAME: ccma_user
+USER_PASSWD: ccma_user
+priv_level: 2
+user_id: 5
+channel_num: 1
+Note: But please set the settings in the section using ipmitool/dcmitool manually on SUT before starting user level test.
+
+
+######[Add User Test]######
+[Add User Test]
+NEW_USER_NAME: ccma_test
+NEW_USER_ID: 6
+Note: Do not need to create this account manually
+

=== added file 'bin/bad_block_test'
--- bin/bad_block_test	1970-01-01 00:00:00 +0000
+++ bin/bad_block_test	2015-08-14 22:03:31 +0000
@@ -0,0 +1,72 @@
+#!/usr/bin/env python3
+
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+It is NOT YET officially approved by OCP.
+
+bad_block_test
+ 1. Use badblocks command to perform a full disk bad block scan 
+    with given pattern.
+ 2. The duration of the test is under 24 hours.
+ 3. Criteria: pass if no hard disk error.
+
+Authors
+  Nelson Chu <Nelson.Chu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+import os
+import re
+import sys
+from subprocess import check_output, STDOUT
+from argparse import ArgumentParser, RawTextHelpFormatter
+
+def run(pattern, device):
+    return_code = 0
+    command = "badblocks -wsvf -t {0} {1}".format(pattern, device)
+
+    try:
+        with open(os.devnull, "w") as NULL:
+            output = check_output(command, stderr=STDOUT, shell=True)
+            output = output.decode('utf-8')
+    except Exception as e:
+        print(e.output.decode('utf-8'))
+        return_code = 10
+        return return_code
+
+    bad_blocks_match = re.search(r'\n(Pass completed\,\s(\d+)\s.*)\n$', output)
+    if bad_blocks_match:
+        print(bad_blocks_match.group(1))
+        if int(bad_blocks_match.group(2)) != 0:
+            return_code = 20
+    else:
+        print("Cannot parse badblocks output.")
+        return_code = 30
+    return return_code
+
+def main():
+    parser = ArgumentParser(formatter_class=RawTextHelpFormatter)
+    parser.add_argument('-t', '--pattern', type=str, required=True,
+                        help=("Specify a test pattern to be read \n"
+                              + "(and written) to disk  blocks."))
+    parser.add_argument('-d', '--device', type=str, required=True,
+                        help=("The device which tests in badblocks."))
+    args = parser.parse_args()
+    return run(args.pattern, args.device)
+
+if __name__ == '__main__':
+    sys.exit(main())

=== modified file 'bin/bios_info'
--- bin/bios_info	2015-03-03 15:59:42 +0000
+++ bin/bios_info	2015-08-14 22:03:31 +0000
@@ -3,6 +3,8 @@
 Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
 Industrial Technology Research Institute
 
+It is NOT YET officially approved by OCP.
+
 bios_info
   1. Use lshw command to gather BIOS information.
   2. The program will output BIOS vendor, version and release date.

=== added file 'bin/block_device_resource'
--- bin/block_device_resource	1970-01-01 00:00:00 +0000
+++ bin/block_device_resource	2015-08-14 22:03:31 +0000
@@ -0,0 +1,80 @@
+#!/usr/bin/env python3
+
+import os
+import re
+from glob import glob
+
+rootdir_pattern = re.compile('^.*?/devices')
+
+def device_state(name):
+    """
+    Follow pmount policy to determine whether a device is removable or internal.
+    """
+    with open('/sys/block/%s/device/block/%s/removable' % (name, name)) as f:
+        if f.read(1) == '1':
+            return 'removable'
+
+    path = rootdir_pattern.sub('', os.readlink('/sys/block/%s' % name))
+    hotplug_buses = ("usb", "ieee1394", "mmc", "pcmcia", "firewire")
+    for bus in hotplug_buses:
+        if os.path.exists('/sys/bus/%s' % bus):
+            for device_bus in os.listdir('/sys/bus/%s/devices' % bus):
+                device_link = rootdir_pattern.sub('', os.readlink(
+                    '/sys/bus/%s/devices/%s' % (bus, device_bus)))
+                if re.search(device_link, path):
+                    return 'removable'
+
+    return 'internal'
+
+
+def usb_support(name, version):
+    """
+    Check the USB specification number for both hub port and device
+    """
+    path = rootdir_pattern.sub('', os.readlink('/sys/block/%s' % name))
+
+    # Remove the usb config.interface part of the path
+    m = re.match('((.*usb\d+).*\/)\d-[\d\.:\-]+\/.*', path)
+    if m:
+        device_path = m.group(1)
+        hub_port_path = m.group(2)
+
+        # Check the highest version of USB the device supports
+        with open('/sys/devices/%s/version' %device_path) as f:
+            if float(f.readline()) < version:
+                return 'unsupported'
+
+        # Check the highest version of USB the hub supports
+        with open('/sys/devices/%s/version' %hub_port_path) as f:
+            if float(f.readline()) < version:
+                return 'unsupported'
+
+        return 'supported'
+
+    return 'unsupported'
+
+def device_rotation(name):
+    with open('/sys/block/%s/device/block/%s/queue/rotational' % (name, name)) as f:
+        if f.read(1) == '1':
+            return 'yes'
+
+    return 'no'
+
+for path in glob('/sys/block/*/device'):
+    name = re.sub('.*/(.*?)/device', '\g<1>', path)
+    state = device_state(name)
+    usb2 = usb_support(name, 2.00)
+    usb3 = usb_support(name, 3.00)
+    rotation = device_rotation(name)
+    # FIXME: Remove leading block device name when the requirements
+    # checking code in Checkbox allows it
+    print("""\
+%(name)s_state: %(state)s
+%(name)s_usb2: %(usb2)s
+%(name)s_usb3: %(usb3)s
+%(name)s_rotation: %(rotation)s
+""" % {"name": name,
+       "state": state,
+       "usb2": usb2,
+       "usb3": usb3,
+       "rotation": rotation})

=== modified file 'bin/check_sata_port'
--- bin/check_sata_port	2015-03-03 15:59:42 +0000
+++ bin/check_sata_port	2015-08-14 22:03:31 +0000
@@ -3,6 +3,8 @@
 # Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
 # Industrial Technology Research Institute
 #
+# It is NOT YET officially approved by OCP.
+#
 # check_sata_port
 #   1. Use dmesg command to gather SATA information.
 #   2. Criteria: SATA port speed up to 6.0Gps.

=== added file 'bin/check_sata_port_leopard'
--- bin/check_sata_port_leopard	1970-01-01 00:00:00 +0000
+++ bin/check_sata_port_leopard	2015-08-14 22:03:31 +0000
@@ -0,0 +1,38 @@
+#!/bin/bash
+#
+# Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+# Industrial Technology Research Institute
+#
+# It is NOT YET officially approved by OCP.
+#
+# check_sata_port
+#   1. Retrieve dmesg log to gather SATA information.
+#   2. Criteria: SATA port speed up to 6.0Gps.
+#
+# Authors
+#   Nelson Chu <Nelson.Chu@xxxxxxxxxxx>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3,
+# as published by the Free Software 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.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+output=(`cat /var/log/dmesg |grep -i "SATA link up"| awk '{print $7}'`)
+
+for ((i=0; i<${#output[@]}; i++)); do
+    if [ "$output" != "6.0" ]; then
+	echo "Do not support SATA 6Gps ports"
+	exit 1
+    fi
+done
+
+echo "Support SATA 6Gps ports"
+exit 0

=== modified file 'bin/check_usb_port'
--- bin/check_usb_port	2015-03-03 15:59:42 +0000
+++ bin/check_usb_port	2015-08-14 22:03:31 +0000
@@ -3,6 +3,8 @@
 # Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
 # Industrial Technology Research Institute
 #
+# It is NOT YET officially approved by OCP.
+#
 # check_usb_port
 #   1. Use dmesg command to gather USB information.
 #   2. Criteria: USB version must be 2.0.

=== added file 'bin/check_usb_port_leopard'
--- bin/check_usb_port_leopard	1970-01-01 00:00:00 +0000
+++ bin/check_usb_port_leopard	2015-08-14 22:03:31 +0000
@@ -0,0 +1,43 @@
+#!/bin/bash
+#
+# Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+# Industrial Technology Research Institute
+#
+# It is NOT YET officially approved by OCP.
+#
+# check_usb_port
+#   1. Retrieve dmesg log to gather USB information.
+#   2. Criteria: USB version must be 2.0 or higher.
+#
+# Authors
+#   Nelson Chu <Nelson.Chu@xxxxxxxxxxx>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3,
+# as published by the Free Software 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.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+support_usb_3=`cat /var/log/dmesg |grep -i "xhci_hcd" -c`
+
+if [ "$support_usb_3" -gt "0" ]; then
+    echo "Support USB 3.0 ports."
+    exit 0
+fi
+
+output=`cat /var/log/dmesg |grep -i ehci_hcd:| awk '{print $5}'`
+
+if [ "$output" = "2.0" ]; then
+    echo "Support USB 2.0 ports."
+    exit 0
+fi
+
+echo "Do not support USB 2.0 ports or higher."
+exit 1

=== modified file 'bin/cpu_info'
--- bin/cpu_info	2015-03-03 15:59:42 +0000
+++ bin/cpu_info	2015-08-14 22:03:31 +0000
@@ -3,6 +3,8 @@
 Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications 
 Industrial Technology Research Institute
 
+It is NOT YET officially approved by OCP.
+
 cpu_info
   Use lshw command to gather CPU information.
   The program will output CPU model and L1, L2, L3 cache size.

=== added file 'bin/cpu_info_leopard'
--- bin/cpu_info_leopard	1970-01-01 00:00:00 +0000
+++ bin/cpu_info_leopard	2015-08-14 22:03:31 +0000
@@ -0,0 +1,83 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications 
+Industrial Technology Research Institute
+
+It is NOT YET officially approved by OCP.
+
+cpu_info
+  Use dmidecode command to gather CPU information.
+  The program will output CPU model and L1, L2, L3 cache size.
+  Criteria: CPU model and product family must match user's input.
+
+Authors
+  Nelson Chu <Nelson.Chu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+import os
+import re
+import sys
+import xml.etree.ElementTree as ET
+from subprocess import check_output
+from argparse import ArgumentParser, RawTextHelpFormatter
+
+def run(product, family):
+    command = "dmidecode -t processor |grep -E 'Version|Cache'"
+    with open(os.devnull, 'w') as NULL:
+        output = check_output(command, stderr=NULL, shell=True)
+    output = output.decode('utf-8').strip()
+
+    cpu_attr = []
+    for item in output.split('\n'):
+        cpu_attr.append(item.strip())
+
+    for attr in cpu_attr:
+        if attr.startswith("Version"):
+            processor = attr.split(':')[1].strip()
+            print(processor)
+            match = re.search(product + '.*' + family, processor)
+            if not match:
+                print("Fail: Cannot match CPU %s %s family." %(product, family)
+                      ,file=sys.stderr)
+                return 1
+        else:
+            cache_handle = attr.split(':')[1].strip()
+            command = "dmidecode -t cache|grep -a6 {0}".format(cache_handle) +\
+                "|grep -E 'Socket Designation|Installed Size'"
+            with open(os.devnull, 'w') as NULL:
+                output = check_output(command, stderr=NULL, shell=True)
+            output = output.decode('utf-8').strip()
+            print(output.split('\n')[0].split(':')[1].strip(),":", end="")
+            print(output.split('\n')[1].split(':')[1].strip())
+
+    return 0
+
+def main():
+    parser = ArgumentParser(formatter_class=RawTextHelpFormatter)
+
+    parser.add_argument('-p', '--product', type=str, required=True,
+                        help=("The CPU product name. [Example: Xeon]"))
+    parser.add_argument('-f', '--family', type=str, required=True,
+                        help=("Processor family. [Example: E5]"))
+
+    args = parser.parse_args()
+
+    product = args.product.title()
+    family = args.family.title()
+    return run(product, family)
+
+if __name__ == '__main__':
+    sys.exit(main())

=== added file 'bin/create_raid'
--- bin/create_raid	1970-01-01 00:00:00 +0000
+++ bin/create_raid	2015-08-14 22:03:31 +0000
@@ -0,0 +1,140 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+It is NOT YET officially approved by OCP.
+
+create_raid
+  Use megacli command to build user desired RAID on JBOD.
+
+  Warning: Make sure there is no RAID configuration in LSI RAID card 
+           before this program is performed.
+
+Authors
+  Nelson Chu <Nelson.Chu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+import os
+import re
+import sys
+from time import sleep
+from subprocess import check_output, STDOUT, CalledProcessError
+from argparse import ArgumentParser, RawTextHelpFormatter
+
+def get_adapter():
+    """
+    Gather all adapter number if there are multiple RAID cards.
+    """
+
+    command = 'megacli -CfgDsply -Aall|grep Adapter'
+    adapter_list = []
+
+    adapter_info = check_output(command, shell=True)
+    adapter_info = adapter_info.decode('utf-8')
+
+    for adapter in adapter_info.strip().split('\n'):
+        adapter_list.append(adapter.strip().split(' ')[-1])
+    return adapter_list
+
+
+def get_all_disk(adapter):
+    """
+    Gather all disks Enclosure and Slot number, and make a 
+    Enclosure:Slot pair list.
+    """
+
+    command = 'megacli -PDList -A{0}'.format(adapter) \
+        + '|grep -E "Enclosure Device ID|Slot Number"'
+
+    disk_list = []
+    disk_info = check_output(command, shell=True)
+    disk_info = disk_info.decode('utf-8')
+
+    for line in disk_info.strip().split('\n'):
+        if line.startswith('Enclosure'):
+            match = re.search(r'\d+', line)
+            disk_list.append(match.group(0))
+        if line.startswith('Slot'):
+            match = re.search(r'\d+', line)
+            enclosure = disk_list.pop()
+            E_S = '%s:%s' %(enclosure, match.group(0))
+            disk_list.append(E_S)
+    return disk_list
+
+
+def build_raid(raid_type, adapter, disk_list):
+    """
+    Use all disks creatd RAID.
+    If RAID type is 6 then set last disk as hot spare.
+    """
+
+    if raid_type == 0:
+        disk = ','.join(disk_list)
+        command = 'megacli -CfgLDadd -r{0} [{1}] WB Direct -a{2}'.format(
+            raid_type, disk, adapter)
+
+    if raid_type == 6:
+        # use the last disk as hot spare
+        spare = disk_list.pop()
+
+        disk = ','.join(disk_list)
+        command = 'megacli -CfgLDadd -r{0} [{1}] WB Direct -Hsp[{2}] -a{3}'.format(
+            raid_type, disk, spare, adapter)
+
+    output = check_output(command, stderr=STDOUT, shell=True)
+    output = output.decode('utf-8')
+    # wait for raid created
+    sleep(5)
+    print(output)
+
+
+def main():
+    parser = ArgumentParser(formatter_class=RawTextHelpFormatter)
+    parser.add_argument('-t', '--type', type=int, required=True,
+                        help=("The RAID type which want to create. "
+                              "[Example: 0 or 6]"))
+    args = parser.parse_args()
+    knox_dict = {}
+
+    # get RAID card adapter number
+    try:
+        adapter_list = get_adapter()
+    except CalledProcessError as e:
+        print(e.output.decode('utf-8'))
+        return 10
+
+    # get all disks in JBOD
+    try:
+        for adapter in adapter_list:
+            knox_dict[adapter] = get_all_disk(adapter)
+    except CalledProcessError as e:
+        print(e.output.decode('utf-8'))
+        return 20
+
+    # use all HDDs to build RAID
+    try:
+        for adapter, disk_list in knox_dict.items():
+            build_raid(args.type, adapter, disk_list)
+    except CalledProcessError as e:
+        print(e.output.decode('utf-8'))
+        return 30
+
+    return 0
+
+
+if __name__ == '__main__':
+    sys.exit(main())

=== added file 'bin/dcmi_inventory'
--- bin/dcmi_inventory	1970-01-01 00:00:00 +0000
+++ bin/dcmi_inventory	2015-08-14 22:03:31 +0000
@@ -0,0 +1,136 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  dcmi_inventory
+  1. Use dcmitool to collect inventory information including Asset Tag, Device ID, System GUI, Firmware/Software Information, Management Controller ID
+  2. Criteria: All information mentioned above must not should not be null
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+import sys
+import time
+import shlex
+import subprocess
+import re
+import subprocess
+from subprocess import (
+    CalledProcessError,
+    check_call,
+    check_output
+)
+
+def get_asset_tag():
+
+    try:
+        cmd = 'dcmitool dcmi asset_tag'
+        dcmi_asset_tag_return = check_output(shlex.split(cmd), universal_newlines=True)
+        time.sleep(5)
+    except CalledProcessError as command_exception:
+        print("Failed executing dcmi command for getting asset tag. Reason:%s" % command_exception)
+   
+    try:
+        asset_tag = re.search(r'Asset tag\s*:\s*([a-zA-Z0-9-._ ]+)', dcmi_asset_tag_return)
+        if asset_tag == None:
+            return 'Error'
+        return asset_tag.group(1).strip()
+    except:
+        return 'Error'
+
+def get_guid():
+
+    try:
+        cmd = 'dcmitool mc guid'
+        dcmi_guid_return = check_output(shlex.split(cmd), universal_newlines=True)
+        time.sleep(5)
+    except CalledProcessError as command_exception:
+        print("Failed executing dcmi command for getting guid. Reason:%s" % command_exception)
+        
+    try:
+        mcguid = re.search(r'System GUID\s*:\s*([a-zA-Z0-9-._ ]+)', dcmi_guid_return)
+        if mcguid == None:
+            return 'Error'
+        return mcguid.group(1).strip()
+    except:
+        return 'Error'
+    
+def get_mcid():
+
+    try:
+        cmd = 'dcmitool dcmi get_mc_id_string'
+        dcmi_mcid_return = check_output(shlex.split(cmd), universal_newlines=True)
+        time.sleep(5)
+    except CalledProcessError as command_exception:
+        print("Failed executing dcmi command for getting mc id. Reason:%s" % command_exception)
+
+    try:
+        mcid =  re.search(r'Get Management Controller Identifier String\s*:\s*([a-zA-Z0-9-._ ]+)', dcmi_mcid_return)
+        if mcid == None:
+            return 'Error'
+        return mcid.group(1).strip()
+    except:
+        return 'Error'
+
+def get_mcinfo():
+
+    try:
+        cmd = 'dcmitool mc info'
+        dcmi_mcinfo_return = check_output(shlex.split(cmd), universal_newlines=True)
+        time.sleep(5)
+    except CalledProcessError as command_exception:
+        print("Failed executing dcmi command for getting mc info. Reason:%s" % command_exception)
+    
+    try:
+        deviceid = re.search(r'Device ID\s*:\s*([a-zA-Z0-9-._ ]+)', dcmi_mcinfo_return)
+        Manufac = re.search(r'Manufacturer Name\s*:\s*([a-zA-Z-._ ]+)', dcmi_mcinfo_return)
+        Firm = re.search(r'Firmware Revision\s+\s*:\s*([a-zA-Z0-9-._ ]+)', dcmi_mcinfo_return)
+
+        if deviceid == None or Manufac == None or Firm == None:
+            return 'Error', 'Error', 'Error'
+        return (deviceid.group(1).strip(), Manufac.group(1).strip(), Firm.group(1).strip())
+    except:
+        return 'Error', 'Error', 'Error'
+
+def main():
+
+    flag = 0
+    inventory_dict = {}
+    inventory_list = ['Asset Tag', 'System GUID', 'Get Management Controller Identifier String', 'Device ID', 'Manufacturer Name', 'Firmware Revision']
+    Device_ID, Manufacturer, Firmware = get_mcinfo()
+    inventory_dict.update({'Asset Tag':get_asset_tag()})
+    inventory_dict.update({'System GUID':get_guid()})
+    inventory_dict.update({'Get Management Controller Identifier String':get_mcid()})
+    inventory_dict.update({'Device ID':Device_ID})
+    inventory_dict.update({'Manufacturer Name':Manufacturer})
+    inventory_dict.update({'Firmware Revision':Firmware})
+
+    for item in inventory_list:
+        if inventory_dict.get(item) == 'Error':
+            flag = 1
+        else:
+            print("{}: {}".format(item, inventory_dict.get(item)))
+
+    if flag == 1:
+        return 1
+    return 0
+
+if __name__ == '__main__':
+    sys.exit(main())
+
+

=== added file 'bin/dcmi_power_off_on'
--- bin/dcmi_power_off_on	1970-01-01 00:00:00 +0000
+++ bin/dcmi_power_off_on	2015-08-14 22:03:31 +0000
@@ -0,0 +1,190 @@
+#! /usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  dcmi_power_off_on
+  Use dcmitool out-of-band access to turn on/off the SUT
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+
+import sys
+import configparser
+import shlex
+import subprocess
+import ast
+import time
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+
+def check_power_status(host_ip, user, password):
+
+    cmd_status_on = 'dcmitool -H {} -U {} -P {} power status| grep -q "on"'\
+			.format(host_ip, user, password)
+    check_on_value = subprocess.call(cmd_status_on, shell=True)
+    time.sleep(5)
+
+    cmd_status_off = 'dcmitool -H {} -U {} -P {} power status| grep -q "off"'\
+			.format(host_ip, user, password)
+    check_off_value = subprocess.call(cmd_status_off, shell=True)
+    time.sleep(5)
+
+    if check_on_value == 0 and check_off_value == 1:
+        check_status = 'on'
+    
+    elif check_on_value == 1 and check_off_value == 0:
+        check_status = 'off'
+
+    else:
+        check_status = 'error'
+
+    return check_status
+
+def run_power_off(host_ip, user, password):
+    cmd_power_off = 'dcmitool -H {} -U {} -P {} power off'\
+        .format(host_ip, user, password)
+    power_off_return_code = subprocess.call(cmd_power_off, shell=True)
+    return power_off_return_code
+
+def run_power_on(host_ip, user, password):
+    cmd_power_on = 'dcmitool -H {} -U {} -P {} power on'\
+        .format(host_ip, user, password)
+    power_on_return_code = subprocess.call(cmd_power_on, shell=True)
+    return power_on_return_code
+
+def dcmi_reset_oob(args):
+
+    #DCMI config file
+    DEFAULT_CFG = "/etc/checkbox.d/me.cfg"
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+
+    config = configparser.RawConfigParser()
+
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 20
+
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 30
+
+    try:
+        user_value = config.get('Account', 'USER')
+        passwd_value = config.get('Account', 'PASSWORD')
+        if not user_value or not passwd_value:
+            print("Invalid or Empty credential info")
+            return 40
+
+    except configparser.Error:
+        print("Invalid or Empty credential info")
+        return 50
+
+    ping_flag = 0
+    for tg in targets_list:
+    
+        if not tg or not user_value or not passwd_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for DCMI out-of-band access")
+            return 21
+        else:
+
+            print("SUT =", tg)
+            print("USER =", user_value)
+            print("PASSWORD =", passwd_value)
+
+            for n in range(2):
+
+                count = 0
+                while count < 10:
+                    ping_cmd = 'ping -c 1 {}>/dev/null 2>/dev/null'.format(tg)
+                    ping_rtn = subprocess.call(ping_cmd, shell=True)
+                    if ping_rtn == 0:
+                        print("Destination Host Reachable")
+                        
+                        #run test
+                        status = check_power_status(tg, user_value, passwd_value)
+
+                        if status == 'on':
+                            #run power off
+                            power_off_result = run_power_off(tg, user_value, passwd_value)
+                            print(" ")
+                            if power_off_result == 1:
+                                print("Failed to power off SUT.")
+                                return 88
+                        elif status == 'off':
+                            #run power on
+                            power_on_result = run_power_on(tg, user_value, passwd_value)
+                            print(" ")
+                            if power_on_result == 1:
+                                print("Failed to power on SUT.")
+                                return 99
+                        else:
+                            #do nothing
+                            print("Failed to check power status")
+                            return 77
+                        
+                        time.sleep(30)
+                        break
+
+                    else:
+                        time.sleep(10)
+                        count = count+1
+                        print("Destination Host Unreachable")
+
+                if count == 10:         
+                    print("Host Has No Response, End of Test")
+                    ping_flag = 100
+
+    if ping_flag == 100:
+        return 100
+    return 0
+
+def main():
+
+    intro_message = "Default config location is /etc/checkbox.d/me.cfg"
+    parser = ArgumentParser(description=intro_message,
+		 formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', type=str,
+		 default="/etc/checkbox.d/me.cfg",
+		 help="Supply config file for getting authentication info")
+    args = parser.parse_args()
+    return dcmi_reset_oob(args)
+
+if __name__ == "__main__":
+    sys.exit(main())

=== added file 'bin/dcmi_power_reset'
--- bin/dcmi_power_reset	1970-01-01 00:00:00 +0000
+++ bin/dcmi_power_reset	2015-08-14 22:03:31 +0000
@@ -0,0 +1,139 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  dcmi_power_reset
+  Complete 20 power reset on SUT successfully using dcmitool out-of-band access
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+
+import sys
+import configparser
+import shlex
+import subprocess
+import ast
+import time
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+
+def run(host_ip, user, password):
+    cmd = 'dcmitool -H {} -U {} -P {} power reset'.format(host_ip, user, password)
+    power_reset_return = check_output(shlex.split(cmd), universal_newlines=True)
+    return power_reset_return
+        
+def dcmi_reset_oob(args):
+
+    #DCMI config file
+    DEFAULT_CFG = "/etc/checkbox.d/me.cfg"
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+
+    config = configparser.RawConfigParser()
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 1
+
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 2
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 2
+
+    try:
+        user_value = config.get("Account", "USER")
+        password_value = config.get("Account", "PASSWORD")
+    except configparser.NoOptionError:
+        print("Invalid or Empty credential info")
+        return 3
+
+    ping_flag = 0
+    for tg in targets_list:    
+
+        if not tg or not user_value or not password_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for DCMI out-of-band access")
+            return 4
+        else:
+            print("SUT =", tg)
+            print("USER =", user_value)
+            print("PASSWORD =", password_value)
+
+            for n in range(20):
+                print("---------------- %s ----------------" % n)
+                count = 0
+                while count < 10:
+                    print("+++++++++++ %s ++++++++++++" % count)
+                    ping_cmd = 'ping -c 1 {}>/dev/null 2>/dev/null'.format(tg)
+                    ping_rtn = subprocess.call(ping_cmd, shell=True)
+
+                    if ping_rtn == 0:
+                        print("Destination Host Reachable")
+
+                        try:
+                            power_control = run(tg, user_value, password_value)
+                            print(power_control)
+                        except CalledProcessError as dcmi_exception:
+                            print("Failed executing dcmi, Reason: %s" % dcmi_exception)
+                            return 6
+
+                        time.sleep(30)
+                        break
+                    else:
+                        time.sleep(10)
+                        count = count+1
+                        print("Destination Host Unreachable")
+                
+                if count == 10:
+                    print("Host Has No Response, End of Test")
+                    ping_flag = 100
+
+    if ping_flag == 100:
+        return 100
+    return 0
+
+def main():
+
+    intro_message = "Default config location is /etc/checkbox.d/me.cfg"
+    parser = ArgumentParser(description=intro_message,
+                            formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config',
+                        default="/etc/checkbox.d/me.cfg",
+                        help="Supply config file for getting authentication info")
+    args = parser.parse_args()
+    return dcmi_reset_oob(args)
+
+if __name__ == "__main__":
+    sys.exit(main())

=== added file 'bin/dcmi_priv_admin'
--- bin/dcmi_priv_admin	1970-01-01 00:00:00 +0000
+++ bin/dcmi_priv_admin	2015-08-14 22:03:31 +0000
@@ -0,0 +1,174 @@
+#! /usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  dcmi_priv_admin  
+  1. Use dcmitool out-of-band to read power status, to perform power reset and add a new user account
+  2. Criteria: Reading power status, performing power reset and adding a user account must all be successful
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+
+import sys
+import configparser
+import shlex
+import subprocess
+import ast
+import time
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+
+def get_power_status(host_ip, user, password):
+    cmd_status = 'dcmitool -H {} -U {} -P {} power status 1>/dev/null 2>/dev/null'\
+        .format(host_ip, user, password)
+    status_code = subprocess.call(cmd_status, shell=True)
+    return status_code
+    
+def power_reset(host_ip, user, password):
+    cmd_reset = 'dcmitool -H {} -U {} -P {} power reset 1>/dev/null 2>/dev/null'\
+        .format(host_ip, user, password)
+    reset_code = subprocess.call(cmd_reset, shell=True)
+    return reset_code
+
+def add_user(host_ip, user, password, new_id, new_user):
+    cmd_add_user = 'dcmitool -H {} -U {} -P {} user set name {} {} 1>/dev/null 2>/dev/null'\
+        .format(host_ip, user, password, new_id, new_user)
+    add_user_code = subprocess.call(cmd_add_user, shell=True)
+    return add_user_code
+
+def dcmi_user_level_test(args):
+
+    #DCMI config file
+    DEFAULT_CFG = "/etc/checkbox.d/me.cfg"
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+    config = configparser.RawConfigParser()
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 20
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 20
+
+    try:
+        user_value = config.get("Admin Level", "ADMIN_NAME")
+        password_value = config.get("Admin Level", "ADMIN_PASSWD")
+    except configparser.NoOptionError:
+        print("Invalid or Empty credential info")
+        print("Require Operator Level info pre-configured in /etc/checkbox.d/me.cfg")
+        return 30
+
+    try:
+        new_user_value = config.get("Add User Test", "NEW_USER_NAME")
+        new_user_id_value = config.get("Add User Test", "NEW_USER_ID")
+    except configparser.NoOptionError:
+        print("Invalid or Empty new user info")
+        print("Require new User info pre-configured in /etc/checkbox.d/me.cfg")
+        return 40
+
+    flag = 0
+    for tg in targets_list:
+
+        if not tg or not user_value or not password_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for DCMI out-of-band access")
+            return 50
+        else:
+            print("SUT", tg)
+
+            ping_result = ping_test(tg)
+            if ping_result != 0:
+                return 88
+
+            status_result = get_power_status(tg, user_value, password_value)
+            time.sleep(5)
+
+            reset_result = power_reset(tg, user_value, password_value)
+            time.sleep(5)
+            if not new_user_value or not new_user_id_value:
+                print("Require new user info pre-configured in /etc/checkbox.d/me.cfg")
+                return 60
+            else:
+
+                ping_result = ping_test(tg)
+                if ping_result != 0:
+                    return 88
+
+                add_user_result = add_user(tg, user_value, password_value, new_user_id_value, new_user_value)
+                time.sleep(5)
+
+            if status_result == 0 and reset_result == 0 and add_user_result == 0:
+                print("User can read power status.")
+                print("User can reset power.")
+                print("User can add a new user.")
+            else:
+                print("Authentication: Not Administrator Level")
+                flag = 1
+
+    if flag == 1:
+        return 100
+    return 0
+
+def ping_test(host_ip):
+    count = 0
+    while count < 10:
+        ping_cmd = 'ping -c 1 {}>/dev/null 2>/dev/null'.format(host_ip)
+        ping_rtn = subprocess.call(ping_cmd, shell=True)
+        if ping_rtn == 0:
+            return 0
+        else:
+            print("Destination Host Unreachable")
+            time.sleep(10)
+            count = count+1
+
+    if count == 10:
+        print("Host Has No Response, End of Test")
+        return 1
+
+
+def main():
+
+    intro_message = "Default config location is /etc/checkbox.d/me.cfg"
+    parser = ArgumentParser(description=intro_message, formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', type=str,
+		 default="/etc/checkbox.d/me.cfg",
+		 help="Supply config file for getting authentication info")
+    args = parser.parse_args()
+    return dcmi_user_level_test(args)
+
+if __name__ == "__main__":
+    sys.exit(main())

=== added file 'bin/dcmi_priv_oper'
--- bin/dcmi_priv_oper	1970-01-01 00:00:00 +0000
+++ bin/dcmi_priv_oper	2015-08-14 22:03:31 +0000
@@ -0,0 +1,174 @@
+#! /usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  dcmi_priv_oper
+  1. Use dcmitool out-of-band to read power status, to perform power reset and add a new user account
+  2. Criteria: power status reading and power reset must be successful and must fail at adding a new user account
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+
+import sys
+import configparser
+import shlex
+import subprocess
+import ast
+import time
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+
+def get_power_status(host_ip, user, password):
+    cmd_status = 'dcmitool -H {} -U {} -P {} power status 1>/dev/null 2>/dev/null'\
+        .format(host_ip, user, password)
+    status_code = subprocess.call(cmd_status, shell=True)
+    return status_code
+    
+def power_reset(host_ip, user, password):
+    cmd_reset = 'dcmitool -H {} -U {} -P {} power reset 1>/dev/null 2>/dev/null'\
+        .format(host_ip, user, password)
+    reset_code = subprocess.call(cmd_reset, shell=True)
+    return reset_code
+
+def add_user(host_ip, user, password, new_id, new_user):
+    cmd_add_user = 'dcmitool -H {} -U {} -P {} user set name {} {} 1>/dev/null 2>/dev/null'\
+        .format(host_ip, user, password, new_id, new_user)
+    add_user_code = subprocess.call(cmd_add_user, shell=True)
+    return add_user_code
+
+def dcmi_user_level_test(args):
+
+    #DCMI config file
+    DEFAULT_CFG = "/etc/checkbox.d/me.cfg"
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+    config = configparser.RawConfigParser()
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 20
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 20
+
+    try:
+        user_value = config.get("Operator Level", "OPER_NAME")
+        password_value = config.get("Operator Level", "OPER_PASSWD")
+    except configparser.NoOptionError:
+        print("Invalid or Empty credential info")
+        print("Require Operator Level info pre-configured in /etc/checkbox.d/me.cfg")
+        return 30
+
+    try:
+        new_user_value = config.get("Add User Test", "NEW_USER_NAME")
+        new_user_id_value = config.get("Add User Test", "NEW_USER_ID")
+    except configparser.NoOptionError:
+        print("Invalid or Empty new user info")
+        print("Require new User info pre-configured in /etc/checkbox.d/me.cfg")
+        return 40
+
+    flag = 0
+    for tg in targets_list:
+
+        if not tg or not user_value or not password_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for DCMI out-of-band access")
+            return 50
+        else:
+            print("SUT", tg)
+
+            ping_result = ping_test(tg)
+            if ping_result != 0:
+                return 88
+
+            status_result = get_power_status(tg, user_value, password_value)
+            time.sleep(5)
+
+            reset_result = power_reset(tg, user_value, password_value)
+            time.sleep(5)
+            if not new_user_value or not new_user_id_value:
+                print("Require new user info pre-configured in /etc/checkbox.d/me.cfg")
+                return 60
+            else:
+
+                ping_result = ping_test(tg)
+                if ping_result != 0:
+                    return 88
+
+                add_user_result = add_user(tg, user_value, password_value, new_user_id_value, new_user_value)
+                time.sleep(5)
+
+            if status_result == 0 and reset_result == 0 and add_user_result == 1:
+                print("User can read power status.")
+                print("User can reset power.")
+                print("User can't add a new user.")
+            else:
+                print("Authentication: Not Operator Level")
+                flag = 1
+
+    if flag == 1:
+        return 100
+    return 0
+
+def ping_test(host_ip):
+    count = 0
+    while count < 10:
+        ping_cmd = 'ping -c 1 {}>/dev/null 2>/dev/null'.format(host_ip)
+        ping_rtn = subprocess.call(ping_cmd, shell=True)
+        if ping_rtn == 0:
+            return 0
+        else:
+            print("Destination Host Unreachable")
+            time.sleep(10)
+            count = count+1
+
+    if count == 10:
+        print("Host Has No Response, End of Test")
+        return 1
+
+
+def main():
+
+    intro_message = "Default config location is /etc/checkbox.d/me.cfg"
+    parser = ArgumentParser(description=intro_message, formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', type=str,
+		 default="/etc/checkbox.d/me.cfg",
+		 help="Supply config file for getting authentication info")
+    args = parser.parse_args()
+    return dcmi_user_level_test(args)
+
+if __name__ == "__main__":
+    sys.exit(main())

=== added file 'bin/dcmi_priv_user'
--- bin/dcmi_priv_user	1970-01-01 00:00:00 +0000
+++ bin/dcmi_priv_user	2015-08-14 22:03:31 +0000
@@ -0,0 +1,174 @@
+#! /usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  dcmi_priv_uesr  
+  1. Use dcmitool out-of-band to read power status, to perform power reset and add a new user account
+  2. Criteria: power status reading must be successful and must fail at power reset and adding a new user account
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+
+import sys
+import configparser
+import shlex
+import subprocess
+import ast
+import time
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+
+def get_power_status(host_ip, user, password):
+    cmd_status = 'dcmitool -H {} -U {} -P {} power status 1>/dev/null 2>/dev/null'\
+        .format(host_ip, user, password)
+    status_code = subprocess.call(cmd_status, shell=True)
+    return status_code
+    
+def power_reset(host_ip, user, password):
+    cmd_reset = 'dcmitool -H {} -U {} -P {} power reset 1>/dev/null 2>/dev/null'\
+        .format(host_ip, user, password)
+    reset_code = subprocess.call(cmd_reset, shell=True)
+    return reset_code
+
+def add_user(host_ip, user, password, new_id, new_user):
+    cmd_add_user = 'dcmitool -H {} -U {} -P {} user set name {} {} 1>/dev/null 2>/dev/null'\
+        .format(host_ip, user, password, new_id, new_user)
+    add_user_code = subprocess.call(cmd_add_user, shell=True)
+    return add_user_code
+
+def dcmi_user_level_test(args):
+
+    #DCMI config file
+    DEFAULT_CFG = "/etc/checkbox.d/me.cfg"
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+    config = configparser.RawConfigParser()
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 20
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 20
+
+    try:
+        user_value = config.get("User Level", "USER_NAME")
+        password_value = config.get("User Level", "USER_PASSWD")
+    except configparser.NoOptionError:
+        print("Invalid or Empty credential info")
+        print("Require User Level info pre-configured in /etc/checkbox.d/me.cfg")
+        return 30
+
+    try:
+        new_user_value = config.get("Add User Test", "NEW_USER_NAME")
+        new_user_id_value = config.get("Add User Test", "NEW_USER_ID")
+    except configparser.NoOptionError:
+        print("Invalid or Empty new user info")
+        print("Require new User info pre-configured in /etc/checkbox.d/me.cfg")
+        return 40
+
+    flag = 0
+    for tg in targets_list:
+
+        if not tg or not user_value or not password_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for DCMI out-of-band access")
+            return 50
+        else:
+            print("SUT", tg)
+
+            ping_result = ping_test(tg)
+            if ping_result != 0:
+                return 88
+
+            status_result = get_power_status(tg, user_value, password_value)
+            time.sleep(5)
+
+            reset_result = power_reset(tg, user_value, password_value)
+            time.sleep(5)
+            if not new_user_value or not new_user_id_value:
+                print("Require new user info pre-configured in /etc/checkbox.d/me.cfg")
+                return 60
+            else:
+
+                ping_result = ping_test(tg)
+                if ping_result != 0:
+                    return 88
+
+                add_user_result = add_user(tg, user_value, password_value, new_user_id_value, new_user_value)
+                time.sleep(5)
+
+            if status_result == 0 and reset_result == 1 and add_user_result == 1:
+                print("User can read power status.")
+                print("User can't reset power.")
+                print("User can't add a new user.")
+            else:
+                print("Authentication: Not User Level")
+                flag = 1
+
+    if flag == 1:
+        return 100
+    return 0
+
+def ping_test(host_ip):
+    count = 0
+    while count < 10:
+        ping_cmd = 'ping -c 1 {}>/dev/null 2>/dev/null'.format(host_ip)
+        ping_rtn = subprocess.call(ping_cmd, shell=True)
+        if ping_rtn == 0:
+            return 0
+        else:
+            print("Destination Host Unreachable")
+            time.sleep(10)
+            count = count+1
+
+    if count == 10:
+        print("Host Has No Response, End of Test")
+        return 1
+
+
+def main():
+
+    intro_message = "Default config location is /etc/checkbox.d/me.cfg"
+    parser = ArgumentParser(description=intro_message, formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', type=str,
+		 default="/etc/checkbox.d/me.cfg",
+		 help="Supply config file for getting authentication info")
+    args = parser.parse_args()
+    return dcmi_user_level_test(args)
+
+if __name__ == "__main__":
+    sys.exit(main())

=== added file 'bin/dcmi_sampling'
--- bin/dcmi_sampling	1970-01-01 00:00:00 +0000
+++ bin/dcmi_sampling	2015-08-14 22:03:31 +0000
@@ -0,0 +1,271 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  dcmi_sampling
+  1. Retrieve CPU and intake temperature 30 times at 3 second intervals using dcmitool
+  2. If failed to retrieve temperature at any time within 30 times, the test is considered failed
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+import sys
+import time
+import re
+import configparser
+import shlex
+import subprocess
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+
+def get_sdr_remote(host_ip, user, password):
+    cmd = "dcmitool -H {} -U {} -P {} sdr".format(host_ip, user, password)
+    sdr_return = subprocess.check_output(shlex.split(cmd), stderr=subprocess.STDOUT,
+                                         universal_newlines=True)
+    return sdr_return
+
+def parse_sdr(output):
+    output = output.strip()
+    output_1Line = output.split("\n")
+    data = {}
+
+    for line in output_1Line:
+        sub_value = {}
+        string_list = line.split("|")
+        name = string_list[0].strip()
+        sensor_output = string_list[1].strip()
+        sub_value.update({'output':sensor_output})
+        status = string_list[2].strip()
+        sub_value.update({'status':status})
+        data.update({name:sub_value})
+    return data
+
+def calculate_CPU_temp(data_dict, CPU_Therm_Margin_id, CPU_Tjmax_id):
+    if data_dict.get(CPU_Therm_Margin_id) and data_dict.get(CPU_Tjmax_id):
+        if data_dict.get(CPU_Therm_Margin_id).get('status') == 'ok' and data_dict.get(CPU_Tjmax_id).get('status') == 'ok':
+            P_Therm_Margin_output = data_dict.get(CPU_Therm_Margin_id).get('output')
+            CPU_Tjmax_output = data_dict.get(CPU_Tjmax_id).get('output')
+            P_Therm_Margin = re.search(r'[0-9-]+', P_Therm_Margin_output).group(0)
+            CPU_Tjmax = re.search(r'[0-9-]+', CPU_Tjmax_output).group(0)
+            CPU_temp = int(P_Therm_Margin)+int(CPU_Tjmax)
+            return str(CPU_temp)+' degrees C'
+        else:
+            return 'Error'
+    else:
+        return 'None'
+        
+def dcmi_sdr(args):
+
+    cmd_flag = 0
+    #DCMI config file
+    DEFAULT_CFG = "/etc/checkbox.d/me.cfg"
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+
+    config = configparser.RawConfigParser()
+
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    try:
+        sensor_nick = config.options("SensorsForSampling")
+    except configparser.NoSectionError:
+        print("No Section: SensorsForSampling")
+        return 20
+
+    if sensor_nick:
+        sensor_list = []
+        for id in sensor_nick:
+            sensor_key = config.get("SensorsForSampling", id)
+            if sensor_key:
+                sensor_list.append(sensor_key)
+            else:
+                print("No Sensor ID specified in Config file")
+                return 30
+    else:
+        print("No key of Sensor ID specified in config file")
+        return 40
+
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 60
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 60
+
+    try:
+        user_value = config.get("Account", "USER")
+        password_value = config.get("Account", "PASSWORD")
+    except configparser.NoOptionError:
+        print("Invalid or Empty credential info")
+        return 70
+
+    for tg in targets_list:
+
+        if not tg or not user_value or not password_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for DCMI out-of-band access")
+            return 80
+        else:
+
+            c = 0
+            while c < 10:
+                ping_cmd = 'ping -c 1 {}>/dev/null 2>/dev/null'.format(tg)
+                ping_rtn = subprocess.call(ping_cmd, shell=True)
+                if ping_rtn == 0:
+                    print("Destination Host Reachable")
+                    break
+                else:
+                    time.sleep(10)
+                    c = c+1
+                    print("Destination Host Unreachable")
+
+            if c == 10:
+                print("Host Has No Response, End of Test")
+                return 99
+
+
+            sampling_data = []
+            times = 30
+            for n in range(times):
+
+                try:
+                    sensor_data = get_sdr_remote(tg, user_value, password_value)
+                    time.sleep(3)
+                except CalledProcessError as dcmi_exception:
+                    print("Failed executing dcmi, Reason: %s" % dcmi_exception)
+                    sensor_data = ''
+
+                sampling_data.append(sensor_data)
+            
+            count = 0
+            prs_flag = 0
+            dis_flag = 0
+            for output in sampling_data:
+                try:
+                    data = parse_sdr(output)
+                except:
+                    print("Parsing output of sdr table error")
+                    print("=======================================================")
+                    prs_flag = 1
+                    count = count+1
+                    continue
+
+                disable = 0
+                need_data = {}
+
+                for need_id in sensor_list:
+
+                    if data.get(need_id):
+                        need_value = data.get(need_id).get('output')
+                        need_data.update({need_id:need_value})
+                        if data.get(need_id).get('status') != 'ok':
+                            disable = 1
+                    else:
+
+                        try:
+                            CPUx_Temp = config.get("Sensors", "CPUx")
+                        except configparser.NoOptionError:
+                            CPUx_Temp = ''
+
+                        try:
+                            CPUy_Temp = config.get("Sensors", "CPUy")
+                        except configparser.NoOptionError:
+                            CPUy_Temp = ''
+                    
+                        if need_id == CPUx_Temp:
+                        
+                            try:
+                                PxTM = config.get("SensorsForCPUTemp", "Px Therm Margin")
+                            except configparser.NoOptionError:
+                                PxTM = ''
+
+                            try:
+                                CPUx_Tjmax = config.get("SensorsForCPUTemp", "CPUx Tjmax")
+                            except configparser.NoOptionError:
+                                CPUx_Tjmax = ''
+
+                            if PxTM and CPUx_Tjmax:
+                                Px_temp = calculate_CPU_temp(data, PxTM, CPUx_Tjmax) 
+                                need_data.update({CPUx_Temp:Px_temp})
+                                if Px_temp == 'None' or Px_temp == 'Error':
+                                    disable = 1
+                            else:
+                                disable = 1
+                                
+                        elif need_id == CPUy_Temp:
+
+                            try:
+                                PyTM = config.get("SensorsForCPUTemp", "Py Therm Margin")
+                            except configparser.NoOptionError:
+                                PyTM = ''
+
+                            try:
+                                CPUy_Tjmax = config.get("SensorsForCPUTemp", "CPUy Tjmax")
+                            except configparser.NoOptionError:
+                                CPUy_Tjmax = ''
+
+                            if PyTM and CPUy_Tjmax:
+                                Py_temp = calculate_CPU_temp(data, PyTM, CPUy_Tjmax)
+                                need_data.update({CPUy_Temp:Py_temp})
+                                if Py_temp == 'None' or Py_temp == 'Error':
+                                    disable = 1
+                            else:
+                                disable = 1
+                                
+                        else:
+                            need_data.update({need_id:'None'})
+                            disable = 1
+            
+                if disable == 1:
+                    dis_flag = 1
+                    print(need_data)
+                    print("=======================================================")
+                    count = count+1
+        print("Pass: %d" %(times-count))
+        print("Fail: %d" %(count))
+        
+    if cmd_flag == 1 or prs_flag == 1 or dis_flag == 1:
+        return 100
+    return 0
+
+def main():
+
+    intro_message = "Default config location is /etc/checkbox.d/me.cfg"
+    parser = ArgumentParser(description=intro_message, formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', type=str, default="/etc/checkbox.d/me.cfg", help="Supply config file for sensor IDs parameters")
+    args = parser.parse_args()
+    return dcmi_sdr(args)
+
+if __name__ == "__main__":
+    sys.exit(main())

=== added file 'bin/dcmi_thermal_ib'
--- bin/dcmi_thermal_ib	1970-01-01 00:00:00 +0000
+++ bin/dcmi_thermal_ib	2015-08-14 22:03:31 +0000
@@ -0,0 +1,212 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  dcmi_thermal_ib
+  1. Retrieve CPU, DIMM, chipset, inlet and outlet temperatures via DCMI in-band access using dcmitool.
+  2. The motherboard has five thermal sensors:
+     Two for CPU0 and CPU1 temperatures,
+     Two for CPU0 DIMM group and CPU1 DIMM group temperatures,
+     One for PCH temperature, 
+     One for Inlet temperature,
+     One for outlet temperature.
+  3. Criteria: Must retrieve temperatures from all abovementioned thermal sensors via DCMI in-band access.
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+import sys
+import time
+import re
+import configparser
+import shlex
+import subprocess
+import ast
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+
+
+def get_sdr():
+    cmd = "dcmitool sdr"
+    sdr_return = subprocess.check_output(shlex.split(cmd), universal_newlines=True)
+    return sdr_return
+
+def parse_sdr(output):
+    output = output.strip()
+    output_1Line = output.split("\n")
+    data = {}
+
+    for line in output_1Line:
+        sub_value = {}
+        string_list = line.split("|")
+        name = string_list[0].strip()
+        sensor_output = string_list[1].strip()
+        sub_value.update({'output':sensor_output})
+        status = string_list[2].strip()
+        sub_value.update({'status':status})
+        data.update({name:sub_value})
+    return data
+
+def calculate_CPU_temp(data_dict, CPU_Therm_Margin_id, CPU_Tjmax_id):
+
+    if data_dict.get(CPU_Therm_Margin_id) and data_dict.get(CPU_Tjmax_id):
+        if data_dict.get(CPU_Therm_Margin_id).get('status') == 'ok' and data_dict.get(CPU_Tjmax_id).get('status') == 'ok':
+            P_Therm_Margin_output = data_dict.get(CPU_Therm_Margin_id).get('output')
+            CPU_Tjmax_output = data_dict.get(CPU_Tjmax_id).get('output')
+            P_Therm_Margin = re.search(r'[0-9-]+', P_Therm_Margin_output).group(0)
+            CPU_Tjmax = re.search(r'[0-9-]+', CPU_Tjmax_output).group(0)
+            CPU_temp = int(P_Therm_Margin)+int(CPU_Tjmax)
+            return str(CPU_temp)+' degrees C'
+        else:
+            return 'Error'
+    else:
+        return 'None'
+
+def dcmi_sdr(args):
+
+    flag = 0
+    #DCMI config file
+    DEFAULT_CFG = "/etc/checkbox.d/me.cfg"
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+    config = configparser.RawConfigParser()
+
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    try:
+        sensor_nick = config.options("Sensors")			
+    except configparser.NoSectionError:
+        print("No Section: Sensors")
+        return 20
+
+    if sensor_nick:
+        sensor_list = []
+        for id in sensor_nick:
+            sensor_key = config.get("Sensors", id)
+            if sensor_key:
+                sensor_list.append(sensor_key)
+            else:
+                print("No Sensor ID specified in Config file")
+                return 30
+    else:
+        print("No key of Sensor ID specified in config file")
+        return 40
+
+    try:
+        sensor_data = get_sdr()
+        time.sleep(5)
+    except CalledProcessError as dcmi_exception:
+        print("Failed executing dcmi, Reason: %s" % dcmi_exception)
+        return 50
+
+    try:
+        data = parse_sdr(sensor_data)
+    except:
+        print("Parsing output of sdr table error")
+        return 60
+
+    need_data = {}
+    for need_id in sensor_list:
+        if data.get(need_id):
+            need_value = data.get(need_id).get('output')
+            need_data.update({need_id:need_value})
+            
+            if data.get(need_id).get('status') != 'ok':
+                flag = 1
+        else:
+
+           try:
+               CPUx_Temp = config.get("Sensors", "CPUx")
+           except configparser.NoOptionError:
+               CPUx_Temp = ''
+
+           try:
+               CPUy_Temp = config.get("Sensors", "CPUy")
+           except configparser.NoOptionError:
+               CPUy_Temp = ''
+
+           if need_id == CPUx_Temp:
+
+                try:
+                    PxTM = config.get("SensorsForCPUTemp", "Px Therm Margin")
+                except configparser.NoOptionError:
+                    PxTM = ''
+                    
+                try:
+                    CPUx_Tjmax = config.get("SensorsForCPUTemp", "CPUx Tjmax")
+                except configparser.NoOptionError:
+                    CPUx_Tjmax = ''
+
+                if PxTM and CPUx_Tjmax:
+                    need_data.update({CPUx_Temp:calculate_CPU_temp(data, PxTM, CPUx_Tjmax)})
+                    if calculate_CPU_temp(data, PxTM, CPUx_Tjmax) == 'None' or calculate_CPU_temp(data, PxTM, CPUx_Tjmax) == 'Error':
+                        flag = 1
+                else:
+                    flag = 1
+
+           elif need_id == CPUy_Temp:
+                
+                try:
+                    PyTM = config.get("SensorsForCPUTemp", "Py Therm Margin")
+                except configparser.NoOptionError:
+                    PyTM = ''
+
+                try:
+                    CPUy_Tjmax = config.get("SensorsForCPUTemp", "CPUy Tjmax")
+                except configparser.NoOptionError:
+                    CPUy_Tjmax = ''
+
+
+                if PyTM and CPUy_Tjmax:
+                    need_data.update({CPUy_Temp:calculate_CPU_temp(data, PyTM, CPUy_Tjmax)})
+                    if calculate_CPU_temp(data, PyTM, CPUy_Tjmax) == 'None' or calculate_CPU_temp(data, PyTM, CPUy_Tjmax) == 'Error':
+                        flag = 1
+                else:
+                    flag = 1
+           else:
+                flag = 1
+            
+        print("%s: %s" %(need_id, need_data.get(need_id)))
+
+    if flag == 1:
+        return 100
+    return 0
+
+def main():
+
+    intro_message = "Default config location is /etc/checkbox.d/me.cfg"
+    parser = ArgumentParser(description=intro_message, formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', type=str, default="/etc/checkbox.d/me.cfg", help="Supply config file for sensor IDs parameters")
+    args = parser.parse_args()
+    return dcmi_sdr(args)
+
+if __name__ == "__main__":
+    sys.exit(main())
+

=== added file 'bin/dcmi_thermal_oob'
--- bin/dcmi_thermal_oob	1970-01-01 00:00:00 +0000
+++ bin/dcmi_thermal_oob	2015-08-14 22:03:31 +0000
@@ -0,0 +1,243 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  dcmi_thermal_oob
+  1. Retrieving CPU, DIMM, chipset, inlet, outlet temperature via DCMI out-of-band access using dcmitool.
+  2. The motherboard has five thermal sensors: Two for CPU0 and CPU1 temperatures,
+     Two for CPU0 DIMM group and CPU1 DIMM group temperatures,
+     One for PCH temperature,
+     One for Inlet temperature,
+     One for outlet temperature.
+  3. Criteria: Must retrieve temperatures from all abovementioned thermal sensors via DCMI out-of-band access.
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+import sys
+import time
+import re
+import configparser
+import shlex
+import subprocess
+import ast
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+
+def get_sdr_remote(host_ip, user, password):
+    cmd = "dcmitool -H {} -U {} -P {} sdr".format(host_ip, user, password)
+    sdr_return = subprocess.check_output(shlex.split(cmd), stderr=subprocess.STDOUT,
+                                         universal_newlines=True)
+    return sdr_return
+
+def parse_sdr(output):
+    output = output.strip()
+    output_1Line = output.split("\n")
+    data = {}
+
+    for line in output_1Line:
+        sub_value = {}
+        string_list = line.split("|")
+        name = string_list[0].strip()
+        sensor_output = string_list[1].strip()
+        sub_value.update({'output':sensor_output})
+        status = string_list[2].strip()
+        sub_value.update({'status':status})
+        data.update({name:sub_value})
+    return data
+
+def calculate_CPU_temp(data_dict, CPU_Therm_Margin_id, CPU_Tjmax_id):
+
+    if data_dict.get(CPU_Therm_Margin_id) and data_dict.get(CPU_Tjmax_id):
+        if data_dict.get(CPU_Therm_Margin_id).get('status') == 'ok' and data_dict.get(CPU_Tjmax_id).get('status') == 'ok':
+            P_Therm_Margin_output = data_dict.get(CPU_Therm_Margin_id).get('output')
+            CPU_Tjmax_output = data_dict.get(CPU_Tjmax_id).get('output')
+            P_Therm_Margin = re.search(r'[0-9-]+', P_Therm_Margin_output).group(0)
+            CPU_Tjmax = re.search(r'[0-9-]+', CPU_Tjmax_output).group(0)
+            CPU_temp = int(P_Therm_Margin)+int(CPU_Tjmax)
+            return str(CPU_temp)+' degrees C'
+        else:
+            return 'Error'
+    else:
+        return 'None'
+
+def dcmi_sdr(args):
+
+    flag = 0
+    #DCMI config file
+    DEFAULT_CFG = "/etc/checkbox.d/me.cfg"
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+
+    config = configparser.RawConfigParser()
+
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    try:
+        sensor_nick = config.options("Sensors")
+    except configparser.NoSectionError:
+        print("No Section: Sensors")
+        return 20
+    
+    if sensor_nick:
+        sensor_list = []
+        for id in sensor_nick:
+            sensor_key = config.get("Sensors", id)
+            if sensor_key:
+                sensor_list.append(sensor_key)
+            else:
+                print("No Sensor ID specified in Config file")
+                return 30
+    else:
+        print("No key of Sensor ID specified in config file")
+        return 40
+
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 60
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 60
+
+    try:
+        user_value = config.get("Account", "USER")
+        password_value = config.get("Account", "PASSWORD")
+    except configparser.NoOptionError:
+        print("Invalid or Empty credential info")
+        return 70
+
+    for tg in targets_list:
+
+        if not tg or not user_value or not password_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for DCMI out-of-band access")
+            return 80
+        else:
+
+            print("SUT =", tg)
+            print("USER =", user_value)
+            print("PASSWORD =", password_value)
+
+            try:
+                sensor_data = get_sdr_remote(tg, user_value, password_value)
+                time.sleep(5)
+            except CalledProcessError as dcmi_exception:
+                print("Failed executing dcmi, Reason: %s" % dcmi_exception)
+                return 50
+
+            try:
+                data = parse_sdr(sensor_data)
+            except:
+                print("Parsing output of sdr table error")
+                flag = 1
+                continue
+
+            need_data = {}
+            for need_id in sensor_list:
+
+                if data.get(need_id):
+                    need_value = data.get(need_id).get('output')
+                    need_data.update({need_id:need_value})
+
+                    if data.get(need_id).get('status') != 'ok':
+                        flag = 1
+                else:
+
+                    try:
+                        CPUx_Temp = config.get("Sensors", "CPUx")
+                    except configparser.NoOptionError:
+                        CPUx_Temp = ''
+
+                    try:
+                        CPUy_Temp = config.get("Sensors", "CPUy")
+                    except configparser.NoOptionError:
+                        CPUy_Temp = ''
+
+                    if need_id == CPUx_Temp:
+
+                        try:
+                            PxTM = config.get("SensorsForCPUTemp", "Px Therm Margin")
+                        except configparser.NoOptionError:
+                            PxTM = ''
+
+                        try:
+                            CPUx_Tjmax = config.get("SensorsForCPUTemp", "CPUx Tjmax")
+                        except configparser.NoOptionError:
+                            CPUx_Tjmax = ''
+
+                        if PxTM and CPUx_Tjmax:
+                            need_data.update({CPUx_Temp:calculate_CPU_temp(data, PxTM, CPUx_Tjmax)})
+                            if calculate_CPU_temp(data, PxTM, CPUx_Tjmax) == 'None' or calculate_CPU_temp(data, PxTM, CPUx_Tjmax) == 'Error':
+                                flag = 1
+                        else:
+                            flag = 1
+
+                    elif need_id == CPUy_Temp:
+                        
+                        try:
+                            PyTM = config.get("SensorsForCPUTemp", "Py Therm Margin")
+                        except configparser.NoOptionError:
+                            PyTM = ''
+
+                        try:
+                            CPUy_Tjmax = config.get("SensorsForCPUTemp", "CPUy Tjmax")
+                        except configparser.NoOptionError:
+                            CPUy_Tjmax = ''
+                        
+                        if PyTM and CPUy_Tjmax:
+                            need_data.update({CPUy_Temp:calculate_CPU_temp(data, PyTM, CPUy_Tjmax)})
+                            if calculate_CPU_temp(data, PyTM, CPUy_Tjmax) == 'None' or calculate_CPU_temp(data, PyTM, CPUy_Tjmax) == 'Error':
+                                flag = 1
+                        else:
+                            flag = 1
+                    else:
+                        #need_data.update({need_id:'None'})
+                        flag = 1
+
+                print("%s: %s" %(need_id, need_data.get(need_id)))
+
+    if flag == 1:
+        return 100
+    return 0
+
+def main():
+
+    intro_message = "Default config location is /etc/checkbox.d/me.cfg"
+    parser = ArgumentParser(description=intro_message, formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', type=str, default="/etc/checkbox.d/me.cfg", help="Supply config file for sensor IDs parameters")
+    args = parser.parse_args()
+    return dcmi_sdr(args)
+
+if __name__ == "__main__":
+    sys.exit(main())

=== added file 'bin/disk_health'
--- bin/disk_health	1970-01-01 00:00:00 +0000
+++ bin/disk_health	2015-08-14 22:03:31 +0000
@@ -0,0 +1,138 @@
+#!/usr/bin/env python3
+
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+It is NOT YET officially approved by OCP.
+
+disk_health
+  1. Use smartmontools to monitor disk health.
+  2. SMART threshold, grown defect list (glist or reallocated sectors) 
+     <= 100 for 4TB, glist <=50 for 2TB for all vendors.
+  3. SMART HDD temp <= 60 degrees centigrade.
+  4. Criteria: all threshold must not exceed the criteria listed in item 2 
+               and 3.
+
+Authors
+  Nelson Chu <Nelson.Chu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+import os
+import re
+import sys
+from subprocess import check_output
+from argparse import ArgumentParser, RawTextHelpFormatter
+
+def run(device):
+    return_code = 0
+    command = "smartctl -a {0}".format(device)
+
+    try:
+        with open(os.devnull, "w") as NULL:
+            smartctl_info = check_output(command, stderr=NULL, shell=True)
+    except Exception as e:
+        print(e.output.decode('utf-8'))
+        return_code = 10
+        return return_code
+
+    smartctl_info = smartctl_info.decode('utf-8')
+
+    # Verify disk capacity match the criteria or not.
+    capacity_match =re.search(r'User Capacity.*\[(2|4).*TB\]', smartctl_info)
+    if not capacity_match:
+        print("Disk capacity is not match 2TB or 4TB.")
+        return_code = 20
+        return return_code
+
+    disk_capacity = int(capacity_match.group(1))
+    print("Disk capacity: %dTB" %(disk_capacity))
+
+    # Verify disk temperature match the criteria or not.
+    temperature_match = re.search(r'Temperature_Celsius.*\s(\d+)(\s\(|\n)',
+                                  smartctl_info)
+    if not temperature_match:
+        temperature_match = re.search(r'Current Drive Temperature\D*(\d+)',
+                                      smartctl_info)
+        if not temperature_match:
+            print("Cannot retrieve disk temperature.")
+            return_code = 30
+            return return_code
+
+    disk_temperature = int(temperature_match.group(1))
+    print("Disk current temperature: %d degrees centigrade"
+          %disk_temperature)
+    if disk_temperature > 60:
+        return_code = 40
+
+    # Verify reallocated sectors match the criteria or not.
+    reallocated_sector_match = re.search(r'Reallocated_Sector_Ct.*\s(\d+)\n',
+                                         smartctl_info)
+    if reallocated_sector_match:
+        reallocated_sector = int(reallocated_sector_match.group(1))
+        print("Reallocated_Sector_Ct: %d" %reallocated_sector)
+        if disk_capacity == 2 and reallocated_sector > 50:
+            return_code = 50
+        if disk_capacity == 4 and reallocated_sector > 100:
+            return_code = 60
+
+    # Verify grown defect list match the criteria or not.
+    grown_defect_match = re.search(r'Elements in grown defect list\:\s(\d+)\n',
+                                   smartctl_info)
+    if grown_defect_match:
+        grown_defect_list = int(grown_defect_match.group(1))
+        print("Elements in grown defect list: %d" %grown_defect_list)
+        if disk_capacity == 2 and grown_defect_list > 50:
+            return_code = 70
+        if disk_capacity == 4 and grown_defect_list > 100:
+            return_code = 80
+
+    # Check current pending sectort.
+    current_pending_match = re.search(r'Current_Pending_Sector.*\s(\d+)\n',
+                                      smartctl_info)
+    if current_pending_match:
+        current_pending_sector = int(current_pending_match.group(1))
+        print("Current_Pending_Sector: %d" %current_pending_sector)
+        if current_pending_sector != 0:
+            return_code = 90
+
+    # Check error counter log.
+    total_uncorrected_errors = re.search(
+        r'\nread.*\s(\d+)\nwrite.*\s(\d+)\nverify.*\s(\d+)', smartctl_info)
+    if total_uncorrected_errors:
+        read = int(total_uncorrected_errors.group(1))
+        write = int(total_uncorrected_errors.group(2))
+        verify = int(total_uncorrected_errors.group(3))
+        print("Total uncorrected errors: read=%d write=%d verify=%d"
+              %(read, write, verify))
+        if read != 0 or write != 0 or verify != 0:
+            return_code = 100
+    return return_code
+
+def main():
+    parser = ArgumentParser(formatter_class=RawTextHelpFormatter)
+    parser.add_argument('-d', '--device', type=str, required=True,
+                        help=("The device that wants to monitor health."))
+    args = parser.parse_args()
+    
+    device = args.device
+    if not device.startswith('/dev/'):
+        device = '/dev/' + device
+
+    return run(device)
+
+if __name__ == '__main__':
+    sys.exit(main())

=== modified file 'bin/disk_info'
--- bin/disk_info	2015-03-03 15:59:42 +0000
+++ bin/disk_info	2015-08-14 22:03:31 +0000
@@ -3,6 +3,8 @@
 Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
 Industrial Technology Research Institute
 
+It is NOT YET officially approved by OCP.
+
 disk_info
   1. Use lshw command to gather disk information.
   2. The program will output disk type, vendor, product, capacity.

=== added file 'bin/disk_info_leopard'
--- bin/disk_info_leopard	1970-01-01 00:00:00 +0000
+++ bin/disk_info_leopard	2015-08-14 22:03:31 +0000
@@ -0,0 +1,67 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+It is NOT YET officially approved by OCP.
+
+disk_info
+  1. Use lshw command to gather disk information.
+  2. The program will output disk type, vendor, product, capacity.
+  3. Criteria: must be able to retrieve disk information.
+
+Authors
+  Nelson Chu <Nelson.Chu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+import sys
+import xml.etree.ElementTree as ET
+from subprocess import Popen, PIPE
+
+def main():
+    attribute = ['description', 'product', 'size']
+    command = 'lshw -xml'
+    hwinfo_xml = Popen(command, stdout=PIPE, stderr=PIPE,
+                       shell=True).communicate()[0]
+    root = ET.fromstring(hwinfo_xml)
+
+    # Parse lshw XML for gathering disk information.
+    disk_list = root.findall(".//node[@class='disk']")
+
+    if not disk_list:
+        print("Cannot parse any disk information.", file=sys.stderr)
+        return 10
+
+    for disk in disk_list:
+        for attr in attribute:
+            if disk.find(attr) is None:
+                print(("Cannot found disk %s") %attr, file=sys.stderr)
+                return 20
+
+        disk_size = int(disk.find('size').text) / (1000**3)
+        for attr in attribute:
+            if attr == 'description':
+                print(("Type=\"%s\"") %disk.find(attr).text)
+                continue
+            elif attr == 'size':
+                print(("%s=\"%dGB\"") %(attr.capitalize(), disk_size))
+                continue
+            else:
+                print(("%s=\"%s\"") %(attr.capitalize(), disk.find(attr).text))
+    return 0
+
+if __name__ == '__main__':
+    sys.exit(main())

=== added file 'bin/ipmi_fru'
--- bin/ipmi_fru	1970-01-01 00:00:00 +0000
+++ bin/ipmi_fru	2015-08-14 22:03:31 +0000
@@ -0,0 +1,163 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  ipmi_fru
+
+Description
+  1. Use ipmitool to retrieve FRU data.
+  2. The data contains product manufacture, product part number, product serial number, motherboard serial number.
+  3. Criteria: Above All data mentioned above must notshould not be null
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+
+import sys
+import shlex
+import time
+import subprocess
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+import re
+import configparser
+
+def get_system_manufacturer(output):
+    system_manufacture = re.search(r'Product Manufacturer\s*:\s*([a-zA-Z0-9-._ ]+\n)', output)
+    if system_manufacture  == None:
+        return 'Error'
+    else:
+        return system_manufacture.group(1).strip()
+
+def get_system_part_number(output):
+    system_part_number = re.search(r'Product Part Number\s*:\s*([a-zA-Z0-9-._ ]+\n)', output)
+    if system_part_number == None:
+        return 'Error'
+    else:
+        return system_part_number.group(1).strip()
+    
+def get_system_serial_number(output):
+    system_serial_number = re.search(r'Product Serial\s*:\s*([a-zA-Z0-9-._ ]+\n)', output)
+    if system_serial_number == None:
+        return 'Error'
+    else:
+        return system_serial_number.group(1).strip()
+
+def get_board_serial_number(output):
+    board_serial_number = re.search(r'Board Serial\s*:\s*([a-zA-Z0-9-._ ]+\n)', output)
+    if board_serial_number == None:
+        return 'Error'
+    else:
+        return board_serial_number.group(1).strip()
+
+def get_fru_info(host_ip, user, password):
+    fru_cmd = 'ipmitool -H {} -U {} -P {} fru'.format(host_ip, user, password)
+    fru_return = check_output(shlex.split(fru_cmd), universal_newlines=True)
+    return fru_return
+
+def ipmi_fru(args):
+    #IPMI config file
+    DEFAULT_CFG = "/etc/checkbox.d/bmc.cfg"
+
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+
+    config = configparser.RawConfigParser()
+
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 20
+
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 30
+
+    try:
+        user_value = config.get('Account', 'USER')
+        passwd_value = config.get('Account', 'PASSWORD')
+        if not user_value or not passwd_value:
+            print("Invalid or Empty credential info")
+            return 40
+
+    except configparser.Error:
+        print("Invalid or Empty credential info")
+        return 50
+
+    inevntory_fru = {}
+    flag = 0
+    for tg in targets_list:
+            
+        if not tg or not user_value or not passwd_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for IPMI out-of-band access")
+            return 60
+        else:
+            print("SUT =", tg)
+            try:
+                fru_data = get_fru_info(tg, user_value, passwd_value)
+                time.sleep(5)
+            except CalledProcessError as ipmi_exception:
+                print("Failed executing ipmi, Reason: %s" % ipmi_exception)
+                return 70
+
+            inevntory_fru.update({'Product Manufacturer':get_system_manufacturer(fru_data)})
+            inevntory_fru.update({'Product Part Number':get_system_part_number(fru_data)})
+            inevntory_fru.update({'Product Serial':get_system_serial_number(fru_data)})
+            inevntory_fru.update({'Board Serial':get_board_serial_number(fru_data)})
+    
+            inevntory_fru_list = ['Product Manufacturer', 'Product Part Number', 'Product Serial', 'Board Serial']
+            for item in inevntory_fru_list:
+                print("{}: {}".format(item, inevntory_fru.get(item)))
+                if inevntory_fru.get(item) == 'Error' or inevntory_fru.get(item) == '':
+                    flag = 1
+    if flag == 1:
+        return 100
+    return 0
+
+def main():
+    intro_message = "Default config location is /etc/checkbox.d/bmc.cfg"
+    parser = ArgumentParser(description=intro_message,
+                            formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', type=str,
+                        default="/etc/checkbox.d/bmc.cfg",
+                        help="Supply config file for getting authentication info")
+    args = parser.parse_args()
+    return ipmi_fru(args)
+
+if __name__ == '__main__':
+    sys.exit(main())

=== added file 'bin/ipmi_inventory'
--- bin/ipmi_inventory	1970-01-01 00:00:00 +0000
+++ bin/ipmi_inventory	2015-08-14 22:03:31 +0000
@@ -0,0 +1,214 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  ipmi_inventory
+  1. Use ipmitool to collect inventory information including Asset Tag, Device ID, System GUID, Firmware Revision, IPMI Version, Management Controller ID.
+  2. Criteria: All information mentioned above must not should not be null.
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+
+import sys
+import shlex
+import time
+import subprocess
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+import re
+import configparser
+
+
+def get_mcinfo(host_ip, user, password):
+
+    try:
+        cmd = 'ipmitool -H {} -U {} -P {} mc info'.format(host_ip, user, password)
+        mcinfo_return = check_output(shlex.split(cmd), universal_newlines=True)
+        time.sleep(5)
+    except CalledProcessError as command_exception:
+        print("Failed executing ipmi command for getting mc info. Reason:%s" % command_exception)
+
+    try:
+
+        deviceid = re.search(r'Device ID\s*:\s*([a-zA-Z0-9-._ ]+)', mcinfo_return)
+        if deviceid == None:
+            deviceid = 'Error'
+        else:
+            deviceid = deviceid.group(1).strip()
+
+        Firm = re.search(r'Firmware Revision\s+\s*:\s*([a-zA-Z0-9-._ ]+)', mcinfo_return)
+        if Firm == None:
+            Firm = 'Error'
+        else:
+            Firm = Firm.group(1).strip()
+
+        IPMI_Ver = re.search(r'IPMI Version\s+\s*:\s*([a-zA-Z0-9-._ ]+)', mcinfo_return)
+        if IPMI_Ver == None:
+            IPMI_Ver = 'Error'
+        else:
+            IPMI_Ver = IPMI_Ver.group(1).strip()
+
+        return deviceid, Firm, IPMI_Ver    
+
+    except:
+
+        return 'Error', 'Error', 'Error'
+
+def get_asset_tag(host_ip, user, password):
+
+    try:
+        cmd = 'ipmitool -H {} -U {} -P {} fru'.format(host_ip, user, password)
+        asset_tag_return = check_output(shlex.split(cmd), universal_newlines=True)
+        time.sleep(5)
+    except CalledProcessError as command_exception:
+        print("Failed executing ipmi command for getting asset tag. Reason:%s" % command_exception)
+
+    try:
+        asset_tag = re.search(r'Product Asset Tag\s*:\s*([a-zA-Z0-9-._ ]+)', asset_tag_return)
+        if asset_tag == None:
+            return 'Error'
+        return asset_tag.group(1).strip()
+    except:
+        return 'Error'
+
+def get_guid(host_ip, user, password):
+
+    try:
+        cmd = 'ipmitool -H {} -U {} -P {} mc guid'.format(host_ip, user, password)
+        guid_return = check_output(shlex.split(cmd), universal_newlines=True)
+        time.sleep(5)
+    except CalledProcessError as command_exception:
+        print("Failed executing ipmi command for getting guid. Reason:%s" % command_exception)
+
+    try:
+        mcguid = re.search(r'System GUID\s*:\s*([a-zA-Z0-9-._ ]+)', guid_return)
+        if mcguid == None:
+            return 'Error'
+        return mcguid.group(1).strip()
+    except:
+        return 'Error'
+
+def get_mcid(host_ip, user, password):
+
+    try:
+        cmd = 'ipmitool -H {} -U {} -P {} dcmi get_mc_id_string'.format(host_ip, user, password)
+        mcid_return = check_output(shlex.split(cmd), universal_newlines=True)
+        time.sleep(5)
+    except CalledProcessError as command_exception:
+        print("Failed executing ipmi command for getting mc id. Reason:%s" % command_exception)
+
+    try:
+        mcid =  re.search(r'Get Management Controller Identifier String\s*:\s*([a-zA-Z0-9-._ ]+)', mcid_return)
+        if mcid == None:
+            return 'Error'
+        return mcid.group(1).strip()
+    except:
+        return 'Error'
+
+def inventory(args):
+
+    #IPMI config file
+    DEFAULT_CFG = "/etc/checkbox.d/bmc.cfg"
+
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+
+    config = configparser.RawConfigParser()
+
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 20
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 30
+
+    try:
+        user_value = config.get('Account', 'USER')
+        passwd_value = config.get('Account', 'PASSWORD')
+        if not user_value or not passwd_value:
+            print("Invalid or Empty credential info")
+            return 40
+
+    except configparser.Error:
+        print("Invalid or Empty credential info")
+        return 50
+
+
+    flag = 0
+    for tg in targets_list:
+        
+        if not tg or not user_value or not passwd_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for IPMI out-of-band access")
+            return 60
+        else:
+            print("SUT =", tg)
+            inventory_dict = {}
+            inventory_list = ['Asset Tag', 'System GUID', 'Get Management Controller Identifier String', 'Device ID', 'Firmware Revision', 'IPMI Version']
+            Device_ID, Firmware, IPMI_version = get_mcinfo(tg, user_value, passwd_value)
+            inventory_dict.update({'Asset Tag':get_asset_tag(tg, user_value, passwd_value)})
+            inventory_dict.update({'System GUID':get_guid(tg, user_value, passwd_value)})
+            inventory_dict.update({'Get Management Controller Identifier String':get_mcid(tg, user_value, passwd_value)})
+            inventory_dict.update({'Device ID':Device_ID})
+            #inventory_dict.update({'Manufacturer Name':Manufacturer})
+            inventory_dict.update({'Firmware Revision':Firmware})
+            inventory_dict.update({'IPMI Version':IPMI_version})
+
+            for item in inventory_list:
+                if inventory_dict.get(item) == 'Error' or inventory_dict.get(item) == None:
+                    flag = 1
+                
+                print("{}: {}".format(item, inventory_dict.get(item)))
+
+    if flag == 1:
+        return 1
+    return 0
+
+def main():
+    intro_message = "Default config location is /etc/checkbox.d/bmc.cfg"
+    parser = ArgumentParser(description=intro_message,
+                            formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', type=str,
+                        default="/etc/checkbox.d/bmc.cfg",
+                        help="Supply config file for getting authentication info")
+    args = parser.parse_args()
+
+    return inventory(args)
+
+if __name__ == '__main__':
+    sys.exit(main())

=== added file 'bin/ipmi_power_draw'
--- bin/ipmi_power_draw	1970-01-01 00:00:00 +0000
+++ bin/ipmi_power_draw	2015-08-14 22:03:31 +0000
@@ -0,0 +1,126 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  ipmi_power_draw  
+  1. GatherRetrieving power draw datainfo via ipmitool
+  2. The datainfo contains "Minimum during sampling period", "Maximum during sampling period", "Average power reading over sample period", "IPMI timestamp", "Sampling period", "Power reading state".
+  3. Criteria: The return value of each item cannot be null
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+import sys
+import shlex
+import re
+import time
+import configparser
+import subprocess
+from subprocess import (
+    CalledProcessError,
+    check_call,
+    check_output
+)
+
+def get_power_draw(host_ip, user, password):
+    cmd = 'ipmitool -H {} -U {} -P {} dcmi power reading'.format(host_ip, user, password)
+    output = check_output(shlex.split(cmd), universal_newlines=True)    
+    return output
+
+def power_draw_test(args):
+
+    #Default config file to config requirement info for DCMI in-band/out-of-band access
+    DEFAULT_CFG = "/etc/checkbox.d/me.cfg"
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+
+    config = configparser.RawConfigParser()
+
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    # Acquire ME IP/Credential parameters from config file
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 20
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 30
+
+    try:
+        user_value = config.get('Account', 'USER')
+        passwd_value = config.get('Account', 'PASSWORD')
+    except configparser.Error:
+        print("Invalid or Empty credential info")
+        return 40
+
+    flag = 0
+    for target in targets_list:
+
+        if not target or not user_value or not passwd_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for DCMI out-of-band access")
+            return 50
+        else:
+            print("SUT =", target)
+
+            try:
+                power_draw_return = get_power_draw(target, user_value, passwd_value)
+                time.sleep(5)
+            except CalledProcessError as command_exception:
+                print("Failed executing dcmi command", command_exception)
+                return 60
+
+            power_list = ['Minimum during sampling period', 'Maximum during sampling period',\
+                      'Average power reading over sample period',\
+                      'IPMI timestamp', 'Sampling period', 'Power reading state is']
+            for i in power_list:
+                value = re.search(i+':\s*([a-zA-Z0-9-: ]+)', power_draw_return)
+                if value == None:
+                    print("{}: Error".format(i))
+                    flag = 1
+                else:
+                    print("{}: {}".format(i, value.group(1)))
+    if flag == 1:
+        return 1
+    return 0
+
+def main():
+    intro_message = "Default config location is /etc/checkbox.d/me.cfg"
+    parser = ArgumentParser(description=intro_message,
+                            formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', default="/etc/checkbox.d/me.cfg",
+                        help="Supply config file for getting authentication info")
+    args = parser.parse_args()
+    return power_draw_test(args)
+
+if __name__ == '__main__':
+    sys.exit(main())

=== added file 'bin/ipmi_power_off_on'
--- bin/ipmi_power_off_on	1970-01-01 00:00:00 +0000
+++ bin/ipmi_power_off_on	2015-08-14 22:03:31 +0000
@@ -0,0 +1,193 @@
+#! /usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  ipmi_power_off_on
+
+Description
+  1. Use ipmitool out-of-band access to turn on/off the SUT.
+  2. Criteria: the SUT can be powered on/off by ipmitool out-of-band access.
+ 
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+
+import sys
+import configparser
+import shlex
+import subprocess
+import ast
+import time
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+
+def check_power_status(host_ip, user, password):
+
+    cmd_status_on = 'ipmitool -H {} -U {} -P {} power status| grep -q "on"'\
+			.format(host_ip, user, password)
+    check_on_value = subprocess.call(cmd_status_on, shell=True)
+    time.sleep(5)
+
+    cmd_status_off = 'ipmitool -H {} -U {} -P {} power status| grep -q "off"'\
+			.format(host_ip, user, password)
+    check_off_value = subprocess.call(cmd_status_off, shell=True)
+    time.sleep(5)
+
+    if check_on_value == 0 and check_off_value == 1:
+        check_status = 'on'
+    
+    elif check_on_value == 1 and check_off_value == 0:
+        check_status = 'off'
+
+    else:
+        check_status = 'error'
+
+    return check_status
+
+def run_power_off(host_ip, user, password):
+    cmd_power_off = 'ipmitool -H {} -U {} -P {} power off'\
+        .format(host_ip, user, password)
+    power_off_return_code = subprocess.call(cmd_power_off, shell=True)
+    return power_off_return_code
+
+def run_power_on(host_ip, user, password):
+    cmd_power_on = 'ipmitool -H {} -U {} -P {} power on'\
+        .format(host_ip, user, password)
+    power_on_return_code = subprocess.call(cmd_power_on, shell=True)
+    return power_on_return_code
+
+def ipmi_reset_oob(args):
+
+    #IPMI config file
+    DEFAULT_CFG = "/etc/checkbox.d/bmc.cfg"
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+
+    config = configparser.RawConfigParser()
+
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 20
+
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 30
+
+    try:
+        user_value = config.get('Account', 'USER')
+        passwd_value = config.get('Account', 'PASSWORD')
+        if not user_value or not passwd_value:
+            print("Invalid or Empty credential info")
+            return 40
+
+    except configparser.Error:
+        print("Invalid or Empty credential info")
+        return 50
+
+    ping_flag = 0
+    for tg in targets_list:
+    
+        if not tg or not user_value or not passwd_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for IPMI out-of-band access")
+            return 21
+        else:
+
+            print("SUT =", tg)
+            print("USER =", user_value)
+            print("PASSWORD =", passwd_value)
+
+            for n in range(2):
+
+                count = 0
+                while count < 10:
+                    ping_cmd = 'ping -c 1 {}>/dev/null 2>/dev/null'.format(tg)
+                    ping_rtn = subprocess.call(ping_cmd, shell=True)
+                    if ping_rtn == 0:
+                        print("Destination Host Reachable")
+                        
+                        #run test
+                        status = check_power_status(tg, user_value, passwd_value)
+
+                        if status == 'on':
+                            #run power off
+                            power_off_result = run_power_off(tg, user_value, passwd_value)
+                            print(" ")
+                            if power_off_result == 1:
+                                print("Failed to power off SUT.")
+                                return 88
+                        elif status == 'off':
+                            #run power on
+                            power_on_result = run_power_on(tg, user_value, passwd_value)
+                            print(" ")
+                            if power_on_result == 1:
+                                print("Failed to power on SUT.")
+                                return 99
+                        else:
+                            #do nothing
+                            print("Failed to check power status")
+                            return 77
+                        
+                        time.sleep(180)
+                        break
+
+                    else:
+                        time.sleep(10)
+                        count = count+1
+                        print("Destination Host Unreachable")
+
+                if count == 10:         
+                    print("Host Has No Response, End of Test")
+                    ping_flag = 100
+
+    if ping_flag == 100:
+        return 100
+    return 0
+
+def main():
+
+    intro_message = "Default config location is /etc/checkbox.d/bmc.cfg"
+    parser = ArgumentParser(description=intro_message,
+		 formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', type=str,
+		 default="/etc/checkbox.d/bmc.cfg",
+		 help="Supply config file for getting authentication info")
+    args = parser.parse_args()
+    return ipmi_reset_oob(args)
+
+if __name__ == "__main__":
+    sys.exit(main())

=== added file 'bin/ipmi_power_policy'
--- bin/ipmi_power_policy	1970-01-01 00:00:00 +0000
+++ bin/ipmi_power_policy	2015-08-14 22:03:31 +0000
@@ -0,0 +1,165 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  ipmi_power_policy
+
+Description
+ 1. Use ipmitool to set power on policy through OOB.
+ 2. Criteria: the change of power policy should take effect without BMC firmware cold reset or system reboot.
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+
+import sys
+import shlex
+import time
+import subprocess
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+import re
+import configparser
+import os
+
+def set_power_policy(host_ip, user, password, rule):
+    os.system('ipmitool -H {} -U {} -P {} chassis policy {}'.format(host_ip, user, password, rule))
+
+def get_chassis_status(host_ip, user, password):
+    cmd = 'ipmitool -H {} -U {} -P {} chassis status'.format(host_ip, user, password)
+    output = check_output(shlex.split(cmd), universal_newlines=True)
+    return output
+
+def get_power_policy(host_ip, user, password):
+    result = get_chassis_status(host_ip, user, password)
+    policy = re.search(r'Power Restore Policy\s*:\s*([a-zA-Z0-9-._ ]+\n)', result)
+    if policy  == None:
+        return 'Error'
+    else:
+        return policy.group(1).strip()
+
+def check_policy(host_ip, user, password, rule):
+    current_policy = get_power_policy(host_ip, user, password)
+    if current_policy == rule:
+        print("Successfully setting power policy")
+        return 0
+    else:
+        return 1
+
+def power_policy_test(args):
+
+    #IPMI config file
+    policy_rule = args.rule
+    if not policy_rule:
+        print("No specified policy to set")
+        return 88
+
+    DEFAULT_CFG = "/etc/checkbox.d/bmc.cfg"
+
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+
+    config = configparser.RawConfigParser()
+
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 20
+
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 30
+
+    try:
+        user_value = config.get('Account', 'USER')
+        passwd_value = config.get('Account', 'PASSWORD')
+        if not user_value or not passwd_value:
+            print("Invalid or Empty credential info")
+            return 40
+
+    except configparser.Error:
+        print("Invalid or Empty credential info")
+        return 50
+
+    flag = 0
+    for tg in targets_list:
+            
+        if not tg or not user_value or not passwd_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for IPMI out-of-band access")
+            return 60
+        else:
+            print("SUT =", tg)
+
+            try:
+                set_power_policy(tg, user_value, passwd_value, policy_rule)
+            except:
+                print("Fail to set power policy")
+                return 70
+
+            time.sleep(5)          
+
+            try:
+                chassis_status = get_chassis_status(tg, user_value, passwd_value)
+            except:
+                print("Fail to get chassis status")
+                return 80
+
+            current_policy = get_power_policy(tg, user_value, passwd_value)
+
+            value = check_policy(tg, user_value, passwd_value, policy_rule)
+
+            if value == 1:
+                flag = 1
+
+    if flag == 1:
+        return 1
+    return 0
+
+def main():
+    intro_message = "Default config location is /etc/checkbox.d/bmc.cfg"
+    parser = ArgumentParser(description=intro_message,
+                            formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', type=str,
+                        default="/etc/checkbox.d/bmc.cfg",
+                        help="Supply config file for getting authentication info")
+    parser.add_argument('--rule', help="always-on, always-off or previous")
+    args = parser.parse_args()
+    return power_policy_test(args)
+
+if __name__ == '__main__':
+    sys.exit(main())

=== added file 'bin/ipmi_power_reset'
--- bin/ipmi_power_reset	1970-01-01 00:00:00 +0000
+++ bin/ipmi_power_reset	2015-08-14 22:03:31 +0000
@@ -0,0 +1,142 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  ipmi_power_reset
+
+Description
+  1. Use ipmitool out-of-band access to power hard reset the SUT 20 times.
+  2. Criteria: complete 20 power hard reset on SUT successfully using ipmitool out-of-band access.
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+
+import sys
+import configparser
+import shlex
+import subprocess
+import ast
+import time
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+
+def run(host_ip, user, password):
+    cmd = 'ipmitool -H {} -U {} -P {} power reset'.format(host_ip, user, password)
+    power_reset_return = check_output(shlex.split(cmd), universal_newlines=True)
+    return power_reset_return
+        
+def ipmi_reset_oob(args):
+
+    #IPMI config file
+    DEFAULT_CFG = "/etc/checkbox.d/bmc.cfg"
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+
+    config = configparser.RawConfigParser()
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 1
+
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 2
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 2
+
+    try:
+        user_value = config.get("Account", "USER")
+        password_value = config.get("Account", "PASSWORD")
+    except configparser.NoOptionError:
+        print("Invalid or Empty credential info")
+        return 3
+
+    ping_flag = 0
+    for tg in targets_list:    
+
+        if not tg or not user_value or not password_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for IPMI out-of-band access")
+            return 4
+        else:
+            print("SUT =", tg)
+            print("USER =", user_value)
+            print("PASSWORD =", password_value)
+
+            for n in range(20):
+                print("---------------- %s ----------------" % n)
+                count = 0
+                while count < 10:
+                    print("+++++++++++ %s ++++++++++++" % count)
+                    ping_cmd = 'ping -c 1 {}>/dev/null 2>/dev/null'.format(tg)
+                    ping_rtn = subprocess.call(ping_cmd, shell=True)
+
+                    if ping_rtn == 0:
+                        print("Destination Host Reachable")
+
+                        try:
+                            power_control = run(tg, user_value, password_value)
+                            print(power_control)
+                        except CalledProcessError as ipmi_exception:
+                            print("Failed executing ipmi, Reason: %s" % ipmi_exception)
+                            return 6
+
+                        time.sleep(180)
+                        break
+                    else:
+                        time.sleep(10)
+                        count = count+1
+                        print("Destination Host Unreachable")
+                
+                if count == 10:
+                    print("Host Has No Response, End of Test")
+                    ping_flag = 100
+
+    if ping_flag == 100:
+        return 100
+    return 0
+
+def main():
+
+    intro_message = "Default config location is /etc/checkbox.d/bmc.cfg"
+    parser = ArgumentParser(description=intro_message,
+                            formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config',
+                        default="/etc/checkbox.d/bmc.cfg",
+                        help="Supply config file for getting authentication info")
+    args = parser.parse_args()
+    return ipmi_reset_oob(args)
+
+if __name__ == "__main__":
+    sys.exit(main())

=== added file 'bin/ipmi_priv_admin'
--- bin/ipmi_priv_admin	1970-01-01 00:00:00 +0000
+++ bin/ipmi_priv_admin	2015-08-14 22:03:31 +0000
@@ -0,0 +1,176 @@
+#! /usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  ipmi_priv_admin  
+
+Description
+  1. Use ipmitool out-of-band to read power status, to perform power reset and add a new user account.
+  2. Criteria: reading power status, performing power reset and adding a user account must all be successful.
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+
+import sys
+import configparser
+import shlex
+import subprocess
+import ast
+import time
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+
+def get_power_status(host_ip, user, password):
+    cmd_status = 'ipmitool -H {} -U {} -P {} power status 1>/dev/null 2>/dev/null'\
+        .format(host_ip, user, password)
+    status_code = subprocess.call(cmd_status, shell=True)
+    return status_code
+    
+def power_reset(host_ip, user, password):
+    cmd_reset = 'ipmitool -H {} -U {} -P {} power reset 1>/dev/null 2>/dev/null'\
+        .format(host_ip, user, password)
+    reset_code = subprocess.call(cmd_reset, shell=True)
+    return reset_code
+
+def add_user(host_ip, user, password, new_id, new_user):
+    cmd_add_user = 'ipmitool -H {} -U {} -P {} user set name {} {} 1>/dev/null 2>/dev/null'\
+        .format(host_ip, user, password, new_id, new_user)
+    add_user_code = subprocess.call(cmd_add_user, shell=True)
+    return add_user_code
+
+def ipmi_user_level_test(args):
+
+    #IPMI config file
+    DEFAULT_CFG = "/etc/checkbox.d/bmc.cfg"
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+    config = configparser.RawConfigParser()
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 20
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 20
+
+    try:
+        user_value = config.get("Admin Level", "ADMIN_NAME")
+        password_value = config.get("Admin Level", "ADMIN_PASSWD")
+    except configparser.NoOptionError:
+        print("Invalid or Empty credential info")
+        print("Require Operator Level info pre-configured in /etc/checkbox.d/bmc.cfg")
+        return 30
+
+    try:
+        new_user_value = config.get("Add User Test", "NEW_USER_NAME")
+        new_user_id_value = config.get("Add User Test", "NEW_USER_ID")
+    except configparser.NoOptionError:
+        print("Invalid or Empty new user info")
+        print("Require new User info pre-configured in /etc/checkbox.d/bmc.cfg")
+        return 40
+
+    flag = 0
+    for tg in targets_list:
+
+        if not tg or not user_value or not password_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for IPMI out-of-band access")
+            return 50
+        else:
+            print("SUT", tg)
+
+            ping_result = ping_test(tg)
+            if ping_result != 0:
+                return 88
+
+            status_result = get_power_status(tg, user_value, password_value)
+            time.sleep(5)
+
+            reset_result = power_reset(tg, user_value, password_value)
+            time.sleep(180)
+            if not new_user_value or not new_user_id_value:
+                print("Require new user info pre-configured in /etc/checkbox.d/bmc.cfg")
+                return 60
+            else:
+
+                ping_result = ping_test(tg)
+                if ping_result != 0:
+                    return 88
+
+                add_user_result = add_user(tg, user_value, password_value, new_user_id_value, new_user_value)
+                time.sleep(5)
+
+            if status_result == 0 and reset_result == 0 and add_user_result == 0:
+                print("User can read power status.")
+                print("User can reset power.")
+                print("User can add a new user.")
+            else:
+                print("Authentication: Not Administrator Level")
+                flag = 1
+
+    if flag == 1:
+        return 100
+    return 0
+
+def ping_test(host_ip):
+    count = 0
+    while count < 10:
+        ping_cmd = 'ping -c 1 {}>/dev/null 2>/dev/null'.format(host_ip)
+        ping_rtn = subprocess.call(ping_cmd, shell=True)
+        if ping_rtn == 0:
+            return 0
+        else:
+            print("Destination Host Unreachable")
+            time.sleep(10)
+            count = count+1
+
+    if count == 10:
+        print("Host Has No Response, End of Test")
+        return 1
+
+
+def main():
+
+    intro_message = "Default config location is /etc/checkbox.d/bmc.cfg"
+    parser = ArgumentParser(description=intro_message, formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', type=str,
+		 default="/etc/checkbox.d/bmc.cfg",
+		 help="Supply config file for getting authentication info")
+    args = parser.parse_args()
+    return ipmi_user_level_test(args)
+
+if __name__ == "__main__":
+    sys.exit(main())

=== added file 'bin/ipmi_priv_oper'
--- bin/ipmi_priv_oper	1970-01-01 00:00:00 +0000
+++ bin/ipmi_priv_oper	2015-08-14 22:03:31 +0000
@@ -0,0 +1,174 @@
+#! /usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  ipmi_priv_oper
+  1. Use ipmitool out-of-band to read power status, to perform power reset and add a new user account.
+  2. Criteria: power status reading and power reset must be successful and must fail at adding a new user account.
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+
+import sys
+import configparser
+import shlex
+import subprocess
+import ast
+import time
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+
+def get_power_status(host_ip, user, password):
+    cmd_status = 'ipmitool -H {} -U {} -P {} power status -L operator 1>/dev/null 2>/dev/null'\
+        .format(host_ip, user, password)
+    status_code = subprocess.call(cmd_status, shell=True)
+    return status_code
+    
+def power_reset(host_ip, user, password):
+    cmd_reset = 'ipmitool -H {} -U {} -P {} power reset -L operator 1>/dev/null 2>/dev/null'\
+        .format(host_ip, user, password)
+    reset_code = subprocess.call(cmd_reset, shell=True)
+    return reset_code
+
+def add_user(host_ip, user, password, new_id, new_user):
+    cmd_add_user = 'ipmitool -H {} -U {} -P {} user set name {} {} -L operator 1>/dev/null 2>/dev/null'\
+        .format(host_ip, user, password, new_id, new_user)
+    add_user_code = subprocess.call(cmd_add_user, shell=True)
+    return add_user_code
+
+def ipmi_user_level_test(args):
+
+    #IPMI config file
+    DEFAULT_CFG = "/etc/checkbox.d/bmc.cfg"
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+    config = configparser.RawConfigParser()
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 20
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 20
+
+    try:
+        user_value = config.get("Operator Level", "OPER_NAME")
+        password_value = config.get("Operator Level", "OPER_PASSWD")
+    except configparser.NoOptionError:
+        print("Invalid or Empty credential info")
+        print("Require Operator Level info pre-configured in /etc/checkbox.d/bmc.cfg")
+        return 30
+
+    try:
+        new_user_value = config.get("Add User Test", "NEW_USER_NAME")
+        new_user_id_value = config.get("Add User Test", "NEW_USER_ID")
+    except configparser.NoOptionError:
+        print("Invalid or Empty new user info")
+        print("Require new User info pre-configured in /etc/checkbox.d/bmc.cfg")
+        return 40
+
+    flag = 0
+    for tg in targets_list:
+
+        if not tg or not user_value or not password_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for IPMI out-of-band access")
+            return 50
+        else:
+            print("SUT", tg)
+
+            ping_result = ping_test(tg)
+            if ping_result != 0:
+                return 88
+
+            status_result = get_power_status(tg, user_value, password_value)
+            time.sleep(5)
+
+            reset_result = power_reset(tg, user_value, password_value)
+            time.sleep(180)
+            if not new_user_value or not new_user_id_value:
+                print("Require new user info pre-configured in /etc/checkbox.d/bmc.cfg")
+                return 60
+            else:
+
+                ping_result = ping_test(tg)
+                if ping_result != 0:
+                    return 88
+
+                add_user_result = add_user(tg, user_value, password_value, new_user_id_value, new_user_value)
+                time.sleep(5)
+
+            if status_result == 0 and reset_result == 0 and add_user_result == 1:
+                print("User can read power status.")
+                print("User can reset power.")
+                print("User can't add a new user.")
+            else:
+                print("Authentication: Not Operator Level")
+                flag = 1
+
+    if flag == 1:
+        return 100
+    return 0
+
+def ping_test(host_ip):
+    count = 0
+    while count < 10:
+        ping_cmd = 'ping -c 1 {}>/dev/null 2>/dev/null'.format(host_ip)
+        ping_rtn = subprocess.call(ping_cmd, shell=True)
+        if ping_rtn == 0:
+            return 0
+        else:
+            print("Destination Host Unreachable")
+            time.sleep(10)
+            count = count+1
+
+    if count == 10:
+        print("Host Has No Response, End of Test")
+        return 1
+
+
+def main():
+
+    intro_message = "Default config location is /etc/checkbox.d/bmc.cfg"
+    parser = ArgumentParser(description=intro_message, formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', type=str,
+		 default="/etc/checkbox.d/bmc.cfg",
+		 help="Supply config file for getting authentication info")
+    args = parser.parse_args()
+    return ipmi_user_level_test(args)
+
+if __name__ == "__main__":
+    sys.exit(main())

=== added file 'bin/ipmi_priv_user'
--- bin/ipmi_priv_user	1970-01-01 00:00:00 +0000
+++ bin/ipmi_priv_user	2015-08-14 22:03:31 +0000
@@ -0,0 +1,176 @@
+#! /usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  ipmi_priv_uesr  
+
+Description
+  1. Use ipmitool out-of-band to read power status, to perform power reset and add a new user account.
+  2. Criteria: power status reading must be successful and must fail at power reset and adding a new user account.
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+
+import sys
+import configparser
+import shlex
+import subprocess
+import ast
+import time
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+
+def get_power_status(host_ip, user, password):
+    cmd_status = 'ipmitool -H {} -U {} -P {} power status -L user 1>/dev/null 2>/dev/null'\
+        .format(host_ip, user, password)
+    status_code = subprocess.call(cmd_status, shell=True)
+    return status_code
+    
+def power_reset(host_ip, user, password):
+    cmd_reset = 'ipmitool -H {} -U {} -P {} power reset -L user 1>/dev/null 2>/dev/null'\
+        .format(host_ip, user, password)
+    reset_code = subprocess.call(cmd_reset, shell=True)
+    return reset_code
+
+def add_user(host_ip, user, password, new_id, new_user):
+    cmd_add_user = 'ipmitool -H {} -U {} -P {} user set name {} {} -L user 1>/dev/null 2>/dev/null'\
+        .format(host_ip, user, password, new_id, new_user)
+    add_user_code = subprocess.call(cmd_add_user, shell=True)
+    return add_user_code
+
+def ipmi_user_level_test(args):
+
+    #IPMI config file
+    DEFAULT_CFG = "/etc/checkbox.d/bmc.cfg"
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+    config = configparser.RawConfigParser()
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 20
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 20
+
+    try:
+        user_value = config.get("User Level", "USER_NAME")
+        password_value = config.get("User Level", "USER_PASSWD")
+    except configparser.NoOptionError:
+        print("Invalid or Empty credential info")
+        print("Require User Level info pre-configured in /etc/checkbox.d/bmc.cfg")
+        return 30
+
+    try:
+        new_user_value = config.get("Add User Test", "NEW_USER_NAME")
+        new_user_id_value = config.get("Add User Test", "NEW_USER_ID")
+    except configparser.NoOptionError:
+        print("Invalid or Empty new user info")
+        print("Require new User info pre-configured in /etc/checkbox.d/bmc.cfg")
+        return 40
+
+    flag = 0
+    for tg in targets_list:
+
+        if not tg or not user_value or not password_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for IPMI out-of-band access")
+            return 50
+        else:
+            print("SUT", tg)
+
+            ping_result = ping_test(tg)
+            if ping_result != 0:
+                return 88
+
+            status_result = get_power_status(tg, user_value, password_value)
+            time.sleep(5)
+
+            reset_result = power_reset(tg, user_value, password_value)
+            time.sleep(180)
+            if not new_user_value or not new_user_id_value:
+                print("Require new user info pre-configured in /etc/checkbox.d/bmc.cfg")
+                return 60
+            else:
+
+                ping_result = ping_test(tg)
+                if ping_result != 0:
+                    return 88
+
+                add_user_result = add_user(tg, user_value, password_value, new_user_id_value, new_user_value)
+                time.sleep(5)
+
+            if status_result == 0 and reset_result == 1 and add_user_result == 1:
+                print("User can read power status.")
+                print("User can't reset power.")
+                print("User can't add a new user.")
+            else:
+                print("Authentication: Not User Level")
+                flag = 1
+
+    if flag == 1:
+        return 100
+    return 0
+
+def ping_test(host_ip):
+    count = 0
+    while count < 10:
+        ping_cmd = 'ping -c 1 {}>/dev/null 2>/dev/null'.format(host_ip)
+        ping_rtn = subprocess.call(ping_cmd, shell=True)
+        if ping_rtn == 0:
+            return 0
+        else:
+            print("Destination Host Unreachable")
+            time.sleep(10)
+            count = count+1
+
+    if count == 10:
+        print("Host Has No Response, End of Test")
+        return 1
+
+
+def main():
+
+    intro_message = "Default config location is /etc/checkbox.d/bmc.cfg"
+    parser = ArgumentParser(description=intro_message, formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', type=str,
+		 default="/etc/checkbox.d/bmc.cfg",
+		 help="Supply config file for getting authentication info")
+    args = parser.parse_args()
+    return ipmi_user_level_test(args)
+
+if __name__ == "__main__":
+    sys.exit(main())

=== added file 'bin/ipmi_sampling'
--- bin/ipmi_sampling	1970-01-01 00:00:00 +0000
+++ bin/ipmi_sampling	2015-08-14 22:03:31 +0000
@@ -0,0 +1,273 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  ipmi_sampling
+
+Description
+  1. Retrieve CPU and intake temperature 30 times at 3 second intervals using ipmitool
+  2. If failed to retrieve temperature at any time within 30 times, the test is considered failed
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+import sys
+import time
+import re
+import configparser
+import shlex
+import subprocess
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+
+def get_sdr_remote(host_ip, user, password):
+    cmd = "ipmitool -H {} -U {} -P {} sdr".format(host_ip, user, password)
+    sdr_return = subprocess.check_output(shlex.split(cmd), stderr=subprocess.STDOUT,
+                                         universal_newlines=True)
+    return sdr_return
+
+def parse_sdr(output):
+    output = output.strip()
+    output_1Line = output.split("\n")
+    data = {}
+
+    for line in output_1Line:
+        sub_value = {}
+        string_list = line.split("|")
+        name = string_list[0].strip()
+        sensor_output = string_list[1].strip()
+        sub_value.update({'output':sensor_output})
+        status = string_list[2].strip()
+        sub_value.update({'status':status})
+        data.update({name:sub_value})
+    return data
+
+def calculate_CPU_temp(data_dict, CPU_Therm_Margin_id, CPU_Tjmax_id):
+    if data_dict.get(CPU_Therm_Margin_id) and data_dict.get(CPU_Tjmax_id):
+        if data_dict.get(CPU_Therm_Margin_id).get('status') == 'ok' and data_dict.get(CPU_Tjmax_id).get('status') == 'ok':
+            P_Therm_Margin_output = data_dict.get(CPU_Therm_Margin_id).get('output')
+            CPU_Tjmax_output = data_dict.get(CPU_Tjmax_id).get('output')
+            P_Therm_Margin = re.search(r'[0-9-]+', P_Therm_Margin_output).group(0)
+            CPU_Tjmax = re.search(r'[0-9-]+', CPU_Tjmax_output).group(0)
+            CPU_temp = int(P_Therm_Margin)+int(CPU_Tjmax)
+            return str(CPU_temp)+' degrees C'
+        else:
+            return 'Error'
+    else:
+        return 'None'
+        
+def ipmi_sdr(args):
+
+    cmd_flag = 0
+    #IPMI config file
+    DEFAULT_CFG = "/etc/checkbox.d/bmc.cfg"
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+
+    config = configparser.RawConfigParser()
+
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    try:
+        sensor_nick = config.options("SensorsForSampling")
+    except configparser.NoSectionError:
+        print("No Section: SensorsForSampling")
+        return 20
+
+    if sensor_nick:
+        sensor_list = []
+        for id in sensor_nick:
+            sensor_key = config.get("SensorsForSampling", id)
+            if sensor_key:
+                sensor_list.append(sensor_key)
+            else:
+                print("No Sensor ID specified in Config file")
+                return 30
+    else:
+        print("No key of Sensor ID specified in config file")
+        return 40
+
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 60
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 60
+
+    try:
+        user_value = config.get("Account", "USER")
+        password_value = config.get("Account", "PASSWORD")
+    except configparser.NoOptionError:
+        print("Invalid or Empty credential info")
+        return 70
+
+    for tg in targets_list:
+
+        if not tg or not user_value or not password_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for IPMI out-of-band access")
+            return 80
+        else:
+
+            c = 0
+            while c < 10:
+                ping_cmd = 'ping -c 1 {}>/dev/null 2>/dev/null'.format(tg)
+                ping_rtn = subprocess.call(ping_cmd, shell=True)
+                if ping_rtn == 0:
+                    print("Destination Host Reachable")
+                    break
+                else:
+                    time.sleep(10)
+                    c = c+1
+                    print("Destination Host Unreachable")
+
+            if c == 10:
+                print("Host Has No Response, End of Test")
+                return 99
+
+
+            sampling_data = []
+            times = 30
+            for n in range(times):
+
+                try:
+                    sensor_data = get_sdr_remote(tg, user_value, password_value)
+                    time.sleep(3)
+                except CalledProcessError as ipmi_exception:
+                    print("Failed executing ipmi, Reason: %s" % ipmi_exception)
+                    sensor_data = ''
+
+                sampling_data.append(sensor_data)
+            
+            count = 0
+            prs_flag = 0
+            dis_flag = 0
+            for output in sampling_data:
+                try:
+                    data = parse_sdr(output)
+                except:
+                    print("Parsing output of sdr table error")
+                    print("=======================================================")
+                    prs_flag = 1
+                    count = count+1
+                    continue
+
+                disable = 0
+                need_data = {}
+
+                for need_id in sensor_list:
+
+                    if data.get(need_id):
+                        need_value = data.get(need_id).get('output')
+                        need_data.update({need_id:need_value})
+                        if data.get(need_id).get('status') != 'ok':
+                            disable = 1
+                    else:
+
+                        try:
+                            CPUx_Temp = config.get("Sensors", "CPUx")
+                        except configparser.NoOptionError:
+                            CPUx_Temp = ''
+
+                        try:
+                            CPUy_Temp = config.get("Sensors", "CPUy")
+                        except configparser.NoOptionError:
+                            CPUy_Temp = ''
+                    
+                        if need_id == CPUx_Temp:
+                        
+                            try:
+                                PxTM = config.get("SensorsForCPUTemp", "Px Therm Margin")
+                            except configparser.NoOptionError:
+                                PxTM = ''
+
+                            try:
+                                CPUx_Tjmax = config.get("SensorsForCPUTemp", "CPUx Tjmax")
+                            except configparser.NoOptionError:
+                                CPUx_Tjmax = ''
+
+                            if PxTM and CPUx_Tjmax:
+                                Px_temp = calculate_CPU_temp(data, PxTM, CPUx_Tjmax) 
+                                need_data.update({CPUx_Temp:Px_temp})
+                                if Px_temp == 'None' or Px_temp == 'Error':
+                                    disable = 1
+                            else:
+                                disable = 1
+                                
+                        elif need_id == CPUy_Temp:
+
+                            try:
+                                PyTM = config.get("SensorsForCPUTemp", "Py Therm Margin")
+                            except configparser.NoOptionError:
+                                PyTM = ''
+
+                            try:
+                                CPUy_Tjmax = config.get("SensorsForCPUTemp", "CPUy Tjmax")
+                            except configparser.NoOptionError:
+                                CPUy_Tjmax = ''
+
+                            if PyTM and CPUy_Tjmax:
+                                Py_temp = calculate_CPU_temp(data, PyTM, CPUy_Tjmax)
+                                need_data.update({CPUy_Temp:Py_temp})
+                                if Py_temp == 'None' or Py_temp == 'Error':
+                                    disable = 1
+                            else:
+                                disable = 1
+                                
+                        else:
+                            need_data.update({need_id:'None'})
+                            disable = 1
+            
+                if disable == 1:
+                    dis_flag = 1
+                    print(need_data)
+                    print("=======================================================")
+                    count = count+1
+        print("Pass: %d" %(times-count))
+        print("Fail: %d" %(count))
+        
+    if cmd_flag == 1 or prs_flag == 1 or dis_flag == 1:
+        return 100
+    return 0
+
+def main():
+
+    intro_message = "Default config location is /etc/checkbox.d/bmc.cfg"
+    parser = ArgumentParser(description=intro_message, formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', type=str, default="/etc/checkbox.d/bmc.cfg", help="Supply config file for sensor IDs parameters")
+    args = parser.parse_args()
+    return ipmi_sdr(args)
+
+if __name__ == "__main__":
+    sys.exit(main())

=== modified file 'bin/ipmi_sel_entries'
--- bin/ipmi_sel_entries	2015-03-03 15:59:42 +0000
+++ bin/ipmi_sel_entries	2015-08-14 22:03:31 +0000
@@ -5,13 +5,11 @@
 
 File Name
   ipmi_sel_entries
+
+Description
   1. Use ipmitool to collect event log information
   2. Calculate entries number of system event log
-  3. Criteria: the A log must be capable of saving at least 256 entries
-
-Description
-  Use ipmitool to get system event log info and calculate whether 
-  total number of entries is more than 256.
+  3. Criteria: the log must be capable of saving at least 256 entries
 
 Authors
   Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
@@ -63,8 +61,8 @@
 
 def sel_entry_test(args):
 
-    #Default config file to config requirement info for DCMI in-band/out-of-band access 
-    DEFAULT_CFG = "/etc/checkbox.d/me.cfg"
+    #Default config file to config requirement info for IPMI in-band/out-of-band access 
+    DEFAULT_CFG = "/etc/checkbox.d/bmc.cfg"
     if not "config" in vars(args):
         config_file = DEFAULT_CFG
     else:
@@ -101,7 +99,7 @@
     for target in targets_list:
 
         if not target or not user_value or not passwd_value:
-            print("Require Taget IP, Account(USER/PASSWORD) for DCMI out-of-band access")
+            print("Require Taget IP, Account(USER/PASSWORD) for IPMI out-of-band access")
             return 50
         else:
             print("SUT =", target)
@@ -135,11 +133,11 @@
 
 def main():
 
-    intro_message = "Default config location is /etc/checkbox.d/me.cfg"
+    intro_message = "Default config location is /etc/xdg/bmc.cfg"
     parser = ArgumentParser(description=intro_message,
                             formatter_class=RawTextHelpFormatter)
-    parser.add_argument('--config', default="/etc/checkbox.d/me.cfg",
-                        help="Supply config file for getting default credential")
+    parser.add_argument('--config', default="/etc/checkbox.d/bmc.cfg",
+                        help="Supply config file for getting authentication info")
     args = parser.parse_args()
     return sel_entry_test(args)
 

=== added file 'bin/ipmi_sensors_ib'
--- bin/ipmi_sensors_ib	1970-01-01 00:00:00 +0000
+++ bin/ipmi_sensors_ib	2015-08-14 22:03:31 +0000
@@ -0,0 +1,215 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  ipmi_sensors_ib
+
+Description
+  1. Use ipmitool/dcmitool to monitor analog sensors in SDR table through in-band access.
+  2. Criteria: the status of analog sensors should be "ok" and the data should not be null.
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+import sys
+import time
+import re
+import configparser
+import shlex
+import subprocess
+import ast
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+
+
+def get_sdr(TOOL):
+    cmd = "{} sdr".format(TOOL)
+    sdr_return = subprocess.check_output(shlex.split(cmd), universal_newlines=True)
+    return sdr_return
+
+def parse_sdr(output):
+    output = output.strip()
+    output_1Line = output.split("\n")
+    data = {}
+
+    for line in output_1Line:
+        sub_value = {}
+        string_list = line.split("|")
+        name = string_list[0].strip()
+        sensor_output = string_list[1].strip()
+        sub_value.update({'output':sensor_output})
+        status = string_list[2].strip()
+        sub_value.update({'status':status})
+        data.update({name:sub_value})
+    return data
+
+def calculate_CPU_temp(data_dict, CPU_Therm_Margin_id, CPU_Tjmax_id):
+
+    if data_dict.get(CPU_Therm_Margin_id) and data_dict.get(CPU_Tjmax_id):
+        if data_dict.get(CPU_Therm_Margin_id).get('status') == 'ok' and data_dict.get(CPU_Tjmax_id).get('status') == 'ok':
+            P_Therm_Margin_output = data_dict.get(CPU_Therm_Margin_id).get('output')
+            CPU_Tjmax_output = data_dict.get(CPU_Tjmax_id).get('output')
+            P_Therm_Margin = re.search(r'[0-9-]+', P_Therm_Margin_output).group(0)
+            CPU_Tjmax = re.search(r'[0-9-]+', CPU_Tjmax_output).group(0)
+            CPU_temp = int(P_Therm_Margin)+int(CPU_Tjmax)
+            return str(CPU_temp)+' degrees C'
+        else:
+            return 'Error'
+    else:
+        return 'None'
+
+def ipmi_sdr(args):
+
+    flag = 0
+
+    tool_name = args.tool
+    if not tool_name:
+        print("No specified tool to use")
+        return 99
+        
+    #IPMI/DCMI config file
+    DEFAULT_CFG = "/etc/checkbox.d/bmc.cfg"
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+    config = configparser.RawConfigParser()
+
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    try:
+        sensor_nick = config.options("Sensors")			
+    except configparser.NoSectionError:
+        print("No Section: Sensors")
+        return 20
+
+    if sensor_nick:
+        sensor_list = []
+        for id in sensor_nick:
+            sensor_key = config.get("Sensors", id)
+            if sensor_key:
+                sensor_list.append(sensor_key)
+            else:
+                print("No Sensor ID specified in Config file")
+                return 30
+    else:
+        print("No key of Sensor ID specified in config file")
+        return 40
+
+    try:
+        sensor_data = get_sdr(tool_name)
+        time.sleep(5)
+    except CalledProcessError as ipmi_exception:
+        print("Failed executing ipmi, Reason: %s" % ipmi_exception)
+        return 50
+
+    try:
+        data = parse_sdr(sensor_data)
+    except:
+        print("Parsing output of sdr table error")
+        return 60
+
+    need_data = {}
+    for need_id in sensor_list:
+        if data.get(need_id):
+            need_value = data.get(need_id).get('output')
+            need_data.update({need_id:need_value})
+            
+            if data.get(need_id).get('status') != 'ok':
+                flag = 1
+        else:
+
+           try:
+               CPUx_Temp = config.get("Sensors", "CPUx")
+           except configparser.NoOptionError:
+               CPUx_Temp = ''
+
+           try:
+               CPUy_Temp = config.get("Sensors", "CPUy")
+           except configparser.NoOptionError:
+               CPUy_Temp = ''
+
+           if need_id == CPUx_Temp:
+
+                try:
+                    PxTM = config.get("SensorsForCPUTemp", "Px Therm Margin")
+                except configparser.NoOptionError:
+                    PxTM = ''
+                    
+                try:
+                    CPUx_Tjmax = config.get("SensorsForCPUTemp", "CPUx Tjmax")
+                except configparser.NoOptionError:
+                    CPUx_Tjmax = ''
+
+                if PxTM and CPUx_Tjmax:
+                    need_data.update({CPUx_Temp:calculate_CPU_temp(data, PxTM, CPUx_Tjmax)})
+                    if calculate_CPU_temp(data, PxTM, CPUx_Tjmax) == 'None' or calculate_CPU_temp(data, PxTM, CPUx_Tjmax) == 'Error':
+                        flag = 1
+                else:
+                    flag = 1
+
+           elif need_id == CPUy_Temp:
+                
+                try:
+                    PyTM = config.get("SensorsForCPUTemp", "Py Therm Margin")
+                except configparser.NoOptionError:
+                    PyTM = ''
+
+                try:
+                    CPUy_Tjmax = config.get("SensorsForCPUTemp", "CPUy Tjmax")
+                except configparser.NoOptionError:
+                    CPUy_Tjmax = ''
+
+
+                if PyTM and CPUy_Tjmax:
+                    need_data.update({CPUy_Temp:calculate_CPU_temp(data, PyTM, CPUy_Tjmax)})
+                    if calculate_CPU_temp(data, PyTM, CPUy_Tjmax) == 'None' or calculate_CPU_temp(data, PyTM, CPUy_Tjmax) == 'Error':
+                        flag = 1
+                else:
+                    flag = 1
+           else:
+                flag = 1
+            
+        print("%s: %s" %(need_id, need_data.get(need_id)))
+
+    if flag == 1:
+        return 100
+    return 0
+
+def main():
+
+    intro_message = "Default config location is /etc/checkbox.d/bmc.cfg"
+    parser = ArgumentParser(description=intro_message, formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', type=str, default="/etc/checkbox.d/bmc.cfg", help="Supply config file for sensor IDs parameters")
+    parser.add_argument('--tool', help="ipmitool or dcmitool")
+    args = parser.parse_args()
+    return ipmi_sdr(args)
+
+if __name__ == "__main__":
+    sys.exit(main())
+

=== added file 'bin/ipmi_sensors_oob'
--- bin/ipmi_sensors_oob	1970-01-01 00:00:00 +0000
+++ bin/ipmi_sensors_oob	2015-08-14 22:03:31 +0000
@@ -0,0 +1,240 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  ipmi_sensors_oob
+
+Description
+  1. Use ipmitool to monitor analog sensors in SDR table through OOB access.
+  2. Criteria: the status of analog sensors should be "ok" and the data should not be null.
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+import sys
+import time
+import re
+import configparser
+import shlex
+import subprocess
+import ast
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+
+def get_sdr_remote(host_ip, user, password):
+    cmd = "ipmitool -H {} -U {} -P {} sdr".format(host_ip, user, password)
+    sdr_return = subprocess.check_output(shlex.split(cmd), stderr=subprocess.STDOUT,
+                                         universal_newlines=True)
+    return sdr_return
+
+def parse_sdr(output):
+    output = output.strip()
+    output_1Line = output.split("\n")
+    data = {}
+
+    for line in output_1Line:
+        sub_value = {}
+        string_list = line.split("|")
+        name = string_list[0].strip()
+        sensor_output = string_list[1].strip()
+        sub_value.update({'output':sensor_output})
+        status = string_list[2].strip()
+        sub_value.update({'status':status})
+        data.update({name:sub_value})
+    return data
+
+def calculate_CPU_temp(data_dict, CPU_Therm_Margin_id, CPU_Tjmax_id):
+
+    if data_dict.get(CPU_Therm_Margin_id) and data_dict.get(CPU_Tjmax_id):
+        if data_dict.get(CPU_Therm_Margin_id).get('status') == 'ok' and data_dict.get(CPU_Tjmax_id).get('status') == 'ok':
+            P_Therm_Margin_output = data_dict.get(CPU_Therm_Margin_id).get('output')
+            CPU_Tjmax_output = data_dict.get(CPU_Tjmax_id).get('output')
+            P_Therm_Margin = re.search(r'[0-9-]+', P_Therm_Margin_output).group(0)
+            CPU_Tjmax = re.search(r'[0-9-]+', CPU_Tjmax_output).group(0)
+            CPU_temp = int(P_Therm_Margin)+int(CPU_Tjmax)
+            return str(CPU_temp)+' degrees C'
+        else:
+            return 'Error'
+    else:
+        return 'None'
+
+def ipmi_sdr(args):
+
+    flag = 0
+    #IPMI config file
+    DEFAULT_CFG = "/etc/checkbox.d/bmc.cfg"
+    if not "config" in vars(args):
+        config_file = DEFAULT_CFG
+    else:
+        config_file = args.config
+
+    config = configparser.RawConfigParser()
+
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    try:
+        sensor_nick = config.options("Sensors")
+    except configparser.NoSectionError:
+        print("No Section: Sensors")
+        return 20
+    
+    if sensor_nick:
+        sensor_list = []
+        for id in sensor_nick:
+            sensor_key = config.get("Sensors", id)
+            if sensor_key:
+                sensor_list.append(sensor_key)
+            else:
+                print("No Sensor ID specified in Config file")
+                return 30
+    else:
+        print("No key of Sensor ID specified in config file")
+        return 40
+
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 60
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 60
+
+    try:
+        user_value = config.get("Account", "USER")
+        password_value = config.get("Account", "PASSWORD")
+    except configparser.NoOptionError:
+        print("Invalid or Empty credential info")
+        return 70
+
+    for tg in targets_list:
+
+        if not tg or not user_value or not password_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for IPMI out-of-band access")
+            return 80
+        else:
+
+            print("SUT =", tg)
+            print("USER =", user_value)
+            print("PASSWORD =", password_value)
+
+            try:
+                sensor_data = get_sdr_remote(tg, user_value, password_value)
+                time.sleep(5)
+            except CalledProcessError as ipmi_exception:
+                print("Failed executing ipmi, Reason: %s" % ipmi_exception)
+                return 50
+
+            try:
+                data = parse_sdr(sensor_data)
+            except:
+                print("Parsing output of sdr table error")
+                flag = 1
+                continue
+
+            need_data = {}
+            for need_id in sensor_list:
+
+                if data.get(need_id):
+                    need_value = data.get(need_id).get('output')
+                    need_data.update({need_id:need_value})
+
+                    if data.get(need_id).get('status') != 'ok':
+                        flag = 1
+                else:
+
+                    try:
+                        CPUx_Temp = config.get("Sensors", "CPUx")
+                    except configparser.NoOptionError:
+                        CPUx_Temp = ''
+
+                    try:
+                        CPUy_Temp = config.get("Sensors", "CPUy")
+                    except configparser.NoOptionError:
+                        CPUy_Temp = ''
+
+                    if need_id == CPUx_Temp:
+
+                        try:
+                            PxTM = config.get("SensorsForCPUTemp", "Px Therm Margin")
+                        except configparser.NoOptionError:
+                            PxTM = ''
+
+                        try:
+                            CPUx_Tjmax = config.get("SensorsForCPUTemp", "CPUx Tjmax")
+                        except configparser.NoOptionError:
+                            CPUx_Tjmax = ''
+
+                        if PxTM and CPUx_Tjmax:
+                            need_data.update({CPUx_Temp:calculate_CPU_temp(data, PxTM, CPUx_Tjmax)})
+                            if calculate_CPU_temp(data, PxTM, CPUx_Tjmax) == 'None' or calculate_CPU_temp(data, PxTM, CPUx_Tjmax) == 'Error':
+                                flag = 1
+                        else:
+                            flag = 1
+
+                    elif need_id == CPUy_Temp:
+                        
+                        try:
+                            PyTM = config.get("SensorsForCPUTemp", "Py Therm Margin")
+                        except configparser.NoOptionError:
+                            PyTM = ''
+
+                        try:
+                            CPUy_Tjmax = config.get("SensorsForCPUTemp", "CPUy Tjmax")
+                        except configparser.NoOptionError:
+                            CPUy_Tjmax = ''
+                        
+                        if PyTM and CPUy_Tjmax:
+                            need_data.update({CPUy_Temp:calculate_CPU_temp(data, PyTM, CPUy_Tjmax)})
+                            if calculate_CPU_temp(data, PyTM, CPUy_Tjmax) == 'None' or calculate_CPU_temp(data, PyTM, CPUy_Tjmax) == 'Error':
+                                flag = 1
+                        else:
+                            flag = 1
+                    else:
+                        #need_data.update({need_id:'None'})
+                        flag = 1
+
+                print("%s: %s" %(need_id, need_data.get(need_id)))
+
+    if flag == 1:
+        return 100
+    return 0
+
+def main():
+
+    intro_message = "Default config location is /etc/checkbox.d/bmc.cfg"
+    parser = ArgumentParser(description=intro_message, formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', type=str, default="/etc/checkbox.d/bmc.cfg", help="Supply config file for sensor IDs parameters")
+    args = parser.parse_args()
+    return ipmi_sdr(args)
+
+if __name__ == "__main__":
+    sys.exit(main())

=== added file 'bin/ipmi_warm_reboot'
--- bin/ipmi_warm_reboot	1970-01-01 00:00:00 +0000
+++ bin/ipmi_warm_reboot	2015-08-14 22:03:31 +0000
@@ -0,0 +1,173 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2014 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+File Name
+  ipmi_warm_reboot
+
+Description
+  1. Use ipmitool out-of-band access to power soft(off) and power on the SUT 20 times.
+  2. Criteria: complete power soft(off) and power on the SUT successfully using ipmitool out-of-band access.
+
+Authors
+  Sophia Wu <Sophia.Wu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+import sys
+import subprocess
+import time 
+import configparser
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+
+def ping_host_test(host_ip):
+    
+    ping_host_cmd = '/usr/share/checkbox/scripts/ping_test --ip_addr {} --cycle_time 60 --times 5 1>/dev/null 2>/dev/null'.format(host_ip)
+    return_code = subprocess.call(ping_host_cmd, shell=True)
+    return return_code
+
+def ping_bmc_test(bmc_ip):
+
+    ping_bmc_cmd = '/usr/share/checkbox/scripts/ping_test --ip_addr {} --cycle_time 30 --times 6 1>/dev/null 2>/dev/null'.format(bmc_ip)
+    return_code = subprocess.call(ping_bmc_cmd, shell=True)
+    return return_code
+
+def ping_result(ip):
+    
+    ping_cmd = 'ping -c 1 {} 1>/dev/null 2>/dev/null'.format(ip)
+    return_code = subprocess.call(ping_cmd, shell=True)
+    return return_code
+
+def ipmi_power_soft(bmc_ip, user, password):
+    power_soft_cmd = 'ipmitool -H {} -P {} -U {} power soft 1>/dev/null 2>/dev/null'.format(bmc_ip, user, password)
+    return_code = subprocess.call(power_soft_cmd, shell=True)
+    return return_code
+
+def ipmi_power_on(bmc_ip, user, password):
+    power_on_cmd = 'ipmitool -H {} -P {} -U {} power on 1>/dev/null 2>/dev/null'.format(bmc_ip, user, password)
+    return_code = subprocess.call(power_on_cmd, shell=True)
+    return return_code
+
+def ipmi_warm_reboot(args):
+
+    DEFAULT_CFG = "/etc/checkbox.d/bmc.cfg"
+    host_ip = args.ip_addr
+    config_file = DEFAULT_CFG
+
+    config = configparser.RawConfigParser()
+
+    try:
+        config.readfp(open(config_file))
+    except IOError:
+        print("No config file found")
+        return 10
+
+    try:
+        targets_options = config.options('Targets')
+        targets_list = []
+        for target_key in targets_options:
+            targets_list.append(config.get('Targets', target_key))
+
+        if not targets_list:
+            print("Invalid or Empty targets")
+            return 20
+
+    except configparser.Error:
+        print("Invalid or Empty targets")
+        return 30
+
+    try:
+        user_value = config.get('Account', 'USER')
+        passwd_value = config.get('Account', 'PASSWORD')
+        if not user_value or not passwd_value:
+            print("Invalid or Empty credential info")
+            return 40
+
+    except configparser.Error:
+        print("Invalid or Empty credential info")
+        return 50
+
+    flag = 0
+    for tg in targets_list:
+
+        if not tg or not user_value or not passwd_value:
+            print("Require Taget IP, Account(USER/PASSWORD) for IPMI out-of-band access")
+            return 60
+        elif not host_ip:
+            print("No IP address given")
+            return 70
+        else:
+
+            print("SUT =", tg)
+            print("HOST =", host_ip)
+            for n in range(20):
+                
+                print("COUNT =", n)
+                
+                if ping_host_test(host_ip) == 0 and ping_bmc_test(tg) == 0:
+                    power_soft_return = ipmi_power_soft(tg, user_value, passwd_value)
+                    time.sleep(30)
+                    if power_soft_return == 0:
+                        print("Successful to perform power soft via BMC")
+                        ping_count = 0
+                        while ping_result(host_ip) == 0:
+                            time.sleep(30)
+                            ping_count = ping_count+1
+                            if ping_count >= 5:
+                                print("OS is still alive")
+                                return 80
+                        if ping_bmc_test(tg) == 0:
+                            power_on_return = ipmi_power_on(tg, user_value, passwd_value)
+                            time.sleep(300)
+                            if power_on_return == 0:
+                                print("Successful to perform power on via BMC")
+                            else:
+                                print("Fail to perform power on via BMC")
+                                flag = 1
+                                break
+                        else: 
+                            print("Fail to connect to BMC")
+                            flag = 1
+                            break	    
+                    else:
+                        print("Fail to perform power soft via BMC")
+                        flag = 1
+                        break
+                else:
+                    print("Network connection fail")
+                    flag=1
+                    break
+
+    if flag == 1:
+        return 1
+    return 0
+
+def main():
+
+    intro_message = "Default config location is /etc/checkbox.d/bmc.cfg"
+    parser = ArgumentParser(description=intro_message,
+                 formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--config', type=str,
+                 default="/etc/checkbox.d/bmc.cfg",
+                 help="Supply config file for getting authentication info")
+    parser.add_argument('--ip_addr', help="Host IP Address")
+    args = parser.parse_args()
+    return ipmi_warm_reboot(args)
+
+if __name__ == '__main__':
+    sys.exit(main())

=== added file 'bin/ocp_memory_info'
--- bin/ocp_memory_info	1970-01-01 00:00:00 +0000
+++ bin/ocp_memory_info	2015-08-14 22:03:31 +0000
@@ -0,0 +1,80 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+It is NOT YET officially approved by OCP.
+
+memory_info
+  1. Use lshw command to gather memory information.
+  2. Testing prerequisites:
+     4 channels DDR3 registered memory interface on each processor 0 
+     and processor 1.
+     2 DDR3 slots per channel per processor. (total of 16 DIMMs 
+                                              on the motherboard)
+  3. The program will output memory module, vendor, size and slot.
+  4. Criteria: Total of 16 DIMMs on the motherboard.
+
+Authors
+  Nelson Chu <Nelson.Chu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+import sys
+import xml.etree.ElementTree as ET
+from subprocess import Popen, PIPE
+
+def main():
+    attribute = ['description', 'vendor', 'slot', 'size']
+    command = 'lshw -xml'
+    hwinfo_xml = Popen(command, stdout=PIPE, stderr=PIPE,
+                       shell=True).communicate()[0]
+    root = ET.fromstring(hwinfo_xml)
+
+    # Parse lshw XML for gathering memory information.
+    memory_list = root.findall(".//clock/..[@class='memory']")
+
+    if not memory_list:
+        print("Fail: Cannot parse any memory information.", file=sys.stderr)
+        return 10
+
+    count = 0
+    for dimm in memory_list:
+        count = count +1
+        for attr in attribute:
+            if dimm.find(attr) is None:
+                print(("Fail: Cannot find memory %s") %attr, file=sys.stderr)
+                return 20
+
+        memory_size = int(dimm.find('size').text) / (1024**3)
+        for attr in attribute:
+            if attr == 'description':
+                print('%s' %(dimm.find(attr).text), end=" ")
+                continue
+            elif attr == 'size':
+                print('%s=%dGB.' %(attr, memory_size))
+                continue
+            print('%s=%s' %(attr, dimm.find(attr).text), end=" ")
+
+    print("Total number of DIMMs is %s." %(count))
+    if count != 16:
+        print("Fail: Memory DIMM number is not meet the requirement.",
+        file=sys.stderr)
+        return 30
+
+    return 0
+
+if __name__ == '__main__':
+    sys.exit(main())

=== added file 'bin/ping_test'
--- bin/ping_test	1970-01-01 00:00:00 +0000
+++ bin/ping_test	2015-08-14 22:03:31 +0000
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+"""
+File Name
+  ping_test
+
+Description
+ 1. Test network connection using ping
+ 
+Authors
+  Sophia Wu 
+
+"""
+
+from argparse import (
+    ArgumentParser,
+    RawTextHelpFormatter
+)
+import sys
+import time
+import subprocess
+from subprocess import (
+    check_output,
+    CalledProcessError
+)
+
+def ping_test(args):
+    IP = args.ip_addr
+    CYCLE_TIME = args.cycle_time
+    TIMES = args.times
+    if IP is None:
+        print("No IP address given")
+        return 1
+
+    if CYCLE_TIME is None:
+        CYCLE_TIME = 10
+
+    if TIMES is None:
+        TIMES = 30
+
+
+    count = 1
+    while count <= TIMES: 
+        ping_cmd = 'ping -c 1 {}>/dev/null 2>/dev/null'.format(IP)
+        ping_rtn = subprocess.call(ping_cmd, shell=True)
+        print("=============================================")
+        print("ping test count = ", count)
+
+        if ping_rtn == 0:
+            print("Succesfully connect to", IP)
+            return 0
+        else:
+            print("Fail to connect to", IP)
+            time.sleep(CYCLE_TIME)
+            if count >= TIMES:
+                print()
+                print("*********************************************")
+                print()
+                print("TIMEOUT, END of TEST.")
+                print()
+                print("*********************************************")
+                return 2
+            count = count+1
+            continue
+        
+def main():
+    intro_message = "Test network connection using ping tool."
+    parser = ArgumentParser(description=intro_message,
+                            formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--ip_addr')
+    parser.add_argument('--cycle_time', type=int)
+    parser.add_argument('--times', type=int)
+    args = parser.parse_args()
+    return ping_test(args)
+
+if __name__ == '__main__':
+    sys.exit(main())

=== modified file 'bin/processor_topology'
--- bin/processor_topology	2015-03-03 15:59:42 +0000
+++ bin/processor_topology	2015-08-14 22:03:31 +0000
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 '''
+It is NOT YET officially approved by OCP.
 cpu_topology
 Written by Jeffrey Lane <jeffrey.lane@xxxxxxxxxxxxx>
 '''
@@ -46,6 +47,11 @@
         for i in items:
             syscpu_fh = open(os.path.join(self.path, i), 'r')
             try:
+                syscpu_fh = open(os.path.join(self.path, i), 'r')
+            except OSError as e:
+                print("ERROR: %s" % e)
+                sys.exit(1)
+            else:
                 self.syscpu[i] = syscpu_fh.readline().strip()
             finally:
                 syscpu_fh.close()

=== added file 'bin/raid_availability_test'
--- bin/raid_availability_test	1970-01-01 00:00:00 +0000
+++ bin/raid_availability_test	2015-08-14 22:03:31 +0000
@@ -0,0 +1,62 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+It is NOT YET officially approved by OCP.
+
+raid_availability_test
+  Test Read/Write file correctly on RAID.
+
+Authors
+  Nelson Chu <Nelson.Chu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+import os
+import sys
+import xml.etree.ElementTree as ET
+from subprocess import check_output, Popen, PIPE
+
+def main():
+    current_directory = os.getcwd()
+    working_directory = os.path.dirname(os.path.abspath(__file__))
+    return_code = 0
+
+    command = "lsscsi |grep -i lsi | awk -F ' ' '{print $6}'"
+    with open(os.devnull, "w") as NULL:
+      device = check_output(command, stderr=NULL, shell=True)
+
+    device = device.decode('utf-8')
+
+    if not device:
+        print("Cannot find any RAID volume.")
+        return 10
+
+    # Test read/write file on RAID device.
+    command = '{0}/read_write_file -d {1}'.format(working_directory,
+                                                  device)
+    proc = Popen(command, stdout=PIPE, stderr=PIPE, shell=True)
+    try:
+        outs = proc.communicate()[1]
+        return_code = proc.returncode
+        print(outs.decode('utf-8'))
+    except Exception as e:
+        return 20
+
+    return return_code
+
+if __name__ == '__main__':
+    sys.exit(main())

=== added file 'bin/raid_hdd_info'
--- bin/raid_hdd_info	1970-01-01 00:00:00 +0000
+++ bin/raid_hdd_info	2015-08-14 22:03:31 +0000
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+It is NOT YET officially approved by OCP.
+
+raid_hdd_info
+  1. Use megasasctl command to get all JBOD HDD information.
+  2. Show total HDD number in JBOD and check disks readiness.
+  3. Criteria: ensure all JBOD disks information and status are correct.
+
+Authors
+  Nelson Chu <Nelson.Chu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+import sys
+from subprocess import Popen, PIPE
+
+def main():
+    command = 'megasasctl |grep -E "a[0-9]+e[0-9]+s[0-9]+ +[0-9]+GiB"'
+    hdd_info = Popen(command, stdout=PIPE, stderr=PIPE,
+                     shell=True).communicate()[0]
+    hdd_info = hdd_info.decode('utf-8')
+    disk_number = 0
+    fail = 0
+
+    # Check is there has any disk.
+    if not hdd_info:
+        print('There is no disk in knox.')
+        return 10
+
+    for disk in hdd_info.strip().split('\n'):
+        disk_number = disk_number+1
+        # Check disk status is readiness.
+        if disk.strip().split(' ')[-1] != 'ready':
+            fail = fail+1
+
+    print(('Total number of %d HDDs in JBOD.') %disk_number)
+
+    if fail:
+        print(('There are %d disks status not in ready.') %fail)
+        return 20
+
+    return 0
+
+if __name__ == '__main__':
+    sys.exit(main())

=== modified file 'bin/raid_info'
--- bin/raid_info	2015-03-03 15:59:42 +0000
+++ bin/raid_info	2015-08-14 22:03:31 +0000
@@ -3,6 +3,8 @@
 # Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
 # Industrial Technology Research Institute
 #
+#It is NOT YET officially approved by OCP.
+#
 # raid_info
 #   1. Use megasasctl command to gather LSI RAID card information.
 #   2. The program will output adapter, product name, memory, BBU, serial no.

=== added file 'bin/read_write_file'
--- bin/read_write_file	1970-01-01 00:00:00 +0000
+++ bin/read_write_file	2015-08-14 22:03:31 +0000
@@ -0,0 +1,181 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+It is NOT YET officially approved by OCP.
+
+read_write_file
+  1. Create one partition and format on disk to test disk I/O.
+  2. Test RAID Read/Write file correctly.
+  3. Criteria: Create/Read/Write file without error.
+
+Authors
+  Nelson Chu <Nelson.Chu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+import os
+import re
+import sys
+import logging
+from subprocess import check_output, check_call, STDOUT
+from argparse import ArgumentParser, RawTextHelpFormatter
+
+log_formatter = '%(asctime)s [%(levelname)-4s] %(funcName)s: %(message)s'
+logging.basicConfig(level=logging.INFO,
+                    format=log_formatter,
+                    datefmt='%Y-%m-%d %H:%M:%S')
+
+
+def read_file_test(mount_point, file_size):
+    command = "dd if={0}/test_file of=/dev/null ".format(mount_point) \
+        + "bs=1M count={0} iflag=direct".format(file_size)
+
+    output = check_output(command, stderr=STDOUT, shell=True)
+    output = output.decode("utf-8")
+
+    match = re.search(r'\((.*)\)\D*(\d+\.\d+)\D*(\d+.*)', output)
+    if not match:
+        logging.error('Does not match patterns of read file test.')
+        return False
+
+    logging.info('Read file successful: %s in %s seconds, speed= %s.'
+                %match.group(1,2,3))
+    return True
+
+
+def write_file_test(mount_point, file_size):
+    command = "dd if=/dev/zero of={0}/test_file ".format(mount_point) \
+        + "bs=1M count={0} oflag=direct".format(file_size)
+
+    output = check_output(command, stderr=STDOUT, shell=True)
+    output = output.decode("utf-8")
+
+    match = re.search(r'\((.*)\)\D*(\d+\.\d+)\D*(\d+.*)', output)
+    if not match:
+        logging.error('Does not match patterns of write file test.')
+        return False
+
+    logging.info('Write file successful: %s in %s seconds, speed= %s.'
+                %match.group(1,2,3))
+    return True
+
+
+def umount_filesystem(mount_point):
+    umount_cmd = "umount {0}".format(mount_point)
+    with open(os.devnull, "w") as NULL:
+        check_call(umount_cmd, stdout=NULL, stderr=NULL, shell=True)
+    logging.debug('Umount %s directory successful.' %mount_point)
+    
+
+def mount_filesystem(device):
+    mount_point = '/mnt/' + os.path.basename(device)
+    if not os.path.exists(mount_point):
+        os.mkdir(mount_point)
+        logging.debug('Create %s directory successful!' %mount_point)
+    else:
+        if os.path.ismount(mount_point):
+            logging.debug('The %s directory is already mounted.' %mount_point)
+            umount_filesystem(mount_point)
+    
+    mount_cmd = "mount {0} {1}".format(device, mount_point)
+    with open(os.devnull, "w") as NULL:
+        check_call(mount_cmd, stdout=NULL, stderr=NULL, shell=True)
+    logging.debug('Mount %s on %s directory successful.' 
+                %(device, mount_point))
+    return mount_point
+
+
+def format_device(device):
+    command = "mkfs.ext4 -F {0}".format(device)
+    logging.debug('Format %s device beginning.' %device)
+    with open(os.devnull, "w") as NULL:
+        check_call(command, stdout=NULL, stderr=NULL, shell=True)
+    logging.debug('Format %s completed successfully.' %device)
+
+
+def run(device, file_size):
+
+    # format device
+    try:
+        format_device(device)
+    except Exception as e:
+        logging.error('%s' %e)
+        return 20
+
+    # mount device on system
+    try:
+        mount_point = mount_filesystem(device)
+    except Exception as e:
+        logging.error('%s' %e)
+        return 30
+
+    # write file test
+    try:
+        if not write_file_test(mount_point, file_size):
+            return 35
+    except Exception as e:
+        logging.error('%s' %e)
+        return 40
+
+    # read file test
+    try:
+        if not read_file_test(mount_point, file_size):
+            return 45
+    except Exception as e:
+        logging.error('%s' %e)
+        return 50
+
+    # umount device
+    try:
+        umount_filesystem(mount_point)
+    except Exception as e:
+        logging.error('%s' %e)
+        return 60
+
+    return 0
+
+
+def main():
+    description_text = 'read_write_file\n\tTest the device read/write file ' \
+        + 'correctly.\n\n\n\tWarning: This program will create one partition' \
+        + ' on device and format it.\n\t\t  Please make sure what you are ' \
+        + 'doing!\n\n\n\tRequirement: Give a device name on the system.'
+
+    parser = ArgumentParser(description=description_text,
+                            formatter_class=RawTextHelpFormatter)
+
+    parser.add_argument('-d', '--device', type=str, required=True,
+                      help=('The device name which used to read write test.\n'
+                            '[Example: sda]'))
+    parser.add_argument('-m', '--megabyte', type=int,
+                        default=5000,
+                        help=('The test file size. [Default: 5GB]'))
+
+    args = parser.parse_args()
+
+    device = args.device
+    if not device.startswith('/dev/'):
+        device = '/dev/' + device
+
+    if not os.path.exists(device):
+        parser.print_help()
+        return 10
+
+    return run(device, args.megabyte)
+
+
+if __name__ == '__main__':
+    sys.exit(main())

=== added file 'bin/rebulid_raid'
--- bin/rebulid_raid	1970-01-01 00:00:00 +0000
+++ bin/rebulid_raid	2015-08-14 22:03:31 +0000
@@ -0,0 +1,280 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+It is NOT YET officially approved by OCP.
+
+rebulid_raid
+  1. Tests LSI RAID card auto rebuild function.
+  2. Criteria: rebuild RAID successfully.
+
+Authors
+  Nelson Chu <Nelson.Chu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+import os
+import re
+import sys
+import time
+import random
+import logging
+from subprocess import check_output, check_call
+from argparse import ArgumentParser, RawTextHelpFormatter
+
+logFormatter = logging.Formatter(
+    "%(asctime)s [%(levelname)-5.5s] %(funcName)s: %(message)s", 
+    datefmt='%Y-%m-%d %H:%M:%S')
+logger = logging.getLogger()
+logger.setLevel(logging.DEBUG)
+
+
+def get_adapter():
+    """
+    Gather all adapter number if there are multiple RAID card.
+    """
+
+    command = 'megacli -CfgDsply -Aall|grep Adapter'
+    adapter_list = []
+
+    adapter_info = check_output(command, shell=True)
+    adapter_info = adapter_info.decode('utf-8')
+
+    for adapter in adapter_info.strip().split('\n'):
+        adapter_list.append(adapter.strip().split(' ')[-1])
+    logger.debug('adapter_list: %s' %adapter_list)
+    return adapter_list
+
+
+def get_all_disk(adapter):
+    """
+    Gather all disks Enclosure and Slot number, and make a 
+    Enclosure:Slot pair list.
+    """
+
+    command = ('megacli -PDList -A%s|grep -E "Enclosure Device ID|Slot Numbe"' 
+               %adapter)
+    disk_list = []
+    disk_info = check_output(command, shell=True)
+    disk_info = disk_info.decode('utf-8')
+
+    for line in disk_info.strip().split('\n'):
+        if line.startswith('Enclosure'):
+            match = re.search(r'\d+', line)
+            disk_list.append(match.group(0))
+        if line.startswith('Slot'):
+            match = re.search(r'\d+', line)
+            enclosure = disk_list.pop()
+            E_S = '%s:%s' %(enclosure, match.group(0))
+            disk_list.append(E_S)
+
+    logger.debug('adapter: %s, disk_list: %s' %(adapter, disk_list))
+    return disk_list
+
+
+def set_disk_offline(adapter, disk_list):
+    """
+    Use all disk creatd RAID 6 and set last disk as hot spare.
+    """
+
+    # Random offline one disk in disk list.
+    disk = disk_list[random.randint(0, len(disk_list)-1)]
+    command = ('megacli -PDOffline -PhysDrv [%s] -a%s' %(disk, adapter))
+    with open(os.devnull, "w") as NULL:
+        check_call(command, stdout=NULL, stderr=NULL, shell=True)
+    logger.info('Random offline one disk in disk list, Enclosure: %s, Slot: %s' 
+                %(disk.split(':')[0], disk.split(':')[1]))
+
+
+def find_hotspare_disk(adapter):
+    """
+    Find hotspare disk in adapter
+    """
+    command = "megasasctl |grep -E '^a%s.*hotspare'" %adapter
+    output = check_output(command, shell=True)
+    output = output.decode('utf-8')
+    hotspare = output.strip()
+
+    if len(hotspare.split('\n')) != 1:
+        logger.error('Hotspare disk number is not correct.' \
+                         + 'It can be only one hotspare in a ' \
+                         + 'adapter.')
+        return False
+
+    match = re.match(r'a(\d+)e(\d+)s(\d+)',hotspare)
+    if not match:
+        logger.error('Can not found enclosure and slot number of hotspare.')
+        return False
+
+    hotspare_E_S = "%s:%s" %(match.group(2), match.group(3))
+    logger.info('Found hotspare, Enclosure: %s, Slot: %s' 
+                %(match.group(2), match.group(3)))
+    return hotspare_E_S
+
+
+def check_rebuild_status(adapter, spare):
+    command = 'megacli -PDRbld -ShowProg -PhysDrv [%s] -A%s|grep -i rebuild' \
+        %(spare, adapter)
+    output = check_output(command, shell=True)
+    output = output.decode('utf-8')
+    logger.debug('%s' %output.strip())
+
+    match = re.search(r'Completed (\d+)% in (\d+) Minutes', output)
+    if not match:
+        return True
+    return False
+
+
+def all_rebuild_status(adapter_list, spare_dict):
+    for adapter in adapter_list:
+        if not check_rebuild_status(adapter, spare_dict[adapter]):
+            return False
+    return True
+
+
+def confirm_rebuild_status(adapter, spare):
+    enclosure, slot = spare.split(':')
+    command = ("megasasctl|grep -E '^a%se%ss%s'" %(adapter, enclosure, slot))
+    output = check_output(command, shell=True)
+    output = output.decode('utf-8')
+
+    match = re.search(r'online', output)
+    if not match:
+        logger.error('Hotspare status did not change to online. Adapter: %s, ' \
+                         +'Hotspare: [$s:$s]' %(adapter, enclosure, slot))
+        return False
+    return True
+
+
+def run(Adapter= None, Hsp=None, disk_list=None):
+    disk_dict = {}
+    spare_dict = {}
+    adapter_list = []
+    rebuild_status = {}
+
+    try:
+        if Adapter:
+            adapter_list.append(Adapter)
+        else:
+            adapter_list = get_adapter()
+    except Exception as e:
+        logger.error('%s' %e)
+        return 10
+
+    try:
+        if Adapter and disk_list:
+            disk_dict[Adapter] = disk_list
+        else:
+            for adapter in adapter_list:
+                disk_dict[adapter] = get_all_disk(adapter)
+    except Exception as e:
+        logger.error('%s' %e)
+        return 20
+
+    try:
+        if Adapter and Hsp:
+            spare_dict[Adapter] = Hsp
+        else:
+            for adapter in adapter_list:
+                spare_dict[adapter] = find_hotspare_disk(adapter)
+                if not spare_dict[adapter]:
+                    return 30
+    except Exception as e:
+        logger.error('%s' %e)
+        return 40
+
+    try:
+        for adapter in adapter_list:
+            # Remove hotspare disk from disk dict.
+            if spare_dict[adapter] in disk_dict[adapter]:
+                disk_dict[adapter].remove(spare_dict[adapter])
+            set_disk_offline(adapter, disk_dict[adapter])
+    except Exception as e:
+        logger.error('%s' %e)
+        return 50
+
+    # Wait for rebuild process
+    time.sleep(5)
+
+    try:
+        while(True):
+            if not all_rebuild_status(adapter_list, spare_dict):
+                # Check rebuild RAID status every 15 min.
+                time.sleep(900)
+                continue
+            break
+    except Exception as e:
+        logger.error('%s' %e)
+        return 60
+
+    check = 0
+    try:
+        for adapter in adapter_list:
+            if not confirm_rebuild_status(adapter, spare_dict[adapter]):
+                logger.error('Rebuild RAID failed, Adapter: %s, Hotspare: %s' 
+                             %(adapter, spare_dict[adapter]))
+                check = 1
+        if check != 0:
+            return 70
+    except Exception as e:
+        logger.error('%s' %e)
+        return 80
+
+    logger.info('All adapter rebuild RAID successful!')
+    return 0
+
+
+def main():
+    description_text = 'rebulit_raid\n\tTests LSI RAID card auto rebuild ' \
+        + 'function.\n\n\n\tWarning: This program will rebuild RAID ' \
+        + 'automaticity.\n\t\t Please make sure what you are doing!\n\n\n' \
+        + '\tRequirement: It can be only one hotspare in a adapter.'
+
+    parser = ArgumentParser(description=description_text,
+                            formatter_class=RawTextHelpFormatter)
+
+    parser.add_argument('-l', '--log', type=str,
+                      default='/tmp/rebulid_raid.log',
+                      help=('Specify the location and name of the log file.\n'
+                            '[Default: %(default)s]'))
+    parser.add_argument('-P', '--PhysDrv', type=str,
+                        help=('The physical drive enclosure and slot of RAID.'
+                              '\n[Example: --PhysDrv E0:S0,E1:S1,...] '))
+    parser.add_argument('-H', '--Hsp', type=str,
+                        help=('The hotspare\'s enclosure and slot of RAID.'
+                              '\n[Example: --Hsp E0:S0] '))
+    parser.add_argument('-A', '--Adapter', type=str,
+                        help=('The adapter number of RAID card.'
+                              '\n[Example: 0'))
+    args = parser.parse_args()
+
+    file_handler = logging.FileHandler(args.log)
+    file_handler.setFormatter(logFormatter)
+    console_handler = logging.StreamHandler()
+    console_handler.setFormatter(logFormatter)
+    console_handler.setLevel(logging.INFO)
+    logger.addHandler(file_handler)
+    logger.addHandler(console_handler)
+
+    disk_list = None
+    if args.PhysDrv:
+       disk_list = args.PhysDrv.split(',')
+
+    logger.info('Rebuild process beginning.')
+    return run(args.Adapter, args.Hsp, disk_list)
+
+if __name__ == '__main__':
+    sys.exit(main())

=== added file 'bin/system_stress'
--- bin/system_stress	1970-01-01 00:00:00 +0000
+++ bin/system_stress	2015-08-14 22:03:31 +0000
@@ -0,0 +1,71 @@
+#!/usr/bin/env python3
+"""
+Copyright (C) 2010-2013 by Cloud Computing Center for Mobile Applications
+Industrial Technology Research Institute
+
+It is NOT YET officially approved by OCP.
+
+system_stress
+ 1. Use google stressapptest tool to perform system stress test 
+    for hours requested.
+ 2. Criteria: pass without MCE error log.
+
+Authors
+  Nelson Chu <Nelson.Chu@xxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software 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.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+
+import os
+import sys
+from subprocess import check_output, STDOUT, CalledProcessError
+from argparse import ArgumentParser, RawTextHelpFormatter
+
+def run(seconds):
+    return_code = 0
+    command = "stressapptest -s {0} -v 3".format(seconds)
+    try:
+        print("Start stressapptest with commandline: %s" %(command))
+        output = check_output(command, stderr=STDOUT, shell=True)
+        output = output.decode("utf-8")
+        print(output)
+    except CalledProcessError as e:
+        print(e.output.decode("utf-8"))
+        return_code = 10
+
+    try:
+        mcelog_path = "/var/log/mcelog"
+        if os.stat(mcelog_path).st_size != 0:
+            mcelog = open(mcelog_path, "r")
+            print(mcelog.read())
+            mcelog.close()
+            return_code = 20
+    except Exception as e:
+        print(e)
+        print(e.output.decode("utf-8"))
+        return_code = 30
+
+    return return_code
+
+def main():
+    parser = ArgumentParser(formatter_class=RawTextHelpFormatter)
+
+    parser.add_argument('-s', '--seconds', type=int, required=True,
+                        help=("number of seconds to run."))
+
+    args = parser.parse_args()
+    return run(args.seconds)
+
+if __name__ == '__main__':
+    sys.exit(main())

=== modified file 'debian/changelog'
--- debian/changelog	2015-03-07 17:48:09 +0000
+++ debian/changelog	2015-08-14 22:03:31 +0000
@@ -1,8 +1,20 @@
-plainbox-provider-opencompute-certification (0.6~ocp2) trusty; urgency=medium
+plainbox-provider-opencompute-certification (0.7~ocp1) trusty; urgency=medium
+
+  * Major Update 
+    - Added whitelists and job files from Github
+    - Updated current scripts in bin/ to match github versions
+    - Added remaining new github scripts to bin/
+
+
+ -- Jeff Lane <jeff@xxxxxxxxxx>  Fri, 14 Aug 2015 16:32:20 -0400
+
+plainbox-provider-opencompute-certification (0.6~ocp3) trusty; urgency=medium
 
   * Modified whitelists and local.txt to better organize certification jobs.
   * Fixed missing recommends of iperf for p-p-o-c
   * Fixed job names for ocp-power-management.txt
+  * Changed the depends on checkbox-ng to 0.3-2 or greater (the Trusty Main
+    version)
 
  -- Jeff Lane <jeff@xxxxxxxxxx>  Fri, 06 Mar 2015 16:47:00 -0500
 

=== modified file 'debian/control'
--- debian/control	2015-03-07 17:48:09 +0000
+++ debian/control	2015-08-14 22:03:31 +0000
@@ -17,14 +17,14 @@
 
 Package: opencompute-certification
 Architecture: all
-Depends:    checkbox-ng (>=0.7~dev),
+Depends:    checkbox-ng (>=0.3-2),
             plainbox-provider-opencompute-certification
 Description: OCP Certification Launcher
  This package provides the Open Compute Certification Launcher
 
 Package: opencompute-ready
 Architecture: all
-Depends:    checkbox-ng (>=0.7~dev),
+Depends:    checkbox-ng (>=0.3-2),
             plainbox-provider-opencompute-certification
 Description: OCP Certification Launcher
  This package provides the Open Compute Ready Launcher

=== added file 'examples/bmc.cfg'
--- examples/bmc.cfg	1970-01-01 00:00:00 +0000
+++ examples/bmc.cfg	2015-08-14 22:03:31 +0000
@@ -0,0 +1,144 @@
+#########Before running ME/BMC test, please fill in related information in configuration file.#######
+#########Without these settings pre-setting in configuration file, you won't start tests smoothly########
+
+#Please fill in BMC/ME IP
+#for example, BMC IP address of SUT is 10.0.0.1
+
+[Targets]
+target1: 10.0.0.1
+
+
+#Please fill BMC/ME Account info 
+#for example, USER/PASSWORD:OCP/OCP
+
+[Account]
+USER: OCP
+PASSWORD: OCP
+
+
+#for example, SENSOR_NICKNAME:SENSOR_ID
+#if you don't have the sensor ID "CPU0 Temp"in sdr table that to retrieve CPU0 temperature,
+#please fill the sensor ID "P0 Therm Margin" and "CPU0 Tjmax"
+#in section([SensorsForCPUTemp]) to acquire CPU0 temperature.
+#And string 'CPU0 Temp' marked behind CPUx is still required
+
+[Sensors]
+Outlet: Outlet Temp
+Inlet: Inlet Temp
+PCH: PCH Temp
+CPUx: P0 Temp
+CPUy: P1 Temp
+P0VR: P0 VR Temp
+P1VR: P1 VR Temp
+P0DIMMVR0: P0 DIMM VR0 Temp
+P0DIMMVR1: P0 DIMM VR1 Temp
+P1DIMMVR0: P1 DIMM VR0 Temp
+P1DIMMVR1: P1 DIMM VR1 Temp
+HSC: HSC Temp
+DIMM0: P0 CH0DIMM0 Temp
+DIMM1: P0 CH0DIMM1 Temp
+DIMM2: P0 CH1DIMM0 Temp
+DIMM3: P0 CH1DIMM1 Temp
+DIMM4: P0 CH2DIMM0 Temp
+DIMM5: P0 CH2DIMM1 Temp
+DIMM6: P0 CH3DIMM0 Temp
+DIMM7: P0 CH3DIMM1 Temp
+DIMM8: P1 CH1DIMM0 Temp
+DIMM9: P1 CH0DIMM1 Temp
+DIMM10: P1 CH0DIMM0 Temp
+DIMM11: P1 CH1DIMM1 Temp
+DIMM12: P1 CH2DIMM0 Temp
+DIMM13: P1 CH2DIMM1 Temp
+DIMM14: P1 CH3DIMM0 Temp
+DIMM15: P1 CH3DIMM1 Temp
+HSC_Input_Power: HSC Input Power
+HSC_Output_Current: HSC Out Current
+HSC_Input_Voltage: HSC Input Volage
+P0_Package_Power: P0 Package Power
+P1_Package_Power: P1 Package Power
+P0_core_VR_Power: P0 core VR Power
+P0_core_VR_Current: P0 coreVRcurrent
+P0_core_VR_Voltage: P0 coreVRvoltage
+P1_core_VR_Power: P1 core VR Power
+P1_core_VR_Current: P1 coreVRcurrent
+P1_core_VR_Voltage: P1 coreVRvoltage
+P0_DIMM_VR0_Power: P0 DIMM VR0Power
+P0_DIMM_VR0_Current: P0 DIMM VR0 curr
+P0_DIMM_VR0_Voltage: P0 DIMM VR0 Volt
+P0_DIMM_VR1_Power: P0 DIMM VR1Power
+P0_DIMM_VR1_Current: P0 DIMM VR1 curr
+P0_DIMM_VR1_Voltage: P0 DIMM VR1 Volt
+P1_DIMM_VR0_Power: P1 DIMM VR0Power
+P1_DIMM_VR0_Current: P1 DIMM VR0 curr
+P1_DIMM_VR0_Voltage: P1 DIMM VR0 Volt
+P1_DIMM_VR1_Power: P1 DIMM VR1Power
+P1_DIMM_VR1_Current: P1 DIMM VR1 curr
+P1_DIMM_VR1_Voltage: P1 DIMM VR1 Volt
+SYS_FAN0: SYS Fan 0
+SYS_FAN1: SYS Fan 1
+P0_PROCHOT: P0 Tjmax
+P1_PROCHOT: P1 Tjmax
+Airflow: Airflow
+P3V3: P3V3
+P5V: P5V
+P12V: P12V
+P1V05_STBY: P1V05_STBY
+P1V8_AUX: P1V8_AUX
+P3V3_AUX: P3V3_AUX
+P5V_AUX: P5V_AUX
+P3V_BAT: P3V_BAT
+
+[SensorsForCPUTemp]
+Px Therm Margin: P0 Therm Margin
+Py Therm Margin: P1 Therm Margin
+CPUx Tjmax: CPU0 Tjmax
+CPUy Tjmax: CPU1 Tjmax
+
+
+#Refers to test case TC-002-0008-001-Temp_Sampling_Increment
+#rule of settings are the same as [Sensors]
+
+[SensorsForSampling]
+Inlet: Inlet Temp
+CPUx: P0 Temp
+CPUy: P1 Temp
+
+#Don't modify the settings in [Admin Level], [Operator Level] and [User Level]
+#Please create new user account following these settings using ipmitool/dcmitool manually
+#please create a new account on SUT using ipmitool/dcmitool manually.
+#And the account must follow settings below
+#for example, accordding to [Admin Level] section,
+#user name: ccma_admin, user password: ccma_admin, network priviledge: 4, user ID: 3  
+#the rule of the other two sectios are the same
+
+#Authentication Level: Administrator
+[Admin Level]
+ADMIN_NAME: ccma_admin
+ADMIN_PASSWD: ccma_admin
+priv_level: 4
+user_id: 3
+channel_num: 1
+
+#Authentication Level: Operator
+[Operator Level]
+OPER_NAME: ccma_oper
+OPER_PASSWD: ccma_oper
+priv_level: 3
+user_id: 4
+channel_num: 1
+
+#Authentication Level: User
+[User Level]
+USER_NAME: ccma_user
+USER_PASSWD: ccma_user
+priv_level: 2
+user_id: 5
+channel_num: 1
+
+
+#Don't modify the settings in [Add User Test]
+#Don't create user:ccma_test on SUT manually, the test script will check this automatically
+[Add User Test]
+NEW_USER_NAME: ccma_test
+NEW_USER_ID: 6
+

=== modified file 'examples/me.cfg'
--- examples/me.cfg	2015-02-23 22:51:04 +0000
+++ examples/me.cfg	2015-08-14 22:03:31 +0000
@@ -1,15 +1,88 @@
-#Please config ME IP of server that you want to test
-#for example, if ME ip of your server is 10.0.0.1, 
-#then you must replace x.x.x.x to 10.0.0.1 in [Targets]
+#########Before running ME/BMC test, please fill in related information in configuration file.#######
+#########Without these settings pre-setting in configuration file, you won't start tests smoothly########
+
+#Please fill in BMC/ME IP
+#for example, BMC IP address of SUT is 10.0.0.1
 
 [Targets]
-Target1: x.x.x.x
-
-#please config ME account(USER/PASSWORD) of server that you want to test
-#for example, if ME account of your server is ADMIN/ADMIN, 
-#then you must replace OCP/OCP to ADMIN/ADMIN in [Account]
+target1: 10.0.0.1
+
+
+#Please fill BMC/ME Account info 
+#for example, USER/PASSWORD:OCP/OCP
 
 [Account]
 USER: OCP
 PASSWORD: OCP
 
+
+#for example, SENSOR_NICKNAME:SENSOR_ID
+#if you don't have the sensor ID "CPU0 Temp"in sdr table that to retrieve CPU0 temperature,
+#please fill the sensor ID "P0 Therm Margin" and "CPU0 Tjmax"
+#in section([SensorsForCPUTemp]) to acquire CPU0 temperature.
+#And string 'CPU0 Temp' marked behind CPUx is still required
+
+[Sensors]
+Outlet: Outlet Temp
+Inlet: Inlet Temp
+PCH: PCH Temp
+Px DIMM: P0 DIMM Temp
+Py DIMM: P1 DIMM Temp
+CPUx: CPU0 Temp
+CPUy: CPU1 Temp
+
+[SensorsForCPUTemp]
+Px Therm Margin: P0 Therm Margin
+Py Therm Margin: P1 Therm Margin
+CPUx Tjmax: CPU0 Tjmax
+CPUy Tjmax: CPU1 Tjmax
+
+
+#Refers to test case TC-002-0008-001-Temp_Sampling_Increment
+#rule of settings are the same as [Sensors]
+
+[SensorsForSampling]
+Inlet: Inlet Temp
+CPUx: CPU0 Temp
+CPUy: CPU1 Temp
+
+
+#Don't modify the settings in [Admin Level], [Operator Level] and [User Level]
+#Please create new user account following these settings using ipmitool/dcmitool manually
+#please create a new account on SUT using ipmitool/dcmitool manually.
+#And the account must follow settings below
+#for example, accordding to [Admin Level] section,
+#user name: ccma_admin, user password: ccma_admin, network priviledge: 4, user ID: 3  
+#the rule of the other two sectios are the same
+
+#Authentication Level: Administrator
+[Admin Level]
+ADMIN_NAME: ccma_admin
+ADMIN_PASSWD: ccma_admin
+priv_level: 4
+user_id: 3
+channel_num: 1
+
+#Authentication Level: Operator
+[Operator Level]
+OPER_NAME: ccma_oper
+OPER_PASSWD: ccma_oper
+priv_level: 3
+user_id: 4
+channel_num: 1
+
+#Authentication Level: User
+[User Level]
+USER_NAME: ccma_user
+USER_PASSWD: ccma_user
+priv_level: 2
+user_id: 5
+channel_num: 1
+
+
+#Don't modify the settings in [Add User Test]
+#Don't create user:ccma_test on SUT manually, the test script will check this automatically
+[Add User Test]
+NEW_USER_NAME: ccma_test
+NEW_USER_ID: 6
+

=== added file 'jobs/TC-001-0001-CPU_Memory.txt.in'
--- jobs/TC-001-0001-CPU_Memory.txt.in	1970-01-01 00:00:00 +0000
+++ jobs/TC-001-0001-CPU_Memory.txt.in	2015-08-14 22:03:31 +0000
@@ -0,0 +1,32 @@
+plugin: shell
+name: TC-001-0001-001/CPU_Information
+requires: package.name == 'lshw'
+user: root
+command: cpu_info -p Xeon -f E5
+description:
+ 1. Use lshw command to gather CPU information.
+ 2. The program will output CPU model and L1, L2, L3 cache size.
+ 3. Criteria: CPU model must be Intel Xeon processor E5-2600 product family and L3 cache size must be up to 20MB.
+
+plugin: shell
+name: TC-001-0001-002/Processor_Topology
+command: processor_topology
+description:
+ 1. This test checks CPU topology for accuracy.
+ 2. Use lscpu command to gather CPU information.
+ 3. The program will output the total number of CPUs, the number of threads per core, the number of cores per socket, and the number of sockets.
+ 4. Criteria: It should be 8-12 cores per CPU and 2 threads per core.
+
+plugin: shell
+name: TC-001-0001-003/Memory_Information
+requires: package.name == 'lshw'
+user: root
+command: ocp_memory_info
+description:
+ 1. Use lshw command to gather memory information.
+ 2. Testing prerequisites:
+    4 channels DDR3 registered memory interface on each processor 0 and processor 1.
+    2 DDR3 slots per channel per processor. (total of 16 DIMMs on the motherboard)
+ 3. The program will output memory module, vendor, size and slot.
+ 4. Criteria: Total of 16 DIMMs on the motherboard.
+

=== removed file 'jobs/TC-001-0001-CPU_Memory.txt.in'
--- jobs/TC-001-0001-CPU_Memory.txt.in	2015-03-06 21:47:21 +0000
+++ jobs/TC-001-0001-CPU_Memory.txt.in	1970-01-01 00:00:00 +0000
@@ -1,32 +0,0 @@
-plugin: shell
-name: TC-001-0001-001/CPU_Information
-requires: package.name == 'lshw'
-user: root
-command: cpu_info -p Xeon -f E5
-description:
- 1. Use lshw command to gather CPU information.
- 2. The program will output CPU model and L1, L2, L3 cache size.
- 3. Criteria: CPU model must be Intel Xeon processor E5-2600 product family and L3 cache size must be up to 20MB.
-
-plugin: shell
-name: TC-001-0001-002/Processor_Topology
-command: processor_topology
-description:
- 1. This test checks CPU topology for accuracy.
- 2. Use lscpu command to gather CPU information.
- 3. The program will output the total number of CPUs, the number of threads per core, the number of cores per socket, and the number of sockets.
- 4. Criteria: It should be 8-12 cores per CPU and 2 threads per core.
-
-plugin: shell
-name: TC-001-0001-003/Memory_Information
-requires: package.name == 'lshw'
-user: root
-command: memory_info
-description:
- 1. Use lshw command to gather memory information.
- 2. Testing prerequisites:
-    4 channels DDR3 registered memory interface on each processor 0 and processor 1.
-    2 DDR3 slots per channel per processor. (total of 16 DIMMs on the motherboard)
- 3. The program will output memory module, vendor, size and slot.
- 4. Criteria: Total of 16 DIMMs on the motherboard.
-

=== added file 'jobs/TC-001-0002-Platform_Controller_Hub.txt.in'
--- jobs/TC-001-0002-Platform_Controller_Hub.txt.in	1970-01-01 00:00:00 +0000
+++ jobs/TC-001-0002-Platform_Controller_Hub.txt.in	2015-08-14 22:03:31 +0000
@@ -0,0 +1,14 @@
+plugin: shell
+name: TC-001-0002-001/SATA_port
+command: check_sata_port
+description:
+ 1. Use dmesg command to gather SATA information.
+ 2. Criteria: SATA port speed up to 6.0Gps.
+
+plugin: shell
+name: TC-001-0002-002/USB_2.0
+command: check_usb_port
+description:
+ 1. Use dmesg command to gather USB information.
+ 2. Criteria: USB version must be 2.0.
+

=== removed file 'jobs/TC-001-0002-Platform_Controller_Hub.txt.in'
--- jobs/TC-001-0002-Platform_Controller_Hub.txt.in	2015-03-06 21:47:21 +0000
+++ jobs/TC-001-0002-Platform_Controller_Hub.txt.in	1970-01-01 00:00:00 +0000
@@ -1,14 +0,0 @@
-plugin: shell
-name: TC-001-0002-001/SATA_port
-command: check_sata_port
-description:
- 1. Use dmesg command to gather SATA information.
- 2. Criteria: SATA port speed up to 6.0Gps.
-
-plugin: shell
-name: TC-001-0002-002/USB_2.0
-command: check_usb_port
-description:
- 1. Use dmesg command to gather USB information.
- 2. Criteria: USB version must be 2.0.
-

=== added file 'jobs/TC-001-0006-Hardware_Monitoring.txt'
--- jobs/TC-001-0006-Hardware_Monitoring.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-001-0006-Hardware_Monitoring.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,22 @@
+plugin: shell
+name: TC-001-0006-001/Thermal_Monitoring
+requires: package.name == 'dcmitool'
+user: root
+command: dcmi_thermal_ib 
+_description:
+ 1. Retrieve CPU, DIMM, chipset, inlet and outlet temperatures via DCMI in-band access using dcmitool.
+ 2. The motherboard has five thermal sensors: 
+    Two for CPU0 and CPU1 temperatures, 
+    Two for CPU0 DIMM group and CPU1 DIMM group temperatures, 
+    One for PCH temperature, one for Inlet temperature, 
+    One for outlet temperature.
+ 3. Criteria: Must retrieve temperatures from all abovementioned thermal sensors via DCMI in-band access.
+
+plugin: shell
+name: TC-001-0006-002/CPU_Thermal_Throttling_Issue
+user: root
+command: echo "Refers to TC-002-0011-002 System Log Hardware Error"
+_description: 
+ 1. Use dcmitool to retrieve system event log.
+ 2. Verify CPU Thermal Throttling issues by retrieving system event log via dcmitool.
+ 3. Criteria: The CPU throttling log shall not occur during the testing period.

=== added file 'jobs/TC-001-0007-In_band_Platform_Controller_Hub_Management_Engine.txt'
--- jobs/TC-001-0007-In_band_Platform_Controller_Hub_Management_Engine.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-001-0007-In_band_Platform_Controller_Hub_Management_Engine.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,15 @@
+plugin: shell
+name: TC-001-0007-001/In_band_Power_and_Thermal_Monitoring
+requires: package.name == 'dcmitool'
+user: root
+command: echo "Refers to TC-001-0006-001 Thermal Monitoring."
+_description: 
+ 1. Retrieve CPU, DIMM, chipset, inlet and outlet temperatures via DCMI in-band access using dcmitool.
+ 2. The motherboard has five thermal sensors:
+    Two for CPU0 and CPU1 temperatures,
+    Two for CPU0 DIMM group and CPU1 DIMM group temperatures,
+    One for PCH temperature, one for Inlet temperature,
+    One for outlet temperature.
+ 3. Criteria: Must retrieve temperatures from all abovementioned thermal sensors via DCMI in-band access.
+
+

=== added file 'jobs/TC-001-0008-Out_of_band_Platform_Controller_Hub_Management_Engine.txt'
--- jobs/TC-001-0008-Out_of_band_Platform_Controller_Hub_Management_Engine.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-001-0008-Out_of_band_Platform_Controller_Hub_Management_Engine.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,16 @@
+plugin: shell
+name: TC-001-0008-001/Out_of_band_Power_and_Thermal_Monitoring
+requires: package.name == 'dcmitool'
+user: root
+command: dcmi_thermal_oob
+_description: 
+ 1. Retrieving CPU, DIMM, chipset, inlet, outlet temperature via DCMI out-of-band access using dcmitool.
+ 2. The motherboard has five thermal sensors: Two for CPU0 and CPU1 temperatures,
+    Two for CPU0 DIMM group and CPU1 DIMM group temperatures,
+    One for PCH temperature,
+    One for Inlet temperature,
+    One for outlet temperature.
+ 3. Criteria: Must retrieve temperatures from all abovementioned thermal sensors via DCMI out-of-band access.
+
+
+

=== added file 'jobs/TC-002-0002-Management_Node_Identifier.txt'
--- jobs/TC-002-0002-Management_Node_Identifier.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-002-0002-Management_Node_Identifier.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,6 @@
+plugin: shell
+name: TC-002-0002-001/Management_Node_Identifier
+requires: package.name == 'dcmitool'
+user: root
+command: echo "Refer to TC-002-0010-001 Inventory Information." 
+_description: Retrieve GUID using dcmitool

=== added file 'jobs/TC-002-0003-Rights_and_Credentials.txt'
--- jobs/TC-002-0003-Rights_and_Credentials.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-002-0003-Rights_and_Credentials.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,14 @@
+#plugin: shell
+#name: TC-002-0003-001/ME_User_Account
+#requires: package.name == 'dcmitool'
+#user: root
+#command: dcmi_cred_default
+#_description: Verify whether the default account is accessible through OOB
+
+#plugin: shell
+#name: TC-002-0003-002/ME_User_Password
+#requires: package.name == 'dcmitool'
+#user: root
+#command: dcmi_cred_change
+#_description: Use dcmitool to change ME user password
+

=== added file 'jobs/TC-002-0006-Remotely_Power_Control.txt'
--- jobs/TC-002-0006-Remotely_Power_Control.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-002-0006-Remotely_Power_Control.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,13 @@
+plugin: shell
+name: TC-002-0006-001/Remotely_Power_Off_and_On
+requires: package.name == 'dcmitool'
+user: root
+command: dcmi_power_off_on 
+_description: Use dcmitool out-of-band access to turn on/off the SUT
+
+plugin: shell
+name: TC-002-0006-002/Remotely_Power_Reset
+requires: package.name == 'dcmitool'
+user: root
+command: dcmi_power_reset
+_description: Complete 20 power reset on SUT successfully using dcmitool out-of-band access

=== added file 'jobs/TC-002-0007-Power_Draw.txt'
--- jobs/TC-002-0007-Power_Draw.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-002-0007-Power_Draw.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,9 @@
+plugin: shell
+name: TC-002-0007-001/Power_Draw
+requires: package.name == 'ipmitool'
+user: root
+command: ipmi_power_draw
+_description:
+ 1. Gather power draw data via ipmitool
+ 2. The data contains "Minimum during sampling period", "Maximum during sampling period", "Average power reading over sample period", "IPMI timestamp", "Sampling period", "Power reading state".
+ 3. Criteria: The return value of each item cannot be null

=== added file 'jobs/TC-002-0008-Temperature.txt'
--- jobs/TC-002-0008-Temperature.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-002-0008-Temperature.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,8 @@
+plugin: shell
+name: TC-002-0008-001/Temp_Sampling_Increment
+requires: package.name == 'dcmitool'
+user: root
+command: dcmi_sampling
+_description: 
+ 1. Retrieve CPU and intake temperature 30 times at 3 second intervals using dcmitool
+ 2. If failed to retrieve temperature at any time within 30 times, the test is considered failed

=== added file 'jobs/TC-002-0009-User_Levels.txt'
--- jobs/TC-002-0009-User_Levels.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-002-0009-User_Levels.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,26 @@
+plugin: shell
+name: TC-002-0009-001/BMC_Account_Privilege_Verify-User
+requires: package.name == 'dcmitool'
+user: root
+command: dcmi_priv_user
+_description: 
+ 1. Use dcmitool out-of-band to read power status, to perform power reset and add a new user account
+ 2. Criteria: power status reading must be successful and must fail at power reset and adding a new user account
+
+plugin: shell
+name: TC-002-0009-002/BMC_Account_Privilege_Verify-Operator
+requires: package.name == 'dcmitool'
+user: root
+command: dcmi_priv_oper 
+_description:
+ 1. Use dcmitool out-of-band to read power status, to perform power reset and add a new user account
+ 2. Criteria: power status reading and power reset must be successful and must fail at adding a new user account 
+
+plugin: shell
+name: TC-002-0009-003/BMC_Account_Privilege_Verify-Administrator
+requires: package.name == 'dcmitool'
+user: root
+command: dcmi_priv_admin
+_description:
+ 1. Use dcmitool out-of-band to read power status, to perform power reset and add a new user account
+ 2. Criteria: Reading power status, performing power reset and adding a user account must all be successful

=== added file 'jobs/TC-002-0010-Inventory.txt'
--- jobs/TC-002-0010-Inventory.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-002-0010-Inventory.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,19 @@
+plugin: shell
+name: TC-002-0010-001/Inventory_Infomation
+requires: package.name == 'dcmitool'
+user: root
+command: dcmi_inventory
+_description: 
+ 1. Use dcmitool to collect inventory information including Asset Tag, Device ID, System GUI, Firmware/Software Information, Management Controller ID
+ 2. Criteria: All information mentioned above must not should not be null
+
+plugin: shell
+name: TC-002-0010-002/FRU
+requires: package.name == 'ipmitool'
+user: root
+command: ipmi_fru
+_description: 
+ 1. Use ipmitool to retrieve FRU data.
+ 2. The data contains product manufacture, product part number, product serial number, motherboard serial number.
+ 3. Criteria: Above All data mentioned above must notshould not be null
+

=== added file 'jobs/TC-002-0011-System_Log.txt.in'
--- jobs/TC-002-0011-System_Log.txt.in	1970-01-01 00:00:00 +0000
+++ jobs/TC-002-0011-System_Log.txt.in	2015-08-14 22:03:31 +0000
@@ -0,0 +1,10 @@
+plugin: shell
+name: TC-002-0011-001/System_Log_Entries
+requires: package.name == 'ipmitool'
+user: root
+command: ipmi_sel_entries
+description: 
+  1. Use ipmitool to collect event log information
+  2. Calculate entries number of system event log
+  3. Criteria: the A log must be capable of saving at least 256 entries
+

=== removed file 'jobs/TC-002-0011-System_Log.txt.in'
--- jobs/TC-002-0011-System_Log.txt.in	2015-03-06 21:47:21 +0000
+++ jobs/TC-002-0011-System_Log.txt.in	1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
-plugin: shell
-name: TC-002-0011-001/System_Log_Entries
-requires: package.name == 'ipmitool'
-user: root
-command: ipmi_sel_entries
-description: 
-  1. Use ipmitool to collect event log information
-  2. Calculate entries number of system event log
-  3. Criteria: the A log must be capable of saving at least 256 entries
-

=== added file 'jobs/TC-003-0001-Hardware_Information.txt.in'
--- jobs/TC-003-0001-Hardware_Information.txt.in	1970-01-01 00:00:00 +0000
+++ jobs/TC-003-0001-Hardware_Information.txt.in	2015-08-14 22:03:31 +0000
@@ -0,0 +1,57 @@
+plugin: shell
+name: TC-003-0001-001/CPU_Information
+command: echo "Refers to TC-001-0001-001/CPU_Information"
+description:
+ Refers to TC-001-0001-001/CPU_Information
+
+plugin: shell
+name: TC-003-0001-002/Memory_Information
+command: echo "Refers to TC-001-0001-003/Memory_Information"
+description:
+ Refers to TC-001-0001-003/Memory_Information
+
+plugin: shell
+name: TC-003-0001-003/Disk_Information
+requires: package.name == 'lshw'
+user: root
+command: disk_info
+description:
+ 1. Use lshw command to gather disk information. 
+ 2. The program will output disk type, vendor, product, capacity.
+ 3. Criteria: must be able to retrieve disk information.
+
+plugin: shell
+name: TC-003-0001-004/BIOS_Information
+requires: package.name == 'lshw'
+user: root
+command: bios_info
+description:
+ 1. Use lshw command to gather BIOS information. 
+ 2. The program will output BIOS vendor, version and release date.
+ 3. Criteria: must be able to retrieve BIOS information.
+
+plugin: shell
+name: TC-003-0001-005/ME_Information
+command: echo "Refers to TC-002-0010-001/Inventory_Infomation"
+description:
+ Refers to TC-002-0010-001/Inventory_Infomation
+
+plugin: shell
+name: TC-003-0001-006/NIC_Information
+command: network_device_info
+description:
+ 1. Use udevadm command to gather NIC information.
+ 2. The program will output Interface, product, vendor, driver, device path.
+ 3. Criteria: must be able to retrieve NIC information.
+
+plugin: shell
+name: TC-003-0001-007/RAID_Card_Information
+requires:
+ package.name == 'megacli'
+ package.name == 'megactl'
+user: root
+command: raid_info
+description:
+ 1. Use megasasctl command to gather LSI RAID card information.
+ 2. The program will output adapter, product name, memory, BBU, serial no.
+ 3. Criteria: All information listed in item 2 must have value to show that RAID card exists.

=== removed file 'jobs/TC-003-0001-Hardware_Information.txt.in'
--- jobs/TC-003-0001-Hardware_Information.txt.in	2015-03-06 21:47:21 +0000
+++ jobs/TC-003-0001-Hardware_Information.txt.in	1970-01-01 00:00:00 +0000
@@ -1,58 +0,0 @@
-plugin: shell
-name: TC-003-0001-001/CPU_Information
-command: echo "Refers to TC-001-0001-001/CPU_Information"
-description:
- Refers to TC-001-0001-001/CPU_Information
-
-plugin: shell
-name: TC-003-0001-002/Memory_Information
-command: echo "Refers to TC-001-0001-003/Memory_Information"
-description:
- Refers to TC-001-0001-003/Memory_Information
-
-plugin: shell
-name: TC-003-0001-003/Disk_Information
-requires: package.name == 'lshw'
-user: root
-command: disk_info
-description:
- 1. Use lshw command to gather disk information. 
- 2. The program will output disk type, vendor, product, capacity.
- 3. Criteria: must be able to retrieve disk information.
-
-plugin: shell
-name: TC-003-0001-004/BIOS_Information
-requires: package.name == 'lshw'
-user: root
-command: bios_info
-description:
- 1. Use lshw command to gather BIOS information. 
- 2. The program will output BIOS vendor, version and release date.
- 3. Criteria: must be able to retrieve BIOS information.
-
-plugin: shell
-name: TC-003-0001-005/ME_Information
-command: echo "Refers to TC-002-0010-001/Inventory_Infomation"
-description:
- Refers to TC-002-0010-001/Inventory_Infomation
-
-plugin: shell
-name: TC-003-0001-006/NIC_Information
-command: network_device_info
-description:
- 1. Use udevadm command to gather NIC information.
- 2. The program will output Interface, product, vendor, driver, device path.
- 3. Criteria: must be able to retrieve NIC information.
-
-plugin: shell
-name: TC-003-0001-007/RAID_Card_Information
-requires:
- package.name == 'megacli'
- package.name == 'megactl'
-user: root
-command: raid_info
-description:
- 1. Use megasasctl command to gather LSI RAID card information.
- 2. The program will output adapter, product name, memory, BBU, serial no.
- 3. Criteria: All information listed in item 2 must have value to show that RAID card exists.
-

=== added file 'jobs/TC-003-0003-Network_Performance.txt.in'
--- jobs/TC-003-0003-Network_Performance.txt.in	1970-01-01 00:00:00 +0000
+++ jobs/TC-003-0003-Network_Performance.txt.in	2015-08-14 22:03:31 +0000
@@ -0,0 +1,23 @@
+plugin: local
+_summary: Automated test to walk multiple network cards and test each one in sequence.
+id: TC-003-0003-001/Network_performance
+requires: 
+ device.category == 'NETWORK'
+_description: Automated test to walk multiple network cards and test each one
+ in sequence.
+command:
+ cat <<'EOF' | run_templates -s 'udev_resource | filter_templates -w "category=NETWORK" | awk "/path: / { print \$2 }" | xargs -n 1 sh -c "for i in \`ls /sys\$0/net 2>/dev/null\`; do echo \$0 \$i; done"'
+ plugin: shell
+ id: TC-003-0003-001/Network_performance_$2
+ requires:
+  package.name == 'ethtool'
+  package.name == 'nmap'
+  device.path == "$1"
+ user: root
+ environ: TEST_TARGET_FTP TEST_TARGET_IPERF TEST_USER TEST_PASS
+ command: network test -i $2 -t iperf --fail-threshold 80
+ estimated_duration: 330.0
+ description:
+  Testing for NIC $2
+ EOF
+

=== removed file 'jobs/TC-003-0003-Network_Performance.txt.in'
--- jobs/TC-003-0003-Network_Performance.txt.in	2015-03-06 21:47:21 +0000
+++ jobs/TC-003-0003-Network_Performance.txt.in	1970-01-01 00:00:00 +0000
@@ -1,23 +0,0 @@
-plugin: local
-_summary: Automated test to walk multiple network cards and test each one in sequence.
-id: TC-003-0003-001/Network_performance
-requires: 
- device.category == 'NETWORK'
-_description: Automated test to walk multiple network cards and test each one
- in sequence.
-command:
- cat <<'EOF' | run_templates -s 'udev_resource | filter_templates -w "category=NETWORK" | awk "/path: / { print \$2 }" | xargs -n 1 sh -c "for i in \`ls /sys\$0/net 2>/dev/null\`; do echo \$0 \$i; done"'
- plugin: shell
- id: TC-003-0003-001/Network_performance_$2
- requires:
-  package.name == 'ethtool'
-  package.name == 'nmap'
-  device.path == "$1"
- user: root
- environ: TEST_TARGET_FTP TEST_TARGET_IPERF TEST_USER TEST_PASS
- command: network test -i $2 -t iperf --fail-threshold 80
- estimated_duration: 330.0
- description:
-  Testing for NIC $2
- EOF
-

=== added file 'jobs/TC-003-0004-Disk_Healthiness.txt'
--- jobs/TC-003-0004-Disk_Healthiness.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-003-0004-Disk_Healthiness.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,40 @@
+plugin: local
+name: TC-003-0004-001/Disk_Health
+requires:
+ package.name == 'smartmontools'
+ device.category == 'DISK'
+command:
+ cat <<'EOF' | run_templates -t -s 'udev_resource | filter_templates -w "category=DISK"'
+ plugin: shell
+ name: TC-003-0004-001/Disk_Health_`ls /sys$path/block`
+ requires:
+  device.path == "$path"
+  block_device.`ls /sys$path/block`_state != 'removable'
+ description:
+  1. Use smartmontools to monitor disk health.
+  2. SMART threshold, grown defect list (glist or reallocated sectors) <= 100 for 4TB, glist <=50 for 2TB for all vendors.
+  3. SMART HDD temp <= 60 degrees centigrade.
+  4. Criteria: all threshold must not exceed the criteria listed in item 2 an 3.
+ user: root
+ command: disk_health -d /dev/`ls /sys$path/block`
+ EOF
+
+plugin: local
+name: TC-003-0004-002/Bad_block_test
+requires:
+ package.name == 'badblocks'
+ device.category == 'DISK'
+command:
+ cat <<'EOF' | run_templates -t -s 'udev_resource | filter_templates -w "category=DISK"'
+ plugin: shell
+ name: TC-003-0004-002/Bad_block_test_`ls /sys$path/block`
+ requires:
+  device.path == "$path"
+  block_device.`ls /sys$path/block`_state != 'removable'
+ description:
+  1. Use badblocks command to perform a full disk bad block scan with 0xff pattern.
+  2. The duration of the test is under 24 hours.
+  3. Criteria: pass if no hard disk error.
+ user: root
+ command: bad_block_test -t 0xff -d /dev/`ls /sys$path/block`
+ EOF

=== added file 'jobs/TC-003-0005-System_Stress.txt'
--- jobs/TC-003-0005-System_Stress.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-003-0005-System_Stress.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,7 @@
+plugin: shell
+name: TC-003-0005-001/System_stress
+user: root
+command: system_stress -s 28800
+description:
+ 1. Use google stressapptest tool to perform system stress test for 8 hours.
+ 2. Criteria: pass without MCE error log.

=== added file 'jobs/TC-004-0001-JBOD_Testing.txt'
--- jobs/TC-004-0001-JBOD_Testing.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-004-0001-JBOD_Testing.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,74 @@
+plugin: shell
+name: TC-004-0001-001/RAID_card_information
+command: echo "refer to TC-003-0001-007"
+description:
+ refers to TC-003-0001-007
+
+plugin: shell
+name: TC-004-0002-001/Get_all_HDD
+requires:
+ package.name == 'megacli'
+ package.name == 'megactl'
+user: root
+command: raid_hdd_info
+description:
+ 1. Use megasasctl command to get all JBOD HDD information.
+ 2. Show total HDD number in JBOD and check disks readiness.
+ 3. Criteria: ensure all JBOD disks information and status are correct.
+
+plugin: shell
+name: TC-004-0003-001/Build_raid_6
+requires:
+ package.name == 'megacli'
+ package.name == 'megactl'
+user: root
+depends: TC-004-0002-001/Get_all_HDD
+command: create_raid -t 6
+description:
+ 1. Use megacli command to build RAID 6 on JBOD from LSI RAID card. 
+ 2. Criteria: pass if the return code is zero.
+
+plugin: shell
+name: TC-004-0003-002/Build_raid_0
+requires:
+ package.name == 'megacli'
+ package.name == 'megactl'
+user: root
+depends: TC-004-0002-001/Get_all_HDD
+command: create_raid -t 0
+description:
+ 1. Use megacli command to build RAID 0 on JBOD from LSI RAID card. 
+ 2. Criteria: pass if the return code is zero.
+
+plugin: shell
+name: TC-004-0004-001/RAID_6_availability_test
+user: root
+depends: TC-004-0003-002/Build_raid_6
+command: raid_availability_test
+description:
+ 1. Create one partition and format on RAID 6 to test disk I/O.
+ 2. Test RAID Read/Write file correctly on JBOD.
+ 3. Criteria: Create/Read/Write file without error.
+
+plugin: shell
+name: TC-004-0004-002/RAID_0_availability_test
+user: root
+depends: TC-004-0003-002/Build_raid_0
+command: raid_availability_test
+description:
+ 1. Create one partition and format on RAID 0 to test disk I/O.
+ 2. Test RAID Read/Write file correctly on JBOD.
+ 3. Criteria: Create/Read/Write file without error.
+
+plugin: shell
+name: TC-004-0005-001/Rebuild_Raid
+requires:
+ package.name == 'megacli'
+ package.name == 'megactl'
+depends: TC-004-0004-001/Read-Write_file
+environ: CHECKBOX_DATA
+user: root
+command: rebulid_raid -l $CHECKBOX_DATA/rebulid_raid.log
+description:
+ 1. Test RAID 6 auto rebuild feature in hot spare mode.
+ 2. Criteria: rebuild RAID 6 successfully.

=== added file 'jobs/TC-005-0001-CPU_Memory.txt'
--- jobs/TC-005-0001-CPU_Memory.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-005-0001-CPU_Memory.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,35 @@
+plugin: shell
+name: TC-005-0001-001/CPU_Information
+requires: package.name == 'lshw'
+user: root
+command: cpu_info_leopard -p Xeon -f E5
+description:
+ This test case is used for test leopard.
+ 1. Use dmidecode command to gather CPU information.
+ 2. The program will output CPU model and L1, L2, L3 cache size.
+ 3. Criteria: CPU model must be Intel Xeon processor E5-2600 product family.
+
+
+plugin: shell
+name: TC-005-0001-002/Processor_Topology
+command: processor_topology
+description:
+ This test case is used for test leopard will check CPU topology for accuracy.
+ 1. Use lscpu command to gather CPU information.
+ 2. The program will output the total number of CPUs, the number of threads per core, the number of cores per socket, and the number of sockets.
+ 3. Criteria: It should be 8-12 cores per CPU and 2 threads per core.
+
+
+plugin: shell
+name: TC-005-0001-003/Memory_Information
+requires: package.name == 'lshw'
+user: root
+command: ocp_memory_info
+description:
+ This test case is used for test leopard.
+ 1. Use lshw command to gather memory information.
+ 2. Testing prerequisites:
+    4 channels DDR3 registered memory interface on each processor 0 and processor 1.
+    2 DDR3 slots per channel per processor. (total of 16 DIMMs on the motherboard)
+ 3. The program will output memory module, vendor, size and slot.
+ 4. Criteria: Total of 16 DIMMs on the motherboard.

=== added file 'jobs/TC-005-0002-Platform_Controller_Hub.txt'
--- jobs/TC-005-0002-Platform_Controller_Hub.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-005-0002-Platform_Controller_Hub.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,15 @@
+plugin: shell
+name: TC-005-0002-001/SATA_Port
+command: check_sata_port_leopard
+description:
+ This test case is used for test leopard.
+ 1. Retrieve dmesg log to gather SATA information.
+ 2. Criteria: SATA port speed up to 6.0Gps.
+
+plugin: shell
+name: TC-005-0002-002/USB_Port
+command: check_usb_port_leopard
+description:
+ This test case is used for test leopard.
+ 1. Retrieve dmesg log to gather USB information.
+ 2. Criteria: USB version must be 2.0 or higher.

=== added file 'jobs/TC-005-0006-Sensors_Monitoring.txt'
--- jobs/TC-005-0006-Sensors_Monitoring.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-005-0006-Sensors_Monitoring.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,55 @@
+plugin: shell
+name: TC-005-0006-001/In-band_Sensors_Monitoring
+requires: 
+ package.name == 'dcmitool'
+ package.name == 'ipmitool'
+user: root
+command: 
+ lsmod |grep -q "ipmi_si"
+ result_ipmi=`echo $?` 
+ lsmod |grep -q "dcmi" 
+ result_dcmi=`echo $?` 
+ code=-1
+ output='' 
+ if [ $result_ipmi -eq 1 ] && [ $result_dcmi -eq 1 ]; then 
+	echo "Aborting IPMI test"
+ 	exit 1
+ elif [ $result_ipmi -eq 1 ] && [ $result_dcmi -eq 0 ]; then 
+	output=`/usr/share/checkbox/scripts/ipmi_sensors_ib --tool dcmitool` 
+	code=$? 
+ elif [ $result_ipmi -eq 0 ] && [ $result_dcmi -eq 1 ]; then 
+	output=`/usr/share/checkbox/scripts/ipmi_sensors_ib --tool ipmitool` 
+	code=$? 
+ fi 
+ echo $output
+ exit $code
+_description:
+ 1. Use ipmitool/dcmitool to monitor analog sensors in SDR table through in-band access.
+ 2. Criteria: the status of analog sensors should be "ok" and the data should not be null.
+
+plugin: shell
+name: TC-005-0006-002/OOB_Sensors_Monitoring
+requires:
+ package.name == 'ipmitool'
+user: root
+command: ipmi_sensors_oob
+_description:
+ 1. Use ipmitool to monitor analog sensors in SDR table through OOB access.
+ 2. Criteria: the status of analog sensors should be "ok" and the data should not be null.
+
+plugin: shell
+name: TC-005-0006-003/Thermal_Monitoring
+user: root
+command: echo "Refers to TC-005-0006-001 In-band Sensors Monitoring."; echo "Refers to TC-005-0006-002 OOB Sensors Monitoring."
+_description: 
+ 1. Use ipmitool to monitor thermal sensors in SDR table through in-band/OOB access.
+ 2. Criteria: the status of thermal sensors should be "ok" and the data should not be null.
+
+plugin: shell
+name: TC-005-0006-004/Power_Monitoring
+user: root
+command: echo "Refers to TC-005-0006-001 In-band Sensors Monitoring."; echo "Refers to TC-005-0006-002 OOB Sensors Monitoring."
+_description:
+ 1. Use ipmitool to monitor power sensors in SDR table through in-band/OOB access.
+ 2. Criteria: the status of power sensors should be "ok" and the data should not be null.
+

=== added file 'jobs/TC-005-0009-Power_Policy.txt'
--- jobs/TC-005-0009-Power_Policy.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-005-0009-Power_Policy.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,30 @@
+plugin: shell
+name: TC-005-0009-001/last-state 
+requires:
+ package.name == 'ipmitool'
+user: root
+command: ipmi_power_policy --rule previous
+_description:
+ 1. Use ipmitool to set power on policy to be last-state through OOB.
+ 2. Criteria: the change of power policy should take effect without BMC firmware cold reset or system reboot.
+
+plugin: shell
+name: TC-005-0009-021/always-on
+requires:
+ package.name == 'ipmitool'
+user: root
+command: ipmi_power_policy --rule always-on
+_description:
+ 1. Use ipmitool to set power on policy to be always-on through OOB.
+ 2. Criteria: the change of power policy should take effect without BMC firmware cold reset or system reboot.
+
+plugin: shell
+name: TC-005-0009-003/always-off
+requires:
+ package.name == 'ipmitool'
+user: root
+command: ipmi_power_policy --rule always-off
+_description:
+ 1. Use ipmitool to set power on policy to be always-off through OOB.
+ 2. Criteria: the change of power policy should take effect without BMC firmware cold reset or system reboot.
+

=== added file 'jobs/TC-006-0002-Management_Node_Identifier.txt'
--- jobs/TC-006-0002-Management_Node_Identifier.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-006-0002-Management_Node_Identifier.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,6 @@
+plugin: shell
+name: TC-006-0002-001/Management_Node_Identifier
+requires: package.name == 'ipmitool'
+user: root
+command: echo "Refer to TC-006-0009-001 Inventory Information." 
+_description: Retrieve GUID using ipmitool

=== added file 'jobs/TC-006-0003-Rights_and_Credentials.txt'
--- jobs/TC-006-0003-Rights_and_Credentials.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-006-0003-Rights_and_Credentials.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,21 @@
+plugin: shell
+name: TC-006-0003-001/BMC_Default_Credential_Validation
+requires: 
+ package.name == 'ipmitool'
+user: root
+command: echo "Test by manual"; exit 1
+_description: 
+ 1. Use ipmitool to verify whether the default account is accessible through OOB(manually).
+ 2. Criteria: Successfully access default account.
+
+plugin: shell
+name: TC-006-0003-002/BMC_Default_Credential_Change
+requires: 
+ package.name == 'ipmitool'
+user: root
+command: echo "Test by manual"; exit 1
+_description: 
+ 1. Use ipmitool to change BMC user password(manually).
+ 2. Criteria: Able to change BMC user password.
+
+

=== added file 'jobs/TC-006-0006-Remotely_Power_Control.txt'
--- jobs/TC-006-0006-Remotely_Power_Control.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-006-0006-Remotely_Power_Control.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,27 @@
+plugin: shell
+name: TC-006-0006-001/Remotely_Power_Off_and_On
+requires: package.name == 'ipmitool'
+user: root
+command: ipmi_power_off_on
+_description:
+ 1. Use ipmitool out-of-band access to turn on/off the SUT
+ 2. Criteria: the SUT can be powered on/off by ipmitool out-of-band access
+
+plugin: shell
+name: TC-006-0006-002/Remotely_Hard_Reset
+requires: package.name == 'ipmitool'
+user: root
+command: ipmi_power_reset
+_description:
+ 1. Use ipmitool out-of-band access to power hard reset the SUT 20 times
+ 2. Criteria: complete 20 power hard reset on SUT successfully using ipmitool out-of-band access
+
+plugin: shell
+name: TC-006-0006-003/Remotely_Warm_Reboot
+requires: package.name == 'ipmitool'
+user: root
+command: echo "TBD"; exit 1
+_description:
+ 1. Use ipmitool out-of-band access to power warm reboot the SUT 20 times
+ 2. Criteria: complete 20 power warm reboot on SUT successfully using ipmitool out-of-band acces
+

=== added file 'jobs/TC-006-0007-Temperature.txt'
--- jobs/TC-006-0007-Temperature.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-006-0007-Temperature.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,8 @@
+plugin: shell
+name: TC-006-0007-001/Temp_Sampling_Increment
+requires: package.name == 'ipmitool'
+user: root
+command: ipmi_sampling
+_description: 
+ 1. Retrieve CPU and intake temperature 30 times at 3 second intervals using ipmitool
+ 2. If failed to retrieve temperature at any time within 30 times, the test is considered failed

=== added file 'jobs/TC-006-0008-User_Levels.txt'
--- jobs/TC-006-0008-User_Levels.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-006-0008-User_Levels.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,26 @@
+plugin: shell
+name: TC-006-0008-001/Verify_BMC_Account_Privilege-User
+requires: package.name == 'ipmitool'
+user: root
+command: ipmi_priv_user
+_description: 
+ 1. Use ipmitool out-of-band to read power status, to perform power reset and add a new user account
+ 2. Criteria: power status reading must be successful and must fail at power reset and adding a new user account
+
+plugin: shell
+name: TC-006-0008-002/Verify_BMC_Account_Privilege-Operator
+requires: package.name == 'ipmitool'
+user: root
+command: ipmi_priv_oper 
+_description:
+ 1. Use ipmitool out-of-band to read power status, to perform power reset and add a new user account
+ 2. Criteria: power status reading and power reset must be successful and must fail at adding a new user account 
+
+plugin: shell
+name: TC-006-0008-003/Verify_BMC_Account_Privilege-Administrator
+requires: package.name == 'ipmitool'
+user: root
+command: ipmi_priv_admin
+_description:
+ 1. Use ipmitool out-of-band to read power status, to perform power reset and add a new user account
+ 2. Criteria: Reading power status, performing power reset and adding a user account must all be successful

=== added file 'jobs/TC-006-0009-Inventory.txt'
--- jobs/TC-006-0009-Inventory.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-006-0009-Inventory.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,20 @@
+plugin: shell
+name: TC-006-0009-001/Inventory_Infomation
+requires: 
+ package.name == 'ipmitool'
+user: root
+command: ipmi_inventory
+_description: 
+ 1. Use ipmitool to collect inventory information including Asset Tag, Device ID, System GUID, Firmware Revision, IPMI Version, Management Controller ID
+ 2. Criteria: All information mentioned above must not should not be null
+
+plugin: shell
+name: TC-006-0009-002/FRU
+requires: package.name == 'ipmitool'
+user: root
+command: ipmi_fru
+_description: 
+ 1. Use ipmitool to retrieve FRU data.
+ 2. The data contains product manufacture, product part number, product serial number, motherboard serial number.
+ 3. Criteria: Above All data mentioned above must notshould not be null
+

=== added file 'jobs/TC-006-0010-System_Log.txt'
--- jobs/TC-006-0010-System_Log.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-006-0010-System_Log.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,27 @@
+plugin: shell
+name: TC-006-0010-001/System_Log_Entries
+requires: package.name == 'ipmitool'
+user: root
+command: ipmi_sel_entries
+_description: 
+  1. Use ipmitool to collect event log information
+  2. Calculate entries number of system event log
+  3. Criteria: the log must be capable of saving at least 256 entries
+
+plugin: shell
+name: TC-006-0010-002/System_Log_Hardware_Error
+requires: package.name == 'ipmitool'
+user: root
+command: ipmitool sel elist
+_description:
+ 1. Use ipmitool to capture and check system log.
+ 2. Criteria: hardware errors must not exist in system log. (check manually)
+
+plugin: shell
+name: TC-006-0010-003/System_Log_PET_Format
+requires: package.name == 'ipmitool'
+user: root
+command: echo "Refers to TC-006-0010-002 System Log Hardware Error"
+_description:
+ 1. Use ipmitool to capture and check system log.
+ 2. Criteria: system log must follow PET format.

=== added file 'jobs/TC-007-0001-System_Information.txt'
--- jobs/TC-007-0001-System_Information.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-007-0001-System_Information.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,43 @@
+plugin: shell
+name: TC-007-0001-001/Disk_Information
+requires: package.name == 'lshw'
+user: root
+command: disk_info_leopard
+description:
+ This test case is used for test leopard.
+ 1. Use lshw command to gather disk information. 
+ 2. The program will output disk type, vendor, product, capacity.
+ 3. Criteria: must be able to retrieve disk information.
+
+plugin: shell
+name: TC-007-0001-002/BIOS_Information
+requires: package.name == 'lshw'
+user: root
+command: bios_info
+description:
+ This test case is used for test leopard.
+ 1. Use lshw command to gather BIOS information. 
+ 2. The program will output BIOS vendor, version and release date.
+ 3. Criteria: must be able to retrieve BIOS information.
+
+plugin: shell
+name: TC-007-0001-003/NIC_Information
+command: network_device_info
+description:
+ This test case is used for test leopard.
+ 1. Use udevadm command to gather NIC information.
+ 2. The program will output Interface, product, vendor, driver, device path.
+ 3. Criteria: must be able to retrieve NIC information.
+
+plugin: shell
+name: TC-007-0001-004/RAID_Card_Information
+requires:
+ package.name == 'megacli'
+ package.name == 'megactl'
+user: root
+command: raid_info
+description:
+ This test case is used for test leopard.
+ 1. Use megasasctl command to gather LSI RAID card information.
+ 2. The program will output adapter, product name, memory, BBU, serial no.
+ 3. Criteria: All information listed in item 2 must have value to show that RAID card exists.

=== added file 'jobs/TC-007-0002-Network_Interface_Controller.txt'
--- jobs/TC-007-0002-Network_Interface_Controller.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-007-0002-Network_Interface_Controller.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,24 @@
+plugin: local
+_summary: Automated test to walk multiple network cards and test each one in sequence.
+id: TC-007-0002-001/Network_performance
+requires: 
+ device.category == 'NETWORK'
+_description: Automated test to walk multiple network cards and test each one
+ in sequence.
+command:
+ cat <<'EOF' | run_templates -s 'udev_resource | filter_templates -w "category=NETWORK" | awk "/path: / { print \$2 }" | xargs -n 1 sh -c "for i in \`ls /sys\$0/net 2>/dev/null\`; do echo \$0 \$i; done"'
+ plugin: shell
+ id: TC-007-0002-001/Network_Performance_$2
+ requires:
+  package.name == 'ethtool'
+  package.name == 'nmap'
+  device.path == "$1"
+ user: root
+ environ: TEST_TARGET_FTP TEST_TARGET_IPERF TEST_USER TEST_PASS
+ command: network test -i $2 -t iperf --fail-threshold 90
+ estimated_duration: 330.0
+ description:
+  This test case is used for test leopard.
+  1. Use iperf to test network performance. 
+  2. Criteria: Network performance must be larger than or equal to 90% of NIC hardware specification.
+     For example the network performance should be no less than 9Gb/s in a 10Gb/s NIC card.

=== added file 'jobs/TC-007-0003-Hard_Disk_Drive.txt'
--- jobs/TC-007-0003-Hard_Disk_Drive.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-007-0003-Hard_Disk_Drive.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,44 @@
+plugin: local
+name: TC-007-0003/001-HDD_Healthiness
+requires:
+ package.name == 'smartmontools'
+ device.category == 'DISK'
+command:
+ cat <<'EOF' | run_templates -t -s 'udev_resource | filter_templates -w "category=DISK"'
+ plugin: shell
+ name: TC-007-0003-001/HDD_Healthiness_`ls /sys$path/block`
+ requires:
+  device.path == "$path"
+  block_device.`ls /sys$path/block`_state != 'removable'
+  block_device.`ls /sys$path/block`_rotation == 'yes'
+ description:
+  This test case is used for test leopard.
+  1. Use smartmontools to monitor disk health.
+  2. SMART threshold, grown defect list (glist or reallocated sectors) <= 100 for 4TB, glist <=50 for 2TB for all vendors.
+  3. SMART HDD temp <= 60 degrees centigrade.
+  4. Criteria: all threshold must not exceed the criteria listed in item 2 an 3.
+ user: root
+ command: disk_health -d /dev/`ls /sys$path/block`
+ EOF
+
+plugin: local
+name: TC-007-0003-002/Bad_block_test
+requires:
+ package.name == 'badblocks'
+ device.category == 'DISK'
+command:
+ cat <<'EOF' | run_templates -t -s 'udev_resource | filter_templates -w "category=DISK"'
+ plugin: shell
+ name: TC-007-0003-002/Bad_block_test_`ls /sys$path/block`
+ requires:
+  device.path == "$path"
+  block_device.`ls /sys$path/block`_state != 'removable'
+  block_device.`ls /sys$path/block`_rotation == 'yes'
+ description:
+  This test case is used for test leopard.
+  1. Use badblocks command to perform a full disk bad block scan with 0xff pattern.
+  2. The duration of the test is under 24 hours.
+  3. Criteria: pass if no hard disk error.
+ user: root
+ command: bad_block_test -t 0xff -d /dev/`ls /sys$path/block`
+ EOF

=== added file 'jobs/TC-007-0004-System_Idle_and_Stress_Test.txt'
--- jobs/TC-007-0004-System_Idle_and_Stress_Test.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-007-0004-System_Idle_and_Stress_Test.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,8 @@
+plugin: shell
+name: TC-007-0004-002/System_Stress
+user: root
+command: system_stress -s 28800
+description:
+ This test case is used for test leopard.
+ 1. Use google stressapptest tool to perform system stress test for 8 hours.
+ 2. Criteria: pass without MCE error log.

=== added file 'jobs/TC-007-0005-JBOD_Testing.txt'
--- jobs/TC-007-0005-JBOD_Testing.txt	1970-01-01 00:00:00 +0000
+++ jobs/TC-007-0005-JBOD_Testing.txt	2015-08-14 22:03:31 +0000
@@ -0,0 +1,74 @@
+plugin: shell
+name: TC-007-0005-001/Get_All_HDDs
+requires:
+ package.name == 'megacli'
+ package.name == 'megactl'
+user: root
+command: raid_hdd_info
+description:
+ This test case is used for test leopard.
+ 1. Use megasasctl command to get all JBOD HDD information.
+ 2. Show total HDD number in JBOD and check disks readiness.
+ 3. Criteria: ensure all JBOD disks information and status are correct.
+
+plugin: shell
+name: TC-007-0005-002/Build_RAID_6
+requires:
+ package.name == 'megacli'
+ package.name == 'megactl'
+user: root
+depends: TC-007-0005-001/Get_All_HDDs
+command: create_raid -t 6
+description:
+ This test case is used for test leopard.
+ 1. Use megacli command to build RAID 6 on JBOD from LSI RAID card. 
+ 2. Criteria: pass if the return code is zero.
+
+plugin: shell
+name: TC-007-0005-003/Build_RAID_0
+requires:
+ package.name == 'megacli'
+ package.name == 'megactl'
+user: root
+depends: TC-007-0005-001/Get_All_HDDs
+command: create_raid -t 0
+description:
+ This test case is used for test leopard.
+ 1. Use megacli command to build RAID 0 on JBOD from LSI RAID card. 
+ 2. Criteria: pass if the return code is zero.
+
+plugin: shell
+name: TC-007-0005-004/RAID_6_Availability_Test
+user: root
+depends: TC-007-0005-002/Build_RAID_6
+command: raid_availability_test
+description:
+ This test case is used for test leopard.
+ 1. Create one partition and format on RAID 6 to test disk I/O.
+ 2. Test RAID Read/Write file correctly on JBOD.
+ 3. Criteria: Create/Read/Write file without error.
+
+plugin: shell
+name: TC-007-0005-005/RAID_0_Availability_Test
+user: root
+depends: TC-007-0005-003/Build_RAID_0
+command: raid_availability_test
+description:
+ This test case is used for test leopard.
+ 1. Create one partition and format on RAID 0 to test disk I/O.
+ 2. Test RAID Read/Write file correctly on JBOD.
+ 3. Criteria: Create/Read/Write file without error.
+
+plugin: shell
+name: TC-007-0005-006/Rebuild_RAID_6
+requires:
+ package.name == 'megacli'
+ package.name == 'megactl'
+depends: TC-007-0005-004/RAID_6_Availability_Test
+environ: CHECKBOX_DATA
+user: root
+command: rebulid_raid -l $CHECKBOX_DATA/rebulid_raid.log
+description:
+ This test case is used for test leopard.
+ 1. Test RAID 6 auto rebuild feature in hot spare mode.
+ 2. Criteria: rebuild RAID 6 successfully.

=== added file 'jobs/dcmi_in_band.txt.in'
--- jobs/dcmi_in_band.txt.in	1970-01-01 00:00:00 +0000
+++ jobs/dcmi_in_band.txt.in	2015-08-14 22:03:31 +0000
@@ -0,0 +1,56 @@
+plugin: shell
+name: dcmi/in_band/admin/get_capabilities
+requires: package.name == 'dcmitool'
+user: root
+command: sleep 5; dcmitool dcmi discover
+_description:
+ Retrieve management interface capabilities.
+
+plugin: shell
+name: dcmi/in_band/admin/channel_info
+requires: package.name == 'dcmitool'
+user: root
+command: sleep 5; dcmitool channel info
+_description:
+ Retrieve management interface channel info.
+
+plugin: shell
+name: dcmi/in_band/admin/controller_info
+requires: package.name == 'dcmitool'
+user: root
+command: sleep 5; dcmitool mc info
+_description:
+ Retrieve management interface channel info.
+
+plugin: shell
+name: dcmi/in_band/admin/temp_readings
+requires: package.name == 'dcmitool'
+user: root
+command: sleep 5; dcmitool dcmi sensors
+_description:
+ Retrieve CPU and Baseboard temperature readings.
+
+plugin: shell
+name: dcmi/in_band/admin/chassis_readings
+requires: package.name == 'dcmitool'
+user: root
+command: sleep 5; dcmitool dcmi sensors
+_description:
+ Retrieve Thermal threshold settings and readings.
+
+plugin: shell
+name: dcmi/in_band/admin/chassis_power_status
+requires: package.name == 'dcmitool'
+user: root
+command: sleep 5; dcmitool chassis power status
+_description:
+ Retrieve Chassis power status.
+
+plugin: shell
+name: dcmi/in_band/admin/chassis_status
+requires: package.name == 'dcmitool'
+user: root
+command: sleep 5; dcmitool chassis status
+_description:
+ Retrieve Chassis status.
+

=== removed file 'jobs/dcmi_in_band.txt.in'
--- jobs/dcmi_in_band.txt.in	2015-02-27 22:25:54 +0000
+++ jobs/dcmi_in_band.txt.in	1970-01-01 00:00:00 +0000
@@ -1,56 +0,0 @@
-plugin: shell
-name: dcmi/in_band/admin/get_capabilities
-requires: package.name == 'dcmitool'
-user: root
-command: sleep 5; dcmitool dcmi discover
-_description:
- Retrieve management interface capabilities.
-
-plugin: shell
-name: dcmi/in_band/admin/channel_info
-requires: package.name == 'dcmitool'
-user: root
-command: sleep 5; dcmitool channel info
-_description:
- Retrieve management interface channel info.
-
-plugin: shell
-name: dcmi/in_band/admin/controller_info
-requires: package.name == 'dcmitool'
-user: root
-command: sleep 5; dcmitool mc info
-_description:
- Retrieve management interface channel info.
-
-plugin: shell
-name: dcmi/in_band/admin/temp_readings
-requires: package.name == 'dcmitool'
-user: root
-command: sleep 5; dcmitool dcmi sensors
-_description:
- Retrieve CPU and Baseboard temperature readings.
-
-plugin: shell
-name: dcmi/in_band/admin/chassis_readings
-requires: package.name == 'dcmitool'
-user: root
-command: sleep 5; dcmitool dcmi sensors
-_description:
- Retrieve Thermal threshold settings and readings.
-
-plugin: shell
-name: dcmi/in_band/admin/chassis_power_status
-requires: package.name == 'dcmitool'
-user: root
-command: sleep 5; dcmitool chassis power status
-_description:
- Retrieve Chassis power status.
-
-plugin: shell
-name: dcmi/in_band/admin/chassis_status
-requires: package.name == 'dcmitool'
-user: root
-command: sleep 5; dcmitool chassis status
-_description:
- Retrieve Chassis status.
-

=== added file 'jobs/ipmi.txt.in'
--- jobs/ipmi.txt.in	1970-01-01 00:00:00 +0000
+++ jobs/ipmi.txt.in	2015-08-14 22:03:31 +0000
@@ -0,0 +1,151 @@
+plugin: attachment
+name: ipmi/in_band/admin/chassis_info
+requires: package.name == 'ipmitool'
+user: root
+command: ipmitool fru -C3
+_description:
+ Retrieve chassis model and manufacturer information.
+
+plugin: attachment
+name: ipmi/out_of_band/admin/chassis_info
+requires: package.name == 'ipmitool'
+user: root
+environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
+command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD fru -C3
+_description:
+ Retrieve chassis model and manufacturer information.
+
+plugin: shell
+name: ipmi/out_of_band/admin/check_power_on
+requires: package.name == 'ipmitool'
+user: root
+environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
+command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis power status -C3 | grep -q "on"
+_description:
+ Retrieve Chassis Status information with Admin credentials
+
+plugin: shell
+name: ipmi/out_of_band/admin/check_power_off
+requires: package.name == 'ipmitool'
+user: root
+environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
+command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis power status -C3 | grep -q "off"
+_description:
+ Retrieve Chassis Status information with Admin credentials
+
+plugin: shell
+name: ipmi/out_of_band/admin/power_on
+requires: package.name == 'ipmitool'
+depends: ipmi/out_of_band/admin/check_power_off
+user: root
+environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
+command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis power on -C3; retval=$?; sleep 30; exit $retval
+_description:
+ Power on server via BMC with Admin credentials
+
+plugin: shell
+name: ipmi/out_of_band/admin/power_off
+requires: package.name == 'ipmitool'
+depends: ipmi/out_of_band/admin/check_power_on
+user: root
+environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
+command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis power off -C3; retval=$?; sleep 30; exit $retval
+_description:
+ Power off server via BMC with Admin credentials
+
+plugin: shell
+name: ipmi/out_of_band/admin/power_reset
+requires: package.name == 'ipmitool'
+user: root
+environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
+command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis power reset -C3; retval=$?; sleep 30; exit $retval
+_description:
+ Power reset server via BMC with Admin credentials
+
+plugin: shell
+name: ipmi/out_of_band/admin/power_cycle
+requires: package.name == 'ipmitool'
+user: root
+environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
+command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis power cycle -C3; retval=$?; sleep 30; exit $retval
+_description:
+ Power cycle server via BMC with Admin credentials
+
+plugin: shell
+name: ipmi/out_of_band/admin/power_policy_always_on
+requires: package.name == 'ipmitool'
+user: root
+environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
+command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis policy always-on -C3
+_description:
+ Set server power policy to always on via BMC with Admin credentials
+
+plugin: shell
+name: ipmi/out_of_band/admin/power_policy_always_off
+requires: package.name == 'ipmitool'
+user: root
+environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
+command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis policy always-off -C3
+_description:
+ Set server power policy to always off via BMC with Admin credentials
+
+plugin: shell
+name: ipmi/out_of_band/admin/power_policy_previous
+requires: package.name == 'ipmitool'
+user: root
+environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
+command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis policy previous -C3
+_description:
+ Set server power policy to previous via BMC with Admin credentials
+
+plugin: shell
+name: ipmi/in_band/admin/chassis_self_test
+requires: package.name == 'ipmitool'
+user: root
+command: ipmitool chassis selftest -C3
+_description:
+ Run chassis BMC self test with Admin credentials
+
+plugin: shell
+name: ipmi/out_of_band/admin/chassis_self_test
+requires: package.name == 'ipmitool'
+user: root
+environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
+command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis selftest -C3
+_description:
+ Run chassis BMC self test with Admin credentials
+
+plugin: shell
+name: ipmi/in_band/admin/detailed_sensor_readings
+requires: package.name == 'ipmitool'
+user: root
+command: ipmitool sensor -C3
+_description:
+ Retrieve detailed chassis sensor readings
+
+plugin: shell
+name: ipmi/out_of_band/admin/detailed_sensor_readings
+requires: package.name == 'ipmitool'
+user: root
+environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
+command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD sensor -C3
+_description:
+ Retrieve detailed chassis sensor readings
+
+plugin: shell
+name: ipmi/in_band/admin/chassis_status
+requires: package.name == 'ipmitool'
+user: root
+command: ipmitool chassis status -C3
+_description:
+ Retrieve Chassis Status information with Admin credentials
+
+plugin: shell
+name: ipmi/out_of_band/admin/chassis_status
+requires: package.name == 'ipmitool'
+user: root
+environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
+command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis status -C3
+_description:
+ Retrieve Chassis Status information with Admin credentials
+

=== removed file 'jobs/ipmi.txt.in'
--- jobs/ipmi.txt.in	2015-02-27 22:25:54 +0000
+++ jobs/ipmi.txt.in	1970-01-01 00:00:00 +0000
@@ -1,151 +0,0 @@
-plugin: attachment
-name: ipmi/in_band/admin/chassis_info
-requires: package.name == 'ipmitool'
-user: root
-command: ipmitool fru -C3
-_description:
- Retrieve chassis model and manufacturer information.
-
-plugin: attachment
-name: ipmi/out_of_band/admin/chassis_info
-requires: package.name == 'ipmitool'
-user: root
-environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
-command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD fru -C3
-_description:
- Retrieve chassis model and manufacturer information.
-
-plugin: shell
-name: ipmi/out_of_band/admin/check_power_on
-requires: package.name == 'ipmitool'
-user: root
-environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
-command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis power status -C3 | grep -q "on"
-_description:
- Retrieve Chassis Status information with Admin credentials
-
-plugin: shell
-name: ipmi/out_of_band/admin/check_power_off
-requires: package.name == 'ipmitool'
-user: root
-environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
-command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis power status -C3 | grep -q "off"
-_description:
- Retrieve Chassis Status information with Admin credentials
-
-plugin: shell
-name: ipmi/out_of_band/admin/power_on
-requires: package.name == 'ipmitool'
-depends: ipmi/out_of_band/admin/check_power_off
-user: root
-environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
-command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis power on -C3; retval=$?; sleep 30; exit $retval
-_description:
- Power on server via BMC with Admin credentials
-
-plugin: shell
-name: ipmi/out_of_band/admin/power_off
-requires: package.name == 'ipmitool'
-depends: ipmi/out_of_band/admin/check_power_on
-user: root
-environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
-command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis power off -C3; retval=$?; sleep 30; exit $retval
-_description:
- Power off server via BMC with Admin credentials
-
-plugin: shell
-name: ipmi/out_of_band/admin/power_reset
-requires: package.name == 'ipmitool'
-user: root
-environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
-command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis power reset -C3; retval=$?; sleep 30; exit $retval
-_description:
- Power reset server via BMC with Admin credentials
-
-plugin: shell
-name: ipmi/out_of_band/admin/power_cycle
-requires: package.name == 'ipmitool'
-user: root
-environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
-command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis power cycle -C3; retval=$?; sleep 30; exit $retval
-_description:
- Power cycle server via BMC with Admin credentials
-
-plugin: shell
-name: ipmi/out_of_band/admin/power_policy_always_on
-requires: package.name == 'ipmitool'
-user: root
-environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
-command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis policy always-on -C3
-_description:
- Set server power policy to always on via BMC with Admin credentials
-
-plugin: shell
-name: ipmi/out_of_band/admin/power_policy_always_off
-requires: package.name == 'ipmitool'
-user: root
-environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
-command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis policy always-off -C3
-_description:
- Set server power policy to always off via BMC with Admin credentials
-
-plugin: shell
-name: ipmi/out_of_band/admin/power_policy_previous
-requires: package.name == 'ipmitool'
-user: root
-environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
-command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis policy previous -C3
-_description:
- Set server power policy to previous via BMC with Admin credentials
-
-plugin: shell
-name: ipmi/in_band/admin/chassis_self_test
-requires: package.name == 'ipmitool'
-user: root
-command: ipmitool chassis selftest -C3
-_description:
- Run chassis BMC self test with Admin credentials
-
-plugin: shell
-name: ipmi/out_of_band/admin/chassis_self_test
-requires: package.name == 'ipmitool'
-user: root
-environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
-command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis selftest -C3
-_description:
- Run chassis BMC self test with Admin credentials
-
-plugin: shell
-name: ipmi/in_band/admin/detailed_sensor_readings
-requires: package.name == 'ipmitool'
-user: root
-command: ipmitool sensor -C3
-_description:
- Retrieve detailed chassis sensor readings
-
-plugin: shell
-name: ipmi/out_of_band/admin/detailed_sensor_readings
-requires: package.name == 'ipmitool'
-user: root
-environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
-command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD sensor -C3
-_description:
- Retrieve detailed chassis sensor readings
-
-plugin: shell
-name: ipmi/in_band/admin/chassis_status
-requires: package.name == 'ipmitool'
-user: root
-command: ipmitool chassis status -C3
-_description:
- Retrieve Chassis Status information with Admin credentials
-
-plugin: shell
-name: ipmi/out_of_band/admin/chassis_status
-requires: package.name == 'ipmitool'
-user: root
-environ: IPMI_TARGET IPMI_ADMIN IPMI_ADMIN_PASSWORD
-command: ipmitool -I lanplus -H $IPMI_TARGET -U $IPMI_ADMIN -P $IPMI_ADMIN_PASSWORD chassis status -C3
-_description:
- Retrieve Chassis Status information with Admin credentials
-

=== added file 'jobs/ocp-disk.txt.in'
--- jobs/ocp-disk.txt.in	1970-01-01 00:00:00 +0000
+++ jobs/ocp-disk.txt.in	2015-08-14 22:03:31 +0000
@@ -0,0 +1,17 @@
+plugin: local
+name: disk/ocp/io_stress
+requires:
+ device.category == 'DISK'
+ package.name == 'stressapptest'
+_description: Verify that storage devices, such as Fibre Channel and RAID can be detected and perform under stress.
+command:
+ cat <<'EOF' | run_templates -t -s 'udev_resource | filter_templates -w "category=DISK"'
+ plugin: shell
+ name: disk/ocp/io_stress_`ls /sys$path/block`
+ user: root
+ requires:
+  device.path == "$path"
+  block_device.`ls /sys$path/block`_state != 'removable'
+ description: Disk I/O stress test for $product
+ command: disk_stress `ls /sys$path/block | sed 's|!|/|'`
+ EOF

=== removed file 'jobs/ocp-disk.txt.in'
--- jobs/ocp-disk.txt.in	2015-03-06 21:01:15 +0000
+++ jobs/ocp-disk.txt.in	1970-01-01 00:00:00 +0000
@@ -1,17 +0,0 @@
-plugin: local
-name: disk/ocp/io_stress
-requires:
- device.category == 'DISK'
- package.name == 'stressapptest'
-_description: Verify that storage devices, such as Fibre Channel and RAID can be detected and perform under stress.
-command:
- cat <<'EOF' | run_templates -t -s 'udev_resource | filter_templates -w "category=DISK"'
- plugin: shell
- name: disk/ocp/io_stress_`ls /sys$path/block`
- user: root
- requires:
-  device.path == "$path"
-  block_device.`ls /sys$path/block`_state != 'removable'
- description: Disk I/O stress test for $product
- command: disk_stress `ls /sys$path/block | sed 's|!|/|'`
- EOF

=== added file 'jobs/ocp-local.txt.in'
--- jobs/ocp-local.txt.in	1970-01-01 00:00:00 +0000
+++ jobs/ocp-local.txt.in	2015-08-14 22:03:31 +0000
@@ -0,0 +1,62 @@
+id: __dcmi_in_band__
+plugin: local
+_description: DCMI in-band tests (OCP)
+command:
+  shopt -s extglob
+  cat $PLAINBOX_PROVIDER_DATA/../jobs/dcmi_in_band.txt?(.in)
+
+id: __ocp-disk__
+plugin: local
+_description: Disk tests (OCP)
+command:
+  shopt -s extglob
+  cat $PLAINBOX_PROVIDER_DATA/../jobs/ocp-disk.txt?(.in)
+
+id: __ipmi__
+plugin: local
+_description: IPMI tests (OCP)
+command:
+  shopt -s extglob
+  cat $PLAINBOX_PROVIDER_DATA/../jobs/ipmi.txt?(.in)
+
+id: __ocp-memory__
+plugin: local
+_description: Memory tests (OCP)
+command:
+  shopt -s extglob
+  cat $PLAINBOX_PROVIDER_DATA/../jobs/ocp-memory.txt?(.in)
+
+id: __ocp-miscellanea__
+plugin: local
+_description: Miscellaneous tests (OCP)
+command:
+  shopt -s extglob
+  cat $PLAINBOX_PROVIDER_DATA/../jobs/ocp-miscellanea.txt?(.in)
+
+id: __ocp-power-management__
+plugin: local
+_description: Power Management tests (OCP)
+command:
+  shopt -s extglob
+  cat $PLAINBOX_PROVIDER_DATA/../jobs/ocp-power-management.txt?(.in)
+
+id: __TC-001__
+plugin: local
+_description: TC-001 CPU / Memory
+command:
+  shopt -s extglob
+  cat $PLAINBOX_PROVIDER_DATA/../jobs/TC-001-*.txt?(.in)
+
+id: __TC-002__
+plugin: local
+_description: TC-002 Platform Controller Hub
+command:
+  shopt -s extglob
+  cat $PLAINBOX_PROVIDER_DATA/../jobs/TC-002-*.txt?(.in)
+
+id: __TC-003__
+plugin: local
+_description: TC-003 Network Performance
+command:
+  shopt -s extglob
+  cat $PLAINBOX_PROVIDER_DATA/../jobs/TC-003-*.txt?(.in)

=== removed file 'jobs/ocp-local.txt.in'
--- jobs/ocp-local.txt.in	2015-03-06 21:47:21 +0000
+++ jobs/ocp-local.txt.in	1970-01-01 00:00:00 +0000
@@ -1,62 +0,0 @@
-id: __dcmi_in_band__
-plugin: local
-_description: DCMI in-band tests (OCP)
-command:
-  shopt -s extglob
-  cat $PLAINBOX_PROVIDER_DATA/../jobs/dcmi_in_band.txt?(.in)
-
-id: __ocp-disk__
-plugin: local
-_description: Disk tests (OCP)
-command:
-  shopt -s extglob
-  cat $PLAINBOX_PROVIDER_DATA/../jobs/ocp-disk.txt?(.in)
-
-id: __ipmi__
-plugin: local
-_description: IPMI tests (OCP)
-command:
-  shopt -s extglob
-  cat $PLAINBOX_PROVIDER_DATA/../jobs/ipmi.txt?(.in)
-
-id: __ocp-memory__
-plugin: local
-_description: Memory tests (OCP)
-command:
-  shopt -s extglob
-  cat $PLAINBOX_PROVIDER_DATA/../jobs/ocp-memory.txt?(.in)
-
-id: __ocp-miscellanea__
-plugin: local
-_description: Miscellaneous tests (OCP)
-command:
-  shopt -s extglob
-  cat $PLAINBOX_PROVIDER_DATA/../jobs/ocp-miscellanea.txt?(.in)
-
-id: __ocp-power-management__
-plugin: local
-_description: Power Management tests (OCP)
-command:
-  shopt -s extglob
-  cat $PLAINBOX_PROVIDER_DATA/../jobs/ocp-power-management.txt?(.in)
-
-id: __TC-001__
-plugin: local
-_description: TC-001 CPU / Memory
-command:
-  shopt -s extglob
-  cat $PLAINBOX_PROVIDER_DATA/../jobs/TC-001-*.txt?(.in)
-
-id: __TC-002__
-plugin: local
-_description: TC-002 Platform Controller Hub
-command:
-  shopt -s extglob
-  cat $PLAINBOX_PROVIDER_DATA/../jobs/TC-002-*.txt?(.in)
-
-id: __TC-003__
-plugin: local
-_description: TC-003 Network Performance
-command:
-  shopt -s extglob
-  cat $PLAINBOX_PROVIDER_DATA/../jobs/TC-003-*.txt?(.in)

=== added file 'jobs/ocp-memory.txt.in'
--- jobs/ocp-memory.txt.in	1970-01-01 00:00:00 +0000
+++ jobs/ocp-memory.txt.in	2015-08-14 22:03:31 +0000
@@ -0,0 +1,20 @@
+plugin: shell
+name: memory/ocp/stress_30min
+user: root
+command: stressapptest -s 1800
+_description:
+ Test and exercise memory.
+
+plugin: shell
+name: memory/ocp/stress_1hr
+user: root
+command: stressapptest -s 3600
+_description:
+ Test and exercise memory.
+
+plugin: shell
+name: memory/ocp/mcelog_check
+user: root
+command: cat /var/log/mcelog; [ ! -s /var/log/mcelog ]
+_description:
+ Grabs mcelog containing memory errors.

=== removed file 'jobs/ocp-memory.txt.in'
--- jobs/ocp-memory.txt.in	2015-03-06 21:01:15 +0000
+++ jobs/ocp-memory.txt.in	1970-01-01 00:00:00 +0000
@@ -1,20 +0,0 @@
-plugin: shell
-name: memory/ocp/stress_30min
-user: root
-command: stressapptest -s 1800
-_description:
- Test and exercise memory.
-
-plugin: shell
-name: memory/ocp/stress_1hr
-user: root
-command: stressapptest -s 3600
-_description:
- Test and exercise memory.
-
-plugin: shell
-name: memory/ocp/mcelog_check
-user: root
-command: cat /var/log/mcelog; [ ! -s /var/log/mcelog ]
-_description:
- Grabs mcelog containing memory errors.

=== added file 'jobs/ocp-miscellanea.txt.in'
--- jobs/ocp-miscellanea.txt.in	1970-01-01 00:00:00 +0000
+++ jobs/ocp-miscellanea.txt.in	2015-08-14 22:03:31 +0000
@@ -0,0 +1,19 @@
+plugin: shell
+name: miscellanea/ocp/idle_check
+command: [ `uptime | awk '{split($3,a,":"); print a[1]}'` -lt 12 ] && [[ "`uptime | awk '{print $4}'`" == *min* ]] && [[ "`uptime`" != *day* ]]
+_description:
+ Quick check to validate hardware has remained idle for 12+ hours
+
+plugin: manual
+name: miscellanea/ocp/12hr_idle_verify
+depends: miscellanea/ocp/idle_check
+_description:
+ PURPOSE:
+   Warning. We could not verify that the system has already completed a 12 hour idle session.
+   This test will ask you to verify the system has remained active and booted to an OS for 12+ hours.
+ STEPS:
+   1. Prior to running this test, you should have attempted to let the machine idle for more than 12 hrs while booted to an OS.
+ VERIFICATION:
+   1. Select Yes if the system remained on and booted to an operating system for 12 hours without error.
+   2. Select No if you have not allowed the system to be on and booted to an operating system for 12 hours.
+   3. Select No if you attempted to let the system remain idle for 12 hours and it failed to do so for any reason/

=== removed file 'jobs/ocp-miscellanea.txt.in'
--- jobs/ocp-miscellanea.txt.in	2015-03-06 21:01:15 +0000
+++ jobs/ocp-miscellanea.txt.in	1970-01-01 00:00:00 +0000
@@ -1,19 +0,0 @@
-plugin: shell
-name: miscellanea/ocp/idle_check
-command: [ `uptime | awk '{split($3,a,":"); print a[1]}'` -lt 12 ] && [[ "`uptime | awk '{print $4}'`" == *min* ]] && [[ "`uptime`" != *day* ]]
-_description:
- Quick check to validate hardware has remained idle for 12+ hours
-
-plugin: manual
-name: miscellanea/ocp/12hr_idle_verify
-depends: miscellanea/ocp/idle_check
-_description:
- PURPOSE:
-   Warning. We could not verify that the system has already completed a 12 hour idle session.
-   This test will ask you to verify the system has remained active and booted to an OS for 12+ hours.
- STEPS:
-   1. Prior to running this test, you should have attempted to let the machine idle for more than 12 hrs while booted to an OS.
- VERIFICATION:
-   1. Select Yes if the system remained on and booted to an operating system for 12 hours without error.
-   2. Select No if you have not allowed the system to be on and booted to an operating system for 12 hours.
-   3. Select No if you attempted to let the system remain idle for 12 hours and it failed to do so for any reason/

=== added file 'jobs/ocp-power-management.txt.in'
--- jobs/ocp-power-management.txt.in	1970-01-01 00:00:00 +0000
+++ jobs/ocp-power-management.txt.in	2015-08-14 22:03:31 +0000
@@ -0,0 +1,42 @@
+plugin: user-interact-verify
+id: power-management/ocp/poweroff
+estimated_duration: 120.0
+user: root
+environ: PLAINBOX_SESSION_SHARE
+requires:
+command: shutdown -h now
+flags: noreturn
+_description:
+ PURPOSE:
+  This test will check the system's ability to power-off and boot.
+ STEPS:
+  1. When prompted, hit Enter to begin.
+  2. The machine will shut down.
+  3. Power the machine back on.
+  4. After rebooting, restart the Open Compute testing tool
+  5. Select 'r' to 'resume this session'
+  6. Select 'p' to indicate the system successfully powered off or 'f' to
+  indicate that the system did NOT successfully power off.
+ VERIFICATION:
+  If the machine successfully shuts down and boots, select 'p', otherwise,
+  select 'f'.
+
+plugin: user-interact-verify
+id: power-management/ocp/reboot
+estimated_duration: 120.0
+user: root
+environ: PLAINBOX_SESSION_SHARE
+command: shutdown -r now
+flags: noreturn
+_description:
+ PURPOSE:
+  This test will check the system's ability to reboot cleanly.
+ STEPS:
+  1. When prompted, hit Enter to begin.
+  2. The machine will reboot.
+  3. After rebooting, restart the Open Compute testing tool
+  4. Select 'r' to 'resume this session'
+  5. Select 'p' to indicate the system successfully powered off or 'f' to
+  indicate that the system did NOT successfully power off.
+ VERIFICATION:
+  If the machine successfully reboots, select Yes then select Next.

=== removed file 'jobs/ocp-power-management.txt.in'
--- jobs/ocp-power-management.txt.in	2015-03-07 17:48:09 +0000
+++ jobs/ocp-power-management.txt.in	1970-01-01 00:00:00 +0000
@@ -1,42 +0,0 @@
-plugin: user-interact-verify
-id: power-management/ocp/poweroff
-estimated_duration: 120.0
-user: root
-environ: PLAINBOX_SESSION_SHARE
-requires:
-command: shutdown -h now
-flags: noreturn
-_description:
- PURPOSE:
-  This test will check the system's ability to power-off and boot.
- STEPS:
-  1. When prompted, hit Enter to begin.
-  2. The machine will shut down.
-  3. Power the machine back on.
-  4. After rebooting, restart the Open Compute testing tool
-  5. Select 'r' to 'resume this session'
-  6. Select 'p' to indicate the system successfully powered off or 'f' to
-  indicate that the system did NOT successfully power off.
- VERIFICATION:
-  If the machine successfully shuts down and boots, select 'p', otherwise,
-  select 'f'.
-
-plugin: user-interact-verify
-id: power-management/ocp/reboot
-estimated_duration: 120.0
-user: root
-environ: PLAINBOX_SESSION_SHARE
-command: shutdown -r now
-flags: noreturn
-_description:
- PURPOSE:
-  This test will check the system's ability to reboot cleanly.
- STEPS:
-  1. When prompted, hit Enter to begin.
-  2. The machine will reboot.
-  3. After rebooting, restart the Open Compute testing tool
-  4. Select 'r' to 'resume this session'
-  5. Select 'p' to indicate the system successfully powered off or 'f' to
-  indicate that the system did NOT successfully power off.
- VERIFICATION:
-  If the machine successfully reboots, select Yes then select Next.

=== added file 'whitelists/opencompute-certify-basic.whitelist'
--- whitelists/opencompute-certify-basic.whitelist	1970-01-01 00:00:00 +0000
+++ whitelists/opencompute-certify-basic.whitelist	2015-08-14 22:03:31 +0000
@@ -0,0 +1,42 @@
+# Resource jobs
+miscellanea/submission-resources
+#Info attachment jobs
+__info__
+cpuinfo_attachment
+dmesg_attachment
+dmi_attachment
+dmidecode_attachment
+efi_attachment
+lspci_attachment
+lshw_attachment
+mcelog_attachment
+meminfo_attachment
+modprobe_attachment
+modules_attachment
+sysctl_attachment
+sysfs_attachment
+udev_attachment
+lsmod_attachment
+acpi_sleep_attachment
+info/hdparm
+info/hdparm_.*.txt
+installer_debug.gz
+info/disk_partitions
+# Actual test cases
+__TC-001-0001-CPU_Memory__
+TC-001-0001-001/CPU_Information
+TC-001-0001-002/Processor_Topology
+TC-001-0001-003/Memory_Information
+__TC-001-0002-Platform_Controller_Hub__
+TC-001-0002-001/SATA_port
+TC-001-0002-002/USB_2.0
+__TC-002-0010-Inventory__
+TC-002-0010-001/Inventory_Infomation
+__TC-003-0001-Hardware_Information__
+TC-003-0001-001/CPU_Information
+TC-003-0001-002/Memory_Information
+TC-003-0001-003/Disk_Information
+TC-003-0001-004/BIOS_Information
+TC-003-0001-005/ME_Information
+TC-003-0001-006/NIC_Information
+TC-003-0001-007/RAID_Card_Information

=== added file 'whitelists/opencompute-certify-basic_leopard.whitelist'
--- whitelists/opencompute-certify-basic_leopard.whitelist	1970-01-01 00:00:00 +0000
+++ whitelists/opencompute-certify-basic_leopard.whitelist	2015-08-14 22:03:31 +0000
@@ -0,0 +1,37 @@
+# Resource Jobs
+miscellanea/submission-resources
+#Info attachment jobs
+__info__
+cpuinfo_attachment
+dmesg_attachment
+dmi_attachment
+dmidecode_attachment
+efi_attachment
+lspci_attachment
+lshw_attachment
+mcelog_attachment
+meminfo_attachment
+modprobe_attachment
+modules_attachment
+sysctl_attachment
+sysfs_attachment
+udev_attachment
+lsmod_attachment
+acpi_sleep_attachment
+info/hdparm
+info/hdparm_.*.txt
+installer_debug.gz
+info/disk_partitions
+# Actual test cases
+__TC-005-0001-CPU_Memory__
+TC-005-0001-001/CPU_Information
+TC-005-0001-002/Processor_Topology
+TC-005-0001-003/Memory_Information
+__TC-005-0002-Platform_Controller_Hub__
+TC-005-0002-001/SATA_Port
+TC-005-0002-002/USB_Port
+__TC-007-0001-System_Information__
+TC-007-0001-001/Disk_Information
+TC-007-0001-002/BIOS_Information
+TC-007-0001-003/NIC_Information
+TC-007-0001-004/RAID_Card_Information

=== modified file 'whitelists/opencompute-certify-iperf.whitelist'
--- whitelists/opencompute-certify-iperf.whitelist	2015-03-06 21:47:21 +0000
+++ whitelists/opencompute-certify-iperf.whitelist	2015-08-14 22:03:31 +0000
@@ -23,6 +23,6 @@
 installer_debug.gz
 info/disk_partitions
 # Actual test cases
-__TC-003__
+__TC-003-0003-Network_Performance__
 TC-003-0003-001/Network_performance
 TC-003-0003-001/Network_performance_.*

=== modified file 'whitelists/opencompute-certify-local.whitelist'
--- whitelists/opencompute-certify-local.whitelist	2015-03-06 21:47:21 +0000
+++ whitelists/opencompute-certify-local.whitelist	2015-08-14 22:03:31 +0000
@@ -23,13 +23,26 @@
 installer_debug.gz
 info/disk_partitions
 # Actual test cases
-__TC-001__
+__TC-001-0001-CPU_Memory__
 TC-001-0001-001/CPU_Information
 TC-001-0001-002/Processor_Topology
 TC-001-0001-003/Memory_Information
+__TC-001-0002-Platform_Controller_Hub__
 TC-001-0002-001/SATA_port
 TC-001-0002-002/USB_2.0
-__TC-003__
+__TC-001-0004-BIOS_Remote_Update__
+TC-001-0004-001/Sample-Audit_BIOS_settings
+TC-001-0004-002/Update_BIOS_settings_with_pre-configured
+TC-001-0004-003/BIOS-firmware_update
+__TC-001-0006-Hardware_Monitoring__
+TC-001-0006-001/Thermal_Monitoring
+__TC-001-0007-In_band_Platform_Controller_Hub_Management_Engine__
+TC-001-0007-001/In_band_Power_and_Thermal_Monitoring
+__TC-002-0002-Management_Node_Identifier__
+TC-002-0002-001/Management_Node_Identifier
+__TC-002-0010-Inventory__
+TC-002-0010-001/Inventory_Infomation
+__TC-003-0001-Hardware_Information__
 TC-003-0001-001/CPU_Information
 TC-003-0001-002/Memory_Information
 TC-003-0001-003/Disk_Information
@@ -37,3 +50,6 @@
 TC-003-0001-005/ME_Information
 TC-003-0001-006/NIC_Information
 TC-003-0001-007/RAID_Card_Information
+__TC-003-0004-Disk_Healthiness__
+TC-003-0004-001/Disk_Health
+TC-003-0004-001/Disk_Health.*

=== added file 'whitelists/opencompute-certify-local_leopard.whitelist'
--- whitelists/opencompute-certify-local_leopard.whitelist	1970-01-01 00:00:00 +0000
+++ whitelists/opencompute-certify-local_leopard.whitelist	2015-08-14 22:03:31 +0000
@@ -0,0 +1,48 @@
+# Resource jobs
+miscellanea/submission-resources
+#Info attachment jobs
+__info__
+cpuinfo_attachment
+dmesg_attachment
+dmi_attachment
+dmidecode_attachment
+efi_attachment
+lspci_attachment
+lshw_attachment
+mcelog_attachment
+meminfo_attachment
+modprobe_attachment
+modules_attachment
+sysctl_attachment
+sysfs_attachment
+udev_attachment
+lsmod_attachment
+acpi_sleep_attachment
+info/hdparm
+info/hdparm_.*.txt
+installer_debug.gz
+info/disk_partitions
+# Actual test cases
+__TC-005-0001-CPU_Memory__
+TC-005-0001-001/CPU_Information
+TC-005-0001-002/Processor_Topology
+TC-005-0001-003/Memory_Information
+__TC-005-0002-Platform_Controller_Hub__
+TC-005-0002-001/SATA_Port
+TC-005-0002-002/USB_Port
+TC-005-0002-003/mSATA_Port
+__TC-005-0006-Sensors_Monitoring__
+TC-005-0006-001/In-band_Sensors_Monitoring
+TC-005-0006-003/Thermal_Monitoring
+TC-005-0006-004/Power_Monitoring
+__TC-006-0010-System_Log__
+TC-006-0010-002/System_Log_Hardware_Error
+TC-006-0010-003/System_Log_PET_Format
+__TC-007-0001-System_Information__
+TC-007-0001-001/Disk_Information
+TC-007-0001-002/BIOS_Information
+TC-007-0001-003/NIC_Information
+TC-007-0001-004/RAID_Card_Information
+__TC-007-0003-Hard_Disk_Drive__
+TC-007-0003-001/HDD_Healthiness
+TC-007-0003-001/HDD_Healthiness.*

=== added file 'whitelists/opencompute-certify-raid0.whitelist'
--- whitelists/opencompute-certify-raid0.whitelist	1970-01-01 00:00:00 +0000
+++ whitelists/opencompute-certify-raid0.whitelist	2015-08-14 22:03:31 +0000
@@ -0,0 +1,29 @@
+# Resource jobs
+miscellanea/submission-resources
+#Info attachment jobs
+__info__
+cpuinfo_attachment
+dmesg_attachment
+dmi_attachment
+dmidecode_attachment
+efi_attachment
+lspci_attachment
+lshw_attachment
+mcelog_attachment
+meminfo_attachment
+modprobe_attachment
+modules_attachment
+sysctl_attachment
+sysfs_attachment
+udev_attachment
+lsmod_attachment
+acpi_sleep_attachment
+info/hdparm
+info/hdparm_.*.txt
+installer_debug.gz
+info/disk_partitions
+# Actual test cases
+__TC-004-0001-JBOD_Testing__
+TC-004-0002-001/Get_all_HDD
+TC-004-0003-002/Build_raid_0
+TC-004-0004-002/RAID_0_availability_test

=== added file 'whitelists/opencompute-certify-raid0_leopard.whitelist'
--- whitelists/opencompute-certify-raid0_leopard.whitelist	1970-01-01 00:00:00 +0000
+++ whitelists/opencompute-certify-raid0_leopard.whitelist	2015-08-14 22:03:31 +0000
@@ -0,0 +1,29 @@
+# Resource jobs
+miscellanea/submission-resources
+#Info attachment jobs
+__info__
+cpuinfo_attachment
+dmesg_attachment
+dmi_attachment
+dmidecode_attachment
+efi_attachment
+lspci_attachment
+lshw_attachment
+mcelog_attachment
+meminfo_attachment
+modprobe_attachment
+modules_attachment
+sysctl_attachment
+sysfs_attachment
+udev_attachment
+lsmod_attachment
+acpi_sleep_attachment
+info/hdparm
+info/hdparm_.*.txt
+installer_debug.gz
+info/disk_partitions
+# Actual test cases
+__TC-007-0005-JBOD_Testing__
+TC-007-0005-001/Get_All_HDDs
+TC-007-0005-003/Build_RAID_0
+TC-007-0005-005/RAID_0_Availability_Test

=== added file 'whitelists/opencompute-certify-raid6.whitelist'
--- whitelists/opencompute-certify-raid6.whitelist	1970-01-01 00:00:00 +0000
+++ whitelists/opencompute-certify-raid6.whitelist	2015-08-14 22:03:31 +0000
@@ -0,0 +1,31 @@
+# Resource jobs
+miscellanea/submission-resources
+#Info attachment jobs
+__info__
+cpuinfo_attachment
+dmesg_attachment
+dmi_attachment
+dmidecode_attachment
+efi_attachment
+lspci_attachment
+lshw_attachment
+mcelog_attachment
+meminfo_attachment
+modprobe_attachment
+modules_attachment
+sysctl_attachment
+sysfs_attachment
+udev_attachment
+lsmod_attachment
+acpi_sleep_attachment
+info/hdparm
+info/hdparm_.*.txt
+installer_debug.gz
+info/disk_partitions
+# Actual test cases
+__TC-004-0001-JBOD_Testing__
+TC-004-0001-001/RAID_card_information
+TC-004-0002-001/Get_all_HDD
+TC-004-0003-001/Build_raid_6
+TC-004-0004-001/RAID_6_availability_test
+TC-004-0005-001/Rebuild_Raid

=== added file 'whitelists/opencompute-certify-raid6_leopard.whitelist'
--- whitelists/opencompute-certify-raid6_leopard.whitelist	1970-01-01 00:00:00 +0000
+++ whitelists/opencompute-certify-raid6_leopard.whitelist	2015-08-14 22:03:31 +0000
@@ -0,0 +1,30 @@
+# Resource jobs
+miscellanea/submission-resources
+#Info attachment jobs
+__info__
+cpuinfo_attachment
+dmesg_attachment
+dmi_attachment
+dmidecode_attachment
+efi_attachment
+lspci_attachment
+lshw_attachment
+mcelog_attachment
+meminfo_attachment
+modprobe_attachment
+modules_attachment
+sysctl_attachment
+sysfs_attachment
+udev_attachment
+lsmod_attachment
+acpi_sleep_attachment
+info/hdparm
+info/hdparm_.*.txt
+installer_debug.gz
+info/disk_partitions
+# Actual test cases
+__TC-007-0005-JBOD_Testing__
+TC-007-0005-001/Get_All_HDDs
+TC-007-0005-002/Build_RAID_6
+TC-007-0005-004/RAID_6_Availability_Test
+TC-007-0005-006/Rebuild_RAID_6

=== added file 'whitelists/opencompute-certify-remoteBMC_leopard.whitelist'
--- whitelists/opencompute-certify-remoteBMC_leopard.whitelist	1970-01-01 00:00:00 +0000
+++ whitelists/opencompute-certify-remoteBMC_leopard.whitelist	2015-08-14 22:03:31 +0000
@@ -0,0 +1,42 @@
+# Resource jobs
+miscellanea/submission-resources
+#Info attachment jobs
+__info__
+cpuinfo_attachment
+dmesg_attachment
+dmi_attachment
+dmidecode_attachment
+efi_attachment
+lspci_attachment
+lshw_attachment
+mcelog_attachment
+meminfo_attachment
+modprobe_attachment
+modules_attachment
+sysctl_attachment
+sysfs_attachment
+udev_attachment
+lsmod_attachment
+acpi_sleep_attachment
+info/hdparm
+info/hdparm_.*.txt
+installer_debug.gz
+info/disk_partitions
+# Actual test cases
+__TC-005-0006-Sensors_Monitoring__
+TC-005-0006-002/OOB_Sensors_Monitoring
+__TC-005-0009-Power_Policy__
+TC-005-0009-001/last-state
+TC-005-0009-021/always-on
+TC-005-0009-003/always-off
+__TC-006-0002-Management_Node_Identifier__
+TC-006-0002-001/Management_Node_Identifier
+__TC-006-0003-Rights_and_Credentials__
+TC-006-0003-001/BMC_Default_Credential_Validation
+TC-006-0003-002/BMC_Default_Credential_Change
+__TC-006-0009-Inventory__
+TC-006-0009-001/Inventory_Infomation
+TC-006-0009-002/FRU
+__TC-006-0010-System_Log__
+TC-006-0010-001/System_Log_Entries
+

=== modified file 'whitelists/opencompute-certify-remoteME.whitelist'
--- whitelists/opencompute-certify-remoteME.whitelist	2015-03-06 21:47:21 +0000
+++ whitelists/opencompute-certify-remoteME.whitelist	2015-08-14 22:03:31 +0000
@@ -21,5 +21,12 @@
 installer_debug.gz
 info/disk_partitions
 # Actual test cases
-__TC-002__
+__TC-001-0008-Out_of_band_Platform_Controller_Hub_Management_Engine__
+TC-001-0008-001/Out_of_band_Power_and_Thermal_Monitoring
+__TC-002-0010-Inventory__
+__TC-002-0007-Power_Draw__
+TC-002-0007-001/Power_Draw
+__TC-002-0010-Inventory__
+TC-002-0010-002/FRU
+__TC-002-0011-System_Log__
 TC-002-0011-001/System_Log_Entries

=== added file 'whitelists/opencompute-certify-remotePC.whitelist'
--- whitelists/opencompute-certify-remotePC.whitelist	1970-01-01 00:00:00 +0000
+++ whitelists/opencompute-certify-remotePC.whitelist	2015-08-14 22:03:31 +0000
@@ -0,0 +1,32 @@
+# Resource jobs
+miscellanea/submission-resources
+#Info attachment jobs
+__info__
+cpuinfo_attachment
+dmesg_attachment
+dmi_attachment
+dmidecode_attachment
+efi_attachment
+lspci_attachment
+lshw_attachment
+mcelog_attachment
+meminfo_attachment
+modprobe_attachment
+modules_attachment
+sysctl_attachment
+sysfs_attachment
+udev_attachment
+lsmod_attachment
+acpi_sleep_attachment
+info/hdparm
+info/hdparm_.*.txt
+installer_debug.gz
+info/disk_partitions
+# Actual test cases
+__TC-002-0006-Remotely_Power_Control__
+TC-002-0006-001/Remotely_Power_Off_and_On
+TC-002-0006-002/Remotely_Power_Reset
+__TC-002-0009-User_Levels__
+TC-002-0009-001/BMC_Account_Privilege_Verify-User
+TC-002-0009-002/BMC_Account_Privilege_Verify-Operator
+TC-002-0009-003/BMC_Account_Privilege_Verify-Administrator

=== added file 'whitelists/opencompute-certify-remotePC_leopard.whitelist'
--- whitelists/opencompute-certify-remotePC_leopard.whitelist	1970-01-01 00:00:00 +0000
+++ whitelists/opencompute-certify-remotePC_leopard.whitelist	2015-08-14 22:03:31 +0000
@@ -0,0 +1,34 @@
+# Resource jobs
+miscellanea/submission-resources
+#Info attachment jobs
+__info__
+cpuinfo_attachment
+dmesg_attachment
+dmi_attachment
+dmidecode_attachment
+efi_attachment
+lspci_attachment
+lshw_attachment
+mcelog_attachment
+meminfo_attachment
+modprobe_attachment
+modules_attachment
+sysctl_attachment
+sysfs_attachment
+udev_attachment
+lsmod_attachment
+acpi_sleep_attachment
+info/hdparm
+info/hdparm_.*.txt
+installer_debug.gz
+info/disk_partitions
+# Actual test cases
+__TC-006-0006-Remotely_Power_Control__
+TC-006-0006-001/Remotely_Power_Off_and_On
+TC-006-0006-002/Remotely_Hard_Reset
+TC-006-0006-003/Remotely_Warm_Reboot
+__TC-006-0008-User_Levels__
+TC-006-0008-001/Verify_BMC_Account_Privilege-User
+TC-006-0008-002/Verify_BMC_Account_Privilege-Operator
+TC-006-0008-003/Verify_BMC_Account_Privilege-Administrator
+

=== added file 'whitelists/opencompute-certify-stress.whitelist'
--- whitelists/opencompute-certify-stress.whitelist	1970-01-01 00:00:00 +0000
+++ whitelists/opencompute-certify-stress.whitelist	2015-08-14 22:03:31 +0000
@@ -0,0 +1,32 @@
+# Resource jobs
+miscellanea/submission-resources
+#Info attachment jobs
+__info__
+cpuinfo_attachment
+dmesg_attachment
+dmi_attachment
+dmidecode_attachment
+efi_attachment
+lspci_attachment
+lshw_attachment
+mcelog_attachment
+meminfo_attachment
+modprobe_attachment
+modules_attachment
+sysctl_attachment
+sysfs_attachment
+udev_attachment
+lsmod_attachment
+acpi_sleep_attachment
+info/hdparm
+info/hdparm_.*.txt
+installer_debug.gz
+info/disk_partitions
+# Actual test cases
+__TC-003-0004-Disk_Healthiness__
+TC-003-0004-001/Disk_Health
+TC-003-0004-001/Disk_Health.*
+TC-003-0004-002/Bad_block_test
+TC-003-0004-002/Bad_block_test.*
+__TC-003-0005-System_Stress__
+TC-003-0005-001/System_stress

=== added file 'whitelists/opencompute-certify-stressBMC_leopard.whitelist'
--- whitelists/opencompute-certify-stressBMC_leopard.whitelist	1970-01-01 00:00:00 +0000
+++ whitelists/opencompute-certify-stressBMC_leopard.whitelist	2015-08-14 22:03:31 +0000
@@ -0,0 +1,27 @@
+# Resource jobs
+miscellanea/submission-resources
+#Info attachment jobs
+__info__
+cpuinfo_attachment
+dmesg_attachment
+dmi_attachment
+dmidecode_attachment
+efi_attachment
+lspci_attachment
+lshw_attachment
+mcelog_attachment
+meminfo_attachment
+modprobe_attachment
+modules_attachment
+sysctl_attachment
+sysfs_attachment
+udev_attachment
+lsmod_attachment
+acpi_sleep_attachment
+info/hdparm
+info/hdparm_.*.txt
+installer_debug.gz
+info/disk_partitions
+# Actual test cases
+__TC-006-0007-Temperature__
+TC-006-0007-001/Temp_Sampling_Increment

=== added file 'whitelists/opencompute-certify-stressME.whitelist'
--- whitelists/opencompute-certify-stressME.whitelist	1970-01-01 00:00:00 +0000
+++ whitelists/opencompute-certify-stressME.whitelist	2015-08-14 22:03:31 +0000
@@ -0,0 +1,28 @@
+# Resource jobs
+miscellanea/submission-resources
+#Info attachment jobs
+__info__
+cpuinfo_attachment
+dmesg_attachment
+dmi_attachment
+dmidecode_attachment
+efi_attachment
+lspci_attachment
+lshw_attachment
+mcelog_attachment
+meminfo_attachment
+modprobe_attachment
+modules_attachment
+sysctl_attachment
+sysfs_attachment
+udev_attachment
+lsmod_attachment
+acpi_sleep_attachment
+info/hdparm
+info/hdparm_.*.txt
+installer_debug.gz
+info/disk_partitions
+# Actual test cases
+__TC-002-0008-Temperature__
+TC-002-0008-001/Temp_Sampling_Increment
+

=== added file 'whitelists/opencompute-certify-stress_leopard.whitelist'
--- whitelists/opencompute-certify-stress_leopard.whitelist	1970-01-01 00:00:00 +0000
+++ whitelists/opencompute-certify-stress_leopard.whitelist	2015-08-14 22:03:31 +0000
@@ -0,0 +1,32 @@
+# Resource jobs
+miscellanea/submission-resources
+#Info attachment jobs
+__info__
+cpuinfo_attachment
+dmesg_attachment
+dmi_attachment
+dmidecode_attachment
+efi_attachment
+lspci_attachment
+lshw_attachment
+mcelog_attachment
+meminfo_attachment
+modprobe_attachment
+modules_attachment
+sysctl_attachment
+sysfs_attachment
+udev_attachment
+lsmod_attachment
+acpi_sleep_attachment
+info/hdparm
+info/hdparm_.*.txt
+installer_debug.gz
+info/disk_partitions
+# Actual test cases
+__TC-007-0003-Hard_Disk_Drive__
+TC-007-0003-001/HDD_Healthiness
+TC-007-0003-001/HDD_Healthiness.*
+TC-007-0003-002/Bad_block_test
+TC-007-0003-002/Bad_block_test.*
+__TC-007-0004-System_Idle_and_Stress_Test__
+TC-007-0004-002/System_Stress

=== modified file 'whitelists/sample-normal.whitelist'
--- whitelists/sample-normal.whitelist	2015-02-23 22:46:57 +0000
+++ whitelists/sample-normal.whitelist	2015-08-14 22:03:31 +0000
@@ -1,2 +1,28 @@
+# Resource jobs
+miscellanea/submission-resources
+#Info attachment jobs
+__info__
+cpuinfo_attachment
+dmesg_attachment
+dmi_attachment
+dmidecode_attachment
+efi_attachment
+lspci_attachment
+lshw_attachment
+mcelog_attachment
+meminfo_attachment
+modprobe_attachment
+modules_attachment
+sysctl_attachment
+sysfs_attachment
+udev_attachment
+lsmod_attachment
+acpi_sleep_attachment
+info/hdparm
+info/hdparm_.*.txt
+installer_debug.gz
+info/disk_partitions
+# Actual test cases
+__TC-000-0000-DESCRIPTOR__
 # use regular expression to select all normal jobs
-examples/normal/.*
\ No newline at end of file
+examples/normal/.*


References