/// <summary>
        /// Given a uncovered code location and the associated terms, this
        /// method infers factory method for that code location.
        ///
        /// Assumes that the uncovered branch is mainly due to an object creating issue
        /// </summary>
        /// <returns></returns>
        public bool TryInferFactoryMethod(UncoveredCodeLocationStore ucls, out SafeSet <Method> suggestedMethods)
        {
            SafeDebug.AssumeNotNull(ucls, "ucls");

            if (ucls.AllFields.Count == 0)
            {
                this.host.Log.LogError(WikiTopics.MissingWikiTopic, "factoryguesser",
                                       "No information about involving fields in the uncovered branch");
                suggestedMethods = null;
                return(false);
            }

            //Check whether the feature is currently supported
            FieldModificationType fmt = this.GetRequiredFieldModificationType(ucls);

            if (!(fmt == FieldModificationType.NON_NULL_SET ||
                  fmt == FieldModificationType.NULL_SET || fmt == FieldModificationType.INCREMENT || fmt == FieldModificationType.DECREMENT ||
                  fmt == FieldModificationType.FALSE_SET || fmt == FieldModificationType.TRUE_SET))
            {
                this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "factoryguesser",
                                         "Format " + fmt.ToString() + " is not supported for suggesting factory methods");
                suggestedMethods = null;
                return(false);
            }

            //Step 1: Get the exact type whose factory method is required for covering this branch.
            //Decided based on where there is a subsequent field which can be directly handled rather than the top field.
            //This step is moved to the place where the uncovered location is initially stored

            //Step 2: Decide which methods of this type should be invoked. Use a bottomup approach
            //for inferrinfg the exact method
            if (!this.GetTargetMethod(ucls, ucls.TargetField, out suggestedMethods))
            {
                this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "factoryguesser",
                                         "Failed to retrieve the target method of field " + ucls.TargetField.FullName + " in type " + ucls.ExplorableType.FullName);
                suggestedMethods = null;
                return(false);
            }

            var sb = new StringBuilder();

            foreach (var m in suggestedMethods)
            {
                sb.AppendLine(MethodOrFieldAnalyzer.GetMethodSignature(m));
            }
            ucls.SuggestedMethodsforFactory = sb.ToString();

            //Create a factory suggestion store. This is expected by the rest of the code.
            FactorySuggestionStore fss;

            if (!this.pmd.FactorySuggestionsDictionary.TryGetValue(ucls.ExplorableType.ToString(), out fss))
            {
                fss = new FactorySuggestionStore();
                fss.DeclaringType = ucls.ExplorableType.ToString();
                this.pmd.FactorySuggestionsDictionary[ucls.ExplorableType.ToString()] = fss;
            }

            return(true);
        }
Esempio n. 2
0
        /// <summary>
        /// Filters out covered code locations
        /// </summary>
        public void FilterOutCoveredCodeLocations()
        {
            //Finding out covered locations
            //Also Finding out other locations in system libraries
            //that do not contribute to increase in the covered. Those
            //libraries should also be removed
            var coveredLocations = new SafeSet <UncoveredCodeLocationStoreList>();

            foreach (var uclStoreList in this.UncoveredLocationDictionary.Values)
            {
                var cl = uclStoreList.Location;
                if (this.IsBranchOffsetCoveredInMethod(cl.Method, cl.Offset))
                {
                    coveredLocations.Add(uclStoreList);
                }
                else
                {
                    //Check whether the uncoverd location is in system library
                    var  currAssembly  = this.Services.CurrentAssembly.Assembly.Assembly;
                    bool bDeleteUCList = true;

                    foreach (var ucstore in uclStoreList.StoreList)
                    {
                        //Check the CUTMethodCall sequence in the ucstore to decide
                        //whether to continue with this
                        foreach (var method in ucstore.CUTMethodCallSequence)
                        {
                            var methoddef = method.Definition;
                            if (methoddef.Module.Assembly == currAssembly && !this.AreAllOffsetsCoveredInMethod(method))
                            {
                                bDeleteUCList = false;
                                break;
                            }
                        }

                        if (!bDeleteUCList)
                        {
                            break;
                        }
                    }

                    if (bDeleteUCList)
                    {
                        coveredLocations.Add(uclStoreList);
                    }
                }
            }

            foreach (var covered in coveredLocations)
            {
                var key = UncoveredCodeLocationStore.GetKey(covered.Location.ToString(), covered.ExplorableType, covered.TermIndex);
                this.UncoveredLocationDictionary.Remove(key);
            }
        }
        /// <summary>
        /// Gets the target method that need to be invoked for setting a field.
        /// Based on static analysis and later uses dynamic analysis for giving
        /// more priority to those methods that are identified through dynamic analysis also.
        /// </summary>
        /// <param name="ucls"></param>
        /// <param name="targetField"></param>
        /// <param name="declaringType"></param>
        /// <param name="targetMethods"></param>
        /// <returns></returns>
        private bool GetTargetMethod(UncoveredCodeLocationStore ucls, Field targetField,
                                     out SafeSet <Method> targetMethods)
        {
            targetMethods = new SafeSet <Method>();

            int numfields = ucls.AllFields.Count;

            for (int count = 0; count < numfields; count++)
            {
                var field = ucls.AllFields[count];

                //Get all write methods for this field
                SafeSet <Method> writeMethods = null;

                //Get the declaring type of the field. There are two possibilities of choosing
                //a declaring type: from the next field or the enclosing type
                TypeEx declaringType1 = null, declaringType2 = null;

                //If there is a parent field, the declaring type should
                //be upgraded to the type of the next field in the list, which could be
                //a sub-class of the actual declaring type
                if (count < numfields - 1)
                {
                    var nextField = ucls.AllFields[count + 1];
                    declaringType1 = nextField.Type;
                }

                if (!MethodOrFieldAnalyzer.TryGetDeclaringTypeEx(this.host, field, out declaringType2))
                {
                    SafeDebug.AssumeNotNull(declaringType2, "declaringType");
                }

                var declaringType = declaringType2;
                if (declaringType1 != null && declaringType1 != declaringType2)
                {
                    declaringType = this.ChooseADeclaringType(declaringType1, declaringType2);
                }

                //Chosen declaringType should be a part of all field types stored
                //in UCLS. If not, there can be inheritance issues
                if (!ucls.AllFieldTypes.Contains(declaringType))
                {
                    //Find out the type to which declaringType is assignable and update it
                    foreach (var tex in ucls.AllFieldTypes)
                    {
                        if (tex.IsAssignableTo(declaringType))
                        {
                            declaringType = tex;
                            break;
                        }
                    }
                }

                //For the first field, get all the methods that modify the field
                //using static analysis
                if (targetMethods.Count == 0)
                {
                    //Try from static analysis store
                    if (!this.psd.TryGetFilteredWriteMethods(field, declaringType, ucls.DesiredFieldModificationType, out writeMethods))
                    {
                        this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "factoryguesser",
                                                 "Failed to get write methods for the field " + field.FullName);
                        return(false);
                    }

                    //Try from dynamic analysis
                    //if (!this.pmd.FieldDictionary.TryGetValue(field.GlobalIndex, out fs))
                    targetMethods.AddRange(writeMethods);
                }
                else
                {
                    //Get the callers of all methods in targetmethods
                    SafeSet <Method> callerMethods = new SafeSet <Method>();
                    foreach (var tmw in targetMethods)
                    {
                        SafeSet <Method> callingMethods;

                        //TODO: Performance improvements can be done here as we repeat the loops inside
                        //the method for each method in targetMethods
                        if (!this.psd.TryGetCallingMethodsInType(tmw, field, declaringType, out callingMethods))
                        {
                            this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "factoryguesser",
                                                     SafeString.Format("Failed to get calling methods of {0} through static and dynamic analysis", tmw));
                            continue;
                        }

                        //Filter the called methods based on field to avoid
                        //unnecessary additional methods
                        SafeSet <Method> subcallingMethods = this.psd.FilterCallingMethodsBasedOnField(tmw, field, callingMethods);
                        if (callingMethods.Count > 0 && subcallingMethods.Count == 0)
                        {
                            this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "callingmethods",
                                                     "Failed to filter calling methods based on field, adding all methods");
                            subcallingMethods.AddRange(callingMethods);
                        }

                        //Check in dynamic analysis portion
                        //if (!this.pmd.MethodDictionary.TryGetValue(tmw.GlobalIndex, out mstore))
                        //{
                        //}
                        //else
                        //    callingMethods = mstore.CallingMethods[declaringType];

                        callerMethods.AddRange(subcallingMethods);
                    }

                    //All caller methods in the parent type
                    targetMethods = callerMethods;
                }

                //Our objective is to search for the methods that belong to our target field.
                //Stop traversal once the desired method is found
                if (field == targetField)
                {
                    break;
                }
            }

            return(true);
        }
 /// <summary>
 /// Analyzes the currently implemented features and makes sure only relevant
 /// features that are implemented further are processed.
 /// </summary>
 /// <param name="ucls"></param>
 /// <returns></returns>
 private FieldModificationType GetRequiredFieldModificationType(UncoveredCodeLocationStore ucls)
 {
     return(ucls.DesiredFieldModificationType);
 }
Esempio n. 5
0
        /// <summary>
        /// Helps guess factory methods for each uncovered condition
        /// </summary>
        private void GuessFactorymethods(out SafeSet <Method> allNewSuggestedPUTs, string currPUTSignature, out bool bHasSomeCoveredLocation,
                                         out bool bAllAreNewLocations, out bool bNoneAreNewLocations)
        {
            PexMeFactoryGuesser pfg = new PexMeFactoryGuesser(this.host);

            HashSet <string> allGivenUpLocations, allCoveredLocations, newUnCoveredLocations;

            //Analyze the current uncovered and previously uncovered locations
            this.pmd.AnalyzePreviousAndCurrentUncoveredLoc(currPUTSignature, out allGivenUpLocations,
                                                           out allCoveredLocations, out newUnCoveredLocations, out bHasSomeCoveredLocation, out bAllAreNewLocations, out bNoneAreNewLocations);

            allNewSuggestedPUTs = new SafeSet <Method>();
            //Iterate through each uncovered location
            foreach (var ucovLocList in pmd.UncoveredLocationDictionary.Values)
            {
                //TODO: Classify the uncovered locations into different groups
                //Because, it can happen that a single code location can have multiple terms which
                //cannot be merged together.
                if (ucovLocList.StoreList.Count == 0)
                {
                    continue;
                }

                //Check whether this location is earlier attempted and is failed. no
                //need to try this location again
                FactorySuggestionStore fss = null;
                string key = null;
                if (this.pmd.FactorySuggestionsDictionary.TryGetValue(ucovLocList.ExplorableType, out fss))
                {
                    key = UncoveredCodeLocationStore.GetKey(ucovLocList.Location.ToString(),
                                                            ucovLocList.ExplorableType, ucovLocList.TermIndex);

                    //A fix to keep track of uncovered locations in system libraries
                    if (TargetBranchAnalyzer.IsUncoveredLocationInSystemLib(ucovLocList.Location))
                    {
                        fss.UncoveredSystemLibLocations.Add(key);
                    }

                    if (allGivenUpLocations.Contains(key))
                    {
                        continue;
                    }
                    //Already covered locations can be reported again due to different PUTs or different call sites
                    //if (allCoveredLocations.Contains(key))
                    //    continue;
                    if (fss.PermanentFailedUncoveredLocations.Contains(key))
                    {
                        continue;
                    }
                    //if (fss.SuccessfulCoveredLocations.Contains(key))
                    //    continue;
                }

                //A single element of ucovLoc is sufficient here
                var ucovLoc = ucovLocList.StoreList[0];
                if (!pfg.TryInferFactoryMethod(ucovLoc, out ucovLoc.SuggestedMethodSetforFactory))
                {
                    this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "postprocessor",
                                             "Failed to suggest factory methods for uncovered location " + ucovLoc.ToString() + " -> Adding to permanent failed locations");

                    if (fss != null && key != null)
                    {
                        fss.PermanentFailedUncoveredLocations.Add(key);
                    }

                    continue;
                }

                //If a suggested method is not yet explored, add it to all new suggested method
                if (ucovLoc.SuggestedMethodSetforFactory != null)
                {
                    foreach (var suggestedm in ucovLoc.SuggestedMethodSetforFactory)
                    {
                        if (suggestedm.IsConstructor)
                        {
                            continue;
                        }

                        //Check if this is ever explored by this process by getting associated PUT
                        Method pexmethod;
                        bool   bretval = PUTGenerator.PUTGenerator.TryRetrievePUT(this.pmd, this.currAssembly, suggestedm, out pexmethod);
                        if (!bretval)
                        {
                            //The suggested method is out of scope of current library and
                            //no need to explore it explicitly
                            continue;
                        }

                        //Ignore self suggestions
                        if (pexmethod == this.pmd.CurrentPUTMethod)
                        {
                            continue;
                        }
                        var signature = MethodOrFieldAnalyzer.GetMethodSignature(pexmethod);
                        if (this.pmd.AllExploredMethods.Contains(signature))
                        {
                            continue;
                        }

                        if (this.pmd.PendingExplorationMethods.Contains(signature))
                        {
                            this.host.Log.LogWarning(WikiTopics.MissingWikiTopic,
                                                     "Nested PUTs", "Ignoring the nested PUT due to cycle detection " + signature);
                            continue;
                        }

                        allNewSuggestedPUTs.Add(pexmethod);
                    }
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Updates all sequences in uncovered location stores with new suggestions that
        /// are also stored within the PUT itself
        /// </summary>
        private void UpdateUncoveredLocationsWithNewSuggestions(string currPUTSignature)
        {
            //Iterate through each uncovered location
            foreach (var ucovLocList in this.pmd.UncoveredLocationDictionary.Values)
            {
                //TODO: Classify the uncovered locations into different groups
                //Because, it can happen that a single code location can have multiple terms which
                //cannot be merged together.
                if (ucovLocList.StoreList.Count == 0)
                {
                    continue;
                }

                //Check whether this location is earlier attempted and is failed. no
                //need to try this location again
                FactorySuggestionStore fss;
                if (!this.pmd.FactorySuggestionsDictionary.TryGetValue(ucovLocList.ExplorableType, out fss))
                {
                    this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "UncoveredLocations",
                                             "Failed to retrieve factory suggestion store for explorable type " + ucovLocList.ExplorableType);
                    continue;
                }

                MethodSignatureSequenceList putspecificlist;
                if (!fss.FinalPUTSequences.TryGetValue(currPUTSignature, out putspecificlist))
                {
                    putspecificlist = new MethodSignatureSequenceList();
                }

                var ucovLoc = ucovLocList.StoreList[0];
                //If a suggested method is not yet explored, add it to all new suggested method
                if (ucovLoc.SuggestedMethodSetforFactory != null)
                {
                    //Prepare new sequences with the suggested method
                    var newmssl = new MethodSignatureSequenceList();
                    foreach (var suggestedm in ucovLoc.SuggestedMethodSetforFactory)
                    {
                        //Get all the pre-requisite sequences for this suggested method
                        var suggestedmsig = MethodOrFieldAnalyzer.GetMethodSignature(suggestedm);
                        MethodSignatureSequenceList mssl;
                        fss.FinalSuggestedMethodSequences.TryGetValue(suggestedmsig, out mssl);
                        if (mssl == null || mssl.SequenceList.Count == 0)
                        {
                            var tempmss = new MethodSignatureSequence();
                            tempmss.Sequence.Add(suggestedmsig);
                            newmssl.SequenceList.Add(tempmss);
                        }
                        else
                        {
                            //Make a new sequence from the suggested method and its pre-requisite
                            foreach (var seq in mssl.SequenceList)
                            {
                                var tempmss = new MethodSignatureSequence();
                                tempmss.Sequence.AddRange(seq.Sequence);
                                tempmss.Sequence.Add(suggestedmsig);
                                newmssl.SequenceList.Add(tempmss);
                            }
                        }
                    }

                    //Add all these suggestions to the uncovered location store itself
                    bool bNewlyCreated = false;
                    var  pucls         = fss.GetPersistentLocationstore(ucovLoc, out bNewlyCreated);
                    pucls.UpdateSuggestedMethodSequences(newmssl, putspecificlist);

                    //Check whether any looping is required. If a method
                    //is repeated more than 3 times, in a sequence, we consider
                    //it as a looping requirement. This is only a heuristic based.
                    if (!PexMeConstants.IGNORE_LOOP_FEATURE && !pucls.LoopingFeatureApplied)
                    {
                        this.CheckNEnhanceForLooping(pucls, pucls.Fitnessvalue,
                                                     ucovLoc.DesiredFieldModificationType, ucovLoc.AllFields);
                    }

                    //Check for the number of sequences in this pucls. If they
                    //exceed the limit, delete the sequences
                    if ((pucls.SuggestedMethodSequences.Count - fss.FinalSuggestedMethodSequences.Values.Count)
                        > PexMeConstants.MAX_ALLOWED_SEQUENCES)
                    {
                        fss.RemoveUncoveredLocationStore(pucls, false, this.pmd);
                        var key = UncoveredCodeLocationStore.GetKey(pucls.CodeLocation, pucls.ExplorableType, pucls.TermIndex);
                        fss.PermanentFailedUncoveredLocations.Add(key);
                        fss.TemporaryFailedUncoveredLocations.Add(key, PexMeConstants.MAX_UNCOVEREDLOC_ATTEMPTS);
                        this.pmd.Log.LogWarning(WikiTopics.MissingWikiTopic, "uncoveredlocation",
                                                @"Sequences for uncovered location " + pucls.CodeLocation +
                                                "crossed the threshold " + PexMeConstants.MAX_ALLOWED_SEQUENCES + ", Deleted forever");
                    }
                }
            }

            //Add default sequences to the newly created factory suggestion stores
            foreach (var ucovLocList in this.pmd.UncoveredLocationDictionary.Values)
            {
                if (ucovLocList.StoreList.Count == 0)
                {
                    continue;
                }

                FactorySuggestionStore fss;
                if (!this.pmd.FactorySuggestionsDictionary.TryGetValue(ucovLocList.ExplorableType, out fss))
                {
                    continue;
                }

                var ucovLoc = ucovLocList.StoreList[0];
                if (fss.BCreatedNow)
                {
                    fss.BCreatedNow = false;
                    var mss            = new MethodSignatureSequence();
                    var explorableType = ucovLocList.ExplorableType;
                    foreach (var methodinucov in ucovLoc.MethodCallSequence.Sequence)
                    {
                        if (methodinucov.Contains("..ctor(")) //Don't add constructors
                        {
                            continue;
                        }
                        if (!methodinucov.Contains(explorableType)) //Ignore the method calls from other types
                        {
                            continue;
                        }
                        mss.Sequence.Add(methodinucov);
                    }
                    fss.AddDefaultSequence(this.pmd, mss);
                }
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Compares current uncovered locations with the previous uncovered locations
        /// </summary>
        internal void AnalyzePreviousAndCurrentUncoveredLoc(string currPUTSignature,
                                                            out HashSet <string> allGivenUpLocations, out HashSet <string> allCoveredLocations,
                                                            out HashSet <string> newUncoveredLocations, out bool hasSomeCoveredLocation,
                                                            out bool bAllAreNewLocations, out bool bNoneAreNewLocations)
        {
            hasSomeCoveredLocation = false;
            bAllAreNewLocations    = true;
            bNoneAreNewLocations   = true;

            var resolvedPrevLocations = new SafeSet <string>();
            var bestFitnessValues     = new SafeDictionary <string, int>();

            //This dictionary is constructed since the FactorySuggestionStore is based
            //on declarting type not on the explorable type, which can be different
            allGivenUpLocations  = new HashSet <string>();
            allCoveredLocations  = new HashSet <string>();
            tempAllLocationStore = new SafeDictionary <string, PersistentUncoveredLocationStore>();

            //All final suggested sequences of the current PUT
            var putspecificsequences = new List <MethodSignatureSequence>();

            foreach (var fss in this.FactorySuggestionsDictionary.Values)
            {
                foreach (var codelockey in fss.locationStoreSpecificSequences.Keys)
                {
                    var pucls = fss.locationStoreSpecificSequences[codelockey];
                    if (!pucls.IsDormat())  //Donot touch dormant persistent stores
                    {
                        tempAllLocationStore[codelockey] = pucls;
                    }
                }

                foreach (var givenUpLocation in fss.PermanentFailedUncoveredLocations)
                {
                    allGivenUpLocations.Add(givenUpLocation);
                }

                foreach (var coveredLocation in fss.SuccessfulCoveredLocations)
                {
                    allCoveredLocations.Add(coveredLocation);
                }

                //MethodSignatureSequenceList mssl;
                //if (fss.FinalPUTSequences.TryGetValue(currPUTSignature, out mssl))
                //{
                //    foreach (var seq in mssl.SequenceList)
                //    {
                //        if (!putspecificsequences.Contains(seq))
                //            putspecificsequences.Add(seq);
                //    }
                //}
            }

            var failedLocations = new SafeSet <PersistentUncoveredLocationStore>();

            //Traverse all uncovered locations
            foreach (var ucovLocList in this.UncoveredLocationDictionary.Values)
            {
                var locationStr = ucovLocList.Location.ToString();
                var key         = UncoveredCodeLocationStore.GetKey(ucovLocList.Location.ToString(),
                                                                    ucovLocList.ExplorableType.ToString(), ucovLocList.TermIndex);

                //Check whether there are any defect detecting sequences. If yes promote them
                //in the associated factory store
                foreach (var ucls in ucovLocList.StoreList)
                {
                    if (ucls.IsADefectDetectingSequence)
                    {
                        var fss = this.FactorySuggestionsDictionary[ucls.ExplorableType.ToString()];
                        SafeDebug.AssumeNotNull(fss, "fss cannot be null");
                        fss.AddToDefectDetectingSequences(ucls.MethodCallSequence);
                    }
                }

                if (allGivenUpLocations.Contains(key))
                {
                    //This location has been earlier given up. No need to deal with this
                    resolvedPrevLocations.Add(key);
                    this.Log.LogMessage(WikiTopics.MissingWikiTopic, "Location " + locationStr + " is ignored since it was already given up earlier!!!");
                    continue;
                }

                if (allCoveredLocations.Contains(key))
                {
                    //This location has been covered earlier. Ideally this case should not happen
                    //resolvedPrevLocations.Add(key);
                    this.Log.LogMessage(WikiTopics.MissingWikiTopic,
                                        "Location " + locationStr + " is previously covered, but can be reported since the caller could be different.");
                    bAllAreNewLocations = false;
                    //continue;
                }

                //Get the associated factory suggestion store
                if (tempAllLocationStore.ContainsKey(key))
                {
                    bAllAreNewLocations = false;
                    var pucls = tempAllLocationStore[key];
                    resolvedPrevLocations.Add(key);

                    //For some formats such as TRUE_SET, we do not need the fitness measure
                    //If they are not covered in one attempt, they won't be covered any time
                    if (ucovLocList.StoreList.Count > 0)
                    {
                        var fmt = ucovLocList.StoreList[0].DesiredFieldModificationType;
                        if (!this.IsFitnessRequired(fmt))
                        {
                            pucls.NumberOfUnsuccessfulAttempts = PexMeConstants.MAX_UNSUCCESSFUL_ATTEMPTS + 1;
                        }
                    }

                    //Reached the threshold of number of attempts. So deleting this uncovered location forever
                    if (pucls.NumberOfUnsuccessfulAttempts + 1 <= PexMeConstants.MAX_UNSUCCESSFUL_ATTEMPTS)
                    {
                        //Handle according to fitness value and drop the other methods that
                        //acutally did not help increase the fitness value
                        this.RemoveSuggestionsWithLowFitness(ucovLocList, tempAllLocationStore[key], putspecificsequences);
                        this.Log.LogMessage(WikiTopics.MissingWikiTopic,
                                            "Location " + locationStr + " is resolved and is still uncovered in the new run " +
                                            "(fitness: " + pucls.Fitnessvalue + "), (Attempt: " + pucls.NumberOfUnsuccessfulAttempts + ")");
                    }
                    else
                    {
                        this.Log.LogMessage(WikiTopics.MissingWikiTopic,
                                            "Location " + locationStr + " is resolved and but not making any process!!! Will be deleted forever");
                        //This pucls data will be deleted forever since it reached its max attempts without any progress
                        failedLocations.Add(pucls);
                    }
                }
            }

            //New locations that added to the factory suggestion store
            newUncoveredLocations = new HashSet <string>();
            foreach (var ucovLocList in this.UncoveredLocationDictionary.Values)
            {
                var key = UncoveredCodeLocationStore.GetKey(ucovLocList.Location.ToString(),
                                                            ucovLocList.ExplorableType.ToString(), ucovLocList.TermIndex);
                if (!resolvedPrevLocations.Contains(key))
                {
                    newUncoveredLocations.Add(key);
                    this.Log.LogMessage(WikiTopics.MissingWikiTopic,
                                        "Location " + ucovLocList.Location.ToString() + " is newly added in the new run");
                    bNoneAreNewLocations = false;
                }
            }

            //Unresolved locations from the previous run. This means that these sequences
            //are either already covered or not covered due to some new exception...
            var unresolvedPrevLocations = new SafeSet <PersistentUncoveredLocationStore>();
            var alreadyCoveredLocations = new SafeSet <PersistentUncoveredLocationStore>();

            foreach (var fss in this.FactorySuggestionsDictionary.Values)
            {
                var allRemovedPUCLS = new List <PersistentUncoveredLocationStore>();

                //Delete all failed locations if the suggested methods for this
                //failed location are all actually already explored. If not, place
                //them in pending status. Usually this case happens, if covering
                //the same location within the method is required by another location
                foreach (var pucls in failedLocations)
                {
                    var key = UncoveredCodeLocationStore.GetKey(pucls.CodeLocation.ToString(),
                                                                pucls.ExplorableType.ToString(), pucls.TermIndex);

                    fss.RemoveUncoveredLocationStore(pucls, false, this);
                    allRemovedPUCLS.Add(pucls);
                }

                foreach (var codelockey in fss.locationStoreSpecificSequences.Keys)
                {
                    var tpucls = fss.locationStoreSpecificSequences[codelockey];
                    if (tpucls.IsDormat())
                    {
                        continue;
                    }

                    if (allGivenUpLocations.Contains(codelockey))
                    {
                        bAllAreNewLocations = false;
                        unresolvedPrevLocations.Add(tpucls);
                        this.Log.LogWarning(WikiTopics.MissingWikiTopic, "UncoveredLocation",
                                            "Location " + codelockey + " was already given up. Should not be reported again!!! Anyways, Deleting this location forever");
                        continue;
                    }

                    if (!resolvedPrevLocations.Contains(codelockey))
                    {
                        //Check whether this location is covered based on the coverage
                        if (tpucls.AlreadyCovered || this.IsPrevUncoveredLocationCovered(tpucls))
                        {
                            alreadyCoveredLocations.Add(tpucls);
                            this.Log.LogMessage(WikiTopics.MissingWikiTopic,
                                                "Location " + codelockey + " is successfully covered in the new run");
                            hasSomeCoveredLocation = true;
                        }
                        else
                        {
                            bAllAreNewLocations = false;
                            unresolvedPrevLocations.Add(tpucls);
                            this.Log.LogWarning(WikiTopics.MissingWikiTopic, "UncoveredLocation",
                                                "Location " + codelockey + " from the previous run is not found in the new run!!! Deleting this location forever");
                        }
                    }
                }

                //Delete all unresolved locations as they won't be required anymore!!!
                foreach (var pucls in unresolvedPrevLocations)
                {
                    fss.RemoveUncoveredLocationStore(pucls, false, this);
                    allRemovedPUCLS.Add(pucls);
                }

                //Handle all removed PUCLS
                foreach (var pucls in allRemovedPUCLS)
                {
                    var key = UncoveredCodeLocationStore.GetKey(pucls.CodeLocation, pucls.ExplorableType, pucls.TermIndex);
                    fss.PermanentFailedUncoveredLocations.Add(key);
                    if (!fss.TemporaryFailedUncoveredLocations.ContainsKey(key))
                    {
                        //Are there any active uncovered locations
                        if (this.AnyActiveUncoveredLocations())
                        {
                            fss.TemporaryFailedUncoveredLocations[key] = 1;
                        }
                        else
                        {
                            fss.TemporaryFailedUncoveredLocations[key] = PexMeConstants.MAX_UNCOVEREDLOC_ATTEMPTS;
                        }
                    }
                }

                //Delete all the information regarding covered locations and upgrade their specific factory methods
                foreach (var pucls in alreadyCoveredLocations)
                {
                    fss.RemoveUncoveredLocationStore(pucls, true, this);
                }

                alreadyCoveredLocations.Clear();
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Adds a field to an unsuccessful code location.
        /// </summary>
        /// <param name="location"></param>
        /// <param name="fields"></param>
        public void AddFieldsOfUncoveredCodeLocations(CodeLocation location, SafeList <Field> fields, FieldModificationType fmt,
                                                      Term condition, string terms, int fitnessval, TypeEx explorableType, SafeList <TypeEx> allFieldTypes)
        {
            //No need to process this location.
            if (fields.Count == 0)
            {
                return;
            }

            Field  targetField;
            TypeEx declaringType;   //This declaring type is considered as explorable type in the rest of the analysis

            if (!PexMeFactoryGuesser.GetTargetExplorableField(this, fields, out targetField, out declaringType))
            {
                this.Log.LogError(WikiTopics.MissingWikiTopic, "factoryguesser",
                                  "Failed to retrieve the target field for uncovered location " + location.ToString());
                return;
            }

            //Compare the declaring type and actual explorable type.
            //If there is a inheritance relation, use the actual one
            if (explorableType.IsAssignableTo(declaringType))
            {
                declaringType = explorableType;
            }

            var uclskey = UncoveredCodeLocationStore.GetKey(location.ToString(), declaringType.ToString(), condition.UniqueIndex);
            UncoveredCodeLocationStoreList uclslist;

            if (!this.unCoveredLocationDic.TryGetValue(uclskey, out uclslist))
            {
                uclslist                           = new UncoveredCodeLocationStoreList();
                uclslist.Location                  = location;
                uclslist.ExplorableType            = declaringType.ToString();
                uclslist.TermIndex                 = condition.UniqueIndex;
                this.unCoveredLocationDic[uclskey] = uclslist;
            }

            var ucls = new UncoveredCodeLocationStore();

            ucls.Location       = location;
            ucls.ExplorableType = declaringType;
            ucls.TargetField    = targetField;
            ucls.AllFields.AddRange(fields);
            ucls.AllFieldTypes.AddRange(allFieldTypes);
            ucls.TermIndex = condition.UniqueIndex;
            //add the sequence of method calls
            ucls.MethodCallSequence = new MethodSignatureSequence();
            foreach (var m in this.LastExecutedFactoryMethodCallSequence)
            {
                ucls.MethodCallSequence.Sequence.Add(MethodOrFieldAnalyzer.GetMethodSignature(m));
            }
            ucls.IsADefectDetectingSequence = this.DefectDetectingSequence;
            ucls.CUTMethodCallSequence      = this.LastExecutedCUTMethodCallSequence;

            if (!uclslist.StoreList.Contains(ucls))
            {
                ucls.TextualTerms.Add(terms);
                ucls.DesiredFieldModificationType = fmt;
                ucls.Fitnessvalue = fitnessval;
                uclslist.StoreList.Add(ucls);
            }
        }