Exemplo n.º 1
0
 public AffectedGraph GetAffectedGraphForChangeSet(IEnumerable<Change<MethodReference>> changes)
 {
     InvokeMinimizerMessage(MessageType.Debug, "getting tests for changes");
     var start = DateTime.Now;
     var graph = new AffectedGraph();
     var breadCrumbs = new Dictionary<string, bool>();
     var affectedItems = GetAffectedItems(changes, graph);
     var rets = affectedItems.ForkAndJoinTo(_numthreads, x =>
                                                             {
                                                                 var tmp = new AffectedGraph();
                                                                 FillAfferentGraph(x.Member, breadCrumbs,
                                                                                   tmp, null, 0, null, false,
                                                                                   new List<string>(),
                                                                                   GenericContext.Empty(), false);
                                                                 return tmp;
                                                             });
     InvokeMinimizerMessage(MessageType.Debug, "there are " + rets.Count() + " graphs returned. Combining.");
     foreach(var g in rets)
     {
         if (g != null)
         {
             InvokeMinimizerMessage(MessageType.Debug,
                                    "there are " + g.AllNodes().Count() + " Nodes in graph. TOTAL=" +
                                    graph.AllNodes().Count());
             graph = graph.Merge(g);
         }
     }
     InvokeMinimizerMessage(MessageType.Debug, "there are " + rets.Count() + " nodes in combined graph."); 
     var end = DateTime.Now;
     InvokeMinimizerMessage(MessageType.Debug, "took " + (end - start) + " to walk graph");
     return graph;
 }
Exemplo n.º 2
0
        public void adding_a_null_node_does_not_add_node()
        {
            var g = new AffectedGraph();

            g.AddNode(null);
            Assert.AreEqual(0, g.AllNodes().Count());
        }
Exemplo n.º 3
0
        public void adding_a_null_to_connection_does_not_add_node()
        {
            var g = new AffectedGraph();

            g.AddConnection("FROM", null, false);
            Assert.AreEqual(0, g.AllConnections().Count());
        }
Exemplo n.º 4
0
        public void when_no_root_node_get_root_node_returns_null()
        {
            var g = new AffectedGraph();

            g.AddNode(new AffectedGraphNode("foo", false, false, false, "name", "bar::foo", "assembly", "type", new List <TestDescriptor>(), false, false, 0));
            Assert.IsNull(g.GetRootNode());
        }
        public void node_and_direct_test_in_graph()
        {
            var graph = new AffectedGraph();

            graph.AddNode(new AffectedGraphNode(displayName: "display",
                                                isInterface: false,
                                                isTest: false,
                                                isRootNode: true,
                                                name: "A name",
                                                fullName: "fullnamecode",
                                                assembly: "foo.dll",
                                                type: "Type",
                                                testDescriptors: new List <TestDescriptor>(),
                                                isChange: false, inTestAssembly: false, complexity: 0));
            graph.AddNode(new AffectedGraphNode(displayName: "display",
                                                isInterface: false,
                                                isTest: true,
                                                isRootNode: true,
                                                name: "A name",
                                                fullName: "fullnametest",
                                                assembly: "foo.dll",
                                                type: "Type",
                                                testDescriptors: new List <TestDescriptor>(),
                                                isChange: false, inTestAssembly: true, complexity: 0));
            graph.AddConnection("fullnamecode", "fullnametest", false);
            var classifier = new TestPathsGraphRiskClassifier();

            Assert.AreEqual(100, classifier.CalculateRiskFor(graph));
        }
Exemplo n.º 6
0
        public void connection_can_be_added_between_same_nodes()
        {
            var g = new AffectedGraph();

            g.AddNode(new AffectedGraphNode("foo", false, false, false, "name", "bar::foo", "assembly", "type", new List <TestDescriptor>(), false, false, 0));
            g.AddConnection("bar::foo", "bar::foo", false);
            Assert.AreEqual(1, g.AllConnections().Count());
        }
Exemplo n.º 7
0
        public void a_connection_from_a_non_existant_node_does_not_add_connection()
        {
            var g = new AffectedGraph();

            g.AddNode(new AffectedGraphNode("foo", false, false, false, "name", "bar::foo", "assembly", "type", new List <TestDescriptor>(), false, false, 0));
            g.AddConnection("somethingnon-existant", "bar::foo", false);
            Assert.AreEqual(0, g.AllConnections().Count());
        }
Exemplo n.º 8
0
        public void empty_graphs_merge_to_empty_graph()
        {
            var graph1 = new AffectedGraph();
            var graph2 = new AffectedGraph();
            var merged = graph1.Merge(graph2);

            Assert.AreEqual(0, merged.AllNodes().Count());
        }
Exemplo n.º 9
0
        public void when_root_node_get_root_node_returns_root_node()
        {
            var g    = new AffectedGraph();
            var root = new AffectedGraphNode("foo", false, false, true, "name", "bar::foo", "assembly", "type", new List <TestDescriptor>(), false, false, 0);

            g.AddNode(root);
            g.AddNode(new AffectedGraphNode("foo", false, false, false, "name", "bar::foo2", "assembly", "type", new List <TestDescriptor>(), false, false, 0));
            Assert.AreEqual(root, g.GetRootNode());
        }
Exemplo n.º 10
0
        public void multiple_connections_can_be_added_between_two_valid_nodes_but_only_one_appears()
        {
            var g = new AffectedGraph();

            g.AddNode(new AffectedGraphNode("foo", false, false, false, "name", "bar::foo", "assembly", "type", new List <TestDescriptor>(), false, false, 0));
            g.AddNode(new AffectedGraphNode("foo", false, false, false, "name", "bar::foo2", "assembly", "type", new List <TestDescriptor>(), false, false, 0));
            g.AddConnection("bar::foo2", "bar::foo", false);
            g.AddConnection("bar::foo2", "bar::foo", false);
            Assert.AreEqual(1, g.AllConnections().Count());
        }
Exemplo n.º 11
0
        public void a_node_can_be_added()
        {
            var g = new AffectedGraph();

            g.AddNode(new AffectedGraphNode("foo", false, false, false, "name", "bar::foo", "assembly", "type", new List <TestDescriptor>(), false, false, 0));
            Assert.AreEqual(1, g.AllNodes().Count());
            Assert.AreEqual("foo", g.AllNodes().First().DisplayName);
            Assert.AreEqual("bar::foo", g.AllNodes().First().FullName);
            Assert.IsNotNull(g.GetNode("bar::foo"));
        }
Exemplo n.º 12
0
        public void SetUp()
        {
            var paths = new[]
            {
                new List <string> {
                    "GrandChild", "Child3", "Root"
                },
            };

            _graph = GraphBuilder.BuildGraphFor(paths);
        }
Exemplo n.º 13
0
        public void nodes_from_both_graphs_get_added_to_output()
        {
            var graph1 = new AffectedGraph();

            graph1.AddNode(new AffectedGraphNode("test1", false, false, false, "test", "test12", "assembly", "type", new List <TestDescriptor>(), false, false, 0));
            var graph2 = new AffectedGraph();

            graph2.AddNode(new AffectedGraphNode("test1", false, false, false, "test", "test123", "assembly", "type", new List <TestDescriptor>(), false, false, 0));
            var merged = graph1.Merge(graph2);

            Assert.AreEqual(2, merged.AllNodes().Count());
        }
        private void EnrichGraphWithProfilerInformation(string name, AffectedGraph graph)
        {
            var profilerOff = _configuration.AllSettings("mm-ProfilerSetup") == "DONTRUN";
            var items       = _profilerData.GetTestsFor(name);

            foreach (var entry in items)
            {
                var node = graph.GetNode(entry);
                if (node != null)
                {
                    node.MarkAsProfiled();
                }
            }
        }
 public int CalculateRiskFor(AffectedGraph graph)
 {
     //TODO make interface take the hash not the graph (so it canbe reused between strategies instead of built n times)
     if (graph == null) return 0;
     var root = graph.GetRootNode();
     if (root == null) return 0;
     var visited = new Dictionary<string, int>();
     var hash = GraphNodeHashBuilder.GetHashFrom(graph);
     var testsScore = RecurseFrom(root.FullName, hash, 0, 0, visited);
     var complexity = root.Complexity > 1.0m ? root.Complexity : 1.0m;
     var overallScore = testsScore/complexity;
     var ret = overallScore > 1.0m ? 1.0m : overallScore;
     return (int) (ret * 100m);
 }
Exemplo n.º 16
0
 public AffectedGraph GetCouplingGraphFor(string cacheName)
 {
     var affected = new List<ChangeContext>();
     var graph = new AffectedGraph();
     var forwardCutOffPoints = new Dictionary<string, bool>();
     var backCutOffPoints = new Dictionary<string, bool>();
     TypeDefinition scope = null;
     GetEfferentGraph(null, cacheName, forwardCutOffPoints, affected, graph, true, scope);
     WriteWalkerDebug("got " + affected + " nodes for " + cacheName, 0);
     var rets = affected.ForkAndJoinTo(_numthreads, x =>
     {
         FillAfferentGraph(x.Member, backCutOffPoints, graph, null, 0, null, false, new List<string>(), GenericContext.Empty(), false); //gets all tests Ca
         return true;
     });
     return graph;
 }
Exemplo n.º 17
0
        public int CalculateRiskFor(AffectedGraph g)
        {
            var root = g.AllNodes().FirstOrDefault(x => x.IsRootNode);

            if (root == null)
            {
                return(-1);
            }
            var connections = GetHashFrom(g);
            var risk        = RecurseRisk(root.FullName, connections, new Dictionary <string, bool>());

            if (risk.nottested + risk.tested == 0)
            {
                return(0);
            }
            return((int)(risk.tested / (decimal)(risk.nottested + risk.tested) * 100.0m));
        }
        public void single_node_in_graph_that_is_not_a_test()
        {
            var graph = new AffectedGraph();

            graph.AddNode(new AffectedGraphNode(displayName: "display",
                                                isInterface: false,
                                                isTest: false,
                                                isRootNode: true,
                                                name: "A name",
                                                fullName: "name",
                                                assembly: "foo.dll",
                                                type: "Type",
                                                testDescriptors: new List <TestDescriptor>(),
                                                isChange: false, inTestAssembly: false, complexity: 0));
            var classifier = new TestPathsGraphRiskClassifier();

            Assert.AreEqual(0, classifier.CalculateRiskFor(graph));
        }
Exemplo n.º 19
0
        public void single_node_nodein_graph_that_is_a_covered_test()
        {
            var graph = new AffectedGraph();

            graph.AddNode(new AffectedGraphNode(displayName: "display",
                                                isInterface: false,
                                                isTest: true,
                                                isRootNode: true,
                                                name: "A name",
                                                fullName: "name",
                                                assembly: "foo.dll",
                                                type: "Type",
                                                testDescriptors: new List <TestDescriptor>(),
                                                isChange: false,
                                                inTestAssembly: false,
                                                complexity: 0));
            graph.AllNodes().First().MarkAsProfiled();
            var classifier = new CoverageDistanceAndComplexityGraphRiskClassifier();

            Assert.AreEqual(100, classifier.CalculateRiskFor(graph));
        }
Exemplo n.º 20
0
        public int CalculateRiskFor(AffectedGraph graph)
        {
            if (graph == null)
            {
                return(0);
            }
            var root = graph.GetRootNode();

            if (root == null)
            {
                return(0);
            }
            var connections = GraphNodeHashBuilder.GetHashFrom(graph);
            var risk        = RecurseRisk(root.FullName, connections, new Dictionary <string, bool>());

            if (risk.nottested + risk.tested == 0)
            {
                return(0);
            }
            return((int)(risk.tested / (decimal)(risk.nottested + risk.tested) * 100.0m));
        }
Exemplo n.º 21
0
        public AffectedGraph GetProfiledGraphFor(string method)
        {
            var graph = new AffectedGraph();
            var tests = GetTestsFor(method);

            if (tests == null || !tests.Any())
            {
                return(graph);
            }
            var paths = new List <IEnumerable <string> >();

            foreach (var test in tests)
            {
                var info = GetTestInformationFor(test);
                if (info != null)
                {
                    var path = PathFinder.FindPathsTo(info, method);
                    paths.AddRange(path);
                }
            }
            return(GraphBuilder.BuildGraphFor(paths));
        }
Exemplo n.º 22
0
        private Dictionary <string, RiskNode> GetHashFrom(AffectedGraph graph)
        {
            var ret = new Dictionary <string, RiskNode>();

            foreach (var node in graph.AllNodes())
            {
                ret.Add(node.FullName, new RiskNode()
                {
                    Node = node
                });
            }
            foreach (var connection in graph.AllConnections())
            {
                RiskNode item;
                if (!ret.TryGetValue(connection.From, out item))
                {
                    ret.Add(connection.From, item);
                }
                item.connections.Add(connection.To);
            }
            return(ret);
        }
Exemplo n.º 23
0
        public static AffectedGraph BuildGraphFor(IEnumerable <IEnumerable <string> > paths)
        {
            bool first = true;
            var  ret   = new AffectedGraph();

            foreach (var path in paths)
            {
                string last = null;
                foreach (var node in path)
                {
                    if (!ret.ContainsNode(node))
                    {
                        ret.AddNode(new AffectedGraphNode(node, false, false, first, node, node, "", "", new List <TestDescriptor>(), false, false, 0));
                        first = false;
                    }
                    if (last != null)
                    {
                        ret.AddConnection(last, node, false);
                    }
                    last = node;
                }
            }
            return(ret);
        }
Exemplo n.º 24
0
 public void EnrichGraph(AffectedGraph graph)
 {
     _cache.EnrichGraph(graph);
 }
Exemplo n.º 25
0
 private IEnumerable<TestEntry> BuildEntriesFor(AffectedGraph graph)
 {
     InvokeMinimizerMessage(MessageType.Info, "there are " + graph.AllNodes().Count() + "in the graph.");
     foreach(var n in graph.AllNodes())
     {
         if (n.TestDescriptors == null) continue;
         foreach (var desc in n.TestDescriptors)
         {
             yield return new TestEntry
                              {
                                  TestAssembly = n.Assembly,
                                  TestClass = n.Type,
                                  TestName = desc.Target,
                                  TestRunners = new List<string> {desc.TestRunner}
                              };
         }
     }
 }
Exemplo n.º 26
0
 public void EnrichGraph(AffectedGraph graph)
 {
     foreach (var node in graph.AllNodes())
     {
         var cachenode = TryGetEfferentCouplingNode(node.FullName.Replace('+', '/'));
         if (cachenode != null)
         {
             var r = cachenode.MemberReference;
             if (r != null)
             {
                 node.DisplayName = r.DeclaringType.Name + "::" + r.Name;
                 node.Assembly = r.Module.Assembly.FullName;
                 node.IsInterface = r.DeclaringType.ThreadSafeResolve().IsInterface;
             }
             node.Profiled = true;
             node.IsTest = _testIdentifiers.IsTest(cachenode.MemberReference);
         }
     }
 }
 public void adding_null_node_throws_argument_null_exception()
 {
     var graph = new AffectedGraph();
     //Assert.Throws<ArgumentNullException>(() => graph.AddNode(null));
 }
Exemplo n.º 28
0
        private void FillAfferentGraph(string fullName, Dictionary<string, bool> cutPoints, AffectedGraph graph, MemberReference parent, int depth, TypeDefinition inheritedTypeContext, bool inVirtual, List<string> breadCrumbs, GenericContext genericContext, bool inSelf)
        { 
            WriteWalkerDebug(fullName, depth);
            if (TryBreadCrumbsPrune(fullName, depth, breadCrumbs))
            {
                if (parent != null)
                {
                    WriteWalkerDebug("truncating but adding connection to " + fullName, depth);
                    graph.AddConnection(parent.GetCacheName(), fullName, false);
                }
                return;
            }
            breadCrumbs.Add(fullName);
            if (TryCutPointPrune(fullName, depth, cutPoints))
            {
                if (parent != null)
                {

                    WriteWalkerDebug("bread crumbs truncating but adding connection to " + fullName, depth);
                    graph.AddConnection(parent.GetCacheName(), fullName, false);
                }
                return;
            }
            
            var efferentEntry = _cache.TryGetEfferentCouplingNode(fullName);
            var afferentEntry = _cache.TryGetEfferentCouplingNode(fullName);
            MethodDefinition currentDefinition = null;
            if (efferentEntry != null)
            {
                TypeReference parentType = null;
                if (parent != null) parentType = parent.DeclaringType;
                var definition = efferentEntry.MemberReference.DeclaringType.ThreadSafeResolve();
                if (TryInterfacePrune(fullName, depth, breadCrumbs, efferentEntry, parentType, definition)) return;
                if (TryInheritancePrune(fullName, depth, breadCrumbs, inVirtual, definition, inheritedTypeContext)) {return;}
                inheritedTypeContext = GetNewTypeContext(inheritedTypeContext, definition);
                currentDefinition = efferentEntry.MemberReference as MethodDefinition;
                if (currentDefinition != null)
                {
                    if(currentDefinition.DeclaringType == null) {}
                    if (parent is FieldReference && currentDefinition.IsConstructor)
                    {
                        breadCrumbs.Remove(fullName);
                        return;
                    }
                }
            }
            var touse = afferentEntry ?? efferentEntry;
            WriteWalkerDebug("adding node " + fullName, depth);
            var newnode = GetGraphNode(fullName, touse, parent == null, false);
            graph.AddNode(newnode);
            if (parent != null)
            {
                 graph.AddConnection(parent.GetCacheName(), newnode.FullName, false);    
            }
            if(currentDefinition != null)
                RecurseSynonyms(depth, cutPoints, inheritedTypeContext, currentDefinition, graph, breadCrumbs, genericContext);
            RecurseAfferentCouplings(fullName, depth, cutPoints, inVirtual, inheritedTypeContext, graph, parent, breadCrumbs, genericContext);
            breadCrumbs.Remove(fullName);
        }
Exemplo n.º 29
0
 private IEnumerable<ChangeContext> GetAffectedItems(IEnumerable<Change<MethodReference>> changes, AffectedGraph graph)
 {
     var affected = new List<ChangeContext>();
     foreach (var change in changes)
     {
         var forwardCutOffPoints = new Dictionary<string, bool>();
         if (change.ChangeType == ChangeType.Remove) continue;
         change.ItemChanged.GetCacheName();
         var scope = change.ItemChanged.DeclaringType.ThreadSafeResolve();
         GetEfferentGraph(null, change.ItemChanged.GetCacheName(), forwardCutOffPoints, affected, graph, true, scope);
     }
     return affected;
 }
Exemplo n.º 30
0
 static IEnumerable<TestDescriptor> GetTestsInGraph(AffectedGraph graph)
 {
     return graph.AllNodes().Where(entry => entry.IsTest).SelectMany(entry => entry.TestDescriptors);
 }
 private static void ConvertToGraphMessage(VisualGraphGeneratedMessage message, AffectedGraph graph)
 {
     foreach (var node in graph.AllNodes())
     {
         message.Nodes.Add(new GraphNode
         {
             Assembly       = node.Assembly,
             DisplayName    = node.DisplayName,
             FullName       = node.FullName,
             IsInterface    = node.IsInterface,
             IsChange       = node.IsChange,
             IsRootNode     = node.IsRootNode,
             IsTest         = node.IsTest,
             Name           = node.Name,
             Type           = node.Type,
             InTestAssembly = node.InTestAssembly,
             IsProfiledTest = node.Profiled,
             Complexity     = node.Complexity,
         });
     }
     foreach (var c in graph.AllConnections())
     {
         message.Connections.Add(new Connection {
             From = c.From, To = c.To
         });
     }
 }
 private static void ConvertToGraphMessage(VisualGraphGeneratedMessage message, AffectedGraph graph)
 {
     foreach (var node in graph.AllNodes())
     {
         message.Nodes.Add(new GraphNode
                           {
                               Assembly = node.Assembly,
                               DisplayName = node.DisplayName,
                               FullName = node.FullName,
                               IsInterface = node.IsInterface,
                               IsChange = node.IsChange,
                               IsRootNode = node.IsRootNode,
                               IsTest = node.IsTest,
                               Name = node.Name,
                               Type = node.Type,
                               InTestAssembly = node.InTestAssembly,
                               IsProfiledTest = node.Profiled,
                               Complexity = node.Complexity,
                           });
     }
     foreach (var c in graph.AllConnections())
     {
         message.Connections.Add(new Connection {From = c.From, To = c.To});
     }
 }
Exemplo n.º 33
0
        private void RecurseSynonyms(int depth, Dictionary<string, bool> history, TypeDefinition inheritedTypeContext, MethodDefinition currentDefinition, AffectedGraph graph, List<string> breadCrumbs, GenericContext genericContext)
        {
            var synonyms = SynonymFinder.FindSynonymsFor(currentDefinition);

            foreach (var current in synonyms)
            {
                var c = current as MethodDefinition;
                if (c == null) continue; //shouldn't happen
                if (!c.DeclaringType.IsInterface)
                {
                    FillAfferentGraph(current.GetCacheName(), history, graph, currentDefinition, depth + 1,
                                    inheritedTypeContext, true, breadCrumbs, genericContext, true); //always a base
                }
                else
                {
                    FillAfferentGraph(current.GetCacheName(), history, graph, currentDefinition, depth + 1, 
                        inheritedTypeContext, false, breadCrumbs, genericContext, false);
                }
            }
        }
Exemplo n.º 34
0
        private void RecurseAfferentCouplings(string fullName, int depth, Dictionary<string, bool> history, bool inInheritanceChain, TypeDefinition inheritedTypeContext, AffectedGraph graph, MemberReference parent, List<string> breadCrumbs, GenericContext genericContext)
        {
            var afferentEntry = _cache.TryGetAfferentCouplingNode(fullName);

            if (afferentEntry == null) return;
            genericContext.SetIndirectConstraintsOn(afferentEntry.MemberReference, parent, inInheritanceChain);
            if (!inInheritanceChain && genericContext.IsClear())
            {
                lock (history) //double lock, TryCutPointPrune already did this
                {
                    if (!history.ContainsKey(fullName))
                    {
                        history.Add(fullName, true);
                    }
                }
            }
            foreach (var current in afferentEntry.Couplings)
            {
                if (current.IgnoreWalk) continue;
                var proposed = genericContext.GetGenericContextOf(current.ActualReference);
                if (!genericContext.CanTransitionTo(proposed))
                {
                    WriteWalkerDebug("Generics truncate", depth);
                    continue;
                }
                var newContext = genericContext.TransitionTo(proposed);
                FillAfferentGraph(current.To, history, graph, afferentEntry.MemberReference, depth + 1, inheritedTypeContext, inInheritanceChain && current.IsSelfCall, breadCrumbs, newContext, current.IsSelfCall);
            }
        }
Exemplo n.º 35
0
        public List<TestEntry> GetTestsFor(List<string> assemblies)
        {
            var ret = new List<TestEntry>();
            var param = from a in assemblies select new BuildFullMapParams(a, a);
            BuildFullMap(param);
            toDispose.Clear();
            changes = GetChanges(assemblies);
            if (changes != null)
            {
                foreach (var change in changes)
                {
                    InvokeMinimizerMessage(MessageType.Debug, change.ChangeType + " " + change.ItemChanged.GetCacheName());
                }
                ReIndex(changes);
            }

            toDispose.ForEach(x => x.Dispose());
            ModuleDefinition.KillAllReadModules();
            var strategy = new GraphBuilder(_cache, _testStrategies, new IfInTestAssemblyContinueInterfaceFollowingStrategy(_cache), _debug, _numThreads);
            strategy.DebugMessage += (x,y) => InvokeMinimizerMessage(y.MessageType, y.Message);
            _lastAffectedGraph = strategy.GetAffectedGraphForChangeSet(changes);
            var entries = BuildEntriesFor(_lastAffectedGraph).ToList();
            foreach(var file in assemblies) WriteHistoryFile(file);
            return entries;
        }
 private void EnrichGraphWithProfilerInformation(string name, AffectedGraph graph)
 {
     var profilerOff = _configuration.AllSettings("mm-ProfilerSetup") == "DONTRUN";
     var items = _profilerData.GetTestsFor(name);
     foreach (var entry in items)
     {
         var node = graph.GetNode(entry);
         if (node != null)
         {
             node.MarkAsProfiled();
         }
     }
 }
Exemplo n.º 37
0
        private void GetEfferentGraph(string parent, string fullName, IDictionary<string, bool> cutOffs, List<ChangeContext> found, AffectedGraph graph, bool isRootNode, TypeDefinition originalContext)
        {
            var entry = _cache.TryGetEfferentCouplingNode(fullName);
            var afferent = _cache.TryGetAfferentCouplingNode(fullName);
            if (isRootNode)
            {
                entry = entry ?? afferent; 
                found.Add(new ChangeContext(fullName, null));
                graph.AddNode(GetGraphNode(fullName, entry, true, true));
                if (entry != null && entry.MemberReference != null)
                {
                    var refer = entry.MemberReference as MethodReference;
                    if (refer != null && _testStrategies.IsTest(refer))
                    {
                        return;
                    }
                }
            }
            //TODO Greg this hamstrings some stuff but should work better in most cases
            //I think we only really need statics past here but need to look it over a bit.
            return;

            WriteWalkerDebug("checking " + fullName, 0);
            if (entry == null)
            {
                WriteWalkerDebug("efferent entry is null", 0);
                if (afferent != null && afferent.MemberReference is MethodReference) return; //Leaf node to a method call
            }
            if(afferent == null)
            {
                WriteWalkerDebug("afferent entry is null", 0);
            }
            if (afferent != null)
            {
                var memref = afferent.MemberReference as MethodReference;
                MethodDefinition def = null;
                if (memref != null)
                {
                    def = memref.ThreadSafeResolve();
                }
                if (!isRootNode && def != null)
                {
                    if (def.IsGetter) return;
                    if (def.DeclaringType.IsInterface) return; //don't recurse forward on interface calls
                    if (!def.HasThis) return;
                }
                var reference = afferent.MemberReference as FieldReference; //Leaf node to a field reference
                if (reference != null)
                {
                    graph.AddNode(GetGraphNode(fullName, afferent, isRootNode, false));
                    if (parent != null)
                        graph.AddConnection(parent, fullName, true);

                    found.Add(new ChangeContext(fullName, originalContext));
                }                    
            }

            if (entry == null) return;
            graph.AddNode(GetGraphNode(fullName, entry, isRootNode, false));
            if (parent != null)
                graph.AddConnection(parent, fullName, true);
            foreach (var current in entry.Couplings)
            {
                if (cutOffs.ContainsKey(current.To)) continue;
                if (current.IgnoreWalk) continue;
                if (current.ActualReference is MethodReference && !current.IsSelfCall) continue;
                cutOffs.Add(current.To, true);
                GetEfferentGraph(fullName, current.To, cutOffs, found, graph, false, originalContext);
            }
        }