1
+ using System ;
2
+ using System . Diagnostics ;
3
+ using System . IO ;
4
+ using System . Linq ;
5
+ using Newtonsoft . Json . Linq ;
6
+ using NUnit . Framework ;
7
+ using PChecker ;
8
+ using UnitTests . Core ;
9
+ using UnitTests . Runners ;
10
+ using Plang . Options ;
11
+ namespace UnitTests ;
12
+
13
+ [ TestFixture ]
14
+ [ Parallelizable ( ParallelScope . Children ) ]
15
+ public class PCheckerLogGeneratorTests
16
+ {
17
+ [ Test ]
18
+ public void TestLogGenerator ( )
19
+ {
20
+ var tempDir = Directory . CreateDirectory ( Path . Combine ( Constants . ScratchParentDirectory , "TestLogGenerator" ) ) ;
21
+ var srcPath = new FileInfo ( Path . Combine ( Constants . SolutionDirectory , "Tst" , "RegressionTests" ,
22
+ "Feature1SMLevelDecls" , "DynamicError" , "bug2" , "bug2.p" ) ) ;
23
+ var dllPath = Path . Combine ( Constants . ScratchParentDirectory , "TestLogGenerator" , "CSharp" , "net8.0" , "Main.dll" ) ;
24
+ var expectedPath = Path . Combine ( Constants . SolutionDirectory , "Tst" , "CorrectLogs" , "bugs2" ) ;
25
+
26
+ var runner = new PCheckerRunner ( [ srcPath ] ) ;
27
+ runner . DoCompile ( tempDir ) ;
28
+
29
+ var configuration = new PCheckerOptions ( ) . Parse ( [ dllPath , "-o" , tempDir . ToString ( ) ] ) ;
30
+ Checker . Run ( configuration ) ;
31
+
32
+ AssertLog ( tempDir + "/BugFinding" , expectedPath ) ;
33
+ }
34
+
35
+ private void AssertLog ( string generatedDir , string expectedDir )
36
+ {
37
+ if ( ! Directory . Exists ( generatedDir ) || ! Directory . Exists ( expectedDir ) )
38
+ {
39
+ Assert . Fail ( "One or both directories do not exist." ) ;
40
+ }
41
+
42
+ var generatedFiles = Directory . GetFiles ( generatedDir ) . Select ( Path . GetFileName ) . ToHashSet ( ) ;
43
+ var expectedFiles = Directory . GetFiles ( expectedDir ) . Select ( Path . GetFileName ) . ToHashSet ( ) ;
44
+
45
+ foreach ( var fileName in expectedFiles . Intersect ( generatedFiles ) )
46
+ {
47
+ string generatedFilePath = Path . Combine ( generatedDir , fileName ) ;
48
+ string expectedFilePath = Path . Combine ( expectedDir , fileName ) ;
49
+
50
+ if ( fileName == "trace_0_0.trace.json" )
51
+ {
52
+ // Perform "Is JSON Included" check for this specific file
53
+ if ( ! IsJsonContentIncluded ( generatedFilePath , expectedFilePath ) )
54
+ {
55
+ Assert . Fail ( $ "Test Failed \n Content of { expectedFilePath } is not fully included in { generatedFilePath } ") ;
56
+ }
57
+ }
58
+ else
59
+ {
60
+ // Perform exact match for other files
61
+ if ( ! File . ReadAllBytes ( generatedFilePath ) . SequenceEqual ( File . ReadAllBytes ( expectedFilePath ) ) )
62
+ {
63
+ Assert . Fail ( $ "Test Failed \n Files differ: { fileName } \n Generated File: { generatedFilePath } \n Expected File: { expectedFilePath } ") ;
64
+ }
65
+ }
66
+ }
67
+
68
+ // Check for missing files in generatedDir
69
+ foreach ( var file in expectedFiles . Except ( generatedFiles ) )
70
+ {
71
+ Assert . Fail ( $ "Test Failed \n Missing expected file in { generatedDir } : { file } ") ;
72
+ }
73
+ Console . WriteLine ( "Test Succeeded" ) ;
74
+ }
75
+
76
+ private static bool IsJsonContentIncluded ( string generatedFilePath , string expectedFilePath )
77
+ {
78
+ var generatedJson = JToken . Parse ( File . ReadAllText ( generatedFilePath ) ) ;
79
+ var expectedJson = JToken . Parse ( File . ReadAllText ( expectedFilePath ) ) ;
80
+
81
+ return IsSubset ( expectedJson , generatedJson ) ;
82
+ }
83
+
84
+ private static bool IsSubset ( JToken subset , JToken superset )
85
+ {
86
+ if ( JToken . DeepEquals ( subset , superset ) )
87
+ {
88
+ return true ;
89
+ }
90
+
91
+ if ( subset . Type == JTokenType . Object && superset . Type == JTokenType . Object )
92
+ {
93
+ var subsetObj = ( JObject ) subset ;
94
+ var supersetObj = ( JObject ) superset ;
95
+
96
+ foreach ( var property in subsetObj . Properties ( ) )
97
+ {
98
+ if ( ! supersetObj . TryGetValue ( property . Name , out var supersetValue ) || ! IsSubset ( property . Value , supersetValue ) )
99
+ {
100
+ return false ;
101
+ }
102
+ }
103
+
104
+ return true ;
105
+ }
106
+
107
+ if ( subset . Type == JTokenType . Array && superset . Type == JTokenType . Array )
108
+ {
109
+ var subsetArray = ( JArray ) subset ;
110
+ var supersetArray = ( JArray ) superset ;
111
+
112
+ foreach ( var subsetItem in subsetArray )
113
+ {
114
+ if ( ! supersetArray . Any ( supersetItem => IsSubset ( subsetItem , supersetItem ) ) )
115
+ {
116
+ return false ;
117
+ }
118
+ }
119
+
120
+ return true ;
121
+ }
122
+
123
+ return false ;
124
+ }
125
+ }
0 commit comments