#!/usr/bin/env python3
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
#
# $Source: op-test-framework/testcases/OpTestOCC.py $
#
# OpenPOWER Automated Test Project
#
# Contributors Listed Below - COPYRIGHT 2015
# [+] International Business Machines Corp.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied. See the License for the specific language governing
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG
'''
OpTestOCC
---------
OCC Control package for OpenPower testing.
This class will test the functionality of following.
1. OCC Reset\Enable\Disable
'''
import time
import subprocess
import re
import sys
import os
import random
from common.OpTestConstants import OpTestConstants as BMC_CONST
import unittest
import OpTestConfiguration
from common.OpTestError import OpTestError
from common.OpTestSystem import OpSystemState
from common.Exceptions import CommandFailed
import testcases.OpTestEM
import logging
import OpTestLogger
log = OpTestLogger.optest_logger_glob.get_logger(__name__)
class OpTestOCCBase(testcases.OpTestEM.OpTestEM):
def setUp(self):
conf = OpTestConfiguration.conf
self.cv_IPMI = conf.ipmi()
self.cv_SYSTEM = conf.system()
self.cv_HOST = conf.host()
self.cv_FSP = conf.bmc()
self.platform = conf.platform()
self.bmc_type = conf.args.bmc_type
self.rest = conf.system().rest
self.cv_SYSTEM.goto_state(OpSystemState.OS)
self.c = self.cv_SYSTEM.cv_HOST.get_ssh_connection() # use ssh, console is chatty
if "OpenBMC" in self.bmc_type:
self.occ_ids = self.rest.get_occ_ids()
def do_occ_reset_fsp(self):
cmd = "tmgtclient --reset_occ_clear=0xFF; echo $?"
res = self.cv_FSP.fspc.run_command(cmd)
self.assertEqual(int(res[-1]), 0, "occ reset command failed from fsp")
def do_occ_reset(self):
try:
log.debug("OPAL-PRD: OCC Enable")
self.c.run_command(BMC_CONST.OCC_ENABLE)
log.debug("OPAL-PRD: OCC DISABLE")
self.c.run_command(BMC_CONST.OCC_DISABLE)
log.debug("OPAL-PRD: OCC Enable")
self.c.run_command(BMC_CONST.OCC_ENABLE)
log.debug("OPAL-PRD: OCC RESET")
self.c.run_command(BMC_CONST.OCC_RESET)
except Exception as e:
log.debug("Unexpected problem, Exception={}".format(e))
self.assertTrue(
False, "Unexpected problem, Exception={}".format(e))
def clear_occ_rr_count(self):
# Clear the OCC reset reload count
try:
log.debug("OPAL-PRD: occ query reset reload count")
self.c.run_command(BMC_CONST.OCC_QUERY_RESET_COUNTS)
log.debug("OPAL-PRD: occ reset reset/reload count")
self.c.run_command(BMC_CONST.OCC_SET_RESET_RELOAD_COUNT)
log.debug("OPAL-PRD: occ query reset reload count")
self.c.run_command(BMC_CONST.OCC_QUERY_RESET_COUNTS)
except Exception as e:
log.debug("Unexpected problem, Exception={}".format(e))
self.assertTrue(
False, "Unexpected problem, Exception={}".format(e))
def check_occ_status(self):
'''
This function is used to get OCC status enable/disable.
@return BMC_CONST.FW_SUCCESS - OCC's are active or
BMC_CONST.FW_FAILED - OCC's are not in active state
'''
if "OpenBMC" in self.bmc_type:
for id in self.occ_ids:
if not self.rest.is_occ_active(id):
return BMC_CONST.FW_FAILED
return BMC_CONST.FW_SUCCESS
l_status = self.cv_IPMI.ipmi_get_occ_status()
log.debug(l_status)
if BMC_CONST.OCC_DEVICE_ENABLED in l_status:
log.debug("OCC's are up and active")
return BMC_CONST.FW_SUCCESS
else:
log.warning("OCC's are not in active state")
return BMC_CONST.FW_FAILED
def get_cpu_freq(self):
l_cmd = "cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq"
cur_freq = self.c.run_command(l_cmd)
return cur_freq[0].strip()
def dvfs_test(self):
freq_list = self.get_list_of_cpu_freq()
self.set_cpu_gov("userspace")
self.verify_cpu_gov("userspace")
for i in range(1, 20):
i_freq = random.choice(freq_list)
self.set_cpu_freq(i_freq)
try:
self.verify_cpu_freq(i_freq, and_measure=False)
except AssertionError as ae:
log.debug(str(ae))
def set_and_get_cpu_freq(self):
freq_list = self.get_list_of_cpu_freq()
self.set_cpu_gov("userspace")
self.verify_cpu_gov("userspace")
i_freq = random.choice(freq_list)
self.set_cpu_freq(i_freq)
cur_freq = self.get_cpu_freq() # Only cpu0 frequency
return cur_freq
def tearDown(self):
try:
pass
# self.cv_HOST.host_gather_opal_msg_log()
# self.cv_HOST.host_gather_kernel_log()
except:
log.debug("Failed to collect debug info")
[docs]class OpTestOCCBasic(OpTestOCCBase, unittest.TestCase):
# Check basic test of occ disable when system is in standby
# and occ enable when it is in runtime
def test_occ_active(self):
if any(s in self.bmc_type for s in ("FSP", "QEMU")):
self.skipTest("OpenPower OCC Reset test")
if self.cv_SYSTEM.get_state() in [OpSystemState.PETITBOOT, OpSystemState.PETITBOOT_SHELL,
OpSystemState.BOOTING, OpSystemState.OS]:
self.assertNotEqual(self.check_occ_status(), BMC_CONST.FW_FAILED,
"OCC's are not in active state")
elif self.cv_SYSTEM.get_state() == OpSystemState.OFF:
self.assertNotEqual(self.check_occ_status(), BMC_CONST.FW_SUCCESS,
"OCC's are still in active state")
[docs]class OpTestOCC(OpTestOCCBase, unittest.TestCase):
def _test_occ_reset(self):
if any(s in self.bmc_type for s in ("FSP", "QEMU")):
self.skipTest("OpenPower OCC Reset test")
self.assertNotEqual(self.check_occ_status(), BMC_CONST.FW_FAILED,
"OCC's are not in active state")
cur_freq = self.set_and_get_cpu_freq()
self.do_occ_reset()
tries = 10
for j in range(1, tries):
log.debug("Waiting for OCC Enable\Disable (%d\%d)" % (j, tries))
time.sleep(10)
rc = self.check_occ_status()
if rc == BMC_CONST.FW_SUCCESS:
break
if rc == BMC_CONST.FW_FAILED:
self.cv_SYSTEM.set_state(OpSystemState.UNKNOWN)
self.assertNotEqual(rc, BMC_CONST.FW_FAILED,
"OCC's are not in active state")
# verify pstate restored to last requested pstate before occ reset
# Make the fail less noisy, as it is less priority one
try:
self.verify_cpu_freq(cur_freq, and_measure=False)
except AssertionError as ae:
log.debug(str(ae))
self.dvfs_test()
[docs]class OpTestOCCFull(OpTestOCCBase, unittest.TestCase):
'''
This function is used to test OCC Reset funtionality in BMC based systems.
OCC Reset reload is limited to 3 times per full power cycle.
'''
def test_occ_reset_functionality(self):
if any(s in self.bmc_type for s in ("FSP", "QEMU")):
self.skipTest("OpenPower OCC Reset test")
self.assertNotEqual(self.check_occ_status(), BMC_CONST.FW_FAILED,
"OCC's are not in active state")
self.clear_occ_rr_count()
max_reset_count = 4
for i in range(1, max_reset_count+1):
log.debug(
"*******************OCC Reset count %d*******************" % i)
cur_freq = self.set_and_get_cpu_freq()
self.do_occ_reset()
tries = 30
for j in range(1, tries):
log.debug("Waiting for OCC Enable\Disable (%d\%d)" %
(j, tries))
time.sleep(10)
rc = self.check_occ_status()
if rc == BMC_CONST.FW_SUCCESS:
break
# on 4th interation occ's will be disabled, do dvfs when occ's are active
if i < max_reset_count:
self.assertNotEqual(rc, BMC_CONST.FW_FAILED,
"OCC's are not in active state")
# verify pstate restored to last requested pstate before occ reset
try:
self.verify_cpu_freq(cur_freq, and_measure=False)
except AssertionError as ae:
log.debug(str(ae))
self.dvfs_test()
if rc == BMC_CONST.FW_FAILED:
self.cv_SYSTEM.set_state(OpSystemState.UNKNOWN)
# After max_reset_count times occ reset, occ's will be disabled
self.assertEqual(rc, BMC_CONST.FW_FAILED,
"OCC's are still in active state after max occ reset count %s" % max_reset_count)
log.debug("OCC\'s are not in active state, rebooting the system")
self.cv_SYSTEM.goto_state(OpSystemState.OFF)
[docs] def test_occ_reset_n_times(self):
'''
This function is used to test OCC Reset funtionality in BMC based systems.
OCC Reset reload can be done more than 3 times per full power cycle, by
resetting OCC resetreload count.
'''
if any(s in self.bmc_type for s in ("FSP", "QEMU")):
self.skipTest("OpenPower OCC Reset test")
self.assertNotEqual(self.check_occ_status(), BMC_CONST.FW_FAILED,
"OCC's are not in active state")
for i in range(1, BMC_CONST.OCC_RESET_RELOAD_COUNT):
log.debug(
"*******************OCC Reset count %d*******************" % i)
self.do_occ_reset()
tries = 30
for j in range(1, tries):
time.sleep(10)
log.debug("Waiting for OCC Enable\Disable (%d\%d)" %
(j, tries))
rc = self.check_occ_status()
if rc == BMC_CONST.FW_SUCCESS:
break
if rc == BMC_CONST.FW_FAILED:
self.cv_SYSTEM.set_state(OpSystemState.UNKNOWN)
self.assertNotEqual(rc, BMC_CONST.FW_FAILED,
"OCC's are not in active state")
self.dvfs_test()
self.clear_occ_rr_count()
[docs] def test_occ_enable_disable_functionality(self):
'''
This function is used to test OCC Enable and Disable funtionality in BMC based systems.
There is no limit for occ enable and disable, as of now doing 10 times in a loop.
'''
if any(s in self.bmc_type for s in ("FSP", "QEMU")):
self.skipTest("OpenPower OCC Reset test")
self.assertNotEqual(self.check_occ_status(), BMC_CONST.FW_FAILED,
"OCC's are not in active state")
for count in range(1, 7):
try:
log.debug("OPAL-PRD: OCC Enable")
self.c.run_command(BMC_CONST.OCC_ENABLE)
log.debug("OPAL-PRD: OCC Disable")
self.c.run_command(BMC_CONST.OCC_DISABLE)
log.debug("OPAL-PRD: OCC Enable")
self.c.run_command(BMC_CONST.OCC_ENABLE)
except Exception as e:
log.debug("Unexpected problem, Exception={}".format(e))
self.assertTrue(
False, "Unexpected problem, Exception={}".format(e))
tries = 12
for i in range(1, tries):
log.debug("Waiting for OCC Enable\Disable (%d\%d)" %
(i, tries))
time.sleep(10)
rc = self.check_occ_status()
if rc == BMC_CONST.FW_SUCCESS:
break
# If occ's are disabled re-IPL the system
if rc == BMC_CONST.FW_FAILED:
self.cv_SYSTEM.set_state(OpSystemState.UNKNOWN)
self.dvfs_test()
[docs]class OCCRESET_FSP(OpTestOCCBase, unittest.TestCase):
def runTest(self):
if "FSP" not in self.bmc_type:
self.skipTest("FSP OCC Reset test")
count = 10
for i in range(1, count+1):
self.c.run_command("dmesg -C")
cur_freq = self.set_and_get_cpu_freq()
self.do_occ_reset_fsp()
tries = 50
recovered = False
for j in range(1, tries):
log.debug("Waiting for OCC Active (%d\%d)" % (j, tries))
time.sleep(1)
try:
res = self.c.run_command("dmesg | grep -i 'OCC Active'")
recovered = True
break
except CommandFailed as cf:
pass
self.assertTrue(
recovered, "OCC's are not in active state or reset notification to host is failed")
# verify pstate restored to last requested pstate before occ reset
self.verify_cpu_freq(cur_freq, and_measure=False)
self.dvfs_test()
[docs]class OCC_RESET(OpTestOCC, unittest.TestCase):
def runTest(self):
self._test_occ_reset()
def basic_suite():
return unittest.defaultTestLoader.loadTestsFromTestCase(OpTestOCCBasic)
def full_suite():
return unittest.defaultTestLoader.loadTestsFromTestCase(OpTestOCCFull)