1+ """Tests the behavior of the GNATfuzz integration, on the
2+ "fuzz" parts of the workflow.
3+ """
4+
5+ from distutils .log import debug
6+ from gs_utils .internal .utils import (
7+ run_test_driver ,
8+ timeout ,
9+ get_button_from_label ,
10+ get_widget_by_name ,
11+ get_window_by_title ,
12+ gps_assert ,
13+ idle_modal_dialog ,
14+ wait_for_mdi_child ,
15+ )
16+ from pygps import double_click_events
17+ from pygps .tree import click_in_tree
18+
19+ INCREMENTS_MS = 1000 # Timeout increments
20+ MAX_TIME_MS = 20 * 1000 # Max timeout wait
21+
22+ @run_test_driver
23+ def driver ():
24+ # Launch a fuzzing session
25+ yield idle_modal_dialog (lambda : GPS .execute_action ("gnatfuzz fuzz workflow" ))
26+ yield wait_for_mdi_child ("gnatfuzz fuzz" )
27+ dialog = get_window_by_title ("gnatfuzz fuzz" )
28+ get_button_from_label ("Execute" , dialog ).clicked ()
29+
30+ yield wait_for_mdi_child ("Fuzz Crashes" )
31+
32+ view = get_widget_by_name ("fuzz_crash_list_view" )
33+ model = view .get_model ()
34+
35+ # Wait 20 seconds at most, until messages appear in the "Fuzz crashes" view
36+
37+ time_waited = 0
38+
39+ while time_waited < MAX_TIME_MS :
40+ if len (model ) > 0 :
41+ break
42+ yield timeout (INCREMENTS_MS )
43+ time_waited += INCREMENTS_MS
44+
45+ # Test the contents of the model: presence of the crash...
46+ gps_assert (model [0 ][0 ], "1 (Crash)" , "wrong contents in the first row" )
47+
48+ # ... and the fact that the faulty parameter (causing integer overflow)
49+ # is properly found by the fuzzer and displayed in the view.
50+ gps_assert (
51+ int (model [0 , 0 ][1 ]),
52+ 2 ** 31 - 1 ,
53+ "wrong value for the parameter which causes the crash" ,
54+ )
55+
56+ # We can stop fuzzing now that we've had one crash
57+ GPS .execute_action ("gnatfuzz fuzz workflow" )
58+
59+ # Click in the view to launch a debug workflow
60+ click_in_tree (view , path = "0" , events = double_click_events )
61+
62+ # Wait 20 seconds at most, until we have the right data in the debugger view
63+
64+ debugger_text = None
65+
66+ time_waited = 0
67+
68+ expected_text = "Y := X + 1"
69+
70+ while time_waited < MAX_TIME_MS :
71+ yield timeout (INCREMENTS_MS )
72+ time_waited += INCREMENTS_MS
73+ d = None
74+ try :
75+ d = GPS .Debugger .get ()
76+ except GPS .Exception :
77+ pass
78+ if d is None :
79+ continue
80+ debugger_text = d .get_console ().get_text ()
81+
82+ # The debugger console should contain this
83+ if expected_text in debugger_text :
84+ break
85+
86+
87+ gps_assert (expected_text in debugger_text , True ,
88+ f"{ expected_text } didn't appear in output:\n { debugger_text } " )
0 commit comments