How do you include multiple activities in the Gradle Liquibase plugin's runList field? - testing

I’m using Gradle 2.7 on Mac Yosemite with Java 8. I’m using the Liquibase 1.1.1 plugin and would like to use it to do a couple of activities (build a test database and build my normal database). So I have
liquibase {
activities {
main {
File propsFile = new File("${project.rootDir}/src/main/resources/liquibase.properties")
Properties properties = new Properties()
properties.load(new FileInputStream(propsFile))
changeLogFile 'src/main/resources/db.changelog-master.xml'
url properties['url']
username properties['username']
password properties['password']
}
test {
url 'jdbc:h2:file:target/testdb'
username 'sa'
}
runList = (
"test"
"main"
)
}
}
But I can’t figure out the proper syntax for runList. I get the error when running the above …
* Where:
Build file '/Users/myuser/Dropbox/cb_workspace/cbmyproject/build.gradle' line: 163
* What went wrong:
Could not compile build file '/Users/myuser/Dropbox/cb_workspace/cbmyproject/build.gradle'.
> startup failed:
build file '/Users/myuser/Dropbox/cb_workspace/cbmyproject/build.gradle': 163: expecting ')', found 'main' # line 163, column 2.
"main"
^
1 error
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED

According to one of there example, the runList must be placed after the activity block:
liquibase {
activities {
main {
File propsFile = new File("${project.rootDir}/src/main/resources/liquibase.properties")
Properties properties = new Properties()
properties.load(new FileInputStream(propsFile))
changeLogFile 'src/main/resources/db.changelog-master.xml'
url properties['url']
username properties['username']
password properties['password']
}
test {
url 'jdbc:h2:file:target/testdb'
username 'sa'
}
}
runList = 'test, main'
}
See the example here.
Hope this helps.

Related

How to display in a project that is called from another pipeline project in jenkins text in "Edit Build Information"

Hello: I have a pipeline project at Jenkins called "ProjectLaunch" that launches other projects automatically one day a week. I would like to show in "Edit Build Information" a text that says something like "ProjectCalled full launched", in the project that is called. With the pipeline I have in "ProjectLaunch" I can only get that text in its "Edit Execution Information" but not in the projects called.
My pipeline:
pipeline {
agent any
stages {
stage('Proyect called') {
steps{
build job: 'Proyect called',string(name: "DESCRIPTION", value: "ProjectCalled full launched") ]
}
}
}
}
In the project called in the configuration I have an Execute system Groovy script, it is this:
import hudson.model.*
def build = manager.build
def params = build.action(hudson.model.ParametersAction).getParameters()
def description = "${params.DESCRIPTION}"
echo "Setting build description to: ${description}"
build.createSummary("Build description").appendText(description, "html")
But when I launch it I get this error:
Caught: groovy.lang.MissingPropertyException: No such property: manager for class: hudson1130775177255181016
groovy.lang.MissingPropertyException: No such property: manager for class: hudson1130775177255181016
Any ideas?
Thank you.
As far as I know, you can't set the build description of a downstream job from an upstream Job. Hence in your Downstream Job, you can have some logic to set the description based on the trigger.
pipeline {
agent any
stages {
stage('Hello') {
steps {
script {
echo 'Your second Job'
if(currentBuild.getBuildCauses()[0]._class == "org.jenkinsci.plugins.workflow.support.steps.build.BuildUpstreamCause") {
echo "This is triggered by upstream Job"
currentBuild.description = "ProjectCalled full launched."
}
}
}
}
}
}
I've done the following because with Groovy I couldn't do it. I installed "Build Name and Description Setter" plugin. In the "ProjectLaunch" pipeline project, the pipeline would be more or less like this:
Pipeline {
agent any
parameters{
string(name: "DESCRIPTION", defaultValue: "ProjectCalled full launched", description: "")
}
stages {
stage('ProjectCalled') {
steps{
build job: 'ProjectCalled', parameters: [string(name: "DESCRIPTION", value: params.DESCRIPTION)]
}
}
}
}
And in the ProjectCalled in settings, add a parameter, I select the plugin option Changes build description, and I write ${DESCRIPTION}.
Changes build description
Ah!, I have also created string parameter named DESCRIPTION and without value.
String parameter

How to add cookie to Selenium IDE test running in grid via selenium-side-runner for Zalenium messages

I've recorded a test using Selenium IDE and am submitting the generated .side file to selenium-side-runner to run on a Selenium Grid built using Zalenium. Is it possible to run a command that calls driver.manage().addCookie() from the test that was submitted to selenium-side-runner? I want to do this to send messages back to Zalenium with test progress and status
I added a command executeScript to the Selenium IDE editor with a target of driver.manage().addCookie({name: 'test', value: 'test'})
I see that the command that selenium-side-runner generated in commons.js was
await driver.executeScript(`driver.manage().addCookie({name:'test', value: 'test'});`);
Doing this causes the browser to report an error JavascriptError: javascript error: driver is not defined
I think what I need is the code to be generated without the driver.executeScript wrapper. Is there a way to accomplish this without exporting my Selenium IDE test to NUnit?
I was able to make this functionality work by crudely modifying the selenium-side-runner package on my Windows dev machine
In file ~\node_modules\selenium-side-runner\node_modules\selianize\dist\selianize.cjs.js
Change
function generateScript(script, isExpression = false) {
return `await driver.executeScript(\`${isExpression ? `return (${script.script})` : script.script}\`${script.argv.length ? ',' : ''}${script.argv.map(n => `vars["${n}"]`).join(',')});`;
}
to
function generateScript(script, isExpression = false) {
if (script.script.indexOf('zalenium') > -1)
{
return script.script;
} else
{
return `await driver.executeScript(\`${isExpression ? `return (${script.script})` : script.script}\`${script.argv.length ? ',' : ''}${script.argv.map(n => `vars["${n}"]`).join(',')});`;
}
}
Now when running a test with selenium-side-runner, calling "executeScript" with any value that contains zalenium will generate the command verbatim in the test script

Feature with tag still being run when configured not to

I have a main feature file where I have included a "setup" feature file that should add some test data. This setup feature file has an annotation that I have called #ignore. However, following the instructions in this Can't be enable to #ignore annotation for the features SO answer, but I am still seeing the setup feature file being run outside of the main test feature.
Main feature file, unsubscribe_user.feature:
Feature: Unsubscribe User
Background:
* def props = read('properties/user-properties.json')
* url urlBase
* configure headers = props.headers
* def authoriZation = call read('classpath:basic-auth.js') { username: 'admin', password: 'admin' }
* def testDataSetup = call read('classpath:com/meanwhileinhell/app/karate/feature/mockserver/testDataSetup.feature') { data1: #(props.data1), data2: #(props.data2) }
Scenario: Unsubscribe user
...
...
Scenario: Remove test data
* def testDataTearDown = call read('classpath:com/meanwhileinhell/app/karate/feature/mockserver/testDataTearDown.feature') { data1: #(props.data1), data2: #(props.data2) }
...
testDataSetup.feature file
#ignore
Feature: Add data to REST Mock Server
Background:
* url mockServerUrlBase
Scenario: Add data
* print 'Adding test data'
Given path 'mapping'
And request { data1: '#(data1)', data2: '#(data2)' }
When method post
Then status 201
Now from my Java runner class, I have added #KarateOptions(tags = "~#ignore").
import org.junit.runner.RunWith;
import com.intuit.karate.KarateOptions;
import com.intuit.karate.junit4.Karate;
import cucumber.api.CucumberOptions;
#RunWith(Karate.class)
#CucumberOptions(features = "classpath:com/meanwhileinhell/app/karate/feature/unsubscribe_user.feature")
#KarateOptions(tags = "~#ignore")
public class KarateTestUnSubscribeUserRunner {
}
However, I can still see my print statement in my setup class being called, and two POSTs being performed. I have also tried running my suite with the following cmd options, but again, still see the feature file run twice.
./gradlew clean test -Dkarate.env=local -Dkarate.options="--tags ~#ignore" --debug
I am following this wrong somewhere? Is there something I can add to my karate-config.js file? I am using Karate version 0.9.0.
Annotations only work on the "top level" feature. Not on "called" features.
If your problem is that the features are being run even when not expected, you must be missing something, or some Java class is running without knowing it. So please follow this process and we can fix it: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue
EDIT: I think I got it - please don't mix CucumberOptions, in fact we deprecated it, use only KarateOptions. Even that is not recommended in 0.9.5 onwards and you should move to JUnit 5.
Read the docs: https://github.com/intuit/karate#karate-options

Gulp task to SSH and then mysqldump

So I've got this scenario where I have separate Web server and MySQL server, and I can only connect to the MySQL server from the web server.
So basically everytime I have to go like:
step 1: 'ssh -i ~/somecert.pem ubuntu#1.2.3.4'
step 2: 'mysqldump -u root -p'password' -h 6.7.8.9 database_name > output.sql'
I'm new to gulp and my aim was to create a task that could automate all this, so running one gulp task would automatically deliver me the SQL file.
This would make the developer life a lot easier since it would just take a command to download the latest db dump.
This is where I got so far (gulpfile.js):
////////////////////////////////////////////////////////////////////
// Run: 'gulp download-db' to get latest SQL dump from production //
// File will be put under the 'dumps' folder //
////////////////////////////////////////////////////////////////////
// Load stuff
'use strict'
var gulp = require('gulp')
var GulpSSH = require('gulp-ssh')
var fs = require('fs');
// Function to get home path
function getUserHome() {
return process.env.HOME || process.env.USERPROFILE;
}
var homepath = getUserHome();
///////////////////////////////////////
// SETTINGS (change if needed) //
///////////////////////////////////////
var config = {
// SSH connection
host: '1.2.3.4',
port: 22,
username: 'ubuntu',
//password: '1337p4ssw0rd', // Uncomment if needed
privateKey: fs.readFileSync( homepath + '/certs/somecert.pem'), // Uncomment if needed
// MySQL connection
db_host: 'localhost',
db_name: 'clients_db',
db_username: 'root',
db_password: 'dbp4ssw0rd',
}
////////////////////////////////////////////////
// Core script, don't need to touch from here //
////////////////////////////////////////////////
// Set up SSH connector
var gulpSSH = new GulpSSH({
ignoreErrors: true,
sshConfig: config
})
// Run the mysqldump
gulp.task('download-db', function(){
return gulpSSH
// runs the mysql dump
.exec(['mysqldump -u '+config.db_username+' -p\''+config.db_password+'\' -h '+config.db_host+' '+config.db_name+''], {filePath: 'dump.sql'})
// pipes output into local folder
.pipe(gulp.dest('dumps'))
})
// Run search/replace "optional"
SSH into the web server runs fine, but I have an issue when trying to get the mysqldump, I'm getting this message:
events.js:85
throw er; // Unhandled 'error' event
^
Error: Warning:
If I try the same mysqldump command manually from the server SSH, I get:
Warning: mysqldump: unknown variable 'loose-local-infile=1'
Followed by the correct mylsql dump info.
So I think this warning message is messing up my script, I would like to ignore warnings in cases like this, but don't know how to do it or if it's possible.
Also I read that using the password directly in the command line is not really good practice.
Ideally, I would like to have all the config vars loaded from another file, but this is my first gulp task and not really familiar with how I would do that.
Can someone with experience in Gulp orient me towards a good way of getting this thing done? Or do you think I shouldn't be using Gulp for this at all?
Thanks!
As I suspected, that warning message was preventing the gulp task from finalizing, I got rid of it by commenting the: loose-local-infile=1 From /etc/mysql/my.cnf

Gradle ternary/elvis operator not setting 'else' value when external property not set

The 'else' value of the elvis/ternary operator in my gradle build file is not setting the property value if I do not run gradle with the "-P" option.
Here's the root project's build.gradle
defaultTasks 'loadConfiguration'
task loadConfiguration << {
def profile = hasProperty('profile') ? profile : 'dev'
ext.profile = profile
def configFile = file('profile.properties')
def config = new ConfigSlurper(profile).parse(configFile.toURL())
ext.config = config
}
configure (subprojects) {
profile = profile //inject property into sub-project
println profile
task buildear << {
ear
}
}
The sub-project 'ear' is in the settings.gradle file.
Below are the results of a build attempt-
With external property set:
$ gradle -Pprofile=wwww
Parallel execution is an incubating feature.
wwww
wwww
wwww
:loadConfiguration
BUILD SUCCESSFUL
Total time: 5.834 secs
With empty external property set:
$ gradle -Pprofile
Parallel execution is an incubating feature.
:loadConfiguration
BUILD SUCCESSFUL
Total time: 5.389 secs
With no external property set:
$ gradle
Parallel execution is an incubating feature.
FAILURE: Build failed with an exception.
* Where:
Build file '/home/robert/codingk/kazi/trunk2/mazama2/build.gradle' line: 13
* What went wrong:
A problem occurred evaluating root project 'mazama2'.
> Could not find property 'profile' on project ':ear'.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 2.104 secs
Line 13 is the line "profile = profile //inject property into sub-project"
I cannot figure out why the 'profile' property is not getting set to 'dev'. A few things I've tried without success:
profile= "${profile}
def profile = project.hasProperty('profile') ? profile : 'dev'
project.ext.profile = profile
some remarks about your initial build script.
In your initial build script you declared a task (loadConfiguration) to set the profile. This logic is executed AFTER the configure block below
is executed. That's one reason why "profile" is always null in the configuration block
The second problem is, that you need to be careful about scoping. In the snippet
ext.profile = profile
you add a dynamic property to the loadConfiguration task, not to the project itself. That's why you can't reference
The profile property if you havn't passed it via commandline.
Maybe instead of doing the configuration loading in a seperate task, do it on the top level of your build:
ext.profile = hasProperty('profile') ? profile : 'dev'
def configFile = file('profile.properties')
def config = new ConfigSlurper(profile).parse(configFile.toURL())
ext.config = config
configure (subprojects) {
profile = profile //inject property into sub-project
println profile
task buildear << {
ear
}
}
Got it working with the following modifications. I may be wrong but I believe it had to do with task ordering; declaring loadConfiguration() as a default task did not cause it to be executed first which is what I needed
def loadConfiguration() {
def profile = hasProperty('profile') ? profile : 'dev'
ext.profile = profile
def configFile = file('profile.properties')
def config = new ConfigSlurper(profile).parse(configFile.toURL())
ext.config = config
}
configure (subprojects) {
loadConfiguration()
profile = profile //inject property into sub-project
println profile
task buildear << {
ear
}
}