Skip to content

Dev p3.0/param testcases #879

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 29 commits into
base: major/P3.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
6be2b01
Add global constant varaibles; TODO backend
zhezhouzz Jun 11, 2024
82637c6
Updated BuildGlobalScope
zhezhouzz Jun 11, 2024
7b55329
add global variable
zhezhouzz Jun 12, 2024
8cfe5c9
fix global variable types
zhezhouzz Jun 12, 2024
d630b9f
Allow multiple tests
zhezhouzz Jun 12, 2024
f39c431
Add int list literal syntax
zhezhouzz Jun 13, 2024
246d1d6
add parametric test
zhezhouzz Jun 13, 2024
71b519b
Quick-fix
zhezhouzz Jun 13, 2024
740de07
fix bad quick-fix
zhezhouzz Jun 13, 2024
5def42a
add rich syntax
zhezhouzz Jun 13, 2024
38dbf6d
Merge branch 'master' into paramtest
zhezhouzz Jun 17, 2024
08ee970
Merge branch 'mainp' into paramtest
zhezhouzz Jul 16, 2024
57d7c4b
Merge branch 'paramtest' of github.com:p-org/P-TestGeneration into pa…
zhezhouzz Jul 16, 2024
1a9754d
Merge branch 'master' into paramtest
zhezhouzz Aug 21, 2024
50463f5
Merge branch 'master' into paramtest
ankushdesai Dec 4, 2024
658c304
Merge branch 'paramtest' of https://github.com/p-org/P-TestGeneration…
ankushdesai Dec 4, 2024
924eced
Merge branch 'p-org-paramtest' into dev_p3.0/param_testcases
ankushdesai Dec 4, 2024
60d3fb4
Small merge error
ankushdesai Dec 4, 2024
bd3d167
Param (#833)
zhezhouzz Mar 19, 2025
c7e86ab
T-wise combinatorial test (#837)
zhezhouzz Mar 31, 2025
ef898a0
T-wise combinatorial (Solved Concerns from Lewis) (#838)
zhezhouzz Apr 8, 2025
55a1199
Dev/remove libhandler (#847)
ankushdesai Apr 24, 2025
c5c6c72
Update build system and Java compiler, remove dependency JARs (#849)
ankushdesai Apr 24, 2025
28833bf
Merge branch 'master' into major/P3.0
ankushdesai Apr 25, 2025
5c77847
Merge branch 'major/P3.0' into dev_p3.0/param_testcases
ankushdesai Apr 29, 2025
a4a6195
Modified regression tests to run in process, added test cases for par…
ChristineZh0u Jun 29, 2025
e8c605a
resolve merging conflict
Jun 30, 2025
5320e40
Fix pex regression test
Jun 30, 2025
936c47e
remove unnecessary line
Jul 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/macosci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,10 @@ jobs:
- name: Build
run: dotnet build --configuration Release
- name: Test
run: dotnet test --configuration Release
run: dotnet test --configuration Release --blame-crash --blame-hang --blame-hang-timeout 300s --logger:"console;verbosity=detailed"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please explain this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is to get better logs when the GitHub Action fails. Without it, we just see that something crashed, but not what caused it. With these flags, we get more detailed output and can tell which test hung or crashed, which makes debugging a lot easier.

- name: Upload Test Results
uses: actions/upload-artifact@v4
if: always() # This ensures it runs even after test failure
with:
name: test-results
path: Tst/UnitTests/TestResults/**/*.xml
9 changes: 7 additions & 2 deletions Src/PChecker/CheckerCore/Checker.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using System;
using PChecker.IO.Debugging;
using PChecker.IO.Logging;
using PChecker.SystematicTesting;
using PChecker.Testing;
using PChecker.SystematicTesting;

namespace PChecker;

Expand Down Expand Up @@ -51,7 +51,12 @@ public static void Run(CheckerConfiguration configuration)
switch (configuration.Mode)
{
case CheckerMode.BugFinding:
TestingProcess.Create(configuration).Run();
var testingEngine = TestingProcess.Create(configuration);
if (configuration.ListTestCases)
{
break;
}
testingEngine.Run();
break;
case CheckerMode.PEx:
ExhaustiveEngine.Create(configuration).Run();
Expand Down
4 changes: 2 additions & 2 deletions Src/PChecker/CheckerCore/SystematicTesting/TestingEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public static TestingEngine Create(CheckerConfiguration checkerConfiguration) =>
/// <summary>
/// Creates a new systematic testing engine.
/// </summary>
public static TestingEngine Create(CheckerConfiguration checkerConfiguration, Assembly assembly)
private static TestingEngine Create(CheckerConfiguration checkerConfiguration, Assembly assembly)
{
if (checkerConfiguration.ListTestCases)
{
Expand All @@ -190,7 +190,7 @@ public static TestingEngine Create(CheckerConfiguration checkerConfiguration, As
Console.Out.WriteLine($"{mi.DeclaringType.Name}");
}

Environment.Exit(0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is needed because, for parametric tests, we have to fetch all the test case names using this function. The problem is that it calls Environment.Exit(0), which ends the entire regression test run early. So we had to handle it differently to avoid stopping the whole suite.

return null;
}
catch
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.IO;
using System.Linq;
using System.Reflection;
Expand All @@ -21,7 +22,8 @@ public class PCheckerCodeGenerator : ICodeGenerator
/// This compiler has a compilation stage.
/// </summary>
public bool HasCompilationStage => true;
private static List<Variable> _globalParams = [];
[ThreadStatic]
private static List<Variable> _globalParams;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was causing issues when I ran regression tests in parallel. Since _globalParams was static, all the tests were sharing the same list, which led to conflicts. Adding [ThreadStatic] makes sure each test thread gets its own copy, so they don’t mess with each other.


private string GetGlobalParamAndLocalVariableName(CompilationContext context, Variable v)
{
Expand Down Expand Up @@ -346,6 +348,7 @@ private static void WriteForeignType(CompilationContext context, StringWriter ou
// For normal test, the assignment is empty dictionary
private void WriteSafetyTestDecl(CompilationContext context, StringWriter output, SafetyTest safety, Dictionary<Variable, IPExpr> assignment)
{
// Console.WriteLine($"dic: {string.Join(',', dic.ToList())}");
WriteNameSpacePrologue(context, output);
var name = ParamAssignment.RenameSafetyTestByAssignment(context.Names.GetNameForDecl(safety), assignment);
context.WriteLine(output, $"public class {name} {{");
Expand Down
5 changes: 5 additions & 0 deletions Src/PCompiler/CompilerCore/TypeChecker/ParamAssignment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ private static Dictionary<Variable, IPExpr> IndexDic2Dic(List<Variable> globalPa
foreach (var (k, i) in indexDic)
{
var values = paramExprDic[k];
if (!globalParams.Any(v => v.Name == k))
{
throw new Exception($"Variable name '{k}' not found in globalParams. " +
$"GlobalParams are: [{string.Join(", ", globalParams.Select(v => v.Name))}]");
}
var variable = globalParams.First(v => v.Name == k);
if (i >= values.Count) throw new ArgumentException("Index out of range in global variable config.");
dic[variable] = values[i];
Expand Down
17 changes: 13 additions & 4 deletions Src/PCompiler/CompilerCore/TypeChecker/ParamVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,25 @@ public override IPExpr VisitSeqLiteralBody([NotNull] PParser.SeqLiteralBodyConte
if (context.primitive() != null)
{
var values = context.primitive().Select(Visit).ToList();
if (values.Count == 0) return new SeqLiteralExpr(context, values, PrimitiveType.Int);
// Console.WriteLine($"value[0] = {values[0].GetType()}");

if (values.Count == 2 &&
values[0] is IntLiteralExpr first &&
values[1] is IntLiteralExpr second &&
first.Value == second.Value)
{
throw handler.InternalError(context, new Exception("Invalid range: start and end must not be equal (e.g., [2, 2] is not allowed)")); }

if (values.Count == 0)
return new SeqLiteralExpr(context, values, PrimitiveType.Int);

var type = values[0].Type;
foreach (var v in values.Where(v => !v.Type.Equals(type)))
{
throw handler.TypeMismatch(v.SourceLocation, v.Type, type);
}

return new SeqLiteralExpr(context, values, new SequenceType(type));

}
}
if (context.seqLiteral() != null)
{
return Visit(context.seqLiteral());
Expand Down
2 changes: 1 addition & 1 deletion Src/PCompiler/PCommandLine/CommandLine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public static class CommandLine

private static readonly object ConsoleLock = new object();

private static void Main(string[] args)
public static void Main(string[] args)
{
// Save these so we can force output to happen even if TestingProcess has re-routed it.
StdOut = Console.Out;
Expand Down
4 changes: 4 additions & 0 deletions Src/PEx/src/test/java/pex/TestPEx.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,11 @@ Collection<DynamicTest> loadTests(String testDirPath) {
pathKeys.sort(String.CASE_INSENSITIVE_ORDER);

if (testDir.contains("Correct")) {

for (String key : pathKeys) {
if (key.contains("ParamTest")) {
continue;
}
runDynamicTest(0, paths.get(key), key, dynamicTests);
}
} else if (testDir.contains("DynamicError")) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,4 @@
[
{
"type": "CreateStateMachine",
"details": {
"log": "Main(1) was created by task \u00272\u0027.",
"id": "Main(1)",
"payload": "null",
"clock": {
"Main(1)": 1
}
}
},
[
{
"type": "StateTransition",
"details": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
<TestLog> Running test 'DefaultImpl'.
<CreateLog> Main(1) was created by task '2'.
<StateLog> Main(1) enters state 'S'.
<RaiseLog> 'Main(1)' raised event 'x with payload (<a,3,>)' in state 'S'.
<RaiseLog> 'Main(1)' raised event 'a with payload (3)' in state 'S'.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
BasicNonParametricTest
FullCartesianProductParametricTest___g1_1__g2_3__g3_5__g4_7
FullCartesianProductParametricTest___g1_2__g2_3__g3_5__g4_7
FullCartesianProductParametricTest___g1_1__g2_4__g3_5__g4_7
FullCartesianProductParametricTest___g1_2__g2_4__g3_5__g4_7
FullCartesianProductParametricTest___g1_1__g2_3__g3_6__g4_7
FullCartesianProductParametricTest___g1_2__g2_3__g3_6__g4_7
FullCartesianProductParametricTest___g1_1__g2_4__g3_6__g4_7
FullCartesianProductParametricTest___g1_2__g2_4__g3_6__g4_7
FullCartesianProductParametricTest___g1_1__g2_3__g3_5__g4_8
FullCartesianProductParametricTest___g1_2__g2_3__g3_5__g4_8
FullCartesianProductParametricTest___g1_1__g2_4__g3_5__g4_8
FullCartesianProductParametricTest___g1_2__g2_4__g3_5__g4_8
FullCartesianProductParametricTest___g1_1__g2_3__g3_6__g4_8
FullCartesianProductParametricTest___g1_2__g2_3__g3_6__g4_8
FullCartesianProductParametricTest___g1_1__g2_4__g3_6__g4_8
FullCartesianProductParametricTest___g1_2__g2_4__g3_6__g4_8
ParametricTestWithAssumption___g1_1__g2_3__g3_5__g4_7
ParametricTestWithAssumption___g1_2__g2_3__g3_5__g4_7
ParametricTestWithAssumption___g1_1__g2_4__g3_5__g4_7
ParametricTestWithAssumption___g1_2__g2_4__g3_5__g4_7
ParametricTestWithAssumption___g1_1__g2_3__g3_6__g4_7
ParametricTestWithAssumption___g1_2__g2_3__g3_6__g4_7
ParametricTestWithAssumption___g1_1__g2_4__g3_6__g4_7
ParametricTestWithAssumption___g1_2__g2_4__g3_6__g4_7
ParametricTestWithAssumption___g1_1__g2_3__g3_5__g4_8
ParametricTestWithAssumption___g1_2__g2_3__g3_5__g4_8
ParametricTestWithAssumption___g1_1__g2_4__g3_5__g4_8
ParametricTestWithAssumption___g1_2__g2_4__g3_5__g4_8
ParametricTestWithAssumption___g1_1__g2_3__g3_6__g4_8
ParametricTestWithAssumption___g1_2__g2_3__g3_6__g4_8
ParametricTestWithAssumption___g1_1__g2_4__g3_6__g4_8
ParametricTestWithAssumption___g1_2__g2_4__g3_6__g4_8
ParametricTestWithBoolAssumption___g1_1__g2_3__g3_5__g4_7__b1_False
ParametricTestWithBoolAssumption___g1_2__g2_3__g3_5__g4_7__b1_False
ParametricTestWithBoolAssumption___g1_1__g2_4__g3_5__g4_7__b1_False
ParametricTestWithBoolAssumption___g1_2__g2_4__g3_5__g4_7__b1_False
ParametricTestWithBoolAssumption___g1_1__g2_3__g3_6__g4_7__b1_False
ParametricTestWithBoolAssumption___g1_2__g2_3__g3_6__g4_7__b1_False
ParametricTestWithBoolAssumption___g1_1__g2_4__g3_6__g4_7__b1_False
ParametricTestWithBoolAssumption___g1_2__g2_4__g3_6__g4_7__b1_False
ParametricTestWithBoolAssumption___g1_1__g2_3__g3_5__g4_8__b1_False
ParametricTestWithBoolAssumption___g1_2__g2_3__g3_5__g4_8__b1_False
ParametricTestWithBoolAssumption___g1_1__g2_4__g3_5__g4_8__b1_False
ParametricTestWithBoolAssumption___g1_2__g2_4__g3_5__g4_8__b1_False
ParametricTestWithBoolAssumption___g1_1__g2_3__g3_6__g4_8__b1_False
ParametricTestWithBoolAssumption___g1_2__g2_3__g3_6__g4_8__b1_False
ParametricTestWithBoolAssumption___g1_1__g2_4__g3_6__g4_8__b1_False
ParametricTestWithBoolAssumption___g1_2__g2_4__g3_6__g4_8__b1_False
TWise1CoverageTest___g1_1__g2_3__g3_5__g4_7__b1_True
TWise1CoverageTest___g1_2__g2_4__g3_6__g4_8__b1_False
TWise2CoverageTest___g1_1__g2_3__g3_5__g4_7__b1_True
TWise2CoverageTest___g1_2__g2_4__g3_6__g4_8__b1_True
TWise2CoverageTest___g1_2__g2_4__g3_5__g4_7__b1_False
TWise2CoverageTest___g1_1__g2_3__g3_6__g4_8__b1_False
TWise2CoverageTest___g1_2__g2_3__g3_6__g4_7__b1_True
TWise2CoverageTest___g1_1__g2_4__g3_5__g4_8__b1_True
TWise3CoverageTest___g1_1__g2_3__g3_5__g4_7__b1_True
TWise3CoverageTest___g1_2__g2_4__g3_6__g4_7__b1_True
TWise3CoverageTest___g1_2__g2_3__g3_5__g4_8__b1_False
TWise3CoverageTest___g1_1__g2_4__g3_6__g4_8__b1_False
TWise3CoverageTest___g1_1__g2_4__g3_5__g4_8__b1_True
TWise3CoverageTest___g1_2__g2_3__g3_6__g4_8__b1_True
TWise3CoverageTest___g1_2__g2_4__g3_5__g4_7__b1_False
TWise3CoverageTest___g1_1__g2_3__g3_6__g4_7__b1_False
TWise3CoverageTest___g1_2__g2_3__g3_5__g4_7__b1_True
TWise3CoverageTest___g1_1__g2_4__g3_6__g4_7__b1_True
TWise3CoverageTest___g1_1__g2_3__g3_5__g4_8__b1_False
TWise3CoverageTest___g1_2__g2_4__g3_6__g4_8__b1_False
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
param g1 : int;
param g2 : int;
param g3 : int;
param g4 : int;

machine Main {
var M: machine;
start state Init {
entry {
print format("global varaible g1 = {0}", g1);
print format("global varaible g2 = {0}", g2);
print format("global varaible g3 = {0}", g3);
print format("global varaible g4 = {0}", g4);
}
}
}


test BasicNonParametricTest [main=Main]:{Main};

test param (g1 in [1, 2], g2 in [3, 4], g3 in [5, 6], g4 in [7, 8]) FullCartesianProductParametricTest [main=Main]:{Main};

test param (g1 in [1, 2], g2 in [3, 4], g3 in [5, 6], g4 in [7, 8]) assume (g1 + g2 < g3 + g4) ParametricTestWithAssumption [main=Main]:{Main};

param b1: bool;

test param (g1 in [1, 2], g2 in [3, 4], g3 in [5, 6], g4 in [7, 8], b1 in [true, false]) assume (b1 == (g1 + g2 > g3 + g4)) ParametricTestWithBoolAssumption [main=Main]:{Main};

test param (g1 in [1, 2], g2 in [3, 4], g3 in [5, 6], g4 in [7, 8], b1 in [true, false]) (1 wise) TWise1CoverageTest [main=Main]:{Main};

test param (g1 in [1, 2], g2 in [3, 4], g3 in [5, 6], g4 in [7, 8], b1 in [true, false]) (2 wise) TWise2CoverageTest [main=Main]:{Main};

test param (g1 in [1, 2], g2 in [3, 4], g3 in [5, 6], g4 in [7, 8], b1 in [true, false]) (3 wise) TWise3CoverageTest [main=Main]:{Main};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TestParam___g1_1__g2_3
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
param g1 : int;
param g2 : int;


machine Main {
var M: machine;
start state Init {
entry {
print format("global varaible g1 = {0}", g1);
print format("global varaible g2 = {0}", g2);
assert g1 != 1 && g2 != 3 ;
}
}
}


test param (g1 in [1], g2 in [3]) TestParam [main=Main]:{Main};
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
param g1 : int;

machine Main {
var M: machine;
start state Init {
entry {
print format("global varaible g1 = {0}", g1);
}
}
}

test param (g1 in [2, 2]) Test1 [main=Main]:{Main};

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
param g1 : int;

machine Main {
var M: machine;
start state Init {
entry {
print format("global varaible g1 = {0}", g1);
}
}
}


test param (g1 in [1, 2]) (0 wise) TWise0CoverageTest [main=Main]:{Main};
2 changes: 1 addition & 1 deletion Tst/TestParamTester/1_ClientServer/PTst/TestDriver.p
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ fun CreateRandomInitialAccounts(numAccounts: int) : map[int, int]
var i: int;
var bankBalance: map[int, int];
while(i < numAccounts) {
bankBalance[i] = choose(10) + 10; // min 10 in the account
bankBalance[i] = choose(100) + 10; // min 10 in the account
i = i + 1;
}
return bankBalance;
Expand Down
19 changes: 15 additions & 4 deletions Tst/UnitTests/PCheckerLogGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ public void TestLogGenerator()
var tempDir = Directory.CreateDirectory(testLogGeneratorPath);
var srcPath = new FileInfo(Path.Combine(Constants.SolutionDirectory, "Tst", "RegressionTests",
"Feature1SMLevelDecls", "DynamicError", "bug2", "bug2.p"));
var dllPath = Path.Combine(Constants.ScratchParentDirectory, "TestLogGenerator", "PChecker", "net8.0", "Main.dll");
var runner = new PCheckerRunner([srcPath]);
var dllPath = Path.Combine(Constants.ScratchParentDirectory, "TestLogGenerator", "PChecker", "net8.0", "bug2.dll");
var expectedPath = Path.Combine(Constants.SolutionDirectory, "Tst", "CorrectLogs", "bugs2");

var runner = new PCheckerRunner([srcPath]);
runner.DoCompile(tempDir);

var configuration = new PCheckerOptions().Parse([dllPath, "-o", tempDir.ToString()]);
Expand All @@ -53,14 +53,25 @@ private void AssertLog(string generatedDir, string expectedDir)
string generatedFilePath = Path.Combine(generatedDir, fileName);
string expectedFilePath = Path.Combine(expectedDir, fileName);

if (fileName == "Main_0_0.trace.json")
if (fileName == "bug2_0_0.trace.json")
{
// Perform "Is JSON Included" check for this specific file
if (!IsJsonContentIncluded(generatedFilePath, expectedFilePath))
{
Assert.Fail($"Test Failed \nContent of {expectedFilePath} is not fully included in {generatedFilePath}");
}
}
else if (fileName == "bug2_0_0.txt")
{
// Perform "Is text included" check for this specific file
var expectedContent = File.ReadAllText(expectedFilePath);
var generatedContent = File.ReadAllText(generatedFilePath);

if (!generatedContent.Contains(expectedContent))
{
Assert.Fail($"Test Failed \nExpected content from {expectedFilePath} not found in {generatedFilePath}");
}
}
else
{
// Perform exact match for other files
Expand Down Expand Up @@ -128,4 +139,4 @@ private static bool IsSubset(JToken subset, JToken superset)

return false;
}
}
}
Loading
Loading