コード例 #1
0
        /// <summary>
        /// Detects a matching sequence of "seq" in the sequence list. There should be an exact match
        /// </summary>
        /// <param name="seq"></param>
        /// <param name="seqlist"></param>
        /// <returns></returns>
        internal static bool TryGetMatchingSequence(MethodSignatureSequence seq, List <MethodSignatureSequence> seqlist,
                                                    out MethodSignatureSequence matchingseq)
        {
            var matchingList = new Microsoft.ExtendedReflection.Collections.SafeList <MethodSignatureSequence>();

            matchingseq = null;
            foreach (var tseq in seqlist)
            {
                if (IsASubsequence(seq, tseq))
                {
                    matchingList.Add(tseq);
                }
            }

            if (matchingList.Count == 0)
            {
                return(false);
            }
            else
            {
                matchingList.Sort();
                matchingseq = matchingList[0];
                return(true);
            }
        }
コード例 #2
0
        /// <summary>
        /// Checks whether seq2 is a subsequence of seq1. This function do not considers null sequences
        /// </summary>
        /// <param name="seq1"></param>
        /// <param name="seq2"></param>
        /// <returns></returns>
        internal static bool IsASubsequence(MethodSignatureSequence seq1, MethodSignatureSequence seq2)
        {
            if (seq1.Sequence.Count == 0 || seq2.Sequence.Count == 0)
            {
                return(false);
            }

            IEnumerator <string> seq2iter = seq2.Sequence.GetEnumerator();

            seq2iter.MoveNext();
            var seq2elem = seq2iter.Current;

            foreach (var seq1elem in seq1.Sequence)
            {
                if (seq1elem == seq2elem)
                {
                    if (seq2iter.MoveNext())
                    {
                        seq2elem = seq2iter.Current;
                    }
                    else
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
コード例 #3
0
        /// <summary>
        /// Adds a default method-call sequence that represents the first execution
        /// of the PUT
        /// </summary>
        internal void AddDefaultSequence(PexMeDynamicDatabase pmd, MethodSignatureSequence defaultSeq)
        {
            //Get the method associated with the current exploring PUT
            string methodcallname = PexMeConstants.DEFAULT_FINAL_SUGGESTION_STORE;
            Method assocMethod;

            if (PUTGenerator.PUTGenerator.TryRetrieveMethodCall(pmd.CurrentPUTMethod, out assocMethod))
            {
                methodcallname = MethodOrFieldAnalyzer.GetMethodSignature(assocMethod);
            }

            //Get PUT independent sequence list
            MethodSignatureSequenceList putIndependentMssl;

            if (!this.FinalSuggestedMethodSequences.TryGetValue(methodcallname, out putIndependentMssl))
            {
                putIndependentMssl = new MethodSignatureSequenceList();
                this.FinalSuggestedMethodSequences.Add(methodcallname, putIndependentMssl);
                putIndependentMssl.Add(defaultSeq);
            }

            //Also update the PUT specific sequences. These gets cleared once a
            //PUT is completely explored.
            var putsignature = MethodOrFieldAnalyzer.GetMethodSignature(pmd.CurrentPUTMethod);
            MethodSignatureSequenceList putSpecificMssl;

            if (!this.FinalPUTSequences.TryGetValue(putsignature, out putSpecificMssl))
            {
                putSpecificMssl = new MethodSignatureSequenceList();
                this.FinalPUTSequences.Add(putsignature, putSpecificMssl);
                putSpecificMssl.Add(defaultSeq);
            }
        }
コード例 #4
0
 /// <summary>
 /// Adds a method signature sequence to defect detecting sequences.
 /// </summary>
 /// <param name="mss"></param>
 public void AddToDefectDetectingSequences(MethodSignatureSequence mss)
 {
     if (!this.DefectDetectingSequences.Contains(mss))
     {
         this.DefectDetectingSequences.Add(mss);
     }
 }
コード例 #5
0
 public void Add(MethodSignatureSequence seq)
 {
     if (!this.list.Contains(seq))
     {
         this.list.Add(seq);
     }
 }
コード例 #6
0
        /// <summary>
        /// Upgrades other PersistentUncoveredLocationStores that are currently
        /// active with the newly detected sequences.
        /// </summary>
        /// <param name="putsignature"></param>
        /// <param name="matchingseq"></param>
        private void UpgradeActiveULStores(string putsignature, MethodSignatureSequence matchingseq)
        {
            foreach (var pucls in this.locationStoreSpecificSequences.Values)
            {
                if (pucls.IsDormat())
                {
                    continue;
                }

                if (!pucls.SuggestedMethodSequences.Contains(matchingseq))
                {
                    pucls.SuggestedMethodSequences.Add(matchingseq);
                }
            }
        }
コード例 #7
0
        /// <summary>
        /// Checks whether seq2 is equal to seq1. This function do not considers null sequences
        /// </summary>
        /// <param name="seq1"></param>
        /// <param name="seq2"></param>
        /// <returns></returns>
        internal static bool AreEqualSequences(MethodSignatureSequence seq1, MethodSignatureSequence seq2)
        {
            if (seq1.Sequence.Count == 0 || seq2.Sequence.Count == 0 || seq1.Sequence.Count != seq2.Sequence.Count)
            {
                return(false);
            }

            IEnumerator <string> seq2iter = seq2.Sequence.GetEnumerator();

            seq2iter.MoveNext();
            var seq2elem = seq2iter.Current;

            foreach (var seq1elem in seq1.Sequence)
            {
                if (seq1elem != seq2elem)
                {
                    return(false);
                }

                seq2elem = seq2iter.Current;
            }

            return(true);
        }
コード例 #8
0
        /// <summary>
        /// Re-activates this PUT;
        /// </summary>
        /// <param name="?"></param>
        /// <returns></returns>
        public bool ActivateFromDormant(string putname)
        {
            if (this.associatedPUTName == putname)
            {
                bDormant = false;
                var newSequenceList = new List <MethodSignatureSequence>();

                //Re-activate based on the snapshot of sequences taken.
                MethodSignatureSequenceList mssl;
                if (!this.parentfss.FinalPUTSequences.TryGetValue(putname, out mssl))
                {
                    return(true);
                }

                if (this.putSeqSnapshot == null)
                {
                    this.putSeqSnapshot = new MethodSignatureSequenceList();
                }

                foreach (var seq in mssl.SequenceList)
                {
                    if (this.putSeqSnapshot.SequenceList.Contains(seq))
                    {
                        continue;
                    }

                    //A new sequence is detected after this uncovered location store went to dormant stage
                    MethodSignatureSequence newMs = new MethodSignatureSequence();
                    newMs.Sequence.AddRange(seq.Sequence);
                    this.SuggestedMethodSequences.Add(newMs);
                }

                return(true);
            }
            return(false);
        }
コード例 #9
0
        /// <summary>
        /// Gets the entire list of suggested methods
        /// </summary>
        /// <returns></returns>
        public IEnumerable <MethodSignatureSequence> GetSuggestedMethodSequences(PexMeDynamicDatabase pmd)
        {
            var uniqueSequenceList = new List <MethodSignatureSequence>();

            //Gather all sequences among all location stores. Detect the unique
            //sequences among them and suggest the complete unique sequences
            foreach (var pucls in this.locationStoreSpecificSequences.Values)
            {
                if (pucls.IsDormat())
                {
                    continue;
                }

                foreach (var ms in pucls.SuggestedMethodSequences)
                {
                    if (ms.Sequence.Count == 0)
                    {
                        continue;
                    }

                    if (!uniqueSequenceList.Contains(ms))
                    {
                        uniqueSequenceList.Add(ms);
                    }
                }
            }

            //Return all final sequence ever collected to help cover more
            //at the first time itself. Along with the final suggested method,
            //we also need to add the method itself
            foreach (var methodid in this.FinalSuggestedMethodSequences.Keys)
            {
                var seqlist = this.FinalSuggestedMethodSequences[methodid];
                foreach (var seq in seqlist.SequenceList)
                {
                    MethodSignatureSequence tempseq = new MethodSignatureSequence();
                    tempseq.Sequence.AddRange(seq.Sequence);
                    tempseq.Sequence.Add(methodid);

                    if (!uniqueSequenceList.Contains(tempseq))
                    {
                        uniqueSequenceList.Add(tempseq);
                    }
                }
            }

            foreach (var seqlist in this.FinalSuggestedMethodSequences.Values)
            {
                foreach (var seq in seqlist.SequenceList)
                {
                    if (seq.Sequence.Count == 0)
                    {
                        continue;
                    }

                    if (!uniqueSequenceList.Contains(seq))
                    {
                        uniqueSequenceList.Add(seq);
                    }
                }
            }

            //Return all previously collected sequences for this PUT, if there exist
            //no sequences specific to any uncovered location yet.
            var putsignature = MethodOrFieldAnalyzer.GetMethodSignature(pmd.CurrentPUTMethod);
            MethodSignatureSequenceList mssl;

            if (this.FinalPUTSequences.TryGetValue(putsignature, out mssl))
            {
                foreach (var seq in mssl.SequenceList)
                {
                    if (seq.Sequence.Count == 0)
                    {
                        continue;
                    }

                    if (!uniqueSequenceList.Contains(seq))
                    {
                        uniqueSequenceList.Add(seq);
                    }
                }
            }

            foreach (var ms in uniqueSequenceList)
            {
                yield return(ms);
            }
        }
コード例 #10
0
        /// <summary>
        /// Removes the uncovered location store. Mainly keeps the sequence
        /// that helped to cover the target location and drops all others
        /// </summary>
        /// <param name="pucls"></param>
        /// <param name="successful">Helps to distinguish between a removal during success and failure</param>
        internal void RemoveUncoveredLocationStore(PersistentUncoveredLocationStore pucls,
                                                   bool successful, PexMeDynamicDatabase pmd)
        {
            var key = UncoveredCodeLocationStore.GetKey(pucls.CodeLocation, pucls.ExplorableType, pucls.TermIndex);

            this.locationStoreSpecificSequences.Remove(key);
            if (!successful)
            {
                return;
            }

            this.SuccessfulCoveredLocations.Add(key);
            this.PermanentFailedUncoveredLocations.Remove(key);
            this.TemporaryFailedUncoveredLocations.Remove(key);
            this.UncoveredSystemLibLocations.Remove(key);

            //Get the method associated with the current exploring PUT
            string methodcallname = PexMeConstants.DEFAULT_FINAL_SUGGESTION_STORE;
            Method assocMethod;

            if (PUTGenerator.PUTGenerator.TryRetrieveMethodCall(pmd.CurrentPUTMethod, out assocMethod))
            {
                methodcallname = MethodOrFieldAnalyzer.GetMethodSignature(assocMethod);
            }

            //Get PUT independent sequence list
            MethodSignatureSequenceList putIndependentMssl;

            if (!this.FinalSuggestedMethodSequences.TryGetValue(methodcallname, out putIndependentMssl))
            {
                putIndependentMssl = new MethodSignatureSequenceList();
                this.FinalSuggestedMethodSequences.Add(methodcallname, putIndependentMssl);
            }

            //Also update the PUT specific sequences. These gets cleared once a
            //PUT is completely explored.
            var putsignature = MethodOrFieldAnalyzer.GetMethodSignature(pmd.CurrentPUTMethod);
            MethodSignatureSequenceList putSpecificMssl;

            if (!this.FinalPUTSequences.TryGetValue(putsignature, out putSpecificMssl))
            {
                putSpecificMssl = new MethodSignatureSequenceList();
                this.FinalPUTSequences.Add(putsignature, putSpecificMssl);
            }

            //Any Persistent Uncovered location store that is successfully
            //covered gets a hit sequence
            SafeDebug.AssumeNotNull(pucls.HitSequence, "pucls.HitSequence");
            MethodSignatureSequence matchingseq;

            if (!FactorySuggestionStore.TryGetMatchingSequence(pucls.HitSequence,
                                                               pucls.SuggestedMethodSequences, out matchingseq))
            {
                //Failed to retrieve the hit sequence. However, a heuristic
                //can be used where there is only one suggested sequence
                if (pucls.SuggestedMethodSequences.Count == 1)
                {
                    matchingseq = pucls.SuggestedMethodSequences[0];
                    putIndependentMssl.Add(matchingseq);
                    putSpecificMssl.Add(matchingseq);
                }
                else
                {
                    pmd.Log.LogWarning(WikiTopics.MissingWikiTopic, "SequenceMatch",
                                       "Failed to retrieve a matching sequence for a hit sequence, adding complete hit sequence " + pucls.HitSequence);

                    var hitSubSequence = new MethodSignatureSequence();
                    foreach (var mhit in pucls.HitSequence.Sequence)
                    {
                        if (mhit.Contains("..ctor(")) //Don't add constructors
                        {
                            continue;
                        }
                        if (!mhit.Contains(this.DeclaringType)) //Ignore the method calls from other types
                        {
                            continue;
                        }
                        hitSubSequence.Sequence.Add(mhit);
                    }

                    //Add all sequences to final set of sequences for further usage.
                    putIndependentMssl.Add(hitSubSequence);
                    putSpecificMssl.Add(hitSubSequence);
                    //this.UpgradeActiveULStores(putsignature, pucls.SuggestedMethodSequences);
                }
            }
            else
            {
                //Add all sequences to final set of sequences for further usage.
                putIndependentMssl.Add(matchingseq);
                putSpecificMssl.Add(matchingseq);
                //this.UpgradeActiveULStores(putsignature, matchingseq);
            }
        }
コード例 #11
0
        /// <summary>
        /// Takes a new sequence list and updates the existing sequence list
        /// with the new list
        /// </summary>
        /// <param name="mssl"></param>
        public void UpdateSuggestedMethodSequences(MethodSignatureSequenceList mssl, MethodSignatureSequenceList putSpecificList)
        {
            var newSuggesedMethodSequences = new List <MethodSignatureSequence>();

            if (this.SuggestedMethodSequences.Count == 0)
            {
                //A fresh location.
                //Make up new sequences with the known list
                if (putSpecificList.SequenceList.Count == 0)
                {
                    foreach (var suggestedm in mssl.SequenceList)
                    {
                        MethodSignatureSequence newMS = new MethodSignatureSequence();
                        newMS.Sequence.AddRange(suggestedm.Sequence);
                        newSuggesedMethodSequences.Add(newMS);
                    }
                }
                else
                {
                    foreach (var pseq in putSpecificList.SequenceList)
                    {
                        foreach (var suggestedm in mssl.SequenceList)
                        {
                            MethodSignatureSequence newMS = new MethodSignatureSequence();
                            newMS.Sequence.AddRange(pseq.Sequence);
                            foreach (var method in suggestedm.Sequence)
                            {
                                if (!method.Contains("..ctor("))
                                {
                                    newMS.Sequence.Add(method);
                                }
                            }

                            if (!newSuggesedMethodSequences.Contains(newMS))
                            {
                                newSuggesedMethodSequences.Add(newMS);
                            }
                        }
                    }
                }
            }
            else
            {
                //Once the looping feature is applied, there is no point in updating the sequences
                if (!this.LoopingFeatureApplied)
                {
                    //Merge and make up the new list
                    foreach (var pseq in this.SuggestedMethodSequences)
                    {
                        foreach (var suggestedm in mssl.SequenceList)
                        {
                            MethodSignatureSequence newMS = new MethodSignatureSequence();
                            newMS.Sequence.AddRange(pseq.Sequence);
                            foreach (var method in suggestedm.Sequence)
                            {
                                if (!method.Contains("..ctor("))
                                {
                                    newMS.Sequence.Add(method);
                                }
                            }

                            if (!newSuggesedMethodSequences.Contains(newMS))
                            {
                                newSuggesedMethodSequences.Add(newMS);
                            }
                        }
                    }
                }
                else
                {
                    newSuggesedMethodSequences = this.SuggestedMethodSequences;
                }
            }

            this.SuggestedMethodSequences = newSuggesedMethodSequences;
        }