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); }
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); }