blob: dcc1568c5f766e3f6c01a9fad7cbec8f4f4f809b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 CEA LIST.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Created on: 25 juil. 2008
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* Alain Faivre (CEA LIST) alain.faivre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "TransitionCoverageFilter.h"
#include <computer/primitive/AvmCommunicationFactory.h>
#include <fml/executable/ExecutableForm.h>
#include <fml/executable/ExecutableQuery.h>
#include <fml/executable/InstanceOfMachine.h>
#include <fml/expression/ExpressionConstructor.h>
#include <fml/common/SpecifierElement.h>
#include <fml/runtime/ExecutionConfiguration.h>
#include <fml/runtime/ExecutionData.h>
#include <fml/runtime/RuntimeForm.h>
#include <fml/runtime/RuntimeID.h>
#include <fml/workflow/Query.h>
#include <fml/workflow/WObject.h>
#include <fam/queue/WaitingStrategy.h>
#include <fam/queue/ExecutionQueue.h>
#include <sew/Configuration.h>
#include <sew/SymbexControllerRequestManager.h>
namespace sep
{
/**
***************************************************************************
prototype filter::transition_coverage as &avm::core.filter.PROGRAM_COVERAGE is
section PROPERTY
// Nombre de pas de calcul "cumulés" avant de débuter
// la vérification de la couverture
@begin_step = 0;
// Arrète l'exécution dès que la couverture est complète
@stop = true;
// Arrète l'exécution au plutôt
@minimize = true;
// Arrète l'exécution du chemin courant dès qu'un objectif est atteint
@break = true;
// Elagage du graphe des scénarios à la fin de la vérification
@slice = true;
// Active l'utilisation d'heuristique
@heuristic = true;
// choix de l'heuristique de départ
// basic | naive | smart | agressive
@heuristic#start = 'basic';
// Nombre d'essais d'heuristiques
@heuristic#trials = 7;
// Critère de satisfaction du succès des heuristiques
// taux de couverte / nombre d'élément restant...
@objective#rate = 95;
@objective#rest = 5;
// Choix des contextes avec des transitions
// [ fortement | faiblement | autre ] tirables
// Limitations temporaire de la profondeur d'exploration
@coverage#height = 7;
// nombre de fois que la limite doit être atteint avant de l'augmenter
@coverage#height#reached#limit = 42;
@hit#strongly#random = false;
@hit#strongly#count = 1;
@hit#weakly#random = false;
@hit#weakly#count = 1;
@hit#other#random = false;
@hit#other#count = 1;
@scope = 'DETAILS'; // 'INSTANCE' | 'FORM' | 'DETAILS'
endsection PROPERTY
// Utilisé pour préciser les machines ou les transitions particulières à couvrir!
section DETAILS
@form = spec::ascenseur.ascenseur.controler;
@instance = spec::ascenseur.ascenseur.enregistrer;
@transition = spec::ascenseur.ascenseur.aller_a_l_etage.attente.transition#6;
endsection DETAILS
endprototype
***************************************************************************
*/
/**
* DESTRUCTOR
*/
TransitionCoverageFilter::~TransitionCoverageFilter()
{
if( mExecutableCoverageTable != NULL )
{
const ExecutionData & anED = getConfiguration().getMainExecutionData();
avm_size_t endOffset = mTransitionCoverageTable->size();
for( avm_size_t i = 0 ; i < endOffset ; ++i )
{
if( mTransitionCoverageTable->at(i) != mExecutableCoverageTable->
at(anED.getRuntime(i).getExecutable()->getOffset()) )
{
delete( mTransitionCoverageTable->at(i) );
}
}
delete( mTransitionCoverageTable );
endOffset = mExecutableCoverageTable->size();
for( avm_size_t i = 0 ; i < endOffset ; ++i )
{
if( mExecutableCoverageTable->at(i) != NULL )
{
delete( mExecutableCoverageTable->at(i) );
}
}
delete( mExecutableCoverageTable );
}
else if( mTransitionCoverageTable != NULL )
{
avm_size_t endOffset = mTransitionCoverageTable->size();
for( avm_size_t i = 0 ; i < endOffset ; ++i )
{
if( mTransitionCoverageTable->at(i) != NULL )
{
delete( mTransitionCoverageTable->at(i) );
}
}
delete( mTransitionCoverageTable );
}
}
/**
* CONFIGURE
*/
bool TransitionCoverageFilter::configureImpl()
{
// SUPER CONFIGURATION
mConfigFlag = BaseCoverageFilter::configureImpl();
WObject * thePROPERTY = Query::getRegexWSequence(
getParameterWObject(), OR_WID2("property", "PROPERTY"));
if( thePROPERTY != WObject::_NULL_ )
{
mNbCoverage = Query::getWPropertyPosSizeT(
thePROPERTY, "nbCoverage", AVM_NUMERIC_MAX_SIZE_T);
mCoverageHeight = mCoverageHeightPeriod =
Query::getRegexWPropertySizeT(
thePROPERTY, CONS_WID2("coverage", "height"), 0);
mCoverageHeightReachedLimit = Query::getRegexWPropertySizeT(thePROPERTY,
CONS_WID4("coverage", "height", "reached", "limit"), 0);
// Options pour les transitions fortement tirables
mHitStronglyRandomFlag = Query::getRegexWPropertyBoolean(
thePROPERTY, CONS_WID3("hit", "strongly", "random"), false);
mHitStronglyCount = Query::getRegexWPropertyPosSizeT(
thePROPERTY, CONS_WID3("hit", "strongly", "count"), 1);
// Options pour les transitions faiblement tirables
mHitWeaklyRandomFlag = Query::getRegexWPropertyBoolean(
thePROPERTY, CONS_WID3("hit", "weakly", "random"), false);
mHitWeaklyCount = Query::getRegexWPropertyPosSizeT(
thePROPERTY, CONS_WID3("hit", "weakly", "count"), 1);
// Options pour les autres transitions tirables ?
mHitOtherRandomFlag = Query::getRegexWPropertyBoolean(
thePROPERTY, CONS_WID3("hit", "other", "random"), false);
mHitOtherCount = Query::getRegexWPropertyPosSizeT(
thePROPERTY, CONS_WID3("hit", "other", "count"), 1);
const ExecutionData & anED = getConfiguration().getMainExecutionData();
mTransitionCoverageTable = new ArrayOfBitset(
anED.getTableOfRuntime().size(), NULL);
ExecutableQuery XQuery( getConfiguration() );
XQuery.getRuntimeExecutable( mTableofRuntimeExecutable );
mScope = Specifier::toDesignKind(
Query::getWPropertyString(thePROPERTY, "scope", "MODEL") );
switch( mScope )
{
case Specifier::DESIGN_INSTANCE_KIND:
{
// INITIALISATION de la table de tous les PROGRAM
// associés à chacune des INSTANCE...
configureInstanceCoverageTableFlag(false);
break;
}
case Specifier::DESIGN_MODEL_KIND:
{
// INITIALISATION de la table de tous les PROGRAM
// associés à chacune des EXECUTABLE...
configureExecutableCoverageTableFlag(false);
break;
}
default: // for << @scope = 'DETAILS'; >>
{
WObject * theDETAILS = Query::getRegexWSequence(
getParameterWObject(), OR_WID2("details", "DETAILS"));
if( theDETAILS != WObject::_NULL_ )
{
ExecutableForm * anExecutable = NULL;
AvmTransition * aTransition = NULL;
ListOfExecutableForm listOfExecutable;
ListOfInstanceOfMachine listOfInstance;
ListOfAvmTransition listOfTransition;
WObject::const_iterator itWfO = theDETAILS->owned_begin();
WObject::const_iterator endWfO = theDETAILS->owned_end();
for( ; itWfO != endWfO ; ++itWfO )
{
if( (*itWfO)->isWProperty() )
{
const std::string & kind = (*itWfO)->getNameID();
const std::string & qnid = (*itWfO)->toStringValue();
if( (kind == "model") || (kind == "form") ||
(kind == "executable") )
{
anExecutable =
XQuery.getExecutableByQualifiedNameID(
qnid ).to_ptr< ExecutableForm >();
if( anExecutable != NULL )
{
listOfExecutable.append(anExecutable);
}
else
{
AVM_OS_WARN << "Unfound the machine "
<< kind << " << " << qnid
<< " >> as coverage processor parameter:> "
<< getParameterWObject()
->getFullyQualifiedNameID()
<< std::endl;
}
}
else if( kind == "instance" )
{
const BF & anInstance = XQuery.searchMachine(
Specifier::DESIGN_INSTANCE_KIND, qnid);
if( anInstance.valid() )
{
listOfInstance.append(
anInstance.to_ptr< InstanceOfMachine >());
}
else
{
AVM_OS_WARN << "Unfound the machine "
<< kind << " << " << qnid
<< " >> as coverage processor parameter:> "
<< getParameterWObject()
->getFullyQualifiedNameID()
<< std::endl;
}
}
else if( kind == "transition" )
{
aTransition =
XQuery.getTransitionByQualifiedNameID(
qnid ).to_ptr< AvmTransition >();
if( aTransition != NULL )
{
listOfTransition.append(aTransition);
}
else
{
AVM_OS_WARN << "Unfound the "
<< kind << " << " << qnid
<< " >> as coverage processor parameter:> "
<< getParameterWObject()
->getFullyQualifiedNameID()
<< std::endl;
}
}
else if( kind == "program" )
{
aTransition =
XQuery.getTransitionByQualifiedNameID(
qnid ).to_ptr< AvmTransition >();
if( aTransition != NULL )
{
listOfTransition.append(aTransition);
}
else
{
AVM_OS_WARN << "Unfound the "
<< kind << " << " << qnid
<< " >> as coverage processor parameter:> "
<< getParameterWObject()
->getFullyQualifiedNameID()
<< std::endl;
}
}
else
{
AVM_OS_WARN << "Unexpected attribute << "
<< (*itWfO)->str()
<< " >> as coverage processor parameter:> "
<< getParameterWObject()
->getFullyQualifiedNameID()
<< std::endl;
}
}
}
// INITIALISATION de la table de tous les PROGRAM
// associés à chacun des EXECUTABLE...
configureExecutableCoverageTableFlag(true);
ListOfExecutableForm::iterator itExec = listOfExecutable.begin();
ListOfExecutableForm::iterator endExec = listOfExecutable.end();
for( ; itExec != endExec ; ++itExec )
{
configureExecutableCoverageTableFlag((*itExec), false);
}
// Cas des programmes
configureTransitionCoverageTableFlag(listOfTransition, false);
// INITIALISATION de la table de tous les PROGRAM
// associés à chacune des INSTANCE...
ListOfInstanceOfMachine::iterator itInst = listOfInstance.begin();
ListOfInstanceOfMachine::iterator endInst = listOfInstance.end();
for( ; itInst != endInst ; ++itInst )
{
if( (*itInst)->getExecutable()->hasTransition() )
{
configureInstanceCoverageTableFlag(anED,
anED.getRuntimeID(*itInst), false);
}
}
if( mExecutableCoverageTable != NULL)
{
if( mTransitionCoverageTable != NULL)
{
// INITIALISATION de la table de tous les PROGRAM
// associés à chacune des INSTANCE...
configureInstanceCoverageTableFlag();
}
else
{
mScope = Specifier::DESIGN_MODEL_KIND;
}
}
}
else
{
AVM_OS_WARN << "Unfound section << DETAILS >> "
"as coverage processor parameter:> "
<< getParameterWObject()->getFullyQualifiedNameID()
<< std::endl;
}
break;
}
}
AVM_IF_DEBUG_LEVEL_FLAG( MEDIUM , CONFIGURING )
AVM_OS_TRACE << "Uncovered Transition Count at the beginning :> "
<< mCoverageStatistics.mNumberOfElements << std::endl << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , CONFIGURING )
}
if( (mCoverageHeightPeriod == 0) ||
(mCoverageHeightPeriod == AVM_NUMERIC_MAX_SIZE_T) )
{
mCoverageHeight = mCoverageHeightPeriod = 7;
// mCoverageStatistics.mNumberOfElements;
}
mCoverageHeightReachedCount = 0;
mCoverageHeightReachedFlag = false;
if( mCoverageHeightReachedLimit == 0 )
{
mCoverageHeightReachedLimit = mCoverageStatistics.mNumberOfElements;
}
enablePreprocess( this );
return mConfigFlag;
}
void TransitionCoverageFilter::configureExecutableCoverageTableFlag(bool value)
{
if( mExecutableCoverageTable == NULL )
{
mExecutableCoverageTable = new ArrayOfBitset(
getConfiguration().getExecutableSystem().size(), NULL);
}
Bitset * tableOfFlag = NULL;
avm_size_t itTransition = 0;
avm_size_t endTransition = 0;
VectorOfExecutableForm::iterator itExec = mTableofRuntimeExecutable.begin();
VectorOfExecutableForm::iterator endExec = mTableofRuntimeExecutable.end();
for( ; itExec != endExec ; ++itExec )
{
if( (*itExec)->hasTransition() )
{
AVM_IF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING , (! value) )
AVM_OS_TRACE << "executable :> " << (*itExec)->getFullyQualifiedNameID()
<< std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING )
tableOfFlag = mExecutableCoverageTable->at((*itExec)->getOffset());
if( tableOfFlag == NULL )
{
tableOfFlag = new Bitset(
(*itExec)->getTransition().size(), true);
mExecutableCoverageTable->set(
(*itExec)->getOffset(), tableOfFlag);
}
endTransition = (*itExec)->getTransition().size();
for( itTransition = 0 ; itTransition < endTransition ; ++itTransition )
{
if( (not value) && tableOfFlag->test(itTransition) )
{
tableOfFlag->set(itTransition, value);
if( not value )
{
mCoverageStatistics.addUncoveredElement();
AVM_IF_DEBUG_LEVEL_FLAG( MEDIUM , CONFIGURING )
AVM_OS_TRACE << "\t" << "program :> "
<< (*itExec)->rawTransition(itTransition)->getFullyQualifiedNameID()
<< std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , CONFIGURING )
}
}
}
AVM_IF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING , (! value) )
AVM_OS_TRACE << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING )
}
else
{
mExecutableCoverageTable->set((*itExec)->getOffset(), NULL);
}
}
}
void TransitionCoverageFilter::configureExecutableCoverageTableFlag(
ExecutableForm * anExecutable, bool value)
{
if( mExecutableCoverageTable == NULL )
{
mExecutableCoverageTable = new ArrayOfBitset(
getConfiguration().getExecutableSystem().size(), NULL);
}
if( anExecutable->hasTransition() )
{
AVM_IF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING , (! value) )
AVM_OS_TRACE << "executable :> " << anExecutable->getFullyQualifiedNameID()
<< std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING )
Bitset * tableOfFlag =
mExecutableCoverageTable->at( anExecutable->getOffset() );
if( tableOfFlag == NULL )
{
tableOfFlag = new Bitset(anExecutable->getTransition().size(), true);
mExecutableCoverageTable->set(anExecutable->getOffset(), tableOfFlag);
}
avm_size_t endTransition = anExecutable->getTransition().size();
avm_size_t itTransition = 0;
for( ; itTransition < endTransition ; ++itTransition )
{
if( (! value) && tableOfFlag->test(itTransition) )
{
tableOfFlag->set(itTransition, value);
mCoverageStatistics.addUncoveredElement();
AVM_IF_DEBUG_LEVEL_FLAG( MEDIUM , CONFIGURING )
AVM_OS_TRACE << "\t" << "program :> "
<< anExecutable->rawTransition(itTransition)->getFullyQualifiedNameID()
<< std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , CONFIGURING )
}
}
AVM_IF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING , (! value) )
AVM_OS_TRACE << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING )
}
// Cas des sous machine executable
if( anExecutable->hasInstanceStatic() )
{
TableOfSymbol::const_iterator it = anExecutable->instance_static_begin();
TableOfSymbol::const_iterator endIt = anExecutable->instance_static_end();
for( ; it != endIt ; ++it )
{
configureExecutableCoverageTableFlag((*it).getExecutable(), value);
}
}
}
void TransitionCoverageFilter::configureInstanceCoverageTableFlag()
{
if( mExecutableCoverageTable != NULL)
{
const ExecutionData & anED = getConfiguration().getMainExecutionData();
RuntimeID aRID;
if( mTransitionCoverageTable == NULL )
{
mTransitionCoverageTable = new ArrayOfBitset(
anED.getTableOfRuntime().size(), NULL);
}
avm_size_t endMachine = mTransitionCoverageTable->size();
for( avm_size_t itMachine = 0 ; itMachine < endMachine ; ++itMachine )
{
aRID = anED.getRuntimeID(itMachine);
if( aRID.getExecutable()->hasTransition() &&
(mTransitionCoverageTable->at(itMachine) == NULL) )
{
mTransitionCoverageTable->set(itMachine,
mExecutableCoverageTable->at(
aRID.getExecutable()->getOffset()));
}
}
}
}
void TransitionCoverageFilter::configureInstanceCoverageTableFlag(bool value)
{
const ExecutionData & anED = getConfiguration().getMainExecutionData();
RuntimeID aRID;
Bitset * tableOfFlag = NULL;
avm_size_t itTransition = 0;
avm_size_t endTransition = 0;
if( mTransitionCoverageTable == NULL )
{
mTransitionCoverageTable = new ArrayOfBitset(
anED.getTableOfRuntime().size(), NULL);
}
avm_size_t endMachine = mTransitionCoverageTable->size();
for( avm_size_t itMachine = 0 ; itMachine < endMachine ; ++itMachine )
{
aRID = anED.getRuntimeID(itMachine);
if( aRID.getExecutable()->hasTransition() )
{
AVM_IF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING , (! value) )
AVM_OS_TRACE << "machine :> " << aRID.getFullyQualifiedNameID() << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING )
tableOfFlag = mTransitionCoverageTable->at( itMachine );
if( tableOfFlag == NULL )
{
tableOfFlag = new Bitset(
aRID.getExecutable()->getTransition().size(), true);
mTransitionCoverageTable->set(itMachine, tableOfFlag);
}
itTransition = 0;
endTransition = aRID.getExecutable()->getTransition().size();
for( ; itTransition < endTransition ; ++itTransition )
{
if( (! value) && tableOfFlag->test(itTransition) )
{
tableOfFlag->set(itTransition, value);
if( not value )
{
mCoverageStatistics.addUncoveredElement();
AVM_IF_DEBUG_LEVEL_FLAG( MEDIUM , CONFIGURING )
AVM_OS_TRACE << "\t" << "program :> "
<< aRID.getExecutable()->rawTransition(
itTransition )->getFullyQualifiedNameID()
<< std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , CONFIGURING )
}
}
}
AVM_IF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING , (! value) )
AVM_OS_TRACE << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING )
}
else
{
mTransitionCoverageTable->set(itMachine, NULL);
}
}
}
void TransitionCoverageFilter::configureInstanceCoverageTableFlag(
const ExecutionData & anED, const RuntimeID & aRID, bool value)
{
if( mExecutableCoverageTable == NULL )
{
configureExecutableCoverageTableFlag( true );
}
if( mTransitionCoverageTable == NULL )
{
mTransitionCoverageTable = new ArrayOfBitset(
anED.getTableOfRuntime().size(), NULL);
}
ExecutableForm * anExecutable = aRID.getExecutable();
if( (anExecutable != NULL) &&
(mTransitionCoverageTable->at(aRID.getOffset()) == NULL) )
{
if( anExecutable->hasTransition() &&
mExecutableCoverageTable->at(anExecutable->getOffset()) == NULL )
{
AVM_IF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING , (! value) )
AVM_OS_TRACE << "machine :> " << aRID.getFullyQualifiedNameID() << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING )
Bitset * tableOfFlag =
mTransitionCoverageTable->at( aRID.getOffset() );
if( tableOfFlag == NULL )
{
tableOfFlag = new Bitset(
anExecutable->getTransition().size(), true);
mTransitionCoverageTable->set(aRID.getOffset(), tableOfFlag);
}
avm_size_t endTransition = anExecutable->getTransition().size();
avm_size_t itTransition = 0;
for( ; itTransition < endTransition ; ++itTransition )
{
if( (not value) && tableOfFlag->test(itTransition) )
{
tableOfFlag->set(itTransition, value);
mCoverageStatistics.addUncoveredElement();
AVM_IF_DEBUG_LEVEL_FLAG( MEDIUM , CONFIGURING )
AVM_OS_TRACE << "\t" << "program :> "
<< anExecutable->rawTransition(itTransition)->getFullyQualifiedNameID()
<< std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , CONFIGURING )
}
}
AVM_IF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING , (! value) )
AVM_OS_TRACE << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING )
}
else if( anExecutable->hasTransition() )
{
AVM_IF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING , (! value) )
AVM_OS_TRACE << "machine :> " << aRID.getFullyQualifiedNameID() << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING )
Bitset * tableOfFlag =
mTransitionCoverageTable->at( aRID.getOffset() );
if( tableOfFlag == NULL )
{
tableOfFlag = new Bitset(
anExecutable->getTransition().size(), true);
mTransitionCoverageTable->set(aRID.getOffset(), tableOfFlag);
}
avm_size_t endTransition = anExecutable->getTransition().size();
avm_size_t itTransition = 0;
for( ; itTransition < endTransition ; ++itTransition )
{
tableOfFlag->set(itTransition,
value && mExecutableCoverageTable->at(
anExecutable->getOffset())->test(itTransition) );
if( (! value) && mExecutableCoverageTable->at(
anExecutable->getOffset())->test(itTransition) )
{
mCoverageStatistics.addUncoveredElement();
AVM_IF_DEBUG_LEVEL_FLAG( MEDIUM , CONFIGURING )
AVM_OS_TRACE << "\t" << "program :> "
<< anExecutable->rawTransition(itTransition)->getFullyQualifiedNameID()
<< std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , CONFIGURING )
}
}
AVM_IF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING , (! value) )
AVM_OS_TRACE << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING )
}
// Cas des sous machine instance
if( anED.getRuntime(aRID).hasChild() )
{
TableOfRuntimeID::const_iterator itSubMachine =
anED.getRuntime(aRID).beginChild();
TableOfRuntimeID::const_iterator endSubMachine =
anED.getRuntime(aRID).endChild();
for( ; itSubMachine != endSubMachine ; ++itSubMachine )
{
configureInstanceCoverageTableFlag(anED, (*itSubMachine), value);
}
}
}
}
void TransitionCoverageFilter::configureTransitionCoverageTableFlag(
ListOfAvmTransition & listOfTransition, bool value)
{
if( mExecutableCoverageTable == NULL )
{
mExecutableCoverageTable = new ArrayOfBitset(
getConfiguration().getExecutableSystem().size(), NULL);
}
Bitset * tableOfFlag = NULL;
avm_offset_t containerExecOffset = 0;
AVM_IF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING ,
(! value) && listOfTransition.nonempty() )
AVM_OS_TRACE << "program :> user details" << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING )
ListOfAvmTransition::iterator itProg = listOfTransition.begin();
ListOfAvmTransition::iterator endProg = listOfTransition.end();
for( ; itProg != endProg ; ++itProg )
{
containerExecOffset = (*itProg)->getExecutableContainer()->getOffset();
tableOfFlag = mExecutableCoverageTable->at(containerExecOffset);
if( tableOfFlag == NULL )
{
tableOfFlag = new Bitset((*itProg)->getExecutableContainer()
->getTransition().size(), true);
mExecutableCoverageTable->set(containerExecOffset, tableOfFlag);
}
if( (! value) && tableOfFlag->test( (*itProg)->getOffset() ) )
{
mExecutableCoverageTable->at( containerExecOffset )->set(
(*itProg)->getOffset(), value);
mCoverageStatistics.addUncoveredElement();
AVM_IF_DEBUG_LEVEL_FLAG( MEDIUM , CONFIGURING )
AVM_OS_TRACE << "\t" << "program :> "
<< (*itProg)->getFullyQualifiedNameID() << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , CONFIGURING )
}
}
AVM_IF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING ,
(! value) && listOfTransition.nonempty() )
AVM_OS_TRACE << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG_AND( MEDIUM , CONFIGURING )
}
Bitset * TransitionCoverageFilter::getCoverageTableBitset(
const RuntimeID & aRID)
{
switch( mScope )
{
case Specifier::DESIGN_MODEL_KIND:
{
return( mExecutableCoverageTable->at(
aRID.getExecutable()->getOffset() ) );
}
case Specifier::DESIGN_INSTANCE_KIND:
default:
{
return( mTransitionCoverageTable->at( aRID.getOffset() ) );
}
}
}
/*
* REPORT
*/
void TransitionCoverageFilter::reportMinimum(OutStream & os) const
{
os << TAB << "TRANSITION COVERAGE PROCESSOR" << EOL_FLUSH;
if( mCoverageStatistics.goalAchieved() )
{
os << TAB2 << "All the << " << mCoverageStatistics.mNumberOfElements
<< " >> transitions are covered !" << EOL;
}
else
{
os << TAB2 << "Warning: all the transitions are not covered !" << EOL;
mCoverageStatistics.toStreamCoverageRate( os << TAB2,
"Results: << ", " on "," >> are covered !\n" );
if( isReportDetails() )
{
os << TAB2 << "List of the << "
<< mCoverageStatistics.getNumberOfUncovered()
<< " >> transitions non covered:" << EOL2;
const ExecutionData & anED =
getConfiguration().getMainExecutionData();
RuntimeID aRID;
StringOutStream oss( os.INDENT );
bool hasOneUncoverdTransition = false;
avm_size_t offset;
avm_size_t endOffset;
AvmTransition * itTransition;
switch( mScope )
{
case Specifier::DESIGN_INSTANCE_KIND:
{
if( mTransitionCoverageTable == NULL )
{
break;
}
avm_size_t endMachine = mTransitionCoverageTable->size();
avm_size_t itMachine = 0;
for( ; itMachine < endMachine ; ++itMachine )
{
aRID = anED.getRuntimeID(itMachine);
if( aRID.getExecutable()->hasTransition() )
{
oss.str("");
if( not aRID.getExecutable()->isReachableState() )
{
oss << TAB2 << "instance[ NO INCOMING TRANSITION ] :> "
<< aRID.getFullyQualifiedNameID() << EOL;
}
hasOneUncoverdTransition = false;
endOffset = aRID.getExecutable()->getTransition().size();
for( offset = 0 ; offset < endOffset ; ++offset )
{
itTransition = aRID.getExecutable()->
getTransition().rawAt(offset);
if( not mTransitionCoverageTable->
at( aRID.getOffset() )->test( offset ) )
{
hasOneUncoverdTransition = true;
oss << TAB3 << itTransition->
strTransitionHeader() << EOL;
}
}
if( hasOneUncoverdTransition )
{
os << oss.str() << EOL;
}
}
}
break;
}
case Specifier::DESIGN_MODEL_KIND:
{
if( mExecutableCoverageTable == NULL )
{
break;
}
VectorOfExecutableForm::const_iterator itExec =
mTableofRuntimeExecutable.begin();
VectorOfExecutableForm::const_iterator endExec =
mTableofRuntimeExecutable.end();
for( avm_size_t indexExec = 0 ; itExec != endExec ;
++itExec , ++indexExec )
{
if( (*itExec)->hasTransition() )
{
oss.str("");
if( not (*itExec)->isReachableState() )
{
oss << TAB2 << "model[ NO INCOMING TRANSITION ] :> "
<< (*itExec)->getFullyQualifiedNameID() << EOL;
}
hasOneUncoverdTransition = false;
endOffset = (*itExec)->getTransition().size();
for( offset = 0 ; offset < endOffset ; ++offset )
{
itTransition = (*itExec)->getTransition().rawAt(offset);
if( not mExecutableCoverageTable->
at((*itExec)->getOffset())->test( offset ) )
{
hasOneUncoverdTransition = true;
oss << TAB3 << itTransition->
strTransitionHeader() << EOL;
}
}
if( hasOneUncoverdTransition )
{
os << oss.str() << EOL;
}
}
}
break;
}
default:
{
if( mExecutableCoverageTable != NULL )
{
VectorOfExecutableForm::const_iterator itExec =
mTableofRuntimeExecutable.begin();
VectorOfExecutableForm::const_iterator endExec =
mTableofRuntimeExecutable.end();
for( avm_size_t indexExec = 0 ; itExec != endExec ;
++itExec , ++indexExec )
{
if( (*itExec)->hasTransition() )
{
oss.str("");
if( not (*itExec)->isReachableState() )
{
oss << TAB2 << "model[ NO INCOMING TRANSITION ] :> "
<< (*itExec)->getFullyQualifiedNameID() << EOL;
}
hasOneUncoverdTransition = false;
endOffset = (*itExec)->getTransition().size();
for( offset = 0 ; offset < endOffset ; ++offset )
{
itTransition = (*itExec)->getTransition().rawAt(offset);
if( not mExecutableCoverageTable->
at((*itExec)->getOffset())->test( offset ) )
{
hasOneUncoverdTransition = true;
oss << TAB3 << itTransition->
strTransitionHeader() << EOL;
}
}
if( hasOneUncoverdTransition )
{
os << oss.str() << EOL;
}
}
}
}
if( mTransitionCoverageTable != NULL )
{
avm_size_t endMachine = mTransitionCoverageTable->size();
avm_size_t itMachine = 0;
for( ; itMachine < endMachine ; ++itMachine )
{
aRID = anED.getRuntimeID(itMachine);
if( aRID.getExecutable()->hasTransition() )
{
oss.str("");
if( not aRID.getExecutable()->isReachableState() )
{
oss << TAB2 << "instance[ NO INCOMING TRANSITION ] :> "
<< aRID.getFullyQualifiedNameID() << EOL;
}
hasOneUncoverdTransition = false;
endOffset = aRID.getExecutable()->getTransition().size();
for( offset = 0 ; offset < endOffset ; ++offset )
{
itTransition = aRID.getExecutable()->
getTransition().rawAt(offset);
if( (not mTransitionCoverageTable->
at(aRID.getOffset())->test(offset))
&& mExecutableCoverageTable->
at(aRID.getExecutable()->getOffset())->
test(offset) )
{
hasOneUncoverdTransition = true;
oss << TAB3 << itTransition->
strTransitionHeader() << EOL;
}
}
if( hasOneUncoverdTransition )
{
os << oss.str() << EOL;
}
}
}
}
break;
}
}
}
if ( isReportDetails() && mCoverageStatistics.hasUncovered() )
{
mCoverageStatistics.toStreamCoverageRate( os << TAB2,
"Results: << ", " on "," >> are covered !\n" );
}
}
if( mSliceFlag )
{
os << TAB2 << "Number of nodes cut back: " << mSliceCount << EOL;
}
os << std::flush;
}
void TransitionCoverageFilter::reportDefault(OutStream & os) const
{
reportHeader(os, "TRANSITION COVERAGE ");
if( mHeuristicProperty.mHeuristicEnabled )
{
os << std::boolalpha
<< " < chp:" << mCoverageHeightPeriod
<< " , ch:" << mCoverageHeight
<< " ; hsr:" << mHitStronglyRandomFlag
<< " , hsc:" << mHitStronglyCount
<< " ; hwr:" << mHitWeaklyRandomFlag
<< " , hwc:" << mHitWeaklyCount
<< " ; hor:" << mHitOtherRandomFlag
<< " , hoc:" << mHitOtherCount
<< " > "
<< std::noboolalpha;
}
os << EOL_FLUSH;
if( mCoverageStatistics.goalAchieved() )
{
os << TAB2 << "All the << " << mCoverageStatistics.mNumberOfElements
<< " >> transitions are covered !" << EOL;
}
else
{
os << TAB2 << "Warning: all the transitions are not covered !" << EOL;
mCoverageStatistics.toStreamCoverageRate( os << TAB2,
"Results: << ", " on "," >> are covered !\n" );
if( isReportDetails() )
{
os << TAB2 << "List of the << "
<< mCoverageStatistics.getNumberOfUncovered()
<< " >> transitions non covered:" << EOL << EOL;
const ExecutionData & anED = getConfiguration().getMainExecutionData();
RuntimeID aRID;
StringOutStream oss( os.INDENT );
bool hasOneUncoverdTransition = false;
avm_size_t offset;
avm_size_t endOffset;
AvmTransition * itTransition;
switch( mScope )
{
case Specifier::DESIGN_INSTANCE_KIND:
{
if( mTransitionCoverageTable == NULL )
{
break;
}
avm_size_t endMachine = mTransitionCoverageTable->size();
avm_size_t itMachine = 0;
for( ; itMachine < endMachine ; ++itMachine )
{
aRID = anED.getRuntimeID(itMachine);
if( aRID.getExecutable()->hasTransition() )
{
oss.str("");
oss << TAB2 << "instance";
if( not aRID.getExecutable()->isReachableState() )
{
oss << "[ NO INCOMING TRANSITION ]";
}
oss << " :> " << aRID.getFullyQualifiedNameID() << EOL;
hasOneUncoverdTransition = false;
endOffset = aRID.getExecutable()->getTransition().size();
for( offset = 0 ; offset < endOffset ; ++offset )
{
itTransition = aRID.getExecutable()->
getTransition().rawAt(offset);
if( not mTransitionCoverageTable->
at( aRID.getOffset() )->test( offset ) )
{
hasOneUncoverdTransition = true;
oss << TAB3 << itTransition->
strTransitionHeader() << EOL;
}
}
if( hasOneUncoverdTransition )
{
os << oss.str() << EOL;
}
}
}
break;
}
case Specifier::DESIGN_MODEL_KIND:
{
if( mExecutableCoverageTable == NULL )
{
break;
}
VectorOfExecutableForm::const_iterator itExec =
mTableofRuntimeExecutable.begin();
VectorOfExecutableForm::const_iterator endExec =
mTableofRuntimeExecutable.end();
for( avm_size_t indexExec = 0 ; itExec != endExec ;
++itExec , ++indexExec )
{
if( (*itExec)->hasTransition() )
{
oss.str("");
oss << TAB2 << "model";
if( not (*itExec)->isReachableState() )
{
oss << "[ NO INCOMING TRANSITION ]";
}
oss << " :> " << (*itExec)->getFullyQualifiedNameID() << EOL;
hasOneUncoverdTransition = false;
endOffset = (*itExec)->getTransition().size();
for( offset = 0 ; offset < endOffset ; ++offset )
{
itTransition = (*itExec)->getTransition().rawAt(offset);
if( not mExecutableCoverageTable->
at((*itExec)->getOffset())->test( offset ) )
{
hasOneUncoverdTransition = true;
oss << TAB3 << itTransition->
strTransitionHeader() << EOL;
}
}
if( hasOneUncoverdTransition )
{
os << oss.str() << EOL;
}
}
}
break;
}
default:
{
if( mExecutableCoverageTable != NULL )
{
VectorOfExecutableForm::const_iterator itExec =
mTableofRuntimeExecutable.begin();
VectorOfExecutableForm::const_iterator endExec =
mTableofRuntimeExecutable.end();
avm_size_t indexExec = 0;
for( ; itExec != endExec ; ++itExec , ++indexExec )
{
if( (*itExec)->hasTransition() )
{
oss.str("");
oss << TAB2 << "model";
if( not (*itExec)->isReachableState() )
{
oss << "[ NO INCOMING TRANSITION ]";
}
oss << " :> " << (*itExec)->getFullyQualifiedNameID() << EOL;
hasOneUncoverdTransition = false;
endOffset = (*itExec)->getTransition().size();
for( offset = 0 ; offset < endOffset ; ++offset )
{
itTransition = (*itExec)->getTransition().rawAt(offset);
if( not mExecutableCoverageTable->
at((*itExec)->getOffset())->test( offset ) )
{
hasOneUncoverdTransition = true;
oss << TAB3 << itTransition->
strTransitionHeader() << EOL;
}
}
if( hasOneUncoverdTransition )
{
os << oss.str() << EOL;
}
}
}
}
if( mTransitionCoverageTable != NULL )
{
avm_size_t endMachine = mTransitionCoverageTable->size();
avm_size_t itMachine = 0;
for( ; itMachine < endMachine ; ++itMachine )
{
aRID = anED.getRuntimeID(itMachine);
if( aRID.getExecutable()->hasTransition() )
{
oss.str("");
oss << TAB2 << "instance";
if( not aRID.getExecutable()->isReachableState() )
{
oss << "[ NO INCOMING TRANSITION ]";
}
oss << " :> " << aRID.getFullyQualifiedNameID() << EOL;
hasOneUncoverdTransition = false;
endOffset = aRID.getExecutable()->getTransition().size();
for( offset = 0 ; offset < endOffset ; ++offset )
{
itTransition = aRID.getExecutable()->
getTransition().rawAt(offset);
if( (not mTransitionCoverageTable->
at(aRID.getOffset())->test(offset))
&& mExecutableCoverageTable->
at(aRID.getExecutable()->getOffset())->
test(offset) )
{
hasOneUncoverdTransition = true;
oss << TAB3 << itTransition->
strTransitionHeader() << EOL;
}
}
if( hasOneUncoverdTransition )
{
os << oss.str() << EOL;
}
}
}
}
break;
}
}
}
if ( isReportDetails() && mCoverageStatistics.hasUncovered() )
{
mCoverageStatistics.toStreamCoverageRate( os << TAB2,
"Results: << ", " on "," >> are covered !\n" );
}
}
if( mSliceFlag )
{
os << TAB2 << "Number of nodes cut back: " << mSliceCount << EOL;
}
os << std::flush;
}
////////////////////////////////////////////////////////////////////////////////
// NON-REGRESSION TEST API
////////////////////////////////////////////////////////////////////////////////
void TransitionCoverageFilter::tddRegressionReportImpl(OutStream & os)
{
os << TAB1 << "COVERED TRANSITIONS : ";
if( mCoverageStatistics.goalAchieved() )
{
os << mCoverageStatistics.mNumberOfElements << " / "
<< mCoverageStatistics.mNumberOfElements << EOL;
}
else
{
os << mCoverageStatistics.getNumberOfUncovered() << " / "
<< mCoverageStatistics.mNumberOfElements << EOL;
}
//$ if( mSliceFlag )
// {
// os << TAB2 << "Number of nodes cut back: " << mSliceCount << EOL;
//$ }
os << std::flush;
}
/**
* PRE-FILTER
*/
bool TransitionCoverageFilter::prefilter()
{
bool mCondition =
( mNbCoverage > mCoverageStatistics.mNumberOfElements ) ?
mCoverageStatistics.goalAchieved() && mStopFlag :
(mCoverageStatistics.mNumberOfCovered >= mNbCoverage);
if( mCondition )
{
getSymbexRequestManager().postRequestStop( this );
return false;
}
return( getExecutionQueue().hasReady() );
}
/**
* postEval Filter
*/
bool TransitionCoverageFilter::postfilter()
{
ecQueue = &( getExecutionQueue().getResultQueue() );
if( mCoverageStatistics.hasUncovered() )
{
mCoverageStatistics.backupCovered();
ecQueueIt = ecQueue->begin();
ecQueueItEnd = ecQueue->end();
for( ; ecQueueIt != ecQueueItEnd ; ++ecQueueIt )
{
itEndEC = (*ecQueueIt)->end();
for( itEC = (*ecQueueIt)->begin() ; (itEC != itEndEC) ; ++itEC )
{
updateTransitionCoverageTable((*itEC) ,
(*itEC)->getRunnableElementTrace());
}
}
if( mHeuristicProperty.mHeuristicEnabled )
{
if( mTraceDirectiveRunningFlag )
{
if( runTraceDriver() )
{
//!! Continue driven
}
else
{
getSymbexRequestManager().postRequestRequeueWaiting( this );
}
if( mTraceDirectiveRunningFlag )
{
if( not mCoverageStatistics.updateFailedStep() )
{
mCoverageStatistics.resetFailedStep();
}
return( getExecutionQueue().hasResult() );
}
}
if( mCoverageStatistics.updateFailedStep() )
{
//!!! TODO optimization
if( mCoverageStatistics.isSeriouslyFailedStep() )
{
mHeuristicProperty.incrHeuristicClass();
getSymbexRequestManager().postRequestRequeueWaiting( this );
AVM_IF_DEBUG_FLAG( PROCESSOR )
AVM_OS_INFO << EMPHASIS(mHeuristicProperty.strHeuristicClass(), '*', 80);
AVM_ENDIF_DEBUG_FLAG( PROCESSOR )
}
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
mCoverageStatistics.toStreamFailedStep(AVM_OS_COUT,
"No new transition covered since << ", " step", " >> !!!\n");
mCoverageStatistics.toStreamFailedStep(AVM_OS_TRACE,
"No new transition covered since << ", " step", " >> !!!\n");
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
}
else
{
mCoverageStatistics.resetFailedStep();
}
switch( mHeuristicProperty.mHeuristicClass )
{
case IHeuristicClass::HEURISTIC_BASIC_CLASS:
{
mHeuristicProperty.mHeuristicClass =
IHeuristicClass::HEURISTIC_BASIC_CLASS;
heuristicNaiveClassImpl();
break;
}
case IHeuristicClass::HEURISTIC_NAIVE_CLASS:
{
heuristicNaiveClassImpl();
break;
}
case IHeuristicClass::HEURISTIC_SMART_CLASS:
{
heuristicSmartClassImpl();
break;
}
case IHeuristicClass::HEURISTIC_AGRESSIVE_CLASS:
{
heuristicAgressiveClassImpl();
break;
}
case IHeuristicClass::HEURISTIC_NOTHING_ELSE_CLASS:
default:
{
heuristicNothingElseClassImpl();
break;
}
}
}
}
return( getExecutionQueue().hasResult() );
}
/**
* Heuristic NAIVE Class implementation
*/
void TransitionCoverageFilter::heuristicNaiveClassImpl()
{
if( mCoverageStatistics.hasUncovered() )
{
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
mCoverageStatistics.toStreamCoverageRate(AVM_OS_COUT ,
"Number of covered transitions = ", " / ", "\n");
mCoverageStatistics.toStreamCoverageRate(AVM_OS_TRACE,
"Number of covered transitions = ", " / ", "\n");
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
computeWeightOfResult();
// case of found strong hit EC
if( mStronglyFireableTransitionCount > 0 )
{
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
AVM_OS_INFO << "==> Next [ Strongly ] Fireable Count :> "
<< mStronglyFireableTransitionCount
<< " Hit Count : " << mStronglyHitEC.size() << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
setHitWeight(mStronglyHitEC, WEIGHT_SELECTED_ACHIEVABLE,
mHitStronglyRandomFlag, mHitStronglyCount);
}
// case of has waiting strong hit EC
else if( getExecutionQueue().getWaitingStrategy()->
hasWaiting(WEIGHT_STRONGLY_ACHIEVABLE) )
{
getSymbexRequestManager().postRequestRequeueWaiting( this );
}
// case of found weak hit EC
else if( mWeaklyFireableTransitionCount > 0 )
{
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
AVM_OS_INFO << "==> Next [ Weakly ] Fireable Count :> "
<< mWeaklyFireableTransitionCount
<< " Hit Count : " << mWeaklyHitEC.size() << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
setHitWeight(mWeaklyHitEC, WEIGHT_SELECTED_ACHIEVABLE,
mHitWeaklyRandomFlag, mHitWeaklyCount);
}
//!!! TODO optimization
else// if( mCoverageStatistics.updateFailedHeuristic() )
{
getSymbexRequestManager().postRequestRequeueWaiting( this );
}
}
}
/**
* Heuristic SMART Class implementation
*/
void TransitionCoverageFilter::heuristicSmartClassImpl()
{
heuristicNaiveClassImpl();
}
/**
* Heuristic AGRESSIVE Class implementation
*/
void TransitionCoverageFilter::heuristicAgressiveClassImpl()
{
heuristicNaiveClassImpl();
}
/**
* Heuristic NOTHING HELSE Class implementation
*/
void TransitionCoverageFilter::heuristicNothingElseClassImpl()
{
collectUncoveredTransition();
mHeuristicProperty.resetHeuristicClass(
IHeuristicClass::HEURISTIC_NAIVE_CLASS);
AVM_IF_DEBUG_FLAG( PROCESSOR )
AVM_OS_INFO << EMPHASIS(mHeuristicProperty.strHeuristicClass(), '*', 80);
AVM_ENDIF_DEBUG_FLAG( PROCESSOR )
heuristicNaiveClassImpl();
if( mCoverageStatistics.goalAchievedRate() )
{
if( mStopFlag )
{
getSymbexRequestManager().postRequestStop( this );
}
AVM_IF_DEBUG_FLAG( PROCESSOR )
AVM_OS_INFO << "******* HEURISTIC GOAL ACHIEVED RATE : "
<< mCoverageStatistics.mCoverageRateGoal << " % *******" << std::endl;
AVM_ENDIF_DEBUG_FLAG( PROCESSOR )
}
if( mCoverageStatistics.goalAchievedRest() )
{
if( mStopFlag )
{
getSymbexRequestManager().postRequestStop( this );
}
AVM_IF_DEBUG_FLAG( PROCESSOR )
AVM_OS_INFO << "******* HEURISTIC GOAL ACHIEVED REST : "
<< mCoverageStatistics.mCoverageRestGoal << " *******" << std::endl;
AVM_ENDIF_DEBUG_FLAG( PROCESSOR )
}
if( ++mHeuristicProperty.mHeuristicTrialsCount
> mHeuristicProperty.mHeuristicTrialsLimit )
{
if( mStopFlag )
{
getSymbexRequestManager().postRequestStop( this );
}
AVM_IF_DEBUG_FLAG( PROCESSOR )
AVM_OS_INFO << "******* HEURISTIC TRIALS STOP : "
<< mHeuristicProperty.mHeuristicTrialsLimit
<< " *******" << std::endl;
AVM_ENDIF_DEBUG_FLAG( PROCESSOR )
}
}
/**
* Compute Hit Weigth for Execution Context
*/
void TransitionCoverageFilter::setHitWeight(VectorOfExecutionContext & hitEC,
avm_uint8_t hitWeight, bool randomFlag, avm_size_t hitCount)
{
if( randomFlag && (hitCount < hitEC.size()) )
{
maxRandomOffset = hitEC.size() - 1;
randomOffsetBitset.reset();
randomOffsetBitset.resize(maxRandomOffset + 1, false);
for( ; 0 < hitCount ; --hitCount )
{
do
{
offset = RANDOM::gen_uint(0, maxRandomOffset);
}
while( randomOffsetBitset[offset] );
randomOffsetBitset[offset] = true;
hitEC[ offset ]->setWeight( hitWeight );
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
AVM_OS_INFO << std::endl << DEFAULT_WRAP_DATA << "HIT :> ";
hitEC[ offset ]->traceMinimum(AVM_OS_COUT );
hitEC[ offset ]->traceMinimum(AVM_OS_TRACE);
AVM_OS_INFO << END_WRAP;
fireableTransitionTrace(AVM_OS_COUT , hitEC[ offset ]->refExecutionData());
fireableTransitionTrace(AVM_OS_TRACE, hitEC[ offset ]->refExecutionData());
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
}
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
AVM_OS_INFO << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
}
else
{
if( hitCount > hitEC.size() )
{
hitCount = hitEC.size();
}
for( offset = 0 ; offset < hitCount ; ++offset )
{
hitEC[ offset ]->setWeight( hitWeight );
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
AVM_OS_INFO << std::endl << DEFAULT_WRAP_DATA << "HIT :> ";
hitEC[ offset ]->traceMinimum(AVM_OS_COUT );
hitEC[ offset ]->traceMinimum(AVM_OS_TRACE);
AVM_OS_INFO << END_WRAP;
fireableTransitionTrace(AVM_OS_COUT , hitEC[ offset ]->refExecutionData());
fireableTransitionTrace(AVM_OS_TRACE, hitEC[ offset ]->refExecutionData());
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
}
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
AVM_OS_INFO << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
}
}
/*
* weight: 1 if some transition of leaf EC will be fired
* weight: 2 if some transition of leaf EC could be fired
* weight: 3 else
*/
void TransitionCoverageFilter::computeWeight(ExecutionContext * anEC)
{
switch( mHeuristicProperty.mHeuristicClass )
{
case IHeuristicClass::HEURISTIC_BASIC_CLASS:
{
mHeuristicProperty.mHeuristicClass =
IHeuristicClass::HEURISTIC_BASIC_CLASS;
computeWeightNaive( anEC );
break;
}
case IHeuristicClass::HEURISTIC_NAIVE_CLASS:
{
computeWeightNaive( anEC );
break;
}
case IHeuristicClass::HEURISTIC_SMART_CLASS:
{
computeWeightSmart( anEC );
break;
}
case IHeuristicClass::HEURISTIC_AGRESSIVE_CLASS:
{
computeWeightAgressive( anEC );
break;
}
case IHeuristicClass::HEURISTIC_NOTHING_ELSE_CLASS:
default:
{
computeWeightNaive( anEC );
break;
}
}
}
void TransitionCoverageFilter::computeWeightNaive(ExecutionContext * anEC)
{
if( computeCheckNonPriorityWeight(anEC) )
{
return;
}
computePriorityWeight(anEC);
if( checkStronglyPriorityWeight(anEC) )
{
return;
}
else if( checkWeaklyPriorityWeight(anEC) )
{
return;
}
else
{
anEC->setWeight( WEIGHT_UNKNOWN_ACHIEVABLE );
}
}
void TransitionCoverageFilter::computeWeightSmart(ExecutionContext * anEC)
{
computePriorityWeight(anEC);
if( checkStronglyPriorityWeight(anEC) )
{
return;
}
else if( computeCheckNonPriorityWeight(anEC) )
{
return;
}
else if( checkWeaklyPriorityWeight(anEC) )
{
return;
}
else
{
anEC->setWeight( WEIGHT_UNKNOWN_ACHIEVABLE );
}
}
void TransitionCoverageFilter::computeWeightAgressive(ExecutionContext * anEC)
{
computePriorityWeight(anEC);
if( checkStronglyPriorityWeight(anEC) )
{
return;
}
else if( checkWeaklyPriorityWeight(anEC) )
{
return;
}
else
{
anEC->setWeight( WEIGHT_UNKNOWN_ACHIEVABLE );
}
}
bool TransitionCoverageFilter::computeCheckNonPriorityWeight(
ExecutionContext * anEC)
{
if( anEC->getHeight() > mCoverageHeight )
{
mCoverageHeightReachedFlag = true;
anEC->setWeight( WEIGHT_NON_PRIORITY );
return( true );
}
else if( anEC->getWeight() != WEIGHT_NON_PRIORITY )
{
if( isTrivialLoop(anEC) )
{
anEC->setWeight( WEIGHT_NON_ACHIEVABLE );
return( true );
}
// if( isSyntaxicLoop(anEC) )
// {
// anEC->setWeight( WEIGHT_NON_ACHIEVABLE );
//
// return( true );
// }
else if( isControlLoop(anEC) )
{
anEC->setWeight( WEIGHT_NON_PRIORITY );
return( true );
}
}
return( false );
}
void TransitionCoverageFilter::computePriorityWeight(ExecutionContext * anEC)
{
tmpStronglyFireableTransitionCount = 0;
tmpWeaklyFireableTransitionCount = 0;
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRANSITION )
AVM_OS_INFO << ":> from "; anEC->traceMinimum(AVM_OS_TRACE);
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRANSITION )
// compute :>
// fireableTransitionCount( anEC->getAPExecutionData() );
fireableTransitionCount( anEC->refExecutionData() ,
anEC->refExecutionData().getSystemRuntime() );
}
bool TransitionCoverageFilter::checkStronglyPriorityWeight(
ExecutionContext * anEC)
{
if( tmpStronglyFireableTransitionCount > 0 )
{
anEC->setWeight( WEIGHT_STRONGLY_ACHIEVABLE );
if( mStronglyFireableTransitionCount
< tmpStronglyFireableTransitionCount )
{
mStronglyFireableTransitionCount =
tmpStronglyFireableTransitionCount;
mStronglyHitEC.clear();
mStronglyHitEC.append( anEC );
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRANSITION )
AVM_OS_INFO << "==> HIT EC [ Strong : "
<< mStronglyFireableTransitionCount << " ]:> ";
anEC->traceMinimum(AVM_OS_COUT);
anEC->traceMinimum(AVM_OS_TRACE);
AVM_OS_INFO << std::flush;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRANSITION )
return( true );
}
else if( mStronglyFireableTransitionCount ==
tmpStronglyFireableTransitionCount )
{
mStronglyHitEC.append( anEC );
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRANSITION )
AVM_OS_INFO << "==> HIT EC [ Strong : "
<< mStronglyFireableTransitionCount << " ]:> ";
anEC->traceMinimum(AVM_OS_COUT);
anEC->traceMinimum(AVM_OS_TRACE);
AVM_OS_INFO << std::flush;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRANSITION )
}
return( true );
}
return( false );
}
bool TransitionCoverageFilter::checkWeaklyPriorityWeight(ExecutionContext * anEC)
{
if( tmpWeaklyFireableTransitionCount > 0 )
{
anEC->setWeight( WEIGHT_WEAKLY_ACHIEVABLE );
if( mWeaklyFireableTransitionCount < tmpWeaklyFireableTransitionCount )
{
mWeaklyFireableTransitionCount = tmpWeaklyFireableTransitionCount;
mWeaklyHitEC.clear();
mWeaklyHitEC.append( anEC );
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRANSITION )
AVM_OS_INFO << "==> HIT EC [ Weak : "
<< mWeaklyFireableTransitionCount << " ]:> ";
anEC->traceMinimum(AVM_OS_COUT);
anEC->traceMinimum(AVM_OS_TRACE);
AVM_OS_INFO << std::flush;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRANSITION )
return( true );
}
else if( mWeaklyFireableTransitionCount ==
tmpWeaklyFireableTransitionCount )
{
mWeaklyHitEC.append( anEC );
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRANSITION )
AVM_OS_INFO << "==> HIT EC [ Weak : "
<< mWeaklyFireableTransitionCount << " ]:> ";
anEC->traceMinimum(AVM_OS_COUT);
anEC->traceMinimum(AVM_OS_TRACE);
AVM_OS_INFO << std::flush;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRANSITION )
}
return( true );
}
return( false );
}
void TransitionCoverageFilter::computeWeightOfResult()
{
mStronglyHitEC.clear();
mStronglyFireableTransitionCount = 0;
mWeaklyHitEC.clear();
mWeaklyFireableTransitionCount = 0;
ecQueueIt = ecQueue->begin();
for( ; ecQueueIt != ecQueueItEnd ; ++ecQueueIt )
{
itEndEC = (*ecQueueIt)->end();
for( itEC = (*ecQueueIt)->begin() ; (itEC != itEndEC) ; ++itEC )
{
computeWeight( *itEC );
//AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
// if( (*itEC)->getWeight() == WEIGHT_SELECTED_ACHIEVABLE )
// {
// fireableTransitionTrace(AVM_OS_COUT , (*itEC)->getAPExecutionData());
// fireableTransitionTrace(AVM_OS_TRACE, (*itEC)->getAPExecutionData());
// }
//AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
}
}
// Count one time per step CoverageHeightReached
if( mCoverageHeightReachedFlag )
{
++mCoverageHeightReachedCount;
mCoverageHeightReachedFlag = false;
}
}
void TransitionCoverageFilter::handleRequestRequeueWaitingTable(
WaitingStrategy & aWaitingStrategy,
avm_uint8_t aWeightMin, avm_uint8_t aWeightMax)
{
mCoverageStatistics.setFailedHeuristic();
AVM_IF_DEBUG_LEVEL_FLAG( MEDIUM , PROCESSOR )
AVM_OS_INFO << ">>>>>>> REQUEST REQUEUE <<<<<<<" << std::endl;
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , TRANSITION )
report(AVM_OS_COUT);
report(AVM_OS_TRACE);
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , TRANSITION )
AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , PROCESSOR )
do
{
mWaitingQueue.clear();
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , QUEUE )
aWaitingStrategy.toStream(AVM_OS_COUT);
aWaitingStrategy.toStream(AVM_OS_TRACE);
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , QUEUE )
// aWaitingStrategy.spliceQueueTable(mWaitingQueue, aWeightMax);
aWeightMin = aWaitingStrategy.splicePriorQueueTable(
mWaitingQueue, aWeightMin, aWeightMax);
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
AVM_OS_INFO << "REQUEUE QUEUE << " << strHeuristicWeight(aWeightMin)
<< " >> " << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
mStronglyHitEC.clear();
mStronglyFireableTransitionCount = 0;
mWeaklyHitEC.clear();
mWeaklyFireableTransitionCount = 0;
ecQueueIt = mWaitingQueue.begin();
ecQueueItEnd = mWaitingQueue.end();
for( ; ecQueueIt != ecQueueItEnd ; ++ecQueueIt )
{
computeWeight( *ecQueueIt );
aWaitingStrategy.push( *ecQueueIt );
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
if( (*ecQueueIt)->getWeight() <= WEIGHT_STRONGLY_ACHIEVABLE )
{
AVM_OS_INFO << DEFAULT_WRAP_DATA
<< "REQUEUE candidate [ <= Strongly ] :> ";
(*ecQueueIt)->traceMinimum(AVM_OS_COUT );
(*ecQueueIt)->traceMinimum(AVM_OS_TRACE);
AVM_OS_INFO << END_WRAP;
fireableTransitionTrace(AVM_OS_COUT, (*ecQueueIt)->refExecutionData());
fireableTransitionTrace(AVM_OS_TRACE,(*ecQueueIt)->refExecutionData());
}
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
}
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , QUEUE )
aWaitingStrategy.toStream(AVM_OS_COUT);
aWaitingStrategy.toStream(AVM_OS_TRACE);
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , QUEUE )
// case of found strongly hit EC
if( mStronglyFireableTransitionCount > 0 )
{
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
AVM_OS_INFO << "==> REQUEUE candidate [ Strongly ] Fireable Count :> "
<< mStronglyFireableTransitionCount
<< " Hit Count : " << mStronglyHitEC.size() << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
}
// case of found weakly hit EC
if( mWeaklyFireableTransitionCount > 0 )
{
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
AVM_OS_INFO << "==> REQUEUE candidate [ Weakly ] Fireable Count :> "
<< mWeaklyFireableTransitionCount
<< " Hit Count : " << mWeaklyHitEC.size() << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
}
}
while( ((++aWeightMin) <= WEIGHT_NON_PRIORITY) &&
// while( ((++aWeightMin) <= aWeightMax) &&
(mStronglyFireableTransitionCount == 0) );
//AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
// Passer en mode DIRECTIF vers une transition WEAKLY_ACHIEVABLE à couvrir
// Calcul d'une trace vers cette transition
if( mStronglyFireableTransitionCount == 0 )
{
if( initializeTraceDriver(aWaitingStrategy) )
{
//!! NOTHING
}
}
//AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
if( (mCoverageHeightReachedCount > mCoverageHeightReachedLimit) &&
(mStronglyFireableTransitionCount == 0) )
{
mCoverageHeightReachedCount = 0;
mCoverageHeightReachedFlag = false;
mCoverageHeight += mCoverageHeightPeriod;
mCoverageHeightReachedCount += mCoverageHeightReachedCount;
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
AVM_OS_INFO << "REQUEUE [ chp: " << mCoverageHeightPeriod
<< " ] ==> New Coverage Height :> " << mCoverageHeight << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
}
}
bool TransitionCoverageFilter::testFireability(const ExecutionData & anED,
const RuntimeID & aReceiverRID, AvmTransition * aTransition)
{
if( aTransition->hasCode() && aTransition->getCode()->nonempty() &&
aTransition->getCode()->first().is< AvmCode >() )
{
const AvmCode * firstStatement =
aTransition->getCode()->first().to_ptr< AvmCode >();
switch( firstStatement->getOptimizedOpCode() )
{
case AVM_OPCODE_INPUT_ENV:
case AVM_OPCODE_OUTPUT_ENV:
{
return( true );
}
default:
{
if( firstStatement->isOpCode( AVM_OPCODE_INPUT ) &&
firstStatement->first().is< InstanceOfPort >() )
{
return( AvmCommunicationFactory::computePresence(
anED, aReceiverRID,
firstStatement->first().to_ptr< InstanceOfPort >()) );
}
return( true );
}
}
}
return( true );
}
bool TransitionCoverageFilter::isControlLoop(ExecutionContext * anEC)
{
tmpEC = anEC->getPrevious();
for( ; tmpEC != NULL ; tmpEC = tmpEC->getPrevious() )
{
if( anEC->refExecutionData().getRuntimeFormStateTable()->equalsState(
tmpEC->refExecutionData().getRuntimeFormStateTable() ) )
{
return( true );
}
}
return( false );
}
bool TransitionCoverageFilter::isSyntaxicLoop(ExecutionContext * anEC)
{
tmpEC = anEC->getPrevious();
for( ; tmpEC != NULL ; tmpEC = tmpEC->getPrevious() )
{
if( anEC->refExecutionData().getRuntimeFormStateTable()->equalsState(
tmpEC->refExecutionData().getRuntimeFormStateTable() ) )
{
return( true );
}
}
return( false );
}
bool TransitionCoverageFilter::isTrivialLoop(ExecutionContext * anEC)
{
tmpEC = anEC->getPrevious();
for( ; tmpEC != NULL ; tmpEC = tmpEC->getPrevious() )
{
if( anEC->refExecutionData().isTEQ( tmpEC->getExecutionData() ) )
{
return( true );
}
}
return( false );
}
void TransitionCoverageFilter::fireableTransitionCount(
const ExecutionData & anED, const RuntimeID & aRID)
{
tmpEF = aRID.getExecutable();
tmpRuntimeTransitionBitset = getCoverageTableBitset( aRID );
if( tmpRuntimeTransitionBitset == NULL )
{
//!! NOTHING
}
//tmpEF->hasTransition()
else if( tmpRuntimeTransitionBitset->anyFalse() )
{
AvmTransition * aProg;
avm_size_t endOffset = tmpEF->getTransition().size();
for( avm_size_t offset = 0 ; offset < endOffset ; ++offset )
{
aProg = tmpEF->getTransition().rawAt(offset);
if( not tmpRuntimeTransitionBitset->test(aProg->getOffset()) )
{
tmpWeaklyFireableTransitionCount += 1;
if( testFireability(anED, aRID, aProg) )
{
tmpStronglyFireableTransitionCount += 1;
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRANSITION )
AVM_OS_INFO << "==> Fireable :> " << aProg->strTransitionHeader() << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRANSITION )
}
}
}
}
// else if( tmpRuntimeTransitionBitset->allTrue() )
// {
// anED.setRuntimeFormState((*itRF)->getRID(), PROCESS_SUSPENDED_STATE);
// }
}
void TransitionCoverageFilter::fireableTransitionCount(
const ExecutionData & anED)
{
avm_size_t offset;
avm_size_t endOffset;
AvmTransition * aProg;
itRF = anED.getTableOfRuntime().begin();
endRF = anED.getTableOfRuntime().end();
for( ; (itRF != endRF) ; ++itRF )
{
itRID = (*itRF)->getRID();
if( not anED.isIdleOrRunning( itRID ) )
{
continue;
}
tmpEF = itRID.getExecutable();
tmpRuntimeTransitionBitset = getCoverageTableBitset( itRID );
if( tmpRuntimeTransitionBitset == NULL )
{
//!! NOTHING
}
//tmpEF->hasTransition()
else if( anED.isIdleOrRunning( itRID ) &&
tmpRuntimeTransitionBitset->anyFalse() )
{
endOffset = tmpEF->getTransition().size();
for( offset = 0 ; offset < endOffset ; ++offset )
{
aProg = tmpEF->getTransition().rawAt(offset);
if( not tmpRuntimeTransitionBitset->test(aProg->getOffset()) )
{
tmpWeaklyFireableTransitionCount += 1;
if( testFireability(anED, itRID, aProg) )
{
tmpStronglyFireableTransitionCount += 1;
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRANSITION )
AVM_OS_INFO << "==> Fireable :> " << aProg->strTransitionHeader() << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRANSITION )
}
}
}
}
// else if( tmpRuntimeTransitionBitset->allTrue() )
// {
// anED.setRuntimeFormState(itRID, PROCESS_SUSPENDED_STATE);
// }
}
}
void TransitionCoverageFilter::fireableTransitionCount(
const ExecutionData & anED, const RuntimeForm & aRF)
{
if( not anED.isIdleOrRunning( aRF.getRID() ) )
{
return;
}
tmpEF = aRF.getRID().getExecutable();
if( tmpEF->hasTransition() )
{
tmpRuntimeTransitionBitset = getCoverageTableBitset( aRF.getRID() );
if( tmpRuntimeTransitionBitset->anyFalse() )
{
AvmTransition * aProg = NULL;
avm_size_t endOffset = tmpEF->getTransition().size();
for( avm_size_t offset = 0 ; offset < endOffset ; ++offset )
{
aProg = tmpEF->getTransition().rawAt(offset);
if( not tmpRuntimeTransitionBitset->test(aProg->getOffset()) )
{
if( testFireability(anED, aRF.getRID(), aProg) )
{
tmpStronglyFireableTransitionCount += 1;
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRANSITION )
AVM_OS_INFO << "==> Fireable :> " << aProg->strTransitionHeader() << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , PROCESSOR , TRANSITION )
}
else
{
tmpWeaklyFireableTransitionCount += 1;
}
}
}
}
}
if( aRF.hasChild() )
{
TableOfRuntimeID::const_iterator itRID = aRF.beginChild();
TableOfRuntimeID::const_iterator itRIDEnd = aRF.endChild();
for( ; itRID != itRIDEnd ; ++itRID )
{
if( anED.isIdleOrRunning( *itRID ) )
{
fireableTransitionCount(anED, anED.getRuntime(*itRID));
}
}
}
}
void TransitionCoverageFilter::fireableTransitionTrace(
OutStream & os, const ExecutionData & anED)
{
avm_size_t offset;
avm_size_t endOffset;
AvmTransition * aProg = NULL;
itRF = anED.getTableOfRuntime().begin();
endRF = anED.getTableOfRuntime().end();
for( ; (itRF != endRF) ; ++itRF )
{
itRID = (*itRF)->getRID();
tmpEF = itRID.getExecutable();
tmpRuntimeTransitionBitset = getCoverageTableBitset( itRID );
if( tmpRuntimeTransitionBitset == NULL )
{
//!! NOTHING
}
//tmpEF->hasTransition()
else if( anED.isIdleOrRunning( itRID ) )
{
if( tmpRuntimeTransitionBitset->anyFalse() )
{
endOffset = tmpEF->getTransition().size();
for( offset = 0 ; offset < endOffset ; ++offset )
{
aProg = tmpEF->getTransition().rawAt(offset);
if( not tmpRuntimeTransitionBitset->
test(aProg->getOffset()) )
{
if( testFireability(anED, itRID, aProg) )
{
os << "==> [ Strongly ] Fireable :> "
<< aProg->strTransitionHeader() << std::endl;
}
else
{
os << "==> [ Weakly ] Fireable :> "
<< aProg->strTransitionHeader() << std::endl;
}
}
}
}
// else if( tmpRuntimeTransitionBitset->allTrue() )
// {
// os << "==> [ suspended ! ] machine :> "
// << (*itRF)->getFullyQualifiedNameID() << std::endl;
// }
}
}
}
void TransitionCoverageFilter::fireableTransitionTrace(OutStream & os,
const ExecutionData & anED, const RuntimeForm & aRF)
{
tmpEF = aRF.getRID().getExecutable();
if( tmpEF->hasTransition() )
{
tmpRuntimeTransitionBitset = getCoverageTableBitset( aRF.getRID() );
if( tmpRuntimeTransitionBitset->anyFalse() )
{
AvmTransition * aProg = NULL;
avm_size_t endOffset = tmpEF->getTransition().size();
for( avm_size_t offset = 0 ; offset < endOffset ; ++offset )
{
aProg = tmpEF->getTransition().rawAt(offset);
if( not tmpRuntimeTransitionBitset->test(aProg->getOffset()) )
{
if( testFireability(anED, aRF.getRID(), aProg) )
{
os << "==> [ Strongly ] Fireable :> "
<< aProg->strTransitionHeader() << std::endl;
}
else
{
os << "==> [ Weakly ] Fireable :> "
<< aProg->strTransitionHeader() << std::endl;
}
}
}
}
}
if( aRF.hasChild() )
{
TableOfRuntimeID::const_iterator itRID = aRF.beginChild();
TableOfRuntimeID::const_iterator itRIDEnd = aRF.endChild();
for( ; itRID != itRIDEnd ; ++itRID )
{
if( anED.isIdleOrRunning( *itRID ) )
{
fireableTransitionTrace(os, anED, anED.getRuntime(*itRID));
}
}
}
}
/**
* updateTransitionCoverageTable using new fresh Execution Context
*/
void TransitionCoverageFilter::updateTransitionCoverageTable(
ExecutionContext * anEC, const BF & aFiredCode)
{
if( aFiredCode.invalid() )
{
return;
}
// Vérification de la création de nouvelle instance dynamique
// par la commande ${ NEW , EXEC }
if( (mScope != Specifier::DESIGN_MODEL_KIND) &&
(anEC->refExecutionData().getTableOfRuntime().size() >
mTransitionCoverageTable->size()) )
{
//TODO
return;
}
switch( aFiredCode.classKind() )
{
case FORM_AVMCODE_KIND:
{
const BFCode & anAvmCode = aFiredCode.bfCode();
AvmCode::iterator itEnd = anAvmCode->end();
for( AvmCode::iterator it = anAvmCode->begin() ; it != itEnd ; ++it )
{
updateTransitionCoverageTable(anEC, (*it));
}
break;
}
case FORM_EXECUTION_CONFIGURATION_KIND:
{
ExecutionConfiguration * anExecConf =
aFiredCode.to_ptr< ExecutionConfiguration >();
if( anExecConf->isTransition() )
{
updateTransitionCoverageTable(anEC,
anExecConf->getRuntimeID(), anExecConf->getTransition());
// AvmTransition * firedTransition = anExecConf->getTransition();
//
// if( not mTransitionCoverageTable->
// at( anExecConf->getRuntimeID().getOffset() )->
// test( firedTransition->getOffset() ) )
// {
// mCoverageStatistics.addCoveredElement();
//
// mTransitionCoverageTable->at(
// anExecConf->getRuntimeID().getOffset() )->
// set(firedTransition->getOffset(), true);
//
// if( mExecutableCoverageTable != NULL )
// {
// mExecutableCoverageTable->at( firedTransition->
// getExecutableContainer()->getOffset() )->
// set(firedTransition->getOffset(), true);
// }
//
// anEC->addInfo(*this, ExpressionConstructor::newString(
// firedTransition->getNameID() ) );
//
// mListOfPositiveEC.append( anEC );
}
break;
}
default:
{
break;
}
}
}
void TransitionCoverageFilter::updateTransitionCoverageTable(
ExecutionContext * anEC, const RuntimeID & aRID,
AvmTransition * firedTransition)
{
bool isNewlyCovered = false;
switch( mScope )
{
case Specifier::DESIGN_MODEL_KIND:
{
if( not mExecutableCoverageTable->at( firedTransition->
getExecutableContainer()->getOffset() )->
test(firedTransition->getOffset()) )
{
isNewlyCovered = true;
mExecutableCoverageTable->at( firedTransition->
getExecutableContainer()->getOffset() )->
set(firedTransition->getOffset(), true);
}
break;
}
case Specifier::DESIGN_INSTANCE_KIND:
{
if( not mTransitionCoverageTable->at( aRID.getOffset() )->
test( firedTransition->getOffset() ) )
{
isNewlyCovered = true;
mTransitionCoverageTable->at( aRID.getOffset() )->
set(firedTransition->getOffset(), true);
}
break;
}
default:
{
if( not mTransitionCoverageTable->at( aRID.getOffset() )->
test( firedTransition->getOffset() ) )
{
isNewlyCovered = true;
mTransitionCoverageTable->at( aRID.getOffset() )->
set(firedTransition->getOffset(), true);
if( mExecutableCoverageTable != NULL )
{
mExecutableCoverageTable->at( firedTransition->
getExecutableContainer()->getOffset() )->
set(firedTransition->getOffset(), true);
}
}
break;
}
}
if( isNewlyCovered )
{
mCoverageStatistics.addCoveredElement();
anEC->getwFlags().addCoverageElementTrace();
anEC->addInfo(*this,
ExpressionConstructor::newString( firedTransition->getNameID() ));
mListOfPositiveEC.append( anEC );
}
}
bool TransitionCoverageFilter::testTransitionCoverage(AvmTransition * firedTransition)
{
switch( mScope )
{
case Specifier::DESIGN_MODEL_KIND:
{
return( mExecutableCoverageTable->at( firedTransition->
getExecutableContainer()->getOffset() )->
test(firedTransition->getOffset()) );
}
case Specifier::DESIGN_INSTANCE_KIND:
{
// return( mTransitionCoverageTable->at( aRID.getOffset() )->
// test( firedTransition->getOffset() ) );
return( true );
}
default:
{
return( (mExecutableCoverageTable != NULL) ||
mExecutableCoverageTable->at( firedTransition->
getExecutableContainer()->getOffset() )->
test(firedTransition->getOffset()) );
}
}
}
/**
* mTableofUncoveredTransition
*/
void TransitionCoverageFilter::collectUncoveredTransition()
{
if( mLastCollectedCoverCount < mCoverageStatistics.mNumberOfCovered )
{
mLastCollectedCoverCount = mCoverageStatistics.mNumberOfCovered;
mTableofUncoveredTransition.clear();
// avm_size_t endTransition = mTableofUncoveredTransition.size();
// for( avm_size_t offset = 0 ; offset < endTransition ; ++offset )
// {
// if( testTransitionCoverage(mTableofUncoveredTransition[offset]) )
// {
// mTableofUncoveredTransition[offset] =
// mTableofUncoveredTransition[offset];
// }
// }
}
else
{
return;
}
const ExecutionData & anED = getConfiguration().getMainExecutionData();
RuntimeID aRID;
avm_size_t offset;
avm_size_t endOffset;
AvmTransition * itTransition;
switch( mScope )
{
case Specifier::DESIGN_INSTANCE_KIND:
{
if( mTransitionCoverageTable == NULL )
{
break;
}
avm_size_t endMachine = mTransitionCoverageTable->size();
for( avm_size_t itMachine = 0 ; itMachine < endMachine ; ++itMachine )
{
aRID = anED.getRuntimeID(itMachine);
if( aRID.getExecutable()->hasTransition() )
{
endOffset = aRID.getExecutable()->getTransition().size();
for( offset = 0 ; offset < endOffset ; ++offset )
{
itTransition = aRID.getExecutable()->
getTransition().rawAt(offset);
if( not mTransitionCoverageTable->
at( aRID.getOffset() )->test( offset ) )
{
mTableofUncoveredTransition.append( itTransition );
if( mTableofUncoveredTransition.size() >=
mCoverageStatistics.getNumberOfUncovered() )
{
return;
}
}
}
}
}
break;
}
case Specifier::DESIGN_MODEL_KIND:
{
if( mExecutableCoverageTable == NULL )
{
break;
}
VectorOfExecutableForm::const_iterator itExec =
mTableofRuntimeExecutable.begin();
VectorOfExecutableForm::const_iterator endExec =
mTableofRuntimeExecutable.end();
for( avm_size_t indexExec = 0 ; itExec != endExec ;
++itExec , ++indexExec )
{
if( (*itExec)->hasTransition() )
{
endOffset = (*itExec)->getTransition().size();
for( offset = 0 ; offset < endOffset ; ++offset )
{
itTransition = (*itExec)->getTransition().rawAt(offset);
if( not mExecutableCoverageTable->
at((*itExec)->getOffset())->test( offset ) )
{
mTableofUncoveredTransition.append( itTransition );
if( mTableofUncoveredTransition.size() >=
mCoverageStatistics.getNumberOfUncovered() )
{
return;
}
}
}
}
}
break;
}
default:
{
if( mExecutableCoverageTable != NULL )
{
VectorOfExecutableForm::const_iterator itExec =
mTableofRuntimeExecutable.begin();
VectorOfExecutableForm::const_iterator endExec =
mTableofRuntimeExecutable.end();
for( avm_size_t indexExec = 0 ; itExec != endExec ;
++itExec , ++indexExec )
{
if( (*itExec)->hasTransition() )
{
endOffset = (*itExec)->getTransition().size();
for( offset = 0 ; offset < endOffset ; ++offset )
{
itTransition = (*itExec)->getTransition().rawAt(offset);
if( not mExecutableCoverageTable->
at((*itExec)->getOffset())->test( offset ) )
{
mTableofUncoveredTransition.append( itTransition );
if( mTableofUncoveredTransition.size() >=
mCoverageStatistics.getNumberOfUncovered() )
{
return;
}
}
}
}
}
}
if( mTransitionCoverageTable != NULL )
{
avm_size_t endMachine = mTransitionCoverageTable->size();
for( avm_size_t itMachine = 0 ; itMachine < endMachine ; ++itMachine )
{
aRID = anED.getRuntimeID(itMachine);
if( aRID.getExecutable()->hasTransition() )
{
endOffset = aRID.getExecutable()->getTransition().size();
for( offset = 0 ; offset < endOffset ; ++offset )
{
itTransition = aRID.getExecutable()->
getTransition().rawAt(offset);
if( (not mTransitionCoverageTable->
at(aRID.getOffset())->test(offset))
&& mExecutableCoverageTable->
at(aRID.getExecutable()->getOffset())->test(offset) )
{
mTableofUncoveredTransition.append( itTransition );
if( mTableofUncoveredTransition.size() >=
mCoverageStatistics.getNumberOfUncovered() )
{
return;
}
}
}
}
}
}
break;
}
}
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
AVM_OS_INFO << "TransitionCoverageFilter::collectUncoveredTransition:> count: "
<< mTableofUncoveredTransition.size() << std::endl;
VectorOfAvmTransition::const_iterator itTransition = mTableofUncoveredTransition.begin();
VectorOfAvmTransition::const_iterator endTransition = mTableofUncoveredTransition.end();
for( ; itTransition != endTransition ; ++itTransition )
{
AVM_OS_INFO << "\t" << (*itTransition)->strTransitionHeader() << std::endl;
}
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
}
void TransitionCoverageFilter::collectUncoveredTransition(
const ExecutionData & anED, ListOfAvmTransition & listofTransition)
{
ExecutableForm * tmpExecutable = NULL;
ListOfAvmTransition listOfOutgoingTransition;
ListOfAvmTransition::const_iterator itTrans;
ListOfAvmTransition::const_iterator endTrans;
itRF = anED.getTableOfRuntime().begin();
endRF = anED.getTableOfRuntime().end();
for( ; itRF != endRF ; ++itRF )
{
itRID = (*itRF)->getRID();
tmpExecutable = itRID.getExecutable();
if( anED.isIdleOrRunning( itRID )
&& tmpExecutable->hasTransition() )
{
tmpExecutable->getOutgoingTransition( listOfOutgoingTransition );
itTrans = listOfOutgoingTransition.begin();
endTrans = listOfOutgoingTransition.end();
for( ; itTrans != endTrans ; ++itTrans )
{
if( not testTransitionCoverage(*itTrans) )
{
listofTransition.append( *itTrans );
}
}
}
}
}
/**
* mTraceDriver
*/
bool TransitionCoverageFilter::initializeTraceDriver(
WaitingStrategy & aWaitingStrategy)
{
avm_uint8_t aWeightMin = 0;
mWaitingQueue.clear();
aWeightMin = aWaitingStrategy.splicePriorQueueTable(
mWaitingQueue, aWeightMin, WEIGHT_UNKNOWN_ACHIEVABLE);
ecQueueItEnd = mWaitingQueue.end();
if( mWeaklyFireableTransitionCount > 0 )
{
ecQueueIt = mWaitingQueue.begin();
for( ; ecQueueIt != ecQueueItEnd ; ++ecQueueIt )
{
if( initializeTraceDriver(*ecQueueIt) )
{
mTraceDirectiveRunningFlag = true;
(*ecQueueIt)->setWeight( WEIGHT_SELECTED_ACHIEVABLE );
aWaitingStrategy.push(mWaitingQueue);
return( true );
}
}
}
if( mLastCollectedCoverCount < mCoverageStatistics.mNumberOfCovered )
{
mLastDirectiveTransitionOffset = 0;
}
collectUncoveredTransition();
avm_size_t endTransition = mTableofUncoveredTransition.size();
if( mLastDirectiveTransitionOffset >= endTransition )
{
mLastDirectiveTransitionOffset = 0;
}
do
{
avm_size_t offset = mLastDirectiveTransitionOffset;
for( ; offset < endTransition ; ++offset )
{
ecQueueIt = mWaitingQueue.begin();
for( ; ecQueueIt != ecQueueItEnd ; ++ecQueueIt )
{
if( mTraceDriver.initialize(*ecQueueIt,
mTableofUncoveredTransition[offset]) )
{
++mLastDirectiveTransitionOffset;
mTraceDirectiveRunningFlag = true;
(*ecQueueIt)->setWeight( WEIGHT_SELECTED_ACHIEVABLE );
aWaitingStrategy.push(mWaitingQueue);
return( true );
}
}
}
aWaitingStrategy.push(mWaitingQueue);
if( (++aWeightMin) <= WEIGHT_UNKNOWN_ACHIEVABLE )
{
mWaitingQueue.clear();
aWeightMin = aWaitingStrategy.splicePriorQueueTable(
mWaitingQueue, aWeightMin, WEIGHT_UNKNOWN_ACHIEVABLE);
ecQueueItEnd = mWaitingQueue.end();
}
else
{
break;
}
}
while( mWaitingQueue.nonempty() );
mTraceDriver.resetFailedTransitionTargetHistory();
return( false );
}
bool TransitionCoverageFilter::initializeTraceDriver(ExecutionContext * anEC)
{
ListOfAvmTransition uncoveredTransition;
collectUncoveredTransition(anEC->refExecutionData(), uncoveredTransition);
while( uncoveredTransition.nonempty() )
{
if( mTraceDriver.initialize(anEC, uncoveredTransition.pop_first()) )
{
return( true );
}
}
return( false );
}
bool TransitionCoverageFilter::runTraceDriver()
{
if( mTraceDriver.process( getExecutionQueue().getResultQueue() ) )
{
if( mTraceDriver.goalAchieved() )
{
mTraceDirectiveRunningFlag = false;
mLastDirectiveTransitionOffset = 0;
}
return( true );
}
else
{
mTraceDirectiveRunningFlag = false;
return( false );
}
}
}