diff options
author | Nick Bofferding <bofferdn@us.ibm.com> | 2011-08-16 12:40:36 -0500 |
---|---|---|
committer | Nicholas E. Bofferding <bofferdn@us.ibm.com> | 2011-08-23 14:10:24 -0500 |
commit | 213b45cd7d8b0367f85ee68b79941f6d548c1e9c (patch) | |
tree | 8f78e3999420f6b1b2ca00ccb79f88cf54441d5c /src/usr | |
parent | 91b39e52483cc5a8cc1cb7c7d15c281a150d9572 (diff) | |
download | talos-hostboot-213b45cd7d8b0367f85ee68b79941f6d548c1e9c.tar.gz talos-hostboot-213b45cd7d8b0367f85ee68b79941f6d548c1e9c.zip |
Add target iterator and predicate support
Change-Id: I728bb312277591d81c0575e74878fba9f816b962
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/260
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Reviewed-by: MIKE J. JONES <mjjones@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r-- | src/usr/targeting/iterators/rangefilter.C | 89 | ||||
-rw-r--r-- | src/usr/targeting/iterators/targetiterator.C | 88 | ||||
-rw-r--r-- | src/usr/targeting/makefile | 21 | ||||
-rw-r--r-- | src/usr/targeting/predicates/predicatebase.C | 54 | ||||
-rw-r--r-- | src/usr/targeting/predicates/predicatectm.C | 63 | ||||
-rw-r--r-- | src/usr/targeting/predicates/predicatepostfixexpr.C | 198 | ||||
-rw-r--r-- | src/usr/targeting/targetservice.C | 108 | ||||
-rw-r--r-- | src/usr/targeting/test/targetingtest.H | 533 | ||||
-rw-r--r-- | src/usr/targeting/trace.H | 2 |
9 files changed, 1131 insertions, 25 deletions
diff --git a/src/usr/targeting/iterators/rangefilter.C b/src/usr/targeting/iterators/rangefilter.C new file mode 100644 index 000000000..64ceb1f78 --- /dev/null +++ b/src/usr/targeting/iterators/rangefilter.C @@ -0,0 +1,89 @@ + +/** + * @file rangefilter.C + * + * @brief Implementation of an object which takes an iterator range and + * allows caller to iterate through the elements which match a supplied + * predicate (filter) + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD + +// Other Host Boot Components + +// Targeting Component +#include <targeting/iterators/rangefilter.H> + +//****************************************************************************** +// Macros +//****************************************************************************** + +#undef TARG_NAMESPACE +#undef TARG_CLASS +#undef TARG_FUNC + +//****************************************************************************** +// Implementation +//****************************************************************************** + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" + +#define TARG_CLASS "RangeFilter<IteratorType>::" + +//****************************************************************************** +// RangeFilter<IteratorType>::advance +//****************************************************************************** + +template<typename IteratorType> +void RangeFilter<IteratorType>::advance() +{ + if(iv_current != iv_end) + { + while( (++iv_current) != iv_end ) + { + if( (!iv_pPredicate) + || ((*iv_pPredicate)(*iv_current))) + { + break; + } + } + } +} + +//****************************************************************************** +// RangeFilter<IteratorType>::advanceIfNoMatch +//****************************************************************************** + +template<typename IteratorType> +void RangeFilter<IteratorType>::advanceIfNoMatch() +{ + if( (iv_current != iv_end) + && ( (iv_pPredicate) + && (!((*iv_pPredicate)(*iv_current))))) + { + advance(); + } +} + +//****************************************************************************** +// Explicit template class member function instantiations +//****************************************************************************** + +template void RangeFilter<TargetIterator>::advance(); +template void RangeFilter<ConstTargetIterator>::advance(); + +template void RangeFilter<TargetIterator>::advanceIfNoMatch(); +template void RangeFilter<ConstTargetIterator>::advanceIfNoMatch(); + +#undef TARG_CLASS +#undef TARG_NAMESPACE + +} // End namespace TARGETING + diff --git a/src/usr/targeting/iterators/targetiterator.C b/src/usr/targeting/iterators/targetiterator.C new file mode 100644 index 000000000..f3549a633 --- /dev/null +++ b/src/usr/targeting/iterators/targetiterator.C @@ -0,0 +1,88 @@ + +/** + * @file targetiterator.C + * + * @brief Implementation of iterator/const iterator used to iterate through + * target service targets + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD + +// Other Host Boot Components + +// Targeting Component +#include <targeting/iterators/targetiterator.H> +#include <targeting/targetservice.H> + +//****************************************************************************** +// Macros +//****************************************************************************** + +#undef TARG_NAMESPACE +#undef TARG_CLASS +#undef TARG_FUNC + +//****************************************************************************** +// Implementation +//****************************************************************************** + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" + +#define TARG_CLASS "_TargetIterator<T>::" + +//****************************************************************************** +// TargetIterator::advance +//****************************************************************************** + +template<typename T> +void _TargetIterator<T>::advance() +{ + TargetService& l_targetService = targetService(); + + // If cursor points to end()/NULL, do nothing. Otherwise, check to see if + // it should advance (possibly to NULL) + if(iv_pCurrent != NULL) + { + // Advance to end() if no targets available. Otherwise, check to see if + // it should advance (possibly to NULL) + if (l_targetService.iv_maxTargets > 0) + { + // If at or past last element, advance to end() else advance + if(iv_pCurrent >= + &(*l_targetService.iv_targets)[l_targetService.iv_maxTargets-1]) + { + iv_pCurrent = NULL; + } + else + { + iv_pCurrent++; + } + } + else + { + iv_pCurrent = NULL; + } + } +} + +//****************************************************************************** +// Explicit template class member function instantiations +//****************************************************************************** + +template void _TargetIterator<Target*>::advance(); +template void _TargetIterator<const Target*>::advance(); + +#undef TARG_CLASS +#undef TARG_NAMESPACE + +} // End namespace TARGETING + + + diff --git a/src/usr/targeting/makefile b/src/usr/targeting/makefile index 09b9d3be3..70edd18ac 100644 --- a/src/usr/targeting/makefile +++ b/src/usr/targeting/makefile @@ -1,7 +1,26 @@ ROOTPATH = ../../.. MODULE = targeting -OBJS = target.o targetservice.o entitypath.o fakepnordata.o +VPATH = \ + predicates: \ + iterators: + +PREDICATES_OBJS = \ + predicatebase.o \ + predicatepostfixexpr.o \ + predicatectm.o + +ITERATORS_OBJS = \ + targetiterator.o \ + rangefilter.o + +TARGET_OBJS = \ + target.o \ + targetservice.o \ + entitypath.o \ + fakepnordata.o + +OBJS = ${TARGET_OBJS} ${PREDICATES_OBJS} ${ITERATORS_OBJS} SUBDIRS = test.d diff --git a/src/usr/targeting/predicates/predicatebase.C b/src/usr/targeting/predicates/predicatebase.C new file mode 100644 index 000000000..61e17b984 --- /dev/null +++ b/src/usr/targeting/predicates/predicatebase.C @@ -0,0 +1,54 @@ + +/** + * @file predicatebase.C + * + * @brief Implementation for an abstract targeting predicate which filters a + * set of targets based on the programmed criteria. Only required to + * implement the virtual destrutor which leads to duplicate weak symbols + * if it were instead inlined. + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD + +// Other Host Boot Components + +// Targeting Component +#include <targeting/predicates/predicatebase.H> + +//****************************************************************************** +// Macros +//****************************************************************************** + +#undef TARG_NAMESPACE +#undef TARG_CLASS +#undef TARG_FN + +//****************************************************************************** +// Interface +//****************************************************************************** + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" +#define TARG_CLASS "PredicateBase::" + +//****************************************************************************** +// PredicateBase::~PredicateBase +//****************************************************************************** + +PredicateBase::~PredicateBase() +{ + #define TARG_FN "~PredicateBase()" + #undef TARG_FN +} + +#undef TARG_CLASS +#undef TARG_NAMESPACE + +} // End namespace TARGETING + diff --git a/src/usr/targeting/predicates/predicatectm.C b/src/usr/targeting/predicates/predicatectm.C new file mode 100644 index 000000000..8185020f5 --- /dev/null +++ b/src/usr/targeting/predicates/predicatectm.C @@ -0,0 +1,63 @@ + +/** + * @file predicatectm.C + * + * @brief Implementation for a predicate which fiters a target based on its + * class, type, and model. + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD + +// Other Host Boot Components + +// Targeting Component +#include <targeting/target.H> +#include <targeting/attributeenums.H> +#include <targeting/predicates/predicatectm.H> + +//****************************************************************************** +// Macros +//****************************************************************************** + +#undef TARG_NAMESPACE +#undef TARG_CLASS +#undef TARG_FN + +//****************************************************************************** +// Interface +//****************************************************************************** + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" +#define TARG_CLASS "PredicateCTM::" + +//****************************************************************************** +// PredicateCTM::operator() +//****************************************************************************** + +bool PredicateCTM::operator()( + const Target* const i_pTarget) const +{ + #define TARG_FUNC "operator()(...)" + + return ( ( (iv_class == CLASS_NA) + || (i_pTarget->getAttr<ATTR_CLASS>() == iv_class)) + && ( (iv_type == TYPE_NA) + || (i_pTarget->getAttr<ATTR_TYPE>() == iv_type)) + && ( (iv_model == MODEL_NA) + || (i_pTarget->getAttr<ATTR_MODEL>() == iv_model))); + + #undef TARG_FUNC +} + +#undef TARG_CLASS +#undef TARG_NAMESPACE + +} // End namespace TARGETING + diff --git a/src/usr/targeting/predicates/predicatepostfixexpr.C b/src/usr/targeting/predicates/predicatepostfixexpr.C new file mode 100644 index 000000000..7f5e89260 --- /dev/null +++ b/src/usr/targeting/predicates/predicatepostfixexpr.C @@ -0,0 +1,198 @@ + +/** + * @file predicatepostfixexpr.C + * + * @brief Implementation for predicate which allows callers to chain multiple + * other predicates together in complex logical expressions, and then + * evaluate them against a target + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD + +// Other Host Boot Components +#include <assert.h> + +// Targeting Component +#include <targeting/predicates/predicatepostfixexpr.H> +#include "../trace.H" + +//****************************************************************************** +// Macros +//****************************************************************************** + +#undef TARG_NAMESPACE +#undef TARG_CLASS +#undef TARG_FN + +//****************************************************************************** +// Interface +//****************************************************************************** + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" +#define TARG_CLASS "PredicatePostfixExpr::" + +//****************************************************************************** +// PredicatePostfixExpr::PredicatePostfixExpr +//****************************************************************************** + +PredicatePostfixExpr::PredicatePostfixExpr() +{ +} + +//****************************************************************************** +// PredicatePostfixExpr::~PredicatePostfixExpr +//****************************************************************************** + +PredicatePostfixExpr::~PredicatePostfixExpr() +{ +} + +//****************************************************************************** +// PredicatePostfixExpr::push +//****************************************************************************** + +PredicatePostfixExpr& PredicatePostfixExpr::push( + const PredicateBase* const i_pPredicate) +{ + #define TARG_FN "push(...)" + + assert(i_pPredicate != NULL, + TARG_LOC "Caller supplied a NULL predicate"); + Operation l_op = {EVAL,i_pPredicate}; + iv_ops.push_back(l_op); + return *this; + + #undef TARG_FN +} + +//****************************************************************************** +// PredicatePostfixExpr::And +//****************************************************************************** + +PredicatePostfixExpr& PredicatePostfixExpr::And() +{ + #define TARG_FN "And()" + + Operation l_op = {AND,NULL}; + iv_ops.push_back(l_op); + return *this; + + #undef TARG_FN +} + +//****************************************************************************** +// PredicatePostfixExpr::Not +//****************************************************************************** + +PredicatePostfixExpr& PredicatePostfixExpr::Not() +{ + #define TARG_FN "Not()" + + Operation l_op = {NOT,NULL}; + iv_ops.push_back(l_op); + return *this; + + #undef TARG_FN +} + +//****************************************************************************** +// PredicatePostfixExpr::Or +//****************************************************************************** + +PredicatePostfixExpr& PredicatePostfixExpr::Or() +{ + #define TARG_FN "Or()" + + Operation l_op = {OR,NULL}; + iv_ops.push_back(l_op); + return *this; + + #undef TARG_FN +} + +//****************************************************************************** +// PredicatePostfixExpr::operator() +//****************************************************************************** + +bool PredicatePostfixExpr::operator()( + const Target* const i_pTarget) const +{ + #define TARG_FN "operator()(...)" + + assert(i_pTarget != NULL, + TARG_LOC "Caller supplied a NULL target"); + + std::vector<bool> l_stack; + bool l_result = false; + + for(uint32_t i=0; i<iv_ops.size(); ++i) + { + switch(iv_ops[i].logicalOp) + { + case EVAL: + l_stack.push_back((*iv_ops[i].pPredicate)(i_pTarget)); + break; + case AND: + assert(l_stack.size() >= 2, + TARG_LOC "Stack for AND must be >=2 but is %d", + l_stack.size()); + l_result = l_stack.back(); + l_stack.pop_back(); + l_stack.back() &= l_result; + break; + case OR: + assert(l_stack.size() >= 2, + TARG_LOC "Stack for OR must be >= 2 but is %d", + l_stack.size()); + l_result = l_stack.back(); + l_stack.pop_back(); + l_stack.back() |= l_result; + break; + case NOT: + assert(l_stack.size() >= 1, + TARG_LOC "Stack for NOT must be >= 1 but is %d", + l_stack.size()); + l_stack.back() = !l_stack.back(); + break; + default: + assert(0, + TARG_LOC "Attempted to evaluate unsupported " + "logical operation %d", + iv_ops[i].logicalOp); + break; + } + } + + // If no predicates and we haven't asserted (no misformatting), element + // should be returned + if(l_stack.size() == 0) + { + l_result = true; + } + else + { + assert(l_stack.size() == 1, + TARG_LOC "Postfix expression created incorrectly. Stack " + "size should be 1 but is %d", + l_stack.size()); + + l_result = l_stack.front(); + } + + return l_result; + + #undef TARG_FN +} + +#undef TARG_CLASS +#undef TARG_NAMESPACE + +} // End namespace TARGETING + diff --git a/src/usr/targeting/targetservice.C b/src/usr/targeting/targetservice.C index 4418358ef..3b3b4098b 100644 --- a/src/usr/targeting/targetservice.C +++ b/src/usr/targeting/targetservice.C @@ -23,6 +23,7 @@ #include <targeting/targetservice.H> #include "trace.H" #include "fakepnordata.H" +#include <targeting/predicates/predicatebase.H> //****************************************************************************** // targetService @@ -162,6 +163,72 @@ void TargetService::init() } //****************************************************************************** +// TargetService::begin (non-const version) +//****************************************************************************** + +TargetService::iterator TargetService::begin() +{ + #define TARG_FN "begin()" + + assert(iv_initialized); + + Target* l_pFirstTarget = (iv_maxTargets == 0) ? NULL : &(*iv_targets)[0]; + + return iterator(l_pFirstTarget); + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::begin (const version) +//****************************************************************************** + +//TargetService::const_iterator +_TargetIterator<const Target*> TargetService::begin() const +{ + #define TARG_FN "begin() const" + + assert(iv_initialized); + + const Target* l_pFirstTarget = + (iv_maxTargets == 0) ? NULL : &(*iv_targets)[0]; + + return const_iterator(l_pFirstTarget); + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::end (non-const version) +//****************************************************************************** + +TargetService::iterator TargetService::end() +{ + #define TARG_FN "end()" + + assert(iv_initialized); + + return iterator(NULL); + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::end (const version) +//****************************************************************************** + +TargetService::const_iterator TargetService::end() const +{ + #define TARG_FN "end() const" + + assert(iv_initialized); + + return const_iterator(NULL); + + #undef TARG_FN +} + +//****************************************************************************** // TargetService::getTopLevelTarget //****************************************************************************** @@ -305,10 +372,11 @@ bool TargetService::tryGetPath( //****************************************************************************** void TargetService::getAssociated( - const Target* const i_pTarget, - const ASSOCIATION_TYPE i_type, - const RECURSION_LEVEL i_recursionLevel, - TargetHandleList& o_list) const + TargetHandleList& o_list, + const Target* const i_pTarget, + const ASSOCIATION_TYPE i_type, + const RECURSION_LEVEL i_recursionLevel, + const PredicateBase* const i_pPredicate) const { #define TARG_FN "getAssociated(...)" @@ -340,13 +408,13 @@ void TargetService::getAssociated( if (iv_associationMappings[i].associationDir == INWARDS) { (void) _getInwards(iv_associationMappings[i].attr, - i_recursionLevel, l_entityPath, o_list); + i_recursionLevel, l_entityPath, i_pPredicate, o_list); } else if (iv_associationMappings[i].associationDir == OUTWARDS) { (void) _getOutwards(iv_associationMappings[i].attr, - i_recursionLevel, l_entityPath, o_list); + i_recursionLevel, l_entityPath, i_pPredicate, o_list); } else { @@ -509,10 +577,11 @@ uint32_t TargetService::_maxTargets() //****************************************************************************** void TargetService::_getInwards( - const ATTRIBUTE_ID i_attr, - const RECURSION_LEVEL i_recursionLevel, - EntityPath i_entityPath, - TargetHandleList& o_list) const + const ATTRIBUTE_ID i_attr, + const RECURSION_LEVEL i_recursionLevel, + EntityPath i_entityPath, + const PredicateBase* const i_pPredicate, + TargetHandleList& o_list) const { #define TARG_FN "_getInwards(...)" @@ -524,7 +593,10 @@ void TargetService::_getInwards( EntityPath l_candidatePath; bool l_candidateFound = tryGetPath(i_attr, &(*iv_targets)[i], l_candidatePath); - if (l_candidateFound && (l_candidatePath == i_entityPath)) + if ( l_candidateFound + && (l_candidatePath == i_entityPath) + && ( (i_pPredicate == NULL) + || (*i_pPredicate)( &(*iv_targets)[i]) ) ) { o_list.push_back(&(*iv_targets)[i]); break; @@ -545,10 +617,11 @@ void TargetService::_getInwards( //****************************************************************************** void TargetService::_getOutwards( - const ATTRIBUTE_ID i_attr, - const RECURSION_LEVEL i_recursionLevel, - EntityPath i_entityPath, - TargetHandleList& o_list) const + const ATTRIBUTE_ID i_attr, + const RECURSION_LEVEL i_recursionLevel, + EntityPath i_entityPath, + const PredicateBase* const i_pPredicate, + TargetHandleList& o_list) const { #define TARG_FN "_getOutwards()...)" @@ -573,7 +646,9 @@ void TargetService::_getOutwards( || ( (i_recursionLevel == ALL) && (l_candidatePath.size() > i_entityPath.size()))) { - if (i_entityPath.equals(l_candidatePath,i_entityPath.size())) + if ( i_entityPath.equals(l_candidatePath,i_entityPath.size()) + && ( (i_pPredicate == NULL) + || (*i_pPredicate)( &(*iv_targets)[i]) ) ) { o_list.push_back(&(*iv_targets)[i]); } @@ -591,3 +666,4 @@ void TargetService::_getOutwards( #undef TARG_NAMESPACE } // End namespace TARGETING + diff --git a/src/usr/targeting/test/targetingtest.H b/src/usr/targeting/test/targetingtest.H index bd8ffdb0e..309bf3606 100644 --- a/src/usr/targeting/test/targetingtest.H +++ b/src/usr/targeting/test/targetingtest.H @@ -23,6 +23,9 @@ #include <targeting/entitypath.H> #include <targeting/target.H> #include <targeting/targetservice.H> +#include <targeting/iterators/rangefilter.H> +#include <targeting/predicates/predicatectm.H> +#include <targeting/predicates/predicatepostfixexpr.H> class TargetingTestSuite: public CxxTest::TestSuite { @@ -128,9 +131,11 @@ class TargetingTestSuite: public CxxTest::TestSuite // TargetHandleList& o_list) const; TargetHandleList l_list; - (void) l_targetService.getAssociated(l_pTopLevel, + (void) l_targetService.getAssociated( + l_list, + l_pTopLevel, TARGETING::TargetService::CHILD, - TARGETING::TargetService::IMMEDIATE, l_list); + TARGETING::TargetService::IMMEDIATE); if (!l_list.size()) { TS_FAIL("Should have found some child elements" ); @@ -140,9 +145,11 @@ class TargetingTestSuite: public CxxTest::TestSuite // target TargetHandleList l_parentList; - (void) l_targetService.getAssociated(l_list[0], + (void) l_targetService.getAssociated( + l_parentList, + l_list[0], TARGETING::TargetService::PARENT, - TARGETING::TargetService::IMMEDIATE, l_parentList); + TARGETING::TargetService::IMMEDIATE); if (l_parentList.size() != 1) { @@ -155,18 +162,22 @@ class TargetingTestSuite: public CxxTest::TestSuite "handle" ); } - (void) l_targetService.getAssociated(l_pTopLevel, + (void) l_targetService.getAssociated( + l_list, + l_pTopLevel, TARGETING::TargetService::CHILD_BY_AFFINITY, - TARGETING::TargetService::IMMEDIATE, l_list); + TARGETING::TargetService::IMMEDIATE); if (!l_list.size()) { TS_FAIL("Should have found some child elements" ); } - (void) l_targetService.getAssociated(l_pTopLevel, + (void) l_targetService.getAssociated( + l_list, + l_pTopLevel, TARGETING::TargetService::CHILD_BY_AFFINITY, - TARGETING::TargetService::ALL, l_list); + TARGETING::TargetService::ALL); if (!l_list.size()) { @@ -452,6 +463,512 @@ class TargetingTestSuite: public CxxTest::TestSuite TS_TRACE(EXIT_MRK "testTargetClass" ); } + + void testPredicateCtm() + { + 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) + { + TS_FAIL("Top level handle was NULL when initialization " + "complete"); + } + + PredicateCTM l_allWild; + if( ! l_allWild(l_pTopLevel) ) + { + TS_FAIL("CTM all wildcards filter should have matched system " + "target"); + } + + PredicateCTM l_typeModelWild(CLASS_SYS); + if( ! l_typeModelWild(l_pTopLevel) ) + { + TS_FAIL("CTM class sys, remaining wildcards filter should have " + "matched system "); + } + + PredicateCTM l_modelWild(CLASS_SYS,TYPE_SYS); + if( ! l_modelWild(l_pTopLevel) ) + { + TS_FAIL("CTM class sys, type sys, remaining wildcards filter " + "should have matched system "); + } + + PredicateCTM l_noWild(CLASS_SYS,TYPE_SYS,MODEL_POWER8); + if( ! l_noWild(l_pTopLevel) ) + { + TS_FAIL("CTM class sys, type sys, model power8 should have " + "matched system "); + } + + PredicateCTM l_classWild(CLASS_NA,TYPE_SYS,MODEL_POWER8); + if( ! l_classWild(l_pTopLevel) ) + { + TS_FAIL("CTM class wild, type sys, model power8 should have " + "matched system "); + } + + PredicateCTM l_typeWild(CLASS_SYS,TYPE_NA,MODEL_POWER8); + if( ! l_typeWild(l_pTopLevel) ) + { + TS_FAIL("CTM class sys, wild, model power8 should have " + "matched system "); + } + + PredicateCTM l_classModelWild(CLASS_NA,TYPE_SYS,MODEL_NA); + if( ! l_classModelWild(l_pTopLevel) ) + { + 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) ) + { + TS_FAIL("CTM wild, wild, model should have " + "matched system "); + } + + PredicateCTM l_chipClass(CLASS_CHIP,TYPE_NA,MODEL_NA); + if( l_chipClass(l_pTopLevel) ) + { + 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; + + TS_TRACE(EXIT_MRK "testPredicateCtm" ); + + } + + void testPredicatePostfixExpr() + { + 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) + { + TS_FAIL("Top level handle was NULL when initialization " + "complete"); + } + + PredicatePostfixExpr l_alwaysTrueExpr; + if(!l_alwaysTrueExpr(l_pTopLevel) ) + { + 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) ) + { + 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_power8Model(CLASS_NA,TYPE_NA,MODEL_POWER8); + PredicatePostfixExpr l_expr; + l_expr.push(&l_sysClass).push(&l_sysType).And(); + l_expr.push(&l_power8Model).And(); + + if(!l_expr(l_pTopLevel) ) + { + TS_FAIL("CTM of class sys && type sys && model power8 should " + "have matched system"); + } + + l_expr.Not(); + + if(l_expr(l_pTopLevel) ) + { + TS_FAIL("CTM of class sys && type sys && model power8 should " + "npt have matched system after negation"); + } + + l_expr.push(&l_sysClass); + l_expr.Or(); + + if(!l_expr(l_pTopLevel) ) + { + TS_FAIL("CTM of class sys && type sys && model power8 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_power8Model).And(); + delete (static_cast<PredicateBase*>(l_pExpr)); + + #if 0 + PredicatePostfixExpr l_lhs; + PredicatePostfixExpr l_rhs; + + l_lhs = l_rhs; + + PredicatePostfixExpr l_cpCtor(l_rhs); + #endif + + + TS_TRACE(EXIT_MRK "testPredicatePostfixExpr" ); + } + + void testTargetIterator() + { + TS_TRACE(ENTER_MRK "testTargetIterator"); + + using namespace TARGETING; + TargetService& l_targetService = targetService(); + + + TargetIterator l_pIt; + if( l_pIt != l_targetService.end() ) + { + TS_FAIL("Default TargetIterator should point to past the end " + "of container"); + } + + ++l_pIt; + if( l_pIt != l_targetService.end() ) + { + 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) + { + 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) + { + TS_FAIL("Top level handle was NULL when initialization " + "complete"); + } + + l_pIt = l_targetService.begin(); + if((*l_pIt) == NULL) + { + TS_FAIL("TargetService begin() should return !NULL"); + } + + CLASS l_class = CLASS_NA; + if( !l_pIt->tryGetAttr<ATTR_CLASS>(l_class) ) + { + TS_FAIL("Failed to get expected class attribute"); + } + + TargetIterator l_rhs = l_targetService.begin(); + if( ! (l_pIt == l_rhs) ) + { + TS_FAIL("Iterators should be equal, but aren't"); + } + + l_rhs = l_targetService.begin(); + if( l_pIt != l_rhs ) + { + TS_FAIL("Iterators should be equal, but aren't"); + } + + TargetIterator l_rhs2 = l_targetService.begin(); + ++l_rhs2; + ++l_pIt; + if( l_pIt != l_rhs2 ) + { + TS_FAIL("Iterators should be equal, but aren't"); + } + + l_rhs2++; + l_pIt++; + if( l_pIt != l_rhs2 ) + { + TS_FAIL("Iterators should be equal, but aren't"); + } + + TargetIterator l_pItClone(l_rhs2); + if( l_pIt != l_pItClone) + { + TS_FAIL("Iterators should be equal, but aren't"); + } + + if(l_pIt != l_pItClone++) + { + TS_FAIL("Iterators should be equal, but aren't"); + } + + if( (++l_pIt) != l_pItClone) + { + TS_FAIL("Iterators should be equal, but aren't"); + } + + const TargetService& l_constTargetService = targetService(); + + ConstTargetIterator l_pConstIt; + if( l_pConstIt != l_constTargetService.end() ) + { + TS_FAIL("Default ConstTargetIterator should point to past the " + "end of container"); + } + + l_pConstIt = l_constTargetService.begin(); + if( (*l_pConstIt) == NULL) + { + TS_FAIL("Iterator does not point to valid Target as expected"); + } + + TS_TRACE(EXIT_MRK "testTargetIterator" ); + } + + void testRangeFilter(void) + { + 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) + ) + { + TS_FAIL("Target* pointed to by Begin/next NULL -or- begin ==" + "next"); + } + + l_f1.reset(); + if( *l_f1 != l_pBegin ) + { + 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 ) + { + 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<ATTR_TYPE>() != TYPE_PROC) + { + TS_FAIL("Should only have returned type proc"); + break; + } + } + + TargetIterator l_pIt = targetService().begin(); + ++l_pIt; + ++l_pIt; + + if(l_pIt == targetService().end()) + { + 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) + { + TS_FAIL("Should have gotten 2 elements %d",i); + } + + TS_TRACE(EXIT_MRK "testRangeFilter" ); + } + + void testComplexFilter(void) + { + 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++) + { + } + + TS_TRACE(INF_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<ATTR_PHYS_PATH>(); + l_path.dump(); + } + + TS_TRACE(INF_MRK "Found %d targets that are chips or enclosures ", + l_count); + + l_query.Not(); + f.reset(); + + l_count = 0; + for(; f; ++f, ++l_count) + { + } + + TS_TRACE(INF_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) + { + 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; i<l_list.size(); ++i, ++l_count) + { + EntityPath l_path = l_list[i]->getAttr<ATTR_PHYS_PATH>(); + l_path.dump(); + } + + TS_TRACE(INF_MRK "Found %d targets that are ex/mba units off " + "master processor",l_count); + + TS_TRACE(EXIT_MRK "testComplexFilter" ); + } }; #endif // End __TESTTARGETING_H diff --git a/src/usr/targeting/trace.H b/src/usr/targeting/trace.H index d16ef8ece..e7ffe0365 100644 --- a/src/usr/targeting/trace.H +++ b/src/usr/targeting/trace.H @@ -22,6 +22,8 @@ namespace TARGETING extern trace_desc_t* g_trac_targeting; } +#define TARG_LOC TARG_NAMESPACE TARG_CLASS TARG_FN ": " + #define TARG_TAG "[TARG]" #define TARG_ENTER(args...) \ TRACFCOMP(TARGETING::g_trac_targeting,TARG_TAG " " ENTER_MRK " " TARG_NAMESPACE \ |