-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SDK-269: Added ValidateConfigurationsMojo. (#7)
- Loading branch information
Showing
4 changed files
with
319 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
...s/src/test/java/org/openmrs/maven/plugins/packager/config/ValidateConfigurationsTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package org.openmrs.maven.plugins.packager.config; | ||
|
||
import static org.hamcrest.CoreMatchers.is; | ||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.hamcrest.Matchers.containsInAnyOrder; | ||
import static org.mockito.ArgumentMatchers.any; | ||
import static org.mockito.Mockito.when; | ||
import static org.mockito.Mockito.times; | ||
import static org.mockito.Mockito.verify; | ||
import static org.powermock.api.mockito.PowerMockito.doThrow; | ||
|
||
import java.io.File; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.apache.maven.plugin.MojoExecutionException; | ||
import org.junit.Before; | ||
import org.junit.Rule; | ||
import org.junit.Test; | ||
import org.junit.rules.ExpectedException; | ||
import org.junit.runner.Result; | ||
import org.junit.runner.RunWith; | ||
import org.mockito.Mockito; | ||
import org.openmrs.module.initializer.validator.Validator; | ||
import org.powermock.api.mockito.PowerMockito; | ||
import org.powermock.core.classloader.annotations.PrepareForTest; | ||
import org.powermock.modules.junit4.PowerMockRunner; | ||
|
||
@RunWith(PowerMockRunner.class) | ||
@PrepareForTest(Validator.class) | ||
public class ValidateConfigurationsTest { | ||
|
||
private File logDir = Mockito.mock(File.class); | ||
|
||
private class TestMojo extends ValidateConfigurationsMojo { | ||
@Override | ||
protected File getSourceDir() { | ||
return new File(getClass().getClassLoader().getResource("config-test-parent/configuration").getPath()); | ||
} | ||
@Override | ||
protected File getBuildDir() { | ||
return logDir; | ||
} | ||
} | ||
|
||
private ValidateConfigurationsMojo mojo = new TestMojo(); | ||
|
||
private Result result; | ||
|
||
@Before | ||
public void before() { | ||
PowerMockito.mockStatic(Validator.class); | ||
} | ||
|
||
@Rule | ||
public ExpectedException exceptionRule = ExpectedException.none(); | ||
|
||
@Test(expected = Test.None.class) | ||
public void execute_successfulJUnitResultShouldNotThrowMojoExecutionException() throws Exception { | ||
// setup | ||
result = new Result(); | ||
when(Validator.getJUnitResult(any(String[].class))).thenReturn(result); | ||
|
||
// replay | ||
mojo.execute(); | ||
verify(logDir, times(1)).getAbsolutePath(); | ||
} | ||
|
||
@Test | ||
public void execute_failedJUnitResultShouldThrowMojoExecutionException() throws Exception { | ||
// setup | ||
result = new Result() { | ||
@Override | ||
public boolean wasSuccessful() { | ||
return false; | ||
} | ||
}; | ||
when(Validator.getJUnitResult(any(String[].class))).thenReturn(result); | ||
|
||
// replay | ||
exceptionRule.expect(MojoExecutionException.class); | ||
mojo.execute(); | ||
} | ||
|
||
@Test | ||
public void execute_throwingValidatorShouldThrowMojoExecutionException() throws Exception { | ||
// setup | ||
doThrow(new RuntimeException()).when(Validator.class); | ||
Validator.getJUnitResult(any(String[].class)); | ||
|
||
// replay | ||
exceptionRule.expect(MojoExecutionException.class); | ||
mojo.execute(); | ||
} | ||
|
||
@Test | ||
public void addValidatorCliOptions_shouldParseExtraValidatorArgs() throws MojoExecutionException { | ||
// setup | ||
String extraArgs = "--opt1 --opt2='foo bar' --opt3=bar --unsafe --ciel-file='/path/to/ciel.sql' --config-dir='/path/to/config_dir'"; | ||
List<String> args = new ArrayList<>(); | ||
|
||
// replay | ||
new ValidateConfigurationsMojo().addValidatorCliArguments(extraArgs, args); | ||
|
||
// verify | ||
assertThat(args.size(), is(3)); | ||
assertThat(args, containsInAnyOrder("--opt1", "--opt2='foo bar'", "--opt3=bar")); | ||
} | ||
} |
153 changes: 153 additions & 0 deletions
153
...n/src/main/java/org/openmrs/maven/plugins/packager/config/ValidateConfigurationsMojo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
/** | ||
* This Source Code Form is subject to the terms of the Mozilla Public License, | ||
* v. 2.0. If a copy of the MPL was not distributed with this file, You can | ||
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under | ||
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license. | ||
* | ||
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS | ||
* graphic logo is a trademark of OpenMRS Inc. | ||
*/ | ||
package org.openmrs.maven.plugins.packager.config; | ||
|
||
import static org.apache.commons.lang.StringUtils.isEmpty; | ||
import static org.openmrs.module.initializer.validator.Validator.ARG_CIEL_FILE; | ||
import static org.openmrs.module.initializer.validator.Validator.ARG_CONFIG_DIR; | ||
import static org.openmrs.module.initializer.validator.Validator.ARG_UNSAFE; | ||
import static org.openmrs.module.initializer.validator.Validator.ARG_LOG_DIR; | ||
|
||
import java.io.File; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.stream.Stream; | ||
|
||
import javax.persistence.Cache; | ||
import javax.persistence.EntityGraph; | ||
import javax.persistence.PersistenceException; | ||
import javax.persistence.PersistenceUnitUtil; | ||
import javax.persistence.Query; | ||
import javax.persistence.TransactionRequiredException; | ||
import javax.persistence.criteria.CriteriaBuilder; | ||
import javax.persistence.metamodel.Metamodel; | ||
|
||
import org.apache.maven.plugin.MojoExecutionException; | ||
import org.apache.maven.plugins.annotations.Mojo; | ||
import org.apache.maven.plugins.annotations.Parameter; | ||
import org.junit.runner.Result; | ||
import org.openmrs.module.initializer.validator.Validator; | ||
import org.springframework.dao.EmptyResultDataAccessException; | ||
import org.springframework.orm.jpa.EntityManagerFactoryUtils; | ||
import org.springframework.orm.jpa.JpaObjectRetrievalFailureException; | ||
import org.springframework.orm.jpa.JpaOptimisticLockingFailureException; | ||
import org.springframework.orm.jpa.JpaSystemException; | ||
|
||
/** | ||
* The purpose of this Mojo is to validate configurations. | ||
*/ | ||
@Mojo( name = "validate-configurations" ) | ||
public class ValidateConfigurationsMojo extends AbstractPackagerConfigMojo { | ||
|
||
// Configuration Directory | ||
@Parameter(property = "sourceDir", defaultValue = "configuration") | ||
private File sourceDir; | ||
|
||
@Parameter(property = "cielFile") | ||
private File cielFile; | ||
|
||
// Extra Validator CLI options | ||
@Parameter(property = "extraValidatorArgs") | ||
private String extraValidatorArgs; | ||
|
||
protected File getSourceDir() { | ||
return sourceDir; | ||
} | ||
|
||
/* | ||
* To avoid NoClassDefFoundError on EntityManagerFactoryUtils and related classes. | ||
*/ | ||
private void findClassDefinitions() { | ||
EntityManagerFactoryUtils.class.toString(); | ||
PersistenceException.class.toString(); | ||
TransactionRequiredException.class.toString(); | ||
JpaObjectRetrievalFailureException.class.toString(); | ||
EmptyResultDataAccessException.class.toString(); | ||
JpaOptimisticLockingFailureException.class.toString(); | ||
JpaSystemException.class.toString(); | ||
Cache.class.toString(); | ||
CriteriaBuilder.class.toString(); | ||
Metamodel.class.toString(); | ||
PersistenceUnitUtil.class.toString(); | ||
Query.class.toString(); | ||
EntityGraph.class.toString(); | ||
} | ||
|
||
/** | ||
* @throws MojoExecutionException if the Maven build should be errored. | ||
*/ | ||
public void execute() throws MojoExecutionException { | ||
|
||
findClassDefinitions(); // TODO: figure out why this is needed | ||
|
||
List<String> args = new ArrayList<>(); | ||
if (getSourceDir() == null || !getSourceDir().isDirectory()) { | ||
throw new MojoExecutionException(getSourceDir().getAbsolutePath() + " does not point to a valid directory."); | ||
} | ||
args.add("--" + ARG_CONFIG_DIR + "=" + getSourceDir().getAbsolutePath()); | ||
|
||
// The build directory to be the default log directory. | ||
if (extraValidatorArgs == null || !extraValidatorArgs.contains(ARG_LOG_DIR)) { | ||
args.add("--" + ARG_LOG_DIR + "=" + getBuildDir().getAbsolutePath()); | ||
} | ||
|
||
if (cielFile != null) { | ||
args.add("--" + ARG_CIEL_FILE + "=" + cielFile.getAbsolutePath()); | ||
} | ||
|
||
if (!isEmpty(extraValidatorArgs)) { | ||
addValidatorCliArguments(extraValidatorArgs, args); | ||
|
||
} | ||
|
||
Result result; | ||
try { | ||
args.add("--" + ARG_UNSAFE); | ||
result = Validator.getJUnitResult(args.toArray(new String[0])); | ||
} | ||
catch (Exception e) { | ||
throw new MojoExecutionException(e.getMessage(), e); | ||
} | ||
|
||
if (!result.wasSuccessful()) { | ||
throw new MojoExecutionException("The configuration could not be validated, scroll up the Maven build logs for details."); | ||
} | ||
|
||
} | ||
|
||
/** | ||
* Parses a one liner string of Validators arguments into a list of arguments supported by the plugin. | ||
* | ||
* @param opts The string Validators args/options, eg. "--domains='concepts,locations' --exclude.concepts='*diags*,*interventions*'" | ||
* @param args (ouput) The list of Validator args. | ||
*/ | ||
protected void addValidatorCliArguments(String opts, List<String> args) { | ||
Stream.of(opts.split("--")).map(o -> o.trim()).filter(o -> !isEmpty(o)).filter(o -> includeOption(o)).forEach(o -> { | ||
args.add("--" + o); | ||
}); | ||
} | ||
|
||
protected boolean includeOption(String opt) { | ||
if (opt.startsWith(ARG_CONFIG_DIR)) { | ||
getLog().warn("--" + ARG_CONFIG_DIR + " cannot be provided as an extra Validator argument, use <sourceDir/> instead in the plugin configuration."); | ||
return false; | ||
} | ||
if (opt.startsWith(ARG_CIEL_FILE)) { | ||
getLog().warn("--" + ARG_CIEL_FILE + " cannot be provided as an extra Validator argument, use <cielFile/> instead in the plugin configuration."); | ||
return false; | ||
} | ||
if (opt.startsWith(ARG_UNSAFE)) { | ||
getLog().info("--" + ARG_UNSAFE + " is redundant since the plugin always validates configurations in unsafe mode."); | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters