예제 #1
0
        /// <summary>
        /// Pretty prints the path condition of the given execution node.
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        private string PrettyPrintPathCondition(IExecutionNode node)
        {
            string output = "";

            try
            {
                if (node.GetPathCondition().Conjuncts.Count != 0)
                {
                    TermEmitter       termEmitter      = new TermEmitter(pathComponent.GetService <TermManager>());
                    SafeStringWriter  safeStringWriter = new SafeStringWriter();
                    IMethodBodyWriter methodBodyWriter = pathComponent.GetService <IPexTestManager>().Language.CreateBodyWriter(safeStringWriter, VisibilityContext.Private, 2000);
                    if (termEmitter.TryEvaluate(node.GetPathCondition().Conjuncts, 2000, methodBodyWriter))
                    {
                        for (int i = 0; i < node.GetPathCondition().Conjuncts.Count - 1; i++)
                        {
                            methodBodyWriter.ShortCircuitAnd();
                        }

                        methodBodyWriter.Statement();

                        output = safeStringWriter.ToString().Remove(safeStringWriter.ToString().Count() - 3);
                    }
                }
            }
            catch (Exception e)
            {
                // TODO : Exception handling?
            }
            return(output);
        }
        private static string prettyPrintPathCondition(IPexPathComponent host, Term[] pathConditions)
        {
            var writer     = new SafeStringWriter();
            var codeWriter = host.Services.TestManager.Language.CreateBodyWriter(
                writer,
                VisibilityContext.Private,
                100);
            var emitter = new TermEmitter(
                host.ExplorationServices.TermManager,
                new NameCreator());

            for (int i = pathConditions.Length - 1; i >= 0; i--)
            {
                var pathCondition = pathConditions[i];
                if (!emitter.TryEvaluate(
                        new Term[] { pathCondition },
                        10000,  // bound on size of expression we are going to pretty-print
                        codeWriter))
                {
                    writer.WriteLine("(expression too big; consider using environment variable {0})",
                                     ExtendedReflectionEnvironmentSettings.NoCodeEmitterSizeLimit.Name);
                }
                else
                {
                    writer.WriteLine("path condition: " + pathCondition.GetType());
                    codeWriter.Return(SystemTypes.Bool);
                }
            }
            return(writer.ToString());
        }
예제 #3
0
        private static string prettyPrintTerm(IPexExplorationComponent host, Term term, TypeEx type)
        {
            var writer     = new SafeStringWriter();
            var codeWriter = host.Services.TestManager.Language.CreateBodyWriter(
                writer,
                VisibilityContext.Private,
                100);
            var emitter = new TermEmitter(
                host.ExplorationServices.TermManager,
                new NameCreator());

            if (!emitter.TryEvaluate(
                    new Term[] { term },
                    10000, // bound on size of expression we are going to pretty-print
                    codeWriter))
            {
                writer.WriteLine("(expression too big; consider using environment variable {0})",
                                 ExtendedReflectionEnvironmentSettings.NoCodeEmitterSizeLimit.Name);
            }
            else
            {
                codeWriter.Return(type);
            }
            return(writer.ToString());
        }
 private static string prettyPrintPathCondition(IPexPathComponent host, Term[] pathConditions)
 {
     var writer = new SafeStringWriter();
     var codeWriter = host.Services.TestManager.Language.CreateBodyWriter(
         writer,
         VisibilityContext.Private,
         100);
     var emitter = new TermEmitter(
         host.ExplorationServices.TermManager,
         new NameCreator());
     for (int i = pathConditions.Length - 1; i >= 0; i--)
     {
         var pathCondition = pathConditions[i];
         if (!emitter.TryEvaluate(
                  new Term[] {pathCondition},
                  10000, // bound on size of expression we are going to pretty-print
                  codeWriter))
         {
             writer.WriteLine("(expression too big; consider using environment variable {0})",
                              ExtendedReflectionEnvironmentSettings.NoCodeEmitterSizeLimit.Name);
         }
         else
         {
             writer.WriteLine("path condition: " + pathCondition.GetType());
             codeWriter.Return(SystemTypes.Bool);
         }
     }
     return writer.ToString();
 }
예제 #5
0
        /// <summary>
        /// Pretty prints the path condition of the execution node.
        /// </summary>
        /// <param name="host">Host of the Pex Path Component</param>
        /// <param name="node">The execution node to map</param>
        /// <returns>The pretty printed path condition string</returns>
        private Task <string> PrettyPrintPathCondition(TermEmitter emitter, IMethodBodyWriter mbw, SafeStringWriter ssw, IExecutionNode node)
        {
            MessageBox.Show("PrettyPrintPathCondition()");
            var task = Task.Factory.StartNew(() =>
            {
                string output = "";
                try
                {
                    if (node.GetPathCondition().Conjuncts.Count != 0)
                    {
                        if (emitter.TryEvaluate(node.GetPathCondition().Conjuncts, 2000, mbw)) // TODO Perf leak
                        {
                            for (int i = 0; i < node.GetPathCondition().Conjuncts.Count - 1; i++)
                            {
                                mbw.ShortCircuitAnd();
                            }

                            mbw.Statement();
                            var safeString = ssw.ToString();
                            output         = safeString.Remove(ssw.Length - 3);
                        }
                    }
                }
                catch (Exception) { }
                return(output);
            });

            return(task);
        }
예제 #6
0
        public void AfterRun(IPexPathComponent host, object data)
        {
            MessageBox.Show("AfterRun");

            // Getting the executions nodes in the current path
            var nodesInPath = host.PathServices.CurrentExecutionNodeProvider.ReversedNodes.Reverse().ToArray();

            // Getting the sequence id of the current run
            var runId = host.ExplorationServices.Driver.Runs;

            // Iterating over the nodes in the path
            foreach (var node in nodesInPath)
            {
                var vertex = new CFGNode(node.UniqueIndex, false);

                // Adding the method name this early in order to color edges
                string methodName = null;
                int    offset     = 0;
                if (node.CodeLocation.Method == null)
                {
                    if (node.InCodeBranch.Method != null)
                    {
                        methodName = node.InCodeBranch.Method.FullName;
                    }
                }
                else
                {
                    methodName = node.CodeLocation.Method.FullName;
                    offset     = node.CodeLocation.Offset;
                }
                // Setting the method name
                vertex.MethodName = methodName;

                // Setting the offset
                vertex.ILOffset = (uint)offset;

                var nodeIndex = nodesInPath.ToList().IndexOf(node);
                if (nodeIndex > 0)
                {
                    var prevNode = nodesInPath [nodeIndex - 1];
                    // If there is no edge between the previous and the current node
                    if (!(Edges.ContainsKey(prevNode.UniqueIndex) && Edges [prevNode.UniqueIndex].ContainsKey(node.UniqueIndex)))
                    {
                        var prevVertex = Vertices [prevNode.UniqueIndex];

                        var edge = new CFGEdge(new Random().Next(), prevVertex, vertex);

                        Dictionary <int, CFGEdge> outEdges = null;
                        if (Edges.TryGetValue(prevNode.UniqueIndex, out outEdges))
                        {
                            outEdges.Add(node.UniqueIndex, edge);
                        }
                        else
                        {
                            Edges.Add(prevNode.UniqueIndex, new Dictionary <int, CFGEdge>());
                            Edges [prevNode.UniqueIndex].Add(node.UniqueIndex, edge);
                        }

                        // Edge coloring based on unit border detection
                        if (UnitNamespace != null)
                        {
                            // Checking if pointing into the unit from outside
                            if (!(prevVertex.MethodName.StartsWith(UnitNamespace + ".") || prevVertex.MethodName.Equals(UnitNamespace)) && (vertex.MethodName.StartsWith(UnitNamespace + ".") || vertex.MethodName.Equals(UnitNamespace)))
                            {
                                edge.Color = CFGEdge.EdgeColor.Green;
                            }

                            // Checking if pointing outside the unit from inside
                            if ((prevVertex.MethodName.StartsWith(UnitNamespace + ".") || prevVertex.MethodName.Equals(UnitNamespace)) && !(vertex.MethodName.StartsWith(UnitNamespace + ".") || vertex.MethodName.Equals(UnitNamespace)))
                            {
                                edge.Color = CFGEdge.EdgeColor.Red;
                            }
                        }
                    }
                }

                // If the node is new then it is added to the list and the metadata is filled
                if (!Vertices.ContainsKey(node.UniqueIndex))
                {
                    Vertices.Add(node.UniqueIndex, vertex);

                    // Adding source code mapping
                    vertex.SourceCodeMappingString = MapToSourceCodeLocationString(host, node);

                    // Setting the border based on mapping existence
                    vertex.Border = vertex.SourceCodeMappingString == null ? CFGNode.NodeBorder.Single : CFGNode.NodeBorder.Double;

                    // Setting the color
                    if (nodesInPath.LastOrDefault() == node)
                    {
                        if (!EmittedTestResult.ContainsKey(runId))
                        {
                            vertex.Color = CFGNode.NodeColor.Orange;
                        }
                        else
                        {
                            if (EmittedTestResult [runId].Item1)
                            {
                                vertex.Color = CFGNode.NodeColor.Red;
                            }
                            else
                            {
                                vertex.Color = CFGNode.NodeColor.Green;
                            }
                            vertex.GenerateTestCode = EmittedTestResult [runId].Item2;
                        }
                    }
                    else
                    {
                        vertex.Color = CFGNode.NodeColor.White;
                    }

                    // Setting the default shape
                    vertex.Shape = CFGNode.NodeShape.Rectangle;

                    // Adding path condition tasks and getting the required services
                    TermEmitter       termEmitter      = new TermEmitter(host.GetService <TermManager>());
                    SafeStringWriter  safeStringWriter = new SafeStringWriter();
                    IMethodBodyWriter methodBodyWriter = host.GetService <IPexTestManager>().Language.CreateBodyWriter(safeStringWriter, VisibilityContext.Private, 2000);
                    PrettyPathConditionTasks.Add(vertex.Id, PrettyPrintPathCondition(termEmitter, methodBodyWriter, safeStringWriter, node));

                    // Setting the status
                    vertex.Status = node.ExhaustedReason.ToString();

                    // Collecting the parent nodes for the later incremental path condition calculation
                    if (nodeIndex > 0)
                    {
                        ParentNodes.Add(vertex.Id, nodesInPath [nodeIndex - 1].UniqueIndex);
                    }
                }

                // Adding the Id of the run
                Vertices [node.UniqueIndex].Runs += (runId + ";");
            }
        }
예제 #7
0
        /// <summary>
        /// Solves a term and computes the actual and expected values of fields. There are various possibilites of the term. The actual
        /// fiels in a condition, returned by this function should be only from one side.
        ///
        /// a. One side of the term is concrete and not symbolic. It is easy to handle this case as one side is concrete
        /// b. Both the sides are symbolic. Pex assigns different values to both the sides, since both are symbolic, but this is not possible
        ///     in the context of ours. So, we treat one side as a concrete and other side as symbolic. We use heuristics in deciding which
        ///     side is concrete and which side is symbolic.
        /// </summary>
        /// <param name="host"></param>
        /// <param name="condition"></param>
        /// <param name="binOp"></param>
        /// <param name="actualFieldValues"></param>
        /// <param name="expectedFieldValues"></param>
        /// <param name="allFieldsInCondition"></param>
        /// <returns></returns>
        public static bool SolveTerm(IPexExplorationComponent host, Term condition, BinaryOperator binOp,
                                     out SafeDictionary <Field, FieldValueHolder> actualFieldValues,
                                     out SafeDictionary <Field, FieldValueHolder> expectedFieldValues,
                                     out SafeList <Field> allFieldsInCondition, out SafeList <TypeEx> allFieldTypes)
        {
            var termManager      = host.ExplorationServices.TermManager;
            var solverFactory    = host.ExplorationServices.SolverFactory;
            var solverStatistics = solverFactory.CreateStatistics();

            actualFieldValues   = new SafeDictionary <Field, FieldValueHolder>();
            expectedFieldValues = new SafeDictionary <Field, FieldValueHolder>();
            allFieldTypes       = new SafeList <TypeEx>();

            //Simplifies term based on the contents within the term. gathering a simplied form of condition
            condition = SimplifyTerm(host, termManager, condition);

            allFieldsInCondition = new SafeList <Field>();
            var variables = VariablesCollector.Collect(termManager, condition,
                                                       actualFieldValues, allFieldsInCondition, allFieldTypes);

            using (var solver = solverFactory.CreateSolver(solverStatistics))
            {
                var writer = new SafeStringWriter();
                foreach (var symbolIdWithType in variables)
                {
                    writer.WriteLine("variable: {0}", symbolIdWithType.Description);
                    solver.AddDomainVariable(0, symbolIdWithType);
                }
                writer.WriteLine("condition: {0}", prettyPrintTerm(host, condition, SystemTypes.Bool));

                solver.Assert("is satisfiable check", condition);
                IModel model;
                var    result = solver.TryGetModel(null, out model);
                writer.WriteLine("TryGetModel => {0}", result);
                if (result == TryGetModelResult.Success)
                {
                    foreach (var symbolIdWithType in variables)
                    {
                        writer.Write("{0} => ", symbolIdWithType.Description);
                        var variable = termManager.Symbol(symbolIdWithType);
                        var value    = model.GetValue(variable);
                        writer.WriteLine(prettyPrintTerm(host, value, symbolIdWithType.Type));

                        TypeEx type;

                        if (symbolIdWithType.Layout.Kind == LayoutKind.Ref &&
                            termManager.TryGetObjectType(value, out type) &&
                            type != SystemTypes.Null)
                        {
                            foreach (var field in type.InstanceFields)
                            {
                                var fieldVariable = termManager.SelectInstanceFieldInInitialState(variable, field);
                                var fieldValue    = model.GetValue(fieldVariable);

                                writer.Write("{0}.{1} => ", symbolIdWithType.Description, field.ShortName);
                                writer.WriteLine(prettyPrintTerm(host, fieldValue, field.Type));

                                TypeEx fieldValueType;
                                if (termManager.TryGetObjectType(fieldValue, out fieldValueType)) // is this an object, and if so, what’s its type?
                                {
                                    // do the same thing are before for the nested fields
                                    foreach (var nestedField in field.Type.InstanceFields)
                                    {
                                        var nestedFieldVariable = termManager.SelectInstanceFieldInInitialState(fieldValue, nestedField);
                                        var nestedFieldValue    = model.GetValue(nestedFieldVariable);
                                        writer.Write("{0}.{1}.{2} => ", symbolIdWithType.Description, field.ShortName, nestedField.ShortName);
                                        writer.WriteLine(prettyPrintTerm(host, nestedFieldValue, nestedField.Type));
                                    }
                                }

                                //stores the field value into expected field values
                                StoreFieldValue(termManager, field, fieldValue, expectedFieldValues, actualFieldValues, allFieldsInCondition, host, condition, binOp);
                            }
                        }
                    }
                }
                if (model != null)
                {
                    model.Dispose();
                }

                host.Log.Dump("Satisfiable Checker", "TermSolver", writer.ToString());
            }

            return(true);
        }