From fbbef6d8684ceaf5c539c75f65783da68eb204c5 Mon Sep 17 00:00:00 2001 From: pesse Date: Thu, 31 May 2018 22:57:35 +0200 Subject: [PATCH 01/11] Minimal viable (and ugly) solution to add version info to cli Refactoring needed. Tonight is a tough night for concentration. Turning on programming/concentration music didn't help either. Guess what they played? Command&Conquer Soundtrack. Who could concentrate with so many nice and positive memories triggered? --- pom.xml | 36 ++++++++++++ src/main/java/org/utplsql/cli/Cli.java | 10 +++- .../java/org/utplsql/cli/CliVersionInfo.java | 20 +++++++ .../org/utplsql/cli/VersionInfoCommand.java | 55 +++++++++++++++++++ .../org/utplsql/cli/VersionInfoCommandIT.java | 43 +++++++++++++++ 5 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/utplsql/cli/CliVersionInfo.java create mode 100644 src/main/java/org/utplsql/cli/VersionInfoCommand.java create mode 100644 src/test/java/org/utplsql/cli/VersionInfoCommandIT.java diff --git a/pom.xml b/pom.xml index 4d1e25b..861937c 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,7 @@ 1.8 1.0.3 5.0.3 + local @@ -88,6 +89,41 @@ + + com.google.code.maven-replacer-plugin + replacer + 1.5.3 + + + replace-version-number + generate-sources + + replace + + + + + ${project.basedir}/src/main/java + + **/CliVersionInfo.java + + true + + + MAVEN_PROJECT_NAME = ".*" + MAVEN_PROJECT_NAME = "${project.name}" + + + MAVEN_PROJECT_VERSION = ".*" + MAVEN_PROJECT_VERSION = "${project.version}" + + + BUILD_NO = ".*" + BUILD_NO = "${travisBuildNumber}" + + + + org.apache.maven.plugins maven-surefire-plugin diff --git a/src/main/java/org/utplsql/cli/Cli.java b/src/main/java/org/utplsql/cli/Cli.java index 9189367..ff6a6a5 100644 --- a/src/main/java/org/utplsql/cli/Cli.java +++ b/src/main/java/org/utplsql/cli/Cli.java @@ -13,6 +13,7 @@ public class Cli { static final String HELP_CMD = "-h"; private static final String RUN_CMD = "run"; + private static final String VERSION_CMD = "info"; public static void main(String[] args) { @@ -22,8 +23,9 @@ public static void main(String[] args) { jc.setProgramName("utplsql"); // jc.addCommand(HELP_CMD, new HelpCommand()); RunCommand runCmd = new RunCommand(); + VersionInfoCommand infoCmd = new VersionInfoCommand(); jc.addCommand(RUN_CMD, runCmd); - + jc.addCommand(VERSION_CMD, infoCmd); int exitCode = DEFAULT_ERROR_CODE; try { @@ -31,7 +33,11 @@ public static void main(String[] args) { if (RUN_CMD.equals(jc.getParsedCommand())) { exitCode = runCmd.run(); - } else { + } + else if ( VERSION_CMD.equals(jc.getParsedCommand()) ) { + exitCode = infoCmd.run(); + } + else { throw new ParameterException("Command not specified."); } } catch (ParameterException e) { diff --git a/src/main/java/org/utplsql/cli/CliVersionInfo.java b/src/main/java/org/utplsql/cli/CliVersionInfo.java new file mode 100644 index 0000000..96fbc4c --- /dev/null +++ b/src/main/java/org/utplsql/cli/CliVersionInfo.java @@ -0,0 +1,20 @@ +package org.utplsql.cli; + +/** This class is getting updated automatically by the build process. + * Please do not update its constants manually cause they will be overwritten. + * + * @author pesse + */ +public class CliVersionInfo { + + private static final String BUILD_NO = "local"; + private static final String MAVEN_PROJECT_NAME = "cli"; + private static final String MAVEN_PROJECT_VERSION = "3.1.1-SNAPSHOT"; + + public static String getVersion() { + return MAVEN_PROJECT_VERSION + "." + BUILD_NO; + } + + public static String getInfo() { return MAVEN_PROJECT_NAME + " " + getVersion(); } + +} diff --git a/src/main/java/org/utplsql/cli/VersionInfoCommand.java b/src/main/java/org/utplsql/cli/VersionInfoCommand.java new file mode 100644 index 0000000..b7e4f75 --- /dev/null +++ b/src/main/java/org/utplsql/cli/VersionInfoCommand.java @@ -0,0 +1,55 @@ +package org.utplsql.cli; + + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import org.utplsql.api.DBHelper; +import org.utplsql.api.JavaApiVersionInfo; +import org.utplsql.api.Version; +import org.utplsql.api.exception.UtPLSQLNotInstalledException; + +import java.sql.Connection; +import java.util.ArrayList; +import java.util.List; + +@Parameters(separators = "=", commandDescription = "prints version information of cli, java-api and - if connection is given - database utPLSQL framework") +public class VersionInfoCommand { + + @Parameter( + converter = ConnectionInfo.ConnectionStringConverter.class, + variableArity = true, + description = "/@//[:]/ OR /@ OR /@::") + private List connectionInfoList = new ArrayList<>(); + + public ConnectionInfo getConnectionInfo() { + if ( connectionInfoList != null && connectionInfoList.size() > 0 ) + return connectionInfoList.get(0); + else + return null; + } + + public int run() throws Exception { + + System.out.println(CliVersionInfo.getInfo()); + System.out.println("Java-API " + JavaApiVersionInfo.getVersion()); + + ConnectionInfo ci = getConnectionInfo(); + if ( ci != null ) { + // TODO: Ora-check + ci.setMaxConnections(1); + try (Connection con = ci.getConnection()) { + Version v = DBHelper.getDatabaseFrameworkVersion( con ); + System.out.println("utPLSQL " + v.getNormalizedString()); + } + catch ( UtPLSQLNotInstalledException e ) { + System.out.println("utPLSQL framework is not installed in database."); + } + catch ( Exception e ) { + e.printStackTrace(); + return 1; + } + } + + return 0; + } +} diff --git a/src/test/java/org/utplsql/cli/VersionInfoCommandIT.java b/src/test/java/org/utplsql/cli/VersionInfoCommandIT.java new file mode 100644 index 0000000..33ed77b --- /dev/null +++ b/src/test/java/org/utplsql/cli/VersionInfoCommandIT.java @@ -0,0 +1,43 @@ +package org.utplsql.cli; + +import com.beust.jcommander.JCommander; +import org.junit.jupiter.api.Test; +import org.utplsql.api.EnvironmentVariableUtil; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class VersionInfoCommandIT { + + @Test + public void infoCommandRunsWithoutConnection() throws Exception { + + VersionInfoCommand infoCmd = new VersionInfoCommand(); + + JCommander.newBuilder() + .addObject(infoCmd) + .args(new String[]{}) + .build(); + + int result = infoCmd.run(); + + assertEquals(0, result); + } + @Test + public void infoCommandRunsWithConnection() throws Exception { + + String Url = EnvironmentVariableUtil.getEnvValue("DB_URL", "192.168.99.100:1521:XE"); + String sUser = EnvironmentVariableUtil.getEnvValue("DB_USER", "app"); + String sPass = EnvironmentVariableUtil.getEnvValue("DB_PASS", "app"); + + VersionInfoCommand infoCmd = new VersionInfoCommand(); + + JCommander.newBuilder() + .addObject(infoCmd) + .args(new String[]{sUser + "/" + sPass + "@" + Url}) + .build(); + + int result = infoCmd.run(); + + assertEquals(0, result); + } +} From 2772add63931c2a6bd7f5ca55562846472be4823 Mon Sep 17 00:00:00 2001 From: pesse Date: Tue, 5 Jun 2018 22:06:05 +0200 Subject: [PATCH 02/11] First set of refactorings around ConnectionInfo It should really be only an Info-Object, not a DataSource wannabe --- .../java/org/utplsql/cli/ConnectionInfo.java | 69 ++----------------- .../org/utplsql/cli/DataSourceProvider.java | 44 ++++++++++++ .../java/org/utplsql/cli/ReporterManager.java | 7 +- src/main/java/org/utplsql/cli/RunCommand.java | 17 ++--- .../org/utplsql/cli/RunCommandChecker.java | 24 ++----- .../org/utplsql/cli/VersionInfoCommand.java | 14 ++-- 6 files changed, 75 insertions(+), 100 deletions(-) create mode 100644 src/main/java/org/utplsql/cli/DataSourceProvider.java diff --git a/src/main/java/org/utplsql/cli/ConnectionInfo.java b/src/main/java/org/utplsql/cli/ConnectionInfo.java index f1a32a2..7b48e87 100644 --- a/src/main/java/org/utplsql/cli/ConnectionInfo.java +++ b/src/main/java/org/utplsql/cli/ConnectionInfo.java @@ -1,40 +1,18 @@ package org.utplsql.cli; import com.beust.jcommander.IStringConverter; -import com.zaxxer.hikari.HikariDataSource; - -import java.io.File; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; public class ConnectionInfo { - private String databaseVersion; - - static { - String oracleHome = System.getenv("ORACLE_HOME"); - if (oracleHome != null) { - System.setProperty("oracle.net.tns_admin", - String.join(File.separator, oracleHome, "NETWORK", "ADMIN")); - } - } - - private HikariDataSource pds = new HikariDataSource(); + public static final String COMMANDLINE_PARAM_DESCRIPTION = "/@//[:]/ OR /@ OR /@::"; + private String connectionInfo; public ConnectionInfo(String connectionInfo) { - - pds.setJdbcUrl("jdbc:oracle:thin:" + connectionInfo); - pds.setAutoCommit(false); + this.connectionInfo = connectionInfo; } - public void setMaxConnections( int maxConnections ) { - pds.setMaximumPoolSize(maxConnections); - } - - public Connection getConnection() throws SQLException { - return pds.getConnection(); + public String getConnectionString() { + return connectionInfo; } public static class ConnectionStringConverter implements IStringConverter { @@ -44,41 +22,4 @@ public ConnectionInfo convert(String s) { return new ConnectionInfo(s); } } - - public String getOracleDatabaseVersion() throws SQLException - { - try ( Connection conn = getConnection() ) { - return getOracleDatabaseVersion(conn); - } - } - - public String getOracleDatabaseVersion( Connection conn ) throws SQLException - { - if ( databaseVersion == null ) { - databaseVersion = getOracleDatabaseVersionFromConnection( conn ); - } - - return databaseVersion; - } - - /** TODO: Outsource this to Java-API - * - * @param conn - * @return - * @throws SQLException - */ - public static String getOracleDatabaseVersionFromConnection( Connection conn ) throws SQLException { - assert conn != null; - String result = null; - try (PreparedStatement stmt = conn.prepareStatement("select version from product_component_version where product like 'Oracle Database%'")) - { - ResultSet rs = stmt.executeQuery(); - - if ( rs.next() ) - result = rs.getString(1); - } - - return result; - } - } diff --git a/src/main/java/org/utplsql/cli/DataSourceProvider.java b/src/main/java/org/utplsql/cli/DataSourceProvider.java new file mode 100644 index 0000000..ac790f4 --- /dev/null +++ b/src/main/java/org/utplsql/cli/DataSourceProvider.java @@ -0,0 +1,44 @@ +package org.utplsql.cli; + +import com.zaxxer.hikari.HikariDataSource; +import org.utplsql.api.EnvironmentVariableUtil; + +import javax.sql.DataSource; +import java.io.File; + +/** Helper class to give you a ready-to-use datasource + * + * @author pesse + */ +public class DataSourceProvider { + + static { + String oracleHome = EnvironmentVariableUtil.getEnvValue("ORACLE_HOME"); + if (oracleHome != null) { + System.setProperty("oracle.net.tns_admin", + String.join(File.separator, oracleHome, "NETWORK", "ADMIN")); + } + } + + public static DataSource getDataSource(ConnectionInfo info, int maxConnections ) { + + requireOjdbc(); + + HikariDataSource pds = new HikariDataSource(); + pds.setJdbcUrl("jdbc:oracle:thin:" + info.getConnectionString()); + pds.setAutoCommit(false); + pds.setMaximumPoolSize(maxConnections); + return pds; + } + + private static void requireOjdbc() { + if ( !OracleLibraryChecker.checkOjdbcExists() ) + { + System.out.println("Could not find Oracle JDBC driver in classpath. Please download the jar from Oracle website" + + " and copy it to the 'lib' folder of your utPLSQL-cli installation."); + System.out.println("Download from http://www.oracle.com/technetwork/database/features/jdbc/jdbc-ucp-122-3110062.html"); + + throw new RuntimeException("Can't run utPLSQL-cli without Oracle JDBC driver"); + } + } +} diff --git a/src/main/java/org/utplsql/cli/ReporterManager.java b/src/main/java/org/utplsql/cli/ReporterManager.java index aac7ddf..eed17a8 100644 --- a/src/main/java/org/utplsql/cli/ReporterManager.java +++ b/src/main/java/org/utplsql/cli/ReporterManager.java @@ -6,6 +6,7 @@ import org.utplsql.api.reporter.ReporterFactory; import org.utplsql.cli.reporters.ReporterOptionsAware; +import javax.sql.DataSource; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintStream; @@ -77,10 +78,10 @@ public List initReporters(Connection conn, ReporterFactory reporterFac /** Starts a separate thread for each Reporter to gather its results * * @param executorService - * @param ci + * @param dataSource * @param returnCode */ - public void startReporterGatherers(ExecutorService executorService, final ConnectionInfo ci, final int[] returnCode) + public void startReporterGatherers(ExecutorService executorService, final DataSource dataSource, final int[] returnCode) { // TODO: Implement Init-check // Gather each reporter results on a separate thread. @@ -89,7 +90,7 @@ public void startReporterGatherers(ExecutorService executorService, final Connec List printStreams = new ArrayList<>(); PrintStream fileOutStream = null; - try (Connection conn = ci.getConnection()) { + try (Connection conn = dataSource.getConnection()) { if (ro.outputToScreen()) { printStreams.add(System.out); ro.getReporterObj().getOutputBuffer().setFetchSize(1); diff --git a/src/main/java/org/utplsql/cli/RunCommand.java b/src/main/java/org/utplsql/cli/RunCommand.java index 12ea83f..0529998 100644 --- a/src/main/java/org/utplsql/cli/RunCommand.java +++ b/src/main/java/org/utplsql/cli/RunCommand.java @@ -12,6 +12,7 @@ import org.utplsql.api.reporter.ReporterFactory; import org.utplsql.cli.exception.DatabaseConnectionFailed; +import javax.sql.DataSource; import java.io.File; import java.sql.Connection; import java.sql.SQLException; @@ -35,7 +36,7 @@ public class RunCommand { required = true, converter = ConnectionInfo.ConnectionStringConverter.class, arity = 1, - description = "/@//[:]/ OR /@ OR /@::") + description = ConnectionInfo.COMMANDLINE_PARAM_DESCRIPTION) private List connectionInfoList = new ArrayList<>(); @Parameter( @@ -111,9 +112,6 @@ public List getTestPaths() { public int run() throws Exception { - RunCommandChecker.checkOracleJDBCExists(); - - final List reporterList; final List testPaths = getTestPaths(); @@ -144,14 +142,13 @@ public int run() throws Exception { final ArrayList finalIncludeObjectsList = includeObjectsList; final ArrayList finalExcludeObjectsList = excludeObjectsList; - final ConnectionInfo ci = getConnectionInfo(); - ci.setMaxConnections(getReporterManager().getNumberOfReporters()+1); + final DataSource dataSource = DataSourceProvider.getDataSource(getConnectionInfo(), getReporterManager().getNumberOfReporters()+1); // Do the reporters initialization, so we can use the id to run and gather results. - try (Connection conn = ci.getConnection()) { + try (Connection conn = dataSource.getConnection()) { // Check if orai18n exists if database version is 11g - RunCommandChecker.checkOracleI18nExists(ci.getOracleDatabaseVersion(conn)); + RunCommandChecker.checkOracleI18nExists(conn); // First of all do a compatibility check and fail-fast compatibilityProxy = checkFrameworkCompatibility(conn); @@ -178,7 +175,7 @@ public int run() throws Exception { // Run tests. executorService.submit(() -> { - try (Connection conn = ci.getConnection()) { + try (Connection conn = dataSource.getConnection()) { TestRunner testRunner = new TestRunner() .addPathList(testPaths) .addReporterList(reporterList) @@ -201,7 +198,7 @@ public int run() throws Exception { }); // Gather each reporter results on a separate thread. - getReporterManager().startReporterGatherers(executorService, ci, returnCode); + getReporterManager().startReporterGatherers(executorService, dataSource, returnCode); executorService.shutdown(); executorService.awaitTermination(60, TimeUnit.MINUTES); diff --git a/src/main/java/org/utplsql/cli/RunCommandChecker.java b/src/main/java/org/utplsql/cli/RunCommandChecker.java index e0c1bb2..6adce56 100644 --- a/src/main/java/org/utplsql/cli/RunCommandChecker.java +++ b/src/main/java/org/utplsql/cli/RunCommandChecker.java @@ -1,34 +1,24 @@ package org.utplsql.cli; +import org.utplsql.api.DBHelper; import org.utplsql.api.Version; import org.utplsql.api.compatibility.OptionalFeatures; +import java.sql.Connection; +import java.sql.SQLException; + /** Helper class to check several circumstances with RunCommand. Might need refactoring. * * @author pesse */ class RunCommandChecker { - /** Checks that ojdbc library exists - * - */ - static void checkOracleJDBCExists() - { - if ( !OracleLibraryChecker.checkOjdbcExists() ) - { - System.out.println("Could not find Oracle JDBC driver in classpath. Please download the jar from Oracle website" + - " and copy it to the 'lib' folder of your utPLSQL-cli installation."); - System.out.println("Download from http://www.oracle.com/technetwork/database/features/jdbc/jdbc-ucp-122-3110062.html"); - - throw new RuntimeException("Can't run utPLSQL-cli without Oracle JDBC driver"); - } - } - /** Checks that orai18n library exists if database is an oracle 11 * */ - static void checkOracleI18nExists(String oracleDatabaseVersion ) - { + static void checkOracleI18nExists(Connection con) throws SQLException { + + String oracleDatabaseVersion = DBHelper.getOracleDatabaseVersion(con); if ( oracleDatabaseVersion.startsWith("11.") && !OracleLibraryChecker.checkOrai18nExists() ) { System.out.println("Warning: Could not find Oracle i18n driver in classpath. Depending on the database charset " + diff --git a/src/main/java/org/utplsql/cli/VersionInfoCommand.java b/src/main/java/org/utplsql/cli/VersionInfoCommand.java index b7e4f75..48ce629 100644 --- a/src/main/java/org/utplsql/cli/VersionInfoCommand.java +++ b/src/main/java/org/utplsql/cli/VersionInfoCommand.java @@ -8,6 +8,7 @@ import org.utplsql.api.Version; import org.utplsql.api.exception.UtPLSQLNotInstalledException; +import javax.sql.DataSource; import java.sql.Connection; import java.util.ArrayList; import java.util.List; @@ -18,7 +19,7 @@ public class VersionInfoCommand { @Parameter( converter = ConnectionInfo.ConnectionStringConverter.class, variableArity = true, - description = "/@//[:]/ OR /@ OR /@::") + description = ConnectionInfo.COMMANDLINE_PARAM_DESCRIPTION) private List connectionInfoList = new ArrayList<>(); public ConnectionInfo getConnectionInfo() { @@ -28,16 +29,17 @@ public ConnectionInfo getConnectionInfo() { return null; } - public int run() throws Exception { + public int run() { System.out.println(CliVersionInfo.getInfo()); - System.out.println("Java-API " + JavaApiVersionInfo.getVersion()); + System.out.println(JavaApiVersionInfo.getInfo()); ConnectionInfo ci = getConnectionInfo(); if ( ci != null ) { - // TODO: Ora-check - ci.setMaxConnections(1); - try (Connection con = ci.getConnection()) { + + DataSource dataSource = DataSourceProvider.getDataSource(ci, 1); + + try (Connection con = dataSource.getConnection()) { Version v = DBHelper.getDatabaseFrameworkVersion( con ); System.out.println("utPLSQL " + v.getNormalizedString()); } From 457625d5d114331e011eeea53b32ffaeb598f8ef Mon Sep 17 00:00:00 2001 From: pesse Date: Tue, 5 Jun 2018 23:50:14 +0200 Subject: [PATCH 03/11] Refactoring around commands. I wanted to have more separation between Main-Class and actual commands. There might still be work left to do, but it's a first throw. --- src/main/java/org/utplsql/cli/Cli.java | 35 ++-- .../java/org/utplsql/cli/CommandProvider.java | 36 ++++ .../java/org/utplsql/cli/HelpCommand.java | 23 +++ src/main/java/org/utplsql/cli/ICommand.java | 11 ++ src/main/java/org/utplsql/cli/RunCommand.java | 165 ++++++++++-------- .../org/utplsql/cli/VersionInfoCommand.java | 7 +- .../cli/RunCommandCoverageReporterIT.java | 15 +- .../java/org/utplsql/cli/RunCommandIT.java | 15 +- .../java/org/utplsql/cli/RunCommandTest.java | 11 +- ...CommandTestHelper.java => TestHelper.java} | 19 +- .../org/utplsql/cli/VersionInfoCommandIT.java | 24 +-- 11 files changed, 215 insertions(+), 146 deletions(-) create mode 100644 src/main/java/org/utplsql/cli/CommandProvider.java create mode 100644 src/main/java/org/utplsql/cli/HelpCommand.java create mode 100644 src/main/java/org/utplsql/cli/ICommand.java rename src/test/java/org/utplsql/cli/{RunCommandTestHelper.java => TestHelper.java} (58%) diff --git a/src/main/java/org/utplsql/cli/Cli.java b/src/main/java/org/utplsql/cli/Cli.java index ff6a6a5..11a445e 100644 --- a/src/main/java/org/utplsql/cli/Cli.java +++ b/src/main/java/org/utplsql/cli/Cli.java @@ -12,34 +12,31 @@ public class Cli { static final int DEFAULT_ERROR_CODE = 1; static final String HELP_CMD = "-h"; - private static final String RUN_CMD = "run"; - private static final String VERSION_CMD = "info"; public static void main(String[] args) { + int exitCode = runWithExitCode(args); + + System.exit(exitCode); + } + + static int runWithExitCode( String[] args ) { LocaleInitializer.initLocale(); JCommander jc = new JCommander(); jc.setProgramName("utplsql"); - // jc.addCommand(HELP_CMD, new HelpCommand()); - RunCommand runCmd = new RunCommand(); - VersionInfoCommand infoCmd = new VersionInfoCommand(); - jc.addCommand(RUN_CMD, runCmd); - jc.addCommand(VERSION_CMD, infoCmd); + + CommandProvider cmdProvider = new CommandProvider(); + + cmdProvider.commands().forEach(cmd -> jc.addCommand(cmd.getCommand(), cmd)); + int exitCode = DEFAULT_ERROR_CODE; try { jc.parse(args); - if (RUN_CMD.equals(jc.getParsedCommand())) { - exitCode = runCmd.run(); - } - else if ( VERSION_CMD.equals(jc.getParsedCommand()) ) { - exitCode = infoCmd.run(); - } - else { - throw new ParameterException("Command not specified."); - } + exitCode = cmdProvider.getCommand(jc.getParsedCommand()).run(); + } catch (ParameterException e) { if (jc.getParsedCommand() != null) { System.err.println(e.getMessage()); @@ -47,13 +44,11 @@ else if ( VERSION_CMD.equals(jc.getParsedCommand()) ) { } else { jc.usage(); } - } catch ( DatabaseNotCompatibleException | UtPLSQLNotInstalledException | DatabaseConnectionFailed e ) { - System.out.println(e.getMessage()); - } catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } - System.exit(exitCode); + return exitCode; } private static class HelpCommand { diff --git a/src/main/java/org/utplsql/cli/CommandProvider.java b/src/main/java/org/utplsql/cli/CommandProvider.java new file mode 100644 index 0000000..1137dbe --- /dev/null +++ b/src/main/java/org/utplsql/cli/CommandProvider.java @@ -0,0 +1,36 @@ +package org.utplsql.cli; + +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Stream; + +public class CommandProvider { + + private Map commands; + + public CommandProvider() { + init(); + } + + private void init() { + commands = new HashMap<>(); + + addCommand(new RunCommand()); + addCommand(new VersionInfoCommand()); + } + + private void addCommand( ICommand command ) { + commands.put(command.getCommand().toLowerCase(), command); + } + + public ICommand getCommand( String key ) { + if ( commands.containsKey(key)) + return commands.get(key.toLowerCase()); + else + return new HelpCommand("Unknown command: '" + key + "'"); + } + + public Stream commands() { + return commands.values().stream(); + } +} diff --git a/src/main/java/org/utplsql/cli/HelpCommand.java b/src/main/java/org/utplsql/cli/HelpCommand.java new file mode 100644 index 0000000..3476a07 --- /dev/null +++ b/src/main/java/org/utplsql/cli/HelpCommand.java @@ -0,0 +1,23 @@ +package org.utplsql.cli; + +public class HelpCommand implements ICommand { + + private String errorMessage; + + public HelpCommand( String errorMessage ) { + this.errorMessage = errorMessage; + } + + @Override + public int run() { + if ( errorMessage != null ) + System.out.println(errorMessage); + + return 1; + } + + @Override + public String getCommand() { + return "-h"; + } +} diff --git a/src/main/java/org/utplsql/cli/ICommand.java b/src/main/java/org/utplsql/cli/ICommand.java new file mode 100644 index 0000000..4f039dc --- /dev/null +++ b/src/main/java/org/utplsql/cli/ICommand.java @@ -0,0 +1,11 @@ +package org.utplsql.cli; + +/** Interface to decouple JCommander commands + * + * @author pesse + */ +public interface ICommand { + int run(); + + String getCommand(); +} diff --git a/src/main/java/org/utplsql/cli/RunCommand.java b/src/main/java/org/utplsql/cli/RunCommand.java index 0529998..01ecdbd 100644 --- a/src/main/java/org/utplsql/cli/RunCommand.java +++ b/src/main/java/org/utplsql/cli/RunCommand.java @@ -7,7 +7,9 @@ import org.utplsql.api.TestRunner; import org.utplsql.api.Version; import org.utplsql.api.compatibility.CompatibilityProxy; +import org.utplsql.api.exception.DatabaseNotCompatibleException; import org.utplsql.api.exception.SomeTestsFailedException; +import org.utplsql.api.exception.UtPLSQLNotInstalledException; import org.utplsql.api.reporter.Reporter; import org.utplsql.api.reporter.ReporterFactory; import org.utplsql.cli.exception.DatabaseConnectionFailed; @@ -30,7 +32,7 @@ * @author pesse */ @Parameters(separators = "=", commandDescription = "run tests") -public class RunCommand { +public class RunCommand implements ICommand { @Parameter( required = true, @@ -110,102 +112,113 @@ public List getTestPaths() { return testPaths; } - public int run() throws Exception { + public int run() { - final List reporterList; - final List testPaths = getTestPaths(); + try { - final File baseDir = new File("").getAbsoluteFile(); - final FileMapperOptions[] sourceMappingOptions = {null}; - final FileMapperOptions[] testMappingOptions = {null}; + final List reporterList; + final List testPaths = getTestPaths(); - final int[] returnCode = {0}; + final File baseDir = new File("").getAbsoluteFile(); + final FileMapperOptions[] sourceMappingOptions = {null}; + final FileMapperOptions[] testMappingOptions = {null}; - sourceMappingOptions[0] = getFileMapperOptionsByParamListItem(this.sourcePathParams, baseDir); - testMappingOptions[0] = getFileMapperOptionsByParamListItem(this.testPathParams, baseDir); + final int[] returnCode = {0}; - ArrayList includeObjectsList; - ArrayList excludeObjectsList; + sourceMappingOptions[0] = getFileMapperOptionsByParamListItem(this.sourcePathParams, baseDir); + testMappingOptions[0] = getFileMapperOptionsByParamListItem(this.testPathParams, baseDir); - if (includeObjects != null && !includeObjects.isEmpty()) { - includeObjectsList = new ArrayList<>(Arrays.asList(includeObjects.split(","))); - } else { - includeObjectsList = new ArrayList<>(); - } - - if (excludeObjects != null && !excludeObjects.isEmpty()) { - excludeObjectsList = new ArrayList<>(Arrays.asList(excludeObjects.split(","))); - } else { - excludeObjectsList = new ArrayList<>(); - } + ArrayList includeObjectsList; + ArrayList excludeObjectsList; - final ArrayList finalIncludeObjectsList = includeObjectsList; - final ArrayList finalExcludeObjectsList = excludeObjectsList; - - final DataSource dataSource = DataSourceProvider.getDataSource(getConnectionInfo(), getReporterManager().getNumberOfReporters()+1); + if (includeObjects != null && !includeObjects.isEmpty()) { + includeObjectsList = new ArrayList<>(Arrays.asList(includeObjects.split(","))); + } else { + includeObjectsList = new ArrayList<>(); + } - // Do the reporters initialization, so we can use the id to run and gather results. - try (Connection conn = dataSource.getConnection()) { + if (excludeObjects != null && !excludeObjects.isEmpty()) { + excludeObjectsList = new ArrayList<>(Arrays.asList(excludeObjects.split(","))); + } else { + excludeObjectsList = new ArrayList<>(); + } - // Check if orai18n exists if database version is 11g - RunCommandChecker.checkOracleI18nExists(conn); + final ArrayList finalIncludeObjectsList = includeObjectsList; + final ArrayList finalExcludeObjectsList = excludeObjectsList; - // First of all do a compatibility check and fail-fast - compatibilityProxy = checkFrameworkCompatibility(conn); - reporterFactory = ReporterFactoryProvider.createReporterFactory(compatibilityProxy); + final DataSource dataSource = DataSourceProvider.getDataSource(getConnectionInfo(), getReporterManager().getNumberOfReporters() + 1); - reporterList = getReporterManager().initReporters(conn, reporterFactory, compatibilityProxy); + // Do the reporters initialization, so we can use the id to run and gather results. + try (Connection conn = dataSource.getConnection()) { - } catch (SQLException e) { - if ( e.getErrorCode() == 1017 || e.getErrorCode() == 12514 ) { - throw new DatabaseConnectionFailed(e); - } - else { - throw e; - } - } + // Check if orai18n exists if database version is 11g + RunCommandChecker.checkOracleI18nExists(conn); - // Output a message if --failureExitCode is set but database framework is not capable of - String msg = RunCommandChecker.getCheckFailOnErrorMessage(failureExitCode, compatibilityProxy.getDatabaseVersion()); - if ( msg != null ) { - System.out.println(msg); - } + // First of all do a compatibility check and fail-fast + compatibilityProxy = checkFrameworkCompatibility(conn); + reporterFactory = ReporterFactoryProvider.createReporterFactory(compatibilityProxy); - ExecutorService executorService = Executors.newFixedThreadPool(1 + reporterList.size()); + reporterList = getReporterManager().initReporters(conn, reporterFactory, compatibilityProxy); - // Run tests. - executorService.submit(() -> { - try (Connection conn = dataSource.getConnection()) { - TestRunner testRunner = new TestRunner() - .addPathList(testPaths) - .addReporterList(reporterList) - .sourceMappingOptions(sourceMappingOptions[0]) - .testMappingOptions(testMappingOptions[0]) - .colorConsole(this.colorConsole) - .failOnErrors(true) - .skipCompatibilityCheck(skipCompatibilityCheck) - .includeObjects(finalIncludeObjectsList) - .excludeObjects(finalExcludeObjectsList); - - testRunner.run(conn); - } catch (SomeTestsFailedException e) { - returnCode[0] = this.failureExitCode; } catch (SQLException e) { - System.out.println(e.getMessage()); - returnCode[0] = Cli.DEFAULT_ERROR_CODE; - executorService.shutdownNow(); + if (e.getErrorCode() == 1017 || e.getErrorCode() == 12514) { + throw new DatabaseConnectionFailed(e); + } else { + throw e; + } } - }); - // Gather each reporter results on a separate thread. - getReporterManager().startReporterGatherers(executorService, dataSource, returnCode); + // Output a message if --failureExitCode is set but database framework is not capable of + String msg = RunCommandChecker.getCheckFailOnErrorMessage(failureExitCode, compatibilityProxy.getDatabaseVersion()); + if (msg != null) { + System.out.println(msg); + } - executorService.shutdown(); - executorService.awaitTermination(60, TimeUnit.MINUTES); - return returnCode[0]; - } + ExecutorService executorService = Executors.newFixedThreadPool(1 + reporterList.size()); + + // Run tests. + executorService.submit(() -> { + try (Connection conn = dataSource.getConnection()) { + TestRunner testRunner = new TestRunner() + .addPathList(testPaths) + .addReporterList(reporterList) + .sourceMappingOptions(sourceMappingOptions[0]) + .testMappingOptions(testMappingOptions[0]) + .colorConsole(this.colorConsole) + .failOnErrors(true) + .skipCompatibilityCheck(skipCompatibilityCheck) + .includeObjects(finalIncludeObjectsList) + .excludeObjects(finalExcludeObjectsList); + + testRunner.run(conn); + } catch (SomeTestsFailedException e) { + returnCode[0] = this.failureExitCode; + } catch (SQLException e) { + System.out.println(e.getMessage()); + returnCode[0] = Cli.DEFAULT_ERROR_CODE; + executorService.shutdownNow(); + } + }); + // Gather each reporter results on a separate thread. + getReporterManager().startReporterGatherers(executorService, dataSource, returnCode); + executorService.shutdown(); + executorService.awaitTermination(60, TimeUnit.MINUTES); + return returnCode[0]; + } + catch ( DatabaseNotCompatibleException | UtPLSQLNotInstalledException | DatabaseConnectionFailed e ) { + System.out.println(e.getMessage()); + } catch (Exception e) { + e.printStackTrace(); + } + return 1; + } + + @Override + public String getCommand() { + return "run"; + } /** Returns FileMapperOptions for the first item of a given param list in a baseDir diff --git a/src/main/java/org/utplsql/cli/VersionInfoCommand.java b/src/main/java/org/utplsql/cli/VersionInfoCommand.java index 48ce629..916cd3a 100644 --- a/src/main/java/org/utplsql/cli/VersionInfoCommand.java +++ b/src/main/java/org/utplsql/cli/VersionInfoCommand.java @@ -14,7 +14,7 @@ import java.util.List; @Parameters(separators = "=", commandDescription = "prints version information of cli, java-api and - if connection is given - database utPLSQL framework") -public class VersionInfoCommand { +public class VersionInfoCommand implements ICommand { @Parameter( converter = ConnectionInfo.ConnectionStringConverter.class, @@ -54,4 +54,9 @@ public int run() { return 0; } + + @Override + public String getCommand() { + return "info"; + } } diff --git a/src/test/java/org/utplsql/cli/RunCommandCoverageReporterIT.java b/src/test/java/org/utplsql/cli/RunCommandCoverageReporterIT.java index cc661ef..4a1c6af 100644 --- a/src/test/java/org/utplsql/cli/RunCommandCoverageReporterIT.java +++ b/src/test/java/org/utplsql/cli/RunCommandCoverageReporterIT.java @@ -1,16 +1,11 @@ package org.utplsql.cli; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.io.File; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.HashSet; -import java.util.Scanner; -import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -77,10 +72,9 @@ public void run_CodeCoverageWithIncludeAndExclude() throws Exception { Path coveragePath = getTempCoverageFilePath(); - RunCommand runCmd = RunCommandTestHelper.createRunCommand(RunCommandTestHelper.getConnectionString(), + int result = TestHelper.runApp("run", TestHelper.getConnectionString(), "-f=ut_coverage_html_reporter", "-o=" + coveragePath, "-s", "-exclude=app.award_bonus,app.betwnstr"); - int result = runCmd.run(); String content = new String(Files.readAllBytes(coveragePath)); @@ -95,16 +89,13 @@ public void coverageReporterWriteAssetsToOutput() throws Exception { Path coveragePath = getTempCoverageFilePath(); Path coverageAssetsPath = Paths.get(coveragePath.toString() + "_assets"); - RunCommand runCmd = RunCommandTestHelper.createRunCommand(RunCommandTestHelper.getConnectionString(), + TestHelper.runApp("run", TestHelper.getConnectionString(), "-f=ut_coverage_html_reporter", "-o=" + coveragePath, "-s"); - runCmd.run(); - // Run twice to test overriding of assets - runCmd = RunCommandTestHelper.createRunCommand(RunCommandTestHelper.getConnectionString(), + TestHelper.runApp("run", TestHelper.getConnectionString(), "-f=ut_coverage_html_reporter", "-o=" + coveragePath, "-s"); - runCmd.run(); // Check application file exists File applicationJs = coverageAssetsPath.resolve(Paths.get("application.js")).toFile(); diff --git a/src/test/java/org/utplsql/cli/RunCommandIT.java b/src/test/java/org/utplsql/cli/RunCommandIT.java index f2f93fd..f03b4d2 100644 --- a/src/test/java/org/utplsql/cli/RunCommandIT.java +++ b/src/test/java/org/utplsql/cli/RunCommandIT.java @@ -15,16 +15,16 @@ public class RunCommandIT extends AbstractFileOutputTest { @Test public void run_Default() throws Exception { - RunCommand runCmd = RunCommandTestHelper.createRunCommand(RunCommandTestHelper.getConnectionString(), + + int result = TestHelper.runApp("run", + TestHelper.getConnectionString(), "-f=ut_documentation_reporter", "-s", "-c", "--failure-exit-code=2"); - int result = runCmd.run(); - // Only expect failure-exit-code to work on several framework versions - if (OptionalFeatures.FAIL_ON_ERROR.isAvailableFor(runCmd.getDatabaseVersion())) + if (OptionalFeatures.FAIL_ON_ERROR.isAvailableFor(TestHelper.getFrameworkVersion())) assertEquals(2, result); else assertEquals(0, result); @@ -35,7 +35,8 @@ public void run_MultipleReporters() throws Exception { String outputFileName = "output_" + System.currentTimeMillis() + ".xml"; addTempPath(Paths.get(outputFileName)); - RunCommand runCmd = RunCommandTestHelper.createRunCommand(RunCommandTestHelper.getConnectionString(), + int result = TestHelper.runApp("run", + TestHelper.getConnectionString(), "-f=ut_documentation_reporter", "-s", "-f=" + CoreReporters.UT_SONAR_TEST_REPORTER.name(), @@ -43,10 +44,8 @@ public void run_MultipleReporters() throws Exception { "-c", "--failure-exit-code=2"); - int result = runCmd.run(); - // Only expect failure-exit-code to work on several framework versions - if (OptionalFeatures.FAIL_ON_ERROR.isAvailableFor(runCmd.getDatabaseVersion())) + if (OptionalFeatures.FAIL_ON_ERROR.isAvailableFor(TestHelper.getFrameworkVersion())) assertEquals(2, result); else assertEquals(0, result); diff --git a/src/test/java/org/utplsql/cli/RunCommandTest.java b/src/test/java/org/utplsql/cli/RunCommandTest.java index ba6df7c..5658e59 100644 --- a/src/test/java/org/utplsql/cli/RunCommandTest.java +++ b/src/test/java/org/utplsql/cli/RunCommandTest.java @@ -1,7 +1,6 @@ package org.utplsql.cli; import org.junit.jupiter.api.Test; -import org.utplsql.api.CustomTypes; import org.utplsql.api.reporter.CoreReporters; import java.util.List; @@ -15,7 +14,7 @@ public class RunCommandTest { @Test public void reporterOptions_Default() { - RunCommand runCmd = RunCommandTestHelper.createRunCommand(RunCommandTestHelper.getConnectionString()); + RunCommand runCmd = TestHelper.createRunCommand(TestHelper.getConnectionString()); List reporterOptionsList = runCmd.getReporterOptionsList(); @@ -28,7 +27,7 @@ public void reporterOptions_Default() { @Test public void reporterOptions_OneReporter() { - RunCommand runCmd = RunCommandTestHelper.createRunCommand(RunCommandTestHelper.getConnectionString(), "-f=ut_documentation_reporter", "-o=output.txt"); + RunCommand runCmd = TestHelper.createRunCommand(TestHelper.getConnectionString(), "-f=ut_documentation_reporter", "-o=output.txt"); List reporterOptionsList = runCmd.getReporterOptionsList(); @@ -41,7 +40,7 @@ public void reporterOptions_OneReporter() { @Test public void reporterOptions_OneReporterForceScreen() { - RunCommand runCmd = RunCommandTestHelper.createRunCommand(RunCommandTestHelper.getConnectionString(), "-f=ut_documentation_reporter", "-o=output.txt", "-s"); + RunCommand runCmd = TestHelper.createRunCommand(TestHelper.getConnectionString(), "-f=ut_documentation_reporter", "-o=output.txt", "-s"); List reporterOptionsList = runCmd.getReporterOptionsList(); @@ -54,7 +53,7 @@ public void reporterOptions_OneReporterForceScreen() { @Test public void reporterOptions_OneReporterForceScreenInverse() { - RunCommand runCmd = RunCommandTestHelper.createRunCommand(RunCommandTestHelper.getConnectionString(), "-f=ut_documentation_reporter", "-s", "-o=output.txt"); + RunCommand runCmd = TestHelper.createRunCommand(TestHelper.getConnectionString(), "-f=ut_documentation_reporter", "-s", "-o=output.txt"); List reporterOptionsList = runCmd.getReporterOptionsList(); @@ -67,7 +66,7 @@ public void reporterOptions_OneReporterForceScreenInverse() { @Test public void reporterOptions_TwoReporters() { - RunCommand runCmd = RunCommandTestHelper.createRunCommand(RunCommandTestHelper.getConnectionString(), + RunCommand runCmd = TestHelper.createRunCommand(TestHelper.getConnectionString(), "-f=ut_documentation_reporter", "-f=ut_coverage_html_reporter", "-o=coverage.html", "-s"); diff --git a/src/test/java/org/utplsql/cli/RunCommandTestHelper.java b/src/test/java/org/utplsql/cli/TestHelper.java similarity index 58% rename from src/test/java/org/utplsql/cli/RunCommandTestHelper.java rename to src/test/java/org/utplsql/cli/TestHelper.java index 425659a..ca1abc9 100644 --- a/src/test/java/org/utplsql/cli/RunCommandTestHelper.java +++ b/src/test/java/org/utplsql/cli/TestHelper.java @@ -1,9 +1,15 @@ package org.utplsql.cli; import com.beust.jcommander.JCommander; +import org.utplsql.api.DBHelper; import org.utplsql.api.EnvironmentVariableUtil; +import org.utplsql.api.Version; -class RunCommandTestHelper { +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; + +class TestHelper { private static String sUrl; private static String sUser; private static String sPass; @@ -25,6 +31,17 @@ static RunCommand createRunCommand(String... args) { return runCmd; } + static int runApp(String... args) { + return Cli.runWithExitCode(args); + } + + static Version getFrameworkVersion() throws SQLException { + DataSource ds = DataSourceProvider.getDataSource(new ConnectionInfo(TestHelper.getConnectionString()), 1); + try (Connection con = ds.getConnection() ) { + return DBHelper.getDatabaseFrameworkVersion(con); + } + } + static String getConnectionString() { return sUser + "/" + sPass + "@" + sUrl; } diff --git a/src/test/java/org/utplsql/cli/VersionInfoCommandIT.java b/src/test/java/org/utplsql/cli/VersionInfoCommandIT.java index 33ed77b..44a5fbe 100644 --- a/src/test/java/org/utplsql/cli/VersionInfoCommandIT.java +++ b/src/test/java/org/utplsql/cli/VersionInfoCommandIT.java @@ -1,8 +1,6 @@ package org.utplsql.cli; -import com.beust.jcommander.JCommander; import org.junit.jupiter.api.Test; -import org.utplsql.api.EnvironmentVariableUtil; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -11,32 +9,14 @@ public class VersionInfoCommandIT { @Test public void infoCommandRunsWithoutConnection() throws Exception { - VersionInfoCommand infoCmd = new VersionInfoCommand(); - - JCommander.newBuilder() - .addObject(infoCmd) - .args(new String[]{}) - .build(); - - int result = infoCmd.run(); + int result = TestHelper.runApp("info"); assertEquals(0, result); } @Test public void infoCommandRunsWithConnection() throws Exception { - String Url = EnvironmentVariableUtil.getEnvValue("DB_URL", "192.168.99.100:1521:XE"); - String sUser = EnvironmentVariableUtil.getEnvValue("DB_USER", "app"); - String sPass = EnvironmentVariableUtil.getEnvValue("DB_PASS", "app"); - - VersionInfoCommand infoCmd = new VersionInfoCommand(); - - JCommander.newBuilder() - .addObject(infoCmd) - .args(new String[]{sUser + "/" + sPass + "@" + Url}) - .build(); - - int result = infoCmd.run(); + int result = TestHelper.runApp("info", TestHelper.getConnectionString()); assertEquals(0, result); } From 32360871bb73977d629863abf6bf32329dc97c81 Mon Sep 17 00:00:00 2001 From: pesse Date: Thu, 7 Jun 2018 21:39:24 +0200 Subject: [PATCH 04/11] Improved tests for VersionInfoCommand --- .../org/utplsql/cli/VersionInfoCommandIT.java | 38 ++++++++++ .../utplsql/cli/util/SystemOutCapturer.java | 74 +++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 src/test/java/org/utplsql/cli/util/SystemOutCapturer.java diff --git a/src/test/java/org/utplsql/cli/VersionInfoCommandIT.java b/src/test/java/org/utplsql/cli/VersionInfoCommandIT.java index 44a5fbe..6f4ffdc 100644 --- a/src/test/java/org/utplsql/cli/VersionInfoCommandIT.java +++ b/src/test/java/org/utplsql/cli/VersionInfoCommandIT.java @@ -1,23 +1,61 @@ package org.utplsql.cli; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.utplsql.cli.util.SystemOutCapturer; + +import java.io.IOException; +import java.util.Arrays; import static org.junit.jupiter.api.Assertions.assertEquals; public class VersionInfoCommandIT { + private SystemOutCapturer capturer; + + @BeforeEach + public void setupCaptureSystemOut() { + capturer = new SystemOutCapturer(); + } + + private int getNonEmptyLines(String content) { + return (int) Arrays.stream(content.split("[\n|\r]")) + .filter(line -> !line.isEmpty()) + .count(); + } + + private void assertNumberOfLines( int expected, String content ) { + int numOfLines = getNonEmptyLines(content); + assertEquals(expected, numOfLines, String.format("Expected output to have %n lines, but got %n", expected, numOfLines)); + } @Test public void infoCommandRunsWithoutConnection() throws Exception { + capturer.start(); + int result = TestHelper.runApp("info"); + String output = capturer.stop(); + assertEquals(0, result); + assertNumberOfLines(2, output); } @Test public void infoCommandRunsWithConnection() throws Exception { + capturer.start(); + int result = TestHelper.runApp("info", TestHelper.getConnectionString()); + String output = capturer.stop(); + assertEquals(0, result); + assertNumberOfLines(3, output); + } + + @AfterEach + public void cleanupCaptureSystemOut() throws IOException { + capturer.stop(); } } diff --git a/src/test/java/org/utplsql/cli/util/SystemOutCapturer.java b/src/test/java/org/utplsql/cli/util/SystemOutCapturer.java new file mode 100644 index 0000000..33f60d6 --- /dev/null +++ b/src/test/java/org/utplsql/cli/util/SystemOutCapturer.java @@ -0,0 +1,74 @@ +package org.utplsql.cli.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.Arrays; +import java.util.List; + +/** All credit to Manasjyoti Sharma: https://stackoverflow.com/a/30665299 + */ +public class SystemOutCapturer { + private ByteArrayOutputStream baos; + private PrintStream previous; + private boolean capturing; + + public void start() { + if (capturing) { + return; + } + + capturing = true; + previous = System.out; + baos = new ByteArrayOutputStream(); + + OutputStream outputStreamCombiner = + new OutputStreamCombiner(Arrays.asList(previous, baos)); + PrintStream custom = new PrintStream(outputStreamCombiner); + + System.setOut(custom); + } + + public String stop() { + if (!capturing) { + return ""; + } + + System.setOut(previous); + + String capturedValue = baos.toString(); + + baos = null; + previous = null; + capturing = false; + + return capturedValue; + } + + private static class OutputStreamCombiner extends OutputStream { + private List outputStreams; + + public OutputStreamCombiner(List outputStreams) { + this.outputStreams = outputStreams; + } + + public void write(int b) throws IOException { + for (OutputStream os : outputStreams) { + os.write(b); + } + } + + public void flush() throws IOException { + for (OutputStream os : outputStreams) { + os.flush(); + } + } + + public void close() throws IOException { + for (OutputStream os : outputStreams) { + os.close(); + } + } + } +} From 63265144f0c03d4349f5fe57b075791b66a52a9f Mon Sep 17 00:00:00 2001 From: pesse Date: Fri, 8 Jun 2018 00:48:01 +0200 Subject: [PATCH 05/11] Updated help --- README.md | 128 +++++++++++------- .../java/org/utplsql/cli/CliHelpTest.java | 11 ++ 2 files changed, 88 insertions(+), 51 deletions(-) create mode 100644 src/test/java/org/utplsql/cli/CliHelpTest.java diff --git a/README.md b/README.md index bdcb055..eccd8b0 100644 --- a/README.md +++ b/README.md @@ -39,17 +39,25 @@ export LC_ALL=en_US.utf-8 The charset-part of LC_ALL is ignored. ## Usage +Currently, utPLSQL-cli knows the following commands: +- run +- info -`utplsql run [-p=(ut_path|ut_paths)] [-f=format [-o=output_file] [-s] ...]` - +### run +`utplsql run []` + ``` - accepted formats: - /@//[:]/ - /@:: - /@ - To connect using TNS, you need to have the ORACLE_HOME environment variable set. - The file tnsnames.ora must exist in path %ORACLE_HOME%/network/admin - The file tnsnames.ora must contain valid TNS entries. + /@//[:]/ + /@:: + /@ + To connect using TNS, you need to have the ORACLE_HOME environment variable set. + The file tnsnames.ora must exist in path %ORACLE_HOME%/network/admin + The file tnsnames.ora must contain valid TNS entries. +``` + +#### Options +``` -p=suite_path(s) - A suite path or a comma separated list of suite paths for unit test to be executed. The path(s) can be in one of the following formats: schema[.package[.procedure]] @@ -57,66 +65,54 @@ The charset-part of LC_ALL is ignored. Both formats can be mixed in the list. If only schema is provided, then all suites owner by that schema are executed. If -p is omitted, the current schema is used. + -f=format - A reporter to be used for reporting. If no -f option is provided, the default ut_documentation_reporter is used. - Available options: - -f=ut_documentation_reporter - A textual pretty-print of unit test results (usually use for console output) - -f=ut_teamcity_reporter - For reporting live progress of test execution with Teamcity CI. - -f=ut_xunit_reporter - Used for reporting test results with CI servers like Jenkins/Hudson/Teamcity. - -f=ut_coverage_html_reporter - Generates a HTML coverage report with summary and line by line information on code coverage. - Based on open-source simplecov-html coverage reporter for Ruby. - Includes source code in the report. - -f=ut_coveralls_reporter - Generates a JSON coverage report providing information on code coverage with line numbers. - Designed for [Coveralls](https://coveralls.io/). - -f=ut_coverage_sonar_reporter - Generates a JSON coverage report providing information on code coverage with line numbers. - Designed for [SonarQube](https://about.sonarqube.com/) to report coverage. - -f=ut_sonar_test_reporter - Generates a JSON report providing detailed information on test execution. - Designed for [SonarQube](https://about.sonarqube.com/) to report test execution. - - -o=output - Defines file name to save the output from the specified reporter. + See reporters list for possible values + -o=output - Defines file name to save the output from the specified reporter. If defined, the output is not displayed on screen by default. This can be changed with the -s parameter. If not defined, then output will be displayed on screen, even if the parameter -s is not specified. If more than one -o parameter is specified for one -f parameter, the last one is taken into consideration. - -s - Forces putting output to to screen for a given -f parameter. + -s - Forces putting output to to screen for a given -f parameter. + -source_path=source - path to project source files, use the following options to enable custom type mappings: - -owner="app" - -regex_expression="pattern" - -type_mapping="matched_string=TYPE[/matched_string=TYPE]*" - -owner_subexpression=subexpression_number - -type_subexpression=subexpression_number - -name_subexpression=subexpression_number + -owner="app" + -regex_expression="pattern" + -type_mapping="matched_string=TYPE[/matched_string=TYPE]*" + -owner_subexpression=subexpression_number + -type_subexpression=subexpression_number + -name_subexpression=subexpression_number + -test_path=test - path to project test files, use the following options to enable custom type mappings: - -owner="app" - -regex_expression="pattern" - -type_mapping="matched_string=TYPE[/matched_string=TYPE]*" - -owner_subexpression=subexpression_number - -type_subexpression=subexpression_number - -name_subexpression=subexpression_number + -owner="app" + -regex_expression="pattern" + -type_mapping="matched_string=TYPE[/matched_string=TYPE]*" + -owner_subexpression=subexpression_number + -type_subexpression=subexpression_number + -name_subexpression=subexpression_number + -c - If specified, enables printing of test results in colors as defined by ANSICONSOLE standards. Works only on reporeters that support colors (ut_documentation_reporter). + --failure-exit-code - Override the exit code on failure, defaults to 1. You can set it to 0 to always exit with a success status. + -scc - If specified, skips the compatibility-check with the version of the database framework. If you skip compatibility-check, CLI will expect the most actual framework version --include=package_list - Comma-separated object list to include in the coverage report. - Format: [schema.]package[,[schema.]package ...]. - See coverage reporting options in framework documentation. --exclude=package_list - Comma-separated object list to exclude from the coverage report. - Format: [schema.]package[,[schema.]package ...]. - See coverage reporting options in framework documentation. + +-include=pckg_list - Comma-separated object list to include in the coverage report. + Format: [schema.]package[,[schema.]package ...]. + See coverage reporting options in framework documentation. + +-exclude=pckg_list - Comma-separated object list to exclude from the coverage report. + Format: [schema.]package[,[schema.]package ...]. + See coverage reporting options in framework documentation. ``` Parameters -f, -o, -s are correlated. That is parameters -o and -s are controlling outputs for reporter specified by the preceding -f parameter. Sonar and Coveralls reporter will only provide valid reports, when source_path and/or test_path are provided, and ut_run is executed from your project's root path. -Examples: +#### Examples ``` utplsql run hr/hr@xe -p=hr_test -f=ut_documentation_reporter -o=run.log -s -f=ut_coverage_html_reporter -o=coverage.html -source_path=source @@ -133,7 +129,37 @@ utplsql run hr/hr@xe Invokes all unit test suites from schema "hr". Results are displayed to screen using default ut_documentation_reporter. -#### Enabling Color Outputs on Windows +### info +`utplsql info []` + +``` + - accepted formats: + /@//[:]/ + /@:: + /@ + To connect using TNS, you need to have the ORACLE_HOME environment variable set. + The file tnsnames.ora must exist in path %ORACLE_HOME%/network/admin + The file tnsnames.ora must contain valid TNS entries. +``` + +#### Examples + +``` +utplsql info + +> cli 3.1.1-SNAPSHOT.local +> utPLSQL-java-api 3.1.1-SNAPSHOT.123 +``` +``` +utplsql info app/app@localhost:1521/ORCLPDB1 + +> cli 3.1.1-SNAPSHOT.local +> utPLSQL-java-api 3.1.1-SNAPSHOT.123 +> utPLSQL 3.1.2.1913 +``` + + +## Enabling Color Outputs on Windows To enable color outputs on Windows cmd you need to install an open-source utility called [ANSICON](http://adoxa.altervista.org/ansicon/). diff --git a/src/test/java/org/utplsql/cli/CliHelpTest.java b/src/test/java/org/utplsql/cli/CliHelpTest.java new file mode 100644 index 0000000..6e87370 --- /dev/null +++ b/src/test/java/org/utplsql/cli/CliHelpTest.java @@ -0,0 +1,11 @@ +package org.utplsql.cli; + +import org.junit.jupiter.api.Test; + +public class CliHelpTest { + + @Test + public void showBasicHelp() { + TestHelper.runApp("help"); + } +} From feff4a32b8625d6f4950ba8bfc3cf32c23128d1c Mon Sep 17 00:00:00 2001 From: pesse Date: Fri, 8 Jun 2018 01:16:25 +0200 Subject: [PATCH 06/11] Added another command: reporters --- .../java/org/utplsql/cli/CommandProvider.java | 1 + .../utplsql/cli/ReporterFactoryProvider.java | 7 +++ .../org/utplsql/cli/ReportersCommand.java | 59 +++++++++++++++++++ .../org/utplsql/cli/ReportersCommandIT.java | 16 +++++ 4 files changed, 83 insertions(+) create mode 100644 src/main/java/org/utplsql/cli/ReportersCommand.java create mode 100644 src/test/java/org/utplsql/cli/ReportersCommandIT.java diff --git a/src/main/java/org/utplsql/cli/CommandProvider.java b/src/main/java/org/utplsql/cli/CommandProvider.java index 1137dbe..898eb2a 100644 --- a/src/main/java/org/utplsql/cli/CommandProvider.java +++ b/src/main/java/org/utplsql/cli/CommandProvider.java @@ -17,6 +17,7 @@ private void init() { addCommand(new RunCommand()); addCommand(new VersionInfoCommand()); + addCommand(new ReportersCommand()); } private void addCommand( ICommand command ) { diff --git a/src/main/java/org/utplsql/cli/ReporterFactoryProvider.java b/src/main/java/org/utplsql/cli/ReporterFactoryProvider.java index 31fd314..3226054 100644 --- a/src/main/java/org/utplsql/cli/ReporterFactoryProvider.java +++ b/src/main/java/org/utplsql/cli/ReporterFactoryProvider.java @@ -5,6 +5,9 @@ import org.utplsql.api.reporter.ReporterFactory; import org.utplsql.cli.reporters.LocalAssetsCoverageHTMLReporter; +import java.sql.Connection; +import java.sql.SQLException; + /** A simple class to provide a ReporterFactory for the RunCommand * * @author pesse @@ -17,4 +20,8 @@ public static ReporterFactory createReporterFactory(CompatibilityProxy proxy ) { return reporterFactory; } + + public static ReporterFactory createReporterFactory(Connection con ) throws SQLException { + return createReporterFactory(new CompatibilityProxy(con)); + } } diff --git a/src/main/java/org/utplsql/cli/ReportersCommand.java b/src/main/java/org/utplsql/cli/ReportersCommand.java new file mode 100644 index 0000000..7e3e9b2 --- /dev/null +++ b/src/main/java/org/utplsql/cli/ReportersCommand.java @@ -0,0 +1,59 @@ +package org.utplsql.cli; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import org.utplsql.api.compatibility.CompatibilityProxy; +import org.utplsql.api.reporter.ReporterFactory; +import org.utplsql.api.reporter.inspect.ReporterInfo; +import org.utplsql.api.reporter.inspect.ReporterInspector; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +@Parameters(separators = "=", commandDescription = "prints a list of reporters available in the specified database") +public class ReportersCommand implements ICommand { + + @Parameter( + converter = ConnectionInfo.ConnectionStringConverter.class, + arity = 1, + description = ConnectionInfo.COMMANDLINE_PARAM_DESCRIPTION) + private List connectionInfoList = new ArrayList<>(); + + public ConnectionInfo getConnectionInfo() { + if ( connectionInfoList != null && connectionInfoList.size() > 0 ) + return connectionInfoList.get(0); + else + return null; + } + + @Override + public int run() { + + DataSource ds = DataSourceProvider.getDataSource(getConnectionInfo(), 1); + try (Connection con = ds.getConnection() ) { + + ReporterFactory reporterFactory = ReporterFactoryProvider.createReporterFactory(con); + + ReporterInspector.create(reporterFactory, con).getReporterInfos().stream() + .sorted(Comparator.comparing(ReporterInfo::getName)) + .forEach(r -> { + System.out.println(r.getName() + " (" + r.getType().name() + "): " + r.getDescription()); + System.out.println(); + }); + } + catch ( Exception e ) { + e.printStackTrace(); + return 1; + } + + return 0; + } + + @Override + public String getCommand() { + return "reporters"; + } +} diff --git a/src/test/java/org/utplsql/cli/ReportersCommandIT.java b/src/test/java/org/utplsql/cli/ReportersCommandIT.java new file mode 100644 index 0000000..91a90d7 --- /dev/null +++ b/src/test/java/org/utplsql/cli/ReportersCommandIT.java @@ -0,0 +1,16 @@ +package org.utplsql.cli; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ReportersCommandIT { + + @Test + public void callReportersWorks() { + + int result = TestHelper.runApp("reporters", TestHelper.getConnectionString()); + + assertEquals(0, result); + } +} From 52d4368d16d79f38ae05663cfb6d27bc7146b2c7 Mon Sep 17 00:00:00 2001 From: pesse Date: Fri, 8 Jun 2018 01:20:06 +0200 Subject: [PATCH 07/11] Added documentation --- README.md | 75 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 65 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index eccd8b0..ab98e79 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ The charset-part of LC_ALL is ignored. Currently, utPLSQL-cli knows the following commands: - run - info +- reporters ### run `utplsql run []` @@ -68,7 +69,7 @@ Currently, utPLSQL-cli knows the following commands: -f=format - A reporter to be used for reporting. If no -f option is provided, the default ut_documentation_reporter is used. - See reporters list for possible values + See reporters command for possible values -o=output - Defines file name to save the output from the specified reporter. If defined, the output is not displayed on screen by default. This can be changed with the -s parameter. If not defined, then output will be displayed on screen, even if the parameter -s is not specified. @@ -115,7 +116,7 @@ Sonar and Coveralls reporter will only provide valid reports, when source_path a #### Examples ``` -utplsql run hr/hr@xe -p=hr_test -f=ut_documentation_reporter -o=run.log -s -f=ut_coverage_html_reporter -o=coverage.html -source_path=source +> utplsql run hr/hr@xe -p=hr_test -f=ut_documentation_reporter -o=run.log -s -f=ut_coverage_html_reporter -o=coverage.html -source_path=source ``` Invokes all Unit tests from schema/package "hr_test" with two reporters: @@ -124,7 +125,7 @@ Invokes all Unit tests from schema/package "hr_test" with two reporters: * ut_coverage_html_reporter - will report only on database objects that are mapping to file structure from "source" folder and save output to file "coverage.html" ``` -utplsql run hr/hr@xe +> utplsql run hr/hr@xe ``` Invokes all unit test suites from schema "hr". Results are displayed to screen using default ut_documentation_reporter. @@ -145,19 +146,73 @@ Invokes all unit test suites from schema "hr". Results are displayed to screen u #### Examples ``` -utplsql info +> utplsql info -> cli 3.1.1-SNAPSHOT.local -> utPLSQL-java-api 3.1.1-SNAPSHOT.123 +cli 3.1.1-SNAPSHOT.local +utPLSQL-java-api 3.1.1-SNAPSHOT.123 ``` ``` -utplsql info app/app@localhost:1521/ORCLPDB1 +> utplsql info app/app@localhost:1521/ORCLPDB1 -> cli 3.1.1-SNAPSHOT.local -> utPLSQL-java-api 3.1.1-SNAPSHOT.123 -> utPLSQL 3.1.2.1913 +cli 3.1.1-SNAPSHOT.local +utPLSQL-java-api 3.1.1-SNAPSHOT.123 +utPLSQL 3.1.2.1913 ``` +### reporters +`utplsql info ` + +``` + - accepted formats: + /@//[:]/ + /@:: + /@ + To connect using TNS, you need to have the ORACLE_HOME environment variable set. + The file tnsnames.ora must exist in path %ORACLE_HOME%/network/admin + The file tnsnames.ora must contain valid TNS entries. +``` + +#### Examples +``` +> utplsql reporters app/app@localhost:1521/ORCLPDB1 + +UT_COVERAGE_COBERTURA_REPORTER (SQL): Generates a Cobertura coverage report providing information on code coverage with line numbers. +Designed for Jenkins and TFS to report coverage. +Cobertura Document Type Definition can be found: http://cobertura.sourceforge.net/xml/coverage-04.dtd. +Sample file: https://github.com/leobalter/testing-examples/blob/master/solutions/3/report/cobertura-coverage.xml. + +UT_COVERAGE_HTML_REPORTER (SQL_WITH_JAVA): Generates a HTML coverage report with summary and line by line information on code coverage. +Based on open-source simplecov-html coverage reporter for Ruby. +Includes source code in the report. +Will copy all necessary assets to a folder named after the Output-File + +UT_COVERAGE_SONAR_REPORTER (SQL): Generates a JSON coverage report providing information on code coverage with line numbers. +Designed for [SonarQube](https://about.sonarqube.com/) to report coverage. +JSON format returned conforms with the Sonar specification: https://docs.sonarqube.org/display/SONAR/Generic+Test+Data + +UT_COVERALLS_REPORTER (SQL): Generates a JSON coverage report providing information on code coverage with line numbers. +Designed for [Coveralls](https://coveralls.io/). +JSON format conforms with specification: https://docs.coveralls.io/api-introduction + +UT_DOCUMENTATION_REPORTER (SQL_WITH_JAVA): A textual pretty-print of unit test results (usually use for console output) +Provides additional properties lvl and failed + +UT_JUNIT_REPORTER (SQL): Provides outcomes in a format conforming with JUnit 4 and above as defined in: https://gist.github.com/kuzuha/232902acab1344d6b578 + +UT_SONAR_TEST_REPORTER (SQL): Generates a JSON report providing detailed information on test execution. +Designed for [SonarQube](https://about.sonarqube.com/) to report test execution. +JSON format returned conforms with the Sonar specification: https://docs.sonarqube.org/display/SONAR/Generic+Test+Data + +UT_TEAMCITY_REPORTER (SQL): Provides the TeamCity (a CI server by jetbrains) reporting-format that allows tracking of progress of a CI step/task as it executes. +https://confluence.jetbrains.com/display/TCD9/Build+Script+Interaction+with+TeamCity + +UT_TFS_JUNIT_REPORTER (SQL): Provides outcomes in a format conforming with JUnit version for TFS / VSTS. + As defined by specs :https://docs.microsoft.com/en-us/vsts/build-release/tasks/test/publish-test-results?view=vsts + Version is based on windy road junit https://github.com/windyroad/JUnit-Schema/blob/master/JUnit.xsd. + +UT_XUNIT_REPORTER (SQL): Depracated reporter. Please use Junit. + Provides outcomes in a format conforming with JUnit 4 and above as defined in: https://gist.github.com/kuzuha/232902acab1344d6b578 +``` ## Enabling Color Outputs on Windows From 808a2d6dd5e4d0004085e18af9bc7f034f177428 Mon Sep 17 00:00:00 2001 From: pesse Date: Fri, 8 Jun 2018 09:56:03 +0200 Subject: [PATCH 08/11] Some improvements to documentation --- README.md | 46 ++++++++++++++++------------------------------ 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index ab98e79..ef8b014 100644 --- a/README.md +++ b/README.md @@ -39,23 +39,28 @@ export LC_ALL=en_US.utf-8 The charset-part of LC_ALL is ignored. ## Usage -Currently, utPLSQL-cli knows the following commands: +Currently, utPLSQL-cli supports the following commands: - run - info - reporters +#### \ + +This is used in all commands as first parameter (though it's optional for `info`). + +Accepted formats: + +- `/@//[:]/` +- `/@::` +- `/@` + +To connect using TNS, you need to have the ORACLE_HOME environment variable set. +The file tnsnames.ora must exist in path %ORACLE_HOME%/network/admin +The file tnsnames.ora must contain valid TNS entries. + ### run `utplsql run []` -``` - - accepted formats: - /@//[:]/ - /@:: - /@ - To connect using TNS, you need to have the ORACLE_HOME environment variable set. - The file tnsnames.ora must exist in path %ORACLE_HOME%/network/admin - The file tnsnames.ora must contain valid TNS entries. -``` #### Options ``` @@ -133,15 +138,6 @@ Invokes all unit test suites from schema "hr". Results are displayed to screen u ### info `utplsql info []` -``` - - accepted formats: - /@//[:]/ - /@:: - /@ - To connect using TNS, you need to have the ORACLE_HOME environment variable set. - The file tnsnames.ora must exist in path %ORACLE_HOME%/network/admin - The file tnsnames.ora must contain valid TNS entries. -``` #### Examples @@ -160,17 +156,7 @@ utPLSQL 3.1.2.1913 ``` ### reporters -`utplsql info ` - -``` - - accepted formats: - /@//[:]/ - /@:: - /@ - To connect using TNS, you need to have the ORACLE_HOME environment variable set. - The file tnsnames.ora must exist in path %ORACLE_HOME%/network/admin - The file tnsnames.ora must contain valid TNS entries. -``` +`utplsql reporters ` #### Examples ``` From 554c71bbd3a02b6967f0910c3088ee9faddfb69f Mon Sep 17 00:00:00 2001 From: pesse Date: Tue, 12 Jun 2018 22:48:58 +0200 Subject: [PATCH 09/11] Refactoring of ReportersCommand Also much nicer formatting --- README.md | 56 +++++++++---------- .../org/utplsql/cli/ReportersCommand.java | 56 +++++++++++++++---- 2 files changed, 74 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index ef8b014..2aa2e8b 100644 --- a/README.md +++ b/README.md @@ -162,42 +162,42 @@ utPLSQL 3.1.2.1913 ``` > utplsql reporters app/app@localhost:1521/ORCLPDB1 -UT_COVERAGE_COBERTURA_REPORTER (SQL): Generates a Cobertura coverage report providing information on code coverage with line numbers. -Designed for Jenkins and TFS to report coverage. -Cobertura Document Type Definition can be found: http://cobertura.sourceforge.net/xml/coverage-04.dtd. -Sample file: https://github.com/leobalter/testing-examples/blob/master/solutions/3/report/cobertura-coverage.xml. +UT_COVERAGE_COBERTURA_REPORTER Generates a Cobertura coverage report providing information on code coverage with line numbers. + Designed for Jenkins and TFS to report coverage. + Cobertura Document Type Definition can be found: http://cobertura.sourceforge.net/xml/coverage-04.dtd. + Sample file: https://github.com/leobalter/testing-examples/blob/master/solutions/3/report/cobertura-coverage.xml. -UT_COVERAGE_HTML_REPORTER (SQL_WITH_JAVA): Generates a HTML coverage report with summary and line by line information on code coverage. -Based on open-source simplecov-html coverage reporter for Ruby. -Includes source code in the report. -Will copy all necessary assets to a folder named after the Output-File +UT_COVERAGE_HTML_REPORTER Generates a HTML coverage report with summary and line by line information on code coverage. + Based on open-source simplecov-html coverage reporter for Ruby. + Includes source code in the report. + Will copy all necessary assets to a folder named after the Output-File -UT_COVERAGE_SONAR_REPORTER (SQL): Generates a JSON coverage report providing information on code coverage with line numbers. -Designed for [SonarQube](https://about.sonarqube.com/) to report coverage. -JSON format returned conforms with the Sonar specification: https://docs.sonarqube.org/display/SONAR/Generic+Test+Data +UT_COVERAGE_SONAR_REPORTER Generates a JSON coverage report providing information on code coverage with line numbers. + Designed for [SonarQube](https://about.sonarqube.com/) to report coverage. + JSON format returned conforms with the Sonar specification: https://docs.sonarqube.org/display/SONAR/Generic+Test+Data -UT_COVERALLS_REPORTER (SQL): Generates a JSON coverage report providing information on code coverage with line numbers. -Designed for [Coveralls](https://coveralls.io/). -JSON format conforms with specification: https://docs.coveralls.io/api-introduction +UT_COVERALLS_REPORTER Generates a JSON coverage report providing information on code coverage with line numbers. + Designed for [Coveralls](https://coveralls.io/). + JSON format conforms with specification: https://docs.coveralls.io/api-introduction -UT_DOCUMENTATION_REPORTER (SQL_WITH_JAVA): A textual pretty-print of unit test results (usually use for console output) -Provides additional properties lvl and failed +UT_DOCUMENTATION_REPORTER A textual pretty-print of unit test results (usually use for console output) + Provides additional properties lvl and failed -UT_JUNIT_REPORTER (SQL): Provides outcomes in a format conforming with JUnit 4 and above as defined in: https://gist.github.com/kuzuha/232902acab1344d6b578 +UT_JUNIT_REPORTER Provides outcomes in a format conforming with JUnit 4 and above as defined in: https://gist.github.com/kuzuha/232902acab1344d6b578 -UT_SONAR_TEST_REPORTER (SQL): Generates a JSON report providing detailed information on test execution. -Designed for [SonarQube](https://about.sonarqube.com/) to report test execution. -JSON format returned conforms with the Sonar specification: https://docs.sonarqube.org/display/SONAR/Generic+Test+Data +UT_SONAR_TEST_REPORTER Generates a JSON report providing detailed information on test execution. + Designed for [SonarQube](https://about.sonarqube.com/) to report test execution. + JSON format returned conforms with the Sonar specification: https://docs.sonarqube.org/display/SONAR/Generic+Test+Data -UT_TEAMCITY_REPORTER (SQL): Provides the TeamCity (a CI server by jetbrains) reporting-format that allows tracking of progress of a CI step/task as it executes. -https://confluence.jetbrains.com/display/TCD9/Build+Script+Interaction+with+TeamCity +UT_TEAMCITY_REPORTER Provides the TeamCity (a CI server by jetbrains) reporting-format that allows tracking of progress of a CI step/task as it executes. + https://confluence.jetbrains.com/display/TCD9/Build+Script+Interaction+with+TeamCity -UT_TFS_JUNIT_REPORTER (SQL): Provides outcomes in a format conforming with JUnit version for TFS / VSTS. - As defined by specs :https://docs.microsoft.com/en-us/vsts/build-release/tasks/test/publish-test-results?view=vsts - Version is based on windy road junit https://github.com/windyroad/JUnit-Schema/blob/master/JUnit.xsd. +UT_TFS_JUNIT_REPORTER Provides outcomes in a format conforming with JUnit version for TFS / VSTS. + As defined by specs :https://docs.microsoft.com/en-us/vsts/build-release/tasks/test/publish-test-results?view=vsts + Version is based on windy road junit https://github.com/windyroad/JUnit-Schema/blob/master/JUnit.xsd. -UT_XUNIT_REPORTER (SQL): Depracated reporter. Please use Junit. - Provides outcomes in a format conforming with JUnit 4 and above as defined in: https://gist.github.com/kuzuha/232902acab1344d6b578 +UT_XUNIT_REPORTER Depracated reporter. Please use Junit. + Provides outcomes in a format conforming with JUnit 4 and above as defined in: https://gist.github.com/kuzuha/232902acab1344d6b578 ``` ## Enabling Color Outputs on Windows @@ -210,4 +210,4 @@ Since v3.1.0 you can call custom reporters (PL/SQL) via cli, too. Just call the ``` utplsql run hr/hr@xe -p=hr_test -f=my_custom_reporter -o=run.log -s -``` \ No newline at end of file +``` diff --git a/src/main/java/org/utplsql/cli/ReportersCommand.java b/src/main/java/org/utplsql/cli/ReportersCommand.java index 7e3e9b2..9a18797 100644 --- a/src/main/java/org/utplsql/cli/ReportersCommand.java +++ b/src/main/java/org/utplsql/cli/ReportersCommand.java @@ -2,16 +2,14 @@ import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; -import org.utplsql.api.compatibility.CompatibilityProxy; import org.utplsql.api.reporter.ReporterFactory; import org.utplsql.api.reporter.inspect.ReporterInfo; import org.utplsql.api.reporter.inspect.ReporterInspector; import javax.sql.DataSource; +import java.io.PrintStream; import java.sql.Connection; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; +import java.util.*; @Parameters(separators = "=", commandDescription = "prints a list of reporters available in the specified database") public class ReportersCommand implements ICommand { @@ -37,12 +35,7 @@ public int run() { ReporterFactory reporterFactory = ReporterFactoryProvider.createReporterFactory(con); - ReporterInspector.create(reporterFactory, con).getReporterInfos().stream() - .sorted(Comparator.comparing(ReporterInfo::getName)) - .forEach(r -> { - System.out.println(r.getName() + " (" + r.getType().name() + "): " + r.getDescription()); - System.out.println(); - }); + writeReporters(ReporterInspector.create(reporterFactory, con).getReporterInfos(), System.out); } catch ( Exception e ) { e.printStackTrace(); @@ -56,4 +49,47 @@ public int run() { public String getCommand() { return "reporters"; } + + private int getMaxNameLength(List reporterInfos) { + return reporterInfos.stream() + .mapToInt(info -> info.getName().length()) + .max() + .orElse(0); + } + + private void writeReporters(List reporterInfos, PrintStream out) { + int padding = getMaxNameLength(reporterInfos)+1; + reporterInfos.stream() + .sorted(Comparator.comparing(ReporterInfo::getName)) + .forEach(info -> writeReporter(info, padding, out)); + } + + private void writeReporter(ReporterInfo info, int padding, PrintStream out) { + + writeReporterName(info, padding, out); + writeReporterDescription(info, padding, out); + + out.println(); + } + + private void writeReporterName( ReporterInfo info, int paddingRight, PrintStream out ) { + out.print(String.format("%1$-" + paddingRight + "s", info.getName())); + } + + private void writeReporterDescription( ReporterInfo info, int paddingLeft, PrintStream out ) { + String[] lines = info.getDescription().split("\n"); + + boolean firstLine = true; + for ( String line : lines ) { + + line = line.trim(); + + if ( !firstLine ) + out.print(String.format("%1$" + paddingLeft + "s", "")); + + out.println(line); + firstLine = false; + } + + } } From 93c8e5daa8f9ea8343f968a81e593b8af6fabed4 Mon Sep 17 00:00:00 2001 From: pesse Date: Tue, 12 Jun 2018 22:54:03 +0200 Subject: [PATCH 10/11] Some more minor refactoring --- .../org/utplsql/cli/ReportersCommand.java | 11 +++++----- .../org/utplsql/cli/VersionInfoCommand.java | 20 ++++++++++++------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/utplsql/cli/ReportersCommand.java b/src/main/java/org/utplsql/cli/ReportersCommand.java index 9a18797..cafd7d9 100644 --- a/src/main/java/org/utplsql/cli/ReportersCommand.java +++ b/src/main/java/org/utplsql/cli/ReportersCommand.java @@ -20,11 +20,12 @@ public class ReportersCommand implements ICommand { description = ConnectionInfo.COMMANDLINE_PARAM_DESCRIPTION) private List connectionInfoList = new ArrayList<>(); - public ConnectionInfo getConnectionInfo() { - if ( connectionInfoList != null && connectionInfoList.size() > 0 ) - return connectionInfoList.get(0); - else - return null; + private ConnectionInfo getConnectionInfo() { + assert connectionInfoList != null; + assert connectionInfoList.size() > 0; + assert connectionInfoList.get(0) != null; + + return connectionInfoList.get(0); } @Override diff --git a/src/main/java/org/utplsql/cli/VersionInfoCommand.java b/src/main/java/org/utplsql/cli/VersionInfoCommand.java index 916cd3a..0fec979 100644 --- a/src/main/java/org/utplsql/cli/VersionInfoCommand.java +++ b/src/main/java/org/utplsql/cli/VersionInfoCommand.java @@ -10,6 +10,7 @@ import javax.sql.DataSource; import java.sql.Connection; +import java.sql.SQLException; import java.util.ArrayList; import java.util.List; @@ -34,7 +35,18 @@ public int run() { System.out.println(CliVersionInfo.getInfo()); System.out.println(JavaApiVersionInfo.getInfo()); - ConnectionInfo ci = getConnectionInfo(); + try { + writeUtPlsqlVersion(getConnectionInfo()); + } + catch (SQLException e) { + e.printStackTrace(); + return 1; + } + + return 0; + } + + private void writeUtPlsqlVersion( ConnectionInfo ci ) throws SQLException { if ( ci != null ) { DataSource dataSource = DataSourceProvider.getDataSource(ci, 1); @@ -46,13 +58,7 @@ public int run() { catch ( UtPLSQLNotInstalledException e ) { System.out.println("utPLSQL framework is not installed in database."); } - catch ( Exception e ) { - e.printStackTrace(); - return 1; - } } - - return 0; } @Override From d4027187361fd9a0239f91f060d66581cdd5c84f Mon Sep 17 00:00:00 2001 From: pesse Date: Wed, 13 Jun 2018 00:03:04 +0200 Subject: [PATCH 11/11] Switch table-like to 4-space intendation --- README.md | 82 +++++++++++-------- .../org/utplsql/cli/ReportersCommand.java | 22 ++--- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 2aa2e8b..a9f691a 100644 --- a/README.md +++ b/README.md @@ -162,42 +162,52 @@ utPLSQL 3.1.2.1913 ``` > utplsql reporters app/app@localhost:1521/ORCLPDB1 -UT_COVERAGE_COBERTURA_REPORTER Generates a Cobertura coverage report providing information on code coverage with line numbers. - Designed for Jenkins and TFS to report coverage. - Cobertura Document Type Definition can be found: http://cobertura.sourceforge.net/xml/coverage-04.dtd. - Sample file: https://github.com/leobalter/testing-examples/blob/master/solutions/3/report/cobertura-coverage.xml. - -UT_COVERAGE_HTML_REPORTER Generates a HTML coverage report with summary and line by line information on code coverage. - Based on open-source simplecov-html coverage reporter for Ruby. - Includes source code in the report. - Will copy all necessary assets to a folder named after the Output-File - -UT_COVERAGE_SONAR_REPORTER Generates a JSON coverage report providing information on code coverage with line numbers. - Designed for [SonarQube](https://about.sonarqube.com/) to report coverage. - JSON format returned conforms with the Sonar specification: https://docs.sonarqube.org/display/SONAR/Generic+Test+Data - -UT_COVERALLS_REPORTER Generates a JSON coverage report providing information on code coverage with line numbers. - Designed for [Coveralls](https://coveralls.io/). - JSON format conforms with specification: https://docs.coveralls.io/api-introduction - -UT_DOCUMENTATION_REPORTER A textual pretty-print of unit test results (usually use for console output) - Provides additional properties lvl and failed - -UT_JUNIT_REPORTER Provides outcomes in a format conforming with JUnit 4 and above as defined in: https://gist.github.com/kuzuha/232902acab1344d6b578 - -UT_SONAR_TEST_REPORTER Generates a JSON report providing detailed information on test execution. - Designed for [SonarQube](https://about.sonarqube.com/) to report test execution. - JSON format returned conforms with the Sonar specification: https://docs.sonarqube.org/display/SONAR/Generic+Test+Data - -UT_TEAMCITY_REPORTER Provides the TeamCity (a CI server by jetbrains) reporting-format that allows tracking of progress of a CI step/task as it executes. - https://confluence.jetbrains.com/display/TCD9/Build+Script+Interaction+with+TeamCity - -UT_TFS_JUNIT_REPORTER Provides outcomes in a format conforming with JUnit version for TFS / VSTS. - As defined by specs :https://docs.microsoft.com/en-us/vsts/build-release/tasks/test/publish-test-results?view=vsts - Version is based on windy road junit https://github.com/windyroad/JUnit-Schema/blob/master/JUnit.xsd. - -UT_XUNIT_REPORTER Depracated reporter. Please use Junit. - Provides outcomes in a format conforming with JUnit 4 and above as defined in: https://gist.github.com/kuzuha/232902acab1344d6b578 +UT_COVERAGE_COBERTURA_REPORTER: + Generates a Cobertura coverage report providing information on code coverage with line numbers. + Designed for Jenkins and TFS to report coverage. + Cobertura Document Type Definition can be found: http://cobertura.sourceforge.net/xml/coverage-04.dtd. + Sample file: https://github.com/leobalter/testing-examples/blob/master/solutions/3/report/cobertura-coverage.xml. + +UT_COVERAGE_HTML_REPORTER: + Generates a HTML coverage report with summary and line by line information on code coverage. + Based on open-source simplecov-html coverage reporter for Ruby. + Includes source code in the report. + Will copy all necessary assets to a folder named after the Output-File + +UT_COVERAGE_SONAR_REPORTER: + Generates a JSON coverage report providing information on code coverage with line numbers. + Designed for [SonarQube](https://about.sonarqube.com/) to report coverage. + JSON format returned conforms with the Sonar specification: https://docs.sonarqube.org/display/SONAR/Generic+Test+Data + +UT_COVERALLS_REPORTER: + Generates a JSON coverage report providing information on code coverage with line numbers. + Designed for [Coveralls](https://coveralls.io/). + JSON format conforms with specification: https://docs.coveralls.io/api-introduction + +UT_DOCUMENTATION_REPORTER: + A textual pretty-print of unit test results (usually use for console output) + Provides additional properties lvl and failed + +UT_JUNIT_REPORTER: + Provides outcomes in a format conforming with JUnit 4 and above as defined in: https://gist.github.com/kuzuha/232902acab1344d6b578 + +UT_SONAR_TEST_REPORTER: + Generates a JSON report providing detailed information on test execution. + Designed for [SonarQube](https://about.sonarqube.com/) to report test execution. + JSON format returned conforms with the Sonar specification: https://docs.sonarqube.org/display/SONAR/Generic+Test+Data + +UT_TEAMCITY_REPORTER: + Provides the TeamCity (a CI server by jetbrains) reporting-format that allows tracking of progress of a CI step/task as it executes. + https://confluence.jetbrains.com/display/TCD9/Build+Script+Interaction+with+TeamCity + +UT_TFS_JUNIT_REPORTER: + Provides outcomes in a format conforming with JUnit version for TFS / VSTS. + As defined by specs :https://docs.microsoft.com/en-us/vsts/build-release/tasks/test/publish-test-results?view=vsts + Version is based on windy road junit https://github.com/windyroad/JUnit-Schema/blob/master/JUnit.xsd. + +UT_XUNIT_REPORTER: + Depracated reporter. Please use Junit. + Provides outcomes in a format conforming with JUnit 4 and above as defined in: https://gist.github.com/kuzuha/232902acab1344d6b578 ``` ## Enabling Color Outputs on Windows diff --git a/src/main/java/org/utplsql/cli/ReportersCommand.java b/src/main/java/org/utplsql/cli/ReportersCommand.java index cafd7d9..80f01ff 100644 --- a/src/main/java/org/utplsql/cli/ReportersCommand.java +++ b/src/main/java/org/utplsql/cli/ReportersCommand.java @@ -59,10 +59,10 @@ private int getMaxNameLength(List reporterInfos) { } private void writeReporters(List reporterInfos, PrintStream out) { - int padding = getMaxNameLength(reporterInfos)+1; + //int padding = getMaxNameLength(reporterInfos)+1; reporterInfos.stream() .sorted(Comparator.comparing(ReporterInfo::getName)) - .forEach(info -> writeReporter(info, padding, out)); + .forEach(info -> writeReporter(info, 4, out)); } private void writeReporter(ReporterInfo info, int padding, PrintStream out) { @@ -74,23 +74,13 @@ private void writeReporter(ReporterInfo info, int padding, PrintStream out) { } private void writeReporterName( ReporterInfo info, int paddingRight, PrintStream out ) { - out.print(String.format("%1$-" + paddingRight + "s", info.getName())); + out.println(info.getName()+":"); + } private void writeReporterDescription( ReporterInfo info, int paddingLeft, PrintStream out ) { String[] lines = info.getDescription().split("\n"); - - boolean firstLine = true; - for ( String line : lines ) { - - line = line.trim(); - - if ( !firstLine ) - out.print(String.format("%1$" + paddingLeft + "s", "")); - - out.println(line); - firstLine = false; - } - + String paddingLeftStr = String.format("%1$"+paddingLeft+"s", ""); + Arrays.stream(lines).forEach(line -> out.println(paddingLeftStr+line.trim())); } }