How to check the Groovy assert return? - grails

My assert statement
assert actualObject==expectedObject : "Verify Status"
How can I validate the return statement(TRUE or FALSE) of the above assert statement?
Like
if(WebUI.verifyEqual(actualObject, expectedObject)==true){
My purpose:
if it's True I will do something, else I throw the assert error

How can I validate the return statement(TRUE or FALSE) of the above
assert statement?
My purpose: if it's True I will do something, else I throw the assert
error
That is what will happen if you do this:
assert actualObject==expectedObject : "Verify Status"
EDIT:
#daggett left a comment below indicating "i believe he don't want to throw error". If that is the case the question isn't clear but you can do that simply with an if:
if(actualObject==expectedObject) {
// do something
} else {
// don't throw an error
}
Or:
if(WebUI.verifyEqual(actualObject, expectedObject)) {
// do something
} else {
// don't throw an error
}

Related

Jenkins timeout/abort exception

We have a Jenkins pipeline script that requests approval from the user after all the preparatory steps are complete, before it actually applies the changes.
We want to add a timeout to this step, so that if there is no input from the user then the build is aborted, and are currently working on using this kind of method:
try {
timeout(time: 30, unit: 'SECONDS') {
userInput = input("Apply changes?")
}
} catch(err) {
def user = err.getCauses()[0].getUser()
if (user.toString == 'SYSTEM') { // if it's system it's a timeout
didTimeout = true
echo "Build timed out at approval step"
} else if (userInput == false) { // if not and input is false it's the user
echo "Build aborted by: [${user}]"
}
}
This code is based on examples found here: https://support.cloudbees.com/hc/en-us/articles/226554067-Pipeline-How-to-add-an-input-step-with-timeout-that-continues-if-timeout-is-reached-using-a-default-value and other places online, but I really dislike catching all errors then working out what's caused the exception using err.getCauses()[0].getUser(). I'd rather explicitly catch(TimeoutException) or something like that.
So my question is, what are the actual exceptions that would be thrown by either the approval step timing out or the userInput being false? I haven't been able to find anything in the docs or Jenkins codebase so far about this.
The exception class they are referring to is org.jenkinsci.plugins.workflow.steps.FlowInterruptedException.
Cannot believe that this is an example provided by CloudBeeds.
Most (or probably all?) other exceptions won't even have the getCauses() method which of course would throw another exception then from within the catch block.
Furthermore as you already mentioned it is not a good idea to just catch all exceptions.
Edit:
By the way: Scrolling further down that post - in the comments - there you'll find an example catching a FlowInterruptedException.
Rather old topic, but it helped me, and I've done some more research on it.
As I figured out, FlowInterruptedException's getCauses()[0] has .getUser() only when class of getCauses()[0] is org.jenkinsci.plugins.workflow.support.steps.input.Rejection. It is so only when timeout occured while input was active. But, if timeout occured not in input, getCause()[0] will contain object of another class: org.jenkinsci.plugins.workflow.steps.TimeoutStepExecution$ExceededTimeout (directly mentioning timeout).
So, I end up with this:
def is_interrupted_by_timeout(org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e, Boolean throw_again=true) {
// if cause is not determined, re-throw exception
try {
def cause = e.getCauses()[0]
def cause_class = cause.getClass()
//echo("cause ${cause} class: ${cause_class}")
if( cause_class == org.jenkinsci.plugins.workflow.steps.TimeoutStepExecution$ExceededTimeout ) {
// strong detection
return true
} else if( cause_class == org.jenkinsci.plugins.workflow.support.steps.input.Rejection ) {
// indirect detection
def user = cause.getUser()
if( user.toString().equals('SYSTEM') ) {
return true
} else {
return false
}
}
} catch(org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException e_access) {
// here, we may deal with situation when restricted methods are not approved:
// show message and Jengins' admin will copy/paste and execute them only once per Jenkins installation.
error('''
To run this job, Jenkins admin needs to approve some Java methods.
There are two possible ways to do this:
1. (better) run this code in Jenkins Console (URL: /script):
import org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval;
def scriptApproval = ScriptApproval.get()
scriptApproval.approveSignature('method org.jenkinsci.plugins.workflow.steps.FlowInterruptedException getCauses')
scriptApproval.approveSignature('method org.jenkinsci.plugins.workflow.support.steps.input.Rejection getUser')
scriptApproval.save()
'''.stripIndent())
return null
}
if( throw_again ) {
throw e
} else {
return null
}
}
And now, you may catch it with something like this:
try {
...
} catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException err) {
if( is_interrupted_by_timeout(err) ) {
echo('It is timeout!')
}
}
P.S. I agree, this is bad Jenkins design.

Jenkins Active Choices Parameter plugin not working as expected

I have a hidden parameter in Jenkins called platformType. I want to display choices based on the parameter platformType. I created the following groovy script but it doesn't work
if (platformType.equals("android")) {
return ['7.0', '6.0']
} else (platformType.equals("ios")) {
return ['10.0', '9.0']
}
Pls see the screenshot below
quite sure you did not specify the platformType as a parameter to platformVersion or you have other error in your code..
without error handling you just don't see it.
in your script you can catch the exception like this:
try {
if (platformType.equals("android")) {
return ['7.0', '6.0']
} else if(platformType.equals("ios")) {
return ['10.0', '9.0']
}
}catch(e){ return [e.toString()] }
in this case you'll see the error in your choice field
Looks you are missing if in the else part.
It is supposed to be:
if ('android' == platformType) {
return ['7.0', '6.0']
} else if ('ios' == platformType) {
return ['10.0', '9.0']
} else return []

Grails rejectvalue error and domain error validation

I'm trying to do some serverside validation in grails and pass my errors back to the frontend as json to be processed by angularjs.
Error conditions
Department - required
Department - unique
Description - foobar not allowed
I have the following code.
Controller
def saveDepartment() {
def errors = []
def success = true
def department
try{
department = departmentService.save(request.JSON);
if(department.hasErrors()) {
success = false
errors = department.errors.fieldErrors;
}
} catch(Exception e){
e.printStackTrace()
errors = "Unknown"
success = false
if(log.errorEnabled){
log.error("save department encountered unknown error: ", e)
}
response.status = 500
} finally {
respond ([success:success, errors:errors, department:department]) as JSON;
}
}
Service
def save(jsonObj) {
def dept = new Department();
dept.setName(jsonObj.name);
dept.setDescription(jsonObj.description);
if(dept.description.equals('foobar')) {
dept.errors.rejectValue('description', 'foobar', 'Foobar is not allowed')
}
if (!dept.save()) {
dept.discard();
}
return dept;
}
Service Method Attempt 2 with debugging code
def save(jsonObj) {
def dept = new Department();
dept.setName(jsonObj.name);
dept.setDescription(jsonObj.description);
if(dept.description.equals('foobar')) {
println 'rejected value '
dept.errors.rejectValue('description', 'foobar', 'Foobar is not allowed')
}
println 'dept errors ' + dept.errors.allErrors.size();
if (dept.errors.hasErrors()) {
dept.errors.allErrors.each {FieldError error ->
println error
}
}
if (!dept.save(true)) {
println 'dept errors 2 ' + dept.errors.allErrors.size();
if (dept.errors.hasErrors()) {
dept.errors.allErrors.each {FieldError error ->
println error
}
}
}
return dept;
}
Output
..................rejected value
dept errors 1
Field error in object 'org.hri.leaverequest.Department' on field 'description': rejected value [foobar]; codes [foobar.org.hri.leaverequest.Department.descripti
on,foobar.description,foobar.java.lang.String,foobar]; arguments []; default message [Foobar is not allowed]
dept errors 2 1
Field error in object 'org.hri.leaverequest.Department' on field 'name': rejected value [null]; codes [org.hri.leaverequest.Department.name.nullable.error.org.h
ri.leaverequest.Department.name,org.hri.leaverequest.Department.name.nullable.error.name,org.hri.leaverequest.Department.name.nullable.error.java.lang.String,or
g.hri.leaverequest.Department.name.nullable.error,department.name.nullable.error.org.hri.leaverequest.Department.name,department.name.nullable.error.name,depart
ment.name.nullable.error.java.lang.String,department.name.nullable.error,org.hri.leaverequest.Department.name.nullable.org.hri.leaverequest.Department.name,org.
hri.leaverequest.Department.name.nullable.name,org.hri.leaverequest.Department.name.nullable.java.lang.String,org.hri.leaverequest.Department.name.nullable,depa
rtment.name.nullable.org.hri.leaverequest.Department.name,department.name.nullable.name,department.name.nullable.java.lang.String,department.name.nullable,nulla
ble.org.hri.leaverequest.Department.name,nullable.name,nullable.java.lang.String,nullable]; arguments [name,class org.hri.leaverequest.Department]; default mess
age [Property [{0}] of class [{1}] cannot be null]
Issues
If department is null and description has foobar with rejectValue, only one error, "department null" is returned, foobar does not appear in the errors.
If department contains existing value and description contains foobar, the unique constraint is returned but foobar does not appear in the errors.
If department has a good value and foobar still exist, the rejectValue doesn't prevent the save from happening and no errors are thrown. Now if I output dept.errors after the rejectValue, I can see the error actually exist.
Goal
My goal is to return all my errors and not save to the db if an error exist, what am I missing to achieve that goal?
You can do it this way:
dept.validate()
if(dept.description.equals('foobar')) {
dept.errors.rejectValue('description', 'foobar', 'Foobar is not allowed')
}
if(!dept.errors.hasErrors()) {
dept.save()
}
return dept
surely that is the validation constraints that you need to get right in the domain class or relevant validator?.
You have a set of criterias and the validation on the backend should fail to match what you expect to return or not as an error ? or maybe I am missing something
class Example {
Department deparment
static constraints = {
department(nullable:false, blank:false, unique:true, validator: checkDept)
}
static def checkDept= { val, obj, errors ->
//department has a value
if (val) {
//val is now also the same as object.department
if (obj.deparment.description='foo') {
errors.rejectValue(propertyName, "nullable.input", [''] as Object[], 'this is description as foo being rejected')
} else if (obj.deparment.name='bar') {
errors.rejectValue('department.name', "nullable.input", [''] as Object[], 'this is name of bar')
} else {
errors.rejectValue(propertyName, "nullable.input", [''] as Object[], 'this is null and being rejected')
}
}
}
}
propertyName will bind to actual object name - if you are failing based on department.something and the field names are that on the gsp page then you may need to tweak that.
The logics of above is not exactly what you have asked for but it should give you an idea of how you can customise to exactly what you wish to fail. If it doesn't match those then it will just go through as you require

Grails 2.2.4 testing what does assert means and response url

I do not understand clearly the code behind the "assert". Please tell me what does those mean.
I already put the params attribute above my code . I did not describe detail.
void testSave() {
controller.save()
println 'testSave() from Controller'
assert model.serviceAccountInstance != null
assert view == '/serviceAccount/create'
response.reset()
populateValidParams(params)
controller.save()
println params.passWord
assert response.redirectedUrl == '/serviceAccount/show/1'
assert controller.flash.message != null
assert ServiceAccount.count() == 1
}
Than you for your answer.

Geb 'at null' when asserting page

I'm trying to write a simple Geb/Spock test using Grails but I am receiving the following test failure.
| Failure: login works correctly(...UserAuthAcceptanceSpec)
| Condition not satisfied:
at HomePage
|
null
I can follow the test through with a debugger using a browser and can see that the application works as expected and the correct heading is being shown. However, the test is failing when I try to invoke the at checker. Can anyone tell me why the final assertion in the test might be failing and why the 'at' checker appears to be null?
Here is my code: (Geb v0.9.0, Grails 2.2.2)
Spock Specification:
class UserAuthAcceptanceSpec extends GebReportingSpec {
def "login works correctly"() {
given: "the correct credentials"
def theCorrectUsername = "admin"
def theCorrectPassword = "password"
when: "logging in"
to LoginPage
username = theCorrectUsername
password = theCorrectPassword
submitButton.click() //([HomePage, LoginPage])
then: "the welcome page is shown"
heading =~ /(?i)Welcome.*/ // <- same as 'at' checker in HomePage
and: "the 'at' checker works"
at HomePage // <- fails
}
LoginPage:
class LoginPage extends Page {
final String path = "/login/auth"
static content = {
heading(required: false, wait:true) { $("h1").text() }
username { $("input", name:"j_username") }
password { $("input", name:"j_password") }
submitButton { $("input", id:"submit") }
}
static at = {
title =~ /Login.*/
}
}
HomePage:
class HomePage extends Page {
final String path = "/"
static content = {
heading(required: false, wait:true) { $("h1").text() }
}
static at = {
heading =~ /(?i)Welcome.*/
}
}
The at checker should use ==~ rather than =~.
Geb's implicit assertions mean the statements:
heading1 =~ /(?i)Welcome.*/
heading2 ==~ /(?i)Welcome.*/
effectively become:
assert (heading1 =~ /(?i)Welcome.*/) == true // [1]
assert (heading2 ==~ /(?i)Welcome.*/) == true // [2]
[2] will evaluate to a boolean and pass/fail as expected, whereas [1] evaluates to a java.util.regex.Matcher causing the failure.
See the Groovy Regex FAQ for an explanation of the difference between the two syntaxes.

Resources