Custom init on test/development mode in Grails - groovy

I want to run specific login in BootStrap class depending on development or test mode is currently used.
How can I do this?

From the documentation:
class Bootstrap {
def init = { ServletContext ctx ->
environments {
production {
// prod initialization
}
test {
// test initialization
}
development {
// dev initialization
}
}
}
...
}

import grails.util.Environment
class BootStrap {
def init = { servletContext ->
def currentEnv = Environment.current
if (currentEnv == Environment.DEVELOPMENT) {
// do custom init for dev here
} else if (currentEnv == Environment.TEST) {
// do custom init for test here
} else if (currentEnv == Environment.PRODUCTION) {
// do custom init for prod here
}
}
def destroy = {
}
}

from the official docs
Programmatic Environment Detection
Within your code, such as in a Gant script or a bootstrap class you can detect the environment using the GrailsUtil class:
import grails.util.GrailsUtil
...
switch(GrailsUtil.environment) {
case "development":
configureForDevelopment()
break
case "production":
configureForProduction()
break

Related

GEB: set default environment?

I declared a few environments in GebConfig via environments {} closure.
And if I specify -Dgeb.env in command line, everything works perfectly.
But when I start a single test for debugging purposes, I don't want to explicitly pass any additional environment variables.
What is the way to define the environment to be used by GEB as a default?
Just define a default driver outside of the environments My Geb config looks like this:
driver = {
new HtmlUnitDriver(true)
}
environments {
html_unit {
driver = {
new HtmlUnitDriver(true)
}
}
phantomjs {
driver = {
WebDriverManager.phantomjs().version("2.1.1").setup()
def pjsDriver = new PhantomJSDriver()
pjsDriver.manage().window().size = new Dimension(1024, 768)
pjsDriver
}
}
chrome {
driver = {
// (...)
}
}
chrome_headless {
System.setProperty("webdriver.chrome.logfile", "chromedriver.log")
System.setProperty("webdriver.chrome.verboseLogging", "true")
driver = {
// (...)
}
}
firefox {
driver = {
// (...)
}
}
ie {
driver = {
// (...)
}
}
edge {
driver = {
// (...)
}
}
opera {
driver = {
// (...)
}
}
win_app {
driver = {
// (...)
}
}
}

Jenkins Library / Groovy Script - Wrap Code dynamically

I'm developing a Jenkins shared library right now.
I wasn't able to figure how to easily "wrap" a code inside a function without copy-pasting the whole code. For example: If a developer sets a value to true, then I want to wrap the whole code inside a function. Right now I want to use this to allow e.g. the gitlabIntegration to be turned off from the Jenkinsfile.
Example:
// vars/stageWrapper.groovy
def call(Map parameters = [:], body) {
stage(stageName) {
if (pushtoGitlab) {
gitlabCommitStatus(stageName) {
if (!containerName) body()
else {
container(containerName) {
body()
}
}
}
} else {
if (!containerName) body()
else {
container(containerName) {
body()
}
}
}
}
}
let the user select if the stage should be pushed to gitlab via the gitlabCommitStatus wrapper.
switch to a specified container or use default container (if none is specified)
To realize this I currently repeat the code, which I really don't like...
Is there any way of achieving the same, but without repeating the same code over and over?
Thank You!
In Groovy you can reuse a Closure in different DSL-Builders by setting it's delegate to builder's delegate.
Something like this should work:
def containerNameBody = { body ->
if (!containerName)
body()
else
container(containerName) {
body()
}
}
def call(Map parameters = [:], body) {
stage(stageName) {
containerNameBody.delegate = delegate
if (pushtoGitlab)
gitlabCommitStatus(stageName) {
containerNameBody body
}
else
containerNameBody body
}
}
How about following approach to pass down the param into function, then decide how to do inside the function by the param value.
def gitHub(gitHubOn) {
}
def gitLab(gitLabOn) {
}
def call(Map parameters = [:], body){
//some code....
foo=bar
gitLab(parameters.gitLabOn)
gitHub(parameters.gitHubOn)
body()
}

Serenity Cucumber4 Environment URL on Page Objects not working

Why does this not work?
When I run the feature file as "Run as Cucumber Feature" I get an error
java.lang.AssertionError: Undefined default URL for page object PageObject
Page Object
#DefaultUrl("page:register.page")
public class AccountCreationPage extends PageObject {
...
}
Config File (serenity.config)
environments {
local {
webdriver.base.url = "https://localhost"
}
demo {
webdriver.base.url = "https://demo.example.com"
}
prod {
webdriver.base.url = "https://example.com"
}
all {
home.page = "#{webdriver.base.url}"
register.page = "#{webdriver.base.url}/register"
}
}
https://johnfergusonsmart.com/environment-specific-configuration-in-serenity-bdd/
shows the use of #DefaultUrl("page:register.page")
Serenity-Cucumber4. Java. Eclipse.
the config file is required to have default as an entry 🤦
environments {
default {
webdriver.base.url = "https://localhost"
}
...
all {
home.page = "#{webdriver.base.url}"
register.page = "#{webdriver.base.url}/register"
}
}

Passing different parameters to created jobs

On Jenkins, using Job DLS plugin, I'm trying to prepare one script which will create jobs configured for different environments (dev and preprod). Depends on for which environments this job has to run, different parameters are needed.
In this situation how to define, in the shortest way, that parameters for dev environment include the same as preprod parameters plus additionally i.e. 2 more?
An example of the code which I use is presented below.
def environments = ["DEV", "PREPROD"]
def names = ["name1", "name2", "name3"]
def jobParameters = {
string {
name("browser")
defaultValue("CHROME")
description("Browser on which one tests will run")
trim(true)
}
string {
name("parameter1")
defaultValue("")
description("")
trim(true)
}
}
def jobParametersDev = {
jobParameters
string {
name("parameter2")
defaultValue("")
description("")
trim(true)
}
string {
name("parameter3")
defaultValue("")
description("")
trim(true)
}
}
def createJob(name, env, runCommand, jobParameters) {
job("Job-${-> name}-${-> env}") {
description("My first job for ${-> name}")
parameters(jobParameters)
steps {
shell {
command(runCommand)
}
}
}
}
for (name in names) {
for (env in environments) {
if (env == 'DEV') {
def runCommand = "python35 -u ./TestSuite-${-> name}.py %parameter1% %parameter2%,%parameter3% %browser%"
createJob(name, env, runCommand, jobParametersDev)
} else {
def runCommand = "python35 -u ./TestSuite-${-> name}.py %parameter1% ${-> env} %browser%"
createJob(name, env, runCommand, jobParameters)
}
}
}
To summarise - the last thing which I tried is:
def jobParametersDev = {
jobParameters
...
}
But it doesn't work... Only values for jobParametersDev are visible.
How to add these values? If it's not necessary I don't want to double the same code.
I will be really grateful for any help.
You can not simply call one closure within another. But you can chain method calls. You just need to pass the job reference.
def generateParameters = { job ->
job.parameters {
stringParam('param3', '', '')
// more params here...
}
}
def generateDevParameters = { job ->
generateParameters(job)
job.parameters {
stringParam('param4', '', '')
// more params here...
}
}
def createJob(name, generateParameters) {
def j = job(name) {
// more config here...
}
generateParameters(j)
}
createJob('test1', generateParameters)
createJob('test2', generateDevParameters)

groovy print environments from groovy.config

how do I print available environments from a config file? What is the form of the ojbect ConfigSlurper creates?
I tried
def config2 = new ConfigSlurper().parse(new File('obieeadmincfg.groovy').toURL())
config2.config.environments.each { println ${it} }
and
println prettyPrint(toJson(config2))
and
for ( i in 0 ..config2.config.environments.size()-1)
println config2.config.environments[i]
groovy.config
//Config3.groovy
obieadmin {
//default values
serverurl = "http://default.mycompany.com"
}
environments {
pldev01 {
obieeadmin {
serverurl = 'devgdwobi03.x.com'
}
}
plsbx02 {
obieeadmin {
serverurl = 'devgdwobi03.x.com'
}
}
}
I'm afraid you can't do this out-of box.
But using a bit of Groovy Metaprogramming it's achievable.
Groovy config slurper parses proper Groovy file, and you can do the same with GroovyShell. You can catch call to environment method providing closure in binding. In that closure you have to collect all top-level method calls(with same methodMissing).
Providing base script with property and method missing handlers, you can suppress runtime errors, and execute script without much care to other properties.
Not the nicest path, but it works.
package test
import org.codehaus.groovy.control.CompilerConfiguration
class A extends Script {
def propertyMissing(String name) { null }
def propertyMissing(String name, def arg) {}
def methodMissing(String name, def args) {}
#Override Object run() { null }
}
class NameCollector {
def envs = []
def methodMissing(String name, def args) { envs << name }
}
// configure interceptors.
def configuration = new CompilerConfiguration()
configuration.scriptBaseClass = 'test.A'
def nc = new NameCollector()
def environments = { Closure it ->
it.delegate = nc;
it.resolveStrategy = Closure.DELEGATE_ONLY
it()
}
// execute config script
new GroovyShell([environments: environments] as Binding, configuration).evaluate(new File("config.groovy"))
nc.envs // Return, print them.
Not sure if this is going to work forever but currently you can do it by overriding the setting for the 'environments' conditional block, like this:
def config = """environments {
dev {
foo = "bar"
}
prod {
foo = "baz"
}
}"""
def configSlurper = new ConfigSlurper()
configSlurper.registerConditionalBlock('environments', null)
assert configSlurper.parse(config).environments.keySet() == ['dev', 'prod'].toSet()

Resources