Create groovy script for run REST request - rest

I have a task to create groovy script which will run REST request and setup property.
I setup property by script:
testRunner.testCase.setPropertyValue( "ScriptProFrom", "BIF" )
testRunner.testCase.setPropertyValue( "ScriptProTo", "STD" )
But I can't find how to run REST request. I tried to do it like this:
myInterface = (RestService) testRunner.testCase.testSuite.project.getInterfaceByName("http://www.webservicex.net")
myOperation = myInterface.getOperationByName("ConversionRate")
myRequest = myOperation.getRequestByName("Request 1")
and get "Script-result: com.eviware.soapui.impl.RestRequest#6a80901" and it cool if it my request, but how to run it?
Please, help...

Normally if you have a testStep you can get it and then simply run it, however your are doing it in another way so you can use the submit method of com.eviware.soapui.impl.rest.RestRequest class. This method has two parameters, the context which is an instance of com.eviware.soapui.model.iface.SubmitContext interface and a boolean which indicates if the operation is asynchronous. In your code this could be:
myInterface = testRunner.testCase.testSuite.project.getInterfaceByName("http://www.webservicex.net")
myOperation = myInterface.getOperationByName("ConversionRate")
myRequest = myOperation.getRequestByName("Request 1")
// get the context
def context = testRunner.getRunContext()
// send the request synchronous
myRequest.submit(context,false)
EDIT BASED ON OP COMMENT:
The submit method returns an object which is instance of com.eviware.soapui.impl.wsdl.WsdlSubmit<T>, then you can invoke getResponse() on this object an get another object which is instance of com.eviware.soapui.model.iface.Response then from this you can use getContentAsString() to check the response content or getContentType() to check the content type and so on. Please note that if you invoke submit in asynchronous way you must validate that getStatus() returns com.eviware.soapui.model.iface.Submit.Status.FINISHED before getResponse(). I give you an example:
myInterface = testRunner.testCase.testSuite.project.getInterfaceByName("http://www.webservicex.net")
myOperation = myInterface.getOperationByName("ConversionRate")
myRequest = myOperation.getRequestByName("Request 1")
// get the context
def context = testRunner.getRunContext()
// send the request synchronous
def submitted = myRequest.submit(context,false)
// get the response
def response = submitted.getResponse()
// get the response content as string
def content = response.getContentAsString()
// i.e check that the response contains literal 'OK'
assert content.contains('OK'),"Response not contains OK literal"
Hope this helps,

Related

Mocking input request objects in scala

Is it possible to mock a request object into a mock server? I.e. I want to make a call multiple times but with just one change, the user id in this case: val request = MyServiceRequest(userId = "123", data = "static data"). I.e.
myService.doSomething(MyServiceRequest("1", any()).returns(MyServiceObject(requestId = "1"))
myService.doSomething(MyServiceRequest("2", any()).returns(MyServiceObject(requestId = "2"))
myService.doSomething(MyServiceRequest("3", any()).returns(MyServiceObject(requestId = "2"))
Right now I have to write out the full request each time, I just want to define one parameter.

Jenkins: Active Choices Parameter + Groovy to build a list based on REST responde

I have a REST client that returns me a list of systems.
I need this list to be as a parameter for a jenkins job.
I think I need Actice Choices Parameter plugin with Groovy and HTTPBuilder in order to do that.
What do you guys think?
I did not find a way to install HTTPBuilder into Jenkins.
Is there any other way that you guys think it is possible?
I have run into the same problem trying to parse parameters via groovy script. Arun's answer did not work for me. However, I have managed to get it to work using the following:
import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.OutputStreamWriter
import java.net.URL
import java.net.URLConnection
import groovy.json.JsonSlurper
def choices = []
def url = new URL("some.data.url")
def conn = url.openConnection()
conn.setDoOutput(true)
def reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))
def results = new JsonSlurper().parseText(reader.getText());
reader.close()
results.each { data -> choices.push(data.field) }
return choices.sort()
First paste the JSON body snapshot output -or whatever your REST client is going to return. That'll help.
For ex: if it'll return a JSON object then you can use Active Choice Parameter's Groovy script step - OR Scriptler script (within the Active Choice Parameter plugin). PS: Scriptler script runs in the same JVM of Jenkins process so it has access to Jenkins/etc object for free. You don't need HTTPBuilder or anything. See the code sample below.
Assuming if your REST client is returning a JSON object and from that object if you want to list hostname of the system or some field name then replace the following variable with that and you'll get it listed while doing "Build with parameters" from Jenkins job's dashboard.
import groovy.json.JsonSlurper
//this will be your URL which will return something, tweak it if you want to pass parameters or username/password acc.
def SOME_URL = "https://koba.baby.com/some_url"
// now connect to the URL and create a connection variable 'conn'
def conn = SOME_URL.toURL().openConnection()
// create a list variable 'servernames'
def servernames = []
// if connection response was successful i.e. http protocol return code was 200, then do the following
if( conn.responseCode == 200 ) {
// get the results / output of the URL connection in a variable 'results'
def results = new JsonSlurper().parseText(conn.content.text)
// to see results variable output uncomment the next line
//println results
// now read each element in the 'results' variable and pick servername/somefield variable into the list variable 'servernames'
results.each { id, data -> servernames.push(data.someField_or_HostName) }
}
return servernames.sort().unique()
// return servernames.sort()

Gatling httpRequest with dynamic method from collection

I want to build a Gatling scenario from a collection of structured data (StructuredDataCollection).
My problem is, that I'm unable to pass in the "method" (as in HTTP method) from an element from the collection into the http call of the actual test.
Here's a code snippet.
def testScenario(duration: Int) = scenario("SO").during(duration) {
exec {
session => {
val test = StructuredDataCollection.next()
val title = test.title
val method = test.method // Not being used, because it does not work like that :(
val endpoint = test.endpoint
val requiredParameters = test.requiredParameters
val code = test.code
session
.set("title", title)
.set("methodFUG", method).set("endpoint", endpoint)
.set("requiredParameters", requiredParameters)
.set("code", code)
}
}
.exec(
http("${title}")
.httpRequest("get", "${endpoint}") // TODO: method can't be passed in as an expression.
.queryParamMap("${requiredParameters}")
.check(status.is("${code}"))
)
}
As you can see, I've hard-coded "get", but I'll need that to be replaced with the actual value from the method property from the current selected item from the collection.
Unfortunately, Gatling's DSL isn't available in all the places where you'd expect it to be, and it's just reading that as a string.
It took me some time to realize, that
http("${title}").httpRequest("${methodFUG}", "${endpoint}") will actually make a HTTP call with the invalid method "${methodFUG}" and not the value from the collection element, which could be "GET", "POST", "PUT", "DELETE", and so on.
httpRequest signature is (method: String, url: Expression[String]), see documentation.
It cannot take an Expression, only a static String.

Getting name of previous test step of type Rest Request in SoapUI groovy script

I'm using groovy script to transfer a certain property from the response of a REST request like this:
def setCookie = testRunner.testCase.testSteps["SubmitCompleteDeviceRegistration"].testRequest.response.responseHeaders["Set-Cookie"]
def global = com.eviware.soapui.SoapUI.globalProperties
re = /(SESSION_AUTHENTICATION_TOKEN=[A-Za-z0-9_-]+;)/
matcher = ( setCookie =~ re )
def cookie = matcher[0][0]
global.setPropertyValue("SESSION_AUTHENTICATION_TOKEN","$cookie")
return cookie
Now what I want to do is make the name of the above teststep, "SubmitCompleteDeviceRegistration", variable, so I can use the transfer for various REST-Requests.
The name of this variable TestStep should equal the name of the previous TestStep of the RestRequest type.
How can I go about defining the TestStep that equals this condition?
I'm trying to use something like
def prevGroovyTestStep =
testRunner.testCase.findPreviousStepOfType(testRunner.testCase.getTestStepByName
("SubmitCompleteDeviceRegistration"),RestRequest)
log.info(prevGroovyTestStep.getName())
But I'm not sure how to implement this.
Any help would be really appreciated!
Getting the previous step name
def previousStepName = context.testCase.testStepList[context.currentStepIndex - 1].name
log.info "Previous step name is : ${previousStepName}"
Getting the previous step name if its type is Rest Request
def testStep = context.testCase.testStepList[context.currentStepIndex - 1]
def previousStepName
if (testStep instanceof com.eviware.soapui.impl.wsdl.teststeps.RestTestRequestStep) {
previousStepName = testStep.name
} else {
log.error "Previous step is not of Rest Request Type"
}
if (previousStepName) {
log.info "Previous step name is : ${previousStepName}"
}
If type does not match in the above case, it will log the error message.
UPDATE - updating as per the latest comments from the author of this question. The below one helps all your need and the above may not needed any more.
Add a custom property for the test case, whose name is STEP_NAME and its value is the test step name to which http header needs to be added. As you commented, the last test step name in this case.
Go the request test step where you are getting the Cookie as response header.
Add an assertion of type Script Assertion and have the below code. Note that, you need to modify the test step name to which you want to add the request header Cookie. Using the place holder for now.
/**Below script should be used as script assertion for first test request step
* Assumes below
* a. test response contains http header called 'Set-Cookie'
* b. other request needs to send http header called 'Cookie'
* In case if there is any change in the two header names you may need to
* change its references below
**/
def responseCookieKey = 'Set-Cookie'
def requestCookieKey = 'Cookie'
def setHttpHeaders(String nextStepName, def headers) {
def nextRequest = context.testCase.testSteps[nextStepName].httpRequest
def existingHeaders = nextRequest.requestHeaders
headers.each {
existingHeaders[it.key] = it.value
}
nextRequest.requestHeaders = existingHeaders
}
if (messageExchange.responseHeaders.containsKey(responseCookieKey)) {
log.info "Found Cookie in the response headers"
def cookiez = messageExchange.responseHeaders[responseCookieKey]
assert null != cookiez, "Response does not contain Cookie"
def headers = [(requestCookieKey) : (cookiez)]
setHttpHeaders(context.testCase.getProvertyValue('STEP_NAME'), headers)
} else {
log.error "Not Found Cookie in the response headers"
}

Gatling 2 dynamic queryParam on each request

I am trying to run a load test using Gatling 2. I need to generate one of the query parameters dynamically on each request.
My scenario is defined like this:
val scn = scenario("Load Test Scenario")
.exec(
http("Test API")
.post(url)
.body(StringBody("Some XML"))
.queryParam("x", DigestUtils.md5Hex(generateX().getBytes("UTF-8")))
)
def generateX() : String = {
// generate random string and return
}
This only calls generateX once and uses the result in each request. Is there anyway to have the generateX call on every request?
You have to pass a function, not a value. See Gatling documentation about Expression.
Here, you can just discard the session input parameter as you don't use it, so you can simply write:
.queryParam("x", _ => DigestUtils.md5Hex(generateX().getBytes("UTF-8")))