public IEnumerable <object[]> GetData(MethodInfo methodInfo)
        {
            this.EnsureWorkspaceAndProject();

            var graphProvider = new CSharpFlowGraphProvider(this.workspace.CurrentSolution);

            foreach (var doc in this.project.Documents)
            {
                var syntaxTree    = doc.GetSyntaxTreeAsync().Result;
                var semanticModel = doc.GetSemanticModelAsync().Result;

                var invocationsEnumerable = syntaxTree.GetRoot().DescendantNodes()
                                            .Where(n => n.IsKind(SyntaxKind.InvocationExpression));
                foreach (InvocationExpressionSyntax invocation in invocationsEnumerable)
                {
                    if (invocation.Expression.IsKind(SyntaxKind.SimpleMemberAccessExpression))
                    {
                        string methodName = ((MemberAccessExpressionSyntax)invocation.Expression).Name.Identifier.Text;
                        if (IsEvaluationMethodName(methodName))
                        {
                            var methodDeclaration = (BaseMethodDeclarationSyntax)invocation.FirstAncestorOrSelf <MethodDeclarationSyntax>()
                                                    ?? invocation.FirstAncestorOrSelf <ConstructorDeclarationSyntax>();
                            var methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration);
                            if (methodSymbol != null)
                            {
                                yield return(new object[] { graphProvider, methodSymbol, invocation });
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 2
0
        private static void ConstructControlFlowGraph(Solution solution, MethodLocation method)
        {
            var flowGraphProvider = new CSharpFlowGraphProvider(solution);
            var result            = flowGraphProvider.GetFlowGraphAsync(method).Result;

            Assert.AreNotEqual(null, result);
        }
Exemplo n.º 3
0
        private static async Task AddMethodNodesFromFlow(
            Graph graph,
            HashSet <int> visitedIds,
            CSharpFlowGraphProvider graphProvider,
            IEnumerable <FlowNode> nodes,
            Color nodeColor)
        {
            // TODO: Make more robust (unfinished calls from the target etc.)
            foreach (var callNode in nodes.OfType <CallFlowNode>())
            {
                var cfgId = callNode.Graph.Id;
                if (visitedIds.Add(cfgId.Value))
                {
                    var location = graphProvider.GetLocation(cfgId);

                    var node = graph.AddNode(cfgId.Value.ToString());
                    node.LabelText      = location.ToString();
                    node.Attr.FillColor = nodeColor;
                }

                if (callNode.Location.CanBeExplored &&
                    await graphProvider.GetFlowGraphAsync(callNode.Location) is FlowGraph trg &&
                    visitedIds.Add(trg.Id.Value))
                {
                    var node = graph.AddNode(trg.Id.ToString());
                    node.LabelText      = callNode.Location.ToString();
                    node.Attr.FillColor = nodeColor;
                }
            }
        }
Exemplo n.º 4
0
        public async Task ExplorationResultIsCorrect(
            CSharpFlowGraphProvider graphProvider,
            IMethodSymbol methodSymbol,
            InvocationExpressionSyntax targetSyntax)
        {
            string assertionName  = ((MemberAccessExpressionSyntax)targetSyntax.Expression).Name.Identifier.Text;
            bool   isAssertion    = assertionName.EndsWith("Assert");
            bool   shouldFindPath = assertionName.Contains("Invalid");

            var methodLocation = new MethodLocation(methodSymbol);
            var flowGraph      = await graphProvider.GetFlowGraphAsync(methodLocation);

            var displayGraph = graphProvider.GetDisplayGraph(flowGraph.Id);

            var displayNode   = displayGraph.Nodes.First(n => n.Span.Contains(targetSyntax.Span));
            var displayRecord = displayNode.Records.Last();
            var startInfo     = new StartingNodeInfo(displayRecord.FlowNode, displayRecord.OperationIndex, isAssertion);
            var options       = new ExplorationOptions()
            {
                FinalNodeRecognizer = new PublicMethodEntryRecognizer(),
                TimeoutSeconds      = 60
            };
            var exploration = new ExplorationContext(graphProvider, new ContextFactory(), startInfo, options);

            // Cancel after the first found path to save time
            bool success      = !shouldFindPath;
            var  cancelSource = new CancellationTokenSource();

            exploration.ExecutionModelsObservable
            .Subscribe(m => { success = shouldFindPath; cancelSource.Cancel(); }, cancelSource.Token);
            bool wasExhaustive = await exploration.ExploreAsync(cancelSource);

            string message = shouldFindPath ? "No path was found" : "A path was found, although it shouldn't have been";

            if (success && !shouldFindPath && !wasExhaustive)
            {
                success = false;
                message = $"No path was found during the {options.TimeoutSeconds} second timeout";
            }

            Assert.IsTrue(success, message);
        }
Exemplo n.º 5
0
        private static ResultRow[] EvaluateProgram(
            CSharpFlowGraphProvider graphProvider,
            string programName,
            IMethodSymbol methodSymbol,
            InvocationExpressionSyntax invocation)
        {
            string assertionName  = ((MemberAccessExpressionSyntax)invocation.Expression).Name.Identifier.Text;
            bool   isAssertion    = assertionName.EndsWith("Assert");
            bool   shouldFindPath = assertionName.Contains("Invalid");

            var methodLocation = new MethodLocation(methodSymbol);
            var flowGraph      = graphProvider.GetFlowGraphAsync(methodLocation).Result;
            var displayGraph   = graphProvider.GetDisplayGraph(flowGraph.Id);

            var displayNode   = displayGraph.Nodes.First(n => n.Span.Contains(invocation.Span));
            var displayRecord = displayNode.Records.Last();
            var startInfo     = new StartingNodeInfo(displayRecord.FlowNode, displayRecord.OperationIndex, isAssertion);
            var options       = new ExplorationOptions()
            {
                FinalNodeRecognizer = new PublicMethodEntryRecognizer(),
                TimeoutSeconds      = 40
            };

            var heuristics = GetHeuristicFactories().ToArray();

            var results = new ResultRow[heuristics.Length * RepeatCount];

            int j = 0;

            foreach ((string heuristicName, var heuristicFactory) in heuristics)
            {
                options.SmtHeuristicFactory = heuristicFactory;

                for (int i = 0; i < RepeatCount; i++)
                {
                    var  stopwatch  = new Stopwatch();
                    long?ticksFirst = null;
                    int? callsFirst = null;

                    var exploration = new ExplorationContext(graphProvider, new ContextFactory(), startInfo, options);
                    exploration.ExecutionModelsObservable
                    .Subscribe(m => { ticksFirst = stopwatch.ElapsedTicks; callsFirst = Explorer.SolverCallCount; });

                    stopwatch.Start();
                    exploration.ExploreAsync().ContinueWith(t => stopwatch.Stop()).Wait();
                    long ticksTotal = stopwatch.ElapsedTicks;

                    results[j * RepeatCount + i] = new ResultRow
                    {
                        Heuristic = heuristicName,
                        Program   = programName,
                        FirstCounterexampleTime  = ticksFirst / (double)Stopwatch.Frequency,
                        FirstCounterexampleCalls = callsFirst,
                        TotalTime  = ticksTotal / (double)Stopwatch.Frequency,
                        TotalCalls = Explorer.SolverCallCount
                    };
                }

                j++;
            }

            return(results);
        }
Exemplo n.º 6
0
        static void Main(string[] args)
        {
            MSBuildLocator.RegisterDefaults();

            var workspace     = MSBuildWorkspace.Create();
            var project       = workspace.OpenProjectAsync(InputsProject).Result;
            var graphProvider = new CSharpFlowGraphProvider(workspace.CurrentSolution);
            var results       = new List <ResultRow[]>();

            foreach (var doc in project.Documents)
            {
                var           syntaxTree    = doc.GetSyntaxTreeAsync().Result;
                SemanticModel semanticModel = null;

                var attributesEnumerable = syntaxTree.GetRoot().DescendantNodes()
                                           .Where(n => n.IsKind(SyntaxKind.Attribute));
                foreach (AttributeSyntax attr in attributesEnumerable)
                {
                    if (semanticModel == null)
                    {
                        semanticModel = doc.GetSemanticModelAsync().Result;
                    }

                    var attrInfo = semanticModel.GetSymbolInfo(attr);
                    if (attrInfo.Symbol?.ContainingType?.Name != AttributeName)
                    {
                        continue;
                    }

                    var programName = semanticModel.GetConstantValue(attr.ArgumentList.Arguments.First().Expression).ToString();

                    var methodDeclaration = (BaseMethodDeclarationSyntax)attr.FirstAncestorOrSelf <MethodDeclarationSyntax>()
                                            ?? attr.FirstAncestorOrSelf <ConstructorDeclarationSyntax>();
                    var methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration);
                    if (methodSymbol == null)
                    {
                        continue;
                    }

                    var invocationsEnumerable = methodDeclaration.DescendantNodes()
                                                .Where(n => n.IsKind(SyntaxKind.InvocationExpression));
                    foreach (InvocationExpressionSyntax invocation in invocationsEnumerable)
                    {
                        if (invocation.Expression.IsKind(SyntaxKind.SimpleMemberAccessExpression))
                        {
                            string methodName = ((MemberAccessExpressionSyntax)invocation.Expression).Name.Identifier.Text;
                            if (IsEvaluationMethodName(methodName))
                            {
                                var resultSet = EvaluateProgram(graphProvider, programName, methodSymbol, invocation);
                                results.Add(resultSet);
                            }
                        }
                    }
                }
            }

            using (var writer = new StreamWriter("results.csv"))
            {
                writer.WriteLine(ResultRow.Header);
                foreach (var set in results)
                {
                    foreach (var row in set)
                    {
                        writer.WriteLine(row);
                    }
                }
            }
        }