Esempio n. 1
0
        /// <summary>
        /// Constructs a reproducable trace.
        /// </summary>
        /// <param name="runtime">BugFindingRuntime</param>
        /// <param name="logger">InMemoryLogger</param>
        private void ConstructReproducableTrace(BugFindingRuntime runtime, InMemoryLogger logger)
        {
            this.ReadableTrace  = logger.ToString();
            this.ReadableTrace += this.TestReport.GetText(base.Configuration, "<StrategyLog>");
            this.BugTrace       = runtime.BugTrace;

            StringBuilder stringBuilder = new StringBuilder();

            if (this.Strategy.IsFair())
            {
                stringBuilder.Append("--fair-scheduling").Append(Environment.NewLine);
            }

            if (base.Configuration.CacheProgramState)
            {
                stringBuilder.Append("--state-caching").Append(Environment.NewLine);
                stringBuilder.Append("--liveness-temperature-threshold:" +
                                     base.Configuration.LivenessTemperatureThreshold).
                Append(Environment.NewLine);
            }
            else
            {
                stringBuilder.Append("--liveness-temperature-threshold:" +
                                     base.Configuration.LivenessTemperatureThreshold).
                Append(Environment.NewLine);
            }

            if (!base.Configuration.TestMethodName.Equals(""))
            {
                stringBuilder.Append("--test-method:" +
                                     base.Configuration.TestMethodName).
                Append(Environment.NewLine);
            }

            for (int idx = 0; idx < runtime.ScheduleTrace.Count; idx++)
            {
                ScheduleStep step = runtime.ScheduleTrace[idx];
                if (step.Type == ScheduleStepType.SchedulingChoice)
                {
                    stringBuilder.Append($"{step.ScheduledMachineId.Type}" +
                                         $"({step.ScheduledMachineId.Value})");
                }
                else if (step.BooleanChoice != null)
                {
                    stringBuilder.Append(step.BooleanChoice.Value);
                }
                else
                {
                    stringBuilder.Append(step.IntegerChoice.Value);
                }

                if (idx < runtime.ScheduleTrace.Count - 1)
                {
                    stringBuilder.Append(Environment.NewLine);
                }
            }

            this.ReproducableTrace = stringBuilder.ToString();
        }
Esempio n. 2
0
 private void MenuItem_Open_Trace_Click(object sender, RoutedEventArgs e)
 {
     this.BugTrace = IO.LoadTrace();
     if (this.BugTrace != null)
     {
         this.ObservableBugTrace       = this.GetObservableTrace();
         this.BugTraceView.ItemsSource = this.ObservableBugTrace;
         this.BugTraceView.Items.Refresh();
     }
 }
Esempio n. 3
0
        /// <summary>
        /// Returns the specified trace.
        /// </summary>
        /// <returns>MachineActionTrace</returns>
        internal static BugTrace LoadTrace()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();

            // Sets filter for file extension and default file extension.
            openFileDialog.DefaultExt = ".pstrace";
            openFileDialog.Filter     = "P# Trace Files|*.pstrace";

            // Displays OpenFileDialog by calling the ShowDialog method.
            bool?result = openFileDialog.ShowDialog();

            BugTrace trace = null;

            if (result == true)
            {
                string fileName = openFileDialog.FileName;
                if (fileName != null)
                {
                    using (Stream stream = File.Open(fileName, FileMode.Open))
                    {
                        DataContractSerializer serializer = new DataContractSerializer(typeof(BugTrace));
                        try
                        {
                            trace = (BugTrace)serializer.ReadObject(stream);
                        }
                        catch
                        {
                            MessageBox.Show($"Bug trace '{fileName}' is not readable." +
                                            "Please make sure you selected a '.pstrace' file.");
                        }
                    }
                }
            }

            return(trace);
        }
Esempio n. 4
0
        /// <summary>
        /// Runs the next testing iteration.
        /// </summary>
        /// <param name="iteration">Iteration</param>
        private void RunNextIteration(int iteration)
        {
            if (this.ShouldPrintIteration(iteration + 1))
            {
                base.Logger.WriteLine($"..... Iteration #{iteration + 1}");
            }

            // Runtime used to serialize and test the program in this iteration.
            BugFindingRuntime runtime = null;

            // Logger used to intercept the program output if no custom logger
            // is installed and if verbosity is turned off.
            InMemoryLogger runtimeLogger = null;

            // Gets a handle to the standard output and error streams.
            var stdOut = Console.Out;
            var stdErr = Console.Error;

            try
            {
                // Creates a new instance of the bug-finding runtime.
                runtime = new BugFindingRuntime(base.Configuration, base.Strategy, base.Reporter);

                if (base.Configuration.EnableDataRaceDetection)
                {
                    // Create a reporter to monitor interesting operations for race detection
                    this.Reporter.SetRuntime(runtime);
                }

                // If verbosity is turned off, then intercept the program log, and also dispose
                // the standard output and error streams.
                if (base.Configuration.Verbose < 2)
                {
                    runtimeLogger = new InMemoryLogger();
                    runtime.SetLogger(runtimeLogger);

                    // Sets the scheduling strategy logger to the in-memory logger.
                    base.SchedulingStrategyLogger.SetLogger(runtimeLogger);

                    var writer = new LogWriter(new DisposingLogger());
                    Console.SetOut(writer);
                    Console.SetError(writer);
                }

                // Runs the test inside the P# test-harness machine.
                runtime.RunTestHarness(base.TestMethod, base.TestAction);

                // Wait for the test to terminate.
                runtime.Wait();

                if (runtime.Scheduler.BugFound)
                {
                    base.ErrorReporter.WriteErrorLine(runtime.Scheduler.BugReport);
                }

                // Invokes user-provided cleanup for this iteration.
                if (base.TestIterationDisposeMethod != null)
                {
                    // Disposes the test state.
                    base.TestIterationDisposeMethod.Invoke(null, null);
                }

                // Invoke the per iteration callbacks, if any.
                foreach (var callback in base.PerIterationCallbacks)
                {
                    callback(iteration);
                }

                if (base.Configuration.RaceFound)
                {
                    string message = IO.Utilities.Format("Found a race");
                    runtime.Scheduler.NotifyAssertionFailure(message, false);
                    foreach (var report in this.TestReport.BugReports)
                    {
                        runtime.Logger.WriteLine(report);
                    }
                }

                // Checks that no monitor is in a hot state at termination. Only
                // checked if no safety property violations have been found.
                if (!runtime.Scheduler.BugFound)
                {
                    runtime.AssertNoMonitorInHotStateAtTermination();
                }

                this.GatherIterationStatistics(runtime);

                if (base.TestReport.NumOfFoundBugs > 0)
                {
                    if (runtimeLogger != null)
                    {
                        this.ReadableTrace  = runtimeLogger.ToString();
                        this.ReadableTrace += this.TestReport.GetText(base.Configuration, "<StrategyLog>");
                    }

                    this.BugTrace = runtime.BugTrace;
                    this.ConstructReproducableTrace(runtime);
                }
            }
            finally
            {
                if (base.Configuration.Verbose < 2)
                {
                    // Restores the standard output and error streams.
                    Console.SetOut(stdOut);
                    Console.SetError(stdErr);
                }

                if (base.Configuration.PerformFullExploration && runtime.Scheduler.BugFound)
                {
                    base.Logger.WriteLine($"..... Iteration #{iteration + 1} " +
                                          $"triggered bug #{base.TestReport.NumOfFoundBugs} " +
                                          $"[task-{this.Configuration.TestingProcessId}]");
                }

                // Resets the scheduling strategy logger to the default logger.
                base.SchedulingStrategyLogger.ResetToDefaultLogger();

                // Cleans up the runtime before the next iteration starts.
                runtimeLogger?.Dispose();
                runtime?.Dispose();
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Runs the next testing iteration.
        /// </summary>
        private void RunNextIteration(int iteration)
        {
            if (this.ShouldPrintIteration(iteration + 1))
            {
                this.Logger.WriteLine($"..... Iteration #{iteration + 1}");

                // Flush when logging to console.
                if (this.Logger is ConsoleLogger)
                {
                    Console.Out.Flush();
                }
            }

            // Runtime used to serialize and test the program in this iteration.
            SystematicTestingRuntime runtime = null;

            // Logger used to intercept the program output if no custom logger
            // is installed and if verbosity is turned off.
            InMemoryLogger runtimeLogger = null;

            // Gets a handle to the standard output and error streams.
            var stdOut = Console.Out;
            var stdErr = Console.Error;

            try
            {
                // Creates a new instance of the bug-finding runtime.
                if (this.TestRuntimeFactoryMethod != null)
                {
                    runtime = (SystematicTestingRuntime)this.TestRuntimeFactoryMethod.Invoke(
                        null,
                        new object[] { this.Configuration, this.Strategy, this.Reporter });
                }
                else
                {
                    runtime = new SystematicTestingRuntime(this.Configuration, this.Strategy, this.Reporter);
                }

                if (this.Configuration.EnableDataRaceDetection)
                {
                    this.Reporter.RegisterRuntime(runtime);
                }

                // If verbosity is turned off, then intercept the program log, and also dispose
                // the standard output and error streams.
                if (!this.Configuration.IsVerbose)
                {
                    runtimeLogger = new InMemoryLogger(true);
                    runtime.SetLogger(runtimeLogger);

                    var writer = new LogWriter(new DisposingLogger());
                    Console.SetOut(writer);
                    Console.SetError(writer);
                }

                // Runs the test inside the test-harness machine.
                if (this.TestAction != null)
                {
                    runtime.RunTestHarness(this.TestAction, this.TestName);
                }
                else
                {
                    runtime.RunTestHarness(this.TestFunction, this.TestName);
                }

                // Wait for the test to terminate.
                runtime.WaitAsync().Wait();

                // Invokes user-provided cleanup for this iteration.
                if (this.TestIterationDisposeMethod != null)
                {
                    // Disposes the test state.
                    this.TestIterationDisposeMethod.Invoke(null, null);
                }

                // Invoke the per iteration callbacks, if any.
                foreach (var callback in this.PerIterationCallbacks)
                {
                    callback(iteration);
                }

                if (this.Configuration.RaceFound)
                {
                    runtime.Scheduler.NotifyAssertionFailure("Found a race", killTasks: false, cancelExecution: false);
                    foreach (var report in this.TestReport.BugReports)
                    {
                        runtime.Logger.WriteLine(report);
                    }
                }

                // Checks that no monitor is in a hot state at termination. Only
                // checked if no safety property violations have been found.
                if (!runtime.Scheduler.BugFound)
                {
                    runtime.CheckNoMonitorInHotStateAtTermination();
                }

                if (runtime.Scheduler.BugFound)
                {
                    this.ErrorReporter.WriteErrorLine(runtime.Scheduler.BugReport);
                }

                this.GatherIterationStatistics(runtime);

                if (this.TestReport.NumOfFoundBugs > 0)
                {
                    if (runtimeLogger != null)
                    {
                        this.ReadableTrace  = runtimeLogger.ToString();
                        this.ReadableTrace += this.TestReport.GetText(this.Configuration, "<StrategyLog>");
                    }

                    this.BugTrace = runtime.BugTrace;
                    this.ConstructReproducableTrace(runtime);
                }
            }
            finally
            {
                if (!this.Configuration.IsVerbose)
                {
                    // Restores the standard output and error streams.
                    Console.SetOut(stdOut);
                    Console.SetError(stdErr);
                }

                if (this.Configuration.PerformFullExploration && runtime.Scheduler.BugFound)
                {
                    this.Logger.WriteLine($"..... Iteration #{iteration + 1} " +
                                          $"triggered bug #{this.TestReport.NumOfFoundBugs} " +
                                          $"[task-{this.Configuration.TestingProcessId}]");
                }

                // Cleans up the runtime before the next iteration starts.
                runtimeLogger?.Dispose();
                runtime?.Dispose();
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Creates a new bug-finding task.
        /// </summary>
        /// <returns>Task</returns>
        private Task CreateBugFindingTask()
        {
            if (base.Configuration.TestingProcessId >= 0)
            {
                IO.Error.PrintLine($"... Task {this.Configuration.TestingProcessId} is " +
                                   $"using '{base.Configuration.SchedulingStrategy}' strategy.");
            }
            else
            {
                IO.PrintLine($"... Using '{base.Configuration.SchedulingStrategy}' strategy.");
            }

            Task task = new Task(() =>
            {
                try
                {
                    if (base.TestInitMethod != null)
                    {
                        // Initializes the test state.
                        base.TestInitMethod.Invoke(null, new object[] { });
                    }
                }
                catch (TargetInvocationException ex)
                {
                    if (!(ex.InnerException is TaskCanceledException))
                    {
                        ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                    }
                }

                int maxIterations = base.Configuration.SchedulingIterations;
                for (int i = 0; i < maxIterations; i++)
                {
                    if (this.CancellationTokenSource.IsCancellationRequested)
                    {
                        break;
                    }

                    if (this.ShouldPrintIteration(i + 1))
                    {
                        IO.PrintLine($"..... Iteration #{i + 1}");
                    }

                    var runtime = new PSharpBugFindingRuntime(base.Configuration,
                                                              base.Strategy, base.TestReport.CoverageInfo);

                    StringWriter sw = null;
                    if (base.Configuration.RedirectTestConsoleOutput &&
                        base.Configuration.Verbose < 2)
                    {
                        sw = base.RedirectConsoleOutput();
                        base.HasRedirectedConsoleOutput = true;
                    }

                    // Starts the test.
                    if (base.TestAction != null)
                    {
                        base.TestAction(runtime);
                    }
                    else
                    {
                        try
                        {
                            base.TestMethod.Invoke(null, new object[] { runtime });
                        }
                        catch (TargetInvocationException ex)
                        {
                            if (!(ex.InnerException is TaskCanceledException))
                            {
                                ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                            }
                        }
                    }

                    // Wait for the test to terminate.
                    runtime.Wait();

                    if (this.Configuration.EnableDataRaceDetection)
                    {
                        this.EmitRaceInstrumentationTraces(runtime, i);
                    }

                    try
                    {
                        // Invokes user-provided cleanup for this iteration.
                        if (base.TestIterationDisposeMethod != null)
                        {
                            // Disposes the test state.
                            base.TestIterationDisposeMethod.Invoke(null, null);
                        }
                    }
                    catch (TargetInvocationException ex)
                    {
                        if (!(ex.InnerException is TaskCanceledException))
                        {
                            ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                        }
                    }

                    // Invoke the per iteration callbacks, if any.
                    foreach (var callback in base.PerIterationCallbacks)
                    {
                        callback(i);
                    }

                    // Cleans up the runtime before the next
                    // iteration starts.
                    this.CleanUpRuntime();

                    // Checks for any liveness property violations. Requires
                    // that the program has terminated and no safety property
                    // violations have been found.
                    if (!runtime.BugFinder.BugFound)
                    {
                        runtime.LivenessChecker.CheckLivenessAtTermination();
                    }

                    if (base.HasRedirectedConsoleOutput)
                    {
                        base.ResetOutput();
                    }

                    this.GatherIterationStatistics(runtime);

                    if (runtime.BugFinder.BugFound)
                    {
                        base.TestReport.NumOfFoundBugs++;
                        base.TestReport.BugReport = runtime.BugFinder.BugReport;

                        if (base.Configuration.PerformFullExploration)
                        {
                            IO.PrintLine($"..... Iteration #{i + 1} triggered " +
                                         $"bug #{base.TestReport.NumOfFoundBugs}");
                        }
                    }
                    else
                    {
                        base.TestReport.BugReport = "";
                    }

                    if (base.Strategy.HasFinished())
                    {
                        break;
                    }

                    base.Strategy.ConfigureNextIteration();

                    if (!base.Configuration.PerformFullExploration && base.TestReport.NumOfFoundBugs > 0)
                    {
                        if (sw != null && !base.Configuration.SuppressTrace)
                        {
                            this.ReadableTrace  = sw.ToString();
                            this.ReadableTrace += this.CreateReport("<StrategyLog>");
                            this.BugTrace       = runtime.BugTrace;
                            this.ConstructReproducableTrace(runtime);
                        }

                        break;
                    }
                    else if (sw != null && base.Configuration.PrintTrace)
                    {
                        this.ReadableTrace  = sw.ToString();
                        this.ReadableTrace += this.CreateReport("<StrategyLog>");
                        this.BugTrace       = runtime.BugTrace;
                        this.ConstructReproducableTrace(runtime);
                    }

                    // Increases iterations if there is a specified timeout
                    // and the default iteration given.
                    if (base.Configuration.SchedulingIterations == 1 &&
                        base.Configuration.Timeout > 0)
                    {
                        maxIterations++;
                    }

                    runtime.Dispose();
                }

                try
                {
                    if (base.TestDisposeMethod != null)
                    {
                        // Disposes the test state.
                        base.TestDisposeMethod.Invoke(null, new object[] { });
                    }
                }
                catch (TargetInvocationException ex)
                {
                    if (!(ex.InnerException is TaskCanceledException))
                    {
                        ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                    }
                }
            }, base.CancellationTokenSource.Token);

            return(task);
        }
Esempio n. 7
0
 private void MenuItem_Open_Trace_Click(object sender, RoutedEventArgs e)
 {
     this.BugTrace = IO.LoadTrace();
     if (this.BugTrace != null)
     {
         this.ObservableBugTrace = this.GetObservableTrace();
         this.BugTraceView.ItemsSource = this.ObservableBugTrace;
         this.BugTraceView.Items.Refresh();
     }
 }
Esempio n. 8
0
        /// <summary>
        /// Creates a new bug-finding task.
        /// </summary>
        /// <returns>Task</returns>
        private Task CreateBugFindingTask()
        {
            if (base.Configuration.TestingProcessId >= 0)
            {
                IO.Error.PrintLine($"... Task {this.Configuration.TestingProcessId} is " +
                    $"using '{base.Configuration.SchedulingStrategy}' strategy.");
            }
            else
            {
                IO.PrintLine($"... Using '{base.Configuration.SchedulingStrategy}' strategy.");
            }

            Task task = new Task(() =>
            {
                try
                {
                    if (base.TestInitMethod != null)
                    {
                        // Initializes the test state.
                        base.TestInitMethod.Invoke(null, new object[] { });
                    }
                }
                catch (TargetInvocationException ex)
                {
                    if (!(ex.InnerException is TaskCanceledException))
                    {
                        ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                    }
                }

                int maxIterations = base.Configuration.SchedulingIterations;
                for (int i = 0; i < maxIterations; i++)
                {
                    if (this.CancellationTokenSource.IsCancellationRequested)
                    {
                        break;
                    }

                    if (this.ShouldPrintIteration(i + 1))
                    {
                        IO.PrintLine($"..... Iteration #{i + 1}");
                    }

                    var runtime = new PSharpBugFindingRuntime(base.Configuration,
                        base.Strategy, base.Visualizer);

                    StringWriter sw = null;
                    if (base.Configuration.RedirectTestConsoleOutput &&
                        base.Configuration.Verbose < 2)
                    {
                        sw = base.RedirectConsoleOutput();
                        base.HasRedirectedConsoleOutput = true;
                    }

                    // Starts the test.
                    if (base.TestAction != null)
                    {
                        base.TestAction(runtime);
                    }
                    else
                    {
                        try
                        {
                            base.TestMethod.Invoke(null, new object[] { runtime });
                        }
                        catch (TargetInvocationException ex)
                        {
                            if (!(ex.InnerException is TaskCanceledException))
                            {
                                ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                            }
                        }
                    }

                    // Wait for test to terminate.
                    runtime.Wait();

                    if (base.Configuration.EnableVisualization)
                    {
                        base.Visualizer.Refresh();
                    }

                    if (this.Configuration.EnableDataRaceDetection)
                    {
                        this.EmitRaceInstrumentationTraces(runtime, i);
                    }

                    try
                    {
                        // Invokes user-provided cleanup for this iteration.
                        if (base.TestIterationDisposeMethod != null)
                        {
                            // Disposes the test state.
                            base.TestIterationDisposeMethod.Invoke(null, null);
                        }
                    }
                    catch (TargetInvocationException ex)
                    {
                        if (!(ex.InnerException is TaskCanceledException))
                        {
                            ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                        }
                    }

                    // Invoke the per iteration callbacks, if any.
                    foreach (var callback in base.PerIterationCallbacks)
                    {
                        callback(i);
                    }

                    // Cleans up the runtime before the next
                    // iteration starts.
                    this.CleanUpRuntime();

                    // Checks for any liveness property violations. Requires
                    // that the program has terminated and no safety property
                    // violations have been found.
                    if (!runtime.BugFinder.BugFound)
                    {
                        runtime.LivenessChecker.CheckLivenessAtTermination();
                    }

                    if (base.HasRedirectedConsoleOutput)
                    {
                        base.ResetOutput();
                    }

                    this.ExploredSchedules++;
                    base.ExploredDepth = runtime.BugFinder.ExploredSteps;

                    if (base.Strategy.HasReachedMaxSchedulingSteps())
                    {
                        this.MaxStepsHit++;
                    }

                    if (runtime.BugFinder.BugFound)
                    {
                        base.NumOfFoundBugs++;
                        base.BugReport = runtime.BugFinder.BugReport;

                        if (base.Configuration.PerformFullExploration)
                        {
                            IO.PrintLine($"..... Iteration #{i + 1} triggered " +
                                $"bug #{base.NumOfFoundBugs}");
                        }
                    }
                    else
                    {
                        base.BugReport = "";
                    }

                    if (base.Strategy.HasFinished())
                    {
                        break;
                    }

                    base.Strategy.ConfigureNextIteration();

                    if (!base.Configuration.PerformFullExploration && base.NumOfFoundBugs > 0)
                    {
                        if (sw != null && !base.Configuration.SuppressTrace)
                        {
                            this.ReadableTrace = sw.ToString();
                            this.ReadableTrace += this.CreateReport("<StrategyLog>");
                            this.BugTrace = runtime.BugTrace;
                            this.ConstructReproducableTrace(runtime);
                        }

                        break;
                    }
                    else if (sw != null && base.Configuration.PrintTrace)
                    {
                        this.ReadableTrace = sw.ToString();
                        this.ReadableTrace += this.CreateReport("<StrategyLog>");
                        this.BugTrace = runtime.BugTrace;
                        this.ConstructReproducableTrace(runtime);
                    }

                    // Increases iterations if there is a specified timeout
                    // and the default iteration given.
                    if (base.Configuration.SchedulingIterations == 1 &&
                        base.Configuration.Timeout > 0)
                    {
                        maxIterations++;
                    }

                    runtime.Dispose();
                }

                try
                {
                    if (base.TestDisposeMethod != null)
                    {
                        // Disposes the test state.
                        base.TestDisposeMethod.Invoke(null, new object[] { });
                    }
                }
                catch (TargetInvocationException ex)
                {
                    if (!(ex.InnerException is TaskCanceledException))
                    {
                        ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                    }
                }

            }, base.CancellationTokenSource.Token);

            return task;
        }