예제 #1
0
        private static void ConstructControlFlowGraph(Solution solution, MethodLocation method)
        {
            var flowGraphProvider = new CSharpFlowGraphProvider(solution);
            var result            = flowGraphProvider.GetFlowGraphAsync(method).Result;

            Assert.AreNotEqual(null, result);
        }
예제 #2
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;
                }
            }
        }
예제 #3
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);
        }
예제 #4
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);
        }