/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* $Source: src/usr/targeting/common/test/testcommontargeting.H $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2012,2018 */ /* [+] Google Inc. */ /* [+] 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 */ #ifndef __TARGETING_COMMON_TESTCOMMONTARGETING_H #define __TARGETING_COMMON_TESTCOMMONTARGETING_H /** * @file targeting/common/test/testtargeting.H * * @brief All common unit tests for the targeting infrastructure */ //****************************************************************************** // Includes //****************************************************************************** // STD #include #include // CXXTEST #include // This component #include #include #include "unittest.H" namespace TARGETING { extern void dumpAllAttributes(TARG_TD_t,uint32_t); extern TARG_TD_t g_trac_targeting; }; class CommonTargetingTestSuite: public CxxTest::TestSuite { public: /** * @brief Test a portion of the debug code which * prints out the entity path types */ void testEntityPathElementTypeAsString() { #ifndef CONTEXT_x86_nfp // test_ep.H is generated by xmltohb.pl #include #endif } /** * @brief Test the TargetService class (except debug cases) */ void testTargetServiceClass() { //@fixme - found a Data Storage Exception that needs to be fixed (Task // RTC 35625) return; TARG_TS_TRACE(ENTER_MRK "testTargetServiceClass" ); using namespace TARGETING; TargetService& l_targetService = targetService(); l_targetService.init(); // Post init // Test: void masterProcChipTarget( // TargetHandleList& o_masterProcChipTarget) const; Target* l_pMasterProcChipTargetHandle = NULL; (void) l_targetService.masterProcChipTargetHandle( l_pMasterProcChipTargetHandle); if ( l_pMasterProcChipTargetHandle == MASTER_PROCESSOR_CHIP_TARGET_SENTINEL) { TARG_TS_FAIL("Post init; master proc chip target handle should not " "be the sentinel value"); } if (l_pMasterProcChipTargetHandle == NULL) { TARG_TS_FAIL("Post init; master proc chip target handle should not " "be the NULL value"); } ScomSwitches l_switches = {0}; l_switches = l_pMasterProcChipTargetHandle->getAttr(); if( l_switches.useFsiScom != 0 || l_switches.useXscom != 1 || l_switches.useInbandScom != 0 || l_switches.useSbeScom != 0 || l_switches.reserved != 0) { TARG_TS_FAIL("SCOM Switches stuct was not correct (%d, %d, %d, %d, %d)", l_switches.useFsiScom, l_switches.useXscom, l_switches.useInbandScom,l_switches.useSbeScom, l_switches.reserved); } if ( l_pMasterProcChipTargetHandle->getAttr () != CLASS_CHIP) { TARG_TS_FAIL("Post init; master proc chip target handle was not of " "chip class"); } if ( l_pMasterProcChipTargetHandle->getAttr () != TYPE_PROC) { TARG_TS_FAIL("Post init; master proc chip target handle was not of " "proc type"); } // Post init // Test: void getTopLevelTarget(Target*& o_targetHandle) const; Target* l_pTopLevel = NULL; (void) l_targetService.getTopLevelTarget(l_pTopLevel); if (l_pTopLevel == NULL) { TARG_TS_FAIL("Top level handle was NULL when initialization " "complete"); } if (l_pTopLevel->getAttr () != CLASS_SYS) { TARG_TS_FAIL("Post init; top level target class != CLASS_SYS"); } // Post init // Test: void exists( // const EntityPath& i_entityPath, // bool& o_exists) const; bool l_exists = false; (void) l_targetService.exists( l_pTopLevel->getAttr (), l_exists); if (l_exists != true) { TARG_TS_FAIL("Expected top level target to exist"); } // Post init // Test: Target* toTarget( // const EntityPath& i_entityPath) const; Target* l_pInverseTarget = NULL; l_pInverseTarget = l_targetService.toTarget( l_pTopLevel->getAttr ()); if (l_pInverseTarget != l_pTopLevel) { TARG_TS_FAIL("Expected to get the original target"); } // Post init // Tested API: Target* toTarget( // const EntityPath& i_entityPath) const; // Behavior: Given an arbitrary target, I should be able to take its // affinity path and convert it to the original target PredicateCTM mbaPredicate(CLASS_UNIT,TYPE_MBA); TargetRangeFilter mbaFilter( targetService().begin(), targetService().end(), &mbaPredicate); for(;mbaFilter;++mbaFilter) { Target* pCandidate = l_targetService.toTarget( mbaFilter->getAttr()); if (pCandidate != *mbaFilter) { TARG_TS_FAIL("Failed to convert MBA target's affinity path " "back to original target"); } break; } // Post init // Test: void getAssociated( // const Target* i_pTarget, // ASSOCIATION_TYPE i_type, // RECURSION_LEVEL i_recursionLevel, // TargetHandleList& o_list) const; TargetHandleList l_list; (void) l_targetService.getAssociated( l_list, l_pTopLevel, TARGETING::TargetService::CHILD, TARGETING::TargetService::IMMEDIATE); if (!l_list.size()) { TARG_TS_FAIL("Should have found some child elements" ); } // Verify child of given target has a parent that is the original // target TargetHandleList l_parentList; (void) l_targetService.getAssociated( l_parentList, l_list[0], TARGETING::TargetService::PARENT, TARGETING::TargetService::IMMEDIATE); if (l_parentList.size() != 1) { TARG_TS_FAIL("Should have found a parent element" ); } if (l_parentList[0] != l_pTopLevel) { TARG_TS_FAIL("Parent handle should have matched original target " "handle" ); } (void) l_targetService.getAssociated( l_list, l_pTopLevel, TARGETING::TargetService::CHILD_BY_AFFINITY, TARGETING::TargetService::IMMEDIATE); if (!l_list.size()) { TARG_TS_FAIL("Should have found some child elements" ); } (void) l_targetService.getAssociated( l_list, l_pTopLevel, TARGETING::TargetService::CHILD_BY_AFFINITY, TARGETING::TargetService::ALL); if (!l_list.size()) { TARG_TS_FAIL("Should have found more child elements" ); } l_targetService.dump(); TARG_TS_TRACE(EXIT_MRK "testTargetServiceClass" ); } /** * @test Tests the EntityPath class (except debug cases) */ void testEntityPathClass(void) { TARG_TS_TRACE(ENTER_MRK "testEntityPathClass" ); using namespace TARGETING; EntityPath l_defaultPath; if(l_defaultPath.size() != 0) { TARG_TS_FAIL("Default entity path's size was not 0"); } if(l_defaultPath.type() != EntityPath::PATH_NA) { TARG_TS_FAIL("Default entity path's type was not PATH_NA"); } EntityPath l_nonDefaultPath(EntityPath::PATH_PHYSICAL); if(l_nonDefaultPath.size() != 0) { TARG_TS_FAIL("Non-default entity path's size was not 0"); } if(l_nonDefaultPath.type() != EntityPath::PATH_PHYSICAL) { TARG_TS_FAIL("Non-default entity path's type was not " "EntityPath::PATH_PHYSICAL"); } l_defaultPath.setType(EntityPath::PATH_AFFINITY); if(l_defaultPath.type() != EntityPath::PATH_AFFINITY) { TARG_TS_FAIL("Default entity path's type was not " "EntityPath::PATH_AFFINITY after setting"); } l_defaultPath.setType(EntityPath::PATH_PHYSICAL); if(!(l_defaultPath == l_nonDefaultPath)) { TARG_TS_FAIL("Default entity path should have been equal to " "the non-default entity path"); } if(!l_defaultPath.equals(l_nonDefaultPath,0)) { TARG_TS_FAIL("Default entity path should have been equal to " "the non-default entity path (equals API)"); } l_defaultPath.addLast(TYPE_PROC,0); if(l_defaultPath == l_nonDefaultPath) { TARG_TS_FAIL("Default entity path should NOT have been equal to " "the non-default entity path"); } if(l_defaultPath.equals(l_nonDefaultPath,1)) { TARG_TS_FAIL("Default entity path should NOT have been equal to " "the non-default entity path (equals API, comparing 1 " "element)"); } if(l_defaultPath.size() != 1) { TARG_TS_FAIL("Default entity path should have had one path element" "after adding PROC0"); } l_nonDefaultPath.addLast(TYPE_PROC,0); if(! (l_defaultPath == l_nonDefaultPath) ) { TARG_TS_FAIL("Default entity path should have been equal to " "the non-default entity path since they now" "both have the same 1 path element"); } l_defaultPath.addLast(TYPE_MBA,1).addLast(TYPE_L4,2); if(l_defaultPath.size() != 3) { TARG_TS_FAIL("Default entity path should have had two path elements" "after adding MBA1 and L4"); } if( (l_defaultPath[0].type != TYPE_PROC) || (l_defaultPath[0].instance != 0) || (l_defaultPath[1].type != TYPE_MBA) || (l_defaultPath[1].instance != 1) || (l_defaultPath[2].type != TYPE_L4) || (l_defaultPath[2].instance != 2)) { TARG_TS_FAIL("Default entity path should have had correct 3 path " "elements"); } l_defaultPath.removeLast(); if(l_defaultPath.size() != 2) { TARG_TS_FAIL("Default entity path should have had two path elements" "after removing L4"); } if( (l_defaultPath[0].type != TYPE_PROC) || (l_defaultPath[0].instance != 0) || (l_defaultPath[1].type != TYPE_MBA) || (l_defaultPath[1].instance != 1)) { TARG_TS_FAIL("Default entity path should have had correct 2 path " "elements"); } l_nonDefaultPath.addLast(TYPE_MBA,1).addLast(TYPE_L4,2); // Default now has proc/mba/ // Non-default now has proc/mba/l4 if(l_defaultPath == l_nonDefaultPath) { TARG_TS_FAIL("Default entity path should NOT have been equal to " "the non-default entity path since they now" "have different number of path elements"); } if( !l_defaultPath.equals(l_nonDefaultPath,2) ) { TARG_TS_FAIL("Default entity path should have been equal to " "the non-default entity path since they have the same" "first two path elements"); } l_defaultPath.removeLast().removeLast(); if(l_defaultPath.size() != 0) { TARG_TS_FAIL("Default entity path should have had no path element" "after removing MBA1 and PROC0"); } TargetService& l_targetService = targetService(); l_targetService.init(); EntityPath l_realPath(EntityPath::PATH_PHYSICAL); l_realPath.addLast(TYPE_SYS,0).addLast(TYPE_NODE,0) .addLast(TYPE_PROC,0); Target* l_pTarget = l_realPath.operator->(); if(l_pTarget == NULL) { TARG_TS_FAIL("Real entity path should have mapped to an existing " "target"); } EntityPath l_path(EntityPath::PATH_PHYSICAL); l_path.addLast(TYPE_SYS,0); EntityPath l_changedPath = l_path.copyRemoveLast(); if( (l_changedPath.size() != 0) || (l_path.size() != 1)) { TARG_TS_FAIL("Const entity path should not have been altered in " "const add test"); } l_changedPath = l_path.copyAddLast(TYPE_NODE,0); if( (l_changedPath.size() != 2) || (l_path.size() != 1)) { TARG_TS_FAIL("Const entity path should not have been altered " "in const add test"); } TARG_TS_TRACE(EXIT_MRK "testEntityPathClass" ); } /** * @test Tests the EntityPath class (except debug cases) */ void testTargetClass(void) { TARG_TS_TRACE(ENTER_MRK "testTargetClass" ); using namespace TARGETING; TargetService& l_targetService = targetService(); l_targetService.init(); EntityPath l_realPath(EntityPath::PATH_PHYSICAL); l_realPath.addLast(TYPE_SYS,0).addLast(TYPE_NODE,0) .addLast(TYPE_PROC,0); l_realPath.dump(); Target* l_pTarget = l_realPath.operator->(); if(l_pTarget == NULL) { TARG_TS_FAIL("Failed to convert entity path to initial target"); } CLASS l_class = l_pTarget->getAttr(); if(l_class != CLASS_CHIP) { TARG_TS_FAIL("Failed to get the class attribute"); } l_class = CLASS_NA; if( !l_pTarget->tryGetAttr(l_class) ) { TARG_TS_FAIL("Failed to get the class attribute"); } if(l_class != CLASS_CHIP) { TARG_TS_FAIL("Failed to try/get the class attribute"); } attrToString(l_class); uint8_t l_scom = 0; if( l_pTarget->tryGetAttr(l_scom) ) { TARG_TS_FAIL("ATTR_DUMMY_RO attribute should not have been available " "to read"); } if(l_scom != 0) { TARG_TS_FAIL("Failed ! try/get should not have set the SCOM attribute"); } l_scom = 5; if( l_pTarget->trySetAttr(l_scom) ) { TARG_TS_FAIL("ATTR_DUMMY_WO attribute should not have been available " "to write"); } if(l_scom != 5) { TARG_TS_FAIL("SCOM attribute should not have been altered in the " "failed write"); } DUMMY_RW_ATTR l_wo; memset(l_wo,0x00,sizeof(l_wo)); l_wo[0][1][2] = 6; if( !l_pTarget->trySetAttr(l_wo) ) { TARG_TS_FAIL("ATTR_DUMMY_RW should have been available for write"); } if(l_wo[0][1][2] != 6) { TARG_TS_FAIL("ATTR_DUMMY_RW local attribute should not have been " "altered in the successful write"); } DUMMY_RW_ATTR l_read; l_pTarget->tryGetAttr(l_read); if(memcmp(l_read,l_wo,sizeof(l_read))) { TARG_TS_FAIL("Failed to read back the correct ATTR_DUMMY_RW"); } DUMMY_RW_ATTR l_setWo; memset(l_setWo,0x00,sizeof(l_setWo)); l_setWo[0][2][4] = 9; l_pTarget->setAttr(l_setWo); if(l_setWo[0][2][4] != 9) { TARG_TS_FAIL("ATTR_DUMMY_RW local attribute should not have been " "altered in the successful setAttr"); } DUMMY_RW_ATTR l_setWoVerify; l_pTarget->tryGetAttr(l_setWoVerify); if(memcmp(l_setWoVerify,l_setWo,sizeof(l_setWoVerify))) { TARG_TS_FAIL("ATTR_DUMMY_RW read should have matched prior write"); } memset(l_setWo,0x05,sizeof(l_setWo)); l_pTarget->setAttr(l_setWo); TARG_TS_TRACE(EXIT_MRK "testTargetClass" ); } void testPredicateHwas() { TARG_TS_TRACE(ENTER_MRK "testPredicateHwas" ); do { using namespace TARGETING; TargetService& l_targetService = targetService(); // Get top level (system) target Target* l_pTopLevel = NULL; (void) l_targetService.getTopLevelTarget(l_pTopLevel); if (l_pTopLevel == NULL) { TARG_TS_FAIL("Top level handle was NULL when initialization " "complete"); break; } PredicateHwas hwasPredicate; ATTR_HWAS_STATE_type savedHwasState = l_pTopLevel->getAttr(); // Test: Given a target with any HWAS state, default HWAS predicate // should return a match for(size_t i=0; i<32; ++i) { ATTR_HWAS_STATE_type sweepHwasState = { static_cast(i&8), static_cast(i&4), static_cast(i&2), static_cast(i&1) }; l_pTopLevel->setAttr(sweepHwasState); if(!hwasPredicate(l_pTopLevel)) { TARG_TS_FAIL("Expected default HWAS predicate to match the " "target's HWAS state, using i = %d",i); } } // Test: Given a target with cleared HWAS state of functional, predicate // looking for functional should return false hwasPredicate.reset().functional(true); ATTR_HWAS_STATE_type nonFunctionalHwasState = {0}; l_pTopLevel->setAttr(nonFunctionalHwasState); if(hwasPredicate(l_pTopLevel)) { TARG_TS_FAIL("Expected HWAS functional predicate not to match the " "target's cleared HWAS state"); } // Test: Having previously not matched a target, resetting the HWAS // predicate should match the target again hwasPredicate.reset(); if(!hwasPredicate(l_pTopLevel)) { TARG_TS_FAIL("Expected HWAS reset predicate to match the " "target's functional HWAS state"); } // Test: Given a target with HWAS state of functional, predicate // looking for functional should return true hwasPredicate.reset().functional(true); ATTR_HWAS_STATE_type functionalHwasState = {0}; functionalHwasState.functional = true; l_pTopLevel->setAttr(functionalHwasState); if(!hwasPredicate(l_pTopLevel)) { TARG_TS_FAIL("Expected HWAS functional predicate to match the " "target's functional HWAS state"); } // Test: Given a target with HWAS state of non-functional, predicate // looking for non-functional should return true hwasPredicate.reset().functional(false); l_pTopLevel->setAttr(nonFunctionalHwasState); if(!hwasPredicate(l_pTopLevel)) { TARG_TS_FAIL("Expected HWAS non-functional predicate to match the " "target's non-functional HWAS state"); } // Test: Given a predicate looking for target whose HWAS state // exactly matches all configurable HWAS states, filter should // return true hwasPredicate.reset().poweredOn(true).present(true).functional(false); hwasPredicate.dumpFunctional(false); ATTR_HWAS_STATE_type allHwasState = {0, true,true,false,false}; l_pTopLevel->setAttr(allHwasState); if(!hwasPredicate(l_pTopLevel)) { TARG_TS_FAIL("Expected setting HWAS predicate to match the " "target's similarly configured HWAS state"); } // Test: Given a predicate looking for target whose HWAS state // exactly matches all but 1 configurable HWAS states, filter // should return false allHwasState.dumpfunctional = true; l_pTopLevel->setAttr(allHwasState); if(hwasPredicate(l_pTopLevel)) { TARG_TS_FAIL("Expected HWAS predicate not to match the target's " "all-but-1 matching HWAS state configuration"); } // Restore state. l_pTopLevel->setAttr(savedHwasState); } while(0); TARG_TS_TRACE(EXIT_MRK "testPredicateHwas" ); } void testPredicateHwasChanged() { TARG_TS_TRACE(ENTER_MRK "testPredicateHwasChanged" ); TARG_INF(ENTER_MRK "testPredicateHwasChanged" ); do { using namespace TARGETING; TargetService& l_targetService = targetService(); PredicateHwasChanged hwasChangedPredicate; // Test: Walk every possible bit combo in both polarities // on every target for (TargetIterator targ_iter = l_targetService.begin(); targ_iter != l_targetService.end(); ++targ_iter) { Target* l_pTarget = *targ_iter; // Save off flag ATTR_HWAS_STATE_CHANGED_FLAG_type savedChgState = l_pTarget->getAttr(); // Get all permutations allowed by the hwas subscription mask std::vector l_subscribed_bit_ranges; ATTR_HWAS_STATE_CHANGED_SUBSCRIPTION_MASK_type l_mask = l_pTarget->getAttr(); for (uint64_t i = 1; i <= l_mask; ++i) { // If number is contained within masked bits, then // this number is a valid setting for this mask if ((i & l_mask) == i) { l_subscribed_bit_ranges.push_back(i); } } // Now run each permutation // (note: auto keyword not supported for FSP compile) for(std::vector::iterator it = l_subscribed_bit_ranges.begin(); it != l_subscribed_bit_ranges.end(); ++it) { uint64_t l_expected_bits = *it; l_pTarget->setAttr (l_expected_bits); // Testing polarity 1 hwasChangedPredicate.reset().changedBit( static_cast(l_expected_bits), true); if(!hwasChangedPredicate(l_pTarget)) { TARG_TS_FAIL("Expected HWAS predicate to match the " "0x%.8X target's HWAS state, using 0x%.8X", get_huid(l_pTarget),l_expected_bits); } // Testing polarity 0 hwasChangedPredicate.reset().changedBit (static_cast(l_expected_bits), false); l_pTarget->setAttr (~l_expected_bits); if(!hwasChangedPredicate(l_pTarget)) { TARG_TS_FAIL("Expected HWAS predicate to match the 0x%.8X " "target's HWAS negative polarity state, using 0x%.8X", get_huid(l_pTarget),~l_expected_bits); } } // restore original HWAS_STATE_CHANGED_FLAG l_pTarget->setAttr(savedChgState); } // Get master proc chip to work with Target* l_pTarget = NULL; (void) l_targetService.masterProcChipTargetHandle(l_pTarget); if (l_pTarget == NULL) { TARG_TS_FAIL("MasterProcChipTarget handle was NULL"); break; } ATTR_HWAS_STATE_CHANGED_FLAG_type savedHwasChangedState = l_pTarget->getAttr(); // Test: Check changing non-subscribed bit. Should return false ATTR_HWAS_STATE_CHANGED_SUBSCRIPTION_MASK_type l_hwasSubscriptionMask = l_pTarget->getAttr(); if (l_hwasSubscriptionMask != 0) { // find first unsubscribed bit ATTR_HWAS_STATE_CHANGED_SUBSCRIPTION_MASK_type iBit = 1; while (iBit & l_hwasSubscriptionMask) { iBit = iBit << 1; // try next bit } // setup check for unsubscribed bit hwasChangedPredicate.reset().changedBit( static_cast(iBit), true); // set the bit l_pTarget->setAttr(iBit); if(hwasChangedPredicate(l_pTarget)) { TARG_TS_FAIL("A change to an unsubscribed bit (0x%.8X) in " "target's mask (0x%.8X) should not cause a predicate change", iBit, l_hwasSubscriptionMask); } } else { TARG_TS_FAIL("0x%.8X target has no HWAS subscription mask", get_huid(l_pTarget)); } // Location of two bits allowed to change for the target ATTR_HWAS_STATE_CHANGED_SUBSCRIPTION_MASK_type chgBit1 = 0; ATTR_HWAS_STATE_CHANGED_SUBSCRIPTION_MASK_type chgBit2 = 0; // Test: Subscribe to at least two bits and change only one. // Expect FALSE (predicate is doing exclusive match) if (l_hwasSubscriptionMask != 0) { // find first subscribed bit chgBit1 = 1; while (!(chgBit1 & l_hwasSubscriptionMask)) { chgBit1 = chgBit1 << 1; // try next bit } if (l_hwasSubscriptionMask & (~chgBit1)) { // find second subscribed bit chgBit2 = (chgBit1 << 1); while (!(chgBit2 & l_hwasSubscriptionMask)) { chgBit2 = chgBit2 << 1; } // setup check for subscribed bits hwasChangedPredicate.reset().changedBit( static_cast(chgBit1 | chgBit2), true); // set the bit l_pTarget->setAttr(chgBit1); if(hwasChangedPredicate(l_pTarget)) { TARG_TS_FAIL("A 1-bit HWAS_STATE_CHANGED_FLAG change " "(0%.8X) while monitoring 2 bits (0x%.8X) caused a " "changedPredicate", chgBit1, (chgBit1 | chgBit2)); } } else { TARG_TS_FAIL("0x%.8X target only has one bit subscribed 0x%.8X", get_huid(l_pTarget), l_hwasSubscriptionMask); } } // Test: Check for a combo of one bit cleared and one bit set, // expect true if (chgBit1 && chgBit2) { // setup check for set subscribed bit hwasChangedPredicate.reset().changedBit( static_cast(chgBit1), true); // setup check for set subscribed bit hwasChangedPredicate.changedBit( static_cast(chgBit2), false); // set the bit (the second bit is cleared) l_pTarget->setAttr(chgBit1); if(!hwasChangedPredicate(l_pTarget)) { TARG_TS_FAIL("Expected this %.8X bit set and this %.8X bit " "cleared to result in changedPredicate", chgBit1, chgBit2); } } // Test: Given a target with cleared HWAS GARD bit, predicate // looking for GARD bit should return false hwasChangedPredicate.reset().changedBit(HWAS_CHANGED_BIT_GARD, true); ATTR_HWAS_STATE_CHANGED_FLAG_type noGardHwasChangedBit = 0; l_pTarget->setAttr(noGardHwasChangedBit); if(hwasChangedPredicate(l_pTarget)) { TARG_TS_FAIL("Expected HWAS predicate not to match the " "target's cleared HWAS GARD bit"); } // Test: Look to match the negated HWAS_CHANGED_BIT_GARD bit. // This should match and return true hwasChangedPredicate.reset().changedBit(HWAS_CHANGED_BIT_GARD, false); if(!hwasChangedPredicate(l_pTarget)) { TARG_TS_FAIL("Expected negative HWAS predicate to match the " "target's cleared HWAS GARD bit"); } // Test: Given a target with set HWAS GARD bit, predicate // looking for GARD bit should return true hwasChangedPredicate.reset().changedBit(HWAS_CHANGED_BIT_GARD, true); l_pTarget->setAttr(HWAS_CHANGED_BIT_GARD); if(!hwasChangedPredicate(l_pTarget)) { TARG_TS_FAIL("Expected HWAS GARD bit predicate to match the " "target's GARD bit HWAS state"); } // Test: Given a target with cleared HWAS GARD bit, predicate // looking for cleared GARD bit should return true hwasChangedPredicate.reset().changedBit(HWAS_CHANGED_BIT_GARD, false); l_pTarget->setAttr(0); if(!hwasChangedPredicate(l_pTarget)) { TARG_TS_FAIL("Expected HWAS cleared GARD bit predicate to match " "the target's cleared GARD bit HWAS state"); } // Test: Given a target with all cleared HWAS bits, predicate // looking for all false should return true hwasChangedPredicate.reset().allChangesApplied(false); l_pTarget->setAttr(0); if(!hwasChangedPredicate(l_pTarget)) { TARG_TS_FAIL("Expected HWAS all cleared predicate to match the " "target's all cleared HWAS state"); } // Test: Given a target with all set HWAS bits, predicate // looking for all set should return true hwasChangedPredicate.reset().allChangesApplied(true); l_pTarget->setAttr (l_pTarget->getAttr()); if(!hwasChangedPredicate(l_pTarget)) { TARG_TS_FAIL("Expected HWAS all set predicate to match the " "target's all set HWAS state"); } // Restore state l_pTarget->setAttr (savedHwasChangedState); } while(0); TARG_TS_TRACE(EXIT_MRK "testPredicateHwasChanged" ); } void testPredicateCtm() { TARG_TS_TRACE(ENTER_MRK "testPredicateCtm" ); using namespace TARGETING; TargetService& l_targetService = targetService(); // Get top level (system) target Target* l_pTopLevel = NULL; (void) l_targetService.getTopLevelTarget(l_pTopLevel); if (l_pTopLevel == NULL) { TARG_TS_FAIL("Top level handle was NULL when initialization " "complete"); } PredicateCTM l_allWild; if( ! l_allWild(l_pTopLevel) ) { TARG_TS_FAIL("CTM all wildcards filter should have matched system " "target"); } PredicateCTM l_typeModelWild(CLASS_SYS); if( ! l_typeModelWild(l_pTopLevel) ) { TARG_TS_FAIL("CTM class sys, remaining wildcards filter should have " "matched system "); } PredicateCTM l_modelWild(CLASS_SYS,TYPE_SYS); if( ! l_modelWild(l_pTopLevel) ) { TARG_TS_FAIL("CTM class sys, type sys, remaining wildcards filter " "should have matched system "); } PredicateCTM l_noWild(CLASS_SYS,TYPE_SYS,MODEL_POWER9); if( ! l_noWild(l_pTopLevel) ) { TARG_TS_FAIL("CTM class sys, type sys, model power9 should have " "matched system "); } PredicateCTM l_classWild(CLASS_NA,TYPE_SYS,MODEL_POWER9); if( ! l_classWild(l_pTopLevel) ) { TARG_TS_FAIL("CTM class wild, type sys, model power9 should have " "matched system "); } PredicateCTM l_typeWild(CLASS_SYS,TYPE_NA,MODEL_POWER9); if( ! l_typeWild(l_pTopLevel) ) { TARG_TS_FAIL("CTM class sys, wild, model power9 should have " "matched system "); } PredicateCTM l_classModelWild(CLASS_NA,TYPE_SYS,MODEL_NA); if( ! l_classModelWild(l_pTopLevel) ) { TARG_TS_FAIL("CTM wild, type sys, wild should have " "matched system "); } PredicateCTM l_classTypeWild(CLASS_NA,TYPE_NA,MODEL_NA); if( ! l_classTypeWild(l_pTopLevel) ) { TARG_TS_FAIL("CTM wild, wild, model should have " "matched system "); } PredicateCTM l_chipClass(CLASS_CHIP,TYPE_NA,MODEL_NA); if( l_chipClass(l_pTopLevel) ) { TARG_TS_FAIL("CTM of class chip, wild, wild should not have matched " "matched system "); } #if 0 // Prove copy CTOR/assignment operator is disabled PredicateCTM l_ctmLhs; PredicateCTM l_ctmRhs; l_ctmLhs = l_ctmRhs; PredicateCTM l_ctmCtor(l_ctmRhs); #endif PredicateBase* l_pBase = new PredicateCTM(CLASS_SYS); delete l_pBase; l_pBase = NULL; TARG_TS_TRACE(EXIT_MRK "testPredicateCtm" ); } void testPredicatePostfixExpr() { TARG_TS_TRACE(ENTER_MRK "testPredicatePostfixExpr" ); using namespace TARGETING; TargetService& l_targetService = targetService(); // Get top level (system) target Target* l_pTopLevel = NULL; (void) l_targetService.getTopLevelTarget(l_pTopLevel); if (l_pTopLevel == NULL) { TARG_TS_FAIL("Top level handle was NULL when initialization " "complete"); } PredicatePostfixExpr l_alwaysTrueExpr; if(!l_alwaysTrueExpr(l_pTopLevel) ) { TARG_TS_FAIL("Always true filter should have matched system"); } #if 0 // Triggers NULL assertion check on push l_alwaysTrueExpr.push(NULL); #endif #if 0 // Triggers not enough stack elements assertion when evaluating Not l_alwaysTrueExpr.Not(); if(l_alwaysTrueExpr(l_pTopLevel) ) { TARG_TS_FAIL("Negated always true filter should not have matched " "system"); } #endif #if 0 // Triggers illegal target assertion l_alwaysTrueExpr(NULL); #endif #if 0 // Triggers formatting assertion l_alwaysTrueExpr.And(); l_alwaysTrueExpr(l_pTopLevel); #endif #if 0 // Triggers formatting assertion l_alwaysTrueExpr.Or(); l_alwaysTrueExpr(l_pTopLevel); #endif PredicateCTM l_sysClass(CLASS_SYS); #if 0 // Triggers formatting assertion l_alwaysTrueExpr.push(&l_sysClass); l_alwaysTrueExpr.And(); l_alwaysTrueExpr(l_pTopLevel); #endif #if 0 // Triggers formatting assertion l_alwaysTrueExpr.push(&l_sysClass); l_alwaysTrueExpr.Or(); l_alwaysTrueExpr(l_pTopLevel); #endif #if 0 // Triggers illegal formatting exception // != 1 results on stack l_alwaysTrueExpr.push(&l_sysClass); l_alwaysTrueExpr.push(&l_sysClass); l_alwaysTrueExpr.Not(); l_alwaysTrueExpr(l_pTopLevel); #endif PredicateCTM l_sysType(CLASS_NA,TYPE_SYS); PredicateCTM l_power9Model(CLASS_NA,TYPE_NA,MODEL_POWER9); PredicatePostfixExpr l_expr; l_expr.push(&l_sysClass).push(&l_sysType).And(); l_expr.push(&l_power9Model).And(); if(!l_expr(l_pTopLevel) ) { TARG_TS_FAIL("CTM of class sys && type sys && model power9 should " "have matched system"); } l_expr.Not(); if(l_expr(l_pTopLevel) ) { TARG_TS_FAIL("CTM of class sys && type sys && model power9 should " "npt have matched system after negation"); } l_expr.push(&l_sysClass); l_expr.Or(); if(!l_expr(l_pTopLevel) ) { TARG_TS_FAIL("CTM of class sys && type sys && model power9 should " "have matched system after negation then || sys class"); } PredicatePostfixExpr* l_pExpr = new PredicatePostfixExpr; l_pExpr->push(&l_sysClass).push(&l_sysType).And(); l_pExpr->push(&l_power9Model).And(); delete (static_cast(l_pExpr)); #if 0 PredicatePostfixExpr l_lhs; PredicatePostfixExpr l_rhs; l_lhs = l_rhs; PredicatePostfixExpr l_cpCtor(l_rhs); #endif TARG_TS_TRACE(EXIT_MRK "testPredicatePostfixExpr" ); } void testTargetIterator() { TARG_TS_TRACE(ENTER_MRK "testTargetIterator"); using namespace TARGETING; TargetService& l_targetService = targetService(); TargetIterator l_pIt; if( l_pIt != l_targetService.end() ) { TARG_TS_FAIL("Default TargetIterator should point to past the end " "of container"); } ++l_pIt; if( l_pIt != l_targetService.end() ) { TARG_TS_FAIL("Default TargetIterator preincremented should point to " "past the end of container"); } TargetIterator* l_pItNew = new TargetIterator; delete l_pItNew; l_pItNew = NULL; if(*l_pIt != NULL) { TARG_TS_FAIL("Default TargetIterator dereference should return NULL"); } // Get top level (system) target to verify at least 1 target Target* l_pTopLevel = NULL; (void) l_targetService.getTopLevelTarget(l_pTopLevel); if (l_pTopLevel == NULL) { TARG_TS_FAIL("Top level handle was NULL when initialization " "complete"); } l_pIt = l_targetService.begin(); if((*l_pIt) == NULL) { TARG_TS_FAIL("TargetService begin() should return !NULL"); } CLASS l_class = CLASS_NA; if( !l_pIt->tryGetAttr(l_class) ) { TARG_TS_FAIL("Failed to get expected class attribute"); } TargetIterator l_rhs = l_targetService.begin(); if( ! (l_pIt == l_rhs) ) { TARG_TS_FAIL("Iterators should be equal, but aren't"); } l_rhs = l_targetService.begin(); if( l_pIt != l_rhs ) { TARG_TS_FAIL("Iterators should be equal, but aren't"); } TargetIterator l_rhs2 = l_targetService.begin(); ++l_rhs2; ++l_pIt; if( l_pIt != l_rhs2 ) { TARG_TS_FAIL("Iterators should be equal, but aren't"); } l_rhs2++; l_pIt++; if( l_pIt != l_rhs2 ) { TARG_TS_FAIL("Iterators should be equal, but aren't"); } TargetIterator l_pItClone(l_rhs2); if( l_pIt != l_pItClone) { TARG_TS_FAIL("Iterators should be equal, but aren't"); } if(l_pIt != l_pItClone++) { TARG_TS_FAIL("Iterators should be equal, but aren't"); } if( (++l_pIt) != l_pItClone) { TARG_TS_FAIL("Iterators should be equal, but aren't"); } const TargetService& l_constTargetService = targetService(); ConstTargetIterator l_pConstIt; if( l_pConstIt != l_constTargetService.end() ) { TARG_TS_FAIL("Default ConstTargetIterator should point to past the " "end of container"); } l_pConstIt = l_constTargetService.begin(); if( (*l_pConstIt) == NULL) { TARG_TS_FAIL("Iterator does not point to valid Target as expected"); } TARG_TS_TRACE(EXIT_MRK "testTargetIterator" ); } void testRangeFilter(void) { TARG_TS_TRACE(ENTER_MRK "testRangeFilters" ); using namespace TARGETING; TargetRangeFilter* l_pRangeFilter = new TargetRangeFilter( targetService().begin(), targetService().end(), NULL); delete l_pRangeFilter; l_pRangeFilter = NULL; TargetRangeFilter l_f1( targetService().begin(), targetService().end(), NULL); Target* l_pBegin = (*l_f1); ++l_f1; Target* l_pNext = (*l_f1); if( (l_pBegin == NULL) || (l_pNext == NULL) || (l_pBegin == l_pNext) ) { TARG_TS_FAIL("Target* pointed to by Begin/next NULL -or- begin ==" "next"); } l_f1.reset(); if( *l_f1 != l_pBegin ) { TARG_TS_FAIL("Target* after reset should be equal to original"); } l_f1.reset(); TargetRangeFilter l_f2 = l_f1; PredicateCTM l_ctm(CLASS_SYS,TYPE_CORE); // Nonsense CTM l_f1.setPredicate(&l_ctm); if( *l_f1 == l_pBegin ) { TARG_TS_FAIL("Target* after reset and change of predicate should be" "different than the original"); } PredicateCTM l_ctm1(CLASS_CHIP,TYPE_PROC); TargetRangeFilter l_f3( targetService().begin(), targetService().end(), &l_ctm1); for(;l_f3;++l_f3) { if(l_f3->getAttr() != TYPE_PROC) { TARG_TS_FAIL("Should only have returned type proc"); break; } } TargetIterator l_pIt = targetService().begin(); ++l_pIt; ++l_pIt; if(l_pIt == targetService().end()) { TARG_TS_FAIL("Not enough elements for test"); } TargetRangeFilter l_partial( targetService().begin(), l_pIt, NULL); int i=0; for(; l_partial; ++l_partial) { i++; } if(i != 2) { TARG_TS_FAIL("Should have gotten 2 elements %d",i); } TARG_TS_TRACE(EXIT_MRK "testRangeFilter" ); } void testComplexFilter(void) { TARG_TS_TRACE(ENTER_MRK "testComplexFilter" ); using namespace TARGETING; TargetService& l_targetService = targetService(); TargetRangeFilter f(l_targetService.begin(), l_targetService.end(), NULL); int l_count = 0; for(; f; ++f, l_count++) { } TARG_TS_TRACE(INFO_MRK "Found %d total targets", l_count); PredicateCTM l_procs(CLASS_CHIP); PredicateCTM l_enclosures(CLASS_ENC); PredicatePostfixExpr l_query; l_query.push(&l_procs).push(&l_enclosures).Or(); f.setPredicate(&l_query); f.reset(); l_count = 0; for(; f; ++f, ++l_count) { EntityPath l_path = f->getAttr(); l_path.dump(); } TARG_TS_TRACE(INFO_MRK "Found %d targets that are chips or enclosures ", l_count); l_query.Not(); f.reset(); l_count = 0; for(; f; ++f, ++l_count) { } TARG_TS_TRACE(INFO_MRK "Found %d targets that are not chips or " "enclosures",l_count); Target* l_pMasterProcChipTargetHandle = NULL; (void) l_targetService.masterProcChipTargetHandle( l_pMasterProcChipTargetHandle); if(l_pMasterProcChipTargetHandle == NULL) { TARG_TS_FAIL("Master processor chip target not found"); } PredicateCTM l_ex(CLASS_UNIT,TYPE_EX); PredicateCTM l_mba(CLASS_UNIT,TYPE_MBA); PredicatePostfixExpr l_procquery; l_procquery.push(&l_ex).push(&l_mba).Or(); TargetHandleList l_list; (void) targetService().getAssociated( l_list, l_pMasterProcChipTargetHandle, TARGETING::TargetService::CHILD, TARGETING::TargetService::ALL, &l_procquery); l_count = 0; for(uint32_t i=0; igetAttr(); l_path.dump(); } TARG_TS_TRACE(INFO_MRK "Found %d targets that are ex/mba units off " "master processor",l_count); TARG_TS_TRACE(EXIT_MRK "testComplexFilter" ); } void testFapiToHbMacros () { TARG_TS_TRACE(ENTER_MRK "testFapiToHbMacros" ); TARG_TS_TRACE(INFO_MRK "Now using direct access macros"); using namespace TARGETING; TargetService& l_targetService = targetService(); TARGETING::Target* l_pTarget = NULL; (void) l_targetService.getTopLevelTarget(l_pTarget); if (l_pTarget == NULL) { TARG_TS_FAIL("Top level handle was NULL when initialization " "complete"); } DUMMY_RW_ATTR l_dummyRw; memset(l_dummyRw,0x00,sizeof(l_dummyRw)); l_pTarget->tryGetAttr(l_dummyRw); if(l_dummyRw[0][1][2] != 5) { TARG_TS_FAIL("l_dummyRw value is %d, not 5 as expected in direct " "attribute access",l_dummyRw[0][1][2]); } TARGETING::CLASS l_class = l_pTarget->getAttr(); if(l_class != TARGETING::CLASS_SYS) { TARG_TS_FAIL("l_class value is %d, not %d as expected in direct " "attribute access",l_class,TARGETING::CLASS_SYS); } TARGETING::TYPE l_type = l_pTarget->getAttr(); if(l_type != TARGETING::TYPE_SYS) { TARG_TS_FAIL("l_type value is %d, not %d as expected in direct " "attribute access",l_type,TARGETING::TYPE_SYS); } uint64_t l_xscom = l_pTarget->getAttr(); if(l_xscom != 0x000603FC00000000ULL) { TARG_TS_FAIL("l_xscom value is 0x%016llX, not 0x%016llX as expected in direct " "attribute access",l_xscom,0x000603FC00000000ULL); } TARG_TS_TRACE(INFO_MRK "Now using FAPI get macros"); memset(l_dummyRw,0x00,sizeof(l_dummyRw)); #if 0 //@TODO RTC:142602 fapi::ReturnCode l_rc = FAPI_ATTR_GET( ATTR_DUMMY_SCRATCH_PLAT_INIT_UINT8, NULL, l_dummyRw); if(l_rc != 0) { TARG_TS_FAIL("Failed to get dummy RW attribute on system target"); } if(l_dummyRw[0][2][4] != 5) { TARG_TS_FAIL("l_dummyRw value is %d, not 5 as expected", l_dummyRw[0][2][4]); } TARG_TS_TRACE(INFO_MRK "Now using FAPI set macros"); l_dummyRw[0][2][3] = 6; l_rc = FAPI_ATTR_SET(ATTR_DUMMY_SCRATCH_PLAT_INIT_UINT8, NULL, l_dummyRw); if(l_rc != 0) { TARG_TS_FAIL("Failed to write dummy RW attribute on system target"); } memset(l_dummyRw,0x00,sizeof(l_dummyRw)); l_rc = FAPI_ATTR_GET(ATTR_DUMMY_SCRATCH_PLAT_INIT_UINT8, NULL, l_dummyRw); if(l_rc != 0) { TARG_TS_FAIL("Failed to get dummy RW attribute on system target"); } if(l_dummyRw[0][2][3] != 6) { TARG_TS_FAIL("l_dummyRw value is %d, not 6 as expected due to a " "prior write",l_dummyRw[0][2][3]); } TARG_TS_TRACE(INFO_MRK "Now using targets without the attribute"); memset(l_dummyRw,0x00,sizeof(l_dummyRw)); EntityPath l_realPath(EntityPath::PATH_PHYSICAL); l_realPath.addLast(TYPE_SYS,0).addLast(TYPE_NODE,0); l_pTarget = l_realPath.operator->(); if (l_pTarget == NULL) { TARG_TS_FAIL("Node 0 target handle should not be NULL"); } //@TODO RTC:142602 fapi::Target* l_pFapiTarget = new fapi::Target( fapi::TARGET_TYPE_PROC_CHIP, l_pTarget); l_rc = FAPI_ATTR_GET(ATTR_DUMMY_SCRATCH_PLAT_INIT_UINT8, l_pFapiTarget , l_dummyRw); if(l_rc == 0) { TARG_TS_FAIL("Should have failed getting the attribute on " "non-supporting target"); } else if(l_rc != FAPI_RC_PLAT_ERR_SEE_DATA) { TARG_TS_FAIL("Should have been a platform handled error"); } // The error log will get deleted when the ReturnCode is destructed. The // error log is not committed here to avoid it getting interpreted as a // real problem delete l_pFapiTarget; l_pFapiTarget = NULL; #endif TARG_TS_TRACE(EXIT_MRK "testFapiToHbMacros" ); } void testPodNumericalTypes() { TARG_TS_TRACE(ENTER_MRK "testPodNumericalTypes" ); using namespace TARGETING; TargetService& l_targetService = targetService(); TARGETING::Target* l_pTarget = NULL; (void) l_targetService.getTopLevelTarget(l_pTarget); if (l_pTarget == NULL) { TARG_TS_FAIL("Top level handle was NULL when initialization " "complete"); } NUMERIC_POD_TYPE_TEST_ATTR l_pod; memset(&l_pod,0x00,sizeof(l_pod)); if(!l_pTarget->tryGetAttr(l_pod)) { TARG_TS_FAIL("Numeric POD type not found"); } if( (l_pod.fsiPath.type() != EntityPath::PATH_PHYSICAL) || (l_pod.fsiPath[0].type != TYPE_SYS) || (l_pod.fsiPath[0].instance != 0) || (l_pod.fsiPath.size() != 1 ) ) { TARG_TS_FAIL("Expected physical:sys-0, got a different result"); } if(l_pod.className != CLASS_CHIP) { TARG_TS_FAIL("Expected CLASS value of 0x%08X, got 0x%08X", CLASS_CHIP,l_pod.className); } if(l_pod.uint8 != 0xAB) { TARG_TS_FAIL("Expected uint8_t value of 0xAB, got 0x%02X", l_pod.uint8); } if (l_pod.uint16 != 0xABCD) { TARG_TS_FAIL("Expected uint16_t value of 0xABCD, got 0x%04X", l_pod.uint16); } if (l_pod.uint32 != 0xABCDEF01) { TARG_TS_FAIL("Expected uint32_t value of 0xABCDEF01, got 0x%08X", l_pod.uint32); } if (l_pod.uint64 != 0xABCDEF0123456789ULL) { TARG_TS_FAIL("Expected uint64_t value of 0xABCDEF0123456789, got " "0x%016llX", l_pod.uint64); } if(l_pod.int8 != -124) { TARG_TS_FAIL("Expected int8_t value of -124, got %d", l_pod.int8); } if (l_pod.int16 != -32764) { TARG_TS_FAIL("Expected int16_t value of -32764, got %d", l_pod.int16); } if (l_pod.int32 != -2147483644) { TARG_TS_FAIL("Expected int32_t value of -2147483644, got %d", l_pod.int32); } if (l_pod.int64 != -9223372036854775804LL) { TARG_TS_FAIL("Expected int64_t value of -9223372036854775804, got " "%lld", l_pod.int64); } TARG_TS_TRACE(EXIT_MRK "testPodNumericalTypes" ); } void testCentaurs() { TARG_TS_TRACE(ENTER_MRK "testCentaurs" ); using namespace TARGETING; PredicateCTM l_procChip(CLASS_CHIP,TYPE_PROC); TargetRangeFilter l_filter( targetService().begin(), targetService().end(), &l_procChip); PredicateCTM l_memBuf(CLASS_CHIP,TYPE_MEMBUF); uint32_t l_count = 0; uint32_t l_procs = 0; // For each processor for(;l_filter;++l_filter) { l_procs++; TargetHandleList l_list; (void) targetService().getAssociated( l_list, *l_filter, TARGETING::TargetService::CHILD_BY_AFFINITY, TARGETING::TargetService::ALL, &l_memBuf); l_count += l_list.size(); } if(l_procs) { if(l_count <= 0) { TARG_TS_TRACE("Did not find any Centaur \ chips connected to processors"); } else { TARG_TS_TRACE("Found %d Centaur chips connected to processors",l_count); } } TARG_TS_TRACE(EXIT_MRK "testCentaurs" ); } /** * @test Tests string attributes */ void testStringAttributes(void) { TARG_TS_TRACE(ENTER_MRK "testStringAttributes" ); using namespace TARGETING; do { TargetService& l_targetService = targetService(); // Get the top level target for the string attribute tests Target* l_pTopLevel = NULL; (void) l_targetService.getTopLevelTarget(l_pTopLevel); if (l_pTopLevel == NULL) { TARG_TS_FAIL("ERROR: Can not find top level target; bypassing " "remaining string attribute tests"); break; } // TC1: Test NULL string attribute // TC1.1: String storage size must match the stated size ATTR_TEST_NULL_STRING_type l_nullStringReference = {0}; ATTR_TEST_NULL_STRING_type l_nullString = {0}; if(sizeof(l_nullString) != ATTR_TEST_NULL_STRING_max_chars+1) { TARG_TS_FAIL("ERROR: l_nullString size (%d) " "does not match stated size (%d)", sizeof(l_nullString), ATTR_TEST_NULL_STRING_max_chars+1); } // TC1.2: String size must be non-zero if(sizeof(l_nullString) == 0) { TARG_TS_FAIL("ERROR: l_nullString size is zero"); } // TC1.3: Must be able to read the string if(!l_pTopLevel->tryGetAttr(l_nullString)) { TARG_TS_FAIL("ERROR: Can not read l_nullString attribute"); } // TC1.4: All bytes of the string must match the reference version if(memcmp(l_nullStringReference, l_nullString, sizeof(l_nullStringReference))) { TARG_TS_FAIL("ERROR: l_nullString bytes do not match the reference" "version"); TARG_BIN("Expected (l_nullStringReference)", l_nullStringReference,sizeof(l_nullStringReference)); TARG_BIN("Actual (l_nullString)", l_nullString,sizeof(l_nullString)); } // TC1.5: String must equal the empty string by string comparison if(strcmp(l_nullString,"") != 0) { TARG_TS_FAIL("ERROR: l_nullString does not strcmp to the empty string"); TARG_BIN("Actual (l_nullString)", l_nullString,sizeof(l_nullString)); } // TC2: Test string attribute with only 1 character // TC2.1: String storage size must match the stated size ATTR_TEST_MIN_STRING_type l_minStringReference = {0}; l_minStringReference[0] = 'Z'; ATTR_TEST_MIN_STRING_type l_minString = {0}; if(sizeof(l_minString) != ATTR_TEST_MIN_STRING_max_chars+1) { TARG_TS_FAIL("ERROR: l_minString size (%d) " "does not match stated size (%d)", sizeof(l_minString), ATTR_TEST_MIN_STRING_max_chars+1); } // TC2.2: String size must be non-zero if(sizeof(l_minString) == 0) { TARG_TS_FAIL("ERROR: l_minString size is zero"); } // TC2.3: Must be able to read the string if(!l_pTopLevel->tryGetAttr(l_minString)) { TARG_TS_FAIL("ERROR: Can not read l_minString attribute"); } // TC2.4: All bytes in string must match the reference string if(memcmp(l_minStringReference, l_minString, sizeof(l_minStringReference))) { TARG_TS_FAIL("ERROR l_minString bytes do not match the reference " "version"); TARG_BIN("Expected (l_minStringReference)", l_minStringReference,sizeof(l_minStringReference)); TARG_BIN("Actual (l_minString)", l_minString,sizeof(l_minString)); } // TC2.5: String must equal "Z" by comparison if(strcmp(l_minString,l_minStringReference) != 0) { TARG_TS_FAIL("ERROR l_minString does not strcmp to the reference " "string"); TARG_BIN("Actual (l_minString)", l_minString,sizeof(l_minString)); } // TC3: Test string with maximum number of characters (including NULL) // TC3.1: String storage size must match the stated size ATTR_TEST_MAX_STRING_type l_maxStringReference = {0}; l_maxStringReference[0] = 'a'; l_maxStringReference[1] = 'b'; l_maxStringReference[2] = 'c'; ATTR_TEST_MAX_STRING_type l_maxString = {0}; if(sizeof(l_maxString) != ATTR_TEST_MAX_STRING_max_chars+1) { TARG_TS_FAIL("ERROR: l_maxString size (%d) " "does not match stated size (%d)", sizeof(l_maxString), ATTR_TEST_MAX_STRING_max_chars+1); } // TC3.2: String storage size must be non-zero if(sizeof(l_maxString) == 0) { TARG_TS_FAIL("ERROR: l_maxString storage size is zero"); } // TC3.3: Must be able to read the string if(!l_pTopLevel->tryGetAttr(l_maxString)) { TARG_TS_FAIL("ERROR: Could not read l_maxString"); } // TC3.4: All bytes in string must match the reference if(memcmp(l_maxStringReference, l_maxString, sizeof(l_maxStringReference))) { TARG_TS_FAIL("ERROR: l_maxString bytes do not match the reference " "version"); TARG_BIN("Expected (l_maxStringReference)", l_maxStringReference,sizeof(l_maxStringReference)); TARG_BIN("Actual (l_maxString)", l_maxString,sizeof(l_maxString)); } // TC3.5: String must equal "abc" by comparison if(strcmp(l_maxString,l_maxStringReference) != 0) { TARG_TS_FAIL("ERROR: l_maxString does not strcmp to the reference " "string"); TARG_BIN("Actual (l_maxString)", l_maxString,sizeof(l_maxString)); } // TC4: Test string with no supplied default value // TC4.1: String storage size must match stated size ATTR_TEST_NO_DEFAULT_STRING_type l_noDefaultStringReference = {0}; ATTR_TEST_NO_DEFAULT_STRING_type l_noDefaultString = {0}; if(sizeof(l_noDefaultString) != ATTR_TEST_NO_DEFAULT_STRING_max_chars+1) { TARG_TS_FAIL("ERROR: l_noDefaultString size (%d) " "does not match stated size (%d)", sizeof(l_noDefaultString), ATTR_TEST_NO_DEFAULT_STRING_max_chars+1); } // TC4.2: String storage size must be non-zero if(sizeof(l_noDefaultString) == 0) { TARG_TS_FAIL("ERROR: l_noDefaultString storage size is zero"); } // TC4.3: Must be able to read the string if(!l_pTopLevel->tryGetAttr( l_noDefaultString)) { TARG_TS_FAIL("ERROR: Could not read l_noDefaultString"); } // TC4.4: All bytes in string must match the reference if(memcmp(l_noDefaultStringReference, l_noDefaultString, sizeof(l_noDefaultStringReference))) { TARG_TS_FAIL("ERROR: l_noDefaultString bytes do not match the " "reference"); TARG_BIN("Expected (l_noDefaultStringReference)", l_noDefaultStringReference, sizeof(l_noDefaultStringReference)); TARG_BIN("Actual (l_noDefaultString)", l_noDefaultString,sizeof(l_noDefaultString)); } // TC4.5: String must equal empty string by comparison if(strcmp(l_noDefaultString,l_noDefaultStringReference) != 0) { TARG_TS_FAIL("ERROR: l_noDefaultString does not strcmp to the reference " "string"); TARG_BIN("Actual (l_noDefaultString)", l_noDefaultString,sizeof(l_noDefaultString)); } // TC5: Write string and read back // TC5.1: Must be able to write the string ATTR_TEST_NO_DEFAULT_STRING_type l_writeString = {0}; strcpy(l_writeString,"aabbcc"); if(!l_pTopLevel->trySetAttr(l_writeString)) { TARG_TS_FAIL("ERROR: Could not write l_writeString"); } ATTR_TEST_NO_DEFAULT_STRING_type l_readString = {0}; if(!l_pTopLevel->tryGetAttr(l_readString)) { TARG_TS_FAIL("ERROR: Could not read l_readString"); } if(strcmp(l_writeString,l_readString) != 0) { TARG_TS_FAIL("ERROR: String does not match what was written"); TARG_BIN("Expected (l_writeString)", l_writeString, sizeof(l_writeString)); TARG_BIN("Actual (l_readString)", l_readString, sizeof(l_readString)); } } while(0); TARG_TS_TRACE(EXIT_MRK "testStringAttributes" ); } void testL4s() { TARG_TS_TRACE(ENTER_MRK "testL4s" ); using namespace TARGETING; PredicateCTM l_procChip(CLASS_CHIP,TYPE_PROC); TargetRangeFilter l_filter( targetService().begin(), targetService().end(), &l_procChip); PredicateCTM l_L4s(CLASS_UNIT,TYPE_L4); uint32_t l_count = 0; uint32_t l_procs = 0; // There should be 16 L4s as children of the // 16 processors for(;l_filter;++l_filter) { l_procs++; TargetHandleList l_list; (void) targetService().getAssociated( l_list, *l_filter, TARGETING::TargetService::CHILD_BY_AFFINITY, TARGETING::TargetService::ALL, &l_L4s); l_count += l_list.size(); } // 4 processors -- 4 L4 units per processor uint32_t total = 4 * l_procs; if(l_procs) { if( l_count != total ) { TARG_TS_TRACE("Did not find any L4 targets identified " "with child affinity to the processors"); } else { TARG_TS_TRACE("Found %d L4 targets with child affinity to " "the processors", l_count); } } l_count = 0; PredicateCTM l_mcsChip(CLASS_UNIT,TYPE_MCS); TargetRangeFilter l_filter2( targetService().begin(), targetService().end(), &l_mcsChip); uint32_t l_MCS = 0; // L4 is also a child of the MCS for(;l_filter2;++l_filter2) { l_MCS++; TargetHandleList l_list; (void) targetService().getAssociated( l_list, *l_filter2, TARGETING::TargetService::CHILD_BY_AFFINITY, TARGETING::TargetService::ALL, &l_L4s); l_count += l_list.size(); } // 1 L4 uint per MCS uint total = l_MCS; if(l_MCS) { if(l_count != total ) { TARG_TS_TRACE("Did not find any L4 targets connected to MCS"); } else { TARG_TS_TRACE("Found %d L4 targets connected to MCS",l_count); } } PredicateCTM l_nodes(CLASS_ENC,TYPE_NODE,MODEL_POWER9); TargetRangeFilter l_filter3( targetService().begin(), targetService().end(), &l_nodes); uint32_t l_node = 0; l_count = 0; // L4 is also a child of the NODE for(;l_filter3;++l_filter3) { l_node++; TargetHandleList l_list; (void) targetService().getAssociated( l_list, *l_filter3, TARGETING::TargetService::CHILD_BY_AFFINITY, TARGETING::TargetService::ALL, &l_L4s); l_count += l_list.size(); } // 1 L4 per MCS * number of nodes total = l_node * l_MCS; if(l_node) { if(l_count != total ) { TARG_TS_TRACE("Did not find any L4 targets " "with child affinity to the node"); } else { TARG_TS_TRACE("Found %d L4 targets with child " "affinity to the node",l_count); } } PredicateCTM l_membufs(CLASS_CHIP,TYPE_MEMBUF,MODEL_CENTAUR); TargetRangeFilter l_filter4( targetService().begin(), targetService().end(), &l_membufs); int l_membuf = 0; l_count = 0; // L4 is also a child of the NODE for(;l_filter4;++l_filter4) { l_membuf++; TargetHandleList l_list; (void) targetService().getAssociated( l_list, *l_filter4, TARGETING::TargetService::CHILD_BY_AFFINITY, TARGETING::TargetService::ALL, &l_L4s); l_count += l_list.size(); } // 1 L4 per membuf total = l_membuf; if(l_membuf) { if(l_count != total ) { TARG_TS_TRACE("\n\nDid not find any L4 targets " "with child affinity to the membuf target\n\n"); } else { TARG_TS_TRACE("\n\nFound %d L4 targets with child " "affinity to the membuf\n\n",l_count); } } TARG_TS_TRACE(EXIT_MRK "testL4s" ); } /** * @brief Tests pervasive associations * * @par Detailed Description: * An applicable pervasive target has a "PERVASIVE_CHILD" * association that links it to a child unit target. For * example, a pervasive target may have said link to a child * core target. That child core target, in turn, will have * a "PARENT_PERVASIVE" association back to it's parent, * forming a bidirectional relationship, which can be navigated * with target service getAssociated() calls. This test * verifies that pervasive target A links to child target B, * and that in turn, B links back to A. */ void testPervasiveRelationship() { TARG_TS_TRACE(ENTER_MRK "testPervasiveRelationship" ); using namespace TARGETING; // Get all pervasive targets in the model and loop through // each one PredicateCTM pervasiveUnit(CLASS_UNIT,TYPE_PERV); TargetRangeFilter pervasiveUnitFilter( targetService().begin(), targetService().end(), &pervasiveUnit); size_t pervasives = 0; for(;pervasiveUnitFilter;++pervasiveUnitFilter) { ++pervasives; // For each pervasive target, find all its children // using the special PERVASIVE_CHILD association type TargetHandleList pervasiveChildren; (void)targetService().getAssociated( pervasiveChildren, *pervasiveUnitFilter, TARGETING::TargetService::PERVASIVE_CHILD, TARGETING::TargetService::ALL); ATTR_PHYS_PATH_type pervasivePath = (*pervasiveUnitFilter)-> getAttr(); TARG_TS_TRACE("Found %d children for pervasive w/ " "path %s",pervasiveChildren.size(), pervasivePath.toString()); // Then for each child, navigate back to what should be the original // pervasive target for(TARGETING::TargetHandleList::const_iterator child = pervasiveChildren.begin(); child != pervasiveChildren.end(); ++child) { ATTR_PHYS_PATH_type childPath = (*child)-> getAttr(); TARG_TS_TRACE("Child path is %s", childPath.toString()); TargetHandleList parentPervasive; (void)targetService().getAssociated( parentPervasive, *child, TARGETING::TargetService::PARENT_PERVASIVE, TARGETING::TargetService::ALL); // Make sure every child has exactly one parent pervasive if(parentPervasive.size() != 1) { TARG_TS_FAIL("child of pervasive did not have exactly 1 " "parent pervasive (had %d)",parentPervasive.size()); } // Make sure that the parent of 'the child of the parent' is the // parent if(*parentPervasive.begin() != *pervasiveUnitFilter) { TARG_TS_FAIL("parent of child of pervasive was not the " "original pervasive"); } // Make sure that the parent is not accidentally the child if(*parentPervasive.begin() == *child) { TARG_TS_FAIL("parent is equal to child"); } } } if(!pervasives) { TARG_TS_FAIL("no pervasive units found in the model"); } else { TARG_TS_TRACE("Found total of %d pervasive targets",pervasives); } TARG_TS_TRACE(EXIT_MRK "testPervasiveRelationship" ); } }; #endif // __TARGETING_COMMON_TESTCOMMONTARGETING_H