示例#1
0
        public void TestWildcardEventAction()
        {
            var test = @"
namespace Foo {
machine M {
start state S
{
on *,e1.e2 goto S2;
on * push S2;
}
}
}";

            var configuration = Configuration.Create();

            configuration.Verbose = 2;

            var context = CompilationContext.Create(configuration).LoadSolution(test);

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree();

            var expected = @"
using Microsoft.PSharp;
namespace Foo
{
class M : Machine
{
[Microsoft.PSharp.Start]
[OnEventGotoState(typeof(Microsoft.PSharp.WildCardEvent), typeof(S2))]
[OnEventGotoState(typeof(e1.e2), typeof(S2))]
[OnEventPushState(typeof(Microsoft.PSharp.WildCardEvent), typeof(S2))]
class S : MachineState
{
}
}
}";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty),
                            syntaxTree.ToString().Replace("\n", string.Empty));
        }
示例#2
0
        public void TestMonitorStateGroupDeclaration()
        {
            var test = @"
namespace Foo {
monitor M {
start state S1 { }
group G { state S2 { } }
}
}";

            var configuration = Configuration.Create();

            configuration.Verbose = 2;

            var context = CompilationContext.Create(configuration).LoadSolution(test);

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree();

            var expected = @"
using Microsoft.PSharp;
namespace Foo
{
class M : Monitor
{
[Microsoft.PSharp.Start]
class S1 : MonitorState
{
}
class G : StateGroup
{
public class S2 : MonitorState
{
}
}
}
}";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty),
                            syntaxTree.ToString().Replace("\n", string.Empty));
        }
示例#3
0
        public void TestEntryDeclaration()
        {
            var test = @"
namespace Foo {
machine M {
start state S
{
entry{}
}
}
}";

            var configuration = Configuration.Create();

            configuration.Verbose = 2;

            var context = CompilationContext.Create(configuration).LoadSolution(test);

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree();

            var expected = @"
using Microsoft.PSharp;
namespace Foo
{
class M : Machine
{
[Microsoft.PSharp.Start]
[OnEntry(nameof(psharp_S_on_entry_action))]
class S : MachineState
{
}
protected void psharp_S_on_entry_action()
{
}
}
}";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty),
                            syntaxTree.ToString().Replace("\n", string.Empty));
        }
示例#4
0
        public void TestOnComplexGenericEventGotoStateDeclarationWithBody()
        {
            var test = @"
namespace Foo {
machine M {
start state S1
{
on e<List<Tuple<bool, object>>, Dictionary<string, float>> goto S2 with {}
}
}
}";

            var configuration = Configuration.Create();

            configuration.Verbose = 2;

            var context = CompilationContext.Create(configuration).LoadSolution(test);

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree();

            var expected = @"
using Microsoft.PSharp;
namespace Foo
{
class M : Machine
{
[Microsoft.PSharp.Start]
[OnEventGotoState(typeof(e<List<Tuple<bool,object>>,Dictionary<string,float>>), typeof(S2), nameof(psharp_S1_e_type_0_action))]
class S1 : MachineState
{
}
protected void psharp_S1_e_type_0_action()
{
}
}
}";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty),
                            syntaxTree.ToString().Replace("\n", string.Empty));
        }
示例#5
0
        public void TestOnEventDoActionDeclaration2()
        {
            var test = @"
namespace Foo {
machine M {
start state S1
{
on e1 do Bar;
on e2 do Baz;
}
}
}";

            var configuration = Configuration.Create();

            configuration.Verbose = 2;

            var context = CompilationContext.Create(configuration).LoadSolution(test);

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree();

            var expected = @"
using Microsoft.PSharp;
namespace Foo
{
class M : Machine
{
[Microsoft.PSharp.Start]
[OnEventDoAction(typeof(e1), nameof(Bar))]
[OnEventDoAction(typeof(e2), nameof(Baz))]
class S1 : MachineState
{
}
}
}";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty),
                            syntaxTree.ToString().Replace("\n", string.Empty));
        }
示例#6
0
        public void TestBasicLoop()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class M : Machine
{
 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  int k = 10;
  for (int i = 0; i < k; i++) { k = 2; }
  k = 3;
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "No static analysis errors detected.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
示例#7
0
        public void TestDeferEventDeclarationQualifiedComplex()
        {
            var test = @"
namespace Foo {
machine M {
start state S
{
defer e1<int>, halt, default, Foo.e2<Bar.e3>;
}
}
}";

            var configuration = Configuration.Create();

            configuration.Verbose = 2;

            var context = CompilationContext.Create(configuration).LoadSolution(test);

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree();

            var expected = @"
using Microsoft.PSharp;
namespace Foo
{
class M : Machine
{
[Microsoft.PSharp.Start]
[DeferEvents(typeof(e1<int>), typeof(Microsoft.PSharp.Halt), typeof(Microsoft.PSharp.Default), typeof(Foo.e2<Bar.e3>))]
class S : MachineState
{
}
}
}";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), syntaxTree.ToString().Replace("\n", string.Empty));
        }
示例#8
0
        public void TestUsingDeclaration()
        {
            var test = "using System.Text;";

            var configuration = Configuration.Create();

            configuration.Verbose = 2;

            var context = CompilationContext.Create(configuration).LoadSolution(test);

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree();

            var expected = @"
using Microsoft.PSharp;
using System.Text;";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty),
                            syntaxTree.ToString().Replace("\n", string.Empty));
        }
示例#9
0
        public void TestMemberVisibility()
        {
            var test = @"
namespace Foo {
class M : Machine
{
 int Num;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Num = 1;
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "No static analysis errors detected.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
示例#10
0
        /// <summary>
        /// Rewrites the assemblies specified in the configuration.
        /// </summary>
        private static void RewriteAssemblies(Configuration configuration, RewritingOptions options)
        {
            try
            {
                string assemblyDir = null;
                var    fileList    = new HashSet <string>();
                if (!string.IsNullOrEmpty(configuration.AssemblyToBeAnalyzed))
                {
                    var fullPath = Path.GetFullPath(configuration.AssemblyToBeAnalyzed);
                    Console.WriteLine($". Rewriting {fullPath}");
                    assemblyDir = Path.GetDirectoryName(fullPath);
                    fileList.Add(fullPath);
                }
                else if (Directory.Exists(configuration.RewritingOptionsPath))
                {
                    assemblyDir = Path.GetFullPath(configuration.RewritingOptionsPath);
                    Console.WriteLine($". Rewriting the assemblies specified in {assemblyDir}");
                }

                RewritingOptions config = options;

                if (!string.IsNullOrEmpty(assemblyDir))
                {
                    // Create a new RewritingOptions object from command line args only.
                    config.AssembliesDirectory = assemblyDir;
                    config.OutputDirectory     = assemblyDir;
                    config.AssemblyPaths       = fileList;
                }
                else
                {
                    // Load options from JSON file.
                    config = RewritingOptions.ParseFromJSON(configuration.RewritingOptionsPath);
                    Console.WriteLine($". Rewriting the assemblies specified in {configuration.RewritingOptionsPath}");
                    config.PlatformVersion = configuration.PlatformVersion;

                    // allow command line options to override the json file.
                    if (!string.IsNullOrEmpty(options.StrongNameKeyFile))
                    {
                        config.StrongNameKeyFile = options.StrongNameKeyFile;
                    }

                    if (options.IsRewritingDependencies)
                    {
                        config.IsRewritingDependencies = options.IsRewritingDependencies;
                    }

                    if (options.IsRewritingThreads)
                    {
                        config.IsRewritingThreads = options.IsRewritingThreads;
                    }

                    if (options.IsRewritingUnitTests)
                    {
                        config.IsRewritingUnitTests = options.IsRewritingUnitTests;
                    }
                }

                RewritingEngine.Run(configuration, config);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.StackTrace);
                Error.ReportAndExit(ex.Message);
            }
        }
示例#11
0
        public void TestFieldSendAlias()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;
 public int Num;

 public Letter(string text, int num)
 {
  this.Text = text;
  this.Num = num;
 }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  var letter = new Letter(""test"", 0);
  this.Target = this.CreateMachine(typeof(M));
  var otherLetter = letter;
  letter = this.Foo(letter);
  this.Send(this.Target, new eUnit(otherLetter));
 }

 Letter Foo(Letter letter)
 {
   return this.Bar(letter);
 }

 Letter Bar(Letter letter)
 {
  Letter otherLetter = new Letter(""test"", 0);
  otherLetter = this.Letter;
  return otherLetter;
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "No static analysis errors detected.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
示例#12
0
 /// <summary>
 /// Checks if the test executed by the testing engine has been rewritten.
 /// </summary>
 /// <returns>True if the test has been rewritten, else false.</returns>
 public bool IsTestRewritten() => RewritingEngine.IsAssemblyRewritten(this.TestMethodInfo.Assembly);
        public void TestFieldAccessAfterGivenUpOwnership2Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public MachineId Target;
 public Letter Letter;
 
 public eUnit(MachineId target, Letter letter)
  : base()
 {
  this.Target = target;
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;
 public int Num;

 public Letter(string text, int num)
 {
  this.Text = text;
  this.Num = num;
 }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Target = this.CreateMachine(typeof(M));
  this.Send(this.Target, new eUnit(this.Id, this.Letter));
  int num = this.Letter.Num;
  this.Letter.Text = ""London"";
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.DoStateTransitionAnalysis = false;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '3' errors.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
        public void TestWriteAccessAfterSendInCallee3Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;
 public int Num;

 public Letter(string text, int num)
 {
  this.Text = text;
  this.Num = num;
 }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  var letter = new Letter(""test"", 0);
  this.Target = this.CreateMachine(typeof(M));
  this.Send(this.Target, new eUnit(letter));
  this.Foo(letter);
 }

 void Foo(Letter letter)
 {
  this.Letter = letter;                // ERROR
  letter = new Letter(""test2"", 2);
  this.Letter.Num = 1;                 // ERROR
  int num = this.Letter.Num;           // ERROR
  letter.Text = ""Bangalore"";
  this.Letter.Text = ""Taipei"";       // ERROR
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.DoStateTransitionAnalysis = false;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '7' errors.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
示例#15
0
        public void TestAccessInVirtualMethod()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

internal class Envelope
{
 internal Letter Letter;

 internal virtual void Foo(Letter letter) { }
}

internal class SuperEnvelope : Envelope
{
 internal override void Foo(Letter letter)
 {
  letter.Text = ""Bangalore"";
 }
}

class M : Machine
{
 MachineId Target;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  var letter = new Letter(""London"");
  this.Target = this.CreateMachine(typeof(M));

  Envelope envelope = new Envelope();

  this.Send(this.Target, new eUnit(letter));

  envelope.Foo(letter);
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "No static analysis errors detected.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
示例#16
0
        public void TestComplexAccessesInCall11Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

class OtherClass
{
 AnotherClass AC;

 public void Foo(Letter letter)
 {
  var ac = new AnotherClass(letter);
  this.AC = ac;
  this.AC.Bar();
 }
}

class AnotherClass
{
 internal Letter Letter;

 public AnotherClass(Letter letter)
 {
  this.Letter = letter;
 }

 public void Bar()
 {
  this.Letter.Text = ""Test""; // ERROR
 }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Target = this.CreateMachine(typeof(M));
  Letter letter = new Letter(""London"");
  var oc = new OtherClass();
  this.Send(this.Target, new eUnit(letter));
  oc.Foo(letter);
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.DoStateTransitionAnalysis = false;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '2' errors.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
示例#17
0
        public void TestEventRaiseStatementWithPSharpAPI()
        {
            var test = @"
using Microsoft.PSharp;
namespace Foo
{
class e1 : Event
{
 public e1()
  : base()
 { }
}

class M : Machine
{
[Microsoft.PSharp.Start]
[OnEntry(nameof(psharp_S1_on_entry_action))]
[OnEventGotoState(typeof(e1), typeof(S2))]
class S1 : MachineState
{
}
class S2 : MachineState
{
}
protected void psharp_S1_on_entry_action()
{
this.Raise(new e1());
}
}
}";

            var configuration = Configuration.Create();

            configuration.Verbose = 2;

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            var syntaxTree = context.GetProjects()[0].CSharpPrograms[0].GetSyntaxTree();

            var expected = @"
using Microsoft.PSharp;
namespace Foo
{
class e1 : Event
{
 public e1()
  : base()
 { }
}

class M : Machine
{
[Microsoft.PSharp.Start]
[OnEntry(nameof(psharp_S1_on_entry_action))]
[OnEventGotoState(typeof(e1), typeof(S2))]
class S1 : MachineState
{
}
class S2 : MachineState
{
}
protected void psharp_S1_on_entry_action()
{
{ this.Raise(new e1());return; }
}
}
}";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty),
                            syntaxTree.ToString().Replace(Environment.NewLine, string.Empty));
        }
示例#18
0
        public void TestIfStatement8Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

class eReq : Event
{
 public int Value;
 
 public eReq(int value)
  : base()
 {
  this.Value = value;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  int num = (this.ReceivedEvent as eReq).Value;

  this.Target = this.CreateMachine(typeof(M));
  Letter letter = new Letter(""London"");
  Letter otherLetter = new Letter(""Bangalore"");

  this.Letter = letter;

  if (num == 0)
  {
   otherLetter = new Letter(""Redmond"");
  }
  else
  {
   otherLetter = letter;
  }

  this.Send(this.Target, new eUnit(otherLetter));

  this.Letter.Text = ""text"";
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '2' errors.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
示例#19
0
        public void TestWriteAccessAfterSendInLoop2()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

class M : Machine
{
 MachineId Target;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  var letter = new Letter(""London"");
  this.Target = this.CreateMachine(typeof(M));

  int k = 10;
  for (int i = 0; i < k; i++)
  {
    continue;
    letter.Text = ""Bangalore"";
    this.Send(this.Target, new eUnit(letter));
  }
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "No static analysis errors detected.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
        public void TestFieldGivenUpOwnership1Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  var letter = new Letter(""test"");
  this.Target = this.CreateMachine(typeof(M));
  this.Send(this.Target, new eUnit(letter));
  this.Letter = letter;
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.DoStateTransitionAnalysis = false;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '1' error.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            var error = "Error: Method 'FirstOnEntryAction' of machine 'Foo.M' assigns " +
                        "'letter' to field 'Foo.M.Letter' after giving up its ownership.";
            var actual = IO.GetOutput();

            Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty),
                            actual.Substring(0, actual.IndexOf(Environment.NewLine)));

            IO.StopWritingToMemory();
        }
示例#21
0
        public void TestComplexAccessesInCall1Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Envelope Envelope;
 
 public eUnit(Envelope envelope)
  : base()
 {
  this.Envelope = envelope;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

struct Envelope
{
 public Letter Letter;
 public string Address;
 public int Id;

 public Envelope(string address, int id)
 {
  this.Letter = new Letter("""");
  this.Address = address;
  this.Id = id;
 }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Target = this.CreateMachine(typeof(M));
  Envelope envelope = new Envelope(""London"", 0);
  Envelope otherEnvelope = envelope;

  this.Foo(otherEnvelope);

  this.Send(this.Target, new eUnit(envelope));

  this.Bar(otherEnvelope.Letter);
  otherEnvelope.Letter.Text = ""text"";  // ERROR

  envelope = new Envelope();
  this.FooBar(envelope, otherEnvelope.Letter);
 }

 void Foo(Envelope envelope)
 {
  this.Letter = envelope.Letter;  // ERROR
 }

 void Bar(Letter letter)
 {
  letter.Text = ""text2"";  // ERROR
 }

 void FooBar(Envelope envelope, Letter letter)
 {
  string str = letter.Text;  // ERROR
  envelope.Id = 5;
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.DoStateTransitionAnalysis = false;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '4' errors.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
        public void TestAccessInVirtualMethod7Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

internal class Envelope
{
 internal Letter Letter;

 internal virtual void Foo(Letter letter) { }

 internal virtual void Bar(Letter letter) { }
}

internal class SuperEnvelope : Envelope
{
 internal override void Foo(Letter letter)
 {
  letter.Text = ""Bangalore"";
 }

 internal override void Bar(Letter letter)
 {
  base.Letter.Text = ""Bangalore"";
 }
}

class M : Machine
{
 MachineId Target;
 bool Check;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  var letter = new Letter(""London"");
  this.Target = this.CreateMachine(typeof(M));

  Envelope envelope = this.Foo();

  this.Send(this.Target, new eUnit(letter));

  envelope.Foo(letter); // ERROR
 }

 Envelope Foo()
 {
  Envelope envelope = new SuperEnvelope();
  Envelope anotherEnvelope = new Envelope();
  anotherEnvelope = envelope;

  if (this.Check)
  {
   return new Envelope();
  }
  else
  {
   return anotherEnvelope;
  }
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '1' error.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            var error = "Error: Method 'FirstOnEntryAction' of machine 'Foo.M' accesses " +
                        "'letter' after giving up its ownership.";
            var actual = IO.GetOutput();

            Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty),
                            actual.Substring(0, actual.IndexOf(Environment.NewLine)));

            IO.StopWritingToMemory();
        }
示例#23
0
        public void TestComplexAccessesInCall10Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

class OtherClass
{
 internal Letter Letter;

 public void Foo(Letter letter)
 {
  this.Letter = letter;
 }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;
 OtherClass OC;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Target = this.CreateMachine(typeof(M));
  Letter letter = new Letter(""London"");
  var oc = new OtherClass();
  oc.Foo(letter);
  this.OC = oc;
  this.Send(this.Target, new eUnit(letter)); // ERROR
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.DoStateTransitionAnalysis = false;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '1' error.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            var error = "Error: Method 'FirstOnEntryAction' of machine 'Foo.M' sends " +
                        "'letter', which contains data from field 'letter'.";
            var actual = IO.GetOutput();

            Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty),
                            actual.Substring(0, actual.IndexOf(Environment.NewLine)));

            IO.StopWritingToMemory();
        }
示例#24
0
        public void TestCreateNamedMachineStatementWithDoublePayload()
        {
            var test = @"
namespace Foo {
event e1 (k:int, s:string);

machine M {
machine Target;
start state S
{
entry
{
string s = ""hello"";
create(M, ""NamedMachine"", e1, 10, s);
}
}
}
}";

            var configuration = Configuration.Create();

            configuration.Verbose = 2;

            var context = CompilationContext.Create(configuration).LoadSolution(test);

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree();

            var expected = @"
using Microsoft.PSharp;
namespace Foo
{
class e1 : Event
{
 public int k;
 public string s;
 public e1(int k, string s)
  : base()
 {
  this.k = k;
  this.s = s;
 }
}

class M : Machine
{
MachineId Target;
[Microsoft.PSharp.Start]
[OnEntry(nameof(psharp_S_on_entry_action))]
class S : MachineState
{
}
protected void psharp_S_on_entry_action()
{
string s = ""hello"";
this.CreateMachine(typeof(M),""NamedMachine"",new e1(10, s));
}
}
}";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty),
                            syntaxTree.ToString().Replace("\n", string.Empty));
        }
示例#25
0
        public void TestFieldSendAlias6Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;
 public int Num;

 public Letter(string text, int num)
 {
  this.Text = text;
  this.Num = num;
 }
}

class M : Machine
{
 MachineId Target;
 Object Obj;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Target = this.CreateMachine(typeof(M));
  this.Obj = (this.ReceivedEvent as eUnit).Letter;
  this.Send(this.Target, new eUnit((this.ReceivedEvent as eUnit).Letter));
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.DoStateTransitionAnalysis = false;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '1' error.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            var error = "Error: Method 'FirstOnEntryAction' of machine 'Foo.M' sends " +
                        "'ReceivedEvent', which contains data from field 'Foo.M.Obj'.";
            var actual = IO.GetOutput();

            Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty),
                            actual.Substring(0, actual.IndexOf(Environment.NewLine)));

            IO.StopWritingToMemory();
        }
        public void TestAccessInVirtualMethod9Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

internal class Envelope
{
 internal Letter Letter;

 internal virtual void Foo(Letter letter) { }
}

internal class SuperEnvelope : Envelope
{
 internal override void Foo(Letter letter)
 {
  Letter = letter; // ERROR
  base.Letter.Text = ""Bangalore""; // ERROR
 }
}

class M : Machine
{
 MachineId Target;
 bool Check;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Target = this.CreateMachine(typeof(M));
  var letter = new Letter(""London"");
  Envelope envelope = this.Foo();

  this.Send(this.Target, new eUnit(letter));

  this.Bar(envelope, letter);
 }

 Envelope Foo()
 {
  Envelope someEnvelope = new SuperEnvelope();
  Envelope anotherEnvelope;
  anotherEnvelope = new Envelope();
  anotherEnvelope = someEnvelope;

  if (this.Check)
  {
   return new Envelope();
  }
  else
  {
   return anotherEnvelope;
  }
 }

 void Bar(Envelope envelope, Letter letter)
 {
  this.FooBar(envelope, letter);
 }

 void FooBar(Envelope envelope, Letter letter)
 {
  envelope.Foo(letter);
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.DoStateTransitionAnalysis = false;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '3' errors.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
        public void TestReturnAliasAccess8Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Envelope Envelope;
 
 public eUnit(Envelope envelope)
  : base()
 {
  this.Envelope = envelope;
 }
}

struct Envelope
{
 public Letter Letter;

 public Envelope(Letter letter)
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;
 public int Num;

 public Letter(string text, int num)
 {
  this.Text = text;
  this.Num = num;
 }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Target = this.CreateMachine(typeof(M));
  this.Foo();
 }

 void Foo()
 {
   var letter = new Letter(""test"", 0);
   var envelope = new Envelope(letter);
   envelope.Letter = this.Bar();
   this.Send(this.Target, new eUnit(envelope));
 }

 Letter Bar()
 {
  return this.Letter;
 }
}
}";

            var configuration = base.GetConfiguration();

            configuration.DoStateTransitionAnalysis = false;

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '1' error.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            var error = "Error: Method 'Foo' of machine 'Foo.M' sends 'envelope', " +
                        "which contains data from field 'Foo.M.Letter'.";
            var actual = IO.GetOutput();

            Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty),
                            actual.Substring(0, actual.IndexOf(Environment.NewLine)));

            IO.StopWritingToMemory();
        }
示例#28
0
        public void TestSwitchStatement()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;

 public Letter(string text)
 {
  this.Text = text;
 }
}

class M : Machine
{
 MachineId Target;
 int Num;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  this.Target = this.CreateMachine(typeof(M));
  var letter = new Letter(""London"");

  this.Send(this.Target, new eUnit(letter));

  switch (this.Num)
  {
   case 0:
   case 1:
    letter = new Letter(""Taipei"");
    break;

   case 2:
    letter = new Letter(""Redmond"");
    break;

   default:
    letter = new Letter(""Bangalore"");
    break;
  }

  letter.Text = ""text"";
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "No static analysis errors detected.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            IO.StopWritingToMemory();
        }
        public void TestWriteAccessAfterSendInCallee5Fail()
        {
            var test = @"
using Microsoft.PSharp;

namespace Foo {
class eUnit : Event
{
 public Letter Letter;
 
 public eUnit(Letter letter)
  : base()
 {
  this.Letter = letter;
 }
}

struct Letter
{
 public string Text;
 public int Num;

 public Letter(string text, int num)
 {
  this.Text = text;
  this.Num = num;
 }

 public int Get() { return 0; }
}

class M : Machine
{
 MachineId Target;
 Letter Letter;

 [Start]
 [OnEntry(nameof(FirstOnEntryAction))]
 class First : MachineState { }

 void FirstOnEntryAction()
 {
  var letter = new Letter(""test"", 0);
  this.Target = this.CreateMachine(typeof(M));
  this.Send(this.Target, new eUnit(letter));
  this.Foo(letter);
 }

 void Foo(Letter letter)
 {
  var k = letter.Get(); // ERROR
 }
}
}";

            var configuration = base.GetConfiguration();

            IO.StartWritingToMemory();

            var context = CompilationContext.Create(configuration).LoadSolution(test, "cs");

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            AnalysisErrorReporter.ResetStats();
            StaticAnalysisEngine.Create(context).Run();

            var stats    = AnalysisErrorReporter.GetStats();
            var expected = "Static analysis detected '1' error.";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty), stats);

            var error = "Error: Method 'FirstOnEntryAction' of machine 'Foo.M' " +
                        "accesses 'letter' after giving up its ownership.";
            var actual = IO.GetOutput();

            Assert.AreEqual(error.Replace(Environment.NewLine, string.Empty),
                            actual.Substring(0, actual.IndexOf(Environment.NewLine)));

            IO.StopWritingToMemory();
        }
示例#30
0
        public void TestMachineNestedGroups()
        {
            var test = @"
namespace Foo {
machine M {
group G1 {
  start state S1 { entry { jump(G3.S2); } }
  group G3 {
    state S2 { entry { jump(S1); } }
    state S3 { entry { jump(S2); } }
  }
}
}
}";

            var configuration = Configuration.Create();

            configuration.Verbose = 2;

            var context = CompilationContext.Create(configuration).LoadSolution(test);

            ParsingEngine.Create(context).Run();
            RewritingEngine.Create(context).Run();

            var syntaxTree = context.GetProjects()[0].PSharpPrograms[0].GetSyntaxTree();

            var expected = @"
using Microsoft.PSharp;
namespace Foo
{
class M : Machine
{
class G1 : StateGroup
{
public class G3 : StateGroup
{
[OnEntry(nameof(psharp_G1_G3_S2_on_entry_action))]
public class S2 : MachineState
{
}
[OnEntry(nameof(psharp_G1_G3_S3_on_entry_action))]
public class S3 : MachineState
{
}
}
[Microsoft.PSharp.Start]
[OnEntry(nameof(psharp_G1_S1_on_entry_action))]
public class S1 : MachineState
{
}
}
protected void psharp_G1_S1_on_entry_action(){ { this.Goto(typeof(G1.G3.S2));return; } }
protected void psharp_G1_G3_S2_on_entry_action(){ { this.Goto(typeof(G1.S1));return; } }
protected void psharp_G1_G3_S3_on_entry_action(){ { this.Goto(typeof(G1.G3.S2));return; } }
}
}
";

            Assert.AreEqual(expected.Replace(Environment.NewLine, string.Empty).Replace("\n", string.Empty),
                            syntaxTree.ToString().Replace("\n", string.Empty));
        }