Skip to content

Commit f9c4cf7

Browse files
committed
New RunAction which does the logic based on RunCommandConfig
1 parent 5520562 commit f9c4cf7

File tree

4 files changed

+439
-1
lines changed

4 files changed

+439
-1
lines changed

src/main/java/org/utplsql/cli/DataSourceProvider.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,14 @@ public class DataSourceProvider {
2222
}
2323

2424
public static DataSource getDataSource(ConnectionInfo info, int maxConnections ) throws SQLException {
25+
return getDataSource(info.getConnectionString(), maxConnections);
26+
}
27+
28+
public static DataSource getDataSource(String connectString, int maxConnections ) throws SQLException {
2529

2630
requireOjdbc();
2731

28-
ConnectionConfig config = new ConnectionConfig(info.getConnectionString());
32+
ConnectionConfig config = new ConnectionConfig(connectString);
2933
warnIfSysDba(config);
3034

3135
return new TestedDataSourceProvider(config, maxConnections).getDataSource();
Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
package org.utplsql.cli;
2+
3+
import com.beust.jcommander.Parameter;
4+
import com.beust.jcommander.Parameters;
5+
import com.zaxxer.hikari.HikariDataSource;
6+
import org.slf4j.Logger;
7+
import org.slf4j.LoggerFactory;
8+
import org.utplsql.api.*;
9+
import org.utplsql.api.compatibility.CompatibilityProxy;
10+
import org.utplsql.api.compatibility.OptionalFeatures;
11+
import org.utplsql.api.db.DefaultDatabaseInformation;
12+
import org.utplsql.api.exception.DatabaseNotCompatibleException;
13+
import org.utplsql.api.exception.OracleCreateStatmenetStuckException;
14+
import org.utplsql.api.exception.SomeTestsFailedException;
15+
import org.utplsql.api.exception.UtPLSQLNotInstalledException;
16+
import org.utplsql.api.reporter.Reporter;
17+
import org.utplsql.api.reporter.ReporterFactory;
18+
import org.utplsql.cli.config.FileMapperConfig;
19+
import org.utplsql.cli.config.RunCommandConfig;
20+
import org.utplsql.cli.exception.DatabaseConnectionFailed;
21+
import org.utplsql.cli.exception.ReporterTimeoutException;
22+
import org.utplsql.cli.log.StringBlockFormatter;
23+
24+
import javax.sql.DataSource;
25+
import javax.xml.crypto.dsig.keyinfo.KeyValue;
26+
import java.io.File;
27+
import java.sql.Connection;
28+
import java.sql.SQLException;
29+
import java.util.ArrayList;
30+
import java.util.Arrays;
31+
import java.util.List;
32+
import java.util.concurrent.*;
33+
34+
/**
35+
* Starts a test-runner and gathers the results based on the given Configuration
36+
*
37+
* @author pesse
38+
*/
39+
public class RunAction {
40+
41+
private static final Logger logger = LoggerFactory.getLogger(RunAction.class);
42+
43+
private RunCommandConfig config;
44+
45+
private CompatibilityProxy compatibilityProxy;
46+
private ReporterFactory reporterFactory;
47+
private ReporterManager reporterManager;
48+
49+
public RunAction( RunCommandConfig config ) {
50+
this.config = config;
51+
}
52+
53+
void init() {
54+
LoggerConfiguration.configure(config.getLogConfigLevel());
55+
}
56+
57+
public int doRun() throws OracleCreateStatmenetStuckException {
58+
init();
59+
outputMainInformation();
60+
61+
HikariDataSource dataSource = null;
62+
int returnCode = 0;
63+
try {
64+
65+
final List<Reporter> reporterList;
66+
67+
dataSource = (HikariDataSource) DataSourceProvider.getDataSource(config.getConnectString(), getReporterManager().getNumberOfReporters() + 2);
68+
69+
initDatabase(dataSource);
70+
reporterList = initReporters(dataSource);
71+
72+
checkForCompatibility(compatibilityProxy.getUtPlsqlVersion());
73+
74+
ExecutorService executorService = Executors.newFixedThreadPool(1 + reporterList.size());
75+
76+
// Run tests.
77+
Future<Boolean> future = executorService.submit(new RunTestRunnerTask(dataSource, newTestRunner(reporterList), config.isDbmsOutput()));
78+
79+
// Gather each reporter results on a separate thread.
80+
getReporterManager().startReporterGatherers(executorService, dataSource);
81+
82+
try {
83+
future.get(config.getTimeoutInMinutes(), TimeUnit.MINUTES);
84+
} catch (TimeoutException e) {
85+
executorService.shutdownNow();
86+
throw new ReporterTimeoutException(config.getTimeoutInMinutes());
87+
} catch (ExecutionException e) {
88+
if (e.getCause() instanceof SomeTestsFailedException) {
89+
returnCode = config.getFailureExitCode();
90+
} else {
91+
executorService.shutdownNow();
92+
throw e.getCause();
93+
}
94+
} catch (InterruptedException e) {
95+
executorService.shutdownNow();
96+
throw e;
97+
}
98+
finally {
99+
executorService.shutdown();
100+
if (!executorService.awaitTermination(config.getTimeoutInMinutes(), TimeUnit.MINUTES)) {
101+
throw new ReporterTimeoutException(config.getTimeoutInMinutes());
102+
}
103+
}
104+
105+
logger.info("--------------------------------------");
106+
logger.info("All tests done.");
107+
} catch ( OracleCreateStatmenetStuckException e ) {
108+
throw e;
109+
} catch ( DatabaseNotCompatibleException | UtPLSQLNotInstalledException | DatabaseConnectionFailed | ReporterTimeoutException e ) {
110+
System.out.println(e.getMessage());
111+
returnCode = Cli.DEFAULT_ERROR_CODE;
112+
} catch (Throwable e) {
113+
e.printStackTrace();
114+
returnCode = Cli.DEFAULT_ERROR_CODE;
115+
} finally {
116+
if ( dataSource != null )
117+
dataSource.close();
118+
}
119+
return returnCode;
120+
}
121+
122+
public int run() {
123+
for ( int i = 1; i<5; i++ ) {
124+
try {
125+
return doRun();
126+
} catch (OracleCreateStatmenetStuckException e) {
127+
logger.warn("WARNING: Caught Oracle stuck during creation of Runner-Statement. Retrying ({})", i);
128+
}
129+
}
130+
131+
return Cli.DEFAULT_ERROR_CODE;
132+
}
133+
134+
private void checkForCompatibility( Version utPlSqlVersion ) {
135+
if (!OptionalFeatures.FAIL_ON_ERROR.isAvailableFor(utPlSqlVersion) && config.getFailureExitCode() != null ) {
136+
System.out.println("You specified option `--failure-exit-code` but your database framework version (" +
137+
utPlSqlVersion.getNormalizedString() + ") is not able to " +
138+
"redirect failureCodes. Please upgrade to a newer version if you want to use that feature.");
139+
}
140+
141+
if ( !OptionalFeatures.RANDOM_EXECUTION_ORDER.isAvailableFor(utPlSqlVersion) && config.isRandomTestOrder() ) {
142+
System.out.println("You specified option `-random` but your database framework version (" +
143+
utPlSqlVersion.getNormalizedString() + ") is not able to " +
144+
"redirect failureCodes. Please upgrade to a newer version if you want to use that feature.");
145+
}
146+
147+
if ( !OptionalFeatures.RANDOM_EXECUTION_ORDER.isAvailableFor(utPlSqlVersion) && config.getRandomTestOrderSeed() != null ) {
148+
System.out.println("You specified option `-seed` but your database framework version (" +
149+
utPlSqlVersion.getNormalizedString() + ") is not able to " +
150+
"redirect failureCodes. Please upgrade to a newer version if you want to use that feature.");
151+
}
152+
153+
}
154+
155+
TestRunner newTestRunner( List<Reporter> reporterList) {
156+
157+
final File baseDir = new File("").getAbsoluteFile();
158+
159+
return new TestRunner()
160+
.addPathList(Arrays.asList(config.getSuitePaths()))
161+
.addReporterList(reporterList)
162+
.sourceMappingOptions(getFileMapperOptionsByParamListItem(config.getSourceMapping(), baseDir))
163+
.testMappingOptions(getFileMapperOptionsByParamListItem(config.getTestMapping(), baseDir))
164+
.colorConsole(config.isOutputAnsiColor())
165+
.failOnErrors(true)
166+
.skipCompatibilityCheck(config.isSkipCompatibilityCheck())
167+
.includeObjects(Arrays.asList(config.getIncludePackages()))
168+
.excludeObjects(Arrays.asList(config.getExcludePackages()))
169+
.randomTestOrder(config.isRandomTestOrder())
170+
.randomTestOrderSeed(config.getRandomTestOrderSeed());
171+
}
172+
173+
private void outputMainInformation() {
174+
175+
StringBlockFormatter formatter = new StringBlockFormatter("utPLSQL cli");
176+
formatter.appendLine(CliVersionInfo.getInfo());
177+
formatter.appendLine(JavaApiVersionInfo.getInfo());
178+
formatter.appendLine("Java-Version: " + System.getProperty("java.version"));
179+
formatter.appendLine("ORACLE_HOME: " + EnvironmentVariableUtil.getEnvValue("ORACLE_HOME"));
180+
formatter.appendLine("NLS_LANG: " + EnvironmentVariableUtil.getEnvValue("NLS_LANG"));
181+
formatter.appendLine("");
182+
formatter.appendLine("Thanks for testing!");
183+
184+
logger.info(formatter.toString());
185+
logger.info("");
186+
}
187+
188+
private void initDatabase(DataSource dataSource) throws SQLException {
189+
try (Connection conn = dataSource.getConnection()) {
190+
191+
// Check if orai18n exists if database version is 11g
192+
RunCommandChecker.checkOracleI18nExists(conn);
193+
194+
// First of all do a compatibility check and fail-fast
195+
compatibilityProxy = checkFrameworkCompatibility(conn);
196+
197+
logger.info("Successfully connected to database. UtPLSQL core: {}", compatibilityProxy.getVersionDescription());
198+
logger.info("Oracle-Version: {}", new DefaultDatabaseInformation().getOracleVersion(conn));
199+
}
200+
catch (SQLException e) {
201+
if (e.getErrorCode() == 1017 || e.getErrorCode() == 12514) {
202+
throw new DatabaseConnectionFailed(e);
203+
} else {
204+
throw e;
205+
}
206+
}
207+
}
208+
209+
private List<Reporter> initReporters(DataSource dataSource) throws SQLException {
210+
try (Connection conn = dataSource.getConnection()) {
211+
reporterFactory = ReporterFactoryProvider.createReporterFactory(compatibilityProxy);
212+
return getReporterManager().initReporters(conn, reporterFactory, compatibilityProxy);
213+
}
214+
}
215+
216+
/** Returns FileMapperOptions for the first item of a given param list in a baseDir
217+
*
218+
* @param fileMapperConfig
219+
* @param baseDir
220+
* @return FileMapperOptions or null
221+
*/
222+
private FileMapperOptions getFileMapperOptionsByParamListItem(FileMapperConfig fileMapperConfig, File baseDir )
223+
{
224+
if (fileMapperConfig != null) {
225+
String sourcePath = fileMapperConfig.getPath();
226+
227+
logger.debug("BaseDir: {}", baseDir);
228+
logger.debug("SourcePath: {}", sourcePath);
229+
230+
List<String> files = new FileWalker().getFileList(baseDir, sourcePath);
231+
232+
logger.debug("Getting FileMapperOptions - Files: ");
233+
files.forEach(logger::debug);
234+
235+
FileMapperOptions options = new FileMapperOptions(files);
236+
options.setObjectOwner(fileMapperConfig.getOwner());
237+
options.setRegexPattern(fileMapperConfig.getRegexExpression());
238+
options.setTypeSubExpression(fileMapperConfig.getTypeSubexpression());
239+
options.setOwnerSubExpression(fileMapperConfig.getOwnerSubexpression());
240+
options.setNameSubExpression(fileMapperConfig.getNameSubexpression());
241+
242+
List<KeyValuePair> mappings = new ArrayList<>();
243+
fileMapperConfig.getTypeMapping().forEach((k, v) -> mappings.add(new KeyValuePair(v, k)));
244+
options.setTypeMappings(mappings);
245+
246+
return options;
247+
}
248+
249+
return null;
250+
}
251+
252+
/** Checks whether cli is compatible with the database framework
253+
*
254+
* @param conn Active Connection
255+
* @throws SQLException
256+
*/
257+
private CompatibilityProxy checkFrameworkCompatibility(Connection conn) throws SQLException {
258+
259+
CompatibilityProxy proxy = new CompatibilityProxy(conn, config.isSkipCompatibilityCheck());
260+
261+
if ( !config.isSkipCompatibilityCheck() ) {
262+
proxy.failOnNotCompatible();
263+
}
264+
else {
265+
System.out.println("Skipping Compatibility check with framework version, expecting the latest version " +
266+
"to be installed in database");
267+
}
268+
269+
return proxy;
270+
}
271+
272+
private ReporterManager getReporterManager() {
273+
ArrayList<String> reporterParams = new ArrayList<>();
274+
if ( reporterManager == null )
275+
reporterManager = new ReporterManager(reporterParams);
276+
277+
return reporterManager;
278+
}
279+
280+
List<ReporterOptions> getReporterOptionsList() {
281+
return getReporterManager().getReporterOptionsList();
282+
}
283+
}

0 commit comments

Comments
 (0)