1
- from Assignment1 import *
2
- def check_icfg_case (module_name , result , expected ):
3
- assert len (result ) == len (expected ), f"Wrong paths generated - { module_name } failed!"
4
- for path in result :
5
- assert path in expected , f"Wrong paths generated - { module_name } failed!"
6
- print (f"Test case { module_name } passed!" )
1
+ import os
2
+ import subprocess
3
+ import glob
4
+
5
+ def run_tests (Failed_test_cases :list = []):
6
+ assert isinstance (Failed_test_cases , list ), "L should be a list"
7
+ # Define the base directory containing the test cases
8
+ base_dir = os .path .dirname (__file__ )
9
+ total_test_cases = 0
10
+ # Define test case types and their corresponding subdirectories and flags
11
+ test_types = {
12
+ "pta" : {"subdir" : "../Tests/testcases/pta" , "flag" : "-pta" },
13
+ "icfg" : {"subdir" : "../Tests/testcases/icfg" , "flag" : "-icfg" },
14
+ "taint" : {"subdir" : "../Tests/testcases/taint" , "flag" : "-taint" },
15
+ }
16
+ # Iterate over each test type
17
+ for test_type , config in test_types .items ():
18
+ testcases_dir = os .path .join (base_dir , config ["subdir" ])
19
+ test_files = glob .glob (os .path .join (testcases_dir , "*.ll" ))
20
+
21
+ # Run tests for each file in the test type
22
+ for filename in test_files :
23
+ print (f"Adding Python test for { test_type } : { filename } " )
24
+ total_test_cases += 1
25
+ # Construct the command to run the test
26
+ main_py_path = os .path .join (os .path .dirname (__file__ ), "Main.py" )
27
+ command = [
28
+ "python3" , main_py_path , config ["flag" ], filename
29
+ ]
30
+
31
+ # Run the command and capture the output
32
+ result = subprocess .run (command , cwd = os .path .join (base_dir , ".." ), text = True )
33
+ # Check the result
34
+ if result .returncode == 0 :
35
+ print (f"Test passed for { filename } " )
36
+ else :
37
+ Failed_test_cases .append (filename )
38
+ #assert False, f"Test failed for {filename} with error code {result.returncode}"
39
+ return total_test_cases
7
40
8
41
9
- def test_icfg (module_name_vec ):
10
- pag = pysvf .get_pag (module_name_vec ) # Build Program Assignment Graph (SVFIR)
11
- icfg = pag .get_icfg () # Get ICFG
12
- gt = Ass1_ICFGTraversal (pag ) # Create ICFG Traversal object
13
-
14
- config_path = os .path .join (os .path .dirname (__file__ ), "../Tests/SrcSnk.txt" )
15
- gt .read_srcsnk_from_file (config_path )
16
-
17
- for src in gt .identify_sources ():
18
- for snk in gt .identify_sinks ():
19
- gt .reachability (src , snk )
20
-
21
- module_name = os .path .basename (module_name_vec )
22
- if module_name == "test1.ll" :
23
- expected = {"START->3->4->5->END" }
24
- check_icfg_case (module_name , gt .get_paths (), expected )
25
- elif module_name == "test2.ll" :
26
- expected = {
27
- "START->3->4->5->6->7->8->9->END" ,
28
- "START->3->4->5->6->7->END" ,
29
- "START->5->6->7->8->9->END" ,
30
- "START->5->6->7->END"
31
- }
32
- check_icfg_case (module_name , gt .get_paths (), expected )
33
- elif module_name == "test3.ll" :
34
- expected = {"START->6->7->8->1->5->2->9->10->END" }
35
- check_icfg_case (module_name , gt .get_paths (), expected )
36
- elif module_name == "test4.ll" :
37
- expected = {"START->12->13->14->3->8->9->1->7->2->10->11->4->15->16->END" }
38
- check_icfg_case (module_name , gt .get_paths (), expected )
39
- # Add further test cases as needed...
40
- elif module_name == "test5.ll" :
41
- expected = {
42
- "START->6->7->8->9->10->1->5->2->11->14->END" ,
43
- "START->6->7->8->9->12->1->5->2->13->16->END" ,
44
- }
45
- check_icfg_case (module_name , gt .get_paths (), expected )
46
- elif module_name == "test6.ll" :
47
- expected = {
48
- "START->12->13->14->15->16->3->8->9->1->7->2->10->11->4->17->20->END" ,
49
- "START->12->13->14->15->18->3->8->9->1->7->2->10->11->4->19->22->END" ,
50
- }
51
- check_icfg_case (module_name , gt .get_paths (), expected )
52
- elif module_name == "test7.ll" :
53
- expected = {"START->17->1->7->END" }
54
- check_icfg_case (module_name , gt .get_paths (), expected )
55
- elif module_name == "test8.ll" :
56
- expected = {
57
- "START->6->7->8->9->10->1->5->2->11->14->END" ,
58
- "START->6->7->8->9->12->1->5->2->13->16->END" ,
59
- }
60
- check_icfg_case (module_name , gt .get_paths (), expected )
61
- elif module_name == "test9.ll" :
62
- expected = {"START->7->8->9->10->11->14->END" }
63
- check_icfg_case (module_name , gt .get_paths (), expected )
64
- elif module_name == "test10.ll" :
65
- expected = {
66
- "START->3->4->5->6->7->9->11->END" ,
67
- "START->3->4->5->6->8->10->14->17->END" ,
68
- }
69
- check_icfg_case (module_name , gt .get_paths (), expected )
70
-
71
- else :
72
- print (f"Test case { module_name } not found!" )
73
-
74
-
75
- def test_pta (module_name_vec ):
76
- pag = pysvf .get_pag (module_name_vec ) # Build Program Assignment Graph (SVFIR)
77
- andersen_pta = Ass1_Andersen (pag )
78
- andersen_pta .analyze () # Run Andersen pointer analysis
79
- del andersen_pta
80
-
81
-
82
- def test_taint (module_name_vec ):
83
- pag = pysvf .get_pag (module_name_vec ) # Build Program Assignment Graph (SVFIR)
84
-
85
- taint = Ass1_ICFGTraversal (pag )
86
- taint .taint_checking () # Perform taint analysis
87
-
88
- module_name_vec = os .path .basename (module_name_vec )
89
- print (taint .get_paths ())
90
- if module_name_vec == "test1.ll" :
91
- expected = {"START->6->1->5->2->7->8->9->10->END" }
92
- assert taint .get_paths () == expected , " \n wrong paths generated - test1 failed !"
93
- print ("\n test1 passed !" )
94
- elif module_name_vec == "test4.ll" :
95
- expected = {"START->6->1->5->2->7->8->9->10->11->13->14->END" }
96
- assert taint .get_paths () == expected , " \n wrong paths generated - test4 failed !"
97
- print ("\n test2 passed !" )
98
- elif module_name_vec == "test2.ll" or module_name_vec == "test3.ll" :
99
- expected = set ()
100
- assert taint .get_paths () == expected , " \n wrong paths generated - test2 or test3 failed !"
101
- print ("\n test2 or test3 passed !" )
102
-
103
-
104
- print (f"###################### Tainted Information Flow ({ len (taint .get_paths ())} found) ######################" )
105
- print ("---------------------------------------------" )
106
- for path in taint .get_paths ():
107
- origin_path = path
108
- prefix = "START->"
109
- suffix = "->END"
110
-
111
- if path .startswith (prefix ):
112
- path = path [len (prefix ):]
113
- if path .endswith (suffix ):
114
- path = path [:- len (suffix )]
115
-
116
- tokens = path .split ("->" )
117
- src_id = int (tokens [0 ])
118
- dst_id = int (tokens [- 1 ])
119
- src_node = pag .get_icfg ().get_gnode (src_id )
120
- dst_node = pag .get_icfg ().get_gnode (dst_id )
121
-
122
- print (
123
- f"{ origin_path } \n Source: { src_node .to_string ()} \n Sink: { dst_node .to_string ()} \n ---------------------------------------------" )
124
-
125
- if not taint .get_paths ():
126
- print ("No tainted information flow found" )
127
-
128
-
129
- def main ():
130
- pta_enabled = False
131
- taint_enabled = False
132
- icfg_enabled = False
133
- module_name_vec = ""
134
-
135
- args = sys .argv [1 :]
136
-
137
- for arg in args :
138
- if arg == "-pta" :
139
- pta_enabled = True
140
- elif arg == "-taint" :
141
- taint_enabled = True
142
- elif arg == "-icfg" :
143
- icfg_enabled = True
144
- else :
145
- module_name_vec = arg
146
-
147
- # Default to taint analysis if none specified
148
- if not (pta_enabled or taint_enabled or icfg_enabled ):
149
- assert False , "No analysis specified. Please specify -pta, -taint, or -icfg."
150
-
151
- assert (pta_enabled + taint_enabled + icfg_enabled ) == 1 , "Only one analysis can be enabled."
152
-
153
- if module_name_vec == "" :
154
- assert False , "No module specified. Please specify a module to analyze."
155
-
156
- if pta_enabled :
157
- test_pta (module_name_vec )
158
- elif taint_enabled :
159
- test_taint (module_name_vec )
160
- elif icfg_enabled :
161
- test_icfg (module_name_vec )
162
-
163
42
164
43
if __name__ == "__main__" :
165
- main ()
44
+ Failed_test_cases = []
45
+ total_test_cases = 0
46
+ total_test_cases += run_tests (Failed_test_cases )
47
+ if len (Failed_test_cases ) == 0 :
48
+ print ("\033 [92mAll tests passed!\033 [0m" )
49
+ else :
50
+ print (f"\033 [91m { len (Failed_test_cases )} out of { total_test_cases } failed\033 [0m" )
51
+ print ("\033 [91mFailed tests are:\033 [0m" )
52
+ for failed_test_case in Failed_test_cases :
53
+ print (f"\033 [91m{ failed_test_case } \033 [0m" )
0 commit comments