1212import org .eclipse .lsp4j .MessageType ;
1313import org .junit .jupiter .api .Test ;
1414import org .junit .jupiter .api .extension .ExtendWith ;
15+ import org .mockito .Mock ;
16+ import org .mockito .Spy ;
1517import uk .org .webcompere .systemstubs .jupiter .SystemStub ;
1618import uk .org .webcompere .systemstubs .jupiter .SystemStubsExtension ;
1719import uk .org .webcompere .systemstubs .stream .SystemOut ;
2931@ ExtendWith (SystemStubsExtension .class )
3032class GoblintAnalysisTest {
3133
34+ @ Mock
35+ MagpieServer magpieServer = mock (MagpieServer .class );
36+ @ Mock
37+ GoblintService goblintService = mock (GoblintService .class );
38+ @ Mock
39+ GobPieConfiguration gobPieConfiguration = mock (GobPieConfiguration .class );
40+ @ Spy
41+ GoblintServer goblintServer = spy (new GoblintServer (magpieServer , gobPieConfiguration ));
42+ @ Mock
43+ GoblintConfWatcher goblintConfWatcher = mock (GoblintConfWatcher .class );
44+ GoblintAnalysis goblintAnalysis = new GoblintAnalysis (magpieServer , goblintServer , goblintService , gobPieConfiguration , goblintConfWatcher );
45+ // Mock the arguments (files and analysisConsumer) for calling the GoblintAnalyze.analyze method
46+ Collection <? extends Module > files = new ArrayDeque <>();
47+ AnalysisConsumer analysisConsumer = mock (AnalysisConsumer .class );
3248 @ SystemStub
3349 private SystemOut systemOut ;
3450
35- @ Test
36- void analyzeFailed () {
37- // Mock everything needed for creating GoblintAnalysis
38- MagpieServer magpieServer = mock (MagpieServer .class );
39- GoblintServer goblintServer = mock (GoblintServer .class );
40- GoblintService goblintService = mock (GoblintService .class );
41- GobPieConfiguration gobPieConfiguration = mock (GobPieConfiguration .class );
42- GoblintConfWatcher goblintConfWatcher = mock (GoblintConfWatcher .class );
43- GoblintAnalysis goblintAnalysis = new GoblintAnalysis (magpieServer , goblintServer , goblintService , gobPieConfiguration , goblintConfWatcher );
44-
45- // Mock that GoblintServer is alive and everything is fine with Goblint's configuration file
51+ /**
52+ * A function to mock that GoblintServer is alive
53+ * and Goblint's configuration file is ok.
54+ */
55+ private void mockGoblintServerIsAlive (GoblintServer goblintServer ) {
4656 doReturn (true ).when (goblintServer ).isAlive ();
4757 when (goblintConfWatcher .refreshGoblintConfig ()).thenReturn (true );
58+ }
59+
60+ /**
61+ * Mock test to ensure @analyze function
62+ * messages user when analyzes fails
63+ */
64+ @ Test
65+ void analyzeFailed () {
66+ mockGoblintServerIsAlive (goblintServer );
4867
4968 // Mock that the analyses of Goblint have started and completed
5069 when (goblintService .analyze (new AnalyzeParams (false ))).thenReturn (CompletableFuture .failedFuture (new Throwable (" Testing failed analysis" )));
5170
5271 // Mock that the incremental analysis is turned off (TODO: not sure why this is checked in reanalyze?)
5372 when (gobPieConfiguration .useIncrementalAnalysis ()).thenReturn (true );
5473
55- // Mock the arguments for calling the goblintAnalyze.analyze method
56- // And call the method twice
57- Collection <? extends Module > files = new ArrayDeque <>();
58- AnalysisConsumer analysisConsumer = mock (AnalysisConsumer .class );
59- goblintAnalysis .analyze (files , null , true );
74+ goblintAnalysis .analyze (files , analysisConsumer , true );
6075
6176 // Verify that Analysis has failed
6277 assertTrue (systemOut .getLines ().anyMatch (line -> line .contains ("---------------------- Analysis started ----------------------" )));
@@ -67,25 +82,17 @@ void analyzeFailed() {
6782 verify (magpieServer ).forwardMessageToClient (new MessageParams (MessageType .Error , "GobPie failed to analyze the code:\n Testing failed analysis" ));
6883 }
6984
70-
7185 /**
7286 * Mock test to ensure @analyze function
7387 * behaviour in abort situation
7488 */
7589 @ Test
7690 void abortAnalysis () throws IOException {
77- // Mock everything needed for creating GoblintAnalysis
78- MagpieServer magpieServer = mock (MagpieServer .class );
91+ // Mock server and change goblintAnalysis value
7992 GoblintServer goblintServer = mock (GoblintServer .class );
80- GoblintService goblintService = mock (GoblintService .class );
81- GobPieConfiguration gobPieConfiguration = mock (GobPieConfiguration .class );
82- GoblintConfWatcher goblintConfWatcher = mock (GoblintConfWatcher .class );
83-
8493 GoblintAnalysis goblintAnalysis = new GoblintAnalysis (magpieServer , goblintServer , goblintService , gobPieConfiguration , goblintConfWatcher );
8594
86- // Mock that GoblintServer is alive and everything is fine with Goblint's configuration file
87- doReturn (true ).when (goblintServer ).isAlive ();
88- when (goblintConfWatcher .refreshGoblintConfig ()).thenReturn (true );
95+ mockGoblintServerIsAlive (goblintServer );
8996
9097 // Mock that the analyses of Goblint have started but not completed (still run)
9198 CompletableFuture <GoblintAnalysisResult > runningProcess = new CompletableFuture <>();
@@ -94,10 +101,7 @@ void abortAnalysis() throws IOException {
94101 // Mock that the incremental analysis is turned off (TODO: not sure why this is checked in reanalyze?)
95102 when (gobPieConfiguration .useIncrementalAnalysis ()).thenReturn (true );
96103
97- // Mock the arguments for calling the goblintAnalyze.analyze method
98- // And call the method twice
99- Collection <? extends Module > files = new ArrayDeque <>();
100- AnalysisConsumer analysisConsumer = mock (AnalysisConsumer .class );
104+ // Call analyze method twice
101105 goblintAnalysis .analyze (files , analysisConsumer , true );
102106 goblintAnalysis .analyze (files , analysisConsumer , true );
103107
@@ -107,24 +111,45 @@ void abortAnalysis() throws IOException {
107111 runningProcess .complete (null );
108112 }
109113
114+ /**
115+ * Mock test to ensure @analyze function
116+ * behaves correctly when abort fails
117+ */
118+ @ Test
119+ void abortAnalysisFails () throws IOException {
120+ // Mock server and change goblintAnalysis value
121+ GoblintServer goblintServer = mock (GoblintServer .class );
122+ GoblintAnalysis goblintAnalysis = new GoblintAnalysis (magpieServer , goblintServer , goblintService , gobPieConfiguration , goblintConfWatcher );
123+
124+ mockGoblintServerIsAlive (goblintServer );
125+
126+ // Mock that the analyses of Goblint have started but not completed (still run)
127+ CompletableFuture <GoblintAnalysisResult > runningProcess = new CompletableFuture <>();
128+ when (goblintService .analyze (new AnalyzeParams (false ))).thenReturn (runningProcess );
129+
130+ // Mock that the incremental analysis is turned off (TODO: not sure why this is checked in reanalyze?)
131+ when (gobPieConfiguration .useIncrementalAnalysis ()).thenReturn (true );
132+
133+ // Mock that abortAnalysis throws an exception when called
134+ doThrow (new IOException ()).when (goblintServer ).abortAnalysis ();
135+
136+ // Call analyze method twice
137+ goblintAnalysis .analyze (files , analysisConsumer , true );
138+ goblintAnalysis .analyze (files , analysisConsumer , true );
139+
140+ // Verify that abortAnalysis was indeed called once
141+ verify (goblintServer ).abortAnalysis ();
142+ assertTrue (systemOut .getLines ().anyMatch (line -> line .contains ("Aborting analysis failed." )));
143+ runningProcess .complete (null );
144+ }
145+
110146 /**
111147 * Mock test to ensure @preAnalyse function
112148 * is functional and is called out in @analyze function
113149 */
114-
115150 @ Test
116151 void preAnalyseTest () {
117- // Mock everything needed for creating preAnalysis
118- MagpieServer magpieServer = mock (MagpieServer .class );
119- GoblintService goblintService = mock (GoblintService .class );
120- GobPieConfiguration gobPieConfiguration = mock (GobPieConfiguration .class );
121- GoblintServer goblintServer = spy (new GoblintServer (magpieServer , gobPieConfiguration ));
122- GoblintConfWatcher goblintConfWatcher = mock (GoblintConfWatcher .class );
123- GoblintAnalysis goblintAnalysis = new GoblintAnalysis (magpieServer , goblintServer , goblintService , gobPieConfiguration , goblintConfWatcher );
124-
125- // Mock that GoblintServer is alive and everything is fine with Goblint's configuration file
126- doReturn (true ).when (goblintServer ).isAlive ();
127- when (goblintConfWatcher .refreshGoblintConfig ()).thenReturn (true );
152+ mockGoblintServerIsAlive (goblintServer );
128153
129154 // A process that must be run before analysis
130155 String processPrintout = "'Hello'" ;
@@ -137,9 +162,6 @@ void preAnalyseTest() {
137162 // Mock that the incremental analysis is turned off (TODO: not sure why this is checked in reanalyze?)
138163 when (gobPieConfiguration .useIncrementalAnalysis ()).thenReturn (true );
139164
140- // Mock the arguments for calling the goblintAnalyze.analyze method
141- Collection <? extends Module > files = new ArrayDeque <>();
142- AnalysisConsumer analysisConsumer = mock (AnalysisConsumer .class );
143165 goblintAnalysis .analyze (files , analysisConsumer , true );
144166
145167 // Verify that preAnalysis was indeed called once
@@ -150,22 +172,12 @@ void preAnalyseTest() {
150172 }
151173
152174 /**
153- * * Mock test to ensure @preAnalyse function
154- * is functional and is called out in @analyze function
175+ * Mock test to ensure @preAnalyse function
176+ * is functional when preAnalyzeCommand is empty
155177 */
156178 @ Test
157179 void preAnalyseEmpty () {
158- // Mock everything needed for creating preAnalysis
159- MagpieServer magpieServer = mock (MagpieServer .class );
160- GoblintService goblintService = mock (GoblintService .class );
161- GobPieConfiguration gobPieConfiguration = mock (GobPieConfiguration .class );
162- GoblintServer goblintServer = spy (new GoblintServer (magpieServer , gobPieConfiguration ));
163- GoblintConfWatcher goblintConfWatcher = mock (GoblintConfWatcher .class );
164- GoblintAnalysis goblintAnalysis = new GoblintAnalysis (magpieServer , goblintServer , goblintService , gobPieConfiguration , goblintConfWatcher );
165-
166- // Mock that GoblintServer is alive and everything is fine with Goblint's configuration file
167- doReturn (true ).when (goblintServer ).isAlive ();
168- when (goblintConfWatcher .refreshGoblintConfig ()).thenReturn (true );
180+ mockGoblintServerIsAlive (goblintServer );
169181
170182 // Mock that Goblint returns some messages
171183 when (goblintService .messages ()).thenReturn (CompletableFuture .completedFuture (new ArrayList <>()));
@@ -180,9 +192,6 @@ void preAnalyseEmpty() {
180192 // Mock that the incremental analysis is turned off (TODO: not sure why this is checked in reanalyze?)
181193 when (gobPieConfiguration .useIncrementalAnalysis ()).thenReturn (true );
182194
183- // Mock the arguments for calling the goblintAnalyze.analyze method
184- Collection <? extends Module > files = new ArrayDeque <>();
185- AnalysisConsumer analysisConsumer = mock (AnalysisConsumer .class );
186195 goblintAnalysis .analyze (files , analysisConsumer , true );
187196
188197 // Verify that preAnalysis was indeed called once
@@ -191,19 +200,13 @@ void preAnalyseEmpty() {
191200 verify (magpieServer ).forwardMessageToClient (new MessageParams (MessageType .Info , "GobPie finished analyzing the code." ));
192201 }
193202
203+ /**
204+ * Mock test to ensure @preAnalyse function
205+ * is functional when preAnalyzeCommand is null
206+ */
194207 @ Test
195208 void preAnalyseNull () {
196- // Mock everything needed for creating preAnalysis
197- MagpieServer magpieServer = mock (MagpieServer .class );
198- GoblintService goblintService = mock (GoblintService .class );
199- GobPieConfiguration gobPieConfiguration = mock (GobPieConfiguration .class );
200- GoblintServer goblintServer = spy (new GoblintServer (magpieServer , gobPieConfiguration ));
201- GoblintConfWatcher goblintConfWatcher = mock (GoblintConfWatcher .class );
202- GoblintAnalysis goblintAnalysis = new GoblintAnalysis (magpieServer , goblintServer , goblintService , gobPieConfiguration , goblintConfWatcher );
203-
204- // Mock that GoblintServer is alive and everything is fine with Goblint's configuration file
205- doReturn (true ).when (goblintServer ).isAlive ();
206- when (goblintConfWatcher .refreshGoblintConfig ()).thenReturn (true );
209+ mockGoblintServerIsAlive (goblintServer );
207210
208211 // Mock that Goblint returns some messages
209212 when (goblintService .messages ()).thenReturn (CompletableFuture .completedFuture (new ArrayList <>()));
@@ -217,9 +220,6 @@ void preAnalyseNull() {
217220 // Mock that the incremental analysis is turned off (TODO: not sure why this is checked in reanalyze?)
218221 when (gobPieConfiguration .useIncrementalAnalysis ()).thenReturn (true );
219222
220- // Mock the arguments for calling the goblintAnalyze.analyze method
221- Collection <? extends Module > files = new ArrayDeque <>();
222- AnalysisConsumer analysisConsumer = mock (AnalysisConsumer .class );
223223 goblintAnalysis .analyze (files , analysisConsumer , true );
224224
225225 // Verify that preAnalysis was indeed called once
@@ -228,19 +228,13 @@ void preAnalyseNull() {
228228 verify (magpieServer ).forwardMessageToClient (new MessageParams (MessageType .Info , "GobPie finished analyzing the code." ));
229229 }
230230
231+ /**
232+ * Mock test to ensure @preAnalyse function
233+ * messages user when preAnalysis command fails
234+ */
231235 @ Test
232236 void preAnalyseError () {
233- // Mock everything needed for creating preAnalysis
234- MagpieServer magpieServer = mock (MagpieServer .class );
235- GoblintService goblintService = mock (GoblintService .class );
236- GobPieConfiguration gobPieConfiguration = mock (GobPieConfiguration .class );
237- GoblintServer goblintServer = spy (new GoblintServer (magpieServer , gobPieConfiguration ));
238- GoblintConfWatcher goblintConfWatcher = mock (GoblintConfWatcher .class );
239- GoblintAnalysis goblintAnalysis = new GoblintAnalysis (magpieServer , goblintServer , goblintService , gobPieConfiguration , goblintConfWatcher );
240-
241- // Mock that GoblintServer is alive and everything is fine with Goblint's configuration file
242- doReturn (true ).when (goblintServer ).isAlive ();
243- when (goblintConfWatcher .refreshGoblintConfig ()).thenReturn (true );
237+ mockGoblintServerIsAlive (goblintServer );
244238
245239 // Mock that Goblint returns some messages
246240 when (goblintService .messages ()).thenReturn (CompletableFuture .completedFuture (new ArrayList <>()));
@@ -255,9 +249,6 @@ void preAnalyseError() {
255249 // Mock that the incremental analysis is turned off (TODO: not sure why this is checked in reanalyze?)
256250 when (gobPieConfiguration .useIncrementalAnalysis ()).thenReturn (true );
257251
258- // Mock the arguments for calling the goblintAnalyze.analyze method
259- Collection <? extends Module > files = new ArrayDeque <>();
260- AnalysisConsumer analysisConsumer = mock (AnalysisConsumer .class );
261252 goblintAnalysis .analyze (files , analysisConsumer , true );
262253
263254 // Verify that preAnalysis was indeed called once
0 commit comments