diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..9540ee2 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,85 @@ +name: Build and test + +on: + push: + + pull_request: + branches: [ develop ] + + workflow_dispatch: + + repository_dispatch: + types: [utPLSQL-build,utPLSQL-java-api-build] + +defaults: + run: + shell: bash + +jobs: + build: + name: Test on JDK ${{ matrix.jdk }} with utPLSQL ${{ matrix.utplsql_version }} + runs-on: ubuntu-latest + env: + ORACLE_VERSION: "gvenzl/oracle-xe:18.4.0-slim" + UTPLSQL_VERSION: ${{matrix.utplsql_version}} + UTPLSQL_FILE: ${{matrix.utplsql_file}} + ORACLE_PASSWORD: oracle + DB_URL: "127.0.0.1:1521:XE" + DB_USER: app + DB_PASS: app + + strategy: + fail-fast: false + matrix: + utplsql_version: ["v3.0.1","v3.0.2","v3.0.3","v3.0.4","v3.1.1","v3.1.2","v3.1.3","v3.1.6","v3.1.7","v3.1.8","v3.1.9","v3.1.10","v3.1.11","develop"] + utplsql_file: ["utPLSQL"] + jdk: ['8'] + include: + - utplsql_version: "v3.0.0" + jdk: '8' + utplsql_file: "utPLSQLv3.0.0" + services: + oracle: + image: gvenzl/oracle-xe:18.4.0-slim + env: + ORACLE_PASSWORD: oracle + ports: + - 1521:1521 + options: >- + --health-cmd healthcheck.sh + --health-interval 10s + --health-timeout 5s + --health-retries 10 + --name oracle + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - uses: actions/setup-java@v2 + with: + distribution: 'adopt' + java-version: ${{matrix.jdk}} + + - name: Install utplsql + run: .travis/install_utplsql.sh + + - name: Install demo project + run: .travis/install_demo_project.sh + + - name: Build and Test + run: mvn verify jar:jar appassembler:assemble + + slack-workflow-status: + if: always() + name: Post Workflow Status To Slack + needs: [ build ] + runs-on: ubuntu-latest + steps: + - name: Slack Workflow Notification + uses: Gamesight/slack-workflow-status@master + with: + repo_token: ${{secrets.GITHUB_TOKEN}} + slack_webhook_url: ${{secrets.SLACK_WEBHOOK_URL}} + name: 'Github Actions[bot]' + icon_url: 'https://octodex.github.com/images/mona-the-rivetertocat.png' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..bf6c098 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,47 @@ +name: Release + +on: + push: + tags: + - "*.*.*" + + workflow_dispatch: + +jobs: + + release: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - uses: actions/setup-java@v2 + with: + distribution: 'adopt' + java-version: 8 + + - name: Build Release + run: mvn package appassembler:assemble assembly:single checksum:files -DskipTests + + - name: Release + uses: softprops/action-gh-release@v1 + with: + files: | + target/utPLSQL-cli.zip + target/utPLSQL-cli.zip.md5 + + slack-workflow-status: + if: always() + name: Post Workflow Status To Slack + needs: [ release ] + runs-on: ubuntu-latest + steps: + - name: Slack Workflow Notification + uses: Gamesight/slack-workflow-status@master + with: + repo_token: ${{secrets.GITHUB_TOKEN}} + slack_webhook_url: ${{secrets.SLACK_WEBHOOK_URL}} + name: 'Github Actions[bot]' + icon_url: 'https://octodex.github.com/images/mona-the-rivetertocat.png' diff --git a/.travis.yml b/.travis.yml index 65d84a2..76b64a0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,7 +43,6 @@ cache: - $MAVEN_CFG install: - - bash .travis/maven_cfg.sh - bash .travis/start_db.sh - bash .travis/install_utplsql.sh - bash .travis/install_demo_project.sh diff --git a/.travis/create_api_user.sh b/.travis/create_api_user.sh old mode 100644 new mode 100755 diff --git a/.travis/create_release.sh b/.travis/create_release.sh old mode 100644 new mode 100755 diff --git a/.travis/install_demo_project.sh b/.travis/install_demo_project.sh old mode 100644 new mode 100755 index adb9566..bafc8f1 --- a/.travis/install_demo_project.sh +++ b/.travis/install_demo_project.sh @@ -1,5 +1,5 @@ #!/bin/bash -set -ev +set -evx cd $(dirname $(readlink -f $0)) PROJECT_FILE="utPLSQL-demo-project" @@ -13,32 +13,22 @@ grant select any dictionary to ${DB_USER}; exit SQL -cd ${PROJECT_FILE} +cd /${PROJECT_FILE} sqlplus -S -L ${DB_USER}/${DB_PASS}@//127.0.0.1:1521/xe < install.sh.tmp < - - - - - - - - maven.oracle.com - ${env.ORACLE_OTN_USER} - ${env.ORACLE_OTN_PASSWORD} - - - ANY - ANY - OAM 11g - - - - - - http.protocol.allow-circular-redirects - %b,true - - - - - - - - - diff --git a/.travis/start_db.sh b/.travis/start_db.sh old mode 100644 new mode 100755 diff --git a/README.md b/README.md index 1368172..ba9fe0f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![latest-release](https://img.shields.io/github/release/utPLSQL/utPLSQL-cli.svg)](https://github.com/utPLSQL/utPLSQL-cli/releases) [![license](https://img.shields.io/github/license/utPLSQL/utPLSQL-cli.svg)](https://www.apache.org/licenses/LICENSE-2.0) -[![build](https://img.shields.io/travis/utPLSQL/utPLSQL-cli/develop.svg?label=develop%20branch)](https://travis-ci.org/utPLSQL/utPLSQL-cli) +[![Build status](https://github.com/utPLSQL/utPLSQL-cli/actions/workflows/build.yml/badge.svg)](https://github.com/utPLSQL/utPLSQL-cli/actions/workflows/build.yml) ---------- # utPLSQL-cli @@ -51,6 +51,22 @@ ALTER SESSION SET NLS_LANGUAGE='AMERICAN'; ALTER SESSION SET NLS_TERRITORY='AMERICA'; ``` +## Charset + +Java will use the default charset of your system for any string output. +You can change this by passing the `-Dfile.encoding` property to the JVM when running a java-application. +To avoid changing the utPLSQL-cli shell- or batchscript, you can define `-Dfile.encoding` in the environment variable `JAVA_TOOL_OPTIONS`. +This environment variable will be picked up and interpreted by the JVM: + +``` +export JAVA_TOOL_OPTIONS='-Dfile.encoding=utf8' +utplsql run user/pw@connecstring + +> Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=utf8 +``` + +Make sure that the defined charset matches with the codepage your console is using. + ## Usage Currently, utPLSQL-cli supports the following sub-commands: - run @@ -163,6 +179,11 @@ utplsql run "my/Username"/"myP@ssword"@connectstring -seed - Sets the seed to use for random test execution order. If set, it sets -random to true (--random-test-order-seed) + +--coverage-schemes - A comma separated list of schemas on which coverage should be gathered + Format: --coverage-schemes=schema1[,schema2[,schema3]] + +--ora-stuck-timeout - Sets a timeout around Reporter creation and retries when not ready after a while. 0 = no timeout. ``` Parameters -f, -o, -s are correlated. That is parameters -o and -s are controlling outputs for reporter specified by the preceding -f parameter. diff --git a/pom.xml b/pom.xml index f05df21..f322df9 100644 --- a/pom.xml +++ b/pom.xml @@ -1,14 +1,14 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - org.utplsql - cli - 3.1.8-SNAPSHOT - jar + org.utplsql + cli + 3.1.9 - cli - http://maven.apache.org + utPLSQL CLI + CLI for running Unit Tests with utPLSQL v3+. + https://github.com/utPLSQL/utPLSQL-cli UTF-8 @@ -19,153 +19,201 @@ local - - - org.utplsql - java-api - 3.1.8 - compile - - - com.oracle.jdbc - ucp - - - com.oracle.jdbc - ojdbc8 - - - com.oracle.jdbc - orai18n - - - - - javax.xml.bind - jaxb-api - 2.3.0 - - - ch.qos.logback - logback-classic - 1.2.3 - - - info.picocli - picocli - 4.0.0-beta-1b - - - com.oracle.ojdbc - ojdbc8 - ${oracle.jdbc.version} - compile - - - com.oracle.ojdbc - ucp - - - - - com.oracle.ojdbc - orai18n - ${oracle.jdbc.version} - compile - + + + Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + - - - org.junit.jupiter - junit-jupiter - ${junit.jupiter.version} - test - - - org.hamcrest - hamcrest - 2.1 - test - + + + org.utplsql + java-api + 3.1.9 + compile + + + com.oracle.ojdbc + ucp + + + com.oracle.ojdbc + ojdbc8 + + + com.oracle.ojdbc + orai18n + + + + + javax.xml.bind + jaxb-api + 2.3.1 + + + ch.qos.logback + logback-classic + 1.2.11 + + + info.picocli + picocli + 4.6.3 + + + com.oracle.database.jdbc + ojdbc8 + ${oracle.jdbc.version} + compile + + + com.oracle.database.jdbc + ucp + + + + + com.oracle.database.nls + orai18n + ${oracle.jdbc.version} + compile + - + + + org.junit.jupiter + junit-jupiter + ${junit.jupiter.version} + test + + + org.hamcrest + hamcrest + 2.1 + test + + - - - - org.codehaus.mojo - appassembler-maven-plugin - 1.10 - - true - true - etc - lib - flat - - - org.utplsql.cli.Cli - utplsql - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.0 - + + + + org.codehaus.mojo + appassembler-maven-plugin + 1.10 + + true + true + etc + lib + flat + + + org.utplsql.cli.Cli + utplsql + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.0 + + + **/*IT.java + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.22.0 + + + + integration-test + verify + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.3.0 + + utPLSQL-cli + false + + src/main/assembly/zip.xml + + + + + net.nicoulaj.maven.plugins + checksum-maven-plugin + 1.10 + + + + ${project.build.directory} + + utPLSQL-cli.zip + + + + + MD5 + + + + + com.amashchenko.maven.plugin + gitflow-maven-plugin + 1.18.0 + + true + + main + + + + + + + src/main/resources + true + + **/utplsql-cli.version + + + + src/main/resources + false - **/*IT.java + **/utplsql-cli.version - - - - org.apache.maven.plugins - maven-failsafe-plugin - 2.22.0 - - - - integration-test - verify - - - - - - - - src/main/resources - true - - **/utplsql-cli.version - - - - src/main/resources - false - - **/utplsql-cli.version - - - - + + + - - - utplsql-java-api - - https://packagecloud.io/utplsql/utplsql-java-api/maven2 - - - true - - - true - - - + + + utplsql-java-api + + https://packagecloud.io/utplsql/utplsql-java-api/maven2 + + + true + + + true + + + diff --git a/src/main/assembly/zip.xml b/src/main/assembly/zip.xml new file mode 100644 index 0000000..6d16b57 --- /dev/null +++ b/src/main/assembly/zip.xml @@ -0,0 +1,19 @@ + + + zip + + false + + + zip + + + + + ${project.build.directory}/appassembler + /utPLSQL-cli + + + diff --git a/src/main/java/org/utplsql/cli/Cli.java b/src/main/java/org/utplsql/cli/Cli.java index 2671988..4f711b6 100644 --- a/src/main/java/org/utplsql/cli/Cli.java +++ b/src/main/java/org/utplsql/cli/Cli.java @@ -1,11 +1,15 @@ package org.utplsql.cli; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import picocli.CommandLine; import java.util.List; public class Cli { + private static final Logger logger = LoggerFactory.getLogger(Cli.class); + static final int DEFAULT_ERROR_CODE = 1; public static void main(String[] args) { @@ -17,8 +21,7 @@ public static void main(String[] args) { static int runPicocliWithExitCode(String[] args) { - LoggerConfiguration.configure(LoggerConfiguration.ConfigLevel.NONE); - LocaleInitializer.initLocale(); + logger.debug("Args: "+String.join(", ", args)); CommandLine commandLine = new CommandLine(UtplsqlPicocliCommand.class); commandLine.setTrimQuotes(true); diff --git a/src/main/java/org/utplsql/cli/LocaleInitializer.java b/src/main/java/org/utplsql/cli/LocaleInitializer.java index 44a755a..bcb0fe7 100644 --- a/src/main/java/org/utplsql/cli/LocaleInitializer.java +++ b/src/main/java/org/utplsql/cli/LocaleInitializer.java @@ -1,5 +1,7 @@ package org.utplsql.cli; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.utplsql.api.EnvironmentVariableUtil; import java.util.Locale; @@ -18,6 +20,8 @@ */ class LocaleInitializer { + private static final Logger logger = LoggerFactory.getLogger(RunAction.class); + private static final Pattern REGEX_LOCALE = Pattern.compile("^([a-zA-Z]+)[_-]([a-zA-Z]+)"); // We only need the very first part and are pretty forgiving in parsing /** @@ -27,7 +31,10 @@ static void initLocale() { boolean localeChanged = setDefaultLocale(EnvironmentVariableUtil.getEnvValue("LC_ALL")); if (!localeChanged) { - setDefaultLocale(EnvironmentVariableUtil.getEnvValue("LANG")); + localeChanged = setDefaultLocale(EnvironmentVariableUtil.getEnvValue("LANG")); + } + if ( !localeChanged ) { + logger.debug("Java Locale not changed from LC_ALL or LANG environment variable"); } } @@ -54,6 +61,7 @@ private static boolean setDefaultLocale(String localeString) { Locale l = new Locale.Builder().setLanguageTag(sb.toString()).build(); if (l != null) { Locale.setDefault(l); + logger.debug("Java Locale changed to {}", l); return true; } } diff --git a/src/main/java/org/utplsql/cli/ReportersCommand.java b/src/main/java/org/utplsql/cli/ReportersCommand.java index 257f2ca..f7dcddd 100644 --- a/src/main/java/org/utplsql/cli/ReportersCommand.java +++ b/src/main/java/org/utplsql/cli/ReportersCommand.java @@ -28,6 +28,7 @@ public class ReportersCommand implements ICommand { @Override public int run() { + LoggerConfiguration.configure(LoggerConfiguration.ConfigLevel.NONE); try { DataSource ds = DataSourceProvider.getDataSource(connectionString, 1); diff --git a/src/main/java/org/utplsql/cli/RunAction.java b/src/main/java/org/utplsql/cli/RunAction.java index ba8c934..de1be33 100644 --- a/src/main/java/org/utplsql/cli/RunAction.java +++ b/src/main/java/org/utplsql/cli/RunAction.java @@ -48,6 +48,7 @@ public RunAction(RunCommandConfig config) { void init() { LoggerConfiguration.configure(config.getLogConfigLevel()); + LocaleInitializer.initLocale(); } public RunCommandConfig getConfig() { @@ -164,7 +165,9 @@ TestRunner newTestRunner(List reporterList) { .excludeObjects(Arrays.asList(config.getExcludePackages())) .randomTestOrder(config.isRandomTestOrder()) .randomTestOrderSeed(config.getRandomTestOrderSeed()) - .addTags(Arrays.asList(config.getTags())); + .addTags(Arrays.asList(config.getTags())) + .addCoverageSchemes(Arrays.asList(config.getCoverageSchemes())) + .oraStuckTimeout(config.getOraStuckTimeout()); } private void outputMainInformation() { diff --git a/src/main/java/org/utplsql/cli/RunPicocliCommand.java b/src/main/java/org/utplsql/cli/RunPicocliCommand.java index da0d871..2908cf2 100644 --- a/src/main/java/org/utplsql/cli/RunPicocliCommand.java +++ b/src/main/java/org/utplsql/cli/RunPicocliCommand.java @@ -28,6 +28,11 @@ public class RunPicocliCommand implements IRunCommand { split = ",") private List tags = new ArrayList<>(); + @Option(names = {"--coverage-schemes"}, + description = "comma-separated list of schemas on which coverage should be gathered", + split = ",") + private List coverageSchemes = new ArrayList<>(); + @Option( names = {"-c", "--color"}, @@ -99,7 +104,7 @@ public class RunPicocliCommand implements IRunCommand { private List reporters = new ArrayList<>(); static class Format { - @Option(names = {"-f", "--format"}, required = true, description = "Enables specified format reporting") + @Option(names = {"-f", "--format"}, description = "Enables specified format reporting") String format; @Option(names = {"-o"}, description = "Outputs format to file") String outputFile; @@ -178,6 +183,9 @@ FileMapperConfig toFileMapperConfig() { @Option(names = "-h", usageHelp = true, description = "display this help and exit") boolean help; + @Option(names = "--ora-stuck-timeout", description = "Sets a timeout around Reporter creation and retries when not ready after a while. 0 = no timeout.") + Integer oraStuckTimeout = 0; + private RunAction runAction; private String[] splitOrEmpty(String value) { @@ -222,23 +230,26 @@ public RunCommandConfig getRunCommandConfig() { } } - return new RunCommandConfig( - connectionString, - suitePaths.toArray(new String[0]), - reporterConfigs.toArray(new ReporterConfig[0]), - colorConsole, - failureExitCode, - skipCompatibilityCheck, - splitOrEmpty(includeObjects), - splitOrEmpty(excludeObjects), - sourceFileMapping, - testFileMapping, - loggerConfigLevel, - timeoutInMinutes, - enableDbmsOutput, - randomTestOrder, - randomTestOrderSeed, - tags.toArray(new String[0])); + return new RunCommandConfig.Builder() + .connectString(connectionString) + .suitePaths(suitePaths.toArray(new String[0])) + .reporters(reporterConfigs.toArray(new ReporterConfig[0])) + .outputAnsiColor(colorConsole) + .failureExitCode(failureExitCode) + .skipCompatibilityCheck(skipCompatibilityCheck) + .includePackages(splitOrEmpty(includeObjects)) + .excludePackages(splitOrEmpty(excludeObjects)) + .sourceMapping(sourceFileMapping) + .testMapping(testFileMapping) + .logConfigLevel(loggerConfigLevel) + .timeoutInMinutes(timeoutInMinutes) + .dbmsOutput(enableDbmsOutput) + .randomTestOrder(randomTestOrder) + .randomTestOrderSeed(randomTestOrderSeed) + .tags(tags.toArray(new String[0])) + .coverageSchemes(coverageSchemes.toArray(new String[0])) + .oraStuckTimeout(oraStuckTimeout) + .create(); } private RunAction getRunAction() { diff --git a/src/main/java/org/utplsql/cli/VersionInfoCommand.java b/src/main/java/org/utplsql/cli/VersionInfoCommand.java index d6a40ea..821d0ba 100644 --- a/src/main/java/org/utplsql/cli/VersionInfoCommand.java +++ b/src/main/java/org/utplsql/cli/VersionInfoCommand.java @@ -23,6 +23,7 @@ public class VersionInfoCommand implements ICommand { boolean help; public int run() { + LoggerConfiguration.configure(LoggerConfiguration.ConfigLevel.NONE); System.out.println(CliVersionInfo.getInfo()); System.out.println(JavaApiVersionInfo.getInfo()); diff --git a/src/main/java/org/utplsql/cli/config/ReporterConfig.java b/src/main/java/org/utplsql/cli/config/ReporterConfig.java index e68d6ab..e3e74ba 100644 --- a/src/main/java/org/utplsql/cli/config/ReporterConfig.java +++ b/src/main/java/org/utplsql/cli/config/ReporterConfig.java @@ -1,5 +1,7 @@ package org.utplsql.cli.config; +import org.utplsql.api.reporter.CoreReporters; + import java.beans.ConstructorProperties; public class ReporterConfig { @@ -10,7 +12,11 @@ public class ReporterConfig { @ConstructorProperties({"name", "output", "forceToScreen"}) public ReporterConfig(String name, String output, Boolean forceToScreen) { - this.name = name; + if ( name != null ) { + this.name = name; + } else { + this.name = CoreReporters.UT_DOCUMENTATION_REPORTER.name(); + } this.output = output; if (forceToScreen != null) this.forceToScreen = forceToScreen; } diff --git a/src/main/java/org/utplsql/cli/config/RunCommandConfig.java b/src/main/java/org/utplsql/cli/config/RunCommandConfig.java index 4418a45..218466b 100644 --- a/src/main/java/org/utplsql/cli/config/RunCommandConfig.java +++ b/src/main/java/org/utplsql/cli/config/RunCommandConfig.java @@ -22,9 +22,11 @@ public class RunCommandConfig extends ConnectionConfig { private boolean randomTestOrder = false; private final Integer randomTestOrderSeed; private final String[] tags; + private final String[] coverageSchemes; + private final Integer oraStuckTimeout; - @ConstructorProperties({"connectString", "suitePaths", "reporters", "outputAnsiColor", "failureExitCode", "skipCompatibilityCheck", "includePackages", "excludePackages", "sourceMapping", "testMapping", "logConfigLevel", "timeoutInMinutes", "dbmsOutput", "randomTestOrder", "randomTestOrderSeed", "tags"}) - public RunCommandConfig(String connectString, String[] suitePaths, ReporterConfig[] reporters, boolean outputAnsiColor, Integer failureExitCode, boolean skipCompatibilityCheck, String[] includePackages, String[] excludePackages, FileMapperConfig sourceMapping, FileMapperConfig testMapping, ConfigLevel logConfigLevel, Integer timeoutInMinutes, boolean dbmsOutput, boolean randomTestOrder, Integer randomTestOrderSeed, String[] tags) { + @ConstructorProperties({"connectString", "suitePaths", "reporters", "outputAnsiColor", "failureExitCode", "skipCompatibilityCheck", "includePackages", "excludePackages", "sourceMapping", "testMapping", "logConfigLevel", "timeoutInMinutes", "dbmsOutput", "randomTestOrder", "randomTestOrderSeed", "tags", "coverageSchemes", "oraStuckTimeout"}) + public RunCommandConfig(String connectString, String[] suitePaths, ReporterConfig[] reporters, boolean outputAnsiColor, Integer failureExitCode, boolean skipCompatibilityCheck, String[] includePackages, String[] excludePackages, FileMapperConfig sourceMapping, FileMapperConfig testMapping, ConfigLevel logConfigLevel, Integer timeoutInMinutes, boolean dbmsOutput, boolean randomTestOrder, Integer randomTestOrderSeed, String[] tags, String[] coverageSchemes, Integer oraStuckTimeout) { super(connectString); this.suitePaths = suitePaths; this.reporters = reporters; @@ -41,6 +43,8 @@ public RunCommandConfig(String connectString, String[] suitePaths, ReporterConfi this.randomTestOrder = randomTestOrder; this.randomTestOrderSeed = randomTestOrderSeed; this.tags = tags; + this.coverageSchemes = coverageSchemes; + this.oraStuckTimeout = oraStuckTimeout; } public String[] getSuitePaths() { @@ -102,4 +106,126 @@ public boolean isRandomTestOrder() { public Integer getRandomTestOrderSeed() { return randomTestOrderSeed; } + + public String[] getCoverageSchemes() { + return coverageSchemes; + } + + public Integer getOraStuckTimeout() { return oraStuckTimeout; } + + public static class Builder { + + private String connectString; + private String[] suitePaths = new String[0]; + private ReporterConfig[] reporters; + private boolean outputAnsiColor; + private Integer failureExitCode; + private boolean skipCompatibilityCheck; + private String[] includePackages = new String[0]; + private String[] excludePackages = new String[0]; + private FileMapperConfig sourceMapping; + private FileMapperConfig testMapping; + private ConfigLevel logConfigLevel; + private Integer timeoutInMinutes; + private boolean dbmsOutput; + private boolean randomTestOrder; + private Integer randomTestOrderSeed; + private String[] tags = new String[0]; + private String[] coverageSchemes = new String[0]; + private Integer oraStuckTimeout; + + public Builder connectString(String connectString) { + this.connectString = connectString; + return this; + } + + public Builder suitePaths(String[] suitePaths) { + this.suitePaths = suitePaths; + return this; + } + + public Builder reporters(ReporterConfig[] reporters) { + this.reporters = reporters; + return this; + } + + public Builder outputAnsiColor(boolean outputAnsiColor) { + this.outputAnsiColor = outputAnsiColor; + return this; + } + + public Builder failureExitCode(Integer failureExitCode) { + this.failureExitCode = failureExitCode; + return this; + } + + public Builder skipCompatibilityCheck(boolean skipCompatibilityCheck) { + this.skipCompatibilityCheck = skipCompatibilityCheck; + return this; + } + + public Builder includePackages(String[] includePackages) { + this.includePackages = includePackages; + return this; + } + + public Builder excludePackages(String[] excludePackages) { + this.excludePackages = excludePackages; + return this; + } + + public Builder sourceMapping(FileMapperConfig sourceMapping) { + this.sourceMapping = sourceMapping; + return this; + } + + public Builder testMapping(FileMapperConfig testMapping) { + this.testMapping = testMapping; + return this; + } + + public Builder logConfigLevel(ConfigLevel logConfigLevel) { + this.logConfigLevel = logConfigLevel; + return this; + } + + public Builder timeoutInMinutes(Integer timeoutInMinutes) { + this.timeoutInMinutes = timeoutInMinutes; + return this; + } + + public Builder dbmsOutput(boolean dbmsOutput) { + this.dbmsOutput = dbmsOutput; + return this; + } + + public Builder randomTestOrder(boolean randomTestOrder) { + this.randomTestOrder = randomTestOrder; + return this; + } + + public Builder randomTestOrderSeed(Integer randomTestOrderSeed) { + this.randomTestOrderSeed = randomTestOrderSeed; + return this; + } + + public Builder tags(String[] tags) { + this.tags = tags; + return this; + } + + public Builder coverageSchemes(String[] coverageSchemes) { + this.coverageSchemes = coverageSchemes; + return this; + } + + public Builder oraStuckTimeout(Integer oraStuckTimeout) { + this.oraStuckTimeout = oraStuckTimeout; + return this; + } + + public RunCommandConfig create() { + return new RunCommandConfig(connectString, suitePaths, reporters, outputAnsiColor, failureExitCode, skipCompatibilityCheck, includePackages, excludePackages, sourceMapping, testMapping, logConfigLevel, timeoutInMinutes, dbmsOutput, randomTestOrder, randomTestOrderSeed, tags, coverageSchemes, oraStuckTimeout); + } + } } diff --git a/src/main/java/org/utplsql/cli/datasource/TestedDataSourceProvider.java b/src/main/java/org/utplsql/cli/datasource/TestedDataSourceProvider.java index 8ecfeca..8f99cf3 100644 --- a/src/main/java/org/utplsql/cli/datasource/TestedDataSourceProvider.java +++ b/src/main/java/org/utplsql/cli/datasource/TestedDataSourceProvider.java @@ -54,11 +54,12 @@ private void setThickOrThinJdbcUrl(OracleDataSource ds) throws SQLException { ds.setPassword(config.getPassword()); for (ConnectStringPossibility possibility : possibilities) { + logger.debug("Try connecting {}", possibility.getMaskedConnectString(config)); ds.setURL(possibility.getConnectString(config)); try (Connection ignored = ds.getConnection()) { logger.info("Use connection string {}", possibility.getMaskedConnectString(config)); return; - } catch (UnsatisfiedLinkError | Exception e) { + } catch (Error | Exception e) { errors.add(possibility.getMaskedConnectString(config) + ": " + e.getMessage()); lastException = e; } diff --git a/src/test/java/org/utplsql/cli/PicocliRunCommandTest.java b/src/test/java/org/utplsql/cli/PicocliRunCommandTest.java index c29d3fd..475ca82 100644 --- a/src/test/java/org/utplsql/cli/PicocliRunCommandTest.java +++ b/src/test/java/org/utplsql/cli/PicocliRunCommandTest.java @@ -48,7 +48,8 @@ void runCommandAllArguments() throws Exception { "-type_mapping=\"tsql=PACKAGE BODY\"", "-owner_subexpression=1", "-type_subexpression=2", - "-name_subexpression=3"); + "-name_subexpression=3", + "--coverage-schemes=schema1,other_schema"); assertNotNull(config.getConnectString()); assertThat( config.getSuitePaths(), is(new String[]{"app.betwnstr", "app.basic"})); @@ -65,6 +66,7 @@ void runCommandAllArguments() throws Exception { assertEquals( 123, config.getRandomTestOrderSeed() ); assertNotNull( config.getReporters() ); assertEquals( 1, config.getReporters().length ); + assertThat( config.getCoverageSchemes(), is(new String[]{"schema1", "other_schema"}) ); // Source FileMapping assertNotNull(config.getSourceMapping()); @@ -163,6 +165,20 @@ void multipleReporters() throws Exception { assertTrue(reporterConfig.isForceToScreen()); } + @Test + void outputWithDefaultReporter() throws Exception { + RunCommandConfig config = parseForConfig("run", + TestHelper.getConnectionString(), + "-o=output1.txt"); + + assertNotNull( config.getReporters() ); + + ReporterConfig reporterConfig = config.getReporters()[0]; + assertEquals("ut_documentation_reporter", reporterConfig.getName().toLowerCase()); + assertEquals("output1.txt", reporterConfig.getOutput()); + assertFalse(reporterConfig.isForceToScreen()); + } + @Test void sourceFileMapping() throws Exception { RunCommandConfig config = parseForConfig("run", @@ -224,4 +240,13 @@ void testFileMappingWithoutDetails() throws Exception { assertNull( testMapperConfig.getTypeSubexpression()); assertNull( testMapperConfig.getNameSubexpression()); } + + @Test + void negatedTag() throws Exception { + RunCommandConfig config = parseForConfig("run", + TestHelper.getConnectionString(), + "--tags=\"-dontwantit\""); + + assertThat(config.getTags(), hasItemInArray("-dontwantit") ); + } } diff --git a/src/test/java/org/utplsql/cli/RunCommandArgumentsTest.java b/src/test/java/org/utplsql/cli/RunCommandArgumentsTest.java index a2f0a9a..63be6e2 100644 --- a/src/test/java/org/utplsql/cli/RunCommandArgumentsTest.java +++ b/src/test/java/org/utplsql/cli/RunCommandArgumentsTest.java @@ -1,5 +1,6 @@ package org.utplsql.cli; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.utplsql.api.TestRunner; @@ -11,6 +12,7 @@ public class RunCommandArgumentsTest { @Test + @DisplayName("All arguments are recognized") public void allArgumentsAreRecognized() { IRunCommand runCmd = TestHelper.createRunCommand(TestHelper.getConnectionString(), "-p=app", @@ -18,6 +20,7 @@ public void allArgumentsAreRecognized() { "-o=sonar_result.xml", "-s", "--tags=tag1,tag2", + "--coverage-schemes=schema1,some_other_schema", "-d", "-c", "--failure-exit-code=10", @@ -38,7 +41,8 @@ public void allArgumentsAreRecognized() { "-type_mapping=\"sql=PACKAGE BODY\"", "-owner_subexpression=0", "-type_subexpression=0", - "-name_subexpression=0" + "-name_subexpression=0", + "--ora-stuck-timeout=2" ); TestRunner testRunner = runCmd.newTestRunner(new ArrayList<>()); @@ -64,4 +68,14 @@ void provideTags() { TestRunner testRunner = runCmd.newTestRunner(new ArrayList<>()); assertThat( testRunner.getOptions().tags, contains("tag1", "tag.2") ); } + + @Test + void provideCoverageSchemes() { + IRunCommand runCmd = TestHelper.createRunCommand(TestHelper.getConnectionString(), + "--coverage-schemes=schema-1,some_other_schema" + ); + + TestRunner testRunner = runCmd.newTestRunner(new ArrayList<>()); + assertThat( testRunner.getOptions().coverageSchemes, contains("schema-1", "some_other_schema") ); + } } diff --git a/src/test/java/org/utplsql/cli/RunCommandConfigParamsArePassedToTestRunnerTest.java b/src/test/java/org/utplsql/cli/RunCommandConfigParamsArePassedToTestRunnerTest.java new file mode 100644 index 0000000..95d146a --- /dev/null +++ b/src/test/java/org/utplsql/cli/RunCommandConfigParamsArePassedToTestRunnerTest.java @@ -0,0 +1,42 @@ +package org.utplsql.cli; + +import org.junit.jupiter.api.Test; +import org.utplsql.api.TestRunner; +import org.utplsql.cli.config.RunCommandConfig; + +import java.util.ArrayList; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class RunCommandConfigParamsArePassedToTestRunnerTest { + + @Test + void tags() { + RunCommandConfig config = new RunCommandConfig.Builder() + .tags(new String[]{"tag1", "tag2"}) + .create(); + TestRunner testRunner = new RunAction(config).newTestRunner(new ArrayList<>()); + assertThat( testRunner.getOptions().tags, contains("tag1", "tag2") ); + } + + @Test + void coverageSchemes() { + RunCommandConfig config = new RunCommandConfig.Builder() + .coverageSchemes(new String[]{"schema1", "another_schema", "and-another-one"}) + .create(); + TestRunner testRunner = new RunAction(config).newTestRunner(new ArrayList<>()); + assertThat( testRunner.getOptions().coverageSchemes, contains("schema1", "another_schema", "and-another-one") ); + } + + @Test + void oraStuckTimeout() { + RunCommandConfig config = new RunCommandConfig.Builder() + .oraStuckTimeout(2) + .create(); + TestRunner testRunner = new RunAction(config).newTestRunner(new ArrayList<>()); + assertThat( testRunner.getOptions().oraStuckTimeout, equalTo(2) ); + } +} diff --git a/src/test/java/org/utplsql/cli/RunCommandCoverageReporterIT.java b/src/test/java/org/utplsql/cli/RunCommandCoverageReporterIT.java index bf67f7f..e95dce2 100644 --- a/src/test/java/org/utplsql/cli/RunCommandCoverageReporterIT.java +++ b/src/test/java/org/utplsql/cli/RunCommandCoverageReporterIT.java @@ -19,7 +19,7 @@ */ class RunCommandCoverageReporterIT extends AbstractFileOutputTest { - private static final Pattern REGEX_COVERAGE_TITLE = Pattern.compile("([a-zA-Z0-9\\._]+)<\\/a>"); + private static final Pattern REGEX_COVERAGE_TITLE = Pattern.compile("([a-zA-Z ]+ )?([a-zA-Z0-9\\._]+)<\\/a>"); private String getTempCoverageFileName(int counter) { @@ -60,7 +60,7 @@ private boolean hasCoverageListed(String content, String packageName) { Matcher m = REGEX_COVERAGE_TITLE.matcher(content); while (m.find()) { - if (packageName.equals(m.group(1))) + if (packageName.equals(m.group(2))) return true; } diff --git a/src/test/java/org/utplsql/cli/RunCommandIT.java b/src/test/java/org/utplsql/cli/RunCommandIT.java index 336f2a8..95effad 100644 --- a/src/test/java/org/utplsql/cli/RunCommandIT.java +++ b/src/test/java/org/utplsql/cli/RunCommandIT.java @@ -75,4 +75,28 @@ void run_withDbmsOutputEnabled() throws Exception { assertValidReturnCode(result); } + + @Test + void run_withOutputButNoReporterDefined() throws Exception { + + String outputFileName = "output_" + System.currentTimeMillis() + ".xml"; + addTempPath(Paths.get(outputFileName)); + + int result = TestHelper.runApp("run", + TestHelper.getConnectionString(), + "-o=" + outputFileName, + "--failure-exit-code=2"); + + assertValidReturnCode(result); + } + + @Test + void run_withOraStuckTimeout() throws Exception { + int result = TestHelper.runApp("run", + TestHelper.getConnectionString(), + "--ora-stuck-timeout=2", + "--failure-exit-code=2"); + + assertValidReturnCode(result); + } } diff --git a/src/test/java/org/utplsql/cli/RunCommandIssue20IT.java b/src/test/java/org/utplsql/cli/RunCommandIssue20IT.java index 0976706..8162fc9 100644 --- a/src/test/java/org/utplsql/cli/RunCommandIssue20IT.java +++ b/src/test/java/org/utplsql/cli/RunCommandIssue20IT.java @@ -24,7 +24,8 @@ void runLoop() { IRunCommand runCmd = TestHelper.createRunCommand( TestHelper.getConnectionString(), "-p=TEST_BETWNSTR.normal_case", - "-f=ut_documentation_reporter"); + "-f=ut_documentation_reporter", + "--ora-stuck-timeout=3"); List reporterOptionsList = runCmd.getReporterOptionsList(); ReporterOptions reporterOptions1 = reporterOptionsList.get(0); assertEquals(CoreReporters.UT_DOCUMENTATION_REPORTER.name(), reporterOptions1.getReporterName());