Karate api test: TestRunner.testParallel:15 Multi threaded access requested by thread Thread[pool-1-thread-1,3] but is not allowed for language(s) js - multithreading

Testing api with Karate: mocks and queue implementation: Error TestRunner.testParallel:15 Multi threaded access requested by thread Thread[pool-1-thread-1,3,main] but is not allowed for language(s) js. is produced when try to consume a queue with multiple messages.
Flow:
Call a messageMock.feature :
Background:
* def QueueUtils = Java.type('mocks.QueueUtils')
* configure cors = true
* configure responseHeaders = { 'Content-Type': 'application/json' }
Scenario: pathMatches('/message') && methodIs('post')
* def response = read('../../responses/message/message.json')
* def responseStatus = 200
* QueueUtils.send(response.data, JSON.stringify(read('test.json')), 25)
* QueueUtils.send(response.data, JSON.stringify(read('test1.json')), 25)
* QueueUtils.send(response.data, JSON.stringify(read('test2.json')), 25)
From feature:
Scenario: Send message
* def QueueConsumer = Java.type('mocks.QueueConsumer')
* def port = karate.start('messageMock.feature').port
* url baseUrl + port
Given path '/message';
And request read('req.json')
When method post
Then status 200
* def queue = new QueueConsumer(response.data)
* def handler = function(msg){ karate.signal(msg) }
* queue.listen(karate.toJava(handler))
* listen 2000
* json response = listenResult
* print '### received:', listenResult
And match response == read('test.json')
* listen 2000
* json response1 = listenResult
* print '### received1:', listenResult
And match response1 == read('test1.json')
* listen 2000
* json response2 = listenResult
* print '### received2:', listenResult
And match response2 == read('test2.json')
The error message is given on line:
* json response = listenResult
is it a bug or incorrectly created test?
What I am trying to test is a queue that have several enqueued messages before consumption. Is this possible to do with Karate?

It is possible we have some work left for multiple threads with the new JS engine.
It would be very helpful if you can provide a sample project that replicates this problem. Kindly follow this process: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue
Some work-arounds are given here, but not ideal: https://github.com/intuit/karate/issues/1633#issuecomment-874854857
Which is why it is important that you help us replicate - so that we can figure out a better solution.

Related

java.lang.NullPointerException with a POST call in Karate

I have a feature file like below:
*Feature: Create Quote in D365
Background:
* def myFeature = call read('D365_Authentication.feature')
* header Authorization = 'Bearer ' + myFeature.BearerToken
* def random_string =
"""
function(s){
var text = "";
var pattern = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
for(var i=0; i<s; i++)
text += pattern.charAt(Math.floor(Math.random() * pattern.length()));
return text;
}
"""
* url '<somehost>'
Scenario: Create Opportunity
Given path '<path>'
And def requestPayload = read('CreateOpportunity.json')
And set requestPayload.name = 'Temp Opportunity From Karate ' + random_string(10)
And set requestPayload.hsl_closedate = '2022-03-23T00:00:00.000Z'
And header Content-Type = 'application/json'
And request requestPayload
When method POST
Then status 204*
When running this, getting NullPointerException. Can anybody help me identify why this exception is coming.
Firstly you need to download the jar file specific karate version from https://github.com/karatelabs/karate/releases.
Please unfold the Assets link.
You can run the feature file so:
java - jar jarfinename -m xxx.feature

How to Poll a request for certain interval and determine Pass or Failure

I've the API request as below :
* def reqCreate = read('classpath:integration/create-request.json')
* def resCreate = read('classpath:integration/create-response.json')
* def personId = 12
Given path '/person/' + personId
And header Authorization = 'Bearer ' + accessToken
When method get
Then status 200
Then match response == resCreate
I need to check the response after every 5 seconds till one minute.During one minute or till one minutes any any moment, if response assertion gives true then final result is true else should return false after specified duration.
This is explained clearly in the documentation : https://github.com/intuit/karate#retry-until
* configure retry = { count: 12, interval: 5000 }
Given url demoBaseUrl
And path 'greeting'
And retry until response.id > 3
When method get
Then status 200
In your case :
Given path '/person/' + personId
And configure retry = { count: 12, interval: 5000 }
And header Authorization = 'Bearer ' + accessToken
And retry until response == resCreate
When method get
Then status 200
Please don't forget to mark your previous questions as answered, you have a few that you left open.

How to create a random string everytime a test runs in karate dsl

The json request I am sending is:
Given url applicationURL
And path 'applications'
And header Authorization = subscribeToken
And request:
{
"throttlingTier": "Unlimited",
"description": "sample app description",
"name": "TestbyKarate",
"callbackUrl": "https:/apistore-dev-dev-a878-14-ams10-nonp.qcpaws.qantas.com.au/callback"
}
When method post
Then status 201
* def applicationId = response.applicationId
* print 'applicationId is ', applicationId
I am sending the name in my request as TestbyKarate but I want to send a unique value every time my test runs.
Is there any way to do it?
Can you please read the docs once. It will really benefit you.
https://github.com/intuit/karate#commonly-needed-utilities
So in the Background or common feature, you have:
* def now = function(){ return java.lang.System.currentTimeMillis() }
Then you can do this:
* def name = 'Test-' + now()
* request { name: '#(name)' }
check below example
Feature: Create User Name
Scenario: UserName with unique Name
def getDate =
"""
function(){ return java.lang.System.nanoTime() }
"""
def time = getDate()
def userName = 'createUser' + time + '_Test'

How to skip next steps if a condition is fulfilled in a feature file using karate

My feature file looks somthing like this :
#Subscribe to an API
Given url applicationURL
And path 'subscriptions'
And header Authorization = subscribeToken
And request {'tier': 'Gold','apiIdentifier': '#(APIIDStr)','applicationId': '#(applicationId)'}
When method post
Then status 201
* def subscriptionId = response.subscriptionId
* print 'subscriptionID is ', subscriptionId
* def status = response.status
* print 'subscribed with status ', status , ' and subscriptionID ' , subscriptionId
#* eval if (response.status == 'ON_HOLD') karate.call('BPSWorkflow.feature')
Given url applicationURL + '/applications/generate-keys?'
And param applicationId = applicationId
And header Authorization = subscribeToken
And request {"validityTime": "3600","keyType": "PRODUCTION","accessAllowDomains": ["ALL"]}
When method post
Then status 200
* def accessTokenforInvokation = 'Bearer '+ response.token.accessToken
* print 'accessTokenforInvokation is ', accessTokenforInvokation
I want to skip every step after "#* eval if (response.status == 'ON_HOLD') karate.call('BPSWorkflow.feature')" status is 'ON_HOLD'.
Can someone help?
There is an experimental API you can use karate.abort() - here is the documentation: https://github.com/intuit/karate/tree/master/karate-netty#karateabort
This will be made more obvious and documented better in the next release.
* eval if (response.status == 'ON_HOLD') { karate.call('BPSWorkflow.feature'); karate.abort() }

Why does HTTPBuilder throw "HttpResponseException: Bad Request"?

Http-builder: 0.7.1 |
Language: Groovy |
Framework: Spock
Testing Code
import groovyx.net.http.HTTPBuilder
import spock.lang.Specification
/**
* Created by Long Nguyen on 4/11/2017.
*
* Chatwork api documentation: http://developer.chatwork.com/ja/index.html
*/
class ChatworkApiSpec extends Specification {
// https://api.chatwork.com/v2/contacts
def apiRoot = "http://api.chatwork.com/v2"
def contactsPath = "/contacts"
def apiToken = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx"
def http = new HTTPBuilder(apiRoot)
/**
* Endpoint: /contacts
* You can access the list of users who are in contact with you.
*/
def "Get your contact list"() {
when:
def response = http.get(path: contactsPath, headers: ["X-ChatWorkToken": apiToken])
def responseData = response.responseData
then:
println responseData
}
}
It always throws below exception. I don't know what i was wrong with setting headers.
(Of course this api works for me when I use Postman)
Message:
groovyx.net.http.HttpResponseException: Bad Request
at groovyx.net.http.HTTPBuilder.defaultFailureHandler(HTTPBuilder.java:652)
at groovy.lang.Closure.call(Closure.java:414)
at groovyx.net.http.HTTPBuilder.doRequest(HTTPBuilder.java:508)
at groovyx.net.http.HTTPBuilder.get(HTTPBuilder.java:292)
at groovyx.net.http.HTTPBuilder.get(HTTPBuilder.java:262)
at testcase.ChatworkApiSpec.Get your contact list(ChatworkApiSpec.groovy:24)
Sorry my bad question. I release that my root link also included path in it.
Replace:
def apiRoot = "http://api.chatwork.com/v2"
def contactsPath = "/contacts"
by
def apiRoot = "http://api.chatwork.com"
def contactsPath = "/v2/contacts"
can resolve this problem.

Resources