22
33import com .beust .jcommander .Parameter ;
44import com .beust .jcommander .Parameters ;
5+ import com .zaxxer .hikari .HikariDataSource ;
6+ import com .zaxxer .hikari .pool .HikariProxyConnection ;
57import org .slf4j .Logger ;
68import org .slf4j .LoggerFactory ;
79import org .utplsql .api .*;
810import org .utplsql .api .compatibility .CompatibilityProxy ;
911import org .utplsql .api .db .DefaultDatabaseInformation ;
1012import org .utplsql .api .exception .DatabaseNotCompatibleException ;
13+ import org .utplsql .api .exception .OracleCreateStatmenetStuckException ;
1114import org .utplsql .api .exception .SomeTestsFailedException ;
1215import org .utplsql .api .exception .UtPLSQLNotInstalledException ;
1316import org .utplsql .api .reporter .Reporter ;
2528import java .util .List ;
2629import java .util .concurrent .ExecutorService ;
2730import java .util .concurrent .Executors ;
31+ import java .util .concurrent .Future ;
2832import java .util .concurrent .TimeUnit ;
2933
3034/**
@@ -139,7 +143,7 @@ else if ( logDebug ) {
139143 LoggerConfiguration .configure (level );
140144 }
141145
142- public int run () {
146+ public int doRun () {
143147 init ();
144148 outputMainInformation ();
145149
@@ -148,18 +152,9 @@ public int run() {
148152 final List <Reporter > reporterList ;
149153
150154 final File baseDir = new File ("" ).getAbsoluteFile ();
151- final FileMapperOptions [] sourceMappingOptions = {null };
152- final FileMapperOptions [] testMappingOptions = {null };
153-
154155 final int [] returnCode = {0 };
155156
156- sourceMappingOptions [0 ] = getFileMapperOptionsByParamListItem (this .sourcePathParams , baseDir );
157- testMappingOptions [0 ] = getFileMapperOptionsByParamListItem (this .testPathParams , baseDir );
158-
159- final List <String > finalIncludeObjectsList = getObjectList (includeObjects );
160- final List <String > finalExcludeObjectsList = getObjectList (excludeObjects );
161-
162- final DataSource dataSource = DataSourceProvider .getDataSource (getConnectionInfo (), getReporterManager ().getNumberOfReporters () + 1 );
157+ final DataSource dataSource = DataSourceProvider .getDataSource (getConnectionInfo (), getReporterManager ().getNumberOfReporters () + 2 );
163158
164159 initDatabase (dataSource );
165160 reporterList = initReporters (dataSource );
@@ -173,33 +168,50 @@ public int run() {
173168 ExecutorService executorService = Executors .newFixedThreadPool (1 + reporterList .size ());
174169
175170 // Run tests.
176- executorService .submit (() -> {
177- try (Connection conn = dataSource .getConnection ()) {
178- TestRunner testRunner = new TestRunner ()
179- .addPathList (testPaths )
180- .addReporterList (reporterList )
181- .sourceMappingOptions (sourceMappingOptions [0 ])
182- .testMappingOptions (testMappingOptions [0 ])
183- .colorConsole (this .colorConsole )
184- .failOnErrors (true )
185- .skipCompatibilityCheck (skipCompatibilityCheck )
186- .includeObjects (finalIncludeObjectsList )
187- .excludeObjects (finalExcludeObjectsList );
171+ Future <Integer > future = executorService .submit (() -> {
172+ Connection conn = null ;
173+ try {
174+ conn = dataSource .getConnection ();
175+ TestRunner testRunner = newTestRunner (reporterList );
188176
189177 logger .info ("Running tests now." );
190178 logger .info ("--------------------------------------" );
191179 testRunner .run (conn );
192180 } catch (SomeTestsFailedException e ) {
193181 returnCode [0 ] = this .failureExitCode ;
194- } catch (SQLException e ) {
182+ }
183+ catch (OracleCreateStatmenetStuckException e ) {
184+ try {
185+ conn .abort (Executors .newSingleThreadExecutor ());
186+ conn = null ;
187+ } catch (SQLException e1 ) {
188+ logger .error (e1 .getMessage (), e1 );
189+ }
190+ executorService .shutdownNow ();
191+ return 3 ;
192+ }
193+ catch (SQLException e ) {
195194 System .out .println (e .getMessage ());
196- returnCode [0 ] = Cli .DEFAULT_ERROR_CODE ;
195+ // returnCode[0] = Cli.DEFAULT_ERROR_CODE;
197196 executorService .shutdownNow ();
197+ return Cli .DEFAULT_ERROR_CODE ;
198198 }
199+ finally {
200+ if ( conn != null ) {
201+ try {
202+ conn .close ();
203+ } catch (SQLException e ) {
204+ e .printStackTrace ();
205+ }
206+ }
207+ }
208+ return 0 ;
199209 });
200210
201211 // Gather each reporter results on a separate thread.
202- getReporterManager ().startReporterGatherers (executorService , dataSource , returnCode );
212+ getReporterManager ().startReporterGatherers (executorService , dataSource );
213+
214+ Integer mainTestResult = future .get ();
203215
204216 executorService .shutdown ();
205217 if ( !executorService .awaitTermination (timeoutInMinutes , TimeUnit .MINUTES ) ) {
@@ -209,7 +221,9 @@ public int run() {
209221 logger .info ("--------------------------------------" );
210222 logger .info ("All tests done." );
211223
212- return returnCode [0 ];
224+ ((HikariDataSource )dataSource ).close ();
225+
226+ return mainTestResult ;
213227 }
214228 catch ( DatabaseNotCompatibleException | UtPLSQLNotInstalledException | DatabaseConnectionFailed | ReporterTimeoutException e ) {
215229 System .out .println (e .getMessage ());
@@ -219,6 +233,34 @@ public int run() {
219233 return Cli .DEFAULT_ERROR_CODE ;
220234 }
221235
236+ public int run () {
237+ int i = 1 ;
238+ int exitCode = doRun ();
239+ // Retry
240+ while ( exitCode == 3 && i <10 ) {
241+ logger .warn ("Retry" );
242+ exitCode = doRun ();
243+ i ++;
244+ }
245+ return exitCode ;
246+ }
247+
248+ private TestRunner newTestRunner ( List <Reporter > reporterList ) {
249+
250+ final File baseDir = new File ("" ).getAbsoluteFile ();
251+
252+ return new TestRunner ()
253+ .addPathList (testPaths )
254+ .addReporterList (reporterList )
255+ .sourceMappingOptions (getFileMapperOptionsByParamListItem (this .sourcePathParams , baseDir ))
256+ .testMappingOptions (getFileMapperOptionsByParamListItem (this .testPathParams , baseDir ))
257+ .colorConsole (this .colorConsole )
258+ .failOnErrors (true )
259+ .skipCompatibilityCheck (skipCompatibilityCheck )
260+ .includeObjects (getObjectList (includeObjects ))
261+ .excludeObjects (getObjectList (excludeObjects ));
262+ }
263+
222264 private ArrayList <String > getObjectList (String includeObjects ) {
223265 ArrayList <String > includeObjectsList ;
224266 if (includeObjects != null && !includeObjects .isEmpty ()) {
0 commit comments