opencompute-developers team mailing list archive
-
opencompute-developers team
-
Mailing list archive
-
Message #00399
[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