Grails 3 - conditionally ignore Spock test - grails

I'd like to use Spock annotation #IgnoreIf({condition}) to ignore test based on given environment variable when running from Intellij IDEA.
I use this in my test: #IgnoreIf({ env.IGNORE_REDIS == 'true' }). And set it in Gradle run configuration as following:
However, the environment property is never set. Is it an IDEA bug or am I missing something in my configuration?

How about this?
#IgnoreIf({ properties.IGNORE_REDIS == 'true' })
For me this works in Spock (not using Grails though).

You need to modify your gradle test task to copy the system properties.
task integrationTest(...) {
systemProperties System.properties // this line passes the systemproperties from gradle to your tests
}
And for your test in Spock:
#IgnoreIf({sys['IGNORE_REDIS']})
//or
#IgnoreIf({sys.IGNORE_REDIS})
//or
#IgnoreIf({sys.IGNORE_REDIS == 'true'})

Related

gradle - make a step 100% optional

We use clover for code coverage testing but it interferes with stack traces and error information. I want to be able to use cloverGenerateReport when doing automated builds via jenkins but to skip this step entirely when doing local builds.
I've tried the various suggestions from searches for 'gradle optional dependencies' but I can't seem to get clover completely out of the way.
Suggestions?
You can use the method onlyIf.
cloverGenerateReport.onlyIf {
project.hasProperty('enableClover') ? Boolean.valueOf(project.getProperty('enableClover')) : false
}
On the command line you can enable it by providing the project property:
gradle cloverGenerateReport -PenableClover=true
One solution would be to check if the environment variable "JENKINS_HOME" exists. If it does, then set cloverGenerateReport as a dependency to another task.
In your build.gradle:
def env = System.getenv()
if(env.containsKey('JENKINS_HOME')){
reportTask.dependsOn cloverGenerateReport
}

Why does Gradle always call an ant task first?

I use the OWASP Dependency Check from its ant task (no Gradle support yet) like this:
task checkDependencies() {
ant.taskdef(name: 'checkDependencies',
classname: 'org.owasp.dependencycheck.taskdefs.DependencyCheckTask',
classpath: 'scripts/dependency-check-ant-1.2.5.jar')
ant.checkDependencies(applicationname: "MyProject",
reportoutputdirectory: "generated",
dataDirectory: "generated/dependency-check-cache") {
fileset(dir: 'WebContent/WEB-INF/lib') {
include(name: '**.jar')
}
}
}
This works way too good. Even though nothing defines this ant task as dependency (neither in ant nor in Gradle), it is always executed first, even for a simple gradlew tasks. Why is that and how can I avoid this? (The dependency check is quite slow.)
This is a very common confusion with Gradle. In your example above you are executing the Ant tasks during project configuration. What you really intended was for it to run during task execution. To fix this, your execution logic should be placed within a task action, either by using a doLast {...} configuration block or using the left shift (<<) operator.
task checkDependencies << {
// put your execution logic here
}
See the Gradle docs for more information about the Gradle build lifecycle.

How to tell Grails application which environment it is in?

I would like to load Environment specific configurations in my grails application so that depending on which JVM the grails application is running on, I can point to that environment specific urls. In my case, I have 4 different environments to work with (instead of the default 3 that grails app assumes) when my app goes from dev to prod.
My JVMs all have a System property defined that, when I do "System.getProperty()", tell me which environment that application is running on.
My question is, what is the best place to check and load the environment-specific configurations during run-time? Inside BootStrap.groovy? I do not have the option to build my war file using command line or grails {env_name} war.
Thanks.
Set the variable grailsEnv as a environment Java variable for Tomcat below is an example:
set CATALINA_OPTS=%CATALINA_OPTS% -Xms256m -Xmx1024m -Dgrails.env=development
On a grails command line you add the environment variable:
grails run-app -Dgrails.env=stage
You can use check the environment variable like this:
if (grails.util.Environment.current.name == "development") {
UsageCodeDefinition ucd = new UsageCodeDefinition()
ucd.setDescription("UFARSFileUpload Upload Development")
ucd.setFiscalYear("12-13")
ucd.setInstructions("Welcome to UFARSFileUpload Development were Open")
ucd.save(failOnError: true)
}
You can use the Enumerated values instead of the name variable but if you use custom environmental values then they are mapped to the enumeration custom and using the name works to distinguish between the custom values.
if (grails.util.Environment.current == grails.util.Environment.DEVELOPMENT) {
Without setting the JVM startup parameter:
-Dgrails.env=whatever
Your grails app will use the value set in
<yourapp>/WEB-INF/classes/application.properties
There will be a value set like this:
grails.env=development
This default environment value is determined by what options are used when building the war. You can build the war with
-Dgrails.env=development war
Then the application.properties will have grails.env=development, if you leave that off, it defaults to grails.env=production
As far as your question, you are not specific about what is being configured to use "environment specific urls". And it is not clear how you are storing these environment specific urls. If, for example, the URL variable is a member variable of a Grails service and you are storing the environment specific URLs in the Config.groovy, then you could
import grails.util.Environment
...
//inject the GrailsApplication Configuration in Config.groovy
def grailsApplication
//Hold the URL value from Config.groovy
String environmentUrl
...
Environment current = Environment.getCurrent()
if(Environment.PRODUCTION == current) {
environmentUrl = grailsApplication.config.PRODUCTION_URL
} else {
environmentUrl = grailsApplication.config.DEVELOPMENT_URL
}
Where Config.groovy has
PRODUCTION_URL = "http://blah.com/blah/"
DEVELOPMENT_URL = "http://blah.dev/blah"
Hope that helps.
If you have a System property available that tells you what environment you're in you can simply add if statements or a switch statement in your Config.groovy file, like this:
if (System.getProperty("foo") == "myTestEnvironment") {
myConfigSetting = "test"
} else if (System.getProperty("foo") == "myProductionEnvironment") {
myConfigSetting = "production"
}
This solution also works in other config files under grails-app/conf
Grails config files are parsed using groovy ConfigSlurper so you can put executable code in there without a problem.
Sorry this is way late, but another way is to inject a configuration property in BootStrap.groovy.
For Example:
if (currentEnv == Environment.DEVELOPMENT) {
...
grailsApplication.config.some.property = DEVELOPMENT_ENVRIONMENT
...
}
else if (currentEnv == Environment.TEST) {
...
grailsApplication.config.some.property = TEST_ENVIRONMENT
...
}
I have used this recently and it works really well. We are using Grails 2.5.2
As an addendum to the other answers:
You can use Environment.isDevelopmentMode() or in a groovier way Environment.developmentMode to check if the environment is set to development. This is useful when you take the aproach of only modifying settings for development on your code where production settings are default.

Spock Integration Test fails when run with other integration tests-succeeds in isolation using integration:spock

I am adding a first spock integration test to an existing set of tests for a grails 2.1.1 application. The test runs and tests pass when run using:
grails test-app integration:spock CreditServiceSpec
(Yes, everything is in the default package - fixing this is a ton of work that will not be approved...file under technical debt.)
However, when I run all the tests (grails test-app), unit test pass, spock unit tests pass, integration tests pass, but I get the following failure for spock integration:
| Completed 818 integration tests, 0 failed in 104001ms
| Running 1 spock test...
| Failure: CreditServiceSpec
| groovy.lang.GroovyRuntimeException: failed to invoke constructor: public org.codehaus.groovy.grails.test.support.GrailsTestAutowirer(org.springframework.context.ApplicationContext) with arguments: [] reason: java.lang.IllegalArgumentException
at grails.plugin.spock.IntegrationSpec.$spock_initializeSharedFields(IntegrationSpec.groovy:33)
| Completed 0 spock test, 0 failed in 33ms
| Tests PASSED - view reports in /Users/*/projects/GrailsPlugins/DomainServices/target/test-reports
I get the exact same exception whether I run the full test I built or the following, very strip down example:
import grails.plugin.spock.IntegrationSpec
class CreditServiceSpec extends IntegrationSpec {
def setup() {}
def cleanup() {}
public void "sample"() {
setup:"Nothing to do here."
expect:"This is the truest of truths..."
true == true
}
}
I did crack open IntegrationSpec and looked at line 33:
#Shared private autowirer = new GrailsTestAutowirer(applicationContext)
But determining how/why the applicationContext is not being passed in properly is beyond me and, perhaps, is the thrust of my question.
Has anyone encountered this kind of behavior and found a way to get spock integration to play nice with other tests? Thanks.
It looks like Grails 2.1.1 had several issues with Spock tests in the Integration scope. Jeff's comment and Peter's in particular sound like the issue you were having; basically the ApplicationHolder was null or an empty list.
The parent task lists Grails 2.2.5 as the fix version. Any chance you can upgrade to that (or some even later version) and see if the problem persists?
There have also been cases where a simple grails clean has fixed issues like this.
I had a problem with the exact same symptom.
I was using the BuildTestData plugin and used the #Build annotation in a IntegrationSpec, but using the #Build with use a transformation wich extended the #TestFor transformation which is incompatible with the Intengration runtime.
So just remove the #Build annotations and it will run.

Why is SpringSecurityUtils null in this Grails unit test?

In Grails 2.0.4, I'm trying to write a controller unit test which invokes the static SpringSecurityUtils.reauthenticate. The test returns a NullPointerException on that invocation. In a debugger, I can see that none of the Groovy dynamic properties (declaredMethods,etc.) of SpringSecurityUtils are populated.
I do note that when running the tests, the "Configuring Spring Security Core" log message is emitted after the unit-test failure. Here is a sample test:
class ReproTest {
void testSpringSecurityUtils() {
String.valueOf(true) // OK: a public final class from the JDK
URLUtils.isRelativeURL("foo") // OK: a class from another plugin
SpringSecurityUtils.reauthenticate "user", "pw" // fails, NPE
}
}
My initial reaction is that maybe plugins aren't accessible during unit tests, but if so, why is the URLUtils call working? And why does the test get "far enough" to initialize the plugin, but after the tests have completed?
For a unit test the container isn't starting up. No Spring injection or "grails goodness" is happening. You see in the logs that the plugin is initializing after the unit tests run, because it [container] does start for the integration tests. If you want to test the SpringSecurityUtils, although guessing it is already tested properly in the plugin, you would want to write an integration test.

Resources