@@ -139,25 +139,18 @@ def test_end_to_end_symbol_reachability_pipeline(
139139 finally :
140140 shutil .rmtree (vcs_dir , ignore_errors = True )
141141
142- @patch ("scanpipe.pipes.reachability.GitRepositoryContext" )
143- @patch ("scanpipe.pipes.reachability.PatchAnalyzer.collect_patch_symbols" )
144- @patch .object (Project , "package_vulnerabilities" , new_callable = PropertyMock )
145- def test_python_get_symbol_reachability_results (
142+ def _run_reachability_pipeline (
146143 self ,
147144 mock_package_vulnerabilities ,
148145 mock_collect_symbols ,
149146 mock_git_context ,
147+ file_path ,
148+ app_text ,
149+ vuln_text ,
150+ fixed_text ,
151+ expected_results ,
150152 ):
151- """
152- Test the end-to-end reachability pipeline by analyzing a patch,
153- computing symbol reachability, and storing the results on the
154- corresponding codebase resource.
155- """
156- file_path = "app.py"
157- app_text = (self .data / "python" / file_path ).read_text ()
158- vuln_text = (self .data / "python" / "vuln-app.py" ).read_text ()
159- fixed_text = (self .data / "python" / "fixed-app.py" ).read_text ()
160-
153+ """Shared helper to run the end-to-end reachability pipeline."""
161154 analyzer = PatchAnalyzer (repo = MagicMock (), commit_hash = "dummy" )
162155
163156 removed_lines , added_lines = analyzer .compute_changed_lines (
@@ -173,6 +166,7 @@ def test_python_get_symbol_reachability_results(
173166
174167 self .assertTrue (lang )
175168 self .assertTrue (vuln_meta or fixed_meta )
169+
176170 mock_package_vulnerabilities .return_value = [
177171 {
178172 "fixed_in_patches" : [
@@ -198,71 +192,96 @@ def test_python_get_symbol_reachability_results(
198192 }
199193 }
200194
201- resource_file = self .project1 .codebase_path / "app.py"
195+ resource_file = self .project1 .codebase_path / file_path
196+ resource_file .parent .mkdir (parents = True , exist_ok = True )
202197 resource_file .write_text (app_text )
203198 collect_and_create_codebase_resources (self .project1 )
204199
205- resource = self .project1 .codebaseresources .get (path = "app.py" )
200+ resource = self .project1 .codebaseresources .get (path = file_path )
206201 resource .programming_language = lang
207202 resource .save ()
208203
209204 analyze_and_store_symbol_reachability_results (self .project1 )
210205
211206 resource .refresh_from_db ()
212207 results = resource .extra_data .get ("symbols_reachability" )
208+ self .assertEqual (results , expected_results )
213209
214- self .assertEqual (
215- results ,
216- [
217- {
218- "symbols_reachability" : {
219- "patch" : {
220- "vcs_url" : "https://github.com/aboutcode-org/test" ,
221- "commit_hash" : "07ec0de1964b14bf085a1c9a27ece2b61ab6105c" ,
210+ @patch ("scanpipe.pipes.reachability.GitRepositoryContext" )
211+ @patch ("scanpipe.pipes.reachability.PatchAnalyzer.collect_patch_symbols" )
212+ @patch .object (Project , "package_vulnerabilities" , new_callable = PropertyMock )
213+ def test_python_get_symbol_reachability_results (
214+ self ,
215+ mock_package_vulnerabilities ,
216+ mock_collect_symbols ,
217+ mock_git_context ,
218+ ):
219+ """Test the end-to-end reachability pipeline for Python."""
220+ file_path = "app.py"
221+ app_text = (self .data / "python" / file_path ).read_text ()
222+ vuln_text = (self .data / "python" / "vuln-app.py" ).read_text ()
223+ fixed_text = (self .data / "python" / "fixed-app.py" ).read_text ()
224+
225+ expected_results = [
226+ {
227+ "symbols_reachability" : {
228+ "patch" : {
229+ "vcs_url" : "https://github.com/aboutcode-org/test" ,
230+ "commit_hash" : "07ec0de1964b14bf085a1c9a27ece2b61ab6105c" ,
231+ },
232+ "evidence" : [
233+ {
234+ "called" : False ,
235+ "defined" : True ,
236+ "imported" : False ,
237+ "fingerprint" : "336908735214468b103dbde"
238+ "11c3ffbd2f76ac9212b8514f831cfa078a67892df" ,
239+ "symbol_name" : "debug" ,
240+ "reachable_from" : [],
222241 },
223- "evidence" : [
224- {
225- "called" : False ,
226- "defined" : True ,
227- "imported" : False ,
228- "fingerprint" : "336908735214468b103dbde"
229- "11c3ffbd2f76ac9212b8514f831cfa078a67892df" ,
230- "symbol_name" : "debug" ,
231- "reachable_from" : [],
232- },
233- {
234- "called" : True ,
235- "defined" : True ,
236- "imported" : False ,
237- "fingerprint" : "762e4f7d03b1bf4359c3ca364"
238- "e558140239913bfabcc5aa77156460c2eb0a355" ,
239- "symbol_name" : "serve_report.build_file_path" ,
240- "reachable_from" : ["serve_report" ],
241- },
242- {
243- "called" : False ,
244- "defined" : True ,
245- "imported" : False ,
246- "fingerprint" : "d7675efb263896da2a3c0067951183"
247- "3553907e7e6ea619115a6dfc8625c3457e" ,
248- "symbol_name" : "serve_report" ,
249- "reachable_from" : [],
250- },
251- ],
252- "fixed_symbols" : [
253- "debug" ,
254- "serve_report" ,
255- "serve_report.build_file_path" ,
256- ],
257- "vulnerable_symbols" : [
258- "debug" ,
259- "serve_report" ,
260- "serve_report.build_file_path" ,
261- ],
262- "reachability_status" : "REACHABLE" ,
263- }
242+ {
243+ "called" : True ,
244+ "defined" : True ,
245+ "imported" : False ,
246+ "fingerprint" : "762e4f7d03b1bf4359c3ca364"
247+ "e558140239913bfabcc5aa77156460c2eb0a355" ,
248+ "symbol_name" : "serve_report.build_file_path" ,
249+ "reachable_from" : ["serve_report" ],
250+ },
251+ {
252+ "called" : False ,
253+ "defined" : True ,
254+ "imported" : False ,
255+ "fingerprint" : "d7675efb263896da2a3c0067951183"
256+ "3553907e7e6ea619115a6dfc8625c3457e" ,
257+ "symbol_name" : "serve_report" ,
258+ "reachable_from" : [],
259+ },
260+ ],
261+ "fixed_symbols" : [
262+ "debug" ,
263+ "serve_report" ,
264+ "serve_report.build_file_path" ,
265+ ],
266+ "vulnerable_symbols" : [
267+ "debug" ,
268+ "serve_report" ,
269+ "serve_report.build_file_path" ,
270+ ],
271+ "reachability_status" : "REACHABLE" ,
264272 }
265- ],
273+ }
274+ ]
275+
276+ self ._run_reachability_pipeline (
277+ mock_package_vulnerabilities ,
278+ mock_collect_symbols ,
279+ mock_git_context ,
280+ file_path ,
281+ app_text ,
282+ vuln_text ,
283+ fixed_text ,
284+ expected_results ,
266285 )
267286
268287 @patch ("scanpipe.pipes.reachability.GitRepositoryContext" )
@@ -274,120 +293,70 @@ def test_java_get_symbol_reachability_results(
274293 mock_collect_symbols ,
275294 mock_git_context ,
276295 ):
277- """
278- Test the end-to-end reachability pipeline by analyzing a patch,
279- computing symbol reachability, and storing the results on the
280- corresponding codebase resource.
281- """
296+ """Test the end-to-end reachability pipeline for Java."""
282297 file_path = "app.java"
283298 app_text = (self .data / "java" / file_path ).read_text ()
284299 vuln_text = (self .data / "java" / "vuln-app.java" ).read_text ()
285300 fixed_text = (self .data / "java" / "fixed-app.java" ).read_text ()
286301
287- analyzer = PatchAnalyzer (repo = MagicMock (), commit_hash = "dummy" )
288-
289- removed_lines , added_lines = analyzer .compute_changed_lines (
290- vulnerable_text = vuln_text , fixed_text = fixed_text
291- )
292- vuln_meta , fixed_meta , lang = analyzer .analyze (
293- vulnerable_text = vuln_text ,
294- fixed_text = fixed_text ,
295- removed_lines = removed_lines ,
296- added_lines = added_lines ,
297- file_path = file_path ,
298- )
299-
300- self .assertTrue (lang )
301- self .assertTrue (vuln_meta or fixed_meta )
302- mock_package_vulnerabilities .return_value = [
302+ expected_results = [
303303 {
304- "fixed_in_patches " : [
305- {
304+ "symbols_reachability " : {
305+ "patch" : {
306306 "vcs_url" : "https://github.com/aboutcode-org/test" ,
307307 "commit_hash" : "07ec0de1964b14bf085a1c9a27ece2b61ab6105c" ,
308- }
309- ]
308+ },
309+ "evidence" : [
310+ {
311+ "called" : False ,
312+ "defined" : True ,
313+ "imported" : False ,
314+ "fingerprint" : None ,
315+ "symbol_name" : "App" ,
316+ "reachable_from" : [],
317+ },
318+ {
319+ "called" : False ,
320+ "defined" : True ,
321+ "imported" : False ,
322+ "fingerprint" : "b161e24e9575b655e84c7f249709e5d4d0"
323+ "a1e6f19e2c4baa421a6cc996fda154" ,
324+ "symbol_name" : "App.serveReport" ,
325+ "reachable_from" : [],
326+ },
327+ {
328+ "called" : True ,
329+ "defined" : True ,
330+ "imported" : False ,
331+ "fingerprint" : None ,
332+ "symbol_name" : "App.buildFilePath" ,
333+ "reachable_from" : ["App.serveReport" ],
334+ },
335+ ],
336+ "fixed_symbols" : [
337+ "App" ,
338+ "App.buildFilePath" ,
339+ "App.serveReport" ,
340+ ],
341+ "vulnerable_symbols" : [
342+ "App" ,
343+ "App.buildFilePath" ,
344+ "App.serveReport" ,
345+ ],
346+ "reachability_status" : "REACHABLE" ,
347+ }
310348 }
311349 ]
312350
313- mock_git_context .return_value .__enter__ .return_value .repo = MagicMock ()
314- mock_collect_symbols .return_value = {
315- lang : {
316- "vulnerable" : {
317- f"{ file_path } ::{ key } " : metadata
318- for key , metadata in vuln_meta .items ()
319- },
320- "fixed" : {
321- f"{ file_path } ::{ key } " : metadata
322- for key , metadata in fixed_meta .items ()
323- },
324- }
325- }
326-
327- resource_file = self .project1 .codebase_path / "app.java"
328- resource_file .parent .mkdir (parents = True , exist_ok = True )
329- resource_file .write_text (app_text )
330- collect_and_create_codebase_resources (self .project1 )
331-
332- resource = self .project1 .codebaseresources .get (path = "app.java" )
333- resource .programming_language = lang
334- resource .save ()
335-
336- analyze_and_store_symbol_reachability_results (self .project1 )
337-
338- resource .refresh_from_db ()
339- results = resource .extra_data .get ("symbols_reachability" )
340-
341- self .assertEqual (
342- results ,
343- [
344- {
345- "symbols_reachability" : {
346- "patch" : {
347- "vcs_url" : "https://github.com/aboutcode-org/test" ,
348- "commit_hash" : "07ec0de1964b14bf085a1c9a27ece2b61ab6105c" ,
349- },
350- "evidence" : [
351- {
352- "called" : False ,
353- "defined" : True ,
354- "imported" : False ,
355- "fingerprint" : None ,
356- "symbol_name" : "App" ,
357- "reachable_from" : [],
358- },
359- {
360- "called" : False ,
361- "defined" : True ,
362- "imported" : False ,
363- "fingerprint" : "b161e24e9575b655e84c7f249709e5d4d0"
364- "a1e6f19e2c4baa421a6cc996fda154" ,
365- "symbol_name" : "App.serveReport" ,
366- "reachable_from" : [],
367- },
368- {
369- "called" : True ,
370- "defined" : True ,
371- "imported" : False ,
372- "fingerprint" : None ,
373- "symbol_name" : "App.buildFilePath" ,
374- "reachable_from" : ["App.serveReport" ],
375- },
376- ],
377- "fixed_symbols" : [
378- "App" ,
379- "App.buildFilePath" ,
380- "App.serveReport" ,
381- ],
382- "vulnerable_symbols" : [
383- "App" ,
384- "App.buildFilePath" ,
385- "App.serveReport" ,
386- ],
387- "reachability_status" : "REACHABLE" ,
388- }
389- }
390- ],
351+ self ._run_reachability_pipeline (
352+ mock_package_vulnerabilities ,
353+ mock_collect_symbols ,
354+ mock_git_context ,
355+ file_path ,
356+ app_text ,
357+ vuln_text ,
358+ fixed_text ,
359+ expected_results ,
391360 )
392361
393362 def test_extract_definitions (self ):
0 commit comments