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
740
841
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-
16342
16443if __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