1
+ using System ;
2
+ using System . IO ;
3
+ using System . Linq ;
4
+ using Newtonsoft . Json . Linq ;
5
+ using NUnit . Framework ;
6
+ using PChecker ;
7
+ using UnitTests . Core ;
8
+ using UnitTests . Runners ;
9
+ using Plang . Options ;
10
+ namespace UnitTests ;
11
+
12
+ [ TestFixture ]
13
+ [ Parallelizable ( ParallelScope . Children ) ]
14
+ public class PCheckerLogGeneratorTests
15
+ {
16
+ [ Test ]
17
+ public void TestLogGenerator ( )
18
+ {
19
+ var tempDir = Directory . CreateDirectory ( Path . Combine ( Constants . ScratchParentDirectory , "TestLogGenerator" ) ) ;
20
+ var srcPath = new FileInfo ( Path . Combine ( Constants . SolutionDirectory , "Tst" , "RegressionTests" ,
21
+ "Feature1SMLevelDecls" , "DynamicError" , "bug2" , "bug2.p" ) ) ;
22
+ var dllPath = Path . Combine ( Constants . ScratchParentDirectory , "TestLogGenerator" , "CSharp" , "net8.0" , "Main.dll" ) ;
23
+ var expectedPath = Path . Combine ( Constants . SolutionDirectory , "Tst" , "CorrectLogs" , "bugs2" ) ;
24
+
25
+ var runner = new PCheckerRunner ( [ srcPath ] ) ;
26
+ runner . DoCompile ( tempDir ) ;
27
+
28
+ var configuration = new PCheckerOptions ( ) . Parse ( [ dllPath , "-o" , tempDir . ToString ( ) ] ) ;
29
+ Checker . Run ( configuration ) ;
30
+
31
+ AssertLog ( tempDir + "/BugFinding" , expectedPath ) ;
32
+ TestAssertions . SafeDeleteDirectory ( tempDir ) ;
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
+ }
74
+
75
+ private static bool IsJsonContentIncluded ( string generatedFilePath , string expectedFilePath )
76
+ {
77
+ var generatedJson = JToken . Parse ( File . ReadAllText ( generatedFilePath ) ) ;
78
+ var expectedJson = JToken . Parse ( File . ReadAllText ( expectedFilePath ) ) ;
79
+
80
+ return IsSubset ( expectedJson , generatedJson ) ;
81
+ }
82
+
83
+ private static bool IsSubset ( JToken subset , JToken superset )
84
+ {
85
+ if ( JToken . DeepEquals ( subset , superset ) )
86
+ {
87
+ return true ;
88
+ }
89
+
90
+ if ( subset . Type == JTokenType . Object && superset . Type == JTokenType . Object )
91
+ {
92
+ var subsetObj = ( JObject ) subset ;
93
+ var supersetObj = ( JObject ) superset ;
94
+
95
+ foreach ( var property in subsetObj . Properties ( ) )
96
+ {
97
+ if ( ! supersetObj . TryGetValue ( property . Name , out var supersetValue ) || ! IsSubset ( property . Value , supersetValue ) )
98
+ {
99
+ return false ;
100
+ }
101
+ }
102
+
103
+ return true ;
104
+ }
105
+
106
+ if ( subset . Type == JTokenType . Array && superset . Type == JTokenType . Array )
107
+ {
108
+ var subsetArray = ( JArray ) subset ;
109
+ var supersetArray = ( JArray ) superset ;
110
+
111
+ foreach ( var subsetItem in subsetArray )
112
+ {
113
+ if ( ! supersetArray . Any ( supersetItem => IsSubset ( subsetItem , supersetItem ) ) )
114
+ {
115
+ return false ;
116
+ }
117
+ }
118
+
119
+ return true ;
120
+ }
121
+
122
+ return false ;
123
+ }
124
+ }
0 commit comments