From 611234d9b868bb121bbdfe865d574d0a200e16c5 Mon Sep 17 00:00:00 2001 From: pesse Date: Thu, 14 Jun 2018 23:09:39 +0200 Subject: [PATCH 1/3] First, careful step into YAML-config for cli I have to say, Jackson is working like a charm. Even immutable configuration-objects are no problem at all and it just works out of the box with minimum effort. Great stuff! --- pom.xml | 16 +++++ .../utplsql/cli/config/ConnectionConfig.java | 18 +++++ .../utplsql/cli/config/ReporterConfig.java | 29 ++++++++ .../utplsql/cli/config/TestRunnerConfig.java | 67 +++++++++++++++++++ .../java/org/utplsql/cli/YmlConfigTest.java | 28 ++++++++ src/test/resources/test-config.yml | 22 ++++++ 6 files changed, 180 insertions(+) create mode 100644 src/main/java/org/utplsql/cli/config/ConnectionConfig.java create mode 100644 src/main/java/org/utplsql/cli/config/ReporterConfig.java create mode 100644 src/main/java/org/utplsql/cli/config/TestRunnerConfig.java create mode 100644 src/test/java/org/utplsql/cli/YmlConfigTest.java create mode 100644 src/test/resources/test-config.yml diff --git a/pom.xml b/pom.xml index 861937c..7e9e21c 100644 --- a/pom.xml +++ b/pom.xml @@ -67,6 +67,22 @@ jaxb-api 2.3.0 + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + 2.9.5 + + + com.fasterxml.jackson.core + jackson-databind + 2.9.5 + + + org.apache.commons + commons-lang3 + 3.7 + test + diff --git a/src/main/java/org/utplsql/cli/config/ConnectionConfig.java b/src/main/java/org/utplsql/cli/config/ConnectionConfig.java new file mode 100644 index 0000000..ef0231e --- /dev/null +++ b/src/main/java/org/utplsql/cli/config/ConnectionConfig.java @@ -0,0 +1,18 @@ +package org.utplsql.cli.config; + +import java.beans.ConstructorProperties; + +public class ConnectionConfig { + + private final String connectString; + + @ConstructorProperties({"connectString"}) + public ConnectionConfig(String connectString) { + this.connectString = connectString; + } + + public String getConnectString() { + return connectString; + } + +} diff --git a/src/main/java/org/utplsql/cli/config/ReporterConfig.java b/src/main/java/org/utplsql/cli/config/ReporterConfig.java new file mode 100644 index 0000000..0eed321 --- /dev/null +++ b/src/main/java/org/utplsql/cli/config/ReporterConfig.java @@ -0,0 +1,29 @@ +package org.utplsql.cli.config; + +import java.beans.ConstructorProperties; + +public class ReporterConfig { + + private final String name; + private final String output; + private boolean screen = false; + + @ConstructorProperties({"name", "output", "screen"}) + public ReporterConfig( String name, String output, boolean screen ) { + this.name = name; + this.output = output; + this.screen = screen; + } + + public String getName() { + return name; + } + + public String getOutput() { + return output; + } + + public boolean isScreen() { + return screen; + } +} diff --git a/src/main/java/org/utplsql/cli/config/TestRunnerConfig.java b/src/main/java/org/utplsql/cli/config/TestRunnerConfig.java new file mode 100644 index 0000000..dbdd1c4 --- /dev/null +++ b/src/main/java/org/utplsql/cli/config/TestRunnerConfig.java @@ -0,0 +1,67 @@ +package org.utplsql.cli.config; + + +import java.beans.ConstructorProperties; + +public class TestRunnerConfig extends ConnectionConfig { + + private final String[] suitePaths; + private final ReporterConfig[] reporters; + private boolean outputAnsiColor = false; + private final Integer failureExitCode; + private boolean skipCompatibilityCheck = false; + private final String[] includePackages; + private final String[] excludePackages; + private final String sourcePath; + private final String testPath; + + @ConstructorProperties({"connectString", "suitePaths", "reporters", "outputAnsiColor", "failureExitCode", "skipCompatibilityCheck", "includePackages", "excludePackages", "sourcePath", "testPath"}) + public TestRunnerConfig(String connectString, String[] suitePaths, ReporterConfig[] reporters, boolean outputAnsiColor, Integer failureExitCode, boolean skipCompatibilityCheck, String[] includePackages, String[] excludePackages, String sourcePath, String testPath) { + super(connectString); + this.suitePaths = suitePaths; + this.reporters = reporters; + this.outputAnsiColor = outputAnsiColor; + this.failureExitCode = failureExitCode; + this.skipCompatibilityCheck = skipCompatibilityCheck; + this.includePackages = includePackages; + this.excludePackages = excludePackages; + this.sourcePath = sourcePath; + this.testPath = testPath; + } + + public String[] getSuitePaths() { + return suitePaths; + } + + public ReporterConfig[] getReporters() { + return reporters; + } + + public boolean isOutputAnsiColor() { + return outputAnsiColor; + } + + public Integer getFailureExitCode() { + return failureExitCode; + } + + public boolean isSkipCompatibilityCheck() { + return skipCompatibilityCheck; + } + + public String[] getIncludePackages() { + return includePackages; + } + + public String[] getExcludePackages() { + return excludePackages; + } + + public String getSourcePath() { + return sourcePath; + } + + public String getTestPath() { + return testPath; + } +} diff --git a/src/test/java/org/utplsql/cli/YmlConfigTest.java b/src/test/java/org/utplsql/cli/YmlConfigTest.java new file mode 100644 index 0000000..958442b --- /dev/null +++ b/src/test/java/org/utplsql/cli/YmlConfigTest.java @@ -0,0 +1,28 @@ +package org.utplsql.cli; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import org.apache.commons.lang3.builder.ReflectionToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import org.junit.jupiter.api.Test; +import org.utplsql.cli.config.TestRunnerConfig; + +import java.io.File; +import java.io.IOException; + +public class YmlConfigTest { + + @Test + public void letsPlayAround() throws IOException { + + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + + String testConfigFile = "src/test/resources/test-config.yml"; + + TestRunnerConfig config = mapper.readValue(new File(testConfigFile), TestRunnerConfig.class); + + System.out.println(ReflectionToStringBuilder.toString(config,ToStringStyle.MULTI_LINE_STYLE)); + } + + +} diff --git a/src/test/resources/test-config.yml b/src/test/resources/test-config.yml new file mode 100644 index 0000000..775b70e --- /dev/null +++ b/src/test/resources/test-config.yml @@ -0,0 +1,22 @@ +# utPLSQL cli Test-Config +--- +connectString: app/app@localhost:1522/ORCLPDB1 +suitePaths: + - app.betwnstr + - app +reporters: + - name: ut_documentation_reporter + - name: ut_coverage_html_reporter + output: coverage.html + - name: ut_sonar_test_reporter + output: sonar.txt + screen: true +outputAnsiColor: true +failureExitCode: 2 +skipCompatibilityCheck: true +includePackages: [app.betwnstr, mypackage] +excludePackages: + - mypackage.blubb + - stuff +sourcePath: path/to/source +testPath: path/to/test \ No newline at end of file From 2c682e9c25cb187af91fe3c3d3b5465c89d951f7 Mon Sep 17 00:00:00 2001 From: pesse Date: Tue, 10 Jul 2018 23:32:54 +0200 Subject: [PATCH 2/3] Added config for FileMapper Understanding what's going on was actually the biggest challenge here. --- .../utplsql/cli/config/FileMapperConfig.java | 55 +++++++++++++++++++ .../utplsql/cli/config/TestRunnerConfig.java | 20 +++---- src/test/resources/test-config.yml | 26 ++++++++- 3 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 src/main/java/org/utplsql/cli/config/FileMapperConfig.java diff --git a/src/main/java/org/utplsql/cli/config/FileMapperConfig.java b/src/main/java/org/utplsql/cli/config/FileMapperConfig.java new file mode 100644 index 0000000..ec0826e --- /dev/null +++ b/src/main/java/org/utplsql/cli/config/FileMapperConfig.java @@ -0,0 +1,55 @@ +package org.utplsql.cli.config; + +import java.beans.ConstructorProperties; +import java.util.HashMap; +import java.util.Map; + +public class FileMapperConfig { + + private final String path; + private final String owner; + private final String regexExpression; + private final Map typeMapping; + private final Integer ownerSubexpression; + private final Integer nameSubexpression; + private final Integer typeSubexpression; + + @ConstructorProperties({"path", "owner", "regexExpression", "typeMapping", "ownerSubexpression", "nameSubexpression", "typeSubexpression"}) + public FileMapperConfig(String path, String owner, String regexExpression, Map typeMapping, Integer ownerSubexpression, Integer nameSubexpression, Integer typeSubexpression) { + this.path = path; + this.owner = owner; + this.regexExpression = regexExpression; + this.typeMapping = typeMapping; + this.ownerSubexpression = ownerSubexpression; + this.nameSubexpression = nameSubexpression; + this.typeSubexpression = typeSubexpression; + } + + public String getPath() { + return path; + } + + public String getOwner() { + return owner; + } + + public String getRegexExpression() { + return regexExpression; + } + + public Map getTypeMapping() { + return typeMapping; + } + + public Integer getOwnerSubexpression() { + return ownerSubexpression; + } + + public Integer getNameSubexpression() { + return nameSubexpression; + } + + public Integer getTypeSubexpression() { + return typeSubexpression; + } +} diff --git a/src/main/java/org/utplsql/cli/config/TestRunnerConfig.java b/src/main/java/org/utplsql/cli/config/TestRunnerConfig.java index dbdd1c4..18f95b8 100644 --- a/src/main/java/org/utplsql/cli/config/TestRunnerConfig.java +++ b/src/main/java/org/utplsql/cli/config/TestRunnerConfig.java @@ -12,11 +12,11 @@ public class TestRunnerConfig extends ConnectionConfig { private boolean skipCompatibilityCheck = false; private final String[] includePackages; private final String[] excludePackages; - private final String sourcePath; - private final String testPath; + private final FileMapperConfig sourceMapping; + private final FileMapperConfig testMapping; - @ConstructorProperties({"connectString", "suitePaths", "reporters", "outputAnsiColor", "failureExitCode", "skipCompatibilityCheck", "includePackages", "excludePackages", "sourcePath", "testPath"}) - public TestRunnerConfig(String connectString, String[] suitePaths, ReporterConfig[] reporters, boolean outputAnsiColor, Integer failureExitCode, boolean skipCompatibilityCheck, String[] includePackages, String[] excludePackages, String sourcePath, String testPath) { + @ConstructorProperties({"connectString", "suitePaths", "reporters", "outputAnsiColor", "failureExitCode", "skipCompatibilityCheck", "includePackages", "excludePackages", "sourceMapping", "testMapping"}) + public TestRunnerConfig(String connectString, String[] suitePaths, ReporterConfig[] reporters, boolean outputAnsiColor, Integer failureExitCode, boolean skipCompatibilityCheck, String[] includePackages, String[] excludePackages, FileMapperConfig sourceMapping, FileMapperConfig testMapping) { super(connectString); this.suitePaths = suitePaths; this.reporters = reporters; @@ -25,8 +25,8 @@ public TestRunnerConfig(String connectString, String[] suitePaths, ReporterConfi this.skipCompatibilityCheck = skipCompatibilityCheck; this.includePackages = includePackages; this.excludePackages = excludePackages; - this.sourcePath = sourcePath; - this.testPath = testPath; + this.sourceMapping = sourceMapping; + this.testMapping = testMapping; } public String[] getSuitePaths() { @@ -57,11 +57,11 @@ public String[] getExcludePackages() { return excludePackages; } - public String getSourcePath() { - return sourcePath; + public FileMapperConfig getSourceMapping() { + return sourceMapping; } - public String getTestPath() { - return testPath; + public FileMapperConfig getTestMapping() { + return testMapping; } } diff --git a/src/test/resources/test-config.yml b/src/test/resources/test-config.yml index 775b70e..f8afb4a 100644 --- a/src/test/resources/test-config.yml +++ b/src/test/resources/test-config.yml @@ -18,5 +18,27 @@ includePackages: [app.betwnstr, mypackage] excludePackages: - mypackage.blubb - stuff -sourcePath: path/to/source -testPath: path/to/test \ No newline at end of file +sourceMapping: + path: path/to/source + owner: app + regexExpression: /(\w+)/(\w+)/(\w+)\..{3}$ + typeMapping: + packages_bodies: PACKAGE BODY + types_bodies: TYPE BODY + triggers: TRIGGER + procedures: PROCEDURE + functions: FUNCTION + ownerSubexpression: 1 + nameSubexpression: 3 + typeSubexpression: 2 +testMapping: + path: path/to/test + owner: app + regexExpression: /(\w+)/(\w+)/(\w+)\..{3}$ + typeMapping: + body: PACKAGE BODY + type_body: TYPE BODY + trigger: TRIGGER + ownerSubexpression: 1 + nameSubexpression: 3 + typeSubexpression: 2 \ No newline at end of file From 0e5b5ebb812dba4d23c5900af19519816d5d0d3c Mon Sep 17 00:00:00 2001 From: pesse Date: Thu, 12 Jul 2018 22:16:42 +0200 Subject: [PATCH 3/3] Convert the RunCommand-properties into the new Config-Objects first --- src/main/java/org/utplsql/cli/RunCommand.java | 90 ++++++++++++++++++- .../utplsql/cli/config/ReporterConfig.java | 4 +- .../java/org/utplsql/cli/YmlConfigTest.java | 38 +++++++- src/test/resources/test | 26 ++++++ 4 files changed, 152 insertions(+), 6 deletions(-) create mode 100644 src/test/resources/test diff --git a/src/main/java/org/utplsql/cli/RunCommand.java b/src/main/java/org/utplsql/cli/RunCommand.java index 01ecdbd..45cc0a4 100644 --- a/src/main/java/org/utplsql/cli/RunCommand.java +++ b/src/main/java/org/utplsql/cli/RunCommand.java @@ -10,8 +10,11 @@ import org.utplsql.api.exception.DatabaseNotCompatibleException; import org.utplsql.api.exception.SomeTestsFailedException; import org.utplsql.api.exception.UtPLSQLNotInstalledException; +import org.utplsql.api.reporter.CoreReporters; import org.utplsql.api.reporter.Reporter; import org.utplsql.api.reporter.ReporterFactory; +import org.utplsql.cli.config.ReporterConfig; +import org.utplsql.cli.config.TestRunnerConfig; import org.utplsql.cli.exception.DatabaseConnectionFailed; import javax.sql.DataSource; @@ -36,10 +39,10 @@ public class RunCommand implements ICommand { @Parameter( required = true, - converter = ConnectionInfo.ConnectionStringConverter.class, + //converter = ConnectionInfo.ConnectionStringConverter.class, arity = 1, description = ConnectionInfo.COMMANDLINE_PARAM_DESCRIPTION) - private List connectionInfoList = new ArrayList<>(); + private String connectionInfo = ""; @Parameter( names = {"-p", "--path"}, @@ -100,12 +103,16 @@ public class RunCommand implements ICommand { private String excludeObjects = null; + private ConnectionInfo connectionInfoObj; private CompatibilityProxy compatibilityProxy; private ReporterFactory reporterFactory; private ReporterManager reporterManager; public ConnectionInfo getConnectionInfo() { - return connectionInfoList.get(0); + if ( connectionInfoObj == null ) + connectionInfoObj = new ConnectionInfo(connectionInfo); + + return connectionInfoObj; } public List getTestPaths() { @@ -326,4 +333,81 @@ private ReporterManager getReporterManager() { public List getReporterOptionsList() { return getReporterManager().getReporterOptionsList(); } + + private List getReporterConfigs() { + List reporterConfigs = new ArrayList<>(5); + + String reporterName = null; + String outputFile = null; + Boolean forceToScreen = null; + for (String p : reporterParams) { + if (!p.startsWith("-")) { + if ( reporterName != null ) { + reporterConfigs.add(new ReporterConfig(reporterName, outputFile, forceToScreen)); + reporterName = null; + outputFile = null; + forceToScreen = null; + } + reporterName = p; + } + else if (p.startsWith("-o=")) + outputFile = p.substring(3); + else if (p.equals("-s")) + forceToScreen = true; + } + + if ( reporterName != null ) + reporterConfigs.add(new ReporterConfig(reporterName, outputFile, forceToScreen)); + + return reporterConfigs; + } + + private String[] getSplitList( String delimitedList ) { + if ( delimitedList != null && !delimitedList.isEmpty() ) + return delimitedList.split(","); + else + return null; + } + + public TestRunnerConfig getConfig() { + final List reporterList; + List reporterOptionsList = new ArrayList<>(); + ReporterOptions reporterOptions = null; + + List reporterConfigs = getReporterConfigs(); + + // If no reporter parameters were passed, use default reporter. + if (reporterOptionsList.isEmpty()) { + reporterOptionsList.add(new ReporterOptions(CoreReporters.UT_DOCUMENTATION_REPORTER.name())); + } + final List testPaths = getTestPaths(); + + final File baseDir = new File("").getAbsoluteFile(); + final FileMapperOptions[] sourceMappingOptions = {null}; + final FileMapperOptions[] testMappingOptions = {null}; + + final int[] returnCode = {0}; + + sourceMappingOptions[0] = getFileMapperOptionsByParamListItem(this.sourcePathParams, baseDir); + testMappingOptions[0] = getFileMapperOptionsByParamListItem(this.testPathParams, baseDir); + + String[] testPathArr = new String[testPaths.size()]; + testPathArr = testPaths.toArray(testPathArr); + + ReporterConfig[] reporterConfigArr = new ReporterConfig[reporterConfigs.size()]; + reporterConfigArr = reporterConfigs.toArray(reporterConfigArr); + + return new TestRunnerConfig( + connectionInfo, + testPathArr, + reporterConfigArr, + colorConsole, + failureExitCode, + skipCompatibilityCheck, + getSplitList(includeObjects), + getSplitList(excludeObjects), + null, + null + ); + } } diff --git a/src/main/java/org/utplsql/cli/config/ReporterConfig.java b/src/main/java/org/utplsql/cli/config/ReporterConfig.java index 0eed321..8729848 100644 --- a/src/main/java/org/utplsql/cli/config/ReporterConfig.java +++ b/src/main/java/org/utplsql/cli/config/ReporterConfig.java @@ -9,10 +9,10 @@ public class ReporterConfig { private boolean screen = false; @ConstructorProperties({"name", "output", "screen"}) - public ReporterConfig( String name, String output, boolean screen ) { + public ReporterConfig( String name, String output, Boolean screen ) { this.name = name; this.output = output; - this.screen = screen; + if ( screen != null ) this.screen = screen; } public String getName() { diff --git a/src/test/java/org/utplsql/cli/YmlConfigTest.java b/src/test/java/org/utplsql/cli/YmlConfigTest.java index 958442b..1271cbb 100644 --- a/src/test/java/org/utplsql/cli/YmlConfigTest.java +++ b/src/test/java/org/utplsql/cli/YmlConfigTest.java @@ -1,5 +1,6 @@ package org.utplsql.cli; +import com.beust.jcommander.JCommander; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import org.apache.commons.lang3.builder.ReflectionToStringBuilder; @@ -10,6 +11,10 @@ import java.io.File; import java.io.IOException; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class YmlConfigTest { @Test @@ -21,7 +26,38 @@ public void letsPlayAround() throws IOException { TestRunnerConfig config = mapper.readValue(new File(testConfigFile), TestRunnerConfig.class); - System.out.println(ReflectionToStringBuilder.toString(config,ToStringStyle.MULTI_LINE_STYLE)); + System.out.println(ReflectionToStringBuilder.toString(config, ToStringStyle.MULTI_LINE_STYLE)); + } + + @Test + public void configTest() { + JCommander jc = new JCommander(); + jc.setProgramName("utplsql"); + + CommandProvider cmdProvider = new CommandProvider(); + + cmdProvider.commands().forEach(cmd -> jc.addCommand(cmd.getCommand(), cmd)); + + jc.parse("run", TestHelper.getConnectionString(), + "-f=ut_coverage_html_reporter", "-o=test.html", + "-f=ut_documentation_reporter", "-s", + "-exclude=app.award_bonus,app.betwnstr"); + + RunCommand cmd = (RunCommand) cmdProvider.getCommand(jc.getParsedCommand()); + + TestRunnerConfig config = cmd.getConfig(); + + assertEquals(TestHelper.getConnectionString(), config.getConnectString()); + assertEquals(2, config.getReporters().length); + assertEquals("ut_coverage_html_reporter", config.getReporters()[0].getName()); + assertEquals("test.html", config.getReporters()[0].getOutput()); + assertEquals(false, config.getReporters()[0].isScreen()); + assertEquals("ut_documentation_reporter", config.getReporters()[1].getName()); + assertNull(config.getReporters()[1].getOutput()); + assertEquals(true, config.getReporters()[1].isScreen()); + assertEquals("app.award_bonus", config.getExcludePackages()[0]); + assertEquals("app.betwnstr", config.getExcludePackages()[1]); + } diff --git a/src/test/resources/test b/src/test/resources/test new file mode 100644 index 0000000..abf95a1 --- /dev/null +++ b/src/test/resources/test @@ -0,0 +1,26 @@ +utPLSQL-cli/bin/utplsql run test_runner/pass@db_url \ + -p=hr,app \ + -f=ut_documentation_reporter \ + -f=ut_coverage_html_reporter \ + -o=coverage.html \ + -f=ut_sonar_test_reporter \ + -o=sonar.txt \ + -s \ + -c \ + --failure-exit-code=2 \ + -scc \ + -include=app.betwnstr,mypackage \ + -exclude=mypackage.blugg,stuff \ + -source_path=sources \ + -regex_expression="/(\w+)/(\w+)/(\w+)\..{3}$" \ + -type_mapping="packages_bodies=PACKAGE BODY/types_bodies=TYPE BODY/triggers=TRIGGER/procedures=PROCEDURE/functions=FUNCTION" \ + -owner_subexpression=2 \ + -name_subexpression=3 \ + -type_subexpression=4 \ + -test_path=tests -regex_expression="/(\w+)/(\w+)/(\w+)\..{3}$" \ + -type_mapping="body=PACKAGE BODY/type_body=TYPE BODY/trigger=TRIGGER" \ + -owner_subexpression=2 \ + -name_subexpression=3 \ + -type_subexpression=4 \ + -f=ut_coverage_html_reporter -o=coverage.html \ + -f=ut_sonar_test_reporter -o=test_results.xml \ No newline at end of file